From 7b713e6aaa20bccd0dd1168385ccb721199c2c23 Mon Sep 17 00:00:00 2001 From: Sean Fausett Date: Sun, 4 Apr 2010 00:12:01 +0000 Subject: [PATCH] Cosmetic changes. Set svn properties on files. --HG-- extra : convert_revision : svn%3Affd33b8c-2492-42e0-bdc5-587b920b7d6d/trunk%4044493 --- Library/AssemblyCommentAttribute.cs | 30 +- Library/CustomDictionary.xml | 14 +- Library/DirectSound.cs | 16 +- Library/GCHandleHelpers.cs | 2 +- Library/GeneralSecurity.cs | 554 +- Library/GlobalSuppressions.cs | 8 +- Library/IEnumerableExtensions.cs | 50 +- Library/Lazy.cs | 74 +- Library/MathHelpers.cs | 30 +- Library/SafeAllocHandle.cs | 294 +- Library/SafeFileHandle.cs | 190 +- Library/Silverlight/ApplicationBase.cs | 130 +- Library/Silverlight/FrameRateCounter.xaml | 26 +- Library/Silverlight/FrameRateCounter.xaml.cs | 84 +- .../Silverlight/Properties/AssemblyInfo.cs | 44 +- Library/Silverlight/StringFormatConverter.cs | 82 +- Library/SingletonFactory.cs | 36 +- Library/StreamExtensions.cs | 80 +- Library/StringBuilderExtensions.cs | 76 +- Library/WaveFormat.cs | 2 +- Library/Wpf/ApplicationBase.cs | 144 +- Library/Wpf/FrameRateCounter.xaml | 18 +- Library/Wpf/FrameRateCounter.xaml.cs | 84 +- Library/Wpf/Properties/AssemblyInfo.cs | 44 +- Library/XmlSerializerHelpers.cs | 80 +- Library/Xna/FrameRateCounter.cs | 142 +- Library/Xna/GameBase.cs | 90 +- Library/Xna/Properties/AssemblyInfo.cs | 60 +- Virtu/Cassette.cs | 46 +- Virtu/Cpu.cs | 6466 ++++++++--------- Virtu/CpuData.cs | 166 +- Virtu/CustomDictionary.xml | 48 +- Virtu/Disk525.cs | 86 +- Virtu/DiskDsk.cs | 578 +- Virtu/DiskII.cs | 482 +- Virtu/DiskNib.cs | 44 +- Virtu/Drive525.cs | 236 +- Virtu/GamePort.cs | 316 +- Virtu/Keyboard.cs | 266 +- Virtu/Machine.cs | 256 +- Virtu/MachineComponent.cs | 48 +- Virtu/MachineEvents.cs | 214 +- Virtu/MachineSettings.cs | 786 +- Virtu/Memory.cs | 2938 ++++---- Virtu/MemoryData.cs | 210 +- Virtu/Properties/SR.Designer.cs | 198 +- Virtu/Properties/SR.resx | 262 +- Virtu/Services/AudioService.cs | 134 +- Virtu/Services/GamePortService.cs | 146 +- Virtu/Services/KeyboardService.cs | 140 +- Virtu/Services/MachineServices.cs | 114 +- Virtu/Services/StorageService.cs | 82 +- Virtu/Services/VideoService.cs | 40 +- Virtu/Silverlight/MainApp.xaml | 22 +- Virtu/Silverlight/MainApp.xaml.cs | 26 +- Virtu/Silverlight/MainPage.xaml | 42 +- Virtu/Silverlight/MainPage.xaml.cs | 155 +- Virtu/Silverlight/Properties/AppManifest.xml | 10 +- Virtu/Silverlight/Properties/AssemblyInfo.cs | 44 +- .../Services/SilverlightKeyboardService.cs | 808 +- .../Services/SilverlightStorageService.cs | 122 +- .../Services/SilverlightVideoService.cs | 168 +- Virtu/Speaker.cs | 130 +- Virtu/Video.cs | 2054 +++--- Virtu/VideoData.cs | 3288 ++++----- Virtu/Wpf/MainApp.xaml | 16 +- Virtu/Wpf/MainApp.xaml.cs | 28 +- Virtu/Wpf/MainWindow.xaml | 38 +- Virtu/Wpf/MainWindow.xaml.cs | 175 +- Virtu/Wpf/Properties/AssemblyInfo.cs | 50 +- Virtu/Wpf/Services/WpfKeyboardService.cs | 598 +- Virtu/Wpf/Services/WpfStorageService.cs | 136 +- Virtu/Wpf/Services/WpfVideoService.cs | 188 +- Virtu/Xna/MainApp.cs | 26 +- Virtu/Xna/MainGame.cs | 162 +- Virtu/Xna/Properties/AssemblyInfo.cs | 56 +- Virtu/Xna/Services/XnaAudioService.cs | 5 +- Virtu/Xna/Services/XnaGamePortService.cs | 128 +- Virtu/Xna/Services/XnaKeyboardService.cs | 650 +- Virtu/Xna/Services/XnaStorageService.cs | 126 +- Virtu/Xna/Services/XnaVideoService.cs | 234 +- 81 files changed, 13130 insertions(+), 13141 deletions(-) diff --git a/Library/AssemblyCommentAttribute.cs b/Library/AssemblyCommentAttribute.cs index 3dec478..90a2c6c 100644 --- a/Library/AssemblyCommentAttribute.cs +++ b/Library/AssemblyCommentAttribute.cs @@ -1,15 +1,15 @@ -using System; - -namespace Jellyfish.Library -{ - [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)] - public sealed class AssemblyCommentAttribute : Attribute - { - public AssemblyCommentAttribute(string comment) - { - Comment = comment; - } - - public string Comment { get; private set; } - } -} +using System; + +namespace Jellyfish.Library +{ + [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)] + public sealed class AssemblyCommentAttribute : Attribute + { + public AssemblyCommentAttribute(string comment) + { + Comment = comment; + } + + public string Comment { get; private set; } + } +} diff --git a/Library/CustomDictionary.xml b/Library/CustomDictionary.xml index de0462e..3b27878 100644 --- a/Library/CustomDictionary.xml +++ b/Library/CustomDictionary.xml @@ -1,8 +1,8 @@ - - - - - Alloc - - + + + + + Alloc + + \ No newline at end of file diff --git a/Library/DirectSound.cs b/Library/DirectSound.cs index daa520e..9121004 100644 --- a/Library/DirectSound.cs +++ b/Library/DirectSound.cs @@ -67,12 +67,12 @@ private void Initialize() GCHandleHelpers.Pin(new WaveFormat(_sampleRate, _sampleChannels, _sampleBits), waveFormat => { - BufferDescription description = new BufferDescription(BufferCapabilities.CtrlPositionNotify | BufferCapabilities.CtrlVolume, BlockCount * _sampleSize, waveFormat); + var description = new BufferDescription(BufferCapabilities.CtrlPositionNotify | BufferCapabilities.CtrlVolume, BlockCount * _sampleSize, waveFormat); _device.CreateSoundBuffer(description, out _buffer, IntPtr.Zero); }); ClearBuffer(); - BufferPositionNotify[] positionEvents = new BufferPositionNotify[BlockCount] + var positionEvents = new BufferPositionNotify[BlockCount] { new BufferPositionNotify(0 * _sampleSize, _position1Event), new BufferPositionNotify(1 * _sampleSize, _position2Event) }; @@ -85,10 +85,7 @@ private void Initialize() private void ClearBuffer() { - UpdateBuffer(0, 0, BufferLock.EntireBuffer, (buffer, bufferSize) => - { - MarshalHelpers.ZeroMemory(buffer, bufferSize); - }); + UpdateBuffer(0, 0, BufferLock.EntireBuffer, (buffer, bufferSize) => MarshalHelpers.ZeroMemory(buffer, bufferSize)); } private void RestoreBuffer() @@ -106,10 +103,7 @@ private void UpdateBuffer(int block) EventHandler handler = Update; if (handler != null) { - UpdateBuffer(block * _sampleSize, _sampleSize, BufferLock.None, (buffer, bufferSize) => - { - handler(this, DirectSoundUpdateEventArgs.Create(buffer, bufferSize)); - }); + UpdateBuffer(block * _sampleSize, _sampleSize, BufferLock.None, (buffer, bufferSize) => handler(this, DirectSoundUpdateEventArgs.Create(buffer, bufferSize))); } } @@ -154,7 +148,7 @@ private void Run() // com mta thread { Initialize(); - EventWaitHandle[] eventHandles = new EventWaitHandle[] { _position1Event, _position2Event, _stopEvent }; + var eventHandles = new EventWaitHandle[] { _position1Event, _position2Event, _stopEvent }; int index = WaitHandle.WaitAny(eventHandles); while (index < BlockCount) diff --git a/Library/GCHandleHelpers.cs b/Library/GCHandleHelpers.cs index 52701e8..bab841d 100644 --- a/Library/GCHandleHelpers.cs +++ b/Library/GCHandleHelpers.cs @@ -14,7 +14,7 @@ public static void Pin(object value, Action action) throw new ArgumentNullException("action"); } - GCHandle gcHandle = new GCHandle(); + var gcHandle = new GCHandle(); try { gcHandle = GCHandle.Alloc(value, GCHandleType.Pinned); diff --git a/Library/GeneralSecurity.cs b/Library/GeneralSecurity.cs index 798780d..c224790 100644 --- a/Library/GeneralSecurity.cs +++ b/Library/GeneralSecurity.cs @@ -1,277 +1,277 @@ -using System; -using System.Diagnostics.CodeAnalysis; -using System.Runtime.InteropServices; -using System.Security.AccessControl; -using System.Security.Permissions; -using System.Security.Principal; - -namespace Jellyfish.Library -{ - [StructLayout(LayoutKind.Sequential)] - public sealed class SecurityAttributes - { - [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] - public SecurityAttributes() - { - _length = Marshal.SizeOf(typeof(SecurityAttributes)); - } - - public int Length { get { return _length; } } - public IntPtr SecurityDescriptor { get { return _securityDescriptor; } set { _securityDescriptor = value; } } - public bool InheritHandle { get { return _inheritHandle; } set { _inheritHandle = value; } } - - private int _length; - private IntPtr _securityDescriptor; - private bool _inheritHandle; - } - - public sealed class GeneralAccessRule : AccessRule - { - public GeneralAccessRule(IdentityReference identity, int rights, AccessControlType type) : - base(identity, rights, false, InheritanceFlags.None, PropagationFlags.None, type) - { - } - - public GeneralAccessRule(IdentityReference identity, int rights, InheritanceFlags inheritance, PropagationFlags propagation, AccessControlType type) : - base(identity, rights, false, inheritance, propagation, type) - { - } - - public GeneralAccessRule(IdentityReference identity, int rights, bool isInherited, InheritanceFlags inheritance, PropagationFlags propagation, - AccessControlType type) : - base(identity, rights, isInherited, inheritance, propagation, type) - { - } - - public int AccessRights { get { return AccessMask; } } - } - - public sealed class GeneralAuditRule : AuditRule - { - public GeneralAuditRule(IdentityReference identity, int rights, AuditFlags audit) : - base(identity, rights, false, InheritanceFlags.None, PropagationFlags.None, audit) - { - } - - public GeneralAuditRule(IdentityReference identity, int rights, InheritanceFlags inheritance, PropagationFlags propagation, AuditFlags audit) : - base(identity, rights, false, inheritance, propagation, audit) - { - } - - public GeneralAuditRule(IdentityReference identity, int rights, bool isInherited, InheritanceFlags inheritance, PropagationFlags propagation, - AuditFlags audit) : - base(identity, rights, isInherited, inheritance, propagation, audit) - { - } - - public int AccessRights { get { return AccessMask; } } - } - - public sealed class GeneralSecurity : NativeObjectSecurity - { - public GeneralSecurity(bool isContainer, ResourceType resourceType) : - base(isContainer, resourceType) - { - } - - public GeneralSecurity(bool isContainer, ResourceType resourceType, SafeHandle handle) : - base(isContainer, resourceType, handle, AccessControlSections.Access | AccessControlSections.Group | AccessControlSections.Owner) - { - } - - public GeneralSecurity(bool isContainer, ResourceType resourceType, SafeHandle handle, AccessControlSections includeSections) : - base(isContainer, resourceType, handle, includeSections) - { - } - - public GeneralSecurity(bool isContainer, ResourceType resourceType, string name) : - base(isContainer, resourceType, name, AccessControlSections.Access | AccessControlSections.Group | AccessControlSections.Owner) - { - } - - public GeneralSecurity(bool isContainer, ResourceType resourceType, string name, AccessControlSections includeSections) : - base(isContainer, resourceType, name, includeSections) - { - } - - public override AccessRule AccessRuleFactory(IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, - PropagationFlags propagationFlags, AccessControlType type) - { - return new GeneralAccessRule(identityReference, accessMask, isInherited, inheritanceFlags, propagationFlags, type); - } - - public override AuditRule AuditRuleFactory(IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, - PropagationFlags propagationFlags, AuditFlags flags) - { - return new GeneralAuditRule(identityReference, accessMask, isInherited, inheritanceFlags, propagationFlags, flags); - } - - [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] - public void AddAccessRule(GeneralAccessRule rule) - { - base.AddAccessRule(rule); - } - - [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] - public void AddAuditRule(GeneralAuditRule rule) - { - base.AddAuditRule(rule); - } - - [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] - public void GetSecurityAttributes(bool inheritable, Action action) - { - GetSecurityAttributes(this, inheritable, action); - } - - [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] - public static void GetSecurityAttributes(ObjectSecurity security, bool inheritable, Action action) - { - if (action == null) - { - throw new ArgumentNullException("action"); - } - - if (security != null) - { - GCHandleHelpers.Pin(security.GetSecurityDescriptorBinaryForm(), securityDescriptor => - { - action(new SecurityAttributes() { SecurityDescriptor = securityDescriptor, InheritHandle = inheritable }); - }); - } - else if (inheritable) - { - action(new SecurityAttributes() { InheritHandle = inheritable }); - } - else - { - action(null); - } - } - - [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] - public bool RemoveAccessRule(GeneralAccessRule rule) - { - return base.RemoveAccessRule(rule); - } - - [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] - public void RemoveAccessRuleAll(GeneralAccessRule rule) - { - base.RemoveAccessRuleAll(rule); - } - - [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] - public void RemoveAccessRuleSpecific(GeneralAccessRule rule) - { - base.RemoveAccessRuleSpecific(rule); - } - - [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] - public bool RemoveAuditRule(GeneralAuditRule rule) - { - return base.RemoveAuditRule(rule); - } - - [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] - public void RemoveAuditRuleAll(GeneralAuditRule rule) - { - base.RemoveAuditRuleAll(rule); - } - - [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] - public void RemoveAuditRuleSpecific(GeneralAuditRule rule) - { - base.RemoveAuditRuleSpecific(rule); - } - - [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] - public void ResetAccessRule(GeneralAccessRule rule) - { - base.ResetAccessRule(rule); - } - - [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] - public void SetAccessRule(GeneralAccessRule rule) - { - base.SetAccessRule(rule); - } - - [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] - public void SetAuditRule(GeneralAuditRule rule) - { - base.SetAuditRule(rule); - } - - public void Persist(SafeHandle handle) - { - WriteLock(); - try - { - AccessControlSections sectionsModified = GetAccessControlSectionsModified(); - if (sectionsModified != AccessControlSections.None) - { - Persist(handle, sectionsModified); - ResetAccessControlSectionsModified(); - } - } - finally - { - WriteUnlock(); - } - } - - public void Persist(string name) - { - WriteLock(); - try - { - AccessControlSections sectionsModified = GetAccessControlSectionsModified(); - if (sectionsModified != AccessControlSections.None) - { - Persist(name, sectionsModified); - ResetAccessControlSectionsModified(); - } - } - finally - { - WriteUnlock(); - } - } - - private AccessControlSections GetAccessControlSectionsModified() - { - AccessControlSections sectionsModified = AccessControlSections.None; - if (AccessRulesModified) - { - sectionsModified = AccessControlSections.Access; - } - if (AuditRulesModified) - { - sectionsModified |= AccessControlSections.Audit; - } - if (OwnerModified) - { - sectionsModified |= AccessControlSections.Owner; - } - if (GroupModified) - { - sectionsModified |= AccessControlSections.Group; - } - - return sectionsModified; - } - - private void ResetAccessControlSectionsModified() - { - AccessRulesModified = false; - AuditRulesModified = false; - OwnerModified = false; - GroupModified = false; - } - - public override Type AccessRightType { get { return typeof(int); } } - public override Type AccessRuleType { get { return typeof(GeneralAccessRule); } } - public override Type AuditRuleType { get { return typeof(GeneralAuditRule); } } - } -} +using System; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; +using System.Security.AccessControl; +using System.Security.Permissions; +using System.Security.Principal; + +namespace Jellyfish.Library +{ + [StructLayout(LayoutKind.Sequential)] + public sealed class SecurityAttributes + { + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] + public SecurityAttributes() + { + _length = Marshal.SizeOf(typeof(SecurityAttributes)); + } + + public int Length { get { return _length; } } + public IntPtr SecurityDescriptor { get { return _securityDescriptor; } set { _securityDescriptor = value; } } + public bool InheritHandle { get { return _inheritHandle; } set { _inheritHandle = value; } } + + private int _length; + private IntPtr _securityDescriptor; + private bool _inheritHandle; + } + + public sealed class GeneralAccessRule : AccessRule + { + public GeneralAccessRule(IdentityReference identity, int rights, AccessControlType type) : + base(identity, rights, false, InheritanceFlags.None, PropagationFlags.None, type) + { + } + + public GeneralAccessRule(IdentityReference identity, int rights, InheritanceFlags inheritance, PropagationFlags propagation, AccessControlType type) : + base(identity, rights, false, inheritance, propagation, type) + { + } + + public GeneralAccessRule(IdentityReference identity, int rights, bool isInherited, InheritanceFlags inheritance, PropagationFlags propagation, + AccessControlType type) : + base(identity, rights, isInherited, inheritance, propagation, type) + { + } + + public int AccessRights { get { return AccessMask; } } + } + + public sealed class GeneralAuditRule : AuditRule + { + public GeneralAuditRule(IdentityReference identity, int rights, AuditFlags audit) : + base(identity, rights, false, InheritanceFlags.None, PropagationFlags.None, audit) + { + } + + public GeneralAuditRule(IdentityReference identity, int rights, InheritanceFlags inheritance, PropagationFlags propagation, AuditFlags audit) : + base(identity, rights, false, inheritance, propagation, audit) + { + } + + public GeneralAuditRule(IdentityReference identity, int rights, bool isInherited, InheritanceFlags inheritance, PropagationFlags propagation, + AuditFlags audit) : + base(identity, rights, isInherited, inheritance, propagation, audit) + { + } + + public int AccessRights { get { return AccessMask; } } + } + + public sealed class GeneralSecurity : NativeObjectSecurity + { + public GeneralSecurity(bool isContainer, ResourceType resourceType) : + base(isContainer, resourceType) + { + } + + public GeneralSecurity(bool isContainer, ResourceType resourceType, SafeHandle handle) : + base(isContainer, resourceType, handle, AccessControlSections.Access | AccessControlSections.Group | AccessControlSections.Owner) + { + } + + public GeneralSecurity(bool isContainer, ResourceType resourceType, SafeHandle handle, AccessControlSections includeSections) : + base(isContainer, resourceType, handle, includeSections) + { + } + + public GeneralSecurity(bool isContainer, ResourceType resourceType, string name) : + base(isContainer, resourceType, name, AccessControlSections.Access | AccessControlSections.Group | AccessControlSections.Owner) + { + } + + public GeneralSecurity(bool isContainer, ResourceType resourceType, string name, AccessControlSections includeSections) : + base(isContainer, resourceType, name, includeSections) + { + } + + public override AccessRule AccessRuleFactory(IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, + PropagationFlags propagationFlags, AccessControlType type) + { + return new GeneralAccessRule(identityReference, accessMask, isInherited, inheritanceFlags, propagationFlags, type); + } + + public override AuditRule AuditRuleFactory(IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, + PropagationFlags propagationFlags, AuditFlags flags) + { + return new GeneralAuditRule(identityReference, accessMask, isInherited, inheritanceFlags, propagationFlags, flags); + } + + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + public void AddAccessRule(GeneralAccessRule rule) + { + base.AddAccessRule(rule); + } + + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + public void AddAuditRule(GeneralAuditRule rule) + { + base.AddAuditRule(rule); + } + + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] + public void GetSecurityAttributes(bool inheritable, Action action) + { + GetSecurityAttributes(this, inheritable, action); + } + + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] + public static void GetSecurityAttributes(ObjectSecurity security, bool inheritable, Action action) + { + if (action == null) + { + throw new ArgumentNullException("action"); + } + + if (security != null) + { + GCHandleHelpers.Pin(security.GetSecurityDescriptorBinaryForm(), securityDescriptor => + { + action(new SecurityAttributes() { SecurityDescriptor = securityDescriptor, InheritHandle = inheritable }); + }); + } + else if (inheritable) + { + action(new SecurityAttributes() { InheritHandle = inheritable }); + } + else + { + action(null); + } + } + + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + public bool RemoveAccessRule(GeneralAccessRule rule) + { + return base.RemoveAccessRule(rule); + } + + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + public void RemoveAccessRuleAll(GeneralAccessRule rule) + { + base.RemoveAccessRuleAll(rule); + } + + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + public void RemoveAccessRuleSpecific(GeneralAccessRule rule) + { + base.RemoveAccessRuleSpecific(rule); + } + + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + public bool RemoveAuditRule(GeneralAuditRule rule) + { + return base.RemoveAuditRule(rule); + } + + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + public void RemoveAuditRuleAll(GeneralAuditRule rule) + { + base.RemoveAuditRuleAll(rule); + } + + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + public void RemoveAuditRuleSpecific(GeneralAuditRule rule) + { + base.RemoveAuditRuleSpecific(rule); + } + + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + public void ResetAccessRule(GeneralAccessRule rule) + { + base.ResetAccessRule(rule); + } + + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + public void SetAccessRule(GeneralAccessRule rule) + { + base.SetAccessRule(rule); + } + + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] + public void SetAuditRule(GeneralAuditRule rule) + { + base.SetAuditRule(rule); + } + + public void Persist(SafeHandle handle) + { + WriteLock(); + try + { + var sectionsModified = GetAccessControlSectionsModified(); + if (sectionsModified != AccessControlSections.None) + { + Persist(handle, sectionsModified); + ResetAccessControlSectionsModified(); + } + } + finally + { + WriteUnlock(); + } + } + + public void Persist(string name) + { + WriteLock(); + try + { + var sectionsModified = GetAccessControlSectionsModified(); + if (sectionsModified != AccessControlSections.None) + { + Persist(name, sectionsModified); + ResetAccessControlSectionsModified(); + } + } + finally + { + WriteUnlock(); + } + } + + private AccessControlSections GetAccessControlSectionsModified() + { + var sectionsModified = AccessControlSections.None; + if (AccessRulesModified) + { + sectionsModified = AccessControlSections.Access; + } + if (AuditRulesModified) + { + sectionsModified |= AccessControlSections.Audit; + } + if (OwnerModified) + { + sectionsModified |= AccessControlSections.Owner; + } + if (GroupModified) + { + sectionsModified |= AccessControlSections.Group; + } + + return sectionsModified; + } + + private void ResetAccessControlSectionsModified() + { + AccessRulesModified = false; + AuditRulesModified = false; + OwnerModified = false; + GroupModified = false; + } + + public override Type AccessRightType { get { return typeof(int); } } + public override Type AccessRuleType { get { return typeof(GeneralAccessRule); } } + public override Type AuditRuleType { get { return typeof(GeneralAuditRule); } } + } +} diff --git a/Library/GlobalSuppressions.cs b/Library/GlobalSuppressions.cs index 7a792e7..a2f6f28 100644 --- a/Library/GlobalSuppressions.cs +++ b/Library/GlobalSuppressions.cs @@ -1,4 +1,4 @@ -using System.Diagnostics.CodeAnalysis; - -[assembly: SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames")] -[assembly: SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Scope = "member", Target = "Jellyfish.Library.FrameRateCounter.#frameRateControl")] +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames")] +[assembly: SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Scope = "member", Target = "Jellyfish.Library.FrameRateCounter.#frameRateControl")] diff --git a/Library/IEnumerableExtensions.cs b/Library/IEnumerableExtensions.cs index 2b1bb46..764ee74 100644 --- a/Library/IEnumerableExtensions.cs +++ b/Library/IEnumerableExtensions.cs @@ -1,25 +1,25 @@ -using System; -using System.Collections.Generic; - -namespace Jellyfish.Library -{ - public static class IEnumerableExtensions - { - public static void ForEach(this IEnumerable source, Action action) - { - if (source == null) - { - throw new ArgumentNullException("source"); - } - if (action == null) - { - throw new ArgumentNullException("action"); - } - - foreach (T item in source) - { - action(item); - } - } - } -} +using System; +using System.Collections.Generic; + +namespace Jellyfish.Library +{ + public static class IEnumerableExtensions + { + public static void ForEach(this IEnumerable source, Action action) + { + if (source == null) + { + throw new ArgumentNullException("source"); + } + if (action == null) + { + throw new ArgumentNullException("action"); + } + + foreach (T item in source) + { + action(item); + } + } + } +} diff --git a/Library/Lazy.cs b/Library/Lazy.cs index 492e875..c940f57 100644 --- a/Library/Lazy.cs +++ b/Library/Lazy.cs @@ -1,37 +1,37 @@ -using System; -using System.Threading; - -namespace Jellyfish.Library -{ - public sealed class Lazy where T : class - { - public Lazy(Func initializer) - { - _initializer = initializer; - } - - public T Value - { - get - { - if (_value == null) - { - T value = _initializer(); - if (Interlocked.CompareExchange(ref _value, value, null) != null) - { - IDisposable disposable = value as IDisposable; // dispose preempted instance - if (disposable != null) - { - disposable.Dispose(); - } - } - } - - return _value; - } - } - - private Func _initializer; - private T _value; - } -} +using System; +using System.Threading; + +namespace Jellyfish.Library +{ + public sealed class Lazy where T : class + { + public Lazy(Func initializer) + { + _initializer = initializer; + } + + public T Value + { + get + { + if (_value == null) + { + T value = _initializer(); + if (Interlocked.CompareExchange(ref _value, value, null) != null) + { + var disposable = value as IDisposable; // dispose preempted instance + if (disposable != null) + { + disposable.Dispose(); + } + } + } + + return _value; + } + } + + private Func _initializer; + private T _value; + } +} diff --git a/Library/MathHelpers.cs b/Library/MathHelpers.cs index 3c31801..6ea1a70 100644 --- a/Library/MathHelpers.cs +++ b/Library/MathHelpers.cs @@ -1,15 +1,15 @@ -namespace Jellyfish.Library -{ - public static class MathHelpers - { - public static int Clamp(int value, int min, int max) - { - return (value < min) ? min : (value > max) ? max : value; - } - - public static int ClampByte(int value) - { - return Clamp(value, byte.MinValue, byte.MaxValue); - } - } -} +namespace Jellyfish.Library +{ + public static class MathHelpers + { + public static int Clamp(int value, int min, int max) + { + return (value < min) ? min : (value > max) ? max : value; + } + + public static int ClampByte(int value) + { + return Clamp(value, byte.MinValue, byte.MaxValue); + } + } +} diff --git a/Library/SafeAllocHandle.cs b/Library/SafeAllocHandle.cs index 9851bdd..8e85414 100644 --- a/Library/SafeAllocHandle.cs +++ b/Library/SafeAllocHandle.cs @@ -1,147 +1,147 @@ -using System; -using System.ComponentModel; -using System.Runtime.ConstrainedExecution; -using System.Runtime.InteropServices; -using System.Security; -using System.Security.Permissions; -using Microsoft.Win32.SafeHandles; - -namespace Jellyfish.Library -{ - [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)] - [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] - public abstract class SafeAllocHandle : SafeHandleZeroOrMinusOneIsInvalid - { - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - protected SafeAllocHandle(bool ownsHandle) : - base(ownsHandle) - { - } - } - - [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] - public sealed class SafeGlobalAllocHandle : SafeAllocHandle - { - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - public SafeGlobalAllocHandle() : - base(true) - { - } - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - public SafeGlobalAllocHandle(IntPtr existingHandle, bool ownsHandle) : - base(ownsHandle) - { - SetHandle(existingHandle); - } - - public static SafeGlobalAllocHandle Allocate(int size) - { - return Allocate(0x0, size); - } - - public static SafeGlobalAllocHandle Allocate(byte[] value) - { - if (value == null) - { - throw new ArgumentNullException("value"); - } - - SafeGlobalAllocHandle alloc = Allocate(value.Length); - Marshal.Copy(value, 0, alloc.DangerousGetHandle(), value.Length); - - return alloc; - } - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - protected override bool ReleaseHandle() - { - return (NativeMethods.GlobalFree(handle) == IntPtr.Zero); - } - - private static SafeGlobalAllocHandle Allocate(uint flags, int size) - { - SafeGlobalAllocHandle alloc = NativeMethods.GlobalAlloc(flags, (IntPtr)size); - if (alloc.IsInvalid) - { - throw new Win32Exception(); - } - - return alloc; - } - - [SuppressUnmanagedCodeSecurity] - private static class NativeMethods - { - [DllImport("kernel32.dll", SetLastError = true)] - public static extern SafeGlobalAllocHandle GlobalAlloc(uint dwFlags, IntPtr sizetBytes); - - [DllImport("kernel32.dll", SetLastError = true)] - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - public static extern IntPtr GlobalFree(IntPtr hMem); - } - } - - [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] - public sealed class SafeLocalAllocHandle : SafeAllocHandle - { - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - public SafeLocalAllocHandle() : - base(true) - { - } - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - public SafeLocalAllocHandle(IntPtr existingHandle, bool ownsHandle) : - base(ownsHandle) - { - SetHandle(existingHandle); - } - - public static SafeLocalAllocHandle Allocate(int size) - { - return Allocate(0x0, size); - } - - public static SafeLocalAllocHandle Allocate(byte[] value) - { - if (value == null) - { - throw new ArgumentNullException("value"); - } - - SafeLocalAllocHandle alloc = Allocate(value.Length); - Marshal.Copy(value, 0, alloc.DangerousGetHandle(), value.Length); - - return alloc; - } - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - protected override bool ReleaseHandle() - { - return (NativeMethods.LocalFree(handle) == IntPtr.Zero); - } - - private static SafeLocalAllocHandle Allocate(uint flags, int size) - { - SafeLocalAllocHandle alloc = NativeMethods.LocalAlloc(flags, (IntPtr)size); - if (alloc.IsInvalid) - { - throw new Win32Exception(); - } - - return alloc; - } - - [SuppressUnmanagedCodeSecurity] - private static class NativeMethods - { - [DllImport("kernel32.dll", SetLastError = true)] - public static extern SafeLocalAllocHandle LocalAlloc(uint dwFlags, IntPtr sizetBytes); - - [DllImport("kernel32.dll", SetLastError = true)] - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - public static extern IntPtr LocalFree(IntPtr hMem); - } - } -} +using System; +using System.ComponentModel; +using System.Runtime.ConstrainedExecution; +using System.Runtime.InteropServices; +using System.Security; +using System.Security.Permissions; +using Microsoft.Win32.SafeHandles; + +namespace Jellyfish.Library +{ + [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)] + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] + public abstract class SafeAllocHandle : SafeHandleZeroOrMinusOneIsInvalid + { + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] + protected SafeAllocHandle(bool ownsHandle) : + base(ownsHandle) + { + } + } + + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] + public sealed class SafeGlobalAllocHandle : SafeAllocHandle + { + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] + public SafeGlobalAllocHandle() : + base(true) + { + } + + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] + public SafeGlobalAllocHandle(IntPtr existingHandle, bool ownsHandle) : + base(ownsHandle) + { + SetHandle(existingHandle); + } + + public static SafeGlobalAllocHandle Allocate(int size) + { + return Allocate(0x0, size); + } + + public static SafeGlobalAllocHandle Allocate(byte[] value) + { + if (value == null) + { + throw new ArgumentNullException("value"); + } + + var alloc = Allocate(value.Length); + Marshal.Copy(value, 0, alloc.DangerousGetHandle(), value.Length); + + return alloc; + } + + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] + protected override bool ReleaseHandle() + { + return (NativeMethods.GlobalFree(handle) == IntPtr.Zero); + } + + private static SafeGlobalAllocHandle Allocate(uint flags, int size) + { + var alloc = NativeMethods.GlobalAlloc(flags, (IntPtr)size); + if (alloc.IsInvalid) + { + throw new Win32Exception(); + } + + return alloc; + } + + [SuppressUnmanagedCodeSecurity] + private static class NativeMethods + { + [DllImport("kernel32.dll", SetLastError = true)] + public static extern SafeGlobalAllocHandle GlobalAlloc(uint dwFlags, IntPtr sizetBytes); + + [DllImport("kernel32.dll", SetLastError = true)] + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] + public static extern IntPtr GlobalFree(IntPtr hMem); + } + } + + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] + public sealed class SafeLocalAllocHandle : SafeAllocHandle + { + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] + public SafeLocalAllocHandle() : + base(true) + { + } + + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] + public SafeLocalAllocHandle(IntPtr existingHandle, bool ownsHandle) : + base(ownsHandle) + { + SetHandle(existingHandle); + } + + public static SafeLocalAllocHandle Allocate(int size) + { + return Allocate(0x0, size); + } + + public static SafeLocalAllocHandle Allocate(byte[] value) + { + if (value == null) + { + throw new ArgumentNullException("value"); + } + + var alloc = Allocate(value.Length); + Marshal.Copy(value, 0, alloc.DangerousGetHandle(), value.Length); + + return alloc; + } + + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] + protected override bool ReleaseHandle() + { + return (NativeMethods.LocalFree(handle) == IntPtr.Zero); + } + + private static SafeLocalAllocHandle Allocate(uint flags, int size) + { + var alloc = NativeMethods.LocalAlloc(flags, (IntPtr)size); + if (alloc.IsInvalid) + { + throw new Win32Exception(); + } + + return alloc; + } + + [SuppressUnmanagedCodeSecurity] + private static class NativeMethods + { + [DllImport("kernel32.dll", SetLastError = true)] + public static extern SafeLocalAllocHandle LocalAlloc(uint dwFlags, IntPtr sizetBytes); + + [DllImport("kernel32.dll", SetLastError = true)] + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] + public static extern IntPtr LocalFree(IntPtr hMem); + } + } +} diff --git a/Library/SafeFileHandle.cs b/Library/SafeFileHandle.cs index 3f19320..e7f68ff 100644 --- a/Library/SafeFileHandle.cs +++ b/Library/SafeFileHandle.cs @@ -1,95 +1,95 @@ -using System; -using System.ComponentModel; -using System.Diagnostics.CodeAnalysis; -using System.IO; -using System.Runtime.ConstrainedExecution; -using System.Runtime.InteropServices; -using System.Security; -using System.Security.AccessControl; -using System.Security.Permissions; -using Microsoft.Win32.SafeHandles; - -namespace Jellyfish.Library -{ - [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] - public sealed class SafeFileHandle : SafeHandleZeroOrMinusOneIsInvalid - { - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - public SafeFileHandle() : - base(true) - { - } - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - public SafeFileHandle(IntPtr existingHandle, bool ownsHandle) : - base(ownsHandle) - { - SetHandle(existingHandle); - } - - public static SafeFileHandle CreateFile(string fileName, FileAccess fileAccess, FileShare fileShare, FileMode fileMode, GeneralSecurity fileSecurity) - { - if (fileMode == FileMode.Append) - { - throw new NotImplementedException(); - } - - bool inheritable = ((fileShare & FileShare.Inheritable) != 0); - fileShare &= ~FileShare.Inheritable; - - return CreateFile(fileName, (uint)fileAccess, (uint)fileShare, (uint)fileMode, 0x0, fileSecurity, inheritable); - } - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - protected override bool ReleaseHandle() - { - return NativeMethods.CloseHandle(handle); - } - - [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")] - public GeneralSecurity GetAccessControl() - { - return new GeneralSecurity(false, ResourceType.FileObject, this); - } - - public void SetAccessControl(GeneralSecurity fileSecurity) - { - if (fileSecurity == null) - { - throw new ArgumentNullException("fileSecurity"); - } - - fileSecurity.Persist(this); - } - - private static SafeFileHandle CreateFile(string fileName, uint fileAccess, uint fileShare, uint fileMode, uint fileOptions, GeneralSecurity fileSecurity, - bool inheritable) - { - SafeFileHandle file = new SafeFileHandle(); - - GeneralSecurity.GetSecurityAttributes(fileSecurity, inheritable, securityAttributes => - { - file = NativeMethods.CreateFile(fileName, fileAccess, fileShare, securityAttributes, fileMode, fileOptions, IntPtr.Zero); - if (file.IsInvalid) - { - throw new Win32Exception(); - } - }); - - return file; - } - - [SuppressUnmanagedCodeSecurity] - private static class NativeMethods - { - [DllImport("kernel32.dll", SetLastError = true)] - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool CloseHandle(IntPtr handle); - - [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] - public static extern SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess, uint dwShareMode, SecurityAttributes lpSecurityAttributes, - uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile); - } - } -} +using System; +using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Runtime.ConstrainedExecution; +using System.Runtime.InteropServices; +using System.Security; +using System.Security.AccessControl; +using System.Security.Permissions; +using Microsoft.Win32.SafeHandles; + +namespace Jellyfish.Library +{ + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] + public sealed class SafeFileHandle : SafeHandleZeroOrMinusOneIsInvalid + { + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] + public SafeFileHandle() : + base(true) + { + } + + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] + public SafeFileHandle(IntPtr existingHandle, bool ownsHandle) : + base(ownsHandle) + { + SetHandle(existingHandle); + } + + public static SafeFileHandle CreateFile(string fileName, FileAccess fileAccess, FileShare fileShare, FileMode fileMode, GeneralSecurity fileSecurity) + { + if (fileMode == FileMode.Append) + { + throw new NotImplementedException(); + } + + bool inheritable = ((fileShare & FileShare.Inheritable) != 0); + fileShare &= ~FileShare.Inheritable; + + return CreateFile(fileName, (uint)fileAccess, (uint)fileShare, (uint)fileMode, 0x0, fileSecurity, inheritable); + } + + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] + protected override bool ReleaseHandle() + { + return NativeMethods.CloseHandle(handle); + } + + [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")] + public GeneralSecurity GetAccessControl() + { + return new GeneralSecurity(false, ResourceType.FileObject, this); + } + + public void SetAccessControl(GeneralSecurity fileSecurity) + { + if (fileSecurity == null) + { + throw new ArgumentNullException("fileSecurity"); + } + + fileSecurity.Persist(this); + } + + private static SafeFileHandle CreateFile(string fileName, uint fileAccess, uint fileShare, uint fileMode, uint fileOptions, GeneralSecurity fileSecurity, + bool inheritable) + { + var file = new SafeFileHandle(); + + GeneralSecurity.GetSecurityAttributes(fileSecurity, inheritable, securityAttributes => + { + file = NativeMethods.CreateFile(fileName, fileAccess, fileShare, securityAttributes, fileMode, fileOptions, IntPtr.Zero); + if (file.IsInvalid) + { + throw new Win32Exception(); + } + }); + + return file; + } + + [SuppressUnmanagedCodeSecurity] + private static class NativeMethods + { + [DllImport("kernel32.dll", SetLastError = true)] + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool CloseHandle(IntPtr handle); + + [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] + public static extern SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess, uint dwShareMode, SecurityAttributes lpSecurityAttributes, + uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile); + } + } +} diff --git a/Library/Silverlight/ApplicationBase.cs b/Library/Silverlight/ApplicationBase.cs index b3c287d..7860f75 100644 --- a/Library/Silverlight/ApplicationBase.cs +++ b/Library/Silverlight/ApplicationBase.cs @@ -1,65 +1,65 @@ -using System; -using System.Text; -using System.Windows; - -namespace Jellyfish.Library -{ - public class ApplicationBase : Application - { - public ApplicationBase() : - this(null) - { - } - - public ApplicationBase(string name) - { - Name = name; - - UnhandledException += OnApplicationUnhandledException; - //AppDomain.CurrentDomain.UnhandledException += OnAppDomainUnhandledException; - } - - private void OnApplicationUnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e) - { - MessageBox.Show(GetExceptionMessage(e.ExceptionObject), GetExceptionCaption("Application Exception", false), MessageBoxButton.OK); - e.Handled = true; - } - - //private void OnAppDomainUnhandledException(object sender, UnhandledExceptionEventArgs e) - //{ - // MessageBox.Show(GetExceptionMessage(e.ExceptionObject as Exception), GetExceptionCaption("AppDomain Exception", e.IsTerminating), MessageBoxButton.OK); - //} - - private string GetExceptionCaption(string title, bool isTerminating) - { - StringBuilder caption = new StringBuilder(); - if (!string.IsNullOrEmpty(Name)) - { - caption.Append(Name); - caption.Append(" "); - } - caption.Append(title); - if (isTerminating) - { - caption.Append(" (Terminating)"); - } - - return caption.ToString(); - } - - private static string GetExceptionMessage(Exception exception) - { - StringBuilder message = new StringBuilder(); - if (exception != null) - { - message.Append(exception.Message.ToString()); - message.Append(Environment.NewLine); - message.Append(exception.StackTrace.ToString()); - } - - return message.ToString(); - } - - public string Name { get; private set; } - } -} +using System; +using System.Text; +using System.Windows; + +namespace Jellyfish.Library +{ + public class ApplicationBase : Application + { + public ApplicationBase() : + this(null) + { + } + + public ApplicationBase(string name) + { + Name = name; + + UnhandledException += OnApplicationUnhandledException; + //AppDomain.CurrentDomain.UnhandledException += OnAppDomainUnhandledException; + } + + private void OnApplicationUnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e) + { + MessageBox.Show(GetExceptionMessage(e.ExceptionObject), GetExceptionCaption("Application Exception", false), MessageBoxButton.OK); + e.Handled = true; + } + + //private void OnAppDomainUnhandledException(object sender, UnhandledExceptionEventArgs e) + //{ + // MessageBox.Show(GetExceptionMessage(e.ExceptionObject as Exception), GetExceptionCaption("AppDomain Exception", e.IsTerminating), MessageBoxButton.OK); + //} + + private string GetExceptionCaption(string title, bool isTerminating) + { + var caption = new StringBuilder(); + if (!string.IsNullOrEmpty(Name)) + { + caption.Append(Name); + caption.Append(" "); + } + caption.Append(title); + if (isTerminating) + { + caption.Append(" (Terminating)"); + } + + return caption.ToString(); + } + + private static string GetExceptionMessage(Exception exception) + { + var message = new StringBuilder(); + if (exception != null) + { + message.Append(exception.Message.ToString()); + message.Append(Environment.NewLine); + message.Append(exception.StackTrace.ToString()); + } + + return message.ToString(); + } + + public string Name { get; private set; } + } +} diff --git a/Library/Silverlight/FrameRateCounter.xaml b/Library/Silverlight/FrameRateCounter.xaml index b116f0f..1fd81ad 100644 --- a/Library/Silverlight/FrameRateCounter.xaml +++ b/Library/Silverlight/FrameRateCounter.xaml @@ -1,13 +1,13 @@ - - - - - - - - - - + + + + + + + + + + diff --git a/Library/Silverlight/FrameRateCounter.xaml.cs b/Library/Silverlight/FrameRateCounter.xaml.cs index 3a91b3d..1ccf20d 100644 --- a/Library/Silverlight/FrameRateCounter.xaml.cs +++ b/Library/Silverlight/FrameRateCounter.xaml.cs @@ -1,42 +1,42 @@ -using System; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media; - -namespace Jellyfish.Library -{ - public sealed partial class FrameRateCounter : UserControl - { - public FrameRateCounter() - { - InitializeComponent(); - - CompositionTarget.Rendering += OnCompositionTargetRendering; - } - - private void OnCompositionTargetRendering(object sender, EventArgs e) - { - _frameCount++; - - long time = DateTime.UtcNow.Ticks; - if (time - _lastTime >= TimeSpan.TicksPerSecond) - { - _lastTime = time; - FrameRate = _frameCount; - _frameCount = 0; - } - } - - public static readonly DependencyProperty FrameRateProperty = DependencyProperty.Register("FrameRate", typeof(int), typeof(FrameRateCounter), - new PropertyMetadata(0)); - - public int FrameRate - { - get { return (int)GetValue(FrameRateProperty); } - set { SetValue(FrameRateProperty, value); } - } - - private int _frameCount; - private long _lastTime; - } -} +using System; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Media; + +namespace Jellyfish.Library +{ + public sealed partial class FrameRateCounter : UserControl + { + public FrameRateCounter() + { + InitializeComponent(); + + CompositionTarget.Rendering += OnCompositionTargetRendering; + } + + private void OnCompositionTargetRendering(object sender, EventArgs e) + { + _frameCount++; + + long time = DateTime.UtcNow.Ticks; + if (time - _lastTime >= TimeSpan.TicksPerSecond) + { + _lastTime = time; + FrameRate = _frameCount; + _frameCount = 0; + } + } + + public static readonly DependencyProperty FrameRateProperty = DependencyProperty.Register("FrameRate", typeof(int), typeof(FrameRateCounter), + new PropertyMetadata(0)); + + public int FrameRate + { + get { return (int)GetValue(FrameRateProperty); } + set { SetValue(FrameRateProperty, value); } + } + + private int _frameCount; + private long _lastTime; + } +} diff --git a/Library/Silverlight/Properties/AssemblyInfo.cs b/Library/Silverlight/Properties/AssemblyInfo.cs index e429c70..fdac8bc 100644 --- a/Library/Silverlight/Properties/AssemblyInfo.cs +++ b/Library/Silverlight/Properties/AssemblyInfo.cs @@ -1,22 +1,22 @@ -using System; -using System.Reflection; -using System.Resources; -using System.Runtime.InteropServices; -using Jellyfish.Library; - -[assembly: AssemblyTitle("Library")] -[assembly: AssemblyDescription("Common Library")] -[assembly: AssemblyProduct("Jellyfish.Library.Silverlight")] -[assembly: AssemblyCompany("Digital Jellyfish Design Ltd")] -[assembly: AssemblyCopyright("Copyright © 2009-2010 Digital Jellyfish Design Ltd")] -[assembly: AssemblyComment("Developed by Sean Fausett")] - -[assembly: AssemblyVersion("0.1.0.0")] -[assembly: AssemblyFileVersion("0.1.0.0")] -[assembly: AssemblyInformationalVersion("0.1.0.0")] - -[assembly: CLSCompliant(false)] -[assembly: ComVisible(false)] -[assembly: Guid("66034b9e-9f0b-47b0-aac4-cade9a748891")] - -[assembly: NeutralResourcesLanguage("en")] +using System; +using System.Reflection; +using System.Resources; +using System.Runtime.InteropServices; +using Jellyfish.Library; + +[assembly: AssemblyTitle("Library")] +[assembly: AssemblyDescription("Common Library")] +[assembly: AssemblyProduct("Jellyfish.Library.Silverlight")] +[assembly: AssemblyCompany("Digital Jellyfish Design Ltd")] +[assembly: AssemblyCopyright("Copyright © 2009-2010 Digital Jellyfish Design Ltd")] +[assembly: AssemblyComment("Developed by Sean Fausett")] + +[assembly: AssemblyVersion("0.1.0.0")] +[assembly: AssemblyFileVersion("0.1.0.0")] +[assembly: AssemblyInformationalVersion("0.1.0.0")] + +[assembly: CLSCompliant(false)] +[assembly: ComVisible(false)] +[assembly: Guid("66034b9e-9f0b-47b0-aac4-cade9a748891")] + +[assembly: NeutralResourcesLanguage("en")] diff --git a/Library/Silverlight/StringFormatConverter.cs b/Library/Silverlight/StringFormatConverter.cs index ecb203a..99edc1c 100644 --- a/Library/Silverlight/StringFormatConverter.cs +++ b/Library/Silverlight/StringFormatConverter.cs @@ -1,41 +1,41 @@ -using System; -using System.Globalization; -using System.Windows; -using System.Windows.Data; - -namespace Jellyfish.Library -{ - public sealed class StringFormatConverter : IValueConverter // SL is missing Binding.StringFormat - { - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - if (targetType != typeof(string)) - { - return DependencyProperty.UnsetValue; - } - - if (value == null) - { - return string.Empty; - } - - string format = parameter as string; - if (!string.IsNullOrEmpty(format)) - { - if (format.IndexOf('{') < 0) - { - format = "{0:" + format + "}"; - } - - return string.Format(culture, format, value); - } - - return value.ToString(); - } - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - return DependencyProperty.UnsetValue; // one way only - } - } -} +using System; +using System.Globalization; +using System.Windows; +using System.Windows.Data; + +namespace Jellyfish.Library +{ + public sealed class StringFormatConverter : IValueConverter // SL is missing Binding.StringFormat + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (targetType != typeof(string)) + { + return DependencyProperty.UnsetValue; + } + + if (value == null) + { + return string.Empty; + } + + string format = parameter as string; + if (!string.IsNullOrEmpty(format)) + { + if (format.IndexOf('{') < 0) + { + format = "{0:" + format + "}"; + } + + return string.Format(culture, format, value); + } + + return value.ToString(); + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + return DependencyProperty.UnsetValue; // one way only + } + } +} diff --git a/Library/SingletonFactory.cs b/Library/SingletonFactory.cs index 66e91fb..58340ad 100644 --- a/Library/SingletonFactory.cs +++ b/Library/SingletonFactory.cs @@ -1,18 +1,18 @@ -using System.Diagnostics.CodeAnalysis; - -namespace Jellyfish.Library -{ - public static class SingletonFactory where T : class, new() - { - [SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes")] - public static T Create() - { - return _instance; - } - - [SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes")] - public static T Instance { get { return _instance; } } - - private static readonly T _instance = new T(); - } -} +using System.Diagnostics.CodeAnalysis; + +namespace Jellyfish.Library +{ + public static class SingletonFactory where T : class, new() + { + [SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes")] + public static T Create() + { + return _instance; + } + + [SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes")] + public static T Instance { get { return _instance; } } + + private static readonly T _instance = new T(); + } +} diff --git a/Library/StreamExtensions.cs b/Library/StreamExtensions.cs index 15f2244..4325e2b 100644 --- a/Library/StreamExtensions.cs +++ b/Library/StreamExtensions.cs @@ -1,40 +1,40 @@ -using System; -using System.IO; - -namespace Jellyfish.Library -{ - public static class StreamExtensions - { - public static byte[] ReadAllBytes(this Stream stream) - { - if (stream == null) - { - throw new ArgumentNullException("stream"); - } - - int count = (int)stream.Length; - byte[] buffer = new byte[count]; - ReadBlock(stream, buffer, 0, count); - - return buffer; - } - - public static int ReadBlock(this Stream stream, byte[] buffer, int offset, int count) - { - if (stream == null) - { - throw new ArgumentNullException("stream"); - } - - int total = 0; - int read; - do - { - total += read = stream.Read(buffer, offset + total, count - total); - } - while ((read > 0) && (total < count)); - - return total; - } - } -} +using System; +using System.IO; + +namespace Jellyfish.Library +{ + public static class StreamExtensions + { + public static byte[] ReadAllBytes(this Stream stream) + { + if (stream == null) + { + throw new ArgumentNullException("stream"); + } + + int count = (int)stream.Length; + byte[] buffer = new byte[count]; + ReadBlock(stream, buffer, 0, count); + + return buffer; + } + + public static int ReadBlock(this Stream stream, byte[] buffer, int offset, int count) + { + if (stream == null) + { + throw new ArgumentNullException("stream"); + } + + int total = 0; + int read; + do + { + total += read = stream.Read(buffer, offset + total, count - total); + } + while ((read > 0) && (total < count)); + + return total; + } + } +} diff --git a/Library/StringBuilderExtensions.cs b/Library/StringBuilderExtensions.cs index 2c5c9e8..7a7edb3 100644 --- a/Library/StringBuilderExtensions.cs +++ b/Library/StringBuilderExtensions.cs @@ -1,38 +1,38 @@ -using System.Globalization; -using System.Text; - -namespace Jellyfish.Library -{ - public static class StringBuilderExtensions - { - public static StringBuilder AppendHex(this StringBuilder builder, short value) // little endian - { - return builder.AppendFormat(CultureInfo.InvariantCulture, "{0:X2}{1:X2}", value & 0xFF, value >> 8); - } - - public static StringBuilder AppendHex(this StringBuilder builder, int value) // little endian - { - return builder.AppendFormat(CultureInfo.InvariantCulture, "{0:X2}{1:X2}{2:X2}{3:X2}", value & 0xFF, (value >> 8) & 0xFF, (value >> 16) & 0xFF, value >> 24); - } - - public static StringBuilder AppendWithoutGarbage(this StringBuilder builder, int value) - { - if (value < 0) - { - builder.Append('-'); - } - - int index = builder.Length; - do - { - builder.Insert(index, Digits, (value % 10) + 9, 1); - value /= 10; - } - while (value != 0); - - return builder; - } - - private static readonly char[] Digits = new char[] { '9', '8', '7', '6', '5', '4', '3', '2', '1', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; - } -} +using System.Globalization; +using System.Text; + +namespace Jellyfish.Library +{ + public static class StringBuilderExtensions + { + public static StringBuilder AppendHex(this StringBuilder builder, short value) // little endian + { + return builder.AppendFormat(CultureInfo.InvariantCulture, "{0:X2}{1:X2}", value & 0xFF, value >> 8); + } + + public static StringBuilder AppendHex(this StringBuilder builder, int value) // little endian + { + return builder.AppendFormat(CultureInfo.InvariantCulture, "{0:X2}{1:X2}{2:X2}{3:X2}", value & 0xFF, (value >> 8) & 0xFF, (value >> 16) & 0xFF, value >> 24); + } + + public static StringBuilder AppendWithoutGarbage(this StringBuilder builder, int value) + { + if (value < 0) + { + builder.Append('-'); + } + + int index = builder.Length; + do + { + builder.Insert(index, Digits, (value % 10) + 9, 1); + value /= 10; + } + while (value != 0); + + return builder; + } + + private static readonly char[] Digits = new char[] { '9', '8', '7', '6', '5', '4', '3', '2', '1', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; + } +} diff --git a/Library/WaveFormat.cs b/Library/WaveFormat.cs index da82b2f..8efb65f 100644 --- a/Library/WaveFormat.cs +++ b/Library/WaveFormat.cs @@ -18,7 +18,7 @@ public WaveFormat(int sampleRate, int sampleChannels, int sampleBits) public string ToHexString() // little endian { - StringBuilder builder = new StringBuilder(); + var builder = new StringBuilder(); builder.AppendHex(_formatTag); builder.AppendHex(_channels); diff --git a/Library/Wpf/ApplicationBase.cs b/Library/Wpf/ApplicationBase.cs index b6aad18..ed62bb2 100644 --- a/Library/Wpf/ApplicationBase.cs +++ b/Library/Wpf/ApplicationBase.cs @@ -1,72 +1,72 @@ -using System; -using System.Diagnostics; -using System.Security.Permissions; -using System.Text; -using System.Windows; -using System.Windows.Threading; - -namespace Jellyfish.Library -{ - public class ApplicationBase : Application - { - [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] - public ApplicationBase() : - this(null) - { - } - - [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] - public ApplicationBase(string name) - { - Name = name; - - DispatcherUnhandledException += OnApplicationDispatcherUnhandledException; - AppDomain.CurrentDomain.UnhandledException += OnAppDomainUnhandledException; - } - - private void OnApplicationDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) - { - MessageBox.Show(GetExceptionMessage(e.Exception), GetExceptionCaption("Application Dispatcher Exception", true)); - e.Handled = true; - Shutdown(); - } - - private void OnAppDomainUnhandledException(object sender, UnhandledExceptionEventArgs e) - { - MessageBox.Show(GetExceptionMessage(e.ExceptionObject as Exception), GetExceptionCaption("AppDomain Exception", e.IsTerminating)); - } - - private string GetExceptionCaption(string title, bool isTerminating) - { - StringBuilder caption = new StringBuilder(); - caption.AppendFormat("[{0}] ", Process.GetCurrentProcess().Id); - if (!string.IsNullOrEmpty(Name)) - { - caption.Append(Name); - caption.Append(" "); - } - caption.Append(title); - if (isTerminating) - { - caption.Append(" (Terminating)"); - } - - return caption.ToString(); - } - - private static string GetExceptionMessage(Exception exception) - { - StringBuilder message = new StringBuilder(); - if (exception != null) - { - message.Append(exception.Message.ToString()); - message.Append(Environment.NewLine); - message.Append(exception.StackTrace.ToString()); - } - - return message.ToString(); - } - - public string Name { get; private set; } - } -} +using System; +using System.Diagnostics; +using System.Security.Permissions; +using System.Text; +using System.Windows; +using System.Windows.Threading; + +namespace Jellyfish.Library +{ + public class ApplicationBase : Application + { + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] + public ApplicationBase() : + this(null) + { + } + + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] + public ApplicationBase(string name) + { + Name = name; + + DispatcherUnhandledException += OnApplicationDispatcherUnhandledException; + AppDomain.CurrentDomain.UnhandledException += OnAppDomainUnhandledException; + } + + private void OnApplicationDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) + { + MessageBox.Show(GetExceptionMessage(e.Exception), GetExceptionCaption("Application Dispatcher Exception", true)); + e.Handled = true; + Shutdown(); + } + + private void OnAppDomainUnhandledException(object sender, UnhandledExceptionEventArgs e) + { + MessageBox.Show(GetExceptionMessage(e.ExceptionObject as Exception), GetExceptionCaption("AppDomain Exception", e.IsTerminating)); + } + + private string GetExceptionCaption(string title, bool isTerminating) + { + var caption = new StringBuilder(); + caption.AppendFormat("[{0}] ", Process.GetCurrentProcess().Id); + if (!string.IsNullOrEmpty(Name)) + { + caption.Append(Name); + caption.Append(" "); + } + caption.Append(title); + if (isTerminating) + { + caption.Append(" (Terminating)"); + } + + return caption.ToString(); + } + + private static string GetExceptionMessage(Exception exception) + { + var message = new StringBuilder(); + if (exception != null) + { + message.Append(exception.Message.ToString()); + message.Append(Environment.NewLine); + message.Append(exception.StackTrace.ToString()); + } + + return message.ToString(); + } + + public string Name { get; private set; } + } +} diff --git a/Library/Wpf/FrameRateCounter.xaml b/Library/Wpf/FrameRateCounter.xaml index 3064c94..86d9bc9 100644 --- a/Library/Wpf/FrameRateCounter.xaml +++ b/Library/Wpf/FrameRateCounter.xaml @@ -1,9 +1,9 @@ - - - - - - - + + + + + + + diff --git a/Library/Wpf/FrameRateCounter.xaml.cs b/Library/Wpf/FrameRateCounter.xaml.cs index 3a91b3d..1ccf20d 100644 --- a/Library/Wpf/FrameRateCounter.xaml.cs +++ b/Library/Wpf/FrameRateCounter.xaml.cs @@ -1,42 +1,42 @@ -using System; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media; - -namespace Jellyfish.Library -{ - public sealed partial class FrameRateCounter : UserControl - { - public FrameRateCounter() - { - InitializeComponent(); - - CompositionTarget.Rendering += OnCompositionTargetRendering; - } - - private void OnCompositionTargetRendering(object sender, EventArgs e) - { - _frameCount++; - - long time = DateTime.UtcNow.Ticks; - if (time - _lastTime >= TimeSpan.TicksPerSecond) - { - _lastTime = time; - FrameRate = _frameCount; - _frameCount = 0; - } - } - - public static readonly DependencyProperty FrameRateProperty = DependencyProperty.Register("FrameRate", typeof(int), typeof(FrameRateCounter), - new PropertyMetadata(0)); - - public int FrameRate - { - get { return (int)GetValue(FrameRateProperty); } - set { SetValue(FrameRateProperty, value); } - } - - private int _frameCount; - private long _lastTime; - } -} +using System; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Media; + +namespace Jellyfish.Library +{ + public sealed partial class FrameRateCounter : UserControl + { + public FrameRateCounter() + { + InitializeComponent(); + + CompositionTarget.Rendering += OnCompositionTargetRendering; + } + + private void OnCompositionTargetRendering(object sender, EventArgs e) + { + _frameCount++; + + long time = DateTime.UtcNow.Ticks; + if (time - _lastTime >= TimeSpan.TicksPerSecond) + { + _lastTime = time; + FrameRate = _frameCount; + _frameCount = 0; + } + } + + public static readonly DependencyProperty FrameRateProperty = DependencyProperty.Register("FrameRate", typeof(int), typeof(FrameRateCounter), + new PropertyMetadata(0)); + + public int FrameRate + { + get { return (int)GetValue(FrameRateProperty); } + set { SetValue(FrameRateProperty, value); } + } + + private int _frameCount; + private long _lastTime; + } +} diff --git a/Library/Wpf/Properties/AssemblyInfo.cs b/Library/Wpf/Properties/AssemblyInfo.cs index b564d21..f0d9ae0 100644 --- a/Library/Wpf/Properties/AssemblyInfo.cs +++ b/Library/Wpf/Properties/AssemblyInfo.cs @@ -1,22 +1,22 @@ -using System; -using System.Reflection; -using System.Resources; -using System.Runtime.InteropServices; -using Jellyfish.Library; - -[assembly: AssemblyTitle("Library")] -[assembly: AssemblyDescription("Common Library")] -[assembly: AssemblyProduct("Jellyfish.Library.Wpf")] -[assembly: AssemblyCompany("Digital Jellyfish Design Ltd")] -[assembly: AssemblyCopyright("Copyright © 2009-2010 Digital Jellyfish Design Ltd")] -[assembly: AssemblyComment("Developed by Sean Fausett")] - -[assembly: AssemblyVersion("0.1.0.0")] -[assembly: AssemblyFileVersion("0.1.0.0")] -[assembly: AssemblyInformationalVersion("0.1.0.0")] - -[assembly: CLSCompliant(false)] -[assembly: ComVisible(false)] -[assembly: Guid("66034b9e-9f0b-47b0-aac4-cade9a748891")] - -[assembly: NeutralResourcesLanguage("en")] +using System; +using System.Reflection; +using System.Resources; +using System.Runtime.InteropServices; +using Jellyfish.Library; + +[assembly: AssemblyTitle("Library")] +[assembly: AssemblyDescription("Common Library")] +[assembly: AssemblyProduct("Jellyfish.Library.Wpf")] +[assembly: AssemblyCompany("Digital Jellyfish Design Ltd")] +[assembly: AssemblyCopyright("Copyright © 2009-2010 Digital Jellyfish Design Ltd")] +[assembly: AssemblyComment("Developed by Sean Fausett")] + +[assembly: AssemblyVersion("0.1.0.0")] +[assembly: AssemblyFileVersion("0.1.0.0")] +[assembly: AssemblyInformationalVersion("0.1.0.0")] + +[assembly: CLSCompliant(false)] +[assembly: ComVisible(false)] +[assembly: Guid("66034b9e-9f0b-47b0-aac4-cade9a748891")] + +[assembly: NeutralResourcesLanguage("en")] diff --git a/Library/XmlSerializerHelpers.cs b/Library/XmlSerializerHelpers.cs index ecd3eff..8f98886 100644 --- a/Library/XmlSerializerHelpers.cs +++ b/Library/XmlSerializerHelpers.cs @@ -1,40 +1,40 @@ -using System.Diagnostics.CodeAnalysis; -using System.IO; -using System.Xml; -using System.Xml.Serialization; - -namespace Jellyfish.Library -{ - public static class XmlSerializerHelpers - { - [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")] - public static T Deserialize(Stream stream) - { - return Deserialize(stream, null); - } - - [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")] - public static T Deserialize(Stream stream, string defaultNamespace) - { - using (XmlReader reader = XmlReader.Create(stream)) - { - XmlSerializer serializer = new XmlSerializer(typeof(T), defaultNamespace); - return (T)serializer.Deserialize(reader); - } - } - - public static void Serialize(Stream stream, T instance) - { - Serialize(stream, instance, null); - } - - public static void Serialize(Stream stream, T instance, string defaultNamespace) - { - using (XmlWriter writer = XmlWriter.Create(stream)) - { - XmlSerializer serializer = new XmlSerializer(typeof(T), defaultNamespace); - serializer.Serialize(writer, instance); - } - } - } -} +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Xml; +using System.Xml.Serialization; + +namespace Jellyfish.Library +{ + public static class XmlSerializerHelpers + { + [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")] + public static T Deserialize(Stream stream) + { + return Deserialize(stream, null); + } + + [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")] + public static T Deserialize(Stream stream, string defaultNamespace) + { + using (var reader = XmlReader.Create(stream)) + { + var serializer = new XmlSerializer(typeof(T), defaultNamespace); + return (T)serializer.Deserialize(reader); + } + } + + public static void Serialize(Stream stream, T instance) + { + Serialize(stream, instance, null); + } + + public static void Serialize(Stream stream, T instance, string defaultNamespace) + { + using (var writer = XmlWriter.Create(stream)) + { + var serializer = new XmlSerializer(typeof(T), defaultNamespace); + serializer.Serialize(writer, instance); + } + } + } +} diff --git a/Library/Xna/FrameRateCounter.cs b/Library/Xna/FrameRateCounter.cs index 67faea4..52c016b 100644 --- a/Library/Xna/FrameRateCounter.cs +++ b/Library/Xna/FrameRateCounter.cs @@ -1,71 +1,71 @@ -using System; -using System.Text; -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; - -namespace Jellyfish.Library -{ - public sealed class FrameRateCounter : DrawableGameComponent - { - public FrameRateCounter(GameBase game) : - base(game) - { - FontColor = Color.White; - FontName = "Default"; - - //game.IsFixedTimeStep = true; // fixed (default) - //game.TargetElapsedTime = TimeSpan.FromSeconds(1 / 60f); - - //game.IsFixedTimeStep = false; // flatout - //game.GraphicsDeviceManager.SynchronizeWithVerticalRetrace = false; - } - - protected override void LoadContent() - { - _spriteBatch = new SpriteBatch(GraphicsDevice); - _spriteFont = Game.Content.Load(FontName); - - Rectangle titleSafeArea = Game.GraphicsDevice.DisplayMode.TitleSafeArea; - Position = new Vector2(titleSafeArea.X, titleSafeArea.Y); - } - - public override void Draw(GameTime gameTime) - { - _frameCount++; - - _frameRateBuilder.Length = 0; - _frameRateBuilder.AppendWithoutGarbage(_frameRate).Append(" fps"); - - _spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.None); - //_spriteBatch.DrawString(_spriteFont, fps, Position - Vector2.UnitX, Color.Black); // rough outline - //_spriteBatch.DrawString(_spriteFont, fps, Position + Vector2.UnitX, Color.Black); - //_spriteBatch.DrawString(_spriteFont, fps, Position - Vector2.UnitY, Color.Black); - //_spriteBatch.DrawString(_spriteFont, fps, Position + Vector2.UnitY, Color.Black); - _spriteBatch.DrawString(_spriteFont, _frameRateBuilder, Position, FontColor); - _spriteBatch.End(); - } - - public override void Update(GameTime gameTime) - { - _elapsedTime += gameTime.ElapsedGameTime.Ticks; - - if (_elapsedTime >= TimeSpan.TicksPerSecond) - { - _elapsedTime -= TimeSpan.TicksPerSecond; - _frameRate = _frameCount; - _frameCount = 0; - } - } - - public Color FontColor { get; set; } - public string FontName { get; set; } - public Vector2 Position { get; set; } - - private SpriteBatch _spriteBatch; - private SpriteFont _spriteFont; - private long _elapsedTime; - private int _frameCount; - private int _frameRate; - private StringBuilder _frameRateBuilder = new StringBuilder(); // cache builder; avoids garbage - } -} +using System; +using System.Text; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace Jellyfish.Library +{ + public sealed class FrameRateCounter : DrawableGameComponent + { + public FrameRateCounter(GameBase game) : + base(game) + { + FontColor = Color.White; + FontName = "Default"; + + //game.IsFixedTimeStep = true; // fixed (default) + //game.TargetElapsedTime = TimeSpan.FromSeconds(1 / 60f); + + //game.IsFixedTimeStep = false; // flatout + //game.GraphicsDeviceManager.SynchronizeWithVerticalRetrace = false; + } + + protected override void LoadContent() + { + _spriteBatch = new SpriteBatch(GraphicsDevice); + _spriteFont = Game.Content.Load(FontName); + + var titleSafeArea = Game.GraphicsDevice.DisplayMode.TitleSafeArea; + Position = new Vector2(titleSafeArea.X, titleSafeArea.Y); + } + + public override void Draw(GameTime gameTime) + { + _frameCount++; + + _frameRateBuilder.Length = 0; + _frameRateBuilder.AppendWithoutGarbage(_frameRate).Append(" fps"); + + _spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.None); + //_spriteBatch.DrawString(_spriteFont, fps, Position - Vector2.UnitX, Color.Black); // rough outline + //_spriteBatch.DrawString(_spriteFont, fps, Position + Vector2.UnitX, Color.Black); + //_spriteBatch.DrawString(_spriteFont, fps, Position - Vector2.UnitY, Color.Black); + //_spriteBatch.DrawString(_spriteFont, fps, Position + Vector2.UnitY, Color.Black); + _spriteBatch.DrawString(_spriteFont, _frameRateBuilder, Position, FontColor); + _spriteBatch.End(); + } + + public override void Update(GameTime gameTime) + { + _elapsedTime += gameTime.ElapsedGameTime.Ticks; + + if (_elapsedTime >= TimeSpan.TicksPerSecond) + { + _elapsedTime -= TimeSpan.TicksPerSecond; + _frameRate = _frameCount; + _frameCount = 0; + } + } + + public Color FontColor { get; set; } + public string FontName { get; set; } + public Vector2 Position { get; set; } + + private SpriteBatch _spriteBatch; + private SpriteFont _spriteFont; + private long _elapsedTime; + private int _frameCount; + private int _frameRate; + private StringBuilder _frameRateBuilder = new StringBuilder(); // cache builder; avoids garbage + } +} diff --git a/Library/Xna/GameBase.cs b/Library/Xna/GameBase.cs index c63981b..885a79b 100644 --- a/Library/Xna/GameBase.cs +++ b/Library/Xna/GameBase.cs @@ -1,45 +1,45 @@ -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.GamerServices; -using Microsoft.Xna.Framework.Graphics; -using Microsoft.Xna.Framework.Input; - -namespace Jellyfish.Library -{ - public class GameBase : Game - { - public GameBase() : - this(null) - { - } - - public GameBase(string name) - { - Name = name; - - GraphicsDeviceManager = new GraphicsDeviceManager(this); - GraphicsDeviceService = (IGraphicsDeviceService)Services.GetService(typeof(IGraphicsDeviceService)); - - Components.Add(new GamerServicesComponent(this)); - Content.RootDirectory = "Content"; - if (!string.IsNullOrEmpty(Name)) - { - Window.Title = Name; - } - } - - protected override void Update(GameTime gameTime) - { - GamePadState gamePadState = GamePad.GetState(PlayerIndex.One); - if (gamePadState.Buttons.Back == ButtonState.Pressed) - { - Exit(); - } - - base.Update(gameTime); - } - - public string Name { get; private set; } - public GraphicsDeviceManager GraphicsDeviceManager { get; private set; } - public IGraphicsDeviceService GraphicsDeviceService { get; private set; } - } -} +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.GamerServices; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; + +namespace Jellyfish.Library +{ + public class GameBase : Game + { + public GameBase() : + this(null) + { + } + + public GameBase(string name) + { + Name = name; + + GraphicsDeviceManager = new GraphicsDeviceManager(this); + GraphicsDeviceService = (IGraphicsDeviceService)Services.GetService(typeof(IGraphicsDeviceService)); + + Components.Add(new GamerServicesComponent(this)); + Content.RootDirectory = "Content"; + if (!string.IsNullOrEmpty(Name)) + { + Window.Title = Name; + } + } + + protected override void Update(GameTime gameTime) + { + var gamePadState = GamePad.GetState(PlayerIndex.One); + if (gamePadState.Buttons.Back == ButtonState.Pressed) + { + Exit(); + } + + base.Update(gameTime); + } + + public string Name { get; private set; } + public GraphicsDeviceManager GraphicsDeviceManager { get; private set; } + public IGraphicsDeviceService GraphicsDeviceService { get; private set; } + } +} diff --git a/Library/Xna/Properties/AssemblyInfo.cs b/Library/Xna/Properties/AssemblyInfo.cs index 7133da5..0a8ffc6 100644 --- a/Library/Xna/Properties/AssemblyInfo.cs +++ b/Library/Xna/Properties/AssemblyInfo.cs @@ -1,30 +1,30 @@ -using System; -using System.Reflection; -using System.Resources; -using System.Runtime.InteropServices; -using Jellyfish.Library; - -[assembly: AssemblyTitle("Library")] -[assembly: AssemblyDescription("Common Library")] -#if XBOX -[assembly: AssemblyProduct("Jellyfish.Library.Xna.Xbox")] -#elif ZUNE -[assembly: AssemblyProduct("Jellyfish.Library.Xna.Zune")] -#else -[assembly: AssemblyProduct("Jellyfish.Library.Xna")] -#endif -[assembly: AssemblyCompany("Digital Jellyfish Design Ltd")] -[assembly: AssemblyCopyright("Copyright © 2009-2010 Digital Jellyfish Design Ltd")] -[assembly: AssemblyComment("Developed by Sean Fausett")] - -[assembly: AssemblyVersion("0.1.0.0")] -#if WINDOWS -[assembly: AssemblyFileVersion("0.1.0.0")] -#endif -[assembly: AssemblyInformationalVersion("0.1.0.0")] - -[assembly: CLSCompliant(false)] -[assembly: ComVisible(false)] -[assembly: Guid("66034b9e-9f0b-47b0-aac4-cade9a748891")] - -[assembly: NeutralResourcesLanguage("en")] +using System; +using System.Reflection; +using System.Resources; +using System.Runtime.InteropServices; +using Jellyfish.Library; + +[assembly: AssemblyTitle("Library")] +[assembly: AssemblyDescription("Common Library")] +#if XBOX +[assembly: AssemblyProduct("Jellyfish.Library.Xna.Xbox")] +#elif ZUNE +[assembly: AssemblyProduct("Jellyfish.Library.Xna.Zune")] +#else +[assembly: AssemblyProduct("Jellyfish.Library.Xna")] +#endif +[assembly: AssemblyCompany("Digital Jellyfish Design Ltd")] +[assembly: AssemblyCopyright("Copyright © 2009-2010 Digital Jellyfish Design Ltd")] +[assembly: AssemblyComment("Developed by Sean Fausett")] + +[assembly: AssemblyVersion("0.1.0.0")] +#if WINDOWS +[assembly: AssemblyFileVersion("0.1.0.0")] +#endif +[assembly: AssemblyInformationalVersion("0.1.0.0")] + +[assembly: CLSCompliant(false)] +[assembly: ComVisible(false)] +[assembly: Guid("66034b9e-9f0b-47b0-aac4-cade9a748891")] + +[assembly: NeutralResourcesLanguage("en")] diff --git a/Virtu/Cassette.cs b/Virtu/Cassette.cs index 93abdb9..e4ad339 100644 --- a/Virtu/Cassette.cs +++ b/Virtu/Cassette.cs @@ -1,23 +1,23 @@ -using System.Diagnostics.CodeAnalysis; - -namespace Jellyfish.Virtu -{ - public sealed class Cassette : MachineComponent - { - public Cassette(Machine machine) : - base(machine) - { - } - - [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")] - public bool ReadInput() - { - return false; - } - - [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")] - public void ToggleOutput() - { - } - } -} +using System.Diagnostics.CodeAnalysis; + +namespace Jellyfish.Virtu +{ + public sealed class Cassette : MachineComponent + { + public Cassette(Machine machine) : + base(machine) + { + } + + [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")] + public bool ReadInput() + { + return false; + } + + [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")] + public void ToggleOutput() + { + } + } +} diff --git a/Virtu/Cpu.cs b/Virtu/Cpu.cs index 50e7b95..df67de6 100644 --- a/Virtu/Cpu.cs +++ b/Virtu/Cpu.cs @@ -1,3233 +1,3233 @@ -using System; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Threading; - -namespace Jellyfish.Virtu -{ - public sealed partial class Cpu : MachineComponent - { - public Cpu(Machine machine) : - base(machine) - { - ExecuteOpcode65N02 = new Action[OpcodeCount] - { - Execute65X02Brk00, Execute65X02Ora01, Execute65N02Nop02, Execute65N02Nop03, - Execute65N02Nop04, Execute65X02Ora05, Execute65X02Asl06, Execute65N02Nop07, - Execute65X02Php08, Execute65X02Ora09, Execute65X02Asl0A, Execute65N02Nop0B, - Execute65N02Nop0C, Execute65X02Ora0D, Execute65X02Asl0E, Execute65N02Nop0F, - Execute65X02Bpl10, Execute65X02Ora11, Execute65N02Nop12, Execute65N02Nop13, - Execute65N02Nop14, Execute65X02Ora15, Execute65X02Asl16, Execute65N02Nop17, - Execute65X02Clc18, Execute65X02Ora19, Execute65N02Nop1A, Execute65N02Nop1B, - Execute65N02Nop1C, Execute65X02Ora1D, Execute65N02Asl1E, Execute65N02Nop1F, - Execute65X02Jsr20, Execute65X02And21, Execute65N02Nop22, Execute65N02Nop23, - Execute65X02Bit24, Execute65X02And25, Execute65X02Rol26, Execute65N02Nop27, - Execute65X02Plp28, Execute65X02And29, Execute65X02Rol2A, Execute65N02Nop2B, - Execute65X02Bit2C, Execute65X02And2D, Execute65X02Rol2E, Execute65N02Nop2F, - Execute65X02Bmi30, Execute65X02And31, Execute65N02Nop32, Execute65N02Nop33, - Execute65N02Nop34, Execute65X02And35, Execute65X02Rol36, Execute65N02Nop37, - Execute65X02Sec38, Execute65X02And39, Execute65N02Nop3A, Execute65N02Nop3B, - Execute65N02Nop3C, Execute65X02And3D, Execute65N02Rol3E, Execute65N02Nop3F, - Execute65X02Rti40, Execute65X02Eor41, Execute65N02Nop42, Execute65N02Nop43, - Execute65N02Nop44, Execute65X02Eor45, Execute65X02Lsr46, Execute65N02Nop47, - Execute65X02Pha48, Execute65X02Eor49, Execute65X02Lsr4A, Execute65N02Nop4B, - Execute65X02Jmp4C, Execute65X02Eor4D, Execute65X02Lsr4E, Execute65N02Nop4F, - Execute65X02Bvc50, Execute65X02Eor51, Execute65N02Nop52, Execute65N02Nop53, - Execute65N02Nop54, Execute65X02Eor55, Execute65X02Lsr56, Execute65N02Nop57, - Execute65X02Cli58, Execute65X02Eor59, Execute65N02Nop5A, Execute65N02Nop5B, - Execute65N02Nop5C, Execute65X02Eor5D, Execute65N02Lsr5E, Execute65N02Nop5F, - Execute65X02Rts60, Execute65N02Adc61, Execute65N02Nop62, Execute65N02Nop63, - Execute65N02Nop64, Execute65N02Adc65, Execute65X02Ror66, Execute65N02Nop67, - Execute65X02Pla68, Execute65N02Adc69, Execute65X02Ror6A, Execute65N02Nop6B, - Execute65N02Jmp6C, Execute65N02Adc6D, Execute65X02Ror6E, Execute65N02Nop6F, - Execute65X02Bvs70, Execute65N02Adc71, Execute65N02Nop72, Execute65N02Nop73, - Execute65N02Nop74, Execute65N02Adc75, Execute65X02Ror76, Execute65N02Nop77, - Execute65X02Sei78, Execute65N02Adc79, Execute65N02Nop7A, Execute65N02Nop7B, - Execute65N02Nop7C, Execute65N02Adc7D, Execute65N02Ror7E, Execute65N02Nop7F, - Execute65N02Nop80, Execute65X02Sta81, Execute65N02Nop82, Execute65N02Nop83, - Execute65X02Sty84, Execute65X02Sta85, Execute65X02Stx86, Execute65N02Nop87, - Execute65X02Dey88, Execute65N02Nop89, Execute65X02Txa8A, Execute65N02Nop8B, - Execute65X02Sty8C, Execute65X02Sta8D, Execute65X02Stx8E, Execute65N02Nop8F, - Execute65X02Bcc90, Execute65X02Sta91, Execute65N02Nop92, Execute65N02Nop93, - Execute65X02Sty94, Execute65X02Sta95, Execute65X02Stx96, Execute65N02Nop97, - Execute65X02Tya98, Execute65X02Sta99, Execute65X02Txs9A, Execute65N02Nop9B, - Execute65N02Nop9C, Execute65X02Sta9D, Execute65N02Nop9E, Execute65N02Nop9F, - Execute65X02LdyA0, Execute65X02LdaA1, Execute65X02LdxA2, Execute65N02NopA3, - Execute65X02LdyA4, Execute65X02LdaA5, Execute65X02LdxA6, Execute65N02NopA7, - Execute65X02TayA8, Execute65X02LdaA9, Execute65X02TaxAA, Execute65N02NopAB, - Execute65X02LdyAC, Execute65X02LdaAD, Execute65X02LdxAE, Execute65N02NopAF, - Execute65X02BcsB0, Execute65X02LdaB1, Execute65N02NopB2, Execute65N02NopB3, - Execute65X02LdyB4, Execute65X02LdaB5, Execute65X02LdxB6, Execute65N02NopB7, - Execute65X02ClvB8, Execute65X02LdaB9, Execute65X02TsxBA, Execute65N02NopBB, - Execute65X02LdyBC, Execute65X02LdaBD, Execute65X02LdxBE, Execute65N02NopBF, - Execute65X02CpyC0, Execute65X02CmpC1, Execute65N02NopC2, Execute65N02NopC3, - Execute65X02CpyC4, Execute65X02CmpC5, Execute65X02DecC6, Execute65N02NopC7, - Execute65X02InyC8, Execute65X02CmpC9, Execute65X02DexCA, Execute65N02NopCB, - Execute65X02CpyCC, Execute65X02CmpCD, Execute65X02DecCE, Execute65N02NopCF, - Execute65X02BneD0, Execute65X02CmpD1, Execute65N02NopD2, Execute65N02NopD3, - Execute65N02NopD4, Execute65X02CmpD5, Execute65X02DecD6, Execute65N02NopD7, - Execute65X02CldD8, Execute65X02CmpD9, Execute65N02NopDA, Execute65N02NopDB, - Execute65N02NopDC, Execute65X02CmpDD, Execute65N02DecDE, Execute65N02NopDF, - Execute65X02CpxE0, Execute65N02SbcE1, Execute65N02NopE2, Execute65N02NopE3, - Execute65X02CpxE4, Execute65N02SbcE5, Execute65X02IncE6, Execute65N02NopE7, - Execute65X02InxE8, Execute65N02SbcE9, Execute65X02NopEA, Execute65N02NopEB, - Execute65X02CpxEC, Execute65N02SbcED, Execute65X02IncEE, Execute65N02NopEF, - Execute65X02BeqF0, Execute65N02SbcF1, Execute65N02NopF2, Execute65N02NopF3, - Execute65N02NopF4, Execute65N02SbcF5, Execute65X02IncF6, Execute65N02NopF7, - Execute65X02SedF8, Execute65N02SbcF9, Execute65N02NopFA, Execute65N02NopFB, - Execute65N02NopFC, Execute65N02SbcFD, Execute65N02IncFE, Execute65N02NopFF - }; - - ExecuteOpcode65C02 = new Action[OpcodeCount] - { - Execute65X02Brk00, Execute65X02Ora01, Execute65C02Nop02, Execute65C02Nop03, - Execute65C02Tsb04, Execute65X02Ora05, Execute65X02Asl06, Execute65C02Nop07, - Execute65X02Php08, Execute65X02Ora09, Execute65X02Asl0A, Execute65C02Nop0B, - Execute65C02Tsb0C, Execute65X02Ora0D, Execute65X02Asl0E, Execute65C02Nop0F, - Execute65X02Bpl10, Execute65X02Ora11, Execute65C02Ora12, Execute65C02Nop13, - Execute65C02Trb14, Execute65X02Ora15, Execute65X02Asl16, Execute65C02Nop17, - Execute65X02Clc18, Execute65X02Ora19, Execute65C02Ina1A, Execute65C02Nop1B, - Execute65C02Trb1C, Execute65X02Ora1D, Execute65C02Asl1E, Execute65C02Nop1F, - Execute65X02Jsr20, Execute65X02And21, Execute65C02Nop22, Execute65C02Nop23, - Execute65X02Bit24, Execute65X02And25, Execute65X02Rol26, Execute65C02Nop27, - Execute65X02Plp28, Execute65X02And29, Execute65X02Rol2A, Execute65C02Nop2B, - Execute65X02Bit2C, Execute65X02And2D, Execute65X02Rol2E, Execute65C02Nop2F, - Execute65X02Bmi30, Execute65X02And31, Execute65C02And32, Execute65C02Nop33, - Execute65C02Bit34, Execute65X02And35, Execute65X02Rol36, Execute65C02Nop37, - Execute65X02Sec38, Execute65X02And39, Execute65C02Dea3A, Execute65C02Nop3B, - Execute65C02Bit3C, Execute65X02And3D, Execute65C02Rol3E, Execute65C02Nop3F, - Execute65X02Rti40, Execute65X02Eor41, Execute65C02Nop42, Execute65C02Nop43, - Execute65C02Nop44, Execute65X02Eor45, Execute65X02Lsr46, Execute65C02Nop47, - Execute65X02Pha48, Execute65X02Eor49, Execute65X02Lsr4A, Execute65C02Nop4B, - Execute65X02Jmp4C, Execute65X02Eor4D, Execute65X02Lsr4E, Execute65C02Nop4F, - Execute65X02Bvc50, Execute65X02Eor51, Execute65C02Eor52, Execute65C02Nop53, - Execute65C02Nop54, Execute65X02Eor55, Execute65X02Lsr56, Execute65C02Nop57, - Execute65X02Cli58, Execute65X02Eor59, Execute65C02Phy5A, Execute65C02Nop5B, - Execute65C02Nop5C, Execute65X02Eor5D, Execute65C02Lsr5E, Execute65C02Nop5F, - Execute65X02Rts60, Execute65C02Adc61, Execute65C02Nop62, Execute65C02Nop63, - Execute65C02Stz64, Execute65C02Adc65, Execute65X02Ror66, Execute65C02Nop67, - Execute65X02Pla68, Execute65C02Adc69, Execute65X02Ror6A, Execute65C02Nop6B, - Execute65C02Jmp6C, Execute65C02Adc6D, Execute65X02Ror6E, Execute65C02Nop6F, - Execute65X02Bvs70, Execute65C02Adc71, Execute65C02Adc72, Execute65C02Nop73, - Execute65C02Stz74, Execute65C02Adc75, Execute65X02Ror76, Execute65C02Nop77, - Execute65X02Sei78, Execute65C02Adc79, Execute65C02Ply7A, Execute65C02Nop7B, - Execute65C02Jmp7C, Execute65C02Adc7D, Execute65C02Ror7E, Execute65C02Nop7F, - Execute65C02Bra80, Execute65X02Sta81, Execute65C02Nop82, Execute65C02Nop83, - Execute65X02Sty84, Execute65X02Sta85, Execute65X02Stx86, Execute65C02Nop87, - Execute65X02Dey88, Execute65C02Bit89, Execute65X02Txa8A, Execute65C02Nop8B, - Execute65X02Sty8C, Execute65X02Sta8D, Execute65X02Stx8E, Execute65C02Nop8F, - Execute65X02Bcc90, Execute65X02Sta91, Execute65C02Sta92, Execute65C02Nop93, - Execute65X02Sty94, Execute65X02Sta95, Execute65X02Stx96, Execute65C02Nop97, - Execute65X02Tya98, Execute65X02Sta99, Execute65X02Txs9A, Execute65C02Nop9B, - Execute65C02Stz9C, Execute65X02Sta9D, Execute65C02Stz9E, Execute65C02Nop9F, - Execute65X02LdyA0, Execute65X02LdaA1, Execute65X02LdxA2, Execute65C02NopA3, - Execute65X02LdyA4, Execute65X02LdaA5, Execute65X02LdxA6, Execute65C02NopA7, - Execute65X02TayA8, Execute65X02LdaA9, Execute65X02TaxAA, Execute65C02NopAB, - Execute65X02LdyAC, Execute65X02LdaAD, Execute65X02LdxAE, Execute65C02NopAF, - Execute65X02BcsB0, Execute65X02LdaB1, Execute65C02LdaB2, Execute65C02NopB3, - Execute65X02LdyB4, Execute65X02LdaB5, Execute65X02LdxB6, Execute65C02NopB7, - Execute65X02ClvB8, Execute65X02LdaB9, Execute65X02TsxBA, Execute65C02NopBB, - Execute65X02LdyBC, Execute65X02LdaBD, Execute65X02LdxBE, Execute65C02NopBF, - Execute65X02CpyC0, Execute65X02CmpC1, Execute65C02NopC2, Execute65C02NopC3, - Execute65X02CpyC4, Execute65X02CmpC5, Execute65X02DecC6, Execute65C02NopC7, - Execute65X02InyC8, Execute65X02CmpC9, Execute65X02DexCA, Execute65C02NopCB, - Execute65X02CpyCC, Execute65X02CmpCD, Execute65X02DecCE, Execute65C02NopCF, - Execute65X02BneD0, Execute65X02CmpD1, Execute65C02CmpD2, Execute65C02NopD3, - Execute65C02NopD4, Execute65X02CmpD5, Execute65X02DecD6, Execute65C02NopD7, - Execute65X02CldD8, Execute65X02CmpD9, Execute65C02PhxDA, Execute65C02NopDB, - Execute65C02NopDC, Execute65X02CmpDD, Execute65C02DecDE, Execute65C02NopDF, - Execute65X02CpxE0, Execute65C02SbcE1, Execute65C02NopE2, Execute65C02NopE3, - Execute65X02CpxE4, Execute65C02SbcE5, Execute65X02IncE6, Execute65C02NopE7, - Execute65X02InxE8, Execute65C02SbcE9, Execute65X02NopEA, Execute65C02NopEB, - Execute65X02CpxEC, Execute65C02SbcED, Execute65X02IncEE, Execute65C02NopEF, - Execute65X02BeqF0, Execute65C02SbcF1, Execute65C02SbcF2, Execute65C02NopF3, - Execute65C02NopF4, Execute65C02SbcF5, Execute65X02IncF6, Execute65C02NopF7, - Execute65X02SedF8, Execute65C02SbcF9, Execute65C02PlxFA, Execute65C02NopFB, - Execute65C02NopFC, Execute65C02SbcFD, Execute65C02IncFE, Execute65C02NopFF - }; - - RS = 0xFF; - } - - public override void Initialize() - { - _memory = Machine.Memory; - - UpdateSettings(); - - Machine.Video.VSync += OnVideoVSync; - } - - public override void Reset() - { - RS = (RS - 3) & 0xFF; // [4-14] - RPC = _memory.ReadRomRegionE0FF(0xFFFC) | (_memory.ReadRomRegionE0FF(0xFFFD) << 8); - RP |= (PB | PI); - if (Machine.Settings.Cpu.Is65C02) // [C-10] - { - RP &= ~PD; - } - } - - public override string ToString() - { - return string.Format(CultureInfo.CurrentCulture, "A = 0x{0:X2} X = 0x{1:X2} Y = 0x{2:X2} P = 0x{3:X2} S = 0x01{4:X2} PC = 0x{5:X4} EA = 0x{6:X4} CC = {7}", - RA, RX, RY, RP, RS, RPC, EA, CC); - } - - public int Execute() - { - CC = 0; - Opcode = _memory.Read(RPC); - RPC = (RPC + 1) & 0xFFFF; - _executeOpcode[Opcode](); - Cycles += CC; - - return CC; - } - - public void ToggleThrottle() - { - Machine.Settings.Cpu.IsThrottled ^= true; - } - - #region Core Operand Actions - private void GetAddressAbs() // abs - { - EA = _memory.Read(RPC) | (_memory.Read(RPC + 1) << 8); - RPC = (RPC + 2) & 0xFFFF; - } - - private void GetAddressAbsX() // abs, x - { - EA = (_memory.Read(RPC) + RX + (_memory.Read(RPC + 1) << 8)) & 0xFFFF; - RPC = (RPC + 2) & 0xFFFF; - } - - private void GetAddressAbsXCC() // abs, x - { - int ea = _memory.Read(RPC) + RX; - EA = (ea + (_memory.Read(RPC + 1) << 8)) & 0xFFFF; - RPC = (RPC + 2) & 0xFFFF; - CC += (ea >> 8); - } - - private void GetAddressAbsY() // abs, y - { - EA = (_memory.Read(RPC) + RY + (_memory.Read(RPC + 1) << 8)) & 0xFFFF; - RPC = (RPC + 2) & 0xFFFF; - } - - private void GetAddressAbsYCC() // abs, y - { - int ea = _memory.Read(RPC) + RY; - EA = (ea + (_memory.Read(RPC + 1) << 8)) & 0xFFFF; - RPC = (RPC + 2) & 0xFFFF; - CC += (ea >> 8); - } - - private void GetAddressZpg() // zpg - { - EA = _memory.Read(RPC); - RPC = (RPC + 1) & 0xFFFF; - } - - private void GetAddressZpgInd() // (zpg) - { - int zp = _memory.Read(RPC); - EA = _memory.ReadZeroPage(zp) | (_memory.ReadZeroPage((zp + 1) & 0xFF) << 8); - RPC = (RPC + 1) & 0xFFFF; - } - - private void GetAddressZpgIndX() // (zpg, x) - { - int zp = (_memory.Read(RPC) + RX) & 0xFF; - EA = _memory.ReadZeroPage(zp) | (_memory.ReadZeroPage((zp + 1) & 0xFF) << 8); - RPC = (RPC + 1) & 0xFFFF; - } - - private void GetAddressZpgIndY() // (zpg), y - { - int zp = _memory.Read(RPC); - EA = (_memory.ReadZeroPage(zp) + RY + (_memory.ReadZeroPage((zp + 1) & 0xFF) << 8)) & 0xFFFF; - RPC = (RPC + 1) & 0xFFFF; - } - - private void GetAddressZpgIndYCC() // (zpg), y - { - int zp = _memory.Read(RPC); - int ea = _memory.ReadZeroPage(zp) + RY; - EA = (ea + (_memory.ReadZeroPage((zp + 1) & 0xFF) << 8)) & 0xFFFF; - RPC = (RPC + 1) & 0xFFFF; - CC += (ea >> 8); - } - - private void GetAddressZpgX() // zpg, x - { - EA = (_memory.Read(RPC) + RX) & 0xFF; - RPC = (RPC + 1) & 0xFFFF; - } - - private void GetAddressZpgY() // zpg, y - { - EA = (_memory.Read(RPC) + RY) & 0xFF; - RPC = (RPC + 1) & 0xFFFF; - } - - private int Pull() - { - RS = (RS + 1) & 0xFF; - - return _memory.ReadZeroPage(0x0100 + RS); - } - - private void Push(int data) - { - _memory.WriteZeroPage(0x0100 + RS, data); - RS = (RS - 1) & 0xFF; - } - - private int ReadAbs() // abs - { - return _memory.Read(EA); - } - - private int ReadAbsX() // abs, x - { - return _memory.Read(EA); - } - - private int ReadAbsY() // abs, y - { - return _memory.Read(EA); - } - - private int ReadImm() // imm - { - int data = _memory.Read(RPC); - RPC = (RPC + 1) & 0xFFFF; - - return data; - } - - private int ReadZpg() // zpg - { - return _memory.ReadZeroPage(EA); - } - - private int ReadZpgInd() // (zpg) - { - return _memory.Read(EA); - } - - private int ReadZpgIndX() // (zpg, x) - { - return _memory.Read(EA); - } - - private int ReadZpgIndY() // (zpg), y - { - return _memory.Read(EA); - } - - private int ReadZpgX() // zpg, x - { - return _memory.ReadZeroPage(EA); - } - - private int ReadZpgY() // zpg, y - { - return _memory.ReadZeroPage(EA); - } - - private void WriteAbs(int data) // abs - { - _memory.Write(EA, data); - } - - private void WriteAbsX(int data) // abs, x - { - _memory.Write(EA, data); - } - - private void WriteAbsY(int data) // abs, y - { - _memory.Write(EA, data); - } - - private void WriteZpg(int data) // zpg - { - _memory.WriteZeroPage(EA, data); - } - - private void WriteZpgInd(int data) // (zpg) - { - _memory.Write(EA, data); - } - - private void WriteZpgIndX(int data) // (zpg, x) - { - _memory.Write(EA, data); - } - - private void WriteZpgIndY(int data) // (zpg), y - { - _memory.Write(EA, data); - } - - private void WriteZpgX(int data) // zpg, x - { - _memory.WriteZeroPage(EA, data); - } - - private void WriteZpgY(int data) // zpg, y - { - _memory.WriteZeroPage(EA, data); - } - #endregion - - #region Core Opcode Actions - private void ExecuteAdc65N02(int data, int cc) - { - if ((RP & PD) == 0x0) - { - int ra = RA + data + (RP & PC); - RP = RP & ~(PC | PN | PV | PZ) | ((ra >> 8) & PC) | DataPNZ[ra & 0xFF] | (((~(RA ^ data) & (RA ^ (ra & 0xFF))) >> 1) & PV); - RA = ra & 0xFF; - CC += cc; - } - else // decimal - { - int ral = (RA & 0x0F) + (data & 0x0F) + (RP & PC); - int rah = (RA >> 4) + (data >> 4); - if (ral >= 10) - { - ral -= 10; - rah++; - } - int ra = (ral | (rah << 4)) & 0xFF; - RP = RP & ~(PC | PN | PV | PZ) | DataPN[ra] | (((~(RA ^ data) & (RA ^ ra)) >> 1) & PV) | DataPZ[(RA + data + (RP & PC)) & 0xFF]; - if (rah >= 10) - { - rah -= 10; - RP |= PC; - } - RA = (ral | (rah << 4)) & 0xFF; - CC += cc; - } - } - - private void ExecuteAdc65C02(int data, int cc) - { - if ((RP & PD) == 0x0) - { - int ra = RA + data + (RP & PC); - RP = RP & ~(PC | PN | PV | PZ) | ((ra >> 8) & PC) | DataPNZ[ra & 0xFF] | (((~(RA ^ data) & (RA ^ (ra & 0xFF))) >> 1) & PV); - RA = ra & 0xFF; - CC += cc; - } - else // decimal - { - int ral = (RA & 0x0F) + (data & 0x0F) + (RP & PC); - int rah = (RA >> 4) + (data >> 4); - if (ral >= 10) - { - ral -= 10; - rah++; - } - RP &= ~PC; - if (rah >= 10) - { - rah -= 10; - RP |= PC; - } - int ra = (ral | (rah << 4)) & 0xFF; - RP = RP & ~(PN | PV | PZ) | DataPNZ[ra] | (((~(RA ^ data) & (RA ^ ra)) >> 1) & PV); - RA = ra; - CC += cc + 1; - } - } - - private void ExecuteAnd(int data, int cc) - { - RA &= data; - RP = RP & ~(PN | PZ) | DataPNZ[RA]; - CC += cc; - } - - private int ExecuteAsl(int data, int cc) - { - RP = RP & ~PC | ((data >> 7) & PC); - data = (data << 1) & 0xFF; - RP = RP & ~(PN | PZ) | DataPNZ[data]; - CC += cc; - - return data; - } - - private void ExecuteAslImp(int cc) - { - RP = RP & ~PC | ((RA >> 7) & PC); - RA = (RA << 1) & 0xFF; - RP = RP & ~(PN | PZ) | DataPNZ[RA]; - CC += cc; - } - - private void ExecuteBcc(int cc) - { - if ((RP & PC) == 0x0) - { - int rpc = (RPC + 1) & 0xFFFF; - RPC = (RPC + 1 + (sbyte)_memory.Read(RPC)) & 0xFFFF; - CC += cc + 1 + (((RPC ^ rpc) >> 8) & 0x01); - } - else - { - RPC = (RPC + 1) & 0xFFFF; - CC += cc; - } - } - - private void ExecuteBcs(int cc) - { - if ((RP & PC) != 0x0) - { - int rpc = (RPC + 1) & 0xFFFF; - RPC = (RPC + 1 + (sbyte)_memory.Read(RPC)) & 0xFFFF; - CC += cc + 1 + (((RPC ^ rpc) >> 8) & 0x01); - } - else - { - RPC = (RPC + 1) & 0xFFFF; - CC += cc; - } - } - - private void ExecuteBeq(int cc) - { - if ((RP & PZ) != 0x0) - { - int rpc = (RPC + 1) & 0xFFFF; - RPC = (RPC + 1 + (sbyte)_memory.Read(RPC)) & 0xFFFF; - CC += cc + 1 + (((RPC ^ rpc) >> 8) & 0x01); - } - else - { - RPC = (RPC + 1) & 0xFFFF; - CC += cc; - } - } - - private void ExecuteBit(int data, int cc) - { - RP = RP & ~(PN | PV | PZ) | (data & (PN | PV)) | DataPZ[RA & data]; - CC += cc; - } - - private void ExecuteBitImm(int data, int cc) - { - RP = RP & ~PZ | DataPZ[RA & data]; - CC += cc; - } - - private void ExecuteBmi(int cc) - { - if ((RP & PN) != 0x0) - { - int rpc = (RPC + 1) & 0xFFFF; - RPC = (RPC + 1 + (sbyte)_memory.Read(RPC)) & 0xFFFF; - CC += cc + 1 + (((RPC ^ rpc) >> 8) & 0x01); - } - else - { - RPC = (RPC + 1) & 0xFFFF; - CC += cc; - } - } - - private void ExecuteBne(int cc) - { - if ((RP & PZ) == 0x0) - { - int rpc = (RPC + 1) & 0xFFFF; - RPC = (RPC + 1 + (sbyte)_memory.Read(RPC)) & 0xFFFF; - CC += cc + 1 + (((RPC ^ rpc) >> 8) & 0x01); - } - else - { - RPC = (RPC + 1) & 0xFFFF; - CC += cc; - } - } - - private void ExecuteBpl(int cc) - { - if ((RP & PN) == 0x0) - { - int rpc = (RPC + 1) & 0xFFFF; - RPC = (RPC + 1 + (sbyte)_memory.Read(RPC)) & 0xFFFF; - CC += cc + 1 + (((RPC ^ rpc) >> 8) & 0x01); - } - else - { - RPC = (RPC + 1) & 0xFFFF; - CC += cc; - } - } - - private void ExecuteBra(int cc) - { - int rpc = (RPC + 1) & 0xFFFF; - RPC = (RPC + 1 + (sbyte)_memory.Read(RPC)) & 0xFFFF; - CC += cc + 1 + (((RPC ^ rpc) >> 8) & 0x01); - } - - private void ExecuteBrk(int cc) - { - int rpc = (RPC + 1) & 0xFFFF; // [4-18] - Push(rpc >> 8); - Push(rpc & 0xFF); - Push(RP | PB); - RP |= PI; - RPC = _memory.Read(0xFFFE) | (_memory.Read(0xFFFF) << 8); - CC += cc; - } - - private void ExecuteBvc(int cc) - { - if ((RP & PV) == 0x0) - { - int rpc = (RPC + 1) & 0xFFFF; - RPC = (RPC + 1 + (sbyte)_memory.Read(RPC)) & 0xFFFF; - CC += cc + 1 + (((RPC ^ rpc) >> 8) & 0x01); - } - else - { - RPC = (RPC + 1) & 0xFFFF; - CC += cc; - } - } - - private void ExecuteBvs(int cc) - { - if ((RP & PV) != 0x0) - { - int rpc = (RPC + 1) & 0xFFFF; - RPC = (RPC + 1 + (sbyte)_memory.Read(RPC)) & 0xFFFF; - CC += cc + 1 + (((RPC ^ rpc) >> 8) & 0x01); - } - else - { - RPC = (RPC + 1) & 0xFFFF; - CC += cc; - } - } - - private void ExecuteClc(int cc) - { - RP &= ~PC; - CC += cc; - } - - private void ExecuteCld(int cc) - { - RP &= ~PD; - CC += cc; - } - - private void ExecuteCli(int cc) - { - RP &= ~PI; - CC += cc; - } - - private void ExecuteClv(int cc) - { - RP &= ~PV; - CC += cc; - } - - private void ExecuteCmp(int data, int cc) - { - int diff = RA - data; - RP = RP & ~(PC | PN | PZ) | ((~diff >> 8) & PC) | DataPNZ[diff & 0xFF]; - CC += cc; - } - - private void ExecuteCpx(int data, int cc) - { - int diff = RX - data; - RP = RP & ~(PC | PN | PZ) | ((~diff >> 8) & PC) | DataPNZ[diff & 0xFF]; - CC += cc; - } - - private void ExecuteCpy(int data, int cc) - { - int diff = RY - data; - RP = RP & ~(PC | PN | PZ) | ((~diff >> 8) & PC) | DataPNZ[diff & 0xFF]; - CC += cc; - } - - private void ExecuteDea(int cc) - { - RA = (RA - 1) & 0xFF; - RP = RP & ~(PN | PZ) | DataPNZ[RA]; - CC += cc; - } - - private int ExecuteDec(int data, int cc) - { - data = (data - 1) & 0xFF; - RP = RP & ~(PN | PZ) | DataPNZ[data]; - CC += cc; - - return data; - } - - private void ExecuteDex(int cc) - { - RX = (RX - 1) & 0xFF; - RP = RP & ~(PN | PZ) | DataPNZ[RX]; - CC += cc; - } - - private void ExecuteDey(int cc) - { - RY = (RY - 1) & 0xFF; - RP = RP & ~(PN | PZ) | DataPNZ[RY]; - CC += cc; - } - - private void ExecuteEor(int data, int cc) - { - RA ^= data; - RP = RP & ~(PN | PZ) | DataPNZ[RA]; - CC += cc; - } - - private void ExecuteIna(int cc) - { - RA = (RA + 1) & 0xFF; - RP = RP & ~(PN | PZ) | DataPNZ[RA]; - CC += cc; - } - - private int ExecuteInc(int data, int cc) - { - data = (data + 1) & 0xFF; - RP = RP & ~(PN | PZ) | DataPNZ[data]; - CC += cc; - - return data; - } - - private void ExecuteInx(int cc) - { - RX = (RX + 1) & 0xFF; - RP = RP & ~(PN | PZ) | DataPNZ[RX]; - CC += cc; - } - - private void ExecuteIny(int cc) - { - RY = (RY + 1) & 0xFF; - RP = RP & ~(PN | PZ) | DataPNZ[RY]; - CC += cc; - } - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - private void ExecuteIrq(int cc) - { - Push(RPC >> 8); - Push(RPC & 0xFF); - Push(RP & ~PB); - RP |= PI; - if (Machine.Settings.Cpu.Is65C02) // [C-10] - { - RP &= ~PD; - } - RPC = _memory.Read(0xFFFE) | (_memory.Read(0xFFFF) << 8); - CC += cc; - } - - private void ExecuteJmpAbs(int cc) // jmp abs - { - RPC = _memory.Read(RPC) | (_memory.Read(RPC + 1) << 8); - CC += cc; - } - - private void ExecuteJmpAbsInd65N02(int cc) // jmp (abs) - { - int ea = _memory.Read(RPC) | (_memory.Read(RPC + 1) << 8); - RPC = _memory.Read(ea) | (_memory.Read((ea & 0xFF00) | ((ea + 1) & 0x00FF)) << 8); - CC += cc; - } - - private void ExecuteJmpAbsInd65C02(int cc) // jmp (abs) - { - int ea = _memory.Read(RPC) | (_memory.Read(RPC + 1) << 8); - RPC = _memory.Read(ea) | (_memory.Read(ea + 1) << 8); - CC += cc; - } - - private void ExecuteJmpAbsIndX(int cc) // jmp (abs, x) - { - int ea = (_memory.Read(RPC) + RX + (_memory.Read(RPC + 1) << 8)) & 0xFFFF; - RPC = _memory.Read(ea) | (_memory.Read(ea + 1) << 8); - CC += cc; - } - - private void ExecuteJsr(int cc) // jsr abs - { - int rpc = (RPC + 1) & 0xFFFF; - RPC = _memory.Read(RPC) | (_memory.Read(RPC + 1) << 8); - Push(rpc >> 8); - Push(rpc & 0xFF); - CC += cc; - } - - private void ExecuteLda(int data, int cc) - { - RA = data; - RP = RP & ~(PN | PZ) | DataPNZ[RA]; - CC += cc; - } - - private void ExecuteLdx(int data, int cc) - { - RX = data; - RP = RP & ~(PN | PZ) | DataPNZ[RX]; - CC += cc; - } - - private void ExecuteLdy(int data, int cc) - { - RY = data; - RP = RP & ~(PN | PZ) | DataPNZ[RY]; - CC += cc; - } - - private int ExecuteLsr(int data, int cc) - { - RP = RP & ~PC | (data & PC); - data >>= 1; - RP = RP & ~(PN | PZ) | DataPNZ[data]; - CC += cc; - - return data; - } - - private void ExecuteLsrImp(int cc) - { - RP = RP & ~PC | (RA & PC); - RA >>= 1; - RP = RP & ~(PN | PZ) | DataPNZ[RA]; - CC += cc; - } - - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - private void ExecuteNmi(int cc) - { - Push(RPC >> 8); - Push(RPC & 0xFF); - Push(RP & ~PB); - RP |= PI; - if (Machine.Settings.Cpu.Is65C02) // [C-10] - { - RP &= ~PD; - } - RPC = _memory.Read(0xFFFA) | (_memory.Read(0xFFFB) << 8); - CC += cc; - } - - private void ExecuteNop(int cc) - { - CC += cc; - } - - private void ExecuteNop(int data, int cc) - { - RPC = (RPC + data) & 0xFFFF; - CC += cc; - } - - private void ExecuteOra(int data, int cc) - { - RA |= data; - RP = RP & ~(PN | PZ) | DataPNZ[RA]; - CC += cc; - } - - private void ExecutePha(int cc) - { - Push(RA); - CC += cc; - } - - private void ExecutePhp(int cc) - { - Push(RP | PB); // [4-18] - CC += cc; - } - - private void ExecutePhx(int cc) - { - Push(RX); - CC += cc; - } - - private void ExecutePhy(int cc) - { - Push(RY); - CC += cc; - } - - private void ExecutePla(int cc) - { - RA = Pull(); - RP = RP & ~(PN | PZ) | DataPNZ[RA]; - CC += cc; - } - - private void ExecutePlp(int cc) - { - RP = Pull(); - CC += cc; - } - - private void ExecutePlx(int cc) - { - RX = Pull(); - RP = RP & ~(PN | PZ) | DataPNZ[RX]; - CC += cc; - } - - private void ExecutePly(int cc) - { - RY = Pull(); - RP = RP & ~(PN | PZ) | DataPNZ[RY]; - CC += cc; - } - - private int ExecuteRol(int data, int cc) - { - int c = RP & PC; - RP = RP & ~PC | ((data >> 7) & PC); - data = ((data << 1) | c) & 0xFF; - RP = RP & ~(PN | PZ) | DataPNZ[data]; - CC += cc; - - return data; - } - - private void ExecuteRolImp(int cc) - { - int c = RP & PC; - RP = RP & ~PC | ((RA >> 7) & PC); - RA = ((RA << 1) | c) & 0xFF; - RP = RP & ~(PN | PZ) | DataPNZ[RA]; - CC += cc; - } - - private int ExecuteRor(int data, int cc) - { - int c = RP & PC; - RP = RP & ~PC | (data & PC); - data = (c << 7) | (data >> 1); - RP = RP & ~(PN | PZ) | DataPNZ[data]; - CC += cc; - - return data; - } - - private void ExecuteRorImp(int cc) - { - int c = RP & PC; - RP = RP & ~PC | (RA & PC); - RA = (c << 7) | (RA >> 1); - RP = RP & ~(PN | PZ) | DataPNZ[RA]; - CC += cc; - } - - private void ExecuteRti(int cc) - { - RP = Pull(); - int rpc = Pull(); - RPC = rpc | (Pull() << 8); - CC += cc; - } - - private void ExecuteRts(int cc) - { - int rpc = Pull(); - RPC = (rpc + 1 + (Pull() << 8)) & 0xFFFF; - CC += cc; - } - - private void ExecuteSbc65N02(int data, int cc) - { - if ((RP & PD) == 0x0) - { - int ra = RA - data - (~RP & PC); - RP = RP & ~(PC | PN | PV | PZ) | ((~ra >> 8) & PC) | DataPNZ[ra & 0xFF] | ((((RA ^ data) & (RA ^ (ra & 0xFF))) >> 1) & PV); - RA = ra & 0xFF; - CC += cc; - } - else // decimal - { - int ral = (RA & 0x0F) - (data & 0x0F) - (~RP & PC); - int rah = (RA >> 4) - (data >> 4); - if (ral < 0) - { - ral += 10; - rah--; - } - int ra = (ral | (rah << 4)) & 0xFF; - RP = RP & ~(PN | PV | PZ) | PC | DataPN[ra] | ((((RA ^ data) & (RA ^ ra)) >> 1) & PV) | DataPZ[(RA - data - (~RP & PC)) & 0xFF]; - if (rah < 0) - { - rah += 10; - RP &= ~PC; - } - RA = (ral | (rah << 4)) & 0xFF; - CC += cc; - } - } - - private void ExecuteSbc65C02(int data, int cc) - { - if ((RP & PD) == 0x0) - { - int ra = RA - data - (~RP & PC); - RP = RP & ~(PC | PN | PV | PZ) | ((~ra >> 8) & PC) | DataPNZ[ra & 0xFF] | ((((RA ^ data) & (RA ^ (ra & 0xFF))) >> 1) & PV); - RA = ra & 0xFF; - CC += cc; - } - else // decimal - { - int ral = (RA & 0x0F) - (data & 0x0F) - (~RP & PC); - int rah = (RA >> 4) - (data >> 4); - if (ral < 0) - { - ral += 10; - rah--; - } - RP |= PC; - if (rah < 0) - { - rah += 10; - RP &= ~PC; - } - int ra = (ral | (rah << 4)) & 0xFF; - RP = RP & ~(PN | PV | PZ) | DataPNZ[ra] | ((((RA ^ data) & (RA ^ ra)) >> 1) & PV); - RA = ra; - CC += cc + 1; - } - } - - private void ExecuteSec(int cc) - { - RP |= PC; - CC += cc; - } - - private void ExecuteSed(int cc) - { - RP |= PD; - CC += cc; - } - - private void ExecuteSei(int cc) - { - RP |= PI; - CC += cc; - } - - private void ExecuteSta(int cc) - { - CC += cc; - } - - private void ExecuteStx(int cc) - { - CC += cc; - } - - private void ExecuteSty(int cc) - { - CC += cc; - } - - private void ExecuteStz(int cc) - { - CC += cc; - } - - private void ExecuteTax(int cc) - { - RX = RA; - RP = RP & ~(PN | PZ) | DataPNZ[RX]; - CC += cc; - } - - private void ExecuteTay(int cc) - { - RY = RA; - RP = RP & ~(PN | PZ) | DataPNZ[RY]; - CC += cc; - } - - private int ExecuteTrb(int data, int cc) - { - RP = RP & ~PZ | DataPZ[RA & data]; - data &= ~RA; - CC += cc; - - return data; - } - - private int ExecuteTsb(int data, int cc) - { - RP = RP & ~PZ | DataPZ[RA & data]; - data |= RA; - CC += cc; - - return data; - } - - private void ExecuteTsx(int cc) - { - RX = RS; - RP = RP & ~(PN | PZ) | DataPNZ[RX]; - CC += cc; - } - - private void ExecuteTxa(int cc) - { - RA = RX; - RP = RP & ~(PN | PZ) | DataPNZ[RA]; - CC += cc; - } - - private void ExecuteTxs(int cc) - { - RS = RX; - CC += cc; - } - - private void ExecuteTya(int cc) - { - RA = RY; - RP = RP & ~(PN | PZ) | DataPNZ[RA]; - CC += cc; - } - #endregion - - #region 6502 Opcode Actions - private void Execute65X02And21() // and (zpg, x) - { - GetAddressZpgIndX(); - ExecuteAnd(ReadZpgIndX(), 6); - } - - private void Execute65X02And25() // and zpg - { - GetAddressZpg(); - ExecuteAnd(ReadZpg(), 3); - } - - private void Execute65X02And29() // and imm - { - ExecuteAnd(ReadImm(), 2); - } - - private void Execute65X02And2D() // and abs - { - GetAddressAbs(); - ExecuteAnd(ReadAbs(), 4); - } - - private void Execute65X02And31() // and (zpg), y - { - GetAddressZpgIndYCC(); - ExecuteAnd(ReadZpgIndY(), 5); - } - - private void Execute65X02And35() // and zpg, x - { - GetAddressZpgX(); - ExecuteAnd(ReadZpgX(), 4); - } - - private void Execute65X02And39() // and abs, y - { - GetAddressAbsYCC(); - ExecuteAnd(ReadAbsY(), 4); - } - - private void Execute65X02And3D() // and abs, x - { - GetAddressAbsXCC(); - ExecuteAnd(ReadAbsX(), 4); - } - - private void Execute65X02Asl06() // asl zpg - { - GetAddressZpg(); - WriteZpg(ExecuteAsl(ReadZpg(), 5)); - } - - private void Execute65X02Asl0A() // asl imp - { - ExecuteAslImp(2); - } - - private void Execute65X02Asl0E() // asl abs - { - GetAddressAbs(); - WriteAbs(ExecuteAsl(ReadAbs(), 6)); - } - - private void Execute65X02Asl16() // asl zpg, x - { - GetAddressZpgX(); - WriteZpgX(ExecuteAsl(ReadZpgX(), 6)); - } - - private void Execute65X02Bcc90() // bcc rel - { - ExecuteBcc(2); - } - - private void Execute65X02BcsB0() // bcs rel - { - ExecuteBcs(2); - } - - private void Execute65X02BeqF0() // beq rel - { - ExecuteBeq(2); - } - - private void Execute65X02Bit24() // bit zpg - { - GetAddressZpg(); - ExecuteBit(ReadZpg(), 3); - } - - private void Execute65X02Bit2C() // bit abs - { - GetAddressAbs(); - ExecuteBit(ReadAbs(), 4); - } - - private void Execute65X02Bmi30() // bmi rel - { - ExecuteBmi(2); - } - - private void Execute65X02BneD0() // bne rel - { - ExecuteBne(2); - } - - private void Execute65X02Bpl10() // bpl rel - { - ExecuteBpl(2); - } - - private void Execute65X02Brk00() // brk imp - { - ExecuteBrk(7); - } - - private void Execute65X02Bvc50() // bvc rel - { - ExecuteBvc(2); - } - - private void Execute65X02Bvs70() // bvs rel - { - ExecuteBvs(2); - } - - private void Execute65X02Clc18() // clc imp - { - ExecuteClc(2); - } - - private void Execute65X02CldD8() // cld imp - { - ExecuteCld(2); - } - - private void Execute65X02Cli58() // cli imp - { - ExecuteCli(2); - } - - private void Execute65X02ClvB8() // clv imp - { - ExecuteClv(2); - } - - private void Execute65X02CmpC1() // cmp (zpg, x) - { - GetAddressZpgIndX(); - ExecuteCmp(ReadZpgIndX(), 6); - } - - private void Execute65X02CmpC5() // cmp zpg - { - GetAddressZpg(); - ExecuteCmp(ReadZpg(), 3); - } - - private void Execute65X02CmpC9() // cmp imm - { - ExecuteCmp(ReadImm(), 2); - } - - private void Execute65X02CmpCD() // cmp abs - { - GetAddressAbs(); - ExecuteCmp(ReadAbs(), 4); - } - - private void Execute65X02CmpD1() // cmp (zpg), y - { - GetAddressZpgIndYCC(); - ExecuteCmp(ReadZpgIndY(), 5); - } - - private void Execute65X02CmpD5() // cmp zpg, x - { - GetAddressZpgX(); - ExecuteCmp(ReadZpgX(), 4); - } - - private void Execute65X02CmpD9() // cmp abs, y - { - GetAddressAbsYCC(); - ExecuteCmp(ReadAbsY(), 4); - } - - private void Execute65X02CmpDD() // cmp abs, x - { - GetAddressAbsXCC(); - ExecuteCmp(ReadAbsX(), 4); - } - - private void Execute65X02CpxE0() // cpx imm - { - ExecuteCpx(ReadImm(), 2); - } - - private void Execute65X02CpxE4() // cpx zpg - { - GetAddressZpg(); - ExecuteCpx(ReadZpg(), 3); - } - - private void Execute65X02CpxEC() // cpx abs - { - GetAddressAbs(); - ExecuteCpx(ReadAbs(), 4); - } - - private void Execute65X02CpyC0() // cpy imm - { - ExecuteCpy(ReadImm(), 2); - } - - private void Execute65X02CpyC4() // cpy zpg - { - GetAddressZpg(); - ExecuteCpy(ReadZpg(), 3); - } - - private void Execute65X02CpyCC() // cpy abs - { - GetAddressAbs(); - ExecuteCpy(ReadAbs(), 4); - } - - private void Execute65X02DecC6() // dec zpg - { - GetAddressZpg(); - WriteZpg(ExecuteDec(ReadZpg(), 5)); - } - - private void Execute65X02DecCE() // dec abs - { - GetAddressAbs(); - WriteAbs(ExecuteDec(ReadAbs(), 6)); - } - - private void Execute65X02DecD6() // dec zpg, x - { - GetAddressZpgX(); - WriteZpgX(ExecuteDec(ReadZpgX(), 6)); - } - - private void Execute65X02DexCA() // dex imp - { - ExecuteDex(2); - } - - private void Execute65X02Dey88() // dey imp - { - ExecuteDey(2); - } - - private void Execute65X02Eor41() // eor (zpg, x) - { - GetAddressZpgIndX(); - ExecuteEor(ReadZpgIndX(), 6); - } - - private void Execute65X02Eor45() // eor zpg - { - GetAddressZpg(); - ExecuteEor(ReadZpg(), 3); - } - - private void Execute65X02Eor49() // eor imm - { - ExecuteEor(ReadImm(), 2); - } - - private void Execute65X02Eor4D() // eor abs - { - GetAddressAbs(); - ExecuteEor(ReadAbs(), 4); - } - - private void Execute65X02Eor51() // eor (zpg), y - { - GetAddressZpgIndYCC(); - ExecuteEor(ReadZpgIndY(), 5); - } - - private void Execute65X02Eor55() // eor zpg, x - { - GetAddressZpgX(); - ExecuteEor(ReadZpgX(), 4); - } - - private void Execute65X02Eor59() // eor abs, y - { - GetAddressAbsYCC(); - ExecuteEor(ReadAbsY(), 4); - } - - private void Execute65X02Eor5D() // eor abs, x - { - GetAddressAbsXCC(); - ExecuteEor(ReadAbsX(), 4); - } - - private void Execute65X02IncE6() // inc zpg - { - GetAddressZpg(); - WriteZpg(ExecuteInc(ReadZpg(), 5)); - } - - private void Execute65X02IncEE() // inc abs - { - GetAddressAbs(); - WriteAbs(ExecuteInc(ReadAbs(), 6)); - } - - private void Execute65X02IncF6() // inc zpg, x - { - GetAddressZpgX(); - WriteZpgX(ExecuteInc(ReadZpgX(), 6)); - } - - private void Execute65X02InxE8() // inx imp - { - ExecuteInx(2); - } - - private void Execute65X02InyC8() // iny imp - { - ExecuteIny(2); - } - - private void Execute65X02Jmp4C() // jmp abs - { - ExecuteJmpAbs(3); - } - - private void Execute65X02Jsr20() // jsr abs - { - ExecuteJsr(6); - } - - private void Execute65X02LdaA1() // lda (zpg, x) - { - GetAddressZpgIndX(); - ExecuteLda(ReadZpgIndX(), 6); - } - - private void Execute65X02LdaA5() // lda zpg - { - GetAddressZpg(); - ExecuteLda(ReadZpg(), 3); - } - - private void Execute65X02LdaA9() // lda imm - { - ExecuteLda(ReadImm(), 2); - } - - private void Execute65X02LdaAD() // lda abs - { - GetAddressAbs(); - ExecuteLda(ReadAbs(), 4); - } - - private void Execute65X02LdaB1() // lda (zpg), y - { - GetAddressZpgIndYCC(); - ExecuteLda(ReadZpgIndY(), 5); - } - - private void Execute65X02LdaB5() // lda zpg, x - { - GetAddressZpgX(); - ExecuteLda(ReadZpgX(), 4); - } - - private void Execute65X02LdaB9() // lda abs, y - { - GetAddressAbsYCC(); - ExecuteLda(ReadAbsY(), 4); - } - - private void Execute65X02LdaBD() // lda abs, x - { - GetAddressAbsXCC(); - ExecuteLda(ReadAbsX(), 4); - } - - private void Execute65X02LdxA2() // ldx imm - { - ExecuteLdx(ReadImm(), 2); - } - - private void Execute65X02LdxA6() // ldx zpg - { - GetAddressZpg(); - ExecuteLdx(ReadZpg(), 3); - } - - private void Execute65X02LdxAE() // ldx abs - { - GetAddressAbs(); - ExecuteLdx(ReadAbs(), 4); - } - - private void Execute65X02LdxB6() // ldx zpg, y - { - GetAddressZpgY(); - ExecuteLdx(ReadZpgY(), 4); - } - - private void Execute65X02LdxBE() // ldx abs, y - { - GetAddressAbsYCC(); - ExecuteLdx(ReadAbsY(), 4); - } - - private void Execute65X02LdyA0() // ldy imm - { - ExecuteLdy(ReadImm(), 2); - } - - private void Execute65X02LdyA4() // ldy zpg - { - GetAddressZpg(); - ExecuteLdy(ReadZpg(), 3); - } - - private void Execute65X02LdyAC() // ldy abs - { - GetAddressAbs(); - ExecuteLdy(ReadAbs(), 4); - } - - private void Execute65X02LdyB4() // ldy zpg, x - { - GetAddressZpgX(); - ExecuteLdy(ReadZpgX(), 4); - } - - private void Execute65X02LdyBC() // ldy abs, x - { - GetAddressAbsXCC(); - ExecuteLdy(ReadAbsX(), 4); - } - - private void Execute65X02Lsr46() // lsr zpg - { - GetAddressZpg(); - WriteZpg(ExecuteLsr(ReadZpg(), 5)); - } - - private void Execute65X02Lsr4A() // lsr imp - { - ExecuteLsrImp(2); - } - - private void Execute65X02Lsr4E() // lsr abs - { - GetAddressAbs(); - WriteAbs(ExecuteLsr(ReadAbs(), 6)); - } - - private void Execute65X02Lsr56() // lsr zpg, x - { - GetAddressZpgX(); - WriteZpgX(ExecuteLsr(ReadZpgX(), 6)); - } - - private void Execute65X02NopEA() // nop imp - { - ExecuteNop(2); - } - - private void Execute65X02Ora01() // ora (zpg, x) - { - GetAddressZpgIndX(); - ExecuteOra(ReadZpgIndX(), 6); - } - - private void Execute65X02Ora05() // ora zpg - { - GetAddressZpg(); - ExecuteOra(ReadZpg(), 3); - } - - private void Execute65X02Ora09() // ora imm - { - ExecuteOra(ReadImm(), 2); - } - - private void Execute65X02Ora0D() // ora abs - { - GetAddressAbs(); - ExecuteOra(ReadAbs(), 4); - } - - private void Execute65X02Ora11() // ora (zpg), y - { - GetAddressZpgIndYCC(); - ExecuteOra(ReadZpgIndY(), 5); - } - - private void Execute65X02Ora15() // ora zpg, x - { - GetAddressZpgX(); - ExecuteOra(ReadZpgX(), 4); - } - - private void Execute65X02Ora19() // ora abs, y - { - GetAddressAbsYCC(); - ExecuteOra(ReadAbsY(), 4); - } - - private void Execute65X02Ora1D() // ora abs, x - { - GetAddressAbsXCC(); - ExecuteOra(ReadAbsX(), 4); - } - - private void Execute65X02Pha48() // pha imp - { - ExecutePha(3); - } - - private void Execute65X02Php08() // php imp - { - ExecutePhp(3); - } - - private void Execute65X02Pla68() // pla imp - { - ExecutePla(4); - } - - private void Execute65X02Plp28() // plp imp - { - ExecutePlp(4); - } - - private void Execute65X02Rol26() // rol zpg - { - GetAddressZpg(); - WriteZpg(ExecuteRol(ReadZpg(), 5)); - } - - private void Execute65X02Rol2A() // rol imp - { - ExecuteRolImp(2); - } - - private void Execute65X02Rol2E() // rol abs - { - GetAddressAbs(); - WriteAbs(ExecuteRol(ReadAbs(), 6)); - } - - private void Execute65X02Rol36() // rol zpg, x - { - GetAddressZpgX(); - WriteZpgX(ExecuteRol(ReadZpgX(), 6)); - } - - private void Execute65X02Ror66() // ror zpg - { - GetAddressZpg(); - WriteZpg(ExecuteRor(ReadZpg(), 5)); - } - - private void Execute65X02Ror6A() // ror imp - { - ExecuteRorImp(2); - } - - private void Execute65X02Ror6E() // ror abs - { - GetAddressAbs(); - WriteAbs(ExecuteRor(ReadAbs(), 6)); - } - - private void Execute65X02Ror76() // ror zpg, x - { - GetAddressZpgX(); - WriteZpgX(ExecuteRor(ReadZpgX(), 6)); - } - - private void Execute65X02Rti40() // rti imp - { - ExecuteRti(6); - } - - private void Execute65X02Rts60() // rts imp - { - ExecuteRts(6); - } - - private void Execute65X02Sec38() // sec imp - { - ExecuteSec(2); - } - - private void Execute65X02SedF8() // sed imp - { - ExecuteSed(2); - } - - private void Execute65X02Sei78() // sei imp - { - ExecuteSei(2); - } - - private void Execute65X02Sta81() // sta (zpg, x) - { - GetAddressZpgIndX(); - WriteZpgIndX(RA); - ExecuteSta(6); - } - - private void Execute65X02Sta85() // sta zpg - { - GetAddressZpg(); - WriteZpg(RA); - ExecuteSta(3); - } - - private void Execute65X02Sta8D() // sta abs - { - GetAddressAbs(); - WriteAbs(RA); - ExecuteSta(4); - } - - private void Execute65X02Sta91() // sta (zpg), y - { - GetAddressZpgIndY(); - WriteZpgIndY(RA); - ExecuteSta(6); - } - - private void Execute65X02Sta95() // sta zpg, x - { - GetAddressZpgX(); - WriteZpgX(RA); - ExecuteSta(4); - } - - private void Execute65X02Sta99() // sta abs, y - { - GetAddressAbsY(); - WriteAbsY(RA); - ExecuteSta(5); - } - - private void Execute65X02Sta9D() // sta abs, x - { - GetAddressAbsX(); - WriteAbsX(RA); - ExecuteSta(5); - } - - private void Execute65X02Stx86() // stx zpg - { - GetAddressZpg(); - WriteZpg(RX); - ExecuteStx(3); - } - - private void Execute65X02Stx8E() // stx abs - { - GetAddressAbs(); - WriteAbs(RX); - ExecuteStx(4); - } - - private void Execute65X02Stx96() // stx zpg, y - { - GetAddressZpgY(); - WriteZpgY(RX); - ExecuteStx(4); - } - - private void Execute65X02Sty84() // sty zpg - { - GetAddressZpg(); - WriteZpg(RY); - ExecuteSty(3); - } - - private void Execute65X02Sty8C() // sty abs - { - GetAddressAbs(); - WriteAbs(RY); - ExecuteSty(4); - } - - private void Execute65X02Sty94() // sty zpg, x - { - GetAddressZpgX(); - WriteZpgX(RY); - ExecuteSty(4); - } - - private void Execute65X02TaxAA() // tax imp - { - ExecuteTax(2); - } - - private void Execute65X02TayA8() // tay imp - { - ExecuteTay(2); - } - - private void Execute65X02TsxBA() // tsx imp - { - ExecuteTsx(2); - } - - private void Execute65X02Txa8A() // txa imp - { - ExecuteTxa(2); - } - - private void Execute65X02Txs9A() // txs imp - { - ExecuteTxs(2); - } - - private void Execute65X02Tya98() // tya imp - { - ExecuteTya(2); - } - #endregion - - #region 65N02 Opcode Actions - private void Execute65N02Adc61() // adc (zpg, x) - { - GetAddressZpgIndX(); - ExecuteAdc65N02(ReadZpgIndX(), 6); - } - - private void Execute65N02Adc65() // adc zpg - { - GetAddressZpg(); - ExecuteAdc65N02(ReadZpg(), 3); - } - - private void Execute65N02Adc69() // adc imm - { - ExecuteAdc65N02(ReadImm(), 2); - } - - private void Execute65N02Adc6D() // adc abs - { - GetAddressAbs(); - ExecuteAdc65N02(ReadAbs(), 4); - } - - private void Execute65N02Adc71() // adc (zpg), y - { - GetAddressZpgIndYCC(); - ExecuteAdc65N02(ReadZpgIndY(), 5); - } - - private void Execute65N02Adc75() // adc zpg, x - { - GetAddressZpgX(); - ExecuteAdc65N02(ReadZpgX(), 4); - } - - private void Execute65N02Adc79() // adc abs, y - { - GetAddressAbsYCC(); - ExecuteAdc65N02(ReadAbsY(), 4); - } - - private void Execute65N02Adc7D() // adc abs, x - { - GetAddressAbsXCC(); - ExecuteAdc65N02(ReadAbsX(), 4); - } - - private void Execute65N02Asl1E() // asl abs, x - { - GetAddressAbsX(); - WriteAbsX(ExecuteAsl(ReadAbsX(), 7)); - } - - private void Execute65N02DecDE() // dec abs, x - { - GetAddressAbsX(); - WriteAbsX(ExecuteDec(ReadAbsX(), 7)); - } - - private void Execute65N02IncFE() // inc abs, x - { - GetAddressAbsX(); - WriteAbsX(ExecuteInc(ReadAbsX(), 7)); - } - - private void Execute65N02Jmp6C() // jmp (abs) - { - ExecuteJmpAbsInd65N02(5); - } - - private void Execute65N02Lsr5E() // lsr abs, x - { - GetAddressAbsX(); - WriteAbsX(ExecuteLsr(ReadAbsX(), 7)); - } - - private void Execute65N02Nop02() // nop imp0 - { - ExecuteNop(0, 2); - } - - private void Execute65N02Nop03() // nop imp1 - { - ExecuteNop(1, 6); - } - - private void Execute65N02Nop04() // nop imp1 - { - ExecuteNop(1, 2); - } - - private void Execute65N02Nop07() // nop imp1 - { - ExecuteNop(1, 5); - } - - private void Execute65N02Nop0B() // nop imp1 - { - ExecuteNop(1, 2); - } - - private void Execute65N02Nop0C() // nop imp2 - { - ExecuteNop(2, 4); - } - - private void Execute65N02Nop0F() // nop imp2 - { - ExecuteNop(2, 6); - } - - private void Execute65N02Nop12() // nop imp0 - { - ExecuteNop(0, 2); - } - - private void Execute65N02Nop13() // nop imp1 - { - ExecuteNop(1, 6); - } - - private void Execute65N02Nop14() // nop imp1 - { - ExecuteNop(1, 2); - } - - private void Execute65N02Nop17() // nop imp1 - { - ExecuteNop(1, 6); - } - - private void Execute65N02Nop1A() // nop imp0 - { - ExecuteNop(0, 2); - } - - private void Execute65N02Nop1B() // nop imp2 - { - ExecuteNop(2, 6); - } - - private void Execute65N02Nop1C() // nop imp2 - { - ExecuteNop(2, 4); - } - - private void Execute65N02Nop1F() // nop imp2 - { - ExecuteNop(2, 6); - } - - private void Execute65N02Nop22() // nop imp0 - { - ExecuteNop(0, 2); - } - - private void Execute65N02Nop23() // nop imp1 - { - ExecuteNop(1, 6); - } - - private void Execute65N02Nop27() // nop imp1 - { - ExecuteNop(1, 3); - } - - private void Execute65N02Nop2B() // nop imp1 - { - ExecuteNop(1, 2); - } - - private void Execute65N02Nop2F() // nop imp2 - { - ExecuteNop(2, 4); - } - - private void Execute65N02Nop32() // nop imp0 - { - ExecuteNop(0, 2); - } - - private void Execute65N02Nop33() // nop imp1 - { - ExecuteNop(1, 5); - } - - private void Execute65N02Nop34() // nop imp1 - { - ExecuteNop(1, 2); - } - - private void Execute65N02Nop37() // nop imp1 - { - ExecuteNop(1, 4); - } - - private void Execute65N02Nop3A() // nop imp0 - { - ExecuteNop(0, 2); - } - - private void Execute65N02Nop3B() // nop imp2 - { - ExecuteNop(2, 4); - } - - private void Execute65N02Nop3C() // nop imp2 - { - ExecuteNop(2, 4); - } - - private void Execute65N02Nop3F() // nop imp2 - { - ExecuteNop(2, 4); - } - - private void Execute65N02Nop42() // nop imp0 - { - ExecuteNop(0, 2); - } - - private void Execute65N02Nop43() // nop imp1 - { - ExecuteNop(1, 6); - } - - private void Execute65N02Nop44() // nop imp1 - { - ExecuteNop(1, 2); - } - - private void Execute65N02Nop47() // nop imp1 - { - ExecuteNop(1, 3); - } - - private void Execute65N02Nop4B() // nop imp1 - { - ExecuteNop(1, 2); - } - - private void Execute65N02Nop4F() // nop imp2 - { - ExecuteNop(2, 4); - } - - private void Execute65N02Nop52() // nop imp0 - { - ExecuteNop(0, 2); - } - - private void Execute65N02Nop53() // nop imp1 - { - ExecuteNop(1, 5); - } - - private void Execute65N02Nop54() // nop imp1 - { - ExecuteNop(1, 2); - } - - private void Execute65N02Nop57() // nop imp1 - { - ExecuteNop(1, 4); - } - - private void Execute65N02Nop5A() // nop imp0 - { - ExecuteNop(0, 2); - } - - private void Execute65N02Nop5B() // nop imp2 - { - ExecuteNop(2, 4); - } - - private void Execute65N02Nop5C() // nop imp2 - { - ExecuteNop(2, 4); - } - - private void Execute65N02Nop5F() // nop imp2 - { - ExecuteNop(2, 4); - } - - private void Execute65N02Nop62() // nop imp0 - { - ExecuteNop(0, 2); - } - - private void Execute65N02Nop63() // nop imp1 - { - ExecuteNop(1, 6); - } - - private void Execute65N02Nop64() // nop imp1 - { - ExecuteNop(1, 2); - } - - private void Execute65N02Nop67() // nop imp1 - { - ExecuteNop(1, 3); - } - - private void Execute65N02Nop6B() // nop imp1 - { - ExecuteNop(1, 2); - } - - private void Execute65N02Nop6F() // nop imp2 - { - ExecuteNop(2, 4); - } - - private void Execute65N02Nop72() // nop imp0 - { - ExecuteNop(0, 2); - } - - private void Execute65N02Nop73() // nop imp1 - { - ExecuteNop(1, 5); - } - - private void Execute65N02Nop74() // nop imp1 - { - ExecuteNop(1, 2); - } - - private void Execute65N02Nop77() // nop imp1 - { - ExecuteNop(1, 4); - } - - private void Execute65N02Nop7A() // nop imp0 - { - ExecuteNop(0, 2); - } - - private void Execute65N02Nop7B() // nop imp2 - { - ExecuteNop(2, 4); - } - - private void Execute65N02Nop7C() // nop imp2 - { - ExecuteNop(2, 4); - } - - private void Execute65N02Nop7F() // nop imp2 - { - ExecuteNop(2, 4); - } - - private void Execute65N02Nop80() // nop imp1 - { - ExecuteNop(1, 2); - } - - private void Execute65N02Nop82() // nop imp1 - { - ExecuteNop(1, 2); - } - - private void Execute65N02Nop83() // nop imp1 - { - ExecuteNop(1, 4); - } - - private void Execute65N02Nop87() // nop imp1 - { - ExecuteNop(1, 3); - } - - private void Execute65N02Nop89() // nop imp1 - { - ExecuteNop(1, 2); - } - - private void Execute65N02Nop8B() // nop imp1 - { - ExecuteNop(1, 2); - } - - private void Execute65N02Nop8F() // nop imp2 - { - ExecuteNop(2, 4); - } - - private void Execute65N02Nop92() // nop imp0 - { - ExecuteNop(0, 2); - } - - private void Execute65N02Nop93() // nop imp1 - { - ExecuteNop(1, 6); - } - - private void Execute65N02Nop97() // nop imp1 - { - ExecuteNop(1, 4); - } - - private void Execute65N02Nop9B() // nop imp2 - { - ExecuteNop(2, 5); - } - - private void Execute65N02Nop9C() // nop imp2 - { - ExecuteNop(2, 5); - } - - private void Execute65N02Nop9E() // nop imp2 - { - ExecuteNop(2, 5); - } - - private void Execute65N02Nop9F() // nop imp2 - { - ExecuteNop(2, 5); - } - - private void Execute65N02NopA3() // nop imp1 - { - ExecuteNop(1, 6); - } - - private void Execute65N02NopA7() // nop imp1 - { - ExecuteNop(1, 3); - } - - private void Execute65N02NopAB() // nop imp1 - { - ExecuteNop(1, 2); - } - - private void Execute65N02NopAF() // nop imp2 - { - ExecuteNop(2, 4); - } - - private void Execute65N02NopB2() // nop imp0 - { - ExecuteNop(0, 2); - } - - private void Execute65N02NopB3() // nop imp1 - { - ExecuteNop(1, 5); - } - - private void Execute65N02NopB7() // nop imp1 - { - ExecuteNop(1, 4); - } - - private void Execute65N02NopBB() // nop imp2 - { - ExecuteNop(2, 4); - } - - private void Execute65N02NopBF() // nop imp2 - { - ExecuteNop(2, 4); - } - - private void Execute65N02NopC2() // nop imp1 - { - ExecuteNop(1, 2); - } - - private void Execute65N02NopC3() // nop imp1 - { - ExecuteNop(1, 6); - } - - private void Execute65N02NopC7() // nop imp1 - { - ExecuteNop(1, 5); - } - - private void Execute65N02NopCB() // nop imp1 - { - ExecuteNop(1, 2); - } - - private void Execute65N02NopCF() // nop imp2 - { - ExecuteNop(2, 6); - } - - private void Execute65N02NopD2() // nop imp0 - { - ExecuteNop(0, 2); - } - - private void Execute65N02NopD3() // nop imp1 - { - ExecuteNop(1, 6); - } - - private void Execute65N02NopD4() // nop imp1 - { - ExecuteNop(1, 2); - } - - private void Execute65N02NopD7() // nop imp1 - { - ExecuteNop(1, 6); - } - - private void Execute65N02NopDA() // nop imp0 - { - ExecuteNop(0, 2); - } - - private void Execute65N02NopDB() // nop imp2 - { - ExecuteNop(2, 6); - } - - private void Execute65N02NopDC() // nop imp2 - { - ExecuteNop(2, 4); - } - - private void Execute65N02NopDF() // nop imp2 - { - ExecuteNop(2, 6); - } - - private void Execute65N02NopE2() // nop imp1 - { - ExecuteNop(1, 2); - } - - private void Execute65N02NopE3() // nop imp1 - { - ExecuteNop(1, 6); - } - - private void Execute65N02NopE7() // nop imp1 - { - ExecuteNop(1, 5); - } - - private void Execute65N02NopEB() // nop imp1 - { - ExecuteNop(1, 2); - } - - private void Execute65N02NopEF() // nop imp2 - { - ExecuteNop(2, 6); - } - - private void Execute65N02NopF2() // nop imp0 - { - ExecuteNop(0, 2); - } - - private void Execute65N02NopF3() // nop imp1 - { - ExecuteNop(1, 6); - } - - private void Execute65N02NopF4() // nop imp1 - { - ExecuteNop(1, 2); - } - - private void Execute65N02NopF7() // nop imp1 - { - ExecuteNop(1, 6); - } - - private void Execute65N02NopFA() // nop imp0 - { - ExecuteNop(0, 2); - } - - private void Execute65N02NopFB() // nop imp2 - { - ExecuteNop(2, 6); - } - - private void Execute65N02NopFC() // nop imp2 - { - ExecuteNop(2, 4); - } - - private void Execute65N02NopFF() // nop imp2 - { - ExecuteNop(2, 6); - } - - private void Execute65N02Rol3E() // rol abs, x - { - GetAddressAbsX(); - WriteAbsX(ExecuteRol(ReadAbsX(), 7)); - } - - private void Execute65N02Ror7E() // ror abs, x - { - GetAddressAbsX(); - WriteAbsX(ExecuteRor(ReadAbsX(), 7)); - } - - private void Execute65N02SbcE1() // sbc (zpg, x) - { - GetAddressZpgIndX(); - ExecuteSbc65N02(ReadZpgIndX(), 6); - } - - private void Execute65N02SbcE5() // sbc zpg - { - GetAddressZpg(); - ExecuteSbc65N02(ReadZpg(), 3); - } - - private void Execute65N02SbcE9() // sbc imm - { - ExecuteSbc65N02(ReadImm(), 2); - } - - private void Execute65N02SbcED() // sbc abs - { - GetAddressAbs(); - ExecuteSbc65N02(ReadAbs(), 4); - } - - private void Execute65N02SbcF1() // sbc (zpg), y - { - GetAddressZpgIndYCC(); - ExecuteSbc65N02(ReadZpgIndY(), 5); - } - - private void Execute65N02SbcF5() // sbc zpg, x - { - GetAddressZpgX(); - ExecuteSbc65N02(ReadZpgX(), 4); - } - - private void Execute65N02SbcF9() // sbc abs, y - { - GetAddressAbsYCC(); - ExecuteSbc65N02(ReadAbsY(), 4); - } - - private void Execute65N02SbcFD() // sbc abs, x - { - GetAddressAbsXCC(); - ExecuteSbc65N02(ReadAbsX(), 4); - } - #endregion - - #region 65C02 Opcode Actions - private void Execute65C02Adc61() // adc (zpg, x) - { - GetAddressZpgIndX(); - ExecuteAdc65C02(ReadZpgIndX(), 6); - } - - private void Execute65C02Adc65() // adc zpg - { - GetAddressZpg(); - ExecuteAdc65C02(ReadZpg(), 3); - } - - private void Execute65C02Adc69() // adc imm - { - ExecuteAdc65C02(ReadImm(), 2); - } - - private void Execute65C02Adc6D() // adc abs - { - GetAddressAbs(); - ExecuteAdc65C02(ReadAbs(), 4); - } - - private void Execute65C02Adc71() // adc (zpg), y - { - GetAddressZpgIndYCC(); - ExecuteAdc65C02(ReadZpgIndY(), 5); - } - - private void Execute65C02Adc72() // adc (zpg) - { - GetAddressZpgInd(); - ExecuteAdc65C02(ReadZpgInd(), 5); - } - - private void Execute65C02Adc75() // adc zpg, x - { - GetAddressZpgX(); - ExecuteAdc65C02(ReadZpgX(), 4); - } - - private void Execute65C02Adc79() // adc abs, y - { - GetAddressAbsYCC(); - ExecuteAdc65C02(ReadAbsY(), 4); - } - - private void Execute65C02Adc7D() // adc abs, x - { - GetAddressAbsXCC(); - ExecuteAdc65C02(ReadAbsX(), 4); - } - - private void Execute65C02And32() // and (zpg) - { - GetAddressZpgInd(); - ExecuteAnd(ReadZpgInd(), 5); - } - - private void Execute65C02Asl1E() // asl abs, x - { - GetAddressAbsXCC(); - WriteAbsX(ExecuteAsl(ReadAbsX(), 6)); - } - - private void Execute65C02Bit34() // bit zpg, x - { - GetAddressZpgX(); - ExecuteBit(ReadZpgX(), 4); - } - - private void Execute65C02Bit3C() // bit abs, x - { - GetAddressAbsXCC(); - ExecuteBit(ReadAbsX(), 4); - } - - private void Execute65C02Bit89() // bit imm - { - ExecuteBitImm(ReadImm(), 2); - } - - private void Execute65C02Bra80() // bra rel - { - ExecuteBra(2); - } - - private void Execute65C02CmpD2() // cmp (zpg) - { - GetAddressZpgInd(); - ExecuteCmp(ReadZpgInd(), 5); - } - - private void Execute65C02Dea3A() // dea imp - { - ExecuteDea(2); - } - - private void Execute65C02DecDE() // dec abs, x - { - GetAddressAbsXCC(); - WriteAbsX(ExecuteDec(ReadAbsX(), 6)); - } - - private void Execute65C02Eor52() // eor (zpg) - { - GetAddressZpgInd(); - ExecuteEor(ReadZpgInd(), 5); - } - - private void Execute65C02Ina1A() // ina imp - { - ExecuteIna(2); - } - - private void Execute65C02IncFE() // inc abs, x - { - GetAddressAbsXCC(); - WriteAbsX(ExecuteInc(ReadAbsX(), 6)); - } - - private void Execute65C02Jmp6C() // jmp (abs) - { - ExecuteJmpAbsInd65C02(6); - } - - private void Execute65C02Jmp7C() // jmp (abs, x) - { - ExecuteJmpAbsIndX(6); - } - - private void Execute65C02LdaB2() // lda (zpg) - { - GetAddressZpgInd(); - ExecuteLda(ReadZpgInd(), 5); - } - - private void Execute65C02Lsr5E() // lsr abs, x - { - GetAddressAbsXCC(); - WriteAbsX(ExecuteLsr(ReadAbsX(), 6)); - } - - private void Execute65C02Nop02() // nop imp1 - { - ExecuteNop(1, 2); - } - - private void Execute65C02Nop03() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop07() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop0B() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop0F() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop13() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop17() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop1B() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop1F() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop22() // nop imp1 - { - ExecuteNop(1, 2); - } - - private void Execute65C02Nop23() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop27() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop2B() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop2F() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop33() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop37() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop3B() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop3F() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop42() // nop imp1 - { - ExecuteNop(1, 2); - } - - private void Execute65C02Nop43() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop44() // nop imp1 - { - ExecuteNop(1, 3); - } - - private void Execute65C02Nop47() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop4B() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop4F() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop53() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop54() // nop imp1 - { - ExecuteNop(1, 4); - } - - private void Execute65C02Nop57() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop5B() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop5C() // nop imp2 - { - ExecuteNop(2, 8); - } - - private void Execute65C02Nop5F() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop62() // nop imp1 - { - ExecuteNop(1, 2); - } - - private void Execute65C02Nop63() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop67() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop6B() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop6F() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop73() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop77() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop7B() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop7F() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop82() // nop imp1 - { - ExecuteNop(1, 2); - } - - private void Execute65C02Nop83() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop87() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop8B() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop8F() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop93() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop97() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop9B() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Nop9F() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02NopA3() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02NopA7() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02NopAB() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02NopAF() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02NopB3() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02NopB7() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02NopBB() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02NopBF() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02NopC2() // nop imp1 - { - ExecuteNop(1, 2); - } - - private void Execute65C02NopC3() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02NopC7() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02NopCB() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02NopCF() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02NopD3() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02NopD4() // nop imp1 - { - ExecuteNop(1, 4); - } - - private void Execute65C02NopD7() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02NopDB() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02NopDC() // nop imp2 - { - ExecuteNop(2, 4); - } - - private void Execute65C02NopDF() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02NopE2() // nop imp1 - { - ExecuteNop(1, 2); - } - - private void Execute65C02NopE3() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02NopE7() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02NopEB() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02NopEF() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02NopF3() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02NopF4() // nop imp1 - { - ExecuteNop(1, 4); - } - - private void Execute65C02NopF7() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02NopFB() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02NopFC() // nop imp2 - { - ExecuteNop(2, 4); - } - - private void Execute65C02NopFF() // nop imp0 - { - ExecuteNop(0, 1); - } - - private void Execute65C02Ora12() // ora (zpg) - { - GetAddressZpgInd(); - ExecuteOra(ReadZpgInd(), 5); - } - - private void Execute65C02PhxDA() // phx imp - { - ExecutePhx(3); - } - - private void Execute65C02Phy5A() // phy imp - { - ExecutePhy(3); - } - - private void Execute65C02PlxFA() // plx imp - { - ExecutePlx(4); - } - - private void Execute65C02Ply7A() // ply imp - { - ExecutePly(4); - } - - private void Execute65C02Rol3E() // rol abs, x - { - GetAddressAbsXCC(); - WriteAbsX(ExecuteRol(ReadAbsX(), 6)); - } - - private void Execute65C02Ror7E() // ror abs, x - { - GetAddressAbsXCC(); - WriteAbsX(ExecuteRor(ReadAbsX(), 6)); - } - - private void Execute65C02SbcE1() // sbc (zpg, x) - { - GetAddressZpgIndX(); - ExecuteSbc65C02(ReadZpgIndX(), 6); - } - - private void Execute65C02SbcE5() // sbc zpg - { - GetAddressZpg(); - ExecuteSbc65C02(ReadZpg(), 3); - } - - private void Execute65C02SbcE9() // sbc imm - { - ExecuteSbc65C02(ReadImm(), 2); - } - - private void Execute65C02SbcED() // sbc abs - { - GetAddressAbs(); - ExecuteSbc65C02(ReadAbs(), 4); - } - - private void Execute65C02SbcF1() // sbc (zpg), y - { - GetAddressZpgIndYCC(); - ExecuteSbc65C02(ReadZpgIndY(), 5); - } - - private void Execute65C02SbcF2() // sbc (zpg) - { - GetAddressZpgInd(); - ExecuteSbc65C02(ReadZpgInd(), 5); - } - - private void Execute65C02SbcF5() // sbc zpg, x - { - GetAddressZpgX(); - ExecuteSbc65C02(ReadZpgX(), 4); - } - - private void Execute65C02SbcF9() // sbc abs, y - { - GetAddressAbsYCC(); - ExecuteSbc65C02(ReadAbsY(), 4); - } - - private void Execute65C02SbcFD() // sbc abs, x - { - GetAddressAbsXCC(); - ExecuteSbc65C02(ReadAbsX(), 4); - } - - private void Execute65C02Sta92() // sta (zpg) - { - GetAddressZpgInd(); - WriteZpgInd(RA); - ExecuteSta(5); - } - - private void Execute65C02Stz64() // stz zpg - { - GetAddressZpg(); - WriteZpg(0x00); - ExecuteStz(3); - } - - private void Execute65C02Stz74() // stz zpg, x - { - GetAddressZpgX(); - WriteZpgX(0x00); - ExecuteStz(4); - } - - private void Execute65C02Stz9C() // stz abs - { - GetAddressAbs(); - WriteAbs(0x00); - ExecuteStz(4); - } - - private void Execute65C02Stz9E() // stz abs, x - { - GetAddressAbsX(); - WriteAbsX(0x00); - ExecuteStz(5); - } - - private void Execute65C02Trb14() // trb zpg - { - GetAddressZpg(); - WriteZpg(ExecuteTrb(ReadZpg(), 5)); - } - - private void Execute65C02Trb1C() // trb abs - { - GetAddressAbs(); - WriteAbs(ExecuteTrb(ReadAbs(), 6)); - } - - private void Execute65C02Tsb04() // tsb zpg - { - GetAddressZpg(); - WriteZpg(ExecuteTsb(ReadZpg(), 5)); - } - - private void Execute65C02Tsb0C() // tsb abs - { - GetAddressAbs(); - WriteAbs(ExecuteTsb(ReadAbs(), 6)); - } - #endregion - - private void OnVideoVSync(object sender, EventArgs e) - { - UpdateSettings(); - } - - private void UpdateSettings() - { - _executeOpcode = Machine.Settings.Cpu.Is65C02 ? ExecuteOpcode65C02 : ExecuteOpcode65N02; - } - - public int RA { get; private set; } - public int RX { get; private set; } - public int RY { get; private set; } - public int RS { get; private set; } - public int RP { get; private set; } - public int RPC { get; private 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; } - - private Memory _memory; - - private Action[] _executeOpcode; - } -} +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Threading; + +namespace Jellyfish.Virtu +{ + public sealed partial class Cpu : MachineComponent + { + public Cpu(Machine machine) : + base(machine) + { + ExecuteOpcode65N02 = new Action[OpcodeCount] + { + Execute65X02Brk00, Execute65X02Ora01, Execute65N02Nop02, Execute65N02Nop03, + Execute65N02Nop04, Execute65X02Ora05, Execute65X02Asl06, Execute65N02Nop07, + Execute65X02Php08, Execute65X02Ora09, Execute65X02Asl0A, Execute65N02Nop0B, + Execute65N02Nop0C, Execute65X02Ora0D, Execute65X02Asl0E, Execute65N02Nop0F, + Execute65X02Bpl10, Execute65X02Ora11, Execute65N02Nop12, Execute65N02Nop13, + Execute65N02Nop14, Execute65X02Ora15, Execute65X02Asl16, Execute65N02Nop17, + Execute65X02Clc18, Execute65X02Ora19, Execute65N02Nop1A, Execute65N02Nop1B, + Execute65N02Nop1C, Execute65X02Ora1D, Execute65N02Asl1E, Execute65N02Nop1F, + Execute65X02Jsr20, Execute65X02And21, Execute65N02Nop22, Execute65N02Nop23, + Execute65X02Bit24, Execute65X02And25, Execute65X02Rol26, Execute65N02Nop27, + Execute65X02Plp28, Execute65X02And29, Execute65X02Rol2A, Execute65N02Nop2B, + Execute65X02Bit2C, Execute65X02And2D, Execute65X02Rol2E, Execute65N02Nop2F, + Execute65X02Bmi30, Execute65X02And31, Execute65N02Nop32, Execute65N02Nop33, + Execute65N02Nop34, Execute65X02And35, Execute65X02Rol36, Execute65N02Nop37, + Execute65X02Sec38, Execute65X02And39, Execute65N02Nop3A, Execute65N02Nop3B, + Execute65N02Nop3C, Execute65X02And3D, Execute65N02Rol3E, Execute65N02Nop3F, + Execute65X02Rti40, Execute65X02Eor41, Execute65N02Nop42, Execute65N02Nop43, + Execute65N02Nop44, Execute65X02Eor45, Execute65X02Lsr46, Execute65N02Nop47, + Execute65X02Pha48, Execute65X02Eor49, Execute65X02Lsr4A, Execute65N02Nop4B, + Execute65X02Jmp4C, Execute65X02Eor4D, Execute65X02Lsr4E, Execute65N02Nop4F, + Execute65X02Bvc50, Execute65X02Eor51, Execute65N02Nop52, Execute65N02Nop53, + Execute65N02Nop54, Execute65X02Eor55, Execute65X02Lsr56, Execute65N02Nop57, + Execute65X02Cli58, Execute65X02Eor59, Execute65N02Nop5A, Execute65N02Nop5B, + Execute65N02Nop5C, Execute65X02Eor5D, Execute65N02Lsr5E, Execute65N02Nop5F, + Execute65X02Rts60, Execute65N02Adc61, Execute65N02Nop62, Execute65N02Nop63, + Execute65N02Nop64, Execute65N02Adc65, Execute65X02Ror66, Execute65N02Nop67, + Execute65X02Pla68, Execute65N02Adc69, Execute65X02Ror6A, Execute65N02Nop6B, + Execute65N02Jmp6C, Execute65N02Adc6D, Execute65X02Ror6E, Execute65N02Nop6F, + Execute65X02Bvs70, Execute65N02Adc71, Execute65N02Nop72, Execute65N02Nop73, + Execute65N02Nop74, Execute65N02Adc75, Execute65X02Ror76, Execute65N02Nop77, + Execute65X02Sei78, Execute65N02Adc79, Execute65N02Nop7A, Execute65N02Nop7B, + Execute65N02Nop7C, Execute65N02Adc7D, Execute65N02Ror7E, Execute65N02Nop7F, + Execute65N02Nop80, Execute65X02Sta81, Execute65N02Nop82, Execute65N02Nop83, + Execute65X02Sty84, Execute65X02Sta85, Execute65X02Stx86, Execute65N02Nop87, + Execute65X02Dey88, Execute65N02Nop89, Execute65X02Txa8A, Execute65N02Nop8B, + Execute65X02Sty8C, Execute65X02Sta8D, Execute65X02Stx8E, Execute65N02Nop8F, + Execute65X02Bcc90, Execute65X02Sta91, Execute65N02Nop92, Execute65N02Nop93, + Execute65X02Sty94, Execute65X02Sta95, Execute65X02Stx96, Execute65N02Nop97, + Execute65X02Tya98, Execute65X02Sta99, Execute65X02Txs9A, Execute65N02Nop9B, + Execute65N02Nop9C, Execute65X02Sta9D, Execute65N02Nop9E, Execute65N02Nop9F, + Execute65X02LdyA0, Execute65X02LdaA1, Execute65X02LdxA2, Execute65N02NopA3, + Execute65X02LdyA4, Execute65X02LdaA5, Execute65X02LdxA6, Execute65N02NopA7, + Execute65X02TayA8, Execute65X02LdaA9, Execute65X02TaxAA, Execute65N02NopAB, + Execute65X02LdyAC, Execute65X02LdaAD, Execute65X02LdxAE, Execute65N02NopAF, + Execute65X02BcsB0, Execute65X02LdaB1, Execute65N02NopB2, Execute65N02NopB3, + Execute65X02LdyB4, Execute65X02LdaB5, Execute65X02LdxB6, Execute65N02NopB7, + Execute65X02ClvB8, Execute65X02LdaB9, Execute65X02TsxBA, Execute65N02NopBB, + Execute65X02LdyBC, Execute65X02LdaBD, Execute65X02LdxBE, Execute65N02NopBF, + Execute65X02CpyC0, Execute65X02CmpC1, Execute65N02NopC2, Execute65N02NopC3, + Execute65X02CpyC4, Execute65X02CmpC5, Execute65X02DecC6, Execute65N02NopC7, + Execute65X02InyC8, Execute65X02CmpC9, Execute65X02DexCA, Execute65N02NopCB, + Execute65X02CpyCC, Execute65X02CmpCD, Execute65X02DecCE, Execute65N02NopCF, + Execute65X02BneD0, Execute65X02CmpD1, Execute65N02NopD2, Execute65N02NopD3, + Execute65N02NopD4, Execute65X02CmpD5, Execute65X02DecD6, Execute65N02NopD7, + Execute65X02CldD8, Execute65X02CmpD9, Execute65N02NopDA, Execute65N02NopDB, + Execute65N02NopDC, Execute65X02CmpDD, Execute65N02DecDE, Execute65N02NopDF, + Execute65X02CpxE0, Execute65N02SbcE1, Execute65N02NopE2, Execute65N02NopE3, + Execute65X02CpxE4, Execute65N02SbcE5, Execute65X02IncE6, Execute65N02NopE7, + Execute65X02InxE8, Execute65N02SbcE9, Execute65X02NopEA, Execute65N02NopEB, + Execute65X02CpxEC, Execute65N02SbcED, Execute65X02IncEE, Execute65N02NopEF, + Execute65X02BeqF0, Execute65N02SbcF1, Execute65N02NopF2, Execute65N02NopF3, + Execute65N02NopF4, Execute65N02SbcF5, Execute65X02IncF6, Execute65N02NopF7, + Execute65X02SedF8, Execute65N02SbcF9, Execute65N02NopFA, Execute65N02NopFB, + Execute65N02NopFC, Execute65N02SbcFD, Execute65N02IncFE, Execute65N02NopFF + }; + + ExecuteOpcode65C02 = new Action[OpcodeCount] + { + Execute65X02Brk00, Execute65X02Ora01, Execute65C02Nop02, Execute65C02Nop03, + Execute65C02Tsb04, Execute65X02Ora05, Execute65X02Asl06, Execute65C02Nop07, + Execute65X02Php08, Execute65X02Ora09, Execute65X02Asl0A, Execute65C02Nop0B, + Execute65C02Tsb0C, Execute65X02Ora0D, Execute65X02Asl0E, Execute65C02Nop0F, + Execute65X02Bpl10, Execute65X02Ora11, Execute65C02Ora12, Execute65C02Nop13, + Execute65C02Trb14, Execute65X02Ora15, Execute65X02Asl16, Execute65C02Nop17, + Execute65X02Clc18, Execute65X02Ora19, Execute65C02Ina1A, Execute65C02Nop1B, + Execute65C02Trb1C, Execute65X02Ora1D, Execute65C02Asl1E, Execute65C02Nop1F, + Execute65X02Jsr20, Execute65X02And21, Execute65C02Nop22, Execute65C02Nop23, + Execute65X02Bit24, Execute65X02And25, Execute65X02Rol26, Execute65C02Nop27, + Execute65X02Plp28, Execute65X02And29, Execute65X02Rol2A, Execute65C02Nop2B, + Execute65X02Bit2C, Execute65X02And2D, Execute65X02Rol2E, Execute65C02Nop2F, + Execute65X02Bmi30, Execute65X02And31, Execute65C02And32, Execute65C02Nop33, + Execute65C02Bit34, Execute65X02And35, Execute65X02Rol36, Execute65C02Nop37, + Execute65X02Sec38, Execute65X02And39, Execute65C02Dea3A, Execute65C02Nop3B, + Execute65C02Bit3C, Execute65X02And3D, Execute65C02Rol3E, Execute65C02Nop3F, + Execute65X02Rti40, Execute65X02Eor41, Execute65C02Nop42, Execute65C02Nop43, + Execute65C02Nop44, Execute65X02Eor45, Execute65X02Lsr46, Execute65C02Nop47, + Execute65X02Pha48, Execute65X02Eor49, Execute65X02Lsr4A, Execute65C02Nop4B, + Execute65X02Jmp4C, Execute65X02Eor4D, Execute65X02Lsr4E, Execute65C02Nop4F, + Execute65X02Bvc50, Execute65X02Eor51, Execute65C02Eor52, Execute65C02Nop53, + Execute65C02Nop54, Execute65X02Eor55, Execute65X02Lsr56, Execute65C02Nop57, + Execute65X02Cli58, Execute65X02Eor59, Execute65C02Phy5A, Execute65C02Nop5B, + Execute65C02Nop5C, Execute65X02Eor5D, Execute65C02Lsr5E, Execute65C02Nop5F, + Execute65X02Rts60, Execute65C02Adc61, Execute65C02Nop62, Execute65C02Nop63, + Execute65C02Stz64, Execute65C02Adc65, Execute65X02Ror66, Execute65C02Nop67, + Execute65X02Pla68, Execute65C02Adc69, Execute65X02Ror6A, Execute65C02Nop6B, + Execute65C02Jmp6C, Execute65C02Adc6D, Execute65X02Ror6E, Execute65C02Nop6F, + Execute65X02Bvs70, Execute65C02Adc71, Execute65C02Adc72, Execute65C02Nop73, + Execute65C02Stz74, Execute65C02Adc75, Execute65X02Ror76, Execute65C02Nop77, + Execute65X02Sei78, Execute65C02Adc79, Execute65C02Ply7A, Execute65C02Nop7B, + Execute65C02Jmp7C, Execute65C02Adc7D, Execute65C02Ror7E, Execute65C02Nop7F, + Execute65C02Bra80, Execute65X02Sta81, Execute65C02Nop82, Execute65C02Nop83, + Execute65X02Sty84, Execute65X02Sta85, Execute65X02Stx86, Execute65C02Nop87, + Execute65X02Dey88, Execute65C02Bit89, Execute65X02Txa8A, Execute65C02Nop8B, + Execute65X02Sty8C, Execute65X02Sta8D, Execute65X02Stx8E, Execute65C02Nop8F, + Execute65X02Bcc90, Execute65X02Sta91, Execute65C02Sta92, Execute65C02Nop93, + Execute65X02Sty94, Execute65X02Sta95, Execute65X02Stx96, Execute65C02Nop97, + Execute65X02Tya98, Execute65X02Sta99, Execute65X02Txs9A, Execute65C02Nop9B, + Execute65C02Stz9C, Execute65X02Sta9D, Execute65C02Stz9E, Execute65C02Nop9F, + Execute65X02LdyA0, Execute65X02LdaA1, Execute65X02LdxA2, Execute65C02NopA3, + Execute65X02LdyA4, Execute65X02LdaA5, Execute65X02LdxA6, Execute65C02NopA7, + Execute65X02TayA8, Execute65X02LdaA9, Execute65X02TaxAA, Execute65C02NopAB, + Execute65X02LdyAC, Execute65X02LdaAD, Execute65X02LdxAE, Execute65C02NopAF, + Execute65X02BcsB0, Execute65X02LdaB1, Execute65C02LdaB2, Execute65C02NopB3, + Execute65X02LdyB4, Execute65X02LdaB5, Execute65X02LdxB6, Execute65C02NopB7, + Execute65X02ClvB8, Execute65X02LdaB9, Execute65X02TsxBA, Execute65C02NopBB, + Execute65X02LdyBC, Execute65X02LdaBD, Execute65X02LdxBE, Execute65C02NopBF, + Execute65X02CpyC0, Execute65X02CmpC1, Execute65C02NopC2, Execute65C02NopC3, + Execute65X02CpyC4, Execute65X02CmpC5, Execute65X02DecC6, Execute65C02NopC7, + Execute65X02InyC8, Execute65X02CmpC9, Execute65X02DexCA, Execute65C02NopCB, + Execute65X02CpyCC, Execute65X02CmpCD, Execute65X02DecCE, Execute65C02NopCF, + Execute65X02BneD0, Execute65X02CmpD1, Execute65C02CmpD2, Execute65C02NopD3, + Execute65C02NopD4, Execute65X02CmpD5, Execute65X02DecD6, Execute65C02NopD7, + Execute65X02CldD8, Execute65X02CmpD9, Execute65C02PhxDA, Execute65C02NopDB, + Execute65C02NopDC, Execute65X02CmpDD, Execute65C02DecDE, Execute65C02NopDF, + Execute65X02CpxE0, Execute65C02SbcE1, Execute65C02NopE2, Execute65C02NopE3, + Execute65X02CpxE4, Execute65C02SbcE5, Execute65X02IncE6, Execute65C02NopE7, + Execute65X02InxE8, Execute65C02SbcE9, Execute65X02NopEA, Execute65C02NopEB, + Execute65X02CpxEC, Execute65C02SbcED, Execute65X02IncEE, Execute65C02NopEF, + Execute65X02BeqF0, Execute65C02SbcF1, Execute65C02SbcF2, Execute65C02NopF3, + Execute65C02NopF4, Execute65C02SbcF5, Execute65X02IncF6, Execute65C02NopF7, + Execute65X02SedF8, Execute65C02SbcF9, Execute65C02PlxFA, Execute65C02NopFB, + Execute65C02NopFC, Execute65C02SbcFD, Execute65C02IncFE, Execute65C02NopFF + }; + + RS = 0xFF; + } + + public override void Initialize() + { + _memory = Machine.Memory; + + UpdateSettings(); + + Machine.Video.VSync += OnVideoVSync; + } + + public override void Reset() + { + RS = (RS - 3) & 0xFF; // [4-14] + RPC = _memory.ReadRomRegionE0FF(0xFFFC) | (_memory.ReadRomRegionE0FF(0xFFFD) << 8); + RP |= (PB | PI); + if (Machine.Settings.Cpu.Is65C02) // [C-10] + { + RP &= ~PD; + } + } + + public override string ToString() + { + return string.Format(CultureInfo.CurrentCulture, "A = 0x{0:X2} X = 0x{1:X2} Y = 0x{2:X2} P = 0x{3:X2} S = 0x01{4:X2} PC = 0x{5:X4} EA = 0x{6:X4} CC = {7}", + RA, RX, RY, RP, RS, RPC, EA, CC); + } + + public int Execute() + { + CC = 0; + Opcode = _memory.Read(RPC); + RPC = (RPC + 1) & 0xFFFF; + _executeOpcode[Opcode](); + Cycles += CC; + + return CC; + } + + public void ToggleThrottle() + { + Machine.Settings.Cpu.IsThrottled ^= true; + } + + #region Core Operand Actions + private void GetAddressAbs() // abs + { + EA = _memory.Read(RPC) | (_memory.Read(RPC + 1) << 8); + RPC = (RPC + 2) & 0xFFFF; + } + + private void GetAddressAbsX() // abs, x + { + EA = (_memory.Read(RPC) + RX + (_memory.Read(RPC + 1) << 8)) & 0xFFFF; + RPC = (RPC + 2) & 0xFFFF; + } + + private void GetAddressAbsXCC() // abs, x + { + int ea = _memory.Read(RPC) + RX; + EA = (ea + (_memory.Read(RPC + 1) << 8)) & 0xFFFF; + RPC = (RPC + 2) & 0xFFFF; + CC += (ea >> 8); + } + + private void GetAddressAbsY() // abs, y + { + EA = (_memory.Read(RPC) + RY + (_memory.Read(RPC + 1) << 8)) & 0xFFFF; + RPC = (RPC + 2) & 0xFFFF; + } + + private void GetAddressAbsYCC() // abs, y + { + int ea = _memory.Read(RPC) + RY; + EA = (ea + (_memory.Read(RPC + 1) << 8)) & 0xFFFF; + RPC = (RPC + 2) & 0xFFFF; + CC += (ea >> 8); + } + + private void GetAddressZpg() // zpg + { + EA = _memory.Read(RPC); + RPC = (RPC + 1) & 0xFFFF; + } + + private void GetAddressZpgInd() // (zpg) + { + int zp = _memory.Read(RPC); + EA = _memory.ReadZeroPage(zp) | (_memory.ReadZeroPage((zp + 1) & 0xFF) << 8); + RPC = (RPC + 1) & 0xFFFF; + } + + private void GetAddressZpgIndX() // (zpg, x) + { + int zp = (_memory.Read(RPC) + RX) & 0xFF; + EA = _memory.ReadZeroPage(zp) | (_memory.ReadZeroPage((zp + 1) & 0xFF) << 8); + RPC = (RPC + 1) & 0xFFFF; + } + + private void GetAddressZpgIndY() // (zpg), y + { + int zp = _memory.Read(RPC); + EA = (_memory.ReadZeroPage(zp) + RY + (_memory.ReadZeroPage((zp + 1) & 0xFF) << 8)) & 0xFFFF; + RPC = (RPC + 1) & 0xFFFF; + } + + private void GetAddressZpgIndYCC() // (zpg), y + { + int zp = _memory.Read(RPC); + int ea = _memory.ReadZeroPage(zp) + RY; + EA = (ea + (_memory.ReadZeroPage((zp + 1) & 0xFF) << 8)) & 0xFFFF; + RPC = (RPC + 1) & 0xFFFF; + CC += (ea >> 8); + } + + private void GetAddressZpgX() // zpg, x + { + EA = (_memory.Read(RPC) + RX) & 0xFF; + RPC = (RPC + 1) & 0xFFFF; + } + + private void GetAddressZpgY() // zpg, y + { + EA = (_memory.Read(RPC) + RY) & 0xFF; + RPC = (RPC + 1) & 0xFFFF; + } + + private int Pull() + { + RS = (RS + 1) & 0xFF; + + return _memory.ReadZeroPage(0x0100 + RS); + } + + private void Push(int data) + { + _memory.WriteZeroPage(0x0100 + RS, data); + RS = (RS - 1) & 0xFF; + } + + private int ReadAbs() // abs + { + return _memory.Read(EA); + } + + private int ReadAbsX() // abs, x + { + return _memory.Read(EA); + } + + private int ReadAbsY() // abs, y + { + return _memory.Read(EA); + } + + private int ReadImm() // imm + { + int data = _memory.Read(RPC); + RPC = (RPC + 1) & 0xFFFF; + + return data; + } + + private int ReadZpg() // zpg + { + return _memory.ReadZeroPage(EA); + } + + private int ReadZpgInd() // (zpg) + { + return _memory.Read(EA); + } + + private int ReadZpgIndX() // (zpg, x) + { + return _memory.Read(EA); + } + + private int ReadZpgIndY() // (zpg), y + { + return _memory.Read(EA); + } + + private int ReadZpgX() // zpg, x + { + return _memory.ReadZeroPage(EA); + } + + private int ReadZpgY() // zpg, y + { + return _memory.ReadZeroPage(EA); + } + + private void WriteAbs(int data) // abs + { + _memory.Write(EA, data); + } + + private void WriteAbsX(int data) // abs, x + { + _memory.Write(EA, data); + } + + private void WriteAbsY(int data) // abs, y + { + _memory.Write(EA, data); + } + + private void WriteZpg(int data) // zpg + { + _memory.WriteZeroPage(EA, data); + } + + private void WriteZpgInd(int data) // (zpg) + { + _memory.Write(EA, data); + } + + private void WriteZpgIndX(int data) // (zpg, x) + { + _memory.Write(EA, data); + } + + private void WriteZpgIndY(int data) // (zpg), y + { + _memory.Write(EA, data); + } + + private void WriteZpgX(int data) // zpg, x + { + _memory.WriteZeroPage(EA, data); + } + + private void WriteZpgY(int data) // zpg, y + { + _memory.WriteZeroPage(EA, data); + } + #endregion + + #region Core Opcode Actions + private void ExecuteAdc65N02(int data, int cc) + { + if ((RP & PD) == 0x0) + { + int ra = RA + data + (RP & PC); + RP = RP & ~(PC | PN | PV | PZ) | ((ra >> 8) & PC) | DataPNZ[ra & 0xFF] | (((~(RA ^ data) & (RA ^ (ra & 0xFF))) >> 1) & PV); + RA = ra & 0xFF; + CC += cc; + } + else // decimal + { + int ral = (RA & 0x0F) + (data & 0x0F) + (RP & PC); + int rah = (RA >> 4) + (data >> 4); + if (ral >= 10) + { + ral -= 10; + rah++; + } + int ra = (ral | (rah << 4)) & 0xFF; + RP = RP & ~(PC | PN | PV | PZ) | DataPN[ra] | (((~(RA ^ data) & (RA ^ ra)) >> 1) & PV) | DataPZ[(RA + data + (RP & PC)) & 0xFF]; + if (rah >= 10) + { + rah -= 10; + RP |= PC; + } + RA = (ral | (rah << 4)) & 0xFF; + CC += cc; + } + } + + private void ExecuteAdc65C02(int data, int cc) + { + if ((RP & PD) == 0x0) + { + int ra = RA + data + (RP & PC); + RP = RP & ~(PC | PN | PV | PZ) | ((ra >> 8) & PC) | DataPNZ[ra & 0xFF] | (((~(RA ^ data) & (RA ^ (ra & 0xFF))) >> 1) & PV); + RA = ra & 0xFF; + CC += cc; + } + else // decimal + { + int ral = (RA & 0x0F) + (data & 0x0F) + (RP & PC); + int rah = (RA >> 4) + (data >> 4); + if (ral >= 10) + { + ral -= 10; + rah++; + } + RP &= ~PC; + if (rah >= 10) + { + rah -= 10; + RP |= PC; + } + int ra = (ral | (rah << 4)) & 0xFF; + RP = RP & ~(PN | PV | PZ) | DataPNZ[ra] | (((~(RA ^ data) & (RA ^ ra)) >> 1) & PV); + RA = ra; + CC += cc + 1; + } + } + + private void ExecuteAnd(int data, int cc) + { + RA &= data; + RP = RP & ~(PN | PZ) | DataPNZ[RA]; + CC += cc; + } + + private int ExecuteAsl(int data, int cc) + { + RP = RP & ~PC | ((data >> 7) & PC); + data = (data << 1) & 0xFF; + RP = RP & ~(PN | PZ) | DataPNZ[data]; + CC += cc; + + return data; + } + + private void ExecuteAslImp(int cc) + { + RP = RP & ~PC | ((RA >> 7) & PC); + RA = (RA << 1) & 0xFF; + RP = RP & ~(PN | PZ) | DataPNZ[RA]; + CC += cc; + } + + private void ExecuteBcc(int cc) + { + if ((RP & PC) == 0x0) + { + int rpc = (RPC + 1) & 0xFFFF; + RPC = (RPC + 1 + (sbyte)_memory.Read(RPC)) & 0xFFFF; + CC += cc + 1 + (((RPC ^ rpc) >> 8) & 0x01); + } + else + { + RPC = (RPC + 1) & 0xFFFF; + CC += cc; + } + } + + private void ExecuteBcs(int cc) + { + if ((RP & PC) != 0x0) + { + int rpc = (RPC + 1) & 0xFFFF; + RPC = (RPC + 1 + (sbyte)_memory.Read(RPC)) & 0xFFFF; + CC += cc + 1 + (((RPC ^ rpc) >> 8) & 0x01); + } + else + { + RPC = (RPC + 1) & 0xFFFF; + CC += cc; + } + } + + private void ExecuteBeq(int cc) + { + if ((RP & PZ) != 0x0) + { + int rpc = (RPC + 1) & 0xFFFF; + RPC = (RPC + 1 + (sbyte)_memory.Read(RPC)) & 0xFFFF; + CC += cc + 1 + (((RPC ^ rpc) >> 8) & 0x01); + } + else + { + RPC = (RPC + 1) & 0xFFFF; + CC += cc; + } + } + + private void ExecuteBit(int data, int cc) + { + RP = RP & ~(PN | PV | PZ) | (data & (PN | PV)) | DataPZ[RA & data]; + CC += cc; + } + + private void ExecuteBitImm(int data, int cc) + { + RP = RP & ~PZ | DataPZ[RA & data]; + CC += cc; + } + + private void ExecuteBmi(int cc) + { + if ((RP & PN) != 0x0) + { + int rpc = (RPC + 1) & 0xFFFF; + RPC = (RPC + 1 + (sbyte)_memory.Read(RPC)) & 0xFFFF; + CC += cc + 1 + (((RPC ^ rpc) >> 8) & 0x01); + } + else + { + RPC = (RPC + 1) & 0xFFFF; + CC += cc; + } + } + + private void ExecuteBne(int cc) + { + if ((RP & PZ) == 0x0) + { + int rpc = (RPC + 1) & 0xFFFF; + RPC = (RPC + 1 + (sbyte)_memory.Read(RPC)) & 0xFFFF; + CC += cc + 1 + (((RPC ^ rpc) >> 8) & 0x01); + } + else + { + RPC = (RPC + 1) & 0xFFFF; + CC += cc; + } + } + + private void ExecuteBpl(int cc) + { + if ((RP & PN) == 0x0) + { + int rpc = (RPC + 1) & 0xFFFF; + RPC = (RPC + 1 + (sbyte)_memory.Read(RPC)) & 0xFFFF; + CC += cc + 1 + (((RPC ^ rpc) >> 8) & 0x01); + } + else + { + RPC = (RPC + 1) & 0xFFFF; + CC += cc; + } + } + + private void ExecuteBra(int cc) + { + int rpc = (RPC + 1) & 0xFFFF; + RPC = (RPC + 1 + (sbyte)_memory.Read(RPC)) & 0xFFFF; + CC += cc + 1 + (((RPC ^ rpc) >> 8) & 0x01); + } + + private void ExecuteBrk(int cc) + { + int rpc = (RPC + 1) & 0xFFFF; // [4-18] + Push(rpc >> 8); + Push(rpc & 0xFF); + Push(RP | PB); + RP |= PI; + RPC = _memory.Read(0xFFFE) | (_memory.Read(0xFFFF) << 8); + CC += cc; + } + + private void ExecuteBvc(int cc) + { + if ((RP & PV) == 0x0) + { + int rpc = (RPC + 1) & 0xFFFF; + RPC = (RPC + 1 + (sbyte)_memory.Read(RPC)) & 0xFFFF; + CC += cc + 1 + (((RPC ^ rpc) >> 8) & 0x01); + } + else + { + RPC = (RPC + 1) & 0xFFFF; + CC += cc; + } + } + + private void ExecuteBvs(int cc) + { + if ((RP & PV) != 0x0) + { + int rpc = (RPC + 1) & 0xFFFF; + RPC = (RPC + 1 + (sbyte)_memory.Read(RPC)) & 0xFFFF; + CC += cc + 1 + (((RPC ^ rpc) >> 8) & 0x01); + } + else + { + RPC = (RPC + 1) & 0xFFFF; + CC += cc; + } + } + + private void ExecuteClc(int cc) + { + RP &= ~PC; + CC += cc; + } + + private void ExecuteCld(int cc) + { + RP &= ~PD; + CC += cc; + } + + private void ExecuteCli(int cc) + { + RP &= ~PI; + CC += cc; + } + + private void ExecuteClv(int cc) + { + RP &= ~PV; + CC += cc; + } + + private void ExecuteCmp(int data, int cc) + { + int diff = RA - data; + RP = RP & ~(PC | PN | PZ) | ((~diff >> 8) & PC) | DataPNZ[diff & 0xFF]; + CC += cc; + } + + private void ExecuteCpx(int data, int cc) + { + int diff = RX - data; + RP = RP & ~(PC | PN | PZ) | ((~diff >> 8) & PC) | DataPNZ[diff & 0xFF]; + CC += cc; + } + + private void ExecuteCpy(int data, int cc) + { + int diff = RY - data; + RP = RP & ~(PC | PN | PZ) | ((~diff >> 8) & PC) | DataPNZ[diff & 0xFF]; + CC += cc; + } + + private void ExecuteDea(int cc) + { + RA = (RA - 1) & 0xFF; + RP = RP & ~(PN | PZ) | DataPNZ[RA]; + CC += cc; + } + + private int ExecuteDec(int data, int cc) + { + data = (data - 1) & 0xFF; + RP = RP & ~(PN | PZ) | DataPNZ[data]; + CC += cc; + + return data; + } + + private void ExecuteDex(int cc) + { + RX = (RX - 1) & 0xFF; + RP = RP & ~(PN | PZ) | DataPNZ[RX]; + CC += cc; + } + + private void ExecuteDey(int cc) + { + RY = (RY - 1) & 0xFF; + RP = RP & ~(PN | PZ) | DataPNZ[RY]; + CC += cc; + } + + private void ExecuteEor(int data, int cc) + { + RA ^= data; + RP = RP & ~(PN | PZ) | DataPNZ[RA]; + CC += cc; + } + + private void ExecuteIna(int cc) + { + RA = (RA + 1) & 0xFF; + RP = RP & ~(PN | PZ) | DataPNZ[RA]; + CC += cc; + } + + private int ExecuteInc(int data, int cc) + { + data = (data + 1) & 0xFF; + RP = RP & ~(PN | PZ) | DataPNZ[data]; + CC += cc; + + return data; + } + + private void ExecuteInx(int cc) + { + RX = (RX + 1) & 0xFF; + RP = RP & ~(PN | PZ) | DataPNZ[RX]; + CC += cc; + } + + private void ExecuteIny(int cc) + { + RY = (RY + 1) & 0xFF; + RP = RP & ~(PN | PZ) | DataPNZ[RY]; + CC += cc; + } + + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + private void ExecuteIrq(int cc) + { + Push(RPC >> 8); + Push(RPC & 0xFF); + Push(RP & ~PB); + RP |= PI; + if (Machine.Settings.Cpu.Is65C02) // [C-10] + { + RP &= ~PD; + } + RPC = _memory.Read(0xFFFE) | (_memory.Read(0xFFFF) << 8); + CC += cc; + } + + private void ExecuteJmpAbs(int cc) // jmp abs + { + RPC = _memory.Read(RPC) | (_memory.Read(RPC + 1) << 8); + CC += cc; + } + + private void ExecuteJmpAbsInd65N02(int cc) // jmp (abs) + { + int ea = _memory.Read(RPC) | (_memory.Read(RPC + 1) << 8); + RPC = _memory.Read(ea) | (_memory.Read((ea & 0xFF00) | ((ea + 1) & 0x00FF)) << 8); + CC += cc; + } + + private void ExecuteJmpAbsInd65C02(int cc) // jmp (abs) + { + int ea = _memory.Read(RPC) | (_memory.Read(RPC + 1) << 8); + RPC = _memory.Read(ea) | (_memory.Read(ea + 1) << 8); + CC += cc; + } + + private void ExecuteJmpAbsIndX(int cc) // jmp (abs, x) + { + int ea = (_memory.Read(RPC) + RX + (_memory.Read(RPC + 1) << 8)) & 0xFFFF; + RPC = _memory.Read(ea) | (_memory.Read(ea + 1) << 8); + CC += cc; + } + + private void ExecuteJsr(int cc) // jsr abs + { + int rpc = (RPC + 1) & 0xFFFF; + RPC = _memory.Read(RPC) | (_memory.Read(RPC + 1) << 8); + Push(rpc >> 8); + Push(rpc & 0xFF); + CC += cc; + } + + private void ExecuteLda(int data, int cc) + { + RA = data; + RP = RP & ~(PN | PZ) | DataPNZ[RA]; + CC += cc; + } + + private void ExecuteLdx(int data, int cc) + { + RX = data; + RP = RP & ~(PN | PZ) | DataPNZ[RX]; + CC += cc; + } + + private void ExecuteLdy(int data, int cc) + { + RY = data; + RP = RP & ~(PN | PZ) | DataPNZ[RY]; + CC += cc; + } + + private int ExecuteLsr(int data, int cc) + { + RP = RP & ~PC | (data & PC); + data >>= 1; + RP = RP & ~(PN | PZ) | DataPNZ[data]; + CC += cc; + + return data; + } + + private void ExecuteLsrImp(int cc) + { + RP = RP & ~PC | (RA & PC); + RA >>= 1; + RP = RP & ~(PN | PZ) | DataPNZ[RA]; + CC += cc; + } + + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + private void ExecuteNmi(int cc) + { + Push(RPC >> 8); + Push(RPC & 0xFF); + Push(RP & ~PB); + RP |= PI; + if (Machine.Settings.Cpu.Is65C02) // [C-10] + { + RP &= ~PD; + } + RPC = _memory.Read(0xFFFA) | (_memory.Read(0xFFFB) << 8); + CC += cc; + } + + private void ExecuteNop(int cc) + { + CC += cc; + } + + private void ExecuteNop(int data, int cc) + { + RPC = (RPC + data) & 0xFFFF; + CC += cc; + } + + private void ExecuteOra(int data, int cc) + { + RA |= data; + RP = RP & ~(PN | PZ) | DataPNZ[RA]; + CC += cc; + } + + private void ExecutePha(int cc) + { + Push(RA); + CC += cc; + } + + private void ExecutePhp(int cc) + { + Push(RP | PB); // [4-18] + CC += cc; + } + + private void ExecutePhx(int cc) + { + Push(RX); + CC += cc; + } + + private void ExecutePhy(int cc) + { + Push(RY); + CC += cc; + } + + private void ExecutePla(int cc) + { + RA = Pull(); + RP = RP & ~(PN | PZ) | DataPNZ[RA]; + CC += cc; + } + + private void ExecutePlp(int cc) + { + RP = Pull(); + CC += cc; + } + + private void ExecutePlx(int cc) + { + RX = Pull(); + RP = RP & ~(PN | PZ) | DataPNZ[RX]; + CC += cc; + } + + private void ExecutePly(int cc) + { + RY = Pull(); + RP = RP & ~(PN | PZ) | DataPNZ[RY]; + CC += cc; + } + + private int ExecuteRol(int data, int cc) + { + int c = RP & PC; + RP = RP & ~PC | ((data >> 7) & PC); + data = ((data << 1) | c) & 0xFF; + RP = RP & ~(PN | PZ) | DataPNZ[data]; + CC += cc; + + return data; + } + + private void ExecuteRolImp(int cc) + { + int c = RP & PC; + RP = RP & ~PC | ((RA >> 7) & PC); + RA = ((RA << 1) | c) & 0xFF; + RP = RP & ~(PN | PZ) | DataPNZ[RA]; + CC += cc; + } + + private int ExecuteRor(int data, int cc) + { + int c = RP & PC; + RP = RP & ~PC | (data & PC); + data = (c << 7) | (data >> 1); + RP = RP & ~(PN | PZ) | DataPNZ[data]; + CC += cc; + + return data; + } + + private void ExecuteRorImp(int cc) + { + int c = RP & PC; + RP = RP & ~PC | (RA & PC); + RA = (c << 7) | (RA >> 1); + RP = RP & ~(PN | PZ) | DataPNZ[RA]; + CC += cc; + } + + private void ExecuteRti(int cc) + { + RP = Pull(); + int rpc = Pull(); + RPC = rpc | (Pull() << 8); + CC += cc; + } + + private void ExecuteRts(int cc) + { + int rpc = Pull(); + RPC = (rpc + 1 + (Pull() << 8)) & 0xFFFF; + CC += cc; + } + + private void ExecuteSbc65N02(int data, int cc) + { + if ((RP & PD) == 0x0) + { + int ra = RA - data - (~RP & PC); + RP = RP & ~(PC | PN | PV | PZ) | ((~ra >> 8) & PC) | DataPNZ[ra & 0xFF] | ((((RA ^ data) & (RA ^ (ra & 0xFF))) >> 1) & PV); + RA = ra & 0xFF; + CC += cc; + } + else // decimal + { + int ral = (RA & 0x0F) - (data & 0x0F) - (~RP & PC); + int rah = (RA >> 4) - (data >> 4); + if (ral < 0) + { + ral += 10; + rah--; + } + int ra = (ral | (rah << 4)) & 0xFF; + RP = RP & ~(PN | PV | PZ) | PC | DataPN[ra] | ((((RA ^ data) & (RA ^ ra)) >> 1) & PV) | DataPZ[(RA - data - (~RP & PC)) & 0xFF]; + if (rah < 0) + { + rah += 10; + RP &= ~PC; + } + RA = (ral | (rah << 4)) & 0xFF; + CC += cc; + } + } + + private void ExecuteSbc65C02(int data, int cc) + { + if ((RP & PD) == 0x0) + { + int ra = RA - data - (~RP & PC); + RP = RP & ~(PC | PN | PV | PZ) | ((~ra >> 8) & PC) | DataPNZ[ra & 0xFF] | ((((RA ^ data) & (RA ^ (ra & 0xFF))) >> 1) & PV); + RA = ra & 0xFF; + CC += cc; + } + else // decimal + { + int ral = (RA & 0x0F) - (data & 0x0F) - (~RP & PC); + int rah = (RA >> 4) - (data >> 4); + if (ral < 0) + { + ral += 10; + rah--; + } + RP |= PC; + if (rah < 0) + { + rah += 10; + RP &= ~PC; + } + int ra = (ral | (rah << 4)) & 0xFF; + RP = RP & ~(PN | PV | PZ) | DataPNZ[ra] | ((((RA ^ data) & (RA ^ ra)) >> 1) & PV); + RA = ra; + CC += cc + 1; + } + } + + private void ExecuteSec(int cc) + { + RP |= PC; + CC += cc; + } + + private void ExecuteSed(int cc) + { + RP |= PD; + CC += cc; + } + + private void ExecuteSei(int cc) + { + RP |= PI; + CC += cc; + } + + private void ExecuteSta(int cc) + { + CC += cc; + } + + private void ExecuteStx(int cc) + { + CC += cc; + } + + private void ExecuteSty(int cc) + { + CC += cc; + } + + private void ExecuteStz(int cc) + { + CC += cc; + } + + private void ExecuteTax(int cc) + { + RX = RA; + RP = RP & ~(PN | PZ) | DataPNZ[RX]; + CC += cc; + } + + private void ExecuteTay(int cc) + { + RY = RA; + RP = RP & ~(PN | PZ) | DataPNZ[RY]; + CC += cc; + } + + private int ExecuteTrb(int data, int cc) + { + RP = RP & ~PZ | DataPZ[RA & data]; + data &= ~RA; + CC += cc; + + return data; + } + + private int ExecuteTsb(int data, int cc) + { + RP = RP & ~PZ | DataPZ[RA & data]; + data |= RA; + CC += cc; + + return data; + } + + private void ExecuteTsx(int cc) + { + RX = RS; + RP = RP & ~(PN | PZ) | DataPNZ[RX]; + CC += cc; + } + + private void ExecuteTxa(int cc) + { + RA = RX; + RP = RP & ~(PN | PZ) | DataPNZ[RA]; + CC += cc; + } + + private void ExecuteTxs(int cc) + { + RS = RX; + CC += cc; + } + + private void ExecuteTya(int cc) + { + RA = RY; + RP = RP & ~(PN | PZ) | DataPNZ[RA]; + CC += cc; + } + #endregion + + #region 6502 Opcode Actions + private void Execute65X02And21() // and (zpg, x) + { + GetAddressZpgIndX(); + ExecuteAnd(ReadZpgIndX(), 6); + } + + private void Execute65X02And25() // and zpg + { + GetAddressZpg(); + ExecuteAnd(ReadZpg(), 3); + } + + private void Execute65X02And29() // and imm + { + ExecuteAnd(ReadImm(), 2); + } + + private void Execute65X02And2D() // and abs + { + GetAddressAbs(); + ExecuteAnd(ReadAbs(), 4); + } + + private void Execute65X02And31() // and (zpg), y + { + GetAddressZpgIndYCC(); + ExecuteAnd(ReadZpgIndY(), 5); + } + + private void Execute65X02And35() // and zpg, x + { + GetAddressZpgX(); + ExecuteAnd(ReadZpgX(), 4); + } + + private void Execute65X02And39() // and abs, y + { + GetAddressAbsYCC(); + ExecuteAnd(ReadAbsY(), 4); + } + + private void Execute65X02And3D() // and abs, x + { + GetAddressAbsXCC(); + ExecuteAnd(ReadAbsX(), 4); + } + + private void Execute65X02Asl06() // asl zpg + { + GetAddressZpg(); + WriteZpg(ExecuteAsl(ReadZpg(), 5)); + } + + private void Execute65X02Asl0A() // asl imp + { + ExecuteAslImp(2); + } + + private void Execute65X02Asl0E() // asl abs + { + GetAddressAbs(); + WriteAbs(ExecuteAsl(ReadAbs(), 6)); + } + + private void Execute65X02Asl16() // asl zpg, x + { + GetAddressZpgX(); + WriteZpgX(ExecuteAsl(ReadZpgX(), 6)); + } + + private void Execute65X02Bcc90() // bcc rel + { + ExecuteBcc(2); + } + + private void Execute65X02BcsB0() // bcs rel + { + ExecuteBcs(2); + } + + private void Execute65X02BeqF0() // beq rel + { + ExecuteBeq(2); + } + + private void Execute65X02Bit24() // bit zpg + { + GetAddressZpg(); + ExecuteBit(ReadZpg(), 3); + } + + private void Execute65X02Bit2C() // bit abs + { + GetAddressAbs(); + ExecuteBit(ReadAbs(), 4); + } + + private void Execute65X02Bmi30() // bmi rel + { + ExecuteBmi(2); + } + + private void Execute65X02BneD0() // bne rel + { + ExecuteBne(2); + } + + private void Execute65X02Bpl10() // bpl rel + { + ExecuteBpl(2); + } + + private void Execute65X02Brk00() // brk imp + { + ExecuteBrk(7); + } + + private void Execute65X02Bvc50() // bvc rel + { + ExecuteBvc(2); + } + + private void Execute65X02Bvs70() // bvs rel + { + ExecuteBvs(2); + } + + private void Execute65X02Clc18() // clc imp + { + ExecuteClc(2); + } + + private void Execute65X02CldD8() // cld imp + { + ExecuteCld(2); + } + + private void Execute65X02Cli58() // cli imp + { + ExecuteCli(2); + } + + private void Execute65X02ClvB8() // clv imp + { + ExecuteClv(2); + } + + private void Execute65X02CmpC1() // cmp (zpg, x) + { + GetAddressZpgIndX(); + ExecuteCmp(ReadZpgIndX(), 6); + } + + private void Execute65X02CmpC5() // cmp zpg + { + GetAddressZpg(); + ExecuteCmp(ReadZpg(), 3); + } + + private void Execute65X02CmpC9() // cmp imm + { + ExecuteCmp(ReadImm(), 2); + } + + private void Execute65X02CmpCD() // cmp abs + { + GetAddressAbs(); + ExecuteCmp(ReadAbs(), 4); + } + + private void Execute65X02CmpD1() // cmp (zpg), y + { + GetAddressZpgIndYCC(); + ExecuteCmp(ReadZpgIndY(), 5); + } + + private void Execute65X02CmpD5() // cmp zpg, x + { + GetAddressZpgX(); + ExecuteCmp(ReadZpgX(), 4); + } + + private void Execute65X02CmpD9() // cmp abs, y + { + GetAddressAbsYCC(); + ExecuteCmp(ReadAbsY(), 4); + } + + private void Execute65X02CmpDD() // cmp abs, x + { + GetAddressAbsXCC(); + ExecuteCmp(ReadAbsX(), 4); + } + + private void Execute65X02CpxE0() // cpx imm + { + ExecuteCpx(ReadImm(), 2); + } + + private void Execute65X02CpxE4() // cpx zpg + { + GetAddressZpg(); + ExecuteCpx(ReadZpg(), 3); + } + + private void Execute65X02CpxEC() // cpx abs + { + GetAddressAbs(); + ExecuteCpx(ReadAbs(), 4); + } + + private void Execute65X02CpyC0() // cpy imm + { + ExecuteCpy(ReadImm(), 2); + } + + private void Execute65X02CpyC4() // cpy zpg + { + GetAddressZpg(); + ExecuteCpy(ReadZpg(), 3); + } + + private void Execute65X02CpyCC() // cpy abs + { + GetAddressAbs(); + ExecuteCpy(ReadAbs(), 4); + } + + private void Execute65X02DecC6() // dec zpg + { + GetAddressZpg(); + WriteZpg(ExecuteDec(ReadZpg(), 5)); + } + + private void Execute65X02DecCE() // dec abs + { + GetAddressAbs(); + WriteAbs(ExecuteDec(ReadAbs(), 6)); + } + + private void Execute65X02DecD6() // dec zpg, x + { + GetAddressZpgX(); + WriteZpgX(ExecuteDec(ReadZpgX(), 6)); + } + + private void Execute65X02DexCA() // dex imp + { + ExecuteDex(2); + } + + private void Execute65X02Dey88() // dey imp + { + ExecuteDey(2); + } + + private void Execute65X02Eor41() // eor (zpg, x) + { + GetAddressZpgIndX(); + ExecuteEor(ReadZpgIndX(), 6); + } + + private void Execute65X02Eor45() // eor zpg + { + GetAddressZpg(); + ExecuteEor(ReadZpg(), 3); + } + + private void Execute65X02Eor49() // eor imm + { + ExecuteEor(ReadImm(), 2); + } + + private void Execute65X02Eor4D() // eor abs + { + GetAddressAbs(); + ExecuteEor(ReadAbs(), 4); + } + + private void Execute65X02Eor51() // eor (zpg), y + { + GetAddressZpgIndYCC(); + ExecuteEor(ReadZpgIndY(), 5); + } + + private void Execute65X02Eor55() // eor zpg, x + { + GetAddressZpgX(); + ExecuteEor(ReadZpgX(), 4); + } + + private void Execute65X02Eor59() // eor abs, y + { + GetAddressAbsYCC(); + ExecuteEor(ReadAbsY(), 4); + } + + private void Execute65X02Eor5D() // eor abs, x + { + GetAddressAbsXCC(); + ExecuteEor(ReadAbsX(), 4); + } + + private void Execute65X02IncE6() // inc zpg + { + GetAddressZpg(); + WriteZpg(ExecuteInc(ReadZpg(), 5)); + } + + private void Execute65X02IncEE() // inc abs + { + GetAddressAbs(); + WriteAbs(ExecuteInc(ReadAbs(), 6)); + } + + private void Execute65X02IncF6() // inc zpg, x + { + GetAddressZpgX(); + WriteZpgX(ExecuteInc(ReadZpgX(), 6)); + } + + private void Execute65X02InxE8() // inx imp + { + ExecuteInx(2); + } + + private void Execute65X02InyC8() // iny imp + { + ExecuteIny(2); + } + + private void Execute65X02Jmp4C() // jmp abs + { + ExecuteJmpAbs(3); + } + + private void Execute65X02Jsr20() // jsr abs + { + ExecuteJsr(6); + } + + private void Execute65X02LdaA1() // lda (zpg, x) + { + GetAddressZpgIndX(); + ExecuteLda(ReadZpgIndX(), 6); + } + + private void Execute65X02LdaA5() // lda zpg + { + GetAddressZpg(); + ExecuteLda(ReadZpg(), 3); + } + + private void Execute65X02LdaA9() // lda imm + { + ExecuteLda(ReadImm(), 2); + } + + private void Execute65X02LdaAD() // lda abs + { + GetAddressAbs(); + ExecuteLda(ReadAbs(), 4); + } + + private void Execute65X02LdaB1() // lda (zpg), y + { + GetAddressZpgIndYCC(); + ExecuteLda(ReadZpgIndY(), 5); + } + + private void Execute65X02LdaB5() // lda zpg, x + { + GetAddressZpgX(); + ExecuteLda(ReadZpgX(), 4); + } + + private void Execute65X02LdaB9() // lda abs, y + { + GetAddressAbsYCC(); + ExecuteLda(ReadAbsY(), 4); + } + + private void Execute65X02LdaBD() // lda abs, x + { + GetAddressAbsXCC(); + ExecuteLda(ReadAbsX(), 4); + } + + private void Execute65X02LdxA2() // ldx imm + { + ExecuteLdx(ReadImm(), 2); + } + + private void Execute65X02LdxA6() // ldx zpg + { + GetAddressZpg(); + ExecuteLdx(ReadZpg(), 3); + } + + private void Execute65X02LdxAE() // ldx abs + { + GetAddressAbs(); + ExecuteLdx(ReadAbs(), 4); + } + + private void Execute65X02LdxB6() // ldx zpg, y + { + GetAddressZpgY(); + ExecuteLdx(ReadZpgY(), 4); + } + + private void Execute65X02LdxBE() // ldx abs, y + { + GetAddressAbsYCC(); + ExecuteLdx(ReadAbsY(), 4); + } + + private void Execute65X02LdyA0() // ldy imm + { + ExecuteLdy(ReadImm(), 2); + } + + private void Execute65X02LdyA4() // ldy zpg + { + GetAddressZpg(); + ExecuteLdy(ReadZpg(), 3); + } + + private void Execute65X02LdyAC() // ldy abs + { + GetAddressAbs(); + ExecuteLdy(ReadAbs(), 4); + } + + private void Execute65X02LdyB4() // ldy zpg, x + { + GetAddressZpgX(); + ExecuteLdy(ReadZpgX(), 4); + } + + private void Execute65X02LdyBC() // ldy abs, x + { + GetAddressAbsXCC(); + ExecuteLdy(ReadAbsX(), 4); + } + + private void Execute65X02Lsr46() // lsr zpg + { + GetAddressZpg(); + WriteZpg(ExecuteLsr(ReadZpg(), 5)); + } + + private void Execute65X02Lsr4A() // lsr imp + { + ExecuteLsrImp(2); + } + + private void Execute65X02Lsr4E() // lsr abs + { + GetAddressAbs(); + WriteAbs(ExecuteLsr(ReadAbs(), 6)); + } + + private void Execute65X02Lsr56() // lsr zpg, x + { + GetAddressZpgX(); + WriteZpgX(ExecuteLsr(ReadZpgX(), 6)); + } + + private void Execute65X02NopEA() // nop imp + { + ExecuteNop(2); + } + + private void Execute65X02Ora01() // ora (zpg, x) + { + GetAddressZpgIndX(); + ExecuteOra(ReadZpgIndX(), 6); + } + + private void Execute65X02Ora05() // ora zpg + { + GetAddressZpg(); + ExecuteOra(ReadZpg(), 3); + } + + private void Execute65X02Ora09() // ora imm + { + ExecuteOra(ReadImm(), 2); + } + + private void Execute65X02Ora0D() // ora abs + { + GetAddressAbs(); + ExecuteOra(ReadAbs(), 4); + } + + private void Execute65X02Ora11() // ora (zpg), y + { + GetAddressZpgIndYCC(); + ExecuteOra(ReadZpgIndY(), 5); + } + + private void Execute65X02Ora15() // ora zpg, x + { + GetAddressZpgX(); + ExecuteOra(ReadZpgX(), 4); + } + + private void Execute65X02Ora19() // ora abs, y + { + GetAddressAbsYCC(); + ExecuteOra(ReadAbsY(), 4); + } + + private void Execute65X02Ora1D() // ora abs, x + { + GetAddressAbsXCC(); + ExecuteOra(ReadAbsX(), 4); + } + + private void Execute65X02Pha48() // pha imp + { + ExecutePha(3); + } + + private void Execute65X02Php08() // php imp + { + ExecutePhp(3); + } + + private void Execute65X02Pla68() // pla imp + { + ExecutePla(4); + } + + private void Execute65X02Plp28() // plp imp + { + ExecutePlp(4); + } + + private void Execute65X02Rol26() // rol zpg + { + GetAddressZpg(); + WriteZpg(ExecuteRol(ReadZpg(), 5)); + } + + private void Execute65X02Rol2A() // rol imp + { + ExecuteRolImp(2); + } + + private void Execute65X02Rol2E() // rol abs + { + GetAddressAbs(); + WriteAbs(ExecuteRol(ReadAbs(), 6)); + } + + private void Execute65X02Rol36() // rol zpg, x + { + GetAddressZpgX(); + WriteZpgX(ExecuteRol(ReadZpgX(), 6)); + } + + private void Execute65X02Ror66() // ror zpg + { + GetAddressZpg(); + WriteZpg(ExecuteRor(ReadZpg(), 5)); + } + + private void Execute65X02Ror6A() // ror imp + { + ExecuteRorImp(2); + } + + private void Execute65X02Ror6E() // ror abs + { + GetAddressAbs(); + WriteAbs(ExecuteRor(ReadAbs(), 6)); + } + + private void Execute65X02Ror76() // ror zpg, x + { + GetAddressZpgX(); + WriteZpgX(ExecuteRor(ReadZpgX(), 6)); + } + + private void Execute65X02Rti40() // rti imp + { + ExecuteRti(6); + } + + private void Execute65X02Rts60() // rts imp + { + ExecuteRts(6); + } + + private void Execute65X02Sec38() // sec imp + { + ExecuteSec(2); + } + + private void Execute65X02SedF8() // sed imp + { + ExecuteSed(2); + } + + private void Execute65X02Sei78() // sei imp + { + ExecuteSei(2); + } + + private void Execute65X02Sta81() // sta (zpg, x) + { + GetAddressZpgIndX(); + WriteZpgIndX(RA); + ExecuteSta(6); + } + + private void Execute65X02Sta85() // sta zpg + { + GetAddressZpg(); + WriteZpg(RA); + ExecuteSta(3); + } + + private void Execute65X02Sta8D() // sta abs + { + GetAddressAbs(); + WriteAbs(RA); + ExecuteSta(4); + } + + private void Execute65X02Sta91() // sta (zpg), y + { + GetAddressZpgIndY(); + WriteZpgIndY(RA); + ExecuteSta(6); + } + + private void Execute65X02Sta95() // sta zpg, x + { + GetAddressZpgX(); + WriteZpgX(RA); + ExecuteSta(4); + } + + private void Execute65X02Sta99() // sta abs, y + { + GetAddressAbsY(); + WriteAbsY(RA); + ExecuteSta(5); + } + + private void Execute65X02Sta9D() // sta abs, x + { + GetAddressAbsX(); + WriteAbsX(RA); + ExecuteSta(5); + } + + private void Execute65X02Stx86() // stx zpg + { + GetAddressZpg(); + WriteZpg(RX); + ExecuteStx(3); + } + + private void Execute65X02Stx8E() // stx abs + { + GetAddressAbs(); + WriteAbs(RX); + ExecuteStx(4); + } + + private void Execute65X02Stx96() // stx zpg, y + { + GetAddressZpgY(); + WriteZpgY(RX); + ExecuteStx(4); + } + + private void Execute65X02Sty84() // sty zpg + { + GetAddressZpg(); + WriteZpg(RY); + ExecuteSty(3); + } + + private void Execute65X02Sty8C() // sty abs + { + GetAddressAbs(); + WriteAbs(RY); + ExecuteSty(4); + } + + private void Execute65X02Sty94() // sty zpg, x + { + GetAddressZpgX(); + WriteZpgX(RY); + ExecuteSty(4); + } + + private void Execute65X02TaxAA() // tax imp + { + ExecuteTax(2); + } + + private void Execute65X02TayA8() // tay imp + { + ExecuteTay(2); + } + + private void Execute65X02TsxBA() // tsx imp + { + ExecuteTsx(2); + } + + private void Execute65X02Txa8A() // txa imp + { + ExecuteTxa(2); + } + + private void Execute65X02Txs9A() // txs imp + { + ExecuteTxs(2); + } + + private void Execute65X02Tya98() // tya imp + { + ExecuteTya(2); + } + #endregion + + #region 65N02 Opcode Actions + private void Execute65N02Adc61() // adc (zpg, x) + { + GetAddressZpgIndX(); + ExecuteAdc65N02(ReadZpgIndX(), 6); + } + + private void Execute65N02Adc65() // adc zpg + { + GetAddressZpg(); + ExecuteAdc65N02(ReadZpg(), 3); + } + + private void Execute65N02Adc69() // adc imm + { + ExecuteAdc65N02(ReadImm(), 2); + } + + private void Execute65N02Adc6D() // adc abs + { + GetAddressAbs(); + ExecuteAdc65N02(ReadAbs(), 4); + } + + private void Execute65N02Adc71() // adc (zpg), y + { + GetAddressZpgIndYCC(); + ExecuteAdc65N02(ReadZpgIndY(), 5); + } + + private void Execute65N02Adc75() // adc zpg, x + { + GetAddressZpgX(); + ExecuteAdc65N02(ReadZpgX(), 4); + } + + private void Execute65N02Adc79() // adc abs, y + { + GetAddressAbsYCC(); + ExecuteAdc65N02(ReadAbsY(), 4); + } + + private void Execute65N02Adc7D() // adc abs, x + { + GetAddressAbsXCC(); + ExecuteAdc65N02(ReadAbsX(), 4); + } + + private void Execute65N02Asl1E() // asl abs, x + { + GetAddressAbsX(); + WriteAbsX(ExecuteAsl(ReadAbsX(), 7)); + } + + private void Execute65N02DecDE() // dec abs, x + { + GetAddressAbsX(); + WriteAbsX(ExecuteDec(ReadAbsX(), 7)); + } + + private void Execute65N02IncFE() // inc abs, x + { + GetAddressAbsX(); + WriteAbsX(ExecuteInc(ReadAbsX(), 7)); + } + + private void Execute65N02Jmp6C() // jmp (abs) + { + ExecuteJmpAbsInd65N02(5); + } + + private void Execute65N02Lsr5E() // lsr abs, x + { + GetAddressAbsX(); + WriteAbsX(ExecuteLsr(ReadAbsX(), 7)); + } + + private void Execute65N02Nop02() // nop imp0 + { + ExecuteNop(0, 2); + } + + private void Execute65N02Nop03() // nop imp1 + { + ExecuteNop(1, 6); + } + + private void Execute65N02Nop04() // nop imp1 + { + ExecuteNop(1, 2); + } + + private void Execute65N02Nop07() // nop imp1 + { + ExecuteNop(1, 5); + } + + private void Execute65N02Nop0B() // nop imp1 + { + ExecuteNop(1, 2); + } + + private void Execute65N02Nop0C() // nop imp2 + { + ExecuteNop(2, 4); + } + + private void Execute65N02Nop0F() // nop imp2 + { + ExecuteNop(2, 6); + } + + private void Execute65N02Nop12() // nop imp0 + { + ExecuteNop(0, 2); + } + + private void Execute65N02Nop13() // nop imp1 + { + ExecuteNop(1, 6); + } + + private void Execute65N02Nop14() // nop imp1 + { + ExecuteNop(1, 2); + } + + private void Execute65N02Nop17() // nop imp1 + { + ExecuteNop(1, 6); + } + + private void Execute65N02Nop1A() // nop imp0 + { + ExecuteNop(0, 2); + } + + private void Execute65N02Nop1B() // nop imp2 + { + ExecuteNop(2, 6); + } + + private void Execute65N02Nop1C() // nop imp2 + { + ExecuteNop(2, 4); + } + + private void Execute65N02Nop1F() // nop imp2 + { + ExecuteNop(2, 6); + } + + private void Execute65N02Nop22() // nop imp0 + { + ExecuteNop(0, 2); + } + + private void Execute65N02Nop23() // nop imp1 + { + ExecuteNop(1, 6); + } + + private void Execute65N02Nop27() // nop imp1 + { + ExecuteNop(1, 3); + } + + private void Execute65N02Nop2B() // nop imp1 + { + ExecuteNop(1, 2); + } + + private void Execute65N02Nop2F() // nop imp2 + { + ExecuteNop(2, 4); + } + + private void Execute65N02Nop32() // nop imp0 + { + ExecuteNop(0, 2); + } + + private void Execute65N02Nop33() // nop imp1 + { + ExecuteNop(1, 5); + } + + private void Execute65N02Nop34() // nop imp1 + { + ExecuteNop(1, 2); + } + + private void Execute65N02Nop37() // nop imp1 + { + ExecuteNop(1, 4); + } + + private void Execute65N02Nop3A() // nop imp0 + { + ExecuteNop(0, 2); + } + + private void Execute65N02Nop3B() // nop imp2 + { + ExecuteNop(2, 4); + } + + private void Execute65N02Nop3C() // nop imp2 + { + ExecuteNop(2, 4); + } + + private void Execute65N02Nop3F() // nop imp2 + { + ExecuteNop(2, 4); + } + + private void Execute65N02Nop42() // nop imp0 + { + ExecuteNop(0, 2); + } + + private void Execute65N02Nop43() // nop imp1 + { + ExecuteNop(1, 6); + } + + private void Execute65N02Nop44() // nop imp1 + { + ExecuteNop(1, 2); + } + + private void Execute65N02Nop47() // nop imp1 + { + ExecuteNop(1, 3); + } + + private void Execute65N02Nop4B() // nop imp1 + { + ExecuteNop(1, 2); + } + + private void Execute65N02Nop4F() // nop imp2 + { + ExecuteNop(2, 4); + } + + private void Execute65N02Nop52() // nop imp0 + { + ExecuteNop(0, 2); + } + + private void Execute65N02Nop53() // nop imp1 + { + ExecuteNop(1, 5); + } + + private void Execute65N02Nop54() // nop imp1 + { + ExecuteNop(1, 2); + } + + private void Execute65N02Nop57() // nop imp1 + { + ExecuteNop(1, 4); + } + + private void Execute65N02Nop5A() // nop imp0 + { + ExecuteNop(0, 2); + } + + private void Execute65N02Nop5B() // nop imp2 + { + ExecuteNop(2, 4); + } + + private void Execute65N02Nop5C() // nop imp2 + { + ExecuteNop(2, 4); + } + + private void Execute65N02Nop5F() // nop imp2 + { + ExecuteNop(2, 4); + } + + private void Execute65N02Nop62() // nop imp0 + { + ExecuteNop(0, 2); + } + + private void Execute65N02Nop63() // nop imp1 + { + ExecuteNop(1, 6); + } + + private void Execute65N02Nop64() // nop imp1 + { + ExecuteNop(1, 2); + } + + private void Execute65N02Nop67() // nop imp1 + { + ExecuteNop(1, 3); + } + + private void Execute65N02Nop6B() // nop imp1 + { + ExecuteNop(1, 2); + } + + private void Execute65N02Nop6F() // nop imp2 + { + ExecuteNop(2, 4); + } + + private void Execute65N02Nop72() // nop imp0 + { + ExecuteNop(0, 2); + } + + private void Execute65N02Nop73() // nop imp1 + { + ExecuteNop(1, 5); + } + + private void Execute65N02Nop74() // nop imp1 + { + ExecuteNop(1, 2); + } + + private void Execute65N02Nop77() // nop imp1 + { + ExecuteNop(1, 4); + } + + private void Execute65N02Nop7A() // nop imp0 + { + ExecuteNop(0, 2); + } + + private void Execute65N02Nop7B() // nop imp2 + { + ExecuteNop(2, 4); + } + + private void Execute65N02Nop7C() // nop imp2 + { + ExecuteNop(2, 4); + } + + private void Execute65N02Nop7F() // nop imp2 + { + ExecuteNop(2, 4); + } + + private void Execute65N02Nop80() // nop imp1 + { + ExecuteNop(1, 2); + } + + private void Execute65N02Nop82() // nop imp1 + { + ExecuteNop(1, 2); + } + + private void Execute65N02Nop83() // nop imp1 + { + ExecuteNop(1, 4); + } + + private void Execute65N02Nop87() // nop imp1 + { + ExecuteNop(1, 3); + } + + private void Execute65N02Nop89() // nop imp1 + { + ExecuteNop(1, 2); + } + + private void Execute65N02Nop8B() // nop imp1 + { + ExecuteNop(1, 2); + } + + private void Execute65N02Nop8F() // nop imp2 + { + ExecuteNop(2, 4); + } + + private void Execute65N02Nop92() // nop imp0 + { + ExecuteNop(0, 2); + } + + private void Execute65N02Nop93() // nop imp1 + { + ExecuteNop(1, 6); + } + + private void Execute65N02Nop97() // nop imp1 + { + ExecuteNop(1, 4); + } + + private void Execute65N02Nop9B() // nop imp2 + { + ExecuteNop(2, 5); + } + + private void Execute65N02Nop9C() // nop imp2 + { + ExecuteNop(2, 5); + } + + private void Execute65N02Nop9E() // nop imp2 + { + ExecuteNop(2, 5); + } + + private void Execute65N02Nop9F() // nop imp2 + { + ExecuteNop(2, 5); + } + + private void Execute65N02NopA3() // nop imp1 + { + ExecuteNop(1, 6); + } + + private void Execute65N02NopA7() // nop imp1 + { + ExecuteNop(1, 3); + } + + private void Execute65N02NopAB() // nop imp1 + { + ExecuteNop(1, 2); + } + + private void Execute65N02NopAF() // nop imp2 + { + ExecuteNop(2, 4); + } + + private void Execute65N02NopB2() // nop imp0 + { + ExecuteNop(0, 2); + } + + private void Execute65N02NopB3() // nop imp1 + { + ExecuteNop(1, 5); + } + + private void Execute65N02NopB7() // nop imp1 + { + ExecuteNop(1, 4); + } + + private void Execute65N02NopBB() // nop imp2 + { + ExecuteNop(2, 4); + } + + private void Execute65N02NopBF() // nop imp2 + { + ExecuteNop(2, 4); + } + + private void Execute65N02NopC2() // nop imp1 + { + ExecuteNop(1, 2); + } + + private void Execute65N02NopC3() // nop imp1 + { + ExecuteNop(1, 6); + } + + private void Execute65N02NopC7() // nop imp1 + { + ExecuteNop(1, 5); + } + + private void Execute65N02NopCB() // nop imp1 + { + ExecuteNop(1, 2); + } + + private void Execute65N02NopCF() // nop imp2 + { + ExecuteNop(2, 6); + } + + private void Execute65N02NopD2() // nop imp0 + { + ExecuteNop(0, 2); + } + + private void Execute65N02NopD3() // nop imp1 + { + ExecuteNop(1, 6); + } + + private void Execute65N02NopD4() // nop imp1 + { + ExecuteNop(1, 2); + } + + private void Execute65N02NopD7() // nop imp1 + { + ExecuteNop(1, 6); + } + + private void Execute65N02NopDA() // nop imp0 + { + ExecuteNop(0, 2); + } + + private void Execute65N02NopDB() // nop imp2 + { + ExecuteNop(2, 6); + } + + private void Execute65N02NopDC() // nop imp2 + { + ExecuteNop(2, 4); + } + + private void Execute65N02NopDF() // nop imp2 + { + ExecuteNop(2, 6); + } + + private void Execute65N02NopE2() // nop imp1 + { + ExecuteNop(1, 2); + } + + private void Execute65N02NopE3() // nop imp1 + { + ExecuteNop(1, 6); + } + + private void Execute65N02NopE7() // nop imp1 + { + ExecuteNop(1, 5); + } + + private void Execute65N02NopEB() // nop imp1 + { + ExecuteNop(1, 2); + } + + private void Execute65N02NopEF() // nop imp2 + { + ExecuteNop(2, 6); + } + + private void Execute65N02NopF2() // nop imp0 + { + ExecuteNop(0, 2); + } + + private void Execute65N02NopF3() // nop imp1 + { + ExecuteNop(1, 6); + } + + private void Execute65N02NopF4() // nop imp1 + { + ExecuteNop(1, 2); + } + + private void Execute65N02NopF7() // nop imp1 + { + ExecuteNop(1, 6); + } + + private void Execute65N02NopFA() // nop imp0 + { + ExecuteNop(0, 2); + } + + private void Execute65N02NopFB() // nop imp2 + { + ExecuteNop(2, 6); + } + + private void Execute65N02NopFC() // nop imp2 + { + ExecuteNop(2, 4); + } + + private void Execute65N02NopFF() // nop imp2 + { + ExecuteNop(2, 6); + } + + private void Execute65N02Rol3E() // rol abs, x + { + GetAddressAbsX(); + WriteAbsX(ExecuteRol(ReadAbsX(), 7)); + } + + private void Execute65N02Ror7E() // ror abs, x + { + GetAddressAbsX(); + WriteAbsX(ExecuteRor(ReadAbsX(), 7)); + } + + private void Execute65N02SbcE1() // sbc (zpg, x) + { + GetAddressZpgIndX(); + ExecuteSbc65N02(ReadZpgIndX(), 6); + } + + private void Execute65N02SbcE5() // sbc zpg + { + GetAddressZpg(); + ExecuteSbc65N02(ReadZpg(), 3); + } + + private void Execute65N02SbcE9() // sbc imm + { + ExecuteSbc65N02(ReadImm(), 2); + } + + private void Execute65N02SbcED() // sbc abs + { + GetAddressAbs(); + ExecuteSbc65N02(ReadAbs(), 4); + } + + private void Execute65N02SbcF1() // sbc (zpg), y + { + GetAddressZpgIndYCC(); + ExecuteSbc65N02(ReadZpgIndY(), 5); + } + + private void Execute65N02SbcF5() // sbc zpg, x + { + GetAddressZpgX(); + ExecuteSbc65N02(ReadZpgX(), 4); + } + + private void Execute65N02SbcF9() // sbc abs, y + { + GetAddressAbsYCC(); + ExecuteSbc65N02(ReadAbsY(), 4); + } + + private void Execute65N02SbcFD() // sbc abs, x + { + GetAddressAbsXCC(); + ExecuteSbc65N02(ReadAbsX(), 4); + } + #endregion + + #region 65C02 Opcode Actions + private void Execute65C02Adc61() // adc (zpg, x) + { + GetAddressZpgIndX(); + ExecuteAdc65C02(ReadZpgIndX(), 6); + } + + private void Execute65C02Adc65() // adc zpg + { + GetAddressZpg(); + ExecuteAdc65C02(ReadZpg(), 3); + } + + private void Execute65C02Adc69() // adc imm + { + ExecuteAdc65C02(ReadImm(), 2); + } + + private void Execute65C02Adc6D() // adc abs + { + GetAddressAbs(); + ExecuteAdc65C02(ReadAbs(), 4); + } + + private void Execute65C02Adc71() // adc (zpg), y + { + GetAddressZpgIndYCC(); + ExecuteAdc65C02(ReadZpgIndY(), 5); + } + + private void Execute65C02Adc72() // adc (zpg) + { + GetAddressZpgInd(); + ExecuteAdc65C02(ReadZpgInd(), 5); + } + + private void Execute65C02Adc75() // adc zpg, x + { + GetAddressZpgX(); + ExecuteAdc65C02(ReadZpgX(), 4); + } + + private void Execute65C02Adc79() // adc abs, y + { + GetAddressAbsYCC(); + ExecuteAdc65C02(ReadAbsY(), 4); + } + + private void Execute65C02Adc7D() // adc abs, x + { + GetAddressAbsXCC(); + ExecuteAdc65C02(ReadAbsX(), 4); + } + + private void Execute65C02And32() // and (zpg) + { + GetAddressZpgInd(); + ExecuteAnd(ReadZpgInd(), 5); + } + + private void Execute65C02Asl1E() // asl abs, x + { + GetAddressAbsXCC(); + WriteAbsX(ExecuteAsl(ReadAbsX(), 6)); + } + + private void Execute65C02Bit34() // bit zpg, x + { + GetAddressZpgX(); + ExecuteBit(ReadZpgX(), 4); + } + + private void Execute65C02Bit3C() // bit abs, x + { + GetAddressAbsXCC(); + ExecuteBit(ReadAbsX(), 4); + } + + private void Execute65C02Bit89() // bit imm + { + ExecuteBitImm(ReadImm(), 2); + } + + private void Execute65C02Bra80() // bra rel + { + ExecuteBra(2); + } + + private void Execute65C02CmpD2() // cmp (zpg) + { + GetAddressZpgInd(); + ExecuteCmp(ReadZpgInd(), 5); + } + + private void Execute65C02Dea3A() // dea imp + { + ExecuteDea(2); + } + + private void Execute65C02DecDE() // dec abs, x + { + GetAddressAbsXCC(); + WriteAbsX(ExecuteDec(ReadAbsX(), 6)); + } + + private void Execute65C02Eor52() // eor (zpg) + { + GetAddressZpgInd(); + ExecuteEor(ReadZpgInd(), 5); + } + + private void Execute65C02Ina1A() // ina imp + { + ExecuteIna(2); + } + + private void Execute65C02IncFE() // inc abs, x + { + GetAddressAbsXCC(); + WriteAbsX(ExecuteInc(ReadAbsX(), 6)); + } + + private void Execute65C02Jmp6C() // jmp (abs) + { + ExecuteJmpAbsInd65C02(6); + } + + private void Execute65C02Jmp7C() // jmp (abs, x) + { + ExecuteJmpAbsIndX(6); + } + + private void Execute65C02LdaB2() // lda (zpg) + { + GetAddressZpgInd(); + ExecuteLda(ReadZpgInd(), 5); + } + + private void Execute65C02Lsr5E() // lsr abs, x + { + GetAddressAbsXCC(); + WriteAbsX(ExecuteLsr(ReadAbsX(), 6)); + } + + private void Execute65C02Nop02() // nop imp1 + { + ExecuteNop(1, 2); + } + + private void Execute65C02Nop03() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop07() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop0B() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop0F() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop13() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop17() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop1B() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop1F() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop22() // nop imp1 + { + ExecuteNop(1, 2); + } + + private void Execute65C02Nop23() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop27() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop2B() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop2F() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop33() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop37() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop3B() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop3F() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop42() // nop imp1 + { + ExecuteNop(1, 2); + } + + private void Execute65C02Nop43() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop44() // nop imp1 + { + ExecuteNop(1, 3); + } + + private void Execute65C02Nop47() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop4B() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop4F() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop53() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop54() // nop imp1 + { + ExecuteNop(1, 4); + } + + private void Execute65C02Nop57() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop5B() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop5C() // nop imp2 + { + ExecuteNop(2, 8); + } + + private void Execute65C02Nop5F() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop62() // nop imp1 + { + ExecuteNop(1, 2); + } + + private void Execute65C02Nop63() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop67() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop6B() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop6F() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop73() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop77() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop7B() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop7F() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop82() // nop imp1 + { + ExecuteNop(1, 2); + } + + private void Execute65C02Nop83() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop87() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop8B() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop8F() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop93() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop97() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop9B() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Nop9F() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02NopA3() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02NopA7() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02NopAB() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02NopAF() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02NopB3() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02NopB7() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02NopBB() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02NopBF() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02NopC2() // nop imp1 + { + ExecuteNop(1, 2); + } + + private void Execute65C02NopC3() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02NopC7() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02NopCB() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02NopCF() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02NopD3() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02NopD4() // nop imp1 + { + ExecuteNop(1, 4); + } + + private void Execute65C02NopD7() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02NopDB() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02NopDC() // nop imp2 + { + ExecuteNop(2, 4); + } + + private void Execute65C02NopDF() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02NopE2() // nop imp1 + { + ExecuteNop(1, 2); + } + + private void Execute65C02NopE3() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02NopE7() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02NopEB() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02NopEF() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02NopF3() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02NopF4() // nop imp1 + { + ExecuteNop(1, 4); + } + + private void Execute65C02NopF7() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02NopFB() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02NopFC() // nop imp2 + { + ExecuteNop(2, 4); + } + + private void Execute65C02NopFF() // nop imp0 + { + ExecuteNop(0, 1); + } + + private void Execute65C02Ora12() // ora (zpg) + { + GetAddressZpgInd(); + ExecuteOra(ReadZpgInd(), 5); + } + + private void Execute65C02PhxDA() // phx imp + { + ExecutePhx(3); + } + + private void Execute65C02Phy5A() // phy imp + { + ExecutePhy(3); + } + + private void Execute65C02PlxFA() // plx imp + { + ExecutePlx(4); + } + + private void Execute65C02Ply7A() // ply imp + { + ExecutePly(4); + } + + private void Execute65C02Rol3E() // rol abs, x + { + GetAddressAbsXCC(); + WriteAbsX(ExecuteRol(ReadAbsX(), 6)); + } + + private void Execute65C02Ror7E() // ror abs, x + { + GetAddressAbsXCC(); + WriteAbsX(ExecuteRor(ReadAbsX(), 6)); + } + + private void Execute65C02SbcE1() // sbc (zpg, x) + { + GetAddressZpgIndX(); + ExecuteSbc65C02(ReadZpgIndX(), 6); + } + + private void Execute65C02SbcE5() // sbc zpg + { + GetAddressZpg(); + ExecuteSbc65C02(ReadZpg(), 3); + } + + private void Execute65C02SbcE9() // sbc imm + { + ExecuteSbc65C02(ReadImm(), 2); + } + + private void Execute65C02SbcED() // sbc abs + { + GetAddressAbs(); + ExecuteSbc65C02(ReadAbs(), 4); + } + + private void Execute65C02SbcF1() // sbc (zpg), y + { + GetAddressZpgIndYCC(); + ExecuteSbc65C02(ReadZpgIndY(), 5); + } + + private void Execute65C02SbcF2() // sbc (zpg) + { + GetAddressZpgInd(); + ExecuteSbc65C02(ReadZpgInd(), 5); + } + + private void Execute65C02SbcF5() // sbc zpg, x + { + GetAddressZpgX(); + ExecuteSbc65C02(ReadZpgX(), 4); + } + + private void Execute65C02SbcF9() // sbc abs, y + { + GetAddressAbsYCC(); + ExecuteSbc65C02(ReadAbsY(), 4); + } + + private void Execute65C02SbcFD() // sbc abs, x + { + GetAddressAbsXCC(); + ExecuteSbc65C02(ReadAbsX(), 4); + } + + private void Execute65C02Sta92() // sta (zpg) + { + GetAddressZpgInd(); + WriteZpgInd(RA); + ExecuteSta(5); + } + + private void Execute65C02Stz64() // stz zpg + { + GetAddressZpg(); + WriteZpg(0x00); + ExecuteStz(3); + } + + private void Execute65C02Stz74() // stz zpg, x + { + GetAddressZpgX(); + WriteZpgX(0x00); + ExecuteStz(4); + } + + private void Execute65C02Stz9C() // stz abs + { + GetAddressAbs(); + WriteAbs(0x00); + ExecuteStz(4); + } + + private void Execute65C02Stz9E() // stz abs, x + { + GetAddressAbsX(); + WriteAbsX(0x00); + ExecuteStz(5); + } + + private void Execute65C02Trb14() // trb zpg + { + GetAddressZpg(); + WriteZpg(ExecuteTrb(ReadZpg(), 5)); + } + + private void Execute65C02Trb1C() // trb abs + { + GetAddressAbs(); + WriteAbs(ExecuteTrb(ReadAbs(), 6)); + } + + private void Execute65C02Tsb04() // tsb zpg + { + GetAddressZpg(); + WriteZpg(ExecuteTsb(ReadZpg(), 5)); + } + + private void Execute65C02Tsb0C() // tsb abs + { + GetAddressAbs(); + WriteAbs(ExecuteTsb(ReadAbs(), 6)); + } + #endregion + + private void OnVideoVSync(object sender, EventArgs e) + { + UpdateSettings(); + } + + private void UpdateSettings() + { + _executeOpcode = Machine.Settings.Cpu.Is65C02 ? ExecuteOpcode65C02 : ExecuteOpcode65N02; + } + + public int RA { get; private set; } + public int RX { get; private set; } + public int RY { get; private set; } + public int RS { get; private set; } + public int RP { get; private set; } + public int RPC { get; private 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; } + + private Memory _memory; + + private Action[] _executeOpcode; + } +} diff --git a/Virtu/CpuData.cs b/Virtu/CpuData.cs index ff3d2d5..14ab1b5 100644 --- a/Virtu/CpuData.cs +++ b/Virtu/CpuData.cs @@ -1,83 +1,83 @@ -using System; - -namespace Jellyfish.Virtu -{ - public partial class Cpu - { - private const int OpcodeCount = 256; - - private readonly Action[] ExecuteOpcode65N02; - private readonly Action[] ExecuteOpcode65C02; - - private const int PC = 0x01; - private const int PZ = 0x02; - private const int PI = 0x04; - private const int PD = 0x08; - private const int PB = 0x10; - private const int PR = 0x20; - private const int PV = 0x40; - private const int PN = 0x80; - - private const int DataCount = 256; - - private static readonly int[] DataPN = new int[DataCount] - { - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, - PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, - PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, - PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, - PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, - PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, - PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, - PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN - }; - - private static readonly int[] DataPZ = new int[DataCount] - { - PZ, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 - }; - - private static readonly int[] DataPNZ = new int[DataCount] - { - PZ, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, - PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, - PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, - PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, - PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, - PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, - PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, - PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN - }; - } -} +using System; + +namespace Jellyfish.Virtu +{ + public partial class Cpu + { + private const int OpcodeCount = 256; + + private readonly Action[] ExecuteOpcode65N02; + private readonly Action[] ExecuteOpcode65C02; + + private const int PC = 0x01; + private const int PZ = 0x02; + private const int PI = 0x04; + private const int PD = 0x08; + private const int PB = 0x10; + private const int PR = 0x20; + private const int PV = 0x40; + private const int PN = 0x80; + + private const int DataCount = 256; + + private static readonly int[] DataPN = new int[DataCount] + { + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, + PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, + PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, + PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, + PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, + PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, + PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, + PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN + }; + + private static readonly int[] DataPZ = new int[DataCount] + { + PZ, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 + }; + + private static readonly int[] DataPNZ = new int[DataCount] + { + PZ, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, + PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, + PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, + PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, + PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, + PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, + PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, + PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN + }; + } +} diff --git a/Virtu/CustomDictionary.xml b/Virtu/CustomDictionary.xml index 928be94..0ad9820 100644 --- a/Virtu/CustomDictionary.xml +++ b/Virtu/CustomDictionary.xml @@ -1,25 +1,25 @@ - - - - - CXXX - RPC - - - - - Annunciator - Dsk - Opcode - Unpause - Virtu - Xna - x - y - - - DownRight - UpRight - - + + + + + CXXX + RPC + + + + + Annunciator + Dsk + Opcode + Unpause + Virtu + Xna + x + y + + + DownRight + UpRight + + \ No newline at end of file diff --git a/Virtu/Disk525.cs b/Virtu/Disk525.cs index a688295..e9d7bfa 100644 --- a/Virtu/Disk525.cs +++ b/Virtu/Disk525.cs @@ -1,43 +1,43 @@ -using System; -using System.Diagnostics.CodeAnalysis; - -namespace Jellyfish.Virtu -{ - public abstract class Disk525 - { - protected Disk525(string name, byte[] data, bool isWriteProtected) - { - Name = name; - Data = data; - IsWriteProtected = isWriteProtected; - } - - public static Disk525 CreateDisk(string name, byte[] data, bool isWriteProtected) - { - if (name.EndsWith(".nib", StringComparison.OrdinalIgnoreCase) && (data.Length == TrackCount * TrackSize)) - { - return new DiskNib(name, data, isWriteProtected); - } - else if (name.EndsWith(".dsk", StringComparison.OrdinalIgnoreCase) && (data.Length == TrackCount * SectorCount * SectorSize)) - { - return new DiskDsk(name, data, isWriteProtected); - } - - return null; - } - - public abstract void ReadTrack(int number, int fraction, byte[] buffer); - public abstract void WriteTrack(int number, int fraction, byte[] buffer); - - public string Name { get; private set; } - public bool IsWriteProtected { get; private set; } - - [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] - protected byte[] Data { get; private set; } - - public const int SectorCount = 16; - public const int SectorSize = 0x100; - public const int TrackCount = 35; - public const int TrackSize = 0x1A00; - } -} +using System; +using System.Diagnostics.CodeAnalysis; + +namespace Jellyfish.Virtu +{ + public abstract class Disk525 + { + protected Disk525(string name, byte[] data, bool isWriteProtected) + { + Name = name; + Data = data; + IsWriteProtected = isWriteProtected; + } + + public static Disk525 CreateDisk(string name, byte[] data, bool isWriteProtected) + { + if (name.EndsWith(".nib", StringComparison.OrdinalIgnoreCase) && (data.Length == TrackCount * TrackSize)) + { + return new DiskNib(name, data, isWriteProtected); + } + else if (name.EndsWith(".dsk", StringComparison.OrdinalIgnoreCase) && (data.Length == TrackCount * SectorCount * SectorSize)) + { + return new DiskDsk(name, data, isWriteProtected); + } + + return null; + } + + public abstract void ReadTrack(int number, int fraction, byte[] buffer); + public abstract void WriteTrack(int number, int fraction, byte[] buffer); + + public string Name { get; private set; } + public bool IsWriteProtected { get; private set; } + + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] + protected byte[] Data { get; private set; } + + public const int SectorCount = 16; + public const int SectorSize = 0x100; + public const int TrackCount = 35; + public const int TrackSize = 0x1A00; + } +} diff --git a/Virtu/DiskDsk.cs b/Virtu/DiskDsk.cs index b7f1492..c0f4d7e 100644 --- a/Virtu/DiskDsk.cs +++ b/Virtu/DiskDsk.cs @@ -1,289 +1,289 @@ -using System; - -namespace Jellyfish.Virtu -{ - public sealed class DiskDsk : Disk525 - { - public DiskDsk(string name, byte[] data, bool isWriteProtected) : - base(name, data, isWriteProtected) - { - } - - public override void ReadTrack(int number, int fraction, byte[] buffer) - { - int track = number / 2; - - _trackBuffer = buffer; - _trackOffset = 0; - - WriteNibble(0xFF, 48); // gap 0 - - for (int sector = 0; sector < SectorCount; sector++) - { - WriteNibble(0xD5); // address prologue - WriteNibble(0xAA); - WriteNibble(0x96); - - WriteNibble44(Volume); - WriteNibble44(track); - WriteNibble44(sector); - WriteNibble44(Volume ^ track ^ sector); - - WriteNibble(0xDE); // address epilogue - WriteNibble(0xAA); - WriteNibble(0xEB); - WriteNibble(0xFF, 8); - - WriteNibble(0xD5); // data prologue - WriteNibble(0xAA); - WriteNibble(0xAD); - - WriteDataNibbles((track * SectorCount + DosOrderToLogicalSector[sector]) * SectorSize); - - WriteNibble(0xDE); // data epilogue - WriteNibble(0xAA); - WriteNibble(0xEB); - WriteNibble(0xFF, 16); - } - } - - public override void WriteTrack(int number, int fraction, byte[] buffer) - { - if (IsWriteProtected) - return; - - int track = number / 2; - - _trackBuffer = buffer; - _trackOffset = 0; - int sectorsDone = 0; - - for (int sector = 0; sector < SectorCount; sector++) - { - if (!Read3Nibbles(0xD5, 0xAA, 0x96, 0x304)) - break; // no address prologue - - /*int readVolume = */ReadNibble44(); - - int readTrack = ReadNibble44(); - if (readTrack != track) - break; // bad track number - - int readSector = ReadNibble44(); - if (readSector > SectorCount) - break; // bad sector number - if ((sectorsDone & (0x1 << readSector)) != 0) - break; // already done this sector - - if (ReadNibble44() != (Volume ^ readTrack ^ readSector)) - break; // bad address checksum - - if ((ReadNibble() != 0xDE) || (ReadNibble() != 0xAA)) - break; // bad address epilogue - - if (!Read3Nibbles(0xD5, 0xAA, 0xAD, 0x20)) - break; // no data prologue - - if (!ReadDataNibbles((track * SectorCount + DosOrderToLogicalSector[sector]) * SectorSize)) - break; // bad data checksum - - if ((ReadNibble() != 0xDE) || (ReadNibble() != 0xAA)) - break; // bad data epilogue - - sectorsDone |= 0x1 << sector; - } - - if (sectorsDone != 0xFFFF) - throw new InvalidOperationException("disk error"); // TODO: we should alert the user and "dump" a NIB - } - - private byte ReadNibble() - { - byte data = _trackBuffer[_trackOffset]; - if (_trackOffset++ == TrackSize) - { - _trackOffset = 0; - } - return data; - } - - private bool Read3Nibbles(byte data1, byte data2, byte data3, int maxReads) - { - bool result = false; - while (--maxReads > 0) - { - if (ReadNibble() != data1) - continue; - - if (ReadNibble() != data2) - continue; - - if (ReadNibble() != data3) - continue; - - result = true; - break; - } - return result; - } - - private int ReadNibble44() - { - return (((ReadNibble() << 1) | 0x1) & ReadNibble()); - } - - private byte ReadTranslatedNibble() - { - byte data = NibbleToByte[ReadNibble()]; - // TODO: check that invalid nibbles aren't used - // (put 0xFFs for invalid nibbles in the table) - //if (data == 0xFF) - //{ - //throw an exception - //} - return data; - } - - private bool ReadDataNibbles(int sectorOffset) - { - byte a, x, y; - - y = SecondaryBufferLength; - a = 0; - do // fill and de-nibblize secondary buffer - { - a = _secondaryBuffer[--y] = (byte)(a ^ ReadTranslatedNibble()); - } - while (y > 0); - - do // fill and de-nibblize secondary buffer - { - a = _primaryBuffer[y++] = (byte)(a ^ ReadTranslatedNibble()); - } - while (y != 0); - - int checksum = a ^ ReadTranslatedNibble(); // should be 0 - - x = y = 0; - do // decode data - { - if (x == 0) - { - x = SecondaryBufferLength; - } - a = (byte)((_primaryBuffer[y] << 2) | SwapBits[_secondaryBuffer[--x] & 0x03]); - _secondaryBuffer[x] >>= 2; - Data[sectorOffset + y] = a; - } - while (++y != 0); - - return (checksum == 0); - } - - private void WriteNibble(int data) - { - _trackBuffer[_trackOffset++] = (byte)data; - } - - private void WriteNibble(int data, int count) - { - while (count-- > 0) - { - WriteNibble(data); - } - } - - private void WriteNibble44(int data) - { - WriteNibble((data >> 1) | 0xAA); - WriteNibble(data | 0xAA); - } - - private void WriteDataNibbles(int sectorOffset) - { - byte a, x, y; - - for (x = 0; x < SecondaryBufferLength; x++) - { - _secondaryBuffer[x] = 0; // zero secondary buffer - } - - y = 2; - do // fill buffers - { - x = 0; - do - { - a = Data[sectorOffset + --y]; - _secondaryBuffer[x] = (byte)((_secondaryBuffer[x] << 2) | SwapBits[a & 0x03]); // b1,b0 -> secondary buffer - _primaryBuffer[y] = (byte)(a >> 2); // b7-b2 -> primary buffer - } - while (++x < SecondaryBufferLength); - } - while (y != 0); - - y = SecondaryBufferLength; - do // write secondary buffer - { - WriteNibble(ByteToNibble[_secondaryBuffer[y] ^ _secondaryBuffer[y - 1]]); - } - while (--y != 0); - - a = _secondaryBuffer[0]; - do // write primary buffer - { - WriteNibble(ByteToNibble[a ^ _primaryBuffer[y]]); - a = _primaryBuffer[y]; - } - while (++y != 0); - - 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 const int Volume = 0xFE; - - private static readonly byte[] SwapBits = { 0, 2, 1, 3 }; - - private static readonly int[] DosOrderToLogicalSector = new int[] - { - 0x0, 0x7, 0xE, 0x6, 0xD, 0x5, 0xC, 0x4, 0xB, 0x3, 0xA, 0x2, 0x9, 0x1, 0x8, 0xF - }; - - private static readonly byte[] ByteToNibble = new byte[] - { - 0x96, 0x97, 0x9A, 0x9B, 0x9D, 0x9E, 0x9F, 0xA6, 0xA7, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB2, 0xB3, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xCB, 0xCD, 0xCE, 0xCF, 0xD3, - 0xD6, 0xD7, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE5, 0xE6, 0xE7, 0xE9, 0xEA, 0xEB, 0xEC, - 0xED, 0xEE, 0xEF, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF - }; - - private static readonly byte[] NibbleToByte = new byte[] - { - // padding for offset (not used) - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, - 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, - - // nibble translate table - 0x00, 0x01, 0x98, 0x99, 0x02, 0x03, 0x9C, 0x04, 0x05, 0x06, - 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0x07, 0x08, 0xA8, 0xA9, 0xAA, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, - 0xB0, 0xB1, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0xB8, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, - 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0x1B, 0xCC, 0x1C, 0x1D, 0x1E, - 0xD0, 0xD1, 0xD2, 0x1F, 0xD4, 0xD5, 0x20, 0x21, 0xD8, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, - 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0x29, 0x2A, 0x2B, 0xE8, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, - 0xF0, 0xF1, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0xF8, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F - }; - } -} +using System; + +namespace Jellyfish.Virtu +{ + public sealed class DiskDsk : Disk525 + { + public DiskDsk(string name, byte[] data, bool isWriteProtected) : + base(name, data, isWriteProtected) + { + } + + public override void ReadTrack(int number, int fraction, byte[] buffer) + { + int track = number / 2; + + _trackBuffer = buffer; + _trackOffset = 0; + + WriteNibble(0xFF, 48); // gap 0 + + for (int sector = 0; sector < SectorCount; sector++) + { + WriteNibble(0xD5); // address prologue + WriteNibble(0xAA); + WriteNibble(0x96); + + WriteNibble44(Volume); + WriteNibble44(track); + WriteNibble44(sector); + WriteNibble44(Volume ^ track ^ sector); + + WriteNibble(0xDE); // address epilogue + WriteNibble(0xAA); + WriteNibble(0xEB); + WriteNibble(0xFF, 8); + + WriteNibble(0xD5); // data prologue + WriteNibble(0xAA); + WriteNibble(0xAD); + + WriteDataNibbles((track * SectorCount + DosOrderToLogicalSector[sector]) * SectorSize); + + WriteNibble(0xDE); // data epilogue + WriteNibble(0xAA); + WriteNibble(0xEB); + WriteNibble(0xFF, 16); + } + } + + public override void WriteTrack(int number, int fraction, byte[] buffer) + { + if (IsWriteProtected) + return; + + int track = number / 2; + + _trackBuffer = buffer; + _trackOffset = 0; + int sectorsDone = 0; + + for (int sector = 0; sector < SectorCount; sector++) + { + if (!Read3Nibbles(0xD5, 0xAA, 0x96, 0x304)) + break; // no address prologue + + /*int readVolume = */ReadNibble44(); + + int readTrack = ReadNibble44(); + if (readTrack != track) + break; // bad track number + + int readSector = ReadNibble44(); + if (readSector > SectorCount) + break; // bad sector number + if ((sectorsDone & (0x1 << readSector)) != 0) + break; // already done this sector + + if (ReadNibble44() != (Volume ^ readTrack ^ readSector)) + break; // bad address checksum + + if ((ReadNibble() != 0xDE) || (ReadNibble() != 0xAA)) + break; // bad address epilogue + + if (!Read3Nibbles(0xD5, 0xAA, 0xAD, 0x20)) + break; // no data prologue + + if (!ReadDataNibbles((track * SectorCount + DosOrderToLogicalSector[sector]) * SectorSize)) + break; // bad data checksum + + if ((ReadNibble() != 0xDE) || (ReadNibble() != 0xAA)) + break; // bad data epilogue + + sectorsDone |= 0x1 << sector; + } + + if (sectorsDone != 0xFFFF) + throw new InvalidOperationException("disk error"); // TODO: we should alert the user and "dump" a NIB + } + + private byte ReadNibble() + { + byte data = _trackBuffer[_trackOffset]; + if (_trackOffset++ == TrackSize) + { + _trackOffset = 0; + } + return data; + } + + private bool Read3Nibbles(byte data1, byte data2, byte data3, int maxReads) + { + bool result = false; + while (--maxReads > 0) + { + if (ReadNibble() != data1) + continue; + + if (ReadNibble() != data2) + continue; + + if (ReadNibble() != data3) + continue; + + result = true; + break; + } + return result; + } + + private int ReadNibble44() + { + return (((ReadNibble() << 1) | 0x1) & ReadNibble()); + } + + private byte ReadTranslatedNibble() + { + byte data = NibbleToByte[ReadNibble()]; + // TODO: check that invalid nibbles aren't used + // (put 0xFFs for invalid nibbles in the table) + //if (data == 0xFF) + //{ + //throw an exception + //} + return data; + } + + private bool ReadDataNibbles(int sectorOffset) + { + byte a, x, y; + + y = SecondaryBufferLength; + a = 0; + do // fill and de-nibblize secondary buffer + { + a = _secondaryBuffer[--y] = (byte)(a ^ ReadTranslatedNibble()); + } + while (y > 0); + + do // fill and de-nibblize secondary buffer + { + a = _primaryBuffer[y++] = (byte)(a ^ ReadTranslatedNibble()); + } + while (y != 0); + + int checksum = a ^ ReadTranslatedNibble(); // should be 0 + + x = y = 0; + do // decode data + { + if (x == 0) + { + x = SecondaryBufferLength; + } + a = (byte)((_primaryBuffer[y] << 2) | SwapBits[_secondaryBuffer[--x] & 0x03]); + _secondaryBuffer[x] >>= 2; + Data[sectorOffset + y] = a; + } + while (++y != 0); + + return (checksum == 0); + } + + private void WriteNibble(int data) + { + _trackBuffer[_trackOffset++] = (byte)data; + } + + private void WriteNibble(int data, int count) + { + while (count-- > 0) + { + WriteNibble(data); + } + } + + private void WriteNibble44(int data) + { + WriteNibble((data >> 1) | 0xAA); + WriteNibble(data | 0xAA); + } + + private void WriteDataNibbles(int sectorOffset) + { + byte a, x, y; + + for (x = 0; x < SecondaryBufferLength; x++) + { + _secondaryBuffer[x] = 0; // zero secondary buffer + } + + y = 2; + do // fill buffers + { + x = 0; + do + { + a = Data[sectorOffset + --y]; + _secondaryBuffer[x] = (byte)((_secondaryBuffer[x] << 2) | SwapBits[a & 0x03]); // b1,b0 -> secondary buffer + _primaryBuffer[y] = (byte)(a >> 2); // b7-b2 -> primary buffer + } + while (++x < SecondaryBufferLength); + } + while (y != 0); + + y = SecondaryBufferLength; + do // write secondary buffer + { + WriteNibble(ByteToNibble[_secondaryBuffer[y] ^ _secondaryBuffer[y - 1]]); + } + while (--y != 0); + + a = _secondaryBuffer[0]; + do // write primary buffer + { + WriteNibble(ByteToNibble[a ^ _primaryBuffer[y]]); + a = _primaryBuffer[y]; + } + while (++y != 0); + + 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 const int Volume = 0xFE; + + private static readonly byte[] SwapBits = { 0, 2, 1, 3 }; + + private static readonly int[] DosOrderToLogicalSector = new int[] + { + 0x0, 0x7, 0xE, 0x6, 0xD, 0x5, 0xC, 0x4, 0xB, 0x3, 0xA, 0x2, 0x9, 0x1, 0x8, 0xF + }; + + private static readonly byte[] ByteToNibble = new byte[] + { + 0x96, 0x97, 0x9A, 0x9B, 0x9D, 0x9E, 0x9F, 0xA6, 0xA7, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB2, 0xB3, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xCB, 0xCD, 0xCE, 0xCF, 0xD3, + 0xD6, 0xD7, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE5, 0xE6, 0xE7, 0xE9, 0xEA, 0xEB, 0xEC, + 0xED, 0xEE, 0xEF, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF + }; + + private static readonly byte[] NibbleToByte = new byte[] + { + // padding for offset (not used) + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, + + // nibble translate table + 0x00, 0x01, 0x98, 0x99, 0x02, 0x03, 0x9C, 0x04, 0x05, 0x06, + 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0x07, 0x08, 0xA8, 0xA9, 0xAA, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, + 0xB0, 0xB1, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0xB8, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, + 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0x1B, 0xCC, 0x1C, 0x1D, 0x1E, + 0xD0, 0xD1, 0xD2, 0x1F, 0xD4, 0xD5, 0x20, 0x21, 0xD8, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0x29, 0x2A, 0x2B, 0xE8, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, + 0xF0, 0xF1, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0xF8, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F + }; + } +} diff --git a/Virtu/DiskII.cs b/Virtu/DiskII.cs index c720d70..e0dba46 100644 --- a/Virtu/DiskII.cs +++ b/Virtu/DiskII.cs @@ -1,241 +1,241 @@ -using System.Diagnostics.CodeAnalysis; -using Jellyfish.Virtu.Services; -using Jellyfish.Virtu.Settings; - -namespace Jellyfish.Virtu -{ - public sealed class DiskII : MachineComponent - { - public DiskII(Machine machine) : - base(machine) - { - } - - public override void Initialize() - { - _drives[0].InsertDisk("Default.dsk", StorageService.GetResourceStream("Default.dsk", 0x23000), false); - -#if WINDOWS - DiskIISettings settings = Machine.Settings.DiskII; - if (settings.Disk1.Name.Length > 0) - { - _drives[0].InsertDisk(settings.Disk1.Name, settings.Disk1.IsWriteProtected); - } - if (settings.Disk2.Name.Length > 0) - { - _drives[1].InsertDisk(settings.Disk2.Name, settings.Disk2.IsWriteProtected); - } -#endif - } - - public override void Reset() - { - _phaseStates = 0; - SetMotorOn(false); - SetDriveNumber(0); - _loadMode = false; - _writeMode = false; - } - - public override void Uninitialize() - { - Flush(); - } - - [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] - public int Read(int address) - { - switch (address & 0xF) - { - case 0x0: case 0x1: case 0x2: case 0x3: case 0x4: case 0x5: case 0x6: case 0x7: - SetPhase(address); - break; - - case 0x8: - SetMotorOn(false); - break; - - case 0x9: - SetMotorOn(true); - break; - - case 0xA: - SetDriveNumber(0); - break; - - case 0xB: - SetDriveNumber(1); - break; - - case 0xC: - _loadMode = false; - if (_motorOn) - { - if (!_writeMode) - { - return _latch = _drives[_driveNumber].Read(); - } - else - { - WriteLatch(); - } - } - break; - - case 0xD: - _loadMode = true; - if (_motorOn && !_writeMode) - { - // write protect is forced if phase 1 is on [F9.7] - _latch &= 0x7F; - if (_drives[_driveNumber].IsWriteProtected || - (_phaseStates & Phase1On) != 0) - { - _latch |= 0x80; - } - } - break; - - case 0xE: - _writeMode = false; - break; - - case 0xF: - _writeMode = true; - break; - } - - if ((address & 1) == 0) - { - // only even addresses return the latch - if (_motorOn) - { - return _latch; - } - - // simple hack to fool DOS SAMESLOT drive spin check (usually at $BD34) - _driveSpin = !_driveSpin; - return _driveSpin ? 0x7E : 0x7F; - } - - return Machine.Video.ReadFloatingBus(); // [5-40] - } - - public void Write(int address, int data) - { - switch (address & 0xF) - { - case 0x0: case 0x1: case 0x2: case 0x3: case 0x4: case 0x5: case 0x6: case 0x7: - SetPhase(address); - break; - - case 0x8: - SetMotorOn(false); - break; - - case 0x9: - SetMotorOn(true); - break; - - case 0xA: - SetDriveNumber(0); - break; - - case 0xB: - SetDriveNumber(1); - break; - - case 0xC: - _loadMode = false; - if (_writeMode) - { - WriteLatch(); - } - break; - - case 0xD: - _loadMode = true; - break; - - case 0xE: - _writeMode = false; - break; - - case 0xF: - _writeMode = true; - break; - } - - if (_motorOn && _writeMode) - { - if (_loadMode) - { - // any address writes latch for sequencer LD; OE1/2 irrelevant ['323 datasheet] - _latch = data; - } - } - } - - private void WriteLatch() - { - // write protect is forced if phase 1 is on [F9.7] - if ((_phaseStates & Phase1On) == 0) - { - _drives[_driveNumber].Write(_latch); - } - } - - private void Flush() - { - _drives[_driveNumber].FlushTrack(); - } - - private void SetDriveNumber(int driveNumber) - { - if (_driveNumber != driveNumber) - { - Flush(); - _driveNumber = driveNumber; - } - } - - private void SetMotorOn(bool state) - { - if (_motorOn && !state) - { - Flush(); - } - _motorOn = state; - } - - private void SetPhase(int address) - { - int phase = (address >> 1) & 0x3; - int state = address & 1; - _phaseStates &= ~(1 << phase); - _phaseStates |= (state << phase); - - if (_motorOn) - { - _drives[_driveNumber].ApplyPhaseChange(_phaseStates); - } - } - - [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] - public Drive525[] Drives { get { return _drives; } } - - private const int Phase0On = 1 << 0; - private const int Phase1On = 1 << 1; - private const int Phase2On = 1 << 2; - private const int Phase3On = 1 << 3; - - private Drive525[] _drives = new Drive525[] { new Drive525(), new Drive525() }; - private int _latch; - private int _phaseStates; - private bool _motorOn; - private int _driveNumber; - private bool _loadMode; - private bool _writeMode; - private bool _driveSpin; - } -} +using System.Diagnostics.CodeAnalysis; +using Jellyfish.Virtu.Services; +using Jellyfish.Virtu.Settings; + +namespace Jellyfish.Virtu +{ + public sealed class DiskII : MachineComponent + { + public DiskII(Machine machine) : + base(machine) + { + } + + public override void Initialize() + { + _drives[0].InsertDisk("Default.dsk", StorageService.GetResourceStream("Default.dsk", 0x23000), false); + +#if WINDOWS + var settings = Machine.Settings.DiskII; + if (settings.Disk1.Name.Length > 0) + { + _drives[0].InsertDisk(settings.Disk1.Name, settings.Disk1.IsWriteProtected); + } + if (settings.Disk2.Name.Length > 0) + { + _drives[1].InsertDisk(settings.Disk2.Name, settings.Disk2.IsWriteProtected); + } +#endif + } + + public override void Reset() + { + _phaseStates = 0; + SetMotorOn(false); + SetDriveNumber(0); + _loadMode = false; + _writeMode = false; + } + + public override void Uninitialize() + { + Flush(); + } + + [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] + public int Read(int address) + { + switch (address & 0xF) + { + case 0x0: case 0x1: case 0x2: case 0x3: case 0x4: case 0x5: case 0x6: case 0x7: + SetPhase(address); + break; + + case 0x8: + SetMotorOn(false); + break; + + case 0x9: + SetMotorOn(true); + break; + + case 0xA: + SetDriveNumber(0); + break; + + case 0xB: + SetDriveNumber(1); + break; + + case 0xC: + _loadMode = false; + if (_motorOn) + { + if (!_writeMode) + { + return _latch = _drives[_driveNumber].Read(); + } + else + { + WriteLatch(); + } + } + break; + + case 0xD: + _loadMode = true; + if (_motorOn && !_writeMode) + { + // write protect is forced if phase 1 is on [F9.7] + _latch &= 0x7F; + if (_drives[_driveNumber].IsWriteProtected || + (_phaseStates & Phase1On) != 0) + { + _latch |= 0x80; + } + } + break; + + case 0xE: + _writeMode = false; + break; + + case 0xF: + _writeMode = true; + break; + } + + if ((address & 1) == 0) + { + // only even addresses return the latch + if (_motorOn) + { + return _latch; + } + + // simple hack to fool DOS SAMESLOT drive spin check (usually at $BD34) + _driveSpin = !_driveSpin; + return _driveSpin ? 0x7E : 0x7F; + } + + return Machine.Video.ReadFloatingBus(); // [5-40] + } + + public void Write(int address, int data) + { + switch (address & 0xF) + { + case 0x0: case 0x1: case 0x2: case 0x3: case 0x4: case 0x5: case 0x6: case 0x7: + SetPhase(address); + break; + + case 0x8: + SetMotorOn(false); + break; + + case 0x9: + SetMotorOn(true); + break; + + case 0xA: + SetDriveNumber(0); + break; + + case 0xB: + SetDriveNumber(1); + break; + + case 0xC: + _loadMode = false; + if (_writeMode) + { + WriteLatch(); + } + break; + + case 0xD: + _loadMode = true; + break; + + case 0xE: + _writeMode = false; + break; + + case 0xF: + _writeMode = true; + break; + } + + if (_motorOn && _writeMode) + { + if (_loadMode) + { + // any address writes latch for sequencer LD; OE1/2 irrelevant ['323 datasheet] + _latch = data; + } + } + } + + private void WriteLatch() + { + // write protect is forced if phase 1 is on [F9.7] + if ((_phaseStates & Phase1On) == 0) + { + _drives[_driveNumber].Write(_latch); + } + } + + private void Flush() + { + _drives[_driveNumber].FlushTrack(); + } + + private void SetDriveNumber(int driveNumber) + { + if (_driveNumber != driveNumber) + { + Flush(); + _driveNumber = driveNumber; + } + } + + private void SetMotorOn(bool state) + { + if (_motorOn && !state) + { + Flush(); + } + _motorOn = state; + } + + private void SetPhase(int address) + { + int phase = (address >> 1) & 0x3; + int state = address & 1; + _phaseStates &= ~(1 << phase); + _phaseStates |= (state << phase); + + if (_motorOn) + { + _drives[_driveNumber].ApplyPhaseChange(_phaseStates); + } + } + + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] + public Drive525[] Drives { get { return _drives; } } + + private const int Phase0On = 1 << 0; + private const int Phase1On = 1 << 1; + private const int Phase2On = 1 << 2; + private const int Phase3On = 1 << 3; + + private Drive525[] _drives = new Drive525[] { new Drive525(), new Drive525() }; + private int _latch; + private int _phaseStates; + private bool _motorOn; + private int _driveNumber; + private bool _loadMode; + private bool _writeMode; + private bool _driveSpin; + } +} diff --git a/Virtu/DiskNib.cs b/Virtu/DiskNib.cs index 1466abc..5407a18 100644 --- a/Virtu/DiskNib.cs +++ b/Virtu/DiskNib.cs @@ -1,22 +1,22 @@ -using System; - -namespace Jellyfish.Virtu -{ - public sealed class DiskNib : Disk525 - { - public DiskNib(string name, byte[] data, bool isWriteProtected) : - base(name, data, isWriteProtected) - { - } - - public override void ReadTrack(int number, int fraction, byte[] buffer) - { - Buffer.BlockCopy(Data, (number / 2) * TrackSize, buffer, 0, TrackSize); - } - - public override void WriteTrack(int number, int fraction, byte[] buffer) - { - Buffer.BlockCopy(buffer, 0, Data, (number / 2) * TrackSize, TrackSize); - } - } -} +using System; + +namespace Jellyfish.Virtu +{ + public sealed class DiskNib : Disk525 + { + public DiskNib(string name, byte[] data, bool isWriteProtected) : + base(name, data, isWriteProtected) + { + } + + public override void ReadTrack(int number, int fraction, byte[] buffer) + { + Buffer.BlockCopy(Data, (number / 2) * TrackSize, buffer, 0, TrackSize); + } + + public override void WriteTrack(int number, int fraction, byte[] buffer) + { + Buffer.BlockCopy(buffer, 0, Data, (number / 2) * TrackSize, TrackSize); + } + } +} diff --git a/Virtu/Drive525.cs b/Virtu/Drive525.cs index e036ec9..c140cd9 100644 --- a/Virtu/Drive525.cs +++ b/Virtu/Drive525.cs @@ -1,118 +1,118 @@ -using System; -using System.IO; -using Jellyfish.Library; - -namespace Jellyfish.Virtu -{ - public sealed class Drive525 - { - public Drive525() - { - DriveArmStepDelta[0] = new int[] { 0, 0, 1, 1, 0, 0, 1, 1, -1, -1, 0, 0, -1, -1, 0, 0 }; // phase 0 - DriveArmStepDelta[1] = new int[] { 0, -1, 0, -1, 1, 0, 1, 0, 0, -1, 0, -1, 1, 0, 1, 0 }; // phase 1 - DriveArmStepDelta[2] = new int[] { 0, 0, -1, -1, 0, 0, -1, -1, 1, 1, 0, 0, 1, 1, 0, 0 }; // phase 2 - DriveArmStepDelta[3] = new int[] { 0, 1, 0, 1, -1, 0, -1, 0, 0, 1, 0, 1, -1, 0, -1, 0 }; // phase 3 - } - - public void InsertDisk(string fileName, bool isWriteProtected) - { - using (FileStream stream = File.OpenRead(fileName)) - { - InsertDisk(fileName, stream, isWriteProtected); - } - } - - public void InsertDisk(string name, Stream stream, bool isWriteProtected) - { - FlushTrack(); - - // TODO handle null param/empty string for eject, or add Eject() - - _disk = Disk525.CreateDisk(name, stream.ReadAllBytes(), isWriteProtected); - _trackLoaded = false; - } - - public void ApplyPhaseChange(int phaseState) - { - // step the drive head according to stepper magnet changes - int delta = DriveArmStepDelta[_trackNumber & 0x3][phaseState]; - if (delta != 0) - { - int newTrackNumber = MathHelpers.Clamp(_trackNumber + delta, 0, TrackNumberMax); - if (newTrackNumber != _trackNumber) - { - FlushTrack(); - _trackNumber = newTrackNumber; - _trackOffset = 0; - _trackLoaded = false; - } - } - } - - public int Read() - { - if (LoadTrack()) - { - int data = _trackData[_trackOffset++]; - if (_trackOffset >= Disk525.TrackSize) - { - _trackOffset = 0; - } - - return data; - } - - return _random.Next(0x01, 0xFF); - } - - public void Write(int data) - { - if (LoadTrack()) - { - _trackChanged = true; - _trackData[_trackOffset++] = (byte)data; - if (_trackOffset >= Disk525.TrackSize) - { - _trackOffset = 0; - } - } - } - - private bool LoadTrack() - { - if (!_trackLoaded && (_disk != null)) - { - _disk.ReadTrack(_trackNumber, 0, _trackData); - _trackLoaded = true; - } - - return _trackLoaded; - } - - public void FlushTrack() - { - if (_trackChanged) - { - _disk.WriteTrack(_trackNumber, 0, _trackData); - _trackChanged = false; - } - } - - public bool IsWriteProtected { get { return _disk.IsWriteProtected; } } - - private const int TrackNumberMax = 0x44; - - private const int PhaseCount = 4; - - private readonly int[][] DriveArmStepDelta = new int[PhaseCount][]; - - private Disk525 _disk; - private bool _trackLoaded; - private bool _trackChanged; - private int _trackNumber; - private int _trackOffset; - private byte[] _trackData = new byte[Disk525.TrackSize]; - - private Random _random = new Random(); - } -} +using System; +using System.IO; +using Jellyfish.Library; + +namespace Jellyfish.Virtu +{ + public sealed class Drive525 + { + public Drive525() + { + DriveArmStepDelta[0] = new int[] { 0, 0, 1, 1, 0, 0, 1, 1, -1, -1, 0, 0, -1, -1, 0, 0 }; // phase 0 + DriveArmStepDelta[1] = new int[] { 0, -1, 0, -1, 1, 0, 1, 0, 0, -1, 0, -1, 1, 0, 1, 0 }; // phase 1 + DriveArmStepDelta[2] = new int[] { 0, 0, -1, -1, 0, 0, -1, -1, 1, 1, 0, 0, 1, 1, 0, 0 }; // phase 2 + DriveArmStepDelta[3] = new int[] { 0, 1, 0, 1, -1, 0, -1, 0, 0, 1, 0, 1, -1, 0, -1, 0 }; // phase 3 + } + + public void InsertDisk(string fileName, bool isWriteProtected) + { + using (var stream = File.OpenRead(fileName)) + { + InsertDisk(fileName, stream, isWriteProtected); + } + } + + public void InsertDisk(string name, Stream stream, bool isWriteProtected) + { + FlushTrack(); + + // TODO handle null param/empty string for eject, or add Eject() + + _disk = Disk525.CreateDisk(name, stream.ReadAllBytes(), isWriteProtected); + _trackLoaded = false; + } + + public void ApplyPhaseChange(int phaseState) + { + // step the drive head according to stepper magnet changes + int delta = DriveArmStepDelta[_trackNumber & 0x3][phaseState]; + if (delta != 0) + { + int newTrackNumber = MathHelpers.Clamp(_trackNumber + delta, 0, TrackNumberMax); + if (newTrackNumber != _trackNumber) + { + FlushTrack(); + _trackNumber = newTrackNumber; + _trackOffset = 0; + _trackLoaded = false; + } + } + } + + public int Read() + { + if (LoadTrack()) + { + int data = _trackData[_trackOffset++]; + if (_trackOffset >= Disk525.TrackSize) + { + _trackOffset = 0; + } + + return data; + } + + return _random.Next(0x01, 0xFF); + } + + public void Write(int data) + { + if (LoadTrack()) + { + _trackChanged = true; + _trackData[_trackOffset++] = (byte)data; + if (_trackOffset >= Disk525.TrackSize) + { + _trackOffset = 0; + } + } + } + + private bool LoadTrack() + { + if (!_trackLoaded && (_disk != null)) + { + _disk.ReadTrack(_trackNumber, 0, _trackData); + _trackLoaded = true; + } + + return _trackLoaded; + } + + public void FlushTrack() + { + if (_trackChanged) + { + _disk.WriteTrack(_trackNumber, 0, _trackData); + _trackChanged = false; + } + } + + public bool IsWriteProtected { get { return _disk.IsWriteProtected; } } + + private const int TrackNumberMax = 0x44; + + private const int PhaseCount = 4; + + private readonly int[][] DriveArmStepDelta = new int[PhaseCount][]; + + private Disk525 _disk; + private bool _trackLoaded; + private bool _trackChanged; + private int _trackNumber; + private int _trackOffset; + private byte[] _trackData = new byte[Disk525.TrackSize]; + + private Random _random = new Random(); + } +} diff --git a/Virtu/GamePort.cs b/Virtu/GamePort.cs index 1b009cc..5a456f4 100644 --- a/Virtu/GamePort.cs +++ b/Virtu/GamePort.cs @@ -1,158 +1,158 @@ -using System; -using System.Diagnostics.CodeAnalysis; -using Jellyfish.Library; -using Jellyfish.Virtu.Services; -using Jellyfish.Virtu.Settings; - -namespace Jellyfish.Virtu -{ - public sealed class GamePort : MachineComponent - { - public GamePort(Machine machine) : - base(machine) - { - _resetPaddle0StrobeEvent = ResetPaddle0StrobeEvent; // cache delegates; avoids garbage - _resetPaddle1StrobeEvent = ResetPaddle1StrobeEvent; - _resetPaddle2StrobeEvent = ResetPaddle2StrobeEvent; - _resetPaddle3StrobeEvent = ResetPaddle3StrobeEvent; - } - - public override void Initialize() - { - _keyboardService = Machine.Services.GetService(); - _gamePortService = Machine.Services.GetService(); - } - - public bool ReadButton0() - { - GamePortSettings settings = Machine.Settings.GamePort; - - return (_gamePortService.IsButton0Down || _keyboardService.IsOpenAppleKeyDown || - (settings.UseKeyboard && (settings.Key.Button0 > 0) && _keyboardService.IsKeyDown(settings.Key.Button0))); - } - - public bool ReadButton1() - { - GamePortSettings settings = Machine.Settings.GamePort; - - return (_gamePortService.IsButton1Down || _keyboardService.IsCloseAppleKeyDown || - (settings.UseKeyboard && (settings.Key.Button1 > 0) && _keyboardService.IsKeyDown(settings.Key.Button1))); - } - - public bool ReadButton2() - { - GamePortSettings settings = Machine.Settings.GamePort; - - return (_gamePortService.IsButton2Down || - (settings.UseKeyboard && (settings.Key.Button2 > 0) && _keyboardService.IsKeyDown(settings.Key.Button2))); - } - - [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] - public void TriggerTimers() - { - int paddle0 = _gamePortService.Paddle0; - int paddle1 = _gamePortService.Paddle1; - int paddle2 = _gamePortService.Paddle2; - int paddle3 = _gamePortService.Paddle3; - - GamePortSettings settings = Machine.Settings.GamePort; - - if (settings.UseKeyboard) // override - { - if (((settings.Key.Joystick0.UpLeft > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick0.UpLeft)) || - ((settings.Key.Joystick0.Left > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick0.Left)) || - ((settings.Key.Joystick0.DownLeft > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick0.DownLeft))) - { - paddle0 -= 128; - } - if (((settings.Key.Joystick0.UpRight > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick0.UpRight)) || - ((settings.Key.Joystick0.Right > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick0.Right)) || - ((settings.Key.Joystick0.DownRight > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick0.DownRight))) - { - paddle0 += 128; - } - if (((settings.Key.Joystick0.UpLeft > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick0.UpLeft)) || - ((settings.Key.Joystick0.Up > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick0.Up)) || - ((settings.Key.Joystick0.UpRight > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick0.UpRight))) - { - paddle1 -= 128; - } - if (((settings.Key.Joystick0.DownLeft > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick0.DownLeft)) || - ((settings.Key.Joystick0.Down > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick0.Down)) || - ((settings.Key.Joystick0.DownRight > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick0.DownRight))) - { - paddle1 += 128; - } - if (((settings.Key.Joystick1.UpLeft > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick1.UpLeft)) || - ((settings.Key.Joystick1.Left > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick1.Left)) || - ((settings.Key.Joystick1.DownLeft > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick1.DownLeft))) - { - paddle2 -= 128; - } - if (((settings.Key.Joystick1.UpRight > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick1.UpRight)) || - ((settings.Key.Joystick1.Right > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick1.Right)) || - ((settings.Key.Joystick1.DownRight > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick1.DownRight))) - { - paddle2 += 128; - } - if (((settings.Key.Joystick1.UpLeft > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick1.UpLeft)) || - ((settings.Key.Joystick1.Up > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick1.Up)) || - ((settings.Key.Joystick1.UpRight > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick1.UpRight))) - { - paddle3 -= 128; - } - if (((settings.Key.Joystick1.DownLeft > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick1.DownLeft)) || - ((settings.Key.Joystick1.Down > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick1.Down)) || - ((settings.Key.Joystick1.DownRight > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick1.DownRight))) - { - paddle3 += 128; - } - } - - Paddle0Strobe = true; - Paddle1Strobe = true; - Paddle2Strobe = true; - Paddle3Strobe = true; - - Machine.Events.AddEvent(MathHelpers.ClampByte(paddle0) * CyclesPerValue, _resetPaddle0StrobeEvent); // [7-29] - Machine.Events.AddEvent(MathHelpers.ClampByte(paddle1) * CyclesPerValue, _resetPaddle1StrobeEvent); - Machine.Events.AddEvent(MathHelpers.ClampByte(paddle2) * CyclesPerValue, _resetPaddle2StrobeEvent); - Machine.Events.AddEvent(MathHelpers.ClampByte(paddle3) * CyclesPerValue, _resetPaddle3StrobeEvent); - } - - private void ResetPaddle0StrobeEvent() - { - Paddle0Strobe = false; - } - - private void ResetPaddle1StrobeEvent() - { - Paddle1Strobe = false; - } - - private void ResetPaddle2StrobeEvent() - { - Paddle2Strobe = false; - } - - private void ResetPaddle3StrobeEvent() - { - Paddle3Strobe = false; - } - - public bool Paddle0Strobe { get; private set; } - public bool Paddle1Strobe { get; private set; } - public bool Paddle2Strobe { get; private set; } - public bool Paddle3Strobe { get; private set; } - - private const int CyclesPerValue = 11; - - private Action _resetPaddle0StrobeEvent; - private Action _resetPaddle1StrobeEvent; - private Action _resetPaddle2StrobeEvent; - private Action _resetPaddle3StrobeEvent; - - private KeyboardService _keyboardService; - private GamePortService _gamePortService; - } -} +using System; +using System.Diagnostics.CodeAnalysis; +using Jellyfish.Library; +using Jellyfish.Virtu.Services; +using Jellyfish.Virtu.Settings; + +namespace Jellyfish.Virtu +{ + public sealed class GamePort : MachineComponent + { + public GamePort(Machine machine) : + base(machine) + { + _resetPaddle0StrobeEvent = ResetPaddle0StrobeEvent; // cache delegates; avoids garbage + _resetPaddle1StrobeEvent = ResetPaddle1StrobeEvent; + _resetPaddle2StrobeEvent = ResetPaddle2StrobeEvent; + _resetPaddle3StrobeEvent = ResetPaddle3StrobeEvent; + } + + public override void Initialize() + { + _keyboardService = Machine.Services.GetService(); + _gamePortService = Machine.Services.GetService(); + } + + public bool ReadButton0() + { + var settings = Machine.Settings.GamePort; + + return (_gamePortService.IsButton0Down || _keyboardService.IsOpenAppleKeyDown || + (settings.UseKeyboard && (settings.Key.Button0 > 0) && _keyboardService.IsKeyDown(settings.Key.Button0))); + } + + public bool ReadButton1() + { + var settings = Machine.Settings.GamePort; + + return (_gamePortService.IsButton1Down || _keyboardService.IsCloseAppleKeyDown || + (settings.UseKeyboard && (settings.Key.Button1 > 0) && _keyboardService.IsKeyDown(settings.Key.Button1))); + } + + public bool ReadButton2() + { + var settings = Machine.Settings.GamePort; + + return (_gamePortService.IsButton2Down || + (settings.UseKeyboard && (settings.Key.Button2 > 0) && _keyboardService.IsKeyDown(settings.Key.Button2))); + } + + [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] + public void TriggerTimers() + { + int paddle0 = _gamePortService.Paddle0; + int paddle1 = _gamePortService.Paddle1; + int paddle2 = _gamePortService.Paddle2; + int paddle3 = _gamePortService.Paddle3; + + var settings = Machine.Settings.GamePort; + + if (settings.UseKeyboard) // override + { + if (((settings.Key.Joystick0.UpLeft > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick0.UpLeft)) || + ((settings.Key.Joystick0.Left > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick0.Left)) || + ((settings.Key.Joystick0.DownLeft > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick0.DownLeft))) + { + paddle0 -= 128; + } + if (((settings.Key.Joystick0.UpRight > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick0.UpRight)) || + ((settings.Key.Joystick0.Right > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick0.Right)) || + ((settings.Key.Joystick0.DownRight > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick0.DownRight))) + { + paddle0 += 128; + } + if (((settings.Key.Joystick0.UpLeft > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick0.UpLeft)) || + ((settings.Key.Joystick0.Up > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick0.Up)) || + ((settings.Key.Joystick0.UpRight > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick0.UpRight))) + { + paddle1 -= 128; + } + if (((settings.Key.Joystick0.DownLeft > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick0.DownLeft)) || + ((settings.Key.Joystick0.Down > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick0.Down)) || + ((settings.Key.Joystick0.DownRight > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick0.DownRight))) + { + paddle1 += 128; + } + if (((settings.Key.Joystick1.UpLeft > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick1.UpLeft)) || + ((settings.Key.Joystick1.Left > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick1.Left)) || + ((settings.Key.Joystick1.DownLeft > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick1.DownLeft))) + { + paddle2 -= 128; + } + if (((settings.Key.Joystick1.UpRight > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick1.UpRight)) || + ((settings.Key.Joystick1.Right > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick1.Right)) || + ((settings.Key.Joystick1.DownRight > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick1.DownRight))) + { + paddle2 += 128; + } + if (((settings.Key.Joystick1.UpLeft > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick1.UpLeft)) || + ((settings.Key.Joystick1.Up > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick1.Up)) || + ((settings.Key.Joystick1.UpRight > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick1.UpRight))) + { + paddle3 -= 128; + } + if (((settings.Key.Joystick1.DownLeft > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick1.DownLeft)) || + ((settings.Key.Joystick1.Down > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick1.Down)) || + ((settings.Key.Joystick1.DownRight > 0) && _keyboardService.IsKeyDown(settings.Key.Joystick1.DownRight))) + { + paddle3 += 128; + } + } + + Paddle0Strobe = true; + Paddle1Strobe = true; + Paddle2Strobe = true; + Paddle3Strobe = true; + + Machine.Events.AddEvent(MathHelpers.ClampByte(paddle0) * CyclesPerValue, _resetPaddle0StrobeEvent); // [7-29] + Machine.Events.AddEvent(MathHelpers.ClampByte(paddle1) * CyclesPerValue, _resetPaddle1StrobeEvent); + Machine.Events.AddEvent(MathHelpers.ClampByte(paddle2) * CyclesPerValue, _resetPaddle2StrobeEvent); + Machine.Events.AddEvent(MathHelpers.ClampByte(paddle3) * CyclesPerValue, _resetPaddle3StrobeEvent); + } + + private void ResetPaddle0StrobeEvent() + { + Paddle0Strobe = false; + } + + private void ResetPaddle1StrobeEvent() + { + Paddle1Strobe = false; + } + + private void ResetPaddle2StrobeEvent() + { + Paddle2Strobe = false; + } + + private void ResetPaddle3StrobeEvent() + { + Paddle3Strobe = false; + } + + public bool Paddle0Strobe { get; private set; } + public bool Paddle1Strobe { get; private set; } + public bool Paddle2Strobe { get; private set; } + public bool Paddle3Strobe { get; private set; } + + private const int CyclesPerValue = 11; + + private Action _resetPaddle0StrobeEvent; + private Action _resetPaddle1StrobeEvent; + private Action _resetPaddle2StrobeEvent; + private Action _resetPaddle3StrobeEvent; + + private KeyboardService _keyboardService; + private GamePortService _gamePortService; + } +} diff --git a/Virtu/Keyboard.cs b/Virtu/Keyboard.cs index ef9584c..670f677 100644 --- a/Virtu/Keyboard.cs +++ b/Virtu/Keyboard.cs @@ -1,133 +1,133 @@ -using System; -using System.Diagnostics.CodeAnalysis; -using Jellyfish.Virtu.Services; -using Jellyfish.Virtu.Settings; - -namespace Jellyfish.Virtu -{ - public sealed class Keyboard : MachineComponent - { - public Keyboard(Machine machine) : - base(machine) - { - } - - public override void Initialize() - { - _keyboardService = Machine.Services.GetService(); - _gamePortService = Machine.Services.GetService(); - - _keyboardService.AsciiKeyDown += (sender, e) => Latch = e.AsciiKey; - } - - [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] - public int ReadLatch() - { - if (Strobe) - { - return Latch; - } - - KeyboardSettings settings = Machine.Settings.Keyboard; - - if (settings.UseGamePort) - { - if ((settings.Key.Joystick0.UpLeft > 0) && _gamePortService.Joystick0.IsUp && _gamePortService.Joystick0.IsLeft) - { - Latch = settings.Key.Joystick0.UpLeft; - } - else if ((settings.Key.Joystick0.UpRight > 0) && _gamePortService.Joystick0.IsUp && _gamePortService.Joystick0.IsRight) - { - Latch = settings.Key.Joystick0.UpRight; - } - else if ((settings.Key.Joystick0.DownLeft > 0) && _gamePortService.Joystick0.IsDown && _gamePortService.Joystick0.IsLeft) - { - Latch = settings.Key.Joystick0.DownLeft; - } - else if ((settings.Key.Joystick0.DownRight > 0) && _gamePortService.Joystick0.IsDown && _gamePortService.Joystick0.IsRight) - { - Latch = settings.Key.Joystick0.DownRight; - } - else if ((settings.Key.Joystick0.Up > 0) && _gamePortService.Joystick0.IsUp) - { - Latch = settings.Key.Joystick0.Up; - } - else if ((settings.Key.Joystick0.Left > 0) && _gamePortService.Joystick0.IsLeft) - { - Latch = settings.Key.Joystick0.Left; - } - else if ((settings.Key.Joystick0.Right > 0) && _gamePortService.Joystick0.IsRight) - { - Latch = settings.Key.Joystick0.Right; - } - else if ((settings.Key.Joystick0.Down > 0) && _gamePortService.Joystick0.IsDown) - { - Latch = settings.Key.Joystick0.Down; - } - - if ((settings.Key.Joystick1.UpLeft > 0) && _gamePortService.Joystick1.IsUp && _gamePortService.Joystick1.IsLeft) // override - { - Latch = settings.Key.Joystick1.UpLeft; - } - else if ((settings.Key.Joystick1.UpRight > 0) && _gamePortService.Joystick1.IsUp && _gamePortService.Joystick1.IsRight) - { - Latch = settings.Key.Joystick1.UpRight; - } - else if ((settings.Key.Joystick1.DownLeft > 0) && _gamePortService.Joystick1.IsDown && _gamePortService.Joystick1.IsLeft) - { - Latch = settings.Key.Joystick1.DownLeft; - } - else if ((settings.Key.Joystick1.DownRight > 0) && _gamePortService.Joystick1.IsDown && _gamePortService.Joystick1.IsRight) - { - Latch = settings.Key.Joystick1.DownRight; - } - else if ((settings.Key.Joystick1.Up > 0) && _gamePortService.Joystick1.IsUp) - { - Latch = settings.Key.Joystick1.Up; - } - else if ((settings.Key.Joystick1.Left > 0) && _gamePortService.Joystick1.IsLeft) - { - Latch = settings.Key.Joystick1.Left; - } - else if ((settings.Key.Joystick1.Right > 0) && _gamePortService.Joystick1.IsRight) - { - Latch = settings.Key.Joystick1.Right; - } - else if ((settings.Key.Joystick1.Down > 0) && _gamePortService.Joystick1.IsDown) - { - Latch = settings.Key.Joystick1.Down; - } - - if ((settings.Key.Button0 > 0) && _gamePortService.IsButton0Down) // override - { - Latch = settings.Key.Button0; - } - else if ((settings.Key.Button1 > 0) && _gamePortService.IsButton1Down) - { - Latch = settings.Key.Button1; - } - else if ((settings.Key.Button2 > 0) && _gamePortService.IsButton2Down) - { - Latch = settings.Key.Button2; - } - } - - return Latch; - } - - public void ResetStrobe() - { - Strobe = false; - } - - public bool IsAnyKeyDown { get { return _keyboardService.IsAnyKeyDown; } } - public bool Strobe { get; private set; } - - private int Latch { get { return _latch; } set { _latch = value; Strobe = true; } } - - private KeyboardService _keyboardService; - private GamePortService _gamePortService; - - private int _latch; - } -} +using System; +using System.Diagnostics.CodeAnalysis; +using Jellyfish.Virtu.Services; +using Jellyfish.Virtu.Settings; + +namespace Jellyfish.Virtu +{ + public sealed class Keyboard : MachineComponent + { + public Keyboard(Machine machine) : + base(machine) + { + } + + public override void Initialize() + { + _keyboardService = Machine.Services.GetService(); + _gamePortService = Machine.Services.GetService(); + + _keyboardService.AsciiKeyDown += (sender, e) => Latch = e.AsciiKey; + } + + [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] + public int ReadLatch() + { + if (Strobe) + { + return Latch; + } + + var settings = Machine.Settings.Keyboard; + + if (settings.UseGamePort) + { + if ((settings.Key.Joystick0.UpLeft > 0) && _gamePortService.Joystick0.IsUp && _gamePortService.Joystick0.IsLeft) + { + Latch = settings.Key.Joystick0.UpLeft; + } + else if ((settings.Key.Joystick0.UpRight > 0) && _gamePortService.Joystick0.IsUp && _gamePortService.Joystick0.IsRight) + { + Latch = settings.Key.Joystick0.UpRight; + } + else if ((settings.Key.Joystick0.DownLeft > 0) && _gamePortService.Joystick0.IsDown && _gamePortService.Joystick0.IsLeft) + { + Latch = settings.Key.Joystick0.DownLeft; + } + else if ((settings.Key.Joystick0.DownRight > 0) && _gamePortService.Joystick0.IsDown && _gamePortService.Joystick0.IsRight) + { + Latch = settings.Key.Joystick0.DownRight; + } + else if ((settings.Key.Joystick0.Up > 0) && _gamePortService.Joystick0.IsUp) + { + Latch = settings.Key.Joystick0.Up; + } + else if ((settings.Key.Joystick0.Left > 0) && _gamePortService.Joystick0.IsLeft) + { + Latch = settings.Key.Joystick0.Left; + } + else if ((settings.Key.Joystick0.Right > 0) && _gamePortService.Joystick0.IsRight) + { + Latch = settings.Key.Joystick0.Right; + } + else if ((settings.Key.Joystick0.Down > 0) && _gamePortService.Joystick0.IsDown) + { + Latch = settings.Key.Joystick0.Down; + } + + if ((settings.Key.Joystick1.UpLeft > 0) && _gamePortService.Joystick1.IsUp && _gamePortService.Joystick1.IsLeft) // override + { + Latch = settings.Key.Joystick1.UpLeft; + } + else if ((settings.Key.Joystick1.UpRight > 0) && _gamePortService.Joystick1.IsUp && _gamePortService.Joystick1.IsRight) + { + Latch = settings.Key.Joystick1.UpRight; + } + else if ((settings.Key.Joystick1.DownLeft > 0) && _gamePortService.Joystick1.IsDown && _gamePortService.Joystick1.IsLeft) + { + Latch = settings.Key.Joystick1.DownLeft; + } + else if ((settings.Key.Joystick1.DownRight > 0) && _gamePortService.Joystick1.IsDown && _gamePortService.Joystick1.IsRight) + { + Latch = settings.Key.Joystick1.DownRight; + } + else if ((settings.Key.Joystick1.Up > 0) && _gamePortService.Joystick1.IsUp) + { + Latch = settings.Key.Joystick1.Up; + } + else if ((settings.Key.Joystick1.Left > 0) && _gamePortService.Joystick1.IsLeft) + { + Latch = settings.Key.Joystick1.Left; + } + else if ((settings.Key.Joystick1.Right > 0) && _gamePortService.Joystick1.IsRight) + { + Latch = settings.Key.Joystick1.Right; + } + else if ((settings.Key.Joystick1.Down > 0) && _gamePortService.Joystick1.IsDown) + { + Latch = settings.Key.Joystick1.Down; + } + + if ((settings.Key.Button0 > 0) && _gamePortService.IsButton0Down) // override + { + Latch = settings.Key.Button0; + } + else if ((settings.Key.Button1 > 0) && _gamePortService.IsButton1Down) + { + Latch = settings.Key.Button1; + } + else if ((settings.Key.Button2 > 0) && _gamePortService.IsButton2Down) + { + Latch = settings.Key.Button2; + } + } + + return Latch; + } + + public void ResetStrobe() + { + Strobe = false; + } + + public bool IsAnyKeyDown { get { return _keyboardService.IsAnyKeyDown; } } + public bool Strobe { get; private set; } + + private int Latch { get { return _latch; } set { _latch = value; Strobe = true; } } + + private KeyboardService _keyboardService; + private GamePortService _gamePortService; + + private int _latch; + } +} diff --git a/Virtu/Machine.cs b/Virtu/Machine.cs index 77b05a4..e6c8dbe 100644 --- a/Virtu/Machine.cs +++ b/Virtu/Machine.cs @@ -1,128 +1,128 @@ -using System; -using System.Collections.ObjectModel; -using System.Threading; -using Jellyfish.Library; -using Jellyfish.Virtu.Services; -using Jellyfish.Virtu.Settings; - -namespace Jellyfish.Virtu -{ - public enum MachineState { Stopped = 0, Starting, Running, Pausing, Paused, Stopping } - - public sealed class Machine : IDisposable - { - public Machine() - { - Events = new MachineEvents(); - Services = new MachineServices(); - Settings = new MachineSettings(); - - Cpu = new Cpu(this); - Memory = new Memory(this); - DiskII = new DiskII(this); - Keyboard = new Keyboard(this); - GamePort = new GamePort(this); - Cassette = new Cassette(this); - Speaker = new Speaker(this); - Video = new Video(this); - Components = new Collection { Cpu, Memory, DiskII, Keyboard, GamePort, Cassette, Speaker, Video }; - - Thread = new Thread(Run) { Name = "Machine" }; - } - - public void Dispose() - { - _pauseEvent.Close(); - _unpauseEvent.Close(); - } - - public void Reset() - { - Components.ForEach(component => component.Reset()); // while machine starting or paused - } - - public void Start() - { - _storageService = Services.GetService(); - _storageService.Load(MachineSettings.FileName, stream => Settings.Deserialize(stream)); - - State = MachineState.Starting; - Services.ForEach(service => service.Start()); - - Thread.Start(); - } - - public void Pause() - { - State = MachineState.Pausing; - _pauseEvent.WaitOne(); - State = MachineState.Paused; - } - - public void Unpause() - { - State = MachineState.Running; - _unpauseEvent.Set(); - } - - public void Stop() - { - State = MachineState.Stopping; - Services.ForEach(service => service.Stop()); - - _pauseEvent.Set(); - _unpauseEvent.Set(); - Thread.Join(); - State = MachineState.Stopped; - - _storageService.Save(MachineSettings.FileName, stream => Settings.Serialize(stream)); - } - - private void Run() // machine thread - { - Components.ForEach(component => component.Initialize()); - Reset(); - - State = MachineState.Running; - do - { - do - { - Events.HandleEvents(Cpu.Execute()); - } - while (State == MachineState.Running); - - if (State == MachineState.Pausing) - { - _pauseEvent.Set(); - _unpauseEvent.WaitOne(); - } - } - while (State != MachineState.Stopping); - - Components.ForEach(component => component.Uninitialize()); - } - - public MachineEvents Events { get; private set; } - public MachineServices Services { get; private set; } - public MachineSettings Settings { get; private set; } - public MachineState State { get; private set; } - - public Cpu Cpu { get; private set; } - public Memory Memory { get; private set; } - public DiskII DiskII { get; private set; } - public Keyboard Keyboard { get; private set; } - public GamePort GamePort { get; private set; } - public Cassette Cassette { get; private set; } - public Speaker Speaker { get; private set; } - public Video Video { get; private set; } - public Collection Components { get; private set; } - - public Thread Thread { get; private set; } - - private AutoResetEvent _pauseEvent = new AutoResetEvent(false); - private AutoResetEvent _unpauseEvent = new AutoResetEvent(false); - - private StorageService _storageService; - } -} +using System; +using System.Collections.ObjectModel; +using System.Threading; +using Jellyfish.Library; +using Jellyfish.Virtu.Services; +using Jellyfish.Virtu.Settings; + +namespace Jellyfish.Virtu +{ + public enum MachineState { Stopped = 0, Starting, Running, Pausing, Paused, Stopping } + + public sealed class Machine : IDisposable + { + public Machine() + { + Events = new MachineEvents(); + Services = new MachineServices(); + Settings = new MachineSettings(); + + Cpu = new Cpu(this); + Memory = new Memory(this); + DiskII = new DiskII(this); + Keyboard = new Keyboard(this); + GamePort = new GamePort(this); + Cassette = new Cassette(this); + Speaker = new Speaker(this); + Video = new Video(this); + Components = new Collection { Cpu, Memory, DiskII, Keyboard, GamePort, Cassette, Speaker, Video }; + + Thread = new Thread(Run) { Name = "Machine" }; + } + + public void Dispose() + { + _pauseEvent.Close(); + _unpauseEvent.Close(); + } + + public void Reset() + { + Components.ForEach(component => component.Reset()); // while machine starting or paused + } + + public void Start() + { + _storageService = Services.GetService(); + _storageService.Load(MachineSettings.FileName, stream => Settings.Deserialize(stream)); + + State = MachineState.Starting; + Services.ForEach(service => service.Start()); + + Thread.Start(); + } + + public void Pause() + { + State = MachineState.Pausing; + _pauseEvent.WaitOne(); + State = MachineState.Paused; + } + + public void Unpause() + { + State = MachineState.Running; + _unpauseEvent.Set(); + } + + public void Stop() + { + State = MachineState.Stopping; + Services.ForEach(service => service.Stop()); + + _pauseEvent.Set(); + _unpauseEvent.Set(); + Thread.Join(); + State = MachineState.Stopped; + + _storageService.Save(MachineSettings.FileName, stream => Settings.Serialize(stream)); + } + + private void Run() // machine thread + { + Components.ForEach(component => component.Initialize()); + Reset(); + + State = MachineState.Running; + do + { + do + { + Events.HandleEvents(Cpu.Execute()); + } + while (State == MachineState.Running); + + if (State == MachineState.Pausing) + { + _pauseEvent.Set(); + _unpauseEvent.WaitOne(); + } + } + while (State != MachineState.Stopping); + + Components.ForEach(component => component.Uninitialize()); + } + + public MachineEvents Events { get; private set; } + public MachineServices Services { get; private set; } + public MachineSettings Settings { get; private set; } + public MachineState State { get; private set; } + + public Cpu Cpu { get; private set; } + public Memory Memory { get; private set; } + public DiskII DiskII { get; private set; } + public Keyboard Keyboard { get; private set; } + public GamePort GamePort { get; private set; } + public Cassette Cassette { get; private set; } + public Speaker Speaker { get; private set; } + public Video Video { get; private set; } + public Collection Components { get; private set; } + + public Thread Thread { get; private set; } + + private AutoResetEvent _pauseEvent = new AutoResetEvent(false); + private AutoResetEvent _unpauseEvent = new AutoResetEvent(false); + + private StorageService _storageService; + } +} diff --git a/Virtu/MachineComponent.cs b/Virtu/MachineComponent.cs index 44e1078..c5f0453 100644 --- a/Virtu/MachineComponent.cs +++ b/Virtu/MachineComponent.cs @@ -1,24 +1,24 @@ -namespace Jellyfish.Virtu -{ - public abstract class MachineComponent - { - protected MachineComponent(Machine machine) - { - Machine = machine; - } - - public virtual void Initialize() - { - } - - public virtual void Reset() - { - } - - public virtual void Uninitialize() - { - } - - protected Machine Machine { get; private set; } - } -} +namespace Jellyfish.Virtu +{ + public abstract class MachineComponent + { + protected MachineComponent(Machine machine) + { + Machine = machine; + } + + public virtual void Initialize() + { + } + + public virtual void Reset() + { + } + + public virtual void Uninitialize() + { + } + + protected Machine Machine { get; private set; } + } +} diff --git a/Virtu/MachineEvents.cs b/Virtu/MachineEvents.cs index 160a4ca..da393b0 100644 --- a/Virtu/MachineEvents.cs +++ b/Virtu/MachineEvents.cs @@ -1,107 +1,107 @@ -using System; -using System.Collections.Generic; -using System.Globalization; - -namespace Jellyfish.Virtu -{ - public sealed class MachineEvent - { - public MachineEvent(int delta, Action action) - { - Delta = delta; - Action = action; - } - - public override string ToString() - { - return string.Format(CultureInfo.CurrentCulture, "Delta = {0} Action = {{{1}.{2}}}", Delta, Action.Method.DeclaringType.Name, Action.Method.Name); - } - - public int Delta { get; set; } - public Action Action { get; set; } - } - - public sealed class MachineEvents - { - public void AddEvent(int delta, Action action) - { - LinkedListNode node = _used.First; - for (; node != null; node = node.Next) - { - if (delta < node.Value.Delta) - { - node.Value.Delta -= delta; - break; - } - if (node.Value.Delta > 0) - { - delta -= node.Value.Delta; - } - } - - LinkedListNode newNode = _free.First; - if (newNode != null) - { - _free.RemoveFirst(); - newNode.Value.Delta = delta; - newNode.Value.Action = action; - } - else - { - newNode = new LinkedListNode(new MachineEvent(delta, action)); - } - - if (node != null) - { - _used.AddBefore(node, newNode); - } - else - { - _used.AddLast(newNode); - } - } - - public int FindEvent(Action action) - { - int delta = 0; - - for (LinkedListNode node = _used.First; node != null; node = node.Next) - { - delta += node.Value.Delta; - if (object.ReferenceEquals(node.Value.Action, action)) // assumes delegate cached - { - return delta; - } - } - - return 0; - } - - public void HandleEvents(int delta) - { - LinkedListNode node = _used.First; - node.Value.Delta -= delta; - - while (node.Value.Delta <= 0) - { - node.Value.Action(); - RemoveEvent(node); - node = _used.First; - } - } - - private void RemoveEvent(LinkedListNode node) - { - if (node.Next != null) - { - node.Next.Value.Delta += node.Value.Delta; - } - - _used.Remove(node); - _free.AddFirst(node); // cache node; avoids garbage - } - - private LinkedList _used = new LinkedList(); - private LinkedList _free = new LinkedList(); - } -} +using System; +using System.Collections.Generic; +using System.Globalization; + +namespace Jellyfish.Virtu +{ + public sealed class MachineEvent + { + public MachineEvent(int delta, Action action) + { + Delta = delta; + Action = action; + } + + public override string ToString() + { + return string.Format(CultureInfo.CurrentCulture, "Delta = {0} Action = {{{1}.{2}}}", Delta, Action.Method.DeclaringType.Name, Action.Method.Name); + } + + public int Delta { get; set; } + public Action Action { get; set; } + } + + public sealed class MachineEvents + { + public void AddEvent(int delta, Action action) + { + LinkedListNode node = _used.First; + for (; node != null; node = node.Next) + { + if (delta < node.Value.Delta) + { + node.Value.Delta -= delta; + break; + } + if (node.Value.Delta > 0) + { + delta -= node.Value.Delta; + } + } + + LinkedListNode newNode = _free.First; + if (newNode != null) + { + _free.RemoveFirst(); + newNode.Value.Delta = delta; + newNode.Value.Action = action; + } + else + { + newNode = new LinkedListNode(new MachineEvent(delta, action)); + } + + if (node != null) + { + _used.AddBefore(node, newNode); + } + else + { + _used.AddLast(newNode); + } + } + + public int FindEvent(Action action) + { + int delta = 0; + + for (LinkedListNode node = _used.First; node != null; node = node.Next) + { + delta += node.Value.Delta; + if (object.ReferenceEquals(node.Value.Action, action)) // assumes delegate cached + { + return delta; + } + } + + return 0; + } + + public void HandleEvents(int delta) + { + LinkedListNode node = _used.First; + node.Value.Delta -= delta; + + while (node.Value.Delta <= 0) + { + node.Value.Action(); + RemoveEvent(node); + node = _used.First; + } + } + + private void RemoveEvent(LinkedListNode node) + { + if (node.Next != null) + { + node.Next.Value.Delta += node.Value.Delta; + } + + _used.Remove(node); + _free.AddFirst(node); // cache node; avoids garbage + } + + private LinkedList _used = new LinkedList(); + private LinkedList _free = new LinkedList(); + } +} diff --git a/Virtu/MachineSettings.cs b/Virtu/MachineSettings.cs index 704bd7c..f0ef767 100644 --- a/Virtu/MachineSettings.cs +++ b/Virtu/MachineSettings.cs @@ -1,393 +1,393 @@ -using System; -using System.Diagnostics.CodeAnalysis; -using System.IO; -using System.Xml; -using System.Xml.Linq; - -namespace Jellyfish.Virtu.Settings -{ - public sealed class MachineSettings - { - public MachineSettings() - { - Cpu = new CpuSettings { Is65C02 = true, IsThrottled = true, Multiplier = 1 }; - DiskII = new DiskIISettings - { - Disk1 = new DiskSettings { Name = string.Empty, IsWriteProtected = false }, - Disk2 = new DiskSettings { Name = string.Empty, IsWriteProtected = false } - }; - Keyboard = new KeyboardSettings - { - UseGamePort = false, - Key = new KeySettings - { - Joystick0 = new JoystickSettings { UpLeft = 0, Up = 'I', UpRight = 0, Left = 'J', Right = 'L', DownLeft = 0, Down = 'K', DownRight = 0 }, - Joystick1 = new JoystickSettings { UpLeft = 0, Up = 'E', UpRight = 0, Left = 'S', Right = 'F', DownLeft = 0, Down = 'D', DownRight = 0 }, - Button0 = 0, Button1 = 0, Button2 = 0 - } - }; - GamePort = new GamePortSettings - { - UseKeyboard = false, - Key = new KeySettings - { - Joystick0 = new JoystickSettings { UpLeft = 0, Up = 0, UpRight = 0, Left = 0, Right = 0, DownLeft = 0, Down = 0, DownRight = 0 }, - Joystick1 = new JoystickSettings { UpLeft = 0, Up = 0, UpRight = 0, Left = 0, Right = 0, DownLeft = 0, Down = 0, DownRight = 0 }, - Button0 = 0, Button1 = 0, Button2 = 0 - } - }; - Video = new VideoSettings - { - IsFullScreen = false, IsMonochrome = false, ScannerOptions = ScannerOptions.None, - Color = new ColorSettings - { - Black = 0x000000, - DarkBlue = 0x000099, - DarkGreen = 0x117722, - MediumBlue = 0x0000FF, - Brown = 0x885500, - LightGrey = 0x99AAAA, - Green = 0x00EE11, - Aquamarine = 0x55FFAA, - DeepRed = 0xFF1111, - Purple = 0xDD00DD, - DarkGrey = 0x445555, - LightBlue = 0x33AAFF, - Orange = 0xFF4411, - Pink = 0xFF9988, - Yellow = 0xFFFF11, - White = 0xFFFFFF, - Monochrome = 0x00AA00 - } - }; - } - - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] - public void Deserialize(Stream stream) - { - try - { - using (XmlReader reader = XmlReader.Create(stream)) - { - XNamespace ns = Namespace; - XElement root = XElement.Load(reader); - XElement cpu = root.Element(ns + "Cpu"); - Cpu = new CpuSettings - { - Is65C02 = (bool)cpu.Attribute("Is65C02"), - IsThrottled = (bool)cpu.Attribute("IsThrottled"), - Multiplier = (int)cpu.Attribute("Multiplier") - }; - XElement diskII = root.Element(ns + "DiskII"); - XElement disk1 = diskII.Element(ns + "Disk1"); - XElement disk2 = diskII.Element(ns + "Disk2"); - DiskII = new DiskIISettings - { - Disk1 = new DiskSettings - { - Name = (string)disk1.Attribute("Name") ?? string.Empty, - IsWriteProtected = (bool)disk1.Attribute("IsWriteProtected") - }, - Disk2 = new DiskSettings - { - Name = (string)disk2.Attribute("Name") ?? string.Empty, - IsWriteProtected = (bool)disk2.Attribute("IsWriteProtected") - }, - }; - XElement keyboard = root.Element(ns + "Keyboard"); - XElement key = keyboard.Element(ns + "Key"); - XElement joystick0 = key.Element(ns + "Joystick0"); - XElement joystick1 = key.Element(ns + "Joystick1"); - XElement buttons = key.Element(ns + "Buttons"); - Keyboard = new KeyboardSettings - { - UseGamePort = (bool)keyboard.Attribute("UseGamePort"), - Key = new KeySettings - { - Joystick0 = new JoystickSettings - { - UpLeft = (int)joystick0.Attribute("UpLeft"), - Up = (int)joystick0.Attribute("Up"), - UpRight = (int)joystick0.Attribute("UpRight"), - Left = (int)joystick0.Attribute("Left"), - Right = (int)joystick0.Attribute("Right"), - DownLeft = (int)joystick0.Attribute("DownLeft"), - Down = (int)joystick0.Attribute("Down"), - DownRight = (int)joystick0.Attribute("DownRight") - }, - Joystick1 = new JoystickSettings - { - UpLeft = (int)joystick1.Attribute("UpLeft"), - Up = (int)joystick1.Attribute("Up"), - UpRight = (int)joystick1.Attribute("UpRight"), - Left = (int)joystick1.Attribute("Left"), - Right = (int)joystick1.Attribute("Right"), - DownLeft = (int)joystick1.Attribute("DownLeft"), - Down = (int)joystick1.Attribute("Down"), - DownRight = (int)joystick1.Attribute("DownRight") - }, - Button0 = (int)buttons.Attribute("Button0"), - Button1 = (int)buttons.Attribute("Button1"), - Button2 = (int)buttons.Attribute("Button2") - } - }; - XElement gamePort = root.Element(ns + "GamePort"); - key = gamePort.Element(ns + "Key"); - joystick0 = key.Element(ns + "Joystick0"); - joystick1 = key.Element(ns + "Joystick1"); - buttons = key.Element(ns + "Buttons"); - GamePort = new GamePortSettings - { - UseKeyboard = (bool)gamePort.Attribute("UseKeyboard"), - Key = new KeySettings - { - Joystick0 = new JoystickSettings - { - UpLeft = (int)joystick0.Attribute("UpLeft"), - Up = (int)joystick0.Attribute("Up"), - UpRight = (int)joystick0.Attribute("UpRight"), - Left = (int)joystick0.Attribute("Left"), - Right = (int)joystick0.Attribute("Right"), - DownLeft = (int)joystick0.Attribute("DownLeft"), - Down = (int)joystick0.Attribute("Down"), - DownRight = (int)joystick0.Attribute("DownRight") - }, - Joystick1 = new JoystickSettings - { - UpLeft = (int)joystick1.Attribute("UpLeft"), - Up = (int)joystick1.Attribute("Up"), - UpRight = (int)joystick1.Attribute("UpRight"), - Left = (int)joystick1.Attribute("Left"), - Right = (int)joystick1.Attribute("Right"), - DownLeft = (int)joystick1.Attribute("DownLeft"), - Down = (int)joystick1.Attribute("Down"), - DownRight = (int)joystick1.Attribute("DownRight") - }, - Button0 = (int)buttons.Attribute("Button0"), - Button1 = (int)buttons.Attribute("Button1"), - Button2 = (int)buttons.Attribute("Button2") - } - }; - XElement video = root.Element(ns + "Video"); - XElement color = video.Element(ns + "Color"); - Video = new VideoSettings - { - IsFullScreen = (bool)video.Attribute("IsFullScreen"), - IsMonochrome = (bool)video.Attribute("IsMonochrome"), - ScannerOptions = (ScannerOptions)Enum.Parse(typeof(ScannerOptions), (string)video.Attribute("ScannerOptions"), true), - Color = new ColorSettings - { - Black = (uint)color.Attribute("Black"), - DarkBlue = (uint)color.Attribute("DarkBlue"), - DarkGreen = (uint)color.Attribute("DarkGreen"), - MediumBlue = (uint)color.Attribute("MediumBlue"), - Brown = (uint)color.Attribute("Brown"), - LightGrey = (uint)color.Attribute("LightGrey"), - Green = (uint)color.Attribute("Green"), - Aquamarine = (uint)color.Attribute("Aquamarine"), - DeepRed = (uint)color.Attribute("DeepRed"), - Purple = (uint)color.Attribute("Purple"), - DarkGrey = (uint)color.Attribute("DarkGrey"), - LightBlue = (uint)color.Attribute("LightBlue"), - Orange = (uint)color.Attribute("Orange"), - Pink = (uint)color.Attribute("Pink"), - Yellow = (uint)color.Attribute("Yellow"), - White = (uint)color.Attribute("White"), - Monochrome = (uint)color.Attribute("Monochrome") - } - }; - } - } - catch (Exception) - { - } - } - - public void Serialize(Stream stream) - { - XNamespace ns = Namespace; - XElement xml = new XElement(ns + "MachineSettings", - new XElement(ns + "Cpu", - new XAttribute("Is65C02", Cpu.Is65C02), - new XAttribute("IsThrottled", Cpu.IsThrottled), - new XAttribute("Multiplier", Cpu.Multiplier)), - new XElement(ns + "DiskII", - new XElement(ns + "Disk1", - new XAttribute("Name", DiskII.Disk1.Name), - new XAttribute("IsWriteProtected", DiskII.Disk1.IsWriteProtected)), - new XElement(ns + "Disk2", - new XAttribute("Name", DiskII.Disk2.Name), - new XAttribute("IsWriteProtected", DiskII.Disk2.IsWriteProtected))), - new XElement(ns + "Keyboard", - new XAttribute("UseGamePort", Keyboard.UseGamePort), - new XElement(ns + "Key", - new XElement(ns + "Joystick0", - new XAttribute("UpLeft", Keyboard.Key.Joystick0.UpLeft), - new XAttribute("Up", Keyboard.Key.Joystick0.Up), - new XAttribute("UpRight", Keyboard.Key.Joystick0.UpRight), - new XAttribute("Left", Keyboard.Key.Joystick0.Left), - new XAttribute("Right", Keyboard.Key.Joystick0.Right), - new XAttribute("DownLeft", Keyboard.Key.Joystick0.DownLeft), - new XAttribute("Down", Keyboard.Key.Joystick0.Down), - new XAttribute("DownRight", Keyboard.Key.Joystick0.DownRight)), - new XElement(ns + "Joystick1", - new XAttribute("UpLeft", Keyboard.Key.Joystick1.UpLeft), - new XAttribute("Up", Keyboard.Key.Joystick1.Up), - new XAttribute("UpRight", Keyboard.Key.Joystick1.UpRight), - new XAttribute("Left", Keyboard.Key.Joystick1.Left), - new XAttribute("Right", Keyboard.Key.Joystick1.Right), - new XAttribute("DownLeft", Keyboard.Key.Joystick1.DownLeft), - new XAttribute("Down", Keyboard.Key.Joystick1.Down), - new XAttribute("DownRight", Keyboard.Key.Joystick1.DownRight)), - new XElement(ns + "Buttons", - new XAttribute("Button0", Keyboard.Key.Button0), - new XAttribute("Button1", Keyboard.Key.Button1), - new XAttribute("Button2", Keyboard.Key.Button2)))), - new XElement(ns + "GamePort", - new XAttribute("UseKeyboard", GamePort.UseKeyboard), - new XElement(ns + "Key", - new XElement(ns + "Joystick0", - new XAttribute("UpLeft", GamePort.Key.Joystick0.UpLeft), - new XAttribute("Up", GamePort.Key.Joystick0.Up), - new XAttribute("UpRight", GamePort.Key.Joystick0.UpRight), - new XAttribute("Left", GamePort.Key.Joystick0.Left), - new XAttribute("Right", GamePort.Key.Joystick0.Right), - new XAttribute("DownLeft", GamePort.Key.Joystick0.DownLeft), - new XAttribute("Down", GamePort.Key.Joystick0.Down), - new XAttribute("DownRight", GamePort.Key.Joystick0.DownRight)), - new XElement(ns + "Joystick1", - new XAttribute("UpLeft", GamePort.Key.Joystick1.UpLeft), - new XAttribute("Up", GamePort.Key.Joystick1.Up), - new XAttribute("UpRight", GamePort.Key.Joystick1.UpRight), - new XAttribute("Left", GamePort.Key.Joystick1.Left), - new XAttribute("Right", GamePort.Key.Joystick1.Right), - new XAttribute("DownLeft", GamePort.Key.Joystick1.DownLeft), - new XAttribute("Down", GamePort.Key.Joystick1.Down), - new XAttribute("DownRight", GamePort.Key.Joystick1.DownRight)), - new XElement(ns + "Buttons", - new XAttribute("Button0", Keyboard.Key.Button0), - new XAttribute("Button1", Keyboard.Key.Button1), - new XAttribute("Button2", Keyboard.Key.Button2)))), - new XElement(ns + "Video", - new XAttribute("IsFullScreen", Video.IsFullScreen), - new XAttribute("IsMonochrome", Video.IsMonochrome), - new XAttribute("ScannerOptions", Video.ScannerOptions), - new XElement(ns + "Color", - new XAttribute("Black", Video.Color.Black), - new XAttribute("DarkBlue", Video.Color.DarkBlue), - new XAttribute("DarkGreen", Video.Color.DarkGreen), - new XAttribute("MediumBlue", Video.Color.MediumBlue), - new XAttribute("Brown", Video.Color.Brown), - new XAttribute("LightGrey", Video.Color.LightGrey), - new XAttribute("Green", Video.Color.Green), - new XAttribute("Aquamarine", Video.Color.Aquamarine), - new XAttribute("DeepRed", Video.Color.DeepRed), - new XAttribute("Purple", Video.Color.Purple), - new XAttribute("DarkGrey", Video.Color.DarkGrey), - new XAttribute("LightBlue", Video.Color.LightBlue), - new XAttribute("Orange", Video.Color.Orange), - new XAttribute("Pink", Video.Color.Pink), - new XAttribute("Yellow", Video.Color.Yellow), - new XAttribute("White", Video.Color.White), - new XAttribute("Monochrome", Video.Color.Monochrome)))); - - using (XmlWriter writer = XmlWriter.Create(stream)) - { - xml.WriteTo(writer); - } - } - - public CpuSettings Cpu { get; set; } - public DiskIISettings DiskII { get; set; } - public KeyboardSettings Keyboard { get; set; } - public GamePortSettings GamePort { get; set; } - public VideoSettings Video { get; set; } - - public const string FileName = "Settings.xml"; - public const string Namespace = "http://schemas.jellyfish.co.nz/virtu/settings"; - } - - public sealed class CpuSettings - { - public bool Is65C02 { get; set; } - public bool IsThrottled { get; set; } - public int Multiplier { get; set; } - } - - public sealed class DiskSettings - { - public string Name { get; set; } - public bool IsWriteProtected { get; set; } - }; - - public sealed class DiskIISettings - { - public DiskSettings Disk1 { get; set; } - public DiskSettings Disk2 { get; set; } - }; - - public sealed class JoystickSettings - { - public int UpLeft { get; set; } - public int Up { get; set; } - public int UpRight { get; set; } - public int Left { get; set; } - public int Right { get; set; } - public int DownLeft { get; set; } - public int Down { get; set; } - public int DownRight { get; set; } - }; - - public sealed class KeySettings - { - public JoystickSettings Joystick0 { get; set; } - public JoystickSettings Joystick1 { get; set; } - public int Button0 { get; set; } - public int Button1 { get; set; } - public int Button2 { get; set; } - }; - - public sealed class KeyboardSettings - { - public bool UseGamePort { get; set; } - public KeySettings Key { get; set; } - } - - public sealed class GamePortSettings - { - public bool UseKeyboard { get; set; } - public KeySettings Key { get; set; } - } - - public sealed class ColorSettings - { - public uint Black { get; set; } - public uint DarkBlue { get; set; } - public uint DarkGreen { get; set; } - public uint MediumBlue { get; set; } - public uint Brown { get; set; } - public uint LightGrey { get; set; } - public uint Green { get; set; } - public uint Aquamarine { get; set; } - public uint DeepRed { get; set; } - public uint Purple { get; set; } - public uint DarkGrey { get; set; } - public uint LightBlue { get; set; } - public uint Orange { get; set; } - public uint Pink { get; set; } - public uint Yellow { get; set; } - public uint White { get; set; } - public uint Monochrome { get; set; } - } - - [Flags] - public enum ScannerOptions { None = 0x0, AppleII = 0x1, Pal = 0x2 } // defaults to AppleIIe, Ntsc - - public sealed class VideoSettings - { - public bool IsFullScreen { get; set; } - public bool IsMonochrome { get; set; } - public ScannerOptions ScannerOptions { get; set; } - public ColorSettings Color { get; set; } - }; -} +using System; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Xml; +using System.Xml.Linq; + +namespace Jellyfish.Virtu.Settings +{ + public sealed class MachineSettings + { + public MachineSettings() + { + Cpu = new CpuSettings { Is65C02 = true, IsThrottled = true, Multiplier = 1 }; + DiskII = new DiskIISettings + { + Disk1 = new DiskSettings { Name = string.Empty, IsWriteProtected = false }, + Disk2 = new DiskSettings { Name = string.Empty, IsWriteProtected = false } + }; + Keyboard = new KeyboardSettings + { + UseGamePort = false, + Key = new KeySettings + { + Joystick0 = new JoystickSettings { UpLeft = 0, Up = 'I', UpRight = 0, Left = 'J', Right = 'L', DownLeft = 0, Down = 'K', DownRight = 0 }, + Joystick1 = new JoystickSettings { UpLeft = 0, Up = 'E', UpRight = 0, Left = 'S', Right = 'F', DownLeft = 0, Down = 'D', DownRight = 0 }, + Button0 = 0, Button1 = 0, Button2 = 0 + } + }; + GamePort = new GamePortSettings + { + UseKeyboard = false, + Key = new KeySettings + { + Joystick0 = new JoystickSettings { UpLeft = 0, Up = 0, UpRight = 0, Left = 0, Right = 0, DownLeft = 0, Down = 0, DownRight = 0 }, + Joystick1 = new JoystickSettings { UpLeft = 0, Up = 0, UpRight = 0, Left = 0, Right = 0, DownLeft = 0, Down = 0, DownRight = 0 }, + Button0 = 0, Button1 = 0, Button2 = 0 + } + }; + Video = new VideoSettings + { + IsFullScreen = false, IsMonochrome = false, ScannerOptions = ScannerOptions.None, + Color = new ColorSettings + { + Black = 0x000000, + DarkBlue = 0x000099, + DarkGreen = 0x117722, + MediumBlue = 0x0000FF, + Brown = 0x885500, + LightGrey = 0x99AAAA, + Green = 0x00EE11, + Aquamarine = 0x55FFAA, + DeepRed = 0xFF1111, + Purple = 0xDD00DD, + DarkGrey = 0x445555, + LightBlue = 0x33AAFF, + Orange = 0xFF4411, + Pink = 0xFF9988, + Yellow = 0xFFFF11, + White = 0xFFFFFF, + Monochrome = 0x00AA00 + } + }; + } + + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] + public void Deserialize(Stream stream) + { + try + { + using (var reader = XmlReader.Create(stream)) + { + var ns = Namespace; + var root = XElement.Load(reader); + var cpu = root.Element(ns + "Cpu"); + Cpu = new CpuSettings + { + Is65C02 = (bool)cpu.Attribute("Is65C02"), + IsThrottled = (bool)cpu.Attribute("IsThrottled"), + Multiplier = (int)cpu.Attribute("Multiplier") + }; + var diskII = root.Element(ns + "DiskII"); + var disk1 = diskII.Element(ns + "Disk1"); + var disk2 = diskII.Element(ns + "Disk2"); + DiskII = new DiskIISettings + { + Disk1 = new DiskSettings + { + Name = (string)disk1.Attribute("Name") ?? string.Empty, + IsWriteProtected = (bool)disk1.Attribute("IsWriteProtected") + }, + Disk2 = new DiskSettings + { + Name = (string)disk2.Attribute("Name") ?? string.Empty, + IsWriteProtected = (bool)disk2.Attribute("IsWriteProtected") + }, + }; + var keyboard = root.Element(ns + "Keyboard"); + var key = keyboard.Element(ns + "Key"); + var joystick0 = key.Element(ns + "Joystick0"); + var joystick1 = key.Element(ns + "Joystick1"); + var buttons = key.Element(ns + "Buttons"); + Keyboard = new KeyboardSettings + { + UseGamePort = (bool)keyboard.Attribute("UseGamePort"), + Key = new KeySettings + { + Joystick0 = new JoystickSettings + { + UpLeft = (int)joystick0.Attribute("UpLeft"), + Up = (int)joystick0.Attribute("Up"), + UpRight = (int)joystick0.Attribute("UpRight"), + Left = (int)joystick0.Attribute("Left"), + Right = (int)joystick0.Attribute("Right"), + DownLeft = (int)joystick0.Attribute("DownLeft"), + Down = (int)joystick0.Attribute("Down"), + DownRight = (int)joystick0.Attribute("DownRight") + }, + Joystick1 = new JoystickSettings + { + UpLeft = (int)joystick1.Attribute("UpLeft"), + Up = (int)joystick1.Attribute("Up"), + UpRight = (int)joystick1.Attribute("UpRight"), + Left = (int)joystick1.Attribute("Left"), + Right = (int)joystick1.Attribute("Right"), + DownLeft = (int)joystick1.Attribute("DownLeft"), + Down = (int)joystick1.Attribute("Down"), + DownRight = (int)joystick1.Attribute("DownRight") + }, + Button0 = (int)buttons.Attribute("Button0"), + Button1 = (int)buttons.Attribute("Button1"), + Button2 = (int)buttons.Attribute("Button2") + } + }; + var gamePort = root.Element(ns + "GamePort"); + key = gamePort.Element(ns + "Key"); + joystick0 = key.Element(ns + "Joystick0"); + joystick1 = key.Element(ns + "Joystick1"); + buttons = key.Element(ns + "Buttons"); + GamePort = new GamePortSettings + { + UseKeyboard = (bool)gamePort.Attribute("UseKeyboard"), + Key = new KeySettings + { + Joystick0 = new JoystickSettings + { + UpLeft = (int)joystick0.Attribute("UpLeft"), + Up = (int)joystick0.Attribute("Up"), + UpRight = (int)joystick0.Attribute("UpRight"), + Left = (int)joystick0.Attribute("Left"), + Right = (int)joystick0.Attribute("Right"), + DownLeft = (int)joystick0.Attribute("DownLeft"), + Down = (int)joystick0.Attribute("Down"), + DownRight = (int)joystick0.Attribute("DownRight") + }, + Joystick1 = new JoystickSettings + { + UpLeft = (int)joystick1.Attribute("UpLeft"), + Up = (int)joystick1.Attribute("Up"), + UpRight = (int)joystick1.Attribute("UpRight"), + Left = (int)joystick1.Attribute("Left"), + Right = (int)joystick1.Attribute("Right"), + DownLeft = (int)joystick1.Attribute("DownLeft"), + Down = (int)joystick1.Attribute("Down"), + DownRight = (int)joystick1.Attribute("DownRight") + }, + Button0 = (int)buttons.Attribute("Button0"), + Button1 = (int)buttons.Attribute("Button1"), + Button2 = (int)buttons.Attribute("Button2") + } + }; + var video = root.Element(ns + "Video"); + var color = video.Element(ns + "Color"); + Video = new VideoSettings + { + IsFullScreen = (bool)video.Attribute("IsFullScreen"), + IsMonochrome = (bool)video.Attribute("IsMonochrome"), + ScannerOptions = (ScannerOptions)Enum.Parse(typeof(ScannerOptions), (string)video.Attribute("ScannerOptions"), true), + Color = new ColorSettings + { + Black = (uint)color.Attribute("Black"), + DarkBlue = (uint)color.Attribute("DarkBlue"), + DarkGreen = (uint)color.Attribute("DarkGreen"), + MediumBlue = (uint)color.Attribute("MediumBlue"), + Brown = (uint)color.Attribute("Brown"), + LightGrey = (uint)color.Attribute("LightGrey"), + Green = (uint)color.Attribute("Green"), + Aquamarine = (uint)color.Attribute("Aquamarine"), + DeepRed = (uint)color.Attribute("DeepRed"), + Purple = (uint)color.Attribute("Purple"), + DarkGrey = (uint)color.Attribute("DarkGrey"), + LightBlue = (uint)color.Attribute("LightBlue"), + Orange = (uint)color.Attribute("Orange"), + Pink = (uint)color.Attribute("Pink"), + Yellow = (uint)color.Attribute("Yellow"), + White = (uint)color.Attribute("White"), + Monochrome = (uint)color.Attribute("Monochrome") + } + }; + } + } + catch (Exception) + { + } + } + + public void Serialize(Stream stream) + { + var ns = Namespace; + var xml = new XElement(ns + "MachineSettings", + new XElement(ns + "Cpu", + new XAttribute("Is65C02", Cpu.Is65C02), + new XAttribute("IsThrottled", Cpu.IsThrottled), + new XAttribute("Multiplier", Cpu.Multiplier)), + new XElement(ns + "DiskII", + new XElement(ns + "Disk1", + new XAttribute("Name", DiskII.Disk1.Name), + new XAttribute("IsWriteProtected", DiskII.Disk1.IsWriteProtected)), + new XElement(ns + "Disk2", + new XAttribute("Name", DiskII.Disk2.Name), + new XAttribute("IsWriteProtected", DiskII.Disk2.IsWriteProtected))), + new XElement(ns + "Keyboard", + new XAttribute("UseGamePort", Keyboard.UseGamePort), + new XElement(ns + "Key", + new XElement(ns + "Joystick0", + new XAttribute("UpLeft", Keyboard.Key.Joystick0.UpLeft), + new XAttribute("Up", Keyboard.Key.Joystick0.Up), + new XAttribute("UpRight", Keyboard.Key.Joystick0.UpRight), + new XAttribute("Left", Keyboard.Key.Joystick0.Left), + new XAttribute("Right", Keyboard.Key.Joystick0.Right), + new XAttribute("DownLeft", Keyboard.Key.Joystick0.DownLeft), + new XAttribute("Down", Keyboard.Key.Joystick0.Down), + new XAttribute("DownRight", Keyboard.Key.Joystick0.DownRight)), + new XElement(ns + "Joystick1", + new XAttribute("UpLeft", Keyboard.Key.Joystick1.UpLeft), + new XAttribute("Up", Keyboard.Key.Joystick1.Up), + new XAttribute("UpRight", Keyboard.Key.Joystick1.UpRight), + new XAttribute("Left", Keyboard.Key.Joystick1.Left), + new XAttribute("Right", Keyboard.Key.Joystick1.Right), + new XAttribute("DownLeft", Keyboard.Key.Joystick1.DownLeft), + new XAttribute("Down", Keyboard.Key.Joystick1.Down), + new XAttribute("DownRight", Keyboard.Key.Joystick1.DownRight)), + new XElement(ns + "Buttons", + new XAttribute("Button0", Keyboard.Key.Button0), + new XAttribute("Button1", Keyboard.Key.Button1), + new XAttribute("Button2", Keyboard.Key.Button2)))), + new XElement(ns + "GamePort", + new XAttribute("UseKeyboard", GamePort.UseKeyboard), + new XElement(ns + "Key", + new XElement(ns + "Joystick0", + new XAttribute("UpLeft", GamePort.Key.Joystick0.UpLeft), + new XAttribute("Up", GamePort.Key.Joystick0.Up), + new XAttribute("UpRight", GamePort.Key.Joystick0.UpRight), + new XAttribute("Left", GamePort.Key.Joystick0.Left), + new XAttribute("Right", GamePort.Key.Joystick0.Right), + new XAttribute("DownLeft", GamePort.Key.Joystick0.DownLeft), + new XAttribute("Down", GamePort.Key.Joystick0.Down), + new XAttribute("DownRight", GamePort.Key.Joystick0.DownRight)), + new XElement(ns + "Joystick1", + new XAttribute("UpLeft", GamePort.Key.Joystick1.UpLeft), + new XAttribute("Up", GamePort.Key.Joystick1.Up), + new XAttribute("UpRight", GamePort.Key.Joystick1.UpRight), + new XAttribute("Left", GamePort.Key.Joystick1.Left), + new XAttribute("Right", GamePort.Key.Joystick1.Right), + new XAttribute("DownLeft", GamePort.Key.Joystick1.DownLeft), + new XAttribute("Down", GamePort.Key.Joystick1.Down), + new XAttribute("DownRight", GamePort.Key.Joystick1.DownRight)), + new XElement(ns + "Buttons", + new XAttribute("Button0", Keyboard.Key.Button0), + new XAttribute("Button1", Keyboard.Key.Button1), + new XAttribute("Button2", Keyboard.Key.Button2)))), + new XElement(ns + "Video", + new XAttribute("IsFullScreen", Video.IsFullScreen), + new XAttribute("IsMonochrome", Video.IsMonochrome), + new XAttribute("ScannerOptions", Video.ScannerOptions), + new XElement(ns + "Color", + new XAttribute("Black", Video.Color.Black), + new XAttribute("DarkBlue", Video.Color.DarkBlue), + new XAttribute("DarkGreen", Video.Color.DarkGreen), + new XAttribute("MediumBlue", Video.Color.MediumBlue), + new XAttribute("Brown", Video.Color.Brown), + new XAttribute("LightGrey", Video.Color.LightGrey), + new XAttribute("Green", Video.Color.Green), + new XAttribute("Aquamarine", Video.Color.Aquamarine), + new XAttribute("DeepRed", Video.Color.DeepRed), + new XAttribute("Purple", Video.Color.Purple), + new XAttribute("DarkGrey", Video.Color.DarkGrey), + new XAttribute("LightBlue", Video.Color.LightBlue), + new XAttribute("Orange", Video.Color.Orange), + new XAttribute("Pink", Video.Color.Pink), + new XAttribute("Yellow", Video.Color.Yellow), + new XAttribute("White", Video.Color.White), + new XAttribute("Monochrome", Video.Color.Monochrome)))); + + using (var writer = XmlWriter.Create(stream)) + { + xml.WriteTo(writer); + } + } + + public CpuSettings Cpu { get; set; } + public DiskIISettings DiskII { get; set; } + public KeyboardSettings Keyboard { get; set; } + public GamePortSettings GamePort { get; set; } + public VideoSettings Video { get; set; } + + public const string FileName = "Settings.xml"; + public static readonly XNamespace Namespace = "http://schemas.jellyfish.co.nz/virtu/settings"; + } + + public sealed class CpuSettings + { + public bool Is65C02 { get; set; } + public bool IsThrottled { get; set; } + public int Multiplier { get; set; } + } + + public sealed class DiskSettings + { + public string Name { get; set; } + public bool IsWriteProtected { get; set; } + }; + + public sealed class DiskIISettings + { + public DiskSettings Disk1 { get; set; } + public DiskSettings Disk2 { get; set; } + }; + + public sealed class JoystickSettings + { + public int UpLeft { get; set; } + public int Up { get; set; } + public int UpRight { get; set; } + public int Left { get; set; } + public int Right { get; set; } + public int DownLeft { get; set; } + public int Down { get; set; } + public int DownRight { get; set; } + }; + + public sealed class KeySettings + { + public JoystickSettings Joystick0 { get; set; } + public JoystickSettings Joystick1 { get; set; } + public int Button0 { get; set; } + public int Button1 { get; set; } + public int Button2 { get; set; } + }; + + public sealed class KeyboardSettings + { + public bool UseGamePort { get; set; } + public KeySettings Key { get; set; } + } + + public sealed class GamePortSettings + { + public bool UseKeyboard { get; set; } + public KeySettings Key { get; set; } + } + + public sealed class ColorSettings + { + public uint Black { get; set; } + public uint DarkBlue { get; set; } + public uint DarkGreen { get; set; } + public uint MediumBlue { get; set; } + public uint Brown { get; set; } + public uint LightGrey { get; set; } + public uint Green { get; set; } + public uint Aquamarine { get; set; } + public uint DeepRed { get; set; } + public uint Purple { get; set; } + public uint DarkGrey { get; set; } + public uint LightBlue { get; set; } + public uint Orange { get; set; } + public uint Pink { get; set; } + public uint Yellow { get; set; } + public uint White { get; set; } + public uint Monochrome { get; set; } + } + + [Flags] + public enum ScannerOptions { None = 0x0, AppleII = 0x1, Pal = 0x2 } // defaults to AppleIIe, Ntsc + + public sealed class VideoSettings + { + public bool IsFullScreen { get; set; } + public bool IsMonochrome { get; set; } + public ScannerOptions ScannerOptions { get; set; } + public ColorSettings Color { get; set; } + }; +} diff --git a/Virtu/Memory.cs b/Virtu/Memory.cs index 6b3ac0b..b27e0c5 100644 --- a/Virtu/Memory.cs +++ b/Virtu/Memory.cs @@ -1,1469 +1,1469 @@ -using System; -using System.Diagnostics.CodeAnalysis; -using System.IO; -using Jellyfish.Library; -using Jellyfish.Virtu.Services; - -namespace Jellyfish.Virtu -{ - public enum MonitorType { Unknown, Standard, Enhanced }; - - public sealed partial class Memory : MachineComponent - { - public Memory(Machine machine) : - base(machine) - { - WriteRamModeBankRegion = new Action[Video.ModeCount][][]; - for (int mode = 0; mode < Video.ModeCount; mode++) - { - WriteRamModeBankRegion[mode] = new Action[BankCount][] - { - new Action[RegionCount], new Action[RegionCount] - }; - } - WriteRamModeBankRegion[Video.Mode0][BankMain][Region0407] = WriteRamMode0MainRegion0407; - WriteRamModeBankRegion[Video.Mode0][BankMain][Region080B] = WriteRamMode0MainRegion080B; - WriteRamModeBankRegion[Video.Mode1][BankMain][Region0407] = WriteRamMode1MainRegion0407; - WriteRamModeBankRegion[Video.Mode1][BankMain][Region080B] = WriteRamMode1MainRegion080B; - WriteRamModeBankRegion[Video.Mode2][BankMain][Region0407] = WriteRamMode2MainRegion0407; - WriteRamModeBankRegion[Video.Mode2][BankMain][Region080B] = WriteRamMode2MainRegion080B; - WriteRamModeBankRegion[Video.Mode2][BankAux][Region0407] = WriteRamMode2AuxRegion0407; - WriteRamModeBankRegion[Video.Mode2][BankAux][Region080B] = WriteRamMode2AuxRegion080B; - WriteRamModeBankRegion[Video.Mode3][BankMain][Region0407] = WriteRamMode3MainRegion0407; - WriteRamModeBankRegion[Video.Mode3][BankMain][Region080B] = WriteRamMode3MainRegion080B; - WriteRamModeBankRegion[Video.Mode4][BankMain][Region0407] = WriteRamMode4MainRegion0407; - WriteRamModeBankRegion[Video.Mode4][BankMain][Region080B] = WriteRamMode4MainRegion080B; - WriteRamModeBankRegion[Video.Mode4][BankAux][Region0407] = WriteRamMode4AuxRegion0407; - WriteRamModeBankRegion[Video.Mode4][BankAux][Region080B] = WriteRamMode4AuxRegion080B; - WriteRamModeBankRegion[Video.Mode5][BankMain][Region203F] = WriteRamMode5MainRegion203F; - WriteRamModeBankRegion[Video.Mode5][BankMain][Region405F] = WriteRamMode5MainRegion405F; - WriteRamModeBankRegion[Video.Mode6][BankMain][Region0407] = WriteRamMode6MainRegion0407; - WriteRamModeBankRegion[Video.Mode6][BankMain][Region080B] = WriteRamMode6MainRegion080B; - WriteRamModeBankRegion[Video.Mode6][BankMain][Region203F] = WriteRamMode6MainRegion203F; - WriteRamModeBankRegion[Video.Mode6][BankMain][Region405F] = WriteRamMode6MainRegion405F; - WriteRamModeBankRegion[Video.Mode7][BankMain][Region0407] = WriteRamMode7MainRegion0407; - WriteRamModeBankRegion[Video.Mode7][BankMain][Region080B] = WriteRamMode7MainRegion080B; - WriteRamModeBankRegion[Video.Mode7][BankMain][Region203F] = WriteRamMode7MainRegion203F; - WriteRamModeBankRegion[Video.Mode7][BankMain][Region405F] = WriteRamMode7MainRegion405F; - WriteRamModeBankRegion[Video.Mode7][BankAux][Region0407] = WriteRamMode7AuxRegion0407; - WriteRamModeBankRegion[Video.Mode7][BankAux][Region080B] = WriteRamMode7AuxRegion080B; - WriteRamModeBankRegion[Video.Mode8][BankMain][Region0407] = WriteRamMode8MainRegion0407; - WriteRamModeBankRegion[Video.Mode8][BankMain][Region080B] = WriteRamMode8MainRegion080B; - WriteRamModeBankRegion[Video.Mode9][BankMain][Region0407] = WriteRamMode9MainRegion0407; - WriteRamModeBankRegion[Video.Mode9][BankMain][Region080B] = WriteRamMode9MainRegion080B; - WriteRamModeBankRegion[Video.Mode9][BankAux][Region0407] = WriteRamMode9AuxRegion0407; - WriteRamModeBankRegion[Video.Mode9][BankAux][Region080B] = WriteRamMode9AuxRegion080B; - WriteRamModeBankRegion[Video.ModeA][BankMain][Region0407] = WriteRamModeAMainRegion0407; - WriteRamModeBankRegion[Video.ModeA][BankMain][Region080B] = WriteRamModeAMainRegion080B; - WriteRamModeBankRegion[Video.ModeB][BankMain][Region0407] = WriteRamModeBMainRegion0407; - WriteRamModeBankRegion[Video.ModeB][BankMain][Region080B] = WriteRamModeBMainRegion080B; - WriteRamModeBankRegion[Video.ModeB][BankAux][Region0407] = WriteRamModeBAuxRegion0407; - WriteRamModeBankRegion[Video.ModeB][BankAux][Region080B] = WriteRamModeBAuxRegion080B; - WriteRamModeBankRegion[Video.ModeC][BankMain][Region203F] = WriteRamModeCMainRegion203F; - WriteRamModeBankRegion[Video.ModeC][BankMain][Region405F] = WriteRamModeCMainRegion405F; - WriteRamModeBankRegion[Video.ModeD][BankMain][Region203F] = WriteRamModeDMainRegion203F; - WriteRamModeBankRegion[Video.ModeD][BankMain][Region405F] = WriteRamModeDMainRegion405F; - WriteRamModeBankRegion[Video.ModeD][BankAux][Region203F] = WriteRamModeDAuxRegion203F; - WriteRamModeBankRegion[Video.ModeD][BankAux][Region405F] = WriteRamModeDAuxRegion405F; - WriteRamModeBankRegion[Video.ModeE][BankMain][Region0407] = WriteRamModeEMainRegion0407; - WriteRamModeBankRegion[Video.ModeE][BankMain][Region080B] = WriteRamModeEMainRegion080B; - WriteRamModeBankRegion[Video.ModeE][BankMain][Region203F] = WriteRamModeEMainRegion203F; - WriteRamModeBankRegion[Video.ModeE][BankMain][Region405F] = WriteRamModeEMainRegion405F; - WriteRamModeBankRegion[Video.ModeF][BankMain][Region0407] = WriteRamModeFMainRegion0407; - WriteRamModeBankRegion[Video.ModeF][BankMain][Region080B] = WriteRamModeFMainRegion080B; - WriteRamModeBankRegion[Video.ModeF][BankMain][Region203F] = WriteRamModeFMainRegion203F; - WriteRamModeBankRegion[Video.ModeF][BankMain][Region405F] = WriteRamModeFMainRegion405F; - WriteRamModeBankRegion[Video.ModeF][BankAux][Region0407] = WriteRamModeFAuxRegion0407; - WriteRamModeBankRegion[Video.ModeF][BankAux][Region080B] = WriteRamModeFAuxRegion080B; - WriteRamModeBankRegion[Video.ModeF][BankAux][Region203F] = WriteRamModeFAuxRegion203F; - WriteRamModeBankRegion[Video.ModeF][BankAux][Region405F] = WriteRamModeFAuxRegion405F; - } - - public override void Initialize() - { - _diskII = Machine.DiskII; - _keyboard = Machine.Keyboard; - _gamePort = Machine.GamePort; - _cassette = Machine.Cassette; - _speaker = Machine.Speaker; - _video = Machine.Video; - - Stream romStream = StorageService.GetResourceStream("AppleIIe.rom", 0x4000); - romStream.Seek(0x0100, SeekOrigin.Current); - romStream.ReadBlock(_romInternalRegionC1CF, 0x0000, 0x0F00); - romStream.ReadBlock(_romRegionD0DF, 0x0000, 0x1000); - romStream.ReadBlock(_romRegionE0FF, 0x0000, 0x2000); - - romStream = StorageService.GetResourceStream("DiskII.rom", 0x0100); - romStream.ReadBlock(_romExternalRegionC1CF, 0x0500, 0x0100); - - if ((ReadRomRegionE0FF(0xFBB3) == 0x06) && (ReadRomRegionE0FF(0xFBBF) == 0xC1)) - { - Monitor = MonitorType.Standard; - } - else if ((ReadRomRegionE0FF(0xFBB3) == 0x06) && (ReadRomRegionE0FF(0xFBBF) == 0x00) && (ReadRomRegionE0FF(0xFBC0) == 0xE0)) - { - Monitor = MonitorType.Enhanced; - } - - Buffer.BlockCopy(_romInternalRegionC1CF, 0x0700, _romExternalRegionC1CF, 0x0700, 0x0800); - } - - public override void Reset() // [7-3] - { - ResetState(State80Col | State80Store | StateAltChrSet | StateAltZP | StateBank1 | StateHRamRd | StateHRamPreWrt | StateHRamWrt | // HRamWrt' [5-23] - StateHires | StatePage2 | StateRamRd | StateRamWrt | StateSlotC3Rom | StateIntCXRom | StateAn0 | StateAn1 | StateAn2 | StateAn3); - SetState(StateDRes); // An3' -> DRes [8-20] - - MapRegion0001(); - MapRegion02BF(); - MapRegionC0CF(); - MapRegionD0FF(); - } - - #region Core Read & Write - public int Read(int address) - { - int region = PageRegion[address >> 8]; - - return (region == RegionC0C0) ? ReadIoC0XX(address) : _regionRead[region][address - RegionBaseAddress[region]]; - } - - public int ReadZeroPage(int address) - { - return _zeroPage[address]; - } - - public void Write(int address, int data) - { - int region = PageRegion[address >> 8]; - if (_writeRegion[region] == null) - { - _regionWrite[region][address - RegionBaseAddress[region]] = (byte)data; - } - else - { - _writeRegion[region](address, (byte)data); - } - } - - public void WriteZeroPage(int address, int data) - { - _zeroPage[address] = (byte)data; - } - #endregion - - #region Read Actions - [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] - [SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode")] - private int ReadIoC0XX(int address) - { - switch (address) - { - case 0xC000: case 0xC001: case 0xC002: case 0xC003: case 0xC004: case 0xC005: case 0xC006: case 0xC007: // [7-15] - case 0xC008: case 0xC009: case 0xC00A: case 0xC00B: case 0xC00C: case 0xC00D: case 0xC00E: case 0xC00F: - return SetBit7(_keyboard.ReadLatch(), _keyboard.Strobe); - - case 0xC010: - _keyboard.ResetStrobe(); - return SetBit7(_keyboard.ReadLatch(), _keyboard.IsAnyKeyDown); - - case 0xC011: - return SetBit7(_keyboard.ReadLatch(), !IsHighRamBank1); // Bank1' [5-22] - - case 0xC012: - return SetBit7(_keyboard.ReadLatch(), IsHighRamRead); - - case 0xC013: - return SetBit7(_keyboard.ReadLatch(), IsRamReadAux); - - case 0xC014: - return SetBit7(_keyboard.ReadLatch(), IsRamWriteAux); - - case 0xC015: - return SetBit7(_keyboard.ReadLatch(), IsRomCXXXInternal); - - case 0xC016: - return SetBit7(_keyboard.ReadLatch(), IsZeroPageAux); - - case 0xC017: - return SetBit7(_keyboard.ReadLatch(), IsRomC3XXExternal); - - case 0xC018: - return SetBit7(_keyboard.ReadLatch(), Is80Store); - - case 0xC019: - return SetBit7(_keyboard.ReadLatch(), !_video.IsVBlank); // Vbl' [7-5] - - case 0xC01A: - return SetBit7(_keyboard.ReadLatch(), IsText); - - case 0xC01B: - return SetBit7(_keyboard.ReadLatch(), IsMixed); - - case 0xC01C: - return SetBit7(_keyboard.ReadLatch(), IsPage2); - - case 0xC01D: - return SetBit7(_keyboard.ReadLatch(), IsHires); - - case 0xC01E: - return SetBit7(_keyboard.ReadLatch(), IsCharSetAlternate); - - case 0xC01F: - return SetBit7(_keyboard.ReadLatch(), Is80Columns); - - case 0xC020: case 0xC021: case 0xC022: case 0xC023: case 0xC024: case 0xC025: case 0xC026: case 0xC027: // [7-8] - case 0xC028: case 0xC029: case 0xC02A: case 0xC02B: case 0xC02C: case 0xC02D: case 0xC02E: case 0xC02F: - _cassette.ToggleOutput(); - break; - - case 0xC030: case 0xC031: case 0xC032: case 0xC033: case 0xC034: case 0xC035: case 0xC036: case 0xC037: // [7-9] - case 0xC038: case 0xC039: case 0xC03A: case 0xC03B: case 0xC03C: case 0xC03D: case 0xC03E: case 0xC03F: - _speaker.ToggleOutput(); - break; - - case 0xC040: case 0xC041: case 0xC042: case 0xC043: case 0xC044: case 0xC045: case 0xC046: case 0xC047: // [2-18] - case 0xC048: case 0xC049: case 0xC04A: case 0xC04B: case 0xC04C: case 0xC04D: case 0xC04E: case 0xC04F: - break; - - case 0xC050: case 0xC051: - SetText(TestBit(address, 0)); - break; - - case 0xC052: case 0xC053: - SetMixed(TestBit(address, 0)); - break; - - case 0xC054: case 0xC055: - SetPage2(TestBit(address, 0)); - break; - - case 0xC056: case 0xC057: - SetHires(TestBit(address, 0)); - break; - - case 0xC058: case 0xC059: - SetAnnunciator0(TestBit(address, 0)); - break; - - case 0xC05A: case 0xC05B: - SetAnnunciator1(TestBit(address, 0)); - break; - - case 0xC05C: case 0xC05D: - SetAnnunciator2(TestBit(address, 0)); - break; - - case 0xC05E: case 0xC05F: - SetAnnunciator3(TestBit(address, 0)); - SetDoubleRes(!TestBit(address, 0)); - break; - - case 0xC060: case 0xC068: // [2-18, 7-5] - return SetBit7(_video.ReadFloatingBus(), _cassette.ReadInput()); // [7-8] - - case 0xC061: case 0xC069: - return SetBit7(_video.ReadFloatingBus(), _gamePort.ReadButton0()); - - case 0xC062: case 0xC06A: - return SetBit7(_video.ReadFloatingBus(), _gamePort.ReadButton1()); - - case 0xC063: case 0xC06B: - return SetBit7(_video.ReadFloatingBus(), _gamePort.ReadButton2()); - - case 0xC064: case 0xC06C: - return SetBit7(_video.ReadFloatingBus(), _gamePort.Paddle0Strobe); - - case 0xC065: case 0xC06D: - return SetBit7(_video.ReadFloatingBus(), _gamePort.Paddle1Strobe); - - case 0xC066: case 0xC06E: - return SetBit7(_video.ReadFloatingBus(), _gamePort.Paddle2Strobe); - - case 0xC067: case 0xC06F: - return SetBit7(_video.ReadFloatingBus(), _gamePort.Paddle3Strobe); - - case 0xC070: case 0xC071: case 0xC072: case 0xC073: case 0xC074: case 0xC075: case 0xC076: case 0xC077: - case 0xC078: case 0xC079: case 0xC07A: case 0xC07B: case 0xC07C: case 0xC07D: case 0xC07E: case 0xC07F: - _gamePort.TriggerTimers(); - break; - - case 0xC080: case 0xC081: case 0xC082: case 0xC083: case 0xC084: case 0xC085: case 0xC086: case 0xC087: // slot0 [5-23] - case 0xC088: case 0xC089: case 0xC08A: case 0xC08B: case 0xC08C: case 0xC08D: case 0xC08E: case 0xC08F: - SetHighRam(address, true); - break; - - case 0xC090: case 0xC091: case 0xC092: case 0xC093: case 0xC094: case 0xC095: case 0xC096: case 0xC097: // slot1 - case 0xC098: case 0xC099: case 0xC09A: case 0xC09B: case 0xC09C: case 0xC09D: case 0xC09E: case 0xC09F: - break; - - case 0xC0A0: case 0xC0A1: case 0xC0A2: case 0xC0A3: case 0xC0A4: case 0xC0A5: case 0xC0A6: case 0xC0A7: // slot2 - case 0xC0A8: case 0xC0A9: case 0xC0AA: case 0xC0AB: case 0xC0AC: case 0xC0AD: case 0xC0AE: case 0xC0AF: - break; - - case 0xC0B0: case 0xC0B1: case 0xC0B2: case 0xC0B3: case 0xC0B4: case 0xC0B5: case 0xC0B6: case 0xC0B7: // slot3 - case 0xC0B8: case 0xC0B9: case 0xC0BA: case 0xC0BB: case 0xC0BC: case 0xC0BD: case 0xC0BE: case 0xC0BF: - break; - - case 0xC0C0: case 0xC0C1: case 0xC0C2: case 0xC0C3: case 0xC0C4: case 0xC0C5: case 0xC0C6: case 0xC0C7: // slot4 - case 0xC0C8: case 0xC0C9: case 0xC0CA: case 0xC0CB: case 0xC0CC: case 0xC0CD: case 0xC0CE: case 0xC0CF: - break; - - case 0xC0D0: case 0xC0D1: case 0xC0D2: case 0xC0D3: case 0xC0D4: case 0xC0D5: case 0xC0D6: case 0xC0D7: // slot5 - case 0xC0D8: case 0xC0D9: case 0xC0DA: case 0xC0DB: case 0xC0DC: case 0xC0DD: case 0xC0DE: case 0xC0DF: - break; - - case 0xC0E0: case 0xC0E1: case 0xC0E2: case 0xC0E3: case 0xC0E4: case 0xC0E5: case 0xC0E6: case 0xC0E7: // slot6 - case 0xC0E8: case 0xC0E9: case 0xC0EA: case 0xC0EB: case 0xC0EC: case 0xC0ED: case 0xC0EE: case 0xC0EF: - return _diskII.Read(address); - - case 0xC0F0: case 0xC0F1: case 0xC0F2: case 0xC0F3: case 0xC0F4: case 0xC0F5: case 0xC0F6: case 0xC0F7: // slot7 - case 0xC0F8: case 0xC0F9: case 0xC0FA: case 0xC0FB: case 0xC0FC: case 0xC0FD: case 0xC0FE: case 0xC0FF: - break; - - default: - throw new ArgumentOutOfRangeException("address"); - } - - return _video.ReadFloatingBus(); // [5-40] - } - - [SuppressMessage("Microsoft.Usage", "CA2233:OperationsShouldNotOverflow", MessageId = "address-512")] - public int ReadRamMainRegion02BF(int address) - { - return _ramMainRegion02BF[address - 0x0200]; - } - - [SuppressMessage("Microsoft.Usage", "CA2233:OperationsShouldNotOverflow", MessageId = "address-512")] - public int ReadRamAuxRegion02BF(int address) - { - return _ramAuxRegion02BF[address - 0x0200]; - } - - [SuppressMessage("Microsoft.Usage", "CA2233:OperationsShouldNotOverflow", MessageId = "address-57344")] - public int ReadRomRegionE0FF(int address) - { - return _romRegionE0FF[address - 0xE000]; - } - #endregion - - #region Write Actions - [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] - [SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode")] - private void WriteIoC0XX(int address, byte data) - { - switch (address) - { - case 0xC000: case 0xC001: // [5-22] - Set80Store(TestBit(address, 0)); - break; - - case 0xC002: case 0xC003: - SetRamRead(TestBit(address, 0)); - break; - - case 0xC004: case 0xC005: - SetRamWrite(TestBit(address, 0)); - break; - - case 0xC006: case 0xC007: - SetRomCXXX(TestBit(address, 0)); - break; - - case 0xC008: case 0xC009: - SetZeroPage(TestBit(address, 0)); - break; - - case 0xC00A: case 0xC00B: - SetRomC3XX(TestBit(address, 0)); - break; - - case 0xC00C: case 0xC00D: // [7-5] - Set80Columns(TestBit(address, 0)); - break; - - case 0xC00E: case 0xC00F: - SetCharSet(TestBit(address, 0)); - break; - - case 0xC010: case 0xC011: case 0xC012: case 0xC013: case 0xC014: case 0xC015: case 0xC016: case 0xC017: // [7-15] - case 0xC018: case 0xC019: case 0xC01A: case 0xC01B: case 0xC01C: case 0xC01D: case 0xC01E: case 0xC01F: - _keyboard.ResetStrobe(); - break; - - case 0xC020: case 0xC021: case 0xC022: case 0xC023: case 0xC024: case 0xC025: case 0xC026: case 0xC027: // [7-8] - case 0xC028: case 0xC029: case 0xC02A: case 0xC02B: case 0xC02C: case 0xC02D: case 0xC02E: case 0xC02F: - _cassette.ToggleOutput(); - break; - - case 0xC030: case 0xC031: case 0xC032: case 0xC033: case 0xC034: case 0xC035: case 0xC036: case 0xC037: // [7-9] - case 0xC038: case 0xC039: case 0xC03A: case 0xC03B: case 0xC03C: case 0xC03D: case 0xC03E: case 0xC03F: - _speaker.ToggleOutput(); - break; - - case 0xC040: case 0xC041: case 0xC042: case 0xC043: case 0xC044: case 0xC045: case 0xC046: case 0xC047: // [2-18] - case 0xC048: case 0xC049: case 0xC04A: case 0xC04B: case 0xC04C: case 0xC04D: case 0xC04E: case 0xC04F: - break; - - case 0xC050: case 0xC051: - SetText(TestBit(address, 0)); - break; - - case 0xC052: case 0xC053: - SetMixed(TestBit(address, 0)); - break; - - case 0xC054: case 0xC055: - SetPage2(TestBit(address, 0)); - break; - - case 0xC056: case 0xC057: - SetHires(TestBit(address, 0)); - break; - - case 0xC058: case 0xC059: - SetAnnunciator0(TestBit(address, 0)); - break; - - case 0xC05A: case 0xC05B: - SetAnnunciator1(TestBit(address, 0)); - break; - - case 0xC05C: case 0xC05D: - SetAnnunciator2(TestBit(address, 0)); - break; - - case 0xC05E: case 0xC05F: - SetAnnunciator3(TestBit(address, 0)); - SetDoubleRes(!TestBit(address, 0)); - break; - - case 0xC060: case 0xC061: case 0xC062: case 0xC063: case 0xC064: case 0xC065: case 0xC066: case 0xC067: // [2-18, 7-5] - case 0xC068: case 0xC069: case 0xC06A: case 0xC06B: case 0xC06C: case 0xC06D: case 0xC06E: case 0xC06F: - break; - - case 0xC070: case 0xC071: case 0xC072: case 0xC073: case 0xC074: case 0xC075: case 0xC076: case 0xC077: - case 0xC078: case 0xC079: case 0xC07A: case 0xC07B: case 0xC07C: case 0xC07D: case 0xC07E: case 0xC07F: - _gamePort.TriggerTimers(); - break; - - case 0xC080: case 0xC081: case 0xC082: case 0xC083: case 0xC084: case 0xC085: case 0xC086: case 0xC087: // slot0 [5-23] - case 0xC088: case 0xC089: case 0xC08A: case 0xC08B: case 0xC08C: case 0xC08D: case 0xC08E: case 0xC08F: - SetHighRam(address, false); - break; - - case 0xC090: case 0xC091: case 0xC092: case 0xC093: case 0xC094: case 0xC095: case 0xC096: case 0xC097: // slot1 - case 0xC098: case 0xC099: case 0xC09A: case 0xC09B: case 0xC09C: case 0xC09D: case 0xC09E: case 0xC09F: - break; - - case 0xC0A0: case 0xC0A1: case 0xC0A2: case 0xC0A3: case 0xC0A4: case 0xC0A5: case 0xC0A6: case 0xC0A7: // slot2 - case 0xC0A8: case 0xC0A9: case 0xC0AA: case 0xC0AB: case 0xC0AC: case 0xC0AD: case 0xC0AE: case 0xC0AF: - break; - - case 0xC0B0: case 0xC0B1: case 0xC0B2: case 0xC0B3: case 0xC0B4: case 0xC0B5: case 0xC0B6: case 0xC0B7: // slot3 - case 0xC0B8: case 0xC0B9: case 0xC0BA: case 0xC0BB: case 0xC0BC: case 0xC0BD: case 0xC0BE: case 0xC0BF: - break; - - case 0xC0C0: case 0xC0C1: case 0xC0C2: case 0xC0C3: case 0xC0C4: case 0xC0C5: case 0xC0C6: case 0xC0C7: // slot4 - case 0xC0C8: case 0xC0C9: case 0xC0CA: case 0xC0CB: case 0xC0CC: case 0xC0CD: case 0xC0CE: case 0xC0CF: - break; - - case 0xC0D0: case 0xC0D1: case 0xC0D2: case 0xC0D3: case 0xC0D4: case 0xC0D5: case 0xC0D6: case 0xC0D7: // slot5 - case 0xC0D8: case 0xC0D9: case 0xC0DA: case 0xC0DB: case 0xC0DC: case 0xC0DD: case 0xC0DE: case 0xC0DF: - break; - - case 0xC0E0: case 0xC0E1: case 0xC0E2: case 0xC0E3: case 0xC0E4: case 0xC0E5: case 0xC0E6: case 0xC0E7: // slot6 - case 0xC0E8: case 0xC0E9: case 0xC0EA: case 0xC0EB: case 0xC0EC: case 0xC0ED: case 0xC0EE: case 0xC0EF: - _diskII.Write(address, data); - break; - - case 0xC0F0: case 0xC0F1: case 0xC0F2: case 0xC0F3: case 0xC0F4: case 0xC0F5: case 0xC0F6: case 0xC0F7: // slot7 - case 0xC0F8: case 0xC0F9: case 0xC0FA: case 0xC0FB: case 0xC0FC: case 0xC0FD: case 0xC0FE: case 0xC0FF: - break; - - default: - throw new ArgumentOutOfRangeException("address"); - } - } - - private void WriteRamMode0MainRegion0407(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCell(address - 0x0400); // lores page1 - } - } - - private void WriteRamMode0MainRegion080B(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCell(address - 0x0800); // lores page2 - } - } - - private void WriteRamMode1MainRegion0407(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCell(address - 0x0400); // text40 page1 - } - } - - private void WriteRamMode1MainRegion080B(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCell(address - 0x0800); // text40 page2 - } - } - - private void WriteRamMode2MainRegion0407(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCell(address - 0x0400); // text80 page1 - } - } - - private void WriteRamMode2MainRegion080B(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCell(address - 0x0800); // text80 page2 - } - } - - private void WriteRamMode2AuxRegion0407(int address, byte data) - { - if (_ramAuxRegion02BF[address - 0x0200] != data) - { - _ramAuxRegion02BF[address - 0x0200] = data; - _video.DirtyCell(address - 0x0400); // text80 page1 - } - } - - private void WriteRamMode2AuxRegion080B(int address, byte data) - { - if (_ramAuxRegion02BF[address - 0x0200] != data) - { - _ramAuxRegion02BF[address - 0x0200] = data; - _video.DirtyCell(address - 0x0800); // text80 page2 - } - } - - private void WriteRamMode3MainRegion0407(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCell(address - 0x0400); // lores & text40 page1 - } - } - - private void WriteRamMode3MainRegion080B(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCell(address - 0x0800); // lores & text40 page2 - } - } - - private void WriteRamMode4MainRegion0407(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCell(address - 0x0400); // lores & text80 page1 - } - } - - private void WriteRamMode4MainRegion080B(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCell(address - 0x0800); // lores & text80 page2 - } - } - - private void WriteRamMode4AuxRegion0407(int address, byte data) - { - if (_ramAuxRegion02BF[address - 0x0200] != data) - { - _ramAuxRegion02BF[address - 0x0200] = data; - _video.DirtyCellMixedText(address - 0x0400); // [lores &] text80 page1 - } - } - - private void WriteRamMode4AuxRegion080B(int address, byte data) - { - if (_ramAuxRegion02BF[address - 0x0200] != data) - { - _ramAuxRegion02BF[address - 0x0200] = data; - _video.DirtyCellMixedText(address - 0x0800); // [lores &] text80 page2 - } - } - - private void WriteRamMode5MainRegion203F(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCell(address - 0x2000); // hires page1 - } - } - - private void WriteRamMode5MainRegion405F(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCell(address - 0x4000); // hires page2 - } - } - - private void WriteRamMode6MainRegion0407(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCellMixedText(address - 0x0400); // [hires &] text40 page1 - } - } - - private void WriteRamMode6MainRegion080B(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCellMixedText(address - 0x0800); // [hires &] text40 page2 - } - } - - private void WriteRamMode6MainRegion203F(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCellMixed(address - 0x2000); // hires [& text40] page1 - } - } - - private void WriteRamMode6MainRegion405F(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCellMixed(address - 0x4000); // hires [& text40] page2 - } - } - - private void WriteRamMode7MainRegion0407(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCellMixedText(address - 0x0400); // [hires &] text80 page1 - } - } - - private void WriteRamMode7MainRegion080B(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCellMixedText(address - 0x0800); // [hires &] text80 page2 - } - } - - private void WriteRamMode7MainRegion203F(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCellMixed(address - 0x2000); // hires [& text80] page1 - } - } - - private void WriteRamMode7MainRegion405F(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCellMixed(address - 0x4000); // hires [& text80] page2 - } - } - - private void WriteRamMode7AuxRegion0407(int address, byte data) - { - if (_ramAuxRegion02BF[address - 0x0200] != data) - { - _ramAuxRegion02BF[address - 0x0200] = data; - _video.DirtyCellMixedText(address - 0x0400); // [hires &] text80 page1 - } - } - - private void WriteRamMode7AuxRegion080B(int address, byte data) - { - if (_ramAuxRegion02BF[address - 0x0200] != data) - { - _ramAuxRegion02BF[address - 0x0200] = data; - _video.DirtyCellMixedText(address - 0x0800); // [hires &] text80 page2 - } - } - - private void WriteRamMode8MainRegion0407(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCell(address - 0x0400); // 7mlores page1 - } - } - - private void WriteRamMode8MainRegion080B(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCell(address - 0x0800); // 7mlores page2 - } - } - - private void WriteRamMode9MainRegion0407(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCell(address - 0x0400); // dlores page1 - } - } - - private void WriteRamMode9MainRegion080B(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCell(address - 0x0800); // dlores page2 - } - } - - private void WriteRamMode9AuxRegion0407(int address, byte data) - { - if (_ramAuxRegion02BF[address - 0x0200] != data) - { - _ramAuxRegion02BF[address - 0x0200] = data; - _video.DirtyCell(address - 0x0400); // dlores page1 - } - } - - private void WriteRamMode9AuxRegion080B(int address, byte data) - { - if (_ramAuxRegion02BF[address - 0x0200] != data) - { - _ramAuxRegion02BF[address - 0x0200] = data; - _video.DirtyCell(address - 0x0800); // dlores page2 - } - } - - private void WriteRamModeAMainRegion0407(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCell(address - 0x0400); // 7mlores & text40 page1 - } - } - - private void WriteRamModeAMainRegion080B(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCell(address - 0x0800); // 7mlores & text40 page2 - } - } - - private void WriteRamModeBMainRegion0407(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCell(address - 0x0400); // dlores & text80 page1 - } - } - - private void WriteRamModeBMainRegion080B(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCell(address - 0x0800); // dlores & text80 page2 - } - } - - private void WriteRamModeBAuxRegion0407(int address, byte data) - { - if (_ramAuxRegion02BF[address - 0x0200] != data) - { - _ramAuxRegion02BF[address - 0x0200] = data; - _video.DirtyCell(address - 0x0400); // dlores & text80 page1 - } - } - - private void WriteRamModeBAuxRegion080B(int address, byte data) - { - if (_ramAuxRegion02BF[address - 0x0200] != data) - { - _ramAuxRegion02BF[address - 0x0200] = data; - _video.DirtyCell(address - 0x0800); // dlores & text80 page2 - } - } - - private void WriteRamModeCMainRegion203F(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCell(address - 0x2000); // ndhires page1 - } - } - - private void WriteRamModeCMainRegion405F(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCell(address - 0x4000); // ndhires page2 - } - } - - private void WriteRamModeDMainRegion203F(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCell(address - 0x2000); // dhires page1 - } - } - - private void WriteRamModeDMainRegion405F(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCell(address - 0x4000); // dhires page2 - } - } - - private void WriteRamModeDAuxRegion203F(int address, byte data) - { - if (_ramAuxRegion02BF[address - 0x0200] != data) - { - _ramAuxRegion02BF[address - 0x0200] = data; - _video.DirtyCell(address - 0x2000); // dhires page1 - } - } - - private void WriteRamModeDAuxRegion405F(int address, byte data) - { - if (_ramAuxRegion02BF[address - 0x0200] != data) - { - _ramAuxRegion02BF[address - 0x0200] = data; - _video.DirtyCell(address - 0x4000); // dhires page2 - } - } - - private void WriteRamModeEMainRegion0407(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCellMixedText(address - 0x0400); // [ndhires &] text40 page1 - } - } - - private void WriteRamModeEMainRegion080B(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCellMixedText(address - 0x0800); // [ndhires &] text40 page2 - } - } - - private void WriteRamModeEMainRegion203F(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCellMixed(address - 0x2000); // ndhires [& text40] page1 - } - } - - private void WriteRamModeEMainRegion405F(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCellMixed(address - 0x4000); // ndhires [& text40] page2 - } - } - - private void WriteRamModeFMainRegion0407(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCellMixedText(address - 0x0400); // [dhires &] text80 page1 - } - } - - private void WriteRamModeFMainRegion080B(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCellMixedText(address - 0x0800); // [dhires &] text80 page2 - } - } - - private void WriteRamModeFMainRegion203F(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCellMixed(address - 0x2000); // dhires [& text80] page1 - } - } - - private void WriteRamModeFMainRegion405F(int address, byte data) - { - if (_ramMainRegion02BF[address - 0x0200] != data) - { - _ramMainRegion02BF[address - 0x0200] = data; - _video.DirtyCellMixed(address - 0x4000); // dhires [& text80] page2 - } - } - - private void WriteRamModeFAuxRegion0407(int address, byte data) - { - if (_ramAuxRegion02BF[address - 0x0200] != data) - { - _ramAuxRegion02BF[address - 0x0200] = data; - _video.DirtyCellMixedText(address - 0x0400); // [dhires &] text80 page1 - } - } - - private void WriteRamModeFAuxRegion080B(int address, byte data) - { - if (_ramAuxRegion02BF[address - 0x0200] != data) - { - _ramAuxRegion02BF[address - 0x0200] = data; - _video.DirtyCellMixedText(address - 0x0800); // [dhires &] text80 page2 - } - } - - private void WriteRamModeFAuxRegion203F(int address, byte data) - { - if (_ramAuxRegion02BF[address - 0x0200] != data) - { - _ramAuxRegion02BF[address - 0x0200] = data; - _video.DirtyCellMixed(address - 0x2000); // dhires [& text80] page1 - } - } - - private void WriteRamModeFAuxRegion405F(int address, byte data) - { - if (_ramAuxRegion02BF[address - 0x0200] != data) - { - _ramAuxRegion02BF[address - 0x0200] = data; - _video.DirtyCellMixed(address - 0x4000); // dhires [& text80] page2 - } - } - - private void WriteRomRegionC1FF(int address, byte data) - { - } - #endregion - - #region Softswitch Actions - private void MapRegion0001() - { - if (!IsZeroPageAux) - { - _regionRead[Region0001] = _ramMainRegion0001; - _regionWrite[Region0001] = _ramMainRegion0001; - _zeroPage = _ramMainRegion0001; - } - else - { - _regionRead[Region0001] = _ramAuxRegion0001; - _regionWrite[Region0001] = _ramAuxRegion0001; - _zeroPage = _ramAuxRegion0001; - } - _writeRegion[Region0001] = null; - } - - private void MapRegion02BF() - { - if (!IsRamReadAux) - { - _regionRead[Region02BF] = _ramMainRegion02BF; - _regionRead[Region080B] = _ramMainRegion02BF; - _regionRead[Region405F] = _ramMainRegion02BF; - } - else - { - _regionRead[Region02BF] = _ramAuxRegion02BF; - _regionRead[Region080B] = _ramAuxRegion02BF; - _regionRead[Region405F] = _ramAuxRegion02BF; - } - int mode = VideoMode; - if (!IsRamWriteAux) - { - _regionWrite[Region02BF] = _ramMainRegion02BF; - _regionWrite[Region080B] = _ramMainRegion02BF; - _regionWrite[Region405F] = _ramMainRegion02BF; - _writeRegion[Region02BF] = null; - _writeRegion[Region080B] = WriteRamModeBankRegion[mode][BankMain][Region080B]; - _writeRegion[Region405F] = WriteRamModeBankRegion[mode][BankMain][Region405F]; - } - else - { - _regionWrite[Region02BF] = _ramAuxRegion02BF; - _regionWrite[Region080B] = _ramAuxRegion02BF; - _regionWrite[Region405F] = _ramAuxRegion02BF; - _writeRegion[Region02BF] = null; - _writeRegion[Region080B] = WriteRamModeBankRegion[mode][BankAux][Region080B]; - _writeRegion[Region405F] = WriteRamModeBankRegion[mode][BankAux][Region405F]; - } - MapRegion0407(); - MapRegion203F(); - } - - private void MapRegion0407() - { - if (!IsRamReadAuxRegion0407) - { - _regionRead[Region0407] = _ramMainRegion02BF; - } - else - { - _regionRead[Region0407] = _ramAuxRegion02BF; - } - int mode = VideoMode; - if (!IsRamWriteAuxRegion0407) - { - _regionWrite[Region0407] = _ramMainRegion02BF; - _writeRegion[Region0407] = WriteRamModeBankRegion[mode][BankMain][Region0407]; - } - else - { - _regionWrite[Region0407] = _ramAuxRegion02BF; - _writeRegion[Region0407] = WriteRamModeBankRegion[mode][BankAux][Region0407]; - } - } - - private void MapRegion203F() - { - if (!IsRamReadAuxRegion203F) - { - _regionRead[Region203F] = _ramMainRegion02BF; - } - else - { - _regionRead[Region203F] = _ramAuxRegion02BF; - } - int mode = VideoMode; - if (!IsRamWriteAuxRegion203F) - { - _regionWrite[Region203F] = _ramMainRegion02BF; - _writeRegion[Region203F] = WriteRamModeBankRegion[mode][BankMain][Region203F]; - } - else - { - _regionWrite[Region203F] = _ramAuxRegion02BF; - _writeRegion[Region203F] = WriteRamModeBankRegion[mode][BankAux][Region203F]; - } - } - - private void MapRegionC0CF() - { - _regionRead[RegionC0C0] = null; - if (IsRomCXXXInternal) - { - _regionRead[RegionC1C7] = _romInternalRegionC1CF; - _regionRead[RegionC3C3] = _romInternalRegionC1CF; - _regionRead[RegionC8CF] = _romInternalRegionC1CF; - } - else - { - _regionRead[RegionC1C7] = _romExternalRegionC1CF; - _regionRead[RegionC3C3] = IsRomC3XXExternal ? _romExternalRegionC1CF : _romInternalRegionC1CF; - _regionRead[RegionC8CF] = _romExternalRegionC1CF; - } - _regionWrite[RegionC0C0] = null; - _regionWrite[RegionC1C7] = null; - _regionWrite[RegionC3C3] = null; - _regionWrite[RegionC8CF] = null; - _writeRegion[RegionC0C0] = WriteIoC0XX; - _writeRegion[RegionC1C7] = WriteRomRegionC1FF; - _writeRegion[RegionC3C3] = WriteRomRegionC1FF; - _writeRegion[RegionC8CF] = WriteRomRegionC1FF; - } - - private void MapRegionD0FF() - { - if (IsHighRamRead) - { - if (!IsHighRamAux) - { - _regionRead[RegionD0DF] = IsHighRamBank1 ? _ramMainBank1RegionD0DF : _ramMainBank2RegionD0DF; - _regionRead[RegionE0FF] = _ramMainRegionE0FF; - } - else - { - _regionRead[RegionD0DF] = IsHighRamBank1 ? _ramAuxBank1RegionD0DF : _ramAuxBank2RegionD0DF; - _regionRead[RegionE0FF] = _ramAuxRegionE0FF; - } - } - else - { - _regionRead[RegionD0DF] = _romRegionD0DF; - _regionRead[RegionE0FF] = _romRegionE0FF; - } - if (IsHighRamWrite) - { - if (!IsHighRamAux) - { - _regionWrite[RegionD0DF] = IsHighRamBank1 ? _ramMainBank1RegionD0DF : _ramMainBank2RegionD0DF; - _regionWrite[RegionE0FF] = _ramMainRegionE0FF; - } - else - { - _regionWrite[RegionD0DF] = IsHighRamBank1 ? _ramAuxBank1RegionD0DF : _ramAuxBank2RegionD0DF; - _regionWrite[RegionE0FF] = _ramAuxRegionE0FF; - } - _writeRegion[RegionD0DF] = null; - _writeRegion[RegionE0FF] = null; - } - else - { - _regionWrite[RegionD0DF] = null; - _regionWrite[RegionE0FF] = null; - _writeRegion[RegionD0DF] = WriteRomRegionC1FF; - _writeRegion[RegionE0FF] = WriteRomRegionC1FF; - } - } - - private void Set80Columns(bool value) - { - if (!TestState(State80Col, value)) - { - SetState(State80Col, value); - MapRegion02BF(); - _video.DirtyScreen(); - } - } - - private void Set80Store(bool value) - { - if (!TestState(State80Store, value)) - { - SetState(State80Store, value); - if (IsPage2) // [5-7, 8-19] - { - MapRegion02BF(); - _video.DirtyScreen(); - } - else - { - MapRegion0407(); - MapRegion203F(); - } - } - } - - private void SetAnnunciator0(bool value) - { - SetState(StateAn0, value); - } - - private void SetAnnunciator1(bool value) - { - SetState(StateAn1, value); - } - - private void SetAnnunciator2(bool value) - { - SetState(StateAn2, value); - } - - private void SetAnnunciator3(bool value) - { - SetState(StateAn3, value); - } - - private void SetCharSet(bool value) - { - if (!TestState(StateAltChrSet, value)) - { - SetState(StateAltChrSet, value); - _video.SetCharSet(); - } - } - - private void SetDoubleRes(bool value) - { - if (!TestState(StateDRes, value)) - { - SetState(StateDRes, value); - MapRegion02BF(); - _video.DirtyScreen(); - } - } - - private void SetHighRam(int address, bool isRead) - { - SetState(StateBank1, TestBit(address, 3)); // A3 [5-22] - SetState(StateHRamRd, TestMask(address, 0x3, 0x3) || TestMask(address, 0x3, 0x0)); // A0.A1+A0'.A1' [5-23] (5-22 misprint) - if (TestBit(address, 0)) // A0 [5-23] - { - if (isRead && TestState(StateHRamPreWrt)) - { - ResetState(StateHRamWrt); // HRamWrt' [5-23] - } - } - else - { - SetState(StateHRamWrt); - } - SetState(StateHRamPreWrt, isRead && TestBit(address, 0)); // A0.R/W' [5-22] - MapRegionD0FF(); - } - - private void SetHires(bool value) - { - if (!TestState(StateHires, value)) - { - SetState(StateHires, value); - if (!Is80Store) // [5-7, 8-19] - { - MapRegion02BF(); - _video.DirtyScreen(); - } - else - { - MapRegion203F(); - } - } - } - - private void SetMixed(bool value) - { - if (!TestState(StateMixed, value)) - { - SetState(StateMixed, value); - MapRegion02BF(); - _video.DirtyScreen(); - } - } - - private void SetPage2(bool value) - { - if (!TestState(StatePage2, value)) - { - SetState(StatePage2, value); - if (!Is80Store) // [5-7, 8-19] - { - MapRegion02BF(); - _video.DirtyScreen(); - } - else - { - MapRegion0407(); - MapRegion203F(); - } - } - } - - private void SetRamRead(bool value) - { - if (!TestState(StateRamRd, value)) - { - SetState(StateRamRd, value); - MapRegion02BF(); - } - } - - private void SetRamWrite(bool value) - { - if (!TestState(StateRamWrt, value)) - { - SetState(StateRamWrt, value); - MapRegion02BF(); - } - } - - private void SetRomC3XX(bool value) - { - if (!TestState(StateSlotC3Rom, value)) - { - SetState(StateSlotC3Rom, value); - MapRegionC0CF(); - } - } - - private void SetRomCXXX(bool value) - { - if (!TestState(StateIntCXRom, value)) - { - SetState(StateIntCXRom, value); - MapRegionC0CF(); - } - } - - private void SetText(bool value) - { - if (!TestState(StateText, value)) - { - SetState(StateText, value); - MapRegion02BF(); - _video.DirtyScreen(); - } - } - - private void SetZeroPage(bool value) - { - if (!TestState(StateAltZP, value)) - { - SetState(StateAltZP, value); - MapRegion0001(); - MapRegionD0FF(); - } - } - #endregion - - private static int SetBit7(int data, bool value) - { - return value ? (data | 0x80) : (data & 0x7F); - } - - private static bool TestBit(int data, int bit) - { - return ((data & (0x1 << bit)) != 0x0); - } - - private static bool TestMask(int data, int mask, int value) - { - return ((data & mask) == value); - } - - private void ResetState(int mask) - { - _state &= ~mask; - } - - private void SetState(int mask) - { - _state |= mask; - } - - private void SetState(int mask, bool value) - { - if (value) - { - _state |= mask; - } - else - { - _state &= ~mask; - } - } - - private bool TestState(int mask) - { - return ((_state & mask) != 0x0); - } - - private bool TestState(int mask, bool value) - { - return (((_state & mask) != 0x0) == value); - } - - private bool TestState(int mask, int value) - { - return ((_state & mask) == value); - } - - public bool Is80Columns { get { return TestState(State80Col); } } - public bool Is80Store { get { return TestState(State80Store); } } - public bool IsAnnunciator0 { get { return TestState(StateAn0); } } - public bool IsAnnunciator1 { get { return TestState(StateAn1); } } - public bool IsAnnunciator2 { get { return TestState(StateAn2); } } - public bool IsAnnunciator3 { get { return TestState(StateAn3); } } - public bool IsCharSetAlternate { get { return TestState(StateAltChrSet); } } - public bool IsDoubleRes { get { return TestState(StateDRes); } } - public bool IsHighRamAux { get { return IsZeroPageAux; } } - public bool IsHighRamBank1 { get { return TestState(StateBank1); } } - public bool IsHighRamRead { get { return TestState(StateHRamRd); } } - public bool IsHighRamWrite { get { return !TestState(StateHRamWrt); } } // HRamWrt' [5-23] - public bool IsHires { get { return TestState(StateHires); } } - public bool IsMixed { get { return TestState(StateMixed); } } - public bool IsPage2 { get { return TestState(StatePage2); } } - public bool IsRamReadAux { get { return TestState(StateRamRd); } } - public bool IsRamReadAuxRegion0407 { get { return Is80Store ? IsPage2 : IsRamReadAux; } } - public bool IsRamReadAuxRegion203F { get { return TestState(State80Store | StateHires, State80Store | StateHires) ? IsPage2 : IsRamReadAux; } } - public bool IsRamWriteAux { get { return TestState(StateRamWrt); } } - public bool IsRamWriteAuxRegion0407 { get { return Is80Store ? IsPage2 : IsRamWriteAux; } } - public bool IsRamWriteAuxRegion203F { get { return TestState(State80Store | StateHires, State80Store | StateHires) ? IsPage2 : IsRamWriteAux; } } - public bool IsRomC3XXExternal { get { return TestState(StateSlotC3Rom); } } - public bool IsRomCXXXInternal { get { return TestState(StateIntCXRom); } } - public bool IsText { get { return TestState(StateText); } } - public bool IsVideoPage2 { get { return TestState(State80Store | StatePage2, StatePage2); } } // 80Store inhibits video Page2 [5-7, 8-19] - public bool IsZeroPageAux { get { return TestState(StateAltZP); } } - - public MonitorType Monitor { get; private set; } - public int VideoMode { get { return StateVideoMode[_state & StateVideo]; } } - - private DiskII _diskII; - private Keyboard _keyboard; - private GamePort _gamePort; - private Cassette _cassette; - private Speaker _speaker; - private Video _video; - - private int _state; - - 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]; - } -} +using System; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using Jellyfish.Library; +using Jellyfish.Virtu.Services; + +namespace Jellyfish.Virtu +{ + public enum MonitorType { Unknown, Standard, Enhanced }; + + public sealed partial class Memory : MachineComponent + { + public Memory(Machine machine) : + base(machine) + { + WriteRamModeBankRegion = new Action[Video.ModeCount][][]; + for (int mode = 0; mode < Video.ModeCount; mode++) + { + WriteRamModeBankRegion[mode] = new Action[BankCount][] + { + new Action[RegionCount], new Action[RegionCount] + }; + } + WriteRamModeBankRegion[Video.Mode0][BankMain][Region0407] = WriteRamMode0MainRegion0407; + WriteRamModeBankRegion[Video.Mode0][BankMain][Region080B] = WriteRamMode0MainRegion080B; + WriteRamModeBankRegion[Video.Mode1][BankMain][Region0407] = WriteRamMode1MainRegion0407; + WriteRamModeBankRegion[Video.Mode1][BankMain][Region080B] = WriteRamMode1MainRegion080B; + WriteRamModeBankRegion[Video.Mode2][BankMain][Region0407] = WriteRamMode2MainRegion0407; + WriteRamModeBankRegion[Video.Mode2][BankMain][Region080B] = WriteRamMode2MainRegion080B; + WriteRamModeBankRegion[Video.Mode2][BankAux][Region0407] = WriteRamMode2AuxRegion0407; + WriteRamModeBankRegion[Video.Mode2][BankAux][Region080B] = WriteRamMode2AuxRegion080B; + WriteRamModeBankRegion[Video.Mode3][BankMain][Region0407] = WriteRamMode3MainRegion0407; + WriteRamModeBankRegion[Video.Mode3][BankMain][Region080B] = WriteRamMode3MainRegion080B; + WriteRamModeBankRegion[Video.Mode4][BankMain][Region0407] = WriteRamMode4MainRegion0407; + WriteRamModeBankRegion[Video.Mode4][BankMain][Region080B] = WriteRamMode4MainRegion080B; + WriteRamModeBankRegion[Video.Mode4][BankAux][Region0407] = WriteRamMode4AuxRegion0407; + WriteRamModeBankRegion[Video.Mode4][BankAux][Region080B] = WriteRamMode4AuxRegion080B; + WriteRamModeBankRegion[Video.Mode5][BankMain][Region203F] = WriteRamMode5MainRegion203F; + WriteRamModeBankRegion[Video.Mode5][BankMain][Region405F] = WriteRamMode5MainRegion405F; + WriteRamModeBankRegion[Video.Mode6][BankMain][Region0407] = WriteRamMode6MainRegion0407; + WriteRamModeBankRegion[Video.Mode6][BankMain][Region080B] = WriteRamMode6MainRegion080B; + WriteRamModeBankRegion[Video.Mode6][BankMain][Region203F] = WriteRamMode6MainRegion203F; + WriteRamModeBankRegion[Video.Mode6][BankMain][Region405F] = WriteRamMode6MainRegion405F; + WriteRamModeBankRegion[Video.Mode7][BankMain][Region0407] = WriteRamMode7MainRegion0407; + WriteRamModeBankRegion[Video.Mode7][BankMain][Region080B] = WriteRamMode7MainRegion080B; + WriteRamModeBankRegion[Video.Mode7][BankMain][Region203F] = WriteRamMode7MainRegion203F; + WriteRamModeBankRegion[Video.Mode7][BankMain][Region405F] = WriteRamMode7MainRegion405F; + WriteRamModeBankRegion[Video.Mode7][BankAux][Region0407] = WriteRamMode7AuxRegion0407; + WriteRamModeBankRegion[Video.Mode7][BankAux][Region080B] = WriteRamMode7AuxRegion080B; + WriteRamModeBankRegion[Video.Mode8][BankMain][Region0407] = WriteRamMode8MainRegion0407; + WriteRamModeBankRegion[Video.Mode8][BankMain][Region080B] = WriteRamMode8MainRegion080B; + WriteRamModeBankRegion[Video.Mode9][BankMain][Region0407] = WriteRamMode9MainRegion0407; + WriteRamModeBankRegion[Video.Mode9][BankMain][Region080B] = WriteRamMode9MainRegion080B; + WriteRamModeBankRegion[Video.Mode9][BankAux][Region0407] = WriteRamMode9AuxRegion0407; + WriteRamModeBankRegion[Video.Mode9][BankAux][Region080B] = WriteRamMode9AuxRegion080B; + WriteRamModeBankRegion[Video.ModeA][BankMain][Region0407] = WriteRamModeAMainRegion0407; + WriteRamModeBankRegion[Video.ModeA][BankMain][Region080B] = WriteRamModeAMainRegion080B; + WriteRamModeBankRegion[Video.ModeB][BankMain][Region0407] = WriteRamModeBMainRegion0407; + WriteRamModeBankRegion[Video.ModeB][BankMain][Region080B] = WriteRamModeBMainRegion080B; + WriteRamModeBankRegion[Video.ModeB][BankAux][Region0407] = WriteRamModeBAuxRegion0407; + WriteRamModeBankRegion[Video.ModeB][BankAux][Region080B] = WriteRamModeBAuxRegion080B; + WriteRamModeBankRegion[Video.ModeC][BankMain][Region203F] = WriteRamModeCMainRegion203F; + WriteRamModeBankRegion[Video.ModeC][BankMain][Region405F] = WriteRamModeCMainRegion405F; + WriteRamModeBankRegion[Video.ModeD][BankMain][Region203F] = WriteRamModeDMainRegion203F; + WriteRamModeBankRegion[Video.ModeD][BankMain][Region405F] = WriteRamModeDMainRegion405F; + WriteRamModeBankRegion[Video.ModeD][BankAux][Region203F] = WriteRamModeDAuxRegion203F; + WriteRamModeBankRegion[Video.ModeD][BankAux][Region405F] = WriteRamModeDAuxRegion405F; + WriteRamModeBankRegion[Video.ModeE][BankMain][Region0407] = WriteRamModeEMainRegion0407; + WriteRamModeBankRegion[Video.ModeE][BankMain][Region080B] = WriteRamModeEMainRegion080B; + WriteRamModeBankRegion[Video.ModeE][BankMain][Region203F] = WriteRamModeEMainRegion203F; + WriteRamModeBankRegion[Video.ModeE][BankMain][Region405F] = WriteRamModeEMainRegion405F; + WriteRamModeBankRegion[Video.ModeF][BankMain][Region0407] = WriteRamModeFMainRegion0407; + WriteRamModeBankRegion[Video.ModeF][BankMain][Region080B] = WriteRamModeFMainRegion080B; + WriteRamModeBankRegion[Video.ModeF][BankMain][Region203F] = WriteRamModeFMainRegion203F; + WriteRamModeBankRegion[Video.ModeF][BankMain][Region405F] = WriteRamModeFMainRegion405F; + WriteRamModeBankRegion[Video.ModeF][BankAux][Region0407] = WriteRamModeFAuxRegion0407; + WriteRamModeBankRegion[Video.ModeF][BankAux][Region080B] = WriteRamModeFAuxRegion080B; + WriteRamModeBankRegion[Video.ModeF][BankAux][Region203F] = WriteRamModeFAuxRegion203F; + WriteRamModeBankRegion[Video.ModeF][BankAux][Region405F] = WriteRamModeFAuxRegion405F; + } + + public override void Initialize() + { + _diskII = Machine.DiskII; + _keyboard = Machine.Keyboard; + _gamePort = Machine.GamePort; + _cassette = Machine.Cassette; + _speaker = Machine.Speaker; + _video = Machine.Video; + + var romStream = StorageService.GetResourceStream("AppleIIe.rom", 0x4000); + romStream.Seek(0x0100, SeekOrigin.Current); + romStream.ReadBlock(_romInternalRegionC1CF, 0x0000, 0x0F00); + romStream.ReadBlock(_romRegionD0DF, 0x0000, 0x1000); + romStream.ReadBlock(_romRegionE0FF, 0x0000, 0x2000); + + romStream = StorageService.GetResourceStream("DiskII.rom", 0x0100); + romStream.ReadBlock(_romExternalRegionC1CF, 0x0500, 0x0100); + + if ((ReadRomRegionE0FF(0xFBB3) == 0x06) && (ReadRomRegionE0FF(0xFBBF) == 0xC1)) + { + Monitor = MonitorType.Standard; + } + else if ((ReadRomRegionE0FF(0xFBB3) == 0x06) && (ReadRomRegionE0FF(0xFBBF) == 0x00) && (ReadRomRegionE0FF(0xFBC0) == 0xE0)) + { + Monitor = MonitorType.Enhanced; + } + + Buffer.BlockCopy(_romInternalRegionC1CF, 0x0700, _romExternalRegionC1CF, 0x0700, 0x0800); + } + + public override void Reset() // [7-3] + { + ResetState(State80Col | State80Store | StateAltChrSet | StateAltZP | StateBank1 | StateHRamRd | StateHRamPreWrt | StateHRamWrt | // HRamWrt' [5-23] + StateHires | StatePage2 | StateRamRd | StateRamWrt | StateSlotC3Rom | StateIntCXRom | StateAn0 | StateAn1 | StateAn2 | StateAn3); + SetState(StateDRes); // An3' -> DRes [8-20] + + MapRegion0001(); + MapRegion02BF(); + MapRegionC0CF(); + MapRegionD0FF(); + } + + #region Core Read & Write + public int Read(int address) + { + int region = PageRegion[address >> 8]; + + return (region == RegionC0C0) ? ReadIoC0XX(address) : _regionRead[region][address - RegionBaseAddress[region]]; + } + + public int ReadZeroPage(int address) + { + return _zeroPage[address]; + } + + public void Write(int address, int data) + { + int region = PageRegion[address >> 8]; + if (_writeRegion[region] == null) + { + _regionWrite[region][address - RegionBaseAddress[region]] = (byte)data; + } + else + { + _writeRegion[region](address, (byte)data); + } + } + + public void WriteZeroPage(int address, int data) + { + _zeroPage[address] = (byte)data; + } + #endregion + + #region Read Actions + [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] + [SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode")] + private int ReadIoC0XX(int address) + { + switch (address) + { + case 0xC000: case 0xC001: case 0xC002: case 0xC003: case 0xC004: case 0xC005: case 0xC006: case 0xC007: // [7-15] + case 0xC008: case 0xC009: case 0xC00A: case 0xC00B: case 0xC00C: case 0xC00D: case 0xC00E: case 0xC00F: + return SetBit7(_keyboard.ReadLatch(), _keyboard.Strobe); + + case 0xC010: + _keyboard.ResetStrobe(); + return SetBit7(_keyboard.ReadLatch(), _keyboard.IsAnyKeyDown); + + case 0xC011: + return SetBit7(_keyboard.ReadLatch(), !IsHighRamBank1); // Bank1' [5-22] + + case 0xC012: + return SetBit7(_keyboard.ReadLatch(), IsHighRamRead); + + case 0xC013: + return SetBit7(_keyboard.ReadLatch(), IsRamReadAux); + + case 0xC014: + return SetBit7(_keyboard.ReadLatch(), IsRamWriteAux); + + case 0xC015: + return SetBit7(_keyboard.ReadLatch(), IsRomCXXXInternal); + + case 0xC016: + return SetBit7(_keyboard.ReadLatch(), IsZeroPageAux); + + case 0xC017: + return SetBit7(_keyboard.ReadLatch(), IsRomC3XXExternal); + + case 0xC018: + return SetBit7(_keyboard.ReadLatch(), Is80Store); + + case 0xC019: + return SetBit7(_keyboard.ReadLatch(), !_video.IsVBlank); // Vbl' [7-5] + + case 0xC01A: + return SetBit7(_keyboard.ReadLatch(), IsText); + + case 0xC01B: + return SetBit7(_keyboard.ReadLatch(), IsMixed); + + case 0xC01C: + return SetBit7(_keyboard.ReadLatch(), IsPage2); + + case 0xC01D: + return SetBit7(_keyboard.ReadLatch(), IsHires); + + case 0xC01E: + return SetBit7(_keyboard.ReadLatch(), IsCharSetAlternate); + + case 0xC01F: + return SetBit7(_keyboard.ReadLatch(), Is80Columns); + + case 0xC020: case 0xC021: case 0xC022: case 0xC023: case 0xC024: case 0xC025: case 0xC026: case 0xC027: // [7-8] + case 0xC028: case 0xC029: case 0xC02A: case 0xC02B: case 0xC02C: case 0xC02D: case 0xC02E: case 0xC02F: + _cassette.ToggleOutput(); + break; + + case 0xC030: case 0xC031: case 0xC032: case 0xC033: case 0xC034: case 0xC035: case 0xC036: case 0xC037: // [7-9] + case 0xC038: case 0xC039: case 0xC03A: case 0xC03B: case 0xC03C: case 0xC03D: case 0xC03E: case 0xC03F: + _speaker.ToggleOutput(); + break; + + case 0xC040: case 0xC041: case 0xC042: case 0xC043: case 0xC044: case 0xC045: case 0xC046: case 0xC047: // [2-18] + case 0xC048: case 0xC049: case 0xC04A: case 0xC04B: case 0xC04C: case 0xC04D: case 0xC04E: case 0xC04F: + break; + + case 0xC050: case 0xC051: + SetText(TestBit(address, 0)); + break; + + case 0xC052: case 0xC053: + SetMixed(TestBit(address, 0)); + break; + + case 0xC054: case 0xC055: + SetPage2(TestBit(address, 0)); + break; + + case 0xC056: case 0xC057: + SetHires(TestBit(address, 0)); + break; + + case 0xC058: case 0xC059: + SetAnnunciator0(TestBit(address, 0)); + break; + + case 0xC05A: case 0xC05B: + SetAnnunciator1(TestBit(address, 0)); + break; + + case 0xC05C: case 0xC05D: + SetAnnunciator2(TestBit(address, 0)); + break; + + case 0xC05E: case 0xC05F: + SetAnnunciator3(TestBit(address, 0)); + SetDoubleRes(!TestBit(address, 0)); + break; + + case 0xC060: case 0xC068: // [2-18, 7-5] + return SetBit7(_video.ReadFloatingBus(), _cassette.ReadInput()); // [7-8] + + case 0xC061: case 0xC069: + return SetBit7(_video.ReadFloatingBus(), _gamePort.ReadButton0()); + + case 0xC062: case 0xC06A: + return SetBit7(_video.ReadFloatingBus(), _gamePort.ReadButton1()); + + case 0xC063: case 0xC06B: + return SetBit7(_video.ReadFloatingBus(), _gamePort.ReadButton2()); + + case 0xC064: case 0xC06C: + return SetBit7(_video.ReadFloatingBus(), _gamePort.Paddle0Strobe); + + case 0xC065: case 0xC06D: + return SetBit7(_video.ReadFloatingBus(), _gamePort.Paddle1Strobe); + + case 0xC066: case 0xC06E: + return SetBit7(_video.ReadFloatingBus(), _gamePort.Paddle2Strobe); + + case 0xC067: case 0xC06F: + return SetBit7(_video.ReadFloatingBus(), _gamePort.Paddle3Strobe); + + case 0xC070: case 0xC071: case 0xC072: case 0xC073: case 0xC074: case 0xC075: case 0xC076: case 0xC077: + case 0xC078: case 0xC079: case 0xC07A: case 0xC07B: case 0xC07C: case 0xC07D: case 0xC07E: case 0xC07F: + _gamePort.TriggerTimers(); + break; + + case 0xC080: case 0xC081: case 0xC082: case 0xC083: case 0xC084: case 0xC085: case 0xC086: case 0xC087: // slot0 [5-23] + case 0xC088: case 0xC089: case 0xC08A: case 0xC08B: case 0xC08C: case 0xC08D: case 0xC08E: case 0xC08F: + SetHighRam(address, true); + break; + + case 0xC090: case 0xC091: case 0xC092: case 0xC093: case 0xC094: case 0xC095: case 0xC096: case 0xC097: // slot1 + case 0xC098: case 0xC099: case 0xC09A: case 0xC09B: case 0xC09C: case 0xC09D: case 0xC09E: case 0xC09F: + break; + + case 0xC0A0: case 0xC0A1: case 0xC0A2: case 0xC0A3: case 0xC0A4: case 0xC0A5: case 0xC0A6: case 0xC0A7: // slot2 + case 0xC0A8: case 0xC0A9: case 0xC0AA: case 0xC0AB: case 0xC0AC: case 0xC0AD: case 0xC0AE: case 0xC0AF: + break; + + case 0xC0B0: case 0xC0B1: case 0xC0B2: case 0xC0B3: case 0xC0B4: case 0xC0B5: case 0xC0B6: case 0xC0B7: // slot3 + case 0xC0B8: case 0xC0B9: case 0xC0BA: case 0xC0BB: case 0xC0BC: case 0xC0BD: case 0xC0BE: case 0xC0BF: + break; + + case 0xC0C0: case 0xC0C1: case 0xC0C2: case 0xC0C3: case 0xC0C4: case 0xC0C5: case 0xC0C6: case 0xC0C7: // slot4 + case 0xC0C8: case 0xC0C9: case 0xC0CA: case 0xC0CB: case 0xC0CC: case 0xC0CD: case 0xC0CE: case 0xC0CF: + break; + + case 0xC0D0: case 0xC0D1: case 0xC0D2: case 0xC0D3: case 0xC0D4: case 0xC0D5: case 0xC0D6: case 0xC0D7: // slot5 + case 0xC0D8: case 0xC0D9: case 0xC0DA: case 0xC0DB: case 0xC0DC: case 0xC0DD: case 0xC0DE: case 0xC0DF: + break; + + case 0xC0E0: case 0xC0E1: case 0xC0E2: case 0xC0E3: case 0xC0E4: case 0xC0E5: case 0xC0E6: case 0xC0E7: // slot6 + case 0xC0E8: case 0xC0E9: case 0xC0EA: case 0xC0EB: case 0xC0EC: case 0xC0ED: case 0xC0EE: case 0xC0EF: + return _diskII.Read(address); + + case 0xC0F0: case 0xC0F1: case 0xC0F2: case 0xC0F3: case 0xC0F4: case 0xC0F5: case 0xC0F6: case 0xC0F7: // slot7 + case 0xC0F8: case 0xC0F9: case 0xC0FA: case 0xC0FB: case 0xC0FC: case 0xC0FD: case 0xC0FE: case 0xC0FF: + break; + + default: + throw new ArgumentOutOfRangeException("address"); + } + + return _video.ReadFloatingBus(); // [5-40] + } + + [SuppressMessage("Microsoft.Usage", "CA2233:OperationsShouldNotOverflow", MessageId = "address-512")] + public int ReadRamMainRegion02BF(int address) + { + return _ramMainRegion02BF[address - 0x0200]; + } + + [SuppressMessage("Microsoft.Usage", "CA2233:OperationsShouldNotOverflow", MessageId = "address-512")] + public int ReadRamAuxRegion02BF(int address) + { + return _ramAuxRegion02BF[address - 0x0200]; + } + + [SuppressMessage("Microsoft.Usage", "CA2233:OperationsShouldNotOverflow", MessageId = "address-57344")] + public int ReadRomRegionE0FF(int address) + { + return _romRegionE0FF[address - 0xE000]; + } + #endregion + + #region Write Actions + [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] + [SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode")] + private void WriteIoC0XX(int address, byte data) + { + switch (address) + { + case 0xC000: case 0xC001: // [5-22] + Set80Store(TestBit(address, 0)); + break; + + case 0xC002: case 0xC003: + SetRamRead(TestBit(address, 0)); + break; + + case 0xC004: case 0xC005: + SetRamWrite(TestBit(address, 0)); + break; + + case 0xC006: case 0xC007: + SetRomCXXX(TestBit(address, 0)); + break; + + case 0xC008: case 0xC009: + SetZeroPage(TestBit(address, 0)); + break; + + case 0xC00A: case 0xC00B: + SetRomC3XX(TestBit(address, 0)); + break; + + case 0xC00C: case 0xC00D: // [7-5] + Set80Columns(TestBit(address, 0)); + break; + + case 0xC00E: case 0xC00F: + SetCharSet(TestBit(address, 0)); + break; + + case 0xC010: case 0xC011: case 0xC012: case 0xC013: case 0xC014: case 0xC015: case 0xC016: case 0xC017: // [7-15] + case 0xC018: case 0xC019: case 0xC01A: case 0xC01B: case 0xC01C: case 0xC01D: case 0xC01E: case 0xC01F: + _keyboard.ResetStrobe(); + break; + + case 0xC020: case 0xC021: case 0xC022: case 0xC023: case 0xC024: case 0xC025: case 0xC026: case 0xC027: // [7-8] + case 0xC028: case 0xC029: case 0xC02A: case 0xC02B: case 0xC02C: case 0xC02D: case 0xC02E: case 0xC02F: + _cassette.ToggleOutput(); + break; + + case 0xC030: case 0xC031: case 0xC032: case 0xC033: case 0xC034: case 0xC035: case 0xC036: case 0xC037: // [7-9] + case 0xC038: case 0xC039: case 0xC03A: case 0xC03B: case 0xC03C: case 0xC03D: case 0xC03E: case 0xC03F: + _speaker.ToggleOutput(); + break; + + case 0xC040: case 0xC041: case 0xC042: case 0xC043: case 0xC044: case 0xC045: case 0xC046: case 0xC047: // [2-18] + case 0xC048: case 0xC049: case 0xC04A: case 0xC04B: case 0xC04C: case 0xC04D: case 0xC04E: case 0xC04F: + break; + + case 0xC050: case 0xC051: + SetText(TestBit(address, 0)); + break; + + case 0xC052: case 0xC053: + SetMixed(TestBit(address, 0)); + break; + + case 0xC054: case 0xC055: + SetPage2(TestBit(address, 0)); + break; + + case 0xC056: case 0xC057: + SetHires(TestBit(address, 0)); + break; + + case 0xC058: case 0xC059: + SetAnnunciator0(TestBit(address, 0)); + break; + + case 0xC05A: case 0xC05B: + SetAnnunciator1(TestBit(address, 0)); + break; + + case 0xC05C: case 0xC05D: + SetAnnunciator2(TestBit(address, 0)); + break; + + case 0xC05E: case 0xC05F: + SetAnnunciator3(TestBit(address, 0)); + SetDoubleRes(!TestBit(address, 0)); + break; + + case 0xC060: case 0xC061: case 0xC062: case 0xC063: case 0xC064: case 0xC065: case 0xC066: case 0xC067: // [2-18, 7-5] + case 0xC068: case 0xC069: case 0xC06A: case 0xC06B: case 0xC06C: case 0xC06D: case 0xC06E: case 0xC06F: + break; + + case 0xC070: case 0xC071: case 0xC072: case 0xC073: case 0xC074: case 0xC075: case 0xC076: case 0xC077: + case 0xC078: case 0xC079: case 0xC07A: case 0xC07B: case 0xC07C: case 0xC07D: case 0xC07E: case 0xC07F: + _gamePort.TriggerTimers(); + break; + + case 0xC080: case 0xC081: case 0xC082: case 0xC083: case 0xC084: case 0xC085: case 0xC086: case 0xC087: // slot0 [5-23] + case 0xC088: case 0xC089: case 0xC08A: case 0xC08B: case 0xC08C: case 0xC08D: case 0xC08E: case 0xC08F: + SetHighRam(address, false); + break; + + case 0xC090: case 0xC091: case 0xC092: case 0xC093: case 0xC094: case 0xC095: case 0xC096: case 0xC097: // slot1 + case 0xC098: case 0xC099: case 0xC09A: case 0xC09B: case 0xC09C: case 0xC09D: case 0xC09E: case 0xC09F: + break; + + case 0xC0A0: case 0xC0A1: case 0xC0A2: case 0xC0A3: case 0xC0A4: case 0xC0A5: case 0xC0A6: case 0xC0A7: // slot2 + case 0xC0A8: case 0xC0A9: case 0xC0AA: case 0xC0AB: case 0xC0AC: case 0xC0AD: case 0xC0AE: case 0xC0AF: + break; + + case 0xC0B0: case 0xC0B1: case 0xC0B2: case 0xC0B3: case 0xC0B4: case 0xC0B5: case 0xC0B6: case 0xC0B7: // slot3 + case 0xC0B8: case 0xC0B9: case 0xC0BA: case 0xC0BB: case 0xC0BC: case 0xC0BD: case 0xC0BE: case 0xC0BF: + break; + + case 0xC0C0: case 0xC0C1: case 0xC0C2: case 0xC0C3: case 0xC0C4: case 0xC0C5: case 0xC0C6: case 0xC0C7: // slot4 + case 0xC0C8: case 0xC0C9: case 0xC0CA: case 0xC0CB: case 0xC0CC: case 0xC0CD: case 0xC0CE: case 0xC0CF: + break; + + case 0xC0D0: case 0xC0D1: case 0xC0D2: case 0xC0D3: case 0xC0D4: case 0xC0D5: case 0xC0D6: case 0xC0D7: // slot5 + case 0xC0D8: case 0xC0D9: case 0xC0DA: case 0xC0DB: case 0xC0DC: case 0xC0DD: case 0xC0DE: case 0xC0DF: + break; + + case 0xC0E0: case 0xC0E1: case 0xC0E2: case 0xC0E3: case 0xC0E4: case 0xC0E5: case 0xC0E6: case 0xC0E7: // slot6 + case 0xC0E8: case 0xC0E9: case 0xC0EA: case 0xC0EB: case 0xC0EC: case 0xC0ED: case 0xC0EE: case 0xC0EF: + _diskII.Write(address, data); + break; + + case 0xC0F0: case 0xC0F1: case 0xC0F2: case 0xC0F3: case 0xC0F4: case 0xC0F5: case 0xC0F6: case 0xC0F7: // slot7 + case 0xC0F8: case 0xC0F9: case 0xC0FA: case 0xC0FB: case 0xC0FC: case 0xC0FD: case 0xC0FE: case 0xC0FF: + break; + + default: + throw new ArgumentOutOfRangeException("address"); + } + } + + private void WriteRamMode0MainRegion0407(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCell(address - 0x0400); // lores page1 + } + } + + private void WriteRamMode0MainRegion080B(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCell(address - 0x0800); // lores page2 + } + } + + private void WriteRamMode1MainRegion0407(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCell(address - 0x0400); // text40 page1 + } + } + + private void WriteRamMode1MainRegion080B(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCell(address - 0x0800); // text40 page2 + } + } + + private void WriteRamMode2MainRegion0407(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCell(address - 0x0400); // text80 page1 + } + } + + private void WriteRamMode2MainRegion080B(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCell(address - 0x0800); // text80 page2 + } + } + + private void WriteRamMode2AuxRegion0407(int address, byte data) + { + if (_ramAuxRegion02BF[address - 0x0200] != data) + { + _ramAuxRegion02BF[address - 0x0200] = data; + _video.DirtyCell(address - 0x0400); // text80 page1 + } + } + + private void WriteRamMode2AuxRegion080B(int address, byte data) + { + if (_ramAuxRegion02BF[address - 0x0200] != data) + { + _ramAuxRegion02BF[address - 0x0200] = data; + _video.DirtyCell(address - 0x0800); // text80 page2 + } + } + + private void WriteRamMode3MainRegion0407(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCell(address - 0x0400); // lores & text40 page1 + } + } + + private void WriteRamMode3MainRegion080B(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCell(address - 0x0800); // lores & text40 page2 + } + } + + private void WriteRamMode4MainRegion0407(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCell(address - 0x0400); // lores & text80 page1 + } + } + + private void WriteRamMode4MainRegion080B(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCell(address - 0x0800); // lores & text80 page2 + } + } + + private void WriteRamMode4AuxRegion0407(int address, byte data) + { + if (_ramAuxRegion02BF[address - 0x0200] != data) + { + _ramAuxRegion02BF[address - 0x0200] = data; + _video.DirtyCellMixedText(address - 0x0400); // [lores &] text80 page1 + } + } + + private void WriteRamMode4AuxRegion080B(int address, byte data) + { + if (_ramAuxRegion02BF[address - 0x0200] != data) + { + _ramAuxRegion02BF[address - 0x0200] = data; + _video.DirtyCellMixedText(address - 0x0800); // [lores &] text80 page2 + } + } + + private void WriteRamMode5MainRegion203F(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCell(address - 0x2000); // hires page1 + } + } + + private void WriteRamMode5MainRegion405F(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCell(address - 0x4000); // hires page2 + } + } + + private void WriteRamMode6MainRegion0407(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCellMixedText(address - 0x0400); // [hires &] text40 page1 + } + } + + private void WriteRamMode6MainRegion080B(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCellMixedText(address - 0x0800); // [hires &] text40 page2 + } + } + + private void WriteRamMode6MainRegion203F(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCellMixed(address - 0x2000); // hires [& text40] page1 + } + } + + private void WriteRamMode6MainRegion405F(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCellMixed(address - 0x4000); // hires [& text40] page2 + } + } + + private void WriteRamMode7MainRegion0407(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCellMixedText(address - 0x0400); // [hires &] text80 page1 + } + } + + private void WriteRamMode7MainRegion080B(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCellMixedText(address - 0x0800); // [hires &] text80 page2 + } + } + + private void WriteRamMode7MainRegion203F(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCellMixed(address - 0x2000); // hires [& text80] page1 + } + } + + private void WriteRamMode7MainRegion405F(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCellMixed(address - 0x4000); // hires [& text80] page2 + } + } + + private void WriteRamMode7AuxRegion0407(int address, byte data) + { + if (_ramAuxRegion02BF[address - 0x0200] != data) + { + _ramAuxRegion02BF[address - 0x0200] = data; + _video.DirtyCellMixedText(address - 0x0400); // [hires &] text80 page1 + } + } + + private void WriteRamMode7AuxRegion080B(int address, byte data) + { + if (_ramAuxRegion02BF[address - 0x0200] != data) + { + _ramAuxRegion02BF[address - 0x0200] = data; + _video.DirtyCellMixedText(address - 0x0800); // [hires &] text80 page2 + } + } + + private void WriteRamMode8MainRegion0407(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCell(address - 0x0400); // 7mlores page1 + } + } + + private void WriteRamMode8MainRegion080B(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCell(address - 0x0800); // 7mlores page2 + } + } + + private void WriteRamMode9MainRegion0407(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCell(address - 0x0400); // dlores page1 + } + } + + private void WriteRamMode9MainRegion080B(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCell(address - 0x0800); // dlores page2 + } + } + + private void WriteRamMode9AuxRegion0407(int address, byte data) + { + if (_ramAuxRegion02BF[address - 0x0200] != data) + { + _ramAuxRegion02BF[address - 0x0200] = data; + _video.DirtyCell(address - 0x0400); // dlores page1 + } + } + + private void WriteRamMode9AuxRegion080B(int address, byte data) + { + if (_ramAuxRegion02BF[address - 0x0200] != data) + { + _ramAuxRegion02BF[address - 0x0200] = data; + _video.DirtyCell(address - 0x0800); // dlores page2 + } + } + + private void WriteRamModeAMainRegion0407(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCell(address - 0x0400); // 7mlores & text40 page1 + } + } + + private void WriteRamModeAMainRegion080B(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCell(address - 0x0800); // 7mlores & text40 page2 + } + } + + private void WriteRamModeBMainRegion0407(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCell(address - 0x0400); // dlores & text80 page1 + } + } + + private void WriteRamModeBMainRegion080B(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCell(address - 0x0800); // dlores & text80 page2 + } + } + + private void WriteRamModeBAuxRegion0407(int address, byte data) + { + if (_ramAuxRegion02BF[address - 0x0200] != data) + { + _ramAuxRegion02BF[address - 0x0200] = data; + _video.DirtyCell(address - 0x0400); // dlores & text80 page1 + } + } + + private void WriteRamModeBAuxRegion080B(int address, byte data) + { + if (_ramAuxRegion02BF[address - 0x0200] != data) + { + _ramAuxRegion02BF[address - 0x0200] = data; + _video.DirtyCell(address - 0x0800); // dlores & text80 page2 + } + } + + private void WriteRamModeCMainRegion203F(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCell(address - 0x2000); // ndhires page1 + } + } + + private void WriteRamModeCMainRegion405F(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCell(address - 0x4000); // ndhires page2 + } + } + + private void WriteRamModeDMainRegion203F(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCell(address - 0x2000); // dhires page1 + } + } + + private void WriteRamModeDMainRegion405F(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCell(address - 0x4000); // dhires page2 + } + } + + private void WriteRamModeDAuxRegion203F(int address, byte data) + { + if (_ramAuxRegion02BF[address - 0x0200] != data) + { + _ramAuxRegion02BF[address - 0x0200] = data; + _video.DirtyCell(address - 0x2000); // dhires page1 + } + } + + private void WriteRamModeDAuxRegion405F(int address, byte data) + { + if (_ramAuxRegion02BF[address - 0x0200] != data) + { + _ramAuxRegion02BF[address - 0x0200] = data; + _video.DirtyCell(address - 0x4000); // dhires page2 + } + } + + private void WriteRamModeEMainRegion0407(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCellMixedText(address - 0x0400); // [ndhires &] text40 page1 + } + } + + private void WriteRamModeEMainRegion080B(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCellMixedText(address - 0x0800); // [ndhires &] text40 page2 + } + } + + private void WriteRamModeEMainRegion203F(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCellMixed(address - 0x2000); // ndhires [& text40] page1 + } + } + + private void WriteRamModeEMainRegion405F(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCellMixed(address - 0x4000); // ndhires [& text40] page2 + } + } + + private void WriteRamModeFMainRegion0407(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCellMixedText(address - 0x0400); // [dhires &] text80 page1 + } + } + + private void WriteRamModeFMainRegion080B(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCellMixedText(address - 0x0800); // [dhires &] text80 page2 + } + } + + private void WriteRamModeFMainRegion203F(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCellMixed(address - 0x2000); // dhires [& text80] page1 + } + } + + private void WriteRamModeFMainRegion405F(int address, byte data) + { + if (_ramMainRegion02BF[address - 0x0200] != data) + { + _ramMainRegion02BF[address - 0x0200] = data; + _video.DirtyCellMixed(address - 0x4000); // dhires [& text80] page2 + } + } + + private void WriteRamModeFAuxRegion0407(int address, byte data) + { + if (_ramAuxRegion02BF[address - 0x0200] != data) + { + _ramAuxRegion02BF[address - 0x0200] = data; + _video.DirtyCellMixedText(address - 0x0400); // [dhires &] text80 page1 + } + } + + private void WriteRamModeFAuxRegion080B(int address, byte data) + { + if (_ramAuxRegion02BF[address - 0x0200] != data) + { + _ramAuxRegion02BF[address - 0x0200] = data; + _video.DirtyCellMixedText(address - 0x0800); // [dhires &] text80 page2 + } + } + + private void WriteRamModeFAuxRegion203F(int address, byte data) + { + if (_ramAuxRegion02BF[address - 0x0200] != data) + { + _ramAuxRegion02BF[address - 0x0200] = data; + _video.DirtyCellMixed(address - 0x2000); // dhires [& text80] page1 + } + } + + private void WriteRamModeFAuxRegion405F(int address, byte data) + { + if (_ramAuxRegion02BF[address - 0x0200] != data) + { + _ramAuxRegion02BF[address - 0x0200] = data; + _video.DirtyCellMixed(address - 0x4000); // dhires [& text80] page2 + } + } + + private void WriteRomRegionC1FF(int address, byte data) + { + } + #endregion + + #region Softswitch Actions + private void MapRegion0001() + { + if (!IsZeroPageAux) + { + _regionRead[Region0001] = _ramMainRegion0001; + _regionWrite[Region0001] = _ramMainRegion0001; + _zeroPage = _ramMainRegion0001; + } + else + { + _regionRead[Region0001] = _ramAuxRegion0001; + _regionWrite[Region0001] = _ramAuxRegion0001; + _zeroPage = _ramAuxRegion0001; + } + _writeRegion[Region0001] = null; + } + + private void MapRegion02BF() + { + if (!IsRamReadAux) + { + _regionRead[Region02BF] = _ramMainRegion02BF; + _regionRead[Region080B] = _ramMainRegion02BF; + _regionRead[Region405F] = _ramMainRegion02BF; + } + else + { + _regionRead[Region02BF] = _ramAuxRegion02BF; + _regionRead[Region080B] = _ramAuxRegion02BF; + _regionRead[Region405F] = _ramAuxRegion02BF; + } + int mode = VideoMode; + if (!IsRamWriteAux) + { + _regionWrite[Region02BF] = _ramMainRegion02BF; + _regionWrite[Region080B] = _ramMainRegion02BF; + _regionWrite[Region405F] = _ramMainRegion02BF; + _writeRegion[Region02BF] = null; + _writeRegion[Region080B] = WriteRamModeBankRegion[mode][BankMain][Region080B]; + _writeRegion[Region405F] = WriteRamModeBankRegion[mode][BankMain][Region405F]; + } + else + { + _regionWrite[Region02BF] = _ramAuxRegion02BF; + _regionWrite[Region080B] = _ramAuxRegion02BF; + _regionWrite[Region405F] = _ramAuxRegion02BF; + _writeRegion[Region02BF] = null; + _writeRegion[Region080B] = WriteRamModeBankRegion[mode][BankAux][Region080B]; + _writeRegion[Region405F] = WriteRamModeBankRegion[mode][BankAux][Region405F]; + } + MapRegion0407(); + MapRegion203F(); + } + + private void MapRegion0407() + { + if (!IsRamReadAuxRegion0407) + { + _regionRead[Region0407] = _ramMainRegion02BF; + } + else + { + _regionRead[Region0407] = _ramAuxRegion02BF; + } + int mode = VideoMode; + if (!IsRamWriteAuxRegion0407) + { + _regionWrite[Region0407] = _ramMainRegion02BF; + _writeRegion[Region0407] = WriteRamModeBankRegion[mode][BankMain][Region0407]; + } + else + { + _regionWrite[Region0407] = _ramAuxRegion02BF; + _writeRegion[Region0407] = WriteRamModeBankRegion[mode][BankAux][Region0407]; + } + } + + private void MapRegion203F() + { + if (!IsRamReadAuxRegion203F) + { + _regionRead[Region203F] = _ramMainRegion02BF; + } + else + { + _regionRead[Region203F] = _ramAuxRegion02BF; + } + int mode = VideoMode; + if (!IsRamWriteAuxRegion203F) + { + _regionWrite[Region203F] = _ramMainRegion02BF; + _writeRegion[Region203F] = WriteRamModeBankRegion[mode][BankMain][Region203F]; + } + else + { + _regionWrite[Region203F] = _ramAuxRegion02BF; + _writeRegion[Region203F] = WriteRamModeBankRegion[mode][BankAux][Region203F]; + } + } + + private void MapRegionC0CF() + { + _regionRead[RegionC0C0] = null; + if (IsRomCXXXInternal) + { + _regionRead[RegionC1C7] = _romInternalRegionC1CF; + _regionRead[RegionC3C3] = _romInternalRegionC1CF; + _regionRead[RegionC8CF] = _romInternalRegionC1CF; + } + else + { + _regionRead[RegionC1C7] = _romExternalRegionC1CF; + _regionRead[RegionC3C3] = IsRomC3XXExternal ? _romExternalRegionC1CF : _romInternalRegionC1CF; + _regionRead[RegionC8CF] = _romExternalRegionC1CF; + } + _regionWrite[RegionC0C0] = null; + _regionWrite[RegionC1C7] = null; + _regionWrite[RegionC3C3] = null; + _regionWrite[RegionC8CF] = null; + _writeRegion[RegionC0C0] = WriteIoC0XX; + _writeRegion[RegionC1C7] = WriteRomRegionC1FF; + _writeRegion[RegionC3C3] = WriteRomRegionC1FF; + _writeRegion[RegionC8CF] = WriteRomRegionC1FF; + } + + private void MapRegionD0FF() + { + if (IsHighRamRead) + { + if (!IsHighRamAux) + { + _regionRead[RegionD0DF] = IsHighRamBank1 ? _ramMainBank1RegionD0DF : _ramMainBank2RegionD0DF; + _regionRead[RegionE0FF] = _ramMainRegionE0FF; + } + else + { + _regionRead[RegionD0DF] = IsHighRamBank1 ? _ramAuxBank1RegionD0DF : _ramAuxBank2RegionD0DF; + _regionRead[RegionE0FF] = _ramAuxRegionE0FF; + } + } + else + { + _regionRead[RegionD0DF] = _romRegionD0DF; + _regionRead[RegionE0FF] = _romRegionE0FF; + } + if (IsHighRamWrite) + { + if (!IsHighRamAux) + { + _regionWrite[RegionD0DF] = IsHighRamBank1 ? _ramMainBank1RegionD0DF : _ramMainBank2RegionD0DF; + _regionWrite[RegionE0FF] = _ramMainRegionE0FF; + } + else + { + _regionWrite[RegionD0DF] = IsHighRamBank1 ? _ramAuxBank1RegionD0DF : _ramAuxBank2RegionD0DF; + _regionWrite[RegionE0FF] = _ramAuxRegionE0FF; + } + _writeRegion[RegionD0DF] = null; + _writeRegion[RegionE0FF] = null; + } + else + { + _regionWrite[RegionD0DF] = null; + _regionWrite[RegionE0FF] = null; + _writeRegion[RegionD0DF] = WriteRomRegionC1FF; + _writeRegion[RegionE0FF] = WriteRomRegionC1FF; + } + } + + private void Set80Columns(bool value) + { + if (!TestState(State80Col, value)) + { + SetState(State80Col, value); + MapRegion02BF(); + _video.DirtyScreen(); + } + } + + private void Set80Store(bool value) + { + if (!TestState(State80Store, value)) + { + SetState(State80Store, value); + if (IsPage2) // [5-7, 8-19] + { + MapRegion02BF(); + _video.DirtyScreen(); + } + else + { + MapRegion0407(); + MapRegion203F(); + } + } + } + + private void SetAnnunciator0(bool value) + { + SetState(StateAn0, value); + } + + private void SetAnnunciator1(bool value) + { + SetState(StateAn1, value); + } + + private void SetAnnunciator2(bool value) + { + SetState(StateAn2, value); + } + + private void SetAnnunciator3(bool value) + { + SetState(StateAn3, value); + } + + private void SetCharSet(bool value) + { + if (!TestState(StateAltChrSet, value)) + { + SetState(StateAltChrSet, value); + _video.SetCharSet(); + } + } + + private void SetDoubleRes(bool value) + { + if (!TestState(StateDRes, value)) + { + SetState(StateDRes, value); + MapRegion02BF(); + _video.DirtyScreen(); + } + } + + private void SetHighRam(int address, bool isRead) + { + SetState(StateBank1, TestBit(address, 3)); // A3 [5-22] + SetState(StateHRamRd, TestMask(address, 0x3, 0x3) || TestMask(address, 0x3, 0x0)); // A0.A1+A0'.A1' [5-23] (5-22 misprint) + if (TestBit(address, 0)) // A0 [5-23] + { + if (isRead && TestState(StateHRamPreWrt)) + { + ResetState(StateHRamWrt); // HRamWrt' [5-23] + } + } + else + { + SetState(StateHRamWrt); + } + SetState(StateHRamPreWrt, isRead && TestBit(address, 0)); // A0.R/W' [5-22] + MapRegionD0FF(); + } + + private void SetHires(bool value) + { + if (!TestState(StateHires, value)) + { + SetState(StateHires, value); + if (!Is80Store) // [5-7, 8-19] + { + MapRegion02BF(); + _video.DirtyScreen(); + } + else + { + MapRegion203F(); + } + } + } + + private void SetMixed(bool value) + { + if (!TestState(StateMixed, value)) + { + SetState(StateMixed, value); + MapRegion02BF(); + _video.DirtyScreen(); + } + } + + private void SetPage2(bool value) + { + if (!TestState(StatePage2, value)) + { + SetState(StatePage2, value); + if (!Is80Store) // [5-7, 8-19] + { + MapRegion02BF(); + _video.DirtyScreen(); + } + else + { + MapRegion0407(); + MapRegion203F(); + } + } + } + + private void SetRamRead(bool value) + { + if (!TestState(StateRamRd, value)) + { + SetState(StateRamRd, value); + MapRegion02BF(); + } + } + + private void SetRamWrite(bool value) + { + if (!TestState(StateRamWrt, value)) + { + SetState(StateRamWrt, value); + MapRegion02BF(); + } + } + + private void SetRomC3XX(bool value) + { + if (!TestState(StateSlotC3Rom, value)) + { + SetState(StateSlotC3Rom, value); + MapRegionC0CF(); + } + } + + private void SetRomCXXX(bool value) + { + if (!TestState(StateIntCXRom, value)) + { + SetState(StateIntCXRom, value); + MapRegionC0CF(); + } + } + + private void SetText(bool value) + { + if (!TestState(StateText, value)) + { + SetState(StateText, value); + MapRegion02BF(); + _video.DirtyScreen(); + } + } + + private void SetZeroPage(bool value) + { + if (!TestState(StateAltZP, value)) + { + SetState(StateAltZP, value); + MapRegion0001(); + MapRegionD0FF(); + } + } + #endregion + + private static int SetBit7(int data, bool value) + { + return value ? (data | 0x80) : (data & 0x7F); + } + + private static bool TestBit(int data, int bit) + { + return ((data & (0x1 << bit)) != 0x0); + } + + private static bool TestMask(int data, int mask, int value) + { + return ((data & mask) == value); + } + + private void ResetState(int mask) + { + _state &= ~mask; + } + + private void SetState(int mask) + { + _state |= mask; + } + + private void SetState(int mask, bool value) + { + if (value) + { + _state |= mask; + } + else + { + _state &= ~mask; + } + } + + private bool TestState(int mask) + { + return ((_state & mask) != 0x0); + } + + private bool TestState(int mask, bool value) + { + return (((_state & mask) != 0x0) == value); + } + + private bool TestState(int mask, int value) + { + return ((_state & mask) == value); + } + + public bool Is80Columns { get { return TestState(State80Col); } } + public bool Is80Store { get { return TestState(State80Store); } } + public bool IsAnnunciator0 { get { return TestState(StateAn0); } } + public bool IsAnnunciator1 { get { return TestState(StateAn1); } } + public bool IsAnnunciator2 { get { return TestState(StateAn2); } } + public bool IsAnnunciator3 { get { return TestState(StateAn3); } } + public bool IsCharSetAlternate { get { return TestState(StateAltChrSet); } } + public bool IsDoubleRes { get { return TestState(StateDRes); } } + public bool IsHighRamAux { get { return IsZeroPageAux; } } + public bool IsHighRamBank1 { get { return TestState(StateBank1); } } + public bool IsHighRamRead { get { return TestState(StateHRamRd); } } + public bool IsHighRamWrite { get { return !TestState(StateHRamWrt); } } // HRamWrt' [5-23] + public bool IsHires { get { return TestState(StateHires); } } + public bool IsMixed { get { return TestState(StateMixed); } } + public bool IsPage2 { get { return TestState(StatePage2); } } + public bool IsRamReadAux { get { return TestState(StateRamRd); } } + public bool IsRamReadAuxRegion0407 { get { return Is80Store ? IsPage2 : IsRamReadAux; } } + public bool IsRamReadAuxRegion203F { get { return TestState(State80Store | StateHires, State80Store | StateHires) ? IsPage2 : IsRamReadAux; } } + public bool IsRamWriteAux { get { return TestState(StateRamWrt); } } + public bool IsRamWriteAuxRegion0407 { get { return Is80Store ? IsPage2 : IsRamWriteAux; } } + public bool IsRamWriteAuxRegion203F { get { return TestState(State80Store | StateHires, State80Store | StateHires) ? IsPage2 : IsRamWriteAux; } } + public bool IsRomC3XXExternal { get { return TestState(StateSlotC3Rom); } } + public bool IsRomCXXXInternal { get { return TestState(StateIntCXRom); } } + public bool IsText { get { return TestState(StateText); } } + public bool IsVideoPage2 { get { return TestState(State80Store | StatePage2, StatePage2); } } // 80Store inhibits video Page2 [5-7, 8-19] + public bool IsZeroPageAux { get { return TestState(StateAltZP); } } + + public MonitorType Monitor { get; private set; } + public int VideoMode { get { return StateVideoMode[_state & StateVideo]; } } + + private DiskII _diskII; + private Keyboard _keyboard; + private GamePort _gamePort; + private Cassette _cassette; + private Speaker _speaker; + private Video _video; + + private int _state; + + 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/Virtu/MemoryData.cs b/Virtu/MemoryData.cs index 6b5e1ed..0fc7111 100644 --- a/Virtu/MemoryData.cs +++ b/Virtu/MemoryData.cs @@ -1,105 +1,105 @@ -using System; - -namespace Jellyfish.Virtu -{ - public partial class Memory - { - private const int BankCount = 2; - - private const int BankMain = 0; - private const int BankAux = 1; - - private const int RegionCount = 12; - - private const int Region0001 = 0; - private const int Region02BF = 1; - private const int Region0407 = 2; - private const int Region080B = 3; - private const int Region203F = 4; - private const int Region405F = 5; - private const int RegionC0C0 = 6; - private const int RegionC1C7 = 7; - private const int RegionC3C3 = 8; - private const int RegionC8CF = 9; - private const int RegionD0DF = 10; - private const int RegionE0FF = 11; - - private static readonly int[] RegionBaseAddress = new int[RegionCount] - { - 0x0000, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, 0xC000, 0xC100, 0xC100, 0xC100, 0xD000, 0xE000 - }; - - private const int PageCount = 256; - - private static readonly int[] PageRegion = new int[PageCount] - { - Region0001, Region0001, Region02BF, Region02BF, Region0407, Region0407, Region0407, Region0407, - Region080B, Region080B, Region080B, Region080B, Region02BF, Region02BF, Region02BF, Region02BF, - Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, - Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, - Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, - Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, - Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, - Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, - Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, - Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, - Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, - Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, - Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, - Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, - Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, - Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, - Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, - Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, - Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, - Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, - Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, - Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, - Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, - Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, - RegionC0C0, RegionC1C7, RegionC1C7, RegionC3C3, RegionC1C7, RegionC1C7, RegionC1C7, RegionC1C7, - RegionC8CF, RegionC8CF, RegionC8CF, RegionC8CF, RegionC8CF, RegionC8CF, RegionC8CF, RegionC8CF, - RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, - RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, - RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, - RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, - RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, - RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF - }; - - private const int State80Col = 0x000001; - private const int StateText = 0x000002; - private const int StateMixed = 0x000004; - private const int StateHires = 0x000008; - private const int StateDRes = 0x000010; - private const int State80Store = 0x000020; - private const int StateAltChrSet = 0x000040; - private const int StateAltZP = 0x000080; - private const int StateBank1 = 0x000100; - private const int StateHRamRd = 0x000200; - private const int StateHRamPreWrt = 0x000400; - private const int StateHRamWrt = 0x000800; - private const int StatePage2 = 0x001000; - private const int StateRamRd = 0x002000; - private const int StateRamWrt = 0x004000; - private const int StateSlotC3Rom = 0x008000; - private const int StateIntCXRom = 0x010000; - private const int StateAn0 = 0x020000; - private const int StateAn1 = 0x040000; - private const int StateAn2 = 0x080000; - private const int StateAn3 = 0x100000; - private const int StateVideo = State80Col | StateText | StateMixed | StateHires | StateDRes; - - private const int StateVideoModeCount = 32; - - private static readonly int[] StateVideoMode = new int[StateVideoModeCount] - { - Video.Mode0, Video.Mode0, Video.Mode1, Video.Mode2, Video.Mode3, Video.Mode4, Video.Mode1, Video.Mode2, - Video.Mode5, Video.Mode5, Video.Mode1, Video.Mode2, Video.Mode6, Video.Mode7, Video.Mode1, Video.Mode2, - Video.Mode8, Video.Mode9, Video.Mode1, Video.Mode2, Video.ModeA, Video.ModeB, Video.Mode1, Video.Mode2, - Video.ModeC, Video.ModeD, Video.Mode1, Video.Mode2, Video.ModeE, Video.ModeF, Video.Mode1, Video.Mode2 - }; - - private readonly Action[][][] WriteRamModeBankRegion; - } -} +using System; + +namespace Jellyfish.Virtu +{ + public partial class Memory + { + private const int BankCount = 2; + + private const int BankMain = 0; + private const int BankAux = 1; + + private const int RegionCount = 12; + + private const int Region0001 = 0; + private const int Region02BF = 1; + private const int Region0407 = 2; + private const int Region080B = 3; + private const int Region203F = 4; + private const int Region405F = 5; + private const int RegionC0C0 = 6; + private const int RegionC1C7 = 7; + private const int RegionC3C3 = 8; + private const int RegionC8CF = 9; + private const int RegionD0DF = 10; + private const int RegionE0FF = 11; + + private static readonly int[] RegionBaseAddress = new int[RegionCount] + { + 0x0000, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, 0xC000, 0xC100, 0xC100, 0xC100, 0xD000, 0xE000 + }; + + private const int PageCount = 256; + + private static readonly int[] PageRegion = new int[PageCount] + { + Region0001, Region0001, Region02BF, Region02BF, Region0407, Region0407, Region0407, Region0407, + Region080B, Region080B, Region080B, Region080B, Region02BF, Region02BF, Region02BF, Region02BF, + Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, + Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, + Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, + Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, + Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, + Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, + Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, + Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, + Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, + Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, + Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, + Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, + Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, + Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, + Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, + Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, + Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, + Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, + Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, + Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, + Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, + Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, + RegionC0C0, RegionC1C7, RegionC1C7, RegionC3C3, RegionC1C7, RegionC1C7, RegionC1C7, RegionC1C7, + RegionC8CF, RegionC8CF, RegionC8CF, RegionC8CF, RegionC8CF, RegionC8CF, RegionC8CF, RegionC8CF, + RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, + RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, + RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, + RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, + RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, + RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF + }; + + private const int State80Col = 0x000001; + private const int StateText = 0x000002; + private const int StateMixed = 0x000004; + private const int StateHires = 0x000008; + private const int StateDRes = 0x000010; + private const int State80Store = 0x000020; + private const int StateAltChrSet = 0x000040; + private const int StateAltZP = 0x000080; + private const int StateBank1 = 0x000100; + private const int StateHRamRd = 0x000200; + private const int StateHRamPreWrt = 0x000400; + private const int StateHRamWrt = 0x000800; + private const int StatePage2 = 0x001000; + private const int StateRamRd = 0x002000; + private const int StateRamWrt = 0x004000; + private const int StateSlotC3Rom = 0x008000; + private const int StateIntCXRom = 0x010000; + private const int StateAn0 = 0x020000; + private const int StateAn1 = 0x040000; + private const int StateAn2 = 0x080000; + private const int StateAn3 = 0x100000; + private const int StateVideo = State80Col | StateText | StateMixed | StateHires | StateDRes; + + private const int StateVideoModeCount = 32; + + private static readonly int[] StateVideoMode = new int[StateVideoModeCount] + { + Video.Mode0, Video.Mode0, Video.Mode1, Video.Mode2, Video.Mode3, Video.Mode4, Video.Mode1, Video.Mode2, + Video.Mode5, Video.Mode5, Video.Mode1, Video.Mode2, Video.Mode6, Video.Mode7, Video.Mode1, Video.Mode2, + Video.Mode8, Video.Mode9, Video.Mode1, Video.Mode2, Video.ModeA, Video.ModeB, Video.Mode1, Video.Mode2, + Video.ModeC, Video.ModeD, Video.Mode1, Video.Mode2, Video.ModeE, Video.ModeF, Video.Mode1, Video.Mode2 + }; + + private readonly Action[][][] WriteRamModeBankRegion; + } +} diff --git a/Virtu/Properties/SR.Designer.cs b/Virtu/Properties/SR.Designer.cs index 18dcb5d..e63de99 100644 --- a/Virtu/Properties/SR.Designer.cs +++ b/Virtu/Properties/SR.Designer.cs @@ -1,99 +1,99 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:2.0.50727.4927 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Jellyfish.Virtu.Properties { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class SR { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal SR() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Jellyfish.Virtu.Properties.SR", typeof(SR).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized string similar to Resource '{0}' invalid.. - /// - internal static string ResourceInvalid { - get { - return ResourceManager.GetString("ResourceInvalid", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Resource '{0}' not found.. - /// - internal static string ResourceNotFound { - get { - return ResourceManager.GetString("ResourceNotFound", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Service type '{0}' already present.. - /// - internal static string ServiceAlreadyPresent { - get { - return ResourceManager.GetString("ServiceAlreadyPresent", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Service type '{0}' must be assignable from service provider '{1}'.. - /// - internal static string ServiceMustBeAssignable { - get { - return ResourceManager.GetString("ServiceMustBeAssignable", resourceCulture); - } - } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:2.0.50727.4927 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Jellyfish.Virtu.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class SR { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal SR() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Jellyfish.Virtu.Properties.SR", typeof(SR).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Resource '{0}' invalid.. + /// + internal static string ResourceInvalid { + get { + return ResourceManager.GetString("ResourceInvalid", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Resource '{0}' not found.. + /// + internal static string ResourceNotFound { + get { + return ResourceManager.GetString("ResourceNotFound", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Service type '{0}' already present.. + /// + internal static string ServiceAlreadyPresent { + get { + return ResourceManager.GetString("ServiceAlreadyPresent", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Service type '{0}' must be assignable from service provider '{1}'.. + /// + internal static string ServiceMustBeAssignable { + get { + return ResourceManager.GetString("ServiceMustBeAssignable", resourceCulture); + } + } + } +} diff --git a/Virtu/Properties/SR.resx b/Virtu/Properties/SR.resx index 3ca952f..1d6660e 100644 --- a/Virtu/Properties/SR.resx +++ b/Virtu/Properties/SR.resx @@ -1,132 +1,132 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Resource '{0}' not found. - - - Resource '{0}' invalid. - - - Service type '{0}' already present. - - - Service type '{0}' must be assignable from service provider '{1}'. - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Resource '{0}' not found. + + + Resource '{0}' invalid. + + + Service type '{0}' already present. + + + Service type '{0}' must be assignable from service provider '{1}'. + \ No newline at end of file diff --git a/Virtu/Services/AudioService.cs b/Virtu/Services/AudioService.cs index 819589b..10595c7 100644 --- a/Virtu/Services/AudioService.cs +++ b/Virtu/Services/AudioService.cs @@ -1,67 +1,67 @@ -using System; -using System.Threading; - -namespace Jellyfish.Virtu.Services -{ - public class AudioService : MachineService - { - public AudioService(Machine machine) : - base(machine) - { - } - - public void Output(int data) // machine thread - { - _buffer[_index] = (byte)data; - _index = (_index + 1) % SampleSize; - if (_index == 0) - { - _readEvent.Set(); - if (Machine.Settings.Cpu.IsThrottled) - { - _writeEvent.WaitOne(); - } - } - } - - public void Reset() - { - Buffer.BlockCopy(SampleZero, 0, _buffer, 0, SampleSize); - } - - public override void Stop() // main thread - { - _readEvent.Set(); // signal events; avoids deadlock - _writeEvent.Set(); - } - - protected void Update(int bufferSize, Action updateBuffer) // audio thread - { - if (updateBuffer == null) - { - throw new ArgumentNullException("updateBuffer"); - } - - if (Machine.State == MachineState.Running) - { - _readEvent.WaitOne(); - } - updateBuffer(_buffer, bufferSize); - _writeEvent.Set(); - } - - public const int SampleRate = 44100; // hz - public const int SampleChannels = 1; - public const int SampleBits = 8; - public const int SampleLatency = 40; // ms - public const int SampleSize = (SampleRate * SampleLatency / 1000) * SampleChannels * (SampleBits / 8); - - private static readonly byte[] SampleZero = new byte[SampleSize]; - - private byte[] _buffer = new byte[SampleSize]; - private int _index; - - private AutoResetEvent _readEvent = new AutoResetEvent(false); - private AutoResetEvent _writeEvent = new AutoResetEvent(false); - } -} +using System; +using System.Threading; + +namespace Jellyfish.Virtu.Services +{ + public class AudioService : MachineService + { + public AudioService(Machine machine) : + base(machine) + { + } + + public void Output(int data) // machine thread + { + _buffer[_index] = (byte)data; + _index = (_index + 1) % SampleSize; + if (_index == 0) + { + _readEvent.Set(); + if (Machine.Settings.Cpu.IsThrottled) + { + _writeEvent.WaitOne(); + } + } + } + + public void Reset() + { + Buffer.BlockCopy(SampleZero, 0, _buffer, 0, SampleSize); + } + + public override void Stop() // main thread + { + _readEvent.Set(); // signal events; avoids deadlock + _writeEvent.Set(); + } + + protected void Update(int bufferSize, Action updateBuffer) // audio thread + { + if (updateBuffer == null) + { + throw new ArgumentNullException("updateBuffer"); + } + + if (Machine.State == MachineState.Running) + { + _readEvent.WaitOne(); + } + updateBuffer(_buffer, bufferSize); + _writeEvent.Set(); + } + + public const int SampleRate = 44100; // hz + public const int SampleChannels = 1; + public const int SampleBits = 8; + public const int SampleLatency = 40; // ms + public const int SampleSize = (SampleRate * SampleLatency / 1000) * SampleChannels * (SampleBits / 8); + + private static readonly byte[] SampleZero = new byte[SampleSize]; + + private byte[] _buffer = new byte[SampleSize]; + private int _index; + + private AutoResetEvent _readEvent = new AutoResetEvent(false); + private AutoResetEvent _writeEvent = new AutoResetEvent(false); + } +} diff --git a/Virtu/Services/GamePortService.cs b/Virtu/Services/GamePortService.cs index 395eebb..012a5f4 100644 --- a/Virtu/Services/GamePortService.cs +++ b/Virtu/Services/GamePortService.cs @@ -1,73 +1,73 @@ -namespace Jellyfish.Virtu.Services -{ - public struct Joystick - { - public Joystick(bool isUp, bool isLeft, bool isRight, bool isDown) - { - _isUp = isUp; - _isLeft = isLeft; - _isRight = isRight; - _isDown = isDown; - } - - public override bool Equals(object obj) - { - return ((obj is Joystick) && (this == (Joystick)obj)); - } - - public override int GetHashCode() - { - return (_isUp.GetHashCode() ^ _isLeft.GetHashCode() ^ _isRight.GetHashCode() ^ _isDown.GetHashCode()); - } - - public override string ToString() - { - return !(_isUp || _isDown || _isLeft || _isRight) ? "Position = Center" : - string.Concat("Position = ", _isUp ? "Up" : _isDown ? "Down" : string.Empty, _isLeft ? "Left" : _isRight ? "Right" : string.Empty); - } - - public static bool operator ==(Joystick joystick1, Joystick joystick2) - { - return ((joystick1._isUp == joystick2._isUp) && (joystick1._isLeft == joystick2._isLeft) && - (joystick1._isRight == joystick2._isRight) && (joystick1._isDown == joystick2._isDown)); - } - - public static bool operator !=(Joystick joystick1, Joystick joystick2) - { - return !(joystick1 == joystick2); - } - - public bool IsUp { get { return _isUp; } } // no auto props - public bool IsLeft { get { return _isLeft; } } - public bool IsRight { get { return _isRight; } } - public bool IsDown { get { return _isDown; } } - - private bool _isUp; - private bool _isLeft; - private bool _isRight; - private bool _isDown; - } - - public class GamePortService : MachineService - { - public GamePortService(Machine machine) : - base(machine) - { - Paddle0 = Paddle1 = Paddle2 = Paddle3 = 255; // not connected - } - - public virtual void Update() { } // main thread - - public int Paddle0 { get; protected set; } - public int Paddle1 { get; protected set; } - public int Paddle2 { get; protected set; } - public int Paddle3 { get; protected set; } - - public Joystick Joystick0 { get; protected set; } - public Joystick Joystick1 { get; protected set; } - - public bool IsButton0Down { get; protected set; } - public bool IsButton1Down { get; protected set; } - public bool IsButton2Down { get; protected set; } - } -} +namespace Jellyfish.Virtu.Services +{ + public struct Joystick + { + public Joystick(bool isUp, bool isLeft, bool isRight, bool isDown) + { + _isUp = isUp; + _isLeft = isLeft; + _isRight = isRight; + _isDown = isDown; + } + + public override bool Equals(object obj) + { + return ((obj is Joystick) && (this == (Joystick)obj)); + } + + public override int GetHashCode() + { + return (_isUp.GetHashCode() ^ _isLeft.GetHashCode() ^ _isRight.GetHashCode() ^ _isDown.GetHashCode()); + } + + public override string ToString() + { + return !(_isUp || _isDown || _isLeft || _isRight) ? "Position = Center" : + string.Concat("Position = ", _isUp ? "Up" : _isDown ? "Down" : string.Empty, _isLeft ? "Left" : _isRight ? "Right" : string.Empty); + } + + public static bool operator ==(Joystick joystick1, Joystick joystick2) + { + return ((joystick1._isUp == joystick2._isUp) && (joystick1._isLeft == joystick2._isLeft) && + (joystick1._isRight == joystick2._isRight) && (joystick1._isDown == joystick2._isDown)); + } + + public static bool operator !=(Joystick joystick1, Joystick joystick2) + { + return !(joystick1 == joystick2); + } + + public bool IsUp { get { return _isUp; } } // no auto props + public bool IsLeft { get { return _isLeft; } } + public bool IsRight { get { return _isRight; } } + public bool IsDown { get { return _isDown; } } + + private bool _isUp; + private bool _isLeft; + private bool _isRight; + private bool _isDown; + } + + public class GamePortService : MachineService + { + public GamePortService(Machine machine) : + base(machine) + { + Paddle0 = Paddle1 = Paddle2 = Paddle3 = 255; // not connected + } + + public virtual void Update() { } // main thread + + public int Paddle0 { get; protected set; } + public int Paddle1 { get; protected set; } + public int Paddle2 { get; protected set; } + public int Paddle3 { get; protected set; } + + public Joystick Joystick0 { get; protected set; } + public Joystick Joystick1 { get; protected set; } + + public bool IsButton0Down { get; protected set; } + public bool IsButton1Down { get; protected set; } + public bool IsButton2Down { get; protected set; } + } +} diff --git a/Virtu/Services/KeyboardService.cs b/Virtu/Services/KeyboardService.cs index bebfbd0..f50d51a 100644 --- a/Virtu/Services/KeyboardService.cs +++ b/Virtu/Services/KeyboardService.cs @@ -1,70 +1,70 @@ -using System; -using System.Threading; - -namespace Jellyfish.Virtu.Services -{ - public sealed class AsciiKeyEventArgs : EventArgs - { - private AsciiKeyEventArgs() - { - } - - public static AsciiKeyEventArgs Create(int asciiKey) - { - _instance.AsciiKey = asciiKey; - - return _instance; // use singleton; avoids garbage - } - - public int AsciiKey { get; private set; } - - private static readonly AsciiKeyEventArgs _instance = new AsciiKeyEventArgs(); - } - - public abstract class KeyboardService : MachineService - { - protected KeyboardService(Machine machine) : - base(machine) - { - } - - public abstract bool IsKeyDown(int key); - - public virtual void Update() // main thread - { - if (IsResetKeyDown) - { - if (!_resetKeyDown) - { - _resetKeyDown = true; // entering reset; pause until key released - Machine.Pause(); - Machine.Reset(); - } - } - else if (_resetKeyDown) - { - _resetKeyDown = false; // leaving reset - Machine.Unpause(); - } - } - - protected void OnAsciiKeyDown(int asciiKey) - { - EventHandler handler = AsciiKeyDown; - if (handler != null) - { - handler(this, AsciiKeyEventArgs.Create(asciiKey)); - } - } - - public event EventHandler AsciiKeyDown; - - public bool IsAnyKeyDown { get; protected set; } - public bool IsOpenAppleKeyDown { get; protected set; } - public bool IsCloseAppleKeyDown { get; protected set; } - - protected bool IsResetKeyDown { get; set; } - - private bool _resetKeyDown; - } -} +using System; +using System.Threading; + +namespace Jellyfish.Virtu.Services +{ + public sealed class AsciiKeyEventArgs : EventArgs + { + private AsciiKeyEventArgs() + { + } + + public static AsciiKeyEventArgs Create(int asciiKey) + { + _instance.AsciiKey = asciiKey; + + return _instance; // use singleton; avoids garbage + } + + public int AsciiKey { get; private set; } + + private static readonly AsciiKeyEventArgs _instance = new AsciiKeyEventArgs(); + } + + public abstract class KeyboardService : MachineService + { + protected KeyboardService(Machine machine) : + base(machine) + { + } + + public abstract bool IsKeyDown(int key); + + public virtual void Update() // main thread + { + if (IsResetKeyDown) + { + if (!_resetKeyDown) + { + _resetKeyDown = true; // entering reset; pause until key released + Machine.Pause(); + Machine.Reset(); + } + } + else if (_resetKeyDown) + { + _resetKeyDown = false; // leaving reset + Machine.Unpause(); + } + } + + protected void OnAsciiKeyDown(int asciiKey) + { + EventHandler handler = AsciiKeyDown; + if (handler != null) + { + handler(this, AsciiKeyEventArgs.Create(asciiKey)); + } + } + + public event EventHandler AsciiKeyDown; + + public bool IsAnyKeyDown { get; protected set; } + public bool IsOpenAppleKeyDown { get; protected set; } + public bool IsCloseAppleKeyDown { get; protected set; } + + protected bool IsResetKeyDown { get; set; } + + private bool _resetKeyDown; + } +} diff --git a/Virtu/Services/MachineServices.cs b/Virtu/Services/MachineServices.cs index 766181e..e05d360 100644 --- a/Virtu/Services/MachineServices.cs +++ b/Virtu/Services/MachineServices.cs @@ -1,57 +1,57 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using Jellyfish.Library; -using Jellyfish.Virtu.Properties; - -namespace Jellyfish.Virtu.Services -{ - public sealed class MachineServices : IServiceProvider - { - public void AddService(Type serviceType, MachineService serviceProvider) - { - if (serviceType == null) - { - throw new ArgumentNullException("serviceType"); - } - if (_serviceProviders.ContainsKey(serviceType)) - { - throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, SR.ServiceAlreadyPresent, serviceType.FullName), "serviceType"); - } - if (serviceProvider == null) - { - throw new ArgumentNullException("serviceProvider"); - } - if (!serviceType.IsAssignableFrom(serviceProvider.GetType())) - { - throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, SR.ServiceMustBeAssignable, serviceType.FullName, serviceProvider.GetType().FullName)); - } - - _serviceProviders.Add(serviceType, serviceProvider); - } - - public void ForEach(Action action) - { - _serviceProviders.Values.ForEach(action); - } - - [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")] - public T GetService() - { - return (T)GetService(typeof(T)); - } - - public object GetService(Type serviceType) - { - return _serviceProviders.ContainsKey(serviceType) ? _serviceProviders[serviceType] : null; - } - - public void RemoveService(Type serviceType) - { - _serviceProviders.Remove(serviceType); - } - - private Dictionary _serviceProviders = new Dictionary(); - } -} +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using Jellyfish.Library; +using Jellyfish.Virtu.Properties; + +namespace Jellyfish.Virtu.Services +{ + public sealed class MachineServices : IServiceProvider + { + public void AddService(Type serviceType, MachineService serviceProvider) + { + if (serviceType == null) + { + throw new ArgumentNullException("serviceType"); + } + if (_serviceProviders.ContainsKey(serviceType)) + { + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, SR.ServiceAlreadyPresent, serviceType.FullName), "serviceType"); + } + if (serviceProvider == null) + { + throw new ArgumentNullException("serviceProvider"); + } + if (!serviceType.IsAssignableFrom(serviceProvider.GetType())) + { + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, SR.ServiceMustBeAssignable, serviceType.FullName, serviceProvider.GetType().FullName)); + } + + _serviceProviders.Add(serviceType, serviceProvider); + } + + public void ForEach(Action action) + { + _serviceProviders.Values.ForEach(action); + } + + [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")] + public T GetService() + { + return (T)GetService(typeof(T)); + } + + public object GetService(Type serviceType) + { + return _serviceProviders.ContainsKey(serviceType) ? _serviceProviders[serviceType] : null; + } + + public void RemoveService(Type serviceType) + { + _serviceProviders.Remove(serviceType); + } + + private Dictionary _serviceProviders = new Dictionary(); + } +} diff --git a/Virtu/Services/StorageService.cs b/Virtu/Services/StorageService.cs index ded98e3..69e8bc0 100644 --- a/Virtu/Services/StorageService.cs +++ b/Virtu/Services/StorageService.cs @@ -1,41 +1,41 @@ -using System; -using System.Globalization; -using System.IO; -using System.Reflection; -using System.Resources; -using Jellyfish.Virtu.Properties; - -namespace Jellyfish.Virtu.Services -{ - public abstract class StorageService : MachineService - { - protected StorageService(Machine machine) : - base(machine) - { - } - - public static Stream GetResourceStream(string resourceName) - { - return GetResourceStream(resourceName, 0); - } - - public static Stream GetResourceStream(string resourceName, int resourceSize) - { - ResourceManager resourceManager = new ResourceManager("Jellyfish.Virtu.g", Assembly.GetExecutingAssembly()) { IgnoreCase = true }; - Stream resourceStream = (Stream)resourceManager.GetObject(resourceName); - if (resourceStream == null) - { - throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, SR.ResourceNotFound, resourceName)); - } - if ((resourceSize > 0) && (resourceStream.Length != resourceSize)) - { - throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, SR.ResourceInvalid, resourceName)); - } - - return resourceStream; - } - - public abstract void Load(string path, Action reader); - public abstract void Save(string path, Action writer); - } -} +using System; +using System.Globalization; +using System.IO; +using System.Reflection; +using System.Resources; +using Jellyfish.Virtu.Properties; + +namespace Jellyfish.Virtu.Services +{ + public abstract class StorageService : MachineService + { + protected StorageService(Machine machine) : + base(machine) + { + } + + public static Stream GetResourceStream(string resourceName) + { + return GetResourceStream(resourceName, 0); + } + + public static Stream GetResourceStream(string resourceName, int resourceSize) + { + var resourceManager = new ResourceManager("Jellyfish.Virtu.g", Assembly.GetExecutingAssembly()) { IgnoreCase = true }; + var resourceStream = (Stream)resourceManager.GetObject(resourceName); + if (resourceStream == null) + { + throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, SR.ResourceNotFound, resourceName)); + } + if ((resourceSize > 0) && (resourceStream.Length != resourceSize)) + { + throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, SR.ResourceInvalid, resourceName)); + } + + return resourceStream; + } + + public abstract void Load(string path, Action reader); + public abstract void Save(string path, Action writer); + } +} diff --git a/Virtu/Services/VideoService.cs b/Virtu/Services/VideoService.cs index e56968c..22c5089 100644 --- a/Virtu/Services/VideoService.cs +++ b/Virtu/Services/VideoService.cs @@ -1,20 +1,20 @@ -namespace Jellyfish.Virtu.Services -{ - public abstract class VideoService : MachineService - { - protected VideoService(Machine machine) : - base(machine) - { - } - - public abstract void SetPixel(int x, int y, uint color); - public abstract void Update(); // main thread - - public void ToggleFullScreen() - { - IsFullScreen ^= true; - } - - public bool IsFullScreen { get; private set; } - } -} +namespace Jellyfish.Virtu.Services +{ + public abstract class VideoService : MachineService + { + protected VideoService(Machine machine) : + base(machine) + { + } + + public abstract void SetPixel(int x, int y, uint color); + public abstract void Update(); // main thread + + public void ToggleFullScreen() + { + IsFullScreen ^= true; + } + + public bool IsFullScreen { get; private set; } + } +} diff --git a/Virtu/Silverlight/MainApp.xaml b/Virtu/Silverlight/MainApp.xaml index 3f31c87..8712cfc 100644 --- a/Virtu/Silverlight/MainApp.xaml +++ b/Virtu/Silverlight/MainApp.xaml @@ -1,11 +1,11 @@ - - - - - - - + + + + + + + diff --git a/Virtu/Silverlight/MainApp.xaml.cs b/Virtu/Silverlight/MainApp.xaml.cs index 1cd9c9d..6054ff5 100644 --- a/Virtu/Silverlight/MainApp.xaml.cs +++ b/Virtu/Silverlight/MainApp.xaml.cs @@ -1,13 +1,13 @@ -using Jellyfish.Library; - -namespace Jellyfish.Virtu -{ - public sealed partial class MainApp : ApplicationBase - { - public MainApp() : - base("Virtu") - { - InitializeComponent(); - } - } -} +using Jellyfish.Library; + +namespace Jellyfish.Virtu +{ + public sealed partial class MainApp : ApplicationBase + { + public MainApp() : + base("Virtu") + { + InitializeComponent(); + } + } +} diff --git a/Virtu/Silverlight/MainPage.xaml b/Virtu/Silverlight/MainPage.xaml index 9b17489..ec21ea7 100644 --- a/Virtu/Silverlight/MainPage.xaml +++ b/Virtu/Silverlight/MainPage.xaml @@ -1,21 +1,21 @@ - - - -