diff --git a/BizHawk.Emulation/BizHawk.Emulation.csproj b/BizHawk.Emulation/BizHawk.Emulation.csproj index 6c1441f4d4..a44ccc9d0b 100644 --- a/BizHawk.Emulation/BizHawk.Emulation.csproj +++ b/BizHawk.Emulation/BizHawk.Emulation.csproj @@ -82,6 +82,7 @@ + diff --git a/BizHawk.Emulation/Computers/Commodore64/C64.Core.cs b/BizHawk.Emulation/Computers/Commodore64/C64.Core.cs index 3fa7671363..cf34875580 100644 --- a/BizHawk.Emulation/Computers/Commodore64/C64.Core.cs +++ b/BizHawk.Emulation/Computers/Commodore64/C64.Core.cs @@ -44,6 +44,9 @@ namespace BizHawk.Emulation.Computers.Commodore64 // configure video CoreOutputComm.VsyncDen = chips.vic.CyclesPerFrame; CoreOutputComm.VsyncNum = chips.vic.CyclesPerSecond; + + // configure input + InitInput(); } private void InitMedia() @@ -103,6 +106,7 @@ namespace BizHawk.Emulation.Computers.Commodore64 { for (; count > 0; count--) { + WriteInputPort(); chips.ExecutePhase1(); chips.ExecutePhase2(); } diff --git a/BizHawk.Emulation/Computers/Commodore64/C64.Input.cs b/BizHawk.Emulation/Computers/Commodore64/C64.Input.cs new file mode 100644 index 0000000000..59aa805c6e --- /dev/null +++ b/BizHawk.Emulation/Computers/Commodore64/C64.Input.cs @@ -0,0 +1,151 @@ +using BizHawk.Emulation.Computers.Commodore64.MOS; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace BizHawk.Emulation.Computers.Commodore64 +{ + public partial class C64 : IEmulator + { + private PortAdapter inputAdapter0; + private PortAdapter inputAdapter1; + private byte[] joystickMatrix = new byte[2]; + private byte[] keyboardMatrix = new byte[8]; + + private void InitInput() + { + inputAdapter0 = chips.cia0.Adapter0; + inputAdapter1 = chips.cia0.Adapter1; + } + + private void PollInput() + { + joystickMatrix[0] = 0xFF; + joystickMatrix[0] &= controller["P1 Up"] ? (byte)0xFE : (byte)0xFF; + joystickMatrix[0] &= controller["P1 Down"] ? (byte)0xFD : (byte)0xFF; + joystickMatrix[0] &= controller["P1 Left"] ? (byte)0xFB : (byte)0xFF; + joystickMatrix[0] &= controller["P1 Right"] ? (byte)0xF7 : (byte)0xFF; + joystickMatrix[0] &= controller["P1 Button"] ? (byte)0xEF : (byte)0xFF; + + joystickMatrix[1] = 0xFF; + joystickMatrix[1] &= controller["P2 Up"] ? (byte)0xFE : (byte)0xFF; + joystickMatrix[1] &= controller["P2 Down"] ? (byte)0xFD : (byte)0xFF; + joystickMatrix[1] &= controller["P2 Left"] ? (byte)0xFB : (byte)0xFF; + joystickMatrix[1] &= controller["P2 Right"] ? (byte)0xF7 : (byte)0xFF; + joystickMatrix[1] &= controller["P2 Button"] ? (byte)0xEF : (byte)0xFF; + + keyboardMatrix[0] = 0xFF; + keyboardMatrix[0] &= controller["Key Insert/Delete"] ? (byte)0xFE : (byte)0xFF; + keyboardMatrix[0] &= controller["Key Return"] ? (byte)0xFD : (byte)0xFF; + keyboardMatrix[0] &= controller["Key Cursor Left/Right"] ? (byte)0xFB : (byte)0xFF; + keyboardMatrix[0] &= controller["Key F7"] ? (byte)0xF7 : (byte)0xFF; + keyboardMatrix[0] &= controller["Key F1"] ? (byte)0xEF : (byte)0xFF; + keyboardMatrix[0] &= controller["Key F3"] ? (byte)0xDF : (byte)0xFF; + keyboardMatrix[0] &= controller["Key F5"] ? (byte)0xBF : (byte)0xFF; + keyboardMatrix[0] &= controller["Key Cursor Up/Down"] ? (byte)0x7F : (byte)0xFF; + + keyboardMatrix[1] = 0xFF; + keyboardMatrix[1] &= controller["Key 3"] ? (byte)0xFE : (byte)0xFF; + keyboardMatrix[1] &= controller["Key W"] ? (byte)0xFD : (byte)0xFF; + keyboardMatrix[1] &= controller["Key A"] ? (byte)0xFB : (byte)0xFF; + keyboardMatrix[1] &= controller["Key 4"] ? (byte)0xF7 : (byte)0xFF; + keyboardMatrix[1] &= controller["Key Z"] ? (byte)0xEF : (byte)0xFF; + keyboardMatrix[1] &= controller["Key S"] ? (byte)0xDF : (byte)0xFF; + keyboardMatrix[1] &= controller["Key E"] ? (byte)0xBF : (byte)0xFF; + keyboardMatrix[1] &= controller["Key Left Shift"] ? (byte)0x7F : (byte)0xFF; + + keyboardMatrix[2] = 0xFF; + keyboardMatrix[2] &= controller["Key 5"] ? (byte)0xFE : (byte)0xFF; + keyboardMatrix[2] &= controller["Key R"] ? (byte)0xFD : (byte)0xFF; + keyboardMatrix[2] &= controller["Key D"] ? (byte)0xFB : (byte)0xFF; + keyboardMatrix[2] &= controller["Key 6"] ? (byte)0xF7 : (byte)0xFF; + keyboardMatrix[2] &= controller["Key C"] ? (byte)0xEF : (byte)0xFF; + keyboardMatrix[2] &= controller["Key F"] ? (byte)0xDF : (byte)0xFF; + keyboardMatrix[2] &= controller["Key T"] ? (byte)0xBF : (byte)0xFF; + keyboardMatrix[2] &= controller["Key X"] ? (byte)0x7F : (byte)0xFF; + + keyboardMatrix[3] = 0xFF; + keyboardMatrix[3] &= controller["Key 7"] ? (byte)0xFE : (byte)0xFF; + keyboardMatrix[3] &= controller["Key Y"] ? (byte)0xFD : (byte)0xFF; + keyboardMatrix[3] &= controller["Key G"] ? (byte)0xFB : (byte)0xFF; + keyboardMatrix[3] &= controller["Key 8"] ? (byte)0xF7 : (byte)0xFF; + keyboardMatrix[3] &= controller["Key B"] ? (byte)0xEF : (byte)0xFF; + keyboardMatrix[3] &= controller["Key H"] ? (byte)0xDF : (byte)0xFF; + keyboardMatrix[3] &= controller["Key U"] ? (byte)0xBF : (byte)0xFF; + keyboardMatrix[3] &= controller["Key V"] ? (byte)0x7F : (byte)0xFF; + + keyboardMatrix[4] = 0xFF; + keyboardMatrix[4] &= controller["Key 9"] ? (byte)0xFE : (byte)0xFF; + keyboardMatrix[4] &= controller["Key I"] ? (byte)0xFD : (byte)0xFF; + keyboardMatrix[4] &= controller["Key J"] ? (byte)0xFB : (byte)0xFF; + keyboardMatrix[4] &= controller["Key 0"] ? (byte)0xF7 : (byte)0xFF; + keyboardMatrix[4] &= controller["Key M"] ? (byte)0xEF : (byte)0xFF; + keyboardMatrix[4] &= controller["Key K"] ? (byte)0xDF : (byte)0xFF; + keyboardMatrix[4] &= controller["Key O"] ? (byte)0xBF : (byte)0xFF; + keyboardMatrix[4] &= controller["Key N"] ? (byte)0x7F : (byte)0xFF; + + keyboardMatrix[5] = 0xFF; + keyboardMatrix[5] &= controller["Key Plus"] ? (byte)0xFE : (byte)0xFF; + keyboardMatrix[5] &= controller["Key P"] ? (byte)0xFD : (byte)0xFF; + keyboardMatrix[5] &= controller["Key L"] ? (byte)0xFB : (byte)0xFF; + keyboardMatrix[5] &= controller["Key Minus"] ? (byte)0xF7 : (byte)0xFF; + keyboardMatrix[5] &= controller["Key Period"] ? (byte)0xEF : (byte)0xFF; + keyboardMatrix[5] &= controller["Key Colon"] ? (byte)0xDF : (byte)0xFF; + keyboardMatrix[5] &= controller["Key At"] ? (byte)0xBF : (byte)0xFF; + keyboardMatrix[5] &= controller["Key Comma"] ? (byte)0x7F : (byte)0xFF; + + keyboardMatrix[6] = 0xFF; + keyboardMatrix[6] &= controller["Key Pound"] ? (byte)0xFE : (byte)0xFF; + keyboardMatrix[6] &= controller["Key Asterisk"] ? (byte)0xFD : (byte)0xFF; + keyboardMatrix[6] &= controller["Key Semicolon"] ? (byte)0xFB : (byte)0xFF; + keyboardMatrix[6] &= controller["Key Clear/Home"] ? (byte)0xF7 : (byte)0xFF; + keyboardMatrix[6] &= controller["Key Right Shift"] ? (byte)0xEF : (byte)0xFF; + keyboardMatrix[6] &= controller["Key Equal"] ? (byte)0xDF : (byte)0xFF; + keyboardMatrix[6] &= controller["Key Up Arrow"] ? (byte)0xBF : (byte)0xFF; + keyboardMatrix[6] &= controller["Key Slash"] ? (byte)0x7F : (byte)0xFF; + + keyboardMatrix[7] = 0xFF; + keyboardMatrix[7] &= controller["Key 1"] ? (byte)0xFE : (byte)0xFF; + keyboardMatrix[7] &= controller["Key Left Arrow"] ? (byte)0xFD : (byte)0xFF; + keyboardMatrix[7] &= controller["Key Control"] ? (byte)0xFB : (byte)0xFF; + keyboardMatrix[7] &= controller["Key 2"] ? (byte)0xF7 : (byte)0xFF; + keyboardMatrix[7] &= controller["Key Space"] ? (byte)0xEF : (byte)0xFF; + keyboardMatrix[7] &= controller["Key Commodore"] ? (byte)0xDF : (byte)0xFF; + keyboardMatrix[7] &= controller["Key Q"] ? (byte)0xBF : (byte)0xFF; + keyboardMatrix[7] &= controller["Key Run/Stop"] ? (byte)0x7F : (byte)0xFF; + } + + private void WriteInputPort() + { + inputAdapter0.Data = 0xFF; + inputAdapter1.Data = 0xFF; + + byte portA = inputAdapter0.Data; + byte portB = inputAdapter1.Data; + + if ((portA & 0x01) == 0) + portB &= keyboardMatrix[0]; + if ((portA & 0x02) == 0) + portB &= keyboardMatrix[1]; + if ((portA & 0x04) == 0) + portB &= keyboardMatrix[2]; + if ((portA & 0x08) == 0) + portB &= keyboardMatrix[3]; + if ((portA & 0x10) == 0) + portB &= keyboardMatrix[4]; + if ((portA & 0x20) == 0) + portB &= keyboardMatrix[5]; + if ((portA & 0x40) == 0) + portB &= keyboardMatrix[6]; + if ((portA & 0x80) == 0) + portB &= keyboardMatrix[7]; + + portA &= joystickMatrix[1]; + portB &= joystickMatrix[0]; + + inputAdapter0.Data = portA; + inputAdapter1.Data = portB; + } + } +} diff --git a/BizHawk.Emulation/Computers/Commodore64/C64.cs b/BizHawk.Emulation/Computers/Commodore64/C64.cs index 36ea23dd8a..e75c4474cd 100644 --- a/BizHawk.Emulation/Computers/Commodore64/C64.cs +++ b/BizHawk.Emulation/Computers/Commodore64/C64.cs @@ -9,6 +9,7 @@ namespace BizHawk.Emulation.Computers.Commodore64 { public partial class C64 : IEmulator { + private IController controller; private uint cyclesPerFrame; private string extension; private byte[] inputFile; @@ -64,7 +65,7 @@ namespace BizHawk.Emulation.Computers.Commodore64 // controller public ControllerDefinition ControllerDefinition { get { return C64ControllerDefinition; } } - public IController Controller { get { return null; } set { } } + public IController Controller { get { return controller; } set { controller = value; } } public static readonly ControllerDefinition C64ControllerDefinition = new ControllerDefinition { Name = "Commodore 64 Controller", //TODO @@ -89,6 +90,7 @@ namespace BizHawk.Emulation.Computers.Commodore64 // process frame public void FrameAdvance(bool render, bool rendersound) { + PollInput(); chips.pla.InputWasRead = false; Execute(cyclesPerFrame); _islag = !chips.pla.InputWasRead; diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6526.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6526.cs index efadf816b5..ef6aa82f2f 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6526.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6526.cs @@ -41,8 +41,18 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS Output } + private static byte[] PBOnBit = new byte[] { 0x40, 0x80 }; + private static byte[] PBOnMask = new byte[] { 0xBF, 0x7F }; + // ------------------------------------ + private bool alarmSelect; + private Region chipRegion; + private bool cntPos; + private bool enableIntAlarm; + private bool enableIntFlag; + private bool enableIntSP; + private bool[] enableIntTimer; private bool intAlarm; private bool intFlag; private bool intSP; @@ -50,35 +60,37 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS private bool pinCnt; private bool pinFlag; private bool pinPC; + private byte sr; private InMode[] timerInMode; private OutMode[] timerOutMode; private bool[] timerPortEnable; + private bool[] timerPulse; + private RunMode[] timerRunMode; + private SPMode timerSPMode; private byte[] tod; private byte[] todAlarm; private bool todAlarmPM; - private bool todPM; private uint todCounter; private uint todCounterLatch; + private bool todIn; + private bool todPM; // ------------------------------------ public MOS6526(Region region) { + chipRegion = region; + enableIntTimer = new bool[2]; intTimer = new bool[2]; timerInMode = new InMode[2]; timerOutMode = new OutMode[2]; timerPortEnable = new bool[2]; + timerPulse = new bool[2]; + timerRunMode = new RunMode[2]; tod = new byte[4]; todAlarm = new byte[4]; - switch (region) - { - case Region.NTSC: - todCounterLatch = 14318181 / 140; - break; - case Region.PAL: - todCounterLatch = 17734472 / 180; - break; - } + + SetTodIn(chipRegion); HardReset(); } @@ -92,15 +104,51 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS public void ExecutePhase2() { pinPC = true; + TODRun(); + + if (timerPulse[0]) + portData[0] &= PBOnMask[0]; + if (timerPulse[1]) + portData[1] &= PBOnMask[0]; + TimerRun(0); TimerRun(1); + intAlarm |= ( + tod[0] == todAlarm[0] && + tod[1] == todAlarm[1] && + tod[2] == todAlarm[2] && + tod[3] == todAlarm[3] && + todPM == todAlarmPM); + + cntPos = false; + underflow[0] = false; + underflow[1] = false; + + pinIRQ = !( + (intTimer[0] && enableIntTimer[0]) || + (intTimer[1] && enableIntTimer[1]) || + (intAlarm && enableIntAlarm) || + (intSP && enableIntSP) || + (intFlag && enableIntFlag) + ); } public void HardReset() { HardResetInternal(); + alarmSelect = false; + cntPos = false; + enableIntAlarm = false; + enableIntFlag = false; + enableIntSP = false; + enableIntTimer[0] = false; + enableIntTimer[1] = false; + intAlarm = false; + intFlag = false; + intSP = false; intTimer[0] = false; intTimer[1] = false; + sr = 0; timerPortEnable[0] = false; timerPortEnable[1] = false; timerInMode[0] = InMode.Phase2; @@ -109,6 +157,13 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS timerOn[1] = false; timerOutMode[0] = OutMode.Pulse; timerOutMode[1] = OutMode.Pulse; + timerPortEnable[0] = false; + timerPortEnable[1] = false; + timerPulse[0] = false; + timerPulse[1] = false; + timerRunMode[0] = RunMode.Continuous; + timerRunMode[1] = RunMode.Continuous; + timerSPMode = SPMode.Input; tod[0] = 0; tod[1] = 0; tod[2] = 0; @@ -118,9 +173,27 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS todAlarm[2] = 0; todAlarm[3] = 0; todCounter = todCounterLatch; + todIn = (chipRegion == Region.PAL); + todPM = false; + pinCnt = false; pinFlag = true; pinPC = true; + } + + private void SetTodIn(Region region) + { + switch (region) + { + case Region.NTSC: + todCounterLatch = 14318181 / 140; + todIn = false; + break; + case Region.PAL: + todCounterLatch = 17734472 / 180; + todIn = true; + break; + } } // ------------------------------------ @@ -149,7 +222,76 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS private void TimerRun(uint index) { + if (timerOn[index]) + { + uint t = timer[index]; + bool u = false; + unchecked + { + switch (timerInMode[index]) + { + case InMode.CNT: + // CNT positive + if (cntPos) + { + u = (t == 0); + t--; + } + break; + case InMode.Phase2: + // every clock + u = (t == 0); + t--; + break; + case InMode.TimerAUnderflow: + // every underflow[0] + if (underflow[0]) + { + u = (t == 0); + t--; + } + break; + case InMode.TimerAUnderflowCNT: + // every underflow[0] while CNT high + if (underflow[0] && pinCnt) + { + u = (t == 0); + t--; + } + break; + } + + // underflow? + if (u) + { + t = timerLatch[index]; + if (timerRunMode[index] == RunMode.Oneshot) + timerOn[index] = false; + + if (timerPortEnable[index]) + { + // force port B bit to output + portDir[index] |= PBOnBit[index]; + switch (timerOutMode[index]) + { + case OutMode.Pulse: + timerPulse[index] = true; + portData[index] |= PBOnBit[index]; + break; + case OutMode.Toggle: + portData[index] ^= PBOnBit[index]; + break; + } + } + + intTimer[index] = true; + } + + underflow[index] = u; + timer[index] = t; + } + } } private void TODRun() @@ -184,6 +326,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS } } } + todCounter--; } // ------------------------------------ @@ -191,7 +334,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS public bool CNT { get { return pinCnt; } - set { pinCnt = value; } + set { cntPos |= (!pinCnt && value); pinCnt = value; } } public bool FLAG @@ -236,6 +379,15 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS val = ReadRegister(addr); pinPC = false; break; + case 0x0D: + val = ReadRegister(addr); + intTimer[0] = false; + intTimer[1] = false; + intAlarm = false; + intSP = false; + intFlag = false; + pinIRQ = true; + break; default: val = ReadRegister(addr); break; @@ -264,28 +416,77 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS val = portDir[1]; break; case 0x4: + val = (byte)(timer[0] & 0xFF); break; case 0x5: + val = (byte)(timer[0] >> 8); break; case 0x6: + val = (byte)(timer[1] & 0xFF); break; case 0x7: + val = (byte)(timer[1] >> 8); break; case 0x8: + val = tod[0]; break; case 0x9: + val = tod[1]; break; case 0xA: + val = tod[2]; break; case 0xB: + val = tod[3]; break; case 0xC: + val = sr; break; case 0xD: + val = (byte)( + (intTimer[0] ? 0x01 : 0x00) | + (intTimer[1] ? 0x02 : 0x00) | + (intAlarm ? 0x04 : 0x00) | + (intSP ? 0x08 : 0x00) | + (intFlag ? 0x10 : 0x00) | + (!pinIRQ ? 0x80 : 0x00) + ); break; case 0xE: + val = (byte)( + (timerOn[0] ? 0x01 : 0x00) | + (timerPortEnable[0] ? 0x02 : 0x00) | + (todIn ? 0x80 : 0x00)); + if (timerOutMode[0] == OutMode.Toggle) + val |= 0x04; + if (timerRunMode[0] == RunMode.Oneshot) + val |= 0x08; + if (timerInMode[0] == InMode.CNT) + val |= 0x20; + if (timerSPMode == SPMode.Output) + val |= 0x40; break; case 0xF: + val = (byte)( + (timerOn[1] ? 0x01 : 0x00) | + (timerPortEnable[1] ? 0x02 : 0x00) | + (alarmSelect ? 0x80 : 0x00)); + if (timerOutMode[1] == OutMode.Toggle) + val |= 0x04; + if (timerRunMode[1] == RunMode.Oneshot) + val |= 0x08; + switch (timerInMode[1]) + { + case InMode.CNT: + val |= 0x20; + break; + case InMode.TimerAUnderflow: + val |= 0x40; + break; + case InMode.TimerAUnderflowCNT: + val |= 0x60; + break; + } break; } @@ -299,9 +500,9 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS public void Write(ushort addr, byte val, byte mask) { + addr &= 0xF; val &= mask; val |= (byte)(ReadRegister(addr) & ~mask); - addr &= 0xF; switch (addr) { @@ -312,6 +513,26 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS WritePort1(val); pinPC = false; break; + case 0x5: + WriteRegister(addr, val); + if (!timerOn[0]) + timer[0] = timerLatch[0]; + break; + case 0x7: + WriteRegister(addr, val); + if (!timerOn[1]) + timer[1] = timerLatch[1]; + break; + case 0xE: + WriteRegister(addr, val); + if ((val & 0x10) != 0) + timer[0] = timerLatch[0]; + break; + case 0xF: + WriteRegister(addr, val); + if ((val & 0x10) != 0) + timer[1] = timerLatch[1]; + break; default: WriteRegister(addr, val); break; @@ -320,6 +541,8 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS public void WriteRegister(ushort addr, byte val) { + bool intReg; + switch (addr) { case 0x0: @@ -335,28 +558,89 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS portDir[1] = val; break; case 0x4: + timerLatch[0] &= 0xFF00; + timerLatch[0] |= val; break; case 0x5: + timerLatch[0] &= 0x00FF; + timerLatch[0] |= (uint)val << 8; break; case 0x6: + timerLatch[1] &= 0xFF00; + timerLatch[1] |= val; break; case 0x7: + timerLatch[1] &= 0x00FF; + timerLatch[1] |= (uint)val << 8; break; case 0x8: + if (alarmSelect) + todAlarm[0] = (byte)(val & 0xF); + else + tod[0] = (byte)(val & 0xF); break; case 0x9: + if (alarmSelect) + todAlarm[1] = (byte)(val & 0x7F); + else + tod[1] = (byte)(val & 0x7F); break; case 0xA: + if (alarmSelect) + todAlarm[2] = (byte)(val & 0x7F); + else + tod[2] = (byte)(val & 0x7F); break; case 0xB: + if (alarmSelect) + { + todAlarm[3] = (byte)(val & 0x1F); + todAlarmPM = ((val & 0x80) != 0); + } + else + { + tod[3] = (byte)(val & 0x1F); + todPM = ((val & 0x80) != 0); + } break; case 0xC: + sr = val; break; case 0xD: + intReg = ((val & 0x80) != 0); + if ((val & 0x01) != 0) + enableIntTimer[0] = intReg; + if ((val & 0x02) != 0) + enableIntTimer[1] = intReg; + if ((val & 0x04) != 0) + enableIntAlarm = intReg; + if ((val & 0x08) != 0) + enableIntSP = intReg; + if ((val & 0x10) != 0) + enableIntFlag = intReg; break; case 0xE: + timerOn[0] = ((val & 0x01) != 0); + timerPortEnable[0] = ((val & 0x02) != 0); + timerOutMode[0] = ((val & 0x04) != 0) ? OutMode.Toggle : OutMode.Pulse; + timerRunMode[0] = ((val & 0x08) != 0) ? RunMode.Oneshot : RunMode.Continuous; + timerInMode[0] = ((val & 0x20) != 0) ? InMode.CNT : InMode.Phase2; + timerSPMode = ((val & 0x40) != 0) ? SPMode.Output : SPMode.Input; + todIn = ((val & 0x80) != 0); break; case 0xF: + timerOn[1] = ((val & 0x01) != 0); + timerPortEnable[1] = ((val & 0x02) != 0); + timerOutMode[1] = ((val & 0x04) != 0) ? OutMode.Toggle : OutMode.Pulse; + timerRunMode[1] = ((val & 0x08) != 0) ? RunMode.Oneshot : RunMode.Continuous; + switch (val & 0x60) + { + case 0x00: timerInMode[1] = InMode.Phase2; break; + case 0x20: timerInMode[1] = InMode.CNT; break; + case 0x40: timerInMode[1] = InMode.TimerAUnderflow; break; + case 0x60: timerInMode[1] = InMode.TimerAUnderflowCNT; break; + } + alarmSelect = ((val & 0x80) != 0); break; } } diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/MOSPLA.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/MOSPLA.cs index d70cfb0ba0..b901a7e370 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/MOSPLA.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/MOSPLA.cs @@ -555,7 +555,6 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS case PLABank.None: break; case PLABank.RAM: - chips.ram.Write(addr, val); break; case PLABank.Sid: chips.sid.Write(addr, val); @@ -564,6 +563,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS chips.vic.Write(addr, val); break; } + chips.ram.Write(addr, val); } } } diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/Timer.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/Timer.cs index 473a5b3af1..cc46fd44ea 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/Timer.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/Timer.cs @@ -15,6 +15,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS protected uint[] timer; protected uint[] timerLatch; protected bool[] timerOn; + protected bool[] underflow; public Timer() { @@ -23,16 +24,23 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS timer = new uint[2]; timerLatch = new uint[2]; timerOn = new bool[2]; + underflow = new bool[2]; } - public PortAdapter Adapter0() + public PortAdapter Adapter0 { - return Port.GetAdapter(ReadPort0, ExternalWritePort0); + get + { + return Port.GetAdapter(ReadPort0, ExternalWritePort0); + } } - public PortAdapter Adapter1() + public PortAdapter Adapter1 { - return Port.GetAdapter(ReadPort1, ExternalWritePort1); + get + { + return Port.GetAdapter(ReadPort1, ExternalWritePort1); + } } private void ExternalWritePort(uint index, byte data)