namespace changes to BizHawk.Emulation Cpus

This commit is contained in:
adelikat 2013-11-14 15:01:32 +00:00
parent c076931d0c
commit 906c0316a6
53 changed files with 6362 additions and 6021 deletions

View File

@ -1,6 +1,6 @@
using System.Text; using System.Text;
namespace BizHawk.Emulation.CPUs.M68000 namespace BizHawk.Emulation.Common.Components.M68000
{ {
public sealed class DisassemblyInfo 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

View File

@ -1,163 +1,163 @@
using System; using System;
namespace BizHawk.Emulation.CPUs.M68000 namespace BizHawk.Emulation.Common.Components.M68000
{ {
partial class MC68000 partial class MC68000
{ {
void MOVEtSR() void MOVEtSR()
{ {
if (S == false) if (S == false)
throw new Exception("Write to SR when not in supervisor mode. supposed to trap or something..."); throw new Exception("Write to SR when not in supervisor mode. supposed to trap or something...");
int mode = (op >> 3) & 7; int mode = (op >> 3) & 7;
int reg = (op >> 0) & 7; int reg = (op >> 0) & 7;
SR = ReadValueW(mode, reg); SR = ReadValueW(mode, reg);
PendingCycles -= 12 + EACyclesBW[mode, reg]; PendingCycles -= 12 + EACyclesBW[mode, reg];
} }
void MOVEtSR_Disasm(DisassemblyInfo info) void MOVEtSR_Disasm(DisassemblyInfo info)
{ {
int pc = info.PC + 2; int pc = info.PC + 2;
int mode = (op >> 3) & 7; int mode = (op >> 3) & 7;
int reg = (op >> 0) & 7; int reg = (op >> 0) & 7;
info.Mnemonic = "move"; info.Mnemonic = "move";
info.Args = DisassembleValue(mode, reg, 2, ref pc) + ", SR"; info.Args = DisassembleValue(mode, reg, 2, ref pc) + ", SR";
info.Length = pc - info.PC; info.Length = pc - info.PC;
} }
void MOVEfSR() void MOVEfSR()
{ {
int mode = (op >> 3) & 7; int mode = (op >> 3) & 7;
int reg = (op >> 0) & 7; int reg = (op >> 0) & 7;
WriteValueW(mode, reg, (short) SR); WriteValueW(mode, reg, (short)SR);
PendingCycles -= (mode == 0) ? 6 : 8 + EACyclesBW[mode, reg]; PendingCycles -= (mode == 0) ? 6 : 8 + EACyclesBW[mode, reg];
} }
void MOVEfSR_Disasm(DisassemblyInfo info) void MOVEfSR_Disasm(DisassemblyInfo info)
{ {
int pc = info.PC + 2; int pc = info.PC + 2;
int mode = (op >> 3) & 7; int mode = (op >> 3) & 7;
int reg = (op >> 0) & 7; int reg = (op >> 0) & 7;
info.Mnemonic = "move"; info.Mnemonic = "move";
info.Args = "SR, " + DisassembleValue(mode, reg, 2, ref pc); info.Args = "SR, " + DisassembleValue(mode, reg, 2, ref pc);
info.Length = pc - info.PC; info.Length = pc - info.PC;
} }
void MOVEUSP() void MOVEUSP()
{ {
if (S == false) if (S == false)
throw new Exception("MOVE to USP when not supervisor. needs to trap"); throw new Exception("MOVE to USP when not supervisor. needs to trap");
int dir = (op >> 3) & 1; int dir = (op >> 3) & 1;
int reg = op & 7; int reg = op & 7;
if (dir == 0) usp = A[reg].s32; if (dir == 0) usp = A[reg].s32;
else A[reg].s32 = usp; else A[reg].s32 = usp;
PendingCycles -= 4; PendingCycles -= 4;
} }
void MOVEUSP_Disasm(DisassemblyInfo info) void MOVEUSP_Disasm(DisassemblyInfo info)
{ {
int pc = info.PC + 2; int pc = info.PC + 2;
int dir = (op >> 3) & 1; int dir = (op >> 3) & 1;
int reg = op & 7; int reg = op & 7;
info.Mnemonic = "move"; info.Mnemonic = "move";
info.Args = (dir == 0) ? ("A" + reg + ", USP") : ("USP, A" + reg); info.Args = (dir == 0) ? ("A" + reg + ", USP") : ("USP, A" + reg);
info.Length = pc - info.PC; info.Length = pc - info.PC;
} }
void ANDI_SR() void ANDI_SR()
{ {
if (S == false) if (S == false)
throw new Exception("trap!"); throw new Exception("trap!");
SR &= ReadWord(PC); PC += 2; SR &= ReadWord(PC); PC += 2;
PendingCycles -= 20; PendingCycles -= 20;
} }
void ANDI_SR_Disasm(DisassemblyInfo info) void ANDI_SR_Disasm(DisassemblyInfo info)
{ {
int pc = info.PC + 2; int pc = info.PC + 2;
info.Mnemonic = "andi"; info.Mnemonic = "andi";
info.Args = DisassembleImmediate(2, ref pc) + ", SR"; info.Args = DisassembleImmediate(2, ref pc) + ", SR";
info.Length = pc - info.PC; info.Length = pc - info.PC;
} }
void EORI_SR() void EORI_SR()
{ {
if (S == false) if (S == false)
throw new Exception("trap!"); throw new Exception("trap!");
SR ^= ReadWord(PC); PC += 2; SR ^= ReadWord(PC); PC += 2;
PendingCycles -= 20; PendingCycles -= 20;
} }
void EORI_SR_Disasm(DisassemblyInfo info) void EORI_SR_Disasm(DisassemblyInfo info)
{ {
int pc = info.PC + 2; int pc = info.PC + 2;
info.Mnemonic = "eori"; info.Mnemonic = "eori";
info.Args = DisassembleImmediate(2, ref pc) + ", SR"; info.Args = DisassembleImmediate(2, ref pc) + ", SR";
info.Length = pc - info.PC; info.Length = pc - info.PC;
} }
void ORI_SR() void ORI_SR()
{ {
if (S == false) if (S == false)
throw new Exception("trap!"); throw new Exception("trap!");
SR |= ReadWord(PC); PC += 2; SR |= ReadWord(PC); PC += 2;
PendingCycles -= 20; PendingCycles -= 20;
} }
void ORI_SR_Disasm(DisassemblyInfo info) void ORI_SR_Disasm(DisassemblyInfo info)
{ {
int pc = info.PC + 2; int pc = info.PC + 2;
info.Mnemonic = "ori"; info.Mnemonic = "ori";
info.Args = DisassembleImmediate(2, ref pc) + ", SR"; info.Args = DisassembleImmediate(2, ref pc) + ", SR";
info.Length = pc - info.PC; info.Length = pc - info.PC;
} }
void MOVECCR() void MOVECCR()
{ {
int mode = (op >> 3) & 7; int mode = (op >> 3) & 7;
int reg = (op >> 0) & 7; int reg = (op >> 0) & 7;
ushort sr = (ushort) (SR & 0xFF00); ushort sr = (ushort)(SR & 0xFF00);
sr |= (byte)ReadValueB(mode, reg); sr |= (byte)ReadValueB(mode, reg);
SR = (short)sr; SR = (short)sr;
PendingCycles -= 12 + EACyclesBW[mode, reg]; PendingCycles -= 12 + EACyclesBW[mode, reg];
} }
void MOVECCR_Disasm(DisassemblyInfo info) void MOVECCR_Disasm(DisassemblyInfo info)
{ {
int pc = info.PC + 2; int pc = info.PC + 2;
int mode = (op >> 3) & 7; int mode = (op >> 3) & 7;
int reg = (op >> 0) & 7; int reg = (op >> 0) & 7;
info.Mnemonic = "move"; info.Mnemonic = "move";
info.Args = DisassembleValue(mode, reg, 2, ref pc) + ", CCR"; info.Args = DisassembleValue(mode, reg, 2, ref pc) + ", CCR";
info.Length = pc - info.PC; info.Length = pc - info.PC;
} }
void TRAP() void TRAP()
{ {
int vector = 32 + (op & 0x0F); int vector = 32 + (op & 0x0F);
TrapVector(vector); TrapVector(vector);
PendingCycles -= 26; PendingCycles -= 26;
} }
void TRAP_Disasm(DisassemblyInfo info) void TRAP_Disasm(DisassemblyInfo info)
{ {
info.Mnemonic = "trap"; info.Mnemonic = "trap";
info.Args = string.Format("${0:X}", op & 0xF); info.Args = string.Format("${0:X}", op & 0xF);
} }
void TrapVector(int vector) void TrapVector(int vector)
{ {
short sr = (short)SR; // capture current SR. short sr = (short)SR; // capture current SR.
S = true; // switch to supervisor mode, if not already in it. S = true; // switch to supervisor mode, if not already in it.
A[7].s32 -= 4; // Push PC on stack A[7].s32 -= 4; // Push PC on stack
WriteLong(A[7].s32, PC); WriteLong(A[7].s32, PC);
A[7].s32 -= 2; // Push SR on stack A[7].s32 -= 2; // Push SR on stack
WriteWord(A[7].s32, sr); WriteWord(A[7].s32, sr);
PC = ReadLong(vector * 4); // Jump to vector PC = ReadLong(vector * 4); // Jump to vector
} }
} }
} }

View File

@ -3,269 +3,271 @@ using System.Runtime.InteropServices;
using System.IO; using System.IO;
using System.Globalization; using System.Globalization;
namespace BizHawk.Emulation.CPUs.M68000 namespace BizHawk.Emulation.Common.Components.M68000
{ {
public sealed partial class MC68000 public sealed partial class MC68000
{ {
// Machine State // Machine State
public Register[] D = new Register[8]; public Register[] D = new Register[8];
public Register[] A = new Register[8]; public Register[] A = new Register[8];
public int PC; public int PC;
public int TotalExecutedCycles; public int TotalExecutedCycles;
public int PendingCycles; public int PendingCycles;
// Status Registers // Status Registers
int InterruptMaskLevel; int InterruptMaskLevel;
bool s, m; bool s, m;
int usp, ssp; 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>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> /// <summary>Machine/Interrupt mode</summary>
public bool X; public bool M { get { return m; } set { m = value; } } // TODO probably have some switch logic maybe
/// <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> /// <summary>Supervisor/User mode</summary>
public short SR public bool S
{ {
get get { return s; }
{ set
short value = 0; {
if (C) value |= 0x0001; if (value == s) return;
if (V) value |= 0x0002; if (value == true) // entering supervisor mode
if (Z) value |= 0x0004; {
if (N) value |= 0x0008; Console.WriteLine("&^&^&^&^& ENTER SUPERVISOR MODE");
if (X) value |= 0x0010; usp = A[7].s32;
if (M) value |= 0x1000; A[7].s32 = ssp;
if (S) value |= 0x2000; s = true;
value |= (short) ((InterruptMaskLevel & 7) << 8); }
return value; else
} { // exiting supervisor mode
set Console.WriteLine("&^&^&^&^& LEAVE SUPERVISOR MODE");
{ ssp = A[7].s32;
C = (value & 0x0001) != 0; A[7].s32 = usp;
V = (value & 0x0002) != 0; s = false;
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; } /// <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;
// Memory Access /// <summary>Status Register</summary>
public Func<int, sbyte> ReadByte; public short SR
public Func<int, short> ReadWord; {
public Func<int, int> ReadLong; get
{
short value = 0;
if (C) value |= 0x0001;
if (V) value |= 0x0002;
if (Z) value |= 0x0004;
if (N) value |= 0x0008;
if (X) value |= 0x0010;
if (M) value |= 0x1000;
if (S) value |= 0x2000;
value |= (short)((InterruptMaskLevel & 7) << 8);
return value;
}
set
{
C = (value & 0x0001) != 0;
V = (value & 0x0002) != 0;
Z = (value & 0x0004) != 0;
N = (value & 0x0008) != 0;
X = (value & 0x0010) != 0;
M = (value & 0x1000) != 0;
S = (value & 0x2000) != 0;
InterruptMaskLevel = (value >> 8) & 7;
}
}
public Action<int, sbyte> WriteByte; public int Interrupt { get; set; }
public Action<int, short> WriteWord;
public Action<int, int> WriteLong;
public Action<int> IrqCallback; // Memory Access
public Func<int, sbyte> ReadByte;
public Func<int, short> ReadWord;
public Func<int, int> ReadLong;
// Initialization public Action<int, sbyte> WriteByte;
public Action<int, short> WriteWord;
public Action<int, int> WriteLong;
public MC68000() public Action<int> IrqCallback;
{
BuildOpcodeTable();
}
public void Reset() // Initialization
{
S = true;
InterruptMaskLevel = 7;
A[7].s32 = ReadLong(0);
PC = ReadLong(4);
}
public Action[] Opcodes = new Action[0x10000]; public MC68000()
public ushort op; {
BuildOpcodeTable();
}
public void Step() public void Reset()
{ {
Console.WriteLine(Disassemble(PC)); S = true;
InterruptMaskLevel = 7;
A[7].s32 = ReadLong(0);
PC = ReadLong(4);
}
op = (ushort) ReadWord(PC); public Action[] Opcodes = new Action[0x10000];
PC += 2; public ushort op;
Opcodes[op]();
}
public void ExecuteCycles(int cycles) public void Step()
{ {
PendingCycles += cycles; Console.WriteLine(Disassemble(PC));
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; op = (ushort)ReadWord(PC);
//Log.Note("CPU", State()); PC += 2;
op = (ushort)ReadWord(PC); Opcodes[op]();
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() public void ExecuteCycles(int cycles)
{ {
string a = Disassemble(PC).ToString().PadRight(64); PendingCycles += cycles;
//string a = string.Format("{0:X6}: {1:X4}", PC, ReadWord(PC)).PadRight(64); while (PendingCycles > 0)
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); if (Interrupt > 0 && (Interrupt > InterruptMaskLevel || Interrupt > 7))
string d = string.Format("SR:{0:X4} Pending {1}", SR, PendingCycles); {
return a + b + c + d; // TODO: Entering interrupt is not free. how many cycles does it take?
} //Log.Error("CPU","****** ENTER INTERRUPT {0} *******", Interrupt);
short sr = (short)SR; // capture current SR.
S = true; // switch to supervisor mode, if not already in it.
A[7].s32 -= 4; // Push PC on stack
WriteLong(A[7].s32, PC);
A[7].s32 -= 2; // Push SR on stack
WriteWord(A[7].s32, sr);
PC = ReadLong((24 + Interrupt) * 4); // Jump to interrupt vector
InterruptMaskLevel = Interrupt; // Set interrupt mask to level currently being entered
Interrupt = 0; // "ack" interrupt. Note: this is wrong.
IrqCallback(InterruptMaskLevel); // Invoke the "Interrupt accepted" callback handler
}
public void SaveStateText(TextWriter writer, string id) int prevCycles = PendingCycles;
{ //Log.Note("CPU", State());
writer.WriteLine("[{0}]", id); op = (ushort)ReadWord(PC);
writer.WriteLine("D0 {0:X8}", D[0].s32); if (Opcodes[op] == null) throw new Exception(string.Format("unhandled opcode at pc={0:X6}", PC));
writer.WriteLine("D1 {0:X8}", D[1].s32); PC += 2;
writer.WriteLine("D2 {0:X8}", D[2].s32); Opcodes[op]();
writer.WriteLine("D3 {0:X8}", D[3].s32); int delta = prevCycles - PendingCycles;
writer.WriteLine("D4 {0:X8}", D[4].s32); TotalExecutedCycles += delta;
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); public string State()
writer.WriteLine("A1 {0:X8}", A[1].s32); {
writer.WriteLine("A2 {0:X8}", A[2].s32); string a = Disassemble(PC).ToString().PadRight(64);
writer.WriteLine("A3 {0:X8}", A[3].s32); //string a = string.Format("{0:X6}: {1:X4}", PC, ReadWord(PC)).PadRight(64);
writer.WriteLine("A4 {0:X8}", A[4].s32); 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);
writer.WriteLine("A5 {0:X8}", A[5].s32); 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);
writer.WriteLine("A6 {0:X8}", A[6].s32); string d = string.Format("SR:{0:X4} Pending {1}", SR, PendingCycles);
writer.WriteLine("A7 {0:X8}", A[7].s32); return a + b + c + d;
writer.WriteLine(); }
writer.WriteLine("PC {0:X6}", PC); public void SaveStateText(TextWriter writer, string id)
writer.WriteLine("InterruptMaskLevel {0}", InterruptMaskLevel); {
writer.WriteLine("USP {0:X8}", usp); writer.WriteLine("[{0}]", id);
writer.WriteLine("SSP {0:X8}", ssp); writer.WriteLine("D0 {0:X8}", D[0].s32);
writer.WriteLine("S {0}", s); writer.WriteLine("D1 {0:X8}", D[1].s32);
writer.WriteLine("M {0}", m); writer.WriteLine("D2 {0:X8}", D[2].s32);
writer.WriteLine(); writer.WriteLine("D3 {0:X8}", D[3].s32);
writer.WriteLine("D4 {0:X8}", D[4].s32);
writer.WriteLine("D5 {0:X8}", D[5].s32);
writer.WriteLine("D6 {0:X8}", D[6].s32);
writer.WriteLine("D7 {0:X8}", D[7].s32);
writer.WriteLine();
writer.WriteLine("TotalExecutedCycles {0}", TotalExecutedCycles); writer.WriteLine("A0 {0:X8}", A[0].s32);
writer.WriteLine("PendingCycles {0}", PendingCycles); writer.WriteLine("A1 {0:X8}", A[1].s32);
writer.WriteLine("A2 {0:X8}", A[2].s32);
writer.WriteLine("[/{0}]", id); writer.WriteLine("A3 {0:X8}", A[3].s32);
} writer.WriteLine("A4 {0:X8}", A[4].s32);
writer.WriteLine("A5 {0:X8}", A[5].s32);
writer.WriteLine("A6 {0:X8}", A[6].s32);
writer.WriteLine("A7 {0:X8}", A[7].s32);
writer.WriteLine();
public void LoadStateText(TextReader reader, string id) writer.WriteLine("PC {0:X6}", PC);
{ writer.WriteLine("InterruptMaskLevel {0}", InterruptMaskLevel);
while (true) writer.WriteLine("USP {0:X8}", usp);
{ writer.WriteLine("SSP {0:X8}", ssp);
string[] args = reader.ReadLine().Split(' '); writer.WriteLine("S {0}", s);
if (args[0].Trim() == "") continue; writer.WriteLine("M {0}", m);
if (args[0] == "[/"+id+"]") break; writer.WriteLine();
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); writer.WriteLine("TotalExecutedCycles {0}", TotalExecutedCycles);
else if (args[0] == "A1") A[1].s32 = int.Parse(args[1], NumberStyles.HexNumber); writer.WriteLine("PendingCycles {0}", PendingCycles);
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] == "TotalExecutedCycles") TotalExecutedCycles = int.Parse(args[1]); writer.WriteLine("[/{0}]", id);
else if (args[0] == "PendingCycles") PendingCycles = int.Parse(args[1]); }
else public void LoadStateText(TextReader reader, string id)
Console.WriteLine("Skipping unrecognized identifier " + args[0]); {
} while (true)
} {
} string[] args = reader.ReadLine().Split(' ');
if (args[0].Trim() == "") continue;
if (args[0] == "[/" + id + "]") break;
else if (args[0] == "D0") D[0].s32 = int.Parse(args[1], NumberStyles.HexNumber);
else if (args[0] == "D1") D[1].s32 = int.Parse(args[1], NumberStyles.HexNumber);
else if (args[0] == "D2") D[2].s32 = int.Parse(args[1], NumberStyles.HexNumber);
else if (args[0] == "D3") D[3].s32 = int.Parse(args[1], NumberStyles.HexNumber);
else if (args[0] == "D4") D[4].s32 = int.Parse(args[1], NumberStyles.HexNumber);
else if (args[0] == "D5") D[5].s32 = int.Parse(args[1], NumberStyles.HexNumber);
else if (args[0] == "D6") D[6].s32 = int.Parse(args[1], NumberStyles.HexNumber);
else if (args[0] == "D7") D[7].s32 = int.Parse(args[1], NumberStyles.HexNumber);
[StructLayout(LayoutKind.Explicit)] else if (args[0] == "A0") A[0].s32 = int.Parse(args[1], NumberStyles.HexNumber);
public struct Register 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);
[FieldOffset(0)] else if (args[0] == "A3") A[3].s32 = int.Parse(args[1], NumberStyles.HexNumber);
public uint u32; else if (args[0] == "A4") A[4].s32 = int.Parse(args[1], NumberStyles.HexNumber);
[FieldOffset(0)] else if (args[0] == "A5") A[5].s32 = int.Parse(args[1], NumberStyles.HexNumber);
public int s32; else if (args[0] == "A6") A[6].s32 = int.Parse(args[1], NumberStyles.HexNumber);
else if (args[0] == "A7") A[7].s32 = int.Parse(args[1], NumberStyles.HexNumber);
[FieldOffset(0)] else if (args[0] == "PC") PC = int.Parse(args[1], NumberStyles.HexNumber);
public ushort u16; else if (args[0] == "InterruptMaskLevel") InterruptMaskLevel = int.Parse(args[1]);
[FieldOffset(0)] else if (args[0] == "USP") usp = int.Parse(args[1], NumberStyles.HexNumber);
public short s16; else if (args[0] == "SSP") ssp = int.Parse(args[1], NumberStyles.HexNumber);
else if (args[0] == "S") s = bool.Parse(args[1]);
else if (args[0] == "M") m = bool.Parse(args[1]);
[FieldOffset(0)] else if (args[0] == "TotalExecutedCycles") TotalExecutedCycles = int.Parse(args[1]);
public byte u8; else if (args[0] == "PendingCycles") PendingCycles = int.Parse(args[1]);
[FieldOffset(0)]
public sbyte s8;
public override string ToString() else
{ Console.WriteLine("Skipping unrecognized identifier " + args[0]);
return String.Format("{0:X8}", u32); }
} }
} }
[StructLayout(LayoutKind.Explicit)]
public struct Register
{
[FieldOffset(0)]
public uint u32;
[FieldOffset(0)]
public int s32;
[FieldOffset(0)]
public ushort u16;
[FieldOffset(0)]
public short s16;
[FieldOffset(0)]
public byte u8;
[FieldOffset(0)]
public sbyte s8;
public override string ToString()
{
return String.Format("{0:X8}", u32);
}
}
} }

