Z80: Recast core to cycle accurate memory accesses and wait state timing

This commit is contained in:
alyosha-tas 2018-05-31 21:05:41 -04:00
parent 9a15cbf4d4
commit c0d6c02b2e
6 changed files with 438 additions and 473 deletions

View File

@ -20,13 +20,13 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
public int instr_pntr = 0;
public ushort instr_swap;
public ushort[] cur_instr;
public int opcode;
public byte opcode;
public bool NO_prefix, CB_prefix, IX_prefix, EXTD_prefix, IY_prefix, IXCB_prefix, IYCB_prefix;
public bool IXCB_prefetch, IYCB_prefetch; // value is fetched before opcode
public bool halted;
public ushort PF;
public void FetchInstruction(byte opcode)
public void FetchInstruction()
{
if (NO_prefix)
{
@ -1186,6 +1186,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
IXCB_prefetch = false;
PF = opcode;
Regs[ALU] = PF;
Regs[W] = Regs[Ixh];
Regs[Z] = Regs[Ixl];
PREFETCH_(Ixl, Ixh);
return;
}
@ -1195,6 +1197,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
IYCB_prefetch = false;
PF = opcode;
Regs[ALU] = PF;
Regs[W] = Regs[Iyh];
Regs[Z] = Regs[Iyl];
PREFETCH_(Iyl, Iyh);
return;
}

View File

