diff --git a/BizHawk.Emulation/CPUs/68000/Diassembler.cs b/BizHawk.Emulation/CPUs/68000/Diassembler.cs index d9fb373ddc..34384c369d 100644 --- a/BizHawk.Emulation/CPUs/68000/Diassembler.cs +++ b/BizHawk.Emulation/CPUs/68000/Diassembler.cs @@ -1,6 +1,6 @@ using System.Text; -namespace BizHawk.Emulation.CPUs.M68000 +namespace BizHawk.Emulation.Common.Components.M68000 { public sealed class DisassemblyInfo { diff --git a/BizHawk.Emulation/CPUs/68000/Instructions/BitArithemetic.cs b/BizHawk.Emulation/CPUs/68000/Instructions/BitArithemetic.cs index f7330e3fea..2f8c963996 100644 --- a/BizHawk.Emulation/CPUs/68000/Instructions/BitArithemetic.cs +++ b/BizHawk.Emulation/CPUs/68000/Instructions/BitArithemetic.cs @@ -1,1259 +1,1259 @@ using System; -namespace BizHawk.Emulation.CPUs.M68000 +namespace BizHawk.Emulation.Common.Components.M68000 { - partial class MC68000 - { - // TODO, the timing on AND variants is wrong. IE, and.w w/ immediate should be 8 cycles, but I cant figure out how that should work. - void AND0() // AND , Dn - { - int dstReg = (op >> 9) & 0x07; - int size = (op >> 6) & 0x03; - int srcMode = (op >> 3) & 0x07; - int srcReg = op & 0x07; - - V = false; - C = false; - - switch (size) - { - case 0: // Byte - D[dstReg].s8 &= ReadValueB(srcMode, srcReg); - PendingCycles -= (srcMode == 0) ? 4 : 8 + EACyclesBW[srcMode, srcReg]; - N = (D[dstReg].s8 & 0x80) != 0; - Z = (D[dstReg].s8 == 0); - return; - case 1: // Word - D[dstReg].s16 &= ReadValueW(srcMode, srcReg); - PendingCycles -= (srcMode == 0) ? 4 : 8 + EACyclesBW[srcMode, srcReg]; - N = (D[dstReg].s16 & 0x8000) != 0; - Z = (D[dstReg].s16 == 0); - return; - case 2: // Long - D[dstReg].s32 &= ReadValueL(srcMode, srcReg); - PendingCycles -= (srcMode == 0) ? 8 : 12 + EACyclesL[srcMode, srcReg]; - N = (D[dstReg].s32 & 0x80000000) != 0; - Z = (D[dstReg].s32 == 0); - return; - } - } - - void AND0_Disasm(DisassemblyInfo info) - { - int dstReg = (op >> 9) & 0x07; - int size = (op >> 6) & 0x03; - int srcMode = (op >> 3) & 0x07; - int srcReg = op & 0x07; - - int pc = info.PC + 2; - - switch (size) - { - case 0: // Byte - info.Mnemonic = "and.b"; - info.Args = string.Format("{0}, D{1}", DisassembleValue(srcMode, srcReg, 1, ref pc), dstReg); - break; - case 1: // Word - info.Mnemonic = "and.w"; - info.Args = string.Format("{0}, D{1}", DisassembleValue(srcMode, srcReg, 2, ref pc), dstReg); - break; - case 2: // Long - info.Mnemonic = "and.l"; - info.Args = string.Format("{0}, D{1}", DisassembleValue(srcMode, srcReg, 4, ref pc), dstReg); - break; - } - - info.Length = pc - info.PC; - } - - void AND1() // AND Dn, - { - int srcReg = (op >> 9) & 0x07; - int size = (op >> 6) & 0x03; - int dstMode = (op >> 3) & 0x07; - int dstReg = op & 0x07; - - V = false; - C = false; - - switch (size) - { - case 0: // Byte - { - sbyte dest = PeekValueB(dstMode, dstReg); - sbyte value = (sbyte)(dest & D[srcReg].s8); - WriteValueB(dstMode, dstReg, value); - PendingCycles -= (dstMode == 0) ? 4 : 8 + EACyclesBW[dstMode, dstReg]; - N = (value & 0x80) != 0; - Z = (value == 0); - return; - } - case 1: // Word - { - short dest = PeekValueW(dstMode, dstReg); - short value = (short)(dest & D[srcReg].s16); - WriteValueW(dstMode, dstReg, value); - PendingCycles -= (dstMode == 0) ? 4 : 8 + EACyclesBW[dstMode, dstReg]; - N = (value & 0x8000) != 0; - Z = (value == 0); - return; - } - case 2: // Long - { - int dest = PeekValueL(dstMode, dstReg); - int value = dest & D[srcReg].s32; - WriteValueL(dstMode, dstReg, value); - PendingCycles -= (dstMode == 0) ? 8 : 12 + EACyclesL[dstMode, dstReg]; - N = (value & 0x80000000) != 0; - Z = (value == 0); - return; - } - } - } - - void AND1_Disasm(DisassemblyInfo info) - { - int srcReg = (op >> 9) & 0x07; - int size = (op >> 6) & 0x03; - int dstMode = (op >> 3) & 0x07; - int dstReg = op & 0x07; - - int pc = info.PC + 2; - - switch (size) - { - case 0: // Byte - info.Mnemonic = "and.b"; - info.Args = string.Format("D{0}, {1}", srcReg, DisassembleValue(dstMode, dstReg, 1, ref pc)); - break; - case 1: // Word - info.Mnemonic = "and.w"; - info.Args = string.Format("D{0}, {1}", srcReg, DisassembleValue(dstMode, dstReg, 2, ref pc)); - break; - case 2: // Long - info.Mnemonic = "and.l"; - info.Args = string.Format("D{0}, {1}", srcReg, DisassembleValue(dstMode, dstReg, 4, ref pc)); - break; - } - - info.Length = pc - info.PC; - } - - void ANDI() // ANDI #, - { - int size = (op >> 6) & 0x03; - int dstMode = (op >> 3) & 0x07; - int dstReg = op & 0x07; - - V = false; - C = false; - - switch (size) - { - case 0: // Byte - { - sbyte imm = (sbyte)ReadWord(PC); PC += 2; - sbyte arg = PeekValueB(dstMode, dstReg); - sbyte result = (sbyte)(imm & arg); - WriteValueB(dstMode, dstReg, result); - PendingCycles -= (dstMode == 0) ? 8 : 12 + EACyclesBW[dstMode, dstReg]; - N = (result & 0x80) != 0; - Z = (result == 0); - return; - } - case 1: // Word - { - short imm = ReadWord(PC); PC += 2; - short arg = PeekValueW(dstMode, dstReg); - short result = (short)(imm & arg); - WriteValueW(dstMode, dstReg, result); - PendingCycles -= (dstMode == 0) ? 8 : 12 + EACyclesBW[dstMode, dstReg]; - N = (result & 0x8000) != 0; - Z = (result == 0); - return; - } - case 2: // Long - { - int imm = ReadLong(PC); PC += 4; - int arg = PeekValueL(dstMode, dstReg); - int result = imm & arg; - WriteValueL(dstMode, dstReg, result); - PendingCycles -= (dstMode == 0) ? 8 : 12 + EACyclesL[dstMode, dstReg]; - N = (result & 0x80000000) != 0; - Z = (result == 0); - return; - } - } - } - - void ANDI_Disasm(DisassemblyInfo info) - { - int size = ((op >> 6) & 0x03); - int dstMode = ((op >> 3) & 0x07); - int dstReg = (op & 0x07); - - int pc = info.PC + 2; - - switch (size) - { - case 0: // Byte - { - info.Mnemonic = "andi.b"; - sbyte imm = (sbyte)ReadWord(pc); pc += 2; - info.Args = string.Format("${0:X}, ", imm); - info.Args += DisassembleValue(dstMode, dstReg, 1, ref pc); - break; - } - case 1: // Word - { - info.Mnemonic = "andi.w"; - short imm = ReadWord(pc); pc += 2; - info.Args = string.Format("${0:X}, ", imm); - info.Args += DisassembleValue(dstMode, dstReg, 2, ref pc); - break; - } - case 2: // Long - { - info.Mnemonic = "andi.l"; - int imm = ReadLong(pc); pc += 4; - info.Args = string.Format("${0:X}, ", imm); - info.Args += DisassembleValue(dstMode, dstReg, 4, ref pc); - break; - } - } - - info.Length = pc - info.PC; - } - - void EOR() // EOR Dn, - { - int srcReg = (op >> 9) & 0x07; - int size = (op >> 6) & 0x03; - int dstMode = (op >> 3) & 0x07; - int dstReg = op & 0x07; - - V = false; - C = false; - - switch (size) - { - case 0: // Byte - { - sbyte dest = PeekValueB(dstMode, dstReg); - sbyte value = (sbyte)(dest ^ D[srcReg].s8); - WriteValueB(dstMode, dstReg, value); - PendingCycles -= (dstMode == 0) ? 4 : 8 + EACyclesBW[dstMode, dstReg]; - N = (value & 0x80) != 0; - Z = (value == 0); - return; - } - case 1: // Word - { - short dest = PeekValueW(dstMode, dstReg); - short value = (short)(dest ^ D[srcReg].s16); - WriteValueW(dstMode, dstReg, value); - PendingCycles -= (dstMode == 0) ? 4 : 8 + EACyclesBW[dstMode, dstReg]; - N = (value & 0x8000) != 0; - Z = (value == 0); - return; - } - case 2: // Long - { - int dest = PeekValueL(dstMode, dstReg); - int value = dest ^ D[srcReg].s32; - WriteValueL(dstMode, dstReg, value); - PendingCycles -= (dstMode == 0) ? 8 : 12 + EACyclesL[dstMode, dstReg]; - N = (value & 0x80000000) != 0; - Z = (value == 0); - return; - } - } - } - - void EOR_Disasm(DisassemblyInfo info) - { - int srcReg = (op >> 9) & 0x07; - int size = (op >> 6) & 0x03; - int dstMode = (op >> 3) & 0x07; - int dstReg = op & 0x07; - - int pc = info.PC + 2; - - switch (size) - { - case 0: // Byte - info.Mnemonic = "eor.b"; - info.Args = string.Format("D{0}, {1}", srcReg, DisassembleValue(dstMode, dstReg, 1, ref pc)); - break; - case 1: // Word - info.Mnemonic = "eor.w"; - info.Args = string.Format("D{0}, {1}", srcReg, DisassembleValue(dstMode, dstReg, 2, ref pc)); - break; - case 2: // Long - info.Mnemonic = "eor.l"; - info.Args = string.Format("D{0}, {1}", srcReg, DisassembleValue(dstMode, dstReg, 4, ref pc)); - break; - } - - info.Length = pc - info.PC; - } - - void EORI() - { - int size = (op >> 6) & 3; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - - V = false; - 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 & 0x80) != 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 & 0x8000) != 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 & 0x80000000) != 0; - Z = value == 0; - PendingCycles -= mode == 0 ? 16 : 20 + EACyclesL[mode, reg]; - return; - } - } - } - - void EORI_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int size = (op >> 6) & 3; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - - switch (size) - { - case 0: // byte - { - info.Mnemonic = "eori.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 = "eori.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 = "eori.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 OR0() // OR , Dn - { - int dstReg = (op >> 9) & 0x07; - int size = (op >> 6) & 0x03; - int srcMode = (op >> 3) & 0x07; - int srcReg = op & 0x07; - - V = false; - C = false; - - switch (size) - { - case 0: // Byte - D[dstReg].s8 |= ReadValueB(srcMode, srcReg); - PendingCycles -= (srcMode == 0) ? 4 : 8 + EACyclesBW[srcMode, srcReg]; - N = (D[dstReg].s8 & 0x80) != 0; - Z = (D[dstReg].s8 == 0); - return; - case 1: // Word - D[dstReg].s16 |= ReadValueW(srcMode, srcReg); - PendingCycles -= (srcMode == 0) ? 4 : 8 + EACyclesBW[srcMode, srcReg]; - N = (D[dstReg].s16 & 0x8000) != 0; - Z = (D[dstReg].s16 == 0); - return; - case 2: // Long - D[dstReg].s32 |= ReadValueL(srcMode, srcReg); - PendingCycles -= (srcMode == 0) ? 8 : 12 + EACyclesL[srcMode, srcReg]; - N = (D[dstReg].s32 & 0x80000000) != 0; - Z = (D[dstReg].s32 == 0); - return; - } - } - - void OR0_Disasm(DisassemblyInfo info) - { - int dstReg = (op >> 9) & 0x07; - int size = (op >> 6) & 0x03; - int srcMode = (op >> 3) & 0x07; - int srcReg = op & 0x07; - - int pc = info.PC + 2; - - switch (size) - { - case 0: // Byte - info.Mnemonic = "or.b"; - info.Args = string.Format("{0}, D{1}", DisassembleValue(srcMode, srcReg, 1, ref pc), dstReg); - break; - case 1: // Word - info.Mnemonic = "or.w"; - info.Args = string.Format("{0}, D{1}", DisassembleValue(srcMode, srcReg, 2, ref pc), dstReg); - break; - case 2: // Long - info.Mnemonic = "or.l"; - info.Args = string.Format("{0}, D{1}", DisassembleValue(srcMode, srcReg, 4, ref pc), dstReg); - break; - } - - info.Length = pc - info.PC; - } - - void OR1() // OR Dn, - { - int srcReg = (op >> 9) & 0x07; - int size = (op >> 6) & 0x03; - int dstMode = (op >> 3) & 0x07; - int dstReg = op & 0x07; - - V = false; - C = false; - - switch (size) - { - case 0: // Byte - { - sbyte dest = PeekValueB(dstMode, dstReg); - sbyte value = (sbyte)(dest | D[srcReg].s8); - WriteValueB(dstMode, dstReg, value); - PendingCycles -= (dstMode == 0) ? 4 : 8 + EACyclesBW[dstMode, dstReg]; - N = (value & 0x80) != 0; - Z = (value == 0); - return; - } - case 1: // Word - { - short dest = PeekValueW(dstMode, dstReg); - short value = (short)(dest | D[srcReg].s16); - WriteValueW(dstMode, dstReg, value); - PendingCycles -= (dstMode == 0) ? 4 : 8 + EACyclesBW[dstMode, dstReg]; - N = (value & 0x8000) != 0; - Z = (value == 0); - return; - } - case 2: // Long - { - int dest = PeekValueL(dstMode, dstReg); - int value = dest | D[srcReg].s32; - WriteValueL(dstMode, dstReg, value); - PendingCycles -= (dstMode == 0) ? 8 : 12 + EACyclesL[dstMode, dstReg]; - N = (value & 0x80000000) != 0; - Z = (value == 0); - return; - } - } - } - - void OR1_Disasm(DisassemblyInfo info) - { - int srcReg = (op >> 9) & 0x07; - int size = (op >> 6) & 0x03; - int dstMode = (op >> 3) & 0x07; - int dstReg = op & 0x07; - - int pc = info.PC + 2; - - switch (size) - { - case 0: // Byte - info.Mnemonic = "or.b"; - info.Args = string.Format("D{0}, {1}", srcReg, DisassembleValue(dstMode, dstReg, 1, ref pc)); - break; - case 1: // Word - info.Mnemonic = "or.w"; - info.Args = string.Format("D{0}, {1}", srcReg, DisassembleValue(dstMode, dstReg, 2, ref pc)); - break; - case 2: // Long - info.Mnemonic = "or.l"; - info.Args = string.Format("D{0}, {1}", srcReg, DisassembleValue(dstMode, dstReg, 4, ref pc)); - break; - } - - info.Length = pc - info.PC; - } - - void ORI() - { - int size = (op >> 6) & 3; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - - V = false; - 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 & 0x80) != 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 & 0x8000) != 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 & 0x80000000) != 0; - Z = value == 0; - PendingCycles -= mode == 0 ? 16 : 20 + EACyclesL[mode, reg]; - return; - } - } - } - - void ORI_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - 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 NOT() - { - int size = (op >> 6) & 0x03; - int mode = (op >> 3) & 0x07; - int reg = op & 0x07; - - V = false; - C = false; - - switch (size) - { - case 0: // Byte - { - sbyte value = PeekValueB(mode, reg); - value = (sbyte) ~value; - WriteValueB(mode, reg, value); - PendingCycles -= (mode == 0) ? 4 : 8 + EACyclesBW[mode, reg]; - N = (value & 0x80) != 0; - Z = (value == 0); - return; - } - case 1: // Word - { - short value = PeekValueW(mode, reg); - value = (short) ~value; - WriteValueW(mode, reg, value); - PendingCycles -= (mode == 0) ? 4 : 8 + EACyclesBW[mode, reg]; - N = (value & 0x8000) != 0; - Z = (value == 0); - return; - } - case 2: // Long - { - int value = PeekValueL(mode, reg); - value = ~value; - WriteValueL(mode, reg, value); - PendingCycles -= (mode == 0) ? 8 : 12 + EACyclesL[mode, reg]; - N = (value & 0x80000000) != 0; - Z = (value == 0); - return; - } - } - } - - void NOT_Disasm(DisassemblyInfo info) - { - int size = (op >> 6) & 0x03; - int mode = (op >> 3) & 0x07; - int reg = op & 0x07; - - int pc = info.PC + 2; - - switch (size) - { - case 0: // Byte - info.Mnemonic = "not.b"; - info.Args = DisassembleValue(mode, reg, 1, ref pc); - break; - case 1: // Word - info.Mnemonic = "not.w"; - info.Args = DisassembleValue(mode, reg, 2, ref pc); - break; - case 2: // Long - info.Mnemonic = "not.l"; - info.Args = DisassembleValue(mode, reg, 4, ref pc); - break; - } - - info.Length = pc - info.PC; - } - - void LSLd() - { - int rot = (op >> 9) & 7; - int size = (op >> 6) & 3; - int m = (op >> 5) & 1; - int reg = op & 7; - - if (m == 0 && rot == 0) rot = 8; - else if (m == 1) rot = D[rot].s32 & 63; - - V = false; - C = false; - - switch (size) - { - case 0: // byte - for (int i=0; i> 9) & 7; - int size = (op >> 6) & 3; - int m = (op >> 5) & 1; - int reg = op & 7; - - if (m == 0 && rot == 0) rot = 8; - - switch (size) - { - case 0: info.Mnemonic = "lsl.b"; break; - case 1: info.Mnemonic = "lsl.w"; break; - case 2: info.Mnemonic = "lsl.l"; break; - } - if (m==0) info.Args = rot+", D"+reg; - else info.Args = "D"+rot+", D"+reg; - - info.Length = pc - info.PC; - } - - void LSRd() - { - int rot = (op >> 9) & 7; - int size = (op >> 6) & 3; - int m = (op >> 5) & 1; - int reg = op & 7; - - if (m == 0 && rot == 0) rot = 8; - else if (m == 1) rot = D[rot].s32 & 63; - - V = false; - C = false; - - switch (size) - { - case 0: // byte - for (int i = 0; i < rot; i++) - { - C = X = (D[reg].u8 & 1) != 0; - D[reg].u8 >>= 1; - } - N = (D[reg].s8 & 0x80) != 0; - Z = D[reg].u8 == 0; - PendingCycles -= 6 + (rot * 2); - return; - case 1: // word - for (int i = 0; i < rot; i++) - { - C = X = (D[reg].u16 & 1) != 0; - D[reg].u16 >>= 1; - } - N = (D[reg].s16 & 0x8000) != 0; - Z = D[reg].u16 == 0; - PendingCycles -= 6 + (rot * 2); - return; - case 2: // long - for (int i = 0; i < rot; i++) - { - C = X = (D[reg].u32 & 1) != 0; - D[reg].u32 >>= 1; - } - N = (D[reg].s32 & 0x80000000) != 0; - Z = D[reg].u32 == 0; - PendingCycles -= 8 + (rot * 2); - return; - } - } - - void LSRd_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int rot = (op >> 9) & 7; - int size = (op >> 6) & 3; - int m = (op >> 5) & 1; - int reg = op & 7; - - if (m == 0 && rot == 0) rot = 8; - - switch (size) - { - case 0: info.Mnemonic = "lsr.b"; break; - case 1: info.Mnemonic = "lsr.w"; break; - case 2: info.Mnemonic = "lsr.l"; break; - } - if (m == 0) info.Args = rot + ", D" + reg; - else info.Args = "D" + rot + ", D" + reg; - - info.Length = pc - info.PC; - } - - void ASLd() - { - int rot = (op >> 9) & 7; - int size = (op >> 6) & 3; - int m = (op >> 5) & 1; - int reg = op & 7; - - if (m == 0 && rot == 0) rot = 8; - else if (m == 1) rot = D[rot].s32 & 63; - - V = false; - C = false; - - switch (size) - { - case 0: // byte - for (int i = 0; i < rot; i++) - { - bool msb = D[reg].s8 < 0; - C = X = (D[reg].u8 & 0x80) != 0; - D[reg].s8 <<= 1; - V |= (D[reg].s8 < 0) != msb; - } - N = (D[reg].s8 & 0x80) != 0; - Z = D[reg].u8 == 0; - PendingCycles -= 6 + (rot * 2); - return; - case 1: // word - for (int i = 0; i < rot; i++) - { - bool msb = D[reg].s16 < 0; - C = X = (D[reg].u16 & 0x8000) != 0; - D[reg].s16 <<= 1; - V |= (D[reg].s16 < 0) != msb; - } - N = (D[reg].s16 & 0x8000) != 0; - Z = D[reg].u16 == 0; - PendingCycles -= 6 + (rot * 2); - return; - case 2: // long - for (int i = 0; i < rot; i++) - { - bool msb = D[reg].s32 < 0; - C = X = (D[reg].u32 & 0x80000000) != 0; - D[reg].s32 <<= 1; - V |= (D[reg].s32 < 0) != msb; - } - N = (D[reg].s32 & 0x80000000) != 0; - Z = D[reg].u32 == 0; - PendingCycles -= 8 + (rot * 2); - return; - } - } - - void ASLd_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int rot = (op >> 9) & 7; - int size = (op >> 6) & 3; - int m = (op >> 5) & 1; - int reg = op & 7; - - if (m == 0 && rot == 0) rot = 8; - - switch (size) - { - case 0: info.Mnemonic = "asl.b"; break; - case 1: info.Mnemonic = "asl.w"; break; - case 2: info.Mnemonic = "asl.l"; break; - } - if (m == 0) info.Args = rot + ", D" + reg; - else info.Args = "D" + rot + ", D" + reg; - - info.Length = pc - info.PC; - } - - void ASRd() - { - int rot = (op >> 9) & 7; - int size = (op >> 6) & 3; - int m = (op >> 5) & 1; - int reg = op & 7; - - if (m == 0 && rot == 0) rot = 8; - else if (m == 1) rot = D[rot].s32 & 63; - - V = false; - C = false; - - switch (size) - { - case 0: // byte - for (int i = 0; i < rot; i++) - { - bool msb = D[reg].s8 < 0; - C = X = (D[reg].u8 & 1) != 0; - D[reg].s8 >>= 1; - V |= (D[reg].s8 < 0) != msb; - } - N = (D[reg].s8 & 0x80) != 0; - Z = D[reg].u8 == 0; - PendingCycles -= 6 + (rot * 2); - return; - case 1: // word - for (int i = 0; i < rot; i++) - { - bool msb = D[reg].s16 < 0; - C = X = (D[reg].u16 & 1) != 0; - D[reg].s16 >>= 1; - V |= (D[reg].s16 < 0) != msb; - } - N = (D[reg].s16 & 0x8000) != 0; - Z = D[reg].u16 == 0; - PendingCycles -= 6 + (rot * 2); - return; - case 2: // long - for (int i = 0; i < rot; i++) - { - bool msb = D[reg].s32 < 0; - C = X = (D[reg].u32 & 1) != 0; - D[reg].s32 >>= 1; - V |= (D[reg].s32 < 0) != msb; - } - N = (D[reg].s32 & 0x80000000) != 0; - Z = D[reg].u32 == 0; - PendingCycles -= 8 + (rot * 2); - return; - } - } - - void ASRd_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int rot = (op >> 9) & 7; - int size = (op >> 6) & 3; - int m = (op >> 5) & 1; - int reg = op & 7; - - if (m == 0 && rot == 0) rot = 8; - - switch (size) - { - case 0: info.Mnemonic = "asr.b"; break; - case 1: info.Mnemonic = "asr.w"; break; - case 2: info.Mnemonic = "asr.l"; break; - } - if (m == 0) info.Args = rot + ", D" + reg; - else info.Args = "D" + rot + ", D" + reg; - - info.Length = pc - info.PC; - } - - void ROLd() - { - int rot = (op >> 9) & 7; - int size = (op >> 6) & 3; - int m = (op >> 5) & 1; - int reg = op & 7; - - if (m == 0 && rot == 0) rot = 8; - else if (m == 1) rot = D[rot].s32 & 63; - - V = false; - C = false; - - switch (size) - { - case 0: // byte - for (int i = 0; i < rot; i++) - { - C = (D[reg].u8 & 0x80) != 0; - D[reg].u8 = (byte) ((D[reg].u8 << 1) | (D[reg].u8 >> 7)); - } - N = (D[reg].s8 & 0x80) != 0; - Z = D[reg].u8 == 0; - PendingCycles -= 6 + (rot * 2); - return; - case 1: // word - for (int i = 0; i < rot; i++) - { - C = (D[reg].u16 & 0x8000) != 0; - D[reg].u16 = (ushort) ((D[reg].u16 << 1) | (D[reg].u16 >> 15)); - } - N = (D[reg].s16 & 0x8000) != 0; - Z = D[reg].u16 == 0; - PendingCycles -= 6 + (rot * 2); - return; - case 2: // long - for (int i = 0; i < rot; i++) - { - C = (D[reg].u32 & 0x80000000) != 0; - D[reg].u32 = ((D[reg].u32 << 1) | (D[reg].u32 >> 31)); - } - N = (D[reg].s32 & 0x80000000) != 0; - Z = D[reg].u32 == 0; - PendingCycles -= 8 + (rot * 2); - return; - } - } - - void ROLd_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int rot = (op >> 9) & 7; - int size = (op >> 6) & 3; - int m = (op >> 5) & 1; - int reg = op & 7; - - if (m == 0 && rot == 0) rot = 8; - - switch (size) - { - case 0: info.Mnemonic = "rol.b"; break; - case 1: info.Mnemonic = "rol.w"; break; - case 2: info.Mnemonic = "rol.l"; break; - } - if (m == 0) info.Args = rot + ", D" + reg; - else info.Args = "D" + rot + ", D" + reg; - - info.Length = pc - info.PC; - } - - void RORd() - { - int rot = (op >> 9) & 7; - int size = (op >> 6) & 3; - int m = (op >> 5) & 1; - int reg = op & 7; - - if (m == 0 && rot == 0) rot = 8; - else if (m == 1) rot = D[rot].s32 & 63; - - V = false; - C = false; - - switch (size) - { - case 0: // byte - for (int i = 0; i < rot; i++) - { - C = (D[reg].u8 & 1) != 0; - D[reg].u8 = (byte)((D[reg].u8 >> 1) | (D[reg].u8 << 7)); - } - N = (D[reg].s8 & 0x80) != 0; - Z = D[reg].u8 == 0; - PendingCycles -= 6 + (rot * 2); - return; - case 1: // word - for (int i = 0; i < rot; i++) - { - C = (D[reg].u16 & 1) != 0; - D[reg].u16 = (ushort)((D[reg].u16 >> 1) | (D[reg].u16 << 15)); - } - N = (D[reg].s16 & 0x8000) != 0; - Z = D[reg].u16 == 0; - PendingCycles -= 6 + (rot * 2); - return; - case 2: // long - for (int i = 0; i < rot; i++) - { - C = (D[reg].u32 & 1) != 0; - D[reg].u32 = ((D[reg].u32 >> 1) | (D[reg].u32 << 31)); - } - N = (D[reg].s32 & 0x80000000) != 0; - Z = D[reg].u32 == 0; - PendingCycles -= 8 + (rot * 2); - return; - } - } - - void RORd_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int rot = (op >> 9) & 7; - int size = (op >> 6) & 3; - int m = (op >> 5) & 1; - int reg = op & 7; - - if (m == 0 && rot == 0) rot = 8; - - switch (size) - { - case 0: info.Mnemonic = "ror.b"; break; - case 1: info.Mnemonic = "ror.w"; break; - case 2: info.Mnemonic = "ror.l"; break; - } - if (m == 0) info.Args = rot + ", D" + reg; - else info.Args = "D" + rot + ", D" + reg; - - info.Length = pc - info.PC; - } - - void ROXLd() - { - int rot = (op >> 9) & 7; - int size = (op >> 6) & 3; - int m = (op >> 5) & 1; - int reg = op & 7; - - if (m == 0 && rot == 0) rot = 8; - else if (m == 1) rot = D[rot].s32 & 63; - - C = X; - V = false; - - switch (size) - { - case 0: // byte - for (int i = 0; i < rot; i++) - { - C = (D[reg].u8 & 0x80) != 0; - D[reg].u8 = (byte)((D[reg].u8 << 1) | (X ? 1 : 0)); - X = C; - } - N = (D[reg].s8 & 0x80) != 0; - Z = D[reg].s8 == 0; - PendingCycles -= 6 + (rot * 2); - return; - case 1: // word - for (int i = 0; i < rot; i++) - { - C = (D[reg].u16 & 0x8000) != 0; - D[reg].u16 = (ushort)((D[reg].u16 << 1) | (X ? 1 : 0)); - X = C; - } - N = (D[reg].s16 & 0x8000) != 0; - Z = D[reg].s16 == 0; - PendingCycles -= 6 + (rot * 2); - return; - case 2: // long - for (int i = 0; i < rot; i++) - { - C = (D[reg].s32 & 0x80000000) != 0; - D[reg].s32 = ((D[reg].s32 << 1) | (X ? 1 : 0)); - X = C; - } - N = (D[reg].s32 & 0x80000000) != 0; - Z = D[reg].s32 == 0; - PendingCycles -= 8 + (rot * 2); - return; - } - } - - void ROXLd_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int rot = (op >> 9) & 7; - int size = (op >> 6) & 3; - int m = (op >> 5) & 1; - int reg = op & 7; - - if (m == 0 && rot == 0) rot = 8; - - switch (size) - { - case 0: info.Mnemonic = "roxl.b"; break; - case 1: info.Mnemonic = "roxl.w"; break; - case 2: info.Mnemonic = "roxl.l"; break; - } - if (m == 0) info.Args = rot + ", D" + reg; - else info.Args = "D" + rot + ", D" + reg; - - info.Length = pc - info.PC; - } - - void ROXRd() - { - int rot = (op >> 9) & 7; - int size = (op >> 6) & 3; - int m = (op >> 5) & 1; - int reg = op & 7; - - if (m == 0 && rot == 0) rot = 8; - else if (m == 1) rot = D[rot].s32 & 63; - - C = X; - V = false; - - switch (size) - { - case 0: // byte - for (int i = 0; i < rot; i++) - { - C = (D[reg].u8 & 1) != 0; - D[reg].u8 = (byte)((D[reg].u8 >> 1) | (X ? 0x80 : 0)); - X = C; - } - N = (D[reg].s8 & 0x80) != 0; - Z = D[reg].s8 == 0; - PendingCycles -= 6 + (rot * 2); - return; - case 1: // word - for (int i = 0; i < rot; i++) - { - C = (D[reg].u16 & 1) != 0; - D[reg].u16 = (ushort)((D[reg].u16 >> 1) | (X ? 0x8000 : 0)); - X = C; - } - N = (D[reg].s16 & 0x8000) != 0; - Z = D[reg].s16 == 0; - PendingCycles -= 6 + (rot * 2); - return; - case 2: // long - for (int i = 0; i < rot; i++) - { - C = (D[reg].s32 & 1) != 0; - D[reg].u32 = ((D[reg].u32 >> 1) | (X ? 0x80000000 : 0)); - X = C; - } - N = (D[reg].s32 & 0x80000000) != 0; - Z = D[reg].s32 == 0; - PendingCycles -= 8 + (rot * 2); - return; - } - } - - void ROXRd_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int rot = (op >> 9) & 7; - int size = (op >> 6) & 3; - int m = (op >> 5) & 1; - int reg = op & 7; - - if (m == 0 && rot == 0) rot = 8; - - switch (size) - { - case 0: info.Mnemonic = "roxr.b"; break; - case 1: info.Mnemonic = "roxr.w"; break; - case 2: info.Mnemonic = "roxr.l"; break; - } - if (m == 0) info.Args = rot + ", D" + reg; - else info.Args = "D" + rot + ", D" + reg; - - info.Length = pc - info.PC; - } - - void SWAP() - { - int reg = op & 7; - D[reg].u32 = (D[reg].u32 << 16) | (D[reg].u32 >> 16); - V = C = false; - Z = D[reg].u32 == 0; - N = (D[reg].s32 & 0x80000000) != 0; - PendingCycles -= 4; - } - - void SWAP_Disasm(DisassemblyInfo info) - { - int reg = op & 7; - info.Mnemonic = "swap"; - info.Args = "D" + reg; - } - } + partial class MC68000 + { + // TODO, the timing on AND variants is wrong. IE, and.w w/ immediate should be 8 cycles, but I cant figure out how that should work. + void AND0() // AND , Dn + { + int dstReg = (op >> 9) & 0x07; + int size = (op >> 6) & 0x03; + int srcMode = (op >> 3) & 0x07; + int srcReg = op & 0x07; + + V = false; + C = false; + + switch (size) + { + case 0: // Byte + D[dstReg].s8 &= ReadValueB(srcMode, srcReg); + PendingCycles -= (srcMode == 0) ? 4 : 8 + EACyclesBW[srcMode, srcReg]; + N = (D[dstReg].s8 & 0x80) != 0; + Z = (D[dstReg].s8 == 0); + return; + case 1: // Word + D[dstReg].s16 &= ReadValueW(srcMode, srcReg); + PendingCycles -= (srcMode == 0) ? 4 : 8 + EACyclesBW[srcMode, srcReg]; + N = (D[dstReg].s16 & 0x8000) != 0; + Z = (D[dstReg].s16 == 0); + return; + case 2: // Long + D[dstReg].s32 &= ReadValueL(srcMode, srcReg); + PendingCycles -= (srcMode == 0) ? 8 : 12 + EACyclesL[srcMode, srcReg]; + N = (D[dstReg].s32 & 0x80000000) != 0; + Z = (D[dstReg].s32 == 0); + return; + } + } + + void AND0_Disasm(DisassemblyInfo info) + { + int dstReg = (op >> 9) & 0x07; + int size = (op >> 6) & 0x03; + int srcMode = (op >> 3) & 0x07; + int srcReg = op & 0x07; + + int pc = info.PC + 2; + + switch (size) + { + case 0: // Byte + info.Mnemonic = "and.b"; + info.Args = string.Format("{0}, D{1}", DisassembleValue(srcMode, srcReg, 1, ref pc), dstReg); + break; + case 1: // Word + info.Mnemonic = "and.w"; + info.Args = string.Format("{0}, D{1}", DisassembleValue(srcMode, srcReg, 2, ref pc), dstReg); + break; + case 2: // Long + info.Mnemonic = "and.l"; + info.Args = string.Format("{0}, D{1}", DisassembleValue(srcMode, srcReg, 4, ref pc), dstReg); + break; + } + + info.Length = pc - info.PC; + } + + void AND1() // AND Dn, + { + int srcReg = (op >> 9) & 0x07; + int size = (op >> 6) & 0x03; + int dstMode = (op >> 3) & 0x07; + int dstReg = op & 0x07; + + V = false; + C = false; + + switch (size) + { + case 0: // Byte + { + sbyte dest = PeekValueB(dstMode, dstReg); + sbyte value = (sbyte)(dest & D[srcReg].s8); + WriteValueB(dstMode, dstReg, value); + PendingCycles -= (dstMode == 0) ? 4 : 8 + EACyclesBW[dstMode, dstReg]; + N = (value & 0x80) != 0; + Z = (value == 0); + return; + } + case 1: // Word + { + short dest = PeekValueW(dstMode, dstReg); + short value = (short)(dest & D[srcReg].s16); + WriteValueW(dstMode, dstReg, value); + PendingCycles -= (dstMode == 0) ? 4 : 8 + EACyclesBW[dstMode, dstReg]; + N = (value & 0x8000) != 0; + Z = (value == 0); + return; + } + case 2: // Long + { + int dest = PeekValueL(dstMode, dstReg); + int value = dest & D[srcReg].s32; + WriteValueL(dstMode, dstReg, value); + PendingCycles -= (dstMode == 0) ? 8 : 12 + EACyclesL[dstMode, dstReg]; + N = (value & 0x80000000) != 0; + Z = (value == 0); + return; + } + } + } + + void AND1_Disasm(DisassemblyInfo info) + { + int srcReg = (op >> 9) & 0x07; + int size = (op >> 6) & 0x03; + int dstMode = (op >> 3) & 0x07; + int dstReg = op & 0x07; + + int pc = info.PC + 2; + + switch (size) + { + case 0: // Byte + info.Mnemonic = "and.b"; + info.Args = string.Format("D{0}, {1}", srcReg, DisassembleValue(dstMode, dstReg, 1, ref pc)); + break; + case 1: // Word + info.Mnemonic = "and.w"; + info.Args = string.Format("D{0}, {1}", srcReg, DisassembleValue(dstMode, dstReg, 2, ref pc)); + break; + case 2: // Long + info.Mnemonic = "and.l"; + info.Args = string.Format("D{0}, {1}", srcReg, DisassembleValue(dstMode, dstReg, 4, ref pc)); + break; + } + + info.Length = pc - info.PC; + } + + void ANDI() // ANDI #, + { + int size = (op >> 6) & 0x03; + int dstMode = (op >> 3) & 0x07; + int dstReg = op & 0x07; + + V = false; + C = false; + + switch (size) + { + case 0: // Byte + { + sbyte imm = (sbyte)ReadWord(PC); PC += 2; + sbyte arg = PeekValueB(dstMode, dstReg); + sbyte result = (sbyte)(imm & arg); + WriteValueB(dstMode, dstReg, result); + PendingCycles -= (dstMode == 0) ? 8 : 12 + EACyclesBW[dstMode, dstReg]; + N = (result & 0x80) != 0; + Z = (result == 0); + return; + } + case 1: // Word + { + short imm = ReadWord(PC); PC += 2; + short arg = PeekValueW(dstMode, dstReg); + short result = (short)(imm & arg); + WriteValueW(dstMode, dstReg, result); + PendingCycles -= (dstMode == 0) ? 8 : 12 + EACyclesBW[dstMode, dstReg]; + N = (result & 0x8000) != 0; + Z = (result == 0); + return; + } + case 2: // Long + { + int imm = ReadLong(PC); PC += 4; + int arg = PeekValueL(dstMode, dstReg); + int result = imm & arg; + WriteValueL(dstMode, dstReg, result); + PendingCycles -= (dstMode == 0) ? 8 : 12 + EACyclesL[dstMode, dstReg]; + N = (result & 0x80000000) != 0; + Z = (result == 0); + return; + } + } + } + + void ANDI_Disasm(DisassemblyInfo info) + { + int size = ((op >> 6) & 0x03); + int dstMode = ((op >> 3) & 0x07); + int dstReg = (op & 0x07); + + int pc = info.PC + 2; + + switch (size) + { + case 0: // Byte + { + info.Mnemonic = "andi.b"; + sbyte imm = (sbyte)ReadWord(pc); pc += 2; + info.Args = string.Format("${0:X}, ", imm); + info.Args += DisassembleValue(dstMode, dstReg, 1, ref pc); + break; + } + case 1: // Word + { + info.Mnemonic = "andi.w"; + short imm = ReadWord(pc); pc += 2; + info.Args = string.Format("${0:X}, ", imm); + info.Args += DisassembleValue(dstMode, dstReg, 2, ref pc); + break; + } + case 2: // Long + { + info.Mnemonic = "andi.l"; + int imm = ReadLong(pc); pc += 4; + info.Args = string.Format("${0:X}, ", imm); + info.Args += DisassembleValue(dstMode, dstReg, 4, ref pc); + break; + } + } + + info.Length = pc - info.PC; + } + + void EOR() // EOR Dn, + { + int srcReg = (op >> 9) & 0x07; + int size = (op >> 6) & 0x03; + int dstMode = (op >> 3) & 0x07; + int dstReg = op & 0x07; + + V = false; + C = false; + + switch (size) + { + case 0: // Byte + { + sbyte dest = PeekValueB(dstMode, dstReg); + sbyte value = (sbyte)(dest ^ D[srcReg].s8); + WriteValueB(dstMode, dstReg, value); + PendingCycles -= (dstMode == 0) ? 4 : 8 + EACyclesBW[dstMode, dstReg]; + N = (value & 0x80) != 0; + Z = (value == 0); + return; + } + case 1: // Word + { + short dest = PeekValueW(dstMode, dstReg); + short value = (short)(dest ^ D[srcReg].s16); + WriteValueW(dstMode, dstReg, value); + PendingCycles -= (dstMode == 0) ? 4 : 8 + EACyclesBW[dstMode, dstReg]; + N = (value & 0x8000) != 0; + Z = (value == 0); + return; + } + case 2: // Long + { + int dest = PeekValueL(dstMode, dstReg); + int value = dest ^ D[srcReg].s32; + WriteValueL(dstMode, dstReg, value); + PendingCycles -= (dstMode == 0) ? 8 : 12 + EACyclesL[dstMode, dstReg]; + N = (value & 0x80000000) != 0; + Z = (value == 0); + return; + } + } + } + + void EOR_Disasm(DisassemblyInfo info) + { + int srcReg = (op >> 9) & 0x07; + int size = (op >> 6) & 0x03; + int dstMode = (op >> 3) & 0x07; + int dstReg = op & 0x07; + + int pc = info.PC + 2; + + switch (size) + { + case 0: // Byte + info.Mnemonic = "eor.b"; + info.Args = string.Format("D{0}, {1}", srcReg, DisassembleValue(dstMode, dstReg, 1, ref pc)); + break; + case 1: // Word + info.Mnemonic = "eor.w"; + info.Args = string.Format("D{0}, {1}", srcReg, DisassembleValue(dstMode, dstReg, 2, ref pc)); + break; + case 2: // Long + info.Mnemonic = "eor.l"; + info.Args = string.Format("D{0}, {1}", srcReg, DisassembleValue(dstMode, dstReg, 4, ref pc)); + break; + } + + info.Length = pc - info.PC; + } + + void EORI() + { + int size = (op >> 6) & 3; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + V = false; + 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 & 0x80) != 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 & 0x8000) != 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 & 0x80000000) != 0; + Z = value == 0; + PendingCycles -= mode == 0 ? 16 : 20 + EACyclesL[mode, reg]; + return; + } + } + } + + void EORI_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int size = (op >> 6) & 3; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + switch (size) + { + case 0: // byte + { + info.Mnemonic = "eori.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 = "eori.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 = "eori.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 OR0() // OR , Dn + { + int dstReg = (op >> 9) & 0x07; + int size = (op >> 6) & 0x03; + int srcMode = (op >> 3) & 0x07; + int srcReg = op & 0x07; + + V = false; + C = false; + + switch (size) + { + case 0: // Byte + D[dstReg].s8 |= ReadValueB(srcMode, srcReg); + PendingCycles -= (srcMode == 0) ? 4 : 8 + EACyclesBW[srcMode, srcReg]; + N = (D[dstReg].s8 & 0x80) != 0; + Z = (D[dstReg].s8 == 0); + return; + case 1: // Word + D[dstReg].s16 |= ReadValueW(srcMode, srcReg); + PendingCycles -= (srcMode == 0) ? 4 : 8 + EACyclesBW[srcMode, srcReg]; + N = (D[dstReg].s16 & 0x8000) != 0; + Z = (D[dstReg].s16 == 0); + return; + case 2: // Long + D[dstReg].s32 |= ReadValueL(srcMode, srcReg); + PendingCycles -= (srcMode == 0) ? 8 : 12 + EACyclesL[srcMode, srcReg]; + N = (D[dstReg].s32 & 0x80000000) != 0; + Z = (D[dstReg].s32 == 0); + return; + } + } + + void OR0_Disasm(DisassemblyInfo info) + { + int dstReg = (op >> 9) & 0x07; + int size = (op >> 6) & 0x03; + int srcMode = (op >> 3) & 0x07; + int srcReg = op & 0x07; + + int pc = info.PC + 2; + + switch (size) + { + case 0: // Byte + info.Mnemonic = "or.b"; + info.Args = string.Format("{0}, D{1}", DisassembleValue(srcMode, srcReg, 1, ref pc), dstReg); + break; + case 1: // Word + info.Mnemonic = "or.w"; + info.Args = string.Format("{0}, D{1}", DisassembleValue(srcMode, srcReg, 2, ref pc), dstReg); + break; + case 2: // Long + info.Mnemonic = "or.l"; + info.Args = string.Format("{0}, D{1}", DisassembleValue(srcMode, srcReg, 4, ref pc), dstReg); + break; + } + + info.Length = pc - info.PC; + } + + void OR1() // OR Dn, + { + int srcReg = (op >> 9) & 0x07; + int size = (op >> 6) & 0x03; + int dstMode = (op >> 3) & 0x07; + int dstReg = op & 0x07; + + V = false; + C = false; + + switch (size) + { + case 0: // Byte + { + sbyte dest = PeekValueB(dstMode, dstReg); + sbyte value = (sbyte)(dest | D[srcReg].s8); + WriteValueB(dstMode, dstReg, value); + PendingCycles -= (dstMode == 0) ? 4 : 8 + EACyclesBW[dstMode, dstReg]; + N = (value & 0x80) != 0; + Z = (value == 0); + return; + } + case 1: // Word + { + short dest = PeekValueW(dstMode, dstReg); + short value = (short)(dest | D[srcReg].s16); + WriteValueW(dstMode, dstReg, value); + PendingCycles -= (dstMode == 0) ? 4 : 8 + EACyclesBW[dstMode, dstReg]; + N = (value & 0x8000) != 0; + Z = (value == 0); + return; + } + case 2: // Long + { + int dest = PeekValueL(dstMode, dstReg); + int value = dest | D[srcReg].s32; + WriteValueL(dstMode, dstReg, value); + PendingCycles -= (dstMode == 0) ? 8 : 12 + EACyclesL[dstMode, dstReg]; + N = (value & 0x80000000) != 0; + Z = (value == 0); + return; + } + } + } + + void OR1_Disasm(DisassemblyInfo info) + { + int srcReg = (op >> 9) & 0x07; + int size = (op >> 6) & 0x03; + int dstMode = (op >> 3) & 0x07; + int dstReg = op & 0x07; + + int pc = info.PC + 2; + + switch (size) + { + case 0: // Byte + info.Mnemonic = "or.b"; + info.Args = string.Format("D{0}, {1}", srcReg, DisassembleValue(dstMode, dstReg, 1, ref pc)); + break; + case 1: // Word + info.Mnemonic = "or.w"; + info.Args = string.Format("D{0}, {1}", srcReg, DisassembleValue(dstMode, dstReg, 2, ref pc)); + break; + case 2: // Long + info.Mnemonic = "or.l"; + info.Args = string.Format("D{0}, {1}", srcReg, DisassembleValue(dstMode, dstReg, 4, ref pc)); + break; + } + + info.Length = pc - info.PC; + } + + void ORI() + { + int size = (op >> 6) & 3; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + V = false; + 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 & 0x80) != 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 & 0x8000) != 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 & 0x80000000) != 0; + Z = value == 0; + PendingCycles -= mode == 0 ? 16 : 20 + EACyclesL[mode, reg]; + return; + } + } + } + + void ORI_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + 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 NOT() + { + int size = (op >> 6) & 0x03; + int mode = (op >> 3) & 0x07; + int reg = op & 0x07; + + V = false; + C = false; + + switch (size) + { + case 0: // Byte + { + sbyte value = PeekValueB(mode, reg); + value = (sbyte)~value; + WriteValueB(mode, reg, value); + PendingCycles -= (mode == 0) ? 4 : 8 + EACyclesBW[mode, reg]; + N = (value & 0x80) != 0; + Z = (value == 0); + return; + } + case 1: // Word + { + short value = PeekValueW(mode, reg); + value = (short)~value; + WriteValueW(mode, reg, value); + PendingCycles -= (mode == 0) ? 4 : 8 + EACyclesBW[mode, reg]; + N = (value & 0x8000) != 0; + Z = (value == 0); + return; + } + case 2: // Long + { + int value = PeekValueL(mode, reg); + value = ~value; + WriteValueL(mode, reg, value); + PendingCycles -= (mode == 0) ? 8 : 12 + EACyclesL[mode, reg]; + N = (value & 0x80000000) != 0; + Z = (value == 0); + return; + } + } + } + + void NOT_Disasm(DisassemblyInfo info) + { + int size = (op >> 6) & 0x03; + int mode = (op >> 3) & 0x07; + int reg = op & 0x07; + + int pc = info.PC + 2; + + switch (size) + { + case 0: // Byte + info.Mnemonic = "not.b"; + info.Args = DisassembleValue(mode, reg, 1, ref pc); + break; + case 1: // Word + info.Mnemonic = "not.w"; + info.Args = DisassembleValue(mode, reg, 2, ref pc); + break; + case 2: // Long + info.Mnemonic = "not.l"; + info.Args = DisassembleValue(mode, reg, 4, ref pc); + break; + } + + info.Length = pc - info.PC; + } + + void LSLd() + { + int rot = (op >> 9) & 7; + int size = (op >> 6) & 3; + int m = (op >> 5) & 1; + int reg = op & 7; + + if (m == 0 && rot == 0) rot = 8; + else if (m == 1) rot = D[rot].s32 & 63; + + V = false; + C = false; + + switch (size) + { + case 0: // byte + for (int i = 0; i < rot; i++) + { + C = X = (D[reg].u8 & 0x80) != 0; + D[reg].u8 <<= 1; + } + N = (D[reg].s8 & 0x80) != 0; + Z = D[reg].u8 == 0; + PendingCycles -= 6 + (rot * 2); + return; + case 1: // word + for (int i = 0; i < rot; i++) + { + C = X = (D[reg].u16 & 0x8000) != 0; + D[reg].u16 <<= 1; + } + N = (D[reg].s16 & 0x8000) != 0; + Z = D[reg].u16 == 0; + PendingCycles -= 6 + (rot * 2); + return; + case 2: // long + for (int i = 0; i < rot; i++) + { + C = X = (D[reg].u32 & 0x80000000) != 0; + D[reg].u32 <<= 1; + } + N = (D[reg].s32 & 0x80000000) != 0; + Z = D[reg].u32 == 0; + PendingCycles -= 8 + (rot * 2); + return; + } + } + + void LSLd_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int rot = (op >> 9) & 7; + int size = (op >> 6) & 3; + int m = (op >> 5) & 1; + int reg = op & 7; + + if (m == 0 && rot == 0) rot = 8; + + switch (size) + { + case 0: info.Mnemonic = "lsl.b"; break; + case 1: info.Mnemonic = "lsl.w"; break; + case 2: info.Mnemonic = "lsl.l"; break; + } + if (m == 0) info.Args = rot + ", D" + reg; + else info.Args = "D" + rot + ", D" + reg; + + info.Length = pc - info.PC; + } + + void LSRd() + { + int rot = (op >> 9) & 7; + int size = (op >> 6) & 3; + int m = (op >> 5) & 1; + int reg = op & 7; + + if (m == 0 && rot == 0) rot = 8; + else if (m == 1) rot = D[rot].s32 & 63; + + V = false; + C = false; + + switch (size) + { + case 0: // byte + for (int i = 0; i < rot; i++) + { + C = X = (D[reg].u8 & 1) != 0; + D[reg].u8 >>= 1; + } + N = (D[reg].s8 & 0x80) != 0; + Z = D[reg].u8 == 0; + PendingCycles -= 6 + (rot * 2); + return; + case 1: // word + for (int i = 0; i < rot; i++) + { + C = X = (D[reg].u16 & 1) != 0; + D[reg].u16 >>= 1; + } + N = (D[reg].s16 & 0x8000) != 0; + Z = D[reg].u16 == 0; + PendingCycles -= 6 + (rot * 2); + return; + case 2: // long + for (int i = 0; i < rot; i++) + { + C = X = (D[reg].u32 & 1) != 0; + D[reg].u32 >>= 1; + } + N = (D[reg].s32 & 0x80000000) != 0; + Z = D[reg].u32 == 0; + PendingCycles -= 8 + (rot * 2); + return; + } + } + + void LSRd_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int rot = (op >> 9) & 7; + int size = (op >> 6) & 3; + int m = (op >> 5) & 1; + int reg = op & 7; + + if (m == 0 && rot == 0) rot = 8; + + switch (size) + { + case 0: info.Mnemonic = "lsr.b"; break; + case 1: info.Mnemonic = "lsr.w"; break; + case 2: info.Mnemonic = "lsr.l"; break; + } + if (m == 0) info.Args = rot + ", D" + reg; + else info.Args = "D" + rot + ", D" + reg; + + info.Length = pc - info.PC; + } + + void ASLd() + { + int rot = (op >> 9) & 7; + int size = (op >> 6) & 3; + int m = (op >> 5) & 1; + int reg = op & 7; + + if (m == 0 && rot == 0) rot = 8; + else if (m == 1) rot = D[rot].s32 & 63; + + V = false; + C = false; + + switch (size) + { + case 0: // byte + for (int i = 0; i < rot; i++) + { + bool msb = D[reg].s8 < 0; + C = X = (D[reg].u8 & 0x80) != 0; + D[reg].s8 <<= 1; + V |= (D[reg].s8 < 0) != msb; + } + N = (D[reg].s8 & 0x80) != 0; + Z = D[reg].u8 == 0; + PendingCycles -= 6 + (rot * 2); + return; + case 1: // word + for (int i = 0; i < rot; i++) + { + bool msb = D[reg].s16 < 0; + C = X = (D[reg].u16 & 0x8000) != 0; + D[reg].s16 <<= 1; + V |= (D[reg].s16 < 0) != msb; + } + N = (D[reg].s16 & 0x8000) != 0; + Z = D[reg].u16 == 0; + PendingCycles -= 6 + (rot * 2); + return; + case 2: // long + for (int i = 0; i < rot; i++) + { + bool msb = D[reg].s32 < 0; + C = X = (D[reg].u32 & 0x80000000) != 0; + D[reg].s32 <<= 1; + V |= (D[reg].s32 < 0) != msb; + } + N = (D[reg].s32 & 0x80000000) != 0; + Z = D[reg].u32 == 0; + PendingCycles -= 8 + (rot * 2); + return; + } + } + + void ASLd_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int rot = (op >> 9) & 7; + int size = (op >> 6) & 3; + int m = (op >> 5) & 1; + int reg = op & 7; + + if (m == 0 && rot == 0) rot = 8; + + switch (size) + { + case 0: info.Mnemonic = "asl.b"; break; + case 1: info.Mnemonic = "asl.w"; break; + case 2: info.Mnemonic = "asl.l"; break; + } + if (m == 0) info.Args = rot + ", D" + reg; + else info.Args = "D" + rot + ", D" + reg; + + info.Length = pc - info.PC; + } + + void ASRd() + { + int rot = (op >> 9) & 7; + int size = (op >> 6) & 3; + int m = (op >> 5) & 1; + int reg = op & 7; + + if (m == 0 && rot == 0) rot = 8; + else if (m == 1) rot = D[rot].s32 & 63; + + V = false; + C = false; + + switch (size) + { + case 0: // byte + for (int i = 0; i < rot; i++) + { + bool msb = D[reg].s8 < 0; + C = X = (D[reg].u8 & 1) != 0; + D[reg].s8 >>= 1; + V |= (D[reg].s8 < 0) != msb; + } + N = (D[reg].s8 & 0x80) != 0; + Z = D[reg].u8 == 0; + PendingCycles -= 6 + (rot * 2); + return; + case 1: // word + for (int i = 0; i < rot; i++) + { + bool msb = D[reg].s16 < 0; + C = X = (D[reg].u16 & 1) != 0; + D[reg].s16 >>= 1; + V |= (D[reg].s16 < 0) != msb; + } + N = (D[reg].s16 & 0x8000) != 0; + Z = D[reg].u16 == 0; + PendingCycles -= 6 + (rot * 2); + return; + case 2: // long + for (int i = 0; i < rot; i++) + { + bool msb = D[reg].s32 < 0; + C = X = (D[reg].u32 & 1) != 0; + D[reg].s32 >>= 1; + V |= (D[reg].s32 < 0) != msb; + } + N = (D[reg].s32 & 0x80000000) != 0; + Z = D[reg].u32 == 0; + PendingCycles -= 8 + (rot * 2); + return; + } + } + + void ASRd_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int rot = (op >> 9) & 7; + int size = (op >> 6) & 3; + int m = (op >> 5) & 1; + int reg = op & 7; + + if (m == 0 && rot == 0) rot = 8; + + switch (size) + { + case 0: info.Mnemonic = "asr.b"; break; + case 1: info.Mnemonic = "asr.w"; break; + case 2: info.Mnemonic = "asr.l"; break; + } + if (m == 0) info.Args = rot + ", D" + reg; + else info.Args = "D" + rot + ", D" + reg; + + info.Length = pc - info.PC; + } + + void ROLd() + { + int rot = (op >> 9) & 7; + int size = (op >> 6) & 3; + int m = (op >> 5) & 1; + int reg = op & 7; + + if (m == 0 && rot == 0) rot = 8; + else if (m == 1) rot = D[rot].s32 & 63; + + V = false; + C = false; + + switch (size) + { + case 0: // byte + for (int i = 0; i < rot; i++) + { + C = (D[reg].u8 & 0x80) != 0; + D[reg].u8 = (byte)((D[reg].u8 << 1) | (D[reg].u8 >> 7)); + } + N = (D[reg].s8 & 0x80) != 0; + Z = D[reg].u8 == 0; + PendingCycles -= 6 + (rot * 2); + return; + case 1: // word + for (int i = 0; i < rot; i++) + { + C = (D[reg].u16 & 0x8000) != 0; + D[reg].u16 = (ushort)((D[reg].u16 << 1) | (D[reg].u16 >> 15)); + } + N = (D[reg].s16 & 0x8000) != 0; + Z = D[reg].u16 == 0; + PendingCycles -= 6 + (rot * 2); + return; + case 2: // long + for (int i = 0; i < rot; i++) + { + C = (D[reg].u32 & 0x80000000) != 0; + D[reg].u32 = ((D[reg].u32 << 1) | (D[reg].u32 >> 31)); + } + N = (D[reg].s32 & 0x80000000) != 0; + Z = D[reg].u32 == 0; + PendingCycles -= 8 + (rot * 2); + return; + } + } + + void ROLd_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int rot = (op >> 9) & 7; + int size = (op >> 6) & 3; + int m = (op >> 5) & 1; + int reg = op & 7; + + if (m == 0 && rot == 0) rot = 8; + + switch (size) + { + case 0: info.Mnemonic = "rol.b"; break; + case 1: info.Mnemonic = "rol.w"; break; + case 2: info.Mnemonic = "rol.l"; break; + } + if (m == 0) info.Args = rot + ", D" + reg; + else info.Args = "D" + rot + ", D" + reg; + + info.Length = pc - info.PC; + } + + void RORd() + { + int rot = (op >> 9) & 7; + int size = (op >> 6) & 3; + int m = (op >> 5) & 1; + int reg = op & 7; + + if (m == 0 && rot == 0) rot = 8; + else if (m == 1) rot = D[rot].s32 & 63; + + V = false; + C = false; + + switch (size) + { + case 0: // byte + for (int i = 0; i < rot; i++) + { + C = (D[reg].u8 & 1) != 0; + D[reg].u8 = (byte)((D[reg].u8 >> 1) | (D[reg].u8 << 7)); + } + N = (D[reg].s8 & 0x80) != 0; + Z = D[reg].u8 == 0; + PendingCycles -= 6 + (rot * 2); + return; + case 1: // word + for (int i = 0; i < rot; i++) + { + C = (D[reg].u16 & 1) != 0; + D[reg].u16 = (ushort)((D[reg].u16 >> 1) | (D[reg].u16 << 15)); + } + N = (D[reg].s16 & 0x8000) != 0; + Z = D[reg].u16 == 0; + PendingCycles -= 6 + (rot * 2); + return; + case 2: // long + for (int i = 0; i < rot; i++) + { + C = (D[reg].u32 & 1) != 0; + D[reg].u32 = ((D[reg].u32 >> 1) | (D[reg].u32 << 31)); + } + N = (D[reg].s32 & 0x80000000) != 0; + Z = D[reg].u32 == 0; + PendingCycles -= 8 + (rot * 2); + return; + } + } + + void RORd_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int rot = (op >> 9) & 7; + int size = (op >> 6) & 3; + int m = (op >> 5) & 1; + int reg = op & 7; + + if (m == 0 && rot == 0) rot = 8; + + switch (size) + { + case 0: info.Mnemonic = "ror.b"; break; + case 1: info.Mnemonic = "ror.w"; break; + case 2: info.Mnemonic = "ror.l"; break; + } + if (m == 0) info.Args = rot + ", D" + reg; + else info.Args = "D" + rot + ", D" + reg; + + info.Length = pc - info.PC; + } + + void ROXLd() + { + int rot = (op >> 9) & 7; + int size = (op >> 6) & 3; + int m = (op >> 5) & 1; + int reg = op & 7; + + if (m == 0 && rot == 0) rot = 8; + else if (m == 1) rot = D[rot].s32 & 63; + + C = X; + V = false; + + switch (size) + { + case 0: // byte + for (int i = 0; i < rot; i++) + { + C = (D[reg].u8 & 0x80) != 0; + D[reg].u8 = (byte)((D[reg].u8 << 1) | (X ? 1 : 0)); + X = C; + } + N = (D[reg].s8 & 0x80) != 0; + Z = D[reg].s8 == 0; + PendingCycles -= 6 + (rot * 2); + return; + case 1: // word + for (int i = 0; i < rot; i++) + { + C = (D[reg].u16 & 0x8000) != 0; + D[reg].u16 = (ushort)((D[reg].u16 << 1) | (X ? 1 : 0)); + X = C; + } + N = (D[reg].s16 & 0x8000) != 0; + Z = D[reg].s16 == 0; + PendingCycles -= 6 + (rot * 2); + return; + case 2: // long + for (int i = 0; i < rot; i++) + { + C = (D[reg].s32 & 0x80000000) != 0; + D[reg].s32 = ((D[reg].s32 << 1) | (X ? 1 : 0)); + X = C; + } + N = (D[reg].s32 & 0x80000000) != 0; + Z = D[reg].s32 == 0; + PendingCycles -= 8 + (rot * 2); + return; + } + } + + void ROXLd_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int rot = (op >> 9) & 7; + int size = (op >> 6) & 3; + int m = (op >> 5) & 1; + int reg = op & 7; + + if (m == 0 && rot == 0) rot = 8; + + switch (size) + { + case 0: info.Mnemonic = "roxl.b"; break; + case 1: info.Mnemonic = "roxl.w"; break; + case 2: info.Mnemonic = "roxl.l"; break; + } + if (m == 0) info.Args = rot + ", D" + reg; + else info.Args = "D" + rot + ", D" + reg; + + info.Length = pc - info.PC; + } + + void ROXRd() + { + int rot = (op >> 9) & 7; + int size = (op >> 6) & 3; + int m = (op >> 5) & 1; + int reg = op & 7; + + if (m == 0 && rot == 0) rot = 8; + else if (m == 1) rot = D[rot].s32 & 63; + + C = X; + V = false; + + switch (size) + { + case 0: // byte + for (int i = 0; i < rot; i++) + { + C = (D[reg].u8 & 1) != 0; + D[reg].u8 = (byte)((D[reg].u8 >> 1) | (X ? 0x80 : 0)); + X = C; + } + N = (D[reg].s8 & 0x80) != 0; + Z = D[reg].s8 == 0; + PendingCycles -= 6 + (rot * 2); + return; + case 1: // word + for (int i = 0; i < rot; i++) + { + C = (D[reg].u16 & 1) != 0; + D[reg].u16 = (ushort)((D[reg].u16 >> 1) | (X ? 0x8000 : 0)); + X = C; + } + N = (D[reg].s16 & 0x8000) != 0; + Z = D[reg].s16 == 0; + PendingCycles -= 6 + (rot * 2); + return; + case 2: // long + for (int i = 0; i < rot; i++) + { + C = (D[reg].s32 & 1) != 0; + D[reg].u32 = ((D[reg].u32 >> 1) | (X ? 0x80000000 : 0)); + X = C; + } + N = (D[reg].s32 & 0x80000000) != 0; + Z = D[reg].s32 == 0; + PendingCycles -= 8 + (rot * 2); + return; + } + } + + void ROXRd_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int rot = (op >> 9) & 7; + int size = (op >> 6) & 3; + int m = (op >> 5) & 1; + int reg = op & 7; + + if (m == 0 && rot == 0) rot = 8; + + switch (size) + { + case 0: info.Mnemonic = "roxr.b"; break; + case 1: info.Mnemonic = "roxr.w"; break; + case 2: info.Mnemonic = "roxr.l"; break; + } + if (m == 0) info.Args = rot + ", D" + reg; + else info.Args = "D" + rot + ", D" + reg; + + info.Length = pc - info.PC; + } + + void SWAP() + { + int reg = op & 7; + D[reg].u32 = (D[reg].u32 << 16) | (D[reg].u32 >> 16); + V = C = false; + Z = D[reg].u32 == 0; + N = (D[reg].s32 & 0x80000000) != 0; + PendingCycles -= 4; + } + + void SWAP_Disasm(DisassemblyInfo info) + { + int reg = op & 7; + info.Mnemonic = "swap"; + info.Args = "D" + reg; + } + } } diff --git a/BizHawk.Emulation/CPUs/68000/Instructions/DataMovement.cs b/BizHawk.Emulation/CPUs/68000/Instructions/DataMovement.cs index 6264070c7c..d55dba5f29 100644 --- a/BizHawk.Emulation/CPUs/68000/Instructions/DataMovement.cs +++ b/BizHawk.Emulation/CPUs/68000/Instructions/DataMovement.cs @@ -1,608 +1,618 @@ using System; using System.Text; -namespace BizHawk.Emulation.CPUs.M68000 +namespace BizHawk.Emulation.Common.Components.M68000 { - partial class MC68000 - { - void MOVE() - { - int size = ((op >> 12) & 0x03); - int dstMode = ((op >> 6) & 0x07); - int dstReg = ((op >> 9) & 0x07); - int srcMode = ((op >> 3) & 0x07); - int srcReg = (op & 0x07); + partial class MC68000 + { + void MOVE() + { + int size = ((op >> 12) & 0x03); + int dstMode = ((op >> 6) & 0x07); + int dstReg = ((op >> 9) & 0x07); + int srcMode = ((op >> 3) & 0x07); + int srcReg = (op & 0x07); - int value = 0; - switch (size) - { - case 1: // Byte - value = ReadValueB(srcMode, srcReg); - WriteValueB(dstMode, dstReg, (sbyte) value); - PendingCycles -= MoveCyclesBW[srcMode + (srcMode == 7 ? srcReg : 0), dstMode + (dstMode == 7 ? dstReg : 0)]; - N = (value & 0x80) != 0; - break; - case 3: // Word - value = ReadValueW(srcMode, srcReg); - WriteValueW(dstMode, dstReg, (short)value); - PendingCycles -= MoveCyclesBW[srcMode + (srcMode == 7 ? srcReg : 0), dstMode + (dstMode == 7 ? dstReg : 0)]; - N = (value & 0x8000) != 0; - break; - case 2: // Long - value = ReadValueL(srcMode, srcReg); - WriteValueL(dstMode, dstReg, value); - PendingCycles -= MoveCyclesL[srcMode + (srcMode == 7 ? srcReg : 0), dstMode + (dstMode == 7 ? dstReg : 0)]; - N = (value & 0x80000000) != 0; - break; - } + int value = 0; + switch (size) + { + case 1: // Byte + value = ReadValueB(srcMode, srcReg); + WriteValueB(dstMode, dstReg, (sbyte)value); + PendingCycles -= MoveCyclesBW[srcMode + (srcMode == 7 ? srcReg : 0), dstMode + (dstMode == 7 ? dstReg : 0)]; + N = (value & 0x80) != 0; + break; + case 3: // Word + value = ReadValueW(srcMode, srcReg); + WriteValueW(dstMode, dstReg, (short)value); + PendingCycles -= MoveCyclesBW[srcMode + (srcMode == 7 ? srcReg : 0), dstMode + (dstMode == 7 ? dstReg : 0)]; + N = (value & 0x8000) != 0; + break; + case 2: // Long + value = ReadValueL(srcMode, srcReg); + WriteValueL(dstMode, dstReg, value); + PendingCycles -= MoveCyclesL[srcMode + (srcMode == 7 ? srcReg : 0), dstMode + (dstMode == 7 ? dstReg : 0)]; + N = (value & 0x80000000) != 0; + break; + } - V = false; - C = false; - Z = (value == 0); - } + V = false; + C = false; + Z = (value == 0); + } - void MOVE_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int size = ((op >> 12) & 0x03); - int dstMode = ((op >> 6) & 0x07); - int dstReg = ((op >> 9) & 0x07); - int srcMode = ((op >> 3) & 0x07); - int srcReg = (op & 0x07); + void MOVE_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int size = ((op >> 12) & 0x03); + int dstMode = ((op >> 6) & 0x07); + int dstReg = ((op >> 9) & 0x07); + int srcMode = ((op >> 3) & 0x07); + int srcReg = (op & 0x07); - switch (size) - { - case 1: - info.Mnemonic = "move.b"; - info.Args = DisassembleValue(srcMode, srcReg, 1, ref pc) +", "; - info.Args += DisassembleValue(dstMode, dstReg, 1, ref pc); - break; - case 3: - info.Mnemonic = "move.w"; - info.Args = DisassembleValue(srcMode, srcReg, 2, ref pc) + ", "; - info.Args += DisassembleValue(dstMode, dstReg, 2, ref pc); - break; - case 2: - info.Mnemonic = "move.l"; - info.Args = DisassembleValue(srcMode, srcReg, 4, ref pc) + ", "; - info.Args += DisassembleValue(dstMode, dstReg, 4, ref pc); - break; - } + switch (size) + { + case 1: + info.Mnemonic = "move.b"; + info.Args = DisassembleValue(srcMode, srcReg, 1, ref pc) + ", "; + info.Args += DisassembleValue(dstMode, dstReg, 1, ref pc); + break; + case 3: + info.Mnemonic = "move.w"; + info.Args = DisassembleValue(srcMode, srcReg, 2, ref pc) + ", "; + info.Args += DisassembleValue(dstMode, dstReg, 2, ref pc); + break; + case 2: + info.Mnemonic = "move.l"; + info.Args = DisassembleValue(srcMode, srcReg, 4, ref pc) + ", "; + info.Args += DisassembleValue(dstMode, dstReg, 4, ref pc); + break; + } - info.Length = pc - info.PC; - } + info.Length = pc - info.PC; + } - void MOVEA() - { - int size = ((op >> 12) & 0x03); - int dstReg = ((op >> 9) & 0x07); - int srcMode = ((op >> 3) & 0x07); - int srcReg = (op & 0x07); + void MOVEA() + { + int size = ((op >> 12) & 0x03); + int dstReg = ((op >> 9) & 0x07); + int srcMode = ((op >> 3) & 0x07); + int srcReg = (op & 0x07); - if (size == 3) // Word - { - A[dstReg].s32 = ReadValueW(srcMode, srcReg); - 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 5: PendingCycles -= 12; break; - case 6: PendingCycles -= 14; break; - case 7: - switch (srcReg) - { - case 0: PendingCycles -= 12; break; - case 1: PendingCycles -= 16; break; - case 2: PendingCycles -= 12; break; - case 3: PendingCycles -= 14; break; - case 4: PendingCycles -= 8; break; - default: throw new InvalidOperationException(); - } - break; - } - } else { // Long - A[dstReg].s32 = ReadValueL(srcMode, srcReg); - 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 5: PendingCycles -= 16; break; - case 6: PendingCycles -= 18; break; - case 7: - switch (srcReg) - { - case 0: PendingCycles -= 16; break; - case 1: PendingCycles -= 20; break; - case 2: PendingCycles -= 16; break; - case 3: PendingCycles -= 18; break; - case 4: PendingCycles -= 12; break; - default: throw new InvalidOperationException(); - } - break; - } - } - } + if (size == 3) // Word + { + A[dstReg].s32 = ReadValueW(srcMode, srcReg); + 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 5: PendingCycles -= 12; break; + case 6: PendingCycles -= 14; break; + case 7: + switch (srcReg) + { + case 0: PendingCycles -= 12; break; + case 1: PendingCycles -= 16; break; + case 2: PendingCycles -= 12; break; + case 3: PendingCycles -= 14; break; + case 4: PendingCycles -= 8; break; + default: throw new InvalidOperationException(); + } + break; + } + } + else + { // Long + A[dstReg].s32 = ReadValueL(srcMode, srcReg); + 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 5: PendingCycles -= 16; break; + case 6: PendingCycles -= 18; break; + case 7: + switch (srcReg) + { + case 0: PendingCycles -= 16; break; + case 1: PendingCycles -= 20; break; + case 2: PendingCycles -= 16; break; + case 3: PendingCycles -= 18; break; + case 4: PendingCycles -= 12; break; + default: throw new InvalidOperationException(); + } + break; + } + } + } - void MOVEA_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int size = ((op >> 12) & 0x03); - int dstReg = ((op >> 9) & 0x07); - int srcMode = ((op >> 3) & 0x07); - int srcReg = (op & 0x07); + void MOVEA_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int size = ((op >> 12) & 0x03); + int dstReg = ((op >> 9) & 0x07); + int srcMode = ((op >> 3) & 0x07); + int srcReg = (op & 0x07); - if (size == 3) - { - info.Mnemonic = "movea.w"; - info.Args = DisassembleValue(srcMode, srcReg, 2, ref pc) + ", A" + dstReg; - } else { - info.Mnemonic = "movea.l"; - info.Args = DisassembleValue(srcMode, srcReg, 4, ref pc) + ", A" + dstReg; - } - info.Length = pc - info.PC; - } + if (size == 3) + { + info.Mnemonic = "movea.w"; + info.Args = DisassembleValue(srcMode, srcReg, 2, ref pc) + ", A" + dstReg; + } + else + { + info.Mnemonic = "movea.l"; + info.Args = DisassembleValue(srcMode, srcReg, 4, ref pc) + ", A" + dstReg; + } + info.Length = pc - info.PC; + } - void MOVEQ() - { - int value = (sbyte) op; // 8-bit data payload is sign-extended to 32-bits. - N = (value & 0x80) != 0; - Z = (value == 0); - V = false; - C = false; - D[(op >> 9) & 7].s32 = value; - PendingCycles -= 4; - } + void MOVEQ() + { + int value = (sbyte)op; // 8-bit data payload is sign-extended to 32-bits. + N = (value & 0x80) != 0; + Z = (value == 0); + V = false; + C = false; + D[(op >> 9) & 7].s32 = value; + PendingCycles -= 4; + } - void MOVEQ_Disasm(DisassemblyInfo info) - { - info.Mnemonic = "moveq"; - info.Args = String.Format("{0}, D{1}", (sbyte) op, (op >> 9) & 7); - } + void MOVEQ_Disasm(DisassemblyInfo info) + { + info.Mnemonic = "moveq"; + info.Args = String.Format("{0}, D{1}", (sbyte)op, (op >> 9) & 7); + } - void MOVEM0() - { - // Move register to memory - int size = (op >> 6) & 1; - int dstMode = (op >> 3) & 7; - int dstReg = (op >> 0) & 7; + void MOVEM0() + { + // Move register to memory + int size = (op >> 6) & 1; + int dstMode = (op >> 3) & 7; + int dstReg = (op >> 0) & 7; - ushort registers = (ushort) ReadWord(PC); PC += 2; - int address = ReadAddress(dstMode, dstReg); - int regCount = 0; + ushort registers = (ushort)ReadWord(PC); PC += 2; + int address = ReadAddress(dstMode, dstReg); + int regCount = 0; - if (size == 0) - { - // word-assign - if (dstMode == 4) // decrement address - { - for (int i = 7; i >= 0; i--) - { - if ((registers & 1) == 1) - { - address -= 2; - WriteWord(address, A[i].s16); - regCount++; - } - registers >>= 1; - } - for (int i = 7; i >= 0; i--) - { - if ((registers & 1) == 1) - { - address -= 2; - WriteWord(address, D[i].s16); - regCount++; - } - registers >>= 1; - } - A[dstReg].s32 = address; - } - else - { // increment address - for (int i = 7; i >= 0; i--) - { - if ((registers & 1) == 1) - { - WriteWord(address, A[i].s16); - address += 2; - regCount++; - } - registers >>= 1; - } - for (int i = 7; i >= 0; i--) - { - if ((registers & 1) == 1) - { - WriteWord(address, D[i].s16); - address += 2; - regCount++; - } - registers >>= 1; - } - } - PendingCycles -= regCount*4; - } else { - // long-assign - if (dstMode == 4) // decrement address - { - for (int i=7; i>= 0; i--) - { - if ((registers & 1) == 1) - { - address -= 4; - WriteLong(address, A[i].s32); - regCount++; - } - registers >>= 1; - } - for (int i = 7; i >= 0; i--) - { - if ((registers & 1) == 1) - { - address -= 4; - WriteLong(address, D[i].s32); - regCount++; - } - registers >>= 1; - } - A[dstReg].s32 = address; - } else { // increment address - for (int i = 7; i >= 0; i--) - { - if ((registers & 1) == 1) - { - WriteLong(address, A[i].s32); - address += 4; - regCount++; - } - registers >>= 1; - } - for (int i = 7; i >= 0; i--) - { - if ((registers & 1) == 1) - { - WriteLong(address, D[i].s32); - address += 4; - regCount++; - } - registers >>= 1; - } - } - PendingCycles -= regCount * 8; - } + if (size == 0) + { + // word-assign + if (dstMode == 4) // decrement address + { + for (int i = 7; i >= 0; i--) + { + if ((registers & 1) == 1) + { + address -= 2; + WriteWord(address, A[i].s16); + regCount++; + } + registers >>= 1; + } + for (int i = 7; i >= 0; i--) + { + if ((registers & 1) == 1) + { + address -= 2; + WriteWord(address, D[i].s16); + regCount++; + } + registers >>= 1; + } + A[dstReg].s32 = address; + } + else + { // increment address + for (int i = 7; i >= 0; i--) + { + if ((registers & 1) == 1) + { + WriteWord(address, A[i].s16); + address += 2; + regCount++; + } + registers >>= 1; + } + for (int i = 7; i >= 0; i--) + { + if ((registers & 1) == 1) + { + WriteWord(address, D[i].s16); + address += 2; + regCount++; + } + registers >>= 1; + } + } + PendingCycles -= regCount * 4; + } + else + { + // long-assign + if (dstMode == 4) // decrement address + { + for (int i = 7; i >= 0; i--) + { + if ((registers & 1) == 1) + { + address -= 4; + WriteLong(address, A[i].s32); + regCount++; + } + registers >>= 1; + } + for (int i = 7; i >= 0; i--) + { + if ((registers & 1) == 1) + { + address -= 4; + WriteLong(address, D[i].s32); + regCount++; + } + registers >>= 1; + } + A[dstReg].s32 = address; + } + else + { // increment address + for (int i = 7; i >= 0; i--) + { + if ((registers & 1) == 1) + { + WriteLong(address, A[i].s32); + address += 4; + regCount++; + } + registers >>= 1; + } + for (int i = 7; i >= 0; i--) + { + if ((registers & 1) == 1) + { + WriteLong(address, D[i].s32); + address += 4; + regCount++; + } + registers >>= 1; + } + } + PendingCycles -= regCount * 8; + } - 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; - case 7: - switch (dstReg) - { - case 0: PendingCycles -= 12; break; - case 1: PendingCycles -= 16; break; - } - break; - } - } + 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; + case 7: + switch (dstReg) + { + case 0: PendingCycles -= 12; break; + case 1: PendingCycles -= 16; break; + } + break; + } + } - void MOVEM1() - { - // Move memory to register - int size = (op >> 6) & 1; - int srcMode = (op >> 3) & 7; - int srcReg = (op >> 0) & 7; + void MOVEM1() + { + // Move memory to register + int size = (op >> 6) & 1; + int srcMode = (op >> 3) & 7; + int srcReg = (op >> 0) & 7; - ushort registers = (ushort)ReadWord(PC); PC += 2; - int address = ReadAddress(srcMode, srcReg); - int regCount = 0; + ushort registers = (ushort)ReadWord(PC); PC += 2; + int address = ReadAddress(srcMode, srcReg); + int regCount = 0; - if (size == 0) - { - // word-assign - for (int i = 0; i < 8; i++) - { - if ((registers & 1) == 1) - { - D[i].s32 = ReadWord(address); - address += 2; - regCount++; - } - registers >>= 1; - } - for (int i = 0; i < 8; i++) - { - if ((registers & 1) == 1) - { - A[i].s32 = ReadWord(address); - address += 2; - regCount++; - } - registers >>= 1; - } - PendingCycles -= regCount * 4; - if (srcMode == 3) - A[srcReg].s32 = address; - } else { - // long-assign - for (int i = 0; i < 8; i++) - { - if ((registers & 1) == 1) - { - D[i].s32 = ReadLong(address); - address += 4; - regCount++; - } - registers >>= 1; - } - for (int i = 0; i < 8; i++) - { - if ((registers & 1) == 1) - { - A[i].s32 = ReadLong(address); - address += 4; - regCount++; - } - registers >>= 1; - } - PendingCycles -= regCount * 8; - if (srcMode == 3) - A[srcReg].s32 = address; - } + if (size == 0) + { + // word-assign + for (int i = 0; i < 8; i++) + { + if ((registers & 1) == 1) + { + D[i].s32 = ReadWord(address); + address += 2; + regCount++; + } + registers >>= 1; + } + for (int i = 0; i < 8; i++) + { + if ((registers & 1) == 1) + { + A[i].s32 = ReadWord(address); + address += 2; + regCount++; + } + registers >>= 1; + } + PendingCycles -= regCount * 4; + if (srcMode == 3) + A[srcReg].s32 = address; + } + else + { + // long-assign + for (int i = 0; i < 8; i++) + { + if ((registers & 1) == 1) + { + D[i].s32 = ReadLong(address); + address += 4; + regCount++; + } + registers >>= 1; + } + for (int i = 0; i < 8; i++) + { + if ((registers & 1) == 1) + { + A[i].s32 = ReadLong(address); + address += 4; + regCount++; + } + registers >>= 1; + } + PendingCycles -= regCount * 8; + if (srcMode == 3) + A[srcReg].s32 = address; + } - 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; - case 7: - switch (srcReg) - { - case 0: PendingCycles -= 16; break; - case 1: PendingCycles -= 20; break; - case 2: PendingCycles -= 16; break; - case 3: PendingCycles -= 18; break; - } - break; - } - } + 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; + case 7: + switch (srcReg) + { + case 0: PendingCycles -= 16; break; + case 1: PendingCycles -= 20; break; + case 2: PendingCycles -= 16; break; + case 3: PendingCycles -= 18; break; + } + break; + } + } - static string DisassembleRegisterList0(ushort registers) - { - var str = new StringBuilder(); - int count = 0; - for (int i = 0; i<8; i++) - { - if ((registers & 0x8000) != 0) - { - if (count > 0) str.Append(","); - str.Append("D"+i); - count++; - } - registers <<= 1; - } - for (int i = 0; i < 8; i++) - { - if ((registers & 0x8000) != 0) - { - if (count > 0) str.Append(","); - str.Append("A"+i); - count++; - } - registers <<= 1; - } - return str.ToString(); - } + static string DisassembleRegisterList0(ushort registers) + { + var str = new StringBuilder(); + int count = 0; + for (int i = 0; i < 8; i++) + { + if ((registers & 0x8000) != 0) + { + if (count > 0) str.Append(","); + str.Append("D" + i); + count++; + } + registers <<= 1; + } + for (int i = 0; i < 8; i++) + { + if ((registers & 0x8000) != 0) + { + if (count > 0) str.Append(","); + str.Append("A" + i); + count++; + } + registers <<= 1; + } + return str.ToString(); + } - static string DisassembleRegisterList1(ushort registers) - { - var str = new StringBuilder(); - int count = 0; - for (int i = 0; i < 8; i++) - { - if ((registers & 1) != 0) - { - if (count > 0) str.Append(","); - str.Append("D" + i); - count++; - } - registers >>= 1; - } - for (int i = 0; i < 8; i++) - { - if ((registers & 1) != 0) - { - if (count > 0) str.Append(","); - str.Append("A" + i); - count++; - } - registers >>= 1; - } - return str.ToString(); - } + static string DisassembleRegisterList1(ushort registers) + { + var str = new StringBuilder(); + int count = 0; + for (int i = 0; i < 8; i++) + { + if ((registers & 1) != 0) + { + if (count > 0) str.Append(","); + str.Append("D" + i); + count++; + } + registers >>= 1; + } + for (int i = 0; i < 8; i++) + { + if ((registers & 1) != 0) + { + if (count > 0) str.Append(","); + str.Append("A" + i); + count++; + } + registers >>= 1; + } + return str.ToString(); + } - void MOVEM0_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int size = (op >> 6) & 1; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - - ushort registers = (ushort)ReadWord(pc); pc += 2; - string address = DisassembleAddress(mode, reg, ref pc); + void MOVEM0_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int size = (op >> 6) & 1; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; - info.Mnemonic = size == 0 ? "movem.w" : "movem.l"; - info.Args = DisassembleRegisterList0(registers) + ", " + address; - info.Length = pc - info.PC; - } + ushort registers = (ushort)ReadWord(pc); pc += 2; + string address = DisassembleAddress(mode, reg, ref pc); - void MOVEM1_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int size = (op >> 6) & 1; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; + info.Mnemonic = size == 0 ? "movem.w" : "movem.l"; + info.Args = DisassembleRegisterList0(registers) + ", " + address; + info.Length = pc - info.PC; + } - ushort registers = (ushort)ReadWord(pc); pc += 2; - string address = DisassembleAddress(mode, reg, ref pc); - - info.Mnemonic = size == 0 ? "movem.w" : "movem.l"; - info.Args = address + ", " + DisassembleRegisterList1(registers); - info.Length = pc - info.PC; - } + void MOVEM1_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int size = (op >> 6) & 1; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; - void LEA() - { - int mode = (op >> 3) & 7; - int sReg = (op >> 0) & 7; - int dReg = (op >> 9) & 7; + ushort registers = (ushort)ReadWord(pc); pc += 2; + string address = DisassembleAddress(mode, reg, ref pc); - A[dReg].u32 = (uint)ReadAddress(mode, sReg); - switch (mode) - { - case 2: PendingCycles -= 4; break; - case 5: PendingCycles -= 8; break; - case 6: PendingCycles -= 12; break; - case 7: - switch (sReg) - { - case 0: PendingCycles -= 8; break; - case 1: PendingCycles -= 12; break; - case 2: PendingCycles -= 8; break; - case 3: PendingCycles -= 12; break; - } - break; - } - } + info.Mnemonic = size == 0 ? "movem.w" : "movem.l"; + info.Args = address + ", " + DisassembleRegisterList1(registers); + info.Length = pc - info.PC; + } - void LEA_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int mode = (op >> 3) & 7; - int sReg = (op >> 0) & 7; - int dReg = (op >> 9) & 7; - - info.Mnemonic = "lea"; - info.Args = DisassembleAddress(mode, sReg, ref pc); - info.Args += ", A"+dReg; + void LEA() + { + int mode = (op >> 3) & 7; + int sReg = (op >> 0) & 7; + int dReg = (op >> 9) & 7; - info.Length = pc - info.PC; - } + A[dReg].u32 = (uint)ReadAddress(mode, sReg); + switch (mode) + { + case 2: PendingCycles -= 4; break; + case 5: PendingCycles -= 8; break; + case 6: PendingCycles -= 12; break; + case 7: + switch (sReg) + { + case 0: PendingCycles -= 8; break; + case 1: PendingCycles -= 12; break; + case 2: PendingCycles -= 8; break; + case 3: PendingCycles -= 12; break; + } + break; + } + } - void CLR() - { - int size = (op >> 6) & 3; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; + void LEA_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int mode = (op >> 3) & 7; + int sReg = (op >> 0) & 7; + int dReg = (op >> 9) & 7; - switch (size) - { - case 0: WriteValueB(mode, reg, 0); PendingCycles -= mode == 0 ? 4 : 8 + EACyclesBW[mode, reg]; break; - case 1: WriteValueW(mode, reg, 0); PendingCycles -= mode == 0 ? 4 : 8 + EACyclesBW[mode, reg]; break; - case 2: WriteValueL(mode, reg, 0); PendingCycles -= mode == 0 ? 6 : 12 + EACyclesL[mode, reg]; break; - } + info.Mnemonic = "lea"; + info.Args = DisassembleAddress(mode, sReg, ref pc); + info.Args += ", A" + dReg; - N = V = C = false; - Z = true; - } + info.Length = pc - info.PC; + } - void CLR_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int size = (op >> 6) & 3; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - - switch (size) - { - case 0: info.Mnemonic = "clr.b"; info.Args = DisassembleValue(mode, reg, 1, ref pc); break; - case 1: info.Mnemonic = "clr.w"; info.Args = DisassembleValue(mode, reg, 2, ref pc); break; - case 2: info.Mnemonic = "clr.l"; info.Args = DisassembleValue(mode, reg, 4, ref pc); break; - } - info.Length = pc - info.PC; - } + void CLR() + { + int size = (op >> 6) & 3; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; - void EXT() - { - int size = (op >> 6) & 1; - int reg = op & 7; + switch (size) + { + case 0: WriteValueB(mode, reg, 0); PendingCycles -= mode == 0 ? 4 : 8 + EACyclesBW[mode, reg]; break; + case 1: WriteValueW(mode, reg, 0); PendingCycles -= mode == 0 ? 4 : 8 + EACyclesBW[mode, reg]; break; + case 2: WriteValueL(mode, reg, 0); PendingCycles -= mode == 0 ? 6 : 12 + EACyclesL[mode, reg]; break; + } - switch (size) - { - case 0: // ext.w - D[reg].s16 = D[reg].s8; - N = (D[reg].s16 & 0x8000) != 0; - Z = (D[reg].s16 == 0); - break; - case 1: // ext.l - D[reg].s32 = D[reg].s16; - N = (D[reg].s32 & 0x80000000) != 0; - Z = (D[reg].s32 == 0); - break; - } + N = V = C = false; + Z = true; + } - V = false; - C = false; - PendingCycles -= 4; - } + void CLR_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int size = (op >> 6) & 3; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; - void EXT_Disasm(DisassemblyInfo info) - { - int size = (op >> 6) & 1; - int reg = op & 7; + switch (size) + { + case 0: info.Mnemonic = "clr.b"; info.Args = DisassembleValue(mode, reg, 1, ref pc); break; + case 1: info.Mnemonic = "clr.w"; info.Args = DisassembleValue(mode, reg, 2, ref pc); break; + case 2: info.Mnemonic = "clr.l"; info.Args = DisassembleValue(mode, reg, 4, ref pc); break; + } + info.Length = pc - info.PC; + } - switch (size) - { - case 0: info.Mnemonic = "ext.w"; info.Args = "D" + reg; break; - case 1: info.Mnemonic = "ext.l"; info.Args = "D" + reg; break; - } - } + void EXT() + { + int size = (op >> 6) & 1; + int reg = op & 7; - void PEA() - { - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - int ea = ReadAddress(mode, reg); + switch (size) + { + case 0: // ext.w + D[reg].s16 = D[reg].s8; + N = (D[reg].s16 & 0x8000) != 0; + Z = (D[reg].s16 == 0); + break; + case 1: // ext.l + D[reg].s32 = D[reg].s16; + N = (D[reg].s32 & 0x80000000) != 0; + Z = (D[reg].s32 == 0); + break; + } - A[7].s32 -= 4; - WriteLong(A[7].s32, ea); + V = false; + C = false; + PendingCycles -= 4; + } - 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 EXT_Disasm(DisassemblyInfo info) + { + int size = (op >> 6) & 1; + int reg = op & 7; - void PEA_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; + switch (size) + { + case 0: info.Mnemonic = "ext.w"; info.Args = "D" + reg; break; + case 1: info.Mnemonic = "ext.l"; info.Args = "D" + reg; break; + } + } - info.Mnemonic = "pea"; - info.Args = DisassembleAddress(mode, reg, ref pc); - info.Length = pc - info.PC; - } - } + 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 a09cc7f104..edf04691fa 100644 --- a/BizHawk.Emulation/CPUs/68000/Instructions/IntegerMath.cs +++ b/BizHawk.Emulation/CPUs/68000/Instructions/IntegerMath.cs @@ -1,1146 +1,1150 @@ using System; -namespace BizHawk.Emulation.CPUs.M68000 +namespace BizHawk.Emulation.Common.Components.M68000 { - partial class MC68000 - { - void ADD0() - { - int Dreg = (op >> 9) & 7; - int size = (op >> 6) & 3; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - - switch (size) - { - case 0: // byte - { - sbyte value = ReadValueB(mode, reg); - int result = D[Dreg].s8 + value; - int uresult = D[Dreg].u8 + (byte)value; - X = C = (uresult & 0x100) != 0; - V = result > sbyte.MaxValue || result < sbyte.MinValue; - N = (result & 0x80) != 0; - Z = result == 0; - D[Dreg].s8 = (sbyte) result; - PendingCycles -= 4 + EACyclesBW[mode, reg]; - return; - } - case 1: // word - { - short value = ReadValueW(mode, reg); - int result = D[Dreg].s16 + value; - int uresult = D[Dreg].u16 + (ushort)value; - X = C = (uresult & 0x10000) != 0; - V = result > short.MaxValue || result < short.MinValue; - N = (result & 0x8000) != 0; - Z = result == 0; - D[Dreg].s16 = (short)result; - PendingCycles -= 4 + EACyclesBW[mode, reg]; - return; - } - case 2: // long - { - int value = ReadValueL(mode, reg); - long result = D[Dreg].s32 + value; - long uresult = D[Dreg].u32 + (uint)value; - X = C = (uresult & 0x100000000) != 0; - V = result > int.MaxValue || result < int.MinValue; - N = (result & 0x80000000) != 0; - Z = result == 0; - D[Dreg].s32 = (int)result; - PendingCycles -= 6 + EACyclesL[mode, reg]; - return; - } - } - } - - void ADD1() - { - int Dreg = (op >> 9) & 7; - int size = (op >> 6) & 3; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - - switch (size) - { - case 0: // byte - { - sbyte value = PeekValueB(mode, reg); - int result = value + D[Dreg].s8; - int uresult = (byte)value + D[Dreg].u8; - X = C = (uresult & 0x100) != 0; - V = result > sbyte.MaxValue || result < sbyte.MinValue; - N = (result & 0x80) != 0; - Z = result == 0; - WriteValueB(mode, reg, (sbyte)result); - PendingCycles -= 8 + EACyclesBW[mode, reg]; - return; - } - case 1: // word - { - short value = PeekValueW(mode, reg); - int result = value + D[Dreg].s16; - int uresult = (ushort)value + D[Dreg].u16; - X = C = (uresult & 0x10000) != 0; - V = result > short.MaxValue || result < short.MinValue; - N = (result & 0x8000) != 0; - Z = result == 0; - WriteValueW(mode, reg, (short)result); - PendingCycles -= 8 + EACyclesBW[mode, reg]; - return; - } - case 2: // long - { - int value = PeekValueL(mode, reg); - long result = value + D[Dreg].s32; - long uresult = (uint)value + D[Dreg].u32; - X = C = (uresult & 0x100000000) != 0; - V = result > int.MaxValue || result < int.MinValue; - N = (result & 0x80000000) != 0; - Z = result == 0; - WriteValueL(mode, reg, (int)result); - PendingCycles -= 12 + EACyclesL[mode, reg]; - return; - } - } - } - - void ADD_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int Dreg = (op >> 9) & 7; - int dir = (op >> 8) & 1; - int size = (op >> 6) & 3; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - - string op1 = "D" + Dreg; - string op2; - - switch (size) - { - case 0: info.Mnemonic = "add.b"; op2 = DisassembleValue(mode, reg, 1, ref pc); break; - case 1: info.Mnemonic = "add.w"; op2 = DisassembleValue(mode, reg, 2, ref pc); break; - default: info.Mnemonic = "add.l"; op2 = DisassembleValue(mode, reg, 4, ref pc); break; - } - info.Args = dir == 0 ? (op2 + ", " + op1) : (op1 + ", " + op2); - info.Length = pc - info.PC; - } - - void ADDI() - { - int size = (op >> 6) & 3; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - - switch (size) - { - case 0: // byte - { - int immed = (sbyte) ReadWord(PC); PC += 2; - sbyte value = PeekValueB(mode, reg); - int result = value + immed; - int uresult = (byte)value + (byte)immed; - X = C = (uresult & 0x100) != 0; - V = result > sbyte.MaxValue || result < sbyte.MinValue; - N = (result & 0x80) != 0; - Z = result == 0; - WriteValueB(mode, reg, (sbyte)result); - if (mode == 0) PendingCycles -= 8; - else PendingCycles -= 12 + EACyclesBW[mode, reg]; - return; - } - case 1: // word - { - int immed = ReadWord(PC); PC += 2; - short value = PeekValueW(mode, reg); - int result = value + immed; - int uresult = (ushort)value + (ushort)immed; - X = C = (uresult & 0x10000) != 0; - V = result > short.MaxValue || result < short.MinValue; - N = (result & 0x8000) != 0; - Z = result == 0; - WriteValueW(mode, reg, (short)result); - if (mode == 0) PendingCycles -= 8; - else PendingCycles -= 12 + EACyclesBW[mode, reg]; - return; - } - case 2: // long - { - int immed = ReadLong(PC); PC += 4; - int value = PeekValueL(mode, reg); - long result = value + immed; - long uresult = (uint)value + (uint)immed; - X = C = (uresult & 0x100000000) != 0; - V = result > int.MaxValue || result < int.MinValue; - N = (result & 0x80000000) != 0; - Z = result == 0; - WriteValueL(mode, reg, (int)result); - if (mode == 0) PendingCycles -= 16; - else PendingCycles -= 20 + EACyclesBW[mode, reg]; - return; - } - } - } - - void ADDI_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int size = (op >> 6) & 3; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 3; - - switch (size) - { - case 0: - info.Mnemonic = "addi.b"; - info.Args = DisassembleImmediate(1, ref pc) + ", " + DisassembleValue(mode, reg, 1, ref pc); - break; - case 1: - info.Mnemonic = "addi.w"; - info.Args = DisassembleImmediate(2, ref pc) + ", " + DisassembleValue(mode, reg, 2, ref pc); - break; - case 2: - info.Mnemonic = "addi.l"; - info.Args = DisassembleImmediate(4, ref pc) + ", " + DisassembleValue(mode, reg, 4, ref pc); - break; - } - info.Length = pc - info.PC; - } - - void ADDQ() - { - int data = (op >> 9) & 7; - int size = (op >> 6) & 3; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - - data = data == 0 ? 8 : data; // range is 1-8; 0 represents 8 - - switch (size) - { - case 0: // byte - { - if (mode == 1) throw new Exception("ADDQ.B on address reg is invalid"); - sbyte value = PeekValueB(mode, reg); - int result = value + data; - int uresult = (byte)value + data; - N = (result & 0x80) != 0; - Z = result == 0; - V = result > sbyte.MaxValue || result < sbyte.MinValue; - C = X = (uresult & 0x100) != 0; - WriteValueB(mode, reg, (sbyte) result); - if (mode == 0) PendingCycles -= 4; - else PendingCycles -= 8 + EACyclesBW[mode, reg]; - return; - } - case 1: // word - { - if (mode == 1) - { - int value = PeekValueL(mode, reg); - WriteValueL(mode, reg, value+data); - } - else - { - short value = PeekValueW(mode, reg); - int result = value + data; - int uresult = (ushort)value + data; - N = (result & 0x8000) != 0; - Z = result == 0; - V = result > short.MaxValue || result < short.MinValue; - C = X = (uresult & 0x10000) != 0; - WriteValueW(mode, reg, (short)result); - } - if (mode <= 1) PendingCycles -= 4; - else PendingCycles -= 8 + EACyclesBW[mode, reg]; - return; - } - default: // long - { - int value = PeekValueL(mode, reg); - long result = value + data; - long uresult = (uint)value + data; - if (mode != 1) - { - N = (result & 0x80000000) != 0; - Z = result == 0; - V = result > int.MaxValue || result < int.MinValue; - C = X = (uresult & 0x100000000) != 0; - } - WriteValueL(mode, reg, (int)result); - if (mode <= 1) PendingCycles -= 8; - else PendingCycles -= 12 + EACyclesL[mode, reg]; - return; - } - } - } - - void ADDQ_Disasm(DisassemblyInfo info) - { - 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; - - data = data == 0 ? 8 : data; // range is 1-8; 0 represents 8 - - switch (size) - { - case 0: info.Mnemonic = "addq.b"; info.Args = data+", "+DisassembleValue(mode, reg, 1, ref pc); break; - case 1: info.Mnemonic = "addq.w"; info.Args = data+", "+DisassembleValue(mode, reg, 2, ref pc); break; - case 2: info.Mnemonic = "addq.l"; info.Args = data+", "+DisassembleValue(mode, reg, 4, ref pc); break; - } - info.Length = pc - info.PC; - } - - void ADDA() - { - int aReg = (op >> 9) & 7; - int size = (op >> 8) & 1; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - - if (size == 0) // word - { - int value = ReadValueW(mode, reg); - A[aReg].s32 += value; - PendingCycles -= 8 + EACyclesBW[mode, reg]; - } else { // long - int value = ReadValueL(mode, reg); - A[aReg].s32 += value; - if (mode == 0 || mode == 1 || (mode == 7 && reg == 4)) - PendingCycles -= 8 + EACyclesL[mode, reg]; - else - PendingCycles -= 6 + EACyclesL[mode, reg]; - } - } - - void ADDA_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int aReg = (op >> 9) & 7; - int size = (op >> 8) & 1; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - - info.Mnemonic = (size == 0) ? "adda.w" : "adda.l"; - info.Args = DisassembleValue(mode, reg, (size == 0) ? 2 : 4, ref pc) + ", A" + aReg; - - info.Length = pc - info.PC; - } - - void SUB0() - { - int dReg = (op >> 9) & 7; - int size = (op >> 6) & 3; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - - switch (size) - { - case 0: // byte - { - sbyte a = D[dReg].s8; - sbyte b = ReadValueB(mode, reg); - int result = a - b; - X = C = ((a < b) ^ ((a ^ b) >= 0) == false); - V = result > sbyte.MaxValue || result < sbyte.MinValue; - N = (result & 0x80) != 0; - Z = result == 0; - D[dReg].s8 = (sbyte) result; - PendingCycles -= 4 + EACyclesBW[mode, reg]; - return; - } - case 1: // word - { - short a = D[dReg].s16; - short b = ReadValueW(mode, reg); - int result = a - b; - X = C = ((a < b) ^ ((a ^ b) >= 0) == false); - V = result > short.MaxValue || result < short.MinValue; - N = (result & 0x8000) != 0; - Z = result == 0; - D[dReg].s16 = (short) result; - PendingCycles -= 4 + EACyclesBW[mode, reg]; - return; - } - case 2: // long - { - int a = D[dReg].s32; - int b = ReadValueL(mode, reg); - long result = a - b; - X = C = ((a < b) ^ ((a ^ b) >= 0) == false); - V = result > int.MaxValue || result < int.MinValue; - N = (result & 0x80000000) != 0; - Z = result == 0; - D[dReg].s32 = (int)result; - PendingCycles -= 6 + EACyclesL[mode, reg]; - return; - } - } - } - - void SUB1() - { - int dReg = (op >> 9) & 7; - int size = (op >> 6) & 3; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - - switch (size) - { - case 0: // byte - { - sbyte a = PeekValueB(mode, reg); - sbyte b = D[dReg].s8; - int result = a - b; - X = C = ((a < b) ^ ((a ^ b) >= 0) == false); - V = result > sbyte.MaxValue || result < sbyte.MinValue; - N = (result & 0x80) != 0; - Z = result == 0; - WriteValueB(mode, reg, (sbyte) result); - PendingCycles -= 8 + EACyclesBW[mode, reg]; - return; - } - case 1: // word - { - short a = PeekValueW(mode, reg); - short b = D[dReg].s16; - int result = a - b; - X = C = ((a < b) ^ ((a ^ b) >= 0) == false); - V = result > short.MaxValue || result < short.MinValue; - N = (result & 0x8000) != 0; - Z = result == 0; - WriteValueW(mode, reg, (short) result); - PendingCycles -= 8 + EACyclesBW[mode, reg]; - return; - } - case 2: // long - { - int a = PeekValueL(mode, reg); - int b = D[dReg].s32; - long result = a - b; - X = C = ((a < b) ^ ((a ^ b) >= 0) == false); - V = result > int.MaxValue || result < int.MinValue; - N = (result & 0x80000000) != 0; - Z = result == 0; - WriteValueL(mode, reg, (int) result); - PendingCycles -= 12 + EACyclesL[mode, reg]; - return; - } - } - } - - void SUB_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int dReg = (op >> 9) & 7; - int dir = (op >> 8) & 1; - int size = (op >> 6) & 3; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - - string op1 = "D" + dReg; - string op2; - - switch (size) - { - case 0: info.Mnemonic = "sub.b"; op2 = DisassembleValue(mode, reg, 1, ref pc); break; - case 1: info.Mnemonic = "sub.w"; op2 = DisassembleValue(mode, reg, 2, ref pc); break; - default: info.Mnemonic = "sub.l"; op2 = DisassembleValue(mode, reg, 4, ref pc); break; - } - info.Args = dir == 0 ? (op2 + ", " + op1) : (op1 + ", " + op2); - info.Length = pc - info.PC; - } - - void SUBI() - { - int size = (op >> 6) & 3; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - - switch (size) - { - case 0: // byte - { - sbyte b = (sbyte) ReadWord(PC); PC += 2; - sbyte a = PeekValueB(mode, reg); - int result = a - b; - X = C = ((a < b) ^ ((a ^ b) >= 0) == false); - V = result > sbyte.MaxValue || result < sbyte.MinValue; - N = (result & 0x80) != 0; - Z = result == 0; - WriteValueB(mode, reg, (sbyte)result); - if (mode == 0) PendingCycles -= 8; - else PendingCycles -= 12 + EACyclesBW[mode, reg]; - return; - } - case 1: // word - { - short b = ReadWord(PC); PC += 2; - short a = PeekValueW(mode, reg); - int result = a - b; - X = C = ((a < b) ^ ((a ^ b) >= 0) == false); - V = result > short.MaxValue || result < short.MinValue; - N = (result & 0x8000) != 0; - Z = result == 0; - WriteValueW(mode, reg, (short)result); - if (mode == 0) PendingCycles -= 8; - else PendingCycles -= 12 + EACyclesBW[mode, reg]; - return; - } - case 2: // long - { - int b = ReadLong(PC); PC += 4; - int a = PeekValueL(mode, reg); - long result = a - b; - X = C = ((a < b) ^ ((a ^ b) >= 0) == false); - V = result > int.MaxValue || result < int.MinValue; - N = (result & 0x80000000) != 0; - Z = result == 0; - WriteValueL(mode, reg, (int)result); - if (mode == 0) PendingCycles -= 16; - else PendingCycles -= 20 + EACyclesBW[mode, reg]; - return; - } - } - } - - void SUBI_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int size = (op >> 6) & 3; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 3; - - switch (size) - { - case 0: - info.Mnemonic = "subi.b"; - info.Args = DisassembleImmediate(1, ref pc) + ", " + DisassembleValue(mode, reg, 1, ref pc); - break; - case 1: - info.Mnemonic = "subi.w"; - info.Args = DisassembleImmediate(2, ref pc) + ", " + DisassembleValue(mode, reg, 2, ref pc); - break; - case 2: - info.Mnemonic = "subi.l"; - info.Args = DisassembleImmediate(4, ref pc) + ", " + DisassembleValue(mode, reg, 4, ref pc); - break; - } - info.Length = pc - info.PC; - } - - void SUBQ() - { - int data = (op >> 9) & 7; - int size = (op >> 6) & 3; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - - data = data == 0 ? 8 : data; // range is 1-8; 0 represents 8 - - switch (size) - { - case 0: // byte - { - if (mode == 1) throw new Exception("SUBQ.B on address reg is invalid"); - sbyte value = PeekValueB(mode, reg); - int result = value - data; - N = (result & 0x80) != 0; - Z = result == 0; - V = result > sbyte.MaxValue || result < sbyte.MinValue; - C = X = ((value < data) ^ ((value ^ data) >= 0) == false); - WriteValueB(mode, reg, (sbyte) result); - if (mode == 0) PendingCycles -= 4; - else PendingCycles -= 8 + EACyclesBW[mode, reg]; - return; - } - case 1: // word - { - if (mode == 1) - { - int value = PeekValueL(mode, reg); - WriteValueL(mode, reg, value - data); - } - else - { - short value = PeekValueW(mode, reg); - int result = value - data; - N = (result & 0x8000) != 0; - Z = result == 0; - V = result > short.MaxValue || result < short.MinValue; - C = X = ((value < data) ^ ((value ^ data) >= 0) == false); - WriteValueW(mode, reg, (short)result); - } - if (mode <= 1) PendingCycles -= 4; - else PendingCycles -= 8 + EACyclesBW[mode, reg]; - return; - } - default: // long - { - int value = PeekValueL(mode, reg); - long result = value - data; - if (mode != 1) - { - N = (result & 0x80000000) != 0; - Z = result == 0; - V = result > int.MaxValue || result < int.MinValue; - C = X = ((value < data) ^ ((value ^ data) >= 0) == false); - } - WriteValueL(mode, reg, (int)result); - if (mode <= 1) PendingCycles -= 8; - else PendingCycles -= 12 + EACyclesL[mode, reg]; - return; - } - } - } - - void SUBQ_Disasm(DisassemblyInfo info) - { - 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; - - data = data == 0 ? 8 : data; // range is 1-8; 0 represents 8 - - switch (size) - { - case 0: info.Mnemonic = "subq.b"; info.Args = data+", "+DisassembleValue(mode, reg, 1, ref pc); break; - case 1: info.Mnemonic = "subq.w"; info.Args = data+", "+DisassembleValue(mode, reg, 2, ref pc); break; - case 2: info.Mnemonic = "subq.l"; info.Args = data+", "+DisassembleValue(mode, reg, 4, ref pc); break; - } - info.Length = pc - info.PC; - } - - void SUBA() - { - int aReg = (op >> 9) & 7; - int size = (op >> 8) & 1; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - - if (size == 0) // word - { - int value = ReadValueW(mode, reg); - A[aReg].s32 -= value; - PendingCycles -= 8 + EACyclesBW[mode, reg]; - } else { // long - int value = ReadValueL(mode, reg); - A[aReg].s32 -= value; - if (mode == 0 || mode == 1 || (mode == 7 && reg == 4)) - PendingCycles -= 8 + EACyclesL[mode, reg]; - else - PendingCycles -= 6 + EACyclesL[mode, reg]; - } - } - - void SUBA_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - - int aReg = (op >> 9) & 7; - int size = (op >> 8) & 1; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - - info.Mnemonic = (size == 0) ? "suba.w" : "suba.l"; - info.Args = DisassembleValue(mode, reg, (size == 0) ? 2 : 4, ref pc) + ", A"+aReg; - - info.Length = pc - info.PC; - } - - void NEG() - { - int size = (op >> 6) & 0x03; - int mode = (op >> 3) & 0x07; - int reg = op & 0x07; - - if (mode == 1) throw new Exception("NEG on address reg is invalid"); - - switch (size) - { - case 0: // Byte - { - sbyte value = PeekValueB(mode, reg); - int result = 0 - value; - N = (result & 0x80) != 0; - Z = result == 0; - V = result > sbyte.MaxValue || result < sbyte.MinValue; - C = X = ((0 < value) ^ ((0 ^ value) >= 0) == false); - WriteValueB(mode, reg, (sbyte)result); - if (mode == 0) PendingCycles -= 4; - else PendingCycles -= 8 + EACyclesBW[mode, reg]; - return; - } - case 1: // Word - { - short value = PeekValueW(mode, reg); - int result = 0 - value; - N = (result & 0x8000) != 0; - Z = result == 0; - V = result > short.MaxValue || result < short.MinValue; - C = X = ((0 < value) ^ ((0 ^ value) >= 0) == false); - WriteValueW(mode, reg, (short)result); - if (mode == 0) PendingCycles -= 4; - else PendingCycles -= 8 + EACyclesBW[mode, reg]; - return; - } - case 2: // Long - { - int value = PeekValueL(mode, reg); - long result = 0 - value; - N = (result & 0x80000000) != 0; - Z = result == 0; - V = result > int.MaxValue || result < int.MinValue; - C = X = ((0 < value) ^ ((0 ^ value) >= 0) == false); - WriteValueL(mode, reg, (int)result); - if (mode == 0) PendingCycles -= 8; - else PendingCycles -= 12 + EACyclesL[mode, reg]; - return; - } - } - } - - void NEG_Disasm(DisassemblyInfo info) - { - int size = (op >> 6) & 0x03; - int mode = (op >> 3) & 0x07; - int reg = op & 0x07; - - int pc = info.PC + 2; - - switch (size) - { - case 0: // Byte - info.Mnemonic = "neg.b"; - info.Args = DisassembleValue(mode, reg, 1, ref pc); - break; - case 1: // Word - info.Mnemonic = "neg.w"; - info.Args = DisassembleValue(mode, reg, 2, ref pc); - break; - case 2: // Long - info.Mnemonic = "neg.l"; - info.Args = DisassembleValue(mode, reg, 4, ref pc); - break; - } - - info.Length = pc - info.PC; - } - - void CMP() - { - int dReg = (op >> 9) & 7; - int size = (op >> 6) & 3; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - - switch (size) - { - case 0: // byte - { - sbyte a = D[dReg].s8; - sbyte b = ReadValueB(mode, reg); - int result = a - b; - N = (result & 0x80) != 0; - Z = result == 0; - V = result > sbyte.MaxValue || result < sbyte.MinValue; - C = ((a < b) ^ ((a ^ b) >= 0) == false); - if (mode == 0) PendingCycles -= 8; - PendingCycles -= 4 + EACyclesBW[mode, reg]; - return; - } - case 1: // word - { - short a = D[dReg].s16; - short b = ReadValueW(mode, reg); - int result = a - b; - N = (result & 0x8000) != 0; - Z = result == 0; - V = result > short.MaxValue || result < short.MinValue; - C = ((a < b) ^ ((a ^ b) >= 0) == false); - if (mode == 0) PendingCycles -= 8; - PendingCycles -= 4 + EACyclesBW[mode, reg]; - return; - } - case 2: // long - { - int a = D[dReg].s32; - int b = ReadValueL(mode, reg); - long result = a - b; - N = (result & 0x80000000) != 0; - Z = result == 0; - V = result > int.MaxValue || result < int.MinValue; - C = ((a < b) ^ ((a ^ b) >= 0) == false); - PendingCycles -= 6 + EACyclesL[mode, reg]; - return; - } - } - } - - void CMP_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - - int dReg = (op >> 9) & 7; - int size = (op >> 6) & 3; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - - switch (size) - { - case 0: - info.Mnemonic = "cmp.b"; - info.Args = DisassembleValue(mode, reg, 1, ref pc) + ", D" + dReg; - break; - case 1: - info.Mnemonic = "cmp.w"; - info.Args = DisassembleValue(mode, reg, 2, ref pc) + ", D" + dReg; - break; - case 2: - info.Mnemonic = "cmp.l"; - info.Args = DisassembleValue(mode, reg, 4, ref pc) + ", D" + dReg; - break; - } - info.Length = pc - info.PC; - } - - void CMPA() - { - int aReg = (op >> 9) & 7; - int size = (op >> 8) & 1; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - - switch (size) - { - case 0: // word - { - short a = A[aReg].s16; - short b = ReadValueW(mode, reg); - int result = a - b; - N = (result & 0x8000) != 0; - Z = result == 0; - V = result > short.MaxValue || result < short.MinValue; - C = ((a < b) ^ ((a ^ b) >= 0) == false); - PendingCycles -= 6 + EACyclesBW[mode, reg]; - return; - } - case 1: // long - { - int a = A[aReg].s32; - int b = ReadValueL(mode, reg); - long result = a - b; - N = (result & 0x80000000) != 0; - Z = result == 0; - V = result > int.MaxValue || result < int.MinValue; - C = ((a < b) ^ ((a ^ b) >= 0) == false); - PendingCycles -= 6 + EACyclesL[mode, reg]; - return; - } - } - } - - void CMPA_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - - int aReg = (op >> 9) & 7; - int size = (op >> 8) & 1; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - - switch (size) - { - case 0: - info.Mnemonic = "cmpa.w"; - info.Args = DisassembleValue(mode, reg, 2, ref pc) + ", A" + aReg; - break; - case 1: - info.Mnemonic = "cmpa.l"; - info.Args = DisassembleValue(mode, reg, 4, ref pc) + ", A" + aReg; - break; - } - info.Length = pc - info.PC; - } - - void CMPM() - { - int axReg = (op >> 9) & 7; - int size = (op >> 6) & 3; - int ayReg = (op >> 0) & 7; - - switch (size) - { - case 0: // byte - { - sbyte a = ReadByte(A[axReg].s32); A[axReg].s32 += 1; // Does A7 stay word aligned??? - sbyte b = ReadByte(A[ayReg].s32); A[ayReg].s32 += 1; - int result = a - b; - N = (result & 0x80) != 0; - Z = result == 0; - V = result > sbyte.MaxValue || result < sbyte.MinValue; - C = ((a < b) ^ ((a ^ b) >= 0) == false); - PendingCycles -= 12; - return; - } - case 1: // word - { - short a = ReadWord(A[axReg].s32); A[axReg].s32 += 2; - short b = ReadWord(A[ayReg].s32); A[ayReg].s32 += 2; - int result = a - b; - N = (result & 0x8000) != 0; - Z = result == 0; - V = result > short.MaxValue || result < short.MinValue; - C = ((a < b) ^ ((a ^ b) >= 0) == false); - PendingCycles -= 12; - return; - } - case 2: // long - { - int a = ReadLong(A[axReg].s32); A[axReg].s32 += 4; - int b = ReadLong(A[ayReg].s32); A[ayReg].s32 += 4; - long result = a - b; - N = (result & 0x80000000) != 0; - Z = result == 0; - V = result > int.MaxValue || result < int.MinValue; - C = ((a < b) ^ ((a ^ b) >= 0) == false); - 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; - - switch (size) - { - case 0: // byte - { - sbyte b = (sbyte) ReadWord(PC); PC += 2; - sbyte a = ReadValueB(mode, reg); - int result = a - b; - N = (result & 0x80) != 0; - Z = result == 0; - V = result > sbyte.MaxValue || result < sbyte.MinValue; - C = ((a < b) ^ ((a ^ b) >= 0) == false); - if (mode == 0) PendingCycles -= 8; - else PendingCycles -= 8 + EACyclesBW[mode, reg]; - return; - } - case 1: // word - { - short b = ReadWord(PC); PC += 2; - short a = ReadValueW(mode, reg); - int result = a - b; - N = (result & 0x8000) != 0; - Z = result == 0; - V = result > short.MaxValue || result < short.MinValue; - C = ((a < b) ^ ((a ^ b) >= 0) == false); - if (mode == 0) PendingCycles -= 8; - else PendingCycles -= 8 + EACyclesBW[mode, reg]; - return; - } - case 2: // long - { - int b = ReadLong(PC); PC += 4; - int a = ReadValueL(mode, reg); - long result = a - b; - N = (result & 0x80000000) != 0; - Z = result == 0; - V = result > int.MaxValue || result < int.MinValue; - C = ((a < b) ^ ((a ^ b) >= 0) == false); - if (mode == 0) PendingCycles -= 14; - else PendingCycles -= 12 + EACyclesL[mode, reg]; - return; - } - } - } - - void CMPI_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int size = (op >> 6) & 3; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - int immediate; - - switch (size) - { - case 0: - immediate = (byte)ReadWord(pc); pc += 2; - info.Mnemonic = "cmpi.b"; - info.Args = String.Format("${0:X}, {1}", immediate, DisassembleValue(mode, reg, 1, ref pc)); - break; - case 1: - immediate = ReadWord(pc); pc += 2; - info.Mnemonic = "cmpi.w"; - info.Args = String.Format("${0:X}, {1}", immediate, DisassembleValue(mode, reg, 2, ref pc)); - break; - case 2: - immediate = ReadLong(pc); pc += 4; - info.Mnemonic = "cmpi.l"; - info.Args = String.Format("${0:X}, {1}", immediate, DisassembleValue(mode, reg, 4, ref pc)); - break; - } - info.Length = pc - info.PC; - } - - void MULU() - { - int dreg = (op >> 9) & 7; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - - uint result = (uint) (D[dreg].u16 * (ushort)ReadValueW(mode, reg)); - D[dreg].u32 = result; - - V = false; - C = false; - N = (result & 0x80000000) != 0; - Z = result == 0; - - PendingCycles -= 70 + EACyclesBW[mode, reg]; - } - - void MULU_Disasm(DisassemblyInfo info) - { - int dreg = (op >> 9) & 7; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - - int pc = info.PC + 2; - info.Mnemonic = "mulu"; - info.Args = String.Format("{0}, D{1}", DisassembleValue(mode, reg, 2, ref pc), dreg); - info.Length = pc - info.PC; - } - - void MULS() - { - int dreg = (op >> 9) & 7; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - - int result = D[dreg].s16 * ReadValueW(mode, reg); - D[dreg].s32 = result; - - V = false; - C = false; - N = (result & 0x80000000) != 0; - Z = result == 0; - - PendingCycles -= 70 + EACyclesBW[mode, reg]; - } - - void MULS_Disasm(DisassemblyInfo info) - { - int dreg = (op >> 9) & 7; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - - int pc = info.PC + 2; - info.Mnemonic = "muls"; - info.Args = String.Format("{0}, D{1}", DisassembleValue(mode, reg, 2, ref pc), dreg); - info.Length = pc - info.PC; - } - - void DIVU() - { - int dreg = (op >> 9) & 7; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - - uint source = (ushort) ReadValueW(mode, reg); - uint dest = D[dreg].u32; - - if (source == 0) - throw new Exception("divide by zero"); - - uint quotient = dest / source; - uint remainder = dest % source; - - V = ((int) quotient < short.MinValue || (int) quotient > short.MaxValue); - N = (quotient & 0x8000) != 0; - Z = quotient == 0; - C = false; - - D[dreg].u32 = (quotient & 0xFFFF) | (remainder << 16); - PendingCycles -= 140 + EACyclesBW[mode, reg]; // this is basically a rough approximation at best. - } - - void DIVU_Disasm(DisassemblyInfo info) - { - int dreg = (op >> 9) & 7; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - - int pc = info.PC + 2; - info.Mnemonic = "divu"; - info.Args = String.Format("{0}, D{1}", DisassembleValue(mode, reg, 2, ref pc), dreg); - info.Length = pc - info.PC; - } - - void DIVS() - { - int dreg = (op >> 9) & 7; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - - int source = ReadValueW(mode, reg); - int dest = D[dreg].s32; - - if (source == 0) - throw new Exception("divide by zero"); - - int quotient = dest / source; - int remainder = dest % source; - - V = ((int)quotient < short.MinValue || (int)quotient > short.MaxValue); - N = (quotient & 0x8000) != 0; - Z = quotient == 0; - C = false; - - D[dreg].s32 = (quotient & 0xFFFF) | (remainder << 16); - PendingCycles -= 140 + EACyclesBW[mode, reg]; - } - - void DIVS_Disasm(DisassemblyInfo info) - { - int dreg = (op >> 9) & 7; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - - int pc = info.PC + 2; - info.Mnemonic = "divs"; - info.Args = String.Format("{0}, D{1}", DisassembleValue(mode, reg, 2, ref pc), dreg); - info.Length = pc - info.PC; - } - } + partial class MC68000 + { + void ADD0() + { + int Dreg = (op >> 9) & 7; + int size = (op >> 6) & 3; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + switch (size) + { + case 0: // byte + { + sbyte value = ReadValueB(mode, reg); + int result = D[Dreg].s8 + value; + int uresult = D[Dreg].u8 + (byte)value; + X = C = (uresult & 0x100) != 0; + V = result > sbyte.MaxValue || result < sbyte.MinValue; + N = (result & 0x80) != 0; + Z = result == 0; + D[Dreg].s8 = (sbyte)result; + PendingCycles -= 4 + EACyclesBW[mode, reg]; + return; + } + case 1: // word + { + short value = ReadValueW(mode, reg); + int result = D[Dreg].s16 + value; + int uresult = D[Dreg].u16 + (ushort)value; + X = C = (uresult & 0x10000) != 0; + V = result > short.MaxValue || result < short.MinValue; + N = (result & 0x8000) != 0; + Z = result == 0; + D[Dreg].s16 = (short)result; + PendingCycles -= 4 + EACyclesBW[mode, reg]; + return; + } + case 2: // long + { + int value = ReadValueL(mode, reg); + long result = D[Dreg].s32 + value; + long uresult = D[Dreg].u32 + (uint)value; + X = C = (uresult & 0x100000000) != 0; + V = result > int.MaxValue || result < int.MinValue; + N = (result & 0x80000000) != 0; + Z = result == 0; + D[Dreg].s32 = (int)result; + PendingCycles -= 6 + EACyclesL[mode, reg]; + return; + } + } + } + + void ADD1() + { + int Dreg = (op >> 9) & 7; + int size = (op >> 6) & 3; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + switch (size) + { + case 0: // byte + { + sbyte value = PeekValueB(mode, reg); + int result = value + D[Dreg].s8; + int uresult = (byte)value + D[Dreg].u8; + X = C = (uresult & 0x100) != 0; + V = result > sbyte.MaxValue || result < sbyte.MinValue; + N = (result & 0x80) != 0; + Z = result == 0; + WriteValueB(mode, reg, (sbyte)result); + PendingCycles -= 8 + EACyclesBW[mode, reg]; + return; + } + case 1: // word + { + short value = PeekValueW(mode, reg); + int result = value + D[Dreg].s16; + int uresult = (ushort)value + D[Dreg].u16; + X = C = (uresult & 0x10000) != 0; + V = result > short.MaxValue || result < short.MinValue; + N = (result & 0x8000) != 0; + Z = result == 0; + WriteValueW(mode, reg, (short)result); + PendingCycles -= 8 + EACyclesBW[mode, reg]; + return; + } + case 2: // long + { + int value = PeekValueL(mode, reg); + long result = value + D[Dreg].s32; + long uresult = (uint)value + D[Dreg].u32; + X = C = (uresult & 0x100000000) != 0; + V = result > int.MaxValue || result < int.MinValue; + N = (result & 0x80000000) != 0; + Z = result == 0; + WriteValueL(mode, reg, (int)result); + PendingCycles -= 12 + EACyclesL[mode, reg]; + return; + } + } + } + + void ADD_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int Dreg = (op >> 9) & 7; + int dir = (op >> 8) & 1; + int size = (op >> 6) & 3; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + string op1 = "D" + Dreg; + string op2; + + switch (size) + { + case 0: info.Mnemonic = "add.b"; op2 = DisassembleValue(mode, reg, 1, ref pc); break; + case 1: info.Mnemonic = "add.w"; op2 = DisassembleValue(mode, reg, 2, ref pc); break; + default: info.Mnemonic = "add.l"; op2 = DisassembleValue(mode, reg, 4, ref pc); break; + } + info.Args = dir == 0 ? (op2 + ", " + op1) : (op1 + ", " + op2); + info.Length = pc - info.PC; + } + + void ADDI() + { + int size = (op >> 6) & 3; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + switch (size) + { + case 0: // byte + { + int immed = (sbyte)ReadWord(PC); PC += 2; + sbyte value = PeekValueB(mode, reg); + int result = value + immed; + int uresult = (byte)value + (byte)immed; + X = C = (uresult & 0x100) != 0; + V = result > sbyte.MaxValue || result < sbyte.MinValue; + N = (result & 0x80) != 0; + Z = result == 0; + WriteValueB(mode, reg, (sbyte)result); + if (mode == 0) PendingCycles -= 8; + else PendingCycles -= 12 + EACyclesBW[mode, reg]; + return; + } + case 1: // word + { + int immed = ReadWord(PC); PC += 2; + short value = PeekValueW(mode, reg); + int result = value + immed; + int uresult = (ushort)value + (ushort)immed; + X = C = (uresult & 0x10000) != 0; + V = result > short.MaxValue || result < short.MinValue; + N = (result & 0x8000) != 0; + Z = result == 0; + WriteValueW(mode, reg, (short)result); + if (mode == 0) PendingCycles -= 8; + else PendingCycles -= 12 + EACyclesBW[mode, reg]; + return; + } + case 2: // long + { + int immed = ReadLong(PC); PC += 4; + int value = PeekValueL(mode, reg); + long result = value + immed; + long uresult = (uint)value + (uint)immed; + X = C = (uresult & 0x100000000) != 0; + V = result > int.MaxValue || result < int.MinValue; + N = (result & 0x80000000) != 0; + Z = result == 0; + WriteValueL(mode, reg, (int)result); + if (mode == 0) PendingCycles -= 16; + else PendingCycles -= 20 + EACyclesBW[mode, reg]; + return; + } + } + } + + void ADDI_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int size = (op >> 6) & 3; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 3; + + switch (size) + { + case 0: + info.Mnemonic = "addi.b"; + info.Args = DisassembleImmediate(1, ref pc) + ", " + DisassembleValue(mode, reg, 1, ref pc); + break; + case 1: + info.Mnemonic = "addi.w"; + info.Args = DisassembleImmediate(2, ref pc) + ", " + DisassembleValue(mode, reg, 2, ref pc); + break; + case 2: + info.Mnemonic = "addi.l"; + info.Args = DisassembleImmediate(4, ref pc) + ", " + DisassembleValue(mode, reg, 4, ref pc); + break; + } + info.Length = pc - info.PC; + } + + void ADDQ() + { + int data = (op >> 9) & 7; + int size = (op >> 6) & 3; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + data = data == 0 ? 8 : data; // range is 1-8; 0 represents 8 + + switch (size) + { + case 0: // byte + { + if (mode == 1) throw new Exception("ADDQ.B on address reg is invalid"); + sbyte value = PeekValueB(mode, reg); + int result = value + data; + int uresult = (byte)value + data; + N = (result & 0x80) != 0; + Z = result == 0; + V = result > sbyte.MaxValue || result < sbyte.MinValue; + C = X = (uresult & 0x100) != 0; + WriteValueB(mode, reg, (sbyte)result); + if (mode == 0) PendingCycles -= 4; + else PendingCycles -= 8 + EACyclesBW[mode, reg]; + return; + } + case 1: // word + { + if (mode == 1) + { + int value = PeekValueL(mode, reg); + WriteValueL(mode, reg, value + data); + } + else + { + short value = PeekValueW(mode, reg); + int result = value + data; + int uresult = (ushort)value + data; + N = (result & 0x8000) != 0; + Z = result == 0; + V = result > short.MaxValue || result < short.MinValue; + C = X = (uresult & 0x10000) != 0; + WriteValueW(mode, reg, (short)result); + } + if (mode <= 1) PendingCycles -= 4; + else PendingCycles -= 8 + EACyclesBW[mode, reg]; + return; + } + default: // long + { + int value = PeekValueL(mode, reg); + long result = value + data; + long uresult = (uint)value + data; + if (mode != 1) + { + N = (result & 0x80000000) != 0; + Z = result == 0; + V = result > int.MaxValue || result < int.MinValue; + C = X = (uresult & 0x100000000) != 0; + } + WriteValueL(mode, reg, (int)result); + if (mode <= 1) PendingCycles -= 8; + else PendingCycles -= 12 + EACyclesL[mode, reg]; + return; + } + } + } + + void ADDQ_Disasm(DisassemblyInfo info) + { + 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; + + data = data == 0 ? 8 : data; // range is 1-8; 0 represents 8 + + switch (size) + { + case 0: info.Mnemonic = "addq.b"; info.Args = data + ", " + DisassembleValue(mode, reg, 1, ref pc); break; + case 1: info.Mnemonic = "addq.w"; info.Args = data + ", " + DisassembleValue(mode, reg, 2, ref pc); break; + case 2: info.Mnemonic = "addq.l"; info.Args = data + ", " + DisassembleValue(mode, reg, 4, ref pc); break; + } + info.Length = pc - info.PC; + } + + void ADDA() + { + int aReg = (op >> 9) & 7; + int size = (op >> 8) & 1; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + if (size == 0) // word + { + int value = ReadValueW(mode, reg); + A[aReg].s32 += value; + PendingCycles -= 8 + EACyclesBW[mode, reg]; + } + else + { // long + int value = ReadValueL(mode, reg); + A[aReg].s32 += value; + if (mode == 0 || mode == 1 || (mode == 7 && reg == 4)) + PendingCycles -= 8 + EACyclesL[mode, reg]; + else + PendingCycles -= 6 + EACyclesL[mode, reg]; + } + } + + void ADDA_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int aReg = (op >> 9) & 7; + int size = (op >> 8) & 1; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + info.Mnemonic = (size == 0) ? "adda.w" : "adda.l"; + info.Args = DisassembleValue(mode, reg, (size == 0) ? 2 : 4, ref pc) + ", A" + aReg; + + info.Length = pc - info.PC; + } + + void SUB0() + { + int dReg = (op >> 9) & 7; + int size = (op >> 6) & 3; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + switch (size) + { + case 0: // byte + { + sbyte a = D[dReg].s8; + sbyte b = ReadValueB(mode, reg); + int result = a - b; + X = C = ((a < b) ^ ((a ^ b) >= 0) == false); + V = result > sbyte.MaxValue || result < sbyte.MinValue; + N = (result & 0x80) != 0; + Z = result == 0; + D[dReg].s8 = (sbyte)result; + PendingCycles -= 4 + EACyclesBW[mode, reg]; + return; + } + case 1: // word + { + short a = D[dReg].s16; + short b = ReadValueW(mode, reg); + int result = a - b; + X = C = ((a < b) ^ ((a ^ b) >= 0) == false); + V = result > short.MaxValue || result < short.MinValue; + N = (result & 0x8000) != 0; + Z = result == 0; + D[dReg].s16 = (short)result; + PendingCycles -= 4 + EACyclesBW[mode, reg]; + return; + } + case 2: // long + { + int a = D[dReg].s32; + int b = ReadValueL(mode, reg); + long result = a - b; + X = C = ((a < b) ^ ((a ^ b) >= 0) == false); + V = result > int.MaxValue || result < int.MinValue; + N = (result & 0x80000000) != 0; + Z = result == 0; + D[dReg].s32 = (int)result; + PendingCycles -= 6 + EACyclesL[mode, reg]; + return; + } + } + } + + void SUB1() + { + int dReg = (op >> 9) & 7; + int size = (op >> 6) & 3; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + switch (size) + { + case 0: // byte + { + sbyte a = PeekValueB(mode, reg); + sbyte b = D[dReg].s8; + int result = a - b; + X = C = ((a < b) ^ ((a ^ b) >= 0) == false); + V = result > sbyte.MaxValue || result < sbyte.MinValue; + N = (result & 0x80) != 0; + Z = result == 0; + WriteValueB(mode, reg, (sbyte)result); + PendingCycles -= 8 + EACyclesBW[mode, reg]; + return; + } + case 1: // word + { + short a = PeekValueW(mode, reg); + short b = D[dReg].s16; + int result = a - b; + X = C = ((a < b) ^ ((a ^ b) >= 0) == false); + V = result > short.MaxValue || result < short.MinValue; + N = (result & 0x8000) != 0; + Z = result == 0; + WriteValueW(mode, reg, (short)result); + PendingCycles -= 8 + EACyclesBW[mode, reg]; + return; + } + case 2: // long + { + int a = PeekValueL(mode, reg); + int b = D[dReg].s32; + long result = a - b; + X = C = ((a < b) ^ ((a ^ b) >= 0) == false); + V = result > int.MaxValue || result < int.MinValue; + N = (result & 0x80000000) != 0; + Z = result == 0; + WriteValueL(mode, reg, (int)result); + PendingCycles -= 12 + EACyclesL[mode, reg]; + return; + } + } + } + + void SUB_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int dReg = (op >> 9) & 7; + int dir = (op >> 8) & 1; + int size = (op >> 6) & 3; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + string op1 = "D" + dReg; + string op2; + + switch (size) + { + case 0: info.Mnemonic = "sub.b"; op2 = DisassembleValue(mode, reg, 1, ref pc); break; + case 1: info.Mnemonic = "sub.w"; op2 = DisassembleValue(mode, reg, 2, ref pc); break; + default: info.Mnemonic = "sub.l"; op2 = DisassembleValue(mode, reg, 4, ref pc); break; + } + info.Args = dir == 0 ? (op2 + ", " + op1) : (op1 + ", " + op2); + info.Length = pc - info.PC; + } + + void SUBI() + { + int size = (op >> 6) & 3; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + switch (size) + { + case 0: // byte + { + sbyte b = (sbyte)ReadWord(PC); PC += 2; + sbyte a = PeekValueB(mode, reg); + int result = a - b; + X = C = ((a < b) ^ ((a ^ b) >= 0) == false); + V = result > sbyte.MaxValue || result < sbyte.MinValue; + N = (result & 0x80) != 0; + Z = result == 0; + WriteValueB(mode, reg, (sbyte)result); + if (mode == 0) PendingCycles -= 8; + else PendingCycles -= 12 + EACyclesBW[mode, reg]; + return; + } + case 1: // word + { + short b = ReadWord(PC); PC += 2; + short a = PeekValueW(mode, reg); + int result = a - b; + X = C = ((a < b) ^ ((a ^ b) >= 0) == false); + V = result > short.MaxValue || result < short.MinValue; + N = (result & 0x8000) != 0; + Z = result == 0; + WriteValueW(mode, reg, (short)result); + if (mode == 0) PendingCycles -= 8; + else PendingCycles -= 12 + EACyclesBW[mode, reg]; + return; + } + case 2: // long + { + int b = ReadLong(PC); PC += 4; + int a = PeekValueL(mode, reg); + long result = a - b; + X = C = ((a < b) ^ ((a ^ b) >= 0) == false); + V = result > int.MaxValue || result < int.MinValue; + N = (result & 0x80000000) != 0; + Z = result == 0; + WriteValueL(mode, reg, (int)result); + if (mode == 0) PendingCycles -= 16; + else PendingCycles -= 20 + EACyclesBW[mode, reg]; + return; + } + } + } + + void SUBI_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int size = (op >> 6) & 3; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 3; + + switch (size) + { + case 0: + info.Mnemonic = "subi.b"; + info.Args = DisassembleImmediate(1, ref pc) + ", " + DisassembleValue(mode, reg, 1, ref pc); + break; + case 1: + info.Mnemonic = "subi.w"; + info.Args = DisassembleImmediate(2, ref pc) + ", " + DisassembleValue(mode, reg, 2, ref pc); + break; + case 2: + info.Mnemonic = "subi.l"; + info.Args = DisassembleImmediate(4, ref pc) + ", " + DisassembleValue(mode, reg, 4, ref pc); + break; + } + info.Length = pc - info.PC; + } + + void SUBQ() + { + int data = (op >> 9) & 7; + int size = (op >> 6) & 3; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + data = data == 0 ? 8 : data; // range is 1-8; 0 represents 8 + + switch (size) + { + case 0: // byte + { + if (mode == 1) throw new Exception("SUBQ.B on address reg is invalid"); + sbyte value = PeekValueB(mode, reg); + int result = value - data; + N = (result & 0x80) != 0; + Z = result == 0; + V = result > sbyte.MaxValue || result < sbyte.MinValue; + C = X = ((value < data) ^ ((value ^ data) >= 0) == false); + WriteValueB(mode, reg, (sbyte)result); + if (mode == 0) PendingCycles -= 4; + else PendingCycles -= 8 + EACyclesBW[mode, reg]; + return; + } + case 1: // word + { + if (mode == 1) + { + int value = PeekValueL(mode, reg); + WriteValueL(mode, reg, value - data); + } + else + { + short value = PeekValueW(mode, reg); + int result = value - data; + N = (result & 0x8000) != 0; + Z = result == 0; + V = result > short.MaxValue || result < short.MinValue; + C = X = ((value < data) ^ ((value ^ data) >= 0) == false); + WriteValueW(mode, reg, (short)result); + } + if (mode <= 1) PendingCycles -= 4; + else PendingCycles -= 8 + EACyclesBW[mode, reg]; + return; + } + default: // long + { + int value = PeekValueL(mode, reg); + long result = value - data; + if (mode != 1) + { + N = (result & 0x80000000) != 0; + Z = result == 0; + V = result > int.MaxValue || result < int.MinValue; + C = X = ((value < data) ^ ((value ^ data) >= 0) == false); + } + WriteValueL(mode, reg, (int)result); + if (mode <= 1) PendingCycles -= 8; + else PendingCycles -= 12 + EACyclesL[mode, reg]; + return; + } + } + } + + void SUBQ_Disasm(DisassemblyInfo info) + { + 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; + + data = data == 0 ? 8 : data; // range is 1-8; 0 represents 8 + + switch (size) + { + case 0: info.Mnemonic = "subq.b"; info.Args = data + ", " + DisassembleValue(mode, reg, 1, ref pc); break; + case 1: info.Mnemonic = "subq.w"; info.Args = data + ", " + DisassembleValue(mode, reg, 2, ref pc); break; + case 2: info.Mnemonic = "subq.l"; info.Args = data + ", " + DisassembleValue(mode, reg, 4, ref pc); break; + } + info.Length = pc - info.PC; + } + + void SUBA() + { + int aReg = (op >> 9) & 7; + int size = (op >> 8) & 1; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + if (size == 0) // word + { + int value = ReadValueW(mode, reg); + A[aReg].s32 -= value; + PendingCycles -= 8 + EACyclesBW[mode, reg]; + } + else + { // long + int value = ReadValueL(mode, reg); + A[aReg].s32 -= value; + if (mode == 0 || mode == 1 || (mode == 7 && reg == 4)) + PendingCycles -= 8 + EACyclesL[mode, reg]; + else + PendingCycles -= 6 + EACyclesL[mode, reg]; + } + } + + void SUBA_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + + int aReg = (op >> 9) & 7; + int size = (op >> 8) & 1; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + info.Mnemonic = (size == 0) ? "suba.w" : "suba.l"; + info.Args = DisassembleValue(mode, reg, (size == 0) ? 2 : 4, ref pc) + ", A" + aReg; + + info.Length = pc - info.PC; + } + + void NEG() + { + int size = (op >> 6) & 0x03; + int mode = (op >> 3) & 0x07; + int reg = op & 0x07; + + if (mode == 1) throw new Exception("NEG on address reg is invalid"); + + switch (size) + { + case 0: // Byte + { + sbyte value = PeekValueB(mode, reg); + int result = 0 - value; + N = (result & 0x80) != 0; + Z = result == 0; + V = result > sbyte.MaxValue || result < sbyte.MinValue; + C = X = ((0 < value) ^ ((0 ^ value) >= 0) == false); + WriteValueB(mode, reg, (sbyte)result); + if (mode == 0) PendingCycles -= 4; + else PendingCycles -= 8 + EACyclesBW[mode, reg]; + return; + } + case 1: // Word + { + short value = PeekValueW(mode, reg); + int result = 0 - value; + N = (result & 0x8000) != 0; + Z = result == 0; + V = result > short.MaxValue || result < short.MinValue; + C = X = ((0 < value) ^ ((0 ^ value) >= 0) == false); + WriteValueW(mode, reg, (short)result); + if (mode == 0) PendingCycles -= 4; + else PendingCycles -= 8 + EACyclesBW[mode, reg]; + return; + } + case 2: // Long + { + int value = PeekValueL(mode, reg); + long result = 0 - value; + N = (result & 0x80000000) != 0; + Z = result == 0; + V = result > int.MaxValue || result < int.MinValue; + C = X = ((0 < value) ^ ((0 ^ value) >= 0) == false); + WriteValueL(mode, reg, (int)result); + if (mode == 0) PendingCycles -= 8; + else PendingCycles -= 12 + EACyclesL[mode, reg]; + return; + } + } + } + + void NEG_Disasm(DisassemblyInfo info) + { + int size = (op >> 6) & 0x03; + int mode = (op >> 3) & 0x07; + int reg = op & 0x07; + + int pc = info.PC + 2; + + switch (size) + { + case 0: // Byte + info.Mnemonic = "neg.b"; + info.Args = DisassembleValue(mode, reg, 1, ref pc); + break; + case 1: // Word + info.Mnemonic = "neg.w"; + info.Args = DisassembleValue(mode, reg, 2, ref pc); + break; + case 2: // Long + info.Mnemonic = "neg.l"; + info.Args = DisassembleValue(mode, reg, 4, ref pc); + break; + } + + info.Length = pc - info.PC; + } + + void CMP() + { + int dReg = (op >> 9) & 7; + int size = (op >> 6) & 3; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + switch (size) + { + case 0: // byte + { + sbyte a = D[dReg].s8; + sbyte b = ReadValueB(mode, reg); + int result = a - b; + N = (result & 0x80) != 0; + Z = result == 0; + V = result > sbyte.MaxValue || result < sbyte.MinValue; + C = ((a < b) ^ ((a ^ b) >= 0) == false); + if (mode == 0) PendingCycles -= 8; + PendingCycles -= 4 + EACyclesBW[mode, reg]; + return; + } + case 1: // word + { + short a = D[dReg].s16; + short b = ReadValueW(mode, reg); + int result = a - b; + N = (result & 0x8000) != 0; + Z = result == 0; + V = result > short.MaxValue || result < short.MinValue; + C = ((a < b) ^ ((a ^ b) >= 0) == false); + if (mode == 0) PendingCycles -= 8; + PendingCycles -= 4 + EACyclesBW[mode, reg]; + return; + } + case 2: // long + { + int a = D[dReg].s32; + int b = ReadValueL(mode, reg); + long result = a - b; + N = (result & 0x80000000) != 0; + Z = result == 0; + V = result > int.MaxValue || result < int.MinValue; + C = ((a < b) ^ ((a ^ b) >= 0) == false); + PendingCycles -= 6 + EACyclesL[mode, reg]; + return; + } + } + } + + void CMP_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + + int dReg = (op >> 9) & 7; + int size = (op >> 6) & 3; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + switch (size) + { + case 0: + info.Mnemonic = "cmp.b"; + info.Args = DisassembleValue(mode, reg, 1, ref pc) + ", D" + dReg; + break; + case 1: + info.Mnemonic = "cmp.w"; + info.Args = DisassembleValue(mode, reg, 2, ref pc) + ", D" + dReg; + break; + case 2: + info.Mnemonic = "cmp.l"; + info.Args = DisassembleValue(mode, reg, 4, ref pc) + ", D" + dReg; + break; + } + info.Length = pc - info.PC; + } + + void CMPA() + { + int aReg = (op >> 9) & 7; + int size = (op >> 8) & 1; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + switch (size) + { + case 0: // word + { + short a = A[aReg].s16; + short b = ReadValueW(mode, reg); + int result = a - b; + N = (result & 0x8000) != 0; + Z = result == 0; + V = result > short.MaxValue || result < short.MinValue; + C = ((a < b) ^ ((a ^ b) >= 0) == false); + PendingCycles -= 6 + EACyclesBW[mode, reg]; + return; + } + case 1: // long + { + int a = A[aReg].s32; + int b = ReadValueL(mode, reg); + long result = a - b; + N = (result & 0x80000000) != 0; + Z = result == 0; + V = result > int.MaxValue || result < int.MinValue; + C = ((a < b) ^ ((a ^ b) >= 0) == false); + PendingCycles -= 6 + EACyclesL[mode, reg]; + return; + } + } + } + + void CMPA_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + + int aReg = (op >> 9) & 7; + int size = (op >> 8) & 1; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + switch (size) + { + case 0: + info.Mnemonic = "cmpa.w"; + info.Args = DisassembleValue(mode, reg, 2, ref pc) + ", A" + aReg; + break; + case 1: + info.Mnemonic = "cmpa.l"; + info.Args = DisassembleValue(mode, reg, 4, ref pc) + ", A" + aReg; + break; + } + info.Length = pc - info.PC; + } + + void CMPM() + { + int axReg = (op >> 9) & 7; + int size = (op >> 6) & 3; + int ayReg = (op >> 0) & 7; + + switch (size) + { + case 0: // byte + { + sbyte a = ReadByte(A[axReg].s32); A[axReg].s32 += 1; // Does A7 stay word aligned??? + sbyte b = ReadByte(A[ayReg].s32); A[ayReg].s32 += 1; + int result = a - b; + N = (result & 0x80) != 0; + Z = result == 0; + V = result > sbyte.MaxValue || result < sbyte.MinValue; + C = ((a < b) ^ ((a ^ b) >= 0) == false); + PendingCycles -= 12; + return; + } + case 1: // word + { + short a = ReadWord(A[axReg].s32); A[axReg].s32 += 2; + short b = ReadWord(A[ayReg].s32); A[ayReg].s32 += 2; + int result = a - b; + N = (result & 0x8000) != 0; + Z = result == 0; + V = result > short.MaxValue || result < short.MinValue; + C = ((a < b) ^ ((a ^ b) >= 0) == false); + PendingCycles -= 12; + return; + } + case 2: // long + { + int a = ReadLong(A[axReg].s32); A[axReg].s32 += 4; + int b = ReadLong(A[ayReg].s32); A[ayReg].s32 += 4; + long result = a - b; + N = (result & 0x80000000) != 0; + Z = result == 0; + V = result > int.MaxValue || result < int.MinValue; + C = ((a < b) ^ ((a ^ b) >= 0) == false); + 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; + + switch (size) + { + case 0: // byte + { + sbyte b = (sbyte)ReadWord(PC); PC += 2; + sbyte a = ReadValueB(mode, reg); + int result = a - b; + N = (result & 0x80) != 0; + Z = result == 0; + V = result > sbyte.MaxValue || result < sbyte.MinValue; + C = ((a < b) ^ ((a ^ b) >= 0) == false); + if (mode == 0) PendingCycles -= 8; + else PendingCycles -= 8 + EACyclesBW[mode, reg]; + return; + } + case 1: // word + { + short b = ReadWord(PC); PC += 2; + short a = ReadValueW(mode, reg); + int result = a - b; + N = (result & 0x8000) != 0; + Z = result == 0; + V = result > short.MaxValue || result < short.MinValue; + C = ((a < b) ^ ((a ^ b) >= 0) == false); + if (mode == 0) PendingCycles -= 8; + else PendingCycles -= 8 + EACyclesBW[mode, reg]; + return; + } + case 2: // long + { + int b = ReadLong(PC); PC += 4; + int a = ReadValueL(mode, reg); + long result = a - b; + N = (result & 0x80000000) != 0; + Z = result == 0; + V = result > int.MaxValue || result < int.MinValue; + C = ((a < b) ^ ((a ^ b) >= 0) == false); + if (mode == 0) PendingCycles -= 14; + else PendingCycles -= 12 + EACyclesL[mode, reg]; + return; + } + } + } + + void CMPI_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int size = (op >> 6) & 3; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + int immediate; + + switch (size) + { + case 0: + immediate = (byte)ReadWord(pc); pc += 2; + info.Mnemonic = "cmpi.b"; + info.Args = String.Format("${0:X}, {1}", immediate, DisassembleValue(mode, reg, 1, ref pc)); + break; + case 1: + immediate = ReadWord(pc); pc += 2; + info.Mnemonic = "cmpi.w"; + info.Args = String.Format("${0:X}, {1}", immediate, DisassembleValue(mode, reg, 2, ref pc)); + break; + case 2: + immediate = ReadLong(pc); pc += 4; + info.Mnemonic = "cmpi.l"; + info.Args = String.Format("${0:X}, {1}", immediate, DisassembleValue(mode, reg, 4, ref pc)); + break; + } + info.Length = pc - info.PC; + } + + void MULU() + { + int dreg = (op >> 9) & 7; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + uint result = (uint)(D[dreg].u16 * (ushort)ReadValueW(mode, reg)); + D[dreg].u32 = result; + + V = false; + C = false; + N = (result & 0x80000000) != 0; + Z = result == 0; + + PendingCycles -= 70 + EACyclesBW[mode, reg]; + } + + void MULU_Disasm(DisassemblyInfo info) + { + int dreg = (op >> 9) & 7; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + int pc = info.PC + 2; + info.Mnemonic = "mulu"; + info.Args = String.Format("{0}, D{1}", DisassembleValue(mode, reg, 2, ref pc), dreg); + info.Length = pc - info.PC; + } + + void MULS() + { + int dreg = (op >> 9) & 7; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + int result = D[dreg].s16 * ReadValueW(mode, reg); + D[dreg].s32 = result; + + V = false; + C = false; + N = (result & 0x80000000) != 0; + Z = result == 0; + + PendingCycles -= 70 + EACyclesBW[mode, reg]; + } + + void MULS_Disasm(DisassemblyInfo info) + { + int dreg = (op >> 9) & 7; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + int pc = info.PC + 2; + info.Mnemonic = "muls"; + info.Args = String.Format("{0}, D{1}", DisassembleValue(mode, reg, 2, ref pc), dreg); + info.Length = pc - info.PC; + } + + void DIVU() + { + int dreg = (op >> 9) & 7; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + uint source = (ushort)ReadValueW(mode, reg); + uint dest = D[dreg].u32; + + if (source == 0) + throw new Exception("divide by zero"); + + uint quotient = dest / source; + uint remainder = dest % source; + + V = ((int)quotient < short.MinValue || (int)quotient > short.MaxValue); + N = (quotient & 0x8000) != 0; + Z = quotient == 0; + C = false; + + D[dreg].u32 = (quotient & 0xFFFF) | (remainder << 16); + PendingCycles -= 140 + EACyclesBW[mode, reg]; // this is basically a rough approximation at best. + } + + void DIVU_Disasm(DisassemblyInfo info) + { + int dreg = (op >> 9) & 7; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + int pc = info.PC + 2; + info.Mnemonic = "divu"; + info.Args = String.Format("{0}, D{1}", DisassembleValue(mode, reg, 2, ref pc), dreg); + info.Length = pc - info.PC; + } + + void DIVS() + { + int dreg = (op >> 9) & 7; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + int source = ReadValueW(mode, reg); + int dest = D[dreg].s32; + + if (source == 0) + throw new Exception("divide by zero"); + + int quotient = dest / source; + int remainder = dest % source; + + V = ((int)quotient < short.MinValue || (int)quotient > short.MaxValue); + N = (quotient & 0x8000) != 0; + Z = quotient == 0; + C = false; + + D[dreg].s32 = (quotient & 0xFFFF) | (remainder << 16); + PendingCycles -= 140 + EACyclesBW[mode, reg]; + } + + void DIVS_Disasm(DisassemblyInfo info) + { + int dreg = (op >> 9) & 7; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + int pc = info.PC + 2; + info.Mnemonic = "divs"; + info.Args = String.Format("{0}, D{1}", DisassembleValue(mode, reg, 2, ref pc), dreg); + info.Length = pc - info.PC; + } + } } \ No newline at end of file diff --git a/BizHawk.Emulation/CPUs/68000/Instructions/ProgramFlow.cs b/BizHawk.Emulation/CPUs/68000/Instructions/ProgramFlow.cs index af64da7a0d..4e9300be48 100644 --- a/BizHawk.Emulation/CPUs/68000/Instructions/ProgramFlow.cs +++ b/BizHawk.Emulation/CPUs/68000/Instructions/ProgramFlow.cs @@ -1,723 +1,741 @@ using System; -namespace BizHawk.Emulation.CPUs.M68000 +namespace BizHawk.Emulation.Common.Components.M68000 { - partial class MC68000 - { - bool TestCondition(int condition) - { - switch (condition) - { - case 0x00: return true; // True - case 0x01: return false; // False - case 0x02: return !C && !Z; // High (Unsigned) - case 0x03: return C || Z; // Less or Same (Unsigned) - case 0x04: return !C; // Carry Clear (High or Same) - case 0x05: return C; // Carry Set (Lower) - case 0x06: return !Z; // Not Equal - case 0x07: return Z; // Equal - case 0x08: return !V; // Overflow Clear - case 0x09: return V; // Overflow Set - case 0x0A: return !N; // Plus (Positive) - case 0x0B: return N; // Minus (Negative) - case 0x0C: return N && V || !N && !V; // Greater or Equal - case 0x0D: return N && !V || !N && V; // Less Than - case 0x0E: return N && V && !Z || !N && !V && !Z; // Greater Than - case 0x0F: return Z || N && !V || !N && V; // Less or Equal - default: - throw new Exception("Invalid condition "+condition); - } - } - - string DisassembleCondition(int condition) - { - switch (condition) - { - case 0x00: return "t"; // True - case 0x01: return "f"; // False - case 0x02: return "hi"; // High (Unsigned) - case 0x03: return "ls"; // Less or Same (Unsigned) - case 0x04: return "cc"; // Carry Clear (High or Same) - case 0x05: return "cs"; // Carry Set (Lower) - case 0x06: return "ne"; // Not Equal - case 0x07: return "eq"; // Equal - case 0x08: return "vc"; // Overflow Clear - case 0x09: return "vs"; // Overflow Set - case 0x0A: return "pl"; // Plus (Positive) - case 0x0B: return "mi"; // Minus (Negative) - case 0x0C: return "ge"; // Greater or Equal - case 0x0D: return "lt"; // Less Than - case 0x0E: return "gt"; // Greater Than - case 0x0F: return "le"; // Less or Equal - default: return "??"; // Invalid condition - } - } - - void Bcc() // Branch on condition - { - sbyte displacement8 = (sbyte) op; - int cond = (op >> 8) & 0x0F; - - if (TestCondition(cond) == true) - { - if (displacement8 != 0) - { - // use opcode-embedded displacement - PC += displacement8; - PendingCycles -= 10; - } else { - // use extension word displacement - PC += ReadWord(PC); - PendingCycles -= 10; - } - } else { // false - if (displacement8 != 0) - PendingCycles -= 8; - else { - PC += 2; - PendingCycles -= 12; - } - } - } - - void Bcc_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - sbyte displacement8 = (sbyte)op; - int cond = (op >> 8) & 0x0F; - - info.Mnemonic = "b" + DisassembleCondition(cond); - if (displacement8 != 0) - { - info.Args = string.Format("${0:X}", pc + displacement8); - } else { - info.Args = string.Format("${0:X}", pc + ReadWord(pc)); - pc += 2; - } - info.Length = pc - info.PC; - } - - void BRA() - { - sbyte displacement8 = (sbyte)op; - - if (displacement8 != 0) - PC += displacement8; - else - PC += ReadWord(PC); - PendingCycles -= 10; - } - - void BRA_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - info.Mnemonic = "bra"; - - sbyte displacement8 = (sbyte)op; - if (displacement8 != 0) - info.Args = String.Format("${0:X}", pc + displacement8); - else - { - info.Args = String.Format("${0:X}", pc + ReadWord(pc)); - pc += 2; - } - info.Length = pc - info.PC; - } - - void BSR() - { - sbyte displacement8 = (sbyte)op; - - A[7].s32 -= 4; - if (displacement8 != 0) - { - // use embedded displacement - WriteLong(A[7].s32, PC); - PC += displacement8; - } else { - // use extension word displacement - WriteLong(A[7].s32, PC + 2); - PC += ReadWord(PC); - } - PendingCycles -= 18; - } - - void BSR_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - info.Mnemonic = "bsr"; - - sbyte displacement8 = (sbyte)op; - if (displacement8 != 0) - info.Args = String.Format("${0:X}", pc + displacement8); - else { - info.Args = String.Format("${0:X}", pc + ReadWord(pc)); - pc += 2; - } - info.Length = pc - info.PC; - } - - void DBcc() - { - if (TestCondition((op >> 8) & 0x0F) == true) - { - PC += 2; // condition met, break out of loop - PendingCycles -= 12; - } else { - int reg = op & 7; - D[reg].u16--; - - if (D[reg].u16 == 0xFFFF) - { - PC += 2; // counter underflowed, break out of loop - PendingCycles -= 14; - } else { - PC += ReadWord(PC); // condition false and counter not exhausted, so branch. - PendingCycles -= 10; - } - } - } - - void DBcc_Disasm(DisassemblyInfo info) - { - int cond = (op >> 8) & 0x0F; - if (cond == 1) - info.Mnemonic = "dbra"; - else - info.Mnemonic = "db" + DisassembleCondition(cond); - - int pc = info.PC + 2; - info.Args = String.Format("D{0}, ${1:X}", op & 7, pc + ReadWord(pc)); - info.Length = 4; - } - - void RTS() - { - PC = ReadLong(A[7].s32); - A[7].s32 += 4; - PendingCycles -= 16; - } - - void RTS_Disasm(DisassemblyInfo info) - { - info.Mnemonic = "rts"; - info.Args = ""; - } - - void RTR() - { - ushort sr = (ushort)ReadWord(A[7].s32); - A[7].s32 += 2; - C = (sr & 0x0001) != 0; - V = (sr & 0x0002) != 0; - Z = (sr & 0x0004) != 0; - N = (sr & 0x0008) != 0; - X = (sr & 0x0010) != 0; - - PC = ReadLong(A[7].s32); - A[7].s32 += 4; - PendingCycles -= 20; - } - - void RTR_Disasm(DisassemblyInfo info) - { - info.Mnemonic = "rtr"; - info.Args = ""; - } - - void RTE() - { - short newSR = ReadWord(A[7].s32); - A[7].s32 += 2; - PC = ReadLong(A[7].s32); - A[7].s32 += 4; - SR = newSR; - PendingCycles -= 20; - } - - void RTE_Disasm(DisassemblyInfo info) - { - info.Mnemonic = "rte"; - info.Args = ""; - } - - void TST() - { - int size = (op >> 6) & 3; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - - int value; - switch (size) - { - case 0: value = ReadValueB(mode, reg); PendingCycles -= 4 + EACyclesBW[mode, reg]; N = (value & 0x80) !=0; break; - case 1: value = ReadValueW(mode, reg); PendingCycles -= 4 + EACyclesBW[mode, reg]; N = (value & 0x8000) !=0; break; - default: value = ReadValueL(mode, reg); PendingCycles -= 4 + EACyclesL[mode, reg]; N = (value & 0x80000000) !=0; break; - } - V = false; - C = false; - Z = (value == 0); - } - - void TST_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int size = (op >> 6) & 3; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - - switch (size) - { - case 0: info.Mnemonic = "tst.b"; info.Args = DisassembleValue(mode, reg, 1, ref pc); break; - case 1: info.Mnemonic = "tst.w"; info.Args = DisassembleValue(mode, reg, 2, ref pc); break; - case 2: info.Mnemonic = "tst.l"; info.Args = DisassembleValue(mode, reg, 4, ref pc); break; - } - info.Length = pc - info.PC; - } - - void BTSTi() - { - int bit = ReadWord(PC); PC += 2; - int mode = (op >> 3) & 7; - int reg = op & 7; - - if (mode == 0) - { - bit &= 31; - int mask = 1 << bit; - Z = (D[reg].s32 & mask) == 0; - PendingCycles -= 10; - } else { - bit &= 7; - int mask = 1 << bit; - Z = (ReadValueB(mode, reg) & mask) == 0; - PendingCycles -= 8 + EACyclesBW[mode, reg]; - } - } - - void BTSTi_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int bit = ReadWord(pc); pc += 2; - int mode = (op >> 3) & 7; - int reg = op & 7; - - info.Mnemonic = "btst"; - info.Args = String.Format("${0:X}, {1}", bit, DisassembleValue(mode, reg, 1, ref pc)); - info.Length = pc - info.PC; - } - - void BTSTr() - { - 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]; - } - } - - void BTSTr_Disasm(DisassemblyInfo info) - { - 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; - } - - void BCHGi() - { - int bit = ReadWord(PC); PC += 2; - int mode = (op >> 3) & 7; - int reg = op & 7; - - if (mode == 0) - { - bit &= 31; - int mask = 1 << bit; - Z = (D[reg].s32 & mask) == 0; - D[reg].s32 ^= mask; - PendingCycles -= 10; - } - else - { - bit &= 7; - int mask = 1 << bit; - sbyte value = PeekValueB(mode, reg); - Z = (value & mask) == 0; - value ^= (sbyte) mask; - WriteValueB(mode, reg, value); - PendingCycles -= 8 + EACyclesBW[mode, reg]; - } - } - - void BCHGi_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int bit = ReadWord(pc); pc += 2; - int mode = (op >> 3) & 7; - int reg = op & 7; - - info.Mnemonic = "bchg"; - info.Args = String.Format("${0:X}, {1}", bit, DisassembleValue(mode, reg, 1, ref pc)); - info.Length = pc - info.PC; - } - - void BCHGr() - { - 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; - D[reg].s32 ^= mask; - PendingCycles -= 6; - } - else - { - bit &= 7; - int mask = 1 << bit; - sbyte value = PeekValueB(mode, reg); - Z = (value & mask) == 0; - value ^= (sbyte) mask; - WriteValueB(mode, reg, value); - PendingCycles -= 4 + EACyclesBW[mode, reg]; - } - } - - void BCHGr_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int dReg = (op >> 9) & 7; - int mode = (op >> 3) & 7; - int reg = op & 7; - - info.Mnemonic = "bchg"; - info.Args = String.Format("D{0}, {1}", dReg, DisassembleValue(mode, reg, 1, ref pc)); - info.Length = pc - info.PC; - } - - void BCLRi() - { - int bit = ReadWord(PC); PC += 2; - int mode = (op >> 3) & 7; - int reg = op & 7; - - if (mode == 0) - { - bit &= 31; - int mask = 1 << bit; - Z = (D[reg].s32 & mask) == 0; - D[reg].s32 &= ~mask; - PendingCycles -= 10; - } - else - { - bit &= 7; - int mask = 1 << bit; - sbyte value = PeekValueB(mode, reg); - Z = (value & mask) == 0; - value &= (sbyte) ~mask; - WriteValueB(mode, reg, value); - PendingCycles -= 8 + EACyclesBW[mode, reg]; - } - } - - void BCLRi_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int bit = ReadWord(pc); pc += 2; - int mode = (op >> 3) & 7; - int reg = op & 7; - - info.Mnemonic = "bclr"; - info.Args = String.Format("${0:X}, {1}", bit, DisassembleValue(mode, reg, 1, ref pc)); - info.Length = pc - info.PC; - } - - void BCLRr() - { - 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; - D[reg].s32 &= ~mask; - PendingCycles -= 6; - } - else - { - bit &= 7; - int mask = 1 << bit; - sbyte value = PeekValueB(mode, reg); - Z = (value & mask) == 0; - value &= (sbyte) ~mask; - WriteValueB(mode, reg, value); - PendingCycles -= 4 + EACyclesBW[mode, reg]; - } - } - - void BCLRr_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int dReg = (op >> 9) & 7; - int mode = (op >> 3) & 7; - int reg = op & 7; - - info.Mnemonic = "bclr"; - info.Args = String.Format("D{0}, {1}", dReg, DisassembleValue(mode, reg, 1, ref pc)); - info.Length = pc - info.PC; - } - - void BSETi() - { - int bit = ReadWord(PC); PC += 2; - int mode = (op >> 3) & 7; - int reg = op & 7; - - if (mode == 0) - { - bit &= 31; - int mask = 1 << bit; - Z = (D[reg].s32 & mask) == 0; - D[reg].s32 |= mask; - PendingCycles -= 10; - } - else - { - bit &= 7; - int mask = 1 << bit; - sbyte value = PeekValueB(mode, reg); - Z = (value & mask) == 0; - value |= (sbyte) mask; - WriteValueB(mode, reg, value); - PendingCycles -= 8 + EACyclesBW[mode, reg]; - } - } - - void BSETi_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int bit = ReadWord(pc); pc += 2; - int mode = (op >> 3) & 7; - int reg = op & 7; - - info.Mnemonic = "bset"; - info.Args = String.Format("${0:X}, {1}", bit, DisassembleValue(mode, reg, 1, ref pc)); - info.Length = pc - info.PC; - } - - void BSETr() - { - 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; - D[reg].s32 |= mask; - PendingCycles -= 6; - } - else - { - bit &= 7; - int mask = 1 << bit; - sbyte value = PeekValueB(mode, reg); - Z = (value & mask) == 0; - value |= (sbyte) mask; - WriteValueB(mode, reg, value); - PendingCycles -= 4 + EACyclesBW[mode, reg]; - } - } - - void BSETr_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int dReg = (op >> 9) & 7; - int mode = (op >> 3) & 7; - int reg = op & 7; - - info.Mnemonic = "bset"; - info.Args = String.Format("D{0}, {1}", dReg, DisassembleValue(mode, reg, 1, ref pc)); - info.Length = pc - info.PC; - } - - void JMP() - { - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - PC = ReadAddress(mode, reg); - - switch (mode) - { - case 2: PendingCycles -= 8; break; - case 5: PendingCycles -= 10; break; - case 6: PendingCycles -= 14; break; - case 7: - switch (reg) - { - case 0: PendingCycles -= 10; break; - case 1: PendingCycles -= 12; break; - case 2: PendingCycles -= 10; break; - case 3: PendingCycles -= 14; break; - } - break; - } - } - - void JMP_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - info.Mnemonic = "jmp"; - info.Args = DisassembleValue(mode, reg, 1, ref pc); - info.Length = pc - info.PC; - } - - void JSR() - { - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - int addr = ReadAddress(mode, reg); - - A[7].s32 -= 4; - WriteLong(A[7].s32, PC); - PC = addr; - - switch (mode) - { - case 2: PendingCycles -= 16; break; - case 5: PendingCycles -= 18; break; - case 6: PendingCycles -= 22; break; - case 7: - switch (reg) - { - case 0: PendingCycles -= 18; break; - case 1: PendingCycles -= 20; break; - case 2: PendingCycles -= 18; break; - case 3: PendingCycles -= 22; break; - } - break; - } - } - - void JSR_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - info.Mnemonic = "jsr"; - info.Args = DisassembleAddress(mode, reg, ref pc); - info.Length = pc - info.PC; - } - - void LINK() - { - int reg = op & 7; - A[7].s32 -= 4; - short offset = ReadWord(PC); PC += 2; - WriteLong(A[7].s32, A[reg].s32); - A[reg].s32 = A[7].s32; - A[7].s32 += offset; - PendingCycles -= 16; - } - - void LINK_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int reg = op & 7; - info.Mnemonic = "link"; - info.Args = "A"+reg+", "+DisassembleImmediate(2, ref pc); // TODO need a DisassembleSigned or something - info.Length = pc - info.PC; - } - - void UNLK() - { - int reg = op & 7; - A[7].s32 = A[reg].s32; - A[reg].s32 = ReadLong(A[7].s32); - A[7].s32 += 4; - PendingCycles -= 12; - } - - void UNLK_Disasm(DisassemblyInfo info) - { - int reg = op & 7; - info.Mnemonic = "unlk"; - info.Args = "A" + reg; - info.Length = 2; - } - - void NOP() - { - PendingCycles -= 4; - } - - 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; - } - } + partial class MC68000 + { + bool TestCondition(int condition) + { + switch (condition) + { + case 0x00: return true; // True + case 0x01: return false; // False + case 0x02: return !C && !Z; // High (Unsigned) + case 0x03: return C || Z; // Less or Same (Unsigned) + case 0x04: return !C; // Carry Clear (High or Same) + case 0x05: return C; // Carry Set (Lower) + case 0x06: return !Z; // Not Equal + case 0x07: return Z; // Equal + case 0x08: return !V; // Overflow Clear + case 0x09: return V; // Overflow Set + case 0x0A: return !N; // Plus (Positive) + case 0x0B: return N; // Minus (Negative) + case 0x0C: return N && V || !N && !V; // Greater or Equal + case 0x0D: return N && !V || !N && V; // Less Than + case 0x0E: return N && V && !Z || !N && !V && !Z; // Greater Than + case 0x0F: return Z || N && !V || !N && V; // Less or Equal + default: + throw new Exception("Invalid condition " + condition); + } + } + + string DisassembleCondition(int condition) + { + switch (condition) + { + case 0x00: return "t"; // True + case 0x01: return "f"; // False + case 0x02: return "hi"; // High (Unsigned) + case 0x03: return "ls"; // Less or Same (Unsigned) + case 0x04: return "cc"; // Carry Clear (High or Same) + case 0x05: return "cs"; // Carry Set (Lower) + case 0x06: return "ne"; // Not Equal + case 0x07: return "eq"; // Equal + case 0x08: return "vc"; // Overflow Clear + case 0x09: return "vs"; // Overflow Set + case 0x0A: return "pl"; // Plus (Positive) + case 0x0B: return "mi"; // Minus (Negative) + case 0x0C: return "ge"; // Greater or Equal + case 0x0D: return "lt"; // Less Than + case 0x0E: return "gt"; // Greater Than + case 0x0F: return "le"; // Less or Equal + default: return "??"; // Invalid condition + } + } + + void Bcc() // Branch on condition + { + sbyte displacement8 = (sbyte)op; + int cond = (op >> 8) & 0x0F; + + if (TestCondition(cond) == true) + { + if (displacement8 != 0) + { + // use opcode-embedded displacement + PC += displacement8; + PendingCycles -= 10; + } + else + { + // use extension word displacement + PC += ReadWord(PC); + PendingCycles -= 10; + } + } + else + { // false + if (displacement8 != 0) + PendingCycles -= 8; + else + { + PC += 2; + PendingCycles -= 12; + } + } + } + + void Bcc_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + sbyte displacement8 = (sbyte)op; + int cond = (op >> 8) & 0x0F; + + info.Mnemonic = "b" + DisassembleCondition(cond); + if (displacement8 != 0) + { + info.Args = string.Format("${0:X}", pc + displacement8); + } + else + { + info.Args = string.Format("${0:X}", pc + ReadWord(pc)); + pc += 2; + } + info.Length = pc - info.PC; + } + + void BRA() + { + sbyte displacement8 = (sbyte)op; + + if (displacement8 != 0) + PC += displacement8; + else + PC += ReadWord(PC); + PendingCycles -= 10; + } + + void BRA_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + info.Mnemonic = "bra"; + + sbyte displacement8 = (sbyte)op; + if (displacement8 != 0) + info.Args = String.Format("${0:X}", pc + displacement8); + else + { + info.Args = String.Format("${0:X}", pc + ReadWord(pc)); + pc += 2; + } + info.Length = pc - info.PC; + } + + void BSR() + { + sbyte displacement8 = (sbyte)op; + + A[7].s32 -= 4; + if (displacement8 != 0) + { + // use embedded displacement + WriteLong(A[7].s32, PC); + PC += displacement8; + } + else + { + // use extension word displacement + WriteLong(A[7].s32, PC + 2); + PC += ReadWord(PC); + } + PendingCycles -= 18; + } + + void BSR_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + info.Mnemonic = "bsr"; + + sbyte displacement8 = (sbyte)op; + if (displacement8 != 0) + info.Args = String.Format("${0:X}", pc + displacement8); + else + { + info.Args = String.Format("${0:X}", pc + ReadWord(pc)); + pc += 2; + } + info.Length = pc - info.PC; + } + + void DBcc() + { + if (TestCondition((op >> 8) & 0x0F) == true) + { + PC += 2; // condition met, break out of loop + PendingCycles -= 12; + } + else + { + int reg = op & 7; + D[reg].u16--; + + if (D[reg].u16 == 0xFFFF) + { + PC += 2; // counter underflowed, break out of loop + PendingCycles -= 14; + } + else + { + PC += ReadWord(PC); // condition false and counter not exhausted, so branch. + PendingCycles -= 10; + } + } + } + + void DBcc_Disasm(DisassemblyInfo info) + { + int cond = (op >> 8) & 0x0F; + if (cond == 1) + info.Mnemonic = "dbra"; + else + info.Mnemonic = "db" + DisassembleCondition(cond); + + int pc = info.PC + 2; + info.Args = String.Format("D{0}, ${1:X}", op & 7, pc + ReadWord(pc)); + info.Length = 4; + } + + void RTS() + { + PC = ReadLong(A[7].s32); + A[7].s32 += 4; + PendingCycles -= 16; + } + + void RTS_Disasm(DisassemblyInfo info) + { + info.Mnemonic = "rts"; + info.Args = ""; + } + + void RTR() + { + ushort sr = (ushort)ReadWord(A[7].s32); + A[7].s32 += 2; + C = (sr & 0x0001) != 0; + V = (sr & 0x0002) != 0; + Z = (sr & 0x0004) != 0; + N = (sr & 0x0008) != 0; + X = (sr & 0x0010) != 0; + + PC = ReadLong(A[7].s32); + A[7].s32 += 4; + PendingCycles -= 20; + } + + void RTR_Disasm(DisassemblyInfo info) + { + info.Mnemonic = "rtr"; + info.Args = ""; + } + + void RTE() + { + short newSR = ReadWord(A[7].s32); + A[7].s32 += 2; + PC = ReadLong(A[7].s32); + A[7].s32 += 4; + SR = newSR; + PendingCycles -= 20; + } + + void RTE_Disasm(DisassemblyInfo info) + { + info.Mnemonic = "rte"; + info.Args = ""; + } + + void TST() + { + int size = (op >> 6) & 3; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + int value; + switch (size) + { + case 0: value = ReadValueB(mode, reg); PendingCycles -= 4 + EACyclesBW[mode, reg]; N = (value & 0x80) != 0; break; + case 1: value = ReadValueW(mode, reg); PendingCycles -= 4 + EACyclesBW[mode, reg]; N = (value & 0x8000) != 0; break; + default: value = ReadValueL(mode, reg); PendingCycles -= 4 + EACyclesL[mode, reg]; N = (value & 0x80000000) != 0; break; + } + V = false; + C = false; + Z = (value == 0); + } + + void TST_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int size = (op >> 6) & 3; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + + switch (size) + { + case 0: info.Mnemonic = "tst.b"; info.Args = DisassembleValue(mode, reg, 1, ref pc); break; + case 1: info.Mnemonic = "tst.w"; info.Args = DisassembleValue(mode, reg, 2, ref pc); break; + case 2: info.Mnemonic = "tst.l"; info.Args = DisassembleValue(mode, reg, 4, ref pc); break; + } + info.Length = pc - info.PC; + } + + void BTSTi() + { + int bit = ReadWord(PC); PC += 2; + int mode = (op >> 3) & 7; + int reg = op & 7; + + if (mode == 0) + { + bit &= 31; + int mask = 1 << bit; + Z = (D[reg].s32 & mask) == 0; + PendingCycles -= 10; + } + else + { + bit &= 7; + int mask = 1 << bit; + Z = (ReadValueB(mode, reg) & mask) == 0; + PendingCycles -= 8 + EACyclesBW[mode, reg]; + } + } + + void BTSTi_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int bit = ReadWord(pc); pc += 2; + int mode = (op >> 3) & 7; + int reg = op & 7; + + info.Mnemonic = "btst"; + info.Args = String.Format("${0:X}, {1}", bit, DisassembleValue(mode, reg, 1, ref pc)); + info.Length = pc - info.PC; + } + + void BTSTr() + { + 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]; + } + } + + void BTSTr_Disasm(DisassemblyInfo info) + { + 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; + } + + void BCHGi() + { + int bit = ReadWord(PC); PC += 2; + int mode = (op >> 3) & 7; + int reg = op & 7; + + if (mode == 0) + { + bit &= 31; + int mask = 1 << bit; + Z = (D[reg].s32 & mask) == 0; + D[reg].s32 ^= mask; + PendingCycles -= 10; + } + else + { + bit &= 7; + int mask = 1 << bit; + sbyte value = PeekValueB(mode, reg); + Z = (value & mask) == 0; + value ^= (sbyte)mask; + WriteValueB(mode, reg, value); + PendingCycles -= 8 + EACyclesBW[mode, reg]; + } + } + + void BCHGi_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int bit = ReadWord(pc); pc += 2; + int mode = (op >> 3) & 7; + int reg = op & 7; + + info.Mnemonic = "bchg"; + info.Args = String.Format("${0:X}, {1}", bit, DisassembleValue(mode, reg, 1, ref pc)); + info.Length = pc - info.PC; + } + + void BCHGr() + { + 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; + D[reg].s32 ^= mask; + PendingCycles -= 6; + } + else + { + bit &= 7; + int mask = 1 << bit; + sbyte value = PeekValueB(mode, reg); + Z = (value & mask) == 0; + value ^= (sbyte)mask; + WriteValueB(mode, reg, value); + PendingCycles -= 4 + EACyclesBW[mode, reg]; + } + } + + void BCHGr_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int dReg = (op >> 9) & 7; + int mode = (op >> 3) & 7; + int reg = op & 7; + + info.Mnemonic = "bchg"; + info.Args = String.Format("D{0}, {1}", dReg, DisassembleValue(mode, reg, 1, ref pc)); + info.Length = pc - info.PC; + } + + void BCLRi() + { + int bit = ReadWord(PC); PC += 2; + int mode = (op >> 3) & 7; + int reg = op & 7; + + if (mode == 0) + { + bit &= 31; + int mask = 1 << bit; + Z = (D[reg].s32 & mask) == 0; + D[reg].s32 &= ~mask; + PendingCycles -= 10; + } + else + { + bit &= 7; + int mask = 1 << bit; + sbyte value = PeekValueB(mode, reg); + Z = (value & mask) == 0; + value &= (sbyte)~mask; + WriteValueB(mode, reg, value); + PendingCycles -= 8 + EACyclesBW[mode, reg]; + } + } + + void BCLRi_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int bit = ReadWord(pc); pc += 2; + int mode = (op >> 3) & 7; + int reg = op & 7; + + info.Mnemonic = "bclr"; + info.Args = String.Format("${0:X}, {1}", bit, DisassembleValue(mode, reg, 1, ref pc)); + info.Length = pc - info.PC; + } + + void BCLRr() + { + 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; + D[reg].s32 &= ~mask; + PendingCycles -= 6; + } + else + { + bit &= 7; + int mask = 1 << bit; + sbyte value = PeekValueB(mode, reg); + Z = (value & mask) == 0; + value &= (sbyte)~mask; + WriteValueB(mode, reg, value); + PendingCycles -= 4 + EACyclesBW[mode, reg]; + } + } + + void BCLRr_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int dReg = (op >> 9) & 7; + int mode = (op >> 3) & 7; + int reg = op & 7; + + info.Mnemonic = "bclr"; + info.Args = String.Format("D{0}, {1}", dReg, DisassembleValue(mode, reg, 1, ref pc)); + info.Length = pc - info.PC; + } + + void BSETi() + { + int bit = ReadWord(PC); PC += 2; + int mode = (op >> 3) & 7; + int reg = op & 7; + + if (mode == 0) + { + bit &= 31; + int mask = 1 << bit; + Z = (D[reg].s32 & mask) == 0; + D[reg].s32 |= mask; + PendingCycles -= 10; + } + else + { + bit &= 7; + int mask = 1 << bit; + sbyte value = PeekValueB(mode, reg); + Z = (value & mask) == 0; + value |= (sbyte)mask; + WriteValueB(mode, reg, value); + PendingCycles -= 8 + EACyclesBW[mode, reg]; + } + } + + void BSETi_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int bit = ReadWord(pc); pc += 2; + int mode = (op >> 3) & 7; + int reg = op & 7; + + info.Mnemonic = "bset"; + info.Args = String.Format("${0:X}, {1}", bit, DisassembleValue(mode, reg, 1, ref pc)); + info.Length = pc - info.PC; + } + + void BSETr() + { + 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; + D[reg].s32 |= mask; + PendingCycles -= 6; + } + else + { + bit &= 7; + int mask = 1 << bit; + sbyte value = PeekValueB(mode, reg); + Z = (value & mask) == 0; + value |= (sbyte)mask; + WriteValueB(mode, reg, value); + PendingCycles -= 4 + EACyclesBW[mode, reg]; + } + } + + void BSETr_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int dReg = (op >> 9) & 7; + int mode = (op >> 3) & 7; + int reg = op & 7; + + info.Mnemonic = "bset"; + info.Args = String.Format("D{0}, {1}", dReg, DisassembleValue(mode, reg, 1, ref pc)); + info.Length = pc - info.PC; + } + + void JMP() + { + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + PC = ReadAddress(mode, reg); + + switch (mode) + { + case 2: PendingCycles -= 8; break; + case 5: PendingCycles -= 10; break; + case 6: PendingCycles -= 14; break; + case 7: + switch (reg) + { + case 0: PendingCycles -= 10; break; + case 1: PendingCycles -= 12; break; + case 2: PendingCycles -= 10; break; + case 3: PendingCycles -= 14; break; + } + break; + } + } + + void JMP_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + info.Mnemonic = "jmp"; + info.Args = DisassembleValue(mode, reg, 1, ref pc); + info.Length = pc - info.PC; + } + + void JSR() + { + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + int addr = ReadAddress(mode, reg); + + A[7].s32 -= 4; + WriteLong(A[7].s32, PC); + PC = addr; + + switch (mode) + { + case 2: PendingCycles -= 16; break; + case 5: PendingCycles -= 18; break; + case 6: PendingCycles -= 22; break; + case 7: + switch (reg) + { + case 0: PendingCycles -= 18; break; + case 1: PendingCycles -= 20; break; + case 2: PendingCycles -= 18; break; + case 3: PendingCycles -= 22; break; + } + break; + } + } + + void JSR_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + info.Mnemonic = "jsr"; + info.Args = DisassembleAddress(mode, reg, ref pc); + info.Length = pc - info.PC; + } + + void LINK() + { + int reg = op & 7; + A[7].s32 -= 4; + short offset = ReadWord(PC); PC += 2; + WriteLong(A[7].s32, A[reg].s32); + A[reg].s32 = A[7].s32; + A[7].s32 += offset; + PendingCycles -= 16; + } + + void LINK_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int reg = op & 7; + info.Mnemonic = "link"; + info.Args = "A" + reg + ", " + DisassembleImmediate(2, ref pc); // TODO need a DisassembleSigned or something + info.Length = pc - info.PC; + } + + void UNLK() + { + int reg = op & 7; + A[7].s32 = A[reg].s32; + A[reg].s32 = ReadLong(A[7].s32); + A[7].s32 += 4; + PendingCycles -= 12; + } + + void UNLK_Disasm(DisassemblyInfo info) + { + int reg = op & 7; + info.Mnemonic = "unlk"; + info.Args = "A" + reg; + info.Length = 2; + } + + void NOP() + { + PendingCycles -= 4; + } + + 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 8efb25198f..4e59b6c6a6 100644 --- a/BizHawk.Emulation/CPUs/68000/Instructions/Supervisor.cs +++ b/BizHawk.Emulation/CPUs/68000/Instructions/Supervisor.cs @@ -1,163 +1,163 @@ using System; -namespace BizHawk.Emulation.CPUs.M68000 +namespace BizHawk.Emulation.Common.Components.M68000 { - partial class MC68000 - { - void MOVEtSR() - { - if (S == false) - throw new Exception("Write to SR when not in supervisor mode. supposed to trap or something..."); + partial class MC68000 + { + void MOVEtSR() + { + if (S == false) + throw new Exception("Write to SR when not in supervisor mode. supposed to trap or something..."); - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - SR = ReadValueW(mode, reg); - PendingCycles -= 12 + EACyclesBW[mode, reg]; - } + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + SR = ReadValueW(mode, reg); + PendingCycles -= 12 + EACyclesBW[mode, reg]; + } - void MOVEtSR_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - info.Mnemonic = "move"; - info.Args = DisassembleValue(mode, reg, 2, ref pc) + ", SR"; - info.Length = pc - info.PC; - } + void MOVEtSR_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + info.Mnemonic = "move"; + info.Args = DisassembleValue(mode, reg, 2, ref pc) + ", SR"; + info.Length = pc - info.PC; + } - void MOVEfSR() - { - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - WriteValueW(mode, reg, (short) SR); - PendingCycles -= (mode == 0) ? 6 : 8 + EACyclesBW[mode, reg]; - } + void MOVEfSR() + { + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + WriteValueW(mode, reg, (short)SR); + PendingCycles -= (mode == 0) ? 6 : 8 + EACyclesBW[mode, reg]; + } - void MOVEfSR_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - info.Mnemonic = "move"; - info.Args = "SR, " + DisassembleValue(mode, reg, 2, ref pc); - info.Length = pc - info.PC; - } + void MOVEfSR_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + info.Mnemonic = "move"; + info.Args = "SR, " + DisassembleValue(mode, reg, 2, ref pc); + info.Length = pc - info.PC; + } - void MOVEUSP() - { - if (S == false) - throw new Exception("MOVE to USP when not supervisor. needs to trap"); + void MOVEUSP() + { + if (S == false) + throw new Exception("MOVE to USP when not supervisor. needs to trap"); - int dir = (op >> 3) & 1; - int reg = op & 7; + int dir = (op >> 3) & 1; + int reg = op & 7; - if (dir == 0) usp = A[reg].s32; - else A[reg].s32 = usp; + if (dir == 0) usp = A[reg].s32; + else A[reg].s32 = usp; - PendingCycles -= 4; - } + PendingCycles -= 4; + } - void MOVEUSP_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int dir = (op >> 3) & 1; - int reg = op & 7; - info.Mnemonic = "move"; - info.Args = (dir == 0) ? ("A" + reg + ", USP") : ("USP, A" + reg); - info.Length = pc - info.PC; - } + void MOVEUSP_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int dir = (op >> 3) & 1; + int reg = op & 7; + info.Mnemonic = "move"; + info.Args = (dir == 0) ? ("A" + reg + ", USP") : ("USP, A" + reg); + info.Length = pc - info.PC; + } - void ANDI_SR() - { - if (S == false) - throw new Exception("trap!"); - SR &= ReadWord(PC); PC += 2; - PendingCycles -= 20; - } + void ANDI_SR() + { + if (S == false) + throw new Exception("trap!"); + SR &= ReadWord(PC); PC += 2; + PendingCycles -= 20; + } - void ANDI_SR_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - info.Mnemonic = "andi"; - info.Args = DisassembleImmediate(2, ref pc) + ", SR"; - info.Length = pc - info.PC; - } + void ANDI_SR_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + info.Mnemonic = "andi"; + info.Args = DisassembleImmediate(2, ref pc) + ", SR"; + info.Length = pc - info.PC; + } - void EORI_SR() - { - if (S == false) - throw new Exception("trap!"); - SR ^= ReadWord(PC); PC += 2; - PendingCycles -= 20; - } + void EORI_SR() + { + if (S == false) + throw new Exception("trap!"); + SR ^= ReadWord(PC); PC += 2; + PendingCycles -= 20; + } - void EORI_SR_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - info.Mnemonic = "eori"; - info.Args = DisassembleImmediate(2, ref pc) + ", SR"; - info.Length = pc - info.PC; - } + void EORI_SR_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + info.Mnemonic = "eori"; + info.Args = DisassembleImmediate(2, ref pc) + ", SR"; + info.Length = pc - info.PC; + } - void ORI_SR() - { - if (S == false) - throw new Exception("trap!"); - SR |= ReadWord(PC); PC += 2; - PendingCycles -= 20; - } + void ORI_SR() + { + if (S == false) + throw new Exception("trap!"); + SR |= ReadWord(PC); PC += 2; + PendingCycles -= 20; + } - void ORI_SR_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - info.Mnemonic = "ori"; - info.Args = DisassembleImmediate(2, ref pc) + ", SR"; - info.Length = pc - info.PC; - } + void ORI_SR_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + info.Mnemonic = "ori"; + info.Args = DisassembleImmediate(2, ref pc) + ", SR"; + info.Length = pc - info.PC; + } - void MOVECCR() - { - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; + void MOVECCR() + { + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; - ushort sr = (ushort) (SR & 0xFF00); - sr |= (byte)ReadValueB(mode, reg); - SR = (short)sr; - PendingCycles -= 12 + EACyclesBW[mode, reg]; - } + ushort sr = (ushort)(SR & 0xFF00); + sr |= (byte)ReadValueB(mode, reg); + SR = (short)sr; + PendingCycles -= 12 + EACyclesBW[mode, reg]; + } - void MOVECCR_Disasm(DisassemblyInfo info) - { - int pc = info.PC + 2; - int mode = (op >> 3) & 7; - int reg = (op >> 0) & 7; - info.Mnemonic = "move"; - info.Args = DisassembleValue(mode, reg, 2, ref pc) + ", CCR"; - info.Length = pc - info.PC; - } + void MOVECCR_Disasm(DisassemblyInfo info) + { + int pc = info.PC + 2; + int mode = (op >> 3) & 7; + int reg = (op >> 0) & 7; + info.Mnemonic = "move"; + info.Args = DisassembleValue(mode, reg, 2, ref pc) + ", CCR"; + info.Length = pc - info.PC; + } - void TRAP() - { - int vector = 32 + (op & 0x0F); - TrapVector(vector); - PendingCycles -= 26; - } + void TRAP() + { + int vector = 32 + (op & 0x0F); + TrapVector(vector); + PendingCycles -= 26; + } - void TRAP_Disasm(DisassemblyInfo info) - { - info.Mnemonic = "trap"; - info.Args = string.Format("${0:X}", op & 0xF); - } + void TRAP_Disasm(DisassemblyInfo info) + { + info.Mnemonic = "trap"; + info.Args = string.Format("${0:X}", op & 0xF); + } - void TrapVector(int vector) - { - short sr = (short)SR; // capture current SR. - S = true; // switch to supervisor mode, if not already in it. - A[7].s32 -= 4; // Push PC on stack - WriteLong(A[7].s32, PC); - A[7].s32 -= 2; // Push SR on stack - WriteWord(A[7].s32, sr); - PC = ReadLong(vector * 4); // Jump to vector - } - } + void TrapVector(int vector) + { + short sr = (short)SR; // capture current SR. + S = true; // switch to supervisor mode, if not already in it. + A[7].s32 -= 4; // Push PC on stack + WriteLong(A[7].s32, PC); + A[7].s32 -= 2; // Push SR on stack + WriteWord(A[7].s32, sr); + PC = ReadLong(vector * 4); // Jump to vector + } + } } \ No newline at end of file diff --git a/BizHawk.Emulation/CPUs/68000/MC68000.cs b/BizHawk.Emulation/CPUs/68000/MC68000.cs index 4c6970b8d4..44171c957a 100644 --- a/BizHawk.Emulation/CPUs/68000/MC68000.cs +++ b/BizHawk.Emulation/CPUs/68000/MC68000.cs @@ -3,269 +3,271 @@ using System.Runtime.InteropServices; using System.IO; using System.Globalization; -namespace BizHawk.Emulation.CPUs.M68000 +namespace BizHawk.Emulation.Common.Components.M68000 { - public sealed partial class MC68000 - { - // Machine State - public Register[] D = new Register[8]; - public Register[] A = new Register[8]; - public int PC; + public sealed partial class MC68000 + { + // Machine State + public Register[] D = new Register[8]; + public Register[] A = new Register[8]; + public int PC; - public int TotalExecutedCycles; - public int PendingCycles; + public int TotalExecutedCycles; + public int PendingCycles; - // Status Registers - int InterruptMaskLevel; - 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 - - /// Supervisor/User mode - public bool S - { - get { return s; } - set - { - if (value == s) return; - if (value == true) // entering supervisor mode - { - Console.WriteLine("&^&^&^&^& ENTER SUPERVISOR MODE"); - usp = A[7].s32; - A[7].s32 = ssp; - s = true; - } else { // exiting supervisor mode - Console.WriteLine("&^&^&^&^& LEAVE SUPERVISOR MODE"); - ssp = A[7].s32; - A[7].s32 = usp; - s = false; - } - } - } + // Status Registers + int InterruptMaskLevel; + bool s, m; + int usp, ssp; - /// Extend Flag - public bool X; - /// Negative Flag - public bool N; - /// Zero Flag - public bool Z; - /// Overflow Flag - public bool V; - /// Carry Flag - public bool C; + /// Machine/Interrupt mode + public bool M { get { return m; } set { m = value; } } // TODO probably have some switch logic maybe - /// Status Register - public short SR - { - get - { - short value = 0; - if (C) value |= 0x0001; - if (V) value |= 0x0002; - if (Z) value |= 0x0004; - if (N) value |= 0x0008; - if (X) value |= 0x0010; - if (M) value |= 0x1000; - if (S) value |= 0x2000; - value |= (short) ((InterruptMaskLevel & 7) << 8); - return value; - } - set - { - C = (value & 0x0001) != 0; - V = (value & 0x0002) != 0; - Z = (value & 0x0004) != 0; - N = (value & 0x0008) != 0; - X = (value & 0x0010) != 0; - M = (value & 0x1000) != 0; - S = (value & 0x2000) != 0; - InterruptMaskLevel = (value >> 8) & 7; - } - } + /// Supervisor/User mode + public bool S + { + get { return s; } + set + { + if (value == s) return; + if (value == true) // entering supervisor mode + { + Console.WriteLine("&^&^&^&^& ENTER SUPERVISOR MODE"); + usp = A[7].s32; + A[7].s32 = ssp; + s = true; + } + else + { // exiting supervisor mode + Console.WriteLine("&^&^&^&^& LEAVE SUPERVISOR MODE"); + ssp = A[7].s32; + A[7].s32 = usp; + s = false; + } + } + } - public int Interrupt { get; set; } + /// Extend Flag + public bool X; + /// Negative Flag + public bool N; + /// Zero Flag + public bool Z; + /// Overflow Flag + public bool V; + /// Carry Flag + public bool C; - // Memory Access - public Func ReadByte; - public Func ReadWord; - public Func ReadLong; + /// Status Register + public short SR + { + get + { + short value = 0; + if (C) value |= 0x0001; + if (V) value |= 0x0002; + if (Z) value |= 0x0004; + if (N) value |= 0x0008; + if (X) value |= 0x0010; + if (M) value |= 0x1000; + if (S) value |= 0x2000; + value |= (short)((InterruptMaskLevel & 7) << 8); + return value; + } + set + { + C = (value & 0x0001) != 0; + V = (value & 0x0002) != 0; + Z = (value & 0x0004) != 0; + N = (value & 0x0008) != 0; + X = (value & 0x0010) != 0; + M = (value & 0x1000) != 0; + S = (value & 0x2000) != 0; + InterruptMaskLevel = (value >> 8) & 7; + } + } - public Action WriteByte; - public Action WriteWord; - public Action WriteLong; + public int Interrupt { get; set; } - public Action IrqCallback; + // Memory Access + public Func ReadByte; + public Func ReadWord; + public Func ReadLong; - // Initialization + public Action WriteByte; + public Action WriteWord; + public Action WriteLong; - public MC68000() - { - BuildOpcodeTable(); - } + public Action IrqCallback; - public void Reset() - { - S = true; - InterruptMaskLevel = 7; - A[7].s32 = ReadLong(0); - PC = ReadLong(4); - } + // Initialization - public Action[] Opcodes = new Action[0x10000]; - public ushort op; + public MC68000() + { + BuildOpcodeTable(); + } - public void Step() - { - Console.WriteLine(Disassemble(PC)); + public void Reset() + { + S = true; + InterruptMaskLevel = 7; + A[7].s32 = ReadLong(0); + PC = ReadLong(4); + } - op = (ushort) ReadWord(PC); - PC += 2; - Opcodes[op](); - } + public Action[] Opcodes = new Action[0x10000]; + public ushort op; - public void ExecuteCycles(int cycles) - { - PendingCycles += cycles; - while (PendingCycles > 0) - { - if (Interrupt > 0 && (Interrupt > InterruptMaskLevel || Interrupt > 7)) - { - // TODO: Entering interrupt is not free. how many cycles does it take? - //Log.Error("CPU","****** ENTER INTERRUPT {0} *******", Interrupt); - short sr = (short) SR; // capture current SR. - S = true; // switch to supervisor mode, if not already in it. - A[7].s32 -= 4; // Push PC on stack - WriteLong(A[7].s32, PC); - A[7].s32 -= 2; // Push SR on stack - WriteWord(A[7].s32, sr); - PC = ReadLong((24 + Interrupt) * 4); // Jump to interrupt vector - InterruptMaskLevel = Interrupt; // Set interrupt mask to level currently being entered - Interrupt = 0; // "ack" interrupt. Note: this is wrong. - IrqCallback(InterruptMaskLevel); // Invoke the "Interrupt accepted" callback handler - } + public void Step() + { + Console.WriteLine(Disassemble(PC)); - int prevCycles = PendingCycles; - //Log.Note("CPU", State()); - op = (ushort)ReadWord(PC); - if (Opcodes[op] == null) throw new Exception(string.Format("unhandled opcode at pc={0:X6}",PC)); - PC += 2; - Opcodes[op](); - int delta = prevCycles - PendingCycles; - TotalExecutedCycles += delta; - } - } + op = (ushort)ReadWord(PC); + PC += 2; + Opcodes[op](); + } - public string State() - { - string a = Disassemble(PC).ToString().PadRight(64); - //string a = string.Format("{0:X6}: {1:X4}", PC, ReadWord(PC)).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}", SR, PendingCycles); - return a + b + c + d; - } + public void ExecuteCycles(int cycles) + { + PendingCycles += cycles; + while (PendingCycles > 0) + { + if (Interrupt > 0 && (Interrupt > InterruptMaskLevel || Interrupt > 7)) + { + // TODO: Entering interrupt is not free. how many cycles does it take? + //Log.Error("CPU","****** ENTER INTERRUPT {0} *******", Interrupt); + short sr = (short)SR; // capture current SR. + S = true; // switch to supervisor mode, if not already in it. + A[7].s32 -= 4; // Push PC on stack + WriteLong(A[7].s32, PC); + A[7].s32 -= 2; // Push SR on stack + WriteWord(A[7].s32, sr); + PC = ReadLong((24 + Interrupt) * 4); // Jump to interrupt vector + InterruptMaskLevel = Interrupt; // Set interrupt mask to level currently being entered + Interrupt = 0; // "ack" interrupt. Note: this is wrong. + IrqCallback(InterruptMaskLevel); // Invoke the "Interrupt accepted" callback handler + } - public void SaveStateText(TextWriter writer, string id) - { - writer.WriteLine("[{0}]", id); - writer.WriteLine("D0 {0:X8}", D[0].s32); - writer.WriteLine("D1 {0:X8}", D[1].s32); - writer.WriteLine("D2 {0:X8}", D[2].s32); - writer.WriteLine("D3 {0:X8}", D[3].s32); - writer.WriteLine("D4 {0:X8}", D[4].s32); - writer.WriteLine("D5 {0:X8}", D[5].s32); - writer.WriteLine("D6 {0:X8}", D[6].s32); - writer.WriteLine("D7 {0:X8}", D[7].s32); - writer.WriteLine(); + int prevCycles = PendingCycles; + //Log.Note("CPU", State()); + op = (ushort)ReadWord(PC); + if (Opcodes[op] == null) throw new Exception(string.Format("unhandled opcode at pc={0:X6}", PC)); + PC += 2; + Opcodes[op](); + int delta = prevCycles - PendingCycles; + TotalExecutedCycles += delta; + } + } - writer.WriteLine("A0 {0:X8}", A[0].s32); - writer.WriteLine("A1 {0:X8}", A[1].s32); - writer.WriteLine("A2 {0:X8}", A[2].s32); - writer.WriteLine("A3 {0:X8}", A[3].s32); - writer.WriteLine("A4 {0:X8}", A[4].s32); - writer.WriteLine("A5 {0:X8}", A[5].s32); - writer.WriteLine("A6 {0:X8}", A[6].s32); - writer.WriteLine("A7 {0:X8}", A[7].s32); - writer.WriteLine(); + public string State() + { + string a = Disassemble(PC).ToString().PadRight(64); + //string a = string.Format("{0:X6}: {1:X4}", PC, ReadWord(PC)).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}", SR, PendingCycles); + return a + b + c + d; + } - writer.WriteLine("PC {0:X6}", PC); - writer.WriteLine("InterruptMaskLevel {0}", InterruptMaskLevel); - writer.WriteLine("USP {0:X8}", usp); - writer.WriteLine("SSP {0:X8}", ssp); - writer.WriteLine("S {0}", s); - writer.WriteLine("M {0}", m); - writer.WriteLine(); + public void SaveStateText(TextWriter writer, string id) + { + writer.WriteLine("[{0}]", id); + writer.WriteLine("D0 {0:X8}", D[0].s32); + writer.WriteLine("D1 {0:X8}", D[1].s32); + writer.WriteLine("D2 {0:X8}", D[2].s32); + writer.WriteLine("D3 {0:X8}", D[3].s32); + writer.WriteLine("D4 {0:X8}", D[4].s32); + writer.WriteLine("D5 {0:X8}", D[5].s32); + writer.WriteLine("D6 {0:X8}", D[6].s32); + writer.WriteLine("D7 {0:X8}", D[7].s32); + writer.WriteLine(); - writer.WriteLine("TotalExecutedCycles {0}", TotalExecutedCycles); - writer.WriteLine("PendingCycles {0}", PendingCycles); - - writer.WriteLine("[/{0}]", id); - } + writer.WriteLine("A0 {0:X8}", A[0].s32); + writer.WriteLine("A1 {0:X8}", A[1].s32); + writer.WriteLine("A2 {0:X8}", A[2].s32); + writer.WriteLine("A3 {0:X8}", A[3].s32); + writer.WriteLine("A4 {0:X8}", A[4].s32); + writer.WriteLine("A5 {0:X8}", A[5].s32); + writer.WriteLine("A6 {0:X8}", A[6].s32); + writer.WriteLine("A7 {0:X8}", A[7].s32); + writer.WriteLine(); - public void LoadStateText(TextReader reader, string id) - { - while (true) - { - string[] args = reader.ReadLine().Split(' '); - if (args[0].Trim() == "") continue; - if (args[0] == "[/"+id+"]") break; - else if (args[0] == "D0") D[0].s32 = int.Parse(args[1], NumberStyles.HexNumber); - else if (args[0] == "D1") D[1].s32 = int.Parse(args[1], NumberStyles.HexNumber); - else if (args[0] == "D2") D[2].s32 = int.Parse(args[1], NumberStyles.HexNumber); - else if (args[0] == "D3") D[3].s32 = int.Parse(args[1], NumberStyles.HexNumber); - else if (args[0] == "D4") D[4].s32 = int.Parse(args[1], NumberStyles.HexNumber); - else if (args[0] == "D5") D[5].s32 = int.Parse(args[1], NumberStyles.HexNumber); - else if (args[0] == "D6") D[6].s32 = int.Parse(args[1], NumberStyles.HexNumber); - else if (args[0] == "D7") D[7].s32 = int.Parse(args[1], NumberStyles.HexNumber); + writer.WriteLine("PC {0:X6}", PC); + writer.WriteLine("InterruptMaskLevel {0}", InterruptMaskLevel); + writer.WriteLine("USP {0:X8}", usp); + writer.WriteLine("SSP {0:X8}", ssp); + writer.WriteLine("S {0}", s); + writer.WriteLine("M {0}", m); + writer.WriteLine(); - else if (args[0] == "A0") A[0].s32 = int.Parse(args[1], NumberStyles.HexNumber); - else if (args[0] == "A1") A[1].s32 = int.Parse(args[1], NumberStyles.HexNumber); - else if (args[0] == "A2") A[2].s32 = int.Parse(args[1], NumberStyles.HexNumber); - else if (args[0] == "A3") A[3].s32 = int.Parse(args[1], NumberStyles.HexNumber); - else if (args[0] == "A4") A[4].s32 = int.Parse(args[1], NumberStyles.HexNumber); - else if (args[0] == "A5") A[5].s32 = int.Parse(args[1], NumberStyles.HexNumber); - else if (args[0] == "A6") A[6].s32 = int.Parse(args[1], NumberStyles.HexNumber); - else if (args[0] == "A7") A[7].s32 = int.Parse(args[1], NumberStyles.HexNumber); - - else if (args[0] == "PC") PC = int.Parse(args[1], NumberStyles.HexNumber); - else if (args[0] == "InterruptMaskLevel") InterruptMaskLevel = int.Parse(args[1]); - else if (args[0] == "USP") usp = int.Parse(args[1], NumberStyles.HexNumber); - else if (args[0] == "SSP") ssp = int.Parse(args[1], NumberStyles.HexNumber); - else if (args[0] == "S") s = bool.Parse(args[1]); - else if (args[0] == "M") m = bool.Parse(args[1]); + writer.WriteLine("TotalExecutedCycles {0}", TotalExecutedCycles); + writer.WriteLine("PendingCycles {0}", PendingCycles); - else if (args[0] == "TotalExecutedCycles") TotalExecutedCycles = int.Parse(args[1]); - else if (args[0] == "PendingCycles") PendingCycles = int.Parse(args[1]); + writer.WriteLine("[/{0}]", id); + } - else - Console.WriteLine("Skipping unrecognized identifier " + args[0]); - } - } - } + public void LoadStateText(TextReader reader, string id) + { + while (true) + { + string[] args = reader.ReadLine().Split(' '); + if (args[0].Trim() == "") continue; + if (args[0] == "[/" + id + "]") break; + else if (args[0] == "D0") D[0].s32 = int.Parse(args[1], NumberStyles.HexNumber); + else if (args[0] == "D1") D[1].s32 = int.Parse(args[1], NumberStyles.HexNumber); + else if (args[0] == "D2") D[2].s32 = int.Parse(args[1], NumberStyles.HexNumber); + else if (args[0] == "D3") D[3].s32 = int.Parse(args[1], NumberStyles.HexNumber); + else if (args[0] == "D4") D[4].s32 = int.Parse(args[1], NumberStyles.HexNumber); + else if (args[0] == "D5") D[5].s32 = int.Parse(args[1], NumberStyles.HexNumber); + else if (args[0] == "D6") D[6].s32 = int.Parse(args[1], NumberStyles.HexNumber); + else if (args[0] == "D7") D[7].s32 = int.Parse(args[1], NumberStyles.HexNumber); - [StructLayout(LayoutKind.Explicit)] - public struct Register - { - [FieldOffset(0)] - public uint u32; - [FieldOffset(0)] - public int s32; + else if (args[0] == "A0") A[0].s32 = int.Parse(args[1], NumberStyles.HexNumber); + else if (args[0] == "A1") A[1].s32 = int.Parse(args[1], NumberStyles.HexNumber); + else if (args[0] == "A2") A[2].s32 = int.Parse(args[1], NumberStyles.HexNumber); + else if (args[0] == "A3") A[3].s32 = int.Parse(args[1], NumberStyles.HexNumber); + else if (args[0] == "A4") A[4].s32 = int.Parse(args[1], NumberStyles.HexNumber); + else if (args[0] == "A5") A[5].s32 = int.Parse(args[1], NumberStyles.HexNumber); + else if (args[0] == "A6") A[6].s32 = int.Parse(args[1], NumberStyles.HexNumber); + else if (args[0] == "A7") A[7].s32 = int.Parse(args[1], NumberStyles.HexNumber); - [FieldOffset(0)] - public ushort u16; - [FieldOffset(0)] - public short s16; + else if (args[0] == "PC") PC = int.Parse(args[1], NumberStyles.HexNumber); + else if (args[0] == "InterruptMaskLevel") InterruptMaskLevel = int.Parse(args[1]); + else if (args[0] == "USP") usp = int.Parse(args[1], NumberStyles.HexNumber); + else if (args[0] == "SSP") ssp = int.Parse(args[1], NumberStyles.HexNumber); + else if (args[0] == "S") s = bool.Parse(args[1]); + else if (args[0] == "M") m = bool.Parse(args[1]); - [FieldOffset(0)] - public byte u8; - [FieldOffset(0)] - public sbyte s8; + else if (args[0] == "TotalExecutedCycles") TotalExecutedCycles = int.Parse(args[1]); + else if (args[0] == "PendingCycles") PendingCycles = int.Parse(args[1]); - public override string ToString() - { - return String.Format("{0:X8}", u32); - } - } + else + Console.WriteLine("Skipping unrecognized identifier " + args[0]); + } + } + } + + [StructLayout(LayoutKind.Explicit)] + public struct Register + { + [FieldOffset(0)] + public uint u32; + [FieldOffset(0)] + public int s32; + + [FieldOffset(0)] + public ushort u16; + [FieldOffset(0)] + public short s16; + + [FieldOffset(0)] + public byte u8; + [FieldOffset(0)] + public sbyte s8; + + public override string ToString() + { + return String.Format("{0:X8}", u32); + } + } } diff --git a/BizHawk.Emulation/CPUs/68000/Memory.cs b/BizHawk.Emulation/CPUs/68000/Memory.cs index 6262c96f0e..b065f2c430 100644 --- a/BizHawk.Emulation/CPUs/68000/Memory.cs +++ b/BizHawk.Emulation/CPUs/68000/Memory.cs @@ -1,626 +1,626 @@ using System; -namespace BizHawk.Emulation.CPUs.M68000 +namespace BizHawk.Emulation.Common.Components.M68000 { - partial class MC68000 - { - sbyte ReadValueB(int mode, int reg) - { - sbyte value; - switch (mode) - { - case 0: // Dn - return D[reg].s8; - case 1: // An - return A[reg].s8; - case 2: // (An) - return ReadByte(A[reg].s32); - case 3: // (An)+ - value = ReadByte(A[reg].s32); - A[reg].s32 += reg == 7 ? 2 : 1; - return value; - case 4: // -(An) - A[reg].s32 -= reg == 7 ? 2 : 1; - return ReadByte(A[reg].s32); - case 5: // (d16,An) - value = ReadByte((A[reg].s32 + ReadWord(PC))); PC += 2; - return value; - case 6: // (d8,An,Xn) - return ReadByte(A[reg].s32 + GetIndex()); - case 7: - switch (reg) - { - case 0: // (imm).W - value = ReadByte(ReadWord(PC)); PC += 2; - return value; - case 1: // (imm).L - value = ReadByte(ReadLong(PC)); PC += 4; - return value; - case 2: // (d16,PC) - value = ReadByte(PC + ReadWord(PC)); PC += 2; - return value; - case 3: // (d8,PC,Xn) - int pc = PC; - value = ReadByte((pc + GetIndex())); - return value; - case 4: // immediate - value = (sbyte) ReadWord(PC); PC += 2; - return value; - default: - throw new Exception("Invalid addressing mode!"); - } - } - throw new Exception("Invalid addressing mode!"); - } + partial class MC68000 + { + sbyte ReadValueB(int mode, int reg) + { + sbyte value; + switch (mode) + { + case 0: // Dn + return D[reg].s8; + case 1: // An + return A[reg].s8; + case 2: // (An) + return ReadByte(A[reg].s32); + case 3: // (An)+ + value = ReadByte(A[reg].s32); + A[reg].s32 += reg == 7 ? 2 : 1; + return value; + case 4: // -(An) + A[reg].s32 -= reg == 7 ? 2 : 1; + return ReadByte(A[reg].s32); + case 5: // (d16,An) + value = ReadByte((A[reg].s32 + ReadWord(PC))); PC += 2; + return value; + case 6: // (d8,An,Xn) + return ReadByte(A[reg].s32 + GetIndex()); + case 7: + switch (reg) + { + case 0: // (imm).W + value = ReadByte(ReadWord(PC)); PC += 2; + return value; + case 1: // (imm).L + value = ReadByte(ReadLong(PC)); PC += 4; + return value; + case 2: // (d16,PC) + value = ReadByte(PC + ReadWord(PC)); PC += 2; + return value; + case 3: // (d8,PC,Xn) + int pc = PC; + value = ReadByte((pc + GetIndex())); + return value; + case 4: // immediate + value = (sbyte)ReadWord(PC); PC += 2; + return value; + default: + throw new Exception("Invalid addressing mode!"); + } + } + throw new Exception("Invalid addressing mode!"); + } - short ReadValueW(int mode, int reg) - { - short value; - switch (mode) - { - case 0: // Dn - return D[reg].s16; - case 1: // An - return A[reg].s16; - case 2: // (An) - return ReadWord(A[reg].s32); - case 3: // (An)+ - value = ReadWord(A[reg].s32); - A[reg].s32 += 2; - return value; - case 4: // -(An) - A[reg].s32 -= 2; - return ReadWord(A[reg].s32); - case 5: // (d16,An) - value = ReadWord((A[reg].s32 + ReadWord(PC))); PC += 2; - return value; - case 6: // (d8,An,Xn) - return ReadWord(A[reg].s32 + GetIndex()); - case 7: - switch (reg) - { - case 0: // (imm).W - value = ReadWord(ReadWord(PC)); PC += 2; - return value; - case 1: // (imm).L - value = ReadWord(ReadLong(PC)); PC += 4; - return value; - case 2: // (d16,PC) - value = ReadWord(PC + ReadWord(PC)); PC += 2; - return value; - case 3: // (d8,PC,Xn) - int pc = PC; - value = ReadWord((pc + GetIndex())); - return value; - case 4: // immediate - value = ReadWord(PC); PC += 2; - return value; - default: - throw new Exception("Invalid addressing mode!"); - } - } - throw new Exception("Invalid addressing mode!"); - } + short ReadValueW(int mode, int reg) + { + short value; + switch (mode) + { + case 0: // Dn + return D[reg].s16; + case 1: // An + return A[reg].s16; + case 2: // (An) + return ReadWord(A[reg].s32); + case 3: // (An)+ + value = ReadWord(A[reg].s32); + A[reg].s32 += 2; + return value; + case 4: // -(An) + A[reg].s32 -= 2; + return ReadWord(A[reg].s32); + case 5: // (d16,An) + value = ReadWord((A[reg].s32 + ReadWord(PC))); PC += 2; + return value; + case 6: // (d8,An,Xn) + return ReadWord(A[reg].s32 + GetIndex()); + case 7: + switch (reg) + { + case 0: // (imm).W + value = ReadWord(ReadWord(PC)); PC += 2; + return value; + case 1: // (imm).L + value = ReadWord(ReadLong(PC)); PC += 4; + return value; + case 2: // (d16,PC) + value = ReadWord(PC + ReadWord(PC)); PC += 2; + return value; + case 3: // (d8,PC,Xn) + int pc = PC; + value = ReadWord((pc + GetIndex())); + return value; + case 4: // immediate + value = ReadWord(PC); PC += 2; + return value; + default: + throw new Exception("Invalid addressing mode!"); + } + } + throw new Exception("Invalid addressing mode!"); + } - int ReadValueL(int mode, int reg) - { - int value; - switch (mode) - { - case 0: // Dn - return D[reg].s32; - case 1: // An - return A[reg].s32; - case 2: // (An) - return ReadLong(A[reg].s32); - case 3: // (An)+ - value = ReadLong(A[reg].s32); - A[reg].s32 += 4; - return value; - case 4: // -(An) - A[reg].s32 -= 4; - return ReadLong(A[reg].s32); - case 5: // (d16,An) - value = ReadLong((A[reg].s32 + ReadWord(PC))); PC += 2; - return value; - case 6: // (d8,An,Xn) - return ReadLong(A[reg].s32 + GetIndex()); - case 7: - switch (reg) - { - case 0: // (imm).W - value = ReadLong(ReadWord(PC)); PC += 2; - return value; - case 1: // (imm).L - value = ReadLong(ReadLong(PC)); PC += 4; - return value; - case 2: // (d16,PC) - value = ReadLong(PC + ReadWord(PC)); PC += 2; - return value; - case 3: // (d8,PC,Xn) - int pc = PC; - value = ReadLong((pc + GetIndex())); - return value; - case 4: // immediate - value = ReadLong(PC); PC += 4; - return value; - default: - throw new Exception("Invalid addressing mode!"); - } - } - throw new Exception("Invalid addressing mode!"); - } + int ReadValueL(int mode, int reg) + { + int value; + switch (mode) + { + case 0: // Dn + return D[reg].s32; + case 1: // An + return A[reg].s32; + case 2: // (An) + return ReadLong(A[reg].s32); + case 3: // (An)+ + value = ReadLong(A[reg].s32); + A[reg].s32 += 4; + return value; + case 4: // -(An) + A[reg].s32 -= 4; + return ReadLong(A[reg].s32); + case 5: // (d16,An) + value = ReadLong((A[reg].s32 + ReadWord(PC))); PC += 2; + return value; + case 6: // (d8,An,Xn) + return ReadLong(A[reg].s32 + GetIndex()); + case 7: + switch (reg) + { + case 0: // (imm).W + value = ReadLong(ReadWord(PC)); PC += 2; + return value; + case 1: // (imm).L + value = ReadLong(ReadLong(PC)); PC += 4; + return value; + case 2: // (d16,PC) + value = ReadLong(PC + ReadWord(PC)); PC += 2; + return value; + case 3: // (d8,PC,Xn) + int pc = PC; + value = ReadLong((pc + GetIndex())); + return value; + case 4: // immediate + value = ReadLong(PC); PC += 4; + return value; + default: + throw new Exception("Invalid addressing mode!"); + } + } + throw new Exception("Invalid addressing mode!"); + } - sbyte PeekValueB(int mode, int reg) - { - sbyte value; - switch (mode) - { - case 0: // Dn - return D[reg].s8; - case 1: // An - return A[reg].s8; - case 2: // (An) - return ReadByte(A[reg].s32); - case 3: // (An)+ - value = ReadByte(A[reg].s32); - A[reg].s32 += reg == 7 ? 2 : 1; - return value; - case 4: // -(An) - A[reg].s32 -= reg == 7 ? 2 : 1; - return ReadByte(A[reg].s32); - case 5: // (d16,An) - value = ReadByte((A[reg].s32 + ReadWord(PC))); - return value; - case 6: // (d8,An,Xn) - return ReadByte(A[reg].s32 + PeekIndex()); - case 7: - switch (reg) - { - case 0: // (imm).W - value = ReadByte(ReadWord(PC)); - return value; - case 1: // (imm).L - value = ReadByte(ReadLong(PC)); - return value; - case 2: // (d16,PC) - value = ReadByte(PC + ReadWord(PC)); - return value; - case 3: // (d8,PC,Xn) - value = ReadByte((PC + PeekIndex())); - return value; - case 4: // immediate - return (sbyte) ReadWord(PC); - default: - throw new Exception("Invalid addressing mode!"); - } - } - throw new Exception("Invalid addressing mode!"); - } + sbyte PeekValueB(int mode, int reg) + { + sbyte value; + switch (mode) + { + case 0: // Dn + return D[reg].s8; + case 1: // An + return A[reg].s8; + case 2: // (An) + return ReadByte(A[reg].s32); + case 3: // (An)+ + value = ReadByte(A[reg].s32); + A[reg].s32 += reg == 7 ? 2 : 1; + return value; + case 4: // -(An) + A[reg].s32 -= reg == 7 ? 2 : 1; + return ReadByte(A[reg].s32); + case 5: // (d16,An) + value = ReadByte((A[reg].s32 + ReadWord(PC))); + return value; + case 6: // (d8,An,Xn) + return ReadByte(A[reg].s32 + PeekIndex()); + case 7: + switch (reg) + { + case 0: // (imm).W + value = ReadByte(ReadWord(PC)); + return value; + case 1: // (imm).L + value = ReadByte(ReadLong(PC)); + return value; + case 2: // (d16,PC) + value = ReadByte(PC + ReadWord(PC)); + return value; + case 3: // (d8,PC,Xn) + value = ReadByte((PC + PeekIndex())); + return value; + case 4: // immediate + return (sbyte)ReadWord(PC); + default: + throw new Exception("Invalid addressing mode!"); + } + } + throw new Exception("Invalid addressing mode!"); + } - short PeekValueW(int mode, int reg) - { - short value; - switch (mode) - { - case 0: // Dn - return D[reg].s16; - case 1: // An - return A[reg].s16; - case 2: // (An) - return ReadWord(A[reg].s32); - case 3: // (An)+ - value = ReadWord(A[reg].s32); - A[reg].s32 += 2; - return value; - case 4: // -(An) - A[reg].s32 -= 2; - return ReadWord(A[reg].s32); - case 5: // (d16,An) - value = ReadWord((A[reg].s32 + ReadWord(PC))); - return value; - case 6: // (d8,An,Xn) - return ReadWord(A[reg].s32 + PeekIndex()); - case 7: - switch (reg) - { - case 0: // (imm).W - value = ReadWord(ReadWord(PC)); - return value; - case 1: // (imm).L - value = ReadWord(ReadLong(PC)); - return value; - case 2: // (d16,PC) - value = ReadWord(PC + ReadWord(PC)); - return value; - case 3: // (d8,PC,Xn) - value = ReadWord((PC + PeekIndex())); - return value; - case 4: // immediate - return ReadWord(PC); - default: - throw new Exception("Invalid addressing mode!"); - } - } - throw new Exception("Invalid addressing mode!"); - } + short PeekValueW(int mode, int reg) + { + short value; + switch (mode) + { + case 0: // Dn + return D[reg].s16; + case 1: // An + return A[reg].s16; + case 2: // (An) + return ReadWord(A[reg].s32); + case 3: // (An)+ + value = ReadWord(A[reg].s32); + A[reg].s32 += 2; + return value; + case 4: // -(An) + A[reg].s32 -= 2; + return ReadWord(A[reg].s32); + case 5: // (d16,An) + value = ReadWord((A[reg].s32 + ReadWord(PC))); + return value; + case 6: // (d8,An,Xn) + return ReadWord(A[reg].s32 + PeekIndex()); + case 7: + switch (reg) + { + case 0: // (imm).W + value = ReadWord(ReadWord(PC)); + return value; + case 1: // (imm).L + value = ReadWord(ReadLong(PC)); + return value; + case 2: // (d16,PC) + value = ReadWord(PC + ReadWord(PC)); + return value; + case 3: // (d8,PC,Xn) + value = ReadWord((PC + PeekIndex())); + return value; + case 4: // immediate + return ReadWord(PC); + default: + throw new Exception("Invalid addressing mode!"); + } + } + throw new Exception("Invalid addressing mode!"); + } - int PeekValueL(int mode, int reg) - { - int value; - switch (mode) - { - case 0: // Dn - return D[reg].s32; - case 1: // An - return A[reg].s32; - case 2: // (An) - return ReadLong(A[reg].s32); - case 3: // (An)+ - value = ReadLong(A[reg].s32); - A[reg].s32 += 4; - return value; - case 4: // -(An) - A[reg].s32 -= 4; - return ReadLong(A[reg].s32); - case 5: // (d16,An) - value = ReadLong((A[reg].s32 + ReadWord(PC))); - return value; - case 6: // (d8,An,Xn) - return ReadLong(A[reg].s32 + PeekIndex()); - case 7: - switch (reg) - { - case 0: // (imm).W - value = ReadLong(ReadWord(PC)); - return value; - case 1: // (imm).L - value = ReadLong(ReadLong(PC)); - return value; - case 2: // (d16,PC) - value = ReadLong(PC + ReadWord(PC)); - return value; - case 3: // (d8,PC,Xn) - value = ReadLong((PC + PeekIndex())); - return value; - case 4: // immediate - return ReadLong(PC); - default: - throw new Exception("Invalid addressing mode!"); - } - } - throw new Exception("Invalid addressing mode!"); - } + int PeekValueL(int mode, int reg) + { + int value; + switch (mode) + { + case 0: // Dn + return D[reg].s32; + case 1: // An + return A[reg].s32; + case 2: // (An) + return ReadLong(A[reg].s32); + case 3: // (An)+ + value = ReadLong(A[reg].s32); + A[reg].s32 += 4; + return value; + case 4: // -(An) + A[reg].s32 -= 4; + return ReadLong(A[reg].s32); + case 5: // (d16,An) + value = ReadLong((A[reg].s32 + ReadWord(PC))); + return value; + case 6: // (d8,An,Xn) + return ReadLong(A[reg].s32 + PeekIndex()); + case 7: + switch (reg) + { + case 0: // (imm).W + value = ReadLong(ReadWord(PC)); + return value; + case 1: // (imm).L + value = ReadLong(ReadLong(PC)); + return value; + case 2: // (d16,PC) + value = ReadLong(PC + ReadWord(PC)); + return value; + case 3: // (d8,PC,Xn) + value = ReadLong((PC + PeekIndex())); + return value; + case 4: // immediate + return ReadLong(PC); + default: + throw new Exception("Invalid addressing mode!"); + } + } + throw new Exception("Invalid addressing mode!"); + } - int ReadAddress(int mode, int reg) - { - int addr; - switch (mode) - { - case 0: throw new Exception("Invalid addressing mode!"); // Dn - case 1: throw new Exception("Invalid addressing mode!"); // An - case 2: return A[reg].s32; // (An) - case 3: return A[reg].s32; // (An)+ - case 4: return A[reg].s32; // -(An) - case 5: addr = A[reg].s32 + ReadWord(PC); PC += 2; return addr; // (d16,An) - case 6: return A[reg].s32 + GetIndex(); // (d8,An,Xn) - case 7: - switch (reg) - { - case 0: addr = ReadWord(PC); PC += 2; return addr; // (imm).w - case 1: addr = ReadLong(PC); PC += 4; return addr; // (imm).l - case 2: addr = PC; addr += ReadWord(PC); PC += 2; return addr; // (d16,PC) - case 3: addr = PC; addr += GetIndex(); return addr; // (d8,PC,Xn) - case 4: throw new Exception("Invalid addressing mode!"); // immediate - } - break; - } - throw new Exception("Invalid addressing mode!"); - } + int ReadAddress(int mode, int reg) + { + int addr; + switch (mode) + { + case 0: throw new Exception("Invalid addressing mode!"); // Dn + case 1: throw new Exception("Invalid addressing mode!"); // An + case 2: return A[reg].s32; // (An) + case 3: return A[reg].s32; // (An)+ + case 4: return A[reg].s32; // -(An) + case 5: addr = A[reg].s32 + ReadWord(PC); PC += 2; return addr; // (d16,An) + case 6: return A[reg].s32 + GetIndex(); // (d8,An,Xn) + case 7: + switch (reg) + { + case 0: addr = ReadWord(PC); PC += 2; return addr; // (imm).w + case 1: addr = ReadLong(PC); PC += 4; return addr; // (imm).l + case 2: addr = PC; addr += ReadWord(PC); PC += 2; return addr; // (d16,PC) + case 3: addr = PC; addr += GetIndex(); return addr; // (d8,PC,Xn) + case 4: throw new Exception("Invalid addressing mode!"); // immediate + } + break; + } + throw new Exception("Invalid addressing mode!"); + } - string DisassembleValue(int mode, int reg, int size, ref int pc) - { - string value; - int addr; - switch (mode) - { - case 0: return "D"+reg; // Dn - case 1: return "A"+reg; // An - case 2: return "(A"+reg+")"; // (An) - case 3: return "(A"+reg+")+"; // (An)+ - case 4: return "-(A"+reg+")"; // -(An) - case 5: value = string.Format("(${0:X},A{1})", ReadWord(pc), reg); pc += 2; return value; // (d16,An) - case 6: addr = ReadWord(pc); pc += 2; return DisassembleIndex("A" + reg, (short) addr); // (d8,An,Xn) - case 7: - switch (reg) - { - case 0: value = String.Format("(${0:X})", ReadWord(pc)); pc += 2; return value; // (imm).W - case 1: value = String.Format("(${0:X})", ReadLong(pc)); pc += 4; return value; // (imm).L - case 2: value = String.Format("(${0:X})", pc + ReadWord(pc)); pc += 2; return value; // (d16,PC) - case 3: addr = ReadWord(pc); pc += 2; return DisassembleIndex("PC", (short)addr); // (d8,PC,Xn) - case 4: - switch (size) - { - case 1: value = String.Format("${0:X}", (byte)ReadWord(pc)); pc += 2; return value; - case 2: value = String.Format("${0:X}", ReadWord(pc)); pc += 2; return value; - case 4: value = String.Format("${0:X}", ReadLong(pc)); pc += 4; return value; - } - break; - } - break; - } - throw new Exception("Invalid addressing mode!"); - } + string DisassembleValue(int mode, int reg, int size, ref int pc) + { + string value; + int addr; + switch (mode) + { + case 0: return "D" + reg; // Dn + case 1: return "A" + reg; // An + case 2: return "(A" + reg + ")"; // (An) + case 3: return "(A" + reg + ")+"; // (An)+ + case 4: return "-(A" + reg + ")"; // -(An) + case 5: value = string.Format("(${0:X},A{1})", ReadWord(pc), reg); pc += 2; return value; // (d16,An) + case 6: addr = ReadWord(pc); pc += 2; return DisassembleIndex("A" + reg, (short)addr); // (d8,An,Xn) + case 7: + switch (reg) + { + case 0: value = String.Format("(${0:X})", ReadWord(pc)); pc += 2; return value; // (imm).W + case 1: value = String.Format("(${0:X})", ReadLong(pc)); pc += 4; return value; // (imm).L + case 2: value = String.Format("(${0:X})", pc + ReadWord(pc)); pc += 2; return value; // (d16,PC) + case 3: addr = ReadWord(pc); pc += 2; return DisassembleIndex("PC", (short)addr); // (d8,PC,Xn) + case 4: + switch (size) + { + case 1: value = String.Format("${0:X}", (byte)ReadWord(pc)); pc += 2; return value; + case 2: value = String.Format("${0:X}", ReadWord(pc)); pc += 2; return value; + case 4: value = String.Format("${0:X}", ReadLong(pc)); pc += 4; return value; + } + break; + } + break; + } + throw new Exception("Invalid addressing mode!"); + } - string DisassembleImmediate(int size, ref int pc) - { - int immed; - switch (size) - { - case 1: - immed = (byte)ReadWord(pc); pc += 2; - return String.Format("${0:X}", immed); - case 2: - immed = (ushort) ReadWord(pc); pc += 2; - return String.Format("${0:X}", immed); - case 4: - immed = ReadLong(pc); pc += 4; - return String.Format("${0:X}", immed); - } - throw new ArgumentException("Invalid size"); - } + string DisassembleImmediate(int size, ref int pc) + { + int immed; + switch (size) + { + case 1: + immed = (byte)ReadWord(pc); pc += 2; + return String.Format("${0:X}", immed); + case 2: + immed = (ushort)ReadWord(pc); pc += 2; + return String.Format("${0:X}", immed); + case 4: + immed = ReadLong(pc); pc += 4; + return String.Format("${0:X}", immed); + } + throw new ArgumentException("Invalid size"); + } - string DisassembleAddress(int mode, int reg, ref int pc) - { - int addr; - switch (mode) - { - case 0: return "INVALID"; // Dn - case 1: return "INVALID"; // An - case 2: return "(A"+reg+")"; // (An) - case 3: return "(A"+reg+")+"; // (An)+ - case 4: return "-(A"+reg+")"; // -(An) - case 5: addr = ReadWord(pc); pc += 2; return String.Format("({0},A{1})", addr, reg); // (d16,An) - case 6: addr = ReadWord(pc); pc += 2; return DisassembleIndex("A" + reg, (short)addr); // (d8,An,Xn) - case 7: - switch (reg) - { - case 0: addr = ReadWord(pc); pc += 2; return String.Format("${0:X}.w",addr); // (imm).w - case 1: addr = ReadLong(pc); pc += 4; return String.Format("${0:X}.l",addr); // (imm).l - case 2: addr = ReadWord(pc); pc += 2; return String.Format("(${0:X},PC)",addr); // (d16,PC) - case 3: addr = ReadWord(pc); pc += 2; return DisassembleIndex("PC", (short)addr); // (d8,PC,Xn) - case 4: return "INVALID"; // immediate - } - break; - } - throw new Exception("Invalid addressing mode!"); - } + string DisassembleAddress(int mode, int reg, ref int pc) + { + int addr; + switch (mode) + { + case 0: return "INVALID"; // Dn + case 1: return "INVALID"; // An + case 2: return "(A" + reg + ")"; // (An) + case 3: return "(A" + reg + ")+"; // (An)+ + case 4: return "-(A" + reg + ")"; // -(An) + case 5: addr = ReadWord(pc); pc += 2; return String.Format("({0},A{1})", addr, reg); // (d16,An) + case 6: addr = ReadWord(pc); pc += 2; return DisassembleIndex("A" + reg, (short)addr); // (d8,An,Xn) + case 7: + switch (reg) + { + case 0: addr = ReadWord(pc); pc += 2; return String.Format("${0:X}.w", addr); // (imm).w + case 1: addr = ReadLong(pc); pc += 4; return String.Format("${0:X}.l", addr); // (imm).l + case 2: addr = ReadWord(pc); pc += 2; return String.Format("(${0:X},PC)", addr); // (d16,PC) + case 3: addr = ReadWord(pc); pc += 2; return DisassembleIndex("PC", (short)addr); // (d8,PC,Xn) + case 4: return "INVALID"; // immediate + } + break; + } + throw new Exception("Invalid addressing mode!"); + } - void WriteValueB(int mode, int reg, sbyte value) - { - switch (mode) - { - case 0x00: // Dn - D[reg].s8 = value; - return; - case 0x01: // An - A[reg].s32 = value; - return; - case 0x02: // (An) - WriteByte(A[reg].s32, value); - return; - case 0x03: // (An)+ - WriteByte(A[reg].s32, value); - A[reg].s32 += reg == 7 ? 2 : 1; - return; - case 0x04: // -(An) - A[reg].s32 -= reg == 7 ? 2 : 1; - WriteByte(A[reg].s32, value); - return; - case 0x05: // (d16,An) - WriteByte(A[reg].s32 + ReadWord(PC), value); PC += 2; - return; - case 0x06: // (d8,An,Xn) - WriteByte(A[reg].s32 + GetIndex(), value); - return; - case 0x07: - switch (reg) - { - case 0x00: // (imm).W - WriteByte(ReadWord(PC), value); PC += 2; - return; - case 0x01: // (imm).L - WriteByte(ReadLong(PC), value); PC += 4; - return; - case 0x02: // (d16,PC) - WriteByte(PC + ReadWord(PC), value); PC += 2; - return; - case 0x03: // (d8,PC,Xn) - int pc = PC; - WriteByte(pc + PeekIndex(), value); - PC += 2; - return; - default: throw new Exception("Invalid addressing mode!"); - } - } - } + void WriteValueB(int mode, int reg, sbyte value) + { + switch (mode) + { + case 0x00: // Dn + D[reg].s8 = value; + return; + case 0x01: // An + A[reg].s32 = value; + return; + case 0x02: // (An) + WriteByte(A[reg].s32, value); + return; + case 0x03: // (An)+ + WriteByte(A[reg].s32, value); + A[reg].s32 += reg == 7 ? 2 : 1; + return; + case 0x04: // -(An) + A[reg].s32 -= reg == 7 ? 2 : 1; + WriteByte(A[reg].s32, value); + return; + case 0x05: // (d16,An) + WriteByte(A[reg].s32 + ReadWord(PC), value); PC += 2; + return; + case 0x06: // (d8,An,Xn) + WriteByte(A[reg].s32 + GetIndex(), value); + return; + case 0x07: + switch (reg) + { + case 0x00: // (imm).W + WriteByte(ReadWord(PC), value); PC += 2; + return; + case 0x01: // (imm).L + WriteByte(ReadLong(PC), value); PC += 4; + return; + case 0x02: // (d16,PC) + WriteByte(PC + ReadWord(PC), value); PC += 2; + return; + case 0x03: // (d8,PC,Xn) + int pc = PC; + WriteByte(pc + PeekIndex(), value); + PC += 2; + return; + default: throw new Exception("Invalid addressing mode!"); + } + } + } - void WriteValueW(int mode, int reg, short value) - { - switch (mode) - { - case 0x00: // Dn - D[reg].s16 = value; - return; - case 0x01: // An - A[reg].s32 = value; - return; - case 0x02: // (An) - WriteWord(A[reg].s32, value); - return; - case 0x03: // (An)+ - WriteWord(A[reg].s32, value); - A[reg].s32 += 2; - return; - case 0x04: // -(An) - A[reg].s32 -= 2; - WriteWord(A[reg].s32, value); - return; - case 0x05: // (d16,An) - WriteWord(A[reg].s32 + ReadWord(PC), value); PC += 2; - return; - case 0x06: // (d8,An,Xn) - WriteWord(A[reg].s32 + GetIndex(), value); - return; - case 0x07: - switch (reg) - { - case 0x00: // (imm).W - WriteWord(ReadWord(PC), value); PC += 2; - return; - case 0x01: // (imm).L - WriteWord(ReadLong(PC), value); PC += 4; - return; - case 0x02: // (d16,PC) - WriteWord(PC + ReadWord(PC), value); PC += 2; - return; - case 0x03: // (d8,PC,Xn) - int pc = PC; - WriteWord(pc + PeekIndex(), value); - PC += 2; - return; - default: throw new Exception("Invalid addressing mode!"); - } - } - } + void WriteValueW(int mode, int reg, short value) + { + switch (mode) + { + case 0x00: // Dn + D[reg].s16 = value; + return; + case 0x01: // An + A[reg].s32 = value; + return; + case 0x02: // (An) + WriteWord(A[reg].s32, value); + return; + case 0x03: // (An)+ + WriteWord(A[reg].s32, value); + A[reg].s32 += 2; + return; + case 0x04: // -(An) + A[reg].s32 -= 2; + WriteWord(A[reg].s32, value); + return; + case 0x05: // (d16,An) + WriteWord(A[reg].s32 + ReadWord(PC), value); PC += 2; + return; + case 0x06: // (d8,An,Xn) + WriteWord(A[reg].s32 + GetIndex(), value); + return; + case 0x07: + switch (reg) + { + case 0x00: // (imm).W + WriteWord(ReadWord(PC), value); PC += 2; + return; + case 0x01: // (imm).L + WriteWord(ReadLong(PC), value); PC += 4; + return; + case 0x02: // (d16,PC) + WriteWord(PC + ReadWord(PC), value); PC += 2; + return; + case 0x03: // (d8,PC,Xn) + int pc = PC; + WriteWord(pc + PeekIndex(), value); + PC += 2; + return; + default: throw new Exception("Invalid addressing mode!"); + } + } + } - void WriteValueL(int mode, int reg, int value) - { - switch (mode) - { - case 0x00: // Dn - D[reg].s32 = value; - return; - case 0x01: // An - A[reg].s32 = value; - return; - case 0x02: // (An) - WriteLong(A[reg].s32, value); - return; - case 0x03: // (An)+ - WriteLong(A[reg].s32, value); - A[reg].s32 += 4; - return; - case 0x04: // -(An) - A[reg].s32 -= 4; - WriteLong(A[reg].s32, value); - return; - case 0x05: // (d16,An) - WriteLong(A[reg].s32 + ReadWord(PC), value); PC += 2; - return; - case 0x06: // (d8,An,Xn) - WriteLong(A[reg].s32 + GetIndex(), value); - return; - case 0x07: - switch (reg) - { - case 0x00: // (imm).W - WriteLong(ReadWord(PC), value); PC += 2; - return; - case 0x01: // (imm).L - WriteLong(ReadLong(PC), value); PC += 4; - return; - case 0x02: // (d16,PC) - WriteLong(PC + ReadWord(PC), value); PC += 2; - return; - case 0x03: // (d8,PC,Xn) - int pc = PC; - WriteLong(pc + PeekIndex(), value); - PC += 2; - return; - default: throw new Exception("Invalid addressing mode!"); - } - } - } + void WriteValueL(int mode, int reg, int value) + { + switch (mode) + { + case 0x00: // Dn + D[reg].s32 = value; + return; + case 0x01: // An + A[reg].s32 = value; + return; + case 0x02: // (An) + WriteLong(A[reg].s32, value); + return; + case 0x03: // (An)+ + WriteLong(A[reg].s32, value); + A[reg].s32 += 4; + return; + case 0x04: // -(An) + A[reg].s32 -= 4; + WriteLong(A[reg].s32, value); + return; + case 0x05: // (d16,An) + WriteLong(A[reg].s32 + ReadWord(PC), value); PC += 2; + return; + case 0x06: // (d8,An,Xn) + WriteLong(A[reg].s32 + GetIndex(), value); + return; + case 0x07: + switch (reg) + { + case 0x00: // (imm).W + WriteLong(ReadWord(PC), value); PC += 2; + return; + case 0x01: // (imm).L + WriteLong(ReadLong(PC), value); PC += 4; + return; + case 0x02: // (d16,PC) + WriteLong(PC + ReadWord(PC), value); PC += 2; + return; + case 0x03: // (d8,PC,Xn) + int pc = PC; + WriteLong(pc + PeekIndex(), value); + PC += 2; + return; + default: throw new Exception("Invalid addressing mode!"); + } + } + } - int GetIndex() - { - //Console.WriteLine("IN INDEX PORTION - NOT VERIFIED!!!"); - // TODO kid chameleon triggers this in startup sequence + int GetIndex() + { + //Console.WriteLine("IN INDEX PORTION - NOT VERIFIED!!!"); + // TODO kid chameleon triggers this in startup sequence - short extension = ReadWord(PC); PC += 2; + short extension = ReadWord(PC); PC += 2; - int da = (extension >> 15) & 0x1; - int reg = (extension >> 12) & 0x7; - int size = (extension >> 11) & 0x1; - int scale = (extension >> 9) & 0x3; - sbyte displacement = (sbyte)extension; + int da = (extension >> 15) & 0x1; + int reg = (extension >> 12) & 0x7; + int size = (extension >> 11) & 0x1; + int scale = (extension >> 9) & 0x3; + sbyte displacement = (sbyte)extension; - int indexReg; - switch (scale) - { - case 0: indexReg = 1; break; - case 1: indexReg = 2; break; - case 2: indexReg = 4; break; - default: indexReg = 8; break; - } - if (da == 0) - indexReg *= size == 0 ? D[reg].s16 : D[reg].s32; - else - indexReg *= size == 0 ? A[reg].s16 : A[reg].s32; + int indexReg; + switch (scale) + { + case 0: indexReg = 1; break; + case 1: indexReg = 2; break; + case 2: indexReg = 4; break; + default: indexReg = 8; break; + } + if (da == 0) + indexReg *= size == 0 ? D[reg].s16 : D[reg].s32; + else + indexReg *= size == 0 ? A[reg].s16 : A[reg].s32; - return displacement + indexReg; - } + return displacement + indexReg; + } - int PeekIndex() - { - //Console.WriteLine("IN INDEX PORTION - NOT VERIFIED!!!"); + int PeekIndex() + { + //Console.WriteLine("IN INDEX PORTION - NOT VERIFIED!!!"); - short extension = ReadWord(PC); + short extension = ReadWord(PC); - int da = (extension >> 15) & 0x1; - int reg = (extension >> 12) & 0x7; - int size = (extension >> 11) & 0x1; - int scale = (extension >> 9) & 0x3; - sbyte displacement = (sbyte)extension; + int da = (extension >> 15) & 0x1; + int reg = (extension >> 12) & 0x7; + int size = (extension >> 11) & 0x1; + int scale = (extension >> 9) & 0x3; + sbyte displacement = (sbyte)extension; - int indexReg; - switch (scale) - { - case 0: indexReg = 1; break; - case 1: indexReg = 2; break; - case 2: indexReg = 4; break; - default: indexReg = 8; break; - } - if (da == 0) - indexReg *= size == 0 ? D[reg].s16 : D[reg].s32; - else - indexReg *= size == 0 ? A[reg].s16 : A[reg].s32; + int indexReg; + switch (scale) + { + case 0: indexReg = 1; break; + case 1: indexReg = 2; break; + case 2: indexReg = 4; break; + default: indexReg = 8; break; + } + if (da == 0) + indexReg *= size == 0 ? D[reg].s16 : D[reg].s32; + else + indexReg *= size == 0 ? A[reg].s16 : A[reg].s32; - return displacement + indexReg; - } + return displacement + indexReg; + } - string DisassembleIndex(string baseRegister, short extension) - { - int d_a = (extension >> 15) & 0x1; - int reg = (extension >> 12) & 0x7; - int size = (extension >> 11) & 0x1; - int scale = (extension >> 9) & 0x3; - sbyte displacement = (sbyte)extension; + string DisassembleIndex(string baseRegister, short extension) + { + int d_a = (extension >> 15) & 0x1; + int reg = (extension >> 12) & 0x7; + int size = (extension >> 11) & 0x1; + int scale = (extension >> 9) & 0x3; + sbyte displacement = (sbyte)extension; - string scaleFactor; - switch (scale) - { - case 0: scaleFactor = ""; break; - case 1: scaleFactor = "2"; break; - case 2: scaleFactor = "4"; break; - default: scaleFactor = "8"; break; - } + string scaleFactor; + switch (scale) + { + case 0: scaleFactor = ""; break; + case 1: scaleFactor = "2"; break; + case 2: scaleFactor = "4"; break; + default: scaleFactor = "8"; break; + } - string offsetRegister = (d_a == 0) ? "D" : "A"; - string sizeStr = size == 0 ? ".w" : ".l"; - string displacementStr = displacement == 0 ? "" : ("," + displacement); - return string.Format("({0},{1}{2}{3}{4}{5})", baseRegister, scaleFactor, offsetRegister, reg, sizeStr, displacementStr); - } - } + string offsetRegister = (d_a == 0) ? "D" : "A"; + string sizeStr = size == 0 ? ".w" : ".l"; + string displacementStr = displacement == 0 ? "" : ("," + displacement); + return string.Format("({0},{1}{2}{3}{4}{5})", baseRegister, scaleFactor, offsetRegister, reg, sizeStr, displacementStr); + } + } } \ No newline at end of file diff --git a/BizHawk.Emulation/CPUs/68000/OpcodeTable.cs b/BizHawk.Emulation/CPUs/68000/OpcodeTable.cs index 574b5cbc91..3e52b7bdd0 100644 --- a/BizHawk.Emulation/CPUs/68000/OpcodeTable.cs +++ b/BizHawk.Emulation/CPUs/68000/OpcodeTable.cs @@ -3,174 +3,174 @@ using System.Collections.Generic; using BizHawk.Common; -namespace BizHawk.Emulation.CPUs.M68000 +namespace BizHawk.Emulation.Common.Components.M68000 { - partial class MC68000 - { - 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. - // TODO: should really come up with means of only assigning to applicable addressing modes, - // instead of this lame overwriting business. + partial class MC68000 + { + 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. + // 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"); - Assign("moveq", MOVEQ, "0111", "Xn", "0", "Data8"); - Assign("movem", MOVEM0,"010010001", "Size1", "AmXn"); - Assign("movem", MOVEM1,"010011001", "Size1", "AmXn"); - 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("move", MOVE, "00", "Size2_0", "XnAm", "AmXn"); + Assign("movea", MOVEA, "00", "Size2_0", "Xn", "001", "AmXn"); + Assign("moveq", MOVEQ, "0111", "Xn", "0", "Data8"); + Assign("movem", MOVEM0, "010010001", "Size1", "AmXn"); + Assign("movem", MOVEM1, "010011001", "Size1", "AmXn"); + 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("eori", EORI, "00001010", "Size2_1", "AmXn"); - Assign("ori", ORI, "00000000", "Size2_1", "AmXn"); - Assign("asl", ASLd, "1110", "Data3", "1", "Size2_1", "Data1", "00", "Xn"); - Assign("asr", ASRd, "1110", "Data3", "0", "Size2_1", "Data1", "00", "Xn"); - Assign("lsl", LSLd, "1110", "Data3", "1", "Size2_1", "Data1", "01", "Xn"); - Assign("lsr", LSRd, "1110", "Data3", "0", "Size2_1", "Data1", "01", "Xn"); - Assign("roxl", ROXLd, "1110", "Data3", "1", "Size2_1", "Data1", "10", "Xn"); - Assign("roxr", ROXRd, "1110", "Data3", "0", "Size2_1", "Data1", "10", "Xn"); - 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("and", AND0, "1100", "Xn", "0", "Size2_1", "AmXn"); - Assign("and", AND1, "1100", "Xn", "1", "Size2_1", "AmXn"); - Assign("eor", EOR, "1011", "Xn", "1", "Size2_1", "AmXn"); - Assign("or", OR0, "1000", "Xn", "0", "Size2_1", "AmXn"); - Assign("or", OR1, "1000", "Xn", "1", "Size2_1", "AmXn"); - Assign("not", NOT, "01000110", "Size2_1", "AmXn"); - Assign("neg", NEG, "01000100", "Size2_1", "AmXn"); + Assign("andi", ANDI, "00000010", "Size2_1", "AmXn"); + Assign("eori", EORI, "00001010", "Size2_1", "AmXn"); + Assign("ori", ORI, "00000000", "Size2_1", "AmXn"); + Assign("asl", ASLd, "1110", "Data3", "1", "Size2_1", "Data1", "00", "Xn"); + Assign("asr", ASRd, "1110", "Data3", "0", "Size2_1", "Data1", "00", "Xn"); + Assign("lsl", LSLd, "1110", "Data3", "1", "Size2_1", "Data1", "01", "Xn"); + Assign("lsr", LSRd, "1110", "Data3", "0", "Size2_1", "Data1", "01", "Xn"); + Assign("roxl", ROXLd, "1110", "Data3", "1", "Size2_1", "Data1", "10", "Xn"); + Assign("roxr", ROXRd, "1110", "Data3", "0", "Size2_1", "Data1", "10", "Xn"); + 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("and", AND0, "1100", "Xn", "0", "Size2_1", "AmXn"); + Assign("and", AND1, "1100", "Xn", "1", "Size2_1", "AmXn"); + Assign("eor", EOR, "1011", "Xn", "1", "Size2_1", "AmXn"); + Assign("or", OR0, "1000", "Xn", "0", "Size2_1", "AmXn"); + Assign("or", OR1, "1000", "Xn", "1", "Size2_1", "AmXn"); + Assign("not", NOT, "01000110", "Size2_1", "AmXn"); + Assign("neg", NEG, "01000100", "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"); - Assign("scc", Scc, "0101", "CondAll", "11","AmXn"); - Assign("dbcc", DBcc, "0101", "CondAll", "11001", "Xn"); - Assign("rte", RTE, "0100111001110011"); - Assign("rts", RTS, "0100111001110101"); - Assign("rtr", RTR, "0100111001110111"); - Assign("tst", TST, "01001010", "Size2_1", "AmXn"); - Assign("btst", BTSTi, "0000100000", "AmXn"); - Assign("btst", BTSTr, "0000", "Xn", "100", "AmXn"); - Assign("bchg", BCHGi, "0000100001", "AmXn"); - Assign("bchg", BCHGr, "0000", "Xn", "101", "AmXn"); - Assign("bclr", BCLRi, "0000100010", "AmXn"); - Assign("bclr", BCLRr, "0000", "Xn", "110", "AmXn"); - Assign("bset", BSETi, "0000100011", "AmXn"); - Assign("bset", BSETr, "0000", "Xn", "111", "AmXn"); - Assign("link", LINK, "0100111001010", "Xn"); - Assign("unlk", UNLK, "0100111001011", "Xn"); - Assign("nop", NOP, "0100111001110001"); + 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"); + Assign("scc", Scc, "0101", "CondAll", "11", "AmXn"); + Assign("dbcc", DBcc, "0101", "CondAll", "11001", "Xn"); + Assign("rte", RTE, "0100111001110011"); + Assign("rts", RTS, "0100111001110101"); + Assign("rtr", RTR, "0100111001110111"); + Assign("tst", TST, "01001010", "Size2_1", "AmXn"); + Assign("btst", BTSTi, "0000100000", "AmXn"); + Assign("btst", BTSTr, "0000", "Xn", "100", "AmXn"); + Assign("bchg", BCHGi, "0000100001", "AmXn"); + Assign("bchg", BCHGr, "0000", "Xn", "101", "AmXn"); + Assign("bclr", BCLRi, "0000100010", "AmXn"); + Assign("bclr", BCLRr, "0000", "Xn", "110", "AmXn"); + Assign("bset", BSETi, "0000100011", "AmXn"); + Assign("bset", BSETr, "0000", "Xn", "111", "AmXn"); + Assign("link", LINK, "0100111001010", "Xn"); + Assign("unlk", UNLK, "0100111001011", "Xn"); + Assign("nop", NOP, "0100111001110001"); - Assign("add", ADD0, "1101", "Xn", "0", "Size2_1", "AmXn"); - Assign("add", ADD1, "1101", "Xn", "1", "Size2_1", "AmXn"); - Assign("adda", ADDA, "1101", "Xn", "Size1", "11", "AmXn"); - Assign("addi", ADDI, "00000110", "Size2_1", "AmXn"); - Assign("addq", ADDQ, "0101", "Data3", "0", "Size2_1", "AmXn"); - Assign("sub", SUB0, "1001", "Xn", "0", "Size2_1", "AmXn"); - Assign("sub", SUB1, "1001", "Xn", "1", "Size2_1", "AmXn"); - Assign("suba", SUBA, "1001", "Xn", "Size1", "11", "AmXn"); - 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 - Assign("muls", MULS, "1100", "Xn", "111", "AmXn"); // TODO accurate timing - Assign("divu", DIVU, "1000", "Xn", "011", "AmXn"); // TODO accurate timing - Assign("divs", DIVS, "1000", "Xn", "111", "AmXn"); // TODO accurate timing + Assign("add", ADD0, "1101", "Xn", "0", "Size2_1", "AmXn"); + Assign("add", ADD1, "1101", "Xn", "1", "Size2_1", "AmXn"); + Assign("adda", ADDA, "1101", "Xn", "Size1", "11", "AmXn"); + Assign("addi", ADDI, "00000110", "Size2_1", "AmXn"); + Assign("addq", ADDQ, "0101", "Data3", "0", "Size2_1", "AmXn"); + Assign("sub", SUB0, "1001", "Xn", "0", "Size2_1", "AmXn"); + Assign("sub", SUB1, "1001", "Xn", "1", "Size2_1", "AmXn"); + Assign("suba", SUBA, "1001", "Xn", "Size1", "11", "AmXn"); + 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 + Assign("muls", MULS, "1100", "Xn", "111", "AmXn"); // TODO accurate timing + Assign("divu", DIVU, "1000", "Xn", "011", "AmXn"); // TODO accurate timing + Assign("divs", DIVS, "1000", "Xn", "111", "AmXn"); // TODO accurate timing - Assign("move2sr", MOVEtSR, "0100011011", "AmXn"); - Assign("movefsr", MOVEfSR, "0100000011", "AmXn"); - Assign("moveusp", MOVEUSP, "010011100110", "Data1", "Xn"); - Assign("andi2sr", ANDI_SR, "0000001001111100"); - Assign("eori2sr", EORI_SR, "0000101001111100"); - Assign("ori2sr", ORI_SR, "0000000001111100"); - Assign("moveccr", MOVECCR, "0100010011", "AmXn"); - Assign("trap", TRAP, "010011100100", "Data4"); - } + Assign("move2sr", MOVEtSR, "0100011011", "AmXn"); + Assign("movefsr", MOVEfSR, "0100000011", "AmXn"); + Assign("moveusp", MOVEUSP, "010011100110", "Data1", "Xn"); + Assign("andi2sr", ANDI_SR, "0000001001111100"); + Assign("eori2sr", EORI_SR, "0000101001111100"); + Assign("ori2sr", ORI_SR, "0000000001111100"); + Assign("moveccr", MOVECCR, "0100010011", "AmXn"); + Assign("trap", TRAP, "010011100100", "Data4"); + } - void Assign(string instr, Action exec, string root, params string[] bitfield) - { - List opList = new List(); - opList.Add(root); + void Assign(string instr, Action exec, string root, params string[] bitfield) + { + List opList = new List(); + opList.Add(root); - foreach (var component in bitfield) - { - if (component.IsBinary()) AppendConstant(opList, component); - else if (component == "Size1") opList = AppendPermutations(opList, Size1); - else if (component == "Size2_0") opList = AppendPermutations(opList, Size2_0); - else if (component == "Size2_1") opList = AppendPermutations(opList, Size2_1); - else if (component == "XnAm") opList = AppendPermutations(opList, Xn3Am3); - else if (component == "AmXn") opList = AppendPermutations(opList, Am3Xn3); - else if (component == "Xn") opList = AppendPermutations(opList, Xn3); - else if (component == "CondMain") opList = AppendPermutations(opList, ConditionMain); - else if (component == "CondAll") opList = AppendPermutations(opList, ConditionAll); - else if (component == "Data1") opList = AppendData(opList, 1); - else if (component == "Data4") opList = AppendData(opList, 4); - else if (component == "Data3") opList = AppendData(opList, 3); - else if (component == "Data8") opList = AppendData(opList, 8); - } + foreach (var component in bitfield) + { + if (component.IsBinary()) AppendConstant(opList, component); + else if (component == "Size1") opList = AppendPermutations(opList, Size1); + else if (component == "Size2_0") opList = AppendPermutations(opList, Size2_0); + else if (component == "Size2_1") opList = AppendPermutations(opList, Size2_1); + else if (component == "XnAm") opList = AppendPermutations(opList, Xn3Am3); + else if (component == "AmXn") opList = AppendPermutations(opList, Am3Xn3); + else if (component == "Xn") opList = AppendPermutations(opList, Xn3); + else if (component == "CondMain") opList = AppendPermutations(opList, ConditionMain); + else if (component == "CondAll") opList = AppendPermutations(opList, ConditionAll); + else if (component == "Data1") opList = AppendData(opList, 1); + else if (component == "Data4") opList = AppendData(opList, 4); + else if (component == "Data3") opList = AppendData(opList, 3); + else if (component == "Data8") opList = AppendData(opList, 8); + } - foreach (var opcode in opList) - { - int opc = Convert.ToInt32(opcode, 2); - 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; - } - } + foreach (var opcode in opList) + { + int opc = Convert.ToInt32(opcode, 2); + 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; + } + } - void AppendConstant(List ops, string constant) - { - for (int i=0; i ops, string constant) + { + for (int i = 0; i < ops.Count; i++) + ops[i] = ops[i] + constant; + } - List AppendPermutations(List ops, string[] permutations) - { - List output = new List(); + List AppendPermutations(List ops, string[] permutations) + { + List output = new List(); - foreach (var input in ops) - foreach (var perm in permutations) - output.Add(input + perm); + foreach (var input in ops) + foreach (var perm in permutations) + output.Add(input + perm); - return output; - } + return output; + } - List AppendData(List ops, int bits) - { - List output = new List(); - - foreach (var input in ops) - for (int i = 0; i < BinaryExp(bits); i++) - output.Add(input+Convert.ToString(i, 2).PadLeft(bits, '0')); + List AppendData(List ops, int bits) + { + List output = new List(); - return output; - } + foreach (var input in ops) + for (int i = 0; i < BinaryExp(bits); i++) + output.Add(input + Convert.ToString(i, 2).PadLeft(bits, '0')); - int BinaryExp(int bits) - { - int res = 1; - for (int i = 0; i < bits; i++) - res *= 2; - return res; - } + return output; + } - #region Tables + int BinaryExp(int bits) + { + int res = 1; + for (int i = 0; i < bits; i++) + res *= 2; + return res; + } - 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"}; + #region Tables - static readonly string[] Xn3Am3 = { + 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" }; + + static readonly string[] Xn3Am3 = { "000000", // Dn Data register "001000", "010000", @@ -239,9 +239,9 @@ namespace BizHawk.Emulation.CPUs.M68000 "000111", // (xxx).W Absolute Short "001111", // (xxx).L Absolute Long "100111", // #imm Immediate - }; + }; - static readonly string[] Am3Xn3 = { + static readonly string[] Am3Xn3 = { "000000", // Dn Data register "000001", "000010", @@ -312,7 +312,7 @@ namespace BizHawk.Emulation.CPUs.M68000 "111100", // #imm Immediate }; - 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) @@ -329,7 +329,7 @@ namespace BizHawk.Emulation.CPUs.M68000 "1111" // LE Less or Equal (signed) }; - static readonly string[] ConditionAll = { + static readonly string[] ConditionAll = { "0000", // T True "0001", // F False "0010", // HI Higher (unsigned) @@ -348,6 +348,6 @@ namespace BizHawk.Emulation.CPUs.M68000 "1111" // LE Less or Equal (signed) }; - #endregion - } + #endregion + } } \ No newline at end of file diff --git a/BizHawk.Emulation/CPUs/68000/Tables.cs b/BizHawk.Emulation/CPUs/68000/Tables.cs index 01d9600ff7..9a602dd805 100644 --- a/BizHawk.Emulation/CPUs/68000/Tables.cs +++ b/BizHawk.Emulation/CPUs/68000/Tables.cs @@ -1,10 +1,10 @@ -namespace BizHawk.Emulation.CPUs.M68000 +namespace BizHawk.Emulation.Common.Components.M68000 { - partial class MC68000 - { - static readonly int[,] MoveCyclesBW = new int[12,9] - { - { 4, 4, 8, 8, 8, 12, 14, 12, 16 }, + partial class MC68000 + { + 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 }, { 8, 8, 12, 12, 12, 16, 18, 16, 20 }, { 8, 8, 12, 12, 12, 16, 18, 16, 20 }, @@ -16,10 +16,10 @@ { 12, 12, 16, 16, 16, 20, 22, 20, 24 }, { 14, 14, 18, 18, 18, 22, 24, 22, 26 }, { 8, 8, 12, 12, 12, 16, 18, 16, 20 } - }; + }; - 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 }, { 12, 12, 20, 20, 20, 24, 26, 24, 28 }, @@ -32,30 +32,30 @@ { 16, 16, 24, 24, 24, 28, 30, 28, 32 }, { 18, 18, 26, 26, 26, 30, 32, 30, 34 }, { 12, 12, 20, 20, 20, 24, 26, 24, 28 } - }; + }; - static readonly int[,] EACyclesBW = new int[8, 8] - { - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 4, 4, 4, 4, 4, 4, 4, 4 }, - { 4, 4, 4, 4, 4, 4, 4, 4 }, - { 6, 6, 6, 6, 6, 6, 6, 6 }, - { 8, 8, 8, 8, 8, 8, 8, 8 }, - { 10, 10, 10, 10, 10, 10, 10, 10 }, - { 8, 12, 8, 10, 4, 99, 99, 99 } - }; + static readonly int[,] EACyclesBW = new int[8, 8] + { + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 4, 4, 4, 4, 4, 4, 4, 4 }, + { 4, 4, 4, 4, 4, 4, 4, 4 }, + { 6, 6, 6, 6, 6, 6, 6, 6 }, + { 8, 8, 8, 8, 8, 8, 8, 8 }, + { 10, 10, 10, 10, 10, 10, 10, 10 }, + { 8, 12, 8, 10, 4, 99, 99, 99 } + }; - static readonly int[,] EACyclesL = new int[8, 8] - { - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 8, 8, 8, 8, 8, 8, 8, 8 }, - { 8, 8, 8, 8, 8, 8, 8, 8 }, - { 10, 10, 10, 10, 10, 10, 10, 10 }, - { 12, 12, 12, 12, 12, 12, 12, 12 }, - { 14, 14, 14, 14, 14, 14, 14, 14 }, - { 12, 16, 12, 14, 8, 99, 99, 99 } - }; - } + static readonly int[,] EACyclesL = new int[8, 8] + { + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 8, 8, 8, 8, 8, 8, 8, 8 }, + { 8, 8, 8, 8, 8, 8, 8, 8 }, + { 10, 10, 10, 10, 10, 10, 10, 10 }, + { 12, 12, 12, 12, 12, 12, 12, 12 }, + { 14, 14, 14, 14, 14, 14, 14, 14 }, + { 12, 16, 12, 14, 8, 99, 99, 99 } + }; + } } \ No newline at end of file diff --git a/BizHawk.Emulation/CPUs/CP1610/CP1610.cs b/BizHawk.Emulation/CPUs/CP1610/CP1610.cs index 867c34af9f..b995e748cb 100644 --- a/BizHawk.Emulation/CPUs/CP1610/CP1610.cs +++ b/BizHawk.Emulation/CPUs/CP1610/CP1610.cs @@ -1,7 +1,7 @@ using System; using System.IO; -namespace BizHawk.Emulation.CPUs.CP1610 +namespace BizHawk.Emulation.Common.Components.CP1610 { public sealed partial class CP1610 { diff --git a/BizHawk.Emulation/CPUs/CP1610/Disassembler.cs b/BizHawk.Emulation/CPUs/CP1610/Disassembler.cs index 8316b52bef..c76df3f478 100644 --- a/BizHawk.Emulation/CPUs/CP1610/Disassembler.cs +++ b/BizHawk.Emulation/CPUs/CP1610/Disassembler.cs @@ -1,4 +1,4 @@ -namespace BizHawk.Emulation.CPUs.CP1610 +namespace BizHawk.Emulation.Common.Components.CP1610 { public sealed partial class CP1610 { diff --git a/BizHawk.Emulation/CPUs/CP1610/Execute.cs b/BizHawk.Emulation/CPUs/CP1610/Execute.cs index 9c2f5ac5c9..6ac14990e8 100644 --- a/BizHawk.Emulation/CPUs/CP1610/Execute.cs +++ b/BizHawk.Emulation/CPUs/CP1610/Execute.cs @@ -1,6 +1,6 @@ using System; -namespace BizHawk.Emulation.CPUs.CP1610 +namespace BizHawk.Emulation.Common.Components.CP1610 { public sealed partial class CP1610 { diff --git a/BizHawk.Emulation/CPUs/HuC6280/Disassembler.cs b/BizHawk.Emulation/CPUs/HuC6280/Disassembler.cs index 920cebed95..d0356ca4e2 100644 --- a/BizHawk.Emulation/CPUs/HuC6280/Disassembler.cs +++ b/BizHawk.Emulation/CPUs/HuC6280/Disassembler.cs @@ -1,4 +1,4 @@ -namespace BizHawk.Emulation.CPUs.H6280 +namespace BizHawk.Emulation.Common.Components.H6280 // Do not modify this file directly! This is GENERATED code. // Please open the CpuCoreGenerator solution and make your modifications there. diff --git a/BizHawk.Emulation/CPUs/HuC6280/Execute.cs b/BizHawk.Emulation/CPUs/HuC6280/Execute.cs index 645548e41e..d77be38d83 100644 --- a/BizHawk.Emulation/CPUs/HuC6280/Execute.cs +++ b/BizHawk.Emulation/CPUs/HuC6280/Execute.cs @@ -3,7 +3,7 @@ using System; // Do not modify this file directly! This is GENERATED code. // Please open the CpuCoreGenerator solution and make your modifications there. -namespace BizHawk.Emulation.CPUs.H6280 +namespace BizHawk.Emulation.Common.Components.H6280 { public partial class HuC6280 { diff --git a/BizHawk.Emulation/CPUs/HuC6280/HuC6280.cs b/BizHawk.Emulation/CPUs/HuC6280/HuC6280.cs index df717a9628..3f635e63c8 100644 --- a/BizHawk.Emulation/CPUs/HuC6280/HuC6280.cs +++ b/BizHawk.Emulation/CPUs/HuC6280/HuC6280.cs @@ -4,7 +4,7 @@ using System.IO; using BizHawk.Common; -namespace BizHawk.Emulation.CPUs.H6280 +namespace BizHawk.Emulation.Common.Components.H6280 { public sealed partial class HuC6280 { diff --git a/BizHawk.Emulation/CPUs/MOS 6502X/Disassembler.cs b/BizHawk.Emulation/CPUs/MOS 6502X/Disassembler.cs index a19af2860f..ebeb0a772d 100644 --- a/BizHawk.Emulation/CPUs/MOS 6502X/Disassembler.cs +++ b/BizHawk.Emulation/CPUs/MOS 6502X/Disassembler.cs @@ -1,7 +1,7 @@ // Do not modify this file directly! This is GENERATED code. // Please open the CpuCoreGenerator solution and make your modifications there. -namespace BizHawk.Emulation.CPUs.M6502 +namespace BizHawk.Emulation.Common.Components.M6502 { public partial class MOS6502X { diff --git a/BizHawk.Emulation/CPUs/MOS 6502X/Execute.cs b/BizHawk.Emulation/CPUs/MOS 6502X/Execute.cs index 0bd0893c8d..0d3ce95e00 100644 --- a/BizHawk.Emulation/CPUs/MOS 6502X/Execute.cs +++ b/BizHawk.Emulation/CPUs/MOS 6502X/Execute.cs @@ -1,10 +1,9 @@ //http://nesdev.parodius.com/6502_cpu.txt using System; - using BizHawk.Common; -namespace BizHawk.Emulation.CPUs.M6502 +namespace BizHawk.Emulation.Common.Components.M6502 { public partial class MOS6502X { diff --git a/BizHawk.Emulation/CPUs/MOS 6502X/MOS6502X.cs b/BizHawk.Emulation/CPUs/MOS 6502X/MOS6502X.cs index f04539aeda..08bb2f02f5 100644 --- a/BizHawk.Emulation/CPUs/MOS 6502X/MOS6502X.cs +++ b/BizHawk.Emulation/CPUs/MOS 6502X/MOS6502X.cs @@ -3,7 +3,7 @@ using System.IO; using BizHawk.Common; -namespace BizHawk.Emulation.CPUs.M6502 +namespace BizHawk.Emulation.Common.Components.M6502 { public sealed partial class MOS6502X { diff --git a/BizHawk.Emulation/CPUs/MOS 6502X/MOS6502XDouble.cs b/BizHawk.Emulation/CPUs/MOS 6502X/MOS6502XDouble.cs index f4fac02eac..17f0c7db2e 100644 --- a/BizHawk.Emulation/CPUs/MOS 6502X/MOS6502XDouble.cs +++ b/BizHawk.Emulation/CPUs/MOS 6502X/MOS6502XDouble.cs @@ -4,7 +4,7 @@ using System.IO; using BizHawk.Common; -namespace BizHawk.Emulation.CPUs.M6502 +namespace BizHawk.Emulation.Common.Components.M6502 { /// /// maintains a managed 6502X and an unmanaged 6502X, running them alongside and ensuring consistency diff --git a/BizHawk.Emulation/CPUs/MOS 6502X/MOS6502XNative.cs b/BizHawk.Emulation/CPUs/MOS 6502X/MOS6502XNative.cs index 3489311e98..774116d2fa 100644 --- a/BizHawk.Emulation/CPUs/MOS 6502X/MOS6502XNative.cs +++ b/BizHawk.Emulation/CPUs/MOS 6502X/MOS6502XNative.cs @@ -3,7 +3,7 @@ using System.Runtime.InteropServices; using BizHawk.Common; -namespace BizHawk.Emulation.CPUs.M6502 +namespace BizHawk.Emulation.Common.Components.M6502 { public static class MOS6502X_DLL { diff --git a/BizHawk.Emulation/CPUs/Z80-GB/Execute.cs b/BizHawk.Emulation/CPUs/Z80-GB/Execute.cs index 3e347a3042..a53ef53861 100644 --- a/BizHawk.Emulation/CPUs/Z80-GB/Execute.cs +++ b/BizHawk.Emulation/CPUs/Z80-GB/Execute.cs @@ -30,7 +30,7 @@ using System; SRL */ -namespace BizHawk.Emulation.CPUs.Z80GB +namespace BizHawk.Emulation.Common.Components.Z80GB { public partial class Z80 { diff --git a/BizHawk.Emulation/CPUs/Z80-GB/Interrupts.cs b/BizHawk.Emulation/CPUs/Z80-GB/Interrupts.cs index f876089c07..59c76cdc07 100644 --- a/BizHawk.Emulation/CPUs/Z80-GB/Interrupts.cs +++ b/BizHawk.Emulation/CPUs/Z80-GB/Interrupts.cs @@ -1,9 +1,9 @@ using System; -namespace BizHawk.Emulation.CPUs.Z80GB +namespace BizHawk.Emulation.Common.Components.Z80GB { - public partial class Z80 - { + public partial class Z80 + { private bool iff1; public bool IFF1 { get { return iff1; } set { iff1 = value; } } @@ -14,8 +14,8 @@ namespace BizHawk.Emulation.CPUs.Z80GB public bool Interrupt { get { return interrupt; } set { interrupt = value; } } private bool nonMaskableInterrupt; - public bool NonMaskableInterrupt - { + public bool NonMaskableInterrupt + { get { return nonMaskableInterrupt; } set { if (value && !nonMaskableInterrupt) NonMaskableInterruptPending = true; nonMaskableInterrupt = value; } } @@ -24,8 +24,8 @@ namespace BizHawk.Emulation.CPUs.Z80GB public bool NonMaskableInterruptPending { get { return nonMaskableInterruptPending; } set { nonMaskableInterruptPending = value; } } private int interruptMode; - public int InterruptMode - { + public int InterruptMode + { get { return interruptMode; } set { if (value < 0 || value > 2) throw new ArgumentOutOfRangeException(); interruptMode = value; } } @@ -33,8 +33,8 @@ namespace BizHawk.Emulation.CPUs.Z80GB private bool halted; public bool Halted { get { return halted; } set { halted = value; } } - private void ResetInterrupts() - { + private void ResetInterrupts() + { IFF1 = false; IFF2 = false; Interrupt = false; @@ -44,8 +44,8 @@ namespace BizHawk.Emulation.CPUs.Z80GB Halted = false; } - private void Halt() - { + private void Halt() + { Halted = true; } } diff --git a/BizHawk.Emulation/CPUs/Z80-GB/NewDisassembler.cs b/BizHawk.Emulation/CPUs/Z80-GB/NewDisassembler.cs index c8d91f78c7..7b0140aa0a 100644 --- a/BizHawk.Emulation/CPUs/Z80-GB/NewDisassembler.cs +++ b/BizHawk.Emulation/CPUs/Z80-GB/NewDisassembler.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; -namespace BizHawk.Emulation.CPUs.Z80GB +namespace BizHawk.Emulation.Common.Components.Z80GB { // adapted from the information at http://www.pastraiser.com/cpu/gameboy/gameboy_opcodes.html public class NewDisassembler diff --git a/BizHawk.Emulation/CPUs/Z80-GB/Registers.cs b/BizHawk.Emulation/CPUs/Z80-GB/Registers.cs index 4c4fcda434..7466eeba2a 100644 --- a/BizHawk.Emulation/CPUs/Z80-GB/Registers.cs +++ b/BizHawk.Emulation/CPUs/Z80-GB/Registers.cs @@ -1,14 +1,14 @@ using System.Runtime.InteropServices; using System; -namespace BizHawk.Emulation.CPUs.Z80GB +namespace BizHawk.Emulation.Common.Components.Z80GB { - public partial class Z80 - { + public partial class Z80 + { [StructLayout(LayoutKind.Explicit)] [Serializable] - public struct RegisterPair - { + public struct RegisterPair + { [FieldOffset(0)] public ushort Word; @@ -18,44 +18,44 @@ namespace BizHawk.Emulation.CPUs.Z80GB [FieldOffset(1)] public byte High; - public RegisterPair(ushort value) - { + public RegisterPair(ushort value) + { Word = value; Low = (byte)(Word); High = (byte)(Word >> 8); } - public static implicit operator ushort(RegisterPair rp) - { + public static implicit operator ushort(RegisterPair rp) + { return rp.Word; } - public static implicit operator RegisterPair(ushort value) - { + public static implicit operator RegisterPair(ushort value) + { return new RegisterPair(value); } } - public bool FlagC - { + public bool FlagC + { get { return (RegAF.Low & 0x10) != 0; } set { RegAF.Low = (byte)((RegAF.Low & ~0x10) | (value ? 0x10 : 0x00)); } } - public bool FlagH - { + public bool FlagH + { get { return (RegAF.Low & 0x20) != 0; } set { RegAF.Low = (byte)((RegAF.Low & ~0x20) | (value ? 0x20 : 0x00)); } } - public bool FlagN - { + public bool FlagN + { get { return (RegAF.Low & 0x40) != 0; } set { RegAF.Low = (byte)((RegAF.Low & ~0x40) | (value ? 0x40 : 0x00)); } } - public bool FlagZ - { + public bool FlagZ + { get { return (RegAF.Low & 0x80) != 0; } set { RegAF.Low = (byte)((RegAF.Low & ~0x80) | (value ? 0x80 : 0x00)); } } @@ -64,101 +64,101 @@ namespace BizHawk.Emulation.CPUs.Z80GB private RegisterPair RegBC; private RegisterPair RegDE; private RegisterPair RegHL; - + private byte RegI; // I (interrupt vector) private RegisterPair RegSP; // SP (stack pointer) private RegisterPair RegPC; // PC (program counter) - private void ResetRegisters() - { + private void ResetRegisters() + { RegAF = 0; RegBC = 0; RegDE = 0; RegHL = 0; RegI = 0; RegSP.Word = 0; RegPC.Word = 0; } - public byte RegisterA - { + public byte RegisterA + { get { return RegAF.High; } set { RegAF.High = value; } } - public byte RegisterF - { + public byte RegisterF + { get { return RegAF.Low; } - set { RegAF.Low = (byte)(value&0xF0); } + set { RegAF.Low = (byte)(value & 0xF0); } } - public ushort RegisterAF - { + public ushort RegisterAF + { get { return RegAF.Word; } - set { RegAF.Word = (byte)(value&0xFFF0); } + set { RegAF.Word = (byte)(value & 0xFFF0); } } - public byte RegisterB - { + public byte RegisterB + { get { return RegBC.High; } set { RegBC.High = value; } } - public byte RegisterC - { + public byte RegisterC + { get { return RegBC.Low; } set { RegBC.Low = value; } } - public ushort RegisterBC - { + public ushort RegisterBC + { get { return RegBC.Word; } set { RegBC.Word = value; } } - public byte RegisterD - { + public byte RegisterD + { get { return RegDE.High; } set { RegDE.High = value; } } - public byte RegisterE - { + public byte RegisterE + { get { return RegDE.Low; } set { RegDE.Low = value; } } - public ushort RegisterDE - { + public ushort RegisterDE + { get { return RegDE.Word; } set { RegDE.Word = value; } } - public byte RegisterH - { + public byte RegisterH + { get { return RegHL.High; } set { RegHL.High = value; } } - public byte RegisterL - { + public byte RegisterL + { get { return RegHL.Low; } set { RegHL.Low = value; } } - public ushort RegisterHL - { + public ushort RegisterHL + { get { return RegHL.Word; } set { RegHL.Word = value; } } - public ushort RegisterPC - { + public ushort RegisterPC + { get { return RegPC.Word; } set { RegPC.Word = value; } } - public ushort RegisterSP - { + public ushort RegisterSP + { get { return RegSP.Word; } set { RegSP.Word = value; } } - public byte RegisterI - { + public byte RegisterI + { get { return RegI; } set { RegI = value; } } diff --git a/BizHawk.Emulation/CPUs/Z80-GB/Tables.cs b/BizHawk.Emulation/CPUs/Z80-GB/Tables.cs index bc876c7e08..c2597ef028 100644 --- a/BizHawk.Emulation/CPUs/Z80-GB/Tables.cs +++ b/BizHawk.Emulation/CPUs/Z80-GB/Tables.cs @@ -1,149 +1,149 @@ -namespace BizHawk.Emulation.CPUs.Z80GB +namespace BizHawk.Emulation.Common.Components.Z80GB { - public partial class Z80 - { - private void InitializeTables() - { + public partial class Z80 + { + private void InitializeTables() + { InitTableDaa(); } - private static readonly byte[] IncTable = - { - 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - + private static readonly byte[] IncTable = + { + 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + private static readonly byte[] DecTable = - { - 192, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96, - 064, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96, - 064, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96, - 064, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96, - 064, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96, - 064, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96, - 064, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96, - 064, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96, - 064, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96, - 064, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96, - 064, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96, - 064, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96, - 064, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96, - 064, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96, - 064, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96, - 064, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96 - }; + { + 192, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96, + 064, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96, + 064, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96, + 064, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96, + 064, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96, + 064, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96, + 064, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96, + 064, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96, + 064, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96, + 064, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96, + 064, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96, + 064, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96, + 064, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96, + 064, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96, + 064, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96, + 064, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 96 + }; - private static readonly byte[] SwapTable = - { - 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0, - 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1, - 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72, 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2, - 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73, 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3, - 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74, 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4, - 0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75, 0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5, - 0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76, 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6, - 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77, 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7, - 0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78, 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8, - 0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79, 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9, - 0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A, 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA, - 0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B, 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB, - 0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C, 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC, - 0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D, 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD, - 0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E, 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE, - 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F, 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF - }; + private static readonly byte[] SwapTable = + { + 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0, + 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1, + 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72, 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2, + 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73, 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3, + 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74, 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4, + 0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75, 0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5, + 0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76, 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6, + 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77, 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7, + 0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78, 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8, + 0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79, 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9, + 0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A, 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA, + 0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B, 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB, + 0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C, 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC, + 0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D, 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD, + 0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E, 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE, + 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F, 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF + }; - private static readonly byte[] mCycleTable = new byte[] - { - 1, 3, 2, 2, 1, 1, 2, 1, 5, 2, 2, 2, 1, 1, 2, 1, - 1, 3, 2, 2, 1, 1, 2, 1, 3, 2, 2, 2, 1, 1, 2, 1, - 3, 3, 2, 2, 1, 1, 2, 1, 3, 2, 2, 2, 1, 1, 2, 1, - 3, 3, 2, 2, 1, 3, 3, 3, 3, 2, 2, 2, 1, 1, 2, 1, - 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, - 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, - 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, - 2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, - 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, - 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, - 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, - 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, - 5, 3, 4, 4, 6, 4, 2, 4, 5, 4, 4, 1, 6, 6, 2, 4, - 5, 3, 4, 0, 6, 4, 2, 4, 5, 4, 4, 0, 6, 0, 2, 4, - 3, 3, 2, 0, 0, 4, 2, 4, 4, 1, 4, 0, 0, 0, 2, 4, - 3, 3, 2, 1, 0, 4, 2, 4, 3, 2, 4, 1, 0, 0, 2, 4, - }; + private static readonly byte[] mCycleTable = new byte[] + { + 1, 3, 2, 2, 1, 1, 2, 1, 5, 2, 2, 2, 1, 1, 2, 1, + 1, 3, 2, 2, 1, 1, 2, 1, 3, 2, 2, 2, 1, 1, 2, 1, + 3, 3, 2, 2, 1, 1, 2, 1, 3, 2, 2, 2, 1, 1, 2, 1, + 3, 3, 2, 2, 1, 3, 3, 3, 3, 2, 2, 2, 1, 1, 2, 1, + 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, + 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, + 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, + 2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, + 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, + 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, + 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, + 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, + 5, 3, 4, 4, 6, 4, 2, 4, 5, 4, 4, 1, 6, 6, 2, 4, + 5, 3, 4, 0, 6, 4, 2, 4, 5, 4, 4, 0, 6, 0, 2, 4, + 3, 3, 2, 0, 0, 4, 2, 4, 4, 1, 4, 0, 0, 0, 2, 4, + 3, 3, 2, 1, 0, 4, 2, 4, 3, 2, 4, 1, 0, 0, 2, 4, + }; - private static readonly byte[] cbMCycleTable = new byte[] - { - 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, - 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, - 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, - 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, - 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2, - 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2, - 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2, - 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2, - 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, - 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, - 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, - 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, - 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, - 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, - 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, - 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, - }; + private static readonly byte[] cbMCycleTable = new byte[] + { + 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, + 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, + 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, + 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, + 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2, + 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2, + 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2, + 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2, + 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, + 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, + 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, + 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, + 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, + 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, + 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, + 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, + }; - private ushort[] TableDaa; - private void InitTableDaa() - { - TableDaa = new ushort[65536]; - for (int af = 0; af < 65536; ++af) - { - byte a = (byte)(af >> 8); - byte tmp = a; + private ushort[] TableDaa; + private void InitTableDaa() + { + TableDaa = new ushort[65536]; + for (int af = 0; af < 65536; ++af) + { + byte a = (byte)(af >> 8); + byte tmp = a; - if (IsN(af)) - { - if (IsH(af) || ((a & 0x0F) > 0x09)) tmp -= 0x06; - if (IsC(af) || a > 0x99) tmp -= 0x60; - } - else - { - if (IsH(af) || ((a & 0x0F) > 0x09)) tmp += 0x06; - if (IsC(af) || a > 0x99) tmp += 0x60; - } + if (IsN(af)) + { + if (IsH(af) || ((a & 0x0F) > 0x09)) tmp -= 0x06; + if (IsC(af) || a > 0x99) tmp -= 0x60; + } + else + { + if (IsH(af) || ((a & 0x0F) > 0x09)) tmp += 0x06; + if (IsC(af) || a > 0x99) tmp += 0x60; + } - TableDaa[af] = (ushort)((tmp * 256) + FlagByte(IsC(af) || a > 0x99, ((a ^ tmp) & 0x10) != 0, IsN(af), tmp == 0)); - } - } + TableDaa[af] = (ushort)((tmp * 256) + FlagByte(IsC(af) || a > 0x99, ((a ^ tmp) & 0x10) != 0, IsN(af), tmp == 0)); + } + } - private static byte FlagByte(bool C, bool H, bool N, bool Z) - { + private static byte FlagByte(bool C, bool H, bool N, bool Z) + { return (byte)( (C ? 0x10 : 0) + (H ? 0x20 : 0) + - (N ? 0x40 : 0) + + (N ? 0x40 : 0) + (Z ? 0x80 : 0) ); } private static bool IsC(int value) { return (value & 0x10) != 0; } - private static bool IsH(int value) { return (value & 0x20) != 0; } - private static bool IsN(int value) { return (value & 0x40) != 0; } + private static bool IsH(int value) { return (value & 0x20) != 0; } + private static bool IsN(int value) { return (value & 0x40) != 0; } private static bool IsZ(int value) { return (value & 0x80) != 0; } } } diff --git a/BizHawk.Emulation/CPUs/Z80-GB/Z80.cs b/BizHawk.Emulation/CPUs/Z80-GB/Z80.cs index 39f709ad06..eb9842c806 100644 --- a/BizHawk.Emulation/CPUs/Z80-GB/Z80.cs +++ b/BizHawk.Emulation/CPUs/Z80-GB/Z80.cs @@ -5,7 +5,7 @@ using System.IO; // This Z80-Gameboy emulator is a modified version of Ben Ryves 'Brazil' emulator. // It is MIT licensed (not public domain). (See Licenses) -namespace BizHawk.Emulation.CPUs.Z80GB +namespace BizHawk.Emulation.Common.Components.Z80GB { public sealed partial class Z80 { diff --git a/BizHawk.Emulation/CPUs/Z80/Disassembler.cs b/BizHawk.Emulation/CPUs/Z80/Disassembler.cs index 00502bee81..a39dbb5aae 100644 --- a/BizHawk.Emulation/CPUs/Z80/Disassembler.cs +++ b/BizHawk.Emulation/CPUs/Z80/Disassembler.cs @@ -12,7 +12,7 @@ using System; -namespace BizHawk.Emulation.CPUs.Z80 +namespace BizHawk.Emulation.Common.Components.Z80 { public class Disassembler { diff --git a/BizHawk.Emulation/CPUs/Z80/Execute.cs b/BizHawk.Emulation/CPUs/Z80/Execute.cs index 75912faa77..3f14e36e1a 100644 --- a/BizHawk.Emulation/CPUs/Z80/Execute.cs +++ b/BizHawk.Emulation/CPUs/Z80/Execute.cs @@ -1,9 +1,9 @@ using System; -namespace BizHawk.Emulation.CPUs.Z80 +namespace BizHawk.Emulation.Common.Components.Z80 { - public partial class Z80A - { + public partial class Z80A + { private int totalExecutedCycles; public int TotalExecutedCycles { get { return totalExecutedCycles; } set { totalExecutedCycles = value; } } @@ -13,42 +13,44 @@ namespace BizHawk.Emulation.CPUs.Z80 private int pendingCycles; public int PendingCycles { get { return pendingCycles; } set { pendingCycles = value; } } - public bool Debug; - public Action Logger; + public bool Debug; + public Action Logger; /// /// Runs the CPU for a particular number of clock cycles. /// /// The number of cycles to run the CPU emulator for. Specify -1 to run for a single instruction. - public void ExecuteCycles(int cycles) - { - expectedExecutedCycles += cycles; + public void ExecuteCycles(int cycles) + { + expectedExecutedCycles += cycles; pendingCycles += cycles; - + sbyte Displacement; - + byte TB; byte TBH; byte TBL; byte TB1; byte TB2; sbyte TSB; ushort TUS; int TI1; int TI2; int TIR; bool Interruptable; - while (pendingCycles > 0) - { - Interruptable = true; + while (pendingCycles > 0) + { + Interruptable = true; if (halted) - { + { - ++RegR; + ++RegR; totalExecutedCycles += 4; pendingCycles -= 4; - } else { + } + else + { - if (Debug) - Logger(State()); - - ++RegR; - switch (ReadMemory(RegPC.Word++)) - { + if (Debug) + Logger(State()); + + ++RegR; + switch (ReadMemory(RegPC.Word++)) + { case 0x00: // NOP totalExecutedCycles += 4; pendingCycles -= 4; break; @@ -121,10 +123,13 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0x10: // DJNZ d TSB = (sbyte)ReadMemory(RegPC.Word++); - if (--RegBC.High != 0) { + if (--RegBC.High != 0) + { RegPC.Word = (ushort)(RegPC.Word + TSB); totalExecutedCycles += 13; pendingCycles -= 13; - } else { + } + else + { totalExecutedCycles += 8; pendingCycles -= 8; } break; @@ -159,7 +164,7 @@ namespace BizHawk.Emulation.CPUs.Z80 case 0x18: // JR d TSB = (sbyte)ReadMemory(RegPC.Word++); RegPC.Word = (ushort)(RegPC.Word + TSB); - totalExecutedCycles += 12; pendingCycles -= 12; + totalExecutedCycles += 12; pendingCycles -= 12; break; case 0x19: // ADD HL, DE TI1 = (short)RegHL.Word; TI2 = (short)RegDE.Word; TIR = TI1 + TI2; @@ -198,10 +203,13 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0x20: // JR NZ, d TSB = (sbyte)ReadMemory(RegPC.Word++); - if (!RegFlagZ) { + if (!RegFlagZ) + { RegPC.Word = (ushort)(RegPC.Word + TSB); totalExecutedCycles += 12; pendingCycles -= 12; - } else { + } + else + { totalExecutedCycles += 7; pendingCycles -= 7; } break; @@ -237,10 +245,13 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0x28: // JR Z, d TSB = (sbyte)ReadMemory(RegPC.Word++); - if (RegFlagZ) { + if (RegFlagZ) + { RegPC.Word = (ushort)(RegPC.Word + TSB); totalExecutedCycles += 12; pendingCycles -= 12; - } else { + } + else + { totalExecutedCycles += 7; pendingCycles -= 7; } break; @@ -282,10 +293,13 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0x30: // JR NC, d TSB = (sbyte)ReadMemory(RegPC.Word++); - if (!RegFlagC) { + if (!RegFlagC) + { RegPC.Word = (ushort)(RegPC.Word + TSB); totalExecutedCycles += 12; pendingCycles -= 12; - } else { + } + else + { totalExecutedCycles += 7; pendingCycles -= 7; } break; @@ -319,10 +333,13 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0x38: // JR C, d TSB = (sbyte)ReadMemory(RegPC.Word++); - if (RegFlagC) { + if (RegFlagC) + { RegPC.Word = (ushort)(RegPC.Word + TSB); totalExecutedCycles += 12; pendingCycles -= 12; - } else { + } + else + { totalExecutedCycles += 7; pendingCycles -= 7; } break; @@ -867,10 +884,13 @@ namespace BizHawk.Emulation.CPUs.Z80 totalExecutedCycles += 4; pendingCycles -= 4; break; case 0xC0: // RET NZ - if (!RegFlagZ) { + if (!RegFlagZ) + { RegPC.Low = ReadMemory(RegSP.Word++); RegPC.High = ReadMemory(RegSP.Word++); totalExecutedCycles += 11; pendingCycles -= 11; - } else { + } + else + { totalExecutedCycles += 5; pendingCycles -= 5; } break; @@ -880,7 +900,8 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xC2: // JP NZ, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (!RegFlagZ) { + if (!RegFlagZ) + { RegPC.Word = TUS; } totalExecutedCycles += 10; pendingCycles -= 10; @@ -891,11 +912,14 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xC4: // CALL NZ, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (!RegFlagZ) { + if (!RegFlagZ) + { WriteMemory(--RegSP.Word, RegPC.High); WriteMemory(--RegSP.Word, RegPC.Low); RegPC.Word = TUS; totalExecutedCycles += 17; pendingCycles -= 17; - } else { + } + else + { totalExecutedCycles += 10; pendingCycles -= 10; } break; @@ -913,10 +937,13 @@ namespace BizHawk.Emulation.CPUs.Z80 totalExecutedCycles += 11; pendingCycles -= 11; break; case 0xC8: // RET Z - if (RegFlagZ) { + if (RegFlagZ) + { RegPC.Low = ReadMemory(RegSP.Word++); RegPC.High = ReadMemory(RegSP.Word++); totalExecutedCycles += 11; pendingCycles -= 11; - } else { + } + else + { totalExecutedCycles += 5; pendingCycles -= 5; } break; @@ -926,14 +953,16 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xCA: // JP Z, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (RegFlagZ) { + if (RegFlagZ) + { RegPC.Word = TUS; } totalExecutedCycles += 10; pendingCycles -= 10; break; case 0xCB: // (Prefix) ++RegR; - switch (ReadMemory(RegPC.Word++)) { + switch (ReadMemory(RegPC.Word++)) + { case 0x00: // RLC B TUS = TableRotShift[1, 0, RegAF.Low + 256 * RegBC.High]; RegBC.High = (byte)(TUS >> 8); @@ -2474,11 +2503,14 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xCC: // CALL Z, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (RegFlagZ) { + if (RegFlagZ) + { WriteMemory(--RegSP.Word, RegPC.High); WriteMemory(--RegSP.Word, RegPC.Low); RegPC.Word = TUS; totalExecutedCycles += 17; pendingCycles -= 17; - } else { + } + else + { totalExecutedCycles += 10; pendingCycles -= 10; } break; @@ -2498,10 +2530,13 @@ namespace BizHawk.Emulation.CPUs.Z80 totalExecutedCycles += 11; pendingCycles -= 11; break; case 0xD0: // RET NC - if (!RegFlagC) { + if (!RegFlagC) + { RegPC.Low = ReadMemory(RegSP.Word++); RegPC.High = ReadMemory(RegSP.Word++); totalExecutedCycles += 11; pendingCycles -= 11; - } else { + } + else + { totalExecutedCycles += 5; pendingCycles -= 5; } break; @@ -2511,7 +2546,8 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xD2: // JP NC, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (!RegFlagC) { + if (!RegFlagC) + { RegPC.Word = TUS; } totalExecutedCycles += 10; pendingCycles -= 10; @@ -2522,11 +2558,14 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xD4: // CALL NC, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (!RegFlagC) { + if (!RegFlagC) + { WriteMemory(--RegSP.Word, RegPC.High); WriteMemory(--RegSP.Word, RegPC.Low); RegPC.Word = TUS; totalExecutedCycles += 17; pendingCycles -= 17; - } else { + } + else + { totalExecutedCycles += 10; pendingCycles -= 10; } break; @@ -2544,10 +2583,13 @@ namespace BizHawk.Emulation.CPUs.Z80 totalExecutedCycles += 11; pendingCycles -= 11; break; case 0xD8: // RET C - if (RegFlagC) { + if (RegFlagC) + { RegPC.Low = ReadMemory(RegSP.Word++); RegPC.High = ReadMemory(RegSP.Word++); totalExecutedCycles += 11; pendingCycles -= 11; - } else { + } + else + { totalExecutedCycles += 5; pendingCycles -= 5; } break; @@ -2559,7 +2601,8 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xDA: // JP C, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (RegFlagC) { + if (RegFlagC) + { RegPC.Word = TUS; } totalExecutedCycles += 10; pendingCycles -= 10; @@ -2570,17 +2613,21 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xDC: // CALL C, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (RegFlagC) { + if (RegFlagC) + { WriteMemory(--RegSP.Word, RegPC.High); WriteMemory(--RegSP.Word, RegPC.Low); RegPC.Word = TUS; totalExecutedCycles += 17; pendingCycles -= 17; - } else { + } + else + { totalExecutedCycles += 10; pendingCycles -= 10; } break; case 0xDD: // (Prefix) ++RegR; - switch (ReadMemory(RegPC.Word++)) { + switch (ReadMemory(RegPC.Word++)) + { case 0x00: // NOP totalExecutedCycles += 4; pendingCycles -= 4; break; @@ -2653,10 +2700,13 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0x10: // DJNZ d TSB = (sbyte)ReadMemory(RegPC.Word++); - if (--RegBC.High != 0) { + if (--RegBC.High != 0) + { RegPC.Word = (ushort)(RegPC.Word + TSB); totalExecutedCycles += 13; pendingCycles -= 13; - } else { + } + else + { totalExecutedCycles += 8; pendingCycles -= 8; } break; @@ -2691,7 +2741,7 @@ namespace BizHawk.Emulation.CPUs.Z80 case 0x18: // JR d TSB = (sbyte)ReadMemory(RegPC.Word++); RegPC.Word = (ushort)(RegPC.Word + TSB); - totalExecutedCycles += 12; pendingCycles -= 12; + totalExecutedCycles += 12; pendingCycles -= 12; break; case 0x19: // ADD IX, DE TI1 = (short)RegIX.Word; TI2 = (short)RegDE.Word; TIR = TI1 + TI2; @@ -2730,10 +2780,13 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0x20: // JR NZ, d TSB = (sbyte)ReadMemory(RegPC.Word++); - if (!RegFlagZ) { + if (!RegFlagZ) + { RegPC.Word = (ushort)(RegPC.Word + TSB); totalExecutedCycles += 12; pendingCycles -= 12; - } else { + } + else + { totalExecutedCycles += 7; pendingCycles -= 7; } break; @@ -2769,10 +2822,13 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0x28: // JR Z, d TSB = (sbyte)ReadMemory(RegPC.Word++); - if (RegFlagZ) { + if (RegFlagZ) + { RegPC.Word = (ushort)(RegPC.Word + TSB); totalExecutedCycles += 12; pendingCycles -= 12; - } else { + } + else + { totalExecutedCycles += 7; pendingCycles -= 7; } break; @@ -2814,10 +2870,13 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0x30: // JR NC, d TSB = (sbyte)ReadMemory(RegPC.Word++); - if (!RegFlagC) { + if (!RegFlagC) + { RegPC.Word = (ushort)(RegPC.Word + TSB); totalExecutedCycles += 12; pendingCycles -= 12; - } else { + } + else + { totalExecutedCycles += 7; pendingCycles -= 7; } break; @@ -2854,10 +2913,13 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0x38: // JR C, d TSB = (sbyte)ReadMemory(RegPC.Word++); - if (RegFlagC) { + if (RegFlagC) + { RegPC.Word = (ushort)(RegPC.Word + TSB); totalExecutedCycles += 12; pendingCycles -= 12; - } else { + } + else + { totalExecutedCycles += 7; pendingCycles -= 7; } break; @@ -3424,10 +3486,13 @@ namespace BizHawk.Emulation.CPUs.Z80 totalExecutedCycles += 4; pendingCycles -= 4; break; case 0xC0: // RET NZ - if (!RegFlagZ) { + if (!RegFlagZ) + { RegPC.Low = ReadMemory(RegSP.Word++); RegPC.High = ReadMemory(RegSP.Word++); totalExecutedCycles += 11; pendingCycles -= 11; - } else { + } + else + { totalExecutedCycles += 5; pendingCycles -= 5; } break; @@ -3437,7 +3502,8 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xC2: // JP NZ, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (!RegFlagZ) { + if (!RegFlagZ) + { RegPC.Word = TUS; } totalExecutedCycles += 10; pendingCycles -= 10; @@ -3448,11 +3514,14 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xC4: // CALL NZ, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (!RegFlagZ) { + if (!RegFlagZ) + { WriteMemory(--RegSP.Word, RegPC.High); WriteMemory(--RegSP.Word, RegPC.Low); RegPC.Word = TUS; totalExecutedCycles += 17; pendingCycles -= 17; - } else { + } + else + { totalExecutedCycles += 10; pendingCycles -= 10; } break; @@ -3470,10 +3539,13 @@ namespace BizHawk.Emulation.CPUs.Z80 totalExecutedCycles += 11; pendingCycles -= 11; break; case 0xC8: // RET Z - if (RegFlagZ) { + if (RegFlagZ) + { RegPC.Low = ReadMemory(RegSP.Word++); RegPC.High = ReadMemory(RegSP.Word++); totalExecutedCycles += 11; pendingCycles -= 11; - } else { + } + else + { totalExecutedCycles += 5; pendingCycles -= 5; } break; @@ -3483,7 +3555,8 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xCA: // JP Z, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (RegFlagZ) { + if (RegFlagZ) + { RegPC.Word = TUS; } totalExecutedCycles += 10; pendingCycles -= 10; @@ -3491,7 +3564,8 @@ namespace BizHawk.Emulation.CPUs.Z80 case 0xCB: // (Prefix) Displacement = (sbyte)ReadMemory(RegPC.Word++); ++RegR; - switch (ReadMemory(RegPC.Word++)) { + switch (ReadMemory(RegPC.Word++)) + { case 0x00: // RLC (IX+d)→B TUS = TableRotShift[1, 0, RegAF.Low + 256 * ReadMemory((ushort)(RegIX.Word + Displacement))]; WriteMemory((ushort)(RegIX.Word + Displacement), (byte)(TUS >> 8)); @@ -5072,11 +5146,14 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xCC: // CALL Z, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (RegFlagZ) { + if (RegFlagZ) + { WriteMemory(--RegSP.Word, RegPC.High); WriteMemory(--RegSP.Word, RegPC.Low); RegPC.Word = TUS; totalExecutedCycles += 17; pendingCycles -= 17; - } else { + } + else + { totalExecutedCycles += 10; pendingCycles -= 10; } break; @@ -5096,10 +5173,13 @@ namespace BizHawk.Emulation.CPUs.Z80 totalExecutedCycles += 11; pendingCycles -= 11; break; case 0xD0: // RET NC - if (!RegFlagC) { + if (!RegFlagC) + { RegPC.Low = ReadMemory(RegSP.Word++); RegPC.High = ReadMemory(RegSP.Word++); totalExecutedCycles += 11; pendingCycles -= 11; - } else { + } + else + { totalExecutedCycles += 5; pendingCycles -= 5; } break; @@ -5109,7 +5189,8 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xD2: // JP NC, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (!RegFlagC) { + if (!RegFlagC) + { RegPC.Word = TUS; } totalExecutedCycles += 10; pendingCycles -= 10; @@ -5120,11 +5201,14 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xD4: // CALL NC, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (!RegFlagC) { + if (!RegFlagC) + { WriteMemory(--RegSP.Word, RegPC.High); WriteMemory(--RegSP.Word, RegPC.Low); RegPC.Word = TUS; totalExecutedCycles += 17; pendingCycles -= 17; - } else { + } + else + { totalExecutedCycles += 10; pendingCycles -= 10; } break; @@ -5142,10 +5226,13 @@ namespace BizHawk.Emulation.CPUs.Z80 totalExecutedCycles += 11; pendingCycles -= 11; break; case 0xD8: // RET C - if (RegFlagC) { + if (RegFlagC) + { RegPC.Low = ReadMemory(RegSP.Word++); RegPC.High = ReadMemory(RegSP.Word++); totalExecutedCycles += 11; pendingCycles -= 11; - } else { + } + else + { totalExecutedCycles += 5; pendingCycles -= 5; } break; @@ -5157,7 +5244,8 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xDA: // JP C, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (RegFlagC) { + if (RegFlagC) + { RegPC.Word = TUS; } totalExecutedCycles += 10; pendingCycles -= 10; @@ -5168,11 +5256,14 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xDC: // CALL C, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (RegFlagC) { + if (RegFlagC) + { WriteMemory(--RegSP.Word, RegPC.High); WriteMemory(--RegSP.Word, RegPC.Low); RegPC.Word = TUS; totalExecutedCycles += 17; pendingCycles -= 17; - } else { + } + else + { totalExecutedCycles += 10; pendingCycles -= 10; } break; @@ -5190,10 +5281,13 @@ namespace BizHawk.Emulation.CPUs.Z80 totalExecutedCycles += 11; pendingCycles -= 11; break; case 0xE0: // RET PO - if (!RegFlagP) { + if (!RegFlagP) + { RegPC.Low = ReadMemory(RegSP.Word++); RegPC.High = ReadMemory(RegSP.Word++); totalExecutedCycles += 11; pendingCycles -= 11; - } else { + } + else + { totalExecutedCycles += 5; pendingCycles -= 5; } break; @@ -5203,7 +5297,8 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xE2: // JP PO, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (!RegFlagP) { + if (!RegFlagP) + { RegPC.Word = TUS; } totalExecutedCycles += 10; pendingCycles -= 10; @@ -5216,11 +5311,14 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xE4: // CALL C, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (RegFlagC) { + if (RegFlagC) + { WriteMemory(--RegSP.Word, RegPC.High); WriteMemory(--RegSP.Word, RegPC.Low); RegPC.Word = TUS; totalExecutedCycles += 17; pendingCycles -= 17; - } else { + } + else + { totalExecutedCycles += 10; pendingCycles -= 10; } break; @@ -5238,10 +5336,13 @@ namespace BizHawk.Emulation.CPUs.Z80 totalExecutedCycles += 11; pendingCycles -= 11; break; case 0xE8: // RET PE - if (RegFlagP) { + if (RegFlagP) + { RegPC.Low = ReadMemory(RegSP.Word++); RegPC.High = ReadMemory(RegSP.Word++); totalExecutedCycles += 11; pendingCycles -= 11; - } else { + } + else + { totalExecutedCycles += 5; pendingCycles -= 5; } break; @@ -5251,7 +5352,8 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xEA: // JP PE, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (RegFlagP) { + if (RegFlagP) + { RegPC.Word = TUS; } totalExecutedCycles += 10; pendingCycles -= 10; @@ -5262,17 +5364,21 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xEC: // CALL PE, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (RegFlagP) { + if (RegFlagP) + { WriteMemory(--RegSP.Word, RegPC.High); WriteMemory(--RegSP.Word, RegPC.Low); RegPC.Word = TUS; totalExecutedCycles += 17; pendingCycles -= 17; - } else { + } + else + { totalExecutedCycles += 10; pendingCycles -= 10; } break; case 0xED: // (Prefix) ++RegR; - switch (ReadMemory(RegPC.Word++)) { + switch (ReadMemory(RegPC.Word++)) + { case 0x00: // NOP totalExecutedCycles += 4; pendingCycles -= 4; break; @@ -6086,10 +6192,13 @@ namespace BizHawk.Emulation.CPUs.Z80 RegFlagP = RegBC.Word != 0; RegFlagH = false; RegFlagN = false; - if (RegBC.Word != 0) { + if (RegBC.Word != 0) + { RegPC.Word -= 2; totalExecutedCycles += 21; pendingCycles -= 21; - } else { + } + else + { totalExecutedCycles += 16; pendingCycles -= 16; } break; @@ -6102,10 +6211,13 @@ namespace BizHawk.Emulation.CPUs.Z80 TB1 = (byte)(RegAF.High - TB1 - (RegFlagH ? 1 : 0)); RegFlag5 = (TB1 & 0x02) != 0; RegFlag3 = (TB1 & 0x08) != 0; --RegBC.Word; RegFlagP = RegBC.Word != 0; - if (RegBC.Word != 0 && !RegFlagZ) { + if (RegBC.Word != 0 && !RegFlagZ) + { RegPC.Word -= 2; totalExecutedCycles += 21; pendingCycles -= 21; - } else { + } + else + { totalExecutedCycles += 16; pendingCycles -= 16; } break; @@ -6114,10 +6226,13 @@ namespace BizHawk.Emulation.CPUs.Z80 --RegBC.High; RegFlagZ = RegBC.High == 0; RegFlagN = true; - if (RegBC.High != 0) { + if (RegBC.High != 0) + { RegPC.Word -= 2; totalExecutedCycles += 21; pendingCycles -= 21; - } else { + } + else + { totalExecutedCycles += 16; pendingCycles -= 16; } break; @@ -6126,10 +6241,13 @@ namespace BizHawk.Emulation.CPUs.Z80 --RegBC.High; RegFlagZ = RegBC.High == 0; RegFlagN = true; - if (RegBC.High != 0) { + if (RegBC.High != 0) + { RegPC.Word -= 2; totalExecutedCycles += 21; pendingCycles -= 21; - } else { + } + else + { totalExecutedCycles += 16; pendingCycles -= 16; } break; @@ -6152,10 +6270,13 @@ namespace BizHawk.Emulation.CPUs.Z80 RegFlagP = RegBC.Word != 0; RegFlagH = false; RegFlagN = false; - if (RegBC.Word != 0) { + if (RegBC.Word != 0) + { RegPC.Word -= 2; totalExecutedCycles += 21; pendingCycles -= 21; - } else { + } + else + { totalExecutedCycles += 16; pendingCycles -= 16; } break; @@ -6168,10 +6289,13 @@ namespace BizHawk.Emulation.CPUs.Z80 TB1 = (byte)(RegAF.High - TB1 - (RegFlagH ? 1 : 0)); RegFlag5 = (TB1 & 0x02) != 0; RegFlag3 = (TB1 & 0x08) != 0; --RegBC.Word; RegFlagP = RegBC.Word != 0; - if (RegBC.Word != 0 && !RegFlagZ) { + if (RegBC.Word != 0 && !RegFlagZ) + { RegPC.Word -= 2; totalExecutedCycles += 21; pendingCycles -= 21; - } else { + } + else + { totalExecutedCycles += 16; pendingCycles -= 16; } break; @@ -6180,10 +6304,13 @@ namespace BizHawk.Emulation.CPUs.Z80 --RegBC.High; RegFlagZ = RegBC.High == 0; RegFlagN = true; - if (RegBC.High != 0) { + if (RegBC.High != 0) + { RegPC.Word -= 2; totalExecutedCycles += 21; pendingCycles -= 21; - } else { + } + else + { totalExecutedCycles += 16; pendingCycles -= 16; } break; @@ -6192,10 +6319,13 @@ namespace BizHawk.Emulation.CPUs.Z80 --RegBC.High; RegFlagZ = RegBC.High == 0; RegFlagN = true; - if (RegBC.High != 0) { + if (RegBC.High != 0) + { RegPC.Word -= 2; totalExecutedCycles += 21; pendingCycles -= 21; - } else { + } + else + { totalExecutedCycles += 16; pendingCycles -= 16; } break; @@ -6415,10 +6545,13 @@ namespace BizHawk.Emulation.CPUs.Z80 totalExecutedCycles += 11; pendingCycles -= 11; break; case 0xF0: // RET P - if (!RegFlagS) { + if (!RegFlagS) + { RegPC.Low = ReadMemory(RegSP.Word++); RegPC.High = ReadMemory(RegSP.Word++); totalExecutedCycles += 11; pendingCycles -= 11; - } else { + } + else + { totalExecutedCycles += 5; pendingCycles -= 5; } break; @@ -6428,7 +6561,8 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xF2: // JP P, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (!RegFlagS) { + if (!RegFlagS) + { RegPC.Word = TUS; } totalExecutedCycles += 10; pendingCycles -= 10; @@ -6439,11 +6573,14 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xF4: // CALL P, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (!RegFlagS) { + if (!RegFlagS) + { WriteMemory(--RegSP.Word, RegPC.High); WriteMemory(--RegSP.Word, RegPC.Low); RegPC.Word = TUS; totalExecutedCycles += 17; pendingCycles -= 17; - } else { + } + else + { totalExecutedCycles += 10; pendingCycles -= 10; } break; @@ -6461,10 +6598,13 @@ namespace BizHawk.Emulation.CPUs.Z80 totalExecutedCycles += 11; pendingCycles -= 11; break; case 0xF8: // RET M - if (RegFlagS) { + if (RegFlagS) + { RegPC.Low = ReadMemory(RegSP.Word++); RegPC.High = ReadMemory(RegSP.Word++); totalExecutedCycles += 11; pendingCycles -= 11; - } else { + } + else + { totalExecutedCycles += 5; pendingCycles -= 5; } break; @@ -6474,7 +6614,8 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xFA: // JP M, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (RegFlagS) { + if (RegFlagS) + { RegPC.Word = TUS; } totalExecutedCycles += 10; pendingCycles -= 10; @@ -6486,11 +6627,14 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xFC: // CALL M, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (RegFlagS) { + if (RegFlagS) + { WriteMemory(--RegSP.Word, RegPC.High); WriteMemory(--RegSP.Word, RegPC.Low); RegPC.Word = TUS; totalExecutedCycles += 17; pendingCycles -= 17; - } else { + } + else + { totalExecutedCycles += 10; pendingCycles -= 10; } break; @@ -6519,10 +6663,13 @@ namespace BizHawk.Emulation.CPUs.Z80 totalExecutedCycles += 11; pendingCycles -= 11; break; case 0xE0: // RET PO - if (!RegFlagP) { + if (!RegFlagP) + { RegPC.Low = ReadMemory(RegSP.Word++); RegPC.High = ReadMemory(RegSP.Word++); totalExecutedCycles += 11; pendingCycles -= 11; - } else { + } + else + { totalExecutedCycles += 5; pendingCycles -= 5; } break; @@ -6532,7 +6679,8 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xE2: // JP PO, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (!RegFlagP) { + if (!RegFlagP) + { RegPC.Word = TUS; } totalExecutedCycles += 10; pendingCycles -= 10; @@ -6545,11 +6693,14 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xE4: // CALL C, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (RegFlagC) { + if (RegFlagC) + { WriteMemory(--RegSP.Word, RegPC.High); WriteMemory(--RegSP.Word, RegPC.Low); RegPC.Word = TUS; totalExecutedCycles += 17; pendingCycles -= 17; - } else { + } + else + { totalExecutedCycles += 10; pendingCycles -= 10; } break; @@ -6567,10 +6718,13 @@ namespace BizHawk.Emulation.CPUs.Z80 totalExecutedCycles += 11; pendingCycles -= 11; break; case 0xE8: // RET PE - if (RegFlagP) { + if (RegFlagP) + { RegPC.Low = ReadMemory(RegSP.Word++); RegPC.High = ReadMemory(RegSP.Word++); totalExecutedCycles += 11; pendingCycles -= 11; - } else { + } + else + { totalExecutedCycles += 5; pendingCycles -= 5; } break; @@ -6580,7 +6734,8 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xEA: // JP PE, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (RegFlagP) { + if (RegFlagP) + { RegPC.Word = TUS; } totalExecutedCycles += 10; pendingCycles -= 10; @@ -6591,17 +6746,21 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xEC: // CALL PE, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (RegFlagP) { + if (RegFlagP) + { WriteMemory(--RegSP.Word, RegPC.High); WriteMemory(--RegSP.Word, RegPC.Low); RegPC.Word = TUS; totalExecutedCycles += 17; pendingCycles -= 17; - } else { + } + else + { totalExecutedCycles += 10; pendingCycles -= 10; } break; case 0xED: // (Prefix) ++RegR; - switch (ReadMemory(RegPC.Word++)) { + switch (ReadMemory(RegPC.Word++)) + { case 0x00: // NOP totalExecutedCycles += 4; pendingCycles -= 4; break; @@ -7415,10 +7574,13 @@ namespace BizHawk.Emulation.CPUs.Z80 RegFlagP = RegBC.Word != 0; RegFlagH = false; RegFlagN = false; - if (RegBC.Word != 0) { + if (RegBC.Word != 0) + { RegPC.Word -= 2; totalExecutedCycles += 21; pendingCycles -= 21; - } else { + } + else + { totalExecutedCycles += 16; pendingCycles -= 16; } break; @@ -7431,10 +7593,13 @@ namespace BizHawk.Emulation.CPUs.Z80 TB1 = (byte)(RegAF.High - TB1 - (RegFlagH ? 1 : 0)); RegFlag5 = (TB1 & 0x02) != 0; RegFlag3 = (TB1 & 0x08) != 0; --RegBC.Word; RegFlagP = RegBC.Word != 0; - if (RegBC.Word != 0 && !RegFlagZ) { + if (RegBC.Word != 0 && !RegFlagZ) + { RegPC.Word -= 2; totalExecutedCycles += 21; pendingCycles -= 21; - } else { + } + else + { totalExecutedCycles += 16; pendingCycles -= 16; } break; @@ -7443,10 +7608,13 @@ namespace BizHawk.Emulation.CPUs.Z80 --RegBC.High; RegFlagZ = RegBC.High == 0; RegFlagN = true; - if (RegBC.High != 0) { + if (RegBC.High != 0) + { RegPC.Word -= 2; totalExecutedCycles += 21; pendingCycles -= 21; - } else { + } + else + { totalExecutedCycles += 16; pendingCycles -= 16; } break; @@ -7455,10 +7623,13 @@ namespace BizHawk.Emulation.CPUs.Z80 --RegBC.High; RegFlagZ = RegBC.High == 0; RegFlagN = true; - if (RegBC.High != 0) { + if (RegBC.High != 0) + { RegPC.Word -= 2; totalExecutedCycles += 21; pendingCycles -= 21; - } else { + } + else + { totalExecutedCycles += 16; pendingCycles -= 16; } break; @@ -7481,10 +7652,13 @@ namespace BizHawk.Emulation.CPUs.Z80 RegFlagP = RegBC.Word != 0; RegFlagH = false; RegFlagN = false; - if (RegBC.Word != 0) { + if (RegBC.Word != 0) + { RegPC.Word -= 2; totalExecutedCycles += 21; pendingCycles -= 21; - } else { + } + else + { totalExecutedCycles += 16; pendingCycles -= 16; } break; @@ -7497,10 +7671,13 @@ namespace BizHawk.Emulation.CPUs.Z80 TB1 = (byte)(RegAF.High - TB1 - (RegFlagH ? 1 : 0)); RegFlag5 = (TB1 & 0x02) != 0; RegFlag3 = (TB1 & 0x08) != 0; --RegBC.Word; RegFlagP = RegBC.Word != 0; - if (RegBC.Word != 0 && !RegFlagZ) { + if (RegBC.Word != 0 && !RegFlagZ) + { RegPC.Word -= 2; totalExecutedCycles += 21; pendingCycles -= 21; - } else { + } + else + { totalExecutedCycles += 16; pendingCycles -= 16; } break; @@ -7509,10 +7686,13 @@ namespace BizHawk.Emulation.CPUs.Z80 --RegBC.High; RegFlagZ = RegBC.High == 0; RegFlagN = true; - if (RegBC.High != 0) { + if (RegBC.High != 0) + { RegPC.Word -= 2; totalExecutedCycles += 21; pendingCycles -= 21; - } else { + } + else + { totalExecutedCycles += 16; pendingCycles -= 16; } break; @@ -7521,10 +7701,13 @@ namespace BizHawk.Emulation.CPUs.Z80 --RegBC.High; RegFlagZ = RegBC.High == 0; RegFlagN = true; - if (RegBC.High != 0) { + if (RegBC.High != 0) + { RegPC.Word -= 2; totalExecutedCycles += 21; pendingCycles -= 21; - } else { + } + else + { totalExecutedCycles += 16; pendingCycles -= 16; } break; @@ -7744,10 +7927,13 @@ namespace BizHawk.Emulation.CPUs.Z80 totalExecutedCycles += 11; pendingCycles -= 11; break; case 0xF0: // RET P - if (!RegFlagS) { + if (!RegFlagS) + { RegPC.Low = ReadMemory(RegSP.Word++); RegPC.High = ReadMemory(RegSP.Word++); totalExecutedCycles += 11; pendingCycles -= 11; - } else { + } + else + { totalExecutedCycles += 5; pendingCycles -= 5; } break; @@ -7757,7 +7943,8 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xF2: // JP P, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (!RegFlagS) { + if (!RegFlagS) + { RegPC.Word = TUS; } totalExecutedCycles += 10; pendingCycles -= 10; @@ -7768,11 +7955,14 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xF4: // CALL P, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (!RegFlagS) { + if (!RegFlagS) + { WriteMemory(--RegSP.Word, RegPC.High); WriteMemory(--RegSP.Word, RegPC.Low); RegPC.Word = TUS; totalExecutedCycles += 17; pendingCycles -= 17; - } else { + } + else + { totalExecutedCycles += 10; pendingCycles -= 10; } break; @@ -7790,10 +7980,13 @@ namespace BizHawk.Emulation.CPUs.Z80 totalExecutedCycles += 11; pendingCycles -= 11; break; case 0xF8: // RET M - if (RegFlagS) { + if (RegFlagS) + { RegPC.Low = ReadMemory(RegSP.Word++); RegPC.High = ReadMemory(RegSP.Word++); totalExecutedCycles += 11; pendingCycles -= 11; - } else { + } + else + { totalExecutedCycles += 5; pendingCycles -= 5; } break; @@ -7803,7 +7996,8 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xFA: // JP M, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (RegFlagS) { + if (RegFlagS) + { RegPC.Word = TUS; } totalExecutedCycles += 10; pendingCycles -= 10; @@ -7815,17 +8009,21 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xFC: // CALL M, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (RegFlagS) { + if (RegFlagS) + { WriteMemory(--RegSP.Word, RegPC.High); WriteMemory(--RegSP.Word, RegPC.Low); RegPC.Word = TUS; totalExecutedCycles += 17; pendingCycles -= 17; - } else { + } + else + { totalExecutedCycles += 10; pendingCycles -= 10; } break; case 0xFD: // (Prefix) ++RegR; - switch (ReadMemory(RegPC.Word++)) { + switch (ReadMemory(RegPC.Word++)) + { case 0x00: // NOP totalExecutedCycles += 4; pendingCycles -= 4; break; @@ -7898,10 +8096,13 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0x10: // DJNZ d TSB = (sbyte)ReadMemory(RegPC.Word++); - if (--RegBC.High != 0) { + if (--RegBC.High != 0) + { RegPC.Word = (ushort)(RegPC.Word + TSB); totalExecutedCycles += 13; pendingCycles -= 13; - } else { + } + else + { totalExecutedCycles += 8; pendingCycles -= 8; } break; @@ -7936,7 +8137,7 @@ namespace BizHawk.Emulation.CPUs.Z80 case 0x18: // JR d TSB = (sbyte)ReadMemory(RegPC.Word++); RegPC.Word = (ushort)(RegPC.Word + TSB); - totalExecutedCycles += 12; pendingCycles -= 12; + totalExecutedCycles += 12; pendingCycles -= 12; break; case 0x19: // ADD IY, DE TI1 = (short)RegIY.Word; TI2 = (short)RegDE.Word; TIR = TI1 + TI2; @@ -7975,10 +8176,13 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0x20: // JR NZ, d TSB = (sbyte)ReadMemory(RegPC.Word++); - if (!RegFlagZ) { + if (!RegFlagZ) + { RegPC.Word = (ushort)(RegPC.Word + TSB); totalExecutedCycles += 12; pendingCycles -= 12; - } else { + } + else + { totalExecutedCycles += 7; pendingCycles -= 7; } break; @@ -8014,10 +8218,13 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0x28: // JR Z, d TSB = (sbyte)ReadMemory(RegPC.Word++); - if (RegFlagZ) { + if (RegFlagZ) + { RegPC.Word = (ushort)(RegPC.Word + TSB); totalExecutedCycles += 12; pendingCycles -= 12; - } else { + } + else + { totalExecutedCycles += 7; pendingCycles -= 7; } break; @@ -8059,10 +8266,13 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0x30: // JR NC, d TSB = (sbyte)ReadMemory(RegPC.Word++); - if (!RegFlagC) { + if (!RegFlagC) + { RegPC.Word = (ushort)(RegPC.Word + TSB); totalExecutedCycles += 12; pendingCycles -= 12; - } else { + } + else + { totalExecutedCycles += 7; pendingCycles -= 7; } break; @@ -8099,10 +8309,13 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0x38: // JR C, d TSB = (sbyte)ReadMemory(RegPC.Word++); - if (RegFlagC) { + if (RegFlagC) + { RegPC.Word = (ushort)(RegPC.Word + TSB); totalExecutedCycles += 12; pendingCycles -= 12; - } else { + } + else + { totalExecutedCycles += 7; pendingCycles -= 7; } break; @@ -8669,10 +8882,13 @@ namespace BizHawk.Emulation.CPUs.Z80 totalExecutedCycles += 4; pendingCycles -= 4; break; case 0xC0: // RET NZ - if (!RegFlagZ) { + if (!RegFlagZ) + { RegPC.Low = ReadMemory(RegSP.Word++); RegPC.High = ReadMemory(RegSP.Word++); totalExecutedCycles += 11; pendingCycles -= 11; - } else { + } + else + { totalExecutedCycles += 5; pendingCycles -= 5; } break; @@ -8682,7 +8898,8 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xC2: // JP NZ, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (!RegFlagZ) { + if (!RegFlagZ) + { RegPC.Word = TUS; } totalExecutedCycles += 10; pendingCycles -= 10; @@ -8693,11 +8910,14 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xC4: // CALL NZ, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (!RegFlagZ) { + if (!RegFlagZ) + { WriteMemory(--RegSP.Word, RegPC.High); WriteMemory(--RegSP.Word, RegPC.Low); RegPC.Word = TUS; totalExecutedCycles += 17; pendingCycles -= 17; - } else { + } + else + { totalExecutedCycles += 10; pendingCycles -= 10; } break; @@ -8715,10 +8935,13 @@ namespace BizHawk.Emulation.CPUs.Z80 totalExecutedCycles += 11; pendingCycles -= 11; break; case 0xC8: // RET Z - if (RegFlagZ) { + if (RegFlagZ) + { RegPC.Low = ReadMemory(RegSP.Word++); RegPC.High = ReadMemory(RegSP.Word++); totalExecutedCycles += 11; pendingCycles -= 11; - } else { + } + else + { totalExecutedCycles += 5; pendingCycles -= 5; } break; @@ -8728,7 +8951,8 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xCA: // JP Z, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (RegFlagZ) { + if (RegFlagZ) + { RegPC.Word = TUS; } totalExecutedCycles += 10; pendingCycles -= 10; @@ -8736,7 +8960,8 @@ namespace BizHawk.Emulation.CPUs.Z80 case 0xCB: // (Prefix) Displacement = (sbyte)ReadMemory(RegPC.Word++); ++RegR; - switch (ReadMemory(RegPC.Word++)) { + switch (ReadMemory(RegPC.Word++)) + { case 0x00: // RLC (IY+d) TUS = TableRotShift[1, 0, RegAF.Low + 256 * ReadMemory((ushort)(RegIY.Word + Displacement))]; WriteMemory((ushort)(RegIY.Word + Displacement), (byte)(TUS >> 8)); @@ -10149,11 +10374,14 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xCC: // CALL Z, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (RegFlagZ) { + if (RegFlagZ) + { WriteMemory(--RegSP.Word, RegPC.High); WriteMemory(--RegSP.Word, RegPC.Low); RegPC.Word = TUS; totalExecutedCycles += 17; pendingCycles -= 17; - } else { + } + else + { totalExecutedCycles += 10; pendingCycles -= 10; } break; @@ -10173,10 +10401,13 @@ namespace BizHawk.Emulation.CPUs.Z80 totalExecutedCycles += 11; pendingCycles -= 11; break; case 0xD0: // RET NC - if (!RegFlagC) { + if (!RegFlagC) + { RegPC.Low = ReadMemory(RegSP.Word++); RegPC.High = ReadMemory(RegSP.Word++); totalExecutedCycles += 11; pendingCycles -= 11; - } else { + } + else + { totalExecutedCycles += 5; pendingCycles -= 5; } break; @@ -10186,7 +10417,8 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xD2: // JP NC, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (!RegFlagC) { + if (!RegFlagC) + { RegPC.Word = TUS; } totalExecutedCycles += 10; pendingCycles -= 10; @@ -10197,11 +10429,14 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xD4: // CALL NC, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (!RegFlagC) { + if (!RegFlagC) + { WriteMemory(--RegSP.Word, RegPC.High); WriteMemory(--RegSP.Word, RegPC.Low); RegPC.Word = TUS; totalExecutedCycles += 17; pendingCycles -= 17; - } else { + } + else + { totalExecutedCycles += 10; pendingCycles -= 10; } break; @@ -10219,10 +10454,13 @@ namespace BizHawk.Emulation.CPUs.Z80 totalExecutedCycles += 11; pendingCycles -= 11; break; case 0xD8: // RET C - if (RegFlagC) { + if (RegFlagC) + { RegPC.Low = ReadMemory(RegSP.Word++); RegPC.High = ReadMemory(RegSP.Word++); totalExecutedCycles += 11; pendingCycles -= 11; - } else { + } + else + { totalExecutedCycles += 5; pendingCycles -= 5; } break; @@ -10234,7 +10472,8 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xDA: // JP C, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (RegFlagC) { + if (RegFlagC) + { RegPC.Word = TUS; } totalExecutedCycles += 10; pendingCycles -= 10; @@ -10245,11 +10484,14 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xDC: // CALL C, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (RegFlagC) { + if (RegFlagC) + { WriteMemory(--RegSP.Word, RegPC.High); WriteMemory(--RegSP.Word, RegPC.Low); RegPC.Word = TUS; totalExecutedCycles += 17; pendingCycles -= 17; - } else { + } + else + { totalExecutedCycles += 10; pendingCycles -= 10; } break; @@ -10267,10 +10509,13 @@ namespace BizHawk.Emulation.CPUs.Z80 totalExecutedCycles += 11; pendingCycles -= 11; break; case 0xE0: // RET PO - if (!RegFlagP) { + if (!RegFlagP) + { RegPC.Low = ReadMemory(RegSP.Word++); RegPC.High = ReadMemory(RegSP.Word++); totalExecutedCycles += 11; pendingCycles -= 11; - } else { + } + else + { totalExecutedCycles += 5; pendingCycles -= 5; } break; @@ -10280,7 +10525,8 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xE2: // JP PO, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (!RegFlagP) { + if (!RegFlagP) + { RegPC.Word = TUS; } totalExecutedCycles += 10; pendingCycles -= 10; @@ -10293,11 +10539,14 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xE4: // CALL C, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (RegFlagC) { + if (RegFlagC) + { WriteMemory(--RegSP.Word, RegPC.High); WriteMemory(--RegSP.Word, RegPC.Low); RegPC.Word = TUS; totalExecutedCycles += 17; pendingCycles -= 17; - } else { + } + else + { totalExecutedCycles += 10; pendingCycles -= 10; } break; @@ -10315,10 +10564,13 @@ namespace BizHawk.Emulation.CPUs.Z80 totalExecutedCycles += 11; pendingCycles -= 11; break; case 0xE8: // RET PE - if (RegFlagP) { + if (RegFlagP) + { RegPC.Low = ReadMemory(RegSP.Word++); RegPC.High = ReadMemory(RegSP.Word++); totalExecutedCycles += 11; pendingCycles -= 11; - } else { + } + else + { totalExecutedCycles += 5; pendingCycles -= 5; } break; @@ -10328,7 +10580,8 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xEA: // JP PE, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (RegFlagP) { + if (RegFlagP) + { RegPC.Word = TUS; } totalExecutedCycles += 10; pendingCycles -= 10; @@ -10339,17 +10592,21 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xEC: // CALL PE, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (RegFlagP) { + if (RegFlagP) + { WriteMemory(--RegSP.Word, RegPC.High); WriteMemory(--RegSP.Word, RegPC.Low); RegPC.Word = TUS; totalExecutedCycles += 17; pendingCycles -= 17; - } else { + } + else + { totalExecutedCycles += 10; pendingCycles -= 10; } break; case 0xED: // (Prefix) ++RegR; - switch (ReadMemory(RegPC.Word++)) { + switch (ReadMemory(RegPC.Word++)) + { case 0x00: // NOP totalExecutedCycles += 4; pendingCycles -= 4; break; @@ -11163,10 +11420,13 @@ namespace BizHawk.Emulation.CPUs.Z80 RegFlagP = RegBC.Word != 0; RegFlagH = false; RegFlagN = false; - if (RegBC.Word != 0) { + if (RegBC.Word != 0) + { RegPC.Word -= 2; totalExecutedCycles += 21; pendingCycles -= 21; - } else { + } + else + { totalExecutedCycles += 16; pendingCycles -= 16; } break; @@ -11179,10 +11439,13 @@ namespace BizHawk.Emulation.CPUs.Z80 TB1 = (byte)(RegAF.High - TB1 - (RegFlagH ? 1 : 0)); RegFlag5 = (TB1 & 0x02) != 0; RegFlag3 = (TB1 & 0x08) != 0; --RegBC.Word; RegFlagP = RegBC.Word != 0; - if (RegBC.Word != 0 && !RegFlagZ) { + if (RegBC.Word != 0 && !RegFlagZ) + { RegPC.Word -= 2; totalExecutedCycles += 21; pendingCycles -= 21; - } else { + } + else + { totalExecutedCycles += 16; pendingCycles -= 16; } break; @@ -11191,10 +11454,13 @@ namespace BizHawk.Emulation.CPUs.Z80 --RegBC.High; RegFlagZ = RegBC.High == 0; RegFlagN = true; - if (RegBC.High != 0) { + if (RegBC.High != 0) + { RegPC.Word -= 2; totalExecutedCycles += 21; pendingCycles -= 21; - } else { + } + else + { totalExecutedCycles += 16; pendingCycles -= 16; } break; @@ -11203,10 +11469,13 @@ namespace BizHawk.Emulation.CPUs.Z80 --RegBC.High; RegFlagZ = RegBC.High == 0; RegFlagN = true; - if (RegBC.High != 0) { + if (RegBC.High != 0) + { RegPC.Word -= 2; totalExecutedCycles += 21; pendingCycles -= 21; - } else { + } + else + { totalExecutedCycles += 16; pendingCycles -= 16; } break; @@ -11229,10 +11498,13 @@ namespace BizHawk.Emulation.CPUs.Z80 RegFlagP = RegBC.Word != 0; RegFlagH = false; RegFlagN = false; - if (RegBC.Word != 0) { + if (RegBC.Word != 0) + { RegPC.Word -= 2; totalExecutedCycles += 21; pendingCycles -= 21; - } else { + } + else + { totalExecutedCycles += 16; pendingCycles -= 16; } break; @@ -11245,10 +11517,13 @@ namespace BizHawk.Emulation.CPUs.Z80 TB1 = (byte)(RegAF.High - TB1 - (RegFlagH ? 1 : 0)); RegFlag5 = (TB1 & 0x02) != 0; RegFlag3 = (TB1 & 0x08) != 0; --RegBC.Word; RegFlagP = RegBC.Word != 0; - if (RegBC.Word != 0 && !RegFlagZ) { + if (RegBC.Word != 0 && !RegFlagZ) + { RegPC.Word -= 2; totalExecutedCycles += 21; pendingCycles -= 21; - } else { + } + else + { totalExecutedCycles += 16; pendingCycles -= 16; } break; @@ -11257,10 +11532,13 @@ namespace BizHawk.Emulation.CPUs.Z80 --RegBC.High; RegFlagZ = RegBC.High == 0; RegFlagN = true; - if (RegBC.High != 0) { + if (RegBC.High != 0) + { RegPC.Word -= 2; totalExecutedCycles += 21; pendingCycles -= 21; - } else { + } + else + { totalExecutedCycles += 16; pendingCycles -= 16; } break; @@ -11269,10 +11547,13 @@ namespace BizHawk.Emulation.CPUs.Z80 --RegBC.High; RegFlagZ = RegBC.High == 0; RegFlagN = true; - if (RegBC.High != 0) { + if (RegBC.High != 0) + { RegPC.Word -= 2; totalExecutedCycles += 21; pendingCycles -= 21; - } else { + } + else + { totalExecutedCycles += 16; pendingCycles -= 16; } break; @@ -11492,10 +11773,13 @@ namespace BizHawk.Emulation.CPUs.Z80 totalExecutedCycles += 11; pendingCycles -= 11; break; case 0xF0: // RET P - if (!RegFlagS) { + if (!RegFlagS) + { RegPC.Low = ReadMemory(RegSP.Word++); RegPC.High = ReadMemory(RegSP.Word++); totalExecutedCycles += 11; pendingCycles -= 11; - } else { + } + else + { totalExecutedCycles += 5; pendingCycles -= 5; } break; @@ -11505,7 +11789,8 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xF2: // JP P, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (!RegFlagS) { + if (!RegFlagS) + { RegPC.Word = TUS; } totalExecutedCycles += 10; pendingCycles -= 10; @@ -11516,11 +11801,14 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xF4: // CALL P, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (!RegFlagS) { + if (!RegFlagS) + { WriteMemory(--RegSP.Word, RegPC.High); WriteMemory(--RegSP.Word, RegPC.Low); RegPC.Word = TUS; totalExecutedCycles += 17; pendingCycles -= 17; - } else { + } + else + { totalExecutedCycles += 10; pendingCycles -= 10; } break; @@ -11538,10 +11826,13 @@ namespace BizHawk.Emulation.CPUs.Z80 totalExecutedCycles += 11; pendingCycles -= 11; break; case 0xF8: // RET M - if (RegFlagS) { + if (RegFlagS) + { RegPC.Low = ReadMemory(RegSP.Word++); RegPC.High = ReadMemory(RegSP.Word++); totalExecutedCycles += 11; pendingCycles -= 11; - } else { + } + else + { totalExecutedCycles += 5; pendingCycles -= 5; } break; @@ -11551,7 +11842,8 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xFA: // JP M, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (RegFlagS) { + if (RegFlagS) + { RegPC.Word = TUS; } totalExecutedCycles += 10; pendingCycles -= 10; @@ -11563,11 +11855,14 @@ namespace BizHawk.Emulation.CPUs.Z80 break; case 0xFC: // CALL M, nn TUS = (ushort)(ReadMemory(RegPC.Word++) + ReadMemory(RegPC.Word++) * 256); - if (RegFlagS) { + if (RegFlagS) + { WriteMemory(--RegSP.Word, RegPC.High); WriteMemory(--RegSP.Word, RegPC.Low); RegPC.Word = TUS; totalExecutedCycles += 17; pendingCycles -= 17; - } else { + } + else + { totalExecutedCycles += 10; pendingCycles -= 10; } break; @@ -11600,8 +11895,8 @@ namespace BizHawk.Emulation.CPUs.Z80 } // Process interrupt requests. - if (nonMaskableInterruptPending) - { + if (nonMaskableInterruptPending) + { halted = false; totalExecutedCycles += 11; pendingCycles -= 11; @@ -11612,16 +11907,18 @@ namespace BizHawk.Emulation.CPUs.Z80 WriteMemory(--RegSP.Word, RegPC.High); WriteMemory(--RegSP.Word, RegPC.Low); RegPC.Word = 0x66; - NMICallback(); - - } else if (iff1 && interrupt && Interruptable) { - + NMICallback(); + + } + else if (iff1 && interrupt && Interruptable) + { + Halted = false; iff1 = iff2 = false; - switch (interruptMode) - { + switch (interruptMode) + { case 0: totalExecutedCycles += 13; pendingCycles -= 13; break; @@ -11637,30 +11934,30 @@ namespace BizHawk.Emulation.CPUs.Z80 totalExecutedCycles += 19; pendingCycles -= 19; break; } - IRQCallback(); + IRQCallback(); } } } - - // TODO, not super thrilled with the existing Z80 disassembler, lets see if we can find something decent to replace it with - Disassembler Disassembler = new Disassembler(); - public string State() - { - ushort tempPC = RegPC.Word; - string a = string.Format("{0:X4} {1:X2} {2} ", RegPC.Word, ReadMemory(RegPC.Word), Disassembler.Disassemble(() => ReadMemory(tempPC++)).PadRight(41)); - string b = string.Format("AF:{0:X4} BC:{1:X4} DE:{2:X4} HL:{3:X4} IX:{4:X4} IY:{5:X4} SP:{6:X4} Cy:{7}", RegAF.Word, RegBC.Word, RegDE.Word, RegHL.Word, RegIX.Word, RegIY.Word, RegSP.Word, TotalExecutedCycles); - string val = a + b + " "; - - if (RegFlagC) val = val + "C"; - if (RegFlagN) val = val + "N"; - if (RegFlagP) val = val + "P"; - if (RegFlag3) val = val + "3"; - if (RegFlagH) val = val + "H"; - if (RegFlag5) val = val + "5"; - if (RegFlagZ) val = val + "Z"; - if (RegFlagS) val = val + "S"; - return val; - } + // TODO, not super thrilled with the existing Z80 disassembler, lets see if we can find something decent to replace it with + Disassembler Disassembler = new Disassembler(); + + public string State() + { + ushort tempPC = RegPC.Word; + string a = string.Format("{0:X4} {1:X2} {2} ", RegPC.Word, ReadMemory(RegPC.Word), Disassembler.Disassemble(() => ReadMemory(tempPC++)).PadRight(41)); + string b = string.Format("AF:{0:X4} BC:{1:X4} DE:{2:X4} HL:{3:X4} IX:{4:X4} IY:{5:X4} SP:{6:X4} Cy:{7}", RegAF.Word, RegBC.Word, RegDE.Word, RegHL.Word, RegIX.Word, RegIY.Word, RegSP.Word, TotalExecutedCycles); + string val = a + b + " "; + + if (RegFlagC) val = val + "C"; + if (RegFlagN) val = val + "N"; + if (RegFlagP) val = val + "P"; + if (RegFlag3) val = val + "3"; + if (RegFlagH) val = val + "H"; + if (RegFlag5) val = val + "5"; + if (RegFlagZ) val = val + "Z"; + if (RegFlagS) val = val + "S"; + return val; + } } } \ No newline at end of file diff --git a/BizHawk.Emulation/CPUs/Z80/Interrupts.cs b/BizHawk.Emulation/CPUs/Z80/Interrupts.cs index e1acd01ca1..1a94cf5f8b 100644 --- a/BizHawk.Emulation/CPUs/Z80/Interrupts.cs +++ b/BizHawk.Emulation/CPUs/Z80/Interrupts.cs @@ -1,9 +1,9 @@ using System; -namespace BizHawk.Emulation.CPUs.Z80 +namespace BizHawk.Emulation.Common.Components.Z80 { - public partial class Z80A - { + public partial class Z80A + { private bool iff1; public bool IFF1 { get { return iff1; } set { iff1 = value; } } @@ -14,8 +14,8 @@ namespace BizHawk.Emulation.CPUs.Z80 public bool Interrupt { get { return interrupt; } set { interrupt = value; } } private bool nonMaskableInterrupt; - public bool NonMaskableInterrupt - { + public bool NonMaskableInterrupt + { get { return nonMaskableInterrupt; } set { if (value && !nonMaskableInterrupt) NonMaskableInterruptPending = true; nonMaskableInterrupt = value; } } @@ -24,8 +24,8 @@ namespace BizHawk.Emulation.CPUs.Z80 public bool NonMaskableInterruptPending { get { return nonMaskableInterruptPending; } set { nonMaskableInterruptPending = value; } } private int interruptMode; - public int InterruptMode - { + public int InterruptMode + { get { return interruptMode; } set { if (value < 0 || value > 2) throw new ArgumentOutOfRangeException(); interruptMode = value; } } @@ -33,11 +33,11 @@ namespace BizHawk.Emulation.CPUs.Z80 private bool halted; public bool Halted { get { return halted; } set { halted = value; } } - public Action IRQCallback = delegate() { }; - public Action NMICallback = delegate() { }; + public Action IRQCallback = delegate() { }; + public Action NMICallback = delegate() { }; - private void ResetInterrupts() - { + private void ResetInterrupts() + { IFF1 = false; IFF2 = false; Interrupt = false; @@ -47,8 +47,8 @@ namespace BizHawk.Emulation.CPUs.Z80 Halted = false; } - private void Halt() - { + private void Halt() + { Halted = true; } } diff --git a/BizHawk.Emulation/CPUs/Z80/Registers.cs b/BizHawk.Emulation/CPUs/Z80/Registers.cs index 98b395749b..0f3af6022d 100644 --- a/BizHawk.Emulation/CPUs/Z80/Registers.cs +++ b/BizHawk.Emulation/CPUs/Z80/Registers.cs @@ -1,14 +1,14 @@ using System.Runtime.InteropServices; using System; -namespace BizHawk.Emulation.CPUs.Z80 +namespace BizHawk.Emulation.Common.Components.Z80 { - public partial class Z80A - { + public partial class Z80A + { [StructLayout(LayoutKind.Explicit)] [Serializable()] - public struct RegisterPair - { + public struct RegisterPair + { [FieldOffset(0)] public ushort Word; @@ -18,68 +18,68 @@ namespace BizHawk.Emulation.CPUs.Z80 [FieldOffset(1)] public byte High; - public RegisterPair(ushort value) - { + public RegisterPair(ushort value) + { Word = value; Low = (byte)(Word); High = (byte)(Word >> 8); } - public static implicit operator ushort(RegisterPair rp) - { + public static implicit operator ushort(RegisterPair rp) + { return rp.Word; } - public static implicit operator RegisterPair(ushort value) - { + public static implicit operator RegisterPair(ushort value) + { return new RegisterPair(value); } } - private bool RegFlagC - { + private bool RegFlagC + { get { return (RegAF.Low & 0x01) != 0; } set { RegAF.Low = (byte)((RegAF.Low & ~0x01) | (value ? 0x01 : 0x00)); } } - private bool RegFlagN - { + private bool RegFlagN + { get { return (RegAF.Low & 0x02) != 0; } set { RegAF.Low = (byte)((RegAF.Low & ~0x02) | (value ? 0x02 : 0x00)); } } - private bool RegFlagP - { + private bool RegFlagP + { get { return (RegAF.Low & 0x04) != 0; } set { RegAF.Low = (byte)((RegAF.Low & ~0x04) | (value ? 0x04 : 0x00)); } } - private bool RegFlag3 - { + private bool RegFlag3 + { get { return (RegAF.Low & 0x08) != 0; } set { RegAF.Low = (byte)((RegAF.Low & ~0x08) | (value ? 0x08 : 0x00)); } } - private bool RegFlagH - { + private bool RegFlagH + { get { return (RegAF.Low & 0x10) != 0; } set { RegAF.Low = (byte)((RegAF.Low & ~0x10) | (value ? 0x10 : 0x00)); } } - private bool RegFlag5 - { + private bool RegFlag5 + { get { return (RegAF.Low & 0x20) != 0; } set { RegAF.Low = (byte)((RegAF.Low & ~0x20) | (value ? 0x20 : 0x00)); } } - private bool RegFlagZ - { + private bool RegFlagZ + { get { return (RegAF.Low & 0x40) != 0; } set { RegAF.Low = (byte)((RegAF.Low & ~0x40) | (value ? 0x40 : 0x00)); } } - private bool RegFlagS - { + private bool RegFlagS + { get { return (RegAF.Low & 0x80) != 0; } set { RegAF.Low = (byte)((RegAF.Low & ~0x80) | (value ? 0x80 : 0x00)); } } @@ -93,7 +93,7 @@ namespace BizHawk.Emulation.CPUs.Z80 private RegisterPair RegAltBC; // Shadow for B and C private RegisterPair RegAltDE; // Shadow for D and E private RegisterPair RegAltHL; // Shadow for H and L - + private byte RegI; // I (interrupt vector) private byte RegR; // R (memory refresh) @@ -103,8 +103,8 @@ namespace BizHawk.Emulation.CPUs.Z80 private RegisterPair RegSP; // SP (stack pointer) private RegisterPair RegPC; // PC (program counter) - private void ResetRegisters() - { + private void ResetRegisters() + { // Clear main registers RegAF = 0; RegBC = 0; RegDE = 0; RegHL = 0; // Clear alternate registers @@ -115,123 +115,123 @@ namespace BizHawk.Emulation.CPUs.Z80 RegSP.Word = 0; RegPC.Word = 0; } - public byte RegisterA - { + public byte RegisterA + { get { return RegAF.High; } set { RegAF.High = value; } } - public byte RegisterF - { + public byte RegisterF + { get { return RegAF.Low; } set { RegAF.Low = value; } } - public ushort RegisterAF - { + public ushort RegisterAF + { get { return RegAF.Word; } set { RegAF.Word = value; } } - public byte RegisterB - { + public byte RegisterB + { get { return RegBC.High; } set { RegBC.High = value; } } - public byte RegisterC - { + public byte RegisterC + { get { return RegBC.Low; } set { RegBC.Low = value; } } - public ushort RegisterBC - { + public ushort RegisterBC + { get { return RegBC.Word; } set { RegBC.Word = value; } } - public byte RegisterD - { + public byte RegisterD + { get { return RegDE.High; } set { RegDE.High = value; } } - public byte RegisterE - { + public byte RegisterE + { get { return RegDE.Low; } set { RegDE.Low = value; } } - public ushort RegisterDE - { + public ushort RegisterDE + { get { return RegDE.Word; } set { RegDE.Word = value; } } - public byte RegisterH - { + public byte RegisterH + { get { return RegHL.High; } set { RegHL.High = value; } } - public byte RegisterL - { + public byte RegisterL + { get { return RegHL.Low; } set { RegHL.Low = value; } } - public ushort RegisterHL - { + public ushort RegisterHL + { get { return RegHL.Word; } set { RegHL.Word = value; } } - public ushort RegisterPC - { + public ushort RegisterPC + { get { return RegPC.Word; } set { RegPC.Word = value; } } - public ushort RegisterSP - { + public ushort RegisterSP + { get { return RegSP.Word; } set { RegSP.Word = value; } } - public ushort RegisterIX - { + public ushort RegisterIX + { get { return RegIX.Word; } set { RegIX.Word = value; } } - public ushort RegisterIY - { + public ushort RegisterIY + { get { return RegIY.Word; } set { RegIY.Word = value; } } - public byte RegisterI - { + public byte RegisterI + { get { return RegI; } set { RegI = value; } } - public byte RegisterR - { + public byte RegisterR + { get { return RegR; } set { RegR = value; } } - public ushort RegisterShadowAF - { + public ushort RegisterShadowAF + { get { return RegAltAF.Word; } set { RegAltAF.Word = value; } } - public ushort RegisterShadowBC - { + public ushort RegisterShadowBC + { get { return RegAltBC.Word; } set { RegAltBC.Word = value; } } - public ushort RegisterShadowDE - { + public ushort RegisterShadowDE + { get { return RegAltDE.Word; } set { RegAltDE.Word = value; } } - public ushort RegisterShadowHL - { + public ushort RegisterShadowHL + { get { return RegAltHL.Word; } set { RegAltHL.Word = value; } } diff --git a/BizHawk.Emulation/CPUs/Z80/Tables.cs b/BizHawk.Emulation/CPUs/Z80/Tables.cs index 1c52578800..417b3b78aa 100644 --- a/BizHawk.Emulation/CPUs/Z80/Tables.cs +++ b/BizHawk.Emulation/CPUs/Z80/Tables.cs @@ -1,9 +1,9 @@ -namespace BizHawk.Emulation.CPUs.Z80 +namespace BizHawk.Emulation.Common.Components.Z80 { - public partial class Z80A - { - private void InitialiseTables() - { + public partial class Z80A + { + private void InitialiseTables() + { InitTableInc(); InitTableDec(); InitTableParity(); @@ -16,30 +16,30 @@ namespace BizHawk.Emulation.CPUs.Z80 } private byte[] TableInc; - private void InitTableInc() - { + private void InitTableInc() + { TableInc = new byte[256]; for (int i = 0; i < 256; ++i) TableInc[i] = FlagByte(false, false, i == 0x80, UndocumentedX(i), (i & 0xF) == 0x0, UndocumentedY(i), i == 0, i > 127); } private byte[] TableDec; - private void InitTableDec() - { + private void InitTableDec() + { TableDec = new byte[256]; for (int i = 0; i < 256; ++i) TableDec[i] = FlagByte(false, true, i == 0x7F, UndocumentedX(i), (i & 0xF) == 0xF, UndocumentedY(i), i == 0, i > 127); } private bool[] TableParity; - private void InitTableParity() - { + private void InitTableParity() + { TableParity = new bool[256]; - for (int i = 0; i < 256; ++i) - { + for (int i = 0; i < 256; ++i) + { int Bits = 0; - for (int j = 0; j < 8; ++j) - { + for (int j = 0; j < 8; ++j) + { Bits += (i >> j) & 1; } TableParity[i] = (Bits & 1) == 0; @@ -47,18 +47,18 @@ namespace BizHawk.Emulation.CPUs.Z80 } private ushort[, , ,] TableALU; - private void InitTableALU() - { + private void InitTableALU() + { TableALU = new ushort[8, 256, 256, 2]; // Class, OP1, OP2, Carry - for (int i = 0; i < 8; ++i) - { - for (int op1 = 0; op1 < 256; ++op1) - { - for (int op2 = 0; op2 < 256; ++op2) - { - for (int c = 0; c < 2; ++c) - { + for (int i = 0; i < 8; ++i) + { + for (int op1 = 0; op1 < 256; ++op1) + { + for (int op2 = 0; op2 < 256; ++op2) + { + for (int c = 0; c < 2; ++c) + { int ac = (i == 1 || i == 3) ? c : 0; @@ -74,8 +74,8 @@ namespace BizHawk.Emulation.CPUs.Z80 int result_ui = 0; // Fetch result - switch (i) - { + switch (i) + { case 0: case 1: result_si = (sbyte)op1 + (sbyte)op2 + ac; @@ -102,8 +102,8 @@ namespace BizHawk.Emulation.CPUs.Z80 // Parity/Carry - switch (i) - { + switch (i) + { case 0: case 1: case 2: @@ -124,8 +124,8 @@ namespace BizHawk.Emulation.CPUs.Z80 N = i == 2 || i == 3 || i == 7; // Half carry - switch (i) - { + switch (i) + { case 0: case 1: H = ((op1 & 0xF) + (op2 & 0xF) + (ac & 0xF)) > 0xF; @@ -161,72 +161,80 @@ namespace BizHawk.Emulation.CPUs.Z80 } } } - } + } } private bool[,] TableHalfBorrow; - private void InitTableHalfBorrow() - { + private void InitTableHalfBorrow() + { TableHalfBorrow = new bool[256, 256]; - for (int i = 0; i < 256; i++) - { - for (int j = 0; j < 256; j++) - { + for (int i = 0; i < 256; i++) + { + for (int j = 0; j < 256; j++) + { TableHalfBorrow[i, j] = ((i & 0xF) - (j & 0xF)) < 0; } } } private bool[,] TableHalfCarry; - private void InitTableHalfCarry() - { + private void InitTableHalfCarry() + { TableHalfCarry = new bool[256, 256]; - for (int i = 0; i < 256; i++) - { - for (int j = 0; j < 256; j++) - { + for (int i = 0; i < 256; i++) + { + for (int j = 0; j < 256; j++) + { TableHalfCarry[i, j] = ((i & 0xF) + (j & 0xF)) > 0xF; } } } private ushort[, ,] TableRotShift; - private void InitTableRotShift() - { + private void InitTableRotShift() + { TableRotShift = new ushort[2, 8, 65536]; // All, operation, AF - for (int all = 0; all < 2; all++) - { - for (int y = 0; y < 8; ++y) - { - for (int af = 0; af < 65536; af++) - { + for (int all = 0; all < 2; all++) + { + for (int y = 0; y < 8; ++y) + { + for (int af = 0; af < 65536; af++) + { byte Old = (byte)(af >> 8); bool OldCarry = (af & 0x01) != 0; ushort newAf = (ushort)(af & ~(0x13)); // Clear HALF-CARRY, SUBTRACT and CARRY flags byte New = Old; - if ((y & 1) == 0) - { + if ((y & 1) == 0) + { if ((Old & 0x80) != 0) ++newAf; New <<= 1; - if ((y & 0x04) == 0) { + if ((y & 0x04) == 0) + { if (((y & 0x02) == 0) ? ((newAf & 0x01) != 0) : OldCarry) New |= 0x01; - } else { + } + else + { if ((y & 0x02) != 0) New |= 0x01; } - } else { + } + else + { if ((Old & 0x01) != 0) ++newAf; New >>= 1; - if ((y & 0x04) == 0) { + if ((y & 0x04) == 0) + { if (((y & 0x02) == 0) ? ((newAf & 0x01) != 0) : OldCarry) New |= 0x80; - } else { + } + else + { if ((y & 0x02) == 0) New |= (byte)(Old & 0x80); } } @@ -234,8 +242,8 @@ namespace BizHawk.Emulation.CPUs.Z80 newAf &= 0xFF; newAf |= (ushort)(New * 256); - if (all == 1) - { + if (all == 1) + { newAf &= unchecked((ushort)~0xC4); // Clear S, Z, P if (New > 127) newAf |= 0x80; if (New == 0) newAf |= 0x40; @@ -249,11 +257,11 @@ namespace BizHawk.Emulation.CPUs.Z80 } private ushort[] TableNeg; - private void InitTableNeg() - { + private void InitTableNeg() + { TableNeg = new ushort[65536]; - for (int af = 0; af < 65536; af++) - { + for (int af = 0; af < 65536; af++) + { ushort raf = 0; byte b = (byte)(af >> 8); byte a = (byte)-b; @@ -264,19 +272,21 @@ namespace BizHawk.Emulation.CPUs.Z80 } private ushort[] TableDaa; - private void InitTableDaa() - { + private void InitTableDaa() + { TableDaa = new ushort[65536]; - for (int af = 0; af < 65536; ++af) - { + for (int af = 0; af < 65536; ++af) + { byte a = (byte)(af >> 8); byte tmp = a; - if (IsN(af)) - { + if (IsN(af)) + { if (IsH(af) || ((a & 0x0F) > 0x09)) tmp -= 0x06; if (IsC(af) || a > 0x99) tmp -= 0x60; - } else { + } + else + { if (IsH(af) || ((a & 0x0F) > 0x09)) tmp += 0x06; if (IsC(af) || a > 0x99) tmp += 0x60; } @@ -285,8 +295,8 @@ namespace BizHawk.Emulation.CPUs.Z80 } } - private byte FlagByte(bool C, bool N, bool P, bool X, bool H, bool Y, bool Z, bool S) - { + private byte FlagByte(bool C, bool N, bool P, bool X, bool H, bool Y, bool Z, bool S) + { return (byte)( (C ? 0x01 : 0) + (N ? 0x02 : 0) + @@ -299,13 +309,13 @@ namespace BizHawk.Emulation.CPUs.Z80 ); } - private bool UndocumentedX(int value) - { + private bool UndocumentedX(int value) + { return (value & 0x08) != 0; } - private bool UndocumentedY(int value) - { + private bool UndocumentedY(int value) + { return (value & 0x20) != 0; } diff --git a/BizHawk.Emulation/CPUs/Z80/Z80A.cs b/BizHawk.Emulation/CPUs/Z80/Z80A.cs index 417d172e6e..91e72cd257 100644 --- a/BizHawk.Emulation/CPUs/Z80/Z80A.cs +++ b/BizHawk.Emulation/CPUs/Z80/Z80A.cs @@ -5,18 +5,18 @@ using System.IO; // This Z80 emulator is a modified version of Ben Ryves 'Brazil' emulator. // It is MIT licensed. -namespace BizHawk.Emulation.CPUs.Z80 +namespace BizHawk.Emulation.Common.Components.Z80 { /// /// ZiLOG Z80A CPU Emulator /// - public sealed partial class Z80A - { + public sealed partial class Z80A + { /// /// Creates an instance of the emulator class. /// - public Z80A() - { + public Z80A() + { InitialiseTables(); Reset(); } @@ -24,8 +24,8 @@ namespace BizHawk.Emulation.CPUs.Z80 /// /// Reset the Z80 to its initial state /// - public void Reset() - { + public void Reset() + { ResetRegisters(); ResetInterrupts(); PendingCycles = 0; @@ -33,178 +33,178 @@ namespace BizHawk.Emulation.CPUs.Z80 TotalExecutedCycles = 0; } - /// - /// Reset the Z80 to its initial state, but don't modify cycle counters. For use where Z80 may be reset - /// - public void SoftReset() - { - ResetRegisters(); - ResetInterrupts(); - } + /// + /// Reset the Z80 to its initial state, but don't modify cycle counters. For use where Z80 may be reset + /// + public void SoftReset() + { + ResetRegisters(); + ResetInterrupts(); + } - // Memory Access + // Memory Access - public Func ReadMemory; - public Action WriteMemory; + public Func ReadMemory; + public Action WriteMemory; - // Utility function, not used by core - public ushort ReadWord(ushort addr) - { - ushort value = ReadMemory(addr++); - value |= (ushort) (ReadMemory(addr) << 8); - return value; - } + // Utility function, not used by core + public ushort ReadWord(ushort addr) + { + ushort value = ReadMemory(addr++); + value |= (ushort)(ReadMemory(addr) << 8); + return value; + } - // Hardware I/O Port Access + // Hardware I/O Port Access - public Func ReadHardware; - public Action WriteHardware; + public Func ReadHardware; + public Action WriteHardware; - // State Save/Load + // State Save/Load - public void SaveStateText(TextWriter writer) - { - writer.WriteLine("[Z80]"); - writer.WriteLine("AF {0:X4}", RegAF.Word); - writer.WriteLine("BC {0:X4}", RegBC.Word); - writer.WriteLine("DE {0:X4}", RegDE.Word); - writer.WriteLine("HL {0:X4}", RegHL.Word); - writer.WriteLine("ShadowAF {0:X4}", RegAltAF.Word); - writer.WriteLine("ShadowBC {0:X4}", RegAltBC.Word); - writer.WriteLine("ShadowDE {0:X4}", RegAltDE.Word); - writer.WriteLine("ShadowHL {0:X4}", RegAltHL.Word); - writer.WriteLine("I {0:X2}", RegI); - writer.WriteLine("R {0:X2}", RegR); - writer.WriteLine("IX {0:X4}", RegIX.Word); - writer.WriteLine("IY {0:X4}", RegIY.Word); - writer.WriteLine("SP {0:X4}", RegSP.Word); - writer.WriteLine("PC {0:X4}", RegPC.Word); - writer.WriteLine("IRQ {0}", interrupt); - writer.WriteLine("NMI {0}", nonMaskableInterrupt); - writer.WriteLine("NMIPending {0}", nonMaskableInterruptPending); - writer.WriteLine("IM {0}", InterruptMode); - writer.WriteLine("IFF1 {0}", IFF1); - writer.WriteLine("IFF2 {0}", IFF2); - writer.WriteLine("Halted {0}", Halted); - writer.WriteLine("ExecutedCycles {0}", TotalExecutedCycles); - writer.WriteLine("PendingCycles {0}", PendingCycles); - writer.WriteLine("[/Z80]"); - writer.WriteLine(); - } + public void SaveStateText(TextWriter writer) + { + writer.WriteLine("[Z80]"); + writer.WriteLine("AF {0:X4}", RegAF.Word); + writer.WriteLine("BC {0:X4}", RegBC.Word); + writer.WriteLine("DE {0:X4}", RegDE.Word); + writer.WriteLine("HL {0:X4}", RegHL.Word); + writer.WriteLine("ShadowAF {0:X4}", RegAltAF.Word); + writer.WriteLine("ShadowBC {0:X4}", RegAltBC.Word); + writer.WriteLine("ShadowDE {0:X4}", RegAltDE.Word); + writer.WriteLine("ShadowHL {0:X4}", RegAltHL.Word); + writer.WriteLine("I {0:X2}", RegI); + writer.WriteLine("R {0:X2}", RegR); + writer.WriteLine("IX {0:X4}", RegIX.Word); + writer.WriteLine("IY {0:X4}", RegIY.Word); + writer.WriteLine("SP {0:X4}", RegSP.Word); + writer.WriteLine("PC {0:X4}", RegPC.Word); + writer.WriteLine("IRQ {0}", interrupt); + writer.WriteLine("NMI {0}", nonMaskableInterrupt); + writer.WriteLine("NMIPending {0}", nonMaskableInterruptPending); + writer.WriteLine("IM {0}", InterruptMode); + writer.WriteLine("IFF1 {0}", IFF1); + writer.WriteLine("IFF2 {0}", IFF2); + writer.WriteLine("Halted {0}", Halted); + writer.WriteLine("ExecutedCycles {0}", TotalExecutedCycles); + writer.WriteLine("PendingCycles {0}", PendingCycles); + writer.WriteLine("[/Z80]"); + writer.WriteLine(); + } - public void LoadStateText(TextReader reader) - { - while (true) - { - string[] args = reader.ReadLine().Split(' '); - if (args[0].Trim() == "") continue; - if (args[0] == "[/Z80]") break; - if (args[0] == "AF") - RegAF.Word = ushort.Parse(args[1], NumberStyles.HexNumber); - else if (args[0] == "BC") - RegBC.Word = ushort.Parse(args[1], NumberStyles.HexNumber); - else if (args[0] == "DE") - RegDE.Word = ushort.Parse(args[1], NumberStyles.HexNumber); - else if (args[0] == "HL") - RegHL.Word = ushort.Parse(args[1], NumberStyles.HexNumber); - else if (args[0] == "ShadowAF") - RegAltAF.Word = ushort.Parse(args[1], NumberStyles.HexNumber); - else if (args[0] == "ShadowBC") - RegAltBC.Word = ushort.Parse(args[1], NumberStyles.HexNumber); - else if (args[0] == "ShadowDE") - RegAltDE.Word = ushort.Parse(args[1], NumberStyles.HexNumber); - else if (args[0] == "ShadowHL") - RegAltHL.Word = ushort.Parse(args[1], NumberStyles.HexNumber); - else if (args[0] == "I") - RegI = byte.Parse(args[1], NumberStyles.HexNumber); - else if (args[0] == "R") - RegR = byte.Parse(args[1], NumberStyles.HexNumber); - else if (args[0] == "IX") - RegIX.Word = ushort.Parse(args[1], NumberStyles.HexNumber); - else if (args[0] == "IY") - RegIY.Word = ushort.Parse(args[1], NumberStyles.HexNumber); - else if (args[0] == "SP") - RegSP.Word = ushort.Parse(args[1], NumberStyles.HexNumber); - else if (args[0] == "PC") - RegPC.Word = ushort.Parse(args[1], NumberStyles.HexNumber); - else if (args[0] == "IRQ") - interrupt = bool.Parse(args[1]); - else if (args[0] == "NMI") - nonMaskableInterrupt = bool.Parse(args[1]); - else if (args[0] == "NMIPending") - nonMaskableInterruptPending = bool.Parse(args[1]); - else if (args[0] == "IM") - InterruptMode = int.Parse(args[1]); - else if (args[0] == "IFF1") - IFF1 = bool.Parse(args[1]); - else if (args[0] == "IFF2") - IFF2 = bool.Parse(args[1]); - else if (args[0] == "Halted") - Halted = bool.Parse(args[1]); - else if (args[0] == "ExecutedCycles") - TotalExecutedCycles = int.Parse(args[1]); - else if (args[0] == "PendingCycles") - PendingCycles = int.Parse(args[1]); + public void LoadStateText(TextReader reader) + { + while (true) + { + string[] args = reader.ReadLine().Split(' '); + if (args[0].Trim() == "") continue; + if (args[0] == "[/Z80]") break; + if (args[0] == "AF") + RegAF.Word = ushort.Parse(args[1], NumberStyles.HexNumber); + else if (args[0] == "BC") + RegBC.Word = ushort.Parse(args[1], NumberStyles.HexNumber); + else if (args[0] == "DE") + RegDE.Word = ushort.Parse(args[1], NumberStyles.HexNumber); + else if (args[0] == "HL") + RegHL.Word = ushort.Parse(args[1], NumberStyles.HexNumber); + else if (args[0] == "ShadowAF") + RegAltAF.Word = ushort.Parse(args[1], NumberStyles.HexNumber); + else if (args[0] == "ShadowBC") + RegAltBC.Word = ushort.Parse(args[1], NumberStyles.HexNumber); + else if (args[0] == "ShadowDE") + RegAltDE.Word = ushort.Parse(args[1], NumberStyles.HexNumber); + else if (args[0] == "ShadowHL") + RegAltHL.Word = ushort.Parse(args[1], NumberStyles.HexNumber); + else if (args[0] == "I") + RegI = byte.Parse(args[1], NumberStyles.HexNumber); + else if (args[0] == "R") + RegR = byte.Parse(args[1], NumberStyles.HexNumber); + else if (args[0] == "IX") + RegIX.Word = ushort.Parse(args[1], NumberStyles.HexNumber); + else if (args[0] == "IY") + RegIY.Word = ushort.Parse(args[1], NumberStyles.HexNumber); + else if (args[0] == "SP") + RegSP.Word = ushort.Parse(args[1], NumberStyles.HexNumber); + else if (args[0] == "PC") + RegPC.Word = ushort.Parse(args[1], NumberStyles.HexNumber); + else if (args[0] == "IRQ") + interrupt = bool.Parse(args[1]); + else if (args[0] == "NMI") + nonMaskableInterrupt = bool.Parse(args[1]); + else if (args[0] == "NMIPending") + nonMaskableInterruptPending = bool.Parse(args[1]); + else if (args[0] == "IM") + InterruptMode = int.Parse(args[1]); + else if (args[0] == "IFF1") + IFF1 = bool.Parse(args[1]); + else if (args[0] == "IFF2") + IFF2 = bool.Parse(args[1]); + else if (args[0] == "Halted") + Halted = bool.Parse(args[1]); + else if (args[0] == "ExecutedCycles") + TotalExecutedCycles = int.Parse(args[1]); + else if (args[0] == "PendingCycles") + PendingCycles = int.Parse(args[1]); - else - Console.WriteLine("Skipping unrecognized identifier " + args[0]); - } - } + else + Console.WriteLine("Skipping unrecognized identifier " + args[0]); + } + } - public void SaveStateBinary(BinaryWriter writer) - { - writer.Write(RegAF.Word); - writer.Write(RegBC.Word); - writer.Write(RegDE.Word); - writer.Write(RegHL.Word); - writer.Write(RegAltAF.Word); - writer.Write(RegAltBC.Word); - writer.Write(RegAltDE.Word); - writer.Write(RegAltHL.Word); - writer.Write(RegAltAF.Word); - writer.Write(RegI); - writer.Write(RegR); - writer.Write(RegIX.Word); - writer.Write(RegIY.Word); - writer.Write(RegSP.Word); - writer.Write(RegPC.Word); - writer.Write(interrupt); - writer.Write(nonMaskableInterrupt); - writer.Write(nonMaskableInterruptPending); - writer.Write(InterruptMode); - writer.Write(IFF1); - writer.Write(IFF2); - writer.Write(Halted); - writer.Write(TotalExecutedCycles); - writer.Write(PendingCycles); - } + public void SaveStateBinary(BinaryWriter writer) + { + writer.Write(RegAF.Word); + writer.Write(RegBC.Word); + writer.Write(RegDE.Word); + writer.Write(RegHL.Word); + writer.Write(RegAltAF.Word); + writer.Write(RegAltBC.Word); + writer.Write(RegAltDE.Word); + writer.Write(RegAltHL.Word); + writer.Write(RegAltAF.Word); + writer.Write(RegI); + writer.Write(RegR); + writer.Write(RegIX.Word); + writer.Write(RegIY.Word); + writer.Write(RegSP.Word); + writer.Write(RegPC.Word); + writer.Write(interrupt); + writer.Write(nonMaskableInterrupt); + writer.Write(nonMaskableInterruptPending); + writer.Write(InterruptMode); + writer.Write(IFF1); + writer.Write(IFF2); + writer.Write(Halted); + writer.Write(TotalExecutedCycles); + writer.Write(PendingCycles); + } - public void LoadStateBinary(BinaryReader reader) - { - RegAF.Word = reader.ReadUInt16(); - RegBC.Word = reader.ReadUInt16(); - RegDE.Word = reader.ReadUInt16(); - RegHL.Word = reader.ReadUInt16(); - RegAltAF.Word = reader.ReadUInt16(); - RegAltBC.Word = reader.ReadUInt16(); - RegAltDE.Word = reader.ReadUInt16(); - RegAltHL.Word = reader.ReadUInt16(); - RegAltAF.Word = reader.ReadUInt16(); - RegI = reader.ReadByte(); - RegR = reader.ReadByte(); - RegIX.Word = reader.ReadUInt16(); - RegIY.Word = reader.ReadUInt16(); - RegSP.Word = reader.ReadUInt16(); - RegPC.Word = reader.ReadUInt16(); - interrupt = reader.ReadBoolean(); - nonMaskableInterrupt = reader.ReadBoolean(); - nonMaskableInterruptPending = reader.ReadBoolean(); - InterruptMode = reader.ReadInt32(); - IFF1 = reader.ReadBoolean(); - IFF2 = reader.ReadBoolean(); - Halted = reader.ReadBoolean(); - TotalExecutedCycles = reader.ReadInt32(); - PendingCycles = reader.ReadInt32(); - } - } + public void LoadStateBinary(BinaryReader reader) + { + RegAF.Word = reader.ReadUInt16(); + RegBC.Word = reader.ReadUInt16(); + RegDE.Word = reader.ReadUInt16(); + RegHL.Word = reader.ReadUInt16(); + RegAltAF.Word = reader.ReadUInt16(); + RegAltBC.Word = reader.ReadUInt16(); + RegAltDE.Word = reader.ReadUInt16(); + RegAltHL.Word = reader.ReadUInt16(); + RegAltAF.Word = reader.ReadUInt16(); + RegI = reader.ReadByte(); + RegR = reader.ReadByte(); + RegIX.Word = reader.ReadUInt16(); + RegIY.Word = reader.ReadUInt16(); + RegSP.Word = reader.ReadUInt16(); + RegPC.Word = reader.ReadUInt16(); + interrupt = reader.ReadBoolean(); + nonMaskableInterrupt = reader.ReadBoolean(); + nonMaskableInterruptPending = reader.ReadBoolean(); + InterruptMode = reader.ReadInt32(); + IFF1 = reader.ReadBoolean(); + IFF2 = reader.ReadBoolean(); + Halted = reader.ReadBoolean(); + TotalExecutedCycles = reader.ReadInt32(); + PendingCycles = reader.ReadInt32(); + } + } } diff --git a/BizHawk.Emulation/CPUs/x86/Disassembler.cs b/BizHawk.Emulation/CPUs/x86/Disassembler.cs index acfbae8917..22d9a73b28 100644 --- a/BizHawk.Emulation/CPUs/x86/Disassembler.cs +++ b/BizHawk.Emulation/CPUs/x86/Disassembler.cs @@ -1,199 +1,199 @@ using System.Text; -namespace BizHawk.Emulation.CPUs.x86 +namespace BizHawk.Emulation.Common.Components.x86 { - public class DisassemblyInfo - { - public int Addr; - public string Mnemonic; - public string Args; - public string RawBytes; - public int Length; + public class DisassemblyInfo + { + public int Addr; + public string Mnemonic; + public string Args; + public string RawBytes; + public int Length; - public override string ToString() - { - return string.Format("{0:X6} {3,-12} {1,-8} {2}", Addr, Mnemonic, Args, RawBytes); - } - } + public override string ToString() + { + return string.Format("{0:X6} {3,-12} {1,-8} {2}", Addr, Mnemonic, Args, RawBytes); + } + } - public partial class x86 where CpuType : struct, x86CpuType - { - private ushort ReadWord(int addr) - { - return (ushort)(ReadMemory(addr++) + (ReadMemory(addr) << 8)); - } + public partial class x86 where CpuType : struct, x86CpuType + { + private ushort ReadWord(int addr) + { + return (ushort)(ReadMemory(addr++) + (ReadMemory(addr) << 8)); + } - private string DisassembleRM8(ref int addr) - { - byte ModRM = ReadMemory(addr++); - int mod = (ModRM >> 6) & 3; - int r = (ModRM >> 3) & 7; - int m = ModRM & 7; + private string DisassembleRM8(ref int addr) + { + byte ModRM = ReadMemory(addr++); + int mod = (ModRM >> 6) & 3; + int r = (ModRM >> 3) & 7; + int m = ModRM & 7; - string reg; - switch (r) - { - case 0: reg = "AL"; break; - case 1: reg = "CL"; break; - case 2: reg = "DL"; break; - case 3: reg = "BL"; break; - case 4: reg = "AH"; break; - case 5: reg = "CH"; break; - case 6: reg = "DH"; break; - case 7: reg = "BH"; break; - default: reg = "UNKNOWN"; break; - } - return reg+", "+DisassembleMod(ref addr, mod, m, 1); - } + string reg; + switch (r) + { + case 0: reg = "AL"; break; + case 1: reg = "CL"; break; + case 2: reg = "DL"; break; + case 3: reg = "BL"; break; + case 4: reg = "AH"; break; + case 5: reg = "CH"; break; + case 6: reg = "DH"; break; + case 7: reg = "BH"; break; + default: reg = "UNKNOWN"; break; + } + return reg + ", " + DisassembleMod(ref addr, mod, m, 1); + } - private string DisassembleMod(ref int addr, int mod, int m, int size) - { - string ret; - switch (mod) - { - case 0: - switch (m) - { - case 0: return "[BX+SI]"; - case 1: return "[BX+DI]"; - case 2: return "[BP+SI]"; - case 3: return "[BP+DI]"; - case 4: return "[SI]"; - case 5: return "[DI]"; - case 6: ret = string.Format("{0:X4}h", ReadWord(addr)); addr += 2; return ret; - case 7: return "[BX]"; - } - break; - case 1: - switch (m) - { - case 0: return string.Format("[BX+SI] + {0:X2}h", ReadMemory(addr++)); - case 1: return string.Format("[BX+DI] + {0:X2}h", ReadMemory(addr++)); - case 2: return string.Format("[BP+SI] + {0:X2}h", ReadMemory(addr++)); - case 3: return string.Format("[BP+DI] + {0:X2}h", ReadMemory(addr++)); - case 4: return string.Format("[SI] + {0:X2}h", ReadMemory(addr++)); - case 5: return string.Format("[DI] + {0:X2}h", ReadMemory(addr++)); - case 6: return string.Format("[BP] + {0:X2}h", ReadMemory(addr++)); - case 7: return string.Format("[BX] + {0:X2}h", ReadMemory(addr++)); - } - break; - case 2: - switch (m) - { - case 0: ret = string.Format("[BX+SI] + {0:X4}h", ReadWord(addr)); addr += 2; return ret; - case 1: ret = string.Format("[BX+DI] + {0:X4}h", ReadWord(addr)); addr += 2; return ret; - case 2: ret = string.Format("[BP+SI] + {0:X4}h", ReadWord(addr)); addr += 2; return ret; - case 3: ret = string.Format("[BP+DI] + {0:X4}h", ReadWord(addr)); addr += 2; return ret; - case 4: ret = string.Format("[SI] + {0:X4}h", ReadWord(addr)); addr += 2; return ret; - case 5: ret = string.Format("[DI] + {0:X4}h", ReadWord(addr)); addr += 2; return ret; - case 6: ret = string.Format("[BP] + {0:X4}h", ReadWord(addr)); addr += 2; return ret; - case 7: ret = string.Format("[BX] + {0:X4}h", ReadWord(addr)); addr += 2; return ret; - } - break; - case 3: - switch (m) - { - case 0: return size == 1 ? "AL" : "AX"; - case 1: return size == 1 ? "CL" : "CX"; - case 2: return size == 1 ? "DL" : "DX"; - case 3: return size == 1 ? "BL" : "BX"; - case 4: return size == 1 ? "AH" : "SP"; - case 5: return size == 1 ? "CH" : "BP"; - case 6: return size == 1 ? "DH" : "SI"; - case 7: return size == 1 ? "BH" : "DI"; - } - break; - } - return "Disassembly Error"; - } + private string DisassembleMod(ref int addr, int mod, int m, int size) + { + string ret; + switch (mod) + { + case 0: + switch (m) + { + case 0: return "[BX+SI]"; + case 1: return "[BX+DI]"; + case 2: return "[BP+SI]"; + case 3: return "[BP+DI]"; + case 4: return "[SI]"; + case 5: return "[DI]"; + case 6: ret = string.Format("{0:X4}h", ReadWord(addr)); addr += 2; return ret; + case 7: return "[BX]"; + } + break; + case 1: + switch (m) + { + case 0: return string.Format("[BX+SI] + {0:X2}h", ReadMemory(addr++)); + case 1: return string.Format("[BX+DI] + {0:X2}h", ReadMemory(addr++)); + case 2: return string.Format("[BP+SI] + {0:X2}h", ReadMemory(addr++)); + case 3: return string.Format("[BP+DI] + {0:X2}h", ReadMemory(addr++)); + case 4: return string.Format("[SI] + {0:X2}h", ReadMemory(addr++)); + case 5: return string.Format("[DI] + {0:X2}h", ReadMemory(addr++)); + case 6: return string.Format("[BP] + {0:X2}h", ReadMemory(addr++)); + case 7: return string.Format("[BX] + {0:X2}h", ReadMemory(addr++)); + } + break; + case 2: + switch (m) + { + case 0: ret = string.Format("[BX+SI] + {0:X4}h", ReadWord(addr)); addr += 2; return ret; + case 1: ret = string.Format("[BX+DI] + {0:X4}h", ReadWord(addr)); addr += 2; return ret; + case 2: ret = string.Format("[BP+SI] + {0:X4}h", ReadWord(addr)); addr += 2; return ret; + case 3: ret = string.Format("[BP+DI] + {0:X4}h", ReadWord(addr)); addr += 2; return ret; + case 4: ret = string.Format("[SI] + {0:X4}h", ReadWord(addr)); addr += 2; return ret; + case 5: ret = string.Format("[DI] + {0:X4}h", ReadWord(addr)); addr += 2; return ret; + case 6: ret = string.Format("[BP] + {0:X4}h", ReadWord(addr)); addr += 2; return ret; + case 7: ret = string.Format("[BX] + {0:X4}h", ReadWord(addr)); addr += 2; return ret; + } + break; + case 3: + switch (m) + { + case 0: return size == 1 ? "AL" : "AX"; + case 1: return size == 1 ? "CL" : "CX"; + case 2: return size == 1 ? "DL" : "DX"; + case 3: return size == 1 ? "BL" : "BX"; + case 4: return size == 1 ? "AH" : "SP"; + case 5: return size == 1 ? "CH" : "BP"; + case 6: return size == 1 ? "DH" : "SI"; + case 7: return size == 1 ? "BH" : "DI"; + } + break; + } + return "Disassembly Error"; + } - public DisassemblyInfo Disassemble(int addr) - { - var info = new DisassemblyInfo { Addr = addr }; - byte op1 = ReadMemory(addr++); - switch (op1) - { - case 0x02: // ADD r8,r/m8 - info.Mnemonic = "ADD"; - info.Args = DisassembleRM8(ref addr); - break; - case 0xB0: // MOV AL, immed - info.Mnemonic = "MOV"; - info.Args = string.Format("AL, {0:X2}h", ReadMemory(addr++)); - break; - case 0xB1: // MOV CL, immed - info.Mnemonic = "MOV"; - info.Args = string.Format("CL, {0:X2}h", ReadMemory(addr++)); - break; - case 0xB2: // MOV DL, immed - info.Mnemonic = "MOV"; - info.Args = string.Format("DL, {0:X2}h", ReadMemory(addr++)); - break; - case 0xB3: // MOV BL, immed - info.Mnemonic = "MOV"; - info.Args = string.Format("BL, {0:X2}h", ReadMemory(addr++)); - break; - case 0xB4: // MOV AH, immed - info.Mnemonic = "MOV"; - info.Args = string.Format("AH, {0:X2}h", ReadMemory(addr++)); - break; - case 0xB5: // MOV CH, immed - info.Mnemonic = "MOV"; - info.Args = string.Format("CH, {0:X2}h", ReadMemory(addr++)); - break; - case 0xB6: // MOV DH, immed - info.Mnemonic = "MOV"; - info.Args = string.Format("DH, {0:X2}h", ReadMemory(addr++)); - break; - case 0xB7: // MOV BH, immed - info.Mnemonic = "MOV"; - info.Args = string.Format("BH, {0:X2}h", ReadMemory(addr++)); - break; - case 0xB8: // MOV AX, immed - info.Mnemonic = "MOV"; - info.Args = string.Format("AX, {0:X4}h", ReadWord(addr)); addr += 2; - break; - case 0xB9: // MOV CX, immed - info.Mnemonic = "MOV"; - info.Args = string.Format("CX, {0:X4}h", ReadWord(addr)); addr += 2; - break; - case 0xBA: // MOV DX, immed - info.Mnemonic = "MOV"; - info.Args = string.Format("DX, {0:X4}h", ReadWord(addr)); addr += 2; - break; - case 0xBB: // MOV BX, immed - info.Mnemonic = "MOV"; - info.Args = string.Format("BX, {0:X4}h", ReadWord(addr)); addr += 2; - break; - case 0xBC: // MOV SP, immed - info.Mnemonic = "MOV"; - info.Args = string.Format("SP, {0:X4}h", ReadWord(addr)); addr += 2; - break; - case 0xBD: // MOV BP, immed - info.Mnemonic = "MOV"; - info.Args = string.Format("BP, {0:X4}h", ReadWord(addr)); addr += 2; - break; - case 0xBE: // MOV SI, immed - info.Mnemonic = "MOV"; - info.Args = string.Format("SI, {0:X4}h", ReadWord(addr)); addr += 2; - break; - case 0xBF: // MOV DI, immed - info.Mnemonic = "MOV"; - info.Args = string.Format("DI, {0:X4}h", ReadWord(addr)); addr += 2; - break; - default: - info.Mnemonic = "DB"; - info.Args = string.Format("{0:X2}h", op1); - break; - } + public DisassemblyInfo Disassemble(int addr) + { + var info = new DisassemblyInfo { Addr = addr }; + byte op1 = ReadMemory(addr++); + switch (op1) + { + case 0x02: // ADD r8,r/m8 + info.Mnemonic = "ADD"; + info.Args = DisassembleRM8(ref addr); + break; + case 0xB0: // MOV AL, immed + info.Mnemonic = "MOV"; + info.Args = string.Format("AL, {0:X2}h", ReadMemory(addr++)); + break; + case 0xB1: // MOV CL, immed + info.Mnemonic = "MOV"; + info.Args = string.Format("CL, {0:X2}h", ReadMemory(addr++)); + break; + case 0xB2: // MOV DL, immed + info.Mnemonic = "MOV"; + info.Args = string.Format("DL, {0:X2}h", ReadMemory(addr++)); + break; + case 0xB3: // MOV BL, immed + info.Mnemonic = "MOV"; + info.Args = string.Format("BL, {0:X2}h", ReadMemory(addr++)); + break; + case 0xB4: // MOV AH, immed + info.Mnemonic = "MOV"; + info.Args = string.Format("AH, {0:X2}h", ReadMemory(addr++)); + break; + case 0xB5: // MOV CH, immed + info.Mnemonic = "MOV"; + info.Args = string.Format("CH, {0:X2}h", ReadMemory(addr++)); + break; + case 0xB6: // MOV DH, immed + info.Mnemonic = "MOV"; + info.Args = string.Format("DH, {0:X2}h", ReadMemory(addr++)); + break; + case 0xB7: // MOV BH, immed + info.Mnemonic = "MOV"; + info.Args = string.Format("BH, {0:X2}h", ReadMemory(addr++)); + break; + case 0xB8: // MOV AX, immed + info.Mnemonic = "MOV"; + info.Args = string.Format("AX, {0:X4}h", ReadWord(addr)); addr += 2; + break; + case 0xB9: // MOV CX, immed + info.Mnemonic = "MOV"; + info.Args = string.Format("CX, {0:X4}h", ReadWord(addr)); addr += 2; + break; + case 0xBA: // MOV DX, immed + info.Mnemonic = "MOV"; + info.Args = string.Format("DX, {0:X4}h", ReadWord(addr)); addr += 2; + break; + case 0xBB: // MOV BX, immed + info.Mnemonic = "MOV"; + info.Args = string.Format("BX, {0:X4}h", ReadWord(addr)); addr += 2; + break; + case 0xBC: // MOV SP, immed + info.Mnemonic = "MOV"; + info.Args = string.Format("SP, {0:X4}h", ReadWord(addr)); addr += 2; + break; + case 0xBD: // MOV BP, immed + info.Mnemonic = "MOV"; + info.Args = string.Format("BP, {0:X4}h", ReadWord(addr)); addr += 2; + break; + case 0xBE: // MOV SI, immed + info.Mnemonic = "MOV"; + info.Args = string.Format("SI, {0:X4}h", ReadWord(addr)); addr += 2; + break; + case 0xBF: // MOV DI, immed + info.Mnemonic = "MOV"; + info.Args = string.Format("DI, {0:X4}h", ReadWord(addr)); addr += 2; + break; + default: + info.Mnemonic = "DB"; + info.Args = string.Format("{0:X2}h", op1); + break; + } - info.Length = addr - info.Addr; - var sb = new StringBuilder(); - for (int p = info.Addr; p < info.Addr + info.Length; p++) - sb.AppendFormat("{0:X2}", ReadMemory(p)); - info.RawBytes = sb.ToString(); + info.Length = addr - info.Addr; + var sb = new StringBuilder(); + for (int p = info.Addr; p < info.Addr + info.Length; p++) + sb.AppendFormat("{0:X2}", ReadMemory(p)); + info.RawBytes = sb.ToString(); - return info; - } - } + return info; + } + } } diff --git a/BizHawk.Emulation/CPUs/x86/Execute.cs b/BizHawk.Emulation/CPUs/x86/Execute.cs index f9f64ea8dc..62e1693b30 100644 --- a/BizHawk.Emulation/CPUs/x86/Execute.cs +++ b/BizHawk.Emulation/CPUs/x86/Execute.cs @@ -1,84 +1,84 @@ using System; -namespace BizHawk.Emulation.CPUs.x86 +namespace BizHawk.Emulation.Common.Components.x86 { - public partial class x86 where CpuType: struct, x86CpuType - { - public void Execute(int cycles) - { - Console.WriteLine(Disassemble((CS << 4) + IP)); - byte opcode1 = ReadMemory((CS << 4) + IP); - IP++; - - switch (opcode1) - { - case 0xB0: // MOV AL, imm - AL = ReadMemory((CS << 4) + IP++); - PendingCycles -= timing_mov_ri8; - break; - case 0xB1: // MOV CL, immed - CL = ReadMemory((CS << 4) + IP++); - PendingCycles -= timing_mov_ri8; - break; - case 0xB2: // MOV DL, immed - DL = ReadMemory((CS << 4) + IP++); - PendingCycles -= timing_mov_ri8; - break; - case 0xB3: // MOV BL, immed - BL = ReadMemory((CS << 4) + IP++); - PendingCycles -= timing_mov_ri8; - break; - case 0xB4: // MOV AH, immed - AH = ReadMemory((CS << 4) + IP++); - PendingCycles -= timing_mov_ri8; - break; - case 0xB5: // MOV CH, immed - CH = ReadMemory((CS << 4) + IP++); - PendingCycles -= timing_mov_ri8; - break; - case 0xB6: // MOV DH, immed - DH = ReadMemory((CS << 4) + IP++); - PendingCycles -= timing_mov_ri8; - break; - case 0xB7: // MOV BH, immed - BH = ReadMemory((CS << 4) + IP++); - PendingCycles -= timing_mov_ri8; - break; - case 0xB8: // MOV AX, immed - AX = (ushort)(ReadMemory((CS << 4) + IP++) + (ReadMemory((CS << 4) + IP++) << 8)); - PendingCycles -= timing_mov_ri16; - break; - case 0xB9: // MOV CX, imm - CX = (ushort)(ReadMemory((CS << 4) + IP++) + (ReadMemory((CS << 4) + IP++) << 8)); - PendingCycles -= timing_mov_ri16; - break; - case 0xBA: // MOV DX, immed - DX = (ushort)(ReadMemory((CS << 4) + IP++) + (ReadMemory((CS << 4) + IP++) << 8)); - PendingCycles -= timing_mov_ri16; - break; - case 0xBB: // MOV BX, immed - BX = (ushort)(ReadMemory((CS << 4) + IP++) + (ReadMemory((CS << 4) + IP++) << 8)); - PendingCycles -= timing_mov_ri16; - break; - case 0xBC: // MOV SP, immed - SP = (ushort)(ReadMemory((CS << 4) + IP++) + (ReadMemory((CS << 4) + IP++) << 8)); - PendingCycles -= timing_mov_ri16; - break; - case 0xBD: // MOV BP, immed - BP = (ushort)(ReadMemory((CS << 4) + IP++) + (ReadMemory((CS << 4) + IP++) << 8)); - PendingCycles -= timing_mov_ri16; - break; - case 0xBE: // MOV SI, immed - SI = (ushort)(ReadMemory((CS << 4) + IP++) + (ReadMemory((CS << 4) + IP++) << 8)); - PendingCycles -= timing_mov_ri16; - break; - case 0xBF: // MOV DI, immed - DI = (ushort)(ReadMemory((CS << 4) + IP++) + (ReadMemory((CS << 4) + IP++) << 8)); - PendingCycles -= timing_mov_ri16; - break; - default: - throw new NotImplementedException(); - } - } - } + public partial class x86 where CpuType : struct, x86CpuType + { + public void Execute(int cycles) + { + Console.WriteLine(Disassemble((CS << 4) + IP)); + byte opcode1 = ReadMemory((CS << 4) + IP); + IP++; + + switch (opcode1) + { + case 0xB0: // MOV AL, imm + AL = ReadMemory((CS << 4) + IP++); + PendingCycles -= timing_mov_ri8; + break; + case 0xB1: // MOV CL, immed + CL = ReadMemory((CS << 4) + IP++); + PendingCycles -= timing_mov_ri8; + break; + case 0xB2: // MOV DL, immed + DL = ReadMemory((CS << 4) + IP++); + PendingCycles -= timing_mov_ri8; + break; + case 0xB3: // MOV BL, immed + BL = ReadMemory((CS << 4) + IP++); + PendingCycles -= timing_mov_ri8; + break; + case 0xB4: // MOV AH, immed + AH = ReadMemory((CS << 4) + IP++); + PendingCycles -= timing_mov_ri8; + break; + case 0xB5: // MOV CH, immed + CH = ReadMemory((CS << 4) + IP++); + PendingCycles -= timing_mov_ri8; + break; + case 0xB6: // MOV DH, immed + DH = ReadMemory((CS << 4) + IP++); + PendingCycles -= timing_mov_ri8; + break; + case 0xB7: // MOV BH, immed + BH = ReadMemory((CS << 4) + IP++); + PendingCycles -= timing_mov_ri8; + break; + case 0xB8: // MOV AX, immed + AX = (ushort)(ReadMemory((CS << 4) + IP++) + (ReadMemory((CS << 4) + IP++) << 8)); + PendingCycles -= timing_mov_ri16; + break; + case 0xB9: // MOV CX, imm + CX = (ushort)(ReadMemory((CS << 4) + IP++) + (ReadMemory((CS << 4) + IP++) << 8)); + PendingCycles -= timing_mov_ri16; + break; + case 0xBA: // MOV DX, immed + DX = (ushort)(ReadMemory((CS << 4) + IP++) + (ReadMemory((CS << 4) + IP++) << 8)); + PendingCycles -= timing_mov_ri16; + break; + case 0xBB: // MOV BX, immed + BX = (ushort)(ReadMemory((CS << 4) + IP++) + (ReadMemory((CS << 4) + IP++) << 8)); + PendingCycles -= timing_mov_ri16; + break; + case 0xBC: // MOV SP, immed + SP = (ushort)(ReadMemory((CS << 4) + IP++) + (ReadMemory((CS << 4) + IP++) << 8)); + PendingCycles -= timing_mov_ri16; + break; + case 0xBD: // MOV BP, immed + BP = (ushort)(ReadMemory((CS << 4) + IP++) + (ReadMemory((CS << 4) + IP++) << 8)); + PendingCycles -= timing_mov_ri16; + break; + case 0xBE: // MOV SI, immed + SI = (ushort)(ReadMemory((CS << 4) + IP++) + (ReadMemory((CS << 4) + IP++) << 8)); + PendingCycles -= timing_mov_ri16; + break; + case 0xBF: // MOV DI, immed + DI = (ushort)(ReadMemory((CS << 4) + IP++) + (ReadMemory((CS << 4) + IP++) << 8)); + PendingCycles -= timing_mov_ri16; + break; + default: + throw new NotImplementedException(); + } + } + } } diff --git a/BizHawk.Emulation/CPUs/x86/Timing.cs b/BizHawk.Emulation/CPUs/x86/Timing.cs index b3a696ef64..2f62a98a8c 100644 --- a/BizHawk.Emulation/CPUs/x86/Timing.cs +++ b/BizHawk.Emulation/CPUs/x86/Timing.cs @@ -1,19 +1,19 @@ -namespace BizHawk.Emulation.CPUs.x86 +namespace BizHawk.Emulation.Common.Components.x86 { - public partial class x86 where CpuType : struct, x86CpuType - { - // TODO test if static on these is a performance boost - // it would be appropriate if so because closed types have their own static variables - private int timing_mov_ri8; - private int timing_mov_ri16; + public partial class x86 where CpuType : struct, x86CpuType + { + // TODO test if static on these is a performance boost + // it would be appropriate if so because closed types have their own static variables + private int timing_mov_ri8; + private int timing_mov_ri16; - private void InitTiming() - { - if (typeof(CpuType) == typeof(Intel8086)) - { - timing_mov_ri8 = 4; - timing_mov_ri16 = 4; - } - } - } + private void InitTiming() + { + if (typeof(CpuType) == typeof(Intel8086)) + { + timing_mov_ri8 = 4; + timing_mov_ri16 = 4; + } + } + } } diff --git a/BizHawk.Emulation/CPUs/x86/x86.cs b/BizHawk.Emulation/CPUs/x86/x86.cs index df940bfa82..5c1b86265b 100644 --- a/BizHawk.Emulation/CPUs/x86/x86.cs +++ b/BizHawk.Emulation/CPUs/x86/x86.cs @@ -1,100 +1,100 @@ using System; using System.Runtime.InteropServices; -namespace BizHawk.Emulation.CPUs.x86 +namespace BizHawk.Emulation.Common.Components.x86 { - public interface x86CpuType { }; - public struct Intel8086 : x86CpuType { }; + public interface x86CpuType { }; + public struct Intel8086 : x86CpuType { }; - public sealed partial class x86 where CpuType: struct, x86CpuType - { - // Machine State - public Register16 RegAX; - public Register16 RegBX; - public Register16 RegCX; - public Register16 RegDX; + public sealed partial class x86 where CpuType : struct, x86CpuType + { + // Machine State + public Register16 RegAX; + public Register16 RegBX; + public Register16 RegCX; + public Register16 RegDX; - public ushort CS; - public ushort DS; - public ushort ES; - public ushort SS; + public ushort CS; + public ushort DS; + public ushort ES; + public ushort SS; - public ushort SI; - public ushort DI; - public ushort IP; - public ushort SP; - public ushort BP; + public ushort SI; + public ushort DI; + public ushort IP; + public ushort SP; + public ushort BP; - public bool CF; - public bool PF; - public bool AF; - public bool ZF; - public bool SF; - public bool TP; - public bool IF; - public bool DF; - public bool OF; + public bool CF; + public bool PF; + public bool AF; + public bool ZF; + public bool SF; + public bool TP; + public bool IF; + public bool DF; + public bool OF; - public ushort Flags - { - get - { - ushort value = 2; - if (CF) value |= 1; - if (PF) value |= 4; - if (AF) value |= 16; - if (ZF) value |= 64; - if (SF) value |= 128; - if (TP) value |= 256; - if (IF) value |= 512; - if (DF) value |= 1024; - if (OF) value |= 2048; - return value; - } - } + public ushort Flags + { + get + { + ushort value = 2; + if (CF) value |= 1; + if (PF) value |= 4; + if (AF) value |= 16; + if (ZF) value |= 64; + if (SF) value |= 128; + if (TP) value |= 256; + if (IF) value |= 512; + if (DF) value |= 1024; + if (OF) value |= 2048; + return value; + } + } - public int PendingCycles; - public int TotalExecutedCycles; + public int PendingCycles; + public int TotalExecutedCycles; - // Memory Access - public Func ReadMemory; - public Action WriteMemory; + // Memory Access + public Func ReadMemory; + public Action WriteMemory; - public x86() - { - InitTiming(); - } + public x86() + { + InitTiming(); + } - // We expect these properties to get inlined by the CLR -- at some point we should test this assumption - public ushort AX { get { return RegAX.Word; } set { RegAX.Word = value; } } - public ushort BX { get { return RegBX.Word; } set { RegBX.Word = value; } } - public ushort CX { get { return RegCX.Word; } set { RegCX.Word = value; } } - public ushort DX { get { return RegDX.Word; } set { RegDX.Word = value; } } - public byte AL { get { return RegAX.Low; } set { RegAX.Low = value; } } - public byte BL { get { return RegBX.Low; } set { RegBX.Low = value; } } - public byte CL { get { return RegCX.Low; } set { RegCX.Low = value; } } - public byte DL { get { return RegDX.Low; } set { RegDX.Low = value; } } - public byte AH { get { return RegAX.High; } set { RegAX.High = value; } } - public byte BH { get { return RegBX.High; } set { RegBX.High = value; } } - public byte CH { get { return RegCX.High; } set { RegCX.High = value; } } - public byte DH { get { return RegDX.High; } set { RegDX.High = value; } } - } + // We expect these properties to get inlined by the CLR -- at some point we should test this assumption + public ushort AX { get { return RegAX.Word; } set { RegAX.Word = value; } } + public ushort BX { get { return RegBX.Word; } set { RegBX.Word = value; } } + public ushort CX { get { return RegCX.Word; } set { RegCX.Word = value; } } + public ushort DX { get { return RegDX.Word; } set { RegDX.Word = value; } } + public byte AL { get { return RegAX.Low; } set { RegAX.Low = value; } } + public byte BL { get { return RegBX.Low; } set { RegBX.Low = value; } } + public byte CL { get { return RegCX.Low; } set { RegCX.Low = value; } } + public byte DL { get { return RegDX.Low; } set { RegDX.Low = value; } } + public byte AH { get { return RegAX.High; } set { RegAX.High = value; } } + public byte BH { get { return RegBX.High; } set { RegBX.High = value; } } + public byte CH { get { return RegCX.High; } set { RegCX.High = value; } } + public byte DH { get { return RegDX.High; } set { RegDX.High = value; } } + } - [StructLayout(LayoutKind.Explicit)] - public struct Register16 - { - [FieldOffset(0)] - public ushort Word; + [StructLayout(LayoutKind.Explicit)] + public struct Register16 + { + [FieldOffset(0)] + public ushort Word; - [FieldOffset(0)] - public byte Low; + [FieldOffset(0)] + public byte Low; - [FieldOffset(1)] - public byte High; + [FieldOffset(1)] + public byte High; - public override string ToString() - { - return String.Format("{0:X4}", Word); - } - } + public override string ToString() + { + return String.Format("{0:X4}", Word); + } + } } \ No newline at end of file diff --git a/BizHawk.Emulation/Calculator/TI83.cs b/BizHawk.Emulation/Calculator/TI83.cs index 51ef59257f..e10738999a 100644 --- a/BizHawk.Emulation/Calculator/TI83.cs +++ b/BizHawk.Emulation/Calculator/TI83.cs @@ -5,7 +5,7 @@ using System.Collections.Generic; using BizHawk.Common; using BizHawk.Emulation.Common; -using BizHawk.Emulation.CPUs.Z80; +using BizHawk.Emulation.Common.Components.Z80; //http://www.ticalc.org/pub/text/calcinfo/ diff --git a/BizHawk.Emulation/Computers/Commodore64/Disk/VIC1541.cs b/BizHawk.Emulation/Computers/Commodore64/Disk/VIC1541.cs index 132bb78410..3359da36d8 100644 --- a/BizHawk.Emulation/Computers/Commodore64/Disk/VIC1541.cs +++ b/BizHawk.Emulation/Computers/Commodore64/Disk/VIC1541.cs @@ -1,5 +1,5 @@ using System; -using BizHawk.Emulation.CPUs.M6502; +using BizHawk.Emulation.Common.Components.M6502; #if false diff --git a/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Cpu.Internal.cs b/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Cpu.Internal.cs index 4e768fb95b..60298404b3 100644 --- a/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Cpu.Internal.cs +++ b/BizHawk.Emulation/Computers/Commodore64/Experimental/Chips/Internals/Cpu.Internal.cs @@ -1,9 +1,10 @@ -using BizHawk.Emulation.CPUs.M6502; -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; +using BizHawk.Emulation.Common.Components.M6502; + namespace BizHawk.Emulation.Cores.Computers.Commodore64.Experimental { sealed public partial class Cpu diff --git a/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6510.cs b/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6510.cs index 7942d98f12..7f8f629444 100644 --- a/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6510.cs +++ b/BizHawk.Emulation/Computers/Commodore64/MOS/MOS6510.cs @@ -1,9 +1,9 @@ -using BizHawk.Emulation.CPUs.M6502; -using System; +using System; using System.Collections.Generic; using System.Runtime.InteropServices; using BizHawk.Common; +using BizHawk.Emulation.Common.Components.M6502; namespace BizHawk.Emulation.Cores.Computers.Commodore64 { diff --git a/BizHawk.Emulation/Consoles/Atari/2600/Atari2600.Core.cs b/BizHawk.Emulation/Consoles/Atari/2600/Atari2600.Core.cs index 2b4ebfd509..d30113b889 100644 --- a/BizHawk.Emulation/Consoles/Atari/2600/Atari2600.Core.cs +++ b/BizHawk.Emulation/Consoles/Atari/2600/Atari2600.Core.cs @@ -1,7 +1,7 @@ using System; using BizHawk.Common; -using BizHawk.Emulation.CPUs.M6502; +using BizHawk.Emulation.Common.Components.M6502; namespace BizHawk.Emulation.Cores.Atari.Atari2600 diff --git a/BizHawk.Emulation/Consoles/Coleco/ColecoVision.cs b/BizHawk.Emulation/Consoles/Coleco/ColecoVision.cs index e62a4464fb..0488208ac1 100644 --- a/BizHawk.Emulation/Consoles/Coleco/ColecoVision.cs +++ b/BizHawk.Emulation/Consoles/Coleco/ColecoVision.cs @@ -4,7 +4,7 @@ using System.IO; using BizHawk.Common; using BizHawk.Emulation.Common; -using BizHawk.Emulation.CPUs.Z80; +using BizHawk.Emulation.Common.Components.Z80; using BizHawk.Emulation.Sound; namespace BizHawk.Emulation.Cores.ColecoVision diff --git a/BizHawk.Emulation/Consoles/Coleco/TMS9918A.cs b/BizHawk.Emulation/Consoles/Coleco/TMS9918A.cs index 20900a7e23..82b3edea4b 100644 --- a/BizHawk.Emulation/Consoles/Coleco/TMS9918A.cs +++ b/BizHawk.Emulation/Consoles/Coleco/TMS9918A.cs @@ -4,7 +4,7 @@ using System.IO; using BizHawk.Common; using BizHawk.Emulation.Common; -using BizHawk.Emulation.CPUs.Z80; +using BizHawk.Emulation.Common.Components.Z80; namespace BizHawk.Emulation.Cores.ColecoVision { diff --git a/BizHawk.Emulation/Consoles/Intellivision/Intellivision.cs b/BizHawk.Emulation/Consoles/Intellivision/Intellivision.cs index 3d64959664..0abdfc181f 100644 --- a/BizHawk.Emulation/Consoles/Intellivision/Intellivision.cs +++ b/BizHawk.Emulation/Consoles/Intellivision/Intellivision.cs @@ -3,7 +3,7 @@ using System.IO; using System.Collections.Generic; using BizHawk.Emulation.Common; -using BizHawk.Emulation.CPUs.CP1610; +using BizHawk.Emulation.Common.Components.CP1610; namespace BizHawk.Emulation.Cores.Intellivision { diff --git a/BizHawk.Emulation/Consoles/Nintendo/Gameboy/Gambatte.cs b/BizHawk.Emulation/Consoles/Nintendo/Gameboy/Gambatte.cs index 302a8c8d35..5d25db6555 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/Gameboy/Gambatte.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/Gameboy/Gambatte.cs @@ -543,7 +543,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy s[10] & 0xff, s[11] != 0 ? "skip" : "", s[12] & 0xff, - CPUs.Z80GB.NewDisassembler.Disassemble((ushort)s[1], (addr) => LibGambatte.gambatte_cpuread(GambatteState, addr), out unused).PadRight(30) + Common.Components.Z80GB.NewDisassembler.Disassemble((ushort)s[1], (addr) => LibGambatte.gambatte_cpuread(GambatteState, addr), out unused).PadRight(30) )); } diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Core.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Core.cs index 6347562a37..06230f6d96 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/Core.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Core.cs @@ -4,7 +4,7 @@ using System.Runtime.CompilerServices; using BizHawk.Common; using BizHawk.Emulation.Common; -using BizHawk.Emulation.CPUs.M6502; +using BizHawk.Emulation.Common.Components.M6502; #pragma warning disable 162 diff --git a/BizHawk.Emulation/Consoles/PC Engine/PCEngine.cs b/BizHawk.Emulation/Consoles/PC Engine/PCEngine.cs index c835f42f11..26fb771276 100644 --- a/BizHawk.Emulation/Consoles/PC Engine/PCEngine.cs +++ b/BizHawk.Emulation/Consoles/PC Engine/PCEngine.cs @@ -5,7 +5,7 @@ using System.IO; using BizHawk.Common; using BizHawk.Emulation.Common; -using BizHawk.Emulation.CPUs.H6280; +using BizHawk.Emulation.Common.Components.H6280; using BizHawk.Emulation.DiscSystem; using BizHawk.Emulation.Sound; diff --git a/BizHawk.Emulation/Consoles/PC Engine/VDC.cs b/BizHawk.Emulation/Consoles/PC Engine/VDC.cs index 4ddde8af4d..83e58fbbdc 100644 --- a/BizHawk.Emulation/Consoles/PC Engine/VDC.cs +++ b/BizHawk.Emulation/Consoles/PC Engine/VDC.cs @@ -4,7 +4,7 @@ using System.IO; using BizHawk.Common; using BizHawk.Emulation.Common; -using BizHawk.Emulation.CPUs.H6280; +using BizHawk.Emulation.Common.Components.H6280; namespace BizHawk.Emulation.Cores.PCEngine { diff --git a/BizHawk.Emulation/Consoles/PC Engine/VPC.cs b/BizHawk.Emulation/Consoles/PC Engine/VPC.cs index 5c8cc360a3..26285381c8 100644 --- a/BizHawk.Emulation/Consoles/PC Engine/VPC.cs +++ b/BizHawk.Emulation/Consoles/PC Engine/VPC.cs @@ -3,7 +3,7 @@ using System.IO; using BizHawk.Common; using BizHawk.Emulation.Common; -using BizHawk.Emulation.CPUs.H6280; +using BizHawk.Emulation.Common.Components.H6280; namespace BizHawk.Emulation.Cores.PCEngine { diff --git a/BizHawk.Emulation/Consoles/Sega/Genesis/Genesis.cs b/BizHawk.Emulation/Consoles/Sega/Genesis/Genesis.cs index 25d7092b98..e4743b74b3 100644 --- a/BizHawk.Emulation/Consoles/Sega/Genesis/Genesis.cs +++ b/BizHawk.Emulation/Consoles/Sega/Genesis/Genesis.cs @@ -7,8 +7,8 @@ using System.Runtime.InteropServices; using BizHawk.Common; using BizHawk.Emulation.Common; -using BizHawk.Emulation.CPUs.M68000; -using BizHawk.Emulation.CPUs.Z80; +using BizHawk.Emulation.Common.Components.M68000; +using BizHawk.Emulation.Common.Components.Z80; using BizHawk.Emulation.Sound; using Native68000; diff --git a/BizHawk.Emulation/Consoles/Sega/SMS/SMS.cs b/BizHawk.Emulation/Consoles/Sega/SMS/SMS.cs index c09421e80f..3f7bcfb70f 100644 --- a/BizHawk.Emulation/Consoles/Sega/SMS/SMS.cs +++ b/BizHawk.Emulation/Consoles/Sega/SMS/SMS.cs @@ -5,7 +5,7 @@ using System.IO; using BizHawk.Common; using BizHawk.Emulation.Common; -using BizHawk.Emulation.CPUs.Z80; +using BizHawk.Emulation.Common.Components.Z80; using BizHawk.Emulation.Sound; /***************************************************** diff --git a/BizHawk.Emulation/Consoles/Sega/SMS/VDP.cs b/BizHawk.Emulation/Consoles/Sega/SMS/VDP.cs index d1ad4d26e9..43193a5850 100644 --- a/BizHawk.Emulation/Consoles/Sega/SMS/VDP.cs +++ b/BizHawk.Emulation/Consoles/Sega/SMS/VDP.cs @@ -4,7 +4,7 @@ using System.IO; using BizHawk.Common; using BizHawk.Emulation.Common; -using BizHawk.Emulation.CPUs.Z80; +using BizHawk.Emulation.Common.Components.Z80; namespace BizHawk.Emulation.Cores.Sega.MasterSystem