diff --git a/Desktop/Desktop.csproj b/Desktop/Desktop.csproj
index 9785458..57d37e0 100644
--- a/Desktop/Desktop.csproj
+++ b/Desktop/Desktop.csproj
@@ -14,9 +14,9 @@
-
-
-
+
+
+
@@ -36,13 +36,13 @@
Always
-
+
Always
-
+
Always
-
+
Always
diff --git a/Desktop/Form1.Designer.cs b/Desktop/Form1.Designer.cs
index e0690c8..0a8fef2 100644
--- a/Desktop/Form1.Designer.cs
+++ b/Desktop/Form1.Designer.cs
@@ -31,6 +31,9 @@
menuStrip1 = new MenuStrip();
fileToolStripMenuItem = new ToolStripMenuItem();
openToolStripMenuItem = new ToolStripMenuItem();
+ includedToolStripMenuItem = new ToolStripMenuItem();
+ tAPToolStripMenuItem1 = new ToolStripMenuItem();
+ sNAToolStripMenuItem1 = new ToolStripMenuItem();
tAPToolStripMenuItem = new ToolStripMenuItem();
sNAToolStripMenuItem = new ToolStripMenuItem();
exitToolStripMenuItem = new ToolStripMenuItem();
@@ -43,16 +46,14 @@
resetToolStripMenuItem1 = new ToolStripMenuItem();
optionsToolStripMenuItem = new ToolStripMenuItem();
HighSpeedToolStripMenuItem = new ToolStripMenuItem();
- includedToolStripMenuItem = new ToolStripMenuItem();
- tAPToolStripMenuItem1 = new ToolStripMenuItem();
- sNAToolStripMenuItem1 = new ToolStripMenuItem();
+ saveSnapshotToolStripMenuItem = new ToolStripMenuItem();
menuStrip1.SuspendLayout();
SuspendLayout();
//
// menuStrip1
//
menuStrip1.ImageScalingSize = new Size(24, 24);
- menuStrip1.Items.AddRange(new ToolStripItem[] { fileToolStripMenuItem, viewToolStripMenuItem, machineToolStripMenuItem, optionsToolStripMenuItem });
+ menuStrip1.Items.AddRange(new ToolStripItem[] { fileToolStripMenuItem, machineToolStripMenuItem, viewToolStripMenuItem, optionsToolStripMenuItem });
menuStrip1.Location = new Point(0, 0);
menuStrip1.Name = "menuStrip1";
menuStrip1.Padding = new Padding(5, 2, 0, 2);
@@ -62,7 +63,7 @@
//
// fileToolStripMenuItem
//
- fileToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { openToolStripMenuItem, exitToolStripMenuItem });
+ fileToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { openToolStripMenuItem, saveSnapshotToolStripMenuItem, exitToolStripMenuItem });
fileToolStripMenuItem.Name = "fileToolStripMenuItem";
fileToolStripMenuItem.Size = new Size(46, 24);
fileToolStripMenuItem.Text = "File";
@@ -71,9 +72,28 @@
//
openToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { includedToolStripMenuItem, tAPToolStripMenuItem, sNAToolStripMenuItem });
openToolStripMenuItem.Name = "openToolStripMenuItem";
- openToolStripMenuItem.Size = new Size(128, 26);
+ openToolStripMenuItem.Size = new Size(224, 26);
openToolStripMenuItem.Text = "Open";
//
+ // includedToolStripMenuItem
+ //
+ includedToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { tAPToolStripMenuItem1, sNAToolStripMenuItem1 });
+ includedToolStripMenuItem.Name = "includedToolStripMenuItem";
+ includedToolStripMenuItem.Size = new Size(149, 26);
+ includedToolStripMenuItem.Text = "Included";
+ //
+ // tAPToolStripMenuItem1
+ //
+ tAPToolStripMenuItem1.Name = "tAPToolStripMenuItem1";
+ tAPToolStripMenuItem1.Size = new Size(121, 26);
+ tAPToolStripMenuItem1.Text = "TAP";
+ //
+ // sNAToolStripMenuItem1
+ //
+ sNAToolStripMenuItem1.Name = "sNAToolStripMenuItem1";
+ sNAToolStripMenuItem1.Size = new Size(121, 26);
+ sNAToolStripMenuItem1.Text = "SNA";
+ //
// tAPToolStripMenuItem
//
tAPToolStripMenuItem.Name = "tAPToolStripMenuItem";
@@ -91,7 +111,7 @@
// exitToolStripMenuItem
//
exitToolStripMenuItem.Name = "exitToolStripMenuItem";
- exitToolStripMenuItem.Size = new Size(128, 26);
+ exitToolStripMenuItem.Size = new Size(224, 26);
exitToolStripMenuItem.Text = "Exit";
exitToolStripMenuItem.Click += btnExit_Click;
//
@@ -154,28 +174,16 @@
// HighSpeedToolStripMenuItem
//
HighSpeedToolStripMenuItem.Name = "HighSpeedToolStripMenuItem";
- HighSpeedToolStripMenuItem.Size = new Size(224, 26);
+ HighSpeedToolStripMenuItem.Size = new Size(170, 26);
HighSpeedToolStripMenuItem.Text = "High Speed";
HighSpeedToolStripMenuItem.Click += btnHighSpeedToggle_Click;
//
- // includedToolStripMenuItem
+ // saveSnapshotToolStripMenuItem
//
- includedToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { tAPToolStripMenuItem1, sNAToolStripMenuItem1 });
- includedToolStripMenuItem.Name = "includedToolStripMenuItem";
- includedToolStripMenuItem.Size = new Size(149, 26);
- includedToolStripMenuItem.Text = "Included";
- //
- // tAPToolStripMenuItem1
- //
- tAPToolStripMenuItem1.Name = "tAPToolStripMenuItem1";
- tAPToolStripMenuItem1.Size = new Size(224, 26);
- tAPToolStripMenuItem1.Text = "TAP";
- //
- // sNAToolStripMenuItem1
- //
- sNAToolStripMenuItem1.Name = "sNAToolStripMenuItem1";
- sNAToolStripMenuItem1.Size = new Size(224, 26);
- sNAToolStripMenuItem1.Text = "SNA";
+ saveSnapshotToolStripMenuItem.Name = "saveSnapshotToolStripMenuItem";
+ saveSnapshotToolStripMenuItem.Size = new Size(224, 26);
+ saveSnapshotToolStripMenuItem.Text = "Save Snapshot";
+ saveSnapshotToolStripMenuItem.Click += SaveSNAMenuItem_Click;
//
// Form1
//
@@ -212,5 +220,6 @@
private ToolStripMenuItem includedToolStripMenuItem;
private ToolStripMenuItem tAPToolStripMenuItem1;
private ToolStripMenuItem sNAToolStripMenuItem1;
+ private ToolStripMenuItem saveSnapshotToolStripMenuItem;
}
}
diff --git a/Desktop/Form1.cs b/Desktop/Form1.cs
index ceb6f81..2ea7136 100644
--- a/Desktop/Form1.cs
+++ b/Desktop/Form1.cs
@@ -237,6 +237,69 @@ namespace Desktop
});
}
+ private void SaveSNAMenuItem_Click(object? sender, EventArgs e)
+ {
+ _isPaused = true;
+ using (SaveFileDialog sfd = new SaveFileDialog())
+ {
+ sfd.Filter = "Spectrum SNA Files|*.sna";
+ if (sfd.ShowDialog() == DialogResult.OK)
+ {
+ SaveSNA(sfd.FileName);
+ }
+ }
+ _isPaused = false;
+ }
+
+ public void SaveSNA(string filepath)
+ {
+ // 0. Back up the live state BEFORE modifying it
+ ushort originalSP = _cpu.SP;
+ byte originalMemLow = _memoryBus.Read((ushort)(_cpu.SP - 2));
+ byte originalMemHigh = _memoryBus.Read((ushort)(_cpu.SP - 1));
+
+ // 1. We must push the PC onto the stack before saving!
+ _cpu.SP -= 2;
+ _memoryBus.Write(_cpu.SP, (byte)(_cpu.PC & 0xFF)); // Low byte
+ _memoryBus.Write((ushort)(_cpu.SP + 1), (byte)(_cpu.PC >> 8)); // High byte
+
+ using (FileStream fs = new FileStream(filepath, FileMode.Create))
+ using (BinaryWriter bw = new BinaryWriter(fs))
+ {
+ // 2. Write the 27-byte Header
+ bw.Write(_cpu.I);
+ bw.Write(_cpu.HL_Prime.Low); bw.Write(_cpu.HL_Prime.High);
+ bw.Write(_cpu.DE_Prime.Low); bw.Write(_cpu.DE_Prime.High);
+ bw.Write(_cpu.BC_Prime.Low); bw.Write(_cpu.BC_Prime.High);
+ bw.Write(_cpu.AF_Prime.Low); bw.Write(_cpu.AF_Prime.High);
+
+ bw.Write(_cpu.HL.Low); bw.Write(_cpu.HL.High);
+ bw.Write(_cpu.DE.Low); bw.Write(_cpu.DE.High);
+ bw.Write(_cpu.BC.Low); bw.Write(_cpu.BC.High);
+ bw.Write(_cpu.IY.Low); bw.Write(_cpu.IY.High);
+ bw.Write(_cpu.IX.Low); bw.Write(_cpu.IX.High);
+
+ // IFF2 determines the interrupt state in SNA
+ bw.Write((byte)(_cpu.IFF2 ? 0x04 : 0x00));
+ bw.Write(_cpu.R);
+ bw.Write(_cpu.AF.Low); bw.Write(_cpu.AF.High);
+ bw.Write((byte)(_cpu.SP & 0xFF)); bw.Write((byte)(_cpu.SP >> 8));
+ bw.Write((byte)_cpu.InterruptMode);
+ bw.Write(_simpleIoBus.BorderColorIndex);
+
+ // 3. Dump the 48K RAM
+ for (int i = 0x4000; i <= 0xFFFF; i++)
+ {
+ bw.Write(_memoryBus.Read((ushort)i));
+ }
+ }
+
+ // 4. RESTORE the emulator's state so the game can resume safely
+ _cpu.SP = originalSP;
+ _memoryBus.Write((ushort)(originalSP - 2), originalMemLow);
+ _memoryBus.Write((ushort)(originalSP - 1), originalMemHigh);
+ }
+
private void PopulateIncludedTapsMenu()
{
// 1. Get the current assembly (your .exe)
diff --git a/Desktop/ROMS/TAP/DizzyB-TreasureIsland.tap b/Desktop/ROMS/TAP/DizzyB-TreasureIsland.tap
deleted file mode 100644
index d839ef5..0000000
Binary files a/Desktop/ROMS/TAP/DizzyB-TreasureIsland.tap and /dev/null differ
diff --git a/Desktop/ROMS/TAP/GHILL48K.TAP b/Desktop/ROMS/TAP/Grange Hill.TAP
similarity index 100%
rename from Desktop/ROMS/TAP/GHILL48K.TAP
rename to Desktop/ROMS/TAP/Grange Hill.TAP
diff --git a/Desktop/ROMS/TAP/MANIC.TAP b/Desktop/ROMS/TAP/Manic Miner.TAP
similarity index 100%
rename from Desktop/ROMS/TAP/MANIC.TAP
rename to Desktop/ROMS/TAP/Manic Miner.TAP
diff --git a/Desktop/ROMS/TAP/Treasure Island - Dizzy.tap b/Desktop/ROMS/TAP/Treasure Island - Dizzy.tap
new file mode 100644
index 0000000..43012a7
Binary files /dev/null and b/Desktop/ROMS/TAP/Treasure Island - Dizzy.tap differ