Added Snapshot save feature
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user