ZXHawk: start preparing 128k and +2a/+3 for updating timings

This commit is contained in:
Asnivor 2018-06-06 15:56:27 +01:00
parent c80f873adf
commit 535534a94a
10 changed files with 11 additions and 367 deletions

View File

@ -155,11 +155,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
return value;
}
/// <summary>
/// Contends memory if necessary
/// </summary>
public abstract void ContendMemory(ushort addr);
/// <summary>
/// Checks whether supplied address is in a potentially contended bank
/// </summary>

View File

@ -50,7 +50,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
/// This method is for 48k and 128k/+2 machines only and should be overridden for other models
/// </summary>
/// <param name="addr"></param>
public abstract void ContendPort(ushort addr);
//public abstract void ContendPort(ushort addr);
}
}

View File

@ -185,8 +185,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
/// <returns></returns>
public override byte ReadMemory(ushort addr)
{
ContendMemory(addr);
var data = ReadBus(addr);
return data;
}
@ -199,28 +197,9 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
/// <param name="value"></param>
public override void WriteMemory(ushort addr, byte value)
{
// update ULA screen buffer if necessary BEFORE T1 write
if (((addr & 49152) == 16384 || ((addr & 0xc000) == 0xc000) && (RAMPaged == 5 || RAMPaged == 7)) && _render)
ULADevice.RenderScreen((int)CurrentFrameCycle);
ContendMemory(addr);
WriteBus(addr, value);
}
/// <summary>
/// Contends memory if necessary
/// </summary>
public override void ContendMemory(ushort addr)
{
/*
if (IsContended(addr))
{
var delay = ULADevice.GetContentionValue((int)CurrentFrameCycle);
CPU.TotalExecutedCycles += delay;
}
*/
}
/// <summary>
/// Checks whether supplied address is in a potentially contended bank
/// </summary>

View File

@ -18,9 +18,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
{
bool deviceAddressed = true;
// process IO contention
ContendPort(port);
int result = 0xFF;
// check AY
@ -53,29 +50,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
if (!deviceAddressed)
{
// If this is an unused port the floating memory bus should be returned
// Floating bus is read on the previous cycle
long _tStates = CurrentFrameCycle - 1;
ULADevice.ReadFloatingBus((int)_tStates, ref result);
/*
// if we are on the top or bottom border return 0xff
if ((_tStates < ULADevice.contentionStartPeriod) || (_tStates > ULADevice.contentionEndPeriod))
{
result = 0xff;
}
else
{
if (ULADevice.floatingBusTable[_tStates] < 0)
{
result = 0xff;
}
else
{
result = ReadBus((ushort)ULADevice.floatingBusTable[_tStates]);
}
}
*/
ULADevice.ReadFloatingBus((int)CurrentFrameCycle, ref result);
}
return (byte)result;
@ -88,9 +63,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
/// <param name="value"></param>
public override void WritePort(ushort port, byte value)
{
// process IO contention
ContendPort(port);
// get a BitArray of the port
BitArray portBits = new BitArray(BitConverter.GetBytes(port));
// get a BitArray of the value byte
@ -146,7 +118,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
{
// store the last OUT byte
LastULAOutByte = value;
CPU.TotalExecutedCycles += ULADevice.GetContentionValue();
/*
Bit 7 6 5 4 3 2 1 0
@ -156,9 +127,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
*/
// Border - LSB 3 bits hold the border colour
if (ULADevice.BorderColor != (value & BORDER_BIT))
ULADevice.RenderScreen((int)CurrentFrameCycle);
ULADevice.BorderColor = value & BORDER_BIT;
// Buzzer
@ -169,15 +137,5 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
//TapeDevice.ProcessMicBit((value & MIC_BIT) != 0);
}
}
/// <summary>
/// Contend port if necessary
/// </summary>
/// <param name="addr"></param>
public override void ContendPort(ushort addr)
{
//CPUMon.ContendPort(addr);
return;
}
}
}

View File

