diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..3ce801b
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,14 @@
+# Auto detect text files and perform LF normalization
+* text=auto
+
+# Visual Studio
+*.cs diff=csharp
+*.sln merge=union
+*.csproj merge=union
+
+# Virtu
+*.do binary
+*.dsk binary
+*.nib binary
+*.po binary
+*.rom binary
diff --git a/.gitignore b/.gitignore
index 9110376..fd61d2f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,6 @@
-bin/
-obj/
-
-*.cachefile
-*.suo
-*.user
+bin/
+obj/
+
+*.cachefile
+*.suo
+*.user
diff --git a/Library/AssemblyMetadataAttribute.cs b/Library/AssemblyMetadataAttribute.cs
index e885b60..a2e51e2 100644
--- a/Library/AssemblyMetadataAttribute.cs
+++ b/Library/AssemblyMetadataAttribute.cs
@@ -1,17 +1,17 @@
-using System;
-
-namespace Jellyfish.Library
-{
- [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)]
- public sealed class AssemblyMetadataAttribute : Attribute
- {
- public AssemblyMetadataAttribute(string key, string value)
- {
- Key = key;
- Value = value;
- }
-
- public string Key { get; private set; }
- public string Value { get; private set; }
- }
-}
+using System;
+
+namespace Jellyfish.Library
+{
+ [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)]
+ public sealed class AssemblyMetadataAttribute : Attribute
+ {
+ public AssemblyMetadataAttribute(string key, string value)
+ {
+ Key = key;
+ Value = value;
+ }
+
+ public string Key { get; private set; }
+ public string Value { get; private set; }
+ }
+}
diff --git a/Library/CustomDictionary.xml b/Library/CustomDictionary.xml
index 8f2033b..fa103c8 100644
--- a/Library/CustomDictionary.xml
+++ b/Library/CustomDictionary.xml
@@ -1,9 +1,9 @@
-
-
-
-
- x
- y
-
-
-
+
+
+
+
+ x
+ y
+
+
+
diff --git a/Library/DirectSound.cs b/Library/DirectSound.cs
index 23025bf..62856b8 100644
--- a/Library/DirectSound.cs
+++ b/Library/DirectSound.cs
@@ -1,173 +1,173 @@
-using System;
-using System.Runtime.InteropServices;
-using System.Security;
-using System.Threading;
-
-namespace Jellyfish.Library
-{
- public sealed partial class DirectSound : IDisposable
- {
- [SecurityCritical]
- public DirectSound(int sampleRate, int sampleChannels, int sampleBits, int sampleSize, Action updater)
- {
- _sampleRate = sampleRate;
- _sampleChannels = sampleChannels;
- _sampleBits = sampleBits;
- _sampleSize = sampleSize;
-
- _thread = new Thread(Run) { Name = "DirectSound" };
- _updater = updater;
- }
-
- public void Dispose()
- {
- _position1Event.Close();
- _position2Event.Close();
- _stopEvent.Close();
- }
-
- public void SetVolume(float volume)
- {
- int attenuation = (volume < 0.01) ? (int)BufferVolume.Min : (int)Math.Floor(100 * 20 * Math.Log10(volume)); // 100 db
- lock (_bufferLock)
- {
- if (_buffer != null)
- {
- _buffer.SetVolume(attenuation);
- }
- }
- }
-
- public void Start(IntPtr window)
- {
- _window = window;
- _thread.Start();
- }
-
- public void Stop()
- {
- _stopEvent.Set();
- _thread.Join();
- }
-
- [SecurityCritical]
- private void Initialize()
- {
- int hresult = NativeMethods.DirectSoundCreate(IntPtr.Zero, out _device, IntPtr.Zero);
- if (hresult < 0)
- {
- Marshal.ThrowExceptionForHR(hresult);
- }
-
- _device.SetCooperativeLevel(_window, CooperativeLevel.Normal);
-
- GCHandleHelpers.Pin(new WaveFormat(_sampleRate, _sampleChannels, _sampleBits), waveFormat =>
- {
- var description = new BufferDescription(BufferCapabilities.CtrlPositionNotify | BufferCapabilities.CtrlVolume, BlockCount * _sampleSize, waveFormat);
- _device.CreateSoundBuffer(description, out _buffer, IntPtr.Zero);
- });
- ClearBuffer();
-
- var positionEvents = new BufferPositionNotify[BlockCount]
- {
- new BufferPositionNotify(0 * _sampleSize, _position1Event), new BufferPositionNotify(1 * _sampleSize, _position2Event)
- };
- ((IDirectSoundNotify)_buffer).SetNotificationPositions(positionEvents.Length, positionEvents);
-
- _buffer.Play(0, 0, BufferPlay.Looping);
- }
-
- [SecurityCritical]
- private void ClearBuffer()
- {
- UpdateBuffer(0, 0, BufferLock.EntireBuffer, (buffer, bufferSize) => MarshalHelpers.ZeroMemory(buffer, bufferSize));
- }
-
- private void RestoreBuffer()
- {
- BufferStatus status;
- _buffer.GetStatus(out status);
- if ((status & BufferStatus.BufferLost) != 0)
- {
- _buffer.Restore();
- }
- }
-
- private void UpdateBuffer(int offset, int count, BufferLock flags, Action updater)
- {
- RestoreBuffer();
-
- IntPtr buffer1, buffer2;
- int buffer1Size, buffer2Size;
- _buffer.Lock(offset, count, out buffer1, out buffer1Size, out buffer2, out buffer2Size, flags);
- try
- {
- if (buffer1 != IntPtr.Zero)
- {
- updater(buffer1, buffer1Size);
- }
- if (buffer2 != IntPtr.Zero)
- {
- updater(buffer2, buffer2Size);
- }
- }
- finally
- {
- _buffer.Unlock(buffer1, buffer1Size, buffer2, buffer2Size);
- }
- }
-
- private void Uninitialize()
- {
- lock (_bufferLock)
- {
- if (_buffer != null)
- {
- _buffer.Stop();
- Marshal.ReleaseComObject(_buffer);
- _buffer = null;
- }
- }
- if (_device != null)
- {
- Marshal.ReleaseComObject(_device);
- _device = null;
- }
- }
-
- [SecurityCritical]
- private void Run() // com mta thread
- {
- Initialize();
-
- var eventHandles = new EventWaitHandle[] { _position1Event, _position2Event, _stopEvent };
- int index = WaitHandle.WaitAny(eventHandles);
-
- while (index < BlockCount)
- {
- UpdateBuffer(((index + 1) % BlockCount) * _sampleSize, _sampleSize, BufferLock.None, _updater); // update next block in circular buffer
- index = WaitHandle.WaitAny(eventHandles);
- }
-
- Uninitialize();
- }
-
- private const int BlockCount = 2;
-
- private int _sampleRate;
- private int _sampleChannels;
- private int _sampleBits;
- private int _sampleSize;
-
- private Thread _thread;
- private IntPtr _window;
- private IDirectSound _device;
- private IDirectSoundBuffer _buffer;
- private readonly object _bufferLock = new object();
- private Action _updater;
-
- private AutoResetEvent _position1Event = new AutoResetEvent(false);
- private AutoResetEvent _position2Event = new AutoResetEvent(false);
- private ManualResetEvent _stopEvent = new ManualResetEvent(false);
- }
-}
+using System;
+using System.Runtime.InteropServices;
+using System.Security;
+using System.Threading;
+
+namespace Jellyfish.Library
+{
+ public sealed partial class DirectSound : IDisposable
+ {
+ [SecurityCritical]
+ public DirectSound(int sampleRate, int sampleChannels, int sampleBits, int sampleSize, Action updater)
+ {
+ _sampleRate = sampleRate;
+ _sampleChannels = sampleChannels;
+ _sampleBits = sampleBits;
+ _sampleSize = sampleSize;
+
+ _thread = new Thread(Run) { Name = "DirectSound" };
+ _updater = updater;
+ }
+
+ public void Dispose()
+ {
+ _position1Event.Close();
+ _position2Event.Close();
+ _stopEvent.Close();
+ }
+
+ public void SetVolume(float volume)
+ {
+ int attenuation = (volume < 0.01) ? (int)BufferVolume.Min : (int)Math.Floor(100 * 20 * Math.Log10(volume)); // 100 db
+ lock (_bufferLock)
+ {
+ if (_buffer != null)
+ {
+ _buffer.SetVolume(attenuation);
+ }
+ }
+ }
+
+ public void Start(IntPtr window)
+ {
+ _window = window;
+ _thread.Start();
+ }
+
+ public void Stop()
+ {
+ _stopEvent.Set();
+ _thread.Join();
+ }
+
+ [SecurityCritical]
+ private void Initialize()
+ {
+ int hresult = NativeMethods.DirectSoundCreate(IntPtr.Zero, out _device, IntPtr.Zero);
+ if (hresult < 0)
+ {
+ Marshal.ThrowExceptionForHR(hresult);
+ }
+
+ _device.SetCooperativeLevel(_window, CooperativeLevel.Normal);
+
+ GCHandleHelpers.Pin(new WaveFormat(_sampleRate, _sampleChannels, _sampleBits), waveFormat =>
+ {
+ var description = new BufferDescription(BufferCapabilities.CtrlPositionNotify | BufferCapabilities.CtrlVolume, BlockCount * _sampleSize, waveFormat);
+ _device.CreateSoundBuffer(description, out _buffer, IntPtr.Zero);
+ });
+ ClearBuffer();
+
+ var positionEvents = new BufferPositionNotify[BlockCount]
+ {
+ new BufferPositionNotify(0 * _sampleSize, _position1Event), new BufferPositionNotify(1 * _sampleSize, _position2Event)
+ };
+ ((IDirectSoundNotify)_buffer).SetNotificationPositions(positionEvents.Length, positionEvents);
+
+ _buffer.Play(0, 0, BufferPlay.Looping);
+ }
+
+ [SecurityCritical]
+ private void ClearBuffer()
+ {
+ UpdateBuffer(0, 0, BufferLock.EntireBuffer, (buffer, bufferSize) => MarshalHelpers.ZeroMemory(buffer, bufferSize));
+ }
+
+ private void RestoreBuffer()
+ {
+ BufferStatus status;
+ _buffer.GetStatus(out status);
+ if ((status & BufferStatus.BufferLost) != 0)
+ {
+ _buffer.Restore();
+ }
+ }
+
+ private void UpdateBuffer(int offset, int count, BufferLock flags, Action updater)
+ {
+ RestoreBuffer();
+
+ IntPtr buffer1, buffer2;
+ int buffer1Size, buffer2Size;
+ _buffer.Lock(offset, count, out buffer1, out buffer1Size, out buffer2, out buffer2Size, flags);
+ try
+ {
+ if (buffer1 != IntPtr.Zero)
+ {
+ updater(buffer1, buffer1Size);
+ }
+ if (buffer2 != IntPtr.Zero)
+ {
+ updater(buffer2, buffer2Size);
+ }
+ }
+ finally
+ {
+ _buffer.Unlock(buffer1, buffer1Size, buffer2, buffer2Size);
+ }
+ }
+
+ private void Uninitialize()
+ {
+ lock (_bufferLock)
+ {
+ if (_buffer != null)
+ {
+ _buffer.Stop();
+ Marshal.ReleaseComObject(_buffer);
+ _buffer = null;
+ }
+ }
+ if (_device != null)
+ {
+ Marshal.ReleaseComObject(_device);
+ _device = null;
+ }
+ }
+
+ [SecurityCritical]
+ private void Run() // com mta thread
+ {
+ Initialize();
+
+ var eventHandles = new EventWaitHandle[] { _position1Event, _position2Event, _stopEvent };
+ int index = WaitHandle.WaitAny(eventHandles);
+
+ while (index < BlockCount)
+ {
+ UpdateBuffer(((index + 1) % BlockCount) * _sampleSize, _sampleSize, BufferLock.None, _updater); // update next block in circular buffer
+ index = WaitHandle.WaitAny(eventHandles);
+ }
+
+ Uninitialize();
+ }
+
+ private const int BlockCount = 2;
+
+ private int _sampleRate;
+ private int _sampleChannels;
+ private int _sampleBits;
+ private int _sampleSize;
+
+ private Thread _thread;
+ private IntPtr _window;
+ private IDirectSound _device;
+ private IDirectSoundBuffer _buffer;
+ private readonly object _bufferLock = new object();
+ private Action _updater;
+
+ private AutoResetEvent _position1Event = new AutoResetEvent(false);
+ private AutoResetEvent _position2Event = new AutoResetEvent(false);
+ private ManualResetEvent _stopEvent = new ManualResetEvent(false);
+ }
+}
diff --git a/Library/DirectSoundInterop.cs b/Library/DirectSoundInterop.cs
index 455a4fb..275b5e4 100644
--- a/Library/DirectSoundInterop.cs
+++ b/Library/DirectSoundInterop.cs
@@ -1,110 +1,110 @@
-using System;
-using System.Diagnostics.CodeAnalysis;
-using System.Runtime.InteropServices;
-using System.Security;
-using System.Threading;
-
-namespace Jellyfish.Library
-{
- public sealed partial class DirectSound
- {
- [Flags]
- private enum BufferCapabilities { PrimaryBuffer = 0x00000001, CtrlVolume = 0x00000080, CtrlPositionNotify = 0x00000100, StickyFocus = 0x00004000, GlobalFocus = 0x00008000 }
-
- [Flags]
- private enum BufferLock { None = 0x00000000, FromWriteCursor = 0x00000001, EntireBuffer = 0x00000002 }
-
- [Flags]
- private enum BufferPlay { Looping = 0x00000001 }
-
- [Flags]
- private enum BufferStatus { Playing = 0x00000001, BufferLost = 0x00000002, Looping = 0x00000004, Terminated = 0x00000020 }
-
- private enum BufferVolume { Min = -10000, Max = 0 }
-
- private enum CooperativeLevel { Normal = 1, Priority = 2 }
-
- [StructLayout(LayoutKind.Sequential)]
- private sealed class BufferDescription
- {
- public BufferDescription(BufferCapabilities capabilities, int size, IntPtr format)
- {
- dwSize = Marshal.SizeOf(typeof(BufferDescription));
- dwFlags = capabilities;
- dwBufferBytes = size;
- lpwfxFormat = format;
- }
-
- public int dwSize;
- public BufferCapabilities dwFlags;
- public int dwBufferBytes;
- public int dwReserved;
- public IntPtr lpwfxFormat;
- public Guid guid3DAlgorithm;
- }
-
- [StructLayout(LayoutKind.Sequential)]
- private struct BufferPositionNotify
- {
- [SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.Runtime.InteropServices.SafeHandle.DangerousGetHandle")]
- public BufferPositionNotify(int offset, EventWaitHandle notifyEvent)
- {
- dwOffset = offset;
- hEventNotify = notifyEvent.SafeWaitHandle.DangerousGetHandle();
- }
-
- public int dwOffset;
- public IntPtr hEventNotify;
- }
-
- [ComImport, Guid("279AFA83-4981-11CE-A521-0020AF0BE560"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
- private interface IDirectSound
- {
- void CreateSoundBuffer(BufferDescription pcDSBufferDesc, [MarshalAs(UnmanagedType.Interface)] out IDirectSoundBuffer pDSBuffer, IntPtr pUnkOuter);
- void GetCaps(IntPtr pDSCaps);
- void DuplicateSoundBuffer([MarshalAs(UnmanagedType.Interface)] IDirectSoundBuffer pDSBufferOriginal, [MarshalAs(UnmanagedType.Interface)] out IDirectSoundBuffer pDSBufferDuplicate);
- void SetCooperativeLevel(IntPtr hwnd, CooperativeLevel dwLevel);
- void Compact();
- void GetSpeakerConfig(out int dwSpeakerConfig);
- void SetSpeakerConfig(int dwSpeakerConfig);
- void Initialize([MarshalAs(UnmanagedType.LPStruct)] Guid pcGuidDevice);
- }
-
- [ComImport, Guid("279AFA85-4981-11CE-A521-0020AF0BE560"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
- private interface IDirectSoundBuffer
- {
- void GetCaps(IntPtr pDSBufferCaps);
- void GetCurrentPosition(out int dwCurrentPlayCursor, out int dwCurrentWriteCursor);
- void GetFormat(IntPtr pwfxFormat, int dwSizeAllocated, out int dwSizeWritten);
- void GetVolume(out int lVolume);
- void GetPan(out int lPan);
- void GetFrequency(out int dwFrequency);
- void GetStatus(out BufferStatus dwStatus);
- void Initialize([MarshalAs(UnmanagedType.Interface)] IDirectSound pDirectSound, BufferDescription pcDSBufferDesc);
- void Lock(int dwOffset, int dwBytes, out IntPtr pvAudioPtr1, out int dwAudioBytes1, out IntPtr pvAudioPtr2, out int dwAudioBytes2, BufferLock dwFlags);
- void Play(int dwReserved1, int dwPriority, BufferPlay dwFlags);
- void SetCurrentPosition(int dwNewPosition);
- void SetFormat(WaveFormat pcfxFormat);
- void SetVolume(int lVolume);
- void SetPan(int lPan);
- void SetFrequency(int dwFrequency);
- void Stop();
- void Unlock(IntPtr pvAudioPtr1, int dwAudioBytes1, IntPtr pvAudioPtr2, int dwAudioBytes2);
- void Restore();
- }
-
- [ComImport, Guid("B0210783-89CD-11D0-AF08-00A0C925CD16"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
- private interface IDirectSoundNotify
- {
- void SetNotificationPositions(int dwPositionNotifies, [MarshalAs(UnmanagedType.LPArray)] BufferPositionNotify[] pcPositionNotifies);
- }
-
- [SecurityCritical]
- [SuppressUnmanagedCodeSecurity]
- private static class NativeMethods
- {
- [DllImport("dsound.dll")]
- public static extern int DirectSoundCreate(IntPtr pcGuidDevice, [MarshalAs(UnmanagedType.Interface)] out IDirectSound pDS, IntPtr pUnkOuter);
- }
- }
-}
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.Runtime.InteropServices;
+using System.Security;
+using System.Threading;
+
+namespace Jellyfish.Library
+{
+ public sealed partial class DirectSound
+ {
+ [Flags]
+ private enum BufferCapabilities { PrimaryBuffer = 0x00000001, CtrlVolume = 0x00000080, CtrlPositionNotify = 0x00000100, StickyFocus = 0x00004000, GlobalFocus = 0x00008000 }
+
+ [Flags]
+ private enum BufferLock { None = 0x00000000, FromWriteCursor = 0x00000001, EntireBuffer = 0x00000002 }
+
+ [Flags]
+ private enum BufferPlay { Looping = 0x00000001 }
+
+ [Flags]
+ private enum BufferStatus { Playing = 0x00000001, BufferLost = 0x00000002, Looping = 0x00000004, Terminated = 0x00000020 }
+
+ private enum BufferVolume { Min = -10000, Max = 0 }
+
+ private enum CooperativeLevel { Normal = 1, Priority = 2 }
+
+ [StructLayout(LayoutKind.Sequential)]
+ private sealed class BufferDescription
+ {
+ public BufferDescription(BufferCapabilities capabilities, int size, IntPtr format)
+ {
+ dwSize = Marshal.SizeOf(typeof(BufferDescription));
+ dwFlags = capabilities;
+ dwBufferBytes = size;
+ lpwfxFormat = format;
+ }
+
+ public int dwSize;
+ public BufferCapabilities dwFlags;
+ public int dwBufferBytes;
+ public int dwReserved;
+ public IntPtr lpwfxFormat;
+ public Guid guid3DAlgorithm;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ private struct BufferPositionNotify
+ {
+ [SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.Runtime.InteropServices.SafeHandle.DangerousGetHandle")]
+ public BufferPositionNotify(int offset, EventWaitHandle notifyEvent)
+ {
+ dwOffset = offset;
+ hEventNotify = notifyEvent.SafeWaitHandle.DangerousGetHandle();
+ }
+
+ public int dwOffset;
+ public IntPtr hEventNotify;
+ }
+
+ [ComImport, Guid("279AFA83-4981-11CE-A521-0020AF0BE560"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+ private interface IDirectSound
+ {
+ void CreateSoundBuffer(BufferDescription pcDSBufferDesc, [MarshalAs(UnmanagedType.Interface)] out IDirectSoundBuffer pDSBuffer, IntPtr pUnkOuter);
+ void GetCaps(IntPtr pDSCaps);
+ void DuplicateSoundBuffer([MarshalAs(UnmanagedType.Interface)] IDirectSoundBuffer pDSBufferOriginal, [MarshalAs(UnmanagedType.Interface)] out IDirectSoundBuffer pDSBufferDuplicate);
+ void SetCooperativeLevel(IntPtr hwnd, CooperativeLevel dwLevel);
+ void Compact();
+ void GetSpeakerConfig(out int dwSpeakerConfig);
+ void SetSpeakerConfig(int dwSpeakerConfig);
+ void Initialize([MarshalAs(UnmanagedType.LPStruct)] Guid pcGuidDevice);
+ }
+
+ [ComImport, Guid("279AFA85-4981-11CE-A521-0020AF0BE560"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+ private interface IDirectSoundBuffer
+ {
+ void GetCaps(IntPtr pDSBufferCaps);
+ void GetCurrentPosition(out int dwCurrentPlayCursor, out int dwCurrentWriteCursor);
+ void GetFormat(IntPtr pwfxFormat, int dwSizeAllocated, out int dwSizeWritten);
+ void GetVolume(out int lVolume);
+ void GetPan(out int lPan);
+ void GetFrequency(out int dwFrequency);
+ void GetStatus(out BufferStatus dwStatus);
+ void Initialize([MarshalAs(UnmanagedType.Interface)] IDirectSound pDirectSound, BufferDescription pcDSBufferDesc);
+ void Lock(int dwOffset, int dwBytes, out IntPtr pvAudioPtr1, out int dwAudioBytes1, out IntPtr pvAudioPtr2, out int dwAudioBytes2, BufferLock dwFlags);
+ void Play(int dwReserved1, int dwPriority, BufferPlay dwFlags);
+ void SetCurrentPosition(int dwNewPosition);
+ void SetFormat(WaveFormat pcfxFormat);
+ void SetVolume(int lVolume);
+ void SetPan(int lPan);
+ void SetFrequency(int dwFrequency);
+ void Stop();
+ void Unlock(IntPtr pvAudioPtr1, int dwAudioBytes1, IntPtr pvAudioPtr2, int dwAudioBytes2);
+ void Restore();
+ }
+
+ [ComImport, Guid("B0210783-89CD-11D0-AF08-00A0C925CD16"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+ private interface IDirectSoundNotify
+ {
+ void SetNotificationPositions(int dwPositionNotifies, [MarshalAs(UnmanagedType.LPArray)] BufferPositionNotify[] pcPositionNotifies);
+ }
+
+ [SecurityCritical]
+ [SuppressUnmanagedCodeSecurity]
+ private static class NativeMethods
+ {
+ [DllImport("dsound.dll")]
+ public static extern int DirectSoundCreate(IntPtr pcGuidDevice, [MarshalAs(UnmanagedType.Interface)] out IDirectSound pDS, IntPtr pUnkOuter);
+ }
+ }
+}
diff --git a/Library/DispatcherExtensions.cs b/Library/DispatcherExtensions.cs
index 0c3fdc0..af497b8 100644
--- a/Library/DispatcherExtensions.cs
+++ b/Library/DispatcherExtensions.cs
@@ -1,36 +1,36 @@
-using System;
-using System.Windows.Threading;
-
-namespace Jellyfish.Library
-{
- public static class DispatcherExtensions
- {
- public static void Post(this Dispatcher dispatcher, Action action)
- {
- if (dispatcher == null)
- {
- throw new ArgumentNullException("dispatcher");
- }
- if (action == null)
- {
- throw new ArgumentNullException("action");
- }
-
- new DispatcherSynchronizationContext(dispatcher).Post(state => action(), null);
- }
-
- public static void Send(this Dispatcher dispatcher, Action action)
- {
- if (dispatcher == null)
- {
- throw new ArgumentNullException("dispatcher");
- }
- if (action == null)
- {
- throw new ArgumentNullException("action");
- }
-
- new DispatcherSynchronizationContext(dispatcher).Send(state => action(), null);
- }
- }
-}
+using System;
+using System.Windows.Threading;
+
+namespace Jellyfish.Library
+{
+ public static class DispatcherExtensions
+ {
+ public static void Post(this Dispatcher dispatcher, Action action)
+ {
+ if (dispatcher == null)
+ {
+ throw new ArgumentNullException("dispatcher");
+ }
+ if (action == null)
+ {
+ throw new ArgumentNullException("action");
+ }
+
+ new DispatcherSynchronizationContext(dispatcher).Post(state => action(), null);
+ }
+
+ public static void Send(this Dispatcher dispatcher, Action action)
+ {
+ if (dispatcher == null)
+ {
+ throw new ArgumentNullException("dispatcher");
+ }
+ if (action == null)
+ {
+ throw new ArgumentNullException("action");
+ }
+
+ new DispatcherSynchronizationContext(dispatcher).Send(state => action(), null);
+ }
+ }
+}
diff --git a/Library/DisposableBase.cs b/Library/DisposableBase.cs
index 5b9309e..59cee1d 100644
--- a/Library/DisposableBase.cs
+++ b/Library/DisposableBase.cs
@@ -1,26 +1,26 @@
-using System;
-
-namespace Jellyfish.Library
-{
- public abstract class DisposableBase : IDisposable
- {
- protected DisposableBase()
- {
- }
-
- ~DisposableBase()
- {
- Dispose(false);
- }
-
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- protected virtual void Dispose(bool disposing)
- {
- }
- }
-}
+using System;
+
+namespace Jellyfish.Library
+{
+ public abstract class DisposableBase : IDisposable
+ {
+ protected DisposableBase()
+ {
+ }
+
+ ~DisposableBase()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ }
+ }
+}
diff --git a/Library/FrameRateCounter.xaml b/Library/FrameRateCounter.xaml
index 3064c94..86d9bc9 100644
--- a/Library/FrameRateCounter.xaml
+++ b/Library/FrameRateCounter.xaml
@@ -1,9 +1,9 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/Library/FrameRateCounter.xaml.cs b/Library/FrameRateCounter.xaml.cs
index 3a91b3d..1ccf20d 100644
--- a/Library/FrameRateCounter.xaml.cs
+++ b/Library/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/GCHandleHelpers.cs b/Library/GCHandleHelpers.cs
index 75f02e0..abd9c5c 100644
--- a/Library/GCHandleHelpers.cs
+++ b/Library/GCHandleHelpers.cs
@@ -1,32 +1,32 @@
-using System;
-using System.Runtime.InteropServices;
-using System.Security;
-
-namespace Jellyfish.Library
-{
- public static class GCHandleHelpers
- {
- [SecurityCritical]
- public static void Pin(object value, Action action)
- {
- if (action == null)
- {
- throw new ArgumentNullException("action");
- }
-
- var gcHandle = new GCHandle();
- try
- {
- gcHandle = GCHandle.Alloc(value, GCHandleType.Pinned);
- action(gcHandle.AddrOfPinnedObject());
- }
- finally
- {
- if (gcHandle.IsAllocated)
- {
- gcHandle.Free();
- }
- }
- }
- }
-}
+using System;
+using System.Runtime.InteropServices;
+using System.Security;
+
+namespace Jellyfish.Library
+{
+ public static class GCHandleHelpers
+ {
+ [SecurityCritical]
+ public static void Pin(object value, Action action)
+ {
+ if (action == null)
+ {
+ throw new ArgumentNullException("action");
+ }
+
+ var gcHandle = new GCHandle();
+ try
+ {
+ gcHandle = GCHandle.Alloc(value, GCHandleType.Pinned);
+ action(gcHandle.AddrOfPinnedObject());
+ }
+ finally
+ {
+ if (gcHandle.IsAllocated)
+ {
+ gcHandle.Free();
+ }
+ }
+ }
+ }
+}
diff --git a/Library/GlobalSuppressions.cs b/Library/GlobalSuppressions.cs
index 22ad926..ba618f6 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/Jellyfish.Library.sln b/Library/Jellyfish.Library.sln
index 29538dd..acbf445 100644
--- a/Library/Jellyfish.Library.sln
+++ b/Library/Jellyfish.Library.sln
@@ -1,26 +1,26 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2012
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Library.Silverlight", "Silverlight\Jellyfish.Library.Silverlight.csproj", "{99CA7796-B72A-4F8C-BCDB-0D688220A331}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Library.Wpf", "Wpf\Jellyfish.Library.Wpf.csproj", "{93900841-7250-4D3A-837E-43EE3FD118DC}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {93900841-7250-4D3A-837E-43EE3FD118DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {93900841-7250-4D3A-837E-43EE3FD118DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {93900841-7250-4D3A-837E-43EE3FD118DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {93900841-7250-4D3A-837E-43EE3FD118DC}.Release|Any CPU.Build.0 = Release|Any CPU
- {99CA7796-B72A-4F8C-BCDB-0D688220A331}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {99CA7796-B72A-4F8C-BCDB-0D688220A331}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {99CA7796-B72A-4F8C-BCDB-0D688220A331}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {99CA7796-B72A-4F8C-BCDB-0D688220A331}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Library.Silverlight", "Silverlight\Jellyfish.Library.Silverlight.csproj", "{99CA7796-B72A-4F8C-BCDB-0D688220A331}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Library.Wpf", "Wpf\Jellyfish.Library.Wpf.csproj", "{93900841-7250-4D3A-837E-43EE3FD118DC}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {93900841-7250-4D3A-837E-43EE3FD118DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {93900841-7250-4D3A-837E-43EE3FD118DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {93900841-7250-4D3A-837E-43EE3FD118DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {93900841-7250-4D3A-837E-43EE3FD118DC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {99CA7796-B72A-4F8C-BCDB-0D688220A331}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {99CA7796-B72A-4F8C-BCDB-0D688220A331}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {99CA7796-B72A-4F8C-BCDB-0D688220A331}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {99CA7796-B72A-4F8C-BCDB-0D688220A331}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Library/MarshalHelpers.cs b/Library/MarshalHelpers.cs
index eba5394..2e4beed 100644
--- a/Library/MarshalHelpers.cs
+++ b/Library/MarshalHelpers.cs
@@ -1,35 +1,35 @@
-using System;
-using System.Diagnostics.CodeAnalysis;
-using System.Runtime.InteropServices;
-using System.Security;
-
-namespace Jellyfish.Library
-{
- public static class MarshalHelpers
- {
- [SecurityCritical]
- public static void FillMemory(IntPtr buffer, int bufferSize, byte value)
- {
- NativeMethods.FillMemory(buffer, (IntPtr)bufferSize, value);
- }
-
- [SecurityCritical]
- public static void ZeroMemory(IntPtr buffer, int bufferSize)
- {
- NativeMethods.ZeroMemory(buffer, (IntPtr)bufferSize);
- }
-
- [SecurityCritical]
- [SuppressUnmanagedCodeSecurity]
- private static class NativeMethods
- {
- [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage")]
- [DllImport("kernel32.dll", SetLastError = true)]
- public static extern void FillMemory(IntPtr destination, IntPtr length, byte fill);
-
- [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage")]
- [DllImport("kernel32.dll", SetLastError = true)]
- public static extern void ZeroMemory(IntPtr destination, IntPtr length);
- }
- }
-}
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.Runtime.InteropServices;
+using System.Security;
+
+namespace Jellyfish.Library
+{
+ public static class MarshalHelpers
+ {
+ [SecurityCritical]
+ public static void FillMemory(IntPtr buffer, int bufferSize, byte value)
+ {
+ NativeMethods.FillMemory(buffer, (IntPtr)bufferSize, value);
+ }
+
+ [SecurityCritical]
+ public static void ZeroMemory(IntPtr buffer, int bufferSize)
+ {
+ NativeMethods.ZeroMemory(buffer, (IntPtr)bufferSize);
+ }
+
+ [SecurityCritical]
+ [SuppressUnmanagedCodeSecurity]
+ private static class NativeMethods
+ {
+ [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage")]
+ [DllImport("kernel32.dll", SetLastError = true)]
+ public static extern void FillMemory(IntPtr destination, IntPtr length, byte fill);
+
+ [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage")]
+ [DllImport("kernel32.dll", SetLastError = true)]
+ public static extern void ZeroMemory(IntPtr destination, IntPtr length);
+ }
+ }
+}
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/Silverlight/ApplicationBase.cs b/Library/Silverlight/ApplicationBase.cs
index d1c085c..4dc648a 100644
--- a/Library/Silverlight/ApplicationBase.cs
+++ b/Library/Silverlight/ApplicationBase.cs
@@ -1,95 +1,95 @@
-using System;
-using System.Diagnostics;
-using System.Text;
-using System.Windows;
-
-namespace Jellyfish.Library
-{
- public abstract class ApplicationBase : Application
- {
- protected ApplicationBase() :
- this(null)
- {
- }
-
- protected ApplicationBase(string name)
- {
- Name = name;
-
- UnhandledException += OnApplicationUnhandledException;
- //AppDomain.CurrentDomain.UnhandledException += OnAppDomainUnhandledException;
-
- if (Debugger.IsAttached)
- {
- var settings = Application.Current.Host.Settings;
- settings.EnableFrameRateCounter = true;
- //settings.EnableRedrawRegions = true;
- //settings.EnableCacheVisualization = true;
- }
- }
-
- protected void InitializeOutOfBrowserUpdate()
- {
- if (IsRunningOutOfBrowser)
- {
- CheckAndDownloadUpdateCompleted += OnApplicationCheckAndDownloadUpdateCompleted;
- CheckAndDownloadUpdateAsync();
- }
- }
-
- private string GetExceptionCaption(string title, bool isTerminating = false)
- {
- var caption = new StringBuilder();
- if (!string.IsNullOrEmpty(Name))
- {
- caption.Append(Name).Append(' ');
- }
- caption.Append(title);
- if (isTerminating)
- {
- caption.Append(" (Terminating)");
- }
-
- return caption.ToString();
- }
-
- private void OnApplicationCheckAndDownloadUpdateCompleted(object sender, CheckAndDownloadUpdateCompletedEventArgs e)
- {
- if (e.Error != null)
- {
- if (e.Error is PlatformNotSupportedException)
- {
- MessageBox.Show("An application update is available, but it requires the latest version of Silverlight.");
- }
- //else if (Debugger.IsAttached)
- //{
- // Debugger.Break();
- //}
- }
- else if (e.UpdateAvailable)
- {
- MessageBox.Show("An application update was downloaded. Restart the application to run the latest version.");
- }
- }
-
- private void OnApplicationUnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
- {
- MessageBox.Show(e.ExceptionObject.ToString(), GetExceptionCaption("Application Exception"), MessageBoxButton.OK);
- if (Debugger.IsAttached)
- {
- Debugger.Break();
- }
- }
-
- //private void OnAppDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
- //{
- // MessageBox.Show(e.ExceptionObject.ToString(), GetExceptionCaption("AppDomain Exception", e.IsTerminating), MessageBoxButton.OK);
- // if (Debugger.IsAttached)
- // {
- // Debugger.Break();
- // }
- //}
-
- public string Name { get; private set; }
- }
-}
+using System;
+using System.Diagnostics;
+using System.Text;
+using System.Windows;
+
+namespace Jellyfish.Library
+{
+ public abstract class ApplicationBase : Application
+ {
+ protected ApplicationBase() :
+ this(null)
+ {
+ }
+
+ protected ApplicationBase(string name)
+ {
+ Name = name;
+
+ UnhandledException += OnApplicationUnhandledException;
+ //AppDomain.CurrentDomain.UnhandledException += OnAppDomainUnhandledException;
+
+ if (Debugger.IsAttached)
+ {
+ var settings = Application.Current.Host.Settings;
+ settings.EnableFrameRateCounter = true;
+ //settings.EnableRedrawRegions = true;
+ //settings.EnableCacheVisualization = true;
+ }
+ }
+
+ protected void InitializeOutOfBrowserUpdate()
+ {
+ if (IsRunningOutOfBrowser)
+ {
+ CheckAndDownloadUpdateCompleted += OnApplicationCheckAndDownloadUpdateCompleted;
+ CheckAndDownloadUpdateAsync();
+ }
+ }
+
+ private string GetExceptionCaption(string title, bool isTerminating = false)
+ {
+ var caption = new StringBuilder();
+ if (!string.IsNullOrEmpty(Name))
+ {
+ caption.Append(Name).Append(' ');
+ }
+ caption.Append(title);
+ if (isTerminating)
+ {
+ caption.Append(" (Terminating)");
+ }
+
+ return caption.ToString();
+ }
+
+ private void OnApplicationCheckAndDownloadUpdateCompleted(object sender, CheckAndDownloadUpdateCompletedEventArgs e)
+ {
+ if (e.Error != null)
+ {
+ if (e.Error is PlatformNotSupportedException)
+ {
+ MessageBox.Show("An application update is available, but it requires the latest version of Silverlight.");
+ }
+ //else if (Debugger.IsAttached)
+ //{
+ // Debugger.Break();
+ //}
+ }
+ else if (e.UpdateAvailable)
+ {
+ MessageBox.Show("An application update was downloaded. Restart the application to run the latest version.");
+ }
+ }
+
+ private void OnApplicationUnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
+ {
+ MessageBox.Show(e.ExceptionObject.ToString(), GetExceptionCaption("Application Exception"), MessageBoxButton.OK);
+ if (Debugger.IsAttached)
+ {
+ Debugger.Break();
+ }
+ }
+
+ //private void OnAppDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
+ //{
+ // MessageBox.Show(e.ExceptionObject.ToString(), GetExceptionCaption("AppDomain Exception", e.IsTerminating), MessageBoxButton.OK);
+ // if (Debugger.IsAttached)
+ // {
+ // Debugger.Break();
+ // }
+ //}
+
+ public string Name { get; private set; }
+ }
+}
diff --git a/Library/Silverlight/Jellyfish.Library.Silverlight.csproj b/Library/Silverlight/Jellyfish.Library.Silverlight.csproj
index 87eaadb..3412905 100644
--- a/Library/Silverlight/Jellyfish.Library.Silverlight.csproj
+++ b/Library/Silverlight/Jellyfish.Library.Silverlight.csproj
@@ -1,133 +1,133 @@
-
-
-
- Debug
- AnyCPU
- 8.0.50727
- 2.0
- {99CA7796-B72A-4F8C-BCDB-0D688220A331}
- {A1591282-1198-4647-A2B1-27E5FF5F6F3B};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}
- Library
- Properties
- Jellyfish.Library
- Jellyfish.Library
- Silverlight
- v5.0
-
- $(TargetFrameworkVersion)
- false
- true
- true
-
-
-
- v3.5
-
-
- true
- full
- false
- bin\
- DEBUG;TRACE;SILVERLIGHT;CODE_ANALYSIS
- true
- true
- prompt
- 4
- true
- AllRules.ruleset
- false
-
-
- pdbonly
- true
- bin\
- TRACE;SILVERLIGHT;CODE_ANALYSIS
- true
- true
- prompt
- 4
- true
- AllRules.ruleset
- false
-
-
- false
-
-
- ..\..\..\Jellyfish\StrongName.snk
-
-
-
-
-
-
-
-
-
-
-
-
- AssemblyMetadataAttribute.cs
-
-
- DispatcherExtensions.cs
-
-
- DisposableBase.cs
-
-
- FrameRateCounter.xaml.cs
- FrameRateCounter.xaml
-
-
- GlobalSuppressions.cs
-
-
- IEnumerableExtensions.cs
-
-
- MathHelpers.cs
-
-
- StreamExtensions.cs
-
-
- StringBuilderExtensions.cs
-
-
- WaveFormat.cs
-
-
-
-
-
-
-
- FrameRateCounter.xaml
- MSBuild:Compile
- Designer
-
-
-
-
- CustomDictionary.xml
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Debug
+ AnyCPU
+ 8.0.50727
+ 2.0
+ {99CA7796-B72A-4F8C-BCDB-0D688220A331}
+ {A1591282-1198-4647-A2B1-27E5FF5F6F3B};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}
+ Library
+ Properties
+ Jellyfish.Library
+ Jellyfish.Library
+ Silverlight
+ v5.0
+
+ $(TargetFrameworkVersion)
+ false
+ true
+ true
+
+
+
+ v3.5
+
+
+ true
+ full
+ false
+ bin\
+ DEBUG;TRACE;SILVERLIGHT;CODE_ANALYSIS
+ true
+ true
+ prompt
+ 4
+ true
+ AllRules.ruleset
+ false
+
+
+ pdbonly
+ true
+ bin\
+ TRACE;SILVERLIGHT;CODE_ANALYSIS
+ true
+ true
+ prompt
+ 4
+ true
+ AllRules.ruleset
+ false
+
+
+ false
+
+
+ ..\..\..\Jellyfish\StrongName.snk
+
+
+
+
+
+
+
+
+
+
+
+
+ AssemblyMetadataAttribute.cs
+
+
+ DispatcherExtensions.cs
+
+
+ DisposableBase.cs
+
+
+ FrameRateCounter.xaml.cs
+ FrameRateCounter.xaml
+
+
+ GlobalSuppressions.cs
+
+
+ IEnumerableExtensions.cs
+
+
+ MathHelpers.cs
+
+
+ StreamExtensions.cs
+
+
+ StringBuilderExtensions.cs
+
+
+ WaveFormat.cs
+
+
+
+
+
+
+
+ FrameRateCounter.xaml
+ MSBuild:Compile
+ Designer
+
+
+
+
+ CustomDictionary.xml
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Library/Silverlight/Jellyfish.Library.Silverlight.sln b/Library/Silverlight/Jellyfish.Library.Silverlight.sln
index 4c4bae8..9bfc558 100644
--- a/Library/Silverlight/Jellyfish.Library.Silverlight.sln
+++ b/Library/Silverlight/Jellyfish.Library.Silverlight.sln
@@ -1,20 +1,20 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2012
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Library.Silverlight", "Jellyfish.Library.Silverlight.csproj", "{99CA7796-B72A-4F8C-BCDB-0D688220A331}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {99CA7796-B72A-4F8C-BCDB-0D688220A331}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {99CA7796-B72A-4F8C-BCDB-0D688220A331}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {99CA7796-B72A-4F8C-BCDB-0D688220A331}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {99CA7796-B72A-4F8C-BCDB-0D688220A331}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Library.Silverlight", "Jellyfish.Library.Silverlight.csproj", "{99CA7796-B72A-4F8C-BCDB-0D688220A331}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {99CA7796-B72A-4F8C-BCDB-0D688220A331}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {99CA7796-B72A-4F8C-BCDB-0D688220A331}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {99CA7796-B72A-4F8C-BCDB-0D688220A331}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {99CA7796-B72A-4F8C-BCDB-0D688220A331}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Library/Silverlight/Properties/AssemblyInfo.cs b/Library/Silverlight/Properties/AssemblyInfo.cs
index 3e6b2b3..cd28e21 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-2012 Digital Jellyfish Design Ltd")]
-[assembly: AssemblyMetadata("Developer", "Sean Fausett")]
-
-[assembly: AssemblyVersion("0.4.0.0")]
-[assembly: AssemblyFileVersion("0.4.0.0")]
-[assembly: AssemblyInformationalVersion("0.4.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-2012 Digital Jellyfish Design Ltd")]
+[assembly: AssemblyMetadata("Developer", "Sean Fausett")]
+
+[assembly: AssemblyVersion("0.4.0.0")]
+[assembly: AssemblyFileVersion("0.4.0.0")]
+[assembly: AssemblyInformationalVersion("0.4.0.0")]
+
+[assembly: CLSCompliant(false)]
+[assembly: ComVisible(false)]
+[assembly: Guid("66034b9e-9f0b-47b0-aac4-cade9a748891")]
+
+[assembly: NeutralResourcesLanguage("en")]
diff --git a/Library/Silverlight/WaveMediaStreamSource.cs b/Library/Silverlight/WaveMediaStreamSource.cs
index 9aaacd6..fac27ba 100644
--- a/Library/Silverlight/WaveMediaStreamSource.cs
+++ b/Library/Silverlight/WaveMediaStreamSource.cs
@@ -1,76 +1,76 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Windows.Media;
-
-namespace Jellyfish.Library
-{
- public sealed class WaveMediaStreamSource : MediaStreamSource, IDisposable
- {
- public WaveMediaStreamSource(int sampleRate, int sampleChannels, int sampleBits, int sampleSize, int sampleLatency, Action updater)
- {
- _bufferSize = sampleSize;
- _buffer = new byte[_bufferSize];
- _bufferStream = new MemoryStream(_buffer);
- _waveFormat = new WaveFormat(sampleRate, sampleChannels, sampleBits);
- AudioBufferLength = sampleLatency; // ms; avoids audio delay
- _updater = updater;
- }
-
- public void Dispose()
- {
- _bufferStream.Dispose();
- }
-
- protected override void CloseMedia()
- {
- _audioDescription = null;
- }
-
- protected override void GetDiagnosticAsync(MediaStreamSourceDiagnosticKind diagnosticKind)
- {
- throw new NotImplementedException();
- }
-
- protected override void GetSampleAsync(MediaStreamType mediaStreamType)
- {
- _updater(_buffer, _bufferSize);
-
- var sample = new MediaStreamSample(_audioDescription, _bufferStream, 0, _bufferSize, _timestamp, _emptySampleDict);
- _timestamp += _bufferSize * 10000000L / _waveFormat.AverageBytesPerSec; // 100 ns
-
- ReportGetSampleCompleted(sample);
- }
-
- protected override void OpenMediaAsync()
- {
- _timestamp = 0;
-
- var sourceAttributes = new Dictionary() { { MediaSourceAttributesKeys.Duration, "0" }, { MediaSourceAttributesKeys.CanSeek, "false" } };
- var streamAttributes = new Dictionary() { { MediaStreamAttributeKeys.CodecPrivateData, _waveFormat.ToHexString() } };
- _audioDescription = new MediaStreamDescription(MediaStreamType.Audio, streamAttributes);
- var availableStreams = new List() { _audioDescription };
-
- ReportOpenMediaCompleted(sourceAttributes, availableStreams);
- }
-
- protected override void SeekAsync(long seekToTime)
- {
- ReportSeekCompleted(seekToTime);
- }
-
- protected override void SwitchMediaStreamAsync(MediaStreamDescription mediaStreamDescription)
- {
- throw new NotImplementedException();
- }
-
- private byte[] _buffer;
- private int _bufferSize;
- private MemoryStream _bufferStream;
- private Action _updater;
- private WaveFormat _waveFormat;
- private long _timestamp;
- private MediaStreamDescription _audioDescription;
- private Dictionary _emptySampleDict = new Dictionary();
- }
-}
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Windows.Media;
+
+namespace Jellyfish.Library
+{
+ public sealed class WaveMediaStreamSource : MediaStreamSource, IDisposable
+ {
+ public WaveMediaStreamSource(int sampleRate, int sampleChannels, int sampleBits, int sampleSize, int sampleLatency, Action updater)
+ {
+ _bufferSize = sampleSize;
+ _buffer = new byte[_bufferSize];
+ _bufferStream = new MemoryStream(_buffer);
+ _waveFormat = new WaveFormat(sampleRate, sampleChannels, sampleBits);
+ AudioBufferLength = sampleLatency; // ms; avoids audio delay
+ _updater = updater;
+ }
+
+ public void Dispose()
+ {
+ _bufferStream.Dispose();
+ }
+
+ protected override void CloseMedia()
+ {
+ _audioDescription = null;
+ }
+
+ protected override void GetDiagnosticAsync(MediaStreamSourceDiagnosticKind diagnosticKind)
+ {
+ throw new NotImplementedException();
+ }
+
+ protected override void GetSampleAsync(MediaStreamType mediaStreamType)
+ {
+ _updater(_buffer, _bufferSize);
+
+ var sample = new MediaStreamSample(_audioDescription, _bufferStream, 0, _bufferSize, _timestamp, _emptySampleDict);
+ _timestamp += _bufferSize * 10000000L / _waveFormat.AverageBytesPerSec; // 100 ns
+
+ ReportGetSampleCompleted(sample);
+ }
+
+ protected override void OpenMediaAsync()
+ {
+ _timestamp = 0;
+
+ var sourceAttributes = new Dictionary() { { MediaSourceAttributesKeys.Duration, "0" }, { MediaSourceAttributesKeys.CanSeek, "false" } };
+ var streamAttributes = new Dictionary() { { MediaStreamAttributeKeys.CodecPrivateData, _waveFormat.ToHexString() } };
+ _audioDescription = new MediaStreamDescription(MediaStreamType.Audio, streamAttributes);
+ var availableStreams = new List() { _audioDescription };
+
+ ReportOpenMediaCompleted(sourceAttributes, availableStreams);
+ }
+
+ protected override void SeekAsync(long seekToTime)
+ {
+ ReportSeekCompleted(seekToTime);
+ }
+
+ protected override void SwitchMediaStreamAsync(MediaStreamDescription mediaStreamDescription)
+ {
+ throw new NotImplementedException();
+ }
+
+ private byte[] _buffer;
+ private int _bufferSize;
+ private MemoryStream _bufferStream;
+ private Action _updater;
+ private WaveFormat _waveFormat;
+ private long _timestamp;
+ private MediaStreamDescription _audioDescription;
+ private Dictionary _emptySampleDict = new Dictionary();
+ }
+}
diff --git a/Library/StreamExtensions.cs b/Library/StreamExtensions.cs
index e55767f..67137e2 100644
--- a/Library/StreamExtensions.cs
+++ b/Library/StreamExtensions.cs
@@ -1,94 +1,94 @@
-using System;
-using System.Diagnostics.CodeAnalysis;
-using System.IO;
-
-namespace Jellyfish.Library
-{
- public static class StreamExtensions
- {
- [SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference", MessageId = "3#")]
- public static int ReadBlock(this Stream stream, byte[] buffer, int offset, ref int count)
- {
- int read = ReadBlock(stream, buffer, offset, count, count);
- count -= read;
- return read;
- }
-
- [SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed")]
- public static int ReadBlock(this Stream stream, byte[] buffer, int offset = 0, int count = int.MaxValue, int minCount = int.MaxValue)
- {
- if (stream == null)
- {
- throw new ArgumentNullException("stream");
- }
- if (buffer == null)
- {
- throw new ArgumentNullException("buffer");
- }
-
- count = Math.Min(count, buffer.Length - offset);
- minCount = Math.Min(minCount, buffer.Length - offset);
-
- int total = 0;
- int read;
- do
- {
- total += read = stream.Read(buffer, offset + total, count - total);
- }
- while ((read > 0) && (total < count));
-
- if (total < minCount)
- {
- throw new EndOfStreamException();
- }
-
- return total;
- }
-
- [SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed")]
- public static int ReadWord(this Stream stream, bool optional = false)
- {
- if (stream == null)
- {
- throw new ArgumentNullException("stream");
- }
-
- int lowByte = stream.ReadByte();
- int highByte = stream.ReadByte();
- int word = lowByte | (highByte << 8);
- if ((word < 0) && !optional)
- {
- throw new EndOfStreamException();
- }
-
- return word;
- }
-
- public static void SkipBlock(this Stream stream, int count)
- {
- if (stream == null)
- {
- throw new ArgumentNullException("stream");
- }
-
- if (stream.CanSeek)
- {
- stream.Seek(count, SeekOrigin.Current);
- }
- else
- {
- int total = 0;
- int read;
- do
- {
- total += read = stream.Read(_skipBuffer, 0, Math.Min(count - total, SkipBufferSize));
- }
- while ((read > 0) && (total < count));
- }
- }
-
- private const int SkipBufferSize = 1024;
-
- private static byte[] _skipBuffer = new byte[SkipBufferSize];
- }
-}
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.IO;
+
+namespace Jellyfish.Library
+{
+ public static class StreamExtensions
+ {
+ [SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference", MessageId = "3#")]
+ public static int ReadBlock(this Stream stream, byte[] buffer, int offset, ref int count)
+ {
+ int read = ReadBlock(stream, buffer, offset, count, count);
+ count -= read;
+ return read;
+ }
+
+ [SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed")]
+ public static int ReadBlock(this Stream stream, byte[] buffer, int offset = 0, int count = int.MaxValue, int minCount = int.MaxValue)
+ {
+ if (stream == null)
+ {
+ throw new ArgumentNullException("stream");
+ }
+ if (buffer == null)
+ {
+ throw new ArgumentNullException("buffer");
+ }
+
+ count = Math.Min(count, buffer.Length - offset);
+ minCount = Math.Min(minCount, buffer.Length - offset);
+
+ int total = 0;
+ int read;
+ do
+ {
+ total += read = stream.Read(buffer, offset + total, count - total);
+ }
+ while ((read > 0) && (total < count));
+
+ if (total < minCount)
+ {
+ throw new EndOfStreamException();
+ }
+
+ return total;
+ }
+
+ [SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed")]
+ public static int ReadWord(this Stream stream, bool optional = false)
+ {
+ if (stream == null)
+ {
+ throw new ArgumentNullException("stream");
+ }
+
+ int lowByte = stream.ReadByte();
+ int highByte = stream.ReadByte();
+ int word = lowByte | (highByte << 8);
+ if ((word < 0) && !optional)
+ {
+ throw new EndOfStreamException();
+ }
+
+ return word;
+ }
+
+ public static void SkipBlock(this Stream stream, int count)
+ {
+ if (stream == null)
+ {
+ throw new ArgumentNullException("stream");
+ }
+
+ if (stream.CanSeek)
+ {
+ stream.Seek(count, SeekOrigin.Current);
+ }
+ else
+ {
+ int total = 0;
+ int read;
+ do
+ {
+ total += read = stream.Read(_skipBuffer, 0, Math.Min(count - total, SkipBufferSize));
+ }
+ while ((read > 0) && (total < count));
+ }
+ }
+
+ private const int SkipBufferSize = 1024;
+
+ private static byte[] _skipBuffer = new byte[SkipBufferSize];
+ }
+}
diff --git a/Library/StringBuilderExtensions.cs b/Library/StringBuilderExtensions.cs
index 5935c60..744400d 100644
--- a/Library/StringBuilderExtensions.cs
+++ b/Library/StringBuilderExtensions.cs
@@ -1,54 +1,54 @@
-using System;
-using System.Globalization;
-using System.Text;
-
-namespace Jellyfish.Library
-{
- public static class StringBuilderExtensions
- {
- public static StringBuilder AppendHex(this StringBuilder builder, short value) // little endian
- {
- if (builder == null)
- {
- throw new ArgumentNullException("builder");
- }
-
- return builder.AppendFormat(CultureInfo.InvariantCulture, "{0:X2}{1:X2}", value & 0xFF, value >> 8);
- }
-
- public static StringBuilder AppendHex(this StringBuilder builder, int value) // little endian
- {
- if (builder == null)
- {
- throw new ArgumentNullException("builder");
- }
-
- 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 (builder == null)
- {
- throw new ArgumentNullException("builder");
- }
-
- 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;
+using System.Globalization;
+using System.Text;
+
+namespace Jellyfish.Library
+{
+ public static class StringBuilderExtensions
+ {
+ public static StringBuilder AppendHex(this StringBuilder builder, short value) // little endian
+ {
+ if (builder == null)
+ {
+ throw new ArgumentNullException("builder");
+ }
+
+ return builder.AppendFormat(CultureInfo.InvariantCulture, "{0:X2}{1:X2}", value & 0xFF, value >> 8);
+ }
+
+ public static StringBuilder AppendHex(this StringBuilder builder, int value) // little endian
+ {
+ if (builder == null)
+ {
+ throw new ArgumentNullException("builder");
+ }
+
+ 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 (builder == null)
+ {
+ throw new ArgumentNullException("builder");
+ }
+
+ 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 132f815..8efb65f 100644
--- a/Library/WaveFormat.cs
+++ b/Library/WaveFormat.cs
@@ -1,49 +1,49 @@
-using System.Runtime.InteropServices;
-using System.Text;
-
-namespace Jellyfish.Library
-{
- [StructLayout(LayoutKind.Sequential)]
- public sealed class WaveFormat
- {
- public WaveFormat(int sampleRate, int sampleChannels, int sampleBits)
- {
- _formatTag = WaveFormatPcm;
- _samplesPerSec = sampleRate;
- _channels = (short)sampleChannels;
- _bitsPerSample = (short)sampleBits;
- _blockAlign = (short)(sampleChannels * sampleBits / 8);
- _averageBytesPerSec = sampleRate * _blockAlign;
- }
-
- public string ToHexString() // little endian
- {
- var builder = new StringBuilder();
-
- builder.AppendHex(_formatTag);
- builder.AppendHex(_channels);
- builder.AppendHex(_samplesPerSec);
- builder.AppendHex(_averageBytesPerSec);
- builder.AppendHex(_blockAlign);
- builder.AppendHex(_bitsPerSample);
- builder.AppendHex(_size);
-
- return builder.ToString();
- }
-
- public int SamplesPerSec { get { return _samplesPerSec; } } // no auto props
- public int Channels { get { return _channels; } }
- public int BitsPerSample { get { return _bitsPerSample; } }
- public int AverageBytesPerSec { get { return _averageBytesPerSec; } }
-
- private const int WaveFormatPcm = 1;
-
- private short _formatTag;
- private short _channels;
- private int _samplesPerSec;
- private int _averageBytesPerSec;
- private short _blockAlign;
- private short _bitsPerSample;
- private short _size;
- }
-}
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace Jellyfish.Library
+{
+ [StructLayout(LayoutKind.Sequential)]
+ public sealed class WaveFormat
+ {
+ public WaveFormat(int sampleRate, int sampleChannels, int sampleBits)
+ {
+ _formatTag = WaveFormatPcm;
+ _samplesPerSec = sampleRate;
+ _channels = (short)sampleChannels;
+ _bitsPerSample = (short)sampleBits;
+ _blockAlign = (short)(sampleChannels * sampleBits / 8);
+ _averageBytesPerSec = sampleRate * _blockAlign;
+ }
+
+ public string ToHexString() // little endian
+ {
+ var builder = new StringBuilder();
+
+ builder.AppendHex(_formatTag);
+ builder.AppendHex(_channels);
+ builder.AppendHex(_samplesPerSec);
+ builder.AppendHex(_averageBytesPerSec);
+ builder.AppendHex(_blockAlign);
+ builder.AppendHex(_bitsPerSample);
+ builder.AppendHex(_size);
+
+ return builder.ToString();
+ }
+
+ public int SamplesPerSec { get { return _samplesPerSec; } } // no auto props
+ public int Channels { get { return _channels; } }
+ public int BitsPerSample { get { return _bitsPerSample; } }
+ public int AverageBytesPerSec { get { return _averageBytesPerSec; } }
+
+ private const int WaveFormatPcm = 1;
+
+ private short _formatTag;
+ private short _channels;
+ private int _samplesPerSec;
+ private int _averageBytesPerSec;
+ private short _blockAlign;
+ private short _bitsPerSample;
+ private short _size;
+ }
+}
diff --git a/Library/Wpf/ApplicationBase.cs b/Library/Wpf/ApplicationBase.cs
index d1e4a8c..7bd14fc 100644
--- a/Library/Wpf/ApplicationBase.cs
+++ b/Library/Wpf/ApplicationBase.cs
@@ -1,65 +1,65 @@
-using System;
-using System.Diagnostics;
-using System.Security;
-using System.Text;
-using System.Windows;
-using System.Windows.Threading;
-
-namespace Jellyfish.Library
-{
- public abstract class ApplicationBase : Application
- {
- [SecurityCritical]
- protected ApplicationBase() :
- this(null)
- {
- }
-
- [SecurityCritical]
- protected ApplicationBase(string name)
- {
- Name = name;
-
- DispatcherUnhandledException += OnApplicationDispatcherUnhandledException;
- AppDomain.CurrentDomain.UnhandledException += OnAppDomainUnhandledException;
- }
-
- private string GetExceptionCaption(string title, bool isTerminating = false)
- {
- var caption = new StringBuilder();
- if (!string.IsNullOrEmpty(Name))
- {
- caption.Append(Name).Append(' ');
- }
- caption.Append(title);
- if (isTerminating)
- {
- caption.Append(" (Terminating)");
- }
-
- return caption.ToString();
- }
-
- private void OnApplicationDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
- {
- MessageBox.Show(e.Exception.ToString(), GetExceptionCaption("Application Dispatcher Exception", isTerminating: true));
- if (Debugger.IsAttached)
- {
- Debugger.Break();
- }
- e.Handled = true;
- Shutdown();
- }
-
- private void OnAppDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
- {
- MessageBox.Show(e.ExceptionObject.ToString(), GetExceptionCaption("AppDomain Exception", e.IsTerminating));
- if (Debugger.IsAttached)
- {
- Debugger.Break();
- }
- }
-
- public string Name { get; private set; }
- }
-}
+using System;
+using System.Diagnostics;
+using System.Security;
+using System.Text;
+using System.Windows;
+using System.Windows.Threading;
+
+namespace Jellyfish.Library
+{
+ public abstract class ApplicationBase : Application
+ {
+ [SecurityCritical]
+ protected ApplicationBase() :
+ this(null)
+ {
+ }
+
+ [SecurityCritical]
+ protected ApplicationBase(string name)
+ {
+ Name = name;
+
+ DispatcherUnhandledException += OnApplicationDispatcherUnhandledException;
+ AppDomain.CurrentDomain.UnhandledException += OnAppDomainUnhandledException;
+ }
+
+ private string GetExceptionCaption(string title, bool isTerminating = false)
+ {
+ var caption = new StringBuilder();
+ if (!string.IsNullOrEmpty(Name))
+ {
+ caption.Append(Name).Append(' ');
+ }
+ caption.Append(title);
+ if (isTerminating)
+ {
+ caption.Append(" (Terminating)");
+ }
+
+ return caption.ToString();
+ }
+
+ private void OnApplicationDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
+ {
+ MessageBox.Show(e.Exception.ToString(), GetExceptionCaption("Application Dispatcher Exception", isTerminating: true));
+ if (Debugger.IsAttached)
+ {
+ Debugger.Break();
+ }
+ e.Handled = true;
+ Shutdown();
+ }
+
+ private void OnAppDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
+ {
+ MessageBox.Show(e.ExceptionObject.ToString(), GetExceptionCaption("AppDomain Exception", e.IsTerminating));
+ if (Debugger.IsAttached)
+ {
+ Debugger.Break();
+ }
+ }
+
+ public string Name { get; private set; }
+ }
+}
diff --git a/Library/Wpf/Jellyfish.Library.Wpf.csproj b/Library/Wpf/Jellyfish.Library.Wpf.csproj
index 4351007..a804482 100644
--- a/Library/Wpf/Jellyfish.Library.Wpf.csproj
+++ b/Library/Wpf/Jellyfish.Library.Wpf.csproj
@@ -1,120 +1,120 @@
-
-
-
- Debug
- AnyCPU
- 8.0.30703
- 2.0
- {93900841-7250-4D3A-837E-43EE3FD118DC}
- Library
- Properties
- Jellyfish.Library
- Jellyfish.Library
- v4.5
- 512
-
-
- true
- full
- false
- bin\
- DEBUG;TRACE;WINDOWS;CODE_ANALYSIS
- prompt
- 4
- true
- AllRules.ruleset
- false
-
-
- pdbonly
- true
- bin\
- TRACE;WINDOWS;CODE_ANALYSIS
- prompt
- 4
- true
- AllRules.ruleset
- false
-
-
- false
-
-
- ..\..\..\Jellyfish\StrongName.snk
-
-
-
-
-
-
-
-
-
-
-
-
-
- DirectSound.cs
-
-
- DirectSoundInterop.cs
-
-
- DispatcherExtensions.cs
-
-
- DisposableBase.cs
-
-
- FrameRateCounter.xaml.cs
- FrameRateCounter.xaml
-
-
- GCHandleHelpers.cs
-
-
- GlobalSuppressions.cs
-
-
- IEnumerableExtensions.cs
-
-
- MarshalHelpers.cs
-
-
- MathHelpers.cs
-
-
- StreamExtensions.cs
-
-
- StringBuilderExtensions.cs
-
-
- WaveFormat.cs
-
-
-
-
-
-
-
- FrameRateCounter.xaml
- MSBuild:Compile
- Designer
-
-
-
-
- CustomDictionary.xml
-
-
-
-
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {93900841-7250-4D3A-837E-43EE3FD118DC}
+ Library
+ Properties
+ Jellyfish.Library
+ Jellyfish.Library
+ v4.5
+ 512
+
+
+ true
+ full
+ false
+ bin\
+ DEBUG;TRACE;WINDOWS;CODE_ANALYSIS
+ prompt
+ 4
+ true
+ AllRules.ruleset
+ false
+
+
+ pdbonly
+ true
+ bin\
+ TRACE;WINDOWS;CODE_ANALYSIS
+ prompt
+ 4
+ true
+ AllRules.ruleset
+ false
+
+
+ false
+
+
+ ..\..\..\Jellyfish\StrongName.snk
+
+
+
+
+
+
+
+
+
+
+
+
+
+ DirectSound.cs
+
+
+ DirectSoundInterop.cs
+
+
+ DispatcherExtensions.cs
+
+
+ DisposableBase.cs
+
+
+ FrameRateCounter.xaml.cs
+ FrameRateCounter.xaml
+
+
+ GCHandleHelpers.cs
+
+
+ GlobalSuppressions.cs
+
+
+ IEnumerableExtensions.cs
+
+
+ MarshalHelpers.cs
+
+
+ MathHelpers.cs
+
+
+ StreamExtensions.cs
+
+
+ StringBuilderExtensions.cs
+
+
+ WaveFormat.cs
+
+
+
+
+
+
+
+ FrameRateCounter.xaml
+ MSBuild:Compile
+ Designer
+
+
+
+
+ CustomDictionary.xml
+
+
+
+
\ No newline at end of file
diff --git a/Library/Wpf/Jellyfish.Library.Wpf.sln b/Library/Wpf/Jellyfish.Library.Wpf.sln
index 063cef4..c13b9d8 100644
--- a/Library/Wpf/Jellyfish.Library.Wpf.sln
+++ b/Library/Wpf/Jellyfish.Library.Wpf.sln
@@ -1,20 +1,20 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2012
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Library.Wpf", "Jellyfish.Library.Wpf.csproj", "{93900841-7250-4D3A-837E-43EE3FD118DC}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {93900841-7250-4D3A-837E-43EE3FD118DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {93900841-7250-4D3A-837E-43EE3FD118DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {93900841-7250-4D3A-837E-43EE3FD118DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {93900841-7250-4D3A-837E-43EE3FD118DC}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Library.Wpf", "Jellyfish.Library.Wpf.csproj", "{93900841-7250-4D3A-837E-43EE3FD118DC}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {93900841-7250-4D3A-837E-43EE3FD118DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {93900841-7250-4D3A-837E-43EE3FD118DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {93900841-7250-4D3A-837E-43EE3FD118DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {93900841-7250-4D3A-837E-43EE3FD118DC}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Library/Wpf/Properties/AssemblyInfo.cs b/Library/Wpf/Properties/AssemblyInfo.cs
index 614c061..905f607 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-2012 Digital Jellyfish Design Ltd")]
-[assembly: AssemblyMetadata("Developer", "Sean Fausett")]
-
-[assembly: AssemblyVersion("0.4.0.0")]
-[assembly: AssemblyFileVersion("0.4.0.0")]
-[assembly: AssemblyInformationalVersion("0.4.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-2012 Digital Jellyfish Design Ltd")]
+[assembly: AssemblyMetadata("Developer", "Sean Fausett")]
+
+[assembly: AssemblyVersion("0.4.0.0")]
+[assembly: AssemblyFileVersion("0.4.0.0")]
+[assembly: AssemblyInformationalVersion("0.4.0.0")]
+
+[assembly: CLSCompliant(false)]
+[assembly: ComVisible(false)]
+[assembly: Guid("66034b9e-9f0b-47b0-aac4-cade9a748891")]
+
+[assembly: NeutralResourcesLanguage("en")]
diff --git a/Library/Wpf/WindowExtensions.cs b/Library/Wpf/WindowExtensions.cs
index 14d22fe..34b0fec 100644
--- a/Library/Wpf/WindowExtensions.cs
+++ b/Library/Wpf/WindowExtensions.cs
@@ -1,14 +1,14 @@
-using System;
-using System.Windows;
-using System.Windows.Interop;
-
-namespace Jellyfish.Library
-{
- public static class WindowExtensions
- {
- public static IntPtr GetHandle(this Window window)
- {
- return new WindowInteropHelper(window).Handle;
- }
- }
-}
+using System;
+using System.Windows;
+using System.Windows.Interop;
+
+namespace Jellyfish.Library
+{
+ public static class WindowExtensions
+ {
+ public static IntPtr GetHandle(this Window window)
+ {
+ return new WindowInteropHelper(window).Handle;
+ }
+ }
+}
diff --git a/License.txt b/License.txt
index 074a544..f121fec 100644
--- a/License.txt
+++ b/License.txt
@@ -1,280 +1,280 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
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 a2b9773..973a8b3 100644
--- a/Virtu/Cpu.cs
+++ b/Virtu/Cpu.cs
@@ -1,3261 +1,3261 @@
-using System;
-using System.Diagnostics.CodeAnalysis;
-using System.Globalization;
-using System.IO;
-
-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
- };
- }
-
- public override void Initialize()
- {
- _memory = Machine.Memory;
-
- Is65C02 = true;
- IsThrottled = true;
- Multiplier = 1;
-
- RS = 0xFF;
- }
-
- public override void Reset()
- {
- RS = (RS - 3) & 0xFF; // [4-14]
- RPC = _memory.ReadRomRegionE0FF(0xFFFC) | (_memory.ReadRomRegionE0FF(0xFFFD) << 8);
- RP |= (PB | PI);
- if (Is65C02) // [C-10]
- {
- RP &= ~PD;
- }
- }
-
- public override void LoadState(BinaryReader reader, Version version)
- {
- if (reader == null)
- {
- throw new ArgumentNullException("reader");
- }
-
- Is65C02 = reader.ReadBoolean();
- IsThrottled = reader.ReadBoolean();
- Multiplier = reader.ReadInt32();
-
- RA = reader.ReadInt32();
- RX = reader.ReadInt32();
- RY = reader.ReadInt32();
- RS = reader.ReadInt32();
- RP = reader.ReadInt32();
- RPC = reader.ReadInt32();
- }
-
- public override void SaveState(BinaryWriter writer)
- {
- if (writer == null)
- {
- throw new ArgumentNullException("writer");
- }
-
- writer.Write(Is65C02);
- writer.Write(IsThrottled);
- writer.Write(Multiplier);
-
- writer.Write(RA);
- writer.Write(RX);
- writer.Write(RY);
- writer.Write(RS);
- writer.Write(RP);
- writer.Write(RPC);
- }
-
- public override string ToString()
- {
- return string.Format(CultureInfo.InvariantCulture, "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;
- }
-
- #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 (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 (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
-
- public bool Is65C02 { get { return _is65C02; } set { _is65C02 = value; _executeOpCode = _is65C02 ? ExecuteOpCode65C02 : ExecuteOpCode65N02; } }
- public bool IsThrottled { get; set; }
- public int Multiplier { get; set; }
-
- 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 bool _is65C02;
- private Action[] _executeOpCode;
- }
-}
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using System.IO;
+
+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
+ };
+ }
+
+ public override void Initialize()
+ {
+ _memory = Machine.Memory;
+
+ Is65C02 = true;
+ IsThrottled = true;
+ Multiplier = 1;
+
+ RS = 0xFF;
+ }
+
+ public override void Reset()
+ {
+ RS = (RS - 3) & 0xFF; // [4-14]
+ RPC = _memory.ReadRomRegionE0FF(0xFFFC) | (_memory.ReadRomRegionE0FF(0xFFFD) << 8);
+ RP |= (PB | PI);
+ if (Is65C02) // [C-10]
+ {
+ RP &= ~PD;
+ }
+ }
+
+ public override void LoadState(BinaryReader reader, Version version)
+ {
+ if (reader == null)
+ {
+ throw new ArgumentNullException("reader");
+ }
+
+ Is65C02 = reader.ReadBoolean();
+ IsThrottled = reader.ReadBoolean();
+ Multiplier = reader.ReadInt32();
+
+ RA = reader.ReadInt32();
+ RX = reader.ReadInt32();
+ RY = reader.ReadInt32();
+ RS = reader.ReadInt32();
+ RP = reader.ReadInt32();
+ RPC = reader.ReadInt32();
+ }
+
+ public override void SaveState(BinaryWriter writer)
+ {
+ if (writer == null)
+ {
+ throw new ArgumentNullException("writer");
+ }
+
+ writer.Write(Is65C02);
+ writer.Write(IsThrottled);
+ writer.Write(Multiplier);
+
+ writer.Write(RA);
+ writer.Write(RX);
+ writer.Write(RY);
+ writer.Write(RS);
+ writer.Write(RP);
+ writer.Write(RPC);
+ }
+
+ public override string ToString()
+ {
+ return string.Format(CultureInfo.InvariantCulture, "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;
+ }
+
+ #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 (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 (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
+
+ public bool Is65C02 { get { return _is65C02; } set { _is65C02 = value; _executeOpCode = _is65C02 ? ExecuteOpCode65C02 : ExecuteOpCode65N02; } }
+ public bool IsThrottled { get; set; }
+ public int Multiplier { get; set; }
+
+ 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 bool _is65C02;
+ private Action[] _executeOpCode;
+ }
+}
diff --git a/Virtu/CpuData.cs b/Virtu/CpuData.cs
index b0baaef..361aa55 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 c706f7a..f31a749 100644
--- a/Virtu/CustomDictionary.xml
+++ b/Virtu/CustomDictionary.xml
@@ -1,28 +1,28 @@
-
-
-
-
- Io
- RPC
-
-
-
-
- Annunciator
- Cpu
- Dsk
- Prg
- Unpause
- Virtu
- Xex
- Xna
- x
- y
-
-
- DownRight
- GamePad
- UpRight
-
-
-
+
+
+
+
+ Io
+ RPC
+
+
+
+
+ Annunciator
+ Cpu
+ Dsk
+ Prg
+ Unpause
+ Virtu
+ Xex
+ Xna
+ x
+ y
+
+
+ DownRight
+ GamePad
+ UpRight
+
+
+
diff --git a/Virtu/Disk525.cs b/Virtu/Disk525.cs
index 6f9c92c..a21e39c 100644
--- a/Virtu/Disk525.cs
+++ b/Virtu/Disk525.cs
@@ -1,97 +1,97 @@
-using System;
-using System.Diagnostics.CodeAnalysis;
-using System.IO;
-using System.Text.RegularExpressions;
-using Jellyfish.Library;
-
-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, Stream stream, bool isWriteProtected)
- {
- if (name == null)
- {
- throw new ArgumentNullException("name");
- }
-
- if (name.EndsWith(".do", StringComparison.OrdinalIgnoreCase) ||
- name.EndsWith(".dsk", StringComparison.OrdinalIgnoreCase)) // assumes dos sector skew
- {
- return new DiskDsk(name, stream, isWriteProtected, SectorSkew.Dos);
- }
- else if (name.EndsWith(".nib", StringComparison.OrdinalIgnoreCase))
- {
- return new DiskNib(name, stream, isWriteProtected);
- }
- else if (name.EndsWith(".po", StringComparison.OrdinalIgnoreCase))
- {
- return new DiskDsk(name, stream, isWriteProtected, SectorSkew.ProDos);
- }
-
- return null;
- }
-
- [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "version")]
- public static Disk525 LoadState(BinaryReader reader, Version version)
- {
- if (reader == null)
- {
- throw new ArgumentNullException("reader");
- }
-
- string name = reader.ReadString();
- var data = reader.ReadBytes(reader.ReadInt32());
- bool isWriteProtected = reader.ReadBoolean();
-
- if (name.EndsWith(".do", StringComparison.OrdinalIgnoreCase) ||
- name.EndsWith(".dsk", StringComparison.OrdinalIgnoreCase)) // assumes dos sector skew
- {
- return new DiskDsk(name, data, isWriteProtected, SectorSkew.Dos);
- }
- else if (name.EndsWith(".nib", StringComparison.OrdinalIgnoreCase))
- {
- return new DiskNib(name, data, isWriteProtected);
- }
- else if (name.EndsWith(".po", StringComparison.OrdinalIgnoreCase))
- {
- return new DiskDsk(name, data, isWriteProtected, SectorSkew.ProDos);
- }
-
- return null;
- }
-
- public void SaveState(BinaryWriter writer)
- {
- if (writer == null)
- {
- throw new ArgumentNullException("writer");
- }
-
- writer.Write(Name);
- writer.Write(Data.Length);
- writer.Write(Data);
- writer.Write(IsWriteProtected);
- }
-
- 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; }
- [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
- public byte[] Data { get; protected set; }
- public bool IsWriteProtected { 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;
+using System.IO;
+using System.Text.RegularExpressions;
+using Jellyfish.Library;
+
+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, Stream stream, bool isWriteProtected)
+ {
+ if (name == null)
+ {
+ throw new ArgumentNullException("name");
+ }
+
+ if (name.EndsWith(".do", StringComparison.OrdinalIgnoreCase) ||
+ name.EndsWith(".dsk", StringComparison.OrdinalIgnoreCase)) // assumes dos sector skew
+ {
+ return new DiskDsk(name, stream, isWriteProtected, SectorSkew.Dos);
+ }
+ else if (name.EndsWith(".nib", StringComparison.OrdinalIgnoreCase))
+ {
+ return new DiskNib(name, stream, isWriteProtected);
+ }
+ else if (name.EndsWith(".po", StringComparison.OrdinalIgnoreCase))
+ {
+ return new DiskDsk(name, stream, isWriteProtected, SectorSkew.ProDos);
+ }
+
+ return null;
+ }
+
+ [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "version")]
+ public static Disk525 LoadState(BinaryReader reader, Version version)
+ {
+ if (reader == null)
+ {
+ throw new ArgumentNullException("reader");
+ }
+
+ string name = reader.ReadString();
+ var data = reader.ReadBytes(reader.ReadInt32());
+ bool isWriteProtected = reader.ReadBoolean();
+
+ if (name.EndsWith(".do", StringComparison.OrdinalIgnoreCase) ||
+ name.EndsWith(".dsk", StringComparison.OrdinalIgnoreCase)) // assumes dos sector skew
+ {
+ return new DiskDsk(name, data, isWriteProtected, SectorSkew.Dos);
+ }
+ else if (name.EndsWith(".nib", StringComparison.OrdinalIgnoreCase))
+ {
+ return new DiskNib(name, data, isWriteProtected);
+ }
+ else if (name.EndsWith(".po", StringComparison.OrdinalIgnoreCase))
+ {
+ return new DiskDsk(name, data, isWriteProtected, SectorSkew.ProDos);
+ }
+
+ return null;
+ }
+
+ public void SaveState(BinaryWriter writer)
+ {
+ if (writer == null)
+ {
+ throw new ArgumentNullException("writer");
+ }
+
+ writer.Write(Name);
+ writer.Write(Data.Length);
+ writer.Write(Data);
+ writer.Write(IsWriteProtected);
+ }
+
+ 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; }
+ [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
+ public byte[] Data { get; protected set; }
+ public bool IsWriteProtected { 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 90cc81a..6ebc967 100644
--- a/Virtu/DiskDsk.cs
+++ b/Virtu/DiskDsk.cs
@@ -1,324 +1,324 @@
-using System;
-using System.IO;
-using Jellyfish.Library;
-
-namespace Jellyfish.Virtu
-{
- public enum SectorSkew { None = 0, Dos, ProDos };
-
- public sealed class DiskDsk : Disk525
- {
- public DiskDsk(string name, byte[] data, bool isWriteProtected, SectorSkew sectorSkew) :
- base(name, data, isWriteProtected)
- {
- _sectorSkew = SectorSkewMode[(int)sectorSkew];
- }
-
- public DiskDsk(string name, Stream stream, bool isWriteProtected, SectorSkew sectorSkew) :
- base(name, new byte[TrackCount * SectorCount * SectorSize], isWriteProtected)
- {
- if (stream == null)
- {
- throw new ArgumentNullException("stream");
- }
-
- stream.ReadBlock(Data);
- _sectorSkew = SectorSkewMode[(int)sectorSkew];
- }
-
- 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 + _sectorSkew[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 + _sectorSkew[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 int[] _sectorSkew;
- private const int Volume = 0xFE;
-
- private static readonly byte[] SwapBits = { 0, 2, 1, 3 };
-
- private static readonly int[] SectorSkewNone = new int[SectorCount]
- {
- 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF
- };
-
- private static readonly int[] SectorSkewDos = new int[SectorCount]
- {
- 0x0, 0x7, 0xE, 0x6, 0xD, 0x5, 0xC, 0x4, 0xB, 0x3, 0xA, 0x2, 0x9, 0x1, 0x8, 0xF
- };
-
- private static readonly int[] SectorSkewProDos = new int[SectorCount]
- {
- 0x0, 0x8, 0x1, 0x9, 0x2, 0xA, 0x3, 0xB, 0x4, 0xC, 0x5, 0xD, 0x6, 0xE, 0x7, 0xF
- };
-
- private const int SectorSkewCount = 3;
-
- private static readonly int[][] SectorSkewMode = new int[SectorSkewCount][]
- {
- SectorSkewNone, SectorSkewDos, SectorSkewProDos
- };
-
- 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;
+using System.IO;
+using Jellyfish.Library;
+
+namespace Jellyfish.Virtu
+{
+ public enum SectorSkew { None = 0, Dos, ProDos };
+
+ public sealed class DiskDsk : Disk525
+ {
+ public DiskDsk(string name, byte[] data, bool isWriteProtected, SectorSkew sectorSkew) :
+ base(name, data, isWriteProtected)
+ {
+ _sectorSkew = SectorSkewMode[(int)sectorSkew];
+ }
+
+ public DiskDsk(string name, Stream stream, bool isWriteProtected, SectorSkew sectorSkew) :
+ base(name, new byte[TrackCount * SectorCount * SectorSize], isWriteProtected)
+ {
+ if (stream == null)
+ {
+ throw new ArgumentNullException("stream");
+ }
+
+ stream.ReadBlock(Data);
+ _sectorSkew = SectorSkewMode[(int)sectorSkew];
+ }
+
+ 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 + _sectorSkew[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 + _sectorSkew[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 int[] _sectorSkew;
+ private const int Volume = 0xFE;
+
+ private static readonly byte[] SwapBits = { 0, 2, 1, 3 };
+
+ private static readonly int[] SectorSkewNone = new int[SectorCount]
+ {
+ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF
+ };
+
+ private static readonly int[] SectorSkewDos = new int[SectorCount]
+ {
+ 0x0, 0x7, 0xE, 0x6, 0xD, 0x5, 0xC, 0x4, 0xB, 0x3, 0xA, 0x2, 0x9, 0x1, 0x8, 0xF
+ };
+
+ private static readonly int[] SectorSkewProDos = new int[SectorCount]
+ {
+ 0x0, 0x8, 0x1, 0x9, 0x2, 0xA, 0x3, 0xB, 0x4, 0xC, 0x5, 0xD, 0x6, 0xE, 0x7, 0xF
+ };
+
+ private const int SectorSkewCount = 3;
+
+ private static readonly int[][] SectorSkewMode = new int[SectorSkewCount][]
+ {
+ SectorSkewNone, SectorSkewDos, SectorSkewProDos
+ };
+
+ 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/DiskIIController.cs b/Virtu/DiskIIController.cs
index d082a11..e81637e 100644
--- a/Virtu/DiskIIController.cs
+++ b/Virtu/DiskIIController.cs
@@ -1,287 +1,287 @@
-using System;
-using System.Collections.ObjectModel;
-using System.Diagnostics.CodeAnalysis;
-using System.IO;
-using Jellyfish.Library;
-using Jellyfish.Virtu.Services;
-
-namespace Jellyfish.Virtu
-{
- public sealed class DiskIIController : PeripheralCard
- {
- public DiskIIController(Machine machine) :
- base(machine)
- {
- Drive1 = new DiskIIDrive(machine);
- Drive2 = new DiskIIDrive(machine);
-
- Drives = new Collection { Drive1, Drive2 };
-
- BootDrive = Drive1;
- }
-
- public override void Initialize()
- {
- StorageService.LoadResource("Roms/DiskII.rom", stream => stream.ReadBlock(_romRegionC1C7));
- }
-
- public override void Reset()
- {
- _phaseStates = 0;
- SetMotorOn(false);
- SetDriveNumber(0);
- _loadMode = false;
- _writeMode = false;
- }
-
- public override void LoadState(BinaryReader reader, Version version)
- {
- if (reader == null)
- {
- throw new ArgumentNullException("reader");
- }
-
- _latch = reader.ReadInt32();
- _phaseStates = reader.ReadInt32();
- _motorOn = reader.ReadBoolean();
- _driveNumber = reader.ReadInt32();
- _loadMode = reader.ReadBoolean();
- _writeMode = reader.ReadBoolean();
- _driveSpin = reader.ReadBoolean();
- foreach (var drive in Drives)
- {
- DebugService.WriteMessage("Loading machine '{0}'", drive.GetType().Name);
- drive.LoadState(reader, version);
- //DebugService.WriteMessage("Loaded machine '{0}'", drive.GetType().Name);
- }
- }
-
- public override void SaveState(BinaryWriter writer)
- {
- if (writer == null)
- {
- throw new ArgumentNullException("writer");
- }
-
- writer.Write(_latch);
- writer.Write(_phaseStates);
- writer.Write(_motorOn);
- writer.Write(_driveNumber);
- writer.Write(_loadMode);
- writer.Write(_writeMode);
- writer.Write(_driveSpin);
- foreach (var drive in Drives)
- {
- DebugService.WriteMessage("Saving machine '{0}'", drive.GetType().Name);
- drive.SaveState(writer);
- //DebugService.WriteMessage("Saved machine '{0}'", drive.GetType().Name);
- }
- }
-
- [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
- public override int ReadIoRegionC0C0(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 ReadFloatingBus();
- }
-
- public override int ReadIoRegionC1C7(int address)
- {
- return _romRegionC1C7[address & 0xFF];
- }
-
- public override void WriteIoRegionC0C0(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);
- }
- }
-
- public DiskIIDrive Drive1 { get; private set; }
- public DiskIIDrive Drive2 { get; private set; }
-
- public Collection Drives { get; private set; }
-
- public DiskIIDrive BootDrive { get; private set; }
-
- 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 int _latch;
- private int _phaseStates;
- private bool _motorOn;
- private int _driveNumber;
- private bool _loadMode;
- private bool _writeMode;
- private bool _driveSpin;
-
- private byte[] _romRegionC1C7 = new byte[0x0100];
- }
-}
+using System;
+using System.Collections.ObjectModel;
+using System.Diagnostics.CodeAnalysis;
+using System.IO;
+using Jellyfish.Library;
+using Jellyfish.Virtu.Services;
+
+namespace Jellyfish.Virtu
+{
+ public sealed class DiskIIController : PeripheralCard
+ {
+ public DiskIIController(Machine machine) :
+ base(machine)
+ {
+ Drive1 = new DiskIIDrive(machine);
+ Drive2 = new DiskIIDrive(machine);
+
+ Drives = new Collection { Drive1, Drive2 };
+
+ BootDrive = Drive1;
+ }
+
+ public override void Initialize()
+ {
+ StorageService.LoadResource("Roms/DiskII.rom", stream => stream.ReadBlock(_romRegionC1C7));
+ }
+
+ public override void Reset()
+ {
+ _phaseStates = 0;
+ SetMotorOn(false);
+ SetDriveNumber(0);
+ _loadMode = false;
+ _writeMode = false;
+ }
+
+ public override void LoadState(BinaryReader reader, Version version)
+ {
+ if (reader == null)
+ {
+ throw new ArgumentNullException("reader");
+ }
+
+ _latch = reader.ReadInt32();
+ _phaseStates = reader.ReadInt32();
+ _motorOn = reader.ReadBoolean();
+ _driveNumber = reader.ReadInt32();
+ _loadMode = reader.ReadBoolean();
+ _writeMode = reader.ReadBoolean();
+ _driveSpin = reader.ReadBoolean();
+ foreach (var drive in Drives)
+ {
+ DebugService.WriteMessage("Loading machine '{0}'", drive.GetType().Name);
+ drive.LoadState(reader, version);
+ //DebugService.WriteMessage("Loaded machine '{0}'", drive.GetType().Name);
+ }
+ }
+
+ public override void SaveState(BinaryWriter writer)
+ {
+ if (writer == null)
+ {
+ throw new ArgumentNullException("writer");
+ }
+
+ writer.Write(_latch);
+ writer.Write(_phaseStates);
+ writer.Write(_motorOn);
+ writer.Write(_driveNumber);
+ writer.Write(_loadMode);
+ writer.Write(_writeMode);
+ writer.Write(_driveSpin);
+ foreach (var drive in Drives)
+ {
+ DebugService.WriteMessage("Saving machine '{0}'", drive.GetType().Name);
+ drive.SaveState(writer);
+ //DebugService.WriteMessage("Saved machine '{0}'", drive.GetType().Name);
+ }
+ }
+
+ [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
+ public override int ReadIoRegionC0C0(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 ReadFloatingBus();
+ }
+
+ public override int ReadIoRegionC1C7(int address)
+ {
+ return _romRegionC1C7[address & 0xFF];
+ }
+
+ public override void WriteIoRegionC0C0(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);
+ }
+ }
+
+ public DiskIIDrive Drive1 { get; private set; }
+ public DiskIIDrive Drive2 { get; private set; }
+
+ public Collection Drives { get; private set; }
+
+ public DiskIIDrive BootDrive { get; private set; }
+
+ 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 int _latch;
+ private int _phaseStates;
+ private bool _motorOn;
+ private int _driveNumber;
+ private bool _loadMode;
+ private bool _writeMode;
+ private bool _driveSpin;
+
+ private byte[] _romRegionC1C7 = new byte[0x0100];
+ }
+}
diff --git a/Virtu/DiskIIDrive.cs b/Virtu/DiskIIDrive.cs
index c59c2cf..a01e676 100644
--- a/Virtu/DiskIIDrive.cs
+++ b/Virtu/DiskIIDrive.cs
@@ -1,172 +1,172 @@
-using System;
-using System.IO;
-using Jellyfish.Library;
-using Jellyfish.Virtu.Services;
-
-namespace Jellyfish.Virtu
-{
- public sealed class DiskIIDrive : MachineComponent
- {
- public DiskIIDrive(Machine machine) :
- base(machine)
- {
- 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 override void LoadState(BinaryReader reader, Version version)
- {
- if (reader == null)
- {
- throw new ArgumentNullException("reader");
- }
-
- _trackLoaded = reader.ReadBoolean();
- _trackChanged = reader.ReadBoolean();
- _trackNumber = reader.ReadInt32();
- _trackOffset = reader.ReadInt32();
- if (_trackLoaded)
- {
- reader.Read(_trackData, 0, _trackData.Length);
- }
- if (reader.ReadBoolean())
- {
- DebugService.WriteMessage("Loading machine '{0}'", typeof(Disk525).Name);
- _disk = Disk525.LoadState(reader, version);
- }
- else
- {
- _disk = null;
- }
- }
-
- public override void SaveState(BinaryWriter writer)
- {
- if (writer == null)
- {
- throw new ArgumentNullException("writer");
- }
-
- writer.Write(_trackLoaded);
- writer.Write(_trackChanged);
- writer.Write(_trackNumber);
- writer.Write(_trackOffset);
- if (_trackLoaded)
- {
- writer.Write(_trackData);
- }
- writer.Write(_disk != null);
- if (_disk != null)
- {
- DebugService.WriteMessage("Saving machine '{0}'", _disk.GetType().Name);
- _disk.SaveState(writer);
- }
- }
-
- public void InsertDisk(string name, Stream stream, bool isWriteProtected)
- {
- DebugService.WriteMessage("Inserting disk '{0}'", name);
- FlushTrack();
- _disk = Disk525.CreateDisk(name, stream, isWriteProtected);
- _trackLoaded = false;
- }
-
- public void RemoveDisk()
- {
- if (_disk != null)
- {
- DebugService.WriteMessage("Removing disk '{0}'", _disk.Name);
- _trackLoaded = false;
- _trackChanged = false;
- _trackNumber = 0;
- _trackOffset = 0;
- _disk = null;
- }
- }
-
- 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 bool _trackLoaded;
- private bool _trackChanged;
- private int _trackNumber;
- private int _trackOffset;
- private byte[] _trackData = new byte[Disk525.TrackSize];
- private Disk525 _disk;
-
- private Random _random = new Random();
- }
-}
+using System;
+using System.IO;
+using Jellyfish.Library;
+using Jellyfish.Virtu.Services;
+
+namespace Jellyfish.Virtu
+{
+ public sealed class DiskIIDrive : MachineComponent
+ {
+ public DiskIIDrive(Machine machine) :
+ base(machine)
+ {
+ 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 override void LoadState(BinaryReader reader, Version version)
+ {
+ if (reader == null)
+ {
+ throw new ArgumentNullException("reader");
+ }
+
+ _trackLoaded = reader.ReadBoolean();
+ _trackChanged = reader.ReadBoolean();
+ _trackNumber = reader.ReadInt32();
+ _trackOffset = reader.ReadInt32();
+ if (_trackLoaded)
+ {
+ reader.Read(_trackData, 0, _trackData.Length);
+ }
+ if (reader.ReadBoolean())
+ {
+ DebugService.WriteMessage("Loading machine '{0}'", typeof(Disk525).Name);
+ _disk = Disk525.LoadState(reader, version);
+ }
+ else
+ {
+ _disk = null;
+ }
+ }
+
+ public override void SaveState(BinaryWriter writer)
+ {
+ if (writer == null)
+ {
+ throw new ArgumentNullException("writer");
+ }
+
+ writer.Write(_trackLoaded);
+ writer.Write(_trackChanged);
+ writer.Write(_trackNumber);
+ writer.Write(_trackOffset);
+ if (_trackLoaded)
+ {
+ writer.Write(_trackData);
+ }
+ writer.Write(_disk != null);
+ if (_disk != null)
+ {
+ DebugService.WriteMessage("Saving machine '{0}'", _disk.GetType().Name);
+ _disk.SaveState(writer);
+ }
+ }
+
+ public void InsertDisk(string name, Stream stream, bool isWriteProtected)
+ {
+ DebugService.WriteMessage("Inserting disk '{0}'", name);
+ FlushTrack();
+ _disk = Disk525.CreateDisk(name, stream, isWriteProtected);
+ _trackLoaded = false;
+ }
+
+ public void RemoveDisk()
+ {
+ if (_disk != null)
+ {
+ DebugService.WriteMessage("Removing disk '{0}'", _disk.Name);
+ _trackLoaded = false;
+ _trackChanged = false;
+ _trackNumber = 0;
+ _trackOffset = 0;
+ _disk = null;
+ }
+ }
+
+ 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 bool _trackLoaded;
+ private bool _trackChanged;
+ private int _trackNumber;
+ private int _trackOffset;
+ private byte[] _trackData = new byte[Disk525.TrackSize];
+ private Disk525 _disk;
+
+ private Random _random = new Random();
+ }
+}
diff --git a/Virtu/DiskNib.cs b/Virtu/DiskNib.cs
index e186e00..68d0a5f 100644
--- a/Virtu/DiskNib.cs
+++ b/Virtu/DiskNib.cs
@@ -1,35 +1,35 @@
-using System;
-using System.IO;
-using Jellyfish.Library;
-
-namespace Jellyfish.Virtu
-{
- public sealed class DiskNib : Disk525
- {
- public DiskNib(string name, byte[] data, bool isWriteProtected) :
- base(name, data, isWriteProtected)
- {
- }
-
- public DiskNib(string name, Stream stream, bool isWriteProtected) :
- base(name, new byte[TrackCount * TrackSize], isWriteProtected)
- {
- if (stream == null)
- {
- throw new ArgumentNullException("stream");
- }
-
- stream.ReadBlock(Data);
- }
-
- 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;
+using System.IO;
+using Jellyfish.Library;
+
+namespace Jellyfish.Virtu
+{
+ public sealed class DiskNib : Disk525
+ {
+ public DiskNib(string name, byte[] data, bool isWriteProtected) :
+ base(name, data, isWriteProtected)
+ {
+ }
+
+ public DiskNib(string name, Stream stream, bool isWriteProtected) :
+ base(name, new byte[TrackCount * TrackSize], isWriteProtected)
+ {
+ if (stream == null)
+ {
+ throw new ArgumentNullException("stream");
+ }
+
+ stream.ReadBlock(Data);
+ }
+
+ 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/GamePort.cs b/Virtu/GamePort.cs
index 1c5320e..fff1dd3 100644
--- a/Virtu/GamePort.cs
+++ b/Virtu/GamePort.cs
@@ -1,370 +1,370 @@
-using System;
-using System.Diagnostics.CodeAnalysis;
-using System.IO;
-using Jellyfish.Library;
-using Jellyfish.Virtu.Services;
-
-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();
-
- JoystickDeadZone = 0.4f;
-
- InvertPaddles = true; // Raster Blaster
- SwapPaddles = true;
- Joystick0TouchX = 0.35f;
- Joystick0TouchY = 0.6f;
- Joystick0TouchWidth = 0.25f;
- Joystick0TouchHeight = 0.4f;
- Joystick0TouchRadius = 0.2f;
- Joystick0TouchKeepLast = true;
- Button0TouchX = 0;
- Button0TouchY = 0;
- Button0TouchWidth = 0.5f;
- Button0TouchHeight = 1;
- Button1TouchX = 0.5f;
- Button1TouchY = 0;
- Button1TouchWidth = 0.5f;
- Button1TouchHeight = 1;
- Button2TouchX = 0.75f;
- Button2TouchY = 0;
- Button2TouchWidth = 0.25f;
- Button2TouchHeight = 0.25f;
- Button2TouchOrder = 1;
- }
-
- public override void LoadState(BinaryReader reader, Version version)
- {
- if (reader == null)
- {
- throw new ArgumentNullException("reader");
- }
-
- InvertPaddles = reader.ReadBoolean();
- SwapPaddles = reader.ReadBoolean();
- UseShiftKeyMod = reader.ReadBoolean();
- JoystickDeadZone = reader.ReadSingle();
-
- UseKeyboard = reader.ReadBoolean();
- Joystick0UpLeftKey = reader.ReadInt32();
- Joystick0UpKey = reader.ReadInt32();
- Joystick0UpRightKey = reader.ReadInt32();
- Joystick0LeftKey = reader.ReadInt32();
- Joystick0RightKey = reader.ReadInt32();
- Joystick0DownLeftKey = reader.ReadInt32();
- Joystick0DownKey = reader.ReadInt32();
- Joystick0DownRightKey = reader.ReadInt32();
- Joystick1UpLeftKey = reader.ReadInt32();
- Joystick1UpKey = reader.ReadInt32();
- Joystick1UpRightKey = reader.ReadInt32();
- Joystick1LeftKey = reader.ReadInt32();
- Joystick1RightKey = reader.ReadInt32();
- Joystick1DownLeftKey = reader.ReadInt32();
- Joystick1DownKey = reader.ReadInt32();
- Joystick1DownRightKey = reader.ReadInt32();
- Button0Key = reader.ReadInt32();
- Button1Key = reader.ReadInt32();
- Button2Key = reader.ReadInt32();
-
- UseTouch = reader.ReadBoolean();
- Joystick0TouchX = reader.ReadSingle();
- Joystick0TouchY = reader.ReadSingle();
- Joystick0TouchWidth = reader.ReadSingle();
- Joystick0TouchHeight = reader.ReadSingle();
- Joystick0TouchOrder = reader.ReadInt32();
- Joystick0TouchRadius = reader.ReadSingle();
- Joystick0TouchKeepLast = reader.ReadBoolean();
- Joystick1TouchX = reader.ReadSingle();
- Joystick1TouchY = reader.ReadSingle();
- Joystick1TouchWidth = reader.ReadSingle();
- Joystick1TouchHeight = reader.ReadSingle();
- Joystick1TouchOrder = reader.ReadInt32();
- Joystick1TouchRadius = reader.ReadSingle();
- Joystick1TouchKeepLast = reader.ReadBoolean();
- Button0TouchX = reader.ReadSingle();
- Button0TouchY = reader.ReadSingle();
- Button0TouchWidth = reader.ReadSingle();
- Button0TouchHeight = reader.ReadSingle();
- Button0TouchOrder = reader.ReadInt32();
- Button1TouchX = reader.ReadSingle();
- Button1TouchY = reader.ReadSingle();
- Button1TouchWidth = reader.ReadSingle();
- Button1TouchHeight = reader.ReadSingle();
- Button1TouchOrder = reader.ReadInt32();
- Button2TouchX = reader.ReadSingle();
- Button2TouchY = reader.ReadSingle();
- Button2TouchWidth = reader.ReadSingle();
- Button2TouchHeight = reader.ReadSingle();
- Button2TouchOrder = reader.ReadInt32();
- }
-
- public override void SaveState(BinaryWriter writer)
- {
- if (writer == null)
- {
- throw new ArgumentNullException("writer");
- }
-
- writer.Write(InvertPaddles);
- writer.Write(SwapPaddles);
- writer.Write(UseShiftKeyMod);
- writer.Write(JoystickDeadZone);
-
- writer.Write(UseKeyboard);
- writer.Write(Joystick0UpLeftKey);
- writer.Write(Joystick0UpKey);
- writer.Write(Joystick0UpRightKey);
- writer.Write(Joystick0LeftKey);
- writer.Write(Joystick0RightKey);
- writer.Write(Joystick0DownLeftKey);
- writer.Write(Joystick0DownKey);
- writer.Write(Joystick0DownRightKey);
- writer.Write(Joystick1UpLeftKey);
- writer.Write(Joystick1UpKey);
- writer.Write(Joystick1UpRightKey);
- writer.Write(Joystick1LeftKey);
- writer.Write(Joystick1RightKey);
- writer.Write(Joystick1DownLeftKey);
- writer.Write(Joystick1DownKey);
- writer.Write(Joystick1DownRightKey);
- writer.Write(Button0Key);
- writer.Write(Button1Key);
- writer.Write(Button2Key);
-
- writer.Write(UseTouch);
- writer.Write(Joystick0TouchX);
- writer.Write(Joystick0TouchY);
- writer.Write(Joystick0TouchWidth);
- writer.Write(Joystick0TouchHeight);
- writer.Write(Joystick0TouchOrder);
- writer.Write(Joystick0TouchRadius);
- writer.Write(Joystick0TouchKeepLast);
- writer.Write(Joystick1TouchX);
- writer.Write(Joystick1TouchY);
- writer.Write(Joystick1TouchWidth);
- writer.Write(Joystick1TouchHeight);
- writer.Write(Joystick1TouchOrder);
- writer.Write(Joystick1TouchRadius);
- writer.Write(Joystick1TouchKeepLast);
- writer.Write(Button0TouchX);
- writer.Write(Button0TouchY);
- writer.Write(Button0TouchWidth);
- writer.Write(Button0TouchHeight);
- writer.Write(Button0TouchOrder);
- writer.Write(Button1TouchX);
- writer.Write(Button1TouchY);
- writer.Write(Button1TouchWidth);
- writer.Write(Button1TouchHeight);
- writer.Write(Button1TouchOrder);
- writer.Write(Button2TouchX);
- writer.Write(Button2TouchY);
- writer.Write(Button2TouchWidth);
- writer.Write(Button2TouchHeight);
- writer.Write(Button2TouchOrder);
- }
-
- public bool ReadButton0()
- {
- return (_gamePortService.IsButton0Down || _keyboardService.IsOpenAppleKeyDown ||
- (UseKeyboard && (Button0Key > 0) && _keyboardService.IsKeyDown(Button0Key)));
- }
-
- public bool ReadButton1()
- {
- return (_gamePortService.IsButton1Down || _keyboardService.IsCloseAppleKeyDown ||
- (UseKeyboard && (Button1Key > 0) && _keyboardService.IsKeyDown(Button1Key)));
- }
-
- public bool ReadButton2()
- {
- return (_gamePortService.IsButton2Down || (UseShiftKeyMod && !_keyboardService.IsShiftKeyDown) || // Shift' [TN9]
- (UseKeyboard && (Button2Key > 0) && _keyboardService.IsKeyDown(Button2Key)));
- }
-
- [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
- public void TriggerTimers()
- {
- int paddle0 = _gamePortService.Paddle0;
- int paddle1 = _gamePortService.Paddle1;
- int paddle2 = _gamePortService.Paddle2;
- int paddle3 = _gamePortService.Paddle3;
-
- if (UseKeyboard) // override
- {
- if (((Joystick0UpLeftKey > 0) && _keyboardService.IsKeyDown(Joystick0UpLeftKey)) ||
- ((Joystick0LeftKey > 0) && _keyboardService.IsKeyDown(Joystick0LeftKey)) ||
- ((Joystick0DownLeftKey > 0) && _keyboardService.IsKeyDown(Joystick0DownLeftKey)))
- {
- paddle0 -= PaddleScale;
- }
- if (((Joystick0UpRightKey > 0) && _keyboardService.IsKeyDown(Joystick0UpRightKey)) ||
- ((Joystick0RightKey > 0) && _keyboardService.IsKeyDown(Joystick0RightKey)) ||
- ((Joystick0DownRightKey > 0) && _keyboardService.IsKeyDown(Joystick0DownRightKey)))
- {
- paddle0 += PaddleScale;
- }
- if (((Joystick0UpLeftKey > 0) && _keyboardService.IsKeyDown(Joystick0UpLeftKey)) ||
- ((Joystick0UpKey > 0) && _keyboardService.IsKeyDown(Joystick0UpKey)) ||
- ((Joystick0UpRightKey > 0) && _keyboardService.IsKeyDown(Joystick0UpRightKey)))
- {
- paddle1 -= PaddleScale;
- }
- if (((Joystick0DownLeftKey > 0) && _keyboardService.IsKeyDown(Joystick0DownLeftKey)) ||
- ((Joystick0DownKey > 0) && _keyboardService.IsKeyDown(Joystick0DownKey)) ||
- ((Joystick0DownRightKey > 0) && _keyboardService.IsKeyDown(Joystick0DownRightKey)))
- {
- paddle1 += PaddleScale;
- }
- if (((Joystick1UpLeftKey > 0) && _keyboardService.IsKeyDown(Joystick1UpLeftKey)) ||
- ((Joystick1LeftKey > 0) && _keyboardService.IsKeyDown(Joystick1LeftKey)) ||
- ((Joystick1DownLeftKey > 0) && _keyboardService.IsKeyDown(Joystick1DownLeftKey)))
- {
- paddle2 -= PaddleScale;
- }
- if (((Joystick1UpRightKey > 0) && _keyboardService.IsKeyDown(Joystick1UpRightKey)) ||
- ((Joystick1RightKey > 0) && _keyboardService.IsKeyDown(Joystick1RightKey)) ||
- ((Joystick1DownRightKey > 0) && _keyboardService.IsKeyDown(Joystick1DownRightKey)))
- {
- paddle2 += PaddleScale;
- }
- if (((Joystick1UpLeftKey > 0) && _keyboardService.IsKeyDown(Joystick1UpLeftKey)) ||
- ((Joystick1UpKey > 0) && _keyboardService.IsKeyDown(Joystick1UpKey)) ||
- ((Joystick1UpRightKey > 0) && _keyboardService.IsKeyDown(Joystick1UpRightKey)))
- {
- paddle3 -= PaddleScale;
- }
- if (((Joystick1DownLeftKey > 0) && _keyboardService.IsKeyDown(Joystick1DownLeftKey)) ||
- ((Joystick1DownKey > 0) && _keyboardService.IsKeyDown(Joystick1DownKey)) ||
- ((Joystick1DownRightKey > 0) && _keyboardService.IsKeyDown(Joystick1DownRightKey)))
- {
- paddle3 += PaddleScale;
- }
- }
- if (InvertPaddles)
- {
- paddle0 = 2 * PaddleScale - paddle0;
- paddle1 = 2 * PaddleScale - paddle1;
- paddle2 = 2 * PaddleScale - paddle2;
- paddle3 = 2 * PaddleScale - paddle3;
- }
-
- Paddle0Strobe = true;
- Paddle1Strobe = true;
- Paddle2Strobe = true;
- Paddle3Strobe = true;
-
- Machine.Events.AddEvent(MathHelpers.ClampByte(SwapPaddles ? paddle1 : paddle0) * CyclesPerValue, _resetPaddle0StrobeEvent); // [7-29]
- Machine.Events.AddEvent(MathHelpers.ClampByte(SwapPaddles ? paddle0 : paddle1) * CyclesPerValue, _resetPaddle1StrobeEvent);
- Machine.Events.AddEvent(MathHelpers.ClampByte(SwapPaddles ? paddle3 : paddle2) * CyclesPerValue, _resetPaddle2StrobeEvent);
- Machine.Events.AddEvent(MathHelpers.ClampByte(SwapPaddles ? paddle2 : paddle3) * CyclesPerValue, _resetPaddle3StrobeEvent);
- }
-
- private void ResetPaddle0StrobeEvent()
- {
- Paddle0Strobe = false;
- }
-
- private void ResetPaddle1StrobeEvent()
- {
- Paddle1Strobe = false;
- }
-
- private void ResetPaddle2StrobeEvent()
- {
- Paddle2Strobe = false;
- }
-
- private void ResetPaddle3StrobeEvent()
- {
- Paddle3Strobe = false;
- }
-
- public const int PaddleScale = 128;
-
- public bool InvertPaddles { get; set; }
- public bool SwapPaddles { get; set; }
- public bool UseShiftKeyMod { get; set; }
- public float JoystickDeadZone { get; set; }
-
- public bool UseKeyboard { get; set; }
- public int Joystick0UpLeftKey { get; set; }
- public int Joystick0UpKey { get; set; }
- public int Joystick0UpRightKey { get; set; }
- public int Joystick0LeftKey { get; set; }
- public int Joystick0RightKey { get; set; }
- public int Joystick0DownLeftKey { get; set; }
- public int Joystick0DownKey { get; set; }
- public int Joystick0DownRightKey { get; set; }
- public int Joystick1UpLeftKey { get; set; }
- public int Joystick1UpKey { get; set; }
- public int Joystick1UpRightKey { get; set; }
- public int Joystick1LeftKey { get; set; }
- public int Joystick1RightKey { get; set; }
- public int Joystick1DownLeftKey { get; set; }
- public int Joystick1DownKey { get; set; }
- public int Joystick1DownRightKey { get; set; }
- public int Button0Key { get; set; }
- public int Button1Key { get; set; }
- public int Button2Key { get; set; }
-
- public bool UseTouch { get; set; }
- public float Joystick0TouchX { get; set; }
- public float Joystick0TouchY { get; set; }
- public float Joystick0TouchWidth { get; set; }
- public float Joystick0TouchHeight { get; set; }
- public int Joystick0TouchOrder { get; set; }
- public float Joystick0TouchRadius { get; set; }
- public bool Joystick0TouchKeepLast { get; set; }
- public float Joystick1TouchX { get; set; }
- public float Joystick1TouchY { get; set; }
- public float Joystick1TouchWidth { get; set; }
- public float Joystick1TouchHeight { get; set; }
- public int Joystick1TouchOrder { get; set; }
- public float Joystick1TouchRadius { get; set; }
- public bool Joystick1TouchKeepLast { get; set; }
- public float Button0TouchX { get; set; }
- public float Button0TouchY { get; set; }
- public float Button0TouchWidth { get; set; }
- public float Button0TouchHeight { get; set; }
- public int Button0TouchOrder { get; set; }
- public float Button1TouchX { get; set; }
- public float Button1TouchY { get; set; }
- public float Button1TouchWidth { get; set; }
- public float Button1TouchHeight { get; set; }
- public int Button1TouchOrder { get; set; }
- public float Button2TouchX { get; set; }
- public float Button2TouchY { get; set; }
- public float Button2TouchWidth { get; set; }
- public float Button2TouchHeight { get; set; }
- public int Button2TouchOrder { get; set; }
-
- 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 System.IO;
+using Jellyfish.Library;
+using Jellyfish.Virtu.Services;
+
+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();
+
+ JoystickDeadZone = 0.4f;
+
+ InvertPaddles = true; // Raster Blaster
+ SwapPaddles = true;
+ Joystick0TouchX = 0.35f;
+ Joystick0TouchY = 0.6f;
+ Joystick0TouchWidth = 0.25f;
+ Joystick0TouchHeight = 0.4f;
+ Joystick0TouchRadius = 0.2f;
+ Joystick0TouchKeepLast = true;
+ Button0TouchX = 0;
+ Button0TouchY = 0;
+ Button0TouchWidth = 0.5f;
+ Button0TouchHeight = 1;
+ Button1TouchX = 0.5f;
+ Button1TouchY = 0;
+ Button1TouchWidth = 0.5f;
+ Button1TouchHeight = 1;
+ Button2TouchX = 0.75f;
+ Button2TouchY = 0;
+ Button2TouchWidth = 0.25f;
+ Button2TouchHeight = 0.25f;
+ Button2TouchOrder = 1;
+ }
+
+ public override void LoadState(BinaryReader reader, Version version)
+ {
+ if (reader == null)
+ {
+ throw new ArgumentNullException("reader");
+ }
+
+ InvertPaddles = reader.ReadBoolean();
+ SwapPaddles = reader.ReadBoolean();
+ UseShiftKeyMod = reader.ReadBoolean();
+ JoystickDeadZone = reader.ReadSingle();
+
+ UseKeyboard = reader.ReadBoolean();
+ Joystick0UpLeftKey = reader.ReadInt32();
+ Joystick0UpKey = reader.ReadInt32();
+ Joystick0UpRightKey = reader.ReadInt32();
+ Joystick0LeftKey = reader.ReadInt32();
+ Joystick0RightKey = reader.ReadInt32();
+ Joystick0DownLeftKey = reader.ReadInt32();
+ Joystick0DownKey = reader.ReadInt32();
+ Joystick0DownRightKey = reader.ReadInt32();
+ Joystick1UpLeftKey = reader.ReadInt32();
+ Joystick1UpKey = reader.ReadInt32();
+ Joystick1UpRightKey = reader.ReadInt32();
+ Joystick1LeftKey = reader.ReadInt32();
+ Joystick1RightKey = reader.ReadInt32();
+ Joystick1DownLeftKey = reader.ReadInt32();
+ Joystick1DownKey = reader.ReadInt32();
+ Joystick1DownRightKey = reader.ReadInt32();
+ Button0Key = reader.ReadInt32();
+ Button1Key = reader.ReadInt32();
+ Button2Key = reader.ReadInt32();
+
+ UseTouch = reader.ReadBoolean();
+ Joystick0TouchX = reader.ReadSingle();
+ Joystick0TouchY = reader.ReadSingle();
+ Joystick0TouchWidth = reader.ReadSingle();
+ Joystick0TouchHeight = reader.ReadSingle();
+ Joystick0TouchOrder = reader.ReadInt32();
+ Joystick0TouchRadius = reader.ReadSingle();
+ Joystick0TouchKeepLast = reader.ReadBoolean();
+ Joystick1TouchX = reader.ReadSingle();
+ Joystick1TouchY = reader.ReadSingle();
+ Joystick1TouchWidth = reader.ReadSingle();
+ Joystick1TouchHeight = reader.ReadSingle();
+ Joystick1TouchOrder = reader.ReadInt32();
+ Joystick1TouchRadius = reader.ReadSingle();
+ Joystick1TouchKeepLast = reader.ReadBoolean();
+ Button0TouchX = reader.ReadSingle();
+ Button0TouchY = reader.ReadSingle();
+ Button0TouchWidth = reader.ReadSingle();
+ Button0TouchHeight = reader.ReadSingle();
+ Button0TouchOrder = reader.ReadInt32();
+ Button1TouchX = reader.ReadSingle();
+ Button1TouchY = reader.ReadSingle();
+ Button1TouchWidth = reader.ReadSingle();
+ Button1TouchHeight = reader.ReadSingle();
+ Button1TouchOrder = reader.ReadInt32();
+ Button2TouchX = reader.ReadSingle();
+ Button2TouchY = reader.ReadSingle();
+ Button2TouchWidth = reader.ReadSingle();
+ Button2TouchHeight = reader.ReadSingle();
+ Button2TouchOrder = reader.ReadInt32();
+ }
+
+ public override void SaveState(BinaryWriter writer)
+ {
+ if (writer == null)
+ {
+ throw new ArgumentNullException("writer");
+ }
+
+ writer.Write(InvertPaddles);
+ writer.Write(SwapPaddles);
+ writer.Write(UseShiftKeyMod);
+ writer.Write(JoystickDeadZone);
+
+ writer.Write(UseKeyboard);
+ writer.Write(Joystick0UpLeftKey);
+ writer.Write(Joystick0UpKey);
+ writer.Write(Joystick0UpRightKey);
+ writer.Write(Joystick0LeftKey);
+ writer.Write(Joystick0RightKey);
+ writer.Write(Joystick0DownLeftKey);
+ writer.Write(Joystick0DownKey);
+ writer.Write(Joystick0DownRightKey);
+ writer.Write(Joystick1UpLeftKey);
+ writer.Write(Joystick1UpKey);
+ writer.Write(Joystick1UpRightKey);
+ writer.Write(Joystick1LeftKey);
+ writer.Write(Joystick1RightKey);
+ writer.Write(Joystick1DownLeftKey);
+ writer.Write(Joystick1DownKey);
+ writer.Write(Joystick1DownRightKey);
+ writer.Write(Button0Key);
+ writer.Write(Button1Key);
+ writer.Write(Button2Key);
+
+ writer.Write(UseTouch);
+ writer.Write(Joystick0TouchX);
+ writer.Write(Joystick0TouchY);
+ writer.Write(Joystick0TouchWidth);
+ writer.Write(Joystick0TouchHeight);
+ writer.Write(Joystick0TouchOrder);
+ writer.Write(Joystick0TouchRadius);
+ writer.Write(Joystick0TouchKeepLast);
+ writer.Write(Joystick1TouchX);
+ writer.Write(Joystick1TouchY);
+ writer.Write(Joystick1TouchWidth);
+ writer.Write(Joystick1TouchHeight);
+ writer.Write(Joystick1TouchOrder);
+ writer.Write(Joystick1TouchRadius);
+ writer.Write(Joystick1TouchKeepLast);
+ writer.Write(Button0TouchX);
+ writer.Write(Button0TouchY);
+ writer.Write(Button0TouchWidth);
+ writer.Write(Button0TouchHeight);
+ writer.Write(Button0TouchOrder);
+ writer.Write(Button1TouchX);
+ writer.Write(Button1TouchY);
+ writer.Write(Button1TouchWidth);
+ writer.Write(Button1TouchHeight);
+ writer.Write(Button1TouchOrder);
+ writer.Write(Button2TouchX);
+ writer.Write(Button2TouchY);
+ writer.Write(Button2TouchWidth);
+ writer.Write(Button2TouchHeight);
+ writer.Write(Button2TouchOrder);
+ }
+
+ public bool ReadButton0()
+ {
+ return (_gamePortService.IsButton0Down || _keyboardService.IsOpenAppleKeyDown ||
+ (UseKeyboard && (Button0Key > 0) && _keyboardService.IsKeyDown(Button0Key)));
+ }
+
+ public bool ReadButton1()
+ {
+ return (_gamePortService.IsButton1Down || _keyboardService.IsCloseAppleKeyDown ||
+ (UseKeyboard && (Button1Key > 0) && _keyboardService.IsKeyDown(Button1Key)));
+ }
+
+ public bool ReadButton2()
+ {
+ return (_gamePortService.IsButton2Down || (UseShiftKeyMod && !_keyboardService.IsShiftKeyDown) || // Shift' [TN9]
+ (UseKeyboard && (Button2Key > 0) && _keyboardService.IsKeyDown(Button2Key)));
+ }
+
+ [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
+ public void TriggerTimers()
+ {
+ int paddle0 = _gamePortService.Paddle0;
+ int paddle1 = _gamePortService.Paddle1;
+ int paddle2 = _gamePortService.Paddle2;
+ int paddle3 = _gamePortService.Paddle3;
+
+ if (UseKeyboard) // override
+ {
+ if (((Joystick0UpLeftKey > 0) && _keyboardService.IsKeyDown(Joystick0UpLeftKey)) ||
+ ((Joystick0LeftKey > 0) && _keyboardService.IsKeyDown(Joystick0LeftKey)) ||
+ ((Joystick0DownLeftKey > 0) && _keyboardService.IsKeyDown(Joystick0DownLeftKey)))
+ {
+ paddle0 -= PaddleScale;
+ }
+ if (((Joystick0UpRightKey > 0) && _keyboardService.IsKeyDown(Joystick0UpRightKey)) ||
+ ((Joystick0RightKey > 0) && _keyboardService.IsKeyDown(Joystick0RightKey)) ||
+ ((Joystick0DownRightKey > 0) && _keyboardService.IsKeyDown(Joystick0DownRightKey)))
+ {
+ paddle0 += PaddleScale;
+ }
+ if (((Joystick0UpLeftKey > 0) && _keyboardService.IsKeyDown(Joystick0UpLeftKey)) ||
+ ((Joystick0UpKey > 0) && _keyboardService.IsKeyDown(Joystick0UpKey)) ||
+ ((Joystick0UpRightKey > 0) && _keyboardService.IsKeyDown(Joystick0UpRightKey)))
+ {
+ paddle1 -= PaddleScale;
+ }
+ if (((Joystick0DownLeftKey > 0) && _keyboardService.IsKeyDown(Joystick0DownLeftKey)) ||
+ ((Joystick0DownKey > 0) && _keyboardService.IsKeyDown(Joystick0DownKey)) ||
+ ((Joystick0DownRightKey > 0) && _keyboardService.IsKeyDown(Joystick0DownRightKey)))
+ {
+ paddle1 += PaddleScale;
+ }
+ if (((Joystick1UpLeftKey > 0) && _keyboardService.IsKeyDown(Joystick1UpLeftKey)) ||
+ ((Joystick1LeftKey > 0) && _keyboardService.IsKeyDown(Joystick1LeftKey)) ||
+ ((Joystick1DownLeftKey > 0) && _keyboardService.IsKeyDown(Joystick1DownLeftKey)))
+ {
+ paddle2 -= PaddleScale;
+ }
+ if (((Joystick1UpRightKey > 0) && _keyboardService.IsKeyDown(Joystick1UpRightKey)) ||
+ ((Joystick1RightKey > 0) && _keyboardService.IsKeyDown(Joystick1RightKey)) ||
+ ((Joystick1DownRightKey > 0) && _keyboardService.IsKeyDown(Joystick1DownRightKey)))
+ {
+ paddle2 += PaddleScale;
+ }
+ if (((Joystick1UpLeftKey > 0) && _keyboardService.IsKeyDown(Joystick1UpLeftKey)) ||
+ ((Joystick1UpKey > 0) && _keyboardService.IsKeyDown(Joystick1UpKey)) ||
+ ((Joystick1UpRightKey > 0) && _keyboardService.IsKeyDown(Joystick1UpRightKey)))
+ {
+ paddle3 -= PaddleScale;
+ }
+ if (((Joystick1DownLeftKey > 0) && _keyboardService.IsKeyDown(Joystick1DownLeftKey)) ||
+ ((Joystick1DownKey > 0) && _keyboardService.IsKeyDown(Joystick1DownKey)) ||
+ ((Joystick1DownRightKey > 0) && _keyboardService.IsKeyDown(Joystick1DownRightKey)))
+ {
+ paddle3 += PaddleScale;
+ }
+ }
+ if (InvertPaddles)
+ {
+ paddle0 = 2 * PaddleScale - paddle0;
+ paddle1 = 2 * PaddleScale - paddle1;
+ paddle2 = 2 * PaddleScale - paddle2;
+ paddle3 = 2 * PaddleScale - paddle3;
+ }
+
+ Paddle0Strobe = true;
+ Paddle1Strobe = true;
+ Paddle2Strobe = true;
+ Paddle3Strobe = true;
+
+ Machine.Events.AddEvent(MathHelpers.ClampByte(SwapPaddles ? paddle1 : paddle0) * CyclesPerValue, _resetPaddle0StrobeEvent); // [7-29]
+ Machine.Events.AddEvent(MathHelpers.ClampByte(SwapPaddles ? paddle0 : paddle1) * CyclesPerValue, _resetPaddle1StrobeEvent);
+ Machine.Events.AddEvent(MathHelpers.ClampByte(SwapPaddles ? paddle3 : paddle2) * CyclesPerValue, _resetPaddle2StrobeEvent);
+ Machine.Events.AddEvent(MathHelpers.ClampByte(SwapPaddles ? paddle2 : paddle3) * CyclesPerValue, _resetPaddle3StrobeEvent);
+ }
+
+ private void ResetPaddle0StrobeEvent()
+ {
+ Paddle0Strobe = false;
+ }
+
+ private void ResetPaddle1StrobeEvent()
+ {
+ Paddle1Strobe = false;
+ }
+
+ private void ResetPaddle2StrobeEvent()
+ {
+ Paddle2Strobe = false;
+ }
+
+ private void ResetPaddle3StrobeEvent()
+ {
+ Paddle3Strobe = false;
+ }
+
+ public const int PaddleScale = 128;
+
+ public bool InvertPaddles { get; set; }
+ public bool SwapPaddles { get; set; }
+ public bool UseShiftKeyMod { get; set; }
+ public float JoystickDeadZone { get; set; }
+
+ public bool UseKeyboard { get; set; }
+ public int Joystick0UpLeftKey { get; set; }
+ public int Joystick0UpKey { get; set; }
+ public int Joystick0UpRightKey { get; set; }
+ public int Joystick0LeftKey { get; set; }
+ public int Joystick0RightKey { get; set; }
+ public int Joystick0DownLeftKey { get; set; }
+ public int Joystick0DownKey { get; set; }
+ public int Joystick0DownRightKey { get; set; }
+ public int Joystick1UpLeftKey { get; set; }
+ public int Joystick1UpKey { get; set; }
+ public int Joystick1UpRightKey { get; set; }
+ public int Joystick1LeftKey { get; set; }
+ public int Joystick1RightKey { get; set; }
+ public int Joystick1DownLeftKey { get; set; }
+ public int Joystick1DownKey { get; set; }
+ public int Joystick1DownRightKey { get; set; }
+ public int Button0Key { get; set; }
+ public int Button1Key { get; set; }
+ public int Button2Key { get; set; }
+
+ public bool UseTouch { get; set; }
+ public float Joystick0TouchX { get; set; }
+ public float Joystick0TouchY { get; set; }
+ public float Joystick0TouchWidth { get; set; }
+ public float Joystick0TouchHeight { get; set; }
+ public int Joystick0TouchOrder { get; set; }
+ public float Joystick0TouchRadius { get; set; }
+ public bool Joystick0TouchKeepLast { get; set; }
+ public float Joystick1TouchX { get; set; }
+ public float Joystick1TouchY { get; set; }
+ public float Joystick1TouchWidth { get; set; }
+ public float Joystick1TouchHeight { get; set; }
+ public int Joystick1TouchOrder { get; set; }
+ public float Joystick1TouchRadius { get; set; }
+ public bool Joystick1TouchKeepLast { get; set; }
+ public float Button0TouchX { get; set; }
+ public float Button0TouchY { get; set; }
+ public float Button0TouchWidth { get; set; }
+ public float Button0TouchHeight { get; set; }
+ public int Button0TouchOrder { get; set; }
+ public float Button1TouchX { get; set; }
+ public float Button1TouchY { get; set; }
+ public float Button1TouchWidth { get; set; }
+ public float Button1TouchHeight { get; set; }
+ public int Button1TouchOrder { get; set; }
+ public float Button2TouchX { get; set; }
+ public float Button2TouchY { get; set; }
+ public float Button2TouchWidth { get; set; }
+ public float Button2TouchHeight { get; set; }
+ public int Button2TouchOrder { get; set; }
+
+ 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/GlobalSuppressions.cs b/Virtu/GlobalSuppressions.cs
index 93c1eb8..0479618 100644
--- a/Virtu/GlobalSuppressions.cs
+++ b/Virtu/GlobalSuppressions.cs
@@ -1,3 +1,3 @@
-using System.Diagnostics.CodeAnalysis;
-
-[assembly: SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames")]
+using System.Diagnostics.CodeAnalysis;
+
+[assembly: SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames")]
diff --git a/Virtu/Jellyfish.Virtu.sln b/Virtu/Jellyfish.Virtu.sln
index ef948ce..c2bd2ed 100644
--- a/Virtu/Jellyfish.Virtu.sln
+++ b/Virtu/Jellyfish.Virtu.sln
@@ -1,38 +1,38 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2012
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Library.Silverlight", "..\Library\Silverlight\Jellyfish.Library.Silverlight.csproj", "{99CA7796-B72A-4F8C-BCDB-0D688220A331}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Library.Wpf", "..\Library\Wpf\Jellyfish.Library.Wpf.csproj", "{93900841-7250-4D3A-837E-43EE3FD118DC}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Virtu.Silverlight", "Silverlight\Jellyfish.Virtu.Silverlight.csproj", "{F8DB6D3A-807D-4E2D-92D5-469273E088DA}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Virtu.Wpf", "Wpf\Jellyfish.Virtu.Wpf.csproj", "{C152D47E-BBC1-4C35-8646-465180720A72}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {93900841-7250-4D3A-837E-43EE3FD118DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {93900841-7250-4D3A-837E-43EE3FD118DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {93900841-7250-4D3A-837E-43EE3FD118DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {93900841-7250-4D3A-837E-43EE3FD118DC}.Release|Any CPU.Build.0 = Release|Any CPU
- {99CA7796-B72A-4F8C-BCDB-0D688220A331}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {99CA7796-B72A-4F8C-BCDB-0D688220A331}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {99CA7796-B72A-4F8C-BCDB-0D688220A331}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {99CA7796-B72A-4F8C-BCDB-0D688220A331}.Release|Any CPU.Build.0 = Release|Any CPU
- {C152D47E-BBC1-4C35-8646-465180720A72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {C152D47E-BBC1-4C35-8646-465180720A72}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {C152D47E-BBC1-4C35-8646-465180720A72}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {C152D47E-BBC1-4C35-8646-465180720A72}.Release|Any CPU.Build.0 = Release|Any CPU
- {F8DB6D3A-807D-4E2D-92D5-469273E088DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {F8DB6D3A-807D-4E2D-92D5-469273E088DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {F8DB6D3A-807D-4E2D-92D5-469273E088DA}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {F8DB6D3A-807D-4E2D-92D5-469273E088DA}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Library.Silverlight", "..\Library\Silverlight\Jellyfish.Library.Silverlight.csproj", "{99CA7796-B72A-4F8C-BCDB-0D688220A331}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Library.Wpf", "..\Library\Wpf\Jellyfish.Library.Wpf.csproj", "{93900841-7250-4D3A-837E-43EE3FD118DC}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Virtu.Silverlight", "Silverlight\Jellyfish.Virtu.Silverlight.csproj", "{F8DB6D3A-807D-4E2D-92D5-469273E088DA}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Virtu.Wpf", "Wpf\Jellyfish.Virtu.Wpf.csproj", "{C152D47E-BBC1-4C35-8646-465180720A72}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {93900841-7250-4D3A-837E-43EE3FD118DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {93900841-7250-4D3A-837E-43EE3FD118DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {93900841-7250-4D3A-837E-43EE3FD118DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {93900841-7250-4D3A-837E-43EE3FD118DC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {99CA7796-B72A-4F8C-BCDB-0D688220A331}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {99CA7796-B72A-4F8C-BCDB-0D688220A331}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {99CA7796-B72A-4F8C-BCDB-0D688220A331}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {99CA7796-B72A-4F8C-BCDB-0D688220A331}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C152D47E-BBC1-4C35-8646-465180720A72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C152D47E-BBC1-4C35-8646-465180720A72}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C152D47E-BBC1-4C35-8646-465180720A72}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C152D47E-BBC1-4C35-8646-465180720A72}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F8DB6D3A-807D-4E2D-92D5-469273E088DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F8DB6D3A-807D-4E2D-92D5-469273E088DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F8DB6D3A-807D-4E2D-92D5-469273E088DA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F8DB6D3A-807D-4E2D-92D5-469273E088DA}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Virtu/Keyboard.cs b/Virtu/Keyboard.cs
index bee2f5c..b0f6ac4 100644
--- a/Virtu/Keyboard.cs
+++ b/Virtu/Keyboard.cs
@@ -1,120 +1,120 @@
-using System;
-using System.IO;
-using Jellyfish.Virtu.Services;
-
-namespace Jellyfish.Virtu
-{
- public sealed class Keyboard : MachineComponent
- {
- public Keyboard(Machine machine) :
- base(machine)
- {
- }
-
- public override void Initialize()
- {
- _keyboardService = Machine.Services.GetService();
-
- UseGamePort = true; // Raster Blaster
- Button2Key = ' ';
- }
-
- public override void LoadState(BinaryReader reader, Version version)
- {
- if (reader == null)
- {
- throw new ArgumentNullException("reader");
- }
-
- DisableResetKey = reader.ReadBoolean();
-
- UseGamePort = reader.ReadBoolean();
- Joystick0UpLeftKey = reader.ReadInt32();
- Joystick0UpKey = reader.ReadInt32();
- Joystick0UpRightKey = reader.ReadInt32();
- Joystick0LeftKey = reader.ReadInt32();
- Joystick0RightKey = reader.ReadInt32();
- Joystick0DownLeftKey = reader.ReadInt32();
- Joystick0DownKey = reader.ReadInt32();
- Joystick0DownRightKey = reader.ReadInt32();
- Joystick1UpLeftKey = reader.ReadInt32();
- Joystick1UpKey = reader.ReadInt32();
- Joystick1UpRightKey = reader.ReadInt32();
- Joystick1LeftKey = reader.ReadInt32();
- Joystick1RightKey = reader.ReadInt32();
- Joystick1DownLeftKey = reader.ReadInt32();
- Joystick1DownKey = reader.ReadInt32();
- Joystick1DownRightKey = reader.ReadInt32();
- Button0Key = reader.ReadInt32();
- Button1Key = reader.ReadInt32();
- Button2Key = reader.ReadInt32();
- }
-
- public override void SaveState(BinaryWriter writer)
- {
- if (writer == null)
- {
- throw new ArgumentNullException("writer");
- }
-
- writer.Write(DisableResetKey);
-
- writer.Write(UseGamePort);
- writer.Write(Joystick0UpLeftKey);
- writer.Write(Joystick0UpKey);
- writer.Write(Joystick0UpRightKey);
- writer.Write(Joystick0LeftKey);
- writer.Write(Joystick0RightKey);
- writer.Write(Joystick0DownLeftKey);
- writer.Write(Joystick0DownKey);
- writer.Write(Joystick0DownRightKey);
- writer.Write(Joystick1UpLeftKey);
- writer.Write(Joystick1UpKey);
- writer.Write(Joystick1UpRightKey);
- writer.Write(Joystick1LeftKey);
- writer.Write(Joystick1RightKey);
- writer.Write(Joystick1DownLeftKey);
- writer.Write(Joystick1DownKey);
- writer.Write(Joystick1DownRightKey);
- writer.Write(Button0Key);
- writer.Write(Button1Key);
- writer.Write(Button2Key);
- }
-
- public void ResetStrobe()
- {
- Strobe = false;
- }
-
- public bool DisableResetKey { get; set; }
-
- public bool UseGamePort { get; set; }
- public int Joystick0UpLeftKey { get; set; }
- public int Joystick0UpKey { get; set; }
- public int Joystick0UpRightKey { get; set; }
- public int Joystick0LeftKey { get; set; }
- public int Joystick0RightKey { get; set; }
- public int Joystick0DownLeftKey { get; set; }
- public int Joystick0DownKey { get; set; }
- public int Joystick0DownRightKey { get; set; }
- public int Joystick1UpLeftKey { get; set; }
- public int Joystick1UpKey { get; set; }
- public int Joystick1UpRightKey { get; set; }
- public int Joystick1LeftKey { get; set; }
- public int Joystick1RightKey { get; set; }
- public int Joystick1DownLeftKey { get; set; }
- public int Joystick1DownKey { get; set; }
- public int Joystick1DownRightKey { get; set; }
- public int Button0Key { get; set; }
- public int Button1Key { get; set; }
- public int Button2Key { get; set; }
-
- public bool IsAnyKeyDown { get { return _keyboardService.IsAnyKeyDown; } }
- public int Latch { get { return _latch; } set { _latch = value; Strobe = true; } }
- public bool Strobe { get; private set; }
-
- private KeyboardService _keyboardService;
-
- private int _latch;
- }
-}
+using System;
+using System.IO;
+using Jellyfish.Virtu.Services;
+
+namespace Jellyfish.Virtu
+{
+ public sealed class Keyboard : MachineComponent
+ {
+ public Keyboard(Machine machine) :
+ base(machine)
+ {
+ }
+
+ public override void Initialize()
+ {
+ _keyboardService = Machine.Services.GetService();
+
+ UseGamePort = true; // Raster Blaster
+ Button2Key = ' ';
+ }
+
+ public override void LoadState(BinaryReader reader, Version version)
+ {
+ if (reader == null)
+ {
+ throw new ArgumentNullException("reader");
+ }
+
+ DisableResetKey = reader.ReadBoolean();
+
+ UseGamePort = reader.ReadBoolean();
+ Joystick0UpLeftKey = reader.ReadInt32();
+ Joystick0UpKey = reader.ReadInt32();
+ Joystick0UpRightKey = reader.ReadInt32();
+ Joystick0LeftKey = reader.ReadInt32();
+ Joystick0RightKey = reader.ReadInt32();
+ Joystick0DownLeftKey = reader.ReadInt32();
+ Joystick0DownKey = reader.ReadInt32();
+ Joystick0DownRightKey = reader.ReadInt32();
+ Joystick1UpLeftKey = reader.ReadInt32();
+ Joystick1UpKey = reader.ReadInt32();
+ Joystick1UpRightKey = reader.ReadInt32();
+ Joystick1LeftKey = reader.ReadInt32();
+ Joystick1RightKey = reader.ReadInt32();
+ Joystick1DownLeftKey = reader.ReadInt32();
+ Joystick1DownKey = reader.ReadInt32();
+ Joystick1DownRightKey = reader.ReadInt32();
+ Button0Key = reader.ReadInt32();
+ Button1Key = reader.ReadInt32();
+ Button2Key = reader.ReadInt32();
+ }
+
+ public override void SaveState(BinaryWriter writer)
+ {
+ if (writer == null)
+ {
+ throw new ArgumentNullException("writer");
+ }
+
+ writer.Write(DisableResetKey);
+
+ writer.Write(UseGamePort);
+ writer.Write(Joystick0UpLeftKey);
+ writer.Write(Joystick0UpKey);
+ writer.Write(Joystick0UpRightKey);
+ writer.Write(Joystick0LeftKey);
+ writer.Write(Joystick0RightKey);
+ writer.Write(Joystick0DownLeftKey);
+ writer.Write(Joystick0DownKey);
+ writer.Write(Joystick0DownRightKey);
+ writer.Write(Joystick1UpLeftKey);
+ writer.Write(Joystick1UpKey);
+ writer.Write(Joystick1UpRightKey);
+ writer.Write(Joystick1LeftKey);
+ writer.Write(Joystick1RightKey);
+ writer.Write(Joystick1DownLeftKey);
+ writer.Write(Joystick1DownKey);
+ writer.Write(Joystick1DownRightKey);
+ writer.Write(Button0Key);
+ writer.Write(Button1Key);
+ writer.Write(Button2Key);
+ }
+
+ public void ResetStrobe()
+ {
+ Strobe = false;
+ }
+
+ public bool DisableResetKey { get; set; }
+
+ public bool UseGamePort { get; set; }
+ public int Joystick0UpLeftKey { get; set; }
+ public int Joystick0UpKey { get; set; }
+ public int Joystick0UpRightKey { get; set; }
+ public int Joystick0LeftKey { get; set; }
+ public int Joystick0RightKey { get; set; }
+ public int Joystick0DownLeftKey { get; set; }
+ public int Joystick0DownKey { get; set; }
+ public int Joystick0DownRightKey { get; set; }
+ public int Joystick1UpLeftKey { get; set; }
+ public int Joystick1UpKey { get; set; }
+ public int Joystick1UpRightKey { get; set; }
+ public int Joystick1LeftKey { get; set; }
+ public int Joystick1RightKey { get; set; }
+ public int Joystick1DownLeftKey { get; set; }
+ public int Joystick1DownKey { get; set; }
+ public int Joystick1DownRightKey { get; set; }
+ public int Button0Key { get; set; }
+ public int Button1Key { get; set; }
+ public int Button2Key { get; set; }
+
+ public bool IsAnyKeyDown { get { return _keyboardService.IsAnyKeyDown; } }
+ public int Latch { get { return _latch; } set { _latch = value; Strobe = true; } }
+ public bool Strobe { get; private set; }
+
+ private KeyboardService _keyboardService;
+
+ private int _latch;
+ }
+}
diff --git a/Virtu/Machine.cs b/Virtu/Machine.cs
index 0b66ad8..924c9cb 100644
--- a/Virtu/Machine.cs
+++ b/Virtu/Machine.cs
@@ -1,273 +1,273 @@
-using System;
-using System.Collections.ObjectModel;
-using System.Diagnostics.CodeAnalysis;
-using System.IO;
-using System.Linq;
-using System.Threading;
-using Jellyfish.Virtu.Services;
-
-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();
-
- Cpu = new Cpu(this);
- Memory = new Memory(this);
- Keyboard = new Keyboard(this);
- GamePort = new GamePort(this);
- Cassette = new Cassette(this);
- Speaker = new Speaker(this);
- Video = new Video(this);
- NoSlotClock = new NoSlotClock(this);
-
- var emptySlot = new PeripheralCard(this);
- Slot1 = emptySlot;
- Slot2 = emptySlot;
- Slot3 = emptySlot;
- Slot4 = emptySlot;
- Slot5 = emptySlot;
- Slot6 = new DiskIIController(this);
- Slot7 = emptySlot;
-
- Slots = new Collection { null, Slot1, Slot2, Slot3, Slot4, Slot5, Slot6, Slot7 };
- Components = new Collection { Cpu, Memory, Keyboard, GamePort, Cassette, Speaker, Video, NoSlotClock, Slot1, Slot2, Slot3, Slot4, Slot5, Slot6, Slot7 };
-
- BootDiskII = Slots.OfType().Last();
-
- Thread = new Thread(Run) { Name = "Machine" };
- }
-
- public void Dispose()
- {
- _pauseEvent.Close();
- _unpauseEvent.Close();
- }
-
- public void Reset()
- {
- foreach (var component in Components)
- {
- _debugService.WriteMessage("Resetting machine '{0}'", component.GetType().Name);
- component.Reset();
- //_debugService.WriteMessage("Reset machine '{0}'", component.GetType().Name);
- }
- }
-
- [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Jellyfish.Virtu.Services.DebugService.WriteMessage(System.String)")]
- public void Start()
- {
- _debugService = Services.GetService();
- _storageService = Services.GetService();
-
- _debugService.WriteMessage("Starting machine");
- State = MachineState.Starting;
- Thread.Start();
- }
-
- [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Jellyfish.Virtu.Services.DebugService.WriteMessage(System.String)")]
- public void Pause()
- {
- _debugService.WriteMessage("Pausing machine");
- State = MachineState.Pausing;
- _pauseEvent.WaitOne();
- State = MachineState.Paused;
- _debugService.WriteMessage("Paused machine");
- }
-
- [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Jellyfish.Virtu.Services.DebugService.WriteMessage(System.String)")]
- public void Unpause()
- {
- _debugService.WriteMessage("Running machine");
- State = MachineState.Running;
- _unpauseEvent.Set();
- }
-
- [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Jellyfish.Virtu.Services.DebugService.WriteMessage(System.String)")]
- public void Stop()
- {
- _debugService.WriteMessage("Stopping machine");
- State = MachineState.Stopping;
- _unpauseEvent.Set();
- if (Thread.IsAlive)
- {
- Thread.Join();
- }
- State = MachineState.Stopped;
- _debugService.WriteMessage("Stopped machine");
- }
-
- private void Initialize()
- {
- foreach (var component in Components)
- {
- _debugService.WriteMessage("Initializing machine '{0}'", component.GetType().Name);
- component.Initialize();
- //_debugService.WriteMessage("Initialized machine '{0}'", component.GetType().Name);
- }
- }
-
- private void LoadState()
- {
-#if WINDOWS
- var args = Environment.GetCommandLineArgs();
- if (args.Length > 1)
- {
- string name = args[1];
- Func, bool> loader = StorageService.LoadFile;
-
- if (name.StartsWith("res://", StringComparison.OrdinalIgnoreCase))
- {
- name = name.Substring(6);
- loader = StorageService.LoadResource;
- }
-
- if (name.EndsWith(".bin", StringComparison.OrdinalIgnoreCase))
- {
- loader(name, stream => LoadState(stream));
- }
- else if (name.EndsWith(".prg", StringComparison.OrdinalIgnoreCase))
- {
- loader(name, stream => Memory.LoadPrg(stream));
- }
- else if (name.EndsWith(".xex", StringComparison.OrdinalIgnoreCase))
- {
- loader(name, stream => Memory.LoadXex(stream));
- }
- else
- {
- loader(name, stream => BootDiskII.BootDrive.InsertDisk(name, stream, false));
- }
- }
- else
-#endif
- if (!_storageService.Load(Machine.StateFileName, stream => LoadState(stream)))
- {
- StorageService.LoadResource("Disks/Default.dsk", stream => BootDiskII.BootDrive.InsertDisk("Default.dsk", stream, false));
- }
- }
-
- private void LoadState(Stream stream)
- {
- using (var reader = new BinaryReader(stream))
- {
- string signature = reader.ReadString();
- var version = new Version(reader.ReadString());
- if ((signature != StateSignature) || (version != new Version(Machine.Version))) // avoid state version mismatch (for now)
- {
- throw new InvalidOperationException();
- }
- foreach (var component in Components)
- {
- _debugService.WriteMessage("Loading machine '{0}'", component.GetType().Name);
- component.LoadState(reader, version);
- //_debugService.WriteMessage("Loaded machine '{0}'", component.GetType().Name);
- }
- }
- }
-
- private void SaveState()
- {
- _storageService.Save(Machine.StateFileName, stream => SaveState(stream));
- }
-
- private void SaveState(Stream stream)
- {
- using (var writer = new BinaryWriter(stream))
- {
- writer.Write(StateSignature);
- writer.Write(Machine.Version);
- foreach (var component in Components)
- {
- _debugService.WriteMessage("Saving machine '{0}'", component.GetType().Name);
- component.SaveState(writer);
- //_debugService.WriteMessage("Saved machine '{0}'", component.GetType().Name);
- }
- }
- }
-
- private void Uninitialize()
- {
- foreach (var component in Components)
- {
- _debugService.WriteMessage("Uninitializing machine '{0}'", component.GetType().Name);
- component.Uninitialize();
- //_debugService.WriteMessage("Uninitialized machine '{0}'", component.GetType().Name);
- }
- }
-
- [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Jellyfish.Virtu.Services.DebugService.WriteMessage(System.String)")]
- private void Run() // machine thread
- {
- Initialize();
- Reset();
- LoadState();
-
- _debugService.WriteMessage("Running machine");
- 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);
-
- SaveState();
- Uninitialize();
- }
-
- public const string Version = "0.9.4.0";
-
- public MachineEvents Events { get; private set; }
- public MachineServices Services { get; private set; }
- public MachineState State { get { return _state; } private set { _state = value; } }
-
- public Cpu Cpu { get; private set; }
- public Memory Memory { 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 NoSlotClock NoSlotClock { get; private set; }
-
- public PeripheralCard Slot1 { get; private set; }
- public PeripheralCard Slot2 { get; private set; }
- public PeripheralCard Slot3 { get; private set; }
- public PeripheralCard Slot4 { get; private set; }
- public PeripheralCard Slot5 { get; private set; }
- public PeripheralCard Slot6 { get; private set; }
- public PeripheralCard Slot7 { get; private set; }
-
- public Collection Slots { get; private set; }
- public Collection Components { get; private set; }
-
- public DiskIIController BootDiskII { get; private set; }
-
- public Thread Thread { get; private set; }
-
- private const string StateFileName = "State.bin";
- private const string StateSignature = "Virtu";
-
- private DebugService _debugService;
- private StorageService _storageService;
- private volatile MachineState _state;
-
- private AutoResetEvent _pauseEvent = new AutoResetEvent(false);
- private AutoResetEvent _unpauseEvent = new AutoResetEvent(false);
- }
-}
+using System;
+using System.Collections.ObjectModel;
+using System.Diagnostics.CodeAnalysis;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using Jellyfish.Virtu.Services;
+
+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();
+
+ Cpu = new Cpu(this);
+ Memory = new Memory(this);
+ Keyboard = new Keyboard(this);
+ GamePort = new GamePort(this);
+ Cassette = new Cassette(this);
+ Speaker = new Speaker(this);
+ Video = new Video(this);
+ NoSlotClock = new NoSlotClock(this);
+
+ var emptySlot = new PeripheralCard(this);
+ Slot1 = emptySlot;
+ Slot2 = emptySlot;
+ Slot3 = emptySlot;
+ Slot4 = emptySlot;
+ Slot5 = emptySlot;
+ Slot6 = new DiskIIController(this);
+ Slot7 = emptySlot;
+
+ Slots = new Collection { null, Slot1, Slot2, Slot3, Slot4, Slot5, Slot6, Slot7 };
+ Components = new Collection { Cpu, Memory, Keyboard, GamePort, Cassette, Speaker, Video, NoSlotClock, Slot1, Slot2, Slot3, Slot4, Slot5, Slot6, Slot7 };
+
+ BootDiskII = Slots.OfType().Last();
+
+ Thread = new Thread(Run) { Name = "Machine" };
+ }
+
+ public void Dispose()
+ {
+ _pauseEvent.Close();
+ _unpauseEvent.Close();
+ }
+
+ public void Reset()
+ {
+ foreach (var component in Components)
+ {
+ _debugService.WriteMessage("Resetting machine '{0}'", component.GetType().Name);
+ component.Reset();
+ //_debugService.WriteMessage("Reset machine '{0}'", component.GetType().Name);
+ }
+ }
+
+ [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Jellyfish.Virtu.Services.DebugService.WriteMessage(System.String)")]
+ public void Start()
+ {
+ _debugService = Services.GetService();
+ _storageService = Services.GetService();
+
+ _debugService.WriteMessage("Starting machine");
+ State = MachineState.Starting;
+ Thread.Start();
+ }
+
+ [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Jellyfish.Virtu.Services.DebugService.WriteMessage(System.String)")]
+ public void Pause()
+ {
+ _debugService.WriteMessage("Pausing machine");
+ State = MachineState.Pausing;
+ _pauseEvent.WaitOne();
+ State = MachineState.Paused;
+ _debugService.WriteMessage("Paused machine");
+ }
+
+ [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Jellyfish.Virtu.Services.DebugService.WriteMessage(System.String)")]
+ public void Unpause()
+ {
+ _debugService.WriteMessage("Running machine");
+ State = MachineState.Running;
+ _unpauseEvent.Set();
+ }
+
+ [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Jellyfish.Virtu.Services.DebugService.WriteMessage(System.String)")]
+ public void Stop()
+ {
+ _debugService.WriteMessage("Stopping machine");
+ State = MachineState.Stopping;
+ _unpauseEvent.Set();
+ if (Thread.IsAlive)
+ {
+ Thread.Join();
+ }
+ State = MachineState.Stopped;
+ _debugService.WriteMessage("Stopped machine");
+ }
+
+ private void Initialize()
+ {
+ foreach (var component in Components)
+ {
+ _debugService.WriteMessage("Initializing machine '{0}'", component.GetType().Name);
+ component.Initialize();
+ //_debugService.WriteMessage("Initialized machine '{0}'", component.GetType().Name);
+ }
+ }
+
+ private void LoadState()
+ {
+#if WINDOWS
+ var args = Environment.GetCommandLineArgs();
+ if (args.Length > 1)
+ {
+ string name = args[1];
+ Func, bool> loader = StorageService.LoadFile;
+
+ if (name.StartsWith("res://", StringComparison.OrdinalIgnoreCase))
+ {
+ name = name.Substring(6);
+ loader = StorageService.LoadResource;
+ }
+
+ if (name.EndsWith(".bin", StringComparison.OrdinalIgnoreCase))
+ {
+ loader(name, stream => LoadState(stream));
+ }
+ else if (name.EndsWith(".prg", StringComparison.OrdinalIgnoreCase))
+ {
+ loader(name, stream => Memory.LoadPrg(stream));
+ }
+ else if (name.EndsWith(".xex", StringComparison.OrdinalIgnoreCase))
+ {
+ loader(name, stream => Memory.LoadXex(stream));
+ }
+ else
+ {
+ loader(name, stream => BootDiskII.BootDrive.InsertDisk(name, stream, false));
+ }
+ }
+ else
+#endif
+ if (!_storageService.Load(Machine.StateFileName, stream => LoadState(stream)))
+ {
+ StorageService.LoadResource("Disks/Default.dsk", stream => BootDiskII.BootDrive.InsertDisk("Default.dsk", stream, false));
+ }
+ }
+
+ private void LoadState(Stream stream)
+ {
+ using (var reader = new BinaryReader(stream))
+ {
+ string signature = reader.ReadString();
+ var version = new Version(reader.ReadString());
+ if ((signature != StateSignature) || (version != new Version(Machine.Version))) // avoid state version mismatch (for now)
+ {
+ throw new InvalidOperationException();
+ }
+ foreach (var component in Components)
+ {
+ _debugService.WriteMessage("Loading machine '{0}'", component.GetType().Name);
+ component.LoadState(reader, version);
+ //_debugService.WriteMessage("Loaded machine '{0}'", component.GetType().Name);
+ }
+ }
+ }
+
+ private void SaveState()
+ {
+ _storageService.Save(Machine.StateFileName, stream => SaveState(stream));
+ }
+
+ private void SaveState(Stream stream)
+ {
+ using (var writer = new BinaryWriter(stream))
+ {
+ writer.Write(StateSignature);
+ writer.Write(Machine.Version);
+ foreach (var component in Components)
+ {
+ _debugService.WriteMessage("Saving machine '{0}'", component.GetType().Name);
+ component.SaveState(writer);
+ //_debugService.WriteMessage("Saved machine '{0}'", component.GetType().Name);
+ }
+ }
+ }
+
+ private void Uninitialize()
+ {
+ foreach (var component in Components)
+ {
+ _debugService.WriteMessage("Uninitializing machine '{0}'", component.GetType().Name);
+ component.Uninitialize();
+ //_debugService.WriteMessage("Uninitialized machine '{0}'", component.GetType().Name);
+ }
+ }
+
+ [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Jellyfish.Virtu.Services.DebugService.WriteMessage(System.String)")]
+ private void Run() // machine thread
+ {
+ Initialize();
+ Reset();
+ LoadState();
+
+ _debugService.WriteMessage("Running machine");
+ 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);
+
+ SaveState();
+ Uninitialize();
+ }
+
+ public const string Version = "0.9.4.0";
+
+ public MachineEvents Events { get; private set; }
+ public MachineServices Services { get; private set; }
+ public MachineState State { get { return _state; } private set { _state = value; } }
+
+ public Cpu Cpu { get; private set; }
+ public Memory Memory { 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 NoSlotClock NoSlotClock { get; private set; }
+
+ public PeripheralCard Slot1 { get; private set; }
+ public PeripheralCard Slot2 { get; private set; }
+ public PeripheralCard Slot3 { get; private set; }
+ public PeripheralCard Slot4 { get; private set; }
+ public PeripheralCard Slot5 { get; private set; }
+ public PeripheralCard Slot6 { get; private set; }
+ public PeripheralCard Slot7 { get; private set; }
+
+ public Collection Slots { get; private set; }
+ public Collection Components { get; private set; }
+
+ public DiskIIController BootDiskII { get; private set; }
+
+ public Thread Thread { get; private set; }
+
+ private const string StateFileName = "State.bin";
+ private const string StateSignature = "Virtu";
+
+ private DebugService _debugService;
+ private StorageService _storageService;
+ private volatile MachineState _state;
+
+ private AutoResetEvent _pauseEvent = new AutoResetEvent(false);
+ private AutoResetEvent _unpauseEvent = new AutoResetEvent(false);
+ }
+}
diff --git a/Virtu/MachineComponent.cs b/Virtu/MachineComponent.cs
index 195b8ed..0d67f41 100644
--- a/Virtu/MachineComponent.cs
+++ b/Virtu/MachineComponent.cs
@@ -1,42 +1,42 @@
-using System;
-using System.IO;
-using Jellyfish.Library;
-using Jellyfish.Virtu.Services;
-
-namespace Jellyfish.Virtu
-{
- public abstract class MachineComponent
- {
- protected MachineComponent(Machine machine)
- {
- Machine = machine;
-
- _debugService = new Lazy(() => Machine.Services.GetService());
- }
-
- public virtual void Initialize()
- {
- }
-
- public virtual void Reset()
- {
- }
-
- public virtual void LoadState(BinaryReader reader, Version version)
- {
- }
-
- public virtual void Uninitialize()
- {
- }
-
- public virtual void SaveState(BinaryWriter writer)
- {
- }
-
- protected Machine Machine { get; private set; }
- protected DebugService DebugService { get { return _debugService.Value; } }
-
- private Lazy _debugService;
- }
-}
+using System;
+using System.IO;
+using Jellyfish.Library;
+using Jellyfish.Virtu.Services;
+
+namespace Jellyfish.Virtu
+{
+ public abstract class MachineComponent
+ {
+ protected MachineComponent(Machine machine)
+ {
+ Machine = machine;
+
+ _debugService = new Lazy(() => Machine.Services.GetService());
+ }
+
+ public virtual void Initialize()
+ {
+ }
+
+ public virtual void Reset()
+ {
+ }
+
+ public virtual void LoadState(BinaryReader reader, Version version)
+ {
+ }
+
+ public virtual void Uninitialize()
+ {
+ }
+
+ public virtual void SaveState(BinaryWriter writer)
+ {
+ }
+
+ protected Machine Machine { get; private set; }
+ protected DebugService DebugService { get { return _debugService.Value; } }
+
+ private Lazy _debugService;
+ }
+}
diff --git a/Virtu/MachineEvents.cs b/Virtu/MachineEvents.cs
index f008d04..6b87993 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.InvariantCulture, "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)
- {
- var 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;
- }
- }
-
- var 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 (var 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)
- {
- var 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.InvariantCulture, "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)
+ {
+ var 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;
+ }
+ }
+
+ var 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 (var 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)
+ {
+ var 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/Memory.cs b/Virtu/Memory.cs
index 683835f..85df58e 100644
--- a/Virtu/Memory.cs
+++ b/Virtu/Memory.cs
@@ -1,1738 +1,1738 @@
-using System;
-using System.Diagnostics.CodeAnalysis;
-using System.Globalization;
-using System.IO;
-using Jellyfish.Library;
-using Jellyfish.Virtu.Properties;
-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;
-
- _writeIoRegionC0C0 = WriteIoRegionC0C0; // cache delegates; avoids garbage
- _writeIoRegionC1C7 = WriteIoRegionC1C7;
- _writeIoRegionC3C3 = WriteIoRegionC3C3;
- _writeIoRegionC8CF = WriteIoRegionC8CF;
- _writeRomRegionD0FF = WriteRomRegionD0FF;
- }
-
- public override void Initialize()
- {
- _keyboard = Machine.Keyboard;
- _gamePort = Machine.GamePort;
- _cassette = Machine.Cassette;
- _speaker = Machine.Speaker;
- _video = Machine.Video;
- _noSlotClock = Machine.NoSlotClock;
-
- StorageService.LoadResource("Roms/AppleIIe.rom", stream =>
- {
- stream.SkipBlock(0x0100);
- stream.ReadBlock(_romInternalRegionC1CF);
- stream.ReadBlock(_romRegionD0DF);
- stream.ReadBlock(_romRegionE0FF);
- });
-
- if ((ReadRomRegionE0FF(0xFBB3) == 0x06) && (ReadRomRegionE0FF(0xFBBF) == 0xC1))
- {
- Monitor = MonitorType.Standard;
- }
- else if ((ReadRomRegionE0FF(0xFBB3) == 0x06) && (ReadRomRegionE0FF(0xFBBF) == 0x00) && (ReadRomRegionE0FF(0xFBC0) == 0xE0))
- {
- Monitor = MonitorType.Enhanced;
- }
- }
-
- public override void Reset() // [7-3]
- {
- ResetState(State80Col | State80Store | StateAltChrSet | StateAltZP | StateBank1 | StateHRamRd | StateHRamPreWrt | StateHRamWrt | // HRamWrt' [5-23]
- StateHires | StatePage2 | StateRamRd | StateRamWrt | StateIntCXRom | StateSlotC3Rom | StateIntC8Rom | StateAn0 | StateAn1 | StateAn2 | StateAn3);
- SetState(StateDRes); // An3' -> DRes [8-20]
-
- MapRegion0001();
- MapRegion02BF();
- MapRegionC0CF();
- MapRegionD0FF();
- }
-
- public override void LoadState(BinaryReader reader, Version version)
- {
- if (reader == null)
- {
- throw new ArgumentNullException("reader");
- }
-
- _state = reader.ReadInt32();
- _slotRegionC8CF = reader.ReadInt32();
-
- reader.Read(_ramMainRegion0001, 0, _ramMainRegion0001.Length);
- reader.Read(_ramMainRegion02BF, 0, _ramMainRegion02BF.Length);
- reader.Read(_ramMainBank1RegionD0DF, 0, _ramMainBank1RegionD0DF.Length);
- reader.Read(_ramMainBank2RegionD0DF, 0, _ramMainBank2RegionD0DF.Length);
- reader.Read(_ramMainRegionE0FF, 0, _ramMainRegionE0FF.Length);
- reader.Read(_ramAuxRegion0001, 0, _ramAuxRegion0001.Length);
- reader.Read(_ramAuxRegion02BF, 0, _ramAuxRegion02BF.Length);
- reader.Read(_ramAuxBank1RegionD0DF, 0, _ramAuxBank1RegionD0DF.Length);
- reader.Read(_ramAuxBank2RegionD0DF, 0, _ramAuxBank2RegionD0DF.Length);
- reader.Read(_ramAuxRegionE0FF, 0, _ramAuxRegionE0FF.Length);
-
- MapRegion0001();
- MapRegion02BF();
- MapRegionC0CF();
- MapRegionD0FF();
- }
-
- public override void SaveState(BinaryWriter writer)
- {
- if (writer == null)
- {
- throw new ArgumentNullException("writer");
- }
-
- writer.Write(_state);
- writer.Write(_slotRegionC8CF);
-
- writer.Write(_ramMainRegion0001);
- writer.Write(_ramMainRegion02BF);
- writer.Write(_ramMainBank1RegionD0DF);
- writer.Write(_ramMainBank2RegionD0DF);
- writer.Write(_ramMainRegionE0FF);
- writer.Write(_ramAuxRegion0001);
- writer.Write(_ramAuxRegion02BF);
- writer.Write(_ramAuxBank1RegionD0DF);
- writer.Write(_ramAuxBank2RegionD0DF);
- writer.Write(_ramAuxRegionE0FF);
- }
-
- public void LoadPrg(Stream stream)
- {
- if (stream == null)
- {
- throw new ArgumentNullException("stream");
- }
-
- int startAddress = stream.ReadWord();
- SetWarmEntry(startAddress); // assumes autostart monitor
- Load(stream, startAddress);
- }
-
- public void LoadXex(Stream stream)
- {
- if (stream == null)
- {
- throw new ArgumentNullException("stream");
- }
-
- const int Marker = 0xFFFF;
- int marker = stream.ReadWord(); // mandatory marker
- if (marker != Marker)
- {
- throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, Strings.MarkerNotFound, Marker));
- }
- int startAddress = stream.ReadWord();
- int endAddress = stream.ReadWord();
- SetWarmEntry(startAddress); // assumes autostart monitor
-
- do
- {
- if (startAddress > endAddress)
- {
- throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, Strings.InvalidAddressRange, startAddress, endAddress));
- }
- Load(stream, startAddress, endAddress - startAddress + 1);
- marker = stream.ReadWord(optional: true); // optional marker
- startAddress = (marker != Marker) ? marker : stream.ReadWord(optional: true);
- endAddress = stream.ReadWord(optional: true);
- }
- while ((startAddress >= 0) && (endAddress >= 0));
- }
-
- #region Core Read & Write
- public int Read(int address)
- {
- int region = PageRegion[address >> 8];
- return ((address & 0xF000) != 0xC000) ? _regionRead[region][address - RegionBaseAddress[region]] : ReadIoRegionC0CF(address);
- }
-
- 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
- private int ReadIoRegionC0CF(int address)
- {
- switch (address & 0xFF00)
- {
- case 0xC000:
- return ReadIoRegionC0C0(address);
-
- case 0xC100: case 0xC200: case 0xC400: case 0xC500: case 0xC600: case 0xC700:
- return ReadIoRegionC1C7(address);
-
- case 0xC300:
- return ReadIoRegionC3C3(address);
-
- case 0xC800: case 0xC900: case 0xCA00: case 0xCB00: case 0xCC00: case 0xCD00: case 0xCE00: case 0xCF00:
- return ReadIoRegionC8CF(address);
- }
-
- return _video.ReadFloatingBus();
- }
-
- [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
- [SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode")]
- private int ReadIoRegionC0C0(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.Latch, _keyboard.Strobe);
-
- case 0xC010:
- _keyboard.ResetStrobe();
- return SetBit7(_keyboard.Latch, _keyboard.IsAnyKeyDown);
-
- case 0xC011:
- return SetBit7(_keyboard.Latch, !IsHighRamBank1); // Bank1' [5-22]
-
- case 0xC012:
- return SetBit7(_keyboard.Latch, IsHighRamRead);
-
- case 0xC013:
- return SetBit7(_keyboard.Latch, IsRamReadAux);
-
- case 0xC014:
- return SetBit7(_keyboard.Latch, IsRamWriteAux);
-
- case 0xC015:
- return SetBit7(_keyboard.Latch, IsRomC1CFInternal);
-
- case 0xC016:
- return SetBit7(_keyboard.Latch, IsZeroPageAux);
-
- case 0xC017:
- return SetBit7(_keyboard.Latch, IsRomC3C3External);
-
- case 0xC018:
- return SetBit7(_keyboard.Latch, Is80Store);
-
- case 0xC019:
- return SetBit7(_keyboard.Latch, !_video.IsVBlank); // Vbl' [7-5]
-
- case 0xC01A:
- return SetBit7(_keyboard.Latch, IsText);
-
- case 0xC01B:
- return SetBit7(_keyboard.Latch, IsMixed);
-
- case 0xC01C:
- return SetBit7(_keyboard.Latch, IsPage2);
-
- case 0xC01D:
- return SetBit7(_keyboard.Latch, IsHires);
-
- case 0xC01E:
- return SetBit7(_keyboard.Latch, IsCharSetAlternate);
-
- case 0xC01F:
- return SetBit7(_keyboard.Latch, 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:
- return Machine.Slot1.ReadIoRegionC0C0(address);
-
- 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:
- return Machine.Slot2.ReadIoRegionC0C0(address);
-
- 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:
- return Machine.Slot3.ReadIoRegionC0C0(address);
-
- 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:
- return Machine.Slot4.ReadIoRegionC0C0(address);
-
- 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:
- return Machine.Slot5.ReadIoRegionC0C0(address);
-
- 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 Machine.Slot6.ReadIoRegionC0C0(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:
- return Machine.Slot7.ReadIoRegionC0C0(address);
-
- default:
- throw new ArgumentOutOfRangeException("address");
- }
-
- return _video.ReadFloatingBus();
- }
-
- private int ReadIoRegionC1C7(int address)
- {
- _slotRegionC8CF = (address >> 8) & 0x07;
- return IsRomC1CFInternal ? _romInternalRegionC1CF[address - 0xC100] : Machine.Slots[_slotRegionC8CF].ReadIoRegionC1C7(address);
- }
-
- private int ReadIoRegionC3C3(int address)
- {
- _slotRegionC8CF = 3;
- if (!IsRomC3C3External)
- {
- SetRomC8CF(true); // $C3XX sets IntC8Rom; inhibits I/O Strobe' [5-28, 7-21]
- }
- return (IsRomC1CFInternal || !IsRomC3C3External) ? _noSlotClock.Read(address, _romInternalRegionC1CF[address - 0xC100]) : Machine.Slot3.ReadIoRegionC1C7(address);
- }
-
- private int ReadIoRegionC8CF(int address)
- {
- if (address == 0xCFFF)
- {
- SetRomC8CF(false); // $CFFF resets IntC8Rom [5-28, 7-21]
- }
- return (IsRomC1CFInternal || IsRomC8CFInternal) ? _noSlotClock.Read(address, _romInternalRegionC1CF[address - 0xC100]) : Machine.Slots[_slotRegionC8CF].ReadIoRegionC8CF(address);
- }
-
- [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 WriteIoRegionC0C0(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:
- SetRomC1CF(TestBit(address, 0));
- break;
-
- case 0xC008: case 0xC009:
- SetZeroPage(TestBit(address, 0));
- break;
-
- case 0xC00A: case 0xC00B:
- SetRomC3C3(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:
- Machine.Slot1.WriteIoRegionC0C0(address, data);
- 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:
- Machine.Slot2.WriteIoRegionC0C0(address, data);
- 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:
- Machine.Slot3.WriteIoRegionC0C0(address, data);
- 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:
- Machine.Slot4.WriteIoRegionC0C0(address, data);
- 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:
- Machine.Slot5.WriteIoRegionC0C0(address, data);
- 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:
- Machine.Slot6.WriteIoRegionC0C0(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:
- Machine.Slot7.WriteIoRegionC0C0(address, data);
- break;
-
- default:
- throw new ArgumentOutOfRangeException("address");
- }
- }
-
- private void WriteIoRegionC1C7(int address, byte data)
- {
- _slotRegionC8CF = (address >> 8) & 0x07;
- if (!IsRomC1CFInternal)
- {
- Machine.Slots[_slotRegionC8CF].WriteIoRegionC1C7(address, data);
- }
- }
-
- private void WriteIoRegionC3C3(int address, byte data)
- {
- _slotRegionC8CF = 3;
- if (!IsRomC3C3External)
- {
- SetRomC8CF(true); // $C3XX sets IntC8Rom; inhibits I/O Strobe' [5-28, 7-21]
- }
- if (IsRomC1CFInternal || !IsRomC3C3External)
- {
- _noSlotClock.Write(address);
- }
- else
- {
- Machine.Slot3.WriteIoRegionC1C7(address, data);
- }
- }
-
- private void WriteIoRegionC8CF(int address, byte data)
- {
- if (address == 0xCFFF)
- {
- SetRomC8CF(false); // $CFFF resets IntC8Rom [5-28, 7-21]
- }
- if (IsRomC1CFInternal || IsRomC8CFInternal)
- {
- _noSlotClock.Write(address);
- }
- else
- {
- Machine.Slots[_slotRegionC8CF].WriteIoRegionC8CF(address, data);
- }
- }
-
- 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 WriteRomRegionD0FF(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 (IsRomC1CFInternal)
- {
- _regionRead[RegionC1C7] = _romInternalRegionC1CF;
- _regionRead[RegionC3C3] = _romInternalRegionC1CF;
- _regionRead[RegionC8CF] = _romInternalRegionC1CF;
- }
- else
- {
- _regionRead[RegionC1C7] = _romExternalRegionC1CF;
- _regionRead[RegionC3C3] = IsRomC3C3External ? _romExternalRegionC1CF : _romInternalRegionC1CF;
- _regionRead[RegionC8CF] = !IsRomC8CFInternal ? _romExternalRegionC1CF : _romInternalRegionC1CF;
- }
- _regionWrite[RegionC0C0] = null;
- _regionWrite[RegionC1C7] = null;
- _regionWrite[RegionC3C3] = null;
- _regionWrite[RegionC8CF] = null;
- _writeRegion[RegionC0C0] = _writeIoRegionC0C0;
- _writeRegion[RegionC1C7] = _writeIoRegionC1C7;
- _writeRegion[RegionC3C3] = _writeIoRegionC3C3;
- _writeRegion[RegionC8CF] = _writeIoRegionC8CF;
- }
-
- 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] = _writeRomRegionD0FF;
- _writeRegion[RegionE0FF] = _writeRomRegionD0FF;
- }
- }
-
- 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 SetRomC1CF(bool value)
- {
- if (!TestState(StateIntCXRom, value))
- {
- SetState(StateIntCXRom, value);
- MapRegionC0CF();
- }
- }
-
- private void SetRomC3C3(bool value)
- {
- if (!TestState(StateSlotC3Rom, value))
- {
- SetState(StateSlotC3Rom, value);
- MapRegionC0CF();
- }
- }
-
- private void SetRomC8CF(bool value)
- {
- if (!TestState(StateIntC8Rom, value))
- {
- SetState(StateIntC8Rom, 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 void Load(Stream stream, int startAddress)
- {
- DebugService.WriteMessage("Loading memory ${0:X04}", startAddress);
- int address = startAddress;
- if (address < 0x0200)
- {
- address += stream.ReadBlock(_ramMainRegion0001, address, minCount: 0);
- }
- if ((0x0200 <= address) && (address < 0xC000))
- {
- address += stream.ReadBlock(_ramMainRegion02BF, address - 0x0200, minCount: 0);
- }
- if ((0xC000 <= address) && (address < 0xD000))
- {
- address += stream.ReadBlock(_ramMainBank1RegionD0DF, address - 0xC000, minCount: 0);
- }
- if ((0xD000 <= address) && (address < 0xE000))
- {
- address += stream.ReadBlock(_ramMainBank2RegionD0DF, address - 0xD000, minCount: 0);
- }
- if (0xE000 <= address)
- {
- address += stream.ReadBlock(_ramMainRegionE0FF, address - 0xE000, minCount: 0);
- }
- if (address > startAddress)
- {
- DebugService.WriteMessage("Loaded memory ${0:X04}-${1:X04} (${2:X04})", startAddress, address - 1, address - startAddress);
- }
- }
-
- private void Load(Stream stream, int startAddress, int length)
- {
- DebugService.WriteMessage("Loading memory ${0:X04}-${1:X04} (${2:X04})", startAddress, startAddress + length - 1, length);
- int address = startAddress;
- if (address < 0x0200)
- {
- address += stream.ReadBlock(_ramMainRegion0001, address, ref length);
- }
- if ((0x0200 <= address) && (address < 0xC000))
- {
- address += stream.ReadBlock(_ramMainRegion02BF, address - 0x0200, ref length);
- }
- if ((0xC000 <= address) && (address < 0xD000))
- {
- address += stream.ReadBlock(_ramMainBank1RegionD0DF, address - 0xC000, ref length);
- }
- if ((0xD000 <= address) && (address < 0xE000))
- {
- address += stream.ReadBlock(_ramMainBank2RegionD0DF, address - 0xD000, ref length);
- }
- if (0xE000 <= address)
- {
- address += stream.ReadBlock(_ramMainRegionE0FF, address - 0xE000, ref length);
- }
- }
-
- private void SetWarmEntry(int address)
- {
- _ramMainRegion02BF[0x03F2 - 0x0200] = (byte)(address & 0xFF);
- _ramMainRegion02BF[0x03F3 - 0x0200] = (byte)(address >> 8);
- _ramMainRegion02BF[0x03F4 - 0x0200] = (byte)((address >> 8) ^ 0xA5);
- }
-
- 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 IsRomC1CFInternal { get { return TestState(StateIntCXRom); } }
- public bool IsRomC3C3External { get { return TestState(StateSlotC3Rom); } }
- public bool IsRomC8CFInternal { get { return TestState(StateIntC8Rom); } }
- 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 Action _writeIoRegionC0C0;
- private Action _writeIoRegionC1C7;
- private Action _writeIoRegionC3C3;
- private Action _writeIoRegionC8CF;
- private Action _writeRomRegionD0FF;
-
- private Keyboard _keyboard;
- private GamePort _gamePort;
- private Cassette _cassette;
- private Speaker _speaker;
- private Video _video;
- private NoSlotClock _noSlotClock;
-
- private int _state;
- private int _slotRegionC8CF;
-
- private byte[] _zeroPage;
- private byte[][] _regionRead = new byte[RegionCount][];
- private byte[][] _regionWrite = new byte[RegionCount][];
- private Action[] _writeRegion = new Action[RegionCount];
-
- private byte[] _ramMainRegion0001 = new byte[0x0200];
- private byte[] _ramMainRegion02BF = new byte[0xBE00];
- private byte[] _ramMainBank1RegionD0DF = new byte[0x1000];
- private byte[] _ramMainBank2RegionD0DF = new byte[0x1000];
- private byte[] _ramMainRegionE0FF = new byte[0x2000];
- private byte[] _ramAuxRegion0001 = new byte[0x0200];
- private byte[] _ramAuxRegion02BF = new byte[0xBE00];
- private byte[] _ramAuxBank1RegionD0DF = new byte[0x1000];
- private byte[] _ramAuxBank2RegionD0DF = new byte[0x1000];
- private byte[] _ramAuxRegionE0FF = new byte[0x2000];
-
- private byte[] _romExternalRegionC1CF = new byte[0x0F00];
- private byte[] _romInternalRegionC1CF = new byte[0x0F00];
- private byte[] _romRegionD0DF = new byte[0x1000];
- private byte[] _romRegionE0FF = new byte[0x2000];
- }
-}
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using System.IO;
+using Jellyfish.Library;
+using Jellyfish.Virtu.Properties;
+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;
+
+ _writeIoRegionC0C0 = WriteIoRegionC0C0; // cache delegates; avoids garbage
+ _writeIoRegionC1C7 = WriteIoRegionC1C7;
+ _writeIoRegionC3C3 = WriteIoRegionC3C3;
+ _writeIoRegionC8CF = WriteIoRegionC8CF;
+ _writeRomRegionD0FF = WriteRomRegionD0FF;
+ }
+
+ public override void Initialize()
+ {
+ _keyboard = Machine.Keyboard;
+ _gamePort = Machine.GamePort;
+ _cassette = Machine.Cassette;
+ _speaker = Machine.Speaker;
+ _video = Machine.Video;
+ _noSlotClock = Machine.NoSlotClock;
+
+ StorageService.LoadResource("Roms/AppleIIe.rom", stream =>
+ {
+ stream.SkipBlock(0x0100);
+ stream.ReadBlock(_romInternalRegionC1CF);
+ stream.ReadBlock(_romRegionD0DF);
+ stream.ReadBlock(_romRegionE0FF);
+ });
+
+ if ((ReadRomRegionE0FF(0xFBB3) == 0x06) && (ReadRomRegionE0FF(0xFBBF) == 0xC1))
+ {
+ Monitor = MonitorType.Standard;
+ }
+ else if ((ReadRomRegionE0FF(0xFBB3) == 0x06) && (ReadRomRegionE0FF(0xFBBF) == 0x00) && (ReadRomRegionE0FF(0xFBC0) == 0xE0))
+ {
+ Monitor = MonitorType.Enhanced;
+ }
+ }
+
+ public override void Reset() // [7-3]
+ {
+ ResetState(State80Col | State80Store | StateAltChrSet | StateAltZP | StateBank1 | StateHRamRd | StateHRamPreWrt | StateHRamWrt | // HRamWrt' [5-23]
+ StateHires | StatePage2 | StateRamRd | StateRamWrt | StateIntCXRom | StateSlotC3Rom | StateIntC8Rom | StateAn0 | StateAn1 | StateAn2 | StateAn3);
+ SetState(StateDRes); // An3' -> DRes [8-20]
+
+ MapRegion0001();
+ MapRegion02BF();
+ MapRegionC0CF();
+ MapRegionD0FF();
+ }
+
+ public override void LoadState(BinaryReader reader, Version version)
+ {
+ if (reader == null)
+ {
+ throw new ArgumentNullException("reader");
+ }
+
+ _state = reader.ReadInt32();
+ _slotRegionC8CF = reader.ReadInt32();
+
+ reader.Read(_ramMainRegion0001, 0, _ramMainRegion0001.Length);
+ reader.Read(_ramMainRegion02BF, 0, _ramMainRegion02BF.Length);
+ reader.Read(_ramMainBank1RegionD0DF, 0, _ramMainBank1RegionD0DF.Length);
+ reader.Read(_ramMainBank2RegionD0DF, 0, _ramMainBank2RegionD0DF.Length);
+ reader.Read(_ramMainRegionE0FF, 0, _ramMainRegionE0FF.Length);
+ reader.Read(_ramAuxRegion0001, 0, _ramAuxRegion0001.Length);
+ reader.Read(_ramAuxRegion02BF, 0, _ramAuxRegion02BF.Length);
+ reader.Read(_ramAuxBank1RegionD0DF, 0, _ramAuxBank1RegionD0DF.Length);
+ reader.Read(_ramAuxBank2RegionD0DF, 0, _ramAuxBank2RegionD0DF.Length);
+ reader.Read(_ramAuxRegionE0FF, 0, _ramAuxRegionE0FF.Length);
+
+ MapRegion0001();
+ MapRegion02BF();
+ MapRegionC0CF();
+ MapRegionD0FF();
+ }
+
+ public override void SaveState(BinaryWriter writer)
+ {
+ if (writer == null)
+ {
+ throw new ArgumentNullException("writer");
+ }
+
+ writer.Write(_state);
+ writer.Write(_slotRegionC8CF);
+
+ writer.Write(_ramMainRegion0001);
+ writer.Write(_ramMainRegion02BF);
+ writer.Write(_ramMainBank1RegionD0DF);
+ writer.Write(_ramMainBank2RegionD0DF);
+ writer.Write(_ramMainRegionE0FF);
+ writer.Write(_ramAuxRegion0001);
+ writer.Write(_ramAuxRegion02BF);
+ writer.Write(_ramAuxBank1RegionD0DF);
+ writer.Write(_ramAuxBank2RegionD0DF);
+ writer.Write(_ramAuxRegionE0FF);
+ }
+
+ public void LoadPrg(Stream stream)
+ {
+ if (stream == null)
+ {
+ throw new ArgumentNullException("stream");
+ }
+
+ int startAddress = stream.ReadWord();
+ SetWarmEntry(startAddress); // assumes autostart monitor
+ Load(stream, startAddress);
+ }
+
+ public void LoadXex(Stream stream)
+ {
+ if (stream == null)
+ {
+ throw new ArgumentNullException("stream");
+ }
+
+ const int Marker = 0xFFFF;
+ int marker = stream.ReadWord(); // mandatory marker
+ if (marker != Marker)
+ {
+ throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, Strings.MarkerNotFound, Marker));
+ }
+ int startAddress = stream.ReadWord();
+ int endAddress = stream.ReadWord();
+ SetWarmEntry(startAddress); // assumes autostart monitor
+
+ do
+ {
+ if (startAddress > endAddress)
+ {
+ throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, Strings.InvalidAddressRange, startAddress, endAddress));
+ }
+ Load(stream, startAddress, endAddress - startAddress + 1);
+ marker = stream.ReadWord(optional: true); // optional marker
+ startAddress = (marker != Marker) ? marker : stream.ReadWord(optional: true);
+ endAddress = stream.ReadWord(optional: true);
+ }
+ while ((startAddress >= 0) && (endAddress >= 0));
+ }
+
+ #region Core Read & Write
+ public int Read(int address)
+ {
+ int region = PageRegion[address >> 8];
+ return ((address & 0xF000) != 0xC000) ? _regionRead[region][address - RegionBaseAddress[region]] : ReadIoRegionC0CF(address);
+ }
+
+ 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
+ private int ReadIoRegionC0CF(int address)
+ {
+ switch (address & 0xFF00)
+ {
+ case 0xC000:
+ return ReadIoRegionC0C0(address);
+
+ case 0xC100: case 0xC200: case 0xC400: case 0xC500: case 0xC600: case 0xC700:
+ return ReadIoRegionC1C7(address);
+
+ case 0xC300:
+ return ReadIoRegionC3C3(address);
+
+ case 0xC800: case 0xC900: case 0xCA00: case 0xCB00: case 0xCC00: case 0xCD00: case 0xCE00: case 0xCF00:
+ return ReadIoRegionC8CF(address);
+ }
+
+ return _video.ReadFloatingBus();
+ }
+
+ [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
+ [SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode")]
+ private int ReadIoRegionC0C0(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.Latch, _keyboard.Strobe);
+
+ case 0xC010:
+ _keyboard.ResetStrobe();
+ return SetBit7(_keyboard.Latch, _keyboard.IsAnyKeyDown);
+
+ case 0xC011:
+ return SetBit7(_keyboard.Latch, !IsHighRamBank1); // Bank1' [5-22]
+
+ case 0xC012:
+ return SetBit7(_keyboard.Latch, IsHighRamRead);
+
+ case 0xC013:
+ return SetBit7(_keyboard.Latch, IsRamReadAux);
+
+ case 0xC014:
+ return SetBit7(_keyboard.Latch, IsRamWriteAux);
+
+ case 0xC015:
+ return SetBit7(_keyboard.Latch, IsRomC1CFInternal);
+
+ case 0xC016:
+ return SetBit7(_keyboard.Latch, IsZeroPageAux);
+
+ case 0xC017:
+ return SetBit7(_keyboard.Latch, IsRomC3C3External);
+
+ case 0xC018:
+ return SetBit7(_keyboard.Latch, Is80Store);
+
+ case 0xC019:
+ return SetBit7(_keyboard.Latch, !_video.IsVBlank); // Vbl' [7-5]
+
+ case 0xC01A:
+ return SetBit7(_keyboard.Latch, IsText);
+
+ case 0xC01B:
+ return SetBit7(_keyboard.Latch, IsMixed);
+
+ case 0xC01C:
+ return SetBit7(_keyboard.Latch, IsPage2);
+
+ case 0xC01D:
+ return SetBit7(_keyboard.Latch, IsHires);
+
+ case 0xC01E:
+ return SetBit7(_keyboard.Latch, IsCharSetAlternate);
+
+ case 0xC01F:
+ return SetBit7(_keyboard.Latch, 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:
+ return Machine.Slot1.ReadIoRegionC0C0(address);
+
+ 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:
+ return Machine.Slot2.ReadIoRegionC0C0(address);
+
+ 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:
+ return Machine.Slot3.ReadIoRegionC0C0(address);
+
+ 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:
+ return Machine.Slot4.ReadIoRegionC0C0(address);
+
+ 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:
+ return Machine.Slot5.ReadIoRegionC0C0(address);
+
+ 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 Machine.Slot6.ReadIoRegionC0C0(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:
+ return Machine.Slot7.ReadIoRegionC0C0(address);
+
+ default:
+ throw new ArgumentOutOfRangeException("address");
+ }
+
+ return _video.ReadFloatingBus();
+ }
+
+ private int ReadIoRegionC1C7(int address)
+ {
+ _slotRegionC8CF = (address >> 8) & 0x07;
+ return IsRomC1CFInternal ? _romInternalRegionC1CF[address - 0xC100] : Machine.Slots[_slotRegionC8CF].ReadIoRegionC1C7(address);
+ }
+
+ private int ReadIoRegionC3C3(int address)
+ {
+ _slotRegionC8CF = 3;
+ if (!IsRomC3C3External)
+ {
+ SetRomC8CF(true); // $C3XX sets IntC8Rom; inhibits I/O Strobe' [5-28, 7-21]
+ }
+ return (IsRomC1CFInternal || !IsRomC3C3External) ? _noSlotClock.Read(address, _romInternalRegionC1CF[address - 0xC100]) : Machine.Slot3.ReadIoRegionC1C7(address);
+ }
+
+ private int ReadIoRegionC8CF(int address)
+ {
+ if (address == 0xCFFF)
+ {
+ SetRomC8CF(false); // $CFFF resets IntC8Rom [5-28, 7-21]
+ }
+ return (IsRomC1CFInternal || IsRomC8CFInternal) ? _noSlotClock.Read(address, _romInternalRegionC1CF[address - 0xC100]) : Machine.Slots[_slotRegionC8CF].ReadIoRegionC8CF(address);
+ }
+
+ [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 WriteIoRegionC0C0(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:
+ SetRomC1CF(TestBit(address, 0));
+ break;
+
+ case 0xC008: case 0xC009:
+ SetZeroPage(TestBit(address, 0));
+ break;
+
+ case 0xC00A: case 0xC00B:
+ SetRomC3C3(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:
+ Machine.Slot1.WriteIoRegionC0C0(address, data);
+ 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:
+ Machine.Slot2.WriteIoRegionC0C0(address, data);
+ 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:
+ Machine.Slot3.WriteIoRegionC0C0(address, data);
+ 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:
+ Machine.Slot4.WriteIoRegionC0C0(address, data);
+ 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:
+ Machine.Slot5.WriteIoRegionC0C0(address, data);
+ 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:
+ Machine.Slot6.WriteIoRegionC0C0(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:
+ Machine.Slot7.WriteIoRegionC0C0(address, data);
+ break;
+
+ default:
+ throw new ArgumentOutOfRangeException("address");
+ }
+ }
+
+ private void WriteIoRegionC1C7(int address, byte data)
+ {
+ _slotRegionC8CF = (address >> 8) & 0x07;
+ if (!IsRomC1CFInternal)
+ {
+ Machine.Slots[_slotRegionC8CF].WriteIoRegionC1C7(address, data);
+ }
+ }
+
+ private void WriteIoRegionC3C3(int address, byte data)
+ {
+ _slotRegionC8CF = 3;
+ if (!IsRomC3C3External)
+ {
+ SetRomC8CF(true); // $C3XX sets IntC8Rom; inhibits I/O Strobe' [5-28, 7-21]
+ }
+ if (IsRomC1CFInternal || !IsRomC3C3External)
+ {
+ _noSlotClock.Write(address);
+ }
+ else
+ {
+ Machine.Slot3.WriteIoRegionC1C7(address, data);
+ }
+ }
+
+ private void WriteIoRegionC8CF(int address, byte data)
+ {
+ if (address == 0xCFFF)
+ {
+ SetRomC8CF(false); // $CFFF resets IntC8Rom [5-28, 7-21]
+ }
+ if (IsRomC1CFInternal || IsRomC8CFInternal)
+ {
+ _noSlotClock.Write(address);
+ }
+ else
+ {
+ Machine.Slots[_slotRegionC8CF].WriteIoRegionC8CF(address, data);
+ }
+ }
+
+ 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 WriteRomRegionD0FF(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 (IsRomC1CFInternal)
+ {
+ _regionRead[RegionC1C7] = _romInternalRegionC1CF;
+ _regionRead[RegionC3C3] = _romInternalRegionC1CF;
+ _regionRead[RegionC8CF] = _romInternalRegionC1CF;
+ }
+ else
+ {
+ _regionRead[RegionC1C7] = _romExternalRegionC1CF;
+ _regionRead[RegionC3C3] = IsRomC3C3External ? _romExternalRegionC1CF : _romInternalRegionC1CF;
+ _regionRead[RegionC8CF] = !IsRomC8CFInternal ? _romExternalRegionC1CF : _romInternalRegionC1CF;
+ }
+ _regionWrite[RegionC0C0] = null;
+ _regionWrite[RegionC1C7] = null;
+ _regionWrite[RegionC3C3] = null;
+ _regionWrite[RegionC8CF] = null;
+ _writeRegion[RegionC0C0] = _writeIoRegionC0C0;
+ _writeRegion[RegionC1C7] = _writeIoRegionC1C7;
+ _writeRegion[RegionC3C3] = _writeIoRegionC3C3;
+ _writeRegion[RegionC8CF] = _writeIoRegionC8CF;
+ }
+
+ 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] = _writeRomRegionD0FF;
+ _writeRegion[RegionE0FF] = _writeRomRegionD0FF;
+ }
+ }
+
+ 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 SetRomC1CF(bool value)
+ {
+ if (!TestState(StateIntCXRom, value))
+ {
+ SetState(StateIntCXRom, value);
+ MapRegionC0CF();
+ }
+ }
+
+ private void SetRomC3C3(bool value)
+ {
+ if (!TestState(StateSlotC3Rom, value))
+ {
+ SetState(StateSlotC3Rom, value);
+ MapRegionC0CF();
+ }
+ }
+
+ private void SetRomC8CF(bool value)
+ {
+ if (!TestState(StateIntC8Rom, value))
+ {
+ SetState(StateIntC8Rom, 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 void Load(Stream stream, int startAddress)
+ {
+ DebugService.WriteMessage("Loading memory ${0:X04}", startAddress);
+ int address = startAddress;
+ if (address < 0x0200)
+ {
+ address += stream.ReadBlock(_ramMainRegion0001, address, minCount: 0);
+ }
+ if ((0x0200 <= address) && (address < 0xC000))
+ {
+ address += stream.ReadBlock(_ramMainRegion02BF, address - 0x0200, minCount: 0);
+ }
+ if ((0xC000 <= address) && (address < 0xD000))
+ {
+ address += stream.ReadBlock(_ramMainBank1RegionD0DF, address - 0xC000, minCount: 0);
+ }
+ if ((0xD000 <= address) && (address < 0xE000))
+ {
+ address += stream.ReadBlock(_ramMainBank2RegionD0DF, address - 0xD000, minCount: 0);
+ }
+ if (0xE000 <= address)
+ {
+ address += stream.ReadBlock(_ramMainRegionE0FF, address - 0xE000, minCount: 0);
+ }
+ if (address > startAddress)
+ {
+ DebugService.WriteMessage("Loaded memory ${0:X04}-${1:X04} (${2:X04})", startAddress, address - 1, address - startAddress);
+ }
+ }
+
+ private void Load(Stream stream, int startAddress, int length)
+ {
+ DebugService.WriteMessage("Loading memory ${0:X04}-${1:X04} (${2:X04})", startAddress, startAddress + length - 1, length);
+ int address = startAddress;
+ if (address < 0x0200)
+ {
+ address += stream.ReadBlock(_ramMainRegion0001, address, ref length);
+ }
+ if ((0x0200 <= address) && (address < 0xC000))
+ {
+ address += stream.ReadBlock(_ramMainRegion02BF, address - 0x0200, ref length);
+ }
+ if ((0xC000 <= address) && (address < 0xD000))
+ {
+ address += stream.ReadBlock(_ramMainBank1RegionD0DF, address - 0xC000, ref length);
+ }
+ if ((0xD000 <= address) && (address < 0xE000))
+ {
+ address += stream.ReadBlock(_ramMainBank2RegionD0DF, address - 0xD000, ref length);
+ }
+ if (0xE000 <= address)
+ {
+ address += stream.ReadBlock(_ramMainRegionE0FF, address - 0xE000, ref length);
+ }
+ }
+
+ private void SetWarmEntry(int address)
+ {
+ _ramMainRegion02BF[0x03F2 - 0x0200] = (byte)(address & 0xFF);
+ _ramMainRegion02BF[0x03F3 - 0x0200] = (byte)(address >> 8);
+ _ramMainRegion02BF[0x03F4 - 0x0200] = (byte)((address >> 8) ^ 0xA5);
+ }
+
+ 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 IsRomC1CFInternal { get { return TestState(StateIntCXRom); } }
+ public bool IsRomC3C3External { get { return TestState(StateSlotC3Rom); } }
+ public bool IsRomC8CFInternal { get { return TestState(StateIntC8Rom); } }
+ 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 Action _writeIoRegionC0C0;
+ private Action _writeIoRegionC1C7;
+ private Action _writeIoRegionC3C3;
+ private Action _writeIoRegionC8CF;
+ private Action _writeRomRegionD0FF;
+
+ private Keyboard _keyboard;
+ private GamePort _gamePort;
+ private Cassette _cassette;
+ private Speaker _speaker;
+ private Video _video;
+ private NoSlotClock _noSlotClock;
+
+ private int _state;
+ private int _slotRegionC8CF;
+
+ private byte[] _zeroPage;
+ private byte[][] _regionRead = new byte[RegionCount][];
+ private byte[][] _regionWrite = new byte[RegionCount][];
+ private Action[] _writeRegion = new Action[RegionCount];
+
+ private byte[] _ramMainRegion0001 = new byte[0x0200];
+ private byte[] _ramMainRegion02BF = new byte[0xBE00];
+ private byte[] _ramMainBank1RegionD0DF = new byte[0x1000];
+ private byte[] _ramMainBank2RegionD0DF = new byte[0x1000];
+ private byte[] _ramMainRegionE0FF = new byte[0x2000];
+ private byte[] _ramAuxRegion0001 = new byte[0x0200];
+ private byte[] _ramAuxRegion02BF = new byte[0xBE00];
+ private byte[] _ramAuxBank1RegionD0DF = new byte[0x1000];
+ private byte[] _ramAuxBank2RegionD0DF = new byte[0x1000];
+ private byte[] _ramAuxRegionE0FF = new byte[0x2000];
+
+ private byte[] _romExternalRegionC1CF = new byte[0x0F00];
+ private byte[] _romInternalRegionC1CF = new byte[0x0F00];
+ private byte[] _romRegionD0DF = new byte[0x1000];
+ private byte[] _romRegionE0FF = new byte[0x2000];
+ }
+}
diff --git a/Virtu/MemoryData.cs b/Virtu/MemoryData.cs
index e2e9bfa..b3697ec 100644
--- a/Virtu/MemoryData.cs
+++ b/Virtu/MemoryData.cs
@@ -1,106 +1,106 @@
-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 StateIntC8Rom = 0x010000; // [5-28]
- private const int StateIntCXRom = 0x020000;
- private const int StateAn0 = 0x040000;
- private const int StateAn1 = 0x080000;
- private const int StateAn2 = 0x100000;
- private const int StateAn3 = 0x200000;
- 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 StateIntC8Rom = 0x010000; // [5-28]
+ private const int StateIntCXRom = 0x020000;
+ private const int StateAn0 = 0x040000;
+ private const int StateAn1 = 0x080000;
+ private const int StateAn2 = 0x100000;
+ private const int StateAn3 = 0x200000;
+ 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/NoSlotClock.cs b/Virtu/NoSlotClock.cs
index 9ff1292..6e0a298 100644
--- a/Virtu/NoSlotClock.cs
+++ b/Virtu/NoSlotClock.cs
@@ -1,228 +1,228 @@
-using System;
-using System.IO;
-
-namespace Jellyfish.Virtu
-{
- public sealed class NoSlotClock : MachineComponent
- {
- public NoSlotClock(Machine machine) :
- base(machine)
- {
- }
-
- public override void Initialize()
- {
- _clockEnabled = false;
- _writeEnabled = true;
- _clockRegister = new RingRegister(0x0, 0x1);
- _comparisonRegister = new RingRegister(ClockInitSequence, 0x1);
- }
-
- public override void LoadState(BinaryReader reader, Version version)
- {
- if (reader == null)
- {
- throw new ArgumentNullException("reader");
- }
-
- _clockEnabled = reader.ReadBoolean();
- _writeEnabled = reader.ReadBoolean();
- _clockRegister = new RingRegister(reader.ReadUInt64(), reader.ReadUInt64());
- _comparisonRegister = new RingRegister(reader.ReadUInt64(), reader.ReadUInt64());
- }
-
- public override void SaveState(BinaryWriter writer)
- {
- if (writer == null)
- {
- throw new ArgumentNullException("writer");
- }
-
- writer.Write(_clockEnabled);
- writer.Write(_writeEnabled);
- writer.Write(_clockRegister.Data);
- writer.Write(_clockRegister.Mask);
- writer.Write(_comparisonRegister.Data);
- writer.Write(_comparisonRegister.Mask);
- }
-
- public int Read(int address, int data)
- {
- // this may read or write the clock
- if ((address & 0x4) != 0)
- {
- return ReadClock(data);
- }
-
- WriteClock(address);
- return data;
- }
-
- public void Write(int address)
- {
- // this may read or write the clock
- if ((address & 0x4) != 0)
- {
- ReadClock(0);
- }
- else
- {
- WriteClock(address);
- }
- }
-
- private int ReadClock(int data)
- {
- // for a ROM, A2 high = read, and data out (if any) is on D0
- if (!_clockEnabled)
- {
- _comparisonRegister.Reset();
- _writeEnabled = true;
- return data;
- }
-
- data = _clockRegister.ReadBit(Machine.Video.ReadFloatingBus());
- if (_clockRegister.NextBit())
- {
- _clockEnabled = false;
- }
- return data;
- }
-
- private void WriteClock(int address)
- {
- // for a ROM, A2 low = write, and data in is on A0
- if (!_writeEnabled)
- {
- return;
- }
-
- if (!_clockEnabled)
- {
- if ((_comparisonRegister.CompareBit(address)))
- {
- if (_comparisonRegister.NextBit())
- {
- _clockEnabled = true;
- PopulateClockRegister();
- }
- }
- else
- {
- // mismatch ignores further writes
- _writeEnabled = false;
- }
- }
- else if (_clockRegister.NextBit())
- {
- // simulate writes, but our clock register is read-only
- _clockEnabled = false;
- }
- }
-
- private void PopulateClockRegister()
- {
- // all values are in packed BCD format (4 bits per decimal digit)
- var now = DateTime.Now;
-
- int centisecond = now.Millisecond / 10; // 00-99
- _clockRegister.WriteNibble(centisecond % 10);
- _clockRegister.WriteNibble(centisecond / 10);
-
- int second = now.Second; // 00-59
- _clockRegister.WriteNibble(second % 10);
- _clockRegister.WriteNibble(second / 10);
-
- int minute = now.Minute; // 00-59
- _clockRegister.WriteNibble(minute % 10);
- _clockRegister.WriteNibble(minute / 10);
-
- int hour = now.Hour; // 01-23
- _clockRegister.WriteNibble(hour % 10);
- _clockRegister.WriteNibble(hour / 10);
-
- int day = (int)now.DayOfWeek + 1; // 01-07 (1 = Sunday)
- _clockRegister.WriteNibble(day % 10);
- _clockRegister.WriteNibble(day / 10);
-
- int date = now.Day; // 01-31
- _clockRegister.WriteNibble(date % 10);
- _clockRegister.WriteNibble(date / 10);
-
- int month = now.Month; // 01-12
- _clockRegister.WriteNibble(month % 10);
- _clockRegister.WriteNibble(month / 10);
-
- int year = now.Year % 100; // 00-99
- _clockRegister.WriteNibble(year % 10);
- _clockRegister.WriteNibble(year / 10);
- }
-
- private const ulong ClockInitSequence = 0x5CA33AC55CA33AC5;
-
- private bool _clockEnabled;
- private bool _writeEnabled;
- private RingRegister _clockRegister;
- private RingRegister _comparisonRegister;
-
- private struct RingRegister
- {
- public RingRegister(ulong data, ulong mask)
- {
- _data = data;
- _mask = mask;
- }
-
- public void Reset()
- {
- _mask = 0x1;
- }
-
- public void WriteNibble(int data)
- {
- WriteBits(data, 4);
- }
-
- public void WriteBits(int data, int count)
- {
- for (int i = 1; i <= count; i++)
- {
- WriteBit(data);
- NextBit();
- data >>= 1;
- }
- }
-
- public void WriteBit(int data)
- {
- _data = ((data & 0x1) != 0) ? (_data | _mask) : (_data & ~_mask);
- }
-
- public int ReadBit(int data)
- {
- return ((_data & _mask) != 0) ? (data | 0x1) : (data & ~0x1);
- }
-
- public bool CompareBit(int data)
- {
- return (((_data & _mask) != 0) == ((data & 0x1) != 0));
- }
-
- public bool NextBit()
- {
- if ((_mask <<= 1) == 0)
- {
- _mask = 0x1;
- return true; // wrap
- }
- return false;
- }
-
- public ulong Data { get { return _data; } } // no auto props
- public ulong Mask { get { return _mask; } }
-
- private ulong _data;
- private ulong _mask;
- }
- }
-}
+using System;
+using System.IO;
+
+namespace Jellyfish.Virtu
+{
+ public sealed class NoSlotClock : MachineComponent
+ {
+ public NoSlotClock(Machine machine) :
+ base(machine)
+ {
+ }
+
+ public override void Initialize()
+ {
+ _clockEnabled = false;
+ _writeEnabled = true;
+ _clockRegister = new RingRegister(0x0, 0x1);
+ _comparisonRegister = new RingRegister(ClockInitSequence, 0x1);
+ }
+
+ public override void LoadState(BinaryReader reader, Version version)
+ {
+ if (reader == null)
+ {
+ throw new ArgumentNullException("reader");
+ }
+
+ _clockEnabled = reader.ReadBoolean();
+ _writeEnabled = reader.ReadBoolean();
+ _clockRegister = new RingRegister(reader.ReadUInt64(), reader.ReadUInt64());
+ _comparisonRegister = new RingRegister(reader.ReadUInt64(), reader.ReadUInt64());
+ }
+
+ public override void SaveState(BinaryWriter writer)
+ {
+ if (writer == null)
+ {
+ throw new ArgumentNullException("writer");
+ }
+
+ writer.Write(_clockEnabled);
+ writer.Write(_writeEnabled);
+ writer.Write(_clockRegister.Data);
+ writer.Write(_clockRegister.Mask);
+ writer.Write(_comparisonRegister.Data);
+ writer.Write(_comparisonRegister.Mask);
+ }
+
+ public int Read(int address, int data)
+ {
+ // this may read or write the clock
+ if ((address & 0x4) != 0)
+ {
+ return ReadClock(data);
+ }
+
+ WriteClock(address);
+ return data;
+ }
+
+ public void Write(int address)
+ {
+ // this may read or write the clock
+ if ((address & 0x4) != 0)
+ {
+ ReadClock(0);
+ }
+ else
+ {
+ WriteClock(address);
+ }
+ }
+
+ private int ReadClock(int data)
+ {
+ // for a ROM, A2 high = read, and data out (if any) is on D0
+ if (!_clockEnabled)
+ {
+ _comparisonRegister.Reset();
+ _writeEnabled = true;
+ return data;
+ }
+
+ data = _clockRegister.ReadBit(Machine.Video.ReadFloatingBus());
+ if (_clockRegister.NextBit())
+ {
+ _clockEnabled = false;
+ }
+ return data;
+ }
+
+ private void WriteClock(int address)
+ {
+ // for a ROM, A2 low = write, and data in is on A0
+ if (!_writeEnabled)
+ {
+ return;
+ }
+
+ if (!_clockEnabled)
+ {
+ if ((_comparisonRegister.CompareBit(address)))
+ {
+ if (_comparisonRegister.NextBit())
+ {
+ _clockEnabled = true;
+ PopulateClockRegister();
+ }
+ }
+ else
+ {
+ // mismatch ignores further writes
+ _writeEnabled = false;
+ }
+ }
+ else if (_clockRegister.NextBit())
+ {
+ // simulate writes, but our clock register is read-only
+ _clockEnabled = false;
+ }
+ }
+
+ private void PopulateClockRegister()
+ {
+ // all values are in packed BCD format (4 bits per decimal digit)
+ var now = DateTime.Now;
+
+ int centisecond = now.Millisecond / 10; // 00-99
+ _clockRegister.WriteNibble(centisecond % 10);
+ _clockRegister.WriteNibble(centisecond / 10);
+
+ int second = now.Second; // 00-59
+ _clockRegister.WriteNibble(second % 10);
+ _clockRegister.WriteNibble(second / 10);
+
+ int minute = now.Minute; // 00-59
+ _clockRegister.WriteNibble(minute % 10);
+ _clockRegister.WriteNibble(minute / 10);
+
+ int hour = now.Hour; // 01-23
+ _clockRegister.WriteNibble(hour % 10);
+ _clockRegister.WriteNibble(hour / 10);
+
+ int day = (int)now.DayOfWeek + 1; // 01-07 (1 = Sunday)
+ _clockRegister.WriteNibble(day % 10);
+ _clockRegister.WriteNibble(day / 10);
+
+ int date = now.Day; // 01-31
+ _clockRegister.WriteNibble(date % 10);
+ _clockRegister.WriteNibble(date / 10);
+
+ int month = now.Month; // 01-12
+ _clockRegister.WriteNibble(month % 10);
+ _clockRegister.WriteNibble(month / 10);
+
+ int year = now.Year % 100; // 00-99
+ _clockRegister.WriteNibble(year % 10);
+ _clockRegister.WriteNibble(year / 10);
+ }
+
+ private const ulong ClockInitSequence = 0x5CA33AC55CA33AC5;
+
+ private bool _clockEnabled;
+ private bool _writeEnabled;
+ private RingRegister _clockRegister;
+ private RingRegister _comparisonRegister;
+
+ private struct RingRegister
+ {
+ public RingRegister(ulong data, ulong mask)
+ {
+ _data = data;
+ _mask = mask;
+ }
+
+ public void Reset()
+ {
+ _mask = 0x1;
+ }
+
+ public void WriteNibble(int data)
+ {
+ WriteBits(data, 4);
+ }
+
+ public void WriteBits(int data, int count)
+ {
+ for (int i = 1; i <= count; i++)
+ {
+ WriteBit(data);
+ NextBit();
+ data >>= 1;
+ }
+ }
+
+ public void WriteBit(int data)
+ {
+ _data = ((data & 0x1) != 0) ? (_data | _mask) : (_data & ~_mask);
+ }
+
+ public int ReadBit(int data)
+ {
+ return ((_data & _mask) != 0) ? (data | 0x1) : (data & ~0x1);
+ }
+
+ public bool CompareBit(int data)
+ {
+ return (((_data & _mask) != 0) == ((data & 0x1) != 0));
+ }
+
+ public bool NextBit()
+ {
+ if ((_mask <<= 1) == 0)
+ {
+ _mask = 0x1;
+ return true; // wrap
+ }
+ return false;
+ }
+
+ public ulong Data { get { return _data; } } // no auto props
+ public ulong Mask { get { return _mask; } }
+
+ private ulong _data;
+ private ulong _mask;
+ }
+ }
+}
diff --git a/Virtu/PeripheralCard.cs b/Virtu/PeripheralCard.cs
index 662f61e..7aa7b23 100644
--- a/Virtu/PeripheralCard.cs
+++ b/Virtu/PeripheralCard.cs
@@ -1,48 +1,48 @@
-namespace Jellyfish.Virtu
-{
- public class PeripheralCard : MachineComponent
- {
- public PeripheralCard(Machine machine) :
- base(machine)
- {
- }
-
- public virtual int ReadIoRegionC0C0(int address)
- {
- // read Device Select' address $C0nX; n = slot number + 8
- return ReadFloatingBus();
- }
-
- public virtual int ReadIoRegionC1C7(int address)
- {
- // read I/O Select' address $CsXX; s = slot number
- return ReadFloatingBus();
- }
-
- public virtual int ReadIoRegionC8CF(int address)
- {
- // read I/O Strobe' address $C800-$CFFF
- return ReadFloatingBus();
- }
-
- public virtual void WriteIoRegionC0C0(int address, int data)
- {
- // write Device Select' address $C0nX; n = slot number + 8
- }
-
- public virtual void WriteIoRegionC1C7(int address, int data)
- {
- // write I/O Select' address $CsXX; s = slot number
- }
-
- public virtual void WriteIoRegionC8CF(int address, int data)
- {
- // write I/O Strobe' address $C800-$CFFF
- }
-
- protected int ReadFloatingBus()
- {
- return Machine.Video.ReadFloatingBus();
- }
- }
-}
+namespace Jellyfish.Virtu
+{
+ public class PeripheralCard : MachineComponent
+ {
+ public PeripheralCard(Machine machine) :
+ base(machine)
+ {
+ }
+
+ public virtual int ReadIoRegionC0C0(int address)
+ {
+ // read Device Select' address $C0nX; n = slot number + 8
+ return ReadFloatingBus();
+ }
+
+ public virtual int ReadIoRegionC1C7(int address)
+ {
+ // read I/O Select' address $CsXX; s = slot number
+ return ReadFloatingBus();
+ }
+
+ public virtual int ReadIoRegionC8CF(int address)
+ {
+ // read I/O Strobe' address $C800-$CFFF
+ return ReadFloatingBus();
+ }
+
+ public virtual void WriteIoRegionC0C0(int address, int data)
+ {
+ // write Device Select' address $C0nX; n = slot number + 8
+ }
+
+ public virtual void WriteIoRegionC1C7(int address, int data)
+ {
+ // write I/O Select' address $CsXX; s = slot number
+ }
+
+ public virtual void WriteIoRegionC8CF(int address, int data)
+ {
+ // write I/O Strobe' address $C800-$CFFF
+ }
+
+ protected int ReadFloatingBus()
+ {
+ return Machine.Video.ReadFloatingBus();
+ }
+ }
+}
diff --git a/Virtu/Properties/Strings.Designer.cs b/Virtu/Properties/Strings.Designer.cs
index c2fae9e..311e203 100644
--- a/Virtu/Properties/Strings.Designer.cs
+++ b/Virtu/Properties/Strings.Designer.cs
@@ -1,108 +1,108 @@
-//------------------------------------------------------------------------------
-//
-// This code was generated by a tool.
-// Runtime Version:4.0.30319.17626
-//
-// 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", "4.0.0.0")]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- internal class Strings {
-
- private static global::System.Resources.ResourceManager resourceMan;
-
- private static global::System.Globalization.CultureInfo resourceCulture;
-
- [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
- internal Strings() {
- }
-
- ///
- /// 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.Strings", typeof(Strings).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 Invalid address range ${0:X04}-${1:X04}..
- ///
- internal static string InvalidAddressRange {
- get {
- return ResourceManager.GetString("InvalidAddressRange", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Marker ${0:X04} not found..
- ///
- internal static string MarkerNotFound {
- get {
- return ResourceManager.GetString("MarkerNotFound", 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:4.0.30319.17626
+//
+// 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", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Strings {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Strings() {
+ }
+
+ ///
+ /// 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.Strings", typeof(Strings).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 Invalid address range ${0:X04}-${1:X04}..
+ ///
+ internal static string InvalidAddressRange {
+ get {
+ return ResourceManager.GetString("InvalidAddressRange", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Marker ${0:X04} not found..
+ ///
+ internal static string MarkerNotFound {
+ get {
+ return ResourceManager.GetString("MarkerNotFound", 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/Strings.resx b/Virtu/Properties/Strings.resx
index 90993f2..4a8b2bb 100644
--- a/Virtu/Properties/Strings.resx
+++ b/Virtu/Properties/Strings.resx
@@ -1,135 +1,135 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- Invalid address range ${0:X04}-${1:X04}.
-
-
- Marker ${0:X04} not found.
-
-
- Resource '{0}' not found.
-
-
- 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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Invalid address range ${0:X04}-${1:X04}.
+
+
+ Marker ${0:X04} not found.
+
+
+ Resource '{0}' not found.
+
+
+ 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 8f457e2..1928e30 100644
--- a/Virtu/Services/AudioService.cs
+++ b/Virtu/Services/AudioService.cs
@@ -1,66 +1,66 @@
-using System;
-using System.Diagnostics.CodeAnalysis;
-using System.Threading;
-using Jellyfish.Library;
-
-namespace Jellyfish.Virtu.Services
-{
- public abstract class AudioService : MachineService
- {
- protected AudioService(Machine machine) :
- base(machine)
- {
- }
-
- public void Output(int data) // machine thread
- {
- if (BitConverter.IsLittleEndian)
- {
- _buffer[_index + 0] = (byte)(data & 0xFF);
- _buffer[_index + 1] = (byte)(data >> 8);
- }
- else
- {
- _buffer[_index + 0] = (byte)(data >> 8);
- _buffer[_index + 1] = (byte)(data & 0xFF);
- }
- _index = (_index + 2) % SampleSize;
- if (_index == 0)
- {
- if (Machine.Cpu.IsThrottled)
- {
- _writeEvent.WaitOne(SampleLatency * 2); // allow timeout; avoids deadlock
- }
- }
- }
-
- public void Reset()
- {
- Buffer.BlockCopy(SampleZero, 0, _buffer, 0, SampleSize);
- }
-
- public abstract void SetVolume(float volume);
-
- protected void Update() // audio thread
- {
- _writeEvent.Set();
- }
-
- public const int SampleRate = 44100; // hz
- public const int SampleChannels = 1;
- public const int SampleBits = 16;
- public const int SampleLatency = 40; // ms
- public const int SampleSize = (SampleRate * SampleLatency / 1000) * SampleChannels * (SampleBits / 8);
-
- [SuppressMessage("Microsoft.Security", "CA2105:ArrayFieldsShouldNotBeReadOnly")]
- protected static readonly byte[] SampleZero = new byte[SampleSize];
-
- [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
- protected byte[] Source { get { return _buffer; } }
-
- private byte[] _buffer = new byte[SampleSize];
- private int _index;
-
- private AutoResetEvent _writeEvent = new AutoResetEvent(false);
- }
-}
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.Threading;
+using Jellyfish.Library;
+
+namespace Jellyfish.Virtu.Services
+{
+ public abstract class AudioService : MachineService
+ {
+ protected AudioService(Machine machine) :
+ base(machine)
+ {
+ }
+
+ public void Output(int data) // machine thread
+ {
+ if (BitConverter.IsLittleEndian)
+ {
+ _buffer[_index + 0] = (byte)(data & 0xFF);
+ _buffer[_index + 1] = (byte)(data >> 8);
+ }
+ else
+ {
+ _buffer[_index + 0] = (byte)(data >> 8);
+ _buffer[_index + 1] = (byte)(data & 0xFF);
+ }
+ _index = (_index + 2) % SampleSize;
+ if (_index == 0)
+ {
+ if (Machine.Cpu.IsThrottled)
+ {
+ _writeEvent.WaitOne(SampleLatency * 2); // allow timeout; avoids deadlock
+ }
+ }
+ }
+
+ public void Reset()
+ {
+ Buffer.BlockCopy(SampleZero, 0, _buffer, 0, SampleSize);
+ }
+
+ public abstract void SetVolume(float volume);
+
+ protected void Update() // audio thread
+ {
+ _writeEvent.Set();
+ }
+
+ public const int SampleRate = 44100; // hz
+ public const int SampleChannels = 1;
+ public const int SampleBits = 16;
+ public const int SampleLatency = 40; // ms
+ public const int SampleSize = (SampleRate * SampleLatency / 1000) * SampleChannels * (SampleBits / 8);
+
+ [SuppressMessage("Microsoft.Security", "CA2105:ArrayFieldsShouldNotBeReadOnly")]
+ protected static readonly byte[] SampleZero = new byte[SampleSize];
+
+ [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
+ protected byte[] Source { get { return _buffer; } }
+
+ private byte[] _buffer = new byte[SampleSize];
+ private int _index;
+
+ private AutoResetEvent _writeEvent = new AutoResetEvent(false);
+ }
+}
diff --git a/Virtu/Services/DebugService.cs b/Virtu/Services/DebugService.cs
index ecdef36..e562e9f 100644
--- a/Virtu/Services/DebugService.cs
+++ b/Virtu/Services/DebugService.cs
@@ -1,63 +1,63 @@
-using System;
-using System.Diagnostics;
-using System.Globalization;
-using System.Text;
-using System.Threading;
-using Jellyfish.Library;
-
-namespace Jellyfish.Virtu.Services
-{
- public class DebugService : MachineService
- {
- public DebugService(Machine machine) :
- base(machine)
- {
- }
-
- public void WriteMessage(string message)
- {
- OnWriteMessage(FormatMessage(message));
- }
-
- public void WriteMessage(string format, params object[] args)
- {
- OnWriteMessage(FormatMessage(format, args));
- }
-
- protected virtual void OnWriteMessage(string message)
- {
-#if SILVERLIGHT
- Debug.WriteLine(message);
-#else
- Trace.WriteLine(message);
-#endif
- }
-
- private string FormatMessage(string format, params object[] args)
- {
- var message = new StringBuilder(256);
- message.AppendFormat(CultureInfo.InvariantCulture, "[{0} T{1:X3} Virtu] ", DateTime.Now.ToString("HH:mm:ss.fff", CultureInfo.InvariantCulture), Thread.CurrentThread.ManagedThreadId);
- if (args.Length > 0)
- {
- try
- {
- message.AppendFormat(CultureInfo.InvariantCulture, format, args);
- }
- catch (FormatException ex)
- {
- WriteMessage("[DebugService.FormatMessage] format: {0}; args: {1}; exception: {2}", format, string.Join(", ", args), ex.Message);
- }
- }
- else
- {
- message.Append(format);
- }
-
- return message.ToString();
- }
-
- public static DebugService Default { get { return _default.Value; } }
-
- private static readonly Lazy _default = new Lazy(() => new DebugService(null));
- }
-}
+using System;
+using System.Diagnostics;
+using System.Globalization;
+using System.Text;
+using System.Threading;
+using Jellyfish.Library;
+
+namespace Jellyfish.Virtu.Services
+{
+ public class DebugService : MachineService
+ {
+ public DebugService(Machine machine) :
+ base(machine)
+ {
+ }
+
+ public void WriteMessage(string message)
+ {
+ OnWriteMessage(FormatMessage(message));
+ }
+
+ public void WriteMessage(string format, params object[] args)
+ {
+ OnWriteMessage(FormatMessage(format, args));
+ }
+
+ protected virtual void OnWriteMessage(string message)
+ {
+#if SILVERLIGHT
+ Debug.WriteLine(message);
+#else
+ Trace.WriteLine(message);
+#endif
+ }
+
+ private string FormatMessage(string format, params object[] args)
+ {
+ var message = new StringBuilder(256);
+ message.AppendFormat(CultureInfo.InvariantCulture, "[{0} T{1:X3} Virtu] ", DateTime.Now.ToString("HH:mm:ss.fff", CultureInfo.InvariantCulture), Thread.CurrentThread.ManagedThreadId);
+ if (args.Length > 0)
+ {
+ try
+ {
+ message.AppendFormat(CultureInfo.InvariantCulture, format, args);
+ }
+ catch (FormatException ex)
+ {
+ WriteMessage("[DebugService.FormatMessage] format: {0}; args: {1}; exception: {2}", format, string.Join(", ", args), ex.Message);
+ }
+ }
+ else
+ {
+ message.Append(format);
+ }
+
+ return message.ToString();
+ }
+
+ public static DebugService Default { get { return _default.Value; } }
+
+ private static readonly Lazy _default = new Lazy(() => new DebugService(null));
+ }
+}
diff --git a/Virtu/Services/GamePortService.cs b/Virtu/Services/GamePortService.cs
index abe2c4c..4ebbc74 100644
--- a/Virtu/Services/GamePortService.cs
+++ b/Virtu/Services/GamePortService.cs
@@ -1,139 +1,139 @@
-using System;
-
-namespace Jellyfish.Virtu.Services
-{
- public class GamePortService : MachineService
- {
- public GamePortService(Machine machine) :
- base(machine)
- {
- Paddle0 = Paddle1 = Paddle2 = Paddle3 = 255; // not connected
- }
-
- public virtual void Update() // main thread
- {
- var keyboard = Machine.Keyboard;
-
- if (keyboard.UseGamePort)
- {
- UpdateKey(keyboard.Joystick0UpKey, IsJoystick0Up, ref _isJoystick0UpKeyDown, ref _wasJoystick0UpKeyDown);
- UpdateKey(keyboard.Joystick0LeftKey, IsJoystick0Left, ref _isJoystick0LeftKeyDown, ref _wasJoystick0LeftKeyDown);
- UpdateKey(keyboard.Joystick0RightKey, IsJoystick0Right, ref _isJoystick0RightKeyDown, ref _wasJoystick0RightKeyDown);
- UpdateKey(keyboard.Joystick0DownKey, IsJoystick0Down, ref _isJoystick0DownKeyDown, ref _wasJoystick0DownKeyDown);
- UpdateKey(keyboard.Joystick0UpLeftKey, IsJoystick0Up && IsJoystick0Left, ref _isJoystick0UpLeftKeyDown, ref _wasJoystick0UpLeftKeyDown);
- UpdateKey(keyboard.Joystick0UpRightKey, IsJoystick0Up && IsJoystick0Right, ref _isJoystick0UpRightKeyDown, ref _wasJoystick0UpRightKeyDown);
- UpdateKey(keyboard.Joystick0DownLeftKey, IsJoystick0Down && IsJoystick0Left, ref _isJoystick0DownLeftKeyDown, ref _wasJoystick0DownLeftKeyDown);
- UpdateKey(keyboard.Joystick0DownRightKey, IsJoystick0Down && IsJoystick0Right, ref _isJoystick0DownRightKeyDown, ref _wasJoystick0DownRightKeyDown);
- UpdateKey(keyboard.Joystick1UpKey, IsJoystick1Up, ref _isJoystick1UpKeyDown, ref _wasJoystick1UpKeyDown);
- UpdateKey(keyboard.Joystick1LeftKey, IsJoystick1Left, ref _isJoystick1LeftKeyDown, ref _wasJoystick1LeftKeyDown);
- UpdateKey(keyboard.Joystick1RightKey, IsJoystick1Right, ref _isJoystick1RightKeyDown, ref _wasJoystick1RightKeyDown);
- UpdateKey(keyboard.Joystick1DownKey, IsJoystick1Down, ref _isJoystick1DownKeyDown, ref _wasJoystick1DownKeyDown);
- UpdateKey(keyboard.Joystick1UpLeftKey, IsJoystick1Up && IsJoystick1Left, ref _isJoystick1UpLeftKeyDown, ref _wasJoystick1UpLeftKeyDown);
- UpdateKey(keyboard.Joystick1UpRightKey, IsJoystick1Up && IsJoystick1Right, ref _isJoystick1UpRightKeyDown, ref _wasJoystick1UpRightKeyDown);
- UpdateKey(keyboard.Joystick1DownLeftKey, IsJoystick1Down && IsJoystick1Left, ref _isJoystick1DownLeftKeyDown, ref _wasJoystick1DownLeftKeyDown);
- UpdateKey(keyboard.Joystick1DownRightKey, IsJoystick1Down && IsJoystick1Right, ref _isJoystick1DownRightKeyDown, ref _wasJoystick1DownRightKeyDown);
- UpdateKey(keyboard.Button0Key, IsButton0Down, ref _isButton0KeyDown, ref _wasButton0KeyDown);
- UpdateKey(keyboard.Button1Key, IsButton1Down, ref _isButton1KeyDown, ref _wasButton1KeyDown);
- UpdateKey(keyboard.Button2Key, IsButton2Down, ref _isButton2KeyDown, ref _wasButton2KeyDown);
-
- if (_lastKey > 0) // repeat last key
- {
- long time = DateTime.UtcNow.Ticks;
- if (time - _lastTime >= _repeatTime)
- {
- _lastTime = time;
- _repeatTime = RepeatSpeed;
- keyboard.Latch = _lastKey;
- }
- }
- }
- }
-
- private void UpdateKey(int key, bool isActive, ref bool isKeyDown, ref bool wasKeyDown)
- {
- wasKeyDown = isKeyDown;
- isKeyDown = (key > 0) && isActive;
-
- if (isKeyDown != wasKeyDown)
- {
- if (isKeyDown)
- {
- _lastKey = key;
- _lastTime = DateTime.UtcNow.Ticks;
- _repeatTime = RepeatDelay;
- Machine.Keyboard.Latch = key;
- }
- else if (key == _lastKey)
- {
- _lastKey = 0;
- }
- }
- }
-
- 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 bool IsJoystick0Up { get; protected set; }
- public bool IsJoystick0Left { get; protected set; }
- public bool IsJoystick0Right { get; protected set; }
- public bool IsJoystick0Down { get; protected set; }
-
- public bool IsJoystick1Up { get; protected set; }
- public bool IsJoystick1Left { get; protected set; }
- public bool IsJoystick1Right { get; protected set; }
- public bool IsJoystick1Down { get; protected set; }
-
- public bool IsButton0Down { get; protected set; }
- public bool IsButton1Down { get; protected set; }
- public bool IsButton2Down { get; protected set; }
-
- private static readonly long RepeatDelay = TimeSpan.FromMilliseconds(500).Ticks;
- private static readonly long RepeatSpeed = TimeSpan.FromMilliseconds(32).Ticks;
-
- private bool _isJoystick0UpLeftKeyDown;
- private bool _isJoystick0UpKeyDown;
- private bool _isJoystick0UpRightKeyDown;
- private bool _isJoystick0LeftKeyDown;
- private bool _isJoystick0RightKeyDown;
- private bool _isJoystick0DownLeftKeyDown;
- private bool _isJoystick0DownKeyDown;
- private bool _isJoystick0DownRightKeyDown;
- private bool _isJoystick1UpLeftKeyDown;
- private bool _isJoystick1UpKeyDown;
- private bool _isJoystick1UpRightKeyDown;
- private bool _isJoystick1LeftKeyDown;
- private bool _isJoystick1RightKeyDown;
- private bool _isJoystick1DownLeftKeyDown;
- private bool _isJoystick1DownKeyDown;
- private bool _isJoystick1DownRightKeyDown;
- private bool _isButton0KeyDown;
- private bool _isButton1KeyDown;
- private bool _isButton2KeyDown;
-
- private bool _wasJoystick0UpLeftKeyDown;
- private bool _wasJoystick0UpKeyDown;
- private bool _wasJoystick0UpRightKeyDown;
- private bool _wasJoystick0LeftKeyDown;
- private bool _wasJoystick0RightKeyDown;
- private bool _wasJoystick0DownLeftKeyDown;
- private bool _wasJoystick0DownKeyDown;
- private bool _wasJoystick0DownRightKeyDown;
- private bool _wasJoystick1UpLeftKeyDown;
- private bool _wasJoystick1UpKeyDown;
- private bool _wasJoystick1UpRightKeyDown;
- private bool _wasJoystick1LeftKeyDown;
- private bool _wasJoystick1RightKeyDown;
- private bool _wasJoystick1DownLeftKeyDown;
- private bool _wasJoystick1DownKeyDown;
- private bool _wasJoystick1DownRightKeyDown;
- private bool _wasButton0KeyDown;
- private bool _wasButton1KeyDown;
- private bool _wasButton2KeyDown;
-
- private int _lastKey;
- private long _lastTime;
- private long _repeatTime;
- }
-}
+using System;
+
+namespace Jellyfish.Virtu.Services
+{
+ public class GamePortService : MachineService
+ {
+ public GamePortService(Machine machine) :
+ base(machine)
+ {
+ Paddle0 = Paddle1 = Paddle2 = Paddle3 = 255; // not connected
+ }
+
+ public virtual void Update() // main thread
+ {
+ var keyboard = Machine.Keyboard;
+
+ if (keyboard.UseGamePort)
+ {
+ UpdateKey(keyboard.Joystick0UpKey, IsJoystick0Up, ref _isJoystick0UpKeyDown, ref _wasJoystick0UpKeyDown);
+ UpdateKey(keyboard.Joystick0LeftKey, IsJoystick0Left, ref _isJoystick0LeftKeyDown, ref _wasJoystick0LeftKeyDown);
+ UpdateKey(keyboard.Joystick0RightKey, IsJoystick0Right, ref _isJoystick0RightKeyDown, ref _wasJoystick0RightKeyDown);
+ UpdateKey(keyboard.Joystick0DownKey, IsJoystick0Down, ref _isJoystick0DownKeyDown, ref _wasJoystick0DownKeyDown);
+ UpdateKey(keyboard.Joystick0UpLeftKey, IsJoystick0Up && IsJoystick0Left, ref _isJoystick0UpLeftKeyDown, ref _wasJoystick0UpLeftKeyDown);
+ UpdateKey(keyboard.Joystick0UpRightKey, IsJoystick0Up && IsJoystick0Right, ref _isJoystick0UpRightKeyDown, ref _wasJoystick0UpRightKeyDown);
+ UpdateKey(keyboard.Joystick0DownLeftKey, IsJoystick0Down && IsJoystick0Left, ref _isJoystick0DownLeftKeyDown, ref _wasJoystick0DownLeftKeyDown);
+ UpdateKey(keyboard.Joystick0DownRightKey, IsJoystick0Down && IsJoystick0Right, ref _isJoystick0DownRightKeyDown, ref _wasJoystick0DownRightKeyDown);
+ UpdateKey(keyboard.Joystick1UpKey, IsJoystick1Up, ref _isJoystick1UpKeyDown, ref _wasJoystick1UpKeyDown);
+ UpdateKey(keyboard.Joystick1LeftKey, IsJoystick1Left, ref _isJoystick1LeftKeyDown, ref _wasJoystick1LeftKeyDown);
+ UpdateKey(keyboard.Joystick1RightKey, IsJoystick1Right, ref _isJoystick1RightKeyDown, ref _wasJoystick1RightKeyDown);
+ UpdateKey(keyboard.Joystick1DownKey, IsJoystick1Down, ref _isJoystick1DownKeyDown, ref _wasJoystick1DownKeyDown);
+ UpdateKey(keyboard.Joystick1UpLeftKey, IsJoystick1Up && IsJoystick1Left, ref _isJoystick1UpLeftKeyDown, ref _wasJoystick1UpLeftKeyDown);
+ UpdateKey(keyboard.Joystick1UpRightKey, IsJoystick1Up && IsJoystick1Right, ref _isJoystick1UpRightKeyDown, ref _wasJoystick1UpRightKeyDown);
+ UpdateKey(keyboard.Joystick1DownLeftKey, IsJoystick1Down && IsJoystick1Left, ref _isJoystick1DownLeftKeyDown, ref _wasJoystick1DownLeftKeyDown);
+ UpdateKey(keyboard.Joystick1DownRightKey, IsJoystick1Down && IsJoystick1Right, ref _isJoystick1DownRightKeyDown, ref _wasJoystick1DownRightKeyDown);
+ UpdateKey(keyboard.Button0Key, IsButton0Down, ref _isButton0KeyDown, ref _wasButton0KeyDown);
+ UpdateKey(keyboard.Button1Key, IsButton1Down, ref _isButton1KeyDown, ref _wasButton1KeyDown);
+ UpdateKey(keyboard.Button2Key, IsButton2Down, ref _isButton2KeyDown, ref _wasButton2KeyDown);
+
+ if (_lastKey > 0) // repeat last key
+ {
+ long time = DateTime.UtcNow.Ticks;
+ if (time - _lastTime >= _repeatTime)
+ {
+ _lastTime = time;
+ _repeatTime = RepeatSpeed;
+ keyboard.Latch = _lastKey;
+ }
+ }
+ }
+ }
+
+ private void UpdateKey(int key, bool isActive, ref bool isKeyDown, ref bool wasKeyDown)
+ {
+ wasKeyDown = isKeyDown;
+ isKeyDown = (key > 0) && isActive;
+
+ if (isKeyDown != wasKeyDown)
+ {
+ if (isKeyDown)
+ {
+ _lastKey = key;
+ _lastTime = DateTime.UtcNow.Ticks;
+ _repeatTime = RepeatDelay;
+ Machine.Keyboard.Latch = key;
+ }
+ else if (key == _lastKey)
+ {
+ _lastKey = 0;
+ }
+ }
+ }
+
+ 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 bool IsJoystick0Up { get; protected set; }
+ public bool IsJoystick0Left { get; protected set; }
+ public bool IsJoystick0Right { get; protected set; }
+ public bool IsJoystick0Down { get; protected set; }
+
+ public bool IsJoystick1Up { get; protected set; }
+ public bool IsJoystick1Left { get; protected set; }
+ public bool IsJoystick1Right { get; protected set; }
+ public bool IsJoystick1Down { get; protected set; }
+
+ public bool IsButton0Down { get; protected set; }
+ public bool IsButton1Down { get; protected set; }
+ public bool IsButton2Down { get; protected set; }
+
+ private static readonly long RepeatDelay = TimeSpan.FromMilliseconds(500).Ticks;
+ private static readonly long RepeatSpeed = TimeSpan.FromMilliseconds(32).Ticks;
+
+ private bool _isJoystick0UpLeftKeyDown;
+ private bool _isJoystick0UpKeyDown;
+ private bool _isJoystick0UpRightKeyDown;
+ private bool _isJoystick0LeftKeyDown;
+ private bool _isJoystick0RightKeyDown;
+ private bool _isJoystick0DownLeftKeyDown;
+ private bool _isJoystick0DownKeyDown;
+ private bool _isJoystick0DownRightKeyDown;
+ private bool _isJoystick1UpLeftKeyDown;
+ private bool _isJoystick1UpKeyDown;
+ private bool _isJoystick1UpRightKeyDown;
+ private bool _isJoystick1LeftKeyDown;
+ private bool _isJoystick1RightKeyDown;
+ private bool _isJoystick1DownLeftKeyDown;
+ private bool _isJoystick1DownKeyDown;
+ private bool _isJoystick1DownRightKeyDown;
+ private bool _isButton0KeyDown;
+ private bool _isButton1KeyDown;
+ private bool _isButton2KeyDown;
+
+ private bool _wasJoystick0UpLeftKeyDown;
+ private bool _wasJoystick0UpKeyDown;
+ private bool _wasJoystick0UpRightKeyDown;
+ private bool _wasJoystick0LeftKeyDown;
+ private bool _wasJoystick0RightKeyDown;
+ private bool _wasJoystick0DownLeftKeyDown;
+ private bool _wasJoystick0DownKeyDown;
+ private bool _wasJoystick0DownRightKeyDown;
+ private bool _wasJoystick1UpLeftKeyDown;
+ private bool _wasJoystick1UpKeyDown;
+ private bool _wasJoystick1UpRightKeyDown;
+ private bool _wasJoystick1LeftKeyDown;
+ private bool _wasJoystick1RightKeyDown;
+ private bool _wasJoystick1DownLeftKeyDown;
+ private bool _wasJoystick1DownKeyDown;
+ private bool _wasJoystick1DownRightKeyDown;
+ private bool _wasButton0KeyDown;
+ private bool _wasButton1KeyDown;
+ private bool _wasButton2KeyDown;
+
+ private int _lastKey;
+ private long _lastTime;
+ private long _repeatTime;
+ }
+}
diff --git a/Virtu/Services/IsolatedStorageService.cs b/Virtu/Services/IsolatedStorageService.cs
index 68159a9..f8c0c14 100644
--- a/Virtu/Services/IsolatedStorageService.cs
+++ b/Virtu/Services/IsolatedStorageService.cs
@@ -1,53 +1,53 @@
-using System;
-using System.Diagnostics.CodeAnalysis;
-using System.IO;
-using System.IO.IsolatedStorage;
-
-namespace Jellyfish.Virtu.Services
-{
- public class IsolatedStorageService : StorageService
- {
- public IsolatedStorageService(Machine machine) :
- base(machine)
- {
- }
-
- protected override void OnLoad(string fileName, Action reader)
- {
- if (reader == null)
- {
- throw new ArgumentNullException("reader");
- }
-
- using (var store = GetStore())
- {
- using (var stream = store.OpenFile(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
- {
- reader(stream);
- }
- }
- }
-
- protected override void OnSave(string fileName, Action writer)
- {
- if (writer == null)
- {
- throw new ArgumentNullException("writer");
- }
-
- using (var store = GetStore())
- {
- using (var stream = store.OpenFile(fileName, FileMode.Create, FileAccess.Write, FileShare.None))
- {
- writer(stream);
- }
- }
- }
-
- [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
- protected virtual IsolatedStorageFile GetStore()
- {
- return IsolatedStorageFile.GetUserStoreForApplication();
- }
- }
-}
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.IO;
+using System.IO.IsolatedStorage;
+
+namespace Jellyfish.Virtu.Services
+{
+ public class IsolatedStorageService : StorageService
+ {
+ public IsolatedStorageService(Machine machine) :
+ base(machine)
+ {
+ }
+
+ protected override void OnLoad(string fileName, Action reader)
+ {
+ if (reader == null)
+ {
+ throw new ArgumentNullException("reader");
+ }
+
+ using (var store = GetStore())
+ {
+ using (var stream = store.OpenFile(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
+ {
+ reader(stream);
+ }
+ }
+ }
+
+ protected override void OnSave(string fileName, Action writer)
+ {
+ if (writer == null)
+ {
+ throw new ArgumentNullException("writer");
+ }
+
+ using (var store = GetStore())
+ {
+ using (var stream = store.OpenFile(fileName, FileMode.Create, FileAccess.Write, FileShare.None))
+ {
+ writer(stream);
+ }
+ }
+ }
+
+ [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
+ protected virtual IsolatedStorageFile GetStore()
+ {
+ return IsolatedStorageFile.GetUserStoreForApplication();
+ }
+ }
+}
diff --git a/Virtu/Services/KeyboardService.cs b/Virtu/Services/KeyboardService.cs
index 6068f47..bf7ee46 100644
--- a/Virtu/Services/KeyboardService.cs
+++ b/Virtu/Services/KeyboardService.cs
@@ -1,43 +1,43 @@
-namespace Jellyfish.Virtu.Services
-{
- public abstract class KeyboardService : MachineService
- {
- protected KeyboardService(Machine machine) :
- base(machine)
- {
- }
-
- public abstract bool IsKeyDown(int key);
-
- public virtual void Update() // main thread
- {
- var keyboard = Machine.Keyboard;
-
- if (IsResetKeyDown && !keyboard.DisableResetKey)
- {
- if (!_resetKeyDown)
- {
- _resetKeyDown = true; // entering reset; pause until key released
- Machine.Pause();
- Machine.Reset();
- }
- }
- else if (_resetKeyDown)
- {
- _resetKeyDown = false; // leaving reset
- Machine.Unpause();
- }
- }
-
- public bool IsAnyKeyDown { get; protected set; }
- public bool IsControlKeyDown { get; protected set; }
- public bool IsShiftKeyDown { get; protected set; }
-
- public bool IsOpenAppleKeyDown { get; protected set; }
- public bool IsCloseAppleKeyDown { get; protected set; }
-
- protected bool IsResetKeyDown { get; set; }
-
- private bool _resetKeyDown;
- }
-}
+namespace Jellyfish.Virtu.Services
+{
+ public abstract class KeyboardService : MachineService
+ {
+ protected KeyboardService(Machine machine) :
+ base(machine)
+ {
+ }
+
+ public abstract bool IsKeyDown(int key);
+
+ public virtual void Update() // main thread
+ {
+ var keyboard = Machine.Keyboard;
+
+ if (IsResetKeyDown && !keyboard.DisableResetKey)
+ {
+ if (!_resetKeyDown)
+ {
+ _resetKeyDown = true; // entering reset; pause until key released
+ Machine.Pause();
+ Machine.Reset();
+ }
+ }
+ else if (_resetKeyDown)
+ {
+ _resetKeyDown = false; // leaving reset
+ Machine.Unpause();
+ }
+ }
+
+ public bool IsAnyKeyDown { get; protected set; }
+ public bool IsControlKeyDown { get; protected set; }
+ public bool IsShiftKeyDown { 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/MachineService.cs b/Virtu/Services/MachineService.cs
index 8c2b246..b287daf 100644
--- a/Virtu/Services/MachineService.cs
+++ b/Virtu/Services/MachineService.cs
@@ -1,20 +1,20 @@
-using System;
-using Jellyfish.Library;
-
-namespace Jellyfish.Virtu.Services
-{
- public abstract class MachineService : DisposableBase
- {
- protected MachineService(Machine machine)
- {
- Machine = machine;
-
- _debugService = new Lazy(() => Machine.Services.GetService());
- }
-
- protected Machine Machine { get; private set; }
- protected DebugService DebugService { get { return _debugService.Value; } }
-
- private Lazy _debugService;
- }
-}
+using System;
+using Jellyfish.Library;
+
+namespace Jellyfish.Virtu.Services
+{
+ public abstract class MachineService : DisposableBase
+ {
+ protected MachineService(Machine machine)
+ {
+ Machine = machine;
+
+ _debugService = new Lazy(() => Machine.Services.GetService());
+ }
+
+ protected Machine Machine { get; private set; }
+ protected DebugService DebugService { get { return _debugService.Value; } }
+
+ private Lazy _debugService;
+ }
+}
diff --git a/Virtu/Services/MachineServices.cs b/Virtu/Services/MachineServices.cs
index b8669ee..50e1884 100644
--- a/Virtu/Services/MachineServices.cs
+++ b/Virtu/Services/MachineServices.cs
@@ -1,51 +1,51 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics.CodeAnalysis;
-using System.Globalization;
-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.CurrentUICulture, Strings.ServiceAlreadyPresent, serviceType.FullName), "serviceType");
- }
- if (serviceProvider == null)
- {
- throw new ArgumentNullException("serviceProvider");
- }
- if (!serviceType.IsAssignableFrom(serviceProvider.GetType()))
- {
- throw new ArgumentException(string.Format(CultureInfo.CurrentUICulture, Strings.ServiceMustBeAssignable, serviceType.FullName, serviceProvider.GetType().FullName));
- }
-
- _serviceProviders.Add(serviceType, serviceProvider);
- }
-
- [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")]
- public T GetService()
- {
- return (T)((IServiceProvider)this).GetService(typeof(T));
- }
-
- public void RemoveService(Type serviceType)
- {
- _serviceProviders.Remove(serviceType);
- }
-
- object IServiceProvider.GetService(Type serviceType)
- {
- return _serviceProviders.ContainsKey(serviceType) ? _serviceProviders[serviceType] : null;
- }
-
- private Dictionary _serviceProviders = new Dictionary();
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+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.CurrentUICulture, Strings.ServiceAlreadyPresent, serviceType.FullName), "serviceType");
+ }
+ if (serviceProvider == null)
+ {
+ throw new ArgumentNullException("serviceProvider");
+ }
+ if (!serviceType.IsAssignableFrom(serviceProvider.GetType()))
+ {
+ throw new ArgumentException(string.Format(CultureInfo.CurrentUICulture, Strings.ServiceMustBeAssignable, serviceType.FullName, serviceProvider.GetType().FullName));
+ }
+
+ _serviceProviders.Add(serviceType, serviceProvider);
+ }
+
+ [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")]
+ public T GetService()
+ {
+ return (T)((IServiceProvider)this).GetService(typeof(T));
+ }
+
+ public void RemoveService(Type serviceType)
+ {
+ _serviceProviders.Remove(serviceType);
+ }
+
+ object IServiceProvider.GetService(Type serviceType)
+ {
+ return _serviceProviders.ContainsKey(serviceType) ? _serviceProviders[serviceType] : null;
+ }
+
+ private Dictionary _serviceProviders = new Dictionary();
+ }
+}
diff --git a/Virtu/Services/StorageService.cs b/Virtu/Services/StorageService.cs
index b1a438e..dd1b531 100644
--- a/Virtu/Services/StorageService.cs
+++ b/Virtu/Services/StorageService.cs
@@ -1,213 +1,213 @@
-using System;
-using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
-using System.Globalization;
-using System.IO;
-using System.Security;
-using Jellyfish.Virtu.Properties;
-
-namespace Jellyfish.Virtu.Services
-{
- public abstract class StorageService : MachineService
- {
- protected StorageService(Machine machine) :
- base(machine)
- {
- }
-
- [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
- public bool Load(string fileName, Action reader)
- {
- try
- {
- DebugService.WriteMessage("Loading file '{0}'", fileName);
- OnLoad(fileName, reader);
- }
- catch (Exception ex)
- {
- DebugService.WriteMessage(ex.ToString());
- return false;
- }
-
- return true;
- }
-
-#if !WINDOWS
- [SecuritySafeCritical]
-#endif
- [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
- public static bool LoadFile(string fileName, Action reader)
- {
- if (reader == null)
- {
- throw new ArgumentNullException("reader");
- }
-
- try
- {
- DebugService.Default.WriteMessage("Loading file '{0}'", fileName);
- using (var stream = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
- {
- reader(stream);
- }
- }
- catch (Exception ex)
- {
- DebugService.Default.WriteMessage(ex.ToString());
- return false;
- }
-
- return true;
- }
-
-#if !WINDOWS
- [SecuritySafeCritical]
-#endif
- [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
- public static bool LoadFile(FileInfo fileInfo, Action reader)
- {
- if (fileInfo == null)
- {
- throw new ArgumentNullException("fileInfo");
- }
- if (reader == null)
- {
- throw new ArgumentNullException("reader");
- }
-
- try
- {
- DebugService.Default.WriteMessage("Loading file '{0}'", fileInfo.Name);
- using (var stream = fileInfo.Open(FileMode.Open, FileAccess.Read, FileShare.Read))
- {
- reader(stream);
- }
- }
- catch (Exception ex)
- {
- DebugService.Default.WriteMessage(ex.ToString());
- return false;
- }
-
- return true;
- }
-
- [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
- public static bool LoadResource(string resourceName, Action reader)
- {
- if (reader == null)
- {
- throw new ArgumentNullException("reader");
- }
-
- try
- {
- DebugService.Default.WriteMessage("Loading resource '{0}'", resourceName);
- using (var stream = GetResourceStream(resourceName))
- {
- reader(stream);
- }
- }
- catch (Exception ex)
- {
- DebugService.Default.WriteMessage(ex.ToString());
- return false;
- }
-
- return true;
- }
-
- [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
- public bool Save(string fileName, Action writer)
- {
- try
- {
- DebugService.WriteMessage("Saving file '{0}'", fileName);
- OnSave(fileName, writer);
- }
- catch (Exception ex)
- {
- DebugService.WriteMessage(ex.ToString());
- return false;
- }
-
- return true;
- }
-
-#if !WINDOWS
- [SecuritySafeCritical]
-#endif
- [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
- public static bool SaveFile(string fileName, Action writer)
- {
- if (writer == null)
- {
- throw new ArgumentNullException("writer");
- }
-
- try
- {
- DebugService.Default.WriteMessage("Saving file '{0}'", fileName);
- using (var stream = File.Open(fileName, FileMode.Create, FileAccess.Write, FileShare.None))
- {
- writer(stream);
- }
- }
- catch (Exception ex)
- {
- DebugService.Default.WriteMessage(ex.ToString());
- return false;
- }
-
- return true;
- }
-
-#if !WINDOWS
- [SecuritySafeCritical]
-#endif
- [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
- public static bool SaveFile(FileInfo fileInfo, Action writer)
- {
- if (fileInfo == null)
- {
- throw new ArgumentNullException("fileInfo");
- }
- if (writer == null)
- {
- throw new ArgumentNullException("writer");
- }
-
- try
- {
- DebugService.Default.WriteMessage("Saving file '{0}'", fileInfo.Name);
- using (var stream = fileInfo.Open(FileMode.Create, FileAccess.Write, FileShare.None))
- {
- writer(stream);
- }
- }
- catch (Exception ex)
- {
- DebugService.Default.WriteMessage(ex.ToString());
- return false;
- }
-
- return true;
- }
-
- protected abstract void OnLoad(string fileName, Action reader);
-
- protected abstract void OnSave(string fileName, Action writer);
-
- private static Stream GetResourceStream(string resourceName)
- {
- resourceName = "Jellyfish.Virtu." + resourceName.Replace('/', '.');
- var resourceStream = typeof(StorageService).Assembly.GetManifestResourceStream(resourceName);
- if (resourceStream == null)
- {
- throw new FileNotFoundException(string.Format(CultureInfo.CurrentUICulture, Strings.ResourceNotFound, resourceName));
- }
-
- return resourceStream;
- }
- }
-}
+using System;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using System.IO;
+using System.Security;
+using Jellyfish.Virtu.Properties;
+
+namespace Jellyfish.Virtu.Services
+{
+ public abstract class StorageService : MachineService
+ {
+ protected StorageService(Machine machine) :
+ base(machine)
+ {
+ }
+
+ [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
+ public bool Load(string fileName, Action reader)
+ {
+ try
+ {
+ DebugService.WriteMessage("Loading file '{0}'", fileName);
+ OnLoad(fileName, reader);
+ }
+ catch (Exception ex)
+ {
+ DebugService.WriteMessage(ex.ToString());
+ return false;
+ }
+
+ return true;
+ }
+
+#if !WINDOWS
+ [SecuritySafeCritical]
+#endif
+ [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
+ public static bool LoadFile(string fileName, Action reader)
+ {
+ if (reader == null)
+ {
+ throw new ArgumentNullException("reader");
+ }
+
+ try
+ {
+ DebugService.Default.WriteMessage("Loading file '{0}'", fileName);
+ using (var stream = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
+ {
+ reader(stream);
+ }
+ }
+ catch (Exception ex)
+ {
+ DebugService.Default.WriteMessage(ex.ToString());
+ return false;
+ }
+
+ return true;
+ }
+
+#if !WINDOWS
+ [SecuritySafeCritical]
+#endif
+ [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
+ public static bool LoadFile(FileInfo fileInfo, Action reader)
+ {
+ if (fileInfo == null)
+ {
+ throw new ArgumentNullException("fileInfo");
+ }
+ if (reader == null)
+ {
+ throw new ArgumentNullException("reader");
+ }
+
+ try
+ {
+ DebugService.Default.WriteMessage("Loading file '{0}'", fileInfo.Name);
+ using (var stream = fileInfo.Open(FileMode.Open, FileAccess.Read, FileShare.Read))
+ {
+ reader(stream);
+ }
+ }
+ catch (Exception ex)
+ {
+ DebugService.Default.WriteMessage(ex.ToString());
+ return false;
+ }
+
+ return true;
+ }
+
+ [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
+ public static bool LoadResource(string resourceName, Action reader)
+ {
+ if (reader == null)
+ {
+ throw new ArgumentNullException("reader");
+ }
+
+ try
+ {
+ DebugService.Default.WriteMessage("Loading resource '{0}'", resourceName);
+ using (var stream = GetResourceStream(resourceName))
+ {
+ reader(stream);
+ }
+ }
+ catch (Exception ex)
+ {
+ DebugService.Default.WriteMessage(ex.ToString());
+ return false;
+ }
+
+ return true;
+ }
+
+ [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
+ public bool Save(string fileName, Action writer)
+ {
+ try
+ {
+ DebugService.WriteMessage("Saving file '{0}'", fileName);
+ OnSave(fileName, writer);
+ }
+ catch (Exception ex)
+ {
+ DebugService.WriteMessage(ex.ToString());
+ return false;
+ }
+
+ return true;
+ }
+
+#if !WINDOWS
+ [SecuritySafeCritical]
+#endif
+ [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
+ public static bool SaveFile(string fileName, Action writer)
+ {
+ if (writer == null)
+ {
+ throw new ArgumentNullException("writer");
+ }
+
+ try
+ {
+ DebugService.Default.WriteMessage("Saving file '{0}'", fileName);
+ using (var stream = File.Open(fileName, FileMode.Create, FileAccess.Write, FileShare.None))
+ {
+ writer(stream);
+ }
+ }
+ catch (Exception ex)
+ {
+ DebugService.Default.WriteMessage(ex.ToString());
+ return false;
+ }
+
+ return true;
+ }
+
+#if !WINDOWS
+ [SecuritySafeCritical]
+#endif
+ [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
+ public static bool SaveFile(FileInfo fileInfo, Action writer)
+ {
+ if (fileInfo == null)
+ {
+ throw new ArgumentNullException("fileInfo");
+ }
+ if (writer == null)
+ {
+ throw new ArgumentNullException("writer");
+ }
+
+ try
+ {
+ DebugService.Default.WriteMessage("Saving file '{0}'", fileInfo.Name);
+ using (var stream = fileInfo.Open(FileMode.Create, FileAccess.Write, FileShare.None))
+ {
+ writer(stream);
+ }
+ }
+ catch (Exception ex)
+ {
+ DebugService.Default.WriteMessage(ex.ToString());
+ return false;
+ }
+
+ return true;
+ }
+
+ protected abstract void OnLoad(string fileName, Action reader);
+
+ protected abstract void OnSave(string fileName, Action writer);
+
+ private static Stream GetResourceStream(string resourceName)
+ {
+ resourceName = "Jellyfish.Virtu." + resourceName.Replace('/', '.');
+ var resourceStream = typeof(StorageService).Assembly.GetManifestResourceStream(resourceName);
+ if (resourceStream == null)
+ {
+ throw new FileNotFoundException(string.Format(CultureInfo.CurrentUICulture, Strings.ResourceNotFound, resourceName));
+ }
+
+ return resourceStream;
+ }
+ }
+}
diff --git a/Virtu/Services/VideoService.cs b/Virtu/Services/VideoService.cs
index 43a81ae..79ae914 100644
--- a/Virtu/Services/VideoService.cs
+++ b/Virtu/Services/VideoService.cs
@@ -1,17 +1,17 @@
-namespace Jellyfish.Virtu.Services
-{
- public abstract class VideoService : MachineService
- {
- protected VideoService(Machine machine) :
- base(machine)
- {
- }
-
- public virtual void SetFullScreen(bool isFullScreen)
- {
- }
-
- public abstract void SetPixel(int x, int y, uint color);
- public abstract void Update(); // main thread
- }
-}
+namespace Jellyfish.Virtu.Services
+{
+ public abstract class VideoService : MachineService
+ {
+ protected VideoService(Machine machine) :
+ base(machine)
+ {
+ }
+
+ public virtual void SetFullScreen(bool isFullScreen)
+ {
+ }
+
+ public abstract void SetPixel(int x, int y, uint color);
+ public abstract void Update(); // main thread
+ }
+}
diff --git a/Virtu/Silverlight/Jellyfish.Virtu.Silverlight.csproj b/Virtu/Silverlight/Jellyfish.Virtu.Silverlight.csproj
index ad452db..1b5f39d 100644
--- a/Virtu/Silverlight/Jellyfish.Virtu.Silverlight.csproj
+++ b/Virtu/Silverlight/Jellyfish.Virtu.Silverlight.csproj
@@ -1,270 +1,270 @@
-
-
-
- Debug
- AnyCPU
- 8.0.50727
- 2.0
- {F8DB6D3A-807D-4E2D-92D5-469273E088DA}
- {A1591282-1198-4647-A2B1-27E5FF5F6F3B};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}
- Library
- Properties
- Jellyfish.Virtu
- Jellyfish.Virtu
- Silverlight
- v5.0
-
- $(TargetFrameworkVersion)
- true
-
-
- true
- true
- Jellyfish.Virtu.xap
- Properties\AppManifest.xml
- Jellyfish.Virtu.MainApp
- Jellyfish.Virtu.html
- true
- true
- true
- Properties\OutOfBrowserSettings.xml
- false
- true
-
-
-
-
-
- v3.5
-
-
- true
- full
- false
- bin\
- DEBUG;TRACE;SILVERLIGHT;CODE_ANALYSIS
- true
- true
- prompt
- 4
- true
- AllRules.ruleset
- false
-
-
- pdbonly
- true
- bin\
- TRACE;SILVERLIGHT;CODE_ANALYSIS
- true
- true
- prompt
- 4
- true
- AllRules.ruleset
- false
-
-
- false
-
-
- ..\..\..\Jellyfish\StrongName.snk
-
-
- false
-
-
- http://timestamp.verisign.com/scripts/timestamp.dll
-
-
- 7E57BBFFA7D9A57530AC8A09E5236FE0AAB041C2
-
-
- ..\..\..\Jellyfish\CodeSign.pfx
-
-
-
-
-
-
-
-
-
-
-
-
-
- Designer
- MSBuild:Compile
-
-
- Designer
- MSBuild:Compile
-
-
- MainApp.xaml
-
-
- MainPage.xaml
-
-
-
-
- Core\Cassette.cs
-
-
- Core\Cpu.cs
-
-
- Core\CpuData.cs
-
-
- Core\Disk525.cs
-
-
- Core\DiskDsk.cs
-
-
- Core\DiskIIController.cs
-
-
- Core\DiskIIDrive.cs
-
-
- Core\DiskNib.cs
-
-
- Core\GamePort.cs
-
-
- GlobalSuppressions.cs
-
-
- Core\Keyboard.cs
-
-
- Core\Machine.cs
-
-
- Core\MachineComponent.cs
-
-
- Core\MachineEvents.cs
-
-
- Core\Memory.cs
-
-
- Core\MemoryData.cs
-
-
- Core\NoSlotClock.cs
-
-
- Core\PeripheralCard.cs
-
-
- Properties\Strings.Designer.cs
- True
- True
- Strings.resx
-
-
- Services\AudioService.cs
-
-
- Services\DebugService.cs
-
-
- Services\GamePortService.cs
-
-
- Services\IsolatedStorageService.cs
-
-
- Services\KeyboardService.cs
-
-
- Services\MachineService.cs
-
-
- Services\MachineServices.cs
-
-
- Services\StorageService.cs
-
-
- Services\VideoService.cs
-
-
- Core\Speaker.cs
-
-
- Core\Video.cs
-
-
- Core\VideoData.cs
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties\Strings.resx
- ResXFileCodeGenerator
- Strings.Designer.cs
-
-
-
-
- Disks\Default.dsk
-
-
- Roms\AppleIIe.rom
-
-
- Roms\DiskII.rom
-
-
-
-
- CustomDictionary.xml
-
-
-
-
- {99CA7796-B72A-4F8C-BCDB-0D688220A331}
- Jellyfish.Library.Silverlight
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Debug
+ AnyCPU
+ 8.0.50727
+ 2.0
+ {F8DB6D3A-807D-4E2D-92D5-469273E088DA}
+ {A1591282-1198-4647-A2B1-27E5FF5F6F3B};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}
+ Library
+ Properties
+ Jellyfish.Virtu
+ Jellyfish.Virtu
+ Silverlight
+ v5.0
+
+ $(TargetFrameworkVersion)
+ true
+
+
+ true
+ true
+ Jellyfish.Virtu.xap
+ Properties\AppManifest.xml
+ Jellyfish.Virtu.MainApp
+ Jellyfish.Virtu.html
+ true
+ true
+ true
+ Properties\OutOfBrowserSettings.xml
+ false
+ true
+
+
+
+
+
+ v3.5
+
+
+ true
+ full
+ false
+ bin\
+ DEBUG;TRACE;SILVERLIGHT;CODE_ANALYSIS
+ true
+ true
+ prompt
+ 4
+ true
+ AllRules.ruleset
+ false
+
+
+ pdbonly
+ true
+ bin\
+ TRACE;SILVERLIGHT;CODE_ANALYSIS
+ true
+ true
+ prompt
+ 4
+ true
+ AllRules.ruleset
+ false
+
+
+ false
+
+
+ ..\..\..\Jellyfish\StrongName.snk
+
+
+ false
+
+
+ http://timestamp.verisign.com/scripts/timestamp.dll
+
+
+ 7E57BBFFA7D9A57530AC8A09E5236FE0AAB041C2
+
+
+ ..\..\..\Jellyfish\CodeSign.pfx
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
+
+ MainApp.xaml
+
+
+ MainPage.xaml
+
+
+
+
+ Core\Cassette.cs
+
+
+ Core\Cpu.cs
+
+
+ Core\CpuData.cs
+
+
+ Core\Disk525.cs
+
+
+ Core\DiskDsk.cs
+
+
+ Core\DiskIIController.cs
+
+
+ Core\DiskIIDrive.cs
+
+
+ Core\DiskNib.cs
+
+
+ Core\GamePort.cs
+
+
+ GlobalSuppressions.cs
+
+
+ Core\Keyboard.cs
+
+
+ Core\Machine.cs
+
+
+ Core\MachineComponent.cs
+
+
+ Core\MachineEvents.cs
+
+
+ Core\Memory.cs
+
+
+ Core\MemoryData.cs
+
+
+ Core\NoSlotClock.cs
+
+
+ Core\PeripheralCard.cs
+
+
+ Properties\Strings.Designer.cs
+ True
+ True
+ Strings.resx
+
+
+ Services\AudioService.cs
+
+
+ Services\DebugService.cs
+
+
+ Services\GamePortService.cs
+
+
+ Services\IsolatedStorageService.cs
+
+
+ Services\KeyboardService.cs
+
+
+ Services\MachineService.cs
+
+
+ Services\MachineServices.cs
+
+
+ Services\StorageService.cs
+
+
+ Services\VideoService.cs
+
+
+ Core\Speaker.cs
+
+
+ Core\Video.cs
+
+
+ Core\VideoData.cs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Properties\Strings.resx
+ ResXFileCodeGenerator
+ Strings.Designer.cs
+
+
+
+
+ Disks\Default.dsk
+
+
+ Roms\AppleIIe.rom
+
+
+ Roms\DiskII.rom
+
+
+
+
+ CustomDictionary.xml
+
+
+
+
+ {99CA7796-B72A-4F8C-BCDB-0D688220A331}
+ Jellyfish.Library.Silverlight
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Virtu/Silverlight/Jellyfish.Virtu.Silverlight.sln b/Virtu/Silverlight/Jellyfish.Virtu.Silverlight.sln
index 0a356c6..e4fada1 100644
--- a/Virtu/Silverlight/Jellyfish.Virtu.Silverlight.sln
+++ b/Virtu/Silverlight/Jellyfish.Virtu.Silverlight.sln
@@ -1,26 +1,26 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2012
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Library.Silverlight", "..\..\Library\Silverlight\Jellyfish.Library.Silverlight.csproj", "{99CA7796-B72A-4F8C-BCDB-0D688220A331}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Virtu.Silverlight", "Jellyfish.Virtu.Silverlight.csproj", "{F8DB6D3A-807D-4E2D-92D5-469273E088DA}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {99CA7796-B72A-4F8C-BCDB-0D688220A331}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {99CA7796-B72A-4F8C-BCDB-0D688220A331}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {99CA7796-B72A-4F8C-BCDB-0D688220A331}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {99CA7796-B72A-4F8C-BCDB-0D688220A331}.Release|Any CPU.Build.0 = Release|Any CPU
- {F8DB6D3A-807D-4E2D-92D5-469273E088DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {F8DB6D3A-807D-4E2D-92D5-469273E088DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {F8DB6D3A-807D-4E2D-92D5-469273E088DA}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {F8DB6D3A-807D-4E2D-92D5-469273E088DA}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Library.Silverlight", "..\..\Library\Silverlight\Jellyfish.Library.Silverlight.csproj", "{99CA7796-B72A-4F8C-BCDB-0D688220A331}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Virtu.Silverlight", "Jellyfish.Virtu.Silverlight.csproj", "{F8DB6D3A-807D-4E2D-92D5-469273E088DA}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {99CA7796-B72A-4F8C-BCDB-0D688220A331}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {99CA7796-B72A-4F8C-BCDB-0D688220A331}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {99CA7796-B72A-4F8C-BCDB-0D688220A331}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {99CA7796-B72A-4F8C-BCDB-0D688220A331}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F8DB6D3A-807D-4E2D-92D5-469273E088DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F8DB6D3A-807D-4E2D-92D5-469273E088DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F8DB6D3A-807D-4E2D-92D5-469273E088DA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F8DB6D3A-807D-4E2D-92D5-469273E088DA}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Virtu/Silverlight/MainApp.xaml b/Virtu/Silverlight/MainApp.xaml
index 1cecb66..6178bd4 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 68119d8..a13a6b2 100644
--- a/Virtu/Silverlight/MainApp.xaml.cs
+++ b/Virtu/Silverlight/MainApp.xaml.cs
@@ -1,14 +1,14 @@
-using Jellyfish.Library;
-
-namespace Jellyfish.Virtu
-{
- public sealed partial class MainApp : ApplicationBase
- {
- public MainApp() :
- base("Virtu")
- {
- InitializeComponent();
- InitializeOutOfBrowserUpdate();
- }
- }
-}
+using Jellyfish.Library;
+
+namespace Jellyfish.Virtu
+{
+ public sealed partial class MainApp : ApplicationBase
+ {
+ public MainApp() :
+ base("Virtu")
+ {
+ InitializeComponent();
+ InitializeOutOfBrowserUpdate();
+ }
+ }
+}
diff --git a/Virtu/Silverlight/MainPage.xaml b/Virtu/Silverlight/MainPage.xaml
index 26ce27a..adb677c 100644
--- a/Virtu/Silverlight/MainPage.xaml
+++ b/Virtu/Silverlight/MainPage.xaml
@@ -1,23 +1,23 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Virtu/Silverlight/MainPage.xaml.cs b/Virtu/Silverlight/MainPage.xaml.cs
index e6461c3..cae3e8a 100644
--- a/Virtu/Silverlight/MainPage.xaml.cs
+++ b/Virtu/Silverlight/MainPage.xaml.cs
@@ -1,87 +1,87 @@
-using System;
-using System.ComponentModel;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Media;
-using Jellyfish.Virtu.Services;
-
-namespace Jellyfish.Virtu
-{
- public sealed partial class MainPage : UserControl, IDisposable
- {
- public MainPage()
- {
- InitializeComponent();
-
- if (!DesignerProperties.IsInDesignTool)
- {
- _debugService = DebugService.Default;
- _storageService = new IsolatedStorageService(_machine);
- _keyboardService = new SilverlightKeyboardService(_machine, this);
- _gamePortService = new GamePortService(_machine); // not connected
- _audioService = new SilverlightAudioService(_machine, this, _media);
- _videoService = new SilverlightVideoService(_machine, this, _image);
-
- _machine.Services.AddService(typeof(DebugService), _debugService);
- _machine.Services.AddService(typeof(StorageService), _storageService);
- _machine.Services.AddService(typeof(KeyboardService), _keyboardService);
- _machine.Services.AddService(typeof(GamePortService), _gamePortService);
- _machine.Services.AddService(typeof(AudioService), _audioService);
- _machine.Services.AddService(typeof(VideoService), _videoService);
-
- Loaded += (sender, e) => _machine.Start();
- CompositionTarget.Rendering += OnCompositionTargetRendering;
- Application.Current.Exit += (sender, e) => _machine.Stop();
-
- _disk1Button.Click += (sender, e) => OnDiskButtonClick(0);
- _disk2Button.Click += (sender, e) => OnDiskButtonClick(1);
- }
- }
-
- public void Dispose()
- {
- _machine.Dispose();
- _debugService.Dispose();
- _storageService.Dispose();
- _keyboardService.Dispose();
- _gamePortService.Dispose();
- _audioService.Dispose();
- _videoService.Dispose();
- }
-
- public void WriteMessage(string message)
- {
- _debugText.Text += message + Environment.NewLine;
- _debugScrollViewer.UpdateLayout();
- _debugScrollViewer.ScrollToVerticalOffset(double.MaxValue);
- }
-
- private void OnCompositionTargetRendering(object sender, EventArgs e)
- {
- _keyboardService.Update();
- _gamePortService.Update();
- _videoService.Update();
- }
-
- private void OnDiskButtonClick(int drive)
- {
- var dialog = new OpenFileDialog() { Filter = "Disk Files (*.do;*.dsk;*.nib;*.po)|*.do;*.dsk;*.nib;*.po|All Files (*.*)|*.*" };
- bool? result = dialog.ShowDialog();
- if (result.HasValue && result.Value)
- {
- _machine.Pause();
- StorageService.LoadFile(dialog.File, stream => _machine.BootDiskII.Drives[drive].InsertDisk(dialog.File.Name, stream, false));
- _machine.Unpause();
- }
- }
-
- private Machine _machine = new Machine();
-
- private DebugService _debugService;
- private StorageService _storageService;
- private KeyboardService _keyboardService;
- private GamePortService _gamePortService;
- private AudioService _audioService;
- private VideoService _videoService;
- }
-}
+using System;
+using System.ComponentModel;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+using Jellyfish.Virtu.Services;
+
+namespace Jellyfish.Virtu
+{
+ public sealed partial class MainPage : UserControl, IDisposable
+ {
+ public MainPage()
+ {
+ InitializeComponent();
+
+ if (!DesignerProperties.IsInDesignTool)
+ {
+ _debugService = DebugService.Default;
+ _storageService = new IsolatedStorageService(_machine);
+ _keyboardService = new SilverlightKeyboardService(_machine, this);
+ _gamePortService = new GamePortService(_machine); // not connected
+ _audioService = new SilverlightAudioService(_machine, this, _media);
+ _videoService = new SilverlightVideoService(_machine, this, _image);
+
+ _machine.Services.AddService(typeof(DebugService), _debugService);
+ _machine.Services.AddService(typeof(StorageService), _storageService);
+ _machine.Services.AddService(typeof(KeyboardService), _keyboardService);
+ _machine.Services.AddService(typeof(GamePortService), _gamePortService);
+ _machine.Services.AddService(typeof(AudioService), _audioService);
+ _machine.Services.AddService(typeof(VideoService), _videoService);
+
+ Loaded += (sender, e) => _machine.Start();
+ CompositionTarget.Rendering += OnCompositionTargetRendering;
+ Application.Current.Exit += (sender, e) => _machine.Stop();
+
+ _disk1Button.Click += (sender, e) => OnDiskButtonClick(0);
+ _disk2Button.Click += (sender, e) => OnDiskButtonClick(1);
+ }
+ }
+
+ public void Dispose()
+ {
+ _machine.Dispose();
+ _debugService.Dispose();
+ _storageService.Dispose();
+ _keyboardService.Dispose();
+ _gamePortService.Dispose();
+ _audioService.Dispose();
+ _videoService.Dispose();
+ }
+
+ public void WriteMessage(string message)
+ {
+ _debugText.Text += message + Environment.NewLine;
+ _debugScrollViewer.UpdateLayout();
+ _debugScrollViewer.ScrollToVerticalOffset(double.MaxValue);
+ }
+
+ private void OnCompositionTargetRendering(object sender, EventArgs e)
+ {
+ _keyboardService.Update();
+ _gamePortService.Update();
+ _videoService.Update();
+ }
+
+ private void OnDiskButtonClick(int drive)
+ {
+ var dialog = new OpenFileDialog() { Filter = "Disk Files (*.do;*.dsk;*.nib;*.po)|*.do;*.dsk;*.nib;*.po|All Files (*.*)|*.*" };
+ bool? result = dialog.ShowDialog();
+ if (result.HasValue && result.Value)
+ {
+ _machine.Pause();
+ StorageService.LoadFile(dialog.File, stream => _machine.BootDiskII.Drives[drive].InsertDisk(dialog.File.Name, stream, false));
+ _machine.Unpause();
+ }
+ }
+
+ private Machine _machine = new Machine();
+
+ private DebugService _debugService;
+ private StorageService _storageService;
+ private KeyboardService _keyboardService;
+ private GamePortService _gamePortService;
+ private AudioService _audioService;
+ private VideoService _videoService;
+ }
+}
diff --git a/Virtu/Silverlight/Properties/AppManifest.xml b/Virtu/Silverlight/Properties/AppManifest.xml
index 8bcc1ca..8eaa335 100644
--- a/Virtu/Silverlight/Properties/AppManifest.xml
+++ b/Virtu/Silverlight/Properties/AppManifest.xml
@@ -1,5 +1,5 @@
-
-
-
-
+
+
+
+
diff --git a/Virtu/Silverlight/Properties/AssemblyInfo.cs b/Virtu/Silverlight/Properties/AssemblyInfo.cs
index 037c342..2b97014 100644
--- a/Virtu/Silverlight/Properties/AssemblyInfo.cs
+++ b/Virtu/Silverlight/Properties/AssemblyInfo.cs
@@ -1,23 +1,23 @@
-using System;
-using System.Reflection;
-using System.Resources;
-using System.Runtime.InteropServices;
-using Jellyfish.Library;
-using Jellyfish.Virtu;
-
-[assembly: AssemblyTitle("Virtu")]
-[assembly: AssemblyDescription("Apple IIe Emulator")]
-[assembly: AssemblyProduct("Jellyfish.Virtu.Silverlight")]
-[assembly: AssemblyCompany("Digital Jellyfish Design Ltd")]
-[assembly: AssemblyCopyright("Copyright © 1995-2012 Digital Jellyfish Design Ltd")]
-[assembly: AssemblyMetadata("Developers", "Sean Fausett & Nick Westgate")]
-
-[assembly: AssemblyVersion(Machine.Version)]
-[assembly: AssemblyFileVersion(Machine.Version)]
-[assembly: AssemblyInformationalVersion(Machine.Version)]
-
-[assembly: CLSCompliant(false)]
-[assembly: ComVisible(false)]
-[assembly: Guid("89a50370-1ed9-4cf1-ad08-043b6e6f3c90")]
-
-[assembly: NeutralResourcesLanguage("en")]
+using System;
+using System.Reflection;
+using System.Resources;
+using System.Runtime.InteropServices;
+using Jellyfish.Library;
+using Jellyfish.Virtu;
+
+[assembly: AssemblyTitle("Virtu")]
+[assembly: AssemblyDescription("Apple IIe Emulator")]
+[assembly: AssemblyProduct("Jellyfish.Virtu.Silverlight")]
+[assembly: AssemblyCompany("Digital Jellyfish Design Ltd")]
+[assembly: AssemblyCopyright("Copyright © 1995-2012 Digital Jellyfish Design Ltd")]
+[assembly: AssemblyMetadata("Developers", "Sean Fausett & Nick Westgate")]
+
+[assembly: AssemblyVersion(Machine.Version)]
+[assembly: AssemblyFileVersion(Machine.Version)]
+[assembly: AssemblyInformationalVersion(Machine.Version)]
+
+[assembly: CLSCompliant(false)]
+[assembly: ComVisible(false)]
+[assembly: Guid("89a50370-1ed9-4cf1-ad08-043b6e6f3c90")]
+
+[assembly: NeutralResourcesLanguage("en")]
diff --git a/Virtu/Silverlight/Properties/OutOfBrowserSettings.xml b/Virtu/Silverlight/Properties/OutOfBrowserSettings.xml
index 5d296c4..cacb8f7 100644
--- a/Virtu/Silverlight/Properties/OutOfBrowserSettings.xml
+++ b/Virtu/Silverlight/Properties/OutOfBrowserSettings.xml
@@ -1,15 +1,15 @@
-
- Apple IIe Emulator
-
-
-
-
-
-
-
- AppIcon16.png
- AppIcon32.png
- AppIcon48.png
- AppIcon128.png
-
+
+ Apple IIe Emulator
+
+
+
+
+
+
+
+ AppIcon16.png
+ AppIcon32.png
+ AppIcon48.png
+ AppIcon128.png
+
\ No newline at end of file
diff --git a/Virtu/Silverlight/Services/SilverlightAudioService.cs b/Virtu/Silverlight/Services/SilverlightAudioService.cs
index c64f4e4..f8b7cf7 100644
--- a/Virtu/Silverlight/Services/SilverlightAudioService.cs
+++ b/Virtu/Silverlight/Services/SilverlightAudioService.cs
@@ -1,59 +1,59 @@
-using System;
-using System.Windows.Controls;
-using Jellyfish.Library;
-
-namespace Jellyfish.Virtu.Services
-{
- public sealed class SilverlightAudioService : AudioService
- {
- public SilverlightAudioService(Machine machine, UserControl page, MediaElement media) :
- base(machine)
- {
- if (page == null)
- {
- throw new ArgumentNullException("page");
- }
- if (media == null)
- {
- throw new ArgumentNullException("media");
- }
-
- _media = media;
- _mediaSource = new WaveMediaStreamSource(SampleRate, SampleChannels, SampleBits, SampleSize, SampleLatency, OnMediaSourceUpdate);
- _media.SetSource(_mediaSource);
-
- page.Loaded += (sender, e) => _media.Play();
- page.Unloaded += (sender, e) => _media.Stop();
- }
-
- public override void SetVolume(float volume)
- {
- _media.Dispatcher.Send(() => _media.Volume = volume);
- }
-
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- {
- _mediaSource.Dispose();
- }
-
- base.Dispose(disposing);
- }
-
- private void OnMediaSourceUpdate(byte[] buffer, int bufferSize) // audio thread
- {
- //if (_count++ % (1000 / SampleLatency) == 0)
- //{
- // DebugService.WriteLine("OnMediaSourceUpdate");
- //}
-
- Buffer.BlockCopy(Source, 0, buffer, 0, bufferSize);
- Update();
- }
-
- private MediaElement _media;
- private WaveMediaStreamSource _mediaSource;
- //private int _count;
- }
-}
+using System;
+using System.Windows.Controls;
+using Jellyfish.Library;
+
+namespace Jellyfish.Virtu.Services
+{
+ public sealed class SilverlightAudioService : AudioService
+ {
+ public SilverlightAudioService(Machine machine, UserControl page, MediaElement media) :
+ base(machine)
+ {
+ if (page == null)
+ {
+ throw new ArgumentNullException("page");
+ }
+ if (media == null)
+ {
+ throw new ArgumentNullException("media");
+ }
+
+ _media = media;
+ _mediaSource = new WaveMediaStreamSource(SampleRate, SampleChannels, SampleBits, SampleSize, SampleLatency, OnMediaSourceUpdate);
+ _media.SetSource(_mediaSource);
+
+ page.Loaded += (sender, e) => _media.Play();
+ page.Unloaded += (sender, e) => _media.Stop();
+ }
+
+ public override void SetVolume(float volume)
+ {
+ _media.Dispatcher.Send(() => _media.Volume = volume);
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ _mediaSource.Dispose();
+ }
+
+ base.Dispose(disposing);
+ }
+
+ private void OnMediaSourceUpdate(byte[] buffer, int bufferSize) // audio thread
+ {
+ //if (_count++ % (1000 / SampleLatency) == 0)
+ //{
+ // DebugService.WriteLine("OnMediaSourceUpdate");
+ //}
+
+ Buffer.BlockCopy(Source, 0, buffer, 0, bufferSize);
+ Update();
+ }
+
+ private MediaElement _media;
+ private WaveMediaStreamSource _mediaSource;
+ //private int _count;
+ }
+}
diff --git a/Virtu/Silverlight/Services/SilverlightDebugService.cs b/Virtu/Silverlight/Services/SilverlightDebugService.cs
index 4e187ea..cb33f11 100644
--- a/Virtu/Silverlight/Services/SilverlightDebugService.cs
+++ b/Virtu/Silverlight/Services/SilverlightDebugService.cs
@@ -1,26 +1,26 @@
-using System;
-using Jellyfish.Library;
-
-namespace Jellyfish.Virtu.Services
-{
- public sealed class SilverlightDebugService : DebugService
- {
- public SilverlightDebugService(Machine machine, MainPage page) :
- base(machine)
- {
- if (page == null)
- {
- throw new ArgumentNullException("page");
- }
-
- _page = page;
- }
-
- protected override void OnWriteMessage(string message)
- {
- _page.Dispatcher.Post(() => _page.WriteMessage(message));
- }
-
- private MainPage _page;
- }
-}
+using System;
+using Jellyfish.Library;
+
+namespace Jellyfish.Virtu.Services
+{
+ public sealed class SilverlightDebugService : DebugService
+ {
+ public SilverlightDebugService(Machine machine, MainPage page) :
+ base(machine)
+ {
+ if (page == null)
+ {
+ throw new ArgumentNullException("page");
+ }
+
+ _page = page;
+ }
+
+ protected override void OnWriteMessage(string message)
+ {
+ _page.Dispatcher.Post(() => _page.WriteMessage(message));
+ }
+
+ private MainPage _page;
+ }
+}
diff --git a/Virtu/Silverlight/Services/SilverlightKeyboardService.cs b/Virtu/Silverlight/Services/SilverlightKeyboardService.cs
index 208ed41..c923336 100644
--- a/Virtu/Silverlight/Services/SilverlightKeyboardService.cs
+++ b/Virtu/Silverlight/Services/SilverlightKeyboardService.cs
@@ -1,401 +1,401 @@
-using System;
-using System.Diagnostics.CodeAnalysis;
-using System.Linq;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Input;
-
-namespace Jellyfish.Virtu.Services
-{
- public sealed class SilverlightKeyboardService : KeyboardService
- {
- public SilverlightKeyboardService(Machine machine, UserControl page) :
- base(machine)
- {
- if (page == null)
- {
- throw new ArgumentNullException("page");
- }
-
- page.KeyDown += OnPageKeyDown;
- page.KeyUp += OnPageKeyUp;
- page.LostFocus += OnPageLostFocus;
- }
-
- public override bool IsKeyDown(int key)
- {
- return IsKeyDown((Key)key);
- }
-
- public override void Update() // main thread
- {
- if (_updateAnyKeyDown) // SL is missing access to keyboard state; could lose track of keyboard state after Alt+Tab
- {
- _updateAnyKeyDown = false;
- IsAnyKeyDown = false;
- for (int i = 0; i < KeyValues.Length; i++)
- {
- if (IsKeyDown(KeyValues[i]))
- {
- IsAnyKeyDown = true;
- break;
- }
- }
- }
-
- var modifiers = System.Windows.Input.Keyboard.Modifiers;
- IsControlKeyDown = ((modifiers & ModifierKeys.Control) != 0);
- IsShiftKeyDown = ((modifiers & ModifierKeys.Shift) != 0);
-
- IsOpenAppleKeyDown = ((modifiers & ModifierKeys.Alt) != 0) || IsKeyDown(Key.NumPad0);
- IsCloseAppleKeyDown = ((modifiers & ModifierKeys.Windows) != 0) || IsKeyDown(Key.Decimal);
- IsResetKeyDown = IsControlKeyDown && IsKeyDown(Key.Back);
-
- base.Update();
- }
-
- private bool IsKeyDown(Key key)
- {
- return _states[(int)key];
- }
-
- private void OnPageKeyDown(object sender, KeyEventArgs e)
- {
- //DebugService.WriteLine(string.Concat("OnPageKeyDn: Key=", e.Key, " PlatformKeyCode=", e.PlatformKeyCode));
-
- _states[(int)e.Key] = true;
- _updateAnyKeyDown = false;
- IsAnyKeyDown = true;
-
- int asciiKey = GetAsciiKey(e.Key, e.PlatformKeyCode);
- if (asciiKey >= 0)
- {
- Machine.Keyboard.Latch = asciiKey;
- e.Handled = true;
- }
-
- Update();
- }
-
- private void OnPageKeyUp(object sender, KeyEventArgs e)
- {
- //DebugService.WriteLine(string.Concat("OnPageKeyUp: Key=", e.Key, " PlatformKeyCode=", e.PlatformKeyCode));
-
- _states[(int)e.Key] = false;
- _updateAnyKeyDown = true;
-
- var modifiers = System.Windows.Input.Keyboard.Modifiers;
- bool control = ((modifiers & ModifierKeys.Control) != 0);
-
- if (e.Key == Key.CapsLock)
- {
- _capsLock ^= true; // SL is missing caps lock support; try to track manually
- }
- else if (control && (e.Key == Key.Divide))
- {
- Machine.Cpu.IsThrottled ^= true;
- }
- else if (control && (e.Key == Key.Multiply))
- {
- Machine.Video.IsMonochrome ^= true;
- }
- else if (control && (e.Key == Key.Subtract))
- {
- Machine.Video.IsFullScreen ^= true;
- }
- Update();
- }
-
- private void OnPageLostFocus(object sender, RoutedEventArgs e) // reset keyboard state on lost focus; can't access keyboard state on got focus
- {
- IsAnyKeyDown = false;
- for (int i = 0; i < KeyValues.Length; i++)
- {
- _states[(int)KeyValues[i]] = false;
- }
- }
-
- [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
- [SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode")]
- private int GetAsciiKey(Key key, int platformKeyCode)
- {
- var modifiers = System.Windows.Input.Keyboard.Modifiers;
- bool control = ((modifiers & ModifierKeys.Control) != 0);
- bool shift = ((modifiers & ModifierKeys.Shift) != 0);
- bool capsLock = shift ^ _capsLock;
-
- switch (key)
- {
- case Key.Left:
- return 0x08;
-
- case Key.Tab:
- return 0x09;
-
- case Key.Down:
- return 0x0A;
-
- case Key.Up:
- return 0x0B;
-
- case Key.Enter:
- return 0x0D;
-
- case Key.Right:
- return 0x15;
-
- case Key.Escape:
- return 0x1B;
-
- case Key.Back:
- return control ? -1 : 0x7F;
-
- case Key.Space:
- return ' ';
-
- case Key.D1:
- return shift ? '!' : '1';
-
- case Key.D2:
- return control ? 0x00 : shift ? '@' : '2';
-
- case Key.D3:
- return shift ? '#' : '3';
-
- case Key.D4:
- return shift ? '$' : '4';
-
- case Key.D5:
- return shift ? '%' : '5';
-
- case Key.D6:
- return control ? 0x1E : shift ? '^' : '6';
-
- case Key.D7:
- return shift ? '&' : '7';
-
- case Key.D8:
- return shift ? '*' : '8';
-
- case Key.D9:
- return shift ? '(' : '9';
-
- case Key.D0:
- return shift ? ')' : '0';
-
- case Key.A:
- return control ? 0x01 : capsLock ? 'A' : 'a';
-
- case Key.B:
- return control ? 0x02 : capsLock ? 'B' : 'b';
-
- case Key.C:
- return control ? 0x03 : capsLock ? 'C' : 'c';
-
- case Key.D:
- return control ? 0x04 : capsLock ? 'D' : 'd';
-
- case Key.E:
- return control ? 0x05 : capsLock ? 'E' : 'e';
-
- case Key.F:
- return control ? 0x06 : capsLock ? 'F' : 'f';
-
- case Key.G:
- return control ? 0x07 : capsLock ? 'G' : 'g';
-
- case Key.H:
- return control ? 0x08 : capsLock ? 'H' : 'h';
-
- case Key.I:
- return control ? 0x09 : capsLock ? 'I' : 'i';
-
- case Key.J:
- return control ? 0x0A : capsLock ? 'J' : 'j';
-
- case Key.K:
- return control ? 0x0B : capsLock ? 'K' : 'k';
-
- case Key.L:
- return control ? 0x0C : capsLock ? 'L' : 'l';
-
- case Key.M:
- return control ? 0x0D : capsLock ? 'M' : 'm';
-
- case Key.N:
- return control ? 0x0E : capsLock ? 'N' : 'n';
-
- case Key.O:
- return control ? 0x0F : capsLock ? 'O' : 'o';
-
- case Key.P:
- return control ? 0x10 : capsLock ? 'P' : 'p';
-
- case Key.Q:
- return control ? 0x11 : capsLock ? 'Q' : 'q';
-
- case Key.R:
- return control ? 0x12 : capsLock ? 'R' : 'r';
-
- case Key.S:
- return control ? 0x13 : capsLock ? 'S' : 's';
-
- case Key.T:
- return control ? 0x14 : capsLock ? 'T' : 't';
-
- case Key.U:
- return control ? 0x15 : capsLock ? 'U' : 'u';
-
- case Key.V:
- return control ? 0x16 : capsLock ? 'V' : 'v';
-
- case Key.W:
- return control ? 0x17 : capsLock ? 'W' : 'w';
-
- case Key.X:
- return control ? 0x18 : capsLock ? 'X' : 'x';
-
- case Key.Y:
- return control ? 0x19 : capsLock ? 'Y' : 'y';
-
- case Key.Z:
- return control ? 0x1A : capsLock ? 'Z' : 'z';
-
- case Key.Unknown:
- switch (Environment.OSVersion.Platform)
- {
- case PlatformID.Win32NT:
- switch (platformKeyCode)
- {
- case 0xBA: // WinForms Keys.Oem1
- return shift ? ':' : ';';
-
- case 0xBF: // WinForms Keys.Oem2
- return shift ? '?' : '/';
-
- case 0xC0: // WinForms Keys.Oem3
- return shift ? '~' : '`';
-
- case 0xDB: // WinForms Keys.Oem4
- return shift ? '{' : '[';
-
- case 0xDC: // WinForms Keys.Oem5
- return control ? 0x1C : shift ? '|' : '\\';
-
- case 0xDD: // WinForms Keys.Oem6
- return control ? 0x1D : shift ? '}' : ']';
-
- case 0xDE: // WinForms Keys.Oem7
- return shift ? '"' : '\'';
-
- case 0xBD: // WinForms Keys.OemMinus
- return control ? 0x1F : shift ? '_' : '-';
-
- case 0xBB: // WinForms Keys.OemPlus
- return shift ? '+' : '=';
-
- case 0xBC: // WinForms Keys.OemComma
- return shift ? '<' : ',';
-
- case 0xBE: // WinForms Keys.OemPeriod
- return shift ? '>' : '.';
- }
- break;
-
- case PlatformID.MacOSX:
- switch (platformKeyCode)
- {
- case 0x29:
- return shift ? ':' : ';';
-
- case 0x2C:
- return shift ? '?' : '/';
-
- case 0x32:
- return shift ? '~' : '`';
-
- case 0x21:
- return shift ? '{' : '[';
-
- case 0x2A:
- return control ? 0x1C : shift ? '|' : '\\';
-
- case 0x1E:
- return control ? 0x1D : shift ? '}' : ']';
-
- case 0x27:
- return shift ? '"' : '\'';
-
- case 0x1B:
- return control ? 0x1F : shift ? '_' : '-';
-
- case 0x18:
- return shift ? '+' : '=';
-
- case 0x2B:
- return shift ? '<' : ',';
-
- case 0x2F:
- return shift ? '>' : '.';
- }
- break;
-
- case PlatformID.Unix:
- switch (platformKeyCode)
- {
- case 0x2F:
- return shift ? ':' : ';';
-
- case 0x3D:
- return shift ? '?' : '/';
-
- case 0x31:
- return shift ? '~' : '`';
-
- case 0x22:
- return shift ? '{' : '[';
-
- case 0x33:
- return control ? 0x1C : shift ? '|' : '\\';
-
- case 0x23:
- return control ? 0x1D : shift ? '}' : ']';
-
- case 0x30:
- return shift ? '"' : '\'';
-
- case 0x14:
- return control ? 0x1F : shift ? '_' : '-';
-
- case 0x15:
- return shift ? '+' : '=';
-
- case 0x3B:
- return shift ? '<' : ',';
-
- case 0x3C:
- return shift ? '>' : '.';
- }
- break;
- }
- break;
- }
-
- return -1;
- }
-
- private static readonly Key[] KeyValues =
- (from key in
- (from field in typeof(Key).GetFields() // missing Enum.GetValues; use reflection
- where field.IsLiteral
- select (Key)field.GetValue(typeof(Key)))
- where (key != Key.None) // filter Key.None
- select key).ToArray();
-
- private static readonly int KeyCount = (int)(KeyValues.Max()) + 1;
-
- private bool[] _states = new bool[KeyCount];
- private bool _capsLock;
- private bool _updateAnyKeyDown;
- }
-}
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+
+namespace Jellyfish.Virtu.Services
+{
+ public sealed class SilverlightKeyboardService : KeyboardService
+ {
+ public SilverlightKeyboardService(Machine machine, UserControl page) :
+ base(machine)
+ {
+ if (page == null)
+ {
+ throw new ArgumentNullException("page");
+ }
+
+ page.KeyDown += OnPageKeyDown;
+ page.KeyUp += OnPageKeyUp;
+ page.LostFocus += OnPageLostFocus;
+ }
+
+ public override bool IsKeyDown(int key)
+ {
+ return IsKeyDown((Key)key);
+ }
+
+ public override void Update() // main thread
+ {
+ if (_updateAnyKeyDown) // SL is missing access to keyboard state; could lose track of keyboard state after Alt+Tab
+ {
+ _updateAnyKeyDown = false;
+ IsAnyKeyDown = false;
+ for (int i = 0; i < KeyValues.Length; i++)
+ {
+ if (IsKeyDown(KeyValues[i]))
+ {
+ IsAnyKeyDown = true;
+ break;
+ }
+ }
+ }
+
+ var modifiers = System.Windows.Input.Keyboard.Modifiers;
+ IsControlKeyDown = ((modifiers & ModifierKeys.Control) != 0);
+ IsShiftKeyDown = ((modifiers & ModifierKeys.Shift) != 0);
+
+ IsOpenAppleKeyDown = ((modifiers & ModifierKeys.Alt) != 0) || IsKeyDown(Key.NumPad0);
+ IsCloseAppleKeyDown = ((modifiers & ModifierKeys.Windows) != 0) || IsKeyDown(Key.Decimal);
+ IsResetKeyDown = IsControlKeyDown && IsKeyDown(Key.Back);
+
+ base.Update();
+ }
+
+ private bool IsKeyDown(Key key)
+ {
+ return _states[(int)key];
+ }
+
+ private void OnPageKeyDown(object sender, KeyEventArgs e)
+ {
+ //DebugService.WriteLine(string.Concat("OnPageKeyDn: Key=", e.Key, " PlatformKeyCode=", e.PlatformKeyCode));
+
+ _states[(int)e.Key] = true;
+ _updateAnyKeyDown = false;
+ IsAnyKeyDown = true;
+
+ int asciiKey = GetAsciiKey(e.Key, e.PlatformKeyCode);
+ if (asciiKey >= 0)
+ {
+ Machine.Keyboard.Latch = asciiKey;
+ e.Handled = true;
+ }
+
+ Update();
+ }
+
+ private void OnPageKeyUp(object sender, KeyEventArgs e)
+ {
+ //DebugService.WriteLine(string.Concat("OnPageKeyUp: Key=", e.Key, " PlatformKeyCode=", e.PlatformKeyCode));
+
+ _states[(int)e.Key] = false;
+ _updateAnyKeyDown = true;
+
+ var modifiers = System.Windows.Input.Keyboard.Modifiers;
+ bool control = ((modifiers & ModifierKeys.Control) != 0);
+
+ if (e.Key == Key.CapsLock)
+ {
+ _capsLock ^= true; // SL is missing caps lock support; try to track manually
+ }
+ else if (control && (e.Key == Key.Divide))
+ {
+ Machine.Cpu.IsThrottled ^= true;
+ }
+ else if (control && (e.Key == Key.Multiply))
+ {
+ Machine.Video.IsMonochrome ^= true;
+ }
+ else if (control && (e.Key == Key.Subtract))
+ {
+ Machine.Video.IsFullScreen ^= true;
+ }
+ Update();
+ }
+
+ private void OnPageLostFocus(object sender, RoutedEventArgs e) // reset keyboard state on lost focus; can't access keyboard state on got focus
+ {
+ IsAnyKeyDown = false;
+ for (int i = 0; i < KeyValues.Length; i++)
+ {
+ _states[(int)KeyValues[i]] = false;
+ }
+ }
+
+ [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
+ [SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode")]
+ private int GetAsciiKey(Key key, int platformKeyCode)
+ {
+ var modifiers = System.Windows.Input.Keyboard.Modifiers;
+ bool control = ((modifiers & ModifierKeys.Control) != 0);
+ bool shift = ((modifiers & ModifierKeys.Shift) != 0);
+ bool capsLock = shift ^ _capsLock;
+
+ switch (key)
+ {
+ case Key.Left:
+ return 0x08;
+
+ case Key.Tab:
+ return 0x09;
+
+ case Key.Down:
+ return 0x0A;
+
+ case Key.Up:
+ return 0x0B;
+
+ case Key.Enter:
+ return 0x0D;
+
+ case Key.Right:
+ return 0x15;
+
+ case Key.Escape:
+ return 0x1B;
+
+ case Key.Back:
+ return control ? -1 : 0x7F;
+
+ case Key.Space:
+ return ' ';
+
+ case Key.D1:
+ return shift ? '!' : '1';
+
+ case Key.D2:
+ return control ? 0x00 : shift ? '@' : '2';
+
+ case Key.D3:
+ return shift ? '#' : '3';
+
+ case Key.D4:
+ return shift ? '$' : '4';
+
+ case Key.D5:
+ return shift ? '%' : '5';
+
+ case Key.D6:
+ return control ? 0x1E : shift ? '^' : '6';
+
+ case Key.D7:
+ return shift ? '&' : '7';
+
+ case Key.D8:
+ return shift ? '*' : '8';
+
+ case Key.D9:
+ return shift ? '(' : '9';
+
+ case Key.D0:
+ return shift ? ')' : '0';
+
+ case Key.A:
+ return control ? 0x01 : capsLock ? 'A' : 'a';
+
+ case Key.B:
+ return control ? 0x02 : capsLock ? 'B' : 'b';
+
+ case Key.C:
+ return control ? 0x03 : capsLock ? 'C' : 'c';
+
+ case Key.D:
+ return control ? 0x04 : capsLock ? 'D' : 'd';
+
+ case Key.E:
+ return control ? 0x05 : capsLock ? 'E' : 'e';
+
+ case Key.F:
+ return control ? 0x06 : capsLock ? 'F' : 'f';
+
+ case Key.G:
+ return control ? 0x07 : capsLock ? 'G' : 'g';
+
+ case Key.H:
+ return control ? 0x08 : capsLock ? 'H' : 'h';
+
+ case Key.I:
+ return control ? 0x09 : capsLock ? 'I' : 'i';
+
+ case Key.J:
+ return control ? 0x0A : capsLock ? 'J' : 'j';
+
+ case Key.K:
+ return control ? 0x0B : capsLock ? 'K' : 'k';
+
+ case Key.L:
+ return control ? 0x0C : capsLock ? 'L' : 'l';
+
+ case Key.M:
+ return control ? 0x0D : capsLock ? 'M' : 'm';
+
+ case Key.N:
+ return control ? 0x0E : capsLock ? 'N' : 'n';
+
+ case Key.O:
+ return control ? 0x0F : capsLock ? 'O' : 'o';
+
+ case Key.P:
+ return control ? 0x10 : capsLock ? 'P' : 'p';
+
+ case Key.Q:
+ return control ? 0x11 : capsLock ? 'Q' : 'q';
+
+ case Key.R:
+ return control ? 0x12 : capsLock ? 'R' : 'r';
+
+ case Key.S:
+ return control ? 0x13 : capsLock ? 'S' : 's';
+
+ case Key.T:
+ return control ? 0x14 : capsLock ? 'T' : 't';
+
+ case Key.U:
+ return control ? 0x15 : capsLock ? 'U' : 'u';
+
+ case Key.V:
+ return control ? 0x16 : capsLock ? 'V' : 'v';
+
+ case Key.W:
+ return control ? 0x17 : capsLock ? 'W' : 'w';
+
+ case Key.X:
+ return control ? 0x18 : capsLock ? 'X' : 'x';
+
+ case Key.Y:
+ return control ? 0x19 : capsLock ? 'Y' : 'y';
+
+ case Key.Z:
+ return control ? 0x1A : capsLock ? 'Z' : 'z';
+
+ case Key.Unknown:
+ switch (Environment.OSVersion.Platform)
+ {
+ case PlatformID.Win32NT:
+ switch (platformKeyCode)
+ {
+ case 0xBA: // WinForms Keys.Oem1
+ return shift ? ':' : ';';
+
+ case 0xBF: // WinForms Keys.Oem2
+ return shift ? '?' : '/';
+
+ case 0xC0: // WinForms Keys.Oem3
+ return shift ? '~' : '`';
+
+ case 0xDB: // WinForms Keys.Oem4
+ return shift ? '{' : '[';
+
+ case 0xDC: // WinForms Keys.Oem5
+ return control ? 0x1C : shift ? '|' : '\\';
+
+ case 0xDD: // WinForms Keys.Oem6
+ return control ? 0x1D : shift ? '}' : ']';
+
+ case 0xDE: // WinForms Keys.Oem7
+ return shift ? '"' : '\'';
+
+ case 0xBD: // WinForms Keys.OemMinus
+ return control ? 0x1F : shift ? '_' : '-';
+
+ case 0xBB: // WinForms Keys.OemPlus
+ return shift ? '+' : '=';
+
+ case 0xBC: // WinForms Keys.OemComma
+ return shift ? '<' : ',';
+
+ case 0xBE: // WinForms Keys.OemPeriod
+ return shift ? '>' : '.';
+ }
+ break;
+
+ case PlatformID.MacOSX:
+ switch (platformKeyCode)
+ {
+ case 0x29:
+ return shift ? ':' : ';';
+
+ case 0x2C:
+ return shift ? '?' : '/';
+
+ case 0x32:
+ return shift ? '~' : '`';
+
+ case 0x21:
+ return shift ? '{' : '[';
+
+ case 0x2A:
+ return control ? 0x1C : shift ? '|' : '\\';
+
+ case 0x1E:
+ return control ? 0x1D : shift ? '}' : ']';
+
+ case 0x27:
+ return shift ? '"' : '\'';
+
+ case 0x1B:
+ return control ? 0x1F : shift ? '_' : '-';
+
+ case 0x18:
+ return shift ? '+' : '=';
+
+ case 0x2B:
+ return shift ? '<' : ',';
+
+ case 0x2F:
+ return shift ? '>' : '.';
+ }
+ break;
+
+ case PlatformID.Unix:
+ switch (platformKeyCode)
+ {
+ case 0x2F:
+ return shift ? ':' : ';';
+
+ case 0x3D:
+ return shift ? '?' : '/';
+
+ case 0x31:
+ return shift ? '~' : '`';
+
+ case 0x22:
+ return shift ? '{' : '[';
+
+ case 0x33:
+ return control ? 0x1C : shift ? '|' : '\\';
+
+ case 0x23:
+ return control ? 0x1D : shift ? '}' : ']';
+
+ case 0x30:
+ return shift ? '"' : '\'';
+
+ case 0x14:
+ return control ? 0x1F : shift ? '_' : '-';
+
+ case 0x15:
+ return shift ? '+' : '=';
+
+ case 0x3B:
+ return shift ? '<' : ',';
+
+ case 0x3C:
+ return shift ? '>' : '.';
+ }
+ break;
+ }
+ break;
+ }
+
+ return -1;
+ }
+
+ private static readonly Key[] KeyValues =
+ (from key in
+ (from field in typeof(Key).GetFields() // missing Enum.GetValues; use reflection
+ where field.IsLiteral
+ select (Key)field.GetValue(typeof(Key)))
+ where (key != Key.None) // filter Key.None
+ select key).ToArray();
+
+ private static readonly int KeyCount = (int)(KeyValues.Max()) + 1;
+
+ private bool[] _states = new bool[KeyCount];
+ private bool _capsLock;
+ private bool _updateAnyKeyDown;
+ }
+}
diff --git a/Virtu/Silverlight/Services/SilverlightVideoService.cs b/Virtu/Silverlight/Services/SilverlightVideoService.cs
index da8b4e0..baa42bb 100644
--- a/Virtu/Silverlight/Services/SilverlightVideoService.cs
+++ b/Virtu/Silverlight/Services/SilverlightVideoService.cs
@@ -1,99 +1,99 @@
-using System;
-using System.Diagnostics.CodeAnalysis;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Media.Imaging;
-using Jellyfish.Library;
-
-namespace Jellyfish.Virtu.Services
-{
- public sealed class SilverlightVideoService : VideoService
- {
- public SilverlightVideoService(Machine machine, UserControl page, Image image) :
- base(machine)
- {
- if (page == null)
- {
- throw new ArgumentNullException("page");
- }
- if (image == null)
- {
- throw new ArgumentNullException("image");
- }
-
- _page = page;
- _image = image;
- _image.Source = _bitmap;
-
- _page.LayoutUpdated += (sender, e) => SetWindowSizeToContent();
- _page.SizeChanged += (sender, e) => SetImageSize();
- }
-
- public override void SetFullScreen(bool isFullScreen)
- {
- _page.Dispatcher.Send(() =>
- {
- var application = Application.Current;
- if (application.IsRunningOutOfBrowser)
- {
- var content = application.Host.Content;
- if (content.IsFullScreen != isFullScreen)
- {
- content.IsFullScreen = isFullScreen;
- }
- }
- });
- }
-
- [SuppressMessage("Microsoft.Usage", "CA2233:OperationsShouldNotOverflow")]
- public override void SetPixel(int x, int y, uint color)
- {
- _pixels[y * BitmapWidth + x] = (int)color;
- _pixelsDirty = true;
- }
-
- public override void Update() // main thread
- {
- if (_pixelsDirty)
- {
- _pixelsDirty = false;
- for (int i = 0; i < BitmapWidth * BitmapHeight; i++)
- {
- _bitmap.Pixels[i] = _pixels[i];
- }
- _bitmap.Invalidate();
- }
- }
-
- private void SetImageSize(bool swapOrientation = false)
- {
- int uniformScale = Math.Max(1, swapOrientation ? Math.Min((int)_page.RenderSize.Height / BitmapWidth, (int)_page.RenderSize.Width / BitmapHeight) :
- Math.Min((int)_page.RenderSize.Width / BitmapWidth, (int)_page.RenderSize.Height / BitmapHeight));
- _image.Width = uniformScale * BitmapWidth;
- _image.Height = uniformScale * BitmapHeight;
- }
-
- private void SetWindowSizeToContent()
- {
- var application = Application.Current;
- if (application.IsRunningOutOfBrowser && !_sizedToContent)
- {
- _sizedToContent = true;
- var window = application.MainWindow;
- var size = application.RootVisual.DesiredSize;
- window.Width = size.Width;
- window.Height = size.Height;
- }
- }
-
- private const int BitmapWidth = 560;
- private const int BitmapHeight = 384;
-
- private UserControl _page;
- private Image _image;
- private WriteableBitmap _bitmap = new WriteableBitmap(BitmapWidth, BitmapHeight);
- private int[] _pixels = new int[BitmapWidth * BitmapHeight];
- private bool _pixelsDirty;
- private bool _sizedToContent;
- }
-}
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media.Imaging;
+using Jellyfish.Library;
+
+namespace Jellyfish.Virtu.Services
+{
+ public sealed class SilverlightVideoService : VideoService
+ {
+ public SilverlightVideoService(Machine machine, UserControl page, Image image) :
+ base(machine)
+ {
+ if (page == null)
+ {
+ throw new ArgumentNullException("page");
+ }
+ if (image == null)
+ {
+ throw new ArgumentNullException("image");
+ }
+
+ _page = page;
+ _image = image;
+ _image.Source = _bitmap;
+
+ _page.LayoutUpdated += (sender, e) => SetWindowSizeToContent();
+ _page.SizeChanged += (sender, e) => SetImageSize();
+ }
+
+ public override void SetFullScreen(bool isFullScreen)
+ {
+ _page.Dispatcher.Send(() =>
+ {
+ var application = Application.Current;
+ if (application.IsRunningOutOfBrowser)
+ {
+ var content = application.Host.Content;
+ if (content.IsFullScreen != isFullScreen)
+ {
+ content.IsFullScreen = isFullScreen;
+ }
+ }
+ });
+ }
+
+ [SuppressMessage("Microsoft.Usage", "CA2233:OperationsShouldNotOverflow")]
+ public override void SetPixel(int x, int y, uint color)
+ {
+ _pixels[y * BitmapWidth + x] = (int)color;
+ _pixelsDirty = true;
+ }
+
+ public override void Update() // main thread
+ {
+ if (_pixelsDirty)
+ {
+ _pixelsDirty = false;
+ for (int i = 0; i < BitmapWidth * BitmapHeight; i++)
+ {
+ _bitmap.Pixels[i] = _pixels[i];
+ }
+ _bitmap.Invalidate();
+ }
+ }
+
+ private void SetImageSize(bool swapOrientation = false)
+ {
+ int uniformScale = Math.Max(1, swapOrientation ? Math.Min((int)_page.RenderSize.Height / BitmapWidth, (int)_page.RenderSize.Width / BitmapHeight) :
+ Math.Min((int)_page.RenderSize.Width / BitmapWidth, (int)_page.RenderSize.Height / BitmapHeight));
+ _image.Width = uniformScale * BitmapWidth;
+ _image.Height = uniformScale * BitmapHeight;
+ }
+
+ private void SetWindowSizeToContent()
+ {
+ var application = Application.Current;
+ if (application.IsRunningOutOfBrowser && !_sizedToContent)
+ {
+ _sizedToContent = true;
+ var window = application.MainWindow;
+ var size = application.RootVisual.DesiredSize;
+ window.Width = size.Width;
+ window.Height = size.Height;
+ }
+ }
+
+ private const int BitmapWidth = 560;
+ private const int BitmapHeight = 384;
+
+ private UserControl _page;
+ private Image _image;
+ private WriteableBitmap _bitmap = new WriteableBitmap(BitmapWidth, BitmapHeight);
+ private int[] _pixels = new int[BitmapWidth * BitmapHeight];
+ private bool _pixelsDirty;
+ private bool _sizedToContent;
+ }
+}
diff --git a/Virtu/Speaker.cs b/Virtu/Speaker.cs
index e1cf991..774be31 100644
--- a/Virtu/Speaker.cs
+++ b/Virtu/Speaker.cs
@@ -1,90 +1,90 @@
-using System;
-using System.IO;
-using Jellyfish.Virtu.Services;
-
-namespace Jellyfish.Virtu
-{
- public sealed class Speaker : MachineComponent
- {
- public Speaker(Machine machine) :
- base(machine)
- {
- _flushOutputEvent = FlushOutputEvent; // cache delegates; avoids garbage
- }
-
- public override void Initialize()
- {
- _audioService = Machine.Services.GetService();
-
- Volume = 0.5f;
- Machine.Events.AddEvent(CyclesPerFlush * Machine.Cpu.Multiplier, _flushOutputEvent);
- }
-
- public override void Reset()
- {
- _audioService.Reset();
- _isHigh = false;
- _highCycles = _totalCycles = 0;
- }
-
- public override void LoadState(BinaryReader reader, Version version)
- {
- if (reader == null)
- {
- throw new ArgumentNullException("reader");
- }
-
- Volume = reader.ReadSingle();
- }
-
- public override void SaveState(BinaryWriter writer)
- {
- if (writer == null)
- {
- throw new ArgumentNullException("writer");
- }
-
- writer.Write(Volume);
- }
-
- public void ToggleOutput()
- {
- UpdateCycles();
- _isHigh ^= true;
- }
-
- private void FlushOutputEvent()
- {
- UpdateCycles();
- _audioService.Output(_highCycles * short.MaxValue / _totalCycles); // quick and dirty decimation
- _highCycles = _totalCycles = 0;
-
- Machine.Events.AddEvent(CyclesPerFlush * Machine.Cpu.Multiplier, _flushOutputEvent);
- }
-
- private void UpdateCycles()
- {
- int delta = (int)(Machine.Cpu.Cycles - _lastCycles);
- if (_isHigh)
- {
- _highCycles += delta;
- }
- _totalCycles += delta;
- _lastCycles = Machine.Cpu.Cycles;
- }
-
- public float Volume { get { return _volume; } set { _volume = value; _audioService.SetVolume(_volume); } }
-
- private const int CyclesPerFlush = 23;
-
- private Action _flushOutputEvent;
-
- private AudioService _audioService;
-
- private bool _isHigh;
- private int _highCycles;
- private int _totalCycles;
- private long _lastCycles;
- private float _volume;
- }
-}
+using System;
+using System.IO;
+using Jellyfish.Virtu.Services;
+
+namespace Jellyfish.Virtu
+{
+ public sealed class Speaker : MachineComponent
+ {
+ public Speaker(Machine machine) :
+ base(machine)
+ {
+ _flushOutputEvent = FlushOutputEvent; // cache delegates; avoids garbage
+ }
+
+ public override void Initialize()
+ {
+ _audioService = Machine.Services.GetService();
+
+ Volume = 0.5f;
+ Machine.Events.AddEvent(CyclesPerFlush * Machine.Cpu.Multiplier, _flushOutputEvent);
+ }
+
+ public override void Reset()
+ {
+ _audioService.Reset();
+ _isHigh = false;
+ _highCycles = _totalCycles = 0;
+ }
+
+ public override void LoadState(BinaryReader reader, Version version)
+ {
+ if (reader == null)
+ {
+ throw new ArgumentNullException("reader");
+ }
+
+ Volume = reader.ReadSingle();
+ }
+
+ public override void SaveState(BinaryWriter writer)
+ {
+ if (writer == null)
+ {
+ throw new ArgumentNullException("writer");
+ }
+
+ writer.Write(Volume);
+ }
+
+ public void ToggleOutput()
+ {
+ UpdateCycles();
+ _isHigh ^= true;
+ }
+
+ private void FlushOutputEvent()
+ {
+ UpdateCycles();
+ _audioService.Output(_highCycles * short.MaxValue / _totalCycles); // quick and dirty decimation
+ _highCycles = _totalCycles = 0;
+
+ Machine.Events.AddEvent(CyclesPerFlush * Machine.Cpu.Multiplier, _flushOutputEvent);
+ }
+
+ private void UpdateCycles()
+ {
+ int delta = (int)(Machine.Cpu.Cycles - _lastCycles);
+ if (_isHigh)
+ {
+ _highCycles += delta;
+ }
+ _totalCycles += delta;
+ _lastCycles = Machine.Cpu.Cycles;
+ }
+
+ public float Volume { get { return _volume; } set { _volume = value; _audioService.SetVolume(_volume); } }
+
+ private const int CyclesPerFlush = 23;
+
+ private Action _flushOutputEvent;
+
+ private AudioService _audioService;
+
+ private bool _isHigh;
+ private int _highCycles;
+ private int _totalCycles;
+ private long _lastCycles;
+ private float _volume;
+ }
+}
diff --git a/Virtu/Video.cs b/Virtu/Video.cs
index 46adc7f..715dab2 100644
--- a/Virtu/Video.cs
+++ b/Virtu/Video.cs
@@ -1,1150 +1,1150 @@
-using System;
-using System.IO;
-using Jellyfish.Virtu.Services;
-
-namespace Jellyfish.Virtu
-{
- [Flags]
- public enum ScannerOptions { None = 0x0, AppleII = 0x1, Pal = 0x2 } // defaults to AppleIIe, Ntsc
-
- public sealed partial class Video : MachineComponent
- {
- public Video(Machine machine) :
- base(machine)
- {
- _flushRowEvent = FlushRowEvent; // cache delegates; avoids garbage
- _inverseTextEvent = InverseTextEvent;
- _leaveVBlankEvent = LeaveVBlankEvent;
- _resetVSyncEvent = ResetVSyncEvent;
-
- FlushRowMode = new Action[ModeCount]
- {
- FlushRowMode0, FlushRowMode1, FlushRowMode2, FlushRowMode3, FlushRowMode4, FlushRowMode5, FlushRowMode6, FlushRowMode7,
- FlushRowMode8, FlushRowMode9, FlushRowModeA, FlushRowModeB, FlushRowModeC, FlushRowModeD, FlushRowModeE, FlushRowModeF
- };
- }
-
- public override void Initialize()
- {
- _memory = Machine.Memory;
- _videoService = Machine.Services.GetService();
-
-#if SILVERLIGHT || WPF
- _colorBlack = 0xFF000000; // BGRA
- _colorDarkBlue = 0xFF000099;
- _colorDarkGreen = 0xFF117722;
- _colorMediumBlue = 0xFF0000FF;
- _colorBrown = 0xFF885500;
- _colorLightGrey = 0xFF99AAAA;
- _colorGreen = 0xFF00EE11;
- _colorAquamarine = 0xFF55FFAA;
- _colorDeepRed = 0xFFFF1111;
- _colorPurple = 0xFFDD00DD;
- _colorDarkGrey = 0xFF445555;
- _colorLightBlue = 0xFF33AAFF;
- _colorOrange = 0xFFFF4411;
- _colorPink = 0xFFFF9988;
- _colorYellow = 0xFFFFFF11;
- _colorWhite = 0xFFFFFFFF;
- _colorMonochrome = 0xFF00AA00;
-#else
- _colorBlack = 0xFF000000; // RGBA
- _colorDarkBlue = 0xFF990000;
- _colorDarkGreen = 0xFF227711;
- _colorMediumBlue = 0xFFFF0000;
- _colorBrown = 0xFF005588;
- _colorLightGrey = 0xFFAAAA99;
- _colorGreen = 0xFF11EE00;
- _colorAquamarine = 0xFFAAFF55;
- _colorDeepRed = 0xFF1111FF;
- _colorPurple = 0xFFDD00DD;
- _colorDarkGrey = 0xFF555544;
- _colorLightBlue = 0xFFFFAA33;
- _colorOrange = 0xFF1144FF;
- _colorPink = 0xFF8899FF;
- _colorYellow = 0xFF11FFFF;
- _colorWhite = 0xFFFFFFFF;
- _colorMonochrome = 0xFF00AA00;
-#endif
- SetPalette();
-
- IsFullScreen = false;
- IsMonochrome = false;
- ScannerOptions = ScannerOptions.None;
-
- IsVBlank = true;
-
- Machine.Events.AddEvent(_cyclesPerVBlankPreset, _leaveVBlankEvent); // align flush events with scanner; assumes vcount preset at start of frame [3-15, 3-16]
- Machine.Events.AddEvent(_cyclesPerVSync, _resetVSyncEvent);
- Machine.Events.AddEvent(_cyclesPerFlash, _inverseTextEvent);
- }
-
- public override void Reset()
- {
- SetCharSet();
- DirtyScreen();
- FlushScreen();
- }
-
- public override void LoadState(BinaryReader reader, Version version)
- {
- if (reader == null)
- {
- throw new ArgumentNullException("reader");
- }
-
- _colorBlack = reader.ReadUInt32();
- _colorDarkBlue = reader.ReadUInt32();
- _colorDarkGreen = reader.ReadUInt32();
- _colorMediumBlue = reader.ReadUInt32();
- _colorBrown = reader.ReadUInt32();
- _colorLightGrey = reader.ReadUInt32();
- _colorGreen = reader.ReadUInt32();
- _colorAquamarine = reader.ReadUInt32();
- _colorDeepRed = reader.ReadUInt32();
- _colorPurple = reader.ReadUInt32();
- _colorDarkGrey = reader.ReadUInt32();
- _colorLightBlue = reader.ReadUInt32();
- _colorOrange = reader.ReadUInt32();
- _colorPink = reader.ReadUInt32();
- _colorYellow = reader.ReadUInt32();
- _colorWhite = reader.ReadUInt32();
- _colorMonochrome = reader.ReadUInt32();
- SetPalette();
-
- IsFullScreen = reader.ReadBoolean();
- IsMonochrome = reader.ReadBoolean();
- ScannerOptions = (ScannerOptions)reader.ReadInt32();
-
- SetCharSet();
- DirtyScreen();
- FlushScreen();
- }
-
- public override void SaveState(BinaryWriter writer)
- {
- if (writer == null)
- {
- throw new ArgumentNullException("writer");
- }
-
- writer.Write(_colorBlack);
- writer.Write(_colorDarkBlue);
- writer.Write(_colorDarkGreen);
- writer.Write(_colorMediumBlue);
- writer.Write(_colorBrown);
- writer.Write(_colorLightGrey);
- writer.Write(_colorGreen);
- writer.Write(_colorAquamarine);
- writer.Write(_colorDeepRed);
- writer.Write(_colorPurple);
- writer.Write(_colorDarkGrey);
- writer.Write(_colorLightBlue);
- writer.Write(_colorOrange);
- writer.Write(_colorPink);
- writer.Write(_colorYellow);
- writer.Write(_colorWhite);
- writer.Write(_colorMonochrome);
-
- writer.Write(IsFullScreen);
- writer.Write(IsMonochrome);
- writer.Write((int)ScannerOptions);
- }
-
- public void DirtyCell(int addressOffset)
- {
- _isCellDirty[CellIndex[addressOffset]] = true;
- }
-
- public void DirtyCellMixed(int addressOffset)
- {
- int cellIndex = CellIndex[addressOffset];
- if (cellIndex < MixedCellIndex)
- {
- _isCellDirty[cellIndex] = true;
- }
- }
-
- public void DirtyCellMixedText(int addressOffset)
- {
- int cellIndex = CellIndex[addressOffset];
- if (cellIndex >= MixedCellIndex)
- {
- _isCellDirty[cellIndex] = true;
- }
- }
-
- public void DirtyScreen()
- {
- for (int i = 0; i < Height * CellColumns; i++)
- {
- _isCellDirty[i] = true;
- }
- }
-
- public void DirtyScreenText()
- {
- if (_memory.IsText)
- {
- for (int i = 0; i < MixedHeight * CellColumns; i++)
- {
- _isCellDirty[i] = true;
- }
- }
- if (_memory.IsText || _memory.IsMixed)
- {
- for (int i = MixedHeight * CellColumns; i < Height * CellColumns; i++)
- {
- _isCellDirty[i] = true;
- }
- }
- }
-
- public int ReadFloatingBus() // [5-40]
- {
- // derive scanner counters from current cycles into frame; assumes hcount and vcount preset at start of frame [3-13, 3-15, 3-16]
- int cycles = _cyclesPerVSync - Machine.Events.FindEvent(_resetVSyncEvent);
- int hClock = cycles % CyclesPerHSync;
- int hCount = (hClock != 0) ? HCountPreset + hClock - 1 : 0;
- int vLine = cycles / CyclesPerHSync;
- int vCount = _vCountPreset + vLine;
-
- // derive scanner address [5-8]
- int address = ((vCount << 4) & 0x0380) | ((0x0068 + (hCount & 0x0038) + (((vCount >> 1) & 0x0060) | ((vCount >> 3) & 0x0018))) & 0x0078) | (hCount & 0x0007);
- if (_memory.IsHires && !(_memory.IsMixed && ((vCount & 0xA0) == 0xA0))) // hires but not actively mixed [5-13, 5-19]
- {
- address |= (_memory.IsVideoPage2 ? 0x4000 : 0x2000) | ((vCount << 10) & 0x1C00);
- }
- else
- {
- address |= _memory.IsVideoPage2 ? 0x0800 : 0x0400;
- if (((_scannerOptions & ScannerOptions.AppleII) != 0) && (hCount < HCountLeaveHBlank))
- {
- address |= 0x1000;
- }
- }
-
- return _memory.Read(address);
- }
-
- public void SetCharSet()
- {
- _charSet = !_memory.IsCharSetAlternate ? CharSetPrimary : (_memory.Monitor == MonitorType.Standard) ? CharSetSecondaryStandard : CharSetSecondaryEnhanced;
- DirtyScreenText();
- }
-
- #region Draw Methods
- private void DrawText40(int data, int x, int y)
- {
- int color = IsMonochrome ? ColorMono00 : ColorWhite00;
- int index = _charSet[data] * CharBitmapBytes;
- int inverseMask = (_isTextInversed && !_memory.IsCharSetAlternate && (0x40 <= data) && (data <= 0x7F)) ? 0x7F : 0x00;
- for (int i = 0; i < TextHeight; i++, y++)
- {
- data = CharBitmap[index + i] ^ inverseMask;
- SetPixel(x + 0, y, color | (data & 0x01));
- SetPixel(x + 1, y, color | (data & 0x01));
- SetPixel(x + 2, y, color | (data & 0x02));
- SetPixel(x + 3, y, color | (data & 0x02));
- SetPixel(x + 4, y, color | (data & 0x04));
- SetPixel(x + 5, y, color | (data & 0x04));
- SetPixel(x + 6, y, color | (data & 0x08));
- SetPixel(x + 7, y, color | (data & 0x08));
- SetPixel(x + 8, y, color | (data & 0x10));
- SetPixel(x + 9, y, color | (data & 0x10));
- SetPixel(x + 10, y, color | (data & 0x20));
- SetPixel(x + 11, y, color | (data & 0x20));
- SetPixel(x + 12, y, color | (data & 0x40));
- SetPixel(x + 13, y, color | (data & 0x40));
- }
- }
-
- private void DrawText80(int data, int x, int y)
- {
- int color = IsMonochrome ? ColorMono00 : ColorWhite00;
- int index = _charSet[data] * CharBitmapBytes;
- int mask = (_isTextInversed && !_memory.IsCharSetAlternate && (0x40 <= data) && (data <= 0x7F)) ? 0x7F : 0x00;
- for (int i = 0; i < TextHeight; i++, y++)
- {
- data = CharBitmap[index + i] ^ mask;
- SetPixel(x + 0, y, color | (data & 0x01));
- SetPixel(x + 1, y, color | (data & 0x02));
- SetPixel(x + 2, y, color | (data & 0x04));
- SetPixel(x + 3, y, color | (data & 0x08));
- SetPixel(x + 4, y, color | (data & 0x10));
- SetPixel(x + 5, y, color | (data & 0x20));
- SetPixel(x + 6, y, color | (data & 0x40));
- }
- }
-
- private void DrawLores(int data, int x, int y)
- {
- if (IsMonochrome)
- {
- if ((x & 0x02) == 0x02) // odd cell
- {
- data = ((data << 2) & 0xCC) | ((data >> 2) & 0x33);
- }
- for (int i = 0; i < LoresHeight; i++, y++)
- {
- SetPixel(x + 0, y, data & 0x01);
- SetPixel(x + 1, y, data & 0x02);
- SetPixel(x + 2, y, data & 0x04);
- SetPixel(x + 3, y, data & 0x08);
- SetPixel(x + 4, y, data & 0x01);
- SetPixel(x + 5, y, data & 0x02);
- SetPixel(x + 6, y, data & 0x04);
- SetPixel(x + 7, y, data & 0x08);
- SetPixel(x + 8, y, data & 0x01);
- SetPixel(x + 9, y, data & 0x02);
- SetPixel(x + 10, y, data & 0x04);
- SetPixel(x + 11, y, data & 0x08);
- SetPixel(x + 12, y, data & 0x01);
- SetPixel(x + 13, y, data & 0x02);
- }
- for (int i = 0; i < LoresHeight; i++, y++)
- {
- SetPixel(x + 0, y, data & 0x10);
- SetPixel(x + 1, y, data & 0x20);
- SetPixel(x + 2, y, data & 0x40);
- SetPixel(x + 3, y, data & 0x80);
- SetPixel(x + 4, y, data & 0x10);
- SetPixel(x + 5, y, data & 0x20);
- SetPixel(x + 6, y, data & 0x40);
- SetPixel(x + 7, y, data & 0x80);
- SetPixel(x + 8, y, data & 0x10);
- SetPixel(x + 9, y, data & 0x20);
- SetPixel(x + 10, y, data & 0x40);
- SetPixel(x + 11, y, data & 0x80);
- SetPixel(x + 12, y, data & 0x10);
- SetPixel(x + 13, y, data & 0x20);
- }
- }
- else
- {
- int color = ColorLores[data & 0x0F];
- for (int i = 0; i < LoresHeight; i++, y++)
- {
- SetPixel(x + 0, y, color);
- SetPixel(x + 1, y, color);
- SetPixel(x + 2, y, color);
- SetPixel(x + 3, y, color);
- SetPixel(x + 4, y, color);
- SetPixel(x + 5, y, color);
- SetPixel(x + 6, y, color);
- SetPixel(x + 7, y, color);
- SetPixel(x + 8, y, color);
- SetPixel(x + 9, y, color);
- SetPixel(x + 10, y, color);
- SetPixel(x + 11, y, color);
- SetPixel(x + 12, y, color);
- SetPixel(x + 13, y, color);
- }
- color = ColorLores[data >> 4];
- for (int i = 0; i < LoresHeight; i++, y++)
- {
- SetPixel(x + 0, y, color);
- SetPixel(x + 1, y, color);
- SetPixel(x + 2, y, color);
- SetPixel(x + 3, y, color);
- SetPixel(x + 4, y, color);
- SetPixel(x + 5, y, color);
- SetPixel(x + 6, y, color);
- SetPixel(x + 7, y, color);
- SetPixel(x + 8, y, color);
- SetPixel(x + 9, y, color);
- SetPixel(x + 10, y, color);
- SetPixel(x + 11, y, color);
- SetPixel(x + 12, y, color);
- SetPixel(x + 13, y, color);
- }
- }
- }
-
- private void Draw7MLores(int data, int x, int y)
- {
- if (IsMonochrome)
- {
- if ((x & 0x02) == 0x02) // odd cell
- {
- data = ((data << 2) & 0xCC) | ((data >> 2) & 0x33);
- }
- for (int i = 0; i < LoresHeight; i++, y++)
- {
- SetPixel(x + 0, y, data & 0x01);
- SetPixel(x + 1, y, data & 0x01);
- SetPixel(x + 2, y, data & 0x02);
- SetPixel(x + 3, y, data & 0x02);
- SetPixel(x + 4, y, data & 0x04);
- SetPixel(x + 5, y, data & 0x04);
- SetPixel(x + 6, y, data & 0x08);
- SetPixel(x + 7, y, data & 0x08);
- SetPixel(x + 8, y, data & 0x01);
- SetPixel(x + 9, y, data & 0x01);
- SetPixel(x + 10, y, data & 0x02);
- SetPixel(x + 11, y, data & 0x02);
- SetPixel(x + 12, y, data & 0x04);
- SetPixel(x + 13, y, data & 0x04);
- }
- for (int i = 0; i < LoresHeight; i++, y++)
- {
- SetPixel(x + 0, y, data & 0x10);
- SetPixel(x + 1, y, data & 0x10);
- SetPixel(x + 2, y, data & 0x20);
- SetPixel(x + 3, y, data & 0x20);
- SetPixel(x + 4, y, data & 0x40);
- SetPixel(x + 5, y, data & 0x40);
- SetPixel(x + 6, y, data & 0x80);
- SetPixel(x + 7, y, data & 0x80);
- SetPixel(x + 8, y, data & 0x10);
- SetPixel(x + 9, y, data & 0x10);
- SetPixel(x + 10, y, data & 0x20);
- SetPixel(x + 11, y, data & 0x20);
- SetPixel(x + 12, y, data & 0x40);
- SetPixel(x + 13, y, data & 0x40);
- }
- }
- else
- {
- int color = Color7MLores[((x & 0x02) << 3) | (data & 0x0F)];
- for (int i = 0; i < LoresHeight; i++, y++)
- {
- SetPixel(x + 0, y, color);
- SetPixel(x + 1, y, color);
- SetPixel(x + 2, y, color);
- SetPixel(x + 3, y, color);
- SetPixel(x + 4, y, color);
- SetPixel(x + 5, y, color);
- SetPixel(x + 6, y, color);
- SetPixel(x + 7, y, color);
- SetPixel(x + 8, y, color);
- SetPixel(x + 9, y, color);
- SetPixel(x + 10, y, color);
- SetPixel(x + 11, y, color);
- SetPixel(x + 12, y, color);
- SetPixel(x + 13, y, color);
- }
- color = Color7MLores[((x & 0x02) << 3) | (data >> 4)];
- for (int i = 0; i < LoresHeight; i++, y++)
- {
- SetPixel(x + 0, y, color);
- SetPixel(x + 1, y, color);
- SetPixel(x + 2, y, color);
- SetPixel(x + 3, y, color);
- SetPixel(x + 4, y, color);
- SetPixel(x + 5, y, color);
- SetPixel(x + 6, y, color);
- SetPixel(x + 7, y, color);
- SetPixel(x + 8, y, color);
- SetPixel(x + 9, y, color);
- SetPixel(x + 10, y, color);
- SetPixel(x + 11, y, color);
- SetPixel(x + 12, y, color);
- SetPixel(x + 13, y, color);
- }
- }
- }
-
- private void DrawDLores(int data, int x, int y)
- {
- if (IsMonochrome)
- {
- if ((x & 0x01) == 0x00) // even half cell
- {
- data = ((data << 1) & 0xEE) | ((data >> 3) & 0x11);
- }
- for (int i = 0; i < LoresHeight; i++, y++)
- {
- SetPixel(x + 0, y, data & 0x01);
- SetPixel(x + 1, y, data & 0x02);
- SetPixel(x + 2, y, data & 0x04);
- SetPixel(x + 3, y, data & 0x08);
- SetPixel(x + 4, y, data & 0x01);
- SetPixel(x + 5, y, data & 0x02);
- SetPixel(x + 6, y, data & 0x04);
- }
- for (int i = 0; i < LoresHeight; i++, y++)
- {
- SetPixel(x + 0, y, data & 0x10);
- SetPixel(x + 1, y, data & 0x20);
- SetPixel(x + 2, y, data & 0x40);
- SetPixel(x + 3, y, data & 0x80);
- SetPixel(x + 4, y, data & 0x10);
- SetPixel(x + 5, y, data & 0x20);
- SetPixel(x + 6, y, data & 0x40);
- }
- }
- else
- {
- int color = ColorDLores[((x & 0x01) << 4) | (data & 0x0F)];
- for (int i = 0; i < LoresHeight; i++, y++)
- {
- SetPixel(x + 0, y, color);
- SetPixel(x + 1, y, color);
- SetPixel(x + 2, y, color);
- SetPixel(x + 3, y, color);
- SetPixel(x + 4, y, color);
- SetPixel(x + 5, y, color);
- SetPixel(x + 6, y, color);
- }
- color = ColorDLores[((x & 0x01) << 4) | (data >> 4)];
- for (int i = 0; i < LoresHeight; i++, y++)
- {
- SetPixel(x + 0, y, color);
- SetPixel(x + 1, y, color);
- SetPixel(x + 2, y, color);
- SetPixel(x + 3, y, color);
- SetPixel(x + 4, y, color);
- SetPixel(x + 5, y, color);
- SetPixel(x + 6, y, color);
- }
- }
- }
-
- private void DrawHires(int address, int x, int y)
- {
- if (IsMonochrome)
- {
- int data = _memory.ReadRamMainRegion02BF(address);
- SetPixel(x + 0, y, data & 0x01);
- SetPixel(x + 1, y, data & 0x01);
- SetPixel(x + 2, y, data & 0x02);
- SetPixel(x + 3, y, data & 0x02);
- SetPixel(x + 4, y, data & 0x04);
- SetPixel(x + 5, y, data & 0x04);
- SetPixel(x + 6, y, data & 0x08);
- SetPixel(x + 7, y, data & 0x08);
- SetPixel(x + 8, y, data & 0x10);
- SetPixel(x + 9, y, data & 0x10);
- SetPixel(x + 10, y, data & 0x20);
- SetPixel(x + 11, y, data & 0x20);
- SetPixel(x + 12, y, data & 0x40);
- SetPixel(x + 13, y, data & 0x40);
- }
- else
- {
- // 3 2 1 0
- // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- //
- // - - - - - - - - 0 0 0 0 0 0 0 0 + + + + + + + +
- // H 1 0 H 6 5 4 3 2 1 0 H 1 0
-
- int data = _memory.ReadRamMainRegion02BF(address) << 8;
- if (x < Width - CellWidth)
- {
- data |= _memory.ReadRamMainRegion02BF(address + 1);
- SetPixel(x + 14, y, ColorHires[((~x & 0x02) << 3) | ((data >> 4) & 0x08) | ((data << 1) & 0x06) | ((data >> 14) & 0x01)]);
- SetPixel(x + 15, y, ColorHires[((~x & 0x02) << 3) | ((data >> 4) & 0x08) | ((data << 1) & 0x06) | ((data >> 14) & 0x01)]);
- }
- if (x > 0)
- {
- data |= _memory.ReadRamMainRegion02BF(address - 1) << 16;
- SetPixel(x - 2, y, ColorHires[((~x & 0x02) << 3) | ((data >> 20) & 0x08) | ((data >> 6) & 0x04) | ((data >> 21) & 0x03)]);
- SetPixel(x - 1, y, ColorHires[((~x & 0x02) << 3) | ((data >> 20) & 0x08) | ((data >> 6) & 0x04) | ((data >> 21) & 0x03)]);
- }
- SetPixel(x + 0, y, ColorHires[((x & 0x02) << 3) | ((data >> 12) & 0x08) | ((data >> 7) & 0x06) | ((data >> 22) & 0x01)]);
- SetPixel(x + 1, y, ColorHires[((x & 0x02) << 3) | ((data >> 12) & 0x08) | ((data >> 7) & 0x06) | ((data >> 22) & 0x01)]);
- SetPixel(x + 2, y, ColorHires[((~x & 0x02) << 3) | ((data >> 12) & 0x08) | ((data >> 8) & 0x07)]);
- SetPixel(x + 3, y, ColorHires[((~x & 0x02) << 3) | ((data >> 12) & 0x08) | ((data >> 8) & 0x07)]);
- SetPixel(x + 4, y, ColorHires[((x & 0x02) << 3) | ((data >> 12) & 0x08) | ((data >> 9) & 0x07)]);
- SetPixel(x + 5, y, ColorHires[((x & 0x02) << 3) | ((data >> 12) & 0x08) | ((data >> 9) & 0x07)]);
- SetPixel(x + 6, y, ColorHires[((~x & 0x02) << 3) | ((data >> 12) & 0x08) | ((data >> 10) & 0x07)]);
- SetPixel(x + 7, y, ColorHires[((~x & 0x02) << 3) | ((data >> 12) & 0x08) | ((data >> 10) & 0x07)]);
- SetPixel(x + 8, y, ColorHires[((x & 0x02) << 3) | ((data >> 12) & 0x08) | ((data >> 11) & 0x07)]);
- SetPixel(x + 9, y, ColorHires[((x & 0x02) << 3) | ((data >> 12) & 0x08) | ((data >> 11) & 0x07)]);
- SetPixel(x + 10, y, ColorHires[((~x & 0x02) << 3) | ((data >> 12) & 0x0F)]);
- SetPixel(x + 11, y, ColorHires[((~x & 0x02) << 3) | ((data >> 12) & 0x0F)]);
- SetPixel(x + 12, y, ColorHires[((x & 0x02) << 3) | ((data >> 12) & 0x08) | ((data << 2) & 0x04) | ((data >> 13) & 0x03)]);
- SetPixel(x + 13, y, ColorHires[((x & 0x02) << 3) | ((data >> 12) & 0x08) | ((data << 2) & 0x04) | ((data >> 13) & 0x03)]);
- }
- }
-
- private void DrawNDHires(int address, int x, int y)
- {
- if (IsMonochrome)
- {
- int data = _memory.ReadRamMainRegion02BF(address);
- SetPixel(x + 0, y, data & 0x01);
- SetPixel(x + 1, y, data & 0x01);
- SetPixel(x + 2, y, data & 0x02);
- SetPixel(x + 3, y, data & 0x02);
- SetPixel(x + 4, y, data & 0x04);
- SetPixel(x + 5, y, data & 0x04);
- SetPixel(x + 6, y, data & 0x08);
- SetPixel(x + 7, y, data & 0x08);
- SetPixel(x + 8, y, data & 0x10);
- SetPixel(x + 9, y, data & 0x10);
- SetPixel(x + 10, y, data & 0x20);
- SetPixel(x + 11, y, data & 0x20);
- SetPixel(x + 12, y, data & 0x40);
- SetPixel(x + 13, y, data & 0x40);
- }
- else
- {
- // 3 2 1 0
- // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- //
- // - - - - - - - - 0 0 0 0 0 0 0 0 + + + + + + + +
- // X 1 0 X 6 5 4 3 2 1 0 X 1 0
-
- int data = _memory.ReadRamMainRegion02BF(address) << 8;
- if (x < Width - CellWidth)
- {
- data |= _memory.ReadRamMainRegion02BF(address + 1);
- SetPixel(x + 14, y, ColorHires[((~x & 0x02) << 3) | ((data << 1) & 0x06) | ((data >> 14) & 0x01)]);
- SetPixel(x + 15, y, ColorHires[((~x & 0x02) << 3) | ((data << 1) & 0x06) | ((data >> 14) & 0x01)]);
- }
- if (x > 0)
- {
- data |= _memory.ReadRamMainRegion02BF(address - 1) << 16;
- SetPixel(x - 2, y, ColorHires[((~x & 0x02) << 3) | ((data >> 6) & 0x04) | ((data >> 21) & 0x03)]);
- SetPixel(x - 1, y, ColorHires[((~x & 0x02) << 3) | ((data >> 6) & 0x04) | ((data >> 21) & 0x03)]);
- }
- SetPixel(x + 0, y, ColorHires[((x & 0x02) << 3) | ((data >> 7) & 0x06) | ((data >> 22) & 0x01)]);
- SetPixel(x + 1, y, ColorHires[((x & 0x02) << 3) | ((data >> 7) & 0x06) | ((data >> 22) & 0x01)]);
- SetPixel(x + 2, y, ColorHires[((~x & 0x02) << 3) | ((data >> 8) & 0x07)]);
- SetPixel(x + 3, y, ColorHires[((~x & 0x02) << 3) | ((data >> 8) & 0x07)]);
- SetPixel(x + 4, y, ColorHires[((x & 0x02) << 3) | ((data >> 9) & 0x07)]);
- SetPixel(x + 5, y, ColorHires[((x & 0x02) << 3) | ((data >> 9) & 0x07)]);
- SetPixel(x + 6, y, ColorHires[((~x & 0x02) << 3) | ((data >> 10) & 0x07)]);
- SetPixel(x + 7, y, ColorHires[((~x & 0x02) << 3) | ((data >> 10) & 0x07)]);
- SetPixel(x + 8, y, ColorHires[((x & 0x02) << 3) | ((data >> 11) & 0x07)]);
- SetPixel(x + 9, y, ColorHires[((x & 0x02) << 3) | ((data >> 11) & 0x07)]);
- SetPixel(x + 10, y, ColorHires[((~x & 0x02) << 3) | ((data >> 12) & 0x07)]);
- SetPixel(x + 11, y, ColorHires[((~x & 0x02) << 3) | ((data >> 12) & 0x07)]);
- SetPixel(x + 12, y, ColorHires[((x & 0x02) << 3) | ((data << 2) & 0x04) | ((data >> 13) & 0x03)]);
- SetPixel(x + 13, y, ColorHires[((x & 0x02) << 3) | ((data << 2) & 0x04) | ((data >> 13) & 0x03)]);
- }
- }
-
- private void DrawDHiresA(int address, int x, int y)
- {
- if (IsMonochrome)
- {
- if ((x & 0x2) == 0x00) // even cell
- {
- int data = ((_memory.ReadRamMainRegion02BF(address) << 7) & 0x80) | (_memory.ReadRamAuxRegion02BF(address) & 0x7F);
- SetPixel(x + 0, y, data & 0x01);
- SetPixel(x + 1, y, data & 0x02);
- SetPixel(x + 2, y, data & 0x04);
- SetPixel(x + 3, y, data & 0x08);
- SetPixel(x + 4, y, data & 0x10);
- SetPixel(x + 5, y, data & 0x20);
- SetPixel(x + 6, y, data & 0x40);
- SetPixel(x + 7, y, data & 0x80);
- }
- else
- {
- int data = ((_memory.ReadRamMainRegion02BF(address) << 9) & 0xE00) | ((_memory.ReadRamAuxRegion02BF(address) << 2) & 0x1FC) |
- ((_memory.ReadRamMainRegion02BF(address - 1) >> 5) & 0x003);
- SetPixel(x - 2, y, data & 0x01);
- SetPixel(x - 1, y, data & 0x02);
- SetPixel(x + 0, y, data & 0x04);
- SetPixel(x + 1, y, data & 0x08);
- SetPixel(x + 2, y, data & 0x10);
- SetPixel(x + 3, y, data & 0x20);
- SetPixel(x + 4, y, data & 0x40);
- SetPixel(x + 5, y, data & 0x80);
- SetPixel(x + 6, y, (data >> 8) & 0x01);
- SetPixel(x + 7, y, (data >> 8) & 0x02);
- SetPixel(x + 8, y, (data >> 8) & 0x04);
- SetPixel(x + 9, y, (data >> 8) & 0x08);
- }
- }
- else
- {
- if ((x & 0x2) == 0x00) // even cell
- {
- int data = ((_memory.ReadRamMainRegion02BF(address) << 7) & 0x80) | (_memory.ReadRamAuxRegion02BF(address) & 0x7F);
- SetPixel(x + 0, y, ColorDHires0 | (data & 0x0F));
- SetPixel(x + 1, y, ColorDHires0 | (data & 0x0F));
- SetPixel(x + 2, y, ColorDHires0 | (data & 0x0F));
- SetPixel(x + 3, y, ColorDHires0 | (data & 0x0F));
- SetPixel(x + 4, y, ColorDHires0 | (data >> 4));
- SetPixel(x + 5, y, ColorDHires0 | (data >> 4));
- SetPixel(x + 6, y, ColorDHires0 | (data >> 4));
- SetPixel(x + 7, y, ColorDHires0 | (data >> 4));
- }
- else
- {
- int data = ((_memory.ReadRamMainRegion02BF(address) << 9) & 0xE00) | ((_memory.ReadRamAuxRegion02BF(address) << 2) & 0x1FC) |
- ((_memory.ReadRamMainRegion02BF(address - 1) >> 5) & 0x003);
- SetPixel(x - 2, y, ColorDHires0 | (data & 0x0F));
- SetPixel(x - 1, y, ColorDHires0 | (data & 0x0F));
- SetPixel(x + 0, y, ColorDHires0 | (data & 0x0F));
- SetPixel(x + 1, y, ColorDHires0 | (data & 0x0F));
- SetPixel(x + 2, y, ColorDHires0 | ((data >> 4) & 0x0F));
- SetPixel(x + 3, y, ColorDHires0 | ((data >> 4) & 0x0F));
- SetPixel(x + 4, y, ColorDHires0 | ((data >> 4) & 0x0F));
- SetPixel(x + 5, y, ColorDHires0 | ((data >> 4) & 0x0F));
- SetPixel(x + 6, y, ColorDHires0 | (data >> 8));
- SetPixel(x + 7, y, ColorDHires0 | (data >> 8));
- SetPixel(x + 8, y, ColorDHires0 | (data >> 8));
- SetPixel(x + 9, y, ColorDHires0 | (data >> 8));
- }
- }
- }
-
- private void DrawDHiresM(int address, int x, int y)
- {
- if (IsMonochrome)
- {
- if ((x & 0x2) == 0x02) // odd cell
- {
- int data = ((_memory.ReadRamMainRegion02BF(address) << 1) & 0xFE) | ((_memory.ReadRamAuxRegion02BF(address) >> 6) & 0x01);
- SetPixel(x + 6, y, data & 0x01);
- SetPixel(x + 7, y, data & 0x02);
- SetPixel(x + 8, y, data & 0x04);
- SetPixel(x + 9, y, data & 0x08);
- SetPixel(x + 10, y, data & 0x10);
- SetPixel(x + 11, y, data & 0x20);
- SetPixel(x + 12, y, data & 0x40);
- SetPixel(x + 13, y, data & 0x80);
- }
- else
- {
- int data = ((_memory.ReadRamAuxRegion02BF(address + 1) << 10) & 0xC00) | ((_memory.ReadRamMainRegion02BF(address) << 3) & 0x3F8) |
- ((_memory.ReadRamAuxRegion02BF(address) >> 4) & 0x007);
- SetPixel(x + 4, y, data & 0x01);
- SetPixel(x + 5, y, data & 0x02);
- SetPixel(x + 6, y, data & 0x04);
- SetPixel(x + 7, y, data & 0x08);
- SetPixel(x + 8, y, data & 0x10);
- SetPixel(x + 9, y, data & 0x20);
- SetPixel(x + 10, y, data & 0x40);
- SetPixel(x + 11, y, data & 0x80);
- SetPixel(x + 12, y, (data >> 8) & 0x01);
- SetPixel(x + 13, y, (data >> 8) & 0x02);
- SetPixel(x + 14, y, (data >> 8) & 0x04);
- SetPixel(x + 15, y, (data >> 8) & 0x08);
- }
- }
- else
- {
- if ((x & 0x2) == 0x02) // odd cell
- {
- int data = ((_memory.ReadRamMainRegion02BF(address) << 1) & 0xFE) | ((_memory.ReadRamAuxRegion02BF(address) >> 6) & 0x01);
- SetPixel(x + 6, y, ColorDHires0 | (data & 0x0F));
- SetPixel(x + 7, y, ColorDHires0 | (data & 0x0F));
- SetPixel(x + 8, y, ColorDHires0 | (data & 0x0F));
- SetPixel(x + 9, y, ColorDHires0 | (data & 0x0F));
- SetPixel(x + 10, y, ColorDHires0 | (data >> 4));
- SetPixel(x + 11, y, ColorDHires0 | (data >> 4));
- SetPixel(x + 12, y, ColorDHires0 | (data >> 4));
- SetPixel(x + 13, y, ColorDHires0 | (data >> 4));
- }
- else
- {
- int data = ((_memory.ReadRamAuxRegion02BF(address + 1) << 10) & 0xC00) | ((_memory.ReadRamMainRegion02BF(address) << 3) & 0x3F8) |
- ((_memory.ReadRamAuxRegion02BF(address) >> 4) & 0x007);
- SetPixel(x + 4, y, ColorDHires0 | (data & 0x0F));
- SetPixel(x + 5, y, ColorDHires0 | (data & 0x0F));
- SetPixel(x + 6, y, ColorDHires0 | (data & 0x0F));
- SetPixel(x + 7, y, ColorDHires0 | (data & 0x0F));
- SetPixel(x + 8, y, ColorDHires0 | ((data >> 4) & 0x0F));
- SetPixel(x + 9, y, ColorDHires0 | ((data >> 4) & 0x0F));
- SetPixel(x + 10, y, ColorDHires0 | ((data >> 4) & 0x0F));
- SetPixel(x + 11, y, ColorDHires0 | ((data >> 4) & 0x0F));
- SetPixel(x + 12, y, ColorDHires0 | (data >> 8));
- SetPixel(x + 13, y, ColorDHires0 | (data >> 8));
- SetPixel(x + 14, y, ColorDHires0 | (data >> 8));
- SetPixel(x + 15, y, ColorDHires0 | (data >> 8));
- }
- }
- }
- #endregion
-
- #region Flush Methods
- private void FlushRowMode0(int y)
- {
- int address = (_memory.IsVideoPage2 ? 0x0800 : 0x0400) + AddressOffset[y];
- for (int x = 0; x < CellColumns; x++)
- {
- if (_isCellDirty[CellColumns * y + x])
- {
- _isCellDirty[CellColumns * y + x] = false;
- DrawLores(_memory.ReadRamMainRegion02BF(address + x), CellWidth * x, y); // lores
- }
- }
- }
-
- private void FlushRowMode1(int y)
- {
- int address = (_memory.IsVideoPage2 ? 0x0800 : 0x0400) + AddressOffset[y];
- for (int x = 0; x < CellColumns; x++)
- {
- if (_isCellDirty[CellColumns * y + x])
- {
- _isCellDirty[CellColumns * y + x] = false;
- DrawText40(_memory.ReadRamMainRegion02BF(address + x), CellWidth * x, y); // text40
- }
- }
- }
-
- private void FlushRowMode2(int y)
- {
- int address = (_memory.IsVideoPage2 ? 0x0800 : 0x0400) + AddressOffset[y];
- for (int x = 0; x < 2 * CellColumns; x += 2)
- {
- if (_isCellDirty[CellColumns * y + x / 2])
- {
- _isCellDirty[CellColumns * y + x / 2] = false;
- DrawText80(_memory.ReadRamAuxRegion02BF(address + x / 2), CellWidth / 2 * (x + 0), y); // text80
- DrawText80(_memory.ReadRamMainRegion02BF(address + x / 2), CellWidth / 2 * (x + 1), y);
- }
- }
- }
-
- private void FlushRowMode3(int y)
- {
- if (y < MixedHeight)
- {
- FlushRowMode0(y); // lores
- }
- else
- {
- FlushRowMode1(y); // text40
- }
- }
-
- private void FlushRowMode4(int y)
- {
- if (y < MixedHeight)
- {
- FlushRowMode0(y); // lores
- }
- else
- {
- FlushRowMode2(y); // text80
- }
- }
-
- private void FlushRowMode5(int y)
- {
- int address = _memory.IsVideoPage2 ? 0x4000 : 0x2000;
- for (int i = 0; i < CellHeight; i++, y++)
- {
- for (int x = 0; x < CellColumns; x++)
- {
- if (_isCellDirty[CellColumns * y + x])
- {
- _isCellDirty[CellColumns * y + x] = false;
- DrawHires(address + AddressOffset[y] + x, CellWidth * x, y); // hires
- }
- }
- }
- }
-
- private void FlushRowMode6(int y)
- {
- if (y < MixedHeight)
- {
- FlushRowMode5(y); // hires
- }
- else
- {
- FlushRowMode1(y); // text40
- }
- }
-
- private void FlushRowMode7(int y)
- {
- if (y < MixedHeight)
- {
- FlushRowMode5(y); // hires
- }
- else
- {
- FlushRowMode2(y); // text80
- }
- }
-
- private void FlushRowMode8(int y)
- {
- int address = (_memory.IsVideoPage2 ? 0x0800 : 0x0400) + AddressOffset[y];
- for (int x = 0; x < CellColumns; x++)
- {
- if (_isCellDirty[CellColumns * y + x])
- {
- _isCellDirty[CellColumns * y + x] = false;
- Draw7MLores(_memory.ReadRamMainRegion02BF(address + x), CellWidth * x, y); // 7mlores
- }
- }
- }
-
- private void FlushRowMode9(int y)
- {
- int address = (_memory.IsVideoPage2 ? 0x0800 : 0x0400) + AddressOffset[y];
- for (int x = 0; x < 2 * CellColumns; x += 2)
- {
- if (_isCellDirty[CellColumns * y + x / 2])
- {
- _isCellDirty[CellColumns * y + x / 2] = false;
- DrawDLores(_memory.ReadRamAuxRegion02BF(address + x / 2), CellWidth / 2 * (x + 0), y); // dlores
- DrawDLores(_memory.ReadRamMainRegion02BF(address + x / 2), CellWidth / 2 * (x + 1), y);
- }
- }
- }
-
- private void FlushRowModeA(int y)
- {
- if (y < MixedHeight)
- {
- FlushRowMode8(y); // 7mlores
- }
- else
- {
- FlushRowMode1(y); // text40
- }
- }
-
- private void FlushRowModeB(int y)
- {
- if (y < MixedHeight)
- {
- FlushRowMode9(y); // dlores
- }
- else
- {
- FlushRowMode2(y); // text80
- }
- }
-
- private void FlushRowModeC(int y)
- {
- int address = _memory.IsVideoPage2 ? 0x4000 : 0x2000;
- for (int i = 0; i < CellHeight; i++, y++)
- {
- for (int x = 0; x < CellColumns; x++)
- {
- if (_isCellDirty[CellColumns * y + x])
- {
- _isCellDirty[CellColumns * y + x] = false;
- DrawNDHires(address + AddressOffset[y] + x, CellWidth * x, y); // ndhires
- }
- }
- }
- }
-
- private void FlushRowModeD(int y)
- {
- int address = _memory.IsVideoPage2 ? 0x4000 : 0x2000;
- for (int i = 0; i < CellHeight; i++, y++)
- {
- for (int x = 0; x < CellColumns; x++)
- {
- if (_isCellDirty[CellColumns * y + x])
- {
- _isCellDirty[CellColumns * y + x] = false;
- DrawDHiresA(address + AddressOffset[y] + x, CellWidth * x, y); // dhires
- DrawDHiresM(address + AddressOffset[y] + x, CellWidth * x, y);
- }
- }
- }
- }
-
- private void FlushRowModeE(int y)
- {
- if (y < MixedHeight)
- {
- FlushRowModeC(y); // ndhires
- }
- else
- {
- FlushRowMode1(y); // text40
- }
- }
-
- private void FlushRowModeF(int y)
- {
- if (y < MixedHeight)
- {
- FlushRowModeD(y); // dhires
- }
- else
- {
- FlushRowMode2(y); // text80
- }
- }
- #endregion
-
- private void FlushRowEvent()
- {
- int y = (_cyclesPerVSync - _cyclesPerVBlankPreset - Machine.Events.FindEvent(_resetVSyncEvent)) / CyclesPerHSync;
-
- FlushRowMode[_memory.VideoMode](y - CellHeight); // in arrears
-
- if (y < Height)
- {
- Machine.Events.AddEvent(CyclesPerFlush, _flushRowEvent);
- }
- else
- {
- IsVBlank = true;
-
- Machine.Events.AddEvent(_cyclesPerVBlank, _leaveVBlankEvent);
- }
- }
-
- private void FlushScreen()
- {
- var flushRowMode = FlushRowMode[_memory.VideoMode];
-
- for (int y = 0; y < Height; y += CellHeight)
- {
- flushRowMode(y);
- }
- }
-
- private void InverseTextEvent()
- {
- _isTextInversed = !_isTextInversed;
-
- DirtyScreenText();
-
- Machine.Events.AddEvent(_cyclesPerFlash, _inverseTextEvent);
- }
-
- private void LeaveVBlankEvent()
- {
- IsVBlank = false;
-
- Machine.Events.AddEvent(CyclesPerFlush, _flushRowEvent);
- }
-
- private void ResetVSyncEvent()
- {
- Machine.Events.AddEvent(_cyclesPerVSync, _resetVSyncEvent);
- }
-
- private void SetPalette()
- {
- _colorPalette[ColorMono00] = _colorBlack;
- _colorPalette[ColorMono01] = _colorMonochrome;
- _colorPalette[ColorMono02] = _colorMonochrome;
- _colorPalette[ColorMono04] = _colorMonochrome;
- _colorPalette[ColorMono08] = _colorMonochrome;
- _colorPalette[ColorMono10] = _colorMonochrome;
- _colorPalette[ColorMono20] = _colorMonochrome;
- _colorPalette[ColorMono40] = _colorMonochrome;
- _colorPalette[ColorMono80] = _colorMonochrome;
-
- _colorPalette[ColorWhite00] = _colorBlack;
- _colorPalette[ColorWhite01] = _colorWhite;
- _colorPalette[ColorWhite02] = _colorWhite;
- _colorPalette[ColorWhite04] = _colorWhite;
- _colorPalette[ColorWhite08] = _colorWhite;
- _colorPalette[ColorWhite10] = _colorWhite;
- _colorPalette[ColorWhite20] = _colorWhite;
- _colorPalette[ColorWhite40] = _colorWhite;
- _colorPalette[ColorWhite80] = _colorWhite;
-
- _colorPalette[ColorDHires0] = _colorBlack;
- _colorPalette[ColorDHires1] = _colorDarkBlue;
- _colorPalette[ColorDHires2] = _colorDarkGreen;
- _colorPalette[ColorDHires3] = _colorMediumBlue;
- _colorPalette[ColorDHires4] = _colorBrown;
- _colorPalette[ColorDHires5] = _colorLightGrey;
- _colorPalette[ColorDHires6] = _colorGreen;
- _colorPalette[ColorDHires7] = _colorAquamarine;
- _colorPalette[ColorDHires8] = _colorDeepRed;
- _colorPalette[ColorDHires9] = _colorPurple;
- _colorPalette[ColorDHiresA] = _colorDarkGrey;
- _colorPalette[ColorDHiresB] = _colorLightBlue;
- _colorPalette[ColorDHiresC] = _colorOrange;
- _colorPalette[ColorDHiresD] = _colorPink;
- _colorPalette[ColorDHiresE] = _colorYellow;
- _colorPalette[ColorDHiresF] = _colorWhite;
-
- DirtyScreen();
- }
-
- private void SetPixel(int x, int y, int color)
- {
- _videoService.SetPixel(x, 2 * y, _colorPalette[color]);
- }
-
- private void SetScanner()
- {
- if ((_scannerOptions & ScannerOptions.Pal) != 0)
- {
- _vCountPreset = VCountPresetPal;
- _vLineLeaveVBlank = VLineLeaveVBlankPal;
- }
- else
- {
- _vCountPreset = VCountPresetNtsc;
- _vLineLeaveVBlank = VLineLeaveVBlankNtsc;
- }
-
- _cyclesPerVBlank = (_vLineLeaveVBlank - VLineEnterVBlank) * CyclesPerHSync;
- _cyclesPerVBlankPreset = (_vLineLeaveVBlank - VLineTriggerPreset) * CyclesPerHSync; // cycles during vblank after vcount preset [3-15, 3-16]
- _cyclesPerVSync = _vLineLeaveVBlank * CyclesPerHSync;
- _cyclesPerFlash = VSyncsPerFlash * _cyclesPerVSync;
- }
-
- public uint ColorBlack { get { return _colorBlack; } set { _colorBlack = value; SetPalette(); } }
- public uint ColorDarkBlue { get { return _colorDarkBlue; } set { _colorDarkBlue = value; SetPalette(); } }
- public uint ColorDarkGreen { get { return _colorDarkGreen; } set { _colorDarkGreen = value; SetPalette(); } }
- public uint ColorMediumBlue { get { return _colorMediumBlue; } set { _colorMediumBlue = value; SetPalette(); } }
- public uint ColorBrown { get { return _colorBrown; } set { _colorBrown = value; SetPalette(); } }
- public uint ColorLightGrey { get { return _colorLightGrey; } set { _colorLightGrey = value; SetPalette(); } }
- public uint ColorGreen { get { return _colorGreen; } set { _colorGreen = value; SetPalette(); } }
- public uint ColorAquamarine { get { return _colorAquamarine; } set { _colorAquamarine = value; SetPalette(); } }
- public uint ColorDeepRed { get { return _colorDeepRed; } set { _colorDeepRed = value; SetPalette(); } }
- public uint ColorPurple { get { return _colorPurple; } set { _colorPurple = value; SetPalette(); } }
- public uint ColorDarkGrey { get { return _colorDarkGrey; } set { _colorDarkGrey = value; SetPalette(); } }
- public uint ColorLightBlue { get { return _colorLightBlue; } set { _colorLightBlue = value; SetPalette(); } }
- public uint ColorOrange { get { return _colorOrange; } set { _colorOrange = value; SetPalette(); } }
- public uint ColorPink { get { return _colorPink; } set { _colorPink = value; SetPalette(); } }
- public uint ColorYellow { get { return _colorYellow; } set { _colorYellow = value; SetPalette(); } }
- public uint ColorWhite { get { return _colorWhite; } set { _colorWhite = value; SetPalette(); } }
- public uint ColorMonochrome { get { return _colorMonochrome; } set { _colorMonochrome = value; SetPalette(); } }
-
- public bool IsFullScreen { get { return _isFullScreen; } set { _isFullScreen = value; _videoService.SetFullScreen(_isFullScreen); } }
- public bool IsMonochrome { get { return _isMonochrome; } set { _isMonochrome = value; DirtyScreen(); } }
- public ScannerOptions ScannerOptions { get { return _scannerOptions; } set { _scannerOptions = value; SetScanner(); } }
-
- public bool IsVBlank { get; private set; }
-
- private Action _flushRowEvent;
- private Action _inverseTextEvent;
- private Action _leaveVBlankEvent;
- private Action _resetVSyncEvent;
-
- private Memory _memory;
- private VideoService _videoService;
-
- private uint _colorBlack;
- private uint _colorDarkBlue;
- private uint _colorDarkGreen;
- private uint _colorMediumBlue;
- private uint _colorBrown;
- private uint _colorLightGrey;
- private uint _colorGreen;
- private uint _colorAquamarine;
- private uint _colorDeepRed;
- private uint _colorPurple;
- private uint _colorDarkGrey;
- private uint _colorLightBlue;
- private uint _colorOrange;
- private uint _colorPink;
- private uint _colorYellow;
- private uint _colorWhite;
- private uint _colorMonochrome;
- private bool _isFullScreen;
- private bool _isMonochrome;
- private bool _isTextInversed;
- private ScannerOptions _scannerOptions;
- private int _cyclesPerVBlank;
- private int _cyclesPerVBlankPreset;
- private int _cyclesPerVSync;
- private int _cyclesPerFlash;
- private int _vCountPreset;
- private int _vLineLeaveVBlank;
-
- private ushort[] _charSet;
- private uint[] _colorPalette = new uint[ColorPaletteCount];
- private bool[] _isCellDirty = new bool[Height * CellColumns + 1]; // includes sentinel
- }
-}
+using System;
+using System.IO;
+using Jellyfish.Virtu.Services;
+
+namespace Jellyfish.Virtu
+{
+ [Flags]
+ public enum ScannerOptions { None = 0x0, AppleII = 0x1, Pal = 0x2 } // defaults to AppleIIe, Ntsc
+
+ public sealed partial class Video : MachineComponent
+ {
+ public Video(Machine machine) :
+ base(machine)
+ {
+ _flushRowEvent = FlushRowEvent; // cache delegates; avoids garbage
+ _inverseTextEvent = InverseTextEvent;
+ _leaveVBlankEvent = LeaveVBlankEvent;
+ _resetVSyncEvent = ResetVSyncEvent;
+
+ FlushRowMode = new Action[ModeCount]
+ {
+ FlushRowMode0, FlushRowMode1, FlushRowMode2, FlushRowMode3, FlushRowMode4, FlushRowMode5, FlushRowMode6, FlushRowMode7,
+ FlushRowMode8, FlushRowMode9, FlushRowModeA, FlushRowModeB, FlushRowModeC, FlushRowModeD, FlushRowModeE, FlushRowModeF
+ };
+ }
+
+ public override void Initialize()
+ {
+ _memory = Machine.Memory;
+ _videoService = Machine.Services.GetService();
+
+#if SILVERLIGHT || WPF
+ _colorBlack = 0xFF000000; // BGRA
+ _colorDarkBlue = 0xFF000099;
+ _colorDarkGreen = 0xFF117722;
+ _colorMediumBlue = 0xFF0000FF;
+ _colorBrown = 0xFF885500;
+ _colorLightGrey = 0xFF99AAAA;
+ _colorGreen = 0xFF00EE11;
+ _colorAquamarine = 0xFF55FFAA;
+ _colorDeepRed = 0xFFFF1111;
+ _colorPurple = 0xFFDD00DD;
+ _colorDarkGrey = 0xFF445555;
+ _colorLightBlue = 0xFF33AAFF;
+ _colorOrange = 0xFFFF4411;
+ _colorPink = 0xFFFF9988;
+ _colorYellow = 0xFFFFFF11;
+ _colorWhite = 0xFFFFFFFF;
+ _colorMonochrome = 0xFF00AA00;
+#else
+ _colorBlack = 0xFF000000; // RGBA
+ _colorDarkBlue = 0xFF990000;
+ _colorDarkGreen = 0xFF227711;
+ _colorMediumBlue = 0xFFFF0000;
+ _colorBrown = 0xFF005588;
+ _colorLightGrey = 0xFFAAAA99;
+ _colorGreen = 0xFF11EE00;
+ _colorAquamarine = 0xFFAAFF55;
+ _colorDeepRed = 0xFF1111FF;
+ _colorPurple = 0xFFDD00DD;
+ _colorDarkGrey = 0xFF555544;
+ _colorLightBlue = 0xFFFFAA33;
+ _colorOrange = 0xFF1144FF;
+ _colorPink = 0xFF8899FF;
+ _colorYellow = 0xFF11FFFF;
+ _colorWhite = 0xFFFFFFFF;
+ _colorMonochrome = 0xFF00AA00;
+#endif
+ SetPalette();
+
+ IsFullScreen = false;
+ IsMonochrome = false;
+ ScannerOptions = ScannerOptions.None;
+
+ IsVBlank = true;
+
+ Machine.Events.AddEvent(_cyclesPerVBlankPreset, _leaveVBlankEvent); // align flush events with scanner; assumes vcount preset at start of frame [3-15, 3-16]
+ Machine.Events.AddEvent(_cyclesPerVSync, _resetVSyncEvent);
+ Machine.Events.AddEvent(_cyclesPerFlash, _inverseTextEvent);
+ }
+
+ public override void Reset()
+ {
+ SetCharSet();
+ DirtyScreen();
+ FlushScreen();
+ }
+
+ public override void LoadState(BinaryReader reader, Version version)
+ {
+ if (reader == null)
+ {
+ throw new ArgumentNullException("reader");
+ }
+
+ _colorBlack = reader.ReadUInt32();
+ _colorDarkBlue = reader.ReadUInt32();
+ _colorDarkGreen = reader.ReadUInt32();
+ _colorMediumBlue = reader.ReadUInt32();
+ _colorBrown = reader.ReadUInt32();
+ _colorLightGrey = reader.ReadUInt32();
+ _colorGreen = reader.ReadUInt32();
+ _colorAquamarine = reader.ReadUInt32();
+ _colorDeepRed = reader.ReadUInt32();
+ _colorPurple = reader.ReadUInt32();
+ _colorDarkGrey = reader.ReadUInt32();
+ _colorLightBlue = reader.ReadUInt32();
+ _colorOrange = reader.ReadUInt32();
+ _colorPink = reader.ReadUInt32();
+ _colorYellow = reader.ReadUInt32();
+ _colorWhite = reader.ReadUInt32();
+ _colorMonochrome = reader.ReadUInt32();
+ SetPalette();
+
+ IsFullScreen = reader.ReadBoolean();
+ IsMonochrome = reader.ReadBoolean();
+ ScannerOptions = (ScannerOptions)reader.ReadInt32();
+
+ SetCharSet();
+ DirtyScreen();
+ FlushScreen();
+ }
+
+ public override void SaveState(BinaryWriter writer)
+ {
+ if (writer == null)
+ {
+ throw new ArgumentNullException("writer");
+ }
+
+ writer.Write(_colorBlack);
+ writer.Write(_colorDarkBlue);
+ writer.Write(_colorDarkGreen);
+ writer.Write(_colorMediumBlue);
+ writer.Write(_colorBrown);
+ writer.Write(_colorLightGrey);
+ writer.Write(_colorGreen);
+ writer.Write(_colorAquamarine);
+ writer.Write(_colorDeepRed);
+ writer.Write(_colorPurple);
+ writer.Write(_colorDarkGrey);
+ writer.Write(_colorLightBlue);
+ writer.Write(_colorOrange);
+ writer.Write(_colorPink);
+ writer.Write(_colorYellow);
+ writer.Write(_colorWhite);
+ writer.Write(_colorMonochrome);
+
+ writer.Write(IsFullScreen);
+ writer.Write(IsMonochrome);
+ writer.Write((int)ScannerOptions);
+ }
+
+ public void DirtyCell(int addressOffset)
+ {
+ _isCellDirty[CellIndex[addressOffset]] = true;
+ }
+
+ public void DirtyCellMixed(int addressOffset)
+ {
+ int cellIndex = CellIndex[addressOffset];
+ if (cellIndex < MixedCellIndex)
+ {
+ _isCellDirty[cellIndex] = true;
+ }
+ }
+
+ public void DirtyCellMixedText(int addressOffset)
+ {
+ int cellIndex = CellIndex[addressOffset];
+ if (cellIndex >= MixedCellIndex)
+ {
+ _isCellDirty[cellIndex] = true;
+ }
+ }
+
+ public void DirtyScreen()
+ {
+ for (int i = 0; i < Height * CellColumns; i++)
+ {
+ _isCellDirty[i] = true;
+ }
+ }
+
+ public void DirtyScreenText()
+ {
+ if (_memory.IsText)
+ {
+ for (int i = 0; i < MixedHeight * CellColumns; i++)
+ {
+ _isCellDirty[i] = true;
+ }
+ }
+ if (_memory.IsText || _memory.IsMixed)
+ {
+ for (int i = MixedHeight * CellColumns; i < Height * CellColumns; i++)
+ {
+ _isCellDirty[i] = true;
+ }
+ }
+ }
+
+ public int ReadFloatingBus() // [5-40]
+ {
+ // derive scanner counters from current cycles into frame; assumes hcount and vcount preset at start of frame [3-13, 3-15, 3-16]
+ int cycles = _cyclesPerVSync - Machine.Events.FindEvent(_resetVSyncEvent);
+ int hClock = cycles % CyclesPerHSync;
+ int hCount = (hClock != 0) ? HCountPreset + hClock - 1 : 0;
+ int vLine = cycles / CyclesPerHSync;
+ int vCount = _vCountPreset + vLine;
+
+ // derive scanner address [5-8]
+ int address = ((vCount << 4) & 0x0380) | ((0x0068 + (hCount & 0x0038) + (((vCount >> 1) & 0x0060) | ((vCount >> 3) & 0x0018))) & 0x0078) | (hCount & 0x0007);
+ if (_memory.IsHires && !(_memory.IsMixed && ((vCount & 0xA0) == 0xA0))) // hires but not actively mixed [5-13, 5-19]
+ {
+ address |= (_memory.IsVideoPage2 ? 0x4000 : 0x2000) | ((vCount << 10) & 0x1C00);
+ }
+ else
+ {
+ address |= _memory.IsVideoPage2 ? 0x0800 : 0x0400;
+ if (((_scannerOptions & ScannerOptions.AppleII) != 0) && (hCount < HCountLeaveHBlank))
+ {
+ address |= 0x1000;
+ }
+ }
+
+ return _memory.Read(address);
+ }
+
+ public void SetCharSet()
+ {
+ _charSet = !_memory.IsCharSetAlternate ? CharSetPrimary : (_memory.Monitor == MonitorType.Standard) ? CharSetSecondaryStandard : CharSetSecondaryEnhanced;
+ DirtyScreenText();
+ }
+
+ #region Draw Methods
+ private void DrawText40(int data, int x, int y)
+ {
+ int color = IsMonochrome ? ColorMono00 : ColorWhite00;
+ int index = _charSet[data] * CharBitmapBytes;
+ int inverseMask = (_isTextInversed && !_memory.IsCharSetAlternate && (0x40 <= data) && (data <= 0x7F)) ? 0x7F : 0x00;
+ for (int i = 0; i < TextHeight; i++, y++)
+ {
+ data = CharBitmap[index + i] ^ inverseMask;
+ SetPixel(x + 0, y, color | (data & 0x01));
+ SetPixel(x + 1, y, color | (data & 0x01));
+ SetPixel(x + 2, y, color | (data & 0x02));
+ SetPixel(x + 3, y, color | (data & 0x02));
+ SetPixel(x + 4, y, color | (data & 0x04));
+ SetPixel(x + 5, y, color | (data & 0x04));
+ SetPixel(x + 6, y, color | (data & 0x08));
+ SetPixel(x + 7, y, color | (data & 0x08));
+ SetPixel(x + 8, y, color | (data & 0x10));
+ SetPixel(x + 9, y, color | (data & 0x10));
+ SetPixel(x + 10, y, color | (data & 0x20));
+ SetPixel(x + 11, y, color | (data & 0x20));
+ SetPixel(x + 12, y, color | (data & 0x40));
+ SetPixel(x + 13, y, color | (data & 0x40));
+ }
+ }
+
+ private void DrawText80(int data, int x, int y)
+ {
+ int color = IsMonochrome ? ColorMono00 : ColorWhite00;
+ int index = _charSet[data] * CharBitmapBytes;
+ int mask = (_isTextInversed && !_memory.IsCharSetAlternate && (0x40 <= data) && (data <= 0x7F)) ? 0x7F : 0x00;
+ for (int i = 0; i < TextHeight; i++, y++)
+ {
+ data = CharBitmap[index + i] ^ mask;
+ SetPixel(x + 0, y, color | (data & 0x01));
+ SetPixel(x + 1, y, color | (data & 0x02));
+ SetPixel(x + 2, y, color | (data & 0x04));
+ SetPixel(x + 3, y, color | (data & 0x08));
+ SetPixel(x + 4, y, color | (data & 0x10));
+ SetPixel(x + 5, y, color | (data & 0x20));
+ SetPixel(x + 6, y, color | (data & 0x40));
+ }
+ }
+
+ private void DrawLores(int data, int x, int y)
+ {
+ if (IsMonochrome)
+ {
+ if ((x & 0x02) == 0x02) // odd cell
+ {
+ data = ((data << 2) & 0xCC) | ((data >> 2) & 0x33);
+ }
+ for (int i = 0; i < LoresHeight; i++, y++)
+ {
+ SetPixel(x + 0, y, data & 0x01);
+ SetPixel(x + 1, y, data & 0x02);
+ SetPixel(x + 2, y, data & 0x04);
+ SetPixel(x + 3, y, data & 0x08);
+ SetPixel(x + 4, y, data & 0x01);
+ SetPixel(x + 5, y, data & 0x02);
+ SetPixel(x + 6, y, data & 0x04);
+ SetPixel(x + 7, y, data & 0x08);
+ SetPixel(x + 8, y, data & 0x01);
+ SetPixel(x + 9, y, data & 0x02);
+ SetPixel(x + 10, y, data & 0x04);
+ SetPixel(x + 11, y, data & 0x08);
+ SetPixel(x + 12, y, data & 0x01);
+ SetPixel(x + 13, y, data & 0x02);
+ }
+ for (int i = 0; i < LoresHeight; i++, y++)
+ {
+ SetPixel(x + 0, y, data & 0x10);
+ SetPixel(x + 1, y, data & 0x20);
+ SetPixel(x + 2, y, data & 0x40);
+ SetPixel(x + 3, y, data & 0x80);
+ SetPixel(x + 4, y, data & 0x10);
+ SetPixel(x + 5, y, data & 0x20);
+ SetPixel(x + 6, y, data & 0x40);
+ SetPixel(x + 7, y, data & 0x80);
+ SetPixel(x + 8, y, data & 0x10);
+ SetPixel(x + 9, y, data & 0x20);
+ SetPixel(x + 10, y, data & 0x40);
+ SetPixel(x + 11, y, data & 0x80);
+ SetPixel(x + 12, y, data & 0x10);
+ SetPixel(x + 13, y, data & 0x20);
+ }
+ }
+ else
+ {
+ int color = ColorLores[data & 0x0F];
+ for (int i = 0; i < LoresHeight; i++, y++)
+ {
+ SetPixel(x + 0, y, color);
+ SetPixel(x + 1, y, color);
+ SetPixel(x + 2, y, color);
+ SetPixel(x + 3, y, color);
+ SetPixel(x + 4, y, color);
+ SetPixel(x + 5, y, color);
+ SetPixel(x + 6, y, color);
+ SetPixel(x + 7, y, color);
+ SetPixel(x + 8, y, color);
+ SetPixel(x + 9, y, color);
+ SetPixel(x + 10, y, color);
+ SetPixel(x + 11, y, color);
+ SetPixel(x + 12, y, color);
+ SetPixel(x + 13, y, color);
+ }
+ color = ColorLores[data >> 4];
+ for (int i = 0; i < LoresHeight; i++, y++)
+ {
+ SetPixel(x + 0, y, color);
+ SetPixel(x + 1, y, color);
+ SetPixel(x + 2, y, color);
+ SetPixel(x + 3, y, color);
+ SetPixel(x + 4, y, color);
+ SetPixel(x + 5, y, color);
+ SetPixel(x + 6, y, color);
+ SetPixel(x + 7, y, color);
+ SetPixel(x + 8, y, color);
+ SetPixel(x + 9, y, color);
+ SetPixel(x + 10, y, color);
+ SetPixel(x + 11, y, color);
+ SetPixel(x + 12, y, color);
+ SetPixel(x + 13, y, color);
+ }
+ }
+ }
+
+ private void Draw7MLores(int data, int x, int y)
+ {
+ if (IsMonochrome)
+ {
+ if ((x & 0x02) == 0x02) // odd cell
+ {
+ data = ((data << 2) & 0xCC) | ((data >> 2) & 0x33);
+ }
+ for (int i = 0; i < LoresHeight; i++, y++)
+ {
+ SetPixel(x + 0, y, data & 0x01);
+ SetPixel(x + 1, y, data & 0x01);
+ SetPixel(x + 2, y, data & 0x02);
+ SetPixel(x + 3, y, data & 0x02);
+ SetPixel(x + 4, y, data & 0x04);
+ SetPixel(x + 5, y, data & 0x04);
+ SetPixel(x + 6, y, data & 0x08);
+ SetPixel(x + 7, y, data & 0x08);
+ SetPixel(x + 8, y, data & 0x01);
+ SetPixel(x + 9, y, data & 0x01);
+ SetPixel(x + 10, y, data & 0x02);
+ SetPixel(x + 11, y, data & 0x02);
+ SetPixel(x + 12, y, data & 0x04);
+ SetPixel(x + 13, y, data & 0x04);
+ }
+ for (int i = 0; i < LoresHeight; i++, y++)
+ {
+ SetPixel(x + 0, y, data & 0x10);
+ SetPixel(x + 1, y, data & 0x10);
+ SetPixel(x + 2, y, data & 0x20);
+ SetPixel(x + 3, y, data & 0x20);
+ SetPixel(x + 4, y, data & 0x40);
+ SetPixel(x + 5, y, data & 0x40);
+ SetPixel(x + 6, y, data & 0x80);
+ SetPixel(x + 7, y, data & 0x80);
+ SetPixel(x + 8, y, data & 0x10);
+ SetPixel(x + 9, y, data & 0x10);
+ SetPixel(x + 10, y, data & 0x20);
+ SetPixel(x + 11, y, data & 0x20);
+ SetPixel(x + 12, y, data & 0x40);
+ SetPixel(x + 13, y, data & 0x40);
+ }
+ }
+ else
+ {
+ int color = Color7MLores[((x & 0x02) << 3) | (data & 0x0F)];
+ for (int i = 0; i < LoresHeight; i++, y++)
+ {
+ SetPixel(x + 0, y, color);
+ SetPixel(x + 1, y, color);
+ SetPixel(x + 2, y, color);
+ SetPixel(x + 3, y, color);
+ SetPixel(x + 4, y, color);
+ SetPixel(x + 5, y, color);
+ SetPixel(x + 6, y, color);
+ SetPixel(x + 7, y, color);
+ SetPixel(x + 8, y, color);
+ SetPixel(x + 9, y, color);
+ SetPixel(x + 10, y, color);
+ SetPixel(x + 11, y, color);
+ SetPixel(x + 12, y, color);
+ SetPixel(x + 13, y, color);
+ }
+ color = Color7MLores[((x & 0x02) << 3) | (data >> 4)];
+ for (int i = 0; i < LoresHeight; i++, y++)
+ {
+ SetPixel(x + 0, y, color);
+ SetPixel(x + 1, y, color);
+ SetPixel(x + 2, y, color);
+ SetPixel(x + 3, y, color);
+ SetPixel(x + 4, y, color);
+ SetPixel(x + 5, y, color);
+ SetPixel(x + 6, y, color);
+ SetPixel(x + 7, y, color);
+ SetPixel(x + 8, y, color);
+ SetPixel(x + 9, y, color);
+ SetPixel(x + 10, y, color);
+ SetPixel(x + 11, y, color);
+ SetPixel(x + 12, y, color);
+ SetPixel(x + 13, y, color);
+ }
+ }
+ }
+
+ private void DrawDLores(int data, int x, int y)
+ {
+ if (IsMonochrome)
+ {
+ if ((x & 0x01) == 0x00) // even half cell
+ {
+ data = ((data << 1) & 0xEE) | ((data >> 3) & 0x11);
+ }
+ for (int i = 0; i < LoresHeight; i++, y++)
+ {
+ SetPixel(x + 0, y, data & 0x01);
+ SetPixel(x + 1, y, data & 0x02);
+ SetPixel(x + 2, y, data & 0x04);
+ SetPixel(x + 3, y, data & 0x08);
+ SetPixel(x + 4, y, data & 0x01);
+ SetPixel(x + 5, y, data & 0x02);
+ SetPixel(x + 6, y, data & 0x04);
+ }
+ for (int i = 0; i < LoresHeight; i++, y++)
+ {
+ SetPixel(x + 0, y, data & 0x10);
+ SetPixel(x + 1, y, data & 0x20);
+ SetPixel(x + 2, y, data & 0x40);
+ SetPixel(x + 3, y, data & 0x80);
+ SetPixel(x + 4, y, data & 0x10);
+ SetPixel(x + 5, y, data & 0x20);
+ SetPixel(x + 6, y, data & 0x40);
+ }
+ }
+ else
+ {
+ int color = ColorDLores[((x & 0x01) << 4) | (data & 0x0F)];
+ for (int i = 0; i < LoresHeight; i++, y++)
+ {
+ SetPixel(x + 0, y, color);
+ SetPixel(x + 1, y, color);
+ SetPixel(x + 2, y, color);
+ SetPixel(x + 3, y, color);
+ SetPixel(x + 4, y, color);
+ SetPixel(x + 5, y, color);
+ SetPixel(x + 6, y, color);
+ }
+ color = ColorDLores[((x & 0x01) << 4) | (data >> 4)];
+ for (int i = 0; i < LoresHeight; i++, y++)
+ {
+ SetPixel(x + 0, y, color);
+ SetPixel(x + 1, y, color);
+ SetPixel(x + 2, y, color);
+ SetPixel(x + 3, y, color);
+ SetPixel(x + 4, y, color);
+ SetPixel(x + 5, y, color);
+ SetPixel(x + 6, y, color);
+ }
+ }
+ }
+
+ private void DrawHires(int address, int x, int y)
+ {
+ if (IsMonochrome)
+ {
+ int data = _memory.ReadRamMainRegion02BF(address);
+ SetPixel(x + 0, y, data & 0x01);
+ SetPixel(x + 1, y, data & 0x01);
+ SetPixel(x + 2, y, data & 0x02);
+ SetPixel(x + 3, y, data & 0x02);
+ SetPixel(x + 4, y, data & 0x04);
+ SetPixel(x + 5, y, data & 0x04);
+ SetPixel(x + 6, y, data & 0x08);
+ SetPixel(x + 7, y, data & 0x08);
+ SetPixel(x + 8, y, data & 0x10);
+ SetPixel(x + 9, y, data & 0x10);
+ SetPixel(x + 10, y, data & 0x20);
+ SetPixel(x + 11, y, data & 0x20);
+ SetPixel(x + 12, y, data & 0x40);
+ SetPixel(x + 13, y, data & 0x40);
+ }
+ else
+ {
+ // 3 2 1 0
+ // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ //
+ // - - - - - - - - 0 0 0 0 0 0 0 0 + + + + + + + +
+ // H 1 0 H 6 5 4 3 2 1 0 H 1 0
+
+ int data = _memory.ReadRamMainRegion02BF(address) << 8;
+ if (x < Width - CellWidth)
+ {
+ data |= _memory.ReadRamMainRegion02BF(address + 1);
+ SetPixel(x + 14, y, ColorHires[((~x & 0x02) << 3) | ((data >> 4) & 0x08) | ((data << 1) & 0x06) | ((data >> 14) & 0x01)]);
+ SetPixel(x + 15, y, ColorHires[((~x & 0x02) << 3) | ((data >> 4) & 0x08) | ((data << 1) & 0x06) | ((data >> 14) & 0x01)]);
+ }
+ if (x > 0)
+ {
+ data |= _memory.ReadRamMainRegion02BF(address - 1) << 16;
+ SetPixel(x - 2, y, ColorHires[((~x & 0x02) << 3) | ((data >> 20) & 0x08) | ((data >> 6) & 0x04) | ((data >> 21) & 0x03)]);
+ SetPixel(x - 1, y, ColorHires[((~x & 0x02) << 3) | ((data >> 20) & 0x08) | ((data >> 6) & 0x04) | ((data >> 21) & 0x03)]);
+ }
+ SetPixel(x + 0, y, ColorHires[((x & 0x02) << 3) | ((data >> 12) & 0x08) | ((data >> 7) & 0x06) | ((data >> 22) & 0x01)]);
+ SetPixel(x + 1, y, ColorHires[((x & 0x02) << 3) | ((data >> 12) & 0x08) | ((data >> 7) & 0x06) | ((data >> 22) & 0x01)]);
+ SetPixel(x + 2, y, ColorHires[((~x & 0x02) << 3) | ((data >> 12) & 0x08) | ((data >> 8) & 0x07)]);
+ SetPixel(x + 3, y, ColorHires[((~x & 0x02) << 3) | ((data >> 12) & 0x08) | ((data >> 8) & 0x07)]);
+ SetPixel(x + 4, y, ColorHires[((x & 0x02) << 3) | ((data >> 12) & 0x08) | ((data >> 9) & 0x07)]);
+ SetPixel(x + 5, y, ColorHires[((x & 0x02) << 3) | ((data >> 12) & 0x08) | ((data >> 9) & 0x07)]);
+ SetPixel(x + 6, y, ColorHires[((~x & 0x02) << 3) | ((data >> 12) & 0x08) | ((data >> 10) & 0x07)]);
+ SetPixel(x + 7, y, ColorHires[((~x & 0x02) << 3) | ((data >> 12) & 0x08) | ((data >> 10) & 0x07)]);
+ SetPixel(x + 8, y, ColorHires[((x & 0x02) << 3) | ((data >> 12) & 0x08) | ((data >> 11) & 0x07)]);
+ SetPixel(x + 9, y, ColorHires[((x & 0x02) << 3) | ((data >> 12) & 0x08) | ((data >> 11) & 0x07)]);
+ SetPixel(x + 10, y, ColorHires[((~x & 0x02) << 3) | ((data >> 12) & 0x0F)]);
+ SetPixel(x + 11, y, ColorHires[((~x & 0x02) << 3) | ((data >> 12) & 0x0F)]);
+ SetPixel(x + 12, y, ColorHires[((x & 0x02) << 3) | ((data >> 12) & 0x08) | ((data << 2) & 0x04) | ((data >> 13) & 0x03)]);
+ SetPixel(x + 13, y, ColorHires[((x & 0x02) << 3) | ((data >> 12) & 0x08) | ((data << 2) & 0x04) | ((data >> 13) & 0x03)]);
+ }
+ }
+
+ private void DrawNDHires(int address, int x, int y)
+ {
+ if (IsMonochrome)
+ {
+ int data = _memory.ReadRamMainRegion02BF(address);
+ SetPixel(x + 0, y, data & 0x01);
+ SetPixel(x + 1, y, data & 0x01);
+ SetPixel(x + 2, y, data & 0x02);
+ SetPixel(x + 3, y, data & 0x02);
+ SetPixel(x + 4, y, data & 0x04);
+ SetPixel(x + 5, y, data & 0x04);
+ SetPixel(x + 6, y, data & 0x08);
+ SetPixel(x + 7, y, data & 0x08);
+ SetPixel(x + 8, y, data & 0x10);
+ SetPixel(x + 9, y, data & 0x10);
+ SetPixel(x + 10, y, data & 0x20);
+ SetPixel(x + 11, y, data & 0x20);
+ SetPixel(x + 12, y, data & 0x40);
+ SetPixel(x + 13, y, data & 0x40);
+ }
+ else
+ {
+ // 3 2 1 0
+ // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ //
+ // - - - - - - - - 0 0 0 0 0 0 0 0 + + + + + + + +
+ // X 1 0 X 6 5 4 3 2 1 0 X 1 0
+
+ int data = _memory.ReadRamMainRegion02BF(address) << 8;
+ if (x < Width - CellWidth)
+ {
+ data |= _memory.ReadRamMainRegion02BF(address + 1);
+ SetPixel(x + 14, y, ColorHires[((~x & 0x02) << 3) | ((data << 1) & 0x06) | ((data >> 14) & 0x01)]);
+ SetPixel(x + 15, y, ColorHires[((~x & 0x02) << 3) | ((data << 1) & 0x06) | ((data >> 14) & 0x01)]);
+ }
+ if (x > 0)
+ {
+ data |= _memory.ReadRamMainRegion02BF(address - 1) << 16;
+ SetPixel(x - 2, y, ColorHires[((~x & 0x02) << 3) | ((data >> 6) & 0x04) | ((data >> 21) & 0x03)]);
+ SetPixel(x - 1, y, ColorHires[((~x & 0x02) << 3) | ((data >> 6) & 0x04) | ((data >> 21) & 0x03)]);
+ }
+ SetPixel(x + 0, y, ColorHires[((x & 0x02) << 3) | ((data >> 7) & 0x06) | ((data >> 22) & 0x01)]);
+ SetPixel(x + 1, y, ColorHires[((x & 0x02) << 3) | ((data >> 7) & 0x06) | ((data >> 22) & 0x01)]);
+ SetPixel(x + 2, y, ColorHires[((~x & 0x02) << 3) | ((data >> 8) & 0x07)]);
+ SetPixel(x + 3, y, ColorHires[((~x & 0x02) << 3) | ((data >> 8) & 0x07)]);
+ SetPixel(x + 4, y, ColorHires[((x & 0x02) << 3) | ((data >> 9) & 0x07)]);
+ SetPixel(x + 5, y, ColorHires[((x & 0x02) << 3) | ((data >> 9) & 0x07)]);
+ SetPixel(x + 6, y, ColorHires[((~x & 0x02) << 3) | ((data >> 10) & 0x07)]);
+ SetPixel(x + 7, y, ColorHires[((~x & 0x02) << 3) | ((data >> 10) & 0x07)]);
+ SetPixel(x + 8, y, ColorHires[((x & 0x02) << 3) | ((data >> 11) & 0x07)]);
+ SetPixel(x + 9, y, ColorHires[((x & 0x02) << 3) | ((data >> 11) & 0x07)]);
+ SetPixel(x + 10, y, ColorHires[((~x & 0x02) << 3) | ((data >> 12) & 0x07)]);
+ SetPixel(x + 11, y, ColorHires[((~x & 0x02) << 3) | ((data >> 12) & 0x07)]);
+ SetPixel(x + 12, y, ColorHires[((x & 0x02) << 3) | ((data << 2) & 0x04) | ((data >> 13) & 0x03)]);
+ SetPixel(x + 13, y, ColorHires[((x & 0x02) << 3) | ((data << 2) & 0x04) | ((data >> 13) & 0x03)]);
+ }
+ }
+
+ private void DrawDHiresA(int address, int x, int y)
+ {
+ if (IsMonochrome)
+ {
+ if ((x & 0x2) == 0x00) // even cell
+ {
+ int data = ((_memory.ReadRamMainRegion02BF(address) << 7) & 0x80) | (_memory.ReadRamAuxRegion02BF(address) & 0x7F);
+ SetPixel(x + 0, y, data & 0x01);
+ SetPixel(x + 1, y, data & 0x02);
+ SetPixel(x + 2, y, data & 0x04);
+ SetPixel(x + 3, y, data & 0x08);
+ SetPixel(x + 4, y, data & 0x10);
+ SetPixel(x + 5, y, data & 0x20);
+ SetPixel(x + 6, y, data & 0x40);
+ SetPixel(x + 7, y, data & 0x80);
+ }
+ else
+ {
+ int data = ((_memory.ReadRamMainRegion02BF(address) << 9) & 0xE00) | ((_memory.ReadRamAuxRegion02BF(address) << 2) & 0x1FC) |
+ ((_memory.ReadRamMainRegion02BF(address - 1) >> 5) & 0x003);
+ SetPixel(x - 2, y, data & 0x01);
+ SetPixel(x - 1, y, data & 0x02);
+ SetPixel(x + 0, y, data & 0x04);
+ SetPixel(x + 1, y, data & 0x08);
+ SetPixel(x + 2, y, data & 0x10);
+ SetPixel(x + 3, y, data & 0x20);
+ SetPixel(x + 4, y, data & 0x40);
+ SetPixel(x + 5, y, data & 0x80);
+ SetPixel(x + 6, y, (data >> 8) & 0x01);
+ SetPixel(x + 7, y, (data >> 8) & 0x02);
+ SetPixel(x + 8, y, (data >> 8) & 0x04);
+ SetPixel(x + 9, y, (data >> 8) & 0x08);
+ }
+ }
+ else
+ {
+ if ((x & 0x2) == 0x00) // even cell
+ {
+ int data = ((_memory.ReadRamMainRegion02BF(address) << 7) & 0x80) | (_memory.ReadRamAuxRegion02BF(address) & 0x7F);
+ SetPixel(x + 0, y, ColorDHires0 | (data & 0x0F));
+ SetPixel(x + 1, y, ColorDHires0 | (data & 0x0F));
+ SetPixel(x + 2, y, ColorDHires0 | (data & 0x0F));
+ SetPixel(x + 3, y, ColorDHires0 | (data & 0x0F));
+ SetPixel(x + 4, y, ColorDHires0 | (data >> 4));
+ SetPixel(x + 5, y, ColorDHires0 | (data >> 4));
+ SetPixel(x + 6, y, ColorDHires0 | (data >> 4));
+ SetPixel(x + 7, y, ColorDHires0 | (data >> 4));
+ }
+ else
+ {
+ int data = ((_memory.ReadRamMainRegion02BF(address) << 9) & 0xE00) | ((_memory.ReadRamAuxRegion02BF(address) << 2) & 0x1FC) |
+ ((_memory.ReadRamMainRegion02BF(address - 1) >> 5) & 0x003);
+ SetPixel(x - 2, y, ColorDHires0 | (data & 0x0F));
+ SetPixel(x - 1, y, ColorDHires0 | (data & 0x0F));
+ SetPixel(x + 0, y, ColorDHires0 | (data & 0x0F));
+ SetPixel(x + 1, y, ColorDHires0 | (data & 0x0F));
+ SetPixel(x + 2, y, ColorDHires0 | ((data >> 4) & 0x0F));
+ SetPixel(x + 3, y, ColorDHires0 | ((data >> 4) & 0x0F));
+ SetPixel(x + 4, y, ColorDHires0 | ((data >> 4) & 0x0F));
+ SetPixel(x + 5, y, ColorDHires0 | ((data >> 4) & 0x0F));
+ SetPixel(x + 6, y, ColorDHires0 | (data >> 8));
+ SetPixel(x + 7, y, ColorDHires0 | (data >> 8));
+ SetPixel(x + 8, y, ColorDHires0 | (data >> 8));
+ SetPixel(x + 9, y, ColorDHires0 | (data >> 8));
+ }
+ }
+ }
+
+ private void DrawDHiresM(int address, int x, int y)
+ {
+ if (IsMonochrome)
+ {
+ if ((x & 0x2) == 0x02) // odd cell
+ {
+ int data = ((_memory.ReadRamMainRegion02BF(address) << 1) & 0xFE) | ((_memory.ReadRamAuxRegion02BF(address) >> 6) & 0x01);
+ SetPixel(x + 6, y, data & 0x01);
+ SetPixel(x + 7, y, data & 0x02);
+ SetPixel(x + 8, y, data & 0x04);
+ SetPixel(x + 9, y, data & 0x08);
+ SetPixel(x + 10, y, data & 0x10);
+ SetPixel(x + 11, y, data & 0x20);
+ SetPixel(x + 12, y, data & 0x40);
+ SetPixel(x + 13, y, data & 0x80);
+ }
+ else
+ {
+ int data = ((_memory.ReadRamAuxRegion02BF(address + 1) << 10) & 0xC00) | ((_memory.ReadRamMainRegion02BF(address) << 3) & 0x3F8) |
+ ((_memory.ReadRamAuxRegion02BF(address) >> 4) & 0x007);
+ SetPixel(x + 4, y, data & 0x01);
+ SetPixel(x + 5, y, data & 0x02);
+ SetPixel(x + 6, y, data & 0x04);
+ SetPixel(x + 7, y, data & 0x08);
+ SetPixel(x + 8, y, data & 0x10);
+ SetPixel(x + 9, y, data & 0x20);
+ SetPixel(x + 10, y, data & 0x40);
+ SetPixel(x + 11, y, data & 0x80);
+ SetPixel(x + 12, y, (data >> 8) & 0x01);
+ SetPixel(x + 13, y, (data >> 8) & 0x02);
+ SetPixel(x + 14, y, (data >> 8) & 0x04);
+ SetPixel(x + 15, y, (data >> 8) & 0x08);
+ }
+ }
+ else
+ {
+ if ((x & 0x2) == 0x02) // odd cell
+ {
+ int data = ((_memory.ReadRamMainRegion02BF(address) << 1) & 0xFE) | ((_memory.ReadRamAuxRegion02BF(address) >> 6) & 0x01);
+ SetPixel(x + 6, y, ColorDHires0 | (data & 0x0F));
+ SetPixel(x + 7, y, ColorDHires0 | (data & 0x0F));
+ SetPixel(x + 8, y, ColorDHires0 | (data & 0x0F));
+ SetPixel(x + 9, y, ColorDHires0 | (data & 0x0F));
+ SetPixel(x + 10, y, ColorDHires0 | (data >> 4));
+ SetPixel(x + 11, y, ColorDHires0 | (data >> 4));
+ SetPixel(x + 12, y, ColorDHires0 | (data >> 4));
+ SetPixel(x + 13, y, ColorDHires0 | (data >> 4));
+ }
+ else
+ {
+ int data = ((_memory.ReadRamAuxRegion02BF(address + 1) << 10) & 0xC00) | ((_memory.ReadRamMainRegion02BF(address) << 3) & 0x3F8) |
+ ((_memory.ReadRamAuxRegion02BF(address) >> 4) & 0x007);
+ SetPixel(x + 4, y, ColorDHires0 | (data & 0x0F));
+ SetPixel(x + 5, y, ColorDHires0 | (data & 0x0F));
+ SetPixel(x + 6, y, ColorDHires0 | (data & 0x0F));
+ SetPixel(x + 7, y, ColorDHires0 | (data & 0x0F));
+ SetPixel(x + 8, y, ColorDHires0 | ((data >> 4) & 0x0F));
+ SetPixel(x + 9, y, ColorDHires0 | ((data >> 4) & 0x0F));
+ SetPixel(x + 10, y, ColorDHires0 | ((data >> 4) & 0x0F));
+ SetPixel(x + 11, y, ColorDHires0 | ((data >> 4) & 0x0F));
+ SetPixel(x + 12, y, ColorDHires0 | (data >> 8));
+ SetPixel(x + 13, y, ColorDHires0 | (data >> 8));
+ SetPixel(x + 14, y, ColorDHires0 | (data >> 8));
+ SetPixel(x + 15, y, ColorDHires0 | (data >> 8));
+ }
+ }
+ }
+ #endregion
+
+ #region Flush Methods
+ private void FlushRowMode0(int y)
+ {
+ int address = (_memory.IsVideoPage2 ? 0x0800 : 0x0400) + AddressOffset[y];
+ for (int x = 0; x < CellColumns; x++)
+ {
+ if (_isCellDirty[CellColumns * y + x])
+ {
+ _isCellDirty[CellColumns * y + x] = false;
+ DrawLores(_memory.ReadRamMainRegion02BF(address + x), CellWidth * x, y); // lores
+ }
+ }
+ }
+
+ private void FlushRowMode1(int y)
+ {
+ int address = (_memory.IsVideoPage2 ? 0x0800 : 0x0400) + AddressOffset[y];
+ for (int x = 0; x < CellColumns; x++)
+ {
+ if (_isCellDirty[CellColumns * y + x])
+ {
+ _isCellDirty[CellColumns * y + x] = false;
+ DrawText40(_memory.ReadRamMainRegion02BF(address + x), CellWidth * x, y); // text40
+ }
+ }
+ }
+
+ private void FlushRowMode2(int y)
+ {
+ int address = (_memory.IsVideoPage2 ? 0x0800 : 0x0400) + AddressOffset[y];
+ for (int x = 0; x < 2 * CellColumns; x += 2)
+ {
+ if (_isCellDirty[CellColumns * y + x / 2])
+ {
+ _isCellDirty[CellColumns * y + x / 2] = false;
+ DrawText80(_memory.ReadRamAuxRegion02BF(address + x / 2), CellWidth / 2 * (x + 0), y); // text80
+ DrawText80(_memory.ReadRamMainRegion02BF(address + x / 2), CellWidth / 2 * (x + 1), y);
+ }
+ }
+ }
+
+ private void FlushRowMode3(int y)
+ {
+ if (y < MixedHeight)
+ {
+ FlushRowMode0(y); // lores
+ }
+ else
+ {
+ FlushRowMode1(y); // text40
+ }
+ }
+
+ private void FlushRowMode4(int y)
+ {
+ if (y < MixedHeight)
+ {
+ FlushRowMode0(y); // lores
+ }
+ else
+ {
+ FlushRowMode2(y); // text80
+ }
+ }
+
+ private void FlushRowMode5(int y)
+ {
+ int address = _memory.IsVideoPage2 ? 0x4000 : 0x2000;
+ for (int i = 0; i < CellHeight; i++, y++)
+ {
+ for (int x = 0; x < CellColumns; x++)
+ {
+ if (_isCellDirty[CellColumns * y + x])
+ {
+ _isCellDirty[CellColumns * y + x] = false;
+ DrawHires(address + AddressOffset[y] + x, CellWidth * x, y); // hires
+ }
+ }
+ }
+ }
+
+ private void FlushRowMode6(int y)
+ {
+ if (y < MixedHeight)
+ {
+ FlushRowMode5(y); // hires
+ }
+ else
+ {
+ FlushRowMode1(y); // text40
+ }
+ }
+
+ private void FlushRowMode7(int y)
+ {
+ if (y < MixedHeight)
+ {
+ FlushRowMode5(y); // hires
+ }
+ else
+ {
+ FlushRowMode2(y); // text80
+ }
+ }
+
+ private void FlushRowMode8(int y)
+ {
+ int address = (_memory.IsVideoPage2 ? 0x0800 : 0x0400) + AddressOffset[y];
+ for (int x = 0; x < CellColumns; x++)
+ {
+ if (_isCellDirty[CellColumns * y + x])
+ {
+ _isCellDirty[CellColumns * y + x] = false;
+ Draw7MLores(_memory.ReadRamMainRegion02BF(address + x), CellWidth * x, y); // 7mlores
+ }
+ }
+ }
+
+ private void FlushRowMode9(int y)
+ {
+ int address = (_memory.IsVideoPage2 ? 0x0800 : 0x0400) + AddressOffset[y];
+ for (int x = 0; x < 2 * CellColumns; x += 2)
+ {
+ if (_isCellDirty[CellColumns * y + x / 2])
+ {
+ _isCellDirty[CellColumns * y + x / 2] = false;
+ DrawDLores(_memory.ReadRamAuxRegion02BF(address + x / 2), CellWidth / 2 * (x + 0), y); // dlores
+ DrawDLores(_memory.ReadRamMainRegion02BF(address + x / 2), CellWidth / 2 * (x + 1), y);
+ }
+ }
+ }
+
+ private void FlushRowModeA(int y)
+ {
+ if (y < MixedHeight)
+ {
+ FlushRowMode8(y); // 7mlores
+ }
+ else
+ {
+ FlushRowMode1(y); // text40
+ }
+ }
+
+ private void FlushRowModeB(int y)
+ {
+ if (y < MixedHeight)
+ {
+ FlushRowMode9(y); // dlores
+ }
+ else
+ {
+ FlushRowMode2(y); // text80
+ }
+ }
+
+ private void FlushRowModeC(int y)
+ {
+ int address = _memory.IsVideoPage2 ? 0x4000 : 0x2000;
+ for (int i = 0; i < CellHeight; i++, y++)
+ {
+ for (int x = 0; x < CellColumns; x++)
+ {
+ if (_isCellDirty[CellColumns * y + x])
+ {
+ _isCellDirty[CellColumns * y + x] = false;
+ DrawNDHires(address + AddressOffset[y] + x, CellWidth * x, y); // ndhires
+ }
+ }
+ }
+ }
+
+ private void FlushRowModeD(int y)
+ {
+ int address = _memory.IsVideoPage2 ? 0x4000 : 0x2000;
+ for (int i = 0; i < CellHeight; i++, y++)
+ {
+ for (int x = 0; x < CellColumns; x++)
+ {
+ if (_isCellDirty[CellColumns * y + x])
+ {
+ _isCellDirty[CellColumns * y + x] = false;
+ DrawDHiresA(address + AddressOffset[y] + x, CellWidth * x, y); // dhires
+ DrawDHiresM(address + AddressOffset[y] + x, CellWidth * x, y);
+ }
+ }
+ }
+ }
+
+ private void FlushRowModeE(int y)
+ {
+ if (y < MixedHeight)
+ {
+ FlushRowModeC(y); // ndhires
+ }
+ else
+ {
+ FlushRowMode1(y); // text40
+ }
+ }
+
+ private void FlushRowModeF(int y)
+ {
+ if (y < MixedHeight)
+ {
+ FlushRowModeD(y); // dhires
+ }
+ else
+ {
+ FlushRowMode2(y); // text80
+ }
+ }
+ #endregion
+
+ private void FlushRowEvent()
+ {
+ int y = (_cyclesPerVSync - _cyclesPerVBlankPreset - Machine.Events.FindEvent(_resetVSyncEvent)) / CyclesPerHSync;
+
+ FlushRowMode[_memory.VideoMode](y - CellHeight); // in arrears
+
+ if (y < Height)
+ {
+ Machine.Events.AddEvent(CyclesPerFlush, _flushRowEvent);
+ }
+ else
+ {
+ IsVBlank = true;
+
+ Machine.Events.AddEvent(_cyclesPerVBlank, _leaveVBlankEvent);
+ }
+ }
+
+ private void FlushScreen()
+ {
+ var flushRowMode = FlushRowMode[_memory.VideoMode];
+
+ for (int y = 0; y < Height; y += CellHeight)
+ {
+ flushRowMode(y);
+ }
+ }
+
+ private void InverseTextEvent()
+ {
+ _isTextInversed = !_isTextInversed;
+
+ DirtyScreenText();
+
+ Machine.Events.AddEvent(_cyclesPerFlash, _inverseTextEvent);
+ }
+
+ private void LeaveVBlankEvent()
+ {
+ IsVBlank = false;
+
+ Machine.Events.AddEvent(CyclesPerFlush, _flushRowEvent);
+ }
+
+ private void ResetVSyncEvent()
+ {
+ Machine.Events.AddEvent(_cyclesPerVSync, _resetVSyncEvent);
+ }
+
+ private void SetPalette()
+ {
+ _colorPalette[ColorMono00] = _colorBlack;
+ _colorPalette[ColorMono01] = _colorMonochrome;
+ _colorPalette[ColorMono02] = _colorMonochrome;
+ _colorPalette[ColorMono04] = _colorMonochrome;
+ _colorPalette[ColorMono08] = _colorMonochrome;
+ _colorPalette[ColorMono10] = _colorMonochrome;
+ _colorPalette[ColorMono20] = _colorMonochrome;
+ _colorPalette[ColorMono40] = _colorMonochrome;
+ _colorPalette[ColorMono80] = _colorMonochrome;
+
+ _colorPalette[ColorWhite00] = _colorBlack;
+ _colorPalette[ColorWhite01] = _colorWhite;
+ _colorPalette[ColorWhite02] = _colorWhite;
+ _colorPalette[ColorWhite04] = _colorWhite;
+ _colorPalette[ColorWhite08] = _colorWhite;
+ _colorPalette[ColorWhite10] = _colorWhite;
+ _colorPalette[ColorWhite20] = _colorWhite;
+ _colorPalette[ColorWhite40] = _colorWhite;
+ _colorPalette[ColorWhite80] = _colorWhite;
+
+ _colorPalette[ColorDHires0] = _colorBlack;
+ _colorPalette[ColorDHires1] = _colorDarkBlue;
+ _colorPalette[ColorDHires2] = _colorDarkGreen;
+ _colorPalette[ColorDHires3] = _colorMediumBlue;
+ _colorPalette[ColorDHires4] = _colorBrown;
+ _colorPalette[ColorDHires5] = _colorLightGrey;
+ _colorPalette[ColorDHires6] = _colorGreen;
+ _colorPalette[ColorDHires7] = _colorAquamarine;
+ _colorPalette[ColorDHires8] = _colorDeepRed;
+ _colorPalette[ColorDHires9] = _colorPurple;
+ _colorPalette[ColorDHiresA] = _colorDarkGrey;
+ _colorPalette[ColorDHiresB] = _colorLightBlue;
+ _colorPalette[ColorDHiresC] = _colorOrange;
+ _colorPalette[ColorDHiresD] = _colorPink;
+ _colorPalette[ColorDHiresE] = _colorYellow;
+ _colorPalette[ColorDHiresF] = _colorWhite;
+
+ DirtyScreen();
+ }
+
+ private void SetPixel(int x, int y, int color)
+ {
+ _videoService.SetPixel(x, 2 * y, _colorPalette[color]);
+ }
+
+ private void SetScanner()
+ {
+ if ((_scannerOptions & ScannerOptions.Pal) != 0)
+ {
+ _vCountPreset = VCountPresetPal;
+ _vLineLeaveVBlank = VLineLeaveVBlankPal;
+ }
+ else
+ {
+ _vCountPreset = VCountPresetNtsc;
+ _vLineLeaveVBlank = VLineLeaveVBlankNtsc;
+ }
+
+ _cyclesPerVBlank = (_vLineLeaveVBlank - VLineEnterVBlank) * CyclesPerHSync;
+ _cyclesPerVBlankPreset = (_vLineLeaveVBlank - VLineTriggerPreset) * CyclesPerHSync; // cycles during vblank after vcount preset [3-15, 3-16]
+ _cyclesPerVSync = _vLineLeaveVBlank * CyclesPerHSync;
+ _cyclesPerFlash = VSyncsPerFlash * _cyclesPerVSync;
+ }
+
+ public uint ColorBlack { get { return _colorBlack; } set { _colorBlack = value; SetPalette(); } }
+ public uint ColorDarkBlue { get { return _colorDarkBlue; } set { _colorDarkBlue = value; SetPalette(); } }
+ public uint ColorDarkGreen { get { return _colorDarkGreen; } set { _colorDarkGreen = value; SetPalette(); } }
+ public uint ColorMediumBlue { get { return _colorMediumBlue; } set { _colorMediumBlue = value; SetPalette(); } }
+ public uint ColorBrown { get { return _colorBrown; } set { _colorBrown = value; SetPalette(); } }
+ public uint ColorLightGrey { get { return _colorLightGrey; } set { _colorLightGrey = value; SetPalette(); } }
+ public uint ColorGreen { get { return _colorGreen; } set { _colorGreen = value; SetPalette(); } }
+ public uint ColorAquamarine { get { return _colorAquamarine; } set { _colorAquamarine = value; SetPalette(); } }
+ public uint ColorDeepRed { get { return _colorDeepRed; } set { _colorDeepRed = value; SetPalette(); } }
+ public uint ColorPurple { get { return _colorPurple; } set { _colorPurple = value; SetPalette(); } }
+ public uint ColorDarkGrey { get { return _colorDarkGrey; } set { _colorDarkGrey = value; SetPalette(); } }
+ public uint ColorLightBlue { get { return _colorLightBlue; } set { _colorLightBlue = value; SetPalette(); } }
+ public uint ColorOrange { get { return _colorOrange; } set { _colorOrange = value; SetPalette(); } }
+ public uint ColorPink { get { return _colorPink; } set { _colorPink = value; SetPalette(); } }
+ public uint ColorYellow { get { return _colorYellow; } set { _colorYellow = value; SetPalette(); } }
+ public uint ColorWhite { get { return _colorWhite; } set { _colorWhite = value; SetPalette(); } }
+ public uint ColorMonochrome { get { return _colorMonochrome; } set { _colorMonochrome = value; SetPalette(); } }
+
+ public bool IsFullScreen { get { return _isFullScreen; } set { _isFullScreen = value; _videoService.SetFullScreen(_isFullScreen); } }
+ public bool IsMonochrome { get { return _isMonochrome; } set { _isMonochrome = value; DirtyScreen(); } }
+ public ScannerOptions ScannerOptions { get { return _scannerOptions; } set { _scannerOptions = value; SetScanner(); } }
+
+ public bool IsVBlank { get; private set; }
+
+ private Action _flushRowEvent;
+ private Action _inverseTextEvent;
+ private Action _leaveVBlankEvent;
+ private Action _resetVSyncEvent;
+
+ private Memory _memory;
+ private VideoService _videoService;
+
+ private uint _colorBlack;
+ private uint _colorDarkBlue;
+ private uint _colorDarkGreen;
+ private uint _colorMediumBlue;
+ private uint _colorBrown;
+ private uint _colorLightGrey;
+ private uint _colorGreen;
+ private uint _colorAquamarine;
+ private uint _colorDeepRed;
+ private uint _colorPurple;
+ private uint _colorDarkGrey;
+ private uint _colorLightBlue;
+ private uint _colorOrange;
+ private uint _colorPink;
+ private uint _colorYellow;
+ private uint _colorWhite;
+ private uint _colorMonochrome;
+ private bool _isFullScreen;
+ private bool _isMonochrome;
+ private bool _isTextInversed;
+ private ScannerOptions _scannerOptions;
+ private int _cyclesPerVBlank;
+ private int _cyclesPerVBlankPreset;
+ private int _cyclesPerVSync;
+ private int _cyclesPerFlash;
+ private int _vCountPreset;
+ private int _vLineLeaveVBlank;
+
+ private ushort[] _charSet;
+ private uint[] _colorPalette = new uint[ColorPaletteCount];
+ private bool[] _isCellDirty = new bool[Height * CellColumns + 1]; // includes sentinel
+ }
+}
diff --git a/Virtu/VideoData.cs b/Virtu/VideoData.cs
index b6085fc..1bf1857 100644
--- a/Virtu/VideoData.cs
+++ b/Virtu/VideoData.cs
@@ -1,1644 +1,1644 @@
-using System;
-
-namespace Jellyfish.Virtu
-{
- public partial class Video
- {
- private static readonly int[] AddressOffset = new int[Height]
- {
- 0x0000, 0x0400, 0x0800, 0x0C00, 0x1000, 0x1400, 0x1800, 0x1C00,
- 0x0080, 0x0480, 0x0880, 0x0C80, 0x1080, 0x1480, 0x1880, 0x1C80,
- 0x0100, 0x0500, 0x0900, 0x0D00, 0x1100, 0x1500, 0x1900, 0x1D00,
- 0x0180, 0x0580, 0x0980, 0x0D80, 0x1180, 0x1580, 0x1980, 0x1D80,
- 0x0200, 0x0600, 0x0A00, 0x0E00, 0x1200, 0x1600, 0x1A00, 0x1E00,
- 0x0280, 0x0680, 0x0A80, 0x0E80, 0x1280, 0x1680, 0x1A80, 0x1E80,
- 0x0300, 0x0700, 0x0B00, 0x0F00, 0x1300, 0x1700, 0x1B00, 0x1F00,
- 0x0380, 0x0780, 0x0B80, 0x0F80, 0x1380, 0x1780, 0x1B80, 0x1F80,
- 0x0028, 0x0428, 0x0828, 0x0C28, 0x1028, 0x1428, 0x1828, 0x1C28,
- 0x00A8, 0x04A8, 0x08A8, 0x0CA8, 0x10A8, 0x14A8, 0x18A8, 0x1CA8,
- 0x0128, 0x0528, 0x0928, 0x0D28, 0x1128, 0x1528, 0x1928, 0x1D28,
- 0x01A8, 0x05A8, 0x09A8, 0x0DA8, 0x11A8, 0x15A8, 0x19A8, 0x1DA8,
- 0x0228, 0x0628, 0x0A28, 0x0E28, 0x1228, 0x1628, 0x1A28, 0x1E28,
- 0x02A8, 0x06A8, 0x0AA8, 0x0EA8, 0x12A8, 0x16A8, 0x1AA8, 0x1EA8,
- 0x0328, 0x0728, 0x0B28, 0x0F28, 0x1328, 0x1728, 0x1B28, 0x1F28,
- 0x03A8, 0x07A8, 0x0BA8, 0x0FA8, 0x13A8, 0x17A8, 0x1BA8, 0x1FA8,
- 0x0050, 0x0450, 0x0850, 0x0C50, 0x1050, 0x1450, 0x1850, 0x1C50,
- 0x00D0, 0x04D0, 0x08D0, 0x0CD0, 0x10D0, 0x14D0, 0x18D0, 0x1CD0,
- 0x0150, 0x0550, 0x0950, 0x0D50, 0x1150, 0x1550, 0x1950, 0x1D50,
- 0x01D0, 0x05D0, 0x09D0, 0x0DD0, 0x11D0, 0x15D0, 0x19D0, 0x1DD0,
- 0x0250, 0x0650, 0x0A50, 0x0E50, 0x1250, 0x1650, 0x1A50, 0x1E50,
- 0x02D0, 0x06D0, 0x0AD0, 0x0ED0, 0x12D0, 0x16D0, 0x1AD0, 0x1ED0,
- 0x0350, 0x0750, 0x0B50, 0x0F50, 0x1350, 0x1750, 0x1B50, 0x1F50,
- 0x03D0, 0x07D0, 0x0BD0, 0x0FD0, 0x13D0, 0x17D0, 0x1BD0, 0x1FD0
- };
-
- private const int CellWidth = 14;
- private const int CellHeight = 8;
- private const int CellRows = Height / CellHeight;
- private const int CellColumns = Width / CellWidth;
-
- private const int CellIndexCount = 0x2000;
-
- private static readonly ushort[] CellIndex = new ushort[CellIndexCount]
- {
- 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
- 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
- 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
- 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
- 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
- 0x0A00, 0x0A01, 0x0A02, 0x0A03, 0x0A04, 0x0A05, 0x0A06, 0x0A07,
- 0x0A08, 0x0A09, 0x0A0A, 0x0A0B, 0x0A0C, 0x0A0D, 0x0A0E, 0x0A0F,
- 0x0A10, 0x0A11, 0x0A12, 0x0A13, 0x0A14, 0x0A15, 0x0A16, 0x0A17,
- 0x0A18, 0x0A19, 0x0A1A, 0x0A1B, 0x0A1C, 0x0A1D, 0x0A1E, 0x0A1F,
- 0x0A20, 0x0A21, 0x0A22, 0x0A23, 0x0A24, 0x0A25, 0x0A26, 0x0A27,
- 0x1400, 0x1401, 0x1402, 0x1403, 0x1404, 0x1405, 0x1406, 0x1407,
- 0x1408, 0x1409, 0x140A, 0x140B, 0x140C, 0x140D, 0x140E, 0x140F,
- 0x1410, 0x1411, 0x1412, 0x1413, 0x1414, 0x1415, 0x1416, 0x1417,
- 0x1418, 0x1419, 0x141A, 0x141B, 0x141C, 0x141D, 0x141E, 0x141F,
- 0x1420, 0x1421, 0x1422, 0x1423, 0x1424, 0x1425, 0x1426, 0x1427,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0146, 0x0147,
- 0x0148, 0x0149, 0x014A, 0x014B, 0x014C, 0x014D, 0x014E, 0x014F,
- 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155, 0x0156, 0x0157,
- 0x0158, 0x0159, 0x015A, 0x015B, 0x015C, 0x015D, 0x015E, 0x015F,
- 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165, 0x0166, 0x0167,
- 0x0B40, 0x0B41, 0x0B42, 0x0B43, 0x0B44, 0x0B45, 0x0B46, 0x0B47,
- 0x0B48, 0x0B49, 0x0B4A, 0x0B4B, 0x0B4C, 0x0B4D, 0x0B4E, 0x0B4F,
- 0x0B50, 0x0B51, 0x0B52, 0x0B53, 0x0B54, 0x0B55, 0x0B56, 0x0B57,
- 0x0B58, 0x0B59, 0x0B5A, 0x0B5B, 0x0B5C, 0x0B5D, 0x0B5E, 0x0B5F,
- 0x0B60, 0x0B61, 0x0B62, 0x0B63, 0x0B64, 0x0B65, 0x0B66, 0x0B67,
- 0x1540, 0x1541, 0x1542, 0x1543, 0x1544, 0x1545, 0x1546, 0x1547,
- 0x1548, 0x1549, 0x154A, 0x154B, 0x154C, 0x154D, 0x154E, 0x154F,
- 0x1550, 0x1551, 0x1552, 0x1553, 0x1554, 0x1555, 0x1556, 0x1557,
- 0x1558, 0x1559, 0x155A, 0x155B, 0x155C, 0x155D, 0x155E, 0x155F,
- 0x1560, 0x1561, 0x1562, 0x1563, 0x1564, 0x1565, 0x1566, 0x1567,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0280, 0x0281, 0x0282, 0x0283, 0x0284, 0x0285, 0x0286, 0x0287,
- 0x0288, 0x0289, 0x028A, 0x028B, 0x028C, 0x028D, 0x028E, 0x028F,
- 0x0290, 0x0291, 0x0292, 0x0293, 0x0294, 0x0295, 0x0296, 0x0297,
- 0x0298, 0x0299, 0x029A, 0x029B, 0x029C, 0x029D, 0x029E, 0x029F,
- 0x02A0, 0x02A1, 0x02A2, 0x02A3, 0x02A4, 0x02A5, 0x02A6, 0x02A7,
- 0x0C80, 0x0C81, 0x0C82, 0x0C83, 0x0C84, 0x0C85, 0x0C86, 0x0C87,
- 0x0C88, 0x0C89, 0x0C8A, 0x0C8B, 0x0C8C, 0x0C8D, 0x0C8E, 0x0C8F,
- 0x0C90, 0x0C91, 0x0C92, 0x0C93, 0x0C94, 0x0C95, 0x0C96, 0x0C97,
- 0x0C98, 0x0C99, 0x0C9A, 0x0C9B, 0x0C9C, 0x0C9D, 0x0C9E, 0x0C9F,
- 0x0CA0, 0x0CA1, 0x0CA2, 0x0CA3, 0x0CA4, 0x0CA5, 0x0CA6, 0x0CA7,
- 0x1680, 0x1681, 0x1682, 0x1683, 0x1684, 0x1685, 0x1686, 0x1687,
- 0x1688, 0x1689, 0x168A, 0x168B, 0x168C, 0x168D, 0x168E, 0x168F,
- 0x1690, 0x1691, 0x1692, 0x1693, 0x1694, 0x1695, 0x1696, 0x1697,
- 0x1698, 0x1699, 0x169A, 0x169B, 0x169C, 0x169D, 0x169E, 0x169F,
- 0x16A0, 0x16A1, 0x16A2, 0x16A3, 0x16A4, 0x16A5, 0x16A6, 0x16A7,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
- 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x03CF,
- 0x03D0, 0x03D1, 0x03D2, 0x03D3, 0x03D4, 0x03D5, 0x03D6, 0x03D7,
- 0x03D8, 0x03D9, 0x03DA, 0x03DB, 0x03DC, 0x03DD, 0x03DE, 0x03DF,
- 0x03E0, 0x03E1, 0x03E2, 0x03E3, 0x03E4, 0x03E5, 0x03E6, 0x03E7,
- 0x0DC0, 0x0DC1, 0x0DC2, 0x0DC3, 0x0DC4, 0x0DC5, 0x0DC6, 0x0DC7,
- 0x0DC8, 0x0DC9, 0x0DCA, 0x0DCB, 0x0DCC, 0x0DCD, 0x0DCE, 0x0DCF,
- 0x0DD0, 0x0DD1, 0x0DD2, 0x0DD3, 0x0DD4, 0x0DD5, 0x0DD6, 0x0DD7,
- 0x0DD8, 0x0DD9, 0x0DDA, 0x0DDB, 0x0DDC, 0x0DDD, 0x0DDE, 0x0DDF,
- 0x0DE0, 0x0DE1, 0x0DE2, 0x0DE3, 0x0DE4, 0x0DE5, 0x0DE6, 0x0DE7,
- 0x17C0, 0x17C1, 0x17C2, 0x17C3, 0x17C4, 0x17C5, 0x17C6, 0x17C7,
- 0x17C8, 0x17C9, 0x17CA, 0x17CB, 0x17CC, 0x17CD, 0x17CE, 0x17CF,
- 0x17D0, 0x17D1, 0x17D2, 0x17D3, 0x17D4, 0x17D5, 0x17D6, 0x17D7,
- 0x17D8, 0x17D9, 0x17DA, 0x17DB, 0x17DC, 0x17DD, 0x17DE, 0x17DF,
- 0x17E0, 0x17E1, 0x17E2, 0x17E3, 0x17E4, 0x17E5, 0x17E6, 0x17E7,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0500, 0x0501, 0x0502, 0x0503, 0x0504, 0x0505, 0x0506, 0x0507,
- 0x0508, 0x0509, 0x050A, 0x050B, 0x050C, 0x050D, 0x050E, 0x050F,
- 0x0510, 0x0511, 0x0512, 0x0513, 0x0514, 0x0515, 0x0516, 0x0517,
- 0x0518, 0x0519, 0x051A, 0x051B, 0x051C, 0x051D, 0x051E, 0x051F,
- 0x0520, 0x0521, 0x0522, 0x0523, 0x0524, 0x0525, 0x0526, 0x0527,
- 0x0F00, 0x0F01, 0x0F02, 0x0F03, 0x0F04, 0x0F05, 0x0F06, 0x0F07,
- 0x0F08, 0x0F09, 0x0F0A, 0x0F0B, 0x0F0C, 0x0F0D, 0x0F0E, 0x0F0F,
- 0x0F10, 0x0F11, 0x0F12, 0x0F13, 0x0F14, 0x0F15, 0x0F16, 0x0F17,
- 0x0F18, 0x0F19, 0x0F1A, 0x0F1B, 0x0F1C, 0x0F1D, 0x0F1E, 0x0F1F,
- 0x0F20, 0x0F21, 0x0F22, 0x0F23, 0x0F24, 0x0F25, 0x0F26, 0x0F27,
- 0x1900, 0x1901, 0x1902, 0x1903, 0x1904, 0x1905, 0x1906, 0x1907,
- 0x1908, 0x1909, 0x190A, 0x190B, 0x190C, 0x190D, 0x190E, 0x190F,
- 0x1910, 0x1911, 0x1912, 0x1913, 0x1914, 0x1915, 0x1916, 0x1917,
- 0x1918, 0x1919, 0x191A, 0x191B, 0x191C, 0x191D, 0x191E, 0x191F,
- 0x1920, 0x1921, 0x1922, 0x1923, 0x1924, 0x1925, 0x1926, 0x1927,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647,
- 0x0648, 0x0649, 0x064A, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F,
- 0x0650, 0x0651, 0x0652, 0x0653, 0x0654, 0x0655, 0x0656, 0x0657,
- 0x0658, 0x0659, 0x065A, 0x065B, 0x065C, 0x065D, 0x065E, 0x065F,
- 0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667,
- 0x1040, 0x1041, 0x1042, 0x1043, 0x1044, 0x1045, 0x1046, 0x1047,
- 0x1048, 0x1049, 0x104A, 0x104B, 0x104C, 0x104D, 0x104E, 0x104F,
- 0x1050, 0x1051, 0x1052, 0x1053, 0x1054, 0x1055, 0x1056, 0x1057,
- 0x1058, 0x1059, 0x105A, 0x105B, 0x105C, 0x105D, 0x105E, 0x105F,
- 0x1060, 0x1061, 0x1062, 0x1063, 0x1064, 0x1065, 0x1066, 0x1067,
- 0x1A40, 0x1A41, 0x1A42, 0x1A43, 0x1A44, 0x1A45, 0x1A46, 0x1A47,
- 0x1A48, 0x1A49, 0x1A4A, 0x1A4B, 0x1A4C, 0x1A4D, 0x1A4E, 0x1A4F,
- 0x1A50, 0x1A51, 0x1A52, 0x1A53, 0x1A54, 0x1A55, 0x1A56, 0x1A57,
- 0x1A58, 0x1A59, 0x1A5A, 0x1A5B, 0x1A5C, 0x1A5D, 0x1A5E, 0x1A5F,
- 0x1A60, 0x1A61, 0x1A62, 0x1A63, 0x1A64, 0x1A65, 0x1A66, 0x1A67,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0786, 0x0787,
- 0x0788, 0x0789, 0x078A, 0x078B, 0x078C, 0x078D, 0x078E, 0x078F,
- 0x0790, 0x0791, 0x0792, 0x0793, 0x0794, 0x0795, 0x0796, 0x0797,
- 0x0798, 0x0799, 0x079A, 0x079B, 0x079C, 0x079D, 0x079E, 0x079F,
- 0x07A0, 0x07A1, 0x07A2, 0x07A3, 0x07A4, 0x07A5, 0x07A6, 0x07A7,
- 0x1180, 0x1181, 0x1182, 0x1183, 0x1184, 0x1185, 0x1186, 0x1187,
- 0x1188, 0x1189, 0x118A, 0x118B, 0x118C, 0x118D, 0x118E, 0x118F,
- 0x1190, 0x1191, 0x1192, 0x1193, 0x1194, 0x1195, 0x1196, 0x1197,
- 0x1198, 0x1199, 0x119A, 0x119B, 0x119C, 0x119D, 0x119E, 0x119F,
- 0x11A0, 0x11A1, 0x11A2, 0x11A3, 0x11A4, 0x11A5, 0x11A6, 0x11A7,
- 0x1B80, 0x1B81, 0x1B82, 0x1B83, 0x1B84, 0x1B85, 0x1B86, 0x1B87,
- 0x1B88, 0x1B89, 0x1B8A, 0x1B8B, 0x1B8C, 0x1B8D, 0x1B8E, 0x1B8F,
- 0x1B90, 0x1B91, 0x1B92, 0x1B93, 0x1B94, 0x1B95, 0x1B96, 0x1B97,
- 0x1B98, 0x1B99, 0x1B9A, 0x1B9B, 0x1B9C, 0x1B9D, 0x1B9E, 0x1B9F,
- 0x1BA0, 0x1BA1, 0x1BA2, 0x1BA3, 0x1BA4, 0x1BA5, 0x1BA6, 0x1BA7,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x08C0, 0x08C1, 0x08C2, 0x08C3, 0x08C4, 0x08C5, 0x08C6, 0x08C7,
- 0x08C8, 0x08C9, 0x08CA, 0x08CB, 0x08CC, 0x08CD, 0x08CE, 0x08CF,
- 0x08D0, 0x08D1, 0x08D2, 0x08D3, 0x08D4, 0x08D5, 0x08D6, 0x08D7,
- 0x08D8, 0x08D9, 0x08DA, 0x08DB, 0x08DC, 0x08DD, 0x08DE, 0x08DF,
- 0x08E0, 0x08E1, 0x08E2, 0x08E3, 0x08E4, 0x08E5, 0x08E6, 0x08E7,
- 0x12C0, 0x12C1, 0x12C2, 0x12C3, 0x12C4, 0x12C5, 0x12C6, 0x12C7,
- 0x12C8, 0x12C9, 0x12CA, 0x12CB, 0x12CC, 0x12CD, 0x12CE, 0x12CF,
- 0x12D0, 0x12D1, 0x12D2, 0x12D3, 0x12D4, 0x12D5, 0x12D6, 0x12D7,
- 0x12D8, 0x12D9, 0x12DA, 0x12DB, 0x12DC, 0x12DD, 0x12DE, 0x12DF,
- 0x12E0, 0x12E1, 0x12E2, 0x12E3, 0x12E4, 0x12E5, 0x12E6, 0x12E7,
- 0x1CC0, 0x1CC1, 0x1CC2, 0x1CC3, 0x1CC4, 0x1CC5, 0x1CC6, 0x1CC7,
- 0x1CC8, 0x1CC9, 0x1CCA, 0x1CCB, 0x1CCC, 0x1CCD, 0x1CCE, 0x1CCF,
- 0x1CD0, 0x1CD1, 0x1CD2, 0x1CD3, 0x1CD4, 0x1CD5, 0x1CD6, 0x1CD7,
- 0x1CD8, 0x1CD9, 0x1CDA, 0x1CDB, 0x1CDC, 0x1CDD, 0x1CDE, 0x1CDF,
- 0x1CE0, 0x1CE1, 0x1CE2, 0x1CE3, 0x1CE4, 0x1CE5, 0x1CE6, 0x1CE7,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
- 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
- 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
- 0x0A28, 0x0A29, 0x0A2A, 0x0A2B, 0x0A2C, 0x0A2D, 0x0A2E, 0x0A2F,
- 0x0A30, 0x0A31, 0x0A32, 0x0A33, 0x0A34, 0x0A35, 0x0A36, 0x0A37,
- 0x0A38, 0x0A39, 0x0A3A, 0x0A3B, 0x0A3C, 0x0A3D, 0x0A3E, 0x0A3F,
- 0x0A40, 0x0A41, 0x0A42, 0x0A43, 0x0A44, 0x0A45, 0x0A46, 0x0A47,
- 0x0A48, 0x0A49, 0x0A4A, 0x0A4B, 0x0A4C, 0x0A4D, 0x0A4E, 0x0A4F,
- 0x1428, 0x1429, 0x142A, 0x142B, 0x142C, 0x142D, 0x142E, 0x142F,
- 0x1430, 0x1431, 0x1432, 0x1433, 0x1434, 0x1435, 0x1436, 0x1437,
- 0x1438, 0x1439, 0x143A, 0x143B, 0x143C, 0x143D, 0x143E, 0x143F,
- 0x1440, 0x1441, 0x1442, 0x1443, 0x1444, 0x1445, 0x1446, 0x1447,
- 0x1448, 0x1449, 0x144A, 0x144B, 0x144C, 0x144D, 0x144E, 0x144F,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0168, 0x0169, 0x016A, 0x016B, 0x016C, 0x016D, 0x016E, 0x016F,
- 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175, 0x0176, 0x0177,
- 0x0178, 0x0179, 0x017A, 0x017B, 0x017C, 0x017D, 0x017E, 0x017F,
- 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185, 0x0186, 0x0187,
- 0x0188, 0x0189, 0x018A, 0x018B, 0x018C, 0x018D, 0x018E, 0x018F,
- 0x0B68, 0x0B69, 0x0B6A, 0x0B6B, 0x0B6C, 0x0B6D, 0x0B6E, 0x0B6F,
- 0x0B70, 0x0B71, 0x0B72, 0x0B73, 0x0B74, 0x0B75, 0x0B76, 0x0B77,
- 0x0B78, 0x0B79, 0x0B7A, 0x0B7B, 0x0B7C, 0x0B7D, 0x0B7E, 0x0B7F,
- 0x0B80, 0x0B81, 0x0B82, 0x0B83, 0x0B84, 0x0B85, 0x0B86, 0x0B87,
- 0x0B88, 0x0B89, 0x0B8A, 0x0B8B, 0x0B8C, 0x0B8D, 0x0B8E, 0x0B8F,
- 0x1568, 0x1569, 0x156A, 0x156B, 0x156C, 0x156D, 0x156E, 0x156F,
- 0x1570, 0x1571, 0x1572, 0x1573, 0x1574, 0x1575, 0x1576, 0x1577,
- 0x1578, 0x1579, 0x157A, 0x157B, 0x157C, 0x157D, 0x157E, 0x157F,
- 0x1580, 0x1581, 0x1582, 0x1583, 0x1584, 0x1585, 0x1586, 0x1587,
- 0x1588, 0x1589, 0x158A, 0x158B, 0x158C, 0x158D, 0x158E, 0x158F,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x02A8, 0x02A9, 0x02AA, 0x02AB, 0x02AC, 0x02AD, 0x02AE, 0x02AF,
- 0x02B0, 0x02B1, 0x02B2, 0x02B3, 0x02B4, 0x02B5, 0x02B6, 0x02B7,
- 0x02B8, 0x02B9, 0x02BA, 0x02BB, 0x02BC, 0x02BD, 0x02BE, 0x02BF,
- 0x02C0, 0x02C1, 0x02C2, 0x02C3, 0x02C4, 0x02C5, 0x02C6, 0x02C7,
- 0x02C8, 0x02C9, 0x02CA, 0x02CB, 0x02CC, 0x02CD, 0x02CE, 0x02CF,
- 0x0CA8, 0x0CA9, 0x0CAA, 0x0CAB, 0x0CAC, 0x0CAD, 0x0CAE, 0x0CAF,
- 0x0CB0, 0x0CB1, 0x0CB2, 0x0CB3, 0x0CB4, 0x0CB5, 0x0CB6, 0x0CB7,
- 0x0CB8, 0x0CB9, 0x0CBA, 0x0CBB, 0x0CBC, 0x0CBD, 0x0CBE, 0x0CBF,
- 0x0CC0, 0x0CC1, 0x0CC2, 0x0CC3, 0x0CC4, 0x0CC5, 0x0CC6, 0x0CC7,
- 0x0CC8, 0x0CC9, 0x0CCA, 0x0CCB, 0x0CCC, 0x0CCD, 0x0CCE, 0x0CCF,
- 0x16A8, 0x16A9, 0x16AA, 0x16AB, 0x16AC, 0x16AD, 0x16AE, 0x16AF,
- 0x16B0, 0x16B1, 0x16B2, 0x16B3, 0x16B4, 0x16B5, 0x16B6, 0x16B7,
- 0x16B8, 0x16B9, 0x16BA, 0x16BB, 0x16BC, 0x16BD, 0x16BE, 0x16BF,
- 0x16C0, 0x16C1, 0x16C2, 0x16C3, 0x16C4, 0x16C5, 0x16C6, 0x16C7,
- 0x16C8, 0x16C9, 0x16CA, 0x16CB, 0x16CC, 0x16CD, 0x16CE, 0x16CF,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x03E8, 0x03E9, 0x03EA, 0x03EB, 0x03EC, 0x03ED, 0x03EE, 0x03EF,
- 0x03F0, 0x03F1, 0x03F2, 0x03F3, 0x03F4, 0x03F5, 0x03F6, 0x03F7,
- 0x03F8, 0x03F9, 0x03FA, 0x03FB, 0x03FC, 0x03FD, 0x03FE, 0x03FF,
- 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407,
- 0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x040D, 0x040E, 0x040F,
- 0x0DE8, 0x0DE9, 0x0DEA, 0x0DEB, 0x0DEC, 0x0DED, 0x0DEE, 0x0DEF,
- 0x0DF0, 0x0DF1, 0x0DF2, 0x0DF3, 0x0DF4, 0x0DF5, 0x0DF6, 0x0DF7,
- 0x0DF8, 0x0DF9, 0x0DFA, 0x0DFB, 0x0DFC, 0x0DFD, 0x0DFE, 0x0DFF,
- 0x0E00, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07,
- 0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F,
- 0x17E8, 0x17E9, 0x17EA, 0x17EB, 0x17EC, 0x17ED, 0x17EE, 0x17EF,
- 0x17F0, 0x17F1, 0x17F2, 0x17F3, 0x17F4, 0x17F5, 0x17F6, 0x17F7,
- 0x17F8, 0x17F9, 0x17FA, 0x17FB, 0x17FC, 0x17FD, 0x17FE, 0x17FF,
- 0x1800, 0x1801, 0x1802, 0x1803, 0x1804, 0x1805, 0x1806, 0x1807,
- 0x1808, 0x1809, 0x180A, 0x180B, 0x180C, 0x180D, 0x180E, 0x180F,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0528, 0x0529, 0x052A, 0x052B, 0x052C, 0x052D, 0x052E, 0x052F,
- 0x0530, 0x0531, 0x0532, 0x0533, 0x0534, 0x0535, 0x0536, 0x0537,
- 0x0538, 0x0539, 0x053A, 0x053B, 0x053C, 0x053D, 0x053E, 0x053F,
- 0x0540, 0x0541, 0x0542, 0x0543, 0x0544, 0x0545, 0x0546, 0x0547,
- 0x0548, 0x0549, 0x054A, 0x054B, 0x054C, 0x054D, 0x054E, 0x054F,
- 0x0F28, 0x0F29, 0x0F2A, 0x0F2B, 0x0F2C, 0x0F2D, 0x0F2E, 0x0F2F,
- 0x0F30, 0x0F31, 0x0F32, 0x0F33, 0x0F34, 0x0F35, 0x0F36, 0x0F37,
- 0x0F38, 0x0F39, 0x0F3A, 0x0F3B, 0x0F3C, 0x0F3D, 0x0F3E, 0x0F3F,
- 0x0F40, 0x0F41, 0x0F42, 0x0F43, 0x0F44, 0x0F45, 0x0F46, 0x0F47,
- 0x0F48, 0x0F49, 0x0F4A, 0x0F4B, 0x0F4C, 0x0F4D, 0x0F4E, 0x0F4F,
- 0x1928, 0x1929, 0x192A, 0x192B, 0x192C, 0x192D, 0x192E, 0x192F,
- 0x1930, 0x1931, 0x1932, 0x1933, 0x1934, 0x1935, 0x1936, 0x1937,
- 0x1938, 0x1939, 0x193A, 0x193B, 0x193C, 0x193D, 0x193E, 0x193F,
- 0x1940, 0x1941, 0x1942, 0x1943, 0x1944, 0x1945, 0x1946, 0x1947,
- 0x1948, 0x1949, 0x194A, 0x194B, 0x194C, 0x194D, 0x194E, 0x194F,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0668, 0x0669, 0x066A, 0x066B, 0x066C, 0x066D, 0x066E, 0x066F,
- 0x0670, 0x0671, 0x0672, 0x0673, 0x0674, 0x0675, 0x0676, 0x0677,
- 0x0678, 0x0679, 0x067A, 0x067B, 0x067C, 0x067D, 0x067E, 0x067F,
- 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0686, 0x0687,
- 0x0688, 0x0689, 0x068A, 0x068B, 0x068C, 0x068D, 0x068E, 0x068F,
- 0x1068, 0x1069, 0x106A, 0x106B, 0x106C, 0x106D, 0x106E, 0x106F,
- 0x1070, 0x1071, 0x1072, 0x1073, 0x1074, 0x1075, 0x1076, 0x1077,
- 0x1078, 0x1079, 0x107A, 0x107B, 0x107C, 0x107D, 0x107E, 0x107F,
- 0x1080, 0x1081, 0x1082, 0x1083, 0x1084, 0x1085, 0x1086, 0x1087,
- 0x1088, 0x1089, 0x108A, 0x108B, 0x108C, 0x108D, 0x108E, 0x108F,
- 0x1A68, 0x1A69, 0x1A6A, 0x1A6B, 0x1A6C, 0x1A6D, 0x1A6E, 0x1A6F,
- 0x1A70, 0x1A71, 0x1A72, 0x1A73, 0x1A74, 0x1A75, 0x1A76, 0x1A77,
- 0x1A78, 0x1A79, 0x1A7A, 0x1A7B, 0x1A7C, 0x1A7D, 0x1A7E, 0x1A7F,
- 0x1A80, 0x1A81, 0x1A82, 0x1A83, 0x1A84, 0x1A85, 0x1A86, 0x1A87,
- 0x1A88, 0x1A89, 0x1A8A, 0x1A8B, 0x1A8C, 0x1A8D, 0x1A8E, 0x1A8F,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x07A8, 0x07A9, 0x07AA, 0x07AB, 0x07AC, 0x07AD, 0x07AE, 0x07AF,
- 0x07B0, 0x07B1, 0x07B2, 0x07B3, 0x07B4, 0x07B5, 0x07B6, 0x07B7,
- 0x07B8, 0x07B9, 0x07BA, 0x07BB, 0x07BC, 0x07BD, 0x07BE, 0x07BF,
- 0x07C0, 0x07C1, 0x07C2, 0x07C3, 0x07C4, 0x07C5, 0x07C6, 0x07C7,
- 0x07C8, 0x07C9, 0x07CA, 0x07CB, 0x07CC, 0x07CD, 0x07CE, 0x07CF,
- 0x11A8, 0x11A9, 0x11AA, 0x11AB, 0x11AC, 0x11AD, 0x11AE, 0x11AF,
- 0x11B0, 0x11B1, 0x11B2, 0x11B3, 0x11B4, 0x11B5, 0x11B6, 0x11B7,
- 0x11B8, 0x11B9, 0x11BA, 0x11BB, 0x11BC, 0x11BD, 0x11BE, 0x11BF,
- 0x11C0, 0x11C1, 0x11C2, 0x11C3, 0x11C4, 0x11C5, 0x11C6, 0x11C7,
- 0x11C8, 0x11C9, 0x11CA, 0x11CB, 0x11CC, 0x11CD, 0x11CE, 0x11CF,
- 0x1BA8, 0x1BA9, 0x1BAA, 0x1BAB, 0x1BAC, 0x1BAD, 0x1BAE, 0x1BAF,
- 0x1BB0, 0x1BB1, 0x1BB2, 0x1BB3, 0x1BB4, 0x1BB5, 0x1BB6, 0x1BB7,
- 0x1BB8, 0x1BB9, 0x1BBA, 0x1BBB, 0x1BBC, 0x1BBD, 0x1BBE, 0x1BBF,
- 0x1BC0, 0x1BC1, 0x1BC2, 0x1BC3, 0x1BC4, 0x1BC5, 0x1BC6, 0x1BC7,
- 0x1BC8, 0x1BC9, 0x1BCA, 0x1BCB, 0x1BCC, 0x1BCD, 0x1BCE, 0x1BCF,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x08E8, 0x08E9, 0x08EA, 0x08EB, 0x08EC, 0x08ED, 0x08EE, 0x08EF,
- 0x08F0, 0x08F1, 0x08F2, 0x08F3, 0x08F4, 0x08F5, 0x08F6, 0x08F7,
- 0x08F8, 0x08F9, 0x08FA, 0x08FB, 0x08FC, 0x08FD, 0x08FE, 0x08FF,
- 0x0900, 0x0901, 0x0902, 0x0903, 0x0904, 0x0905, 0x0906, 0x0907,
- 0x0908, 0x0909, 0x090A, 0x090B, 0x090C, 0x090D, 0x090E, 0x090F,
- 0x12E8, 0x12E9, 0x12EA, 0x12EB, 0x12EC, 0x12ED, 0x12EE, 0x12EF,
- 0x12F0, 0x12F1, 0x12F2, 0x12F3, 0x12F4, 0x12F5, 0x12F6, 0x12F7,
- 0x12F8, 0x12F9, 0x12FA, 0x12FB, 0x12FC, 0x12FD, 0x12FE, 0x12FF,
- 0x1300, 0x1301, 0x1302, 0x1303, 0x1304, 0x1305, 0x1306, 0x1307,
- 0x1308, 0x1309, 0x130A, 0x130B, 0x130C, 0x130D, 0x130E, 0x130F,
- 0x1CE8, 0x1CE9, 0x1CEA, 0x1CEB, 0x1CEC, 0x1CED, 0x1CEE, 0x1CEF,
- 0x1CF0, 0x1CF1, 0x1CF2, 0x1CF3, 0x1CF4, 0x1CF5, 0x1CF6, 0x1CF7,
- 0x1CF8, 0x1CF9, 0x1CFA, 0x1CFB, 0x1CFC, 0x1CFD, 0x1CFE, 0x1CFF,
- 0x1D00, 0x1D01, 0x1D02, 0x1D03, 0x1D04, 0x1D05, 0x1D06, 0x1D07,
- 0x1D08, 0x1D09, 0x1D0A, 0x1D0B, 0x1D0C, 0x1D0D, 0x1D0E, 0x1D0F,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
- 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
- 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
- 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
- 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
- 0x0A50, 0x0A51, 0x0A52, 0x0A53, 0x0A54, 0x0A55, 0x0A56, 0x0A57,
- 0x0A58, 0x0A59, 0x0A5A, 0x0A5B, 0x0A5C, 0x0A5D, 0x0A5E, 0x0A5F,
- 0x0A60, 0x0A61, 0x0A62, 0x0A63, 0x0A64, 0x0A65, 0x0A66, 0x0A67,
- 0x0A68, 0x0A69, 0x0A6A, 0x0A6B, 0x0A6C, 0x0A6D, 0x0A6E, 0x0A6F,
- 0x0A70, 0x0A71, 0x0A72, 0x0A73, 0x0A74, 0x0A75, 0x0A76, 0x0A77,
- 0x1450, 0x1451, 0x1452, 0x1453, 0x1454, 0x1455, 0x1456, 0x1457,
- 0x1458, 0x1459, 0x145A, 0x145B, 0x145C, 0x145D, 0x145E, 0x145F,
- 0x1460, 0x1461, 0x1462, 0x1463, 0x1464, 0x1465, 0x1466, 0x1467,
- 0x1468, 0x1469, 0x146A, 0x146B, 0x146C, 0x146D, 0x146E, 0x146F,
- 0x1470, 0x1471, 0x1472, 0x1473, 0x1474, 0x1475, 0x1476, 0x1477,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0190, 0x0191, 0x0192, 0x0193, 0x0194, 0x0195, 0x0196, 0x0197,
- 0x0198, 0x0199, 0x019A, 0x019B, 0x019C, 0x019D, 0x019E, 0x019F,
- 0x01A0, 0x01A1, 0x01A2, 0x01A3, 0x01A4, 0x01A5, 0x01A6, 0x01A7,
- 0x01A8, 0x01A9, 0x01AA, 0x01AB, 0x01AC, 0x01AD, 0x01AE, 0x01AF,
- 0x01B0, 0x01B1, 0x01B2, 0x01B3, 0x01B4, 0x01B5, 0x01B6, 0x01B7,
- 0x0B90, 0x0B91, 0x0B92, 0x0B93, 0x0B94, 0x0B95, 0x0B96, 0x0B97,
- 0x0B98, 0x0B99, 0x0B9A, 0x0B9B, 0x0B9C, 0x0B9D, 0x0B9E, 0x0B9F,
- 0x0BA0, 0x0BA1, 0x0BA2, 0x0BA3, 0x0BA4, 0x0BA5, 0x0BA6, 0x0BA7,
- 0x0BA8, 0x0BA9, 0x0BAA, 0x0BAB, 0x0BAC, 0x0BAD, 0x0BAE, 0x0BAF,
- 0x0BB0, 0x0BB1, 0x0BB2, 0x0BB3, 0x0BB4, 0x0BB5, 0x0BB6, 0x0BB7,
- 0x1590, 0x1591, 0x1592, 0x1593, 0x1594, 0x1595, 0x1596, 0x1597,
- 0x1598, 0x1599, 0x159A, 0x159B, 0x159C, 0x159D, 0x159E, 0x159F,
- 0x15A0, 0x15A1, 0x15A2, 0x15A3, 0x15A4, 0x15A5, 0x15A6, 0x15A7,
- 0x15A8, 0x15A9, 0x15AA, 0x15AB, 0x15AC, 0x15AD, 0x15AE, 0x15AF,
- 0x15B0, 0x15B1, 0x15B2, 0x15B3, 0x15B4, 0x15B5, 0x15B6, 0x15B7,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x02D0, 0x02D1, 0x02D2, 0x02D3, 0x02D4, 0x02D5, 0x02D6, 0x02D7,
- 0x02D8, 0x02D9, 0x02DA, 0x02DB, 0x02DC, 0x02DD, 0x02DE, 0x02DF,
- 0x02E0, 0x02E1, 0x02E2, 0x02E3, 0x02E4, 0x02E5, 0x02E6, 0x02E7,
- 0x02E8, 0x02E9, 0x02EA, 0x02EB, 0x02EC, 0x02ED, 0x02EE, 0x02EF,
- 0x02F0, 0x02F1, 0x02F2, 0x02F3, 0x02F4, 0x02F5, 0x02F6, 0x02F7,
- 0x0CD0, 0x0CD1, 0x0CD2, 0x0CD3, 0x0CD4, 0x0CD5, 0x0CD6, 0x0CD7,
- 0x0CD8, 0x0CD9, 0x0CDA, 0x0CDB, 0x0CDC, 0x0CDD, 0x0CDE, 0x0CDF,
- 0x0CE0, 0x0CE1, 0x0CE2, 0x0CE3, 0x0CE4, 0x0CE5, 0x0CE6, 0x0CE7,
- 0x0CE8, 0x0CE9, 0x0CEA, 0x0CEB, 0x0CEC, 0x0CED, 0x0CEE, 0x0CEF,
- 0x0CF0, 0x0CF1, 0x0CF2, 0x0CF3, 0x0CF4, 0x0CF5, 0x0CF6, 0x0CF7,
- 0x16D0, 0x16D1, 0x16D2, 0x16D3, 0x16D4, 0x16D5, 0x16D6, 0x16D7,
- 0x16D8, 0x16D9, 0x16DA, 0x16DB, 0x16DC, 0x16DD, 0x16DE, 0x16DF,
- 0x16E0, 0x16E1, 0x16E2, 0x16E3, 0x16E4, 0x16E5, 0x16E6, 0x16E7,
- 0x16E8, 0x16E9, 0x16EA, 0x16EB, 0x16EC, 0x16ED, 0x16EE, 0x16EF,
- 0x16F0, 0x16F1, 0x16F2, 0x16F3, 0x16F4, 0x16F5, 0x16F6, 0x16F7,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
- 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
- 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
- 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
- 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
- 0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17,
- 0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F,
- 0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
- 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F,
- 0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37,
- 0x1810, 0x1811, 0x1812, 0x1813, 0x1814, 0x1815, 0x1816, 0x1817,
- 0x1818, 0x1819, 0x181A, 0x181B, 0x181C, 0x181D, 0x181E, 0x181F,
- 0x1820, 0x1821, 0x1822, 0x1823, 0x1824, 0x1825, 0x1826, 0x1827,
- 0x1828, 0x1829, 0x182A, 0x182B, 0x182C, 0x182D, 0x182E, 0x182F,
- 0x1830, 0x1831, 0x1832, 0x1833, 0x1834, 0x1835, 0x1836, 0x1837,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0550, 0x0551, 0x0552, 0x0553, 0x0554, 0x0555, 0x0556, 0x0557,
- 0x0558, 0x0559, 0x055A, 0x055B, 0x055C, 0x055D, 0x055E, 0x055F,
- 0x0560, 0x0561, 0x0562, 0x0563, 0x0564, 0x0565, 0x0566, 0x0567,
- 0x0568, 0x0569, 0x056A, 0x056B, 0x056C, 0x056D, 0x056E, 0x056F,
- 0x0570, 0x0571, 0x0572, 0x0573, 0x0574, 0x0575, 0x0576, 0x0577,
- 0x0F50, 0x0F51, 0x0F52, 0x0F53, 0x0F54, 0x0F55, 0x0F56, 0x0F57,
- 0x0F58, 0x0F59, 0x0F5A, 0x0F5B, 0x0F5C, 0x0F5D, 0x0F5E, 0x0F5F,
- 0x0F60, 0x0F61, 0x0F62, 0x0F63, 0x0F64, 0x0F65, 0x0F66, 0x0F67,
- 0x0F68, 0x0F69, 0x0F6A, 0x0F6B, 0x0F6C, 0x0F6D, 0x0F6E, 0x0F6F,
- 0x0F70, 0x0F71, 0x0F72, 0x0F73, 0x0F74, 0x0F75, 0x0F76, 0x0F77,
- 0x1950, 0x1951, 0x1952, 0x1953, 0x1954, 0x1955, 0x1956, 0x1957,
- 0x1958, 0x1959, 0x195A, 0x195B, 0x195C, 0x195D, 0x195E, 0x195F,
- 0x1960, 0x1961, 0x1962, 0x1963, 0x1964, 0x1965, 0x1966, 0x1967,
- 0x1968, 0x1969, 0x196A, 0x196B, 0x196C, 0x196D, 0x196E, 0x196F,
- 0x1970, 0x1971, 0x1972, 0x1973, 0x1974, 0x1975, 0x1976, 0x1977,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0690, 0x0691, 0x0692, 0x0693, 0x0694, 0x0695, 0x0696, 0x0697,
- 0x0698, 0x0699, 0x069A, 0x069B, 0x069C, 0x069D, 0x069E, 0x069F,
- 0x06A0, 0x06A1, 0x06A2, 0x06A3, 0x06A4, 0x06A5, 0x06A6, 0x06A7,
- 0x06A8, 0x06A9, 0x06AA, 0x06AB, 0x06AC, 0x06AD, 0x06AE, 0x06AF,
- 0x06B0, 0x06B1, 0x06B2, 0x06B3, 0x06B4, 0x06B5, 0x06B6, 0x06B7,
- 0x1090, 0x1091, 0x1092, 0x1093, 0x1094, 0x1095, 0x1096, 0x1097,
- 0x1098, 0x1099, 0x109A, 0x109B, 0x109C, 0x109D, 0x109E, 0x109F,
- 0x10A0, 0x10A1, 0x10A2, 0x10A3, 0x10A4, 0x10A5, 0x10A6, 0x10A7,
- 0x10A8, 0x10A9, 0x10AA, 0x10AB, 0x10AC, 0x10AD, 0x10AE, 0x10AF,
- 0x10B0, 0x10B1, 0x10B2, 0x10B3, 0x10B4, 0x10B5, 0x10B6, 0x10B7,
- 0x1A90, 0x1A91, 0x1A92, 0x1A93, 0x1A94, 0x1A95, 0x1A96, 0x1A97,
- 0x1A98, 0x1A99, 0x1A9A, 0x1A9B, 0x1A9C, 0x1A9D, 0x1A9E, 0x1A9F,
- 0x1AA0, 0x1AA1, 0x1AA2, 0x1AA3, 0x1AA4, 0x1AA5, 0x1AA6, 0x1AA7,
- 0x1AA8, 0x1AA9, 0x1AAA, 0x1AAB, 0x1AAC, 0x1AAD, 0x1AAE, 0x1AAF,
- 0x1AB0, 0x1AB1, 0x1AB2, 0x1AB3, 0x1AB4, 0x1AB5, 0x1AB6, 0x1AB7,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x07D0, 0x07D1, 0x07D2, 0x07D3, 0x07D4, 0x07D5, 0x07D6, 0x07D7,
- 0x07D8, 0x07D9, 0x07DA, 0x07DB, 0x07DC, 0x07DD, 0x07DE, 0x07DF,
- 0x07E0, 0x07E1, 0x07E2, 0x07E3, 0x07E4, 0x07E5, 0x07E6, 0x07E7,
- 0x07E8, 0x07E9, 0x07EA, 0x07EB, 0x07EC, 0x07ED, 0x07EE, 0x07EF,
- 0x07F0, 0x07F1, 0x07F2, 0x07F3, 0x07F4, 0x07F5, 0x07F6, 0x07F7,
- 0x11D0, 0x11D1, 0x11D2, 0x11D3, 0x11D4, 0x11D5, 0x11D6, 0x11D7,
- 0x11D8, 0x11D9, 0x11DA, 0x11DB, 0x11DC, 0x11DD, 0x11DE, 0x11DF,
- 0x11E0, 0x11E1, 0x11E2, 0x11E3, 0x11E4, 0x11E5, 0x11E6, 0x11E7,
- 0x11E8, 0x11E9, 0x11EA, 0x11EB, 0x11EC, 0x11ED, 0x11EE, 0x11EF,
- 0x11F0, 0x11F1, 0x11F2, 0x11F3, 0x11F4, 0x11F5, 0x11F6, 0x11F7,
- 0x1BD0, 0x1BD1, 0x1BD2, 0x1BD3, 0x1BD4, 0x1BD5, 0x1BD6, 0x1BD7,
- 0x1BD8, 0x1BD9, 0x1BDA, 0x1BDB, 0x1BDC, 0x1BDD, 0x1BDE, 0x1BDF,
- 0x1BE0, 0x1BE1, 0x1BE2, 0x1BE3, 0x1BE4, 0x1BE5, 0x1BE6, 0x1BE7,
- 0x1BE8, 0x1BE9, 0x1BEA, 0x1BEB, 0x1BEC, 0x1BED, 0x1BEE, 0x1BEF,
- 0x1BF0, 0x1BF1, 0x1BF2, 0x1BF3, 0x1BF4, 0x1BF5, 0x1BF6, 0x1BF7,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0910, 0x0911, 0x0912, 0x0913, 0x0914, 0x0915, 0x0916, 0x0917,
- 0x0918, 0x0919, 0x091A, 0x091B, 0x091C, 0x091D, 0x091E, 0x091F,
- 0x0920, 0x0921, 0x0922, 0x0923, 0x0924, 0x0925, 0x0926, 0x0927,
- 0x0928, 0x0929, 0x092A, 0x092B, 0x092C, 0x092D, 0x092E, 0x092F,
- 0x0930, 0x0931, 0x0932, 0x0933, 0x0934, 0x0935, 0x0936, 0x0937,
- 0x1310, 0x1311, 0x1312, 0x1313, 0x1314, 0x1315, 0x1316, 0x1317,
- 0x1318, 0x1319, 0x131A, 0x131B, 0x131C, 0x131D, 0x131E, 0x131F,
- 0x1320, 0x1321, 0x1322, 0x1323, 0x1324, 0x1325, 0x1326, 0x1327,
- 0x1328, 0x1329, 0x132A, 0x132B, 0x132C, 0x132D, 0x132E, 0x132F,
- 0x1330, 0x1331, 0x1332, 0x1333, 0x1334, 0x1335, 0x1336, 0x1337,
- 0x1D10, 0x1D11, 0x1D12, 0x1D13, 0x1D14, 0x1D15, 0x1D16, 0x1D17,
- 0x1D18, 0x1D19, 0x1D1A, 0x1D1B, 0x1D1C, 0x1D1D, 0x1D1E, 0x1D1F,
- 0x1D20, 0x1D21, 0x1D22, 0x1D23, 0x1D24, 0x1D25, 0x1D26, 0x1D27,
- 0x1D28, 0x1D29, 0x1D2A, 0x1D2B, 0x1D2C, 0x1D2D, 0x1D2E, 0x1D2F,
- 0x1D30, 0x1D31, 0x1D32, 0x1D33, 0x1D34, 0x1D35, 0x1D36, 0x1D37,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
- 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
- 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
- 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
- 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
- 0x0A78, 0x0A79, 0x0A7A, 0x0A7B, 0x0A7C, 0x0A7D, 0x0A7E, 0x0A7F,
- 0x0A80, 0x0A81, 0x0A82, 0x0A83, 0x0A84, 0x0A85, 0x0A86, 0x0A87,
- 0x0A88, 0x0A89, 0x0A8A, 0x0A8B, 0x0A8C, 0x0A8D, 0x0A8E, 0x0A8F,
- 0x0A90, 0x0A91, 0x0A92, 0x0A93, 0x0A94, 0x0A95, 0x0A96, 0x0A97,
- 0x0A98, 0x0A99, 0x0A9A, 0x0A9B, 0x0A9C, 0x0A9D, 0x0A9E, 0x0A9F,
- 0x1478, 0x1479, 0x147A, 0x147B, 0x147C, 0x147D, 0x147E, 0x147F,
- 0x1480, 0x1481, 0x1482, 0x1483, 0x1484, 0x1485, 0x1486, 0x1487,
- 0x1488, 0x1489, 0x148A, 0x148B, 0x148C, 0x148D, 0x148E, 0x148F,
- 0x1490, 0x1491, 0x1492, 0x1493, 0x1494, 0x1495, 0x1496, 0x1497,
- 0x1498, 0x1499, 0x149A, 0x149B, 0x149C, 0x149D, 0x149E, 0x149F,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x01B8, 0x01B9, 0x01BA, 0x01BB, 0x01BC, 0x01BD, 0x01BE, 0x01BF,
- 0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C4, 0x01C5, 0x01C6, 0x01C7,
- 0x01C8, 0x01C9, 0x01CA, 0x01CB, 0x01CC, 0x01CD, 0x01CE, 0x01CF,
- 0x01D0, 0x01D1, 0x01D2, 0x01D3, 0x01D4, 0x01D5, 0x01D6, 0x01D7,
- 0x01D8, 0x01D9, 0x01DA, 0x01DB, 0x01DC, 0x01DD, 0x01DE, 0x01DF,
- 0x0BB8, 0x0BB9, 0x0BBA, 0x0BBB, 0x0BBC, 0x0BBD, 0x0BBE, 0x0BBF,
- 0x0BC0, 0x0BC1, 0x0BC2, 0x0BC3, 0x0BC4, 0x0BC5, 0x0BC6, 0x0BC7,
- 0x0BC8, 0x0BC9, 0x0BCA, 0x0BCB, 0x0BCC, 0x0BCD, 0x0BCE, 0x0BCF,
- 0x0BD0, 0x0BD1, 0x0BD2, 0x0BD3, 0x0BD4, 0x0BD5, 0x0BD6, 0x0BD7,
- 0x0BD8, 0x0BD9, 0x0BDA, 0x0BDB, 0x0BDC, 0x0BDD, 0x0BDE, 0x0BDF,
- 0x15B8, 0x15B9, 0x15BA, 0x15BB, 0x15BC, 0x15BD, 0x15BE, 0x15BF,
- 0x15C0, 0x15C1, 0x15C2, 0x15C3, 0x15C4, 0x15C5, 0x15C6, 0x15C7,
- 0x15C8, 0x15C9, 0x15CA, 0x15CB, 0x15CC, 0x15CD, 0x15CE, 0x15CF,
- 0x15D0, 0x15D1, 0x15D2, 0x15D3, 0x15D4, 0x15D5, 0x15D6, 0x15D7,
- 0x15D8, 0x15D9, 0x15DA, 0x15DB, 0x15DC, 0x15DD, 0x15DE, 0x15DF,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x02F8, 0x02F9, 0x02FA, 0x02FB, 0x02FC, 0x02FD, 0x02FE, 0x02FF,
- 0x0300, 0x0301, 0x0302, 0x0303, 0x0304, 0x0305, 0x0306, 0x0307,
- 0x0308, 0x0309, 0x030A, 0x030B, 0x030C, 0x030D, 0x030E, 0x030F,
- 0x0310, 0x0311, 0x0312, 0x0313, 0x0314, 0x0315, 0x0316, 0x0317,
- 0x0318, 0x0319, 0x031A, 0x031B, 0x031C, 0x031D, 0x031E, 0x031F,
- 0x0CF8, 0x0CF9, 0x0CFA, 0x0CFB, 0x0CFC, 0x0CFD, 0x0CFE, 0x0CFF,
- 0x0D00, 0x0D01, 0x0D02, 0x0D03, 0x0D04, 0x0D05, 0x0D06, 0x0D07,
- 0x0D08, 0x0D09, 0x0D0A, 0x0D0B, 0x0D0C, 0x0D0D, 0x0D0E, 0x0D0F,
- 0x0D10, 0x0D11, 0x0D12, 0x0D13, 0x0D14, 0x0D15, 0x0D16, 0x0D17,
- 0x0D18, 0x0D19, 0x0D1A, 0x0D1B, 0x0D1C, 0x0D1D, 0x0D1E, 0x0D1F,
- 0x16F8, 0x16F9, 0x16FA, 0x16FB, 0x16FC, 0x16FD, 0x16FE, 0x16FF,
- 0x1700, 0x1701, 0x1702, 0x1703, 0x1704, 0x1705, 0x1706, 0x1707,
- 0x1708, 0x1709, 0x170A, 0x170B, 0x170C, 0x170D, 0x170E, 0x170F,
- 0x1710, 0x1711, 0x1712, 0x1713, 0x1714, 0x1715, 0x1716, 0x1717,
- 0x1718, 0x1719, 0x171A, 0x171B, 0x171C, 0x171D, 0x171E, 0x171F,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
- 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
- 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
- 0x0450, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457,
- 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x045D, 0x045E, 0x045F,
- 0x0E38, 0x0E39, 0x0E3A, 0x0E3B, 0x0E3C, 0x0E3D, 0x0E3E, 0x0E3F,
- 0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47,
- 0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F,
- 0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57,
- 0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0x0E5C, 0x0E5D, 0x0E5E, 0x0E5F,
- 0x1838, 0x1839, 0x183A, 0x183B, 0x183C, 0x183D, 0x183E, 0x183F,
- 0x1840, 0x1841, 0x1842, 0x1843, 0x1844, 0x1845, 0x1846, 0x1847,
- 0x1848, 0x1849, 0x184A, 0x184B, 0x184C, 0x184D, 0x184E, 0x184F,
- 0x1850, 0x1851, 0x1852, 0x1853, 0x1854, 0x1855, 0x1856, 0x1857,
- 0x1858, 0x1859, 0x185A, 0x185B, 0x185C, 0x185D, 0x185E, 0x185F,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0578, 0x0579, 0x057A, 0x057B, 0x057C, 0x057D, 0x057E, 0x057F,
- 0x0580, 0x0581, 0x0582, 0x0583, 0x0584, 0x0585, 0x0586, 0x0587,
- 0x0588, 0x0589, 0x058A, 0x058B, 0x058C, 0x058D, 0x058E, 0x058F,
- 0x0590, 0x0591, 0x0592, 0x0593, 0x0594, 0x0595, 0x0596, 0x0597,
- 0x0598, 0x0599, 0x059A, 0x059B, 0x059C, 0x059D, 0x059E, 0x059F,
- 0x0F78, 0x0F79, 0x0F7A, 0x0F7B, 0x0F7C, 0x0F7D, 0x0F7E, 0x0F7F,
- 0x0F80, 0x0F81, 0x0F82, 0x0F83, 0x0F84, 0x0F85, 0x0F86, 0x0F87,
- 0x0F88, 0x0F89, 0x0F8A, 0x0F8B, 0x0F8C, 0x0F8D, 0x0F8E, 0x0F8F,
- 0x0F90, 0x0F91, 0x0F92, 0x0F93, 0x0F94, 0x0F95, 0x0F96, 0x0F97,
- 0x0F98, 0x0F99, 0x0F9A, 0x0F9B, 0x0F9C, 0x0F9D, 0x0F9E, 0x0F9F,
- 0x1978, 0x1979, 0x197A, 0x197B, 0x197C, 0x197D, 0x197E, 0x197F,
- 0x1980, 0x1981, 0x1982, 0x1983, 0x1984, 0x1985, 0x1986, 0x1987,
- 0x1988, 0x1989, 0x198A, 0x198B, 0x198C, 0x198D, 0x198E, 0x198F,
- 0x1990, 0x1991, 0x1992, 0x1993, 0x1994, 0x1995, 0x1996, 0x1997,
- 0x1998, 0x1999, 0x199A, 0x199B, 0x199C, 0x199D, 0x199E, 0x199F,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x06B8, 0x06B9, 0x06BA, 0x06BB, 0x06BC, 0x06BD, 0x06BE, 0x06BF,
- 0x06C0, 0x06C1, 0x06C2, 0x06C3, 0x06C4, 0x06C5, 0x06C6, 0x06C7,
- 0x06C8, 0x06C9, 0x06CA, 0x06CB, 0x06CC, 0x06CD, 0x06CE, 0x06CF,
- 0x06D0, 0x06D1, 0x06D2, 0x06D3, 0x06D4, 0x06D5, 0x06D6, 0x06D7,
- 0x06D8, 0x06D9, 0x06DA, 0x06DB, 0x06DC, 0x06DD, 0x06DE, 0x06DF,
- 0x10B8, 0x10B9, 0x10BA, 0x10BB, 0x10BC, 0x10BD, 0x10BE, 0x10BF,
- 0x10C0, 0x10C1, 0x10C2, 0x10C3, 0x10C4, 0x10C5, 0x10C6, 0x10C7,
- 0x10C8, 0x10C9, 0x10CA, 0x10CB, 0x10CC, 0x10CD, 0x10CE, 0x10CF,
- 0x10D0, 0x10D1, 0x10D2, 0x10D3, 0x10D4, 0x10D5, 0x10D6, 0x10D7,
- 0x10D8, 0x10D9, 0x10DA, 0x10DB, 0x10DC, 0x10DD, 0x10DE, 0x10DF,
- 0x1AB8, 0x1AB9, 0x1ABA, 0x1ABB, 0x1ABC, 0x1ABD, 0x1ABE, 0x1ABF,
- 0x1AC0, 0x1AC1, 0x1AC2, 0x1AC3, 0x1AC4, 0x1AC5, 0x1AC6, 0x1AC7,
- 0x1AC8, 0x1AC9, 0x1ACA, 0x1ACB, 0x1ACC, 0x1ACD, 0x1ACE, 0x1ACF,
- 0x1AD0, 0x1AD1, 0x1AD2, 0x1AD3, 0x1AD4, 0x1AD5, 0x1AD6, 0x1AD7,
- 0x1AD8, 0x1AD9, 0x1ADA, 0x1ADB, 0x1ADC, 0x1ADD, 0x1ADE, 0x1ADF,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x07F8, 0x07F9, 0x07FA, 0x07FB, 0x07FC, 0x07FD, 0x07FE, 0x07FF,
- 0x0800, 0x0801, 0x0802, 0x0803, 0x0804, 0x0805, 0x0806, 0x0807,
- 0x0808, 0x0809, 0x080A, 0x080B, 0x080C, 0x080D, 0x080E, 0x080F,
- 0x0810, 0x0811, 0x0812, 0x0813, 0x0814, 0x0815, 0x0816, 0x0817,
- 0x0818, 0x0819, 0x081A, 0x081B, 0x081C, 0x081D, 0x081E, 0x081F,
- 0x11F8, 0x11F9, 0x11FA, 0x11FB, 0x11FC, 0x11FD, 0x11FE, 0x11FF,
- 0x1200, 0x1201, 0x1202, 0x1203, 0x1204, 0x1205, 0x1206, 0x1207,
- 0x1208, 0x1209, 0x120A, 0x120B, 0x120C, 0x120D, 0x120E, 0x120F,
- 0x1210, 0x1211, 0x1212, 0x1213, 0x1214, 0x1215, 0x1216, 0x1217,
- 0x1218, 0x1219, 0x121A, 0x121B, 0x121C, 0x121D, 0x121E, 0x121F,
- 0x1BF8, 0x1BF9, 0x1BFA, 0x1BFB, 0x1BFC, 0x1BFD, 0x1BFE, 0x1BFF,
- 0x1C00, 0x1C01, 0x1C02, 0x1C03, 0x1C04, 0x1C05, 0x1C06, 0x1C07,
- 0x1C08, 0x1C09, 0x1C0A, 0x1C0B, 0x1C0C, 0x1C0D, 0x1C0E, 0x1C0F,
- 0x1C10, 0x1C11, 0x1C12, 0x1C13, 0x1C14, 0x1C15, 0x1C16, 0x1C17,
- 0x1C18, 0x1C19, 0x1C1A, 0x1C1B, 0x1C1C, 0x1C1D, 0x1C1E, 0x1C1F,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0938, 0x0939, 0x093A, 0x093B, 0x093C, 0x093D, 0x093E, 0x093F,
- 0x0940, 0x0941, 0x0942, 0x0943, 0x0944, 0x0945, 0x0946, 0x0947,
- 0x0948, 0x0949, 0x094A, 0x094B, 0x094C, 0x094D, 0x094E, 0x094F,
- 0x0950, 0x0951, 0x0952, 0x0953, 0x0954, 0x0955, 0x0956, 0x0957,
- 0x0958, 0x0959, 0x095A, 0x095B, 0x095C, 0x095D, 0x095E, 0x095F,
- 0x1338, 0x1339, 0x133A, 0x133B, 0x133C, 0x133D, 0x133E, 0x133F,
- 0x1340, 0x1341, 0x1342, 0x1343, 0x1344, 0x1345, 0x1346, 0x1347,
- 0x1348, 0x1349, 0x134A, 0x134B, 0x134C, 0x134D, 0x134E, 0x134F,
- 0x1350, 0x1351, 0x1352, 0x1353, 0x1354, 0x1355, 0x1356, 0x1357,
- 0x1358, 0x1359, 0x135A, 0x135B, 0x135C, 0x135D, 0x135E, 0x135F,
- 0x1D38, 0x1D39, 0x1D3A, 0x1D3B, 0x1D3C, 0x1D3D, 0x1D3E, 0x1D3F,
- 0x1D40, 0x1D41, 0x1D42, 0x1D43, 0x1D44, 0x1D45, 0x1D46, 0x1D47,
- 0x1D48, 0x1D49, 0x1D4A, 0x1D4B, 0x1D4C, 0x1D4D, 0x1D4E, 0x1D4F,
- 0x1D50, 0x1D51, 0x1D52, 0x1D53, 0x1D54, 0x1D55, 0x1D56, 0x1D57,
- 0x1D58, 0x1D59, 0x1D5A, 0x1D5B, 0x1D5C, 0x1D5D, 0x1D5E, 0x1D5F,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
- 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
- 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
- 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
- 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
- 0x0AA0, 0x0AA1, 0x0AA2, 0x0AA3, 0x0AA4, 0x0AA5, 0x0AA6, 0x0AA7,
- 0x0AA8, 0x0AA9, 0x0AAA, 0x0AAB, 0x0AAC, 0x0AAD, 0x0AAE, 0x0AAF,
- 0x0AB0, 0x0AB1, 0x0AB2, 0x0AB3, 0x0AB4, 0x0AB5, 0x0AB6, 0x0AB7,
- 0x0AB8, 0x0AB9, 0x0ABA, 0x0ABB, 0x0ABC, 0x0ABD, 0x0ABE, 0x0ABF,
- 0x0AC0, 0x0AC1, 0x0AC2, 0x0AC3, 0x0AC4, 0x0AC5, 0x0AC6, 0x0AC7,
- 0x14A0, 0x14A1, 0x14A2, 0x14A3, 0x14A4, 0x14A5, 0x14A6, 0x14A7,
- 0x14A8, 0x14A9, 0x14AA, 0x14AB, 0x14AC, 0x14AD, 0x14AE, 0x14AF,
- 0x14B0, 0x14B1, 0x14B2, 0x14B3, 0x14B4, 0x14B5, 0x14B6, 0x14B7,
- 0x14B8, 0x14B9, 0x14BA, 0x14BB, 0x14BC, 0x14BD, 0x14BE, 0x14BF,
- 0x14C0, 0x14C1, 0x14C2, 0x14C3, 0x14C4, 0x14C5, 0x14C6, 0x14C7,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x01E0, 0x01E1, 0x01E2, 0x01E3, 0x01E4, 0x01E5, 0x01E6, 0x01E7,
- 0x01E8, 0x01E9, 0x01EA, 0x01EB, 0x01EC, 0x01ED, 0x01EE, 0x01EF,
- 0x01F0, 0x01F1, 0x01F2, 0x01F3, 0x01F4, 0x01F5, 0x01F6, 0x01F7,
- 0x01F8, 0x01F9, 0x01FA, 0x01FB, 0x01FC, 0x01FD, 0x01FE, 0x01FF,
- 0x0200, 0x0201, 0x0202, 0x0203, 0x0204, 0x0205, 0x0206, 0x0207,
- 0x0BE0, 0x0BE1, 0x0BE2, 0x0BE3, 0x0BE4, 0x0BE5, 0x0BE6, 0x0BE7,
- 0x0BE8, 0x0BE9, 0x0BEA, 0x0BEB, 0x0BEC, 0x0BED, 0x0BEE, 0x0BEF,
- 0x0BF0, 0x0BF1, 0x0BF2, 0x0BF3, 0x0BF4, 0x0BF5, 0x0BF6, 0x0BF7,
- 0x0BF8, 0x0BF9, 0x0BFA, 0x0BFB, 0x0BFC, 0x0BFD, 0x0BFE, 0x0BFF,
- 0x0C00, 0x0C01, 0x0C02, 0x0C03, 0x0C04, 0x0C05, 0x0C06, 0x0C07,
- 0x15E0, 0x15E1, 0x15E2, 0x15E3, 0x15E4, 0x15E5, 0x15E6, 0x15E7,
- 0x15E8, 0x15E9, 0x15EA, 0x15EB, 0x15EC, 0x15ED, 0x15EE, 0x15EF,
- 0x15F0, 0x15F1, 0x15F2, 0x15F3, 0x15F4, 0x15F5, 0x15F6, 0x15F7,
- 0x15F8, 0x15F9, 0x15FA, 0x15FB, 0x15FC, 0x15FD, 0x15FE, 0x15FF,
- 0x1600, 0x1601, 0x1602, 0x1603, 0x1604, 0x1605, 0x1606, 0x1607,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0320, 0x0321, 0x0322, 0x0323, 0x0324, 0x0325, 0x0326, 0x0327,
- 0x0328, 0x0329, 0x032A, 0x032B, 0x032C, 0x032D, 0x032E, 0x032F,
- 0x0330, 0x0331, 0x0332, 0x0333, 0x0334, 0x0335, 0x0336, 0x0337,
- 0x0338, 0x0339, 0x033A, 0x033B, 0x033C, 0x033D, 0x033E, 0x033F,
- 0x0340, 0x0341, 0x0342, 0x0343, 0x0344, 0x0345, 0x0346, 0x0347,
- 0x0D20, 0x0D21, 0x0D22, 0x0D23, 0x0D24, 0x0D25, 0x0D26, 0x0D27,
- 0x0D28, 0x0D29, 0x0D2A, 0x0D2B, 0x0D2C, 0x0D2D, 0x0D2E, 0x0D2F,
- 0x0D30, 0x0D31, 0x0D32, 0x0D33, 0x0D34, 0x0D35, 0x0D36, 0x0D37,
- 0x0D38, 0x0D39, 0x0D3A, 0x0D3B, 0x0D3C, 0x0D3D, 0x0D3E, 0x0D3F,
- 0x0D40, 0x0D41, 0x0D42, 0x0D43, 0x0D44, 0x0D45, 0x0D46, 0x0D47,
- 0x1720, 0x1721, 0x1722, 0x1723, 0x1724, 0x1725, 0x1726, 0x1727,
- 0x1728, 0x1729, 0x172A, 0x172B, 0x172C, 0x172D, 0x172E, 0x172F,
- 0x1730, 0x1731, 0x1732, 0x1733, 0x1734, 0x1735, 0x1736, 0x1737,
- 0x1738, 0x1739, 0x173A, 0x173B, 0x173C, 0x173D, 0x173E, 0x173F,
- 0x1740, 0x1741, 0x1742, 0x1743, 0x1744, 0x1745, 0x1746, 0x1747,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0460, 0x0461, 0x0462, 0x0463, 0x0464, 0x0465, 0x0466, 0x0467,
- 0x0468, 0x0469, 0x046A, 0x046B, 0x046C, 0x046D, 0x046E, 0x046F,
- 0x0470, 0x0471, 0x0472, 0x0473, 0x0474, 0x0475, 0x0476, 0x0477,
- 0x0478, 0x0479, 0x047A, 0x047B, 0x047C, 0x047D, 0x047E, 0x047F,
- 0x0480, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x0487,
- 0x0E60, 0x0E61, 0x0E62, 0x0E63, 0x0E64, 0x0E65, 0x0E66, 0x0E67,
- 0x0E68, 0x0E69, 0x0E6A, 0x0E6B, 0x0E6C, 0x0E6D, 0x0E6E, 0x0E6F,
- 0x0E70, 0x0E71, 0x0E72, 0x0E73, 0x0E74, 0x0E75, 0x0E76, 0x0E77,
- 0x0E78, 0x0E79, 0x0E7A, 0x0E7B, 0x0E7C, 0x0E7D, 0x0E7E, 0x0E7F,
- 0x0E80, 0x0E81, 0x0E82, 0x0E83, 0x0E84, 0x0E85, 0x0E86, 0x0E87,
- 0x1860, 0x1861, 0x1862, 0x1863, 0x1864, 0x1865, 0x1866, 0x1867,
- 0x1868, 0x1869, 0x186A, 0x186B, 0x186C, 0x186D, 0x186E, 0x186F,
- 0x1870, 0x1871, 0x1872, 0x1873, 0x1874, 0x1875, 0x1876, 0x1877,
- 0x1878, 0x1879, 0x187A, 0x187B, 0x187C, 0x187D, 0x187E, 0x187F,
- 0x1880, 0x1881, 0x1882, 0x1883, 0x1884, 0x1885, 0x1886, 0x1887,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x05A0, 0x05A1, 0x05A2, 0x05A3, 0x05A4, 0x05A5, 0x05A6, 0x05A7,
- 0x05A8, 0x05A9, 0x05AA, 0x05AB, 0x05AC, 0x05AD, 0x05AE, 0x05AF,
- 0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7,
- 0x05B8, 0x05B9, 0x05BA, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF,
- 0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05C4, 0x05C5, 0x05C6, 0x05C7,
- 0x0FA0, 0x0FA1, 0x0FA2, 0x0FA3, 0x0FA4, 0x0FA5, 0x0FA6, 0x0FA7,
- 0x0FA8, 0x0FA9, 0x0FAA, 0x0FAB, 0x0FAC, 0x0FAD, 0x0FAE, 0x0FAF,
- 0x0FB0, 0x0FB1, 0x0FB2, 0x0FB3, 0x0FB4, 0x0FB5, 0x0FB6, 0x0FB7,
- 0x0FB8, 0x0FB9, 0x0FBA, 0x0FBB, 0x0FBC, 0x0FBD, 0x0FBE, 0x0FBF,
- 0x0FC0, 0x0FC1, 0x0FC2, 0x0FC3, 0x0FC4, 0x0FC5, 0x0FC6, 0x0FC7,
- 0x19A0, 0x19A1, 0x19A2, 0x19A3, 0x19A4, 0x19A5, 0x19A6, 0x19A7,
- 0x19A8, 0x19A9, 0x19AA, 0x19AB, 0x19AC, 0x19AD, 0x19AE, 0x19AF,
- 0x19B0, 0x19B1, 0x19B2, 0x19B3, 0x19B4, 0x19B5, 0x19B6, 0x19B7,
- 0x19B8, 0x19B9, 0x19BA, 0x19BB, 0x19BC, 0x19BD, 0x19BE, 0x19BF,
- 0x19C0, 0x19C1, 0x19C2, 0x19C3, 0x19C4, 0x19C5, 0x19C6, 0x19C7,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x06E0, 0x06E1, 0x06E2, 0x06E3, 0x06E4, 0x06E5, 0x06E6, 0x06E7,
- 0x06E8, 0x06E9, 0x06EA, 0x06EB, 0x06EC, 0x06ED, 0x06EE, 0x06EF,
- 0x06F0, 0x06F1, 0x06F2, 0x06F3, 0x06F4, 0x06F5, 0x06F6, 0x06F7,
- 0x06F8, 0x06F9, 0x06FA, 0x06FB, 0x06FC, 0x06FD, 0x06FE, 0x06FF,
- 0x0700, 0x0701, 0x0702, 0x0703, 0x0704, 0x0705, 0x0706, 0x0707,
- 0x10E0, 0x10E1, 0x10E2, 0x10E3, 0x10E4, 0x10E5, 0x10E6, 0x10E7,
- 0x10E8, 0x10E9, 0x10EA, 0x10EB, 0x10EC, 0x10ED, 0x10EE, 0x10EF,
- 0x10F0, 0x10F1, 0x10F2, 0x10F3, 0x10F4, 0x10F5, 0x10F6, 0x10F7,
- 0x10F8, 0x10F9, 0x10FA, 0x10FB, 0x10FC, 0x10FD, 0x10FE, 0x10FF,
- 0x1100, 0x1101, 0x1102, 0x1103, 0x1104, 0x1105, 0x1106, 0x1107,
- 0x1AE0, 0x1AE1, 0x1AE2, 0x1AE3, 0x1AE4, 0x1AE5, 0x1AE6, 0x1AE7,
- 0x1AE8, 0x1AE9, 0x1AEA, 0x1AEB, 0x1AEC, 0x1AED, 0x1AEE, 0x1AEF,
- 0x1AF0, 0x1AF1, 0x1AF2, 0x1AF3, 0x1AF4, 0x1AF5, 0x1AF6, 0x1AF7,
- 0x1AF8, 0x1AF9, 0x1AFA, 0x1AFB, 0x1AFC, 0x1AFD, 0x1AFE, 0x1AFF,
- 0x1B00, 0x1B01, 0x1B02, 0x1B03, 0x1B04, 0x1B05, 0x1B06, 0x1B07,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0820, 0x0821, 0x0822, 0x0823, 0x0824, 0x0825, 0x0826, 0x0827,
- 0x0828, 0x0829, 0x082A, 0x082B, 0x082C, 0x082D, 0x082E, 0x082F,
- 0x0830, 0x0831, 0x0832, 0x0833, 0x0834, 0x0835, 0x0836, 0x0837,
- 0x0838, 0x0839, 0x083A, 0x083B, 0x083C, 0x083D, 0x083E, 0x083F,
- 0x0840, 0x0841, 0x0842, 0x0843, 0x0844, 0x0845, 0x0846, 0x0847,
- 0x1220, 0x1221, 0x1222, 0x1223, 0x1224, 0x1225, 0x1226, 0x1227,
- 0x1228, 0x1229, 0x122A, 0x122B, 0x122C, 0x122D, 0x122E, 0x122F,
- 0x1230, 0x1231, 0x1232, 0x1233, 0x1234, 0x1235, 0x1236, 0x1237,
- 0x1238, 0x1239, 0x123A, 0x123B, 0x123C, 0x123D, 0x123E, 0x123F,
- 0x1240, 0x1241, 0x1242, 0x1243, 0x1244, 0x1245, 0x1246, 0x1247,
- 0x1C20, 0x1C21, 0x1C22, 0x1C23, 0x1C24, 0x1C25, 0x1C26, 0x1C27,
- 0x1C28, 0x1C29, 0x1C2A, 0x1C2B, 0x1C2C, 0x1C2D, 0x1C2E, 0x1C2F,
- 0x1C30, 0x1C31, 0x1C32, 0x1C33, 0x1C34, 0x1C35, 0x1C36, 0x1C37,
- 0x1C38, 0x1C39, 0x1C3A, 0x1C3B, 0x1C3C, 0x1C3D, 0x1C3E, 0x1C3F,
- 0x1C40, 0x1C41, 0x1C42, 0x1C43, 0x1C44, 0x1C45, 0x1C46, 0x1C47,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0960, 0x0961, 0x0962, 0x0963, 0x0964, 0x0965, 0x0966, 0x0967,
- 0x0968, 0x0969, 0x096A, 0x096B, 0x096C, 0x096D, 0x096E, 0x096F,
- 0x0970, 0x0971, 0x0972, 0x0973, 0x0974, 0x0975, 0x0976, 0x0977,
- 0x0978, 0x0979, 0x097A, 0x097B, 0x097C, 0x097D, 0x097E, 0x097F,
- 0x0980, 0x0981, 0x0982, 0x0983, 0x0984, 0x0985, 0x0986, 0x0987,
- 0x1360, 0x1361, 0x1362, 0x1363, 0x1364, 0x1365, 0x1366, 0x1367,
- 0x1368, 0x1369, 0x136A, 0x136B, 0x136C, 0x136D, 0x136E, 0x136F,
- 0x1370, 0x1371, 0x1372, 0x1373, 0x1374, 0x1375, 0x1376, 0x1377,
- 0x1378, 0x1379, 0x137A, 0x137B, 0x137C, 0x137D, 0x137E, 0x137F,
- 0x1380, 0x1381, 0x1382, 0x1383, 0x1384, 0x1385, 0x1386, 0x1387,
- 0x1D60, 0x1D61, 0x1D62, 0x1D63, 0x1D64, 0x1D65, 0x1D66, 0x1D67,
- 0x1D68, 0x1D69, 0x1D6A, 0x1D6B, 0x1D6C, 0x1D6D, 0x1D6E, 0x1D6F,
- 0x1D70, 0x1D71, 0x1D72, 0x1D73, 0x1D74, 0x1D75, 0x1D76, 0x1D77,
- 0x1D78, 0x1D79, 0x1D7A, 0x1D7B, 0x1D7C, 0x1D7D, 0x1D7E, 0x1D7F,
- 0x1D80, 0x1D81, 0x1D82, 0x1D83, 0x1D84, 0x1D85, 0x1D86, 0x1D87,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
- 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
- 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
- 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
- 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
- 0x0AC8, 0x0AC9, 0x0ACA, 0x0ACB, 0x0ACC, 0x0ACD, 0x0ACE, 0x0ACF,
- 0x0AD0, 0x0AD1, 0x0AD2, 0x0AD3, 0x0AD4, 0x0AD5, 0x0AD6, 0x0AD7,
- 0x0AD8, 0x0AD9, 0x0ADA, 0x0ADB, 0x0ADC, 0x0ADD, 0x0ADE, 0x0ADF,
- 0x0AE0, 0x0AE1, 0x0AE2, 0x0AE3, 0x0AE4, 0x0AE5, 0x0AE6, 0x0AE7,
- 0x0AE8, 0x0AE9, 0x0AEA, 0x0AEB, 0x0AEC, 0x0AED, 0x0AEE, 0x0AEF,
- 0x14C8, 0x14C9, 0x14CA, 0x14CB, 0x14CC, 0x14CD, 0x14CE, 0x14CF,
- 0x14D0, 0x14D1, 0x14D2, 0x14D3, 0x14D4, 0x14D5, 0x14D6, 0x14D7,
- 0x14D8, 0x14D9, 0x14DA, 0x14DB, 0x14DC, 0x14DD, 0x14DE, 0x14DF,
- 0x14E0, 0x14E1, 0x14E2, 0x14E3, 0x14E4, 0x14E5, 0x14E6, 0x14E7,
- 0x14E8, 0x14E9, 0x14EA, 0x14EB, 0x14EC, 0x14ED, 0x14EE, 0x14EF,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0208, 0x0209, 0x020A, 0x020B, 0x020C, 0x020D, 0x020E, 0x020F,
- 0x0210, 0x0211, 0x0212, 0x0213, 0x0214, 0x0215, 0x0216, 0x0217,
- 0x0218, 0x0219, 0x021A, 0x021B, 0x021C, 0x021D, 0x021E, 0x021F,
- 0x0220, 0x0221, 0x0222, 0x0223, 0x0224, 0x0225, 0x0226, 0x0227,
- 0x0228, 0x0229, 0x022A, 0x022B, 0x022C, 0x022D, 0x022E, 0x022F,
- 0x0C08, 0x0C09, 0x0C0A, 0x0C0B, 0x0C0C, 0x0C0D, 0x0C0E, 0x0C0F,
- 0x0C10, 0x0C11, 0x0C12, 0x0C13, 0x0C14, 0x0C15, 0x0C16, 0x0C17,
- 0x0C18, 0x0C19, 0x0C1A, 0x0C1B, 0x0C1C, 0x0C1D, 0x0C1E, 0x0C1F,
- 0x0C20, 0x0C21, 0x0C22, 0x0C23, 0x0C24, 0x0C25, 0x0C26, 0x0C27,
- 0x0C28, 0x0C29, 0x0C2A, 0x0C2B, 0x0C2C, 0x0C2D, 0x0C2E, 0x0C2F,
- 0x1608, 0x1609, 0x160A, 0x160B, 0x160C, 0x160D, 0x160E, 0x160F,
- 0x1610, 0x1611, 0x1612, 0x1613, 0x1614, 0x1615, 0x1616, 0x1617,
- 0x1618, 0x1619, 0x161A, 0x161B, 0x161C, 0x161D, 0x161E, 0x161F,
- 0x1620, 0x1621, 0x1622, 0x1623, 0x1624, 0x1625, 0x1626, 0x1627,
- 0x1628, 0x1629, 0x162A, 0x162B, 0x162C, 0x162D, 0x162E, 0x162F,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0348, 0x0349, 0x034A, 0x034B, 0x034C, 0x034D, 0x034E, 0x034F,
- 0x0350, 0x0351, 0x0352, 0x0353, 0x0354, 0x0355, 0x0356, 0x0357,
- 0x0358, 0x0359, 0x035A, 0x035B, 0x035C, 0x035D, 0x035E, 0x035F,
- 0x0360, 0x0361, 0x0362, 0x0363, 0x0364, 0x0365, 0x0366, 0x0367,
- 0x0368, 0x0369, 0x036A, 0x036B, 0x036C, 0x036D, 0x036E, 0x036F,
- 0x0D48, 0x0D49, 0x0D4A, 0x0D4B, 0x0D4C, 0x0D4D, 0x0D4E, 0x0D4F,
- 0x0D50, 0x0D51, 0x0D52, 0x0D53, 0x0D54, 0x0D55, 0x0D56, 0x0D57,
- 0x0D58, 0x0D59, 0x0D5A, 0x0D5B, 0x0D5C, 0x0D5D, 0x0D5E, 0x0D5F,
- 0x0D60, 0x0D61, 0x0D62, 0x0D63, 0x0D64, 0x0D65, 0x0D66, 0x0D67,
- 0x0D68, 0x0D69, 0x0D6A, 0x0D6B, 0x0D6C, 0x0D6D, 0x0D6E, 0x0D6F,
- 0x1748, 0x1749, 0x174A, 0x174B, 0x174C, 0x174D, 0x174E, 0x174F,
- 0x1750, 0x1751, 0x1752, 0x1753, 0x1754, 0x1755, 0x1756, 0x1757,
- 0x1758, 0x1759, 0x175A, 0x175B, 0x175C, 0x175D, 0x175E, 0x175F,
- 0x1760, 0x1761, 0x1762, 0x1763, 0x1764, 0x1765, 0x1766, 0x1767,
- 0x1768, 0x1769, 0x176A, 0x176B, 0x176C, 0x176D, 0x176E, 0x176F,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0488, 0x0489, 0x048A, 0x048B, 0x048C, 0x048D, 0x048E, 0x048F,
- 0x0490, 0x0491, 0x0492, 0x0493, 0x0494, 0x0495, 0x0496, 0x0497,
- 0x0498, 0x0499, 0x049A, 0x049B, 0x049C, 0x049D, 0x049E, 0x049F,
- 0x04A0, 0x04A1, 0x04A2, 0x04A3, 0x04A4, 0x04A5, 0x04A6, 0x04A7,
- 0x04A8, 0x04A9, 0x04AA, 0x04AB, 0x04AC, 0x04AD, 0x04AE, 0x04AF,
- 0x0E88, 0x0E89, 0x0E8A, 0x0E8B, 0x0E8C, 0x0E8D, 0x0E8E, 0x0E8F,
- 0x0E90, 0x0E91, 0x0E92, 0x0E93, 0x0E94, 0x0E95, 0x0E96, 0x0E97,
- 0x0E98, 0x0E99, 0x0E9A, 0x0E9B, 0x0E9C, 0x0E9D, 0x0E9E, 0x0E9F,
- 0x0EA0, 0x0EA1, 0x0EA2, 0x0EA3, 0x0EA4, 0x0EA5, 0x0EA6, 0x0EA7,
- 0x0EA8, 0x0EA9, 0x0EAA, 0x0EAB, 0x0EAC, 0x0EAD, 0x0EAE, 0x0EAF,
- 0x1888, 0x1889, 0x188A, 0x188B, 0x188C, 0x188D, 0x188E, 0x188F,
- 0x1890, 0x1891, 0x1892, 0x1893, 0x1894, 0x1895, 0x1896, 0x1897,
- 0x1898, 0x1899, 0x189A, 0x189B, 0x189C, 0x189D, 0x189E, 0x189F,
- 0x18A0, 0x18A1, 0x18A2, 0x18A3, 0x18A4, 0x18A5, 0x18A6, 0x18A7,
- 0x18A8, 0x18A9, 0x18AA, 0x18AB, 0x18AC, 0x18AD, 0x18AE, 0x18AF,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x05C8, 0x05C9, 0x05CA, 0x05CB, 0x05CC, 0x05CD, 0x05CE, 0x05CF,
- 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
- 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
- 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
- 0x05E8, 0x05E9, 0x05EA, 0x05EB, 0x05EC, 0x05ED, 0x05EE, 0x05EF,
- 0x0FC8, 0x0FC9, 0x0FCA, 0x0FCB, 0x0FCC, 0x0FCD, 0x0FCE, 0x0FCF,
- 0x0FD0, 0x0FD1, 0x0FD2, 0x0FD3, 0x0FD4, 0x0FD5, 0x0FD6, 0x0FD7,
- 0x0FD8, 0x0FD9, 0x0FDA, 0x0FDB, 0x0FDC, 0x0FDD, 0x0FDE, 0x0FDF,
- 0x0FE0, 0x0FE1, 0x0FE2, 0x0FE3, 0x0FE4, 0x0FE5, 0x0FE6, 0x0FE7,
- 0x0FE8, 0x0FE9, 0x0FEA, 0x0FEB, 0x0FEC, 0x0FED, 0x0FEE, 0x0FEF,
- 0x19C8, 0x19C9, 0x19CA, 0x19CB, 0x19CC, 0x19CD, 0x19CE, 0x19CF,
- 0x19D0, 0x19D1, 0x19D2, 0x19D3, 0x19D4, 0x19D5, 0x19D6, 0x19D7,
- 0x19D8, 0x19D9, 0x19DA, 0x19DB, 0x19DC, 0x19DD, 0x19DE, 0x19DF,
- 0x19E0, 0x19E1, 0x19E2, 0x19E3, 0x19E4, 0x19E5, 0x19E6, 0x19E7,
- 0x19E8, 0x19E9, 0x19EA, 0x19EB, 0x19EC, 0x19ED, 0x19EE, 0x19EF,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0708, 0x0709, 0x070A, 0x070B, 0x070C, 0x070D, 0x070E, 0x070F,
- 0x0710, 0x0711, 0x0712, 0x0713, 0x0714, 0x0715, 0x0716, 0x0717,
- 0x0718, 0x0719, 0x071A, 0x071B, 0x071C, 0x071D, 0x071E, 0x071F,
- 0x0720, 0x0721, 0x0722, 0x0723, 0x0724, 0x0725, 0x0726, 0x0727,
- 0x0728, 0x0729, 0x072A, 0x072B, 0x072C, 0x072D, 0x072E, 0x072F,
- 0x1108, 0x1109, 0x110A, 0x110B, 0x110C, 0x110D, 0x110E, 0x110F,
- 0x1110, 0x1111, 0x1112, 0x1113, 0x1114, 0x1115, 0x1116, 0x1117,
- 0x1118, 0x1119, 0x111A, 0x111B, 0x111C, 0x111D, 0x111E, 0x111F,
- 0x1120, 0x1121, 0x1122, 0x1123, 0x1124, 0x1125, 0x1126, 0x1127,
- 0x1128, 0x1129, 0x112A, 0x112B, 0x112C, 0x112D, 0x112E, 0x112F,
- 0x1B08, 0x1B09, 0x1B0A, 0x1B0B, 0x1B0C, 0x1B0D, 0x1B0E, 0x1B0F,
- 0x1B10, 0x1B11, 0x1B12, 0x1B13, 0x1B14, 0x1B15, 0x1B16, 0x1B17,
- 0x1B18, 0x1B19, 0x1B1A, 0x1B1B, 0x1B1C, 0x1B1D, 0x1B1E, 0x1B1F,
- 0x1B20, 0x1B21, 0x1B22, 0x1B23, 0x1B24, 0x1B25, 0x1B26, 0x1B27,
- 0x1B28, 0x1B29, 0x1B2A, 0x1B2B, 0x1B2C, 0x1B2D, 0x1B2E, 0x1B2F,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0848, 0x0849, 0x084A, 0x084B, 0x084C, 0x084D, 0x084E, 0x084F,
- 0x0850, 0x0851, 0x0852, 0x0853, 0x0854, 0x0855, 0x0856, 0x0857,
- 0x0858, 0x0859, 0x085A, 0x085B, 0x085C, 0x085D, 0x085E, 0x085F,
- 0x0860, 0x0861, 0x0862, 0x0863, 0x0864, 0x0865, 0x0866, 0x0867,
- 0x0868, 0x0869, 0x086A, 0x086B, 0x086C, 0x086D, 0x086E, 0x086F,
- 0x1248, 0x1249, 0x124A, 0x124B, 0x124C, 0x124D, 0x124E, 0x124F,
- 0x1250, 0x1251, 0x1252, 0x1253, 0x1254, 0x1255, 0x1256, 0x1257,
- 0x1258, 0x1259, 0x125A, 0x125B, 0x125C, 0x125D, 0x125E, 0x125F,
- 0x1260, 0x1261, 0x1262, 0x1263, 0x1264, 0x1265, 0x1266, 0x1267,
- 0x1268, 0x1269, 0x126A, 0x126B, 0x126C, 0x126D, 0x126E, 0x126F,
- 0x1C48, 0x1C49, 0x1C4A, 0x1C4B, 0x1C4C, 0x1C4D, 0x1C4E, 0x1C4F,
- 0x1C50, 0x1C51, 0x1C52, 0x1C53, 0x1C54, 0x1C55, 0x1C56, 0x1C57,
- 0x1C58, 0x1C59, 0x1C5A, 0x1C5B, 0x1C5C, 0x1C5D, 0x1C5E, 0x1C5F,
- 0x1C60, 0x1C61, 0x1C62, 0x1C63, 0x1C64, 0x1C65, 0x1C66, 0x1C67,
- 0x1C68, 0x1C69, 0x1C6A, 0x1C6B, 0x1C6C, 0x1C6D, 0x1C6E, 0x1C6F,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0988, 0x0989, 0x098A, 0x098B, 0x098C, 0x098D, 0x098E, 0x098F,
- 0x0990, 0x0991, 0x0992, 0x0993, 0x0994, 0x0995, 0x0996, 0x0997,
- 0x0998, 0x0999, 0x099A, 0x099B, 0x099C, 0x099D, 0x099E, 0x099F,
- 0x09A0, 0x09A1, 0x09A2, 0x09A3, 0x09A4, 0x09A5, 0x09A6, 0x09A7,
- 0x09A8, 0x09A9, 0x09AA, 0x09AB, 0x09AC, 0x09AD, 0x09AE, 0x09AF,
- 0x1388, 0x1389, 0x138A, 0x138B, 0x138C, 0x138D, 0x138E, 0x138F,
- 0x1390, 0x1391, 0x1392, 0x1393, 0x1394, 0x1395, 0x1396, 0x1397,
- 0x1398, 0x1399, 0x139A, 0x139B, 0x139C, 0x139D, 0x139E, 0x139F,
- 0x13A0, 0x13A1, 0x13A2, 0x13A3, 0x13A4, 0x13A5, 0x13A6, 0x13A7,
- 0x13A8, 0x13A9, 0x13AA, 0x13AB, 0x13AC, 0x13AD, 0x13AE, 0x13AF,
- 0x1D88, 0x1D89, 0x1D8A, 0x1D8B, 0x1D8C, 0x1D8D, 0x1D8E, 0x1D8F,
- 0x1D90, 0x1D91, 0x1D92, 0x1D93, 0x1D94, 0x1D95, 0x1D96, 0x1D97,
- 0x1D98, 0x1D99, 0x1D9A, 0x1D9B, 0x1D9C, 0x1D9D, 0x1D9E, 0x1D9F,
- 0x1DA0, 0x1DA1, 0x1DA2, 0x1DA3, 0x1DA4, 0x1DA5, 0x1DA6, 0x1DA7,
- 0x1DA8, 0x1DA9, 0x1DAA, 0x1DAB, 0x1DAC, 0x1DAD, 0x1DAE, 0x1DAF,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
- 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF,
- 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, 0x0107,
- 0x0108, 0x0109, 0x010A, 0x010B, 0x010C, 0x010D, 0x010E, 0x010F,
- 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116, 0x0117,
- 0x0AF0, 0x0AF1, 0x0AF2, 0x0AF3, 0x0AF4, 0x0AF5, 0x0AF6, 0x0AF7,
- 0x0AF8, 0x0AF9, 0x0AFA, 0x0AFB, 0x0AFC, 0x0AFD, 0x0AFE, 0x0AFF,
- 0x0B00, 0x0B01, 0x0B02, 0x0B03, 0x0B04, 0x0B05, 0x0B06, 0x0B07,
- 0x0B08, 0x0B09, 0x0B0A, 0x0B0B, 0x0B0C, 0x0B0D, 0x0B0E, 0x0B0F,
- 0x0B10, 0x0B11, 0x0B12, 0x0B13, 0x0B14, 0x0B15, 0x0B16, 0x0B17,
- 0x14F0, 0x14F1, 0x14F2, 0x14F3, 0x14F4, 0x14F5, 0x14F6, 0x14F7,
- 0x14F8, 0x14F9, 0x14FA, 0x14FB, 0x14FC, 0x14FD, 0x14FE, 0x14FF,
- 0x1500, 0x1501, 0x1502, 0x1503, 0x1504, 0x1505, 0x1506, 0x1507,
- 0x1508, 0x1509, 0x150A, 0x150B, 0x150C, 0x150D, 0x150E, 0x150F,
- 0x1510, 0x1511, 0x1512, 0x1513, 0x1514, 0x1515, 0x1516, 0x1517,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0230, 0x0231, 0x0232, 0x0233, 0x0234, 0x0235, 0x0236, 0x0237,
- 0x0238, 0x0239, 0x023A, 0x023B, 0x023C, 0x023D, 0x023E, 0x023F,
- 0x0240, 0x0241, 0x0242, 0x0243, 0x0244, 0x0245, 0x0246, 0x0247,
- 0x0248, 0x0249, 0x024A, 0x024B, 0x024C, 0x024D, 0x024E, 0x024F,
- 0x0250, 0x0251, 0x0252, 0x0253, 0x0254, 0x0255, 0x0256, 0x0257,
- 0x0C30, 0x0C31, 0x0C32, 0x0C33, 0x0C34, 0x0C35, 0x0C36, 0x0C37,
- 0x0C38, 0x0C39, 0x0C3A, 0x0C3B, 0x0C3C, 0x0C3D, 0x0C3E, 0x0C3F,
- 0x0C40, 0x0C41, 0x0C42, 0x0C43, 0x0C44, 0x0C45, 0x0C46, 0x0C47,
- 0x0C48, 0x0C49, 0x0C4A, 0x0C4B, 0x0C4C, 0x0C4D, 0x0C4E, 0x0C4F,
- 0x0C50, 0x0C51, 0x0C52, 0x0C53, 0x0C54, 0x0C55, 0x0C56, 0x0C57,
- 0x1630, 0x1631, 0x1632, 0x1633, 0x1634, 0x1635, 0x1636, 0x1637,
- 0x1638, 0x1639, 0x163A, 0x163B, 0x163C, 0x163D, 0x163E, 0x163F,
- 0x1640, 0x1641, 0x1642, 0x1643, 0x1644, 0x1645, 0x1646, 0x1647,
- 0x1648, 0x1649, 0x164A, 0x164B, 0x164C, 0x164D, 0x164E, 0x164F,
- 0x1650, 0x1651, 0x1652, 0x1653, 0x1654, 0x1655, 0x1656, 0x1657,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0370, 0x0371, 0x0372, 0x0373, 0x0374, 0x0375, 0x0376, 0x0377,
- 0x0378, 0x0379, 0x037A, 0x037B, 0x037C, 0x037D, 0x037E, 0x037F,
- 0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0386, 0x0387,
- 0x0388, 0x0389, 0x038A, 0x038B, 0x038C, 0x038D, 0x038E, 0x038F,
- 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
- 0x0D70, 0x0D71, 0x0D72, 0x0D73, 0x0D74, 0x0D75, 0x0D76, 0x0D77,
- 0x0D78, 0x0D79, 0x0D7A, 0x0D7B, 0x0D7C, 0x0D7D, 0x0D7E, 0x0D7F,
- 0x0D80, 0x0D81, 0x0D82, 0x0D83, 0x0D84, 0x0D85, 0x0D86, 0x0D87,
- 0x0D88, 0x0D89, 0x0D8A, 0x0D8B, 0x0D8C, 0x0D8D, 0x0D8E, 0x0D8F,
- 0x0D90, 0x0D91, 0x0D92, 0x0D93, 0x0D94, 0x0D95, 0x0D96, 0x0D97,
- 0x1770, 0x1771, 0x1772, 0x1773, 0x1774, 0x1775, 0x1776, 0x1777,
- 0x1778, 0x1779, 0x177A, 0x177B, 0x177C, 0x177D, 0x177E, 0x177F,
- 0x1780, 0x1781, 0x1782, 0x1783, 0x1784, 0x1785, 0x1786, 0x1787,
- 0x1788, 0x1789, 0x178A, 0x178B, 0x178C, 0x178D, 0x178E, 0x178F,
- 0x1790, 0x1791, 0x1792, 0x1793, 0x1794, 0x1795, 0x1796, 0x1797,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x04B0, 0x04B1, 0x04B2, 0x04B3, 0x04B4, 0x04B5, 0x04B6, 0x04B7,
- 0x04B8, 0x04B9, 0x04BA, 0x04BB, 0x04BC, 0x04BD, 0x04BE, 0x04BF,
- 0x04C0, 0x04C1, 0x04C2, 0x04C3, 0x04C4, 0x04C5, 0x04C6, 0x04C7,
- 0x04C8, 0x04C9, 0x04CA, 0x04CB, 0x04CC, 0x04CD, 0x04CE, 0x04CF,
- 0x04D0, 0x04D1, 0x04D2, 0x04D3, 0x04D4, 0x04D5, 0x04D6, 0x04D7,
- 0x0EB0, 0x0EB1, 0x0EB2, 0x0EB3, 0x0EB4, 0x0EB5, 0x0EB6, 0x0EB7,
- 0x0EB8, 0x0EB9, 0x0EBA, 0x0EBB, 0x0EBC, 0x0EBD, 0x0EBE, 0x0EBF,
- 0x0EC0, 0x0EC1, 0x0EC2, 0x0EC3, 0x0EC4, 0x0EC5, 0x0EC6, 0x0EC7,
- 0x0EC8, 0x0EC9, 0x0ECA, 0x0ECB, 0x0ECC, 0x0ECD, 0x0ECE, 0x0ECF,
- 0x0ED0, 0x0ED1, 0x0ED2, 0x0ED3, 0x0ED4, 0x0ED5, 0x0ED6, 0x0ED7,
- 0x18B0, 0x18B1, 0x18B2, 0x18B3, 0x18B4, 0x18B5, 0x18B6, 0x18B7,
- 0x18B8, 0x18B9, 0x18BA, 0x18BB, 0x18BC, 0x18BD, 0x18BE, 0x18BF,
- 0x18C0, 0x18C1, 0x18C2, 0x18C3, 0x18C4, 0x18C5, 0x18C6, 0x18C7,
- 0x18C8, 0x18C9, 0x18CA, 0x18CB, 0x18CC, 0x18CD, 0x18CE, 0x18CF,
- 0x18D0, 0x18D1, 0x18D2, 0x18D3, 0x18D4, 0x18D5, 0x18D6, 0x18D7,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x05F0, 0x05F1, 0x05F2, 0x05F3, 0x05F4, 0x05F5, 0x05F6, 0x05F7,
- 0x05F8, 0x05F9, 0x05FA, 0x05FB, 0x05FC, 0x05FD, 0x05FE, 0x05FF,
- 0x0600, 0x0601, 0x0602, 0x0603, 0x0604, 0x0605, 0x0606, 0x0607,
- 0x0608, 0x0609, 0x060A, 0x060B, 0x060C, 0x060D, 0x060E, 0x060F,
- 0x0610, 0x0611, 0x0612, 0x0613, 0x0614, 0x0615, 0x0616, 0x0617,
- 0x0FF0, 0x0FF1, 0x0FF2, 0x0FF3, 0x0FF4, 0x0FF5, 0x0FF6, 0x0FF7,
- 0x0FF8, 0x0FF9, 0x0FFA, 0x0FFB, 0x0FFC, 0x0FFD, 0x0FFE, 0x0FFF,
- 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 0x1007,
- 0x1008, 0x1009, 0x100A, 0x100B, 0x100C, 0x100D, 0x100E, 0x100F,
- 0x1010, 0x1011, 0x1012, 0x1013, 0x1014, 0x1015, 0x1016, 0x1017,
- 0x19F0, 0x19F1, 0x19F2, 0x19F3, 0x19F4, 0x19F5, 0x19F6, 0x19F7,
- 0x19F8, 0x19F9, 0x19FA, 0x19FB, 0x19FC, 0x19FD, 0x19FE, 0x19FF,
- 0x1A00, 0x1A01, 0x1A02, 0x1A03, 0x1A04, 0x1A05, 0x1A06, 0x1A07,
- 0x1A08, 0x1A09, 0x1A0A, 0x1A0B, 0x1A0C, 0x1A0D, 0x1A0E, 0x1A0F,
- 0x1A10, 0x1A11, 0x1A12, 0x1A13, 0x1A14, 0x1A15, 0x1A16, 0x1A17,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0730, 0x0731, 0x0732, 0x0733, 0x0734, 0x0735, 0x0736, 0x0737,
- 0x0738, 0x0739, 0x073A, 0x073B, 0x073C, 0x073D, 0x073E, 0x073F,
- 0x0740, 0x0741, 0x0742, 0x0743, 0x0744, 0x0745, 0x0746, 0x0747,
- 0x0748, 0x0749, 0x074A, 0x074B, 0x074C, 0x074D, 0x074E, 0x074F,
- 0x0750, 0x0751, 0x0752, 0x0753, 0x0754, 0x0755, 0x0756, 0x0757,
- 0x1130, 0x1131, 0x1132, 0x1133, 0x1134, 0x1135, 0x1136, 0x1137,
- 0x1138, 0x1139, 0x113A, 0x113B, 0x113C, 0x113D, 0x113E, 0x113F,
- 0x1140, 0x1141, 0x1142, 0x1143, 0x1144, 0x1145, 0x1146, 0x1147,
- 0x1148, 0x1149, 0x114A, 0x114B, 0x114C, 0x114D, 0x114E, 0x114F,
- 0x1150, 0x1151, 0x1152, 0x1153, 0x1154, 0x1155, 0x1156, 0x1157,
- 0x1B30, 0x1B31, 0x1B32, 0x1B33, 0x1B34, 0x1B35, 0x1B36, 0x1B37,
- 0x1B38, 0x1B39, 0x1B3A, 0x1B3B, 0x1B3C, 0x1B3D, 0x1B3E, 0x1B3F,
- 0x1B40, 0x1B41, 0x1B42, 0x1B43, 0x1B44, 0x1B45, 0x1B46, 0x1B47,
- 0x1B48, 0x1B49, 0x1B4A, 0x1B4B, 0x1B4C, 0x1B4D, 0x1B4E, 0x1B4F,
- 0x1B50, 0x1B51, 0x1B52, 0x1B53, 0x1B54, 0x1B55, 0x1B56, 0x1B57,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0870, 0x0871, 0x0872, 0x0873, 0x0874, 0x0875, 0x0876, 0x0877,
- 0x0878, 0x0879, 0x087A, 0x087B, 0x087C, 0x087D, 0x087E, 0x087F,
- 0x0880, 0x0881, 0x0882, 0x0883, 0x0884, 0x0885, 0x0886, 0x0887,
- 0x0888, 0x0889, 0x088A, 0x088B, 0x088C, 0x088D, 0x088E, 0x088F,
- 0x0890, 0x0891, 0x0892, 0x0893, 0x0894, 0x0895, 0x0896, 0x0897,
- 0x1270, 0x1271, 0x1272, 0x1273, 0x1274, 0x1275, 0x1276, 0x1277,
- 0x1278, 0x1279, 0x127A, 0x127B, 0x127C, 0x127D, 0x127E, 0x127F,
- 0x1280, 0x1281, 0x1282, 0x1283, 0x1284, 0x1285, 0x1286, 0x1287,
- 0x1288, 0x1289, 0x128A, 0x128B, 0x128C, 0x128D, 0x128E, 0x128F,
- 0x1290, 0x1291, 0x1292, 0x1293, 0x1294, 0x1295, 0x1296, 0x1297,
- 0x1C70, 0x1C71, 0x1C72, 0x1C73, 0x1C74, 0x1C75, 0x1C76, 0x1C77,
- 0x1C78, 0x1C79, 0x1C7A, 0x1C7B, 0x1C7C, 0x1C7D, 0x1C7E, 0x1C7F,
- 0x1C80, 0x1C81, 0x1C82, 0x1C83, 0x1C84, 0x1C85, 0x1C86, 0x1C87,
- 0x1C88, 0x1C89, 0x1C8A, 0x1C8B, 0x1C8C, 0x1C8D, 0x1C8E, 0x1C8F,
- 0x1C90, 0x1C91, 0x1C92, 0x1C93, 0x1C94, 0x1C95, 0x1C96, 0x1C97,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x09B0, 0x09B1, 0x09B2, 0x09B3, 0x09B4, 0x09B5, 0x09B6, 0x09B7,
- 0x09B8, 0x09B9, 0x09BA, 0x09BB, 0x09BC, 0x09BD, 0x09BE, 0x09BF,
- 0x09C0, 0x09C1, 0x09C2, 0x09C3, 0x09C4, 0x09C5, 0x09C6, 0x09C7,
- 0x09C8, 0x09C9, 0x09CA, 0x09CB, 0x09CC, 0x09CD, 0x09CE, 0x09CF,
- 0x09D0, 0x09D1, 0x09D2, 0x09D3, 0x09D4, 0x09D5, 0x09D6, 0x09D7,
- 0x13B0, 0x13B1, 0x13B2, 0x13B3, 0x13B4, 0x13B5, 0x13B6, 0x13B7,
- 0x13B8, 0x13B9, 0x13BA, 0x13BB, 0x13BC, 0x13BD, 0x13BE, 0x13BF,
- 0x13C0, 0x13C1, 0x13C2, 0x13C3, 0x13C4, 0x13C5, 0x13C6, 0x13C7,
- 0x13C8, 0x13C9, 0x13CA, 0x13CB, 0x13CC, 0x13CD, 0x13CE, 0x13CF,
- 0x13D0, 0x13D1, 0x13D2, 0x13D3, 0x13D4, 0x13D5, 0x13D6, 0x13D7,
- 0x1DB0, 0x1DB1, 0x1DB2, 0x1DB3, 0x1DB4, 0x1DB5, 0x1DB6, 0x1DB7,
- 0x1DB8, 0x1DB9, 0x1DBA, 0x1DBB, 0x1DBC, 0x1DBD, 0x1DBE, 0x1DBF,
- 0x1DC0, 0x1DC1, 0x1DC2, 0x1DC3, 0x1DC4, 0x1DC5, 0x1DC6, 0x1DC7,
- 0x1DC8, 0x1DC9, 0x1DCA, 0x1DCB, 0x1DCC, 0x1DCD, 0x1DCE, 0x1DCF,
- 0x1DD0, 0x1DD1, 0x1DD2, 0x1DD3, 0x1DD4, 0x1DD5, 0x1DD6, 0x1DD7,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0118, 0x0119, 0x011A, 0x011B, 0x011C, 0x011D, 0x011E, 0x011F,
- 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126, 0x0127,
- 0x0128, 0x0129, 0x012A, 0x012B, 0x012C, 0x012D, 0x012E, 0x012F,
- 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136, 0x0137,
- 0x0138, 0x0139, 0x013A, 0x013B, 0x013C, 0x013D, 0x013E, 0x013F,
- 0x0B18, 0x0B19, 0x0B1A, 0x0B1B, 0x0B1C, 0x0B1D, 0x0B1E, 0x0B1F,
- 0x0B20, 0x0B21, 0x0B22, 0x0B23, 0x0B24, 0x0B25, 0x0B26, 0x0B27,
- 0x0B28, 0x0B29, 0x0B2A, 0x0B2B, 0x0B2C, 0x0B2D, 0x0B2E, 0x0B2F,
- 0x0B30, 0x0B31, 0x0B32, 0x0B33, 0x0B34, 0x0B35, 0x0B36, 0x0B37,
- 0x0B38, 0x0B39, 0x0B3A, 0x0B3B, 0x0B3C, 0x0B3D, 0x0B3E, 0x0B3F,
- 0x1518, 0x1519, 0x151A, 0x151B, 0x151C, 0x151D, 0x151E, 0x151F,
- 0x1520, 0x1521, 0x1522, 0x1523, 0x1524, 0x1525, 0x1526, 0x1527,
- 0x1528, 0x1529, 0x152A, 0x152B, 0x152C, 0x152D, 0x152E, 0x152F,
- 0x1530, 0x1531, 0x1532, 0x1533, 0x1534, 0x1535, 0x1536, 0x1537,
- 0x1538, 0x1539, 0x153A, 0x153B, 0x153C, 0x153D, 0x153E, 0x153F,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0258, 0x0259, 0x025A, 0x025B, 0x025C, 0x025D, 0x025E, 0x025F,
- 0x0260, 0x0261, 0x0262, 0x0263, 0x0264, 0x0265, 0x0266, 0x0267,
- 0x0268, 0x0269, 0x026A, 0x026B, 0x026C, 0x026D, 0x026E, 0x026F,
- 0x0270, 0x0271, 0x0272, 0x0273, 0x0274, 0x0275, 0x0276, 0x0277,
- 0x0278, 0x0279, 0x027A, 0x027B, 0x027C, 0x027D, 0x027E, 0x027F,
- 0x0C58, 0x0C59, 0x0C5A, 0x0C5B, 0x0C5C, 0x0C5D, 0x0C5E, 0x0C5F,
- 0x0C60, 0x0C61, 0x0C62, 0x0C63, 0x0C64, 0x0C65, 0x0C66, 0x0C67,
- 0x0C68, 0x0C69, 0x0C6A, 0x0C6B, 0x0C6C, 0x0C6D, 0x0C6E, 0x0C6F,
- 0x0C70, 0x0C71, 0x0C72, 0x0C73, 0x0C74, 0x0C75, 0x0C76, 0x0C77,
- 0x0C78, 0x0C79, 0x0C7A, 0x0C7B, 0x0C7C, 0x0C7D, 0x0C7E, 0x0C7F,
- 0x1658, 0x1659, 0x165A, 0x165B, 0x165C, 0x165D, 0x165E, 0x165F,
- 0x1660, 0x1661, 0x1662, 0x1663, 0x1664, 0x1665, 0x1666, 0x1667,
- 0x1668, 0x1669, 0x166A, 0x166B, 0x166C, 0x166D, 0x166E, 0x166F,
- 0x1670, 0x1671, 0x1672, 0x1673, 0x1674, 0x1675, 0x1676, 0x1677,
- 0x1678, 0x1679, 0x167A, 0x167B, 0x167C, 0x167D, 0x167E, 0x167F,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
- 0x03A0, 0x03A1, 0x03A2, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
- 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
- 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
- 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
- 0x0D98, 0x0D99, 0x0D9A, 0x0D9B, 0x0D9C, 0x0D9D, 0x0D9E, 0x0D9F,
- 0x0DA0, 0x0DA1, 0x0DA2, 0x0DA3, 0x0DA4, 0x0DA5, 0x0DA6, 0x0DA7,
- 0x0DA8, 0x0DA9, 0x0DAA, 0x0DAB, 0x0DAC, 0x0DAD, 0x0DAE, 0x0DAF,
- 0x0DB0, 0x0DB1, 0x0DB2, 0x0DB3, 0x0DB4, 0x0DB5, 0x0DB6, 0x0DB7,
- 0x0DB8, 0x0DB9, 0x0DBA, 0x0DBB, 0x0DBC, 0x0DBD, 0x0DBE, 0x0DBF,
- 0x1798, 0x1799, 0x179A, 0x179B, 0x179C, 0x179D, 0x179E, 0x179F,
- 0x17A0, 0x17A1, 0x17A2, 0x17A3, 0x17A4, 0x17A5, 0x17A6, 0x17A7,
- 0x17A8, 0x17A9, 0x17AA, 0x17AB, 0x17AC, 0x17AD, 0x17AE, 0x17AF,
- 0x17B0, 0x17B1, 0x17B2, 0x17B3, 0x17B4, 0x17B5, 0x17B6, 0x17B7,
- 0x17B8, 0x17B9, 0x17BA, 0x17BB, 0x17BC, 0x17BD, 0x17BE, 0x17BF,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x04D8, 0x04D9, 0x04DA, 0x04DB, 0x04DC, 0x04DD, 0x04DE, 0x04DF,
- 0x04E0, 0x04E1, 0x04E2, 0x04E3, 0x04E4, 0x04E5, 0x04E6, 0x04E7,
- 0x04E8, 0x04E9, 0x04EA, 0x04EB, 0x04EC, 0x04ED, 0x04EE, 0x04EF,
- 0x04F0, 0x04F1, 0x04F2, 0x04F3, 0x04F4, 0x04F5, 0x04F6, 0x04F7,
- 0x04F8, 0x04F9, 0x04FA, 0x04FB, 0x04FC, 0x04FD, 0x04FE, 0x04FF,
- 0x0ED8, 0x0ED9, 0x0EDA, 0x0EDB, 0x0EDC, 0x0EDD, 0x0EDE, 0x0EDF,
- 0x0EE0, 0x0EE1, 0x0EE2, 0x0EE3, 0x0EE4, 0x0EE5, 0x0EE6, 0x0EE7,
- 0x0EE8, 0x0EE9, 0x0EEA, 0x0EEB, 0x0EEC, 0x0EED, 0x0EEE, 0x0EEF,
- 0x0EF0, 0x0EF1, 0x0EF2, 0x0EF3, 0x0EF4, 0x0EF5, 0x0EF6, 0x0EF7,
- 0x0EF8, 0x0EF9, 0x0EFA, 0x0EFB, 0x0EFC, 0x0EFD, 0x0EFE, 0x0EFF,
- 0x18D8, 0x18D9, 0x18DA, 0x18DB, 0x18DC, 0x18DD, 0x18DE, 0x18DF,
- 0x18E0, 0x18E1, 0x18E2, 0x18E3, 0x18E4, 0x18E5, 0x18E6, 0x18E7,
- 0x18E8, 0x18E9, 0x18EA, 0x18EB, 0x18EC, 0x18ED, 0x18EE, 0x18EF,
- 0x18F0, 0x18F1, 0x18F2, 0x18F3, 0x18F4, 0x18F5, 0x18F6, 0x18F7,
- 0x18F8, 0x18F9, 0x18FA, 0x18FB, 0x18FC, 0x18FD, 0x18FE, 0x18FF,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0618, 0x0619, 0x061A, 0x061B, 0x061C, 0x061D, 0x061E, 0x061F,
- 0x0620, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627,
- 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
- 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637,
- 0x0638, 0x0639, 0x063A, 0x063B, 0x063C, 0x063D, 0x063E, 0x063F,
- 0x1018, 0x1019, 0x101A, 0x101B, 0x101C, 0x101D, 0x101E, 0x101F,
- 0x1020, 0x1021, 0x1022, 0x1023, 0x1024, 0x1025, 0x1026, 0x1027,
- 0x1028, 0x1029, 0x102A, 0x102B, 0x102C, 0x102D, 0x102E, 0x102F,
- 0x1030, 0x1031, 0x1032, 0x1033, 0x1034, 0x1035, 0x1036, 0x1037,
- 0x1038, 0x1039, 0x103A, 0x103B, 0x103C, 0x103D, 0x103E, 0x103F,
- 0x1A18, 0x1A19, 0x1A1A, 0x1A1B, 0x1A1C, 0x1A1D, 0x1A1E, 0x1A1F,
- 0x1A20, 0x1A21, 0x1A22, 0x1A23, 0x1A24, 0x1A25, 0x1A26, 0x1A27,
- 0x1A28, 0x1A29, 0x1A2A, 0x1A2B, 0x1A2C, 0x1A2D, 0x1A2E, 0x1A2F,
- 0x1A30, 0x1A31, 0x1A32, 0x1A33, 0x1A34, 0x1A35, 0x1A36, 0x1A37,
- 0x1A38, 0x1A39, 0x1A3A, 0x1A3B, 0x1A3C, 0x1A3D, 0x1A3E, 0x1A3F,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0758, 0x0759, 0x075A, 0x075B, 0x075C, 0x075D, 0x075E, 0x075F,
- 0x0760, 0x0761, 0x0762, 0x0763, 0x0764, 0x0765, 0x0766, 0x0767,
- 0x0768, 0x0769, 0x076A, 0x076B, 0x076C, 0x076D, 0x076E, 0x076F,
- 0x0770, 0x0771, 0x0772, 0x0773, 0x0774, 0x0775, 0x0776, 0x0777,
- 0x0778, 0x0779, 0x077A, 0x077B, 0x077C, 0x077D, 0x077E, 0x077F,
- 0x1158, 0x1159, 0x115A, 0x115B, 0x115C, 0x115D, 0x115E, 0x115F,
- 0x1160, 0x1161, 0x1162, 0x1163, 0x1164, 0x1165, 0x1166, 0x1167,
- 0x1168, 0x1169, 0x116A, 0x116B, 0x116C, 0x116D, 0x116E, 0x116F,
- 0x1170, 0x1171, 0x1172, 0x1173, 0x1174, 0x1175, 0x1176, 0x1177,
- 0x1178, 0x1179, 0x117A, 0x117B, 0x117C, 0x117D, 0x117E, 0x117F,
- 0x1B58, 0x1B59, 0x1B5A, 0x1B5B, 0x1B5C, 0x1B5D, 0x1B5E, 0x1B5F,
- 0x1B60, 0x1B61, 0x1B62, 0x1B63, 0x1B64, 0x1B65, 0x1B66, 0x1B67,
- 0x1B68, 0x1B69, 0x1B6A, 0x1B6B, 0x1B6C, 0x1B6D, 0x1B6E, 0x1B6F,
- 0x1B70, 0x1B71, 0x1B72, 0x1B73, 0x1B74, 0x1B75, 0x1B76, 0x1B77,
- 0x1B78, 0x1B79, 0x1B7A, 0x1B7B, 0x1B7C, 0x1B7D, 0x1B7E, 0x1B7F,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x0898, 0x0899, 0x089A, 0x089B, 0x089C, 0x089D, 0x089E, 0x089F,
- 0x08A0, 0x08A1, 0x08A2, 0x08A3, 0x08A4, 0x08A5, 0x08A6, 0x08A7,
- 0x08A8, 0x08A9, 0x08AA, 0x08AB, 0x08AC, 0x08AD, 0x08AE, 0x08AF,
- 0x08B0, 0x08B1, 0x08B2, 0x08B3, 0x08B4, 0x08B5, 0x08B6, 0x08B7,
- 0x08B8, 0x08B9, 0x08BA, 0x08BB, 0x08BC, 0x08BD, 0x08BE, 0x08BF,
- 0x1298, 0x1299, 0x129A, 0x129B, 0x129C, 0x129D, 0x129E, 0x129F,
- 0x12A0, 0x12A1, 0x12A2, 0x12A3, 0x12A4, 0x12A5, 0x12A6, 0x12A7,
- 0x12A8, 0x12A9, 0x12AA, 0x12AB, 0x12AC, 0x12AD, 0x12AE, 0x12AF,
- 0x12B0, 0x12B1, 0x12B2, 0x12B3, 0x12B4, 0x12B5, 0x12B6, 0x12B7,
- 0x12B8, 0x12B9, 0x12BA, 0x12BB, 0x12BC, 0x12BD, 0x12BE, 0x12BF,
- 0x1C98, 0x1C99, 0x1C9A, 0x1C9B, 0x1C9C, 0x1C9D, 0x1C9E, 0x1C9F,
- 0x1CA0, 0x1CA1, 0x1CA2, 0x1CA3, 0x1CA4, 0x1CA5, 0x1CA6, 0x1CA7,
- 0x1CA8, 0x1CA9, 0x1CAA, 0x1CAB, 0x1CAC, 0x1CAD, 0x1CAE, 0x1CAF,
- 0x1CB0, 0x1CB1, 0x1CB2, 0x1CB3, 0x1CB4, 0x1CB5, 0x1CB6, 0x1CB7,
- 0x1CB8, 0x1CB9, 0x1CBA, 0x1CBB, 0x1CBC, 0x1CBD, 0x1CBE, 0x1CBF,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
- 0x09D8, 0x09D9, 0x09DA, 0x09DB, 0x09DC, 0x09DD, 0x09DE, 0x09DF,
- 0x09E0, 0x09E1, 0x09E2, 0x09E3, 0x09E4, 0x09E5, 0x09E6, 0x09E7,
- 0x09E8, 0x09E9, 0x09EA, 0x09EB, 0x09EC, 0x09ED, 0x09EE, 0x09EF,
- 0x09F0, 0x09F1, 0x09F2, 0x09F3, 0x09F4, 0x09F5, 0x09F6, 0x09F7,
- 0x09F8, 0x09F9, 0x09FA, 0x09FB, 0x09FC, 0x09FD, 0x09FE, 0x09FF,
- 0x13D8, 0x13D9, 0x13DA, 0x13DB, 0x13DC, 0x13DD, 0x13DE, 0x13DF,
- 0x13E0, 0x13E1, 0x13E2, 0x13E3, 0x13E4, 0x13E5, 0x13E6, 0x13E7,
- 0x13E8, 0x13E9, 0x13EA, 0x13EB, 0x13EC, 0x13ED, 0x13EE, 0x13EF,
- 0x13F0, 0x13F1, 0x13F2, 0x13F3, 0x13F4, 0x13F5, 0x13F6, 0x13F7,
- 0x13F8, 0x13F9, 0x13FA, 0x13FB, 0x13FC, 0x13FD, 0x13FE, 0x13FF,
- 0x1DD8, 0x1DD9, 0x1DDA, 0x1DDB, 0x1DDC, 0x1DDD, 0x1DDE, 0x1DDF,
- 0x1DE0, 0x1DE1, 0x1DE2, 0x1DE3, 0x1DE4, 0x1DE5, 0x1DE6, 0x1DE7,
- 0x1DE8, 0x1DE9, 0x1DEA, 0x1DEB, 0x1DEC, 0x1DED, 0x1DEE, 0x1DEF,
- 0x1DF0, 0x1DF1, 0x1DF2, 0x1DF3, 0x1DF4, 0x1DF5, 0x1DF6, 0x1DF7,
- 0x1DF8, 0x1DF9, 0x1DFA, 0x1DFB, 0x1DFC, 0x1DFD, 0x1DFE, 0x1DFF,
- 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00
- };
-
- private const int CharBitmapCount = 322;
- private const int CharBitmapBytes = 8;
-
- private static readonly byte[] CharBitmap = new byte[CharBitmapCount * CharBitmapBytes]
- {
- 0x43, 0x5D, 0x55, 0x45, 0x65, 0x7D, 0x43, 0x7F,
- 0x77, 0x6B, 0x5D, 0x5D, 0x41, 0x5D, 0x5D, 0x7F,
- 0x61, 0x5D, 0x5D, 0x61, 0x5D, 0x5D, 0x61, 0x7F,
- 0x63, 0x5D, 0x7D, 0x7D, 0x7D, 0x5D, 0x63, 0x7F,
- 0x61, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x61, 0x7F,
- 0x41, 0x7D, 0x7D, 0x61, 0x7D, 0x7D, 0x41, 0x7F,
- 0x41, 0x7D, 0x7D, 0x61, 0x7D, 0x7D, 0x7D, 0x7F,
- 0x43, 0x7D, 0x7D, 0x7D, 0x4D, 0x5D, 0x43, 0x7F,
- 0x5D, 0x5D, 0x5D, 0x41, 0x5D, 0x5D, 0x5D, 0x7F,
- 0x63, 0x77, 0x77, 0x77, 0x77, 0x77, 0x63, 0x7F,
- 0x5F, 0x5F, 0x5F, 0x5F, 0x5F, 0x5D, 0x63, 0x7F,
- 0x5D, 0x6D, 0x75, 0x79, 0x75, 0x6D, 0x5D, 0x7F,
- 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x41, 0x7F,
- 0x5D, 0x49, 0x55, 0x55, 0x5D, 0x5D, 0x5D, 0x7F,
- 0x5D, 0x5D, 0x59, 0x55, 0x4D, 0x5D, 0x5D, 0x7F,
- 0x63, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x63, 0x7F,
- 0x61, 0x5D, 0x5D, 0x61, 0x7D, 0x7D, 0x7D, 0x7F,
- 0x63, 0x5D, 0x5D, 0x5D, 0x55, 0x6D, 0x53, 0x7F,
- 0x61, 0x5D, 0x5D, 0x61, 0x75, 0x6D, 0x5D, 0x7F,
- 0x63, 0x5D, 0x7D, 0x63, 0x5F, 0x5D, 0x63, 0x7F,
- 0x41, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x7F,
- 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x63, 0x7F,
- 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x6B, 0x77, 0x7F,
- 0x5D, 0x5D, 0x5D, 0x55, 0x55, 0x49, 0x5D, 0x7F,
- 0x5D, 0x5D, 0x6B, 0x77, 0x6B, 0x5D, 0x5D, 0x7F,
- 0x5D, 0x5D, 0x6B, 0x77, 0x77, 0x77, 0x77, 0x7F,
- 0x41, 0x5F, 0x6F, 0x77, 0x7B, 0x7D, 0x41, 0x7F,
- 0x41, 0x79, 0x79, 0x79, 0x79, 0x79, 0x41, 0x7F,
- 0x7F, 0x7D, 0x7B, 0x77, 0x6F, 0x5F, 0x7F, 0x7F,
- 0x41, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x41, 0x7F,
- 0x7F, 0x7F, 0x77, 0x6B, 0x5D, 0x7F, 0x7F, 0x7F,
- 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x00,
- 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
- 0x77, 0x77, 0x77, 0x77, 0x77, 0x7F, 0x77, 0x7F,
- 0x6B, 0x6B, 0x6B, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
- 0x6B, 0x6B, 0x00, 0x6B, 0x00, 0x6B, 0x6B, 0x7F,
- 0x77, 0x43, 0x75, 0x63, 0x57, 0x61, 0x77, 0x7F,
- 0x79, 0x59, 0x6F, 0x77, 0x7B, 0x4D, 0x4F, 0x7F,
- 0x7B, 0x75, 0x75, 0x7B, 0x55, 0x6D, 0x53, 0x7F,
- 0x77, 0x77, 0x77, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
- 0x77, 0x7B, 0x7D, 0x7D, 0x7D, 0x7B, 0x77, 0x7F,
- 0x77, 0x6F, 0x5F, 0x5F, 0x5F, 0x6F, 0x77, 0x7F,
- 0x77, 0x55, 0x63, 0x77, 0x63, 0x55, 0x77, 0x7F,
- 0x7F, 0x77, 0x77, 0x41, 0x77, 0x77, 0x7F, 0x7F,
- 0x7F, 0x7F, 0x7F, 0x7F, 0x77, 0x77, 0x7B, 0x7F,
- 0x7F, 0x7F, 0x7F, 0x41, 0x7F, 0x7F, 0x7F, 0x7F,
- 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x77, 0x7F,
- 0x7F, 0x5F, 0x6F, 0x77, 0x7B, 0x7D, 0x7F, 0x7F,
- 0x63, 0x5D, 0x4D, 0x55, 0x59, 0x5D, 0x63, 0x7F,
- 0x77, 0x73, 0x77, 0x77, 0x77, 0x77, 0x63, 0x7F,
- 0x63, 0x5D, 0x5F, 0x67, 0x7B, 0x7D, 0x41, 0x7F,
- 0x41, 0x5F, 0x6F, 0x67, 0x5F, 0x5D, 0x63, 0x7F,
- 0x6F, 0x67, 0x6B, 0x6D, 0x41, 0x6F, 0x6F, 0x7F,
- 0x41, 0x7D, 0x61, 0x5F, 0x5F, 0x5D, 0x63, 0x7F,
- 0x47, 0x7B, 0x7D, 0x61, 0x5D, 0x5D, 0x63, 0x7F,
- 0x41, 0x5F, 0x6F, 0x77, 0x7B, 0x7B, 0x7B, 0x7F,
- 0x63, 0x5D, 0x5D, 0x63, 0x5D, 0x5D, 0x63, 0x7F,
- 0x63, 0x5D, 0x5D, 0x43, 0x5F, 0x6F, 0x71, 0x7F,
- 0x7F, 0x7F, 0x77, 0x7F, 0x77, 0x7F, 0x7F, 0x7F,
- 0x7F, 0x7F, 0x77, 0x7F, 0x77, 0x77, 0x7B, 0x7F,
- 0x6F, 0x77, 0x7B, 0x7D, 0x7B, 0x77, 0x6F, 0x7F,
- 0x7F, 0x7F, 0x41, 0x7F, 0x41, 0x7F, 0x7F, 0x7F,
- 0x7B, 0x77, 0x6F, 0x5F, 0x6F, 0x77, 0x7B, 0x7F,
- 0x63, 0x5D, 0x6F, 0x77, 0x77, 0x7F, 0x77, 0x7F,
- 0x43, 0x5D, 0x55, 0x45, 0x65, 0x7D, 0x43, 0x7F,
- 0x77, 0x6B, 0x5D, 0x5D, 0x41, 0x5D, 0x5D, 0x7F,
- 0x61, 0x5D, 0x5D, 0x61, 0x5D, 0x5D, 0x61, 0x7F,
- 0x63, 0x5D, 0x7D, 0x7D, 0x7D, 0x5D, 0x63, 0x7F,
- 0x61, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x61, 0x7F,
- 0x41, 0x7D, 0x7D, 0x61, 0x7D, 0x7D, 0x41, 0x7F,
- 0x41, 0x7D, 0x7D, 0x61, 0x7D, 0x7D, 0x7D, 0x7F,
- 0x43, 0x7D, 0x7D, 0x7D, 0x4D, 0x5D, 0x43, 0x7F,
- 0x5D, 0x5D, 0x5D, 0x41, 0x5D, 0x5D, 0x5D, 0x7F,
- 0x63, 0x77, 0x77, 0x77, 0x77, 0x77, 0x63, 0x7F,
- 0x5F, 0x5F, 0x5F, 0x5F, 0x5F, 0x5D, 0x63, 0x7F,
- 0x5D, 0x6D, 0x75, 0x79, 0x75, 0x6D, 0x5D, 0x7F,
- 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x41, 0x7F,
- 0x5D, 0x49, 0x55, 0x55, 0x5D, 0x5D, 0x5D, 0x7F,
- 0x5D, 0x5D, 0x59, 0x55, 0x4D, 0x5D, 0x5D, 0x7F,
- 0x63, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x63, 0x7F,
- 0x61, 0x5D, 0x5D, 0x61, 0x7D, 0x7D, 0x7D, 0x7F,
- 0x63, 0x5D, 0x5D, 0x5D, 0x55, 0x6D, 0x53, 0x7F,
- 0x61, 0x5D, 0x5D, 0x61, 0x75, 0x6D, 0x5D, 0x7F,
- 0x63, 0x5D, 0x7D, 0x63, 0x5F, 0x5D, 0x63, 0x7F,
- 0x41, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x7F,
- 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x63, 0x7F,
- 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x6B, 0x77, 0x7F,
- 0x5D, 0x5D, 0x5D, 0x55, 0x55, 0x49, 0x5D, 0x7F,
- 0x5D, 0x5D, 0x6B, 0x77, 0x6B, 0x5D, 0x5D, 0x7F,
- 0x5D, 0x5D, 0x6B, 0x77, 0x77, 0x77, 0x77, 0x7F,
- 0x41, 0x5F, 0x6F, 0x77, 0x7B, 0x7D, 0x41, 0x7F,
- 0x41, 0x79, 0x79, 0x79, 0x79, 0x79, 0x41, 0x7F,
- 0x7F, 0x7D, 0x7B, 0x77, 0x6F, 0x5F, 0x7F, 0x7F,
- 0x41, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x41, 0x7F,
- 0x7F, 0x7F, 0x77, 0x6B, 0x5D, 0x7F, 0x7F, 0x7F,
- 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x00,
- 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
- 0x77, 0x77, 0x77, 0x77, 0x77, 0x7F, 0x77, 0x7F,
- 0x6B, 0x6B, 0x6B, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
- 0x6B, 0x6B, 0x00, 0x6B, 0x00, 0x6B, 0x6B, 0x7F,
- 0x77, 0x43, 0x75, 0x63, 0x57, 0x61, 0x77, 0x7F,
- 0x79, 0x59, 0x6F, 0x77, 0x7B, 0x4D, 0x4F, 0x7F,
- 0x7B, 0x75, 0x75, 0x7B, 0x55, 0x6D, 0x53, 0x7F,
- 0x77, 0x77, 0x77, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
- 0x77, 0x7B, 0x7D, 0x7D, 0x7D, 0x7B, 0x77, 0x7F,
- 0x77, 0x6F, 0x5F, 0x5F, 0x5F, 0x6F, 0x77, 0x7F,
- 0x77, 0x55, 0x63, 0x77, 0x63, 0x55, 0x77, 0x7F,
- 0x7F, 0x77, 0x77, 0x41, 0x77, 0x77, 0x7F, 0x7F,
- 0x7F, 0x7F, 0x7F, 0x7F, 0x77, 0x77, 0x7B, 0x7F,
- 0x7F, 0x7F, 0x7F, 0x41, 0x7F, 0x7F, 0x7F, 0x7F,
- 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x77, 0x7F,
- 0x7F, 0x5F, 0x6F, 0x77, 0x7B, 0x7D, 0x7F, 0x7F,
- 0x63, 0x5D, 0x4D, 0x55, 0x59, 0x5D, 0x63, 0x7F,
- 0x77, 0x73, 0x77, 0x77, 0x77, 0x77, 0x63, 0x7F,
- 0x63, 0x5D, 0x5F, 0x67, 0x7B, 0x7D, 0x41, 0x7F,
- 0x41, 0x5F, 0x6F, 0x67, 0x5F, 0x5D, 0x63, 0x7F,
- 0x6F, 0x67, 0x6B, 0x6D, 0x41, 0x6F, 0x6F, 0x7F,
- 0x41, 0x7D, 0x61, 0x5F, 0x5F, 0x5D, 0x63, 0x7F,
- 0x47, 0x7B, 0x7D, 0x61, 0x5D, 0x5D, 0x63, 0x7F,
- 0x41, 0x5F, 0x6F, 0x77, 0x7B, 0x7B, 0x7B, 0x7F,
- 0x63, 0x5D, 0x5D, 0x63, 0x5D, 0x5D, 0x63, 0x7F,
- 0x63, 0x5D, 0x5D, 0x43, 0x5F, 0x6F, 0x71, 0x7F,
- 0x7F, 0x7F, 0x77, 0x7F, 0x77, 0x7F, 0x7F, 0x7F,
- 0x7F, 0x7F, 0x77, 0x7F, 0x77, 0x77, 0x7B, 0x7F,
- 0x6F, 0x77, 0x7B, 0x7D, 0x7B, 0x77, 0x6F, 0x7F,
- 0x7F, 0x7F, 0x41, 0x7F, 0x41, 0x7F, 0x7F, 0x7F,
- 0x7B, 0x77, 0x6F, 0x5F, 0x6F, 0x77, 0x7B, 0x7F,
- 0x63, 0x5D, 0x6F, 0x77, 0x77, 0x7F, 0x77, 0x7F,
- 0x3C, 0x22, 0x2A, 0x3A, 0x1A, 0x02, 0x3C, 0x00,
- 0x08, 0x14, 0x22, 0x22, 0x3E, 0x22, 0x22, 0x00,
- 0x1E, 0x22, 0x22, 0x1E, 0x22, 0x22, 0x1E, 0x00,
- 0x1C, 0x22, 0x02, 0x02, 0x02, 0x22, 0x1C, 0x00,
- 0x1E, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1E, 0x00,
- 0x3E, 0x02, 0x02, 0x1E, 0x02, 0x02, 0x3E, 0x00,
- 0x3E, 0x02, 0x02, 0x1E, 0x02, 0x02, 0x02, 0x00,
- 0x3C, 0x02, 0x02, 0x02, 0x32, 0x22, 0x3C, 0x00,
- 0x22, 0x22, 0x22, 0x3E, 0x22, 0x22, 0x22, 0x00,
- 0x1C, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1C, 0x00,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x1C, 0x00,
- 0x22, 0x12, 0x0A, 0x06, 0x0A, 0x12, 0x22, 0x00,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x3E, 0x00,
- 0x22, 0x36, 0x2A, 0x2A, 0x22, 0x22, 0x22, 0x00,
- 0x22, 0x22, 0x26, 0x2A, 0x32, 0x22, 0x22, 0x00,
- 0x1C, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1C, 0x00,
- 0x1E, 0x22, 0x22, 0x1E, 0x02, 0x02, 0x02, 0x00,
- 0x1C, 0x22, 0x22, 0x22, 0x2A, 0x12, 0x2C, 0x00,
- 0x1E, 0x22, 0x22, 0x1E, 0x0A, 0x12, 0x22, 0x00,
- 0x1C, 0x22, 0x02, 0x1C, 0x20, 0x22, 0x1C, 0x00,
- 0x3E, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00,
- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1C, 0x00,
- 0x22, 0x22, 0x22, 0x22, 0x22, 0x14, 0x08, 0x00,
- 0x22, 0x22, 0x22, 0x2A, 0x2A, 0x36, 0x22, 0x00,
- 0x22, 0x22, 0x14, 0x08, 0x14, 0x22, 0x22, 0x00,
- 0x22, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08, 0x00,
- 0x3E, 0x20, 0x10, 0x08, 0x04, 0x02, 0x3E, 0x00,
- 0x3E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x3E, 0x00,
- 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00,
- 0x3E, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3E, 0x00,
- 0x00, 0x00, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08, 0x00,
- 0x14, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x14, 0x14, 0x7F, 0x14, 0x7F, 0x14, 0x14, 0x00,
- 0x08, 0x3C, 0x0A, 0x1C, 0x28, 0x1E, 0x08, 0x00,
- 0x06, 0x26, 0x10, 0x08, 0x04, 0x32, 0x30, 0x00,
- 0x04, 0x0A, 0x0A, 0x04, 0x2A, 0x12, 0x2C, 0x00,
- 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x08, 0x04, 0x02, 0x02, 0x02, 0x04, 0x08, 0x00,
- 0x08, 0x10, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00,
- 0x08, 0x2A, 0x1C, 0x08, 0x1C, 0x2A, 0x08, 0x00,
- 0x00, 0x08, 0x08, 0x3E, 0x08, 0x08, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x04, 0x00,
- 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
- 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00, 0x00,
- 0x1C, 0x22, 0x32, 0x2A, 0x26, 0x22, 0x1C, 0x00,
- 0x08, 0x0C, 0x08, 0x08, 0x08, 0x08, 0x1C, 0x00,
- 0x1C, 0x22, 0x20, 0x18, 0x04, 0x02, 0x3E, 0x00,
- 0x3E, 0x20, 0x10, 0x18, 0x20, 0x22, 0x1C, 0x00,
- 0x10, 0x18, 0x14, 0x12, 0x3E, 0x10, 0x10, 0x00,
- 0x3E, 0x02, 0x1E, 0x20, 0x20, 0x22, 0x1C, 0x00,
- 0x38, 0x04, 0x02, 0x1E, 0x22, 0x22, 0x1C, 0x00,
- 0x3E, 0x20, 0x10, 0x08, 0x04, 0x04, 0x04, 0x00,
- 0x1C, 0x22, 0x22, 0x1C, 0x22, 0x22, 0x1C, 0x00,
- 0x1C, 0x22, 0x22, 0x3C, 0x20, 0x10, 0x0E, 0x00,
- 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x08, 0x00, 0x08, 0x08, 0x04, 0x00,
- 0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x00,
- 0x00, 0x00, 0x3E, 0x00, 0x3E, 0x00, 0x00, 0x00,
- 0x04, 0x08, 0x10, 0x20, 0x10, 0x08, 0x04, 0x00,
- 0x1C, 0x22, 0x10, 0x08, 0x08, 0x00, 0x08, 0x00,
- 0x3C, 0x22, 0x2A, 0x3A, 0x1A, 0x02, 0x3C, 0x00,
- 0x08, 0x14, 0x22, 0x22, 0x3E, 0x22, 0x22, 0x00,
- 0x1E, 0x22, 0x22, 0x1E, 0x22, 0x22, 0x1E, 0x00,
- 0x1C, 0x22, 0x02, 0x02, 0x02, 0x22, 0x1C, 0x00,
- 0x1E, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1E, 0x00,
- 0x3E, 0x02, 0x02, 0x1E, 0x02, 0x02, 0x3E, 0x00,
- 0x3E, 0x02, 0x02, 0x1E, 0x02, 0x02, 0x02, 0x00,
- 0x3C, 0x02, 0x02, 0x02, 0x32, 0x22, 0x3C, 0x00,
- 0x22, 0x22, 0x22, 0x3E, 0x22, 0x22, 0x22, 0x00,
- 0x1C, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1C, 0x00,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x1C, 0x00,
- 0x22, 0x12, 0x0A, 0x06, 0x0A, 0x12, 0x22, 0x00,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x3E, 0x00,
- 0x22, 0x36, 0x2A, 0x2A, 0x22, 0x22, 0x22, 0x00,
- 0x22, 0x22, 0x26, 0x2A, 0x32, 0x22, 0x22, 0x00,
- 0x1C, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1C, 0x00,
- 0x1E, 0x22, 0x22, 0x1E, 0x02, 0x02, 0x02, 0x00,
- 0x1C, 0x22, 0x22, 0x22, 0x2A, 0x12, 0x2C, 0x00,
- 0x1E, 0x22, 0x22, 0x1E, 0x0A, 0x12, 0x22, 0x00,
- 0x1C, 0x22, 0x02, 0x1C, 0x20, 0x22, 0x1C, 0x00,
- 0x3E, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00,
- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1C, 0x00,
- 0x22, 0x22, 0x22, 0x22, 0x22, 0x14, 0x08, 0x00,
- 0x22, 0x22, 0x22, 0x2A, 0x2A, 0x36, 0x22, 0x00,
- 0x22, 0x22, 0x14, 0x08, 0x14, 0x22, 0x22, 0x00,
- 0x22, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08, 0x00,
- 0x3E, 0x20, 0x10, 0x08, 0x04, 0x02, 0x3E, 0x00,
- 0x3E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x3E, 0x00,
- 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00,
- 0x3E, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3E, 0x00,
- 0x00, 0x00, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F,
- 0x04, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x1C, 0x20, 0x3C, 0x22, 0x3C, 0x00,
- 0x02, 0x02, 0x1E, 0x22, 0x22, 0x22, 0x1E, 0x00,
- 0x00, 0x00, 0x3C, 0x02, 0x02, 0x02, 0x3C, 0x00,
- 0x20, 0x20, 0x3C, 0x22, 0x22, 0x22, 0x3C, 0x00,
- 0x00, 0x00, 0x1C, 0x22, 0x3E, 0x02, 0x3C, 0x00,
- 0x18, 0x24, 0x04, 0x1E, 0x04, 0x04, 0x04, 0x00,
- 0x00, 0x00, 0x1C, 0x22, 0x22, 0x3C, 0x20, 0x1C,
- 0x02, 0x02, 0x1E, 0x22, 0x22, 0x22, 0x22, 0x00,
- 0x08, 0x00, 0x0C, 0x08, 0x08, 0x08, 0x1C, 0x00,
- 0x10, 0x00, 0x18, 0x10, 0x10, 0x10, 0x12, 0x0C,
- 0x02, 0x02, 0x22, 0x12, 0x0E, 0x12, 0x22, 0x00,
- 0x0C, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1C, 0x00,
- 0x00, 0x00, 0x36, 0x2A, 0x2A, 0x2A, 0x22, 0x00,
- 0x00, 0x00, 0x1E, 0x22, 0x22, 0x22, 0x22, 0x00,
- 0x00, 0x00, 0x1C, 0x22, 0x22, 0x22, 0x1C, 0x00,
- 0x00, 0x00, 0x1E, 0x22, 0x22, 0x1E, 0x02, 0x02,
- 0x00, 0x00, 0x3C, 0x22, 0x22, 0x3C, 0x20, 0x20,
- 0x00, 0x00, 0x3A, 0x06, 0x02, 0x02, 0x02, 0x00,
- 0x00, 0x00, 0x3C, 0x02, 0x1C, 0x20, 0x1E, 0x00,
- 0x04, 0x04, 0x1E, 0x04, 0x04, 0x24, 0x18, 0x00,
- 0x00, 0x00, 0x22, 0x22, 0x22, 0x32, 0x2C, 0x00,
- 0x00, 0x00, 0x22, 0x22, 0x22, 0x14, 0x08, 0x00,
- 0x00, 0x00, 0x22, 0x22, 0x2A, 0x2A, 0x36, 0x00,
- 0x00, 0x00, 0x22, 0x14, 0x08, 0x14, 0x22, 0x00,
- 0x00, 0x00, 0x22, 0x22, 0x22, 0x3C, 0x20, 0x1C,
- 0x00, 0x00, 0x3E, 0x10, 0x08, 0x04, 0x3E, 0x00,
- 0x38, 0x0C, 0x0C, 0x06, 0x0C, 0x0C, 0x38, 0x00,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x0E, 0x18, 0x18, 0x30, 0x18, 0x18, 0x0E, 0x00,
- 0x2C, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x2A, 0x14, 0x2A, 0x14, 0x2A, 0x00, 0x00,
- 0x10, 0x08, 0x36, 0x7F, 0x3F, 0x3F, 0x7E, 0x36,
- 0x10, 0x08, 0x36, 0x49, 0x21, 0x21, 0x4A, 0x36,
- 0x00, 0x00, 0x02, 0x06, 0x0E, 0x1E, 0x36, 0x42,
- 0x7F, 0x22, 0x14, 0x08, 0x08, 0x14, 0x2A, 0x7F,
- 0x00, 0x40, 0x20, 0x11, 0x0A, 0x04, 0x04, 0x00,
- 0x7F, 0x3F, 0x5F, 0x6C, 0x75, 0x7B, 0x7B, 0x7F,
- 0x3F, 0x3F, 0x3F, 0x3B, 0x39, 0x00, 0x79, 0x7B,
- 0x7F, 0x00, 0x7F, 0x00, 0x7F, 0x00, 0x00, 0x7F,
- 0x08, 0x04, 0x02, 0x7F, 0x02, 0x04, 0x08, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A,
- 0x08, 0x08, 0x08, 0x08, 0x49, 0x2A, 0x1C, 0x08,
- 0x08, 0x1C, 0x2A, 0x49, 0x08, 0x08, 0x08, 0x08,
- 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x40, 0x40, 0x40, 0x44, 0x46, 0x7F, 0x06, 0x04,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x13, 0x18, 0x1C, 0x7E, 0x1C, 0x18, 0x10, 0x6F,
- 0x64, 0x0C, 0x1C, 0x3F, 0x1C, 0x0C, 0x04, 0x7B,
- 0x40, 0x48, 0x08, 0x7F, 0x3E, 0x1C, 0x48, 0x40,
- 0x40, 0x48, 0x1C, 0x3E, 0x7F, 0x08, 0x48, 0x48,
- 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x7F,
- 0x08, 0x10, 0x20, 0x7F, 0x20, 0x10, 0x08, 0x00,
- 0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55,
- 0x55, 0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55, 0x2A,
- 0x00, 0x3E, 0x41, 0x01, 0x01, 0x01, 0x7F, 0x00,
- 0x00, 0x00, 0x3F, 0x40, 0x40, 0x40, 0x7F, 0x00,
- 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
- 0x08, 0x1C, 0x3E, 0x7F, 0x3E, 0x1C, 0x08, 0x00,
- 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F,
- 0x14, 0x14, 0x77, 0x00, 0x77, 0x14, 0x14, 0x00,
- 0x7F, 0x40, 0x40, 0x4C, 0x4C, 0x40, 0x40, 0x7F,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x7B, 0x77, 0x6F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
- 0x7F, 0x7F, 0x63, 0x5F, 0x43, 0x5D, 0x43, 0x7F,
- 0x7D, 0x7D, 0x61, 0x5D, 0x5D, 0x5D, 0x61, 0x7F,
- 0x7F, 0x7F, 0x43, 0x7D, 0x7D, 0x7D, 0x43, 0x7F,
- 0x5F, 0x5F, 0x43, 0x5D, 0x5D, 0x5D, 0x43, 0x7F,
- 0x7F, 0x7F, 0x63, 0x5D, 0x41, 0x7D, 0x43, 0x7F,
- 0x67, 0x5B, 0x7B, 0x61, 0x7B, 0x7B, 0x7B, 0x7F,
- 0x7F, 0x7F, 0x63, 0x5D, 0x5D, 0x43, 0x5F, 0x63,
- 0x7D, 0x7D, 0x61, 0x5D, 0x5D, 0x5D, 0x5D, 0x7F,
- 0x77, 0x7F, 0x73, 0x77, 0x77, 0x77, 0x63, 0x7F,
- 0x6F, 0x7F, 0x67, 0x6F, 0x6F, 0x6F, 0x6D, 0x73,
- 0x7D, 0x7D, 0x5D, 0x6D, 0x71, 0x6D, 0x5D, 0x7F,
- 0x73, 0x77, 0x77, 0x77, 0x77, 0x77, 0x63, 0x7F,
- 0x7F, 0x7F, 0x49, 0x55, 0x55, 0x55, 0x5D, 0x7F,
- 0x7F, 0x7F, 0x61, 0x5D, 0x5D, 0x5D, 0x5D, 0x7F,
- 0x7F, 0x7F, 0x63, 0x5D, 0x5D, 0x5D, 0x63, 0x7F,
- 0x7F, 0x7F, 0x61, 0x5D, 0x5D, 0x61, 0x7D, 0x7D,
- 0x7F, 0x7F, 0x43, 0x5D, 0x5D, 0x43, 0x5F, 0x5F,
- 0x7F, 0x7F, 0x45, 0x79, 0x7D, 0x7D, 0x7D, 0x7F,
- 0x7F, 0x7F, 0x43, 0x7D, 0x63, 0x5F, 0x61, 0x7F,
- 0x7B, 0x7B, 0x61, 0x7B, 0x7B, 0x5B, 0x67, 0x7F,
- 0x7F, 0x7F, 0x5D, 0x5D, 0x5D, 0x4D, 0x53, 0x7F,
- 0x7F, 0x7F, 0x5D, 0x5D, 0x5D, 0x6B, 0x77, 0x7F,
- 0x7F, 0x7F, 0x5D, 0x5D, 0x55, 0x55, 0x49, 0x7F,
- 0x7F, 0x7F, 0x5D, 0x6B, 0x77, 0x6B, 0x5D, 0x7F,
- 0x7F, 0x7F, 0x5D, 0x5D, 0x5D, 0x43, 0x5F, 0x63,
- 0x7F, 0x7F, 0x41, 0x6F, 0x77, 0x7B, 0x41, 0x7F,
- 0x47, 0x73, 0x73, 0x79, 0x73, 0x73, 0x47, 0x7F,
- 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
- 0x71, 0x67, 0x67, 0x4F, 0x67, 0x67, 0x71, 0x7F,
- 0x53, 0x65, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
- 0x7F, 0x55, 0x6B, 0x55, 0x6B, 0x55, 0x7F, 0x7F,
- 0x70, 0x60, 0x7E, 0x31, 0x79, 0x30, 0x3F, 0x02,
- 0x00, 0x18, 0x07, 0x00, 0x07, 0x0C, 0x08, 0x70
- };
-
- private const int CharSetCharCount = 256;
-
- private static readonly ushort[] CharSetPrimary = new ushort[CharSetCharCount]
- {
- 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
- 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
- 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
- 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
- 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
- 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
- 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
- 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
- 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
- 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
- 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
- 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
- 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
- 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
- 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
- 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
- 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
- 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
- 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
- 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
- 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
- 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
- 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
- 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
- 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
- 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
- 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
- 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
- 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
- };
-
- private static readonly ushort[] CharSetSecondaryStandard = new ushort[CharSetCharCount]
- {
- 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
- 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
- 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
- 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
- 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
- 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
- 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
- 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
- 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
- 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126, 0x0127,
- 0x0128, 0x0129, 0x012A, 0x012B, 0x012C, 0x012D, 0x012E, 0x012F,
- 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136, 0x0137,
- 0x0138, 0x0139, 0x013A, 0x013B, 0x013C, 0x013D, 0x013E, 0x013F,
- 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
- 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
- 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
- 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
- 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
- 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
- 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
- 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
- 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
- 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
- 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
- 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
- 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
- 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
- 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
- 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
- };
-
- private static readonly ushort[] CharSetSecondaryEnhanced = new ushort[CharSetCharCount]
- {
- 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
- 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
- 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
- 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
- 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
- 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
- 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
- 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, 0x0107,
- 0x0108, 0x0109, 0x010A, 0x010B, 0x010C, 0x010D, 0x010E, 0x010F,
- 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116, 0x0117,
- 0x0118, 0x0119, 0x011A, 0x011B, 0x011C, 0x011D, 0x011E, 0x011F,
- 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126, 0x0127,
- 0x0128, 0x0129, 0x012A, 0x012B, 0x012C, 0x012D, 0x012E, 0x012F,
- 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136, 0x0137,
- 0x0138, 0x0139, 0x013A, 0x013B, 0x013C, 0x013D, 0x013E, 0x013F,
- 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
- 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
- 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
- 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
- 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
- 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
- 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
- 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
- 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
- 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
- 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
- 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
- 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
- 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
- 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
- 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
- };
-
- private const int ColorPaletteCount = 0x210;
-
- private const int ColorMono00 = 0x000;
- private const int ColorMono01 = 0x001;
- private const int ColorMono02 = 0x002;
- private const int ColorMono04 = 0x004;
- private const int ColorMono08 = 0x008;
- private const int ColorMono10 = 0x010;
- private const int ColorMono20 = 0x020;
- private const int ColorMono40 = 0x040;
- private const int ColorMono80 = 0x080;
-
- private const int ColorWhite00 = 0x100;
- private const int ColorWhite01 = 0x101;
- private const int ColorWhite02 = 0x102;
- private const int ColorWhite04 = 0x104;
- private const int ColorWhite08 = 0x108;
- private const int ColorWhite10 = 0x110;
- private const int ColorWhite20 = 0x120;
- private const int ColorWhite40 = 0x140;
- private const int ColorWhite80 = 0x180;
-
- private const int ColorDHires0 = 0x200;
- private const int ColorDHires1 = 0x201;
- private const int ColorDHires2 = 0x202;
- private const int ColorDHires3 = 0x203;
- private const int ColorDHires4 = 0x204;
- private const int ColorDHires5 = 0x205;
- private const int ColorDHires6 = 0x206;
- private const int ColorDHires7 = 0x207;
- private const int ColorDHires8 = 0x208;
- private const int ColorDHires9 = 0x209;
- private const int ColorDHiresA = 0x20A;
- private const int ColorDHiresB = 0x20B;
- private const int ColorDHiresC = 0x20C;
- private const int ColorDHiresD = 0x20D;
- private const int ColorDHiresE = 0x20E;
- private const int ColorDHiresF = 0x20F;
-
- private const int ColorLoresDataCount = 16;
-
- private static readonly int[] ColorLores = new int[ColorLoresDataCount]
- {
- ColorDHires0, ColorDHires8, ColorDHires1, ColorDHires9,
- ColorDHires2, ColorDHiresA, ColorDHires3, ColorDHiresB,
- ColorDHires4, ColorDHiresC, ColorDHires5, ColorDHiresD,
- ColorDHires6, ColorDHiresE, ColorDHires7, ColorDHiresF
- };
-
- private static readonly int[] Color7MLores = new int[2 * ColorLoresDataCount]
- {
- ColorDHires0, ColorDHires9, ColorDHires6, ColorDHiresF, // even columns
- ColorDHires0, ColorDHires9, ColorDHires6, ColorDHiresF,
- ColorDHires0, ColorDHires9, ColorDHires6, ColorDHiresF,
- ColorDHires0, ColorDHires9, ColorDHires6, ColorDHiresF,
- ColorDHires0, ColorDHires0, ColorDHires0, ColorDHires0, // odd columns
- ColorDHires6, ColorDHires6, ColorDHires6, ColorDHires6,
- ColorDHires9, ColorDHires9, ColorDHires9, ColorDHires9,
- ColorDHiresF, ColorDHiresF, ColorDHiresF, ColorDHiresF
- };
-
- private static readonly int[] ColorDLores = new int[2 * ColorLoresDataCount]
- {
- ColorDHires0, ColorDHires4, ColorDHires8, ColorDHiresC, // even columns
- ColorDHires1, ColorDHires5, ColorDHires9, ColorDHiresD,
- ColorDHires2, ColorDHires6, ColorDHiresA, ColorDHiresE,
- ColorDHires3, ColorDHires7, ColorDHiresB, ColorDHiresF,
- ColorDHires0, ColorDHires8, ColorDHires1, ColorDHires9, // odd columns
- ColorDHires2, ColorDHiresA, ColorDHires3, ColorDHiresB,
- ColorDHires4, ColorDHiresC, ColorDHires5, ColorDHiresD,
- ColorDHires6, ColorDHiresE, ColorDHires7, ColorDHiresF
- };
-
- private const int ColorHiresDataCount = 8;
-
- private static readonly int[] ColorHires = new int[4 * ColorHiresDataCount]
- {
- ColorDHires0, ColorDHires0, ColorDHires9, ColorDHiresF, // even columns, high bit off
- ColorDHires0, ColorDHires6, ColorDHiresF, ColorDHiresF,
- ColorDHires0, ColorDHires0, ColorDHires3, ColorDHiresF, // even columns, high bit on
- ColorDHires0, ColorDHiresC, ColorDHiresF, ColorDHiresF,
- ColorDHires0, ColorDHires0, ColorDHires6, ColorDHiresF, // odd columns, high bit off
- ColorDHires0, ColorDHires9, ColorDHiresF, ColorDHiresF,
- ColorDHires0, ColorDHires0, ColorDHiresC, ColorDHiresF, // odd columns, high bit on
- ColorDHires0, ColorDHires3, ColorDHiresF, ColorDHiresF
- };
-
- private const int CyclesPerHBlank = 25;
- private const int CyclesPerHSync = 65;
- private const int CyclesPerFlush = 8 * CyclesPerHSync;
- private const int CyclesPerSecond = 1022730;
-
- private const int HCountPreset = 0x40; // hcount preset after hcount overflows -> HPE' low [3-13]
- private const int HCountLeaveHBlank = 0x58; // hcount when leaving hblank [3-15]
- private const int VCountPresetNtsc = 0xFA; // vcount preset after vcount overflows (NTSC) [3-13]
- private const int VCountPresetPal = 0xC8; // vcount preset after vcount overflows (PAL) [3-17]
- private const int VLineEnterVBlank = 192; // vline when entering vblank (NTSC & PAL) [3-17]
- private const int VLineTriggerPreset = 256; // vline when vcount overflows and presets (NTSC & PAL) [3-15, 3-16]
- private const int VLineLeaveVBlankNtsc = 262; // vline when leaving vblank (NTSC) [3-13]
- private const int VLineLeaveVBlankPal = 312; // vline when leaving vblank (PAL) [3-17]
- private const int VSyncsPerFlash = 16; // flash count using vcount overflow [3-17]
-
- public const int ModeCount = 16;
-
- public const int Mode0 = 0x0;
- public const int Mode1 = 0x1;
- public const int Mode2 = 0x2;
- public const int Mode3 = 0x3;
- public const int Mode4 = 0x4;
- public const int Mode5 = 0x5;
- public const int Mode6 = 0x6;
- public const int Mode7 = 0x7;
- public const int Mode8 = 0x8;
- public const int Mode9 = 0x9;
- public const int ModeA = 0xA;
- public const int ModeB = 0xB;
- public const int ModeC = 0xC;
- public const int ModeD = 0xD;
- public const int ModeE = 0xE;
- public const int ModeF = 0xF;
-
- private readonly Action[] FlushRowMode;
-
- private const int Width = 560;
- private const int Height = VLineEnterVBlank;
-
- private const int TextHeight = 8;
- private const int TextRows = Height / TextHeight;
-
- private const int LoresHeight = 4;
- private const int LoresRows = Height / LoresHeight;
-
- private const int MixedHeight = 160;
- private const int MixedCellIndex = MixedHeight * CellColumns;
- }
-}
+using System;
+
+namespace Jellyfish.Virtu
+{
+ public partial class Video
+ {
+ private static readonly int[] AddressOffset = new int[Height]
+ {
+ 0x0000, 0x0400, 0x0800, 0x0C00, 0x1000, 0x1400, 0x1800, 0x1C00,
+ 0x0080, 0x0480, 0x0880, 0x0C80, 0x1080, 0x1480, 0x1880, 0x1C80,
+ 0x0100, 0x0500, 0x0900, 0x0D00, 0x1100, 0x1500, 0x1900, 0x1D00,
+ 0x0180, 0x0580, 0x0980, 0x0D80, 0x1180, 0x1580, 0x1980, 0x1D80,
+ 0x0200, 0x0600, 0x0A00, 0x0E00, 0x1200, 0x1600, 0x1A00, 0x1E00,
+ 0x0280, 0x0680, 0x0A80, 0x0E80, 0x1280, 0x1680, 0x1A80, 0x1E80,
+ 0x0300, 0x0700, 0x0B00, 0x0F00, 0x1300, 0x1700, 0x1B00, 0x1F00,
+ 0x0380, 0x0780, 0x0B80, 0x0F80, 0x1380, 0x1780, 0x1B80, 0x1F80,
+ 0x0028, 0x0428, 0x0828, 0x0C28, 0x1028, 0x1428, 0x1828, 0x1C28,
+ 0x00A8, 0x04A8, 0x08A8, 0x0CA8, 0x10A8, 0x14A8, 0x18A8, 0x1CA8,
+ 0x0128, 0x0528, 0x0928, 0x0D28, 0x1128, 0x1528, 0x1928, 0x1D28,
+ 0x01A8, 0x05A8, 0x09A8, 0x0DA8, 0x11A8, 0x15A8, 0x19A8, 0x1DA8,
+ 0x0228, 0x0628, 0x0A28, 0x0E28, 0x1228, 0x1628, 0x1A28, 0x1E28,
+ 0x02A8, 0x06A8, 0x0AA8, 0x0EA8, 0x12A8, 0x16A8, 0x1AA8, 0x1EA8,
+ 0x0328, 0x0728, 0x0B28, 0x0F28, 0x1328, 0x1728, 0x1B28, 0x1F28,
+ 0x03A8, 0x07A8, 0x0BA8, 0x0FA8, 0x13A8, 0x17A8, 0x1BA8, 0x1FA8,
+ 0x0050, 0x0450, 0x0850, 0x0C50, 0x1050, 0x1450, 0x1850, 0x1C50,
+ 0x00D0, 0x04D0, 0x08D0, 0x0CD0, 0x10D0, 0x14D0, 0x18D0, 0x1CD0,
+ 0x0150, 0x0550, 0x0950, 0x0D50, 0x1150, 0x1550, 0x1950, 0x1D50,
+ 0x01D0, 0x05D0, 0x09D0, 0x0DD0, 0x11D0, 0x15D0, 0x19D0, 0x1DD0,
+ 0x0250, 0x0650, 0x0A50, 0x0E50, 0x1250, 0x1650, 0x1A50, 0x1E50,
+ 0x02D0, 0x06D0, 0x0AD0, 0x0ED0, 0x12D0, 0x16D0, 0x1AD0, 0x1ED0,
+ 0x0350, 0x0750, 0x0B50, 0x0F50, 0x1350, 0x1750, 0x1B50, 0x1F50,
+ 0x03D0, 0x07D0, 0x0BD0, 0x0FD0, 0x13D0, 0x17D0, 0x1BD0, 0x1FD0
+ };
+
+ private const int CellWidth = 14;
+ private const int CellHeight = 8;
+ private const int CellRows = Height / CellHeight;
+ private const int CellColumns = Width / CellWidth;
+
+ private const int CellIndexCount = 0x2000;
+
+ private static readonly ushort[] CellIndex = new ushort[CellIndexCount]
+ {
+ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
+ 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
+ 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
+ 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
+ 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
+ 0x0A00, 0x0A01, 0x0A02, 0x0A03, 0x0A04, 0x0A05, 0x0A06, 0x0A07,
+ 0x0A08, 0x0A09, 0x0A0A, 0x0A0B, 0x0A0C, 0x0A0D, 0x0A0E, 0x0A0F,
+ 0x0A10, 0x0A11, 0x0A12, 0x0A13, 0x0A14, 0x0A15, 0x0A16, 0x0A17,
+ 0x0A18, 0x0A19, 0x0A1A, 0x0A1B, 0x0A1C, 0x0A1D, 0x0A1E, 0x0A1F,
+ 0x0A20, 0x0A21, 0x0A22, 0x0A23, 0x0A24, 0x0A25, 0x0A26, 0x0A27,
+ 0x1400, 0x1401, 0x1402, 0x1403, 0x1404, 0x1405, 0x1406, 0x1407,
+ 0x1408, 0x1409, 0x140A, 0x140B, 0x140C, 0x140D, 0x140E, 0x140F,
+ 0x1410, 0x1411, 0x1412, 0x1413, 0x1414, 0x1415, 0x1416, 0x1417,
+ 0x1418, 0x1419, 0x141A, 0x141B, 0x141C, 0x141D, 0x141E, 0x141F,
+ 0x1420, 0x1421, 0x1422, 0x1423, 0x1424, 0x1425, 0x1426, 0x1427,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0146, 0x0147,
+ 0x0148, 0x0149, 0x014A, 0x014B, 0x014C, 0x014D, 0x014E, 0x014F,
+ 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155, 0x0156, 0x0157,
+ 0x0158, 0x0159, 0x015A, 0x015B, 0x015C, 0x015D, 0x015E, 0x015F,
+ 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165, 0x0166, 0x0167,
+ 0x0B40, 0x0B41, 0x0B42, 0x0B43, 0x0B44, 0x0B45, 0x0B46, 0x0B47,
+ 0x0B48, 0x0B49, 0x0B4A, 0x0B4B, 0x0B4C, 0x0B4D, 0x0B4E, 0x0B4F,
+ 0x0B50, 0x0B51, 0x0B52, 0x0B53, 0x0B54, 0x0B55, 0x0B56, 0x0B57,
+ 0x0B58, 0x0B59, 0x0B5A, 0x0B5B, 0x0B5C, 0x0B5D, 0x0B5E, 0x0B5F,
+ 0x0B60, 0x0B61, 0x0B62, 0x0B63, 0x0B64, 0x0B65, 0x0B66, 0x0B67,
+ 0x1540, 0x1541, 0x1542, 0x1543, 0x1544, 0x1545, 0x1546, 0x1547,
+ 0x1548, 0x1549, 0x154A, 0x154B, 0x154C, 0x154D, 0x154E, 0x154F,
+ 0x1550, 0x1551, 0x1552, 0x1553, 0x1554, 0x1555, 0x1556, 0x1557,
+ 0x1558, 0x1559, 0x155A, 0x155B, 0x155C, 0x155D, 0x155E, 0x155F,
+ 0x1560, 0x1561, 0x1562, 0x1563, 0x1564, 0x1565, 0x1566, 0x1567,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0280, 0x0281, 0x0282, 0x0283, 0x0284, 0x0285, 0x0286, 0x0287,
+ 0x0288, 0x0289, 0x028A, 0x028B, 0x028C, 0x028D, 0x028E, 0x028F,
+ 0x0290, 0x0291, 0x0292, 0x0293, 0x0294, 0x0295, 0x0296, 0x0297,
+ 0x0298, 0x0299, 0x029A, 0x029B, 0x029C, 0x029D, 0x029E, 0x029F,
+ 0x02A0, 0x02A1, 0x02A2, 0x02A3, 0x02A4, 0x02A5, 0x02A6, 0x02A7,
+ 0x0C80, 0x0C81, 0x0C82, 0x0C83, 0x0C84, 0x0C85, 0x0C86, 0x0C87,
+ 0x0C88, 0x0C89, 0x0C8A, 0x0C8B, 0x0C8C, 0x0C8D, 0x0C8E, 0x0C8F,
+ 0x0C90, 0x0C91, 0x0C92, 0x0C93, 0x0C94, 0x0C95, 0x0C96, 0x0C97,
+ 0x0C98, 0x0C99, 0x0C9A, 0x0C9B, 0x0C9C, 0x0C9D, 0x0C9E, 0x0C9F,
+ 0x0CA0, 0x0CA1, 0x0CA2, 0x0CA3, 0x0CA4, 0x0CA5, 0x0CA6, 0x0CA7,
+ 0x1680, 0x1681, 0x1682, 0x1683, 0x1684, 0x1685, 0x1686, 0x1687,
+ 0x1688, 0x1689, 0x168A, 0x168B, 0x168C, 0x168D, 0x168E, 0x168F,
+ 0x1690, 0x1691, 0x1692, 0x1693, 0x1694, 0x1695, 0x1696, 0x1697,
+ 0x1698, 0x1699, 0x169A, 0x169B, 0x169C, 0x169D, 0x169E, 0x169F,
+ 0x16A0, 0x16A1, 0x16A2, 0x16A3, 0x16A4, 0x16A5, 0x16A6, 0x16A7,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
+ 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x03CF,
+ 0x03D0, 0x03D1, 0x03D2, 0x03D3, 0x03D4, 0x03D5, 0x03D6, 0x03D7,
+ 0x03D8, 0x03D9, 0x03DA, 0x03DB, 0x03DC, 0x03DD, 0x03DE, 0x03DF,
+ 0x03E0, 0x03E1, 0x03E2, 0x03E3, 0x03E4, 0x03E5, 0x03E6, 0x03E7,
+ 0x0DC0, 0x0DC1, 0x0DC2, 0x0DC3, 0x0DC4, 0x0DC5, 0x0DC6, 0x0DC7,
+ 0x0DC8, 0x0DC9, 0x0DCA, 0x0DCB, 0x0DCC, 0x0DCD, 0x0DCE, 0x0DCF,
+ 0x0DD0, 0x0DD1, 0x0DD2, 0x0DD3, 0x0DD4, 0x0DD5, 0x0DD6, 0x0DD7,
+ 0x0DD8, 0x0DD9, 0x0DDA, 0x0DDB, 0x0DDC, 0x0DDD, 0x0DDE, 0x0DDF,
+ 0x0DE0, 0x0DE1, 0x0DE2, 0x0DE3, 0x0DE4, 0x0DE5, 0x0DE6, 0x0DE7,
+ 0x17C0, 0x17C1, 0x17C2, 0x17C3, 0x17C4, 0x17C5, 0x17C6, 0x17C7,
+ 0x17C8, 0x17C9, 0x17CA, 0x17CB, 0x17CC, 0x17CD, 0x17CE, 0x17CF,
+ 0x17D0, 0x17D1, 0x17D2, 0x17D3, 0x17D4, 0x17D5, 0x17D6, 0x17D7,
+ 0x17D8, 0x17D9, 0x17DA, 0x17DB, 0x17DC, 0x17DD, 0x17DE, 0x17DF,
+ 0x17E0, 0x17E1, 0x17E2, 0x17E3, 0x17E4, 0x17E5, 0x17E6, 0x17E7,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0500, 0x0501, 0x0502, 0x0503, 0x0504, 0x0505, 0x0506, 0x0507,
+ 0x0508, 0x0509, 0x050A, 0x050B, 0x050C, 0x050D, 0x050E, 0x050F,
+ 0x0510, 0x0511, 0x0512, 0x0513, 0x0514, 0x0515, 0x0516, 0x0517,
+ 0x0518, 0x0519, 0x051A, 0x051B, 0x051C, 0x051D, 0x051E, 0x051F,
+ 0x0520, 0x0521, 0x0522, 0x0523, 0x0524, 0x0525, 0x0526, 0x0527,
+ 0x0F00, 0x0F01, 0x0F02, 0x0F03, 0x0F04, 0x0F05, 0x0F06, 0x0F07,
+ 0x0F08, 0x0F09, 0x0F0A, 0x0F0B, 0x0F0C, 0x0F0D, 0x0F0E, 0x0F0F,
+ 0x0F10, 0x0F11, 0x0F12, 0x0F13, 0x0F14, 0x0F15, 0x0F16, 0x0F17,
+ 0x0F18, 0x0F19, 0x0F1A, 0x0F1B, 0x0F1C, 0x0F1D, 0x0F1E, 0x0F1F,
+ 0x0F20, 0x0F21, 0x0F22, 0x0F23, 0x0F24, 0x0F25, 0x0F26, 0x0F27,
+ 0x1900, 0x1901, 0x1902, 0x1903, 0x1904, 0x1905, 0x1906, 0x1907,
+ 0x1908, 0x1909, 0x190A, 0x190B, 0x190C, 0x190D, 0x190E, 0x190F,
+ 0x1910, 0x1911, 0x1912, 0x1913, 0x1914, 0x1915, 0x1916, 0x1917,
+ 0x1918, 0x1919, 0x191A, 0x191B, 0x191C, 0x191D, 0x191E, 0x191F,
+ 0x1920, 0x1921, 0x1922, 0x1923, 0x1924, 0x1925, 0x1926, 0x1927,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647,
+ 0x0648, 0x0649, 0x064A, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F,
+ 0x0650, 0x0651, 0x0652, 0x0653, 0x0654, 0x0655, 0x0656, 0x0657,
+ 0x0658, 0x0659, 0x065A, 0x065B, 0x065C, 0x065D, 0x065E, 0x065F,
+ 0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667,
+ 0x1040, 0x1041, 0x1042, 0x1043, 0x1044, 0x1045, 0x1046, 0x1047,
+ 0x1048, 0x1049, 0x104A, 0x104B, 0x104C, 0x104D, 0x104E, 0x104F,
+ 0x1050, 0x1051, 0x1052, 0x1053, 0x1054, 0x1055, 0x1056, 0x1057,
+ 0x1058, 0x1059, 0x105A, 0x105B, 0x105C, 0x105D, 0x105E, 0x105F,
+ 0x1060, 0x1061, 0x1062, 0x1063, 0x1064, 0x1065, 0x1066, 0x1067,
+ 0x1A40, 0x1A41, 0x1A42, 0x1A43, 0x1A44, 0x1A45, 0x1A46, 0x1A47,
+ 0x1A48, 0x1A49, 0x1A4A, 0x1A4B, 0x1A4C, 0x1A4D, 0x1A4E, 0x1A4F,
+ 0x1A50, 0x1A51, 0x1A52, 0x1A53, 0x1A54, 0x1A55, 0x1A56, 0x1A57,
+ 0x1A58, 0x1A59, 0x1A5A, 0x1A5B, 0x1A5C, 0x1A5D, 0x1A5E, 0x1A5F,
+ 0x1A60, 0x1A61, 0x1A62, 0x1A63, 0x1A64, 0x1A65, 0x1A66, 0x1A67,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0786, 0x0787,
+ 0x0788, 0x0789, 0x078A, 0x078B, 0x078C, 0x078D, 0x078E, 0x078F,
+ 0x0790, 0x0791, 0x0792, 0x0793, 0x0794, 0x0795, 0x0796, 0x0797,
+ 0x0798, 0x0799, 0x079A, 0x079B, 0x079C, 0x079D, 0x079E, 0x079F,
+ 0x07A0, 0x07A1, 0x07A2, 0x07A3, 0x07A4, 0x07A5, 0x07A6, 0x07A7,
+ 0x1180, 0x1181, 0x1182, 0x1183, 0x1184, 0x1185, 0x1186, 0x1187,
+ 0x1188, 0x1189, 0x118A, 0x118B, 0x118C, 0x118D, 0x118E, 0x118F,
+ 0x1190, 0x1191, 0x1192, 0x1193, 0x1194, 0x1195, 0x1196, 0x1197,
+ 0x1198, 0x1199, 0x119A, 0x119B, 0x119C, 0x119D, 0x119E, 0x119F,
+ 0x11A0, 0x11A1, 0x11A2, 0x11A3, 0x11A4, 0x11A5, 0x11A6, 0x11A7,
+ 0x1B80, 0x1B81, 0x1B82, 0x1B83, 0x1B84, 0x1B85, 0x1B86, 0x1B87,
+ 0x1B88, 0x1B89, 0x1B8A, 0x1B8B, 0x1B8C, 0x1B8D, 0x1B8E, 0x1B8F,
+ 0x1B90, 0x1B91, 0x1B92, 0x1B93, 0x1B94, 0x1B95, 0x1B96, 0x1B97,
+ 0x1B98, 0x1B99, 0x1B9A, 0x1B9B, 0x1B9C, 0x1B9D, 0x1B9E, 0x1B9F,
+ 0x1BA0, 0x1BA1, 0x1BA2, 0x1BA3, 0x1BA4, 0x1BA5, 0x1BA6, 0x1BA7,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x08C0, 0x08C1, 0x08C2, 0x08C3, 0x08C4, 0x08C5, 0x08C6, 0x08C7,
+ 0x08C8, 0x08C9, 0x08CA, 0x08CB, 0x08CC, 0x08CD, 0x08CE, 0x08CF,
+ 0x08D0, 0x08D1, 0x08D2, 0x08D3, 0x08D4, 0x08D5, 0x08D6, 0x08D7,
+ 0x08D8, 0x08D9, 0x08DA, 0x08DB, 0x08DC, 0x08DD, 0x08DE, 0x08DF,
+ 0x08E0, 0x08E1, 0x08E2, 0x08E3, 0x08E4, 0x08E5, 0x08E6, 0x08E7,
+ 0x12C0, 0x12C1, 0x12C2, 0x12C3, 0x12C4, 0x12C5, 0x12C6, 0x12C7,
+ 0x12C8, 0x12C9, 0x12CA, 0x12CB, 0x12CC, 0x12CD, 0x12CE, 0x12CF,
+ 0x12D0, 0x12D1, 0x12D2, 0x12D3, 0x12D4, 0x12D5, 0x12D6, 0x12D7,
+ 0x12D8, 0x12D9, 0x12DA, 0x12DB, 0x12DC, 0x12DD, 0x12DE, 0x12DF,
+ 0x12E0, 0x12E1, 0x12E2, 0x12E3, 0x12E4, 0x12E5, 0x12E6, 0x12E7,
+ 0x1CC0, 0x1CC1, 0x1CC2, 0x1CC3, 0x1CC4, 0x1CC5, 0x1CC6, 0x1CC7,
+ 0x1CC8, 0x1CC9, 0x1CCA, 0x1CCB, 0x1CCC, 0x1CCD, 0x1CCE, 0x1CCF,
+ 0x1CD0, 0x1CD1, 0x1CD2, 0x1CD3, 0x1CD4, 0x1CD5, 0x1CD6, 0x1CD7,
+ 0x1CD8, 0x1CD9, 0x1CDA, 0x1CDB, 0x1CDC, 0x1CDD, 0x1CDE, 0x1CDF,
+ 0x1CE0, 0x1CE1, 0x1CE2, 0x1CE3, 0x1CE4, 0x1CE5, 0x1CE6, 0x1CE7,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
+ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
+ 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
+ 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
+ 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
+ 0x0A28, 0x0A29, 0x0A2A, 0x0A2B, 0x0A2C, 0x0A2D, 0x0A2E, 0x0A2F,
+ 0x0A30, 0x0A31, 0x0A32, 0x0A33, 0x0A34, 0x0A35, 0x0A36, 0x0A37,
+ 0x0A38, 0x0A39, 0x0A3A, 0x0A3B, 0x0A3C, 0x0A3D, 0x0A3E, 0x0A3F,
+ 0x0A40, 0x0A41, 0x0A42, 0x0A43, 0x0A44, 0x0A45, 0x0A46, 0x0A47,
+ 0x0A48, 0x0A49, 0x0A4A, 0x0A4B, 0x0A4C, 0x0A4D, 0x0A4E, 0x0A4F,
+ 0x1428, 0x1429, 0x142A, 0x142B, 0x142C, 0x142D, 0x142E, 0x142F,
+ 0x1430, 0x1431, 0x1432, 0x1433, 0x1434, 0x1435, 0x1436, 0x1437,
+ 0x1438, 0x1439, 0x143A, 0x143B, 0x143C, 0x143D, 0x143E, 0x143F,
+ 0x1440, 0x1441, 0x1442, 0x1443, 0x1444, 0x1445, 0x1446, 0x1447,
+ 0x1448, 0x1449, 0x144A, 0x144B, 0x144C, 0x144D, 0x144E, 0x144F,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0168, 0x0169, 0x016A, 0x016B, 0x016C, 0x016D, 0x016E, 0x016F,
+ 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175, 0x0176, 0x0177,
+ 0x0178, 0x0179, 0x017A, 0x017B, 0x017C, 0x017D, 0x017E, 0x017F,
+ 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185, 0x0186, 0x0187,
+ 0x0188, 0x0189, 0x018A, 0x018B, 0x018C, 0x018D, 0x018E, 0x018F,
+ 0x0B68, 0x0B69, 0x0B6A, 0x0B6B, 0x0B6C, 0x0B6D, 0x0B6E, 0x0B6F,
+ 0x0B70, 0x0B71, 0x0B72, 0x0B73, 0x0B74, 0x0B75, 0x0B76, 0x0B77,
+ 0x0B78, 0x0B79, 0x0B7A, 0x0B7B, 0x0B7C, 0x0B7D, 0x0B7E, 0x0B7F,
+ 0x0B80, 0x0B81, 0x0B82, 0x0B83, 0x0B84, 0x0B85, 0x0B86, 0x0B87,
+ 0x0B88, 0x0B89, 0x0B8A, 0x0B8B, 0x0B8C, 0x0B8D, 0x0B8E, 0x0B8F,
+ 0x1568, 0x1569, 0x156A, 0x156B, 0x156C, 0x156D, 0x156E, 0x156F,
+ 0x1570, 0x1571, 0x1572, 0x1573, 0x1574, 0x1575, 0x1576, 0x1577,
+ 0x1578, 0x1579, 0x157A, 0x157B, 0x157C, 0x157D, 0x157E, 0x157F,
+ 0x1580, 0x1581, 0x1582, 0x1583, 0x1584, 0x1585, 0x1586, 0x1587,
+ 0x1588, 0x1589, 0x158A, 0x158B, 0x158C, 0x158D, 0x158E, 0x158F,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x02A8, 0x02A9, 0x02AA, 0x02AB, 0x02AC, 0x02AD, 0x02AE, 0x02AF,
+ 0x02B0, 0x02B1, 0x02B2, 0x02B3, 0x02B4, 0x02B5, 0x02B6, 0x02B7,
+ 0x02B8, 0x02B9, 0x02BA, 0x02BB, 0x02BC, 0x02BD, 0x02BE, 0x02BF,
+ 0x02C0, 0x02C1, 0x02C2, 0x02C3, 0x02C4, 0x02C5, 0x02C6, 0x02C7,
+ 0x02C8, 0x02C9, 0x02CA, 0x02CB, 0x02CC, 0x02CD, 0x02CE, 0x02CF,
+ 0x0CA8, 0x0CA9, 0x0CAA, 0x0CAB, 0x0CAC, 0x0CAD, 0x0CAE, 0x0CAF,
+ 0x0CB0, 0x0CB1, 0x0CB2, 0x0CB3, 0x0CB4, 0x0CB5, 0x0CB6, 0x0CB7,
+ 0x0CB8, 0x0CB9, 0x0CBA, 0x0CBB, 0x0CBC, 0x0CBD, 0x0CBE, 0x0CBF,
+ 0x0CC0, 0x0CC1, 0x0CC2, 0x0CC3, 0x0CC4, 0x0CC5, 0x0CC6, 0x0CC7,
+ 0x0CC8, 0x0CC9, 0x0CCA, 0x0CCB, 0x0CCC, 0x0CCD, 0x0CCE, 0x0CCF,
+ 0x16A8, 0x16A9, 0x16AA, 0x16AB, 0x16AC, 0x16AD, 0x16AE, 0x16AF,
+ 0x16B0, 0x16B1, 0x16B2, 0x16B3, 0x16B4, 0x16B5, 0x16B6, 0x16B7,
+ 0x16B8, 0x16B9, 0x16BA, 0x16BB, 0x16BC, 0x16BD, 0x16BE, 0x16BF,
+ 0x16C0, 0x16C1, 0x16C2, 0x16C3, 0x16C4, 0x16C5, 0x16C6, 0x16C7,
+ 0x16C8, 0x16C9, 0x16CA, 0x16CB, 0x16CC, 0x16CD, 0x16CE, 0x16CF,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x03E8, 0x03E9, 0x03EA, 0x03EB, 0x03EC, 0x03ED, 0x03EE, 0x03EF,
+ 0x03F0, 0x03F1, 0x03F2, 0x03F3, 0x03F4, 0x03F5, 0x03F6, 0x03F7,
+ 0x03F8, 0x03F9, 0x03FA, 0x03FB, 0x03FC, 0x03FD, 0x03FE, 0x03FF,
+ 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407,
+ 0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x040D, 0x040E, 0x040F,
+ 0x0DE8, 0x0DE9, 0x0DEA, 0x0DEB, 0x0DEC, 0x0DED, 0x0DEE, 0x0DEF,
+ 0x0DF0, 0x0DF1, 0x0DF2, 0x0DF3, 0x0DF4, 0x0DF5, 0x0DF6, 0x0DF7,
+ 0x0DF8, 0x0DF9, 0x0DFA, 0x0DFB, 0x0DFC, 0x0DFD, 0x0DFE, 0x0DFF,
+ 0x0E00, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07,
+ 0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F,
+ 0x17E8, 0x17E9, 0x17EA, 0x17EB, 0x17EC, 0x17ED, 0x17EE, 0x17EF,
+ 0x17F0, 0x17F1, 0x17F2, 0x17F3, 0x17F4, 0x17F5, 0x17F6, 0x17F7,
+ 0x17F8, 0x17F9, 0x17FA, 0x17FB, 0x17FC, 0x17FD, 0x17FE, 0x17FF,
+ 0x1800, 0x1801, 0x1802, 0x1803, 0x1804, 0x1805, 0x1806, 0x1807,
+ 0x1808, 0x1809, 0x180A, 0x180B, 0x180C, 0x180D, 0x180E, 0x180F,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0528, 0x0529, 0x052A, 0x052B, 0x052C, 0x052D, 0x052E, 0x052F,
+ 0x0530, 0x0531, 0x0532, 0x0533, 0x0534, 0x0535, 0x0536, 0x0537,
+ 0x0538, 0x0539, 0x053A, 0x053B, 0x053C, 0x053D, 0x053E, 0x053F,
+ 0x0540, 0x0541, 0x0542, 0x0543, 0x0544, 0x0545, 0x0546, 0x0547,
+ 0x0548, 0x0549, 0x054A, 0x054B, 0x054C, 0x054D, 0x054E, 0x054F,
+ 0x0F28, 0x0F29, 0x0F2A, 0x0F2B, 0x0F2C, 0x0F2D, 0x0F2E, 0x0F2F,
+ 0x0F30, 0x0F31, 0x0F32, 0x0F33, 0x0F34, 0x0F35, 0x0F36, 0x0F37,
+ 0x0F38, 0x0F39, 0x0F3A, 0x0F3B, 0x0F3C, 0x0F3D, 0x0F3E, 0x0F3F,
+ 0x0F40, 0x0F41, 0x0F42, 0x0F43, 0x0F44, 0x0F45, 0x0F46, 0x0F47,
+ 0x0F48, 0x0F49, 0x0F4A, 0x0F4B, 0x0F4C, 0x0F4D, 0x0F4E, 0x0F4F,
+ 0x1928, 0x1929, 0x192A, 0x192B, 0x192C, 0x192D, 0x192E, 0x192F,
+ 0x1930, 0x1931, 0x1932, 0x1933, 0x1934, 0x1935, 0x1936, 0x1937,
+ 0x1938, 0x1939, 0x193A, 0x193B, 0x193C, 0x193D, 0x193E, 0x193F,
+ 0x1940, 0x1941, 0x1942, 0x1943, 0x1944, 0x1945, 0x1946, 0x1947,
+ 0x1948, 0x1949, 0x194A, 0x194B, 0x194C, 0x194D, 0x194E, 0x194F,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0668, 0x0669, 0x066A, 0x066B, 0x066C, 0x066D, 0x066E, 0x066F,
+ 0x0670, 0x0671, 0x0672, 0x0673, 0x0674, 0x0675, 0x0676, 0x0677,
+ 0x0678, 0x0679, 0x067A, 0x067B, 0x067C, 0x067D, 0x067E, 0x067F,
+ 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0686, 0x0687,
+ 0x0688, 0x0689, 0x068A, 0x068B, 0x068C, 0x068D, 0x068E, 0x068F,
+ 0x1068, 0x1069, 0x106A, 0x106B, 0x106C, 0x106D, 0x106E, 0x106F,
+ 0x1070, 0x1071, 0x1072, 0x1073, 0x1074, 0x1075, 0x1076, 0x1077,
+ 0x1078, 0x1079, 0x107A, 0x107B, 0x107C, 0x107D, 0x107E, 0x107F,
+ 0x1080, 0x1081, 0x1082, 0x1083, 0x1084, 0x1085, 0x1086, 0x1087,
+ 0x1088, 0x1089, 0x108A, 0x108B, 0x108C, 0x108D, 0x108E, 0x108F,
+ 0x1A68, 0x1A69, 0x1A6A, 0x1A6B, 0x1A6C, 0x1A6D, 0x1A6E, 0x1A6F,
+ 0x1A70, 0x1A71, 0x1A72, 0x1A73, 0x1A74, 0x1A75, 0x1A76, 0x1A77,
+ 0x1A78, 0x1A79, 0x1A7A, 0x1A7B, 0x1A7C, 0x1A7D, 0x1A7E, 0x1A7F,
+ 0x1A80, 0x1A81, 0x1A82, 0x1A83, 0x1A84, 0x1A85, 0x1A86, 0x1A87,
+ 0x1A88, 0x1A89, 0x1A8A, 0x1A8B, 0x1A8C, 0x1A8D, 0x1A8E, 0x1A8F,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x07A8, 0x07A9, 0x07AA, 0x07AB, 0x07AC, 0x07AD, 0x07AE, 0x07AF,
+ 0x07B0, 0x07B1, 0x07B2, 0x07B3, 0x07B4, 0x07B5, 0x07B6, 0x07B7,
+ 0x07B8, 0x07B9, 0x07BA, 0x07BB, 0x07BC, 0x07BD, 0x07BE, 0x07BF,
+ 0x07C0, 0x07C1, 0x07C2, 0x07C3, 0x07C4, 0x07C5, 0x07C6, 0x07C7,
+ 0x07C8, 0x07C9, 0x07CA, 0x07CB, 0x07CC, 0x07CD, 0x07CE, 0x07CF,
+ 0x11A8, 0x11A9, 0x11AA, 0x11AB, 0x11AC, 0x11AD, 0x11AE, 0x11AF,
+ 0x11B0, 0x11B1, 0x11B2, 0x11B3, 0x11B4, 0x11B5, 0x11B6, 0x11B7,
+ 0x11B8, 0x11B9, 0x11BA, 0x11BB, 0x11BC, 0x11BD, 0x11BE, 0x11BF,
+ 0x11C0, 0x11C1, 0x11C2, 0x11C3, 0x11C4, 0x11C5, 0x11C6, 0x11C7,
+ 0x11C8, 0x11C9, 0x11CA, 0x11CB, 0x11CC, 0x11CD, 0x11CE, 0x11CF,
+ 0x1BA8, 0x1BA9, 0x1BAA, 0x1BAB, 0x1BAC, 0x1BAD, 0x1BAE, 0x1BAF,
+ 0x1BB0, 0x1BB1, 0x1BB2, 0x1BB3, 0x1BB4, 0x1BB5, 0x1BB6, 0x1BB7,
+ 0x1BB8, 0x1BB9, 0x1BBA, 0x1BBB, 0x1BBC, 0x1BBD, 0x1BBE, 0x1BBF,
+ 0x1BC0, 0x1BC1, 0x1BC2, 0x1BC3, 0x1BC4, 0x1BC5, 0x1BC6, 0x1BC7,
+ 0x1BC8, 0x1BC9, 0x1BCA, 0x1BCB, 0x1BCC, 0x1BCD, 0x1BCE, 0x1BCF,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x08E8, 0x08E9, 0x08EA, 0x08EB, 0x08EC, 0x08ED, 0x08EE, 0x08EF,
+ 0x08F0, 0x08F1, 0x08F2, 0x08F3, 0x08F4, 0x08F5, 0x08F6, 0x08F7,
+ 0x08F8, 0x08F9, 0x08FA, 0x08FB, 0x08FC, 0x08FD, 0x08FE, 0x08FF,
+ 0x0900, 0x0901, 0x0902, 0x0903, 0x0904, 0x0905, 0x0906, 0x0907,
+ 0x0908, 0x0909, 0x090A, 0x090B, 0x090C, 0x090D, 0x090E, 0x090F,
+ 0x12E8, 0x12E9, 0x12EA, 0x12EB, 0x12EC, 0x12ED, 0x12EE, 0x12EF,
+ 0x12F0, 0x12F1, 0x12F2, 0x12F3, 0x12F4, 0x12F5, 0x12F6, 0x12F7,
+ 0x12F8, 0x12F9, 0x12FA, 0x12FB, 0x12FC, 0x12FD, 0x12FE, 0x12FF,
+ 0x1300, 0x1301, 0x1302, 0x1303, 0x1304, 0x1305, 0x1306, 0x1307,
+ 0x1308, 0x1309, 0x130A, 0x130B, 0x130C, 0x130D, 0x130E, 0x130F,
+ 0x1CE8, 0x1CE9, 0x1CEA, 0x1CEB, 0x1CEC, 0x1CED, 0x1CEE, 0x1CEF,
+ 0x1CF0, 0x1CF1, 0x1CF2, 0x1CF3, 0x1CF4, 0x1CF5, 0x1CF6, 0x1CF7,
+ 0x1CF8, 0x1CF9, 0x1CFA, 0x1CFB, 0x1CFC, 0x1CFD, 0x1CFE, 0x1CFF,
+ 0x1D00, 0x1D01, 0x1D02, 0x1D03, 0x1D04, 0x1D05, 0x1D06, 0x1D07,
+ 0x1D08, 0x1D09, 0x1D0A, 0x1D0B, 0x1D0C, 0x1D0D, 0x1D0E, 0x1D0F,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
+ 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
+ 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
+ 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
+ 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
+ 0x0A50, 0x0A51, 0x0A52, 0x0A53, 0x0A54, 0x0A55, 0x0A56, 0x0A57,
+ 0x0A58, 0x0A59, 0x0A5A, 0x0A5B, 0x0A5C, 0x0A5D, 0x0A5E, 0x0A5F,
+ 0x0A60, 0x0A61, 0x0A62, 0x0A63, 0x0A64, 0x0A65, 0x0A66, 0x0A67,
+ 0x0A68, 0x0A69, 0x0A6A, 0x0A6B, 0x0A6C, 0x0A6D, 0x0A6E, 0x0A6F,
+ 0x0A70, 0x0A71, 0x0A72, 0x0A73, 0x0A74, 0x0A75, 0x0A76, 0x0A77,
+ 0x1450, 0x1451, 0x1452, 0x1453, 0x1454, 0x1455, 0x1456, 0x1457,
+ 0x1458, 0x1459, 0x145A, 0x145B, 0x145C, 0x145D, 0x145E, 0x145F,
+ 0x1460, 0x1461, 0x1462, 0x1463, 0x1464, 0x1465, 0x1466, 0x1467,
+ 0x1468, 0x1469, 0x146A, 0x146B, 0x146C, 0x146D, 0x146E, 0x146F,
+ 0x1470, 0x1471, 0x1472, 0x1473, 0x1474, 0x1475, 0x1476, 0x1477,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0190, 0x0191, 0x0192, 0x0193, 0x0194, 0x0195, 0x0196, 0x0197,
+ 0x0198, 0x0199, 0x019A, 0x019B, 0x019C, 0x019D, 0x019E, 0x019F,
+ 0x01A0, 0x01A1, 0x01A2, 0x01A3, 0x01A4, 0x01A5, 0x01A6, 0x01A7,
+ 0x01A8, 0x01A9, 0x01AA, 0x01AB, 0x01AC, 0x01AD, 0x01AE, 0x01AF,
+ 0x01B0, 0x01B1, 0x01B2, 0x01B3, 0x01B4, 0x01B5, 0x01B6, 0x01B7,
+ 0x0B90, 0x0B91, 0x0B92, 0x0B93, 0x0B94, 0x0B95, 0x0B96, 0x0B97,
+ 0x0B98, 0x0B99, 0x0B9A, 0x0B9B, 0x0B9C, 0x0B9D, 0x0B9E, 0x0B9F,
+ 0x0BA0, 0x0BA1, 0x0BA2, 0x0BA3, 0x0BA4, 0x0BA5, 0x0BA6, 0x0BA7,
+ 0x0BA8, 0x0BA9, 0x0BAA, 0x0BAB, 0x0BAC, 0x0BAD, 0x0BAE, 0x0BAF,
+ 0x0BB0, 0x0BB1, 0x0BB2, 0x0BB3, 0x0BB4, 0x0BB5, 0x0BB6, 0x0BB7,
+ 0x1590, 0x1591, 0x1592, 0x1593, 0x1594, 0x1595, 0x1596, 0x1597,
+ 0x1598, 0x1599, 0x159A, 0x159B, 0x159C, 0x159D, 0x159E, 0x159F,
+ 0x15A0, 0x15A1, 0x15A2, 0x15A3, 0x15A4, 0x15A5, 0x15A6, 0x15A7,
+ 0x15A8, 0x15A9, 0x15AA, 0x15AB, 0x15AC, 0x15AD, 0x15AE, 0x15AF,
+ 0x15B0, 0x15B1, 0x15B2, 0x15B3, 0x15B4, 0x15B5, 0x15B6, 0x15B7,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x02D0, 0x02D1, 0x02D2, 0x02D3, 0x02D4, 0x02D5, 0x02D6, 0x02D7,
+ 0x02D8, 0x02D9, 0x02DA, 0x02DB, 0x02DC, 0x02DD, 0x02DE, 0x02DF,
+ 0x02E0, 0x02E1, 0x02E2, 0x02E3, 0x02E4, 0x02E5, 0x02E6, 0x02E7,
+ 0x02E8, 0x02E9, 0x02EA, 0x02EB, 0x02EC, 0x02ED, 0x02EE, 0x02EF,
+ 0x02F0, 0x02F1, 0x02F2, 0x02F3, 0x02F4, 0x02F5, 0x02F6, 0x02F7,
+ 0x0CD0, 0x0CD1, 0x0CD2, 0x0CD3, 0x0CD4, 0x0CD5, 0x0CD6, 0x0CD7,
+ 0x0CD8, 0x0CD9, 0x0CDA, 0x0CDB, 0x0CDC, 0x0CDD, 0x0CDE, 0x0CDF,
+ 0x0CE0, 0x0CE1, 0x0CE2, 0x0CE3, 0x0CE4, 0x0CE5, 0x0CE6, 0x0CE7,
+ 0x0CE8, 0x0CE9, 0x0CEA, 0x0CEB, 0x0CEC, 0x0CED, 0x0CEE, 0x0CEF,
+ 0x0CF0, 0x0CF1, 0x0CF2, 0x0CF3, 0x0CF4, 0x0CF5, 0x0CF6, 0x0CF7,
+ 0x16D0, 0x16D1, 0x16D2, 0x16D3, 0x16D4, 0x16D5, 0x16D6, 0x16D7,
+ 0x16D8, 0x16D9, 0x16DA, 0x16DB, 0x16DC, 0x16DD, 0x16DE, 0x16DF,
+ 0x16E0, 0x16E1, 0x16E2, 0x16E3, 0x16E4, 0x16E5, 0x16E6, 0x16E7,
+ 0x16E8, 0x16E9, 0x16EA, 0x16EB, 0x16EC, 0x16ED, 0x16EE, 0x16EF,
+ 0x16F0, 0x16F1, 0x16F2, 0x16F3, 0x16F4, 0x16F5, 0x16F6, 0x16F7,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
+ 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
+ 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
+ 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
+ 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
+ 0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17,
+ 0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F,
+ 0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
+ 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F,
+ 0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37,
+ 0x1810, 0x1811, 0x1812, 0x1813, 0x1814, 0x1815, 0x1816, 0x1817,
+ 0x1818, 0x1819, 0x181A, 0x181B, 0x181C, 0x181D, 0x181E, 0x181F,
+ 0x1820, 0x1821, 0x1822, 0x1823, 0x1824, 0x1825, 0x1826, 0x1827,
+ 0x1828, 0x1829, 0x182A, 0x182B, 0x182C, 0x182D, 0x182E, 0x182F,
+ 0x1830, 0x1831, 0x1832, 0x1833, 0x1834, 0x1835, 0x1836, 0x1837,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0550, 0x0551, 0x0552, 0x0553, 0x0554, 0x0555, 0x0556, 0x0557,
+ 0x0558, 0x0559, 0x055A, 0x055B, 0x055C, 0x055D, 0x055E, 0x055F,
+ 0x0560, 0x0561, 0x0562, 0x0563, 0x0564, 0x0565, 0x0566, 0x0567,
+ 0x0568, 0x0569, 0x056A, 0x056B, 0x056C, 0x056D, 0x056E, 0x056F,
+ 0x0570, 0x0571, 0x0572, 0x0573, 0x0574, 0x0575, 0x0576, 0x0577,
+ 0x0F50, 0x0F51, 0x0F52, 0x0F53, 0x0F54, 0x0F55, 0x0F56, 0x0F57,
+ 0x0F58, 0x0F59, 0x0F5A, 0x0F5B, 0x0F5C, 0x0F5D, 0x0F5E, 0x0F5F,
+ 0x0F60, 0x0F61, 0x0F62, 0x0F63, 0x0F64, 0x0F65, 0x0F66, 0x0F67,
+ 0x0F68, 0x0F69, 0x0F6A, 0x0F6B, 0x0F6C, 0x0F6D, 0x0F6E, 0x0F6F,
+ 0x0F70, 0x0F71, 0x0F72, 0x0F73, 0x0F74, 0x0F75, 0x0F76, 0x0F77,
+ 0x1950, 0x1951, 0x1952, 0x1953, 0x1954, 0x1955, 0x1956, 0x1957,
+ 0x1958, 0x1959, 0x195A, 0x195B, 0x195C, 0x195D, 0x195E, 0x195F,
+ 0x1960, 0x1961, 0x1962, 0x1963, 0x1964, 0x1965, 0x1966, 0x1967,
+ 0x1968, 0x1969, 0x196A, 0x196B, 0x196C, 0x196D, 0x196E, 0x196F,
+ 0x1970, 0x1971, 0x1972, 0x1973, 0x1974, 0x1975, 0x1976, 0x1977,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0690, 0x0691, 0x0692, 0x0693, 0x0694, 0x0695, 0x0696, 0x0697,
+ 0x0698, 0x0699, 0x069A, 0x069B, 0x069C, 0x069D, 0x069E, 0x069F,
+ 0x06A0, 0x06A1, 0x06A2, 0x06A3, 0x06A4, 0x06A5, 0x06A6, 0x06A7,
+ 0x06A8, 0x06A9, 0x06AA, 0x06AB, 0x06AC, 0x06AD, 0x06AE, 0x06AF,
+ 0x06B0, 0x06B1, 0x06B2, 0x06B3, 0x06B4, 0x06B5, 0x06B6, 0x06B7,
+ 0x1090, 0x1091, 0x1092, 0x1093, 0x1094, 0x1095, 0x1096, 0x1097,
+ 0x1098, 0x1099, 0x109A, 0x109B, 0x109C, 0x109D, 0x109E, 0x109F,
+ 0x10A0, 0x10A1, 0x10A2, 0x10A3, 0x10A4, 0x10A5, 0x10A6, 0x10A7,
+ 0x10A8, 0x10A9, 0x10AA, 0x10AB, 0x10AC, 0x10AD, 0x10AE, 0x10AF,
+ 0x10B0, 0x10B1, 0x10B2, 0x10B3, 0x10B4, 0x10B5, 0x10B6, 0x10B7,
+ 0x1A90, 0x1A91, 0x1A92, 0x1A93, 0x1A94, 0x1A95, 0x1A96, 0x1A97,
+ 0x1A98, 0x1A99, 0x1A9A, 0x1A9B, 0x1A9C, 0x1A9D, 0x1A9E, 0x1A9F,
+ 0x1AA0, 0x1AA1, 0x1AA2, 0x1AA3, 0x1AA4, 0x1AA5, 0x1AA6, 0x1AA7,
+ 0x1AA8, 0x1AA9, 0x1AAA, 0x1AAB, 0x1AAC, 0x1AAD, 0x1AAE, 0x1AAF,
+ 0x1AB0, 0x1AB1, 0x1AB2, 0x1AB3, 0x1AB4, 0x1AB5, 0x1AB6, 0x1AB7,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x07D0, 0x07D1, 0x07D2, 0x07D3, 0x07D4, 0x07D5, 0x07D6, 0x07D7,
+ 0x07D8, 0x07D9, 0x07DA, 0x07DB, 0x07DC, 0x07DD, 0x07DE, 0x07DF,
+ 0x07E0, 0x07E1, 0x07E2, 0x07E3, 0x07E4, 0x07E5, 0x07E6, 0x07E7,
+ 0x07E8, 0x07E9, 0x07EA, 0x07EB, 0x07EC, 0x07ED, 0x07EE, 0x07EF,
+ 0x07F0, 0x07F1, 0x07F2, 0x07F3, 0x07F4, 0x07F5, 0x07F6, 0x07F7,
+ 0x11D0, 0x11D1, 0x11D2, 0x11D3, 0x11D4, 0x11D5, 0x11D6, 0x11D7,
+ 0x11D8, 0x11D9, 0x11DA, 0x11DB, 0x11DC, 0x11DD, 0x11DE, 0x11DF,
+ 0x11E0, 0x11E1, 0x11E2, 0x11E3, 0x11E4, 0x11E5, 0x11E6, 0x11E7,
+ 0x11E8, 0x11E9, 0x11EA, 0x11EB, 0x11EC, 0x11ED, 0x11EE, 0x11EF,
+ 0x11F0, 0x11F1, 0x11F2, 0x11F3, 0x11F4, 0x11F5, 0x11F6, 0x11F7,
+ 0x1BD0, 0x1BD1, 0x1BD2, 0x1BD3, 0x1BD4, 0x1BD5, 0x1BD6, 0x1BD7,
+ 0x1BD8, 0x1BD9, 0x1BDA, 0x1BDB, 0x1BDC, 0x1BDD, 0x1BDE, 0x1BDF,
+ 0x1BE0, 0x1BE1, 0x1BE2, 0x1BE3, 0x1BE4, 0x1BE5, 0x1BE6, 0x1BE7,
+ 0x1BE8, 0x1BE9, 0x1BEA, 0x1BEB, 0x1BEC, 0x1BED, 0x1BEE, 0x1BEF,
+ 0x1BF0, 0x1BF1, 0x1BF2, 0x1BF3, 0x1BF4, 0x1BF5, 0x1BF6, 0x1BF7,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0910, 0x0911, 0x0912, 0x0913, 0x0914, 0x0915, 0x0916, 0x0917,
+ 0x0918, 0x0919, 0x091A, 0x091B, 0x091C, 0x091D, 0x091E, 0x091F,
+ 0x0920, 0x0921, 0x0922, 0x0923, 0x0924, 0x0925, 0x0926, 0x0927,
+ 0x0928, 0x0929, 0x092A, 0x092B, 0x092C, 0x092D, 0x092E, 0x092F,
+ 0x0930, 0x0931, 0x0932, 0x0933, 0x0934, 0x0935, 0x0936, 0x0937,
+ 0x1310, 0x1311, 0x1312, 0x1313, 0x1314, 0x1315, 0x1316, 0x1317,
+ 0x1318, 0x1319, 0x131A, 0x131B, 0x131C, 0x131D, 0x131E, 0x131F,
+ 0x1320, 0x1321, 0x1322, 0x1323, 0x1324, 0x1325, 0x1326, 0x1327,
+ 0x1328, 0x1329, 0x132A, 0x132B, 0x132C, 0x132D, 0x132E, 0x132F,
+ 0x1330, 0x1331, 0x1332, 0x1333, 0x1334, 0x1335, 0x1336, 0x1337,
+ 0x1D10, 0x1D11, 0x1D12, 0x1D13, 0x1D14, 0x1D15, 0x1D16, 0x1D17,
+ 0x1D18, 0x1D19, 0x1D1A, 0x1D1B, 0x1D1C, 0x1D1D, 0x1D1E, 0x1D1F,
+ 0x1D20, 0x1D21, 0x1D22, 0x1D23, 0x1D24, 0x1D25, 0x1D26, 0x1D27,
+ 0x1D28, 0x1D29, 0x1D2A, 0x1D2B, 0x1D2C, 0x1D2D, 0x1D2E, 0x1D2F,
+ 0x1D30, 0x1D31, 0x1D32, 0x1D33, 0x1D34, 0x1D35, 0x1D36, 0x1D37,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
+ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x0A78, 0x0A79, 0x0A7A, 0x0A7B, 0x0A7C, 0x0A7D, 0x0A7E, 0x0A7F,
+ 0x0A80, 0x0A81, 0x0A82, 0x0A83, 0x0A84, 0x0A85, 0x0A86, 0x0A87,
+ 0x0A88, 0x0A89, 0x0A8A, 0x0A8B, 0x0A8C, 0x0A8D, 0x0A8E, 0x0A8F,
+ 0x0A90, 0x0A91, 0x0A92, 0x0A93, 0x0A94, 0x0A95, 0x0A96, 0x0A97,
+ 0x0A98, 0x0A99, 0x0A9A, 0x0A9B, 0x0A9C, 0x0A9D, 0x0A9E, 0x0A9F,
+ 0x1478, 0x1479, 0x147A, 0x147B, 0x147C, 0x147D, 0x147E, 0x147F,
+ 0x1480, 0x1481, 0x1482, 0x1483, 0x1484, 0x1485, 0x1486, 0x1487,
+ 0x1488, 0x1489, 0x148A, 0x148B, 0x148C, 0x148D, 0x148E, 0x148F,
+ 0x1490, 0x1491, 0x1492, 0x1493, 0x1494, 0x1495, 0x1496, 0x1497,
+ 0x1498, 0x1499, 0x149A, 0x149B, 0x149C, 0x149D, 0x149E, 0x149F,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x01B8, 0x01B9, 0x01BA, 0x01BB, 0x01BC, 0x01BD, 0x01BE, 0x01BF,
+ 0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C4, 0x01C5, 0x01C6, 0x01C7,
+ 0x01C8, 0x01C9, 0x01CA, 0x01CB, 0x01CC, 0x01CD, 0x01CE, 0x01CF,
+ 0x01D0, 0x01D1, 0x01D2, 0x01D3, 0x01D4, 0x01D5, 0x01D6, 0x01D7,
+ 0x01D8, 0x01D9, 0x01DA, 0x01DB, 0x01DC, 0x01DD, 0x01DE, 0x01DF,
+ 0x0BB8, 0x0BB9, 0x0BBA, 0x0BBB, 0x0BBC, 0x0BBD, 0x0BBE, 0x0BBF,
+ 0x0BC0, 0x0BC1, 0x0BC2, 0x0BC3, 0x0BC4, 0x0BC5, 0x0BC6, 0x0BC7,
+ 0x0BC8, 0x0BC9, 0x0BCA, 0x0BCB, 0x0BCC, 0x0BCD, 0x0BCE, 0x0BCF,
+ 0x0BD0, 0x0BD1, 0x0BD2, 0x0BD3, 0x0BD4, 0x0BD5, 0x0BD6, 0x0BD7,
+ 0x0BD8, 0x0BD9, 0x0BDA, 0x0BDB, 0x0BDC, 0x0BDD, 0x0BDE, 0x0BDF,
+ 0x15B8, 0x15B9, 0x15BA, 0x15BB, 0x15BC, 0x15BD, 0x15BE, 0x15BF,
+ 0x15C0, 0x15C1, 0x15C2, 0x15C3, 0x15C4, 0x15C5, 0x15C6, 0x15C7,
+ 0x15C8, 0x15C9, 0x15CA, 0x15CB, 0x15CC, 0x15CD, 0x15CE, 0x15CF,
+ 0x15D0, 0x15D1, 0x15D2, 0x15D3, 0x15D4, 0x15D5, 0x15D6, 0x15D7,
+ 0x15D8, 0x15D9, 0x15DA, 0x15DB, 0x15DC, 0x15DD, 0x15DE, 0x15DF,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x02F8, 0x02F9, 0x02FA, 0x02FB, 0x02FC, 0x02FD, 0x02FE, 0x02FF,
+ 0x0300, 0x0301, 0x0302, 0x0303, 0x0304, 0x0305, 0x0306, 0x0307,
+ 0x0308, 0x0309, 0x030A, 0x030B, 0x030C, 0x030D, 0x030E, 0x030F,
+ 0x0310, 0x0311, 0x0312, 0x0313, 0x0314, 0x0315, 0x0316, 0x0317,
+ 0x0318, 0x0319, 0x031A, 0x031B, 0x031C, 0x031D, 0x031E, 0x031F,
+ 0x0CF8, 0x0CF9, 0x0CFA, 0x0CFB, 0x0CFC, 0x0CFD, 0x0CFE, 0x0CFF,
+ 0x0D00, 0x0D01, 0x0D02, 0x0D03, 0x0D04, 0x0D05, 0x0D06, 0x0D07,
+ 0x0D08, 0x0D09, 0x0D0A, 0x0D0B, 0x0D0C, 0x0D0D, 0x0D0E, 0x0D0F,
+ 0x0D10, 0x0D11, 0x0D12, 0x0D13, 0x0D14, 0x0D15, 0x0D16, 0x0D17,
+ 0x0D18, 0x0D19, 0x0D1A, 0x0D1B, 0x0D1C, 0x0D1D, 0x0D1E, 0x0D1F,
+ 0x16F8, 0x16F9, 0x16FA, 0x16FB, 0x16FC, 0x16FD, 0x16FE, 0x16FF,
+ 0x1700, 0x1701, 0x1702, 0x1703, 0x1704, 0x1705, 0x1706, 0x1707,
+ 0x1708, 0x1709, 0x170A, 0x170B, 0x170C, 0x170D, 0x170E, 0x170F,
+ 0x1710, 0x1711, 0x1712, 0x1713, 0x1714, 0x1715, 0x1716, 0x1717,
+ 0x1718, 0x1719, 0x171A, 0x171B, 0x171C, 0x171D, 0x171E, 0x171F,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
+ 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
+ 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
+ 0x0450, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457,
+ 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x045D, 0x045E, 0x045F,
+ 0x0E38, 0x0E39, 0x0E3A, 0x0E3B, 0x0E3C, 0x0E3D, 0x0E3E, 0x0E3F,
+ 0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47,
+ 0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F,
+ 0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57,
+ 0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0x0E5C, 0x0E5D, 0x0E5E, 0x0E5F,
+ 0x1838, 0x1839, 0x183A, 0x183B, 0x183C, 0x183D, 0x183E, 0x183F,
+ 0x1840, 0x1841, 0x1842, 0x1843, 0x1844, 0x1845, 0x1846, 0x1847,
+ 0x1848, 0x1849, 0x184A, 0x184B, 0x184C, 0x184D, 0x184E, 0x184F,
+ 0x1850, 0x1851, 0x1852, 0x1853, 0x1854, 0x1855, 0x1856, 0x1857,
+ 0x1858, 0x1859, 0x185A, 0x185B, 0x185C, 0x185D, 0x185E, 0x185F,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0578, 0x0579, 0x057A, 0x057B, 0x057C, 0x057D, 0x057E, 0x057F,
+ 0x0580, 0x0581, 0x0582, 0x0583, 0x0584, 0x0585, 0x0586, 0x0587,
+ 0x0588, 0x0589, 0x058A, 0x058B, 0x058C, 0x058D, 0x058E, 0x058F,
+ 0x0590, 0x0591, 0x0592, 0x0593, 0x0594, 0x0595, 0x0596, 0x0597,
+ 0x0598, 0x0599, 0x059A, 0x059B, 0x059C, 0x059D, 0x059E, 0x059F,
+ 0x0F78, 0x0F79, 0x0F7A, 0x0F7B, 0x0F7C, 0x0F7D, 0x0F7E, 0x0F7F,
+ 0x0F80, 0x0F81, 0x0F82, 0x0F83, 0x0F84, 0x0F85, 0x0F86, 0x0F87,
+ 0x0F88, 0x0F89, 0x0F8A, 0x0F8B, 0x0F8C, 0x0F8D, 0x0F8E, 0x0F8F,
+ 0x0F90, 0x0F91, 0x0F92, 0x0F93, 0x0F94, 0x0F95, 0x0F96, 0x0F97,
+ 0x0F98, 0x0F99, 0x0F9A, 0x0F9B, 0x0F9C, 0x0F9D, 0x0F9E, 0x0F9F,
+ 0x1978, 0x1979, 0x197A, 0x197B, 0x197C, 0x197D, 0x197E, 0x197F,
+ 0x1980, 0x1981, 0x1982, 0x1983, 0x1984, 0x1985, 0x1986, 0x1987,
+ 0x1988, 0x1989, 0x198A, 0x198B, 0x198C, 0x198D, 0x198E, 0x198F,
+ 0x1990, 0x1991, 0x1992, 0x1993, 0x1994, 0x1995, 0x1996, 0x1997,
+ 0x1998, 0x1999, 0x199A, 0x199B, 0x199C, 0x199D, 0x199E, 0x199F,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x06B8, 0x06B9, 0x06BA, 0x06BB, 0x06BC, 0x06BD, 0x06BE, 0x06BF,
+ 0x06C0, 0x06C1, 0x06C2, 0x06C3, 0x06C4, 0x06C5, 0x06C6, 0x06C7,
+ 0x06C8, 0x06C9, 0x06CA, 0x06CB, 0x06CC, 0x06CD, 0x06CE, 0x06CF,
+ 0x06D0, 0x06D1, 0x06D2, 0x06D3, 0x06D4, 0x06D5, 0x06D6, 0x06D7,
+ 0x06D8, 0x06D9, 0x06DA, 0x06DB, 0x06DC, 0x06DD, 0x06DE, 0x06DF,
+ 0x10B8, 0x10B9, 0x10BA, 0x10BB, 0x10BC, 0x10BD, 0x10BE, 0x10BF,
+ 0x10C0, 0x10C1, 0x10C2, 0x10C3, 0x10C4, 0x10C5, 0x10C6, 0x10C7,
+ 0x10C8, 0x10C9, 0x10CA, 0x10CB, 0x10CC, 0x10CD, 0x10CE, 0x10CF,
+ 0x10D0, 0x10D1, 0x10D2, 0x10D3, 0x10D4, 0x10D5, 0x10D6, 0x10D7,
+ 0x10D8, 0x10D9, 0x10DA, 0x10DB, 0x10DC, 0x10DD, 0x10DE, 0x10DF,
+ 0x1AB8, 0x1AB9, 0x1ABA, 0x1ABB, 0x1ABC, 0x1ABD, 0x1ABE, 0x1ABF,
+ 0x1AC0, 0x1AC1, 0x1AC2, 0x1AC3, 0x1AC4, 0x1AC5, 0x1AC6, 0x1AC7,
+ 0x1AC8, 0x1AC9, 0x1ACA, 0x1ACB, 0x1ACC, 0x1ACD, 0x1ACE, 0x1ACF,
+ 0x1AD0, 0x1AD1, 0x1AD2, 0x1AD3, 0x1AD4, 0x1AD5, 0x1AD6, 0x1AD7,
+ 0x1AD8, 0x1AD9, 0x1ADA, 0x1ADB, 0x1ADC, 0x1ADD, 0x1ADE, 0x1ADF,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x07F8, 0x07F9, 0x07FA, 0x07FB, 0x07FC, 0x07FD, 0x07FE, 0x07FF,
+ 0x0800, 0x0801, 0x0802, 0x0803, 0x0804, 0x0805, 0x0806, 0x0807,
+ 0x0808, 0x0809, 0x080A, 0x080B, 0x080C, 0x080D, 0x080E, 0x080F,
+ 0x0810, 0x0811, 0x0812, 0x0813, 0x0814, 0x0815, 0x0816, 0x0817,
+ 0x0818, 0x0819, 0x081A, 0x081B, 0x081C, 0x081D, 0x081E, 0x081F,
+ 0x11F8, 0x11F9, 0x11FA, 0x11FB, 0x11FC, 0x11FD, 0x11FE, 0x11FF,
+ 0x1200, 0x1201, 0x1202, 0x1203, 0x1204, 0x1205, 0x1206, 0x1207,
+ 0x1208, 0x1209, 0x120A, 0x120B, 0x120C, 0x120D, 0x120E, 0x120F,
+ 0x1210, 0x1211, 0x1212, 0x1213, 0x1214, 0x1215, 0x1216, 0x1217,
+ 0x1218, 0x1219, 0x121A, 0x121B, 0x121C, 0x121D, 0x121E, 0x121F,
+ 0x1BF8, 0x1BF9, 0x1BFA, 0x1BFB, 0x1BFC, 0x1BFD, 0x1BFE, 0x1BFF,
+ 0x1C00, 0x1C01, 0x1C02, 0x1C03, 0x1C04, 0x1C05, 0x1C06, 0x1C07,
+ 0x1C08, 0x1C09, 0x1C0A, 0x1C0B, 0x1C0C, 0x1C0D, 0x1C0E, 0x1C0F,
+ 0x1C10, 0x1C11, 0x1C12, 0x1C13, 0x1C14, 0x1C15, 0x1C16, 0x1C17,
+ 0x1C18, 0x1C19, 0x1C1A, 0x1C1B, 0x1C1C, 0x1C1D, 0x1C1E, 0x1C1F,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0938, 0x0939, 0x093A, 0x093B, 0x093C, 0x093D, 0x093E, 0x093F,
+ 0x0940, 0x0941, 0x0942, 0x0943, 0x0944, 0x0945, 0x0946, 0x0947,
+ 0x0948, 0x0949, 0x094A, 0x094B, 0x094C, 0x094D, 0x094E, 0x094F,
+ 0x0950, 0x0951, 0x0952, 0x0953, 0x0954, 0x0955, 0x0956, 0x0957,
+ 0x0958, 0x0959, 0x095A, 0x095B, 0x095C, 0x095D, 0x095E, 0x095F,
+ 0x1338, 0x1339, 0x133A, 0x133B, 0x133C, 0x133D, 0x133E, 0x133F,
+ 0x1340, 0x1341, 0x1342, 0x1343, 0x1344, 0x1345, 0x1346, 0x1347,
+ 0x1348, 0x1349, 0x134A, 0x134B, 0x134C, 0x134D, 0x134E, 0x134F,
+ 0x1350, 0x1351, 0x1352, 0x1353, 0x1354, 0x1355, 0x1356, 0x1357,
+ 0x1358, 0x1359, 0x135A, 0x135B, 0x135C, 0x135D, 0x135E, 0x135F,
+ 0x1D38, 0x1D39, 0x1D3A, 0x1D3B, 0x1D3C, 0x1D3D, 0x1D3E, 0x1D3F,
+ 0x1D40, 0x1D41, 0x1D42, 0x1D43, 0x1D44, 0x1D45, 0x1D46, 0x1D47,
+ 0x1D48, 0x1D49, 0x1D4A, 0x1D4B, 0x1D4C, 0x1D4D, 0x1D4E, 0x1D4F,
+ 0x1D50, 0x1D51, 0x1D52, 0x1D53, 0x1D54, 0x1D55, 0x1D56, 0x1D57,
+ 0x1D58, 0x1D59, 0x1D5A, 0x1D5B, 0x1D5C, 0x1D5D, 0x1D5E, 0x1D5F,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+ 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
+ 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
+ 0x0AA0, 0x0AA1, 0x0AA2, 0x0AA3, 0x0AA4, 0x0AA5, 0x0AA6, 0x0AA7,
+ 0x0AA8, 0x0AA9, 0x0AAA, 0x0AAB, 0x0AAC, 0x0AAD, 0x0AAE, 0x0AAF,
+ 0x0AB0, 0x0AB1, 0x0AB2, 0x0AB3, 0x0AB4, 0x0AB5, 0x0AB6, 0x0AB7,
+ 0x0AB8, 0x0AB9, 0x0ABA, 0x0ABB, 0x0ABC, 0x0ABD, 0x0ABE, 0x0ABF,
+ 0x0AC0, 0x0AC1, 0x0AC2, 0x0AC3, 0x0AC4, 0x0AC5, 0x0AC6, 0x0AC7,
+ 0x14A0, 0x14A1, 0x14A2, 0x14A3, 0x14A4, 0x14A5, 0x14A6, 0x14A7,
+ 0x14A8, 0x14A9, 0x14AA, 0x14AB, 0x14AC, 0x14AD, 0x14AE, 0x14AF,
+ 0x14B0, 0x14B1, 0x14B2, 0x14B3, 0x14B4, 0x14B5, 0x14B6, 0x14B7,
+ 0x14B8, 0x14B9, 0x14BA, 0x14BB, 0x14BC, 0x14BD, 0x14BE, 0x14BF,
+ 0x14C0, 0x14C1, 0x14C2, 0x14C3, 0x14C4, 0x14C5, 0x14C6, 0x14C7,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x01E0, 0x01E1, 0x01E2, 0x01E3, 0x01E4, 0x01E5, 0x01E6, 0x01E7,
+ 0x01E8, 0x01E9, 0x01EA, 0x01EB, 0x01EC, 0x01ED, 0x01EE, 0x01EF,
+ 0x01F0, 0x01F1, 0x01F2, 0x01F3, 0x01F4, 0x01F5, 0x01F6, 0x01F7,
+ 0x01F8, 0x01F9, 0x01FA, 0x01FB, 0x01FC, 0x01FD, 0x01FE, 0x01FF,
+ 0x0200, 0x0201, 0x0202, 0x0203, 0x0204, 0x0205, 0x0206, 0x0207,
+ 0x0BE0, 0x0BE1, 0x0BE2, 0x0BE3, 0x0BE4, 0x0BE5, 0x0BE6, 0x0BE7,
+ 0x0BE8, 0x0BE9, 0x0BEA, 0x0BEB, 0x0BEC, 0x0BED, 0x0BEE, 0x0BEF,
+ 0x0BF0, 0x0BF1, 0x0BF2, 0x0BF3, 0x0BF4, 0x0BF5, 0x0BF6, 0x0BF7,
+ 0x0BF8, 0x0BF9, 0x0BFA, 0x0BFB, 0x0BFC, 0x0BFD, 0x0BFE, 0x0BFF,
+ 0x0C00, 0x0C01, 0x0C02, 0x0C03, 0x0C04, 0x0C05, 0x0C06, 0x0C07,
+ 0x15E0, 0x15E1, 0x15E2, 0x15E3, 0x15E4, 0x15E5, 0x15E6, 0x15E7,
+ 0x15E8, 0x15E9, 0x15EA, 0x15EB, 0x15EC, 0x15ED, 0x15EE, 0x15EF,
+ 0x15F0, 0x15F1, 0x15F2, 0x15F3, 0x15F4, 0x15F5, 0x15F6, 0x15F7,
+ 0x15F8, 0x15F9, 0x15FA, 0x15FB, 0x15FC, 0x15FD, 0x15FE, 0x15FF,
+ 0x1600, 0x1601, 0x1602, 0x1603, 0x1604, 0x1605, 0x1606, 0x1607,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0320, 0x0321, 0x0322, 0x0323, 0x0324, 0x0325, 0x0326, 0x0327,
+ 0x0328, 0x0329, 0x032A, 0x032B, 0x032C, 0x032D, 0x032E, 0x032F,
+ 0x0330, 0x0331, 0x0332, 0x0333, 0x0334, 0x0335, 0x0336, 0x0337,
+ 0x0338, 0x0339, 0x033A, 0x033B, 0x033C, 0x033D, 0x033E, 0x033F,
+ 0x0340, 0x0341, 0x0342, 0x0343, 0x0344, 0x0345, 0x0346, 0x0347,
+ 0x0D20, 0x0D21, 0x0D22, 0x0D23, 0x0D24, 0x0D25, 0x0D26, 0x0D27,
+ 0x0D28, 0x0D29, 0x0D2A, 0x0D2B, 0x0D2C, 0x0D2D, 0x0D2E, 0x0D2F,
+ 0x0D30, 0x0D31, 0x0D32, 0x0D33, 0x0D34, 0x0D35, 0x0D36, 0x0D37,
+ 0x0D38, 0x0D39, 0x0D3A, 0x0D3B, 0x0D3C, 0x0D3D, 0x0D3E, 0x0D3F,
+ 0x0D40, 0x0D41, 0x0D42, 0x0D43, 0x0D44, 0x0D45, 0x0D46, 0x0D47,
+ 0x1720, 0x1721, 0x1722, 0x1723, 0x1724, 0x1725, 0x1726, 0x1727,
+ 0x1728, 0x1729, 0x172A, 0x172B, 0x172C, 0x172D, 0x172E, 0x172F,
+ 0x1730, 0x1731, 0x1732, 0x1733, 0x1734, 0x1735, 0x1736, 0x1737,
+ 0x1738, 0x1739, 0x173A, 0x173B, 0x173C, 0x173D, 0x173E, 0x173F,
+ 0x1740, 0x1741, 0x1742, 0x1743, 0x1744, 0x1745, 0x1746, 0x1747,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0460, 0x0461, 0x0462, 0x0463, 0x0464, 0x0465, 0x0466, 0x0467,
+ 0x0468, 0x0469, 0x046A, 0x046B, 0x046C, 0x046D, 0x046E, 0x046F,
+ 0x0470, 0x0471, 0x0472, 0x0473, 0x0474, 0x0475, 0x0476, 0x0477,
+ 0x0478, 0x0479, 0x047A, 0x047B, 0x047C, 0x047D, 0x047E, 0x047F,
+ 0x0480, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x0487,
+ 0x0E60, 0x0E61, 0x0E62, 0x0E63, 0x0E64, 0x0E65, 0x0E66, 0x0E67,
+ 0x0E68, 0x0E69, 0x0E6A, 0x0E6B, 0x0E6C, 0x0E6D, 0x0E6E, 0x0E6F,
+ 0x0E70, 0x0E71, 0x0E72, 0x0E73, 0x0E74, 0x0E75, 0x0E76, 0x0E77,
+ 0x0E78, 0x0E79, 0x0E7A, 0x0E7B, 0x0E7C, 0x0E7D, 0x0E7E, 0x0E7F,
+ 0x0E80, 0x0E81, 0x0E82, 0x0E83, 0x0E84, 0x0E85, 0x0E86, 0x0E87,
+ 0x1860, 0x1861, 0x1862, 0x1863, 0x1864, 0x1865, 0x1866, 0x1867,
+ 0x1868, 0x1869, 0x186A, 0x186B, 0x186C, 0x186D, 0x186E, 0x186F,
+ 0x1870, 0x1871, 0x1872, 0x1873, 0x1874, 0x1875, 0x1876, 0x1877,
+ 0x1878, 0x1879, 0x187A, 0x187B, 0x187C, 0x187D, 0x187E, 0x187F,
+ 0x1880, 0x1881, 0x1882, 0x1883, 0x1884, 0x1885, 0x1886, 0x1887,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x05A0, 0x05A1, 0x05A2, 0x05A3, 0x05A4, 0x05A5, 0x05A6, 0x05A7,
+ 0x05A8, 0x05A9, 0x05AA, 0x05AB, 0x05AC, 0x05AD, 0x05AE, 0x05AF,
+ 0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7,
+ 0x05B8, 0x05B9, 0x05BA, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF,
+ 0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05C4, 0x05C5, 0x05C6, 0x05C7,
+ 0x0FA0, 0x0FA1, 0x0FA2, 0x0FA3, 0x0FA4, 0x0FA5, 0x0FA6, 0x0FA7,
+ 0x0FA8, 0x0FA9, 0x0FAA, 0x0FAB, 0x0FAC, 0x0FAD, 0x0FAE, 0x0FAF,
+ 0x0FB0, 0x0FB1, 0x0FB2, 0x0FB3, 0x0FB4, 0x0FB5, 0x0FB6, 0x0FB7,
+ 0x0FB8, 0x0FB9, 0x0FBA, 0x0FBB, 0x0FBC, 0x0FBD, 0x0FBE, 0x0FBF,
+ 0x0FC0, 0x0FC1, 0x0FC2, 0x0FC3, 0x0FC4, 0x0FC5, 0x0FC6, 0x0FC7,
+ 0x19A0, 0x19A1, 0x19A2, 0x19A3, 0x19A4, 0x19A5, 0x19A6, 0x19A7,
+ 0x19A8, 0x19A9, 0x19AA, 0x19AB, 0x19AC, 0x19AD, 0x19AE, 0x19AF,
+ 0x19B0, 0x19B1, 0x19B2, 0x19B3, 0x19B4, 0x19B5, 0x19B6, 0x19B7,
+ 0x19B8, 0x19B9, 0x19BA, 0x19BB, 0x19BC, 0x19BD, 0x19BE, 0x19BF,
+ 0x19C0, 0x19C1, 0x19C2, 0x19C3, 0x19C4, 0x19C5, 0x19C6, 0x19C7,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x06E0, 0x06E1, 0x06E2, 0x06E3, 0x06E4, 0x06E5, 0x06E6, 0x06E7,
+ 0x06E8, 0x06E9, 0x06EA, 0x06EB, 0x06EC, 0x06ED, 0x06EE, 0x06EF,
+ 0x06F0, 0x06F1, 0x06F2, 0x06F3, 0x06F4, 0x06F5, 0x06F6, 0x06F7,
+ 0x06F8, 0x06F9, 0x06FA, 0x06FB, 0x06FC, 0x06FD, 0x06FE, 0x06FF,
+ 0x0700, 0x0701, 0x0702, 0x0703, 0x0704, 0x0705, 0x0706, 0x0707,
+ 0x10E0, 0x10E1, 0x10E2, 0x10E3, 0x10E4, 0x10E5, 0x10E6, 0x10E7,
+ 0x10E8, 0x10E9, 0x10EA, 0x10EB, 0x10EC, 0x10ED, 0x10EE, 0x10EF,
+ 0x10F0, 0x10F1, 0x10F2, 0x10F3, 0x10F4, 0x10F5, 0x10F6, 0x10F7,
+ 0x10F8, 0x10F9, 0x10FA, 0x10FB, 0x10FC, 0x10FD, 0x10FE, 0x10FF,
+ 0x1100, 0x1101, 0x1102, 0x1103, 0x1104, 0x1105, 0x1106, 0x1107,
+ 0x1AE0, 0x1AE1, 0x1AE2, 0x1AE3, 0x1AE4, 0x1AE5, 0x1AE6, 0x1AE7,
+ 0x1AE8, 0x1AE9, 0x1AEA, 0x1AEB, 0x1AEC, 0x1AED, 0x1AEE, 0x1AEF,
+ 0x1AF0, 0x1AF1, 0x1AF2, 0x1AF3, 0x1AF4, 0x1AF5, 0x1AF6, 0x1AF7,
+ 0x1AF8, 0x1AF9, 0x1AFA, 0x1AFB, 0x1AFC, 0x1AFD, 0x1AFE, 0x1AFF,
+ 0x1B00, 0x1B01, 0x1B02, 0x1B03, 0x1B04, 0x1B05, 0x1B06, 0x1B07,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0820, 0x0821, 0x0822, 0x0823, 0x0824, 0x0825, 0x0826, 0x0827,
+ 0x0828, 0x0829, 0x082A, 0x082B, 0x082C, 0x082D, 0x082E, 0x082F,
+ 0x0830, 0x0831, 0x0832, 0x0833, 0x0834, 0x0835, 0x0836, 0x0837,
+ 0x0838, 0x0839, 0x083A, 0x083B, 0x083C, 0x083D, 0x083E, 0x083F,
+ 0x0840, 0x0841, 0x0842, 0x0843, 0x0844, 0x0845, 0x0846, 0x0847,
+ 0x1220, 0x1221, 0x1222, 0x1223, 0x1224, 0x1225, 0x1226, 0x1227,
+ 0x1228, 0x1229, 0x122A, 0x122B, 0x122C, 0x122D, 0x122E, 0x122F,
+ 0x1230, 0x1231, 0x1232, 0x1233, 0x1234, 0x1235, 0x1236, 0x1237,
+ 0x1238, 0x1239, 0x123A, 0x123B, 0x123C, 0x123D, 0x123E, 0x123F,
+ 0x1240, 0x1241, 0x1242, 0x1243, 0x1244, 0x1245, 0x1246, 0x1247,
+ 0x1C20, 0x1C21, 0x1C22, 0x1C23, 0x1C24, 0x1C25, 0x1C26, 0x1C27,
+ 0x1C28, 0x1C29, 0x1C2A, 0x1C2B, 0x1C2C, 0x1C2D, 0x1C2E, 0x1C2F,
+ 0x1C30, 0x1C31, 0x1C32, 0x1C33, 0x1C34, 0x1C35, 0x1C36, 0x1C37,
+ 0x1C38, 0x1C39, 0x1C3A, 0x1C3B, 0x1C3C, 0x1C3D, 0x1C3E, 0x1C3F,
+ 0x1C40, 0x1C41, 0x1C42, 0x1C43, 0x1C44, 0x1C45, 0x1C46, 0x1C47,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0960, 0x0961, 0x0962, 0x0963, 0x0964, 0x0965, 0x0966, 0x0967,
+ 0x0968, 0x0969, 0x096A, 0x096B, 0x096C, 0x096D, 0x096E, 0x096F,
+ 0x0970, 0x0971, 0x0972, 0x0973, 0x0974, 0x0975, 0x0976, 0x0977,
+ 0x0978, 0x0979, 0x097A, 0x097B, 0x097C, 0x097D, 0x097E, 0x097F,
+ 0x0980, 0x0981, 0x0982, 0x0983, 0x0984, 0x0985, 0x0986, 0x0987,
+ 0x1360, 0x1361, 0x1362, 0x1363, 0x1364, 0x1365, 0x1366, 0x1367,
+ 0x1368, 0x1369, 0x136A, 0x136B, 0x136C, 0x136D, 0x136E, 0x136F,
+ 0x1370, 0x1371, 0x1372, 0x1373, 0x1374, 0x1375, 0x1376, 0x1377,
+ 0x1378, 0x1379, 0x137A, 0x137B, 0x137C, 0x137D, 0x137E, 0x137F,
+ 0x1380, 0x1381, 0x1382, 0x1383, 0x1384, 0x1385, 0x1386, 0x1387,
+ 0x1D60, 0x1D61, 0x1D62, 0x1D63, 0x1D64, 0x1D65, 0x1D66, 0x1D67,
+ 0x1D68, 0x1D69, 0x1D6A, 0x1D6B, 0x1D6C, 0x1D6D, 0x1D6E, 0x1D6F,
+ 0x1D70, 0x1D71, 0x1D72, 0x1D73, 0x1D74, 0x1D75, 0x1D76, 0x1D77,
+ 0x1D78, 0x1D79, 0x1D7A, 0x1D7B, 0x1D7C, 0x1D7D, 0x1D7E, 0x1D7F,
+ 0x1D80, 0x1D81, 0x1D82, 0x1D83, 0x1D84, 0x1D85, 0x1D86, 0x1D87,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
+ 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
+ 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
+ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
+ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
+ 0x0AC8, 0x0AC9, 0x0ACA, 0x0ACB, 0x0ACC, 0x0ACD, 0x0ACE, 0x0ACF,
+ 0x0AD0, 0x0AD1, 0x0AD2, 0x0AD3, 0x0AD4, 0x0AD5, 0x0AD6, 0x0AD7,
+ 0x0AD8, 0x0AD9, 0x0ADA, 0x0ADB, 0x0ADC, 0x0ADD, 0x0ADE, 0x0ADF,
+ 0x0AE0, 0x0AE1, 0x0AE2, 0x0AE3, 0x0AE4, 0x0AE5, 0x0AE6, 0x0AE7,
+ 0x0AE8, 0x0AE9, 0x0AEA, 0x0AEB, 0x0AEC, 0x0AED, 0x0AEE, 0x0AEF,
+ 0x14C8, 0x14C9, 0x14CA, 0x14CB, 0x14CC, 0x14CD, 0x14CE, 0x14CF,
+ 0x14D0, 0x14D1, 0x14D2, 0x14D3, 0x14D4, 0x14D5, 0x14D6, 0x14D7,
+ 0x14D8, 0x14D9, 0x14DA, 0x14DB, 0x14DC, 0x14DD, 0x14DE, 0x14DF,
+ 0x14E0, 0x14E1, 0x14E2, 0x14E3, 0x14E4, 0x14E5, 0x14E6, 0x14E7,
+ 0x14E8, 0x14E9, 0x14EA, 0x14EB, 0x14EC, 0x14ED, 0x14EE, 0x14EF,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0208, 0x0209, 0x020A, 0x020B, 0x020C, 0x020D, 0x020E, 0x020F,
+ 0x0210, 0x0211, 0x0212, 0x0213, 0x0214, 0x0215, 0x0216, 0x0217,
+ 0x0218, 0x0219, 0x021A, 0x021B, 0x021C, 0x021D, 0x021E, 0x021F,
+ 0x0220, 0x0221, 0x0222, 0x0223, 0x0224, 0x0225, 0x0226, 0x0227,
+ 0x0228, 0x0229, 0x022A, 0x022B, 0x022C, 0x022D, 0x022E, 0x022F,
+ 0x0C08, 0x0C09, 0x0C0A, 0x0C0B, 0x0C0C, 0x0C0D, 0x0C0E, 0x0C0F,
+ 0x0C10, 0x0C11, 0x0C12, 0x0C13, 0x0C14, 0x0C15, 0x0C16, 0x0C17,
+ 0x0C18, 0x0C19, 0x0C1A, 0x0C1B, 0x0C1C, 0x0C1D, 0x0C1E, 0x0C1F,
+ 0x0C20, 0x0C21, 0x0C22, 0x0C23, 0x0C24, 0x0C25, 0x0C26, 0x0C27,
+ 0x0C28, 0x0C29, 0x0C2A, 0x0C2B, 0x0C2C, 0x0C2D, 0x0C2E, 0x0C2F,
+ 0x1608, 0x1609, 0x160A, 0x160B, 0x160C, 0x160D, 0x160E, 0x160F,
+ 0x1610, 0x1611, 0x1612, 0x1613, 0x1614, 0x1615, 0x1616, 0x1617,
+ 0x1618, 0x1619, 0x161A, 0x161B, 0x161C, 0x161D, 0x161E, 0x161F,
+ 0x1620, 0x1621, 0x1622, 0x1623, 0x1624, 0x1625, 0x1626, 0x1627,
+ 0x1628, 0x1629, 0x162A, 0x162B, 0x162C, 0x162D, 0x162E, 0x162F,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0348, 0x0349, 0x034A, 0x034B, 0x034C, 0x034D, 0x034E, 0x034F,
+ 0x0350, 0x0351, 0x0352, 0x0353, 0x0354, 0x0355, 0x0356, 0x0357,
+ 0x0358, 0x0359, 0x035A, 0x035B, 0x035C, 0x035D, 0x035E, 0x035F,
+ 0x0360, 0x0361, 0x0362, 0x0363, 0x0364, 0x0365, 0x0366, 0x0367,
+ 0x0368, 0x0369, 0x036A, 0x036B, 0x036C, 0x036D, 0x036E, 0x036F,
+ 0x0D48, 0x0D49, 0x0D4A, 0x0D4B, 0x0D4C, 0x0D4D, 0x0D4E, 0x0D4F,
+ 0x0D50, 0x0D51, 0x0D52, 0x0D53, 0x0D54, 0x0D55, 0x0D56, 0x0D57,
+ 0x0D58, 0x0D59, 0x0D5A, 0x0D5B, 0x0D5C, 0x0D5D, 0x0D5E, 0x0D5F,
+ 0x0D60, 0x0D61, 0x0D62, 0x0D63, 0x0D64, 0x0D65, 0x0D66, 0x0D67,
+ 0x0D68, 0x0D69, 0x0D6A, 0x0D6B, 0x0D6C, 0x0D6D, 0x0D6E, 0x0D6F,
+ 0x1748, 0x1749, 0x174A, 0x174B, 0x174C, 0x174D, 0x174E, 0x174F,
+ 0x1750, 0x1751, 0x1752, 0x1753, 0x1754, 0x1755, 0x1756, 0x1757,
+ 0x1758, 0x1759, 0x175A, 0x175B, 0x175C, 0x175D, 0x175E, 0x175F,
+ 0x1760, 0x1761, 0x1762, 0x1763, 0x1764, 0x1765, 0x1766, 0x1767,
+ 0x1768, 0x1769, 0x176A, 0x176B, 0x176C, 0x176D, 0x176E, 0x176F,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0488, 0x0489, 0x048A, 0x048B, 0x048C, 0x048D, 0x048E, 0x048F,
+ 0x0490, 0x0491, 0x0492, 0x0493, 0x0494, 0x0495, 0x0496, 0x0497,
+ 0x0498, 0x0499, 0x049A, 0x049B, 0x049C, 0x049D, 0x049E, 0x049F,
+ 0x04A0, 0x04A1, 0x04A2, 0x04A3, 0x04A4, 0x04A5, 0x04A6, 0x04A7,
+ 0x04A8, 0x04A9, 0x04AA, 0x04AB, 0x04AC, 0x04AD, 0x04AE, 0x04AF,
+ 0x0E88, 0x0E89, 0x0E8A, 0x0E8B, 0x0E8C, 0x0E8D, 0x0E8E, 0x0E8F,
+ 0x0E90, 0x0E91, 0x0E92, 0x0E93, 0x0E94, 0x0E95, 0x0E96, 0x0E97,
+ 0x0E98, 0x0E99, 0x0E9A, 0x0E9B, 0x0E9C, 0x0E9D, 0x0E9E, 0x0E9F,
+ 0x0EA0, 0x0EA1, 0x0EA2, 0x0EA3, 0x0EA4, 0x0EA5, 0x0EA6, 0x0EA7,
+ 0x0EA8, 0x0EA9, 0x0EAA, 0x0EAB, 0x0EAC, 0x0EAD, 0x0EAE, 0x0EAF,
+ 0x1888, 0x1889, 0x188A, 0x188B, 0x188C, 0x188D, 0x188E, 0x188F,
+ 0x1890, 0x1891, 0x1892, 0x1893, 0x1894, 0x1895, 0x1896, 0x1897,
+ 0x1898, 0x1899, 0x189A, 0x189B, 0x189C, 0x189D, 0x189E, 0x189F,
+ 0x18A0, 0x18A1, 0x18A2, 0x18A3, 0x18A4, 0x18A5, 0x18A6, 0x18A7,
+ 0x18A8, 0x18A9, 0x18AA, 0x18AB, 0x18AC, 0x18AD, 0x18AE, 0x18AF,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x05C8, 0x05C9, 0x05CA, 0x05CB, 0x05CC, 0x05CD, 0x05CE, 0x05CF,
+ 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
+ 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
+ 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
+ 0x05E8, 0x05E9, 0x05EA, 0x05EB, 0x05EC, 0x05ED, 0x05EE, 0x05EF,
+ 0x0FC8, 0x0FC9, 0x0FCA, 0x0FCB, 0x0FCC, 0x0FCD, 0x0FCE, 0x0FCF,
+ 0x0FD0, 0x0FD1, 0x0FD2, 0x0FD3, 0x0FD4, 0x0FD5, 0x0FD6, 0x0FD7,
+ 0x0FD8, 0x0FD9, 0x0FDA, 0x0FDB, 0x0FDC, 0x0FDD, 0x0FDE, 0x0FDF,
+ 0x0FE0, 0x0FE1, 0x0FE2, 0x0FE3, 0x0FE4, 0x0FE5, 0x0FE6, 0x0FE7,
+ 0x0FE8, 0x0FE9, 0x0FEA, 0x0FEB, 0x0FEC, 0x0FED, 0x0FEE, 0x0FEF,
+ 0x19C8, 0x19C9, 0x19CA, 0x19CB, 0x19CC, 0x19CD, 0x19CE, 0x19CF,
+ 0x19D0, 0x19D1, 0x19D2, 0x19D3, 0x19D4, 0x19D5, 0x19D6, 0x19D7,
+ 0x19D8, 0x19D9, 0x19DA, 0x19DB, 0x19DC, 0x19DD, 0x19DE, 0x19DF,
+ 0x19E0, 0x19E1, 0x19E2, 0x19E3, 0x19E4, 0x19E5, 0x19E6, 0x19E7,
+ 0x19E8, 0x19E9, 0x19EA, 0x19EB, 0x19EC, 0x19ED, 0x19EE, 0x19EF,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0708, 0x0709, 0x070A, 0x070B, 0x070C, 0x070D, 0x070E, 0x070F,
+ 0x0710, 0x0711, 0x0712, 0x0713, 0x0714, 0x0715, 0x0716, 0x0717,
+ 0x0718, 0x0719, 0x071A, 0x071B, 0x071C, 0x071D, 0x071E, 0x071F,
+ 0x0720, 0x0721, 0x0722, 0x0723, 0x0724, 0x0725, 0x0726, 0x0727,
+ 0x0728, 0x0729, 0x072A, 0x072B, 0x072C, 0x072D, 0x072E, 0x072F,
+ 0x1108, 0x1109, 0x110A, 0x110B, 0x110C, 0x110D, 0x110E, 0x110F,
+ 0x1110, 0x1111, 0x1112, 0x1113, 0x1114, 0x1115, 0x1116, 0x1117,
+ 0x1118, 0x1119, 0x111A, 0x111B, 0x111C, 0x111D, 0x111E, 0x111F,
+ 0x1120, 0x1121, 0x1122, 0x1123, 0x1124, 0x1125, 0x1126, 0x1127,
+ 0x1128, 0x1129, 0x112A, 0x112B, 0x112C, 0x112D, 0x112E, 0x112F,
+ 0x1B08, 0x1B09, 0x1B0A, 0x1B0B, 0x1B0C, 0x1B0D, 0x1B0E, 0x1B0F,
+ 0x1B10, 0x1B11, 0x1B12, 0x1B13, 0x1B14, 0x1B15, 0x1B16, 0x1B17,
+ 0x1B18, 0x1B19, 0x1B1A, 0x1B1B, 0x1B1C, 0x1B1D, 0x1B1E, 0x1B1F,
+ 0x1B20, 0x1B21, 0x1B22, 0x1B23, 0x1B24, 0x1B25, 0x1B26, 0x1B27,
+ 0x1B28, 0x1B29, 0x1B2A, 0x1B2B, 0x1B2C, 0x1B2D, 0x1B2E, 0x1B2F,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0848, 0x0849, 0x084A, 0x084B, 0x084C, 0x084D, 0x084E, 0x084F,
+ 0x0850, 0x0851, 0x0852, 0x0853, 0x0854, 0x0855, 0x0856, 0x0857,
+ 0x0858, 0x0859, 0x085A, 0x085B, 0x085C, 0x085D, 0x085E, 0x085F,
+ 0x0860, 0x0861, 0x0862, 0x0863, 0x0864, 0x0865, 0x0866, 0x0867,
+ 0x0868, 0x0869, 0x086A, 0x086B, 0x086C, 0x086D, 0x086E, 0x086F,
+ 0x1248, 0x1249, 0x124A, 0x124B, 0x124C, 0x124D, 0x124E, 0x124F,
+ 0x1250, 0x1251, 0x1252, 0x1253, 0x1254, 0x1255, 0x1256, 0x1257,
+ 0x1258, 0x1259, 0x125A, 0x125B, 0x125C, 0x125D, 0x125E, 0x125F,
+ 0x1260, 0x1261, 0x1262, 0x1263, 0x1264, 0x1265, 0x1266, 0x1267,
+ 0x1268, 0x1269, 0x126A, 0x126B, 0x126C, 0x126D, 0x126E, 0x126F,
+ 0x1C48, 0x1C49, 0x1C4A, 0x1C4B, 0x1C4C, 0x1C4D, 0x1C4E, 0x1C4F,
+ 0x1C50, 0x1C51, 0x1C52, 0x1C53, 0x1C54, 0x1C55, 0x1C56, 0x1C57,
+ 0x1C58, 0x1C59, 0x1C5A, 0x1C5B, 0x1C5C, 0x1C5D, 0x1C5E, 0x1C5F,
+ 0x1C60, 0x1C61, 0x1C62, 0x1C63, 0x1C64, 0x1C65, 0x1C66, 0x1C67,
+ 0x1C68, 0x1C69, 0x1C6A, 0x1C6B, 0x1C6C, 0x1C6D, 0x1C6E, 0x1C6F,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0988, 0x0989, 0x098A, 0x098B, 0x098C, 0x098D, 0x098E, 0x098F,
+ 0x0990, 0x0991, 0x0992, 0x0993, 0x0994, 0x0995, 0x0996, 0x0997,
+ 0x0998, 0x0999, 0x099A, 0x099B, 0x099C, 0x099D, 0x099E, 0x099F,
+ 0x09A0, 0x09A1, 0x09A2, 0x09A3, 0x09A4, 0x09A5, 0x09A6, 0x09A7,
+ 0x09A8, 0x09A9, 0x09AA, 0x09AB, 0x09AC, 0x09AD, 0x09AE, 0x09AF,
+ 0x1388, 0x1389, 0x138A, 0x138B, 0x138C, 0x138D, 0x138E, 0x138F,
+ 0x1390, 0x1391, 0x1392, 0x1393, 0x1394, 0x1395, 0x1396, 0x1397,
+ 0x1398, 0x1399, 0x139A, 0x139B, 0x139C, 0x139D, 0x139E, 0x139F,
+ 0x13A0, 0x13A1, 0x13A2, 0x13A3, 0x13A4, 0x13A5, 0x13A6, 0x13A7,
+ 0x13A8, 0x13A9, 0x13AA, 0x13AB, 0x13AC, 0x13AD, 0x13AE, 0x13AF,
+ 0x1D88, 0x1D89, 0x1D8A, 0x1D8B, 0x1D8C, 0x1D8D, 0x1D8E, 0x1D8F,
+ 0x1D90, 0x1D91, 0x1D92, 0x1D93, 0x1D94, 0x1D95, 0x1D96, 0x1D97,
+ 0x1D98, 0x1D99, 0x1D9A, 0x1D9B, 0x1D9C, 0x1D9D, 0x1D9E, 0x1D9F,
+ 0x1DA0, 0x1DA1, 0x1DA2, 0x1DA3, 0x1DA4, 0x1DA5, 0x1DA6, 0x1DA7,
+ 0x1DA8, 0x1DA9, 0x1DAA, 0x1DAB, 0x1DAC, 0x1DAD, 0x1DAE, 0x1DAF,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
+ 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF,
+ 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, 0x0107,
+ 0x0108, 0x0109, 0x010A, 0x010B, 0x010C, 0x010D, 0x010E, 0x010F,
+ 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116, 0x0117,
+ 0x0AF0, 0x0AF1, 0x0AF2, 0x0AF3, 0x0AF4, 0x0AF5, 0x0AF6, 0x0AF7,
+ 0x0AF8, 0x0AF9, 0x0AFA, 0x0AFB, 0x0AFC, 0x0AFD, 0x0AFE, 0x0AFF,
+ 0x0B00, 0x0B01, 0x0B02, 0x0B03, 0x0B04, 0x0B05, 0x0B06, 0x0B07,
+ 0x0B08, 0x0B09, 0x0B0A, 0x0B0B, 0x0B0C, 0x0B0D, 0x0B0E, 0x0B0F,
+ 0x0B10, 0x0B11, 0x0B12, 0x0B13, 0x0B14, 0x0B15, 0x0B16, 0x0B17,
+ 0x14F0, 0x14F1, 0x14F2, 0x14F3, 0x14F4, 0x14F5, 0x14F6, 0x14F7,
+ 0x14F8, 0x14F9, 0x14FA, 0x14FB, 0x14FC, 0x14FD, 0x14FE, 0x14FF,
+ 0x1500, 0x1501, 0x1502, 0x1503, 0x1504, 0x1505, 0x1506, 0x1507,
+ 0x1508, 0x1509, 0x150A, 0x150B, 0x150C, 0x150D, 0x150E, 0x150F,
+ 0x1510, 0x1511, 0x1512, 0x1513, 0x1514, 0x1515, 0x1516, 0x1517,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0230, 0x0231, 0x0232, 0x0233, 0x0234, 0x0235, 0x0236, 0x0237,
+ 0x0238, 0x0239, 0x023A, 0x023B, 0x023C, 0x023D, 0x023E, 0x023F,
+ 0x0240, 0x0241, 0x0242, 0x0243, 0x0244, 0x0245, 0x0246, 0x0247,
+ 0x0248, 0x0249, 0x024A, 0x024B, 0x024C, 0x024D, 0x024E, 0x024F,
+ 0x0250, 0x0251, 0x0252, 0x0253, 0x0254, 0x0255, 0x0256, 0x0257,
+ 0x0C30, 0x0C31, 0x0C32, 0x0C33, 0x0C34, 0x0C35, 0x0C36, 0x0C37,
+ 0x0C38, 0x0C39, 0x0C3A, 0x0C3B, 0x0C3C, 0x0C3D, 0x0C3E, 0x0C3F,
+ 0x0C40, 0x0C41, 0x0C42, 0x0C43, 0x0C44, 0x0C45, 0x0C46, 0x0C47,
+ 0x0C48, 0x0C49, 0x0C4A, 0x0C4B, 0x0C4C, 0x0C4D, 0x0C4E, 0x0C4F,
+ 0x0C50, 0x0C51, 0x0C52, 0x0C53, 0x0C54, 0x0C55, 0x0C56, 0x0C57,
+ 0x1630, 0x1631, 0x1632, 0x1633, 0x1634, 0x1635, 0x1636, 0x1637,
+ 0x1638, 0x1639, 0x163A, 0x163B, 0x163C, 0x163D, 0x163E, 0x163F,
+ 0x1640, 0x1641, 0x1642, 0x1643, 0x1644, 0x1645, 0x1646, 0x1647,
+ 0x1648, 0x1649, 0x164A, 0x164B, 0x164C, 0x164D, 0x164E, 0x164F,
+ 0x1650, 0x1651, 0x1652, 0x1653, 0x1654, 0x1655, 0x1656, 0x1657,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0370, 0x0371, 0x0372, 0x0373, 0x0374, 0x0375, 0x0376, 0x0377,
+ 0x0378, 0x0379, 0x037A, 0x037B, 0x037C, 0x037D, 0x037E, 0x037F,
+ 0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0386, 0x0387,
+ 0x0388, 0x0389, 0x038A, 0x038B, 0x038C, 0x038D, 0x038E, 0x038F,
+ 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
+ 0x0D70, 0x0D71, 0x0D72, 0x0D73, 0x0D74, 0x0D75, 0x0D76, 0x0D77,
+ 0x0D78, 0x0D79, 0x0D7A, 0x0D7B, 0x0D7C, 0x0D7D, 0x0D7E, 0x0D7F,
+ 0x0D80, 0x0D81, 0x0D82, 0x0D83, 0x0D84, 0x0D85, 0x0D86, 0x0D87,
+ 0x0D88, 0x0D89, 0x0D8A, 0x0D8B, 0x0D8C, 0x0D8D, 0x0D8E, 0x0D8F,
+ 0x0D90, 0x0D91, 0x0D92, 0x0D93, 0x0D94, 0x0D95, 0x0D96, 0x0D97,
+ 0x1770, 0x1771, 0x1772, 0x1773, 0x1774, 0x1775, 0x1776, 0x1777,
+ 0x1778, 0x1779, 0x177A, 0x177B, 0x177C, 0x177D, 0x177E, 0x177F,
+ 0x1780, 0x1781, 0x1782, 0x1783, 0x1784, 0x1785, 0x1786, 0x1787,
+ 0x1788, 0x1789, 0x178A, 0x178B, 0x178C, 0x178D, 0x178E, 0x178F,
+ 0x1790, 0x1791, 0x1792, 0x1793, 0x1794, 0x1795, 0x1796, 0x1797,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x04B0, 0x04B1, 0x04B2, 0x04B3, 0x04B4, 0x04B5, 0x04B6, 0x04B7,
+ 0x04B8, 0x04B9, 0x04BA, 0x04BB, 0x04BC, 0x04BD, 0x04BE, 0x04BF,
+ 0x04C0, 0x04C1, 0x04C2, 0x04C3, 0x04C4, 0x04C5, 0x04C6, 0x04C7,
+ 0x04C8, 0x04C9, 0x04CA, 0x04CB, 0x04CC, 0x04CD, 0x04CE, 0x04CF,
+ 0x04D0, 0x04D1, 0x04D2, 0x04D3, 0x04D4, 0x04D5, 0x04D6, 0x04D7,
+ 0x0EB0, 0x0EB1, 0x0EB2, 0x0EB3, 0x0EB4, 0x0EB5, 0x0EB6, 0x0EB7,
+ 0x0EB8, 0x0EB9, 0x0EBA, 0x0EBB, 0x0EBC, 0x0EBD, 0x0EBE, 0x0EBF,
+ 0x0EC0, 0x0EC1, 0x0EC2, 0x0EC3, 0x0EC4, 0x0EC5, 0x0EC6, 0x0EC7,
+ 0x0EC8, 0x0EC9, 0x0ECA, 0x0ECB, 0x0ECC, 0x0ECD, 0x0ECE, 0x0ECF,
+ 0x0ED0, 0x0ED1, 0x0ED2, 0x0ED3, 0x0ED4, 0x0ED5, 0x0ED6, 0x0ED7,
+ 0x18B0, 0x18B1, 0x18B2, 0x18B3, 0x18B4, 0x18B5, 0x18B6, 0x18B7,
+ 0x18B8, 0x18B9, 0x18BA, 0x18BB, 0x18BC, 0x18BD, 0x18BE, 0x18BF,
+ 0x18C0, 0x18C1, 0x18C2, 0x18C3, 0x18C4, 0x18C5, 0x18C6, 0x18C7,
+ 0x18C8, 0x18C9, 0x18CA, 0x18CB, 0x18CC, 0x18CD, 0x18CE, 0x18CF,
+ 0x18D0, 0x18D1, 0x18D2, 0x18D3, 0x18D4, 0x18D5, 0x18D6, 0x18D7,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x05F0, 0x05F1, 0x05F2, 0x05F3, 0x05F4, 0x05F5, 0x05F6, 0x05F7,
+ 0x05F8, 0x05F9, 0x05FA, 0x05FB, 0x05FC, 0x05FD, 0x05FE, 0x05FF,
+ 0x0600, 0x0601, 0x0602, 0x0603, 0x0604, 0x0605, 0x0606, 0x0607,
+ 0x0608, 0x0609, 0x060A, 0x060B, 0x060C, 0x060D, 0x060E, 0x060F,
+ 0x0610, 0x0611, 0x0612, 0x0613, 0x0614, 0x0615, 0x0616, 0x0617,
+ 0x0FF0, 0x0FF1, 0x0FF2, 0x0FF3, 0x0FF4, 0x0FF5, 0x0FF6, 0x0FF7,
+ 0x0FF8, 0x0FF9, 0x0FFA, 0x0FFB, 0x0FFC, 0x0FFD, 0x0FFE, 0x0FFF,
+ 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 0x1007,
+ 0x1008, 0x1009, 0x100A, 0x100B, 0x100C, 0x100D, 0x100E, 0x100F,
+ 0x1010, 0x1011, 0x1012, 0x1013, 0x1014, 0x1015, 0x1016, 0x1017,
+ 0x19F0, 0x19F1, 0x19F2, 0x19F3, 0x19F4, 0x19F5, 0x19F6, 0x19F7,
+ 0x19F8, 0x19F9, 0x19FA, 0x19FB, 0x19FC, 0x19FD, 0x19FE, 0x19FF,
+ 0x1A00, 0x1A01, 0x1A02, 0x1A03, 0x1A04, 0x1A05, 0x1A06, 0x1A07,
+ 0x1A08, 0x1A09, 0x1A0A, 0x1A0B, 0x1A0C, 0x1A0D, 0x1A0E, 0x1A0F,
+ 0x1A10, 0x1A11, 0x1A12, 0x1A13, 0x1A14, 0x1A15, 0x1A16, 0x1A17,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0730, 0x0731, 0x0732, 0x0733, 0x0734, 0x0735, 0x0736, 0x0737,
+ 0x0738, 0x0739, 0x073A, 0x073B, 0x073C, 0x073D, 0x073E, 0x073F,
+ 0x0740, 0x0741, 0x0742, 0x0743, 0x0744, 0x0745, 0x0746, 0x0747,
+ 0x0748, 0x0749, 0x074A, 0x074B, 0x074C, 0x074D, 0x074E, 0x074F,
+ 0x0750, 0x0751, 0x0752, 0x0753, 0x0754, 0x0755, 0x0756, 0x0757,
+ 0x1130, 0x1131, 0x1132, 0x1133, 0x1134, 0x1135, 0x1136, 0x1137,
+ 0x1138, 0x1139, 0x113A, 0x113B, 0x113C, 0x113D, 0x113E, 0x113F,
+ 0x1140, 0x1141, 0x1142, 0x1143, 0x1144, 0x1145, 0x1146, 0x1147,
+ 0x1148, 0x1149, 0x114A, 0x114B, 0x114C, 0x114D, 0x114E, 0x114F,
+ 0x1150, 0x1151, 0x1152, 0x1153, 0x1154, 0x1155, 0x1156, 0x1157,
+ 0x1B30, 0x1B31, 0x1B32, 0x1B33, 0x1B34, 0x1B35, 0x1B36, 0x1B37,
+ 0x1B38, 0x1B39, 0x1B3A, 0x1B3B, 0x1B3C, 0x1B3D, 0x1B3E, 0x1B3F,
+ 0x1B40, 0x1B41, 0x1B42, 0x1B43, 0x1B44, 0x1B45, 0x1B46, 0x1B47,
+ 0x1B48, 0x1B49, 0x1B4A, 0x1B4B, 0x1B4C, 0x1B4D, 0x1B4E, 0x1B4F,
+ 0x1B50, 0x1B51, 0x1B52, 0x1B53, 0x1B54, 0x1B55, 0x1B56, 0x1B57,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0870, 0x0871, 0x0872, 0x0873, 0x0874, 0x0875, 0x0876, 0x0877,
+ 0x0878, 0x0879, 0x087A, 0x087B, 0x087C, 0x087D, 0x087E, 0x087F,
+ 0x0880, 0x0881, 0x0882, 0x0883, 0x0884, 0x0885, 0x0886, 0x0887,
+ 0x0888, 0x0889, 0x088A, 0x088B, 0x088C, 0x088D, 0x088E, 0x088F,
+ 0x0890, 0x0891, 0x0892, 0x0893, 0x0894, 0x0895, 0x0896, 0x0897,
+ 0x1270, 0x1271, 0x1272, 0x1273, 0x1274, 0x1275, 0x1276, 0x1277,
+ 0x1278, 0x1279, 0x127A, 0x127B, 0x127C, 0x127D, 0x127E, 0x127F,
+ 0x1280, 0x1281, 0x1282, 0x1283, 0x1284, 0x1285, 0x1286, 0x1287,
+ 0x1288, 0x1289, 0x128A, 0x128B, 0x128C, 0x128D, 0x128E, 0x128F,
+ 0x1290, 0x1291, 0x1292, 0x1293, 0x1294, 0x1295, 0x1296, 0x1297,
+ 0x1C70, 0x1C71, 0x1C72, 0x1C73, 0x1C74, 0x1C75, 0x1C76, 0x1C77,
+ 0x1C78, 0x1C79, 0x1C7A, 0x1C7B, 0x1C7C, 0x1C7D, 0x1C7E, 0x1C7F,
+ 0x1C80, 0x1C81, 0x1C82, 0x1C83, 0x1C84, 0x1C85, 0x1C86, 0x1C87,
+ 0x1C88, 0x1C89, 0x1C8A, 0x1C8B, 0x1C8C, 0x1C8D, 0x1C8E, 0x1C8F,
+ 0x1C90, 0x1C91, 0x1C92, 0x1C93, 0x1C94, 0x1C95, 0x1C96, 0x1C97,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x09B0, 0x09B1, 0x09B2, 0x09B3, 0x09B4, 0x09B5, 0x09B6, 0x09B7,
+ 0x09B8, 0x09B9, 0x09BA, 0x09BB, 0x09BC, 0x09BD, 0x09BE, 0x09BF,
+ 0x09C0, 0x09C1, 0x09C2, 0x09C3, 0x09C4, 0x09C5, 0x09C6, 0x09C7,
+ 0x09C8, 0x09C9, 0x09CA, 0x09CB, 0x09CC, 0x09CD, 0x09CE, 0x09CF,
+ 0x09D0, 0x09D1, 0x09D2, 0x09D3, 0x09D4, 0x09D5, 0x09D6, 0x09D7,
+ 0x13B0, 0x13B1, 0x13B2, 0x13B3, 0x13B4, 0x13B5, 0x13B6, 0x13B7,
+ 0x13B8, 0x13B9, 0x13BA, 0x13BB, 0x13BC, 0x13BD, 0x13BE, 0x13BF,
+ 0x13C0, 0x13C1, 0x13C2, 0x13C3, 0x13C4, 0x13C5, 0x13C6, 0x13C7,
+ 0x13C8, 0x13C9, 0x13CA, 0x13CB, 0x13CC, 0x13CD, 0x13CE, 0x13CF,
+ 0x13D0, 0x13D1, 0x13D2, 0x13D3, 0x13D4, 0x13D5, 0x13D6, 0x13D7,
+ 0x1DB0, 0x1DB1, 0x1DB2, 0x1DB3, 0x1DB4, 0x1DB5, 0x1DB6, 0x1DB7,
+ 0x1DB8, 0x1DB9, 0x1DBA, 0x1DBB, 0x1DBC, 0x1DBD, 0x1DBE, 0x1DBF,
+ 0x1DC0, 0x1DC1, 0x1DC2, 0x1DC3, 0x1DC4, 0x1DC5, 0x1DC6, 0x1DC7,
+ 0x1DC8, 0x1DC9, 0x1DCA, 0x1DCB, 0x1DCC, 0x1DCD, 0x1DCE, 0x1DCF,
+ 0x1DD0, 0x1DD1, 0x1DD2, 0x1DD3, 0x1DD4, 0x1DD5, 0x1DD6, 0x1DD7,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0118, 0x0119, 0x011A, 0x011B, 0x011C, 0x011D, 0x011E, 0x011F,
+ 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126, 0x0127,
+ 0x0128, 0x0129, 0x012A, 0x012B, 0x012C, 0x012D, 0x012E, 0x012F,
+ 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136, 0x0137,
+ 0x0138, 0x0139, 0x013A, 0x013B, 0x013C, 0x013D, 0x013E, 0x013F,
+ 0x0B18, 0x0B19, 0x0B1A, 0x0B1B, 0x0B1C, 0x0B1D, 0x0B1E, 0x0B1F,
+ 0x0B20, 0x0B21, 0x0B22, 0x0B23, 0x0B24, 0x0B25, 0x0B26, 0x0B27,
+ 0x0B28, 0x0B29, 0x0B2A, 0x0B2B, 0x0B2C, 0x0B2D, 0x0B2E, 0x0B2F,
+ 0x0B30, 0x0B31, 0x0B32, 0x0B33, 0x0B34, 0x0B35, 0x0B36, 0x0B37,
+ 0x0B38, 0x0B39, 0x0B3A, 0x0B3B, 0x0B3C, 0x0B3D, 0x0B3E, 0x0B3F,
+ 0x1518, 0x1519, 0x151A, 0x151B, 0x151C, 0x151D, 0x151E, 0x151F,
+ 0x1520, 0x1521, 0x1522, 0x1523, 0x1524, 0x1525, 0x1526, 0x1527,
+ 0x1528, 0x1529, 0x152A, 0x152B, 0x152C, 0x152D, 0x152E, 0x152F,
+ 0x1530, 0x1531, 0x1532, 0x1533, 0x1534, 0x1535, 0x1536, 0x1537,
+ 0x1538, 0x1539, 0x153A, 0x153B, 0x153C, 0x153D, 0x153E, 0x153F,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0258, 0x0259, 0x025A, 0x025B, 0x025C, 0x025D, 0x025E, 0x025F,
+ 0x0260, 0x0261, 0x0262, 0x0263, 0x0264, 0x0265, 0x0266, 0x0267,
+ 0x0268, 0x0269, 0x026A, 0x026B, 0x026C, 0x026D, 0x026E, 0x026F,
+ 0x0270, 0x0271, 0x0272, 0x0273, 0x0274, 0x0275, 0x0276, 0x0277,
+ 0x0278, 0x0279, 0x027A, 0x027B, 0x027C, 0x027D, 0x027E, 0x027F,
+ 0x0C58, 0x0C59, 0x0C5A, 0x0C5B, 0x0C5C, 0x0C5D, 0x0C5E, 0x0C5F,
+ 0x0C60, 0x0C61, 0x0C62, 0x0C63, 0x0C64, 0x0C65, 0x0C66, 0x0C67,
+ 0x0C68, 0x0C69, 0x0C6A, 0x0C6B, 0x0C6C, 0x0C6D, 0x0C6E, 0x0C6F,
+ 0x0C70, 0x0C71, 0x0C72, 0x0C73, 0x0C74, 0x0C75, 0x0C76, 0x0C77,
+ 0x0C78, 0x0C79, 0x0C7A, 0x0C7B, 0x0C7C, 0x0C7D, 0x0C7E, 0x0C7F,
+ 0x1658, 0x1659, 0x165A, 0x165B, 0x165C, 0x165D, 0x165E, 0x165F,
+ 0x1660, 0x1661, 0x1662, 0x1663, 0x1664, 0x1665, 0x1666, 0x1667,
+ 0x1668, 0x1669, 0x166A, 0x166B, 0x166C, 0x166D, 0x166E, 0x166F,
+ 0x1670, 0x1671, 0x1672, 0x1673, 0x1674, 0x1675, 0x1676, 0x1677,
+ 0x1678, 0x1679, 0x167A, 0x167B, 0x167C, 0x167D, 0x167E, 0x167F,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
+ 0x03A0, 0x03A1, 0x03A2, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
+ 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
+ 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
+ 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
+ 0x0D98, 0x0D99, 0x0D9A, 0x0D9B, 0x0D9C, 0x0D9D, 0x0D9E, 0x0D9F,
+ 0x0DA0, 0x0DA1, 0x0DA2, 0x0DA3, 0x0DA4, 0x0DA5, 0x0DA6, 0x0DA7,
+ 0x0DA8, 0x0DA9, 0x0DAA, 0x0DAB, 0x0DAC, 0x0DAD, 0x0DAE, 0x0DAF,
+ 0x0DB0, 0x0DB1, 0x0DB2, 0x0DB3, 0x0DB4, 0x0DB5, 0x0DB6, 0x0DB7,
+ 0x0DB8, 0x0DB9, 0x0DBA, 0x0DBB, 0x0DBC, 0x0DBD, 0x0DBE, 0x0DBF,
+ 0x1798, 0x1799, 0x179A, 0x179B, 0x179C, 0x179D, 0x179E, 0x179F,
+ 0x17A0, 0x17A1, 0x17A2, 0x17A3, 0x17A4, 0x17A5, 0x17A6, 0x17A7,
+ 0x17A8, 0x17A9, 0x17AA, 0x17AB, 0x17AC, 0x17AD, 0x17AE, 0x17AF,
+ 0x17B0, 0x17B1, 0x17B2, 0x17B3, 0x17B4, 0x17B5, 0x17B6, 0x17B7,
+ 0x17B8, 0x17B9, 0x17BA, 0x17BB, 0x17BC, 0x17BD, 0x17BE, 0x17BF,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x04D8, 0x04D9, 0x04DA, 0x04DB, 0x04DC, 0x04DD, 0x04DE, 0x04DF,
+ 0x04E0, 0x04E1, 0x04E2, 0x04E3, 0x04E4, 0x04E5, 0x04E6, 0x04E7,
+ 0x04E8, 0x04E9, 0x04EA, 0x04EB, 0x04EC, 0x04ED, 0x04EE, 0x04EF,
+ 0x04F0, 0x04F1, 0x04F2, 0x04F3, 0x04F4, 0x04F5, 0x04F6, 0x04F7,
+ 0x04F8, 0x04F9, 0x04FA, 0x04FB, 0x04FC, 0x04FD, 0x04FE, 0x04FF,
+ 0x0ED8, 0x0ED9, 0x0EDA, 0x0EDB, 0x0EDC, 0x0EDD, 0x0EDE, 0x0EDF,
+ 0x0EE0, 0x0EE1, 0x0EE2, 0x0EE3, 0x0EE4, 0x0EE5, 0x0EE6, 0x0EE7,
+ 0x0EE8, 0x0EE9, 0x0EEA, 0x0EEB, 0x0EEC, 0x0EED, 0x0EEE, 0x0EEF,
+ 0x0EF0, 0x0EF1, 0x0EF2, 0x0EF3, 0x0EF4, 0x0EF5, 0x0EF6, 0x0EF7,
+ 0x0EF8, 0x0EF9, 0x0EFA, 0x0EFB, 0x0EFC, 0x0EFD, 0x0EFE, 0x0EFF,
+ 0x18D8, 0x18D9, 0x18DA, 0x18DB, 0x18DC, 0x18DD, 0x18DE, 0x18DF,
+ 0x18E0, 0x18E1, 0x18E2, 0x18E3, 0x18E4, 0x18E5, 0x18E6, 0x18E7,
+ 0x18E8, 0x18E9, 0x18EA, 0x18EB, 0x18EC, 0x18ED, 0x18EE, 0x18EF,
+ 0x18F0, 0x18F1, 0x18F2, 0x18F3, 0x18F4, 0x18F5, 0x18F6, 0x18F7,
+ 0x18F8, 0x18F9, 0x18FA, 0x18FB, 0x18FC, 0x18FD, 0x18FE, 0x18FF,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0618, 0x0619, 0x061A, 0x061B, 0x061C, 0x061D, 0x061E, 0x061F,
+ 0x0620, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627,
+ 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
+ 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637,
+ 0x0638, 0x0639, 0x063A, 0x063B, 0x063C, 0x063D, 0x063E, 0x063F,
+ 0x1018, 0x1019, 0x101A, 0x101B, 0x101C, 0x101D, 0x101E, 0x101F,
+ 0x1020, 0x1021, 0x1022, 0x1023, 0x1024, 0x1025, 0x1026, 0x1027,
+ 0x1028, 0x1029, 0x102A, 0x102B, 0x102C, 0x102D, 0x102E, 0x102F,
+ 0x1030, 0x1031, 0x1032, 0x1033, 0x1034, 0x1035, 0x1036, 0x1037,
+ 0x1038, 0x1039, 0x103A, 0x103B, 0x103C, 0x103D, 0x103E, 0x103F,
+ 0x1A18, 0x1A19, 0x1A1A, 0x1A1B, 0x1A1C, 0x1A1D, 0x1A1E, 0x1A1F,
+ 0x1A20, 0x1A21, 0x1A22, 0x1A23, 0x1A24, 0x1A25, 0x1A26, 0x1A27,
+ 0x1A28, 0x1A29, 0x1A2A, 0x1A2B, 0x1A2C, 0x1A2D, 0x1A2E, 0x1A2F,
+ 0x1A30, 0x1A31, 0x1A32, 0x1A33, 0x1A34, 0x1A35, 0x1A36, 0x1A37,
+ 0x1A38, 0x1A39, 0x1A3A, 0x1A3B, 0x1A3C, 0x1A3D, 0x1A3E, 0x1A3F,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0758, 0x0759, 0x075A, 0x075B, 0x075C, 0x075D, 0x075E, 0x075F,
+ 0x0760, 0x0761, 0x0762, 0x0763, 0x0764, 0x0765, 0x0766, 0x0767,
+ 0x0768, 0x0769, 0x076A, 0x076B, 0x076C, 0x076D, 0x076E, 0x076F,
+ 0x0770, 0x0771, 0x0772, 0x0773, 0x0774, 0x0775, 0x0776, 0x0777,
+ 0x0778, 0x0779, 0x077A, 0x077B, 0x077C, 0x077D, 0x077E, 0x077F,
+ 0x1158, 0x1159, 0x115A, 0x115B, 0x115C, 0x115D, 0x115E, 0x115F,
+ 0x1160, 0x1161, 0x1162, 0x1163, 0x1164, 0x1165, 0x1166, 0x1167,
+ 0x1168, 0x1169, 0x116A, 0x116B, 0x116C, 0x116D, 0x116E, 0x116F,
+ 0x1170, 0x1171, 0x1172, 0x1173, 0x1174, 0x1175, 0x1176, 0x1177,
+ 0x1178, 0x1179, 0x117A, 0x117B, 0x117C, 0x117D, 0x117E, 0x117F,
+ 0x1B58, 0x1B59, 0x1B5A, 0x1B5B, 0x1B5C, 0x1B5D, 0x1B5E, 0x1B5F,
+ 0x1B60, 0x1B61, 0x1B62, 0x1B63, 0x1B64, 0x1B65, 0x1B66, 0x1B67,
+ 0x1B68, 0x1B69, 0x1B6A, 0x1B6B, 0x1B6C, 0x1B6D, 0x1B6E, 0x1B6F,
+ 0x1B70, 0x1B71, 0x1B72, 0x1B73, 0x1B74, 0x1B75, 0x1B76, 0x1B77,
+ 0x1B78, 0x1B79, 0x1B7A, 0x1B7B, 0x1B7C, 0x1B7D, 0x1B7E, 0x1B7F,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x0898, 0x0899, 0x089A, 0x089B, 0x089C, 0x089D, 0x089E, 0x089F,
+ 0x08A0, 0x08A1, 0x08A2, 0x08A3, 0x08A4, 0x08A5, 0x08A6, 0x08A7,
+ 0x08A8, 0x08A9, 0x08AA, 0x08AB, 0x08AC, 0x08AD, 0x08AE, 0x08AF,
+ 0x08B0, 0x08B1, 0x08B2, 0x08B3, 0x08B4, 0x08B5, 0x08B6, 0x08B7,
+ 0x08B8, 0x08B9, 0x08BA, 0x08BB, 0x08BC, 0x08BD, 0x08BE, 0x08BF,
+ 0x1298, 0x1299, 0x129A, 0x129B, 0x129C, 0x129D, 0x129E, 0x129F,
+ 0x12A0, 0x12A1, 0x12A2, 0x12A3, 0x12A4, 0x12A5, 0x12A6, 0x12A7,
+ 0x12A8, 0x12A9, 0x12AA, 0x12AB, 0x12AC, 0x12AD, 0x12AE, 0x12AF,
+ 0x12B0, 0x12B1, 0x12B2, 0x12B3, 0x12B4, 0x12B5, 0x12B6, 0x12B7,
+ 0x12B8, 0x12B9, 0x12BA, 0x12BB, 0x12BC, 0x12BD, 0x12BE, 0x12BF,
+ 0x1C98, 0x1C99, 0x1C9A, 0x1C9B, 0x1C9C, 0x1C9D, 0x1C9E, 0x1C9F,
+ 0x1CA0, 0x1CA1, 0x1CA2, 0x1CA3, 0x1CA4, 0x1CA5, 0x1CA6, 0x1CA7,
+ 0x1CA8, 0x1CA9, 0x1CAA, 0x1CAB, 0x1CAC, 0x1CAD, 0x1CAE, 0x1CAF,
+ 0x1CB0, 0x1CB1, 0x1CB2, 0x1CB3, 0x1CB4, 0x1CB5, 0x1CB6, 0x1CB7,
+ 0x1CB8, 0x1CB9, 0x1CBA, 0x1CBB, 0x1CBC, 0x1CBD, 0x1CBE, 0x1CBF,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00,
+ 0x09D8, 0x09D9, 0x09DA, 0x09DB, 0x09DC, 0x09DD, 0x09DE, 0x09DF,
+ 0x09E0, 0x09E1, 0x09E2, 0x09E3, 0x09E4, 0x09E5, 0x09E6, 0x09E7,
+ 0x09E8, 0x09E9, 0x09EA, 0x09EB, 0x09EC, 0x09ED, 0x09EE, 0x09EF,
+ 0x09F0, 0x09F1, 0x09F2, 0x09F3, 0x09F4, 0x09F5, 0x09F6, 0x09F7,
+ 0x09F8, 0x09F9, 0x09FA, 0x09FB, 0x09FC, 0x09FD, 0x09FE, 0x09FF,
+ 0x13D8, 0x13D9, 0x13DA, 0x13DB, 0x13DC, 0x13DD, 0x13DE, 0x13DF,
+ 0x13E0, 0x13E1, 0x13E2, 0x13E3, 0x13E4, 0x13E5, 0x13E6, 0x13E7,
+ 0x13E8, 0x13E9, 0x13EA, 0x13EB, 0x13EC, 0x13ED, 0x13EE, 0x13EF,
+ 0x13F0, 0x13F1, 0x13F2, 0x13F3, 0x13F4, 0x13F5, 0x13F6, 0x13F7,
+ 0x13F8, 0x13F9, 0x13FA, 0x13FB, 0x13FC, 0x13FD, 0x13FE, 0x13FF,
+ 0x1DD8, 0x1DD9, 0x1DDA, 0x1DDB, 0x1DDC, 0x1DDD, 0x1DDE, 0x1DDF,
+ 0x1DE0, 0x1DE1, 0x1DE2, 0x1DE3, 0x1DE4, 0x1DE5, 0x1DE6, 0x1DE7,
+ 0x1DE8, 0x1DE9, 0x1DEA, 0x1DEB, 0x1DEC, 0x1DED, 0x1DEE, 0x1DEF,
+ 0x1DF0, 0x1DF1, 0x1DF2, 0x1DF3, 0x1DF4, 0x1DF5, 0x1DF6, 0x1DF7,
+ 0x1DF8, 0x1DF9, 0x1DFA, 0x1DFB, 0x1DFC, 0x1DFD, 0x1DFE, 0x1DFF,
+ 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00
+ };
+
+ private const int CharBitmapCount = 322;
+ private const int CharBitmapBytes = 8;
+
+ private static readonly byte[] CharBitmap = new byte[CharBitmapCount * CharBitmapBytes]
+ {
+ 0x43, 0x5D, 0x55, 0x45, 0x65, 0x7D, 0x43, 0x7F,
+ 0x77, 0x6B, 0x5D, 0x5D, 0x41, 0x5D, 0x5D, 0x7F,
+ 0x61, 0x5D, 0x5D, 0x61, 0x5D, 0x5D, 0x61, 0x7F,
+ 0x63, 0x5D, 0x7D, 0x7D, 0x7D, 0x5D, 0x63, 0x7F,
+ 0x61, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x61, 0x7F,
+ 0x41, 0x7D, 0x7D, 0x61, 0x7D, 0x7D, 0x41, 0x7F,
+ 0x41, 0x7D, 0x7D, 0x61, 0x7D, 0x7D, 0x7D, 0x7F,
+ 0x43, 0x7D, 0x7D, 0x7D, 0x4D, 0x5D, 0x43, 0x7F,
+ 0x5D, 0x5D, 0x5D, 0x41, 0x5D, 0x5D, 0x5D, 0x7F,
+ 0x63, 0x77, 0x77, 0x77, 0x77, 0x77, 0x63, 0x7F,
+ 0x5F, 0x5F, 0x5F, 0x5F, 0x5F, 0x5D, 0x63, 0x7F,
+ 0x5D, 0x6D, 0x75, 0x79, 0x75, 0x6D, 0x5D, 0x7F,
+ 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x41, 0x7F,
+ 0x5D, 0x49, 0x55, 0x55, 0x5D, 0x5D, 0x5D, 0x7F,
+ 0x5D, 0x5D, 0x59, 0x55, 0x4D, 0x5D, 0x5D, 0x7F,
+ 0x63, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x63, 0x7F,
+ 0x61, 0x5D, 0x5D, 0x61, 0x7D, 0x7D, 0x7D, 0x7F,
+ 0x63, 0x5D, 0x5D, 0x5D, 0x55, 0x6D, 0x53, 0x7F,
+ 0x61, 0x5D, 0x5D, 0x61, 0x75, 0x6D, 0x5D, 0x7F,
+ 0x63, 0x5D, 0x7D, 0x63, 0x5F, 0x5D, 0x63, 0x7F,
+ 0x41, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x7F,
+ 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x63, 0x7F,
+ 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x6B, 0x77, 0x7F,
+ 0x5D, 0x5D, 0x5D, 0x55, 0x55, 0x49, 0x5D, 0x7F,
+ 0x5D, 0x5D, 0x6B, 0x77, 0x6B, 0x5D, 0x5D, 0x7F,
+ 0x5D, 0x5D, 0x6B, 0x77, 0x77, 0x77, 0x77, 0x7F,
+ 0x41, 0x5F, 0x6F, 0x77, 0x7B, 0x7D, 0x41, 0x7F,
+ 0x41, 0x79, 0x79, 0x79, 0x79, 0x79, 0x41, 0x7F,
+ 0x7F, 0x7D, 0x7B, 0x77, 0x6F, 0x5F, 0x7F, 0x7F,
+ 0x41, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x41, 0x7F,
+ 0x7F, 0x7F, 0x77, 0x6B, 0x5D, 0x7F, 0x7F, 0x7F,
+ 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x00,
+ 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x7F, 0x77, 0x7F,
+ 0x6B, 0x6B, 0x6B, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
+ 0x6B, 0x6B, 0x00, 0x6B, 0x00, 0x6B, 0x6B, 0x7F,
+ 0x77, 0x43, 0x75, 0x63, 0x57, 0x61, 0x77, 0x7F,
+ 0x79, 0x59, 0x6F, 0x77, 0x7B, 0x4D, 0x4F, 0x7F,
+ 0x7B, 0x75, 0x75, 0x7B, 0x55, 0x6D, 0x53, 0x7F,
+ 0x77, 0x77, 0x77, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
+ 0x77, 0x7B, 0x7D, 0x7D, 0x7D, 0x7B, 0x77, 0x7F,
+ 0x77, 0x6F, 0x5F, 0x5F, 0x5F, 0x6F, 0x77, 0x7F,
+ 0x77, 0x55, 0x63, 0x77, 0x63, 0x55, 0x77, 0x7F,
+ 0x7F, 0x77, 0x77, 0x41, 0x77, 0x77, 0x7F, 0x7F,
+ 0x7F, 0x7F, 0x7F, 0x7F, 0x77, 0x77, 0x7B, 0x7F,
+ 0x7F, 0x7F, 0x7F, 0x41, 0x7F, 0x7F, 0x7F, 0x7F,
+ 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x77, 0x7F,
+ 0x7F, 0x5F, 0x6F, 0x77, 0x7B, 0x7D, 0x7F, 0x7F,
+ 0x63, 0x5D, 0x4D, 0x55, 0x59, 0x5D, 0x63, 0x7F,
+ 0x77, 0x73, 0x77, 0x77, 0x77, 0x77, 0x63, 0x7F,
+ 0x63, 0x5D, 0x5F, 0x67, 0x7B, 0x7D, 0x41, 0x7F,
+ 0x41, 0x5F, 0x6F, 0x67, 0x5F, 0x5D, 0x63, 0x7F,
+ 0x6F, 0x67, 0x6B, 0x6D, 0x41, 0x6F, 0x6F, 0x7F,
+ 0x41, 0x7D, 0x61, 0x5F, 0x5F, 0x5D, 0x63, 0x7F,
+ 0x47, 0x7B, 0x7D, 0x61, 0x5D, 0x5D, 0x63, 0x7F,
+ 0x41, 0x5F, 0x6F, 0x77, 0x7B, 0x7B, 0x7B, 0x7F,
+ 0x63, 0x5D, 0x5D, 0x63, 0x5D, 0x5D, 0x63, 0x7F,
+ 0x63, 0x5D, 0x5D, 0x43, 0x5F, 0x6F, 0x71, 0x7F,
+ 0x7F, 0x7F, 0x77, 0x7F, 0x77, 0x7F, 0x7F, 0x7F,
+ 0x7F, 0x7F, 0x77, 0x7F, 0x77, 0x77, 0x7B, 0x7F,
+ 0x6F, 0x77, 0x7B, 0x7D, 0x7B, 0x77, 0x6F, 0x7F,
+ 0x7F, 0x7F, 0x41, 0x7F, 0x41, 0x7F, 0x7F, 0x7F,
+ 0x7B, 0x77, 0x6F, 0x5F, 0x6F, 0x77, 0x7B, 0x7F,
+ 0x63, 0x5D, 0x6F, 0x77, 0x77, 0x7F, 0x77, 0x7F,
+ 0x43, 0x5D, 0x55, 0x45, 0x65, 0x7D, 0x43, 0x7F,
+ 0x77, 0x6B, 0x5D, 0x5D, 0x41, 0x5D, 0x5D, 0x7F,
+ 0x61, 0x5D, 0x5D, 0x61, 0x5D, 0x5D, 0x61, 0x7F,
+ 0x63, 0x5D, 0x7D, 0x7D, 0x7D, 0x5D, 0x63, 0x7F,
+ 0x61, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x61, 0x7F,
+ 0x41, 0x7D, 0x7D, 0x61, 0x7D, 0x7D, 0x41, 0x7F,
+ 0x41, 0x7D, 0x7D, 0x61, 0x7D, 0x7D, 0x7D, 0x7F,
+ 0x43, 0x7D, 0x7D, 0x7D, 0x4D, 0x5D, 0x43, 0x7F,
+ 0x5D, 0x5D, 0x5D, 0x41, 0x5D, 0x5D, 0x5D, 0x7F,
+ 0x63, 0x77, 0x77, 0x77, 0x77, 0x77, 0x63, 0x7F,
+ 0x5F, 0x5F, 0x5F, 0x5F, 0x5F, 0x5D, 0x63, 0x7F,
+ 0x5D, 0x6D, 0x75, 0x79, 0x75, 0x6D, 0x5D, 0x7F,
+ 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x41, 0x7F,
+ 0x5D, 0x49, 0x55, 0x55, 0x5D, 0x5D, 0x5D, 0x7F,
+ 0x5D, 0x5D, 0x59, 0x55, 0x4D, 0x5D, 0x5D, 0x7F,
+ 0x63, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x63, 0x7F,
+ 0x61, 0x5D, 0x5D, 0x61, 0x7D, 0x7D, 0x7D, 0x7F,
+ 0x63, 0x5D, 0x5D, 0x5D, 0x55, 0x6D, 0x53, 0x7F,
+ 0x61, 0x5D, 0x5D, 0x61, 0x75, 0x6D, 0x5D, 0x7F,
+ 0x63, 0x5D, 0x7D, 0x63, 0x5F, 0x5D, 0x63, 0x7F,
+ 0x41, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x7F,
+ 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x63, 0x7F,
+ 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x6B, 0x77, 0x7F,
+ 0x5D, 0x5D, 0x5D, 0x55, 0x55, 0x49, 0x5D, 0x7F,
+ 0x5D, 0x5D, 0x6B, 0x77, 0x6B, 0x5D, 0x5D, 0x7F,
+ 0x5D, 0x5D, 0x6B, 0x77, 0x77, 0x77, 0x77, 0x7F,
+ 0x41, 0x5F, 0x6F, 0x77, 0x7B, 0x7D, 0x41, 0x7F,
+ 0x41, 0x79, 0x79, 0x79, 0x79, 0x79, 0x41, 0x7F,
+ 0x7F, 0x7D, 0x7B, 0x77, 0x6F, 0x5F, 0x7F, 0x7F,
+ 0x41, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x41, 0x7F,
+ 0x7F, 0x7F, 0x77, 0x6B, 0x5D, 0x7F, 0x7F, 0x7F,
+ 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x00,
+ 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x7F, 0x77, 0x7F,
+ 0x6B, 0x6B, 0x6B, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
+ 0x6B, 0x6B, 0x00, 0x6B, 0x00, 0x6B, 0x6B, 0x7F,
+ 0x77, 0x43, 0x75, 0x63, 0x57, 0x61, 0x77, 0x7F,
+ 0x79, 0x59, 0x6F, 0x77, 0x7B, 0x4D, 0x4F, 0x7F,
+ 0x7B, 0x75, 0x75, 0x7B, 0x55, 0x6D, 0x53, 0x7F,
+ 0x77, 0x77, 0x77, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
+ 0x77, 0x7B, 0x7D, 0x7D, 0x7D, 0x7B, 0x77, 0x7F,
+ 0x77, 0x6F, 0x5F, 0x5F, 0x5F, 0x6F, 0x77, 0x7F,
+ 0x77, 0x55, 0x63, 0x77, 0x63, 0x55, 0x77, 0x7F,
+ 0x7F, 0x77, 0x77, 0x41, 0x77, 0x77, 0x7F, 0x7F,
+ 0x7F, 0x7F, 0x7F, 0x7F, 0x77, 0x77, 0x7B, 0x7F,
+ 0x7F, 0x7F, 0x7F, 0x41, 0x7F, 0x7F, 0x7F, 0x7F,
+ 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x77, 0x7F,
+ 0x7F, 0x5F, 0x6F, 0x77, 0x7B, 0x7D, 0x7F, 0x7F,
+ 0x63, 0x5D, 0x4D, 0x55, 0x59, 0x5D, 0x63, 0x7F,
+ 0x77, 0x73, 0x77, 0x77, 0x77, 0x77, 0x63, 0x7F,
+ 0x63, 0x5D, 0x5F, 0x67, 0x7B, 0x7D, 0x41, 0x7F,
+ 0x41, 0x5F, 0x6F, 0x67, 0x5F, 0x5D, 0x63, 0x7F,
+ 0x6F, 0x67, 0x6B, 0x6D, 0x41, 0x6F, 0x6F, 0x7F,
+ 0x41, 0x7D, 0x61, 0x5F, 0x5F, 0x5D, 0x63, 0x7F,
+ 0x47, 0x7B, 0x7D, 0x61, 0x5D, 0x5D, 0x63, 0x7F,
+ 0x41, 0x5F, 0x6F, 0x77, 0x7B, 0x7B, 0x7B, 0x7F,
+ 0x63, 0x5D, 0x5D, 0x63, 0x5D, 0x5D, 0x63, 0x7F,
+ 0x63, 0x5D, 0x5D, 0x43, 0x5F, 0x6F, 0x71, 0x7F,
+ 0x7F, 0x7F, 0x77, 0x7F, 0x77, 0x7F, 0x7F, 0x7F,
+ 0x7F, 0x7F, 0x77, 0x7F, 0x77, 0x77, 0x7B, 0x7F,
+ 0x6F, 0x77, 0x7B, 0x7D, 0x7B, 0x77, 0x6F, 0x7F,
+ 0x7F, 0x7F, 0x41, 0x7F, 0x41, 0x7F, 0x7F, 0x7F,
+ 0x7B, 0x77, 0x6F, 0x5F, 0x6F, 0x77, 0x7B, 0x7F,
+ 0x63, 0x5D, 0x6F, 0x77, 0x77, 0x7F, 0x77, 0x7F,
+ 0x3C, 0x22, 0x2A, 0x3A, 0x1A, 0x02, 0x3C, 0x00,
+ 0x08, 0x14, 0x22, 0x22, 0x3E, 0x22, 0x22, 0x00,
+ 0x1E, 0x22, 0x22, 0x1E, 0x22, 0x22, 0x1E, 0x00,
+ 0x1C, 0x22, 0x02, 0x02, 0x02, 0x22, 0x1C, 0x00,
+ 0x1E, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1E, 0x00,
+ 0x3E, 0x02, 0x02, 0x1E, 0x02, 0x02, 0x3E, 0x00,
+ 0x3E, 0x02, 0x02, 0x1E, 0x02, 0x02, 0x02, 0x00,
+ 0x3C, 0x02, 0x02, 0x02, 0x32, 0x22, 0x3C, 0x00,
+ 0x22, 0x22, 0x22, 0x3E, 0x22, 0x22, 0x22, 0x00,
+ 0x1C, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1C, 0x00,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x1C, 0x00,
+ 0x22, 0x12, 0x0A, 0x06, 0x0A, 0x12, 0x22, 0x00,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x3E, 0x00,
+ 0x22, 0x36, 0x2A, 0x2A, 0x22, 0x22, 0x22, 0x00,
+ 0x22, 0x22, 0x26, 0x2A, 0x32, 0x22, 0x22, 0x00,
+ 0x1C, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1C, 0x00,
+ 0x1E, 0x22, 0x22, 0x1E, 0x02, 0x02, 0x02, 0x00,
+ 0x1C, 0x22, 0x22, 0x22, 0x2A, 0x12, 0x2C, 0x00,
+ 0x1E, 0x22, 0x22, 0x1E, 0x0A, 0x12, 0x22, 0x00,
+ 0x1C, 0x22, 0x02, 0x1C, 0x20, 0x22, 0x1C, 0x00,
+ 0x3E, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00,
+ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1C, 0x00,
+ 0x22, 0x22, 0x22, 0x22, 0x22, 0x14, 0x08, 0x00,
+ 0x22, 0x22, 0x22, 0x2A, 0x2A, 0x36, 0x22, 0x00,
+ 0x22, 0x22, 0x14, 0x08, 0x14, 0x22, 0x22, 0x00,
+ 0x22, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08, 0x00,
+ 0x3E, 0x20, 0x10, 0x08, 0x04, 0x02, 0x3E, 0x00,
+ 0x3E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x3E, 0x00,
+ 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00,
+ 0x3E, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3E, 0x00,
+ 0x00, 0x00, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08, 0x00,
+ 0x14, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x14, 0x14, 0x7F, 0x14, 0x7F, 0x14, 0x14, 0x00,
+ 0x08, 0x3C, 0x0A, 0x1C, 0x28, 0x1E, 0x08, 0x00,
+ 0x06, 0x26, 0x10, 0x08, 0x04, 0x32, 0x30, 0x00,
+ 0x04, 0x0A, 0x0A, 0x04, 0x2A, 0x12, 0x2C, 0x00,
+ 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x08, 0x04, 0x02, 0x02, 0x02, 0x04, 0x08, 0x00,
+ 0x08, 0x10, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00,
+ 0x08, 0x2A, 0x1C, 0x08, 0x1C, 0x2A, 0x08, 0x00,
+ 0x00, 0x08, 0x08, 0x3E, 0x08, 0x08, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+ 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00, 0x00,
+ 0x1C, 0x22, 0x32, 0x2A, 0x26, 0x22, 0x1C, 0x00,
+ 0x08, 0x0C, 0x08, 0x08, 0x08, 0x08, 0x1C, 0x00,
+ 0x1C, 0x22, 0x20, 0x18, 0x04, 0x02, 0x3E, 0x00,
+ 0x3E, 0x20, 0x10, 0x18, 0x20, 0x22, 0x1C, 0x00,
+ 0x10, 0x18, 0x14, 0x12, 0x3E, 0x10, 0x10, 0x00,
+ 0x3E, 0x02, 0x1E, 0x20, 0x20, 0x22, 0x1C, 0x00,
+ 0x38, 0x04, 0x02, 0x1E, 0x22, 0x22, 0x1C, 0x00,
+ 0x3E, 0x20, 0x10, 0x08, 0x04, 0x04, 0x04, 0x00,
+ 0x1C, 0x22, 0x22, 0x1C, 0x22, 0x22, 0x1C, 0x00,
+ 0x1C, 0x22, 0x22, 0x3C, 0x20, 0x10, 0x0E, 0x00,
+ 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x08, 0x00, 0x08, 0x08, 0x04, 0x00,
+ 0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x00,
+ 0x00, 0x00, 0x3E, 0x00, 0x3E, 0x00, 0x00, 0x00,
+ 0x04, 0x08, 0x10, 0x20, 0x10, 0x08, 0x04, 0x00,
+ 0x1C, 0x22, 0x10, 0x08, 0x08, 0x00, 0x08, 0x00,
+ 0x3C, 0x22, 0x2A, 0x3A, 0x1A, 0x02, 0x3C, 0x00,
+ 0x08, 0x14, 0x22, 0x22, 0x3E, 0x22, 0x22, 0x00,
+ 0x1E, 0x22, 0x22, 0x1E, 0x22, 0x22, 0x1E, 0x00,
+ 0x1C, 0x22, 0x02, 0x02, 0x02, 0x22, 0x1C, 0x00,
+ 0x1E, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1E, 0x00,
+ 0x3E, 0x02, 0x02, 0x1E, 0x02, 0x02, 0x3E, 0x00,
+ 0x3E, 0x02, 0x02, 0x1E, 0x02, 0x02, 0x02, 0x00,
+ 0x3C, 0x02, 0x02, 0x02, 0x32, 0x22, 0x3C, 0x00,
+ 0x22, 0x22, 0x22, 0x3E, 0x22, 0x22, 0x22, 0x00,
+ 0x1C, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1C, 0x00,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x1C, 0x00,
+ 0x22, 0x12, 0x0A, 0x06, 0x0A, 0x12, 0x22, 0x00,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x3E, 0x00,
+ 0x22, 0x36, 0x2A, 0x2A, 0x22, 0x22, 0x22, 0x00,
+ 0x22, 0x22, 0x26, 0x2A, 0x32, 0x22, 0x22, 0x00,
+ 0x1C, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1C, 0x00,
+ 0x1E, 0x22, 0x22, 0x1E, 0x02, 0x02, 0x02, 0x00,
+ 0x1C, 0x22, 0x22, 0x22, 0x2A, 0x12, 0x2C, 0x00,
+ 0x1E, 0x22, 0x22, 0x1E, 0x0A, 0x12, 0x22, 0x00,
+ 0x1C, 0x22, 0x02, 0x1C, 0x20, 0x22, 0x1C, 0x00,
+ 0x3E, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00,
+ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1C, 0x00,
+ 0x22, 0x22, 0x22, 0x22, 0x22, 0x14, 0x08, 0x00,
+ 0x22, 0x22, 0x22, 0x2A, 0x2A, 0x36, 0x22, 0x00,
+ 0x22, 0x22, 0x14, 0x08, 0x14, 0x22, 0x22, 0x00,
+ 0x22, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08, 0x00,
+ 0x3E, 0x20, 0x10, 0x08, 0x04, 0x02, 0x3E, 0x00,
+ 0x3E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x3E, 0x00,
+ 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00,
+ 0x3E, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3E, 0x00,
+ 0x00, 0x00, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F,
+ 0x04, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x1C, 0x20, 0x3C, 0x22, 0x3C, 0x00,
+ 0x02, 0x02, 0x1E, 0x22, 0x22, 0x22, 0x1E, 0x00,
+ 0x00, 0x00, 0x3C, 0x02, 0x02, 0x02, 0x3C, 0x00,
+ 0x20, 0x20, 0x3C, 0x22, 0x22, 0x22, 0x3C, 0x00,
+ 0x00, 0x00, 0x1C, 0x22, 0x3E, 0x02, 0x3C, 0x00,
+ 0x18, 0x24, 0x04, 0x1E, 0x04, 0x04, 0x04, 0x00,
+ 0x00, 0x00, 0x1C, 0x22, 0x22, 0x3C, 0x20, 0x1C,
+ 0x02, 0x02, 0x1E, 0x22, 0x22, 0x22, 0x22, 0x00,
+ 0x08, 0x00, 0x0C, 0x08, 0x08, 0x08, 0x1C, 0x00,
+ 0x10, 0x00, 0x18, 0x10, 0x10, 0x10, 0x12, 0x0C,
+ 0x02, 0x02, 0x22, 0x12, 0x0E, 0x12, 0x22, 0x00,
+ 0x0C, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1C, 0x00,
+ 0x00, 0x00, 0x36, 0x2A, 0x2A, 0x2A, 0x22, 0x00,
+ 0x00, 0x00, 0x1E, 0x22, 0x22, 0x22, 0x22, 0x00,
+ 0x00, 0x00, 0x1C, 0x22, 0x22, 0x22, 0x1C, 0x00,
+ 0x00, 0x00, 0x1E, 0x22, 0x22, 0x1E, 0x02, 0x02,
+ 0x00, 0x00, 0x3C, 0x22, 0x22, 0x3C, 0x20, 0x20,
+ 0x00, 0x00, 0x3A, 0x06, 0x02, 0x02, 0x02, 0x00,
+ 0x00, 0x00, 0x3C, 0x02, 0x1C, 0x20, 0x1E, 0x00,
+ 0x04, 0x04, 0x1E, 0x04, 0x04, 0x24, 0x18, 0x00,
+ 0x00, 0x00, 0x22, 0x22, 0x22, 0x32, 0x2C, 0x00,
+ 0x00, 0x00, 0x22, 0x22, 0x22, 0x14, 0x08, 0x00,
+ 0x00, 0x00, 0x22, 0x22, 0x2A, 0x2A, 0x36, 0x00,
+ 0x00, 0x00, 0x22, 0x14, 0x08, 0x14, 0x22, 0x00,
+ 0x00, 0x00, 0x22, 0x22, 0x22, 0x3C, 0x20, 0x1C,
+ 0x00, 0x00, 0x3E, 0x10, 0x08, 0x04, 0x3E, 0x00,
+ 0x38, 0x0C, 0x0C, 0x06, 0x0C, 0x0C, 0x38, 0x00,
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+ 0x0E, 0x18, 0x18, 0x30, 0x18, 0x18, 0x0E, 0x00,
+ 0x2C, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x2A, 0x14, 0x2A, 0x14, 0x2A, 0x00, 0x00,
+ 0x10, 0x08, 0x36, 0x7F, 0x3F, 0x3F, 0x7E, 0x36,
+ 0x10, 0x08, 0x36, 0x49, 0x21, 0x21, 0x4A, 0x36,
+ 0x00, 0x00, 0x02, 0x06, 0x0E, 0x1E, 0x36, 0x42,
+ 0x7F, 0x22, 0x14, 0x08, 0x08, 0x14, 0x2A, 0x7F,
+ 0x00, 0x40, 0x20, 0x11, 0x0A, 0x04, 0x04, 0x00,
+ 0x7F, 0x3F, 0x5F, 0x6C, 0x75, 0x7B, 0x7B, 0x7F,
+ 0x3F, 0x3F, 0x3F, 0x3B, 0x39, 0x00, 0x79, 0x7B,
+ 0x7F, 0x00, 0x7F, 0x00, 0x7F, 0x00, 0x00, 0x7F,
+ 0x08, 0x04, 0x02, 0x7F, 0x02, 0x04, 0x08, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A,
+ 0x08, 0x08, 0x08, 0x08, 0x49, 0x2A, 0x1C, 0x08,
+ 0x08, 0x1C, 0x2A, 0x49, 0x08, 0x08, 0x08, 0x08,
+ 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x40, 0x40, 0x40, 0x44, 0x46, 0x7F, 0x06, 0x04,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x13, 0x18, 0x1C, 0x7E, 0x1C, 0x18, 0x10, 0x6F,
+ 0x64, 0x0C, 0x1C, 0x3F, 0x1C, 0x0C, 0x04, 0x7B,
+ 0x40, 0x48, 0x08, 0x7F, 0x3E, 0x1C, 0x48, 0x40,
+ 0x40, 0x48, 0x1C, 0x3E, 0x7F, 0x08, 0x48, 0x48,
+ 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x7F,
+ 0x08, 0x10, 0x20, 0x7F, 0x20, 0x10, 0x08, 0x00,
+ 0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55,
+ 0x55, 0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55, 0x2A,
+ 0x00, 0x3E, 0x41, 0x01, 0x01, 0x01, 0x7F, 0x00,
+ 0x00, 0x00, 0x3F, 0x40, 0x40, 0x40, 0x7F, 0x00,
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x08, 0x1C, 0x3E, 0x7F, 0x3E, 0x1C, 0x08, 0x00,
+ 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F,
+ 0x14, 0x14, 0x77, 0x00, 0x77, 0x14, 0x14, 0x00,
+ 0x7F, 0x40, 0x40, 0x4C, 0x4C, 0x40, 0x40, 0x7F,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x7B, 0x77, 0x6F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
+ 0x7F, 0x7F, 0x63, 0x5F, 0x43, 0x5D, 0x43, 0x7F,
+ 0x7D, 0x7D, 0x61, 0x5D, 0x5D, 0x5D, 0x61, 0x7F,
+ 0x7F, 0x7F, 0x43, 0x7D, 0x7D, 0x7D, 0x43, 0x7F,
+ 0x5F, 0x5F, 0x43, 0x5D, 0x5D, 0x5D, 0x43, 0x7F,
+ 0x7F, 0x7F, 0x63, 0x5D, 0x41, 0x7D, 0x43, 0x7F,
+ 0x67, 0x5B, 0x7B, 0x61, 0x7B, 0x7B, 0x7B, 0x7F,
+ 0x7F, 0x7F, 0x63, 0x5D, 0x5D, 0x43, 0x5F, 0x63,
+ 0x7D, 0x7D, 0x61, 0x5D, 0x5D, 0x5D, 0x5D, 0x7F,
+ 0x77, 0x7F, 0x73, 0x77, 0x77, 0x77, 0x63, 0x7F,
+ 0x6F, 0x7F, 0x67, 0x6F, 0x6F, 0x6F, 0x6D, 0x73,
+ 0x7D, 0x7D, 0x5D, 0x6D, 0x71, 0x6D, 0x5D, 0x7F,
+ 0x73, 0x77, 0x77, 0x77, 0x77, 0x77, 0x63, 0x7F,
+ 0x7F, 0x7F, 0x49, 0x55, 0x55, 0x55, 0x5D, 0x7F,
+ 0x7F, 0x7F, 0x61, 0x5D, 0x5D, 0x5D, 0x5D, 0x7F,
+ 0x7F, 0x7F, 0x63, 0x5D, 0x5D, 0x5D, 0x63, 0x7F,
+ 0x7F, 0x7F, 0x61, 0x5D, 0x5D, 0x61, 0x7D, 0x7D,
+ 0x7F, 0x7F, 0x43, 0x5D, 0x5D, 0x43, 0x5F, 0x5F,
+ 0x7F, 0x7F, 0x45, 0x79, 0x7D, 0x7D, 0x7D, 0x7F,
+ 0x7F, 0x7F, 0x43, 0x7D, 0x63, 0x5F, 0x61, 0x7F,
+ 0x7B, 0x7B, 0x61, 0x7B, 0x7B, 0x5B, 0x67, 0x7F,
+ 0x7F, 0x7F, 0x5D, 0x5D, 0x5D, 0x4D, 0x53, 0x7F,
+ 0x7F, 0x7F, 0x5D, 0x5D, 0x5D, 0x6B, 0x77, 0x7F,
+ 0x7F, 0x7F, 0x5D, 0x5D, 0x55, 0x55, 0x49, 0x7F,
+ 0x7F, 0x7F, 0x5D, 0x6B, 0x77, 0x6B, 0x5D, 0x7F,
+ 0x7F, 0x7F, 0x5D, 0x5D, 0x5D, 0x43, 0x5F, 0x63,
+ 0x7F, 0x7F, 0x41, 0x6F, 0x77, 0x7B, 0x41, 0x7F,
+ 0x47, 0x73, 0x73, 0x79, 0x73, 0x73, 0x47, 0x7F,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x71, 0x67, 0x67, 0x4F, 0x67, 0x67, 0x71, 0x7F,
+ 0x53, 0x65, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
+ 0x7F, 0x55, 0x6B, 0x55, 0x6B, 0x55, 0x7F, 0x7F,
+ 0x70, 0x60, 0x7E, 0x31, 0x79, 0x30, 0x3F, 0x02,
+ 0x00, 0x18, 0x07, 0x00, 0x07, 0x0C, 0x08, 0x70
+ };
+
+ private const int CharSetCharCount = 256;
+
+ private static readonly ushort[] CharSetPrimary = new ushort[CharSetCharCount]
+ {
+ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
+ 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
+ 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
+ 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
+ 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
+ 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
+ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
+ 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
+ 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
+ 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
+ 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
+ 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
+ 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
+ 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
+ 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
+ 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
+ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+ 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
+ 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
+ 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
+ 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
+ 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
+ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
+ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
+ 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
+ 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
+ };
+
+ private static readonly ushort[] CharSetSecondaryStandard = new ushort[CharSetCharCount]
+ {
+ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
+ 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
+ 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
+ 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
+ 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
+ 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
+ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
+ 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
+ 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
+ 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
+ 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
+ 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
+ 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126, 0x0127,
+ 0x0128, 0x0129, 0x012A, 0x012B, 0x012C, 0x012D, 0x012E, 0x012F,
+ 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136, 0x0137,
+ 0x0138, 0x0139, 0x013A, 0x013B, 0x013C, 0x013D, 0x013E, 0x013F,
+ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+ 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
+ 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
+ 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
+ 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
+ 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
+ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
+ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
+ 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
+ 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
+ };
+
+ private static readonly ushort[] CharSetSecondaryEnhanced = new ushort[CharSetCharCount]
+ {
+ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
+ 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
+ 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
+ 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
+ 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
+ 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
+ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
+ 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
+ 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, 0x0107,
+ 0x0108, 0x0109, 0x010A, 0x010B, 0x010C, 0x010D, 0x010E, 0x010F,
+ 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116, 0x0117,
+ 0x0118, 0x0119, 0x011A, 0x011B, 0x011C, 0x011D, 0x011E, 0x011F,
+ 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126, 0x0127,
+ 0x0128, 0x0129, 0x012A, 0x012B, 0x012C, 0x012D, 0x012E, 0x012F,
+ 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136, 0x0137,
+ 0x0138, 0x0139, 0x013A, 0x013B, 0x013C, 0x013D, 0x013E, 0x013F,
+ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+ 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
+ 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
+ 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
+ 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
+ 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
+ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
+ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
+ 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
+ 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
+ };
+
+ private const int ColorPaletteCount = 0x210;
+
+ private const int ColorMono00 = 0x000;
+ private const int ColorMono01 = 0x001;
+ private const int ColorMono02 = 0x002;
+ private const int ColorMono04 = 0x004;
+ private const int ColorMono08 = 0x008;
+ private const int ColorMono10 = 0x010;
+ private const int ColorMono20 = 0x020;
+ private const int ColorMono40 = 0x040;
+ private const int ColorMono80 = 0x080;
+
+ private const int ColorWhite00 = 0x100;
+ private const int ColorWhite01 = 0x101;
+ private const int ColorWhite02 = 0x102;
+ private const int ColorWhite04 = 0x104;
+ private const int ColorWhite08 = 0x108;
+ private const int ColorWhite10 = 0x110;
+ private const int ColorWhite20 = 0x120;
+ private const int ColorWhite40 = 0x140;
+ private const int ColorWhite80 = 0x180;
+
+ private const int ColorDHires0 = 0x200;
+ private const int ColorDHires1 = 0x201;
+ private const int ColorDHires2 = 0x202;
+ private const int ColorDHires3 = 0x203;
+ private const int ColorDHires4 = 0x204;
+ private const int ColorDHires5 = 0x205;
+ private const int ColorDHires6 = 0x206;
+ private const int ColorDHires7 = 0x207;
+ private const int ColorDHires8 = 0x208;
+ private const int ColorDHires9 = 0x209;
+ private const int ColorDHiresA = 0x20A;
+ private const int ColorDHiresB = 0x20B;
+ private const int ColorDHiresC = 0x20C;
+ private const int ColorDHiresD = 0x20D;
+ private const int ColorDHiresE = 0x20E;
+ private const int ColorDHiresF = 0x20F;
+
+ private const int ColorLoresDataCount = 16;
+
+ private static readonly int[] ColorLores = new int[ColorLoresDataCount]
+ {
+ ColorDHires0, ColorDHires8, ColorDHires1, ColorDHires9,
+ ColorDHires2, ColorDHiresA, ColorDHires3, ColorDHiresB,
+ ColorDHires4, ColorDHiresC, ColorDHires5, ColorDHiresD,
+ ColorDHires6, ColorDHiresE, ColorDHires7, ColorDHiresF
+ };
+
+ private static readonly int[] Color7MLores = new int[2 * ColorLoresDataCount]
+ {
+ ColorDHires0, ColorDHires9, ColorDHires6, ColorDHiresF, // even columns
+ ColorDHires0, ColorDHires9, ColorDHires6, ColorDHiresF,
+ ColorDHires0, ColorDHires9, ColorDHires6, ColorDHiresF,
+ ColorDHires0, ColorDHires9, ColorDHires6, ColorDHiresF,
+ ColorDHires0, ColorDHires0, ColorDHires0, ColorDHires0, // odd columns
+ ColorDHires6, ColorDHires6, ColorDHires6, ColorDHires6,
+ ColorDHires9, ColorDHires9, ColorDHires9, ColorDHires9,
+ ColorDHiresF, ColorDHiresF, ColorDHiresF, ColorDHiresF
+ };
+
+ private static readonly int[] ColorDLores = new int[2 * ColorLoresDataCount]
+ {
+ ColorDHires0, ColorDHires4, ColorDHires8, ColorDHiresC, // even columns
+ ColorDHires1, ColorDHires5, ColorDHires9, ColorDHiresD,
+ ColorDHires2, ColorDHires6, ColorDHiresA, ColorDHiresE,
+ ColorDHires3, ColorDHires7, ColorDHiresB, ColorDHiresF,
+ ColorDHires0, ColorDHires8, ColorDHires1, ColorDHires9, // odd columns
+ ColorDHires2, ColorDHiresA, ColorDHires3, ColorDHiresB,
+ ColorDHires4, ColorDHiresC, ColorDHires5, ColorDHiresD,
+ ColorDHires6, ColorDHiresE, ColorDHires7, ColorDHiresF
+ };
+
+ private const int ColorHiresDataCount = 8;
+
+ private static readonly int[] ColorHires = new int[4 * ColorHiresDataCount]
+ {
+ ColorDHires0, ColorDHires0, ColorDHires9, ColorDHiresF, // even columns, high bit off
+ ColorDHires0, ColorDHires6, ColorDHiresF, ColorDHiresF,
+ ColorDHires0, ColorDHires0, ColorDHires3, ColorDHiresF, // even columns, high bit on
+ ColorDHires0, ColorDHiresC, ColorDHiresF, ColorDHiresF,
+ ColorDHires0, ColorDHires0, ColorDHires6, ColorDHiresF, // odd columns, high bit off
+ ColorDHires0, ColorDHires9, ColorDHiresF, ColorDHiresF,
+ ColorDHires0, ColorDHires0, ColorDHiresC, ColorDHiresF, // odd columns, high bit on
+ ColorDHires0, ColorDHires3, ColorDHiresF, ColorDHiresF
+ };
+
+ private const int CyclesPerHBlank = 25;
+ private const int CyclesPerHSync = 65;
+ private const int CyclesPerFlush = 8 * CyclesPerHSync;
+ private const int CyclesPerSecond = 1022730;
+
+ private const int HCountPreset = 0x40; // hcount preset after hcount overflows -> HPE' low [3-13]
+ private const int HCountLeaveHBlank = 0x58; // hcount when leaving hblank [3-15]
+ private const int VCountPresetNtsc = 0xFA; // vcount preset after vcount overflows (NTSC) [3-13]
+ private const int VCountPresetPal = 0xC8; // vcount preset after vcount overflows (PAL) [3-17]
+ private const int VLineEnterVBlank = 192; // vline when entering vblank (NTSC & PAL) [3-17]
+ private const int VLineTriggerPreset = 256; // vline when vcount overflows and presets (NTSC & PAL) [3-15, 3-16]
+ private const int VLineLeaveVBlankNtsc = 262; // vline when leaving vblank (NTSC) [3-13]
+ private const int VLineLeaveVBlankPal = 312; // vline when leaving vblank (PAL) [3-17]
+ private const int VSyncsPerFlash = 16; // flash count using vcount overflow [3-17]
+
+ public const int ModeCount = 16;
+
+ public const int Mode0 = 0x0;
+ public const int Mode1 = 0x1;
+ public const int Mode2 = 0x2;
+ public const int Mode3 = 0x3;
+ public const int Mode4 = 0x4;
+ public const int Mode5 = 0x5;
+ public const int Mode6 = 0x6;
+ public const int Mode7 = 0x7;
+ public const int Mode8 = 0x8;
+ public const int Mode9 = 0x9;
+ public const int ModeA = 0xA;
+ public const int ModeB = 0xB;
+ public const int ModeC = 0xC;
+ public const int ModeD = 0xD;
+ public const int ModeE = 0xE;
+ public const int ModeF = 0xF;
+
+ private readonly Action[] FlushRowMode;
+
+ private const int Width = 560;
+ private const int Height = VLineEnterVBlank;
+
+ private const int TextHeight = 8;
+ private const int TextRows = Height / TextHeight;
+
+ private const int LoresHeight = 4;
+ private const int LoresRows = Height / LoresHeight;
+
+ private const int MixedHeight = 160;
+ private const int MixedCellIndex = MixedHeight * CellColumns;
+ }
+}
diff --git a/Virtu/Wpf/Jellyfish.Virtu.Wpf.csproj b/Virtu/Wpf/Jellyfish.Virtu.Wpf.csproj
index f3c0872..5071344 100644
--- a/Virtu/Wpf/Jellyfish.Virtu.Wpf.csproj
+++ b/Virtu/Wpf/Jellyfish.Virtu.Wpf.csproj
@@ -1,250 +1,250 @@
-
-
-
- Debug
- AnyCPU
- 8.0.30703
- 2.0
- {C152D47E-BBC1-4C35-8646-465180720A72}
- WinExe
- Properties
- Jellyfish.Virtu
- Jellyfish.Virtu
- v4.5
- 512
- {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- 4
- AppIcon.ico
-
-
- AnyCPU
- true
- full
- false
- bin\
- DEBUG;TRACE;WPF;WINDOWS;CODE_ANALYSIS
- prompt
- 4
- true
- AllRules.ruleset
- false
-
-
- AnyCPU
- pdbonly
- true
- bin\
- TRACE;WPF;WINDOWS;CODE_ANALYSIS
- prompt
- 4
- true
- AllRules.ruleset
- false
-
-
- Jellyfish.Virtu.MainApp
-
-
- false
-
-
- ..\..\..\Jellyfish\StrongName.snk
-
-
- false
-
-
- http://timestamp.verisign.com/scripts/timestamp.dll
-
-
- 7E57BBFFA7D9A57530AC8A09E5236FE0AAB041C2
-
-
- ..\..\..\Jellyfish\CodeSign.pfx
-
-
-
-
-
-
-
-
-
- 4.0
-
-
-
-
-
-
- MSBuild:Compile
- Designer
-
-
- MSBuild:Compile
- Designer
-
-
- MSBuild:Compile
- Designer
-
-
- MainApp.xaml
- Code
-
-
- MainPage.xaml
-
-
- MainWindow.xaml
- Code
-
-
-
-
- Core\Cassette.cs
-
-
- Core\Cpu.cs
-
-
- Core\CpuData.cs
-
-
- Core\Disk525.cs
-
-
- Core\DiskDsk.cs
-
-
- Core\DiskIIController.cs
-
-
- Core\DiskIIDrive.cs
-
-
- Core\DiskNib.cs
-
-
- Core\GamePort.cs
-
-
- GlobalSuppressions.cs
-
-
- Core\Keyboard.cs
-
-
- Core\Machine.cs
-
-
- Core\MachineComponent.cs
-
-
- Core\MachineEvents.cs
-
-
- Core\Memory.cs
-
-
- Core\MemoryData.cs
-
-
- Core\NoSlotClock.cs
-
-
- Core\PeripheralCard.cs
-
-
- Properties\Strings.Designer.cs
- True
- True
- Strings.resx
-
-
- Services\AudioService.cs
-
-
- Services\DebugService.cs
-
-
- Services\GamePortService.cs
-
-
- Services\IsolatedStorageService.cs
-
-
- Services\KeyboardService.cs
-
-
- Services\MachineService.cs
-
-
- Services\MachineServices.cs
-
-
- Services\StorageService.cs
-
-
- Services\VideoService.cs
-
-
- Core\Speaker.cs
-
-
- Core\Video.cs
-
-
- Core\VideoData.cs
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties\Strings.resx
- ResXFileCodeGenerator
- Strings.Designer.cs
-
-
-
-
- Disks\Default.dsk
-
-
- Roms\AppleIIe.rom
-
-
- Roms\DiskII.rom
-
-
-
-
- CustomDictionary.xml
-
-
-
-
- {93900841-7250-4D3A-837E-43EE3FD118DC}
- Jellyfish.Library.Wpf
-
-
-
-
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {C152D47E-BBC1-4C35-8646-465180720A72}
+ WinExe
+ Properties
+ Jellyfish.Virtu
+ Jellyfish.Virtu
+ v4.5
+ 512
+ {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ 4
+ AppIcon.ico
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\
+ DEBUG;TRACE;WPF;WINDOWS;CODE_ANALYSIS
+ prompt
+ 4
+ true
+ AllRules.ruleset
+ false
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\
+ TRACE;WPF;WINDOWS;CODE_ANALYSIS
+ prompt
+ 4
+ true
+ AllRules.ruleset
+ false
+
+
+ Jellyfish.Virtu.MainApp
+
+
+ false
+
+
+ ..\..\..\Jellyfish\StrongName.snk
+
+
+ false
+
+
+ http://timestamp.verisign.com/scripts/timestamp.dll
+
+
+ 7E57BBFFA7D9A57530AC8A09E5236FE0AAB041C2
+
+
+ ..\..\..\Jellyfish\CodeSign.pfx
+
+
+
+
+
+
+
+
+
+ 4.0
+
+
+
+
+
+
+ MSBuild:Compile
+ Designer
+
+
+ MSBuild:Compile
+ Designer
+
+
+ MSBuild:Compile
+ Designer
+
+
+ MainApp.xaml
+ Code
+
+
+ MainPage.xaml
+
+
+ MainWindow.xaml
+ Code
+
+
+
+
+ Core\Cassette.cs
+
+
+ Core\Cpu.cs
+
+
+ Core\CpuData.cs
+
+
+ Core\Disk525.cs
+
+
+ Core\DiskDsk.cs
+
+
+ Core\DiskIIController.cs
+
+
+ Core\DiskIIDrive.cs
+
+
+ Core\DiskNib.cs
+
+
+ Core\GamePort.cs
+
+
+ GlobalSuppressions.cs
+
+
+ Core\Keyboard.cs
+
+
+ Core\Machine.cs
+
+
+ Core\MachineComponent.cs
+
+
+ Core\MachineEvents.cs
+
+
+ Core\Memory.cs
+
+
+ Core\MemoryData.cs
+
+
+ Core\NoSlotClock.cs
+
+
+ Core\PeripheralCard.cs
+
+
+ Properties\Strings.Designer.cs
+ True
+ True
+ Strings.resx
+
+
+ Services\AudioService.cs
+
+
+ Services\DebugService.cs
+
+
+ Services\GamePortService.cs
+
+
+ Services\IsolatedStorageService.cs
+
+
+ Services\KeyboardService.cs
+
+
+ Services\MachineService.cs
+
+
+ Services\MachineServices.cs
+
+
+ Services\StorageService.cs
+
+
+ Services\VideoService.cs
+
+
+ Core\Speaker.cs
+
+
+ Core\Video.cs
+
+
+ Core\VideoData.cs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Properties\Strings.resx
+ ResXFileCodeGenerator
+ Strings.Designer.cs
+
+
+
+
+ Disks\Default.dsk
+
+
+ Roms\AppleIIe.rom
+
+
+ Roms\DiskII.rom
+
+
+
+
+ CustomDictionary.xml
+
+
+
+
+ {93900841-7250-4D3A-837E-43EE3FD118DC}
+ Jellyfish.Library.Wpf
+
+
+
+
\ No newline at end of file
diff --git a/Virtu/Wpf/Jellyfish.Virtu.Wpf.sln b/Virtu/Wpf/Jellyfish.Virtu.Wpf.sln
index 0e69568..07cfaf5 100644
--- a/Virtu/Wpf/Jellyfish.Virtu.Wpf.sln
+++ b/Virtu/Wpf/Jellyfish.Virtu.Wpf.sln
@@ -1,26 +1,26 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2012
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Library.Wpf", "..\..\Library\Wpf\Jellyfish.Library.Wpf.csproj", "{93900841-7250-4D3A-837E-43EE3FD118DC}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Virtu.Wpf", "Jellyfish.Virtu.Wpf.csproj", "{C152D47E-BBC1-4C35-8646-465180720A72}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {93900841-7250-4D3A-837E-43EE3FD118DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {93900841-7250-4D3A-837E-43EE3FD118DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {93900841-7250-4D3A-837E-43EE3FD118DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {93900841-7250-4D3A-837E-43EE3FD118DC}.Release|Any CPU.Build.0 = Release|Any CPU
- {C152D47E-BBC1-4C35-8646-465180720A72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {C152D47E-BBC1-4C35-8646-465180720A72}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {C152D47E-BBC1-4C35-8646-465180720A72}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {C152D47E-BBC1-4C35-8646-465180720A72}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Library.Wpf", "..\..\Library\Wpf\Jellyfish.Library.Wpf.csproj", "{93900841-7250-4D3A-837E-43EE3FD118DC}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Virtu.Wpf", "Jellyfish.Virtu.Wpf.csproj", "{C152D47E-BBC1-4C35-8646-465180720A72}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {93900841-7250-4D3A-837E-43EE3FD118DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {93900841-7250-4D3A-837E-43EE3FD118DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {93900841-7250-4D3A-837E-43EE3FD118DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {93900841-7250-4D3A-837E-43EE3FD118DC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C152D47E-BBC1-4C35-8646-465180720A72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C152D47E-BBC1-4C35-8646-465180720A72}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C152D47E-BBC1-4C35-8646-465180720A72}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C152D47E-BBC1-4C35-8646-465180720A72}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Virtu/Wpf/MainApp.xaml b/Virtu/Wpf/MainApp.xaml
index 7dc677f..67df395 100644
--- a/Virtu/Wpf/MainApp.xaml
+++ b/Virtu/Wpf/MainApp.xaml
@@ -1,8 +1,8 @@
-
-
-
-
+
+
+
+
diff --git a/Virtu/Wpf/MainApp.xaml.cs b/Virtu/Wpf/MainApp.xaml.cs
index af1ea1d..c1ab7e0 100644
--- a/Virtu/Wpf/MainApp.xaml.cs
+++ b/Virtu/Wpf/MainApp.xaml.cs
@@ -1,14 +1,14 @@
-using System.Security;
-using Jellyfish.Library;
-
-namespace Jellyfish.Virtu
-{
- public sealed partial class MainApp : ApplicationBase
- {
- [SecurityCritical]
- public MainApp() :
- base("Virtu")
- {
- }
- }
-}
+using System.Security;
+using Jellyfish.Library;
+
+namespace Jellyfish.Virtu
+{
+ public sealed partial class MainApp : ApplicationBase
+ {
+ [SecurityCritical]
+ public MainApp() :
+ base("Virtu")
+ {
+ }
+ }
+}
diff --git a/Virtu/Wpf/MainPage.xaml b/Virtu/Wpf/MainPage.xaml
index 8640c62..7437966 100644
--- a/Virtu/Wpf/MainPage.xaml
+++ b/Virtu/Wpf/MainPage.xaml
@@ -1,23 +1,23 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Virtu/Wpf/MainPage.xaml.cs b/Virtu/Wpf/MainPage.xaml.cs
index 041d411..b3da90f 100644
--- a/Virtu/Wpf/MainPage.xaml.cs
+++ b/Virtu/Wpf/MainPage.xaml.cs
@@ -1,88 +1,88 @@
-using System;
-using System.ComponentModel;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Media;
-using Jellyfish.Virtu.Services;
-using Microsoft.Win32;
-
-namespace Jellyfish.Virtu
-{
- public sealed partial class MainPage : UserControl, IDisposable
- {
- public MainPage()
- {
- InitializeComponent();
-
- if (!DesignerProperties.GetIsInDesignMode(this))
- {
- _debugService = DebugService.Default;
- _storageService = new WpfStorageService(_machine);
- _keyboardService = new WpfKeyboardService(_machine, this);
- _gamePortService = new GamePortService(_machine); // not connected
- _audioService = new WpfAudioService(_machine, this);
- _videoService = new WpfVideoService(_machine, this, _image);
-
- _machine.Services.AddService(typeof(DebugService), _debugService);
- _machine.Services.AddService(typeof(StorageService), _storageService);
- _machine.Services.AddService(typeof(KeyboardService), _keyboardService);
- _machine.Services.AddService(typeof(GamePortService), _gamePortService);
- _machine.Services.AddService(typeof(AudioService), _audioService);
- _machine.Services.AddService(typeof(VideoService), _videoService);
-
- Loaded += (sender, e) => _machine.Start();
- CompositionTarget.Rendering += OnCompositionTargetRendering;
- Application.Current.Exit += (sender, e) => _machine.Stop();
-
- _disk1Button.Click += (sender, e) => OnDiskButtonClick(0);
- _disk2Button.Click += (sender, e) => OnDiskButtonClick(1);
- }
- }
-
- public void Dispose()
- {
- _machine.Dispose();
- _debugService.Dispose();
- _storageService.Dispose();
- _keyboardService.Dispose();
- _gamePortService.Dispose();
- _audioService.Dispose();
- _videoService.Dispose();
- }
-
- public void WriteMessage(string message)
- {
- _debugText.Text += message + Environment.NewLine;
- _debugScrollViewer.UpdateLayout();
- _debugScrollViewer.ScrollToVerticalOffset(double.MaxValue);
- }
-
- private void OnCompositionTargetRendering(object sender, EventArgs e)
- {
- _keyboardService.Update();
- _gamePortService.Update();
- _videoService.Update();
- }
-
- private void OnDiskButtonClick(int drive)
- {
- var dialog = new OpenFileDialog() { Filter = "Disk Files (*.do;*.dsk;*.nib;*.po)|*.do;*.dsk;*.nib;*.po|All Files (*.*)|*.*" };
- bool? result = dialog.ShowDialog();
- if (result.HasValue && result.Value)
- {
- _machine.Pause();
- StorageService.LoadFile(dialog.FileName, stream => _machine.BootDiskII.Drives[drive].InsertDisk(dialog.FileName, stream, false));
- _machine.Unpause();
- }
- }
-
- private Machine _machine = new Machine();
-
- private DebugService _debugService;
- private StorageService _storageService;
- private KeyboardService _keyboardService;
- private GamePortService _gamePortService;
- private AudioService _audioService;
- private VideoService _videoService;
- }
-}
+using System;
+using System.ComponentModel;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+using Jellyfish.Virtu.Services;
+using Microsoft.Win32;
+
+namespace Jellyfish.Virtu
+{
+ public sealed partial class MainPage : UserControl, IDisposable
+ {
+ public MainPage()
+ {
+ InitializeComponent();
+
+ if (!DesignerProperties.GetIsInDesignMode(this))
+ {
+ _debugService = DebugService.Default;
+ _storageService = new WpfStorageService(_machine);
+ _keyboardService = new WpfKeyboardService(_machine, this);
+ _gamePortService = new GamePortService(_machine); // not connected
+ _audioService = new WpfAudioService(_machine, this);
+ _videoService = new WpfVideoService(_machine, this, _image);
+
+ _machine.Services.AddService(typeof(DebugService), _debugService);
+ _machine.Services.AddService(typeof(StorageService), _storageService);
+ _machine.Services.AddService(typeof(KeyboardService), _keyboardService);
+ _machine.Services.AddService(typeof(GamePortService), _gamePortService);
+ _machine.Services.AddService(typeof(AudioService), _audioService);
+ _machine.Services.AddService(typeof(VideoService), _videoService);
+
+ Loaded += (sender, e) => _machine.Start();
+ CompositionTarget.Rendering += OnCompositionTargetRendering;
+ Application.Current.Exit += (sender, e) => _machine.Stop();
+
+ _disk1Button.Click += (sender, e) => OnDiskButtonClick(0);
+ _disk2Button.Click += (sender, e) => OnDiskButtonClick(1);
+ }
+ }
+
+ public void Dispose()
+ {
+ _machine.Dispose();
+ _debugService.Dispose();
+ _storageService.Dispose();
+ _keyboardService.Dispose();
+ _gamePortService.Dispose();
+ _audioService.Dispose();
+ _videoService.Dispose();
+ }
+
+ public void WriteMessage(string message)
+ {
+ _debugText.Text += message + Environment.NewLine;
+ _debugScrollViewer.UpdateLayout();
+ _debugScrollViewer.ScrollToVerticalOffset(double.MaxValue);
+ }
+
+ private void OnCompositionTargetRendering(object sender, EventArgs e)
+ {
+ _keyboardService.Update();
+ _gamePortService.Update();
+ _videoService.Update();
+ }
+
+ private void OnDiskButtonClick(int drive)
+ {
+ var dialog = new OpenFileDialog() { Filter = "Disk Files (*.do;*.dsk;*.nib;*.po)|*.do;*.dsk;*.nib;*.po|All Files (*.*)|*.*" };
+ bool? result = dialog.ShowDialog();
+ if (result.HasValue && result.Value)
+ {
+ _machine.Pause();
+ StorageService.LoadFile(dialog.FileName, stream => _machine.BootDiskII.Drives[drive].InsertDisk(dialog.FileName, stream, false));
+ _machine.Unpause();
+ }
+ }
+
+ private Machine _machine = new Machine();
+
+ private DebugService _debugService;
+ private StorageService _storageService;
+ private KeyboardService _keyboardService;
+ private GamePortService _gamePortService;
+ private AudioService _audioService;
+ private VideoService _videoService;
+ }
+}
diff --git a/Virtu/Wpf/MainWindow.xaml b/Virtu/Wpf/MainWindow.xaml
index 2d445e3..cc9f594 100644
--- a/Virtu/Wpf/MainWindow.xaml
+++ b/Virtu/Wpf/MainWindow.xaml
@@ -1,7 +1,7 @@
-
-
-
+
+
+
diff --git a/Virtu/Wpf/MainWindow.xaml.cs b/Virtu/Wpf/MainWindow.xaml.cs
index 92d6340..538825e 100644
--- a/Virtu/Wpf/MainWindow.xaml.cs
+++ b/Virtu/Wpf/MainWindow.xaml.cs
@@ -1,12 +1,12 @@
-using System.Windows;
-
-namespace Jellyfish.Virtu
-{
- public sealed partial class MainWindow : Window
- {
- public MainWindow()
- {
- InitializeComponent();
- }
- }
-}
+using System.Windows;
+
+namespace Jellyfish.Virtu
+{
+ public sealed partial class MainWindow : Window
+ {
+ public MainWindow()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Virtu/Wpf/Properties/AssemblyInfo.cs b/Virtu/Wpf/Properties/AssemblyInfo.cs
index 198f9bc..ba014fe 100644
--- a/Virtu/Wpf/Properties/AssemblyInfo.cs
+++ b/Virtu/Wpf/Properties/AssemblyInfo.cs
@@ -1,26 +1,26 @@
-using System;
-using System.Reflection;
-using System.Resources;
-using System.Runtime.InteropServices;
-using System.Windows;
-using Jellyfish.Library;
-using Jellyfish.Virtu;
-
-[assembly: AssemblyTitle("Virtu")]
-[assembly: AssemblyDescription("Apple IIe Emulator")]
-[assembly: AssemblyProduct("Jellyfish.Virtu.Wpf")]
-[assembly: AssemblyCompany("Digital Jellyfish Design Ltd")]
-[assembly: AssemblyCopyright("Copyright © 1995-2012 Digital Jellyfish Design Ltd")]
-[assembly: AssemblyMetadata("Developers", "Sean Fausett & Nick Westgate")]
-
-[assembly: AssemblyVersion(Machine.Version)]
-[assembly: AssemblyFileVersion(Machine.Version)]
-[assembly: AssemblyInformationalVersion(Machine.Version)]
-
-[assembly: CLSCompliant(false)]
-[assembly: ComVisible(false)]
-[assembly: Guid("89a50370-1ed9-4cf1-ad08-043b6e6f3c90")]
-
-[assembly: NeutralResourcesLanguage("en")]
-
-[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]
+using System;
+using System.Reflection;
+using System.Resources;
+using System.Runtime.InteropServices;
+using System.Windows;
+using Jellyfish.Library;
+using Jellyfish.Virtu;
+
+[assembly: AssemblyTitle("Virtu")]
+[assembly: AssemblyDescription("Apple IIe Emulator")]
+[assembly: AssemblyProduct("Jellyfish.Virtu.Wpf")]
+[assembly: AssemblyCompany("Digital Jellyfish Design Ltd")]
+[assembly: AssemblyCopyright("Copyright © 1995-2012 Digital Jellyfish Design Ltd")]
+[assembly: AssemblyMetadata("Developers", "Sean Fausett & Nick Westgate")]
+
+[assembly: AssemblyVersion(Machine.Version)]
+[assembly: AssemblyFileVersion(Machine.Version)]
+[assembly: AssemblyInformationalVersion(Machine.Version)]
+
+[assembly: CLSCompliant(false)]
+[assembly: ComVisible(false)]
+[assembly: Guid("89a50370-1ed9-4cf1-ad08-043b6e6f3c90")]
+
+[assembly: NeutralResourcesLanguage("en")]
+
+[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]
diff --git a/Virtu/Wpf/Services/WpfAudioService.cs b/Virtu/Wpf/Services/WpfAudioService.cs
index 3f100e3..1bad97a 100644
--- a/Virtu/Wpf/Services/WpfAudioService.cs
+++ b/Virtu/Wpf/Services/WpfAudioService.cs
@@ -1,60 +1,60 @@
-using System;
-using System.Runtime.InteropServices;
-using System.Security;
-using System.Windows;
-using System.Windows.Controls;
-using Jellyfish.Library;
-
-namespace Jellyfish.Virtu.Services
-{
- public sealed class WpfAudioService : AudioService
- {
- [SecurityCritical]
- public WpfAudioService(Machine machine, UserControl page) :
- base(machine)
- {
- if (page == null)
- {
- throw new ArgumentNullException("page");
- }
-
- _directSound = new DirectSound(SampleRate, SampleChannels, SampleBits, SampleSize, OnDirectSoundUpdate);
-
- page.Loaded += (sender, e) =>
- {
- var window = Window.GetWindow(page);
- _directSound.Start(window.GetHandle());
- window.Closed += (_sender, _e) => _directSound.Stop();
- };
- }
-
- public override void SetVolume(float volume)
- {
- _directSound.SetVolume(volume);
- }
-
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- {
- _directSound.Dispose();
- }
-
- base.Dispose(disposing);
- }
-
- private void OnDirectSoundUpdate(IntPtr buffer, int bufferSize) // audio thread
- {
- //if (_count++ % (1000 / SampleLatency) == 0)
- //{
- // DebugService.WriteLine("OnDirectSoundUpdate");
- //}
-
- Marshal.Copy(Source, 0, buffer, bufferSize);
- Update();
- }
-
- private DirectSound _directSound;
- //private int _count;
- }
-}
+using System;
+using System.Runtime.InteropServices;
+using System.Security;
+using System.Windows;
+using System.Windows.Controls;
+using Jellyfish.Library;
+
+namespace Jellyfish.Virtu.Services
+{
+ public sealed class WpfAudioService : AudioService
+ {
+ [SecurityCritical]
+ public WpfAudioService(Machine machine, UserControl page) :
+ base(machine)
+ {
+ if (page == null)
+ {
+ throw new ArgumentNullException("page");
+ }
+
+ _directSound = new DirectSound(SampleRate, SampleChannels, SampleBits, SampleSize, OnDirectSoundUpdate);
+
+ page.Loaded += (sender, e) =>
+ {
+ var window = Window.GetWindow(page);
+ _directSound.Start(window.GetHandle());
+ window.Closed += (_sender, _e) => _directSound.Stop();
+ };
+ }
+
+ public override void SetVolume(float volume)
+ {
+ _directSound.SetVolume(volume);
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ _directSound.Dispose();
+ }
+
+ base.Dispose(disposing);
+ }
+
+ private void OnDirectSoundUpdate(IntPtr buffer, int bufferSize) // audio thread
+ {
+ //if (_count++ % (1000 / SampleLatency) == 0)
+ //{
+ // DebugService.WriteLine("OnDirectSoundUpdate");
+ //}
+
+ Marshal.Copy(Source, 0, buffer, bufferSize);
+ Update();
+ }
+
+ private DirectSound _directSound;
+ //private int _count;
+ }
+}
diff --git a/Virtu/Wpf/Services/WpfDebugService.cs b/Virtu/Wpf/Services/WpfDebugService.cs
index 6ce27e1..b015e58 100644
--- a/Virtu/Wpf/Services/WpfDebugService.cs
+++ b/Virtu/Wpf/Services/WpfDebugService.cs
@@ -1,26 +1,26 @@
-using System;
-using Jellyfish.Library;
-
-namespace Jellyfish.Virtu.Services
-{
- public sealed class WpfDebugService : DebugService
- {
- public WpfDebugService(Machine machine, MainPage page) :
- base(machine)
- {
- if (page == null)
- {
- throw new ArgumentNullException("page");
- }
-
- _page = page;
- }
-
- protected override void OnWriteMessage(string message)
- {
- _page.Dispatcher.Post(() => _page.WriteMessage(message));
- }
-
- private MainPage _page;
- }
-}
+using System;
+using Jellyfish.Library;
+
+namespace Jellyfish.Virtu.Services
+{
+ public sealed class WpfDebugService : DebugService
+ {
+ public WpfDebugService(Machine machine, MainPage page) :
+ base(machine)
+ {
+ if (page == null)
+ {
+ throw new ArgumentNullException("page");
+ }
+
+ _page = page;
+ }
+
+ protected override void OnWriteMessage(string message)
+ {
+ _page.Dispatcher.Post(() => _page.WriteMessage(message));
+ }
+
+ private MainPage _page;
+ }
+}
diff --git a/Virtu/Wpf/Services/WpfKeyboardService.cs b/Virtu/Wpf/Services/WpfKeyboardService.cs
index 7d9cc82..7689a65 100644
--- a/Virtu/Wpf/Services/WpfKeyboardService.cs
+++ b/Virtu/Wpf/Services/WpfKeyboardService.cs
@@ -1,298 +1,298 @@
-using System;
-using System.Diagnostics.CodeAnalysis;
-using System.Linq;
-using System.Windows.Controls;
-using System.Windows.Input;
-
-namespace Jellyfish.Virtu.Services
-{
- public sealed class WpfKeyboardService : KeyboardService
- {
- public WpfKeyboardService(Machine machine, UserControl page) :
- base(machine)
- {
- if (page == null)
- {
- throw new ArgumentNullException("page");
- }
-
- page.KeyDown += OnPageKeyDown;
- page.KeyUp += OnPageKeyUp;
- page.GotKeyboardFocus += (sender, e) => _updateAnyKeyDown = true;
- }
-
- public override bool IsKeyDown(int key)
- {
- return IsKeyDown((Key)key);
- }
-
- public override void Update() // main thread
- {
- var keyboard = System.Windows.Input.Keyboard.PrimaryDevice;
- if (_updateAnyKeyDown)
- {
- _updateAnyKeyDown = false;
- IsAnyKeyDown = false;
- for (int i = 0; i < KeyValues.Length; i++)
- {
- var key = KeyValues[i];
- bool isKeyDown = keyboard.IsKeyDown(key);
- _states[(int)key] = isKeyDown;
- if (isKeyDown)
- {
- IsAnyKeyDown = true;
- }
- }
- }
-
- IsControlKeyDown = ((keyboard.Modifiers & ModifierKeys.Control) != 0);
- IsShiftKeyDown = ((keyboard.Modifiers & ModifierKeys.Shift) != 0);
-
- IsOpenAppleKeyDown = keyboard.IsKeyDown(Key.LeftAlt) || IsKeyDown(Key.NumPad0);
- IsCloseAppleKeyDown = keyboard.IsKeyDown(Key.RightAlt) || IsKeyDown(Key.Decimal);
- IsResetKeyDown = IsControlKeyDown && keyboard.IsKeyDown(Key.Back);
-
- base.Update();
- }
-
- private bool IsKeyDown(Key key)
- {
- return _states[(int)key];
- }
-
- private void OnPageKeyDown(object sender, KeyEventArgs e)
- {
- //DebugService.WriteLine(string.Concat("OnPageKeyDn: Key=", e.Key));
-
- _states[(int)((e.Key == Key.System) ? e.SystemKey : e.Key)] = true;
- _updateAnyKeyDown = false;
- IsAnyKeyDown = true;
-
- int asciiKey = GetAsciiKey(e.Key, e.KeyboardDevice);
- if (asciiKey >= 0)
- {
- Machine.Keyboard.Latch = asciiKey;
- e.Handled = true;
- }
-
- Update();
- }
-
- private void OnPageKeyUp(object sender, KeyEventArgs e)
- {
- //DebugService.WriteLine(string.Concat("OnPageKeyUp: Key=", e.Key));
-
- _states[(int)((e.Key == Key.System) ? e.SystemKey : e.Key)] = false;
- _updateAnyKeyDown = true;
-
- bool control = ((e.KeyboardDevice.Modifiers & ModifierKeys.Control) != 0);
-
- if (control && (e.Key == Key.Divide))
- {
- Machine.Cpu.IsThrottled ^= true;
- }
- else if (control && (e.Key == Key.Multiply))
- {
- Machine.Video.IsMonochrome ^= true;
- }
- else if (control && (e.Key == Key.Subtract))
- {
- Machine.Video.IsFullScreen ^= true;
- }
-
- Update();
- }
-
- [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
- [SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode")]
- private static int GetAsciiKey(Key key, KeyboardDevice keyboard)
- {
- bool control = ((keyboard.Modifiers & ModifierKeys.Control) != 0);
- bool shift = ((keyboard.Modifiers & ModifierKeys.Shift) != 0);
- bool capsLock = shift ^ keyboard.IsKeyToggled(Key.CapsLock);
-
- switch (key)
- {
- case Key.Left:
- return 0x08;
-
- case Key.Tab:
- return 0x09;
-
- case Key.Down:
- return 0x0A;
-
- case Key.Up:
- return 0x0B;
-
- case Key.Enter:
- return 0x0D;
-
- case Key.Right:
- return 0x15;
-
- case Key.Escape:
- return 0x1B;
-
- case Key.Back:
- return control ? -1 : 0x7F;
-
- case Key.Space:
- return ' ';
-
- case Key.D1:
- return shift ? '!' : '1';
-
- case Key.D2:
- return control ? 0x00 : shift ? '@' : '2';
-
- case Key.D3:
- return shift ? '#' : '3';
-
- case Key.D4:
- return shift ? '$' : '4';
-
- case Key.D5:
- return shift ? '%' : '5';
-
- case Key.D6:
- return control ? 0x1E : shift ? '^' : '6';
-
- case Key.D7:
- return shift ? '&' : '7';
-
- case Key.D8:
- return shift ? '*' : '8';
-
- case Key.D9:
- return shift ? '(' : '9';
-
- case Key.D0:
- return shift ? ')' : '0';
-
- case Key.A:
- return control ? 0x01 : capsLock ? 'A' : 'a';
-
- case Key.B:
- return control ? 0x02 : capsLock ? 'B' : 'b';
-
- case Key.C:
- return control ? 0x03 : capsLock ? 'C' : 'c';
-
- case Key.D:
- return control ? 0x04 : capsLock ? 'D' : 'd';
-
- case Key.E:
- return control ? 0x05 : capsLock ? 'E' : 'e';
-
- case Key.F:
- return control ? 0x06 : capsLock ? 'F' : 'f';
-
- case Key.G:
- return control ? 0x07 : capsLock ? 'G' : 'g';
-
- case Key.H:
- return control ? 0x08 : capsLock ? 'H' : 'h';
-
- case Key.I:
- return control ? 0x09 : capsLock ? 'I' : 'i';
-
- case Key.J:
- return control ? 0x0A : capsLock ? 'J' : 'j';
-
- case Key.K:
- return control ? 0x0B : capsLock ? 'K' : 'k';
-
- case Key.L:
- return control ? 0x0C : capsLock ? 'L' : 'l';
-
- case Key.M:
- return control ? 0x0D : capsLock ? 'M' : 'm';
-
- case Key.N:
- return control ? 0x0E : capsLock ? 'N' : 'n';
-
- case Key.O:
- return control ? 0x0F : capsLock ? 'O' : 'o';
-
- case Key.P:
- return control ? 0x10 : capsLock ? 'P' : 'p';
-
- case Key.Q:
- return control ? 0x11 : capsLock ? 'Q' : 'q';
-
- case Key.R:
- return control ? 0x12 : capsLock ? 'R' : 'r';
-
- case Key.S:
- return control ? 0x13 : capsLock ? 'S' : 's';
-
- case Key.T:
- return control ? 0x14 : capsLock ? 'T' : 't';
-
- case Key.U:
- return control ? 0x15 : capsLock ? 'U' : 'u';
-
- case Key.V:
- return control ? 0x16 : capsLock ? 'V' : 'v';
-
- case Key.W:
- return control ? 0x17 : capsLock ? 'W' : 'w';
-
- case Key.X:
- return control ? 0x18 : capsLock ? 'X' : 'x';
-
- case Key.Y:
- return control ? 0x19 : capsLock ? 'Y' : 'y';
-
- case Key.Z:
- return control ? 0x1A : capsLock ? 'Z' : 'z';
-
- case Key.Oem1:
- return shift ? ':' : ';';
-
- case Key.Oem2:
- return shift ? '?' : '/';
-
- case Key.Oem3:
- return shift ? '~' : '`';
-
- case Key.Oem4:
- return shift ? '{' : '[';
-
- case Key.Oem5:
- return control ? 0x1C : shift ? '|' : '\\';
-
- case Key.Oem6:
- return control ? 0x1D : shift ? '}' : ']';
-
- case Key.Oem7:
- return shift ? '"' : '\'';
-
- case Key.OemMinus:
- return control ? 0x1F : shift ? '_' : '-';
-
- case Key.OemPlus:
- return shift ? '+' : '=';
-
- case Key.OemComma:
- return shift ? '<' : ',';
-
- case Key.OemPeriod:
- return shift ? '>' : '.';
- }
-
- return -1;
- }
-
- private static readonly Key[] KeyValues =
- (from key in (Key[])Enum.GetValues(typeof(Key))
- where (key != Key.None) // filter Key.None; avoids validation exception
- select key).ToArray();
-
- private static readonly int KeyCount = (int)(KeyValues.Max()) + 1;
-
- private bool[] _states = new bool[KeyCount];
- private bool _updateAnyKeyDown;
- }
-}
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using System.Windows.Controls;
+using System.Windows.Input;
+
+namespace Jellyfish.Virtu.Services
+{
+ public sealed class WpfKeyboardService : KeyboardService
+ {
+ public WpfKeyboardService(Machine machine, UserControl page) :
+ base(machine)
+ {
+ if (page == null)
+ {
+ throw new ArgumentNullException("page");
+ }
+
+ page.KeyDown += OnPageKeyDown;
+ page.KeyUp += OnPageKeyUp;
+ page.GotKeyboardFocus += (sender, e) => _updateAnyKeyDown = true;
+ }
+
+ public override bool IsKeyDown(int key)
+ {
+ return IsKeyDown((Key)key);
+ }
+
+ public override void Update() // main thread
+ {
+ var keyboard = System.Windows.Input.Keyboard.PrimaryDevice;
+ if (_updateAnyKeyDown)
+ {
+ _updateAnyKeyDown = false;
+ IsAnyKeyDown = false;
+ for (int i = 0; i < KeyValues.Length; i++)
+ {
+ var key = KeyValues[i];
+ bool isKeyDown = keyboard.IsKeyDown(key);
+ _states[(int)key] = isKeyDown;
+ if (isKeyDown)
+ {
+ IsAnyKeyDown = true;
+ }
+ }
+ }
+
+ IsControlKeyDown = ((keyboard.Modifiers & ModifierKeys.Control) != 0);
+ IsShiftKeyDown = ((keyboard.Modifiers & ModifierKeys.Shift) != 0);
+
+ IsOpenAppleKeyDown = keyboard.IsKeyDown(Key.LeftAlt) || IsKeyDown(Key.NumPad0);
+ IsCloseAppleKeyDown = keyboard.IsKeyDown(Key.RightAlt) || IsKeyDown(Key.Decimal);
+ IsResetKeyDown = IsControlKeyDown && keyboard.IsKeyDown(Key.Back);
+
+ base.Update();
+ }
+
+ private bool IsKeyDown(Key key)
+ {
+ return _states[(int)key];
+ }
+
+ private void OnPageKeyDown(object sender, KeyEventArgs e)
+ {
+ //DebugService.WriteLine(string.Concat("OnPageKeyDn: Key=", e.Key));
+
+ _states[(int)((e.Key == Key.System) ? e.SystemKey : e.Key)] = true;
+ _updateAnyKeyDown = false;
+ IsAnyKeyDown = true;
+
+ int asciiKey = GetAsciiKey(e.Key, e.KeyboardDevice);
+ if (asciiKey >= 0)
+ {
+ Machine.Keyboard.Latch = asciiKey;
+ e.Handled = true;
+ }
+
+ Update();
+ }
+
+ private void OnPageKeyUp(object sender, KeyEventArgs e)
+ {
+ //DebugService.WriteLine(string.Concat("OnPageKeyUp: Key=", e.Key));
+
+ _states[(int)((e.Key == Key.System) ? e.SystemKey : e.Key)] = false;
+ _updateAnyKeyDown = true;
+
+ bool control = ((e.KeyboardDevice.Modifiers & ModifierKeys.Control) != 0);
+
+ if (control && (e.Key == Key.Divide))
+ {
+ Machine.Cpu.IsThrottled ^= true;
+ }
+ else if (control && (e.Key == Key.Multiply))
+ {
+ Machine.Video.IsMonochrome ^= true;
+ }
+ else if (control && (e.Key == Key.Subtract))
+ {
+ Machine.Video.IsFullScreen ^= true;
+ }
+
+ Update();
+ }
+
+ [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
+ [SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode")]
+ private static int GetAsciiKey(Key key, KeyboardDevice keyboard)
+ {
+ bool control = ((keyboard.Modifiers & ModifierKeys.Control) != 0);
+ bool shift = ((keyboard.Modifiers & ModifierKeys.Shift) != 0);
+ bool capsLock = shift ^ keyboard.IsKeyToggled(Key.CapsLock);
+
+ switch (key)
+ {
+ case Key.Left:
+ return 0x08;
+
+ case Key.Tab:
+ return 0x09;
+
+ case Key.Down:
+ return 0x0A;
+
+ case Key.Up:
+ return 0x0B;
+
+ case Key.Enter:
+ return 0x0D;
+
+ case Key.Right:
+ return 0x15;
+
+ case Key.Escape:
+ return 0x1B;
+
+ case Key.Back:
+ return control ? -1 : 0x7F;
+
+ case Key.Space:
+ return ' ';
+
+ case Key.D1:
+ return shift ? '!' : '1';
+
+ case Key.D2:
+ return control ? 0x00 : shift ? '@' : '2';
+
+ case Key.D3:
+ return shift ? '#' : '3';
+
+ case Key.D4:
+ return shift ? '$' : '4';
+
+ case Key.D5:
+ return shift ? '%' : '5';
+
+ case Key.D6:
+ return control ? 0x1E : shift ? '^' : '6';
+
+ case Key.D7:
+ return shift ? '&' : '7';
+
+ case Key.D8:
+ return shift ? '*' : '8';
+
+ case Key.D9:
+ return shift ? '(' : '9';
+
+ case Key.D0:
+ return shift ? ')' : '0';
+
+ case Key.A:
+ return control ? 0x01 : capsLock ? 'A' : 'a';
+
+ case Key.B:
+ return control ? 0x02 : capsLock ? 'B' : 'b';
+
+ case Key.C:
+ return control ? 0x03 : capsLock ? 'C' : 'c';
+
+ case Key.D:
+ return control ? 0x04 : capsLock ? 'D' : 'd';
+
+ case Key.E:
+ return control ? 0x05 : capsLock ? 'E' : 'e';
+
+ case Key.F:
+ return control ? 0x06 : capsLock ? 'F' : 'f';
+
+ case Key.G:
+ return control ? 0x07 : capsLock ? 'G' : 'g';
+
+ case Key.H:
+ return control ? 0x08 : capsLock ? 'H' : 'h';
+
+ case Key.I:
+ return control ? 0x09 : capsLock ? 'I' : 'i';
+
+ case Key.J:
+ return control ? 0x0A : capsLock ? 'J' : 'j';
+
+ case Key.K:
+ return control ? 0x0B : capsLock ? 'K' : 'k';
+
+ case Key.L:
+ return control ? 0x0C : capsLock ? 'L' : 'l';
+
+ case Key.M:
+ return control ? 0x0D : capsLock ? 'M' : 'm';
+
+ case Key.N:
+ return control ? 0x0E : capsLock ? 'N' : 'n';
+
+ case Key.O:
+ return control ? 0x0F : capsLock ? 'O' : 'o';
+
+ case Key.P:
+ return control ? 0x10 : capsLock ? 'P' : 'p';
+
+ case Key.Q:
+ return control ? 0x11 : capsLock ? 'Q' : 'q';
+
+ case Key.R:
+ return control ? 0x12 : capsLock ? 'R' : 'r';
+
+ case Key.S:
+ return control ? 0x13 : capsLock ? 'S' : 's';
+
+ case Key.T:
+ return control ? 0x14 : capsLock ? 'T' : 't';
+
+ case Key.U:
+ return control ? 0x15 : capsLock ? 'U' : 'u';
+
+ case Key.V:
+ return control ? 0x16 : capsLock ? 'V' : 'v';
+
+ case Key.W:
+ return control ? 0x17 : capsLock ? 'W' : 'w';
+
+ case Key.X:
+ return control ? 0x18 : capsLock ? 'X' : 'x';
+
+ case Key.Y:
+ return control ? 0x19 : capsLock ? 'Y' : 'y';
+
+ case Key.Z:
+ return control ? 0x1A : capsLock ? 'Z' : 'z';
+
+ case Key.Oem1:
+ return shift ? ':' : ';';
+
+ case Key.Oem2:
+ return shift ? '?' : '/';
+
+ case Key.Oem3:
+ return shift ? '~' : '`';
+
+ case Key.Oem4:
+ return shift ? '{' : '[';
+
+ case Key.Oem5:
+ return control ? 0x1C : shift ? '|' : '\\';
+
+ case Key.Oem6:
+ return control ? 0x1D : shift ? '}' : ']';
+
+ case Key.Oem7:
+ return shift ? '"' : '\'';
+
+ case Key.OemMinus:
+ return control ? 0x1F : shift ? '_' : '-';
+
+ case Key.OemPlus:
+ return shift ? '+' : '=';
+
+ case Key.OemComma:
+ return shift ? '<' : ',';
+
+ case Key.OemPeriod:
+ return shift ? '>' : '.';
+ }
+
+ return -1;
+ }
+
+ private static readonly Key[] KeyValues =
+ (from key in (Key[])Enum.GetValues(typeof(Key))
+ where (key != Key.None) // filter Key.None; avoids validation exception
+ select key).ToArray();
+
+ private static readonly int KeyCount = (int)(KeyValues.Max()) + 1;
+
+ private bool[] _states = new bool[KeyCount];
+ private bool _updateAnyKeyDown;
+ }
+}
diff --git a/Virtu/Wpf/Services/WpfStorageService.cs b/Virtu/Wpf/Services/WpfStorageService.cs
index e4f3a25..83659d3 100644
--- a/Virtu/Wpf/Services/WpfStorageService.cs
+++ b/Virtu/Wpf/Services/WpfStorageService.cs
@@ -1,19 +1,19 @@
-using System.Deployment.Application;
-using System.IO.IsolatedStorage;
-
-namespace Jellyfish.Virtu.Services
-{
- public sealed class WpfStorageService : IsolatedStorageService
- {
- public WpfStorageService(Machine machine) :
- base(machine)
- {
- }
-
- protected override IsolatedStorageFile GetStore()
- {
- return ApplicationDeployment.IsNetworkDeployed ? // clickonce
- IsolatedStorageFile.GetUserStoreForApplication() : IsolatedStorageFile.GetUserStoreForAssembly();
- }
- }
-}
+using System.Deployment.Application;
+using System.IO.IsolatedStorage;
+
+namespace Jellyfish.Virtu.Services
+{
+ public sealed class WpfStorageService : IsolatedStorageService
+ {
+ public WpfStorageService(Machine machine) :
+ base(machine)
+ {
+ }
+
+ protected override IsolatedStorageFile GetStore()
+ {
+ return ApplicationDeployment.IsNetworkDeployed ? // clickonce
+ IsolatedStorageFile.GetUserStoreForApplication() : IsolatedStorageFile.GetUserStoreForAssembly();
+ }
+ }
+}
diff --git a/Virtu/Wpf/Services/WpfVideoService.cs b/Virtu/Wpf/Services/WpfVideoService.cs
index 0e4ad3d..26bea0b 100644
--- a/Virtu/Wpf/Services/WpfVideoService.cs
+++ b/Virtu/Wpf/Services/WpfVideoService.cs
@@ -1,107 +1,107 @@
-using System;
-using System.Diagnostics.CodeAnalysis;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Media;
-using System.Windows.Media.Imaging;
-using Jellyfish.Library;
-
-namespace Jellyfish.Virtu.Services
-{
- public sealed class WpfVideoService : VideoService
- {
- public WpfVideoService(Machine machine, UserControl page, Image image) :
- base(machine)
- {
- if (page == null)
- {
- throw new ArgumentNullException("page");
- }
- if (image == null)
- {
- throw new ArgumentNullException("image");
- }
-
- _page = page;
- _image = image;
- _image.Source = _bitmap;
-
- _page.Loaded += (sender, e) => SetWindowSizeToContent();
- _page.SizeChanged += (sender, e) => SetImageSize();
- }
-
- public override void SetFullScreen(bool isFullScreen)
- {
- if (_isFullScreen != isFullScreen)
- {
- _isFullScreen = isFullScreen;
- _page.Dispatcher.Send(() =>
- {
- var window = Window.GetWindow(_page);
- if (_isFullScreen)
- {
- window.ResizeMode = ResizeMode.NoResize;
- window.WindowStyle = WindowStyle.None;
- window.WindowState = WindowState.Maximized;
- }
- else
- {
- window.WindowState = WindowState.Normal;
- window.WindowStyle = WindowStyle.SingleBorderWindow;
- window.ResizeMode = ResizeMode.CanResize;
- }
- });
- }
- }
-
- [SuppressMessage("Microsoft.Usage", "CA2233:OperationsShouldNotOverflow")]
- public override void SetPixel(int x, int y, uint color)
- {
- _pixels[y * BitmapWidth + x] = color;
- _pixelsDirty = true;
- }
-
- public override void Update() // main thread
- {
- if (_pixelsDirty)
- {
- _pixelsDirty = false;
- _bitmap.WritePixels(BitmapRect, _pixels, BitmapStride, 0);
- }
- }
-
- private void SetImageSize()
- {
- int uniformScale = Math.Max(1, Math.Min((int)_page.RenderSize.Width / BitmapWidth, (int)_page.RenderSize.Height / BitmapHeight));
- _image.Width = uniformScale * BitmapWidth;
- _image.Height = uniformScale * BitmapHeight;
- }
-
- private void SetWindowSizeToContent()
- {
- if (!_sizedToContent)
- {
- _sizedToContent = true;
- var window = Application.Current.MainWindow;
- var size = window.DesiredSize;
- window.Width = size.Width;
- window.Height = size.Height;
- }
- }
-
- private const int BitmapWidth = 560;
- private const int BitmapHeight = 384;
- private const int BitmapDpi = 96;
- private static readonly PixelFormat BitmapPixelFormat = PixelFormats.Bgr32;
- private static readonly int BitmapStride = (BitmapWidth * BitmapPixelFormat.BitsPerPixel + 7) / 8;
- private static readonly Int32Rect BitmapRect = new Int32Rect(0, 0, BitmapWidth, BitmapHeight);
-
- private UserControl _page;
- private Image _image;
- private WriteableBitmap _bitmap = new WriteableBitmap(BitmapWidth, BitmapHeight, BitmapDpi, BitmapDpi, BitmapPixelFormat, null);
- private uint[] _pixels = new uint[BitmapWidth * BitmapHeight];
- private bool _pixelsDirty;
- private bool _isFullScreen;
- private bool _sizedToContent;
- }
-}
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using Jellyfish.Library;
+
+namespace Jellyfish.Virtu.Services
+{
+ public sealed class WpfVideoService : VideoService
+ {
+ public WpfVideoService(Machine machine, UserControl page, Image image) :
+ base(machine)
+ {
+ if (page == null)
+ {
+ throw new ArgumentNullException("page");
+ }
+ if (image == null)
+ {
+ throw new ArgumentNullException("image");
+ }
+
+ _page = page;
+ _image = image;
+ _image.Source = _bitmap;
+
+ _page.Loaded += (sender, e) => SetWindowSizeToContent();
+ _page.SizeChanged += (sender, e) => SetImageSize();
+ }
+
+ public override void SetFullScreen(bool isFullScreen)
+ {
+ if (_isFullScreen != isFullScreen)
+ {
+ _isFullScreen = isFullScreen;
+ _page.Dispatcher.Send(() =>
+ {
+ var window = Window.GetWindow(_page);
+ if (_isFullScreen)
+ {
+ window.ResizeMode = ResizeMode.NoResize;
+ window.WindowStyle = WindowStyle.None;
+ window.WindowState = WindowState.Maximized;
+ }
+ else
+ {
+ window.WindowState = WindowState.Normal;
+ window.WindowStyle = WindowStyle.SingleBorderWindow;
+ window.ResizeMode = ResizeMode.CanResize;
+ }
+ });
+ }
+ }
+
+ [SuppressMessage("Microsoft.Usage", "CA2233:OperationsShouldNotOverflow")]
+ public override void SetPixel(int x, int y, uint color)
+ {
+ _pixels[y * BitmapWidth + x] = color;
+ _pixelsDirty = true;
+ }
+
+ public override void Update() // main thread
+ {
+ if (_pixelsDirty)
+ {
+ _pixelsDirty = false;
+ _bitmap.WritePixels(BitmapRect, _pixels, BitmapStride, 0);
+ }
+ }
+
+ private void SetImageSize()
+ {
+ int uniformScale = Math.Max(1, Math.Min((int)_page.RenderSize.Width / BitmapWidth, (int)_page.RenderSize.Height / BitmapHeight));
+ _image.Width = uniformScale * BitmapWidth;
+ _image.Height = uniformScale * BitmapHeight;
+ }
+
+ private void SetWindowSizeToContent()
+ {
+ if (!_sizedToContent)
+ {
+ _sizedToContent = true;
+ var window = Application.Current.MainWindow;
+ var size = window.DesiredSize;
+ window.Width = size.Width;
+ window.Height = size.Height;
+ }
+ }
+
+ private const int BitmapWidth = 560;
+ private const int BitmapHeight = 384;
+ private const int BitmapDpi = 96;
+ private static readonly PixelFormat BitmapPixelFormat = PixelFormats.Bgr32;
+ private static readonly int BitmapStride = (BitmapWidth * BitmapPixelFormat.BitsPerPixel + 7) / 8;
+ private static readonly Int32Rect BitmapRect = new Int32Rect(0, 0, BitmapWidth, BitmapHeight);
+
+ private UserControl _page;
+ private Image _image;
+ private WriteableBitmap _bitmap = new WriteableBitmap(BitmapWidth, BitmapHeight, BitmapDpi, BitmapDpi, BitmapPixelFormat, null);
+ private uint[] _pixels = new uint[BitmapWidth * BitmapHeight];
+ private bool _pixelsDirty;
+ private bool _isFullScreen;
+ private bool _sizedToContent;
+ }
+}