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)