68000: implement CMPM

This commit is contained in:
beirich 2011-10-27 04:02:11 +00:00
parent e96912dab0
commit 7ae6dfb534
3 changed files with 93 additions and 27 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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;
}