From f628848127b151f97946a28cc58782067d095b36 Mon Sep 17 00:00:00 2001 From: parsons Date: Wed, 29 Apr 2026 22:07:49 +0100 Subject: [PATCH] Started 128K model --- Core/SpectrumMachine.cs | 15 +++++++++ Desktop/Form1.Designer.cs | 68 +++++++++++++++++++++++++-------------- Desktop/Form1.cs | 18 ++++++++--- Desktop/Program.cs | 8 +++-- 4 files changed, 78 insertions(+), 31 deletions(-) diff --git a/Core/SpectrumMachine.cs b/Core/SpectrumMachine.cs index 728b5e1..65e2420 100644 --- a/Core/SpectrumMachine.cs +++ b/Core/SpectrumMachine.cs @@ -9,8 +9,14 @@ using System.Threading.Tasks; namespace Core { + public enum MachineModel + { + Spectrum48K, + SpectrumPlus2A + } public class SpectrumMachine { + public MachineModel CurrentModel { get; private set; } = MachineModel.Spectrum48K; // The Hardware public Z80 Cpu { get; private set; } public MemoryBus Memory { get; private set; } @@ -43,6 +49,15 @@ namespace Core public event Action? OnStatsUpdated; // Passes FPS and TapeLoaded status public event Action? OnMachineCrashed; + public void SetMachineModel(MachineModel newModel) + { + if (CurrentModel == newModel) return; // Do nothing if it's the same + + CurrentModel = newModel; + + // Flag the main loop to perform a hard reset on the next frame + _pendingReset = true; + } public SpectrumMachine(IAudioDevice beeperDevice) { _beeper = beeperDevice; diff --git a/Desktop/Form1.Designer.cs b/Desktop/Form1.Designer.cs index 3c35577..5fed49d 100644 --- a/Desktop/Form1.Designer.cs +++ b/Desktop/Form1.Designer.cs @@ -39,6 +39,8 @@ saveSnapshotToolStripMenuItem = new ToolStripMenuItem(); exitToolStripMenuItem = new ToolStripMenuItem(); machineToolStripMenuItem = new ToolStripMenuItem(); + spectrum48KToolStripMenuItem = new ToolStripMenuItem(); + spectrum128KPlus2AToolStripMenuItem = new ToolStripMenuItem(); runToolStripMenuItem = new ToolStripMenuItem(); resetToolStripMenuItem = new ToolStripMenuItem(); stepToolStripMenuItem = new ToolStripMenuItem(); @@ -58,8 +60,7 @@ menuStrip1.Items.AddRange(new ToolStripItem[] { fileToolStripMenuItem, machineToolStripMenuItem, viewToolStripMenuItem, optionsToolStripMenuItem, playTapeToolStripMenuItem }); menuStrip1.Location = new Point(0, 0); menuStrip1.Name = "menuStrip1"; - menuStrip1.Padding = new Padding(5, 2, 0, 2); - menuStrip1.Size = new Size(738, 28); + menuStrip1.Size = new Size(922, 33); menuStrip1.TabIndex = 1; menuStrip1.Text = "menuStrip1"; // @@ -67,95 +68,109 @@ // fileToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { openToolStripMenuItem, saveSnapshotToolStripMenuItem, exitToolStripMenuItem }); fileToolStripMenuItem.Name = "fileToolStripMenuItem"; - fileToolStripMenuItem.Size = new Size(46, 24); + fileToolStripMenuItem.Size = new Size(54, 29); fileToolStripMenuItem.Text = "File"; // // openToolStripMenuItem // openToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { includedToolStripMenuItem, tAPToolStripMenuItem, sNAToolStripMenuItem }); openToolStripMenuItem.Name = "openToolStripMenuItem"; - openToolStripMenuItem.Size = new Size(188, 26); + openToolStripMenuItem.Size = new Size(231, 34); openToolStripMenuItem.Text = "Open"; // // includedToolStripMenuItem // includedToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { tAPToolStripMenuItem1, sNAToolStripMenuItem1 }); includedToolStripMenuItem.Name = "includedToolStripMenuItem"; - includedToolStripMenuItem.Size = new Size(149, 26); + includedToolStripMenuItem.Size = new Size(182, 34); includedToolStripMenuItem.Text = "Included"; // // tAPToolStripMenuItem1 // tAPToolStripMenuItem1.Name = "tAPToolStripMenuItem1"; - tAPToolStripMenuItem1.Size = new Size(121, 26); + tAPToolStripMenuItem1.Size = new Size(149, 34); tAPToolStripMenuItem1.Text = "TAP"; // // sNAToolStripMenuItem1 // sNAToolStripMenuItem1.Name = "sNAToolStripMenuItem1"; - sNAToolStripMenuItem1.Size = new Size(121, 26); + sNAToolStripMenuItem1.Size = new Size(149, 34); sNAToolStripMenuItem1.Text = "SNA"; // // tAPToolStripMenuItem // tAPToolStripMenuItem.Name = "tAPToolStripMenuItem"; - tAPToolStripMenuItem.Size = new Size(149, 26); + tAPToolStripMenuItem.Size = new Size(182, 34); tAPToolStripMenuItem.Text = "TAP"; tAPToolStripMenuItem.Click += loadTAPToolStripMenuItem_Click; // // sNAToolStripMenuItem // sNAToolStripMenuItem.Name = "sNAToolStripMenuItem"; - sNAToolStripMenuItem.Size = new Size(149, 26); + sNAToolStripMenuItem.Size = new Size(182, 34); sNAToolStripMenuItem.Text = "SNA"; sNAToolStripMenuItem.Click += openSNAToolStripMenuItem_Click; // // saveSnapshotToolStripMenuItem // saveSnapshotToolStripMenuItem.Name = "saveSnapshotToolStripMenuItem"; - saveSnapshotToolStripMenuItem.Size = new Size(188, 26); + saveSnapshotToolStripMenuItem.Size = new Size(231, 34); saveSnapshotToolStripMenuItem.Text = "Save Snapshot"; saveSnapshotToolStripMenuItem.Click += SaveSNAMenuItem_Click; // // exitToolStripMenuItem // exitToolStripMenuItem.Name = "exitToolStripMenuItem"; - exitToolStripMenuItem.Size = new Size(188, 26); + exitToolStripMenuItem.Size = new Size(231, 34); exitToolStripMenuItem.Text = "Exit"; exitToolStripMenuItem.Click += btnExit_Click; // // machineToolStripMenuItem // - machineToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { runToolStripMenuItem, resetToolStripMenuItem, stepToolStripMenuItem, resetToolStripMenuItem1 }); + machineToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { spectrum48KToolStripMenuItem, spectrum128KPlus2AToolStripMenuItem, runToolStripMenuItem, resetToolStripMenuItem, stepToolStripMenuItem, resetToolStripMenuItem1 }); machineToolStripMenuItem.Name = "machineToolStripMenuItem"; - machineToolStripMenuItem.Size = new Size(79, 24); + machineToolStripMenuItem.Size = new Size(94, 29); machineToolStripMenuItem.Text = "Machine"; // + // spectrum48KToolStripMenuItem + // + spectrum48KToolStripMenuItem.Checked = true; + spectrum48KToolStripMenuItem.CheckState = CheckState.Checked; + spectrum48KToolStripMenuItem.Name = "spectrum48KToolStripMenuItem"; + spectrum48KToolStripMenuItem.Size = new Size(270, 34); + spectrum48KToolStripMenuItem.Text = "48K"; + // + // spectrum128KPlus2AToolStripMenuItem + // + spectrum128KPlus2AToolStripMenuItem.Name = "spectrum128KPlus2AToolStripMenuItem"; + spectrum128KPlus2AToolStripMenuItem.Size = new Size(270, 34); + spectrum128KPlus2AToolStripMenuItem.Text = "128K +2A"; + // // runToolStripMenuItem // runToolStripMenuItem.Name = "runToolStripMenuItem"; - runToolStripMenuItem.Size = new Size(129, 26); + runToolStripMenuItem.Size = new Size(270, 34); runToolStripMenuItem.Text = "Run"; runToolStripMenuItem.Click += btnRun_Click; // // resetToolStripMenuItem // resetToolStripMenuItem.Name = "resetToolStripMenuItem"; - resetToolStripMenuItem.Size = new Size(129, 26); + resetToolStripMenuItem.Size = new Size(270, 34); resetToolStripMenuItem.Text = "Pause"; resetToolStripMenuItem.Click += btnPause_Click; // // stepToolStripMenuItem // stepToolStripMenuItem.Name = "stepToolStripMenuItem"; - stepToolStripMenuItem.Size = new Size(129, 26); + stepToolStripMenuItem.Size = new Size(270, 34); stepToolStripMenuItem.Text = "Step"; stepToolStripMenuItem.Click += btnStep_Click; // // resetToolStripMenuItem1 // resetToolStripMenuItem1.Name = "resetToolStripMenuItem1"; - resetToolStripMenuItem1.Size = new Size(129, 26); + resetToolStripMenuItem1.Size = new Size(270, 34); resetToolStripMenuItem1.Text = "Reset"; resetToolStripMenuItem1.Click += btnReset_Click; // @@ -163,13 +178,13 @@ // viewToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { debuggerToolStripMenuItem }); viewToolStripMenuItem.Name = "viewToolStripMenuItem"; - viewToolStripMenuItem.Size = new Size(55, 24); + viewToolStripMenuItem.Size = new Size(65, 29); viewToolStripMenuItem.Text = "View"; // // debuggerToolStripMenuItem // debuggerToolStripMenuItem.Name = "debuggerToolStripMenuItem"; - debuggerToolStripMenuItem.Size = new Size(159, 26); + debuggerToolStripMenuItem.Size = new Size(194, 34); debuggerToolStripMenuItem.Text = "Debugger"; debuggerToolStripMenuItem.Click += openDebuggerToolStripMenuItem_Click; // @@ -177,13 +192,13 @@ // optionsToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { HighSpeedToolStripMenuItem, fastLoadToolStripMenuItem }); optionsToolStripMenuItem.Name = "optionsToolStripMenuItem"; - optionsToolStripMenuItem.Size = new Size(75, 24); + optionsToolStripMenuItem.Size = new Size(92, 29); optionsToolStripMenuItem.Text = "Options"; // // HighSpeedToolStripMenuItem // HighSpeedToolStripMenuItem.Name = "HighSpeedToolStripMenuItem"; - HighSpeedToolStripMenuItem.Size = new Size(224, 26); + HighSpeedToolStripMenuItem.Size = new Size(214, 34); HighSpeedToolStripMenuItem.Text = "High Speed"; HighSpeedToolStripMenuItem.Click += btnHighSpeedToggle_Click; // @@ -192,25 +207,26 @@ fastLoadToolStripMenuItem.Checked = true; fastLoadToolStripMenuItem.CheckState = CheckState.Checked; fastLoadToolStripMenuItem.Name = "fastLoadToolStripMenuItem"; - fastLoadToolStripMenuItem.Size = new Size(224, 26); + fastLoadToolStripMenuItem.Size = new Size(214, 34); fastLoadToolStripMenuItem.Text = "Fast Loading"; fastLoadToolStripMenuItem.Click += fastLoadToolStripMenuItem_Click; // // playTapeToolStripMenuItem // playTapeToolStripMenuItem.Name = "playTapeToolStripMenuItem"; - playTapeToolStripMenuItem.Size = new Size(85, 24); + playTapeToolStripMenuItem.Size = new Size(101, 29); playTapeToolStripMenuItem.Text = "Play Tape"; playTapeToolStripMenuItem.Click += playTapeToolStripMenuItem_Click; // // Form1 // - AutoScaleDimensions = new SizeF(8F, 20F); + AutoScaleDimensions = new SizeF(10F, 25F); AutoScaleMode = AutoScaleMode.Font; - ClientSize = new Size(738, 608); + ClientSize = new Size(922, 760); Controls.Add(menuStrip1); KeyPreview = true; MainMenuStrip = menuStrip1; + Margin = new Padding(4); Name = "Form1"; Text = "Parsons Sinclair ZX Spectrum 48K - 2026"; menuStrip1.ResumeLayout(false); @@ -241,5 +257,7 @@ private ToolStripMenuItem saveSnapshotToolStripMenuItem; private ToolStripMenuItem playTapeToolStripMenuItem; private ToolStripMenuItem fastLoadToolStripMenuItem; + private ToolStripMenuItem spectrum48KToolStripMenuItem; + private ToolStripMenuItem spectrum128KPlus2AToolStripMenuItem; } } diff --git a/Desktop/Form1.cs b/Desktop/Form1.cs index 94eb401..4af0ad3 100644 --- a/Desktop/Form1.cs +++ b/Desktop/Form1.cs @@ -228,9 +228,20 @@ namespace Desktop _machine.IoBus.KeyboardRows[row] |= (byte)(1 << col); } - // ==================================================================== - // MENU CONTROLS - // ==================================================================== + + private void spectrum48KToolStripMenuItem_Click(object sender, EventArgs e) + { + spectrum48KToolStripMenuItem.Checked = true; + spectrum128KPlus2AToolStripMenuItem.Checked = false; + _machine.SetMachineModel(MachineModel.Spectrum48K); + } + + private void spectrum128KPlus2AToolStripMenuItem_Click(object sender, EventArgs e) + { + spectrum48KToolStripMenuItem.Checked = false; + spectrum128KPlus2AToolStripMenuItem.Checked = true; + _machine.SetMachineModel(MachineModel.SpectrumPlus2A); + } private void btnRun_Click(object sender, EventArgs e) => _machine.Resume(); private void btnPause_Click(object sender, EventArgs e) => _machine.Pause(); @@ -408,6 +419,5 @@ namespace Desktop } } - } } \ No newline at end of file diff --git a/Desktop/Program.cs b/Desktop/Program.cs index 804fa5c..e273f48 100644 --- a/Desktop/Program.cs +++ b/Desktop/Program.cs @@ -8,8 +8,12 @@ namespace Desktop [STAThread] static void Main() { - // To customize application configuration such as set high DPI settings or default font, - // see https://aka.ms/applicationconfiguration. + Application.ThreadException += (s, e) => + MessageBox.Show($"UI Thread Crash: {e.Exception.Message}\n\n{e.Exception.StackTrace}", "Fatal Error"); + + AppDomain.CurrentDomain.UnhandledException += (s, e) => + MessageBox.Show($"Background Crash: {((Exception)e.ExceptionObject).Message}\n\n{((Exception)e.ExceptionObject).StackTrace}", "Fatal Error"); + ApplicationConfiguration.Initialize(); Application.Run(new Form1()); }