mirror of
https://github.com/MoleskiCoder/EightBitNet.git
synced 2026-03-11 05:41:49 +00:00
More Z80 timing fixes
This commit is contained in:
@@ -333,10 +333,10 @@
|
||||
private void InitialiseState(Test test)
|
||||
{
|
||||
var initial = test.Initial ?? throw new InvalidOperationException("Test cannot have an invalid initial state");
|
||||
this.InitialiseState(initial);
|
||||
this.InitialiseState(initial, test.AvailablePorts());
|
||||
}
|
||||
|
||||
private void InitialiseState(State state)
|
||||
private void InitialiseState(State state, IEnumerable<Port> ports)
|
||||
{
|
||||
var runner = this.Runner;
|
||||
var cpu = runner.CPU;
|
||||
@@ -390,6 +390,24 @@
|
||||
var value = (byte)entry[1];
|
||||
runner.Poke(address, value);
|
||||
}
|
||||
|
||||
foreach (var port in ports)
|
||||
{
|
||||
var address = new Register16(port.Address).Low;
|
||||
var value = port.Value;
|
||||
if (port.Type == "r")
|
||||
{
|
||||
cpu.Ports.WriteInputPort(address, value);
|
||||
}
|
||||
else if (port.Type == "w")
|
||||
{
|
||||
cpu.Ports.WriteOutputPort(address, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException($"Unknown port action type: {port.Type}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AddActualCycle(EightBit.Register16 address, byte value, string action) => this.AddActualCycle(address.Word, value, action);
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
{
|
||||
if (this.Ports is null)
|
||||
{
|
||||
throw new InvalidOperationException("Ports have not been initialised");
|
||||
yield break;
|
||||
}
|
||||
|
||||
foreach (var port in this.Ports)
|
||||
|
||||
43
Z80/Z80.cs
43
Z80/Z80.cs
@@ -19,6 +19,8 @@ namespace Z80
|
||||
|
||||
private readonly InputOutput _ports;
|
||||
|
||||
public InputOutput Ports => this._ports;
|
||||
|
||||
private readonly Register16[] _accumulatorFlags = [new Register16(), new Register16()];
|
||||
private readonly Register16[][] _registers =
|
||||
[
|
||||
@@ -504,8 +506,16 @@ namespace Z80
|
||||
var returned = base.MemoryRead();
|
||||
this.RaiseRD();
|
||||
this.RaiseMREQ();
|
||||
if (this.M1.Raised())
|
||||
if (this.M1.Lowered())
|
||||
{
|
||||
this.Bus.Address.Assign(this.REFRESH, this.IV);
|
||||
this.LowerRFSH();
|
||||
this.Tick();
|
||||
this.LowerMREQ();
|
||||
this.RaiseMREQ();
|
||||
this.RaiseRFSH();
|
||||
}
|
||||
this.Tick();
|
||||
return returned;
|
||||
}
|
||||
|
||||
@@ -1509,6 +1519,7 @@ namespace Z80
|
||||
break;
|
||||
case 3: // LD SP,HL
|
||||
this.SP.Assign(this.HL2());
|
||||
this.Tick(2);
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException("Invalid operation mode");
|
||||
@@ -1695,15 +1706,6 @@ namespace Z80
|
||||
this.LowerM1();
|
||||
var returned = this.MemoryRead(this.PC);
|
||||
this.RaiseM1();
|
||||
|
||||
this.Bus.Address.Assign(this.REFRESH, this.IV);
|
||||
this.LowerRFSH();
|
||||
this.Tick();
|
||||
this.LowerMREQ();
|
||||
this.RaiseMREQ();
|
||||
this.RaiseRFSH();
|
||||
this.Tick();
|
||||
|
||||
return returned;
|
||||
}
|
||||
|
||||
@@ -1766,9 +1768,9 @@ namespace Z80
|
||||
protected sealed override bool ReturnConditionalFlag(int flag)
|
||||
{
|
||||
var condition = this.ConvertCondition(flag);
|
||||
this.Tick();
|
||||
if (condition)
|
||||
{
|
||||
this.Tick();
|
||||
this.Return();
|
||||
}
|
||||
return condition;
|
||||
@@ -2029,11 +2031,18 @@ namespace Z80
|
||||
++this.Bus.Address.Word;
|
||||
this.MEMPTR.High = this.MemoryRead();
|
||||
this.Tick();
|
||||
this.MemoryWrite(exchange.High);
|
||||
exchange.High = this.MEMPTR.High;
|
||||
--this.Bus.Address.Word;
|
||||
this.MemoryWrite(exchange.Low);
|
||||
this.Tick();
|
||||
this.Bus.Data = exchange.Low;
|
||||
exchange.Low = this.MEMPTR.Low;
|
||||
this.MemoryUpdate(1);
|
||||
this.Tick();
|
||||
++this.Bus.Address.Word;
|
||||
this.Tick();
|
||||
this.Bus.Data = exchange.High;
|
||||
exchange.High = this.MEMPTR.High;
|
||||
this.MemoryUpdate(1);
|
||||
this.Tick(3);
|
||||
}
|
||||
|
||||
private void BlockCompare(Register16 source, ushort counter)
|
||||
@@ -2265,18 +2274,20 @@ namespace Z80
|
||||
{
|
||||
this.Bus.Address.Assign(port, this.Bus.Data = this.A);
|
||||
this.MEMPTR.Assign(this.Bus.Address);
|
||||
++this.MEMPTR.Low;
|
||||
++this.MEMPTR.Word;
|
||||
this.ReadPort();
|
||||
}
|
||||
|
||||
private void ReadPort()
|
||||
{
|
||||
this.Tick();
|
||||
this.Tick(2);
|
||||
this.LowerIORQ();
|
||||
this.LowerRD();
|
||||
this.Bus.Data = this._ports.Read(this.Bus.Address.Low);
|
||||
this.Tick();
|
||||
this.RaiseRD();
|
||||
this.RaiseIORQ();
|
||||
this.Tick();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user