Sync with C++ z80 implementation

Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
Adrian Conlon 2019-11-10 11:17:47 +00:00
parent 0f2a69509b
commit a5598942a7
1 changed files with 63 additions and 15 deletions

View File

@ -31,6 +31,7 @@ namespace EightBit
private PinLevel nmiLine = PinLevel.Low;
private PinLevel m1Line = PinLevel.Low;
private PinLevel mreqLine = PinLevel.Low;
private PinLevel iorqLine = PinLevel.Low;
private PinLevel rdLine = PinLevel.Low;
private PinLevel wrLine = PinLevel.Low;
@ -64,6 +65,14 @@ namespace EightBit
public event EventHandler<EventArgs> LoweredM1;
public event EventHandler<EventArgs> RaisingMREQ;
public event EventHandler<EventArgs> RaisedMREQ;
public event EventHandler<EventArgs> LoweringMREQ;
public event EventHandler<EventArgs> LoweredMREQ;
public event EventHandler<EventArgs> RaisingIORQ;
public event EventHandler<EventArgs> RaisedIORQ;
@ -122,6 +131,8 @@ namespace EightBit
public ref PinLevel M1 => ref this.m1Line;
public ref PinLevel MREQ => ref this.mreqLine;
public ref PinLevel IORQ => ref this.iorqLine;
public ref PinLevel RD => ref this.rdLine;
@ -181,6 +192,26 @@ namespace EightBit
}
}
public virtual void RaiseMREQ()
{
if (this.MREQ.Lowered())
{
this.OnRaisingMREQ();
this.MREQ.Raise();
this.OnRaisedMREQ();
}
}
public virtual void LowerMREQ()
{
if (this.MREQ.Raised())
{
this.OnLoweringMREQ();
this.MREQ.Lower();
this.OnLoweredMREQ();
}
}
public virtual void RaiseIORQ()
{
if (this.IORQ.Lowered())
@ -243,8 +274,6 @@ namespace EightBit
public override int Execute()
{
this.RaiseM1();
var decoded = this.GetDecodedOpCode(this.OpCode);
var x = decoded.X;
@ -291,20 +320,21 @@ namespace EightBit
else if (this.INT.Lowered())
{
this.RaiseHALT();
if (handled = this.IFF1)
if (this.IFF1)
{
this.HandleINT();
handled = true;
}
}
else if (this.HALT.Lowered())
{
this.Execute(0); // NOP
handled = true;
}
if (!handled)
{
this.LowerM1();
this.Execute(this.FetchByte());
this.Execute(this.FetchInitialOpCode());
}
}
@ -315,6 +345,7 @@ namespace EightBit
protected override void OnRaisedPOWER()
{
this.RaiseM1();
this.RaiseMREQ();
this.RaiseIORQ();
this.RaiseRD();
this.RaiseWR();
@ -325,11 +356,11 @@ namespace EightBit
this.REFRESH = new RefreshRegister(0);
this.IV = (byte)Mask.Mask8;
this.AF.Word = this.IX.Word = this.IY.Word = this.BC.Word = this.DE.Word = this.HL.Word = (ushort)Mask.Mask16;
this.ExxAF();
this.Exx();
this.AF.Word = this.IX.Word = this.IY.Word = this.BC.Word = this.DE.Word = this.HL.Word = (ushort)Mask.Mask16;
this.prefixCB = this.prefixDD = this.prefixED = false;
base.OnRaisedPOWER();
@ -359,6 +390,14 @@ namespace EightBit
this.LoweredM1?.Invoke(this, EventArgs.Empty);
}
protected virtual void OnLoweringMREQ() => this.LoweringMREQ?.Invoke(this, EventArgs.Empty);
protected virtual void OnLoweredMREQ() => this.LoweredMREQ?.Invoke(this, EventArgs.Empty);
protected virtual void OnRaisingMREQ() => this.RaisingMREQ?.Invoke(this, EventArgs.Empty);
protected virtual void OnRaisedMREQ() => this.RaisedMREQ?.Invoke(this, EventArgs.Empty);
protected virtual void OnLoweringIORQ() => this.LoweringIORQ?.Invoke(this, EventArgs.Empty);
protected virtual void OnLoweredIORQ() => this.LoweredIORQ?.Invoke(this, EventArgs.Empty);
@ -385,16 +424,20 @@ namespace EightBit
protected override void BusWrite()
{
this.LowerMREQ();
this.LowerWR();
base.BusWrite();
this.RaiseWR();
this.RaiseMREQ();
}
protected override byte BusRead()
{
this.LowerMREQ();
this.LowerRD();
var returned = base.BusRead();
this.RaiseRD();
this.RaiseMREQ();
return returned;
}
@ -1415,13 +1458,13 @@ namespace EightBit
if (this.displaced)
{
this.FetchDisplacement();
this.Execute(this.FetchByte());
}
else
{
this.LowerM1();
this.Execute(this.FetchInitialOpCode());
}
this.Execute(this.FetchByte());
break;
case 2: // OUT (n),A
this.WritePort(this.FetchByte());
@ -1476,18 +1519,15 @@ namespace EightBit
break;
case 1: // DD prefix
this.displaced = this.prefixDD = true;
this.LowerM1();
this.Execute(this.FetchByte());
this.Execute(this.FetchInitialOpCode());
break;
case 2: // ED prefix
this.prefixED = true;
this.LowerM1();
this.Execute(this.FetchByte());
this.Execute(this.FetchInitialOpCode());
break;
case 3: // FD prefix
this.displaced = true;
this.LowerM1();
this.Execute(this.FetchByte());
this.Execute(this.FetchInitialOpCode());
break;
default:
throw new NotSupportedException("Invalid operation mode");
@ -1562,6 +1602,14 @@ namespace EightBit
private void FetchDisplacement() => this.displacement = (sbyte)this.FetchByte();
private byte FetchInitialOpCode()
{
this.LowerM1();
var returned = this.FetchByte();
this.RaiseM1();
return returned;
}
private byte Subtract(byte operand, byte value, int carry = 0)
{
this.intermediate.Word = (ushort)(operand - value - carry);