From f2ca21759c370d83abcac79cedea837c13635b24 Mon Sep 17 00:00:00 2001 From: beirich Date: Fri, 7 Oct 2011 03:04:48 +0000 Subject: [PATCH] 68000 timings and flags fixes, some new opcode handlers --- BizHawk.Emulation/CPUs/68000/Diassembler.cs | 6 +- .../CPUs/68000/Instructions/BitArithemetic.cs | 122 ++++++++-- .../CPUs/68000/Instructions/DataMovement.cs | 120 +++++++-- .../CPUs/68000/Instructions/IntegerMath.cs | 229 ++++++++++-------- .../CPUs/68000/Instructions/ProgramFlow.cs | 123 +++++++--- .../CPUs/68000/Instructions/Supervisor.cs | 18 +- BizHawk.Emulation/CPUs/68000/M68000.cs | 27 ++- BizHawk.Emulation/CPUs/68000/Memory.cs | 32 +-- BizHawk.Emulation/CPUs/68000/OpcodeTable.cs | 36 +-- BizHawk.Emulation/CPUs/68000/Tables.cs | 10 +- .../Consoles/Sega/Genesis/GenVDP.Render.cs | 2 +- .../Consoles/Sega/Genesis/GenVDP.cs | 4 +- .../Consoles/Sega/Genesis/Genesis.cs | 9 +- 13 files changed, 495 insertions(+), 243 deletions(-) diff --git a/BizHawk.Emulation/CPUs/68000/Diassembler.cs b/BizHawk.Emulation/CPUs/68000/Diassembler.cs index f3f8f9a2ff..833a9c4827 100644 --- a/BizHawk.Emulation/CPUs/68000/Diassembler.cs +++ b/BizHawk.Emulation/CPUs/68000/Diassembler.cs @@ -12,11 +12,11 @@ namespace BizHawk.Emulation.CPUs.M68K public override string ToString() { - return string.Format("{0:X6} {3,-20} {1,-8} {2}", PC, Mnemonic, Args, RawBytes); + return string.Format("{0:X6}: {3,-20} {1,-8} {2}", PC, Mnemonic, Args, RawBytes); } } - public partial class M68000 + partial class MC68000 { public DisassemblyInfo Disassemble(int pc) { @@ -31,6 +31,7 @@ namespace BizHawk.Emulation.CPUs.M68K else if (Opcodes[op] == LEA) LEA_Disasm(info); else if (Opcodes[op] == CLR) CLR_Disasm(info); else if (Opcodes[op] == EXT) EXT_Disasm(info); + else if (Opcodes[op] == PEA) PEA_Disasm(info); else if (Opcodes[op] == ANDI) ANDI_Disasm(info); else if (Opcodes[op] == ORI) ORI_Disasm(info); @@ -48,6 +49,7 @@ namespace BizHawk.Emulation.CPUs.M68K else if (Opcodes[op] == BRA) BRA_Disasm(info); else if (Opcodes[op] == BSR) BSR_Disasm(info); else if (Opcodes[op] == DBcc) DBcc_Disasm(info); + else if (Opcodes[op] == Scc) Scc_Disasm(info); else if (Opcodes[op] == RTS) RTS_Disasm(info); else if (Opcodes[op] == TST) TST_Disasm(info); else if (Opcodes[op] == BTSTi) BTSTi_Disasm(info); diff --git a/BizHawk.Emulation/CPUs/68000/Instructions/BitArithemetic.cs b/BizHawk.Emulation/CPUs/68000/Instructions/BitArithemetic.cs index acc0ef1f28..3d9455377a 100644 --- a/BizHawk.Emulation/CPUs/68000/Instructions/BitArithemetic.cs +++ b/BizHawk.Emulation/CPUs/68000/Instructions/BitArithemetic.cs @@ -2,9 +2,9 @@ namespace BizHawk.Emulation.CPUs.M68K { - public partial class M68000 + partial class MC68000 { - private void ANDI() // AND immediate + void ANDI() // AND immediate { int size = ((op >> 6) & 0x03); int dstMode = ((op >> 3) & 0x07); @@ -51,7 +51,7 @@ namespace BizHawk.Emulation.CPUs.M68K } } - private void ANDI_Disasm(DisassemblyInfo info) + void ANDI_Disasm(DisassemblyInfo info) { int size = ((op >> 6) & 0x03); int dstMode = ((op >> 3) & 0x07); @@ -90,7 +90,7 @@ namespace BizHawk.Emulation.CPUs.M68K info.Length = pc - info.PC; } - private void ORI() + void ORI() { int size = (op >> 6) & 3; int mode = (op >> 3) & 7; @@ -127,13 +127,13 @@ namespace BizHawk.Emulation.CPUs.M68K WriteValueL(mode, reg, value); N = value < 0; Z = value == 0; - PendingCycles -= mode == 0 ? 17 : 20 + EACyclesL[mode, reg]; + PendingCycles -= mode == 0 ? 16 : 20 + EACyclesL[mode, reg]; return; } } } - private void ORI_Disasm(DisassemblyInfo info) + void ORI_Disasm(DisassemblyInfo info) { int pc = info.PC + 2; int size = (op >> 6) & 3; @@ -168,7 +168,89 @@ namespace BizHawk.Emulation.CPUs.M68K info.Length = pc - info.PC; } - private void LSLd() + void OR() + { + throw new Exception(); + /*int size = (op >> 6) & 3; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + V = C = false; + + switch (size) + { + case 0: // byte + { + sbyte immed = (sbyte)ReadWord(PC); PC += 2; + sbyte value = (sbyte)(PeekValueB(mode, reg) | immed); + WriteValueB(mode, reg, value); + N = value < 0; + Z = value == 0; + PendingCycles -= mode == 0 ? 8 : 12 + EACyclesBW[mode, reg]; + return; + } + case 1: // word + { + short immed = ReadWord(PC); PC += 2; + short value = (short)(PeekValueW(mode, reg) | immed); + WriteValueW(mode, reg, value); + N = value < 0; + Z = value == 0; + PendingCycles -= mode == 0 ? 8 : 12 + EACyclesBW[mode, reg]; + return; + } + case 2: // long + { + int immed = ReadLong(PC); PC += 4; + int value = PeekValueL(mode, reg) | immed; + WriteValueL(mode, reg, value); + N = value < 0; + Z = value == 0; + PendingCycles -= mode == 0 ? 17 : 20 + EACyclesL[mode, reg]; + return; + } + }*/ + } + + void OR_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int dReg = (op >> 9) & 3; + int d = (op >> 8) & 1; + int size = (op >> 6) & 3; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + switch (size) + { + case 0: // byte + { + info.Mnemonic = "ori.b"; + sbyte immed = (sbyte)ReadWord(pc); pc += 2; + info.Args = String.Format("${0:X}, {1}", immed, DisassembleValue(mode, reg, 1, ref pc)); + break; + } + case 1: // word + { + info.Mnemonic = "ori.w"; + short immed = ReadWord(pc); pc += 2; + info.Args = String.Format("${0:X}, {1}", immed, DisassembleValue(mode, reg, 2, ref pc)); + break; + } + case 2: // long + { + info.Mnemonic = "ori.l"; + int immed = ReadLong(pc); pc += 4; + info.Args = String.Format("${0:X}, {1}", immed, DisassembleValue(mode, reg, 4, ref pc)); + break; + } + } + + info.Length = pc - info.PC; + } + + + void LSLd() { int rot = (op >> 9) & 7; int size = (op >> 6) & 3; @@ -216,7 +298,7 @@ namespace BizHawk.Emulation.CPUs.M68K } } - private void LSLd_Disasm(DisassemblyInfo info) + void LSLd_Disasm(DisassemblyInfo info) { int pc = info.PC + 2; int rot = (op >> 9) & 7; @@ -238,7 +320,7 @@ namespace BizHawk.Emulation.CPUs.M68K info.Length = pc - info.PC; } - private void LSRd() + void LSRd() { int rot = (op >> 9) & 7; int size = (op >> 6) & 3; @@ -286,7 +368,7 @@ namespace BizHawk.Emulation.CPUs.M68K } } - private void LSRd_Disasm(DisassemblyInfo info) + void LSRd_Disasm(DisassemblyInfo info) { int pc = info.PC + 2; int rot = (op >> 9) & 7; @@ -308,7 +390,7 @@ namespace BizHawk.Emulation.CPUs.M68K info.Length = pc - info.PC; } - private void ASLd() + void ASLd() { int rot = (op >> 9) & 7; int size = (op >> 6) & 3; @@ -356,7 +438,7 @@ namespace BizHawk.Emulation.CPUs.M68K } } - private void ASLd_Disasm(DisassemblyInfo info) + void ASLd_Disasm(DisassemblyInfo info) { int pc = info.PC + 2; int rot = (op >> 9) & 7; @@ -378,7 +460,7 @@ namespace BizHawk.Emulation.CPUs.M68K info.Length = pc - info.PC; } - private void ASRd() + void ASRd() { int rot = (op >> 9) & 7; int size = (op >> 6) & 3; @@ -426,7 +508,7 @@ namespace BizHawk.Emulation.CPUs.M68K } } - private void ASRd_Disasm(DisassemblyInfo info) + void ASRd_Disasm(DisassemblyInfo info) { int pc = info.PC + 2; int rot = (op >> 9) & 7; @@ -448,7 +530,7 @@ namespace BizHawk.Emulation.CPUs.M68K info.Length = pc - info.PC; } - private void ROLd() + void ROLd() { int rot = (op >> 9) & 7; int size = (op >> 6) & 3; @@ -496,7 +578,7 @@ namespace BizHawk.Emulation.CPUs.M68K } } - private void ROLd_Disasm(DisassemblyInfo info) + void ROLd_Disasm(DisassemblyInfo info) { int pc = info.PC + 2; int rot = (op >> 9) & 7; @@ -518,7 +600,7 @@ namespace BizHawk.Emulation.CPUs.M68K info.Length = pc - info.PC; } - private void RORd() + void RORd() { int rot = (op >> 9) & 7; int size = (op >> 6) & 3; @@ -566,7 +648,7 @@ namespace BizHawk.Emulation.CPUs.M68K } } - private void RORd_Disasm(DisassemblyInfo info) + void RORd_Disasm(DisassemblyInfo info) { int pc = info.PC + 2; int rot = (op >> 9) & 7; @@ -588,7 +670,7 @@ namespace BizHawk.Emulation.CPUs.M68K info.Length = pc - info.PC; } - private void SWAP() + void SWAP() { int reg = op & 7; D[reg].u32 = (D[reg].u32 << 16) | (D[reg].u32 >> 16); @@ -598,7 +680,7 @@ namespace BizHawk.Emulation.CPUs.M68K PendingCycles -= 4; } - private void SWAP_Disasm(DisassemblyInfo info) + void SWAP_Disasm(DisassemblyInfo info) { int reg = op & 7; info.Mnemonic = "swap"; diff --git a/BizHawk.Emulation/CPUs/68000/Instructions/DataMovement.cs b/BizHawk.Emulation/CPUs/68000/Instructions/DataMovement.cs index 14add03f99..c5f834b61a 100644 --- a/BizHawk.Emulation/CPUs/68000/Instructions/DataMovement.cs +++ b/BizHawk.Emulation/CPUs/68000/Instructions/DataMovement.cs @@ -3,9 +3,9 @@ using System.Text; namespace BizHawk.Emulation.CPUs.M68K { - public partial class M68000 + partial class MC68000 { - private void MOVE() + void MOVE() { int size = ((op >> 12) & 0x03); int dstMode = ((op >> 6) & 0x07); @@ -41,7 +41,7 @@ namespace BizHawk.Emulation.CPUs.M68K Z = (value == 0); } - private void MOVE_Disasm(DisassemblyInfo info) + void MOVE_Disasm(DisassemblyInfo info) { int size = ((op >> 12) & 0x03); int dstMode = ((op >> 6) & 0x07); @@ -73,7 +73,7 @@ namespace BizHawk.Emulation.CPUs.M68K info.Length = pc - info.PC; } - private void MOVEA() + void MOVEA() { int size = ((op >> 12) & 0x03); int dstReg = ((op >> 9) & 0x07); @@ -83,14 +83,48 @@ namespace BizHawk.Emulation.CPUs.M68K if (size == 3) // Word { A[dstReg].s32 = ReadValueW(srcMode, srcReg); - PendingCycles -= EACyclesBW[srcMode, srcReg]; // TODO this is wrong, check pg 957 + switch (srcMode) + { + case 0: PendingCycles -= 4; break; + case 1: PendingCycles -= 4; break; + case 2: PendingCycles -= 8; break; + case 3: PendingCycles -= 8; break; + case 4: PendingCycles -= 10; break; + case 7: + switch (srcReg) + { + case 0: PendingCycles -= 12; break; + case 1: PendingCycles -= 16; break; + case 4: PendingCycles -= 8; break; + default: throw new NotImplementedException(); + } + break; + default: throw new NotImplementedException(); + } } else { // Long A[dstReg].s32 = ReadValueL(srcMode, srcReg); - PendingCycles -= EACyclesL[srcMode, srcReg]; // TODO this is wrong, check pg 957 + switch (srcMode) + { + case 0: PendingCycles -= 4; break; + case 1: PendingCycles -= 4; break; + case 2: PendingCycles -= 12; break; + case 3: PendingCycles -= 12; break; + case 4: PendingCycles -= 14; break; + case 7: + switch (srcReg) + { + case 0: PendingCycles -= 16; break; + case 1: PendingCycles -= 20; break; + case 4: PendingCycles -= 12; break; + default: throw new NotImplementedException(); + } + break; + default: throw new NotImplementedException(); + } } } - private void MOVEA_Disasm(DisassemblyInfo info) + void MOVEA_Disasm(DisassemblyInfo info) { int size = ((op >> 12) & 0x03); int dstReg = ((op >> 9) & 0x07); @@ -109,7 +143,7 @@ namespace BizHawk.Emulation.CPUs.M68K info.Length = pc - info.PC; } - private void MOVEQ() + void MOVEQ() { int value = (sbyte) op; // 8-bit data payload is sign-extended to 32-bits. N = (value < 0); @@ -120,13 +154,13 @@ namespace BizHawk.Emulation.CPUs.M68K PendingCycles -= 4; } - private void MOVEQ_Disasm(DisassemblyInfo info) + void MOVEQ_Disasm(DisassemblyInfo info) { info.Mnemonic = "moveq"; info.Args = String.Format("{0}, D{1}", (sbyte) op, (op >> 9) & 7); } - private void MOVEM0() + void MOVEM0() { // Move register to memory int size = (op >> 6) & 1; @@ -241,6 +275,7 @@ namespace BizHawk.Emulation.CPUs.M68K switch (dstMode) { case 2: PendingCycles -= 8; break; + case 3: PendingCycles -= 8; break; case 4: PendingCycles -= 8; break; case 5: PendingCycles -= 12; break; case 6: PendingCycles -= 14; break; @@ -254,7 +289,7 @@ namespace BizHawk.Emulation.CPUs.M68K } } - private void MOVEM1() + void MOVEM1() { // Move memory to register int size = (op >> 6) & 1; @@ -321,6 +356,7 @@ namespace BizHawk.Emulation.CPUs.M68K switch (srcMode) { case 2: PendingCycles -= 12; break; + case 3: PendingCycles -= 12; break; case 4: PendingCycles -= 12; break; case 5: PendingCycles -= 16; break; case 6: PendingCycles -= 18; break; @@ -336,7 +372,7 @@ namespace BizHawk.Emulation.CPUs.M68K } } - private static string DisassembleRegisterList0(ushort registers) + static string DisassembleRegisterList0(ushort registers) { var str = new StringBuilder(); int count = 0; @@ -354,7 +390,7 @@ namespace BizHawk.Emulation.CPUs.M68K { if ((registers & 0x8000) != 0) { - if (count > 0) str.Append("/"); + if (count > 0) str.Append(","); str.Append("A"+i); count++; } @@ -363,7 +399,7 @@ namespace BizHawk.Emulation.CPUs.M68K return str.ToString(); } - private static string DisassembleRegisterList1(ushort registers) + static string DisassembleRegisterList1(ushort registers) { var str = new StringBuilder(); int count = 0; @@ -381,7 +417,7 @@ namespace BizHawk.Emulation.CPUs.M68K { if ((registers & 1) != 0) { - if (count > 0) str.Append("/"); + if (count > 0) str.Append(","); str.Append("A" + i); count++; } @@ -390,7 +426,7 @@ namespace BizHawk.Emulation.CPUs.M68K return str.ToString(); } - private void MOVEM0_Disasm(DisassemblyInfo info) + void MOVEM0_Disasm(DisassemblyInfo info) { int size = (op >> 6) & 1; int mode = (op >> 3) & 7; @@ -405,7 +441,7 @@ namespace BizHawk.Emulation.CPUs.M68K info.Length = pc - info.PC; } - private void MOVEM1_Disasm(DisassemblyInfo info) + void MOVEM1_Disasm(DisassemblyInfo info) { int size = (op >> 6) & 1; int mode = (op >> 3) & 7; @@ -420,7 +456,7 @@ namespace BizHawk.Emulation.CPUs.M68K info.Length = pc - info.PC; } - private void LEA() + void LEA() { int mode = (op >> 3) & 7; int sReg = (op >> 0) & 7; @@ -444,7 +480,7 @@ namespace BizHawk.Emulation.CPUs.M68K } } - private void LEA_Disasm(DisassemblyInfo info) + void LEA_Disasm(DisassemblyInfo info) { int pc = info.PC + 2; @@ -459,7 +495,7 @@ namespace BizHawk.Emulation.CPUs.M68K info.Length = pc - info.PC; } - private void CLR() + void CLR() { int size = (op >> 6) & 3; int mode = (op >> 3) & 7; @@ -476,7 +512,7 @@ namespace BizHawk.Emulation.CPUs.M68K Z = true; } - private void CLR_Disasm(DisassemblyInfo info) + void CLR_Disasm(DisassemblyInfo info) { int pc = info.PC + 2; int size = (op >> 6) & 3; @@ -492,7 +528,7 @@ namespace BizHawk.Emulation.CPUs.M68K info.Length = pc - info.PC; } - private void EXT() + void EXT() { int size = (op >> 6) & 1; int reg = op & 7; @@ -504,8 +540,9 @@ namespace BizHawk.Emulation.CPUs.M68K PendingCycles -= 4; } - private void EXT_Disasm(DisassemblyInfo info) + void EXT_Disasm(DisassemblyInfo info) { + int pc = info.PC; int size = (op >> 6) & 1; int reg = op & 7; switch (size) @@ -513,6 +550,43 @@ namespace BizHawk.Emulation.CPUs.M68K case 0: info.Mnemonic = "ext.w"; info.Args = "D" + reg; break; case 1: info.Mnemonic = "ext.l"; info.Args = "D" + reg; break; } + + } + + void PEA() + { + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + int ea = ReadAddress(mode, reg); + A[7].s32 -= 4; + WriteLong(A[7].s32, ea); + + switch (mode) + { + case 2: PendingCycles -= 12; break; + case 5: PendingCycles -= 16; break; + case 6: PendingCycles -= 20; break; + case 7: + switch (reg) + { + case 0: PendingCycles -= 16; break; + case 1: PendingCycles -= 20; break; + case 2: PendingCycles -= 16; break; + case 3: PendingCycles -= 20; break; + } + break; + } + } + + void PEA_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + info.Mnemonic = "pea"; + info.Args = DisassembleAddress(mode, reg, ref pc); + info.Length = pc - info.PC; } } } diff --git a/BizHawk.Emulation/CPUs/68000/Instructions/IntegerMath.cs b/BizHawk.Emulation/CPUs/68000/Instructions/IntegerMath.cs index 7c2d29630a..cbfb7f80d4 100644 --- a/BizHawk.Emulation/CPUs/68000/Instructions/IntegerMath.cs +++ b/BizHawk.Emulation/CPUs/68000/Instructions/IntegerMath.cs @@ -2,9 +2,9 @@ namespace BizHawk.Emulation.CPUs.M68K { - public partial class M68000 + partial class MC68000 { - private void ADD0() + void ADD0() { int Dreg = (op >> 9) & 7; int size = (op >> 6) & 3; @@ -15,41 +15,47 @@ namespace BizHawk.Emulation.CPUs.M68K { case 0: // byte { - int result = D[Dreg].s8 + ReadValueB(mode, reg); - X = C = (result & 0x100) != 0; - V = result > sbyte.MaxValue || result < sbyte.MinValue; - N = result < 0; - Z = result == 0; - D[Dreg].s8 = (sbyte)result; + sbyte value = ReadValueB(mode, reg); + int sResult = D[Dreg].s8 + value; + int uResult = D[Dreg].u8 + (byte)value; + X = C = (uResult & 0x100) != 0; + V = sResult > sbyte.MaxValue || sResult < sbyte.MinValue; + N = (sResult & 0x80) != 0; + Z = sResult == 0; + D[Dreg].s8 = (sbyte) sResult; PendingCycles -= 4 + EACyclesBW[mode, reg]; return; } case 1: // word { - int result = D[Dreg].s16 + ReadValueW(mode, reg); - X = C = (result & 0x10000) != 0; - V = result > short.MaxValue || result < short.MinValue; - N = result < 0; - Z = result == 0; - D[Dreg].s16 = (short)result; + short value = ReadValueW(mode, reg); + int sResult = D[Dreg].s16 + value; + int uResult = D[Dreg].u16 + (ushort)value; + X = C = (uResult & 0x10000) != 0; + V = sResult > short.MaxValue || sResult < short.MinValue; + N = (sResult & 0x8000) != 0; + Z = sResult == 0; + D[Dreg].s16 = (short)sResult; PendingCycles -= 4 + EACyclesBW[mode, reg]; return; } case 2: // long { - long result = D[Dreg].s32 + ReadValueL(mode, reg); - X = C = (result & 0x100000000) != 0; - V = result > int.MaxValue || result < int.MinValue; - N = result < 0; - Z = result == 0; - D[Dreg].s32 = (int)result; + int value = ReadValueL(mode, reg); + long sResult = D[Dreg].s32 + value; + long uResult = D[Dreg].u32 + (uint)value; + X = C = (uResult & 0x100000000) != 0; + V = sResult > int.MaxValue || sResult < int.MinValue; + N = (sResult & 0x80000000) != 0; + Z = sResult == 0; + D[Dreg].s32 = (int)sResult; PendingCycles -= 6 + EACyclesL[mode, reg]; return; } } } - private void ADD1() + void ADD1() { int Dreg = (op >> 9) & 7; int size = (op >> 6) & 3; @@ -60,41 +66,48 @@ namespace BizHawk.Emulation.CPUs.M68K { case 0: // byte { - int result = PeekValueB(mode, reg) + D[Dreg].s8; - X = C = (result & 0x100) != 0; - V = result > sbyte.MaxValue || result < sbyte.MinValue; - N = result < 0; - Z = result == 0; - WriteValueB(mode, reg, (sbyte)result); + sbyte value = PeekValueB(mode, reg); + int sResult = value + D[Dreg].s8; + int uResult = (byte)value + D[Dreg].u8; + X = C = (uResult & 0x100) != 0; + V = sResult > sbyte.MaxValue || sResult < sbyte.MinValue; + N = (sResult & 0x80) != 0; + Z = sResult == 0; + WriteValueB(mode, reg, (sbyte)sResult); PendingCycles -= 8 + EACyclesBW[mode, reg]; return; } case 1: // word { - int result = PeekValueW(mode, reg) + D[Dreg].s16; - X = C = (result & 0x10000) != 0; - V = result > short.MaxValue || result < short.MinValue; - N = result < 0; - Z = result == 0; - WriteValueW(mode, reg, (short)result); + short value = PeekValueW(mode, reg); + int sResult = value + D[Dreg].s16; + int uResult = (ushort)value + D[Dreg].u16; + Log.Note("CPU", "ADD1.W. value={0}, reg={1}, signed result = {2}, unsigned result = {3}", value, D[Dreg].s16, sResult, uResult); + X = C = (uResult & 0x10000) != 0; + V = sResult > short.MaxValue || sResult < short.MinValue; + N = (sResult & 0x8000) != 0; + Z = sResult == 0; + WriteValueW(mode, reg, (short)sResult); PendingCycles -= 8 + EACyclesBW[mode, reg]; return; } case 2: // long { - long result = PeekValueL(mode, reg) + D[Dreg].s32; - X = C = (result & 0x100000000) != 0; - V = result > int.MaxValue || result < int.MinValue; - N = result < 0; - Z = result == 0; - WriteValueL(mode, reg, (int)result); + int value = PeekValueL(mode, reg); + long sResult = value + D[Dreg].s32; + long uResult = (uint)value + D[Dreg].u32; + X = C = (uResult & 0x100000000) != 0; + V = sResult > int.MaxValue || sResult < int.MinValue; + N = (sResult & 0x80000000) != 0; + Z = sResult == 0; + WriteValueL(mode, reg, (int)sResult); PendingCycles -= 12 + EACyclesL[mode, reg]; return; } } } - private void ADD_Disasm(DisassemblyInfo info) + void ADD_Disasm(DisassemblyInfo info) { int pc = info.PC + 2; @@ -117,12 +130,12 @@ namespace BizHawk.Emulation.CPUs.M68K info.Length = pc - info.PC; } - private void ADDI() + void ADDI() { int size = (op >> 6) & 3; int mode = (op >> 3) & 7; int reg = (op >> 0) & 7; - + Log.Error("CPU", "ADDI: note, flags probably calculated wrong. I suck."); switch (size) { case 0: // byte @@ -167,7 +180,7 @@ namespace BizHawk.Emulation.CPUs.M68K } } - private void ADDI_Disasm(DisassemblyInfo info) + void ADDI_Disasm(DisassemblyInfo info) { int pc = info.PC + 2; @@ -193,13 +206,13 @@ namespace BizHawk.Emulation.CPUs.M68K info.Length = pc - info.PC; } - private void ADDQ() + void ADDQ() { int data = (op >> 9) & 7; int size = (op >> 6) & 3; int mode = (op >> 3) & 7; int reg = (op >> 0) & 7; - +Log.Error("CPU", "ADDQ: note, flags probably calculated wrong. I suck."); data = data == 0 ? 8 : data; // range is 1-8; 0 represents 8 switch (size) @@ -254,7 +267,7 @@ namespace BizHawk.Emulation.CPUs.M68K } } - private void ADDQ_Disasm(DisassemblyInfo info) + void ADDQ_Disasm(DisassemblyInfo info) { int pc = info.PC + 2; int data = (op >> 9) & 7; @@ -273,7 +286,7 @@ namespace BizHawk.Emulation.CPUs.M68K info.Length = pc - info.PC; } - private void ADDA() + void ADDA() { int aReg = (op >> 9) & 7; int size = (op >> 8) & 1; @@ -292,7 +305,7 @@ namespace BizHawk.Emulation.CPUs.M68K } } - private void ADDA_Disasm(DisassemblyInfo info) + void ADDA_Disasm(DisassemblyInfo info) { int pc = info.PC + 2; @@ -307,7 +320,7 @@ namespace BizHawk.Emulation.CPUs.M68K info.Length = pc - info.PC; } - private void SUB0() + void SUB0() { int Dreg = (op >> 9) & 7; int size = (op >> 6) & 3; @@ -318,41 +331,47 @@ namespace BizHawk.Emulation.CPUs.M68K { case 0: // byte { - int result = D[Dreg].s8 - ReadValueB(mode, reg); - X = C = (result & 0x100) != 0; - V = result > sbyte.MaxValue || result < sbyte.MinValue; - N = result < 0; - Z = result == 0; - D[Dreg].s8 = (sbyte) result; + sbyte value = ReadValueB(mode, reg); + int sResult = D[Dreg].s8 - value; + int uResult = D[Dreg].u8 - (byte)value; + X = C = (uResult & 0x100) != 0; + V = sResult > sbyte.MaxValue || sResult < sbyte.MinValue; + N = (sResult & 0x80) != 0; + Z = sResult == 0; + D[Dreg].s8 = (sbyte) sResult; PendingCycles -= 4 + EACyclesBW[mode, reg]; return; } case 1: // word { - int result = D[Dreg].s16 - ReadValueW(mode, reg); - X = C = (result & 0x10000) != 0; - V = result > short.MaxValue || result < short.MinValue; - N = result < 0; - Z = result == 0; - D[Dreg].s16 = (short) result; + short value = ReadValueW(mode, reg); + int sResult = D[Dreg].s16 - value; + int uResult = D[Dreg].u16 - (ushort)value; + X = C = (uResult & 0x10000) != 0; + V = sResult > short.MaxValue || sResult < short.MinValue; + N = (sResult & 0x8000) != 0; + Z = sResult == 0; + D[Dreg].s16 = (short) sResult; PendingCycles -= 4 + EACyclesBW[mode, reg]; return; } case 2: // long { - long result = D[Dreg].s32 - ReadValueL(mode, reg); - X = C = (result & 0x100000000) != 0; - V = result > int.MaxValue || result < int.MinValue; - N = result < 0; - Z = result == 0; - D[Dreg].s32 = (int)result; + int value = ReadValueL(mode, reg); + long sResult = D[Dreg].s32 - value; + long uResult = D[Dreg].u32 - (uint)value; + X = C = (uResult & 0x100000000) != 0; + V = sResult > int.MaxValue || sResult < int.MinValue; + N = (sResult & 0x80000000) != 0; + Z = sResult == 0; + D[Dreg].s32 = (int)sResult; PendingCycles -= 6 + EACyclesL[mode, reg]; return; } } } - private void SUB1() + void SUB1() { int Dreg = (op >> 9) & 7; int size = (op >> 6) & 3; @@ -363,41 +382,47 @@ namespace BizHawk.Emulation.CPUs.M68K { case 0: // byte { - int result = PeekValueB(mode, reg) - D[Dreg].s8; - X = C = (result & 0x100) != 0; - V = result > sbyte.MaxValue || result < sbyte.MinValue; - N = result < 0; - Z = result == 0; - WriteValueB(mode, reg, (sbyte) result); + sbyte value = PeekValueB(mode, reg); + int sResult = value - D[Dreg].s8; + int uResult = (byte)value - D[Dreg].u8; + X = C = (uResult & 0x100) != 0; + V = sResult > sbyte.MaxValue || sResult < sbyte.MinValue; + N = (sResult & 0x80) != 0; + Z = sResult == 0; + WriteValueB(mode, reg, (sbyte) sResult); PendingCycles -= 8 + EACyclesBW[mode, reg]; return; } case 1: // word { - int result = PeekValueW(mode, reg) - D[Dreg].s16; - X = C = (result & 0x10000) != 0; - V = result > short.MaxValue || result < short.MinValue; - N = result < 0; - Z = result == 0; - WriteValueW(mode, reg, (short) result); + short value = PeekValueW(mode, reg); + int sResult = value - D[Dreg].s16; + int uResult = (ushort)value - D[Dreg].u16; + X = C = (uResult & 0x10000) != 0; + V = sResult > short.MaxValue || sResult < short.MinValue; + N = (sResult & 0x8000) != 0; + Z = sResult == 0; + WriteValueW(mode, reg, (short) sResult); PendingCycles -= 8 + EACyclesBW[mode, reg]; return; } case 2: // long { - long result = PeekValueL(mode, reg) - D[Dreg].s32; - X = C = (result & 0x100000000) != 0; - V = result > int.MaxValue || result < int.MinValue; - N = result < 0; - Z = result == 0; - WriteValueL(mode, reg, (int) result); + int value = PeekValueL(mode, reg); + long sResult = value - D[Dreg].s32; + long uResult = (uint)value - D[Dreg].u32; + X = C = (uResult & 0x100000000) != 0; + V = sResult > int.MaxValue || sResult < int.MinValue; + N = (sResult & 0x80000000) != 0; + Z = sResult == 0; + WriteValueL(mode, reg, (int) sResult); PendingCycles -= 12 + EACyclesL[mode, reg]; return; } } } - private void SUB_Disasm(DisassemblyInfo info) + void SUB_Disasm(DisassemblyInfo info) { int pc = info.PC + 2; @@ -420,12 +445,12 @@ namespace BizHawk.Emulation.CPUs.M68K info.Length = pc - info.PC; } - private void SUBI() + void SUBI() { int size = (op >> 6) & 3; int mode = (op >> 3) & 7; int reg = (op >> 0) & 7; - +Log.Error("CPU", "SUBI, bad flag calculations, I = lame"); switch (size) { case 0: // byte @@ -470,7 +495,7 @@ namespace BizHawk.Emulation.CPUs.M68K } } - private void SUBI_Disasm(DisassemblyInfo info) + void SUBI_Disasm(DisassemblyInfo info) { int pc = info.PC + 2; @@ -496,13 +521,13 @@ namespace BizHawk.Emulation.CPUs.M68K info.Length = pc - info.PC; } - private void SUBQ() + void SUBQ() { int data = (op >> 9) & 7; int size = (op >> 6) & 3; int mode = (op >> 3) & 7; int reg = (op >> 0) & 7; - +Log.Error("CPU", "SUBQ, bad flag calculations, I = lame"); data = data == 0 ? 8 : data; // range is 1-8; 0 represents 8 switch (size) @@ -553,7 +578,7 @@ namespace BizHawk.Emulation.CPUs.M68K } } - private void SUBQ_Disasm(DisassemblyInfo info) + void SUBQ_Disasm(DisassemblyInfo info) { int pc = info.PC + 2; int data = (op >> 9) & 7; @@ -572,7 +597,7 @@ namespace BizHawk.Emulation.CPUs.M68K info.Length = pc - info.PC; } - private void SUBA() + void SUBA() { int aReg = (op >> 9) & 7; int size = (op >> 8) & 1; @@ -591,7 +616,7 @@ namespace BizHawk.Emulation.CPUs.M68K } } - private void SUBA_Disasm(DisassemblyInfo info) + void SUBA_Disasm(DisassemblyInfo info) { int pc = info.PC + 2; @@ -606,13 +631,13 @@ namespace BizHawk.Emulation.CPUs.M68K info.Length = pc - info.PC; } - private void CMP() + void CMP() { int dReg = (op >> 9) & 7; int size = (op >> 6) & 3; int mode = (op >> 3) & 7; int reg = (op >> 0) & 7; - +Log.Error("CPU", "CMP, very possibly bad flag calculations, I = lame"); switch (size) { case 0: // byte @@ -650,7 +675,7 @@ namespace BizHawk.Emulation.CPUs.M68K } } - private void CMP_Disasm(DisassemblyInfo info) + void CMP_Disasm(DisassemblyInfo info) { int pc = info.PC + 2; @@ -677,7 +702,7 @@ namespace BizHawk.Emulation.CPUs.M68K info.Length = pc - info.PC; } - private void CMPA() + void CMPA() { int aReg = (op >> 9) & 7; int size = (op >> 8) & 1; @@ -709,7 +734,7 @@ namespace BizHawk.Emulation.CPUs.M68K } } - private void CMPA_Disasm(DisassemblyInfo info) + void CMPA_Disasm(DisassemblyInfo info) { int pc = info.PC + 2; @@ -733,7 +758,7 @@ namespace BizHawk.Emulation.CPUs.M68K } - private void CMPI() + void CMPI() { int size = (op >> 6) & 3; int mode = (op >> 3) & 7; @@ -780,7 +805,7 @@ namespace BizHawk.Emulation.CPUs.M68K } } - private void CMPI_Disasm(DisassemblyInfo info) + void CMPI_Disasm(DisassemblyInfo info) { int pc = info.PC + 2; int size = (op >> 6) & 3; diff --git a/BizHawk.Emulation/CPUs/68000/Instructions/ProgramFlow.cs b/BizHawk.Emulation/CPUs/68000/Instructions/ProgramFlow.cs index 67932bed56..9ff5f638b2 100644 --- a/BizHawk.Emulation/CPUs/68000/Instructions/ProgramFlow.cs +++ b/BizHawk.Emulation/CPUs/68000/Instructions/ProgramFlow.cs @@ -3,9 +3,9 @@ using System; namespace BizHawk.Emulation.CPUs.M68K { - public partial class M68000 + partial class MC68000 { - private bool TestCondition(int condition) + bool TestCondition(int condition) { switch (condition) { @@ -30,7 +30,7 @@ namespace BizHawk.Emulation.CPUs.M68K } } - private string DisassembleCondition(int condition) + string DisassembleCondition(int condition) { switch (condition) { @@ -54,7 +54,7 @@ namespace BizHawk.Emulation.CPUs.M68K } } - private void Bcc() // Branch on condition + void Bcc() // Branch on condition { sbyte displacement8 = (sbyte) op; int cond = (op >> 8) & 0x0F; @@ -81,7 +81,7 @@ namespace BizHawk.Emulation.CPUs.M68K } } - private void Bcc_Disasm(DisassemblyInfo info) + void Bcc_Disasm(DisassemblyInfo info) { int pc = info.PC + 2; sbyte displacement8 = (sbyte)op; @@ -98,7 +98,7 @@ namespace BizHawk.Emulation.CPUs.M68K info.Length = pc - info.PC; } - private void BRA() + void BRA() { sbyte displacement8 = (sbyte)op; @@ -109,7 +109,7 @@ namespace BizHawk.Emulation.CPUs.M68K PendingCycles -= 10; } - private void BRA_Disasm(DisassemblyInfo info) + void BRA_Disasm(DisassemblyInfo info) { int pc = info.PC + 2; info.Mnemonic = "bra"; @@ -125,7 +125,7 @@ namespace BizHawk.Emulation.CPUs.M68K info.Length = pc - info.PC; } - private void BSR() + void BSR() { sbyte displacement8 = (sbyte)op; @@ -143,7 +143,7 @@ namespace BizHawk.Emulation.CPUs.M68K PendingCycles -= 18; } - private void BSR_Disasm(DisassemblyInfo info) + void BSR_Disasm(DisassemblyInfo info) { int pc = info.PC + 2; info.Mnemonic = "bsr"; @@ -158,12 +158,11 @@ namespace BizHawk.Emulation.CPUs.M68K info.Length = pc - info.PC; } - private void DBcc() + void DBcc() { if (TestCondition((op >> 8) & 0x0F) == true) { - // break out of loop - PC += 2; + PC += 2; // condition met, break out of loop PendingCycles -= 12; } else { int reg = op & 7; @@ -171,16 +170,16 @@ namespace BizHawk.Emulation.CPUs.M68K if (D[reg].u16 == 0xFFFF) { - PC += 2; + PC += 2; // counter underflowed, break out of loop PendingCycles -= 14; } else { - PC += ReadWord(PC); - TotalExecutedCycles -= 10; + PC += ReadWord(PC); // condition false and counter not exhausted, so branch. + PendingCycles -= 10; } } } - private void DBcc_Disasm(DisassemblyInfo info) + void DBcc_Disasm(DisassemblyInfo info) { int cond = (op >> 8) & 0x0F; if (cond == 1) @@ -193,20 +192,20 @@ namespace BizHawk.Emulation.CPUs.M68K info.Length = 4; } - private void RTS() + void RTS() { PC = ReadLong(A[7].s32); A[7].s32 += 4; PendingCycles -= 16; } - private void RTS_Disasm(DisassemblyInfo info) + void RTS_Disasm(DisassemblyInfo info) { info.Mnemonic = "rts"; info.Args = ""; } - private void TST() + void TST() { int size = (op >> 6) & 3; int mode = (op >> 3) & 7; @@ -225,7 +224,7 @@ namespace BizHawk.Emulation.CPUs.M68K Z = (value == 0); } - private void TST_Disasm(DisassemblyInfo info) + void TST_Disasm(DisassemblyInfo info) { int pc = info.PC + 2; int size = (op >> 6) & 3; @@ -241,7 +240,7 @@ namespace BizHawk.Emulation.CPUs.M68K info.Length = pc - info.PC; } - private void BTSTi() + void BTSTi() { int bit = ReadWord(PC); PC += 2; @@ -262,7 +261,7 @@ namespace BizHawk.Emulation.CPUs.M68K } } - private void BTSTi_Disasm(DisassemblyInfo info) + void BTSTi_Disasm(DisassemblyInfo info) { int pc = info.PC + 2; int bit = ReadWord(pc); pc += 2; @@ -271,21 +270,45 @@ namespace BizHawk.Emulation.CPUs.M68K info.Mnemonic = "btst"; info.Args = String.Format("${0:X}, {1}", bit, DisassembleValue(mode, reg, 1, ref pc)); - info.Length = pc - info.PC; } - private void BTSTr() + void BTSTr() { - throw new NotImplementedException(); + int dReg = (op >> 9) & 7; + int mode = (op >> 3) & 7; + int reg = op & 7; + int bit = D[dReg].s32; + + if (mode == 0) + { + bit &= 31; + int mask = 1 << bit; + Z = (D[reg].s32 & mask) == 0; + PendingCycles -= 6; + } + else + { + bit &= 7; + int mask = 1 << bit; + Z = (ReadValueB(mode, reg) & mask) == 0; + PendingCycles -= 4 + EACyclesBW[mode, reg]; + } } - private void BTSTr_Disasm(DisassemblyInfo info) + void BTSTr_Disasm(DisassemblyInfo info) { - throw new NotImplementedException(); + int pc = info.PC + 2; + int dReg = (op >> 9) & 7; + int mode = (op >> 3) & 7; + int reg = op & 7; + + info.Mnemonic = "btst"; + info.Args = String.Format("D{0}, {1}", dReg, DisassembleValue(mode, reg, 1, ref pc)); + info.Length = pc - info.PC; } - private void JMP() + void JMP() { int mode = (op >> 3) & 7; int reg = (op >> 0) & 7; @@ -308,7 +331,7 @@ namespace BizHawk.Emulation.CPUs.M68K } } - private void JMP_Disasm(DisassemblyInfo info) + void JMP_Disasm(DisassemblyInfo info) { int pc = info.PC + 2; int mode = (op >> 3) & 7; @@ -318,7 +341,7 @@ namespace BizHawk.Emulation.CPUs.M68K info.Length = pc - info.PC; } - private void JSR() + void JSR() { int mode = (op >> 3) & 7; int reg = (op >> 0) & 7; @@ -345,7 +368,7 @@ namespace BizHawk.Emulation.CPUs.M68K } } - private void JSR_Disasm(DisassemblyInfo info) + void JSR_Disasm(DisassemblyInfo info) { int pc = info.PC + 2; int mode = (op >> 3) & 7; @@ -355,7 +378,7 @@ namespace BizHawk.Emulation.CPUs.M68K info.Length = pc - info.PC; } - private void LINK() + void LINK() { int reg = op & 7; A[7].s32 -= 4; @@ -365,7 +388,7 @@ namespace BizHawk.Emulation.CPUs.M68K PendingCycles -= 16; } - private void LINK_Disasm(DisassemblyInfo info) + void LINK_Disasm(DisassemblyInfo info) { int pc = info.PC + 2; int reg = op & 7; @@ -374,14 +397,44 @@ namespace BizHawk.Emulation.CPUs.M68K info.Length = pc - info.PC; } - private void NOP() + void NOP() { PendingCycles -= 4; } - private void NOP_Disasm(DisassemblyInfo info) + void NOP_Disasm(DisassemblyInfo info) { info.Mnemonic = "nop"; } + + void Scc() // Set on condition + { + int cond = (op >> 8) & 0x0F; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + if (TestCondition(cond) == true) + { + WriteValueB(mode, reg, -1); + if (mode == 0) PendingCycles -= 6; + else PendingCycles -= 8 + EACyclesBW[mode, reg]; + } else { + WriteValueB(mode, reg, 0); + if (mode == 0) PendingCycles -= 4; + else PendingCycles -= 8 + EACyclesBW[mode, reg]; + } + } + + void Scc_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int cond = (op >> 8) & 0x0F; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + info.Mnemonic = "s" + DisassembleCondition(cond); + info.Args = DisassembleValue(mode, reg, 1, ref pc); + info.Length = pc - info.PC; + } } } diff --git a/BizHawk.Emulation/CPUs/68000/Instructions/Supervisor.cs b/BizHawk.Emulation/CPUs/68000/Instructions/Supervisor.cs index a1dc88491d..f1fc328f97 100644 --- a/BizHawk.Emulation/CPUs/68000/Instructions/Supervisor.cs +++ b/BizHawk.Emulation/CPUs/68000/Instructions/Supervisor.cs @@ -2,9 +2,9 @@ namespace BizHawk.Emulation.CPUs.M68K { - public partial class M68000 + partial class MC68000 { - private void MOVEtSR() + void MOVEtSR() { if (S == false) throw new Exception("Write to SR when not in supervisor mode. supposed to trap or something..."); @@ -15,7 +15,7 @@ namespace BizHawk.Emulation.CPUs.M68K PendingCycles -= (mode == 0) ? 12 : 12 + EACyclesBW[mode, reg]; } - private void MOVEtSR_Disasm(DisassemblyInfo info) + void MOVEtSR_Disasm(DisassemblyInfo info) { int pc = info.PC + 2; int mode = (op >> 3) & 7; @@ -25,7 +25,7 @@ namespace BizHawk.Emulation.CPUs.M68K info.Length = pc - info.PC; } - private void MOVEfSR() + void MOVEfSR() { int mode = (op >> 3) & 7; int reg = (op >> 0) & 7; @@ -33,7 +33,7 @@ namespace BizHawk.Emulation.CPUs.M68K PendingCycles -= (mode == 0) ? 6 : 8 + EACyclesBW[mode, reg]; } - private void MOVEfSR_Disasm(DisassemblyInfo info) + void MOVEfSR_Disasm(DisassemblyInfo info) { int pc = info.PC + 2; int mode = (op >> 3) & 7; @@ -43,7 +43,7 @@ namespace BizHawk.Emulation.CPUs.M68K info.Length = pc - info.PC; } - private void MOVEUSP() + void MOVEUSP() { if (S == false) throw new Exception("MOVE to USP when not supervisor. needs to trap"); @@ -57,7 +57,7 @@ namespace BizHawk.Emulation.CPUs.M68K PendingCycles -= 4; } - private void MOVEUSP_Disasm(DisassemblyInfo info) + void MOVEUSP_Disasm(DisassemblyInfo info) { int pc = info.PC + 2; int dir = (op >> 3) & 1; @@ -67,7 +67,7 @@ namespace BizHawk.Emulation.CPUs.M68K info.Length = pc - info.PC; } - private void ORI_SR() + void ORI_SR() { if (S == false) throw new Exception("trap!"); @@ -75,7 +75,7 @@ namespace BizHawk.Emulation.CPUs.M68K PendingCycles -= 20; } - private void ORI_SR_Disasm(DisassemblyInfo info) + void ORI_SR_Disasm(DisassemblyInfo info) { int pc = info.PC + 2; info.Mnemonic = "ori"; diff --git a/BizHawk.Emulation/CPUs/68000/M68000.cs b/BizHawk.Emulation/CPUs/68000/M68000.cs index 475dc107a3..6288ae6948 100644 --- a/BizHawk.Emulation/CPUs/68000/M68000.cs +++ b/BizHawk.Emulation/CPUs/68000/M68000.cs @@ -3,7 +3,7 @@ using System.Runtime.InteropServices; namespace BizHawk.Emulation.CPUs.M68K { - public sealed partial class M68000 + public sealed partial class MC68000 { // Machine State public Register[] D = new Register[8]; @@ -14,10 +14,10 @@ namespace BizHawk.Emulation.CPUs.M68K public int PendingCycles; // Status Registers - private int InterruptMaskLevel; + int InterruptMaskLevel; - private bool s, m; - private int usp, ssp; + bool s, m; + int usp, ssp; /// Machine/Interrupt mode public bool M { get { return m; } set { m = value; } } // TODO probably have some switch logic maybe @@ -94,14 +94,15 @@ namespace BizHawk.Emulation.CPUs.M68K // Initialization - public M68000() + public MC68000() { BuildOpcodeTable(); } public void Reset() { - s = true; + S = true; + InterruptMaskLevel = 7; A[7].s32 = ReadLong(0); PC = ReadLong(4); } @@ -123,12 +124,24 @@ namespace BizHawk.Emulation.CPUs.M68K PendingCycles += cycles; while (PendingCycles > 0) { - //Console.WriteLine(Disassemble(PC)); + int prevCycles = PendingCycles; + Log.Note("CPU", State()); op = (ushort)ReadWord(PC); PC += 2; Opcodes[op](); + int delta = prevCycles - PendingCycles; + TotalExecutedCycles += delta; } } + + public string State() + { + string a = Disassemble(PC).ToString().PadRight(64); + string b = string.Format("D0:{0:X8} D1:{1:X8} D2:{2:X8} D3:{3:X8} D4:{4:X8} D5:{5:X8} D6:{6:X8} D7:{7:X8} ", D[0].u32, D[1].u32, D[2].u32, D[3].u32, D[4].u32, D[5].u32, D[6].u32, D[7].u32); + string c = string.Format("A0:{0:X8} A1:{1:X8} A2:{2:X8} A3:{3:X8} A4:{4:X8} A5:{5:X8} A6:{6:X8} A7:{7:X8} ", A[0].u32, A[1].u32, A[2].u32, A[3].u32, A[4].u32, A[5].u32, A[6].u32, A[7].u32); + string d = string.Format("SR:{0:X4} Pending {1} Cycles {2}", SR, PendingCycles, TotalExecutedCycles); + return a + b + c + d; + } } [StructLayout(LayoutKind.Explicit)] diff --git a/BizHawk.Emulation/CPUs/68000/Memory.cs b/BizHawk.Emulation/CPUs/68000/Memory.cs index a823910fd5..5fd5db752d 100644 --- a/BizHawk.Emulation/CPUs/68000/Memory.cs +++ b/BizHawk.Emulation/CPUs/68000/Memory.cs @@ -2,9 +2,9 @@ namespace BizHawk.Emulation.CPUs.M68K { - public partial class M68000 + partial class MC68000 { - private sbyte ReadValueB(int mode, int reg) + sbyte ReadValueB(int mode, int reg) { sbyte value; switch (mode) @@ -53,7 +53,7 @@ namespace BizHawk.Emulation.CPUs.M68K throw new Exception("Invalid addressing mode!"); } - private short ReadValueW(int mode, int reg) + short ReadValueW(int mode, int reg) { short value; switch (mode) @@ -102,7 +102,7 @@ namespace BizHawk.Emulation.CPUs.M68K throw new Exception("Invalid addressing mode!"); } - private int ReadValueL(int mode, int reg) + int ReadValueL(int mode, int reg) { int value; switch (mode) @@ -151,7 +151,7 @@ namespace BizHawk.Emulation.CPUs.M68K throw new Exception("Invalid addressing mode!"); } - private sbyte PeekValueB(int mode, int reg) + sbyte PeekValueB(int mode, int reg) { sbyte value; switch (mode) @@ -198,7 +198,7 @@ namespace BizHawk.Emulation.CPUs.M68K throw new Exception("Invalid addressing mode!"); } - private short PeekValueW(int mode, int reg) + short PeekValueW(int mode, int reg) { short value; switch (mode) @@ -245,7 +245,7 @@ namespace BizHawk.Emulation.CPUs.M68K throw new Exception("Invalid addressing mode!"); } - private int PeekValueL(int mode, int reg) + int PeekValueL(int mode, int reg) { int value; switch (mode) @@ -292,7 +292,7 @@ namespace BizHawk.Emulation.CPUs.M68K throw new Exception("Invalid addressing mode!"); } - private int ReadAddress(int mode, int reg) + int ReadAddress(int mode, int reg) { int addr; switch (mode) @@ -321,7 +321,7 @@ namespace BizHawk.Emulation.CPUs.M68K throw new Exception("Invalid addressing mode!"); } - private string DisassembleValue(int mode, int reg, int size, ref int pc) + string DisassembleValue(int mode, int reg, int size, ref int pc) { string value; switch (mode) @@ -372,7 +372,7 @@ namespace BizHawk.Emulation.CPUs.M68K throw new Exception("Invalid addressing mode!"); } - private string DisassembleImmediate(int size, ref int pc) + string DisassembleImmediate(int size, ref int pc) { int immed; switch (size) @@ -390,7 +390,7 @@ namespace BizHawk.Emulation.CPUs.M68K throw new ArgumentException("Invalid size"); } - private string DisassembleAddress(int mode, int reg, ref int pc) + string DisassembleAddress(int mode, int reg, ref int pc) { int addr; switch (mode) @@ -419,7 +419,7 @@ namespace BizHawk.Emulation.CPUs.M68K throw new Exception("Invalid addressing mode!"); } - private void WriteValueB(int mode, int reg, sbyte value) + void WriteValueB(int mode, int reg, sbyte value) { switch (mode) { @@ -468,7 +468,7 @@ namespace BizHawk.Emulation.CPUs.M68K } } - private void WriteValueW(int mode, int reg, short value) + void WriteValueW(int mode, int reg, short value) { switch (mode) { @@ -517,7 +517,7 @@ namespace BizHawk.Emulation.CPUs.M68K } } - private void WriteValueL(int mode, int reg, int value) + void WriteValueL(int mode, int reg, int value) { switch (mode) { @@ -566,7 +566,7 @@ namespace BizHawk.Emulation.CPUs.M68K } } - private int GetIndex() + int GetIndex() { Console.WriteLine("IN INDEX PORTION - NOT VERIFIED!!!"); // TODO kid chameleon triggers this in startup sequence @@ -595,7 +595,7 @@ namespace BizHawk.Emulation.CPUs.M68K return displacement + indexReg; } - private int PeekIndex() + int PeekIndex() { Console.WriteLine("IN INDEX PORTION - NOT VERIFIED!!!"); diff --git a/BizHawk.Emulation/CPUs/68000/OpcodeTable.cs b/BizHawk.Emulation/CPUs/68000/OpcodeTable.cs index bef2e36e9f..f399d44fc7 100644 --- a/BizHawk.Emulation/CPUs/68000/OpcodeTable.cs +++ b/BizHawk.Emulation/CPUs/68000/OpcodeTable.cs @@ -3,9 +3,9 @@ using System.Collections.Generic; namespace BizHawk.Emulation.CPUs.M68K { - public partial class M68000 + partial class MC68000 { - private void BuildOpcodeTable() + void BuildOpcodeTable() { // NOTE: Do not change the order of these assigns without testing. There is // some overwriting of less-specific opcodes with more-specific opcodes. @@ -22,6 +22,7 @@ namespace BizHawk.Emulation.CPUs.M68K Assign("lea", LEA, "0100", "Xn", "111", "AmXn"); Assign("clr", CLR, "01000010", "Size2_1", "AmXn"); Assign("ext", EXT, "010010001", "Size1", "000", "Xn"); + Assign("pea", PEA, "0100100001", "AmXn"); Assign("andi", ANDI, "00000010", "Size2_1", "AmXn"); Assign("ori", ORI, "00000000", "Size2_1", "AmXn"); @@ -32,13 +33,14 @@ namespace BizHawk.Emulation.CPUs.M68K Assign("rol", ROLd, "1110", "Data3", "1", "Size2_1", "Data1", "11", "Xn"); Assign("ror", RORd, "1110", "Data3", "0", "Size2_1", "Data1", "11", "Xn"); Assign("swap", SWAP, "0100100001000","Xn"); + //Assign("or", OR, "1000", "Xn", "Data1","Size2_1", "AmXn"); Assign("jmp", JMP, "0100111011", "AmXn"); Assign("jsr", JSR, "0100111010", "AmXn"); Assign("bcc", Bcc, "0110", "CondMain", "Data8"); Assign("bra", BRA, "01100000", "Data8"); Assign("bsr", BSR, "01100001", "Data8"); - // NOTE: Scc must be assigned before DBcc + Assign("scc", Scc, "0101", "CondAll", "11","AmXn"); Assign("dbcc", DBcc, "0101", "CondAll", "11001", "Xn"); Assign("rts", RTS, "0100111001110101"); Assign("tst", TST, "01001010", "Size2_1", "AmXn"); @@ -67,7 +69,7 @@ namespace BizHawk.Emulation.CPUs.M68K Assign("ori2sr", ORI_SR, "0000000001111100"); } - private void Assign(string instr, Action exec, string root, params string[] bitfield) + void Assign(string instr, Action exec, string root, params string[] bitfield) { List opList = new List(); opList.Add(root); @@ -91,19 +93,19 @@ namespace BizHawk.Emulation.CPUs.M68K foreach (var opcode in opList) { int opc = Convert.ToInt32(opcode, 2); - if (Opcodes[opc] != null && instr.NotIn("movea","ori2sr","ext")) + if (Opcodes[opc] != null && instr.NotIn("movea","ori2sr","ext","dbcc","swap")) Console.WriteLine("Setting opcode for {0}, a handler is already set. overwriting. {1:X4}", instr, opc); Opcodes[opc] = exec; } } - private void AppendConstant(List ops, string constant) + void AppendConstant(List ops, string constant) { for (int i=0; i AppendPermutations(List ops, string[] permutations) + List AppendPermutations(List ops, string[] permutations) { List output = new List(); @@ -114,7 +116,7 @@ namespace BizHawk.Emulation.CPUs.M68K return output; } - private List AppendData(List ops, int bits) + List AppendData(List ops, int bits) { List output = new List(); @@ -125,7 +127,7 @@ namespace BizHawk.Emulation.CPUs.M68K return output; } - private int BinaryExp(int bits) + int BinaryExp(int bits) { int res = 1; for (int i = 0; i < bits; i++) @@ -135,12 +137,12 @@ namespace BizHawk.Emulation.CPUs.M68K #region Tables - private static readonly string[] Size2_0 = {"01", "11", "10"}; - private static readonly string[] Size2_1 = {"00", "01", "10"}; - private static readonly string[] Size1 = {"0", "1" }; - private static readonly string[] Xn3 = {"000","001","010","011","100","101","110","111"}; + static readonly string[] Size2_0 = {"01", "11", "10"}; + static readonly string[] Size2_1 = {"00", "01", "10"}; + static readonly string[] Size1 = {"0", "1" }; + static readonly string[] Xn3 = {"000","001","010","011","100","101","110","111"}; - private static readonly string[] Xn3Am3 = { + static readonly string[] Xn3Am3 = { "000000", // Dn Data register "001000", "010000", @@ -211,7 +213,7 @@ namespace BizHawk.Emulation.CPUs.M68K "100111", // #imm Immediate }; - private static readonly string[] Am3Xn3 = { + static readonly string[] Am3Xn3 = { "000000", // Dn Data register "000001", "000010", @@ -282,7 +284,7 @@ namespace BizHawk.Emulation.CPUs.M68K "111100", // #imm Immediate }; - private static readonly string[] ConditionMain = { + static readonly string[] ConditionMain = { "0010", // HI Higher (unsigned) "0011", // LS Lower or Same (unsigned) "0100", // CC Carry Clear (aka Higher or Same, unsigned) @@ -299,7 +301,7 @@ namespace BizHawk.Emulation.CPUs.M68K "1111" // LE Less or Equal (signed) }; - private static readonly string[] ConditionAll = { + static readonly string[] ConditionAll = { "0000", // T True "0001", // F False "0010", // HI Higher (unsigned) diff --git a/BizHawk.Emulation/CPUs/68000/Tables.cs b/BizHawk.Emulation/CPUs/68000/Tables.cs index b108786c85..b2b3a4ee85 100644 --- a/BizHawk.Emulation/CPUs/68000/Tables.cs +++ b/BizHawk.Emulation/CPUs/68000/Tables.cs @@ -1,8 +1,8 @@ namespace BizHawk.Emulation.CPUs.M68K { - public partial class M68000 + partial class MC68000 { - private static readonly int[,] MoveCyclesBW = new int[12,9] + static readonly int[,] MoveCyclesBW = new int[12,9] { { 4, 4, 8, 8, 8, 12, 14, 12, 16 }, { 4, 4, 8, 8, 8, 12, 14, 12, 16 }, @@ -18,7 +18,7 @@ { 8, 8, 12, 12, 12, 16, 18, 16, 20 } }; - private static readonly int[,] MoveCyclesL = new int[12, 9] + static readonly int[,] MoveCyclesL = new int[12, 9] { { 4, 4, 12, 12, 12, 16, 18, 16, 20 }, { 4, 4, 12, 12, 12, 16, 18, 16, 20 }, @@ -34,7 +34,7 @@ { 12, 12, 20, 20, 20, 24, 26, 24, 28 } }; - private static readonly int[,] EACyclesBW = new int[8, 9] + static readonly int[,] EACyclesBW = new int[8, 9] { { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, @@ -46,7 +46,7 @@ { 8, 12, 8, 10, 4, 99, 99, 99, 99 } }; - private static readonly int[,] EACyclesL = new int[8, 9] + static readonly int[,] EACyclesL = new int[8, 9] { { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, diff --git a/BizHawk.Emulation/Consoles/Sega/Genesis/GenVDP.Render.cs b/BizHawk.Emulation/Consoles/Sega/Genesis/GenVDP.Render.cs index 555c55b6c9..bd150e6cf8 100644 --- a/BizHawk.Emulation/Consoles/Sega/Genesis/GenVDP.Render.cs +++ b/BizHawk.Emulation/Consoles/Sega/Genesis/GenVDP.Render.cs @@ -6,7 +6,7 @@ namespace BizHawk.Emulation.Consoles.Sega { public void RenderLine() { - if (ScanLine == 223) + if (ScanLine == 0) { for (int i = 0; i < FrameBuffer.Length; i++) FrameBuffer[i] = 0; diff --git a/BizHawk.Emulation/Consoles/Sega/Genesis/GenVDP.cs b/BizHawk.Emulation/Consoles/Sega/Genesis/GenVDP.cs index 67e27d3943..c03d733b57 100644 --- a/BizHawk.Emulation/Consoles/Sega/Genesis/GenVDP.cs +++ b/BizHawk.Emulation/Consoles/Sega/Genesis/GenVDP.cs @@ -97,8 +97,8 @@ namespace BizHawk.Emulation.Consoles.Sega public ushort ReadVdpControl() { //Console.WriteLine("VDP: Control Read"); - ushort value = 0; - value |= 0x8000; // Fifo empty + ushort value = 0x3400; // fixed bits per genvdp.txt TODO test on everdrive, I guess. + value |= 0x0200; // Fifo empty return value; } diff --git a/BizHawk.Emulation/Consoles/Sega/Genesis/Genesis.cs b/BizHawk.Emulation/Consoles/Sega/Genesis/Genesis.cs index cfceb4d683..f18bd9105d 100644 --- a/BizHawk.Emulation/Consoles/Sega/Genesis/Genesis.cs +++ b/BizHawk.Emulation/Consoles/Sega/Genesis/Genesis.cs @@ -13,7 +13,7 @@ namespace BizHawk.Emulation.Consoles.Sega public byte[] RomData; // Machine stuff - public M68000 MainCPU; + public MC68000 MainCPU; public Z80A SoundCPU; public GenVDP VDP; public SN76489 PSG; @@ -56,7 +56,7 @@ namespace BizHawk.Emulation.Consoles.Sega public Genesis(GameInfo game, byte[] rom) { CoreOutputComm = new CoreOutputComm(); - MainCPU = new M68000(); + MainCPU = new MC68000(); SoundCPU = new Z80A(); YM2612 = new YM2612(); PSG = new SN76489(); @@ -90,12 +90,12 @@ namespace BizHawk.Emulation.Consoles.Sega PSG.BeginFrame(SoundCPU.TotalExecutedCycles); for (VDP.ScanLine = 0; VDP.ScanLine < 262; VDP.ScanLine++) { - Console.WriteLine("Frame {0} ScanLine {1}", Frame, VDP.ScanLine); + Log.Error("VDP","FRAME {0}, SCANLINE {1}", Frame, VDP.ScanLine); if (VDP.ScanLine < 224) VDP.RenderLine(); - MainCPU.ExecuteCycles(488); + MainCPU.ExecuteCycles(487); // 488?? if (Z80Runnable) { //Console.WriteLine("running z80"); @@ -105,6 +105,7 @@ namespace BizHawk.Emulation.Consoles.Sega if (VDP.ScanLine == 224) { + MainCPU.ExecuteCycles(16);// stupid crap to sync with genesis plus for log testing // End-frame stuff /*if (VDP.VInterruptEnabled) MainCPU.Interrupt(6);*/