diff --git a/BizHawk.Emulation/Consoles/Intellivision/Intellicart.cs b/BizHawk.Emulation/Consoles/Intellivision/Intellicart.cs index 33bcba0711..4886f5795d 100644 --- a/BizHawk.Emulation/Consoles/Intellivision/Intellicart.cs +++ b/BizHawk.Emulation/Consoles/Intellivision/Intellicart.cs @@ -7,7 +7,8 @@ namespace BizHawk.Emulation.Consoles.Intellivision { public sealed partial class Intellivision : ICart { - private ushort[] memory = new ushort[65536]; + private ushort[] Intellicart = new ushort[65536]; + private bool[][] MemoryAttributes = new bool[32][]; private ushort[] CRC16_table = { @@ -52,10 +53,11 @@ namespace BizHawk.Emulation.Consoles.Intellivision public void Parse() { + int offset = 0; // Check to see if the header is valid. - if (Rom[0] != 0xA8 || Rom[1] != (0xFF ^ Rom[2])) + if (Rom[offset++] != 0xA8 || Rom[offset++] != (0xFF ^ Rom[offset++])) throw new ArgumentException(); - int offset = 3; + // Parse for data segments. for (int segment = 0; segment < Rom[1]; segment++) { ushort crc = 0xFFFF; @@ -76,23 +78,55 @@ namespace BizHawk.Emulation.Consoles.Intellivision crc = UpdateCRC16(crc, high); crc = UpdateCRC16(crc, low); data = (high << 8) | low; - WriteCart((ushort)addr, (ushort)data); + Intellicart[addr] = (ushort)data; } int expected = (Rom[offset++] << 8) | Rom[offset++]; // Check if there is an invalid CRC. if (expected != crc) throw new ArgumentException(); } + // Parse for memory attributes. + for (int attr = 0; attr < 32; attr++) + { + byte attributes = Rom[offset + (attr >> 1)]; + // Every second 2K block is stored in the upper 4 bits. + if ((attr & 0x1) != 0) + attributes = (byte)(attributes >> 4); + attributes &= 0xF; + MemoryAttributes[attr] = new bool[4]; + // Readable. + MemoryAttributes[attr][0] = ((attr & 0x1) != 0); + // Writeable. + MemoryAttributes[attr][1] = ((attr & 0x2) != 0); + // Narrow. + MemoryAttributes[attr][2] = ((attr & 0x4) != 0); + // Bank-switched. + MemoryAttributes[attr][3] = ((attr & 0x8) != 0); + } } public ushort? ReadCart(ushort addr) { + bool[] attributes = MemoryAttributes[addr / 2048]; + if (attributes[0]) + return Intellicart[addr]; return null; } - public bool? WriteCart(ushort addr, ushort value) + public bool WriteCart(ushort addr, ushort value) { - return null; + bool[] attributes = MemoryAttributes[addr / 2048]; + if (attributes[1]) + { + // Only write lower 8 bits if the Narrow attribute is set. + if (attributes[2]) + value &= 0xFF; + if (attributes[3]) + throw new NotImplementedException("Bank-switched memory attribute not implemented."); + Intellicart[addr] = value; + return true; + } + return false; } } } diff --git a/BizHawk.Emulation/Consoles/Intellivision/MemoryMap.cs b/BizHawk.Emulation/Consoles/Intellivision/MemoryMap.cs index dbeb167cb7..ee13904fa3 100644 --- a/BizHawk.Emulation/Consoles/Intellivision/MemoryMap.cs +++ b/BizHawk.Emulation/Consoles/Intellivision/MemoryMap.cs @@ -17,6 +17,9 @@ namespace BizHawk.Emulation.Consoles.Intellivision public ushort ReadMemory(ushort addr) { + ushort? cart = ReadCart(addr); + if (cart != null) + return (ushort)cart; switch (addr & 0xF000) { case 0x0000: @@ -41,6 +44,9 @@ namespace BizHawk.Emulation.Consoles.Intellivision public void WriteMemory(ushort addr, ushort value) { + bool cart = WriteCart(addr, value); + if (cart) + return; switch (addr & 0xF000) { case 0x0000: diff --git a/BizHawk.Emulation/Interfaces/ICart.cs b/BizHawk.Emulation/Interfaces/ICart.cs index 3e85b03e6c..ab26cdaf10 100644 --- a/BizHawk.Emulation/Interfaces/ICart.cs +++ b/BizHawk.Emulation/Interfaces/ICart.cs @@ -8,6 +8,6 @@ namespace BizHawk public interface ICart { ushort? ReadCart(ushort addr); - bool? WriteCart(ushort addr, ushort value); + bool WriteCart(ushort addr, ushort value); } }