From 33ad336b6add5b12bbb176ad16d8e44ac46b497c Mon Sep 17 00:00:00 2001 From: adelikat Date: Sat, 22 Feb 2020 09:53:56 -0600 Subject: [PATCH] Apple II - refactor states to use Serializer (#1859) * apple II - poc to redo binary states to use the Serializer and pass it into virtu * virtu - savestate logic for Video * AppleII - serialize more components with AppleSerializer * cleanup * refactor MachineEvents to store delegates to call and have the calling code interact with an enum, prep work for serializing this class * apple II - first attempt at serializing Machine events * cleanup * add isvblank to savestates * put more things in savestates, cleanup * cleanup * cleanup, save more things * cleanup, fixes * cleanup, save more things * virtu - savestate fixes * cleanup * save CurrentDisk in savestates --- .../Computers/AppleII/AppleII.IEmulator.cs | 3 +- .../AppleII/AppleII.IInputPollable.cs | 7 +- .../Computers/AppleII/AppleII.IStatable.cs | 196 +++------- .../Computers/AppleII/AppleII.cs | 10 +- .../Computers/AppleII/Components.cs | 22 +- .../Computers/AppleII/JsonConvert.cs | 334 ------------------ .../Computers/AppleII/LBSON.cs | 238 ------------- ExternalCoreProjects/Virtu/Cpu.Data.cs | 43 ++- ExternalCoreProjects/Virtu/Cpu.cs | 49 +-- ExternalCoreProjects/Virtu/Disk525.cs | 16 +- ExternalCoreProjects/Virtu/DiskDsk.cs | 34 +- .../Virtu/DiskIIController.cs | 61 ++-- ExternalCoreProjects/Virtu/DiskIIDrive.cs | 46 +-- ExternalCoreProjects/Virtu/DiskNib.cs | 3 - .../Virtu/IComponentSerializer.cs | 17 + ExternalCoreProjects/Virtu/Keyboard.cs | 9 +- ExternalCoreProjects/Virtu/MachineEvents.cs | 96 +++-- ExternalCoreProjects/Virtu/Memory.Data.cs | 4 +- ExternalCoreProjects/Virtu/Memory.cs | 108 +++--- ExternalCoreProjects/Virtu/NoSlotClock.cs | 31 +- ExternalCoreProjects/Virtu/Speaker.cs | 67 ++-- ExternalCoreProjects/Virtu/Video.Data.cs | 3 +- ExternalCoreProjects/Virtu/Video.cs | 179 +++++----- ExternalCoreProjects/Virtu/Virtu.csproj | 4 +- .../Virtu/Virtu.sln.DotSettings | 1 + References/Virtu.dll | Bin 139264 -> 141824 bytes 26 files changed, 533 insertions(+), 1048 deletions(-) delete mode 100644 BizHawk.Emulation.Cores/Computers/AppleII/JsonConvert.cs delete mode 100644 BizHawk.Emulation.Cores/Computers/AppleII/LBSON.cs create mode 100644 ExternalCoreProjects/Virtu/IComponentSerializer.cs diff --git a/BizHawk.Emulation.Cores/Computers/AppleII/AppleII.IEmulator.cs b/BizHawk.Emulation.Cores/Computers/AppleII/AppleII.IEmulator.cs index 9e871c553b..48eed6610b 100644 --- a/BizHawk.Emulation.Cores/Computers/AppleII/AppleII.IEmulator.cs +++ b/BizHawk.Emulation.Cores/Computers/AppleII/AppleII.IEmulator.cs @@ -8,7 +8,8 @@ namespace BizHawk.Emulation.Cores.Computers.AppleII public ControllerDefinition ControllerDefinition => AppleIIController; - public int Frame { get; private set; } + private int _frame; + public int Frame { get => _frame; set => _frame = value; } public string SystemId => "AppleII"; diff --git a/BizHawk.Emulation.Cores/Computers/AppleII/AppleII.IInputPollable.cs b/BizHawk.Emulation.Cores/Computers/AppleII/AppleII.IInputPollable.cs index 11f71559f8..34ad51858d 100644 --- a/BizHawk.Emulation.Cores/Computers/AppleII/AppleII.IInputPollable.cs +++ b/BizHawk.Emulation.Cores/Computers/AppleII/AppleII.IInputPollable.cs @@ -4,7 +4,12 @@ namespace BizHawk.Emulation.Cores.Computers.AppleII { public partial class AppleII : IInputPollable { - public int LagCount { get; set; } + private int _lagcount; + public int LagCount + { + get => _lagcount; + set => _lagcount = value; + } public bool IsLagFrame { diff --git a/BizHawk.Emulation.Cores/Computers/AppleII/AppleII.IStatable.cs b/BizHawk.Emulation.Cores/Computers/AppleII/AppleII.IStatable.cs index e6efc269d3..d02f1fccd1 100644 --- a/BizHawk.Emulation.Cores/Computers/AppleII/AppleII.IStatable.cs +++ b/BizHawk.Emulation.Cores/Computers/AppleII/AppleII.IStatable.cs @@ -1,181 +1,97 @@ -using System; -using System.IO; - +using System.IO; +using BizHawk.Common; using BizHawk.Emulation.Common; using Jellyfish.Virtu; -using Newtonsoft.Json; -using Newtonsoft.Json.Serialization; namespace BizHawk.Emulation.Cores.Computers.AppleII { public partial class AppleII : ITextStatable { - private class CoreConverter : JsonConverter - { - public override bool CanConvert(Type objectType) - { - return objectType == typeof(Components); - } - - public override bool CanRead => true; - - public override bool CanWrite => false; - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - return CreateSerializer().Deserialize(reader); - } - - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - throw new NotImplementedException(); - } - } - - private void SerializeEverything(JsonWriter w) - { - // this is much faster than other possibilities for serialization - w.WriteStartObject(); - w.WritePropertyName(nameof(Frame)); - w.WriteValue(Frame); - w.WritePropertyName(nameof(LagCount)); - w.WriteValue(LagCount); - w.WritePropertyName(nameof(IsLagFrame)); - w.WriteValue(IsLagFrame); - w.WritePropertyName(nameof(CurrentDisk)); - w.WriteValue(CurrentDisk); - w.WritePropertyName("PreviousDiskPressed"); - w.WriteValue(_prevPressed); - w.WritePropertyName("NextDiskPressed"); - w.WriteValue(_nextPressed); - w.WritePropertyName("Core"); - CreateSerializer().Serialize(w, _machine); - w.WriteEndObject(); - } - - private void DeserializeEverything(JsonReader r) - { - var o = (OtherData)_ser.Deserialize(r, typeof(OtherData)); - Frame = o.Frame; - LagCount = o.LagCount; - IsLagFrame = o.IsLagFrame; - CurrentDisk = o.CurrentDisk; - _machine = o.Core; - _prevPressed = o.PreviousDiskPressed; - _nextPressed = o.NextDiskPressed; - - // since _machine was replaced, we need to reload settings from frontend - PutSettings(_settings); - } - - public class OtherData - { - public int Frame; - public int LagCount; - public bool IsLagFrame; - public int CurrentDisk; - public bool PreviousDiskPressed; - public bool NextDiskPressed; - public Components Core; - } - - private void InitSaveStates() - { - _ser.Converters.Add(new CoreConverter()); - } - - private readonly JsonSerializer _ser = new JsonSerializer(); - public void SaveStateText(TextWriter writer) { - SerializeEverything(new JsonTextWriter(writer) { Formatting = Formatting.None }); + SyncState(new AppleSerializer(writer)); } public void LoadStateText(TextReader reader) { - DeserializeEverything(new JsonTextReader(reader)); + SyncState(new AppleSerializer(reader)); } - /* - * These are horrible; the LoadStateBinary() takes over 10x as long as LoadStateText() - * Until we figure out why JSON.NET's BSONwriter sucks and how to fix it, stick with text-as-binary public void SaveStateBinary(BinaryWriter writer) { - SerializeEverything(new BsonWriter(writer)); + SyncState(new AppleSerializer(writer)); } public void LoadStateBinary(BinaryReader reader) { - DeserializeEverything(new BsonReader(reader)); - } - */ - /* - public void SaveStateBinary(BinaryWriter writer) - { - var tw = new StreamWriter(writer.BaseStream, new System.Text.UTF8Encoding(false)); - SaveStateText(tw); - tw.Flush(); - } - - public void LoadStateBinary(BinaryReader reader) - { - var tr = new StreamReader(reader.BaseStream, System.Text.Encoding.UTF8); - LoadStateText(tr); - }*/ - - // these homemade classes edge out the stock ones slightly, but need BufferedStream to not be bad - public void SaveStateBinary(BinaryWriter writer) - { - var buffer = new BufferedStream(writer.BaseStream, 16384); - var bw2 = new BinaryWriter(buffer); - SerializeEverything(new LBW(bw2)); - bw2.Flush(); - buffer.Flush(); - } - - public void LoadStateBinary(BinaryReader reader) - { - var buffer = new BufferedStream(reader.BaseStream, 16384); - var br2 = new BinaryReader(buffer); - DeserializeEverything(new LBR(br2)); + SyncState(new AppleSerializer(reader)); } public byte[] SaveStateBinary() { // our savestate array can be of varying sizes, so this can't be too clever - var stream = new MemoryStream(); - var writer = new BinaryWriter(stream); + using var stream = new MemoryStream(); + using var writer = new BinaryWriter(stream); SaveStateBinary(writer); writer.Flush(); return stream.ToArray(); } - private static JsonSerializer CreateSerializer() + private void SyncState(AppleSerializer ser) { - // TODO: converters could be cached for speedup + int version = 2; + ser.BeginSection(nameof(AppleII)); + ser.Sync(nameof(version), ref version); + ser.Sync("Frame", ref _frame); + ser.Sync("Lag", ref _lagcount); + ser.Sync("PrevDiskPressed", ref _prevPressed); + ser.Sync("NextDiskPressed", ref _nextPressed); + ser.Sync("CurrentDisk", ref _currentDisk); - var ser = new JsonSerializer + ser.BeginSection("Events"); + _machine.Events.Sync(ser); + ser.EndSection(); + + ser.BeginSection("Cpu"); + _machine.Cpu.Sync(ser); + ser.EndSection(); + + ser.BeginSection("Video"); + _machine.Video.Sync(ser); + ser.EndSection(); + + ser.BeginSection("Memory"); + _machine.Memory.Sync(ser); + ser.EndSection(); + + ser.BeginSection("NoSlotClock"); + _machine.NoSlotClock.Sync(ser); + ser.EndSection(); + + ser.BeginSection("DiskIIController"); + _machine.DiskIIController.Sync(ser); + ser.EndSection(); + + ser.EndSection(); + } + + public class AppleSerializer : Serializer, IComponentSerializer + { + public AppleSerializer(BinaryReader br) : base(br) { - TypeNameHandling = TypeNameHandling.Auto, - PreserveReferencesHandling = PreserveReferencesHandling.All, // leaving out Array is a very important problem, and means that we can't rely on a directly shared array to work. - ReferenceLoopHandling = ReferenceLoopHandling.Serialize, - }; + } - ser.Converters.Add(new TypeTypeConverter(new[] + public AppleSerializer(BinaryWriter bw) : base(bw) { - // all expected Types to convert are either in this assembly or mscorlib - typeof(Memory).Assembly, - typeof(object).Assembly - })); + } - ser.Converters.Add(new DelegateConverter()); - ser.Converters.Add(new ArrayConverter()); + public AppleSerializer(TextReader tr) : base(tr) + { + } - var cr = new DefaultContractResolver(); - cr.DefaultMembersSearchFlags |= System.Reflection.BindingFlags.NonPublic; - ser.ContractResolver = cr; - - return ser; + public AppleSerializer(TextWriter tw) : base(tw) + { + } } } } diff --git a/BizHawk.Emulation.Cores/Computers/AppleII/AppleII.cs b/BizHawk.Emulation.Cores/Computers/AppleII/AppleII.cs index b5ed1872a8..6ddf214cb7 100644 --- a/BizHawk.Emulation.Cores/Computers/AppleII/AppleII.cs +++ b/BizHawk.Emulation.Cores/Computers/AppleII/AppleII.cs @@ -57,7 +57,6 @@ namespace BizHawk.Emulation.Cores.Computers.AppleII SetCallbacks(); - InitSaveStates(); SetupMemoryDomains(); PutSettings(settings ?? new Settings()); } @@ -72,7 +71,14 @@ namespace BizHawk.Emulation.Cores.Computers.AppleII private readonly byte[] _appleIIRom; private readonly byte[] _diskIIRom; - public int CurrentDisk { get; private set; } + private int _currentDisk; + + public int CurrentDisk + { + get => _currentDisk; + set => _currentDisk = value; + } + public int DiskCount => _romSet.Count; public void SetDisk(int discNum) diff --git a/BizHawk.Emulation.Cores/Computers/AppleII/Components.cs b/BizHawk.Emulation.Cores/Computers/AppleII/Components.cs index fec8a94e2d..6a7ae54a3c 100644 --- a/BizHawk.Emulation.Cores/Computers/AppleII/Components.cs +++ b/BizHawk.Emulation.Cores/Computers/AppleII/Components.cs @@ -7,11 +7,6 @@ namespace BizHawk.Emulation.Cores.Computers.AppleII /// public sealed class Components { - /// - /// for deserialization only!! - /// - public Components() { } - public Components(byte[] appleIIe, byte[] diskIIRom) { Events = new MachineEvents(); @@ -19,6 +14,9 @@ namespace BizHawk.Emulation.Cores.Computers.AppleII Cpu = new Cpu(Memory); Video = new Video(Events, Memory); + NoSlotClock = new NoSlotClock(Video); + DiskIIController = new DiskIIController(Video, diskIIRom); + var emptySlot = new EmptyPeripheralCard(Video); // Necessary because of tangling dependencies between memory and video classes @@ -28,7 +26,7 @@ namespace BizHawk.Emulation.Cores.Computers.AppleII new EmptyCassetteComponent(), new Speaker(Events, Cpu), Video, - new NoSlotClock(Video), + NoSlotClock, emptySlot, emptySlot, emptySlot, @@ -42,9 +40,13 @@ namespace BizHawk.Emulation.Cores.Computers.AppleII Video.Reset(); } - public MachineEvents Events { get; set; } - public Memory Memory { get; private set; } - public Cpu Cpu { get; private set; } - public Video Video { get; private set; } + public MachineEvents Events { get; } + public Memory Memory { get; } + public Cpu Cpu { get; } + public Video Video { get; } + + // Only needed for convenience of savestate syncing, else the memory component needs to do it + public NoSlotClock NoSlotClock { get; } + public DiskIIController DiskIIController { get; } } } diff --git a/BizHawk.Emulation.Cores/Computers/AppleII/JsonConvert.cs b/BizHawk.Emulation.Cores/Computers/AppleII/JsonConvert.cs deleted file mode 100644 index 40c9b0e4a5..0000000000 --- a/BizHawk.Emulation.Cores/Computers/AppleII/JsonConvert.cs +++ /dev/null @@ -1,334 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using Newtonsoft.Json; - -namespace BizHawk.Emulation.Cores.Computers.AppleII -{ - public class ArrayConverter : JsonConverter - { - // JSON.NET cannot, when reading, use PreserveReferencesHandling on arrays, although it fully supports it on writing. - // Doing so while being able to fully preserve circular references would require storing the length of the array, - // or reading ahead in the JSON to compute the length. For arrays that could contain reference types, we choose the latter. - // For arrays of primitive types, there is no issue. - - // TODO: on serialization, the type of the object is available, but is the expected type (ie, the one that we'll be fed during deserialization) available? - // need this to at least detect covariance cases... - - public override bool CanConvert(Type objectType) - { - if (!typeof(Array).IsAssignableFrom(objectType)) - { - return false; - } - - if (objectType.GetArrayRank() > 1) - { - throw new NotImplementedException(); - } - - return true; - } - - public override bool CanRead => true; - public override bool CanWrite => true; - - private readonly JsonSerializer _bareSerializer = new JsonSerializer(); // full default settings, separate context - - // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local - private static void ReadExpectType(JsonReader reader, JsonToken expected) - { - if (!reader.Read()) - { - throw new InvalidOperationException(); - } - - if (reader.TokenType != expected) - { - throw new InvalidOperationException(); - } - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - if (reader.TokenType == JsonToken.Null) - { - return null; - } - - if (reader.TokenType != JsonToken.StartObject) - { - throw new InvalidOperationException(); - } - - ReadExpectType(reader, JsonToken.PropertyName); - string prop = reader.Value.ToString(); - ReadExpectType(reader, JsonToken.String); - string id = reader.Value.ToString(); - if (prop == "$ref") - { - object ret = serializer.ReferenceResolver.ResolveReference(serializer, id); - ReadExpectType(reader, JsonToken.EndObject); - return ret; - } - - if (prop == "$id") - { - ReadExpectType(reader, JsonToken.PropertyName); - prop = reader.Value.ToString(); - if (prop == "$length") // complex array - { - ReadExpectType(reader, JsonToken.Integer); - int length = Convert.ToInt32(reader.Value); - ReadExpectType(reader, JsonToken.PropertyName); - if (reader.Value.ToString() != "$values") - throw new InvalidOperationException(); - - Type elementType = objectType.GetElementType(); - - // ReSharper disable once AssignNullToNotNullAttribute - Array ret = Array.CreateInstance(elementType, length); - - // must register reference before deserializing elements to handle possible circular references - serializer.ReferenceResolver.AddReference(serializer, id, ret); - int index = 0; - - ReadExpectType(reader, JsonToken.StartArray); - while (true) - { - if (!reader.Read()) - throw new InvalidOperationException(); - if (reader.TokenType == JsonToken.EndArray) - break; - ret.SetValue(serializer.Deserialize(reader, elementType), index++); - } - ReadExpectType(reader, JsonToken.EndObject); - return ret; - } - - if (prop == "$values") // simple array - { - if (!reader.Read()) - { - throw new InvalidOperationException(); - } - - object ret = _bareSerializer.Deserialize(reader, objectType); - - // OK to add this after deserializing, as arrays of primitive types can't contain backrefs - serializer.ReferenceResolver.AddReference(serializer, id, ret); - ReadExpectType(reader, JsonToken.EndObject); - return ret; - } - - throw new InvalidOperationException(); - } - - throw new InvalidOperationException(); - } - - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - if (serializer.ReferenceResolver.IsReferenced(serializer, value)) - { - writer.WriteStartObject(); - - writer.WritePropertyName("$ref"); - writer.WriteValue(serializer.ReferenceResolver.GetReference(serializer, value)); - - writer.WriteEndObject(); - } - else - { - writer.WriteStartObject(); - - writer.WritePropertyName("$id"); - writer.WriteValue(serializer.ReferenceResolver.GetReference(serializer, value)); - - var elementType = value.GetType().GetElementType(); - if (elementType?.IsPrimitive ?? false) - { - writer.WritePropertyName("$values"); - _bareSerializer.Serialize(writer, value); - } - else - { - var array = (Array)value; - writer.WritePropertyName("$length"); - writer.WriteValue(array.Length); - - writer.WritePropertyName("$values"); - writer.WriteStartArray(); - foreach (object o in array) - { - serializer.Serialize(writer, o, elementType); - } - - writer.WriteEndArray(); - } - - writer.WriteEndObject(); - } - } - } - - public class TypeTypeConverter : JsonConverter - { - // serialize and deserialize types, ignoring assembly entirely and only using namespace+typename - // all types, including generic type arguments to supplied types, must be in one of the declared assemblies (only checked on read!) - // the main goal here is to have something with a slight chance of working across versions - public TypeTypeConverter(IEnumerable ass) - { - _assemblies = ass.ToList(); - } - - private readonly List _assemblies; - private readonly Dictionary _readLookup = new Dictionary(); - - public override bool CanConvert(Type objectType) - { - return typeof(Type).IsAssignableFrom(objectType); - } - - public override bool CanRead => true; - public override bool CanWrite => true; - - private Type GetType(string name) - { - if (!_readLookup.TryGetValue(name, out var ret)) - { - ret = _assemblies.Select(ass => ass.GetType(name, false)).Single(t => t != null); - _readLookup.Add(name, ret); - } - - return ret; - } - - private static string GetName(Type type) - { - return $"{type.Namespace}.{type.Name}"; - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - if (reader.TokenType == JsonToken.Null) - { - return null; - } - - if (reader.TokenType == JsonToken.String) - { - return GetType(reader.Value.ToString()); - } - - if (reader.TokenType == JsonToken.StartArray) // full generic - { - List values = serializer.Deserialize>(reader); - return GetType(values[0]).MakeGenericType(values.Skip(1).Select(GetType).ToArray()); - } - - throw new InvalidOperationException(); - } - - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - var type = (Type)value; - if (type.IsGenericType && !type.IsGenericTypeDefinition) - { - writer.WriteStartArray(); - writer.WriteValue(GetName(type)); - foreach (var t in type.GetGenericArguments()) - { - writer.WriteValue(GetName(t)); - } - writer.WriteEndArray(); - } - else - { - writer.WriteValue(GetName(type)); - } - } - } - - public class DelegateConverter : JsonConverter - { - // caveats: if used on anonymous delegates and/or closures, brittle to name changes in the generated classes and methods - // brittle to type name changes in general - // must be serialized in tree with any real classes referred to by closures - - // CAN NOT preserve reference equality of the delegates themselves, because the delegate must be created with - // target in one shot, with no possibility to change the target later. We preserve references to targets, - // and lose the ability to preserve references to delegates. - - - // TODO: much of this could be made somewhat smarter and more resilient - - public override bool CanConvert(Type objectType) - { - return typeof(Delegate).IsAssignableFrom(objectType); - } - - public override bool CanRead => true; - public override bool CanWrite => true; - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - var slug = serializer.Deserialize(reader); - return slug?.GetDelegate(); - } - - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - var slug = new Slug((Delegate)value); - serializer.Serialize(writer, slug); - } - - private class Slug - { - // ReSharper disable once MemberCanBePrivate.Local - // ReSharper disable once FieldCanBeMadeReadOnly.Local - public Type DelegateType; - - // ReSharper disable once MemberCanBePrivate.Local - // ReSharper disable once FieldCanBeMadeReadOnly.Local - public Type MethodDeclaringType; - - // ReSharper disable once MemberCanBePrivate.Local - // ReSharper disable once FieldCanBeMadeReadOnly.Local - public string MethodName; - - // ReSharper disable once MemberCanBePrivate.Local - // ReSharper disable once FieldCanBeMadeReadOnly.Local - public List MethodParameters; - - // ReSharper disable once MemberCanBePrivate.Local - // ReSharper disable once FieldCanBeMadeReadOnly.Local - public object Target; - - public Delegate GetDelegate() - { - var mi = MethodDeclaringType.GetMethod( - MethodName, - BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static, - null, - MethodParameters.ToArray(), - null); - - // ReSharper disable once AssignNullToNotNullAttribute - return Delegate.CreateDelegate(DelegateType, Target, mi); - } - - public Slug() { } - - public Slug(Delegate d) - { - DelegateType = d.GetType(); - MethodDeclaringType = d.Method.DeclaringType; - MethodName = d.Method.Name; - MethodParameters = d.Method.GetParameters().Select(p => p.ParameterType).ToList(); - Target = d.Target; - } - } - } -} diff --git a/BizHawk.Emulation.Cores/Computers/AppleII/LBSON.cs b/BizHawk.Emulation.Cores/Computers/AppleII/LBSON.cs deleted file mode 100644 index d2895b8802..0000000000 --- a/BizHawk.Emulation.Cores/Computers/AppleII/LBSON.cs +++ /dev/null @@ -1,238 +0,0 @@ -using System; -using System.IO; - -using Newtonsoft.Json; - -namespace BizHawk.Emulation.Cores.Computers.AppleII -{ - // barebones classes for writing and reading a simple bson-like format, used to gain a bit of speed in Apple II savestates - internal enum LBTOK : byte - { - Null, - Undefined, - StartArray, - EndArray, - StartObject, - EndObject, - Property, - S8, - U8, - S16, - U16, - S32, - U32, - S64, - U64, - False, - True, - String, - F32, - F64, - ByteArray, - } - - public class LBR : JsonReader - { - private readonly BinaryReader _r; - private object _v; - private JsonToken _t; - - public LBR(BinaryReader reader) - { - _r = reader; - } - - public override void Close() - { - } - - // as best as I can tell, the serializers refer to depth, but don't actually need to work except when doing certain error recovery - public override int Depth => 0; - - public override string Path => throw new NotImplementedException(); - - public override Type ValueType => _v?.GetType(); - - public override JsonToken TokenType => _t; - - public override object Value => _v; - - public override bool Read() - { - LBTOK l = (LBTOK)_r.ReadByte(); - switch (l) - { - case LBTOK.StartArray: _t = JsonToken.StartArray; _v = null; break; - case LBTOK.EndArray: _t = JsonToken.EndArray; _v = null; break; - case LBTOK.StartObject: _t = JsonToken.StartObject; _v = null; break; - case LBTOK.EndObject: _t = JsonToken.EndObject; _v = null; break; - case LBTOK.Null: _t = JsonToken.Null; _v = null; break; - case LBTOK.False: _t = JsonToken.Boolean; _v = false; break; - case LBTOK.True: _t = JsonToken.Boolean; _v = true; break; - case LBTOK.Property: _t = JsonToken.PropertyName; _v = _r.ReadString(); break; - case LBTOK.Undefined: _t = JsonToken.Undefined; _v = null; break; - case LBTOK.S8: _t = JsonToken.Integer; _v = _r.ReadSByte(); break; - case LBTOK.U8: _t = JsonToken.Integer; _v = _r.ReadByte(); break; - case LBTOK.S16: _t = JsonToken.Integer; _v = _r.ReadInt16(); break; - case LBTOK.U16: _t = JsonToken.Integer; _v = _r.ReadUInt16(); break; - case LBTOK.S32: _t = JsonToken.Integer; _v = _r.ReadInt32(); break; - case LBTOK.U32: _t = JsonToken.Integer; _v = _r.ReadUInt32(); break; - case LBTOK.S64: _t = JsonToken.Integer; _v = _r.ReadInt64(); break; - case LBTOK.U64: _t = JsonToken.Integer; _v = _r.ReadUInt64(); break; - case LBTOK.String: _t = JsonToken.String; _v = _r.ReadString(); break; - case LBTOK.F32: _t = JsonToken.Float; _v = _r.ReadSingle(); break; - case LBTOK.F64: _t = JsonToken.Float; _v = _r.ReadDouble(); break; - case LBTOK.ByteArray: _t = JsonToken.Bytes; _v = _r.ReadBytes(_r.ReadInt32()); break; - - default: - throw new InvalidOperationException(); - } - - return true; - } - - public override byte[] ReadAsBytes() - { - if (!Read() || _t != JsonToken.Bytes) - { - return null; - } - - return (byte[])_v; - } - - public override DateTime? ReadAsDateTime() - { - throw new NotImplementedException(); - } - - public override DateTimeOffset? ReadAsDateTimeOffset() - { - throw new NotImplementedException(); - } - - public override decimal? ReadAsDecimal() - { - throw new NotImplementedException(); - } - - public override int? ReadAsInt32() - { - // TODO: speed this up if needed - if (!Read()) - { - return null; - } - - switch (_t) - { - case JsonToken.Null: - return null; - case JsonToken.Integer: - case JsonToken.Float: - return Convert.ToInt32(_v); - case JsonToken.String: - if (int.TryParse(_v.ToString(), out var i)) - { - return i; - } - - return null; - default: - return null; - } - } - - public override string ReadAsString() - { - if (!Read()) - { - return null; - } - - switch (_t) - { - case JsonToken.Null: - return null; - case JsonToken.Float: - case JsonToken.Integer: - case JsonToken.Boolean: - case JsonToken.String: - return _v.ToString(); - default: - return null; - } - } - } - - public class LBW : JsonWriter - { - private readonly BinaryWriter w; - - private void WT(LBTOK t) - { - w.Write((byte)t); - } - - public LBW(BinaryWriter w) - { - this.w = w; - } - - public override void Flush() - { - w.Flush(); - } - - public override void Close() - { - } - - public override void WriteValue(bool value) { WT(value ? LBTOK.True : LBTOK.False); } - - public override void WriteValue(sbyte value) { WT(LBTOK.S8); w.Write(value); } - public override void WriteValue(byte value) { WT(LBTOK.U8); w.Write(value); } - public override void WriteValue(short value) { WT(LBTOK.S16); w.Write(value); } - public override void WriteValue(ushort value) { WT(LBTOK.U16); w.Write(value); } - public override void WriteValue(int value) { WT(LBTOK.S32); w.Write(value); } - public override void WriteValue(uint value) { WT(LBTOK.U32); w.Write(value); } - public override void WriteValue(long value) { WT(LBTOK.S64); w.Write(value); } - public override void WriteValue(ulong value) { WT(LBTOK.U64); w.Write(value); } - - public override void WriteStartArray() { WT(LBTOK.StartArray); } - public override void WriteEndArray() { WT(LBTOK.EndArray); } - public override void WriteStartObject() { WT(LBTOK.StartObject); } - public override void WriteEndObject() { WT(LBTOK.EndObject); } - public override void WriteNull() { WT(LBTOK.Null); } - public override void WriteUndefined() { WT(LBTOK.Undefined); } - - public override void WriteValue(float value) { WT(LBTOK.F32); w.Write(value); } - public override void WriteValue(double value) { WT(LBTOK.F64); w.Write(value); } - - public override void WriteValue(byte[] value) { WT(LBTOK.ByteArray); w.Write(value.Length); w.Write(value); } - - public override void WriteComment(string text) { throw new NotImplementedException(); } - public override void WriteWhitespace(string ws) { throw new NotImplementedException(); } - protected override void WriteIndent() { throw new NotImplementedException(); } - protected override void WriteIndentSpace() { throw new NotImplementedException(); } - public override void WriteEnd() { throw new NotImplementedException(); } - protected override void WriteEnd(JsonToken token) { throw new NotImplementedException(); } - public override void WriteRaw(string json) { throw new NotImplementedException(); } - public override void WriteRawValue(string json) { throw new NotImplementedException(); } - public override void WriteStartConstructor(string name) { throw new NotImplementedException(); } - public override void WriteEndConstructor() { throw new NotImplementedException(); } - protected override void WriteValueDelimiter() { throw new NotImplementedException(); } - - public override void WritePropertyName(string name) { WT(LBTOK.Property); w.Write(name); } - public override void WriteValue(string value) { WT(LBTOK.String); w.Write(value); } - public override void WritePropertyName(string name, bool escape) { WT(LBTOK.Property); w.Write(name); } // no escaping required - - public override void WriteValue(char value) { throw new NotImplementedException(); } - public override void WriteValue(DateTime value) { throw new NotImplementedException(); } - public override void WriteValue(DateTimeOffset value) { throw new NotImplementedException(); } - public override void WriteValue(decimal value) { throw new NotImplementedException(); } - public override void WriteValue(Guid value) { throw new NotImplementedException(); } - public override void WriteValue(TimeSpan value) { throw new NotImplementedException(); } - public override void WriteValue(Uri value) { throw new NotImplementedException(); } - } -} diff --git a/ExternalCoreProjects/Virtu/Cpu.Data.cs b/ExternalCoreProjects/Virtu/Cpu.Data.cs index 30bc7deda7..07ac1567eb 100644 --- a/ExternalCoreProjects/Virtu/Cpu.Data.cs +++ b/ExternalCoreProjects/Virtu/Cpu.Data.cs @@ -1,15 +1,50 @@ -using Newtonsoft.Json; -using System; +using System; namespace Jellyfish.Virtu { // ReSharper disable once UnusedMember.Global public partial class Cpu { - [JsonIgnore] + public void Sync(IComponentSerializer ser) + { + ser.Sync(nameof(_is65C02), ref _is65C02); + ser.Sync(nameof(_multiplier), ref _multiplier); + + ser.Sync(nameof(_ra), ref _ra); + ser.Sync(nameof(_rx), ref _rx); + ser.Sync(nameof(_ry), ref _ry); + ser.Sync(nameof(_rs), ref _rs); + ser.Sync(nameof(_rp), ref _rp); + ser.Sync(nameof(_rpc), ref _rpc); + ser.Sync(nameof(_ea), ref _ea); + ser.Sync(nameof(_cc), ref _cc); + ser.Sync(nameof(_opCode), ref _opCode); + ser.Sync(nameof(_cycles), ref _cycles); + + if (!ser.IsReader) + { + // A way to set the action callback + Is65C02 = _is65C02; + } + } + private Action[] _executeOpCode65N02; - [JsonIgnore] private Action[] _executeOpCode65C02; + private Action[] _executeOpCode; + + private bool _is65C02; + private int _multiplier; + + private int _ra; + private int _rx; + private int _ry; + private int _rs; + private int _rp; + private int _rpc; + private int _ea; + private int _cc; + private int _opCode; + private long _cycles; private const int Pc = 0x01; private const int Pz = 0x02; diff --git a/ExternalCoreProjects/Virtu/Cpu.cs b/ExternalCoreProjects/Virtu/Cpu.cs index e824ac6b2e..84d1d00454 100644 --- a/ExternalCoreProjects/Virtu/Cpu.cs +++ b/ExternalCoreProjects/Virtu/Cpu.cs @@ -1,6 +1,5 @@ using System; using System.Globalization; -using Newtonsoft.Json; namespace Jellyfish.Virtu { @@ -13,19 +12,15 @@ namespace Jellyfish.Virtu int Execute(); long Cycles { get; } int Multiplier { get; } + + // ReSharper disable once UnusedMember.Global + void Sync(IComponentSerializer ser); } // ReSharper disable once UnusedMember.Global public sealed partial class Cpu : ICpu { - // ReSharper disable once FieldCanBeMadeReadOnly.Local - private IMemoryBus _memory; - - // ReSharper disable once UnusedMember.Global - public Cpu() - { - InitializeOpCodeDelegates(); - } + private readonly IMemoryBus _memory; public Cpu(IMemoryBus memory) { @@ -3432,29 +3427,22 @@ namespace Jellyfish.Virtu set { _is65C02 = value; _executeOpCode = _is65C02 ? _executeOpCode65C02 : _executeOpCode65N02; } } - public int Multiplier { get; set; } + public int Multiplier { get => _multiplier; private set => _multiplier = value; } - public int RA { get; set; } - public int RX { get; set; } - public int RY { get; set; } - public int RS { get; set; } - public int RP { get; set; } - public int RPC { get; set; } - public int EA { get; private set; } - public int CC { get; private set; } - public int OpCode { get; private set; } - public long Cycles { get; private set; } + public int RA { get => _ra; set => _ra = value; } + public int RX { get => _rx; set => _rx = value; } + public int RY { get => _ry; set => _ry = value; } + public int RS { get => _rs; set => _rs = value; } + public int RP { get => _rp; set => _rp = value; } + public int RPC { get => _rpc; set => _rpc = value; } + public int EA { get => _ea; private set => _ea = value; } + public int CC { get => _cc; private set => _cc = value; } + public int OpCode { get => _opCode; private set => _opCode = value; } + public long Cycles { get => _cycles; private set => _cycles = value; } - [JsonIgnore] - private bool _is65C02; - [JsonIgnore] - private Action[] _executeOpCode; - - [JsonIgnore] public Action TraceCallback; /// Carry Flag - [JsonIgnore] public bool FlagC { get => (RP & 0x01) != 0; @@ -3462,7 +3450,6 @@ namespace Jellyfish.Virtu } /// Zero Flag - [JsonIgnore] public bool FlagZ { get => (RP & 0x02) != 0; @@ -3470,7 +3457,6 @@ namespace Jellyfish.Virtu } /// Interrupt Disable Flag - [JsonIgnore] public bool FlagI { get => (RP & 0x04) != 0; @@ -3478,7 +3464,6 @@ namespace Jellyfish.Virtu } /// Decimal Mode Flag - [JsonIgnore] public bool FlagD { get => (RP & 0x08) != 0; @@ -3486,7 +3471,6 @@ namespace Jellyfish.Virtu } /// Break Flag - [JsonIgnore] public bool FlagB { get => (RP & 0x10) != 0; @@ -3494,7 +3478,6 @@ namespace Jellyfish.Virtu } /// T... Flag - [JsonIgnore] public bool FlagT { get => (RP & 0x20) != 0; @@ -3502,7 +3485,6 @@ namespace Jellyfish.Virtu } /// Overflow Flag - [JsonIgnore] public bool FlagV { get => (RP & 0x40) != 0; @@ -3510,7 +3492,6 @@ namespace Jellyfish.Virtu } /// Negative Flag - [JsonIgnore] public bool FlagN { get => (RP & 0x80) != 0; diff --git a/ExternalCoreProjects/Virtu/Disk525.cs b/ExternalCoreProjects/Virtu/Disk525.cs index 03012e3383..65f22147d3 100644 --- a/ExternalCoreProjects/Virtu/Disk525.cs +++ b/ExternalCoreProjects/Virtu/Disk525.cs @@ -4,9 +4,8 @@ namespace Jellyfish.Virtu { internal abstract class Disk525 { - // ReSharper disable once UnusedMember.Global - // ReSharper disable once PublicConstructorInAbstractClass - public Disk525() { } + protected byte[] Data; + public bool IsWriteProtected; protected Disk525(byte[] data, bool isWriteProtected) { @@ -14,6 +13,12 @@ namespace Jellyfish.Virtu IsWriteProtected = isWriteProtected; } + public virtual void Sync(IComponentSerializer ser) + { + ser.Sync(nameof(Data), ref Data, false); + ser.Sync(nameof(IsWriteProtected), ref IsWriteProtected); + } + public static Disk525 CreateDisk(string name, byte[] data, bool isWriteProtected) { if (name == null) @@ -43,11 +48,6 @@ namespace Jellyfish.Virtu public abstract void ReadTrack(int number, int fraction, byte[] buffer); public abstract void WriteTrack(int number, int fraction, byte[] buffer); - public byte[] Data { get; protected set; } - - // ReSharper disable once AutoPropertyCanBeMadeGetOnly.Local - public bool IsWriteProtected { get; private set; } - public const int SectorCount = 16; public const int SectorSize = 0x100; public const int TrackSize = 0x1A00; diff --git a/ExternalCoreProjects/Virtu/DiskDsk.cs b/ExternalCoreProjects/Virtu/DiskDsk.cs index 95b014fc85..ff60fc1771 100644 --- a/ExternalCoreProjects/Virtu/DiskDsk.cs +++ b/ExternalCoreProjects/Virtu/DiskDsk.cs @@ -2,12 +2,19 @@ namespace Jellyfish.Virtu { + // ReSharper disable once UnusedMember.Global internal enum SectorSkew { None = 0, Dos, ProDos }; internal sealed class DiskDsk : Disk525 { - // ReSharper disable once UnusedMember.Global - public DiskDsk() { } + private const int SecondaryBufferLength = 0x56; + private const int Volume = 0xFE; + + private byte[] _trackBuffer; + private int _trackOffset; + private byte[] _primaryBuffer = new byte[0x100]; + private byte[] _secondaryBuffer = new byte[SecondaryBufferLength + 1]; + private int[] _sectorSkew; public DiskDsk(byte[] data, bool isWriteProtected, SectorSkew sectorSkew) : base(data, isWriteProtected) @@ -15,6 +22,16 @@ namespace Jellyfish.Virtu _sectorSkew = SectorSkewMode[(int)sectorSkew]; } + public override void Sync(IComponentSerializer ser) + { + ser.Sync(nameof(_trackBuffer), ref _trackBuffer, false); + ser.Sync(nameof(_trackOffset), ref _trackOffset); + ser.Sync(nameof(_primaryBuffer), ref _primaryBuffer, false); + ser.Sync(nameof(_secondaryBuffer), ref _secondaryBuffer, false); + ser.Sync(nameof(_sectorSkew), ref _sectorSkew, false); + base.Sync(ser); + } + public override void ReadTrack(int number, int fraction, byte[] buffer) { int track = number / 2; @@ -165,13 +182,12 @@ namespace Jellyfish.Virtu private int ReadNibble44() { - return (((ReadNibble() << 1) | 0x1) & ReadNibble()); + return ((ReadNibble() << 1) | 0x1) & ReadNibble(); } private byte ReadTranslatedNibble() { - byte data = NibbleToByte[ReadNibble()]; - return data; + return NibbleToByte[ReadNibble()]; } private bool ReadDataNibbles(int sectorOffset) @@ -268,14 +284,6 @@ namespace Jellyfish.Virtu WriteNibble(ByteToNibble[a]); // data checksum } - private byte[] _trackBuffer; - private int _trackOffset; - private byte[] _primaryBuffer = new byte[0x100]; - private const int SecondaryBufferLength = 0x56; - private byte[] _secondaryBuffer = new byte[SecondaryBufferLength + 1]; - private int[] _sectorSkew; - private const int Volume = 0xFE; - private static readonly byte[] SwapBits = { 0, 2, 1, 3 }; private static readonly int[] SectorSkewNone = diff --git a/ExternalCoreProjects/Virtu/DiskIIController.cs b/ExternalCoreProjects/Virtu/DiskIIController.cs index 138d4bad01..0275bdc836 100644 --- a/ExternalCoreProjects/Virtu/DiskIIController.cs +++ b/ExternalCoreProjects/Virtu/DiskIIController.cs @@ -8,16 +8,26 @@ namespace Jellyfish.Virtu // ReSharper disable once UnusedMemberInSuper.Global DiskIIDrive Drive1 { get; } + + // ReSharper disable once UnusedMember.Global + void Sync(IComponentSerializer ser); } // ReSharper disable once UnusedMember.Global public sealed class DiskIIController : IDiskIIController { - // ReSharper disable once FieldCanBeMadeReadOnly.Local - private IVideo _video; + private const int Phase1On = 1 << 1; + private readonly IVideo _video; + private readonly byte[] _romRegionC1C7; - // ReSharper disable once UnusedMember.Global - public DiskIIController() { } + private bool _driveLight; + private int _latch; + private int _phaseStates; + private bool _motorOn; + private int _driveNumber; + private bool _loadMode; + private bool _writeMode; + private bool _driveSpin; public DiskIIController(IVideo video, byte[] diskIIRom) { @@ -32,8 +42,30 @@ namespace Jellyfish.Virtu _writeMode = false; } - public bool DriveLight { get; set; } + public DiskIIDrive Drive1 { get; } + public DiskIIDrive Drive2 { get; } + public bool DriveLight + { + get => _driveLight; + set => _driveLight = value; + } + + public void Sync(IComponentSerializer ser) + { + ser.Sync(nameof(_driveLight), ref _driveLight); + + ser.Sync(nameof(_latch), ref _latch); + ser.Sync(nameof(_phaseStates), ref _phaseStates); + ser.Sync(nameof(_motorOn), ref _motorOn); + ser.Sync(nameof(_driveNumber), ref _driveNumber); + ser.Sync(nameof(_loadMode), ref _loadMode); + ser.Sync(nameof(_writeMode), ref _writeMode); + ser.Sync(nameof(_driveSpin), ref _driveSpin); + + Drive1.Sync(ser); + Drive2.Sync(ser); + } public IList Drives => new List { Drive1, Drive2 }; public void WriteIoRegionC8CF(int address, int data) => _video.ReadFloatingBus(); @@ -236,24 +268,5 @@ namespace Jellyfish.Virtu Drives[_driveNumber].ApplyPhaseChange(_phaseStates); } } - - // ReSharper disable once AutoPropertyCanBeMadeGetOnly.Local - public DiskIIDrive Drive1 { get; private set; } - - - // ReSharper disable once AutoPropertyCanBeMadeGetOnly.Local - public DiskIIDrive Drive2 { get; private set; } - - private const int Phase1On = 1 << 1; - - private int _latch; - private int _phaseStates; - private bool _motorOn; - private int _driveNumber; - private bool _loadMode; - private bool _writeMode; - private bool _driveSpin; - - private byte[] _romRegionC1C7 = new byte[0x0100]; } } diff --git a/ExternalCoreProjects/Virtu/DiskIIDrive.cs b/ExternalCoreProjects/Virtu/DiskIIDrive.cs index ab96889a38..8ad31f65d0 100644 --- a/ExternalCoreProjects/Virtu/DiskIIDrive.cs +++ b/ExternalCoreProjects/Virtu/DiskIIDrive.cs @@ -1,14 +1,17 @@ -using Newtonsoft.Json; - -namespace Jellyfish.Virtu +namespace Jellyfish.Virtu { public sealed class DiskIIDrive { - // ReSharper disable once FieldCanBeMadeReadOnly.Local - private IDiskIIController _diskController; + private readonly IDiskIIController _diskController; + private readonly int[][] _driveArmStepDelta = new int[PhaseCount][]; - // ReSharper disable once UnusedMember.Global - public DiskIIDrive() { } + private bool _trackLoaded; + private bool _trackChanged; + private int _trackNumber; + private int _trackOffset; + + private byte[] _trackData = new byte[Disk525.TrackSize]; + private Disk525 _disk; public DiskIIDrive(IDiskIIController diskController) { @@ -19,6 +22,18 @@ namespace Jellyfish.Virtu _driveArmStepDelta[3] = new[] { 0, 1, 0, 1, -1, 0, -1, 0, 0, 1, 0, 1, -1, 0, -1, 0 }; // phase 3 } + public void Sync(IComponentSerializer ser) + { + ser.Sync(nameof(_trackLoaded), ref _trackLoaded); + ser.Sync(nameof(_trackChanged), ref _trackChanged); + ser.Sync(nameof(_trackNumber), ref _trackNumber); + ser.Sync(nameof(_trackOffset), ref _trackOffset); + ser.Sync(nameof(_trackData), ref _trackData, false); + + // TODO: save the delta, this is saving the rom into save states + _disk?.Sync(ser); + } + // ReSharper disable once UnusedMember.Global public void InsertDisk(string name, byte[] data, bool isWriteProtected) { @@ -101,24 +116,9 @@ namespace Jellyfish.Virtu } } - [JsonIgnore] - public bool IsWriteProtected => _disk.IsWriteProtected; + public bool IsWriteProtected => _disk?.IsWriteProtected ?? false; private const int TrackNumberMax = 0x44; - private const int PhaseCount = 4; - - // ReSharper disable once FieldCanBeMadeReadOnly.Local - private int[][] _driveArmStepDelta = new int[PhaseCount][]; - - private bool _trackLoaded; - private bool _trackChanged; - private int _trackNumber; - private int _trackOffset; - - // ReSharper disable once FieldCanBeMadeReadOnly.Local - private byte[] _trackData = new byte[Disk525.TrackSize]; - - private Disk525 _disk; } } diff --git a/ExternalCoreProjects/Virtu/DiskNib.cs b/ExternalCoreProjects/Virtu/DiskNib.cs index 301513e692..6b2b615c71 100644 --- a/ExternalCoreProjects/Virtu/DiskNib.cs +++ b/ExternalCoreProjects/Virtu/DiskNib.cs @@ -4,9 +4,6 @@ namespace Jellyfish.Virtu { internal sealed class DiskNib : Disk525 { - // ReSharper disable once UnusedMember.Global - public DiskNib() { } - public DiskNib(byte[] data, bool isWriteProtected) : base(data, isWriteProtected) { diff --git a/ExternalCoreProjects/Virtu/IComponentSerializer.cs b/ExternalCoreProjects/Virtu/IComponentSerializer.cs new file mode 100644 index 0000000000..5a60c95a66 --- /dev/null +++ b/ExternalCoreProjects/Virtu/IComponentSerializer.cs @@ -0,0 +1,17 @@ +namespace Jellyfish.Virtu +{ + // Serves as a generalized interface to the BizHawk serializer + public interface IComponentSerializer + { + bool IsReader { get; } + void Sync(string name, ref bool val); + void Sync(string name, ref int val); + void Sync(string name, ref long val); + void Sync(string name, ref ulong val); + + void Sync(string name, ref bool[] val, bool useNull); + void Sync(string name, ref byte[] val, bool useNull); + void Sync(string name, ref ushort[] val, bool useNull); + void Sync(string name, ref int[] val, bool useNull); + } +} diff --git a/ExternalCoreProjects/Virtu/Keyboard.cs b/ExternalCoreProjects/Virtu/Keyboard.cs index 7802087208..b4246da83c 100644 --- a/ExternalCoreProjects/Virtu/Keyboard.cs +++ b/ExternalCoreProjects/Virtu/Keyboard.cs @@ -143,9 +143,6 @@ namespace Jellyfish.Virtu public sealed class Keyboard { - // ReSharper disable once UnusedMember.Global - public Keyboard() { } - static Keyboard() { for (int i = 0; i < 62; i++) @@ -226,15 +223,15 @@ namespace Jellyfish.Virtu 0x7a1a5a1a, // z }; - /// 0 - 55 + // key: 0 - 55 private static int KeyToAscii(int key, bool control, bool shift) { - int s = control ? (shift ? 0 : 16) : (shift ? 8 : 24); + int s = control ? shift ? 0 : 16 : shift ? 8 : 24; return (int)(KeyAsciiData[key] >> s & 0x7f); } // ReSharper disable once InconsistentNaming - private static Dictionary DescriptionsToKeys = new Dictionary(); + private static readonly Dictionary DescriptionsToKeys = new Dictionary(); private static Keys FromStrings(IEnumerable keynames) { diff --git a/ExternalCoreProjects/Virtu/MachineEvents.cs b/ExternalCoreProjects/Virtu/MachineEvents.cs index 588b71c50b..0f7d97414d 100644 --- a/ExternalCoreProjects/Virtu/MachineEvents.cs +++ b/ExternalCoreProjects/Virtu/MachineEvents.cs @@ -1,29 +1,87 @@ using System; using System.Collections.Generic; -using System.Globalization; +using System.Linq; namespace Jellyfish.Virtu { + public enum EventCallbacks + { + FlushOutput, + FlushRow, + LeaveVBlank, + ResetVsync, + InverseText + } + internal sealed class MachineEvent { - public MachineEvent(int delta, Action action) + public MachineEvent(int delta, EventCallbacks type) { Delta = delta; - Action = action; - } - - public override string ToString() - { - return string.Format(CultureInfo.InvariantCulture, "Delta = {0} Action = {{{1}.{2}}}", Delta, Action.Method.DeclaringType?.Name, Action.Method.Name); + Type = type; } public int Delta { get; set; } - public Action Action { get; set; } + public EventCallbacks Type { get; set; } } public sealed class MachineEvents { - public void AddEvent(int delta, Action action) + private readonly Dictionary _eventDelegates = new Dictionary(); + + private readonly LinkedList _used = new LinkedList(); + private readonly LinkedList _free = new LinkedList(); + + // ReSharper disable once UnusedMember.Global + public void Sync(IComponentSerializer ser) + { + if (ser.IsReader) + { + int[] usedDelta = new int[0]; + int[] usedType = new int[0]; + int[] freeDelta = new int[0]; + int[] freeType = new int[0]; + + ser.Sync("UsedDelta", ref usedDelta, false); + ser.Sync("UsedType", ref usedType, false); + ser.Sync("FreeDelta", ref freeDelta, false); + ser.Sync("FreeType", ref freeType, false); + + _used.Clear(); + for (int i = 0; i < usedDelta.Length; i++) + { + var e = new MachineEvent(usedDelta[i], (EventCallbacks)usedType[i]); + _used.AddLast(new LinkedListNode(e)); + } + + _free.Clear(); + for (int i = 0; i < freeDelta.Length; i++) + { + var e = new MachineEvent(freeDelta[i], (EventCallbacks)freeType[i]); + _free.AddLast(new LinkedListNode(e)); + } + } + else + { + var usedDelta = _used.Select(u => u.Delta).ToArray(); + var usedType = _used.Select(u => (int)u.Type).ToArray(); + var freeDelta = _free.Select(f => f.Delta).ToArray(); + var freeType = _free.Select(f => (int)f.Type).ToArray(); + + ser.Sync("UsedDelta", ref usedDelta, false); + ser.Sync("UsedType", ref usedType, false); + ser.Sync("FreeDelta", ref freeDelta, false); + ser.Sync("FreeType", ref freeType, false); + } + } + + public void AddEventDelegate(EventCallbacks type, Action action) + + { + _eventDelegates[type] = action; + } + + public void AddEvent(int delta, EventCallbacks type) { var node = _used.First; for (; node != null; node = node.Next) @@ -44,11 +102,11 @@ namespace Jellyfish.Virtu { _free.RemoveFirst(); newNode.Value.Delta = delta; - newNode.Value.Action = action; + newNode.Value.Type = type; } else { - newNode = new LinkedListNode(new MachineEvent(delta, action)); + newNode = new LinkedListNode(new MachineEvent(delta, type)); } if (node != null) @@ -61,7 +119,7 @@ namespace Jellyfish.Virtu } } - public int FindEvent(Action action) + public int FindEvent(EventCallbacks type) { int delta = 0; @@ -69,9 +127,9 @@ namespace Jellyfish.Virtu { delta += node.Value.Delta; - var other = node.Value.Action; + var other = node.Value.Type; - if (other.Method == action.Method && other.Target == action.Target) + if (other == type) { return delta; } @@ -88,7 +146,7 @@ namespace Jellyfish.Virtu while (node.Value.Delta <= 0) { - node.Value.Action(); + _eventDelegates[node.Value.Type](); RemoveEvent(node); node = _used.First; } @@ -104,11 +162,5 @@ namespace Jellyfish.Virtu _used.Remove(node); _free.AddFirst(node); // cache node; avoids garbage } - - // ReSharper disable once FieldCanBeMadeReadOnly.Local - private LinkedList _used = new LinkedList(); - - // ReSharper disable once FieldCanBeMadeReadOnly.Local - private LinkedList _free = new LinkedList(); } } diff --git a/ExternalCoreProjects/Virtu/Memory.Data.cs b/ExternalCoreProjects/Virtu/Memory.Data.cs index b41b6af390..ba658d204c 100644 --- a/ExternalCoreProjects/Virtu/Memory.Data.cs +++ b/ExternalCoreProjects/Virtu/Memory.Data.cs @@ -1,5 +1,4 @@ -using Newtonsoft.Json; -using System; +using System; namespace Jellyfish.Virtu { @@ -96,7 +95,6 @@ namespace Jellyfish.Virtu Video.ModeC, Video.ModeD, Video.Mode1, Video.Mode2, Video.ModeE, Video.ModeF, Video.Mode1, Video.Mode2 }; - [JsonIgnore] private Action[][][] WriteRamModeBankRegion; } } diff --git a/ExternalCoreProjects/Virtu/Memory.cs b/ExternalCoreProjects/Virtu/Memory.cs index 94fda5d1fa..48a1ebda66 100644 --- a/ExternalCoreProjects/Virtu/Memory.cs +++ b/ExternalCoreProjects/Virtu/Memory.cs @@ -1,10 +1,10 @@ using System; using System.Collections.Generic; using System.Linq; -using Newtonsoft.Json; namespace Jellyfish.Virtu { + // ReSharper disable once UnusedMember.Global public enum MonitorType { Unknown, Standard, Enhanced } public interface IMemoryBus @@ -31,8 +31,12 @@ namespace Jellyfish.Virtu int VideoMode { get; } MonitorType Monitor { get; } + + // ReSharper disable once UnusedMember.Global + void Sync(IComponentSerializer ser); } + // ReSharper disable once UnusedMember.Global public sealed partial class Memory : IMemoryBus { private IGamePort _gamePort; @@ -47,15 +51,30 @@ namespace Jellyfish.Virtu private IPeripheralCard _slot5; private IPeripheralCard _slot7; - // TODO: this shouldn't be in savestates! - // ReSharper disable once FieldCanBeMadeReadOnly.Local - private byte[] _appleIIe; + private readonly byte[] _appleIIe; + private readonly byte[][] _regionRead = new byte[RegionCount][]; + private readonly byte[][] _regionWrite = new byte[RegionCount][]; + private readonly Action[] _writeRegion = new Action[RegionCount]; - // ReSharper disable once UnusedMember.Global - public Memory() - { - InitializeWriteDelegates(); - } + private bool _lagged; + private int _state; + private int _slotRegionC8CF; + private byte[] _zeroPage; + private byte[] _ramMainRegion0001 = new byte[0x0200]; + private byte[] _ramMainRegion02BF = new byte[0xBE00]; + private byte[] _ramMainBank1RegionD0DF = new byte[0x1000]; + private byte[] _ramMainBank2RegionD0DF = new byte[0x1000]; + private byte[] _ramMainRegionE0FF = new byte[0x2000]; + private byte[] _ramAuxRegion0001 = new byte[0x0200]; + private byte[] _ramAuxRegion02BF = new byte[0xBE00]; + private byte[] _ramAuxBank1RegionD0DF = new byte[0x1000]; + private byte[] _ramAuxBank2RegionD0DF = new byte[0x1000]; + private byte[] _ramAuxRegionE0FF = new byte[0x2000]; + + private byte[] _romExternalRegionC1CF = new byte[0x0F00]; + private byte[] _romInternalRegionC1CF = new byte[0x0F00]; + private byte[] _romRegionD0DF = new byte[0x1000]; + private byte[] _romRegionE0FF = new byte[0x2000]; // ReSharper disable once UnusedMember.Global public Memory(byte[] appleIIe) @@ -64,6 +83,37 @@ namespace Jellyfish.Virtu InitializeWriteDelegates(); } + public void Sync(IComponentSerializer ser) + { + ser.Sync(nameof(_lagged), ref _lagged); + ser.Sync(nameof(_state), ref _state); + ser.Sync(nameof(_slotRegionC8CF), ref _slotRegionC8CF); + ser.Sync(nameof(_zeroPage), ref _zeroPage, false); + + ser.Sync(nameof(_ramMainRegion0001), ref _ramMainRegion0001, false); + ser.Sync(nameof(_ramMainRegion02BF), ref _ramMainRegion02BF, false); + ser.Sync(nameof(_ramMainBank1RegionD0DF), ref _ramMainBank1RegionD0DF, false); + ser.Sync(nameof(_ramMainBank2RegionD0DF), ref _ramMainBank2RegionD0DF, false); + ser.Sync(nameof(_ramMainRegionE0FF), ref _ramMainRegionE0FF, false); + ser.Sync(nameof(_ramAuxRegion0001), ref _ramAuxRegion0001, false); + ser.Sync(nameof(_ramAuxRegion02BF), ref _ramAuxRegion02BF, false); + ser.Sync(nameof(_ramAuxBank1RegionD0DF), ref _ramAuxBank1RegionD0DF, false); + ser.Sync(nameof(_ramAuxBank2RegionD0DF), ref _ramAuxBank2RegionD0DF, false); + ser.Sync(nameof(_ramAuxRegionE0FF), ref _ramAuxRegionE0FF, false); + ser.Sync(nameof(_romExternalRegionC1CF), ref _romExternalRegionC1CF, false); + ser.Sync(nameof(_romInternalRegionC1CF), ref _romInternalRegionC1CF, false); + ser.Sync(nameof(_romRegionD0DF), ref _romRegionD0DF, false); + ser.Sync(nameof(_romRegionE0FF), ref _romRegionE0FF, false); + + if (ser.IsReader) + { + MapRegion0001(); + MapRegion02BF(); + MapRegionC0CF(); + MapRegionD0FF(); + } + } + // ReSharper disable once UnusedMember.Global public void Initialize( Keyboard keyboard, @@ -123,7 +173,7 @@ namespace Jellyfish.Virtu } } - public bool Lagged { get; set; } + public bool Lagged { get => _lagged; set => _lagged = value; } private IList Slots => new List { @@ -2100,51 +2150,15 @@ namespace Jellyfish.Virtu public MonitorType Monitor { get; private set; } public int VideoMode => StateVideoMode[_state & StateVideo]; - [JsonIgnore] private Action _writeIoRegionC0C0; - [JsonIgnore] private Action _writeIoRegionC1C7; - [JsonIgnore] private Action _writeIoRegionC3C3; - [JsonIgnore] private Action _writeIoRegionC8CF; - [JsonIgnore] private Action _writeRomRegionD0FF; - - [JsonIgnore] + public Action ReadCallback; - - [JsonIgnore] public Action WriteCallback; - - [JsonIgnore] public Action ExecuteCallback; - - [JsonIgnore] public Action InputCallback; - - private int _state; - private int _slotRegionC8CF; - - private byte[] _zeroPage; - private byte[][] _regionRead = new byte[RegionCount][]; - private byte[][] _regionWrite = new byte[RegionCount][]; - private Action[] _writeRegion = new Action[RegionCount]; - - private byte[] _ramMainRegion0001 = new byte[0x0200]; - private byte[] _ramMainRegion02BF = new byte[0xBE00]; - private byte[] _ramMainBank1RegionD0DF = new byte[0x1000]; - private byte[] _ramMainBank2RegionD0DF = new byte[0x1000]; - private byte[] _ramMainRegionE0FF = new byte[0x2000]; - private byte[] _ramAuxRegion0001 = new byte[0x0200]; - private byte[] _ramAuxRegion02BF = new byte[0xBE00]; - private byte[] _ramAuxBank1RegionD0DF = new byte[0x1000]; - private byte[] _ramAuxBank2RegionD0DF = new byte[0x1000]; - private byte[] _ramAuxRegionE0FF = new byte[0x2000]; - - private byte[] _romExternalRegionC1CF = new byte[0x0F00]; - private byte[] _romInternalRegionC1CF = new byte[0x0F00]; - private byte[] _romRegionD0DF = new byte[0x1000]; - private byte[] _romRegionE0FF = new byte[0x2000]; } } diff --git a/ExternalCoreProjects/Virtu/NoSlotClock.cs b/ExternalCoreProjects/Virtu/NoSlotClock.cs index 2e793d0d4e..79d8e91b45 100644 --- a/ExternalCoreProjects/Virtu/NoSlotClock.cs +++ b/ExternalCoreProjects/Virtu/NoSlotClock.cs @@ -6,16 +6,20 @@ namespace Jellyfish.Virtu { int Read(int address, int value); void Write(int address); + + // ReSharper disable once UnusedMember.Global + void Sync(IComponentSerializer ser); } // ReSharper disable once UnusedMember.Global public sealed class NoSlotClock : ISlotClock { - // ReSharper disable once FieldCanBeMadeReadOnly.Local - private Video _video; + private readonly Video _video; - // ReSharper disable once UnusedMember.Global - public NoSlotClock() { } + private bool _clockEnabled; + private bool _writeEnabled; + private RingRegister _clockRegister; + private RingRegister _comparisonRegister; public NoSlotClock(Video video) { @@ -27,6 +31,14 @@ namespace Jellyfish.Virtu _comparisonRegister = new RingRegister(ClockInitSequence, 0x1); } + public void Sync(IComponentSerializer ser) + { + ser.Sync(nameof(_clockEnabled), ref _clockEnabled); + ser.Sync(nameof(_writeEnabled), ref _writeEnabled); + _clockRegister.Sync(ser); + _comparisonRegister.Sync(ser); + } + public int Read(int address, int value) { // this may read or write the clock @@ -142,11 +154,6 @@ namespace Jellyfish.Virtu private const ulong ClockInitSequence = 0x5CA33AC55CA33AC5; - private bool _clockEnabled; - private bool _writeEnabled; - private RingRegister _clockRegister; - private RingRegister _comparisonRegister; - private struct RingRegister { public RingRegister(ulong data, ulong mask) @@ -155,6 +162,12 @@ namespace Jellyfish.Virtu _mask = mask; } + public void Sync(IComponentSerializer ser) + { + ser.Sync(nameof(_data), ref _data); + ser.Sync(nameof(_mask), ref _mask); + } + public void Reset() { _mask = 0x1; diff --git a/ExternalCoreProjects/Virtu/Speaker.cs b/ExternalCoreProjects/Virtu/Speaker.cs index 0e3c371a14..09e1a34b63 100644 --- a/ExternalCoreProjects/Virtu/Speaker.cs +++ b/ExternalCoreProjects/Virtu/Speaker.cs @@ -1,8 +1,4 @@ -using System; -using System.Runtime.Serialization; -using Newtonsoft.Json; - -namespace Jellyfish.Virtu +namespace Jellyfish.Virtu { public interface ISpeaker { @@ -13,46 +9,46 @@ namespace Jellyfish.Virtu // ReSharper disable once UnusedMember.Global void GetSamples(out short[] samples, out int nSamp); + + // ReSharper disable once UnusedMember.Global + void Sync(IComponentSerializer ser); } + // ReSharper disable once UnusedMember.Global public sealed class Speaker : ISpeaker { - // ReSharper disable once FieldCanBeMadeReadOnly.Local - private MachineEvents _events; - - // ReSharper disable once FieldCanBeMadeReadOnly.Local - private ICpu _cpu; - - public Speaker() { } - public Speaker(MachineEvents events, ICpu cpu) - { - _events = events; - _cpu = cpu; - _flushOutputEvent = FlushOutputEvent; // cache delegates; avoids garbage - - _events.AddEvent(CyclesPerFlush * _cpu.Multiplier, _flushOutputEvent); - - _isHigh = false; - _highCycles = _totalCycles = 0; - } - private const int CyclesPerFlush = 23; - // ReSharper disable once FieldCanBeMadeReadOnly.Local - private Action _flushOutputEvent; + private readonly MachineEvents _events; + private readonly ICpu _cpu; private bool _isHigh; private int _highCycles; private int _totalCycles; private long _lastCycles; - [JsonIgnore] // only relevant if trying to savestate mid-frame + // only relevant if trying to savestate mid-frame private readonly short[] _buffer = new short[4096]; - - [JsonIgnore] // only relevant if trying to savestate mid-frame private int _position; - #region Api + public Speaker(MachineEvents events, ICpu cpu) + { + _events = events; + _cpu = cpu; + _events.AddEventDelegate(EventCallbacks.FlushOutput, FlushOutputEvent); + _events.AddEvent(CyclesPerFlush * _cpu.Multiplier, EventCallbacks.FlushOutput); + + _isHigh = false; + _highCycles = _totalCycles = 0; + } + + public void Sync(IComponentSerializer ser) + { + ser.Sync(nameof(_isHigh), ref _isHigh); + ser.Sync(nameof(_highCycles), ref _highCycles); + ser.Sync(nameof(_totalCycles), ref _totalCycles); + ser.Sync(nameof(_lastCycles), ref _lastCycles); + } public void Clear() { @@ -66,8 +62,6 @@ namespace Jellyfish.Virtu _position = 0; } - #endregion - public void ToggleOutput() { UpdateCycles(); @@ -81,7 +75,7 @@ namespace Jellyfish.Virtu Output(_highCycles * short.MaxValue / _totalCycles); _highCycles = _totalCycles = 0; - _events.AddEvent(CyclesPerFlush * _cpu.Multiplier, _flushOutputEvent); + _events.AddEvent(CyclesPerFlush * _cpu.Multiplier, EventCallbacks.FlushOutput); } private void UpdateCycles() @@ -104,12 +98,5 @@ namespace Jellyfish.Virtu _buffer[_position++] = (short)data; } } - - - [OnDeserialized] - private void OnDeserialized(StreamingContext context) - { - _position = 0; - } } } diff --git a/ExternalCoreProjects/Virtu/Video.Data.cs b/ExternalCoreProjects/Virtu/Video.Data.cs index 0ecda3e45f..92b74fb921 100644 --- a/ExternalCoreProjects/Virtu/Video.Data.cs +++ b/ExternalCoreProjects/Virtu/Video.Data.cs @@ -1615,8 +1615,7 @@ namespace Jellyfish.Virtu public const int ModeE = 0xE; public const int ModeF = 0xF; - // ReSharper disable once FieldCanBeMadeReadOnly.Local - private Action[] _flushRowMode; + private readonly Action[] _flushRowMode; private const int Width = 560; private const int Height = VLineEnterVBlank; diff --git a/ExternalCoreProjects/Virtu/Video.cs b/ExternalCoreProjects/Virtu/Video.cs index 967b51e69e..4d12a1607b 100644 --- a/ExternalCoreProjects/Virtu/Video.cs +++ b/ExternalCoreProjects/Virtu/Video.cs @@ -1,6 +1,4 @@ using System; -using System.Runtime.Serialization; -using Newtonsoft.Json; namespace Jellyfish.Virtu { @@ -9,7 +7,9 @@ namespace Jellyfish.Virtu public interface IVideo { + // ReSharper disable once UnusedMember.Global int[] GetVideoBuffer(); + // ReSharper disable once UnusedMember.Global void Reset(); void DirtyCell(int addressOffset); @@ -20,26 +20,42 @@ namespace Jellyfish.Virtu void SetCharSet(); bool IsVBlank { get; } + + // ReSharper disable once UnusedMember.Global + void Sync(IComponentSerializer ser); } public sealed partial class Video : IVideo { - // ReSharper disable once FieldCanBeMadeReadOnly.Local - private MachineEvents _events; + private readonly MachineEvents _events; + private readonly IMemoryBus _memory; - // ReSharper disable once FieldCanBeMadeReadOnly.Local - private IMemoryBus _memory; + private readonly int[] _colorPalette = new int[ColorPaletteCount]; + + private bool _isVBlank; + private int[] _framebuffer = new int[560 * 384]; + private bool _isTextInversed; + private ScannerOptions _scannerOptions; + private int _cyclesPerVBlank; + private int _cyclesPerVBlankPreset; + private int _cyclesPerVSync; + private int _cyclesPerFlash; + private int _vCountPreset; + private int _vLineLeaveVBlank; + private ushort[] _charSet; + private bool _isMonochrome; + + private bool[] _isCellDirty = new bool[Height * CellColumns + 1]; // includes sentinel - public Video() { } public Video(MachineEvents events, IMemoryBus memory) { _events = events; _memory = memory; - _flushRowEvent = FlushRowEvent; // cache delegates; avoids garbage - _inverseTextEvent = InverseTextEvent; - _leaveVBlankEvent = LeaveVBlankEvent; - _resetVSyncEvent = ResetVSyncEvent; + _events.AddEventDelegate(EventCallbacks.FlushRow, FlushRowEvent); + _events.AddEventDelegate(EventCallbacks.InverseText, InverseTextEvent); + _events.AddEventDelegate(EventCallbacks.LeaveVBlank, LeaveVBlankEvent); + _events.AddEventDelegate(EventCallbacks.ResetVsync, ResetVSyncEvent); _flushRowMode = new Action[] { @@ -73,22 +89,43 @@ namespace Jellyfish.Virtu IsMonochrome = false; ScannerOptions = ScannerOptions.None; - IsVBlank = true; + _isVBlank = true; - _events.AddEvent(_cyclesPerVBlankPreset, _leaveVBlankEvent); // align flush events with scanner; assumes vcount preset at start of frame [3-15, 3-16] - _events.AddEvent(_cyclesPerVSync, _resetVSyncEvent); - _events.AddEvent(_cyclesPerFlash, _inverseTextEvent); + _events.AddEvent(_cyclesPerVBlankPreset, EventCallbacks.LeaveVBlank); // align flush events with scanner; assumes vcount preset at start of frame [3-15, 3-16] + _events.AddEvent(_cyclesPerVSync, EventCallbacks.ResetVsync); + _events.AddEvent(_cyclesPerFlash, EventCallbacks.InverseText); + } + + public void Sync(IComponentSerializer ser) + { + if (ser.IsReader) + { + int option = 0; + ser.Sync(nameof(_scannerOptions), ref option); + _scannerOptions = (ScannerOptions)option; + } + else + { + int option = (int)_scannerOptions; + ser.Sync(nameof(_scannerOptions), ref option); + } + + ser.Sync(nameof(_isVBlank), ref _isVBlank); + ser.Sync(nameof(_framebuffer), ref _framebuffer, false); + ser.Sync(nameof(_isTextInversed), ref _isTextInversed); + ser.Sync(nameof(_cyclesPerVBlank), ref _cyclesPerVBlank); + ser.Sync(nameof(_cyclesPerVBlankPreset), ref _cyclesPerVBlankPreset); + ser.Sync(nameof(_cyclesPerVSync), ref _cyclesPerVSync); + ser.Sync(nameof(_cyclesPerFlash), ref _cyclesPerFlash); + ser.Sync(nameof(_vCountPreset), ref _vCountPreset); + ser.Sync(nameof(_vLineLeaveVBlank), ref _vLineLeaveVBlank); + ser.Sync(nameof(_charSet), ref _charSet, false); + ser.Sync(nameof(_isCellDirty), ref _isCellDirty, false); + ser.Sync(nameof(_isMonochrome), ref _isMonochrome); } // ReSharper disable once UnusedMember.Global - public int[] GetVideoBuffer() => Framebuffer; - - [OnDeserialized] - private void OnDeserialized(StreamingContext context) - { - // the VideoService forgets all of its information on LoadState - DirtyScreen(); - } + public int[] GetVideoBuffer() => _framebuffer; public void Reset() { @@ -149,7 +186,7 @@ namespace Jellyfish.Virtu public int ReadFloatingBus() // [5-40] { // derive scanner counters from current cycles into frame; assumes hcount and vcount preset at start of frame [3-13, 3-15, 3-16] - int cycles = _cyclesPerVSync - _events.FindEvent(_resetVSyncEvent); + int cycles = _cyclesPerVSync - _events.FindEvent(EventCallbacks.ResetVsync); int hClock = cycles % CyclesPerHSync; int hCount = (hClock != 0) ? HCountPreset + hClock - 1 : 0; int vLine = cycles / CyclesPerHSync; @@ -918,18 +955,18 @@ namespace Jellyfish.Virtu private void FlushRowEvent() { - int y = (_cyclesPerVSync - _cyclesPerVBlankPreset - _events.FindEvent(_resetVSyncEvent)) / CyclesPerHSync; + int y = (_cyclesPerVSync - _cyclesPerVBlankPreset - _events.FindEvent(EventCallbacks.ResetVsync)) / CyclesPerHSync; _flushRowMode[_memory.VideoMode](y - CellHeight); // in arrears if (y < Height) { - _events.AddEvent(CyclesPerFlush, _flushRowEvent); + _events.AddEvent(CyclesPerFlush, EventCallbacks.FlushRow); } else { - IsVBlank = true; - _events.AddEvent(_cyclesPerVBlank, _leaveVBlankEvent); + _isVBlank = true; + _events.AddEvent(_cyclesPerVBlank, EventCallbacks.LeaveVBlank); } } @@ -946,18 +983,18 @@ namespace Jellyfish.Virtu { _isTextInversed = !_isTextInversed; DirtyScreenText(); - _events.AddEvent(_cyclesPerFlash, _inverseTextEvent); + _events.AddEvent(_cyclesPerFlash, EventCallbacks.InverseText); } private void LeaveVBlankEvent() { - IsVBlank = false; - _events.AddEvent(CyclesPerFlush, _flushRowEvent); + _isVBlank = false; + _events.AddEvent(CyclesPerFlush, EventCallbacks.FlushRow); } private void ResetVSyncEvent() { - _events.AddEvent(_cyclesPerVSync, _resetVSyncEvent); + _events.AddEvent(_cyclesPerVSync, EventCallbacks.ResetVsync); } private void SetPalette() @@ -1002,13 +1039,10 @@ namespace Jellyfish.Virtu DirtyScreen(); } - // ReSharper disable once AutoPropertyCanBeMadeGetOnly.Local - private int[] Framebuffer { get; set; } = new int[560 * 384]; - private void SetPixel(int x, int y, int color) { int i = 560 * (2 * y) + x; - Framebuffer[i] = Framebuffer[i + 560] = _colorPalette[color]; + _framebuffer[i] = _framebuffer[i + 560] = _colorPalette[color]; } private void SetScanner() @@ -1030,53 +1064,36 @@ namespace Jellyfish.Virtu _cyclesPerFlash = VSyncsPerFlash * _cyclesPerVSync; } - [JsonIgnore] - public bool IsMonochrome { get => _isMonochrome; set { _isMonochrome = value; DirtyScreen(); } } + public bool IsMonochrome + { + get => _isMonochrome; + set { _isMonochrome = value; DirtyScreen(); } + } - [JsonIgnore] - internal ScannerOptions ScannerOptions { get => _scannerOptions; set { _scannerOptions = value; SetScanner(); } } + internal ScannerOptions ScannerOptions + { + get => _scannerOptions; + set { _scannerOptions = value; SetScanner(); } + } - public bool IsVBlank { get; private set; } + public bool IsVBlank => _isVBlank; - private Action _flushRowEvent; - private Action _inverseTextEvent; - private Action _leaveVBlankEvent; - private Action _resetVSyncEvent; - - private int _colorBlack; - private int _colorDarkBlue; - private int _colorDarkGreen; - private int _colorMediumBlue; - private int _colorBrown; - private int _colorLightGrey; - private int _colorGreen; - private int _colorAquamarine; - private int _colorDeepRed; - private int _colorPurple; - private int _colorDarkGrey; - private int _colorLightBlue; - private int _colorOrange; - private int _colorPink; - private int _colorYellow; - private int _colorWhite; - private int _colorMonochrome; - - [JsonIgnore] // not sync relevant - private bool _isMonochrome; - - private bool _isTextInversed; - private ScannerOptions _scannerOptions; - private int _cyclesPerVBlank; - private int _cyclesPerVBlankPreset; - private int _cyclesPerVSync; - private int _cyclesPerFlash; - private int _vCountPreset; - private int _vLineLeaveVBlank; - - private ushort[] _charSet; - private int[] _colorPalette = new int[ColorPaletteCount]; - - [JsonIgnore] // everything is automatically dirtied on load, so no need to save - private bool[] _isCellDirty = new bool[Height * CellColumns + 1]; // includes sentinel + private readonly int _colorBlack; + private readonly int _colorDarkBlue; + private readonly int _colorDarkGreen; + private readonly int _colorMediumBlue; + private readonly int _colorBrown; + private readonly int _colorLightGrey; + private readonly int _colorGreen; + private readonly int _colorAquamarine; + private readonly int _colorDeepRed; + private readonly int _colorPurple; + private readonly int _colorDarkGrey; + private readonly int _colorLightBlue; + private readonly int _colorOrange; + private readonly int _colorPink; + private readonly int _colorYellow; + private readonly int _colorWhite; + private readonly int _colorMonochrome; } } diff --git a/ExternalCoreProjects/Virtu/Virtu.csproj b/ExternalCoreProjects/Virtu/Virtu.csproj index 1dded9d752..0c5a5d2c32 100644 --- a/ExternalCoreProjects/Virtu/Virtu.csproj +++ b/ExternalCoreProjects/Virtu/Virtu.csproj @@ -33,9 +33,6 @@ false - - ..\..\References\Newtonsoft.Json.dll - @@ -53,6 +50,7 @@ + diff --git a/ExternalCoreProjects/Virtu/Virtu.sln.DotSettings b/ExternalCoreProjects/Virtu/Virtu.sln.DotSettings index 3211634121..26b84f0adc 100644 --- a/ExternalCoreProjects/Virtu/Virtu.sln.DotSettings +++ b/ExternalCoreProjects/Virtu/Virtu.sln.DotSettings @@ -1,5 +1,6 @@  DO_NOT_SHOW + 0DF AA AB AC diff --git a/References/Virtu.dll b/References/Virtu.dll index a9e41c53f18db9e7e044a25a589a8992ab1cf19d..a54efa15469aad36b4b04ccc42331faa4d371a1e 100644 GIT binary patch literal 141824 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 H7lHo;S-%@+