From 160f54234009daf30958e5b9ba2953113086e50d Mon Sep 17 00:00:00 2001 From: SuuperW Date: Tue, 8 Jul 2025 18:36:33 -0500 Subject: [PATCH 1/8] fix use of mixed spaces and tabs for indentation --- .../lua/CommonLibs/MovieLuaLibrary.cs | 4 +- .../AmstradCPC/AmstradCPC.Messaging.cs | 18 +- .../Computers/AmstradCPC/Hardware/AY38912.cs | 204 ++--- .../Hardware/Datacorder/DatacorderDevice.cs | 228 ++--- .../Hardware/Disk/NECUPD765.Definitions.cs | 10 +- .../AmstradCPC/Hardware/Disk/NECUPD765.FDC.cs | 138 +-- .../AmstradCPC/Hardware/Disk/NECUPD765.FDD.cs | 834 +++++++++--------- .../Hardware/Disk/NECUPD765.IPortIODevice.cs | 28 +- .../Hardware/Disk/NECUPD765.Timing.cs | 10 +- .../AmstradCPC/Hardware/Disk/NECUPD765.cs | 78 +- .../Hardware/Disk/NECUPS765.Static.cs | 10 +- .../AmstradCPC/Hardware/GateArray.cs | 120 +-- .../Hardware/Input/StandardKeyboard.cs | 40 +- .../Computers/AmstradCPC/Hardware/PPI_8255.cs | 10 +- .../Computers/AmstradCPC/Machine/CPCBase.cs | 184 ++-- .../AmstradCPC/Media/Disk/FloppyDisk.cs | 208 ++--- .../AmstradCPC/Media/Tape/CDT/CdtConverter.cs | 174 ++-- .../AmstradCPC/Media/Tape/TapeDataBlock.cs | 46 +- .../Computers/Commodore64/MOS/Sid.cs | 24 +- .../Hardware/Disk/NECUPD765.FDC.cs | 138 +-- .../Hardware/Disk/NECUPD765.FDD.cs | 834 +++++++++--------- .../Hardware/Disk/NECUPD765.cs | 78 +- .../Hardware/Input/CursorJoystick.cs | 10 +- .../Hardware/Input/KempstonJoystick.cs | 18 +- .../Hardware/Input/NullJoystick.cs | 18 +- .../Hardware/Input/SinclairJoystick1.cs | 10 +- .../Hardware/Input/SinclairJoystick2.cs | 10 +- .../Hardware/Input/StandardKeyboard.cs | 28 +- .../Hardware/SoundOuput/AY38912.cs | 136 +-- .../Machine/Pentagon128K/Pentagon128.Port.cs | 306 +++---- .../Machine/SpectrumBase.Memory.cs | 440 ++++----- .../Machine/SpectrumBase.Port.cs | 54 +- .../Machine/ZXSpectrum128K/ZX128.Port.cs | 304 +++---- .../ZXSpectrum128KPlus2a/ZX128Plus2a.Port.cs | 338 +++---- .../ZXSpectrum128KPlus3/ZX128Plus3.Port.cs | 352 ++++---- .../Machine/ZXSpectrum16K/ZX16.cs | 26 +- .../SinclairSpectrum/Media/Disk/FloppyDisk.cs | 208 ++--- .../Media/Snapshot/SZX/SZX.Methods.cs | 82 +- .../Media/Tape/CSW/CswConverter.cs | 72 +- .../Media/Tape/PZX/PzxConverter.cs | 80 +- .../Media/Tape/TAP/TapConverter.cs | 123 +-- .../Media/Tape/TZX/TzxConverter.cs | 41 +- .../Consoles/Nintendo/GBHawk/GBHawk.cs | 2 +- .../Consoles/Sega/SMS/SMS.cs | 8 +- .../Waterbox/NymaCore.Controller.cs | 2 +- .../DiscFormats/MDS_Format.cs | 4 +- src/BizHawk.Emulation.DiscSystem/DiscTrack.cs | 100 +-- 47 files changed, 3097 insertions(+), 3093 deletions(-) diff --git a/src/BizHawk.Client.Common/lua/CommonLibs/MovieLuaLibrary.cs b/src/BizHawk.Client.Common/lua/CommonLibs/MovieLuaLibrary.cs index b2060e62ba4..bc28cfe5ef1 100644 --- a/src/BizHawk.Client.Common/lua/CommonLibs/MovieLuaLibrary.cs +++ b/src/BizHawk.Client.Common/lua/CommonLibs/MovieLuaLibrary.cs @@ -31,8 +31,8 @@ public string Filename() [LuaMethod("getinput", "Returns a table of buttons pressed on a given frame of the loaded movie")] public LuaTable GetInput(int frame, int? controller = null) => APIs.Movie.GetInput(frame, controller) is IReadOnlyDictionary dict - ? _th.DictToTable(dict) - : null; + ? _th.DictToTable(dict) + : null; [LuaMethodExample("local stmovget = movie.getinputasmnemonic( 500 );")] [LuaMethod("getinputasmnemonic", "Returns the input of a given frame of the loaded movie in a raw inputlog string")] diff --git a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/AmstradCPC.Messaging.cs b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/AmstradCPC.Messaging.cs index 3e3b0294d4b..de776e85fc1 100644 --- a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/AmstradCPC.Messaging.cs +++ b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/AmstradCPC.Messaging.cs @@ -118,15 +118,15 @@ public void OSD_ShowDiskStatus() SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Disk); sb.Clear(); /* - string protection = "None"; - protection = Enum.GetName(typeof(ProtectionType), _machine.UPDDiskDevice.DiskPointer.Protection); - if (protection == "None") - protection += " (OR UNKNOWN)"; - - sb.Append("Detected Protection: " + protection); - SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Disk); - sb.Clear(); - */ + string protection = "None"; + protection = Enum.GetName(typeof(ProtectionType), _machine.UPDDiskDevice.DiskPointer.Protection); + if (protection == "None") + protection += " (OR UNKNOWN)"; + + sb.Append("Detected Protection: " + protection); + SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Disk); + sb.Clear(); + */ sb.Append("Status: "); diff --git a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/AY38912.cs b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/AY38912.cs index 87b083049ab..3c2163724ac 100644 --- a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/AY38912.cs +++ b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/AY38912.cs @@ -117,30 +117,30 @@ public int SelectedRegister public void Reset() { /* - _noiseVal = 0x0FFFF; - _outABC = 0; - _outNoiseABC = 0; - _counterNoise = 0; - _counterA = 0; - _counterB = 0; - _counterC = 0; - _EnvelopeCounterBend = 0; - - // clear all the registers - for (int i = 0; i < 14; i++) - { - SelectedRegister = i; - PortWrite(0); - } - - randomSeed = 1; - - // number of frames to update - var fr = (_audioBufferIndex * _tStatesPerFrame) / _audioBuffer.Length; - - // update the audio buffer - BufferUpdate(fr); - */ + _noiseVal = 0x0FFFF; + _outABC = 0; + _outNoiseABC = 0; + _counterNoise = 0; + _counterA = 0; + _counterB = 0; + _counterC = 0; + _EnvelopeCounterBend = 0; + + // clear all the registers + for (int i = 0; i < 14; i++) + { + SelectedRegister = i; + PortWrite(0); + } + + randomSeed = 1; + + // number of frames to update + var fr = (_audioBufferIndex * _tStatesPerFrame) / _audioBuffer.Length; + + // update the audio buffer + BufferUpdate(fr); + */ } /// @@ -357,36 +357,36 @@ public void UpdateSound(int frameCycle) /// The register array /// /* - The AY-3-8910/8912 contains 16 internal registers as follows: - - Register Function Range - 0 Channel A fine pitch 8-bit (0-255) - 1 Channel A course pitch 4-bit (0-15) - 2 Channel B fine pitch 8-bit (0-255) - 3 Channel B course pitch 4-bit (0-15) - 4 Channel C fine pitch 8-bit (0-255) - 5 Channel C course pitch 4-bit (0-15) - 6 Noise pitch 5-bit (0-31) - 7 Mixer 8-bit (see below) - 8 Channel A volume 4-bit (0-15, see below) - 9 Channel B volume 4-bit (0-15, see below) - 10 Channel C volume 4-bit (0-15, see below) - 11 Envelope fine duration 8-bit (0-255) - 12 Envelope course duration 8-bit (0-255) - 13 Envelope shape 4-bit (0-15) - 14 I/O port A 8-bit (0-255) - 15 I/O port B 8-bit (0-255) (Not present on the AY-3-8912) - - * The volume registers (8, 9 and 10) contain a 4-bit setting but if bit 5 is set then that channel uses the - envelope defined by register 13 and ignores its volume setting. - * The mixer (register 7) is made up of the following bits (low=enabled): - - Bit: 7 6 5 4 3 2 1 0 - Register: I/O I/O Noise Noise Noise Tone Tone Tone - Channel: B A C B A C B A - - The AY-3-8912 ignores bit 7 of this register. - */ + The AY-3-8910/8912 contains 16 internal registers as follows: + + Register Function Range + 0 Channel A fine pitch 8-bit (0-255) + 1 Channel A course pitch 4-bit (0-15) + 2 Channel B fine pitch 8-bit (0-255) + 3 Channel B course pitch 4-bit (0-15) + 4 Channel C fine pitch 8-bit (0-255) + 5 Channel C course pitch 4-bit (0-15) + 6 Noise pitch 5-bit (0-31) + 7 Mixer 8-bit (see below) + 8 Channel A volume 4-bit (0-15, see below) + 9 Channel B volume 4-bit (0-15, see below) + 10 Channel C volume 4-bit (0-15, see below) + 11 Envelope fine duration 8-bit (0-255) + 12 Envelope course duration 8-bit (0-255) + 13 Envelope shape 4-bit (0-15) + 14 I/O port A 8-bit (0-255) + 15 I/O port B 8-bit (0-255) (Not present on the AY-3-8912) + + * The volume registers (8, 9 and 10) contain a 4-bit setting but if bit 5 is set then that channel uses the + envelope defined by register 13 and ignores its volume setting. + * The mixer (register 7) is made up of the following bits (low=enabled): + + Bit: 7 6 5 4 3 2 1 0 + Register: I/O I/O Noise Noise Noise Tone Tone Tone + Channel: B A C B A C B A + + The AY-3-8912 ignores bit 7 of this register. + */ private int[] _registers = new int[16]; /// @@ -498,20 +498,20 @@ The AY-3-8912 ignores bit 7 of this register. /// private static readonly List PanTabs = new List { - // MONO - new uint[] { 50,50, 50,50, 50,50 }, - // ABC - new uint[] { 100,10, 66,66, 10,100 }, - // ACB - new uint[] { 100,10, 10,100, 66,66 }, - // BAC - new uint[] { 66,66, 100,10, 10,100 }, - // BCA - new uint[] { 10,100, 100,10, 66,66 }, - // CAB - new uint[] { 66,66, 10,100, 100,10 }, - // CBA - new uint[] { 10,100, 66,66, 100,10 } + // MONO + new uint[] { 50,50, 50,50, 50,50 }, + // ABC + new uint[] { 100,10, 66,66, 10,100 }, + // ACB + new uint[] { 100,10, 10,100, 66,66 }, + // BAC + new uint[] { 66,66, 100,10, 10,100 }, + // BCA + new uint[] { 10,100, 100,10, 66,66 }, + // CAB + new uint[] { 66,66, 10,100, 100,10 }, + // CBA + new uint[] { 10,100, 66,66, 100,10 } }; /// @@ -720,40 +720,40 @@ public void GetSamplesSync(out short[] samples, out int nsamp) tickCounter = 0; return; /* - _blipL.EndFrame((uint)SampleClock); - _blipR.EndFrame((uint)SampleClock); - SampleClock = 0; - - int sampL = _blipL.SamplesAvailable(); - int sampR = _blipR.SamplesAvailable(); - - if (sampL > sampR) - nsamp = sampL; - else - nsamp = sampR; - - short[] buffL = new short[sampL]; - short[] buffR = new short[sampR]; - - _blipL.ReadSamples(buffL, sampL - 1, false); - _blipR.ReadSamples(buffR, sampR - 1, false); - - if (_audioBuffer.Length != nsamp * 2) - _audioBuffer = new short[nsamp * 2]; - - int p = 0; - for (int i = 0; i < nsamp; i++) - { - if (i < sampL) - _audioBuffer[p++] = buffL[i]; - if (i < sampR) - _audioBuffer[p++] = buffR[i]; - } - - //nsamp = _samplesPerFrame; - samples = _audioBuffer; - DiscardSamples(); - */ + _blipL.EndFrame((uint)SampleClock); + _blipR.EndFrame((uint)SampleClock); + SampleClock = 0; + + int sampL = _blipL.SamplesAvailable(); + int sampR = _blipR.SamplesAvailable(); + + if (sampL > sampR) + nsamp = sampL; + else + nsamp = sampR; + + short[] buffL = new short[sampL]; + short[] buffR = new short[sampR]; + + _blipL.ReadSamples(buffL, sampL - 1, false); + _blipR.ReadSamples(buffR, sampR - 1, false); + + if (_audioBuffer.Length != nsamp * 2) + _audioBuffer = new short[nsamp * 2]; + + int p = 0; + for (int i = 0; i < nsamp; i++) + { + if (i < sampL) + _audioBuffer[p++] = buffL[i]; + if (i < sampR) + _audioBuffer[p++] = buffR[i]; + } + + //nsamp = _samplesPerFrame; + samples = _audioBuffer; + DiscardSamples(); + */ } public int nullDump = 0; diff --git a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Datacorder/DatacorderDevice.cs b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Datacorder/DatacorderDevice.cs index 7de96bd7cdc..421da54a1ea 100644 --- a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Datacorder/DatacorderDevice.cs +++ b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Datacorder/DatacorderDevice.cs @@ -513,40 +513,40 @@ public bool GetEarBit(long cpuCycle) throw new Exception("spectrum tape command found in CPC tape"); /* - // 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.CPC.OSD_TapeStoppedAuto(); - shouldStop = true; - - if (_currentDataBlockIndex >= _dataBlocks.Count) - RTZ(); - else - { - Stop(); - } - - _monitorTimeOut = 2000; - - break; - case TapeCommand.STOP_THE_TAPE_48K: - if (is48k) - { - _machine.CPC.OSD_TapeStoppedAuto(); - shouldStop = true; - - if (_currentDataBlockIndex >= _dataBlocks.Count) - RTZ(); - else - { - Stop(); - } - - _monitorTimeOut = 2000; - } - break; - */ + // 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.CPC.OSD_TapeStoppedAuto(); + shouldStop = true; + + if (_currentDataBlockIndex >= _dataBlocks.Count) + RTZ(); + else + { + Stop(); + } + + _monitorTimeOut = 2000; + + break; + case TapeCommand.STOP_THE_TAPE_48K: + if (is48k) + { + _machine.CPC.OSD_TapeStoppedAuto(); + shouldStop = true; + + if (_currentDataBlockIndex >= _dataBlocks.Count) + RTZ(); + else + { + Stop(); + } + + _monitorTimeOut = 2000; + } + break; + */ default: break; } @@ -619,72 +619,72 @@ public void AutoStartTape() } /* - public int MaskableInterruptCount = 0; - - private void MonitorFrame() - { - if (_tapeIsPlaying && _autoPlay) - { - if (DataBlocks.Count > 1 - || _dataBlocks[_currentDataBlockIndex].BlockDescription is not (BlockType.CSW_Recording or BlockType.WAV_Recording)) - { - // we should only stop the tape when there are multiple blocks - // if we just have one big block (maybe a CSW or WAV) then auto stopping will cock things up - _monitorTimeOut--; - } - - if (_monitorTimeOut < 0) - { - if (_dataBlocks[_currentDataBlockIndex].BlockDescription is not (BlockType.PAUSE_BLOCK or BlockType.PAUS)) - { - AutoStopTape(); - } - - return; - } - - // fallback in case usual monitor detection methods do not work - - // number of t-states since last IN operation - long diff = _machine.CPU.TotalExecutedCycles - _lastINCycle; - - // get current datablock - var block = DataBlocks[_currentDataBlockIndex]; - - // is this a pause block? - if (block.BlockDescription is BlockType.PAUS or BlockType.PAUSE_BLOCK) - { - // don't autostop the tape here - return; - } - - // pause in ms at the end of the current block - int blockPause = block.PauseInMS; - - // timeout in t-states (equiv. to blockpause) - int timeout = ((_machine.GateArray.FrameLength * 50) / 1000) * blockPause; - - // don't use autostop detection if block has no pause at the end - if (timeout == 0) - return; - - // don't autostop if there is only 1 block - if (DataBlocks.Count is 1 - || _dataBlocks[_currentDataBlockIndex].BlockDescription is BlockType.CSW_Recording or BlockType.WAV_Recording) - { - return; - } - - if (diff >= timeout * 2) - { - // There have been no attempted tape reads by the CPU within the double timeout period - // Autostop the tape - AutoStopTape(); - _lastCycle = _cpu.TotalExecutedCycles; - } - } - } - */ + public int MaskableInterruptCount = 0; + + private void MonitorFrame() + { + if (_tapeIsPlaying && _autoPlay) + { + if (DataBlocks.Count > 1 + || _dataBlocks[_currentDataBlockIndex].BlockDescription is not (BlockType.CSW_Recording or BlockType.WAV_Recording)) + { + // we should only stop the tape when there are multiple blocks + // if we just have one big block (maybe a CSW or WAV) then auto stopping will cock things up + _monitorTimeOut--; + } + + if (_monitorTimeOut < 0) + { + if (_dataBlocks[_currentDataBlockIndex].BlockDescription is not (BlockType.PAUSE_BLOCK or BlockType.PAUS)) + { + AutoStopTape(); + } + + return; + } + + // fallback in case usual monitor detection methods do not work + + // number of t-states since last IN operation + long diff = _machine.CPU.TotalExecutedCycles - _lastINCycle; + + // get current datablock + var block = DataBlocks[_currentDataBlockIndex]; + + // is this a pause block? + if (block.BlockDescription is BlockType.PAUS or BlockType.PAUSE_BLOCK) + { + // don't autostop the tape here + return; + } + + // pause in ms at the end of the current block + int blockPause = block.PauseInMS; + + // timeout in t-states (equiv. to blockpause) + int timeout = ((_machine.GateArray.FrameLength * 50) / 1000) * blockPause; + + // don't use autostop detection if block has no pause at the end + if (timeout == 0) + return; + + // don't autostop if there is only 1 block + if (DataBlocks.Count is 1 + || _dataBlocks[_currentDataBlockIndex].BlockDescription is BlockType.CSW_Recording or BlockType.WAV_Recording) + { + return; + } + + if (diff >= timeout * 2) + { + // There have been no attempted tape reads by the CPU within the double timeout period + // Autostop the tape + AutoStopTape(); + _lastCycle = _cpu.TotalExecutedCycles; + } + } + } + */ /// /// Mask constants @@ -703,15 +703,15 @@ public bool ReadPort() GetEarBit(CPU.TotalExecutedCycles); } /* - if (currentState) - { - result |= TAPE_BIT; - } - else - { - result &= ~TAPE_BIT; - } - */ + if (currentState) + { + result |= TAPE_BIT; + } + else + { + result &= ~TAPE_BIT; + } + */ if (!TapeIsPlaying) { @@ -732,11 +732,11 @@ public void WritePort(bool state) // not implemented /* - if (!TapeIsPlaying) - { - currentState = ((byte)result & 0x10) != 0; - } - */ + if (!TapeIsPlaying) + { + currentState = ((byte)result & 0x10) != 0; + } + */ } /// diff --git a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPD765.Definitions.cs b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPD765.Definitions.cs index 971b1bfbe4d..72ddb052666 100644 --- a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPD765.Definitions.cs +++ b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPD765.Definitions.cs @@ -6,11 +6,11 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC /// Definitions /// /* - Implementation based on the information contained here: - http://www.cpcwiki.eu/index.php/765_FDC - and here: - http://www.cpcwiki.eu/imgs/f/f3/UPD765_Datasheet_OCRed.pdf - */ + Implementation based on the information contained here: + http://www.cpcwiki.eu/index.php/765_FDC + and here: + http://www.cpcwiki.eu/imgs/f/f3/UPD765_Datasheet_OCRed.pdf + */ public partial class NECUPD765 { /// diff --git a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPD765.FDC.cs b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPD765.FDC.cs index 0a5dd32424e..d87b0e14864 100644 --- a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPD765.FDC.cs +++ b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPD765.FDC.cs @@ -9,11 +9,11 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC /// FDC State and Methods /// /* - Implementation based on the information contained here: - http://www.cpcwiki.eu/index.php/765_FDC - and here: - http://www.cpcwiki.eu/imgs/f/f3/UPD765_Datasheet_OCRed.pdf - */ + Implementation based on the information contained here: + http://www.cpcwiki.eu/index.php/765_FDC + and here: + http://www.cpcwiki.eu/imgs/f/f3/UPD765_Datasheet_OCRed.pdf + */ public partial class NECUPD765 { /// @@ -206,69 +206,69 @@ public int CMDIndex /// Main status register (accessed via reads to port 0x2ffd) /// /* - b0..3 DB FDD0..3 Busy (seek/recalib active, until succesful sense intstat) - b4 CB FDC Busy (still in command-, execution- or result-phase) - b5 EXM Execution Mode (still in execution-phase, non_DMA_only) - b6 DIO Data Input/Output (0=CPU->FDC, 1=FDC->CPU) (see b7) - b7 RQM Request For Master (1=ready for next byte) (see b6 for direction) - */ + b0..3 DB FDD0..3 Busy (seek/recalib active, until succesful sense intstat) + b4 CB FDC Busy (still in command-, execution- or result-phase) + b5 EXM Execution Mode (still in execution-phase, non_DMA_only) + b6 DIO Data Input/Output (0=CPU->FDC, 1=FDC->CPU) (see b7) + b7 RQM Request For Master (1=ready for next byte) (see b6 for direction) + */ private byte StatusMain; /// /// Status Register 0 /// /* - b0,1 US Unit Select (driveno during interrupt) - b2 HD Head Address (head during interrupt) - b3 NR Not Ready (drive not ready or non-existing 2nd head selected) - b4 EC Equipment Check (drive failure or recalibrate failed (retry)) - b5 SE Seek End (Set if seek-command completed) - b6,7 IC Interrupt Code (0=OK, 1=aborted:readfail/OK if EN, 2=unknown cmd - or senseint with no int occured, 3=aborted:disc removed etc.) - */ + b0,1 US Unit Select (driveno during interrupt) + b2 HD Head Address (head during interrupt) + b3 NR Not Ready (drive not ready or non-existing 2nd head selected) + b4 EC Equipment Check (drive failure or recalibrate failed (retry)) + b5 SE Seek End (Set if seek-command completed) + b6,7 IC Interrupt Code (0=OK, 1=aborted:readfail/OK if EN, 2=unknown cmd + or senseint with no int occured, 3=aborted:disc removed etc.) + */ private byte Status0; /// /// Status Register 1 /// /* - b0 MA Missing Address Mark (Sector_ID or DAM not found) - b1 NW Not Writeable (tried to write/format disc with wprot_tab=on) - b2 ND No Data (Sector_ID not found, CRC fail in ID_field) - b3,6 0 Not used - b4 OR Over Run (CPU too slow in execution-phase (ca. 26us/Byte)) - b5 DE Data Error (CRC-fail in ID- or Data-Field) - b7 EN End of Track (set past most read/write commands) (see IC) - */ + b0 MA Missing Address Mark (Sector_ID or DAM not found) + b1 NW Not Writeable (tried to write/format disc with wprot_tab=on) + b2 ND No Data (Sector_ID not found, CRC fail in ID_field) + b3,6 0 Not used + b4 OR Over Run (CPU too slow in execution-phase (ca. 26us/Byte)) + b5 DE Data Error (CRC-fail in ID- or Data-Field) + b7 EN End of Track (set past most read/write commands) (see IC) + */ private byte Status1; /// /// Status Register 2 /// /* - b0 MD Missing Address Mark in Data Field (DAM not found) - b1 BC Bad Cylinder (read/programmed track-ID different and read-ID = FF) - b2 SN Scan Not Satisfied (no fitting sector found) - b3 SH Scan Equal Hit (equal) - b4 WC Wrong Cylinder (read/programmed track-ID different) (see b1) - b5 DD Data Error in Data Field (CRC-fail in data-field) - b6 CM Control Mark (read/scan command found sector with deleted DAM) - b7 0 Not Used - */ + b0 MD Missing Address Mark in Data Field (DAM not found) + b1 BC Bad Cylinder (read/programmed track-ID different and read-ID = FF) + b2 SN Scan Not Satisfied (no fitting sector found) + b3 SH Scan Equal Hit (equal) + b4 WC Wrong Cylinder (read/programmed track-ID different) (see b1) + b5 DD Data Error in Data Field (CRC-fail in data-field) + b6 CM Control Mark (read/scan command found sector with deleted DAM) + b7 0 Not Used + */ private byte Status2; /// /// Status Register 3 /// /* - b0,1 US Unit Select (pin 28,29 of FDC) - b2 HD Head Address (pin 27 of FDC) - b3 TS Two Side (0=yes, 1=no (!)) - b4 T0 Track 0 (on track 0 we are) - b5 RY Ready (drive ready signal) - b6 WP Write Protected (write protected) - b7 FT Fault (if supported: 1=Drive failure) - */ + b0,1 US Unit Select (pin 28,29 of FDC) + b2 HD Head Address (pin 27 of FDC) + b3 TS Two Side (0=yes, 1=no (!)) + b4 T0 Track 0 (on track 0 we are) + b5 RY Ready (drive ready signal) + b6 WP Write Protected (write protected) + b7 FT Fault (if supported: 1=Drive failure) + */ private byte Status3; /// @@ -2128,16 +2128,16 @@ private void UPD_SenseInterruptStatus() ResBuffer[1] = ActiveDrive.CurrentTrackID; } /* - else if (ActiveDrive.SeekStatus == SEEK_INTACKNOWLEDGED) - { - // DriveA interrupt has already been acknowledged - ActiveDrive.SeekStatus = SEEK_IDLE; - - ResLength = 1; - Status0 = 192; - ResBuffer[0] = Status0; - } - */ + else if (ActiveDrive.SeekStatus == SEEK_INTACKNOWLEDGED) + { + // DriveA interrupt has already been acknowledged + ActiveDrive.SeekStatus = SEEK_IDLE; + + ResLength = 1; + Status0 = 192; + ResBuffer[0] = Status0; + } + */ else if (ActiveDrive.SeekStatus == SEEK_IDLE) { // SIS with no interrupt @@ -2526,14 +2526,14 @@ private bool ParseCommandByte(byte cmdByte) } /* - if ((CMD_FLAG_MF && !ActiveCommand.MF) - || (CMD_FLAG_MT && !ActiveCommand.MT) - || (CMD_FLAG_SK && !ActiveCommand.SK)) - { - // command byte included spurious bit 5,6 or 7 flags - CMDIndex = CommandList.Count - 1; - } - */ + if ((CMD_FLAG_MF && !ActiveCommand.MF) + || (CMD_FLAG_MT && !ActiveCommand.MT) + || (CMD_FLAG_SK && !ActiveCommand.SK)) + { + // command byte included spurious bit 5,6 or 7 flags + CMDIndex = CommandList.Count - 1; + } + */ } CommCounter = 0; @@ -2544,13 +2544,13 @@ private bool ParseCommandByte(byte cmdByte) ActivePhase = Phase.Command; /* - // check for invalid SIS - if (ActiveInterrupt == InterruptState.None && CMDIndex == CC_SENSE_INTSTATUS) - { - CMDIndex = CC_INVALID; - //ActiveCommand.CommandDelegate(InstructionState.StartResult); - } - */ + // check for invalid SIS + if (ActiveInterrupt == InterruptState.None && CMDIndex == CC_SENSE_INTSTATUS) + { + CMDIndex = CC_INVALID; + //ActiveCommand.CommandDelegate(InstructionState.StartResult); + } + */ // set reslength ResLength = ActiveCommand.ResultByteCount; diff --git a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPD765.FDD.cs b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPD765.FDD.cs index 801deee8e76..2f588bfb066 100644 --- a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPD765.FDD.cs +++ b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPD765.FDD.cs @@ -7,11 +7,11 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC /// Floppy drive related stuff /// /* - Implementation based on the information contained here: - http://www.cpcwiki.eu/index.php/765_FDC - and here: - http://www.cpcwiki.eu/imgs/f/f3/UPD765_Datasheet_OCRed.pdf - */ + Implementation based on the information contained here: + http://www.cpcwiki.eu/index.php/765_FDC + and here: + http://www.cpcwiki.eu/imgs/f/f3/UPD765_Datasheet_OCRed.pdf + */ public partial class NECUPD765 : IFDDHost { /// @@ -298,424 +298,424 @@ public bool FLAG_TRACK0 } /* - /// - /// Moves the head across the disk cylinders - /// - public void MoveHead(SkipDirection direction, int cylinderCount) - { - // get total tracks - int trackCount = Disk.DiskTracks.Length; - - int trk = 0; - - switch (direction) - { - case SkipDirection.Increment: - trk = (int)CurrentTrack + cylinderCount; - if (trk >= trackCount) - { - // past the last track - trk = trackCount - 1; - } - else if (trk < 0) - trk = 0; - break; - case SkipDirection.Decrement: - trk = (int)CurrentTrack - cylinderCount; - if (trk < 0) - { - // before the first track - trk = 0; - } - else if (trk >= trackCount) - trk = trackCount - 1; - break; - } - - // move the head - CurrentTrack = (byte)trk; - } - */ + /// + /// Moves the head across the disk cylinders + /// + public void MoveHead(SkipDirection direction, int cylinderCount) + { + // get total tracks + int trackCount = Disk.DiskTracks.Length; + + int trk = 0; + + switch (direction) + { + case SkipDirection.Increment: + trk = (int)CurrentTrack + cylinderCount; + if (trk >= trackCount) + { + // past the last track + trk = trackCount - 1; + } + else if (trk < 0) + trk = 0; + break; + case SkipDirection.Decrement: + trk = (int)CurrentTrack - cylinderCount; + if (trk < 0) + { + // before the first track + trk = 0; + } + else if (trk >= trackCount) + trk = trackCount - 1; + break; + } + + // move the head + CurrentTrack = (byte)trk; + } + */ /* - /// - /// Finds a supplied sector - /// - public FloppyDisk.Sector FindSector(ref byte[] resBuffer, CommandParameters prms) - { - int index =CurrentSector; - int lc = 0; - FloppyDisk.Sector sector = null; - - bool found = false; - - do - { - sector = Disk.DiskTracks[CurrentTrack].Sectors[index]; - if (sector != null && sector.SectorID == prms.Sector) - { - // sector found - // check for data errors - if ((sector.Status1 & 0x20) != 0 || (sector.Status2 & 0x20) != 0) - { - // data errors found - } - found = true; - break; - } - - // sector doesnt match - var c = Disk.DiskTracks[CurrentTrack].Sectors[index].TrackNumber; - if (c == 255) - { - // bad cylinder - resBuffer[RS_ST2] |= 0x02; - } - else if (prms.Cylinder != c) - { - // cylinder mismatch - resBuffer[RS_ST2] |= 0x10; - } - - // increment index - index++; - - if (index >= Disk.DiskTracks[CurrentTrack].NumberOfSectors) - { - // out of bounds - index = 0; - lc++; - } - - } while (lc < 2); - - if ((resBuffer[RS_ST2] & 0x02) != 0) - { - // bad cylinder set - remove no cylinder - UnSetBit(SR2_WC, ref resBuffer[RS_ST2]); - } - - // update current sector - CurrentSector = index; - - if (found) - return sector; - else - return null; - } - - - /// - /// Populates a result buffer - /// - public void FillResult(ref byte[] resBuffer, CHRN chrn) - { - // clear results - resBuffer[RS_ST0] = 0; - resBuffer[RS_ST1] = 0; - resBuffer[RS_ST2] = 0; - resBuffer[RS_C] = 0; - resBuffer[RS_H] = 0; - resBuffer[RS_R] = 0; - resBuffer[RS_N] = 0; - - if (chrn == null) - { - // no chrn supplied - resBuffer[RS_ST0] = ST0; - resBuffer[RS_ST1] = 0; - resBuffer[RS_ST2] = 0; - resBuffer[RS_C] = 0; - resBuffer[RS_H] = 0; - resBuffer[RS_R] = 0; - resBuffer[RS_N] = 0; - } - } - - - - /// - /// Populates the result buffer with ReadID data - /// - public void ReadID(ref byte[] resBuffer) - { - if (CheckDriveStatus() == false) - { - // drive not ready - resBuffer[RS_ST0] = ST0; - return; - } - - var track = Disk.DiskTracks.Where(a => a.TrackNumber == CurrentTrack).FirstOrDefault(); - - if (track != null && track.NumberOfSectors > 0) - { - // formatted track - - // get the current sector - int index = CurrentSector; - - // is the index out of bounds? - if (index >= track.NumberOfSectors) - { - // reset the index - index = 0; - } - - // read the sector data - var data = track.Sectors[index]; - resBuffer[RS_C] = data.TrackNumber; - resBuffer[RS_H] = data.SideNumber; - resBuffer[RS_R] = data.SectorID; - resBuffer[RS_N] = data.SectorSize; - - resBuffer[RS_ST0] = ST0; - - // increment the current sector - CurrentSector = index + 1; - return; - } - else - { - // unformatted track? - resBuffer[RS_C] = FDC.CommBuffer[CM_C]; - resBuffer[RS_H] = FDC.CommBuffer[CM_H]; - resBuffer[RS_R] = FDC.CommBuffer[CM_R]; - resBuffer[RS_N] = FDC.CommBuffer[CM_N]; - - SetBit(SR0_IC0, ref ST0); - resBuffer[RS_ST0] = ST0; - resBuffer[RS_ST1] = 0x01; - return; - } - } - */ + /// + /// Finds a supplied sector + /// + public FloppyDisk.Sector FindSector(ref byte[] resBuffer, CommandParameters prms) + { + int index =CurrentSector; + int lc = 0; + FloppyDisk.Sector sector = null; + + bool found = false; + + do + { + sector = Disk.DiskTracks[CurrentTrack].Sectors[index]; + if (sector != null && sector.SectorID == prms.Sector) + { + // sector found + // check for data errors + if ((sector.Status1 & 0x20) != 0 || (sector.Status2 & 0x20) != 0) + { + // data errors found + } + found = true; + break; + } + + // sector doesnt match + var c = Disk.DiskTracks[CurrentTrack].Sectors[index].TrackNumber; + if (c == 255) + { + // bad cylinder + resBuffer[RS_ST2] |= 0x02; + } + else if (prms.Cylinder != c) + { + // cylinder mismatch + resBuffer[RS_ST2] |= 0x10; + } + + // increment index + index++; + + if (index >= Disk.DiskTracks[CurrentTrack].NumberOfSectors) + { + // out of bounds + index = 0; + lc++; + } + + } while (lc < 2); + + if ((resBuffer[RS_ST2] & 0x02) != 0) + { + // bad cylinder set - remove no cylinder + UnSetBit(SR2_WC, ref resBuffer[RS_ST2]); + } + + // update current sector + CurrentSector = index; + + if (found) + return sector; + else + return null; + } + + + /// + /// Populates a result buffer + /// + public void FillResult(ref byte[] resBuffer, CHRN chrn) + { + // clear results + resBuffer[RS_ST0] = 0; + resBuffer[RS_ST1] = 0; + resBuffer[RS_ST2] = 0; + resBuffer[RS_C] = 0; + resBuffer[RS_H] = 0; + resBuffer[RS_R] = 0; + resBuffer[RS_N] = 0; + + if (chrn == null) + { + // no chrn supplied + resBuffer[RS_ST0] = ST0; + resBuffer[RS_ST1] = 0; + resBuffer[RS_ST2] = 0; + resBuffer[RS_C] = 0; + resBuffer[RS_H] = 0; + resBuffer[RS_R] = 0; + resBuffer[RS_N] = 0; + } + } + + + + /// + /// Populates the result buffer with ReadID data + /// + public void ReadID(ref byte[] resBuffer) + { + if (CheckDriveStatus() == false) + { + // drive not ready + resBuffer[RS_ST0] = ST0; + return; + } + + var track = Disk.DiskTracks.Where(a => a.TrackNumber == CurrentTrack).FirstOrDefault(); + + if (track != null && track.NumberOfSectors > 0) + { + // formatted track + + // get the current sector + int index = CurrentSector; + + // is the index out of bounds? + if (index >= track.NumberOfSectors) + { + // reset the index + index = 0; + } + + // read the sector data + var data = track.Sectors[index]; + resBuffer[RS_C] = data.TrackNumber; + resBuffer[RS_H] = data.SideNumber; + resBuffer[RS_R] = data.SectorID; + resBuffer[RS_N] = data.SectorSize; + + resBuffer[RS_ST0] = ST0; + + // increment the current sector + CurrentSector = index + 1; + return; + } + else + { + // unformatted track? + resBuffer[RS_C] = FDC.CommBuffer[CM_C]; + resBuffer[RS_H] = FDC.CommBuffer[CM_H]; + resBuffer[RS_R] = FDC.CommBuffer[CM_R]; + resBuffer[RS_N] = FDC.CommBuffer[CM_N]; + + SetBit(SR0_IC0, ref ST0); + resBuffer[RS_ST0] = ST0; + resBuffer[RS_ST1] = 0x01; + return; + } + } + */ /* - /// - /// The drive performs a seek operation if necessary - /// Return value TRUE indicates seek complete - /// - public void DoSeek() - { - if (CurrentState is not (DriveMainState.Recalibrate or DriveMainState.Seek)) - { - // no seek/recalibrate has been asked for - return; - } - - if (GetBit(ID, FDC.StatusMain)) - { - // drive is already seeking - return; - } - - RunSeekCycle(); - } - - /// - /// Runs a seek cycle - /// - public void RunSeekCycle() - { - for (;;) - { - switch (SeekState) - { - // seek or recalibrate has been requested - case SeekSubState.Idle: - - if (CurrentState == DriveMainState.Recalibrate) - { - // recalibrate always seeks to track 0 - SeekingTrack = 0; - } - SeekState = SeekSubState.MoveInit; - - // mark drive as busy - // this should be cleared by SIS command - SetBit(ID, ref FDC.StatusMain); - - break; - - // setup for the head move - case SeekSubState.MoveInit: - - if (CurrentTrack == SeekingTrack) - { - // we are already at the required track - if (CurrentState is DriveMainState.Recalibrate && !FLAG_TRACK0) - { - // recalibration fail - SeekIntState = SeekIntStatus.Abnormal; - - // raise seek interrupt - FDC.ActiveInterrupt = InterruptState.Seek; - - // unset DB bit - UnSetBit(ID, ref FDC.StatusMain); - - // equipment check - SetBit(SR0_EC, ref FDC.Status0); - - SeekState = SeekSubState.PerformCompletion; - break; - } - - if (CurrentState is DriveMainState.Recalibrate && FLAG_TRACK0) - { - // recalibration success - SeekIntState = SeekIntStatus.Normal; - - // raise seek interrupt - FDC.ActiveInterrupt = InterruptState.Seek; - - // unset DB bit - UnSetBit(ID, ref FDC.StatusMain); - - SeekState = SeekSubState.PerformCompletion; - break; - } - } - - // check for error - if (IntStatus >= IC_ABORTED_DISCREMOVED || Disk == null) - { - // drive not ready - FLAG_READY = false; - - // drive not ready - SeekIntState = SeekIntStatus.DriveNotReady; - - // cancel any interrupt - FDC.ActiveInterrupt = InterruptState.None; - - // unset DB bit - UnSetBit(ID, ref FDC.StatusMain); - - SeekState = SeekSubState.PerformCompletion; - break; - } - - if (SeekCounter > 1) - { - // not ready to seek yet - SeekCounter--; - return; - } - - if (FDC.SRT < 1 && CurrentTrack != SeekingTrack) - { - SeekState = SeekSubState.MoveImmediate; - break; - } - - // head move - SeekState = SeekSubState.HeadMove; - - break; - - case SeekSubState.HeadMove: - - // do the seek - SeekCounter = FDC.SRT; - - if (CurrentTrack < SeekingTrack) - { - // we are seeking forward - var delta = SeekingTrack - CurrentTrack; - MoveHead(SkipDirection.Increment, 1); - } - else if (CurrentTrack > SeekingTrack) - { - // we are seeking backward - var delta = CurrentTrack - SeekingTrack; - MoveHead(SkipDirection.Decrement, 1); - } - - // should the seek be completed now? - if (CurrentTrack == SeekingTrack) - { - SeekState = SeekSubState.PerformCompletion; - break; - } - - // seek not finished yet - return; - - // seek emulation processed immediately - case SeekSubState.MoveImmediate: - - if (CurrentTrack < SeekingTrack) - { - // we are seeking forward - var delta = SeekingTrack - CurrentTrack; - MoveHead(SkipDirection.Increment, delta); - - } - else if (CurrentTrack > SeekingTrack) - { - // we are seeking backward - var delta = CurrentTrack - SeekingTrack; - MoveHead(SkipDirection.Decrement, delta); - } - - SeekState = SeekSubState.PerformCompletion; - break; - - case SeekSubState.PerformCompletion: - SeekDone(); - SeekState = SeekSubState.SeekCompleted; - break; - - case SeekSubState.SeekCompleted: - // seek has already completed - return; - } - } - } - - /// - /// Called when a seek operation has completed - /// - public void SeekDone() - { - SeekCounter = 0; - SeekingTrack = CurrentTrack; - - // generate ST0 register data - - // get only the IC bits - IntStatus &= IC_ABORTED_DISCREMOVED; - - // drive ready? - if (!FLAG_READY) - { - SetBit(SR0_NR, ref IntStatus); - SetBit(SR0_EC, ref IntStatus); - - // are we recalibrating? - if (CurrentState == DriveMainState.Recalibrate) - { - SetBit(SR0_EC, ref IntStatus); - } - } - - // set seek end - SetBit(SR0_SE, ref IntStatus); - /* - // head address - if (CurrentSide > 0) - { - SetBit(SR0_HD, ref IntStatus); - - // drive only supports 1 head - // set the EC bit - SetBit(SR0_EC, ref IntStatus); - } - */ + /// + /// The drive performs a seek operation if necessary + /// Return value TRUE indicates seek complete + /// + public void DoSeek() + { + if (CurrentState is not (DriveMainState.Recalibrate or DriveMainState.Seek)) + { + // no seek/recalibrate has been asked for + return; + } + + if (GetBit(ID, FDC.StatusMain)) + { + // drive is already seeking + return; + } + + RunSeekCycle(); + } + + /// + /// Runs a seek cycle + /// + public void RunSeekCycle() + { + for (;;) + { + switch (SeekState) + { + // seek or recalibrate has been requested + case SeekSubState.Idle: + + if (CurrentState == DriveMainState.Recalibrate) + { + // recalibrate always seeks to track 0 + SeekingTrack = 0; + } + SeekState = SeekSubState.MoveInit; + + // mark drive as busy + // this should be cleared by SIS command + SetBit(ID, ref FDC.StatusMain); + + break; + + // setup for the head move + case SeekSubState.MoveInit: + + if (CurrentTrack == SeekingTrack) + { + // we are already at the required track + if (CurrentState is DriveMainState.Recalibrate && !FLAG_TRACK0) + { + // recalibration fail + SeekIntState = SeekIntStatus.Abnormal; + + // raise seek interrupt + FDC.ActiveInterrupt = InterruptState.Seek; + + // unset DB bit + UnSetBit(ID, ref FDC.StatusMain); + + // equipment check + SetBit(SR0_EC, ref FDC.Status0); + + SeekState = SeekSubState.PerformCompletion; + break; + } + + if (CurrentState is DriveMainState.Recalibrate && FLAG_TRACK0) + { + // recalibration success + SeekIntState = SeekIntStatus.Normal; + + // raise seek interrupt + FDC.ActiveInterrupt = InterruptState.Seek; + + // unset DB bit + UnSetBit(ID, ref FDC.StatusMain); + + SeekState = SeekSubState.PerformCompletion; + break; + } + } + + // check for error + if (IntStatus >= IC_ABORTED_DISCREMOVED || Disk == null) + { + // drive not ready + FLAG_READY = false; + + // drive not ready + SeekIntState = SeekIntStatus.DriveNotReady; + + // cancel any interrupt + FDC.ActiveInterrupt = InterruptState.None; + + // unset DB bit + UnSetBit(ID, ref FDC.StatusMain); + + SeekState = SeekSubState.PerformCompletion; + break; + } + + if (SeekCounter > 1) + { + // not ready to seek yet + SeekCounter--; + return; + } + + if (FDC.SRT < 1 && CurrentTrack != SeekingTrack) + { + SeekState = SeekSubState.MoveImmediate; + break; + } + + // head move + SeekState = SeekSubState.HeadMove; + + break; + + case SeekSubState.HeadMove: + + // do the seek + SeekCounter = FDC.SRT; + + if (CurrentTrack < SeekingTrack) + { + // we are seeking forward + var delta = SeekingTrack - CurrentTrack; + MoveHead(SkipDirection.Increment, 1); + } + else if (CurrentTrack > SeekingTrack) + { + // we are seeking backward + var delta = CurrentTrack - SeekingTrack; + MoveHead(SkipDirection.Decrement, 1); + } + + // should the seek be completed now? + if (CurrentTrack == SeekingTrack) + { + SeekState = SeekSubState.PerformCompletion; + break; + } + + // seek not finished yet + return; + + // seek emulation processed immediately + case SeekSubState.MoveImmediate: + + if (CurrentTrack < SeekingTrack) + { + // we are seeking forward + var delta = SeekingTrack - CurrentTrack; + MoveHead(SkipDirection.Increment, delta); + + } + else if (CurrentTrack > SeekingTrack) + { + // we are seeking backward + var delta = CurrentTrack - SeekingTrack; + MoveHead(SkipDirection.Decrement, delta); + } + + SeekState = SeekSubState.PerformCompletion; + break; + + case SeekSubState.PerformCompletion: + SeekDone(); + SeekState = SeekSubState.SeekCompleted; + break; + + case SeekSubState.SeekCompleted: + // seek has already completed + return; + } + } + } + + /// + /// Called when a seek operation has completed + /// + public void SeekDone() + { + SeekCounter = 0; + SeekingTrack = CurrentTrack; + + // generate ST0 register data + + // get only the IC bits + IntStatus &= IC_ABORTED_DISCREMOVED; + + // drive ready? + if (!FLAG_READY) + { + SetBit(SR0_NR, ref IntStatus); + SetBit(SR0_EC, ref IntStatus); + + // are we recalibrating? + if (CurrentState == DriveMainState.Recalibrate) + { + SetBit(SR0_EC, ref IntStatus); + } + } + + // set seek end + SetBit(SR0_SE, ref IntStatus); + /* + // head address + if (CurrentSide > 0) + { + SetBit(SR0_HD, ref IntStatus); + + // drive only supports 1 head + // set the EC bit + SetBit(SR0_EC, ref IntStatus); + } + */ /* // UnitSelect SetUnitSelect(ID, ref IntStatus); diff --git a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPD765.IPortIODevice.cs b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPD765.IPortIODevice.cs index 2c37ce05799..e1b638f8ae4 100644 --- a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPD765.IPortIODevice.cs +++ b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPD765.IPortIODevice.cs @@ -9,11 +9,11 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC /// IPortIODevice /// /* - Implementation based on the information contained here: - http://www.cpcwiki.eu/index.php/765_FDC - and here: - http://www.cpcwiki.eu/imgs/f/f3/UPD765_Datasheet_OCRed.pdf - */ + Implementation based on the information contained here: + http://www.cpcwiki.eu/index.php/765_FDC + and here: + http://www.cpcwiki.eu/imgs/f/f3/UPD765_Datasheet_OCRed.pdf + */ public partial class NECUPD765 : IPortIODevice { public string outputfile = @"D:\Dropbox\Dropbox\_Programming\TASVideos\BizHawk\output\zxhawkio-" + DateTime.Now.ToString("yyyyMMdd_HHmmss", DateTimeFormatInfo.InvariantInfo) + ".csv"; @@ -27,15 +27,15 @@ public partial class NECUPD765 : IPortIODevice /* - * Status read - * Data write - * Data read - * CMD code - * CMD string - * MT flag - * MK flag - * SK flag - * */ + * Status read + * Data write + * Data read + * CMD code + * CMD string + * MT flag + * MK flag + * SK flag + * */ private readonly string[] workingArr = new string[3]; private void BuildCSVLine() diff --git a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPD765.Timing.cs b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPD765.Timing.cs index f0484213009..50857cef8b5 100644 --- a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPD765.Timing.cs +++ b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPD765.Timing.cs @@ -5,11 +5,11 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC /// Timimng /// /* - Implementation based on the information contained here: - http://www.cpcwiki.eu/index.php/765_FDC - and here: - http://www.cpcwiki.eu/imgs/f/f3/UPD765_Datasheet_OCRed.pdf - */ + Implementation based on the information contained here: + http://www.cpcwiki.eu/index.php/765_FDC + and here: + http://www.cpcwiki.eu/imgs/f/f3/UPD765_Datasheet_OCRed.pdf + */ public partial class NECUPD765 { /// diff --git a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPD765.cs b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPD765.cs index bef96504c45..38e90171d8b 100644 --- a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPD765.cs +++ b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPD765.cs @@ -7,11 +7,11 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC /// The NEC floppy disk controller (and floppy drive) found in the +3 /// /* - Implementation based on the information contained here: - http://www.cpcwiki.eu/index.php/765_FDC - and here: - http://www.cpcwiki.eu/imgs/f/f3/UPD765_Datasheet_OCRed.pdf - */ + Implementation based on the information contained here: + http://www.cpcwiki.eu/index.php/765_FDC + and here: + http://www.cpcwiki.eu/imgs/f/f3/UPD765_Datasheet_OCRed.pdf + */ public partial class NECUPD765 { /// @@ -84,56 +84,56 @@ private void InitCommandList() { CommandList = new List { - // read data - new Command { CommandDelegate = UPD_ReadData, CommandCode = 0x06, MT = true, MF = true, SK = true, IsRead = true, + // read data + new Command { CommandDelegate = UPD_ReadData, CommandCode = 0x06, MT = true, MF = true, SK = true, IsRead = true, Direction = CommandDirection.OUT, ParameterByteCount = 8, ResultByteCount = 7 }, - // read id - new Command { CommandDelegate = UPD_ReadID, CommandCode = 0x0a, MF = true, IsRead = true, + // read id + new Command { CommandDelegate = UPD_ReadID, CommandCode = 0x0a, MF = true, IsRead = true, Direction = CommandDirection.OUT, ParameterByteCount = 1, ResultByteCount = 7 }, - // specify - new Command { CommandDelegate = UPD_Specify, CommandCode = 0x03, + // specify + new Command { CommandDelegate = UPD_Specify, CommandCode = 0x03, Direction = CommandDirection.OUT, ParameterByteCount = 2, ResultByteCount = 0 }, - // read diagnostic - new Command { CommandDelegate = UPD_ReadDiagnostic, CommandCode = 0x02, MF = true, SK = true, IsRead = true, + // read diagnostic + new Command { CommandDelegate = UPD_ReadDiagnostic, CommandCode = 0x02, MF = true, SK = true, IsRead = true, Direction = CommandDirection.OUT, ParameterByteCount = 8, ResultByteCount = 7 }, - // scan equal - new Command { CommandDelegate = UPD_ScanEqual, CommandCode = 0x11, MT = true, MF = true, SK = true, IsRead = true, + // scan equal + new Command { CommandDelegate = UPD_ScanEqual, CommandCode = 0x11, MT = true, MF = true, SK = true, IsRead = true, Direction = CommandDirection.IN, ParameterByteCount = 8, ResultByteCount = 7 }, - // scan high or equal - new Command { CommandDelegate = UPD_ScanHighOrEqual, CommandCode = 0x1d, MT = true, MF = true, SK = true, IsRead = true, + // scan high or equal + new Command { CommandDelegate = UPD_ScanHighOrEqual, CommandCode = 0x1d, MT = true, MF = true, SK = true, IsRead = true, Direction = CommandDirection.IN, ParameterByteCount = 8, ResultByteCount = 7 }, - // scan low or equal - new Command { CommandDelegate = UPD_ScanLowOrEqual, CommandCode = 0x19, MT = true, MF = true, SK = true, IsRead = true, + // scan low or equal + new Command { CommandDelegate = UPD_ScanLowOrEqual, CommandCode = 0x19, MT = true, MF = true, SK = true, IsRead = true, Direction = CommandDirection.IN, ParameterByteCount = 8, ResultByteCount = 7 }, - // read deleted data - new Command { CommandDelegate = UPD_ReadDeletedData, CommandCode = 0x0c, MT = true, MF = true, SK = true, IsRead = true, + // read deleted data + new Command { CommandDelegate = UPD_ReadDeletedData, CommandCode = 0x0c, MT = true, MF = true, SK = true, IsRead = true, Direction = CommandDirection.OUT, ParameterByteCount = 8, ResultByteCount = 7 }, - // write data - new Command { CommandDelegate = UPD_WriteData, CommandCode = 0x05, MT = true, MF = true, IsWrite = true, + // write data + new Command { CommandDelegate = UPD_WriteData, CommandCode = 0x05, MT = true, MF = true, IsWrite = true, Direction = CommandDirection.IN, ParameterByteCount = 8, ResultByteCount = 7 }, - // write id - new Command { CommandDelegate = UPD_WriteID, CommandCode = 0x0d, MF = true, IsWrite = true, + // write id + new Command { CommandDelegate = UPD_WriteID, CommandCode = 0x0d, MF = true, IsWrite = true, Direction = CommandDirection.IN, ParameterByteCount = 5, ResultByteCount = 7 }, - // write deleted data - new Command { CommandDelegate = UPD_WriteDeletedData, CommandCode = 0x09, MT = true, MF = true, IsWrite = true, + // write deleted data + new Command { CommandDelegate = UPD_WriteDeletedData, CommandCode = 0x09, MT = true, MF = true, IsWrite = true, Direction = CommandDirection.IN, ParameterByteCount = 8, ResultByteCount = 7 }, - // seek - new Command { CommandDelegate = UPD_Seek, CommandCode = 0x0f, + // seek + new Command { CommandDelegate = UPD_Seek, CommandCode = 0x0f, Direction = CommandDirection.OUT, ParameterByteCount = 2, ResultByteCount = 0 }, - // recalibrate (seek track00) - new Command { CommandDelegate = UPD_Recalibrate, CommandCode = 0x07, + // recalibrate (seek track00) + new Command { CommandDelegate = UPD_Recalibrate, CommandCode = 0x07, Direction = CommandDirection.OUT, ParameterByteCount = 1, ResultByteCount = 0 }, - // sense interrupt status - new Command { CommandDelegate = UPD_SenseInterruptStatus, CommandCode = 0x08, + // sense interrupt status + new Command { CommandDelegate = UPD_SenseInterruptStatus, CommandCode = 0x08, Direction = CommandDirection.OUT, ParameterByteCount = 0, ResultByteCount = 2 }, - // sense drive status - new Command { CommandDelegate = UPD_SenseDriveStatus, CommandCode = 0x04, + // sense drive status + new Command { CommandDelegate = UPD_SenseDriveStatus, CommandCode = 0x04, Direction = CommandDirection.OUT, ParameterByteCount = 1, ResultByteCount = 1 }, - // version - new Command { CommandDelegate = UPD_Version, CommandCode = 0x10, + // version + new Command { CommandDelegate = UPD_Version, CommandCode = 0x10, Direction = CommandDirection.OUT, ParameterByteCount = 0, ResultByteCount = 1 }, - // invalid - new Command { CommandDelegate = UPD_Invalid, CommandCode = 0x00, + // invalid + new Command { CommandDelegate = UPD_Invalid, CommandCode = 0x00, Direction = CommandDirection.OUT, ParameterByteCount = 0, ResultByteCount = 1 }, }; } diff --git a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPS765.Static.cs b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPS765.Static.cs index ae70ad7a2ff..8923d8c804b 100644 --- a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPS765.Static.cs +++ b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPS765.Static.cs @@ -6,11 +6,11 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC /// Static helper methods /// /* - Implementation based on the information contained here: - http://www.cpcwiki.eu/index.php/765_FDC - and here: - http://www.cpcwiki.eu/imgs/f/f3/UPD765_Datasheet_OCRed.pdf - */ + Implementation based on the information contained here: + http://www.cpcwiki.eu/index.php/765_FDC + and here: + http://www.cpcwiki.eu/imgs/f/f3/UPD765_Datasheet_OCRed.pdf + */ public partial class NECUPD765 { /// diff --git a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/GateArray.cs b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/GateArray.cs index 69e2f536559..1b68b239863 100644 --- a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/GateArray.cs +++ b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/GateArray.cs @@ -146,34 +146,34 @@ private void SetPalette(GateArrayType gaType) /// private static readonly int[] CPCFirmwarePalette = { - Colors.ARGB(0x00, 0x00, 0x00), // Black 0 - Colors.ARGB(0x00, 0x00, 0x80), // Blue 1 - Colors.ARGB(0x00, 0x00, 0xFF), // Bright Blue 2 - Colors.ARGB(0x80, 0x00, 0x00), // Red 3 - Colors.ARGB(0x80, 0x00, 0x80), // Magenta 4 - Colors.ARGB(0x80, 0x00, 0xFF), // Mauve 5 - Colors.ARGB(0xFF, 0x00, 0x00), // Bright Red 6 - Colors.ARGB(0xFF, 0x00, 0x80), // Purple 7 - Colors.ARGB(0xFF, 0x00, 0xFF), // Bright Magenta 8 - Colors.ARGB(0x00, 0x80, 0x00), // Green 9 - Colors.ARGB(0x00, 0x80, 0x80), // Cyan 10 - Colors.ARGB(0x00, 0x80, 0xFF), // Sky Blue 11 - Colors.ARGB(0x80, 0x80, 0x00), // Yellow 12 - Colors.ARGB(0x80, 0x80, 0x80), // White 13 - Colors.ARGB(0x80, 0x80, 0xFF), // Pastel Blue 14 - Colors.ARGB(0xFF, 0x80, 0x00), // Orange 15 - Colors.ARGB(0xFF, 0x80, 0x80), // Pink 16 - Colors.ARGB(0xFF, 0x80, 0xFF), // Pastel Magenta 17 - Colors.ARGB(0x00, 0xFF, 0x00), // Bright Green 18 - Colors.ARGB(0x00, 0xFF, 0x80), // Sea Green 19 - Colors.ARGB(0x00, 0xFF, 0xFF), // Bright Cyan 20 - Colors.ARGB(0x80, 0xFF, 0x00), // Lime 21 - Colors.ARGB(0x80, 0xFF, 0x80), // Pastel Green 22 - Colors.ARGB(0x80, 0xFF, 0xFF), // Pastel Cyan 23 - Colors.ARGB(0xFF, 0xFF, 0x00), // Bright Yellow 24 - Colors.ARGB(0xFF, 0xFF, 0x80), // Pastel Yellow 25 - Colors.ARGB(0xFF, 0xFF, 0xFF), // Bright White 26 - }; + Colors.ARGB(0x00, 0x00, 0x00), // Black 0 + Colors.ARGB(0x00, 0x00, 0x80), // Blue 1 + Colors.ARGB(0x00, 0x00, 0xFF), // Bright Blue 2 + Colors.ARGB(0x80, 0x00, 0x00), // Red 3 + Colors.ARGB(0x80, 0x00, 0x80), // Magenta 4 + Colors.ARGB(0x80, 0x00, 0xFF), // Mauve 5 + Colors.ARGB(0xFF, 0x00, 0x00), // Bright Red 6 + Colors.ARGB(0xFF, 0x00, 0x80), // Purple 7 + Colors.ARGB(0xFF, 0x00, 0xFF), // Bright Magenta 8 + Colors.ARGB(0x00, 0x80, 0x00), // Green 9 + Colors.ARGB(0x00, 0x80, 0x80), // Cyan 10 + Colors.ARGB(0x00, 0x80, 0xFF), // Sky Blue 11 + Colors.ARGB(0x80, 0x80, 0x00), // Yellow 12 + Colors.ARGB(0x80, 0x80, 0x80), // White 13 + Colors.ARGB(0x80, 0x80, 0xFF), // Pastel Blue 14 + Colors.ARGB(0xFF, 0x80, 0x00), // Orange 15 + Colors.ARGB(0xFF, 0x80, 0x80), // Pink 16 + Colors.ARGB(0xFF, 0x80, 0xFF), // Pastel Magenta 17 + Colors.ARGB(0x00, 0xFF, 0x00), // Bright Green 18 + Colors.ARGB(0x00, 0xFF, 0x80), // Sea Green 19 + Colors.ARGB(0x00, 0xFF, 0xFF), // Bright Cyan 20 + Colors.ARGB(0x80, 0xFF, 0x00), // Lime 21 + Colors.ARGB(0x80, 0xFF, 0x80), // Pastel Green 22 + Colors.ARGB(0x80, 0xFF, 0xFF), // Pastel Cyan 23 + Colors.ARGB(0xFF, 0xFF, 0x00), // Bright Yellow 24 + Colors.ARGB(0xFF, 0xFF, 0x80), // Pastel Yellow 25 + Colors.ARGB(0xFF, 0xFF, 0xFF), // Bright White 26 + }; /// /// The standard CPC Pallete (ordered by hardware #) @@ -182,38 +182,38 @@ private void SetPalette(GateArrayType gaType) private static readonly int[] CPCHardwarePalette = { Colors.ARGB(0x80, 0x80, 0x80), // White - Colors.ARGB(0x80, 0x80, 0x80), // White (duplicate) - Colors.ARGB(0x00, 0xFF, 0x80), // Sea Green - Colors.ARGB(0xFF, 0xFF, 0x80), // Pastel Yellow - Colors.ARGB(0x00, 0x00, 0x80), // Blue - Colors.ARGB(0xFF, 0x00, 0x80), // Purple - Colors.ARGB(0x00, 0x80, 0x80), // Cyan - Colors.ARGB(0xFF, 0x80, 0x80), // Pink - Colors.ARGB(0xFF, 0x00, 0x80), // Purple (duplicate) - Colors.ARGB(0xFF, 0xFF, 0x80), // Pastel Yellow (duplicate) - Colors.ARGB(0xFF, 0xFF, 0x00), // Bright Yellow - Colors.ARGB(0xFF, 0xFF, 0xFF), // Bright White - Colors.ARGB(0xFF, 0x00, 0x00), // Bright Red - Colors.ARGB(0xFF, 0x00, 0xFF), // Bright Magenta - Colors.ARGB(0xFF, 0x80, 0x00), // Orange - Colors.ARGB(0xFF, 0x80, 0xFF), // Pastel Magenta - Colors.ARGB(0x00, 0x00, 0x80), // Blue (duplicate) - Colors.ARGB(0x00, 0xFF, 0x80), // Sea Green (duplicate) - Colors.ARGB(0x00, 0xFF, 0x00), // Bright Green - Colors.ARGB(0x00, 0xFF, 0xFF), // Bright Cyan - Colors.ARGB(0x00, 0x00, 0x00), // Black - Colors.ARGB(0x00, 0x00, 0xFF), // Bright Blue - Colors.ARGB(0x00, 0x80, 0x00), // Green - Colors.ARGB(0x00, 0x80, 0xFF), // Sky Blue - Colors.ARGB(0x80, 0x00, 0x80), // Magenta - Colors.ARGB(0x80, 0xFF, 0x80), // Pastel Green - Colors.ARGB(0x80, 0xFF, 0x00), // Lime - Colors.ARGB(0x80, 0xFF, 0xFF), // Pastel Cyan - Colors.ARGB(0x80, 0x00, 0x00), // Red - Colors.ARGB(0x80, 0x00, 0xFF), // Mauve - Colors.ARGB(0x80, 0x80, 0x00), // Yellow - Colors.ARGB(0x80, 0x80, 0xFF), // Pastel Blue - }; + Colors.ARGB(0x80, 0x80, 0x80), // White (duplicate) + Colors.ARGB(0x00, 0xFF, 0x80), // Sea Green + Colors.ARGB(0xFF, 0xFF, 0x80), // Pastel Yellow + Colors.ARGB(0x00, 0x00, 0x80), // Blue + Colors.ARGB(0xFF, 0x00, 0x80), // Purple + Colors.ARGB(0x00, 0x80, 0x80), // Cyan + Colors.ARGB(0xFF, 0x80, 0x80), // Pink + Colors.ARGB(0xFF, 0x00, 0x80), // Purple (duplicate) + Colors.ARGB(0xFF, 0xFF, 0x80), // Pastel Yellow (duplicate) + Colors.ARGB(0xFF, 0xFF, 0x00), // Bright Yellow + Colors.ARGB(0xFF, 0xFF, 0xFF), // Bright White + Colors.ARGB(0xFF, 0x00, 0x00), // Bright Red + Colors.ARGB(0xFF, 0x00, 0xFF), // Bright Magenta + Colors.ARGB(0xFF, 0x80, 0x00), // Orange + Colors.ARGB(0xFF, 0x80, 0xFF), // Pastel Magenta + Colors.ARGB(0x00, 0x00, 0x80), // Blue (duplicate) + Colors.ARGB(0x00, 0xFF, 0x80), // Sea Green (duplicate) + Colors.ARGB(0x00, 0xFF, 0x00), // Bright Green + Colors.ARGB(0x00, 0xFF, 0xFF), // Bright Cyan + Colors.ARGB(0x00, 0x00, 0x00), // Black + Colors.ARGB(0x00, 0x00, 0xFF), // Bright Blue + Colors.ARGB(0x00, 0x80, 0x00), // Green + Colors.ARGB(0x00, 0x80, 0xFF), // Sky Blue + Colors.ARGB(0x80, 0x00, 0x80), // Magenta + Colors.ARGB(0x80, 0xFF, 0x80), // Pastel Green + Colors.ARGB(0x80, 0xFF, 0x00), // Lime + Colors.ARGB(0x80, 0xFF, 0xFF), // Pastel Cyan + Colors.ARGB(0x80, 0x00, 0x00), // Red + Colors.ARGB(0x80, 0x00, 0xFF), // Mauve + Colors.ARGB(0x80, 0x80, 0x00), // Yellow + Colors.ARGB(0x80, 0x80, 0xFF), // Pastel Blue + }; /// /// 4bit Screen Mode Value diff --git a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Input/StandardKeyboard.cs b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Input/StandardKeyboard.cs index 38e31171572..5aa407da2f0 100644 --- a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Input/StandardKeyboard.cs +++ b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Input/StandardKeyboard.cs @@ -62,26 +62,26 @@ public StandardKeyboard(CPCBase machine) // scancode rows, ascending (Bit0 - Bit7) KeyboardMatrix = new string[] { - // 0x40 - "Key CURUP", "Key CURRIGHT", "Key CURDOWN", "Key NUM9", "Key NUM6", "Key NUM3", "Key ENTER", "Key NUMPERIOD", - // 0x41 - "Key CURLEFT", "Key COPY", "Key NUM7", "Key NUM8", "Key NUM5", "Key NUM1", "Key NUM2", "Key NUM0", - // 0x42 - "Key CLR", "Key LeftBracket", "Key RETURN", "Key RightBracket", "Key NUM4", "Key SHIFT", "Key BackSlash", "Key CONTROL", - // 0x43 - "Key Hat", "Key Dash", "Key @", "Key P", "Key SemiColon", "Key Colon", "Key ForwardSlash", "Key Period", - // 0x44 - "Key 0", "Key 9", "Key O", "Key I", "Key L", "Key K", "Key M", "Key Comma", - // 0x45 - "Key 8", "Key 7", "Key U", "Key Y", "Key H", "Key J", "Key N", "Key SPACE", - // 0x46 - "Key 6", "Key 5", "Key R", "Key T", "Key G", "Key F", "Key B", "Key V", - // 0x47 - "Key 4", "Key 3", "Key E", "Key W", "Key S", "Key D", "Key C", "Key X", - // 0x48 - "Key 1", "Key 2", "Key ESC", "Key Q", "Key TAB", "Key A", "Key CAPSLOCK", "Key Z", - // 0x49 - "P1 Up", "P1 Down", "P1 Left", "P1 Right", "P1 Fire1", "P1 Fire2", "P1 Fire3", "Key DEL", + // 0x40 + "Key CURUP", "Key CURRIGHT", "Key CURDOWN", "Key NUM9", "Key NUM6", "Key NUM3", "Key ENTER", "Key NUMPERIOD", + // 0x41 + "Key CURLEFT", "Key COPY", "Key NUM7", "Key NUM8", "Key NUM5", "Key NUM1", "Key NUM2", "Key NUM0", + // 0x42 + "Key CLR", "Key LeftBracket", "Key RETURN", "Key RightBracket", "Key NUM4", "Key SHIFT", "Key BackSlash", "Key CONTROL", + // 0x43 + "Key Hat", "Key Dash", "Key @", "Key P", "Key SemiColon", "Key Colon", "Key ForwardSlash", "Key Period", + // 0x44 + "Key 0", "Key 9", "Key O", "Key I", "Key L", "Key K", "Key M", "Key Comma", + // 0x45 + "Key 8", "Key 7", "Key U", "Key Y", "Key H", "Key J", "Key N", "Key SPACE", + // 0x46 + "Key 6", "Key 5", "Key R", "Key T", "Key G", "Key F", "Key B", "Key V", + // 0x47 + "Key 4", "Key 3", "Key E", "Key W", "Key S", "Key D", "Key C", "Key X", + // 0x48 + "Key 1", "Key 2", "Key ESC", "Key Q", "Key TAB", "Key A", "Key CAPSLOCK", "Key Z", + // 0x49 + "P1 Up", "P1 Down", "P1 Left", "P1 Right", "P1 Fire1", "P1 Fire2", "P1 Fire3", "Key DEL", }; // keystatus array to match the matrix diff --git a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/PPI_8255.cs b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/PPI_8255.cs index 42dab204059..34e082c7e24 100644 --- a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/PPI_8255.cs +++ b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/PPI_8255.cs @@ -290,11 +290,11 @@ public void Reset() } /* - #F4XX %xxxx0x00 xxxxxxxx 8255 PIO Port A (PSG Data) Read Write - #F5XX %xxxx0x01 xxxxxxxx 8255 PIO Port B (Vsync,PrnBusy,Tape,etc.) Read - - #F6XX %xxxx0x10 xxxxxxxx 8255 PIO Port C (KeybRow,Tape,PSG Control) - Write - #F7XX %xxxx0x11 xxxxxxxx 8255 PIO Control-Register - Write - */ + #F4XX %xxxx0x00 xxxxxxxx 8255 PIO Port A (PSG Data) Read Write + #F5XX %xxxx0x01 xxxxxxxx 8255 PIO Port B (Vsync,PrnBusy,Tape,etc.) Read - + #F6XX %xxxx0x10 xxxxxxxx 8255 PIO Port C (KeybRow,Tape,PSG Control) - Write + #F7XX %xxxx0x11 xxxxxxxx 8255 PIO Control-Register - Write + */ /// /// Device responds to an IN instruction diff --git a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Machine/CPCBase.cs b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Machine/CPCBase.cs index 25dd7d9b85d..05010bbcb64 100644 --- a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Machine/CPCBase.cs +++ b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Machine/CPCBase.cs @@ -202,52 +202,52 @@ public virtual void ExecuteFrame(bool render, bool renderSound) public virtual void HardReset() { /* - //ULADevice.ResetInterrupt(); - ROMPaged = 0; - SpecialPagingMode = false; - RAMPaged = 0; - CPU.RegPC = 0; - - Spectrum.SetCpuRegister("SP", 0xFFFF); - Spectrum.SetCpuRegister("IY", 0xFFFF); - Spectrum.SetCpuRegister("IX", 0xFFFF); - Spectrum.SetCpuRegister("AF", 0xFFFF); - Spectrum.SetCpuRegister("BC", 0xFFFF); - Spectrum.SetCpuRegister("DE", 0xFFFF); - Spectrum.SetCpuRegister("HL", 0xFFFF); - Spectrum.SetCpuRegister("SP", 0xFFFF); - Spectrum.SetCpuRegister("Shadow AF", 0xFFFF); - Spectrum.SetCpuRegister("Shadow BC", 0xFFFF); - Spectrum.SetCpuRegister("Shadow DE", 0xFFFF); - Spectrum.SetCpuRegister("Shadow HL", 0xFFFF); - - CPU.Regs[CPU.I] = 0; - CPU.Regs[CPU.R] = 0; - - TapeDevice.Reset(); - if (AYDevice != null) - AYDevice.Reset(); - - byte[][] rams = new byte[][] - { - RAM0, - RAM1, - RAM2, - RAM3, - RAM4, - RAM5, - RAM6, - RAM7 - }; - - foreach (var r in rams) - { - for (int i = 0; i < r.Length; i++) - { - r[i] = 0x00; - } - } - */ + //ULADevice.ResetInterrupt(); + ROMPaged = 0; + SpecialPagingMode = false; + RAMPaged = 0; + CPU.RegPC = 0; + + Spectrum.SetCpuRegister("SP", 0xFFFF); + Spectrum.SetCpuRegister("IY", 0xFFFF); + Spectrum.SetCpuRegister("IX", 0xFFFF); + Spectrum.SetCpuRegister("AF", 0xFFFF); + Spectrum.SetCpuRegister("BC", 0xFFFF); + Spectrum.SetCpuRegister("DE", 0xFFFF); + Spectrum.SetCpuRegister("HL", 0xFFFF); + Spectrum.SetCpuRegister("SP", 0xFFFF); + Spectrum.SetCpuRegister("Shadow AF", 0xFFFF); + Spectrum.SetCpuRegister("Shadow BC", 0xFFFF); + Spectrum.SetCpuRegister("Shadow DE", 0xFFFF); + Spectrum.SetCpuRegister("Shadow HL", 0xFFFF); + + CPU.Regs[CPU.I] = 0; + CPU.Regs[CPU.R] = 0; + + TapeDevice.Reset(); + if (AYDevice != null) + AYDevice.Reset(); + + byte[][] rams = new byte[][] + { + RAM0, + RAM1, + RAM2, + RAM3, + RAM4, + RAM5, + RAM6, + RAM7 + }; + + foreach (var r in rams) + { + for (int i = 0; i < r.Length; i++) + { + r[i] = 0x00; + } + } + */ } /// @@ -256,52 +256,52 @@ public virtual void HardReset() public virtual void SoftReset() { /* - //ULADevice.ResetInterrupt(); - ROMPaged = 0; - SpecialPagingMode = false; - RAMPaged = 0; - CPU.RegPC = 0; - - Spectrum.SetCpuRegister("SP", 0xFFFF); - Spectrum.SetCpuRegister("IY", 0xFFFF); - Spectrum.SetCpuRegister("IX", 0xFFFF); - Spectrum.SetCpuRegister("AF", 0xFFFF); - Spectrum.SetCpuRegister("BC", 0xFFFF); - Spectrum.SetCpuRegister("DE", 0xFFFF); - Spectrum.SetCpuRegister("HL", 0xFFFF); - Spectrum.SetCpuRegister("SP", 0xFFFF); - Spectrum.SetCpuRegister("Shadow AF", 0xFFFF); - Spectrum.SetCpuRegister("Shadow BC", 0xFFFF); - Spectrum.SetCpuRegister("Shadow DE", 0xFFFF); - Spectrum.SetCpuRegister("Shadow HL", 0xFFFF); - - CPU.Regs[CPU.I] = 0; - CPU.Regs[CPU.R] = 0; - - TapeDevice.Reset(); - if (AYDevice != null) - AYDevice.Reset(); - - byte[][] rams = new byte[][] - { - RAM0, - RAM1, - RAM2, - RAM3, - RAM4, - RAM5, - RAM6, - RAM7 - }; - - foreach (var r in rams) - { - for (int i = 0; i < r.Length; i++) - { - r[i] = 0x00; - } - } - */ + //ULADevice.ResetInterrupt(); + ROMPaged = 0; + SpecialPagingMode = false; + RAMPaged = 0; + CPU.RegPC = 0; + + Spectrum.SetCpuRegister("SP", 0xFFFF); + Spectrum.SetCpuRegister("IY", 0xFFFF); + Spectrum.SetCpuRegister("IX", 0xFFFF); + Spectrum.SetCpuRegister("AF", 0xFFFF); + Spectrum.SetCpuRegister("BC", 0xFFFF); + Spectrum.SetCpuRegister("DE", 0xFFFF); + Spectrum.SetCpuRegister("HL", 0xFFFF); + Spectrum.SetCpuRegister("SP", 0xFFFF); + Spectrum.SetCpuRegister("Shadow AF", 0xFFFF); + Spectrum.SetCpuRegister("Shadow BC", 0xFFFF); + Spectrum.SetCpuRegister("Shadow DE", 0xFFFF); + Spectrum.SetCpuRegister("Shadow HL", 0xFFFF); + + CPU.Regs[CPU.I] = 0; + CPU.Regs[CPU.R] = 0; + + TapeDevice.Reset(); + if (AYDevice != null) + AYDevice.Reset(); + + byte[][] rams = new byte[][] + { + RAM0, + RAM1, + RAM2, + RAM3, + RAM4, + RAM5, + RAM6, + RAM7 + }; + + foreach (var r in rams) + { + for (int i = 0; i < r.Length; i++) + { + r[i] = 0x00; + } + } + */ } public void SyncState(Serializer ser) diff --git a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Media/Disk/FloppyDisk.cs b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Media/Disk/FloppyDisk.cs index 581db2ef738..b8a9025e01e 100644 --- a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Media/Disk/FloppyDisk.cs +++ b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Media/Disk/FloppyDisk.cs @@ -399,102 +399,102 @@ public bool DetectHexagon(ref int[] weak) } /* - /// - /// Should be run at the end of the ParseDisk process - /// If speedlock is detected the flag is set in the disk image - /// - protected virtual void SpeedlockDetection() - { - - if (DiskTracks.Length == 0) - return; - - // check for speedlock copyright notice - string ident = Encoding.ASCII.GetString(DiskData, 0x100, 0x1400); - if (!ident.ContainsIgnoreCase("SPEEDLOCK")) - { - // speedlock not found - return; - } - - // get cylinder 0 - var cyl = DiskTracks[0]; - - // get sector with ID=2 - var sec = cyl.Sectors.Where(a => a.SectorID == 2).FirstOrDefault(); - - if (sec == null) - return; - - // check for already multiple weak copies - if (sec.ContainsMultipleWeakSectors || sec.SectorData.Length != 0x80 << sec.SectorSize) - return; - - // check for invalid crcs in sector 2 - if (sec.Status1.Bit(5) || sec.Status2.Bit(5)) - { - Protection = ProtectionType.Speedlock; - } - else - { - return; - } - - // we are going to create a total of 5 weak sector copies - // keeping the original copy - byte[] origData = sec.SectorData.ToArray(); - List data = new(); //TODO pretty sure the length and indices here are known in advance and this can just be an array --yoshi - - for (int i = 0; i < 6; i++) - { - for (int s = 0; s < origData.Length; s++) - { - if (i == 0) - { - data.Add(origData[s]); - continue; - } - - // deterministic 'random' implementation - int n = origData[s] + i + 1; - if (n > 0xff) - n = n - 0xff; - else if (n < 0) - n = 0xff + n; - - byte nByte = (byte)n; - - if (s < 336) - { - // non weak data - data.Add(origData[s]); - } - else if (s < 511) - { - // weak data - data.Add(nByte); - } - else if (s == 511) - { - // final sector byte - data.Add(nByte); - } - else - { - // speedlock sector should not be more than 512 bytes - // but in case it is just do non weak - data.Add(origData[i]); - } - } - } - - // commit the sector data - sec.SectorData = data.ToArray(); - sec.ContainsMultipleWeakSectors = true; - sec.ActualDataByteLength = data.Count; - - } - */ + /// + /// Should be run at the end of the ParseDisk process + /// If speedlock is detected the flag is set in the disk image + /// + protected virtual void SpeedlockDetection() + { + + if (DiskTracks.Length == 0) + return; + + // check for speedlock copyright notice + string ident = Encoding.ASCII.GetString(DiskData, 0x100, 0x1400); + if (!ident.ContainsIgnoreCase("SPEEDLOCK")) + { + // speedlock not found + return; + } + + // get cylinder 0 + var cyl = DiskTracks[0]; + + // get sector with ID=2 + var sec = cyl.Sectors.Where(a => a.SectorID == 2).FirstOrDefault(); + + if (sec == null) + return; + + // check for already multiple weak copies + if (sec.ContainsMultipleWeakSectors || sec.SectorData.Length != 0x80 << sec.SectorSize) + return; + + // check for invalid crcs in sector 2 + if (sec.Status1.Bit(5) || sec.Status2.Bit(5)) + { + Protection = ProtectionType.Speedlock; + } + else + { + return; + } + + // we are going to create a total of 5 weak sector copies + // keeping the original copy + byte[] origData = sec.SectorData.ToArray(); + List data = new(); //TODO pretty sure the length and indices here are known in advance and this can just be an array --yoshi + + for (int i = 0; i < 6; i++) + { + for (int s = 0; s < origData.Length; s++) + { + if (i == 0) + { + data.Add(origData[s]); + continue; + } + + // deterministic 'random' implementation + int n = origData[s] + i + 1; + if (n > 0xff) + n = n - 0xff; + else if (n < 0) + n = 0xff + n; + + byte nByte = (byte)n; + + if (s < 336) + { + // non weak data + data.Add(origData[s]); + } + else if (s < 511) + { + // weak data + data.Add(nByte); + } + else if (s == 511) + { + // final sector byte + data.Add(nByte); + } + else + { + // speedlock sector should not be more than 512 bytes + // but in case it is just do non weak + data.Add(origData[i]); + } + } + } + + // commit the sector data + sec.SectorData = data.ToArray(); + sec.ContainsMultipleWeakSectors = true; + sec.ActualDataByteLength = data.Count; + + } + */ /// /// Returns the track count for the disk @@ -668,14 +668,14 @@ public byte[] ActualData return res; /* - int copies = ActualDataByteLength / (0x80 << SectorSize); - var r = new Random(Seed: 4) // chosen by fair dice roll. guaranteed to be random. - .Next(0, copies - 1); - int step = r * (0x80 << SectorSize); - byte[] res = new byte[(0x80 << SectorSize)]; - Array.Copy(SectorData, step, res, 0, 0x80 << SectorSize); - return res; - */ + int copies = ActualDataByteLength / (0x80 << SectorSize); + var r = new Random(Seed: 4) // chosen by fair dice roll. guaranteed to be random. + .Next(0, copies - 1); + int step = r * (0x80 << SectorSize); + byte[] res = new byte[(0x80 << SectorSize)]; + Array.Copy(SectorData, step, res, 0, 0x80 << SectorSize); + return res; + */ } } } diff --git a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Media/Tape/CDT/CdtConverter.cs b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Media/Tape/CDT/CdtConverter.cs index b9264cbc08d..47a200de551 100644 --- a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Media/Tape/CDT/CdtConverter.cs +++ b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Media/Tape/CDT/CdtConverter.cs @@ -105,14 +105,14 @@ private int Adjust(int val) public override bool CheckType(byte[] data) { /* - // TZX Header - length: 10 bytes - Offset Value Type Description - 0x00 "ZXTape!" ASCII[7] TZX signature - 0x07 0x1A BYTE End of text file marker - 0x08 1 BYTE TZX major revision number - 0x09 20 BYTE TZX minor revision number - */ + // TZX Header + length: 10 bytes + Offset Value Type Description + 0x00 "ZXTape!" ASCII[7] TZX signature + 0x07 0x1A BYTE End of text file marker + 0x08 1 BYTE TZX major revision number + 0x09 20 BYTE TZX minor revision number + */ // check whether this is a valid tzx format file by looking at the identifier in the header // (first 7 bytes of the file) @@ -181,16 +181,16 @@ 0x09 20 BYTE TZX minor revision number } /* - // convert for Amstrad CPC - List newBlocks = new List(); - for (int i = 0; i < _datacorder.DataBlocks.Count; i++) - { - newBlocks.Add(ConvertClock(_datacorder.DataBlocks[i])); - } - - _datacorder.DataBlocks.Clear(); - _datacorder.DataBlocks.AddRange(newBlocks); - */ + // convert for Amstrad CPC + List newBlocks = new List(); + for (int i = 0; i < _datacorder.DataBlocks.Count; i++) + { + newBlocks.Add(ConvertClock(_datacorder.DataBlocks[i])); + } + + _datacorder.DataBlocks.Clear(); + _datacorder.DataBlocks.AddRange(newBlocks); + */ } /// @@ -1587,18 +1587,19 @@ private void ProcessBlockID34(byte[] data) _position += 8; } - /* length: [01,02,03]+04 - Offset Value Type Description - 0x00 - BYTE Snapshot type: - 00: .Z80 format - 01: .SNA format - 0x01 L BYTE[3] Snapshot length - 0x04 - BYTE[L] Snapshot itself - - This would enable one to snapshot the game at the start and still have all the tape blocks (level data, etc.) in the same file. - Only .Z80 and .SNA snapshots are supported for compatibility reasons! - The emulator should take care of that the snapshot is not taken while the actual Tape loading is taking place (which doesn't do much sense). - And when an emulator encounters the snapshot block it should load it and then continue with the next block. */ + /* length: [01,02,03]+04 + Offset Value Type Description + 0x00 - BYTE Snapshot type: + 00: .Z80 format + 01: .SNA format + 0x01 L BYTE[3] Snapshot length + 0x04 - BYTE[L] Snapshot itself + + This would enable one to snapshot the game at the start and still have all the tape blocks (level data, etc.) in the same file. + Only .Z80 and .SNA snapshots are supported for compatibility reasons! + The emulator should take care of that the snapshot is not taken while the actual Tape loading is taking place (which doesn't do much sense). + And when an emulator encounters the snapshot block it should load it and then continue with the next block. + */ private void ProcessBlockID40(byte[] data) { // currently not implemented properly in CPCHawk @@ -1647,12 +1648,13 @@ private TapeDataBlock DecodeDataBlock string description = string.Empty; // process the type byte - /* (The type is 0,1,2 or 3 for a Program, Number array, Character array or Code file. - A SCREEN$ file is regarded as a Code file with start address 16384 and length 6912 decimal. - If the file is a Program file, parameter 1 holds the autostart line number (or a number >=32768 if no LINE parameter was given) - and parameter 2 holds the start of the variable area relative to the start of the program. If it's a Code file, parameter 1 holds - the start of the code block when saved, and parameter 2 holds 32768. For data files finally, the byte at position 14 decimal holds the variable name.) - */ + /* + (The type is 0,1,2 or 3 for a Program, Number array, Character array or Code file. + A SCREEN$ file is regarded as a Code file with start address 16384 and length 6912 decimal. + If the file is a Program file, parameter 1 holds the autostart line number (or a number >=32768 if no LINE parameter was given) + and parameter 2 holds the start of the variable area relative to the start of the program. If it's a Code file, parameter 1 holds + the start of the code block when saved, and parameter 2 holds 32768. For data files finally, the byte at position 14 decimal holds the variable name.) + */ int blockSize = blockdata.Length; @@ -1708,49 +1710,49 @@ A SCREEN$ file is regarded as a Code file with start address 16384 and length 69 block.AddMetaData(BlockDescriptorTitle.Undefined, description); } /* - if (blockdata[0] == 0x00 && blockSize == 19 && (blockdata[1] == 0x00) || (blockdata[1] == 3 && blockdata.Length > 3)) - { - if (dataBlockType != DataBlockType.Turbo) - { - // This is the program header - string fileName = Encoding.ASCII.GetString(blockdata.Skip(2).Take(10).ToArray()).Trim(); - - string type = ""; - if (blockdata[0] == 0x00) - { - type = "Program"; - block.AddMetaData(BlockDescriptorTitle.Program, fileName); - } - else - { - type = "Bytes"; - block.AddMetaData(BlockDescriptorTitle.Bytes, fileName); - } - - // now build the description string - StringBuilder sb = new StringBuilder(); - sb.Append(type + ": "); - sb.Append(fileName + " "); - sb.Append(GetWordValue(blockdata, 14)); - sb.Append(':'); - sb.Append(GetWordValue(blockdata, 12)); - description = sb.ToString(); - } - } - else if (blockdata[0] == 0xFF) - { - // this is a data block - description = "Data Block " + (blockSize - 2) + "bytes"; - block.AddMetaData(BlockDescriptorTitle.Data_Bytes, (blockSize - 2).ToString() + " Bytes"); - } - else - { - // other type - description = $"#{blockdata[0]:X2} block, {blockSize} bytes"; - //description += (crc != 0) ? $", crc bad (#{crcFile:X2}!=#{crcValue:X2})" : ", crc ok"; - block.AddMetaData(BlockDescriptorTitle.Undefined, description); - } - */ + if (blockdata[0] == 0x00 && blockSize == 19 && (blockdata[1] == 0x00) || (blockdata[1] == 3 && blockdata.Length > 3)) + { + if (dataBlockType != DataBlockType.Turbo) + { + // This is the program header + string fileName = Encoding.ASCII.GetString(blockdata.Skip(2).Take(10).ToArray()).Trim(); + + string type = ""; + if (blockdata[0] == 0x00) + { + type = "Program"; + block.AddMetaData(BlockDescriptorTitle.Program, fileName); + } + else + { + type = "Bytes"; + block.AddMetaData(BlockDescriptorTitle.Bytes, fileName); + } + + // now build the description string + StringBuilder sb = new StringBuilder(); + sb.Append(type + ": "); + sb.Append(fileName + " "); + sb.Append(GetWordValue(blockdata, 14)); + sb.Append(':'); + sb.Append(GetWordValue(blockdata, 12)); + description = sb.ToString(); + } + } + else if (blockdata[0] == 0xFF) + { + // this is a data block + description = "Data Block " + (blockSize - 2) + "bytes"; + block.AddMetaData(BlockDescriptorTitle.Data_Bytes, (blockSize - 2).ToString() + " Bytes"); + } + else + { + // other type + description = $"#{blockdata[0]:X2} block, {blockSize} bytes"; + //description += (crc != 0) ? $", crc bad (#{crcFile:X2}!=#{crcValue:X2})" : ", crc ok"; + block.AddMetaData(BlockDescriptorTitle.Undefined, description); + } + */ } // update metadata @@ -1867,13 +1869,13 @@ private TapeDataBlock DecodeDataBlock int pilotCount = 3220; /* - // pilot count needs to be ascertained from flag byte - int pilotCount; - if (blockData[0] < 128) - pilotCount = 8063; - else - pilotCount = 3223; - */ + // pilot count needs to be ascertained from flag byte + int pilotCount; + if (blockData[0] < 128) + pilotCount = 8063; + else + pilotCount = 3223; + */ // now we can decode var nBlock = DecodeDataBlock diff --git a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Media/Tape/TapeDataBlock.cs b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Media/Tape/TapeDataBlock.cs index f6ddea27939..a457980b54b 100644 --- a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Media/Tape/TapeDataBlock.cs +++ b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Media/Tape/TapeDataBlock.cs @@ -53,29 +53,29 @@ public byte[] BlockData } /* - /// - /// An array of bytearray encoded strings (stored in this format for easy Bizhawk serialization) - /// Its basically tape information - /// - private byte[][] _tapeDescriptionData; - - /// - /// Returns the Tape Description Data in a human readable format - /// - public List TapeDescriptionData - { - get - { - List data = new List(); - - foreach (byte[] b in _tapeDescriptionData) - { - data.Add(Encoding.ASCII.GetString(b)); - } - - return data; - } - } + /// + /// An array of bytearray encoded strings (stored in this format for easy Bizhawk serialization) + /// Its basically tape information + /// + private byte[][] _tapeDescriptionData; + + /// + /// Returns the Tape Description Data in a human readable format + /// + public List TapeDescriptionData + { + get + { + List data = new List(); + + foreach (byte[] b in _tapeDescriptionData) + { + data.Add(Encoding.ASCII.GetString(b)); + } + + return data; + } + } */ diff --git a/src/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Sid.cs b/src/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Sid.cs index 17d6a19b82b..9dc7985889c 100644 --- a/src/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Sid.cs +++ b/src/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Sid.cs @@ -5,18 +5,18 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS public sealed partial class Sid { /* - Commodore SID 6581/8580 core. - - Many thanks to: - - Michael Huth for die shots of the 6569R3 chip (to get ideas how to implement) - http://mail.lipsia.de/~enigma/neu/6581.html - - Kevtris for figuring out ADSR tables - http://blog.kevtris.org/?p=13 - - Mixer for a lot of useful SID info - http://www.sid.fi/sidwiki/doku.php?id=sid-knowledge - - Documentation collected by the libsidplayfp team - https://sourceforge.net/projects/sidplay-residfp/ - */ + Commodore SID 6581/8580 core. + + Many thanks to: + - Michael Huth for die shots of the 6569R3 chip (to get ideas how to implement) + http://mail.lipsia.de/~enigma/neu/6581.html + - Kevtris for figuring out ADSR tables + http://blog.kevtris.org/?p=13 + - Mixer for a lot of useful SID info + http://www.sid.fi/sidwiki/doku.php?id=sid-knowledge + - Documentation collected by the libsidplayfp team + https://sourceforge.net/projects/sidplay-residfp/ + */ // ------------------------------------ public int _databus; diff --git a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Disk/NECUPD765.FDC.cs b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Disk/NECUPD765.FDC.cs index 04df7579e46..ef753015511 100644 --- a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Disk/NECUPD765.FDC.cs +++ b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Disk/NECUPD765.FDC.cs @@ -9,11 +9,11 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum /// FDC State and Methods /// /* - Implementation based on the information contained here: - http://www.cpcwiki.eu/index.php/765_FDC - and here: - http://www.cpcwiki.eu/imgs/f/f3/UPD765_Datasheet_OCRed.pdf - */ + Implementation based on the information contained here: + http://www.cpcwiki.eu/index.php/765_FDC + and here: + http://www.cpcwiki.eu/imgs/f/f3/UPD765_Datasheet_OCRed.pdf + */ public partial class NECUPD765 { /// @@ -206,69 +206,69 @@ public int CMDIndex /// Main status register (accessed via reads to port 0x2ffd) /// /* - b0..3 DB FDD0..3 Busy (seek/recalib active, until succesful sense intstat) - b4 CB FDC Busy (still in command-, execution- or result-phase) - b5 EXM Execution Mode (still in execution-phase, non_DMA_only) - b6 DIO Data Input/Output (0=CPU->FDC, 1=FDC->CPU) (see b7) - b7 RQM Request For Master (1=ready for next byte) (see b6 for direction) - */ + b0..3 DB FDD0..3 Busy (seek/recalib active, until succesful sense intstat) + b4 CB FDC Busy (still in command-, execution- or result-phase) + b5 EXM Execution Mode (still in execution-phase, non_DMA_only) + b6 DIO Data Input/Output (0=CPU->FDC, 1=FDC->CPU) (see b7) + b7 RQM Request For Master (1=ready for next byte) (see b6 for direction) + */ private byte StatusMain; /// /// Status Register 0 /// /* - b0,1 US Unit Select (driveno during interrupt) - b2 HD Head Address (head during interrupt) - b3 NR Not Ready (drive not ready or non-existing 2nd head selected) - b4 EC Equipment Check (drive failure or recalibrate failed (retry)) - b5 SE Seek End (Set if seek-command completed) - b6,7 IC Interrupt Code (0=OK, 1=aborted:readfail/OK if EN, 2=unknown cmd - or senseint with no int occured, 3=aborted:disc removed etc.) - */ + b0,1 US Unit Select (driveno during interrupt) + b2 HD Head Address (head during interrupt) + b3 NR Not Ready (drive not ready or non-existing 2nd head selected) + b4 EC Equipment Check (drive failure or recalibrate failed (retry)) + b5 SE Seek End (Set if seek-command completed) + b6,7 IC Interrupt Code (0=OK, 1=aborted:readfail/OK if EN, 2=unknown cmd + or senseint with no int occured, 3=aborted:disc removed etc.) + */ private byte Status0; /// /// Status Register 1 /// /* - b0 MA Missing Address Mark (Sector_ID or DAM not found) - b1 NW Not Writeable (tried to write/format disc with wprot_tab=on) - b2 ND No Data (Sector_ID not found, CRC fail in ID_field) - b3,6 0 Not used - b4 OR Over Run (CPU too slow in execution-phase (ca. 26us/Byte)) - b5 DE Data Error (CRC-fail in ID- or Data-Field) - b7 EN End of Track (set past most read/write commands) (see IC) - */ + b0 MA Missing Address Mark (Sector_ID or DAM not found) + b1 NW Not Writeable (tried to write/format disc with wprot_tab=on) + b2 ND No Data (Sector_ID not found, CRC fail in ID_field) + b3,6 0 Not used + b4 OR Over Run (CPU too slow in execution-phase (ca. 26us/Byte)) + b5 DE Data Error (CRC-fail in ID- or Data-Field) + b7 EN End of Track (set past most read/write commands) (see IC) + */ private byte Status1; /// /// Status Register 2 /// /* - b0 MD Missing Address Mark in Data Field (DAM not found) - b1 BC Bad Cylinder (read/programmed track-ID different and read-ID = FF) - b2 SN Scan Not Satisfied (no fitting sector found) - b3 SH Scan Equal Hit (equal) - b4 WC Wrong Cylinder (read/programmed track-ID different) (see b1) - b5 DD Data Error in Data Field (CRC-fail in data-field) - b6 CM Control Mark (read/scan command found sector with deleted DAM) - b7 0 Not Used - */ + b0 MD Missing Address Mark in Data Field (DAM not found) + b1 BC Bad Cylinder (read/programmed track-ID different and read-ID = FF) + b2 SN Scan Not Satisfied (no fitting sector found) + b3 SH Scan Equal Hit (equal) + b4 WC Wrong Cylinder (read/programmed track-ID different) (see b1) + b5 DD Data Error in Data Field (CRC-fail in data-field) + b6 CM Control Mark (read/scan command found sector with deleted DAM) + b7 0 Not Used + */ private byte Status2; /// /// Status Register 3 /// /* - b0,1 US Unit Select (pin 28,29 of FDC) - b2 HD Head Address (pin 27 of FDC) - b3 TS Two Side (0=yes, 1=no (!)) - b4 T0 Track 0 (on track 0 we are) - b5 RY Ready (drive ready signal) - b6 WP Write Protected (write protected) - b7 FT Fault (if supported: 1=Drive failure) - */ + b0,1 US Unit Select (pin 28,29 of FDC) + b2 HD Head Address (pin 27 of FDC) + b3 TS Two Side (0=yes, 1=no (!)) + b4 T0 Track 0 (on track 0 we are) + b5 RY Ready (drive ready signal) + b6 WP Write Protected (write protected) + b7 FT Fault (if supported: 1=Drive failure) + */ private byte Status3; /// @@ -2150,16 +2150,16 @@ private void UPD_SenseInterruptStatus() ResBuffer[1] = ActiveDrive.CurrentTrackID; } /* - else if (ActiveDrive.SeekStatus == SEEK_INTACKNOWLEDGED) - { - // DriveA interrupt has already been acknowledged - ActiveDrive.SeekStatus = SEEK_IDLE; - - ResLength = 1; - Status0 = 192; - ResBuffer[0] = Status0; - } - */ + else if (ActiveDrive.SeekStatus == SEEK_INTACKNOWLEDGED) + { + // DriveA interrupt has already been acknowledged + ActiveDrive.SeekStatus = SEEK_IDLE; + + ResLength = 1; + Status0 = 192; + ResBuffer[0] = Status0; + } + */ else if (ActiveDrive.SeekStatus == SEEK_IDLE) { // SIS with no interrupt @@ -2554,14 +2554,14 @@ private bool ParseCommandByte(byte cmdByte) } /* - if ((CMD_FLAG_MF && !ActiveCommand.MF) - || (CMD_FLAG_MT && !ActiveCommand.MT) - || (CMD_FLAG_SK && !ActiveCommand.SK)) - { - // command byte included spurious bit 5,6 or 7 flags - CMDIndex = CommandList.Count - 1; - } - */ + if ((CMD_FLAG_MF && !ActiveCommand.MF) + || (CMD_FLAG_MT && !ActiveCommand.MT) + || (CMD_FLAG_SK && !ActiveCommand.SK)) + { + // command byte included spurious bit 5,6 or 7 flags + CMDIndex = CommandList.Count - 1; + } + */ } CommCounter = 0; @@ -2572,13 +2572,13 @@ private bool ParseCommandByte(byte cmdByte) ActivePhase = Phase.Command; /* - // check for invalid SIS - if (ActiveInterrupt == InterruptState.None && CMDIndex == CC_SENSE_INTSTATUS) - { - CMDIndex = CC_INVALID; - //ActiveCommand.CommandDelegate(InstructionState.StartResult); - } - */ + // check for invalid SIS + if (ActiveInterrupt == InterruptState.None && CMDIndex == CC_SENSE_INTSTATUS) + { + CMDIndex = CC_INVALID; + //ActiveCommand.CommandDelegate(InstructionState.StartResult); + } + */ // set reslength ResLength = ActiveCommand.ResultByteCount; diff --git a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Disk/NECUPD765.FDD.cs b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Disk/NECUPD765.FDD.cs index 3768a0694a1..79adcd0f6e4 100644 --- a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Disk/NECUPD765.FDD.cs +++ b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Disk/NECUPD765.FDD.cs @@ -7,11 +7,11 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum /// Floppy drive related stuff /// /* - Implementation based on the information contained here: - http://www.cpcwiki.eu/index.php/765_FDC - and here: - http://www.cpcwiki.eu/imgs/f/f3/UPD765_Datasheet_OCRed.pdf - */ + Implementation based on the information contained here: + http://www.cpcwiki.eu/index.php/765_FDC + and here: + http://www.cpcwiki.eu/imgs/f/f3/UPD765_Datasheet_OCRed.pdf + */ public partial class NECUPD765 : IFDDHost { /// @@ -291,424 +291,424 @@ public byte CurrentTrackID public bool FLAG_TRACK0 => TrackIndex == 0; /* - /// - /// Moves the head across the disk cylinders - /// - public void MoveHead(SkipDirection direction, int cylinderCount) - { - // get total tracks - int trackCount = Disk.DiskTracks.Length; - - int trk = 0; - - switch (direction) - { - case SkipDirection.Increment: - trk = (int)CurrentTrack + cylinderCount; - if (trk >= trackCount) - { - // past the last track - trk = trackCount - 1; - } - else if (trk < 0) - trk = 0; - break; - case SkipDirection.Decrement: - trk = (int)CurrentTrack - cylinderCount; - if (trk < 0) - { - // before the first track - trk = 0; - } - else if (trk >= trackCount) - trk = trackCount - 1; - break; - } - - // move the head - CurrentTrack = (byte)trk; - } - */ + /// + /// Moves the head across the disk cylinders + /// + public void MoveHead(SkipDirection direction, int cylinderCount) + { + // get total tracks + int trackCount = Disk.DiskTracks.Length; + + int trk = 0; + + switch (direction) + { + case SkipDirection.Increment: + trk = (int)CurrentTrack + cylinderCount; + if (trk >= trackCount) + { + // past the last track + trk = trackCount - 1; + } + else if (trk < 0) + trk = 0; + break; + case SkipDirection.Decrement: + trk = (int)CurrentTrack - cylinderCount; + if (trk < 0) + { + // before the first track + trk = 0; + } + else if (trk >= trackCount) + trk = trackCount - 1; + break; + } + + // move the head + CurrentTrack = (byte)trk; + } + */ /* - /// - /// Finds a supplied sector - /// - public FloppyDisk.Sector FindSector(ref byte[] resBuffer, CommandParameters prms) - { - int index =CurrentSector; - int lc = 0; - FloppyDisk.Sector sector = null; - - bool found = false; - - do - { - sector = Disk.DiskTracks[CurrentTrack].Sectors[index]; - if (sector != null && sector.SectorID == prms.Sector) - { - // sector found - // check for data errors - if ((sector.Status1 & 0x20) != 0 || (sector.Status2 & 0x20) != 0) - { - // data errors found - } - found = true; - break; - } - - // sector doesnt match - var c = Disk.DiskTracks[CurrentTrack].Sectors[index].TrackNumber; - if (c == 255) - { - // bad cylinder - resBuffer[RS_ST2] |= 0x02; - } - else if (prms.Cylinder != c) - { - // cylinder mismatch - resBuffer[RS_ST2] |= 0x10; - } - - // increment index - index++; - - if (index >= Disk.DiskTracks[CurrentTrack].NumberOfSectors) - { - // out of bounds - index = 0; - lc++; - } - - } while (lc < 2); - - if ((resBuffer[RS_ST2] & 0x02) != 0) - { - // bad cylinder set - remove no cylinder - UnSetBit(SR2_WC, ref resBuffer[RS_ST2]); - } - - // update current sector - CurrentSector = index; - - if (found) - return sector; - else - return null; - } - - - /// - /// Populates a result buffer - /// - public void FillResult(ref byte[] resBuffer, CHRN chrn) - { - // clear results - resBuffer[RS_ST0] = 0; - resBuffer[RS_ST1] = 0; - resBuffer[RS_ST2] = 0; - resBuffer[RS_C] = 0; - resBuffer[RS_H] = 0; - resBuffer[RS_R] = 0; - resBuffer[RS_N] = 0; - - if (chrn == null) - { - // no chrn supplied - resBuffer[RS_ST0] = ST0; - resBuffer[RS_ST1] = 0; - resBuffer[RS_ST2] = 0; - resBuffer[RS_C] = 0; - resBuffer[RS_H] = 0; - resBuffer[RS_R] = 0; - resBuffer[RS_N] = 0; - } - } - - - - /// - /// Populates the result buffer with ReadID data - /// - public void ReadID(ref byte[] resBuffer) - { - if (CheckDriveStatus() == false) - { - // drive not ready - resBuffer[RS_ST0] = ST0; - return; - } - - var track = Disk.DiskTracks.Where(a => a.TrackNumber == CurrentTrack).FirstOrDefault(); - - if (track != null && track.NumberOfSectors > 0) - { - // formatted track - - // get the current sector - int index = CurrentSector; - - // is the index out of bounds? - if (index >= track.NumberOfSectors) - { - // reset the index - index = 0; - } - - // read the sector data - var data = track.Sectors[index]; - resBuffer[RS_C] = data.TrackNumber; - resBuffer[RS_H] = data.SideNumber; - resBuffer[RS_R] = data.SectorID; - resBuffer[RS_N] = data.SectorSize; - - resBuffer[RS_ST0] = ST0; - - // increment the current sector - CurrentSector = index + 1; - return; - } - else - { - // unformatted track? - resBuffer[RS_C] = FDC.CommBuffer[CM_C]; - resBuffer[RS_H] = FDC.CommBuffer[CM_H]; - resBuffer[RS_R] = FDC.CommBuffer[CM_R]; - resBuffer[RS_N] = FDC.CommBuffer[CM_N]; - - SetBit(SR0_IC0, ref ST0); - resBuffer[RS_ST0] = ST0; - resBuffer[RS_ST1] = 0x01; - return; - } - } - */ + /// + /// Finds a supplied sector + /// + public FloppyDisk.Sector FindSector(ref byte[] resBuffer, CommandParameters prms) + { + int index =CurrentSector; + int lc = 0; + FloppyDisk.Sector sector = null; + + bool found = false; + + do + { + sector = Disk.DiskTracks[CurrentTrack].Sectors[index]; + if (sector != null && sector.SectorID == prms.Sector) + { + // sector found + // check for data errors + if ((sector.Status1 & 0x20) != 0 || (sector.Status2 & 0x20) != 0) + { + // data errors found + } + found = true; + break; + } + + // sector doesnt match + var c = Disk.DiskTracks[CurrentTrack].Sectors[index].TrackNumber; + if (c == 255) + { + // bad cylinder + resBuffer[RS_ST2] |= 0x02; + } + else if (prms.Cylinder != c) + { + // cylinder mismatch + resBuffer[RS_ST2] |= 0x10; + } + + // increment index + index++; + + if (index >= Disk.DiskTracks[CurrentTrack].NumberOfSectors) + { + // out of bounds + index = 0; + lc++; + } + + } while (lc < 2); + + if ((resBuffer[RS_ST2] & 0x02) != 0) + { + // bad cylinder set - remove no cylinder + UnSetBit(SR2_WC, ref resBuffer[RS_ST2]); + } + + // update current sector + CurrentSector = index; + + if (found) + return sector; + else + return null; + } + + + /// + /// Populates a result buffer + /// + public void FillResult(ref byte[] resBuffer, CHRN chrn) + { + // clear results + resBuffer[RS_ST0] = 0; + resBuffer[RS_ST1] = 0; + resBuffer[RS_ST2] = 0; + resBuffer[RS_C] = 0; + resBuffer[RS_H] = 0; + resBuffer[RS_R] = 0; + resBuffer[RS_N] = 0; + + if (chrn == null) + { + // no chrn supplied + resBuffer[RS_ST0] = ST0; + resBuffer[RS_ST1] = 0; + resBuffer[RS_ST2] = 0; + resBuffer[RS_C] = 0; + resBuffer[RS_H] = 0; + resBuffer[RS_R] = 0; + resBuffer[RS_N] = 0; + } + } + + + + /// + /// Populates the result buffer with ReadID data + /// + public void ReadID(ref byte[] resBuffer) + { + if (CheckDriveStatus() == false) + { + // drive not ready + resBuffer[RS_ST0] = ST0; + return; + } + + var track = Disk.DiskTracks.Where(a => a.TrackNumber == CurrentTrack).FirstOrDefault(); + + if (track != null && track.NumberOfSectors > 0) + { + // formatted track + + // get the current sector + int index = CurrentSector; + + // is the index out of bounds? + if (index >= track.NumberOfSectors) + { + // reset the index + index = 0; + } + + // read the sector data + var data = track.Sectors[index]; + resBuffer[RS_C] = data.TrackNumber; + resBuffer[RS_H] = data.SideNumber; + resBuffer[RS_R] = data.SectorID; + resBuffer[RS_N] = data.SectorSize; + + resBuffer[RS_ST0] = ST0; + + // increment the current sector + CurrentSector = index + 1; + return; + } + else + { + // unformatted track? + resBuffer[RS_C] = FDC.CommBuffer[CM_C]; + resBuffer[RS_H] = FDC.CommBuffer[CM_H]; + resBuffer[RS_R] = FDC.CommBuffer[CM_R]; + resBuffer[RS_N] = FDC.CommBuffer[CM_N]; + + SetBit(SR0_IC0, ref ST0); + resBuffer[RS_ST0] = ST0; + resBuffer[RS_ST1] = 0x01; + return; + } + } + */ /* - /// - /// The drive performs a seek operation if necessary - /// Return value TRUE indicates seek complete - /// - public void DoSeek() - { - if (CurrentState is not (DriveMainState.Recalibrate or DriveMainState.Seek)) - { - // no seek/recalibrate has been asked for - return; - } - - if (GetBit(ID, FDC.StatusMain)) - { - // drive is already seeking - return; - } - - RunSeekCycle(); - } - - /// - /// Runs a seek cycle - /// - public void RunSeekCycle() - { - for (;;) - { - switch (SeekState) - { - // seek or recalibrate has been requested - case SeekSubState.Idle: - - if (CurrentState == DriveMainState.Recalibrate) - { - // recalibrate always seeks to track 0 - SeekingTrack = 0; - } - SeekState = SeekSubState.MoveInit; - - // mark drive as busy - // this should be cleared by SIS command - SetBit(ID, ref FDC.StatusMain); - - break; - - // setup for the head move - case SeekSubState.MoveInit: - - if (CurrentTrack == SeekingTrack) - { - // we are already at the required track - if (CurrentState is DriveMainState.Recalibrate && !FLAG_TRACK0) - { - // recalibration fail - SeekIntState = SeekIntStatus.Abnormal; - - // raise seek interrupt - FDC.ActiveInterrupt = InterruptState.Seek; - - // unset DB bit - UnSetBit(ID, ref FDC.StatusMain); - - // equipment check - SetBit(SR0_EC, ref FDC.Status0); - - SeekState = SeekSubState.PerformCompletion; - break; - } - - if (CurrentState is DriveMainState.Recalibrate && FLAG_TRACK0) - { - // recalibration success - SeekIntState = SeekIntStatus.Normal; - - // raise seek interrupt - FDC.ActiveInterrupt = InterruptState.Seek; - - // unset DB bit - UnSetBit(ID, ref FDC.StatusMain); - - SeekState = SeekSubState.PerformCompletion; - break; - } - } - - // check for error - if (IntStatus >= IC_ABORTED_DISCREMOVED || Disk == null) - { - // drive not ready - FLAG_READY = false; - - // drive not ready - SeekIntState = SeekIntStatus.DriveNotReady; - - // cancel any interrupt - FDC.ActiveInterrupt = InterruptState.None; - - // unset DB bit - UnSetBit(ID, ref FDC.StatusMain); - - SeekState = SeekSubState.PerformCompletion; - break; - } - - if (SeekCounter > 1) - { - // not ready to seek yet - SeekCounter--; - return; - } - - if (FDC.SRT < 1 && CurrentTrack != SeekingTrack) - { - SeekState = SeekSubState.MoveImmediate; - break; - } - - // head move - SeekState = SeekSubState.HeadMove; - - break; - - case SeekSubState.HeadMove: - - // do the seek - SeekCounter = FDC.SRT; - - if (CurrentTrack < SeekingTrack) - { - // we are seeking forward - var delta = SeekingTrack - CurrentTrack; - MoveHead(SkipDirection.Increment, 1); - } - else if (CurrentTrack > SeekingTrack) - { - // we are seeking backward - var delta = CurrentTrack - SeekingTrack; - MoveHead(SkipDirection.Decrement, 1); - } - - // should the seek be completed now? - if (CurrentTrack == SeekingTrack) - { - SeekState = SeekSubState.PerformCompletion; - break; - } - - // seek not finished yet - return; - - // seek emulation processed immediately - case SeekSubState.MoveImmediate: - - if (CurrentTrack < SeekingTrack) - { - // we are seeking forward - var delta = SeekingTrack - CurrentTrack; - MoveHead(SkipDirection.Increment, delta); - - } - else if (CurrentTrack > SeekingTrack) - { - // we are seeking backward - var delta = CurrentTrack - SeekingTrack; - MoveHead(SkipDirection.Decrement, delta); - } - - SeekState = SeekSubState.PerformCompletion; - break; - - case SeekSubState.PerformCompletion: - SeekDone(); - SeekState = SeekSubState.SeekCompleted; - break; - - case SeekSubState.SeekCompleted: - // seek has already completed - return; - } - } - } - - /// - /// Called when a seek operation has completed - /// - public void SeekDone() - { - SeekCounter = 0; - SeekingTrack = CurrentTrack; - - // generate ST0 register data - - // get only the IC bits - IntStatus &= IC_ABORTED_DISCREMOVED; - - // drive ready? - if (!FLAG_READY) - { - SetBit(SR0_NR, ref IntStatus); - SetBit(SR0_EC, ref IntStatus); - - // are we recalibrating? - if (CurrentState == DriveMainState.Recalibrate) - { - SetBit(SR0_EC, ref IntStatus); - } - } - - // set seek end - SetBit(SR0_SE, ref IntStatus); - /* - // head address - if (CurrentSide > 0) - { - SetBit(SR0_HD, ref IntStatus); - - // drive only supports 1 head - // set the EC bit - SetBit(SR0_EC, ref IntStatus); - } - */ + /// + /// The drive performs a seek operation if necessary + /// Return value TRUE indicates seek complete + /// + public void DoSeek() + { + if (CurrentState is not (DriveMainState.Recalibrate or DriveMainState.Seek)) + { + // no seek/recalibrate has been asked for + return; + } + + if (GetBit(ID, FDC.StatusMain)) + { + // drive is already seeking + return; + } + + RunSeekCycle(); + } + + /// + /// Runs a seek cycle + /// + public void RunSeekCycle() + { + for (;;) + { + switch (SeekState) + { + // seek or recalibrate has been requested + case SeekSubState.Idle: + + if (CurrentState == DriveMainState.Recalibrate) + { + // recalibrate always seeks to track 0 + SeekingTrack = 0; + } + SeekState = SeekSubState.MoveInit; + + // mark drive as busy + // this should be cleared by SIS command + SetBit(ID, ref FDC.StatusMain); + + break; + + // setup for the head move + case SeekSubState.MoveInit: + + if (CurrentTrack == SeekingTrack) + { + // we are already at the required track + if (CurrentState is DriveMainState.Recalibrate && !FLAG_TRACK0) + { + // recalibration fail + SeekIntState = SeekIntStatus.Abnormal; + + // raise seek interrupt + FDC.ActiveInterrupt = InterruptState.Seek; + + // unset DB bit + UnSetBit(ID, ref FDC.StatusMain); + + // equipment check + SetBit(SR0_EC, ref FDC.Status0); + + SeekState = SeekSubState.PerformCompletion; + break; + } + + if (CurrentState is DriveMainState.Recalibrate && FLAG_TRACK0) + { + // recalibration success + SeekIntState = SeekIntStatus.Normal; + + // raise seek interrupt + FDC.ActiveInterrupt = InterruptState.Seek; + + // unset DB bit + UnSetBit(ID, ref FDC.StatusMain); + + SeekState = SeekSubState.PerformCompletion; + break; + } + } + + // check for error + if (IntStatus >= IC_ABORTED_DISCREMOVED || Disk == null) + { + // drive not ready + FLAG_READY = false; + + // drive not ready + SeekIntState = SeekIntStatus.DriveNotReady; + + // cancel any interrupt + FDC.ActiveInterrupt = InterruptState.None; + + // unset DB bit + UnSetBit(ID, ref FDC.StatusMain); + + SeekState = SeekSubState.PerformCompletion; + break; + } + + if (SeekCounter > 1) + { + // not ready to seek yet + SeekCounter--; + return; + } + + if (FDC.SRT < 1 && CurrentTrack != SeekingTrack) + { + SeekState = SeekSubState.MoveImmediate; + break; + } + + // head move + SeekState = SeekSubState.HeadMove; + + break; + + case SeekSubState.HeadMove: + + // do the seek + SeekCounter = FDC.SRT; + + if (CurrentTrack < SeekingTrack) + { + // we are seeking forward + var delta = SeekingTrack - CurrentTrack; + MoveHead(SkipDirection.Increment, 1); + } + else if (CurrentTrack > SeekingTrack) + { + // we are seeking backward + var delta = CurrentTrack - SeekingTrack; + MoveHead(SkipDirection.Decrement, 1); + } + + // should the seek be completed now? + if (CurrentTrack == SeekingTrack) + { + SeekState = SeekSubState.PerformCompletion; + break; + } + + // seek not finished yet + return; + + // seek emulation processed immediately + case SeekSubState.MoveImmediate: + + if (CurrentTrack < SeekingTrack) + { + // we are seeking forward + var delta = SeekingTrack - CurrentTrack; + MoveHead(SkipDirection.Increment, delta); + + } + else if (CurrentTrack > SeekingTrack) + { + // we are seeking backward + var delta = CurrentTrack - SeekingTrack; + MoveHead(SkipDirection.Decrement, delta); + } + + SeekState = SeekSubState.PerformCompletion; + break; + + case SeekSubState.PerformCompletion: + SeekDone(); + SeekState = SeekSubState.SeekCompleted; + break; + + case SeekSubState.SeekCompleted: + // seek has already completed + return; + } + } + } + + /// + /// Called when a seek operation has completed + /// + public void SeekDone() + { + SeekCounter = 0; + SeekingTrack = CurrentTrack; + + // generate ST0 register data + + // get only the IC bits + IntStatus &= IC_ABORTED_DISCREMOVED; + + // drive ready? + if (!FLAG_READY) + { + SetBit(SR0_NR, ref IntStatus); + SetBit(SR0_EC, ref IntStatus); + + // are we recalibrating? + if (CurrentState == DriveMainState.Recalibrate) + { + SetBit(SR0_EC, ref IntStatus); + } + } + + // set seek end + SetBit(SR0_SE, ref IntStatus); + /* + // head address + if (CurrentSide > 0) + { + SetBit(SR0_HD, ref IntStatus); + + // drive only supports 1 head + // set the EC bit + SetBit(SR0_EC, ref IntStatus); + } + */ /* // UnitSelect SetUnitSelect(ID, ref IntStatus); diff --git a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Disk/NECUPD765.cs b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Disk/NECUPD765.cs index 1339c5524b2..ca8210a636b 100644 --- a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Disk/NECUPD765.cs +++ b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Disk/NECUPD765.cs @@ -7,11 +7,11 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum /// The NEC floppy disk controller (and floppy drive) found in the +3 /// /* - Implementation based on the information contained here: - http://www.cpcwiki.eu/index.php/765_FDC - and here: - http://www.cpcwiki.eu/imgs/f/f3/UPD765_Datasheet_OCRed.pdf - */ + Implementation based on the information contained here: + http://www.cpcwiki.eu/index.php/765_FDC + and here: + http://www.cpcwiki.eu/imgs/f/f3/UPD765_Datasheet_OCRed.pdf + */ public partial class NECUPD765 { /// @@ -84,56 +84,56 @@ private void InitCommandList() { CommandList = new List { - // read data - new Command { CommandDelegate = UPD_ReadData, CommandCode = 0x06, MT = true, MF = true, SK = true, IsRead = true, + // read data + new Command { CommandDelegate = UPD_ReadData, CommandCode = 0x06, MT = true, MF = true, SK = true, IsRead = true, Direction = CommandDirection.OUT, ParameterByteCount = 8, ResultByteCount = 7 }, - // read id - new Command { CommandDelegate = UPD_ReadID, CommandCode = 0x0a, MF = true, IsRead = true, + // read id + new Command { CommandDelegate = UPD_ReadID, CommandCode = 0x0a, MF = true, IsRead = true, Direction = CommandDirection.OUT, ParameterByteCount = 1, ResultByteCount = 7 }, - // specify - new Command { CommandDelegate = UPD_Specify, CommandCode = 0x03, + // specify + new Command { CommandDelegate = UPD_Specify, CommandCode = 0x03, Direction = CommandDirection.OUT, ParameterByteCount = 2, ResultByteCount = 0 }, - // read diagnostic - new Command { CommandDelegate = UPD_ReadDiagnostic, CommandCode = 0x02, MF = true, SK = true, IsRead = true, + // read diagnostic + new Command { CommandDelegate = UPD_ReadDiagnostic, CommandCode = 0x02, MF = true, SK = true, IsRead = true, Direction = CommandDirection.OUT, ParameterByteCount = 8, ResultByteCount = 7 }, - // scan equal - new Command { CommandDelegate = UPD_ScanEqual, CommandCode = 0x11, MT = true, MF = true, SK = true, IsRead = true, + // scan equal + new Command { CommandDelegate = UPD_ScanEqual, CommandCode = 0x11, MT = true, MF = true, SK = true, IsRead = true, Direction = CommandDirection.IN, ParameterByteCount = 8, ResultByteCount = 7 }, - // scan high or equal - new Command { CommandDelegate = UPD_ScanHighOrEqual, CommandCode = 0x1d, MT = true, MF = true, SK = true, IsRead = true, + // scan high or equal + new Command { CommandDelegate = UPD_ScanHighOrEqual, CommandCode = 0x1d, MT = true, MF = true, SK = true, IsRead = true, Direction = CommandDirection.IN, ParameterByteCount = 8, ResultByteCount = 7 }, - // scan low or equal - new Command { CommandDelegate = UPD_ScanLowOrEqual, CommandCode = 0x19, MT = true, MF = true, SK = true, IsRead = true, + // scan low or equal + new Command { CommandDelegate = UPD_ScanLowOrEqual, CommandCode = 0x19, MT = true, MF = true, SK = true, IsRead = true, Direction = CommandDirection.IN, ParameterByteCount = 8, ResultByteCount = 7 }, - // read deleted data - new Command { CommandDelegate = UPD_ReadDeletedData, CommandCode = 0x0c, MT = true, MF = true, SK = true, IsRead = true, + // read deleted data + new Command { CommandDelegate = UPD_ReadDeletedData, CommandCode = 0x0c, MT = true, MF = true, SK = true, IsRead = true, Direction = CommandDirection.OUT, ParameterByteCount = 8, ResultByteCount = 7 }, - // write data - new Command { CommandDelegate = UPD_WriteData, CommandCode = 0x05, MT = true, MF = true, IsWrite = true, + // write data + new Command { CommandDelegate = UPD_WriteData, CommandCode = 0x05, MT = true, MF = true, IsWrite = true, Direction = CommandDirection.IN, ParameterByteCount = 8, ResultByteCount = 7 }, - // write id - new Command { CommandDelegate = UPD_WriteID, CommandCode = 0x0d, MF = true, IsWrite = true, + // write id + new Command { CommandDelegate = UPD_WriteID, CommandCode = 0x0d, MF = true, IsWrite = true, Direction = CommandDirection.IN, ParameterByteCount = 5, ResultByteCount = 7 }, - // write deleted data - new Command { CommandDelegate = UPD_WriteDeletedData, CommandCode = 0x09, MT = true, MF = true, IsWrite = true, + // write deleted data + new Command { CommandDelegate = UPD_WriteDeletedData, CommandCode = 0x09, MT = true, MF = true, IsWrite = true, Direction = CommandDirection.IN, ParameterByteCount = 8, ResultByteCount = 7 }, - // seek - new Command { CommandDelegate = UPD_Seek, CommandCode = 0x0f, + // seek + new Command { CommandDelegate = UPD_Seek, CommandCode = 0x0f, Direction = CommandDirection.OUT, ParameterByteCount = 2, ResultByteCount = 0 }, - // recalibrate (seek track00) - new Command { CommandDelegate = UPD_Recalibrate, CommandCode = 0x07, + // recalibrate (seek track00) + new Command { CommandDelegate = UPD_Recalibrate, CommandCode = 0x07, Direction = CommandDirection.OUT, ParameterByteCount = 1, ResultByteCount = 0 }, - // sense interrupt status - new Command { CommandDelegate = UPD_SenseInterruptStatus, CommandCode = 0x08, + // sense interrupt status + new Command { CommandDelegate = UPD_SenseInterruptStatus, CommandCode = 0x08, Direction = CommandDirection.OUT, ParameterByteCount = 0, ResultByteCount = 2 }, - // sense drive status - new Command { CommandDelegate = UPD_SenseDriveStatus, CommandCode = 0x04, + // sense drive status + new Command { CommandDelegate = UPD_SenseDriveStatus, CommandCode = 0x04, Direction = CommandDirection.OUT, ParameterByteCount = 1, ResultByteCount = 1 }, - // version - new Command { CommandDelegate = UPD_Version, CommandCode = 0x10, + // version + new Command { CommandDelegate = UPD_Version, CommandCode = 0x10, Direction = CommandDirection.OUT, ParameterByteCount = 0, ResultByteCount = 1 }, - // invalid - new Command { CommandDelegate = UPD_Invalid, CommandCode = 0x00, + // invalid + new Command { CommandDelegate = UPD_Invalid, CommandCode = 0x00, Direction = CommandDirection.OUT, ParameterByteCount = 0, ResultByteCount = 1 }, }; } diff --git a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Input/CursorJoystick.cs b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Input/CursorJoystick.cs index 69a163e1d7d..9026066f06f 100644 --- a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Input/CursorJoystick.cs +++ b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Input/CursorJoystick.cs @@ -30,11 +30,11 @@ public CursorJoystick(SpectrumBase machine, int playerNumber) private readonly List btnLookups = new List { "Key 5", // left - "Key 8", // right - "Key 6", // down - "Key 7", // up - "Key 0", // fire - }; + "Key 8", // right + "Key 6", // down + "Key 7", // up + "Key 0", // fire + }; public JoystickType JoyType => JoystickType.Cursor; diff --git a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Input/KempstonJoystick.cs b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Input/KempstonJoystick.cs index c3331dfb4c3..6c92d25f470 100644 --- a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Input/KempstonJoystick.cs +++ b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Input/KempstonJoystick.cs @@ -76,14 +76,14 @@ public int GetBitPos(string key) /* - public readonly string[] _bitPos = new string[] - { - "P1 Right", - "P1 Left", - "P1 Down", - "P1 Up", - "P1 Button" - }; - */ + public readonly string[] _bitPos = new string[] + { + "P1 Right", + "P1 Left", + "P1 Down", + "P1 Up", + "P1 Button" + }; + */ } } diff --git a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Input/NullJoystick.cs b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Input/NullJoystick.cs index 55c460a7ab8..1f9fefe34df 100644 --- a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Input/NullJoystick.cs +++ b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Input/NullJoystick.cs @@ -69,14 +69,14 @@ public int GetBitPos(string key) /* - public readonly string[] _bitPos = new string[] - { - "P1 Right", - "P1 Left", - "P1 Down", - "P1 Up", - "P1 Button" - }; - */ + public readonly string[] _bitPos = new string[] + { + "P1 Right", + "P1 Left", + "P1 Down", + "P1 Up", + "P1 Button" + }; + */ } } diff --git a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Input/SinclairJoystick1.cs b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Input/SinclairJoystick1.cs index 79d5cb2b4a4..30193eb7cf3 100644 --- a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Input/SinclairJoystick1.cs +++ b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Input/SinclairJoystick1.cs @@ -30,11 +30,11 @@ public SinclairJoystick1(SpectrumBase machine, int playerNumber) private readonly List btnLookups = new List { "Key 1", // left - "Key 2", // right - "Key 3", // down - "Key 4", // up - "Key 5", // fire - }; + "Key 2", // right + "Key 3", // down + "Key 4", // up + "Key 5", // fire + }; public JoystickType JoyType => JoystickType.SinclairLEFT; diff --git a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Input/SinclairJoystick2.cs b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Input/SinclairJoystick2.cs index f267e7c1daa..7fb790b2606 100644 --- a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Input/SinclairJoystick2.cs +++ b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Input/SinclairJoystick2.cs @@ -30,11 +30,11 @@ public SinclairJoystick2(SpectrumBase machine, int playerNumber) private readonly List btnLookups = new List { "Key 6", // left - "Key 7", // right - "Key 8", // down - "Key 9", // up - "Key 0", // fire - }; + "Key 7", // right + "Key 8", // down + "Key 9", // up + "Key 0", // fire + }; public JoystickType JoyType => JoystickType.SinclairRIGHT; diff --git a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Input/StandardKeyboard.cs b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Input/StandardKeyboard.cs index 8ab4c87f8d8..89bd3c68d0a 100644 --- a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Input/StandardKeyboard.cs +++ b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Input/StandardKeyboard.cs @@ -189,20 +189,20 @@ public byte GetByteFromKeyMatrix(string key) public bool ReadPort(ushort port, ref int result) { /* - The high byte indicates which half-row of keys is being polled - A zero on one of these lines selects a particular half-row of five keys: - - IN: Reads keys (bit 0 to bit 4 inclusive) - 0xfefe SHIFT, Z, X, C, V 0xeffe 0, 9, 8, 7, 6 - 0xfdfe A, S, D, F, G 0xdffe P, O, I, U, Y - 0xfbfe Q, W, E, R, T 0xbffe ENTER, L, K, J, H - 0xf7fe 1, 2, 3, 4, 5 0x7ffe SPACE, SYM SHFT, M, N, B - - A zero in one of the five lowest bits means that the corresponding key is pressed. If more than one address line - is made low, the result is the logical AND of all single inputs, so a zero in a bit means that at least one of the - appropriate keys is pressed. For example, only if each of the five lowest bits of the result from reading from Port 00FE - (for instance by XOR A/IN A,(FE)) is one, no key is pressed - */ + The high byte indicates which half-row of keys is being polled + A zero on one of these lines selects a particular half-row of five keys: + + IN: Reads keys (bit 0 to bit 4 inclusive) + 0xfefe SHIFT, Z, X, C, V 0xeffe 0, 9, 8, 7, 6 + 0xfdfe A, S, D, F, G 0xdffe P, O, I, U, Y + 0xfbfe Q, W, E, R, T 0xbffe ENTER, L, K, J, H + 0xf7fe 1, 2, 3, 4, 5 0x7ffe SPACE, SYM SHFT, M, N, B + + A zero in one of the five lowest bits means that the corresponding key is pressed. If more than one address line + is made low, the result is the logical AND of all single inputs, so a zero in a bit means that at least one of the + appropriate keys is pressed. For example, only if each of the five lowest bits of the result from reading from Port 00FE + (for instance by XOR A/IN A,(FE)) is one, no key is pressed + */ if ((port & 0x0001) != 0) return false; diff --git a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/SoundOuput/AY38912.cs b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/SoundOuput/AY38912.cs index 5b400487835..d5217db9c77 100644 --- a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/SoundOuput/AY38912.cs +++ b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/SoundOuput/AY38912.cs @@ -178,30 +178,30 @@ public void Reset() } /* - _noiseVal = 0x0FFFF; - _outABC = 0; - _outNoiseABC = 0; - _counterNoise = 0; - _counterA = 0; - _counterB = 0; - _counterC = 0; - _EnvelopeCounterBend = 0; - - // clear all the registers - for (int i = 0; i < 14; i++) - { - SelectedRegister = i; - PortWrite(0); - } - - randomSeed = 1; - - // number of frames to update - var fr = (_audioBufferIndex * _tStatesPerFrame) / _audioBuffer.Length; - - // update the audio buffer - BufferUpdate(fr); - */ + _noiseVal = 0x0FFFF; + _outABC = 0; + _outNoiseABC = 0; + _counterNoise = 0; + _counterA = 0; + _counterB = 0; + _counterC = 0; + _EnvelopeCounterBend = 0; + + // clear all the registers + for (int i = 0; i < 14; i++) + { + SelectedRegister = i; + PortWrite(0); + } + + randomSeed = 1; + + // number of frames to update + var fr = (_audioBufferIndex * _tStatesPerFrame) / _audioBuffer.Length; + + // update the audio buffer + BufferUpdate(fr); + */ } /// @@ -353,36 +353,36 @@ public void UpdateSound(int frameCycle) /// The register array /// /* - The AY-3-8910/8912 contains 16 internal registers as follows: - - Register Function Range - 0 Channel A fine pitch 8-bit (0-255) - 1 Channel A course pitch 4-bit (0-15) - 2 Channel B fine pitch 8-bit (0-255) - 3 Channel B course pitch 4-bit (0-15) - 4 Channel C fine pitch 8-bit (0-255) - 5 Channel C course pitch 4-bit (0-15) - 6 Noise pitch 5-bit (0-31) - 7 Mixer 8-bit (see below) - 8 Channel A volume 4-bit (0-15, see below) - 9 Channel B volume 4-bit (0-15, see below) - 10 Channel C volume 4-bit (0-15, see below) - 11 Envelope fine duration 8-bit (0-255) - 12 Envelope course duration 8-bit (0-255) - 13 Envelope shape 4-bit (0-15) - 14 I/O port A 8-bit (0-255) - 15 I/O port B 8-bit (0-255) (Not present on the AY-3-8912) - - * The volume registers (8, 9 and 10) contain a 4-bit setting but if bit 5 is set then that channel uses the - envelope defined by register 13 and ignores its volume setting. - * The mixer (register 7) is made up of the following bits (low=enabled): - - Bit: 7 6 5 4 3 2 1 0 - Register: I/O I/O Noise Noise Noise Tone Tone Tone - Channel: B A C B A C B A - - The AY-3-8912 ignores bit 7 of this register. - */ + The AY-3-8910/8912 contains 16 internal registers as follows: + + Register Function Range + 0 Channel A fine pitch 8-bit (0-255) + 1 Channel A course pitch 4-bit (0-15) + 2 Channel B fine pitch 8-bit (0-255) + 3 Channel B course pitch 4-bit (0-15) + 4 Channel C fine pitch 8-bit (0-255) + 5 Channel C course pitch 4-bit (0-15) + 6 Noise pitch 5-bit (0-31) + 7 Mixer 8-bit (see below) + 8 Channel A volume 4-bit (0-15, see below) + 9 Channel B volume 4-bit (0-15, see below) + 10 Channel C volume 4-bit (0-15, see below) + 11 Envelope fine duration 8-bit (0-255) + 12 Envelope course duration 8-bit (0-255) + 13 Envelope shape 4-bit (0-15) + 14 I/O port A 8-bit (0-255) + 15 I/O port B 8-bit (0-255) (Not present on the AY-3-8912) + + * The volume registers (8, 9 and 10) contain a 4-bit setting but if bit 5 is set then that channel uses the + envelope defined by register 13 and ignores its volume setting. + * The mixer (register 7) is made up of the following bits (low=enabled): + + Bit: 7 6 5 4 3 2 1 0 + Register: I/O I/O Noise Noise Noise Tone Tone Tone + Channel: B A C B A C B A + + The AY-3-8912 ignores bit 7 of this register. + */ private int[] _registers = new int[16]; /// @@ -490,20 +490,20 @@ The AY-3-8912 ignores bit 7 of this register. /// private static readonly List PanTabs = new List { - // MONO - new uint[] { 50,50, 50,50, 50,50 }, - // ABC - new uint[] { 100,10, 66,66, 10,100 }, - // ACB - new uint[] { 100,10, 10,100, 66,66 }, - // BAC - new uint[] { 66,66, 100,10, 10,100 }, - // BCA - new uint[] { 10,100, 100,10, 66,66 }, - // CAB - new uint[] { 66,66, 10,100, 100,10 }, - // CBA - new uint[] { 10,100, 66,66, 100,10 } + // MONO + new uint[] { 50,50, 50,50, 50,50 }, + // ABC + new uint[] { 100,10, 66,66, 10,100 }, + // ACB + new uint[] { 100,10, 10,100, 66,66 }, + // BAC + new uint[] { 66,66, 100,10, 10,100 }, + // BCA + new uint[] { 10,100, 100,10, 66,66 }, + // CAB + new uint[] { 66,66, 10,100, 100,10 }, + // CBA + new uint[] { 10,100, 66,66, 100,10 } }; /// diff --git a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/Pentagon128K/Pentagon128.Port.cs b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/Pentagon128K/Pentagon128.Port.cs index b9775db98db..842759416b1 100644 --- a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/Pentagon128K/Pentagon128.Port.cs +++ b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/Pentagon128K/Pentagon128.Port.cs @@ -2,162 +2,162 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum { - /// - /// Pentagon 128K Port - /// - public partial class Pentagon128 : SpectrumBase - { - /// - /// Reads a byte of data from a specified port address - /// - public override byte ReadPort(ushort port) - { - bool deviceAddressed = true; - - int result = 0xFF; - - // ports 0x3ffd & 0x7ffd - // traditionally thought to be write-only - if (port == 0x3ffd || port == 0x7ffd) - { - // https://faqwiki.zxnet.co.uk/wiki/ZX_Spectrum_128 - // HAL bugs - // Reads from port 0x7ffd cause a crash, as the 128's HAL10H8 chip does not distinguish between reads and writes to this port, - // resulting in a floating data bus being used to set the paging registers. - - // -asni (2018-06-08) - need this to pass the final portread tests from fusetest.tap - - // get the floating bus value - ULADevice.ReadFloatingBus((int)CurrentFrameCycle, ref result, port); - // use this to set the paging registers - WritePort(port, (byte)result); - // return the floating bus value - return (byte)result; - } - - // check AY - if (AYDevice.ReadPort(port, ref result)) - return (byte)result; - - byte lowByte = (byte)(port & 0xff); - - // Kempston joystick input takes priority over keyboard input - // if this is detected just return the kempston byte - if (lowByte == 0x1f) - { - //TODO lines swapped? - if (LocateUniqueJoystick(JoystickType.Kempston) is KempstonJoystick j) return (byte) j.JoyLine; - InputRead = true; - } - else - { - if (KeyboardDevice.ReadPort(port, ref result)) - { - // not a lagframe - InputRead = true; - - // process tape INs - TapeDevice.ReadPort(port, ref result); - } - else - deviceAddressed = false; - } - - if (!deviceAddressed) - { - // If this is an unused port the floating memory bus should be returned - ULADevice.ReadFloatingBus((int)CurrentFrameCycle, ref result, port); - } - - return (byte)result; - } - - /// - /// Writes a byte of data to a specified port address - /// - public override void WritePort(ushort port, byte value) - { - // get a BitArray of the port - BitArray portBits = new BitArray(BitConverter.GetBytes(port)); - // get a BitArray of the value byte - BitArray bits = new BitArray(new byte[] { value }); - - // handle AY port writes - AYDevice.WritePort(port, value); - - // memory paging - // this is controlled by writes to port 0x7ffd - // but it is only partially decoded so it actually responds to any port with bits 1 and 15 reset - if (!portBits[1] && !portBits[15]) - { - Last7ffd = value; - - // if paging is disabled then all writes to this port are ignored until the next reboot - if (!PagingDisabled) - { - // Bits 0, 1, 2 select the RAM page - var rp = value & 0x07; - if (RAMPaged != rp && rp < 8) - RAMPaged = rp; - - // bit 3 controls shadow screen - if (SHADOWPaged != bits[3]) - SHADOWPaged = bits[3]; - - // ROM page - if (bits[4]) - { - // 48k basic rom - ROMPaged = 1; - } - else - { - // 128k editor and menu system - ROMPaged = 0; - } - - // Bit 5 set signifies that paging is disabled until next reboot - PagingDisabled = bits[5]; - } - else - { - // no changes to paging - } - } - - // Check whether the low bit is reset - // Technically the ULA should respond to every even I/O address - bool lowBitReset = !portBits[0]; // (port & 0x01) == 0; - - // Only even addresses address the ULA - if (lowBitReset) - { - LastFe = value; - - // store the last OUT byte - LastULAOutByte = value; - - /* - Bit 7 6 5 4 3 2 1 0 - +-------------------------------+ - | | | | E | M | Border | - +-------------------------------+ - */ - - // Border - LSB 3 bits hold the border colour - if (ULADevice.BorderColor != (value & BORDER_BIT)) - { - //ULADevice.RenderScreen((int)CurrentFrameCycle); - ULADevice.BorderColor = value & BORDER_BIT; - } + /// + /// Pentagon 128K Port + /// + public partial class Pentagon128 : SpectrumBase + { + /// + /// Reads a byte of data from a specified port address + /// + public override byte ReadPort(ushort port) + { + bool deviceAddressed = true; + + int result = 0xFF; + + // ports 0x3ffd & 0x7ffd + // traditionally thought to be write-only + if (port == 0x3ffd || port == 0x7ffd) + { + // https://faqwiki.zxnet.co.uk/wiki/ZX_Spectrum_128 + // HAL bugs + // Reads from port 0x7ffd cause a crash, as the 128's HAL10H8 chip does not distinguish between reads and writes to this port, + // resulting in a floating data bus being used to set the paging registers. + + // -asni (2018-06-08) - need this to pass the final portread tests from fusetest.tap + + // get the floating bus value + ULADevice.ReadFloatingBus((int)CurrentFrameCycle, ref result, port); + // use this to set the paging registers + WritePort(port, (byte)result); + // return the floating bus value + return (byte)result; + } + + // check AY + if (AYDevice.ReadPort(port, ref result)) + return (byte)result; + + byte lowByte = (byte)(port & 0xff); + + // Kempston joystick input takes priority over keyboard input + // if this is detected just return the kempston byte + if (lowByte == 0x1f) + { + //TODO lines swapped? + if (LocateUniqueJoystick(JoystickType.Kempston) is KempstonJoystick j) return (byte) j.JoyLine; + InputRead = true; + } + else + { + if (KeyboardDevice.ReadPort(port, ref result)) + { + // not a lagframe + InputRead = true; + + // process tape INs + TapeDevice.ReadPort(port, ref result); + } + else + deviceAddressed = false; + } + + if (!deviceAddressed) + { + // If this is an unused port the floating memory bus should be returned + ULADevice.ReadFloatingBus((int)CurrentFrameCycle, ref result, port); + } + + return (byte)result; + } + + /// + /// Writes a byte of data to a specified port address + /// + public override void WritePort(ushort port, byte value) + { + // get a BitArray of the port + BitArray portBits = new BitArray(BitConverter.GetBytes(port)); + // get a BitArray of the value byte + BitArray bits = new BitArray(new byte[] { value }); + + // handle AY port writes + AYDevice.WritePort(port, value); + + // memory paging + // this is controlled by writes to port 0x7ffd + // but it is only partially decoded so it actually responds to any port with bits 1 and 15 reset + if (!portBits[1] && !portBits[15]) + { + Last7ffd = value; + + // if paging is disabled then all writes to this port are ignored until the next reboot + if (!PagingDisabled) + { + // Bits 0, 1, 2 select the RAM page + var rp = value & 0x07; + if (RAMPaged != rp && rp < 8) + RAMPaged = rp; + + // bit 3 controls shadow screen + if (SHADOWPaged != bits[3]) + SHADOWPaged = bits[3]; + + // ROM page + if (bits[4]) + { + // 48k basic rom + ROMPaged = 1; + } + else + { + // 128k editor and menu system + ROMPaged = 0; + } + + // Bit 5 set signifies that paging is disabled until next reboot + PagingDisabled = bits[5]; + } + else + { + // no changes to paging + } + } + + // Check whether the low bit is reset + // Technically the ULA should respond to every even I/O address + bool lowBitReset = !portBits[0]; // (port & 0x01) == 0; + + // Only even addresses address the ULA + if (lowBitReset) + { + LastFe = value; + + // store the last OUT byte + LastULAOutByte = value; + + /* + Bit 7 6 5 4 3 2 1 0 + +-------------------------------+ + | | | | E | M | Border | + +-------------------------------+ + */ + + // Border - LSB 3 bits hold the border colour + if (ULADevice.BorderColor != (value & BORDER_BIT)) + { + //ULADevice.RenderScreen((int)CurrentFrameCycle); + ULADevice.BorderColor = value & BORDER_BIT; + } // Buzzer BuzzerDevice.ProcessPulseValue((value & EAR_BIT) != 0, _renderSound); TapeDevice.WritePort(port, value); - // Tape - //TapeDevice.ProcessMicBit((value & MIC_BIT) != 0); - } - } - } + // Tape + //TapeDevice.ProcessMicBit((value & MIC_BIT) != 0); + } + } + } } diff --git a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Memory.cs b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Memory.cs index 4988352ff8d..e9e4579746b 100644 --- a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Memory.cs +++ b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Memory.cs @@ -1,224 +1,224 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum { - /// - /// The abstract class that all emulated models will inherit from - /// * Memory * - /// - public abstract partial class SpectrumBase - { - /// - /// ROM Banks - /// - public byte[] ROM0 = new byte[0x4000]; - public byte[] ROM1 = new byte[0x4000]; - public byte[] ROM2 = new byte[0x4000]; - public byte[] ROM3 = new byte[0x4000]; - - /// - /// RAM Banks - /// - public byte[] RAM0 = new byte[0x4000]; // Bank 0 - public byte[] RAM1 = new byte[0x4000]; // Bank 1 - public byte[] RAM2 = new byte[0x4000]; // Bank 2 - public byte[] RAM3 = new byte[0x4000]; // Bank 3 - public byte[] RAM4 = new byte[0x4000]; // Bank 4 - public byte[] RAM5 = new byte[0x4000]; // Bank 5 - public byte[] RAM6 = new byte[0x4000]; // Bank 6 - public byte[] RAM7 = new byte[0x4000]; // Bank 7 - - /// - /// Signs that the shadow screen is now displaying - /// Note: normal screen memory in RAM5 is not altered, the ULA just outputs Screen1 instead (RAM7) - /// - public bool SHADOWPaged; - - /// - /// Index of the current RAM page - /// /// 128k, +2/2a and +3 only - /// - public int RAMPaged; - - /// - /// Signs that all paging is disabled - /// If this is TRUE, then 128k and above machines need a hard reset before paging is allowed again - /// - public bool PagingDisabled; - - /// - /// Index of the currently paged ROM - /// 128k, +2/2a and +3 only - /// - protected int ROMPaged; - public virtual int _ROMpaged - { - get => ROMPaged; - set => ROMPaged = value; - } - - /* - * +3/+2A only - */ - - /// - /// High bit of the ROM selection (in normal paging mode) - /// - public bool ROMhigh = false; - - /// - /// Low bit of the ROM selection (in normal paging mode) - /// - public bool ROMlow = false; - - /// - /// Signs that the +2a/+3 special paging mode is activated - /// - public bool SpecialPagingMode; - - /// - /// Index of the current special paging mode (0-3) - /// - public int PagingConfiguration; - - /// - /// The last byte that was read after contended cycles - /// - public byte LastContendedReadByte; - - /// - /// Simulates reading from the bus - /// Paging should be handled here - /// - public abstract byte ReadBus(ushort addr); - - /// - /// Pushes a value onto the data bus that should be valid as long as the interrupt is true - /// - public virtual byte PushBus() - { - return 0xFF; - } - - /// - /// Simulates writing to the bus - /// Paging should be handled here - /// - public virtual void WriteBus(ushort addr, byte value) - { - throw new NotImplementedException("Must be overriden"); - } - - /// - /// Reads a byte of data from a specified memory address - /// (with memory contention if appropriate) - /// - public abstract byte ReadMemory(ushort addr); - - /// - /// Returns the ROM/RAM enum that relates to this particular memory read operation - /// - public abstract ZXSpectrum.CDLResult ReadCDL(ushort addr); - - /// - /// Writes a byte of data to a specified memory address - /// (with memory contention if appropriate) - /// - public abstract void WriteMemory(ushort addr, byte value); - - /// - /// Sets up the ROM - /// - public abstract void InitROM(RomData romData); - - /// - /// ULA reads the memory at the specified address - /// (No memory contention) - /// - public virtual byte FetchScreenMemory(ushort addr) - { - var value = ReadBus((ushort)((addr & 0x3FFF) + 0x4000)); - //var value = ReadBus(addr); - return value; - } - - /// - /// Checks whether supplied address is in a potentially contended bank - /// - public abstract bool IsContended(ushort addr); - - - /// - /// Returns TRUE if there is a contended bank paged in - /// - public abstract bool ContendedBankPaged(); - - /// - /// Detects whether this is a 48k machine (or a 128k in 48k mode) - /// - public virtual bool IsIn48kMode() - => PagingDisabled || this is ZX48 or ZX16; - - /// - /// Monitors ROM access - /// Used to auto start/stop the tape device when appropriate + /// + /// The abstract class that all emulated models will inherit from + /// * Memory * + /// + public abstract partial class SpectrumBase + { + /// + /// ROM Banks + /// + public byte[] ROM0 = new byte[0x4000]; + public byte[] ROM1 = new byte[0x4000]; + public byte[] ROM2 = new byte[0x4000]; + public byte[] ROM3 = new byte[0x4000]; + + /// + /// RAM Banks + /// + public byte[] RAM0 = new byte[0x4000]; // Bank 0 + public byte[] RAM1 = new byte[0x4000]; // Bank 1 + public byte[] RAM2 = new byte[0x4000]; // Bank 2 + public byte[] RAM3 = new byte[0x4000]; // Bank 3 + public byte[] RAM4 = new byte[0x4000]; // Bank 4 + public byte[] RAM5 = new byte[0x4000]; // Bank 5 + public byte[] RAM6 = new byte[0x4000]; // Bank 6 + public byte[] RAM7 = new byte[0x4000]; // Bank 7 + + /// + /// Signs that the shadow screen is now displaying + /// Note: normal screen memory in RAM5 is not altered, the ULA just outputs Screen1 instead (RAM7) + /// + public bool SHADOWPaged; + + /// + /// Index of the current RAM page + /// /// 128k, +2/2a and +3 only + /// + public int RAMPaged; + + /// + /// Signs that all paging is disabled + /// If this is TRUE, then 128k and above machines need a hard reset before paging is allowed again + /// + public bool PagingDisabled; + + /// + /// Index of the currently paged ROM + /// 128k, +2/2a and +3 only + /// + protected int ROMPaged; + public virtual int _ROMpaged + { + get => ROMPaged; + set => ROMPaged = value; + } + + /* + * +3/+2A only + */ + + /// + /// High bit of the ROM selection (in normal paging mode) + /// + public bool ROMhigh = false; + + /// + /// Low bit of the ROM selection (in normal paging mode) + /// + public bool ROMlow = false; + + /// + /// Signs that the +2a/+3 special paging mode is activated + /// + public bool SpecialPagingMode; + + /// + /// Index of the current special paging mode (0-3) + /// + public int PagingConfiguration; + + /// + /// The last byte that was read after contended cycles + /// + public byte LastContendedReadByte; + + /// + /// Simulates reading from the bus + /// Paging should be handled here + /// + public abstract byte ReadBus(ushort addr); + + /// + /// Pushes a value onto the data bus that should be valid as long as the interrupt is true + /// + public virtual byte PushBus() + { + return 0xFF; + } + + /// + /// Simulates writing to the bus + /// Paging should be handled here + /// + public virtual void WriteBus(ushort addr, byte value) + { + throw new NotImplementedException("Must be overriden"); + } + + /// + /// Reads a byte of data from a specified memory address + /// (with memory contention if appropriate) + /// + public abstract byte ReadMemory(ushort addr); + + /// + /// Returns the ROM/RAM enum that relates to this particular memory read operation + /// + public abstract ZXSpectrum.CDLResult ReadCDL(ushort addr); + + /// + /// Writes a byte of data to a specified memory address + /// (with memory contention if appropriate) + /// + public abstract void WriteMemory(ushort addr, byte value); + + /// + /// Sets up the ROM + /// + public abstract void InitROM(RomData romData); + + /// + /// ULA reads the memory at the specified address + /// (No memory contention) + /// + public virtual byte FetchScreenMemory(ushort addr) + { + var value = ReadBus((ushort)((addr & 0x3FFF) + 0x4000)); + //var value = ReadBus(addr); + return value; + } + + /// + /// Checks whether supplied address is in a potentially contended bank + /// + public abstract bool IsContended(ushort addr); + + + /// + /// Returns TRUE if there is a contended bank paged in + /// + public abstract bool ContendedBankPaged(); + + /// + /// Detects whether this is a 48k machine (or a 128k in 48k mode) + /// + public virtual bool IsIn48kMode() + => PagingDisabled || this is ZX48 or ZX16; + + /// + /// Monitors ROM access + /// Used to auto start/stop the tape device when appropriate /// * This isnt really used anymore for tape trap detection * - /// - public virtual void TestForTapeTraps(int addr) - { - if (TapeDevice.TapeIsPlaying) - { - // THE 'ERROR' RESTART - if (addr == 8) - { - //TapeDevice?.AutoStopTape(); - return; - } - - // THE 'ED-ERROR' SUBROUTINE - if (addr == 4223) - { - //TapeDevice?.AutoStopTape(); - return; - } - - // THE 'ERROR-2' ROUTINE - if (addr == 83) - { - //TapeDevice?.AutoStopTape(); - return; - } - - // THE 'MASKABLE INTERRUPT' ROUTINE - // This is sometimes used when the tape is to be stopped - if (addr == 56) - { - //TapeDevice.MaskableInterruptCount++; - - //if (TapeDevice.MaskableInterruptCount > 50) - //{ - //TapeDevice.MaskableInterruptCount = 0; - //TapeDevice.AutoStopTape(); - //} - - //TapeDevice?.AutoStopTape(); - return; - } - } - else - { - // THE 'LD-BYTES' SUBROUTINE - if (addr == 1366) - { - //TapeDevice?.AutoStartTape(); - return; - } - - // THE 'LD-EDGE-2' AND 'LD-EDGE-1' SUBROUTINES - if (addr == 1507) - { - //TapeDevice?.AutoStartTape(); - return; - } - } - } - } + /// + public virtual void TestForTapeTraps(int addr) + { + if (TapeDevice.TapeIsPlaying) + { + // THE 'ERROR' RESTART + if (addr == 8) + { + //TapeDevice?.AutoStopTape(); + return; + } + + // THE 'ED-ERROR' SUBROUTINE + if (addr == 4223) + { + //TapeDevice?.AutoStopTape(); + return; + } + + // THE 'ERROR-2' ROUTINE + if (addr == 83) + { + //TapeDevice?.AutoStopTape(); + return; + } + + // THE 'MASKABLE INTERRUPT' ROUTINE + // This is sometimes used when the tape is to be stopped + if (addr == 56) + { + //TapeDevice.MaskableInterruptCount++; + + //if (TapeDevice.MaskableInterruptCount > 50) + //{ + //TapeDevice.MaskableInterruptCount = 0; + //TapeDevice.AutoStopTape(); + //} + + //TapeDevice?.AutoStopTape(); + return; + } + } + else + { + // THE 'LD-BYTES' SUBROUTINE + if (addr == 1366) + { + //TapeDevice?.AutoStartTape(); + return; + } + + // THE 'LD-EDGE-2' AND 'LD-EDGE-1' SUBROUTINES + if (addr == 1507) + { + //TapeDevice?.AutoStartTape(); + return; + } + } + } + } } diff --git a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Port.cs b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Port.cs index da68bd8e1f1..8474ddb882f 100644 --- a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Port.cs +++ b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Port.cs @@ -1,34 +1,34 @@  namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum { - /// - /// The abstract class that all emulated models will inherit from - /// * Port Access * - /// - public abstract partial class SpectrumBase - { - /// - /// The last OUT data that was sent to the ULA - /// - protected byte LastULAOutByte; - public byte LASTULAOutByte - { - get => LastULAOutByte; - set => LastULAOutByte = value; - } + /// + /// The abstract class that all emulated models will inherit from + /// * Port Access * + /// + public abstract partial class SpectrumBase + { + /// + /// The last OUT data that was sent to the ULA + /// + protected byte LastULAOutByte; + public byte LASTULAOutByte + { + get => LastULAOutByte; + set => LastULAOutByte = value; + } - public byte Last7ffd; - public byte LastFe; - public byte Last1ffd; + public byte Last7ffd; + public byte LastFe; + public byte Last1ffd; - /// - /// Reads a byte of data from a specified port address - /// - public abstract byte ReadPort(ushort port); + /// + /// Reads a byte of data from a specified port address + /// + public abstract byte ReadPort(ushort port); - /// - /// Writes a byte of data to a specified port address - /// - public abstract void WritePort(ushort port, byte value); - } + /// + /// Writes a byte of data to a specified port address + /// + public abstract void WritePort(ushort port, byte value); + } } diff --git a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128K/ZX128.Port.cs b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128K/ZX128.Port.cs index 79d714fbfd6..a0a936a11b4 100644 --- a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128K/ZX128.Port.cs +++ b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128K/ZX128.Port.cs @@ -2,161 +2,161 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum { - /// - /// 128K/+2 Port - /// - public partial class ZX128 : SpectrumBase - { - /// - /// Reads a byte of data from a specified port address - /// - public override byte ReadPort(ushort port) - { - bool deviceAddressed = true; - - int result = 0xFF; - - // ports 0x3ffd & 0x7ffd - // traditionally thought to be write-only - if (port == 0x3ffd || port == 0x7ffd) - { - // https://faqwiki.zxnet.co.uk/wiki/ZX_Spectrum_128 - // HAL bugs - // Reads from port 0x7ffd cause a crash, as the 128's HAL10H8 chip does not distinguish between reads and writes to this port, - // resulting in a floating data bus being used to set the paging registers. - - // -asni (2018-06-08) - need this to pass the final portread tests from fusetest.tap - - // get the floating bus value - ULADevice.ReadFloatingBus((int)CurrentFrameCycle, ref result, port); - // use this to set the paging registers - WritePort(port, (byte)result); - // return the floating bus value - return (byte)result; - } - - // check AY - if (AYDevice.ReadPort(port, ref result)) - return (byte)result; - - byte lowByte = (byte)(port & 0xff); - - // Kempston joystick input takes priority over keyboard input - // if this is detected just return the kempston byte - if (lowByte == 0x1f) - { - InputRead = true; - if (LocateUniqueJoystick(JoystickType.Kempston) is KempstonJoystick j) return (byte) j.JoyLine; - } - else - { - if (KeyboardDevice.ReadPort(port, ref result)) - { - // not a lagframe - InputRead = true; - - // process tape INs - TapeDevice.ReadPort(port, ref result); - } - else - deviceAddressed = false; - } - - if (!deviceAddressed) - { - // If this is an unused port the floating memory bus should be returned - ULADevice.ReadFloatingBus((int)CurrentFrameCycle, ref result, port); - } - - return (byte)result; - } - - /// - /// Writes a byte of data to a specified port address - /// - public override void WritePort(ushort port, byte value) - { - // get a BitArray of the port - BitArray portBits = new BitArray(BitConverter.GetBytes(port)); - // get a BitArray of the value byte - BitArray bits = new BitArray(new byte[] { value }); - - // handle AY port writes - AYDevice.WritePort(port, value); - - // memory paging - // this is controlled by writes to port 0x7ffd - // but it is only partially decoded so it actually responds to any port with bits 1 and 15 reset - if (!portBits[1] && !portBits[15]) - { - Last7ffd = value; - - // if paging is disabled then all writes to this port are ignored until the next reboot - if (!PagingDisabled) - { - // Bits 0, 1, 2 select the RAM page - var rp = value & 0x07; - if (RAMPaged != rp && rp < 8) - RAMPaged = rp; - - // bit 3 controls shadow screen - if (SHADOWPaged != bits[3]) - SHADOWPaged = bits[3]; - - // ROM page - if (bits[4]) - { - // 48k basic rom - ROMPaged = 1; - } - else - { - // 128k editor and menu system - ROMPaged = 0; - } - - // Bit 5 set signifies that paging is disabled until next reboot - PagingDisabled = bits[5]; - } - else - { - // no changes to paging - } - } - - // Check whether the low bit is reset - // Technically the ULA should respond to every even I/O address - bool lowBitReset = !portBits[0]; // (port & 0x01) == 0; - - // Only even addresses address the ULA - if (lowBitReset) - { - LastFe = value; - - // store the last OUT byte - LastULAOutByte = value; - - /* - Bit 7 6 5 4 3 2 1 0 - +-------------------------------+ - | | | | E | M | Border | - +-------------------------------+ - */ - - // Border - LSB 3 bits hold the border colour - if (ULADevice.BorderColor != (value & BORDER_BIT)) - { - //ULADevice.RenderScreen((int)CurrentFrameCycle); - ULADevice.BorderColor = value & BORDER_BIT; - } + /// + /// 128K/+2 Port + /// + public partial class ZX128 : SpectrumBase + { + /// + /// Reads a byte of data from a specified port address + /// + public override byte ReadPort(ushort port) + { + bool deviceAddressed = true; + + int result = 0xFF; + + // ports 0x3ffd & 0x7ffd + // traditionally thought to be write-only + if (port == 0x3ffd || port == 0x7ffd) + { + // https://faqwiki.zxnet.co.uk/wiki/ZX_Spectrum_128 + // HAL bugs + // Reads from port 0x7ffd cause a crash, as the 128's HAL10H8 chip does not distinguish between reads and writes to this port, + // resulting in a floating data bus being used to set the paging registers. + + // -asni (2018-06-08) - need this to pass the final portread tests from fusetest.tap + + // get the floating bus value + ULADevice.ReadFloatingBus((int)CurrentFrameCycle, ref result, port); + // use this to set the paging registers + WritePort(port, (byte)result); + // return the floating bus value + return (byte)result; + } + + // check AY + if (AYDevice.ReadPort(port, ref result)) + return (byte)result; + + byte lowByte = (byte)(port & 0xff); + + // Kempston joystick input takes priority over keyboard input + // if this is detected just return the kempston byte + if (lowByte == 0x1f) + { + InputRead = true; + if (LocateUniqueJoystick(JoystickType.Kempston) is KempstonJoystick j) return (byte) j.JoyLine; + } + else + { + if (KeyboardDevice.ReadPort(port, ref result)) + { + // not a lagframe + InputRead = true; + + // process tape INs + TapeDevice.ReadPort(port, ref result); + } + else + deviceAddressed = false; + } + + if (!deviceAddressed) + { + // If this is an unused port the floating memory bus should be returned + ULADevice.ReadFloatingBus((int)CurrentFrameCycle, ref result, port); + } + + return (byte)result; + } + + /// + /// Writes a byte of data to a specified port address + /// + public override void WritePort(ushort port, byte value) + { + // get a BitArray of the port + BitArray portBits = new BitArray(BitConverter.GetBytes(port)); + // get a BitArray of the value byte + BitArray bits = new BitArray(new byte[] { value }); + + // handle AY port writes + AYDevice.WritePort(port, value); + + // memory paging + // this is controlled by writes to port 0x7ffd + // but it is only partially decoded so it actually responds to any port with bits 1 and 15 reset + if (!portBits[1] && !portBits[15]) + { + Last7ffd = value; + + // if paging is disabled then all writes to this port are ignored until the next reboot + if (!PagingDisabled) + { + // Bits 0, 1, 2 select the RAM page + var rp = value & 0x07; + if (RAMPaged != rp && rp < 8) + RAMPaged = rp; + + // bit 3 controls shadow screen + if (SHADOWPaged != bits[3]) + SHADOWPaged = bits[3]; + + // ROM page + if (bits[4]) + { + // 48k basic rom + ROMPaged = 1; + } + else + { + // 128k editor and menu system + ROMPaged = 0; + } + + // Bit 5 set signifies that paging is disabled until next reboot + PagingDisabled = bits[5]; + } + else + { + // no changes to paging + } + } + + // Check whether the low bit is reset + // Technically the ULA should respond to every even I/O address + bool lowBitReset = !portBits[0]; // (port & 0x01) == 0; + + // Only even addresses address the ULA + if (lowBitReset) + { + LastFe = value; + + // store the last OUT byte + LastULAOutByte = value; + + /* + Bit 7 6 5 4 3 2 1 0 + +-------------------------------+ + | | | | E | M | Border | + +-------------------------------+ + */ + + // Border - LSB 3 bits hold the border colour + if (ULADevice.BorderColor != (value & BORDER_BIT)) + { + //ULADevice.RenderScreen((int)CurrentFrameCycle); + ULADevice.BorderColor = value & BORDER_BIT; + } // Buzzer BuzzerDevice.ProcessPulseValue((value & EAR_BIT) != 0, _renderSound); TapeDevice.WritePort(port, value); - // Tape - //TapeDevice.ProcessMicBit((value & MIC_BIT) != 0); - } - } - } + // Tape + //TapeDevice.ProcessMicBit((value & MIC_BIT) != 0); + } + } + } } diff --git a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus2a/ZX128Plus2a.Port.cs b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus2a/ZX128Plus2a.Port.cs index 3f43ec18f2c..3529894507e 100644 --- a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus2a/ZX128Plus2a.Port.cs +++ b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus2a/ZX128Plus2a.Port.cs @@ -2,153 +2,153 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum { - /// - /// +2a Port - /// - public partial class ZX128Plus2a : SpectrumBase - { - /// - /// Reads a byte of data from a specified port address - /// - public override byte ReadPort(ushort port) - { - bool deviceAddressed = true; - - int result = 0xFF; - - // check AY - if (AYDevice.ReadPort(port, ref result)) - return (byte)result; - - byte lowByte = (byte)(port & 0xff); - - // Kempston joystick input takes priority over all keyboard input - // if this is detected just return the kempston byte - if (lowByte == 0x1f) - { - InputRead = true; - if (LocateUniqueJoystick(JoystickType.Kempston) is KempstonJoystick j) return (byte) j.JoyLine; - } - else - { - if (KeyboardDevice.ReadPort(port, ref result)) - { - // not a lagframe - InputRead = true; - - // process tape INs - TapeDevice.ReadPort(port, ref result); - } - else - deviceAddressed = false; - } - - if (!deviceAddressed) - { - // If this is an unused port the floating memory bus should be returned - ULADevice.ReadFloatingBus((int)CurrentFrameCycle, ref result, port); - } - - return (byte)result; - } - - /// - /// Writes a byte of data to a specified port address - /// - public override void WritePort(ushort port, byte value) - { - // get a BitArray of the port - BitArray portBits = new BitArray(BitConverter.GetBytes(port)); - // get a BitArray of the value byte - BitArray bits = new BitArray(new byte[] { value }); - - // Check whether the low bit is reset - bool lowBitReset = !portBits[0]; // (port & 0x01) == 0; - - AYDevice.WritePort(port, value); - - // port 0x7ffd - hardware should only respond when bits 1 & 15 are reset and bit 14 is set - if (!portBits[1] && !portBits[15] && portBits[14]) - { - Last7ffd = value; - - if (!PagingDisabled) - { - // bits 0, 1, 2 select the RAM page - var rp = value & 0x07; - if (rp < 8) - RAMPaged = rp; - - // bit 3 controls shadow screen - SHADOWPaged = bits[3]; - - // Bit 5 set signifies that paging is disabled until next reboot - PagingDisabled = bits[5]; - - // portbit 4 is the LOW BIT of the ROM selection - ROMlow = bits[4]; - } - } - // port 0x1ffd - hardware should only respond when bits 1, 13, 14 & 15 are reset and bit 12 is set - if (!portBits[1] && portBits[12] && !portBits[13] && !portBits[14] && !portBits[15]) - { - Last1ffd = value; - - if (!PagingDisabled) - { - if (!bits[0]) - { - // special paging is not enabled - get the ROMpage high byte - ROMhigh = bits[2]; - - // set the special paging mode flag - SpecialPagingMode = false; - } - else - { - // special paging is enabled - // this is decided based on combinations of bits 1 & 2 - // Config 0 = Bit1-0 Bit2-0 - // Config 1 = Bit1-1 Bit2-0 - // Config 2 = Bit1-0 Bit2-1 - // Config 3 = Bit1-1 Bit2-1 - BitArray confHalfNibble = new BitArray(2); - confHalfNibble[0] = bits[1]; - confHalfNibble[1] = bits[2]; - - // set special paging configuration - PagingConfiguration = ZXSpectrum.GetIntFromBitArray(confHalfNibble); - - // set the special paging mode flag - SpecialPagingMode = true; - } - } - - // bit 4 is the printer port strobe - PrinterPortStrobe = bits[4]; - } - - // Only even addresses address the ULA - if (lowBitReset) - { - LastFe = value; - - // store the last OUT byte - LastULAOutByte = value; - - /* - Bit 7 6 5 4 3 2 1 0 - +-------------------------------+ - | | | | E | M | Border | - +-------------------------------+ - */ - - // Border - LSB 3 bits hold the border colour - if (ULADevice.BorderColor != (value & BORDER_BIT)) - { - //ULADevice.RenderScreen((int)CurrentFrameCycle); - ULADevice.BorderColor = value & BORDER_BIT; - } + /// + /// +2a Port + /// + public partial class ZX128Plus2a : SpectrumBase + { + /// + /// Reads a byte of data from a specified port address + /// + public override byte ReadPort(ushort port) + { + bool deviceAddressed = true; + + int result = 0xFF; + + // check AY + if (AYDevice.ReadPort(port, ref result)) + return (byte)result; + + byte lowByte = (byte)(port & 0xff); + + // Kempston joystick input takes priority over all keyboard input + // if this is detected just return the kempston byte + if (lowByte == 0x1f) + { + InputRead = true; + if (LocateUniqueJoystick(JoystickType.Kempston) is KempstonJoystick j) return (byte) j.JoyLine; + } + else + { + if (KeyboardDevice.ReadPort(port, ref result)) + { + // not a lagframe + InputRead = true; + + // process tape INs + TapeDevice.ReadPort(port, ref result); + } + else + deviceAddressed = false; + } + + if (!deviceAddressed) + { + // If this is an unused port the floating memory bus should be returned + ULADevice.ReadFloatingBus((int)CurrentFrameCycle, ref result, port); + } + + return (byte)result; + } + + /// + /// Writes a byte of data to a specified port address + /// + public override void WritePort(ushort port, byte value) + { + // get a BitArray of the port + BitArray portBits = new BitArray(BitConverter.GetBytes(port)); + // get a BitArray of the value byte + BitArray bits = new BitArray(new byte[] { value }); + + // Check whether the low bit is reset + bool lowBitReset = !portBits[0]; // (port & 0x01) == 0; + + AYDevice.WritePort(port, value); + + // port 0x7ffd - hardware should only respond when bits 1 & 15 are reset and bit 14 is set + if (!portBits[1] && !portBits[15] && portBits[14]) + { + Last7ffd = value; + + if (!PagingDisabled) + { + // bits 0, 1, 2 select the RAM page + var rp = value & 0x07; + if (rp < 8) + RAMPaged = rp; + + // bit 3 controls shadow screen + SHADOWPaged = bits[3]; + + // Bit 5 set signifies that paging is disabled until next reboot + PagingDisabled = bits[5]; + + // portbit 4 is the LOW BIT of the ROM selection + ROMlow = bits[4]; + } + } + // port 0x1ffd - hardware should only respond when bits 1, 13, 14 & 15 are reset and bit 12 is set + if (!portBits[1] && portBits[12] && !portBits[13] && !portBits[14] && !portBits[15]) + { + Last1ffd = value; + + if (!PagingDisabled) + { + if (!bits[0]) + { + // special paging is not enabled - get the ROMpage high byte + ROMhigh = bits[2]; + + // set the special paging mode flag + SpecialPagingMode = false; + } + else + { + // special paging is enabled + // this is decided based on combinations of bits 1 & 2 + // Config 0 = Bit1-0 Bit2-0 + // Config 1 = Bit1-1 Bit2-0 + // Config 2 = Bit1-0 Bit2-1 + // Config 3 = Bit1-1 Bit2-1 + BitArray confHalfNibble = new BitArray(2); + confHalfNibble[0] = bits[1]; + confHalfNibble[1] = bits[2]; + + // set special paging configuration + PagingConfiguration = ZXSpectrum.GetIntFromBitArray(confHalfNibble); + + // set the special paging mode flag + SpecialPagingMode = true; + } + } + + // bit 4 is the printer port strobe + PrinterPortStrobe = bits[4]; + } + + // Only even addresses address the ULA + if (lowBitReset) + { + LastFe = value; + + // store the last OUT byte + LastULAOutByte = value; + + /* + Bit 7 6 5 4 3 2 1 0 + +-------------------------------+ + | | | | E | M | Border | + +-------------------------------+ + */ + + // Border - LSB 3 bits hold the border colour + if (ULADevice.BorderColor != (value & BORDER_BIT)) + { + //ULADevice.RenderScreen((int)CurrentFrameCycle); + ULADevice.BorderColor = value & BORDER_BIT; + } // Buzzer BuzzerDevice.ProcessPulseValue((value & EAR_BIT) != 0, _renderSound); @@ -156,26 +156,26 @@ Bit 7 6 5 4 3 2 1 0 // Tape TapeDevice.WritePort(port, value); - // Tape - //TapeDevice.ProcessMicBit((value & MIC_BIT) != 0); - } - - - LastULAOutByte = value; - } - - /// - /// +3 and 2a overidden method - /// - public override int _ROMpaged - { - get - { - // calculate the ROMpage from the high and low bits - var rp = ZXSpectrum.GetIntFromBitArray(new BitArray(new bool[] { ROMlow, ROMhigh })); - return rp; - } - set => ROMPaged = value; - } - } + // Tape + //TapeDevice.ProcessMicBit((value & MIC_BIT) != 0); + } + + + LastULAOutByte = value; + } + + /// + /// +3 and 2a overidden method + /// + public override int _ROMpaged + { + get + { + // calculate the ROMpage from the high and low bits + var rp = ZXSpectrum.GetIntFromBitArray(new BitArray(new bool[] { ROMlow, ROMhigh })); + return rp; + } + set => ROMPaged = value; + } + } } diff --git a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus3/ZX128Plus3.Port.cs b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus3/ZX128Plus3.Port.cs index 1c64bb538a4..b2554b8ac72 100644 --- a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus3/ZX128Plus3.Port.cs +++ b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus3/ZX128Plus3.Port.cs @@ -2,160 +2,160 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum { - /// - /// +3 Port - /// - public partial class ZX128Plus3 : SpectrumBase - { - /// - /// Reads a byte of data from a specified port address - /// - public override byte ReadPort(ushort port) - { - bool deviceAddressed = true; - - int result = 0xFF; - - // check AY - if (AYDevice.ReadPort(port, ref result)) - return (byte)result; - - byte lowByte = (byte)(port & 0xff); - - // Kempston joystick input takes priority over all keyboard input - // if this is detected just return the kempston byte - if (lowByte == 0x1f) - { - InputRead = true; - if (LocateUniqueJoystick(JoystickType.Kempston) is KempstonJoystick j) return (byte) j.JoyLine; - } - else if (UPDDiskDevice.ReadPort(port, ref result)) - { - return (byte)result; - } - else - { - if (KeyboardDevice.ReadPort(port, ref result)) - { - // not a lagframe - InputRead = true; - - // process tape INs - TapeDevice.ReadPort(port, ref result); - } - else - deviceAddressed = false; - } - - if (!deviceAddressed) - { - // If this is an unused port the floating memory bus should be returned - ULADevice.ReadFloatingBus((int)CurrentFrameCycle, ref result, port); - } - - return (byte)result; - } - - /// - /// Writes a byte of data to a specified port address - /// - public override void WritePort(ushort port, byte value) - { - if (port == 0x7ffd) - Last7ffd = value; - else if (port == 0x1ffd) - Last1ffd = value; - else if ((port & 0x01) == 0) - LastFe = value; - - // get a BitArray of the port - BitArray portBits = new BitArray(BitConverter.GetBytes(port)); - // get a BitArray of the value byte - BitArray bits = new BitArray(new byte[] { value }); - - // Check whether the low bit is reset - bool lowBitReset = !portBits[0]; // (port & 0x01) == 0; - - AYDevice.WritePort(port, value); - - UPDDiskDevice.WritePort(port, value); - - // port 0x7ffd - hardware should only respond when bits 1 & 15 are reset and bit 14 is set - if (!portBits[1] && !portBits[15] && portBits[14]) - { - if (!PagingDisabled) - { - // bits 0, 1, 2 select the RAM page - var rp = value & 0x07; - if (rp < 8) - RAMPaged = rp; - - // bit 3 controls shadow screen - SHADOWPaged = bits[3]; - - // Bit 5 set signifies that paging is disabled until next reboot - PagingDisabled = bits[5]; - - // portbit 4 is the LOW BIT of the ROM selection - ROMlow = bits[4]; - } - } - // port 0x1ffd - hardware should only respond when bits 1, 13, 14 & 15 are reset and bit 12 is set - if (!portBits[1] && portBits[12] && !portBits[13] && !portBits[14] && !portBits[15]) - { - if (!PagingDisabled) - { - if (!bits[0]) - { - // special paging is not enabled - get the ROMpage high byte - ROMhigh = bits[2]; - - // set the special paging mode flag - SpecialPagingMode = false; - } - else - { - // special paging is enabled - // this is decided based on combinations of bits 1 & 2 - // Config 0 = Bit1-0 Bit2-0 - // Config 1 = Bit1-1 Bit2-0 - // Config 2 = Bit1-0 Bit2-1 - // Config 3 = Bit1-1 Bit2-1 - BitArray confHalfNibble = new BitArray(2); - confHalfNibble[0] = bits[1]; - confHalfNibble[1] = bits[2]; - - // set special paging configuration - PagingConfiguration = ZXSpectrum.GetIntFromBitArray(confHalfNibble); - - // set the special paging mode flag - SpecialPagingMode = true; - } - } - - // bit 4 is the printer port strobe - PrinterPortStrobe = bits[4]; - } - - // Only even addresses address the ULA - if (lowBitReset) - { - // store the last OUT byte - LastULAOutByte = value; - - /* - Bit 7 6 5 4 3 2 1 0 - +-------------------------------+ - | | | | E | M | Border | - +-------------------------------+ - */ - - // Border - LSB 3 bits hold the border colour - if (ULADevice.BorderColor != (value & BORDER_BIT)) - { - //ULADevice.RenderScreen((int)CurrentFrameCycle); - ULADevice.BorderColor = value & BORDER_BIT; - } + /// + /// +3 Port + /// + public partial class ZX128Plus3 : SpectrumBase + { + /// + /// Reads a byte of data from a specified port address + /// + public override byte ReadPort(ushort port) + { + bool deviceAddressed = true; + + int result = 0xFF; + + // check AY + if (AYDevice.ReadPort(port, ref result)) + return (byte)result; + + byte lowByte = (byte)(port & 0xff); + + // Kempston joystick input takes priority over all keyboard input + // if this is detected just return the kempston byte + if (lowByte == 0x1f) + { + InputRead = true; + if (LocateUniqueJoystick(JoystickType.Kempston) is KempstonJoystick j) return (byte) j.JoyLine; + } + else if (UPDDiskDevice.ReadPort(port, ref result)) + { + return (byte)result; + } + else + { + if (KeyboardDevice.ReadPort(port, ref result)) + { + // not a lagframe + InputRead = true; + + // process tape INs + TapeDevice.ReadPort(port, ref result); + } + else + deviceAddressed = false; + } + + if (!deviceAddressed) + { + // If this is an unused port the floating memory bus should be returned + ULADevice.ReadFloatingBus((int)CurrentFrameCycle, ref result, port); + } + + return (byte)result; + } + + /// + /// Writes a byte of data to a specified port address + /// + public override void WritePort(ushort port, byte value) + { + if (port == 0x7ffd) + Last7ffd = value; + else if (port == 0x1ffd) + Last1ffd = value; + else if ((port & 0x01) == 0) + LastFe = value; + + // get a BitArray of the port + BitArray portBits = new BitArray(BitConverter.GetBytes(port)); + // get a BitArray of the value byte + BitArray bits = new BitArray(new byte[] { value }); + + // Check whether the low bit is reset + bool lowBitReset = !portBits[0]; // (port & 0x01) == 0; + + AYDevice.WritePort(port, value); + + UPDDiskDevice.WritePort(port, value); + + // port 0x7ffd - hardware should only respond when bits 1 & 15 are reset and bit 14 is set + if (!portBits[1] && !portBits[15] && portBits[14]) + { + if (!PagingDisabled) + { + // bits 0, 1, 2 select the RAM page + var rp = value & 0x07; + if (rp < 8) + RAMPaged = rp; + + // bit 3 controls shadow screen + SHADOWPaged = bits[3]; + + // Bit 5 set signifies that paging is disabled until next reboot + PagingDisabled = bits[5]; + + // portbit 4 is the LOW BIT of the ROM selection + ROMlow = bits[4]; + } + } + // port 0x1ffd - hardware should only respond when bits 1, 13, 14 & 15 are reset and bit 12 is set + if (!portBits[1] && portBits[12] && !portBits[13] && !portBits[14] && !portBits[15]) + { + if (!PagingDisabled) + { + if (!bits[0]) + { + // special paging is not enabled - get the ROMpage high byte + ROMhigh = bits[2]; + + // set the special paging mode flag + SpecialPagingMode = false; + } + else + { + // special paging is enabled + // this is decided based on combinations of bits 1 & 2 + // Config 0 = Bit1-0 Bit2-0 + // Config 1 = Bit1-1 Bit2-0 + // Config 2 = Bit1-0 Bit2-1 + // Config 3 = Bit1-1 Bit2-1 + BitArray confHalfNibble = new BitArray(2); + confHalfNibble[0] = bits[1]; + confHalfNibble[1] = bits[2]; + + // set special paging configuration + PagingConfiguration = ZXSpectrum.GetIntFromBitArray(confHalfNibble); + + // set the special paging mode flag + SpecialPagingMode = true; + } + } + + // bit 4 is the printer port strobe + PrinterPortStrobe = bits[4]; + } + + // Only even addresses address the ULA + if (lowBitReset) + { + // store the last OUT byte + LastULAOutByte = value; + + /* + Bit 7 6 5 4 3 2 1 0 + +-------------------------------+ + | | | | E | M | Border | + +-------------------------------+ + */ + + // Border - LSB 3 bits hold the border colour + if (ULADevice.BorderColor != (value & BORDER_BIT)) + { + //ULADevice.RenderScreen((int)CurrentFrameCycle); + ULADevice.BorderColor = value & BORDER_BIT; + } // Buzzer BuzzerDevice.ProcessPulseValue((value & EAR_BIT) != 0, _renderSound); @@ -163,26 +163,26 @@ Bit 7 6 5 4 3 2 1 0 // Tape TapeDevice.WritePort(port, value); - // Tape - //TapeDevice.ProcessMicBit((value & MIC_BIT) != 0); - } - - - LastULAOutByte = value; - } - - /// - /// +3 and 2a overidden method - /// - public override int _ROMpaged - { - get - { - // calculate the ROMpage from the high and low bits - var rp = ZXSpectrum.GetIntFromBitArray(new BitArray(new bool[] { ROMlow, ROMhigh })); - return rp; - } - set => ROMPaged = value; - } - } + // Tape + //TapeDevice.ProcessMicBit((value & MIC_BIT) != 0); + } + + + LastULAOutByte = value; + } + + /// + /// +3 and 2a overidden method + /// + public override int _ROMpaged + { + get + { + // calculate the ROMpage from the high and low bits + var rp = ZXSpectrum.GetIntFromBitArray(new BitArray(new bool[] { ROMlow, ROMhigh })); + return rp; + } + set => ROMPaged = value; + } + } } diff --git a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum16K/ZX16.cs b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum16K/ZX16.cs index 61b3ae4ece9..525749f0dab 100644 --- a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum16K/ZX16.cs +++ b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum16K/ZX16.cs @@ -15,19 +15,19 @@ public ZX16(ZXSpectrum spectrum, Z80A cpu, ZXSpectrum.Border : base(spectrum, cpu, borderType, files, joysticks) {} /* 48K Spectrum has NO memory paging - * - * - | Bank 0 | - | | - | | - | screen | - 0x4000 +--------+ - | ROM 0 | - | | - | | - | | - 0x0000 +--------+ - */ + * + * + | Bank 0 | + | | + | | + | screen | + 0x4000 +--------+ + | ROM 0 | + | | + | | + | | + 0x0000 +--------+ + */ /// /// Simulates reading from the bus (no contention) diff --git a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Disk/FloppyDisk.cs b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Disk/FloppyDisk.cs index cbe56f61e13..dfdd3e656fb 100644 --- a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Disk/FloppyDisk.cs +++ b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Disk/FloppyDisk.cs @@ -399,102 +399,102 @@ public bool DetectHexagon(ref int[] weak) } /* - /// - /// Should be run at the end of the ParseDisk process - /// If speedlock is detected the flag is set in the disk image - /// - protected virtual void SpeedlockDetection() - { - - if (DiskTracks.Length == 0) - return; - - // check for speedlock copyright notice - string ident = Encoding.ASCII.GetString(DiskData, 0x100, 0x1400); - if (!ident.ContainsIgnoreCase("SPEEDLOCK")) - { - // speedlock not found - return; - } - - // get cylinder 0 - var cyl = DiskTracks[0]; - - // get sector with ID=2 - var sec = cyl.Sectors.Where(a => a.SectorID == 2).FirstOrDefault(); - - if (sec == null) - return; - - // check for already multiple weak copies - if (sec.ContainsMultipleWeakSectors || sec.SectorData.Length != 0x80 << sec.SectorSize) - return; - - // check for invalid crcs in sector 2 - if (sec.Status1.Bit(5) || sec.Status2.Bit(5)) - { - Protection = ProtectionType.Speedlock; - } - else - { - return; - } - - // we are going to create a total of 5 weak sector copies - // keeping the original copy - byte[] origData = sec.SectorData.ToArray(); - List data = new(); //TODO pretty sure the length and indices here are known in advance and this can just be an array --yoshi - - for (int i = 0; i < 6; i++) - { - for (int s = 0; s < origData.Length; s++) - { - if (i == 0) - { - data.Add(origData[s]); - continue; - } - - // deterministic 'random' implementation - int n = origData[s] + i + 1; - if (n > 0xff) - n = n - 0xff; - else if (n < 0) - n = 0xff + n; - - byte nByte = (byte)n; - - if (s < 336) - { - // non weak data - data.Add(origData[s]); - } - else if (s < 511) - { - // weak data - data.Add(nByte); - } - else if (s == 511) - { - // final sector byte - data.Add(nByte); - } - else - { - // speedlock sector should not be more than 512 bytes - // but in case it is just do non weak - data.Add(origData[i]); - } - } - } - - // commit the sector data - sec.SectorData = data.ToArray(); - sec.ContainsMultipleWeakSectors = true; - sec.ActualDataByteLength = data.Count; - - } - */ + /// + /// Should be run at the end of the ParseDisk process + /// If speedlock is detected the flag is set in the disk image + /// + protected virtual void SpeedlockDetection() + { + + if (DiskTracks.Length == 0) + return; + + // check for speedlock copyright notice + string ident = Encoding.ASCII.GetString(DiskData, 0x100, 0x1400); + if (!ident.ContainsIgnoreCase("SPEEDLOCK")) + { + // speedlock not found + return; + } + + // get cylinder 0 + var cyl = DiskTracks[0]; + + // get sector with ID=2 + var sec = cyl.Sectors.Where(a => a.SectorID == 2).FirstOrDefault(); + + if (sec == null) + return; + + // check for already multiple weak copies + if (sec.ContainsMultipleWeakSectors || sec.SectorData.Length != 0x80 << sec.SectorSize) + return; + + // check for invalid crcs in sector 2 + if (sec.Status1.Bit(5) || sec.Status2.Bit(5)) + { + Protection = ProtectionType.Speedlock; + } + else + { + return; + } + + // we are going to create a total of 5 weak sector copies + // keeping the original copy + byte[] origData = sec.SectorData.ToArray(); + List data = new(); //TODO pretty sure the length and indices here are known in advance and this can just be an array --yoshi + + for (int i = 0; i < 6; i++) + { + for (int s = 0; s < origData.Length; s++) + { + if (i == 0) + { + data.Add(origData[s]); + continue; + } + + // deterministic 'random' implementation + int n = origData[s] + i + 1; + if (n > 0xff) + n = n - 0xff; + else if (n < 0) + n = 0xff + n; + + byte nByte = (byte)n; + + if (s < 336) + { + // non weak data + data.Add(origData[s]); + } + else if (s < 511) + { + // weak data + data.Add(nByte); + } + else if (s == 511) + { + // final sector byte + data.Add(nByte); + } + else + { + // speedlock sector should not be more than 512 bytes + // but in case it is just do non weak + data.Add(origData[i]); + } + } + } + + // commit the sector data + sec.SectorData = data.ToArray(); + sec.ContainsMultipleWeakSectors = true; + sec.ActualDataByteLength = data.Count; + + } + */ /// /// Returns the track count for the disk @@ -669,14 +669,14 @@ public byte[] ActualData return res; /* - int copies = ActualDataByteLength / (0x80 << SectorSize); - var r = new Random(Seed: 4) // chosen by fair dice roll. guaranteed to be random. - .Next(0, copies - 1); - int step = r * (0x80 << SectorSize); - byte[] res = new byte[(0x80 << SectorSize)]; - Array.Copy(SectorData, step, res, 0, 0x80 << SectorSize); - return res; - */ + int copies = ActualDataByteLength / (0x80 << SectorSize); + var r = new Random(Seed: 4) // chosen by fair dice roll. guaranteed to be random. + .Next(0, copies - 1); + int step = r * (0x80 << SectorSize); + byte[] res = new byte[(0x80 << SectorSize)]; + Array.Copy(SectorData, step, res, 0, 0x80 << SectorSize); + return res; + */ } } } diff --git a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Snapshot/SZX/SZX.Methods.cs b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Snapshot/SZX/SZX.Methods.cs index f1c11e00091..8a943994c60 100644 --- a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Snapshot/SZX/SZX.Methods.cs +++ b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Snapshot/SZX/SZX.Methods.cs @@ -179,47 +179,47 @@ public static byte[] ExportSZX(SpectrumBase machine) break; } /* - // ZXSTPLUS3 - if (s._machine.Spectrum.MachineType == MachineType.ZXSpectrum128Plus3) - { - var iStruct = s.GetZXSTPLUS3(); - block.dwId = MediaConverter.GetUInt32(Encoding.UTF8.GetBytes("+3\0\0"), 0); - block.dwSize = (uint)Marshal.SizeOf(iStruct); - buff = MediaConverter.SerializeRaw(block); - r.Write(buff); - buff = MediaConverter.SerializeRaw(iStruct); - r.Write(buff); - - // ZXSTDSKFILE - if (s._machine.diskImages.Count() > 0) - { - var jStruct = s.GetZXSTDSKFILE(); - block.dwId = MediaConverter.GetUInt32(Encoding.UTF8.GetBytes("DSK\0"), 0); - block.dwSize = (uint)Marshal.SizeOf(jStruct); - buff = MediaConverter.SerializeRaw(block); - r.Write(buff); - buff = MediaConverter.SerializeRaw(jStruct); - r.Write(buff); - } - } - - // ZXSTTAPE - if (s._machine.tapeImages.Count() > 0) - { - var hStruct = s.GetZXSTTAPE(); - var tapeData = s._machine.tapeImages[s._machine.TapeMediaIndex]; - block.dwId = MediaConverter.GetUInt32(Encoding.UTF8.GetBytes("TAPE"), 0); - block.dwSize = (uint)Marshal.SizeOf(hStruct) + (uint)tapeData.Length; - buff = MediaConverter.SerializeRaw(block); - r.Write(buff); - buff = MediaConverter.SerializeRaw(hStruct); - r.Write(buff); - buff = MediaConverter.SerializeRaw(tapeData); - r.Write(buff); - char[] terminator = "\0".ToCharArray(); - r.Write(terminator); - } - */ + // ZXSTPLUS3 + if (s._machine.Spectrum.MachineType == MachineType.ZXSpectrum128Plus3) + { + var iStruct = s.GetZXSTPLUS3(); + block.dwId = MediaConverter.GetUInt32(Encoding.UTF8.GetBytes("+3\0\0"), 0); + block.dwSize = (uint)Marshal.SizeOf(iStruct); + buff = MediaConverter.SerializeRaw(block); + r.Write(buff); + buff = MediaConverter.SerializeRaw(iStruct); + r.Write(buff); + + // ZXSTDSKFILE + if (s._machine.diskImages.Count() > 0) + { + var jStruct = s.GetZXSTDSKFILE(); + block.dwId = MediaConverter.GetUInt32(Encoding.UTF8.GetBytes("DSK\0"), 0); + block.dwSize = (uint)Marshal.SizeOf(jStruct); + buff = MediaConverter.SerializeRaw(block); + r.Write(buff); + buff = MediaConverter.SerializeRaw(jStruct); + r.Write(buff); + } + } + + // ZXSTTAPE + if (s._machine.tapeImages.Count() > 0) + { + var hStruct = s.GetZXSTTAPE(); + var tapeData = s._machine.tapeImages[s._machine.TapeMediaIndex]; + block.dwId = MediaConverter.GetUInt32(Encoding.UTF8.GetBytes("TAPE"), 0); + block.dwSize = (uint)Marshal.SizeOf(hStruct) + (uint)tapeData.Length; + buff = MediaConverter.SerializeRaw(block); + r.Write(buff); + buff = MediaConverter.SerializeRaw(hStruct); + r.Write(buff); + buff = MediaConverter.SerializeRaw(tapeData); + r.Write(buff); + char[] terminator = "\0".ToCharArray(); + r.Write(terminator); + } + */ } result = ms.ToArray(); diff --git a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/CSW/CswConverter.cs b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/CSW/CswConverter.cs index e2cbedce039..9c594fd5927 100644 --- a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/CSW/CswConverter.cs +++ b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/CSW/CswConverter.cs @@ -111,27 +111,27 @@ public override void Read(byte[] data) if (majorVer == 2) { /* - CSW-2 Header - CSW global file header - status: required - Offset Value Type Description - 0x00 (note) ASCII[22] "Compressed Square Wave" signature - 0x16 0x1A BYTE Terminator code - 0x17 0x02 BYTE CSW major revision number - 0x18 0x00 BYTE CSW minor revision number - 0x19 - DWORD Sample rate - 0x1D - DWORD Total number of pulses (after decompression) - 0x21 - BYTE Compression type (see notes below) - 0x01: RLE - 0x02: Z-RLE - 0x22 - BYTE Flags - b0: initial polarity; if set, the signal starts at logical high - 0x23 HDR BYTE Header extension length in bytes (0x00) - For future expansions only, see note below. - 0x24 - ASCIIZ[16] Encoding application description - Information about the tool which created the file (e.g. name and version) - 0x34 - BYTE[HDR] Header extension data (if present) - 0x34+HDR - - CSW data. - */ + CSW-2 Header + CSW global file header - status: required + Offset Value Type Description + 0x00 (note) ASCII[22] "Compressed Square Wave" signature + 0x16 0x1A BYTE Terminator code + 0x17 0x02 BYTE CSW major revision number + 0x18 0x00 BYTE CSW minor revision number + 0x19 - DWORD Sample rate + 0x1D - DWORD Total number of pulses (after decompression) + 0x21 - BYTE Compression type (see notes below) + 0x01: RLE + 0x02: Z-RLE + 0x22 - BYTE Flags + b0: initial polarity; if set, the signal starts at logical high + 0x23 HDR BYTE Header extension length in bytes (0x00) + For future expansions only, see note below. + 0x24 - ASCIIZ[16] Encoding application description + Information about the tool which created the file (e.g. name and version) + 0x34 - BYTE[HDR] Header extension data (if present) + 0x34+HDR - - CSW data. + */ _position = 0x19; sampleRate = GetInt32(data, _position); @@ -155,21 +155,21 @@ Information about the tool which created the file (e.g. name and version) else if (majorVer == 1) { /* - CSW-1 Header - CSW global file header - status: required - Offset Value Type Description - 0x00 (note) ASCII[22] "Compressed Square Wave" signature - 0x16 0x1A BYTE Terminator code - 0x17 0x01 BYTE CSW major revision number - 0x18 0x01 BYTE CSW minor revision number - 0x19 - WORD Sample rate - 0x1B 0x01 BYTE Compression type - 0x01: RLE - 0x1C - BYTE Flags - b0: initial polarity; if set, the signal starts at logical high - 0x1D 0x00 BYTE[3] Reserved. - 0x20 - - CSW data. - */ + CSW-1 Header + CSW global file header - status: required + Offset Value Type Description + 0x00 (note) ASCII[22] "Compressed Square Wave" signature + 0x16 0x1A BYTE Terminator code + 0x17 0x01 BYTE CSW major revision number + 0x18 0x01 BYTE CSW minor revision number + 0x19 - WORD Sample rate + 0x1B 0x01 BYTE Compression type + 0x01: RLE + 0x1C - BYTE Flags + b0: initial polarity; if set, the signal starts at logical high + 0x1D 0x00 BYTE[3] Reserved. + 0x20 - - CSW data. + */ _position = 0x19; sampleRate = GetWordValue(data, _position); diff --git a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/PZX/PzxConverter.cs b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/PZX/PzxConverter.cs index df416ae6f03..68d308eef3e 100644 --- a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/PZX/PzxConverter.cs +++ b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/PZX/PzxConverter.cs @@ -87,13 +87,13 @@ public override void Read(byte[] data) _datacorder.DataBlocks.Clear(); /* - // PZX uniform block layout - offset type name meaning - ------ ---- ---- ------- - 0 u32 tag unique identifier for the block type. - 4 u32 size size of the block in bytes, excluding the tag and size fields themselves. - 8 u8[size] data arbitrary amount of block data. - */ + // PZX uniform block layout + offset type name meaning + ------ ---- ---- ------- + 0 u32 tag unique identifier for the block type. + 4 u32 size size of the block in bytes, excluding the tag and size fields themselves. + 8 u8[size] data arbitrary amount of block data. + */ // check whether this is a valid pzx format file by looking at the identifier in the header block string ident = Encoding.ASCII.GetString(data, 0, 4); @@ -139,25 +139,25 @@ 8 u8[size] data arbitrary amount of block data. { // PZXT - PZX header block /* - offset type name meaning - 0 u8 major major version number (currently 1). - 1 u8 minor minor version number (currently 0). - 2 u8[?] info tape info, see below. - */ + offset type name meaning + 0 u8 major major version number (currently 1). + 1 u8 minor minor version number (currently 0). + 2 u8[?] info tape info, see below. + */ case "PZXT": break; // PULS - Pulse sequence /* - offset type name meaning - 0 u16 count bits 0-14 optional repeat count (see bit 15), always greater than zero - bit 15 repeat count present: 0 not present 1 present - 2 u16 duration1 bits 0-14 low/high (see bit 15) pulse duration bits - bit 15 duration encoding: 0 duration1 1 ((duration1<<16)+duration2) - 4 u16 duration2 optional low bits of pulse duration (see bit 15 of duration1) - 6 ... ... ditto repeated until the end of the block - */ + offset type name meaning + 0 u16 count bits 0-14 optional repeat count (see bit 15), always greater than zero + bit 15 repeat count present: 0 not present 1 present + 2 u16 duration1 bits 0-14 low/high (see bit 15) pulse duration bits + bit 15 duration encoding: 0 duration1 1 ((duration1<<16)+duration2) + 4 u16 duration2 optional low bits of pulse duration (see bit 15 of duration1) + 6 ... ... ditto repeated until the end of the block + */ case "PULS": t.BlockID = GetInt32(b, 0); @@ -214,16 +214,16 @@ 6 ... ... ditto repeated until the end of the block // DATA - Data block /* - offset type name meaning - 0 u32 count bits 0-30 number of bits in the data stream - bit 31 initial pulse level: 0 low 1 high - 4 u16 tail duration of extra pulse after last bit of the block - 6 u8 p0 number of pulses encoding bit equal to 0. - 7 u8 p1 number of pulses encoding bit equal to 1. - 8 u16[p0] s0 sequence of pulse durations encoding bit equal to 0. - 8+2*p0 u16[p1] s1 sequence of pulse durations encoding bit equal to 1. - 8+2*(p0+p1) u8[ceil(bits/8)] data data stream, see below. - */ + offset type name meaning + 0 u32 count bits 0-30 number of bits in the data stream + bit 31 initial pulse level: 0 low 1 high + 4 u16 tail duration of extra pulse after last bit of the block + 6 u8 p0 number of pulses encoding bit equal to 0. + 7 u8 p1 number of pulses encoding bit equal to 1. + 8 u16[p0] s0 sequence of pulse durations encoding bit equal to 0. + 8+2*p0 u16[p1] s1 sequence of pulse durations encoding bit equal to 1. + 8+2*(p0+p1) u8[ceil(bits/8)] data data stream, see below. + */ case "DATA": t.BlockID = GetInt32(b, 0); @@ -315,10 +315,10 @@ 8 u16[p0] s0 sequence of pulse durations encoding bit equa // PAUS - Pause /* - offset type name meaning - 0 u32 duration bits 0-30 duration of the pause - bit 31 initial pulse level: 0 low 1 high - */ + offset type name meaning + 0 u32 duration bits 0-30 duration of the pause + bit 31 initial pulse level: 0 low 1 high + */ case "PAUS": t.BlockID = GetInt32(b, 0); @@ -353,9 +353,9 @@ 0 u32 duration bits 0-30 duration of the pause // BRWS - Browse point /* - offset type name meaning - 0 u8[?] text text describing this browse point - */ + offset type name meaning + 0 u8[?] text text describing this browse point + */ case "BRWS": t.BlockID = GetInt32(b, 0); @@ -374,9 +374,9 @@ 0 u8[?] text text describing this browse point // STOP - Stop tape command /* - offset type name meaning - 0 u16 flags when exactly to stop the tape (1 48k only, other always). - */ + offset type name meaning + 0 u16 flags when exactly to stop the tape (1 48k only, other always). + */ case "STOP": diff --git a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/TAP/TapConverter.cs b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/TAP/TapConverter.cs index 1fcc30263f9..22e8c1f6e36 100644 --- a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/TAP/TapConverter.cs +++ b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/TAP/TapConverter.cs @@ -92,24 +92,24 @@ public TapConverter(DatacorderDevice _tapeDevice) public override void Read(byte[] data) { /* - The .TAP files contain blocks of tape-saved data. All blocks start with two bytes specifying how many bytes will follow (not counting the two length bytes). Then raw tape data follows, including the flag and checksum bytes. The checksum is the bitwise XOR of all bytes including the flag byte. For example, when you execute the line SAVE "ROM" CODE 0,2 this will result: + The .TAP files contain blocks of tape-saved data. All blocks start with two bytes specifying how many bytes will follow (not counting the two length bytes). Then raw tape data follows, including the flag and checksum bytes. The checksum is the bitwise XOR of all bytes including the flag byte. For example, when you execute the line SAVE "ROM" CODE 0,2 this will result: - |------ Spectrum-generated data -------| |---------| + |------ Spectrum-generated data -------| |---------| - 13 00 00 03 52 4f 4d 7x20 02 00 00 00 00 80 f1 04 00 ff f3 af a3 + 13 00 00 03 52 4f 4d 7x20 02 00 00 00 00 80 f1 04 00 ff f3 af a3 - ^^^^^...... first block is 19 bytes (17 bytes+flag+checksum) - ^^... flag byte (A reg, 00 for headers, ff for data blocks) - ^^ first byte of header, indicating a code block + ^^^^^...... first block is 19 bytes (17 bytes+flag+checksum) + ^^... flag byte (A reg, 00 for headers, ff for data blocks) + ^^ first byte of header, indicating a code block - file name ..^^^^^^^^^^^^^ - header info ..............^^^^^^^^^^^^^^^^^ - checksum of header .........................^^ - length of second block ........................^^^^^ - flag byte ............................................^^ - first two bytes of rom .................................^^^^^ - checksum (checkbittoggle would be a better name!).............^^ - */ + file name ..^^^^^^^^^^^^^ + header info ..............^^^^^^^^^^^^^^^^^ + checksum of header .........................^^ + length of second block ........................^^^^^ + flag byte ............................................^^ + first two bytes of rom .................................^^^^^ + checksum (checkbittoggle would be a better name!).............^^ + */ // clear existing tape blocks _datacorder.DataBlocks.Clear(); @@ -162,12 +162,13 @@ first two bytes of rom .................................^^^^^ } // process the type byte - /* (The type is 0,1,2 or 3 for a Program, Number array, Character array or Code file. - A SCREEN$ file is regarded as a Code file with start address 16384 and length 6912 decimal. - If the file is a Program file, parameter 1 holds the autostart line number (or a number >=32768 if no LINE parameter was given) - and parameter 2 holds the start of the variable area relative to the start of the program. If it's a Code file, parameter 1 holds - the start of the code block when saved, and parameter 2 holds 32768. For data files finally, the byte at position 14 decimal holds the variable name.) - */ + /* + (The type is 0,1,2 or 3 for a Program, Number array, Character array or Code file. + A SCREEN$ file is regarded as a Code file with start address 16384 and length 6912 decimal. + If the file is a Program file, parameter 1 holds the autostart line number (or a number >=32768 if no LINE parameter was given) + and parameter 2 holds the start of the variable area relative to the start of the program. If it's a Code file, parameter 1 holds + the start of the code block when saved, and parameter 2 holds 32768. For data files finally, the byte at position 14 decimal holds the variable name.) + */ tdb.MetaData = new Dictionary(); @@ -220,47 +221,47 @@ A SCREEN$ file is regarded as a Code file with start address 16384 and length 69 tdb.AddMetaData(BlockDescriptorTitle.Undefined, description); } /* - if (blockdata[0] == 0x00 && blockSize == 19 && (blockdata[1] == 0x00) || blockdata[1] == 3) - { - // This is the PROGRAM header - // take the 10 filename bytes (that start at offset 2) - programData = blockdata.Skip(2).Take(10).ToArray(); - - // get the filename as a string (with padding removed) - string fileName = Encoding.ASCII.GetString(programData).Trim(); - - // get the type - string type = ""; - if (blockdata[0] == 0x00) - { - type = "Program"; - } - else - { - type = "Bytes"; - } - - // now build the description string - StringBuilder sb = new StringBuilder(); - sb.Append(type + ": "); - sb.Append(fileName + " "); - sb.Append(GetWordValue(blockdata, 14)); - sb.Append(':'); - sb.Append(GetWordValue(blockdata, 12)); - description = sb.ToString(); - } - else if (blockdata[0] == 0xFF) - { - // this is a data block - description = "Data Block " + (blockSize - 2) + "bytes"; - } - else - { - // other type - description = $"#{blockdata[0]:X2} block, {blockSize - 2} bytes"; - description += (crc != 0) ? $", crc bad (#{crcFile:X2}!=#{crcValue:X2})" : ", crc ok"; - } - */ + if (blockdata[0] == 0x00 && blockSize == 19 && (blockdata[1] == 0x00) || blockdata[1] == 3) + { + // This is the PROGRAM header + // take the 10 filename bytes (that start at offset 2) + programData = blockdata.Skip(2).Take(10).ToArray(); + + // get the filename as a string (with padding removed) + string fileName = Encoding.ASCII.GetString(programData).Trim(); + + // get the type + string type = ""; + if (blockdata[0] == 0x00) + { + type = "Program"; + } + else + { + type = "Bytes"; + } + + // now build the description string + StringBuilder sb = new StringBuilder(); + sb.Append(type + ": "); + sb.Append(fileName + " "); + sb.Append(GetWordValue(blockdata, 14)); + sb.Append(':'); + sb.Append(GetWordValue(blockdata, 12)); + description = sb.ToString(); + } + else if (blockdata[0] == 0xFF) + { + // this is a data block + description = "Data Block " + (blockSize - 2) + "bytes"; + } + else + { + // other type + description = $"#{blockdata[0]:X2} block, {blockSize - 2} bytes"; + description += (crc != 0) ? $", crc bad (#{crcFile:X2}!=#{crcValue:X2})" : ", crc ok"; + } + */ tdb.BlockDescription = BlockType.Standard_Speed_Data_Block; diff --git a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/TZX/TzxConverter.cs b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/TZX/TzxConverter.cs index 19b46b016f3..c749356749b 100644 --- a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/TZX/TzxConverter.cs +++ b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Tape/TZX/TzxConverter.cs @@ -59,14 +59,14 @@ public TzxConverter(DatacorderDevice _tapeDevice) public override bool CheckType(byte[] tzxRaw) { /* - // TZX Header - length: 10 bytes - Offset Value Type Description - 0x00 "ZXTape!" ASCII[7] TZX signature - 0x07 0x1A BYTE End of text file marker - 0x08 1 BYTE TZX major revision number - 0x09 20 BYTE TZX minor revision number - */ + // TZX Header + length: 10 bytes + Offset Value Type Description + 0x00 "ZXTape!" ASCII[7] TZX signature + 0x07 0x1A BYTE End of text file marker + 0x08 1 BYTE TZX major revision number + 0x09 20 BYTE TZX minor revision number + */ // check whether this is a valid tzx format file by looking at the identifier in the header // (first 7 bytes of the file) @@ -1938,18 +1938,19 @@ private void ProcessBlockID34() _position += 8; } - /* length: [01,02,03]+04 - Offset Value Type Description - 0x00 - BYTE Snapshot type: - 00: .Z80 format - 01: .SNA format - 0x01 L BYTE[3] Snapshot length - 0x04 - BYTE[L] Snapshot itself - - This would enable one to snapshot the game at the start and still have all the tape blocks (level data, etc.) in the same file. - Only .Z80 and .SNA snapshots are supported for compatibility reasons! - The emulator should take care of that the snapshot is not taken while the actual Tape loading is taking place (which doesn't do much sense). - And when an emulator encounters the snapshot block it should load it and then continue with the next block. */ + /* length: [01,02,03]+04 + Offset Value Type Description + 0x00 - BYTE Snapshot type: + 00: .Z80 format + 01: .SNA format + 0x01 L BYTE[3] Snapshot length + 0x04 - BYTE[L] Snapshot itself + + This would enable one to snapshot the game at the start and still have all the tape blocks (level data, etc.) in the same file. + Only .Z80 and .SNA snapshots are supported for compatibility reasons! + The emulator should take care of that the snapshot is not taken while the actual Tape loading is taking place (which doesn't do much sense). + And when an emulator encounters the snapshot block it should load it and then continue with the next block. + */ private void ProcessBlockID40() { // currently not implemented properly in ZXHawk diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.cs index 51ca93e79d8..de02213be23 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.cs @@ -214,7 +214,7 @@ public GBHawk(CoreComm comm, GameInfo game, byte[] rom, /*string gameDbFn,*/ GBS _tracer = new TraceBuffer(cpu.TraceHeader); ser.Register(_tracer); ser.Register(new StateSerializer(SyncState)); - ser.Register(_disassembler); + ser.Register(_disassembler); SetupMemoryDomains(); cpu.SetCallbacks(ReadMemory, PeekMemory, PeekMemory, WriteMemory); HardReset(); diff --git a/src/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.cs b/src/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.cs index 8b09cbb1901..e55079ecf10 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.cs @@ -3,10 +3,10 @@ using BizHawk.Emulation.Cores.Components.Z80A; /***************************************************** - TODO: - + HCounter (Manually set for light phaser emulation... should be only case it's polled) - + Try to clean up the organization of the source code. - + Mode 1 not implemented in VDP TMS modes. (I don't have a test case in SG1000 or Coleco) +TODO: ++ HCounter (Manually set for light phaser emulation... should be only case it's polled) ++ Try to clean up the organization of the source code. ++ Mode 1 not implemented in VDP TMS modes. (I don't have a test case in SG1000 or Coleco) **********************************************************/ diff --git a/src/BizHawk.Emulation.Cores/Waterbox/NymaCore.Controller.cs b/src/BizHawk.Emulation.Cores/Waterbox/NymaCore.Controller.cs index ac2ab3c8c9f..533d4f03474 100644 --- a/src/BizHawk.Emulation.Cores/Waterbox/NymaCore.Controller.cs +++ b/src/BizHawk.Emulation.Cores/Waterbox/NymaCore.Controller.cs @@ -228,7 +228,7 @@ public ControllerAdapter( } _switchPreviousFrame[si] = val; _switchPreviousFrame[si + 1] = allNewPressed; - b[byteStart] |= (byte)(val << bitOffset); + b[byteStart] |= (byte)(val << bitOffset); }); break; } diff --git a/src/BizHawk.Emulation.DiscSystem/DiscFormats/MDS_Format.cs b/src/BizHawk.Emulation.DiscSystem/DiscFormats/MDS_Format.cs index bc876c80e1a..2c42948a95d 100644 --- a/src/BizHawk.Emulation.DiscSystem/DiscFormats/MDS_Format.cs +++ b/src/BizHawk.Emulation.DiscSystem/DiscFormats/MDS_Format.cs @@ -145,7 +145,7 @@ public class ASession public byte NonTrackBlocks; /* Number of lead-in data blocks */ public int FirstTrack; /* First track in session */ public int LastTrack; /* Last track in session */ - public long TrackOffset; /* Offset of lead-in+regular track data blocks. */ + public long TrackOffset; /* Offset of lead-in+regular track data blocks. */ } /// @@ -173,7 +173,7 @@ public class ATrack public byte SubMode; /* Subchannel mode */ /* These are the fields from Sub-channel Q information, which are - also returned in full TOC by READ TOC/PMA/ATIP command */ + also returned in full TOC by READ TOC/PMA/ATIP command */ public int ADR_Control; /* Adr/Ctl */ public int TrackNo; /* Track number field */ public int Point; /* Point field (= track number for track entries) */ diff --git a/src/BizHawk.Emulation.DiscSystem/DiscTrack.cs b/src/BizHawk.Emulation.DiscSystem/DiscTrack.cs index 47e1e90fd9c..666341050d6 100644 --- a/src/BizHawk.Emulation.DiscSystem/DiscTrack.cs +++ b/src/BizHawk.Emulation.DiscSystem/DiscTrack.cs @@ -1,68 +1,68 @@ namespace BizHawk.Emulation.DiscSystem { /// - /// Information about a Track. - /// - public class DiscTrack - { - //Notable omission: - //a list of Indices. It's difficult to reliably construct it. - //Notably, mednafen can't readily produce it. - //Indices may need scanning sector by sector. - //It's unlikely that any software would be needing indices anyway. - //We should add another index scanning service if that's ever needed. - //(note: a CCD should contain indices, but it's not clear whether it's required. logically it shouldn't be) - //Notable omission: - //Length of the track. - //How should this be defined? Between which indices? It's really hard. + /// Information about a Track. + /// + public class DiscTrack + { + //Notable omission: + //a list of Indices. It's difficult to reliably construct it. + //Notably, mednafen can't readily produce it. + //Indices may need scanning sector by sector. + //It's unlikely that any software would be needing indices anyway. + //We should add another index scanning service if that's ever needed. + //(note: a CCD should contain indices, but it's not clear whether it's required. logically it shouldn't be) + //Notable omission: + //Length of the track. + //How should this be defined? Between which indices? It's really hard. - //These omissions could be handled by ReadStructure() policies which permit the scanning of the entire disc. - //After that, they could be cached in here. + //These omissions could be handled by ReadStructure() policies which permit the scanning of the entire disc. + //After that, they could be cached in here. - /// - /// The number of the track (1-indexed) - /// - public int Number; + /// + /// The number of the track (1-indexed) + /// + public int Number; - /// - /// The Mode of the track (0 is Audio, 1 and 2 are data) - /// This is heuristically determined. - /// Actual sector contents may vary - /// - public int Mode; + /// + /// The Mode of the track (0 is Audio, 1 and 2 are data) + /// This is heuristically determined. + /// Actual sector contents may vary + /// + public int Mode; - /// - /// Is this track a Data track? - /// - public bool IsData => !IsAudio; + /// + /// Is this track a Data track? + /// + public bool IsData => !IsAudio; - /// - /// Is this track an Audio track? - /// - public bool IsAudio => Mode == 0; + /// + /// Is this track an Audio track? + /// + public bool IsAudio => Mode == 0; - /// - /// The 'control' properties of the track expected to be found in the track's subQ. - /// However, this is what's indicated by the disc TOC. - /// Actual sector contents may vary. - /// - public EControlQ Control; + /// + /// The 'control' properties of the track expected to be found in the track's subQ. + /// However, this is what's indicated by the disc TOC. + /// Actual sector contents may vary. + /// + public EControlQ Control; - /// - /// The starting LBA of the track (index 1). - /// - public int LBA; + /// + /// The starting LBA of the track (index 1). + /// + public int LBA; - /// - /// The next track in the session. null for the leadout track of a session. - /// - public DiscTrack NextTrack; + /// + /// The next track in the session. null for the leadout track of a session. + /// + public DiscTrack NextTrack; /// /// The Type of a track as specified in the TOC Q-Subchannel data from the control flags. /// Could also be 4-Channel Audio, but we'll handle that later if needed /// - public enum ETrackType + public enum ETrackType { /// /// The track type isn't always known.. it can take this value til its populated @@ -79,5 +79,5 @@ public enum ETrackType /// Audio, } - } + } } \ No newline at end of file From 73c78a351e1a31f37ec212bb512fc08f58a979c5 Mon Sep 17 00:00:00 2001 From: SuuperW Date: Sat, 2 Aug 2025 16:31:06 -0500 Subject: [PATCH 2/8] update .git-blame-ignore-revs --- .git-blame-ignore-revs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 9bf8ffb97c8..d9ed1394360 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -21,3 +21,6 @@ fec63fb66afe70a22cf328eecdaf09e37c21ada5 # Remove line-end whitespace across main solution 605deb682dacec3342c650e76fb77972e5ffbe04 + +# Fix use of mixed spaces and tabs for indentation +1f62c65b6a9ccbe0837481a8c691ac4598868a83 From a765111570d7a4074b198238de08635c7f7232b4 Mon Sep 17 00:00:00 2001 From: SuuperW Date: Tue, 8 Jul 2025 21:32:20 -0500 Subject: [PATCH 3/8] Enable IDE0051 and IDE0052 (remove unread/unused private member) and fix (or ignore) violations. Don't bother with a couple of particularly offensive cores. A few non-trivial violations remain. --- .editorconfig | 4 +- .../cheats/GbaGameSharkDecoder.cs | 4 +- .../fwmanager/FirmwareManager.cs | 1 - .../lua/CommonLibs/CommLuaLibrary.cs | 4 ++ src/BizHawk.Client.EmuHawk/AVOut/JMDWriter.cs | 2 +- .../AVOut/SynclessRecorder.cs | 4 ++ .../tools/Debugger/AddBreakpointDialog.cs | 39 +++++++------------ .../tools/ExternalToolManager.cs | 4 +- .../tools/Lua/LuaLibraries.cs | 6 --- .../tools/TAStudio/TAStudio.cs | 19 +-------- .../tools/TraceLogger.cs | 9 ----- .../controls/VirtualPadAnalogButton.cs | 2 +- .../SatellaviewFileTypeDetector.cs | 2 + .../CPUs/CP1610/.editorconfig | 7 ++++ .../CPUs/FairchildF8/F3850.Execute.cs | 8 ++-- .../CPUs/HuC6280/HuC6280.cs | 4 ++ .../CPUs/MC6800/Indexed_Modes.cs | 2 + .../CPUs/MC6800/OP_Tables.cs | 2 + .../CPUs/MOS 6502X/.editorconfig | 7 ++++ .../Computers/AmstradCPC/.editorconfig | 6 +++ .../Computers/Commodore64/.editorconfig | 6 +++ .../Computers/MSX/.editorconfig | 6 +++ .../Computers/SinclairSpectrum/.editorconfig | 6 +++ .../Consoles/Atari/A7800Hawk/.editorconfig | 6 +++ .../Consoles/Coleco/.editorconfig | 6 +++ .../GCE/Vectrex/VectrexHawk.ICodeDataLog.cs | 2 + .../Consoles/Nintendo/GBHawk/.editorconfig | 6 +++ .../Nintendo/GBHawkLink/GBHawkLink.cs | 2 + .../Consoles/Nintendo/N64/.editorconfig | 6 +++ .../Consoles/Nintendo/NES/.editorconfig | 6 +++ .../Consoles/PC Engine/ScsiCDBus.cs | 2 + .../Consoles/Sega/GGHawkLink/GGHawkLink.cs | 2 + .../Consoles/Sega/SMS/MemoryMap.Korea.cs | 2 + .../Consoles/Sega/SMS/TerebiOekaki.cs | 2 + .../Sound/OneBitBeeper.cs | 2 + src/BizHawk.Emulation.Cores/Sound/YM2413.cs | 2 + .../vpads_schemata/SmsSchema.cs | 2 + .../vpads_schemata/ZXSpectrumSchema.cs | 2 + .../DiscFormats/Blobs/Blob_ECM.cs | 4 +- .../DiscStream.cs | 2 - src/BizHawk.Emulation.DiscSystem/DiscUtils.cs | 16 -------- 41 files changed, 138 insertions(+), 88 deletions(-) create mode 100644 src/BizHawk.Emulation.Cores/CPUs/CP1610/.editorconfig create mode 100644 src/BizHawk.Emulation.Cores/CPUs/MOS 6502X/.editorconfig diff --git a/.editorconfig b/.editorconfig index e7fa14bdf8c..beae5341de0 100644 --- a/.editorconfig +++ b/.editorconfig @@ -70,9 +70,9 @@ dotnet_diagnostic.IDE0041.severity = warning dotnet_diagnostic.IDE0042.severity = suggestion # dotnet_diagnostic.IDE0049.severity = error # see SA1121 # Remove unused private member -dotnet_diagnostic.IDE0051.severity = suggestion +dotnet_diagnostic.IDE0051.severity = warning # Remove unread private member -dotnet_diagnostic.IDE0052.severity = silent # TODO: should be warning imo, but there's too much violation currently +dotnet_diagnostic.IDE0052.severity = warning # Use compound assignment dotnet_diagnostic.IDE0054.severity = warning # Use index operator diff --git a/src/BizHawk.Client.Common/cheats/GbaGameSharkDecoder.cs b/src/BizHawk.Client.Common/cheats/GbaGameSharkDecoder.cs index da83762119d..5ca78e946b5 100644 --- a/src/BizHawk.Client.Common/cheats/GbaGameSharkDecoder.cs +++ b/src/BizHawk.Client.Common/cheats/GbaGameSharkDecoder.cs @@ -7,7 +7,6 @@ namespace BizHawk.Client.Common.cheats public static class GbaGameSharkDecoder { private static readonly uint[] GameSharkSeeds = { 0x09F4FBBDU, 0x9681884AU, 0x352027E9U, 0xF3DEE5A7U }; - private static readonly uint[] ProActionReplaySeeds = { 0x7AA9648FU, 0x7FAE6994U, 0xC0EFAAD5U, 0x42712C57U }; private static string Decrypt(string code) { @@ -28,6 +27,8 @@ private static string Decrypt(string code) } // TODO: When to use this? +#if false + private static readonly uint[] ProActionReplaySeeds = { 0x7AA9648FU, 0x7FAE6994U, 0xC0EFAAD5U, 0x42712C57U }; private static string DecryptPro(string code) { var sum = 0xC6EF3720; @@ -43,6 +44,7 @@ private static string DecryptPro(string code) return $"{op1:X8} {op2:X8}"; } +#endif public static IDecodeResult Decode(string code) { diff --git a/src/BizHawk.Client.Common/fwmanager/FirmwareManager.cs b/src/BizHawk.Client.Common/fwmanager/FirmwareManager.cs index dd6b39efd89..943d75404aa 100644 --- a/src/BizHawk.Client.Common/fwmanager/FirmwareManager.cs +++ b/src/BizHawk.Client.Common/fwmanager/FirmwareManager.cs @@ -13,7 +13,6 @@ namespace BizHawk.Client.Common { public sealed class FirmwareManager { - private static readonly FirmwareID NDS_FIRMWARE = new("NDS", "firmware"); private const int DSI_NAND_LENGTH = 251658240 + 64; public static (byte[] Patched, string ActualHash) PerformPatchInMemory(byte[] @base, in FirmwarePatchOption patchOption) diff --git a/src/BizHawk.Client.Common/lua/CommonLibs/CommLuaLibrary.cs b/src/BizHawk.Client.Common/lua/CommonLibs/CommLuaLibrary.cs index 81b34a90173..ef84385b389 100644 --- a/src/BizHawk.Client.Common/lua/CommonLibs/CommLuaLibrary.cs +++ b/src/BizHawk.Client.Common/lua/CommonLibs/CommLuaLibrary.cs @@ -1,4 +1,6 @@ +#if ENABLE_WEBSOCKETS using System.Collections.Generic; +#endif using System.ComponentModel; using System.Linq; using System.Text; @@ -10,7 +12,9 @@ namespace BizHawk.Client.Common [Description("A library for communicating with other programs")] public sealed class CommLuaLibrary : LuaLibraryBase { +#if ENABLE_WEBSOCKETS private readonly IDictionary _websockets = new Dictionary(); +#endif public CommLuaLibrary(ILuaLibraries luaLibsImpl, ApiContainer apiContainer, Action logOutputCallback) : base(luaLibsImpl, apiContainer, logOutputCallback) {} diff --git a/src/BizHawk.Client.EmuHawk/AVOut/JMDWriter.cs b/src/BizHawk.Client.EmuHawk/AVOut/JMDWriter.cs index 864e056892d..73728172de8 100644 --- a/src/BizHawk.Client.EmuHawk/AVOut/JMDWriter.cs +++ b/src/BizHawk.Client.EmuHawk/AVOut/JMDWriter.cs @@ -26,7 +26,7 @@ public class JmdWriter : IVideoWriter private const int NO_COMPRESSION = 0; private const int BEST_COMPRESSION = 9; private const int DEFAULT_COMPRESSION = -1; - private const int BEST_SPEED = 1; + //private const int BEST_SPEED = 1; private static CompressionLevel GetCompressionLevel(int v) { diff --git a/src/BizHawk.Client.EmuHawk/AVOut/SynclessRecorder.cs b/src/BizHawk.Client.EmuHawk/AVOut/SynclessRecorder.cs index 7dc76f9606a..de8afb8733c 100644 --- a/src/BizHawk.Client.EmuHawk/AVOut/SynclessRecorder.cs +++ b/src/BizHawk.Client.EmuHawk/AVOut/SynclessRecorder.cs @@ -1,5 +1,7 @@ using System.IO; +#if false using System.Collections.Generic; +#endif using System.Drawing.Imaging; using System.Text; @@ -113,6 +115,7 @@ public void SetMetaData(string gameName, string authors, ulong lengthMs, ulong r public string DesiredExtension() => "syncless.txt"; +#if false /// /// splits the string into chunks of length s /// @@ -139,6 +142,7 @@ private static List StringChunkSplit(string s, int len) return output; } +#endif private string GetAndCreatePathForFrameNum(int index) { diff --git a/src/BizHawk.Client.EmuHawk/tools/Debugger/AddBreakpointDialog.cs b/src/BizHawk.Client.EmuHawk/tools/Debugger/AddBreakpointDialog.cs index 834922c386b..cfe6d4bd814 100644 --- a/src/BizHawk.Client.EmuHawk/tools/Debugger/AddBreakpointDialog.cs +++ b/src/BizHawk.Client.EmuHawk/tools/Debugger/AddBreakpointDialog.cs @@ -9,9 +9,21 @@ public partial class AddBreakpointDialog : Form public AddBreakpointDialog(BreakpointOperation op) { InitializeComponent(); - Operation = op; AddressMaskBox.SetHexProperties(0xFFFFFFFF); AddressMask = 0xFFFFFFFF; + + switch (op) + { + case BreakpointOperation.Add: + Text = "Add Breakpoint"; + break; + case BreakpointOperation.Duplicate: + Text = "Duplicate Breakpoint"; + break; + case BreakpointOperation.Edit: + Text = "Edit Breakpoint"; + break; + } } public AddBreakpointDialog(BreakpointOperation op, uint address, uint mask, MemoryCallbackType type) @@ -23,31 +35,6 @@ public AddBreakpointDialog(BreakpointOperation op, uint address, uint mask, Memo BreakType = type; } - private BreakpointOperation _operation; - - private BreakpointOperation Operation - { - get => _operation; - - set - { - switch (value) - { - case BreakpointOperation.Add: - Text = "Add Breakpoint"; - break; - case BreakpointOperation.Duplicate: - Text = "Duplicate Breakpoint"; - break; - case BreakpointOperation.Edit: - Text = "Edit Breakpoint"; - break; - } - - _operation = value; - } - } - public void DisableExecuteOption() { if (ExecuteRadio.Checked) diff --git a/src/BizHawk.Client.EmuHawk/tools/ExternalToolManager.cs b/src/BizHawk.Client.EmuHawk/tools/ExternalToolManager.cs index 1c2d494ef4f..d689465291c 100644 --- a/src/BizHawk.Client.EmuHawk/tools/ExternalToolManager.cs +++ b/src/BizHawk.Client.EmuHawk/tools/ExternalToolManager.cs @@ -17,7 +17,9 @@ public sealed class ExternalToolManager { public struct MenuItemInfo { +#if !DEBUG private readonly string _asmChecksum; +#endif private readonly string _entryPointTypeName; @@ -33,12 +35,12 @@ public MenuItemInfo( string asmFilename, string entryPointTypeName) { - _asmChecksum = asmChecksum; _entryPointTypeName = entryPointTypeName; _extToolMan = extToolMan; #if DEBUG _skipExtToolWarning = true; #else + _asmChecksum = asmChecksum; _skipExtToolWarning = _extToolMan._config.TrustedExtTools.TryGetValue(asmFilename, out var s) && s == _asmChecksum; #endif AsmFilename = asmFilename; diff --git a/src/BizHawk.Client.EmuHawk/tools/Lua/LuaLibraries.cs b/src/BizHawk.Client.EmuHawk/tools/Lua/LuaLibraries.cs index c466bd7996f..fa9fb311d93 100644 --- a/src/BizHawk.Client.EmuHawk/tools/Lua/LuaLibraries.cs +++ b/src/BizHawk.Client.EmuHawk/tools/Lua/LuaLibraries.cs @@ -3,7 +3,6 @@ using System.IO; using System.Linq; using System.Reflection; -using System.Threading; using NLua; using NLua.Native; @@ -60,7 +59,6 @@ void EnumerateLuaFunctions(string name, Type type, LuaLibraryBase instance) _displayManager = displayManager; _inputManager = inputManager; _mainForm = mainForm; - LuaWait = new AutoResetEvent(false); PathEntries = config.PathEntries; RegisteredFunctions = registeredFuncList; ScriptList = scriptList; @@ -153,8 +151,6 @@ void EnumerateLuaFunctions(string name, Type type, LuaLibraryBase instance) private readonly DisplayManagerBase _displayManager; - private GuiApi GuiAPI => (GuiApi)_apiContainer.Gui; - private readonly InputManager _inputManager; private readonly MainForm _mainForm; @@ -182,8 +178,6 @@ void EnumerateLuaFunctions(string name, Type type, LuaLibraryBase instance) private readonly IDictionary Libraries = new Dictionary(); - private EventWaitHandle LuaWait; - public PathEntryCollection PathEntries { get; private set; } public LuaFileList ScriptList { get; } diff --git a/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs b/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs index 07712656610..7b2e6e75e82 100644 --- a/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs +++ b/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs @@ -497,23 +497,6 @@ public IMovieController GetBranchInput(string branchId, int frame) return controller; } - private int? FirstNonEmptySelectedFrame - { - get - { - var empty = Bk2LogEntryGenerator.EmptyEntry(MovieSession.MovieController); - foreach (var row in TasView.SelectedRows) - { - if (CurrentTasMovie[row].LogEntry != empty) - { - return row; - } - } - - return null; - } - } - private ITasMovie ConvertCurrentMovieToTasproj() { var tasMovie = MovieSession.Movie.ToTasMovie(); @@ -972,6 +955,7 @@ protected override bool ProcessCmdKey(ref Message msg, Keys keyData) return base.ProcessCmdKey(ref msg, keyData); } +#if false private bool AutoAdjustInput() { var lagLog = CurrentTasMovie[Emulator.Frame - 1]; // Minus one because get frame is +1; @@ -1024,6 +1008,7 @@ private bool AutoAdjustInput() return false; } +#endif private void MainVerticalSplit_SplitterMoved(object sender, SplitterEventArgs e) { diff --git a/src/BizHawk.Client.EmuHawk/tools/TraceLogger.cs b/src/BizHawk.Client.EmuHawk/tools/TraceLogger.cs index 912bf1d3d69..afd96b1f8b8 100644 --- a/src/BizHawk.Client.EmuHawk/tools/TraceLogger.cs +++ b/src/BizHawk.Client.EmuHawk/tools/TraceLogger.cs @@ -224,15 +224,6 @@ private void DumpToDisk() } } - private void LogToWindow() - { - if (_instructions.Count >= MaxLines) - { - _instructions.RemoveRange(0, _instructions.Count - MaxLines); - } - TraceView.RowCount = _instructions.Count; - } - private void SetTracerBoxTitle() { if (LoggingEnabled.Checked) diff --git a/src/BizHawk.Client.EmuHawk/tools/VirtualPads/controls/VirtualPadAnalogButton.cs b/src/BizHawk.Client.EmuHawk/tools/VirtualPads/controls/VirtualPadAnalogButton.cs index 6164de0acc2..1b20af38109 100644 --- a/src/BizHawk.Client.EmuHawk/tools/VirtualPads/controls/VirtualPadAnalogButton.cs +++ b/src/BizHawk.Client.EmuHawk/tools/VirtualPads/controls/VirtualPadAnalogButton.cs @@ -154,7 +154,7 @@ private void AnalogTrackBar_ValueChanged(object sender, EventArgs e) private void RefreshWidgets() { - if (!_isSet) + if (!IsSet) { _programmaticallyChangingValue = true; AnalogTrackBar.Value = _stickyHoldController.AxisValue(Name); diff --git a/src/BizHawk.Emulation.Common/filetype_detectors/SatellaviewFileTypeDetector.cs b/src/BizHawk.Emulation.Common/filetype_detectors/SatellaviewFileTypeDetector.cs index 1f3a1a2f48a..062d432419b 100644 --- a/src/BizHawk.Emulation.Common/filetype_detectors/SatellaviewFileTypeDetector.cs +++ b/src/BizHawk.Emulation.Common/filetype_detectors/SatellaviewFileTypeDetector.cs @@ -26,11 +26,13 @@ public readonly ref struct SatellaviewHeader private const byte LIMITED_5_PLAYS_LEFT = 0b11111100; +#pragma warning disable IDE0051 // Remove unused private members private const int OFFSET_BROADCAST_DATE = 0x26; // 2 octets private const int OFFSET_CHECKSUM = 0x2C; // 2 octets private const int OFFSET_CHECKSUM_COMPLEMENT = 0x2E; // 2 octets +#pragma warning restore IDE0051 // Remove unused private members private const int OFFSET_CONTENT_TYPE = 0x29; // 1 octet diff --git a/src/BizHawk.Emulation.Cores/CPUs/CP1610/.editorconfig b/src/BizHawk.Emulation.Cores/CPUs/CP1610/.editorconfig new file mode 100644 index 00000000000..902cc6122a8 --- /dev/null +++ b/src/BizHawk.Emulation.Cores/CPUs/CP1610/.editorconfig @@ -0,0 +1,7 @@ +# This core has existing violations, but let's assume they are in the middle of a refactor and let them be. +[*.cs] + +# Remove unused private member +dotnet_diagnostic.IDE0051.severity = suggestion +# Remove unread private member +dotnet_diagnostic.IDE0052.severity = suggestion diff --git a/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.Execute.cs b/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.Execute.cs index 12421fa1284..b449adcd57a 100644 --- a/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.Execute.cs +++ b/src/BizHawk.Emulation.Cores/CPUs/FairchildF8/F3850.Execute.cs @@ -1,6 +1,4 @@ -using System.Text; - -namespace BizHawk.Emulation.Cores.Components.FairchildF8 +namespace BizHawk.Emulation.Cores.Components.FairchildF8 { public sealed partial class F3850 { @@ -14,10 +12,11 @@ public sealed partial class F3850 public byte opcode; public long[] dLog = new long[0xFF]; +#if false private string debug = ""; private void UpdateDebug() { - StringBuilder sb = new StringBuilder(); + System.Text.StringBuilder sb = new(); for (int i = 0; i < 255; i++) { if (dLog[i] > 0) @@ -28,6 +27,7 @@ private void UpdateDebug() debug = sb.ToString(); } +#endif public void FetchInstruction() { diff --git a/src/BizHawk.Emulation.Cores/CPUs/HuC6280/HuC6280.cs b/src/BizHawk.Emulation.Cores/CPUs/HuC6280/HuC6280.cs index b5c19378e64..b5d2d896bb2 100644 --- a/src/BizHawk.Emulation.Cores/CPUs/HuC6280/HuC6280.cs +++ b/src/BizHawk.Emulation.Cores/CPUs/HuC6280/HuC6280.cs @@ -197,7 +197,9 @@ public void SetCpuRegister(string register, int value) // ==== Interrupts ==== private const ushort ResetVector = 0xFFFE; +#pragma warning disable IDE0051 // Remove unused private members private const ushort NMIVector = 0xFFFC; +#pragma warning restore IDE0051 // Remove unused private members private const ushort TimerVector = 0xFFFA; private const ushort IRQ1Vector = 0xFFF8; private const ushort IRQ2Vector = 0xFFF6; @@ -363,7 +365,9 @@ private ushort ReadWord(ushort address) return (ushort)((h << 8) | l); } +#pragma warning disable IDE0051 // Remove unused private members private void WriteWord(ushort address, ushort value) +#pragma warning restore IDE0051 // Remove unused private members { byte l = (byte)(value & 0xFF); byte h = (byte)(value >> 8); diff --git a/src/BizHawk.Emulation.Cores/CPUs/MC6800/Indexed_Modes.cs b/src/BizHawk.Emulation.Cores/CPUs/MC6800/Indexed_Modes.cs index 91892ef5f53..65ebb1ef69f 100644 --- a/src/BizHawk.Emulation.Cores/CPUs/MC6800/Indexed_Modes.cs +++ b/src/BizHawk.Emulation.Cores/CPUs/MC6800/Indexed_Modes.cs @@ -34,6 +34,8 @@ public partial class MC6800 public ushort indexed_reg; public ushort indexed_op_reg; +#pragma warning disable IDE0051 // Remove unused private members + private void INDEX_OP(ushort oper) { indexed_op = oper; diff --git a/src/BizHawk.Emulation.Cores/CPUs/MC6800/OP_Tables.cs b/src/BizHawk.Emulation.Cores/CPUs/MC6800/OP_Tables.cs index 660396419c6..1c1701cacf7 100644 --- a/src/BizHawk.Emulation.Cores/CPUs/MC6800/OP_Tables.cs +++ b/src/BizHawk.Emulation.Cores/CPUs/MC6800/OP_Tables.cs @@ -36,7 +36,9 @@ private void REG_OP_16(ushort oper, ushort src) IRQS = 3; } +#pragma warning disable IDE0051 // Remove unused private members private void DIRECT_MEM(ushort oper) +#pragma warning restore IDE0051 // Remove unused private members { PopulateCURINSTR(RD_INC, ALU, PC, SET_ADDR, ADDR, DP, ALU, diff --git a/src/BizHawk.Emulation.Cores/CPUs/MOS 6502X/.editorconfig b/src/BizHawk.Emulation.Cores/CPUs/MOS 6502X/.editorconfig new file mode 100644 index 00000000000..902cc6122a8 --- /dev/null +++ b/src/BizHawk.Emulation.Cores/CPUs/MOS 6502X/.editorconfig @@ -0,0 +1,7 @@ +# This core has existing violations, but let's assume they are in the middle of a refactor and let them be. +[*.cs] + +# Remove unused private member +dotnet_diagnostic.IDE0051.severity = suggestion +# Remove unread private member +dotnet_diagnostic.IDE0052.severity = suggestion diff --git a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/.editorconfig b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/.editorconfig index 259a0557971..b1494491628 100644 --- a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/.editorconfig +++ b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/.editorconfig @@ -1,5 +1,11 @@ [*.cs] +# Remove unused private member +dotnet_diagnostic.IDE0051.severity = suggestion + +# Remove unread private member +dotnet_diagnostic.IDE0052.severity = suggestion + # The value returned by Stream.Read/Stream.ReadAsync is not used dotnet_diagnostic.MA0060.severity = suggestion diff --git a/src/BizHawk.Emulation.Cores/Computers/Commodore64/.editorconfig b/src/BizHawk.Emulation.Cores/Computers/Commodore64/.editorconfig index 055ef71bcec..5e95141314e 100644 --- a/src/BizHawk.Emulation.Cores/Computers/Commodore64/.editorconfig +++ b/src/BizHawk.Emulation.Cores/Computers/Commodore64/.editorconfig @@ -1,5 +1,11 @@ [*.cs] +# Remove unused private member +dotnet_diagnostic.IDE0051.severity = suggestion + +# Remove unread private member +dotnet_diagnostic.IDE0052.severity = suggestion + # Add paragraph to documentation comment dotnet_diagnostic.RCS1226.severity = suggestion diff --git a/src/BizHawk.Emulation.Cores/Computers/MSX/.editorconfig b/src/BizHawk.Emulation.Cores/Computers/MSX/.editorconfig index d865d618260..476fd30bd54 100644 --- a/src/BizHawk.Emulation.Cores/Computers/MSX/.editorconfig +++ b/src/BizHawk.Emulation.Cores/Computers/MSX/.editorconfig @@ -3,5 +3,11 @@ # Do not ignore method results dotnet_diagnostic.CA1806.severity = suggestion +# Remove unused private member +dotnet_diagnostic.IDE0051.severity = suggestion + +# Remove unread private member +dotnet_diagnostic.IDE0052.severity = suggestion + # Use trailing comma in multi-line initializers dotnet_diagnostic.SA1413.severity = suggestion diff --git a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/.editorconfig b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/.editorconfig index e90c3fe0758..3261586d481 100644 --- a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/.editorconfig +++ b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/.editorconfig @@ -1,5 +1,11 @@ [*.cs] +# Remove unused private member +dotnet_diagnostic.IDE0051.severity = suggestion + +# Remove unread private member +dotnet_diagnostic.IDE0052.severity = suggestion + # The value returned by Stream.Read/Stream.ReadAsync is not used dotnet_diagnostic.MA0060.severity = suggestion diff --git a/src/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/.editorconfig b/src/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/.editorconfig index 19a92085ce9..9add0d13af6 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/.editorconfig +++ b/src/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/.editorconfig @@ -3,6 +3,12 @@ # Do not ignore method results dotnet_diagnostic.CA1806.severity = suggestion +# Remove unused private member +dotnet_diagnostic.IDE0051.severity = suggestion + +# Remove unread private member +dotnet_diagnostic.IDE0052.severity = suggestion + # Both if and else branch have identical code dotnet_diagnostic.MA0140.severity = suggestion diff --git a/src/BizHawk.Emulation.Cores/Consoles/Coleco/.editorconfig b/src/BizHawk.Emulation.Cores/Consoles/Coleco/.editorconfig index 91c83b474af..f96be77dc1a 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Coleco/.editorconfig +++ b/src/BizHawk.Emulation.Cores/Consoles/Coleco/.editorconfig @@ -1,4 +1,10 @@ [*.cs] +# Remove unused private member +dotnet_diagnostic.IDE0051.severity = suggestion + +# Remove unread private member +dotnet_diagnostic.IDE0052.severity = suggestion + # Use trailing comma in multi-line initializers dotnet_diagnostic.SA1413.severity = suggestion diff --git a/src/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/VectrexHawk.ICodeDataLog.cs b/src/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/VectrexHawk.ICodeDataLog.cs index ed8ae4f81a0..e8dbca58569 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/VectrexHawk.ICodeDataLog.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/VectrexHawk.ICodeDataLog.cs @@ -65,6 +65,7 @@ private void RunCDL(ushort address, CDLog_Flags flags) } } +#pragma warning disable IDE0051 // Remove unused private members /// /// A wrapper for FetchMemory which inserts CDL logic /// @@ -82,5 +83,6 @@ private byte ReadMemory_CDL(ushort address) RunCDL(address, CDLog_Flags.Data); return ReadMemory(address); } +#pragma warning restore IDE0051 // Remove unused private members } } \ No newline at end of file diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/.editorconfig b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/.editorconfig index 9c0be83ffad..7fef44fd026 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/.editorconfig +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/.editorconfig @@ -1,5 +1,11 @@ [*.cs] +# Remove unused private member +dotnet_diagnostic.IDE0051.severity = suggestion + +# Remove unread private member +dotnet_diagnostic.IDE0052.severity = suggestion + # Remove empty else/finally block dotnet_diagnostic.MA0090.severity = suggestion diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink/GBHawkLink.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink/GBHawkLink.cs index fd77e0ba821..7da1f3a8a3e 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink/GBHawkLink.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawkLink/GBHawkLink.cs @@ -100,7 +100,9 @@ public bool LinkConnected set => _cableconnected = value; } +#pragma warning disable IDE0051 // Remove unused private members private void ExecFetch(ushort addr) +#pragma warning restore IDE0051 // Remove unused private members { uint flags = (uint)(MemoryCallbackFlags.AccessExecute); MemoryCallbacks.CallMemoryCallbacks(addr, 0, flags, "System Bus"); diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/.editorconfig b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/.editorconfig index 5c9939940f5..988a6366ad0 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/.editorconfig +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/.editorconfig @@ -3,6 +3,12 @@ # Do not ignore method results dotnet_diagnostic.CA1806.severity = suggestion +# Remove unused private member +dotnet_diagnostic.IDE0051.severity = suggestion + +# Remove unread private member +dotnet_diagnostic.IDE0052.severity = suggestion + # Do not use default value type constructor dotnet_diagnostic.SA1129.severity = suggestion diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/.editorconfig b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/.editorconfig index 7a8de96128e..f2a5b969a95 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/.editorconfig +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/.editorconfig @@ -1,5 +1,11 @@ [*.cs] +# Remove unused private member +dotnet_diagnostic.IDE0051.severity = suggestion + +# Remove unread private member +dotnet_diagnostic.IDE0052.severity = suggestion + # The value returned by Stream.Read/Stream.ReadAsync is not used dotnet_diagnostic.MA0060.severity = suggestion diff --git a/src/BizHawk.Emulation.Cores/Consoles/PC Engine/ScsiCDBus.cs b/src/BizHawk.Emulation.Cores/Consoles/PC Engine/ScsiCDBus.cs index 69a64cbbffc..5802b15fdfb 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/PC Engine/ScsiCDBus.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/PC Engine/ScsiCDBus.cs @@ -10,6 +10,7 @@ namespace BizHawk.Emulation.Cores.PCEngine // which incidentally would allow us to put it back to an int from a long if we wanted to public sealed class ScsiCDBus { +#pragma warning disable IDE0051 // Remove unused private members private const int STATUS_GOOD = 0; private const int STATUS_CHECK_CONDITION = 1; private const int STATUS_CONDITION_MET = 2; @@ -24,6 +25,7 @@ public sealed class ScsiCDBus private const int SCSI_PAUSE = 0xDA; private const int SCSI_READ_SUBCODE_Q = 0xDD; private const int SCSI_READ_TOC = 0xDE; +#pragma warning restore IDE0051 // Remove unused private members private bool bsy, sel, cd, io, msg, req, ack, atn, rst; private bool signalsChanged; diff --git a/src/BizHawk.Emulation.Cores/Consoles/Sega/GGHawkLink/GGHawkLink.cs b/src/BizHawk.Emulation.Cores/Consoles/Sega/GGHawkLink/GGHawkLink.cs index 2ca77759c64..9c66a8af653 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Sega/GGHawkLink/GGHawkLink.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Sega/GGHawkLink/GGHawkLink.cs @@ -83,7 +83,9 @@ public bool LinkConnected set => _cableconnected = value; } +#pragma warning disable IDE0051 // Remove unused private members private void ExecFetch(ushort addr) +#pragma warning restore IDE0051 // Remove unused private members { uint flags = (uint)MemoryCallbackFlags.AccessExecute; MemoryCallbacks.CallMemoryCallbacks(addr, 0, flags, "System Bus"); diff --git a/src/BizHawk.Emulation.Cores/Consoles/Sega/SMS/MemoryMap.Korea.cs b/src/BizHawk.Emulation.Cores/Consoles/Sega/SMS/MemoryMap.Korea.cs index af437475938..c86ea437d50 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Sega/SMS/MemoryMap.Korea.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Sega/SMS/MemoryMap.Korea.cs @@ -78,7 +78,9 @@ private byte ReadMemoryMSX(ushort address) return SystemRam[address & RamSizeMask]; } +#pragma warning disable IDE0051 // Remove unused private members private CDLog_MapResults MapMemoryMSX(ushort address, bool write) +#pragma warning restore IDE0051 // Remove unused private members { if (address < 0x4000) return new CDLog_MapResults { Type = CDLog_AddrType.ROM, Address = address & 0x3FFF }; if (address < 0x6000) return new CDLog_MapResults { Type = CDLog_AddrType.ROM, Address = (RomBank0 * 0x2000) + (address & 0x1FFF) }; diff --git a/src/BizHawk.Emulation.Cores/Consoles/Sega/SMS/TerebiOekaki.cs b/src/BizHawk.Emulation.Cores/Consoles/Sega/SMS/TerebiOekaki.cs index 0b2ac4e13da..43e70e65c36 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Sega/SMS/TerebiOekaki.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Sega/SMS/TerebiOekaki.cs @@ -4,6 +4,7 @@ public partial class SMS { //This doesn't look functional. Illogical and nothing like http://www.smspower.org/Articles/TerebiOekaki +#pragma warning disable IDE0052 // Remove unread private members private byte xCoord = 128; private byte yCoord = 100; @@ -14,6 +15,7 @@ private enum Axis } private Axis axis = Axis.XAxis; +#pragma warning restore IDE0052 // Remove unread private members private byte ReadMemoryTO(ushort address) diff --git a/src/BizHawk.Emulation.Cores/Sound/OneBitBeeper.cs b/src/BizHawk.Emulation.Cores/Sound/OneBitBeeper.cs index 7554efe6d45..ed375b499c0 100644 --- a/src/BizHawk.Emulation.Cores/Sound/OneBitBeeper.cs +++ b/src/BizHawk.Emulation.Cores/Sound/OneBitBeeper.cs @@ -100,7 +100,9 @@ public int Volume /// /// The last used volume (used to modify blipbuffer delta values) /// +#pragma warning disable IDE0052 // Remove unread private members private int lastVolume; +#pragma warning restore IDE0052 // Remove unread private members /// diff --git a/src/BizHawk.Emulation.Cores/Sound/YM2413.cs b/src/BizHawk.Emulation.Cores/Sound/YM2413.cs index c3c2f569081..deac30e131c 100644 --- a/src/BizHawk.Emulation.Cores/Sound/YM2413.cs +++ b/src/BizHawk.Emulation.Cores/Sound/YM2413.cs @@ -7,6 +7,8 @@ using BizHawk.Common; +#pragma warning disable IDE0051 // Remove unused private members (Lots of private methods here with logic. Are they needed?) + namespace BizHawk.Emulation.Cores.Components { public sealed class YM2413 diff --git a/src/BizHawk.Emulation.Cores/vpads_schemata/SmsSchema.cs b/src/BizHawk.Emulation.Cores/vpads_schemata/SmsSchema.cs index a1624509afb..5a74d0ed6a2 100644 --- a/src/BizHawk.Emulation.Cores/vpads_schemata/SmsSchema.cs +++ b/src/BizHawk.Emulation.Cores/vpads_schemata/SmsSchema.cs @@ -62,10 +62,12 @@ public class SG1000Schema : SMSSchema { } // are these really the same controlle [Schema(VSystemID.Raw.SMS)] public class SMSSchema : IVirtualPadSchema { +#pragma warning disable IDE0051 // Remove unused private members private static string StandardControllerName => typeof(SmsController).DisplayName(); private static string PaddleControllerName => typeof(SMSPaddleController).DisplayName(); private static string SportControllerName => typeof(SMSSportsPadController).DisplayName(); private static string LightGunControllerName => typeof(SMSLightPhaserController).DisplayName(); +#pragma warning restore IDE0051 // Remove unused private members public IEnumerable GetPadSchemas(IEmulator core, Action showMessageBox) { diff --git a/src/BizHawk.Emulation.Cores/vpads_schemata/ZXSpectrumSchema.cs b/src/BizHawk.Emulation.Cores/vpads_schemata/ZXSpectrumSchema.cs index 9cf3ac85d44..7e89ea288ab 100644 --- a/src/BizHawk.Emulation.Cores/vpads_schemata/ZXSpectrumSchema.cs +++ b/src/BizHawk.Emulation.Cores/vpads_schemata/ZXSpectrumSchema.cs @@ -166,7 +166,9 @@ private static PadSchema Keyboard() return ps; } +#pragma warning disable IDE0051 // Remove unused private members private static PadSchema TapeDevice() +#pragma warning restore IDE0051 // Remove unused private members { return new PadSchema { diff --git a/src/BizHawk.Emulation.DiscSystem/DiscFormats/Blobs/Blob_ECM.cs b/src/BizHawk.Emulation.DiscSystem/DiscFormats/Blobs/Blob_ECM.cs index 6ea74629c8f..a2bc98d9835 100644 --- a/src/BizHawk.Emulation.DiscSystem/DiscFormats/Blobs/Blob_ECM.cs +++ b/src/BizHawk.Emulation.DiscSystem/DiscFormats/Blobs/Blob_ECM.cs @@ -47,10 +47,12 @@ public IndexEntry(int type, uint number, long ecmOffset, long logicalOffset) /// private readonly List Index = new(); +#if false /// /// the ECMfile-provided EDC integrity checksum. not being used right now /// private int EDC; +#endif public long Length; @@ -118,7 +120,7 @@ public void Load(string path) //TODO - endian bug. need an endian-independent binary reader with good license (miscutils is apache license) //extension methods on binary reader wont suffice, we need something that lets you control the endianness used for reading. a complete replacement. var br = new BinaryReader(stream); - EDC = br.ReadInt32(); + /*EDC*/_ = br.ReadInt32(); Length = logOffset; } diff --git a/src/BizHawk.Emulation.DiscSystem/DiscStream.cs b/src/BizHawk.Emulation.DiscSystem/DiscStream.cs index 71d0389ebe5..7e9719c2134 100644 --- a/src/BizHawk.Emulation.DiscSystem/DiscStream.cs +++ b/src/BizHawk.Emulation.DiscSystem/DiscStream.cs @@ -53,7 +53,6 @@ public class DiscStream : System.IO.Stream { private readonly int SectorSize; private readonly int NumSectors; - private Disc Disc; private long currPosition; private readonly byte[] cachedSectorBuffer; @@ -64,7 +63,6 @@ public class DiscStream : System.IO.Stream public DiscStream(Disc disc, EDiscStreamView view, int from_lba) { SectorSize = 2048; - Disc = disc; NumSectors = disc.Session1.LeadoutLBA; dsr = new(disc); diff --git a/src/BizHawk.Emulation.DiscSystem/DiscUtils.cs b/src/BizHawk.Emulation.DiscSystem/DiscUtils.cs index 456aad4fd40..84d3fcbbd35 100644 --- a/src/BizHawk.Emulation.DiscSystem/DiscUtils.cs +++ b/src/BizHawk.Emulation.DiscSystem/DiscUtils.cs @@ -2,22 +2,6 @@ namespace BizHawk.Emulation.DiscSystem { public static class DiscUtils { - private static byte IntToBCD(int n) - { - var tens = Math.DivRem(n, 10, out var ones); - return (byte)((tens << 4) | ones); - } - - /// - /// converts the given int to a BCD value - /// - public static int BCD_Byte(this int val) - { - var ret = (byte)(val % 10); - ret += (byte)(16 * (val / 10)); - return ret; - } - /// /// converts an LBA to AMSF absolute minute:second:frame format. /// From d210981b83875284e39083007f127d1c59391d6d Mon Sep 17 00:00:00 2001 From: SuuperW Date: Wed, 9 Jul 2025 01:42:51 -0500 Subject: [PATCH 4/8] Convert RestoreDefaultsAttribute usage to an interface because runtime reflection is evil. --- .../config/IRestoreDefaults.cs | 10 ++++++++++ .../config/RestoreDefaultsAttribute.cs | 1 + src/BizHawk.Client.EmuHawk/tools/Cheats/Cheats.cs | 5 ++--- src/BizHawk.Client.EmuHawk/tools/Lua/LuaConsole.cs | 5 ++--- .../tools/TAStudio/TAStudio.MenuItems.cs | 6 ++---- src/BizHawk.Client.EmuHawk/tools/ToolManager.cs | 13 +++++++++++-- src/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs | 5 ++--- src/BizHawk.Client.EmuHawk/tools/Watch/RamWatch.cs | 5 ++--- 8 files changed, 32 insertions(+), 18 deletions(-) create mode 100644 src/BizHawk.Client.Common/config/IRestoreDefaults.cs diff --git a/src/BizHawk.Client.Common/config/IRestoreDefaults.cs b/src/BizHawk.Client.Common/config/IRestoreDefaults.cs new file mode 100644 index 00000000000..39e1a49532a --- /dev/null +++ b/src/BizHawk.Client.Common/config/IRestoreDefaults.cs @@ -0,0 +1,10 @@ +namespace BizHawk.Client.Common +{ + /// + /// When the implementing class also implements , this interface's method is called when the generated Restore Defaults menu item is clicked. + /// + public interface IRestoreDefaults + { + void RestoreDefaults(); + } +} diff --git a/src/BizHawk.Client.Common/config/RestoreDefaultsAttribute.cs b/src/BizHawk.Client.Common/config/RestoreDefaultsAttribute.cs index c891c6fc556..e758ae144a3 100644 --- a/src/BizHawk.Client.Common/config/RestoreDefaultsAttribute.cs +++ b/src/BizHawk.Client.Common/config/RestoreDefaultsAttribute.cs @@ -3,6 +3,7 @@ namespace BizHawk.Client.Common /// Indicates which method of an is to be called when the generated Restore Defaults menu item is clicked. /// If not present on any instance method, the menu item will do nothing. If present on multiple, the first will be called. [AttributeUsage(AttributeTargets.Method)] + [Obsolete("Use interface IRestoreDefaults instead.")] public sealed class RestoreDefaultsAttribute : Attribute { } diff --git a/src/BizHawk.Client.EmuHawk/tools/Cheats/Cheats.cs b/src/BizHawk.Client.EmuHawk/tools/Cheats/Cheats.cs index 3c8447ea799..fbcf7ea7558 100644 --- a/src/BizHawk.Client.EmuHawk/tools/Cheats/Cheats.cs +++ b/src/BizHawk.Client.EmuHawk/tools/Cheats/Cheats.cs @@ -13,7 +13,7 @@ namespace BizHawk.Client.EmuHawk { - public partial class Cheats : ToolFormBase, IToolFormAutoConfig + public partial class Cheats : ToolFormBase, IToolFormAutoConfig, IRestoreDefaults { private const string NameColumn = "NamesColumn"; private const string AddressColumn = "AddressColumn"; @@ -513,8 +513,7 @@ private void AutoSaveCheatsMenuItem_Click(object sender, EventArgs e) private void CheatsOnOffLoadMenuItem_Click(object sender, EventArgs e) => Config.Cheats.DisableOnLoad = !Config.Cheats.DisableOnLoad; - [RestoreDefaults] - private void RestoreDefaults() + void IRestoreDefaults.RestoreDefaults() { Settings = new CheatsSettings(); diff --git a/src/BizHawk.Client.EmuHawk/tools/Lua/LuaConsole.cs b/src/BizHawk.Client.EmuHawk/tools/Lua/LuaConsole.cs index 25892fd6061..222b27b74a6 100644 --- a/src/BizHawk.Client.EmuHawk/tools/Lua/LuaConsole.cs +++ b/src/BizHawk.Client.EmuHawk/tools/Lua/LuaConsole.cs @@ -18,7 +18,7 @@ namespace BizHawk.Client.EmuHawk { - public partial class LuaConsole : ToolFormBase, IToolFormAutoConfig + public partial class LuaConsole : ToolFormBase, IToolFormAutoConfig, IRestoreDefaults { private const string IconColumnName = "Icon"; private const string ScriptColumnName = "Script"; @@ -1532,8 +1532,7 @@ private void RefreshLuaScript(LuaFile file) ToggleLuaScript(file); } - [RestoreDefaults] - private void RestoreDefaults() + void IRestoreDefaults.RestoreDefaults() { Settings = new LuaConsoleSettings(); LuaListView.AllColumns.Clear(); diff --git a/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.MenuItems.cs b/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.MenuItems.cs index 2e78e58b4a0..ec692a6858b 100644 --- a/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.MenuItems.cs +++ b/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.MenuItems.cs @@ -12,7 +12,7 @@ namespace BizHawk.Client.EmuHawk { - public partial class TAStudio + public partial class TAStudio : IRestoreDefaults { private static readonly FilesystemFilterSet MoviesFSFilterSet = new( new FilesystemFilter("All Available Files", MovieService.MovieExtensions.Reverse().ToArray()), @@ -1255,9 +1255,7 @@ void UpdateAggregateCheckState() }); } - // ReSharper disable once UnusedMember.Local - [RestoreDefaults] - private void RestoreDefaults() + void IRestoreDefaults.RestoreDefaults() { SetUpColumns(); SetUpToolStripColumns(); diff --git a/src/BizHawk.Client.EmuHawk/tools/ToolManager.cs b/src/BizHawk.Client.EmuHawk/tools/ToolManager.cs index bec31d413cb..6751b224f6e 100644 --- a/src/BizHawk.Client.EmuHawk/tools/ToolManager.cs +++ b/src/BizHawk.Client.EmuHawk/tools/ToolManager.cs @@ -378,8 +378,17 @@ private void AttachSettingHooks(IToolFormAutoConfig tool, ToolDialogSettings set RefreshSettings(form, dest, settings, idx); form.Size = oldSize; - form.GetType().GetMethodsWithAttrib(typeof(RestoreDefaultsAttribute)) - .FirstOrDefault()?.Invoke(form, Array.Empty()); + if (form is IRestoreDefaults restorable) + { + restorable.RestoreDefaults(); + } + else if (form is IExternalToolForm) + { +#pragma warning disable CS0618 // We temporarily keep this use of obsolete attribute so external tools don't immediately break. + form.GetType().GetMethodsWithAttrib(typeof(RestoreDefaultsAttribute)) + .FirstOrDefault()?.Invoke(form, Array.Empty()); +#pragma warning restore CS0618 + } }; } diff --git a/src/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs b/src/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs index a7371f5716f..4c5da8ea25c 100644 --- a/src/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs +++ b/src/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs @@ -20,7 +20,7 @@ namespace BizHawk.Client.EmuHawk /// /// A form designed to search through ram values /// - public partial class RamSearch : ToolFormBase, IToolFormAutoConfig + public partial class RamSearch : ToolFormBase, IToolFormAutoConfig, IRestoreDefaults { private const int MaxDetailedSize = 1024 * 1024; // 1mb, semi-arbitrary decision, sets the size to check for and automatically switch to fast mode for the user private const int MaxSupportedSize = 1024 * 1024 * 64; // 64mb, semi-arbitrary decision, sets the maximum size RAM Search will support (as it will crash beyond this) @@ -1325,8 +1325,7 @@ private void UseUndoHistoryMenuItem_Click(object sender, EventArgs e) Settings.UseUndoHistory = _searches.UndoEnabled; } - [RestoreDefaults] - private void RestoreDefaultsMenuItem() + void IRestoreDefaults.RestoreDefaults() { var recentFiles = Settings.RecentSearches; // We don't want to wipe recent files when restoring diff --git a/src/BizHawk.Client.EmuHawk/tools/Watch/RamWatch.cs b/src/BizHawk.Client.EmuHawk/tools/Watch/RamWatch.cs index e54bf3a62ff..796bb332b1f 100644 --- a/src/BizHawk.Client.EmuHawk/tools/Watch/RamWatch.cs +++ b/src/BizHawk.Client.EmuHawk/tools/Watch/RamWatch.cs @@ -17,7 +17,7 @@ namespace BizHawk.Client.EmuHawk { - public partial class RamWatch : ToolFormBase, IToolFormAutoConfig + public partial class RamWatch : ToolFormBase, IToolFormAutoConfig, IRestoreDefaults { public static Icon ToolIcon => Resources.WatchIcon; @@ -1062,8 +1062,7 @@ private void DoubleClickToPokeMenuItem_Click(object sender, EventArgs e) Settings.DoubleClickToPoke = true; } - [RestoreDefaults] - private void RestoreDefaultsMenuItem() + void IRestoreDefaults.RestoreDefaults() { Settings = new RamWatchSettings(); From c77b3dcccdc2129441917410df5d5492194155e6 Mon Sep 17 00:00:00 2001 From: SuuperW Date: Thu, 31 Jul 2025 00:51:20 -0500 Subject: [PATCH 5/8] Reduce reliance on reflection for config persisting. This fixes the last violations of IDE0051 and IDE0052. --- .../config/ConfigPersistAttribute.cs | 1 + .../config/IConfigPersist.cs | 56 +++++++++++++++++ .../CoreFeatureAnalysis.cs | 18 +++++- .../tools/BasicBot/BasicBot.cs | 17 ++++- src/BizHawk.Client.EmuHawk/tools/CDL.cs | 31 ++++++--- .../tools/Cheats/Cheats.cs | 17 ++++- .../tools/GB/GBGPUView.cs | 17 ++++- .../tools/HexEditor/HexEditor.cs | 37 +++++++---- .../tools/Lua/LuaConsole.cs | 17 ++++- .../tools/NES/NESNameTableViewer.cs | 17 ++++- .../tools/NES/NESPPU.cs | 21 ++++++- .../tools/PCE/PCEBGViewer.cs | 18 +++++- .../tools/SNES/SNESGraphicsDebugger.cs | 20 +++++- .../tools/TAStudio/TAStudio.cs | 22 +++++-- .../tools/TI83/TI83KeyPad.cs | 20 +++++- .../tools/ToolManager.cs | 63 ++----------------- .../tools/TraceLogger.cs | 27 ++++++-- .../tools/VirtualPads/VirtualpadsTool.cs | 23 +++++-- .../tools/Watch/RamSearch.cs | 17 ++++- .../tools/Watch/RamWatch.cs | 17 ++++- 20 files changed, 350 insertions(+), 126 deletions(-) create mode 100644 src/BizHawk.Client.Common/config/IConfigPersist.cs diff --git a/src/BizHawk.Client.Common/config/ConfigPersistAttribute.cs b/src/BizHawk.Client.Common/config/ConfigPersistAttribute.cs index 03839199183..7ffc42495a7 100644 --- a/src/BizHawk.Client.Common/config/ConfigPersistAttribute.cs +++ b/src/BizHawk.Client.Common/config/ConfigPersistAttribute.cs @@ -2,6 +2,7 @@ namespace BizHawk.Client.Common { /// Indicates that a property is to be saved to config for persistence. [AttributeUsage(AttributeTargets.Property)] + [Obsolete("Use interface IConfigPersist instead.")] public sealed class ConfigPersistAttribute : Attribute { } diff --git a/src/BizHawk.Client.Common/config/IConfigPersist.cs b/src/BizHawk.Client.Common/config/IConfigPersist.cs new file mode 100644 index 00000000000..2e0098a8c9f --- /dev/null +++ b/src/BizHawk.Client.Common/config/IConfigPersist.cs @@ -0,0 +1,56 @@ +using System.Collections.Generic; +using System.ComponentModel; +using System.Globalization; + +namespace BizHawk.Client.Common +{ + public interface IConfigPersist + { + public class Provider + { + private Dictionary _data; + + public Provider(Dictionary data) + { + _data = data; + } + + public bool Get(string name, ref T value) + { + if (_data.TryGetValue(name, out var val)) + { + if (val is string str && typeof(T) != typeof(string)) + { + // if a type has a TypeConverter, and that converter can convert to string, + // that will be used in place of object markup by JSON.NET + + // but that doesn't work with $type metadata, and JSON.NET fails to fall + // back on regular object serialization when needed. so try to undo a TypeConverter + // operation here + var converter = TypeDescriptor.GetConverter(typeof(T)); + val = converter.ConvertFromString(null, CultureInfo.InvariantCulture, str); + } + else if (val is not bool && typeof(T).IsPrimitive) + { + // numeric constants are similarly hosed + val = Convert.ChangeType(val, typeof(T), CultureInfo.InvariantCulture); + } + + value = (T)val; + return true; + } + return false; + } + } + + /// + /// Load the provided configuration. + /// + void LoadConfig(Provider provider); + + /// + /// Return a dictionary representing the current configuration. + /// + Dictionary SaveConfig(); + } +} diff --git a/src/BizHawk.Client.EmuHawk/CoreFeatureAnalysis.cs b/src/BizHawk.Client.EmuHawk/CoreFeatureAnalysis.cs index 37f6120a426..5f4a237bdde 100644 --- a/src/BizHawk.Client.EmuHawk/CoreFeatureAnalysis.cs +++ b/src/BizHawk.Client.EmuHawk/CoreFeatureAnalysis.cs @@ -11,7 +11,7 @@ namespace BizHawk.Client.EmuHawk { - public partial class CoreFeatureAnalysis : ToolFormBase, IToolFormAutoConfig + public partial class CoreFeatureAnalysis : ToolFormBase, IToolFormAutoConfig, IConfigPersist { private class CoreInfo { @@ -93,8 +93,20 @@ public FunctionInfo(MethodInfo m, object service) public static Icon ToolIcon => Properties.Resources.Logo; - [ConfigPersist] - private Dictionary KnownCores { get; set; } + private Dictionary KnownCores; + + void IConfigPersist.LoadConfig(IConfigPersist.Provider provider) + { + provider.Get(nameof(KnownCores), ref KnownCores); + } + + Dictionary IConfigPersist.SaveConfig() + { + return new() + { + [nameof(KnownCores)] = KnownCores, + }; + } // ReSharper disable once UnusedAutoPropertyAccessor.Local [RequiredService] diff --git a/src/BizHawk.Client.EmuHawk/tools/BasicBot/BasicBot.cs b/src/BizHawk.Client.EmuHawk/tools/BasicBot/BasicBot.cs index 5bf3d3155ce..4bd216d4220 100644 --- a/src/BizHawk.Client.EmuHawk/tools/BasicBot/BasicBot.cs +++ b/src/BizHawk.Client.EmuHawk/tools/BasicBot/BasicBot.cs @@ -13,7 +13,7 @@ namespace BizHawk.Client.EmuHawk { - public sealed partial class BasicBot : ToolFormBase, IToolFormAutoConfig + public sealed partial class BasicBot : ToolFormBase, IToolFormAutoConfig, IConfigPersist { private static readonly FilesystemFilterSet BotFilesFSFilterSet = new(new FilesystemFilter("Bot files", new[] { "bot" })); @@ -69,8 +69,19 @@ private string CurrentFileName [RequiredService] private IMemoryDomains MemoryDomains { get; set; } - [ConfigPersist] - public BasicBotSettings Settings { get; set; } + private BasicBotSettings Settings; + + void IConfigPersist.LoadConfig(IConfigPersist.Provider provider) + { + provider.Get(nameof(Settings), ref Settings); + } + Dictionary IConfigPersist.SaveConfig() + { + return new() + { + [nameof(Settings)] = Settings, + }; + } public class BasicBotSettings { diff --git a/src/BizHawk.Client.EmuHawk/tools/CDL.cs b/src/BizHawk.Client.EmuHawk/tools/CDL.cs index 5c12ce5572e..3c2cb505a4f 100644 --- a/src/BizHawk.Client.EmuHawk/tools/CDL.cs +++ b/src/BizHawk.Client.EmuHawk/tools/CDL.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Drawing; using System.IO; using System.Windows.Forms; @@ -17,7 +18,7 @@ // TODO - context menu should have copy option too namespace BizHawk.Client.EmuHawk { - public partial class CDL : ToolFormBase, IToolFormAutoConfig + public partial class CDL : ToolFormBase, IToolFormAutoConfig, IConfigPersist { private static readonly FilesystemFilterSet CDLFilesFSFilterSet = new(new FilesystemFilter("Code Data Logger Files", new[] { "cdl" })); @@ -26,21 +27,35 @@ public static Icon ToolIcon private RecentFiles _recentFld = new RecentFiles(); - [ConfigPersist] private RecentFiles _recent { get => _recentFld; set => _recentFld = value; } - [ConfigPersist] - private bool CDLAutoSave { get; set; } = true; + private bool CDLAutoSave = true; - [ConfigPersist] - private bool CDLAutoStart { get; set; } = true; + private bool CDLAutoStart = true; - [ConfigPersist] - private bool CDLAutoResume { get; set; } = true; + private bool CDLAutoResume = true; + + void IConfigPersist.LoadConfig(IConfigPersist.Provider provider) + { + provider.Get(nameof(_recentFld), ref _recentFld); + provider.Get(nameof(CDLAutoSave), ref CDLAutoSave); + provider.Get(nameof(CDLAutoStart), ref CDLAutoStart); + provider.Get(nameof(CDLAutoResume), ref CDLAutoResume); + } + Dictionary IConfigPersist.SaveConfig() + { + return new() + { + [nameof(_recent)] = _recent, + [nameof(CDLAutoSave)] = CDLAutoSave, + [nameof(CDLAutoStart)] = CDLAutoStart, + [nameof(CDLAutoResume)] = CDLAutoResume, + }; + } private void SetCurrentFilename(string fname) { diff --git a/src/BizHawk.Client.EmuHawk/tools/Cheats/Cheats.cs b/src/BizHawk.Client.EmuHawk/tools/Cheats/Cheats.cs index fbcf7ea7558..ed187cb5215 100644 --- a/src/BizHawk.Client.EmuHawk/tools/Cheats/Cheats.cs +++ b/src/BizHawk.Client.EmuHawk/tools/Cheats/Cheats.cs @@ -13,7 +13,7 @@ namespace BizHawk.Client.EmuHawk { - public partial class Cheats : ToolFormBase, IToolFormAutoConfig, IRestoreDefaults + public partial class Cheats : ToolFormBase, IToolFormAutoConfig, IRestoreDefaults, IConfigPersist { private const string NameColumn = "NamesColumn"; private const string AddressColumn = "AddressColumn"; @@ -78,8 +78,19 @@ public Cheats() [RequiredService] private IMemoryDomains Core { get; set; } - [ConfigPersist] - public CheatsSettings Settings { get; set; } + public CheatsSettings Settings; + + void IConfigPersist.LoadConfig(IConfigPersist.Provider provider) + { + provider.Get(nameof(Settings), ref Settings); + } + Dictionary IConfigPersist.SaveConfig() + { + return new() + { + [nameof(Settings)] = Settings, + }; + } public override void Restart() { diff --git a/src/BizHawk.Client.EmuHawk/tools/GB/GBGPUView.cs b/src/BizHawk.Client.EmuHawk/tools/GB/GBGPUView.cs index 03ecbb6b622..98e7c2c61a2 100644 --- a/src/BizHawk.Client.EmuHawk/tools/GB/GBGPUView.cs +++ b/src/BizHawk.Client.EmuHawk/tools/GB/GBGPUView.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.Text; @@ -10,7 +11,7 @@ namespace BizHawk.Client.EmuHawk { - public partial class GbGpuView : ToolFormBase, IToolFormAutoConfig + public partial class GbGpuView : ToolFormBase, IToolFormAutoConfig, IConfigPersist { public static Icon ToolIcon => Properties.Resources.GambatteIcon; @@ -58,7 +59,6 @@ private IntPtr ComputeTilesPalFromMemory(IGPUMemoryAreas m) private Color _spriteback; - [ConfigPersist] public Color Spriteback { get => _spriteback; @@ -70,6 +70,19 @@ public Color Spriteback } } + void IConfigPersist.LoadConfig(IConfigPersist.Provider provider) + { + Color outValue = default; + if (provider.Get(nameof(Spriteback), ref outValue)) Spriteback = outValue; + } + Dictionary IConfigPersist.SaveConfig() + { + return new() + { + [nameof(Spriteback)] = Spriteback, + }; + } + protected override string WindowTitleStatic => "GPU Viewer"; public GbGpuView() diff --git a/src/BizHawk.Client.EmuHawk/tools/HexEditor/HexEditor.cs b/src/BizHawk.Client.EmuHawk/tools/HexEditor/HexEditor.cs index 1e32aae52f6..508943bd684 100644 --- a/src/BizHawk.Client.EmuHawk/tools/HexEditor/HexEditor.cs +++ b/src/BizHawk.Client.EmuHawk/tools/HexEditor/HexEditor.cs @@ -20,7 +20,7 @@ namespace BizHawk.Client.EmuHawk { // int to long TODO: 32 bit domains have more digits than the hex editor can account for and the address covers up the 0 column - public partial class HexEditor : ToolFormBase, IToolFormAutoConfig + public partial class HexEditor : ToolFormBase, IToolFormAutoConfig, IConfigPersist { private sealed class N64MatrixDisplayDialog : Form { @@ -121,17 +121,13 @@ private bool AreAnyHighlighted private HexFind _hexFind; private string _lastRom = ""; - [ConfigPersist] - private string LastDomain { get; set; } + private string LastDomain; - [ConfigPersist] - private bool BigEndian { get; set; } + private bool BigEndian; - [ConfigPersist] - private int DataSize { get; set; } + private int DataSize; - [ConfigPersist] - private RecentFiles RecentTables { get; set; } + private RecentFiles RecentTables; internal class ColorConfig { @@ -143,8 +139,27 @@ internal class ColorConfig public Color HighlightFreeze { get; set; } = Color.Violet; } - [ConfigPersist] - internal ColorConfig Colors { get; set; } = new ColorConfig(); + internal ColorConfig Colors = new ColorConfig(); + + void IConfigPersist.LoadConfig(IConfigPersist.Provider provider) + { + provider.Get(nameof(LastDomain), ref LastDomain); + provider.Get(nameof(BigEndian), ref BigEndian); + provider.Get(nameof(DataSize), ref DataSize); + provider.Get(nameof(RecentTables), ref RecentTables); + provider.Get(nameof(Colors), ref Colors); + } + Dictionary IConfigPersist.SaveConfig() + { + return new() + { + [nameof(LastDomain)] = LastDomain, + [nameof(BigEndian)] = BigEndian, + [nameof(DataSize)] = DataSize, + [nameof(RecentTables)] = RecentTables, + [nameof(Colors)] = Colors, + }; + } private WatchSize WatchSize => (WatchSize)DataSize; diff --git a/src/BizHawk.Client.EmuHawk/tools/Lua/LuaConsole.cs b/src/BizHawk.Client.EmuHawk/tools/Lua/LuaConsole.cs index 222b27b74a6..4bf686b3cf2 100644 --- a/src/BizHawk.Client.EmuHawk/tools/Lua/LuaConsole.cs +++ b/src/BizHawk.Client.EmuHawk/tools/Lua/LuaConsole.cs @@ -18,7 +18,7 @@ namespace BizHawk.Client.EmuHawk { - public partial class LuaConsole : ToolFormBase, IToolFormAutoConfig, IRestoreDefaults + public partial class LuaConsole : ToolFormBase, IToolFormAutoConfig, IRestoreDefaults, IConfigPersist { private const string IconColumnName = "Icon"; private const string ScriptColumnName = "Script"; @@ -74,8 +74,19 @@ public LuaConsoleSettings() public bool WarnedOnceOnOverwrite { get; set; } } - [ConfigPersist] - public LuaConsoleSettings Settings { get; set; } + public LuaConsoleSettings Settings; + + void IConfigPersist.LoadConfig(IConfigPersist.Provider provider) + { + provider.Get(nameof(Settings), ref Settings); + } + Dictionary IConfigPersist.SaveConfig() + { + return new() + { + [nameof(Settings)] = Settings, + }; + } protected override string WindowTitleStatic => "Lua Console"; diff --git a/src/BizHawk.Client.EmuHawk/tools/NES/NESNameTableViewer.cs b/src/BizHawk.Client.EmuHawk/tools/NES/NESNameTableViewer.cs index f9e03ec0e15..0a5a598ac1a 100644 --- a/src/BizHawk.Client.EmuHawk/tools/NES/NESNameTableViewer.cs +++ b/src/BizHawk.Client.EmuHawk/tools/NES/NESNameTableViewer.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.Windows.Forms; @@ -8,7 +9,7 @@ namespace BizHawk.Client.EmuHawk { - public partial class NESNameTableViewer : ToolFormBase, IToolFormAutoConfig + public partial class NESNameTableViewer : ToolFormBase, IToolFormAutoConfig, IConfigPersist { // TODO: // Show Scroll Lines + UI Toggle @@ -28,13 +29,25 @@ private INESPPUViewable _ppu private IEmulator _emu => _core!; - [ConfigPersist] private int RefreshRateConfig { get => RefreshRate.Value; set => RefreshRate.Value = value; } + void IConfigPersist.LoadConfig(IConfigPersist.Provider provider) + { + int outValue = default; + if (provider.Get(nameof(RefreshRateConfig), ref outValue)) RefreshRateConfig = outValue; + } + Dictionary IConfigPersist.SaveConfig() + { + return new() + { + [nameof(RefreshRateConfig)] = RefreshRateConfig, + }; + } + private int _scanline; protected override string WindowTitleStatic => "Nametable Viewer"; diff --git a/src/BizHawk.Client.EmuHawk/tools/NES/NESPPU.cs b/src/BizHawk.Client.EmuHawk/tools/NES/NESPPU.cs index 543589ae794..062ca9d452e 100644 --- a/src/BizHawk.Client.EmuHawk/tools/NES/NESPPU.cs +++ b/src/BizHawk.Client.EmuHawk/tools/NES/NESPPU.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.Windows.Forms; @@ -8,7 +9,7 @@ namespace BizHawk.Client.EmuHawk { - public partial class NesPPU : ToolFormBase, IToolFormAutoConfig + public partial class NesPPU : ToolFormBase, IToolFormAutoConfig, IConfigPersist { // TODO: // If 8/16 sprite mode, mouse over should put 32x64 version of sprite @@ -39,7 +40,6 @@ private INESPPUViewable _ppu private IEmulator _emu => _core!; - [ConfigPersist] private int RefreshRateConfig { get => RefreshRate.Value; @@ -47,13 +47,28 @@ private int RefreshRateConfig } private bool _chrRomView; - [ConfigPersist] private bool ChrRomView { get => _chrRomView; set { _chrRomView = value; CalculateFormSize(); } } + void IConfigPersist.LoadConfig(IConfigPersist.Provider provider) + { + int outValue = default; + if (provider.Get(nameof(RefreshRateConfig), ref outValue)) RefreshRateConfig = outValue; + bool outValue2 = default; + if (provider.Get(nameof(ChrRomView), ref outValue2)) ChrRomView = outValue2; + } + Dictionary IConfigPersist.SaveConfig() + { + return new() + { + [nameof(RefreshRateConfig)] = RefreshRateConfig, + [nameof(ChrRomView)] = ChrRomView, + }; + } + protected override string WindowTitleStatic => "PPU Viewer"; public NesPPU() diff --git a/src/BizHawk.Client.EmuHawk/tools/PCE/PCEBGViewer.cs b/src/BizHawk.Client.EmuHawk/tools/PCE/PCEBGViewer.cs index c21bf8530e9..b1dd99bc008 100644 --- a/src/BizHawk.Client.EmuHawk/tools/PCE/PCEBGViewer.cs +++ b/src/BizHawk.Client.EmuHawk/tools/PCE/PCEBGViewer.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.Windows.Forms; @@ -9,7 +10,7 @@ namespace BizHawk.Client.EmuHawk { [SpecializedTool("BG Viewer")] - public partial class PceBgViewer : ToolFormBase, IToolFormAutoConfig + public partial class PceBgViewer : ToolFormBase, IToolFormAutoConfig, IConfigPersist { public static Icon ToolIcon => Properties.Resources.PceIcon; @@ -19,14 +20,25 @@ public static Icon ToolIcon [RequiredService] public IEmulator Emulator { get; private set; } - [ConfigPersist] - // ReSharper disable once UnusedMember.Local private int RefreshRateConfig { get => RefreshRate.Value; set => RefreshRate.Value = Math.Max(Math.Min(value, RefreshRate.Maximum), RefreshRate.Minimum); } + void IConfigPersist.LoadConfig(IConfigPersist.Provider provider) + { + int outValue = default; + if (provider.Get(nameof(RefreshRateConfig), ref outValue)) RefreshRateConfig = outValue; + } + Dictionary IConfigPersist.SaveConfig() + { + return new() + { + [nameof(RefreshRateConfig)] = RefreshRateConfig, + }; + } + private int _vdcType; protected override string WindowTitleStatic => "Background Viewer"; diff --git a/src/BizHawk.Client.EmuHawk/tools/SNES/SNESGraphicsDebugger.cs b/src/BizHawk.Client.EmuHawk/tools/SNES/SNESGraphicsDebugger.cs index 975972f0f7a..cacf800f8ed 100644 --- a/src/BizHawk.Client.EmuHawk/tools/SNES/SNESGraphicsDebugger.cs +++ b/src/BizHawk.Client.EmuHawk/tools/SNES/SNESGraphicsDebugger.cs @@ -36,22 +36,36 @@ namespace BizHawk.Client.EmuHawk { - public unsafe partial class SNESGraphicsDebugger : ToolFormBase, IToolFormAutoConfig + public unsafe partial class SNESGraphicsDebugger : ToolFormBase, IToolFormAutoConfig, IConfigPersist { private readonly List displayTypeItems = new List(); [RequiredService] private IBSNESForGfxDebugger Emulator { get; set; } - [ConfigPersist] public bool UseUserBackdropColor { get => checkBackdropColor.Checked; set => checkBackdropColor.Checked = value; } - [ConfigPersist] public int UserBackdropColor { get; set; } + void IConfigPersist.LoadConfig(IConfigPersist.Provider provider) + { + bool outValue = default; + if (provider.Get(nameof(UseUserBackdropColor), ref outValue)) UseUserBackdropColor = outValue; + int outValue2 = default; + if (provider.Get(nameof(UserBackdropColor), ref outValue2)) UserBackdropColor = outValue2; + } + Dictionary IConfigPersist.SaveConfig() + { + return new() + { + [nameof(UseUserBackdropColor)] = UseUserBackdropColor, + [nameof(UserBackdropColor)] = UserBackdropColor, + }; + } + protected override string WindowTitleStatic => "Graphics Debugger"; public SNESGraphicsDebugger() diff --git a/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs b/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs index 7b2e6e75e82..2601700cf08 100644 --- a/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs +++ b/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs @@ -13,7 +13,7 @@ namespace BizHawk.Client.EmuHawk { - public partial class TAStudio : ToolFormBase, IToolFormAutoConfig, IControlMainform + public partial class TAStudio : ToolFormBase, IToolFormAutoConfig, IControlMainform, IConfigPersist { public static readonly FilesystemFilterSet TAStudioProjectsFSFilterSet = new(FilesystemFilter.TAStudioProjects); @@ -56,13 +56,25 @@ public static Icon ToolIcon private int _seekingTo = -1; - [ConfigPersist] - public TAStudioSettings Settings { get; set; } = new TAStudioSettings(); + public TAStudioSettings Settings = new TAStudioSettings(); public TAStudioPalette Palette => Settings.Palette; - [ConfigPersist] - public Font TasViewFont { get; set; } = new Font("Arial", 8.25F, FontStyle.Bold, GraphicsUnit.Point, 0); + public Font TasViewFont = new Font("Arial", 8.25F, FontStyle.Bold, GraphicsUnit.Point, 0); + + void IConfigPersist.LoadConfig(IConfigPersist.Provider provider) + { + provider.Get(nameof(Settings), ref Settings); + provider.Get(nameof(TasViewFont), ref TasViewFont); + } + Dictionary IConfigPersist.SaveConfig() + { + return new() + { + [nameof(Settings)] = Settings, + [nameof(TasViewFont)] = TasViewFont, + }; + } /// /// This is meant to be used by Lua. diff --git a/src/BizHawk.Client.EmuHawk/tools/TI83/TI83KeyPad.cs b/src/BizHawk.Client.EmuHawk/tools/TI83/TI83KeyPad.cs index 7facceb6e13..a613574473b 100644 --- a/src/BizHawk.Client.EmuHawk/tools/TI83/TI83KeyPad.cs +++ b/src/BizHawk.Client.EmuHawk/tools/TI83/TI83KeyPad.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Drawing; using BizHawk.Client.Common; @@ -8,7 +9,7 @@ namespace BizHawk.Client.EmuHawk { - public sealed partial class TI83KeyPad : ToolFormBase, IToolFormAutoConfig + public sealed partial class TI83KeyPad : ToolFormBase, IToolFormAutoConfig, IConfigPersist { public static Icon ToolIcon => Resources.CalculateIcon; @@ -30,8 +31,21 @@ public TI83KeyPad() if (OSTailoredCode.IsUnixHost) MinimumSize = (MaximumSize += new Size(48, 32)); // also updates current size } - [ConfigPersist] - public bool TI83ToolTips { get; set; } = true; + public bool TI83ToolTips = true; + + void IConfigPersist.LoadConfig(IConfigPersist.Provider provider) + { + bool outValue = default; + if (provider.Get(nameof(TI83ToolTips), ref outValue)) TI83ToolTips = outValue; + } + Dictionary IConfigPersist.SaveConfig() + { + return new() + { + [nameof(TI83ToolTips)] = TI83ToolTips, + }; + } + private void TI83KeyPad_Load(object sender, EventArgs e) { diff --git a/src/BizHawk.Client.EmuHawk/tools/ToolManager.cs b/src/BizHawk.Client.EmuHawk/tools/ToolManager.cs index 6751b224f6e..f26f0211bb2 100644 --- a/src/BizHawk.Client.EmuHawk/tools/ToolManager.cs +++ b/src/BizHawk.Client.EmuHawk/tools/ToolManager.cs @@ -1,10 +1,8 @@ using System.Collections.Generic; using System.Drawing; -using System.Globalization; using System.IO; using System.Linq; using System.Reflection; -using System.ComponentModel; using System.Windows.Forms; using BizHawk.Client.Common; @@ -139,9 +137,10 @@ public T Load(bool focus = true, string toolPath = "") AttachSettingHooks(autoConfigTool, _config.CommonToolSettings.GetValueOrPutNew(toolTypeName)); } // custom settings - if (HasCustomConfig(newTool)) + if (newTool is IConfigPersist persister) { - InstallCustomConfig(newTool, _config.CustomToolSettings.GetValueOrPutNew(toolTypeName)); + persister.LoadConfig(new(_config.CustomToolSettings.GetValueOrPutNew(toolTypeName))); + ((Form)(IToolForm)newTool).FormClosing += (o, e) => _config.CustomToolSettings[toolTypeName] = persister.SaveConfig(); } newTool.Restart(); @@ -183,9 +182,10 @@ public IExternalToolForm LoadExternalToolForm(string toolPath, string customForm AttachSettingHooks(autoConfigTool, _config.CommonToolSettings.GetValueOrPutNew(customFormTypeName)); } // custom settings - if (HasCustomConfig(newTool)) + if (newTool is IConfigPersist persister) { - InstallCustomConfig(newTool, _config.CustomToolSettings.GetValueOrPutNew(customFormTypeName)); + persister.LoadConfig(new(_config.CustomToolSettings.GetValueOrPutNew(customFormTypeName))); + ((Form)(IToolForm)newTool).FormClosing += (o, e) => _config.CustomToolSettings[customFormTypeName] = persister.SaveConfig(); } newTool.Restart(); @@ -392,57 +392,6 @@ private void AttachSettingHooks(IToolFormAutoConfig tool, ToolDialogSettings set }; } - private static bool HasCustomConfig(IToolForm tool) - { - return tool.GetType().GetPropertiesWithAttrib(typeof(ConfigPersistAttribute)).Any(); - } - - private static void InstallCustomConfig(IToolForm tool, Dictionary data) - { - Type type = tool.GetType(); - var props = type.GetPropertiesWithAttrib(typeof(ConfigPersistAttribute)).ToList(); - if (props.Count == 0) - { - return; - } - - foreach (var prop in props) - { - if (data.TryGetValue(prop.Name, out var val)) - { - if (val is string str && prop.PropertyType != typeof(string)) - { - // if a type has a TypeConverter, and that converter can convert to string, - // that will be used in place of object markup by JSON.NET - - // but that doesn't work with $type metadata, and JSON.NET fails to fall - // back on regular object serialization when needed. so try to undo a TypeConverter - // operation here - var converter = TypeDescriptor.GetConverter(prop.PropertyType); - val = converter.ConvertFromString(null, CultureInfo.InvariantCulture, str); - } - else if (val is not bool && prop.PropertyType.IsPrimitive) - { - // numeric constants are similarly hosed - val = Convert.ChangeType(val, prop.PropertyType, CultureInfo.InvariantCulture); - } - - prop.SetValue(tool, val, null); - } - } - - ((Form)tool).FormClosing += (o, e) => SaveCustomConfig(tool, data, props); - } - - private static void SaveCustomConfig(IToolForm tool, Dictionary data, List props) - { - data.Clear(); - foreach (var prop in props) - { - data.Add(prop.Name, prop.GetValue(tool, BindingFlags.GetProperty, Type.DefaultBinder, null, CultureInfo.InvariantCulture)); - } - } - /// /// Determines whether a given IToolForm is already loaded /// diff --git a/src/BizHawk.Client.EmuHawk/tools/TraceLogger.cs b/src/BizHawk.Client.EmuHawk/tools/TraceLogger.cs index afd96b1f8b8..09c263e2f6a 100644 --- a/src/BizHawk.Client.EmuHawk/tools/TraceLogger.cs +++ b/src/BizHawk.Client.EmuHawk/tools/TraceLogger.cs @@ -11,7 +11,7 @@ namespace BizHawk.Client.EmuHawk { - public partial class TraceLogger : ToolFormBase, IToolFormAutoConfig + public partial class TraceLogger : ToolFormBase, IToolFormAutoConfig, IConfigPersist { public static Icon ToolIcon => Properties.Resources.PencilIcon; @@ -26,13 +26,10 @@ public static Icon ToolIcon private ITraceable Tracer => _tracerCore!; - [ConfigPersist] - private int MaxLines { get; set; } + private int MaxLines; - [ConfigPersist] - private int FileSizeCap { get; set; } + private int FileSizeCap; - [ConfigPersist] private List Columns { get => TraceView.AllColumns; @@ -48,6 +45,24 @@ private List Columns } } + void IConfigPersist.LoadConfig(IConfigPersist.Provider provider) + { + provider.Get(nameof(MaxLines), ref MaxLines); + provider.Get(nameof(FileSizeCap), ref FileSizeCap); + + List outValue = default; + if (provider.Get(nameof(Columns), ref outValue)) Columns = outValue; + } + Dictionary IConfigPersist.SaveConfig() + { + return new() + { + [nameof(MaxLines)] = MaxLines, + [nameof(FileSizeCap)] = FileSizeCap, + [nameof(Columns)] = Columns, + }; + } + private FileInfo _logFile; private FileInfo LogFile { diff --git a/src/BizHawk.Client.EmuHawk/tools/VirtualPads/VirtualpadsTool.cs b/src/BizHawk.Client.EmuHawk/tools/VirtualPads/VirtualpadsTool.cs index 025a0cd9de0..9f849fa6fb0 100644 --- a/src/BizHawk.Client.EmuHawk/tools/VirtualPads/VirtualpadsTool.cs +++ b/src/BizHawk.Client.EmuHawk/tools/VirtualPads/VirtualpadsTool.cs @@ -9,7 +9,7 @@ namespace BizHawk.Client.EmuHawk { - public partial class VirtualpadTool : ToolFormBase, IToolFormAutoConfig + public partial class VirtualpadTool : ToolFormBase, IToolFormAutoConfig, IConfigPersist { public static Icon ToolIcon => Properties.Resources.GameControllerIcon; @@ -17,11 +17,24 @@ public static Icon ToolIcon [RequiredService] private IEmulator Emulator { get; set; } - [ConfigPersist] - public bool StickyPads { get; set; } + public bool StickyPads; + + public bool ClearAlsoClearsAnalog; + + void IConfigPersist.LoadConfig(IConfigPersist.Provider provider) + { + provider.Get(nameof(StickyPads), ref StickyPads); + provider.Get(nameof(ClearAlsoClearsAnalog), ref ClearAlsoClearsAnalog); + } + Dictionary IConfigPersist.SaveConfig() + { + return new() + { + [nameof(StickyPads)] = StickyPads, + [nameof(ClearAlsoClearsAnalog)] = ClearAlsoClearsAnalog, + }; + } - [ConfigPersist] - public bool ClearAlsoClearsAnalog { get; set; } private bool _readOnly; diff --git a/src/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs b/src/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs index 4c5da8ea25c..5b210dd0819 100644 --- a/src/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs +++ b/src/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs @@ -20,7 +20,7 @@ namespace BizHawk.Client.EmuHawk /// /// A form designed to search through ram values /// - public partial class RamSearch : ToolFormBase, IToolFormAutoConfig, IRestoreDefaults + public partial class RamSearch : ToolFormBase, IToolFormAutoConfig, IRestoreDefaults, IConfigPersist { private const int MaxDetailedSize = 1024 * 1024; // 1mb, semi-arbitrary decision, sets the size to check for and automatically switch to fast mode for the user private const int MaxSupportedSize = 1024 * 1024 * 64; // 64mb, semi-arbitrary decision, sets the maximum size RAM Search will support (as it will crash beyond this) @@ -106,8 +106,19 @@ public RamSearch() [OptionalService] public IInputPollable InputPollableCore { get; set; } - [ConfigPersist] - public RamSearchSettings Settings { get; set; } + public RamSearchSettings Settings; + + void IConfigPersist.LoadConfig(IConfigPersist.Provider provider) + { + provider.Get(nameof(Settings), ref Settings); + } + Dictionary IConfigPersist.SaveConfig() + { + return new() + { + [nameof(Settings)] = Settings, + }; + } private void HardSetDisplayTypeDropDown(Common.WatchDisplayType type) { diff --git a/src/BizHawk.Client.EmuHawk/tools/Watch/RamWatch.cs b/src/BizHawk.Client.EmuHawk/tools/Watch/RamWatch.cs index 796bb332b1f..73671e71a87 100644 --- a/src/BizHawk.Client.EmuHawk/tools/Watch/RamWatch.cs +++ b/src/BizHawk.Client.EmuHawk/tools/Watch/RamWatch.cs @@ -17,7 +17,7 @@ namespace BizHawk.Client.EmuHawk { - public partial class RamWatch : ToolFormBase, IToolFormAutoConfig, IRestoreDefaults + public partial class RamWatch : ToolFormBase, IToolFormAutoConfig, IRestoreDefaults, IConfigPersist { public static Icon ToolIcon => Resources.WatchIcon; @@ -157,8 +157,19 @@ private void SetColumns() WatchListView.Refresh(); } - [ConfigPersist] - public RamWatchSettings Settings { get; set; } + public RamWatchSettings Settings; + + void IConfigPersist.LoadConfig(IConfigPersist.Provider provider) + { + provider.Get(nameof(Settings), ref Settings); + } + Dictionary IConfigPersist.SaveConfig() + { + return new() + { + [nameof(Settings)] = Settings, + }; + } public class RamWatchSettings { From 195f1804f24f969e51abb3620c7c66ebc25f8205 Mon Sep 17 00:00:00 2001 From: SuuperW Date: Wed, 9 Jul 2025 00:12:48 -0500 Subject: [PATCH 6/8] Make a note of this dotnet bug. --- .editorconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.editorconfig b/.editorconfig index beae5341de0..bd2288feba2 100644 --- a/.editorconfig +++ b/.editorconfig @@ -63,7 +63,7 @@ dotnet_diagnostic.IDE0032.severity = suggestion # Simplify default expression dotnet_diagnostic.IDE0034.severity = suggestion # Use pattern matching to avoid is check followed by a cast (without variable) -dotnet_diagnostic.IDE0038.severity = warning +dotnet_diagnostic.IDE0038.severity = warning # Note that this doesn't work with `dotnet build` but does work inside Visual Studio. # Use is null check dotnet_diagnostic.IDE0041.severity = warning # Deconstruct variable declaration From e68f8a072cb4a2d89119dbb8f3736261e8dc8d63 Mon Sep 17 00:00:00 2001 From: SuuperW Date: Wed, 9 Jul 2025 00:15:37 -0500 Subject: [PATCH 7/8] Enable IDE0080 (suppression operator has no effect) and fix violation. --- .editorconfig | 2 ++ .../CustomControls/InputRoll/InputRoll.cs | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.editorconfig b/.editorconfig index bd2288feba2..4eb6270c60a 100644 --- a/.editorconfig +++ b/.editorconfig @@ -97,6 +97,8 @@ dotnet_diagnostic.IDE0071.severity = suggestion dotnet_diagnostic.IDE0074.severity = suggestion # Use pattern matching dotnet_diagnostic.IDE0078.severity = suggestion +# Suppression operator has no effect and can be misinterpreted +dotnet_diagnostic.IDE0080.severity = warning # Convert typeof to nameof dotnet_diagnostic.IDE0082.severity = warning # Use pattern matching (not operator) diff --git a/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/InputRoll.cs b/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/InputRoll.cs index 0034e9519c3..95ccd8ae6ba 100644 --- a/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/InputRoll.cs +++ b/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/InputRoll.cs @@ -1150,7 +1150,7 @@ protected override void OnMouseDown(MouseEventArgs e) { // do marker drag here } - else if (ModifierKeys is Keys.Shift && CurrentCell.Column! is { Type: ColumnType.Text } col) + else if (ModifierKeys is Keys.Shift && CurrentCell.Column is { Type: ColumnType.Text } col) { if (_selectedItems.Count is not 0) { From 4564e200cbb5da54d8bb24bec2dce740ad5b7ccb Mon Sep 17 00:00:00 2001 From: SuuperW Date: Thu, 31 Jul 2025 00:52:59 -0500 Subject: [PATCH 8/8] Fix some violations of SA1509 (opening braces should not be preceded by blank line). Don't enable it because it flags some silly things. --- src/BizHawk.Bizware.Input/SDL2/SDL2Gamepad.cs | 1 - .../Computers/AmstradCPC/Hardware/Disk/NECUPD765.FDD.cs | 3 --- .../Computers/AmstradCPC/Media/Disk/FloppyDisk.cs | 1 - .../Computers/SinclairSpectrum/Hardware/Disk/NECUPD765.FDD.cs | 3 --- .../Computers/SinclairSpectrum/Media/Disk/FloppyDisk.cs | 1 - src/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/PPU.cs | 1 - src/BizHawk.Emulation.DiscSystem/Internal/Algorithms/ECM.cs | 1 - 7 files changed, 11 deletions(-) diff --git a/src/BizHawk.Bizware.Input/SDL2/SDL2Gamepad.cs b/src/BizHawk.Bizware.Input/SDL2/SDL2Gamepad.cs index 200f266cb0a..8eef3d78c42 100644 --- a/src/BizHawk.Bizware.Input/SDL2/SDL2Gamepad.cs +++ b/src/BizHawk.Bizware.Input/SDL2/SDL2Gamepad.cs @@ -367,4 +367,3 @@ public void SetVibration(int left, int right) } } } - diff --git a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPD765.FDD.cs b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPD765.FDD.cs index 2f588bfb066..cd39bbf0cad 100644 --- a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPD765.FDD.cs +++ b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Disk/NECUPD765.FDD.cs @@ -387,7 +387,6 @@ public FloppyDisk.Sector FindSector(ref byte[] resBuffer, CommandParameters prms index = 0; lc++; } - } while (lc < 2); if ((resBuffer[RS_ST2] & 0x02) != 0) @@ -653,7 +652,6 @@ public void RunSeekCycle() // we are seeking forward var delta = SeekingTrack - CurrentTrack; MoveHead(SkipDirection.Increment, delta); - } else if (CurrentTrack > SeekingTrack) { @@ -730,7 +728,6 @@ public void SeekDone() FLAG_SEEK_INTERRUPT = true; //CurrentState = DriveMainState.None; - } */ diff --git a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Media/Disk/FloppyDisk.cs b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Media/Disk/FloppyDisk.cs index b8a9025e01e..59f746bc95e 100644 --- a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Media/Disk/FloppyDisk.cs +++ b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Media/Disk/FloppyDisk.cs @@ -492,7 +492,6 @@ protected virtual void SpeedlockDetection() sec.SectorData = data.ToArray(); sec.ContainsMultipleWeakSectors = true; sec.ActualDataByteLength = data.Count; - } */ diff --git a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Disk/NECUPD765.FDD.cs b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Disk/NECUPD765.FDD.cs index 79adcd0f6e4..b6c0579484a 100644 --- a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Disk/NECUPD765.FDD.cs +++ b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Disk/NECUPD765.FDD.cs @@ -380,7 +380,6 @@ public FloppyDisk.Sector FindSector(ref byte[] resBuffer, CommandParameters prms index = 0; lc++; } - } while (lc < 2); if ((resBuffer[RS_ST2] & 0x02) != 0) @@ -646,7 +645,6 @@ public void RunSeekCycle() // we are seeking forward var delta = SeekingTrack - CurrentTrack; MoveHead(SkipDirection.Increment, delta); - } else if (CurrentTrack > SeekingTrack) { @@ -723,7 +721,6 @@ public void SeekDone() FLAG_SEEK_INTERRUPT = true; //CurrentState = DriveMainState.None; - } */ diff --git a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Disk/FloppyDisk.cs b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Disk/FloppyDisk.cs index dfdd3e656fb..869ddcc4a2a 100644 --- a/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Disk/FloppyDisk.cs +++ b/src/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Media/Disk/FloppyDisk.cs @@ -492,7 +492,6 @@ protected virtual void SpeedlockDetection() sec.SectorData = data.ToArray(); sec.ContainsMultipleWeakSectors = true; sec.ActualDataByteLength = data.Count; - } */ diff --git a/src/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/PPU.cs b/src/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/PPU.cs index 4fcec0644c3..03601c36fe8 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/PPU.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/PPU.cs @@ -78,7 +78,6 @@ public void tick() Core._vidbuffer[(int)(Math.Round(x_pos) + 1 + 260 * (Math.Round(y_pos) - 1))] |= (int)(br & bright_int_3); Core._vidbuffer[(int)(Math.Round(x_pos) - 1 + 260 * (Math.Round(y_pos) + 1))] |= (int)(br & bright_int_3); Core._vidbuffer[(int)(Math.Round(x_pos) - 1 + 260 * (Math.Round(y_pos) - 1))] |= (int)(br & bright_int_3); - } */ } diff --git a/src/BizHawk.Emulation.DiscSystem/Internal/Algorithms/ECM.cs b/src/BizHawk.Emulation.DiscSystem/Internal/Algorithms/ECM.cs index dfa1d0e237c..bbc4cd497c9 100644 --- a/src/BizHawk.Emulation.DiscSystem/Internal/Algorithms/ECM.cs +++ b/src/BizHawk.Emulation.DiscSystem/Internal/Algorithms/ECM.cs @@ -302,7 +302,6 @@ static FFUtil() for (int i = 255; i < 512; i++) gf_exp[i] = gf_exp[(byte)(i - 255)]; } - } //static class FFUtil #endif }