@ -341,10 +341,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
break;
}
}
// update ULA screen buffer if necessary
if ((addr & 49152) == 16384 && _render)
ULADevice.RenderScreen((int)CurrentFrameCycle);
}
/// <summary>
@ -355,8 +351,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
/// <returns></returns>
public override byte ReadMemory(ushort addr)
{
ContendMemory(addr);
var data = ReadBus(addr);
return data;
}
@ -370,6 +364,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
public override void WriteMemory(ushort addr, byte value)
{
// update ULA screen buffer if necessary BEFORE T1 write
/*
if (!SpecialPagingMode)
{
if (((addr & 49152) == 16384 || ((addr & 0xc000) == 0xc000) && (RAMPaged == 5 || RAMPaged == 7)) && _render)
@ -390,23 +385,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
break;
}
}
ContendMemory(addr);
WriteBus(addr, value);
}
/// <summary>
/// Contends memory if necessary
/// </summary>
public override void ContendMemory(ushort addr)
{
/*
if (IsContended(addr))
{
var delay = ULADevice.GetContentionValue((int)CurrentFrameCycle);
CPU.TotalExecutedCycles += delay;
}
*/
WriteBus(addr, value);
}
/// <summary>

View File

@ -18,9 +18,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
{
bool deviceAddressed = true;
// process IO contention
ContendPort(port);
int result = 0xFF;
// check AY
@ -53,102 +50,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
if (!deviceAddressed)
{
// If this is an unused port the floating memory bus should be returned
// Floating bus is read on the previous cycle
long _tStates = CurrentFrameCycle - 1;
ULADevice.ReadFloatingBus((int)_tStates, ref result);
/*
// if we are on the top or bottom border return 0xff
if ((_tStates < ULADevice.contentionStartPeriod) || (_tStates > ULADevice.contentionEndPeriod))
{
result = 0xff;
}
else
{
if (ULADevice.floatingBusTable[_tStates] < 0)
{
result = 0xff;
}
else
{
result = ReadBus((ushort)ULADevice.floatingBusTable[_tStates]);
}
}
*/
ULADevice.ReadFloatingBus((int)CurrentFrameCycle, ref result);
}
/*
// Check whether the low bit is reset
// Technically the ULA should respond to every even I/O address
bool lowBitReset = (port & 0x0001) == 0;
// Kempston joystick input takes priority over all other input
// if this is detected just return the kempston byte
if ((port & 0xe0) == 0 || (port & 0x20) == 0)
{
if (LocateUniqueJoystick(JoystickType.Kempston) != null)
return (byte)((KempstonJoystick)LocateUniqueJoystick(JoystickType.Kempston) as KempstonJoystick).JoyLine;
InputRead = true;
}
else if (lowBitReset)
{
// Even I/O address so get input from keyboard
KeyboardDevice.ReadPort(port, ref result);
TapeDevice.MonitorRead();
// not a lagframe
InputRead = true;
// tape loading monitor cycle
//TapeDevice.MonitorRead();
// process tape INs
TapeDevice.ReadPort(port, ref result);
}
else
{
// devices other than the ULA will respond here
// (e.g. the AY sound chip in a 128k spectrum
// AY register activate - on +3/2a both FFFD and BFFD active AY
if ((port & 0xc002) == 0xc000)
{
result = (int)AYDevice.PortRead();
}
else if ((port & 0xc002) == 0x8000)
{
result = (int)AYDevice.PortRead();
}
// Kempston Mouse
/*
else if ((port & 0xF002) == 0x2000) //Is bit 12 set and bits 13,14,15 and 1 reset?
{
//result = udpDrive.DiskStatusRead();
// disk drive is not yet implemented - return a max status byte for the menu to load
result = 255;
}
else if ((port & 0xF002) == 0x3000)
{
//result = udpDrive.DiskReadByte();
result = 0;
}
else if ((port & 0xF002) == 0x0)
{
if (PagingDisabled)
result = 0x1;
else
result = 0xff;
}
*//*
// if unused port the floating memory bus should be returned (still todo)
}
*/
return (byte)result;
}
@ -160,9 +63,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
/// <param name="value"></param>
public override void WritePort(ushort port, byte value)
{
// process IO contention
ContendPort(port);
// get a BitArray of the port
BitArray portBits = new BitArray(BitConverter.GetBytes(port));
// get a BitArray of the value byte
@ -244,9 +144,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
*/
// Border - LSB 3 bits hold the border colour
if (ULADevice.BorderColor != (value & BORDER_BIT))
ULADevice.RenderScreen((int)CurrentFrameCycle);
ULADevice.BorderColor = value & BORDER_BIT;
// Buzzer
@ -282,15 +179,5 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
}
set { ROMPaged = value; }
}
/// <summary>
/// Contend port if necessary
/// </summary>
/// <param name="addr"></param>
public override void ContendPort(ushort addr)
{
//CPUMon.ContendPort(addr);
return;
}
}
}

