using System; using System.Collections.Generic; using System.IO; using BizHawk.Common; namespace BizHawk.Emulation.Cores.Computers.Commodore64 { // this is the base cartridge class public class Cart { // --------------------------------- static public Cart Load(byte[] crtFile) { Cart result = null; MemoryStream mem = new MemoryStream(crtFile); BinaryReader reader = new BinaryReader(mem); if (new string(reader.ReadChars(16)) == "C64 CARTRIDGE ") { List chipAddress = new List(); List chipBank = new List(); List chipData = new List(); List chipType = new List(); int headerLength = ReadCRTInt(reader); int version = ReadCRTShort(reader); int mapper = ReadCRTShort(reader); bool exrom = (reader.ReadByte() != 0); bool 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") { int chipLength = ReadCRTInt(reader); chipType.Add(ReadCRTShort(reader)); chipBank.Add(ReadCRTShort(reader)); chipAddress.Add(ReadCRTShort(reader)); int chipDataLength = ReadCRTShort(reader); chipData.Add(reader.ReadBytes(chipDataLength)); chipLength -= (chipDataLength + 0x10); if (chipLength > 0) reader.ReadBytes(chipLength); } } if (chipData.Count > 0) { 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; } static private int ReadCRTShort(BinaryReader reader) { int result; result = (int)reader.ReadByte() << 8; result |= (int)reader.ReadByte(); return result; } static private int ReadCRTInt(BinaryReader reader) { int result; result = (int)reader.ReadByte() << 24; result |= (int)reader.ReadByte() << 16; result |= (int)reader.ReadByte() << 8; result |= (int)reader.ReadByte(); return result; } // --------------------------------- 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 byte Peek8000(int addr) { return 0xFF; } public virtual byte PeekA000(int addr) { return 0xFF; } public virtual byte PeekDE00(int addr) { return 0xFF; } public virtual byte PeekDF00(int addr) { return 0xFF; } public virtual void Poke8000(int addr, byte val) { } public virtual void PokeA000(int addr, byte val) { } public virtual void PokeDE00(int addr, byte val) { } public virtual void PokeDF00(int addr, byte val) { } public virtual byte Read8000(int addr) { return 0xFF; } public virtual byte ReadA000(int addr) { return 0xFF; } public virtual byte ReadDE00(int addr) { return 0xFF; } public virtual byte 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, byte val) { } public virtual void WriteA000(int addr, byte val) { } public virtual void WriteDE00(int addr, byte val) { } public virtual void WriteDF00(int addr, byte val) { } } }