@ -33,16 +33,16 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
private void NMI_()
{
cur_instr = new ushort[]
{IDLE,
DEC16, SPl, SPh,
{DEC16, SPl, SPh,
WAIT,
WR, SPl, SPh, PCh,
IDLE,
DEC16, SPl, SPh,
WAIT,
WR, SPl, SPh, PCl,
IDLE,
ASGN, PCl, 0x66,
ASGN, PCh, 0,
IDLE,
WAIT,
OP_F,
OP };
}
@ -55,11 +55,11 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
{
cur_instr = new ushort[]
{IDLE,
IDLE,
WAIT,
RD, ALU, PCl, PCh,
IDLE,
INC16, PCl, PCh,
IDLE,
WAIT,
OP_F,
OP };
}
@ -68,17 +68,17 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
{
cur_instr = new ushort[]
{DEC16, SPl, SPh,
IDLE,
WAIT,
WR, SPl, SPh, PCh,
IDLE,
DEC16, SPl, SPh,
IDLE,
WAIT,
WR, SPl, SPh, PCl,
IDLE,
ASGN, PCl, 0x38,
IDLE,
ASGN, PCh, 0,
IDLE,
WAIT,
OP_F,
OP };
}
@ -87,23 +87,23 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
{
cur_instr = new ushort[]
{IDLE,
IDLE,
WAIT,
FTCH_DB,
TR, Z, DB,
TR, W, I,
IDLE,
TR16, Z, W, DB, I,
DEC16, SPl, SPh,
WAIT,
WR, SPl, SPh, PCh,
IDLE,
DEC16, SPl, SPh,
WR, SPl, SPh, PCl,
WAIT,
WR, SPl, SPh, PCl,
IDLE,
RD, PCl, Z, W,
INC16, Z, W,
WAIT,
RD_INC, PCl, Z, W,
IDLE,
RD, PCh, Z, W,
IDLE,
IDLE,
WAIT,
OP_F,
OP };
}

View File

@ -11,6 +11,13 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
Regs[DB] = Regs[dest];
}
public void Read_INC_Func(ushort dest, ushort src_l, ushort src_h)
{
Regs[dest] = ReadMemory((ushort)(Regs[src_l] | (Regs[src_h]) << 8));
Regs[DB] = Regs[dest];
INC16_Func(src_l, src_h);
}
public void I_Read_Func(ushort dest, ushort src_l, ushort src_h, ushort inc)
{
Regs[dest] = ReadMemory((ushort)((Regs[src_l] | (Regs[src_h] << 8)) + inc));
@ -23,6 +30,13 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
WriteMemory((ushort)(Regs[dest_l] | (Regs[dest_h] << 8)), (byte)Regs[src]);
}
public void Write_INC_Func(ushort dest_l, ushort dest_h, ushort src)
{
Regs[DB] = Regs[src];
WriteMemory((ushort)(Regs[dest_l] | (Regs[dest_h] << 8)), (byte)Regs[src]);
INC16_Func(dest_l, dest_h);
}
public void I_Write_Func(ushort dest_l, ushort dest_h, ushort inc, ushort src)
{
Regs[DB] = Regs[src];

View File

@ -10,10 +10,10 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
private void NOP_()
{
cur_instr = new ushort[]
{IDLE,
IDLE,
IDLE,
OP };
{ IDLE,
WAIT,
OP_F,
OP };
}
// NOTE: In a real Z80, this operation just flips a switch to choose between 2 registers
@ -22,8 +22,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
{
cur_instr = new ushort[]
{EXCH,
IDLE,
IDLE,
WAIT,
OP_F,
OP };
}
@ -31,8 +31,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
{
cur_instr = new ushort[]
{EXX,
IDLE,
IDLE,
WAIT,
OP_F,
OP };
}
@ -41,19 +41,19 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
{
cur_instr = new ushort[]
{EXCH_16, dest_l, dest_h, src_l, src_h,
IDLE,
IDLE,
WAIT,
OP_F,
OP };
}
private void INC_16(ushort src_l, ushort src_h)
{
cur_instr = new ushort[]
{IDLE,
{INC16, src_l, src_h,
IDLE,
IDLE,
INC16, src_l, src_h,
IDLE,
WAIT,
OP_F,
OP };
}
@ -61,11 +61,11 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
private void DEC_16(ushort src_l, ushort src_h)
{
cur_instr = new ushort[]
{IDLE,
IDLE,
DEC16, src_l, src_h,
{DEC16, src_l, src_h,
IDLE,
IDLE,
WAIT,
OP_F,
OP };
}
@ -74,16 +74,16 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
private void ADD_16(ushort dest_l, ushort dest_h, ushort src_l, ushort src_h)
{
cur_instr = new ushort[]
{IDLE,
{TR16, Z, W, dest_l, dest_h,
IDLE,
IDLE,
TR16, Z, W, dest_l, dest_h,
INC16, Z, W,
IDLE,
IDLE,
ADD16, dest_l, dest_h, src_l, src_h,
IDLE,
IDLE,
IDLE,
WAIT,
OP_F,
OP };
}
@ -91,8 +91,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
{
cur_instr = new ushort[]
{operation, dest, src,
IDLE,
IDLE,
WAIT,
OP_F,
OP };
}
@ -101,9 +101,9 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
{
cur_instr = new ushort[]
{operation, dest, src,
IDLE,
IDLE,
SET_FL_IR, dest,
WAIT,
OP_F,
OP };
}
@ -114,17 +114,17 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
{
cur_instr = new ushort[]
{IDLE,
ASGN, B, (ushort)((Regs[B] - 1) & 0xFF),
WAIT,
RD_INC, Z, PCl, PCh,
IDLE,
ASGN, B, (ushort)((Regs[B] - 1) & 0xFF),
IDLE,
RD, Z, PCl, PCh,
IDLE,
INC16, PCl, PCh,
IDLE,
ASGN, W, 0,
IDLE,
ADDS, PCl, PCh, Z, W,
TR16, Z, W, PCl, PCh,
IDLE,
WAIT,
OP_F,
OP };
}
else
@ -132,11 +132,11 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
cur_instr = new ushort[]
{IDLE,
ASGN, B, (ushort)((Regs[B] - 1) & 0xFF),
WAIT,
RD_INC, ALU, PCl, PCh,
IDLE,
RD, ALU, PCl, PCh,
IDLE,
INC16, PCl, PCh,
IDLE,
WAIT,
OP_F,
OP };
}
}
@ -156,27 +156,27 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
{
cur_instr = new ushort[]
{IDLE,
IDLE,
RD, Z, PCl, PCh,
INC16, PCl, PCh,
IDLE,
WAIT,
RD_INC, Z, PCl, PCh,
IDLE,
ASGN, W, 0,
IDLE,
ADDS, PCl, PCh, Z, W,
TR16, Z, W, PCl, PCh,
TR16, Z, W, PCl, PCh,
IDLE,
IDLE,
WAIT,
OP_F,
OP };
}
else
{
cur_instr = new ushort[]
{IDLE,
WAIT,
RD_INC, ALU, PCl, PCh,
IDLE,
IDLE,
RD, ALU, PCl, PCh,
IDLE,
INC16, PCl, PCh,
WAIT,
OP_F,
OP };
}
}
@ -187,28 +187,28 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
{
cur_instr = new ushort[]
{IDLE,
WAIT,
RD_INC, Z, PCl, PCh,
IDLE,
RD, Z, PCl, PCh,
INC16, PCl, PCh,
RD, W, PCl, PCh,
IDLE,
INC16, PCl, PCh,
WAIT,
RD_INC, W, PCl, PCh,
TR16, PCl, PCh, Z, W,
IDLE,
WAIT,
OP_F,
OP };
}
else
{
cur_instr = new ushort[]
{IDLE,
WAIT,
RD_INC, Z, PCl, PCh,
IDLE,
RD, Z, PCl, PCh,
INC16, PCl, PCh,
IDLE,
RD, W, PCl, PCh,
INC16, PCl, PCh,
IDLE,
WAIT,
RD_INC, W, PCl, PCh,
IDLE,
WAIT,
OP_F,
OP };
}
}
@ -217,14 +217,14 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
{
cur_instr = new ushort[]
{IDLE,
WAIT,
RD_INC, Z, SPl, SPh,
IDLE,
RD, Z, SPl, SPh,
INC16, SPl, SPh,
IDLE,
IDLE,
RD, W, SPl, SPh,
INC16, SPl, SPh,
TR16, PCl, PCh, Z, W,
WAIT,
RD_INC, W, SPl, SPh,
TR16, PCl, PCh, Z, W,
WAIT,
OP_F,
OP };
}
@ -232,14 +232,14 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
{
cur_instr = new ushort[]
{IDLE,
WAIT,
RD_INC, Z, SPl, SPh,
IDLE,
RD, Z, SPl, SPh,
INC16, SPl, SPh,
IDLE,
IDLE,
RD, W, SPl, SPh,
INC16, SPl, SPh,
WAIT,
RD_INC, W, SPl, SPh,
TR16, PCl, PCh, Z, W,
WAIT,
OP_F,
OP };
}
@ -247,14 +247,14 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
{
cur_instr = new ushort[]
{IDLE,
IDLE,
RD, Z, SPl, SPh,
INC16, SPl, SPh,
IDLE,
RD, W, SPl, SPh,
INC16, SPl, SPh,
WAIT,
RD_INC, Z, SPl, SPh,
EI_RETN,
WAIT,
RD_INC, W, SPl, SPh,
TR16, PCl, PCh, Z, W,
WAIT,
OP_F,
OP };
}
@ -266,14 +266,14 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
cur_instr = new ushort[]
{IDLE,
IDLE,
RD, Z, SPl, SPh,
INC16, SPl, SPh,
WAIT,
RD_INC, Z, SPl, SPh,
IDLE,
IDLE,
RD, W, SPl, SPh,
INC16, SPl, SPh,
IDLE,
WAIT,
RD_INC, W, SPl, SPh,
TR16, PCl, PCh, Z, W,
WAIT,
OP_F,
OP };
}
else
@ -281,8 +281,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
cur_instr = new ushort[]
{IDLE,
IDLE,
IDLE,
IDLE,
WAIT,
OP_F,
OP };
}
}
@ -293,35 +293,35 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
{
cur_instr = new ushort[]
{IDLE,
WAIT,
RD_INC, Z, PCl, PCh,
IDLE,
RD, Z, PCl, PCh,
INC16, PCl, PCh,
IDLE,
RD, W, PCl, PCh,
INC16, PCl, PCh,
IDLE,
WAIT,
RD_INC, W, PCl, PCh,
DEC16, SPl, SPh,
IDLE,
WR, SPl, SPh, PCh,
WAIT,
WR, SPl, SPh, PCh,
DEC16, SPl, SPh,
WAIT,
WR, SPl, SPh, PCl,
IDLE,
TR, PCl, Z,
TR, PCh, W,
TR16, PCl, PCh, Z, W,
WAIT,
OP_F,
OP };
}
else
{
cur_instr = new ushort[]
{IDLE,
WAIT,
RD_INC, Z, PCl, PCh,
IDLE,
RD, Z, PCl, PCh,
WAIT,
RD_INC, W, PCl, PCh,
IDLE,
INC16, PCl, PCh,
IDLE,
RD, W, PCl, PCh,
IDLE,
INC16, PCl, PCh,
WAIT,
OP_F,
OP };
}
}
@ -330,8 +330,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
{
cur_instr = new ushort[]
{operation, src,
IDLE,
IDLE,
WAIT,
OP_F,
OP };
}
@ -339,8 +339,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
{
cur_instr = new ushort[]
{operation, bit, src,
IDLE,
IDLE,
WAIT,
OP_F,
OP };
}
@ -348,15 +348,15 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
{
cur_instr = new ushort[]
{IDLE,
IDLE,
DEC16, SPl, SPh,
IDLE,
WAIT,
WR, SPl, SPh, src_h,
IDLE,
DEC16, SPl, SPh,
IDLE,
WAIT,
WR, SPl, SPh, src_l,
IDLE,
WAIT,
OP_F,
OP };
}
@ -365,14 +365,14 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
{
cur_instr = new ushort[]
{IDLE,
RD, src_l, SPl, SPh,
WAIT,
RD_INC, src_l, SPl, SPh,
IDLE,
INC16, SPl, SPh,
IDLE,
RD, src_h, SPl, SPh,
IDLE,
INC16, SPl, SPh,
WAIT,
RD_INC, src_h, SPl, SPh,
IDLE,
WAIT,
OP_F,
OP };
}
@ -380,15 +380,15 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
{
cur_instr = new ushort[]
{IDLE,
IDLE,
DEC16, SPl, SPh,
WAIT,
WR, SPl, SPh, PCh,
DEC16, SPl, SPh,
WAIT,
WR, SPl, SPh, PCl,
IDLE,
ASGN, Z, n,
ASGN, W, 0,
TR16, PCl, PCh, Z, W,
RST, n,
WAIT,
OP_F,
OP };
}
@ -396,17 +396,17 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
{
cur_instr = new ushort[]
{IDLE,
IDLE,
IDLE,
WAIT,
OP_F,
PREFIX, src};
}
private void PREFETCH_(ushort src_l, ushort src_h)
{
cur_instr = new ushort[]
{TR16, Z, W, src_l, src_h,
ADDS, Z, W, ALU, ZERO,
IDLE,
{ADDS, Z, W, ALU, ZERO,
WAIT,
OP_F,
PREFIX, IXYprefetch };
}
@ -414,8 +414,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
{
cur_instr = new ushort[]
{DI,
IDLE,
IDLE,
WAIT,
OP_F,
OP };
}
@ -423,17 +423,17 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
{
cur_instr = new ushort[]
{EI,
IDLE,
IDLE,
WAIT,
OP_F,
OP };
}
private void JP_16(ushort src_l, ushort src_h)
{
cur_instr = new ushort[]
{TR, PCl, src_l,
IDLE,
TR, PCh, src_h,
{TR16, PCl, PCh, src_l, src_h,
WAIT,
OP_F,
OP };
}
@ -442,9 +442,9 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
cur_instr = new ushort[]
{IDLE,
IDLE,
TR, SPl, src_l,
TR, SPh, src_h,
IDLE,
TR16, SPl, SPh, src_l, src_h,
WAIT,
OP_F,
OP };
}
@ -452,15 +452,15 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
{
cur_instr = new ushort[]
{IDLE,
RD, Z, PCl, PCh,
WAIT,
RD_INC, Z, PCl, PCh,
IDLE,
INC16, PCl, PCh,
TR, W, A,
OUT, Z, W, A,
IDLE,
INC16, Z, W,
IDLE,
IDLE,
WAIT,
OP_F,
OP};
}
@ -468,12 +468,12 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
{
cur_instr = new ushort[]
{IDLE,
IDLE,
TR16, Z, W, C, B,
OUT, Z, W, src,
IDLE,
INC16, Z, W,
IDLE,
IDLE,
WAIT,
OP_F,
OP};
}
@ -481,15 +481,15 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
{
cur_instr = new ushort[]
{IDLE,
RD, Z, PCl, PCh,
WAIT,
RD_INC, Z, PCl, PCh,
IDLE,
INC16, PCl, PCh,
TR, W, A,
IN, A, Z, W,
IDLE,
INC16, Z, W,
IDLE,
IDLE,
WAIT,
OP_F,
OP};
}
@ -497,12 +497,12 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
{
cur_instr = new ushort[]
{IDLE,
IDLE,
IN, dest, src, B,
IDLE,
TR16, Z, W, C, B,
INC16, Z, W,
IDLE,
WAIT,
OP_F,
OP};
}
@ -511,61 +511,61 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
cur_instr = new ushort[]
{IDLE,
IDLE,
IDLE,
TR16, Z, W, dest_l, dest_h,
INC16, Z, W,
IDLE,
IDLE,
op, dest_l, dest_h, src_l, src_h,
IDLE,
IDLE,
WAIT,
OP_F,
OP};
}
private void INT_MODE_(ushort src)
{
cur_instr = new ushort[]
{IDLE,
IDLE,
INT_MODE, src,
{INT_MODE, src,
WAIT,
OP_F,
OP };
}
private void RRD_()
{
cur_instr = new ushort[]
{IDLE,
IDLE,
TR16, Z, W, L, H,
IDLE,
{TR16, Z, W, L, H,
WAIT,
RD, ALU, Z, W,
IDLE,
RRD, ALU, A,
IDLE,
IDLE,
IDLE,
WAIT,
WR, Z, W, ALU,
IDLE,
INC16, Z, W,
IDLE,
IDLE,
WAIT,
OP_F,
OP };
}
private void RLD_()
{
cur_instr = new ushort[]
{IDLE,
IDLE,
TR16, Z, W, L, H,
IDLE,
{TR16, Z, W, L, H,
WAIT,
RD, ALU, Z, W,
IDLE,
RLD, ALU, A,
IDLE,
IDLE,
IDLE,
WAIT,
WR, Z, W, ALU,
IDLE,
INC16, Z, W,
IDLE,
IDLE,
WAIT,
OP_F,
OP };
}
}

View File

@ -6,15 +6,15 @@
{
cur_instr = new ushort[]
{IDLE,
IDLE,
IDLE,
WAIT,
RD, ALU, src_l, src_h,
IDLE,
operation, ALU,
IDLE,
WAIT,
WR, src_l, src_h, ALU,
IDLE,
IDLE,
IDLE,
WAIT,
OP_F,
OP };
}
@ -23,14 +23,14 @@
cur_instr = new ushort[]
{IDLE,
IDLE,
IDLE,
WAIT,
RD, ALU, src_l, src_h,
IDLE,
operation, bit, ALU,
IDLE,
WAIT,
WR, src_l, src_h, ALU,
IDLE,
IDLE,
WAIT,
OP_F,
OP };
}
@ -43,11 +43,11 @@
cur_instr = new ushort[]
{IDLE,
IDLE,
IDLE,
WAIT,
RD, ALU, src_l, src_h,
IDLE,
I_BIT, bit, ALU,
IDLE,
WAIT,
OP_F,
OP };
}
@ -55,23 +55,23 @@
{
cur_instr = new ushort[]
{IDLE,
IDLE,
RD, ALU, src_l, src_h,
IDLE,
WAIT,
RD_INC, ALU, src_l, src_h,
operation, dest, ALU,
INC16, src_l, src_h,
WAIT,
OP_F,
OP };
}
private void REG_OP_IND(ushort operation, ushort dest, ushort src_l, ushort src_h)
{
cur_instr = new ushort[]
{IDLE,
IDLE,
TR16, Z, W, src_l, src_h,
RD, ALU, Z, W,
INC16, Z, W,
operation, dest, ALU,
{TR16, Z, W, src_l, src_h,
WAIT,
RD_INC, ALU, Z, W,
operation, dest, ALU,
WAIT,
OP_F,
OP };
}
@ -79,20 +79,20 @@
{
cur_instr = new ushort[]
{IDLE,
RD, Z, PCl, PCh,
WAIT,
RD_INC, Z, PCl, PCh,
IDLE,
INC16, PCl, PCh,
IDLE,
RD, W, PCl, PCh,
IDLE,
INC16, PCl, PCh,
WAIT,
RD_INC, W, PCl, PCh,
IDLE,
WAIT,
WR, Z, W, src_l,
IDLE,
INC16, Z, W,
IDLE,
WAIT,
WR, Z, W, src_h,
IDLE,
WAIT,
OP_F,
OP };
}
@ -100,20 +100,20 @@
{
cur_instr = new ushort[]
{IDLE,
RD, Z, PCl, PCh,
WAIT,
RD_INC, Z, PCl, PCh,
IDLE,
INC16, PCl, PCh,
WAIT,
RD_INC, W, PCl, PCh,
IDLE,
RD, W, PCl, PCh,
IDLE,
INC16, PCl, PCh,
IDLE,
RD, dest_l, Z, W,
IDLE,
INC16, Z, W,
WAIT,
RD_INC, dest_l, Z, W,
IDLE,
WAIT,
RD, dest_h, Z, W,
IDLE,
WAIT,
OP_F,
OP };
}
@ -121,17 +121,17 @@
{
cur_instr = new ushort[]
{IDLE,
RD, Z, PCl, PCh,
WAIT,
RD_INC, Z, PCl, PCh,
IDLE,
INC16, PCl, PCh,
WAIT,
RD_INC, W, PCl, PCh,
IDLE,
RD, W, PCl, PCh,
IDLE,
INC16, PCl, PCh,
IDLE,
WR, Z, W, src,
INC16, Z, W,
WAIT,
WR_INC, Z, W, src,
TR, W, A,
WAIT,
OP_F,
OP };
}
@ -139,29 +139,29 @@
{
cur_instr = new ushort[]
{IDLE,
RD, Z, PCl, PCh,
WAIT,
RD_INC, Z, PCl, PCh,
IDLE,
INC16, PCl, PCh,
WAIT,
RD_INC, W, PCl, PCh,
IDLE,
RD, W, PCl, PCh,
WAIT,
RD_INC, dest, Z, W,
IDLE,
INC16, PCl, PCh,
IDLE,
RD, dest, Z, W,
IDLE,
INC16, Z, W,
WAIT,
OP_F,
OP };
}
private void LD_8_IND(ushort dest_l, ushort dest_h, ushort src)
{
cur_instr = new ushort[]
{IDLE,
IDLE,
TR16, Z, W, dest_l, dest_h,
WR, Z, W, src,
INC16, Z, W,
TR, W, A,
{TR16, Z, W, dest_l, dest_h,
WAIT,
WR_INC, Z, W, src,
TR, W, A,
WAIT,
OP_F,
OP };
}
@ -169,14 +169,14 @@
{
cur_instr = new ushort[]
{IDLE,
WAIT,
RD_INC, ALU, src_l, src_h,
IDLE,
IDLE,
RD, ALU, src_l, src_h,
IDLE,
INC16, src_l, src_h,
IDLE,
WAIT,
WR, dest_l, dest_h, ALU,
IDLE,
WAIT,
OP_F,
OP };
}
@ -184,24 +184,11 @@
{
cur_instr = new ushort[]
{IDLE,
WAIT,
RD_INC, dest, src_l, src_h,
IDLE,
IDLE,
RD, dest, src_l, src_h,
IDLE,
INC16, src_l, src_h,
OP };
}
private void LD_IND_8_DEC(ushort dest, ushort src_l, ushort src_h)
{
cur_instr = new ushort[]
{IDLE,
IDLE,
IDLE,
RD, dest, src_l, src_h,
IDLE,
DEC16, src_l, src_h,
IDLE,
WAIT,
OP_F,
OP };
}
@ -209,14 +196,14 @@
{
cur_instr = new ushort[]
{IDLE,
WAIT,
RD_INC, dest_l, src_l, src_h,
IDLE,
WAIT,
RD_INC, dest_h, src_l, src_h,
IDLE,
RD, dest_l, src_l, src_h,
IDLE,
INC16, src_l, src_h,
RD, dest_h, src_l, src_h,
IDLE,
INC16, src_l, src_h,
WAIT,
OP_F,
OP };
}
@ -225,14 +212,14 @@
cur_instr = new ushort[]
{IDLE,
IDLE,
IDLE,
WAIT,
RD, ALU, src_l, src_h,
IDLE,
INC8, ALU,
IDLE,
WAIT,
WR, src_l, src_h, ALU,
IDLE,
IDLE,
WAIT,
OP_F,
OP };
}
@ -241,14 +228,14 @@
cur_instr = new ushort[]
{IDLE,
IDLE,
IDLE,
WAIT,
RD, ALU, src_l, src_h,
IDLE,
DEC8, ALU,
IDLE,
WAIT,
WR, src_l, src_h, ALU,
IDLE,
IDLE,
WAIT,
OP_F,
OP };
}
@ -258,14 +245,14 @@
cur_instr = new ushort[]
{IDLE,
IDLE,
WAIT,
RD, ALU, Z, W,
IDLE,
operation, ALU,
IDLE,
WAIT,
WR, Z, W, ALU,
IDLE,
TR, dest, ALU,
IDLE,
WAIT,
OP_F,
OP };
}
@ -274,14 +261,14 @@
cur_instr = new ushort[]
{IDLE,
IDLE,
WAIT,
RD, ALU, Z, W,
IDLE,
operation, bit, ALU,
IDLE,
WAIT,
WR, Z, W, ALU,
IDLE,
TR, dest, ALU,
IDLE,
WAIT,
OP_F,
OP };
}
@ -290,11 +277,11 @@
cur_instr = new ushort[]
{IDLE,
IDLE,
IDLE,
WAIT,
RD, ALU, Z, W,
IDLE,
I_BIT, bit, ALU,
IDLE,
WAIT,
OP_F,
OP };
}
@ -302,23 +289,23 @@
{
cur_instr = new ushort[]
{IDLE,
WAIT,
RD_INC, ALU, PCl, PCh,
IDLE,
RD, ALU, PCl, PCh,
INC16, PCl, PCh,
IDLE,
TR16, Z, W, src_l, src_h,
ADDS, Z, W, ALU, ZERO,
IDLE,
ADDS, Z, W, ALU, ZERO,
IDLE,
IDLE,
WAIT,
RD, ALU, Z, W,
IDLE,
IDLE,
operation, ALU,
IDLE,
IDLE,
IDLE,
WAIT,
WR, Z, W, ALU,
IDLE,
WAIT,
OP_F,
OP };
}
@ -326,19 +313,19 @@
{
cur_instr = new ushort[]
{IDLE,
IDLE,
RD, ALU, PCl, PCh,
INC16, PCl, PCh,
WAIT,
RD_INC, ALU, PCl, PCh,
IDLE,
TR16, Z, W, src_l, src_h,
IDLE,
ADDS, Z, W, ALU, ZERO,
WAIT,
RD_INC, ALU, PCl, PCh,
IDLE,
RD, ALU, PCl, PCh,
INC16, PCl, PCh,
IDLE,
WAIT,
WR, Z, W, ALU,
IDLE,
WAIT,
OP_F,
OP };
}
@ -346,19 +333,19 @@
{
cur_instr = new ushort[]
{IDLE,
IDLE,
RD, ALU, PCl, PCh,
IDLE,
INC16, PCl, PCh,
WAIT,
RD_INC, ALU, PCl, PCh,
IDLE,
TR16, Z, W, src_l, src_h,
IDLE,
ADDS, Z, W, ALU, ZERO,
IDLE,
WAIT,
RD, ALU, Z, W,
IDLE,
operation, dest, ALU,
IDLE,
WAIT,
OP_F,
OP };
}
@ -366,36 +353,36 @@
{
cur_instr = new ushort[]
{IDLE,
RD, ALU, PCl, PCh,
WAIT,
RD_INC, ALU, PCl, PCh,
IDLE,
INC16, PCl, PCh,
IDLE,
TR16, Z, W, dest_l, dest_h,
IDLE,
ADDS, Z, W, ALU, ZERO,
IDLE,
WR, Z, W, src,
IDLE,
IDLE,
IDLE,
WAIT,
WR, Z, W, src,
IDLE,
WAIT,
OP_F,
OP };
}
private void LD_OP_R(ushort operation, ushort repeat_instr)
{
cur_instr = new ushort[]
{RD, ALU, L, H,
{IDLE,
WAIT,
RD, ALU, L, H,
IDLE,
WAIT,
WR, E, D, ALU,
IDLE,
operation, L, H,
IDLE,
operation, E, D,
IDLE,
DEC16, C, B,
SET_FL_LD,
IDLE,
SET_FL_LD, // BC gets decremented in here
WAIT,
OP_F,
OP_R, 0, operation, repeat_instr };
}
@ -403,16 +390,16 @@
{
cur_instr = new ushort[]
{IDLE,
IDLE,
WAIT,
RD, ALU, L, H,
operation, L, H,
IDLE,
IDLE,
DEC16, C, B,
SET_FL_CP,
IDLE,
operation, Z, W,
IDLE,
IDLE,
WAIT,
OP_F,
OP_R, 1, operation, repeat_instr };
}
@ -421,32 +408,32 @@
cur_instr = new ushort[]
{IN, ALU, C, B,
IDLE,
IDLE,
IDLE,
IDLE,
WAIT,
WR, L, H, ALU,
REP_OP_I, operation,
IDLE,
operation, L, H,
IDLE,
TR16, Z, W, C, B,
operation, Z, W,
IDLE,
DEC8, B,
IDLE,
WAIT,
OP_F,
OP_R, 2, operation, repeat_instr };
}
private void OUT_OP_R(ushort operation, ushort repeat_instr)
{
cur_instr = new ushort[]
{RD, ALU, L, H,
{IDLE,
WAIT,
RD, ALU, L, H,
IDLE,
OUT, C, B, ALU,
IDLE,
IDLE,
operation, L, H,
DEC8, B,
IDLE,
TR16, Z, W, C, B,
operation, Z, W,
REP_OP_O, operation,
IDLE,
WAIT,
OP_F,
OP_R, 3, operation, repeat_instr };
}
@ -455,23 +442,23 @@
{
cur_instr = new ushort[]
{IDLE,
IDLE,
WAIT,
RD, Z, dest_l, dest_h,
IDLE,
IDLE,
WAIT,
I_RD, W, dest_l, dest_h, 1,
IDLE,
IDLE,
WR, dest_l, dest_h, src_l,
WAIT,
WR, dest_l, dest_h, src_l,
IDLE,
IDLE,
IDLE,
WAIT,
I_WR, dest_l, dest_h, 1, src_h,
IDLE,
IDLE,
TR16, src_l, src_h, Z, W,
IDLE,
IDLE,
IDLE,
WAIT,
OP_F,
OP };
}
}