View File

@ -341,10 +341,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
break;
}
}
// update ULA screen buffer if necessary
if ((addr & 49152) == 16384 && _render)
ULADevice.RenderScreen((int)CurrentFrameCycle);
}
/// <summary>
@ -355,8 +351,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
/// <returns></returns>
public override byte ReadMemory(ushort addr)
{
ContendMemory(addr);
var data = ReadBus(addr);
return data;
}
@ -369,6 +363,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
/// <param name="value"></param>
public override void WriteMemory(ushort addr, byte value)
{
/*
// update ULA screen buffer if necessary BEFORE T1 write
if (!SpecialPagingMode)
{
@ -390,23 +385,9 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
break;
}
}
ContendMemory(addr);
WriteBus(addr, value);
}
/// <summary>
/// Contends memory if necessary
/// </summary>
public override void ContendMemory(ushort addr)
{
/*
if (IsContended(addr))
{
var delay = ULADevice.GetContentionValue((int)CurrentFrameCycle);
CPU.TotalExecutedCycles += delay;
}
*/
WriteBus(addr, value);
}
/// <summary>

View File

@ -18,9 +18,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
{
bool deviceAddressed = true;
// process IO contention
ContendPort(port);
int result = 0xFF;
// check AY
@ -57,30 +54,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
if (!deviceAddressed)
{
// If this is an unused port the floating memory bus should be returned
// Floating bus is read on the previous cycle
long _tStates = CurrentFrameCycle - 1;
ULADevice.ReadFloatingBus((int)_tStates, ref result);
/*
// if we are on the top or bottom border return 0xff
if ((_tStates < ULADevice.contentionStartPeriod) || (_tStates > ULADevice.contentionEndPeriod))
{
result = 0xff;
}
else
{
if (ULADevice.floatingBusTable[_tStates] < 0)
{
result = 0xff;
}
else
{
result = ReadBus((ushort)ULADevice.floatingBusTable[_tStates]);
}
}
*/
ULADevice.ReadFloatingBus((int)CurrentFrameCycle, ref result);
}
return (byte)result;
@ -93,9 +67,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
/// <param name="value"></param>
public override void WritePort(ushort port, byte value)
{
// process IO contention
ContendPort(port);
// get a BitArray of the port
BitArray portBits = new BitArray(BitConverter.GetBytes(port));
// get a BitArray of the value byte
@ -179,9 +150,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
*/
// Border - LSB 3 bits hold the border colour
if (ULADevice.BorderColor != (value & BORDER_BIT))
ULADevice.RenderScreen((int)CurrentFrameCycle);
ULADevice.BorderColor = value & BORDER_BIT;
// Buzzer
@ -217,15 +185,5 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
}
set { ROMPaged = value; }
}
/// <summary>
/// Contend port if necessary
/// </summary>
/// <param name="addr"></param>
public override void ContendPort(ushort addr)
{
//CPUMon.ContendPort(addr);
return;
}
}
}

View File

