From 91baebf8b24516b09a5db8baffa2edacc52e9d92 Mon Sep 17 00:00:00 2001 From: beirich Date: Sat, 23 Jul 2011 21:24:43 +0000 Subject: [PATCH] [PCE] Implement ORA under T-Flag, fixes City Hunter --- BizHawk.Emulation/CPUs/HuC6280/Execute.cs | 140 ++++++++++++++---- .../Consoles/PC Engine/Compat.txt | 1 - CpuCoreGenerator/HuC6280/CoreGenerator.cs | 3 +- CpuCoreGenerator/HuC6280/Instructions.cs | 18 ++- 4 files changed, 127 insertions(+), 35 deletions(-) diff --git a/BizHawk.Emulation/CPUs/HuC6280/Execute.cs b/BizHawk.Emulation/CPUs/HuC6280/Execute.cs index d9ed95909a..c2bbf457b3 100644 --- a/BizHawk.Emulation/CPUs/HuC6280/Execute.cs +++ b/BizHawk.Emulation/CPUs/HuC6280/Execute.cs @@ -73,9 +73,18 @@ namespace BizHawk.Emulation.CPUs.H6280 break; case 0x01: // ORA (addr,X) value8 = ReadMemory(ReadWordPageWrap((ushort)((byte)(ReadMemory(PC++)+X)+0x2000))); - A |= value8; - P = (byte)((P & 0x7D) | TableNZ[A]); - PendingCycles -= 7; + if (FlagT == false) + { + A |= value8; + P = (byte)((P & 0x7D) | TableNZ[A]); + PendingCycles -= 7; + } else { + source8 = ReadMemory((ushort)(0x2000 + X)); + source8 |= value8; + P = (byte)((P & 0x7D) | TableNZ[source8]); + WriteMemory((ushort)(0x2000 + X), source8); + PendingCycles -= 10; + } break; case 0x02: // SXY temp8 = X; @@ -99,9 +108,18 @@ namespace BizHawk.Emulation.CPUs.H6280 break; case 0x05: // ORA zp value8 = ReadMemory((ushort)(ReadMemory(PC++)+0x2000)); - A |= value8; - P = (byte)((P & 0x7D) | TableNZ[A]); - PendingCycles -= 4; + if (FlagT == false) + { + A |= value8; + P = (byte)((P & 0x7D) | TableNZ[A]); + PendingCycles -= 4; + } else { + source8 = ReadMemory((ushort)(0x2000 + X)); + source8 |= value8; + P = (byte)((P & 0x7D) | TableNZ[source8]); + WriteMemory((ushort)(0x2000 + X), source8); + PendingCycles -= 7; + } break; case 0x06: // ASL zp value16 = (ushort)(ReadMemory(PC++)+0x2000); @@ -125,9 +143,18 @@ namespace BizHawk.Emulation.CPUs.H6280 break; case 0x09: // ORA #nn value8 = ReadMemory(PC++); - A |= value8; - P = (byte)((P & 0x7D) | TableNZ[A]); - PendingCycles -= 2; + if (FlagT == false) + { + A |= value8; + P = (byte)((P & 0x7D) | TableNZ[A]); + PendingCycles -= 2; + } else { + source8 = ReadMemory((ushort)(0x2000 + X)); + source8 |= value8; + P = (byte)((P & 0x7D) | TableNZ[source8]); + WriteMemory((ushort)(0x2000 + X), source8); + PendingCycles -= 5; + } break; case 0x0A: // ASL A FlagC = (A & 0x80) != 0; @@ -146,9 +173,18 @@ namespace BizHawk.Emulation.CPUs.H6280 break; case 0x0D: // ORA addr value8 = ReadMemory(ReadWord(PC)); PC += 2; - A |= value8; - P = (byte)((P & 0x7D) | TableNZ[A]); - PendingCycles -= 5; + if (FlagT == false) + { + A |= value8; + P = (byte)((P & 0x7D) | TableNZ[A]); + PendingCycles -= 5; + } else { + source8 = ReadMemory((ushort)(0x2000 + X)); + source8 |= value8; + P = (byte)((P & 0x7D) | TableNZ[source8]); + WriteMemory((ushort)(0x2000 + X), source8); + PendingCycles -= 8; + } break; case 0x0E: // ASL addr value16 = ReadWord(PC); PC += 2; @@ -180,15 +216,33 @@ namespace BizHawk.Emulation.CPUs.H6280 case 0x11: // ORA (addr),Y temp16 = ReadWordPageWrap((ushort)(ReadMemory(PC++)+0x2000)); value8 = ReadMemory((ushort)(temp16+Y)); - A |= value8; - P = (byte)((P & 0x7D) | TableNZ[A]); - PendingCycles -= 7; + if (FlagT == false) + { + A |= value8; + P = (byte)((P & 0x7D) | TableNZ[A]); + PendingCycles -= 7; + } else { + source8 = ReadMemory((ushort)(0x2000 + X)); + source8 |= value8; + P = (byte)((P & 0x7D) | TableNZ[source8]); + WriteMemory((ushort)(0x2000 + X), source8); + PendingCycles -= 10; + } break; case 0x12: // ORA (addr) value8 = ReadMemory(ReadWordPageWrap((ushort)(ReadMemory(PC++)+0x2000))); - A |= value8; - P = (byte)((P & 0x7D) | TableNZ[A]); - PendingCycles -= 7; + if (FlagT == false) + { + A |= value8; + P = (byte)((P & 0x7D) | TableNZ[A]); + PendingCycles -= 7; + } else { + source8 = ReadMemory((ushort)(0x2000 + X)); + source8 |= value8; + P = (byte)((P & 0x7D) | TableNZ[source8]); + WriteMemory((ushort)(0x2000 + X), source8); + PendingCycles -= 10; + } break; case 0x13: // ST1 #nn value8 = ReadMemory(PC++); @@ -206,9 +260,18 @@ namespace BizHawk.Emulation.CPUs.H6280 break; case 0x15: // ORA zp,X value8 = ReadMemory((ushort)(((ReadMemory(PC++)+X)&0xFF)+0x2000)); - A |= value8; - P = (byte)((P & 0x7D) | TableNZ[A]); - PendingCycles -= 4; + if (FlagT == false) + { + A |= value8; + P = (byte)((P & 0x7D) | TableNZ[A]); + PendingCycles -= 4; + } else { + source8 = ReadMemory((ushort)(0x2000 + X)); + source8 |= value8; + P = (byte)((P & 0x7D) | TableNZ[source8]); + WriteMemory((ushort)(0x2000 + X), source8); + PendingCycles -= 7; + } break; case 0x16: // ASL zp,X value16 = (ushort)(((ReadMemory(PC++)+X)&0xFF)+0x2000); @@ -233,9 +296,18 @@ namespace BizHawk.Emulation.CPUs.H6280 case 0x19: // ORA addr,Y value8 = ReadMemory((ushort)(ReadWord(PC)+Y)); PC += 2; - A |= value8; - P = (byte)((P & 0x7D) | TableNZ[A]); - PendingCycles -= 5; + if (FlagT == false) + { + A |= value8; + P = (byte)((P & 0x7D) | TableNZ[A]); + PendingCycles -= 5; + } else { + source8 = ReadMemory((ushort)(0x2000 + X)); + source8 |= value8; + P = (byte)((P & 0x7D) | TableNZ[source8]); + WriteMemory((ushort)(0x2000 + X), source8); + PendingCycles -= 8; + } break; case 0x1A: // INC A P = (byte)((P & 0x7D) | TableNZ[++A]); @@ -253,9 +325,18 @@ namespace BizHawk.Emulation.CPUs.H6280 case 0x1D: // ORA addr,X value8 = ReadMemory((ushort)(ReadWord(PC)+X)); PC += 2; - A |= value8; - P = (byte)((P & 0x7D) | TableNZ[A]); - PendingCycles -= 5; + if (FlagT == false) + { + A |= value8; + P = (byte)((P & 0x7D) | TableNZ[A]); + PendingCycles -= 5; + } else { + source8 = ReadMemory((ushort)(0x2000 + X)); + source8 |= value8; + P = (byte)((P & 0x7D) | TableNZ[source8]); + WriteMemory((ushort)(0x2000 + X), source8); + PendingCycles -= 8; + } break; case 0x1E: // ASL addr,X value16 = (ushort)(ReadWord(PC)+X); @@ -2087,7 +2168,7 @@ namespace BizHawk.Emulation.CPUs.H6280 case 0xF4: // SET int a; // TODO remove these extra checks string b = Disassemble(PC, out a); - if (b.StartsWith("ADC") == false && b.StartsWith("EOR") == false && b.StartsWith("AND") == false) + if (b.StartsWith("ADC") == false && b.StartsWith("EOR") == false && b.StartsWith("AND") == false && b.StartsWith("ORA") == false) Console.WriteLine("SETTING T FLAG, NEXT INSTRUCTION IS UNHANDLED: {0}", b); FlagT = true; PendingCycles -= 2; @@ -2198,7 +2279,8 @@ namespace BizHawk.Emulation.CPUs.H6280 PendingCycles -= 6; break; default: - throw new Exception(String.Format("Unhandled opcode: {0:X2}", opcode)); + Console.WriteLine("Unhandled opcode: {0:X2}", opcode); + break; } P &= 0xDF; // Clear T flag diff --git a/BizHawk.Emulation/Consoles/PC Engine/Compat.txt b/BizHawk.Emulation/Consoles/PC Engine/Compat.txt index f4a7fdfe33..11372dba02 100644 --- a/BizHawk.Emulation/Consoles/PC Engine/Compat.txt +++ b/BizHawk.Emulation/Consoles/PC Engine/Compat.txt @@ -21,7 +21,6 @@ Outrun - Req HBlank hack to eliminate visual artifact Tiger Road - On second level, sprites should be getting masked from the top status area somehow Bouken Danshaku Don - The Lost Sunheart (J) - Uses LFO in intro sound strongly! -City Hunter- uses SET on ORA instruction Eagan's Rendered Sprite Demo by Eagan Rackley (PD) - demonstrates sprites that shouldnt be displayed Games Express CD Card 1993 - dont forget to treat as a turbocd system card Puzzle Boy(J) - screen vert height is fucked up...needs to be masked or just clipped? diff --git a/CpuCoreGenerator/HuC6280/CoreGenerator.cs b/CpuCoreGenerator/HuC6280/CoreGenerator.cs index 8b23f027e1..93a99cd581 100644 --- a/CpuCoreGenerator/HuC6280/CoreGenerator.cs +++ b/CpuCoreGenerator/HuC6280/CoreGenerator.cs @@ -502,7 +502,8 @@ namespace HuC6280 } w.WriteLine(" default:"); - w.WriteLine(" throw new Exception(String.Format(\"Unhandled opcode: {0:X2}\", opcode));"); + w.WriteLine(" Console.WriteLine(\"Unhandled opcode: {0:X2}\", opcode);"); + w.WriteLine(" break;"); w.WriteLine(" }"); w.WriteLine(); w.WriteLine(" P &= 0xDF; // Clear T flag"); diff --git a/CpuCoreGenerator/HuC6280/Instructions.cs b/CpuCoreGenerator/HuC6280/Instructions.cs index f85a6dc461..8c9648e280 100644 --- a/CpuCoreGenerator/HuC6280/Instructions.cs +++ b/CpuCoreGenerator/HuC6280/Instructions.cs @@ -342,9 +342,19 @@ namespace HuC6280 private void ORA(OpcodeInfo op, TextWriter w) { GetValue8(op, w, "value8"); - w.WriteLine(Spaces + "A |= value8;"); - w.WriteLine(Spaces + SetNZ("A")); - w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles); + + w.WriteLine(Spaces + "if (FlagT == false)"); + w.WriteLine(Spaces + "{"); + w.WriteLine(Spaces + " A |= value8;"); + w.WriteLine(Spaces + " "+SetNZ("A")); + w.WriteLine(Spaces + " PendingCycles -= {0};", op.Cycles); + w.WriteLine(Spaces + "} else {"); + w.WriteLine(Spaces + " source8 = ReadMemory((ushort)(0x2000 + X));"); + w.WriteLine(Spaces + " source8 |= value8;"); + w.WriteLine(Spaces + " " + SetNZ("source8")); + w.WriteLine(Spaces + " WriteMemory((ushort)(0x2000 + X), source8);"); + w.WriteLine(Spaces + " PendingCycles -= {0};", op.Cycles+3); + w.WriteLine(Spaces + "}"); } private void PushReg(OpcodeInfo op, TextWriter w, string reg) @@ -496,7 +506,7 @@ namespace HuC6280 { w.WriteLine(" int a; // TODO remove these extra checks"); // TODO remove these extra checks w.WriteLine(" string b = Disassemble(PC, out a);"); - w.WriteLine(" if (b.StartsWith(\"ADC\") == false && b.StartsWith(\"EOR\") == false && b.StartsWith(\"AND\") == false)"); + w.WriteLine(" if (b.StartsWith(\"ADC\") == false && b.StartsWith(\"EOR\") == false && b.StartsWith(\"AND\") == false && b.StartsWith(\"ORA\") == false)"); w.WriteLine(" Console.WriteLine(\"SETTING T FLAG, NEXT INSTRUCTION IS UNHANDLED: {0}\", b);"); w.WriteLine(Spaces + "FlagT = true;"); w.WriteLine(Spaces + "PendingCycles -= {0};", op.Cycles);