From 1e2c9e45f00ed9074aaed05d8eb1b753c0835e2a Mon Sep 17 00:00:00 2001 From: Anthony Konzel Date: Tue, 1 Mar 2016 13:50:07 -0600 Subject: [PATCH] C64: Apply savestate info to cartridge subsystem. --- .../Commodore64/Cartridge/CartridgeDevice.cs | 544 +++++++++--------- .../Commodore64/Cartridge/Mapper0000.cs | 6 +- .../Commodore64/Cartridge/Mapper0005.cs | 7 + .../Commodore64/Cartridge/Mapper000B.cs | 3 +- .../Commodore64/Cartridge/Mapper000F.cs | 4 + .../Commodore64/Cartridge/Mapper0012.cs | 4 + .../Commodore64/Cartridge/Mapper0013.cs | 5 + .../Commodore64/Cartridge/Mapper0020.cs | 29 +- .../Computers/Commodore64/SaveState.cs | 4 - 9 files changed, 330 insertions(+), 276 deletions(-) diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/CartridgeDevice.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/CartridgeDevice.cs index 4e322315d4..40dd410c29 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/CartridgeDevice.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/CartridgeDevice.cs @@ -1,268 +1,276 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using BizHawk.Common; - -namespace BizHawk.Emulation.Cores.Computers.Commodore64.Cartridge -{ - public abstract partial class CartridgeDevice - { - // --------------------------------- - - public static CartridgeDevice Load(byte[] crtFile) - { - var mem = new MemoryStream(crtFile); - var reader = new BinaryReader(mem); - - if (new string(reader.ReadChars(16)) != "C64 CARTRIDGE ") - { - return null; - } - - var chipAddress = new List(); - var chipBank = new List(); - var chipData = new List(); - var chipType = new List(); - - var headerLength = ReadCRTInt(reader); - var version = ReadCRTShort(reader); - var mapper = ReadCRTShort(reader); - var exrom = reader.ReadByte() != 0; - var game = reader.ReadByte() != 0; - - // reserved - reader.ReadBytes(6); - - // cartridge name - reader.ReadBytes(0x20); - - // skip extra header bytes - if (headerLength > 0x40) - { - reader.ReadBytes(headerLength - 0x40); - } - - // read chips - while (reader.PeekChar() >= 0) - { - if (new string(reader.ReadChars(4)) != "CHIP") - { - break; - } - - var chipLength = ReadCRTInt(reader); - chipType.Add(ReadCRTShort(reader)); - chipBank.Add(ReadCRTShort(reader)); - chipAddress.Add(ReadCRTShort(reader)); - var chipDataLength = ReadCRTShort(reader); - chipData.Add(reader.ReadBytes(chipDataLength).Select(x => (int)x).ToArray()); - chipLength -= chipDataLength + 0x10; - if (chipLength > 0) - reader.ReadBytes(chipLength); - } - - if (chipData.Count <= 0) - { - return null; - } - - CartridgeDevice result; - switch (mapper) - { - case 0x0000: - result = new Mapper0000(chipAddress, chipBank, chipData, game, exrom); - break; - case 0x0005: - result = new Mapper0005(chipAddress, chipBank, chipData); - break; - case 0x000B: - result = new Mapper000B(chipAddress, chipBank, chipData); - break; - case 0x000F: - result = new Mapper000F(chipAddress, chipBank, chipData); - break; - case 0x0011: - result = new Mapper0011(chipAddress, chipBank, chipData); - break; - case 0x0012: - result = new Mapper0012(chipAddress, chipBank, chipData); - break; - case 0x0013: - result = new Mapper0013(chipAddress, chipBank, chipData); - break; - case 0x0020: - result = new Mapper0020(chipAddress, chipBank, chipData); - break; - default: - throw new Exception("This cartridge file uses an unrecognized mapper: " + mapper); - } - result.HardReset(); - - return result; - } - - private static int ReadCRTShort(BinaryReader reader) - { - return (reader.ReadByte() << 8) | - reader.ReadByte(); - } - - private static int ReadCRTInt(BinaryReader reader) - { - return (reader.ReadByte() << 24) | - (reader.ReadByte() << 16) | - (reader.ReadByte() << 8) | - reader.ReadByte(); - } - - // --------------------------------- - - protected bool pinExRom; - protected bool pinGame; - protected bool pinIRQ; - protected bool pinNMI; - protected bool pinReset; - protected bool validCartridge; - - public virtual void ExecutePhase1() - { - } - - public virtual void ExecutePhase2() - { - } - - public bool ExRom - { - get - { - return pinExRom; - } - } - - public bool Game - { - get - { - return pinGame; - } - } - - public virtual void HardReset() - { - pinIRQ = true; - pinNMI = true; - pinReset = true; - } - - public bool IRQ - { - get - { - return pinIRQ; - } - } - - public bool NMI - { - get - { - return pinNMI; - } - } - - public virtual int Peek8000(int addr) - { - return 0xFF; - } - - public virtual int PeekA000(int addr) - { - return 0xFF; - } - - public virtual int PeekDE00(int addr) - { - return 0xFF; - } - - public virtual int PeekDF00(int addr) - { - return 0xFF; - } - - public virtual void Poke8000(int addr, int val) - { - } - - public virtual void PokeA000(int addr, int val) - { - } - - public virtual void PokeDE00(int addr, int val) - { - } - - public virtual void PokeDF00(int addr, int val) - { - } - - public virtual int Read8000(int addr) - { - return 0xFF; - } - - public virtual int ReadA000(int addr) - { - return 0xFF; - } - - public virtual int ReadDE00(int addr) - { - return 0xFF; - } - - public virtual int ReadDF00(int addr) - { - return 0xFF; - } - - public bool Reset - { - get - { - return pinReset; - } - } - - public virtual void SyncState(Serializer ser) - { - SaveState.SyncObject(ser, this); - } - - public bool Valid - { - get - { - return validCartridge; - } - } - - public virtual void Write8000(int addr, int val) - { - } - - public virtual void WriteA000(int addr, int val) - { - } - - public virtual void WriteDE00(int addr, int val) - { - } - - public virtual void WriteDF00(int addr, int val) - { - } - } -} +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using BizHawk.Common; + +namespace BizHawk.Emulation.Cores.Computers.Commodore64.Cartridge +{ + public abstract partial class CartridgeDevice + { + public static CartridgeDevice Load(byte[] crtFile) + { + var mem = new MemoryStream(crtFile); + var reader = new BinaryReader(mem); + + if (new string(reader.ReadChars(16)) != "C64 CARTRIDGE ") + { + return null; + } + + var chipAddress = new List(); + var chipBank = new List(); + var chipData = new List(); + var chipType = new List(); + + var headerLength = ReadCRTInt(reader); + var version = ReadCRTShort(reader); + var mapper = ReadCRTShort(reader); + var exrom = reader.ReadByte() != 0; + var game = reader.ReadByte() != 0; + + // reserved + reader.ReadBytes(6); + + // cartridge name + reader.ReadBytes(0x20); + + // skip extra header bytes + if (headerLength > 0x40) + { + reader.ReadBytes(headerLength - 0x40); + } + + // read chips + while (reader.PeekChar() >= 0) + { + if (new string(reader.ReadChars(4)) != "CHIP") + { + break; + } + + var chipLength = ReadCRTInt(reader); + chipType.Add(ReadCRTShort(reader)); + chipBank.Add(ReadCRTShort(reader)); + chipAddress.Add(ReadCRTShort(reader)); + var chipDataLength = ReadCRTShort(reader); + chipData.Add(reader.ReadBytes(chipDataLength).Select(x => (int)x).ToArray()); + chipLength -= chipDataLength + 0x10; + if (chipLength > 0) + reader.ReadBytes(chipLength); + } + + if (chipData.Count <= 0) + { + return null; + } + + CartridgeDevice result; + switch (mapper) + { + case 0x0000: + result = new Mapper0000(chipAddress, chipData, game, exrom); + break; + case 0x0005: + result = new Mapper0005(chipAddress, chipBank, chipData); + break; + case 0x000B: + result = new Mapper000B(chipAddress, chipData); + break; + case 0x000F: + result = new Mapper000F(chipAddress, chipBank, chipData); + break; + case 0x0011: + result = new Mapper0011(chipAddress, chipBank, chipData); + break; + case 0x0012: + result = new Mapper0012(chipAddress, chipBank, chipData); + break; + case 0x0013: + result = new Mapper0013(chipAddress, chipBank, chipData); + break; + case 0x0020: + result = new Mapper0020(chipAddress, chipBank, chipData); + break; + default: + throw new Exception("This cartridge file uses an unrecognized mapper: " + mapper); + } + result.HardReset(); + + return result; + } + + private static int ReadCRTShort(BinaryReader reader) + { + return (reader.ReadByte() << 8) | + reader.ReadByte(); + } + + private static int ReadCRTInt(BinaryReader reader) + { + return (reader.ReadByte() << 24) | + (reader.ReadByte() << 16) | + (reader.ReadByte() << 8) | + reader.ReadByte(); + } + + [SaveState.SaveWithName("ExRom")] + protected bool pinExRom; + [SaveState.SaveWithName("Game")] + protected bool pinGame; + [SaveState.SaveWithName("IRQ")] + protected bool pinIRQ; + [SaveState.SaveWithName("NMI")] + protected bool pinNMI; + [SaveState.SaveWithName("Reset")] + protected bool pinReset; + [SaveState.DoNotSave] + protected bool validCartridge; + + public virtual void ExecutePhase1() + { + } + + public virtual void ExecutePhase2() + { + } + + [SaveState.DoNotSave] + public bool ExRom + { + get + { + return pinExRom; + } + } + + [SaveState.DoNotSave] + public bool Game + { + get + { + return pinGame; + } + } + + public virtual void HardReset() + { + pinIRQ = true; + pinNMI = true; + pinReset = true; + } + + [SaveState.DoNotSave] + public bool IRQ + { + get + { + return pinIRQ; + } + } + + [SaveState.DoNotSave] + public bool NMI + { + get + { + return pinNMI; + } + } + + public virtual int Peek8000(int addr) + { + return 0xFF; + } + + public virtual int PeekA000(int addr) + { + return 0xFF; + } + + public virtual int PeekDE00(int addr) + { + return 0xFF; + } + + public virtual int PeekDF00(int addr) + { + return 0xFF; + } + + public virtual void Poke8000(int addr, int val) + { + } + + public virtual void PokeA000(int addr, int val) + { + } + + public virtual void PokeDE00(int addr, int val) + { + } + + public virtual void PokeDF00(int addr, int val) + { + } + + public virtual int Read8000(int addr) + { + return 0xFF; + } + + public virtual int ReadA000(int addr) + { + return 0xFF; + } + + public virtual int ReadDE00(int addr) + { + return 0xFF; + } + + public virtual int ReadDF00(int addr) + { + return 0xFF; + } + + [SaveState.DoNotSave] + public bool Reset + { + get + { + return pinReset; + } + } + + public virtual void SyncState(Serializer ser) + { + SaveState.SyncObject(ser, this); + } + + [SaveState.DoNotSave] + public bool Valid + { + get + { + return validCartridge; + } + } + + public virtual void Write8000(int addr, int val) + { + } + + public virtual void WriteA000(int addr, int val) + { + } + + public virtual void WriteDE00(int addr, int val) + { + } + + public virtual void WriteDF00(int addr, int val) + { + } + } +} diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/Mapper0000.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/Mapper0000.cs index 1aa840440c..cfb7574c05 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/Mapper0000.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/Mapper0000.cs @@ -8,15 +8,19 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.Cartridge { private sealed class Mapper0000 : CartridgeDevice { + [SaveState.DoNotSave] private readonly int[] _romA; + [SaveState.SaveWithName("RomMaskA")] private readonly int _romAMask; + [SaveState.DoNotSave] private readonly int[] _romB; + [SaveState.SaveWithName("RomMaskB")] private readonly int _romBMask; // standard cartridge mapper (Commodore) // note that this format also covers Ultimax carts - public Mapper0000(IList newAddresses, IList newBanks, IList newData, bool game, bool exrom) + public Mapper0000(IList newAddresses, IList newData, bool game, bool exrom) { pinGame = game; pinExRom = exrom; diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/Mapper0005.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/Mapper0005.cs index a8fe648890..4a3a3cc486 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/Mapper0005.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/Mapper0005.cs @@ -9,12 +9,19 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.Cartridge { private sealed class Mapper0005 : CartridgeDevice { + [SaveState.DoNotSave] private readonly int[][] _banksA; //8000 + [SaveState.DoNotSave] private readonly int[][] _banksB = new int[0][]; //A000 + [SaveState.SaveWithName("BankMask")] private readonly int _bankMask; + [SaveState.SaveWithName("BankNumber")] private int _bankNumber; + [SaveState.DoNotSave] private int[] _currentBankA; + [SaveState.DoNotSave] private int[] _currentBankB; + [SaveState.DoNotSave] private readonly int[] _dummyBank; public Mapper0005(IList newAddresses, IList newBanks, IList newData) diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/Mapper000B.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/Mapper000B.cs index ab46dfe7e1..2ddf62bee1 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/Mapper000B.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/Mapper000B.cs @@ -14,9 +14,10 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.Cartridge { private sealed class Mapper000B : CartridgeDevice { + [SaveState.DoNotSave] private readonly int[] _rom = new int[0x4000]; - public Mapper000B(IList newAddresses, IList newBanks, IList newData) + public Mapper000B(IList newAddresses, IList newData) { validCartridge = false; diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/Mapper000F.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/Mapper000F.cs index 2cec7f2eb4..0dcf2f3465 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/Mapper000F.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/Mapper000F.cs @@ -16,9 +16,13 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.Cartridge { private class Mapper000F : CartridgeDevice { + [SaveState.DoNotSave] private readonly int[][] _banks; //8000 + [SaveState.SaveWithName("BankMask")] private readonly int _bankMask; + [SaveState.SaveWithName("BankNumber")] private int _bankNumber; + [SaveState.SaveWithName("CurrentBank")] private int[] _currentBank; public Mapper000F(IList newAddresses, IList newBanks, IList newData) diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/Mapper0012.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/Mapper0012.cs index 6008df1297..c0ff12e715 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/Mapper0012.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/Mapper0012.cs @@ -8,9 +8,13 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.Cartridge { private sealed class Mapper0012 : CartridgeDevice { + [SaveState.DoNotSave] private readonly int[] _bankMain; + [SaveState.DoNotSave] private readonly int[][] _bankHigh; + [SaveState.SaveWithName("BankHighSelected")] private int[] _bankHighSelected; + [SaveState.SaveWithName("BankIndex")] private int _bankIndex; // Zaxxon and Super Zaxxon cartridges diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/Mapper0013.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/Mapper0013.cs index 538f41201e..5282d6ce02 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/Mapper0013.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/Mapper0013.cs @@ -16,10 +16,15 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.Cartridge { private sealed class Mapper0013 : CartridgeDevice { + [SaveState.DoNotSave] private readonly int[][] _banks; //8000 + [SaveState.SaveWithName("BankMask")] private readonly int _bankMask; + [SaveState.SaveWithName("BankNumber")] private int _bankNumber; + [SaveState.DoNotSave] private int[] _currentBank; + [SaveState.SaveWithName("ROMEnable")] private bool _romEnable; public Mapper0013(IList newAddresses, IList newBanks, IList newData) diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/Mapper0020.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/Mapper0020.cs index 7a65d27320..f27d8d09f3 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/Mapper0020.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/Mapper0020.cs @@ -26,15 +26,29 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.Cartridge { private sealed class Mapper0020 : CartridgeDevice { + [SaveState.SaveWithName("BankOffset")] private int _bankOffset = 63 << 13; - private readonly int[] _banksA = new int[64 << 13]; //8000 - private readonly int[] _banksB = new int[64 << 13]; //A000 + [SaveState.DoNotSave] + private int[] _banksA = new int[64 << 13]; //8000 + [SaveState.DoNotSave] + private int[] _banksB = new int[64 << 13]; //A000 + [SaveState.DoNotSave] + private readonly int[] _originalMediaA; //8000 + [SaveState.DoNotSave] + private readonly int[] _originalMediaB; //A000 + [SaveState.SaveWithName("BoardLed")] private bool _boardLed; + [SaveState.SaveWithName("Jumper")] private bool _jumper = false; + [SaveState.SaveWithName("StateBits")] private int _stateBits; + [SaveState.SaveWithName("RAM")] private readonly int[] _ram = new int[256]; + [SaveState.SaveWithName("CommandLatch55")] private bool _commandLatch55; + [SaveState.SaveWithName("CommandLatchAA")] private bool _commandLatchAa; + [SaveState.SaveWithName("InternalROMState")] private int _internalRomState; public Mapper0020(IList newAddresses, IList newBanks, IList newData) @@ -75,6 +89,10 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.Cartridge _commandLatch55 = false; _commandLatchAa = false; _internalRomState = 0; + + // back up original media + _originalMediaA = _banksA.Select(d => d).ToArray(); + _originalMediaB = _banksB.Select(d => d).ToArray(); } private void BankSet(int index) @@ -265,6 +283,13 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.Cartridge { _ram[addr] = val & 0xFF; } + + public override void SyncState(Serializer ser) + { + SaveState.SyncDeltaBytes("MediaStateA", ser, _originalMediaA, ref _banksA); + SaveState.SyncDeltaBytes("MediaStateB", ser, _originalMediaB, ref _banksB); + base.SyncState(ser); + } } } } diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/SaveState.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/SaveState.cs index 464c33fdee..c9cc886db5 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/SaveState.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/SaveState.cs @@ -19,10 +19,6 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64 { public string Name { get; set; } - public SaveWithName() - { - } - public SaveWithName(string name) { Name = name;