namespace changes to BizHawk.Emulation Cpus
This commit is contained in:
parent
c076931d0c
commit
906c0316a6
|
@ -1,6 +1,6 @@
|
|||
using System.Text;
|
||||
|
||||
namespace BizHawk.Emulation.CPUs.M68000
|
||||
namespace BizHawk.Emulation.Common.Components.M68000
|
||||
{
|
||||
public sealed class DisassemblyInfo
|
||||
{
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
// Status Registers
|
||||
int InterruptMaskLevel;
|
||||
bool s, m;
|
||||
int usp, ssp;
|
||||
|
||||
/// <summary>Machine/Interrupt mode</summary>
|
||||
public bool M { get { return m; } set { m = value; } } // TODO probably have some switch logic maybe
|
||||
/// <summary>Machine/Interrupt mode</summary>
|
||||
public bool M { get { return m; } set { m = value; } } // TODO probably have some switch logic maybe
|
||||
|
||||
/// <summary>Supervisor/User mode</summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>Supervisor/User mode</summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Extend Flag</summary>
|
||||
public bool X;
|
||||
/// <summary>Negative Flag</summary>
|
||||
public bool N;
|
||||
/// <summary>Zero Flag</summary>
|
||||
public bool Z;
|
||||
/// <summary>Overflow Flag</summary>
|
||||
public bool V;
|
||||
/// <summary>Carry Flag</summary>
|
||||
public bool C;
|
||||
/// <summary>Extend Flag</summary>
|
||||
public bool X;
|
||||
/// <summary>Negative Flag</summary>
|
||||
public bool N;
|
||||
/// <summary>Zero Flag</summary>
|
||||
public bool Z;
|
||||
/// <summary>Overflow Flag</summary>
|
||||
public bool V;
|
||||
/// <summary>Carry Flag</summary>
|
||||
public bool C;
|
||||
|
||||
/// <summary>Status Register</summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
/// <summary>Status Register</summary>
|
||||
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 int Interrupt { get; set; }
|
||||
public int Interrupt { get; set; }
|
||||
|
||||
// Memory Access
|
||||
public Func<int, sbyte> ReadByte;
|
||||
public Func<int, short> ReadWord;
|
||||
public Func<int, int> ReadLong;
|
||||
// Memory Access
|
||||
public Func<int, sbyte> ReadByte;
|
||||
public Func<int, short> ReadWord;
|
||||
public Func<int, int> ReadLong;
|
||||
|
||||
public Action<int, sbyte> WriteByte;
|
||||
public Action<int, short> WriteWord;
|
||||
public Action<int, int> WriteLong;
|
||||
public Action<int, sbyte> WriteByte;
|
||||
public Action<int, short> WriteWord;
|
||||
public Action<int, int> WriteLong;
|
||||
|
||||
public Action<int> IrqCallback;
|
||||
public Action<int> IrqCallback;
|
||||
|
||||
// Initialization
|
||||
// Initialization
|
||||
|
||||
public MC68000()
|
||||
{
|
||||
BuildOpcodeTable();
|
||||
}
|
||||
public MC68000()
|
||||
{
|
||||
BuildOpcodeTable();
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
S = true;
|
||||
InterruptMaskLevel = 7;
|
||||
A[7].s32 = ReadLong(0);
|
||||
PC = ReadLong(4);
|
||||
}
|
||||
public void Reset()
|
||||
{
|
||||
S = true;
|
||||
InterruptMaskLevel = 7;
|
||||
A[7].s32 = ReadLong(0);
|
||||
PC = ReadLong(4);
|
||||
}
|
||||
|
||||
public Action[] Opcodes = new Action[0x10000];
|
||||
public ushort op;
|
||||
public Action[] Opcodes = new Action[0x10000];
|
||||
public ushort op;
|
||||
|
||||
public void Step()
|
||||
{
|
||||
Console.WriteLine(Disassemble(PC));
|
||||
public void Step()
|
||||
{
|
||||
Console.WriteLine(Disassemble(PC));
|
||||
|
||||
op = (ushort) ReadWord(PC);
|
||||
PC += 2;
|
||||
Opcodes[op]();
|
||||
}
|
||||
op = (ushort)ReadWord(PC);
|
||||
PC += 2;
|
||||
Opcodes[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 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
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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 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 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();
|
||||
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("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();
|
||||
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();
|
||||
|
||||
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();
|
||||
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();
|
||||
|
||||
writer.WriteLine("TotalExecutedCycles {0}", TotalExecutedCycles);
|
||||
writer.WriteLine("PendingCycles {0}", PendingCycles);
|
||||
writer.WriteLine("TotalExecutedCycles {0}", TotalExecutedCycles);
|
||||
writer.WriteLine("PendingCycles {0}", PendingCycles);
|
||||
|
||||
writer.WriteLine("[/{0}]", id);
|
||||
}
|
||||
writer.WriteLine("[/{0}]", id);
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
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] == "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]);
|
||||
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]);
|
||||
|
||||
else if (args[0] == "TotalExecutedCycles") TotalExecutedCycles = int.Parse(args[1]);
|
||||
else if (args[0] == "PendingCycles") PendingCycles = int.Parse(args[1]);
|
||||
else if (args[0] == "TotalExecutedCycles") 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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public struct Register
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public uint u32;
|
||||
[FieldOffset(0)]
|
||||
public int s32;
|
||||
[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 ushort u16;
|
||||
[FieldOffset(0)]
|
||||
public short s16;
|
||||
|
||||
[FieldOffset(0)]
|
||||
public byte u8;
|
||||
[FieldOffset(0)]
|
||||
public sbyte s8;
|
||||
[FieldOffset(0)]
|
||||
public byte u8;
|
||||
[FieldOffset(0)]
|
||||
public sbyte s8;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("{0:X8}", u32);
|
||||
}
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("{0:X8}", u32);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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<string> opList = new List<string>();
|
||||
opList.Add(root);
|
||||
void Assign(string instr, Action exec, string root, params string[] bitfield)
|
||||
{
|
||||
List<string> opList = new List<string>();
|
||||
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<string> ops, string constant)
|
||||
{
|
||||
for (int i=0; i<ops.Count; i++)
|
||||
ops[i] = ops[i] + constant;
|
||||
}
|
||||
void AppendConstant(List<string> ops, string constant)
|
||||
{
|
||||
for (int i = 0; i < ops.Count; i++)
|
||||
ops[i] = ops[i] + constant;
|
||||
}
|
||||
|
||||
List<string> AppendPermutations(List<string> ops, string[] permutations)
|
||||
{
|
||||
List<string> output = new List<string>();
|
||||
List<string> AppendPermutations(List<string> ops, string[] permutations)
|
||||
{
|
||||
List<string> output = new List<string>();
|
||||
|
||||
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<string> AppendData(List<string> ops, int bits)
|
||||
{
|
||||
List<string> output = new List<string>();
|
||||
List<string> AppendData(List<string> ops, int bits)
|
||||
{
|
||||
List<string> output = new List<string>();
|
||||
|
||||
foreach (var input in ops)
|
||||
for (int i = 0; i < BinaryExp(bits); i++)
|
||||
output.Add(input+Convert.ToString(i, 2).PadLeft(bits, '0'));
|
||||
foreach (var input in ops)
|
||||
for (int i = 0; i < BinaryExp(bits); i++)
|
||||
output.Add(input + Convert.ToString(i, 2).PadLeft(bits, '0'));
|
||||
|
||||
return output;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
int BinaryExp(int bits)
|
||||
{
|
||||
int res = 1;
|
||||
for (int i = 0; i < bits; i++)
|
||||
res *= 2;
|
||||
return res;
|
||||
}
|
||||
int BinaryExp(int bits)
|
||||
{
|
||||
int res = 1;
|
||||
for (int i = 0; i < bits; i++)
|
||||
res *= 2;
|
||||
return res;
|
||||
}
|
||||
|
||||
#region Tables
|
||||
#region Tables
|
||||
|
||||
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[] 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 = {
|
||||
static readonly string[] Xn3Am3 = {
|
||||
"000000", // Dn Data register
|
||||
"001000",
|
||||
"010000",
|
||||
|
@ -241,7 +241,7 @@ namespace BizHawk.Emulation.CPUs.M68000
|
|||
"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
|
||||
}
|
||||
}
|
|
@ -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 }
|
||||
};
|
||||
}
|
||||
}
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
namespace BizHawk.Emulation.CPUs.CP1610
|
||||
namespace BizHawk.Emulation.Common.Components.CP1610
|
||||
{
|
||||
public sealed partial class CP1610
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using System;
|
||||
|
||||
namespace BizHawk.Emulation.CPUs.CP1610
|
||||
namespace BizHawk.Emulation.Common.Components.CP1610
|
||||
{
|
||||
public sealed partial class CP1610
|
||||
{
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -4,7 +4,7 @@ using System.IO;
|
|||
|
||||
using BizHawk.Common;
|
||||
|
||||
namespace BizHawk.Emulation.CPUs.M6502
|
||||
namespace BizHawk.Emulation.Common.Components.M6502
|
||||
{
|
||||
/// <summary>
|
||||
/// maintains a managed 6502X and an unmanaged 6502X, running them alongside and ensuring consistency
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -30,7 +30,7 @@ using System;
|
|||
SRL
|
||||
*/
|
||||
|
||||
namespace BizHawk.Emulation.CPUs.Z80GB
|
||||
namespace BizHawk.Emulation.Common.Components.Z80GB
|
||||
{
|
||||
public partial class Z80
|
||||
{
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
using System;
|
||||
|
||||
namespace BizHawk.Emulation.CPUs.Z80GB
|
||||
namespace BizHawk.Emulation.Common.Components.Z80GB
|
||||
{
|
||||
public partial class Z80
|
||||
{
|
||||
{
|
||||
private bool iff1;
|
||||
public bool IFF1 { get { return iff1; } set { iff1 = value; } }
|
||||
|
||||
|
@ -15,7 +15,7 @@ namespace BizHawk.Emulation.CPUs.Z80GB
|
|||
|
||||
private bool nonMaskableInterrupt;
|
||||
public bool NonMaskableInterrupt
|
||||
{
|
||||
{
|
||||
get { return nonMaskableInterrupt; }
|
||||
set { if (value && !nonMaskableInterrupt) NonMaskableInterruptPending = true; nonMaskableInterrupt = value; }
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ namespace BizHawk.Emulation.CPUs.Z80GB
|
|||
|
||||
private int interruptMode;
|
||||
public int InterruptMode
|
||||
{
|
||||
{
|
||||
get { return interruptMode; }
|
||||
set { if (value < 0 || value > 2) throw new ArgumentOutOfRangeException(); interruptMode = value; }
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ namespace BizHawk.Emulation.CPUs.Z80GB
|
|||
public bool Halted { get { return halted; } set { halted = value; } }
|
||||
|
||||
private void ResetInterrupts()
|
||||
{
|
||||
{
|
||||
IFF1 = false;
|
||||
IFF2 = false;
|
||||
Interrupt = false;
|
||||
|
@ -45,7 +45,7 @@ namespace BizHawk.Emulation.CPUs.Z80GB
|
|||
}
|
||||
|
||||
private void Halt()
|
||||
{
|
||||
{
|
||||
Halted = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
{
|
||||
{
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
[Serializable]
|
||||
public struct RegisterPair
|
||||
{
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public ushort Word;
|
||||
|
||||
|
@ -19,43 +19,43 @@ namespace BizHawk.Emulation.CPUs.Z80GB
|
|||
public byte High;
|
||||
|
||||
public RegisterPair(ushort value)
|
||||
{
|
||||
{
|
||||
Word = value;
|
||||
Low = (byte)(Word);
|
||||
High = (byte)(Word >> 8);
|
||||
}
|
||||
|
||||
public static implicit operator ushort(RegisterPair rp)
|
||||
{
|
||||
{
|
||||
return rp.Word;
|
||||
}
|
||||
|
||||
public static implicit operator RegisterPair(ushort value)
|
||||
{
|
||||
{
|
||||
return new RegisterPair(value);
|
||||
}
|
||||
}
|
||||
|
||||
public bool FlagC
|
||||
{
|
||||
{
|
||||
get { return (RegAF.Low & 0x10) != 0; }
|
||||
set { RegAF.Low = (byte)((RegAF.Low & ~0x10) | (value ? 0x10 : 0x00)); }
|
||||
}
|
||||
|
||||
public bool FlagH
|
||||
{
|
||||
{
|
||||
get { return (RegAF.Low & 0x20) != 0; }
|
||||
set { RegAF.Low = (byte)((RegAF.Low & ~0x20) | (value ? 0x20 : 0x00)); }
|
||||
}
|
||||
|
||||
public bool FlagN
|
||||
{
|
||||
{
|
||||
get { return (RegAF.Low & 0x40) != 0; }
|
||||
set { RegAF.Low = (byte)((RegAF.Low & ~0x40) | (value ? 0x40 : 0x00)); }
|
||||
}
|
||||
|
||||
public bool FlagZ
|
||||
{
|
||||
{
|
||||
get { return (RegAF.Low & 0x80) != 0; }
|
||||
set { RegAF.Low = (byte)((RegAF.Low & ~0x80) | (value ? 0x80 : 0x00)); }
|
||||
}
|
||||
|
@ -71,94 +71,94 @@ namespace BizHawk.Emulation.CPUs.Z80GB
|
|||
private RegisterPair RegPC; // PC (program counter)
|
||||
|
||||
private void ResetRegisters()
|
||||
{
|
||||
{
|
||||
RegAF = 0; RegBC = 0; RegDE = 0; RegHL = 0;
|
||||
RegI = 0;
|
||||
RegSP.Word = 0; RegPC.Word = 0;
|
||||
}
|
||||
|
||||
public byte RegisterA
|
||||
{
|
||||
{
|
||||
get { return RegAF.High; }
|
||||
set { RegAF.High = value; }
|
||||
}
|
||||
|
||||
public byte RegisterF
|
||||
{
|
||||
{
|
||||
get { return RegAF.Low; }
|
||||
set { RegAF.Low = (byte)(value&0xF0); }
|
||||
set { RegAF.Low = (byte)(value & 0xF0); }
|
||||
}
|
||||
|
||||
public ushort RegisterAF
|
||||
{
|
||||
{
|
||||
get { return RegAF.Word; }
|
||||
set { RegAF.Word = (byte)(value&0xFFF0); }
|
||||
set { RegAF.Word = (byte)(value & 0xFFF0); }
|
||||
}
|
||||
|
||||
public byte RegisterB
|
||||
{
|
||||
{
|
||||
get { return RegBC.High; }
|
||||
set { RegBC.High = value; }
|
||||
}
|
||||
|
||||
public byte RegisterC
|
||||
{
|
||||
{
|
||||
get { return RegBC.Low; }
|
||||
set { RegBC.Low = value; }
|
||||
}
|
||||
|
||||
public ushort RegisterBC
|
||||
{
|
||||
{
|
||||
get { return RegBC.Word; }
|
||||
set { RegBC.Word = value; }
|
||||
}
|
||||
|
||||
public byte RegisterD
|
||||
{
|
||||
{
|
||||
get { return RegDE.High; }
|
||||
set { RegDE.High = value; }
|
||||
}
|
||||
|
||||
public byte RegisterE
|
||||
{
|
||||
{
|
||||
get { return RegDE.Low; }
|
||||
set { RegDE.Low = value; }
|
||||
}
|
||||
public ushort RegisterDE
|
||||
{
|
||||
{
|
||||
get { return RegDE.Word; }
|
||||
set { RegDE.Word = value; }
|
||||
}
|
||||
|
||||
public byte RegisterH
|
||||
{
|
||||
{
|
||||
get { return RegHL.High; }
|
||||
set { RegHL.High = value; }
|
||||
}
|
||||
|
||||
public byte RegisterL
|
||||
{
|
||||
{
|
||||
get { return RegHL.Low; }
|
||||
set { RegHL.Low = value; }
|
||||
}
|
||||
public ushort RegisterHL
|
||||
{
|
||||
{
|
||||
get { return RegHL.Word; }
|
||||
set { RegHL.Word = value; }
|
||||
}
|
||||
|
||||
public ushort RegisterPC
|
||||
{
|
||||
{
|
||||
get { return RegPC.Word; }
|
||||
set { RegPC.Word = value; }
|
||||
}
|
||||
public ushort RegisterSP
|
||||
{
|
||||
{
|
||||
get { return RegSP.Word; }
|
||||
set { RegSP.Word = value; }
|
||||
}
|
||||
public byte RegisterI
|
||||
{
|
||||
{
|
||||
get { return RegI; }
|
||||
set { RegI = value; }
|
||||
}
|
||||
|
|
|
@ -1,149 +1,149 @@
|
|||
namespace BizHawk.Emulation.CPUs.Z80GB
|
||||
namespace BizHawk.Emulation.Common.Components.Z80GB
|
||||
{
|
||||
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; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
using System;
|
||||
|
||||
namespace BizHawk.Emulation.CPUs.Z80
|
||||
namespace BizHawk.Emulation.Common.Components.Z80
|
||||
{
|
||||
public class Disassembler
|
||||
{
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,9 +1,9 @@
|
|||
using System;
|
||||
|
||||
namespace BizHawk.Emulation.CPUs.Z80
|
||||
namespace BizHawk.Emulation.Common.Components.Z80
|
||||
{
|
||||
public partial class Z80A
|
||||
{
|
||||
{
|
||||
private bool iff1;
|
||||
public bool IFF1 { get { return iff1; } set { iff1 = value; } }
|
||||
|
||||
|
@ -15,7 +15,7 @@ namespace BizHawk.Emulation.CPUs.Z80
|
|||
|
||||
private bool nonMaskableInterrupt;
|
||||
public bool NonMaskableInterrupt
|
||||
{
|
||||
{
|
||||
get { return nonMaskableInterrupt; }
|
||||
set { if (value && !nonMaskableInterrupt) NonMaskableInterruptPending = true; nonMaskableInterrupt = value; }
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ namespace BizHawk.Emulation.CPUs.Z80
|
|||
|
||||
private 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()
|
||||
{
|
||||
{
|
||||
IFF1 = false;
|
||||
IFF2 = false;
|
||||
Interrupt = false;
|
||||
|
@ -48,7 +48,7 @@ namespace BizHawk.Emulation.CPUs.Z80
|
|||
}
|
||||
|
||||
private void Halt()
|
||||
{
|
||||
{
|
||||
Halted = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{
|
||||
{
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
[Serializable()]
|
||||
public struct RegisterPair
|
||||
{
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public ushort Word;
|
||||
|
||||
|
@ -19,67 +19,67 @@ namespace BizHawk.Emulation.CPUs.Z80
|
|||
public byte High;
|
||||
|
||||
public RegisterPair(ushort value)
|
||||
{
|
||||
{
|
||||
Word = value;
|
||||
Low = (byte)(Word);
|
||||
High = (byte)(Word >> 8);
|
||||
}
|
||||
|
||||
public static implicit operator ushort(RegisterPair rp)
|
||||
{
|
||||
{
|
||||
return rp.Word;
|
||||
}
|
||||
|
||||
public static implicit operator RegisterPair(ushort value)
|
||||
{
|
||||
{
|
||||
return new RegisterPair(value);
|
||||
}
|
||||
}
|
||||
|
||||
private bool RegFlagC
|
||||
{
|
||||
{
|
||||
get { return (RegAF.Low & 0x01) != 0; }
|
||||
set { RegAF.Low = (byte)((RegAF.Low & ~0x01) | (value ? 0x01 : 0x00)); }
|
||||
}
|
||||
|
||||
private bool RegFlagN
|
||||
{
|
||||
{
|
||||
get { return (RegAF.Low & 0x02) != 0; }
|
||||
set { RegAF.Low = (byte)((RegAF.Low & ~0x02) | (value ? 0x02 : 0x00)); }
|
||||
}
|
||||
|
||||
private bool RegFlagP
|
||||
{
|
||||
{
|
||||
get { return (RegAF.Low & 0x04) != 0; }
|
||||
set { RegAF.Low = (byte)((RegAF.Low & ~0x04) | (value ? 0x04 : 0x00)); }
|
||||
}
|
||||
|
||||
private bool RegFlag3
|
||||
{
|
||||
{
|
||||
get { return (RegAF.Low & 0x08) != 0; }
|
||||
set { RegAF.Low = (byte)((RegAF.Low & ~0x08) | (value ? 0x08 : 0x00)); }
|
||||
}
|
||||
|
||||
private bool RegFlagH
|
||||
{
|
||||
{
|
||||
get { return (RegAF.Low & 0x10) != 0; }
|
||||
set { RegAF.Low = (byte)((RegAF.Low & ~0x10) | (value ? 0x10 : 0x00)); }
|
||||
}
|
||||
|
||||
private bool RegFlag5
|
||||
{
|
||||
{
|
||||
get { return (RegAF.Low & 0x20) != 0; }
|
||||
set { RegAF.Low = (byte)((RegAF.Low & ~0x20) | (value ? 0x20 : 0x00)); }
|
||||
}
|
||||
|
||||
private bool RegFlagZ
|
||||
{
|
||||
{
|
||||
get { return (RegAF.Low & 0x40) != 0; }
|
||||
set { RegAF.Low = (byte)((RegAF.Low & ~0x40) | (value ? 0x40 : 0x00)); }
|
||||
}
|
||||
|
||||
private bool RegFlagS
|
||||
{
|
||||
{
|
||||
get { return (RegAF.Low & 0x80) != 0; }
|
||||
set { RegAF.Low = (byte)((RegAF.Low & ~0x80) | (value ? 0x80 : 0x00)); }
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ namespace BizHawk.Emulation.CPUs.Z80
|
|||
private RegisterPair RegPC; // PC (program counter)
|
||||
|
||||
private void ResetRegisters()
|
||||
{
|
||||
{
|
||||
// Clear main registers
|
||||
RegAF = 0; RegBC = 0; RegDE = 0; RegHL = 0;
|
||||
// Clear alternate registers
|
||||
|
@ -116,122 +116,122 @@ namespace BizHawk.Emulation.CPUs.Z80
|
|||
}
|
||||
|
||||
public byte RegisterA
|
||||
{
|
||||
{
|
||||
get { return RegAF.High; }
|
||||
set { RegAF.High = value; }
|
||||
}
|
||||
|
||||
public byte RegisterF
|
||||
{
|
||||
{
|
||||
get { return RegAF.Low; }
|
||||
set { RegAF.Low = value; }
|
||||
}
|
||||
|
||||
public ushort RegisterAF
|
||||
{
|
||||
{
|
||||
get { return RegAF.Word; }
|
||||
set { RegAF.Word = value; }
|
||||
}
|
||||
|
||||
public byte RegisterB
|
||||
{
|
||||
{
|
||||
get { return RegBC.High; }
|
||||
set { RegBC.High = value; }
|
||||
}
|
||||
|
||||
public byte RegisterC
|
||||
{
|
||||
{
|
||||
get { return RegBC.Low; }
|
||||
set { RegBC.Low = value; }
|
||||
}
|
||||
|
||||
public ushort RegisterBC
|
||||
{
|
||||
{
|
||||
get { return RegBC.Word; }
|
||||
set { RegBC.Word = value; }
|
||||
}
|
||||
|
||||
public byte RegisterD
|
||||
{
|
||||
{
|
||||
get { return RegDE.High; }
|
||||
set { RegDE.High = value; }
|
||||
}
|
||||
|
||||
public byte RegisterE
|
||||
{
|
||||
{
|
||||
get { return RegDE.Low; }
|
||||
set { RegDE.Low = value; }
|
||||
}
|
||||
public ushort RegisterDE
|
||||
{
|
||||
{
|
||||
get { return RegDE.Word; }
|
||||
set { RegDE.Word = value; }
|
||||
}
|
||||
|
||||
public byte RegisterH
|
||||
{
|
||||
{
|
||||
get { return RegHL.High; }
|
||||
set { RegHL.High = value; }
|
||||
}
|
||||
|
||||
public byte RegisterL
|
||||
{
|
||||
{
|
||||
get { return RegHL.Low; }
|
||||
set { RegHL.Low = value; }
|
||||
}
|
||||
public ushort RegisterHL
|
||||
{
|
||||
{
|
||||
get { return RegHL.Word; }
|
||||
set { RegHL.Word = value; }
|
||||
}
|
||||
|
||||
public ushort RegisterPC
|
||||
{
|
||||
{
|
||||
get { return RegPC.Word; }
|
||||
set { RegPC.Word = value; }
|
||||
}
|
||||
public ushort RegisterSP
|
||||
{
|
||||
{
|
||||
get { return RegSP.Word; }
|
||||
set { RegSP.Word = value; }
|
||||
}
|
||||
public ushort RegisterIX
|
||||
{
|
||||
{
|
||||
get { return RegIX.Word; }
|
||||
set { RegIX.Word = value; }
|
||||
}
|
||||
public ushort RegisterIY
|
||||
{
|
||||
{
|
||||
get { return RegIY.Word; }
|
||||
set { RegIY.Word = value; }
|
||||
}
|
||||
public byte RegisterI
|
||||
{
|
||||
{
|
||||
get { return RegI; }
|
||||
set { RegI = value; }
|
||||
}
|
||||
public byte RegisterR
|
||||
{
|
||||
{
|
||||
get { return RegR; }
|
||||
set { RegR = value; }
|
||||
}
|
||||
public ushort RegisterShadowAF
|
||||
{
|
||||
{
|
||||
get { return RegAltAF.Word; }
|
||||
set { RegAltAF.Word = value; }
|
||||
}
|
||||
public ushort RegisterShadowBC
|
||||
{
|
||||
{
|
||||
get { return RegAltBC.Word; }
|
||||
set { RegAltBC.Word = value; }
|
||||
}
|
||||
public ushort RegisterShadowDE
|
||||
{
|
||||
{
|
||||
get { return RegAltDE.Word; }
|
||||
set { RegAltDE.Word = value; }
|
||||
}
|
||||
public ushort RegisterShadowHL
|
||||
{
|
||||
{
|
||||
get { return RegAltHL.Word; }
|
||||
set { RegAltHL.Word = value; }
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
namespace BizHawk.Emulation.CPUs.Z80
|
||||
namespace BizHawk.Emulation.Common.Components.Z80
|
||||
{
|
||||
public partial class Z80A
|
||||
{
|
||||
{
|
||||
private void InitialiseTables()
|
||||
{
|
||||
{
|
||||
InitTableInc();
|
||||
InitTableDec();
|
||||
InitTableParity();
|
||||
|
@ -17,7 +17,7 @@ namespace BizHawk.Emulation.CPUs.Z80
|
|||
|
||||
private byte[] TableInc;
|
||||
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);
|
||||
|
@ -25,7 +25,7 @@ namespace BizHawk.Emulation.CPUs.Z80
|
|||
|
||||
private byte[] TableDec;
|
||||
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);
|
||||
|
@ -33,13 +33,13 @@ namespace BizHawk.Emulation.CPUs.Z80
|
|||
|
||||
private bool[] TableParity;
|
||||
private void InitTableParity()
|
||||
{
|
||||
{
|
||||
TableParity = new bool[256];
|
||||
for (int i = 0; i < 256; ++i)
|
||||
{
|
||||
{
|
||||
int Bits = 0;
|
||||
for (int j = 0; j < 8; ++j)
|
||||
{
|
||||
{
|
||||
Bits += (i >> j) & 1;
|
||||
}
|
||||
TableParity[i] = (Bits & 1) == 0;
|
||||
|
@ -48,17 +48,17 @@ namespace BizHawk.Emulation.CPUs.Z80
|
|||
|
||||
private ushort[, , ,] TableALU;
|
||||
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)
|
||||
{
|
||||
{
|
||||
|
||||
int ac = (i == 1 || i == 3) ? c : 0;
|
||||
|
||||
|
@ -75,7 +75,7 @@ namespace BizHawk.Emulation.CPUs.Z80
|
|||
|
||||
// Fetch result
|
||||
switch (i)
|
||||
{
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
result_si = (sbyte)op1 + (sbyte)op2 + ac;
|
||||
|
@ -103,7 +103,7 @@ namespace BizHawk.Emulation.CPUs.Z80
|
|||
// Parity/Carry
|
||||
|
||||
switch (i)
|
||||
{
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
|
@ -125,7 +125,7 @@ namespace BizHawk.Emulation.CPUs.Z80
|
|||
|
||||
// Half carry
|
||||
switch (i)
|
||||
{
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
H = ((op1 & 0xF) + (op2 & 0xF) + (ac & 0xF)) > 0xF;
|
||||
|
@ -166,12 +166,12 @@ namespace BizHawk.Emulation.CPUs.Z80
|
|||
|
||||
private bool[,] TableHalfBorrow;
|
||||
private void InitTableHalfBorrow()
|
||||
{
|
||||
{
|
||||
TableHalfBorrow = new bool[256, 256];
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
{
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
{
|
||||
TableHalfBorrow[i, j] = ((i & 0xF) - (j & 0xF)) < 0;
|
||||
}
|
||||
}
|
||||
|
@ -179,12 +179,12 @@ namespace BizHawk.Emulation.CPUs.Z80
|
|||
|
||||
private bool[,] TableHalfCarry;
|
||||
private void InitTableHalfCarry()
|
||||
{
|
||||
{
|
||||
TableHalfCarry = new bool[256, 256];
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
{
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
{
|
||||
TableHalfCarry[i, j] = ((i & 0xF) + (j & 0xF)) > 0xF;
|
||||
}
|
||||
}
|
||||
|
@ -192,14 +192,14 @@ namespace BizHawk.Emulation.CPUs.Z80
|
|||
|
||||
private ushort[, ,] TableRotShift;
|
||||
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++)
|
||||
{
|
||||
{
|
||||
byte Old = (byte)(af >> 8);
|
||||
bool OldCarry = (af & 0x01) != 0;
|
||||
|
||||
|
@ -207,26 +207,34 @@ namespace BizHawk.Emulation.CPUs.Z80
|
|||
|
||||
byte New = Old;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -235,7 +243,7 @@ namespace BizHawk.Emulation.CPUs.Z80
|
|||
newAf |= (ushort)(New * 256);
|
||||
|
||||
if (all == 1)
|
||||
{
|
||||
{
|
||||
newAf &= unchecked((ushort)~0xC4); // Clear S, Z, P
|
||||
if (New > 127) newAf |= 0x80;
|
||||
if (New == 0) newAf |= 0x40;
|
||||
|
@ -250,10 +258,10 @@ namespace BizHawk.Emulation.CPUs.Z80
|
|||
|
||||
private ushort[] TableNeg;
|
||||
private void InitTableNeg()
|
||||
{
|
||||
{
|
||||
TableNeg = new ushort[65536];
|
||||
for (int af = 0; af < 65536; af++)
|
||||
{
|
||||
{
|
||||
ushort raf = 0;
|
||||
byte b = (byte)(af >> 8);
|
||||
byte a = (byte)-b;
|
||||
|
@ -265,18 +273,20 @@ namespace BizHawk.Emulation.CPUs.Z80
|
|||
|
||||
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 {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsH(af) || ((a & 0x0F) > 0x09)) tmp += 0x06;
|
||||
if (IsC(af) || a > 0x99) tmp += 0x60;
|
||||
}
|
||||
|
@ -286,7 +296,7 @@ namespace BizHawk.Emulation.CPUs.Z80
|
|||
}
|
||||
|
||||
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) +
|
||||
|
@ -300,12 +310,12 @@ namespace BizHawk.Emulation.CPUs.Z80
|
|||
}
|
||||
|
||||
private bool UndocumentedX(int value)
|
||||
{
|
||||
{
|
||||
return (value & 0x08) != 0;
|
||||
}
|
||||
|
||||
private bool UndocumentedY(int value)
|
||||
{
|
||||
{
|
||||
return (value & 0x20) != 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// ZiLOG Z80A CPU Emulator
|
||||
/// </summary>
|
||||
public sealed partial class Z80A
|
||||
{
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates an instance of the <see cref="Z80A"/> emulator class.
|
||||
/// </summary>
|
||||
public Z80A()
|
||||
{
|
||||
{
|
||||
InitialiseTables();
|
||||
Reset();
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ namespace BizHawk.Emulation.CPUs.Z80
|
|||
/// Reset the Z80 to its initial state
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
{
|
||||
ResetRegisters();
|
||||
ResetInterrupts();
|
||||
PendingCycles = 0;
|
||||
|
@ -33,178 +33,178 @@ namespace BizHawk.Emulation.CPUs.Z80
|
|||
TotalExecutedCycles = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reset the Z80 to its initial state, but don't modify cycle counters. For use where Z80 may be reset
|
||||
/// </summary>
|
||||
public void SoftReset()
|
||||
{
|
||||
ResetRegisters();
|
||||
ResetInterrupts();
|
||||
}
|
||||
/// <summary>
|
||||
/// Reset the Z80 to its initial state, but don't modify cycle counters. For use where Z80 may be reset
|
||||
/// </summary>
|
||||
public void SoftReset()
|
||||
{
|
||||
ResetRegisters();
|
||||
ResetInterrupts();
|
||||
}
|
||||
|
||||
// Memory Access
|
||||
// Memory Access
|
||||
|
||||
public Func<ushort, byte> ReadMemory;
|
||||
public Action<ushort, byte> WriteMemory;
|
||||
public Func<ushort, byte> ReadMemory;
|
||||
public Action<ushort, byte> 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<ushort, byte> ReadHardware;
|
||||
public Action<ushort, byte> WriteHardware;
|
||||
public Func<ushort, byte> ReadHardware;
|
||||
public Action<ushort, byte> 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<CpuType> where CpuType : struct, x86CpuType
|
||||
{
|
||||
private ushort ReadWord(int addr)
|
||||
{
|
||||
return (ushort)(ReadMemory(addr++) + (ReadMemory(addr) << 8));
|
||||
}
|
||||
public partial class x86<CpuType> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,84 +1,84 @@
|
|||
using System;
|
||||
|
||||
namespace BizHawk.Emulation.CPUs.x86
|
||||
namespace BizHawk.Emulation.Common.Components.x86
|
||||
{
|
||||
public partial class x86<CpuType> where CpuType: struct, x86CpuType
|
||||
{
|
||||
public void Execute(int cycles)
|
||||
{
|
||||
Console.WriteLine(Disassemble((CS << 4) + IP));
|
||||
byte opcode1 = ReadMemory((CS << 4) + IP);
|
||||
IP++;
|
||||
public partial class x86<CpuType> 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
namespace BizHawk.Emulation.CPUs.x86
|
||||
namespace BizHawk.Emulation.Common.Components.x86
|
||||
{
|
||||
public partial class x86<CpuType> 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<CpuType> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<CpuType> where CpuType: struct, x86CpuType
|
||||
{
|
||||
// Machine State
|
||||
public Register16 RegAX;
|
||||
public Register16 RegBX;
|
||||
public Register16 RegCX;
|
||||
public Register16 RegDX;
|
||||
public sealed partial class x86<CpuType> 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<int, byte> ReadMemory;
|
||||
public Action<int, byte> WriteMemory;
|
||||
// Memory Access
|
||||
public Func<int, byte> ReadMemory;
|
||||
public Action<int, byte> 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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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/
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using System;
|
||||
using BizHawk.Emulation.CPUs.M6502;
|
||||
using BizHawk.Emulation.Common.Components.M6502;
|
||||
|
||||
#if false
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
/*****************************************************
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue