diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Port.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Port.cs
index 600a1c259e..d42f7301f9 100644
--- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Port.cs
+++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Port.cs
@@ -24,29 +24,22 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
///
public virtual byte ReadPort(ushort port)
{
- CPU.TotalExecutedCycles += 4;
-
int result = 0xFF;
- // get the high byte from Regs[6]
- ushort high = CPU.Regs[6];
-
- // combine the low byte (passed in as port) and the high byte (maybe not needed)
- //ushort word = Convert.ToUInt16((port << 8 | high));
-
- int word = (high << 8) + port;
-
- //port += (ushort)(CPU.Regs[CPU.A] << 8);
-
// Check whether the low bit is reset
// Technically the ULA should respond to every even I/O address
- bool lowBitReset = (word & 0x0001) == 0;
+ bool lowBitReset = (port & 0x0001) == 0;
+
+ ContendPort((ushort)port);
+
// Kempston Joystick
- //not implemented yet
+ if (port == 0x1f)
+ {
- if (port == 254)
- {
+ }
+ else if (lowBitReset)
+ {
// Even I/O address so get input
// The high byte indicates which half-row of keys is being polled
/*
@@ -57,6 +50,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
0xf7fe 1, 2, 3, 4, 5 0x7ffe SPACE, SYM SHFT, M, N, B
*/
+ result &= KeyboardDevice.GetLineStatus((byte)(port >> 8));
+ /*
if (high == 0xfe)
result &= KeyboardDevice.KeyLine[0];
if (high == 0xfd)
@@ -73,7 +68,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
result &= KeyboardDevice.KeyLine[6];
if (high == 0x7f)
result &= KeyboardDevice.KeyLine[7];
-
+*/
result = result & 0x1f; //mask out lower 4 bits
result = result | 0xa0; //set bit 5 & 7 to 1
@@ -150,11 +145,11 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
///
public virtual void WritePort(ushort port, byte value)
{
- CPU.TotalExecutedCycles += 4;
-
// Check whether the low bit is reset
// Technically the ULA should respond to every even I/O address
- bool lowBitReset = (port & 0x0001) == 0;
+ bool lowBitReset = (port & 0x01) == 0;
+
+ ContendPort(port);
// Only even addresses address the ULA
if (lowBitReset)
@@ -179,5 +174,28 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
TapeDevice.ProcessMicBit((value & MIC_BIT) != 0);
}
}
+
+ ///
+ /// Apply I/O contention if necessary
+ ///
+ ///
+ public virtual void ContendPort(ushort port)
+ {
+ var lowBit = (port & 0x0001) != 0;
+ var ulaHigh = (port & 0xc000) == 0x4000;
+ var cfc = CurrentFrameCycle;
+ if (cfc < 1)
+ cfc = 1;
+
+ if (ulaHigh)
+ {
+ CPU.TotalExecutedCycles += GetContentionValue(cfc - 1);
+ }
+ else
+ {
+ if (!lowBit)
+ CPU.TotalExecutedCycles += GetContentionValue(cfc);
+ }
+ }
}
}
diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum48K/ZX48.Keyboard.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum48K/ZX48.Keyboard.cs
index 096408a101..afa886675a 100644
--- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum48K/ZX48.Keyboard.cs
+++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum48K/ZX48.Keyboard.cs
@@ -273,8 +273,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
}
public byte GetLineStatus(byte lines)
- {
-
+ {
lock(this)
{
byte status = 0;
@@ -287,7 +286,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
lineIndex++;
lines >>= 1;
}
- var result = (byte)~status;
+ var result = (byte)status;
return result;
}