From 420bad0a2e26f026f5ab05aa5801bfd0183007af Mon Sep 17 00:00:00 2001 From: beirich Date: Sun, 13 Mar 2011 02:22:29 +0000 Subject: [PATCH] HuC6280: Accepting an interrupt takes 8 cycles; Correcting handling of T flag on RTI and PLP instructions; 1-cycle penalty for accesses across page boundaries does not apply --- BizHawk.Emulation/CPUs/HuC6280/Execute.cs | 38 +++++------------------ CpuCoreGenerator/HuC6280/CoreGenerator.cs | 22 +++++-------- CpuCoreGenerator/HuC6280/Instructions.cs | 2 ++ 3 files changed, 17 insertions(+), 45 deletions(-) diff --git a/BizHawk.Emulation/CPUs/HuC6280/Execute.cs b/BizHawk.Emulation/CPUs/HuC6280/Execute.cs index 14357e2c49..721350256b 100644 --- a/BizHawk.Emulation/CPUs/HuC6280/Execute.cs +++ b/BizHawk.Emulation/CPUs/HuC6280/Execute.cs @@ -22,28 +22,26 @@ namespace BizHawk.Emulation.CPUs.H6280 if (IRQ1Assert && FlagI == false && LagIFlag == false && (IRQControlByte & IRQ1Selector) == 0) { - FlagB = false; + //Log.Note("CPU", "ENTERING IRQ1 INTERRUPT"); WriteMemory((ushort)(S-- + 0x2100), (byte)(PC >> 8)); WriteMemory((ushort)(S-- + 0x2100), (byte)PC); - WriteMemory((ushort)(S-- + 0x2100), P); + WriteMemory((ushort)(S-- + 0x2100), (byte)(P & (~0x10))); FlagD = false; FlagI = true; PC = ReadWord(IRQ1Vector); - PendingCycles -= 7; - //Log.Note("CPU", "ENTERING IRQ1 INTERRUPT"); + PendingCycles -= 8; } if (TimerAssert && FlagI == false && LagIFlag == false && (IRQControlByte & TimerSelector) == 0) { - FlagB = false; + //Log.Note("CPU", "ENTERING __TIMER__ INTERRUPT"); WriteMemory((ushort)(S-- + 0x2100), (byte)(PC >> 8)); WriteMemory((ushort)(S-- + 0x2100), (byte)PC); - WriteMemory((ushort)(S-- + 0x2100), P); + WriteMemory((ushort)(S-- + 0x2100), (byte)(P & (~0x10))); FlagD = false; FlagI = true; PC = ReadWord(TimerVector); - PendingCycles -= 7; - //Log.Note("CPU", "ENTERING __TIMER__ INTERRUPT"); + PendingCycles -= 8; } IRQControlByte = IRQNextControlByte; @@ -250,8 +248,6 @@ throw new Exception("break"); break; case 0x1E: // ASL addr,X value16 = (ushort)(ReadWord(PC)+X); - if ((PC & 0xFF00) != ((PC+Y) & 0xFF00)) - PendingCycles--; PC += 2; value8 = ReadMemory(value16); FlagC = (value8 & 0x80) != 0; @@ -341,7 +337,7 @@ throw new Exception("break"); case 0x28: // PLP P = ReadMemory((ushort)(++S + 0x2100)); PendingCycles -= 4; - break; + goto AfterClearTFlag; case 0x29: // AND #nn value8 = ReadMemory(PC++); if (FlagT == false) { @@ -533,8 +529,6 @@ throw new Exception("break"); break; case 0x3E: // ROL addr,X value16 = (ushort)(ReadWord(PC)+X); - if ((PC & 0xFF00) != ((PC+Y) & 0xFF00)) - PendingCycles--; PC += 2; value8 = temp8 = ReadMemory(value16); value8 = (byte)((value8 << 1) | (P & 1)); @@ -557,7 +551,7 @@ throw new Exception("break"); PC = ReadMemory((ushort)(++S + 0x2100)); PC |= (ushort)(ReadMemory((ushort)(++S + 0x2100)) << 8); PendingCycles -= 7; - break; + goto AfterClearTFlag; case 0x41: // EOR (addr,X) value8 = ReadMemory(ReadWordPageWrap((ushort)((byte)(ReadMemory(PC++)+X)+0x2000))); if (FlagT == false) { @@ -815,8 +809,6 @@ throw new Exception("break"); break; case 0x5E: // LSR addr,X value16 = (ushort)(ReadWord(PC)+X); - if ((PC & 0xFF00) != ((PC+Y) & 0xFF00)) - PendingCycles--; PC += 2; value8 = ReadMemory(value16); FlagC = (value8 & 1) != 0; @@ -1241,8 +1233,6 @@ throw new Exception("break"); break; case 0x7E: // ROR addr,X value16 = (ushort)(ReadWord(PC)+X); - if ((PC & 0xFF00) != ((PC+Y) & 0xFF00)) - PendingCycles--; PC += 2; value8 = temp8 = ReadMemory(value16); value8 = (byte)((value8 >> 1) | ((P & 1)<<7)); @@ -1356,8 +1346,6 @@ throw new Exception("break"); case 0x91: // STA (addr),Y temp16 = ReadWordPageWrap((ushort)(ReadMemory(PC++)+0x2000)); value16 = (ushort)(temp16+Y); - if ((temp16 & 0xFF00) != ((temp16+Y) & 0xFF00)) - PendingCycles--; WriteMemory(value16, A); PendingCycles -= 7; break; @@ -1403,8 +1391,6 @@ throw new Exception("break"); break; case 0x99: // STA addr,Y value16 = (ushort)(ReadWord(PC)+Y); - if ((PC & 0xFF00) != ((PC+Y) & 0xFF00)) - PendingCycles--; PC += 2; WriteMemory(value16, A); PendingCycles -= 5; @@ -1420,16 +1406,12 @@ throw new Exception("break"); break; case 0x9D: // STA addr,X value16 = (ushort)(ReadWord(PC)+X); - if ((PC & 0xFF00) != ((PC+Y) & 0xFF00)) - PendingCycles--; PC += 2; WriteMemory(value16, A); PendingCycles -= 5; break; case 0x9E: // STZ addr,X value16 = (ushort)(ReadWord(PC)+X); - if ((PC & 0xFF00) != ((PC+Y) & 0xFF00)) - PendingCycles--; PC += 2; WriteMemory(value16, 0); PendingCycles -= 5; @@ -1821,8 +1803,6 @@ throw new Exception("break"); break; case 0xDE: // DEC addr,X value16 = (ushort)(ReadWord(PC)+X); - if ((PC & 0xFF00) != ((PC+Y) & 0xFF00)) - PendingCycles--; PC += 2; value8 = (byte)(ReadMemory(value16) - 1); WriteMemory(value16, value8); @@ -2162,8 +2142,6 @@ throw new Exception("break"); break; case 0xFE: // INC addr,X value16 = (ushort)(ReadWord(PC)+X); - if ((PC & 0xFF00) != ((PC+Y) & 0xFF00)) - PendingCycles--; PC += 2; value8 = (byte)(ReadMemory(value16) + 1); WriteMemory(value16, value8); diff --git a/CpuCoreGenerator/HuC6280/CoreGenerator.cs b/CpuCoreGenerator/HuC6280/CoreGenerator.cs index 85b8c43ba8..d055a228a6 100644 --- a/CpuCoreGenerator/HuC6280/CoreGenerator.cs +++ b/CpuCoreGenerator/HuC6280/CoreGenerator.cs @@ -457,28 +457,26 @@ namespace HuC6280 w.WriteLine(); w.WriteLine(" if (IRQ1Assert && FlagI == false && LagIFlag == false && (IRQControlByte & IRQ1Selector) == 0)"); w.WriteLine(" {"); - w.WriteLine(" FlagB = false;"); + w.WriteLine(" //Log.Note(\"CPU\", \"ENTERING IRQ1 INTERRUPT\");"); w.WriteLine(" WriteMemory((ushort)(S-- + 0x2100), (byte)(PC >> 8));"); w.WriteLine(" WriteMemory((ushort)(S-- + 0x2100), (byte)PC);"); - w.WriteLine(" WriteMemory((ushort)(S-- + 0x2100), P);"); + w.WriteLine(" WriteMemory((ushort)(S-- + 0x2100), (byte)(P & (~0x10)));"); w.WriteLine(" FlagD = false;"); w.WriteLine(" FlagI = true;"); w.WriteLine(" PC = ReadWord(IRQ1Vector);"); - w.WriteLine(" PendingCycles -= 7;"); - w.WriteLine(" //Log.Note(\"CPU\", \"ENTERING IRQ1 INTERRUPT\");"); + w.WriteLine(" PendingCycles -= 8;"); w.WriteLine(" }"); w.WriteLine(); w.WriteLine(" if (TimerAssert && FlagI == false && LagIFlag == false && (IRQControlByte & TimerSelector) == 0)"); w.WriteLine(" {"); - w.WriteLine(" FlagB = false;"); + w.WriteLine(" //Log.Note(\"CPU\", \"ENTERING __TIMER__ INTERRUPT\");"); w.WriteLine(" WriteMemory((ushort)(S-- + 0x2100), (byte)(PC >> 8));"); w.WriteLine(" WriteMemory((ushort)(S-- + 0x2100), (byte)PC);"); - w.WriteLine(" WriteMemory((ushort)(S-- + 0x2100), P);"); + w.WriteLine(" WriteMemory((ushort)(S-- + 0x2100), (byte)(P & (~0x10)));"); w.WriteLine(" FlagD = false;"); w.WriteLine(" FlagI = true;"); w.WriteLine(" PC = ReadWord(TimerVector);"); - w.WriteLine(" PendingCycles -= 7;"); - w.WriteLine(" //Log.Note(\"CPU\", \"ENTERING __TIMER__ INTERRUPT\");"); + w.WriteLine(" PendingCycles -= 8;"); w.WriteLine(" }"); w.WriteLine(); w.WriteLine(" IRQControlByte = IRQNextControlByte;"); @@ -657,7 +655,7 @@ namespace HuC6280 w.WriteLine("throw new Exception(\"unsupported opcode {0:X2}\");",opcode); break; } - if (op.Instruction != "SET") + if (op.Instruction != "SET" && op.Instruction != "RTI" && op.Instruction != "PLP") w.WriteLine(Spaces + "break;"); } @@ -725,14 +723,10 @@ namespace HuC6280 w.WriteLine(Spaces + dest + " = ReadWord(PC); PC += 2;"); break; case AddrMode.AbsoluteX: w.WriteLine(Spaces + dest + " = (ushort)(ReadWord(PC)+X);"); - w.WriteLine(Spaces + "if ((PC & 0xFF00) != ((PC+Y) & 0xFF00)) "); - w.WriteLine(Spaces + " PendingCycles--;"); w.WriteLine(Spaces + "PC += 2;"); break; case AddrMode.AbsoluteY: w.WriteLine(Spaces + dest + " = (ushort)(ReadWord(PC)+Y);"); - w.WriteLine(Spaces + "if ((PC & 0xFF00) != ((PC+Y) & 0xFF00)) "); - w.WriteLine(Spaces + " PendingCycles--;"); w.WriteLine(Spaces + "PC += 2;"); break; case AddrMode.Indirect: @@ -742,8 +736,6 @@ namespace HuC6280 case AddrMode.IndirectY: w.WriteLine(Spaces + "temp16 = ReadWordPageWrap((ushort)(ReadMemory(PC++)+0x2000));"); w.WriteLine(Spaces + dest + " = (ushort)(temp16+Y);"); - w.WriteLine(Spaces + "if ((temp16 & 0xFF00) != ((temp16+Y) & 0xFF00)) "); - w.WriteLine(Spaces + " PendingCycles--;"); break; case AddrMode.Relative: w.WriteLine(Spaces + "rel8 = (sbyte)ReadMemory(PC++);"); diff --git a/CpuCoreGenerator/HuC6280/Instructions.cs b/CpuCoreGenerator/HuC6280/Instructions.cs index f0f1d87101..24544c5a35 100644 --- a/CpuCoreGenerator/HuC6280/Instructions.cs +++ b/CpuCoreGenerator/HuC6280/Instructions.cs @@ -338,6 +338,7 @@ namespace HuC6280 { w.WriteLine(Spaces + "P = ReadMemory((ushort)(++S + 0x2100));"); w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles); + w.WriteLine(Spaces + "goto AfterClearTFlag;"); } private void ROL(OpcodeInfo op, TextWriter w) @@ -388,6 +389,7 @@ namespace HuC6280 w.WriteLine(Spaces + "PC = ReadMemory((ushort)(++S + 0x2100));"); w.WriteLine(Spaces + "PC |= (ushort)(ReadMemory((ushort)(++S + 0x2100)) << 8);"); w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles); + w.WriteLine(Spaces + "goto AfterClearTFlag;"); } private void RTS(OpcodeInfo op, TextWriter w)