namespace EMU7800.Core { /// /// Parker Brothers 8KB bankswitched carts. /// public sealed class CartPB8K : Cart { // // Cart Format Mapping to ROM Address Space // Segment1: 0x0000:0x0400 Bank1:0x1000:0x0400 Select Segment: 1fe0-1fe7 // Segment2: 0x0400:0x0400 Bank2:0x1400:0x0400 Select Segment: 1fe8-1ff0 // Segment3: 0x0800:0x0400 Bank3:0x1800:0x0400 Select Segment: 1ff0-1ff8 // Segment4: 0x0c00:0x0400 Bank4:0x1c00:0x0400 Always Segment8 // Segment5: 0x1000:0x0400 // Segment6: 0x1400:0x0400 // Segment7: 0x1800:0x0400 // Segment8: 0x1c00:0x0400 // readonly ushort[] SegmentBase; #region IDevice Members public override void Reset() { SegmentBase[0] = ComputeSegmentBase(4); SegmentBase[1] = ComputeSegmentBase(5); SegmentBase[2] = ComputeSegmentBase(6); } public override byte this[ushort addr] { get { addr &= 0x0fff; UpdateSegmentBases(addr); return ROM[SegmentBase[addr >> 10] + (addr & 0x03ff)]; } set { addr &= 0x0fff; UpdateSegmentBases(addr); } } #endregion private CartPB8K() { } public CartPB8K(byte[] romBytes) { LoadRom(romBytes, 0x2000); SegmentBase = new ushort[4]; SegmentBase[0] = ComputeSegmentBase(4); SegmentBase[1] = ComputeSegmentBase(5); SegmentBase[2] = ComputeSegmentBase(6); SegmentBase[3] = ComputeSegmentBase(7); } static ushort ComputeSegmentBase(int slice) { return (ushort)(slice << 10); // multiply by 1024 } void UpdateSegmentBases(ushort addr) { if (addr < 0xfe0 || addr >= 0x0ff8) { } else if (addr >= 0x0fe0 && addr < 0x0fe8) { SegmentBase[0] = ComputeSegmentBase(addr & 0x07); } else if (addr >= 0x0fe8 && addr < 0x0ff0) { SegmentBase[1] = ComputeSegmentBase(addr & 0x07); } else if (addr >= 0x0ff0 && addr < 0x0ff8) { SegmentBase[2] = ComputeSegmentBase(addr & 0x07); } } #region Serialization Members public CartPB8K(DeserializationContext input, MachineBase m) : base(input) { input.CheckVersion(1); LoadRom(input.ReadExpectedBytes(0x2000), 0x2000); SegmentBase = input.ReadUnsignedShorts(); } public override void GetObjectData(SerializationContext output) { base.GetObjectData(output); output.WriteVersion(1); output.Write(ROM); output.Write(SegmentBase); } #endregion } }