From 7ae6dfb5346cc32ef5ddc1c62312a2f774549e9e Mon Sep 17 00:00:00 2001 From: beirich Date: Thu, 27 Oct 2011 04:02:11 +0000 Subject: [PATCH] 68000: implement CMPM --- BizHawk.Emulation/CPUs/68000/Diassembler.cs | 2 + .../CPUs/68000/Instructions/IntegerMath.cs | 113 ++++++++++++++---- BizHawk.Emulation/CPUs/68000/OpcodeTable.cs | 5 +- 3 files changed, 93 insertions(+), 27 deletions(-) diff --git a/BizHawk.Emulation/CPUs/68000/Diassembler.cs b/BizHawk.Emulation/CPUs/68000/Diassembler.cs index bbbbe0399a..d9fb373ddc 100644 --- a/BizHawk.Emulation/CPUs/68000/Diassembler.cs +++ b/BizHawk.Emulation/CPUs/68000/Diassembler.cs @@ -87,7 +87,9 @@ namespace BizHawk.Emulation.CPUs.M68000 else if (Opcodes[op] == SUBI) SUBI_Disasm(info); else if (Opcodes[op] == SUBQ) SUBQ_Disasm(info); else if (Opcodes[op] == CMP) CMP_Disasm(info); + else if (Opcodes[op] == CMPM) CMPM_Disasm(info); else if (Opcodes[op] == CMPA) CMPA_Disasm(info); + else if (Opcodes[op] == CMPI) CMPI_Disasm(info); else if (Opcodes[op] == MULU) MULU_Disasm(info); else if (Opcodes[op] == MULS) MULS_Disasm(info); diff --git a/BizHawk.Emulation/CPUs/68000/Instructions/IntegerMath.cs b/BizHawk.Emulation/CPUs/68000/Instructions/IntegerMath.cs index 259d99642b..72f3a8bb46 100644 --- a/BizHawk.Emulation/CPUs/68000/Instructions/IntegerMath.cs +++ b/BizHawk.Emulation/CPUs/68000/Instructions/IntegerMath.cs @@ -9,7 +9,7 @@ namespace BizHawk.Emulation.CPUs.M68000 int Dreg = (op >> 9) & 7; int size = (op >> 6) & 3; int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; + int reg = (op >> 0) & 7; switch (size) { @@ -60,7 +60,7 @@ namespace BizHawk.Emulation.CPUs.M68000 int Dreg = (op >> 9) & 7; int size = (op >> 6) & 3; int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; + int reg = (op >> 0) & 7; switch (size) { @@ -108,13 +108,12 @@ namespace BizHawk.Emulation.CPUs.M68000 void ADD_Disasm(DisassemblyInfo info) { - int pc = info.PC + 2; - + int pc = info.PC + 2; int Dreg = (op >> 9) & 7; - int dir = (op >> 8) & 1; + int dir = (op >> 8) & 1; int size = (op >> 6) & 3; int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; + int reg = (op >> 0) & 7; string op1 = "D" + Dreg; string op2; @@ -187,8 +186,7 @@ namespace BizHawk.Emulation.CPUs.M68000 void ADDI_Disasm(DisassemblyInfo info) { - int pc = info.PC + 2; - + int pc = info.PC + 2; int size = (op >> 6) & 3; int mode = (op >> 3) & 7; int reg = (op >> 0) & 3; @@ -281,7 +279,7 @@ namespace BizHawk.Emulation.CPUs.M68000 void ADDQ_Disasm(DisassemblyInfo info) { - int pc = info.PC + 2; + int pc = info.PC + 2; int data = (op >> 9) & 7; int size = (op >> 6) & 3; int mode = (op >> 3) & 7; @@ -322,8 +320,7 @@ namespace BizHawk.Emulation.CPUs.M68000 void ADDA_Disasm(DisassemblyInfo info) { - int pc = info.PC + 2; - + int pc = info.PC + 2; int aReg = (op >> 9) & 7; int size = (op >> 8) & 1; int mode = (op >> 3) & 7; @@ -340,7 +337,7 @@ namespace BizHawk.Emulation.CPUs.M68000 int Dreg = (op >> 9) & 7; int size = (op >> 6) & 3; int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; + int reg = (op >> 0) & 7; switch (size) { @@ -391,7 +388,7 @@ namespace BizHawk.Emulation.CPUs.M68000 int Dreg = (op >> 9) & 7; int size = (op >> 6) & 3; int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; + int reg = (op >> 0) & 7; switch (size) { @@ -439,8 +436,7 @@ namespace BizHawk.Emulation.CPUs.M68000 void SUB_Disasm(DisassemblyInfo info) { - int pc = info.PC + 2; - + int pc = info.PC + 2; int Dreg = (op >> 9) & 7; int dir = (op >> 8) & 1; int size = (op >> 6) & 3; @@ -518,8 +514,7 @@ namespace BizHawk.Emulation.CPUs.M68000 void SUBI_Disasm(DisassemblyInfo info) { - int pc = info.PC + 2; - + int pc = info.PC + 2; int size = (op >> 6) & 3; int mode = (op >> 3) & 7; int reg = (op >> 0) & 3; @@ -547,7 +542,7 @@ namespace BizHawk.Emulation.CPUs.M68000 int data = (op >> 9) & 7; int size = (op >> 6) & 3; int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; + int reg = (op >> 0) & 7; data = data == 0 ? 8 : data; // range is 1-8; 0 represents 8 @@ -612,11 +607,11 @@ namespace BizHawk.Emulation.CPUs.M68000 void SUBQ_Disasm(DisassemblyInfo info) { - int pc = info.PC + 2; + int pc = info.PC + 2; int data = (op >> 9) & 7; int size = (op >> 6) & 3; int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; + int reg = (op >> 0) & 7; data = data == 0 ? 8 : data; // range is 1-8; 0 represents 8 @@ -670,7 +665,7 @@ namespace BizHawk.Emulation.CPUs.M68000 { int size = (op >> 6) & 0x03; int mode = (op >> 3) & 0x07; - int reg = op & 0x07; + int reg = op & 0x07; if (mode == 1) throw new Exception("NEG on address reg is invalid"); @@ -725,7 +720,7 @@ namespace BizHawk.Emulation.CPUs.M68000 { int size = (op >> 6) & 0x03; int mode = (op >> 3) & 0x07; - int reg = op & 0x07; + int reg = op & 0x07; int pc = info.PC + 2; @@ -884,12 +879,78 @@ namespace BizHawk.Emulation.CPUs.M68000 info.Length = pc - info.PC; } + void CMPM() + { + int axReg = (op >> 9) & 7; //dst + int size = (op >> 6) & 3; + int ayReg = (op >> 0) & 7; //src + + switch (size) + { + case 0: // byte + { + sbyte src = ReadByte(A[ayReg].s32); A[ayReg].s32 += 1; if (axReg == 7) A[axReg].s32++; // A7 must stay word aligned + sbyte dst = ReadByte(A[axReg].s32); A[axReg].s32 += 1; if (ayReg == 7) A[ayReg].s32++; + int result = dst - src; + int uresult = (byte) dst - (byte) src; + N = (result & 0x80) != 0; + Z = result == 0; + V = result > sbyte.MaxValue || result < sbyte.MinValue; + C = (uresult & 0x100) != 0; + PendingCycles -= 12; + return; + } + case 1: // word + { + short src = ReadWord(A[ayReg].s32); A[ayReg].s32 += 2; + short dst = ReadWord(A[axReg].s32); A[axReg].s32 += 2; + int result = dst - src; + int uresult = (ushort) dst - (ushort) src; + N = (result & 0x8000) != 0; + Z = result == 0; + V = result > short.MaxValue || result < short.MinValue; + C = (uresult & 0x10000) != 0; + PendingCycles -= 12; + return; + } + case 2: // long + { + int src = ReadLong(A[ayReg].s32); A[ayReg].s32 += 4; + int dst = ReadLong(A[axReg].s32); A[axReg].s32 += 4; + long result = dst - src; + long uresult = (uint) dst - (uint) src; + N = (result & 0x80000000) != 0; + Z = result == 0; + V = result > int.MaxValue || result < int.MinValue; + C = (uresult & 0x100000000) != 0; + PendingCycles -= 20; + return; + } + } + } + + void CMPM_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int axReg = (op >> 9) & 7; + int size = (op >> 6) & 3; + int ayReg = (op >> 0) & 7; + + switch (size) + { + case 0: info.Mnemonic = "cmpm.b"; break; + case 1: info.Mnemonic = "cmpm.w"; break; + case 2: info.Mnemonic = "cmpm.l"; break; + } + info.Args = string.Format("(A{0})+, (A{1})+", ayReg, axReg); + info.Length = pc - info.PC; + } void CMPI() { int size = (op >> 6) & 3; int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; + int reg = (op >> 0) & 7; switch (size) { @@ -940,10 +1001,10 @@ namespace BizHawk.Emulation.CPUs.M68000 void CMPI_Disasm(DisassemblyInfo info) { - int pc = info.PC + 2; + int pc = info.PC + 2; int size = (op >> 6) & 3; int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; + int reg = (op >> 0) & 7; int immediate; switch (size) @@ -971,7 +1032,7 @@ namespace BizHawk.Emulation.CPUs.M68000 { int dreg = (op >> 9) & 7; int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; + int reg = (op >> 0) & 7; uint result = (uint) (D[dreg].u16 * (ushort)ReadValueW(mode, reg)); D[dreg].u32 = result; diff --git a/BizHawk.Emulation/CPUs/68000/OpcodeTable.cs b/BizHawk.Emulation/CPUs/68000/OpcodeTable.cs index 3387396be8..f302f484bf 100644 --- a/BizHawk.Emulation/CPUs/68000/OpcodeTable.cs +++ b/BizHawk.Emulation/CPUs/68000/OpcodeTable.cs @@ -9,6 +9,8 @@ namespace BizHawk.Emulation.CPUs.M68000 { // NOTE: Do not change the order of these assigns without testing. There is // some overwriting of less-specific opcodes with more-specific opcodes. + // TODO: should really come up with means of only assigning to applicable addressing modes, + // instead of this lame overwriting business. Assign("move", MOVE, "00", "Size2_0", "XnAm", "AmXn"); Assign("movea", MOVEA, "00", "Size2_0", "Xn", "001", "AmXn"); @@ -74,6 +76,7 @@ namespace BizHawk.Emulation.CPUs.M68000 Assign("subi", SUBI, "00000100", "Size2_1", "AmXn"); Assign("subq", SUBQ, "0101", "Data3", "1", "Size2_1", "AmXn"); Assign("cmp", CMP, "1011", "Xn", "0", "Size2_1", "AmXn"); + Assign("cmpm", CMPM, "1011", "Xn", "1", "Size2_1", "001", "Xn"); Assign("cmpa", CMPA, "1011", "Xn", "Size1", "11", "AmXn"); Assign("cmpi", CMPI, "00001100", "Size2_1", "AmXn"); Assign("mulu", MULU, "1100", "Xn", "011", "AmXn"); // TODO accurate timing @@ -116,7 +119,7 @@ namespace BizHawk.Emulation.CPUs.M68000 foreach (var opcode in opList) { int opc = Convert.ToInt32(opcode, 2); - if (Opcodes[opc] != null && instr.NotIn("movea","andi2sr","eori2sr","ori2sr","ext","dbcc","swap")) + if (Opcodes[opc] != null && instr.NotIn("movea","andi2sr","eori2sr","ori2sr","ext","dbcc","swap","cmpm")) Console.WriteLine("Setting opcode for {0}, a handler is already set. overwriting. {1:X4}", instr, opc); Opcodes[opc] = exec; }