View File

@ -76,6 +76,12 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
public const ushort HL_BIT = 61;
public const ushort FTCH_DB = 62;
public const ushort WAIT = 63; // enterred when readin or writing and FlagW is true
public const ushort OP_F = 64; // fetch the opcode, happens on cycle 3 of fetch cycle
public const ushort RD_INC = 65; // read and increment
public const ushort RST = 66;
public const ushort WR_INC = 67; // write and increment
public const ushort REP_OP_I = 68;
public const ushort REP_OP_O = 69;
public byte temp_R;
@ -90,7 +96,11 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
ResetRegisters();
ResetInterrupts();
TotalExecutedCycles = 0;
cur_instr = new ushort[] { OP };
cur_instr = new ushort[]
{ IDLE,
WAIT,
OP_F,
OP };
instr_pntr = 0;
NO_prefix = true;
}
@ -205,19 +215,11 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
}
else
{
if(!FlagW)
{
if (OnExecFetch != null) OnExecFetch(RegPC);
if (TraceCallback != null) TraceCallback(State());
FetchInstruction(FetchMemory(RegPC++));
instr_pntr = 0;
}
else
{
instr_pntr--;
instr_swap = OP;
cur_instr[instr_pntr] = WAIT;
}
if (OnExecFetch != null) OnExecFetch(RegPC);
if (TraceCallback != null) TraceCallback(State());
RegPC++;
FetchInstruction();
instr_pntr = 0;
}
temp_R = (byte)(Regs[R] & 0x7F);
@ -255,10 +257,10 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
if (repeat && temp3 > 0)
{
cur_instr = new ushort[]
{IDLE,
DEC16, PCl, PCh,
IDLE,
{DEC16, PCl, PCh,
DEC16, PCl, PCh,
WAIT,
OP_F,
OP };
instr_pntr = 0;
@ -340,19 +342,11 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
}
else
{
if (!FlagW)
{
if (OnExecFetch != null) OnExecFetch(RegPC);
if (TraceCallback != null) TraceCallback(State());
FetchInstruction(FetchMemory(RegPC++));
instr_pntr = 0;
}
else
{
instr_pntr--;
instr_swap = OP;
cur_instr[instr_pntr] = WAIT;
}
if (OnExecFetch != null) OnExecFetch(RegPC);
if (TraceCallback != null) TraceCallback(State());
RegPC++;
FetchInstruction();
instr_pntr = 0;
}
temp_R = (byte)(Regs[R] & 0x7F);
@ -432,53 +426,16 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
instr_pntr = 0;
break;
case RD:
if (!FlagW)
{
Read_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
}
else
{
instr_pntr--;
instr_swap = RD;
cur_instr[instr_pntr] = WAIT;
}
Read_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case WR:
if (!FlagW)
{
Write_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
}
else
{
instr_pntr--;
instr_swap = WR;
cur_instr[instr_pntr] = WAIT;
}
Write_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case I_RD:
if (!FlagW)
{
I_Read_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
}
else
{
instr_pntr--;
instr_swap = I_RD;
cur_instr[instr_pntr] = WAIT;
}
I_Read_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case I_WR:
if (!FlagW)
{
I_Write_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
}
else
{
instr_pntr--;
instr_swap =I_WR;
cur_instr[instr_pntr] = WAIT;
}
I_Write_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case TR:
TR_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
@ -606,7 +563,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
if (prefix_src == IXCBpre) { IXCB_prefix = true; IXCB_prefetch = true; }
if (prefix_src == IYCBpre) { IYCB_prefix = true; IYCB_prefetch = true; }
FetchInstruction(FetchMemory(RegPC++));
RegPC++;
FetchInstruction();
instr_pntr = 0;
// only the first prefix in a double prefix increases R, although I don't know how / why
if (prefix_src < 4)
@ -632,28 +590,10 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
iff1 = iff2;
break;
case OUT:
if (!FlagW)
{
OUT_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
}
else
{
instr_pntr--;
instr_swap = OUT;
cur_instr[instr_pntr] = WAIT;
}
OUT_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case IN:
if (!FlagW)
{
IN_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
}
else
{
instr_pntr--;
instr_swap = IN;
cur_instr[instr_pntr] = WAIT;
}
IN_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case NEG:
NEG_8_Func(cur_instr[instr_pntr++]);
@ -668,6 +608,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
RLD_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case SET_FL_LD:
DEC16_Func(C, B);
SET_FL_LD_Func();
break;
case SET_FL_CP:
@ -684,35 +625,54 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
{
instr_pntr--;
}
break;
case OP_F:
opcode = FetchMemory(RegPC);
break;
case RD_INC:
Read_INC_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case WR_INC:
Write_INC_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case RST:
Regs[Z] = cur_instr[instr_pntr++];
Regs[W] = 0;
Regs[PCl] = Regs[Z];
Regs[PCh] = Regs[W];
break;
case REP_OP_I:
ushort temp4 = cur_instr[instr_pntr++];
if (temp4 == DEC16)
{
DEC16_Func(L, H);
TR16_Func(Z, W, C, B);
DEC16_Func(Z, W);
DEC8_Func(B);
}
else
{
switch (instr_swap)
{
case OP:
if (OnExecFetch != null) OnExecFetch(RegPC);
if (TraceCallback != null) TraceCallback(State());
FetchInstruction(FetchMemory(RegPC++));
instr_pntr = 0;
break;
case RD:
Read_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case WR:
Write_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case I_RD:
I_Read_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case I_WR:
I_Read_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case IN:
IN_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case OUT:
OUT_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
}
INC16_Func(L, H);
TR16_Func(Z, W, C, B);
INC16_Func(Z, W);
DEC8_Func(B);
}
break;
case REP_OP_O:
ushort temp5 = cur_instr[instr_pntr++];
if (temp5 == DEC16)
{
DEC16_Func(L, H);
DEC8_Func(B);
TR16_Func(Z, W, C, B);
DEC16_Func(Z, W);
}
else
{
INC16_Func(L, H);
DEC8_Func(B);
TR16_Func(Z, W, C, B);
INC16_Func(Z, W);
}
break;
}