ZXHawk: implemented +2a/+3 floating bus (confirmed working with 2017 release of 'A Yankee in Iraq')
This commit is contained in:
parent
7ce55e6601
commit
373db35805
|
@ -62,6 +62,11 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ushort lastPortAddr;
|
public ushort lastPortAddr;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If true, the next read memory operation has been contended
|
||||||
|
/// </summary>
|
||||||
|
public bool NextMemReadContended;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Methods
|
#region Methods
|
||||||
|
@ -87,6 +92,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
if (cont > 0)
|
if (cont > 0)
|
||||||
{
|
{
|
||||||
_cpu.TotalExecutedCycles += cont;
|
_cpu.TotalExecutedCycles += cont;
|
||||||
|
NextMemReadContended = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -393,7 +399,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
public void SyncState(Serializer ser)
|
public void SyncState(Serializer ser)
|
||||||
{
|
{
|
||||||
ser.BeginSection("CPUMonitor");
|
ser.BeginSection("CPUMonitor");
|
||||||
ser.Sync("", ref lastPortAddr);
|
ser.Sync("lastPortAddr", ref lastPortAddr);
|
||||||
|
ser.Sync("NextMemReadContended", ref NextMemReadContended);
|
||||||
ser.EndSection();
|
ser.EndSection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
/// Signs that all paging is disabled
|
/// Signs that all paging is disabled
|
||||||
/// If this is TRUE, then 128k and above machines need a hard reset before paging is allowed again
|
/// If this is TRUE, then 128k and above machines need a hard reset before paging is allowed again
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected bool PagingDisabled;
|
public bool PagingDisabled;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Index of the currently paged ROM
|
/// Index of the currently paged ROM
|
||||||
|
@ -87,6 +87,11 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected int PagingConfiguration;
|
protected int PagingConfiguration;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The last byte that was read after contended cycles
|
||||||
|
/// </summary>
|
||||||
|
public byte LastContendedReadByte;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Memory Related Methods
|
#region Memory Related Methods
|
||||||
|
|
|
@ -357,11 +357,13 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
ser.Sync("PagingConfiguration", ref PagingConfiguration);
|
ser.Sync("PagingConfiguration", ref PagingConfiguration);
|
||||||
ser.Sync("ROMhigh", ref ROMhigh);
|
ser.Sync("ROMhigh", ref ROMhigh);
|
||||||
ser.Sync("ROMlow", ref ROMlow);
|
ser.Sync("ROMlow", ref ROMlow);
|
||||||
|
ser.Sync("LastContendedReadByte", ref LastContendedReadByte);
|
||||||
|
|
||||||
KeyboardDevice.SyncState(ser);
|
KeyboardDevice.SyncState(ser);
|
||||||
BuzzerDevice.SyncState(ser);
|
BuzzerDevice.SyncState(ser);
|
||||||
TapeBuzzer.SyncState(ser);
|
TapeBuzzer.SyncState(ser);
|
||||||
ULADevice.SyncState(ser);
|
ULADevice.SyncState(ser);
|
||||||
|
CPUMon.SyncState(ser);
|
||||||
|
|
||||||
if (AYDevice != null)
|
if (AYDevice != null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -667,12 +667,31 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generates the port lookup table for +2a/+3 allowed floating bus ports
|
||||||
|
/// </summary>
|
||||||
|
public void GenerateP3PortTable()
|
||||||
|
{
|
||||||
|
List<ushort> table = new List<ushort>();
|
||||||
|
for (int i = 0; i < 0x1000; i++)
|
||||||
|
{
|
||||||
|
ushort r = (ushort)(1 + (4 * i));
|
||||||
|
if (r > 4093)
|
||||||
|
break;
|
||||||
|
table.Add(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
Plus3FBPortTable = table.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ushort[] Plus3FBPortTable = new ushort[1];
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns floating bus value (if available)
|
/// Returns floating bus value (if available)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="tstate"></param>
|
/// <param name="tstate"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public void ReadFloatingBus(int tstate, ref int result)
|
public void ReadFloatingBus(int tstate, ref int result, ushort port)
|
||||||
{
|
{
|
||||||
tstate += FloatingBusOffset;
|
tstate += FloatingBusOffset;
|
||||||
if (tstate >= RenderingTable.Renderer.Length)
|
if (tstate >= RenderingTable.Renderer.Length)
|
||||||
|
@ -688,13 +707,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
case MachineType.ZXSpectrum48:
|
case MachineType.ZXSpectrum48:
|
||||||
case MachineType.ZXSpectrum128:
|
case MachineType.ZXSpectrum128:
|
||||||
case MachineType.ZXSpectrum128Plus2:
|
case MachineType.ZXSpectrum128Plus2:
|
||||||
/*
|
|
||||||
if (item.FloatingBusAddress > 0)
|
|
||||||
{
|
|
||||||
result = _machine.FetchScreenMemory(item.FloatingBusAddress);
|
|
||||||
//result = 0x00;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
switch (item.RAction)
|
switch (item.RAction)
|
||||||
{
|
{
|
||||||
case RenderTable.RenderAction.BorderAndFetchByte1:
|
case RenderTable.RenderAction.BorderAndFetchByte1:
|
||||||
|
@ -708,15 +721,46 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
result = _machine.FetchScreenMemory(item.AttributeAddress);
|
result = _machine.FetchScreenMemory(item.AttributeAddress);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
//result = _machine.FetchScreenMemory(fetchA2);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MachineType.ZXSpectrum128Plus2a:
|
case MachineType.ZXSpectrum128Plus2a:
|
||||||
case MachineType.ZXSpectrum128Plus3:
|
case MachineType.ZXSpectrum128Plus3:
|
||||||
|
|
||||||
|
// http://sky.relative-path.com/zx/floating_bus.html
|
||||||
|
if (_machine.PagingDisabled)
|
||||||
|
{
|
||||||
|
result = 0xff;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check whether fb is found on this port
|
||||||
|
ushort pLook = Array.Find(Plus3FBPortTable, s => s == port);
|
||||||
|
if (pLook == 0)
|
||||||
|
{
|
||||||
|
result = 0xff;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// floating bus on +2a/+3 always returns a byte with Bit0 set
|
||||||
|
switch (item.RAction)
|
||||||
|
{
|
||||||
|
case RenderTable.RenderAction.BorderAndFetchByte1:
|
||||||
|
case RenderTable.RenderAction.Shift1AndFetchByte2:
|
||||||
|
case RenderTable.RenderAction.Shift2AndFetchByte1:
|
||||||
|
result = (byte)(_machine.FetchScreenMemory(item.ByteAddress) | 0x01);
|
||||||
|
break;
|
||||||
|
case RenderTable.RenderAction.BorderAndFetchAttribute1:
|
||||||
|
case RenderTable.RenderAction.Shift1AndFetchAttribute2:
|
||||||
|
case RenderTable.RenderAction.Shift2AndFetchAttribute1:
|
||||||
|
result = (byte)(_machine.FetchScreenMemory(item.AttributeAddress) | 0x01);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result = (byte)(_machine.LastContendedReadByte | 0x01);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
// -asni (2018-06-08) - need this to pass the final portread tests from fusetest.tap
|
// -asni (2018-06-08) - need this to pass the final portread tests from fusetest.tap
|
||||||
|
|
||||||
// get the floating bus value
|
// get the floating bus value
|
||||||
ULADevice.ReadFloatingBus((int)CurrentFrameCycle, ref result);
|
ULADevice.ReadFloatingBus((int)CurrentFrameCycle, ref result, port);
|
||||||
// use this to set the paging registers
|
// use this to set the paging registers
|
||||||
WritePort(port, (byte)result);
|
WritePort(port, (byte)result);
|
||||||
// return the floating bus value
|
// return the floating bus value
|
||||||
|
@ -71,7 +71,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
if (!deviceAddressed)
|
if (!deviceAddressed)
|
||||||
{
|
{
|
||||||
// If this is an unused port the floating memory bus should be returned
|
// If this is an unused port the floating memory bus should be returned
|
||||||
ULADevice.ReadFloatingBus((int)CurrentFrameCycle, ref result);
|
ULADevice.ReadFloatingBus((int)CurrentFrameCycle, ref result, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (byte)result;
|
return (byte)result;
|
||||||
|
|
|
@ -358,6 +358,12 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
public override byte ReadMemory(ushort addr)
|
public override byte ReadMemory(ushort addr)
|
||||||
{
|
{
|
||||||
var data = ReadBus(addr);
|
var data = ReadBus(addr);
|
||||||
|
if (CPUMon.NextMemReadContended)
|
||||||
|
{
|
||||||
|
LastContendedReadByte = data;
|
||||||
|
CPUMon.NextMemReadContended = false;
|
||||||
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
if (!deviceAddressed)
|
if (!deviceAddressed)
|
||||||
{
|
{
|
||||||
// If this is an unused port the floating memory bus should be returned
|
// If this is an unused port the floating memory bus should be returned
|
||||||
ULADevice.ReadFloatingBus((int)CurrentFrameCycle, ref result);
|
ULADevice.ReadFloatingBus((int)CurrentFrameCycle, ref result, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (byte)result;
|
return (byte)result;
|
||||||
|
|
|
@ -19,7 +19,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
// offsets
|
// offsets
|
||||||
RenderTableOffset = 58;
|
RenderTableOffset = 58;
|
||||||
ContentionOffset = 9;
|
ContentionOffset = 9;
|
||||||
FloatingBusOffset = 1;
|
FloatingBusOffset = 0;
|
||||||
// timing
|
// timing
|
||||||
ClockSpeed = 3546900;
|
ClockSpeed = 3546900;
|
||||||
FrameCycleLength = 70908;
|
FrameCycleLength = 70908;
|
||||||
|
@ -43,6 +43,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
MachineType.ZXSpectrum128Plus2a);
|
MachineType.ZXSpectrum128Plus2a);
|
||||||
|
|
||||||
SetupScreenSize();
|
SetupScreenSize();
|
||||||
|
|
||||||
|
GenerateP3PortTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
@ -358,6 +358,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
public override byte ReadMemory(ushort addr)
|
public override byte ReadMemory(ushort addr)
|
||||||
{
|
{
|
||||||
var data = ReadBus(addr);
|
var data = ReadBus(addr);
|
||||||
|
if (CPUMon.NextMemReadContended)
|
||||||
|
LastContendedReadByte = data;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
if (!deviceAddressed)
|
if (!deviceAddressed)
|
||||||
{
|
{
|
||||||
// If this is an unused port the floating memory bus should be returned
|
// If this is an unused port the floating memory bus should be returned
|
||||||
ULADevice.ReadFloatingBus((int)CurrentFrameCycle, ref result);
|
ULADevice.ReadFloatingBus((int)CurrentFrameCycle, ref result, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (byte)result;
|
return (byte)result;
|
||||||
|
|
|
@ -55,7 +55,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
|
|
||||||
|
|
||||||
// If this is an unused port the floating memory bus should be returned
|
// If this is an unused port the floating memory bus should be returned
|
||||||
ULADevice.ReadFloatingBus((int)CurrentFrameCycle, ref result);
|
ULADevice.ReadFloatingBus((int)CurrentFrameCycle, ref result, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (byte)result;
|
return (byte)result;
|
||||||
|
|
Loading…
Reference in New Issue