@ -96,7 +96,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
/// <returns></returns>
public override byte ReadMemory(ushort addr)
{
ContendMemory(addr);
var data = ReadBus(addr);
return data;
}
@ -108,41 +107,10 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
/// <param name="addr"></param>
/// <param name="value"></param>
public override void WriteMemory(ushort addr, byte value)
{
// update ULA screen buffer if necessary BEFORE T1 write
//if ((addr & 49152) == 16384 && _render)
//ULADevice.RenderScreen((int)CurrentFrameCycle);
ContendMemory(addr);
{
WriteBus(addr, value);
}
/// <summary>
/// Contends memory if necessary
/// </summary>
public override void ContendMemory(ushort addr)
{
return;
/*
if (IsContended(addr))
{
var off = 1;
var offset = CurrentFrameCycle + off;
if (offset < 0)
offset += ULADevice.FrameCycleLength;
if (offset >= ULADevice.FrameCycleLength)
offset -= ULADevice.FrameCycleLength;
var delay = ULADevice.GetContentionValue((int)offset);
if (delay > 0)
{
}
CPU.TotalExecutedCycles += delay;
}
*/
}
/// <summary>
/// Checks whether supplied address is in a potentially contended bank
/// </summary>

View File

@ -15,9 +15,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
/// <returns></returns>
public override byte ReadPort(ushort port)
{
// process IO contention
ContendPort(port);
int result = 0xFF;
// Check whether the low bit is reset
@ -56,29 +53,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
// If this is an unused port the floating memory bus should be returned
ULADevice.ReadFloatingBus((int)CurrentFrameCycle, ref result);
/*
// Floating bus is read on the previous cycle
long _tStates = CurrentFrameCycle - 1;
// if we are on the top or bottom border return 0xff
if ((_tStates < ULADevice.contentionStartPeriod) || (_tStates > ULADevice.contentionEndPeriod))
{
result = 0xff;
}
else
{
if (ULADevice.floatingBusTable[_tStates] < 0)
{
result = 0xff;
}
else
{
result = ReadBus((ushort)ULADevice.floatingBusTable[_tStates]);
}
}
*/
ULADevice.ReadFloatingBus((int)CurrentFrameCycle, ref result);
}
return (byte)result;
@ -91,9 +66,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
/// <param name="value"></param>
public override void WritePort(ushort port, byte value)
{
// process IO contention
ContendPort(port);
// Check whether the low bit is reset
// Technically the ULA should respond to every even I/O address
if ((port & 0x0001) != 0)
@ -124,39 +96,5 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
}
/// <summary>
/// Simulates IO port contention based on the supplied address
/// This method is for 48k and 128k/+2 machines only and should be overridden for other models
/// </summary>
/// <param name="addr"></param>
public override void ContendPort(ushort addr)
{
/*
It takes four T states for the Z80 to read a value from an I/O port, or write a value to a port. As is the case with memory access,
this can be lengthened by the ULA. There are two effects which occur here:
If the port address being accessed has its low bit reset, the ULA is required to supply the result, which leads to a delay if it is
currently busy handling the screen.
The address of the port being accessed is placed on the data bus. If this is in the range 0x4000 to 0x7fff, the ULA treats this as an
attempted access to contended memory and therefore introduces a delay. If the port being accessed is between 0xc000 and 0xffff,
this effect does not apply, even on a 128K machine if a contended memory bank is paged into the range 0xc000 to 0xffff.
These two effects combine to lead to the following contention patterns:
High byte | |
in 40 - 7F? | Low bit | Contention pattern
------------+---------+-------------------
No | Reset | N:1, C:3
No | Set | N:4
Yes | Reset | C:1, C:3
Yes | Set | C:1, C:1, C:1, C:1
The 'Contention pattern' column should be interpreted from left to right. An "N:n" entry means that no delay is applied at this cycle, and the Z80 continues uninterrupted for 'n' T states. A "C:n" entry means that the ULA halts the Z80; the delay is exactly the same as would occur for a contended memory access at this cycle (eg 6 T states at cycle 14335, 5 at 14336, etc on the 48K machine). After this delay, the Z80 then continues for 'n' cycles.
*/
//CPUMon.ContendPort(addr);
return;
}
}
}