68000 timings and flags fixes, some new opcode handlers

This commit is contained in:
beirich 2011-10-07 03:04:48 +00:00
parent dcc0a34d93
commit f2ca21759c
13 changed files with 495 additions and 243 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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;
/// <summary>Machine/Interrupt mode</summary>
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)]

View File

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

View File

@ -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<string> opList = new List<string>();
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<string> ops, string constant)
void AppendConstant(List<string> ops, string constant)
{
for (int i=0; i<ops.Count; i++)
ops[i] = ops[i] + constant;
}
private List<string> AppendPermutations(List<string> ops, string[] permutations)
List<string> AppendPermutations(List<string> ops, string[] permutations)
{
List<string> output = new List<string>();
@ -114,7 +116,7 @@ namespace BizHawk.Emulation.CPUs.M68K
return output;
}
private List<string> AppendData(List<string> ops, int bits)
List<string> AppendData(List<string> ops, int bits)
{
List<string> output = new List<string>();
@ -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)

View File

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

View File

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

View File

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

View File

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