diff --git a/Assets/defctrl.json b/Assets/defctrl.json index c2bb94b42b..dace0123e0 100644 --- a/Assets/defctrl.json +++ b/Assets/defctrl.json @@ -532,7 +532,8 @@ "Insert Next Tape": "F6", "Insert Previous Tape": "F5", "Next Tape Block": "F8", - "Prev Tape Block": "F7" + "Prev Tape Block": "F7", + "Get Tape Status": "F10" }, "Intellivision Controller": { "P1 Up": "UpArrow, J1 POV1U, X1 DpadUp, X1 LStickUp", diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Datacorder/DatacorderDevice.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Datacorder/DatacorderDevice.cs index 29a746b880..88d5f844f3 100644 --- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Datacorder/DatacorderDevice.cs +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Datacorder/DatacorderDevice.cs @@ -137,8 +137,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum /// public const ushort ERROR_ROM_ADDRESS = 0x0008; - Stopwatch sw = new Stopwatch(); - /// /// Should be fired at the end of every frame /// Primary purpose is to detect tape traps and manage auto play (if/when this is ever implemented) @@ -373,6 +371,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum // decide how many cycles worth of data we are capturing long cycles = cpuCycle - _lastCycle; + bool is48k = _machine.IsIn48kMode(); + // check whether tape is actually playing if (_tapeIsPlaying == false) { @@ -398,11 +398,11 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum // flip the current state currentState = !currentState; - if (_position == 0) + if (_position == 0 && _tapeIsPlaying) { // start of block - // notify about the current block + // notify about the current block var bl = _dataBlocks[_currentDataBlockIndex]; StringBuilder sbd = new StringBuilder(); @@ -427,47 +427,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum { // we have reached the end of the current block - // check for any commands - var command = _dataBlocks[_currentDataBlockIndex].Command; - var block = _dataBlocks[_currentDataBlockIndex]; - switch (command) - { - // Stop the tape command found - if this is the end of the tape RTZ - // otherwise just STOP and move to the next block - case TapeCommand.STOP_THE_TAPE: - - _machine.Spectrum.OSD_TapeStoppedAuto(); - - if (_currentDataBlockIndex >= _dataBlocks.Count()) - RTZ(); - else - { - Stop(); - } - break; - case TapeCommand.STOP_THE_TAPE_48K: - - if ((_machine.GetType() != typeof(ZX128) && - _machine.GetType() != typeof(ZX128Plus2) && - _machine.GetType() != typeof(ZX128Plus3)) || - (_machine.GetType() == typeof(ZX128) || - _machine.GetType() != typeof(ZX128Plus2) || - _machine.GetType() != typeof(ZX128Plus3)) && - _machine._ROMpaged == 1) - { - _machine.Spectrum.OSD_TapeStoppedAuto(); - - if (_currentDataBlockIndex >= _dataBlocks.Count()) - RTZ(); - else - { - Stop(); - } - - } - break; - } - if (_dataBlocks[_currentDataBlockIndex].DataPeriods.Count() == 0) { // notify about the current block (we are skipping it because its empty) @@ -487,11 +446,77 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum } - // skip any empty blocks + // skip any empty blocks (and process any command blocks) while (_position >= _dataBlocks[_currentDataBlockIndex].DataPeriods.Count()) - { + { + // check for any commands + var command = _dataBlocks[_currentDataBlockIndex].Command; + var block = _dataBlocks[_currentDataBlockIndex]; + bool shouldStop = false; + switch (command) + { + // Stop the tape command found - if this is the end of the tape RTZ + // otherwise just STOP and move to the next block + case TapeCommand.STOP_THE_TAPE: + + _machine.Spectrum.OSD_TapeStoppedAuto(); + + if (_currentDataBlockIndex >= _dataBlocks.Count()) + RTZ(); + else + { + Stop(); + } + + _monitorTimeOut = 2000; + + break; + case TapeCommand.STOP_THE_TAPE_48K: + if (is48k) + { + _machine.Spectrum.OSD_TapeStoppedAuto(); + + if (_currentDataBlockIndex >= _dataBlocks.Count()) + RTZ(); + else + { + Stop(); + } + + _monitorTimeOut = 2000; + } + /* + if ((_machine.GetType() != typeof(ZX128) && + _machine.GetType() != typeof(ZX128Plus2) && + _machine.GetType() != typeof(ZX128Plus3)) || + (_machine.GetType() == typeof(ZX128) || + _machine.GetType() != typeof(ZX128Plus2) || + _machine.GetType() != typeof(ZX128Plus3)) && + _machine._ROMpaged == 1) + { + _machine.Spectrum.OSD_TapeStoppedAuto(); + + if (_currentDataBlockIndex >= _dataBlocks.Count()) + RTZ(); + else + { + Stop(); + } + + _monitorTimeOut = 2000; + } + */ + break; + } + + if (shouldStop) + break; + _position = 0; _currentDataBlockIndex++; + + + if (_currentDataBlockIndex >= _dataBlocks.Count()) { break; @@ -584,7 +609,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum { _monitorCount++; - if (_monitorCount >= 8 && _machine.Spectrum.Settings.AutoLoadTape) + if (_monitorCount >= 16 && _cpu.RegPC == 1523 && _machine.Spectrum.Settings.AutoLoadTape) { if (!_tapeIsPlaying) { @@ -592,7 +617,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum _machine.Spectrum.OSD_TapePlayingAuto(); } - _monitorTimeOut = 500; + _monitorTimeOut = 90; } } else diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Input.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Input.cs index eb2bcd63a8..bf6a679f15 100644 --- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Input.cs +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Input.cs @@ -17,6 +17,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum string PrevTape = "Insert Previous Tape"; string NextBlock = "Next Tape Block"; string PrevBlock = "Prev Tape Block"; + string TapeStatus = "Get Tape Status"; bool pressed_Play = false; bool pressed_Stop = false; @@ -25,6 +26,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum bool pressed_PrevTape = false; bool pressed_NextBlock = false; bool pressed_PrevBlock = false; + bool pressed_TapeStatus = false; public void PollInput() { @@ -85,8 +87,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum } } - - // Tape control if (Spectrum._controller.IsPressed(Play)) { @@ -175,6 +175,18 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum } else pressed_PrevBlock = false; + + if (Spectrum._controller.IsPressed(TapeStatus)) + { + if (!pressed_TapeStatus) + { + //Spectrum.OSD_FireInputMessage(TapeStatus); + Spectrum.OSD_ShowTapeStatus(); + pressed_TapeStatus = true; + } + } + else + pressed_TapeStatus = false; } /// diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Memory.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Memory.cs index 6ddbccedbc..0179c0c5f5 100644 --- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Memory.cs +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Memory.cs @@ -105,6 +105,19 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum /// Helper function to refresh memory array (probably not the best way to do things) /// public abstract void ReInitMemory(); + + /// + /// Detects whether the 48k rom is resident (or paged in) at 0x0001 + /// + /// + public virtual bool IsIn48kMode() + { + var data = ReadBus(0x0001); + if (data == 0xaf) + return true; + + return false; + } } } diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.Controllers.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.Controllers.cs index a59f03de9e..1ba7dd5b74 100644 --- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.Controllers.cs +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.Controllers.cs @@ -86,7 +86,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum List tape = new List { // Tape functions - "Play Tape", "Stop Tape", "RTZ Tape", "Record Tape", "Insert Next Tape", "Insert Previous Tape", "Next Tape Block", "Prev Tape Block" + "Play Tape", "Stop Tape", "RTZ Tape", "Record Tape", "Insert Next Tape", + "Insert Previous Tape", "Next Tape Block", "Prev Tape Block", "Get Tape Status" }; foreach (var s in tape) diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.Messaging.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.Messaging.cs index 9a583013e8..9ad4e3615a 100644 --- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.Messaging.cs +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.Messaging.cs @@ -200,6 +200,46 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape); } + /// + /// Tape message that prints the current status of the tape device + /// + public void OSD_ShowTapeStatus() + { + StringBuilder sb = new StringBuilder(); + sb.Append("Status: "); + + if (_machine.TapeDevice.TapeIsPlaying) + sb.Append("PLAYING"); + else + sb.Append("STOPPED"); + + SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape); + sb.Clear(); + + sb.Append("Tape: " + _machine.TapeMediaIndex + ": " + _gameInfo[_machine.TapeMediaIndex].Name); + SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape); + sb.Clear(); + + sb.Append("Block: "); + sb.Append("(" + (_machine.TapeDevice.CurrentDataBlockIndex + 1) + + " of " + _machine.TapeDevice.DataBlocks.Count() + ") " + + _machine.TapeDevice.DataBlocks[_machine.TapeDevice.CurrentDataBlockIndex].BlockDescription); + SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape); + sb.Clear(); + + sb.Append("Block Pos: "); + + int pos = _machine.TapeDevice.Position; + int end = _machine.TapeDevice.DataBlocks[_machine.TapeDevice.CurrentDataBlockIndex].DataPeriods.Count; + double p = 0; + if (end != 0) + p = ((double)pos / (double)end) * (double)100; + + sb.Append(p.ToString("N0") + "%"); + SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape); + sb.Clear(); + } + #endregion ///