From 6a8a5aa41ecca9e5571e936157a2dcda60bed8ff Mon Sep 17 00:00:00 2001 From: saxxonpike Date: Wed, 1 Jan 2025 11:04:22 -0600 Subject: [PATCH] [C64] Move SaveRam implementation to its own partial --- .../Commodore64/Serial/Drive1541.SaveRam.cs | 103 ++++++++++++++++++ .../Computers/Commodore64/Serial/Drive1541.cs | 95 +--------------- 2 files changed, 104 insertions(+), 94 deletions(-) create mode 100644 src/BizHawk.Emulation.Cores/Computers/Commodore64/Serial/Drive1541.SaveRam.cs diff --git a/src/BizHawk.Emulation.Cores/Computers/Commodore64/Serial/Drive1541.SaveRam.cs b/src/BizHawk.Emulation.Cores/Computers/Commodore64/Serial/Drive1541.SaveRam.cs new file mode 100644 index 0000000000..6786ffc72c --- /dev/null +++ b/src/BizHawk.Emulation.Cores/Computers/Commodore64/Serial/Drive1541.SaveRam.cs @@ -0,0 +1,103 @@ +using System.IO; + +using BizHawk.Common; +using BizHawk.Emulation.Common; + +namespace BizHawk.Emulation.Cores.Computers.Commodore64.Serial; + +public sealed partial class Drive1541 : ISaveRam +{ + // ISaveRam implementation + + // this is some extra state used to keep savestate size down, as most tracks don't get used + // we keep it here for all disks as we need to remember it when swapping disks around + // _usedDiskTracks.Length also doubles as a way to remember the disk count + private bool[][] _usedDiskTracks; + private byte[,][] _diskDeltas; + private readonly Func _getCurrentDiskNumber; + + public void InitSaveRam(int diskCount) + { + _usedDiskTracks = new bool[diskCount][]; + _diskDeltas = new byte[diskCount, 84][]; + for (var i = 0; i < diskCount; i++) + { + _usedDiskTracks[i] = new bool[84]; + } + } + + public bool SaveRamModified => true; + + public byte[] CloneSaveRam() + { + SaveDeltas(); // update the current deltas + + using var ms = new MemoryStream(); + using var bw = new BinaryWriter(ms); + bw.Write(_usedDiskTracks.Length); + for (var i = 0; i < _usedDiskTracks.Length; i++) + { + bw.WriteByteBuffer(_usedDiskTracks[i] + .ToUByteBuffer()); + for (var j = 0; j < 84; j++) + { + bw.WriteByteBuffer(_diskDeltas[i, j]); + } + } + + return ms.ToArray(); + } + + public void StoreSaveRam(byte[] data) + { + using var ms = new MemoryStream(data, false); + using var br = new BinaryReader(ms); + + var ndisks = br.ReadInt32(); + if (ndisks != _usedDiskTracks.Length) + { + throw new InvalidOperationException("Disk count mismatch!"); + } + + ResetDeltas(); + + for (var i = 0; i < _usedDiskTracks.Length; i++) + { + _usedDiskTracks[i] = br.ReadByteBuffer(returnNull: false)!.ToBoolBuffer(); + for (var j = 0; j < 84; j++) + { + _diskDeltas[i, j] = br.ReadByteBuffer(returnNull: true); + } + } + + _disk?.AttachTracker(_usedDiskTracks[_getCurrentDiskNumber()]); + LoadDeltas(); // load up new deltas + _usedDiskTracks[_getCurrentDiskNumber()][_trackNumber] = true; // make sure this gets set to true now + } + + public void SaveDeltas() + { + _disk?.DeltaUpdate((tracknum, original, current) => + { + _diskDeltas[_getCurrentDiskNumber(), tracknum] = DeltaSerializer.GetDelta(original, current) + .ToArray(); + }); + } + + public void LoadDeltas() + { + _disk?.DeltaUpdate((tracknum, original, current) => + { + DeltaSerializer.ApplyDelta(original, current, _diskDeltas[_getCurrentDiskNumber(), tracknum]); + }); + } + + private void ResetDeltas() + { + _disk?.DeltaUpdate(static (_, original, current) => + { + original.AsSpan() + .CopyTo(current); + }); + } +} diff --git a/src/BizHawk.Emulation.Cores/Computers/Commodore64/Serial/Drive1541.cs b/src/BizHawk.Emulation.Cores/Computers/Commodore64/Serial/Drive1541.cs index 129f496a0a..b9aaa241f3 100644 --- a/src/BizHawk.Emulation.Cores/Computers/Commodore64/Serial/Drive1541.cs +++ b/src/BizHawk.Emulation.Cores/Computers/Commodore64/Serial/Drive1541.cs @@ -1,14 +1,11 @@ -using System.IO; - using BizHawk.Common; -using BizHawk.Emulation.Common; using BizHawk.Emulation.Cores.Components.M6502; using BizHawk.Emulation.Cores.Computers.Commodore64.Media; using BizHawk.Emulation.Cores.Computers.Commodore64.MOS; namespace BizHawk.Emulation.Cores.Computers.Commodore64.Serial { - public sealed partial class Drive1541 : SerialPortDevice, ISaveRam + public sealed partial class Drive1541 : SerialPortDevice { private Disk _disk; private int _bitHistory; @@ -258,95 +255,5 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.Serial _diskBits = 0; } - // ISaveRam implementation - - // this is some extra state used to keep savestate size down, as most tracks don't get used - // we keep it here for all disks as we need to remember it when swapping disks around - // _usedDiskTracks.Length also doubles as a way to remember the disk count - private bool[][] _usedDiskTracks; - private byte[,][] _diskDeltas; - private readonly Func _getCurrentDiskNumber; - - public void InitSaveRam(int diskCount) - { - _usedDiskTracks = new bool[diskCount][]; - _diskDeltas = new byte[diskCount, 84][]; - for (var i = 0; i < diskCount; i++) - { - _usedDiskTracks[i] = new bool[84]; - } - } - - public bool SaveRamModified => true; - - public byte[] CloneSaveRam() - { - SaveDeltas(); // update the current deltas - - using var ms = new MemoryStream(); - using var bw = new BinaryWriter(ms); - bw.Write(_usedDiskTracks.Length); - for (var i = 0; i < _usedDiskTracks.Length; i++) - { - bw.WriteByteBuffer(_usedDiskTracks[i].ToUByteBuffer()); - for (var j = 0; j < 84; j++) - { - bw.WriteByteBuffer(_diskDeltas[i, j]); - } - } - - return ms.ToArray(); - } - - public void StoreSaveRam(byte[] data) - { - using var ms = new MemoryStream(data, false); - using var br = new BinaryReader(ms); - - var ndisks = br.ReadInt32(); - if (ndisks != _usedDiskTracks.Length) - { - throw new InvalidOperationException("Disk count mismatch!"); - } - - ResetDeltas(); - - for (var i = 0; i < _usedDiskTracks.Length; i++) - { - _usedDiskTracks[i] = br.ReadByteBuffer(returnNull: false)!.ToBoolBuffer(); - for (var j = 0; j < 84; j++) - { - _diskDeltas[i, j] = br.ReadByteBuffer(returnNull: true); - } - } - - _disk?.AttachTracker(_usedDiskTracks[_getCurrentDiskNumber()]); - LoadDeltas(); // load up new deltas - _usedDiskTracks[_getCurrentDiskNumber()][_trackNumber] = true; // make sure this gets set to true now - } - - public void SaveDeltas() - { - _disk?.DeltaUpdate((tracknum, original, current) => - { - _diskDeltas[_getCurrentDiskNumber(), tracknum] = DeltaSerializer.GetDelta(original, current).ToArray(); - }); - } - - public void LoadDeltas() - { - _disk?.DeltaUpdate((tracknum, original, current) => - { - DeltaSerializer.ApplyDelta(original, current, _diskDeltas[_getCurrentDiskNumber(), tracknum]); - }); - } - - private void ResetDeltas() - { - _disk?.DeltaUpdate(static (_, original, current) => - { - original.AsSpan().CopyTo(current); - }); - } } }