File diff suppressed because it is too large Load Diff

View File

@ -3,174 +3,174 @@ using System.Collections.Generic;
using BizHawk.Common; using BizHawk.Common;
namespace BizHawk.Emulation.CPUs.M68000 namespace BizHawk.Emulation.Common.Components.M68000
{ {
partial class MC68000 partial class MC68000
{ {
void BuildOpcodeTable() void BuildOpcodeTable()
{ {
// NOTE: Do not change the order of these assigns without testing. There is // NOTE: Do not change the order of these assigns without testing. There is
// some overwriting of less-specific opcodes with more-specific opcodes. // some overwriting of less-specific opcodes with more-specific opcodes.
// TODO: should really come up with means of only assigning to applicable addressing modes, // TODO: should really come up with means of only assigning to applicable addressing modes,
// instead of this lame overwriting business. // instead of this lame overwriting business.
Assign("move", MOVE, "00", "Size2_0", "XnAm", "AmXn"); Assign("move", MOVE, "00", "Size2_0", "XnAm", "AmXn");
Assign("movea", MOVEA, "00", "Size2_0", "Xn", "001", "AmXn"); Assign("movea", MOVEA, "00", "Size2_0", "Xn", "001", "AmXn");
Assign("moveq", MOVEQ, "0111", "Xn", "0", "Data8"); Assign("moveq", MOVEQ, "0111", "Xn", "0", "Data8");
Assign("movem", MOVEM0,"010010001", "Size1", "AmXn"); Assign("movem", MOVEM0, "010010001", "Size1", "AmXn");
Assign("movem", MOVEM1,"010011001", "Size1", "AmXn"); Assign("movem", MOVEM1, "010011001", "Size1", "AmXn");
Assign("lea", LEA, "0100", "Xn", "111", "AmXn"); Assign("lea", LEA, "0100", "Xn", "111", "AmXn");
Assign("clr", CLR, "01000010", "Size2_1", "AmXn"); Assign("clr", CLR, "01000010", "Size2_1", "AmXn");
Assign("ext", EXT, "010010001", "Size1", "000", "Xn"); Assign("ext", EXT, "010010001", "Size1", "000", "Xn");
Assign("pea", PEA, "0100100001", "AmXn"); Assign("pea", PEA, "0100100001", "AmXn");
Assign("andi", ANDI, "00000010", "Size2_1", "AmXn"); Assign("andi", ANDI, "00000010", "Size2_1", "AmXn");
Assign("eori", EORI, "00001010", "Size2_1", "AmXn"); Assign("eori", EORI, "00001010", "Size2_1", "AmXn");
Assign("ori", ORI, "00000000", "Size2_1", "AmXn"); Assign("ori", ORI, "00000000", "Size2_1", "AmXn");
Assign("asl", ASLd, "1110", "Data3", "1", "Size2_1", "Data1", "00", "Xn"); Assign("asl", ASLd, "1110", "Data3", "1", "Size2_1", "Data1", "00", "Xn");
Assign("asr", ASRd, "1110", "Data3", "0", "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("lsl", LSLd, "1110", "Data3", "1", "Size2_1", "Data1", "01", "Xn");
Assign("lsr", LSRd, "1110", "Data3", "0", "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("roxl", ROXLd, "1110", "Data3", "1", "Size2_1", "Data1", "10", "Xn");
Assign("roxr", ROXRd, "1110", "Data3", "0", "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("rol", ROLd, "1110", "Data3", "1", "Size2_1", "Data1", "11", "Xn");
Assign("ror", RORd, "1110", "Data3", "0", "Size2_1", "Data1", "11", "Xn"); Assign("ror", RORd, "1110", "Data3", "0", "Size2_1", "Data1", "11", "Xn");
Assign("swap", SWAP, "0100100001000","Xn"); Assign("swap", SWAP, "0100100001000", "Xn");
Assign("and", AND0, "1100", "Xn", "0", "Size2_1", "AmXn"); Assign("and", AND0, "1100", "Xn", "0", "Size2_1", "AmXn");
Assign("and", AND1, "1100", "Xn", "1", "Size2_1", "AmXn"); Assign("and", AND1, "1100", "Xn", "1", "Size2_1", "AmXn");
Assign("eor", EOR, "1011", "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", OR0, "1000", "Xn", "0", "Size2_1", "AmXn");
Assign("or", OR1, "1000", "Xn", "1", "Size2_1", "AmXn"); Assign("or", OR1, "1000", "Xn", "1", "Size2_1", "AmXn");
Assign("not", NOT, "01000110", "Size2_1", "AmXn"); Assign("not", NOT, "01000110", "Size2_1", "AmXn");
Assign("neg", NEG, "01000100", "Size2_1", "AmXn"); Assign("neg", NEG, "01000100", "Size2_1", "AmXn");
Assign("jmp", JMP, "0100111011", "AmXn"); Assign("jmp", JMP, "0100111011", "AmXn");
Assign("jsr", JSR, "0100111010", "AmXn"); Assign("jsr", JSR, "0100111010", "AmXn");
Assign("bcc", Bcc, "0110", "CondMain", "Data8"); Assign("bcc", Bcc, "0110", "CondMain", "Data8");
Assign("bra", BRA, "01100000", "Data8"); Assign("bra", BRA, "01100000", "Data8");
Assign("bsr", BSR, "01100001", "Data8"); Assign("bsr", BSR, "01100001", "Data8");
Assign("scc", Scc, "0101", "CondAll", "11","AmXn"); Assign("scc", Scc, "0101", "CondAll", "11", "AmXn");
Assign("dbcc", DBcc, "0101", "CondAll", "11001", "Xn"); Assign("dbcc", DBcc, "0101", "CondAll", "11001", "Xn");
Assign("rte", RTE, "0100111001110011"); Assign("rte", RTE, "0100111001110011");
Assign("rts", RTS, "0100111001110101"); Assign("rts", RTS, "0100111001110101");
Assign("rtr", RTR, "0100111001110111"); Assign("rtr", RTR, "0100111001110111");
Assign("tst", TST, "01001010", "Size2_1", "AmXn"); Assign("tst", TST, "01001010", "Size2_1", "AmXn");
Assign("btst", BTSTi, "0000100000", "AmXn"); Assign("btst", BTSTi, "0000100000", "AmXn");
Assign("btst", BTSTr, "0000", "Xn", "100", "AmXn"); Assign("btst", BTSTr, "0000", "Xn", "100", "AmXn");
Assign("bchg", BCHGi, "0000100001", "AmXn"); Assign("bchg", BCHGi, "0000100001", "AmXn");
Assign("bchg", BCHGr, "0000", "Xn", "101", "AmXn"); Assign("bchg", BCHGr, "0000", "Xn", "101", "AmXn");
Assign("bclr", BCLRi, "0000100010", "AmXn"); Assign("bclr", BCLRi, "0000100010", "AmXn");
Assign("bclr", BCLRr, "0000", "Xn", "110", "AmXn"); Assign("bclr", BCLRr, "0000", "Xn", "110", "AmXn");
Assign("bset", BSETi, "0000100011", "AmXn"); Assign("bset", BSETi, "0000100011", "AmXn");
Assign("bset", BSETr, "0000", "Xn", "111", "AmXn"); Assign("bset", BSETr, "0000", "Xn", "111", "AmXn");
Assign("link", LINK, "0100111001010", "Xn"); Assign("link", LINK, "0100111001010", "Xn");
Assign("unlk", UNLK, "0100111001011", "Xn"); Assign("unlk", UNLK, "0100111001011", "Xn");
Assign("nop", NOP, "0100111001110001"); Assign("nop", NOP, "0100111001110001");
Assign("add", ADD0, "1101", "Xn", "0", "Size2_1", "AmXn"); Assign("add", ADD0, "1101", "Xn", "0", "Size2_1", "AmXn");
Assign("add", ADD1, "1101", "Xn", "1", "Size2_1", "AmXn"); Assign("add", ADD1, "1101", "Xn", "1", "Size2_1", "AmXn");
Assign("adda", ADDA, "1101", "Xn", "Size1", "11", "AmXn"); Assign("adda", ADDA, "1101", "Xn", "Size1", "11", "AmXn");
Assign("addi", ADDI, "00000110", "Size2_1", "AmXn"); Assign("addi", ADDI, "00000110", "Size2_1", "AmXn");
Assign("addq", ADDQ, "0101", "Data3", "0", "Size2_1", "AmXn"); Assign("addq", ADDQ, "0101", "Data3", "0", "Size2_1", "AmXn");
Assign("sub", SUB0, "1001", "Xn", "0", "Size2_1", "AmXn"); Assign("sub", SUB0, "1001", "Xn", "0", "Size2_1", "AmXn");
Assign("sub", SUB1, "1001", "Xn", "1", "Size2_1", "AmXn"); Assign("sub", SUB1, "1001", "Xn", "1", "Size2_1", "AmXn");
Assign("suba", SUBA, "1001", "Xn", "Size1", "11", "AmXn"); Assign("suba", SUBA, "1001", "Xn", "Size1", "11", "AmXn");
Assign("subi", SUBI, "00000100", "Size2_1", "AmXn"); Assign("subi", SUBI, "00000100", "Size2_1", "AmXn");
Assign("subq", SUBQ, "0101", "Data3", "1", "Size2_1", "AmXn"); Assign("subq", SUBQ, "0101", "Data3", "1", "Size2_1", "AmXn");
Assign("cmp", CMP, "1011", "Xn", "0", "Size2_1", "AmXn"); Assign("cmp", CMP, "1011", "Xn", "0", "Size2_1", "AmXn");
Assign("cmpm", CMPM, "1011", "Xn", "1", "Size2_1", "001", "Xn"); Assign("cmpm", CMPM, "1011", "Xn", "1", "Size2_1", "001", "Xn");
Assign("cmpa", CMPA, "1011", "Xn", "Size1", "11", "AmXn"); Assign("cmpa", CMPA, "1011", "Xn", "Size1", "11", "AmXn");
Assign("cmpi", CMPI, "00001100", "Size2_1", "AmXn"); Assign("cmpi", CMPI, "00001100", "Size2_1", "AmXn");
Assign("mulu", MULU, "1100", "Xn", "011", "AmXn"); // TODO accurate timing Assign("mulu", MULU, "1100", "Xn", "011", "AmXn"); // TODO accurate timing
Assign("muls", MULS, "1100", "Xn", "111", "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("divu", DIVU, "1000", "Xn", "011", "AmXn"); // TODO accurate timing
Assign("divs", DIVS, "1000", "Xn", "111", "AmXn"); // TODO accurate timing Assign("divs", DIVS, "1000", "Xn", "111", "AmXn"); // TODO accurate timing
Assign("move2sr", MOVEtSR, "0100011011", "AmXn"); Assign("move2sr", MOVEtSR, "0100011011", "AmXn");
Assign("movefsr", MOVEfSR, "0100000011", "AmXn"); Assign("movefsr", MOVEfSR, "0100000011", "AmXn");
Assign("moveusp", MOVEUSP, "010011100110", "Data1", "Xn"); Assign("moveusp", MOVEUSP, "010011100110", "Data1", "Xn");
Assign("andi2sr", ANDI_SR, "0000001001111100"); Assign("andi2sr", ANDI_SR, "0000001001111100");
Assign("eori2sr", EORI_SR, "0000101001111100"); Assign("eori2sr", EORI_SR, "0000101001111100");
Assign("ori2sr", ORI_SR, "0000000001111100"); Assign("ori2sr", ORI_SR, "0000000001111100");
Assign("moveccr", MOVECCR, "0100010011", "AmXn"); Assign("moveccr", MOVECCR, "0100010011", "AmXn");
Assign("trap", TRAP, "010011100100", "Data4"); Assign("trap", TRAP, "010011100100", "Data4");
} }
void Assign(string instr, Action exec, string root, params string[] bitfield) void Assign(string instr, Action exec, string root, params string[] bitfield)
{ {
List<string> opList = new List<string>(); List<string> opList = new List<string>();
opList.Add(root); opList.Add(root);
foreach (var component in bitfield) foreach (var component in bitfield)
{ {
if (component.IsBinary()) AppendConstant(opList, component); if (component.IsBinary()) AppendConstant(opList, component);
else if (component == "Size1") opList = AppendPermutations(opList, Size1); else if (component == "Size1") opList = AppendPermutations(opList, Size1);
else if (component == "Size2_0") opList = AppendPermutations(opList, Size2_0); else if (component == "Size2_0") opList = AppendPermutations(opList, Size2_0);
else if (component == "Size2_1") opList = AppendPermutations(opList, Size2_1); else if (component == "Size2_1") opList = AppendPermutations(opList, Size2_1);
else if (component == "XnAm") opList = AppendPermutations(opList, Xn3Am3); else if (component == "XnAm") opList = AppendPermutations(opList, Xn3Am3);
else if (component == "AmXn") opList = AppendPermutations(opList, Am3Xn3); else if (component == "AmXn") opList = AppendPermutations(opList, Am3Xn3);
else if (component == "Xn") opList = AppendPermutations(opList, Xn3); else if (component == "Xn") opList = AppendPermutations(opList, Xn3);
else if (component == "CondMain") opList = AppendPermutations(opList, ConditionMain); else if (component == "CondMain") opList = AppendPermutations(opList, ConditionMain);
else if (component == "CondAll") opList = AppendPermutations(opList, ConditionAll); else if (component == "CondAll") opList = AppendPermutations(opList, ConditionAll);
else if (component == "Data1") opList = AppendData(opList, 1); else if (component == "Data1") opList = AppendData(opList, 1);
else if (component == "Data4") opList = AppendData(opList, 4); else if (component == "Data4") opList = AppendData(opList, 4);
else if (component == "Data3") opList = AppendData(opList, 3); else if (component == "Data3") opList = AppendData(opList, 3);
else if (component == "Data8") opList = AppendData(opList, 8); else if (component == "Data8") opList = AppendData(opList, 8);
} }
foreach (var opcode in opList) foreach (var opcode in opList)
{ {
int opc = Convert.ToInt32(opcode, 2); int opc = Convert.ToInt32(opcode, 2);
if (Opcodes[opc] != null && instr.NotIn("movea","andi2sr","eori2sr","ori2sr","ext","dbcc","swap","cmpm")) 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); Console.WriteLine("Setting opcode for {0}, a handler is already set. overwriting. {1:X4}", instr, opc);
Opcodes[opc] = exec; Opcodes[opc] = exec;
} }
} }
void AppendConstant(List<string> ops, string constant) void AppendConstant(List<string> ops, string constant)
{ {
for (int i=0; i<ops.Count; i++) for (int i = 0; i < ops.Count; i++)
ops[i] = ops[i] + constant; ops[i] = ops[i] + constant;
} }
List<string> AppendPermutations(List<string> ops, string[] permutations) List<string> AppendPermutations(List<string> ops, string[] permutations)
{ {
List<string> output = new List<string>(); List<string> output = new List<string>();
foreach (var input in ops) foreach (var input in ops)
foreach (var perm in permutations) foreach (var perm in permutations)
output.Add(input + perm); output.Add(input + perm);
return output; return output;
} }
List<string> AppendData(List<string> ops, int bits) List<string> AppendData(List<string> ops, int bits)
{ {
List<string> output = new List<string>(); 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'));
return output; foreach (var input in ops)
} for (int i = 0; i < BinaryExp(bits); i++)
output.Add(input + Convert.ToString(i, 2).PadLeft(bits, '0'));
int BinaryExp(int bits) return output;
{ }
int res = 1;
for (int i = 0; i < bits; i++)
res *= 2;
return res;
}
#region Tables int BinaryExp(int bits)
{
int res = 1;
for (int i = 0; i < bits; i++)
res *= 2;
return res;
}
static readonly string[] Size2_0 = {"01", "11", "10"}; #region Tables
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[] Size2_0 = { "01", "11", "10" };
static readonly string[] Size2_1 = { "00", "01", "10" };
static readonly string[] Size1 = { "0", "1" };
static readonly string[] Xn3 = { "000", "001", "010", "011", "100", "101", "110", "111" };
static readonly string[] Xn3Am3 = {
"000000", // Dn Data register "000000", // Dn Data register
"001000", "001000",
"010000", "010000",
@ -239,9 +239,9 @@ namespace BizHawk.Emulation.CPUs.M68000
"000111", // (xxx).W Absolute Short "000111", // (xxx).W Absolute Short
"001111", // (xxx).L Absolute Long "001111", // (xxx).L Absolute Long
"100111", // #imm Immediate "100111", // #imm Immediate
}; };
static readonly string[] Am3Xn3 = { static readonly string[] Am3Xn3 = {
"000000", // Dn Data register "000000", // Dn Data register
"000001", "000001",
"000010", "000010",
@ -312,7 +312,7 @@ namespace BizHawk.Emulation.CPUs.M68000
"111100", // #imm Immediate "111100", // #imm Immediate
}; };
static readonly string[] ConditionMain = { static readonly string[] ConditionMain = {
"0010", // HI Higher (unsigned) "0010", // HI Higher (unsigned)
"0011", // LS Lower or Same (unsigned) "0011", // LS Lower or Same (unsigned)
"0100", // CC Carry Clear (aka Higher 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) "1111" // LE Less or Equal (signed)
}; };
static readonly string[] ConditionAll = { static readonly string[] ConditionAll = {
"0000", // T True "0000", // T True
"0001", // F False "0001", // F False
"0010", // HI Higher (unsigned) "0010", // HI Higher (unsigned)
@ -348,6 +348,6 @@ namespace BizHawk.Emulation.CPUs.M68000
"1111" // LE Less or Equal (signed) "1111" // LE Less or Equal (signed)
}; };
#endregion #endregion
} }
} }

View File

@ -1,10 +1,10 @@
namespace BizHawk.Emulation.CPUs.M68000 namespace BizHawk.Emulation.Common.Components.M68000
{ {
partial class MC68000 partial class MC68000
{ {
static readonly int[,] MoveCyclesBW = new int[12,9] static readonly int[,] MoveCyclesBW = new int[12, 9]
{ {
{ 4, 4, 8, 8, 8, 12, 14, 12, 16 }, { 4, 4, 8, 8, 8, 12, 14, 12, 16 },
{ 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 },
{ 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 }, { 12, 12, 16, 16, 16, 20, 22, 20, 24 },
{ 14, 14, 18, 18, 18, 22, 24, 22, 26 }, { 14, 14, 18, 18, 18, 22, 24, 22, 26 },
{ 8, 8, 12, 12, 12, 16, 18, 16, 20 } { 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 },
{ 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 }, { 12, 12, 20, 20, 20, 24, 26, 24, 28 },
@ -32,30 +32,30 @@
{ 16, 16, 24, 24, 24, 28, 30, 28, 32 }, { 16, 16, 24, 24, 24, 28, 30, 28, 32 },
{ 18, 18, 26, 26, 26, 30, 32, 30, 34 }, { 18, 18, 26, 26, 26, 30, 32, 30, 34 },
{ 12, 12, 20, 20, 20, 24, 26, 24, 28 } { 12, 12, 20, 20, 20, 24, 26, 24, 28 }
}; };
static readonly int[,] EACyclesBW = new int[8, 8] static readonly int[,] EACyclesBW = new int[8, 8]
{ {
{ 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 },
{ 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 },
{ 4, 4, 4, 4, 4, 4, 4, 4 }, { 4, 4, 4, 4, 4, 4, 4, 4 },
{ 6, 6, 6, 6, 6, 6, 6, 6 }, { 6, 6, 6, 6, 6, 6, 6, 6 },
{ 8, 8, 8, 8, 8, 8, 8, 8 }, { 8, 8, 8, 8, 8, 8, 8, 8 },
{ 10, 10, 10, 10, 10, 10, 10, 10 }, { 10, 10, 10, 10, 10, 10, 10, 10 },
{ 8, 12, 8, 10, 4, 99, 99, 99 } { 8, 12, 8, 10, 4, 99, 99, 99 }
}; };
static readonly int[,] EACyclesL = new int[8, 8] static readonly int[,] EACyclesL = new int[8, 8]
{ {
{ 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 },
{ 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 },
{ 8, 8, 8, 8, 8, 8, 8, 8 }, { 8, 8, 8, 8, 8, 8, 8, 8 },
{ 10, 10, 10, 10, 10, 10, 10, 10 }, { 10, 10, 10, 10, 10, 10, 10, 10 },
{ 12, 12, 12, 12, 12, 12, 12, 12 }, { 12, 12, 12, 12, 12, 12, 12, 12 },
{ 14, 14, 14, 14, 14, 14, 14, 14 }, { 14, 14, 14, 14, 14, 14, 14, 14 },
{ 12, 16, 12, 14, 8, 99, 99, 99 } { 12, 16, 12, 14, 8, 99, 99, 99 }
}; };
} }
} }

View File

@ -1,7 +1,7 @@
using System; using System;
using System.IO; using System.IO;
namespace BizHawk.Emulation.CPUs.CP1610 namespace BizHawk.Emulation.Common.Components.CP1610
{ {
public sealed partial class CP1610 public sealed partial class CP1610
{ {

View File

@ -1,4 +1,4 @@
namespace BizHawk.Emulation.CPUs.CP1610 namespace BizHawk.Emulation.Common.Components.CP1610
{ {
public sealed partial class CP1610 public sealed partial class CP1610
{ {

View File

@ -1,6 +1,6 @@
using System; using System;
namespace BizHawk.Emulation.CPUs.CP1610 namespace BizHawk.Emulation.Common.Components.CP1610
{ {
public sealed partial class CP1610 public sealed partial class CP1610
{ {

View File

@ -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. // Do not modify this file directly! This is GENERATED code.
// Please open the CpuCoreGenerator solution and make your modifications there. // Please open the CpuCoreGenerator solution and make your modifications there.

View File

@ -3,7 +3,7 @@ using System;
// Do not modify this file directly! This is GENERATED code. // Do not modify this file directly! This is GENERATED code.
// Please open the CpuCoreGenerator solution and make your modifications there. // 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 public partial class HuC6280
{ {

View File

@ -4,7 +4,7 @@ using System.IO;
using BizHawk.Common; using BizHawk.Common;
namespace BizHawk.Emulation.CPUs.H6280 namespace BizHawk.Emulation.Common.Components.H6280
{ {
public sealed partial class HuC6280 public sealed partial class HuC6280
{ {

View File

@ -1,7 +1,7 @@
// Do not modify this file directly! This is GENERATED code. // Do not modify this file directly! This is GENERATED code.
// Please open the CpuCoreGenerator solution and make your modifications there. // 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 public partial class MOS6502X
{ {

View File

@ -1,10 +1,9 @@
//http://nesdev.parodius.com/6502_cpu.txt //http://nesdev.parodius.com/6502_cpu.txt
using System; using System;
using BizHawk.Common; using BizHawk.Common;
namespace BizHawk.Emulation.CPUs.M6502 namespace BizHawk.Emulation.Common.Components.M6502
{ {
public partial class MOS6502X public partial class MOS6502X
{ {

View File

@ -3,7 +3,7 @@ using System.IO;
using BizHawk.Common; using BizHawk.Common;
namespace BizHawk.Emulation.CPUs.M6502 namespace BizHawk.Emulation.Common.Components.M6502
{ {
public sealed partial class MOS6502X public sealed partial class MOS6502X
{ {

View File

@ -4,7 +4,7 @@ using System.IO;
using BizHawk.Common; using BizHawk.Common;
namespace BizHawk.Emulation.CPUs.M6502 namespace BizHawk.Emulation.Common.Components.M6502
{ {
/// <summary> /// <summary>
/// maintains a managed 6502X and an unmanaged 6502X, running them alongside and ensuring consistency /// maintains a managed 6502X and an unmanaged 6502X, running them alongside and ensuring consistency

View File

@ -3,7 +3,7 @@ using System.Runtime.InteropServices;
using BizHawk.Common; using BizHawk.Common;
namespace BizHawk.Emulation.CPUs.M6502 namespace BizHawk.Emulation.Common.Components.M6502
{ {
public static class MOS6502X_DLL public static class MOS6502X_DLL
{ {

View File

@ -30,7 +30,7 @@ using System;
SRL SRL
*/ */
namespace BizHawk.Emulation.CPUs.Z80GB namespace BizHawk.Emulation.Common.Components.Z80GB
{ {
public partial class Z80 public partial class Z80
{ {

View File

@ -1,9 +1,9 @@
using System; using System;
namespace BizHawk.Emulation.CPUs.Z80GB namespace BizHawk.Emulation.Common.Components.Z80GB
{ {
public partial class Z80 public partial class Z80
{ {
private bool iff1; private bool iff1;
public bool IFF1 { get { return iff1; } set { iff1 = value; } } public bool IFF1 { get { return iff1; } set { iff1 = value; } }
@ -14,8 +14,8 @@ namespace BizHawk.Emulation.CPUs.Z80GB
public bool Interrupt { get { return interrupt; } set { interrupt = value; } } public bool Interrupt { get { return interrupt; } set { interrupt = value; } }
private bool nonMaskableInterrupt; private bool nonMaskableInterrupt;
public bool NonMaskableInterrupt public bool NonMaskableInterrupt
{ {
get { return nonMaskableInterrupt; } get { return nonMaskableInterrupt; }
set { if (value && !nonMaskableInterrupt) NonMaskableInterruptPending = true; nonMaskableInterrupt = value; } set { if (value && !nonMaskableInterrupt) NonMaskableInterruptPending = true; nonMaskableInterrupt = value; }
} }
@ -24,8 +24,8 @@ namespace BizHawk.Emulation.CPUs.Z80GB
public bool NonMaskableInterruptPending { get { return nonMaskableInterruptPending; } set { nonMaskableInterruptPending = value; } } public bool NonMaskableInterruptPending { get { return nonMaskableInterruptPending; } set { nonMaskableInterruptPending = value; } }
private int interruptMode; private int interruptMode;
public int InterruptMode public int InterruptMode
{ {
get { return interruptMode; } get { return interruptMode; }
set { if (value < 0 || value > 2) throw new ArgumentOutOfRangeException(); interruptMode = value; } set { if (value < 0 || value > 2) throw new ArgumentOutOfRangeException(); interruptMode = value; }
} }
@ -33,8 +33,8 @@ namespace BizHawk.Emulation.CPUs.Z80GB
private bool halted; private bool halted;
public bool Halted { get { return halted; } set { halted = value; } } public bool Halted { get { return halted; } set { halted = value; } }
private void ResetInterrupts() private void ResetInterrupts()
{ {
IFF1 = false; IFF1 = false;
IFF2 = false; IFF2 = false;
Interrupt = false; Interrupt = false;
@ -44,8 +44,8 @@ namespace BizHawk.Emulation.CPUs.Z80GB
Halted = false; Halted = false;
} }
private void Halt() private void Halt()
{ {
Halted = true; Halted = true;
} }
} }

View File

@ -2,7 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; 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 // adapted from the information at http://www.pastraiser.com/cpu/gameboy/gameboy_opcodes.html
public class NewDisassembler public class NewDisassembler

View File

@ -1,14 +1,14 @@
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System; using System;
namespace BizHawk.Emulation.CPUs.Z80GB namespace BizHawk.Emulation.Common.Components.Z80GB
{ {
public partial class Z80 public partial class Z80
{ {
[StructLayout(LayoutKind.Explicit)] [StructLayout(LayoutKind.Explicit)]
[Serializable] [Serializable]
public struct RegisterPair public struct RegisterPair
{ {
[FieldOffset(0)] [FieldOffset(0)]
public ushort Word; public ushort Word;
@ -18,44 +18,44 @@ namespace BizHawk.Emulation.CPUs.Z80GB
[FieldOffset(1)] [FieldOffset(1)]
public byte High; public byte High;
public RegisterPair(ushort value) public RegisterPair(ushort value)
{ {
Word = value; Word = value;
Low = (byte)(Word); Low = (byte)(Word);
High = (byte)(Word >> 8); High = (byte)(Word >> 8);
} }
public static implicit operator ushort(RegisterPair rp) public static implicit operator ushort(RegisterPair rp)
{ {
return rp.Word; return rp.Word;
} }
public static implicit operator RegisterPair(ushort value) public static implicit operator RegisterPair(ushort value)
{ {
return new RegisterPair(value); return new RegisterPair(value);
} }
} }
public bool FlagC public bool FlagC
{ {
get { return (RegAF.Low & 0x10) != 0; } get { return (RegAF.Low & 0x10) != 0; }
set { RegAF.Low = (byte)((RegAF.Low & ~0x10) | (value ? 0x10 : 0x00)); } set { RegAF.Low = (byte)((RegAF.Low & ~0x10) | (value ? 0x10 : 0x00)); }
} }
public bool FlagH public bool FlagH
{ {
get { return (RegAF.Low & 0x20) != 0; } get { return (RegAF.Low & 0x20) != 0; }
set { RegAF.Low = (byte)((RegAF.Low & ~0x20) | (value ? 0x20 : 0x00)); } set { RegAF.Low = (byte)((RegAF.Low & ~0x20) | (value ? 0x20 : 0x00)); }
} }
public bool FlagN public bool FlagN
{ {
get { return (RegAF.Low & 0x40) != 0; } get { return (RegAF.Low & 0x40) != 0; }
set { RegAF.Low = (byte)((RegAF.Low & ~0x40) | (value ? 0x40 : 0x00)); } set { RegAF.Low = (byte)((RegAF.Low & ~0x40) | (value ? 0x40 : 0x00)); }
} }
public bool FlagZ public bool FlagZ
{ {
get { return (RegAF.Low & 0x80) != 0; } get { return (RegAF.Low & 0x80) != 0; }
set { RegAF.Low = (byte)((RegAF.Low & ~0x80) | (value ? 0x80 : 0x00)); } set { RegAF.Low = (byte)((RegAF.Low & ~0x80) | (value ? 0x80 : 0x00)); }
} }
@ -64,101 +64,101 @@ namespace BizHawk.Emulation.CPUs.Z80GB
private RegisterPair RegBC; private RegisterPair RegBC;
private RegisterPair RegDE; private RegisterPair RegDE;
private RegisterPair RegHL; private RegisterPair RegHL;
private byte RegI; // I (interrupt vector) private byte RegI; // I (interrupt vector)
private RegisterPair RegSP; // SP (stack pointer) private RegisterPair RegSP; // SP (stack pointer)
private RegisterPair RegPC; // PC (program counter) private RegisterPair RegPC; // PC (program counter)
private void ResetRegisters() private void ResetRegisters()
{ {
RegAF = 0; RegBC = 0; RegDE = 0; RegHL = 0; RegAF = 0; RegBC = 0; RegDE = 0; RegHL = 0;
RegI = 0; RegI = 0;
RegSP.Word = 0; RegPC.Word = 0; RegSP.Word = 0; RegPC.Word = 0;
} }
public byte RegisterA public byte RegisterA
{ {
get { return RegAF.High; } get { return RegAF.High; }
set { RegAF.High = value; } set { RegAF.High = value; }
} }
public byte RegisterF public byte RegisterF
{ {
get { return RegAF.Low; } get { return RegAF.Low; }
set { RegAF.Low = (byte)(value&0xF0); } set { RegAF.Low = (byte)(value & 0xF0); }
} }
public ushort RegisterAF public ushort RegisterAF
{ {
get { return RegAF.Word; } get { return RegAF.Word; }
set { RegAF.Word = (byte)(value&0xFFF0); } set { RegAF.Word = (byte)(value & 0xFFF0); }
} }
public byte RegisterB public byte RegisterB
{ {
get { return RegBC.High; } get { return RegBC.High; }
set { RegBC.High = value; } set { RegBC.High = value; }
} }
public byte RegisterC public byte RegisterC
{ {
get { return RegBC.Low; } get { return RegBC.Low; }
set { RegBC.Low = value; } set { RegBC.Low = value; }
} }
public ushort RegisterBC public ushort RegisterBC
{ {
get { return RegBC.Word; } get { return RegBC.Word; }
set { RegBC.Word = value; } set { RegBC.Word = value; }
} }
public byte RegisterD public byte RegisterD
{ {
get { return RegDE.High; } get { return RegDE.High; }
set { RegDE.High = value; } set { RegDE.High = value; }
} }
public byte RegisterE public byte RegisterE
{ {
get { return RegDE.Low; } get { return RegDE.Low; }
set { RegDE.Low = value; } set { RegDE.Low = value; }
} }
public ushort RegisterDE public ushort RegisterDE
{ {
get { return RegDE.Word; } get { return RegDE.Word; }
set { RegDE.Word = value; } set { RegDE.Word = value; }
} }
public byte RegisterH public byte RegisterH
{ {
get { return RegHL.High; } get { return RegHL.High; }
set { RegHL.High = value; } set { RegHL.High = value; }
} }
public byte RegisterL public byte RegisterL
{ {
get { return RegHL.Low; } get { return RegHL.Low; }
set { RegHL.Low = value; } set { RegHL.Low = value; }
} }
public ushort RegisterHL public ushort RegisterHL
{ {
get { return RegHL.Word; } get { return RegHL.Word; }
set { RegHL.Word = value; } set { RegHL.Word = value; }
} }
public ushort RegisterPC public ushort RegisterPC
{ {
get { return RegPC.Word; } get { return RegPC.Word; }
set { RegPC.Word = value; } set { RegPC.Word = value; }
} }
public ushort RegisterSP public ushort RegisterSP
{ {
get { return RegSP.Word; } get { return RegSP.Word; }
set { RegSP.Word = value; } set { RegSP.Word = value; }
} }
public byte RegisterI public byte RegisterI
{ {
get { return RegI; } get { return RegI; }
set { RegI = value; } set { RegI = value; }
} }

View File

@ -1,149 +1,149 @@
namespace BizHawk.Emulation.CPUs.Z80GB namespace BizHawk.Emulation.Common.Components.Z80GB
{ {
public partial class Z80 public partial class Z80
{ {
private void InitializeTables() private void InitializeTables()
{ {
InitTableDaa(); InitTableDaa();
} }
private static readonly byte[] IncTable = private static readonly byte[] IncTable =
{ {
160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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 = private static readonly byte[] DecTable =
{ {
192, 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, 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 = private static readonly byte[] SwapTable =
{ {
0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F, 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
}; };
private static readonly byte[] mCycleTable = new byte[] 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, 5, 2, 2, 2, 1, 1, 2, 1,
1, 3, 2, 2, 1, 1, 2, 1, 3, 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, 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, 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, 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, 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,
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, 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, 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, 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, 3, 3, 2, 1, 0, 4, 2, 4, 3, 2, 4, 1, 0, 0, 2, 4,
}; };
private static readonly byte[] cbMCycleTable = new byte[] 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, 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, 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,
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 ushort[] TableDaa;
private void InitTableDaa() private void InitTableDaa()
{ {
TableDaa = new ushort[65536]; TableDaa = new ushort[65536];
for (int af = 0; af < 65536; ++af) for (int af = 0; af < 65536; ++af)
{ {
byte a = (byte)(af >> 8); byte a = (byte)(af >> 8);
byte tmp = a; byte tmp = a;
if (IsN(af)) if (IsN(af))
{ {
if (IsH(af) || ((a & 0x0F) > 0x09)) tmp -= 0x06; if (IsH(af) || ((a & 0x0F) > 0x09)) tmp -= 0x06;
if (IsC(af) || a > 0x99) tmp -= 0x60; if (IsC(af) || a > 0x99) tmp -= 0x60;
} }
else else
{ {
if (IsH(af) || ((a & 0x0F) > 0x09)) tmp += 0x06; if (IsH(af) || ((a & 0x0F) > 0x09)) tmp += 0x06;
if (IsC(af) || a > 0x99) tmp += 0x60; 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)( return (byte)(
(C ? 0x10 : 0) + (C ? 0x10 : 0) +
(H ? 0x20 : 0) + (H ? 0x20 : 0) +
(N ? 0x40 : 0) + (N ? 0x40 : 0) +
(Z ? 0x80 : 0) (Z ? 0x80 : 0)
); );
} }
private static bool IsC(int value) { return (value & 0x10) != 0; } private static bool IsC(int value) { return (value & 0x10) != 0; }
private static bool IsH(int value) { return (value & 0x20) != 0; } private static bool IsH(int value) { return (value & 0x20) != 0; }
private static bool IsN(int value) { return (value & 0x40) != 0; } private static bool IsN(int value) { return (value & 0x40) != 0; }
private static bool IsZ(int value) { return (value & 0x80) != 0; } private static bool IsZ(int value) { return (value & 0x80) != 0; }
} }
} }

View File

@ -5,7 +5,7 @@ using System.IO;
// This Z80-Gameboy emulator is a modified version of Ben Ryves 'Brazil' emulator. // This Z80-Gameboy emulator is a modified version of Ben Ryves 'Brazil' emulator.
// It is MIT licensed (not public domain). (See Licenses) // 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 public sealed partial class Z80
{ {

View File

@ -12,7 +12,7 @@
using System; using System;
namespace BizHawk.Emulation.CPUs.Z80 namespace BizHawk.Emulation.Common.Components.Z80
{ {
public class Disassembler public class Disassembler
{ {

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,9 @@
using System; using System;
namespace BizHawk.Emulation.CPUs.Z80 namespace BizHawk.Emulation.Common.Components.Z80
{ {
public partial class Z80A public partial class Z80A
{ {
private bool iff1; private bool iff1;
public bool IFF1 { get { return iff1; } set { iff1 = value; } } public bool IFF1 { get { return iff1; } set { iff1 = value; } }
@ -14,8 +14,8 @@ namespace BizHawk.Emulation.CPUs.Z80
public bool Interrupt { get { return interrupt; } set { interrupt = value; } } public bool Interrupt { get { return interrupt; } set { interrupt = value; } }
private bool nonMaskableInterrupt; private bool nonMaskableInterrupt;
public bool NonMaskableInterrupt public bool NonMaskableInterrupt
{ {
get { return nonMaskableInterrupt; } get { return nonMaskableInterrupt; }
set { if (value && !nonMaskableInterrupt) NonMaskableInterruptPending = true; nonMaskableInterrupt = value; } set { if (value && !nonMaskableInterrupt) NonMaskableInterruptPending = true; nonMaskableInterrupt = value; }
} }
@ -24,8 +24,8 @@ namespace BizHawk.Emulation.CPUs.Z80
public bool NonMaskableInterruptPending { get { return nonMaskableInterruptPending; } set { nonMaskableInterruptPending = value; } } public bool NonMaskableInterruptPending { get { return nonMaskableInterruptPending; } set { nonMaskableInterruptPending = value; } }
private int interruptMode; private int interruptMode;
public int InterruptMode public int InterruptMode
{ {
get { return interruptMode; } get { return interruptMode; }
set { if (value < 0 || value > 2) throw new ArgumentOutOfRangeException(); interruptMode = value; } set { if (value < 0 || value > 2) throw new ArgumentOutOfRangeException(); interruptMode = value; }
} }
@ -33,11 +33,11 @@ namespace BizHawk.Emulation.CPUs.Z80
private bool halted; private bool halted;
public bool Halted { get { return halted; } set { halted = value; } } public bool Halted { get { return halted; } set { halted = value; } }
public Action IRQCallback = delegate() { }; public Action IRQCallback = delegate() { };
public Action NMICallback = delegate() { }; public Action NMICallback = delegate() { };
private void ResetInterrupts() private void ResetInterrupts()
{ {
IFF1 = false; IFF1 = false;
IFF2 = false; IFF2 = false;
Interrupt = false; Interrupt = false;
@ -47,8 +47,8 @@ namespace BizHawk.Emulation.CPUs.Z80
Halted = false; Halted = false;
} }
private void Halt() private void Halt()
{ {
Halted = true; Halted = true;
} }
} }

View File

@ -1,14 +1,14 @@
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System; using System;
namespace BizHawk.Emulation.CPUs.Z80 namespace BizHawk.Emulation.Common.Components.Z80
{ {
public partial class Z80A public partial class Z80A
{ {
[StructLayout(LayoutKind.Explicit)] [StructLayout(LayoutKind.Explicit)]
[Serializable()] [Serializable()]
public struct RegisterPair public struct RegisterPair
{ {
[FieldOffset(0)] [FieldOffset(0)]
public ushort Word; public ushort Word;
@ -18,68 +18,68 @@ namespace BizHawk.Emulation.CPUs.Z80
[FieldOffset(1)] [FieldOffset(1)]
public byte High; public byte High;
public RegisterPair(ushort value) public RegisterPair(ushort value)
{ {
Word = value; Word = value;
Low = (byte)(Word); Low = (byte)(Word);
High = (byte)(Word >> 8); High = (byte)(Word >> 8);
} }
public static implicit operator ushort(RegisterPair rp) public static implicit operator ushort(RegisterPair rp)
{ {
return rp.Word; return rp.Word;
} }
public static implicit operator RegisterPair(ushort value) public static implicit operator RegisterPair(ushort value)
{ {
return new RegisterPair(value); return new RegisterPair(value);
} }
} }
private bool RegFlagC private bool RegFlagC
{ {
get { return (RegAF.Low & 0x01) != 0; } get { return (RegAF.Low & 0x01) != 0; }
set { RegAF.Low = (byte)((RegAF.Low & ~0x01) | (value ? 0x01 : 0x00)); } set { RegAF.Low = (byte)((RegAF.Low & ~0x01) | (value ? 0x01 : 0x00)); }
} }
private bool RegFlagN private bool RegFlagN
{ {
get { return (RegAF.Low & 0x02) != 0; } get { return (RegAF.Low & 0x02) != 0; }
set { RegAF.Low = (byte)((RegAF.Low & ~0x02) | (value ? 0x02 : 0x00)); } set { RegAF.Low = (byte)((RegAF.Low & ~0x02) | (value ? 0x02 : 0x00)); }
} }
private bool RegFlagP private bool RegFlagP
{ {
get { return (RegAF.Low & 0x04) != 0; } get { return (RegAF.Low & 0x04) != 0; }
set { RegAF.Low = (byte)((RegAF.Low & ~0x04) | (value ? 0x04 : 0x00)); } set { RegAF.Low = (byte)((RegAF.Low & ~0x04) | (value ? 0x04 : 0x00)); }
} }
private bool RegFlag3 private bool RegFlag3
{ {
get { return (RegAF.Low & 0x08) != 0; } get { return (RegAF.Low & 0x08) != 0; }
set { RegAF.Low = (byte)((RegAF.Low & ~0x08) | (value ? 0x08 : 0x00)); } set { RegAF.Low = (byte)((RegAF.Low & ~0x08) | (value ? 0x08 : 0x00)); }
} }
private bool RegFlagH private bool RegFlagH
{ {
get { return (RegAF.Low & 0x10) != 0; } get { return (RegAF.Low & 0x10) != 0; }
set { RegAF.Low = (byte)((RegAF.Low & ~0x10) | (value ? 0x10 : 0x00)); } set { RegAF.Low = (byte)((RegAF.Low & ~0x10) | (value ? 0x10 : 0x00)); }
} }
private bool RegFlag5 private bool RegFlag5
{ {
get { return (RegAF.Low & 0x20) != 0; } get { return (RegAF.Low & 0x20) != 0; }
set { RegAF.Low = (byte)((RegAF.Low & ~0x20) | (value ? 0x20 : 0x00)); } set { RegAF.Low = (byte)((RegAF.Low & ~0x20) | (value ? 0x20 : 0x00)); }
} }
private bool RegFlagZ private bool RegFlagZ
{ {
get { return (RegAF.Low & 0x40) != 0; } get { return (RegAF.Low & 0x40) != 0; }
set { RegAF.Low = (byte)((RegAF.Low & ~0x40) | (value ? 0x40 : 0x00)); } set { RegAF.Low = (byte)((RegAF.Low & ~0x40) | (value ? 0x40 : 0x00)); }
} }
private bool RegFlagS private bool RegFlagS
{ {
get { return (RegAF.Low & 0x80) != 0; } get { return (RegAF.Low & 0x80) != 0; }
set { RegAF.Low = (byte)((RegAF.Low & ~0x80) | (value ? 0x80 : 0x00)); } set { RegAF.Low = (byte)((RegAF.Low & ~0x80) | (value ? 0x80 : 0x00)); }
} }
@ -93,7 +93,7 @@ namespace BizHawk.Emulation.CPUs.Z80
private RegisterPair RegAltBC; // Shadow for B and C private RegisterPair RegAltBC; // Shadow for B and C
private RegisterPair RegAltDE; // Shadow for D and E private RegisterPair RegAltDE; // Shadow for D and E
private RegisterPair RegAltHL; // Shadow for H and L private RegisterPair RegAltHL; // Shadow for H and L
private byte RegI; // I (interrupt vector) private byte RegI; // I (interrupt vector)
private byte RegR; // R (memory refresh) private byte RegR; // R (memory refresh)
@ -103,8 +103,8 @@ namespace BizHawk.Emulation.CPUs.Z80
private RegisterPair RegSP; // SP (stack pointer) private RegisterPair RegSP; // SP (stack pointer)
private RegisterPair RegPC; // PC (program counter) private RegisterPair RegPC; // PC (program counter)
private void ResetRegisters() private void ResetRegisters()
{ {
// Clear main registers // Clear main registers
RegAF = 0; RegBC = 0; RegDE = 0; RegHL = 0; RegAF = 0; RegBC = 0; RegDE = 0; RegHL = 0;
// Clear alternate registers // Clear alternate registers
@ -115,123 +115,123 @@ namespace BizHawk.Emulation.CPUs.Z80
RegSP.Word = 0; RegPC.Word = 0; RegSP.Word = 0; RegPC.Word = 0;
} }
public byte RegisterA public byte RegisterA
{ {
get { return RegAF.High; } get { return RegAF.High; }
set { RegAF.High = value; } set { RegAF.High = value; }
} }
public byte RegisterF public byte RegisterF
{ {
get { return RegAF.Low; } get { return RegAF.Low; }
set { RegAF.Low = value; } set { RegAF.Low = value; }
} }
public ushort RegisterAF public ushort RegisterAF
{ {
get { return RegAF.Word; } get { return RegAF.Word; }
set { RegAF.Word = value; } set { RegAF.Word = value; }
} }
public byte RegisterB public byte RegisterB
{ {
get { return RegBC.High; } get { return RegBC.High; }
set { RegBC.High = value; } set { RegBC.High = value; }
} }
public byte RegisterC public byte RegisterC
{ {
get { return RegBC.Low; } get { return RegBC.Low; }
set { RegBC.Low = value; } set { RegBC.Low = value; }
} }
public ushort RegisterBC public ushort RegisterBC
{ {
get { return RegBC.Word; } get { return RegBC.Word; }
set { RegBC.Word = value; } set { RegBC.Word = value; }
} }
public byte RegisterD public byte RegisterD
{ {
get { return RegDE.High; } get { return RegDE.High; }
set { RegDE.High = value; } set { RegDE.High = value; }
} }
public byte RegisterE public byte RegisterE
{ {
get { return RegDE.Low; } get { return RegDE.Low; }
set { RegDE.Low = value; } set { RegDE.Low = value; }
} }
public ushort RegisterDE public ushort RegisterDE
{ {
get { return RegDE.Word; } get { return RegDE.Word; }
set { RegDE.Word = value; } set { RegDE.Word = value; }
} }
public byte RegisterH public byte RegisterH
{ {
get { return RegHL.High; } get { return RegHL.High; }
set { RegHL.High = value; } set { RegHL.High = value; }
} }
public byte RegisterL public byte RegisterL
{ {
get { return RegHL.Low; } get { return RegHL.Low; }
set { RegHL.Low = value; } set { RegHL.Low = value; }
} }
public ushort RegisterHL public ushort RegisterHL
{ {
get { return RegHL.Word; } get { return RegHL.Word; }
set { RegHL.Word = value; } set { RegHL.Word = value; }
} }
public ushort RegisterPC public ushort RegisterPC
{ {
get { return RegPC.Word; } get { return RegPC.Word; }
set { RegPC.Word = value; } set { RegPC.Word = value; }
} }
public ushort RegisterSP public ushort RegisterSP
{ {
get { return RegSP.Word; } get { return RegSP.Word; }
set { RegSP.Word = value; } set { RegSP.Word = value; }
} }
public ushort RegisterIX public ushort RegisterIX
{ {
get { return RegIX.Word; } get { return RegIX.Word; }
set { RegIX.Word = value; } set { RegIX.Word = value; }
} }
public ushort RegisterIY public ushort RegisterIY
{ {
get { return RegIY.Word; } get { return RegIY.Word; }
set { RegIY.Word = value; } set { RegIY.Word = value; }
} }
public byte RegisterI public byte RegisterI
{ {
get { return RegI; } get { return RegI; }
set { RegI = value; } set { RegI = value; }
} }
public byte RegisterR public byte RegisterR
{ {
get { return RegR; } get { return RegR; }
set { RegR = value; } set { RegR = value; }
} }
public ushort RegisterShadowAF public ushort RegisterShadowAF
{ {
get { return RegAltAF.Word; } get { return RegAltAF.Word; }
set { RegAltAF.Word = value; } set { RegAltAF.Word = value; }
} }
public ushort RegisterShadowBC public ushort RegisterShadowBC
{ {
get { return RegAltBC.Word; } get { return RegAltBC.Word; }
set { RegAltBC.Word = value; } set { RegAltBC.Word = value; }
} }
public ushort RegisterShadowDE public ushort RegisterShadowDE
{ {
get { return RegAltDE.Word; } get { return RegAltDE.Word; }
set { RegAltDE.Word = value; } set { RegAltDE.Word = value; }
} }
public ushort RegisterShadowHL public ushort RegisterShadowHL
{ {
get { return RegAltHL.Word; } get { return RegAltHL.Word; }
set { RegAltHL.Word = value; } set { RegAltHL.Word = value; }
} }

View File

@ -1,9 +1,9 @@
namespace BizHawk.Emulation.CPUs.Z80 namespace BizHawk.Emulation.Common.Components.Z80
{ {
public partial class Z80A public partial class Z80A
{ {
private void InitialiseTables() private void InitialiseTables()
{ {
InitTableInc(); InitTableInc();
InitTableDec(); InitTableDec();
InitTableParity(); InitTableParity();
@ -16,30 +16,30 @@ namespace BizHawk.Emulation.CPUs.Z80
} }
private byte[] TableInc; private byte[] TableInc;
private void InitTableInc() private void InitTableInc()
{ {
TableInc = new byte[256]; TableInc = new byte[256];
for (int i = 0; i < 256; ++i) 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); TableInc[i] = FlagByte(false, false, i == 0x80, UndocumentedX(i), (i & 0xF) == 0x0, UndocumentedY(i), i == 0, i > 127);
} }
private byte[] TableDec; private byte[] TableDec;
private void InitTableDec() private void InitTableDec()
{ {
TableDec = new byte[256]; TableDec = new byte[256];
for (int i = 0; i < 256; ++i) 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); TableDec[i] = FlagByte(false, true, i == 0x7F, UndocumentedX(i), (i & 0xF) == 0xF, UndocumentedY(i), i == 0, i > 127);
} }
private bool[] TableParity; private bool[] TableParity;
private void InitTableParity() private void InitTableParity()
{ {
TableParity = new bool[256]; TableParity = new bool[256];
for (int i = 0; i < 256; ++i) for (int i = 0; i < 256; ++i)
{ {
int Bits = 0; int Bits = 0;
for (int j = 0; j < 8; ++j) for (int j = 0; j < 8; ++j)
{ {
Bits += (i >> j) & 1; Bits += (i >> j) & 1;
} }
TableParity[i] = (Bits & 1) == 0; TableParity[i] = (Bits & 1) == 0;
@ -47,18 +47,18 @@ namespace BizHawk.Emulation.CPUs.Z80
} }
private ushort[, , ,] TableALU; private ushort[, , ,] TableALU;
private void InitTableALU() private void InitTableALU()
{ {
TableALU = new ushort[8, 256, 256, 2]; // Class, OP1, OP2, Carry TableALU = new ushort[8, 256, 256, 2]; // Class, OP1, OP2, Carry
for (int i = 0; i < 8; ++i) for (int i = 0; i < 8; ++i)
{ {
for (int op1 = 0; op1 < 256; ++op1) for (int op1 = 0; op1 < 256; ++op1)
{ {
for (int op2 = 0; op2 < 256; ++op2) for (int op2 = 0; op2 < 256; ++op2)
{ {
for (int c = 0; c < 2; ++c) for (int c = 0; c < 2; ++c)
{ {
int ac = (i == 1 || i == 3) ? c : 0; int ac = (i == 1 || i == 3) ? c : 0;
@ -74,8 +74,8 @@ namespace BizHawk.Emulation.CPUs.Z80
int result_ui = 0; int result_ui = 0;
// Fetch result // Fetch result
switch (i) switch (i)
{ {
case 0: case 0:
case 1: case 1:
result_si = (sbyte)op1 + (sbyte)op2 + ac; result_si = (sbyte)op1 + (sbyte)op2 + ac;
@ -102,8 +102,8 @@ namespace BizHawk.Emulation.CPUs.Z80
// Parity/Carry // Parity/Carry
switch (i) switch (i)
{ {
case 0: case 0:
case 1: case 1:
case 2: case 2:
@ -124,8 +124,8 @@ namespace BizHawk.Emulation.CPUs.Z80
N = i == 2 || i == 3 || i == 7; N = i == 2 || i == 3 || i == 7;
// Half carry // Half carry
switch (i) switch (i)
{ {
case 0: case 0:
case 1: case 1:
H = ((op1 & 0xF) + (op2 & 0xF) + (ac & 0xF)) > 0xF; H = ((op1 & 0xF) + (op2 & 0xF) + (ac & 0xF)) > 0xF;
@ -161,72 +161,80 @@ namespace BizHawk.Emulation.CPUs.Z80
} }
} }
} }
} }
} }
private bool[,] TableHalfBorrow; private bool[,] TableHalfBorrow;
private void InitTableHalfBorrow() private void InitTableHalfBorrow()
{ {
TableHalfBorrow = new bool[256, 256]; TableHalfBorrow = new bool[256, 256];
for (int i = 0; i < 256; i++) for (int i = 0; i < 256; i++)
{ {
for (int j = 0; j < 256; j++) for (int j = 0; j < 256; j++)
{ {
TableHalfBorrow[i, j] = ((i & 0xF) - (j & 0xF)) < 0; TableHalfBorrow[i, j] = ((i & 0xF) - (j & 0xF)) < 0;
} }
} }
} }
private bool[,] TableHalfCarry; private bool[,] TableHalfCarry;
private void InitTableHalfCarry() private void InitTableHalfCarry()
{ {
TableHalfCarry = new bool[256, 256]; TableHalfCarry = new bool[256, 256];
for (int i = 0; i < 256; i++) for (int i = 0; i < 256; i++)
{ {
for (int j = 0; j < 256; j++) for (int j = 0; j < 256; j++)
{ {
TableHalfCarry[i, j] = ((i & 0xF) + (j & 0xF)) > 0xF; TableHalfCarry[i, j] = ((i & 0xF) + (j & 0xF)) > 0xF;
} }
} }
} }
private ushort[, ,] TableRotShift; private ushort[, ,] TableRotShift;
private void InitTableRotShift() private void InitTableRotShift()
{ {
TableRotShift = new ushort[2, 8, 65536]; // All, operation, AF TableRotShift = new ushort[2, 8, 65536]; // All, operation, AF
for (int all = 0; all < 2; all++) for (int all = 0; all < 2; all++)
{ {
for (int y = 0; y < 8; ++y) for (int y = 0; y < 8; ++y)
{ {
for (int af = 0; af < 65536; af++) for (int af = 0; af < 65536; af++)
{ {
byte Old = (byte)(af >> 8); byte Old = (byte)(af >> 8);
bool OldCarry = (af & 0x01) != 0; bool OldCarry = (af & 0x01) != 0;
ushort newAf = (ushort)(af & ~(0x13)); // Clear HALF-CARRY, SUBTRACT and CARRY flags ushort newAf = (ushort)(af & ~(0x13)); // Clear HALF-CARRY, SUBTRACT and CARRY flags
byte New = Old; byte New = Old;
if ((y & 1) == 0) if ((y & 1) == 0)
{ {
if ((Old & 0x80) != 0) ++newAf; if ((Old & 0x80) != 0) ++newAf;
New <<= 1; New <<= 1;
if ((y & 0x04) == 0) { if ((y & 0x04) == 0)
{
if (((y & 0x02) == 0) ? ((newAf & 0x01) != 0) : OldCarry) New |= 0x01; if (((y & 0x02) == 0) ? ((newAf & 0x01) != 0) : OldCarry) New |= 0x01;
} else { }
else
{
if ((y & 0x02) != 0) New |= 0x01; if ((y & 0x02) != 0) New |= 0x01;
} }
} else { }
else
{
if ((Old & 0x01) != 0) ++newAf; if ((Old & 0x01) != 0) ++newAf;
New >>= 1; New >>= 1;
if ((y & 0x04) == 0) { if ((y & 0x04) == 0)
{
if (((y & 0x02) == 0) ? ((newAf & 0x01) != 0) : OldCarry) New |= 0x80; if (((y & 0x02) == 0) ? ((newAf & 0x01) != 0) : OldCarry) New |= 0x80;
} else { }
else
{
if ((y & 0x02) == 0) New |= (byte)(Old & 0x80); if ((y & 0x02) == 0) New |= (byte)(Old & 0x80);
} }
} }
@ -234,8 +242,8 @@ namespace BizHawk.Emulation.CPUs.Z80
newAf &= 0xFF; newAf &= 0xFF;
newAf |= (ushort)(New * 256); newAf |= (ushort)(New * 256);
if (all == 1) if (all == 1)
{ {
newAf &= unchecked((ushort)~0xC4); // Clear S, Z, P newAf &= unchecked((ushort)~0xC4); // Clear S, Z, P
if (New > 127) newAf |= 0x80; if (New > 127) newAf |= 0x80;
if (New == 0) newAf |= 0x40; if (New == 0) newAf |= 0x40;
@ -249,11 +257,11 @@ namespace BizHawk.Emulation.CPUs.Z80
} }
private ushort[] TableNeg; private ushort[] TableNeg;
private void InitTableNeg() private void InitTableNeg()
{ {
TableNeg = new ushort[65536]; TableNeg = new ushort[65536];
for (int af = 0; af < 65536; af++) for (int af = 0; af < 65536; af++)
{ {
ushort raf = 0; ushort raf = 0;
byte b = (byte)(af >> 8); byte b = (byte)(af >> 8);
byte a = (byte)-b; byte a = (byte)-b;
@ -264,19 +272,21 @@ namespace BizHawk.Emulation.CPUs.Z80
} }
private ushort[] TableDaa; private ushort[] TableDaa;
private void InitTableDaa() private void InitTableDaa()
{ {
TableDaa = new ushort[65536]; TableDaa = new ushort[65536];
for (int af = 0; af < 65536; ++af) for (int af = 0; af < 65536; ++af)
{ {
byte a = (byte)(af >> 8); byte a = (byte)(af >> 8);
byte tmp = a; byte tmp = a;
if (IsN(af)) if (IsN(af))
{ {
if (IsH(af) || ((a & 0x0F) > 0x09)) tmp -= 0x06; if (IsH(af) || ((a & 0x0F) > 0x09)) tmp -= 0x06;
if (IsC(af) || a > 0x99) tmp -= 0x60; if (IsC(af) || a > 0x99) tmp -= 0x60;
} else { }
else
{
if (IsH(af) || ((a & 0x0F) > 0x09)) tmp += 0x06; if (IsH(af) || ((a & 0x0F) > 0x09)) tmp += 0x06;
if (IsC(af) || a > 0x99) tmp += 0x60; if (IsC(af) || a > 0x99) tmp += 0x60;
} }
@ -285,8 +295,8 @@ namespace BizHawk.Emulation.CPUs.Z80
} }
} }
private byte FlagByte(bool C, bool N, bool P, bool X, bool H, bool Y, bool Z, bool S) private byte FlagByte(bool C, bool N, bool P, bool X, bool H, bool Y, bool Z, bool S)
{ {
return (byte)( return (byte)(
(C ? 0x01 : 0) + (C ? 0x01 : 0) +
(N ? 0x02 : 0) + (N ? 0x02 : 0) +
@ -299,13 +309,13 @@ namespace BizHawk.Emulation.CPUs.Z80
); );
} }
private bool UndocumentedX(int value) private bool UndocumentedX(int value)
{ {
return (value & 0x08) != 0; return (value & 0x08) != 0;
} }
private bool UndocumentedY(int value) private bool UndocumentedY(int value)
{ {
return (value & 0x20) != 0; return (value & 0x20) != 0;
} }

View File

@ -5,18 +5,18 @@ using System.IO;
// This Z80 emulator is a modified version of Ben Ryves 'Brazil' emulator. // This Z80 emulator is a modified version of Ben Ryves 'Brazil' emulator.
// It is MIT licensed. // It is MIT licensed.
namespace BizHawk.Emulation.CPUs.Z80 namespace BizHawk.Emulation.Common.Components.Z80
{ {
/// <summary> /// <summary>
/// ZiLOG Z80A CPU Emulator /// ZiLOG Z80A CPU Emulator
/// </summary> /// </summary>
public sealed partial class Z80A public sealed partial class Z80A
{ {
/// <summary> /// <summary>
/// Creates an instance of the <see cref="Z80A"/> emulator class. /// Creates an instance of the <see cref="Z80A"/> emulator class.
/// </summary> /// </summary>
public Z80A() public Z80A()
{ {
InitialiseTables(); InitialiseTables();
Reset(); Reset();
} }
@ -24,8 +24,8 @@ namespace BizHawk.Emulation.CPUs.Z80
/// <summary> /// <summary>
/// Reset the Z80 to its initial state /// Reset the Z80 to its initial state
/// </summary> /// </summary>
public void Reset() public void Reset()
{ {
ResetRegisters(); ResetRegisters();
ResetInterrupts(); ResetInterrupts();
PendingCycles = 0; PendingCycles = 0;
@ -33,178 +33,178 @@ namespace BizHawk.Emulation.CPUs.Z80
TotalExecutedCycles = 0; TotalExecutedCycles = 0;
} }
/// <summary> /// <summary>
/// Reset the Z80 to its initial state, but don't modify cycle counters. For use where Z80 may be reset /// Reset the Z80 to its initial state, but don't modify cycle counters. For use where Z80 may be reset
/// </summary> /// </summary>
public void SoftReset() public void SoftReset()
{ {
ResetRegisters(); ResetRegisters();
ResetInterrupts(); ResetInterrupts();
} }
// Memory Access // Memory Access
public Func<ushort, byte> ReadMemory; public Func<ushort, byte> ReadMemory;
public Action<ushort, byte> WriteMemory; public Action<ushort, byte> WriteMemory;
// Utility function, not used by core // Utility function, not used by core
public ushort ReadWord(ushort addr) public ushort ReadWord(ushort addr)
{ {
ushort value = ReadMemory(addr++); ushort value = ReadMemory(addr++);
value |= (ushort) (ReadMemory(addr) << 8); value |= (ushort)(ReadMemory(addr) << 8);
return value; return value;
} }
// Hardware I/O Port Access // Hardware I/O Port Access
public Func<ushort, byte> ReadHardware; public Func<ushort, byte> ReadHardware;
public Action<ushort, byte> WriteHardware; public Action<ushort, byte> WriteHardware;
// State Save/Load // State Save/Load
public void SaveStateText(TextWriter writer) public void SaveStateText(TextWriter writer)
{ {
writer.WriteLine("[Z80]"); writer.WriteLine("[Z80]");
writer.WriteLine("AF {0:X4}", RegAF.Word); writer.WriteLine("AF {0:X4}", RegAF.Word);
writer.WriteLine("BC {0:X4}", RegBC.Word); writer.WriteLine("BC {0:X4}", RegBC.Word);
writer.WriteLine("DE {0:X4}", RegDE.Word); writer.WriteLine("DE {0:X4}", RegDE.Word);
writer.WriteLine("HL {0:X4}", RegHL.Word); writer.WriteLine("HL {0:X4}", RegHL.Word);
writer.WriteLine("ShadowAF {0:X4}", RegAltAF.Word); writer.WriteLine("ShadowAF {0:X4}", RegAltAF.Word);
writer.WriteLine("ShadowBC {0:X4}", RegAltBC.Word); writer.WriteLine("ShadowBC {0:X4}", RegAltBC.Word);
writer.WriteLine("ShadowDE {0:X4}", RegAltDE.Word); writer.WriteLine("ShadowDE {0:X4}", RegAltDE.Word);
writer.WriteLine("ShadowHL {0:X4}", RegAltHL.Word); writer.WriteLine("ShadowHL {0:X4}", RegAltHL.Word);
writer.WriteLine("I {0:X2}", RegI); writer.WriteLine("I {0:X2}", RegI);
writer.WriteLine("R {0:X2}", RegR); writer.WriteLine("R {0:X2}", RegR);
writer.WriteLine("IX {0:X4}", RegIX.Word); writer.WriteLine("IX {0:X4}", RegIX.Word);
writer.WriteLine("IY {0:X4}", RegIY.Word); writer.WriteLine("IY {0:X4}", RegIY.Word);
writer.WriteLine("SP {0:X4}", RegSP.Word); writer.WriteLine("SP {0:X4}", RegSP.Word);
writer.WriteLine("PC {0:X4}", RegPC.Word); writer.WriteLine("PC {0:X4}", RegPC.Word);
writer.WriteLine("IRQ {0}", interrupt); writer.WriteLine("IRQ {0}", interrupt);
writer.WriteLine("NMI {0}", nonMaskableInterrupt); writer.WriteLine("NMI {0}", nonMaskableInterrupt);
writer.WriteLine("NMIPending {0}", nonMaskableInterruptPending); writer.WriteLine("NMIPending {0}", nonMaskableInterruptPending);
writer.WriteLine("IM {0}", InterruptMode); writer.WriteLine("IM {0}", InterruptMode);
writer.WriteLine("IFF1 {0}", IFF1); writer.WriteLine("IFF1 {0}", IFF1);
writer.WriteLine("IFF2 {0}", IFF2); writer.WriteLine("IFF2 {0}", IFF2);
writer.WriteLine("Halted {0}", Halted); writer.WriteLine("Halted {0}", Halted);
writer.WriteLine("ExecutedCycles {0}", TotalExecutedCycles); writer.WriteLine("ExecutedCycles {0}", TotalExecutedCycles);
writer.WriteLine("PendingCycles {0}", PendingCycles); writer.WriteLine("PendingCycles {0}", PendingCycles);
writer.WriteLine("[/Z80]"); writer.WriteLine("[/Z80]");
writer.WriteLine(); writer.WriteLine();
} }
public void LoadStateText(TextReader reader) public void LoadStateText(TextReader reader)
{ {
while (true) while (true)
{ {
string[] args = reader.ReadLine().Split(' '); string[] args = reader.ReadLine().Split(' ');
if (args[0].Trim() == "") continue; if (args[0].Trim() == "") continue;
if (args[0] == "[/Z80]") break; if (args[0] == "[/Z80]") break;
if (args[0] == "AF") if (args[0] == "AF")
RegAF.Word = ushort.Parse(args[1], NumberStyles.HexNumber); RegAF.Word = ushort.Parse(args[1], NumberStyles.HexNumber);
else if (args[0] == "BC") else if (args[0] == "BC")
RegBC.Word = ushort.Parse(args[1], NumberStyles.HexNumber); RegBC.Word = ushort.Parse(args[1], NumberStyles.HexNumber);
else if (args[0] == "DE") else if (args[0] == "DE")
RegDE.Word = ushort.Parse(args[1], NumberStyles.HexNumber); RegDE.Word = ushort.Parse(args[1], NumberStyles.HexNumber);
else if (args[0] == "HL") else if (args[0] == "HL")
RegHL.Word = ushort.Parse(args[1], NumberStyles.HexNumber); RegHL.Word = ushort.Parse(args[1], NumberStyles.HexNumber);
else if (args[0] == "ShadowAF") else if (args[0] == "ShadowAF")
RegAltAF.Word = ushort.Parse(args[1], NumberStyles.HexNumber); RegAltAF.Word = ushort.Parse(args[1], NumberStyles.HexNumber);
else if (args[0] == "ShadowBC") else if (args[0] == "ShadowBC")
RegAltBC.Word = ushort.Parse(args[1], NumberStyles.HexNumber); RegAltBC.Word = ushort.Parse(args[1], NumberStyles.HexNumber);
else if (args[0] == "ShadowDE") else if (args[0] == "ShadowDE")
RegAltDE.Word = ushort.Parse(args[1], NumberStyles.HexNumber); RegAltDE.Word = ushort.Parse(args[1], NumberStyles.HexNumber);
else if (args[0] == "ShadowHL") else if (args[0] == "ShadowHL")
RegAltHL.Word = ushort.Parse(args[1], NumberStyles.HexNumber); RegAltHL.Word = ushort.Parse(args[1], NumberStyles.HexNumber);
else if (args[0] == "I") else if (args[0] == "I")
RegI = byte.Parse(args[1], NumberStyles.HexNumber); RegI = byte.Parse(args[1], NumberStyles.HexNumber);
else if (args[0] == "R") else if (args[0] == "R")
RegR = byte.Parse(args[1], NumberStyles.HexNumber); RegR = byte.Parse(args[1], NumberStyles.HexNumber);
else if (args[0] == "IX") else if (args[0] == "IX")
RegIX.Word = ushort.Parse(args[1], NumberStyles.HexNumber); RegIX.Word = ushort.Parse(args[1], NumberStyles.HexNumber);
else if (args[0] == "IY") else if (args[0] == "IY")
RegIY.Word = ushort.Parse(args[1], NumberStyles.HexNumber); RegIY.Word = ushort.Parse(args[1], NumberStyles.HexNumber);
else if (args[0] == "SP") else if (args[0] == "SP")
RegSP.Word = ushort.Parse(args[1], NumberStyles.HexNumber); RegSP.Word = ushort.Parse(args[1], NumberStyles.HexNumber);
else if (args[0] == "PC") else if (args[0] == "PC")
RegPC.Word = ushort.Parse(args[1], NumberStyles.HexNumber); RegPC.Word = ushort.Parse(args[1], NumberStyles.HexNumber);
else if (args[0] == "IRQ") else if (args[0] == "IRQ")
interrupt = bool.Parse(args[1]); interrupt = bool.Parse(args[1]);
else if (args[0] == "NMI") else if (args[0] == "NMI")
nonMaskableInterrupt = bool.Parse(args[1]); nonMaskableInterrupt = bool.Parse(args[1]);
else if (args[0] == "NMIPending") else if (args[0] == "NMIPending")
nonMaskableInterruptPending = bool.Parse(args[1]); nonMaskableInterruptPending = bool.Parse(args[1]);
else if (args[0] == "IM") else if (args[0] == "IM")
InterruptMode = int.Parse(args[1]); InterruptMode = int.Parse(args[1]);
else if (args[0] == "IFF1") else if (args[0] == "IFF1")
IFF1 = bool.Parse(args[1]); IFF1 = bool.Parse(args[1]);
else if (args[0] == "IFF2") else if (args[0] == "IFF2")
IFF2 = bool.Parse(args[1]); IFF2 = bool.Parse(args[1]);
else if (args[0] == "Halted") else if (args[0] == "Halted")
Halted = bool.Parse(args[1]); Halted = bool.Parse(args[1]);
else if (args[0] == "ExecutedCycles") else if (args[0] == "ExecutedCycles")
TotalExecutedCycles = int.Parse(args[1]); TotalExecutedCycles = int.Parse(args[1]);
else if (args[0] == "PendingCycles") else if (args[0] == "PendingCycles")
PendingCycles = int.Parse(args[1]); PendingCycles = int.Parse(args[1]);
else else
Console.WriteLine("Skipping unrecognized identifier " + args[0]); Console.WriteLine("Skipping unrecognized identifier " + args[0]);
} }
} }
public void SaveStateBinary(BinaryWriter writer) public void SaveStateBinary(BinaryWriter writer)
{ {
writer.Write(RegAF.Word); writer.Write(RegAF.Word);
writer.Write(RegBC.Word); writer.Write(RegBC.Word);
writer.Write(RegDE.Word); writer.Write(RegDE.Word);
writer.Write(RegHL.Word); writer.Write(RegHL.Word);
writer.Write(RegAltAF.Word); writer.Write(RegAltAF.Word);
writer.Write(RegAltBC.Word); writer.Write(RegAltBC.Word);
writer.Write(RegAltDE.Word); writer.Write(RegAltDE.Word);
writer.Write(RegAltHL.Word); writer.Write(RegAltHL.Word);
writer.Write(RegAltAF.Word); writer.Write(RegAltAF.Word);
writer.Write(RegI); writer.Write(RegI);
writer.Write(RegR); writer.Write(RegR);
writer.Write(RegIX.Word); writer.Write(RegIX.Word);
writer.Write(RegIY.Word); writer.Write(RegIY.Word);
writer.Write(RegSP.Word); writer.Write(RegSP.Word);
writer.Write(RegPC.Word); writer.Write(RegPC.Word);
writer.Write(interrupt); writer.Write(interrupt);
writer.Write(nonMaskableInterrupt); writer.Write(nonMaskableInterrupt);
writer.Write(nonMaskableInterruptPending); writer.Write(nonMaskableInterruptPending);
writer.Write(InterruptMode); writer.Write(InterruptMode);
writer.Write(IFF1); writer.Write(IFF1);
writer.Write(IFF2); writer.Write(IFF2);
writer.Write(Halted); writer.Write(Halted);
writer.Write(TotalExecutedCycles); writer.Write(TotalExecutedCycles);
writer.Write(PendingCycles); writer.Write(PendingCycles);
} }
public void LoadStateBinary(BinaryReader reader) public void LoadStateBinary(BinaryReader reader)
{ {
RegAF.Word = reader.ReadUInt16(); RegAF.Word = reader.ReadUInt16();
RegBC.Word = reader.ReadUInt16(); RegBC.Word = reader.ReadUInt16();
RegDE.Word = reader.ReadUInt16(); RegDE.Word = reader.ReadUInt16();
RegHL.Word = reader.ReadUInt16(); RegHL.Word = reader.ReadUInt16();
RegAltAF.Word = reader.ReadUInt16(); RegAltAF.Word = reader.ReadUInt16();
RegAltBC.Word = reader.ReadUInt16(); RegAltBC.Word = reader.ReadUInt16();
RegAltDE.Word = reader.ReadUInt16(); RegAltDE.Word = reader.ReadUInt16();
RegAltHL.Word = reader.ReadUInt16(); RegAltHL.Word = reader.ReadUInt16();
RegAltAF.Word = reader.ReadUInt16(); RegAltAF.Word = reader.ReadUInt16();
RegI = reader.ReadByte(); RegI = reader.ReadByte();
RegR = reader.ReadByte(); RegR = reader.ReadByte();
RegIX.Word = reader.ReadUInt16(); RegIX.Word = reader.ReadUInt16();
RegIY.Word = reader.ReadUInt16(); RegIY.Word = reader.ReadUInt16();
RegSP.Word = reader.ReadUInt16(); RegSP.Word = reader.ReadUInt16();
RegPC.Word = reader.ReadUInt16(); RegPC.Word = reader.ReadUInt16();
interrupt = reader.ReadBoolean(); interrupt = reader.ReadBoolean();
nonMaskableInterrupt = reader.ReadBoolean(); nonMaskableInterrupt = reader.ReadBoolean();
nonMaskableInterruptPending = reader.ReadBoolean(); nonMaskableInterruptPending = reader.ReadBoolean();
InterruptMode = reader.ReadInt32(); InterruptMode = reader.ReadInt32();
IFF1 = reader.ReadBoolean(); IFF1 = reader.ReadBoolean();
IFF2 = reader.ReadBoolean(); IFF2 = reader.ReadBoolean();
Halted = reader.ReadBoolean(); Halted = reader.ReadBoolean();
TotalExecutedCycles = reader.ReadInt32(); TotalExecutedCycles = reader.ReadInt32();
PendingCycles = reader.ReadInt32(); PendingCycles = reader.ReadInt32();
} }
} }
} }

View File

@ -1,199 +1,199 @@
using System.Text; using System.Text;
namespace BizHawk.Emulation.CPUs.x86 namespace BizHawk.Emulation.Common.Components.x86
{ {
public class DisassemblyInfo public class DisassemblyInfo
{ {
public int Addr; public int Addr;
public string Mnemonic; public string Mnemonic;
public string Args; public string Args;
public string RawBytes; public string RawBytes;
public int Length; public int Length;
public override string ToString() public override string ToString()
{ {
return string.Format("{0:X6} {3,-12} {1,-8} {2}", Addr, Mnemonic, Args, RawBytes); return string.Format("{0:X6} {3,-12} {1,-8} {2}", Addr, Mnemonic, Args, RawBytes);
} }
} }
public partial class x86<CpuType> where CpuType : struct, x86CpuType public partial class x86<CpuType> where CpuType : struct, x86CpuType
{ {
private ushort ReadWord(int addr) private ushort ReadWord(int addr)
{ {
return (ushort)(ReadMemory(addr++) + (ReadMemory(addr) << 8)); return (ushort)(ReadMemory(addr++) + (ReadMemory(addr) << 8));
} }
private string DisassembleRM8(ref int addr) private string DisassembleRM8(ref int addr)
{ {
byte ModRM = ReadMemory(addr++); byte ModRM = ReadMemory(addr++);
int mod = (ModRM >> 6) & 3; int mod = (ModRM >> 6) & 3;
int r = (ModRM >> 3) & 7; int r = (ModRM >> 3) & 7;
int m = ModRM & 7; int m = ModRM & 7;
string reg; string reg;
switch (r) switch (r)
{ {
case 0: reg = "AL"; break; case 0: reg = "AL"; break;
case 1: reg = "CL"; break; case 1: reg = "CL"; break;
case 2: reg = "DL"; break; case 2: reg = "DL"; break;
case 3: reg = "BL"; break; case 3: reg = "BL"; break;
case 4: reg = "AH"; break; case 4: reg = "AH"; break;
case 5: reg = "CH"; break; case 5: reg = "CH"; break;
case 6: reg = "DH"; break; case 6: reg = "DH"; break;
case 7: reg = "BH"; break; case 7: reg = "BH"; break;
default: reg = "UNKNOWN"; break; default: reg = "UNKNOWN"; break;
} }
return reg+", "+DisassembleMod(ref addr, mod, m, 1); return reg + ", " + DisassembleMod(ref addr, mod, m, 1);
} }
private string DisassembleMod(ref int addr, int mod, int m, int size) private string DisassembleMod(ref int addr, int mod, int m, int size)
{ {
string ret; string ret;
switch (mod) switch (mod)
{ {
case 0: case 0:
switch (m) switch (m)
{ {
case 0: return "[BX+SI]"; case 0: return "[BX+SI]";
case 1: return "[BX+DI]"; case 1: return "[BX+DI]";
case 2: return "[BP+SI]"; case 2: return "[BP+SI]";
case 3: return "[BP+DI]"; case 3: return "[BP+DI]";
case 4: return "[SI]"; case 4: return "[SI]";
case 5: return "[DI]"; case 5: return "[DI]";
case 6: ret = string.Format("{0:X4}h", ReadWord(addr)); addr += 2; return ret; case 6: ret = string.Format("{0:X4}h", ReadWord(addr)); addr += 2; return ret;
case 7: return "[BX]"; case 7: return "[BX]";
} }
break; break;
case 1: case 1:
switch (m) switch (m)
{ {
case 0: return string.Format("[BX+SI] + {0:X2}h", ReadMemory(addr++)); 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 1: return string.Format("[BX+DI] + {0:X2}h", ReadMemory(addr++));
case 2: return string.Format("[BP+SI] + {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 3: return string.Format("[BP+DI] + {0:X2}h", ReadMemory(addr++));
case 4: return string.Format("[SI] + {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 5: return string.Format("[DI] + {0:X2}h", ReadMemory(addr++));
case 6: return string.Format("[BP] + {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++)); case 7: return string.Format("[BX] + {0:X2}h", ReadMemory(addr++));
} }
break; break;
case 2: case 2:
switch (m) switch (m)
{ {
case 0: ret = string.Format("[BX+SI] + {0:X4}h", ReadWord(addr)); addr += 2; return ret; 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 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 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 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 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 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 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; case 7: ret = string.Format("[BX] + {0:X4}h", ReadWord(addr)); addr += 2; return ret;
} }
break; break;
case 3: case 3:
switch (m) switch (m)
{ {
case 0: return size == 1 ? "AL" : "AX"; case 0: return size == 1 ? "AL" : "AX";
case 1: return size == 1 ? "CL" : "CX"; case 1: return size == 1 ? "CL" : "CX";
case 2: return size == 1 ? "DL" : "DX"; case 2: return size == 1 ? "DL" : "DX";
case 3: return size == 1 ? "BL" : "BX"; case 3: return size == 1 ? "BL" : "BX";
case 4: return size == 1 ? "AH" : "SP"; case 4: return size == 1 ? "AH" : "SP";
case 5: return size == 1 ? "CH" : "BP"; case 5: return size == 1 ? "CH" : "BP";
case 6: return size == 1 ? "DH" : "SI"; case 6: return size == 1 ? "DH" : "SI";
case 7: return size == 1 ? "BH" : "DI"; case 7: return size == 1 ? "BH" : "DI";
} }
break; break;
} }
return "Disassembly Error"; return "Disassembly Error";
} }
public DisassemblyInfo Disassemble(int addr) public DisassemblyInfo Disassemble(int addr)
{ {
var info = new DisassemblyInfo { Addr = addr }; var info = new DisassemblyInfo { Addr = addr };
byte op1 = ReadMemory(addr++); byte op1 = ReadMemory(addr++);
switch (op1) switch (op1)
{ {
case 0x02: // ADD r8,r/m8 case 0x02: // ADD r8,r/m8
info.Mnemonic = "ADD"; info.Mnemonic = "ADD";
info.Args = DisassembleRM8(ref addr); info.Args = DisassembleRM8(ref addr);
break; break;
case 0xB0: // MOV AL, immed case 0xB0: // MOV AL, immed
info.Mnemonic = "MOV"; info.Mnemonic = "MOV";
info.Args = string.Format("AL, {0:X2}h", ReadMemory(addr++)); info.Args = string.Format("AL, {0:X2}h", ReadMemory(addr++));
break; break;
case 0xB1: // MOV CL, immed case 0xB1: // MOV CL, immed
info.Mnemonic = "MOV"; info.Mnemonic = "MOV";
info.Args = string.Format("CL, {0:X2}h", ReadMemory(addr++)); info.Args = string.Format("CL, {0:X2}h", ReadMemory(addr++));
break; break;
case 0xB2: // MOV DL, immed case 0xB2: // MOV DL, immed
info.Mnemonic = "MOV"; info.Mnemonic = "MOV";
info.Args = string.Format("DL, {0:X2}h", ReadMemory(addr++)); info.Args = string.Format("DL, {0:X2}h", ReadMemory(addr++));
break; break;
case 0xB3: // MOV BL, immed case 0xB3: // MOV BL, immed
info.Mnemonic = "MOV"; info.Mnemonic = "MOV";
info.Args = string.Format("BL, {0:X2}h", ReadMemory(addr++)); info.Args = string.Format("BL, {0:X2}h", ReadMemory(addr++));
break; break;
case 0xB4: // MOV AH, immed case 0xB4: // MOV AH, immed
info.Mnemonic = "MOV"; info.Mnemonic = "MOV";
info.Args = string.Format("AH, {0:X2}h", ReadMemory(addr++)); info.Args = string.Format("AH, {0:X2}h", ReadMemory(addr++));
break; break;
case 0xB5: // MOV CH, immed case 0xB5: // MOV CH, immed
info.Mnemonic = "MOV"; info.Mnemonic = "MOV";
info.Args = string.Format("CH, {0:X2}h", ReadMemory(addr++)); info.Args = string.Format("CH, {0:X2}h", ReadMemory(addr++));
break; break;
case 0xB6: // MOV DH, immed case 0xB6: // MOV DH, immed
info.Mnemonic = "MOV"; info.Mnemonic = "MOV";
info.Args = string.Format("DH, {0:X2}h", ReadMemory(addr++)); info.Args = string.Format("DH, {0:X2}h", ReadMemory(addr++));
break; break;
case 0xB7: // MOV BH, immed case 0xB7: // MOV BH, immed
info.Mnemonic = "MOV"; info.Mnemonic = "MOV";
info.Args = string.Format("BH, {0:X2}h", ReadMemory(addr++)); info.Args = string.Format("BH, {0:X2}h", ReadMemory(addr++));
break; break;
case 0xB8: // MOV AX, immed case 0xB8: // MOV AX, immed
info.Mnemonic = "MOV"; info.Mnemonic = "MOV";
info.Args = string.Format("AX, {0:X4}h", ReadWord(addr)); addr += 2; info.Args = string.Format("AX, {0:X4}h", ReadWord(addr)); addr += 2;
break; break;
case 0xB9: // MOV CX, immed case 0xB9: // MOV CX, immed
info.Mnemonic = "MOV"; info.Mnemonic = "MOV";
info.Args = string.Format("CX, {0:X4}h", ReadWord(addr)); addr += 2; info.Args = string.Format("CX, {0:X4}h", ReadWord(addr)); addr += 2;
break; break;
case 0xBA: // MOV DX, immed case 0xBA: // MOV DX, immed
info.Mnemonic = "MOV"; info.Mnemonic = "MOV";
info.Args = string.Format("DX, {0:X4}h", ReadWord(addr)); addr += 2; info.Args = string.Format("DX, {0:X4}h", ReadWord(addr)); addr += 2;
break; break;
case 0xBB: // MOV BX, immed case 0xBB: // MOV BX, immed
info.Mnemonic = "MOV"; info.Mnemonic = "MOV";
info.Args = string.Format("BX, {0:X4}h", ReadWord(addr)); addr += 2; info.Args = string.Format("BX, {0:X4}h", ReadWord(addr)); addr += 2;
break; break;
case 0xBC: // MOV SP, immed case 0xBC: // MOV SP, immed
info.Mnemonic = "MOV"; info.Mnemonic = "MOV";
info.Args = string.Format("SP, {0:X4}h", ReadWord(addr)); addr += 2; info.Args = string.Format("SP, {0:X4}h", ReadWord(addr)); addr += 2;
break; break;
case 0xBD: // MOV BP, immed case 0xBD: // MOV BP, immed
info.Mnemonic = "MOV"; info.Mnemonic = "MOV";
info.Args = string.Format("BP, {0:X4}h", ReadWord(addr)); addr += 2; info.Args = string.Format("BP, {0:X4}h", ReadWord(addr)); addr += 2;
break; break;
case 0xBE: // MOV SI, immed case 0xBE: // MOV SI, immed
info.Mnemonic = "MOV"; info.Mnemonic = "MOV";
info.Args = string.Format("SI, {0:X4}h", ReadWord(addr)); addr += 2; info.Args = string.Format("SI, {0:X4}h", ReadWord(addr)); addr += 2;
break; break;
case 0xBF: // MOV DI, immed case 0xBF: // MOV DI, immed
info.Mnemonic = "MOV"; info.Mnemonic = "MOV";
info.Args = string.Format("DI, {0:X4}h", ReadWord(addr)); addr += 2; info.Args = string.Format("DI, {0:X4}h", ReadWord(addr)); addr += 2;
break; break;
default: default:
info.Mnemonic = "DB"; info.Mnemonic = "DB";
info.Args = string.Format("{0:X2}h", op1); info.Args = string.Format("{0:X2}h", op1);
break; break;
} }
info.Length = addr - info.Addr; info.Length = addr - info.Addr;
var sb = new StringBuilder(); var sb = new StringBuilder();
for (int p = info.Addr; p < info.Addr + info.Length; p++) for (int p = info.Addr; p < info.Addr + info.Length; p++)
sb.AppendFormat("{0:X2}", ReadMemory(p)); sb.AppendFormat("{0:X2}", ReadMemory(p));
info.RawBytes = sb.ToString(); info.RawBytes = sb.ToString();
return info; return info;
} }
} }
} }

View File

@ -1,84 +1,84 @@
using System; using System;
namespace BizHawk.Emulation.CPUs.x86 namespace BizHawk.Emulation.Common.Components.x86
{ {
public partial class x86<CpuType> where CpuType: struct, x86CpuType public partial class x86<CpuType> where CpuType : struct, x86CpuType
{ {
public void Execute(int cycles) public void Execute(int cycles)
{ {
Console.WriteLine(Disassemble((CS << 4) + IP)); Console.WriteLine(Disassemble((CS << 4) + IP));
byte opcode1 = ReadMemory((CS << 4) + IP); byte opcode1 = ReadMemory((CS << 4) + IP);
IP++; IP++;
switch (opcode1) switch (opcode1)
{ {
case 0xB0: // MOV AL, imm case 0xB0: // MOV AL, imm
AL = ReadMemory((CS << 4) + IP++); AL = ReadMemory((CS << 4) + IP++);
PendingCycles -= timing_mov_ri8; PendingCycles -= timing_mov_ri8;
break; break;
case 0xB1: // MOV CL, immed case 0xB1: // MOV CL, immed
CL = ReadMemory((CS << 4) + IP++); CL = ReadMemory((CS << 4) + IP++);
PendingCycles -= timing_mov_ri8; PendingCycles -= timing_mov_ri8;
break; break;
case 0xB2: // MOV DL, immed case 0xB2: // MOV DL, immed
DL = ReadMemory((CS << 4) + IP++); DL = ReadMemory((CS << 4) + IP++);
PendingCycles -= timing_mov_ri8; PendingCycles -= timing_mov_ri8;
break; break;
case 0xB3: // MOV BL, immed case 0xB3: // MOV BL, immed
BL = ReadMemory((CS << 4) + IP++); BL = ReadMemory((CS << 4) + IP++);
PendingCycles -= timing_mov_ri8; PendingCycles -= timing_mov_ri8;
break; break;
case 0xB4: // MOV AH, immed case 0xB4: // MOV AH, immed
AH = ReadMemory((CS << 4) + IP++); AH = ReadMemory((CS << 4) + IP++);
PendingCycles -= timing_mov_ri8; PendingCycles -= timing_mov_ri8;
break; break;
case 0xB5: // MOV CH, immed case 0xB5: // MOV CH, immed
CH = ReadMemory((CS << 4) + IP++); CH = ReadMemory((CS << 4) + IP++);
PendingCycles -= timing_mov_ri8; PendingCycles -= timing_mov_ri8;
break; break;
case 0xB6: // MOV DH, immed case 0xB6: // MOV DH, immed
DH = ReadMemory((CS << 4) + IP++); DH = ReadMemory((CS << 4) + IP++);
PendingCycles -= timing_mov_ri8; PendingCycles -= timing_mov_ri8;
break; break;
case 0xB7: // MOV BH, immed case 0xB7: // MOV BH, immed
BH = ReadMemory((CS << 4) + IP++); BH = ReadMemory((CS << 4) + IP++);
PendingCycles -= timing_mov_ri8; PendingCycles -= timing_mov_ri8;
break; break;
case 0xB8: // MOV AX, immed case 0xB8: // MOV AX, immed
AX = (ushort)(ReadMemory((CS << 4) + IP++) + (ReadMemory((CS << 4) + IP++) << 8)); AX = (ushort)(ReadMemory((CS << 4) + IP++) + (ReadMemory((CS << 4) + IP++) << 8));
PendingCycles -= timing_mov_ri16; PendingCycles -= timing_mov_ri16;
break; break;
case 0xB9: // MOV CX, imm case 0xB9: // MOV CX, imm
CX = (ushort)(ReadMemory((CS << 4) + IP++) + (ReadMemory((CS << 4) + IP++) << 8)); CX = (ushort)(ReadMemory((CS << 4) + IP++) + (ReadMemory((CS << 4) + IP++) << 8));
PendingCycles -= timing_mov_ri16; PendingCycles -= timing_mov_ri16;
break; break;
case 0xBA: // MOV DX, immed case 0xBA: // MOV DX, immed
DX = (ushort)(ReadMemory((CS << 4) + IP++) + (ReadMemory((CS << 4) + IP++) << 8)); DX = (ushort)(ReadMemory((CS << 4) + IP++) + (ReadMemory((CS << 4) + IP++) << 8));
PendingCycles -= timing_mov_ri16; PendingCycles -= timing_mov_ri16;
break; break;
case 0xBB: // MOV BX, immed case 0xBB: // MOV BX, immed
BX = (ushort)(ReadMemory((CS << 4) + IP++) + (ReadMemory((CS << 4) + IP++) << 8)); BX = (ushort)(ReadMemory((CS << 4) + IP++) + (ReadMemory((CS << 4) + IP++) << 8));
PendingCycles -= timing_mov_ri16; PendingCycles -= timing_mov_ri16;
break; break;
case 0xBC: // MOV SP, immed case 0xBC: // MOV SP, immed
SP = (ushort)(ReadMemory((CS << 4) + IP++) + (ReadMemory((CS << 4) + IP++) << 8)); SP = (ushort)(ReadMemory((CS << 4) + IP++) + (ReadMemory((CS << 4) + IP++) << 8));
PendingCycles -= timing_mov_ri16; PendingCycles -= timing_mov_ri16;
break; break;
case 0xBD: // MOV BP, immed case 0xBD: // MOV BP, immed
BP = (ushort)(ReadMemory((CS << 4) + IP++) + (ReadMemory((CS << 4) + IP++) << 8)); BP = (ushort)(ReadMemory((CS << 4) + IP++) + (ReadMemory((CS << 4) + IP++) << 8));
PendingCycles -= timing_mov_ri16; PendingCycles -= timing_mov_ri16;
break; break;
case 0xBE: // MOV SI, immed case 0xBE: // MOV SI, immed
SI = (ushort)(ReadMemory((CS << 4) + IP++) + (ReadMemory((CS << 4) + IP++) << 8)); SI = (ushort)(ReadMemory((CS << 4) + IP++) + (ReadMemory((CS << 4) + IP++) << 8));
PendingCycles -= timing_mov_ri16; PendingCycles -= timing_mov_ri16;
break; break;
case 0xBF: // MOV DI, immed case 0xBF: // MOV DI, immed
DI = (ushort)(ReadMemory((CS << 4) + IP++) + (ReadMemory((CS << 4) + IP++) << 8)); DI = (ushort)(ReadMemory((CS << 4) + IP++) + (ReadMemory((CS << 4) + IP++) << 8));
PendingCycles -= timing_mov_ri16; PendingCycles -= timing_mov_ri16;
break; break;
default: default:
throw new NotImplementedException(); throw new NotImplementedException();
} }
} }
} }
} }

View File

@ -1,19 +1,19 @@
namespace BizHawk.Emulation.CPUs.x86 namespace BizHawk.Emulation.Common.Components.x86
{ {
public partial class x86<CpuType> where CpuType : struct, x86CpuType public partial class x86<CpuType> where CpuType : struct, x86CpuType
{ {
// TODO test if static on these is a performance boost // TODO test if static on these is a performance boost
// it would be appropriate if so because closed types have their own static variables // it would be appropriate if so because closed types have their own static variables
private int timing_mov_ri8; private int timing_mov_ri8;
private int timing_mov_ri16; private int timing_mov_ri16;
private void InitTiming() private void InitTiming()
{ {
if (typeof(CpuType) == typeof(Intel8086)) if (typeof(CpuType) == typeof(Intel8086))
{ {
timing_mov_ri8 = 4; timing_mov_ri8 = 4;
timing_mov_ri16 = 4; timing_mov_ri16 = 4;
} }
} }
} }
} }

View File

@ -1,100 +1,100 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace BizHawk.Emulation.CPUs.x86 namespace BizHawk.Emulation.Common.Components.x86
{ {
public interface x86CpuType { }; public interface x86CpuType { };
public struct Intel8086 : x86CpuType { }; public struct Intel8086 : x86CpuType { };
public sealed partial class x86<CpuType> where CpuType: struct, x86CpuType public sealed partial class x86<CpuType> where CpuType : struct, x86CpuType
{ {
// Machine State // Machine State
public Register16 RegAX; public Register16 RegAX;
public Register16 RegBX; public Register16 RegBX;
public Register16 RegCX; public Register16 RegCX;
public Register16 RegDX; public Register16 RegDX;
public ushort CS; public ushort CS;
public ushort DS; public ushort DS;
public ushort ES; public ushort ES;
public ushort SS; public ushort SS;
public ushort SI; public ushort SI;
public ushort DI; public ushort DI;
public ushort IP; public ushort IP;
public ushort SP; public ushort SP;
public ushort BP; public ushort BP;
public bool CF; public bool CF;
public bool PF; public bool PF;
public bool AF; public bool AF;
public bool ZF; public bool ZF;
public bool SF; public bool SF;
public bool TP; public bool TP;
public bool IF; public bool IF;
public bool DF; public bool DF;
public bool OF; public bool OF;
public ushort Flags public ushort Flags
{ {
get get
{ {
ushort value = 2; ushort value = 2;
if (CF) value |= 1; if (CF) value |= 1;
if (PF) value |= 4; if (PF) value |= 4;
if (AF) value |= 16; if (AF) value |= 16;
if (ZF) value |= 64; if (ZF) value |= 64;
if (SF) value |= 128; if (SF) value |= 128;
if (TP) value |= 256; if (TP) value |= 256;
if (IF) value |= 512; if (IF) value |= 512;
if (DF) value |= 1024; if (DF) value |= 1024;
if (OF) value |= 2048; if (OF) value |= 2048;
return value; return value;
} }
} }
public int PendingCycles; public int PendingCycles;
public int TotalExecutedCycles; public int TotalExecutedCycles;
// Memory Access // Memory Access
public Func<int, byte> ReadMemory; public Func<int, byte> ReadMemory;
public Action<int, byte> WriteMemory; public Action<int, byte> WriteMemory;
public x86() public x86()
{ {
InitTiming(); InitTiming();
} }
// We expect these properties to get inlined by the CLR -- at some point we should test this assumption // 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 AX { get { return RegAX.Word; } set { RegAX.Word = value; } }
public ushort BX { get { return RegBX.Word; } set { RegBX.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 CX { get { return RegCX.Word; } set { RegCX.Word = value; } }
public ushort DX { get { return RegDX.Word; } set { RegDX.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 AL { get { return RegAX.Low; } set { RegAX.Low = value; } }
public byte BL { get { return RegBX.Low; } set { RegBX.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 CL { get { return RegCX.Low; } set { RegCX.Low = value; } }
public byte DL { get { return RegDX.Low; } set { RegDX.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 AH { get { return RegAX.High; } set { RegAX.High = value; } }
public byte BH { get { return RegBX.High; } set { RegBX.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 CH { get { return RegCX.High; } set { RegCX.High = value; } }
public byte DH { get { return RegDX.High; } set { RegDX.High = value; } } public byte DH { get { return RegDX.High; } set { RegDX.High = value; } }
} }
[StructLayout(LayoutKind.Explicit)] [StructLayout(LayoutKind.Explicit)]
public struct Register16 public struct Register16
{ {
[FieldOffset(0)] [FieldOffset(0)]
public ushort Word; public ushort Word;
[FieldOffset(0)] [FieldOffset(0)]
public byte Low; public byte Low;
[FieldOffset(1)] [FieldOffset(1)]
public byte High; public byte High;
public override string ToString() public override string ToString()
{ {
return String.Format("{0:X4}", Word); return String.Format("{0:X4}", Word);
} }
} }
} }

View File

@ -5,7 +5,7 @@ using System.Collections.Generic;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Emulation.CPUs.Z80; using BizHawk.Emulation.Common.Components.Z80;
//http://www.ticalc.org/pub/text/calcinfo/ //http://www.ticalc.org/pub/text/calcinfo/

View File

@ -1,5 +1,5 @@
using System; using System;
using BizHawk.Emulation.CPUs.M6502; using BizHawk.Emulation.Common.Components.M6502;
#if false #if false

View File

@ -1,9 +1,10 @@
using BizHawk.Emulation.CPUs.M6502; using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using BizHawk.Emulation.Common.Components.M6502;
namespace BizHawk.Emulation.Cores.Computers.Commodore64.Experimental namespace BizHawk.Emulation.Cores.Computers.Commodore64.Experimental
{ {
sealed public partial class Cpu sealed public partial class Cpu

View File

@ -1,9 +1,9 @@
using BizHawk.Emulation.CPUs.M6502; using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Emulation.Common.Components.M6502;
namespace BizHawk.Emulation.Cores.Computers.Commodore64 namespace BizHawk.Emulation.Cores.Computers.Commodore64
{ {

View File

@ -1,7 +1,7 @@
using System; using System;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Emulation.CPUs.M6502; using BizHawk.Emulation.Common.Components.M6502;
namespace BizHawk.Emulation.Cores.Atari.Atari2600 namespace BizHawk.Emulation.Cores.Atari.Atari2600

View File

@ -4,7 +4,7 @@ using System.IO;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Emulation.CPUs.Z80; using BizHawk.Emulation.Common.Components.Z80;
using BizHawk.Emulation.Sound; using BizHawk.Emulation.Sound;
namespace BizHawk.Emulation.Cores.ColecoVision namespace BizHawk.Emulation.Cores.ColecoVision

View File

@ -4,7 +4,7 @@ using System.IO;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Emulation.CPUs.Z80; using BizHawk.Emulation.Common.Components.Z80;
namespace BizHawk.Emulation.Cores.ColecoVision namespace BizHawk.Emulation.Cores.ColecoVision
{ {

View File

@ -3,7 +3,7 @@ using System.IO;
using System.Collections.Generic; using System.Collections.Generic;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Emulation.CPUs.CP1610; using BizHawk.Emulation.Common.Components.CP1610;
namespace BizHawk.Emulation.Cores.Intellivision namespace BizHawk.Emulation.Cores.Intellivision
{ {

View File

@ -543,7 +543,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
s[10] & 0xff, s[10] & 0xff,
s[11] != 0 ? "skip" : "", s[11] != 0 ? "skip" : "",
s[12] & 0xff, 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)
)); ));
} }

View File

@ -4,7 +4,7 @@ using System.Runtime.CompilerServices;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Emulation.CPUs.M6502; using BizHawk.Emulation.Common.Components.M6502;
#pragma warning disable 162 #pragma warning disable 162

View File

@ -5,7 +5,7 @@ using System.IO;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Emulation.CPUs.H6280; using BizHawk.Emulation.Common.Components.H6280;
using BizHawk.Emulation.DiscSystem; using BizHawk.Emulation.DiscSystem;
using BizHawk.Emulation.Sound; using BizHawk.Emulation.Sound;

View File

@ -4,7 +4,7 @@ using System.IO;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Emulation.CPUs.H6280; using BizHawk.Emulation.Common.Components.H6280;
namespace BizHawk.Emulation.Cores.PCEngine namespace BizHawk.Emulation.Cores.PCEngine
{ {

View File

@ -3,7 +3,7 @@ using System.IO;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Emulation.CPUs.H6280; using BizHawk.Emulation.Common.Components.H6280;
namespace BizHawk.Emulation.Cores.PCEngine namespace BizHawk.Emulation.Cores.PCEngine
{ {

View File

@ -7,8 +7,8 @@ using System.Runtime.InteropServices;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Emulation.CPUs.M68000; using BizHawk.Emulation.Common.Components.M68000;
using BizHawk.Emulation.CPUs.Z80; using BizHawk.Emulation.Common.Components.Z80;
using BizHawk.Emulation.Sound; using BizHawk.Emulation.Sound;
using Native68000; using Native68000;

View File

@ -5,7 +5,7 @@ using System.IO;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Emulation.CPUs.Z80; using BizHawk.Emulation.Common.Components.Z80;
using BizHawk.Emulation.Sound; using BizHawk.Emulation.Sound;
/***************************************************** /*****************************************************

View File

@ -4,7 +4,7 @@ using System.IO;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Emulation.CPUs.Z80; using BizHawk.Emulation.Common.Components.Z80;
namespace BizHawk.Emulation.Cores.Sega.MasterSystem namespace BizHawk.Emulation.Cores.Sega.MasterSystem