diff --git a/BizHawk.Emulation/Computers/Commodore64/C64.Core.cs b/BizHawk.Emulation/Computers/Commodore64/C64.Core.cs index 56bf99fbcc..39e27d5680 100644 --- a/BizHawk.Emulation/Computers/Commodore64/C64.Core.cs +++ b/BizHawk.Emulation/Computers/Commodore64/C64.Core.cs @@ -16,7 +16,7 @@ namespace BizHawk.Emulation.Computers.Commodore64 // ------------------------------------ private Motherboard board; - private VIC1541 disk; + //private VIC1541 disk; // ------------------------------------ @@ -51,7 +51,7 @@ namespace BizHawk.Emulation.Computers.Commodore64 { byte[] diskRom = new byte[0x4000]; //GetFirmware("dos1541", 0x4000); - disk = new VIC1541(initRegion, diskRom); + //disk = new VIC1541(initRegion, diskRom); //disk.Connect(board.serPort); } @@ -90,14 +90,15 @@ namespace BizHawk.Emulation.Computers.Commodore64 { get { - return (disk.PeekVia1(0x00) & 0x08) != 0; + //return (disk.PeekVia1(0x00) & 0x08) != 0; + return false; } } public void HardReset() { board.HardReset(); - disk.HardReset(); + //disk.HardReset(); } // ------------------------------------ diff --git a/BizHawk.Emulation/Computers/Commodore64/C64.Input.cs b/BizHawk.Emulation/Computers/Commodore64/C64.Input.cs index 97986b17dc..82de63cc60 100644 --- a/BizHawk.Emulation/Computers/Commodore64/C64.Input.cs +++ b/BizHawk.Emulation/Computers/Commodore64/C64.Input.cs @@ -28,6 +28,9 @@ namespace BizHawk.Emulation.Computers.Commodore64 static private byte[] inputBitMask = new byte[] { 0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F }; static private byte[] inputBitSelect = new byte[] { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; + private byte cia0InputLatchA; + private byte cia0InputLatchB; + public void PollInput() { // scan joysticks @@ -51,8 +54,8 @@ namespace BizHawk.Emulation.Computers.Commodore64 private void WriteInputPort() { - byte portA = Port.ExternalWrite(cia0DataA, 0xFF, cia0DirA); - byte portB = Port.ExternalWrite(cia0DataB, 0xFF, cia0DirB); + byte portA = cia0.PortAData; + byte portB = cia0.PortBData; byte resultA = 0xFF; byte resultB = 0xFF; byte joyA = 0xFF; @@ -84,8 +87,8 @@ namespace BizHawk.Emulation.Computers.Commodore64 resultA &= joyA; resultB &= joyB; - cia0DataA = Port.ExternalWrite(cia0DataA, resultA, cia0DirA); - cia0DataB = Port.ExternalWrite(cia0DataB, resultB, cia0DirB); + cia0InputLatchA = resultA; + cia0InputLatchB = resultB; } } } diff --git a/BizHawk.Emulation/Computers/Commodore64/C64.Motherboard.cs b/BizHawk.Emulation/Computers/Commodore64/C64.Motherboard.cs index 866859f6c5..a85100ccfe 100644 --- a/BizHawk.Emulation/Computers/Commodore64/C64.Motherboard.cs +++ b/BizHawk.Emulation/Computers/Commodore64/C64.Motherboard.cs @@ -20,28 +20,15 @@ namespace BizHawk.Emulation.Computers.Commodore64 // ports public CartridgePort cartPort; public CassettePort cassPort; - public IController controller; + public IController controller; public SerialPort serPort; public UserPort userPort; // state public ushort address; public byte bus; - public byte cia0DataA; - public byte cia0DataB; - public byte cia0DirA; - public byte cia0DirB; - public bool cia0FlagCassette; - public bool cia0FlagSerial; - public byte cia1DataA; - public byte cia1DataB; - public byte cia1DirA; - public byte cia1DirB; public bool inputRead; - // cache - private ushort vicBank; - public Motherboard(Region initRegion) { // note: roms need to be added on their own externally @@ -49,7 +36,7 @@ namespace BizHawk.Emulation.Computers.Commodore64 cartPort = new CartridgePort(); cassPort = new CassettePort(); cia0 = new MOS6526(initRegion); - cia1 = new MOS6526(initRegion); + cia1 = new MOS6526(initRegion); colorRam = new Chip2114(); cpu = new MOS6510(); pla = new MOSPLA(); @@ -68,8 +55,6 @@ namespace BizHawk.Emulation.Computers.Commodore64 public void Execute() { - WriteInputPort(); - cia0.ExecutePhase1(); cia1.ExecutePhase1(); sid.ExecutePhase1(); @@ -89,16 +74,6 @@ namespace BizHawk.Emulation.Computers.Commodore64 { address = 0xFFFF; bus = 0xFF; - cia0DataA = 0xFF; - cia0DataB = 0xFF; - cia0DirA = 0xFF; - cia0DirB = 0xFF; - cia0FlagCassette = true; - cia0FlagSerial = true; - cia1DataA = 0xFF; - cia1DataB = 0xFF; - cia1DirA = 0xFF; - cia1DirB = 0xFF; inputRead = false; cpu.HardReset(); @@ -113,45 +88,27 @@ namespace BizHawk.Emulation.Computers.Commodore64 // because of how mapping works, the cpu needs to be hard reset twice cpu.HardReset(); - - // now reset the cache - UpdateVicBank(); } public void Init() { - cassPort.DeviceReadLevel = CassPort_DeviceReadLevel; - cassPort.DeviceReadMotor = CassPort_DeviceReadMotor; - cassPort.DeviceWriteButton = CassPort_DeviceWriteButton; - cassPort.DeviceWriteLevel = CassPort_DeviceWriteLevel; - cassPort.SystemReadButton = CassPort_SystemReadLevel; - cassPort.SystemReadLevel = CassPort_SystemReadLevel; - cassPort.SystemWriteLevel = CassPort_SystemWriteLevel; - cassPort.SystemWriteMotor = CassPort_SystemWriteMotor; + cassPort.ReadDataOutput = CassPort_DeviceReadLevel; + cassPort.ReadMotor = CassPort_DeviceReadMotor; - cia0.ReadDirA = Cia0_ReadDirA; - cia0.ReadDirB = Cia0_ReadDirB; + cia0.ReadFlag = Cia0_ReadFlag; cia0.ReadPortA = Cia0_ReadPortA; cia0.ReadPortB = Cia0_ReadPortB; - cia0.WriteDirA = Cia0_WriteDirA; - cia0.WriteDirB = Cia0_WriteDirB; - cia0.WritePortA = Cia0_WritePortA; - cia0.WritePortB = Cia0_WritePortB; - cia1.ReadDirA = Cia1_ReadDirA; - cia1.ReadDirB = Cia1_ReadDirB; - cia1.ReadPortA = Cia1_ReadPortA; + cia1.ReadFlag = Cia1_ReadFlag; + cia1.ReadPortA = Cia1_ReadPortA; cia1.ReadPortB = Cia1_ReadPortB; - cia1.WriteDirA = Cia1_WriteDirA; - cia1.WriteDirB = Cia1_WriteDirB; - cia1.WritePortA = Cia1_WritePortA; - cia1.WritePortB = Cia1_WritePortB; cpu.PeekMemory = pla.Peek; cpu.PokeMemory = pla.Poke; cpu.ReadAEC = Cpu_ReadAEC; cpu.ReadIRQ = Cpu_ReadIRQ; cpu.ReadNMI = Cpu_ReadNMI; + cpu.ReadPort = Cpu_ReadPort; cpu.ReadRDY = Cpu_ReadRDY; cpu.ReadMemory = pla.Read; cpu.WriteMemory = pla.Write; @@ -230,16 +187,5 @@ namespace BizHawk.Emulation.Computers.Commodore64 public void SyncState(Serializer ser) { } - - private void UpdateVicBank() - { - switch (cia1DataA & 0x3) - { - case 0: vicBank = 0xC000; break; - case 1: vicBank = 0x8000; break; - case 2: vicBank = 0x4000; break; - default: vicBank = 0x0000; break; - } - } } } diff --git a/BizHawk.Emulation/Computers/Commodore64/C64.MotherboardInterface.cs b/BizHawk.Emulation/Computers/Commodore64/C64.MotherboardInterface.cs index b4844492d3..31ff65c49f 100644 --- a/BizHawk.Emulation/Computers/Commodore64/C64.MotherboardInterface.cs +++ b/BizHawk.Emulation/Computers/Commodore64/C64.MotherboardInterface.cs @@ -11,127 +11,45 @@ namespace BizHawk.Emulation.Computers.Commodore64 { bool CassPort_DeviceReadLevel() { - return cpu.CassetteOutputLevel; + return (cpu.PortData & 0x08) != 0; } bool CassPort_DeviceReadMotor() { - return cpu.CassetteMotor; + return (cpu.PortData & 0x20) != 0; } - void CassPort_DeviceWriteButton(bool val) + bool Cia0_ReadFlag() { - cpu.CassetteButton = val; - } - - void CassPort_DeviceWriteLevel(bool val) - { - cia0FlagCassette = val; - cia0.FLAG = cia0FlagCassette & cia0FlagSerial; - } - - bool CassPort_SystemReadButton() - { - return true; - } - - bool CassPort_SystemReadLevel() - { - return true; - } - - void CassPort_SystemWriteLevel(bool val) - { - return; - } - - void CassPort_SystemWriteMotor(bool val) - { - return; - } - - byte Cia0_ReadDirA() - { - return cia0DirA; - } - - byte Cia0_ReadDirB() - { - return cia0DirB; + return cassPort.DataInput; } byte Cia0_ReadPortA() { - return cia0DataA; + WriteInputPort(); + return cia0InputLatchA; } byte Cia0_ReadPortB() { - return cia0DataB; + WriteInputPort(); + return cia0InputLatchB; } - void Cia0_WriteDirA(byte val) + bool Cia1_ReadFlag() { - cia0DirA = val; - } - - void Cia0_WriteDirB(byte val) - { - cia0DirB = val; - } - - void Cia0_WritePortA(byte val) - { - cia0DataA = Port.CPUWrite(cia0DataA, val, cia0DirA); - } - - void Cia0_WritePortB(byte val) - { - cia0DataB = Port.CPUWrite(cia0DataB, val, cia0DirB); - } - - byte Cia1_ReadDirA() - { - return cia1DirA; - } - - byte Cia1_ReadDirB() - { - return cia1DirB; + return true; } byte Cia1_ReadPortA() { - return cia1DataA; + // the low bits are actually the VIC memory address. + return 0x3F; } byte Cia1_ReadPortB() { - return cia1DataB; - } - - void Cia1_WriteDirA(byte val) - { - cia1DirA = val; - } - - void Cia1_WriteDirB(byte val) - { - cia1DirB = val; - } - - void Cia1_WritePortA(byte val) - { - cia1DataA = Port.CPUWrite(cia1DataA, val, cia1DirA); - UpdateVicBank(); - serPort.SystemWriteAtn((cia1DataA & 0x08) == 0); - serPort.SystemWriteClock((cia1DataA & 0x10) == 0); - serPort.SystemWriteData((cia1DataA & 0x20) == 0); - } - - void Cia1_WritePortB(byte val) - { - cia1DataB = Port.CPUWrite(cia1DataB, val, cia1DirB); + return 0xFF; } bool Cpu_ReadAEC() @@ -139,6 +57,11 @@ namespace BizHawk.Emulation.Computers.Commodore64 return vic.AEC; } + bool Cpu_ReadCassetteButton() + { + return true; + } + bool Cpu_ReadIRQ() { return cia0.IRQ & vic.IRQ & cartPort.IRQ; @@ -149,6 +72,11 @@ namespace BizHawk.Emulation.Computers.Commodore64 return cia1.IRQ; } + byte Cpu_ReadPort() + { + return 0xFF; + } + bool Cpu_ReadRDY() { return vic.BA; @@ -187,7 +115,7 @@ namespace BizHawk.Emulation.Computers.Commodore64 bool Pla_ReadCharen() { - return cpu.Charen; + return (cpu.PortData & 0x04) != 0; } byte Pla_ReadCharRom(ushort addr) @@ -247,7 +175,7 @@ namespace BizHawk.Emulation.Computers.Commodore64 bool Pla_ReadHiRam() { - return cpu.HiRam; + return (cpu.PortData & 0x02) != 0; } byte Pla_ReadKernalRom(ushort addr) @@ -259,7 +187,7 @@ namespace BizHawk.Emulation.Computers.Commodore64 bool Pla_ReadLoRam() { - return cpu.LoRam; + return (cpu.PortData & 0x01) != 0; } byte Pla_ReadMemory(ushort addr) @@ -355,17 +283,17 @@ namespace BizHawk.Emulation.Computers.Commodore64 bool SerPort_DeviceReadAtn() { - return (cia1DataA & 0x08) == 0; + return (cia1.PortBData & 0x08) == 0; } bool SerPort_DeviceReadClock() { - return (cia1DataA & 0x10) == 0; + return (cia1.PortAData & 0x10) == 0; } bool SerPort_DeviceReadData() { - return (cia1DataA & 0x20) == 0; + return (cia1.PortAData & 0x20) == 0; } bool SerPort_DeviceReadReset() @@ -381,18 +309,18 @@ namespace BizHawk.Emulation.Computers.Commodore64 void SerPort_DeviceWriteClock(bool val) { - cia1DataA = Port.ExternalWrite(cia1DataA, (byte)((cia1DataA & 0xBF) | (val ? 0x00 : 0x40)), cia1DirA); + //cia1DataA = Port.ExternalWrite(cia1DataA, (byte)((cia1DataA & 0xBF) | (val ? 0x00 : 0x40)), cia1DirA); } void SerPort_DeviceWriteData(bool val) { - cia1DataA = Port.ExternalWrite(cia1DataA, (byte)((cia1DataA & 0x7F) | (val ? 0x00 : 0x80)), cia1DirA); + //cia1DataA = Port.ExternalWrite(cia1DataA, (byte)((cia1DataA & 0x7F) | (val ? 0x00 : 0x80)), cia1DirA); } void SerPort_DeviceWriteSrq(bool val) { - cia0FlagSerial = val; - cia0.FLAG = cia0FlagCassette & cia0FlagSerial; + //cia0FlagSerial = val; + //cia0.FLAG = cia0FlagCassette & cia0FlagSerial; } byte Sid_ReadPotX() @@ -407,7 +335,18 @@ namespace BizHawk.Emulation.Computers.Commodore64 byte Vic_ReadMemory(ushort addr) { - addr |= vicBank; + switch (cia1.PortAData & 0x3) + { + case 0: + addr |= 0xC000; + break; + case 1: + addr |= 0x8000; + break; + case 2: + addr |= 0x4000; + break; + } address = addr; if ((addr & 0x7000) == 0x1000) bus = charRom.Read(addr); diff --git a/BizHawk.Emulation/Computers/Commodore64/C64.cs b/BizHawk.Emulation/Computers/Commodore64/C64.cs index 05e1b622dd..8af0afae14 100644 --- a/BizHawk.Emulation/Computers/Commodore64/C64.cs +++ b/BizHawk.Emulation/Computers/Commodore64/C64.cs @@ -120,7 +120,7 @@ namespace BizHawk.Emulation.Computers.Commodore64 LagCount++; _frame++; - Console.WriteLine("CPUPC: " + C64Util.ToHex(board.cpu.PC, 4) + " 1541PC: " + C64Util.ToHex(disk.PC, 4)); + //Console.WriteLine("CPUPC: " + C64Util.ToHex(board.cpu.PC, 4) + " 1541PC: " + C64Util.ToHex(disk.PC, 4)); CoreComm.DriveLED = DriveLED; } @@ -152,10 +152,10 @@ namespace BizHawk.Emulation.Computers.Commodore64 domains.Add(new MemoryDomain("CIA1", 0x10, Endian.Little, new Func(board.cia1.Peek), new Action(board.cia1.Poke))); domains.Add(new MemoryDomain("VIC", 0x40, Endian.Little, new Func(board.vic.Peek), new Action(board.vic.Poke))); domains.Add(new MemoryDomain("SID", 0x20, Endian.Little, new Func(board.sid.Peek), new Action(board.sid.Poke))); - domains.Add(new MemoryDomain("1541 Bus", 0x10000, Endian.Little, new Func(disk.Peek), new Action(disk.Poke))); - domains.Add(new MemoryDomain("1541 VIA0", 0x10, Endian.Little, new Func(disk.PeekVia0), new Action(disk.PokeVia0))); - domains.Add(new MemoryDomain("1541 VIA1", 0x10, Endian.Little, new Func(disk.PeekVia1), new Action(disk.PokeVia1))); - domains.Add(new MemoryDomain("1541 RAM", 0x1000, Endian.Little, new Func(disk.PeekRam), new Action(disk.PokeRam))); + //domains.Add(new MemoryDomain("1541 Bus", 0x10000, Endian.Little, new Func(disk.Peek), new Action(disk.Poke))); + //domains.Add(new MemoryDomain("1541 VIA0", 0x10, Endian.Little, new Func(disk.PeekVia0), new Action(disk.PokeVia0))); + //domains.Add(new MemoryDomain("1541 VIA1", 0x10, Endian.Little, new Func(disk.PeekVia1), new Action(disk.PokeVia1))); + //domains.Add(new MemoryDomain("1541 RAM", 0x1000, Endian.Little, new Func(disk.PeekRam), new Action(disk.PokeRam))); memoryDomains = domains.AsReadOnly(); } } diff --git a/BizHawk.Emulation/Computers/Commodore64/Disk/VIC1541.cs b/BizHawk.Emulation/Computers/Commodore64/Disk/VIC1541.cs index c571c648b3..8d7c54420f 100644 --- a/BizHawk.Emulation/Computers/Commodore64/Disk/VIC1541.cs +++ b/BizHawk.Emulation/Computers/Commodore64/Disk/VIC1541.cs @@ -2,6 +2,8 @@ using BizHawk.Emulation.Computers.Commodore64.MOS; using System; +#if false + namespace BizHawk.Emulation.Computers.Commodore64.Disk { public class VIC1541 @@ -262,3 +264,4 @@ namespace BizHawk.Emulation.Computers.Commodore64.Disk } } } +#endif \ No newline at end of file diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/CassettePort.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/CassettePort.cs index dc0bb32922..9f39c9197b 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/CassettePort.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/CassettePort.cs @@ -4,19 +4,27 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS { public class CassettePort { - public Func DeviceReadLevel; - public Func DeviceReadMotor; - public Action DeviceWriteButton; - public Action DeviceWriteLevel; - public Func SystemReadButton; - public Func SystemReadLevel; - public Action SystemWriteLevel; - public Action SystemWriteMotor; - - // Connect() needs to set System functions above + public Func ReadDataOutput; + public Func ReadMotor; public void HardReset() { } + + public bool DataInput + { + get + { + return true; + } + } + + public bool Sense + { + get + { + return true; + } + } } } diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6510.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6510.cs index 740d6dbea0..dc4cac9c9e 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6510.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6510.cs @@ -14,14 +14,8 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS private MOS6502X cpu; private List disposeList = new List(); private bool freezeCpu; - private bool pinCassetteButton; // note: these are only - private bool pinCassetteMotor; // latches! - private bool pinCassetteOutput; - private bool pinCharen; - private bool pinLoram; - private bool pinHiram; private bool pinNMILast; - private byte portDir; + private LatchedPort port; private bool unusedPin0; private bool unusedPin1; private uint unusedPinTTL0; @@ -31,13 +25,11 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS public Func PeekMemory; public Action PokeMemory; public Func ReadAEC; - public Func ReadCassetteButton; public Func ReadIRQ; public Func ReadNMI; public Func ReadRDY; public Func ReadMemory; - public Action WriteCassetteLevel; - public Action WriteCassetteMotor; + public Func ReadPort; public Action WriteMemory; // ------------------------------------ @@ -76,8 +68,9 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS cpu.PC = (ushort)(ReadMemory(0xFFFC) | (ReadMemory(0xFFFD) << 8)); // configure data port defaults - portDir = 0x00; - SetPortData(0x1F); + port = new LatchedPort(); + port.Direction = 0x00; + port.Latch = 0x1F; // NMI is high on startup (todo: verify) pinNMILast = true; @@ -138,7 +131,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS public byte Peek(int addr) { if (addr == 0x0000) - return PortDirection; + return port.Direction; else if (addr == 0x0001) return PortData; else @@ -148,153 +141,58 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS public void Poke(int addr, byte val) { if (addr == 0x0000) - SetPortDir(val); + port.Direction = val; else if (addr == 0x0001) - SetPortData(val); + port.Latch = val; else PokeMemory(addr, val); } - public byte Read(ushort addr) + public byte PortData + { + get + { + return port.ReadOutput(); + } + set + { + port.Latch = value; + } + } + + public byte Read(ushort addr) { // cpu freezes after first read when RDY is low if (!ReadRDY()) freezeCpu = true; if (addr == 0x0000) - return PortDirection; + return port.Direction; else if (addr == 0x0001) return PortData; else return ReadMemory(addr); } - public void Write(ushort addr, byte val) + public void SyncState(Serializer ser) + { + cpu.SyncState(ser); + ser.Sync("freezeCpu", ref freezeCpu); + ser.Sync("pinNMILast", ref pinNMILast); + ser.Sync("unusedPin0", ref unusedPin0); + ser.Sync("unusedPin1", ref unusedPin1); + ser.Sync("unusedPinTTL0", ref unusedPinTTL0); + ser.Sync("unusedPinTTL1", ref unusedPinTTL1); + ser.Sync("unusedPinTTLCycles", ref unusedPinTTLCycles); + } + + public void Write(ushort addr, byte val) { if (addr == 0x0000) - PortDirection = val; + port.Direction = val; else if (addr == 0x0001) - PortData = val; + port.Latch = val; WriteMemory(addr, val); } - - // ------------------------------------ - - public bool CassetteButton - { - get { return pinCassetteButton; } - set { pinCassetteButton = value; } - } - - public bool CassetteMotor - { - get { return pinCassetteMotor; } - } - - public bool CassetteOutputLevel - { - get { return pinCassetteOutput; } - } - - public bool Charen - { - get { return pinCharen; } - } - - public bool HiRam - { - get { return pinHiram; } - } - - public bool LoRam - { - get { return pinLoram; } - } - - public byte PortData - { - get - { - //byte result = 0x00; - byte result = (byte)(~portDir & 0xEF); - - result |= pinLoram ? (byte)0x01 : (byte)0x00; - result |= pinHiram ? (byte)0x02 : (byte)0x00; - result |= pinCharen ? (byte)0x04 : (byte)0x00; - result |= pinCassetteOutput ? (byte)0x08 : (byte)0x00; - result |= pinCassetteButton ? (byte)0x10 : (byte)0x00; - result |= pinCassetteMotor ? (byte)0x20 : (byte)0x00; - result |= unusedPin0 ? (byte)0x40 : (byte)0x00; - result |= unusedPin1 ? (byte)0x80 : (byte)0x00; - return result; - } - set - { - byte val = Port.CPUWrite(PortData, value, portDir); - SetPortData(val); - } - } - - public byte PortDirection - { - get { return portDir; } - set - { - SetPortDir(value); - } - } - - public byte ReadPortData() - { - return PortData; - } - - private void SetPortData(byte val) - { - pinCassetteOutput = ((val & 0x08) != 0); - pinCassetteButton = ((val & 0x10) != 0); - pinCassetteMotor = ((val & 0x20) != 0); - - pinLoram = ((val & 0x01) != 0) || ((portDir & 0x01) == 0); - pinHiram = ((val & 0x02) != 0) || ((portDir & 0x02) == 0); - pinCharen = ((val & 0x04) != 0) || ((portDir & 0x04) == 0); - - unusedPin0 = ((val & 0x40) != 0); - unusedPin1 = ((val & 0x80) != 0); - unusedPinTTL0 = unusedPinTTLCycles; - unusedPinTTL1 = unusedPinTTLCycles; - } - - private void SetPortDir(byte val) - { - portDir = val; - SetPortData(PortData); - } - - public void SyncState(Serializer ser) - { - cpu.SyncState(ser); - ser.Sync("freezeCpu", ref freezeCpu); - ser.Sync("pinCassetteButton", ref pinCassetteButton); - ser.Sync("pinCassetteMotor", ref pinCassetteMotor); - ser.Sync("pinCassetteOutput", ref pinCassetteOutput); - ser.Sync("pinCharen", ref pinCharen); - ser.Sync("pinLoram", ref pinLoram); - ser.Sync("pinHiram", ref pinHiram); - ser.Sync("pinNMILast", ref pinNMILast); - ser.Sync("portDir", ref portDir); - ser.Sync("unusedPin0", ref unusedPin0); - ser.Sync("unusedPin1", ref unusedPin1); - ser.Sync("unusedPinTTL0", ref unusedPinTTL0); - ser.Sync("unusedPinTTL1", ref unusedPinTTL1); - ser.Sync("unusedPinTTLCycles", ref unusedPinTTLCycles); - } - - public void WritePortData(byte data) - { - PortData = data; - } - - // ------------------------------------ } } diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6522.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6522.cs index 08d04b9931..7d3c0ce0ff 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6522.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6522.cs @@ -1,5 +1,6 @@ using System; +#if false namespace BizHawk.Emulation.Computers.Commodore64.MOS { // via @@ -566,3 +567,4 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS // ------------------------------------ } } +#endif \ No newline at end of file diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6526.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6526.cs index 1d60e449a4..bc49f6d4be 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6526.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6526.cs @@ -1,4 +1,6 @@ -namespace BizHawk.Emulation.Computers.Commodore64.MOS +using System; + +namespace BizHawk.Emulation.Computers.Commodore64.MOS { // MOS technology 6526 "CIA" // @@ -41,7 +43,12 @@ // ------------------------------------ - private bool alarmSelect; + public Func ReadCNT; + public Func ReadFlag; + + // ------------------------------------ + + private bool alarmSelect; private Region chipRegion; private bool cntPos; private bool enableIntAlarm; @@ -53,7 +60,6 @@ private bool intSP; private bool[] intTimer; private bool pinCnt; - private bool pinFlag; private bool pinPC; private byte sr; private uint[] timerDelay; @@ -88,7 +94,6 @@ todAlarm = new byte[4]; SetTodIn(chipRegion); - pinFlag = true; } // ------------------------------------ @@ -100,18 +105,17 @@ public void ExecutePhase2() { - { pinPC = true; TODRun(); if (timerPulse[0]) { - WritePortA((byte)(ReadPortA() & PBOnMask[0])); + portA.Latch &= PBOnMask[0]; } if (timerPulse[1]) { - WritePortB((byte)(ReadPortA() & PBOnMask[1])); + portB.Latch &= PBOnMask[1]; } if (timerDelay[0] == 0) @@ -291,15 +295,15 @@ if (timerPortEnable[index]) { // force port B bit to output - WriteDirB((byte)(ReadDirB() | PBOnBit[index])); + portB.Direction |= PBOnBit[index]; switch (timerOutMode[index]) { case OutMode.Pulse: timerPulse[index] = true; - WritePortB((byte)(ReadPortB() | PBOnBit[index])); + portB.Latch |= PBOnBit[index]; break; case OutMode.Toggle: - WritePortB((byte)(ReadPortB() ^ PBOnBit[index])); + portB.Latch ^= PBOnBit[index]; break; } } @@ -358,17 +362,6 @@ set { cntPos |= (!pinCnt && value); pinCnt = value; } } - public bool FLAG - { - get { return pinFlag; } - set - { - if (pinFlag && !value) - intFlag = true; - pinFlag = value; - } - } - public bool PC { get { return pinPC; } @@ -426,16 +419,16 @@ switch (addr) { case 0x0: - val = ReadPortA(); + val = portA.ReadInput(ReadPortA()); break; case 0x1: - val = ReadPortB(); + val = portB.ReadInput(ReadPortB()); break; case 0x2: - val = ReadDirA(); + val = portA.Direction; break; case 0x3: - val = ReadDirB(); + val = portB.Direction; break; case 0x4: timerVal = ReadTimerValue(0); @@ -560,7 +553,6 @@ ser.Sync("intTimer0", ref intTimer[0]); ser.Sync("intTimer1", ref intTimer[1]); ser.Sync("pinCnt", ref pinCnt); - ser.Sync("pinFlag", ref pinFlag); ser.Sync("pinPC", ref pinPC); ser.Sync("sr", ref sr); ser.Sync("timerDelay0", ref timerDelay[0]); @@ -650,16 +642,16 @@ switch (addr) { case 0x0: - WritePortA(val); + portA.Latch = val; break; case 0x1: - WritePortB(val); + portB.Latch = val; break; case 0x2: - WriteDirA(val); + portA.Direction = val; break; case 0x3: - WriteDirB(val); + portB.Direction = val; break; case 0x4: timerLatch[0] &= 0xFF00; diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/Port.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/Port.cs index acb9fd99ac..f81db8b10b 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/Port.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/Port.cs @@ -2,58 +2,38 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS { - static public class Port - { - static public byte CPUWrite(byte latch, byte val, byte dir) - { - byte result; - result = (byte)(latch & (dir ^ 0xFF)); - result |= (byte)(val & dir); - return result; - } + public class LatchedPort + { + public byte Direction; + public byte Latch; - static public byte ExternalWrite(byte latch, byte val, byte dir) - { - byte result; - result = (byte)(latch & dir); - result |= (byte)(val & (dir ^ 0xFF)); - return result; - } + public LatchedPort() + { + Direction = 0x00; + Latch = 0x00; + } - static public PortAdapter GetAdapter(Func newRead, Action newWrite, Action newWriteForce) - { - return new PortAdapter(newRead, newWrite, newWriteForce); - } - } + // data works like this in these types of systems: + // + // directionA directionB result + // 0 0 1 + // 1 0 latchA + // 0 1 latchB + // 1 1 latchA && latchB + // + // however because this uses transistor logic, there are cases where wired-ands + // cause the pull-up resistors not to be enough to keep the bus bit set to 1 when + // both the direction and latch are 1 (the keyboard and joystick port 2 can do this.) + // the class does not handle this case as it must be handled differently in every occurrence. - public class PortAdapter - { - private Action actWrite; - private Action actWriteMask; - private Func funcRead; + public byte ReadInput(byte bus) + { + return (byte)((Latch & Direction) | ((Direction ^ 0xFF) & bus)); + } - public PortAdapter(Func newRead, Action newWrite, Action newWriteMask) - { - funcRead = newRead; - actWrite = newWrite; - actWriteMask = newWriteMask; - } - - public byte Data - { - get - { - return funcRead(); - } - set - { - actWrite(value); - } - } - - public void MaskWrite(byte val) - { - actWriteMask(val); - } - } + public byte ReadOutput() + { + return (byte)((Latch & Direction) | (Direction ^ 0xFF)); + } + } } diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/Timer.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/Timer.cs index 4a87ca64ab..86271a74ee 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/Timer.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/Timer.cs @@ -7,22 +7,20 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS public abstract class Timer { protected bool pinIRQ; - protected uint[] timer; + protected LatchedPort portA; + protected LatchedPort portB; + protected uint[] timer; protected uint[] timerLatch; protected bool[] timerOn; protected bool[] underflow; - public Func ReadDirA = (() => { return 0xFF; }); - public Func ReadDirB = (() => { return 0xFF; }); public Func ReadPortA = (() => { return 0xFF; }); public Func ReadPortB = (() => { return 0xFF; }); - public Action WriteDirA = ((byte val) => { }); - public Action WriteDirB = ((byte val) => { }); - public Action WritePortA = ((byte val) => { }); - public Action WritePortB = ((byte val) => { }); public Timer() { + portA = new LatchedPort(); + portB = new LatchedPort(); timer = new uint[2]; timerLatch = new uint[2]; timerOn = new bool[2]; @@ -31,8 +29,6 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS protected void HardResetInternal() { - WriteDirA(0x00); - WriteDirB(0x00); timer[0] = 0xFFFF; timer[1] = 0xFFFF; timerLatch[0] = timer[0]; @@ -48,6 +44,22 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS } } + public byte PortAData + { + get + { + return portA.ReadOutput(); + } + } + + public byte PortBData + { + get + { + return portB.ReadOutput(); + } + } + protected void SyncInternal(Serializer ser) { ser.Sync("pinIRQ", ref pinIRQ);