diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/CPUMonitor.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/CPUMonitor.cs index 5890279f31..9708236f5d 100644 --- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/CPUMonitor.cs +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/CPUMonitor.cs @@ -237,10 +237,66 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum switch (machineType) { case MachineType.ZXSpectrum16: - case MachineType.ZXSpectrum48: + case MachineType.ZXSpectrum48: + + if ((lastPortAddr & 0xc000) == 0x4000) + highByte407f = true; + + if (highByte407f) + { + // high byte 40-7f + if (lowBitSet) + { + // high byte 40-7f + // low bit set + // C:1, C:1, C:1, C:1 + switch (T) + { + case 1: + case 2: + case 3: + case 4: + return true; + } + } + else + { + // high byte 40-7f + // low bit reset + // C:1, C:3 + switch (T) + { + case 1: + case 2: + return true; + } + } + } + else + { + // high byte not 40-7f + if (lowBitSet) + { + // high byte not 40-7f + // low bit set + // N:4 + } + else + { + // high byte not 40-7f + // low bit reset + // N:1, C:3 + switch (T) + { + case 2: + return true; + } + } + } + break; + case MachineType.ZXSpectrum128: case MachineType.ZXSpectrum128Plus2: - if ((lastPortAddr & 0xc000) == 0x4000) highByte407f = true; @@ -299,6 +355,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum case MachineType.ZXSpectrum128Plus2a: case MachineType.ZXSpectrum128Plus3: + // No contention occurs as the ULA only applies contention when the Z80 MREQ line is active + // (which is not during an IO operation) break; } diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ULA.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ULA.cs index e953e2a9e0..0bec3a194c 100644 --- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ULA.cs +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ULA.cs @@ -88,6 +88,16 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum /// public int InterruptLength; + /// + /// Arbitrary offset into the contention array (for memory ops) + /// + public int MemoryContentionOffset; + + /// + /// Arbitrary offset into the contention array (for port ops) + /// + public int PortContentionOffset; + /// /// The time in T-States for one scanline to complete /// @@ -776,8 +786,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum /// public int GetContentionValue(int tstate) { - int off = 5; - tstate += off; + tstate += MemoryContentionOffset; if (tstate >= FrameCycleLength) tstate -= FrameCycleLength; @@ -793,8 +802,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum /// public int GetPortContentionValue(int tstate) { - int off = 5; - tstate += off; + tstate += PortContentionOffset; if (tstate >= FrameCycleLength) tstate -= FrameCycleLength; diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128K/ZX128.Screen.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128K/ZX128.Screen.cs index cbd98f1128..547e0fab72 100644 --- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128K/ZX128.Screen.cs +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128K/ZX128.Screen.cs @@ -20,6 +20,9 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum InterruptLength = 36; ScanlineTime = 228; + MemoryContentionOffset = 5; + PortContentionOffset = 5; + BorderLeftTime = 24; BorderRightTime = 24; diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus2a/ZX128Plus2a.Screen.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus2a/ZX128Plus2a.Screen.cs index e9026ce5d7..949ca558ce 100644 --- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus2a/ZX128Plus2a.Screen.cs +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus2a/ZX128Plus2a.Screen.cs @@ -20,6 +20,9 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum InterruptLength = 32; ScanlineTime = 228; + MemoryContentionOffset = 7; + PortContentionOffset = 7; + BorderLeftTime = 24; BorderRightTime = 24; diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum48K/ZX48.Screen.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum48K/ZX48.Screen.cs index 96219e04db..5af98f944a 100644 --- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum48K/ZX48.Screen.cs +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum48K/ZX48.Screen.cs @@ -20,6 +20,9 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum InterruptLength = 32; ScanlineTime = 224; + MemoryContentionOffset = 5; + PortContentionOffset = 5; + BorderLeftTime = 24; BorderRightTime = 24;