diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Datacorder/DatacorderDevice.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Datacorder/DatacorderDevice.cs index 0227fee185..be338e7fb2 100644 --- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Datacorder/DatacorderDevice.cs +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Datacorder/DatacorderDevice.cs @@ -120,12 +120,18 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum /// Signs whether the device should autodetect when the Z80 has entered into /// 'load' mode and auto-play the tape if neccesary /// - public bool AutoPlay { get; set; } + private bool _autoPlay; + public bool AutoPlay + { + get { return _machine.Spectrum.Settings.AutoLoadTape; } + set { _autoPlay = value; MonitorReset(); } + } + #endregion #region Emulator - + /// /// This is the address the that ROM will jump to when the spectrum has quit tape playing /// @@ -138,7 +144,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum /// Primary purpose is to detect tape traps and manage auto play (if/when this is ever implemented) /// public void EndFrame() - { + {/* if (TapeIsPlaying) { @@ -172,6 +178,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum } } */ + + MonitorFrame(); } /// @@ -302,7 +310,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum // update the lastCycle _lastCycle = _cpu.TotalExecutedCycles; - } /// @@ -419,9 +426,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum #endregion #region Tape Device Methods - - private bool initialBlockPlayed = false; - + /// /// Simulates the spectrum 'EAR' input reading data from the tape /// @@ -582,6 +587,105 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum #endregion + #region TapeMonitor + + private long _lastINCycle = 0; + private int _monitorCount; + private int _monitorTimeOut; + private ushort _monitorLastPC; + private ushort[] _monitorLastRegs = new ushort[7]; + + /// + /// Resets the TapeMonitor + /// + private void MonitorReset() + { + _lastINCycle = 0; + _monitorCount = 0; + _monitorLastPC = 0; + _monitorLastRegs = null; + } + + /// + /// An iteration of the monitor process + /// + public void MonitorRead() + { + long cpuCycle = _cpu.TotalExecutedCycles; + int delta = (int)(cpuCycle - _lastINCycle); + _lastINCycle = cpuCycle; + + var nRegs = new ushort[] + { + _cpu.Regs[_cpu.A], + _cpu.Regs[_cpu.B], + _cpu.Regs[_cpu.C], + _cpu.Regs[_cpu.D], + _cpu.Regs[_cpu.E], + _cpu.Regs[_cpu.H], + _cpu.Regs[_cpu.L] + }; + + if (delta > 0 && + delta < 96 && + _cpu.RegPC == _monitorLastPC && + _monitorLastRegs != null) + { + int dCnt = 0; + int dVal = 0; + + for (int i = 0; i < nRegs.Length; i++) + { + if (_monitorLastRegs[i] != nRegs[i]) + { + dVal = _monitorLastRegs[i] - nRegs[i]; + dCnt++; + } + } + + if (dCnt == 1 && + (dVal == 1 || dVal == -1)) + { + _monitorCount++; + + if (_monitorCount >= 8 && _machine.Spectrum.Settings.AutoLoadTape) + { + if (!_tapeIsPlaying) + { + Play(); + _machine.Spectrum.OSD_TapePlayingAuto(); + } + + _monitorTimeOut = 50; + } + } + else + { + _monitorCount = 0; + } + } + + _monitorLastRegs = nRegs; + _monitorLastPC = _cpu.RegPC; + } + + + private void MonitorFrame() + { + if (_tapeIsPlaying && _machine.Spectrum.Settings.AutoLoadTape) + { + _monitorTimeOut--; + + if (_monitorTimeOut < 0) + { + Stop(); + _machine.Spectrum.OSD_TapeStoppedAuto(); + } + } + } + + #endregion + #region State Serialization private int _tempBlockCount; @@ -593,39 +697,17 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum public void SyncState(Serializer ser) { ser.BeginSection("DatacorderDevice"); - ser.Sync("_currentDataBlockIndex", ref _currentDataBlockIndex); ser.Sync("_position", ref _position); ser.Sync("_tapeIsPlaying", ref _tapeIsPlaying); ser.Sync("_lastCycle", ref _lastCycle); ser.Sync("_waitEdge", ref _waitEdge); - //ser.Sync("_initialBlockPlayed", ref initialBlockPlayed); ser.Sync("currentState", ref currentState); - - //_dataBlocks - /* - ser.BeginSection("Datablocks"); - - if (ser.IsWriter) - { - _tempBlockCount = _dataBlocks.Count(); - ser.Sync("_tempBlockCount", ref _tempBlockCount); - - for (int i = 0; i < _tempBlockCount; i++) - { - _dataBlocks[i].SyncState(ser, i); - } - } - else - { - ser.Sync("_tempBlockCount", ref _tempBlockCount); - } - - - - ser.EndSection(); - */ - + ser.Sync("_lastINCycle", ref _lastINCycle); + ser.Sync("_monitorCount", ref _monitorCount); + ser.Sync("_monitorTimeOut", ref _monitorTimeOut); + ser.Sync("_monitorLastPC", ref _monitorLastPC); + ser.Sync("_monitorLastRegs", ref _monitorLastRegs, false); ser.EndSection(); } diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128K/ZX128.Port.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128K/ZX128.Port.cs index 434f4c7cfa..5ef01f9504 100644 --- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128K/ZX128.Port.cs +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128K/ZX128.Port.cs @@ -96,6 +96,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum result = result & 0x1f; //mask out lower 4 bits result = result | 0xa0; //set bit 5 & 7 to 1 + TapeDevice.MonitorRead(); if (TapeDevice.TapeIsPlaying)//.CurrentMode == TapeOperationMode.Load) { diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus2a/ZX128Plus2a.Port.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus2a/ZX128Plus2a.Port.cs index 07e22b4203..c29876cc3c 100644 --- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus2a/ZX128Plus2a.Port.cs +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus2a/ZX128Plus2a.Port.cs @@ -89,6 +89,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum result = result & 0x1f; //mask out lower 4 bits result = result | 0xa0; //set bit 5 & 7 to 1 + TapeDevice.MonitorRead(); if (TapeDevice.TapeIsPlaying)//.CurrentMode == TapeOperationMode.Load) { diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus3/ZX128Plus3.Port.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus3/ZX128Plus3.Port.cs index ea53156118..eb8ff18e36 100644 --- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus3/ZX128Plus3.Port.cs +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus3/ZX128Plus3.Port.cs @@ -90,6 +90,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum result = result | 0xa0; //set bit 5 & 7 to 1 + TapeDevice.MonitorRead(); + if (TapeDevice.TapeIsPlaying)//.CurrentMode == TapeOperationMode.Load) { if (!TapeDevice.GetEarBit(CPU.TotalExecutedCycles)) diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum48K/ZX48.Port.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum48K/ZX48.Port.cs index 2c7db07cbd..5dc5c2a514 100644 --- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum48K/ZX48.Port.cs +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum48K/ZX48.Port.cs @@ -95,6 +95,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum result = result & 0x1f; //mask out lower 4 bits result = result | 0xa0; //set bit 5 & 7 to 1 + TapeDevice.MonitorRead(); if (TapeDevice.TapeIsPlaying)//.CurrentMode == TapeOperationMode.Load) {