From c5d6fad0e19f41696b497654a0b4efbabc72c136 Mon Sep 17 00:00:00 2001 From: saxxonpike Date: Thu, 15 Nov 2012 07:41:59 +0000 Subject: [PATCH] commodore64: CIA timer underflow interrupts implemented (BASIC now works) --- .../Computers/Commodore64/C64.core.cs | 1 + .../Computers/Commodore64/C64.cs | 2 ++ .../Computers/Commodore64/Cia.cs | 31 +++++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/BizHawk.Emulation/Computers/Commodore64/C64.core.cs b/BizHawk.Emulation/Computers/Commodore64/C64.core.cs index ee0c4ade09..78eb1f66ef 100644 --- a/BizHawk.Emulation/Computers/Commodore64/C64.core.cs +++ b/BizHawk.Emulation/Computers/Commodore64/C64.core.cs @@ -71,6 +71,7 @@ namespace BizHawk.Emulation.Computers.Commodore64 // initialize cpu hard reset vector cpu.PC = (ushort)(ReadMemory(0xFFFC) + (ReadMemory(0xFFFD) << 8)); + cpu.BCD_Enabled = true; // initailize input input = new Input( new DataPortConnector[] { cia0.ConnectPort(0), cia0.ConnectPort(1) } ); diff --git a/BizHawk.Emulation/Computers/Commodore64/C64.cs b/BizHawk.Emulation/Computers/Commodore64/C64.cs index 5cecb6be53..0139966dc8 100644 --- a/BizHawk.Emulation/Computers/Commodore64/C64.cs +++ b/BizHawk.Emulation/Computers/Commodore64/C64.cs @@ -103,7 +103,9 @@ namespace BizHawk.Emulation.Computers.Commodore64 if (diskDriveAttached) diskDrive.PerformCycle(); cia0.PerformCycle(); + signal.CiaIRQ0 = cia0.IRQ; cia1.PerformCycle(); + signal.CiaIRQ1 = cia1.IRQ; } if (_islag) diff --git a/BizHawk.Emulation/Computers/Commodore64/Cia.cs b/BizHawk.Emulation/Computers/Commodore64/Cia.cs index b390ed6e3d..0e903e2524 100644 --- a/BizHawk.Emulation/Computers/Commodore64/Cia.cs +++ b/BizHawk.Emulation/Computers/Commodore64/Cia.cs @@ -13,6 +13,10 @@ namespace BizHawk.Emulation.Computers.Commodore64 public int ALARMMIN; // alarm minutes public bool ALARMPM; // alarm AM/PM public int ALARMSEC; // alarm seconds + public bool EIALARM; // enable alarm interrupt (internal) + public bool EIFLAG; // enable flag pin interrupt (internal) + public bool EISP; // enable shift register interrupt (internal) + public bool[] EIT = new bool[2]; // enable timer interrupt (internal) public bool IALARM; // alarm interrupt triggered public bool IFLG; // interrupt triggered on FLAG pin public int[] INMODE = new int[2]; // timer input mode @@ -348,6 +352,14 @@ namespace BizHawk.Emulation.Computers.Commodore64 todCounter = todFrequency; } + public bool IRQ + { + get + { + return regs.IRQ; + } + } + public byte Peek(int addr) { addr &= 0xF; @@ -394,6 +406,8 @@ namespace BizHawk.Emulation.Computers.Commodore64 } } } + + UpdateInterrupt(); } public void Poke(int addr, byte val) @@ -463,6 +477,7 @@ namespace BizHawk.Emulation.Computers.Commodore64 underflow[index] = false; } + regs.IT[index] |= underflow[index]; regs.T[index] = timer; } @@ -488,6 +503,17 @@ namespace BizHawk.Emulation.Computers.Commodore64 } } + public void UpdateInterrupt() + { + bool irq = false; + irq |= (regs.EIT[0] & regs.IT[0]); + irq |= (regs.EIT[1] & regs.IT[1]); + irq |= (regs.EIFLAG & regs.IFLG); + irq |= (regs.EISP & regs.ISP); + irq |= (regs.EIALARM & regs.IALARM); + regs.IRQ = irq; + } + public void Write(ushort addr, byte val) { addr &= 0xF; @@ -550,6 +576,11 @@ namespace BizHawk.Emulation.Computers.Commodore64 intMask &= ~val; if ((val & 0x80) != 0x00) intMask ^= val; + regs.EIT[0] = ((intMask & 0x01) != 0x00); + regs.EIT[1] = ((intMask & 0x02) != 0x00); + regs.EIALARM = ((intMask & 0x04) != 0x00); + regs.EISP = ((intMask & 0x08) != 0x00); + regs.EIFLAG = ((intMask & 0x10) != 0x00); break; default: regs[addr] = val;