Z80A: Add a WAIT state that can puase the CPU on reads / writes
NOTE: a wait state is added automatically to IN/OUT reads / writes, but I don't know if this is already accounted for in the cycle timings, TODO.
This commit is contained in:
parent
258fef46d7
commit
a185f33487
|
@ -18,6 +18,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
|
||||
// variables for executing instructions
|
||||
public int instr_pntr = 0;
|
||||
public ushort instr_swap;
|
||||
public ushort[] cur_instr;
|
||||
public int opcode;
|
||||
public bool NO_prefix, CB_prefix, IX_prefix, EXTD_prefix, IY_prefix, IXCB_prefix, IYCB_prefix;
|
||||
|
|
|
@ -45,6 +45,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
|
||||
public bool FlagI;
|
||||
|
||||
public bool FlagW; // wait flag, when set to true reads / writes will be delayed
|
||||
|
||||
public bool FlagC
|
||||
{
|
||||
get { return (Regs[5] & 0x01) != 0; }
|
||||
|
@ -109,6 +111,9 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
{
|
||||
Regs[i] = 0;
|
||||
}
|
||||
|
||||
FlagI = false;
|
||||
FlagW = false;
|
||||
}
|
||||
|
||||
private bool[] TableParity;
|
||||
|
@ -125,8 +130,5 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
TableParity[i] = (Bits & 1) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -75,6 +75,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
public const ushort I_BIT = 60;
|
||||
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 byte temp_R;
|
||||
|
||||
|
@ -146,7 +147,6 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
// Execute instructions
|
||||
public void ExecuteOne()
|
||||
{
|
||||
if (Regs[A] > 255) { Console.WriteLine(RegPC); }
|
||||
switch (cur_instr[instr_pntr++])
|
||||
{
|
||||
case IDLE:
|
||||
|
@ -174,6 +174,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
iff1 = false;
|
||||
NMI_();
|
||||
NMICallback();
|
||||
instr_pntr = 0;
|
||||
}
|
||||
else if (iff1 && FlagI)
|
||||
{
|
||||
|
@ -200,14 +201,24 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
break;
|
||||
}
|
||||
IRQCallback();
|
||||
instr_pntr = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (OnExecFetch != null) OnExecFetch(RegPC);
|
||||
if (TraceCallback != null) TraceCallback(State());
|
||||
FetchInstruction(FetchMemory(RegPC++));
|
||||
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;
|
||||
}
|
||||
}
|
||||
instr_pntr = 0;
|
||||
|
||||
temp_R = (byte)(Regs[R] & 0x7F);
|
||||
temp_R++;
|
||||
|
@ -250,6 +261,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
DEC16, PCl, PCh,
|
||||
OP };
|
||||
|
||||
instr_pntr = 0;
|
||||
// adjust WZ register accordingly
|
||||
switch (temp1)
|
||||
{
|
||||
|
@ -297,6 +309,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
iff1 = false;
|
||||
NMI_();
|
||||
NMICallback();
|
||||
instr_pntr = 0;
|
||||
}
|
||||
else if (iff1 && FlagI)
|
||||
{
|
||||
|
@ -323,12 +336,23 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
break;
|
||||
}
|
||||
IRQCallback();
|
||||
instr_pntr = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (OnExecFetch != null) OnExecFetch(RegPC);
|
||||
if (TraceCallback != null) TraceCallback(State());
|
||||
FetchInstruction(FetchMemory(RegPC++));
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
temp_R = (byte)(Regs[R] & 0x7F);
|
||||
|
@ -336,7 +360,6 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
temp_R &= 0x7F;
|
||||
Regs[R] = (byte)((Regs[R] & 0x80) | temp_R);
|
||||
}
|
||||
instr_pntr = 0;
|
||||
break;
|
||||
|
||||
case HALT:
|
||||
|
@ -409,16 +432,53 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
instr_pntr = 0;
|
||||
break;
|
||||
case RD:
|
||||
Read_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
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;
|
||||
}
|
||||
|
||||
break;
|
||||
case WR:
|
||||
Write_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
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;
|
||||
}
|
||||
break;
|
||||
case I_RD:
|
||||
I_Read_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
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;
|
||||
}
|
||||
break;
|
||||
case I_WR:
|
||||
I_Write_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
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;
|
||||
}
|
||||
break;
|
||||
case TR:
|
||||
TR_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
|
@ -572,10 +632,28 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
iff1 = iff2;
|
||||
break;
|
||||
case OUT:
|
||||
OUT_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
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;
|
||||
}
|
||||
break;
|
||||
case IN:
|
||||
IN_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
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;
|
||||
}
|
||||
break;
|
||||
case NEG:
|
||||
NEG_8_Func(cur_instr[instr_pntr++]);
|
||||
|
@ -601,6 +679,42 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
case FTCH_DB:
|
||||
FTCH_DB_Func();
|
||||
break;
|
||||
case WAIT:
|
||||
if (FlagW)
|
||||
{
|
||||
instr_pntr--;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
TotalExecutedCycles++;
|
||||
}
|
||||
|
@ -672,10 +786,12 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
ser.Sync("ExecutedCycles", ref TotalExecutedCycles);
|
||||
ser.Sync("EI_pending", ref EI_pending);
|
||||
|
||||
ser.Sync("instruction_pointer", ref instr_pntr);
|
||||
ser.Sync("current instruction", ref cur_instr, false);
|
||||
ser.Sync("instr_pntr", ref instr_pntr);
|
||||
ser.Sync("cur_instr", ref cur_instr, false);
|
||||
ser.Sync("instr_swap", ref instr_swap);
|
||||
ser.Sync("opcode", ref opcode);
|
||||
ser.Sync("FlagI", ref FlagI);
|
||||
ser.Sync("FlagW", ref FlagW);
|
||||
|
||||
ser.Sync("NO Preifx", ref NO_prefix);
|
||||
ser.Sync("CB Preifx", ref CB_prefix);
|
||||
|
|
Loading…
Reference in New Issue