diff --git a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
index a9d9eeafbc..9d0ef455f7 100644
--- a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
+++ b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
@@ -413,7 +413,7 @@
- Intellivision.cs
+ Intellivision.cs
Intellivision.cs
@@ -491,26 +491,10 @@
+
-
-
-
- Meteor.cs
-
-
- Meteor.cs
-
-
- Meteor.cs
-
-
- Meteor.cs
-
-
- Meteor.cs
-
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/LibMeteor.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/LibMeteor.cs
deleted file mode 100644
index 4f4dc96f68..0000000000
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/LibMeteor.cs
+++ /dev/null
@@ -1,294 +0,0 @@
-using System;
-using System.Runtime.InteropServices;
-
-namespace BizHawk.Emulation.Cores.Nintendo.GBA
-{
- ///
- /// bindings into libmeteor.dll
- ///
- public static class LibMeteor
- {
- ///
- /// power cycle the emulation core
- ///
- [DllImport("libmeteor.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern void libmeteor_hardreset();
-
- ///
- /// signal that you are removing data from the sound buffer.
- /// the next time frameadvance() is called, writing will start from the beginning
- ///
- /// the valid length of the buffer, in bytes
- [DllImport("libmeteor.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern uint libmeteor_emptysound();
-
- ///
- /// set up buffers for libmeteor to dump data to. these must be valid before every frameadvance
- ///
- /// buffer to hold video data as BGRA32
- /// length in bytes. must be at least 240 * 160 * 4
- /// buffer to hold audio data as stereo s16le
- /// length in bytes. must be 0 mod 4 (hold a full stereo sample set)
- /// false if some problem. buffers will not be valid in this case
- [DllImport("libmeteor.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern bool libmeteor_setbuffers(IntPtr vid, uint vidlen, IntPtr aud, uint audlen);
-
- ///
- /// initialize the library
- ///
- [DllImport("libmeteor.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern void libmeteor_init();
-
- ///
- /// run emulation for one frame, updating sound and video along the way
- ///
- [DllImport("libmeteor.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern void libmeteor_frameadvance();
-
- ///
- /// load a rom image
- ///
- /// raw rom data. need not persist past this call
- /// length of data in bytes
- [DllImport("libmeteor.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern void libmeteor_loadrom(byte[] data, uint datalen);
-
- ///
- /// load a bios image
- ///
- /// raw bios data. need not persist past this call
- /// length of data in bytes
- [DllImport("libmeteor.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern void libmeteor_loadbios(byte[] data, uint datalen);
-
- ///
- /// core callback to print meaningful (or meaningless) log messages
- ///
- /// message to be printed
- /// true if emulation should be aborted
- [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- public delegate void MessageCallback(string msg, bool abort);
-
- ///
- /// set callback for log messages. this can (and should) be called first
- ///
- ///
- [DllImport("libmeteor.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern void libmeteor_setmessagecallback(MessageCallback cb);
-
- ///
- /// combination of button flags used by the key callback
- ///
- [Flags]
- public enum Buttons : ushort
- {
- BTN_A = 0x001,
- BTN_B = 0x002,
- BTN_SELECT = 0x004,
- BTN_START = 0x008,
- BTN_RIGHT = 0x010,
- BTN_LEFT = 0x020,
- BTN_UP = 0x040,
- BTN_DOWN = 0x080,
- BTN_R = 0x100,
- BTN_L = 0x200
- }
-
- ///
- /// core callback to get input state
- ///
- /// buttons pressed bitfield
- [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- public delegate Buttons InputCallback();
-
- ///
- /// set callback for whenever input is requested
- ///
- ///
- [DllImport("libmeteor.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern void libmeteor_setkeycallback(InputCallback callback);
-
- ///
- /// parameter to libmeteor_getmemoryarea
- ///
- public enum MemoryArea
- {
- ///
- /// BIOS, may be invalid if bios not loaded. valid size: 16K. system bus: @00000000h
- ///
- bios = 0,
- ///
- /// external workram. valid size: 256K. system bus: @02000000h
- ///
- ewram = 1,
- ///
- /// internal workram. valid size: 32K. system bus: @03000000h
- ///
- iwram = 2,
- ///
- /// palettes. valid size: 1K. system bus: @05000000h
- ///
- palram = 3,
- ///
- /// video ram. valid size: 96K. system bus: @06000000h
- ///
- vram = 4,
- ///
- /// sprite attribute ram. valid size: 1K. system bus: @07000000h
- ///
- oam = 5,
- ///
- /// rom. always valid to full size, even if no rom or small rom loaded. valid size: 32M. system bus: @08000000h, others
- ///
- rom = 6,
- ///
- /// direct access to cached io port values. this should NEVER be modified! valid size: 4K. system bus: @04000000h (sort of)
- ///
- io = 7
- }
-
- ///
- /// return a pointer to a memory area
- ///
- ///
- /// IntPtr.Zero if which is unrecognized
- [DllImport("libmeteor.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern IntPtr libmeteor_getmemoryarea(MemoryArea which);
-
- ///
- /// core callback for tracelogging
- ///
- /// disassembly of an instruction about to be run
- [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- public delegate void TraceCallback(string msg);
-
- ///
- /// set callback to run before each instruction is executed
- ///
- /// null to clear
- [DllImport("libmeteor.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern void libmeteor_settracecallback(TraceCallback callback);
-
- ///
- /// load saveram from a byte buffer
- ///
- ///
- ///
- /// success
- [DllImport("libmeteor.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern bool libmeteor_loadsaveram(byte[] data, uint size);
-
- ///
- /// save saveram to a byte buffer
- ///
- /// buffer generated by core. copy from, but do not modify
- /// length of buffer
- /// success
- [DllImport("libmeteor.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern bool libmeteor_savesaveram(ref IntPtr data, ref uint size);
-
- ///
- /// destroy a buffer previously returned by libmeteor_savesaveram() to avoid leakage
- ///
- ///
- [DllImport("libmeteor.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern void libmeteor_savesaveram_destroy(IntPtr data);
-
- ///
- /// return true if there is saveram installed on currently loaded cart
- ///
- ///
- [DllImport("libmeteor.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern bool libmeteor_hassaveram();
-
- ///
- /// resets the current cart's saveram
- ///
- [DllImport("libmeteor.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern void libmeteor_clearsaveram();
-
- ///
- /// serialize state
- ///
- /// buffer generated by core
- /// size of buffer
- /// success
- [DllImport("libmeteor.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern bool libmeteor_savestate(ref IntPtr data, ref uint size);
-
- ///
- /// destroy a buffer previously returned by libmeteor_savestate() to avoid leakage
- ///
- ///
- [DllImport("libmeteor.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern void libmeteor_savestate_destroy(IntPtr data);
-
- ///
- /// unserialize state
- ///
- ///
- ///
- /// success
- [DllImport("libmeteor.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern bool libmeteor_loadstate(byte[] data, uint size);
-
- ///
- /// read a byte off the system bus. guaranteed to have no side effects
- ///
- ///
- ///
- [DllImport("libmeteor.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern byte libmeteor_peekbus(uint addr);
-
- ///
- /// write a byte to the system bus.
- ///
- ///
- ///
- [DllImport("libmeteor.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern void libmeteor_writebus(uint addr, byte val);
-
- ///
- /// type of the scanline callback
- ///
- [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- public delegate void ScanlineCallback();
-
- ///
- /// set a callback to coincide with vcount interrupts
- ///
- /// null to clear
- /// 0-227, 160 occurring first in a frame
- [DllImport("libmeteor.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern void libmeteor_setscanlinecallback(ScanlineCallback callback, int scanline);
-
- ///
- /// get current cpu regs
- ///
- /// length 18 please
- [DllImport("libmeteor.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern void libmeteor_getregs(int[] dest);
-
- public static readonly string[] regnames = new string[]
- {
- "r0",
- "r1",
- "r2",
- "r3",
- "r4",
- "r5",
- "r6",
- "r7",
- "r8",
- "r9",
- "r10",
- "r11",
- "r12",
- "r13",
- "r14",
- "r15",
- "cpsr",
- "spsr"
- };
- }
-}
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/Meteor.IGBAGPUViewable.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/Meteor.IGBAGPUViewable.cs
deleted file mode 100644
index 76142c1433..0000000000
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/Meteor.IGBAGPUViewable.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-using BizHawk.Emulation.Common;
-
-namespace BizHawk.Emulation.Cores.Nintendo.GBA
-{
- public partial class GBA : IGBAGPUViewable
- {
- public GBAGPUMemoryAreas GetMemoryAreas()
- {
- IntPtr _vram = LibMeteor.libmeteor_getmemoryarea(LibMeteor.MemoryArea.vram);
- IntPtr _palram = LibMeteor.libmeteor_getmemoryarea(LibMeteor.MemoryArea.palram);
- IntPtr _oam = LibMeteor.libmeteor_getmemoryarea(LibMeteor.MemoryArea.oam);
- IntPtr _mmio = LibMeteor.libmeteor_getmemoryarea(LibMeteor.MemoryArea.io);
-
- if (_vram == IntPtr.Zero || _palram == IntPtr.Zero || _oam == IntPtr.Zero || _mmio == IntPtr.Zero)
- throw new Exception("libmeteor_getmemoryarea() failed!");
-
- return new GBAGPUMemoryAreas
- {
- vram = _vram,
- palram = _palram,
- oam = _oam,
- mmio = _mmio
- };
- }
-
- public void SetScanlineCallback(Action callback, int scanline)
- {
- if (scanline < 0 || scanline > 227)
- {
- throw new ArgumentOutOfRangeException(nameof(scanline), "Scanline must be in [0, 227]!");
- }
-
- if (callback == null)
- {
- scanlinecb = null;
- LibMeteor.libmeteor_setscanlinecallback(null, 0);
- }
- else
- {
- scanlinecb = new LibMeteor.ScanlineCallback(callback);
- LibMeteor.libmeteor_setscanlinecallback(scanlinecb, scanline);
- }
- }
-
- private LibMeteor.ScanlineCallback scanlinecb = null;
- }
-}
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/Meteor.IMemoryDomains.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/Meteor.IMemoryDomains.cs
deleted file mode 100644
index 5835a4241d..0000000000
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/Meteor.IMemoryDomains.cs
+++ /dev/null
@@ -1,84 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-using BizHawk.Emulation.Common;
-
-namespace BizHawk.Emulation.Cores.Nintendo.GBA
-{
- public partial class GBA
- {
- private List _domainList = new List();
- private IMemoryDomains _memoryDomains;
-
- private void AddMemoryDomain(LibMeteor.MemoryArea which, int size, string name)
- {
- IntPtr data = LibMeteor.libmeteor_getmemoryarea(which);
- if (data == IntPtr.Zero)
- throw new Exception("libmeteor_getmemoryarea() returned NULL??");
-
- MemoryDomain md = MemoryDomain.FromIntPtr(name, size, MemoryDomain.Endian.Little, data);
- _domainList.Add(md);
- }
-
- private void SetUpMemoryDomains()
- {
- _domainList.Clear();
- // this must be first to coincide with "main memory"
- // note that ewram could also be considered main memory depending on which hairs you split
- AddMemoryDomain(LibMeteor.MemoryArea.iwram, 32 * 1024, "IWRAM");
- AddMemoryDomain(LibMeteor.MemoryArea.ewram, 256 * 1024, "EWRAM");
- AddMemoryDomain(LibMeteor.MemoryArea.bios, 16 * 1024, "BIOS");
- AddMemoryDomain(LibMeteor.MemoryArea.palram, 1024, "PALRAM");
- AddMemoryDomain(LibMeteor.MemoryArea.vram, 96 * 1024, "VRAM");
- AddMemoryDomain(LibMeteor.MemoryArea.oam, 1024, "OAM");
- // even if the rom is less than 32MB, the whole is still valid in meteor
- AddMemoryDomain(LibMeteor.MemoryArea.rom, 32 * 1024 * 1024, "ROM");
- // special domain for system bus
- {
- MemoryDomain sb = new MemoryDomainDelegate("System Bus", 1 << 28, MemoryDomain.Endian.Little,
- delegate(long addr)
- {
- if (addr < 0 || addr >= 0x10000000)
- throw new IndexOutOfRangeException();
- return LibMeteor.libmeteor_peekbus((uint)addr);
- },
- delegate(long addr, byte val)
- {
- if (addr < 0 || addr >= 0x10000000)
- throw new IndexOutOfRangeException();
- LibMeteor.libmeteor_writebus((uint)addr, val);
- }, 4);
- _domainList.Add(sb);
- }
- // special combined ram memory domain
- {
- var ew = _domainList[1];
- var iw = _domainList[0];
- MemoryDomain cr = new MemoryDomainDelegate("Combined WRAM", (256 + 32) * 1024, MemoryDomain.Endian.Little,
- delegate(long addr)
- {
- if (addr < 0 || addr >= (256 + 32) * 1024)
- throw new IndexOutOfRangeException();
- if (addr >= 256 * 1024)
- return iw.PeekByte(addr & 32767);
- else
- return ew.PeekByte(addr);
- },
- delegate(long addr, byte val)
- {
- if (addr < 0 || addr >= (256 + 32) * 1024)
- throw new IndexOutOfRangeException();
- if (addr >= 256 * 1024)
- iw.PokeByte(addr & 32767, val);
- else
- ew.PokeByte(addr, val);
- }, 4);
- _domainList.Add(cr);
- }
-
- _memoryDomains = new MemoryDomainList(_domainList);
- (ServiceProvider as BasicServiceProvider).Register(_memoryDomains);
- }
- }
-}
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/Meteor.ISaveRam.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/Meteor.ISaveRam.cs
deleted file mode 100644
index ec182a2855..0000000000
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/Meteor.ISaveRam.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-using System;
-using BizHawk.Emulation.Common;
-
-namespace BizHawk.Emulation.Cores.Nintendo.GBA
-{
- public partial class GBA : ISaveRam
- {
- public bool SaveRamModified
- {
- get
- {
- if (disposed)
- throw new ObjectDisposedException(this.GetType().ToString());
- return LibMeteor.libmeteor_hassaveram();
- }
- }
-
- public byte[] CloneSaveRam()
- {
- throw new Exception("This needs to be fixed to match the VBANext Core!");
-#if false
- if (disposed)
- throw new ObjectDisposedException(this.GetType().ToString());
- if (!LibMeteor.libmeteor_hassaveram())
- return null;
- IntPtr data = IntPtr.Zero;
- uint size = 0;
- if (!LibMeteor.libmeteor_savesaveram(ref data, ref size))
- throw new Exception("libmeteor_savesaveram() returned false!");
- byte[] ret = new byte[size];
- Marshal.Copy(data, ret, 0, (int)size);
- LibMeteor.libmeteor_savesaveram_destroy(data);
- return ret;
-#endif
- }
-
- public void StoreSaveRam(byte[] data)
- {
- throw new Exception("This needs to be fixed to match the VBANext Core!");
-#if false
- if (disposed)
- throw new ObjectDisposedException(this.GetType().ToString());
- if (!LibMeteor.libmeteor_loadsaveram(data, (uint)data.Length))
- throw new Exception("libmeteor_loadsaveram() returned false!");
-#endif
- }
- }
-}
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/Meteor.IStatable.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/Meteor.IStatable.cs
deleted file mode 100644
index 8ac877e5af..0000000000
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/Meteor.IStatable.cs
+++ /dev/null
@@ -1,83 +0,0 @@
-using System;
-using System.IO;
-using System.Runtime.InteropServices;
-
-using BizHawk.Common.BufferExtensions;
-using BizHawk.Emulation.Common;
-
-
-namespace BizHawk.Emulation.Cores.Nintendo.GBA
-{
- public partial class GBA : IStatable
- {
- public bool BinarySaveStatesPreferred { get { return true; } }
-
- public void SaveStateText(System.IO.TextWriter writer)
- {
- var temp = SaveStateBinary();
- temp.SaveAsHex(writer);
- // write extra copy of stuff we don't use
- writer.WriteLine("Frame {0}", Frame);
- }
-
- public void LoadStateText(System.IO.TextReader reader)
- {
- string hex = reader.ReadLine();
- byte[] state = new byte[hex.Length / 2];
- state.ReadFromHex(hex);
- LoadStateBinary(new BinaryReader(new MemoryStream(state)));
- }
-
- public void SaveStateBinary(System.IO.BinaryWriter writer)
- {
- byte[] data = SaveCoreBinary();
- writer.Write(data.Length);
- writer.Write(data);
- // other variables
- writer.Write(IsLagFrame);
- writer.Write(LagCount);
- writer.Write(Frame);
- }
-
- public void LoadStateBinary(System.IO.BinaryReader reader)
- {
- int length = reader.ReadInt32();
- byte[] data = reader.ReadBytes(length);
- LoadCoreBinary(data);
- // other variables
- IsLagFrame = reader.ReadBoolean();
- LagCount = reader.ReadInt32();
- Frame = reader.ReadInt32();
- }
-
- public byte[] SaveStateBinary()
- {
- MemoryStream ms = new MemoryStream();
- BinaryWriter bw = new BinaryWriter(ms);
- SaveStateBinary(bw);
- bw.Flush();
- return ms.ToArray();
- }
-
- private byte[] SaveCoreBinary()
- {
- IntPtr ndata = IntPtr.Zero;
- uint nsize = 0;
- if (!LibMeteor.libmeteor_savestate(ref ndata, ref nsize))
- throw new Exception("libmeteor_savestate() failed!");
- if (ndata == IntPtr.Zero || nsize == 0)
- throw new Exception("libmeteor_savestate() returned bad!");
-
- byte[] ret = new byte[nsize];
- Marshal.Copy(ndata, ret, 0, (int)nsize);
- LibMeteor.libmeteor_savestate_destroy(ndata);
- return ret;
- }
-
- private void LoadCoreBinary(byte[] data)
- {
- if (!LibMeteor.libmeteor_loadstate(data, (uint)data.Length))
- throw new Exception("libmeteor_loadstate() failed!");
- }
- }
-}
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/Meteor.IVideoProvider.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/Meteor.IVideoProvider.cs
deleted file mode 100644
index ba313a0280..0000000000
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/Meteor.IVideoProvider.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using System;
-using System.Runtime.InteropServices;
-
-using BizHawk.Emulation.Common;
-
-namespace BizHawk.Emulation.Cores.Nintendo.GBA
-{
- public partial class GBA : IVideoProvider
- {
- public int VirtualWidth { get { return 240; } }
- public int VirtualHeight { get { return 160; } }
- public int BufferWidth { get { return 240; } }
- public int BufferHeight { get { return 160; } }
- public int BackgroundColor
- {
- get { return unchecked((int)0xff000000); }
- }
-
- public int[] GetVideoBuffer()
- {
- return videobuffer;
- }
-
- private int[] videobuffer;
- private GCHandle videohandle;
- }
-}
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/Meteor.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/Meteor.cs
deleted file mode 100644
index d0eaa8ff52..0000000000
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/Meteor.cs
+++ /dev/null
@@ -1,336 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Runtime.InteropServices;
-using System.IO;
-
-using BizHawk.Common.BufferExtensions;
-using BizHawk.Emulation.Common;
-
-namespace BizHawk.Emulation.Cores.Nintendo.GBA
-{
- [CoreAttributes(
- "Meteor",
- "blastrock",
- isPorted: true,
- isReleased: false,
- singleInstance: true
- )]
- [ServiceNotApplicable(typeof(IDriveLight), typeof(IRegionable))]
- public partial class GBA : IEmulator, IVideoProvider, ISoundProvider, IGBAGPUViewable, ISaveRam, IStatable, IInputPollable
- {
- [CoreConstructor("GBA")]
- public GBA(CoreComm comm, byte[] file)
- {
- ServiceProvider = new BasicServiceProvider(this);
- Tracer = new TraceBuffer
- {
- Header = " -Addr--- -Opcode- -Instruction------------------- -R0----- -R1----- -R2----- -R3----- -R4----- -R5----- -R6----- -R7----- -R8----- -R9----- -R10---- -R11---- -R12---- -R13(SP) -R14(LR) -R15(PC) -CPSR--- -SPSR---"
- };
-
- (ServiceProvider as BasicServiceProvider).Register(Tracer);
-
- CoreComm = comm;
-
- comm.VsyncNum = 262144;
- comm.VsyncDen = 4389;
- comm.NominalWidth = 240;
- comm.NominalHeight = 160;
-
- byte[] bios = CoreComm.CoreFileProvider.GetFirmware("GBA", "Bios", true, "GBA bios file is mandatory.");
-
- if (bios.Length != 16384)
- throw new InvalidDataException("GBA bios must be exactly 16384 bytes!");
- if (file.Length > 32 * 1024 * 1024)
- throw new InvalidDataException("Rom file is too big! No GBA game is larger than 32MB");
- Init();
- LibMeteor.libmeteor_hardreset();
- LibMeteor.libmeteor_loadbios(bios, (uint)bios.Length);
- LibMeteor.libmeteor_loadrom(file, (uint)file.Length);
-
- SetUpMemoryDomains();
- }
-
- public IEmulatorServiceProvider ServiceProvider { get; private set; }
-
- public IDictionary GetCpuFlagsAndRegisters()
- {
- var ret = new Dictionary();
- int[] data = new int[LibMeteor.regnames.Length];
- LibMeteor.libmeteor_getregs(data);
- for (int i = 0; i < data.Length; i++)
- ret.Add(LibMeteor.regnames[i], data[i]);
- return ret;
- }
-
- public static readonly ControllerDefinition GBAController =
- new ControllerDefinition
- {
- Name = "GBA Controller",
- BoolButtons =
- {
- "Up", "Down", "Left", "Right", "Start", "Select", "B", "A", "L", "R", "Power"
- },
- FloatControls =
- {
- "Tilt X", "Tilt Y", "Tilt Z", "Light Sensor"
- },
- FloatRanges =
- {
- new[] { -32767f, 0f, 32767f },
- new[] { -32767f, 0f, 32767f },
- new[] { -32767f, 0f, 32767f },
- new[] { 0f, 100f, 200f },
- }
- };
- public ControllerDefinition ControllerDefinition { get { return GBAController; } }
- public IController Controller { get; set; }
-
- public void FrameAdvance(bool render, bool rendersound = true)
- {
- Frame++;
- IsLagFrame = true;
-
- if (Controller.IsPressed("Power"))
- LibMeteor.libmeteor_hardreset();
- // due to the design of the tracing api, we have to poll whether it's active each frame
- LibMeteor.libmeteor_settracecallback(Tracer.Enabled ? tracecallback : null);
- if (!coredead)
- LibMeteor.libmeteor_frameadvance();
- if (IsLagFrame)
- LagCount++;
- }
-
- public int Frame { get; private set; }
- public int LagCount { get; set; }
- public bool IsLagFrame { get; set; }
-
- private readonly InputCallbackSystem _inputCallbacks = new InputCallbackSystem();
-
- // TODO: optimize managed to unmanaged using the ActiveChanged event
- public IInputCallbackSystem InputCallbacks { [FeatureNotImplemented]get { return _inputCallbacks; } }
-
- private ITraceable Tracer { get; set; }
-
- public string SystemId { get { return "GBA"; } }
- public bool DeterministicEmulation { get { return true; } }
-
- // todo: information about the saveram type would be useful here.
- public string BoardName { get { return null; } }
-
- public void ResetCounters()
- {
- Frame = 0;
- LagCount = 0;
- IsLagFrame = false;
- }
-
- public CoreComm CoreComm { get; private set; }
-
- /// like libsnes, the library is single-instance
- static GBA attachedcore;
- /// hold pointer to message callback so it won't get GCed
- LibMeteor.MessageCallback messagecallback;
- /// hold pointer to input callback so it won't get GCed
- LibMeteor.InputCallback inputcallback;
- /// true if libmeteor aborted
- bool coredead = false;
- /// hold pointer to trace callback so it won't get GCed
- LibMeteor.TraceCallback tracecallback;
-
- LibMeteor.Buttons GetInput()
- {
- InputCallbacks.Call();
- // libmeteor bitflips everything itself, so 0 == off, 1 == on
- IsLagFrame = false;
- LibMeteor.Buttons ret = 0;
- if (Controller.IsPressed("Up")) ret |= LibMeteor.Buttons.BTN_UP;
- if (Controller.IsPressed("Down")) ret |= LibMeteor.Buttons.BTN_DOWN;
- if (Controller.IsPressed("Left")) ret |= LibMeteor.Buttons.BTN_LEFT;
- if (Controller.IsPressed("Right")) ret |= LibMeteor.Buttons.BTN_RIGHT;
- if (Controller.IsPressed("Select")) ret |= LibMeteor.Buttons.BTN_SELECT;
- if (Controller.IsPressed("Start")) ret |= LibMeteor.Buttons.BTN_START;
- if (Controller.IsPressed("B")) ret |= LibMeteor.Buttons.BTN_B;
- if (Controller.IsPressed("A")) ret |= LibMeteor.Buttons.BTN_A;
- if (Controller.IsPressed("L")) ret |= LibMeteor.Buttons.BTN_L;
- if (Controller.IsPressed("R")) ret |= LibMeteor.Buttons.BTN_R;
- return ret;
- }
-
- #region messagecallbacks
-
- void PrintMessage(string msg, bool abort)
- {
- Console.Write(msg.Replace("\n", "\r\n"));
- if (abort)
- StopCore(msg);
- }
-
- void StopCore(string msg)
- {
- coredead = true;
- Console.WriteLine("Core stopped.");
- for (int i = 0; i < soundbuffer.Length; i++)
- soundbuffer[i] = 0;
-
- var gz = new System.IO.Compression.GZipStream(
- new MemoryStream(Convert.FromBase64String(dispfont), false),
- System.IO.Compression.CompressionMode.Decompress);
- byte[] font = new byte[2048];
- gz.Read(font, 0, 2048);
- gz.Dispose();
-
- // cores aren't supposed to have bad dependencies like System.Drawing, right?
-
- int scx = 0;
- int scy = 0;
-
- foreach (char c in msg)
- {
- if (scx == 240 || c == '\n')
- {
- scy += 8;
- scx = 0;
- }
- if (scy == 160)
- break;
- if (c == '\r' || c == '\n')
- continue;
- if (c < 256 && c != ' ')
- {
- int fpos = c * 8;
- for (int j = 0; j < 8; j++)
- {
- for (int i = 0; i < 8; i++)
- {
- if ((font[fpos] >> i & 1) != 0)
- videobuffer[(scy + j) * 240 + scx + i] = unchecked((int)0xffff0000);
- else
- videobuffer[(scy + j) * 240 + scx + i] = unchecked((int)0xff000000);
- }
- fpos++;
- }
- }
- scx += 8;
- }
- }
-
- const string dispfont =
- "H4sICAInrFACAGZvby5yYXcARVU9q9RAFL2gjK8IT+0GDGoh1oGFGHDYQvwL2hoQroXhsdUqGGbxZ/gD" +
- "bKys7BRhIZVYLgurIghvG3ksCPKKJfGcm1nfSTJn750792smWUmIr9++/vjmdYzDZlhuh1guFotpfiRH" +
- "+dQ4n+aLxfOj/MgUR7mID8GLDMN2CftBgj54oEGG5ZuPH98sh93P3afJZHIzqGrw0e+/7LPs+OqVvuu7" +
- "7vTZJb8J223Y+MtZHvLsstwuqlAVt+E1eh+DV0JU+s3mx3q9luCChjoIsVgI7Wg2kAHBQ1mkqPu6EBhk" +
- "feYFcM5F0B0d9A74WtX2QvRtdU0SrBp6kaZpKIJ7XI341oV66sVp4TOtJS/L/IN+k8pnQkCbZb4QPEVB" +
- "nYYhKB16JHZwbsZRDuBEDWsnEnQeTzSIz60CyHWV6cg19LOXjfb1TqKb1pSrzE0VHBUOvIed8ia3dZGb" +
- "c96JM0ZhfgzPBPCbkWEPEs/4j+fO1kd2HM55Q0bf4PdmCW15E/HdFI1M7Dg/Z1xN64InguxqpGn6kkvF" +
- "GaJ0Z32/6jrRkxjntFciMB79mTwPM5NLm0ffWac3iCb7kbx0XbfqzzqhEGBPLe2i9TVKmxGtiGPFIm1N" +
- "tNj+ppMLDDl7Ywh1q62gPEUKlJX1Yw3k1uTo2P9sCseQW3Y80B4QLznrNwaOnbMGUDK9SNOvVgxt9vQH" +
- "gj51IPn7SdlRFDt4MoarIGvKwyoFd6tV34CtAWTLRySiAZF5Oq5DcHvyAvuO8/FtLgZrRNcf9tlp8l/4" +
- "sc64HPuhMnLmR/Z3jA/9cbAzexVj2CU59SPYD+rJyU6VfsiIh5NtL+j+/b7cyzmOu+op1wXrjzHXG2Ow" +
- "Qikba6pbgwL0P7J4y89XDRsY7ZxEXLcmkydP/zz9NVv74P2N4yLVVaT8wIxDNv9NaRtG1pM5kinLVqKY" +
- "ERndzXhOgOicGNe1yPLp5NUXnezAm99//3ymoX0xodQvsMKoE5GH18fr3aPx+v5ivPwFbt1KIx9VffYM" +
- "g30GyUkPbV1zJgGzJpt+sWAxGEWSHwH4izg/hwAeBjEMw0GPweTDfNLyUWzSqdroXN+L9L1z1Gy3tsKe" +
- "7Zbzpj/oOE+9P8iq5j/Nj/HUQK+S4omkuMJIaqD3g5+xQ2KwvIcEKshXE3YJNkfgjbg7/8YNLbV0Lqo6" +
- "AFEaQqJmPlM7n+l9VeDHJTm57wGJPtjRwhg53+LD1DRnMvNFO9q3q9WqFfncnq6+tm7mszbzM4QziERe" +
- "h7+LyO+zz8AYfQGerdf+P27cOBYaeUubt1RNU138q4wg74qiuFeGKjQA5BwOgxABACX8A6+GHm0ACAAA";
-
- #endregion
-
- // Tracer refactor TODO - rehook up meteor, if it is worth it
- //void Trace(string msg)
- //{
- // Tracer.Put(msg);
- //}
-
- private void Init()
- {
- if (attachedcore != null)
- attachedcore.Dispose();
-
- messagecallback = PrintMessage;
- inputcallback = GetInput;
-
- // Tracer refactor TODO - rehook up meteor, if it is worth it
- //tracecallback = Trace; // don't set this callback now, only set if enabled
- LibMeteor.libmeteor_setmessagecallback(messagecallback);
- LibMeteor.libmeteor_setkeycallback(inputcallback);
-
- LibMeteor.libmeteor_init();
- videobuffer = new int[240 * 160];
- videohandle = GCHandle.Alloc(videobuffer, GCHandleType.Pinned);
- soundbuffer = new short[2048]; // nominal length of one frame is something like 1480 shorts?
- soundhandle = GCHandle.Alloc(soundbuffer, GCHandleType.Pinned);
-
- if (!LibMeteor.libmeteor_setbuffers
- (videohandle.AddrOfPinnedObject(), (uint)(sizeof(int) * videobuffer.Length),
- soundhandle.AddrOfPinnedObject(), (uint)(sizeof(short) * soundbuffer.Length)))
- throw new Exception("libmeteor_setbuffers() returned false??");
-
- attachedcore = this;
- }
-
- private bool disposed = false;
- public void Dispose()
- {
- if (!disposed)
- {
- disposed = true;
- videohandle.Free();
- soundhandle.Free();
- // guarantee crash if it gets accessed
- LibMeteor.libmeteor_setbuffers(IntPtr.Zero, 240 * 160 * 4, IntPtr.Zero, 4);
- messagecallback = null;
- inputcallback = null;
- tracecallback = null;
- LibMeteor.libmeteor_setmessagecallback(messagecallback);
- LibMeteor.libmeteor_setkeycallback(inputcallback);
- LibMeteor.libmeteor_settracecallback(tracecallback);
- _domainList.Clear();
- }
- }
-
- #region ISoundProvider
-
- short[] soundbuffer;
- GCHandle soundhandle;
-
- public void GetSamplesSync(out short[] samples, out int nsamp)
- {
- uint nbytes = LibMeteor.libmeteor_emptysound();
- samples = soundbuffer;
- if (!coredead)
- nsamp = (int)(nbytes / 4);
- else
- nsamp = 738;
- }
-
- public void DiscardSamples()
- {
- LibMeteor.libmeteor_emptysound();
- }
-
- public bool CanProvideAsync
- {
- get { return false; }
- }
-
- public void SetSyncMode(SyncSoundMode mode)
- {
- if (mode == SyncSoundMode.Async)
- {
- throw new NotSupportedException("Async mode is not supported.");
- }
- }
-
- public SyncSoundMode SyncMode
- {
- get { return SyncSoundMode.Sync; }
- }
-
- public void GetSamplesAsync(short[] samples)
- {
- throw new InvalidOperationException("Async mode is not supported.");
- }
-
- #endregion
- }
-}
diff --git a/attic/GarboDev/Arm7Processor.cs b/attic/GarboDev/Arm7Processor.cs
deleted file mode 100644
index 6b9c83c499..0000000000
--- a/attic/GarboDev/Arm7Processor.cs
+++ /dev/null
@@ -1,501 +0,0 @@
-namespace GarboDev
-{
- using System;
- using System.Collections.Generic;
- using System.Text;
-
- public class Arm7Processor
- {
- private Memory memory = null;
- private FastArmCore armCore = null;
- private ThumbCore thumbCore = null;
- private Dictionary breakpoints = null;
-
- private int cycles = 0;
- private int timerCycles = 0;
- private int soundCycles = 0;
-
- // CPU mode definitions
- public const uint USR = 0x10;
- public const uint FIQ = 0x11;
- public const uint IRQ = 0x12;
- public const uint SVC = 0x13;
- public const uint ABT = 0x17;
- public const uint UND = 0x1B;
- public const uint SYS = 0x1F;
-
- // CPSR bit definitions
- public const int N_BIT = 31;
- public const int Z_BIT = 30;
- public const int C_BIT = 29;
- public const int V_BIT = 28;
- public const int I_BIT = 7;
- public const int F_BIT = 6;
- public const int T_BIT = 5;
-
- public const uint N_MASK = (uint)(1U << N_BIT);
- public const uint Z_MASK = (uint)(1U << Z_BIT);
- public const uint C_MASK = (uint)(1U << C_BIT);
- public const uint V_MASK = (uint)(1U << V_BIT);
- public const uint I_MASK = (uint)(1U << I_BIT);
- public const uint F_MASK = (uint)(1U << F_BIT);
- public const uint T_MASK = (uint)(1U << T_BIT);
-
- // Standard registers
- private uint[] registers = new uint[16];
- private uint cpsr = 0;
-
- // Banked registers
- private uint[] bankedFIQ = new uint[7];
- private uint[] bankedIRQ = new uint[2];
- private uint[] bankedSVC = new uint[2];
- private uint[] bankedABT = new uint[2];
- private uint[] bankedUND = new uint[2];
-
- // Saved CPSR's
- private uint spsrFIQ = 0;
- private uint spsrIRQ = 0;
- private uint spsrSVC = 0;
- private uint spsrABT = 0;
- private uint spsrUND = 0;
-
- private ushort keyState;
-
- private bool breakpointHit = false;
- private bool cpuHalted = false;
-
- public ushort KeyState
- {
- set { this.keyState = value; }
- }
-
- public int Cycles
- {
- get { return this.cycles; }
- set { this.cycles = value; }
- }
-
- public bool ArmState
- {
- get { return (this.cpsr & Arm7Processor.T_MASK) != Arm7Processor.T_MASK; }
- }
-
- public uint[] Registers
- {
- get { return this.registers; }
- }
-
- public uint CPSR
- {
- get { return this.cpsr; }
- set { this.cpsr = value; }
- }
-
- public bool SPSRExists
- {
- get
- {
- switch (this.cpsr & 0x1F)
- {
- case USR:
- case SYS:
- return false;
- case FIQ:
- case SVC:
- case ABT:
- case IRQ:
- case UND:
- return true;
- default:
- return false;
- }
- }
- }
-
- public uint SPSR
- {
- get
- {
- switch (this.cpsr & 0x1F)
- {
- case USR:
- case SYS:
- return 0xFFFFFFFF;
- case FIQ:
- return this.spsrFIQ;
- case SVC:
- return this.spsrSVC;
- case ABT:
- return this.spsrABT;
- case IRQ:
- return this.spsrIRQ;
- case UND:
- return this.spsrUND;
- default:
- throw new Exception("Unhandled CPSR state...");
- }
- }
- set
- {
- switch (this.cpsr & 0x1F)
- {
- case USR:
- case SYS:
- break;
- case FIQ:
- this.spsrFIQ = value;
- break;
- case SVC:
- this.spsrSVC = value;
- break;
- case ABT:
- this.spsrABT = value;
- break;
- case IRQ:
- this.spsrIRQ = value;
- break;
- case UND:
- this.spsrUND = value;
- break;
- default:
- throw new Exception("Unhandled CPSR state...");
- }
- }
- }
-
- public Dictionary Breakpoints
- {
- get
- {
- return this.breakpoints;
- }
- }
-
- public bool BreakpointHit
- {
- get { return this.breakpointHit; }
- set { this.breakpointHit = value; }
- }
-
- public Arm7Processor(Memory memory)
- {
- this.memory = memory;
- this.memory.Processor = this;
- this.armCore = new FastArmCore(this, this.memory);
- this.thumbCore = new ThumbCore(this, this.memory);
- this.breakpoints = new Dictionary();
- this.breakpointHit = false;
- }
-
- private void SwapRegsHelper(uint[] swapRegs)
- {
- for (int i = 14; i > 14 - swapRegs.Length; i--)
- {
- uint tmp = this.registers[i];
- this.registers[i] = swapRegs[swapRegs.Length - (14 - i) - 1];
- swapRegs[swapRegs.Length - (14 - i) - 1] = tmp;
- }
- }
-
- private void SwapRegisters(uint bank)
- {
- switch (bank & 0x1F)
- {
- case FIQ:
- this.SwapRegsHelper(this.bankedFIQ);
- break;
- case SVC:
- this.SwapRegsHelper(this.bankedSVC);
- break;
- case ABT:
- this.SwapRegsHelper(this.bankedABT);
- break;
- case IRQ:
- this.SwapRegsHelper(this.bankedIRQ);
- break;
- case UND:
- this.SwapRegsHelper(this.bankedUND);
- break;
- }
- }
-
- public void WriteCpsr(uint newCpsr)
- {
- if ((newCpsr & 0x1F) != (this.cpsr & 0x1F))
- {
- // Swap out the old registers
- this.SwapRegisters(this.cpsr);
- // Swap in the new registers
- this.SwapRegisters(newCpsr);
- }
-
- this.cpsr = newCpsr;
- }
-
- public void EnterException(uint mode, uint vector, bool interruptsDisabled, bool fiqDisabled)
- {
- uint oldCpsr = this.cpsr;
-
- if ((oldCpsr & Arm7Processor.T_MASK) != 0)
- {
- registers[15] += 2U;
- }
-
- // Clear T bit, and set mode
- uint newCpsr = (oldCpsr & ~0x3FU) | mode;
- if (interruptsDisabled) newCpsr |= 1 << 7;
- if (fiqDisabled) newCpsr |= 1 << 6;
- this.WriteCpsr(newCpsr);
-
- this.SPSR = oldCpsr;
- registers[14] = registers[15];
- registers[15] = vector;
-
- this.ReloadQueue();
- }
-
- public void RequestIrq(int irq)
- {
- ushort iflag = Memory.ReadU16(this.memory.IORam, Memory.IF);
- iflag |= (ushort)(1 << irq);
- Memory.WriteU16(this.memory.IORam, Memory.IF, iflag);
- }
-
- public void FireIrq()
- {
- ushort ime = Memory.ReadU16(this.memory.IORam, Memory.IME);
- ushort ie = Memory.ReadU16(this.memory.IORam, Memory.IE);
- ushort iflag = Memory.ReadU16(this.memory.IORam, Memory.IF);
-
- if ((ie & (iflag)) != 0 && (ime & 1) != 0 && (this.cpsr & (1 << 7)) == 0)
- {
- // Off to the irq exception vector
- this.EnterException(Arm7Processor.IRQ, 0x18, true, false);
- }
- }
-
- public void Reset(bool skipBios)
- {
- this.breakpointHit = false;
- this.cpuHalted = false;
-
- // Default to ARM state
- this.cycles = 0;
- this.timerCycles = 0;
- this.soundCycles = 0;
-
- this.bankedSVC[0] = 0x03007FE0;
- this.bankedIRQ[0] = 0x03007FA0;
-
- this.cpsr = SYS;
- this.spsrSVC = this.cpsr;
- for (int i = 0; i < 15; i++) this.registers[i] = 0;
-
- if (skipBios)
- {
- this.registers[15] = 0x8000000;
- }
- else
- {
- this.registers[15] = 0;
- }
-
- this.armCore.BeginExecution();
- }
-
- public void Halt()
- {
- this.cpuHalted = true;
- this.cycles = 0;
- }
-
- public void Step()
- {
- this.breakpointHit = false;
-
- if ((this.cpsr & Arm7Processor.T_MASK) == Arm7Processor.T_MASK)
- {
- this.thumbCore.Step();
- }
- else
- {
- this.armCore.Step();
- }
-
- this.UpdateTimers();
- }
-
- public void ReloadQueue()
- {
- if ((this.cpsr & Arm7Processor.T_MASK) == Arm7Processor.T_MASK)
- {
- this.thumbCore.BeginExecution();
- }
- else
- {
- this.armCore.BeginExecution();
- }
- }
-
- private void UpdateTimer(int timer, int cycles, bool countUp)
- {
- ushort control = Memory.ReadU16(this.memory.IORam, Memory.TM0CNT + (uint)(timer * 4));
-
- // Make sure timer is enabled, or count up is disabled
- if ((control & (1 << 7)) == 0) return;
- if (!countUp && (control & (1 << 2)) != 0) return;
-
- if (!countUp)
- {
- switch (control & 3)
- {
- case 0: cycles *= 1 << 10; break;
- case 1: cycles *= 1 << 4; break;
- case 2: cycles *= 1 << 2; break;
- // Don't need to do anything for case 3
- }
- }
-
- this.memory.TimerCnt[timer] += (uint)cycles;
- uint timerCnt = this.memory.TimerCnt[timer] >> 10;
-
- if (timerCnt > 0xffff)
- {
- ushort soundCntX = Memory.ReadU16(this.memory.IORam, Memory.SOUNDCNT_X);
- if ((soundCntX & (1 << 7)) != 0)
- {
- ushort soundCntH = Memory.ReadU16(this.memory.IORam, Memory.SOUNDCNT_H);
- if (timer == ((soundCntH >> 10) & 1))
- {
- // FIFO A overflow
- this.memory.SoundManager.DequeueA();
- if (this.memory.SoundManager.QueueSizeA < 16)
- {
- this.memory.FifoDma(1);
- // TODO
- if (this.memory.SoundManager.QueueSizeA < 16)
- {
- }
- }
- }
- if (timer == ((soundCntH >> 14) & 1))
- {
- // FIFO B overflow
- this.memory.SoundManager.DequeueB();
- if (this.memory.SoundManager.QueueSizeB < 16)
- {
- this.memory.FifoDma(2);
- }
- }
- }
-
- // Overflow, attempt to fire IRQ
- if ((control & (1 << 6)) != 0)
- {
- this.RequestIrq(3 + timer);
- }
-
- if (timer < 3)
- {
- ushort control2 = Memory.ReadU16(this.memory.IORam, Memory.TM0CNT + (uint)((timer + 1) * 4));
- if ((control2 & (1 << 2)) != 0)
- {
- // Count-up
- this.UpdateTimer(timer + 1, (int)((timerCnt >> 16) << 10), true);
- }
- }
-
- // Reset the original value
- uint count = Memory.ReadU16(this.memory.IORam, Memory.TM0D + (uint)(timer * 4));
- this.memory.TimerCnt[timer] = count << 10;
- }
- }
-
- public void UpdateTimers()
- {
- int cycles = this.timerCycles - this.cycles;
-
- for (int i = 0; i < 4; i++)
- {
- this.UpdateTimer(i, cycles, false);
- }
-
- this.timerCycles = this.cycles;
- }
-
- public void UpdateKeyState()
- {
- ushort KEYCNT = this.memory.ReadU16Debug(Memory.REG_BASE + Memory.KEYCNT);
-
- if ((KEYCNT & (1 << 14)) != 0)
- {
- if ((KEYCNT & (1 << 15)) != 0)
- {
- KEYCNT &= 0x3FF;
- if (((~this.keyState) & KEYCNT) == KEYCNT)
- this.RequestIrq(12);
- }
- else
- {
- KEYCNT &= 0x3FF;
- if (((~this.keyState) & KEYCNT) != 0)
- this.RequestIrq(12);
- }
- }
-
- this.memory.KeyState = this.keyState;
- }
-
- public void UpdateSound()
- {
- this.memory.SoundManager.Mix(this.soundCycles);
- this.soundCycles = 0;
- }
-
- public void Execute(int cycles)
- {
- this.cycles += cycles;
- this.timerCycles += cycles;
- this.soundCycles += cycles;
- this.breakpointHit = false;
-
- if (this.cpuHalted)
- {
- ushort ie = Memory.ReadU16(this.memory.IORam, Memory.IE);
- ushort iflag = Memory.ReadU16(this.memory.IORam, Memory.IF);
-
- if ((ie & iflag) != 0)
- {
- this.cpuHalted = false;
- }
- else
- {
- this.cycles = 0;
- this.UpdateTimers();
- this.UpdateSound();
- return;
- }
- }
-
- while (this.cycles > 0)
- {
- if ((this.cpsr & Arm7Processor.T_MASK) == Arm7Processor.T_MASK)
- {
- this.thumbCore.Execute();
- }
- else
- {
- this.armCore.Execute();
- }
-
- this.UpdateTimers();
- this.UpdateSound();
-
- if (this.breakpointHit)
- {
- break;
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/attic/GarboDev/ArmCore.cs b/attic/GarboDev/ArmCore.cs
deleted file mode 100644
index 5eda1e7a5d..0000000000
--- a/attic/GarboDev/ArmCore.cs
+++ /dev/null
@@ -1,1273 +0,0 @@
-//#define ARM_DEBUG
-
-namespace GarboDev
-{
- using System;
-
- public class ArmCore
- {
- private const uint COND_EQ = 0; // Z set
- private const uint COND_NE = 1; // Z clear
- private const uint COND_CS = 2; // C set
- private const uint COND_CC = 3; // C clear
- private const uint COND_MI = 4; // N set
- private const uint COND_PL = 5; // N clear
- private const uint COND_VS = 6; // V set
- private const uint COND_VC = 7; // V clear
- private const uint COND_HI = 8; // C set and Z clear
- private const uint COND_LS = 9; // C clear or Z set
- private const uint COND_GE = 10; // N equals V
- private const uint COND_LT = 11; // N not equal to V
- private const uint COND_GT = 12; // Z clear AND (N equals V)
- private const uint COND_LE = 13; // Z set OR (N not equal to V)
- private const uint COND_AL = 14; // Always
- private const uint COND_NV = 15; // Never execute
-
- private const uint OP_AND = 0x0;
- private const uint OP_EOR = 0x1;
- private const uint OP_SUB = 0x2;
- private const uint OP_RSB = 0x3;
- private const uint OP_ADD = 0x4;
- private const uint OP_ADC = 0x5;
- private const uint OP_SBC = 0x6;
- private const uint OP_RSC = 0x7;
- private const uint OP_TST = 0x8;
- private const uint OP_TEQ = 0x9;
- private const uint OP_CMP = 0xA;
- private const uint OP_CMN = 0xB;
- private const uint OP_ORR = 0xC;
- private const uint OP_MOV = 0xD;
- private const uint OP_BIC = 0xE;
- private const uint OP_MVN = 0xF;
-
- private delegate void ExecuteInstruction();
- private ExecuteInstruction[] NormalOps = null;
-
- private Arm7Processor parent;
- private Memory memory;
- private uint[] registers;
-
- private uint instructionQueue;
- private uint curInstruction;
-
- // CPU flags
- private uint zero, carry, negative, overflow;
- private uint shifterCarry;
-
- private bool thumbMode;
-
- public ArmCore(Arm7Processor parent, Memory memory)
- {
- this.parent = parent;
- this.memory = memory;
- this.registers = this.parent.Registers;
-
- this.NormalOps = new ExecuteInstruction[8]
- {
- this.DataProcessing,
- this.DataProcessingImmed,
- this.LoadStoreImmediate,
- this.LoadStoreRegister,
- this.LoadStoreMultiple,
- this.Branch,
- this.CoprocessorLoadStore,
- this.SoftwareInterrupt
- };
- }
-
- public void BeginExecution()
- {
- this.FlushQueue();
- }
-
- public void Step()
- {
- this.UnpackFlags();
-
- this.curInstruction = this.instructionQueue;
- this.instructionQueue = this.memory.ReadU32(registers[15]);
- registers[15] += 4;
-
- uint cond = 0;
- switch (this.curInstruction >> 28)
- {
- case COND_AL: cond = 1; break;
- case COND_EQ: cond = zero; break;
- case COND_NE: cond = 1 - zero; break;
- case COND_CS: cond = carry; break;
- case COND_CC: cond = 1 - carry; break;
- case COND_MI: cond = negative; break;
- case COND_PL: cond = 1 - negative; break;
- case COND_VS: cond = overflow; break;
- case COND_VC: cond = 1 - overflow; break;
- case COND_HI: cond = carry & (1 - zero); break;
- case COND_LS: cond = (1 - carry) | zero; break;
- case COND_GE: cond = (1 - negative) ^ overflow; break;
- case COND_LT: cond = negative ^ overflow; break;
- case COND_GT: cond = (1 - zero) & (negative ^ (1 - overflow)); break;
- case COND_LE: cond = (negative ^ overflow) | zero; break;
- }
-
- if (cond == 1)
- {
- // Execute the instruction
- this.NormalOps[(curInstruction >> 25) & 0x7]();
- }
-
- this.parent.Cycles -= this.memory.WaitCycles;
-
- if ((this.parent.CPSR & Arm7Processor.T_MASK) == Arm7Processor.T_MASK)
- {
- this.parent.ReloadQueue();
- }
-
- this.PackFlags();
- }
-
- public void Execute()
- {
- this.UnpackFlags();
- this.thumbMode = false;
-
- while (this.parent.Cycles > 0)
- {
- this.curInstruction = this.instructionQueue;
- this.instructionQueue = this.memory.ReadU32Aligned(registers[15]);
- registers[15] += 4;
-
- if ((this.curInstruction >> 28) == COND_AL)
- {
- this.NormalOps[(curInstruction >> 25) & 0x7]();
- }
- else
- {
- uint cond = 0;
- switch (this.curInstruction >> 28)
- {
- case COND_EQ: cond = zero; break;
- case COND_NE: cond = 1 - zero; break;
- case COND_CS: cond = carry; break;
- case COND_CC: cond = 1 - carry; break;
- case COND_MI: cond = negative; break;
- case COND_PL: cond = 1 - negative; break;
- case COND_VS: cond = overflow; break;
- case COND_VC: cond = 1 - overflow; break;
- case COND_HI: cond = carry & (1 - zero); break;
- case COND_LS: cond = (1 - carry) | zero; break;
- case COND_GE: cond = (1 - negative) ^ overflow; break;
- case COND_LT: cond = negative ^ overflow; break;
- case COND_GT: cond = (1 - zero) & (negative ^ (1 - overflow)); break;
- case COND_LE: cond = (negative ^ overflow) | zero; break;
- }
-
- if (cond == 1)
- {
- // Execute the instruction
- this.NormalOps[(curInstruction >> 25) & 0x7]();
- }
- }
-
- this.parent.Cycles -= this.memory.WaitCycles;
-
- if (this.thumbMode)
- {
- this.parent.ReloadQueue();
- break;
- }
-
-#if ARM_DEBUG
- // Check the current PC
- if (this.parent.Breakpoints.ContainsKey(registers[15] - 4U))
- {
- this.parent.BreakpointHit = true;
- break;
- }
-#endif
- }
-
- this.PackFlags();
- }
-
- #region Barrel Shifter
- private const uint SHIFT_LSL = 0;
- private const uint SHIFT_LSR = 1;
- private const uint SHIFT_ASR = 2;
- private const uint SHIFT_ROR = 3;
-
- private uint BarrelShifter(uint shifterOperand)
- {
- uint type = (shifterOperand >> 5) & 0x3;
-
- bool registerShift = (shifterOperand & (1 << 4)) == (1 << 4);
-
- uint rm = registers[shifterOperand & 0xF];
-
- int amount;
- if (registerShift)
- {
- uint rs = (shifterOperand >> 8) & 0xF;
- if (rs == 15)
- {
- amount = (int)((registers[rs] + 0x4) & 0xFF);
- }
- else
- {
- amount = (int)(registers[rs] & 0xFF);
- }
-
- if ((shifterOperand & 0xF) == 15)
- {
- rm += 4;
- }
- }
- else
- {
- amount = (int)((shifterOperand >> 7) & 0x1F);
- }
-
- if (registerShift)
- {
- if (amount == 0)
- {
- this.shifterCarry = this.carry;
- return rm;
- }
-
- switch (type)
- {
- case SHIFT_LSL:
- if (amount < 32)
- {
- this.shifterCarry = (rm >> (32 - amount)) & 1;
- return rm << amount;
- }
- else if (amount == 32)
- {
- this.shifterCarry = rm & 1;
- return 0;
- }
- else
- {
- this.shifterCarry = 0;
- return 0;
- }
-
- case SHIFT_LSR:
- if (amount < 32)
- {
- this.shifterCarry = (rm >> (amount - 1)) & 1;
- return rm >> amount;
- }
- else if (amount == 32)
- {
- this.shifterCarry = (rm >> 31) & 1;
- return 0;
- }
- else
- {
- this.shifterCarry = 0;
- return 0;
- }
-
- case SHIFT_ASR:
- if (amount >= 32)
- {
- if ((rm & (1 << 31)) == 0)
- {
- this.shifterCarry = 0;
- return 0;
- }
- else
- {
- this.shifterCarry = 1;
- return 0xFFFFFFFF;
- }
- }
- else
- {
- this.shifterCarry = (rm >> (amount - 1)) & 1;
- return (uint)(((int)rm) >> amount);
- }
-
- case SHIFT_ROR:
- if ((amount & 0x1F) == 0)
- {
- this.shifterCarry = (rm >> 31) & 1;
- return rm;
- }
- else
- {
- amount &= 0x1F;
- this.shifterCarry = (rm >> amount) & 1;
- return (rm >> amount) | (rm << (32 - amount));
- }
- }
- }
- else
- {
- switch (type)
- {
- case SHIFT_LSL:
- if (amount == 0)
- {
- this.shifterCarry = this.carry;
- return rm;
- }
- else
- {
- this.shifterCarry = (rm >> (32 - amount)) & 1;
- return rm << amount;
- }
-
- case SHIFT_LSR:
- if (amount == 0)
- {
- this.shifterCarry = (rm >> 31) & 1;
- return 0;
- }
- else
- {
- this.shifterCarry = (rm >> (amount - 1)) & 1;
- return rm >> amount;
- }
-
- case SHIFT_ASR:
- if (amount == 0)
- {
- if ((rm & (1 << 31)) == 0)
- {
- this.shifterCarry = 0;
- return 0;
- }
- else
- {
- this.shifterCarry = 1;
- return 0xFFFFFFFF;
- }
- }
- else
- {
- this.shifterCarry = (rm >> (amount - 1)) & 1;
- return (uint)(((int)rm) >> amount);
- }
-
- case SHIFT_ROR:
- if (amount == 0)
- {
- // Actually an RRX
- this.shifterCarry = rm & 1;
- return (this.carry << 31) | (rm >> 1);
- }
- else
- {
- this.shifterCarry = (rm >> (amount - 1)) & 1;
- return (rm >> amount) | (rm << (32 - amount));
- }
- }
- }
-
- // Should never happen...
- throw new Exception("Barrel Shifter has messed up.");
- }
- #endregion
-
- #region Flag helpers
- public void OverflowCarryAdd(uint a, uint b, uint r)
- {
- overflow = ((a & b & ~r) | (~a & ~b & r)) >> 31;
- carry = ((a & b) | (a & ~r) | (b & ~r)) >> 31;
- }
-
- public void OverflowCarrySub(uint a, uint b, uint r)
- {
- overflow = ((a & ~b & ~r) | (~a & b & r)) >> 31;
- carry = ((a & ~b) | (a & ~r) | (~b & ~r)) >> 31;
- }
- #endregion
-
- #region Opcodes
- private void DoDataProcessing(uint shifterOperand)
- {
- uint rn = (this.curInstruction >> 16) & 0xF;
- uint rd = (this.curInstruction >> 12) & 0xF;
- uint alu;
-
- bool registerShift = (this.curInstruction & (1 << 4)) == (1 << 4);
- if (rn == 15 && ((this.curInstruction >> 25) & 0x7) == 0 && registerShift)
- {
- rn = registers[rn] + 4;
- }
- else
- {
- rn = registers[rn];
- }
-
- uint opcode = (this.curInstruction >> 21) & 0xF;
-
- if (((this.curInstruction >> 20) & 1) == 1)
- {
- // Set flag bit set
- switch (opcode)
- {
- case OP_ADC:
- registers[rd] = rn + shifterOperand + carry;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
- break;
-
- case OP_ADD:
- registers[rd] = rn + shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
- break;
-
- case OP_AND:
- registers[rd] = rn & shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- break;
-
- case OP_BIC:
- registers[rd] = rn & ~shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- break;
-
- case OP_CMN:
- alu = rn + shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, alu);
- break;
-
- case OP_CMP:
- alu = rn - shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, alu);
- break;
-
- case OP_EOR:
- registers[rd] = rn ^ shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- break;
-
- case OP_MOV:
- registers[rd] = shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- break;
-
- case OP_MVN:
- registers[rd] = ~shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- break;
-
- case OP_ORR:
- registers[rd] = rn | shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- break;
-
- case OP_RSB:
- registers[rd] = shifterOperand - rn;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
- break;
-
- case OP_RSC:
- registers[rd] = shifterOperand - rn - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
- break;
-
- case OP_SBC:
- registers[rd] = rn - shifterOperand - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
- break;
-
- case OP_SUB:
- registers[rd] = rn - shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
- break;
-
- case OP_TEQ:
- alu = rn ^ shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- break;
-
- case OP_TST:
- alu = rn & shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- break;
- }
-
- if (rd == 15)
- {
- // Prevent writing if no SPSR exists (this will be true for USER or SYSTEM mode)
- if (this.parent.SPSRExists) this.parent.WriteCpsr(this.parent.SPSR);
- this.UnpackFlags();
-
- // Check for branch back to Thumb Mode
- if ((this.parent.CPSR & Arm7Processor.T_MASK) == Arm7Processor.T_MASK)
- {
- this.thumbMode = true;
- return;
- }
-
- // Otherwise, flush the instruction queue
- this.FlushQueue();
- }
- }
- else
- {
- // Set flag bit not set
- switch (opcode)
- {
- case OP_ADC: registers[rd] = rn + shifterOperand + carry; break;
- case OP_ADD: registers[rd] = rn + shifterOperand; break;
- case OP_AND: registers[rd] = rn & shifterOperand; break;
- case OP_BIC: registers[rd] = rn & ~shifterOperand; break;
- case OP_EOR: registers[rd] = rn ^ shifterOperand; break;
- case OP_MOV: registers[rd] = shifterOperand; break;
- case OP_MVN: registers[rd] = ~shifterOperand; break;
- case OP_ORR: registers[rd] = rn | shifterOperand; break;
- case OP_RSB: registers[rd] = shifterOperand - rn; break;
- case OP_RSC: registers[rd] = shifterOperand - rn - (1U - carry); break;
- case OP_SBC: registers[rd] = rn - shifterOperand - (1U - carry); break;
- case OP_SUB: registers[rd] = rn - shifterOperand; break;
-
- case OP_CMN:
- // MSR SPSR, shifterOperand
- if ((this.curInstruction & (1 << 16)) == 1 << 16 && this.parent.SPSRExists)
- {
- this.parent.SPSR &= 0xFFFFFF00;
- this.parent.SPSR |= shifterOperand & 0x000000FF;
- }
- if ((this.curInstruction & (1 << 17)) == 1 << 17 && this.parent.SPSRExists)
- {
- this.parent.SPSR &= 0xFFFF00FF;
- this.parent.SPSR |= shifterOperand & 0x0000FF00;
- }
- if ((this.curInstruction & (1 << 18)) == 1 << 18 && this.parent.SPSRExists)
- {
- this.parent.SPSR &= 0xFF00FFFF;
- this.parent.SPSR |= shifterOperand & 0x00FF0000;
- }
- if ((this.curInstruction & (1 << 19)) == 1 << 19 && this.parent.SPSRExists)
- {
- this.parent.SPSR &= 0x00FFFFFF;
- this.parent.SPSR |= shifterOperand & 0xFF000000;
- }
-
- // Queue will be flushed since rd == 15, so adjust the PC
- registers[15] -= 4;
- break;
-
- case OP_CMP:
- // MRS rd, SPSR
- if (this.parent.SPSRExists) registers[rd] = this.parent.SPSR;
- break;
-
- case OP_TEQ:
- if (((this.curInstruction >> 4) & 0xf) == 1)
- {
- // BX
- uint rm = this.curInstruction & 0xf;
-
- this.PackFlags();
-
- this.parent.CPSR &= ~Arm7Processor.T_MASK;
- this.parent.CPSR |= (registers[rm] & 1) << Arm7Processor.T_BIT;
-
- registers[15] = registers[rm] & (~1U);
-
- this.UnpackFlags();
-
- // Check for branch back to Thumb Mode
- if ((this.parent.CPSR & Arm7Processor.T_MASK) == Arm7Processor.T_MASK)
- {
- this.thumbMode = true;
- return;
- }
-
- // Queue will be flushed later because rd == 15
- }
- else if (((this.curInstruction >> 4) & 0xf) == 0)
- {
- // MSR CPSR, shifterOperand
- bool userMode = (this.parent.CPSR & 0x1F) == Arm7Processor.USR;
-
- this.PackFlags();
-
- uint tmpCPSR = this.parent.CPSR;
-
- if ((this.curInstruction & (1 << 16)) == 1 << 16 && !userMode)
- {
- tmpCPSR &= 0xFFFFFF00;
- tmpCPSR |= shifterOperand & 0x000000FF;
- }
- if ((this.curInstruction & (1 << 17)) == 1 << 17 && !userMode)
- {
- tmpCPSR &= 0xFFFF00FF;
- tmpCPSR |= shifterOperand & 0x0000FF00;
- }
- if ((this.curInstruction & (1 << 18)) == 1 << 18 && !userMode)
- {
- tmpCPSR &= 0xFF00FFFF;
- tmpCPSR |= shifterOperand & 0x00FF0000;
- }
- if ((this.curInstruction & (1 << 19)) == 1 << 19)
- {
- tmpCPSR &= 0x00FFFFFF;
- tmpCPSR |= shifterOperand & 0xFF000000;
- }
-
- this.parent.WriteCpsr(tmpCPSR);
-
- this.UnpackFlags();
-
- // Check for branch back to Thumb Mode
- if ((this.parent.CPSR & Arm7Processor.T_MASK) == Arm7Processor.T_MASK)
- {
- this.thumbMode = true;
- return;
- }
-
- // Queue will be flushed since rd == 15, so adjust the PC
- registers[15] -= 4;
- }
- break;
-
- case OP_TST:
- // MRS rd, CPSR
- this.PackFlags();
- registers[rd] = this.parent.CPSR;
- break;
- }
-
- if (rd == 15)
- {
- // Flush the queue
- this.FlushQueue();
- }
- }
- }
-
- private void DataProcessing()
- {
- // Special instruction
- switch ((this.curInstruction >> 4) & 0xF)
- {
- case 0x9:
- // Multiply or swap instructions
- this.MultiplyOrSwap();
- return;
- case 0xB:
- // Load/Store Unsigned halfword
- this.LoadStoreHalfword();
- return;
- case 0xD:
- // Load/Store Signed byte
- this.LoadStoreHalfword();
- return;
- case 0xF:
- // Load/Store Signed halfword
- this.LoadStoreHalfword();
- return;
- }
-
- this.DoDataProcessing(this.BarrelShifter(this.curInstruction));
- }
-
- private void DataProcessingImmed()
- {
- uint immed = this.curInstruction & 0xFF;
- int rotateAmount = (int)(((this.curInstruction >> 8) & 0xF) * 2);
-
- immed = (immed >> rotateAmount) | (immed << (32 - rotateAmount));
-
- if (rotateAmount == 0)
- {
- this.shifterCarry = this.carry;
- }
- else
- {
- this.shifterCarry = (immed >> 31) & 1;
- }
-
- this.DoDataProcessing(immed);
- }
-
- private void LoadStore(uint offset)
- {
- uint rn = (this.curInstruction >> 16) & 0xF;
- uint rd = (this.curInstruction >> 12) & 0xF;
-
- uint address = registers[rn];
-
- bool preIndexed = (this.curInstruction & (1 << 24)) == 1 << 24;
- bool byteTransfer = (this.curInstruction & (1 << 22)) == 1 << 22;
- bool writeback = (this.curInstruction & (1 << 21)) == 1 << 21;
-
- // Add or subtract offset
- if ((this.curInstruction & (1 << 23)) != 1 << 23) offset = (uint)-offset;
-
- if (preIndexed)
- {
- address += offset;
-
- if (writeback)
- {
- registers[rn] = address;
- }
- }
-
- if ((this.curInstruction & (1 << 20)) == 1 << 20)
- {
- // Load
- if (byteTransfer)
- {
- registers[rd] = this.memory.ReadU8(address);
- }
- else
- {
- registers[rd] = this.memory.ReadU32(address);
- }
-
- // ARM9 fix here
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (!preIndexed)
- {
- if (rn != rd)
- registers[rn] = address + offset;
- }
- }
- else
- {
- // Store
- uint amount = registers[rd];
- if (rd == 15) amount += 4;
-
- if (byteTransfer)
- {
- this.memory.WriteU8(address, (byte)(amount & 0xFF));
- }
- else
- {
- this.memory.WriteU32(address, amount);
- }
-
- if (!preIndexed)
- {
- registers[rn] = address + offset;
- }
- }
- }
-
- private void LoadStoreImmediate()
- {
- this.LoadStore(this.curInstruction & 0xFFF);
- }
-
- private void LoadStoreRegister()
- {
- // The barrel shifter expects a 0 in bit 4 for immediate shifts, this is implicit in
- // the meaning of the instruction, so it is fine
- this.LoadStore(this.BarrelShifter(this.curInstruction));
- }
-
- private void LoadStoreMultiple()
- {
- uint rn = (this.curInstruction >> 16) & 0xF;
-
- this.PackFlags();
- uint curCpsr = this.parent.CPSR;
-
- bool preIncrement = (this.curInstruction & (1 << 24)) != 0;
- bool up = (this.curInstruction & (1 << 23)) != 0;
- bool writeback = (this.curInstruction & (1 << 21)) != 0;
-
- uint address;
- uint bitsSet = 0;
- for (int i = 0; i < 16; i++) if (((this.curInstruction >> i) & 1) != 0) bitsSet++;
-
- if (preIncrement)
- {
- if (up)
- {
- // Increment before
- address = this.registers[rn] + 4;
- if (writeback) this.registers[rn] += bitsSet * 4;
- }
- else
- {
- // Decrement before
- address = this.registers[rn] - (bitsSet * 4);
- if (writeback) this.registers[rn] -= bitsSet * 4;
- }
- }
- else
- {
- if (up)
- {
- // Increment after
- address = this.registers[rn];
- if (writeback) this.registers[rn] += bitsSet * 4;
- }
- else
- {
- // Decrement after
- address = this.registers[rn] - (bitsSet * 4) + 4;
- if (writeback) this.registers[rn] -= bitsSet * 4;
- }
- }
-
- if ((this.curInstruction & (1 << 20)) != 0)
- {
- if ((this.curInstruction & (1 << 22)) != 0 && ((this.curInstruction >> 15) & 1) == 0)
- {
- // Switch to user mode temporarily
- this.parent.WriteCpsr((curCpsr & ~0x1FU) | Arm7Processor.USR);
- }
-
- // Load multiple
- for (int i = 0; i < 15; i++)
- {
- if (((this.curInstruction >> i) & 1) != 1) continue;
- this.registers[i] = this.memory.ReadU32Aligned(address & (~0x3U));
- address += 4;
- }
-
- if (((this.curInstruction >> 15) & 1) == 1)
- {
- // Arm9 fix here
-
- this.registers[15] = this.memory.ReadU32Aligned(address & (~0x3U));
-
- if ((this.curInstruction & (1 << 22)) != 0)
- {
- // Load the CPSR from the SPSR
- if (this.parent.SPSRExists)
- {
- this.parent.WriteCpsr(this.parent.SPSR);
- this.UnpackFlags();
-
- // Check for branch back to Thumb Mode
- if ((this.parent.CPSR & Arm7Processor.T_MASK) == Arm7Processor.T_MASK)
- {
- this.thumbMode = true;
- this.registers[15] &= ~0x1U;
- return;
- }
- }
- }
-
- this.registers[15] &= ~0x3U;
- this.FlushQueue();
- }
- else
- {
- if ((this.curInstruction & (1 << 22)) != 0)
- {
- // Switch back to the correct mode
- this.parent.WriteCpsr(curCpsr);
- this.UnpackFlags();
-
- if ((this.parent.CPSR & Arm7Processor.T_MASK) == Arm7Processor.T_MASK)
- {
- this.thumbMode = true;
- return;
- }
- }
- }
- }
- else
- {
- if ((this.curInstruction & (1 << 22)) != 0)
- {
- // Switch to user mode temporarily
- this.parent.WriteCpsr((curCpsr & ~0x1FU) | Arm7Processor.USR);
- }
-
- if (((this.curInstruction >> (int)rn) & 1) != 0 && writeback &&
- (this.curInstruction & ~(0xFFFFFFFF << (int)rn)) == 0)
- {
- // If the lowest register is also the writeback, we use the original value
- // Does anybody do this????
- throw new Exception("Unhandled STM state");
- }
- else
- {
- // Store multiple
- for (int i = 0; i < 15; i++)
- {
- if (((this.curInstruction >> i) & 1) == 0) continue;
- this.memory.WriteU32(address, this.registers[i]);
- address += 4;
- }
-
- if (((this.curInstruction >> 15) & 1) != 0)
- {
- this.memory.WriteU32(address, this.registers[15] + 4U);
- }
- }
-
- if ((this.curInstruction & (1 << 22)) != 0)
- {
- // Switch back to the correct mode
- this.parent.WriteCpsr(curCpsr);
- this.UnpackFlags();
- }
- }
- }
-
- private void Branch()
- {
- if ((this.curInstruction & (1 << 24)) != 0)
- {
- this.registers[14] = (this.registers[15] - 4U) & ~3U;
- }
-
- uint branchOffset = this.curInstruction & 0x00FFFFFF;
- if (branchOffset >> 23 == 1) branchOffset |= 0xFF000000;
-
- this.registers[15] += branchOffset << 2;
-
- this.FlushQueue();
- }
-
- private void CoprocessorLoadStore()
- {
- throw new Exception("Unhandled opcode - coproc load/store");
- }
-
- private void SoftwareInterrupt()
- {
- // Adjust PC for prefetch
- this.registers[15] -= 4U;
- this.parent.EnterException(Arm7Processor.SVC, 0x8, false, false);
- }
-
- private void MultiplyOrSwap()
- {
- if ((this.curInstruction & (1 << 24)) == 1 << 24)
- {
- // Swap instruction
- uint rn = (this.curInstruction >> 16) & 0xF;
- uint rd = (this.curInstruction >> 12) & 0xF;
- uint rm = this.curInstruction & 0xF;
-
- if ((this.curInstruction & (1 << 22)) != 0)
- {
- // SWPB
- byte tmp = this.memory.ReadU8(registers[rn]);
- this.memory.WriteU8(registers[rn], (byte)(registers[rm] & 0xFF));
- registers[rd] = tmp;
- }
- else
- {
- // SWP
- uint tmp = this.memory.ReadU32(registers[rn]);
- this.memory.WriteU32(registers[rn], registers[rm]);
- registers[rd] = tmp;
- }
- }
- else
- {
- // Multiply instruction
- switch ((this.curInstruction >> 21) & 0x7)
- {
- case 0:
- case 1:
- {
- // Multiply/Multiply + Accumulate
- uint rd = (this.curInstruction >> 16) & 0xF;
- uint rn = registers[(this.curInstruction >> 12) & 0xF];
- uint rs = (this.curInstruction >> 8) & 0xF;
- uint rm = this.curInstruction & 0xF;
-
- int cycles = 4;
- // Multiply cycle calculations
- if ((registers[rs] & 0xFFFFFF00) == 0 || (registers[rs] & 0xFFFFFF00) == 0xFFFFFF00)
- {
- cycles = 1;
- }
- else if ((registers[rs] & 0xFFFF0000) == 0 || (registers[rs] & 0xFFFF0000) == 0xFFFF0000)
- {
- cycles = 2;
- }
- else if ((registers[rs] & 0xFF000000) == 0 || (registers[rs] & 0xFF000000) == 0xFF000000)
- {
- cycles = 3;
- }
-
- registers[rd] = registers[rs] * registers[rm];
- this.parent.Cycles -= cycles;
-
- if ((this.curInstruction & (1 << 21)) == 1 << 21)
- {
- registers[rd] += rn;
- this.parent.Cycles -= 1;
- }
-
- if ((this.curInstruction & (1 << 20)) == 1 << 20)
- {
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- }
- break;
- }
-
- case 2:
- case 3:
- throw new Exception("Invalid multiply");
-
- case 4:
- case 5:
- case 6:
- case 7:
- {
- // Multiply/Signed Multiply Long
- uint rdhi = (this.curInstruction >> 16) & 0xF;
- uint rdlo = (this.curInstruction >> 12) & 0xF;
- uint rs = (this.curInstruction >> 8) & 0xF;
- uint rm = this.curInstruction & 0xF;
-
- int cycles = 5;
- // Multiply cycle calculations
- if ((registers[rs] & 0xFFFFFF00) == 0 || (registers[rs] & 0xFFFFFF00) == 0xFFFFFF00)
- {
- cycles = 2;
- }
- else if ((registers[rs] & 0xFFFF0000) == 0 || (registers[rs] & 0xFFFF0000) == 0xFFFF0000)
- {
- cycles = 3;
- }
- else if ((registers[rs] & 0xFF000000) == 0 || (registers[rs] & 0xFF000000) == 0xFF000000)
- {
- cycles = 4;
- }
-
- this.parent.Cycles -= cycles;
-
- switch ((this.curInstruction >> 21) & 0x3)
- {
- case 0:
- {
- // UMULL
- ulong result = ((ulong)registers[rm]) * registers[rs];
- registers[rdhi] = (uint)(result >> 32);
- registers[rdlo] = (uint)(result & 0xFFFFFFFF);
- break;
- }
- case 1:
- {
- // UMLAL
- ulong accum = (((ulong)registers[rdhi]) << 32) | registers[rdlo];
- ulong result = ((ulong)registers[rm]) * registers[rs];
- result += accum;
- registers[rdhi] = (uint)(result >> 32);
- registers[rdlo] = (uint)(result & 0xFFFFFFFF);
- break;
- }
- case 2:
- {
- // SMULL
- long result = ((long)((int)registers[rm])) * ((long)((int)registers[rs]));
- registers[rdhi] = (uint)(result >> 32);
- registers[rdlo] = (uint)(result & 0xFFFFFFFF);
- break;
- }
- case 3:
- {
- // SMLAL
- long accum = (((long)((int)registers[rdhi])) << 32) | registers[rdlo];
- long result = ((long)((int)registers[rm])) * ((long)((int)registers[rs]));
- result += accum;
- registers[rdhi] = (uint)(result >> 32);
- registers[rdlo] = (uint)(result & 0xFFFFFFFF);
- break;
- }
- }
-
- if ((this.curInstruction & (1 << 20)) == 1 << 20)
- {
- negative = registers[rdhi] >> 31;
- zero = (registers[rdhi] == 0 && registers[rdlo] == 0) ? 1U : 0U;
- }
- break;
- }
- }
- }
- }
-
- private void LoadStoreHalfword()
- {
- uint rn = (this.curInstruction >> 16) & 0xF;
- uint rd = (this.curInstruction >> 12) & 0xF;
-
- uint address = registers[rn];
-
- bool preIndexed = (this.curInstruction & (1 << 24)) != 0;
- bool byteTransfer = (this.curInstruction & (1 << 5)) == 0;
- bool signedTransfer = (this.curInstruction & (1 << 6)) != 0;
- bool writeback = (this.curInstruction & (1 << 21)) != 0;
-
- uint offset;
- if ((this.curInstruction & (1 << 22)) != 0)
- {
- // Immediate offset
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
- }
- else
- {
- // Register offset
- offset = this.registers[this.curInstruction & 0xF];
- }
-
- // Add or subtract offset
- if ((this.curInstruction & (1 << 23)) == 0) offset = (uint)-offset;
-
- if (preIndexed)
- {
- address += offset;
-
- if (writeback)
- {
- registers[rn] = address;
- }
- }
-
- if ((this.curInstruction & (1 << 20)) != 0)
- {
- // Load
- if (byteTransfer)
- {
- if (signedTransfer)
- {
- registers[rd] = this.memory.ReadU8(address);
- if ((registers[rd] & 0x80) != 0)
- {
- registers[rd] |= 0xFFFFFF00;
- }
- }
- else
- {
- registers[rd] = this.memory.ReadU8(address);
- }
- }
- else
- {
- if (signedTransfer)
- {
- registers[rd] = this.memory.ReadU16(address);
- if ((registers[rd] & 0x8000) != 0)
- {
- registers[rd] |= 0xFFFF0000;
- }
- }
- else
- {
- registers[rd] = this.memory.ReadU16(address);
- }
- }
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (!preIndexed)
- {
- if (rn != rd)
- registers[rn] = address + offset;
- }
- }
- else
- {
- // Store
- if (byteTransfer)
- {
- this.memory.WriteU8(address, (byte)(registers[rd] & 0xFF));
- }
- else
- {
- this.memory.WriteU16(address, (ushort)(registers[rd] & 0xFFFF));
- }
-
- if (!preIndexed)
- {
- registers[rn] = address + offset;
- }
- }
- }
- #endregion Opcodes
-
- private void PackFlags()
- {
- this.parent.CPSR &= 0x0FFFFFFF;
- this.parent.CPSR |= this.negative << Arm7Processor.N_BIT;
- this.parent.CPSR |= this.zero << Arm7Processor.Z_BIT;
- this.parent.CPSR |= this.carry << Arm7Processor.C_BIT;
- this.parent.CPSR |= this.overflow << Arm7Processor.V_BIT;
- }
-
- private void UnpackFlags()
- {
- this.negative = (this.parent.CPSR >> Arm7Processor.N_BIT) & 1;
- this.zero = (this.parent.CPSR >> Arm7Processor.Z_BIT) & 1;
- this.carry = (this.parent.CPSR >> Arm7Processor.C_BIT) & 1;
- this.overflow = (this.parent.CPSR >> Arm7Processor.V_BIT) & 1;
- }
-
- private void FlushQueue()
- {
- this.instructionQueue = this.memory.ReadU32(registers[15]);
- registers[15] += 4;
- }
- }
-}
\ No newline at end of file
diff --git a/attic/GarboDev/FastArmCore.cs b/attic/GarboDev/FastArmCore.cs
deleted file mode 100644
index c944036fb1..0000000000
--- a/attic/GarboDev/FastArmCore.cs
+++ /dev/null
@@ -1,9916 +0,0 @@
-//#define ARM_DEBUG
-
-namespace GarboDev
-{
- using System;
-
- public partial class FastArmCore
- {
- private const uint COND_EQ = 0; // Z set
- private const uint COND_NE = 1; // Z clear
- private const uint COND_CS = 2; // C set
- private const uint COND_CC = 3; // C clear
- private const uint COND_MI = 4; // N set
- private const uint COND_PL = 5; // N clear
- private const uint COND_VS = 6; // V set
- private const uint COND_VC = 7; // V clear
- private const uint COND_HI = 8; // C set and Z clear
- private const uint COND_LS = 9; // C clear or Z set
- private const uint COND_GE = 10; // N equals V
- private const uint COND_LT = 11; // N not equal to V
- private const uint COND_GT = 12; // Z clear AND (N equals V)
- private const uint COND_LE = 13; // Z set OR (N not equal to V)
- private const uint COND_AL = 14; // Always
- private const uint COND_NV = 15; // Never execute
-
- private const uint OP_AND = 0x0;
- private const uint OP_EOR = 0x1;
- private const uint OP_SUB = 0x2;
- private const uint OP_RSB = 0x3;
- private const uint OP_ADD = 0x4;
- private const uint OP_ADC = 0x5;
- private const uint OP_SBC = 0x6;
- private const uint OP_RSC = 0x7;
- private const uint OP_TST = 0x8;
- private const uint OP_TEQ = 0x9;
- private const uint OP_CMP = 0xA;
- private const uint OP_CMN = 0xB;
- private const uint OP_ORR = 0xC;
- private const uint OP_MOV = 0xD;
- private const uint OP_BIC = 0xE;
- private const uint OP_MVN = 0xF;
-
- private delegate void ExecuteInstructionDelegate();
- private ExecuteInstructionDelegate[] NormalOps = null;
-
- private Arm7Processor parent;
- private Memory memory;
- private uint[] registers;
-
- private uint instructionQueue;
- private uint curInstruction;
-
- // CPU flags
- private uint zero, carry, negative, overflow;
- private uint shifterCarry;
-
- private bool thumbMode;
-
- public FastArmCore(Arm7Processor parent, Memory memory)
- {
- this.parent = parent;
- this.memory = memory;
- this.registers = this.parent.Registers;
-
- this.NormalOps = new ExecuteInstructionDelegate[8]
- {
- this.UndefinedInstruction,
- this.UndefinedInstruction,
- this.UndefinedInstruction,
- this.UndefinedInstruction,
- this.LoadStoreMultiple,
- this.UndefinedInstruction,
- this.CoprocessorLoadStore,
- this.UndefinedInstruction
- };
-
- this.InitializeDispatchFunc();
- }
-
- public void BeginExecution()
- {
- this.FlushQueue();
- }
-
- public void Step()
- {
- this.UnpackFlags();
-
- this.curInstruction = this.instructionQueue;
- this.instructionQueue = this.memory.ReadU32(registers[15]);
- registers[15] += 4;
-
- uint cond = 0;
- switch (this.curInstruction >> 28)
- {
- case COND_AL: cond = 1; break;
- case COND_EQ: cond = zero; break;
- case COND_NE: cond = 1 - zero; break;
- case COND_CS: cond = carry; break;
- case COND_CC: cond = 1 - carry; break;
- case COND_MI: cond = negative; break;
- case COND_PL: cond = 1 - negative; break;
- case COND_VS: cond = overflow; break;
- case COND_VC: cond = 1 - overflow; break;
- case COND_HI: cond = carry & (1 - zero); break;
- case COND_LS: cond = (1 - carry) | zero; break;
- case COND_GE: cond = (1 - negative) ^ overflow; break;
- case COND_LT: cond = negative ^ overflow; break;
- case COND_GT: cond = (1 - zero) & (negative ^ (1 - overflow)); break;
- case COND_LE: cond = (negative ^ overflow) | zero; break;
- }
-
- if (cond == 1)
- {
- // Execute the instruction
- this.ExecuteInstruction((ushort)(((this.curInstruction >> 16) & 0xFF0) | ((this.curInstruction >> 4) & 0xF)));
- }
-
- this.parent.Cycles -= this.memory.WaitCycles;
-
- if ((this.parent.CPSR & Arm7Processor.T_MASK) == Arm7Processor.T_MASK)
- {
- this.parent.ReloadQueue();
- }
-
- this.PackFlags();
- }
-
- public void Execute()
- {
- this.UnpackFlags();
- this.thumbMode = false;
-
- while (this.parent.Cycles > 0)
- {
- this.curInstruction = this.instructionQueue;
- this.instructionQueue = this.memory.ReadU32Aligned(registers[15]);
- registers[15] += 4;
-
- if ((this.curInstruction >> 28) == COND_AL)
- {
- this.fastDispatch[(ushort)(((this.curInstruction >> 16) & 0xFF0) | ((this.curInstruction >> 4) & 0xF))]();
-// this.ExecuteInstruction((ushort)(((this.curInstruction >> 16) & 0xFF0) | ((this.curInstruction >> 4) & 0xF)));
- }
- else
- {
- uint cond = 0;
- switch (this.curInstruction >> 28)
- {
- case COND_EQ: cond = zero; break;
- case COND_NE: cond = 1 - zero; break;
- case COND_CS: cond = carry; break;
- case COND_CC: cond = 1 - carry; break;
- case COND_MI: cond = negative; break;
- case COND_PL: cond = 1 - negative; break;
- case COND_VS: cond = overflow; break;
- case COND_VC: cond = 1 - overflow; break;
- case COND_HI: cond = carry & (1 - zero); break;
- case COND_LS: cond = (1 - carry) | zero; break;
- case COND_GE: cond = (1 - negative) ^ overflow; break;
- case COND_LT: cond = negative ^ overflow; break;
- case COND_GT: cond = (1 - zero) & (negative ^ (1 - overflow)); break;
- case COND_LE: cond = (negative ^ overflow) | zero; break;
- }
-
- if (cond == 1)
- {
- // Execute the instruction
- this.fastDispatch[(ushort)(((this.curInstruction >> 16) & 0xFF0) | ((this.curInstruction >> 4) & 0xF))]();
-// this.ExecuteInstruction((ushort)(((this.curInstruction >> 16) & 0xFF0) | ((this.curInstruction >> 4) & 0xF)));
- }
- }
-
- this.parent.Cycles -= this.memory.WaitCycles;
-
- if (this.thumbMode)
- {
- this.parent.ReloadQueue();
- break;
- }
-
-#if ARM_DEBUG
- // Check the current PC
- if (this.parent.Breakpoints.ContainsKey(registers[15] - 4U))
- {
- this.parent.BreakpointHit = true;
- break;
- }
-#endif
- }
-
- this.PackFlags();
- }
-
- private void DataProcessingWriteToR15()
- {
- // Prevent writing if no SPSR exists (this will be true for USER or SYSTEM mode)
- if (this.parent.SPSRExists) this.parent.WriteCpsr(this.parent.SPSR);
- this.UnpackFlags();
-
- // Check for branch back to Thumb Mode
- if ((this.parent.CPSR & Arm7Processor.T_MASK) == Arm7Processor.T_MASK)
- {
- this.thumbMode = true;
- return;
- }
-
- // Otherwise, flush the instruction queue
- this.FlushQueue();
- }
-
- private uint BarrelShifterLslImmed()
- {
- // rm lsl immed
- uint rm = registers[this.curInstruction & 0xF];
- int amount = (int)((this.curInstruction >> 7) & 0x1F);
-
- if (amount == 0)
- {
- this.shifterCarry = this.carry;
- return rm;
- }
- else
- {
- this.shifterCarry = (rm >> (32 - amount)) & 1;
- return rm << amount;
- }
- }
-
- private uint BarrelShifterLslReg()
- {
- // rm lsl rs
- uint rm = registers[this.curInstruction & 0xF];
- uint rs = (this.curInstruction >> 8) & 0xF;
-
- int amount;
- if (rs == 15)
- {
- amount = (int)((registers[rs] + 0x4) & 0xFF);
- }
- else
- {
- amount = (int)(registers[rs] & 0xFF);
- }
-
- if ((this.curInstruction & 0xF) == 15)
- {
- rm += 4;
- }
-
- if (amount == 0)
- {
- this.shifterCarry = this.carry;
- return rm;
- }
-
- if (amount < 32)
- {
- this.shifterCarry = (rm >> (32 - amount)) & 1;
- return rm << amount;
- }
- else if (amount == 32)
- {
- this.shifterCarry = rm & 1;
- return 0;
- }
- else
- {
- this.shifterCarry = 0;
- return 0;
- }
- }
-
- private uint BarrelShifterLsrImmed()
- {
- // rm lsr immed
- uint rm = registers[this.curInstruction & 0xF];
- int amount = (int)((this.curInstruction >> 7) & 0x1F);
-
- if (amount == 0)
- {
- this.shifterCarry = (rm >> 31) & 1;
- return 0;
- }
- else
- {
- this.shifterCarry = (rm >> (amount - 1)) & 1;
- return rm >> amount;
- }
- }
-
- private uint BarrelShifterLsrReg()
- {
- // rm lsr rs
- uint rm = registers[this.curInstruction & 0xF];
- uint rs = (this.curInstruction >> 8) & 0xF;
-
- int amount;
- if (rs == 15)
- {
- amount = (int)((registers[rs] + 0x4) & 0xFF);
- }
- else
- {
- amount = (int)(registers[rs] & 0xFF);
- }
-
- if ((this.curInstruction & 0xF) == 15)
- {
- rm += 4;
- }
-
- if (amount == 0)
- {
- this.shifterCarry = this.carry;
- return rm;
- }
-
- if (amount < 32)
- {
- this.shifterCarry = (rm >> (amount - 1)) & 1;
- return rm >> amount;
- }
- else if (amount == 32)
- {
- this.shifterCarry = (rm >> 31) & 1;
- return 0;
- }
- else
- {
- this.shifterCarry = 0;
- return 0;
- }
- }
-
- private uint BarrelShifterAsrImmed()
- {
- // rm asr immed
- uint rm = registers[this.curInstruction & 0xF];
- int amount = (int)((this.curInstruction >> 7) & 0x1F);
-
- if (amount == 0)
- {
- if ((rm & (1 << 31)) == 0)
- {
- this.shifterCarry = 0;
- return 0;
- }
- else
- {
- this.shifterCarry = 1;
- return 0xFFFFFFFF;
- }
- }
- else
- {
- this.shifterCarry = (rm >> (amount - 1)) & 1;
- return (uint)(((int)rm) >> amount);
- }
- }
-
- private uint BarrelShifterAsrReg()
- {
- // rm asr rs
- uint rm = registers[this.curInstruction & 0xF];
- uint rs = (this.curInstruction >> 8) & 0xF;
-
- int amount;
- if (rs == 15)
- {
- amount = (int)((registers[rs] + 0x4) & 0xFF);
- }
- else
- {
- amount = (int)(registers[rs] & 0xFF);
- }
-
- if ((this.curInstruction & 0xF) == 15)
- {
- rm += 4;
- }
-
- if (amount == 0)
- {
- this.shifterCarry = this.carry;
- return rm;
- }
-
- if (amount >= 32)
- {
- if ((rm & (1 << 31)) == 0)
- {
- this.shifterCarry = 0;
- return 0;
- }
- else
- {
- this.shifterCarry = 1;
- return 0xFFFFFFFF;
- }
- }
- else
- {
- this.shifterCarry = (rm >> (amount - 1)) & 1;
- return (uint)(((int)rm) >> amount);
- }
- }
-
- private uint BarrelShifterRorImmed()
- {
- // rm ror immed
- uint rm = registers[this.curInstruction & 0xF];
- int amount = (int)((this.curInstruction >> 7) & 0x1F);
-
- if (amount == 0)
- {
- // Actually an RRX
- this.shifterCarry = rm & 1;
- return (this.carry << 31) | (rm >> 1);
- }
- else
- {
- this.shifterCarry = (rm >> (amount - 1)) & 1;
- return (rm >> amount) | (rm << (32 - amount));
- }
- }
-
- private uint BarrelShifterRorReg()
- {
- // rm ror rs
- uint rm = registers[this.curInstruction & 0xF];
- uint rs = (this.curInstruction >> 8) & 0xF;
-
- int amount;
- if (rs == 15)
- {
- amount = (int)((registers[rs] + 0x4) & 0xFF);
- }
- else
- {
- amount = (int)(registers[rs] & 0xFF);
- }
-
- if ((this.curInstruction & 0xF) == 15)
- {
- rm += 4;
- }
-
- if (amount == 0)
- {
- this.shifterCarry = this.carry;
- return rm;
- }
-
- if ((amount & 0x1F) == 0)
- {
- this.shifterCarry = (rm >> 31) & 1;
- return rm;
- }
- else
- {
- amount &= 0x1F;
- this.shifterCarry = (rm >> amount) & 1;
- return (rm >> amount) | (rm << (32 - amount));
- }
- }
-
- private uint BarrelShifterImmed()
- {
- uint immed = this.curInstruction & 0xFF;
- int rotateAmount = (int)(((this.curInstruction >> 8) & 0xF) * 2);
-
- if (rotateAmount == 0)
- {
- this.shifterCarry = this.carry;
- return immed;
- }
- else
- {
- immed = (immed >> rotateAmount) | (immed << (32 - rotateAmount));
- this.shifterCarry = (immed >> 31) & 1;
- return immed;
- }
- }
-
- private int MultiplyCycleCalculation(uint rs)
- {
- // Multiply cycle calculations
- if ((registers[rs] & 0xFFFFFF00) == 0 || (registers[rs] & 0xFFFFFF00) == 0xFFFFFF00)
- {
- return 1;
- }
- else if ((registers[rs] & 0xFFFF0000) == 0 || (registers[rs] & 0xFFFF0000) == 0xFFFF0000)
- {
- return 2;
- }
- else if ((registers[rs] & 0xFF000000) == 0 || (registers[rs] & 0xFF000000) == 0xFF000000)
- {
- return 3;
- }
- return 4;
- }
-
- private void UndefinedInstruction()
- {
- // Do the undefined instruction dance here
- throw new Exception("Undefined exception");
- }
-
- private void ExecuteInstruction(ushort op)
- {
- // Not emulating rn += 4 when register shift, in data operand when rn == pc
-
- uint rn, rd, rs, rm, address, offset, shifterOperand, alu;
- int cycles;
-
- switch (op)
- {
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // AND implementations
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- case 0x000:
- case 0x008:
- // AND rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & BarrelShifterLslImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x001:
- // AND rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & BarrelShifterLslReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x002:
- case 0x00A:
- // AND rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & BarrelShifterLsrImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x003:
- // AND rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & BarrelShifterLsrReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x004:
- case 0x00C:
- // AND rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & BarrelShifterAsrImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x005:
- // AND rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & BarrelShifterAsrReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x006:
- case 0x00E:
- // AND rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & BarrelShifterRorImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x007:
- // AND rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & BarrelShifterRorReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x010:
- case 0x018:
- // ANDS rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & BarrelShifterLslImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x011:
- // ANDS rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & BarrelShifterLslReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x012:
- case 0x01A:
- // ANDS rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & BarrelShifterLsrImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x013:
- // ANDS rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & BarrelShifterLsrReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x014:
- case 0x01C:
- // ANDS rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & BarrelShifterAsrImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x015:
- // ANDS rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & BarrelShifterAsrReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x016:
- case 0x01E:
- // ANDS rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & BarrelShifterRorImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x017:
- // ANDS rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & BarrelShifterRorReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Undefined instruction implementations
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- case 0x00D: case 0x02D: case 0x04D: case 0x06D:
- case 0x08D: case 0x0AD: case 0x0CD: case 0x0ED:
- case 0x10D: case 0x12D: case 0x14D: case 0x16D:
- case 0x18D: case 0x1AD: case 0x1CD: case 0x1ED:
- case 0x00F: case 0x02F: case 0x04F: case 0x06F:
- case 0x08F: case 0x0AF: case 0x0CF: case 0x0EF:
- case 0x10F: case 0x12F: case 0x14F: case 0x16F:
- case 0x18F: case 0x1AF: case 0x1CF: case 0x1EF:
- UndefinedInstruction();
- break;
-
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // MUL implementations
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- case 0x009:
- // MUL rd, rm, rs
- rd = (this.curInstruction >> 16) & 0xF;
- rs = (this.curInstruction >> 8) & 0xF;
- rm = this.curInstruction & 0xF;
-
- cycles = this.MultiplyCycleCalculation(rs);
-
- registers[rd] = registers[rs] * registers[rm];
- this.parent.Cycles -= cycles;
- break;
-
- case 0x019:
- // MULS rd, rm, rs
- rd = (this.curInstruction >> 16) & 0xF;
- rs = (this.curInstruction >> 8) & 0xF;
- rm = this.curInstruction & 0xF;
-
- cycles = this.MultiplyCycleCalculation(rs);
-
- registers[rd] = registers[rs] * registers[rm];
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
-
- this.parent.Cycles -= cycles;
- break;
-
- case 0x029:
- // MLA rd, rm, rs, rn
- rd = (this.curInstruction >> 16) & 0xF;
- rn = registers[(this.curInstruction >> 12) & 0xF];
- rs = (this.curInstruction >> 8) & 0xF;
- rm = this.curInstruction & 0xF;
-
- cycles = this.MultiplyCycleCalculation(rs);
-
- registers[rd] = registers[rs] * registers[rm] + rn;
- this.parent.Cycles -= cycles + 1;
- break;
-
- case 0x039:
- // MLAS rd, rm, rs
- rd = (this.curInstruction >> 16) & 0xF;
- rn = registers[(this.curInstruction >> 12) & 0xF];
- rs = (this.curInstruction >> 8) & 0xF;
- rm = this.curInstruction & 0xF;
-
- cycles = this.MultiplyCycleCalculation(rs);
-
- registers[rd] = registers[rs] * registers[rm] + rn;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
-
- this.parent.Cycles -= cycles + 1;
- break;
-
- case 0x089:
- // UMULL rdlo, rdhi, rm, rs
- {
- uint rdhi = (this.curInstruction >> 16) & 0xF;
- uint rdlo = (this.curInstruction >> 12) & 0xF;
- rs = (this.curInstruction >> 8) & 0xF;
- rm = this.curInstruction & 0xF;
-
- cycles = this.MultiplyCycleCalculation(rs) + 1;
-
- ulong result = ((ulong)registers[rm]) * registers[rs];
- registers[rdhi] = (uint)(result >> 32);
- registers[rdlo] = (uint)(result & 0xFFFFFFFF);
-
- this.parent.Cycles -= cycles;
- }
- break;
-
- case 0x099:
- // UMULLS rdlo, rdhi, rm, rs
- {
- uint rdhi = (this.curInstruction >> 16) & 0xF;
- uint rdlo = (this.curInstruction >> 12) & 0xF;
- rs = (this.curInstruction >> 8) & 0xF;
- rm = this.curInstruction & 0xF;
-
- cycles = this.MultiplyCycleCalculation(rs) + 1;
-
- ulong result = ((ulong)registers[rm]) * registers[rs];
- registers[rdhi] = (uint)(result >> 32);
- registers[rdlo] = (uint)(result & 0xFFFFFFFF);
-
- negative = registers[rdhi] >> 31;
- zero = (registers[rdhi] == 0 && registers[rdlo] == 0) ? 1U : 0U;
-
- this.parent.Cycles -= cycles;
- }
- break;
-
- case 0x0A9:
- // UMLAL rdlo, rdhi, rm, rs
- {
- uint rdhi = (this.curInstruction >> 16) & 0xF;
- uint rdlo = (this.curInstruction >> 12) & 0xF;
- rs = (this.curInstruction >> 8) & 0xF;
- rm = this.curInstruction & 0xF;
-
- cycles = this.MultiplyCycleCalculation(rs) + 2;
-
- ulong accum = (((ulong)registers[rdhi]) << 32) | registers[rdlo];
- ulong result = ((ulong)registers[rm]) * registers[rs];
- result += accum;
- registers[rdhi] = (uint)(result >> 32);
- registers[rdlo] = (uint)(result & 0xFFFFFFFF);
-
- this.parent.Cycles -= cycles;
- }
- break;
-
- case 0x0B9:
- // UMLALS rdlo, rdhi, rm, rs
- {
- uint rdhi = (this.curInstruction >> 16) & 0xF;
- uint rdlo = (this.curInstruction >> 12) & 0xF;
- rs = (this.curInstruction >> 8) & 0xF;
- rm = this.curInstruction & 0xF;
-
- cycles = this.MultiplyCycleCalculation(rs) + 2;
-
- ulong accum = (((ulong)registers[rdhi]) << 32) | registers[rdlo];
- ulong result = ((ulong)registers[rm]) * registers[rs];
- result += accum;
- registers[rdhi] = (uint)(result >> 32);
- registers[rdlo] = (uint)(result & 0xFFFFFFFF);
-
- negative = registers[rdhi] >> 31;
- zero = (registers[rdhi] == 0 && registers[rdlo] == 0) ? 1U : 0U;
-
- this.parent.Cycles -= cycles;
- }
- break;
-
- case 0x0C9:
- // SMULL rdlo, rdhi, rm, rs
- {
- uint rdhi = (this.curInstruction >> 16) & 0xF;
- uint rdlo = (this.curInstruction >> 12) & 0xF;
- rs = (this.curInstruction >> 8) & 0xF;
- rm = this.curInstruction & 0xF;
-
- cycles = this.MultiplyCycleCalculation(rs) + 1;
-
- long result = ((long)((int)registers[rm])) * ((long)((int)registers[rs]));
- registers[rdhi] = (uint)(result >> 32);
- registers[rdlo] = (uint)(result & 0xFFFFFFFF);
-
- this.parent.Cycles -= cycles;
- }
- break;
-
- case 0x0D9:
- // SMULLS rdlo, rdhi, rm, rs
- {
- uint rdhi = (this.curInstruction >> 16) & 0xF;
- uint rdlo = (this.curInstruction >> 12) & 0xF;
- rs = (this.curInstruction >> 8) & 0xF;
- rm = this.curInstruction & 0xF;
-
- cycles = this.MultiplyCycleCalculation(rs) + 1;
-
- long result = ((long)((int)registers[rm])) * ((long)((int)registers[rs]));
- registers[rdhi] = (uint)(result >> 32);
- registers[rdlo] = (uint)(result & 0xFFFFFFFF);
-
- negative = registers[rdhi] >> 31;
- zero = (registers[rdhi] == 0 && registers[rdlo] == 0) ? 1U : 0U;
-
- this.parent.Cycles -= cycles;
- }
- break;
-
- case 0x0E9:
- // SMLAL rdlo, rdhi, rm, rs
- {
- uint rdhi = (this.curInstruction >> 16) & 0xF;
- uint rdlo = (this.curInstruction >> 12) & 0xF;
- rs = (this.curInstruction >> 8) & 0xF;
- rm = this.curInstruction & 0xF;
-
- cycles = this.MultiplyCycleCalculation(rs) + 2;
-
- long accum = (((long)((int)registers[rdhi])) << 32) | registers[rdlo];
- long result = ((long)((int)registers[rm])) * ((long)((int)registers[rs]));
- result += accum;
- registers[rdhi] = (uint)(result >> 32);
- registers[rdlo] = (uint)(result & 0xFFFFFFFF);
-
- this.parent.Cycles -= cycles;
- }
- break;
-
- case 0x0F9:
- // SMLALS rdlo, rdhi, rm, rs
- {
- uint rdhi = (this.curInstruction >> 16) & 0xF;
- uint rdlo = (this.curInstruction >> 12) & 0xF;
- rs = (this.curInstruction >> 8) & 0xF;
- rm = this.curInstruction & 0xF;
-
- cycles = this.MultiplyCycleCalculation(rs) + 2;
-
- long accum = (((long)((int)registers[rdhi])) << 32) | registers[rdlo];
- long result = ((long)((int)registers[rm])) * ((long)((int)registers[rs]));
- result += accum;
- registers[rdhi] = (uint)(result >> 32);
- registers[rdlo] = (uint)(result & 0xFFFFFFFF);
-
- negative = registers[rdhi] >> 31;
- zero = (registers[rdhi] == 0 && registers[rdlo] == 0) ? 1U : 0U;
-
- this.parent.Cycles -= cycles;
- }
- break;
-
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // STRH implementations
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- case 0x00B:
- // STRH rd, [rn], -rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = this.registers[this.curInstruction & 0xF];
- offset = (uint)-offset;
-
- this.memory.WriteU16(address, (ushort)(registers[rd] & 0xFFFF));
- registers[rn] = address + offset;
- break;
-
- case 0x02B:
- // Writeback bit set, instruction is unpredictable
- // STRH rd, [rn], -rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = this.registers[this.curInstruction & 0xF];
- offset = (uint)-offset;
-
- this.memory.WriteU16(address, (ushort)(registers[rd] & 0xFFFF));
- registers[rn] = address + offset;
- break;
-
- case 0x04B:
- // STRH rd, [rn], -immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
- offset = (uint)-offset;
-
- this.memory.WriteU16(address, (ushort)(registers[rd] & 0xFFFF));
- registers[rn] = address + offset;
- break;
-
- case 0x06B:
- // Writeback bit set, instruction is unpredictable
- // STRH rd, [rn], -immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
- offset = (uint)-offset;
-
- this.memory.WriteU16(address, (ushort)(registers[rd] & 0xFFFF));
- registers[rn] = address + offset;
- break;
-
- case 0x08B:
- // STRH rd, [rn], rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = this.registers[this.curInstruction & 0xF];
-
- this.memory.WriteU16(address, (ushort)(registers[rd] & 0xFFFF));
- registers[rn] = address + offset;
- break;
-
- case 0x0AB:
- // Writeback bit set, instruction is unpredictable
- // STRH rd, [rn], rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = this.registers[this.curInstruction & 0xF];
-
- this.memory.WriteU16(address, (ushort)(registers[rd] & 0xFFFF));
- registers[rn] = address + offset;
- break;
-
- case 0x0CB:
- // STRH rd, [rn], immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
-
- this.memory.WriteU16(address, (ushort)(registers[rd] & 0xFFFF));
- registers[rn] = address + offset;
- break;
-
- case 0x0EB:
- // Writeback bit set, instruction is unpredictable
- // STRH rd, [rn], immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
-
- this.memory.WriteU16(address, (ushort)(registers[rd] & 0xFFFF));
- registers[rn] = address + offset;
- break;
-
- case 0x10B:
- // STRH rd, [rn, -rm]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.registers[this.curInstruction & 0xF];
- offset = (uint)-offset;
-
- this.memory.WriteU16(registers[rn] + offset, (ushort)(registers[rd] & 0xFFFF));
- break;
-
- case 0x12B:
- // STRH rd, [rn, -rm]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.registers[this.curInstruction & 0xF];
- offset = (uint)-offset;
-
- registers[rn] += offset;
- this.memory.WriteU16(registers[rn], (ushort)(registers[rd] & 0xFFFF));
- break;
-
- case 0x14B:
- // STRH rd, [rn, -immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
- offset = (uint)-offset;
-
- this.memory.WriteU16(registers[rn] + offset, (ushort)(registers[rd] & 0xFFFF));
- break;
-
- case 0x16B:
- // STRH rd, [rn], -immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
- offset = (uint)-offset;
-
- registers[rn] += offset;
- this.memory.WriteU16(registers[rn], (ushort)(registers[rd] & 0xFFFF));
- break;
-
- case 0x18B:
- // STRH rd, [rn, rm]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.registers[this.curInstruction & 0xF];
-
- this.memory.WriteU16(registers[rn] + offset, (ushort)(registers[rd] & 0xFFFF));
- break;
-
- case 0x1AB:
- // STRH rd, [rn, rm]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.registers[this.curInstruction & 0xF];
-
- registers[rn] += offset;
- this.memory.WriteU16(registers[rn], (ushort)(registers[rd] & 0xFFFF));
- break;
-
- case 0x1CB:
- // STRH rd, [rn, immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
-
- this.memory.WriteU16(registers[rn] + offset, (ushort)(registers[rd] & 0xFFFF));
- break;
-
- case 0x1EB:
- // STRH rd, [rn, immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
-
- registers[rn] += offset;
- this.memory.WriteU16(registers[rn], (ushort)(registers[rd] & 0xFFFF));
- break;
-
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // LDRH implementations
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- case 0x01B:
- // LDRH rd, [rn], -rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = this.registers[this.curInstruction & 0xF];
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU16(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- break;
-
- case 0x03B:
- // Writeback bit set, instruction is unpredictable
- // LDRH rd, [rn], -rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = this.registers[this.curInstruction & 0xF];
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU16(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- break;
-
- case 0x05B:
- // LDRH rd, [rn], -immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU16(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- break;
-
- case 0x07B:
- // Writeback bit set, instruction is unpredictable
- // LDRH rd, [rn], -rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU16(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- break;
-
- case 0x09B:
- // LDRH rd, [rn], rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = this.registers[this.curInstruction & 0xF];
-
- registers[rd] = this.memory.ReadU16(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- break;
-
- case 0x0BB:
- // Writeback bit set, instruction is unpredictable
- // LDRH rd, [rn], rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = this.registers[this.curInstruction & 0xF];
-
- registers[rd] = this.memory.ReadU16(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- break;
-
- case 0x0DB:
- // LDRH rd, [rn], immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
-
- registers[rd] = this.memory.ReadU16(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- break;
-
- case 0x0FB:
- // Writeback bit set, instruction is unpredictable
- // LDRH rd, [rn], rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
-
- registers[rd] = this.memory.ReadU16(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- break;
-
- case 0x11B:
- // LDRH rd, [rn, -rm]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.registers[this.curInstruction & 0xF];
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU16(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x13B:
- // LDRH rd, [rn, -rm]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.registers[this.curInstruction & 0xF];
- offset = (uint)-offset;
-
- registers[rn] += offset;
-
- registers[rd] = this.memory.ReadU16(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x15B:
- // LDRH rd, [rn, -immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU16(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x17B:
- // LDRH rd, [rn, -rm]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
- offset = (uint)-offset;
-
- registers[rn] += offset;
- registers[rd] = this.memory.ReadU16(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x19B:
- // LDRH rd, [rn, rm]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.registers[this.curInstruction & 0xF];
-
- registers[rd] = this.memory.ReadU16(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x1BB:
- // LDRH rd, [rn, rm]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.registers[this.curInstruction & 0xF];
-
- registers[rn] += offset;
- registers[rd] = this.memory.ReadU16(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x1DB:
- // LDRH rd, [rn, immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
-
- registers[rd] = this.memory.ReadU16(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x1FB:
- // LDRH rd, [rn, rm]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
-
- registers[rn] += offset;
- registers[rd] = this.memory.ReadU16(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // LDRSB implementations
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- case 0x01D:
- // LDRSB rd, [rn], -rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = this.registers[this.curInstruction & 0xF];
- offset = (uint)-offset;
-
- registers[rd] = (uint)(sbyte)this.memory.ReadU8(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- break;
-
- case 0x03D:
- // Writeback bit set, instruction is unpredictable
- // LDRSB rd, [rn], -rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = this.registers[this.curInstruction & 0xF];
- offset = (uint)-offset;
-
- registers[rd] = (uint)(sbyte)this.memory.ReadU8(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- break;
-
- case 0x05D:
- // LDRSB rd, [rn], -immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
- offset = (uint)-offset;
-
- registers[rd] = (uint)(sbyte)this.memory.ReadU8(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- break;
-
- case 0x07D:
- // Writeback bit set, instruction is unpredictable
- // LDRSB rd, [rn], -immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
- offset = (uint)-offset;
-
- registers[rd] = (uint)(sbyte)this.memory.ReadU8(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- break;
-
- case 0x09D:
- // LDRSB rd, [rn], rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = this.registers[this.curInstruction & 0xF];
-
- registers[rd] = (uint)(sbyte)this.memory.ReadU8(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- break;
-
- case 0x0BD:
- // Writeback bit set, instruction is unpredictable
- // LDRSB rd, [rn], rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = this.registers[this.curInstruction & 0xF];
-
- registers[rd] = (uint)(sbyte)this.memory.ReadU8(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- break;
-
- case 0x0DD:
- // LDRSB rd, [rn], immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
-
- registers[rd] = (uint)(sbyte)this.memory.ReadU8(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- break;
-
- case 0x0FD:
- // Writeback bit set, instruction is unpredictable
- // LDRSB rd, [rn], immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
-
- registers[rd] = (uint)(sbyte)this.memory.ReadU8(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- break;
-
- case 0x11D:
- // LDRSB rd, [rn, -rm]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.registers[this.curInstruction & 0xF];
- offset = (uint)-offset;
-
- registers[rd] = (uint)(sbyte)this.memory.ReadU8(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x13D:
- // LDRSB rd, [rn, -rm]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.registers[this.curInstruction & 0xF];
- offset = (uint)-offset;
-
- registers[rn] += offset;
- registers[rd] = (uint)(sbyte)this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x15D:
- // LDRSB rd, [rn, -immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
- offset = (uint)-offset;
-
- registers[rd] = (uint)(sbyte)this.memory.ReadU8(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x17D:
- // LDRSB rd, [rn, -immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
- offset = (uint)-offset;
-
- registers[rn] += offset;
- registers[rd] = (uint)(sbyte)this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x19D:
- // LDRSB rd, [rn, rm]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.registers[this.curInstruction & 0xF];
-
- registers[rd] = (uint)(sbyte)this.memory.ReadU8(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x1BD:
- // LDRSB rd, [rn, rm]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.registers[this.curInstruction & 0xF];
-
- registers[rd] = (uint)(sbyte)this.memory.ReadU8(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x1DD:
- // LDRSB rd, [rn, immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
-
- registers[rd] = (uint)(sbyte)this.memory.ReadU8(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x1FD:
- // LDRSB rd, [rn, immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
-
- registers[rn] += offset;
- registers[rd] = (uint)(sbyte)this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // LDRSH implementations
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- case 0x01F:
- // LDRSH rd, [rn], -rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = this.registers[this.curInstruction & 0xF];
- offset = (uint)-offset;
-
- registers[rd] = (uint)(short)this.memory.ReadU16(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- break;
-
- case 0x03F:
- // Writeback bit set, instruction is unpredictable
- // LDRSH rd, [rn], -rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = this.registers[this.curInstruction & 0xF];
- offset = (uint)-offset;
-
- registers[rd] = (uint)(short)this.memory.ReadU16(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- break;
-
- case 0x05F:
- // LDRSH rd, [rn], -immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
- offset = (uint)-offset;
-
- registers[rd] = (uint)(short)this.memory.ReadU16(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- break;
-
- case 0x07F:
- // Writeback bit set, instruction is unpredictable
- // LDRSH rd, [rn], -immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
- offset = (uint)-offset;
-
- registers[rd] = (uint)(short)this.memory.ReadU16(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- break;
-
- case 0x09F:
- // LDRSH rd, [rn], rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = this.registers[this.curInstruction & 0xF];
-
- registers[rd] = (uint)(short)this.memory.ReadU16(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- break;
-
- case 0x0BF:
- // Writeback bit set, instruction is unpredictable
- // LDRSH rd, [rn], rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = this.registers[this.curInstruction & 0xF];
-
- registers[rd] = (uint)(short)this.memory.ReadU16(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- break;
-
- case 0x0DF:
- // LDRSH rd, [rn], immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
-
- registers[rd] = (uint)(short)this.memory.ReadU16(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- break;
-
- case 0x0FF:
- // Writeback bit set, instruction is unpredictable
- // LDRSH rd, [rn], immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
-
- registers[rd] = (uint)(short)this.memory.ReadU16(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- break;
-
- case 0x11F:
- // LDRSH rd, [rn, -rm]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.registers[this.curInstruction & 0xF];
- offset = (uint)-offset;
-
- registers[rd] = (uint)(short)this.memory.ReadU16(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x13F:
- // LDRSH rd, [rn, -rm]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.registers[this.curInstruction & 0xF];
- offset = (uint)-offset;
-
- registers[rn] += offset;
- registers[rd] = (uint)(short)this.memory.ReadU16(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x15F:
- // LDRSH rd, [rn, -immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
- offset = (uint)-offset;
-
- registers[rd] = (uint)(short)this.memory.ReadU16(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x17F:
- // LDRSH rd, [rn, -immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
- offset = (uint)-offset;
-
- registers[rn] += offset;
- registers[rd] = (uint)(short)this.memory.ReadU16(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x19F:
- // LDRSH rd, [rn, rm]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.registers[this.curInstruction & 0xF];
-
- registers[rd] = (uint)(short)this.memory.ReadU16(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x1BF:
- // LDRSH rd, [rn, rm]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.registers[this.curInstruction & 0xF];
-
- registers[rn] += offset;
- registers[rd] = (uint)(short)this.memory.ReadU16(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x1DF:
- // LDRSH rd, [rn, immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
-
- registers[rd] = (uint)(short)this.memory.ReadU16(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x1FF:
- // LDRSH rd, [rn, immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
-
- registers[rn] += offset;
- registers[rd] = (uint)(short)this.memory.ReadU16(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // EOR implementations
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- case 0x020:
- case 0x028:
- // EOR rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn ^ BarrelShifterLslImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x021:
- // EOR rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn ^ BarrelShifterLslReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x022:
- case 0x02A:
- // EOR rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn ^ BarrelShifterLsrImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x023:
- // EOR rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn ^ BarrelShifterLsrReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x024:
- case 0x02C:
- // EOR rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn ^ BarrelShifterAsrImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x025:
- // EOR rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn ^ BarrelShifterAsrReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x026:
- case 0x02E:
- // EOR rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn ^ BarrelShifterRorImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x027:
- // EOR rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn ^ BarrelShifterRorReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x030:
- case 0x038:
- // EORS rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn ^ BarrelShifterLslImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x031:
- // EORS rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn ^ BarrelShifterLslReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x032:
- case 0x03A:
- // EORS rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn ^ BarrelShifterLsrImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x033:
- // EORS rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn ^ BarrelShifterLsrReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x034:
- case 0x03C:
- // EORS rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn ^ BarrelShifterAsrImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x035:
- // EORS rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn ^ BarrelShifterAsrReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x036:
- case 0x03E:
- // EORS rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn ^ BarrelShifterRorImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x037:
- // EORS rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn ^ BarrelShifterRorReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // SUB implementations
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- case 0x040:
- case 0x048:
- // SUB rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn - BarrelShifterLslImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x041:
- // SUB rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn - BarrelShifterLslReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x042:
- case 0x04A:
- // SUB rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn - BarrelShifterLsrImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x043:
- // SUB rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn - BarrelShifterLsrReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x044:
- case 0x04C:
- // SUB rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn - BarrelShifterAsrImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x045:
- // SUB rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn - BarrelShifterAsrReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x046:
- case 0x04E:
- // SUB rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn - BarrelShifterRorImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x047:
- // SUB rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn - BarrelShifterRorReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x050:
- case 0x058:
- // SUBS rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLslImmed();
- registers[rd] = rn - shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x051:
- // SUBS rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLslReg();
- registers[rd] = rn - shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x052:
- case 0x05A:
- // SUBS rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLsrImmed();
- registers[rd] = rn - shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x053:
- // SUBS rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLsrReg();
- registers[rd] = rn - shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x054:
- case 0x05C:
- // SUBS rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterAsrImmed();
- registers[rd] = rn - shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x055:
- // SUBS rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterAsrReg();
- registers[rd] = rn - shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x056:
- case 0x05E:
- // SUBS rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterRorImmed();
- registers[rd] = rn - shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x057:
- // SUBS rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterRorReg();
- registers[rd] = rn - shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // RSB implementations
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- case 0x060:
- case 0x068:
- // RSB rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterLslImmed() - rn;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x061:
- // RSB rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterLslReg() - rn;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x062:
- case 0x06A:
- // RSB rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterLsrImmed() - rn;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x063:
- // RSB rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterLsrReg() - rn;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x064:
- case 0x06C:
- // RSB rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterAsrImmed() - rn;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x065:
- // RSB rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterAsrReg() - rn;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x066:
- case 0x06E:
- // RSB rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterRorImmed() - rn;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x067:
- // RSB rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterRorReg() - rn;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x070:
- case 0x078:
- // RSBS rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLslImmed();
- registers[rd] = shifterOperand - rn;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x071:
- // RSBS rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLslReg();
- registers[rd] = shifterOperand - rn;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x072:
- case 0x07A:
- // RSBS rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLsrImmed();
- registers[rd] = shifterOperand - rn;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x073:
- // RSBS rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLsrReg();
- registers[rd] = shifterOperand - rn;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x074:
- case 0x07C:
- // RSBS rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterAsrImmed();
- registers[rd] = shifterOperand - rn;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x075:
- // RSBS rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterAsrReg();
- registers[rd] = shifterOperand - rn;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x076:
- case 0x07E:
- // RSBS rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterRorImmed();
- registers[rd] = shifterOperand - rn;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x077:
- // RSBS rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterRorReg();
- registers[rd] = shifterOperand - rn;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // ADD implementations
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- case 0x080:
- case 0x088:
- // ADD rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn + BarrelShifterLslImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x081:
- // ADD rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn + BarrelShifterLslReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x082:
- case 0x08A:
- // ADD rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn + BarrelShifterLsrImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x083:
- // ADD rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn + BarrelShifterLsrReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x084:
- case 0x08C:
- // ADD rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn + BarrelShifterAsrImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x085:
- // ADD rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn + BarrelShifterAsrReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x086:
- case 0x08E:
- // ADD rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn + BarrelShifterRorImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x087:
- // ADD rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn + BarrelShifterRorReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x090:
- case 0x098:
- // ADDS rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLslImmed();
- registers[rd] = rn + shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x091:
- // ADDS rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLslReg();
- registers[rd] = rn + shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x092:
- case 0x09A:
- // ADDS rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLsrImmed();
- registers[rd] = rn + shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x093:
- // ADDS rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLsrReg();
- registers[rd] = rn + shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x094:
- case 0x09C:
- // ADDS rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterAsrImmed();
- registers[rd] = rn + shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x095:
- // ADDS rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterAsrReg();
- registers[rd] = rn + shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x096:
- case 0x09E:
- // ADDS rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterRorImmed();
- registers[rd] = rn + shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x097:
- // ADDS rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterRorReg();
- registers[rd] = rn + shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // ADC implementations
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- case 0x0A0:
- case 0x0A8:
- // ADC rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn + BarrelShifterLslImmed() + carry;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x0A1:
- // ADC rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn + BarrelShifterLslReg() + carry;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x0A2:
- case 0x0AA:
- // ADC rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn + BarrelShifterLsrImmed() + carry;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x0A3:
- // ADC rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn + BarrelShifterLsrReg() + carry;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x0A4:
- case 0x0AC:
- // ADC rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn + BarrelShifterAsrImmed() + carry;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x0A5:
- // ADC rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn + BarrelShifterAsrReg() + carry;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x0A6:
- case 0x0AE:
- // ADC rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn + BarrelShifterRorImmed() + carry;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x0A7:
- // ADC rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn + BarrelShifterRorReg() + carry;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x0B0:
- case 0x0B8:
- // ADCS rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLslImmed();
- registers[rd] = rn + shifterOperand + carry;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x0B1:
- // ADCS rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLslReg();
- registers[rd] = rn + shifterOperand + carry;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x0B2:
- case 0x0BA:
- // ADCS rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLsrImmed();
- registers[rd] = rn + shifterOperand + carry;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x0B3:
- // ADCS rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLsrReg();
- registers[rd] = rn + shifterOperand + carry;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x0B4:
- case 0x0BC:
- // ADCS rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterAsrImmed();
- registers[rd] = rn + shifterOperand + carry;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x0B5:
- // ADCS rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterAsrReg();
- registers[rd] = rn + shifterOperand + carry;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x0B6:
- case 0x0BE:
- // ADCS rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterRorImmed();
- registers[rd] = rn + shifterOperand + carry;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x0B7:
- // ADCS rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterRorReg();
- registers[rd] = rn + shifterOperand + carry;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // SBC implementations
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- case 0x0C0:
- case 0x0C8:
- // SBC rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn - BarrelShifterLslImmed() - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x0C1:
- // SBC rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn - BarrelShifterLslReg() - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x0C2:
- case 0x0CA:
- // SBC rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn - BarrelShifterLsrImmed() - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x0C3:
- // SBC rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn - BarrelShifterLsrReg() - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x0C4:
- case 0x0CC:
- // SBC rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn - BarrelShifterAsrImmed() - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x0C5:
- // SBC rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn - BarrelShifterAsrReg() - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x0C6:
- case 0x0CE:
- // SBC rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn - BarrelShifterRorImmed() - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x0C7:
- // SBC rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn - BarrelShifterRorReg() - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x0D0:
- case 0x0D8:
- // SBCS rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLslImmed();
- registers[rd] = rn - shifterOperand - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x0D1:
- // SBCS rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLslReg();
- registers[rd] = rn - shifterOperand - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x0D2:
- case 0x0DA:
- // SBCS rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLsrImmed();
- registers[rd] = rn - shifterOperand - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x0D3:
- // SBCS rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLsrReg();
- registers[rd] = rn - shifterOperand - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x0D4:
- case 0x0DC:
- // SBCS rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterAsrImmed();
- registers[rd] = rn - shifterOperand - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x0D5:
- // SBCS rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterAsrReg();
- registers[rd] = rn - shifterOperand - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x0D6:
- case 0x0DE:
- // SBCS rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterRorImmed();
- registers[rd] = rn - shifterOperand - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x0D7:
- // SBCS rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterRorReg();
- registers[rd] = rn - shifterOperand - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // RSC implementations
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- case 0x0E0:
- case 0x0E8:
- // RSC rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterLslImmed() - rn - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x0E1:
- // RSC rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterLslReg() - rn - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x0E2:
- case 0x0EA:
- // RSC rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterLsrImmed() - rn - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x0E3:
- // RSC rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterLsrReg() - rn - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x0E4:
- case 0x0EC:
- // RSC rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterAsrImmed() - rn - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x0E5:
- // RSC rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterAsrReg() - rn - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x0E6:
- case 0x0EE:
- // RSC rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterRorImmed() - rn - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x0E7:
- // RSC rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterRorReg() - rn - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x0F0:
- case 0x0F8:
- // RSCS rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLslImmed();
- registers[rd] = shifterOperand - rn - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x0F1:
- // RSCS rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLslReg();
- registers[rd] = shifterOperand - rn - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x0F2:
- case 0x0FA:
- // RSCS rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLsrImmed();
- registers[rd] = shifterOperand - rn - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x0F3:
- // RSCS rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLsrReg();
- registers[rd] = shifterOperand - rn - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x0F4:
- case 0x0FC:
- // RSCS rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterAsrImmed();
- registers[rd] = shifterOperand - rn - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x0F5:
- // RSCS rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterAsrReg();
- registers[rd] = shifterOperand - rn - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x0F6:
- case 0x0FE:
- // RSCS rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterRorImmed();
- registers[rd] = shifterOperand - rn - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x0F7:
- // RSCS rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterRorReg();
- registers[rd] = shifterOperand - rn - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Misc. instructions (MSR, MRS, SWP, BX)
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- case 0x109:
- // SWP rd, rm, [rn]
- {
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
- rm = this.curInstruction & 0xF;
- uint tmp = this.memory.ReadU32(registers[rn]);
- this.memory.WriteU32(registers[rn], registers[rm]);
- registers[rd] = tmp;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- break;
-
- case 0x149:
- // SWPB rd, rm, [rn]
- {
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
- rm = this.curInstruction & 0xF;
-
- byte tmp = this.memory.ReadU8(registers[rn]);
- this.memory.WriteU8(registers[rn], (byte)(registers[rm] & 0xFF));
- registers[rd] = tmp;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- break;
-
- case 0x100:
- // MRS rd, cpsr
- rd = (this.curInstruction >> 12) & 0xF;
- this.PackFlags();
- registers[rd] = this.parent.CPSR;
- break;
-
- case 0x140:
- // MRS rd, spsr
- rd = (this.curInstruction >> 12) & 0xF;
- if (this.parent.SPSRExists) registers[rd] = this.parent.SPSR;
- break;
-
- case 0x120:
- // MSR cpsr, rm
- {
- rm = registers[this.curInstruction & 0xF];
- bool userMode = (this.parent.CPSR & 0x1F) == Arm7Processor.USR;
-
- this.PackFlags();
-
- uint tmpCPSR = this.parent.CPSR;
-
- if ((this.curInstruction & (1 << 16)) == 1 << 16 && !userMode)
- {
- tmpCPSR &= 0xFFFFFF00;
- tmpCPSR |= rm & 0x000000FF;
- }
- if ((this.curInstruction & (1 << 17)) == 1 << 17 && !userMode)
- {
- tmpCPSR &= 0xFFFF00FF;
- tmpCPSR |= rm & 0x0000FF00;
- }
- if ((this.curInstruction & (1 << 18)) == 1 << 18 && !userMode)
- {
- tmpCPSR &= 0xFF00FFFF;
- tmpCPSR |= rm & 0x00FF0000;
- }
- if ((this.curInstruction & (1 << 19)) == 1 << 19)
- {
- tmpCPSR &= 0x00FFFFFF;
- tmpCPSR |= rm & 0xFF000000;
- }
-
- this.parent.WriteCpsr(tmpCPSR);
-
- this.UnpackFlags();
-
- // Check for branch back to Thumb Mode
- if ((this.parent.CPSR & Arm7Processor.T_MASK) == Arm7Processor.T_MASK)
- {
- this.thumbMode = true;
- return;
- }
- }
- break;
-
- case 0x160:
- // MSR spsr, rm
- if (this.parent.SPSRExists)
- {
- rm = registers[this.curInstruction & 0xF];
- if ((this.curInstruction & (1 << 16)) == 1 << 16)
- {
- this.parent.SPSR &= 0xFFFFFF00;
- this.parent.SPSR |= rm & 0x000000FF;
- }
- if ((this.curInstruction & (1 << 17)) == 1 << 17)
- {
- this.parent.SPSR &= 0xFFFF00FF;
- this.parent.SPSR |= rm & 0x0000FF00;
- }
- if ((this.curInstruction & (1 << 18)) == 1 << 18)
- {
- this.parent.SPSR &= 0xFF00FFFF;
- this.parent.SPSR |= rm & 0x00FF0000;
- }
- if ((this.curInstruction & (1 << 19)) == 1 << 19)
- {
- this.parent.SPSR &= 0x00FFFFFF;
- this.parent.SPSR |= rm & 0xFF000000;
- }
- }
- break;
-
- case 0x320:
- // MSR cpsr, immed
- {
- uint immed = this.curInstruction & 0xFF;
- int rotateAmount = (int)(((this.curInstruction >> 8) & 0xF) * 2);
-
- immed = (immed >> rotateAmount) | (immed << (32 - rotateAmount));
-
- bool userMode = (this.parent.CPSR & 0x1F) == Arm7Processor.USR;
-
- this.PackFlags();
-
- uint tmpCPSR = this.parent.CPSR;
-
- if ((this.curInstruction & (1 << 16)) == 1 << 16 && !userMode)
- {
- tmpCPSR &= 0xFFFFFF00;
- tmpCPSR |= immed & 0x000000FF;
- }
- if ((this.curInstruction & (1 << 17)) == 1 << 17 && !userMode)
- {
- tmpCPSR &= 0xFFFF00FF;
- tmpCPSR |= immed & 0x0000FF00;
- }
- if ((this.curInstruction & (1 << 18)) == 1 << 18 && !userMode)
- {
- tmpCPSR &= 0xFF00FFFF;
- tmpCPSR |= immed & 0x00FF0000;
- }
- if ((this.curInstruction & (1 << 19)) == 1 << 19)
- {
- tmpCPSR &= 0x00FFFFFF;
- tmpCPSR |= immed & 0xFF000000;
- }
-
- this.parent.WriteCpsr(tmpCPSR);
-
- this.UnpackFlags();
-
- // Check for branch back to Thumb Mode
- if ((this.parent.CPSR & Arm7Processor.T_MASK) == Arm7Processor.T_MASK)
- {
- this.thumbMode = true;
- return;
- }
- }
- break;
-
- case 0x360:
- // MSR spsr, immed
- if (this.parent.SPSRExists)
- {
- uint immed = this.curInstruction & 0xFF;
- int rotateAmount = (int)(((this.curInstruction >> 8) & 0xF) * 2);
-
- immed = (immed >> rotateAmount) | (immed << (32 - rotateAmount));
-
- if ((this.curInstruction & (1 << 16)) == 1 << 16)
- {
- this.parent.SPSR &= 0xFFFFFF00;
- this.parent.SPSR |= immed & 0x000000FF;
- }
- if ((this.curInstruction & (1 << 17)) == 1 << 17)
- {
- this.parent.SPSR &= 0xFFFF00FF;
- this.parent.SPSR |= immed & 0x0000FF00;
- }
- if ((this.curInstruction & (1 << 18)) == 1 << 18)
- {
- this.parent.SPSR &= 0xFF00FFFF;
- this.parent.SPSR |= immed & 0x00FF0000;
- }
- if ((this.curInstruction & (1 << 19)) == 1 << 19)
- {
- this.parent.SPSR &= 0x00FFFFFF;
- this.parent.SPSR |= immed & 0xFF000000;
- }
- }
- break;
-
- case 0x121:
- // BX rm
- rm = this.curInstruction & 0xf;
-
- this.PackFlags();
-
- this.parent.CPSR &= ~Arm7Processor.T_MASK;
- this.parent.CPSR |= (registers[rm] & 1) << Arm7Processor.T_BIT;
-
- registers[15] = registers[rm] & (~1U);
-
- this.UnpackFlags();
-
- // Check for branch back to Thumb Mode
- if ((this.parent.CPSR & Arm7Processor.T_MASK) == Arm7Processor.T_MASK)
- {
- this.thumbMode = true;
- return;
- }
-
- this.FlushQueue();
- break;
-
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // TST implementations
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- case 0x110:
- case 0x118:
- // TSTS rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- alu = rn & BarrelShifterLslImmed();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- break;
-
- case 0x111:
- // TSTS rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- alu = rn & BarrelShifterLslReg();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- break;
-
- case 0x112:
- case 0x11A:
- // TSTS rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- alu = rn & BarrelShifterLsrImmed();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- break;
-
- case 0x113:
- // TSTS rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- alu = rn & BarrelShifterLsrReg();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- break;
-
- case 0x114:
- case 0x11C:
- // TSTS rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- alu = rn & BarrelShifterAsrImmed();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- break;
-
- case 0x115:
- // TSTS rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- alu = rn & BarrelShifterAsrReg();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- break;
-
- case 0x116:
- case 0x11E:
- // TSTS rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- alu = rn & BarrelShifterRorImmed();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- break;
-
- case 0x117:
- // TSTS rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = rn & BarrelShifterRorReg();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- break;
-
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // TEQ implementations
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- case 0x130:
- case 0x138:
- // TEQS rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- alu = rn ^ BarrelShifterLslImmed();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- break;
-
- case 0x131:
- // TEQS rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- alu = rn ^ BarrelShifterLslReg();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- break;
-
- case 0x132:
- case 0x13A:
- // TEQS rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- alu = rn ^ BarrelShifterLsrImmed();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- break;
-
- case 0x133:
- // TEQS rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- alu = rn ^ BarrelShifterLsrReg();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- break;
-
- case 0x134:
- case 0x13C:
- // TEQS rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- alu = rn ^ BarrelShifterAsrImmed();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- break;
-
- case 0x135:
- // TEQS rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- alu = rn ^ BarrelShifterAsrReg();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- break;
-
- case 0x136:
- case 0x13E:
- // TEQS rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- alu = rn ^ BarrelShifterRorImmed();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- break;
-
- case 0x137:
- // TEQS rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = rn ^ BarrelShifterRorReg();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- break;
-
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // CMP implementations
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- case 0x150:
- case 0x158:
- // CMP rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterLslImmed();
- alu = rn - shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, alu);
- break;
-
- case 0x151:
- // CMP rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterLslReg();
- alu = rn - shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, alu);
- break;
-
- case 0x152:
- case 0x15A:
- // CMP rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterLsrImmed();
- alu = rn - shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, alu);
- break;
-
- case 0x153:
- // CMP rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterLsrReg();
- alu = rn - shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, alu);
- break;
-
- case 0x154:
- case 0x15C:
- // CMP rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterAsrImmed();
- alu = rn - shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, alu);
- break;
-
- case 0x155:
- // CMP rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterAsrReg();
- alu = rn - shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, alu);
- break;
-
- case 0x156:
- case 0x15E:
- // CMP rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterRorImmed();
- alu = rn - shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, alu);
- break;
-
- case 0x157:
- // CMP rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterRorReg();
- alu = rn - shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, alu);
- break;
-
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // CMN implementations
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- case 0x170:
- case 0x178:
- // CMN rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterLslImmed();
- alu = rn + shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, alu);
- break;
-
- case 0x171:
- // CMN rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterLslReg();
- alu = rn + shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, alu);
- break;
-
- case 0x172:
- case 0x17A:
- // CMN rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterLsrImmed();
- alu = rn + shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, alu);
- break;
-
- case 0x173:
- // CMN rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterLsrReg();
- alu = rn + shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, alu);
- break;
-
- case 0x174:
- case 0x17C:
- // CMN rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterAsrImmed();
- alu = rn + shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, alu);
- break;
-
- case 0x175:
- // CMN rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterAsrReg();
- alu = rn + shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, alu);
- break;
-
- case 0x176:
- case 0x17E:
- // CMN rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterRorImmed();
- alu = rn + shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, alu);
- break;
-
- case 0x177:
- // CMN rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterRorReg();
- alu = rn + shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, alu);
- break;
-
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // ORR implementations
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- case 0x180:
- case 0x188:
- // ORR rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn | BarrelShifterLslImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x181:
- // ORR rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn | BarrelShifterLslReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x182:
- case 0x18A:
- // ORR rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn | BarrelShifterLsrImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x183:
- // ORR rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn | BarrelShifterLsrReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x184:
- case 0x18C:
- // ORR rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn | BarrelShifterAsrImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x185:
- // ORR rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn | BarrelShifterAsrReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x186:
- case 0x18E:
- // ORR rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn | BarrelShifterRorImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x187:
- // ORR rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn | BarrelShifterRorReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x190:
- case 0x198:
- // ORRS rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn | BarrelShifterLslImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x191:
- // ORRS rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn | BarrelShifterLslReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x192:
- case 0x19A:
- // ORRS rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn | BarrelShifterLsrImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x193:
- // ORRS rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn | BarrelShifterLsrReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x194:
- case 0x19C:
- // ORRS rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn | BarrelShifterAsrImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x195:
- // ORRS rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn | BarrelShifterAsrReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x196:
- case 0x19E:
- // ORRS rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn | BarrelShifterRorImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x197:
- // ORRS rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn | BarrelShifterRorReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // MOV implementations
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- case 0x1A0:
- case 0x1A8:
- // MOV rd, rm lsl immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterLslImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x1A1:
- // MOV rd, rm lsl rs
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterLslReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x1A2:
- case 0x1AA:
- // MOV rd, rm lsr immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterLsrImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x1A3:
- // MOV rd, rm lsr rs
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterLsrReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x1A4:
- case 0x1AC:
- // MOV rd, rm asr immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterAsrImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x1A5:
- // MOV rd, rm asr rs
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterAsrReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x1A6:
- case 0x1AE:
- // MOV rd, rm ror immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterRorImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x1A7:
- // MOV rd, rm ror rs
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterRorReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x1B0:
- case 0x1B8:
- // MOVS rd, rm lsl immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterLslImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x1B1:
- // MOVS rd, rm lsl rs
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterLslReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x1B2:
- case 0x1BA:
- // MOVS rd, rm lsr immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterLsrImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x1B3:
- // MOVS rd, rn, rm lsr rs
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterLsrReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x1B4:
- case 0x1BC:
- // MOVS rd, rn, rm asr immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterAsrImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x1B5:
- // MOVS rd, rn, rm asr rs
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterAsrReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x1B6:
- case 0x1BE:
- // MOVS rd, rn, rm ror immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterRorImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x1B7:
- // MOVS rd, rn, rm ror rs
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterRorReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // BIC implementations
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- case 0x1C0:
- case 0x1C8:
- // BIC rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & ~BarrelShifterLslImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x1C1:
- // BIC rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & ~BarrelShifterLslReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x1C2:
- case 0x1CA:
- // BIC rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & ~BarrelShifterLsrImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x1C3:
- // BIC rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & ~BarrelShifterLsrReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x1C4:
- case 0x1CC:
- // BIC rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & ~BarrelShifterAsrImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x1C5:
- // BIC rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & ~BarrelShifterAsrReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x1C6:
- case 0x1CE:
- // BIC rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & ~BarrelShifterRorImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x1C7:
- // BIC rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & ~BarrelShifterRorReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x1D0:
- case 0x1D8:
- // BICS rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & ~BarrelShifterLslImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x1D1:
- // BICS rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & ~BarrelShifterLslReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x1D2:
- case 0x1DA:
- // BICS rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & ~BarrelShifterLsrImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x1D3:
- // BICS rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & ~BarrelShifterLsrReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x1D4:
- case 0x1DC:
- // BICS rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & ~BarrelShifterAsrImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x1D5:
- // BICS rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & ~BarrelShifterAsrReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x1D6:
- case 0x1DE:
- // BICS rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & ~BarrelShifterRorImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x1D7:
- // BICS rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & ~BarrelShifterRorReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // MVN implementations
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- case 0x1E0:
- case 0x1E8:
- // MVN rd, rm lsl immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterLslImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x1E1:
- // MVN rd, rm lsl rs
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterLslReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x1E2:
- case 0x1EA:
- // MVN rd, rm lsr immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterLsrImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x1E3:
- // MVN rd, rm lsr rs
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterLsrReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x1E4:
- case 0x1EC:
- // MVN rd, rm asr immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterAsrImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x1E5:
- // MVN rd, rm asr rs
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterAsrReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x1E6:
- case 0x1EE:
- // MVN rd, rm ror immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterRorImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x1E7:
- // MVN rd, rm ror rs
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterRorReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x1F0:
- case 0x1F8:
- // MVNS rd, rm lsl immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterLslImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x1F1:
- // MVNS rd, rm lsl rs
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterLslReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x1F2:
- case 0x1FA:
- // MVNS rd, rm lsr immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterLsrImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x1F3:
- // MVNS rd, rn, rm lsr rs
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterLsrReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x1F4:
- case 0x1FC:
- // MVNS rd, rn, rm asr immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterAsrImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x1F5:
- // MVNS rd, rn, rm asr rs
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterAsrReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x1F6:
- case 0x1FE:
- // MVNS rd, rn, rm ror immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterRorImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x1F7:
- // MVNS rd, rn, rm ror rs
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterRorReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Data processing immediate operand implementations
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- case 0x200: case 0x201: case 0x202: case 0x203: case 0x204: case 0x205: case 0x206: case 0x207:
- case 0x208: case 0x209: case 0x20A: case 0x20B: case 0x20C: case 0x20D: case 0x20E: case 0x20F:
- // AND rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- registers[rd] = rn & BarrelShifterImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x210: case 0x211: case 0x212: case 0x213: case 0x214: case 0x215: case 0x216: case 0x217:
- case 0x218: case 0x219: case 0x21A: case 0x21B: case 0x21C: case 0x21D: case 0x21E: case 0x21F:
- // ANDS rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- registers[rd] = rn & BarrelShifterImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x220: case 0x221: case 0x222: case 0x223: case 0x224: case 0x225: case 0x226: case 0x227:
- case 0x228: case 0x229: case 0x22A: case 0x22B: case 0x22C: case 0x22D: case 0x22E: case 0x22F:
- // EOR rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- registers[rd] = rn ^ BarrelShifterImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x230: case 0x231: case 0x232: case 0x233: case 0x234: case 0x235: case 0x236: case 0x237:
- case 0x238: case 0x239: case 0x23A: case 0x23B: case 0x23C: case 0x23D: case 0x23E: case 0x23F:
- // EORS rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- registers[rd] = rn ^ BarrelShifterImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x240: case 0x241: case 0x242: case 0x243: case 0x244: case 0x245: case 0x246: case 0x247:
- case 0x248: case 0x249: case 0x24A: case 0x24B: case 0x24C: case 0x24D: case 0x24E: case 0x24F:
- // SUB rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- registers[rd] = rn - BarrelShifterImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x250: case 0x251: case 0x252: case 0x253: case 0x254: case 0x255: case 0x256: case 0x257:
- case 0x258: case 0x259: case 0x25A: case 0x25B: case 0x25C: case 0x25D: case 0x25E: case 0x25F:
- // SUBS rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterImmed();
- registers[rd] = rn - shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x260: case 0x261: case 0x262: case 0x263: case 0x264: case 0x265: case 0x266: case 0x267:
- case 0x268: case 0x269: case 0x26A: case 0x26B: case 0x26C: case 0x26D: case 0x26E: case 0x26F:
- // RSB rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- registers[rd] = BarrelShifterImmed() - rn;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x270: case 0x271: case 0x272: case 0x273: case 0x274: case 0x275: case 0x276: case 0x277:
- case 0x278: case 0x279: case 0x27A: case 0x27B: case 0x27C: case 0x27D: case 0x27E: case 0x27F:
- // RSBS rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterImmed();
- registers[rd] = shifterOperand - rn;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x280: case 0x281: case 0x282: case 0x283: case 0x284: case 0x285: case 0x286: case 0x287:
- case 0x288: case 0x289: case 0x28A: case 0x28B: case 0x28C: case 0x28D: case 0x28E: case 0x28F:
- // ADD rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- registers[rd] = rn + BarrelShifterImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x290: case 0x291: case 0x292: case 0x293: case 0x294: case 0x295: case 0x296: case 0x297:
- case 0x298: case 0x299: case 0x29A: case 0x29B: case 0x29C: case 0x29D: case 0x29E: case 0x29F:
- // ADDS rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterImmed();
- registers[rd] = rn + shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x2A0: case 0x2A1: case 0x2A2: case 0x2A3: case 0x2A4: case 0x2A5: case 0x2A6: case 0x2A7:
- case 0x2A8: case 0x2A9: case 0x2AA: case 0x2AB: case 0x2AC: case 0x2AD: case 0x2AE: case 0x2AF:
- // ADC rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- registers[rd] = rn + BarrelShifterImmed() + carry;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x2B0: case 0x2B1: case 0x2B2: case 0x2B3: case 0x2B4: case 0x2B5: case 0x2B6: case 0x2B7:
- case 0x2B8: case 0x2B9: case 0x2BA: case 0x2BB: case 0x2BC: case 0x2BD: case 0x2BE: case 0x2BF:
- // ADCS rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterImmed();
- registers[rd] = rn + shifterOperand + carry;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x2C0: case 0x2C1: case 0x2C2: case 0x2C3: case 0x2C4: case 0x2C5: case 0x2C6: case 0x2C7:
- case 0x2C8: case 0x2C9: case 0x2CA: case 0x2CB: case 0x2CC: case 0x2CD: case 0x2CE: case 0x2CF:
- // SBC rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- registers[rd] = rn - BarrelShifterImmed() - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x2D0: case 0x2D1: case 0x2D2: case 0x2D3: case 0x2D4: case 0x2D5: case 0x2D6: case 0x2D7:
- case 0x2D8: case 0x2D9: case 0x2DA: case 0x2DB: case 0x2DC: case 0x2DD: case 0x2DE: case 0x2DF:
- // SBCS rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterImmed();
- registers[rd] = rn - shifterOperand - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x2E0: case 0x2E1: case 0x2E2: case 0x2E3: case 0x2E4: case 0x2E5: case 0x2E6: case 0x2E7:
- case 0x2E8: case 0x2E9: case 0x2EA: case 0x2EB: case 0x2EC: case 0x2ED: case 0x2EE: case 0x2EF:
- // RSC rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- registers[rd] = BarrelShifterImmed() - rn - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x2F0: case 0x2F1: case 0x2F2: case 0x2F3: case 0x2F4: case 0x2F5: case 0x2F6: case 0x2F7:
- case 0x2F8: case 0x2F9: case 0x2FA: case 0x2FB: case 0x2FC: case 0x2FD: case 0x2FE: case 0x2FF:
- // RSCS rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterImmed();
- registers[rd] = shifterOperand - rn - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x310: case 0x311: case 0x312: case 0x313: case 0x314: case 0x315: case 0x316: case 0x317:
- case 0x318: case 0x319: case 0x31A: case 0x31B: case 0x31C: case 0x31D: case 0x31E: case 0x31F:
- // TSTS rn, immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- alu = rn & BarrelShifterImmed();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- break;
-
- case 0x330: case 0x331: case 0x332: case 0x333: case 0x334: case 0x335: case 0x336: case 0x337:
- case 0x338: case 0x339: case 0x33A: case 0x33B: case 0x33C: case 0x33D: case 0x33E: case 0x33F:
- // TEQS rn, immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- alu = rn ^ BarrelShifterImmed();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- break;
-
- case 0x350: case 0x351: case 0x352: case 0x353: case 0x354: case 0x355: case 0x356: case 0x357:
- case 0x358: case 0x359: case 0x35A: case 0x35B: case 0x35C: case 0x35D: case 0x35E: case 0x35F:
- // CMP rn, immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterImmed();
- alu = rn - shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, alu);
- break;
-
- case 0x370: case 0x371: case 0x372: case 0x373: case 0x374: case 0x375: case 0x376: case 0x377:
- case 0x378: case 0x379: case 0x37A: case 0x37B: case 0x37C: case 0x37D: case 0x37E: case 0x37F:
- // CMN rn, immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterImmed();
- alu = rn + shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, alu);
- break;
-
- case 0x380: case 0x381: case 0x382: case 0x383: case 0x384: case 0x385: case 0x386: case 0x387:
- case 0x388: case 0x389: case 0x38A: case 0x38B: case 0x38C: case 0x38D: case 0x38E: case 0x38F:
- // ORR rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- registers[rd] = rn | BarrelShifterImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x390: case 0x391: case 0x392: case 0x393: case 0x394: case 0x395: case 0x396: case 0x397:
- case 0x398: case 0x399: case 0x39A: case 0x39B: case 0x39C: case 0x39D: case 0x39E: case 0x39F:
- // ORRS rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- registers[rd] = rn | BarrelShifterImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x3A0: case 0x3A1: case 0x3A2: case 0x3A3: case 0x3A4: case 0x3A5: case 0x3A6: case 0x3A7:
- case 0x3A8: case 0x3A9: case 0x3AA: case 0x3AB: case 0x3AC: case 0x3AD: case 0x3AE: case 0x3AF:
- // MOV rd, immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x3B0: case 0x3B1: case 0x3B2: case 0x3B3: case 0x3B4: case 0x3B5: case 0x3B6: case 0x3B7:
- case 0x3B8: case 0x3B9: case 0x3BA: case 0x3BB: case 0x3BC: case 0x3BD: case 0x3BE: case 0x3BF:
- // MOVS rd, immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x3C0: case 0x3C1: case 0x3C2: case 0x3C3: case 0x3C4: case 0x3C5: case 0x3C6: case 0x3C7:
- case 0x3C8: case 0x3C9: case 0x3CA: case 0x3CB: case 0x3CC: case 0x3CD: case 0x3CE: case 0x3CF:
- // BIC rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- registers[rd] = rn & ~BarrelShifterImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x3D0: case 0x3D1: case 0x3D2: case 0x3D3: case 0x3D4: case 0x3D5: case 0x3D6: case 0x3D7:
- case 0x3D8: case 0x3D9: case 0x3DA: case 0x3DB: case 0x3DC: case 0x3DD: case 0x3DE: case 0x3DF:
- // BICS rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- registers[rd] = rn & ~BarrelShifterImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- case 0x3E0: case 0x3E1: case 0x3E2: case 0x3E3: case 0x3E4: case 0x3E5: case 0x3E6: case 0x3E7:
- case 0x3E8: case 0x3E9: case 0x3EA: case 0x3EB: case 0x3EC: case 0x3ED: case 0x3EE: case 0x3EF:
- // MVN rd, immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- break;
-
- case 0x3F0: case 0x3F1: case 0x3F2: case 0x3F3: case 0x3F4: case 0x3F5: case 0x3F6: case 0x3F7:
- case 0x3F8: case 0x3F9: case 0x3FA: case 0x3FB: case 0x3FC: case 0x3FD: case 0x3FE: case 0x3FF:
- // MVNS rd, immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- break;
-
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // STR immediate implementations
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- case 0x400: case 0x401: case 0x402: case 0x403: case 0x404: case 0x405: case 0x406: case 0x407:
- case 0x408: case 0x409: case 0x40A: case 0x40B: case 0x40C: case 0x40D: case 0x40E: case 0x40F:
- // STR rd, rn, -immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.curInstruction & 0xFFF;
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += offset;
- break;
-
- case 0x420: case 0x421: case 0x422: case 0x423: case 0x424: case 0x425: case 0x426: case 0x427:
- case 0x428: case 0x429: case 0x42A: case 0x42B: case 0x42C: case 0x42D: case 0x42E: case 0x42F:
- // STRT rd, rn, -immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.curInstruction & 0xFFF;
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += offset;
- break;
-
- case 0x440: case 0x441: case 0x442: case 0x443: case 0x444: case 0x445: case 0x446: case 0x447:
- case 0x448: case 0x449: case 0x44A: case 0x44B: case 0x44C: case 0x44D: case 0x44E: case 0x44F:
- // STRB rd, rn, -immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.curInstruction & 0xFFF;
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += offset;
- break;
-
- case 0x460: case 0x461: case 0x462: case 0x463: case 0x464: case 0x465: case 0x466: case 0x467:
- case 0x468: case 0x469: case 0x46A: case 0x46B: case 0x46C: case 0x46D: case 0x46E: case 0x46F:
- // STRBT rd, rn, -immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.curInstruction & 0xFFF;
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += offset;
- break;
-
- case 0x480: case 0x481: case 0x482: case 0x483: case 0x484: case 0x485: case 0x486: case 0x487:
- case 0x488: case 0x489: case 0x48A: case 0x48B: case 0x48C: case 0x48D: case 0x48E: case 0x48F:
- // STR rd, rn, immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += this.curInstruction & 0xFFF;
- break;
-
- case 0x4A0: case 0x4A1: case 0x4A2: case 0x4A3: case 0x4A4: case 0x4A5: case 0x4A6: case 0x4A7:
- case 0x4A8: case 0x4A9: case 0x4AA: case 0x4AB: case 0x4AC: case 0x4AD: case 0x4AE: case 0x4AF:
- // STRT rd, rn, immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += this.curInstruction & 0xFFF;
- break;
-
- case 0x4C0: case 0x4C1: case 0x4C2: case 0x4C3: case 0x4C4: case 0x4C5: case 0x4C6: case 0x4C7:
- case 0x4C8: case 0x4C9: case 0x4CA: case 0x4CB: case 0x4CC: case 0x4CD: case 0x4CE: case 0x4CF:
- // STRB rd, rn, immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += this.curInstruction & 0xFFF;
- break;
-
- case 0x4E0: case 0x4E1: case 0x4E2: case 0x4E3: case 0x4E4: case 0x4E5: case 0x4E6: case 0x4E7:
- case 0x4E8: case 0x4E9: case 0x4EA: case 0x4EB: case 0x4EC: case 0x4ED: case 0x4EE: case 0x4EF:
- // STRBT rd, rn, immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += this.curInstruction & 0xFFF;
- break;
-
- case 0x500: case 0x501: case 0x502: case 0x503: case 0x504: case 0x505: case 0x506: case 0x507:
- case 0x508: case 0x509: case 0x50A: case 0x50B: case 0x50C: case 0x50D: case 0x50E: case 0x50F:
- // STR rd, [rn, -immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.curInstruction & 0xFFF;
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn] + offset, alu);
- break;
-
- case 0x520: case 0x521: case 0x522: case 0x523: case 0x524: case 0x525: case 0x526: case 0x527:
- case 0x528: case 0x529: case 0x52A: case 0x52B: case 0x52C: case 0x52D: case 0x52E: case 0x52F:
- // STR rd, [rn, -immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.curInstruction & 0xFFF;
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += offset;
- this.memory.WriteU32(registers[rn], alu);
- break;
-
- case 0x540: case 0x541: case 0x542: case 0x543: case 0x544: case 0x545: case 0x546: case 0x547:
- case 0x548: case 0x549: case 0x54A: case 0x54B: case 0x54C: case 0x54D: case 0x54E: case 0x54F:
- // STRB rd, [rn, -immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.curInstruction & 0xFFF;
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn] + offset, (byte)(alu & 0xFF));
- break;
-
- case 0x560: case 0x561: case 0x562: case 0x563: case 0x564: case 0x565: case 0x566: case 0x567:
- case 0x568: case 0x569: case 0x56A: case 0x56B: case 0x56C: case 0x56D: case 0x56E: case 0x56F:
- // STRB rd, [rn, -immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.curInstruction & 0xFFF;
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += offset;
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- break;
-
- case 0x580: case 0x581: case 0x582: case 0x583: case 0x584: case 0x585: case 0x586: case 0x587:
- case 0x588: case 0x589: case 0x58A: case 0x58B: case 0x58C: case 0x58D: case 0x58E: case 0x58F:
- // STR rd, [rn, immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn] + (this.curInstruction & 0xFFF), alu);
- break;
-
- case 0x5A0: case 0x5A1: case 0x5A2: case 0x5A3: case 0x5A4: case 0x5A5: case 0x5A6: case 0x5A7:
- case 0x5A8: case 0x5A9: case 0x5AA: case 0x5AB: case 0x5AC: case 0x5AD: case 0x5AE: case 0x5AF:
- // STRT rd, [rn, immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += this.curInstruction & 0xFFF;
- this.memory.WriteU32(registers[rn], alu);
- break;
-
- case 0x5C0: case 0x5C1: case 0x5C2: case 0x5C3: case 0x5C4: case 0x5C5: case 0x5C6: case 0x5C7:
- case 0x5C8: case 0x5C9: case 0x5CA: case 0x5CB: case 0x5CC: case 0x5CD: case 0x5CE: case 0x5CF:
- // STRB rd, [rn, immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn] + (this.curInstruction & 0xFFF), (byte)(alu & 0xFF));
- break;
-
- case 0x5E0: case 0x5E1: case 0x5E2: case 0x5E3: case 0x5E4: case 0x5E5: case 0x5E6: case 0x5E7:
- case 0x5E8: case 0x5E9: case 0x5EA: case 0x5EB: case 0x5EC: case 0x5ED: case 0x5EE: case 0x5EF:
- // STRB rd, [rn, immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += this.curInstruction & 0xFFF;
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- break;
-
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // LDR immediate implementations
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- case 0x410: case 0x411: case 0x412: case 0x413: case 0x414: case 0x415: case 0x416: case 0x417:
- case 0x418: case 0x419: case 0x41A: case 0x41B: case 0x41C: case 0x41D: case 0x41E: case 0x41F:
- // LDR rd, rn, -immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.curInstruction & 0xFFF;
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x430: case 0x431: case 0x432: case 0x433: case 0x434: case 0x435: case 0x436: case 0x437:
- case 0x438: case 0x439: case 0x43A: case 0x43B: case 0x43C: case 0x43D: case 0x43E: case 0x43F:
- // LDRT rd, rn, -immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.curInstruction & 0xFFF;
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x450: case 0x451: case 0x452: case 0x453: case 0x454: case 0x455: case 0x456: case 0x457:
- case 0x458: case 0x459: case 0x45A: case 0x45B: case 0x45C: case 0x45D: case 0x45E: case 0x45F:
- // LDRB rd, rn, -immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.curInstruction & 0xFFF;
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x470: case 0x471: case 0x472: case 0x473: case 0x474: case 0x475: case 0x476: case 0x477:
- case 0x478: case 0x479: case 0x47A: case 0x47B: case 0x47C: case 0x47D: case 0x47E: case 0x47F:
- // LDRBT rd, rn, -immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.curInstruction & 0xFFF;
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x490: case 0x491: case 0x492: case 0x493: case 0x494: case 0x495: case 0x496: case 0x497:
- case 0x498: case 0x499: case 0x49A: case 0x49B: case 0x49C: case 0x49D: case 0x49E: case 0x49F:
- // LDR rd, rn, immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += this.curInstruction & 0xFFF;
- break;
-
- case 0x4B0: case 0x4B1: case 0x4B2: case 0x4B3: case 0x4B4: case 0x4B5: case 0x4B6: case 0x4B7:
- case 0x4B8: case 0x4B9: case 0x4BA: case 0x4BB: case 0x4BC: case 0x4BD: case 0x4BE: case 0x4BF:
- // LDRT rd, rn, immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += this.curInstruction & 0xFFF;
- break;
-
- case 0x4D0: case 0x4D1: case 0x4D2: case 0x4D3: case 0x4D4: case 0x4D5: case 0x4D6: case 0x4D7:
- case 0x4D8: case 0x4D9: case 0x4DA: case 0x4DB: case 0x4DC: case 0x4DD: case 0x4DE: case 0x4DF:
- // LDRB rd, rn, immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += this.curInstruction & 0xFFF;
- break;
-
- case 0x4F0: case 0x4F1: case 0x4F2: case 0x4F3: case 0x4F4: case 0x4F5: case 0x4F6: case 0x4F7:
- case 0x4F8: case 0x4F9: case 0x4FA: case 0x4FB: case 0x4FC: case 0x4FD: case 0x4FE: case 0x4FF:
- // LDRBT rd, rn, immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += this.curInstruction & 0xFFF;
- break;
-
- case 0x510: case 0x511: case 0x512: case 0x513: case 0x514: case 0x515: case 0x516: case 0x517:
- case 0x518: case 0x519: case 0x51A: case 0x51B: case 0x51C: case 0x51D: case 0x51E: case 0x51F:
- // LDR rd, [rn, -immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.curInstruction & 0xFFF;
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU32(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x530: case 0x531: case 0x532: case 0x533: case 0x534: case 0x535: case 0x536: case 0x537:
- case 0x538: case 0x539: case 0x53A: case 0x53B: case 0x53C: case 0x53D: case 0x53E: case 0x53F:
- // LDR rd, [rn, -immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.curInstruction & 0xFFF;
- offset = (uint)-offset;
-
- registers[rn] += offset;
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x550: case 0x551: case 0x552: case 0x553: case 0x554: case 0x555: case 0x556: case 0x557:
- case 0x558: case 0x559: case 0x55A: case 0x55B: case 0x55C: case 0x55D: case 0x55E: case 0x55F:
- // LDRB rd, [rn, -immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.curInstruction & 0xFFF;
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU8(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x570: case 0x571: case 0x572: case 0x573: case 0x574: case 0x575: case 0x576: case 0x577:
- case 0x578: case 0x579: case 0x57A: case 0x57B: case 0x57C: case 0x57D: case 0x57E: case 0x57F:
- // LDRB rd, [rn, -immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.curInstruction & 0xFFF;
- offset = (uint)-offset;
-
- registers[rn] += offset;
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x590: case 0x591: case 0x592: case 0x593: case 0x594: case 0x595: case 0x596: case 0x597:
- case 0x598: case 0x599: case 0x59A: case 0x59B: case 0x59C: case 0x59D: case 0x59E: case 0x59F:
- // LDR rd, [rn, immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = this.memory.ReadU32(registers[rn] + (this.curInstruction & 0xFFF));
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x5B0: case 0x5B1: case 0x5B2: case 0x5B3: case 0x5B4: case 0x5B5: case 0x5B6: case 0x5B7:
- case 0x5B8: case 0x5B9: case 0x5BA: case 0x5BB: case 0x5BC: case 0x5BD: case 0x5BE: case 0x5BF:
- // LDR rd, [rn, immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rn] += this.curInstruction & 0xFFF;
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x5D0: case 0x5D1: case 0x5D2: case 0x5D3: case 0x5D4: case 0x5D5: case 0x5D6: case 0x5D7:
- case 0x5D8: case 0x5D9: case 0x5DA: case 0x5DB: case 0x5DC: case 0x5DD: case 0x5DE: case 0x5DF:
- // LDRB rd, [rn, immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = this.memory.ReadU8(registers[rn] + (this.curInstruction & 0xFFF));
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x5F0: case 0x5F1: case 0x5F2: case 0x5F3: case 0x5F4: case 0x5F5: case 0x5F6: case 0x5F7:
- case 0x5F8: case 0x5F9: case 0x5FA: case 0x5FB: case 0x5FC: case 0x5FD: case 0x5FE: case 0x5FF:
- // LDRB rd, [rn, immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rn] += this.curInstruction & 0xFFF;
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // STR register shift implementations
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- case 0x600:
- case 0x608:
- // STR rd, rn, -rm lsl immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += offset;
- break;
-
- case 0x602:
- case 0x60A:
- // STR rd, rn, -rm lsr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += offset;
- break;
-
- case 0x604:
- case 0x60C:
- // STR rd, rn, -rm asr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += offset;
- break;
-
- case 0x606:
- case 0x60E:
- // STR rd, rn, -rm ror immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += offset;
- break;
-
- case 0x620:
- case 0x628:
- // STRT rd, rn, -rm lsl immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += offset;
- break;
-
- case 0x622:
- case 0x62A:
- // STRT rd, rn, -rm lsr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += offset;
- break;
-
- case 0x624:
- case 0x62C:
- // STRT rd, rn, -rm asr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += offset;
- break;
-
- case 0x626:
- case 0x62E:
- // STRT rd, rn, -rm ror immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += offset;
- break;
-
- case 0x640:
- case 0x648:
- // STRB rd, rn, -rm lsl immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += offset;
- break;
-
- case 0x642:
- case 0x64A:
- // STRB rd, rn, -rm lsr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += offset;
- break;
-
- case 0x644:
- case 0x64C:
- // STRB rd, rn, -rm asr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += offset;
- break;
-
- case 0x646:
- case 0x64E:
- // STRB rd, rn, -rm ror immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += offset;
- break;
-
- case 0x660:
- case 0x668:
- // STRBT rd, rn, -rm lsl immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += offset;
- break;
-
- case 0x662:
- case 0x66A:
- // STRBT rd, rn, -rm lsr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += offset;
- break;
-
- case 0x664:
- case 0x66C:
- // STRBT rd, rn, -rm asr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += offset;
- break;
-
- case 0x666:
- case 0x66E:
- // STRBT rd, rn, -rm ror immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += offset;
- break;
-
- case 0x680:
- case 0x688:
- // STR rd, rn, rm lsl immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += this.BarrelShifterLslImmed();
- break;
-
- case 0x682:
- case 0x68A:
- // STR rd, rn, rm lsr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += this.BarrelShifterLsrImmed();
- break;
-
- case 0x684:
- case 0x68C:
- // STR rd, rn, rm asr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += this.BarrelShifterAsrImmed();
- break;
-
- case 0x686:
- case 0x68E:
- // STR rd, rn, rm ror immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += this.BarrelShifterRorImmed();
- break;
-
- case 0x6A0:
- case 0x6A2:
- // STRT rd, rn, rm lsl immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += this.BarrelShifterLslImmed();
- break;
-
- case 0x6A4:
- case 0x6A6:
- // STRT rd, rn, rm lsr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += this.BarrelShifterLsrImmed();
- break;
-
- case 0x6A8:
- case 0x6AA:
- // STRT rd, rn, rm asr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += this.BarrelShifterAsrImmed();
- break;
-
- case 0x6AC:
- case 0x6AE:
- // STRT rd, rn, rm ror immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += this.BarrelShifterRorImmed();
- break;
-
- case 0x6C0:
- case 0x6C8:
- // STRB rd, rn, rm lsl immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += this.BarrelShifterLslImmed();
- break;
-
- case 0x6C2:
- case 0x6CA:
- // STRB rd, rn, rm lsr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += this.BarrelShifterLsrImmed();
- break;
-
- case 0x6C4:
- case 0x6CC:
- // STRB rd, rn, rm asr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += this.BarrelShifterAsrImmed();
- break;
-
- case 0x6C6:
- case 0x6CE:
- // STRB rd, rn, rm ror immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += this.BarrelShifterRorImmed();
- break;
-
- case 0x6E0:
- case 0x6E8:
- // STRBT rd, rn, rm lsl immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += this.BarrelShifterLslImmed();
- break;
-
- case 0x6E2:
- case 0x6EA:
- // STRBT rd, rn, rm lsr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += this.BarrelShifterLsrImmed();
- break;
-
- case 0x6E4:
- case 0x6EC:
- // STRBT rd, rn, rm asr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += this.BarrelShifterAsrImmed();
- break;
-
- case 0x6E6:
- case 0x6EE:
- // STRBT rd, rn, rm ror immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += this.BarrelShifterRorImmed();
- break;
-
- case 0x700:
- case 0x708:
- // STR rd, [rn, -rm lsl immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn] + offset, alu);
- break;
-
- case 0x702:
- case 0x70A:
- // STR rd, [rn, -rm lsr immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn] + offset, alu);
- break;
-
- case 0x704:
- case 0x70C:
- // STR rd, [rn, -rm asr immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn] + offset, alu);
- break;
-
- case 0x706:
- case 0x70E:
- // STR rd, [rn, -rm ror immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn] + offset, alu);
- break;
-
- case 0x720:
- case 0x728:
- // STR rd, [rn, -rm lsl immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += offset;
- this.memory.WriteU32(registers[rn], alu);
- break;
-
- case 0x722:
- case 0x72A:
- // STR rd, [rn, -rm lsr immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += offset;
- this.memory.WriteU32(registers[rn], alu);
- break;
-
- case 0x724:
- case 0x72C:
- // STR rd, [rn, -rm asr immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += offset;
- this.memory.WriteU32(registers[rn], alu);
- break;
-
- case 0x726:
- case 0x72E:
- // STR rd, [rn, -rm ror immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += offset;
- this.memory.WriteU32(registers[rn], alu);
- break;
-
- case 0x740:
- case 0x748:
- // STRB rd, [rn, -rm lsl immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn] + offset, (byte)(alu & 0xFF));
- break;
-
- case 0x742:
- case 0x74A:
- // STRB rd, [rn, -rm lsr immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn] + offset, (byte)(alu & 0xFF));
- break;
-
- case 0x744:
- case 0x74C:
- // STRB rd, [rn, -rm asr immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn] + offset, (byte)(alu & 0xFF));
- break;
-
- case 0x746:
- case 0x74E:
- // STRB rd, [rn, -rm ror immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn] + offset, (byte)(alu & 0xFF));
- break;
-
- case 0x760:
- case 0x768:
- // STRB rd, [rn, -rm lsl immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += offset;
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- break;
-
- case 0x762:
- case 0x76A:
- // STRB rd, [rn, -rm lsr immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += offset;
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- break;
-
- case 0x764:
- case 0x76C:
- // STRB rd, [rn, -rm asr immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += offset;
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- break;
-
- case 0x766:
- case 0x76E:
- // STRB rd, [rn, -rm ror immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += offset;
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- break;
-
- case 0x780:
- case 0x788:
- // STR rd, [rn, rm lsl immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn] + this.BarrelShifterLslImmed(), alu);
- break;
-
- case 0x782:
- case 0x78A:
- // STR rd, [rn, rm lsr immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn] + this.BarrelShifterLsrImmed(), alu);
- break;
-
- case 0x784:
- case 0x78C:
- // STR rd, [rn, rm asr immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn] + this.BarrelShifterAsrImmed(), alu);
- break;
-
- case 0x786:
- case 0x78E:
- // STR rd, [rn, rm ror immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn] + this.BarrelShifterRorImmed(), alu);
- break;
-
- case 0x7A0:
- case 0x7A8:
- // STR rd, [rn, rm lsl immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += this.BarrelShifterLslImmed();
- this.memory.WriteU32(registers[rn], alu);
- break;
-
- case 0x7A2:
- case 0x7AA:
- // STR rd, [rn, rm lsr immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += this.BarrelShifterLsrImmed();
- this.memory.WriteU32(registers[rn], alu);
- break;
-
- case 0x7A4:
- case 0x7AC:
- // STR rd, [rn, rm asr immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += this.BarrelShifterAsrImmed();
- this.memory.WriteU32(registers[rn], alu);
- break;
-
- case 0x7A6:
- case 0x7AE:
- // STR rd, [rn, rm ror immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += this.BarrelShifterRorImmed();
- this.memory.WriteU32(registers[rn], alu);
- break;
-
- case 0x7C0:
- case 0x7C8:
- // STRB rd, [rn, rm lsl immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn] + this.BarrelShifterLslImmed(), (byte)(alu & 0xFF));
- break;
-
- case 0x7C2:
- case 0x7CA:
- // STRB rd, [rn, rm lsr immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn] + this.BarrelShifterLsrImmed(), (byte)(alu & 0xFF));
- break;
-
- case 0x7C4:
- case 0x7CC:
- // STRB rd, [rn, rm asr immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn] + this.BarrelShifterAsrImmed(), (byte)(alu & 0xFF));
- break;
-
- case 0x7C6:
- case 0x7CE:
- // STRB rd, [rn, rm ror immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn] + this.BarrelShifterRorImmed(), (byte)(alu & 0xFF));
- break;
-
- case 0x7E0:
- case 0x7E8:
- // STRB rd, [rn, rm lsl immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += this.BarrelShifterLslImmed();
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- break;
-
- case 0x7E2:
- case 0x7EA:
- // STRB rd, [rn, rm lsr immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += this.BarrelShifterLsrImmed();
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- break;
-
- case 0x7E4:
- case 0x7EC:
- // STRB rd, [rn, rm asr immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += this.BarrelShifterAsrImmed();
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- break;
-
- case 0x7E6:
- case 0x7EE:
- // STRB rd, [rn, rm ror immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += this.BarrelShifterRorImmed();
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- break;
-
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // LDR register shift implementations
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- case 0x610:
- case 0x618:
- // LDR rd, rn, -rm lsl immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x612:
- case 0x61A:
- // LDR rd, rn, -rm lsr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x614:
- case 0x61C:
- // LDR rd, rn, -rm asr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x616:
- case 0x61E:
- // LDR rd, rn, -rm ror immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x630:
- case 0x638:
- // LDRT rd, rn, -rm lsl immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x632:
- case 0x63A:
- // LDRT rd, rn, -rm lsr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x634:
- case 0x63C:
- // LDRT rd, rn, -rm asr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x636:
- case 0x63E:
- // LDRT rd, rn, -rm ror immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x650:
- case 0x658:
- // LDRB rd, rn, -rm lsl immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x652:
- case 0x65A:
- // LDRB rd, rn, -rm lsr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x654:
- case 0x65C:
- // LDRB rd, rn, -rm asr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x656:
- case 0x65E:
- // LDRB rd, rn, -rm ror immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x670:
- case 0x678:
- // LDRBT rd, rn, -rm lsl immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x672:
- case 0x67A:
- // LDRBT rd, rn, -rm lsr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x674:
- case 0x67C:
- // LDRBT rd, rn, -rm asr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x676:
- case 0x67E:
- // LDRBT rd, rn, -rm ror immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x690:
- case 0x698:
- // LDR rd, rn, rm lsl immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x692:
- case 0x69A:
- // LDR rd, rn, rm lsr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x694:
- case 0x69C:
- // LDR rd, rn, rm asr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x696:
- case 0x69E:
- // LDR rd, rn, rm ror immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x6B0:
- case 0x6B8:
- // LDRT rd, rn, rm lsl immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x6B2:
- case 0x6BA:
- // LDRT rd, rn, rm lsr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x6B4:
- case 0x6BC:
- // LDRT rd, rn, rm asr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x6B6:
- case 0x6BE:
- // LDRT rd, rn, rm ror immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x6D0:
- case 0x6D8:
- // LDRB rd, rn, rm lsl immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x6D2:
- case 0x6DA:
- // LDRB rd, rn, rm lsr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x6D4:
- case 0x6DC:
- // LDRB rd, rn, rm asr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x6D6:
- case 0x6DE:
- // LDRB rd, rn, rm ror immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x6F0:
- case 0x6F8:
- // LDRBT rd, rn, rm lsl immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x6F2:
- case 0x6FA:
- // LDRBT rd, rn, rm lsr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x6F4:
- case 0x6FC:
- // LDRBT rd, rn, rm asr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x6F6:
- case 0x6FE:
- // LDRBT rd, rn, rm ror immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- break;
-
- case 0x710:
- case 0x718:
- // LDR rd, [rn, -rm lsl immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU32(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x712:
- case 0x71A:
- // LDR rd, [rn, -rm lsr immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU32(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x714:
- case 0x71C:
- // LDR rd, [rn, -rm asr immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU32(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x716:
- case 0x71E:
- // LDR rd, [rn, -rm ror immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU32(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x730:
- case 0x738:
- // LDR rd, [rn, -rm lsl immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- offset = (uint)-offset;
-
- registers[rn] += offset;
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x732:
- case 0x73A:
- // LDR rd, [rn, -rm lsr immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- offset = (uint)-offset;
-
- registers[rn] += offset;
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x734:
- case 0x73C:
- // LDR rd, [rn, -rm asr immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- offset = (uint)-offset;
-
- registers[rn] += offset;
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x736:
- case 0x73E:
- // LDR rd, [rn, -rm ror immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- offset = (uint)-offset;
-
- registers[rn] += offset;
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x750:
- case 0x758:
- // LDRB rd, [rn, -rm lsl immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU8(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x752:
- case 0x75A:
- // LDRB rd, [rn, -rm lsr immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU8(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x754:
- case 0x75C:
- // LDRB rd, [rn, -rm asr immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU8(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x756:
- case 0x75E:
- // LDRB rd, [rn, -rm ror immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU8(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x770:
- case 0x778:
- // LDRB rd, [rn, -rm lsl immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- offset = (uint)-offset;
-
- registers[rn] += offset;
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x772:
- case 0x77A:
- // LDRB rd, [rn, -rm lsr immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- offset = (uint)-offset;
-
- registers[rn] += offset;
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x774:
- case 0x77C:
- // LDRB rd, [rn, -rm asr immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- offset = (uint)-offset;
-
- registers[rn] += offset;
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x776:
- case 0x77E:
- // LDRB rd, [rn, -rm ror immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- offset = (uint)-offset;
-
- registers[rn] += offset;
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x790:
- case 0x798:
- // LDR rd, [rn, rm lsl immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = this.memory.ReadU32(registers[rn] + this.BarrelShifterLslImmed());
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x792:
- case 0x79A:
- // LDR rd, [rn, rm lsr immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = this.memory.ReadU32(registers[rn] + this.BarrelShifterLsrImmed());
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x794:
- case 0x79C:
- // LDR rd, [rn, rm asr immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = this.memory.ReadU32(registers[rn] + this.BarrelShifterAsrImmed());
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x796:
- case 0x79E:
- // LDR rd, [rn, rm ror immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = this.memory.ReadU32(registers[rn] + this.BarrelShifterRorImmed());
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x7B0:
- case 0x7B8:
- // LDR rd, [rn, rm lsl immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rn] += this.BarrelShifterLslImmed();
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x7B2:
- case 0x7BA:
- // LDR rd, [rn, rm lsr immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rn] += this.BarrelShifterLsrImmed();
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x7B4:
- case 0x7BC:
- // LDR rd, [rn, rm asr immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rn] += this.BarrelShifterAsrImmed();
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x7B6:
- case 0x7BE:
- // LDR rd, [rn, rm ror immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rn] += this.BarrelShifterRorImmed();
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x7D0:
- case 0x7D8:
- // LDRB rd, [rn, rm lsl immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = this.memory.ReadU8(registers[rn] + this.BarrelShifterLslImmed());
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x7D2:
- case 0x7DA:
- // LDRB rd, [rn, rm lsr immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = this.memory.ReadU8(registers[rn] + this.BarrelShifterLsrImmed());
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x7D4:
- case 0x7DC:
- // LDRB rd, [rn, rm asr immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = this.memory.ReadU8(registers[rn] + this.BarrelShifterAsrImmed());
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x7D6:
- case 0x7DE:
- // LDRB rd, [rn, rm ror immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = this.memory.ReadU8(registers[rn] + this.BarrelShifterRorImmed());
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x7F0:
- case 0x7F8:
- // LDRB rd, [rn, rm lsl immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rn] += this.BarrelShifterLslImmed();
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x7F2:
- case 0x7FA:
- // LDRB rd, [rn, rm lsr immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rn] += this.BarrelShifterLsrImmed();
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x7F4:
- case 0x7FC:
- // LDRB rd, [rn, rm asr immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rn] += this.BarrelShifterAsrImmed();
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- case 0x7F6:
- case 0x7FE:
- // LDRB rd, [rn, rm ror immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rn] += this.BarrelShifterRorImmed();
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- break;
-
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // LDM implementations (TODO)
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
-
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // STM implementations (TODO)
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
-
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // B implementation
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- case 0xA00: case 0xA01: case 0xA02: case 0xA03: case 0xA04: case 0xA05: case 0xA06: case 0xA07:
- case 0xA08: case 0xA09: case 0xA0A: case 0xA0B: case 0xA0C: case 0xA0D: case 0xA0E: case 0xA0F:
- case 0xA10: case 0xA11: case 0xA12: case 0xA13: case 0xA14: case 0xA15: case 0xA16: case 0xA17:
- case 0xA18: case 0xA19: case 0xA1A: case 0xA1B: case 0xA1C: case 0xA1D: case 0xA1E: case 0xA1F:
- case 0xA20: case 0xA21: case 0xA22: case 0xA23: case 0xA24: case 0xA25: case 0xA26: case 0xA27:
- case 0xA28: case 0xA29: case 0xA2A: case 0xA2B: case 0xA2C: case 0xA2D: case 0xA2E: case 0xA2F:
- case 0xA30: case 0xA31: case 0xA32: case 0xA33: case 0xA34: case 0xA35: case 0xA36: case 0xA37:
- case 0xA38: case 0xA39: case 0xA3A: case 0xA3B: case 0xA3C: case 0xA3D: case 0xA3E: case 0xA3F:
- case 0xA40: case 0xA41: case 0xA42: case 0xA43: case 0xA44: case 0xA45: case 0xA46: case 0xA47:
- case 0xA48: case 0xA49: case 0xA4A: case 0xA4B: case 0xA4C: case 0xA4D: case 0xA4E: case 0xA4F:
- case 0xA50: case 0xA51: case 0xA52: case 0xA53: case 0xA54: case 0xA55: case 0xA56: case 0xA57:
- case 0xA58: case 0xA59: case 0xA5A: case 0xA5B: case 0xA5C: case 0xA5D: case 0xA5E: case 0xA5F:
- case 0xA60: case 0xA61: case 0xA62: case 0xA63: case 0xA64: case 0xA65: case 0xA66: case 0xA67:
- case 0xA68: case 0xA69: case 0xA6A: case 0xA6B: case 0xA6C: case 0xA6D: case 0xA6E: case 0xA6F:
- case 0xA70: case 0xA71: case 0xA72: case 0xA73: case 0xA74: case 0xA75: case 0xA76: case 0xA77:
- case 0xA78: case 0xA79: case 0xA7A: case 0xA7B: case 0xA7C: case 0xA7D: case 0xA7E: case 0xA7F:
- case 0xA80: case 0xA81: case 0xA82: case 0xA83: case 0xA84: case 0xA85: case 0xA86: case 0xA87:
- case 0xA88: case 0xA89: case 0xA8A: case 0xA8B: case 0xA8C: case 0xA8D: case 0xA8E: case 0xA8F:
- case 0xA90: case 0xA91: case 0xA92: case 0xA93: case 0xA94: case 0xA95: case 0xA96: case 0xA97:
- case 0xA98: case 0xA99: case 0xA9A: case 0xA9B: case 0xA9C: case 0xA9D: case 0xA9E: case 0xA9F:
- case 0xAA0: case 0xAA1: case 0xAA2: case 0xAA3: case 0xAA4: case 0xAA5: case 0xAA6: case 0xAA7:
- case 0xAA8: case 0xAA9: case 0xAAA: case 0xAAB: case 0xAAC: case 0xAAD: case 0xAAE: case 0xAAF:
- case 0xAB0: case 0xAB1: case 0xAB2: case 0xAB3: case 0xAB4: case 0xAB5: case 0xAB6: case 0xAB7:
- case 0xAB8: case 0xAB9: case 0xABA: case 0xABB: case 0xABC: case 0xABD: case 0xABE: case 0xABF:
- case 0xAC0: case 0xAC1: case 0xAC2: case 0xAC3: case 0xAC4: case 0xAC5: case 0xAC6: case 0xAC7:
- case 0xAC8: case 0xAC9: case 0xACA: case 0xACB: case 0xACC: case 0xACD: case 0xACE: case 0xACF:
- case 0xAD0: case 0xAD1: case 0xAD2: case 0xAD3: case 0xAD4: case 0xAD5: case 0xAD6: case 0xAD7:
- case 0xAD8: case 0xAD9: case 0xADA: case 0xADB: case 0xADC: case 0xADD: case 0xADE: case 0xADF:
- case 0xAE0: case 0xAE1: case 0xAE2: case 0xAE3: case 0xAE4: case 0xAE5: case 0xAE6: case 0xAE7:
- case 0xAE8: case 0xAE9: case 0xAEA: case 0xAEB: case 0xAEC: case 0xAED: case 0xAEE: case 0xAEF:
- case 0xAF0: case 0xAF1: case 0xAF2: case 0xAF3: case 0xAF4: case 0xAF5: case 0xAF6: case 0xAF7:
- case 0xAF8: case 0xAF9: case 0xAFA: case 0xAFB: case 0xAFC: case 0xAFD: case 0xAFE: case 0xAFF:
- {
- uint branchOffset = this.curInstruction & 0x00FFFFFF;
- if (branchOffset >> 23 == 1) branchOffset |= 0xFF000000;
-
- this.registers[15] += branchOffset << 2;
-
- this.FlushQueue();
- }
- break;
-
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // BL implementation
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- case 0xB00: case 0xB01: case 0xB02: case 0xB03: case 0xB04: case 0xB05: case 0xB06: case 0xB07:
- case 0xB08: case 0xB09: case 0xB0A: case 0xB0B: case 0xB0C: case 0xB0D: case 0xB0E: case 0xB0F:
- case 0xB10: case 0xB11: case 0xB12: case 0xB13: case 0xB14: case 0xB15: case 0xB16: case 0xB17:
- case 0xB18: case 0xB19: case 0xB1A: case 0xB1B: case 0xB1C: case 0xB1D: case 0xB1E: case 0xB1F:
- case 0xB20: case 0xB21: case 0xB22: case 0xB23: case 0xB24: case 0xB25: case 0xB26: case 0xB27:
- case 0xB28: case 0xB29: case 0xB2A: case 0xB2B: case 0xB2C: case 0xB2D: case 0xB2E: case 0xB2F:
- case 0xB30: case 0xB31: case 0xB32: case 0xB33: case 0xB34: case 0xB35: case 0xB36: case 0xB37:
- case 0xB38: case 0xB39: case 0xB3A: case 0xB3B: case 0xB3C: case 0xB3D: case 0xB3E: case 0xB3F:
- case 0xB40: case 0xB41: case 0xB42: case 0xB43: case 0xB44: case 0xB45: case 0xB46: case 0xB47:
- case 0xB48: case 0xB49: case 0xB4A: case 0xB4B: case 0xB4C: case 0xB4D: case 0xB4E: case 0xB4F:
- case 0xB50: case 0xB51: case 0xB52: case 0xB53: case 0xB54: case 0xB55: case 0xB56: case 0xB57:
- case 0xB58: case 0xB59: case 0xB5A: case 0xB5B: case 0xB5C: case 0xB5D: case 0xB5E: case 0xB5F:
- case 0xB60: case 0xB61: case 0xB62: case 0xB63: case 0xB64: case 0xB65: case 0xB66: case 0xB67:
- case 0xB68: case 0xB69: case 0xB6A: case 0xB6B: case 0xB6C: case 0xB6D: case 0xB6E: case 0xB6F:
- case 0xB70: case 0xB71: case 0xB72: case 0xB73: case 0xB74: case 0xB75: case 0xB76: case 0xB77:
- case 0xB78: case 0xB79: case 0xB7A: case 0xB7B: case 0xB7C: case 0xB7D: case 0xB7E: case 0xB7F:
- case 0xB80: case 0xB81: case 0xB82: case 0xB83: case 0xB84: case 0xB85: case 0xB86: case 0xB87:
- case 0xB88: case 0xB89: case 0xB8A: case 0xB8B: case 0xB8C: case 0xB8D: case 0xB8E: case 0xB8F:
- case 0xB90: case 0xB91: case 0xB92: case 0xB93: case 0xB94: case 0xB95: case 0xB96: case 0xB97:
- case 0xB98: case 0xB99: case 0xB9A: case 0xB9B: case 0xB9C: case 0xB9D: case 0xB9E: case 0xB9F:
- case 0xBA0: case 0xBA1: case 0xBA2: case 0xBA3: case 0xBA4: case 0xBA5: case 0xBA6: case 0xBA7:
- case 0xBA8: case 0xBA9: case 0xBAA: case 0xBAB: case 0xBAC: case 0xBAD: case 0xBAE: case 0xBAF:
- case 0xBB0: case 0xBB1: case 0xBB2: case 0xBB3: case 0xBB4: case 0xBB5: case 0xBB6: case 0xBB7:
- case 0xBB8: case 0xBB9: case 0xBBA: case 0xBBB: case 0xBBC: case 0xBBD: case 0xBBE: case 0xBBF:
- case 0xBC0: case 0xBC1: case 0xBC2: case 0xBC3: case 0xBC4: case 0xBC5: case 0xBC6: case 0xBC7:
- case 0xBC8: case 0xBC9: case 0xBCA: case 0xBCB: case 0xBCC: case 0xBCD: case 0xBCE: case 0xBCF:
- case 0xBD0: case 0xBD1: case 0xBD2: case 0xBD3: case 0xBD4: case 0xBD5: case 0xBD6: case 0xBD7:
- case 0xBD8: case 0xBD9: case 0xBDA: case 0xBDB: case 0xBDC: case 0xBDD: case 0xBDE: case 0xBDF:
- case 0xBE0: case 0xBE1: case 0xBE2: case 0xBE3: case 0xBE4: case 0xBE5: case 0xBE6: case 0xBE7:
- case 0xBE8: case 0xBE9: case 0xBEA: case 0xBEB: case 0xBEC: case 0xBED: case 0xBEE: case 0xBEF:
- case 0xBF0: case 0xBF1: case 0xBF2: case 0xBF3: case 0xBF4: case 0xBF5: case 0xBF6: case 0xBF7:
- case 0xBF8: case 0xBF9: case 0xBFA: case 0xBFB: case 0xBFC: case 0xBFD: case 0xBFE: case 0xBFF:
- {
- uint branchOffset = this.curInstruction & 0x00FFFFFF;
- if (branchOffset >> 23 == 1) branchOffset |= 0xFF000000;
-
- this.registers[14] = this.registers[15] - 4U;
- this.registers[15] += branchOffset << 2;
-
- this.FlushQueue();
- }
- break;
-
- ////////////////////////////////////////////////////////////////////////////////////////////
- //
- // SWI implementation
- //
- ////////////////////////////////////////////////////////////////////////////////////////////
- case 0xF00: case 0xF01: case 0xF02: case 0xF03: case 0xF04: case 0xF05: case 0xF06: case 0xF07:
- case 0xF08: case 0xF09: case 0xF0A: case 0xF0B: case 0xF0C: case 0xF0D: case 0xF0E: case 0xF0F:
- case 0xF10: case 0xF11: case 0xF12: case 0xF13: case 0xF14: case 0xF15: case 0xF16: case 0xF17:
- case 0xF18: case 0xF19: case 0xF1A: case 0xF1B: case 0xF1C: case 0xF1D: case 0xF1E: case 0xF1F:
- case 0xF20: case 0xF21: case 0xF22: case 0xF23: case 0xF24: case 0xF25: case 0xF26: case 0xF27:
- case 0xF28: case 0xF29: case 0xF2A: case 0xF2B: case 0xF2C: case 0xF2D: case 0xF2E: case 0xF2F:
- case 0xF30: case 0xF31: case 0xF32: case 0xF33: case 0xF34: case 0xF35: case 0xF36: case 0xF37:
- case 0xF38: case 0xF39: case 0xF3A: case 0xF3B: case 0xF3C: case 0xF3D: case 0xF3E: case 0xF3F:
- case 0xF40: case 0xF41: case 0xF42: case 0xF43: case 0xF44: case 0xF45: case 0xF46: case 0xF47:
- case 0xF48: case 0xF49: case 0xF4A: case 0xF4B: case 0xF4C: case 0xF4D: case 0xF4E: case 0xF4F:
- case 0xF50: case 0xF51: case 0xF52: case 0xF53: case 0xF54: case 0xF55: case 0xF56: case 0xF57:
- case 0xF58: case 0xF59: case 0xF5A: case 0xF5B: case 0xF5C: case 0xF5D: case 0xF5E: case 0xF5F:
- case 0xF60: case 0xF61: case 0xF62: case 0xF63: case 0xF64: case 0xF65: case 0xF66: case 0xF67:
- case 0xF68: case 0xF69: case 0xF6A: case 0xF6B: case 0xF6C: case 0xF6D: case 0xF6E: case 0xF6F:
- case 0xF70: case 0xF71: case 0xF72: case 0xF73: case 0xF74: case 0xF75: case 0xF76: case 0xF77:
- case 0xF78: case 0xF79: case 0xF7A: case 0xF7B: case 0xF7C: case 0xF7D: case 0xF7E: case 0xF7F:
- case 0xF80: case 0xF81: case 0xF82: case 0xF83: case 0xF84: case 0xF85: case 0xF86: case 0xF87:
- case 0xF88: case 0xF89: case 0xF8A: case 0xF8B: case 0xF8C: case 0xF8D: case 0xF8E: case 0xF8F:
- case 0xF90: case 0xF91: case 0xF92: case 0xF93: case 0xF94: case 0xF95: case 0xF96: case 0xF97:
- case 0xF98: case 0xF99: case 0xF9A: case 0xF9B: case 0xF9C: case 0xF9D: case 0xF9E: case 0xF9F:
- case 0xFA0: case 0xFA1: case 0xFA2: case 0xFA3: case 0xFA4: case 0xFA5: case 0xFA6: case 0xFA7:
- case 0xFA8: case 0xFA9: case 0xFAA: case 0xFAB: case 0xFAC: case 0xFAD: case 0xFAE: case 0xFAF:
- case 0xFB0: case 0xFB1: case 0xFB2: case 0xFB3: case 0xFB4: case 0xFB5: case 0xFB6: case 0xFB7:
- case 0xFB8: case 0xFB9: case 0xFBA: case 0xFBB: case 0xFBC: case 0xFBD: case 0xFBE: case 0xFBF:
- case 0xFC0: case 0xFC1: case 0xFC2: case 0xFC3: case 0xFC4: case 0xFC5: case 0xFC6: case 0xFC7:
- case 0xFC8: case 0xFC9: case 0xFCA: case 0xFCB: case 0xFCC: case 0xFCD: case 0xFCE: case 0xFCF:
- case 0xFD0: case 0xFD1: case 0xFD2: case 0xFD3: case 0xFD4: case 0xFD5: case 0xFD6: case 0xFD7:
- case 0xFD8: case 0xFD9: case 0xFDA: case 0xFDB: case 0xFDC: case 0xFDD: case 0xFDE: case 0xFDF:
- case 0xFE0: case 0xFE1: case 0xFE2: case 0xFE3: case 0xFE4: case 0xFE5: case 0xFE6: case 0xFE7:
- case 0xFE8: case 0xFE9: case 0xFEA: case 0xFEB: case 0xFEC: case 0xFED: case 0xFEE: case 0xFEF:
- case 0xFF0: case 0xFF1: case 0xFF2: case 0xFF3: case 0xFF4: case 0xFF5: case 0xFF6: case 0xFF7:
- case 0xFF8: case 0xFF9: case 0xFFA: case 0xFFB: case 0xFFC: case 0xFFD: case 0xFFE: case 0xFFF:
- this.registers[15] -= 4U;
- this.parent.EnterException(Arm7Processor.SVC, 0x8, false, false);
- break;
-
- default:
- this.NormalOps[(curInstruction >> 25) & 0x7]();
- break;
- }
- }
-
- #region Barrel Shifter
- private const uint SHIFT_LSL = 0;
- private const uint SHIFT_LSR = 1;
- private const uint SHIFT_ASR = 2;
- private const uint SHIFT_ROR = 3;
-
- private uint BarrelShifter(uint shifterOperand)
- {
- uint type = (shifterOperand >> 5) & 0x3;
-
- bool registerShift = (shifterOperand & (1 << 4)) == (1 << 4);
-
- uint rm = registers[shifterOperand & 0xF];
-
- int amount;
- if (registerShift)
- {
- uint rs = (shifterOperand >> 8) & 0xF;
- if (rs == 15)
- {
- amount = (int)((registers[rs] + 0x4) & 0xFF);
- }
- else
- {
- amount = (int)(registers[rs] & 0xFF);
- }
-
- if ((shifterOperand & 0xF) == 15)
- {
- rm += 4;
- }
- }
- else
- {
- amount = (int)((shifterOperand >> 7) & 0x1F);
- }
-
- if (registerShift)
- {
- if (amount == 0)
- {
- this.shifterCarry = this.carry;
- return rm;
- }
-
- switch (type)
- {
- case SHIFT_LSL:
- if (amount < 32)
- {
- this.shifterCarry = (rm >> (32 - amount)) & 1;
- return rm << amount;
- }
- else if (amount == 32)
- {
- this.shifterCarry = rm & 1;
- return 0;
- }
- else
- {
- this.shifterCarry = 0;
- return 0;
- }
-
- case SHIFT_LSR:
- if (amount < 32)
- {
- this.shifterCarry = (rm >> (amount - 1)) & 1;
- return rm >> amount;
- }
- else if (amount == 32)
- {
- this.shifterCarry = (rm >> 31) & 1;
- return 0;
- }
- else
- {
- this.shifterCarry = 0;
- return 0;
- }
-
- case SHIFT_ASR:
- if (amount >= 32)
- {
- if ((rm & (1 << 31)) == 0)
- {
- this.shifterCarry = 0;
- return 0;
- }
- else
- {
- this.shifterCarry = 1;
- return 0xFFFFFFFF;
- }
- }
- else
- {
- this.shifterCarry = (rm >> (amount - 1)) & 1;
- return (uint)(((int)rm) >> amount);
- }
-
- case SHIFT_ROR:
- if ((amount & 0x1F) == 0)
- {
- this.shifterCarry = (rm >> 31) & 1;
- return rm;
- }
- else
- {
- amount &= 0x1F;
- this.shifterCarry = (rm >> amount) & 1;
- return (rm >> amount) | (rm << (32 - amount));
- }
- }
- }
- else
- {
- switch (type)
- {
- case SHIFT_LSL:
- if (amount == 0)
- {
- this.shifterCarry = this.carry;
- return rm;
- }
- else
- {
- this.shifterCarry = (rm >> (32 - amount)) & 1;
- return rm << amount;
- }
-
- case SHIFT_LSR:
- if (amount == 0)
- {
- this.shifterCarry = (rm >> 31) & 1;
- return 0;
- }
- else
- {
- this.shifterCarry = (rm >> (amount - 1)) & 1;
- return rm >> amount;
- }
-
- case SHIFT_ASR:
- if (amount == 0)
- {
- if ((rm & (1 << 31)) == 0)
- {
- this.shifterCarry = 0;
- return 0;
- }
- else
- {
- this.shifterCarry = 1;
- return 0xFFFFFFFF;
- }
- }
- else
- {
- this.shifterCarry = (rm >> (amount - 1)) & 1;
- return (uint)(((int)rm) >> amount);
- }
-
- case SHIFT_ROR:
- if (amount == 0)
- {
- // Actually an RRX
- this.shifterCarry = rm & 1;
- return (this.carry << 31) | (rm >> 1);
- }
- else
- {
- this.shifterCarry = (rm >> (amount - 1)) & 1;
- return (rm >> amount) | (rm << (32 - amount));
- }
- }
- }
-
- // Should never happen...
- throw new Exception("Barrel Shifter has messed up.");
- }
- #endregion
-
- #region Flag helpers
- public void OverflowCarryAdd(uint a, uint b, uint r)
- {
- overflow = ((a & b & ~r) | (~a & ~b & r)) >> 31;
- carry = ((a & b) | (a & ~r) | (b & ~r)) >> 31;
- }
-
- public void OverflowCarrySub(uint a, uint b, uint r)
- {
- overflow = ((a & ~b & ~r) | (~a & b & r)) >> 31;
- carry = ((a & ~b) | (a & ~r) | (~b & ~r)) >> 31;
- }
- #endregion
- #region Opcodes
- private void DoDataProcessing(uint shifterOperand)
- {
- uint rn = (this.curInstruction >> 16) & 0xF;
- uint rd = (this.curInstruction >> 12) & 0xF;
- uint alu;
-
- bool registerShift = (this.curInstruction & (1 << 4)) == (1 << 4);
- if (rn == 15 && ((this.curInstruction >> 25) & 0x7) == 0 && registerShift)
- {
- rn = registers[rn] + 4;
- }
- else
- {
- rn = registers[rn];
- }
-
- uint opcode = (this.curInstruction >> 21) & 0xF;
-
- if (((this.curInstruction >> 20) & 1) == 1)
- {
- // Set flag bit set
- switch (opcode)
- {
- case OP_ADC:
- registers[rd] = rn + shifterOperand + carry;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
- break;
-
- case OP_ADD:
- registers[rd] = rn + shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
- break;
-
- case OP_AND:
- registers[rd] = rn & shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- break;
-
- case OP_BIC:
- registers[rd] = rn & ~shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- break;
-
- case OP_CMN:
- alu = rn + shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, alu);
- break;
-
- case OP_CMP:
- alu = rn - shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, alu);
- break;
-
- case OP_EOR:
- registers[rd] = rn ^ shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- break;
-
- case OP_MOV:
- registers[rd] = shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- break;
-
- case OP_MVN:
- registers[rd] = ~shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- break;
-
- case OP_ORR:
- registers[rd] = rn | shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- break;
-
- case OP_RSB:
- registers[rd] = shifterOperand - rn;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
- break;
-
- case OP_RSC:
- registers[rd] = shifterOperand - rn - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
- break;
-
- case OP_SBC:
- registers[rd] = rn - shifterOperand - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
- break;
-
- case OP_SUB:
- registers[rd] = rn - shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
- break;
-
- case OP_TEQ:
- alu = rn ^ shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- break;
-
- case OP_TST:
- alu = rn & shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- break;
- }
-
- if (rd == 15)
- {
- // Prevent writing if no SPSR exists (this will be true for USER or SYSTEM mode)
- if (this.parent.SPSRExists) this.parent.WriteCpsr(this.parent.SPSR);
- this.UnpackFlags();
-
- // Check for branch back to Thumb Mode
- if ((this.parent.CPSR & Arm7Processor.T_MASK) == Arm7Processor.T_MASK)
- {
- this.thumbMode = true;
- return;
- }
-
- // Otherwise, flush the instruction queue
- this.FlushQueue();
- }
- }
- else
- {
- // Set flag bit not set
- switch (opcode)
- {
- case OP_ADC: registers[rd] = rn + shifterOperand + carry; break;
- case OP_ADD: registers[rd] = rn + shifterOperand; break;
- case OP_AND: registers[rd] = rn & shifterOperand; break;
- case OP_BIC: registers[rd] = rn & ~shifterOperand; break;
- case OP_EOR: registers[rd] = rn ^ shifterOperand; break;
- case OP_MOV: registers[rd] = shifterOperand; break;
- case OP_MVN: registers[rd] = ~shifterOperand; break;
- case OP_ORR: registers[rd] = rn | shifterOperand; break;
- case OP_RSB: registers[rd] = shifterOperand - rn; break;
- case OP_RSC: registers[rd] = shifterOperand - rn - (1U - carry); break;
- case OP_SBC: registers[rd] = rn - shifterOperand - (1U - carry); break;
- case OP_SUB: registers[rd] = rn - shifterOperand; break;
-
- case OP_CMN:
- // MSR SPSR, shifterOperand
- if ((this.curInstruction & (1 << 16)) == 1 << 16 && this.parent.SPSRExists)
- {
- this.parent.SPSR &= 0xFFFFFF00;
- this.parent.SPSR |= shifterOperand & 0x000000FF;
- }
- if ((this.curInstruction & (1 << 17)) == 1 << 17 && this.parent.SPSRExists)
- {
- this.parent.SPSR &= 0xFFFF00FF;
- this.parent.SPSR |= shifterOperand & 0x0000FF00;
- }
- if ((this.curInstruction & (1 << 18)) == 1 << 18 && this.parent.SPSRExists)
- {
- this.parent.SPSR &= 0xFF00FFFF;
- this.parent.SPSR |= shifterOperand & 0x00FF0000;
- }
- if ((this.curInstruction & (1 << 19)) == 1 << 19 && this.parent.SPSRExists)
- {
- this.parent.SPSR &= 0x00FFFFFF;
- this.parent.SPSR |= shifterOperand & 0xFF000000;
- }
-
- // Queue will be flushed since rd == 15, so adjust the PC
- registers[15] -= 4;
- break;
-
- case OP_CMP:
- // MRS rd, SPSR
- if (this.parent.SPSRExists) registers[rd] = this.parent.SPSR;
- break;
-
- case OP_TEQ:
- if (((this.curInstruction >> 4) & 0xf) == 1)
- {
- // BX
- uint rm = this.curInstruction & 0xf;
-
- this.PackFlags();
-
- this.parent.CPSR &= ~Arm7Processor.T_MASK;
- this.parent.CPSR |= (registers[rm] & 1) << Arm7Processor.T_BIT;
-
- registers[15] = registers[rm] & (~1U);
-
- this.UnpackFlags();
-
- // Check for branch back to Thumb Mode
- if ((this.parent.CPSR & Arm7Processor.T_MASK) == Arm7Processor.T_MASK)
- {
- this.thumbMode = true;
- return;
- }
-
- // Queue will be flushed later because rd == 15
- }
- else if (((this.curInstruction >> 4) & 0xf) == 0)
- {
- // MSR CPSR, shifterOperand
- bool userMode = (this.parent.CPSR & 0x1F) == Arm7Processor.USR;
-
- this.PackFlags();
-
- uint tmpCPSR = this.parent.CPSR;
-
- if ((this.curInstruction & (1 << 16)) == 1 << 16 && !userMode)
- {
- tmpCPSR &= 0xFFFFFF00;
- tmpCPSR |= shifterOperand & 0x000000FF;
- }
- if ((this.curInstruction & (1 << 17)) == 1 << 17 && !userMode)
- {
- tmpCPSR &= 0xFFFF00FF;
- tmpCPSR |= shifterOperand & 0x0000FF00;
- }
- if ((this.curInstruction & (1 << 18)) == 1 << 18 && !userMode)
- {
- tmpCPSR &= 0xFF00FFFF;
- tmpCPSR |= shifterOperand & 0x00FF0000;
- }
- if ((this.curInstruction & (1 << 19)) == 1 << 19)
- {
- tmpCPSR &= 0x00FFFFFF;
- tmpCPSR |= shifterOperand & 0xFF000000;
- }
-
- this.parent.WriteCpsr(tmpCPSR);
-
- this.UnpackFlags();
-
- // Check for branch back to Thumb Mode
- if ((this.parent.CPSR & Arm7Processor.T_MASK) == Arm7Processor.T_MASK)
- {
- this.thumbMode = true;
- return;
- }
-
- // Queue will be flushed since rd == 15, so adjust the PC
- registers[15] -= 4;
- }
- break;
-
- case OP_TST:
- // MRS rd, CPSR
- this.PackFlags();
- registers[rd] = this.parent.CPSR;
- break;
- }
-
- if (rd == 15)
- {
- // Flush the queue
- this.FlushQueue();
- }
- }
- }
-
- private void DataProcessing()
- {
- // Special instruction
- switch ((this.curInstruction >> 4) & 0xF)
- {
- case 0x9:
- // Multiply or swap instructions
- this.MultiplyOrSwap();
- return;
- case 0xB:
- // Load/Store Unsigned halfword
- this.LoadStoreHalfword();
- return;
- case 0xD:
- // Load/Store Signed byte
- this.LoadStoreHalfword();
- return;
- case 0xF:
- // Load/Store Signed halfword
- this.LoadStoreHalfword();
- return;
- }
-
- this.DoDataProcessing(this.BarrelShifter(this.curInstruction));
- }
-
- private void DataProcessingImmed()
- {
- uint immed = this.curInstruction & 0xFF;
- int rotateAmount = (int)(((this.curInstruction >> 8) & 0xF) * 2);
-
- immed = (immed >> rotateAmount) | (immed << (32 - rotateAmount));
-
- if (rotateAmount == 0)
- {
- this.shifterCarry = this.carry;
- }
- else
- {
- this.shifterCarry = (immed >> 31) & 1;
- }
-
- this.DoDataProcessing(immed);
- }
-
- private void LoadStore(uint offset)
- {
- uint rn = (this.curInstruction >> 16) & 0xF;
- uint rd = (this.curInstruction >> 12) & 0xF;
-
- uint address = registers[rn];
-
- bool preIndexed = (this.curInstruction & (1 << 24)) == 1 << 24;
- bool byteTransfer = (this.curInstruction & (1 << 22)) == 1 << 22;
- bool writeback = (this.curInstruction & (1 << 21)) == 1 << 21;
-
- // Add or subtract offset
- if ((this.curInstruction & (1 << 23)) != 1 << 23) offset = (uint)-offset;
-
- if (preIndexed)
- {
- address += offset;
-
- if (writeback)
- {
- registers[rn] = address;
- }
- }
-
- if ((this.curInstruction & (1 << 20)) == 1 << 20)
- {
- // Load
- if (byteTransfer)
- {
- registers[rd] = this.memory.ReadU8(address);
- }
- else
- {
- registers[rd] = this.memory.ReadU32(address);
- }
-
- // ARM9 fix here
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (!preIndexed)
- {
- if (rn != rd)
- registers[rn] = address + offset;
- }
- }
- else
- {
- // Store
- uint amount = registers[rd];
- if (rd == 15) amount += 4;
-
- if (byteTransfer)
- {
- this.memory.WriteU8(address, (byte)(amount & 0xFF));
- }
- else
- {
- this.memory.WriteU32(address, amount);
- }
-
- if (!preIndexed)
- {
- registers[rn] = address + offset;
- }
- }
- }
-
- private void LoadStoreImmediate()
- {
- this.LoadStore(this.curInstruction & 0xFFF);
- }
-
- private void LoadStoreRegister()
- {
- // The barrel shifter expects a 0 in bit 4 for immediate shifts, this is implicit in
- // the meaning of the instruction, so it is fine
- this.LoadStore(this.BarrelShifter(this.curInstruction));
- }
-
- private void LoadStoreMultiple()
- {
- uint rn = (this.curInstruction >> 16) & 0xF;
-
- this.PackFlags();
- uint curCpsr = this.parent.CPSR;
-
- bool preIncrement = (this.curInstruction & (1 << 24)) != 0;
- bool up = (this.curInstruction & (1 << 23)) != 0;
- bool writeback = (this.curInstruction & (1 << 21)) != 0;
-
- uint address;
- uint bitsSet = 0;
- for (int i = 0; i < 16; i++) if (((this.curInstruction >> i) & 1) != 0) bitsSet++;
-
- if (preIncrement)
- {
- if (up)
- {
- // Increment before
- address = this.registers[rn] + 4;
- if (writeback) this.registers[rn] += bitsSet * 4;
- }
- else
- {
- // Decrement before
- address = this.registers[rn] - (bitsSet * 4);
- if (writeback) this.registers[rn] -= bitsSet * 4;
- }
- }
- else
- {
- if (up)
- {
- // Increment after
- address = this.registers[rn];
- if (writeback) this.registers[rn] += bitsSet * 4;
- }
- else
- {
- // Decrement after
- address = this.registers[rn] - (bitsSet * 4) + 4;
- if (writeback) this.registers[rn] -= bitsSet * 4;
- }
- }
-
- if ((this.curInstruction & (1 << 20)) != 0)
- {
- if ((this.curInstruction & (1 << 22)) != 0 && ((this.curInstruction >> 15) & 1) == 0)
- {
- // Switch to user mode temporarily
- this.parent.WriteCpsr((curCpsr & ~0x1FU) | Arm7Processor.USR);
- }
-
- // Load multiple
- for (int i = 0; i < 15; i++)
- {
- if (((this.curInstruction >> i) & 1) != 1) continue;
- this.registers[i] = this.memory.ReadU32Aligned(address & (~0x3U));
- address += 4;
- }
-
- if (((this.curInstruction >> 15) & 1) == 1)
- {
- // Arm9 fix here
-
- this.registers[15] = this.memory.ReadU32Aligned(address & (~0x3U));
-
- if ((this.curInstruction & (1 << 22)) != 0)
- {
- // Load the CPSR from the SPSR
- if (this.parent.SPSRExists)
- {
- this.parent.WriteCpsr(this.parent.SPSR);
- this.UnpackFlags();
-
- // Check for branch back to Thumb Mode
- if ((this.parent.CPSR & Arm7Processor.T_MASK) == Arm7Processor.T_MASK)
- {
- this.thumbMode = true;
- this.registers[15] &= ~0x1U;
- return;
- }
- }
- }
-
- this.registers[15] &= ~0x3U;
- this.FlushQueue();
- }
- else
- {
- if ((this.curInstruction & (1 << 22)) != 0)
- {
- // Switch back to the correct mode
- this.parent.WriteCpsr(curCpsr);
- this.UnpackFlags();
-
- if ((this.parent.CPSR & Arm7Processor.T_MASK) == Arm7Processor.T_MASK)
- {
- this.thumbMode = true;
- return;
- }
- }
- }
- }
- else
- {
- if ((this.curInstruction & (1 << 22)) != 0)
- {
- // Switch to user mode temporarily
- this.parent.WriteCpsr((curCpsr & ~0x1FU) | Arm7Processor.USR);
- }
-
-/* if (((this.curInstruction >> (int)rn) & 1) != 0 && writeback &&
- (this.curInstruction & ~(0xFFFFFFFF << (int)rn)) == 0)
- {
- // If the lowest register is also the writeback, we use the original value
- // Does anybody do this????
- throw new Exception("Unhandled STM state");
- }
- else*/
- {
- // Store multiple
- for (int i = 0; i < 15; i++)
- {
- if (((this.curInstruction >> i) & 1) == 0) continue;
- this.memory.WriteU32(address, this.registers[i]);
- address += 4;
- }
-
- if (((this.curInstruction >> 15) & 1) != 0)
- {
- this.memory.WriteU32(address, this.registers[15] + 4U);
- }
- }
-
- if ((this.curInstruction & (1 << 22)) != 0)
- {
- // Switch back to the correct mode
- this.parent.WriteCpsr(curCpsr);
- this.UnpackFlags();
- }
- }
- }
-
- private void Branch()
- {
- if ((this.curInstruction & (1 << 24)) != 0)
- {
- this.registers[14] = (this.registers[15] - 4U) & ~3U;
- }
-
- uint branchOffset = this.curInstruction & 0x00FFFFFF;
- if (branchOffset >> 23 == 1) branchOffset |= 0xFF000000;
-
- this.registers[15] += branchOffset << 2;
-
- this.FlushQueue();
- }
-
- private void CoprocessorLoadStore()
- {
- throw new Exception("Unhandled opcode - coproc load/store");
- }
-
- private void SoftwareInterrupt()
- {
- // Adjust PC for prefetch
- this.registers[15] -= 4U;
- this.parent.EnterException(Arm7Processor.SVC, 0x8, false, false);
- }
-
- private void MultiplyOrSwap()
- {
- if ((this.curInstruction & (1 << 24)) == 1 << 24)
- {
- // Swap instruction
- uint rn = (this.curInstruction >> 16) & 0xF;
- uint rd = (this.curInstruction >> 12) & 0xF;
- uint rm = this.curInstruction & 0xF;
-
- if ((this.curInstruction & (1 << 22)) != 0)
- {
- // SWPB
- byte tmp = this.memory.ReadU8(registers[rn]);
- this.memory.WriteU8(registers[rn], (byte)(registers[rm] & 0xFF));
- registers[rd] = tmp;
- }
- else
- {
- // SWP
- uint tmp = this.memory.ReadU32(registers[rn]);
- this.memory.WriteU32(registers[rn], registers[rm]);
- registers[rd] = tmp;
- }
- }
- else
- {
- // Multiply instruction
- switch ((this.curInstruction >> 21) & 0x7)
- {
- case 0:
- case 1:
- {
- // Multiply/Multiply + Accumulate
- uint rd = (this.curInstruction >> 16) & 0xF;
- uint rn = registers[(this.curInstruction >> 12) & 0xF];
- uint rs = (this.curInstruction >> 8) & 0xF;
- uint rm = this.curInstruction & 0xF;
-
- int cycles = 4;
- // Multiply cycle calculations
- if ((registers[rs] & 0xFFFFFF00) == 0 || (registers[rs] & 0xFFFFFF00) == 0xFFFFFF00)
- {
- cycles = 1;
- }
- else if ((registers[rs] & 0xFFFF0000) == 0 || (registers[rs] & 0xFFFF0000) == 0xFFFF0000)
- {
- cycles = 2;
- }
- else if ((registers[rs] & 0xFF000000) == 0 || (registers[rs] & 0xFF000000) == 0xFF000000)
- {
- cycles = 3;
- }
-
- registers[rd] = registers[rs] * registers[rm];
- this.parent.Cycles -= cycles;
-
- if ((this.curInstruction & (1 << 21)) == 1 << 21)
- {
- registers[rd] += rn;
- this.parent.Cycles -= 1;
- }
-
- if ((this.curInstruction & (1 << 20)) == 1 << 20)
- {
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- }
- break;
- }
-
- case 2:
- case 3:
- throw new Exception("Invalid multiply");
-
- case 4:
- case 5:
- case 6:
- case 7:
- {
- // Multiply/Signed Multiply Long
- uint rdhi = (this.curInstruction >> 16) & 0xF;
- uint rdlo = (this.curInstruction >> 12) & 0xF;
- uint rs = (this.curInstruction >> 8) & 0xF;
- uint rm = this.curInstruction & 0xF;
-
- int cycles = 5;
- // Multiply cycle calculations
- if ((registers[rs] & 0xFFFFFF00) == 0 || (registers[rs] & 0xFFFFFF00) == 0xFFFFFF00)
- {
- cycles = 2;
- }
- else if ((registers[rs] & 0xFFFF0000) == 0 || (registers[rs] & 0xFFFF0000) == 0xFFFF0000)
- {
- cycles = 3;
- }
- else if ((registers[rs] & 0xFF000000) == 0 || (registers[rs] & 0xFF000000) == 0xFF000000)
- {
- cycles = 4;
- }
-
- this.parent.Cycles -= cycles;
-
- switch ((this.curInstruction >> 21) & 0x3)
- {
- case 0:
- {
- // UMULL
- ulong result = ((ulong)registers[rm]) * registers[rs];
- registers[rdhi] = (uint)(result >> 32);
- registers[rdlo] = (uint)(result & 0xFFFFFFFF);
- break;
- }
- case 1:
- {
- // UMLAL
- ulong accum = (((ulong)registers[rdhi]) << 32) | registers[rdlo];
- ulong result = ((ulong)registers[rm]) * registers[rs];
- result += accum;
- registers[rdhi] = (uint)(result >> 32);
- registers[rdlo] = (uint)(result & 0xFFFFFFFF);
- break;
- }
- case 2:
- {
- // SMULL
- long result = ((long)((int)registers[rm])) * ((long)((int)registers[rs]));
- registers[rdhi] = (uint)(result >> 32);
- registers[rdlo] = (uint)(result & 0xFFFFFFFF);
- break;
- }
- case 3:
- {
- // SMLAL
- long accum = (((long)((int)registers[rdhi])) << 32) | registers[rdlo];
- long result = ((long)((int)registers[rm])) * ((long)((int)registers[rs]));
- result += accum;
- registers[rdhi] = (uint)(result >> 32);
- registers[rdlo] = (uint)(result & 0xFFFFFFFF);
- break;
- }
- }
-
- if ((this.curInstruction & (1 << 20)) == 1 << 20)
- {
- negative = registers[rdhi] >> 31;
- zero = (registers[rdhi] == 0 && registers[rdlo] == 0) ? 1U : 0U;
- }
- break;
- }
- }
- }
- }
-
- private void LoadStoreHalfword()
- {
- uint rn = (this.curInstruction >> 16) & 0xF;
- uint rd = (this.curInstruction >> 12) & 0xF;
-
- uint address = registers[rn];
-
- bool preIndexed = (this.curInstruction & (1 << 24)) != 0;
- bool byteTransfer = (this.curInstruction & (1 << 5)) == 0;
- bool signedTransfer = (this.curInstruction & (1 << 6)) != 0;
- bool writeback = (this.curInstruction & (1 << 21)) != 0;
-
- uint offset;
- if ((this.curInstruction & (1 << 22)) != 0)
- {
- // Immediate offset
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
- }
- else
- {
- // Register offset
- offset = this.registers[this.curInstruction & 0xF];
- }
-
- // Add or subtract offset
- if ((this.curInstruction & (1 << 23)) == 0) offset = (uint)-offset;
-
- if (preIndexed)
- {
- address += offset;
-
- if (writeback)
- {
- registers[rn] = address;
- }
- }
-
- if ((this.curInstruction & (1 << 20)) != 0)
- {
- // Load
- if (byteTransfer)
- {
- if (signedTransfer)
- {
- registers[rd] = this.memory.ReadU8(address);
- if ((registers[rd] & 0x80) != 0)
- {
- registers[rd] |= 0xFFFFFF00;
- }
- }
- else
- {
- registers[rd] = this.memory.ReadU8(address);
- }
- }
- else
- {
- if (signedTransfer)
- {
- registers[rd] = this.memory.ReadU16(address);
- if ((registers[rd] & 0x8000) != 0)
- {
- registers[rd] |= 0xFFFF0000;
- }
- }
- else
- {
- registers[rd] = this.memory.ReadU16(address);
- }
- }
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (!preIndexed)
- {
- if (rn != rd)
- registers[rn] = address + offset;
- }
- }
- else
- {
- // Store
- if (byteTransfer)
- {
- this.memory.WriteU8(address, (byte)(registers[rd] & 0xFF));
- }
- else
- {
- this.memory.WriteU16(address, (ushort)(registers[rd] & 0xFFFF));
- }
-
- if (!preIndexed)
- {
- registers[rn] = address + offset;
- }
- }
- }
- #endregion Opcodes
-
- private void PackFlags()
- {
- this.parent.CPSR &= 0x0FFFFFFF;
- this.parent.CPSR |= this.negative << Arm7Processor.N_BIT;
- this.parent.CPSR |= this.zero << Arm7Processor.Z_BIT;
- this.parent.CPSR |= this.carry << Arm7Processor.C_BIT;
- this.parent.CPSR |= this.overflow << Arm7Processor.V_BIT;
- }
-
- private void UnpackFlags()
- {
- this.negative = (this.parent.CPSR >> Arm7Processor.N_BIT) & 1;
- this.zero = (this.parent.CPSR >> Arm7Processor.Z_BIT) & 1;
- this.carry = (this.parent.CPSR >> Arm7Processor.C_BIT) & 1;
- this.overflow = (this.parent.CPSR >> Arm7Processor.V_BIT) & 1;
- }
-
- private void FlushQueue()
- {
- this.instructionQueue = this.memory.ReadU32(registers[15]);
- registers[15] += 4;
- }
- }
-}
\ No newline at end of file
diff --git a/attic/GarboDev/FastDispatchCore.cs b/attic/GarboDev/FastDispatchCore.cs
deleted file mode 100644
index cb2c5e6a0f..0000000000
--- a/attic/GarboDev/FastDispatchCore.cs
+++ /dev/null
@@ -1,8469 +0,0 @@
-namespace GarboDev
-{
- partial class FastArmCore
- {
- #region Delegate Dispatcher
- private void DispatchFunc0()
- {
- uint rn, rd;
- // AND rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & BarrelShifterLslImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc1()
- {
- uint rn, rd;
- // AND rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & BarrelShifterLslReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc2()
- {
- uint rn, rd;
- // AND rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & BarrelShifterLsrImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc3()
- {
- uint rn, rd;
- // AND rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & BarrelShifterLsrReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc4()
- {
- uint rn, rd;
- // AND rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & BarrelShifterAsrImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc5()
- {
- uint rn, rd;
- // AND rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & BarrelShifterAsrReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc6()
- {
- uint rn, rd;
- // AND rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & BarrelShifterRorImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc7()
- {
- uint rn, rd;
- // AND rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & BarrelShifterRorReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc8()
- {
- uint rn, rd;
- // ANDS rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & BarrelShifterLslImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc9()
- {
- uint rn, rd;
- // ANDS rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & BarrelShifterLslReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc10()
- {
- uint rn, rd;
- // ANDS rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & BarrelShifterLsrImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc11()
- {
- uint rn, rd;
- // ANDS rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & BarrelShifterLsrReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc12()
- {
- uint rn, rd;
- // ANDS rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & BarrelShifterAsrImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc13()
- {
- uint rn, rd;
- // ANDS rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & BarrelShifterAsrReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc14()
- {
- uint rn, rd;
- // ANDS rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & BarrelShifterRorImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc15()
- {
- uint rn, rd;
- // ANDS rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & BarrelShifterRorReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc16()
- {
- UndefinedInstruction();
- }
- private void DispatchFunc17()
- {
- uint rd, rs, rm;
- int cycles;
- // MUL rd, rm, rs
- rd = (this.curInstruction >> 16) & 0xF;
- rs = (this.curInstruction >> 8) & 0xF;
- rm = this.curInstruction & 0xF;
-
- cycles = this.MultiplyCycleCalculation(rs);
-
- registers[rd] = registers[rs] * registers[rm];
- this.parent.Cycles -= cycles;
- }
- private void DispatchFunc18()
- {
- uint rd, rs, rm;
- int cycles;
- // MULS rd, rm, rs
- rd = (this.curInstruction >> 16) & 0xF;
- rs = (this.curInstruction >> 8) & 0xF;
- rm = this.curInstruction & 0xF;
-
- cycles = this.MultiplyCycleCalculation(rs);
-
- registers[rd] = registers[rs] * registers[rm];
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
-
- this.parent.Cycles -= cycles;
- }
- private void DispatchFunc19()
- {
- uint rn, rd, rs, rm;
- int cycles;
- // MLA rd, rm, rs, rn
- rd = (this.curInstruction >> 16) & 0xF;
- rn = registers[(this.curInstruction >> 12) & 0xF];
- rs = (this.curInstruction >> 8) & 0xF;
- rm = this.curInstruction & 0xF;
-
- cycles = this.MultiplyCycleCalculation(rs);
-
- registers[rd] = registers[rs] * registers[rm] + rn;
- this.parent.Cycles -= cycles + 1;
- }
- private void DispatchFunc20()
- {
- uint rn, rd, rs, rm;
- int cycles;
- // MLAS rd, rm, rs
- rd = (this.curInstruction >> 16) & 0xF;
- rn = registers[(this.curInstruction >> 12) & 0xF];
- rs = (this.curInstruction >> 8) & 0xF;
- rm = this.curInstruction & 0xF;
-
- cycles = this.MultiplyCycleCalculation(rs);
-
- registers[rd] = registers[rs] * registers[rm] + rn;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
-
- this.parent.Cycles -= cycles + 1;
- }
- private void DispatchFunc21()
- {
- uint rs, rm;
- int cycles;
- // UMULL rdlo, rdhi, rm, rs
- {
- uint rdhi = (this.curInstruction >> 16) & 0xF;
- uint rdlo = (this.curInstruction >> 12) & 0xF;
- rs = (this.curInstruction >> 8) & 0xF;
- rm = this.curInstruction & 0xF;
-
- cycles = this.MultiplyCycleCalculation(rs) + 1;
-
- ulong result = ((ulong)registers[rm]) * registers[rs];
- registers[rdhi] = (uint)(result >> 32);
- registers[rdlo] = (uint)(result & 0xFFFFFFFF);
-
- this.parent.Cycles -= cycles;
- }
- }
- private void DispatchFunc22()
- {
- uint rs, rm;
- int cycles;
- // UMULLS rdlo, rdhi, rm, rs
- {
- uint rdhi = (this.curInstruction >> 16) & 0xF;
- uint rdlo = (this.curInstruction >> 12) & 0xF;
- rs = (this.curInstruction >> 8) & 0xF;
- rm = this.curInstruction & 0xF;
-
- cycles = this.MultiplyCycleCalculation(rs) + 1;
-
- ulong result = ((ulong)registers[rm]) * registers[rs];
- registers[rdhi] = (uint)(result >> 32);
- registers[rdlo] = (uint)(result & 0xFFFFFFFF);
-
- negative = registers[rdhi] >> 31;
- zero = (registers[rdhi] == 0 && registers[rdlo] == 0) ? 1U : 0U;
-
- this.parent.Cycles -= cycles;
- }
- }
- private void DispatchFunc23()
- {
- uint rs, rm;
- int cycles;
- // UMLAL rdlo, rdhi, rm, rs
- {
- uint rdhi = (this.curInstruction >> 16) & 0xF;
- uint rdlo = (this.curInstruction >> 12) & 0xF;
- rs = (this.curInstruction >> 8) & 0xF;
- rm = this.curInstruction & 0xF;
-
- cycles = this.MultiplyCycleCalculation(rs) + 2;
-
- ulong accum = (((ulong)registers[rdhi]) << 32) | registers[rdlo];
- ulong result = ((ulong)registers[rm]) * registers[rs];
- result += accum;
- registers[rdhi] = (uint)(result >> 32);
- registers[rdlo] = (uint)(result & 0xFFFFFFFF);
-
- this.parent.Cycles -= cycles;
- }
- }
- private void DispatchFunc24()
- {
- uint rs, rm;
- int cycles;
- // UMLALS rdlo, rdhi, rm, rs
- {
- uint rdhi = (this.curInstruction >> 16) & 0xF;
- uint rdlo = (this.curInstruction >> 12) & 0xF;
- rs = (this.curInstruction >> 8) & 0xF;
- rm = this.curInstruction & 0xF;
-
- cycles = this.MultiplyCycleCalculation(rs) + 2;
-
- ulong accum = (((ulong)registers[rdhi]) << 32) | registers[rdlo];
- ulong result = ((ulong)registers[rm]) * registers[rs];
- result += accum;
- registers[rdhi] = (uint)(result >> 32);
- registers[rdlo] = (uint)(result & 0xFFFFFFFF);
-
- negative = registers[rdhi] >> 31;
- zero = (registers[rdhi] == 0 && registers[rdlo] == 0) ? 1U : 0U;
-
- this.parent.Cycles -= cycles;
- }
- }
- private void DispatchFunc25()
- {
- uint rs, rm;
- int cycles;
- // SMULL rdlo, rdhi, rm, rs
- {
- uint rdhi = (this.curInstruction >> 16) & 0xF;
- uint rdlo = (this.curInstruction >> 12) & 0xF;
- rs = (this.curInstruction >> 8) & 0xF;
- rm = this.curInstruction & 0xF;
-
- cycles = this.MultiplyCycleCalculation(rs) + 1;
-
- long result = ((long)((int)registers[rm])) * ((long)((int)registers[rs]));
- registers[rdhi] = (uint)(result >> 32);
- registers[rdlo] = (uint)(result & 0xFFFFFFFF);
-
- this.parent.Cycles -= cycles;
- }
- }
- private void DispatchFunc26()
- {
- uint rs, rm;
- int cycles;
- // SMULLS rdlo, rdhi, rm, rs
- {
- uint rdhi = (this.curInstruction >> 16) & 0xF;
- uint rdlo = (this.curInstruction >> 12) & 0xF;
- rs = (this.curInstruction >> 8) & 0xF;
- rm = this.curInstruction & 0xF;
-
- cycles = this.MultiplyCycleCalculation(rs) + 1;
-
- long result = ((long)((int)registers[rm])) * ((long)((int)registers[rs]));
- registers[rdhi] = (uint)(result >> 32);
- registers[rdlo] = (uint)(result & 0xFFFFFFFF);
-
- negative = registers[rdhi] >> 31;
- zero = (registers[rdhi] == 0 && registers[rdlo] == 0) ? 1U : 0U;
-
- this.parent.Cycles -= cycles;
- }
- }
- private void DispatchFunc27()
- {
- uint rs, rm;
- int cycles;
- // SMLAL rdlo, rdhi, rm, rs
- {
- uint rdhi = (this.curInstruction >> 16) & 0xF;
- uint rdlo = (this.curInstruction >> 12) & 0xF;
- rs = (this.curInstruction >> 8) & 0xF;
- rm = this.curInstruction & 0xF;
-
- cycles = this.MultiplyCycleCalculation(rs) + 2;
-
- long accum = (((long)((int)registers[rdhi])) << 32) | registers[rdlo];
- long result = ((long)((int)registers[rm])) * ((long)((int)registers[rs]));
- result += accum;
- registers[rdhi] = (uint)(result >> 32);
- registers[rdlo] = (uint)(result & 0xFFFFFFFF);
-
- this.parent.Cycles -= cycles;
- }
- }
- private void DispatchFunc28()
- {
- uint rs, rm;
- int cycles;
- // SMLALS rdlo, rdhi, rm, rs
- {
- uint rdhi = (this.curInstruction >> 16) & 0xF;
- uint rdlo = (this.curInstruction >> 12) & 0xF;
- rs = (this.curInstruction >> 8) & 0xF;
- rm = this.curInstruction & 0xF;
-
- cycles = this.MultiplyCycleCalculation(rs) + 2;
-
- long accum = (((long)((int)registers[rdhi])) << 32) | registers[rdlo];
- long result = ((long)((int)registers[rm])) * ((long)((int)registers[rs]));
- result += accum;
- registers[rdhi] = (uint)(result >> 32);
- registers[rdlo] = (uint)(result & 0xFFFFFFFF);
-
- negative = registers[rdhi] >> 31;
- zero = (registers[rdhi] == 0 && registers[rdlo] == 0) ? 1U : 0U;
-
- this.parent.Cycles -= cycles;
- }
- }
- private void DispatchFunc29()
- {
- uint rn, rd, address, offset;
- // STRH rd, [rn], -rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = this.registers[this.curInstruction & 0xF];
- offset = (uint)-offset;
-
- this.memory.WriteU16(address, (ushort)(registers[rd] & 0xFFFF));
- registers[rn] = address + offset;
- }
- private void DispatchFunc30()
- {
- uint rn, rd, address, offset;
- // Writeback bit set, instruction is unpredictable
- // STRH rd, [rn], -rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = this.registers[this.curInstruction & 0xF];
- offset = (uint)-offset;
-
- this.memory.WriteU16(address, (ushort)(registers[rd] & 0xFFFF));
- registers[rn] = address + offset;
- }
- private void DispatchFunc31()
- {
- uint rn, rd, address, offset;
- // STRH rd, [rn], -immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
- offset = (uint)-offset;
-
- this.memory.WriteU16(address, (ushort)(registers[rd] & 0xFFFF));
- registers[rn] = address + offset;
- }
- private void DispatchFunc32()
- {
- uint rn, rd, address, offset;
- // Writeback bit set, instruction is unpredictable
- // STRH rd, [rn], -immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
- offset = (uint)-offset;
-
- this.memory.WriteU16(address, (ushort)(registers[rd] & 0xFFFF));
- registers[rn] = address + offset;
- }
- private void DispatchFunc33()
- {
- uint rn, rd, address, offset;
- // STRH rd, [rn], rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = this.registers[this.curInstruction & 0xF];
-
- this.memory.WriteU16(address, (ushort)(registers[rd] & 0xFFFF));
- registers[rn] = address + offset;
- }
- private void DispatchFunc34()
- {
- uint rn, rd, address, offset;
- // Writeback bit set, instruction is unpredictable
- // STRH rd, [rn], rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = this.registers[this.curInstruction & 0xF];
-
- this.memory.WriteU16(address, (ushort)(registers[rd] & 0xFFFF));
- registers[rn] = address + offset;
- }
- private void DispatchFunc35()
- {
- uint rn, rd, address, offset;
- // STRH rd, [rn], immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
-
- this.memory.WriteU16(address, (ushort)(registers[rd] & 0xFFFF));
- registers[rn] = address + offset;
- }
- private void DispatchFunc36()
- {
- uint rn, rd, address, offset;
- // Writeback bit set, instruction is unpredictable
- // STRH rd, [rn], immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
-
- this.memory.WriteU16(address, (ushort)(registers[rd] & 0xFFFF));
- registers[rn] = address + offset;
- }
- private void DispatchFunc37()
- {
- uint rn, rd, offset;
- // STRH rd, [rn, -rm]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.registers[this.curInstruction & 0xF];
- offset = (uint)-offset;
-
- this.memory.WriteU16(registers[rn] + offset, (ushort)(registers[rd] & 0xFFFF));
- }
- private void DispatchFunc38()
- {
- uint rn, rd, offset;
- // STRH rd, [rn, -rm]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.registers[this.curInstruction & 0xF];
- offset = (uint)-offset;
-
- registers[rn] += offset;
- this.memory.WriteU16(registers[rn], (ushort)(registers[rd] & 0xFFFF));
- }
- private void DispatchFunc39()
- {
- uint rn, rd, offset;
- // STRH rd, [rn, -immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
- offset = (uint)-offset;
-
- this.memory.WriteU16(registers[rn] + offset, (ushort)(registers[rd] & 0xFFFF));
- }
- private void DispatchFunc40()
- {
- uint rn, rd, offset;
- // STRH rd, [rn], -immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
- offset = (uint)-offset;
-
- registers[rn] += offset;
- this.memory.WriteU16(registers[rn], (ushort)(registers[rd] & 0xFFFF));
- }
- private void DispatchFunc41()
- {
- uint rn, rd, offset;
- // STRH rd, [rn, rm]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.registers[this.curInstruction & 0xF];
-
- this.memory.WriteU16(registers[rn] + offset, (ushort)(registers[rd] & 0xFFFF));
- }
- private void DispatchFunc42()
- {
- uint rn, rd, offset;
- // STRH rd, [rn, rm]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.registers[this.curInstruction & 0xF];
-
- registers[rn] += offset;
- this.memory.WriteU16(registers[rn], (ushort)(registers[rd] & 0xFFFF));
- }
- private void DispatchFunc43()
- {
- uint rn, rd, offset;
- // STRH rd, [rn, immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
-
- this.memory.WriteU16(registers[rn] + offset, (ushort)(registers[rd] & 0xFFFF));
- }
- private void DispatchFunc44()
- {
- uint rn, rd, offset;
- // STRH rd, [rn, immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
-
- registers[rn] += offset;
- this.memory.WriteU16(registers[rn], (ushort)(registers[rd] & 0xFFFF));
- }
- private void DispatchFunc45()
- {
- uint rn, rd, address, offset;
- // LDRH rd, [rn], -rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = this.registers[this.curInstruction & 0xF];
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU16(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- }
- private void DispatchFunc46()
- {
- uint rn, rd, address, offset;
- // Writeback bit set, instruction is unpredictable
- // LDRH rd, [rn], -rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = this.registers[this.curInstruction & 0xF];
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU16(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- }
- private void DispatchFunc47()
- {
- uint rn, rd, address, offset;
- // LDRH rd, [rn], -immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU16(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- }
- private void DispatchFunc48()
- {
- uint rn, rd, address, offset;
- // Writeback bit set, instruction is unpredictable
- // LDRH rd, [rn], -rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU16(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- }
- private void DispatchFunc49()
- {
- uint rn, rd, address, offset;
- // LDRH rd, [rn], rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = this.registers[this.curInstruction & 0xF];
-
- registers[rd] = this.memory.ReadU16(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- }
- private void DispatchFunc50()
- {
- uint rn, rd, address, offset;
- // Writeback bit set, instruction is unpredictable
- // LDRH rd, [rn], rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = this.registers[this.curInstruction & 0xF];
-
- registers[rd] = this.memory.ReadU16(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- }
- private void DispatchFunc51()
- {
- uint rn, rd, address, offset;
- // LDRH rd, [rn], immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
-
- registers[rd] = this.memory.ReadU16(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- }
- private void DispatchFunc52()
- {
- uint rn, rd, address, offset;
- // Writeback bit set, instruction is unpredictable
- // LDRH rd, [rn], rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
-
- registers[rd] = this.memory.ReadU16(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- }
- private void DispatchFunc53()
- {
- uint rn, rd, offset;
- // LDRH rd, [rn, -rm]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.registers[this.curInstruction & 0xF];
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU16(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc54()
- {
- uint rn, rd, offset;
- // LDRH rd, [rn, -rm]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.registers[this.curInstruction & 0xF];
- offset = (uint)-offset;
-
- registers[rn] += offset;
-
- registers[rd] = this.memory.ReadU16(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc55()
- {
- uint rn, rd, offset;
- // LDRH rd, [rn, -immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU16(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc56()
- {
- uint rn, rd, offset;
- // LDRH rd, [rn, -rm]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
- offset = (uint)-offset;
-
- registers[rn] += offset;
- registers[rd] = this.memory.ReadU16(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc57()
- {
- uint rn, rd, offset;
- // LDRH rd, [rn, rm]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.registers[this.curInstruction & 0xF];
-
- registers[rd] = this.memory.ReadU16(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc58()
- {
- uint rn, rd, offset;
- // LDRH rd, [rn, rm]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.registers[this.curInstruction & 0xF];
-
- registers[rn] += offset;
- registers[rd] = this.memory.ReadU16(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc59()
- {
- uint rn, rd, offset;
- // LDRH rd, [rn, immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
-
- registers[rd] = this.memory.ReadU16(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc60()
- {
- uint rn, rd, offset;
- // LDRH rd, [rn, rm]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
-
- registers[rn] += offset;
- registers[rd] = this.memory.ReadU16(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc61()
- {
- uint rn, rd, address, offset;
- // LDRSB rd, [rn], -rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = this.registers[this.curInstruction & 0xF];
- offset = (uint)-offset;
-
- registers[rd] = (uint)(sbyte)this.memory.ReadU8(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- }
- private void DispatchFunc62()
- {
- uint rn, rd, address, offset;
- // Writeback bit set, instruction is unpredictable
- // LDRSB rd, [rn], -rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = this.registers[this.curInstruction & 0xF];
- offset = (uint)-offset;
-
- registers[rd] = (uint)(sbyte)this.memory.ReadU8(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- }
- private void DispatchFunc63()
- {
- uint rn, rd, address, offset;
- // LDRSB rd, [rn], -immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
- offset = (uint)-offset;
-
- registers[rd] = (uint)(sbyte)this.memory.ReadU8(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- }
- private void DispatchFunc64()
- {
- uint rn, rd, address, offset;
- // Writeback bit set, instruction is unpredictable
- // LDRSB rd, [rn], -immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
- offset = (uint)-offset;
-
- registers[rd] = (uint)(sbyte)this.memory.ReadU8(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- }
- private void DispatchFunc65()
- {
- uint rn, rd, address, offset;
- // LDRSB rd, [rn], rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = this.registers[this.curInstruction & 0xF];
-
- registers[rd] = (uint)(sbyte)this.memory.ReadU8(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- }
- private void DispatchFunc66()
- {
- uint rn, rd, address, offset;
- // Writeback bit set, instruction is unpredictable
- // LDRSB rd, [rn], rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = this.registers[this.curInstruction & 0xF];
-
- registers[rd] = (uint)(sbyte)this.memory.ReadU8(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- }
- private void DispatchFunc67()
- {
- uint rn, rd, address, offset;
- // LDRSB rd, [rn], immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
-
- registers[rd] = (uint)(sbyte)this.memory.ReadU8(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- }
- private void DispatchFunc68()
- {
- uint rn, rd, address, offset;
- // Writeback bit set, instruction is unpredictable
- // LDRSB rd, [rn], immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
-
- registers[rd] = (uint)(sbyte)this.memory.ReadU8(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- }
- private void DispatchFunc69()
- {
- uint rn, rd, offset;
- // LDRSB rd, [rn, -rm]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.registers[this.curInstruction & 0xF];
- offset = (uint)-offset;
-
- registers[rd] = (uint)(sbyte)this.memory.ReadU8(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc70()
- {
- uint rn, rd, offset;
- // LDRSB rd, [rn, -rm]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.registers[this.curInstruction & 0xF];
- offset = (uint)-offset;
-
- registers[rn] += offset;
- registers[rd] = (uint)(sbyte)this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc71()
- {
- uint rn, rd, offset;
- // LDRSB rd, [rn, -immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
- offset = (uint)-offset;
-
- registers[rd] = (uint)(sbyte)this.memory.ReadU8(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc72()
- {
- uint rn, rd, offset;
- // LDRSB rd, [rn, -immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
- offset = (uint)-offset;
-
- registers[rn] += offset;
- registers[rd] = (uint)(sbyte)this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc73()
- {
- uint rn, rd, offset;
- // LDRSB rd, [rn, rm]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.registers[this.curInstruction & 0xF];
-
- registers[rd] = (uint)(sbyte)this.memory.ReadU8(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc74()
- {
- uint rn, rd, offset;
- // LDRSB rd, [rn, rm]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.registers[this.curInstruction & 0xF];
-
- registers[rd] = (uint)(sbyte)this.memory.ReadU8(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc75()
- {
- uint rn, rd, offset;
- // LDRSB rd, [rn, immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
-
- registers[rd] = (uint)(sbyte)this.memory.ReadU8(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc76()
- {
- uint rn, rd, offset;
- // LDRSB rd, [rn, immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
-
- registers[rn] += offset;
- registers[rd] = (uint)(sbyte)this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc77()
- {
- uint rn, rd, address, offset;
- // LDRSH rd, [rn], -rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = this.registers[this.curInstruction & 0xF];
- offset = (uint)-offset;
-
- registers[rd] = (uint)(short)this.memory.ReadU16(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- }
- private void DispatchFunc78()
- {
- uint rn, rd, address, offset;
- // Writeback bit set, instruction is unpredictable
- // LDRSH rd, [rn], -rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = this.registers[this.curInstruction & 0xF];
- offset = (uint)-offset;
-
- registers[rd] = (uint)(short)this.memory.ReadU16(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- }
- private void DispatchFunc79()
- {
- uint rn, rd, address, offset;
- // LDRSH rd, [rn], -immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
- offset = (uint)-offset;
-
- registers[rd] = (uint)(short)this.memory.ReadU16(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- }
- private void DispatchFunc80()
- {
- uint rn, rd, address, offset;
- // Writeback bit set, instruction is unpredictable
- // LDRSH rd, [rn], -immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
- offset = (uint)-offset;
-
- registers[rd] = (uint)(short)this.memory.ReadU16(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- }
- private void DispatchFunc81()
- {
- uint rn, rd, address, offset;
- // LDRSH rd, [rn], rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = this.registers[this.curInstruction & 0xF];
-
- registers[rd] = (uint)(short)this.memory.ReadU16(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- }
- private void DispatchFunc82()
- {
- uint rn, rd, address, offset;
- // Writeback bit set, instruction is unpredictable
- // LDRSH rd, [rn], rm
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = this.registers[this.curInstruction & 0xF];
-
- registers[rd] = (uint)(short)this.memory.ReadU16(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- }
- private void DispatchFunc83()
- {
- uint rn, rd, address, offset;
- // LDRSH rd, [rn], immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
-
- registers[rd] = (uint)(short)this.memory.ReadU16(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- }
- private void DispatchFunc84()
- {
- uint rn, rd, address, offset;
- // Writeback bit set, instruction is unpredictable
- // LDRSH rd, [rn], immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- address = registers[rn];
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
-
- registers[rd] = (uint)(short)this.memory.ReadU16(address);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] = address + offset;
- }
- private void DispatchFunc85()
- {
- uint rn, rd, offset;
- // LDRSH rd, [rn, -rm]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.registers[this.curInstruction & 0xF];
- offset = (uint)-offset;
-
- registers[rd] = (uint)(short)this.memory.ReadU16(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc86()
- {
- uint rn, rd, offset;
- // LDRSH rd, [rn, -rm]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.registers[this.curInstruction & 0xF];
- offset = (uint)-offset;
-
- registers[rn] += offset;
- registers[rd] = (uint)(short)this.memory.ReadU16(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc87()
- {
- uint rn, rd, offset;
- // LDRSH rd, [rn, -immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
- offset = (uint)-offset;
-
- registers[rd] = (uint)(short)this.memory.ReadU16(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc88()
- {
- uint rn, rd, offset;
- // LDRSH rd, [rn, -immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
- offset = (uint)-offset;
-
- registers[rn] += offset;
- registers[rd] = (uint)(short)this.memory.ReadU16(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc89()
- {
- uint rn, rd, offset;
- // LDRSH rd, [rn, rm]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.registers[this.curInstruction & 0xF];
-
- registers[rd] = (uint)(short)this.memory.ReadU16(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc90()
- {
- uint rn, rd, offset;
- // LDRSH rd, [rn, rm]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.registers[this.curInstruction & 0xF];
-
- registers[rn] += offset;
- registers[rd] = (uint)(short)this.memory.ReadU16(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc91()
- {
- uint rn, rd, offset;
- // LDRSH rd, [rn, immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
-
- registers[rd] = (uint)(short)this.memory.ReadU16(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc92()
- {
- uint rn, rd, offset;
- // LDRSH rd, [rn, immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = ((this.curInstruction & 0xF00) >> 4) | (this.curInstruction & 0xF);
-
- registers[rn] += offset;
- registers[rd] = (uint)(short)this.memory.ReadU16(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc93()
- {
- uint rn, rd;
- // EOR rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn ^ BarrelShifterLslImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc94()
- {
- uint rn, rd;
- // EOR rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn ^ BarrelShifterLslReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc95()
- {
- uint rn, rd;
- // EOR rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn ^ BarrelShifterLsrImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc96()
- {
- uint rn, rd;
- // EOR rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn ^ BarrelShifterLsrReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc97()
- {
- uint rn, rd;
- // EOR rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn ^ BarrelShifterAsrImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc98()
- {
- uint rn, rd;
- // EOR rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn ^ BarrelShifterAsrReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc99()
- {
- uint rn, rd;
- // EOR rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn ^ BarrelShifterRorImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc100()
- {
- uint rn, rd;
- // EOR rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn ^ BarrelShifterRorReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc101()
- {
- uint rn, rd;
- // EORS rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn ^ BarrelShifterLslImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc102()
- {
- uint rn, rd;
- // EORS rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn ^ BarrelShifterLslReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc103()
- {
- uint rn, rd;
- // EORS rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn ^ BarrelShifterLsrImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc104()
- {
- uint rn, rd;
- // EORS rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn ^ BarrelShifterLsrReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc105()
- {
- uint rn, rd;
- // EORS rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn ^ BarrelShifterAsrImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc106()
- {
- uint rn, rd;
- // EORS rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn ^ BarrelShifterAsrReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc107()
- {
- uint rn, rd;
- // EORS rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn ^ BarrelShifterRorImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc108()
- {
- uint rn, rd;
- // EORS rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn ^ BarrelShifterRorReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc109()
- {
- uint rn, rd;
- // SUB rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn - BarrelShifterLslImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc110()
- {
- uint rn, rd;
- // SUB rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn - BarrelShifterLslReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc111()
- {
- uint rn, rd;
- // SUB rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn - BarrelShifterLsrImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc112()
- {
- uint rn, rd;
- // SUB rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn - BarrelShifterLsrReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc113()
- {
- uint rn, rd;
- // SUB rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn - BarrelShifterAsrImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc114()
- {
- uint rn, rd;
- // SUB rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn - BarrelShifterAsrReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc115()
- {
- uint rn, rd;
- // SUB rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn - BarrelShifterRorImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc116()
- {
- uint rn, rd;
- // SUB rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn - BarrelShifterRorReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc117()
- {
- uint rn, rd, shifterOperand;
- // SUBS rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLslImmed();
- registers[rd] = rn - shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc118()
- {
- uint rn, rd, shifterOperand;
- // SUBS rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLslReg();
- registers[rd] = rn - shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc119()
- {
- uint rn, rd, shifterOperand;
- // SUBS rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLsrImmed();
- registers[rd] = rn - shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc120()
- {
- uint rn, rd, shifterOperand;
- // SUBS rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLsrReg();
- registers[rd] = rn - shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc121()
- {
- uint rn, rd, shifterOperand;
- // SUBS rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterAsrImmed();
- registers[rd] = rn - shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc122()
- {
- uint rn, rd, shifterOperand;
- // SUBS rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterAsrReg();
- registers[rd] = rn - shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc123()
- {
- uint rn, rd, shifterOperand;
- // SUBS rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterRorImmed();
- registers[rd] = rn - shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc124()
- {
- uint rn, rd, shifterOperand;
- // SUBS rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterRorReg();
- registers[rd] = rn - shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc125()
- {
- uint rn, rd;
- // RSB rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterLslImmed() - rn;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc126()
- {
- uint rn, rd;
- // RSB rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterLslReg() - rn;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc127()
- {
- uint rn, rd;
- // RSB rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterLsrImmed() - rn;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc128()
- {
- uint rn, rd;
- // RSB rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterLsrReg() - rn;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc129()
- {
- uint rn, rd;
- // RSB rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterAsrImmed() - rn;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc130()
- {
- uint rn, rd;
- // RSB rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterAsrReg() - rn;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc131()
- {
- uint rn, rd;
- // RSB rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterRorImmed() - rn;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc132()
- {
- uint rn, rd;
- // RSB rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterRorReg() - rn;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc133()
- {
- uint rn, rd, shifterOperand;
- // RSBS rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLslImmed();
- registers[rd] = shifterOperand - rn;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc134()
- {
- uint rn, rd, shifterOperand;
- // RSBS rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLslReg();
- registers[rd] = shifterOperand - rn;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc135()
- {
- uint rn, rd, shifterOperand;
- // RSBS rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLsrImmed();
- registers[rd] = shifterOperand - rn;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc136()
- {
- uint rn, rd, shifterOperand;
- // RSBS rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLsrReg();
- registers[rd] = shifterOperand - rn;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc137()
- {
- uint rn, rd, shifterOperand;
- // RSBS rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterAsrImmed();
- registers[rd] = shifterOperand - rn;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc138()
- {
- uint rn, rd, shifterOperand;
- // RSBS rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterAsrReg();
- registers[rd] = shifterOperand - rn;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc139()
- {
- uint rn, rd, shifterOperand;
- // RSBS rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterRorImmed();
- registers[rd] = shifterOperand - rn;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc140()
- {
- uint rn, rd, shifterOperand;
- // RSBS rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterRorReg();
- registers[rd] = shifterOperand - rn;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc141()
- {
- uint rn, rd;
- // ADD rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn + BarrelShifterLslImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc142()
- {
- uint rn, rd;
- // ADD rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn + BarrelShifterLslReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc143()
- {
- uint rn, rd;
- // ADD rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn + BarrelShifterLsrImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc144()
- {
- uint rn, rd;
- // ADD rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn + BarrelShifterLsrReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc145()
- {
- uint rn, rd;
- // ADD rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn + BarrelShifterAsrImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc146()
- {
- uint rn, rd;
- // ADD rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn + BarrelShifterAsrReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc147()
- {
- uint rn, rd;
- // ADD rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn + BarrelShifterRorImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc148()
- {
- uint rn, rd;
- // ADD rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn + BarrelShifterRorReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc149()
- {
- uint rn, rd, shifterOperand;
- // ADDS rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLslImmed();
- registers[rd] = rn + shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc150()
- {
- uint rn, rd, shifterOperand;
- // ADDS rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLslReg();
- registers[rd] = rn + shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc151()
- {
- uint rn, rd, shifterOperand;
- // ADDS rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLsrImmed();
- registers[rd] = rn + shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc152()
- {
- uint rn, rd, shifterOperand;
- // ADDS rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLsrReg();
- registers[rd] = rn + shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc153()
- {
- uint rn, rd, shifterOperand;
- // ADDS rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterAsrImmed();
- registers[rd] = rn + shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc154()
- {
- uint rn, rd, shifterOperand;
- // ADDS rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterAsrReg();
- registers[rd] = rn + shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc155()
- {
- uint rn, rd, shifterOperand;
- // ADDS rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterRorImmed();
- registers[rd] = rn + shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc156()
- {
- uint rn, rd, shifterOperand;
- // ADDS rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterRorReg();
- registers[rd] = rn + shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc157()
- {
- uint rn, rd;
- // ADC rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn + BarrelShifterLslImmed() + carry;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc158()
- {
- uint rn, rd;
- // ADC rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn + BarrelShifterLslReg() + carry;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc159()
- {
- uint rn, rd;
- // ADC rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn + BarrelShifterLsrImmed() + carry;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc160()
- {
- uint rn, rd;
- // ADC rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn + BarrelShifterLsrReg() + carry;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc161()
- {
- uint rn, rd;
- // ADC rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn + BarrelShifterAsrImmed() + carry;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc162()
- {
- uint rn, rd;
- // ADC rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn + BarrelShifterAsrReg() + carry;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc163()
- {
- uint rn, rd;
- // ADC rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn + BarrelShifterRorImmed() + carry;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc164()
- {
- uint rn, rd;
- // ADC rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn + BarrelShifterRorReg() + carry;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc165()
- {
- uint rn, rd, shifterOperand;
- // ADCS rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLslImmed();
- registers[rd] = rn + shifterOperand + carry;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc166()
- {
- uint rn, rd, shifterOperand;
- // ADCS rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLslReg();
- registers[rd] = rn + shifterOperand + carry;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc167()
- {
- uint rn, rd, shifterOperand;
- // ADCS rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLsrImmed();
- registers[rd] = rn + shifterOperand + carry;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc168()
- {
- uint rn, rd, shifterOperand;
- // ADCS rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLsrReg();
- registers[rd] = rn + shifterOperand + carry;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc169()
- {
- uint rn, rd, shifterOperand;
- // ADCS rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterAsrImmed();
- registers[rd] = rn + shifterOperand + carry;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc170()
- {
- uint rn, rd, shifterOperand;
- // ADCS rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterAsrReg();
- registers[rd] = rn + shifterOperand + carry;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc171()
- {
- uint rn, rd, shifterOperand;
- // ADCS rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterRorImmed();
- registers[rd] = rn + shifterOperand + carry;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc172()
- {
- uint rn, rd, shifterOperand;
- // ADCS rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterRorReg();
- registers[rd] = rn + shifterOperand + carry;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc173()
- {
- uint rn, rd;
- // SBC rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn - BarrelShifterLslImmed() - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc174()
- {
- uint rn, rd;
- // SBC rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn - BarrelShifterLslReg() - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc175()
- {
- uint rn, rd;
- // SBC rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn - BarrelShifterLsrImmed() - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc176()
- {
- uint rn, rd;
- // SBC rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn - BarrelShifterLsrReg() - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc177()
- {
- uint rn, rd;
- // SBC rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn - BarrelShifterAsrImmed() - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc178()
- {
- uint rn, rd;
- // SBC rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn - BarrelShifterAsrReg() - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc179()
- {
- uint rn, rd;
- // SBC rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn - BarrelShifterRorImmed() - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc180()
- {
- uint rn, rd;
- // SBC rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn - BarrelShifterRorReg() - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc181()
- {
- uint rn, rd, shifterOperand;
- // SBCS rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLslImmed();
- registers[rd] = rn - shifterOperand - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc182()
- {
- uint rn, rd, shifterOperand;
- // SBCS rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLslReg();
- registers[rd] = rn - shifterOperand - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc183()
- {
- uint rn, rd, shifterOperand;
- // SBCS rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLsrImmed();
- registers[rd] = rn - shifterOperand - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc184()
- {
- uint rn, rd, shifterOperand;
- // SBCS rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLsrReg();
- registers[rd] = rn - shifterOperand - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc185()
- {
- uint rn, rd, shifterOperand;
- // SBCS rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterAsrImmed();
- registers[rd] = rn - shifterOperand - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc186()
- {
- uint rn, rd, shifterOperand;
- // SBCS rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterAsrReg();
- registers[rd] = rn - shifterOperand - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc187()
- {
- uint rn, rd, shifterOperand;
- // SBCS rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterRorImmed();
- registers[rd] = rn - shifterOperand - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc188()
- {
- uint rn, rd, shifterOperand;
- // SBCS rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterRorReg();
- registers[rd] = rn - shifterOperand - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc189()
- {
- uint rn, rd;
- // RSC rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterLslImmed() - rn - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc190()
- {
- uint rn, rd;
- // RSC rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterLslReg() - rn - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc191()
- {
- uint rn, rd;
- // RSC rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterLsrImmed() - rn - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc192()
- {
- uint rn, rd;
- // RSC rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterLsrReg() - rn - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc193()
- {
- uint rn, rd;
- // RSC rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterAsrImmed() - rn - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc194()
- {
- uint rn, rd;
- // RSC rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterAsrReg() - rn - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc195()
- {
- uint rn, rd;
- // RSC rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterRorImmed() - rn - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc196()
- {
- uint rn, rd;
- // RSC rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterRorReg() - rn - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc197()
- {
- uint rn, rd, shifterOperand;
- // RSCS rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLslImmed();
- registers[rd] = shifterOperand - rn - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc198()
- {
- uint rn, rd, shifterOperand;
- // RSCS rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLslReg();
- registers[rd] = shifterOperand - rn - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc199()
- {
- uint rn, rd, shifterOperand;
- // RSCS rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLsrImmed();
- registers[rd] = shifterOperand - rn - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc200()
- {
- uint rn, rd, shifterOperand;
- // RSCS rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterLsrReg();
- registers[rd] = shifterOperand - rn - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc201()
- {
- uint rn, rd, shifterOperand;
- // RSCS rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterAsrImmed();
- registers[rd] = shifterOperand - rn - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc202()
- {
- uint rn, rd, shifterOperand;
- // RSCS rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterAsrReg();
- registers[rd] = shifterOperand - rn - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc203()
- {
- uint rn, rd, shifterOperand;
- // RSCS rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterRorImmed();
- registers[rd] = shifterOperand - rn - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc204()
- {
- uint rn, rd, shifterOperand;
- // RSCS rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- shifterOperand = BarrelShifterRorReg();
- registers[rd] = shifterOperand - rn - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc205()
- {
- uint rn, rd, rm;
- // SWP rd, rm, [rn]
- {
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
- rm = this.curInstruction & 0xF;
- uint tmp = this.memory.ReadU32(registers[rn]);
- this.memory.WriteU32(registers[rn], registers[rm]);
- registers[rd] = tmp;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- }
- private void DispatchFunc206()
- {
- uint rn, rd, rm;
- // SWPB rd, rm, [rn]
- {
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
- rm = this.curInstruction & 0xF;
-
- byte tmp = this.memory.ReadU8(registers[rn]);
- this.memory.WriteU8(registers[rn], (byte)(registers[rm] & 0xFF));
- registers[rd] = tmp;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- }
- private void DispatchFunc207()
- {
- uint rd;
- // MRS rd, cpsr
- rd = (this.curInstruction >> 12) & 0xF;
- this.PackFlags();
- registers[rd] = this.parent.CPSR;
- }
- private void DispatchFunc208()
- {
- uint rd;
- // MRS rd, spsr
- rd = (this.curInstruction >> 12) & 0xF;
- if (this.parent.SPSRExists) registers[rd] = this.parent.SPSR;
- }
- private void DispatchFunc209()
- {
- uint rm;
- // MSR cpsr, rm
- {
- rm = registers[this.curInstruction & 0xF];
- bool userMode = (this.parent.CPSR & 0x1F) == Arm7Processor.USR;
-
- this.PackFlags();
-
- uint tmpCPSR = this.parent.CPSR;
-
- if ((this.curInstruction & (1 << 16)) == 1 << 16 && !userMode)
- {
- tmpCPSR &= 0xFFFFFF00;
- tmpCPSR |= rm & 0x000000FF;
- }
- if ((this.curInstruction & (1 << 17)) == 1 << 17 && !userMode)
- {
- tmpCPSR &= 0xFFFF00FF;
- tmpCPSR |= rm & 0x0000FF00;
- }
- if ((this.curInstruction & (1 << 18)) == 1 << 18 && !userMode)
- {
- tmpCPSR &= 0xFF00FFFF;
- tmpCPSR |= rm & 0x00FF0000;
- }
- if ((this.curInstruction & (1 << 19)) == 1 << 19)
- {
- tmpCPSR &= 0x00FFFFFF;
- tmpCPSR |= rm & 0xFF000000;
- }
-
- this.parent.WriteCpsr(tmpCPSR);
-
- this.UnpackFlags();
-
- // Check for branch back to Thumb Mode
- if ((this.parent.CPSR & Arm7Processor.T_MASK) == Arm7Processor.T_MASK)
- {
- this.thumbMode = true;
- return;
- }
- }
- }
- private void DispatchFunc210()
- {
- uint rm;
- // MSR spsr, rm
- if (this.parent.SPSRExists)
- {
- rm = registers[this.curInstruction & 0xF];
- if ((this.curInstruction & (1 << 16)) == 1 << 16)
- {
- this.parent.SPSR &= 0xFFFFFF00;
- this.parent.SPSR |= rm & 0x000000FF;
- }
- if ((this.curInstruction & (1 << 17)) == 1 << 17)
- {
- this.parent.SPSR &= 0xFFFF00FF;
- this.parent.SPSR |= rm & 0x0000FF00;
- }
- if ((this.curInstruction & (1 << 18)) == 1 << 18)
- {
- this.parent.SPSR &= 0xFF00FFFF;
- this.parent.SPSR |= rm & 0x00FF0000;
- }
- if ((this.curInstruction & (1 << 19)) == 1 << 19)
- {
- this.parent.SPSR &= 0x00FFFFFF;
- this.parent.SPSR |= rm & 0xFF000000;
- }
- }
- }
- private void DispatchFunc211()
- {
- // MSR cpsr, immed
- {
- uint immed = this.curInstruction & 0xFF;
- int rotateAmount = (int)(((this.curInstruction >> 8) & 0xF) * 2);
-
- immed = (immed >> rotateAmount) | (immed << (32 - rotateAmount));
-
- bool userMode = (this.parent.CPSR & 0x1F) == Arm7Processor.USR;
-
- this.PackFlags();
-
- uint tmpCPSR = this.parent.CPSR;
-
- if ((this.curInstruction & (1 << 16)) == 1 << 16 && !userMode)
- {
- tmpCPSR &= 0xFFFFFF00;
- tmpCPSR |= immed & 0x000000FF;
- }
- if ((this.curInstruction & (1 << 17)) == 1 << 17 && !userMode)
- {
- tmpCPSR &= 0xFFFF00FF;
- tmpCPSR |= immed & 0x0000FF00;
- }
- if ((this.curInstruction & (1 << 18)) == 1 << 18 && !userMode)
- {
- tmpCPSR &= 0xFF00FFFF;
- tmpCPSR |= immed & 0x00FF0000;
- }
- if ((this.curInstruction & (1 << 19)) == 1 << 19)
- {
- tmpCPSR &= 0x00FFFFFF;
- tmpCPSR |= immed & 0xFF000000;
- }
-
- this.parent.WriteCpsr(tmpCPSR);
-
- this.UnpackFlags();
-
- // Check for branch back to Thumb Mode
- if ((this.parent.CPSR & Arm7Processor.T_MASK) == Arm7Processor.T_MASK)
- {
- this.thumbMode = true;
- return;
- }
- }
- }
- private void DispatchFunc212()
- {
- // MSR spsr, immed
- if (this.parent.SPSRExists)
- {
- uint immed = this.curInstruction & 0xFF;
- int rotateAmount = (int)(((this.curInstruction >> 8) & 0xF) * 2);
-
- immed = (immed >> rotateAmount) | (immed << (32 - rotateAmount));
-
- if ((this.curInstruction & (1 << 16)) == 1 << 16)
- {
- this.parent.SPSR &= 0xFFFFFF00;
- this.parent.SPSR |= immed & 0x000000FF;
- }
- if ((this.curInstruction & (1 << 17)) == 1 << 17)
- {
- this.parent.SPSR &= 0xFFFF00FF;
- this.parent.SPSR |= immed & 0x0000FF00;
- }
- if ((this.curInstruction & (1 << 18)) == 1 << 18)
- {
- this.parent.SPSR &= 0xFF00FFFF;
- this.parent.SPSR |= immed & 0x00FF0000;
- }
- if ((this.curInstruction & (1 << 19)) == 1 << 19)
- {
- this.parent.SPSR &= 0x00FFFFFF;
- this.parent.SPSR |= immed & 0xFF000000;
- }
- }
- }
- private void DispatchFunc213()
- {
- uint rm;
- // BX rm
- rm = this.curInstruction & 0xf;
-
- this.PackFlags();
-
- this.parent.CPSR &= ~Arm7Processor.T_MASK;
- this.parent.CPSR |= (registers[rm] & 1) << Arm7Processor.T_BIT;
-
- registers[15] = registers[rm] & (~1U);
-
- this.UnpackFlags();
-
- // Check for branch back to Thumb Mode
- if ((this.parent.CPSR & Arm7Processor.T_MASK) == Arm7Processor.T_MASK)
- {
- this.thumbMode = true;
- return;
- }
-
- this.FlushQueue();
- }
- private void DispatchFunc214()
- {
- uint rn, alu;
- // TSTS rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- alu = rn & BarrelShifterLslImmed();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- }
- private void DispatchFunc215()
- {
- uint rn, alu;
- // TSTS rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- alu = rn & BarrelShifterLslReg();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- }
- private void DispatchFunc216()
- {
- uint rn, alu;
- // TSTS rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- alu = rn & BarrelShifterLsrImmed();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- }
- private void DispatchFunc217()
- {
- uint rn, alu;
- // TSTS rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- alu = rn & BarrelShifterLsrReg();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- }
- private void DispatchFunc218()
- {
- uint rn, alu;
- // TSTS rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- alu = rn & BarrelShifterAsrImmed();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- }
- private void DispatchFunc219()
- {
- uint rn, alu;
- // TSTS rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- alu = rn & BarrelShifterAsrReg();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- }
- private void DispatchFunc220()
- {
- uint rn, alu;
- // TSTS rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- alu = rn & BarrelShifterRorImmed();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- }
- private void DispatchFunc221()
- {
- uint rn, rd, alu;
- // TSTS rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = rn & BarrelShifterRorReg();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- }
- private void DispatchFunc222()
- {
- uint rn, alu;
- // TEQS rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- alu = rn ^ BarrelShifterLslImmed();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- }
- private void DispatchFunc223()
- {
- uint rn, alu;
- // TEQS rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- alu = rn ^ BarrelShifterLslReg();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- }
- private void DispatchFunc224()
- {
- uint rn, alu;
- // TEQS rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- alu = rn ^ BarrelShifterLsrImmed();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- }
- private void DispatchFunc225()
- {
- uint rn, alu;
- // TEQS rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- alu = rn ^ BarrelShifterLsrReg();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- }
- private void DispatchFunc226()
- {
- uint rn, alu;
- // TEQS rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- alu = rn ^ BarrelShifterAsrImmed();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- }
- private void DispatchFunc227()
- {
- uint rn, alu;
- // TEQS rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- alu = rn ^ BarrelShifterAsrReg();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- }
- private void DispatchFunc228()
- {
- uint rn, alu;
- // TEQS rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- alu = rn ^ BarrelShifterRorImmed();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- }
- private void DispatchFunc229()
- {
- uint rn, rd, alu;
- // TEQS rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = rn ^ BarrelShifterRorReg();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- }
- private void DispatchFunc230()
- {
- uint rn, shifterOperand, alu;
- // CMP rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterLslImmed();
- alu = rn - shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, alu);
- }
- private void DispatchFunc231()
- {
- uint rn, shifterOperand, alu;
- // CMP rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterLslReg();
- alu = rn - shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, alu);
- }
- private void DispatchFunc232()
- {
- uint rn, shifterOperand, alu;
- // CMP rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterLsrImmed();
- alu = rn - shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, alu);
- }
- private void DispatchFunc233()
- {
- uint rn, shifterOperand, alu;
- // CMP rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterLsrReg();
- alu = rn - shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, alu);
- }
- private void DispatchFunc234()
- {
- uint rn, shifterOperand, alu;
- // CMP rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterAsrImmed();
- alu = rn - shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, alu);
- }
- private void DispatchFunc235()
- {
- uint rn, shifterOperand, alu;
- // CMP rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterAsrReg();
- alu = rn - shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, alu);
- }
- private void DispatchFunc236()
- {
- uint rn, shifterOperand, alu;
- // CMP rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterRorImmed();
- alu = rn - shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, alu);
- }
- private void DispatchFunc237()
- {
- uint rn, shifterOperand, alu;
- // CMP rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterRorReg();
- alu = rn - shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, alu);
- }
- private void DispatchFunc238()
- {
- uint rn, shifterOperand, alu;
- // CMN rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterLslImmed();
- alu = rn + shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, alu);
- }
- private void DispatchFunc239()
- {
- uint rn, shifterOperand, alu;
- // CMN rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterLslReg();
- alu = rn + shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, alu);
- }
- private void DispatchFunc240()
- {
- uint rn, shifterOperand, alu;
- // CMN rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterLsrImmed();
- alu = rn + shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, alu);
- }
- private void DispatchFunc241()
- {
- uint rn, shifterOperand, alu;
- // CMN rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterLsrReg();
- alu = rn + shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, alu);
- }
- private void DispatchFunc242()
- {
- uint rn, shifterOperand, alu;
- // CMN rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterAsrImmed();
- alu = rn + shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, alu);
- }
- private void DispatchFunc243()
- {
- uint rn, shifterOperand, alu;
- // CMN rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterAsrReg();
- alu = rn + shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, alu);
- }
- private void DispatchFunc244()
- {
- uint rn, shifterOperand, alu;
- // CMN rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterRorImmed();
- alu = rn + shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, alu);
- }
- private void DispatchFunc245()
- {
- uint rn, shifterOperand, alu;
- // CMN rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterRorReg();
- alu = rn + shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, alu);
- }
- private void DispatchFunc246()
- {
- uint rn, rd;
- // ORR rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn | BarrelShifterLslImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc247()
- {
- uint rn, rd;
- // ORR rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn | BarrelShifterLslReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc248()
- {
- uint rn, rd;
- // ORR rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn | BarrelShifterLsrImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc249()
- {
- uint rn, rd;
- // ORR rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn | BarrelShifterLsrReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc250()
- {
- uint rn, rd;
- // ORR rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn | BarrelShifterAsrImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc251()
- {
- uint rn, rd;
- // ORR rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn | BarrelShifterAsrReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc252()
- {
- uint rn, rd;
- // ORR rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn | BarrelShifterRorImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc253()
- {
- uint rn, rd;
- // ORR rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn | BarrelShifterRorReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc254()
- {
- uint rn, rd;
- // ORRS rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn | BarrelShifterLslImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc255()
- {
- uint rn, rd;
- // ORRS rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn | BarrelShifterLslReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc256()
- {
- uint rn, rd;
- // ORRS rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn | BarrelShifterLsrImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc257()
- {
- uint rn, rd;
- // ORRS rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn | BarrelShifterLsrReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc258()
- {
- uint rn, rd;
- // ORRS rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn | BarrelShifterAsrImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc259()
- {
- uint rn, rd;
- // ORRS rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn | BarrelShifterAsrReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc260()
- {
- uint rn, rd;
- // ORRS rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn | BarrelShifterRorImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc261()
- {
- uint rn, rd;
- // ORRS rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn | BarrelShifterRorReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc262()
- {
- uint rd;
- // MOV rd, rm lsl immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterLslImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc263()
- {
- uint rd;
- // MOV rd, rm lsl rs
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterLslReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc264()
- {
- uint rd;
- // MOV rd, rm lsr immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterLsrImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc265()
- {
- uint rd;
- // MOV rd, rm lsr rs
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterLsrReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc266()
- {
- uint rd;
- // MOV rd, rm asr immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterAsrImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc267()
- {
- uint rd;
- // MOV rd, rm asr rs
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterAsrReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc268()
- {
- uint rd;
- // MOV rd, rm ror immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterRorImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc269()
- {
- uint rd;
- // MOV rd, rm ror rs
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterRorReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc270()
- {
- uint rd;
- // MOVS rd, rm lsl immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterLslImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc271()
- {
- uint rd;
- // MOVS rd, rm lsl rs
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterLslReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc272()
- {
- uint rd;
- // MOVS rd, rm lsr immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterLsrImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc273()
- {
- uint rd;
- // MOVS rd, rn, rm lsr rs
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterLsrReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc274()
- {
- uint rd;
- // MOVS rd, rn, rm asr immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterAsrImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc275()
- {
- uint rd;
- // MOVS rd, rn, rm asr rs
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterAsrReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc276()
- {
- uint rd;
- // MOVS rd, rn, rm ror immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterRorImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc277()
- {
- uint rd;
- // MOVS rd, rn, rm ror rs
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterRorReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc278()
- {
- uint rn, rd;
- // BIC rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & ~BarrelShifterLslImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc279()
- {
- uint rn, rd;
- // BIC rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & ~BarrelShifterLslReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc280()
- {
- uint rn, rd;
- // BIC rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & ~BarrelShifterLsrImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc281()
- {
- uint rn, rd;
- // BIC rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & ~BarrelShifterLsrReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc282()
- {
- uint rn, rd;
- // BIC rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & ~BarrelShifterAsrImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc283()
- {
- uint rn, rd;
- // BIC rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & ~BarrelShifterAsrReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc284()
- {
- uint rn, rd;
- // BIC rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & ~BarrelShifterRorImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc285()
- {
- uint rn, rd;
- // BIC rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & ~BarrelShifterRorReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc286()
- {
- uint rn, rd;
- // BICS rd, rn, rm lsl immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & ~BarrelShifterLslImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc287()
- {
- uint rn, rd;
- // BICS rd, rn, rm lsl rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & ~BarrelShifterLslReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc288()
- {
- uint rn, rd;
- // BICS rd, rn, rm lsr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & ~BarrelShifterLsrImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc289()
- {
- uint rn, rd;
- // BICS rd, rn, rm lsr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & ~BarrelShifterLsrReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc290()
- {
- uint rn, rd;
- // BICS rd, rn, rm asr immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & ~BarrelShifterAsrImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc291()
- {
- uint rn, rd;
- // BICS rd, rn, rm asr rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & ~BarrelShifterAsrReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc292()
- {
- uint rn, rd;
- // BICS rd, rn, rm ror immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & ~BarrelShifterRorImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc293()
- {
- uint rn, rd;
- // BICS rd, rn, rm ror rs
- rn = registers[(this.curInstruction >> 16) & 0xF];
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = rn & ~BarrelShifterRorReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc294()
- {
- uint rd;
- // MVN rd, rm lsl immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterLslImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc295()
- {
- uint rd;
- // MVN rd, rm lsl rs
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterLslReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc296()
- {
- uint rd;
- // MVN rd, rm lsr immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterLsrImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc297()
- {
- uint rd;
- // MVN rd, rm lsr rs
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterLsrReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc298()
- {
- uint rd;
- // MVN rd, rm asr immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterAsrImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc299()
- {
- uint rd;
- // MVN rd, rm asr rs
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterAsrReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc300()
- {
- uint rd;
- // MVN rd, rm ror immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterRorImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc301()
- {
- uint rd;
- // MVN rd, rm ror rs
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterRorReg();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc302()
- {
- uint rd;
- // MVNS rd, rm lsl immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterLslImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc303()
- {
- uint rd;
- // MVNS rd, rm lsl rs
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterLslReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc304()
- {
- uint rd;
- // MVNS rd, rm lsr immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterLsrImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc305()
- {
- uint rd;
- // MVNS rd, rn, rm lsr rs
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterLsrReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc306()
- {
- uint rd;
- // MVNS rd, rn, rm asr immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterAsrImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc307()
- {
- uint rd;
- // MVNS rd, rn, rm asr rs
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterAsrReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc308()
- {
- uint rd;
- // MVNS rd, rn, rm ror immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterRorImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc309()
- {
- uint rd;
- // MVNS rd, rn, rm ror rs
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterRorReg();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc310()
- {
- uint rn, rd;
- // AND rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- registers[rd] = rn & BarrelShifterImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc311()
- {
- uint rn, rd;
- // ANDS rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- registers[rd] = rn & BarrelShifterImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc312()
- {
- uint rn, rd;
- // EOR rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- registers[rd] = rn ^ BarrelShifterImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc313()
- {
- uint rn, rd;
- // EORS rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- registers[rd] = rn ^ BarrelShifterImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc314()
- {
- uint rn, rd;
- // SUB rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- registers[rd] = rn - BarrelShifterImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc315()
- {
- uint rn, rd, shifterOperand;
- // SUBS rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterImmed();
- registers[rd] = rn - shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc316()
- {
- uint rn, rd;
- // RSB rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- registers[rd] = BarrelShifterImmed() - rn;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc317()
- {
- uint rn, rd, shifterOperand;
- // RSBS rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterImmed();
- registers[rd] = shifterOperand - rn;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc318()
- {
- uint rn, rd;
- // ADD rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- registers[rd] = rn + BarrelShifterImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc319()
- {
- uint rn, rd, shifterOperand;
- // ADDS rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterImmed();
- registers[rd] = rn + shifterOperand;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc320()
- {
- uint rn, rd;
- // ADC rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- registers[rd] = rn + BarrelShifterImmed() + carry;
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc321()
- {
- uint rn, rd, shifterOperand;
- // ADCS rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterImmed();
- registers[rd] = rn + shifterOperand + carry;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc322()
- {
- uint rn, rd;
- // SBC rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- registers[rd] = rn - BarrelShifterImmed() - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc323()
- {
- uint rn, rd, shifterOperand;
- // SBCS rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterImmed();
- registers[rd] = rn - shifterOperand - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc324()
- {
- uint rn, rd;
- // RSC rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- registers[rd] = BarrelShifterImmed() - rn - (1U - carry);
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc325()
- {
- uint rn, rd, shifterOperand;
- // RSCS rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterImmed();
- registers[rd] = shifterOperand - rn - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(shifterOperand, rn, registers[rd]);
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc326()
- {
- uint rn, alu;
- // TSTS rn, immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- alu = rn & BarrelShifterImmed();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- }
- private void DispatchFunc327()
- {
- uint rn, alu;
- // TEQS rn, immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- alu = rn ^ BarrelShifterImmed();
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- carry = this.shifterCarry;
- }
- private void DispatchFunc328()
- {
- uint rn, shifterOperand, alu;
- // CMP rn, immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterImmed();
- alu = rn - shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarrySub(rn, shifterOperand, alu);
- }
- private void DispatchFunc329()
- {
- uint rn, shifterOperand, alu;
- // CMN rn, immed
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- shifterOperand = BarrelShifterImmed();
- alu = rn + shifterOperand;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarryAdd(rn, shifterOperand, alu);
- }
- private void DispatchFunc330()
- {
- uint rn, rd;
- // ORR rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- registers[rd] = rn | BarrelShifterImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc331()
- {
- uint rn, rd;
- // ORRS rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- registers[rd] = rn | BarrelShifterImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc332()
- {
- uint rd;
- // MOV rd, immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc333()
- {
- uint rd;
- // MOVS rd, immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = BarrelShifterImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc334()
- {
- uint rn, rd;
- // BIC rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- registers[rd] = rn & ~BarrelShifterImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc335()
- {
- uint rn, rd;
- // BICS rd, rn, immed
- rd = (this.curInstruction >> 12) & 0xF;
- rn = registers[(this.curInstruction >> 16) & 0xF];
-
- registers[rd] = rn & ~BarrelShifterImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc336()
- {
- uint rd;
- // MVN rd, immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterImmed();
-
- if (rd == 15)
- {
- this.FlushQueue();
- }
- }
- private void DispatchFunc337()
- {
- uint rd;
- // MVNS rd, immed
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = ~BarrelShifterImmed();
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- carry = this.shifterCarry;
-
- if (rd == 15)
- {
- this.DataProcessingWriteToR15();
- }
- }
- private void DispatchFunc338()
- {
- uint rn, rd, offset, alu;
- // STR rd, rn, -immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.curInstruction & 0xFFF;
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += offset;
- }
- private void DispatchFunc339()
- {
- uint rn, rd, offset, alu;
- // STRT rd, rn, -immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.curInstruction & 0xFFF;
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += offset;
- }
- private void DispatchFunc340()
- {
- uint rn, rd, offset, alu;
- // STRB rd, rn, -immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.curInstruction & 0xFFF;
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += offset;
- }
- private void DispatchFunc341()
- {
- uint rn, rd, offset, alu;
- // STRBT rd, rn, -immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.curInstruction & 0xFFF;
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += offset;
- }
- private void DispatchFunc342()
- {
- uint rn, rd, alu;
- // STR rd, rn, immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += this.curInstruction & 0xFFF;
- }
- private void DispatchFunc343()
- {
- uint rn, rd, alu;
- // STRT rd, rn, immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += this.curInstruction & 0xFFF;
- }
- private void DispatchFunc344()
- {
- uint rn, rd, alu;
- // STRB rd, rn, immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += this.curInstruction & 0xFFF;
- }
- private void DispatchFunc345()
- {
- uint rn, rd, alu;
- // STRBT rd, rn, immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += this.curInstruction & 0xFFF;
- }
- private void DispatchFunc346()
- {
- uint rn, rd, offset, alu;
- // STR rd, [rn, -immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.curInstruction & 0xFFF;
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn] + offset, alu);
- }
- private void DispatchFunc347()
- {
- uint rn, rd, offset, alu;
- // STR rd, [rn, -immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.curInstruction & 0xFFF;
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += offset;
- this.memory.WriteU32(registers[rn], alu);
- }
- private void DispatchFunc348()
- {
- uint rn, rd, offset, alu;
- // STRB rd, [rn, -immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.curInstruction & 0xFFF;
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn] + offset, (byte)(alu & 0xFF));
- }
- private void DispatchFunc349()
- {
- uint rn, rd, offset, alu;
- // STRB rd, [rn, -immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.curInstruction & 0xFFF;
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += offset;
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- }
- private void DispatchFunc350()
- {
- uint rn, rd, alu;
- // STR rd, [rn, immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn] + (this.curInstruction & 0xFFF), alu);
- }
- private void DispatchFunc351()
- {
- uint rn, rd, alu;
- // STRT rd, [rn, immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += this.curInstruction & 0xFFF;
- this.memory.WriteU32(registers[rn], alu);
- }
- private void DispatchFunc352()
- {
- uint rn, rd, alu;
- // STRB rd, [rn, immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn] + (this.curInstruction & 0xFFF), (byte)(alu & 0xFF));
- }
- private void DispatchFunc353()
- {
- uint rn, rd, alu;
- // STRB rd, [rn, immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += this.curInstruction & 0xFFF;
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- }
- private void DispatchFunc354()
- {
- uint rn, rd, offset;
- // LDR rd, rn, -immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.curInstruction & 0xFFF;
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc355()
- {
- uint rn, rd, offset;
- // LDRT rd, rn, -immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.curInstruction & 0xFFF;
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc356()
- {
- uint rn, rd, offset;
- // LDRB rd, rn, -immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.curInstruction & 0xFFF;
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc357()
- {
- uint rn, rd, offset;
- // LDRBT rd, rn, -immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.curInstruction & 0xFFF;
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc358()
- {
- uint rn, rd;
- // LDR rd, rn, immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += this.curInstruction & 0xFFF;
- }
- private void DispatchFunc359()
- {
- uint rn, rd;
- // LDRT rd, rn, immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += this.curInstruction & 0xFFF;
- }
- private void DispatchFunc360()
- {
- uint rn, rd;
- // LDRB rd, rn, immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += this.curInstruction & 0xFFF;
- }
- private void DispatchFunc361()
- {
- uint rn, rd;
- // LDRBT rd, rn, immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += this.curInstruction & 0xFFF;
- }
- private void DispatchFunc362()
- {
- uint rn, rd, offset;
- // LDR rd, [rn, -immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.curInstruction & 0xFFF;
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU32(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc363()
- {
- uint rn, rd, offset;
- // LDR rd, [rn, -immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.curInstruction & 0xFFF;
- offset = (uint)-offset;
-
- registers[rn] += offset;
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc364()
- {
- uint rn, rd, offset;
- // LDRB rd, [rn, -immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.curInstruction & 0xFFF;
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU8(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc365()
- {
- uint rn, rd, offset;
- // LDRB rd, [rn, -immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.curInstruction & 0xFFF;
- offset = (uint)-offset;
-
- registers[rn] += offset;
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc366()
- {
- uint rn, rd;
- // LDR rd, [rn, immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = this.memory.ReadU32(registers[rn] + (this.curInstruction & 0xFFF));
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc367()
- {
- uint rn, rd;
- // LDR rd, [rn, immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rn] += this.curInstruction & 0xFFF;
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc368()
- {
- uint rn, rd;
- // LDRB rd, [rn, immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = this.memory.ReadU8(registers[rn] + (this.curInstruction & 0xFFF));
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc369()
- {
- uint rn, rd;
- // LDRB rd, [rn, immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rn] += this.curInstruction & 0xFFF;
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc370()
- {
- uint rn, rd, offset, alu;
- // STR rd, rn, -rm lsl immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += offset;
- }
- private void DispatchFunc371()
- {
- uint rn, rd, offset, alu;
- // STR rd, rn, -rm lsr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += offset;
- }
- private void DispatchFunc372()
- {
- uint rn, rd, offset, alu;
- // STR rd, rn, -rm asr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += offset;
- }
- private void DispatchFunc373()
- {
- uint rn, rd, offset, alu;
- // STR rd, rn, -rm ror immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += offset;
- }
- private void DispatchFunc374()
- {
- uint rn, rd, offset, alu;
- // STRT rd, rn, -rm lsl immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += offset;
- }
- private void DispatchFunc375()
- {
- uint rn, rd, offset, alu;
- // STRT rd, rn, -rm lsr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += offset;
- }
- private void DispatchFunc376()
- {
- uint rn, rd, offset, alu;
- // STRT rd, rn, -rm asr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += offset;
- }
- private void DispatchFunc377()
- {
- uint rn, rd, offset, alu;
- // STRT rd, rn, -rm ror immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += offset;
- }
- private void DispatchFunc378()
- {
- uint rn, rd, offset, alu;
- // STRB rd, rn, -rm lsl immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += offset;
- }
- private void DispatchFunc379()
- {
- uint rn, rd, offset, alu;
- // STRB rd, rn, -rm lsr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += offset;
- }
- private void DispatchFunc380()
- {
- uint rn, rd, offset, alu;
- // STRB rd, rn, -rm asr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += offset;
- }
- private void DispatchFunc381()
- {
- uint rn, rd, offset, alu;
- // STRB rd, rn, -rm ror immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += offset;
- }
- private void DispatchFunc382()
- {
- uint rn, rd, offset, alu;
- // STRBT rd, rn, -rm lsl immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += offset;
- }
- private void DispatchFunc383()
- {
- uint rn, rd, offset, alu;
- // STRBT rd, rn, -rm lsr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += offset;
- }
- private void DispatchFunc384()
- {
- uint rn, rd, offset, alu;
- // STRBT rd, rn, -rm asr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += offset;
- }
- private void DispatchFunc385()
- {
- uint rn, rd, offset, alu;
- // STRBT rd, rn, -rm ror immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += offset;
- }
- private void DispatchFunc386()
- {
- uint rn, rd, alu;
- // STR rd, rn, rm lsl immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += this.BarrelShifterLslImmed();
- }
- private void DispatchFunc387()
- {
- uint rn, rd, alu;
- // STR rd, rn, rm lsr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += this.BarrelShifterLsrImmed();
- }
- private void DispatchFunc388()
- {
- uint rn, rd, alu;
- // STR rd, rn, rm asr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += this.BarrelShifterAsrImmed();
- }
- private void DispatchFunc389()
- {
- uint rn, rd, alu;
- // STR rd, rn, rm ror immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += this.BarrelShifterRorImmed();
- }
- private void DispatchFunc390()
- {
- uint rn, rd, alu;
- // STRT rd, rn, rm lsl immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += this.BarrelShifterLslImmed();
- }
- private void DispatchFunc391()
- {
- uint rn, rd, alu;
- // STRT rd, rn, rm lsr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += this.BarrelShifterLsrImmed();
- }
- private void DispatchFunc392()
- {
- uint rn, rd, alu;
- // STRT rd, rn, rm asr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += this.BarrelShifterAsrImmed();
- }
- private void DispatchFunc393()
- {
- uint rn, rd, alu;
- // STRT rd, rn, rm ror immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn], alu);
- registers[rn] += this.BarrelShifterRorImmed();
- }
- private void DispatchFunc394()
- {
- uint rn, rd, alu;
- // STRB rd, rn, rm lsl immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += this.BarrelShifterLslImmed();
- }
- private void DispatchFunc395()
- {
- uint rn, rd, alu;
- // STRB rd, rn, rm lsr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += this.BarrelShifterLsrImmed();
- }
- private void DispatchFunc396()
- {
- uint rn, rd, alu;
- // STRB rd, rn, rm asr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += this.BarrelShifterAsrImmed();
- }
- private void DispatchFunc397()
- {
- uint rn, rd, alu;
- // STRB rd, rn, rm ror immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += this.BarrelShifterRorImmed();
- }
- private void DispatchFunc398()
- {
- uint rn, rd, alu;
- // STRBT rd, rn, rm lsl immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += this.BarrelShifterLslImmed();
- }
- private void DispatchFunc399()
- {
- uint rn, rd, alu;
- // STRBT rd, rn, rm lsr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += this.BarrelShifterLsrImmed();
- }
- private void DispatchFunc400()
- {
- uint rn, rd, alu;
- // STRBT rd, rn, rm asr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += this.BarrelShifterAsrImmed();
- }
- private void DispatchFunc401()
- {
- uint rn, rd, alu;
- // STRBT rd, rn, rm ror immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- registers[rn] += this.BarrelShifterRorImmed();
- }
- private void DispatchFunc402()
- {
- uint rn, rd, offset, alu;
- // STR rd, [rn, -rm lsl immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn] + offset, alu);
- }
- private void DispatchFunc403()
- {
- uint rn, rd, offset, alu;
- // STR rd, [rn, -rm lsr immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn] + offset, alu);
- }
- private void DispatchFunc404()
- {
- uint rn, rd, offset, alu;
- // STR rd, [rn, -rm asr immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn] + offset, alu);
- }
- private void DispatchFunc405()
- {
- uint rn, rd, offset, alu;
- // STR rd, [rn, -rm ror immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn] + offset, alu);
- }
- private void DispatchFunc406()
- {
- uint rn, rd, offset, alu;
- // STR rd, [rn, -rm lsl immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += offset;
- this.memory.WriteU32(registers[rn], alu);
- }
- private void DispatchFunc407()
- {
- uint rn, rd, offset, alu;
- // STR rd, [rn, -rm lsr immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += offset;
- this.memory.WriteU32(registers[rn], alu);
- }
- private void DispatchFunc408()
- {
- uint rn, rd, offset, alu;
- // STR rd, [rn, -rm asr immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += offset;
- this.memory.WriteU32(registers[rn], alu);
- }
- private void DispatchFunc409()
- {
- uint rn, rd, offset, alu;
- // STR rd, [rn, -rm ror immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += offset;
- this.memory.WriteU32(registers[rn], alu);
- }
- private void DispatchFunc410()
- {
- uint rn, rd, offset, alu;
- // STRB rd, [rn, -rm lsl immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn] + offset, (byte)(alu & 0xFF));
- }
- private void DispatchFunc411()
- {
- uint rn, rd, offset, alu;
- // STRB rd, [rn, -rm lsr immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn] + offset, (byte)(alu & 0xFF));
- }
- private void DispatchFunc412()
- {
- uint rn, rd, offset, alu;
- // STRB rd, [rn, -rm asr immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn] + offset, (byte)(alu & 0xFF));
- }
- private void DispatchFunc413()
- {
- uint rn, rd, offset, alu;
- // STRB rd, [rn, -rm ror immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn] + offset, (byte)(alu & 0xFF));
- }
- private void DispatchFunc414()
- {
- uint rn, rd, offset, alu;
- // STRB rd, [rn, -rm lsl immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += offset;
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- }
- private void DispatchFunc415()
- {
- uint rn, rd, offset, alu;
- // STRB rd, [rn, -rm lsr immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += offset;
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- }
- private void DispatchFunc416()
- {
- uint rn, rd, offset, alu;
- // STRB rd, [rn, -rm asr immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += offset;
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- }
- private void DispatchFunc417()
- {
- uint rn, rd, offset, alu;
- // STRB rd, [rn, -rm ror immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- offset = (uint)-offset;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += offset;
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- }
- private void DispatchFunc418()
- {
- uint rn, rd, alu;
- // STR rd, [rn, rm lsl immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn] + this.BarrelShifterLslImmed(), alu);
- }
- private void DispatchFunc419()
- {
- uint rn, rd, alu;
- // STR rd, [rn, rm lsr immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn] + this.BarrelShifterLsrImmed(), alu);
- }
- private void DispatchFunc420()
- {
- uint rn, rd, alu;
- // STR rd, [rn, rm asr immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn] + this.BarrelShifterAsrImmed(), alu);
- }
- private void DispatchFunc421()
- {
- uint rn, rd, alu;
- // STR rd, [rn, rm ror immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU32(registers[rn] + this.BarrelShifterRorImmed(), alu);
- }
- private void DispatchFunc422()
- {
- uint rn, rd, alu;
- // STR rd, [rn, rm lsl immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += this.BarrelShifterLslImmed();
- this.memory.WriteU32(registers[rn], alu);
- }
- private void DispatchFunc423()
- {
- uint rn, rd, alu;
- // STR rd, [rn, rm lsr immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += this.BarrelShifterLsrImmed();
- this.memory.WriteU32(registers[rn], alu);
- }
- private void DispatchFunc424()
- {
- uint rn, rd, alu;
- // STR rd, [rn, rm asr immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += this.BarrelShifterAsrImmed();
- this.memory.WriteU32(registers[rn], alu);
- }
- private void DispatchFunc425()
- {
- uint rn, rd, alu;
- // STR rd, [rn, rm ror immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += this.BarrelShifterRorImmed();
- this.memory.WriteU32(registers[rn], alu);
- }
- private void DispatchFunc426()
- {
- uint rn, rd, alu;
- // STRB rd, [rn, rm lsl immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn] + this.BarrelShifterLslImmed(), (byte)(alu & 0xFF));
- }
- private void DispatchFunc427()
- {
- uint rn, rd, alu;
- // STRB rd, [rn, rm lsr immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn] + this.BarrelShifterLsrImmed(), (byte)(alu & 0xFF));
- }
- private void DispatchFunc428()
- {
- uint rn, rd, alu;
- // STRB rd, [rn, rm asr immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn] + this.BarrelShifterAsrImmed(), (byte)(alu & 0xFF));
- }
- private void DispatchFunc429()
- {
- uint rn, rd, alu;
- // STRB rd, [rn, rm ror immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- this.memory.WriteU8(registers[rn] + this.BarrelShifterRorImmed(), (byte)(alu & 0xFF));
- }
- private void DispatchFunc430()
- {
- uint rn, rd, alu;
- // STRB rd, [rn, rm lsl immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += this.BarrelShifterLslImmed();
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- }
- private void DispatchFunc431()
- {
- uint rn, rd, alu;
- // STRB rd, [rn, rm lsr immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += this.BarrelShifterLsrImmed();
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- }
- private void DispatchFunc432()
- {
- uint rn, rd, alu;
- // STRB rd, [rn, rm asr immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += this.BarrelShifterAsrImmed();
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- }
- private void DispatchFunc433()
- {
- uint rn, rd, alu;
- // STRB rd, [rn, rm ror immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- alu = registers[rd];
- if (rd == 15) alu += 4;
-
- registers[rn] += this.BarrelShifterRorImmed();
- this.memory.WriteU8(registers[rn], (byte)(alu & 0xFF));
- }
- private void DispatchFunc434()
- {
- uint rn, rd, offset;
- // LDR rd, rn, -rm lsl immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc435()
- {
- uint rn, rd, offset;
- // LDR rd, rn, -rm lsr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc436()
- {
- uint rn, rd, offset;
- // LDR rd, rn, -rm asr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc437()
- {
- uint rn, rd, offset;
- // LDR rd, rn, -rm ror immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc438()
- {
- uint rn, rd, offset;
- // LDRT rd, rn, -rm lsl immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc439()
- {
- uint rn, rd, offset;
- // LDRT rd, rn, -rm lsr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc440()
- {
- uint rn, rd, offset;
- // LDRT rd, rn, -rm asr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc441()
- {
- uint rn, rd, offset;
- // LDRT rd, rn, -rm ror immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc442()
- {
- uint rn, rd, offset;
- // LDRB rd, rn, -rm lsl immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc443()
- {
- uint rn, rd, offset;
- // LDRB rd, rn, -rm lsr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc444()
- {
- uint rn, rd, offset;
- // LDRB rd, rn, -rm asr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc445()
- {
- uint rn, rd, offset;
- // LDRB rd, rn, -rm ror immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc446()
- {
- uint rn, rd, offset;
- // LDRBT rd, rn, -rm lsl immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc447()
- {
- uint rn, rd, offset;
- // LDRBT rd, rn, -rm lsr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc448()
- {
- uint rn, rd, offset;
- // LDRBT rd, rn, -rm asr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc449()
- {
- uint rn, rd, offset;
- // LDRBT rd, rn, -rm ror immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc450()
- {
- uint rn, rd, offset;
- // LDR rd, rn, rm lsl immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc451()
- {
- uint rn, rd, offset;
- // LDR rd, rn, rm lsr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc452()
- {
- uint rn, rd, offset;
- // LDR rd, rn, rm asr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc453()
- {
- uint rn, rd, offset;
- // LDR rd, rn, rm ror immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc454()
- {
- uint rn, rd, offset;
- // LDRT rd, rn, rm lsl immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc455()
- {
- uint rn, rd, offset;
- // LDRT rd, rn, rm lsr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc456()
- {
- uint rn, rd, offset;
- // LDRT rd, rn, rm asr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc457()
- {
- uint rn, rd, offset;
- // LDRT rd, rn, rm ror immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc458()
- {
- uint rn, rd, offset;
- // LDRB rd, rn, rm lsl immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc459()
- {
- uint rn, rd, offset;
- // LDRB rd, rn, rm lsr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc460()
- {
- uint rn, rd, offset;
- // LDRB rd, rn, rm asr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc461()
- {
- uint rn, rd, offset;
- // LDRB rd, rn, rm ror immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc462()
- {
- uint rn, rd, offset;
- // LDRBT rd, rn, rm lsl immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc463()
- {
- uint rn, rd, offset;
- // LDRBT rd, rn, rm lsr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc464()
- {
- uint rn, rd, offset;
- // LDRBT rd, rn, rm asr immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc465()
- {
- uint rn, rd, offset;
- // LDRBT rd, rn, rm ror immed
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
-
- if (rn != rd)
- registers[rn] += offset;
- }
- private void DispatchFunc466()
- {
- uint rn, rd, offset;
- // LDR rd, [rn, -rm lsl immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU32(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc467()
- {
- uint rn, rd, offset;
- // LDR rd, [rn, -rm lsr immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU32(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc468()
- {
- uint rn, rd, offset;
- // LDR rd, [rn, -rm asr immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU32(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc469()
- {
- uint rn, rd, offset;
- // LDR rd, [rn, -rm ror immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU32(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc470()
- {
- uint rn, rd, offset;
- // LDR rd, [rn, -rm lsl immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- offset = (uint)-offset;
-
- registers[rn] += offset;
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc471()
- {
- uint rn, rd, offset;
- // LDR rd, [rn, -rm lsr immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- offset = (uint)-offset;
-
- registers[rn] += offset;
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc472()
- {
- uint rn, rd, offset;
- // LDR rd, [rn, -rm asr immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- offset = (uint)-offset;
-
- registers[rn] += offset;
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc473()
- {
- uint rn, rd, offset;
- // LDR rd, [rn, -rm ror immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- offset = (uint)-offset;
-
- registers[rn] += offset;
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc474()
- {
- uint rn, rd, offset;
- // LDRB rd, [rn, -rm lsl immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU8(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc475()
- {
- uint rn, rd, offset;
- // LDRB rd, [rn, -rm lsr immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU8(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc476()
- {
- uint rn, rd, offset;
- // LDRB rd, [rn, -rm asr immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU8(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc477()
- {
- uint rn, rd, offset;
- // LDRB rd, [rn, -rm ror immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- offset = (uint)-offset;
-
- registers[rd] = this.memory.ReadU8(registers[rn] + offset);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc478()
- {
- uint rn, rd, offset;
- // LDRB rd, [rn, -rm lsl immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLslImmed();
- offset = (uint)-offset;
-
- registers[rn] += offset;
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc479()
- {
- uint rn, rd, offset;
- // LDRB rd, [rn, -rm lsr immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterLsrImmed();
- offset = (uint)-offset;
-
- registers[rn] += offset;
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc480()
- {
- uint rn, rd, offset;
- // LDRB rd, [rn, -rm asr immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterAsrImmed();
- offset = (uint)-offset;
-
- registers[rn] += offset;
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc481()
- {
- uint rn, rd, offset;
- // LDRB rd, [rn, -rm ror immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- offset = this.BarrelShifterRorImmed();
- offset = (uint)-offset;
-
- registers[rn] += offset;
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc482()
- {
- uint rn, rd;
- // LDR rd, [rn, rm lsl immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = this.memory.ReadU32(registers[rn] + this.BarrelShifterLslImmed());
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc483()
- {
- uint rn, rd;
- // LDR rd, [rn, rm lsr immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = this.memory.ReadU32(registers[rn] + this.BarrelShifterLsrImmed());
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc484()
- {
- uint rn, rd;
- // LDR rd, [rn, rm asr immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = this.memory.ReadU32(registers[rn] + this.BarrelShifterAsrImmed());
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc485()
- {
- uint rn, rd;
- // LDR rd, [rn, rm ror immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = this.memory.ReadU32(registers[rn] + this.BarrelShifterRorImmed());
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc486()
- {
- uint rn, rd;
- // LDR rd, [rn, rm lsl immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rn] += this.BarrelShifterLslImmed();
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc487()
- {
- uint rn, rd;
- // LDR rd, [rn, rm lsr immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rn] += this.BarrelShifterLsrImmed();
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc488()
- {
- uint rn, rd;
- // LDR rd, [rn, rm asr immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rn] += this.BarrelShifterAsrImmed();
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc489()
- {
- uint rn, rd;
- // LDR rd, [rn, rm ror immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rn] += this.BarrelShifterRorImmed();
- registers[rd] = this.memory.ReadU32(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc490()
- {
- uint rn, rd;
- // LDRB rd, [rn, rm lsl immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = this.memory.ReadU8(registers[rn] + this.BarrelShifterLslImmed());
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc491()
- {
- uint rn, rd;
- // LDRB rd, [rn, rm lsr immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = this.memory.ReadU8(registers[rn] + this.BarrelShifterLsrImmed());
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc492()
- {
- uint rn, rd;
- // LDRB rd, [rn, rm asr immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = this.memory.ReadU8(registers[rn] + this.BarrelShifterAsrImmed());
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc493()
- {
- uint rn, rd;
- // LDRB rd, [rn, rm ror immed]
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rd] = this.memory.ReadU8(registers[rn] + this.BarrelShifterRorImmed());
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc494()
- {
- uint rn, rd;
- // LDRB rd, [rn, rm lsl immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rn] += this.BarrelShifterLslImmed();
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc495()
- {
- uint rn, rd;
- // LDRB rd, [rn, rm lsr immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rn] += this.BarrelShifterLsrImmed();
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc496()
- {
- uint rn, rd;
- // LDRB rd, [rn, rm asr immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rn] += this.BarrelShifterAsrImmed();
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc497()
- {
- uint rn, rd;
- // LDRB rd, [rn, rm ror immed]!
- rn = (this.curInstruction >> 16) & 0xF;
- rd = (this.curInstruction >> 12) & 0xF;
-
- registers[rn] += this.BarrelShifterRorImmed();
- registers[rd] = this.memory.ReadU8(registers[rn]);
-
- if (rd == 15)
- {
- registers[rd] &= ~3U;
- this.FlushQueue();
- }
- }
- private void DispatchFunc498()
- {
- {
- uint branchOffset = this.curInstruction & 0x00FFFFFF;
- if (branchOffset >> 23 == 1) branchOffset |= 0xFF000000;
-
- this.registers[15] += branchOffset << 2;
-
- this.FlushQueue();
- }
- }
- private void DispatchFunc499()
- {
- {
- uint branchOffset = this.curInstruction & 0x00FFFFFF;
- if (branchOffset >> 23 == 1) branchOffset |= 0xFF000000;
-
- this.registers[14] = this.registers[15] - 4U;
- this.registers[15] += branchOffset << 2;
-
- this.FlushQueue();
- }
- }
- private void DispatchFunc500()
- {
- this.registers[15] -= 4U;
- this.parent.EnterException(Arm7Processor.SVC, 0x8, false, false);
- }
- private void DefaultDispatchFunc() { this.NormalOps[(curInstruction >> 25) & 0x7](); }
- private ExecuteInstructionDelegate[] fastDispatch = null;
- private void InitializeDispatchFunc()
- {
- this.fastDispatch = new ExecuteInstructionDelegate[] {
-DispatchFunc0,DispatchFunc1,DispatchFunc2,DispatchFunc3,DispatchFunc4,DispatchFunc5,DispatchFunc6,DispatchFunc7,DispatchFunc0,DispatchFunc17,DispatchFunc2,DispatchFunc29,DispatchFunc4,DispatchFunc16,DispatchFunc6,DispatchFunc16,DispatchFunc8,DispatchFunc9,DispatchFunc10,DispatchFunc11,DispatchFunc12
-,DispatchFunc13,DispatchFunc14,DispatchFunc15,DispatchFunc8,DispatchFunc18,DispatchFunc10,DispatchFunc45,DispatchFunc12,DispatchFunc61,DispatchFunc14,DispatchFunc77,DispatchFunc93,DispatchFunc94,DispatchFunc95,DispatchFunc96,DispatchFunc97,DispatchFunc98,DispatchFunc99,DispatchFunc100,DispatchFunc93
-,DispatchFunc19,DispatchFunc95,DispatchFunc30,DispatchFunc97,DispatchFunc16,DispatchFunc99,DispatchFunc16,DispatchFunc101,DispatchFunc102,DispatchFunc103,DispatchFunc104,DispatchFunc105,DispatchFunc106,DispatchFunc107,DispatchFunc108,DispatchFunc101,DispatchFunc20,DispatchFunc103,DispatchFunc46,DispatchFunc105
-,DispatchFunc62,DispatchFunc107,DispatchFunc78,DispatchFunc109,DispatchFunc110,DispatchFunc111,DispatchFunc112,DispatchFunc113,DispatchFunc114,DispatchFunc115,DispatchFunc116,DispatchFunc109,DefaultDispatchFunc,DispatchFunc111,DispatchFunc31,DispatchFunc113,DispatchFunc16,DispatchFunc115,DispatchFunc16,DispatchFunc117
-,DispatchFunc118,DispatchFunc119,DispatchFunc120,DispatchFunc121,DispatchFunc122,DispatchFunc123,DispatchFunc124,DispatchFunc117,DefaultDispatchFunc,DispatchFunc119,DispatchFunc47,DispatchFunc121,DispatchFunc63,DispatchFunc123,DispatchFunc79,DispatchFunc125,DispatchFunc126,DispatchFunc127,DispatchFunc128,DispatchFunc129
-,DispatchFunc130,DispatchFunc131,DispatchFunc132,DispatchFunc125,DefaultDispatchFunc,DispatchFunc127,DispatchFunc32,DispatchFunc129,DispatchFunc16,DispatchFunc131,DispatchFunc16,DispatchFunc133,DispatchFunc134,DispatchFunc135,DispatchFunc136,DispatchFunc137,DispatchFunc138,DispatchFunc139,DispatchFunc140,DispatchFunc133
-,DefaultDispatchFunc,DispatchFunc135,DispatchFunc48,DispatchFunc137,DispatchFunc64,DispatchFunc139,DispatchFunc80,DispatchFunc141,DispatchFunc142,DispatchFunc143,DispatchFunc144,DispatchFunc145,DispatchFunc146,DispatchFunc147,DispatchFunc148,DispatchFunc141,DispatchFunc21,DispatchFunc143,DispatchFunc33,DispatchFunc145
-,DispatchFunc16,DispatchFunc147,DispatchFunc16,DispatchFunc149,DispatchFunc150,DispatchFunc151,DispatchFunc152,DispatchFunc153,DispatchFunc154,DispatchFunc155,DispatchFunc156,DispatchFunc149,DispatchFunc22,DispatchFunc151,DispatchFunc49,DispatchFunc153,DispatchFunc65,DispatchFunc155,DispatchFunc81,DispatchFunc157
-,DispatchFunc158,DispatchFunc159,DispatchFunc160,DispatchFunc161,DispatchFunc162,DispatchFunc163,DispatchFunc164,DispatchFunc157,DispatchFunc23,DispatchFunc159,DispatchFunc34,DispatchFunc161,DispatchFunc16,DispatchFunc163,DispatchFunc16,DispatchFunc165,DispatchFunc166,DispatchFunc167,DispatchFunc168,DispatchFunc169
-,DispatchFunc170,DispatchFunc171,DispatchFunc172,DispatchFunc165,DispatchFunc24,DispatchFunc167,DispatchFunc50,DispatchFunc169,DispatchFunc66,DispatchFunc171,DispatchFunc82,DispatchFunc173,DispatchFunc174,DispatchFunc175,DispatchFunc176,DispatchFunc177,DispatchFunc178,DispatchFunc179,DispatchFunc180,DispatchFunc173
-,DispatchFunc25,DispatchFunc175,DispatchFunc35,DispatchFunc177,DispatchFunc16,DispatchFunc179,DispatchFunc16,DispatchFunc181,DispatchFunc182,DispatchFunc183,DispatchFunc184,DispatchFunc185,DispatchFunc186,DispatchFunc187,DispatchFunc188,DispatchFunc181,DispatchFunc26,DispatchFunc183,DispatchFunc51,DispatchFunc185
-,DispatchFunc67,DispatchFunc187,DispatchFunc83,DispatchFunc189,DispatchFunc190,DispatchFunc191,DispatchFunc192,DispatchFunc193,DispatchFunc194,DispatchFunc195,DispatchFunc196,DispatchFunc189,DispatchFunc27,DispatchFunc191,DispatchFunc36,DispatchFunc193,DispatchFunc16,DispatchFunc195,DispatchFunc16,DispatchFunc197
-,DispatchFunc198,DispatchFunc199,DispatchFunc200,DispatchFunc201,DispatchFunc202,DispatchFunc203,DispatchFunc204,DispatchFunc197,DispatchFunc28,DispatchFunc199,DispatchFunc52,DispatchFunc201,DispatchFunc68,DispatchFunc203,DispatchFunc84,DispatchFunc207,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DispatchFunc205,DefaultDispatchFunc,DispatchFunc37,DefaultDispatchFunc,DispatchFunc16,DefaultDispatchFunc,DispatchFunc16,DispatchFunc214,DispatchFunc215,DispatchFunc216,DispatchFunc217,DispatchFunc218,DispatchFunc219,DispatchFunc220,DispatchFunc221,DispatchFunc214
-,DefaultDispatchFunc,DispatchFunc216,DispatchFunc53,DispatchFunc218,DispatchFunc69,DispatchFunc220,DispatchFunc85,DispatchFunc209,DispatchFunc213,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DispatchFunc38,DefaultDispatchFunc
-,DispatchFunc16,DefaultDispatchFunc,DispatchFunc16,DispatchFunc222,DispatchFunc223,DispatchFunc224,DispatchFunc225,DispatchFunc226,DispatchFunc227,DispatchFunc228,DispatchFunc229,DispatchFunc222,DefaultDispatchFunc,DispatchFunc224,DispatchFunc54,DispatchFunc226,DispatchFunc70,DispatchFunc228,DispatchFunc86,DispatchFunc208
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DispatchFunc206,DefaultDispatchFunc,DispatchFunc39,DefaultDispatchFunc,DispatchFunc16,DefaultDispatchFunc,DispatchFunc16,DispatchFunc230,DispatchFunc231,DispatchFunc232,DispatchFunc233,DispatchFunc234
-,DispatchFunc235,DispatchFunc236,DispatchFunc237,DispatchFunc230,DefaultDispatchFunc,DispatchFunc232,DispatchFunc55,DispatchFunc234,DispatchFunc71,DispatchFunc236,DispatchFunc87,DispatchFunc210,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DispatchFunc40,DefaultDispatchFunc,DispatchFunc16,DefaultDispatchFunc,DispatchFunc16,DispatchFunc238,DispatchFunc239,DispatchFunc240,DispatchFunc241,DispatchFunc242,DispatchFunc243,DispatchFunc244,DispatchFunc245,DispatchFunc238,DefaultDispatchFunc,DispatchFunc240,DispatchFunc56,DispatchFunc242
-,DispatchFunc72,DispatchFunc244,DispatchFunc88,DispatchFunc246,DispatchFunc247,DispatchFunc248,DispatchFunc249,DispatchFunc250,DispatchFunc251,DispatchFunc252,DispatchFunc253,DispatchFunc246,DefaultDispatchFunc,DispatchFunc248,DispatchFunc41,DispatchFunc250,DispatchFunc16,DispatchFunc252,DispatchFunc16,DispatchFunc254
-,DispatchFunc255,DispatchFunc256,DispatchFunc257,DispatchFunc258,DispatchFunc259,DispatchFunc260,DispatchFunc261,DispatchFunc254,DefaultDispatchFunc,DispatchFunc256,DispatchFunc57,DispatchFunc258,DispatchFunc73,DispatchFunc260,DispatchFunc89,DispatchFunc262,DispatchFunc263,DispatchFunc264,DispatchFunc265,DispatchFunc266
-,DispatchFunc267,DispatchFunc268,DispatchFunc269,DispatchFunc262,DefaultDispatchFunc,DispatchFunc264,DispatchFunc42,DispatchFunc266,DispatchFunc16,DispatchFunc268,DispatchFunc16,DispatchFunc270,DispatchFunc271,DispatchFunc272,DispatchFunc273,DispatchFunc274,DispatchFunc275,DispatchFunc276,DispatchFunc277,DispatchFunc270
-,DefaultDispatchFunc,DispatchFunc272,DispatchFunc58,DispatchFunc274,DispatchFunc74,DispatchFunc276,DispatchFunc90,DispatchFunc278,DispatchFunc279,DispatchFunc280,DispatchFunc281,DispatchFunc282,DispatchFunc283,DispatchFunc284,DispatchFunc285,DispatchFunc278,DefaultDispatchFunc,DispatchFunc280,DispatchFunc43,DispatchFunc282
-,DispatchFunc16,DispatchFunc284,DispatchFunc16,DispatchFunc286,DispatchFunc287,DispatchFunc288,DispatchFunc289,DispatchFunc290,DispatchFunc291,DispatchFunc292,DispatchFunc293,DispatchFunc286,DefaultDispatchFunc,DispatchFunc288,DispatchFunc59,DispatchFunc290,DispatchFunc75,DispatchFunc292,DispatchFunc91,DispatchFunc294
-,DispatchFunc295,DispatchFunc296,DispatchFunc297,DispatchFunc298,DispatchFunc299,DispatchFunc300,DispatchFunc301,DispatchFunc294,DefaultDispatchFunc,DispatchFunc296,DispatchFunc44,DispatchFunc298,DispatchFunc16,DispatchFunc300,DispatchFunc16,DispatchFunc302,DispatchFunc303,DispatchFunc304,DispatchFunc305,DispatchFunc306
-,DispatchFunc307,DispatchFunc308,DispatchFunc309,DispatchFunc302,DefaultDispatchFunc,DispatchFunc304,DispatchFunc60,DispatchFunc306,DispatchFunc76,DispatchFunc308,DispatchFunc92,DispatchFunc310,DispatchFunc310,DispatchFunc310,DispatchFunc310,DispatchFunc310,DispatchFunc310,DispatchFunc310,DispatchFunc310,DispatchFunc310
-,DispatchFunc310,DispatchFunc310,DispatchFunc310,DispatchFunc310,DispatchFunc310,DispatchFunc310,DispatchFunc310,DispatchFunc311,DispatchFunc311,DispatchFunc311,DispatchFunc311,DispatchFunc311,DispatchFunc311,DispatchFunc311,DispatchFunc311,DispatchFunc311,DispatchFunc311,DispatchFunc311,DispatchFunc311,DispatchFunc311
-,DispatchFunc311,DispatchFunc311,DispatchFunc311,DispatchFunc312,DispatchFunc312,DispatchFunc312,DispatchFunc312,DispatchFunc312,DispatchFunc312,DispatchFunc312,DispatchFunc312,DispatchFunc312,DispatchFunc312,DispatchFunc312,DispatchFunc312,DispatchFunc312,DispatchFunc312,DispatchFunc312,DispatchFunc312,DispatchFunc313
-,DispatchFunc313,DispatchFunc313,DispatchFunc313,DispatchFunc313,DispatchFunc313,DispatchFunc313,DispatchFunc313,DispatchFunc313,DispatchFunc313,DispatchFunc313,DispatchFunc313,DispatchFunc313,DispatchFunc313,DispatchFunc313,DispatchFunc313,DispatchFunc314,DispatchFunc314,DispatchFunc314,DispatchFunc314,DispatchFunc314
-,DispatchFunc314,DispatchFunc314,DispatchFunc314,DispatchFunc314,DispatchFunc314,DispatchFunc314,DispatchFunc314,DispatchFunc314,DispatchFunc314,DispatchFunc314,DispatchFunc314,DispatchFunc315,DispatchFunc315,DispatchFunc315,DispatchFunc315,DispatchFunc315,DispatchFunc315,DispatchFunc315,DispatchFunc315,DispatchFunc315
-,DispatchFunc315,DispatchFunc315,DispatchFunc315,DispatchFunc315,DispatchFunc315,DispatchFunc315,DispatchFunc315,DispatchFunc316,DispatchFunc316,DispatchFunc316,DispatchFunc316,DispatchFunc316,DispatchFunc316,DispatchFunc316,DispatchFunc316,DispatchFunc316,DispatchFunc316,DispatchFunc316,DispatchFunc316,DispatchFunc316
-,DispatchFunc316,DispatchFunc316,DispatchFunc316,DispatchFunc317,DispatchFunc317,DispatchFunc317,DispatchFunc317,DispatchFunc317,DispatchFunc317,DispatchFunc317,DispatchFunc317,DispatchFunc317,DispatchFunc317,DispatchFunc317,DispatchFunc317,DispatchFunc317,DispatchFunc317,DispatchFunc317,DispatchFunc317,DispatchFunc318
-,DispatchFunc318,DispatchFunc318,DispatchFunc318,DispatchFunc318,DispatchFunc318,DispatchFunc318,DispatchFunc318,DispatchFunc318,DispatchFunc318,DispatchFunc318,DispatchFunc318,DispatchFunc318,DispatchFunc318,DispatchFunc318,DispatchFunc318,DispatchFunc319,DispatchFunc319,DispatchFunc319,DispatchFunc319,DispatchFunc319
-,DispatchFunc319,DispatchFunc319,DispatchFunc319,DispatchFunc319,DispatchFunc319,DispatchFunc319,DispatchFunc319,DispatchFunc319,DispatchFunc319,DispatchFunc319,DispatchFunc319,DispatchFunc320,DispatchFunc320,DispatchFunc320,DispatchFunc320,DispatchFunc320,DispatchFunc320,DispatchFunc320,DispatchFunc320,DispatchFunc320
-,DispatchFunc320,DispatchFunc320,DispatchFunc320,DispatchFunc320,DispatchFunc320,DispatchFunc320,DispatchFunc320,DispatchFunc321,DispatchFunc321,DispatchFunc321,DispatchFunc321,DispatchFunc321,DispatchFunc321,DispatchFunc321,DispatchFunc321,DispatchFunc321,DispatchFunc321,DispatchFunc321,DispatchFunc321,DispatchFunc321
-,DispatchFunc321,DispatchFunc321,DispatchFunc321,DispatchFunc322,DispatchFunc322,DispatchFunc322,DispatchFunc322,DispatchFunc322,DispatchFunc322,DispatchFunc322,DispatchFunc322,DispatchFunc322,DispatchFunc322,DispatchFunc322,DispatchFunc322,DispatchFunc322,DispatchFunc322,DispatchFunc322,DispatchFunc322,DispatchFunc323
-,DispatchFunc323,DispatchFunc323,DispatchFunc323,DispatchFunc323,DispatchFunc323,DispatchFunc323,DispatchFunc323,DispatchFunc323,DispatchFunc323,DispatchFunc323,DispatchFunc323,DispatchFunc323,DispatchFunc323,DispatchFunc323,DispatchFunc323,DispatchFunc324,DispatchFunc324,DispatchFunc324,DispatchFunc324,DispatchFunc324
-,DispatchFunc324,DispatchFunc324,DispatchFunc324,DispatchFunc324,DispatchFunc324,DispatchFunc324,DispatchFunc324,DispatchFunc324,DispatchFunc324,DispatchFunc324,DispatchFunc324,DispatchFunc325,DispatchFunc325,DispatchFunc325,DispatchFunc325,DispatchFunc325,DispatchFunc325,DispatchFunc325,DispatchFunc325,DispatchFunc325
-,DispatchFunc325,DispatchFunc325,DispatchFunc325,DispatchFunc325,DispatchFunc325,DispatchFunc325,DispatchFunc325,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DispatchFunc326,DispatchFunc326,DispatchFunc326,DispatchFunc326,DispatchFunc326,DispatchFunc326,DispatchFunc326,DispatchFunc326,DispatchFunc326,DispatchFunc326,DispatchFunc326,DispatchFunc326,DispatchFunc326,DispatchFunc326,DispatchFunc326,DispatchFunc326,DispatchFunc211
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DispatchFunc327,DispatchFunc327,DispatchFunc327,DispatchFunc327,DispatchFunc327
-,DispatchFunc327,DispatchFunc327,DispatchFunc327,DispatchFunc327,DispatchFunc327,DispatchFunc327,DispatchFunc327,DispatchFunc327,DispatchFunc327,DispatchFunc327,DispatchFunc327,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DispatchFunc328,DispatchFunc328,DispatchFunc328,DispatchFunc328,DispatchFunc328,DispatchFunc328,DispatchFunc328,DispatchFunc328,DispatchFunc328,DispatchFunc328,DispatchFunc328,DispatchFunc328,DispatchFunc328
-,DispatchFunc328,DispatchFunc328,DispatchFunc328,DispatchFunc212,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DispatchFunc329
-,DispatchFunc329,DispatchFunc329,DispatchFunc329,DispatchFunc329,DispatchFunc329,DispatchFunc329,DispatchFunc329,DispatchFunc329,DispatchFunc329,DispatchFunc329,DispatchFunc329,DispatchFunc329,DispatchFunc329,DispatchFunc329,DispatchFunc329,DispatchFunc330,DispatchFunc330,DispatchFunc330,DispatchFunc330,DispatchFunc330
-,DispatchFunc330,DispatchFunc330,DispatchFunc330,DispatchFunc330,DispatchFunc330,DispatchFunc330,DispatchFunc330,DispatchFunc330,DispatchFunc330,DispatchFunc330,DispatchFunc330,DispatchFunc331,DispatchFunc331,DispatchFunc331,DispatchFunc331,DispatchFunc331,DispatchFunc331,DispatchFunc331,DispatchFunc331,DispatchFunc331
-,DispatchFunc331,DispatchFunc331,DispatchFunc331,DispatchFunc331,DispatchFunc331,DispatchFunc331,DispatchFunc331,DispatchFunc332,DispatchFunc332,DispatchFunc332,DispatchFunc332,DispatchFunc332,DispatchFunc332,DispatchFunc332,DispatchFunc332,DispatchFunc332,DispatchFunc332,DispatchFunc332,DispatchFunc332,DispatchFunc332
-,DispatchFunc332,DispatchFunc332,DispatchFunc332,DispatchFunc333,DispatchFunc333,DispatchFunc333,DispatchFunc333,DispatchFunc333,DispatchFunc333,DispatchFunc333,DispatchFunc333,DispatchFunc333,DispatchFunc333,DispatchFunc333,DispatchFunc333,DispatchFunc333,DispatchFunc333,DispatchFunc333,DispatchFunc333,DispatchFunc334
-,DispatchFunc334,DispatchFunc334,DispatchFunc334,DispatchFunc334,DispatchFunc334,DispatchFunc334,DispatchFunc334,DispatchFunc334,DispatchFunc334,DispatchFunc334,DispatchFunc334,DispatchFunc334,DispatchFunc334,DispatchFunc334,DispatchFunc334,DispatchFunc335,DispatchFunc335,DispatchFunc335,DispatchFunc335,DispatchFunc335
-,DispatchFunc335,DispatchFunc335,DispatchFunc335,DispatchFunc335,DispatchFunc335,DispatchFunc335,DispatchFunc335,DispatchFunc335,DispatchFunc335,DispatchFunc335,DispatchFunc335,DispatchFunc336,DispatchFunc336,DispatchFunc336,DispatchFunc336,DispatchFunc336,DispatchFunc336,DispatchFunc336,DispatchFunc336,DispatchFunc336
-,DispatchFunc336,DispatchFunc336,DispatchFunc336,DispatchFunc336,DispatchFunc336,DispatchFunc336,DispatchFunc336,DispatchFunc337,DispatchFunc337,DispatchFunc337,DispatchFunc337,DispatchFunc337,DispatchFunc337,DispatchFunc337,DispatchFunc337,DispatchFunc337,DispatchFunc337,DispatchFunc337,DispatchFunc337,DispatchFunc337
-,DispatchFunc337,DispatchFunc337,DispatchFunc337,DispatchFunc338,DispatchFunc338,DispatchFunc338,DispatchFunc338,DispatchFunc338,DispatchFunc338,DispatchFunc338,DispatchFunc338,DispatchFunc338,DispatchFunc338,DispatchFunc338,DispatchFunc338,DispatchFunc338,DispatchFunc338,DispatchFunc338,DispatchFunc338,DispatchFunc354
-,DispatchFunc354,DispatchFunc354,DispatchFunc354,DispatchFunc354,DispatchFunc354,DispatchFunc354,DispatchFunc354,DispatchFunc354,DispatchFunc354,DispatchFunc354,DispatchFunc354,DispatchFunc354,DispatchFunc354,DispatchFunc354,DispatchFunc354,DispatchFunc339,DispatchFunc339,DispatchFunc339,DispatchFunc339,DispatchFunc339
-,DispatchFunc339,DispatchFunc339,DispatchFunc339,DispatchFunc339,DispatchFunc339,DispatchFunc339,DispatchFunc339,DispatchFunc339,DispatchFunc339,DispatchFunc339,DispatchFunc339,DispatchFunc355,DispatchFunc355,DispatchFunc355,DispatchFunc355,DispatchFunc355,DispatchFunc355,DispatchFunc355,DispatchFunc355,DispatchFunc355
-,DispatchFunc355,DispatchFunc355,DispatchFunc355,DispatchFunc355,DispatchFunc355,DispatchFunc355,DispatchFunc355,DispatchFunc340,DispatchFunc340,DispatchFunc340,DispatchFunc340,DispatchFunc340,DispatchFunc340,DispatchFunc340,DispatchFunc340,DispatchFunc340,DispatchFunc340,DispatchFunc340,DispatchFunc340,DispatchFunc340
-,DispatchFunc340,DispatchFunc340,DispatchFunc340,DispatchFunc356,DispatchFunc356,DispatchFunc356,DispatchFunc356,DispatchFunc356,DispatchFunc356,DispatchFunc356,DispatchFunc356,DispatchFunc356,DispatchFunc356,DispatchFunc356,DispatchFunc356,DispatchFunc356,DispatchFunc356,DispatchFunc356,DispatchFunc356,DispatchFunc341
-,DispatchFunc341,DispatchFunc341,DispatchFunc341,DispatchFunc341,DispatchFunc341,DispatchFunc341,DispatchFunc341,DispatchFunc341,DispatchFunc341,DispatchFunc341,DispatchFunc341,DispatchFunc341,DispatchFunc341,DispatchFunc341,DispatchFunc341,DispatchFunc357,DispatchFunc357,DispatchFunc357,DispatchFunc357,DispatchFunc357
-,DispatchFunc357,DispatchFunc357,DispatchFunc357,DispatchFunc357,DispatchFunc357,DispatchFunc357,DispatchFunc357,DispatchFunc357,DispatchFunc357,DispatchFunc357,DispatchFunc357,DispatchFunc342,DispatchFunc342,DispatchFunc342,DispatchFunc342,DispatchFunc342,DispatchFunc342,DispatchFunc342,DispatchFunc342,DispatchFunc342
-,DispatchFunc342,DispatchFunc342,DispatchFunc342,DispatchFunc342,DispatchFunc342,DispatchFunc342,DispatchFunc342,DispatchFunc358,DispatchFunc358,DispatchFunc358,DispatchFunc358,DispatchFunc358,DispatchFunc358,DispatchFunc358,DispatchFunc358,DispatchFunc358,DispatchFunc358,DispatchFunc358,DispatchFunc358,DispatchFunc358
-,DispatchFunc358,DispatchFunc358,DispatchFunc358,DispatchFunc343,DispatchFunc343,DispatchFunc343,DispatchFunc343,DispatchFunc343,DispatchFunc343,DispatchFunc343,DispatchFunc343,DispatchFunc343,DispatchFunc343,DispatchFunc343,DispatchFunc343,DispatchFunc343,DispatchFunc343,DispatchFunc343,DispatchFunc343,DispatchFunc359
-,DispatchFunc359,DispatchFunc359,DispatchFunc359,DispatchFunc359,DispatchFunc359,DispatchFunc359,DispatchFunc359,DispatchFunc359,DispatchFunc359,DispatchFunc359,DispatchFunc359,DispatchFunc359,DispatchFunc359,DispatchFunc359,DispatchFunc359,DispatchFunc344,DispatchFunc344,DispatchFunc344,DispatchFunc344,DispatchFunc344
-,DispatchFunc344,DispatchFunc344,DispatchFunc344,DispatchFunc344,DispatchFunc344,DispatchFunc344,DispatchFunc344,DispatchFunc344,DispatchFunc344,DispatchFunc344,DispatchFunc344,DispatchFunc360,DispatchFunc360,DispatchFunc360,DispatchFunc360,DispatchFunc360,DispatchFunc360,DispatchFunc360,DispatchFunc360,DispatchFunc360
-,DispatchFunc360,DispatchFunc360,DispatchFunc360,DispatchFunc360,DispatchFunc360,DispatchFunc360,DispatchFunc360,DispatchFunc345,DispatchFunc345,DispatchFunc345,DispatchFunc345,DispatchFunc345,DispatchFunc345,DispatchFunc345,DispatchFunc345,DispatchFunc345,DispatchFunc345,DispatchFunc345,DispatchFunc345,DispatchFunc345
-,DispatchFunc345,DispatchFunc345,DispatchFunc345,DispatchFunc361,DispatchFunc361,DispatchFunc361,DispatchFunc361,DispatchFunc361,DispatchFunc361,DispatchFunc361,DispatchFunc361,DispatchFunc361,DispatchFunc361,DispatchFunc361,DispatchFunc361,DispatchFunc361,DispatchFunc361,DispatchFunc361,DispatchFunc361,DispatchFunc346
-,DispatchFunc346,DispatchFunc346,DispatchFunc346,DispatchFunc346,DispatchFunc346,DispatchFunc346,DispatchFunc346,DispatchFunc346,DispatchFunc346,DispatchFunc346,DispatchFunc346,DispatchFunc346,DispatchFunc346,DispatchFunc346,DispatchFunc346,DispatchFunc362,DispatchFunc362,DispatchFunc362,DispatchFunc362,DispatchFunc362
-,DispatchFunc362,DispatchFunc362,DispatchFunc362,DispatchFunc362,DispatchFunc362,DispatchFunc362,DispatchFunc362,DispatchFunc362,DispatchFunc362,DispatchFunc362,DispatchFunc362,DispatchFunc347,DispatchFunc347,DispatchFunc347,DispatchFunc347,DispatchFunc347,DispatchFunc347,DispatchFunc347,DispatchFunc347,DispatchFunc347
-,DispatchFunc347,DispatchFunc347,DispatchFunc347,DispatchFunc347,DispatchFunc347,DispatchFunc347,DispatchFunc347,DispatchFunc363,DispatchFunc363,DispatchFunc363,DispatchFunc363,DispatchFunc363,DispatchFunc363,DispatchFunc363,DispatchFunc363,DispatchFunc363,DispatchFunc363,DispatchFunc363,DispatchFunc363,DispatchFunc363
-,DispatchFunc363,DispatchFunc363,DispatchFunc363,DispatchFunc348,DispatchFunc348,DispatchFunc348,DispatchFunc348,DispatchFunc348,DispatchFunc348,DispatchFunc348,DispatchFunc348,DispatchFunc348,DispatchFunc348,DispatchFunc348,DispatchFunc348,DispatchFunc348,DispatchFunc348,DispatchFunc348,DispatchFunc348,DispatchFunc364
-,DispatchFunc364,DispatchFunc364,DispatchFunc364,DispatchFunc364,DispatchFunc364,DispatchFunc364,DispatchFunc364,DispatchFunc364,DispatchFunc364,DispatchFunc364,DispatchFunc364,DispatchFunc364,DispatchFunc364,DispatchFunc364,DispatchFunc364,DispatchFunc349,DispatchFunc349,DispatchFunc349,DispatchFunc349,DispatchFunc349
-,DispatchFunc349,DispatchFunc349,DispatchFunc349,DispatchFunc349,DispatchFunc349,DispatchFunc349,DispatchFunc349,DispatchFunc349,DispatchFunc349,DispatchFunc349,DispatchFunc349,DispatchFunc365,DispatchFunc365,DispatchFunc365,DispatchFunc365,DispatchFunc365,DispatchFunc365,DispatchFunc365,DispatchFunc365,DispatchFunc365
-,DispatchFunc365,DispatchFunc365,DispatchFunc365,DispatchFunc365,DispatchFunc365,DispatchFunc365,DispatchFunc365,DispatchFunc350,DispatchFunc350,DispatchFunc350,DispatchFunc350,DispatchFunc350,DispatchFunc350,DispatchFunc350,DispatchFunc350,DispatchFunc350,DispatchFunc350,DispatchFunc350,DispatchFunc350,DispatchFunc350
-,DispatchFunc350,DispatchFunc350,DispatchFunc350,DispatchFunc366,DispatchFunc366,DispatchFunc366,DispatchFunc366,DispatchFunc366,DispatchFunc366,DispatchFunc366,DispatchFunc366,DispatchFunc366,DispatchFunc366,DispatchFunc366,DispatchFunc366,DispatchFunc366,DispatchFunc366,DispatchFunc366,DispatchFunc366,DispatchFunc351
-,DispatchFunc351,DispatchFunc351,DispatchFunc351,DispatchFunc351,DispatchFunc351,DispatchFunc351,DispatchFunc351,DispatchFunc351,DispatchFunc351,DispatchFunc351,DispatchFunc351,DispatchFunc351,DispatchFunc351,DispatchFunc351,DispatchFunc351,DispatchFunc367,DispatchFunc367,DispatchFunc367,DispatchFunc367,DispatchFunc367
-,DispatchFunc367,DispatchFunc367,DispatchFunc367,DispatchFunc367,DispatchFunc367,DispatchFunc367,DispatchFunc367,DispatchFunc367,DispatchFunc367,DispatchFunc367,DispatchFunc367,DispatchFunc352,DispatchFunc352,DispatchFunc352,DispatchFunc352,DispatchFunc352,DispatchFunc352,DispatchFunc352,DispatchFunc352,DispatchFunc352
-,DispatchFunc352,DispatchFunc352,DispatchFunc352,DispatchFunc352,DispatchFunc352,DispatchFunc352,DispatchFunc352,DispatchFunc368,DispatchFunc368,DispatchFunc368,DispatchFunc368,DispatchFunc368,DispatchFunc368,DispatchFunc368,DispatchFunc368,DispatchFunc368,DispatchFunc368,DispatchFunc368,DispatchFunc368,DispatchFunc368
-,DispatchFunc368,DispatchFunc368,DispatchFunc368,DispatchFunc353,DispatchFunc353,DispatchFunc353,DispatchFunc353,DispatchFunc353,DispatchFunc353,DispatchFunc353,DispatchFunc353,DispatchFunc353,DispatchFunc353,DispatchFunc353,DispatchFunc353,DispatchFunc353,DispatchFunc353,DispatchFunc353,DispatchFunc353,DispatchFunc369
-,DispatchFunc369,DispatchFunc369,DispatchFunc369,DispatchFunc369,DispatchFunc369,DispatchFunc369,DispatchFunc369,DispatchFunc369,DispatchFunc369,DispatchFunc369,DispatchFunc369,DispatchFunc369,DispatchFunc369,DispatchFunc369,DispatchFunc369,DispatchFunc370,DefaultDispatchFunc,DispatchFunc371,DefaultDispatchFunc,DispatchFunc372
-,DefaultDispatchFunc,DispatchFunc373,DefaultDispatchFunc,DispatchFunc370,DefaultDispatchFunc,DispatchFunc371,DefaultDispatchFunc,DispatchFunc372,DefaultDispatchFunc,DispatchFunc373,DefaultDispatchFunc,DispatchFunc434,DefaultDispatchFunc,DispatchFunc435,DefaultDispatchFunc,DispatchFunc436,DefaultDispatchFunc,DispatchFunc437,DefaultDispatchFunc,DispatchFunc434
-,DefaultDispatchFunc,DispatchFunc435,DefaultDispatchFunc,DispatchFunc436,DefaultDispatchFunc,DispatchFunc437,DefaultDispatchFunc,DispatchFunc374,DefaultDispatchFunc,DispatchFunc375,DefaultDispatchFunc,DispatchFunc376,DefaultDispatchFunc,DispatchFunc377,DefaultDispatchFunc,DispatchFunc374,DefaultDispatchFunc,DispatchFunc375,DefaultDispatchFunc,DispatchFunc376
-,DefaultDispatchFunc,DispatchFunc377,DefaultDispatchFunc,DispatchFunc438,DefaultDispatchFunc,DispatchFunc439,DefaultDispatchFunc,DispatchFunc440,DefaultDispatchFunc,DispatchFunc441,DefaultDispatchFunc,DispatchFunc438,DefaultDispatchFunc,DispatchFunc439,DefaultDispatchFunc,DispatchFunc440,DefaultDispatchFunc,DispatchFunc441,DefaultDispatchFunc,DispatchFunc378
-,DefaultDispatchFunc,DispatchFunc379,DefaultDispatchFunc,DispatchFunc380,DefaultDispatchFunc,DispatchFunc381,DefaultDispatchFunc,DispatchFunc378,DefaultDispatchFunc,DispatchFunc379,DefaultDispatchFunc,DispatchFunc380,DefaultDispatchFunc,DispatchFunc381,DefaultDispatchFunc,DispatchFunc442,DefaultDispatchFunc,DispatchFunc443,DefaultDispatchFunc,DispatchFunc444
-,DefaultDispatchFunc,DispatchFunc445,DefaultDispatchFunc,DispatchFunc442,DefaultDispatchFunc,DispatchFunc443,DefaultDispatchFunc,DispatchFunc444,DefaultDispatchFunc,DispatchFunc445,DefaultDispatchFunc,DispatchFunc382,DefaultDispatchFunc,DispatchFunc383,DefaultDispatchFunc,DispatchFunc384,DefaultDispatchFunc,DispatchFunc385,DefaultDispatchFunc,DispatchFunc382
-,DefaultDispatchFunc,DispatchFunc383,DefaultDispatchFunc,DispatchFunc384,DefaultDispatchFunc,DispatchFunc385,DefaultDispatchFunc,DispatchFunc446,DefaultDispatchFunc,DispatchFunc447,DefaultDispatchFunc,DispatchFunc448,DefaultDispatchFunc,DispatchFunc449,DefaultDispatchFunc,DispatchFunc446,DefaultDispatchFunc,DispatchFunc447,DefaultDispatchFunc,DispatchFunc448
-,DefaultDispatchFunc,DispatchFunc449,DefaultDispatchFunc,DispatchFunc386,DefaultDispatchFunc,DispatchFunc387,DefaultDispatchFunc,DispatchFunc388,DefaultDispatchFunc,DispatchFunc389,DefaultDispatchFunc,DispatchFunc386,DefaultDispatchFunc,DispatchFunc387,DefaultDispatchFunc,DispatchFunc388,DefaultDispatchFunc,DispatchFunc389,DefaultDispatchFunc,DispatchFunc450
-,DefaultDispatchFunc,DispatchFunc451,DefaultDispatchFunc,DispatchFunc452,DefaultDispatchFunc,DispatchFunc453,DefaultDispatchFunc,DispatchFunc450,DefaultDispatchFunc,DispatchFunc451,DefaultDispatchFunc,DispatchFunc452,DefaultDispatchFunc,DispatchFunc453,DefaultDispatchFunc,DispatchFunc390,DefaultDispatchFunc,DispatchFunc390,DefaultDispatchFunc,DispatchFunc391
-,DefaultDispatchFunc,DispatchFunc391,DefaultDispatchFunc,DispatchFunc392,DefaultDispatchFunc,DispatchFunc392,DefaultDispatchFunc,DispatchFunc393,DefaultDispatchFunc,DispatchFunc393,DefaultDispatchFunc,DispatchFunc454,DefaultDispatchFunc,DispatchFunc455,DefaultDispatchFunc,DispatchFunc456,DefaultDispatchFunc,DispatchFunc457,DefaultDispatchFunc,DispatchFunc454
-,DefaultDispatchFunc,DispatchFunc455,DefaultDispatchFunc,DispatchFunc456,DefaultDispatchFunc,DispatchFunc457,DefaultDispatchFunc,DispatchFunc394,DefaultDispatchFunc,DispatchFunc395,DefaultDispatchFunc,DispatchFunc396,DefaultDispatchFunc,DispatchFunc397,DefaultDispatchFunc,DispatchFunc394,DefaultDispatchFunc,DispatchFunc395,DefaultDispatchFunc,DispatchFunc396
-,DefaultDispatchFunc,DispatchFunc397,DefaultDispatchFunc,DispatchFunc458,DefaultDispatchFunc,DispatchFunc459,DefaultDispatchFunc,DispatchFunc460,DefaultDispatchFunc,DispatchFunc461,DefaultDispatchFunc,DispatchFunc458,DefaultDispatchFunc,DispatchFunc459,DefaultDispatchFunc,DispatchFunc460,DefaultDispatchFunc,DispatchFunc461,DefaultDispatchFunc,DispatchFunc398
-,DefaultDispatchFunc,DispatchFunc399,DefaultDispatchFunc,DispatchFunc400,DefaultDispatchFunc,DispatchFunc401,DefaultDispatchFunc,DispatchFunc398,DefaultDispatchFunc,DispatchFunc399,DefaultDispatchFunc,DispatchFunc400,DefaultDispatchFunc,DispatchFunc401,DefaultDispatchFunc,DispatchFunc462,DefaultDispatchFunc,DispatchFunc463,DefaultDispatchFunc,DispatchFunc464
-,DefaultDispatchFunc,DispatchFunc465,DefaultDispatchFunc,DispatchFunc462,DefaultDispatchFunc,DispatchFunc463,DefaultDispatchFunc,DispatchFunc464,DefaultDispatchFunc,DispatchFunc465,DefaultDispatchFunc,DispatchFunc402,DefaultDispatchFunc,DispatchFunc403,DefaultDispatchFunc,DispatchFunc404,DefaultDispatchFunc,DispatchFunc405,DefaultDispatchFunc,DispatchFunc402
-,DefaultDispatchFunc,DispatchFunc403,DefaultDispatchFunc,DispatchFunc404,DefaultDispatchFunc,DispatchFunc405,DefaultDispatchFunc,DispatchFunc466,DefaultDispatchFunc,DispatchFunc467,DefaultDispatchFunc,DispatchFunc468,DefaultDispatchFunc,DispatchFunc469,DefaultDispatchFunc,DispatchFunc466,DefaultDispatchFunc,DispatchFunc467,DefaultDispatchFunc,DispatchFunc468
-,DefaultDispatchFunc,DispatchFunc469,DefaultDispatchFunc,DispatchFunc406,DefaultDispatchFunc,DispatchFunc407,DefaultDispatchFunc,DispatchFunc408,DefaultDispatchFunc,DispatchFunc409,DefaultDispatchFunc,DispatchFunc406,DefaultDispatchFunc,DispatchFunc407,DefaultDispatchFunc,DispatchFunc408,DefaultDispatchFunc,DispatchFunc409,DefaultDispatchFunc,DispatchFunc470
-,DefaultDispatchFunc,DispatchFunc471,DefaultDispatchFunc,DispatchFunc472,DefaultDispatchFunc,DispatchFunc473,DefaultDispatchFunc,DispatchFunc470,DefaultDispatchFunc,DispatchFunc471,DefaultDispatchFunc,DispatchFunc472,DefaultDispatchFunc,DispatchFunc473,DefaultDispatchFunc,DispatchFunc410,DefaultDispatchFunc,DispatchFunc411,DefaultDispatchFunc,DispatchFunc412
-,DefaultDispatchFunc,DispatchFunc413,DefaultDispatchFunc,DispatchFunc410,DefaultDispatchFunc,DispatchFunc411,DefaultDispatchFunc,DispatchFunc412,DefaultDispatchFunc,DispatchFunc413,DefaultDispatchFunc,DispatchFunc474,DefaultDispatchFunc,DispatchFunc475,DefaultDispatchFunc,DispatchFunc476,DefaultDispatchFunc,DispatchFunc477,DefaultDispatchFunc,DispatchFunc474
-,DefaultDispatchFunc,DispatchFunc475,DefaultDispatchFunc,DispatchFunc476,DefaultDispatchFunc,DispatchFunc477,DefaultDispatchFunc,DispatchFunc414,DefaultDispatchFunc,DispatchFunc415,DefaultDispatchFunc,DispatchFunc416,DefaultDispatchFunc,DispatchFunc417,DefaultDispatchFunc,DispatchFunc414,DefaultDispatchFunc,DispatchFunc415,DefaultDispatchFunc,DispatchFunc416
-,DefaultDispatchFunc,DispatchFunc417,DefaultDispatchFunc,DispatchFunc478,DefaultDispatchFunc,DispatchFunc479,DefaultDispatchFunc,DispatchFunc480,DefaultDispatchFunc,DispatchFunc481,DefaultDispatchFunc,DispatchFunc478,DefaultDispatchFunc,DispatchFunc479,DefaultDispatchFunc,DispatchFunc480,DefaultDispatchFunc,DispatchFunc481,DefaultDispatchFunc,DispatchFunc418
-,DefaultDispatchFunc,DispatchFunc419,DefaultDispatchFunc,DispatchFunc420,DefaultDispatchFunc,DispatchFunc421,DefaultDispatchFunc,DispatchFunc418,DefaultDispatchFunc,DispatchFunc419,DefaultDispatchFunc,DispatchFunc420,DefaultDispatchFunc,DispatchFunc421,DefaultDispatchFunc,DispatchFunc482,DefaultDispatchFunc,DispatchFunc483,DefaultDispatchFunc,DispatchFunc484
-,DefaultDispatchFunc,DispatchFunc485,DefaultDispatchFunc,DispatchFunc482,DefaultDispatchFunc,DispatchFunc483,DefaultDispatchFunc,DispatchFunc484,DefaultDispatchFunc,DispatchFunc485,DefaultDispatchFunc,DispatchFunc422,DefaultDispatchFunc,DispatchFunc423,DefaultDispatchFunc,DispatchFunc424,DefaultDispatchFunc,DispatchFunc425,DefaultDispatchFunc,DispatchFunc422
-,DefaultDispatchFunc,DispatchFunc423,DefaultDispatchFunc,DispatchFunc424,DefaultDispatchFunc,DispatchFunc425,DefaultDispatchFunc,DispatchFunc486,DefaultDispatchFunc,DispatchFunc487,DefaultDispatchFunc,DispatchFunc488,DefaultDispatchFunc,DispatchFunc489,DefaultDispatchFunc,DispatchFunc486,DefaultDispatchFunc,DispatchFunc487,DefaultDispatchFunc,DispatchFunc488
-,DefaultDispatchFunc,DispatchFunc489,DefaultDispatchFunc,DispatchFunc426,DefaultDispatchFunc,DispatchFunc427,DefaultDispatchFunc,DispatchFunc428,DefaultDispatchFunc,DispatchFunc429,DefaultDispatchFunc,DispatchFunc426,DefaultDispatchFunc,DispatchFunc427,DefaultDispatchFunc,DispatchFunc428,DefaultDispatchFunc,DispatchFunc429,DefaultDispatchFunc,DispatchFunc490
-,DefaultDispatchFunc,DispatchFunc491,DefaultDispatchFunc,DispatchFunc492,DefaultDispatchFunc,DispatchFunc493,DefaultDispatchFunc,DispatchFunc490,DefaultDispatchFunc,DispatchFunc491,DefaultDispatchFunc,DispatchFunc492,DefaultDispatchFunc,DispatchFunc493,DefaultDispatchFunc,DispatchFunc430,DefaultDispatchFunc,DispatchFunc431,DefaultDispatchFunc,DispatchFunc432
-,DefaultDispatchFunc,DispatchFunc433,DefaultDispatchFunc,DispatchFunc430,DefaultDispatchFunc,DispatchFunc431,DefaultDispatchFunc,DispatchFunc432,DefaultDispatchFunc,DispatchFunc433,DefaultDispatchFunc,DispatchFunc494,DefaultDispatchFunc,DispatchFunc495,DefaultDispatchFunc,DispatchFunc496,DefaultDispatchFunc,DispatchFunc497,DefaultDispatchFunc,DispatchFunc494
-,DefaultDispatchFunc,DispatchFunc495,DefaultDispatchFunc,DispatchFunc496,DefaultDispatchFunc,DispatchFunc497,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DispatchFunc498
-,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498
-,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498
-,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498
-,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498
-,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498
-,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498
-,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498
-,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498
-,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498
-,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498
-,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498
-,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498
-,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc498,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499
-,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499
-,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499
-,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499
-,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499
-,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499
-,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499
-,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499
-,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499
-,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499
-,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499
-,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499
-,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499
-,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DispatchFunc499,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc
-,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DefaultDispatchFunc,DispatchFunc500
-,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500
-,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500
-,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500
-,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500
-,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500
-,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500
-,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500
-,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500
-,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500
-,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500
-,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500
-,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500,DispatchFunc500
-};
- }
- #endregion Delegate Dispatcher
- }
-}
diff --git a/attic/GarboDev/GbaManager.cs b/attic/GarboDev/GbaManager.cs
deleted file mode 100644
index b03dd4852c..0000000000
--- a/attic/GarboDev/GbaManager.cs
+++ /dev/null
@@ -1,469 +0,0 @@
-//#define ARM_DEBUG
-
-namespace GarboDev
-{
- using System;
- using System.IO;
- using System.Threading;
- using System.Timers;
- using System.Windows.Forms;
- using System.Collections.Generic;
-
- using BizHawk.Emulation;
- using BizHawk;
-
- public class GbaManager : IEmulator, ISyncSoundProvider, IVideoProvider
- {
- public const int cpuFreq = 16 * 1024 * 1024;
-
- private int framesRendered;
-
- private Arm7Processor arm7 = null;
- private Memory memory = null;
- private VideoManager videoManager = null;
- private SoundManager soundManager = null;
-
- private bool skipBios = false;
-
- public delegate void CpuUpdateDelegate(Arm7Processor processor, Memory memory);
- private event CpuUpdateDelegate onCpuUpdate = null;
-
- public Arm7Processor Arm7
- {
- get { return this.arm7; }
- }
-
- public VideoManager VideoManager
- {
- get { return this.videoManager; }
- }
-
- public SoundManager SoundManager
- {
- get { return this.soundManager; }
- }
-
- public Memory Memory
- {
- get { return this.memory; }
- }
-
- public Dictionary Breakpoints
- {
- get { return this.arm7.Breakpoints; }
- }
-
- public ushort KeyState
- {
- get
- {
- if (this.memory != null)
- {
- return this.memory.KeyState;
- }
-
- return 0x3FF;
- }
-
- set
- {
- this.arm7.KeyState = value;
- }
- }
-
- public int FramesRendered
- {
- get { return this.framesRendered; }
- set { this.framesRendered = value; }
- }
-
- public event CpuUpdateDelegate OnCpuUpdate
- {
- add
- {
- this.onCpuUpdate += value;
- this.onCpuUpdate(this.arm7, this.memory);
- }
- remove
- {
- this.onCpuUpdate -= value;
- }
- }
-
- public bool SkipBios
- {
- get { return this.skipBios; }
- set { this.skipBios = value; }
- }
-
- public GbaManager(CoreComm comm)
- {
- _corecomm = comm;
-
- this.memory = new Memory();
- this.arm7 = new Arm7Processor(this.memory);
- this.videoManager = new VideoManager(this);
- this.videoManager.Memory = this.memory;
- this.soundManager = new SoundManager(this.memory, 44100);
-
- this.framesRendered = 0;
- Renderer renderer = new Renderer();
- renderer.Initialize(null);
- VideoManager.Renderer = renderer;
-
- videoManager.Presenter = delegate(uint[] data)
- {
- Buffer.BlockCopy(data, 0, this.vbuf, 0, 240 * 160 * 4);
- };
- }
-
- public void Load(byte[] rom, byte[] bios)
- {
- LoadBios(bios);
- LoadRom(rom);
- }
-
- public void Reset()
- {
- //this.Halt();
-
- this.arm7.Reset(this.skipBios);
- this.memory.Reset();
- this.videoManager.Reset();
- }
-
- public void LoadState(BinaryReader state)
- {
- }
-
- public void SaveState(BinaryWriter state)
- {
- state.Write("GARB");
- }
-
- public void LoadBios(byte[] biosRom)
- {
- this.memory.LoadBios(biosRom);
-
- if (this.onCpuUpdate != null)
- {
- this.onCpuUpdate(this.arm7, this.memory);
- }
- }
-
- public void LoadRom(byte[] cartRom)
- {
- //this.Halt();
-
- /*
- byte[] logo = new byte[]
- {
- 0x24,0xff,0xae,0x51,0x69,0x9a,0xa2,0x21,
- 0x3d,0x84,0x82,0x0a,0x84,0xe4,0x09,0xad,
- 0x11,0x24,0x8b,0x98,0xc0,0x81,0x7f,0x21,
- 0xa3,0x52,0xbe,0x19,0x93,0x09,0xce,0x20,
- 0x10,0x46,0x4a,0x4a,0xf8,0x27,0x31,0xec,
- 0x58,0xc7,0xe8,0x33,0x82,0xe3,0xce,0xbf,
- 0x85,0xf4,0xdf,0x94,0xce,0x4b,0x09,0xc1,
- 0x94,0x56,0x8a,0xc0,0x13,0x72,0xa7,0xfc,
- 0x9f,0x84,0x4d,0x73,0xa3,0xca,0x9a,0x61,
- 0x58,0x97,0xa3,0x27,0xfc,0x03,0x98,0x76,
- 0x23,0x1d,0xc7,0x61,0x03,0x04,0xae,0x56,
- 0xbf,0x38,0x84,0x00,0x40,0xa7,0x0e,0xfd,
- 0xff,0x52,0xfe,0x03,0x6f,0x95,0x30,0xf1,
- 0x97,0xfb,0xc0,0x85,0x60,0xd6,0x80,0x25,
- 0xa9,0x63,0xbe,0x03,0x01,0x4e,0x38,0xe2,
- 0xf9,0xa2,0x34,0xff,0xbb,0x3e,0x03,0x44,
- 0x78,0x00,0x90,0xcb,0x88,0x11,0x3a,0x94,
- 0x65,0xc0,0x7c,0x63,0x87,0xf0,0x3c,0xaf,
- 0xd6,0x25,0xe4,0x8b,0x38,0x0a,0xac,0x72,
- 0x21,0xd4,0xf8,0x07
- };
-
- Array.Copy(logo, 0, cartRom, 4, logo.Length);
- cartRom[0xB2] = 0x96;
- cartRom[0xBD] = 0;
- for (int i = 0xA0; i <= 0xBC; i++) cartRom[0xBD] = (byte)(cartRom[0xBD] - cartRom[i]);
- cartRom[0xBD] = (byte)((cartRom[0xBD] - 0x19) & 0xFF);
- */
- this.memory.LoadCartridge(cartRom);
-
- this.Reset();
-
- if (this.onCpuUpdate != null)
- {
- this.onCpuUpdate(this.arm7, this.memory);
- }
- }
-
- public void Step()
- {
- //this.Halt();
-
- this.arm7.Step();
-
- if (this.onCpuUpdate != null)
- {
- this.onCpuUpdate(this.arm7, this.memory);
- }
- }
-
- public void StepScanline()
- {
- //this.Halt();
-
- this.arm7.Execute(960);
- this.videoManager.RenderLine();
- this.videoManager.EnterHBlank(this.arm7);
- this.arm7.Execute(272);
- this.videoManager.LeaveHBlank(this.arm7);
-
- if (this.onCpuUpdate != null)
- {
- this.onCpuUpdate(this.arm7, this.memory);
- }
- }
-
- void UpdateInputState()
- {
- ushort ret = 0;
- if (_controller["Up"]) ret |= 64;
- if (_controller["Down"]) ret |= 128;
- if (_controller["Left"]) ret |= 32;
- if (_controller["Right"]) ret |= 16;
- if (_controller["Select"]) ret |= 4;
- if (_controller["Start"]) ret |= 8;
- if (_controller["B"]) ret |= 2;
- if (_controller["A"]) ret |= 1;
- if (_controller["L"]) ret |= 512;
- if (_controller["R"]) ret |= 256;
- ret ^= 0x3ff;
- KeyState = ret;
- }
-
- private void StepFrame()
- {
- UpdateInputState();
- if (_controller["Power"])
- Reset();
-
- int vramCycles = 0;
- bool inHblank = false;
-
- //HighPerformanceTimer profileTimer = new HighPerformanceTimer();
-
- while (true)
- {
-
-
- const int cycleStep = 123;
-
-
- if (vramCycles <= 0)
- {
- if (inHblank)
- {
- vramCycles += 960;
- bool HitVBlank = this.videoManager.LeaveHBlank(this.arm7);
- inHblank = false;
- if (HitVBlank)
- break;
- }
- else
- {
- vramCycles += 272;
- this.videoManager.RenderLine();
- this.videoManager.EnterHBlank(this.arm7);
- inHblank = true;
- }
- }
-
- this.arm7.Execute(cycleStep);
-#if ARM_DEBUG
- if (this.arm7.BreakpointHit)
- {
- this.waitingToHalt = true;
- Monitor.Wait(this);
- }
-#endif
- vramCycles -= cycleStep;
- this.arm7.FireIrq();
- }
-
-
- }
-
- IVideoProvider IEmulator.VideoProvider
- {
- get { return this; }
- }
-
- ISoundProvider IEmulator.SoundProvider
- {
- get { return null; }
- }
-
- ISyncSoundProvider IEmulator.SyncSoundProvider
- {
- get { return this; }
- }
-
- bool IEmulator.StartAsyncSound()
- {
- return false;
- }
-
- void IEmulator.EndAsyncSound()
- {
-
- }
-
- ControllerDefinition IEmulator.ControllerDefinition
- {
- get { return BizHawk.Emulation.Consoles.Nintendo.GBA.GBA.GBAController; }
- }
-
- IController _controller;
-
- IController IEmulator.Controller
- {
- get { return _controller; }
- set { _controller = value; }
- }
-
- void IEmulator.FrameAdvance(bool render, bool rendersound)
- {
- StepFrame();
- }
-
- int IEmulator.Frame
- {
- get { return 0; }
- }
-
- int IEmulator.LagCount
- {
- get
- {
- return 0;
- }
- set
- {
-
- }
- }
-
- bool IEmulator.IsLagFrame
- {
- get { return false; }
- }
-
- string IEmulator.SystemId
- {
- get { return "GBA"; }
- }
-
- bool IEmulator.DeterministicEmulation
- {
- get { return true; }
- }
-
- byte[] IEmulator.ReadSaveRam()
- {
- return new byte[0];
- }
-
- void IEmulator.StoreSaveRam(byte[] data)
- {
-
- }
-
- void IEmulator.ClearSaveRam()
- {
-
- }
-
- bool IEmulator.SaveRamModified
- {
- get
- {
- return false;
- }
- set
- {
-
- }
- }
-
- void IEmulator.ResetFrameCounter()
- {
-
- }
-
- void IEmulator.SaveStateText(TextWriter writer)
- {
-
- }
-
- void IEmulator.LoadStateText(TextReader reader)
- {
-
- }
-
- void IEmulator.SaveStateBinary(BinaryWriter writer)
- {
-
- }
-
- void IEmulator.LoadStateBinary(BinaryReader reader)
- {
-
- }
-
- byte[] IEmulator.SaveStateBinary()
- {
- return new byte[16];
- }
-
- CoreComm _corecomm;
-
- CoreComm IEmulator.CoreComm
- {
- get { return _corecomm; }
- }
-
- IList IEmulator.MemoryDomains
- {
- get { return new List(); }
- }
-
- MemoryDomain IEmulator.MainMemory
- {
- get { return null; }
- }
-
- void IDisposable.Dispose()
- {
-
- }
-
- int[] vbuf = new int[240 * 160];
- int[] IVideoProvider.GetVideoBuffer() { return vbuf; }
- int IVideoProvider.VirtualWidth { get { return 240; } }
- int IVideoProvider.BufferWidth { get { return 240; } }
- int IVideoProvider.BufferHeight { get { return 160; } }
- int IVideoProvider.BackgroundColor { get { return unchecked((int)0xff000000); } }
-
- void ISyncSoundProvider.GetSamples(out short[] samples, out int nsamp)
- {
- nsamp = soundManager.SamplesMixed / 2;
- samples = new short[nsamp * 2];
- soundManager.GetSamples(samples, nsamp * 2);
- }
-
- void ISyncSoundProvider.DiscardSamples()
- {
- // should implement
- }
- }
-}
diff --git a/attic/GarboDev/IRenderer.cs b/attic/GarboDev/IRenderer.cs
deleted file mode 100644
index 20fce17447..0000000000
--- a/attic/GarboDev/IRenderer.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace GarboDev
-{
- using System;
-
- public interface IRenderer
- {
- Memory Memory { set; }
- void Initialize(object data);
- void Reset();
- void RenderLine(int line);
- uint[] ShowFrame();
- }
-}
diff --git a/attic/GarboDev/Memory.cs b/attic/GarboDev/Memory.cs
deleted file mode 100644
index e10058db14..0000000000
--- a/attic/GarboDev/Memory.cs
+++ /dev/null
@@ -1,1981 +0,0 @@
-namespace GarboDev
-{
- using System;
- using System.Collections.Generic;
-
- public class Memory
- {
- public const uint REG_BASE = 0x4000000;
- public const uint PAL_BASE = 0x5000000;
- public const uint VRAM_BASE = 0x6000000;
- public const uint OAM_BASE = 0x7000000;
-
- public const uint DISPCNT = 0x0;
- public const uint DISPSTAT = 0x4;
- public const uint VCOUNT = 0x6;
-
- public const uint BG0CNT = 0x8;
- public const uint BG1CNT = 0xA;
- public const uint BG2CNT = 0xC;
- public const uint BG3CNT = 0xE;
-
- public const uint BG0HOFS = 0x10;
- public const uint BG0VOFS = 0x12;
- public const uint BG1HOFS = 0x14;
- public const uint BG1VOFS = 0x16;
- public const uint BG2HOFS = 0x18;
- public const uint BG2VOFS = 0x1A;
- public const uint BG3HOFS = 0x1C;
- public const uint BG3VOFS = 0x1E;
-
- public const uint BG2PA = 0x20;
- public const uint BG2PB = 0x22;
- public const uint BG2PC = 0x24;
- public const uint BG2PD = 0x26;
- public const uint BG2X_L = 0x28;
- public const uint BG2X_H = 0x2A;
- public const uint BG2Y_L = 0x2C;
- public const uint BG2Y_H = 0x2E;
- public const uint BG3PA = 0x30;
- public const uint BG3PB = 0x32;
- public const uint BG3PC = 0x34;
- public const uint BG3PD = 0x36;
- public const uint BG3X_L = 0x38;
- public const uint BG3X_H = 0x3A;
- public const uint BG3Y_L = 0x3C;
- public const uint BG3Y_H = 0x3E;
-
- public const uint WIN0H = 0x40;
- public const uint WIN1H = 0x42;
- public const uint WIN0V = 0x44;
- public const uint WIN1V = 0x46;
- public const uint WININ = 0x48;
- public const uint WINOUT = 0x4A;
-
- public const uint BLDCNT = 0x50;
- public const uint BLDALPHA = 0x52;
- public const uint BLDY = 0x54;
-
- public const uint SOUNDCNT_L = 0x80;
- public const uint SOUNDCNT_H = 0x82;
- public const uint SOUNDCNT_X = 0x84;
-
- public const uint FIFO_A_L = 0xA0;
- public const uint FIFO_A_H = 0xA2;
- public const uint FIFO_B_L = 0xA4;
- public const uint FIFO_B_H = 0xA6;
-
- public const uint DMA0SAD = 0xB0;
- public const uint DMA0DAD = 0xB4;
- public const uint DMA0CNT_L = 0xB8;
- public const uint DMA0CNT_H = 0xBA;
- public const uint DMA1SAD = 0xBC;
- public const uint DMA1DAD = 0xC0;
- public const uint DMA1CNT_L = 0xC4;
- public const uint DMA1CNT_H = 0xC6;
- public const uint DMA2SAD = 0xC8;
- public const uint DMA2DAD = 0xCC;
- public const uint DMA2CNT_L = 0xD0;
- public const uint DMA2CNT_H = 0xD2;
- public const uint DMA3SAD = 0xD4;
- public const uint DMA3DAD = 0xD8;
- public const uint DMA3CNT_L = 0xDC;
- public const uint DMA3CNT_H = 0xDE;
-
- public const uint TM0D = 0x100;
- public const uint TM0CNT = 0x102;
- public const uint TM1D = 0x104;
- public const uint TM1CNT = 0x106;
- public const uint TM2D = 0x108;
- public const uint TM2CNT = 0x10A;
- public const uint TM3D = 0x10C;
- public const uint TM3CNT = 0x10E;
-
- public const uint KEYINPUT = 0x130;
- public const uint KEYCNT = 0x132;
- public const uint IE = 0x200;
- public const uint IF = 0x202;
- public const uint IME = 0x208;
-
- public const uint HALTCNT = 0x300;
-
- private const uint biosRamMask = 0x3FFF;
- private const uint ewRamMask = 0x3FFFF;
- private const uint iwRamMask = 0x7FFF;
- private const uint ioRegMask = 0x4FF;
- private const uint vRamMask = 0x1FFFF;
- private const uint palRamMask = 0x3FF;
- private const uint oamRamMask = 0x3FF;
- private const uint sRamMask = 0xFFFF;
-
- private byte[] biosRam = new byte[Memory.biosRamMask + 1];
- private byte[] ewRam = new byte[Memory.ewRamMask + 1];
- private byte[] iwRam = new byte[Memory.iwRamMask + 1];
- private byte[] ioReg = new byte[Memory.ioRegMask + 1];
- private byte[] vRam = new byte[Memory.vRamMask + 1];
- private byte[] palRam = new byte[Memory.palRamMask + 1];
- private byte[] oamRam = new byte[Memory.oamRamMask + 1];
- private byte[] sRam = new byte[Memory.sRamMask + 1];
-
- public byte[] VideoRam
- {
- get
- {
- return this.vRam;
- }
- }
-
- public byte[] PaletteRam
- {
- get
- {
- return this.palRam;
- }
- }
-
- public byte[] OamRam
- {
- get
- {
- return this.oamRam;
- }
- }
-
- public byte[] IORam
- {
- get
- {
- return this.ioReg;
- }
- }
-
- private ushort keyState = 0x3FF;
-
- public ushort KeyState
- {
- get { return this.keyState; }
- set { this.keyState = value; }
- }
-
- private Arm7Processor processor = null;
- public Arm7Processor Processor
- {
- get { return this.processor; }
- set { this.processor = value; }
- }
-
- private SoundManager soundManager = null;
- public SoundManager SoundManager
- {
- get { return this.soundManager; }
- set { this.soundManager = value; }
- }
-
- private byte[] romBank1 = null;
- private byte[] romBank2 = null;
- private uint romBank1Mask = 0;
- private uint romBank2Mask = 0;
-
- private int[] bankSTimes = new int[0x10];
- private int[] bankNTimes = new int[0x10];
-
- private int waitCycles = 0;
-
- public int WaitCycles
- {
- get { int tmp = this.waitCycles; this.waitCycles = 0; return tmp; }
- }
-
- private bool inUnreadable = false;
-
- private delegate byte ReadU8Delegate(uint address);
- private delegate void WriteU8Delegate(uint address, byte value);
- private delegate ushort ReadU16Delegate(uint address);
- private delegate void WriteU16Delegate(uint address, ushort value);
- private delegate uint ReadU32Delegate(uint address);
- private delegate void WriteU32Delegate(uint address, uint value);
-
- private ReadU8Delegate[] ReadU8Funcs = null;
- private WriteU8Delegate[] WriteU8Funcs = null;
- private ReadU16Delegate[] ReadU16Funcs = null;
- private WriteU16Delegate[] WriteU16Funcs = null;
- private ReadU32Delegate[] ReadU32Funcs = null;
- private WriteU32Delegate[] WriteU32Funcs = null;
-
- private uint[,] dmaRegs = new uint[4, 4];
- private uint[] timerCnt = new uint[4];
- private int[] bgx = new int[2], bgy = new int[2];
-
- public uint[] TimerCnt
- {
- get { return this.timerCnt; }
- }
-
- public int[] Bgx
- {
- get { return this.bgx; }
- }
-
- public int[] Bgy
- {
- get { return this.bgy; }
- }
-
- public Memory()
- {
- this.ReadU8Funcs = new ReadU8Delegate[]
- {
- this.ReadBiosRam8,
- this.ReadNop8,
- this.ReadEwRam8,
- this.ReadIwRam8,
- this.ReadIO8,
- this.ReadPalRam8,
- this.ReadVRam8,
- this.ReadOamRam8,
- this.ReadNop8,
- this.ReadNop8,
- this.ReadNop8,
- this.ReadNop8,
- this.ReadNop8,
- this.ReadNop8,
- this.ReadSRam8,
- this.ReadNop8
- };
-
- this.WriteU8Funcs = new WriteU8Delegate[]
- {
- this.WriteNop8,
- this.WriteNop8,
- this.WriteEwRam8,
- this.WriteIwRam8,
- this.WriteIO8,
- this.WritePalRam8,
- this.WriteVRam8,
- this.WriteOamRam8,
- this.WriteNop8,
- this.WriteNop8,
- this.WriteNop8,
- this.WriteNop8,
- this.WriteNop8,
- this.WriteNop8,
- this.WriteSRam8,
- this.WriteNop8
- };
-
- this.ReadU16Funcs = new ReadU16Delegate[]
- {
- this.ReadBiosRam16,
- this.ReadNop16,
- this.ReadEwRam16,
- this.ReadIwRam16,
- this.ReadIO16,
- this.ReadPalRam16,
- this.ReadVRam16,
- this.ReadOamRam16,
- this.ReadNop16,
- this.ReadNop16,
- this.ReadNop16,
- this.ReadNop16,
- this.ReadNop16,
- this.ReadNop16,
- this.ReadSRam16,
- this.ReadNop16
- };
-
- this.WriteU16Funcs = new WriteU16Delegate[]
- {
- this.WriteNop16,
- this.WriteNop16,
- this.WriteEwRam16,
- this.WriteIwRam16,
- this.WriteIO16,
- this.WritePalRam16,
- this.WriteVRam16,
- this.WriteOamRam16,
- this.WriteNop16,
- this.WriteNop16,
- this.WriteNop16,
- this.WriteNop16,
- this.WriteNop16,
- this.WriteNop16,
- this.WriteSRam16,
- this.WriteNop16
- };
-
- this.ReadU32Funcs = new ReadU32Delegate[]
- {
- this.ReadBiosRam32,
- this.ReadNop32,
- this.ReadEwRam32,
- this.ReadIwRam32,
- this.ReadIO32,
- this.ReadPalRam32,
- this.ReadVRam32,
- this.ReadOamRam32,
- this.ReadNop32,
- this.ReadNop32,
- this.ReadNop32,
- this.ReadNop32,
- this.ReadNop32,
- this.ReadNop32,
- this.ReadSRam32,
- this.ReadNop32
- };
-
- this.WriteU32Funcs = new WriteU32Delegate[]
- {
- this.WriteNop32,
- this.WriteNop32,
- this.WriteEwRam32,
- this.WriteIwRam32,
- this.WriteIO32,
- this.WritePalRam32,
- this.WriteVRam32,
- this.WriteOamRam32,
- this.WriteNop32,
- this.WriteNop32,
- this.WriteNop32,
- this.WriteNop32,
- this.WriteNop32,
- this.WriteNop32,
- this.WriteSRam32,
- this.WriteNop32
- };
- }
-
- public void Reset()
- {
- Array.Clear(this.ewRam, 0, this.ewRam.Length);
- Array.Clear(this.iwRam, 0, this.iwRam.Length);
- Array.Clear(this.ioReg, 0, this.ioReg.Length);
- Array.Clear(this.vRam, 0, this.vRam.Length);
- Array.Clear(this.palRam, 0, this.palRam.Length);
- Array.Clear(this.oamRam, 0, this.oamRam.Length);
- Array.Clear(this.sRam, 0, this.sRam.Length);
-
- Memory.WriteU16(this.ioReg, Memory.BG2PA, 0x0100);
- Memory.WriteU16(this.ioReg, Memory.BG2PD, 0x0100);
- Memory.WriteU16(this.ioReg, Memory.BG3PA, 0x0100);
- Memory.WriteU16(this.ioReg, Memory.BG3PD, 0x0100);
- }
-
- public void HBlankDma()
- {
- for (int i = 0; i < 4; i++)
- {
- if (((this.dmaRegs[i, 3] >> 12) & 0x3) == 2)
- {
- this.DmaTransfer(i);
- }
- }
- }
-
- public void VBlankDma()
- {
- for (int i = 0; i < 4; i++)
- {
- if (((this.dmaRegs[i, 3] >> 12) & 0x3) == 1)
- {
- this.DmaTransfer(i);
- }
- }
- }
-
- public void FifoDma(int channel)
- {
- if (((this.dmaRegs[channel, 3] >> 12) & 0x3) == 0x3)
- {
- this.DmaTransfer(channel);
- }
- }
-
- public void DmaTransfer(int channel)
- {
- // Check if DMA is enabled
- if ((this.dmaRegs[channel, 3] & (1 << 15)) != 0)
- {
- bool wideTransfer = (this.dmaRegs[channel, 3] & (1 << 10)) != 0;
-
- uint srcDirection = 0, destDirection = 0;
- bool reload = false;
-
- switch ((this.dmaRegs[channel, 3] >> 5) & 0x3)
- {
- case 0: destDirection = 1; break;
- case 1: destDirection = 0xFFFFFFFF; break;
- case 2: destDirection = 0; break;
- case 3: destDirection = 1; reload = true; break;
- }
-
- switch ((this.dmaRegs[channel, 3] >> 7) & 0x3)
- {
- case 0: srcDirection = 1; break;
- case 1: srcDirection = 0xFFFFFFFF; break;
- case 2: srcDirection = 0; break;
- case 3: if (channel == 3)
- {
- // TODO
- return;
- }
- throw new Exception("Unhandled DMA mode.");
- }
-
- int numElements = (int)this.dmaRegs[channel, 2];
- if (numElements == 0) numElements = 0x4000;
-
- if (((this.dmaRegs[channel, 3] >> 12) & 0x3) == 0x3)
- {
- // Sound FIFO mode
- wideTransfer = true;
- destDirection = 0;
- numElements = 4;
- reload = false;
- }
-
- if (wideTransfer)
- {
- srcDirection *= 4;
- destDirection *= 4;
- while (numElements-- > 0)
- {
- this.WriteU32(this.dmaRegs[channel, 1], this.ReadU32(this.dmaRegs[channel, 0]));
- this.dmaRegs[channel, 1] += destDirection;
- this.dmaRegs[channel, 0] += srcDirection;
- }
- }
- else
- {
- srcDirection *= 2;
- destDirection *= 2;
- while (numElements-- > 0)
- {
- this.WriteU16(this.dmaRegs[channel, 1], this.ReadU16(this.dmaRegs[channel, 0]));
- this.dmaRegs[channel, 1] += destDirection;
- this.dmaRegs[channel, 0] += srcDirection;
- }
- }
-
- // If not a repeating DMA, then disable the DMA
- if ((this.dmaRegs[channel, 3] & (1 << 9)) == 0)
- {
- this.dmaRegs[channel, 3] &= 0x7FFF;
- }
- else
- {
- // Reload dest and count
- switch (channel)
- {
- case 0:
- if (reload) this.dmaRegs[0, 1] = Memory.ReadU32(this.ioReg, Memory.DMA0DAD) & 0x07FFFFFF;
- this.dmaRegs[0, 2] = Memory.ReadU16(this.ioReg, Memory.DMA0CNT_L);
- break;
- case 1:
- if (reload) this.dmaRegs[1, 1] = Memory.ReadU32(this.ioReg, Memory.DMA1DAD) & 0x07FFFFFF;
- this.dmaRegs[1, 2] = Memory.ReadU16(this.ioReg, Memory.DMA1CNT_L);
- break;
- case 2:
- if (reload) this.dmaRegs[2, 1] = Memory.ReadU32(this.ioReg, Memory.DMA2DAD) & 0x07FFFFFF;
- this.dmaRegs[2, 2] = Memory.ReadU16(this.ioReg, Memory.DMA2CNT_L);
- break;
- case 3:
- if (reload) this.dmaRegs[3, 1] = Memory.ReadU32(this.ioReg, Memory.DMA3DAD) & 0x0FFFFFFF;
- this.dmaRegs[3, 2] = Memory.ReadU16(this.ioReg, Memory.DMA3CNT_L);
- break;
- }
- }
-
- if ((this.dmaRegs[channel, 3] & (1 << 14)) != 0)
- {
- this.processor.RequestIrq(8 + channel);
- }
- }
- }
-
- public void WriteDmaControl(int channel)
- {
- switch (channel)
- {
- case 0:
- if (((this.dmaRegs[0, 3] ^ Memory.ReadU16(this.ioReg, Memory.DMA0CNT_H)) & (1 << 15)) == 0) return;
- this.dmaRegs[0, 0] = Memory.ReadU32(this.ioReg, Memory.DMA0SAD) & 0x07FFFFFF;
- this.dmaRegs[0, 1] = Memory.ReadU32(this.ioReg, Memory.DMA0DAD) & 0x07FFFFFF;
- this.dmaRegs[0, 2] = Memory.ReadU16(this.ioReg, Memory.DMA0CNT_L);
- this.dmaRegs[0, 3] = Memory.ReadU16(this.ioReg, Memory.DMA0CNT_H);
- break;
- case 1:
- if (((this.dmaRegs[1, 3] ^ Memory.ReadU16(this.ioReg, Memory.DMA1CNT_H)) & (1 << 15)) == 0) return;
- this.dmaRegs[1, 0] = Memory.ReadU32(this.ioReg, Memory.DMA1SAD) & 0x0FFFFFFF;
- this.dmaRegs[1, 1] = Memory.ReadU32(this.ioReg, Memory.DMA1DAD) & 0x07FFFFFF;
- this.dmaRegs[1, 2] = Memory.ReadU16(this.ioReg, Memory.DMA1CNT_L);
- this.dmaRegs[1, 3] = Memory.ReadU16(this.ioReg, Memory.DMA1CNT_H);
- break;
- case 2:
- if (((this.dmaRegs[2, 3] ^ Memory.ReadU16(this.ioReg, Memory.DMA2CNT_H)) & (1 << 15)) == 0) return;
- this.dmaRegs[2, 0] = Memory.ReadU32(this.ioReg, Memory.DMA2SAD) & 0x0FFFFFFF;
- this.dmaRegs[2, 1] = Memory.ReadU32(this.ioReg, Memory.DMA2DAD) & 0x07FFFFFF;
- this.dmaRegs[2, 2] = Memory.ReadU16(this.ioReg, Memory.DMA2CNT_L);
- this.dmaRegs[2, 3] = Memory.ReadU16(this.ioReg, Memory.DMA2CNT_H);
- break;
- case 3:
- if (((this.dmaRegs[3, 3] ^ Memory.ReadU16(this.ioReg, Memory.DMA3CNT_H)) & (1 << 15)) == 0) return;
- this.dmaRegs[3, 0] = Memory.ReadU32(this.ioReg, Memory.DMA3SAD) & 0x0FFFFFFF;
- this.dmaRegs[3, 1] = Memory.ReadU32(this.ioReg, Memory.DMA3DAD) & 0x0FFFFFFF;
- this.dmaRegs[3, 2] = Memory.ReadU16(this.ioReg, Memory.DMA3CNT_L);
- this.dmaRegs[3, 3] = Memory.ReadU16(this.ioReg, Memory.DMA3CNT_H);
- break;
- }
-
- // Channel start timing
- switch ((this.dmaRegs[channel, 3] >> 12) & 0x3)
- {
- case 0:
- // Start immediately
- this.DmaTransfer(channel);
- break;
- case 1:
- case 2:
- // Hblank and Vblank DMA's
- break;
- case 3:
- // TODO (DMA sound)
- return;
- }
- }
-
- private void WriteTimerControl(int timer, ushort newCnt)
- {
- ushort control = Memory.ReadU16(this.ioReg, Memory.TM0CNT + (uint)(timer * 4));
- uint count = Memory.ReadU16(this.ioReg, Memory.TM0D + (uint)(timer * 4));
-
- if ((newCnt & (1 << 7)) != 0 && (control & (1 << 7)) == 0)
- {
- this.timerCnt[timer] = count << 10;
- }
- }
-
- #region Read/Write Helpers
- public static ushort ReadU16(byte[] array, uint position)
- {
- return (ushort)(array[position] | (array[position + 1] << 8));
- }
-
- public static uint ReadU32(byte[] array, uint position)
- {
- return (uint)(array[position] | (array[position + 1] << 8) |
- (array[position + 2] << 16) | (array[position + 3] << 24));
- }
-
- public static void WriteU16(byte[] array, uint position, ushort value)
- {
- array[position] = (byte)(value & 0xff);
- array[position + 1] = (byte)(value >> 8);
- }
-
- public static void WriteU32(byte[] array, uint position, uint value)
- {
- array[position] = (byte)(value & 0xff);
- array[position + 1] = (byte)((value >> 8) & 0xff);
- array[position + 2] = (byte)((value >> 16) & 0xff);
- array[position + 3] = (byte)(value >> 24);
- }
- #endregion
-
- #region Memory Reads
- private uint ReadUnreadable()
- {
- if (this.inUnreadable)
- {
- return 0;
- }
-
- this.inUnreadable = true;
-
- uint res;
-
- if (this.processor.ArmState)
- {
- res = this.ReadU32(this.processor.Registers[15]);
- }
- else
- {
- ushort val = this.ReadU16(this.processor.Registers[15]);
- res = (uint)(val | (val << 16));
- }
-
- this.inUnreadable = false;
-
- return res;
- }
-
- private byte ReadNop8(uint address)
- {
- return (byte)(this.ReadUnreadable() & 0xFF);
- }
-
- private ushort ReadNop16(uint address)
- {
- return (ushort)(this.ReadUnreadable() & 0xFFFF);
- }
-
- private uint ReadNop32(uint address)
- {
- return this.ReadUnreadable();
- }
-
- private byte ReadBiosRam8(uint address)
- {
- this.waitCycles++;
- if (this.processor.Registers[15] < 0x01000000)
- {
- return this.biosRam[address & Memory.biosRamMask];
- }
- return (byte)(this.ReadUnreadable() & 0xFF);
- }
-
- private ushort ReadBiosRam16(uint address)
- {
- this.waitCycles++;
- if (this.processor.Registers[15] < 0x01000000)
- {
- return Memory.ReadU16(this.biosRam, address & Memory.biosRamMask);
- }
- return (ushort)(this.ReadUnreadable() & 0xFFFF);
- }
-
- private uint ReadBiosRam32(uint address)
- {
- this.waitCycles++;
- if (this.processor.Registers[15] < 0x01000000)
- {
- return Memory.ReadU32(this.biosRam, address & Memory.biosRamMask);
- }
- return this.ReadUnreadable();
- }
-
- private byte ReadEwRam8(uint address)
- {
- this.waitCycles += 3;
- return this.ewRam[address & Memory.ewRamMask];
- }
-
- private ushort ReadEwRam16(uint address)
- {
- this.waitCycles += 3;
- return Memory.ReadU16(this.ewRam, address & Memory.ewRamMask);
- }
-
- private uint ReadEwRam32(uint address)
- {
- this.waitCycles += 6;
- return Memory.ReadU32(this.ewRam, address & Memory.ewRamMask);
- }
-
- private byte ReadIwRam8(uint address)
- {
- this.waitCycles++;
- return this.iwRam[address & Memory.iwRamMask];
- }
-
- private ushort ReadIwRam16(uint address)
- {
- this.waitCycles++;
- return Memory.ReadU16(this.iwRam, address & Memory.iwRamMask);
- }
-
- private uint ReadIwRam32(uint address)
- {
- this.waitCycles++;
- return Memory.ReadU32(this.iwRam, address & Memory.iwRamMask);
- }
-
- private byte ReadIO8(uint address)
- {
- this.waitCycles++;
- address &= 0xFFFFFF;
- if (address >= Memory.ioRegMask) return 0;
-
- switch (address)
- {
- case KEYINPUT:
- return (byte)(this.keyState & 0xFF);
- case KEYINPUT + 1:
- return (byte)(this.keyState >> 8);
-
- case DMA0CNT_H:
- return (byte)(this.dmaRegs[0, 3] & 0xFF);
- case DMA0CNT_H + 1:
- return (byte)(this.dmaRegs[0, 3] >> 8);
- case DMA1CNT_H:
- return (byte)(this.dmaRegs[1, 3] & 0xFF);
- case DMA1CNT_H + 1:
- return (byte)(this.dmaRegs[1, 3] >> 8);
- case DMA2CNT_H:
- return (byte)(this.dmaRegs[2, 3] & 0xFF);
- case DMA2CNT_H + 1:
- return (byte)(this.dmaRegs[2, 3] >> 8);
- case DMA3CNT_H:
- return (byte)(this.dmaRegs[3, 3] & 0xFF);
- case DMA3CNT_H + 1:
- return (byte)(this.dmaRegs[3, 3] >> 8);
-
- case TM0D:
- this.processor.UpdateTimers();
- return (byte)((this.timerCnt[0] >> 10) & 0xFF);
- case TM0D + 1:
- this.processor.UpdateTimers();
- return (byte)((this.timerCnt[0] >> 10) >> 8);
- case TM1D:
- this.processor.UpdateTimers();
- return (byte)((this.timerCnt[1] >> 10) & 0xFF);
- case TM1D + 1:
- this.processor.UpdateTimers();
- return (byte)((this.timerCnt[1] >> 10) >> 8);
- case TM2D:
- this.processor.UpdateTimers();
- return (byte)((this.timerCnt[2] >> 10) & 0xFF);
- case TM2D + 1:
- this.processor.UpdateTimers();
- return (byte)((this.timerCnt[2] >> 10) >> 8);
- case TM3D:
- this.processor.UpdateTimers();
- return (byte)((this.timerCnt[3] >> 10) & 0xFF);
- case TM3D + 1:
- this.processor.UpdateTimers();
- return (byte)((this.timerCnt[3] >> 10) >> 8);
-
- default:
- return this.ioReg[address];
- }
- }
-
- private ushort ReadIO16(uint address)
- {
- this.waitCycles++;
- address &= 0xFFFFFF;
- if (address >= Memory.ioRegMask) return 0;
-
- switch (address)
- {
- case KEYINPUT:
- return this.keyState;
-
- case DMA0CNT_H:
- return (ushort)this.dmaRegs[0, 3];
- case DMA1CNT_H:
- return (ushort)this.dmaRegs[1, 3];
- case DMA2CNT_H:
- return (ushort)this.dmaRegs[2, 3];
- case DMA3CNT_H:
- return (ushort)this.dmaRegs[3, 3];
-
- case TM0D:
- this.processor.UpdateTimers();
- return (ushort)((this.timerCnt[0] >> 10) & 0xFFFF);
- case TM1D:
- this.processor.UpdateTimers();
- return (ushort)((this.timerCnt[1] >> 10) & 0xFFFF);
- case TM2D:
- this.processor.UpdateTimers();
- return (ushort)((this.timerCnt[2] >> 10) & 0xFFFF);
- case TM3D:
- this.processor.UpdateTimers();
- return (ushort)((this.timerCnt[3] >> 10) & 0xFFFF);
-
- default:
- return Memory.ReadU16(this.ioReg, address);
- }
- }
-
- private uint ReadIO32(uint address)
- {
- this.waitCycles++;
- address &= 0xFFFFFF;
- if (address >= Memory.ioRegMask) return 0;
-
- switch (address)
- {
- case KEYINPUT:
- return this.keyState | ((uint)Memory.ReadU16(this.ioReg, address + 0x2) << 16);
-
- case DMA0CNT_L:
- return (uint)Memory.ReadU16(this.ioReg, address) | (this.dmaRegs[0, 3] << 16);
- case DMA1CNT_L:
- return (uint)Memory.ReadU16(this.ioReg, address) | (this.dmaRegs[1, 3] << 16);
- case DMA2CNT_L:
- return (uint)Memory.ReadU16(this.ioReg, address) | (this.dmaRegs[2, 3] << 16);
- case DMA3CNT_L:
- return (uint)Memory.ReadU16(this.ioReg, address) | (this.dmaRegs[3, 3] << 16);
-
- case TM0D:
- this.processor.UpdateTimers();
- return (uint)(((this.timerCnt[0] >> 10) & 0xFFFF) | (uint)(Memory.ReadU16(this.ioReg, address + 2) << 16));
- case TM1D:
- this.processor.UpdateTimers();
- return (uint)(((this.timerCnt[1] >> 10) & 0xFFFF) | (uint)(Memory.ReadU16(this.ioReg, address + 2) << 16));
- case TM2D:
- this.processor.UpdateTimers();
- return (uint)(((this.timerCnt[2] >> 10) & 0xFFFF) | (uint)(Memory.ReadU16(this.ioReg, address + 2) << 16));
- case TM3D:
- this.processor.UpdateTimers();
- return (uint)(((this.timerCnt[3] >> 10) & 0xFFFF) | (uint)(Memory.ReadU16(this.ioReg, address + 2) << 16));
-
- default:
- return Memory.ReadU32(this.ioReg, address);
- }
- }
-
- private byte ReadPalRam8(uint address)
- {
- this.waitCycles++;
- return this.palRam[address & Memory.palRamMask];
- }
-
- private ushort ReadPalRam16(uint address)
- {
- this.waitCycles++;
- return Memory.ReadU16(this.palRam, address & Memory.palRamMask);
- }
-
- private uint ReadPalRam32(uint address)
- {
- this.waitCycles += 2;
- return Memory.ReadU32(this.palRam, address & Memory.palRamMask);
- }
-
- private byte ReadVRam8(uint address)
- {
- this.waitCycles++;
- address &= Memory.vRamMask;
- if (address > 0x17FFF) address = 0x10000 + ((address - 0x17FFF) & 0x7FFF);
- return this.vRam[address];
- }
-
- private ushort ReadVRam16(uint address)
- {
- this.waitCycles++;
- address &= Memory.vRamMask;
- if (address > 0x17FFF) address = 0x10000 + ((address - 0x17FFF) & 0x7FFF);
- return Memory.ReadU16(this.vRam, address);
- }
-
- private uint ReadVRam32(uint address)
- {
- this.waitCycles += 2;
- address &= Memory.vRamMask;
- if (address > 0x17FFF) address = 0x10000 + ((address - 0x17FFF) & 0x7FFF);
- return Memory.ReadU32(this.vRam, address & Memory.vRamMask);
- }
-
- private byte ReadOamRam8(uint address)
- {
- this.waitCycles++;
- return this.oamRam[address & Memory.oamRamMask];
- }
-
- private ushort ReadOamRam16(uint address)
- {
- this.waitCycles++;
- return Memory.ReadU16(this.oamRam, address & Memory.oamRamMask);
- }
-
- private uint ReadOamRam32(uint address)
- {
- this.waitCycles++;
- return Memory.ReadU32(this.oamRam, address & Memory.oamRamMask);
- }
-
- private byte ReadRom1_8(uint address)
- {
- this.waitCycles += this.bankSTimes[(address >> 24) & 0xf];
- return this.romBank1[address & this.romBank1Mask];
- }
-
- private ushort ReadRom1_16(uint address)
- {
- this.waitCycles += this.bankSTimes[(address >> 24) & 0xf];
- return Memory.ReadU16(this.romBank1, address & this.romBank1Mask);
- }
-
- private uint ReadRom1_32(uint address)
- {
- this.waitCycles += this.bankSTimes[(address >> 24) & 0xf] * 2 + 1;
- return Memory.ReadU32(this.romBank1, address & this.romBank1Mask);
- }
-
- private byte ReadRom2_8(uint address)
- {
- this.waitCycles += this.bankSTimes[(address >> 24) & 0xf];
- return this.romBank2[address & this.romBank2Mask];
- }
-
- private ushort ReadRom2_16(uint address)
- {
- this.waitCycles += this.bankSTimes[(address >> 24) & 0xf];
- return Memory.ReadU16(this.romBank2, address & this.romBank2Mask);
- }
-
- private uint ReadRom2_32(uint address)
- {
- this.waitCycles += this.bankSTimes[(address >> 24) & 0xf] * 2 + 1;
- return Memory.ReadU32(this.romBank2, address & this.romBank2Mask);
- }
-
- private byte ReadSRam8(uint address)
- {
- return this.sRam[address & Memory.sRamMask];
- }
-
- private ushort ReadSRam16(uint address)
- {
- // TODO
- return 0;
- }
-
- private uint ReadSRam32(uint address)
- {
- // TODO
- return 0;
- }
- #endregion
-
- #region Memory Writes
- private void WriteNop8(uint address, byte value)
- {
- }
-
- private void WriteNop16(uint address, ushort value)
- {
- }
-
- private void WriteNop32(uint address, uint value)
- {
- }
-
- private void WriteEwRam8(uint address, byte value)
- {
- this.waitCycles += 3;
- this.ewRam[address & Memory.ewRamMask] = value;
- }
-
- private void WriteEwRam16(uint address, ushort value)
- {
- this.waitCycles += 3;
- Memory.WriteU16(this.ewRam, address & Memory.ewRamMask, value);
- }
-
- private void WriteEwRam32(uint address, uint value)
- {
- this.waitCycles += 6;
- Memory.WriteU32(this.ewRam, address & Memory.ewRamMask, value);
- }
-
- private void WriteIwRam8(uint address, byte value)
- {
- this.waitCycles++;
- this.iwRam[address & Memory.iwRamMask] = value;
- }
-
- private void WriteIwRam16(uint address, ushort value)
- {
- this.waitCycles++;
- Memory.WriteU16(this.iwRam, address & Memory.iwRamMask, value);
- }
-
- private void WriteIwRam32(uint address, uint value)
- {
- this.waitCycles++;
- Memory.WriteU32(this.iwRam, address & Memory.iwRamMask, value);
- }
-
- private void WriteIO8(uint address, byte value)
- {
- this.waitCycles++;
- address &= 0xFFFFFF;
- if (address >= Memory.ioRegMask) return;
-
- switch (address)
- {
- case BG2X_L:
- case BG2X_L + 1:
- case BG2X_L + 2:
- case BG2X_L + 3:
- {
- this.ioReg[address] = value;
- uint tmp = Memory.ReadU32(this.ioReg, BG2X_L);
- if ((tmp & (1 << 27)) != 0) tmp |= 0xF0000000;
- Memory.WriteU32(this.ioReg, BG2X_L, tmp);
-
- this.bgx[0] = (int)tmp;
- }
- break;
-
- case BG3X_L:
- case BG3X_L + 1:
- case BG3X_L + 2:
- case BG3X_L + 3:
- {
- this.ioReg[address] = value;
- uint tmp = Memory.ReadU32(this.ioReg, BG3X_L);
- if ((tmp & (1 << 27)) != 0) tmp |= 0xF0000000;
- Memory.WriteU32(this.ioReg, BG3X_L, tmp);
-
- this.bgx[1] = (int)tmp;
- }
- break;
-
- case BG2Y_L:
- case BG2Y_L + 1:
- case BG2Y_L + 2:
- case BG2Y_L + 3:
- {
- this.ioReg[address] = value;
- uint tmp = Memory.ReadU32(this.ioReg, BG2Y_L);
- if ((tmp & (1 << 27)) != 0) tmp |= 0xF0000000;
- Memory.WriteU32(this.ioReg, BG2Y_L, tmp);
-
- this.bgy[0] = (int)tmp;
- }
- break;
-
- case BG3Y_L:
- case BG3Y_L + 1:
- case BG3Y_L + 2:
- case BG3Y_L + 3:
- {
- this.ioReg[address] = value;
- uint tmp = Memory.ReadU32(this.ioReg, BG3Y_L);
- if ((tmp & (1 << 27)) != 0) tmp |= 0xF0000000;
- Memory.WriteU32(this.ioReg, BG3Y_L, tmp);
-
- this.bgy[1] = (int)tmp;
- }
- break;
-
- case DMA0CNT_H:
- case DMA0CNT_H + 1:
- this.ioReg[address] = value;
- this.WriteDmaControl(0);
- break;
-
- case DMA1CNT_H:
- case DMA1CNT_H + 1:
- this.ioReg[address] = value;
- this.WriteDmaControl(1);
- break;
-
- case DMA2CNT_H:
- case DMA2CNT_H + 1:
- this.ioReg[address] = value;
- this.WriteDmaControl(2);
- break;
-
- case DMA3CNT_H:
- case DMA3CNT_H + 1:
- this.ioReg[address] = value;
- this.WriteDmaControl(3);
- break;
-
- case TM0CNT:
- case TM0CNT + 1:
- {
- ushort oldCnt = Memory.ReadU16(this.ioReg, TM0CNT);
- this.ioReg[address] = value;
- this.WriteTimerControl(0, oldCnt);
- }
- break;
-
- case TM1CNT:
- case TM1CNT + 1:
- {
- ushort oldCnt = Memory.ReadU16(this.ioReg, TM1CNT);
- this.ioReg[address] = value;
- this.WriteTimerControl(1, oldCnt);
- }
- break;
-
- case TM2CNT:
- case TM2CNT + 1:
- {
- ushort oldCnt = Memory.ReadU16(this.ioReg, TM2CNT);
- this.ioReg[address] = value;
- this.WriteTimerControl(2, oldCnt);
- }
- break;
-
- case TM3CNT:
- case TM3CNT + 1:
- {
- ushort oldCnt = Memory.ReadU16(this.ioReg, TM3CNT);
- this.ioReg[address] = value;
- this.WriteTimerControl(3, oldCnt);
- }
- break;
-
- case FIFO_A_L:
- case FIFO_A_L+1:
- case FIFO_A_H:
- case FIFO_A_H+1:
- this.ioReg[address] = value;
- this.soundManager.IncrementFifoA();
- break;
-
- case FIFO_B_L:
- case FIFO_B_L + 1:
- case FIFO_B_H:
- case FIFO_B_H + 1:
- this.ioReg[address] = value;
- this.soundManager.IncrementFifoB();
- break;
-
- case IF:
- case IF + 1:
- this.ioReg[address] &= (byte)~value;
- break;
-
- case HALTCNT + 1:
- this.ioReg[address] = value;
- this.processor.Halt();
- break;
-
- default:
- this.ioReg[address] = value;
- break;
- }
- }
-
- private void WriteIO16(uint address, ushort value)
- {
- this.waitCycles++;
- address &= 0xFFFFFF;
- if (address >= Memory.ioRegMask) return;
-
- switch (address)
- {
- case BG2X_L:
- case BG2X_L + 2:
- {
- Memory.WriteU16(this.ioReg, address, value);
- uint tmp = Memory.ReadU32(this.ioReg, BG2X_L);
- if ((tmp & (1 << 27)) != 0) tmp |= 0xF0000000;
- Memory.WriteU32(this.ioReg, BG2X_L, tmp);
-
- this.bgx[0] = (int)tmp;
- }
- break;
-
- case BG3X_L:
- case BG3X_L + 2:
- {
- Memory.WriteU16(this.ioReg, address, value);
- uint tmp = Memory.ReadU32(this.ioReg, BG3X_L);
- if ((tmp & (1 << 27)) != 0) tmp |= 0xF0000000;
- Memory.WriteU32(this.ioReg, BG3X_L, tmp);
-
- this.bgx[1] = (int)tmp;
- }
- break;
-
- case BG2Y_L:
- case BG2Y_L + 2:
- {
- Memory.WriteU16(this.ioReg, address, value);
- uint tmp = Memory.ReadU32(this.ioReg, BG2Y_L);
- if ((tmp & (1 << 27)) != 0) tmp |= 0xF0000000;
- Memory.WriteU32(this.ioReg, BG2Y_L, tmp);
-
- this.bgy[0] = (int)tmp;
- }
- break;
-
- case BG3Y_L:
- case BG3Y_L + 2:
- {
- Memory.WriteU16(this.ioReg, address, value);
- uint tmp = Memory.ReadU32(this.ioReg, BG3Y_L);
- if ((tmp & (1 << 27)) != 0) tmp |= 0xF0000000;
- Memory.WriteU32(this.ioReg, BG3Y_L, tmp);
-
- this.bgy[1] = (int)tmp;
- }
- break;
-
- case DMA0CNT_H:
- Memory.WriteU16(this.ioReg, address, value);
- this.WriteDmaControl(0);
- break;
-
- case DMA1CNT_H:
- Memory.WriteU16(this.ioReg, address, value);
- this.WriteDmaControl(1);
- break;
-
- case DMA2CNT_H:
- Memory.WriteU16(this.ioReg, address, value);
- this.WriteDmaControl(2);
- break;
-
- case DMA3CNT_H:
- Memory.WriteU16(this.ioReg, address, value);
- this.WriteDmaControl(3);
- break;
-
- case TM0CNT:
- {
- ushort oldCnt = Memory.ReadU16(this.ioReg, TM0CNT);
- Memory.WriteU16(this.ioReg, address, value);
- this.WriteTimerControl(0, oldCnt);
- }
- break;
-
- case TM1CNT:
- {
- ushort oldCnt = Memory.ReadU16(this.ioReg, TM1CNT);
- Memory.WriteU16(this.ioReg, address, value);
- this.WriteTimerControl(1, oldCnt);
- }
- break;
-
- case TM2CNT:
- {
- ushort oldCnt = Memory.ReadU16(this.ioReg, TM2CNT);
- Memory.WriteU16(this.ioReg, address, value);
- this.WriteTimerControl(2, oldCnt);
- }
- break;
-
- case TM3CNT:
- {
- ushort oldCnt = Memory.ReadU16(this.ioReg, TM3CNT);
- Memory.WriteU16(this.ioReg, address, value);
- this.WriteTimerControl(3, oldCnt);
- }
- break;
-
- case FIFO_A_L:
- case FIFO_A_H:
- Memory.WriteU16(this.ioReg, address, value);
- this.soundManager.IncrementFifoA();
- break;
-
- case FIFO_B_L:
- case FIFO_B_H:
- Memory.WriteU16(this.ioReg, address, value);
- this.soundManager.IncrementFifoB();
- break;
-
- case SOUNDCNT_H:
- Memory.WriteU16(this.ioReg, address, value);
- if ((value & (1 << 11)) != 0)
- {
- this.soundManager.ResetFifoA();
- }
- if ((value & (1 << 15)) != 0)
- {
- this.soundManager.ResetFifoB();
- }
- break;
-
- case IF:
- {
- ushort tmp = Memory.ReadU16(this.ioReg, address);
- Memory.WriteU16(this.ioReg, address, (ushort)(tmp & (~value)));
- }
- break;
-
- case HALTCNT:
- Memory.WriteU16(this.ioReg, address, value);
- this.processor.Halt();
- break;
-
- default:
- Memory.WriteU16(this.ioReg, address, value);
- break;
- }
- }
-
- private void WriteIO32(uint address, uint value)
- {
- this.waitCycles++;
- address &= 0xFFFFFF;
- if (address >= Memory.ioRegMask) return;
-
- switch (address)
- {
- case BG2X_L:
- {
- Memory.WriteU32(this.ioReg, address, value);
- uint tmp = Memory.ReadU32(this.ioReg, BG2X_L);
- if ((tmp & (1 << 27)) != 0) tmp |= 0xF0000000;
- Memory.WriteU32(this.ioReg, BG2X_L, tmp);
-
- this.bgx[0] = (int)tmp;
- }
- break;
-
- case BG3X_L:
- {
- Memory.WriteU32(this.ioReg, address, value);
- uint tmp = Memory.ReadU32(this.ioReg, BG3X_L);
- if ((tmp & (1 << 27)) != 0) tmp |= 0xF0000000;
- Memory.WriteU32(this.ioReg, BG3X_L, tmp);
-
- this.bgx[1] = (int)tmp;
- }
- break;
-
- case BG2Y_L:
- {
- Memory.WriteU32(this.ioReg, address, value);
- uint tmp = Memory.ReadU32(this.ioReg, BG2Y_L);
- if ((tmp & (1 << 27)) != 0) tmp |= 0xF0000000;
- Memory.WriteU32(this.ioReg, BG2Y_L, tmp);
-
- this.bgy[0] = (int)tmp;
- }
- break;
-
- case BG3Y_L:
- {
- Memory.WriteU32(this.ioReg, address, value);
- uint tmp = Memory.ReadU32(this.ioReg, BG3Y_L);
- if ((tmp & (1 << 27)) != 0) tmp |= 0xF0000000;
- Memory.WriteU32(this.ioReg, BG3Y_L, tmp);
-
- this.bgy[1] = (int)tmp;
- }
- break;
-
- case DMA0CNT_L:
- Memory.WriteU32(this.ioReg, address, value);
- this.WriteDmaControl(0);
- break;
-
- case DMA1CNT_L:
- Memory.WriteU32(this.ioReg, address, value);
- this.WriteDmaControl(1);
- break;
-
- case DMA2CNT_L:
- Memory.WriteU32(this.ioReg, address, value);
- this.WriteDmaControl(2);
- break;
-
- case DMA3CNT_L:
- Memory.WriteU32(this.ioReg, address, value);
- this.WriteDmaControl(3);
- break;
-
- case TM0D:
- {
- ushort oldCnt = Memory.ReadU16(this.ioReg, TM0CNT);
- Memory.WriteU32(this.ioReg, address, value);
- this.WriteTimerControl(0, oldCnt);
- }
- break;
-
- case TM1D:
- {
- ushort oldCnt = Memory.ReadU16(this.ioReg, TM1CNT);
- Memory.WriteU32(this.ioReg, address, value);
- this.WriteTimerControl(1, oldCnt);
- }
- break;
-
- case TM2D:
- {
- ushort oldCnt = Memory.ReadU16(this.ioReg, TM2CNT);
- Memory.WriteU32(this.ioReg, address, value);
- this.WriteTimerControl(2, oldCnt);
- }
- break;
-
- case TM3D:
- {
- ushort oldCnt = Memory.ReadU16(this.ioReg, TM3CNT);
- Memory.WriteU32(this.ioReg, address, value);
- this.WriteTimerControl(3, oldCnt);
- }
- break;
-
- case FIFO_A_L:
- Memory.WriteU32(this.ioReg, address, value);
- this.soundManager.IncrementFifoA();
- break;
-
- case FIFO_B_L:
- Memory.WriteU32(this.ioReg, address, value);
- this.soundManager.IncrementFifoB();
- break;
-
- case SOUNDCNT_L:
- Memory.WriteU32(this.ioReg, address, value);
- if (((value >> 16) & (1 << 11)) != 0)
- {
- this.soundManager.ResetFifoA();
- }
- if (((value >> 16) & (1 << 15)) != 0)
- {
- this.soundManager.ResetFifoB();
- }
- break;
-
- case IE:
- {
- uint tmp = Memory.ReadU32(this.ioReg, address);
- Memory.WriteU32(this.ioReg, address, (uint)((value & 0xFFFF) | (tmp & (~(value & 0xFFFF0000)))));
- }
- break;
-
- case HALTCNT:
- Memory.WriteU32(this.ioReg, address, value);
- this.processor.Halt();
- break;
-
- default:
- Memory.WriteU32(this.ioReg, address, value);
- break;
- }
- }
-
- private void WritePalRam8(uint address, byte value)
- {
- this.waitCycles++;
- address &= Memory.palRamMask & ~1U;
- this.palRam[address] = value;
- this.palRam[address + 1] = value;
- }
-
- private void WritePalRam16(uint address, ushort value)
- {
- this.waitCycles++;
- Memory.WriteU16(this.palRam, address & Memory.palRamMask, value);
- }
-
- private void WritePalRam32(uint address, uint value)
- {
- this.waitCycles += 2;
- Memory.WriteU32(this.palRam, address & Memory.palRamMask, value);
- }
-
- private void WriteVRam8(uint address, byte value)
- {
- this.waitCycles++;
- address &= Memory.vRamMask & ~1U;
- if (address > 0x17FFF) address = 0x10000 + ((address - 0x17FFF) & 0x7FFF);
- this.vRam[address] = value;
- this.vRam[address + 1] = value;
- }
-
- private void WriteVRam16(uint address, ushort value)
- {
- this.waitCycles++;
- address &= Memory.vRamMask;
- if (address > 0x17FFF) address = 0x10000 + ((address - 0x17FFF) & 0x7FFF);
- Memory.WriteU16(this.vRam, address, value);
- }
-
- private void WriteVRam32(uint address, uint value)
- {
- this.waitCycles += 2;
- address &= Memory.vRamMask;
- if (address > 0x17FFF) address = 0x10000 + ((address - 0x17FFF) & 0x7FFF);
- Memory.WriteU32(this.vRam, address, value);
- }
-
- private void WriteOamRam8(uint address, byte value)
- {
- this.waitCycles++;
- address &= Memory.oamRamMask & ~1U;
-
- this.oamRam[address] = value;
- this.oamRam[address + 1] = value;
- }
-
- private void WriteOamRam16(uint address, ushort value)
- {
- this.waitCycles++;
- Memory.WriteU16(this.oamRam, address & Memory.oamRamMask, value);
- }
-
- private void WriteOamRam32(uint address, uint value)
- {
- this.waitCycles++;
- Memory.WriteU32(this.oamRam, address & Memory.oamRamMask, value);
- }
-
- private void WriteSRam8(uint address, byte value)
- {
- this.sRam[address & Memory.sRamMask] = value;
- }
-
- private void WriteSRam16(uint address, ushort value)
- {
- // TODO
- }
-
- private void WriteSRam32(uint address, uint value)
- {
- // TODO
- }
-
- private enum EepromModes
- {
- Idle,
- ReadData
- }
-
- private EepromModes eepromMode = EepromModes.Idle;
- private byte[] eeprom = new byte[0xffff];
- private byte[] eepromStore = new byte[0xff];
- private int curEepromByte;
- private int eepromReadAddress = -1;
-
- private void WriteEeprom8(uint address, byte value)
- {
- // EEPROM writes must be done by DMA 3
- if ((this.dmaRegs[3, 3] & (1 << 15)) == 0) return;
- // 0 length eeprom writes are bad
- if (this.dmaRegs[3, 2] == 0) return;
-
- if (this.eepromMode != EepromModes.ReadData)
- {
- this.curEepromByte = 0;
- this.eepromMode = EepromModes.ReadData;
- this.eepromReadAddress = -1;
-
- for (int i = 0; i < this.eepromStore.Length; i++) this.eepromStore[i] = 0;
- }
-
- this.eepromStore[this.curEepromByte >> 3] |= (byte)(value << (7 - (this.curEepromByte & 0x7)));
- this.curEepromByte++;
-
- if (this.curEepromByte == this.dmaRegs[3, 2])
- {
- if ((this.eepromStore[0] & 0x80) == 0) return;
-
- if ((this.eepromStore[0] & 0x40) != 0)
- {
- // Read request
- if (this.curEepromByte == 9)
- {
- this.eepromReadAddress = this.eepromStore[0] & 0x3F;
- }
- else
- {
- this.eepromReadAddress = ((this.eepromStore[0] & 0x3F) << 8) | this.eepromStore[1];
- }
-
- this.curEepromByte = 0;
- }
- else
- {
- // Write request
- int eepromAddress, offset;
- if (this.curEepromByte == 64 + 9)
- {
- eepromAddress = (int)(this.eepromStore[0] & 0x3F);
- offset = 1;
- }
- else
- {
- eepromAddress = ((this.eepromStore[0] & 0x3F) << 8) | this.eepromStore[1];
- offset = 2;
- }
-
- for (int i = 0; i < 8; i++)
- {
- this.eeprom[eepromAddress * 8 + i] = this.eepromStore[i + offset];
- }
-
- this.eepromMode = EepromModes.Idle;
- }
- }
- }
-
- private void WriteEeprom16(uint address, ushort value)
- {
- this.WriteEeprom8(address, (byte)(value & 0xff));
- }
-
- private void WriteEeprom32(uint address, uint value)
- {
- this.WriteEeprom8(address, (byte)(value & 0xff));
- }
-
- private byte ReadEeprom8(uint address)
- {
- if (this.eepromReadAddress == -1) return 1;
-
- byte retval = 0;
-
- if (this.curEepromByte >= 4)
- {
- retval = (byte)((this.eeprom[this.eepromReadAddress * 8 + ((this.curEepromByte - 4) / 8)] >> (7 - ((this.curEepromByte - 4) & 7))) & 1);
- }
-
- this.curEepromByte++;
-
- if (this.curEepromByte == this.dmaRegs[3, 2])
- {
- this.eepromReadAddress = -1;
- this.eepromMode = EepromModes.Idle;
- }
-
- return retval;
- }
-
- private ushort ReadEeprom16(uint address)
- {
- return (ushort)this.ReadEeprom8(address);
- }
-
- private uint ReadEeprom32(uint address)
- {
- return (uint)this.ReadEeprom8(address);
- }
- #endregion
-
- #region Shader Renderer Vram Writes
- private List vramUpdated = new List();
- private List palUpdated = new List();
- public const int VramBlockSize = 64;
- public const int PalBlockSize = 32;
- private bool[] vramHit = new bool[(Memory.vRamMask + 1) / VramBlockSize];
- private bool[] palHit = new bool[(Memory.palRamMask + 1) / PalBlockSize];
-
- public List VramUpdated
- {
- get
- {
- List old = this.vramUpdated;
- for (int i = 0; i < old.Count; i++)
- {
- vramHit[old[i]] = false;
- }
- this.vramUpdated = new List();
- return old;
- }
- }
-
-
- public List PalUpdated
- {
- get
- {
- List old = this.palUpdated;
- for (int i = 0; i < old.Count; i++)
- {
- palHit[old[i]] = false;
- }
- this.palUpdated = new List();
- return old;
- }
- }
-
- private void UpdatePal(uint address)
- {
- uint index = address / PalBlockSize;
- if (!palHit[index])
- {
- palHit[index] = true;
- this.palUpdated.Add(index);
- }
- }
-
- private void UpdateVram(uint address)
- {
- uint index = address / VramBlockSize;
- if (!vramHit[index])
- {
- vramHit[index] = true;
- this.vramUpdated.Add(index);
- }
- }
-
- private void ShaderWritePalRam8(uint address, byte value)
- {
- this.waitCycles++;
- address &= Memory.palRamMask & ~1U;
- this.palRam[address] = value;
- this.palRam[address + 1] = value;
-
- this.UpdatePal(address);
- }
-
- private void ShaderWritePalRam16(uint address, ushort value)
- {
- this.waitCycles++;
- Memory.WriteU16(this.palRam, address & Memory.palRamMask, value);
-
- this.UpdatePal(address & Memory.palRamMask);
- }
-
- private void ShaderWritePalRam32(uint address, uint value)
- {
- this.waitCycles += 2;
- Memory.WriteU32(this.palRam, address & Memory.palRamMask, value);
-
- this.UpdatePal(address & Memory.palRamMask);
- }
-
- private void ShaderWriteVRam8(uint address, byte value)
- {
- this.waitCycles++;
- address &= Memory.vRamMask & ~1U;
- if (address > 0x17FFF) address = 0x10000 + ((address - 0x17FFF) & 0x7FFF);
- this.vRam[address] = value;
- this.vRam[address + 1] = value;
-
- this.UpdateVram(address);
- }
-
- private void ShaderWriteVRam16(uint address, ushort value)
- {
- this.waitCycles++;
- address &= Memory.vRamMask;
- if (address > 0x17FFF) address = 0x10000 + ((address - 0x17FFF) & 0x7FFF);
- Memory.WriteU16(this.vRam, address, value);
-
- this.UpdateVram(address);
- }
-
- private void ShaderWriteVRam32(uint address, uint value)
- {
- this.waitCycles += 2;
- address &= Memory.vRamMask;
- if (address > 0x17FFF) address = 0x10000 + ((address - 0x17FFF) & 0x7FFF);
- Memory.WriteU32(this.vRam, address, value);
-
- this.UpdateVram(address);
- }
-
- public void EnableVramUpdating()
- {
- this.WriteU8Funcs[0x5] = this.ShaderWritePalRam8;
- this.WriteU16Funcs[0x5] = this.ShaderWritePalRam16;
- this.WriteU32Funcs[0x5] = this.ShaderWritePalRam32;
- this.WriteU8Funcs[0x6] = this.ShaderWriteVRam8;
- this.WriteU16Funcs[0x6] = this.ShaderWriteVRam16;
- this.WriteU32Funcs[0x6] = this.ShaderWriteVRam32;
-
- for (uint i = 0; i < (Memory.vRamMask + 1) / Memory.VramBlockSize; i++)
- {
- this.vramUpdated.Add(i);
- }
-
- for (uint i = 0; i < (Memory.palRamMask + 1) / Memory.PalBlockSize; i++)
- {
- this.palUpdated.Add(i);
- }
- }
- #endregion
-
- public byte ReadU8(uint address)
- {
- uint bank = (address >> 24) & 0xf;
- return this.ReadU8Funcs[bank](address);
- }
-
- public ushort ReadU16(uint address)
- {
- address &= ~1U;
- uint bank = (address >> 24) & 0xf;
- return this.ReadU16Funcs[bank](address);
- }
-
- public uint ReadU32(uint address)
- {
- int shiftAmt = (int)((address & 3U) << 3);
- address &= ~3U;
- uint bank = (address >> 24) & 0xf;
- uint res = this.ReadU32Funcs[bank](address);
- return (res >> shiftAmt) | (res << (32 - shiftAmt));
- }
-
- public uint ReadU32Aligned(uint address)
- {
- uint bank = (address >> 24) & 0xf;
- return this.ReadU32Funcs[bank](address);
- }
-
- public ushort ReadU16Debug(uint address)
- {
- address &= ~1U;
- uint bank = (address >> 24) & 0xf;
- int oldWaitCycles = this.waitCycles;
- ushort res = this.ReadU16Funcs[bank](address);
- this.waitCycles = oldWaitCycles;
- return res;
- }
-
- public uint ReadU32Debug(uint address)
- {
- int shiftAmt = (int)((address & 3U) << 3);
- address &= ~3U;
- uint bank = (address >> 24) & 0xf;
- int oldWaitCycles = this.waitCycles;
- uint res = this.ReadU32Funcs[bank](address);
- this.waitCycles = oldWaitCycles;
- return (res >> shiftAmt) | (res << (32 - shiftAmt));
- }
-
- public void WriteU8(uint address, byte value)
- {
- uint bank = (address >> 24) & 0xf;
- this.WriteU8Funcs[bank](address, value);
- }
-
- public void WriteU16(uint address, ushort value)
- {
- address &= ~1U;
- uint bank = (address >> 24) & 0xf;
- this.WriteU16Funcs[bank](address, value);
- }
-
- public void WriteU32(uint address, uint value)
- {
- address &= ~3U;
- uint bank = (address >> 24) & 0xf;
- this.WriteU32Funcs[bank](address, value);
- }
-
- public void WriteU8Debug(uint address, byte value)
- {
- uint bank = (address >> 24) & 0xf;
- int oldWaitCycles = this.waitCycles;
- this.WriteU8Funcs[bank](address, value);
- this.waitCycles = oldWaitCycles;
- }
-
- public void WriteU16Debug(uint address, ushort value)
- {
- address &= ~1U;
- uint bank = (address >> 24) & 0xf;
- int oldWaitCycles = this.waitCycles;
- this.WriteU16Funcs[bank](address, value);
- this.waitCycles = oldWaitCycles;
- }
-
- public void WriteU32Debug(uint address, uint value)
- {
- address &= ~3U;
- uint bank = (address >> 24) & 0xf;
- int oldWaitCycles = this.waitCycles;
- this.WriteU32Funcs[bank](address, value);
- this.waitCycles = oldWaitCycles;
- }
-
- public void LoadBios(byte[] biosRom)
- {
- Array.Copy(biosRom, this.biosRam, this.biosRam.Length);
- }
-
- public void LoadCartridge(byte[] cartRom)
- {
- this.ResetRomBank1();
- this.ResetRomBank2();
-
- // Set up the appropriate cart size
- int cartSize = 1;
- while (cartSize < cartRom.Length)
- {
- cartSize <<= 1;
- }
-
- if (cartSize != cartRom.Length)
- {
- throw new Exception("Unable to load non power of two carts");
- }
-
- // Split across bank 1 and 2 if cart is too big
- if (cartSize > 1 << 24)
- {
- this.romBank1 = cartRom;
- this.romBank1Mask = (1 << 24) - 1;
-
- cartRom.CopyTo(this.romBank2, 1 << 24);
- this.romBank2Mask = (1 << 24) - 1;
- }
- else
- {
- this.romBank1 = cartRom;
- this.romBank1Mask = (uint)(cartSize - 1);
- }
-
- if (this.romBank1Mask != 0)
- {
- // TODO: Writes (i.e. eeprom, and other stuff)
- this.ReadU8Funcs[0x8] = this.ReadRom1_8;
- this.ReadU8Funcs[0xA] = this.ReadRom1_8;
- this.ReadU8Funcs[0xC] = this.ReadRom1_8;
- this.ReadU16Funcs[0x8] = this.ReadRom1_16;
- this.ReadU16Funcs[0xA] = this.ReadRom1_16;
- this.ReadU16Funcs[0xC] = this.ReadRom1_16;
- this.ReadU32Funcs[0x8] = this.ReadRom1_32;
- this.ReadU32Funcs[0xA] = this.ReadRom1_32;
- this.ReadU32Funcs[0xC] = this.ReadRom1_32;
- }
-
- if (this.romBank2Mask != 0)
- {
- this.ReadU8Funcs[0x9] = this.ReadRom2_8;
- this.ReadU8Funcs[0xB] = this.ReadRom2_8;
- this.ReadU8Funcs[0xD] = this.ReadRom2_8;
- this.ReadU16Funcs[0x9] = this.ReadRom2_16;
- this.ReadU16Funcs[0xB] = this.ReadRom2_16;
- this.ReadU16Funcs[0xD] = this.ReadRom2_16;
- this.ReadU32Funcs[0x9] = this.ReadRom2_32;
- this.ReadU32Funcs[0xB] = this.ReadRom2_32;
- this.ReadU32Funcs[0xD] = this.ReadRom2_32;
- }
- }
-
- private void ResetRomBank1()
- {
- this.romBank1 = null;
- this.romBank1Mask = 0;
-
- for (int i = 0; i < this.bankSTimes.Length; i++)
- {
- this.bankSTimes[i] = 2;
- }
-
- this.ReadU8Funcs[0x8] = this.ReadNop8;
- this.ReadU8Funcs[0xA] = this.ReadNop8;
- this.ReadU8Funcs[0xC] = this.ReadNop8;
- this.ReadU16Funcs[0x8] = this.ReadNop16;
- this.ReadU16Funcs[0xA] = this.ReadNop16;
- this.ReadU16Funcs[0xC] = this.ReadNop16;
- this.ReadU32Funcs[0x8] = this.ReadNop32;
- this.ReadU32Funcs[0xA] = this.ReadNop32;
- this.ReadU32Funcs[0xC] = this.ReadNop32;
- }
-
- private void ResetRomBank2()
- {
- this.romBank2 = null;
- this.romBank2Mask = 0;
-
- this.ReadU8Funcs[0x9] = this.ReadEeprom8;
- this.ReadU8Funcs[0xB] = this.ReadEeprom8;
- this.ReadU8Funcs[0xD] = this.ReadEeprom8;
- this.ReadU16Funcs[0x9] = this.ReadEeprom16;
- this.ReadU16Funcs[0xB] = this.ReadEeprom16;
- this.ReadU16Funcs[0xD] = this.ReadEeprom16;
- this.ReadU32Funcs[0x9] = this.ReadEeprom32;
- this.ReadU32Funcs[0xB] = this.ReadEeprom32;
- this.ReadU32Funcs[0xD] = this.ReadEeprom32;
-
- this.WriteU8Funcs[0x9] = this.WriteEeprom8;
- this.WriteU8Funcs[0xB] = this.WriteEeprom8;
- this.WriteU8Funcs[0xD] = this.WriteEeprom8;
- this.WriteU16Funcs[0x9] = this.WriteEeprom16;
- this.WriteU16Funcs[0xB] = this.WriteEeprom16;
- this.WriteU16Funcs[0xD] = this.WriteEeprom16;
- this.WriteU32Funcs[0x9] = this.WriteEeprom32;
- this.WriteU32Funcs[0xB] = this.WriteEeprom32;
- this.WriteU32Funcs[0xD] = this.WriteEeprom32;
- }
- }
-}
diff --git a/attic/GarboDev/Renderer.cs b/attic/GarboDev/Renderer.cs
deleted file mode 100644
index 4e7b7301ee..0000000000
--- a/attic/GarboDev/Renderer.cs
+++ /dev/null
@@ -1,952 +0,0 @@
-namespace GarboDev
-{
- using System;
- using System.Collections.Generic;
- using System.Text;
-
- public partial class Renderer : IRenderer
- {
- private Memory memory;
- private uint[] scanline = new uint[240];
- private byte[] blend = new byte[240];
- private byte[] windowCover = new byte[240];
- private uint[] back = new uint[240 * 160];
- //private uint[] front = new uint[240 * 160];
- private const uint pitch = 240;
-
- // Convenience variable as I use it everywhere, set once in RenderLine
- private ushort dispCnt;
-
- // Window helper variables
- private byte win0x1, win0x2, win0y1, win0y2;
- private byte win1x1, win1x2, win1y1, win1y2;
- private byte win0Enabled, win1Enabled, winObjEnabled, winOutEnabled;
- private bool winEnabled;
-
- private byte blendSource, blendTarget;
- private byte blendA, blendB, blendY;
- private int blendType;
-
- private int curLine = 0;
-
- private static uint[] colorLUT;
-
- static Renderer()
- {
- colorLUT = new uint[0x10000];
- // Pre-calculate the color LUT
- for (uint i = 0; i <= 0xFFFF; i++)
- {
- uint r = (i & 0x1FU);
- uint g = (i & 0x3E0U) >> 5;
- uint b = (i & 0x7C00U) >> 10;
- r = (r << 3) | (r >> 2);
- g = (g << 3) | (g >> 2);
- b = (b << 3) | (b >> 2);
- colorLUT[i] = (r << 16) | (g << 8) | b;
- }
- }
-
- public Memory Memory
- {
- set { this.memory = value; }
- }
-
- public void Initialize(object data)
- {
- }
-
- public void Reset()
- {
- }
-
- public uint[] ShowFrame()
- {
- //Array.Copy(this.back, this.front, this.front.Length);
-
- //return this.front;
- return this.back;
- }
-
- public void RenderLine(int line)
- {
- this.curLine = line;
-
- // Render the line
- this.dispCnt = Memory.ReadU16(this.memory.IORam, Memory.DISPCNT);
-
- if ((this.dispCnt & (1 << 7)) != 0)
- {
- uint bgColor = Renderer.GbaTo32((ushort)0x7FFF);
- for (int i = 0; i < 240; i++) this.scanline[i] = bgColor;
- }
- else
- {
- this.winEnabled = false;
-
- if ((this.dispCnt & (1 << 13)) != 0)
- {
- // Calculate window 0 information
- ushort winy = Memory.ReadU16(this.memory.IORam, Memory.WIN0V);
- this.win0y1 = (byte)(winy >> 8);
- this.win0y2 = (byte)(winy & 0xff);
- ushort winx = Memory.ReadU16(this.memory.IORam, Memory.WIN0H);
- this.win0x1 = (byte)(winx >> 8);
- this.win0x2 = (byte)(winx & 0xff);
-
- if (this.win0x2 > 240 || this.win0x1 > this.win0x2)
- {
- this.win0x2 = 240;
- }
-
- if (this.win0y2 > 160 || this.win0y1 > this.win0y2)
- {
- this.win0y2 = 160;
- }
-
- this.win0Enabled = this.memory.IORam[Memory.WININ];
- this.winEnabled = true;
- }
-
- if ((this.dispCnt & (1 << 14)) != 0)
- {
- // Calculate window 1 information
- ushort winy = Memory.ReadU16(this.memory.IORam, Memory.WIN1V);
- this.win1y1 = (byte)(winy >> 8);
- this.win1y2 = (byte)(winy & 0xff);
- ushort winx = Memory.ReadU16(this.memory.IORam, Memory.WIN1H);
- this.win1x1 = (byte)(winx >> 8);
- this.win1x2 = (byte)(winx & 0xff);
-
- if (this.win1x2 > 240 || this.win1x1 > this.win1x2)
- {
- this.win1x2 = 240;
- }
-
- if (this.win1y2 > 160 || this.win1y1 > this.win1y2)
- {
- this.win1y2 = 160;
- }
-
- this.win1Enabled = this.memory.IORam[Memory.WININ + 1];
- this.winEnabled = true;
- }
-
- if ((this.dispCnt & (1 << 15)) != 0 && (this.dispCnt & (1 << 12)) != 0)
- {
- // Object windows are enabled
- this.winObjEnabled = this.memory.IORam[Memory.WINOUT + 1];
- this.winEnabled = true;
- }
-
- if (this.winEnabled)
- {
- this.winOutEnabled = this.memory.IORam[Memory.WINOUT];
- }
-
- // Calculate blending information
- ushort bldcnt = Memory.ReadU16(this.memory.IORam, Memory.BLDCNT);
- this.blendType = (bldcnt >> 6) & 0x3;
- this.blendSource = (byte)(bldcnt & 0x3F);
- this.blendTarget = (byte)((bldcnt >> 8) & 0x3F);
-
- ushort bldalpha = Memory.ReadU16(this.memory.IORam, Memory.BLDALPHA);
- this.blendA = (byte)(bldalpha & 0x1F);
- if (this.blendA > 0x10) this.blendA = 0x10;
- this.blendB = (byte)((bldalpha >> 8) & 0x1F);
- if (this.blendB > 0x10) this.blendB = 0x10;
-
- this.blendY = (byte)(this.memory.IORam[Memory.BLDY] & 0x1F);
- if (this.blendY > 0x10) this.blendY = 0x10;
-
- switch (this.dispCnt & 0x7)
- {
- case 0: this.RenderMode0Line(); break;
- case 1: this.RenderMode1Line(); break;
- case 2: this.RenderMode2Line(); break;
- case 3: this.RenderMode3Line(); break;
- case 4: this.RenderMode4Line(); break;
- case 5: this.RenderMode5Line(); break;
- }
- }
-
- Array.Copy(this.scanline, 0, this.back, this.curLine * Renderer.pitch, Renderer.pitch);
- }
-
- private void DrawBackdrop()
- {
- byte[] palette = this.memory.PaletteRam;
-
- // Initialize window coverage buffer if neccesary
- if (this.winEnabled)
- {
- for (int i = 0; i < 240; i++)
- {
- this.windowCover[i] = this.winOutEnabled;
- }
-
- if ((this.dispCnt & (1 << 15)) != 0)
- {
- // Sprite window
- this.DrawSpriteWindows();
- }
-
- if ((this.dispCnt & (1 << 14)) != 0)
- {
- // Window 1
- if (this.curLine >= this.win1y1 && this.curLine < this.win1y2)
- {
- for (int i = this.win1x1; i < this.win1x2; i++)
- {
- this.windowCover[i] = this.win1Enabled;
- }
- }
- }
-
- if ((this.dispCnt & (1 << 13)) != 0)
- {
- // Window 0
- if (this.curLine >= this.win0y1 && this.curLine < this.win0y2)
- {
- for (int i = this.win0x1; i < this.win0x2; i++)
- {
- this.windowCover[i] = this.win0Enabled;
- }
- }
- }
- }
-
- // Draw backdrop first
- uint bgColor = Renderer.GbaTo32((ushort)(palette[0] | (palette[1] << 8)));
- uint modColor = bgColor;
-
- if (this.blendType == 2 && (this.blendSource & (1 << 5)) != 0)
- {
- // Brightness increase
- uint r = bgColor & 0xFF;
- uint g = (bgColor >> 8) & 0xFF;
- uint b = (bgColor >> 16) & 0xFF;
- r = r + (((0xFF - r) * this.blendY) >> 4);
- g = g + (((0xFF - g) * this.blendY) >> 4);
- b = b + (((0xFF - b) * this.blendY) >> 4);
- modColor = r | (g << 8) | (b << 16);
- }
- else if (this.blendType == 3 && (this.blendSource & (1 << 5)) != 0)
- {
- // Brightness decrease
- uint r = bgColor & 0xFF;
- uint g = (bgColor >> 8) & 0xFF;
- uint b = (bgColor >> 16) & 0xFF;
- r = r - ((r * this.blendY) >> 4);
- g = g - ((g * this.blendY) >> 4);
- b = b - ((b * this.blendY) >> 4);
- modColor = r | (g << 8) | (b << 16);
- }
-
- if (this.winEnabled)
- {
- for (int i = 0; i < 240; i++)
- {
- if ((this.windowCover[i] & (1 << 5)) != 0)
- {
- this.scanline[i] = modColor;
- }
- else
- {
- this.scanline[i] = bgColor;
- }
- this.blend[i] = 1 << 5;
- }
- }
- else
- {
- for (int i = 0; i < 240; i++)
- {
- this.scanline[i] = modColor;
- this.blend[i] = 1 << 5;
- }
- }
- }
-
- private void RenderTextBg(int bg)
- {
- if (this.winEnabled)
- {
- switch (this.blendType)
- {
- case 0:
- this.RenderTextBgWindow(bg);
- break;
- case 1:
- if ((this.blendSource & (1 << bg)) != 0)
- this.RenderTextBgWindowBlend(bg);
- else
- this.RenderTextBgWindow(bg);
- break;
- case 2:
- if ((this.blendSource & (1 << bg)) != 0)
- this.RenderTextBgWindowBrightInc(bg);
- else
- this.RenderTextBgWindow(bg);
- break;
- case 3:
- if ((this.blendSource & (1 << bg)) != 0)
- this.RenderTextBgWindowBrightDec(bg);
- else
- this.RenderTextBgWindow(bg);
- break;
- }
- }
- else
- {
- switch (this.blendType)
- {
- case 0:
- this.RenderTextBgNormal(bg);
- break;
- case 1:
- if ((this.blendSource & (1 << bg)) != 0)
- this.RenderTextBgBlend(bg);
- else
- this.RenderTextBgNormal(bg);
- break;
- case 2:
- if ((this.blendSource & (1 << bg)) != 0)
- this.RenderTextBgBrightInc(bg);
- else
- this.RenderTextBgNormal(bg);
- break;
- case 3:
- if ((this.blendSource & (1 << bg)) != 0)
- this.RenderTextBgBrightDec(bg);
- else
- this.RenderTextBgNormal(bg);
- break;
- }
- }
- }
-
- private void RenderRotScaleBg(int bg)
- {
- if (this.winEnabled)
- {
- switch (this.blendType)
- {
- case 0:
- this.RenderRotScaleBgWindow(bg);
- break;
- case 1:
- if ((this.blendSource & (1 << bg)) != 0)
- this.RenderRotScaleBgWindowBlend(bg);
- else
- this.RenderRotScaleBgWindow(bg);
- break;
- case 2:
- if ((this.blendSource & (1 << bg)) != 0)
- this.RenderRotScaleBgWindowBrightInc(bg);
- else
- this.RenderRotScaleBgWindow(bg);
- break;
- case 3:
- if ((this.blendSource & (1 << bg)) != 0)
- this.RenderRotScaleBgWindowBrightDec(bg);
- else
- this.RenderRotScaleBgWindow(bg);
- break;
- }
- }
- else
- {
- switch (this.blendType)
- {
- case 0:
- this.RenderRotScaleBgNormal(bg);
- break;
- case 1:
- if ((this.blendSource & (1 << bg)) != 0)
- this.RenderRotScaleBgBlend(bg);
- else
- this.RenderRotScaleBgNormal(bg);
- break;
- case 2:
- if ((this.blendSource & (1 << bg)) != 0)
- this.RenderRotScaleBgBrightInc(bg);
- else
- this.RenderRotScaleBgNormal(bg);
- break;
- case 3:
- if ((this.blendSource & (1 << bg)) != 0)
- this.RenderRotScaleBgBrightDec(bg);
- else
- this.RenderRotScaleBgNormal(bg);
- break;
- }
- }
- }
-
- private void DrawSprites(int pri)
- {
- if (this.winEnabled)
- {
- switch (this.blendType)
- {
- case 0:
- this.DrawSpritesWindow(pri);
- break;
- case 1:
- if ((this.blendSource & (1 << 4)) != 0)
- this.DrawSpritesWindowBlend(pri);
- else
- this.DrawSpritesWindow(pri);
- break;
- case 2:
- if ((this.blendSource & (1 << 4)) != 0)
- this.DrawSpritesWindowBrightInc(pri);
- else
- this.DrawSpritesWindow(pri);
- break;
- case 3:
- if ((this.blendSource & (1 << 4)) != 0)
- this.DrawSpritesWindowBrightDec(pri);
- else
- this.DrawSpritesWindow(pri);
- break;
- }
- }
- else
- {
- switch (this.blendType)
- {
- case 0:
- this.DrawSpritesNormal(pri);
- break;
- case 1:
- if ((this.blendSource & (1 << 4)) != 0)
- this.DrawSpritesBlend(pri);
- else
- this.DrawSpritesNormal(pri);
- break;
- case 2:
- if ((this.blendSource & (1 << 4)) != 0)
- this.DrawSpritesBrightInc(pri);
- else
- this.DrawSpritesNormal(pri);
- break;
- case 3:
- if ((this.blendSource & (1 << 4)) != 0)
- this.DrawSpritesBrightDec(pri);
- else
- this.DrawSpritesNormal(pri);
- break;
- }
- }
- }
-
- private void RenderMode0Line()
- {
- byte[] palette = this.memory.PaletteRam;
- byte[] vram = this.memory.VideoRam;
-
- this.DrawBackdrop();
-
- for (int pri = 3; pri >= 0; pri--)
- {
- for (int i = 3; i >= 0; i--)
- {
- if ((this.dispCnt & (1 << (8 + i))) != 0)
- {
- ushort bgcnt = Memory.ReadU16(this.memory.IORam, Memory.BG0CNT + 0x2 * (uint)i);
-
- if ((bgcnt & 0x3) == pri)
- {
- this.RenderTextBg(i);
- }
- }
- }
-
- this.DrawSprites(pri);
- }
- }
-
- private void RenderMode1Line()
- {
- byte[] palette = this.memory.PaletteRam;
- byte[] vram = this.memory.VideoRam;
-
- this.DrawBackdrop();
-
- for (int pri = 3; pri >= 0; pri--)
- {
- if ((this.dispCnt & (1 << (8 + 2))) != 0)
- {
- ushort bgcnt = Memory.ReadU16(this.memory.IORam, Memory.BG2CNT);
-
- if ((bgcnt & 0x3) == pri)
- {
- this.RenderRotScaleBg(2);
- }
- }
-
- for (int i = 1; i >= 0; i--)
- {
- if ((this.dispCnt & (1 << (8 + i))) != 0)
- {
- ushort bgcnt = Memory.ReadU16(this.memory.IORam, Memory.BG0CNT + 0x2 * (uint)i);
-
- if ((bgcnt & 0x3) == pri)
- {
- this.RenderTextBg(i);
- }
- }
- }
-
- this.DrawSprites(pri);
- }
- }
-
- private void RenderMode2Line()
- {
- byte[] palette = this.memory.PaletteRam;
- byte[] vram = this.memory.VideoRam;
-
- this.DrawBackdrop();
-
- for (int pri = 3; pri >= 0; pri--)
- {
- for (int i = 3; i >= 2; i--)
- {
- if ((this.dispCnt & (1 << (8 + i))) != 0)
- {
- ushort bgcnt = Memory.ReadU16(this.memory.IORam, Memory.BG0CNT + 0x2 * (uint)i);
-
- if ((bgcnt & 0x3) == pri)
- {
- this.RenderRotScaleBg(i);
- }
- }
- }
-
- this.DrawSprites(pri);
- }
- }
-
- private void RenderMode3Line()
- {
- ushort bg2Cnt = Memory.ReadU16(this.memory.IORam, Memory.BG2CNT);
-
- byte[] palette = this.memory.PaletteRam;
- byte[] vram = this.memory.VideoRam;
-
- this.DrawBackdrop();
-
- byte blendMaskType = (byte)(1 << 2);
-
- int bgPri = bg2Cnt & 0x3;
- for (int pri = 3; pri > bgPri; pri--)
- {
- this.DrawSprites(pri);
- }
-
- if ((this.dispCnt & (1 << 10)) != 0)
- {
- // Background enabled, render it
- int x = this.memory.Bgx[0];
- int y = this.memory.Bgy[0];
-
- short dx = (short)Memory.ReadU16(this.memory.IORam, Memory.BG2PA);
- short dy = (short)Memory.ReadU16(this.memory.IORam, Memory.BG2PC);
-
- for (int i = 0; i < 240; i++)
- {
- int ax = ((int)x) >> 8;
- int ay = ((int)y) >> 8;
-
- if (ax >= 0 && ax < 240 && ay >= 0 && ay < 160)
- {
- int curIdx = ((ay * 240) + ax) * 2;
- this.scanline[i] = Renderer.GbaTo32((ushort)(vram[curIdx] | (vram[curIdx + 1] << 8)));
- this.blend[i] = blendMaskType;
- }
-
- x += dx;
- y += dy;
- }
- }
-
- for (int pri = bgPri; pri >= 0; pri--)
- {
- this.DrawSprites(pri);
- }
- }
-
- private void RenderMode4Line()
- {
- ushort bg2Cnt = Memory.ReadU16(this.memory.IORam, Memory.BG2CNT);
-
- byte[] palette = this.memory.PaletteRam;
- byte[] vram = this.memory.VideoRam;
-
- this.DrawBackdrop();
-
- byte blendMaskType = (byte)(1 << 2);
-
- int bgPri = bg2Cnt & 0x3;
- for (int pri = 3; pri > bgPri; pri--)
- {
- this.DrawSprites(pri);
- }
-
- if ((this.dispCnt & (1 << 10)) != 0)
- {
- // Background enabled, render it
- int baseIdx = 0;
- if ((this.dispCnt & (1 << 4)) == 1 << 4) baseIdx = 0xA000;
-
- int x = this.memory.Bgx[0];
- int y = this.memory.Bgy[0];
-
- short dx = (short)Memory.ReadU16(this.memory.IORam, Memory.BG2PA);
- short dy = (short)Memory.ReadU16(this.memory.IORam, Memory.BG2PC);
-
- for (int i = 0; i < 240; i++)
- {
- int ax = ((int)x) >> 8;
- int ay = ((int)y) >> 8;
-
- if (ax >= 0 && ax < 240 && ay >= 0 && ay < 160)
- {
- int lookup = vram[baseIdx + (ay * 240) + ax];
- if (lookup != 0)
- {
- this.scanline[i] = Renderer.GbaTo32((ushort)(palette[lookup * 2] | (palette[lookup * 2 + 1] << 8)));
- this.blend[i] = blendMaskType;
- }
- }
-
- x += dx;
- y += dy;
- }
- }
-
- for (int pri = bgPri; pri >= 0; pri--)
- {
- this.DrawSprites(pri);
- }
- }
-
- private void RenderMode5Line()
- {
- ushort bg2Cnt = Memory.ReadU16(this.memory.IORam, Memory.BG2CNT);
-
- byte[] palette = this.memory.PaletteRam;
- byte[] vram = this.memory.VideoRam;
-
- this.DrawBackdrop();
-
- byte blendMaskType = (byte)(1 << 2);
-
- int bgPri = bg2Cnt & 0x3;
- for (int pri = 3; pri > bgPri; pri--)
- {
- this.DrawSprites(pri);
- }
-
- if ((this.dispCnt & (1 << 10)) != 0)
- {
- // Background enabled, render it
- int baseIdx = 0;
- if ((this.dispCnt & (1 << 4)) == 1 << 4) baseIdx += 160 * 128 * 2;
-
- int x = this.memory.Bgx[0];
- int y = this.memory.Bgy[0];
-
- short dx = (short)Memory.ReadU16(this.memory.IORam, Memory.BG2PA);
- short dy = (short)Memory.ReadU16(this.memory.IORam, Memory.BG2PC);
-
- for (int i = 0; i < 240; i++)
- {
- int ax = ((int)x) >> 8;
- int ay = ((int)y) >> 8;
-
- if (ax >= 0 && ax < 160 && ay >= 0 && ay < 128)
- {
- int curIdx = (int)(ay * 160 + ax) * 2;
-
- this.scanline[i] = Renderer.GbaTo32((ushort)(vram[baseIdx + curIdx] | (vram[baseIdx + curIdx + 1] << 8)));
- this.blend[i] = blendMaskType;
- }
-
- x += dx;
- y += dy;
- }
- }
-
- for (int pri = bgPri; pri >= 0; pri--)
- {
- this.DrawSprites(pri);
- }
- }
-
- private void DrawSpriteWindows()
- {
- byte[] palette = this.memory.PaletteRam;
- byte[] vram = this.memory.VideoRam;
-
- // OBJ must be enabled in this.dispCnt
- if ((this.dispCnt & (1 << 12)) == 0) return;
-
- for (int oamNum = 127; oamNum >= 0; oamNum--)
- {
- ushort attr0 = this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(oamNum * 8) + 0);
-
- // Not an object window, so continue
- if (((attr0 >> 10) & 3) != 2) continue;
-
- ushort attr1 = this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(oamNum * 8) + 2);
- ushort attr2 = this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(oamNum * 8) + 4);
-
- int x = attr1 & 0x1FF;
- int y = attr0 & 0xFF;
-
- int width = -1, height = -1;
- switch ((attr0 >> 14) & 3)
- {
- case 0:
- // Square
- switch ((attr1 >> 14) & 3)
- {
- case 0: width = 8; height = 8; break;
- case 1: width = 16; height = 16; break;
- case 2: width = 32; height = 32; break;
- case 3: width = 64; height = 64; break;
- }
- break;
- case 1:
- // Horizontal Rectangle
- switch ((attr1 >> 14) & 3)
- {
- case 0: width = 16; height = 8; break;
- case 1: width = 32; height = 8; break;
- case 2: width = 32; height = 16; break;
- case 3: width = 64; height = 32; break;
- }
- break;
- case 2:
- // Vertical Rectangle
- switch ((attr1 >> 14) & 3)
- {
- case 0: width = 8; height = 16; break;
- case 1: width = 8; height = 32; break;
- case 2: width = 16; height = 32; break;
- case 3: width = 32; height = 64; break;
- }
- break;
- }
-
- // Check double size flag here
-
- int rwidth = width, rheight = height;
- if ((attr0 & (1 << 8)) != 0)
- {
- // Rot-scale on
- if ((attr0 & (1 << 9)) != 0)
- {
- rwidth *= 2;
- rheight *= 2;
- }
- }
- else
- {
- // Invalid sprite
- if ((attr0 & (1 << 9)) != 0)
- width = -1;
- }
-
- if (width == -1)
- {
- // Invalid sprite
- continue;
- }
-
- // Y clipping
- if (y > ((y + rheight) & 0xff))
- {
- if (this.curLine >= ((y + rheight) & 0xff) && !(y < this.curLine)) continue;
- }
- else
- {
- if (this.curLine < y || this.curLine >= ((y + rheight) & 0xff)) continue;
- }
-
- int scale = 1;
- if ((attr0 & (1 << 13)) != 0) scale = 2;
-
- int spritey = this.curLine - y;
- if (spritey < 0) spritey += 256;
-
- if ((attr0 & (1 << 8)) == 0)
- {
- if ((attr1 & (1 << 13)) != 0) spritey = (height - 1) - spritey;
-
- int baseSprite;
- if ((this.dispCnt & (1 << 6)) != 0)
- {
- // 1 dimensional
- baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * (width / 8)) * scale;
- }
- else
- {
- // 2 dimensional
- baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * 0x20);
- }
-
- int baseInc = scale;
- if ((attr1 & (1 << 12)) != 0)
- {
- baseSprite += ((width / 8) * scale) - scale;
- baseInc = -baseInc;
- }
-
- if ((attr0 & (1 << 13)) != 0)
- {
- // 256 colors
- for (int i = x; i < x + width; i++)
- {
- if ((i & 0x1ff) < 240)
- {
- int tx = (i - x) & 7;
- if ((attr1 & (1 << 12)) != 0) tx = 7 - tx;
- int curIdx = baseSprite * 32 + ((spritey & 7) * 8) + tx;
- int lookup = vram[0x10000 + curIdx];
- if (lookup != 0)
- {
- this.windowCover[i & 0x1ff] = this.winObjEnabled;
- }
- }
- if (((i - x) & 7) == 7) baseSprite += baseInc;
- }
- }
- else
- {
- // 16 colors
- int palIdx = 0x200 + (((attr2 >> 12) & 0xF) * 16 * 2);
- for (int i = x; i < x + width; i++)
- {
- if ((i & 0x1ff) < 240)
- {
- int tx = (i - x) & 7;
- if ((attr1 & (1 << 12)) != 0) tx = 7 - tx;
- int curIdx = baseSprite * 32 + ((spritey & 7) * 4) + (tx / 2);
- int lookup = vram[0x10000 + curIdx];
- if ((tx & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- this.windowCover[i & 0x1ff] = this.winObjEnabled;
- }
- }
- if (((i - x) & 7) == 7) baseSprite += baseInc;
- }
- }
- }
- else
- {
- int rotScaleParam = (attr1 >> 9) & 0x1F;
-
- short dx = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x6);
- short dmx = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0xE);
- short dy = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x16);
- short dmy = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x1E);
-
- int cx = rwidth / 2;
- int cy = rheight / 2;
-
- int baseSprite = attr2 & 0x3FF;
- int pitch;
-
- if ((this.dispCnt & (1 << 6)) != 0)
- {
- // 1 dimensional
- pitch = (width / 8) * scale;
- }
- else
- {
- // 2 dimensional
- pitch = 0x20;
- }
-
- short rx = (short)((dmx * (spritey - cy)) - (cx * dx) + (width << 7));
- short ry = (short)((dmy * (spritey - cy)) - (cx * dy) + (height << 7));
-
- // Draw a rot/scale sprite
- if ((attr0 & (1 << 13)) != 0)
- {
- // 256 colors
- for (int i = x; i < x + rwidth; i++)
- {
- int tx = rx >> 8;
- int ty = ry >> 8;
-
- if ((i & 0x1ff) < 240 && tx >= 0 && tx < width && ty >= 0 && ty < height)
- {
- int curIdx = (baseSprite + ((ty / 8) * pitch) + ((tx / 8) * scale)) * 32 + ((ty & 7) * 8) + (tx & 7);
- int lookup = vram[0x10000 + curIdx];
- if (lookup != 0)
- {
- this.windowCover[i & 0x1ff] = this.winObjEnabled;
- }
- }
-
- rx += dx;
- ry += dy;
- }
- }
- else
- {
- // 16 colors
- int palIdx = 0x200 + (((attr2 >> 12) & 0xF) * 16 * 2);
- for (int i = x; i < x + rwidth; i++)
- {
- int tx = rx >> 8;
- int ty = ry >> 8;
-
- if ((i & 0x1ff) < 240 && tx >= 0 && tx < width && ty >= 0 && ty < height)
- {
- int curIdx = (baseSprite + ((ty / 8) * pitch) + ((tx / 8) * scale)) * 32 + ((ty & 7) * 4) + ((tx & 7) / 2);
- int lookup = vram[0x10000 + curIdx];
- if ((tx & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- this.windowCover[i & 0x1ff] = this.winObjEnabled;
- }
- }
-
- rx += dx;
- ry += dy;
- }
- }
- }
- }
- }
-
- public static uint GbaTo32(ushort color)
- {
- // more accurate, but slower :(
- // return colorLUT[color];
- return ((color & 0x1FU) << 19) | ((color & 0x3E0U) << 6) | ((color & 0x7C00U) >> 7);
- }
- }
-}
diff --git a/attic/GarboDev/Renderers.cs b/attic/GarboDev/Renderers.cs
deleted file mode 100644
index a05b3b8634..0000000000
--- a/attic/GarboDev/Renderers.cs
+++ /dev/null
@@ -1,5939 +0,0 @@
-namespace GarboDev
-{
- partial class Renderer
- {
- #region Sprite Drawing
- private void DrawSpritesNormal(int priority)
- {
- byte[] palette = this.memory.PaletteRam;
- byte[] vram = this.memory.VideoRam;
-
- // OBJ must be enabled in this.dispCnt
- if ((this.dispCnt & (1 << 12)) == 0) return;
-
- byte blendMaskType = (byte)(1 << 4);
-
- for (int oamNum = 127; oamNum >= 0; oamNum--)
- {
- ushort attr2 = this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(oamNum * 8) + 4);
-
- if (((attr2 >> 10) & 3) != priority) continue;
-
- ushort attr0 = this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(oamNum * 8) + 0);
- ushort attr1 = this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(oamNum * 8) + 2);
-
- int x = attr1 & 0x1FF;
- int y = attr0 & 0xFF;
-
- bool semiTransparent = false;
-
- switch ((attr0 >> 10) & 3)
- {
- case 1:
- // Semi-transparent
- semiTransparent = true;
- break;
- case 2:
- // Obj window
- continue;
- case 3:
- continue;
- }
-
- if ((this.dispCnt & 0x7) >= 3 && (attr2 & 0x3FF) < 0x200) continue;
-
- int width = -1, height = -1;
- switch ((attr0 >> 14) & 3)
- {
- case 0:
- // Square
- switch ((attr1 >> 14) & 3)
- {
- case 0: width = 8; height = 8; break;
- case 1: width = 16; height = 16; break;
- case 2: width = 32; height = 32; break;
- case 3: width = 64; height = 64; break;
- }
- break;
- case 1:
- // Horizontal Rectangle
- switch ((attr1 >> 14) & 3)
- {
- case 0: width = 16; height = 8; break;
- case 1: width = 32; height = 8; break;
- case 2: width = 32; height = 16; break;
- case 3: width = 64; height = 32; break;
- }
- break;
- case 2:
- // Vertical Rectangle
- switch ((attr1 >> 14) & 3)
- {
- case 0: width = 8; height = 16; break;
- case 1: width = 8; height = 32; break;
- case 2: width = 16; height = 32; break;
- case 3: width = 32; height = 64; break;
- }
- break;
- }
-
- // Check double size flag here
-
- int rwidth = width, rheight = height;
- if ((attr0 & (1 << 8)) != 0)
- {
- // Rot-scale on
- if ((attr0 & (1 << 9)) != 0)
- {
- rwidth *= 2;
- rheight *= 2;
- }
- }
- else
- {
- // Invalid sprite
- if ((attr0 & (1 << 9)) != 0)
- width = -1;
- }
-
- if (width == -1)
- {
- // Invalid sprite
- continue;
- }
-
- // Y clipping
- if (y > ((y + rheight) & 0xff))
- {
- if (this.curLine >= ((y + rheight) & 0xff) && !(y < this.curLine)) continue;
- }
- else
- {
- if (this.curLine < y || this.curLine >= ((y + rheight) & 0xff)) continue;
- }
-
- int scale = 1;
- if ((attr0 & (1 << 13)) != 0) scale = 2;
-
- int spritey = this.curLine - y;
- if (spritey < 0) spritey += 256;
-
- if (semiTransparent)
- {
- if ((attr0 & (1 << 8)) == 0)
- {
- if ((attr1 & (1 << 13)) != 0) spritey = (height - 1) - spritey;
-
- int baseSprite;
- if ((this.dispCnt & (1 << 6)) != 0)
- {
- // 1 dimensional
- baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * (width / 8)) * scale;
- }
- else
- {
- // 2 dimensional
- baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * 0x20);
- }
-
- int baseInc = scale;
- if ((attr1 & (1 << 12)) != 0)
- {
- baseSprite += ((width / 8) * scale) - scale;
- baseInc = -baseInc;
- }
-
- if ((attr0 & (1 << 13)) != 0)
- {
- // 256 colors
- for (int i = x; i < x + width; i++)
- {
- if ((i & 0x1ff) < 240 && true)
- {
- int tx = (i - x) & 7;
- if ((attr1 & (1 << 12)) != 0) tx = 7 - tx;
- int curIdx = baseSprite * 32 + ((spritey & 7) * 8) + tx;
- int lookup = vram[0x10000 + curIdx];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[0x200 + lookup * 2] | (palette[0x200 + lookup * 2 + 1] << 8)));
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
- if (((i - x) & 7) == 7) baseSprite += baseInc;
- }
- }
- else
- {
- // 16 colors
- int palIdx = 0x200 + (((attr2 >> 12) & 0xF) * 16 * 2);
- for (int i = x; i < x + width; i++)
- {
- if ((i & 0x1ff) < 240 && true)
- {
- int tx = (i - x) & 7;
- if ((attr1 & (1 << 12)) != 0) tx = 7 - tx;
- int curIdx = baseSprite * 32 + ((spritey & 7) * 4) + (tx / 2);
- int lookup = vram[0x10000 + curIdx];
- if ((tx & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palIdx + lookup * 2] | (palette[palIdx + lookup * 2 + 1] << 8)));
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
- if (((i - x) & 7) == 7) baseSprite += baseInc;
- }
- }
- }
- else
- {
- int rotScaleParam = (attr1 >> 9) & 0x1F;
-
- short dx = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x6);
- short dmx = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0xE);
- short dy = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x16);
- short dmy = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x1E);
-
- int cx = rwidth / 2;
- int cy = rheight / 2;
-
- int baseSprite = attr2 & 0x3FF;
- int pitch;
-
- if ((this.dispCnt & (1 << 6)) != 0)
- {
- // 1 dimensional
- pitch = (width / 8) * scale;
- }
- else
- {
- // 2 dimensional
- pitch = 0x20;
- }
-
- int rx = (int)((dmx * (spritey - cy)) - (cx * dx) + (width << 7));
- int ry = (int)((dmy * (spritey - cy)) - (cx * dy) + (height << 7));
-
- // Draw a rot/scale sprite
- if ((attr0 & (1 << 13)) != 0)
- {
- // 256 colors
- for (int i = x; i < x + rwidth; i++)
- {
- int tx = rx >> 8;
- int ty = ry >> 8;
-
- if ((i & 0x1ff) < 240 && tx >= 0 && tx < width && ty >= 0 && ty < height
- && true)
- {
- int curIdx = (baseSprite + ((ty / 8) * pitch) + ((tx / 8) * scale)) * 32 + ((ty & 7) * 8) + (tx & 7);
- int lookup = vram[0x10000 + curIdx];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[0x200 + lookup * 2] | (palette[0x200 + lookup * 2 + 1] << 8)));
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
-
- rx += dx;
- ry += dy;
- }
- }
- else
- {
- // 16 colors
- int palIdx = 0x200 + (((attr2 >> 12) & 0xF) * 16 * 2);
- for (int i = x; i < x + rwidth; i++)
- {
- int tx = rx >> 8;
- int ty = ry >> 8;
-
- if ((i & 0x1ff) < 240 && tx >= 0 && tx < width && ty >= 0 && ty < height
- && true)
- {
- int curIdx = (baseSprite + ((ty / 8) * pitch) + ((tx / 8) * scale)) * 32 + ((ty & 7) * 4) + ((tx & 7) / 2);
- int lookup = vram[0x10000 + curIdx];
- if ((tx & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palIdx + lookup * 2] | (palette[palIdx + lookup * 2 + 1] << 8)));
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
-
- rx += dx;
- ry += dy;
- }
- }
- }
- }
- else
- {
- if ((attr0 & (1 << 8)) == 0)
- {
- if ((attr1 & (1 << 13)) != 0) spritey = (height - 1) - spritey;
-
- int baseSprite;
- if ((this.dispCnt & (1 << 6)) != 0)
- {
- // 1 dimensional
- baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * (width / 8)) * scale;
- }
- else
- {
- // 2 dimensional
- baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * 0x20);
- }
-
- int baseInc = scale;
- if ((attr1 & (1 << 12)) != 0)
- {
- baseSprite += ((width / 8) * scale) - scale;
- baseInc = -baseInc;
- }
-
- if ((attr0 & (1 << 13)) != 0)
- {
- // 256 colors
- for (int i = x; i < x + width; i++)
- {
- if ((i & 0x1ff) < 240 && true)
- {
- int tx = (i - x) & 7;
- if ((attr1 & (1 << 12)) != 0) tx = 7 - tx;
- int curIdx = baseSprite * 32 + ((spritey & 7) * 8) + tx;
- int lookup = vram[0x10000 + curIdx];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[0x200 + lookup * 2] | (palette[0x200 + lookup * 2 + 1] << 8)));
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
- if (((i - x) & 7) == 7) baseSprite += baseInc;
- }
- }
- else
- {
- // 16 colors
- int palIdx = 0x200 + (((attr2 >> 12) & 0xF) * 16 * 2);
- for (int i = x; i < x + width; i++)
- {
- if ((i & 0x1ff) < 240 && true)
- {
- int tx = (i - x) & 7;
- if ((attr1 & (1 << 12)) != 0) tx = 7 - tx;
- int curIdx = baseSprite * 32 + ((spritey & 7) * 4) + (tx / 2);
- int lookup = vram[0x10000 + curIdx];
- if ((tx & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palIdx + lookup * 2] | (palette[palIdx + lookup * 2 + 1] << 8)));
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
- if (((i - x) & 7) == 7) baseSprite += baseInc;
- }
- }
- }
- else
- {
- int rotScaleParam = (attr1 >> 9) & 0x1F;
-
- short dx = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x6);
- short dmx = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0xE);
- short dy = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x16);
- short dmy = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x1E);
-
- int cx = rwidth / 2;
- int cy = rheight / 2;
-
- int baseSprite = attr2 & 0x3FF;
- int pitch;
-
- if ((this.dispCnt & (1 << 6)) != 0)
- {
- // 1 dimensional
- pitch = (width / 8) * scale;
- }
- else
- {
- // 2 dimensional
- pitch = 0x20;
- }
-
- int rx = (int)((dmx * (spritey - cy)) - (cx * dx) + (width << 7));
- int ry = (int)((dmy * (spritey - cy)) - (cx * dy) + (height << 7));
-
- // Draw a rot/scale sprite
- if ((attr0 & (1 << 13)) != 0)
- {
- // 256 colors
- for (int i = x; i < x + rwidth; i++)
- {
- int tx = rx >> 8;
- int ty = ry >> 8;
-
- if ((i & 0x1ff) < 240 && tx >= 0 && tx < width && ty >= 0 && ty < height
- && true)
- {
- int curIdx = (baseSprite + ((ty / 8) * pitch) + ((tx / 8) * scale)) * 32 + ((ty & 7) * 8) + (tx & 7);
- int lookup = vram[0x10000 + curIdx];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[0x200 + lookup * 2] | (palette[0x200 + lookup * 2 + 1] << 8)));
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
-
- rx += dx;
- ry += dy;
- }
- }
- else
- {
- // 16 colors
- int palIdx = 0x200 + (((attr2 >> 12) & 0xF) * 16 * 2);
- for (int i = x; i < x + rwidth; i++)
- {
- int tx = rx >> 8;
- int ty = ry >> 8;
-
- if ((i & 0x1ff) < 240 && tx >= 0 && tx < width && ty >= 0 && ty < height
- && true)
- {
- int curIdx = (baseSprite + ((ty / 8) * pitch) + ((tx / 8) * scale)) * 32 + ((ty & 7) * 4) + ((tx & 7) / 2);
- int lookup = vram[0x10000 + curIdx];
- if ((tx & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palIdx + lookup * 2] | (palette[palIdx + lookup * 2 + 1] << 8)));
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
-
- rx += dx;
- ry += dy;
- }
- }
- }
- }
- }
- }
- private void DrawSpritesBlend(int priority)
- {
- byte[] palette = this.memory.PaletteRam;
- byte[] vram = this.memory.VideoRam;
-
- // OBJ must be enabled in this.dispCnt
- if ((this.dispCnt & (1 << 12)) == 0) return;
-
- byte blendMaskType = (byte)(1 << 4);
-
- for (int oamNum = 127; oamNum >= 0; oamNum--)
- {
- ushort attr2 = this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(oamNum * 8) + 4);
-
- if (((attr2 >> 10) & 3) != priority) continue;
-
- ushort attr0 = this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(oamNum * 8) + 0);
- ushort attr1 = this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(oamNum * 8) + 2);
-
- int x = attr1 & 0x1FF;
- int y = attr0 & 0xFF;
-
- bool semiTransparent = false;
-
- switch ((attr0 >> 10) & 3)
- {
- case 1:
- // Semi-transparent
- semiTransparent = true;
- break;
- case 2:
- // Obj window
- continue;
- case 3:
- continue;
- }
-
- if ((this.dispCnt & 0x7) >= 3 && (attr2 & 0x3FF) < 0x200) continue;
-
- int width = -1, height = -1;
- switch ((attr0 >> 14) & 3)
- {
- case 0:
- // Square
- switch ((attr1 >> 14) & 3)
- {
- case 0: width = 8; height = 8; break;
- case 1: width = 16; height = 16; break;
- case 2: width = 32; height = 32; break;
- case 3: width = 64; height = 64; break;
- }
- break;
- case 1:
- // Horizontal Rectangle
- switch ((attr1 >> 14) & 3)
- {
- case 0: width = 16; height = 8; break;
- case 1: width = 32; height = 8; break;
- case 2: width = 32; height = 16; break;
- case 3: width = 64; height = 32; break;
- }
- break;
- case 2:
- // Vertical Rectangle
- switch ((attr1 >> 14) & 3)
- {
- case 0: width = 8; height = 16; break;
- case 1: width = 8; height = 32; break;
- case 2: width = 16; height = 32; break;
- case 3: width = 32; height = 64; break;
- }
- break;
- }
-
- // Check double size flag here
-
- int rwidth = width, rheight = height;
- if ((attr0 & (1 << 8)) != 0)
- {
- // Rot-scale on
- if ((attr0 & (1 << 9)) != 0)
- {
- rwidth *= 2;
- rheight *= 2;
- }
- }
- else
- {
- // Invalid sprite
- if ((attr0 & (1 << 9)) != 0)
- width = -1;
- }
-
- if (width == -1)
- {
- // Invalid sprite
- continue;
- }
-
- // Y clipping
- if (y > ((y + rheight) & 0xff))
- {
- if (this.curLine >= ((y + rheight) & 0xff) && !(y < this.curLine)) continue;
- }
- else
- {
- if (this.curLine < y || this.curLine >= ((y + rheight) & 0xff)) continue;
- }
-
- int scale = 1;
- if ((attr0 & (1 << 13)) != 0) scale = 2;
-
- int spritey = this.curLine - y;
- if (spritey < 0) spritey += 256;
-
- if (semiTransparent)
- {
- if ((attr0 & (1 << 8)) == 0)
- {
- if ((attr1 & (1 << 13)) != 0) spritey = (height - 1) - spritey;
-
- int baseSprite;
- if ((this.dispCnt & (1 << 6)) != 0)
- {
- // 1 dimensional
- baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * (width / 8)) * scale;
- }
- else
- {
- // 2 dimensional
- baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * 0x20);
- }
-
- int baseInc = scale;
- if ((attr1 & (1 << 12)) != 0)
- {
- baseSprite += ((width / 8) * scale) - scale;
- baseInc = -baseInc;
- }
-
- if ((attr0 & (1 << 13)) != 0)
- {
- // 256 colors
- for (int i = x; i < x + width; i++)
- {
- if ((i & 0x1ff) < 240 && true)
- {
- int tx = (i - x) & 7;
- if ((attr1 & (1 << 12)) != 0) tx = 7 - tx;
- int curIdx = baseSprite * 32 + ((spritey & 7) * 8) + tx;
- int lookup = vram[0x10000 + curIdx];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[0x200 + lookup * 2] | (palette[0x200 + lookup * 2 + 1] << 8)));
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
- if (((i - x) & 7) == 7) baseSprite += baseInc;
- }
- }
- else
- {
- // 16 colors
- int palIdx = 0x200 + (((attr2 >> 12) & 0xF) * 16 * 2);
- for (int i = x; i < x + width; i++)
- {
- if ((i & 0x1ff) < 240 && true)
- {
- int tx = (i - x) & 7;
- if ((attr1 & (1 << 12)) != 0) tx = 7 - tx;
- int curIdx = baseSprite * 32 + ((spritey & 7) * 4) + (tx / 2);
- int lookup = vram[0x10000 + curIdx];
- if ((tx & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palIdx + lookup * 2] | (palette[palIdx + lookup * 2 + 1] << 8)));
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
- if (((i - x) & 7) == 7) baseSprite += baseInc;
- }
- }
- }
- else
- {
- int rotScaleParam = (attr1 >> 9) & 0x1F;
-
- short dx = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x6);
- short dmx = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0xE);
- short dy = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x16);
- short dmy = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x1E);
-
- int cx = rwidth / 2;
- int cy = rheight / 2;
-
- int baseSprite = attr2 & 0x3FF;
- int pitch;
-
- if ((this.dispCnt & (1 << 6)) != 0)
- {
- // 1 dimensional
- pitch = (width / 8) * scale;
- }
- else
- {
- // 2 dimensional
- pitch = 0x20;
- }
-
- int rx = (int)((dmx * (spritey - cy)) - (cx * dx) + (width << 7));
- int ry = (int)((dmy * (spritey - cy)) - (cx * dy) + (height << 7));
-
- // Draw a rot/scale sprite
- if ((attr0 & (1 << 13)) != 0)
- {
- // 256 colors
- for (int i = x; i < x + rwidth; i++)
- {
- int tx = rx >> 8;
- int ty = ry >> 8;
-
- if ((i & 0x1ff) < 240 && tx >= 0 && tx < width && ty >= 0 && ty < height
- && true)
- {
- int curIdx = (baseSprite + ((ty / 8) * pitch) + ((tx / 8) * scale)) * 32 + ((ty & 7) * 8) + (tx & 7);
- int lookup = vram[0x10000 + curIdx];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[0x200 + lookup * 2] | (palette[0x200 + lookup * 2 + 1] << 8)));
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
-
- rx += dx;
- ry += dy;
- }
- }
- else
- {
- // 16 colors
- int palIdx = 0x200 + (((attr2 >> 12) & 0xF) * 16 * 2);
- for (int i = x; i < x + rwidth; i++)
- {
- int tx = rx >> 8;
- int ty = ry >> 8;
-
- if ((i & 0x1ff) < 240 && tx >= 0 && tx < width && ty >= 0 && ty < height
- && true)
- {
- int curIdx = (baseSprite + ((ty / 8) * pitch) + ((tx / 8) * scale)) * 32 + ((ty & 7) * 4) + ((tx & 7) / 2);
- int lookup = vram[0x10000 + curIdx];
- if ((tx & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palIdx + lookup * 2] | (palette[palIdx + lookup * 2 + 1] << 8)));
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
-
- rx += dx;
- ry += dy;
- }
- }
- }
- }
- else
- {
- if ((attr0 & (1 << 8)) == 0)
- {
- if ((attr1 & (1 << 13)) != 0) spritey = (height - 1) - spritey;
-
- int baseSprite;
- if ((this.dispCnt & (1 << 6)) != 0)
- {
- // 1 dimensional
- baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * (width / 8)) * scale;
- }
- else
- {
- // 2 dimensional
- baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * 0x20);
- }
-
- int baseInc = scale;
- if ((attr1 & (1 << 12)) != 0)
- {
- baseSprite += ((width / 8) * scale) - scale;
- baseInc = -baseInc;
- }
-
- if ((attr0 & (1 << 13)) != 0)
- {
- // 256 colors
- for (int i = x; i < x + width; i++)
- {
- if ((i & 0x1ff) < 240 && true)
- {
- int tx = (i - x) & 7;
- if ((attr1 & (1 << 12)) != 0) tx = 7 - tx;
- int curIdx = baseSprite * 32 + ((spritey & 7) * 8) + tx;
- int lookup = vram[0x10000 + curIdx];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[0x200 + lookup * 2] | (palette[0x200 + lookup * 2 + 1] << 8)));
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
- if (((i - x) & 7) == 7) baseSprite += baseInc;
- }
- }
- else
- {
- // 16 colors
- int palIdx = 0x200 + (((attr2 >> 12) & 0xF) * 16 * 2);
- for (int i = x; i < x + width; i++)
- {
- if ((i & 0x1ff) < 240 && true)
- {
- int tx = (i - x) & 7;
- if ((attr1 & (1 << 12)) != 0) tx = 7 - tx;
- int curIdx = baseSprite * 32 + ((spritey & 7) * 4) + (tx / 2);
- int lookup = vram[0x10000 + curIdx];
- if ((tx & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palIdx + lookup * 2] | (palette[palIdx + lookup * 2 + 1] << 8)));
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
- if (((i - x) & 7) == 7) baseSprite += baseInc;
- }
- }
- }
- else
- {
- int rotScaleParam = (attr1 >> 9) & 0x1F;
-
- short dx = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x6);
- short dmx = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0xE);
- short dy = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x16);
- short dmy = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x1E);
-
- int cx = rwidth / 2;
- int cy = rheight / 2;
-
- int baseSprite = attr2 & 0x3FF;
- int pitch;
-
- if ((this.dispCnt & (1 << 6)) != 0)
- {
- // 1 dimensional
- pitch = (width / 8) * scale;
- }
- else
- {
- // 2 dimensional
- pitch = 0x20;
- }
-
- int rx = (int)((dmx * (spritey - cy)) - (cx * dx) + (width << 7));
- int ry = (int)((dmy * (spritey - cy)) - (cx * dy) + (height << 7));
-
- // Draw a rot/scale sprite
- if ((attr0 & (1 << 13)) != 0)
- {
- // 256 colors
- for (int i = x; i < x + rwidth; i++)
- {
- int tx = rx >> 8;
- int ty = ry >> 8;
-
- if ((i & 0x1ff) < 240 && tx >= 0 && tx < width && ty >= 0 && ty < height
- && true)
- {
- int curIdx = (baseSprite + ((ty / 8) * pitch) + ((tx / 8) * scale)) * 32 + ((ty & 7) * 8) + (tx & 7);
- int lookup = vram[0x10000 + curIdx];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[0x200 + lookup * 2] | (palette[0x200 + lookup * 2 + 1] << 8)));
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
-
- rx += dx;
- ry += dy;
- }
- }
- else
- {
- // 16 colors
- int palIdx = 0x200 + (((attr2 >> 12) & 0xF) * 16 * 2);
- for (int i = x; i < x + rwidth; i++)
- {
- int tx = rx >> 8;
- int ty = ry >> 8;
-
- if ((i & 0x1ff) < 240 && tx >= 0 && tx < width && ty >= 0 && ty < height
- && true)
- {
- int curIdx = (baseSprite + ((ty / 8) * pitch) + ((tx / 8) * scale)) * 32 + ((ty & 7) * 4) + ((tx & 7) / 2);
- int lookup = vram[0x10000 + curIdx];
- if ((tx & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palIdx + lookup * 2] | (palette[palIdx + lookup * 2 + 1] << 8)));
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
-
- rx += dx;
- ry += dy;
- }
- }
- }
- }
- }
- }
- private void DrawSpritesBrightInc(int priority)
- {
- byte[] palette = this.memory.PaletteRam;
- byte[] vram = this.memory.VideoRam;
-
- // OBJ must be enabled in this.dispCnt
- if ((this.dispCnt & (1 << 12)) == 0) return;
-
- byte blendMaskType = (byte)(1 << 4);
-
- for (int oamNum = 127; oamNum >= 0; oamNum--)
- {
- ushort attr2 = this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(oamNum * 8) + 4);
-
- if (((attr2 >> 10) & 3) != priority) continue;
-
- ushort attr0 = this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(oamNum * 8) + 0);
- ushort attr1 = this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(oamNum * 8) + 2);
-
- int x = attr1 & 0x1FF;
- int y = attr0 & 0xFF;
-
- bool semiTransparent = false;
-
- switch ((attr0 >> 10) & 3)
- {
- case 1:
- // Semi-transparent
- semiTransparent = true;
- break;
- case 2:
- // Obj window
- continue;
- case 3:
- continue;
- }
-
- if ((this.dispCnt & 0x7) >= 3 && (attr2 & 0x3FF) < 0x200) continue;
-
- int width = -1, height = -1;
- switch ((attr0 >> 14) & 3)
- {
- case 0:
- // Square
- switch ((attr1 >> 14) & 3)
- {
- case 0: width = 8; height = 8; break;
- case 1: width = 16; height = 16; break;
- case 2: width = 32; height = 32; break;
- case 3: width = 64; height = 64; break;
- }
- break;
- case 1:
- // Horizontal Rectangle
- switch ((attr1 >> 14) & 3)
- {
- case 0: width = 16; height = 8; break;
- case 1: width = 32; height = 8; break;
- case 2: width = 32; height = 16; break;
- case 3: width = 64; height = 32; break;
- }
- break;
- case 2:
- // Vertical Rectangle
- switch ((attr1 >> 14) & 3)
- {
- case 0: width = 8; height = 16; break;
- case 1: width = 8; height = 32; break;
- case 2: width = 16; height = 32; break;
- case 3: width = 32; height = 64; break;
- }
- break;
- }
-
- // Check double size flag here
-
- int rwidth = width, rheight = height;
- if ((attr0 & (1 << 8)) != 0)
- {
- // Rot-scale on
- if ((attr0 & (1 << 9)) != 0)
- {
- rwidth *= 2;
- rheight *= 2;
- }
- }
- else
- {
- // Invalid sprite
- if ((attr0 & (1 << 9)) != 0)
- width = -1;
- }
-
- if (width == -1)
- {
- // Invalid sprite
- continue;
- }
-
- // Y clipping
- if (y > ((y + rheight) & 0xff))
- {
- if (this.curLine >= ((y + rheight) & 0xff) && !(y < this.curLine)) continue;
- }
- else
- {
- if (this.curLine < y || this.curLine >= ((y + rheight) & 0xff)) continue;
- }
-
- int scale = 1;
- if ((attr0 & (1 << 13)) != 0) scale = 2;
-
- int spritey = this.curLine - y;
- if (spritey < 0) spritey += 256;
-
- if (semiTransparent)
- {
- if ((attr0 & (1 << 8)) == 0)
- {
- if ((attr1 & (1 << 13)) != 0) spritey = (height - 1) - spritey;
-
- int baseSprite;
- if ((this.dispCnt & (1 << 6)) != 0)
- {
- // 1 dimensional
- baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * (width / 8)) * scale;
- }
- else
- {
- // 2 dimensional
- baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * 0x20);
- }
-
- int baseInc = scale;
- if ((attr1 & (1 << 12)) != 0)
- {
- baseSprite += ((width / 8) * scale) - scale;
- baseInc = -baseInc;
- }
-
- if ((attr0 & (1 << 13)) != 0)
- {
- // 256 colors
- for (int i = x; i < x + width; i++)
- {
- if ((i & 0x1ff) < 240 && true)
- {
- int tx = (i - x) & 7;
- if ((attr1 & (1 << 12)) != 0) tx = 7 - tx;
- int curIdx = baseSprite * 32 + ((spritey & 7) * 8) + tx;
- int lookup = vram[0x10000 + curIdx];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[0x200 + lookup * 2] | (palette[0x200 + lookup * 2 + 1] << 8)));
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
- if (((i - x) & 7) == 7) baseSprite += baseInc;
- }
- }
- else
- {
- // 16 colors
- int palIdx = 0x200 + (((attr2 >> 12) & 0xF) * 16 * 2);
- for (int i = x; i < x + width; i++)
- {
- if ((i & 0x1ff) < 240 && true)
- {
- int tx = (i - x) & 7;
- if ((attr1 & (1 << 12)) != 0) tx = 7 - tx;
- int curIdx = baseSprite * 32 + ((spritey & 7) * 4) + (tx / 2);
- int lookup = vram[0x10000 + curIdx];
- if ((tx & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palIdx + lookup * 2] | (palette[palIdx + lookup * 2 + 1] << 8)));
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
- if (((i - x) & 7) == 7) baseSprite += baseInc;
- }
- }
- }
- else
- {
- int rotScaleParam = (attr1 >> 9) & 0x1F;
-
- short dx = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x6);
- short dmx = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0xE);
- short dy = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x16);
- short dmy = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x1E);
-
- int cx = rwidth / 2;
- int cy = rheight / 2;
-
- int baseSprite = attr2 & 0x3FF;
- int pitch;
-
- if ((this.dispCnt & (1 << 6)) != 0)
- {
- // 1 dimensional
- pitch = (width / 8) * scale;
- }
- else
- {
- // 2 dimensional
- pitch = 0x20;
- }
-
- int rx = (int)((dmx * (spritey - cy)) - (cx * dx) + (width << 7));
- int ry = (int)((dmy * (spritey - cy)) - (cx * dy) + (height << 7));
-
- // Draw a rot/scale sprite
- if ((attr0 & (1 << 13)) != 0)
- {
- // 256 colors
- for (int i = x; i < x + rwidth; i++)
- {
- int tx = rx >> 8;
- int ty = ry >> 8;
-
- if ((i & 0x1ff) < 240 && tx >= 0 && tx < width && ty >= 0 && ty < height
- && true)
- {
- int curIdx = (baseSprite + ((ty / 8) * pitch) + ((tx / 8) * scale)) * 32 + ((ty & 7) * 8) + (tx & 7);
- int lookup = vram[0x10000 + curIdx];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[0x200 + lookup * 2] | (palette[0x200 + lookup * 2 + 1] << 8)));
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
-
- rx += dx;
- ry += dy;
- }
- }
- else
- {
- // 16 colors
- int palIdx = 0x200 + (((attr2 >> 12) & 0xF) * 16 * 2);
- for (int i = x; i < x + rwidth; i++)
- {
- int tx = rx >> 8;
- int ty = ry >> 8;
-
- if ((i & 0x1ff) < 240 && tx >= 0 && tx < width && ty >= 0 && ty < height
- && true)
- {
- int curIdx = (baseSprite + ((ty / 8) * pitch) + ((tx / 8) * scale)) * 32 + ((ty & 7) * 4) + ((tx & 7) / 2);
- int lookup = vram[0x10000 + curIdx];
- if ((tx & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palIdx + lookup * 2] | (palette[palIdx + lookup * 2 + 1] << 8)));
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
-
- rx += dx;
- ry += dy;
- }
- }
- }
- }
- else
- {
- if ((attr0 & (1 << 8)) == 0)
- {
- if ((attr1 & (1 << 13)) != 0) spritey = (height - 1) - spritey;
-
- int baseSprite;
- if ((this.dispCnt & (1 << 6)) != 0)
- {
- // 1 dimensional
- baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * (width / 8)) * scale;
- }
- else
- {
- // 2 dimensional
- baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * 0x20);
- }
-
- int baseInc = scale;
- if ((attr1 & (1 << 12)) != 0)
- {
- baseSprite += ((width / 8) * scale) - scale;
- baseInc = -baseInc;
- }
-
- if ((attr0 & (1 << 13)) != 0)
- {
- // 256 colors
- for (int i = x; i < x + width; i++)
- {
- if ((i & 0x1ff) < 240 && true)
- {
- int tx = (i - x) & 7;
- if ((attr1 & (1 << 12)) != 0) tx = 7 - tx;
- int curIdx = baseSprite * 32 + ((spritey & 7) * 8) + tx;
- int lookup = vram[0x10000 + curIdx];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[0x200 + lookup * 2] | (palette[0x200 + lookup * 2 + 1] << 8)));
- uint r = pixelColor & 0xFF;
- uint g = (pixelColor >> 8) & 0xFF;
- uint b = (pixelColor >> 16) & 0xFF;
- r = r + (((0xFF - r) * this.blendY) >> 4);
- g = g + (((0xFF - g) * this.blendY) >> 4);
- b = b + (((0xFF - b) * this.blendY) >> 4);
- pixelColor = r | (g << 8) | (b << 16);
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
- if (((i - x) & 7) == 7) baseSprite += baseInc;
- }
- }
- else
- {
- // 16 colors
- int palIdx = 0x200 + (((attr2 >> 12) & 0xF) * 16 * 2);
- for (int i = x; i < x + width; i++)
- {
- if ((i & 0x1ff) < 240 && true)
- {
- int tx = (i - x) & 7;
- if ((attr1 & (1 << 12)) != 0) tx = 7 - tx;
- int curIdx = baseSprite * 32 + ((spritey & 7) * 4) + (tx / 2);
- int lookup = vram[0x10000 + curIdx];
- if ((tx & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palIdx + lookup * 2] | (palette[palIdx + lookup * 2 + 1] << 8)));
- uint r = pixelColor & 0xFF;
- uint g = (pixelColor >> 8) & 0xFF;
- uint b = (pixelColor >> 16) & 0xFF;
- r = r + (((0xFF - r) * this.blendY) >> 4);
- g = g + (((0xFF - g) * this.blendY) >> 4);
- b = b + (((0xFF - b) * this.blendY) >> 4);
- pixelColor = r | (g << 8) | (b << 16);
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
- if (((i - x) & 7) == 7) baseSprite += baseInc;
- }
- }
- }
- else
- {
- int rotScaleParam = (attr1 >> 9) & 0x1F;
-
- short dx = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x6);
- short dmx = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0xE);
- short dy = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x16);
- short dmy = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x1E);
-
- int cx = rwidth / 2;
- int cy = rheight / 2;
-
- int baseSprite = attr2 & 0x3FF;
- int pitch;
-
- if ((this.dispCnt & (1 << 6)) != 0)
- {
- // 1 dimensional
- pitch = (width / 8) * scale;
- }
- else
- {
- // 2 dimensional
- pitch = 0x20;
- }
-
- int rx = (int)((dmx * (spritey - cy)) - (cx * dx) + (width << 7));
- int ry = (int)((dmy * (spritey - cy)) - (cx * dy) + (height << 7));
-
- // Draw a rot/scale sprite
- if ((attr0 & (1 << 13)) != 0)
- {
- // 256 colors
- for (int i = x; i < x + rwidth; i++)
- {
- int tx = rx >> 8;
- int ty = ry >> 8;
-
- if ((i & 0x1ff) < 240 && tx >= 0 && tx < width && ty >= 0 && ty < height
- && true)
- {
- int curIdx = (baseSprite + ((ty / 8) * pitch) + ((tx / 8) * scale)) * 32 + ((ty & 7) * 8) + (tx & 7);
- int lookup = vram[0x10000 + curIdx];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[0x200 + lookup * 2] | (palette[0x200 + lookup * 2 + 1] << 8)));
- uint r = pixelColor & 0xFF;
- uint g = (pixelColor >> 8) & 0xFF;
- uint b = (pixelColor >> 16) & 0xFF;
- r = r + (((0xFF - r) * this.blendY) >> 4);
- g = g + (((0xFF - g) * this.blendY) >> 4);
- b = b + (((0xFF - b) * this.blendY) >> 4);
- pixelColor = r | (g << 8) | (b << 16);
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
-
- rx += dx;
- ry += dy;
- }
- }
- else
- {
- // 16 colors
- int palIdx = 0x200 + (((attr2 >> 12) & 0xF) * 16 * 2);
- for (int i = x; i < x + rwidth; i++)
- {
- int tx = rx >> 8;
- int ty = ry >> 8;
-
- if ((i & 0x1ff) < 240 && tx >= 0 && tx < width && ty >= 0 && ty < height
- && true)
- {
- int curIdx = (baseSprite + ((ty / 8) * pitch) + ((tx / 8) * scale)) * 32 + ((ty & 7) * 4) + ((tx & 7) / 2);
- int lookup = vram[0x10000 + curIdx];
- if ((tx & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palIdx + lookup * 2] | (palette[palIdx + lookup * 2 + 1] << 8)));
- uint r = pixelColor & 0xFF;
- uint g = (pixelColor >> 8) & 0xFF;
- uint b = (pixelColor >> 16) & 0xFF;
- r = r + (((0xFF - r) * this.blendY) >> 4);
- g = g + (((0xFF - g) * this.blendY) >> 4);
- b = b + (((0xFF - b) * this.blendY) >> 4);
- pixelColor = r | (g << 8) | (b << 16);
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
-
- rx += dx;
- ry += dy;
- }
- }
- }
- }
- }
- }
- private void DrawSpritesBrightDec(int priority)
- {
- byte[] palette = this.memory.PaletteRam;
- byte[] vram = this.memory.VideoRam;
-
- // OBJ must be enabled in this.dispCnt
- if ((this.dispCnt & (1 << 12)) == 0) return;
-
- byte blendMaskType = (byte)(1 << 4);
-
- for (int oamNum = 127; oamNum >= 0; oamNum--)
- {
- ushort attr2 = this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(oamNum * 8) + 4);
-
- if (((attr2 >> 10) & 3) != priority) continue;
-
- ushort attr0 = this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(oamNum * 8) + 0);
- ushort attr1 = this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(oamNum * 8) + 2);
-
- int x = attr1 & 0x1FF;
- int y = attr0 & 0xFF;
-
- bool semiTransparent = false;
-
- switch ((attr0 >> 10) & 3)
- {
- case 1:
- // Semi-transparent
- semiTransparent = true;
- break;
- case 2:
- // Obj window
- continue;
- case 3:
- continue;
- }
-
- if ((this.dispCnt & 0x7) >= 3 && (attr2 & 0x3FF) < 0x200) continue;
-
- int width = -1, height = -1;
- switch ((attr0 >> 14) & 3)
- {
- case 0:
- // Square
- switch ((attr1 >> 14) & 3)
- {
- case 0: width = 8; height = 8; break;
- case 1: width = 16; height = 16; break;
- case 2: width = 32; height = 32; break;
- case 3: width = 64; height = 64; break;
- }
- break;
- case 1:
- // Horizontal Rectangle
- switch ((attr1 >> 14) & 3)
- {
- case 0: width = 16; height = 8; break;
- case 1: width = 32; height = 8; break;
- case 2: width = 32; height = 16; break;
- case 3: width = 64; height = 32; break;
- }
- break;
- case 2:
- // Vertical Rectangle
- switch ((attr1 >> 14) & 3)
- {
- case 0: width = 8; height = 16; break;
- case 1: width = 8; height = 32; break;
- case 2: width = 16; height = 32; break;
- case 3: width = 32; height = 64; break;
- }
- break;
- }
-
- // Check double size flag here
-
- int rwidth = width, rheight = height;
- if ((attr0 & (1 << 8)) != 0)
- {
- // Rot-scale on
- if ((attr0 & (1 << 9)) != 0)
- {
- rwidth *= 2;
- rheight *= 2;
- }
- }
- else
- {
- // Invalid sprite
- if ((attr0 & (1 << 9)) != 0)
- width = -1;
- }
-
- if (width == -1)
- {
- // Invalid sprite
- continue;
- }
-
- // Y clipping
- if (y > ((y + rheight) & 0xff))
- {
- if (this.curLine >= ((y + rheight) & 0xff) && !(y < this.curLine)) continue;
- }
- else
- {
- if (this.curLine < y || this.curLine >= ((y + rheight) & 0xff)) continue;
- }
-
- int scale = 1;
- if ((attr0 & (1 << 13)) != 0) scale = 2;
-
- int spritey = this.curLine - y;
- if (spritey < 0) spritey += 256;
-
- if (semiTransparent)
- {
- if ((attr0 & (1 << 8)) == 0)
- {
- if ((attr1 & (1 << 13)) != 0) spritey = (height - 1) - spritey;
-
- int baseSprite;
- if ((this.dispCnt & (1 << 6)) != 0)
- {
- // 1 dimensional
- baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * (width / 8)) * scale;
- }
- else
- {
- // 2 dimensional
- baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * 0x20);
- }
-
- int baseInc = scale;
- if ((attr1 & (1 << 12)) != 0)
- {
- baseSprite += ((width / 8) * scale) - scale;
- baseInc = -baseInc;
- }
-
- if ((attr0 & (1 << 13)) != 0)
- {
- // 256 colors
- for (int i = x; i < x + width; i++)
- {
- if ((i & 0x1ff) < 240 && true)
- {
- int tx = (i - x) & 7;
- if ((attr1 & (1 << 12)) != 0) tx = 7 - tx;
- int curIdx = baseSprite * 32 + ((spritey & 7) * 8) + tx;
- int lookup = vram[0x10000 + curIdx];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[0x200 + lookup * 2] | (palette[0x200 + lookup * 2 + 1] << 8)));
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
- if (((i - x) & 7) == 7) baseSprite += baseInc;
- }
- }
- else
- {
- // 16 colors
- int palIdx = 0x200 + (((attr2 >> 12) & 0xF) * 16 * 2);
- for (int i = x; i < x + width; i++)
- {
- if ((i & 0x1ff) < 240 && true)
- {
- int tx = (i - x) & 7;
- if ((attr1 & (1 << 12)) != 0) tx = 7 - tx;
- int curIdx = baseSprite * 32 + ((spritey & 7) * 4) + (tx / 2);
- int lookup = vram[0x10000 + curIdx];
- if ((tx & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palIdx + lookup * 2] | (palette[palIdx + lookup * 2 + 1] << 8)));
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
- if (((i - x) & 7) == 7) baseSprite += baseInc;
- }
- }
- }
- else
- {
- int rotScaleParam = (attr1 >> 9) & 0x1F;
-
- short dx = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x6);
- short dmx = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0xE);
- short dy = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x16);
- short dmy = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x1E);
-
- int cx = rwidth / 2;
- int cy = rheight / 2;
-
- int baseSprite = attr2 & 0x3FF;
- int pitch;
-
- if ((this.dispCnt & (1 << 6)) != 0)
- {
- // 1 dimensional
- pitch = (width / 8) * scale;
- }
- else
- {
- // 2 dimensional
- pitch = 0x20;
- }
-
- int rx = (int)((dmx * (spritey - cy)) - (cx * dx) + (width << 7));
- int ry = (int)((dmy * (spritey - cy)) - (cx * dy) + (height << 7));
-
- // Draw a rot/scale sprite
- if ((attr0 & (1 << 13)) != 0)
- {
- // 256 colors
- for (int i = x; i < x + rwidth; i++)
- {
- int tx = rx >> 8;
- int ty = ry >> 8;
-
- if ((i & 0x1ff) < 240 && tx >= 0 && tx < width && ty >= 0 && ty < height
- && true)
- {
- int curIdx = (baseSprite + ((ty / 8) * pitch) + ((tx / 8) * scale)) * 32 + ((ty & 7) * 8) + (tx & 7);
- int lookup = vram[0x10000 + curIdx];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[0x200 + lookup * 2] | (palette[0x200 + lookup * 2 + 1] << 8)));
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
-
- rx += dx;
- ry += dy;
- }
- }
- else
- {
- // 16 colors
- int palIdx = 0x200 + (((attr2 >> 12) & 0xF) * 16 * 2);
- for (int i = x; i < x + rwidth; i++)
- {
- int tx = rx >> 8;
- int ty = ry >> 8;
-
- if ((i & 0x1ff) < 240 && tx >= 0 && tx < width && ty >= 0 && ty < height
- && true)
- {
- int curIdx = (baseSprite + ((ty / 8) * pitch) + ((tx / 8) * scale)) * 32 + ((ty & 7) * 4) + ((tx & 7) / 2);
- int lookup = vram[0x10000 + curIdx];
- if ((tx & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palIdx + lookup * 2] | (palette[palIdx + lookup * 2 + 1] << 8)));
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
-
- rx += dx;
- ry += dy;
- }
- }
- }
- }
- else
- {
- if ((attr0 & (1 << 8)) == 0)
- {
- if ((attr1 & (1 << 13)) != 0) spritey = (height - 1) - spritey;
-
- int baseSprite;
- if ((this.dispCnt & (1 << 6)) != 0)
- {
- // 1 dimensional
- baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * (width / 8)) * scale;
- }
- else
- {
- // 2 dimensional
- baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * 0x20);
- }
-
- int baseInc = scale;
- if ((attr1 & (1 << 12)) != 0)
- {
- baseSprite += ((width / 8) * scale) - scale;
- baseInc = -baseInc;
- }
-
- if ((attr0 & (1 << 13)) != 0)
- {
- // 256 colors
- for (int i = x; i < x + width; i++)
- {
- if ((i & 0x1ff) < 240 && true)
- {
- int tx = (i - x) & 7;
- if ((attr1 & (1 << 12)) != 0) tx = 7 - tx;
- int curIdx = baseSprite * 32 + ((spritey & 7) * 8) + tx;
- int lookup = vram[0x10000 + curIdx];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[0x200 + lookup * 2] | (palette[0x200 + lookup * 2 + 1] << 8)));
- uint r = pixelColor & 0xFF;
- uint g = (pixelColor >> 8) & 0xFF;
- uint b = (pixelColor >> 16) & 0xFF;
- r = r - ((r * this.blendY) >> 4);
- g = g - ((g * this.blendY) >> 4);
- b = b - ((b * this.blendY) >> 4);
- pixelColor = r | (g << 8) | (b << 16);
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
- if (((i - x) & 7) == 7) baseSprite += baseInc;
- }
- }
- else
- {
- // 16 colors
- int palIdx = 0x200 + (((attr2 >> 12) & 0xF) * 16 * 2);
- for (int i = x; i < x + width; i++)
- {
- if ((i & 0x1ff) < 240 && true)
- {
- int tx = (i - x) & 7;
- if ((attr1 & (1 << 12)) != 0) tx = 7 - tx;
- int curIdx = baseSprite * 32 + ((spritey & 7) * 4) + (tx / 2);
- int lookup = vram[0x10000 + curIdx];
- if ((tx & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palIdx + lookup * 2] | (palette[palIdx + lookup * 2 + 1] << 8)));
- uint r = pixelColor & 0xFF;
- uint g = (pixelColor >> 8) & 0xFF;
- uint b = (pixelColor >> 16) & 0xFF;
- r = r - ((r * this.blendY) >> 4);
- g = g - ((g * this.blendY) >> 4);
- b = b - ((b * this.blendY) >> 4);
- pixelColor = r | (g << 8) | (b << 16);
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
- if (((i - x) & 7) == 7) baseSprite += baseInc;
- }
- }
- }
- else
- {
- int rotScaleParam = (attr1 >> 9) & 0x1F;
-
- short dx = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x6);
- short dmx = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0xE);
- short dy = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x16);
- short dmy = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x1E);
-
- int cx = rwidth / 2;
- int cy = rheight / 2;
-
- int baseSprite = attr2 & 0x3FF;
- int pitch;
-
- if ((this.dispCnt & (1 << 6)) != 0)
- {
- // 1 dimensional
- pitch = (width / 8) * scale;
- }
- else
- {
- // 2 dimensional
- pitch = 0x20;
- }
-
- int rx = (int)((dmx * (spritey - cy)) - (cx * dx) + (width << 7));
- int ry = (int)((dmy * (spritey - cy)) - (cx * dy) + (height << 7));
-
- // Draw a rot/scale sprite
- if ((attr0 & (1 << 13)) != 0)
- {
- // 256 colors
- for (int i = x; i < x + rwidth; i++)
- {
- int tx = rx >> 8;
- int ty = ry >> 8;
-
- if ((i & 0x1ff) < 240 && tx >= 0 && tx < width && ty >= 0 && ty < height
- && true)
- {
- int curIdx = (baseSprite + ((ty / 8) * pitch) + ((tx / 8) * scale)) * 32 + ((ty & 7) * 8) + (tx & 7);
- int lookup = vram[0x10000 + curIdx];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[0x200 + lookup * 2] | (palette[0x200 + lookup * 2 + 1] << 8)));
- uint r = pixelColor & 0xFF;
- uint g = (pixelColor >> 8) & 0xFF;
- uint b = (pixelColor >> 16) & 0xFF;
- r = r - ((r * this.blendY) >> 4);
- g = g - ((g * this.blendY) >> 4);
- b = b - ((b * this.blendY) >> 4);
- pixelColor = r | (g << 8) | (b << 16);
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
-
- rx += dx;
- ry += dy;
- }
- }
- else
- {
- // 16 colors
- int palIdx = 0x200 + (((attr2 >> 12) & 0xF) * 16 * 2);
- for (int i = x; i < x + rwidth; i++)
- {
- int tx = rx >> 8;
- int ty = ry >> 8;
-
- if ((i & 0x1ff) < 240 && tx >= 0 && tx < width && ty >= 0 && ty < height
- && true)
- {
- int curIdx = (baseSprite + ((ty / 8) * pitch) + ((tx / 8) * scale)) * 32 + ((ty & 7) * 4) + ((tx & 7) / 2);
- int lookup = vram[0x10000 + curIdx];
- if ((tx & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palIdx + lookup * 2] | (palette[palIdx + lookup * 2 + 1] << 8)));
- uint r = pixelColor & 0xFF;
- uint g = (pixelColor >> 8) & 0xFF;
- uint b = (pixelColor >> 16) & 0xFF;
- r = r - ((r * this.blendY) >> 4);
- g = g - ((g * this.blendY) >> 4);
- b = b - ((b * this.blendY) >> 4);
- pixelColor = r | (g << 8) | (b << 16);
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
-
- rx += dx;
- ry += dy;
- }
- }
- }
- }
- }
- }
- private void DrawSpritesWindow(int priority)
- {
- byte[] palette = this.memory.PaletteRam;
- byte[] vram = this.memory.VideoRam;
-
- // OBJ must be enabled in this.dispCnt
- if ((this.dispCnt & (1 << 12)) == 0) return;
-
- byte blendMaskType = (byte)(1 << 4);
-
- for (int oamNum = 127; oamNum >= 0; oamNum--)
- {
- ushort attr2 = this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(oamNum * 8) + 4);
-
- if (((attr2 >> 10) & 3) != priority) continue;
-
- ushort attr0 = this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(oamNum * 8) + 0);
- ushort attr1 = this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(oamNum * 8) + 2);
-
- int x = attr1 & 0x1FF;
- int y = attr0 & 0xFF;
-
- bool semiTransparent = false;
-
- switch ((attr0 >> 10) & 3)
- {
- case 1:
- // Semi-transparent
- semiTransparent = true;
- break;
- case 2:
- // Obj window
- continue;
- case 3:
- continue;
- }
-
- if ((this.dispCnt & 0x7) >= 3 && (attr2 & 0x3FF) < 0x200) continue;
-
- int width = -1, height = -1;
- switch ((attr0 >> 14) & 3)
- {
- case 0:
- // Square
- switch ((attr1 >> 14) & 3)
- {
- case 0: width = 8; height = 8; break;
- case 1: width = 16; height = 16; break;
- case 2: width = 32; height = 32; break;
- case 3: width = 64; height = 64; break;
- }
- break;
- case 1:
- // Horizontal Rectangle
- switch ((attr1 >> 14) & 3)
- {
- case 0: width = 16; height = 8; break;
- case 1: width = 32; height = 8; break;
- case 2: width = 32; height = 16; break;
- case 3: width = 64; height = 32; break;
- }
- break;
- case 2:
- // Vertical Rectangle
- switch ((attr1 >> 14) & 3)
- {
- case 0: width = 8; height = 16; break;
- case 1: width = 8; height = 32; break;
- case 2: width = 16; height = 32; break;
- case 3: width = 32; height = 64; break;
- }
- break;
- }
-
- // Check double size flag here
-
- int rwidth = width, rheight = height;
- if ((attr0 & (1 << 8)) != 0)
- {
- // Rot-scale on
- if ((attr0 & (1 << 9)) != 0)
- {
- rwidth *= 2;
- rheight *= 2;
- }
- }
- else
- {
- // Invalid sprite
- if ((attr0 & (1 << 9)) != 0)
- width = -1;
- }
-
- if (width == -1)
- {
- // Invalid sprite
- continue;
- }
-
- // Y clipping
- if (y > ((y + rheight) & 0xff))
- {
- if (this.curLine >= ((y + rheight) & 0xff) && !(y < this.curLine)) continue;
- }
- else
- {
- if (this.curLine < y || this.curLine >= ((y + rheight) & 0xff)) continue;
- }
-
- int scale = 1;
- if ((attr0 & (1 << 13)) != 0) scale = 2;
-
- int spritey = this.curLine - y;
- if (spritey < 0) spritey += 256;
-
- if (semiTransparent)
- {
- if ((attr0 & (1 << 8)) == 0)
- {
- if ((attr1 & (1 << 13)) != 0) spritey = (height - 1) - spritey;
-
- int baseSprite;
- if ((this.dispCnt & (1 << 6)) != 0)
- {
- // 1 dimensional
- baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * (width / 8)) * scale;
- }
- else
- {
- // 2 dimensional
- baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * 0x20);
- }
-
- int baseInc = scale;
- if ((attr1 & (1 << 12)) != 0)
- {
- baseSprite += ((width / 8) * scale) - scale;
- baseInc = -baseInc;
- }
-
- if ((attr0 & (1 << 13)) != 0)
- {
- // 256 colors
- for (int i = x; i < x + width; i++)
- {
- if ((i & 0x1ff) < 240 && (this.windowCover[i & 0x1ff] & (1 << 4)) != 0)
- {
- int tx = (i - x) & 7;
- if ((attr1 & (1 << 12)) != 0) tx = 7 - tx;
- int curIdx = baseSprite * 32 + ((spritey & 7) * 8) + tx;
- int lookup = vram[0x10000 + curIdx];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[0x200 + lookup * 2] | (palette[0x200 + lookup * 2 + 1] << 8)));
- if ((this.windowCover[i & 0x1ff] & (1 << 5)) != 0)
- {
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
- if (((i - x) & 7) == 7) baseSprite += baseInc;
- }
- }
- else
- {
- // 16 colors
- int palIdx = 0x200 + (((attr2 >> 12) & 0xF) * 16 * 2);
- for (int i = x; i < x + width; i++)
- {
- if ((i & 0x1ff) < 240 && (this.windowCover[i & 0x1ff] & (1 << 4)) != 0)
- {
- int tx = (i - x) & 7;
- if ((attr1 & (1 << 12)) != 0) tx = 7 - tx;
- int curIdx = baseSprite * 32 + ((spritey & 7) * 4) + (tx / 2);
- int lookup = vram[0x10000 + curIdx];
- if ((tx & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palIdx + lookup * 2] | (palette[palIdx + lookup * 2 + 1] << 8)));
- if ((this.windowCover[i & 0x1ff] & (1 << 5)) != 0)
- {
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
- if (((i - x) & 7) == 7) baseSprite += baseInc;
- }
- }
- }
- else
- {
- int rotScaleParam = (attr1 >> 9) & 0x1F;
-
- short dx = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x6);
- short dmx = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0xE);
- short dy = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x16);
- short dmy = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x1E);
-
- int cx = rwidth / 2;
- int cy = rheight / 2;
-
- int baseSprite = attr2 & 0x3FF;
- int pitch;
-
- if ((this.dispCnt & (1 << 6)) != 0)
- {
- // 1 dimensional
- pitch = (width / 8) * scale;
- }
- else
- {
- // 2 dimensional
- pitch = 0x20;
- }
-
- int rx = (int)((dmx * (spritey - cy)) - (cx * dx) + (width << 7));
- int ry = (int)((dmy * (spritey - cy)) - (cx * dy) + (height << 7));
-
- // Draw a rot/scale sprite
- if ((attr0 & (1 << 13)) != 0)
- {
- // 256 colors
- for (int i = x; i < x + rwidth; i++)
- {
- int tx = rx >> 8;
- int ty = ry >> 8;
-
- if ((i & 0x1ff) < 240 && tx >= 0 && tx < width && ty >= 0 && ty < height
- && (this.windowCover[i & 0x1ff] & (1 << 4)) != 0)
- {
- int curIdx = (baseSprite + ((ty / 8) * pitch) + ((tx / 8) * scale)) * 32 + ((ty & 7) * 8) + (tx & 7);
- int lookup = vram[0x10000 + curIdx];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[0x200 + lookup * 2] | (palette[0x200 + lookup * 2 + 1] << 8)));
- if ((this.windowCover[i & 0x1ff] & (1 << 5)) != 0)
- {
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
-
- rx += dx;
- ry += dy;
- }
- }
- else
- {
- // 16 colors
- int palIdx = 0x200 + (((attr2 >> 12) & 0xF) * 16 * 2);
- for (int i = x; i < x + rwidth; i++)
- {
- int tx = rx >> 8;
- int ty = ry >> 8;
-
- if ((i & 0x1ff) < 240 && tx >= 0 && tx < width && ty >= 0 && ty < height
- && (this.windowCover[i & 0x1ff] & (1 << 4)) != 0)
- {
- int curIdx = (baseSprite + ((ty / 8) * pitch) + ((tx / 8) * scale)) * 32 + ((ty & 7) * 4) + ((tx & 7) / 2);
- int lookup = vram[0x10000 + curIdx];
- if ((tx & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palIdx + lookup * 2] | (palette[palIdx + lookup * 2 + 1] << 8)));
- if ((this.windowCover[i & 0x1ff] & (1 << 5)) != 0)
- {
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
-
- rx += dx;
- ry += dy;
- }
- }
- }
- }
- else
- {
- if ((attr0 & (1 << 8)) == 0)
- {
- if ((attr1 & (1 << 13)) != 0) spritey = (height - 1) - spritey;
-
- int baseSprite;
- if ((this.dispCnt & (1 << 6)) != 0)
- {
- // 1 dimensional
- baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * (width / 8)) * scale;
- }
- else
- {
- // 2 dimensional
- baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * 0x20);
- }
-
- int baseInc = scale;
- if ((attr1 & (1 << 12)) != 0)
- {
- baseSprite += ((width / 8) * scale) - scale;
- baseInc = -baseInc;
- }
-
- if ((attr0 & (1 << 13)) != 0)
- {
- // 256 colors
- for (int i = x; i < x + width; i++)
- {
- if ((i & 0x1ff) < 240 && (this.windowCover[i & 0x1ff] & (1 << 4)) != 0)
- {
- int tx = (i - x) & 7;
- if ((attr1 & (1 << 12)) != 0) tx = 7 - tx;
- int curIdx = baseSprite * 32 + ((spritey & 7) * 8) + tx;
- int lookup = vram[0x10000 + curIdx];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[0x200 + lookup * 2] | (palette[0x200 + lookup * 2 + 1] << 8)));
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
- if (((i - x) & 7) == 7) baseSprite += baseInc;
- }
- }
- else
- {
- // 16 colors
- int palIdx = 0x200 + (((attr2 >> 12) & 0xF) * 16 * 2);
- for (int i = x; i < x + width; i++)
- {
- if ((i & 0x1ff) < 240 && (this.windowCover[i & 0x1ff] & (1 << 4)) != 0)
- {
- int tx = (i - x) & 7;
- if ((attr1 & (1 << 12)) != 0) tx = 7 - tx;
- int curIdx = baseSprite * 32 + ((spritey & 7) * 4) + (tx / 2);
- int lookup = vram[0x10000 + curIdx];
- if ((tx & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palIdx + lookup * 2] | (palette[palIdx + lookup * 2 + 1] << 8)));
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
- if (((i - x) & 7) == 7) baseSprite += baseInc;
- }
- }
- }
- else
- {
- int rotScaleParam = (attr1 >> 9) & 0x1F;
-
- short dx = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x6);
- short dmx = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0xE);
- short dy = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x16);
- short dmy = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x1E);
-
- int cx = rwidth / 2;
- int cy = rheight / 2;
-
- int baseSprite = attr2 & 0x3FF;
- int pitch;
-
- if ((this.dispCnt & (1 << 6)) != 0)
- {
- // 1 dimensional
- pitch = (width / 8) * scale;
- }
- else
- {
- // 2 dimensional
- pitch = 0x20;
- }
-
- int rx = (int)((dmx * (spritey - cy)) - (cx * dx) + (width << 7));
- int ry = (int)((dmy * (spritey - cy)) - (cx * dy) + (height << 7));
-
- // Draw a rot/scale sprite
- if ((attr0 & (1 << 13)) != 0)
- {
- // 256 colors
- for (int i = x; i < x + rwidth; i++)
- {
- int tx = rx >> 8;
- int ty = ry >> 8;
-
- if ((i & 0x1ff) < 240 && tx >= 0 && tx < width && ty >= 0 && ty < height
- && (this.windowCover[i & 0x1ff] & (1 << 4)) != 0)
- {
- int curIdx = (baseSprite + ((ty / 8) * pitch) + ((tx / 8) * scale)) * 32 + ((ty & 7) * 8) + (tx & 7);
- int lookup = vram[0x10000 + curIdx];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[0x200 + lookup * 2] | (palette[0x200 + lookup * 2 + 1] << 8)));
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
-
- rx += dx;
- ry += dy;
- }
- }
- else
- {
- // 16 colors
- int palIdx = 0x200 + (((attr2 >> 12) & 0xF) * 16 * 2);
- for (int i = x; i < x + rwidth; i++)
- {
- int tx = rx >> 8;
- int ty = ry >> 8;
-
- if ((i & 0x1ff) < 240 && tx >= 0 && tx < width && ty >= 0 && ty < height
- && (this.windowCover[i & 0x1ff] & (1 << 4)) != 0)
- {
- int curIdx = (baseSprite + ((ty / 8) * pitch) + ((tx / 8) * scale)) * 32 + ((ty & 7) * 4) + ((tx & 7) / 2);
- int lookup = vram[0x10000 + curIdx];
- if ((tx & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palIdx + lookup * 2] | (palette[palIdx + lookup * 2 + 1] << 8)));
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
-
- rx += dx;
- ry += dy;
- }
- }
- }
- }
- }
- }
- private void DrawSpritesWindowBlend(int priority)
- {
- byte[] palette = this.memory.PaletteRam;
- byte[] vram = this.memory.VideoRam;
-
- // OBJ must be enabled in this.dispCnt
- if ((this.dispCnt & (1 << 12)) == 0) return;
-
- byte blendMaskType = (byte)(1 << 4);
-
- for (int oamNum = 127; oamNum >= 0; oamNum--)
- {
- ushort attr2 = this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(oamNum * 8) + 4);
-
- if (((attr2 >> 10) & 3) != priority) continue;
-
- ushort attr0 = this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(oamNum * 8) + 0);
- ushort attr1 = this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(oamNum * 8) + 2);
-
- int x = attr1 & 0x1FF;
- int y = attr0 & 0xFF;
-
- bool semiTransparent = false;
-
- switch ((attr0 >> 10) & 3)
- {
- case 1:
- // Semi-transparent
- semiTransparent = true;
- break;
- case 2:
- // Obj window
- continue;
- case 3:
- continue;
- }
-
- if ((this.dispCnt & 0x7) >= 3 && (attr2 & 0x3FF) < 0x200) continue;
-
- int width = -1, height = -1;
- switch ((attr0 >> 14) & 3)
- {
- case 0:
- // Square
- switch ((attr1 >> 14) & 3)
- {
- case 0: width = 8; height = 8; break;
- case 1: width = 16; height = 16; break;
- case 2: width = 32; height = 32; break;
- case 3: width = 64; height = 64; break;
- }
- break;
- case 1:
- // Horizontal Rectangle
- switch ((attr1 >> 14) & 3)
- {
- case 0: width = 16; height = 8; break;
- case 1: width = 32; height = 8; break;
- case 2: width = 32; height = 16; break;
- case 3: width = 64; height = 32; break;
- }
- break;
- case 2:
- // Vertical Rectangle
- switch ((attr1 >> 14) & 3)
- {
- case 0: width = 8; height = 16; break;
- case 1: width = 8; height = 32; break;
- case 2: width = 16; height = 32; break;
- case 3: width = 32; height = 64; break;
- }
- break;
- }
-
- // Check double size flag here
-
- int rwidth = width, rheight = height;
- if ((attr0 & (1 << 8)) != 0)
- {
- // Rot-scale on
- if ((attr0 & (1 << 9)) != 0)
- {
- rwidth *= 2;
- rheight *= 2;
- }
- }
- else
- {
- // Invalid sprite
- if ((attr0 & (1 << 9)) != 0)
- width = -1;
- }
-
- if (width == -1)
- {
- // Invalid sprite
- continue;
- }
-
- // Y clipping
- if (y > ((y + rheight) & 0xff))
- {
- if (this.curLine >= ((y + rheight) & 0xff) && !(y < this.curLine)) continue;
- }
- else
- {
- if (this.curLine < y || this.curLine >= ((y + rheight) & 0xff)) continue;
- }
-
- int scale = 1;
- if ((attr0 & (1 << 13)) != 0) scale = 2;
-
- int spritey = this.curLine - y;
- if (spritey < 0) spritey += 256;
-
- if (semiTransparent)
- {
- if ((attr0 & (1 << 8)) == 0)
- {
- if ((attr1 & (1 << 13)) != 0) spritey = (height - 1) - spritey;
-
- int baseSprite;
- if ((this.dispCnt & (1 << 6)) != 0)
- {
- // 1 dimensional
- baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * (width / 8)) * scale;
- }
- else
- {
- // 2 dimensional
- baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * 0x20);
- }
-
- int baseInc = scale;
- if ((attr1 & (1 << 12)) != 0)
- {
- baseSprite += ((width / 8) * scale) - scale;
- baseInc = -baseInc;
- }
-
- if ((attr0 & (1 << 13)) != 0)
- {
- // 256 colors
- for (int i = x; i < x + width; i++)
- {
- if ((i & 0x1ff) < 240 && (this.windowCover[i & 0x1ff] & (1 << 4)) != 0)
- {
- int tx = (i - x) & 7;
- if ((attr1 & (1 << 12)) != 0) tx = 7 - tx;
- int curIdx = baseSprite * 32 + ((spritey & 7) * 8) + tx;
- int lookup = vram[0x10000 + curIdx];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[0x200 + lookup * 2] | (palette[0x200 + lookup * 2 + 1] << 8)));
- if ((this.windowCover[i & 0x1ff] & (1 << 5)) != 0)
- {
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
- if (((i - x) & 7) == 7) baseSprite += baseInc;
- }
- }
- else
- {
- // 16 colors
- int palIdx = 0x200 + (((attr2 >> 12) & 0xF) * 16 * 2);
- for (int i = x; i < x + width; i++)
- {
- if ((i & 0x1ff) < 240 && (this.windowCover[i & 0x1ff] & (1 << 4)) != 0)
- {
- int tx = (i - x) & 7;
- if ((attr1 & (1 << 12)) != 0) tx = 7 - tx;
- int curIdx = baseSprite * 32 + ((spritey & 7) * 4) + (tx / 2);
- int lookup = vram[0x10000 + curIdx];
- if ((tx & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palIdx + lookup * 2] | (palette[palIdx + lookup * 2 + 1] << 8)));
- if ((this.windowCover[i & 0x1ff] & (1 << 5)) != 0)
- {
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
- if (((i - x) & 7) == 7) baseSprite += baseInc;
- }
- }
- }
- else
- {
- int rotScaleParam = (attr1 >> 9) & 0x1F;
-
- short dx = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x6);
- short dmx = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0xE);
- short dy = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x16);
- short dmy = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x1E);
-
- int cx = rwidth / 2;
- int cy = rheight / 2;
-
- int baseSprite = attr2 & 0x3FF;
- int pitch;
-
- if ((this.dispCnt & (1 << 6)) != 0)
- {
- // 1 dimensional
- pitch = (width / 8) * scale;
- }
- else
- {
- // 2 dimensional
- pitch = 0x20;
- }
-
- int rx = (int)((dmx * (spritey - cy)) - (cx * dx) + (width << 7));
- int ry = (int)((dmy * (spritey - cy)) - (cx * dy) + (height << 7));
-
- // Draw a rot/scale sprite
- if ((attr0 & (1 << 13)) != 0)
- {
- // 256 colors
- for (int i = x; i < x + rwidth; i++)
- {
- int tx = rx >> 8;
- int ty = ry >> 8;
-
- if ((i & 0x1ff) < 240 && tx >= 0 && tx < width && ty >= 0 && ty < height
- && (this.windowCover[i & 0x1ff] & (1 << 4)) != 0)
- {
- int curIdx = (baseSprite + ((ty / 8) * pitch) + ((tx / 8) * scale)) * 32 + ((ty & 7) * 8) + (tx & 7);
- int lookup = vram[0x10000 + curIdx];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[0x200 + lookup * 2] | (palette[0x200 + lookup * 2 + 1] << 8)));
- if ((this.windowCover[i & 0x1ff] & (1 << 5)) != 0)
- {
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
-
- rx += dx;
- ry += dy;
- }
- }
- else
- {
- // 16 colors
- int palIdx = 0x200 + (((attr2 >> 12) & 0xF) * 16 * 2);
- for (int i = x; i < x + rwidth; i++)
- {
- int tx = rx >> 8;
- int ty = ry >> 8;
-
- if ((i & 0x1ff) < 240 && tx >= 0 && tx < width && ty >= 0 && ty < height
- && (this.windowCover[i & 0x1ff] & (1 << 4)) != 0)
- {
- int curIdx = (baseSprite + ((ty / 8) * pitch) + ((tx / 8) * scale)) * 32 + ((ty & 7) * 4) + ((tx & 7) / 2);
- int lookup = vram[0x10000 + curIdx];
- if ((tx & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palIdx + lookup * 2] | (palette[palIdx + lookup * 2 + 1] << 8)));
- if ((this.windowCover[i & 0x1ff] & (1 << 5)) != 0)
- {
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
-
- rx += dx;
- ry += dy;
- }
- }
- }
- }
- else
- {
- if ((attr0 & (1 << 8)) == 0)
- {
- if ((attr1 & (1 << 13)) != 0) spritey = (height - 1) - spritey;
-
- int baseSprite;
- if ((this.dispCnt & (1 << 6)) != 0)
- {
- // 1 dimensional
- baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * (width / 8)) * scale;
- }
- else
- {
- // 2 dimensional
- baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * 0x20);
- }
-
- int baseInc = scale;
- if ((attr1 & (1 << 12)) != 0)
- {
- baseSprite += ((width / 8) * scale) - scale;
- baseInc = -baseInc;
- }
-
- if ((attr0 & (1 << 13)) != 0)
- {
- // 256 colors
- for (int i = x; i < x + width; i++)
- {
- if ((i & 0x1ff) < 240 && (this.windowCover[i & 0x1ff] & (1 << 4)) != 0)
- {
- int tx = (i - x) & 7;
- if ((attr1 & (1 << 12)) != 0) tx = 7 - tx;
- int curIdx = baseSprite * 32 + ((spritey & 7) * 8) + tx;
- int lookup = vram[0x10000 + curIdx];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[0x200 + lookup * 2] | (palette[0x200 + lookup * 2 + 1] << 8)));
- if ((this.windowCover[i & 0x1ff] & (1 << 5)) != 0)
- {
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
- if (((i - x) & 7) == 7) baseSprite += baseInc;
- }
- }
- else
- {
- // 16 colors
- int palIdx = 0x200 + (((attr2 >> 12) & 0xF) * 16 * 2);
- for (int i = x; i < x + width; i++)
- {
- if ((i & 0x1ff) < 240 && (this.windowCover[i & 0x1ff] & (1 << 4)) != 0)
- {
- int tx = (i - x) & 7;
- if ((attr1 & (1 << 12)) != 0) tx = 7 - tx;
- int curIdx = baseSprite * 32 + ((spritey & 7) * 4) + (tx / 2);
- int lookup = vram[0x10000 + curIdx];
- if ((tx & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palIdx + lookup * 2] | (palette[palIdx + lookup * 2 + 1] << 8)));
- if ((this.windowCover[i & 0x1ff] & (1 << 5)) != 0)
- {
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
- if (((i - x) & 7) == 7) baseSprite += baseInc;
- }
- }
- }
- else
- {
- int rotScaleParam = (attr1 >> 9) & 0x1F;
-
- short dx = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x6);
- short dmx = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0xE);
- short dy = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x16);
- short dmy = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x1E);
-
- int cx = rwidth / 2;
- int cy = rheight / 2;
-
- int baseSprite = attr2 & 0x3FF;
- int pitch;
-
- if ((this.dispCnt & (1 << 6)) != 0)
- {
- // 1 dimensional
- pitch = (width / 8) * scale;
- }
- else
- {
- // 2 dimensional
- pitch = 0x20;
- }
-
- int rx = (int)((dmx * (spritey - cy)) - (cx * dx) + (width << 7));
- int ry = (int)((dmy * (spritey - cy)) - (cx * dy) + (height << 7));
-
- // Draw a rot/scale sprite
- if ((attr0 & (1 << 13)) != 0)
- {
- // 256 colors
- for (int i = x; i < x + rwidth; i++)
- {
- int tx = rx >> 8;
- int ty = ry >> 8;
-
- if ((i & 0x1ff) < 240 && tx >= 0 && tx < width && ty >= 0 && ty < height
- && (this.windowCover[i & 0x1ff] & (1 << 4)) != 0)
- {
- int curIdx = (baseSprite + ((ty / 8) * pitch) + ((tx / 8) * scale)) * 32 + ((ty & 7) * 8) + (tx & 7);
- int lookup = vram[0x10000 + curIdx];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[0x200 + lookup * 2] | (palette[0x200 + lookup * 2 + 1] << 8)));
- if ((this.windowCover[i & 0x1ff] & (1 << 5)) != 0)
- {
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
-
- rx += dx;
- ry += dy;
- }
- }
- else
- {
- // 16 colors
- int palIdx = 0x200 + (((attr2 >> 12) & 0xF) * 16 * 2);
- for (int i = x; i < x + rwidth; i++)
- {
- int tx = rx >> 8;
- int ty = ry >> 8;
-
- if ((i & 0x1ff) < 240 && tx >= 0 && tx < width && ty >= 0 && ty < height
- && (this.windowCover[i & 0x1ff] & (1 << 4)) != 0)
- {
- int curIdx = (baseSprite + ((ty / 8) * pitch) + ((tx / 8) * scale)) * 32 + ((ty & 7) * 4) + ((tx & 7) / 2);
- int lookup = vram[0x10000 + curIdx];
- if ((tx & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palIdx + lookup * 2] | (palette[palIdx + lookup * 2 + 1] << 8)));
- if ((this.windowCover[i & 0x1ff] & (1 << 5)) != 0)
- {
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
-
- rx += dx;
- ry += dy;
- }
- }
- }
- }
- }
- }
- private void DrawSpritesWindowBrightInc(int priority)
- {
- byte[] palette = this.memory.PaletteRam;
- byte[] vram = this.memory.VideoRam;
-
- // OBJ must be enabled in this.dispCnt
- if ((this.dispCnt & (1 << 12)) == 0) return;
-
- byte blendMaskType = (byte)(1 << 4);
-
- for (int oamNum = 127; oamNum >= 0; oamNum--)
- {
- ushort attr2 = this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(oamNum * 8) + 4);
-
- if (((attr2 >> 10) & 3) != priority) continue;
-
- ushort attr0 = this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(oamNum * 8) + 0);
- ushort attr1 = this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(oamNum * 8) + 2);
-
- int x = attr1 & 0x1FF;
- int y = attr0 & 0xFF;
-
- bool semiTransparent = false;
-
- switch ((attr0 >> 10) & 3)
- {
- case 1:
- // Semi-transparent
- semiTransparent = true;
- break;
- case 2:
- // Obj window
- continue;
- case 3:
- continue;
- }
-
- if ((this.dispCnt & 0x7) >= 3 && (attr2 & 0x3FF) < 0x200) continue;
-
- int width = -1, height = -1;
- switch ((attr0 >> 14) & 3)
- {
- case 0:
- // Square
- switch ((attr1 >> 14) & 3)
- {
- case 0: width = 8; height = 8; break;
- case 1: width = 16; height = 16; break;
- case 2: width = 32; height = 32; break;
- case 3: width = 64; height = 64; break;
- }
- break;
- case 1:
- // Horizontal Rectangle
- switch ((attr1 >> 14) & 3)
- {
- case 0: width = 16; height = 8; break;
- case 1: width = 32; height = 8; break;
- case 2: width = 32; height = 16; break;
- case 3: width = 64; height = 32; break;
- }
- break;
- case 2:
- // Vertical Rectangle
- switch ((attr1 >> 14) & 3)
- {
- case 0: width = 8; height = 16; break;
- case 1: width = 8; height = 32; break;
- case 2: width = 16; height = 32; break;
- case 3: width = 32; height = 64; break;
- }
- break;
- }
-
- // Check double size flag here
-
- int rwidth = width, rheight = height;
- if ((attr0 & (1 << 8)) != 0)
- {
- // Rot-scale on
- if ((attr0 & (1 << 9)) != 0)
- {
- rwidth *= 2;
- rheight *= 2;
- }
- }
- else
- {
- // Invalid sprite
- if ((attr0 & (1 << 9)) != 0)
- width = -1;
- }
-
- if (width == -1)
- {
- // Invalid sprite
- continue;
- }
-
- // Y clipping
- if (y > ((y + rheight) & 0xff))
- {
- if (this.curLine >= ((y + rheight) & 0xff) && !(y < this.curLine)) continue;
- }
- else
- {
- if (this.curLine < y || this.curLine >= ((y + rheight) & 0xff)) continue;
- }
-
- int scale = 1;
- if ((attr0 & (1 << 13)) != 0) scale = 2;
-
- int spritey = this.curLine - y;
- if (spritey < 0) spritey += 256;
-
- if (semiTransparent)
- {
- if ((attr0 & (1 << 8)) == 0)
- {
- if ((attr1 & (1 << 13)) != 0) spritey = (height - 1) - spritey;
-
- int baseSprite;
- if ((this.dispCnt & (1 << 6)) != 0)
- {
- // 1 dimensional
- baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * (width / 8)) * scale;
- }
- else
- {
- // 2 dimensional
- baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * 0x20);
- }
-
- int baseInc = scale;
- if ((attr1 & (1 << 12)) != 0)
- {
- baseSprite += ((width / 8) * scale) - scale;
- baseInc = -baseInc;
- }
-
- if ((attr0 & (1 << 13)) != 0)
- {
- // 256 colors
- for (int i = x; i < x + width; i++)
- {
- if ((i & 0x1ff) < 240 && (this.windowCover[i & 0x1ff] & (1 << 4)) != 0)
- {
- int tx = (i - x) & 7;
- if ((attr1 & (1 << 12)) != 0) tx = 7 - tx;
- int curIdx = baseSprite * 32 + ((spritey & 7) * 8) + tx;
- int lookup = vram[0x10000 + curIdx];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[0x200 + lookup * 2] | (palette[0x200 + lookup * 2 + 1] << 8)));
- if ((this.windowCover[i & 0x1ff] & (1 << 5)) != 0)
- {
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
- if (((i - x) & 7) == 7) baseSprite += baseInc;
- }
- }
- else
- {
- // 16 colors
- int palIdx = 0x200 + (((attr2 >> 12) & 0xF) * 16 * 2);
- for (int i = x; i < x + width; i++)
- {
- if ((i & 0x1ff) < 240 && (this.windowCover[i & 0x1ff] & (1 << 4)) != 0)
- {
- int tx = (i - x) & 7;
- if ((attr1 & (1 << 12)) != 0) tx = 7 - tx;
- int curIdx = baseSprite * 32 + ((spritey & 7) * 4) + (tx / 2);
- int lookup = vram[0x10000 + curIdx];
- if ((tx & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palIdx + lookup * 2] | (palette[palIdx + lookup * 2 + 1] << 8)));
- if ((this.windowCover[i & 0x1ff] & (1 << 5)) != 0)
- {
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
- if (((i - x) & 7) == 7) baseSprite += baseInc;
- }
- }
- }
- else
- {
- int rotScaleParam = (attr1 >> 9) & 0x1F;
-
- short dx = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x6);
- short dmx = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0xE);
- short dy = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x16);
- short dmy = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x1E);
-
- int cx = rwidth / 2;
- int cy = rheight / 2;
-
- int baseSprite = attr2 & 0x3FF;
- int pitch;
-
- if ((this.dispCnt & (1 << 6)) != 0)
- {
- // 1 dimensional
- pitch = (width / 8) * scale;
- }
- else
- {
- // 2 dimensional
- pitch = 0x20;
- }
-
- int rx = (int)((dmx * (spritey - cy)) - (cx * dx) + (width << 7));
- int ry = (int)((dmy * (spritey - cy)) - (cx * dy) + (height << 7));
-
- // Draw a rot/scale sprite
- if ((attr0 & (1 << 13)) != 0)
- {
- // 256 colors
- for (int i = x; i < x + rwidth; i++)
- {
- int tx = rx >> 8;
- int ty = ry >> 8;
-
- if ((i & 0x1ff) < 240 && tx >= 0 && tx < width && ty >= 0 && ty < height
- && (this.windowCover[i & 0x1ff] & (1 << 4)) != 0)
- {
- int curIdx = (baseSprite + ((ty / 8) * pitch) + ((tx / 8) * scale)) * 32 + ((ty & 7) * 8) + (tx & 7);
- int lookup = vram[0x10000 + curIdx];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[0x200 + lookup * 2] | (palette[0x200 + lookup * 2 + 1] << 8)));
- if ((this.windowCover[i & 0x1ff] & (1 << 5)) != 0)
- {
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
-
- rx += dx;
- ry += dy;
- }
- }
- else
- {
- // 16 colors
- int palIdx = 0x200 + (((attr2 >> 12) & 0xF) * 16 * 2);
- for (int i = x; i < x + rwidth; i++)
- {
- int tx = rx >> 8;
- int ty = ry >> 8;
-
- if ((i & 0x1ff) < 240 && tx >= 0 && tx < width && ty >= 0 && ty < height
- && (this.windowCover[i & 0x1ff] & (1 << 4)) != 0)
- {
- int curIdx = (baseSprite + ((ty / 8) * pitch) + ((tx / 8) * scale)) * 32 + ((ty & 7) * 4) + ((tx & 7) / 2);
- int lookup = vram[0x10000 + curIdx];
- if ((tx & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palIdx + lookup * 2] | (palette[palIdx + lookup * 2 + 1] << 8)));
- if ((this.windowCover[i & 0x1ff] & (1 << 5)) != 0)
- {
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
-
- rx += dx;
- ry += dy;
- }
- }
- }
- }
- else
- {
- if ((attr0 & (1 << 8)) == 0)
- {
- if ((attr1 & (1 << 13)) != 0) spritey = (height - 1) - spritey;
-
- int baseSprite;
- if ((this.dispCnt & (1 << 6)) != 0)
- {
- // 1 dimensional
- baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * (width / 8)) * scale;
- }
- else
- {
- // 2 dimensional
- baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * 0x20);
- }
-
- int baseInc = scale;
- if ((attr1 & (1 << 12)) != 0)
- {
- baseSprite += ((width / 8) * scale) - scale;
- baseInc = -baseInc;
- }
-
- if ((attr0 & (1 << 13)) != 0)
- {
- // 256 colors
- for (int i = x; i < x + width; i++)
- {
- if ((i & 0x1ff) < 240 && (this.windowCover[i & 0x1ff] & (1 << 4)) != 0)
- {
- int tx = (i - x) & 7;
- if ((attr1 & (1 << 12)) != 0) tx = 7 - tx;
- int curIdx = baseSprite * 32 + ((spritey & 7) * 8) + tx;
- int lookup = vram[0x10000 + curIdx];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[0x200 + lookup * 2] | (palette[0x200 + lookup * 2 + 1] << 8)));
- if ((this.windowCover[i & 0x1ff] & (1 << 5)) != 0)
- {
- uint r = pixelColor & 0xFF;
- uint g = (pixelColor >> 8) & 0xFF;
- uint b = (pixelColor >> 16) & 0xFF;
- r = r + (((0xFF - r) * this.blendY) >> 4);
- g = g + (((0xFF - g) * this.blendY) >> 4);
- b = b + (((0xFF - b) * this.blendY) >> 4);
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
- if (((i - x) & 7) == 7) baseSprite += baseInc;
- }
- }
- else
- {
- // 16 colors
- int palIdx = 0x200 + (((attr2 >> 12) & 0xF) * 16 * 2);
- for (int i = x; i < x + width; i++)
- {
- if ((i & 0x1ff) < 240 && (this.windowCover[i & 0x1ff] & (1 << 4)) != 0)
- {
- int tx = (i - x) & 7;
- if ((attr1 & (1 << 12)) != 0) tx = 7 - tx;
- int curIdx = baseSprite * 32 + ((spritey & 7) * 4) + (tx / 2);
- int lookup = vram[0x10000 + curIdx];
- if ((tx & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palIdx + lookup * 2] | (palette[palIdx + lookup * 2 + 1] << 8)));
- if ((this.windowCover[i & 0x1ff] & (1 << 5)) != 0)
- {
- uint r = pixelColor & 0xFF;
- uint g = (pixelColor >> 8) & 0xFF;
- uint b = (pixelColor >> 16) & 0xFF;
- r = r + (((0xFF - r) * this.blendY) >> 4);
- g = g + (((0xFF - g) * this.blendY) >> 4);
- b = b + (((0xFF - b) * this.blendY) >> 4);
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
- if (((i - x) & 7) == 7) baseSprite += baseInc;
- }
- }
- }
- else
- {
- int rotScaleParam = (attr1 >> 9) & 0x1F;
-
- short dx = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x6);
- short dmx = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0xE);
- short dy = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x16);
- short dmy = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x1E);
-
- int cx = rwidth / 2;
- int cy = rheight / 2;
-
- int baseSprite = attr2 & 0x3FF;
- int pitch;
-
- if ((this.dispCnt & (1 << 6)) != 0)
- {
- // 1 dimensional
- pitch = (width / 8) * scale;
- }
- else
- {
- // 2 dimensional
- pitch = 0x20;
- }
-
- int rx = (int)((dmx * (spritey - cy)) - (cx * dx) + (width << 7));
- int ry = (int)((dmy * (spritey - cy)) - (cx * dy) + (height << 7));
-
- // Draw a rot/scale sprite
- if ((attr0 & (1 << 13)) != 0)
- {
- // 256 colors
- for (int i = x; i < x + rwidth; i++)
- {
- int tx = rx >> 8;
- int ty = ry >> 8;
-
- if ((i & 0x1ff) < 240 && tx >= 0 && tx < width && ty >= 0 && ty < height
- && (this.windowCover[i & 0x1ff] & (1 << 4)) != 0)
- {
- int curIdx = (baseSprite + ((ty / 8) * pitch) + ((tx / 8) * scale)) * 32 + ((ty & 7) * 8) + (tx & 7);
- int lookup = vram[0x10000 + curIdx];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[0x200 + lookup * 2] | (palette[0x200 + lookup * 2 + 1] << 8)));
- if ((this.windowCover[i & 0x1ff] & (1 << 5)) != 0)
- {
- uint r = pixelColor & 0xFF;
- uint g = (pixelColor >> 8) & 0xFF;
- uint b = (pixelColor >> 16) & 0xFF;
- r = r + (((0xFF - r) * this.blendY) >> 4);
- g = g + (((0xFF - g) * this.blendY) >> 4);
- b = b + (((0xFF - b) * this.blendY) >> 4);
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
-
- rx += dx;
- ry += dy;
- }
- }
- else
- {
- // 16 colors
- int palIdx = 0x200 + (((attr2 >> 12) & 0xF) * 16 * 2);
- for (int i = x; i < x + rwidth; i++)
- {
- int tx = rx >> 8;
- int ty = ry >> 8;
-
- if ((i & 0x1ff) < 240 && tx >= 0 && tx < width && ty >= 0 && ty < height
- && (this.windowCover[i & 0x1ff] & (1 << 4)) != 0)
- {
- int curIdx = (baseSprite + ((ty / 8) * pitch) + ((tx / 8) * scale)) * 32 + ((ty & 7) * 4) + ((tx & 7) / 2);
- int lookup = vram[0x10000 + curIdx];
- if ((tx & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palIdx + lookup * 2] | (palette[palIdx + lookup * 2 + 1] << 8)));
- if ((this.windowCover[i & 0x1ff] & (1 << 5)) != 0)
- {
- uint r = pixelColor & 0xFF;
- uint g = (pixelColor >> 8) & 0xFF;
- uint b = (pixelColor >> 16) & 0xFF;
- r = r + (((0xFF - r) * this.blendY) >> 4);
- g = g + (((0xFF - g) * this.blendY) >> 4);
- b = b + (((0xFF - b) * this.blendY) >> 4);
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
-
- rx += dx;
- ry += dy;
- }
- }
- }
- }
- }
- }
- private void DrawSpritesWindowBrightDec(int priority)
- {
- byte[] palette = this.memory.PaletteRam;
- byte[] vram = this.memory.VideoRam;
-
- // OBJ must be enabled in this.dispCnt
- if ((this.dispCnt & (1 << 12)) == 0) return;
-
- byte blendMaskType = (byte)(1 << 4);
-
- for (int oamNum = 127; oamNum >= 0; oamNum--)
- {
- ushort attr2 = this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(oamNum * 8) + 4);
-
- if (((attr2 >> 10) & 3) != priority) continue;
-
- ushort attr0 = this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(oamNum * 8) + 0);
- ushort attr1 = this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(oamNum * 8) + 2);
-
- int x = attr1 & 0x1FF;
- int y = attr0 & 0xFF;
-
- bool semiTransparent = false;
-
- switch ((attr0 >> 10) & 3)
- {
- case 1:
- // Semi-transparent
- semiTransparent = true;
- break;
- case 2:
- // Obj window
- continue;
- case 3:
- continue;
- }
-
- if ((this.dispCnt & 0x7) >= 3 && (attr2 & 0x3FF) < 0x200) continue;
-
- int width = -1, height = -1;
- switch ((attr0 >> 14) & 3)
- {
- case 0:
- // Square
- switch ((attr1 >> 14) & 3)
- {
- case 0: width = 8; height = 8; break;
- case 1: width = 16; height = 16; break;
- case 2: width = 32; height = 32; break;
- case 3: width = 64; height = 64; break;
- }
- break;
- case 1:
- // Horizontal Rectangle
- switch ((attr1 >> 14) & 3)
- {
- case 0: width = 16; height = 8; break;
- case 1: width = 32; height = 8; break;
- case 2: width = 32; height = 16; break;
- case 3: width = 64; height = 32; break;
- }
- break;
- case 2:
- // Vertical Rectangle
- switch ((attr1 >> 14) & 3)
- {
- case 0: width = 8; height = 16; break;
- case 1: width = 8; height = 32; break;
- case 2: width = 16; height = 32; break;
- case 3: width = 32; height = 64; break;
- }
- break;
- }
-
- // Check double size flag here
-
- int rwidth = width, rheight = height;
- if ((attr0 & (1 << 8)) != 0)
- {
- // Rot-scale on
- if ((attr0 & (1 << 9)) != 0)
- {
- rwidth *= 2;
- rheight *= 2;
- }
- }
- else
- {
- // Invalid sprite
- if ((attr0 & (1 << 9)) != 0)
- width = -1;
- }
-
- if (width == -1)
- {
- // Invalid sprite
- continue;
- }
-
- // Y clipping
- if (y > ((y + rheight) & 0xff))
- {
- if (this.curLine >= ((y + rheight) & 0xff) && !(y < this.curLine)) continue;
- }
- else
- {
- if (this.curLine < y || this.curLine >= ((y + rheight) & 0xff)) continue;
- }
-
- int scale = 1;
- if ((attr0 & (1 << 13)) != 0) scale = 2;
-
- int spritey = this.curLine - y;
- if (spritey < 0) spritey += 256;
-
- if (semiTransparent)
- {
- if ((attr0 & (1 << 8)) == 0)
- {
- if ((attr1 & (1 << 13)) != 0) spritey = (height - 1) - spritey;
-
- int baseSprite;
- if ((this.dispCnt & (1 << 6)) != 0)
- {
- // 1 dimensional
- baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * (width / 8)) * scale;
- }
- else
- {
- // 2 dimensional
- baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * 0x20);
- }
-
- int baseInc = scale;
- if ((attr1 & (1 << 12)) != 0)
- {
- baseSprite += ((width / 8) * scale) - scale;
- baseInc = -baseInc;
- }
-
- if ((attr0 & (1 << 13)) != 0)
- {
- // 256 colors
- for (int i = x; i < x + width; i++)
- {
- if ((i & 0x1ff) < 240 && (this.windowCover[i & 0x1ff] & (1 << 4)) != 0)
- {
- int tx = (i - x) & 7;
- if ((attr1 & (1 << 12)) != 0) tx = 7 - tx;
- int curIdx = baseSprite * 32 + ((spritey & 7) * 8) + tx;
- int lookup = vram[0x10000 + curIdx];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[0x200 + lookup * 2] | (palette[0x200 + lookup * 2 + 1] << 8)));
- if ((this.windowCover[i & 0x1ff] & (1 << 5)) != 0)
- {
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
- if (((i - x) & 7) == 7) baseSprite += baseInc;
- }
- }
- else
- {
- // 16 colors
- int palIdx = 0x200 + (((attr2 >> 12) & 0xF) * 16 * 2);
- for (int i = x; i < x + width; i++)
- {
- if ((i & 0x1ff) < 240 && (this.windowCover[i & 0x1ff] & (1 << 4)) != 0)
- {
- int tx = (i - x) & 7;
- if ((attr1 & (1 << 12)) != 0) tx = 7 - tx;
- int curIdx = baseSprite * 32 + ((spritey & 7) * 4) + (tx / 2);
- int lookup = vram[0x10000 + curIdx];
- if ((tx & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palIdx + lookup * 2] | (palette[palIdx + lookup * 2 + 1] << 8)));
- if ((this.windowCover[i & 0x1ff] & (1 << 5)) != 0)
- {
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
- if (((i - x) & 7) == 7) baseSprite += baseInc;
- }
- }
- }
- else
- {
- int rotScaleParam = (attr1 >> 9) & 0x1F;
-
- short dx = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x6);
- short dmx = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0xE);
- short dy = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x16);
- short dmy = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x1E);
-
- int cx = rwidth / 2;
- int cy = rheight / 2;
-
- int baseSprite = attr2 & 0x3FF;
- int pitch;
-
- if ((this.dispCnt & (1 << 6)) != 0)
- {
- // 1 dimensional
- pitch = (width / 8) * scale;
- }
- else
- {
- // 2 dimensional
- pitch = 0x20;
- }
-
- int rx = (int)((dmx * (spritey - cy)) - (cx * dx) + (width << 7));
- int ry = (int)((dmy * (spritey - cy)) - (cx * dy) + (height << 7));
-
- // Draw a rot/scale sprite
- if ((attr0 & (1 << 13)) != 0)
- {
- // 256 colors
- for (int i = x; i < x + rwidth; i++)
- {
- int tx = rx >> 8;
- int ty = ry >> 8;
-
- if ((i & 0x1ff) < 240 && tx >= 0 && tx < width && ty >= 0 && ty < height
- && (this.windowCover[i & 0x1ff] & (1 << 4)) != 0)
- {
- int curIdx = (baseSprite + ((ty / 8) * pitch) + ((tx / 8) * scale)) * 32 + ((ty & 7) * 8) + (tx & 7);
- int lookup = vram[0x10000 + curIdx];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[0x200 + lookup * 2] | (palette[0x200 + lookup * 2 + 1] << 8)));
- if ((this.windowCover[i & 0x1ff] & (1 << 5)) != 0)
- {
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
-
- rx += dx;
- ry += dy;
- }
- }
- else
- {
- // 16 colors
- int palIdx = 0x200 + (((attr2 >> 12) & 0xF) * 16 * 2);
- for (int i = x; i < x + rwidth; i++)
- {
- int tx = rx >> 8;
- int ty = ry >> 8;
-
- if ((i & 0x1ff) < 240 && tx >= 0 && tx < width && ty >= 0 && ty < height
- && (this.windowCover[i & 0x1ff] & (1 << 4)) != 0)
- {
- int curIdx = (baseSprite + ((ty / 8) * pitch) + ((tx / 8) * scale)) * 32 + ((ty & 7) * 4) + ((tx & 7) / 2);
- int lookup = vram[0x10000 + curIdx];
- if ((tx & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palIdx + lookup * 2] | (palette[palIdx + lookup * 2 + 1] << 8)));
- if ((this.windowCover[i & 0x1ff] & (1 << 5)) != 0)
- {
- if ((this.blend[i & 0x1ff] & this.blendTarget) != 0 && this.blend[i & 0x1ff] != blendMaskType)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[(i & 0x1ff)];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
-
- rx += dx;
- ry += dy;
- }
- }
- }
- }
- else
- {
- if ((attr0 & (1 << 8)) == 0)
- {
- if ((attr1 & (1 << 13)) != 0) spritey = (height - 1) - spritey;
-
- int baseSprite;
- if ((this.dispCnt & (1 << 6)) != 0)
- {
- // 1 dimensional
- baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * (width / 8)) * scale;
- }
- else
- {
- // 2 dimensional
- baseSprite = (attr2 & 0x3FF) + ((spritey / 8) * 0x20);
- }
-
- int baseInc = scale;
- if ((attr1 & (1 << 12)) != 0)
- {
- baseSprite += ((width / 8) * scale) - scale;
- baseInc = -baseInc;
- }
-
- if ((attr0 & (1 << 13)) != 0)
- {
- // 256 colors
- for (int i = x; i < x + width; i++)
- {
- if ((i & 0x1ff) < 240 && (this.windowCover[i & 0x1ff] & (1 << 4)) != 0)
- {
- int tx = (i - x) & 7;
- if ((attr1 & (1 << 12)) != 0) tx = 7 - tx;
- int curIdx = baseSprite * 32 + ((spritey & 7) * 8) + tx;
- int lookup = vram[0x10000 + curIdx];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[0x200 + lookup * 2] | (palette[0x200 + lookup * 2 + 1] << 8)));
- if ((this.windowCover[i & 0x1ff] & (1 << 5)) != 0)
- {
- uint r = pixelColor & 0xFF;
- uint g = (pixelColor >> 8) & 0xFF;
- uint b = (pixelColor >> 16) & 0xFF;
- r = r - ((r * this.blendY) >> 4);
- g = g - ((g * this.blendY) >> 4);
- b = b - ((b * this.blendY) >> 4);
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
- if (((i - x) & 7) == 7) baseSprite += baseInc;
- }
- }
- else
- {
- // 16 colors
- int palIdx = 0x200 + (((attr2 >> 12) & 0xF) * 16 * 2);
- for (int i = x; i < x + width; i++)
- {
- if ((i & 0x1ff) < 240 && (this.windowCover[i & 0x1ff] & (1 << 4)) != 0)
- {
- int tx = (i - x) & 7;
- if ((attr1 & (1 << 12)) != 0) tx = 7 - tx;
- int curIdx = baseSprite * 32 + ((spritey & 7) * 4) + (tx / 2);
- int lookup = vram[0x10000 + curIdx];
- if ((tx & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palIdx + lookup * 2] | (palette[palIdx + lookup * 2 + 1] << 8)));
- if ((this.windowCover[i & 0x1ff] & (1 << 5)) != 0)
- {
- uint r = pixelColor & 0xFF;
- uint g = (pixelColor >> 8) & 0xFF;
- uint b = (pixelColor >> 16) & 0xFF;
- r = r - ((r * this.blendY) >> 4);
- g = g - ((g * this.blendY) >> 4);
- b = b - ((b * this.blendY) >> 4);
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
- if (((i - x) & 7) == 7) baseSprite += baseInc;
- }
- }
- }
- else
- {
- int rotScaleParam = (attr1 >> 9) & 0x1F;
-
- short dx = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x6);
- short dmx = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0xE);
- short dy = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x16);
- short dmy = (short)this.memory.ReadU16Debug(Memory.OAM_BASE + (uint)(rotScaleParam * 8 * 4) + 0x1E);
-
- int cx = rwidth / 2;
- int cy = rheight / 2;
-
- int baseSprite = attr2 & 0x3FF;
- int pitch;
-
- if ((this.dispCnt & (1 << 6)) != 0)
- {
- // 1 dimensional
- pitch = (width / 8) * scale;
- }
- else
- {
- // 2 dimensional
- pitch = 0x20;
- }
-
- int rx = (int)((dmx * (spritey - cy)) - (cx * dx) + (width << 7));
- int ry = (int)((dmy * (spritey - cy)) - (cx * dy) + (height << 7));
-
- // Draw a rot/scale sprite
- if ((attr0 & (1 << 13)) != 0)
- {
- // 256 colors
- for (int i = x; i < x + rwidth; i++)
- {
- int tx = rx >> 8;
- int ty = ry >> 8;
-
- if ((i & 0x1ff) < 240 && tx >= 0 && tx < width && ty >= 0 && ty < height
- && (this.windowCover[i & 0x1ff] & (1 << 4)) != 0)
- {
- int curIdx = (baseSprite + ((ty / 8) * pitch) + ((tx / 8) * scale)) * 32 + ((ty & 7) * 8) + (tx & 7);
- int lookup = vram[0x10000 + curIdx];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[0x200 + lookup * 2] | (palette[0x200 + lookup * 2 + 1] << 8)));
- if ((this.windowCover[i & 0x1ff] & (1 << 5)) != 0)
- {
- uint r = pixelColor & 0xFF;
- uint g = (pixelColor >> 8) & 0xFF;
- uint b = (pixelColor >> 16) & 0xFF;
- r = r - ((r * this.blendY) >> 4);
- g = g - ((g * this.blendY) >> 4);
- b = b - ((b * this.blendY) >> 4);
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
-
- rx += dx;
- ry += dy;
- }
- }
- else
- {
- // 16 colors
- int palIdx = 0x200 + (((attr2 >> 12) & 0xF) * 16 * 2);
- for (int i = x; i < x + rwidth; i++)
- {
- int tx = rx >> 8;
- int ty = ry >> 8;
-
- if ((i & 0x1ff) < 240 && tx >= 0 && tx < width && ty >= 0 && ty < height
- && (this.windowCover[i & 0x1ff] & (1 << 4)) != 0)
- {
- int curIdx = (baseSprite + ((ty / 8) * pitch) + ((tx / 8) * scale)) * 32 + ((ty & 7) * 4) + ((tx & 7) / 2);
- int lookup = vram[0x10000 + curIdx];
- if ((tx & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palIdx + lookup * 2] | (palette[palIdx + lookup * 2 + 1] << 8)));
- if ((this.windowCover[i & 0x1ff] & (1 << 5)) != 0)
- {
- uint r = pixelColor & 0xFF;
- uint g = (pixelColor >> 8) & 0xFF;
- uint b = (pixelColor >> 16) & 0xFF;
- r = r - ((r * this.blendY) >> 4);
- g = g - ((g * this.blendY) >> 4);
- b = b - ((b * this.blendY) >> 4);
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[(i & 0x1ff)] = pixelColor;
- this.blend[(i & 0x1ff)] = blendMaskType;
-
- }
- }
-
- rx += dx;
- ry += dy;
- }
- }
- }
- }
- }
- }
- #endregion Sprite Drawing
- #region Rot/Scale Bg
- private void RenderRotScaleBgNormal(int bg)
- {
- byte[] palette = this.memory.PaletteRam;
- byte[] vram = this.memory.VideoRam;
-
- byte blendMaskType = (byte)(1 << bg);
-
- ushort bgcnt = Memory.ReadU16(this.memory.IORam, Memory.BG0CNT + 0x2 * (uint)bg);
-
- int width = 0, height = 0;
- switch ((bgcnt >> 14) & 0x3)
- {
- case 0: width = 128; height = 128; break;
- case 1: width = 256; height = 256; break;
- case 2: width = 512; height = 512; break;
- case 3: width = 1024; height = 1024; break;
- }
-
- int screenBase = ((bgcnt >> 8) & 0x1F) * 0x800;
- int charBase = ((bgcnt >> 2) & 0x3) * 0x4000;
-
- int x = this.memory.Bgx[bg - 2];
- int y = this.memory.Bgy[bg - 2];
-
- short dx = (short)Memory.ReadU16(this.memory.IORam, Memory.BG2PA + (uint)(bg - 2) * 0x10);
- short dy = (short)Memory.ReadU16(this.memory.IORam, Memory.BG2PC + (uint)(bg - 2) * 0x10);
-
- bool transparent = (bgcnt & (1 << 13)) == 0;
-
- for (int i = 0; i < 240; i++)
- {
- if (true)
- {
- int ax = x >> 8;
- int ay = y >> 8;
-
- if ((ax >= 0 && ax < width && ay >= 0 && ay < height) || !transparent)
- {
- int tmpTileIdx = (int)(screenBase + ((ay & (height - 1)) / 8) * (width / 8) + ((ax & (width - 1)) / 8));
- int tileChar = vram[tmpTileIdx];
-
- int lookup = vram[charBase + (tileChar * 64) + ((ay & 7) * 8) + (ax & 7)];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[lookup * 2] | (palette[lookup * 2 + 1] << 8)));
- this.scanline[i] = pixelColor; this.blend[i] = blendMaskType;
-
- }
- }
- }
-
- x += dx;
- y += dy;
- }
- }
- private void RenderRotScaleBgBlend(int bg)
- {
- byte[] palette = this.memory.PaletteRam;
- byte[] vram = this.memory.VideoRam;
-
- byte blendMaskType = (byte)(1 << bg);
-
- ushort bgcnt = Memory.ReadU16(this.memory.IORam, Memory.BG0CNT + 0x2 * (uint)bg);
-
- int width = 0, height = 0;
- switch ((bgcnt >> 14) & 0x3)
- {
- case 0: width = 128; height = 128; break;
- case 1: width = 256; height = 256; break;
- case 2: width = 512; height = 512; break;
- case 3: width = 1024; height = 1024; break;
- }
-
- int screenBase = ((bgcnt >> 8) & 0x1F) * 0x800;
- int charBase = ((bgcnt >> 2) & 0x3) * 0x4000;
-
- int x = this.memory.Bgx[bg - 2];
- int y = this.memory.Bgy[bg - 2];
-
- short dx = (short)Memory.ReadU16(this.memory.IORam, Memory.BG2PA + (uint)(bg - 2) * 0x10);
- short dy = (short)Memory.ReadU16(this.memory.IORam, Memory.BG2PC + (uint)(bg - 2) * 0x10);
-
- bool transparent = (bgcnt & (1 << 13)) == 0;
-
- for (int i = 0; i < 240; i++)
- {
- if (true)
- {
- int ax = x >> 8;
- int ay = y >> 8;
-
- if ((ax >= 0 && ax < width && ay >= 0 && ay < height) || !transparent)
- {
- int tmpTileIdx = (int)(screenBase + ((ay & (height - 1)) / 8) * (width / 8) + ((ax & (width - 1)) / 8));
- int tileChar = vram[tmpTileIdx];
-
- int lookup = vram[charBase + (tileChar * 64) + ((ay & 7) * 8) + (ax & 7)];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[lookup * 2] | (palette[lookup * 2 + 1] << 8)));
- if ((this.blend[i] & this.blendTarget) != 0)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[i];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[i] = pixelColor; this.blend[i] = blendMaskType;
-
- }
- }
- }
-
- x += dx;
- y += dy;
- }
- }
- private void RenderRotScaleBgBrightInc(int bg)
- {
- byte[] palette = this.memory.PaletteRam;
- byte[] vram = this.memory.VideoRam;
-
- byte blendMaskType = (byte)(1 << bg);
-
- ushort bgcnt = Memory.ReadU16(this.memory.IORam, Memory.BG0CNT + 0x2 * (uint)bg);
-
- int width = 0, height = 0;
- switch ((bgcnt >> 14) & 0x3)
- {
- case 0: width = 128; height = 128; break;
- case 1: width = 256; height = 256; break;
- case 2: width = 512; height = 512; break;
- case 3: width = 1024; height = 1024; break;
- }
-
- int screenBase = ((bgcnt >> 8) & 0x1F) * 0x800;
- int charBase = ((bgcnt >> 2) & 0x3) * 0x4000;
-
- int x = this.memory.Bgx[bg - 2];
- int y = this.memory.Bgy[bg - 2];
-
- short dx = (short)Memory.ReadU16(this.memory.IORam, Memory.BG2PA + (uint)(bg - 2) * 0x10);
- short dy = (short)Memory.ReadU16(this.memory.IORam, Memory.BG2PC + (uint)(bg - 2) * 0x10);
-
- bool transparent = (bgcnt & (1 << 13)) == 0;
-
- for (int i = 0; i < 240; i++)
- {
- if (true)
- {
- int ax = x >> 8;
- int ay = y >> 8;
-
- if ((ax >= 0 && ax < width && ay >= 0 && ay < height) || !transparent)
- {
- int tmpTileIdx = (int)(screenBase + ((ay & (height - 1)) / 8) * (width / 8) + ((ax & (width - 1)) / 8));
- int tileChar = vram[tmpTileIdx];
-
- int lookup = vram[charBase + (tileChar * 64) + ((ay & 7) * 8) + (ax & 7)];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[lookup * 2] | (palette[lookup * 2 + 1] << 8)));
- uint r = pixelColor & 0xFF;
- uint g = (pixelColor >> 8) & 0xFF;
- uint b = (pixelColor >> 16) & 0xFF;
- r = r + (((0xFF - r) * this.blendY) >> 4);
- g = g + (((0xFF - g) * this.blendY) >> 4);
- b = b + (((0xFF - b) * this.blendY) >> 4);
- pixelColor = r | (g << 8) | (b << 16);
- this.scanline[i] = pixelColor; this.blend[i] = blendMaskType;
-
- }
- }
- }
-
- x += dx;
- y += dy;
- }
- }
- private void RenderRotScaleBgBrightDec(int bg)
- {
- byte[] palette = this.memory.PaletteRam;
- byte[] vram = this.memory.VideoRam;
-
- byte blendMaskType = (byte)(1 << bg);
-
- ushort bgcnt = Memory.ReadU16(this.memory.IORam, Memory.BG0CNT + 0x2 * (uint)bg);
-
- int width = 0, height = 0;
- switch ((bgcnt >> 14) & 0x3)
- {
- case 0: width = 128; height = 128; break;
- case 1: width = 256; height = 256; break;
- case 2: width = 512; height = 512; break;
- case 3: width = 1024; height = 1024; break;
- }
-
- int screenBase = ((bgcnt >> 8) & 0x1F) * 0x800;
- int charBase = ((bgcnt >> 2) & 0x3) * 0x4000;
-
- int x = this.memory.Bgx[bg - 2];
- int y = this.memory.Bgy[bg - 2];
-
- short dx = (short)Memory.ReadU16(this.memory.IORam, Memory.BG2PA + (uint)(bg - 2) * 0x10);
- short dy = (short)Memory.ReadU16(this.memory.IORam, Memory.BG2PC + (uint)(bg - 2) * 0x10);
-
- bool transparent = (bgcnt & (1 << 13)) == 0;
-
- for (int i = 0; i < 240; i++)
- {
- if (true)
- {
- int ax = x >> 8;
- int ay = y >> 8;
-
- if ((ax >= 0 && ax < width && ay >= 0 && ay < height) || !transparent)
- {
- int tmpTileIdx = (int)(screenBase + ((ay & (height - 1)) / 8) * (width / 8) + ((ax & (width - 1)) / 8));
- int tileChar = vram[tmpTileIdx];
-
- int lookup = vram[charBase + (tileChar * 64) + ((ay & 7) * 8) + (ax & 7)];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[lookup * 2] | (palette[lookup * 2 + 1] << 8)));
- uint r = pixelColor & 0xFF;
- uint g = (pixelColor >> 8) & 0xFF;
- uint b = (pixelColor >> 16) & 0xFF;
- r = r - ((r * this.blendY) >> 4);
- g = g - ((g * this.blendY) >> 4);
- b = b - ((b * this.blendY) >> 4);
- pixelColor = r | (g << 8) | (b << 16);
- this.scanline[i] = pixelColor; this.blend[i] = blendMaskType;
-
- }
- }
- }
-
- x += dx;
- y += dy;
- }
- }
- private void RenderRotScaleBgWindow(int bg)
- {
- byte[] palette = this.memory.PaletteRam;
- byte[] vram = this.memory.VideoRam;
-
- byte blendMaskType = (byte)(1 << bg);
-
- ushort bgcnt = Memory.ReadU16(this.memory.IORam, Memory.BG0CNT + 0x2 * (uint)bg);
-
- int width = 0, height = 0;
- switch ((bgcnt >> 14) & 0x3)
- {
- case 0: width = 128; height = 128; break;
- case 1: width = 256; height = 256; break;
- case 2: width = 512; height = 512; break;
- case 3: width = 1024; height = 1024; break;
- }
-
- int screenBase = ((bgcnt >> 8) & 0x1F) * 0x800;
- int charBase = ((bgcnt >> 2) & 0x3) * 0x4000;
-
- int x = this.memory.Bgx[bg - 2];
- int y = this.memory.Bgy[bg - 2];
-
- short dx = (short)Memory.ReadU16(this.memory.IORam, Memory.BG2PA + (uint)(bg - 2) * 0x10);
- short dy = (short)Memory.ReadU16(this.memory.IORam, Memory.BG2PC + (uint)(bg - 2) * 0x10);
-
- bool transparent = (bgcnt & (1 << 13)) == 0;
-
- for (int i = 0; i < 240; i++)
- {
- if ((this.windowCover[i] & (1 << bg)) != 0)
- {
- int ax = x >> 8;
- int ay = y >> 8;
-
- if ((ax >= 0 && ax < width && ay >= 0 && ay < height) || !transparent)
- {
- int tmpTileIdx = (int)(screenBase + ((ay & (height - 1)) / 8) * (width / 8) + ((ax & (width - 1)) / 8));
- int tileChar = vram[tmpTileIdx];
-
- int lookup = vram[charBase + (tileChar * 64) + ((ay & 7) * 8) + (ax & 7)];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[lookup * 2] | (palette[lookup * 2 + 1] << 8)));
- this.scanline[i] = pixelColor; this.blend[i] = blendMaskType;
-
- }
- }
- }
-
- x += dx;
- y += dy;
- }
- }
- private void RenderRotScaleBgWindowBlend(int bg)
- {
- byte[] palette = this.memory.PaletteRam;
- byte[] vram = this.memory.VideoRam;
-
- byte blendMaskType = (byte)(1 << bg);
-
- ushort bgcnt = Memory.ReadU16(this.memory.IORam, Memory.BG0CNT + 0x2 * (uint)bg);
-
- int width = 0, height = 0;
- switch ((bgcnt >> 14) & 0x3)
- {
- case 0: width = 128; height = 128; break;
- case 1: width = 256; height = 256; break;
- case 2: width = 512; height = 512; break;
- case 3: width = 1024; height = 1024; break;
- }
-
- int screenBase = ((bgcnt >> 8) & 0x1F) * 0x800;
- int charBase = ((bgcnt >> 2) & 0x3) * 0x4000;
-
- int x = this.memory.Bgx[bg - 2];
- int y = this.memory.Bgy[bg - 2];
-
- short dx = (short)Memory.ReadU16(this.memory.IORam, Memory.BG2PA + (uint)(bg - 2) * 0x10);
- short dy = (short)Memory.ReadU16(this.memory.IORam, Memory.BG2PC + (uint)(bg - 2) * 0x10);
-
- bool transparent = (bgcnt & (1 << 13)) == 0;
-
- for (int i = 0; i < 240; i++)
- {
- if ((this.windowCover[i] & (1 << bg)) != 0)
- {
- int ax = x >> 8;
- int ay = y >> 8;
-
- if ((ax >= 0 && ax < width && ay >= 0 && ay < height) || !transparent)
- {
- int tmpTileIdx = (int)(screenBase + ((ay & (height - 1)) / 8) * (width / 8) + ((ax & (width - 1)) / 8));
- int tileChar = vram[tmpTileIdx];
-
- int lookup = vram[charBase + (tileChar * 64) + ((ay & 7) * 8) + (ax & 7)];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[lookup * 2] | (palette[lookup * 2 + 1] << 8)));
- if ((this.windowCover[i] & (1 << 5)) != 0)
- {
- if ((this.blend[i] & this.blendTarget) != 0)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[i];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- }
- this.scanline[i] = pixelColor; this.blend[i] = blendMaskType;
-
- }
- }
- }
-
- x += dx;
- y += dy;
- }
- }
- private void RenderRotScaleBgWindowBrightInc(int bg)
- {
- byte[] palette = this.memory.PaletteRam;
- byte[] vram = this.memory.VideoRam;
-
- byte blendMaskType = (byte)(1 << bg);
-
- ushort bgcnt = Memory.ReadU16(this.memory.IORam, Memory.BG0CNT + 0x2 * (uint)bg);
-
- int width = 0, height = 0;
- switch ((bgcnt >> 14) & 0x3)
- {
- case 0: width = 128; height = 128; break;
- case 1: width = 256; height = 256; break;
- case 2: width = 512; height = 512; break;
- case 3: width = 1024; height = 1024; break;
- }
-
- int screenBase = ((bgcnt >> 8) & 0x1F) * 0x800;
- int charBase = ((bgcnt >> 2) & 0x3) * 0x4000;
-
- int x = this.memory.Bgx[bg - 2];
- int y = this.memory.Bgy[bg - 2];
-
- short dx = (short)Memory.ReadU16(this.memory.IORam, Memory.BG2PA + (uint)(bg - 2) * 0x10);
- short dy = (short)Memory.ReadU16(this.memory.IORam, Memory.BG2PC + (uint)(bg - 2) * 0x10);
-
- bool transparent = (bgcnt & (1 << 13)) == 0;
-
- for (int i = 0; i < 240; i++)
- {
- if ((this.windowCover[i] & (1 << bg)) != 0)
- {
- int ax = x >> 8;
- int ay = y >> 8;
-
- if ((ax >= 0 && ax < width && ay >= 0 && ay < height) || !transparent)
- {
- int tmpTileIdx = (int)(screenBase + ((ay & (height - 1)) / 8) * (width / 8) + ((ax & (width - 1)) / 8));
- int tileChar = vram[tmpTileIdx];
-
- int lookup = vram[charBase + (tileChar * 64) + ((ay & 7) * 8) + (ax & 7)];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[lookup * 2] | (palette[lookup * 2 + 1] << 8)));
- if ((this.windowCover[i] & (1 << 5)) != 0)
- {
- uint r = pixelColor & 0xFF;
- uint g = (pixelColor >> 8) & 0xFF;
- uint b = (pixelColor >> 16) & 0xFF;
- r = r + (((0xFF - r) * this.blendY) >> 4);
- g = g + (((0xFF - g) * this.blendY) >> 4);
- b = b + (((0xFF - b) * this.blendY) >> 4);
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[i] = pixelColor; this.blend[i] = blendMaskType;
-
- }
- }
- }
-
- x += dx;
- y += dy;
- }
- }
- private void RenderRotScaleBgWindowBrightDec(int bg)
- {
- byte[] palette = this.memory.PaletteRam;
- byte[] vram = this.memory.VideoRam;
-
- byte blendMaskType = (byte)(1 << bg);
-
- ushort bgcnt = Memory.ReadU16(this.memory.IORam, Memory.BG0CNT + 0x2 * (uint)bg);
-
- int width = 0, height = 0;
- switch ((bgcnt >> 14) & 0x3)
- {
- case 0: width = 128; height = 128; break;
- case 1: width = 256; height = 256; break;
- case 2: width = 512; height = 512; break;
- case 3: width = 1024; height = 1024; break;
- }
-
- int screenBase = ((bgcnt >> 8) & 0x1F) * 0x800;
- int charBase = ((bgcnt >> 2) & 0x3) * 0x4000;
-
- int x = this.memory.Bgx[bg - 2];
- int y = this.memory.Bgy[bg - 2];
-
- short dx = (short)Memory.ReadU16(this.memory.IORam, Memory.BG2PA + (uint)(bg - 2) * 0x10);
- short dy = (short)Memory.ReadU16(this.memory.IORam, Memory.BG2PC + (uint)(bg - 2) * 0x10);
-
- bool transparent = (bgcnt & (1 << 13)) == 0;
-
- for (int i = 0; i < 240; i++)
- {
- if ((this.windowCover[i] & (1 << bg)) != 0)
- {
- int ax = x >> 8;
- int ay = y >> 8;
-
- if ((ax >= 0 && ax < width && ay >= 0 && ay < height) || !transparent)
- {
- int tmpTileIdx = (int)(screenBase + ((ay & (height - 1)) / 8) * (width / 8) + ((ax & (width - 1)) / 8));
- int tileChar = vram[tmpTileIdx];
-
- int lookup = vram[charBase + (tileChar * 64) + ((ay & 7) * 8) + (ax & 7)];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[lookup * 2] | (palette[lookup * 2 + 1] << 8)));
- if ((this.windowCover[i] & (1 << 5)) != 0)
- {
- uint r = pixelColor & 0xFF;
- uint g = (pixelColor >> 8) & 0xFF;
- uint b = (pixelColor >> 16) & 0xFF;
- r = r - ((r * this.blendY) >> 4);
- g = g - ((g * this.blendY) >> 4);
- b = b - ((b * this.blendY) >> 4);
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[i] = pixelColor; this.blend[i] = blendMaskType;
-
- }
- }
- }
-
- x += dx;
- y += dy;
- }
- }
- #endregion Rot/Scale Bg
- #region Text Bg
- private void RenderTextBgNormal(int bg)
- {
- byte[] palette = this.memory.PaletteRam;
- byte[] vram = this.memory.VideoRam;
-
- byte blendMaskType = (byte)(1 << bg);
-
- ushort bgcnt = Memory.ReadU16(this.memory.IORam, Memory.BG0CNT + 0x2 * (uint)bg);
-
- int width = 0, height = 0;
- switch ((bgcnt >> 14) & 0x3)
- {
- case 0: width = 256; height = 256; break;
- case 1: width = 512; height = 256; break;
- case 2: width = 256; height = 512; break;
- case 3: width = 512; height = 512; break;
- }
-
- int screenBase = ((bgcnt >> 8) & 0x1F) * 0x800;
- int charBase = ((bgcnt >> 2) & 0x3) * 0x4000;
-
- int hofs = Memory.ReadU16(this.memory.IORam, Memory.BG0HOFS + (uint)bg * 4) & 0x1FF;
- int vofs = Memory.ReadU16(this.memory.IORam, Memory.BG0VOFS + (uint)bg * 4) & 0x1FF;
-
- if ((bgcnt & (1 << 7)) != 0)
- {
- // 256 color tiles
- int bgy = ((this.curLine + vofs) & (height - 1)) / 8;
-
- int tileIdx = screenBase + (((bgy & 31) * 32) * 2);
- switch ((bgcnt >> 14) & 0x3)
- {
- case 2: if (bgy >= 32) tileIdx += 32 * 32 * 2; break;
- case 3: if (bgy >= 32) tileIdx += 32 * 32 * 4; break;
- }
-
- int tileY = ((this.curLine + vofs) & 0x7) * 8;
-
- for (int i = 0; i < 240; i++)
- {
- if (true)
- {
- int bgx = ((i + hofs) & (width - 1)) / 8;
- int tmpTileIdx = tileIdx + ((bgx & 31) * 2);
- if (bgx >= 32) tmpTileIdx += 32 * 32 * 2;
- int tileChar = vram[tmpTileIdx] | (vram[tmpTileIdx + 1] << 8);
- int x = (i + hofs) & 7;
- int y = tileY;
- if ((tileChar & (1 << 10)) != 0) x = 7 - x;
- if ((tileChar & (1 << 11)) != 0) y = 56 - y;
- int lookup = vram[charBase + ((tileChar & 0x3FF) * 64) + y + x];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[lookup * 2] | (palette[lookup * 2 + 1] << 8)));
- this.scanline[i] = pixelColor; this.blend[i] = blendMaskType;
-
- }
- }
- }
- }
- else
- {
- // 16 color tiles
- int bgy = ((this.curLine + vofs) & (height - 1)) / 8;
-
- int tileIdx = screenBase + (((bgy & 31) * 32) * 2);
- switch ((bgcnt >> 14) & 0x3)
- {
- case 2: if (bgy >= 32) tileIdx += 32 * 32 * 2; break;
- case 3: if (bgy >= 32) tileIdx += 32 * 32 * 4; break;
- }
-
- int tileY = ((this.curLine + vofs) & 0x7) * 4;
-
- for (int i = 0; i < 240; i++)
- {
- if (true)
- {
- int bgx = ((i + hofs) & (width - 1)) / 8;
- int tmpTileIdx = tileIdx + ((bgx & 31) * 2);
- if (bgx >= 32) tmpTileIdx += 32 * 32 * 2;
- int tileChar = vram[tmpTileIdx] | (vram[tmpTileIdx + 1] << 8);
- int x = (i + hofs) & 7;
- int y = tileY;
- if ((tileChar & (1 << 10)) != 0) x = 7 - x;
- if ((tileChar & (1 << 11)) != 0) y = 28 - y;
- int lookup = vram[charBase + ((tileChar & 0x3FF) * 32) + y + (x / 2)];
- if ((x & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- int palNum = ((tileChar >> 12) & 0xf) * 16 * 2;
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palNum + lookup * 2] | (palette[palNum + lookup * 2 + 1] << 8)));
- this.scanline[i] = pixelColor; this.blend[i] = blendMaskType;
-
- }
- }
- }
- }
- }
- private void RenderTextBgBlend(int bg)
- {
- byte[] palette = this.memory.PaletteRam;
- byte[] vram = this.memory.VideoRam;
-
- byte blendMaskType = (byte)(1 << bg);
-
- ushort bgcnt = Memory.ReadU16(this.memory.IORam, Memory.BG0CNT + 0x2 * (uint)bg);
-
- int width = 0, height = 0;
- switch ((bgcnt >> 14) & 0x3)
- {
- case 0: width = 256; height = 256; break;
- case 1: width = 512; height = 256; break;
- case 2: width = 256; height = 512; break;
- case 3: width = 512; height = 512; break;
- }
-
- int screenBase = ((bgcnt >> 8) & 0x1F) * 0x800;
- int charBase = ((bgcnt >> 2) & 0x3) * 0x4000;
-
- int hofs = Memory.ReadU16(this.memory.IORam, Memory.BG0HOFS + (uint)bg * 4) & 0x1FF;
- int vofs = Memory.ReadU16(this.memory.IORam, Memory.BG0VOFS + (uint)bg * 4) & 0x1FF;
-
- if ((bgcnt & (1 << 7)) != 0)
- {
- // 256 color tiles
- int bgy = ((this.curLine + vofs) & (height - 1)) / 8;
-
- int tileIdx = screenBase + (((bgy & 31) * 32) * 2);
- switch ((bgcnt >> 14) & 0x3)
- {
- case 2: if (bgy >= 32) tileIdx += 32 * 32 * 2; break;
- case 3: if (bgy >= 32) tileIdx += 32 * 32 * 4; break;
- }
-
- int tileY = ((this.curLine + vofs) & 0x7) * 8;
-
- for (int i = 0; i < 240; i++)
- {
- if (true)
- {
- int bgx = ((i + hofs) & (width - 1)) / 8;
- int tmpTileIdx = tileIdx + ((bgx & 31) * 2);
- if (bgx >= 32) tmpTileIdx += 32 * 32 * 2;
- int tileChar = vram[tmpTileIdx] | (vram[tmpTileIdx + 1] << 8);
- int x = (i + hofs) & 7;
- int y = tileY;
- if ((tileChar & (1 << 10)) != 0) x = 7 - x;
- if ((tileChar & (1 << 11)) != 0) y = 56 - y;
- int lookup = vram[charBase + ((tileChar & 0x3FF) * 64) + y + x];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[lookup * 2] | (palette[lookup * 2 + 1] << 8)));
- if ((this.blend[i] & this.blendTarget) != 0)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[i];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[i] = pixelColor; this.blend[i] = blendMaskType;
-
- }
- }
- }
- }
- else
- {
- // 16 color tiles
- int bgy = ((this.curLine + vofs) & (height - 1)) / 8;
-
- int tileIdx = screenBase + (((bgy & 31) * 32) * 2);
- switch ((bgcnt >> 14) & 0x3)
- {
- case 2: if (bgy >= 32) tileIdx += 32 * 32 * 2; break;
- case 3: if (bgy >= 32) tileIdx += 32 * 32 * 4; break;
- }
-
- int tileY = ((this.curLine + vofs) & 0x7) * 4;
-
- for (int i = 0; i < 240; i++)
- {
- if (true)
- {
- int bgx = ((i + hofs) & (width - 1)) / 8;
- int tmpTileIdx = tileIdx + ((bgx & 31) * 2);
- if (bgx >= 32) tmpTileIdx += 32 * 32 * 2;
- int tileChar = vram[tmpTileIdx] | (vram[tmpTileIdx + 1] << 8);
- int x = (i + hofs) & 7;
- int y = tileY;
- if ((tileChar & (1 << 10)) != 0) x = 7 - x;
- if ((tileChar & (1 << 11)) != 0) y = 28 - y;
- int lookup = vram[charBase + ((tileChar & 0x3FF) * 32) + y + (x / 2)];
- if ((x & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- int palNum = ((tileChar >> 12) & 0xf) * 16 * 2;
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palNum + lookup * 2] | (palette[palNum + lookup * 2 + 1] << 8)));
- if ((this.blend[i] & this.blendTarget) != 0)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[i];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[i] = pixelColor; this.blend[i] = blendMaskType;
-
- }
- }
- }
- }
- }
- private void RenderTextBgBrightInc(int bg)
- {
- byte[] palette = this.memory.PaletteRam;
- byte[] vram = this.memory.VideoRam;
-
- byte blendMaskType = (byte)(1 << bg);
-
- ushort bgcnt = Memory.ReadU16(this.memory.IORam, Memory.BG0CNT + 0x2 * (uint)bg);
-
- int width = 0, height = 0;
- switch ((bgcnt >> 14) & 0x3)
- {
- case 0: width = 256; height = 256; break;
- case 1: width = 512; height = 256; break;
- case 2: width = 256; height = 512; break;
- case 3: width = 512; height = 512; break;
- }
-
- int screenBase = ((bgcnt >> 8) & 0x1F) * 0x800;
- int charBase = ((bgcnt >> 2) & 0x3) * 0x4000;
-
- int hofs = Memory.ReadU16(this.memory.IORam, Memory.BG0HOFS + (uint)bg * 4) & 0x1FF;
- int vofs = Memory.ReadU16(this.memory.IORam, Memory.BG0VOFS + (uint)bg * 4) & 0x1FF;
-
- if ((bgcnt & (1 << 7)) != 0)
- {
- // 256 color tiles
- int bgy = ((this.curLine + vofs) & (height - 1)) / 8;
-
- int tileIdx = screenBase + (((bgy & 31) * 32) * 2);
- switch ((bgcnt >> 14) & 0x3)
- {
- case 2: if (bgy >= 32) tileIdx += 32 * 32 * 2; break;
- case 3: if (bgy >= 32) tileIdx += 32 * 32 * 4; break;
- }
-
- int tileY = ((this.curLine + vofs) & 0x7) * 8;
-
- for (int i = 0; i < 240; i++)
- {
- if (true)
- {
- int bgx = ((i + hofs) & (width - 1)) / 8;
- int tmpTileIdx = tileIdx + ((bgx & 31) * 2);
- if (bgx >= 32) tmpTileIdx += 32 * 32 * 2;
- int tileChar = vram[tmpTileIdx] | (vram[tmpTileIdx + 1] << 8);
- int x = (i + hofs) & 7;
- int y = tileY;
- if ((tileChar & (1 << 10)) != 0) x = 7 - x;
- if ((tileChar & (1 << 11)) != 0) y = 56 - y;
- int lookup = vram[charBase + ((tileChar & 0x3FF) * 64) + y + x];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[lookup * 2] | (palette[lookup * 2 + 1] << 8)));
- uint r = pixelColor & 0xFF;
- uint g = (pixelColor >> 8) & 0xFF;
- uint b = (pixelColor >> 16) & 0xFF;
- r = r + (((0xFF - r) * this.blendY) >> 4);
- g = g + (((0xFF - g) * this.blendY) >> 4);
- b = b + (((0xFF - b) * this.blendY) >> 4);
- pixelColor = r | (g << 8) | (b << 16);
- this.scanline[i] = pixelColor; this.blend[i] = blendMaskType;
-
- }
- }
- }
- }
- else
- {
- // 16 color tiles
- int bgy = ((this.curLine + vofs) & (height - 1)) / 8;
-
- int tileIdx = screenBase + (((bgy & 31) * 32) * 2);
- switch ((bgcnt >> 14) & 0x3)
- {
- case 2: if (bgy >= 32) tileIdx += 32 * 32 * 2; break;
- case 3: if (bgy >= 32) tileIdx += 32 * 32 * 4; break;
- }
-
- int tileY = ((this.curLine + vofs) & 0x7) * 4;
-
- for (int i = 0; i < 240; i++)
- {
- if (true)
- {
- int bgx = ((i + hofs) & (width - 1)) / 8;
- int tmpTileIdx = tileIdx + ((bgx & 31) * 2);
- if (bgx >= 32) tmpTileIdx += 32 * 32 * 2;
- int tileChar = vram[tmpTileIdx] | (vram[tmpTileIdx + 1] << 8);
- int x = (i + hofs) & 7;
- int y = tileY;
- if ((tileChar & (1 << 10)) != 0) x = 7 - x;
- if ((tileChar & (1 << 11)) != 0) y = 28 - y;
- int lookup = vram[charBase + ((tileChar & 0x3FF) * 32) + y + (x / 2)];
- if ((x & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- int palNum = ((tileChar >> 12) & 0xf) * 16 * 2;
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palNum + lookup * 2] | (palette[palNum + lookup * 2 + 1] << 8)));
- uint r = pixelColor & 0xFF;
- uint g = (pixelColor >> 8) & 0xFF;
- uint b = (pixelColor >> 16) & 0xFF;
- r = r + (((0xFF - r) * this.blendY) >> 4);
- g = g + (((0xFF - g) * this.blendY) >> 4);
- b = b + (((0xFF - b) * this.blendY) >> 4);
- pixelColor = r | (g << 8) | (b << 16);
- this.scanline[i] = pixelColor; this.blend[i] = blendMaskType;
-
- }
- }
- }
- }
- }
- private void RenderTextBgBrightDec(int bg)
- {
- byte[] palette = this.memory.PaletteRam;
- byte[] vram = this.memory.VideoRam;
-
- byte blendMaskType = (byte)(1 << bg);
-
- ushort bgcnt = Memory.ReadU16(this.memory.IORam, Memory.BG0CNT + 0x2 * (uint)bg);
-
- int width = 0, height = 0;
- switch ((bgcnt >> 14) & 0x3)
- {
- case 0: width = 256; height = 256; break;
- case 1: width = 512; height = 256; break;
- case 2: width = 256; height = 512; break;
- case 3: width = 512; height = 512; break;
- }
-
- int screenBase = ((bgcnt >> 8) & 0x1F) * 0x800;
- int charBase = ((bgcnt >> 2) & 0x3) * 0x4000;
-
- int hofs = Memory.ReadU16(this.memory.IORam, Memory.BG0HOFS + (uint)bg * 4) & 0x1FF;
- int vofs = Memory.ReadU16(this.memory.IORam, Memory.BG0VOFS + (uint)bg * 4) & 0x1FF;
-
- if ((bgcnt & (1 << 7)) != 0)
- {
- // 256 color tiles
- int bgy = ((this.curLine + vofs) & (height - 1)) / 8;
-
- int tileIdx = screenBase + (((bgy & 31) * 32) * 2);
- switch ((bgcnt >> 14) & 0x3)
- {
- case 2: if (bgy >= 32) tileIdx += 32 * 32 * 2; break;
- case 3: if (bgy >= 32) tileIdx += 32 * 32 * 4; break;
- }
-
- int tileY = ((this.curLine + vofs) & 0x7) * 8;
-
- for (int i = 0; i < 240; i++)
- {
- if (true)
- {
- int bgx = ((i + hofs) & (width - 1)) / 8;
- int tmpTileIdx = tileIdx + ((bgx & 31) * 2);
- if (bgx >= 32) tmpTileIdx += 32 * 32 * 2;
- int tileChar = vram[tmpTileIdx] | (vram[tmpTileIdx + 1] << 8);
- int x = (i + hofs) & 7;
- int y = tileY;
- if ((tileChar & (1 << 10)) != 0) x = 7 - x;
- if ((tileChar & (1 << 11)) != 0) y = 56 - y;
- int lookup = vram[charBase + ((tileChar & 0x3FF) * 64) + y + x];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[lookup * 2] | (palette[lookup * 2 + 1] << 8)));
- uint r = pixelColor & 0xFF;
- uint g = (pixelColor >> 8) & 0xFF;
- uint b = (pixelColor >> 16) & 0xFF;
- r = r - ((r * this.blendY) >> 4);
- g = g - ((g * this.blendY) >> 4);
- b = b - ((b * this.blendY) >> 4);
- pixelColor = r | (g << 8) | (b << 16);
- this.scanline[i] = pixelColor; this.blend[i] = blendMaskType;
-
- }
- }
- }
- }
- else
- {
- // 16 color tiles
- int bgy = ((this.curLine + vofs) & (height - 1)) / 8;
-
- int tileIdx = screenBase + (((bgy & 31) * 32) * 2);
- switch ((bgcnt >> 14) & 0x3)
- {
- case 2: if (bgy >= 32) tileIdx += 32 * 32 * 2; break;
- case 3: if (bgy >= 32) tileIdx += 32 * 32 * 4; break;
- }
-
- int tileY = ((this.curLine + vofs) & 0x7) * 4;
-
- for (int i = 0; i < 240; i++)
- {
- if (true)
- {
- int bgx = ((i + hofs) & (width - 1)) / 8;
- int tmpTileIdx = tileIdx + ((bgx & 31) * 2);
- if (bgx >= 32) tmpTileIdx += 32 * 32 * 2;
- int tileChar = vram[tmpTileIdx] | (vram[tmpTileIdx + 1] << 8);
- int x = (i + hofs) & 7;
- int y = tileY;
- if ((tileChar & (1 << 10)) != 0) x = 7 - x;
- if ((tileChar & (1 << 11)) != 0) y = 28 - y;
- int lookup = vram[charBase + ((tileChar & 0x3FF) * 32) + y + (x / 2)];
- if ((x & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- int palNum = ((tileChar >> 12) & 0xf) * 16 * 2;
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palNum + lookup * 2] | (palette[palNum + lookup * 2 + 1] << 8)));
- uint r = pixelColor & 0xFF;
- uint g = (pixelColor >> 8) & 0xFF;
- uint b = (pixelColor >> 16) & 0xFF;
- r = r - ((r * this.blendY) >> 4);
- g = g - ((g * this.blendY) >> 4);
- b = b - ((b * this.blendY) >> 4);
- pixelColor = r | (g << 8) | (b << 16);
- this.scanline[i] = pixelColor; this.blend[i] = blendMaskType;
-
- }
- }
- }
- }
- }
- private void RenderTextBgWindow(int bg)
- {
- byte[] palette = this.memory.PaletteRam;
- byte[] vram = this.memory.VideoRam;
-
- byte blendMaskType = (byte)(1 << bg);
-
- ushort bgcnt = Memory.ReadU16(this.memory.IORam, Memory.BG0CNT + 0x2 * (uint)bg);
-
- int width = 0, height = 0;
- switch ((bgcnt >> 14) & 0x3)
- {
- case 0: width = 256; height = 256; break;
- case 1: width = 512; height = 256; break;
- case 2: width = 256; height = 512; break;
- case 3: width = 512; height = 512; break;
- }
-
- int screenBase = ((bgcnt >> 8) & 0x1F) * 0x800;
- int charBase = ((bgcnt >> 2) & 0x3) * 0x4000;
-
- int hofs = Memory.ReadU16(this.memory.IORam, Memory.BG0HOFS + (uint)bg * 4) & 0x1FF;
- int vofs = Memory.ReadU16(this.memory.IORam, Memory.BG0VOFS + (uint)bg * 4) & 0x1FF;
-
- if ((bgcnt & (1 << 7)) != 0)
- {
- // 256 color tiles
- int bgy = ((this.curLine + vofs) & (height - 1)) / 8;
-
- int tileIdx = screenBase + (((bgy & 31) * 32) * 2);
- switch ((bgcnt >> 14) & 0x3)
- {
- case 2: if (bgy >= 32) tileIdx += 32 * 32 * 2; break;
- case 3: if (bgy >= 32) tileIdx += 32 * 32 * 4; break;
- }
-
- int tileY = ((this.curLine + vofs) & 0x7) * 8;
-
- for (int i = 0; i < 240; i++)
- {
- if ((this.windowCover[i] & (1 << bg)) != 0)
- {
- int bgx = ((i + hofs) & (width - 1)) / 8;
- int tmpTileIdx = tileIdx + ((bgx & 31) * 2);
- if (bgx >= 32) tmpTileIdx += 32 * 32 * 2;
- int tileChar = vram[tmpTileIdx] | (vram[tmpTileIdx + 1] << 8);
- int x = (i + hofs) & 7;
- int y = tileY;
- if ((tileChar & (1 << 10)) != 0) x = 7 - x;
- if ((tileChar & (1 << 11)) != 0) y = 56 - y;
- int lookup = vram[charBase + ((tileChar & 0x3FF) * 64) + y + x];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[lookup * 2] | (palette[lookup * 2 + 1] << 8)));
- this.scanline[i] = pixelColor; this.blend[i] = blendMaskType;
-
- }
- }
- }
- }
- else
- {
- // 16 color tiles
- int bgy = ((this.curLine + vofs) & (height - 1)) / 8;
-
- int tileIdx = screenBase + (((bgy & 31) * 32) * 2);
- switch ((bgcnt >> 14) & 0x3)
- {
- case 2: if (bgy >= 32) tileIdx += 32 * 32 * 2; break;
- case 3: if (bgy >= 32) tileIdx += 32 * 32 * 4; break;
- }
-
- int tileY = ((this.curLine + vofs) & 0x7) * 4;
-
- for (int i = 0; i < 240; i++)
- {
- if ((this.windowCover[i] & (1 << bg)) != 0)
- {
- int bgx = ((i + hofs) & (width - 1)) / 8;
- int tmpTileIdx = tileIdx + ((bgx & 31) * 2);
- if (bgx >= 32) tmpTileIdx += 32 * 32 * 2;
- int tileChar = vram[tmpTileIdx] | (vram[tmpTileIdx + 1] << 8);
- int x = (i + hofs) & 7;
- int y = tileY;
- if ((tileChar & (1 << 10)) != 0) x = 7 - x;
- if ((tileChar & (1 << 11)) != 0) y = 28 - y;
- int lookup = vram[charBase + ((tileChar & 0x3FF) * 32) + y + (x / 2)];
- if ((x & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- int palNum = ((tileChar >> 12) & 0xf) * 16 * 2;
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palNum + lookup * 2] | (palette[palNum + lookup * 2 + 1] << 8)));
- this.scanline[i] = pixelColor; this.blend[i] = blendMaskType;
-
- }
- }
- }
- }
- }
- private void RenderTextBgWindowBlend(int bg)
- {
- byte[] palette = this.memory.PaletteRam;
- byte[] vram = this.memory.VideoRam;
-
- byte blendMaskType = (byte)(1 << bg);
-
- ushort bgcnt = Memory.ReadU16(this.memory.IORam, Memory.BG0CNT + 0x2 * (uint)bg);
-
- int width = 0, height = 0;
- switch ((bgcnt >> 14) & 0x3)
- {
- case 0: width = 256; height = 256; break;
- case 1: width = 512; height = 256; break;
- case 2: width = 256; height = 512; break;
- case 3: width = 512; height = 512; break;
- }
-
- int screenBase = ((bgcnt >> 8) & 0x1F) * 0x800;
- int charBase = ((bgcnt >> 2) & 0x3) * 0x4000;
-
- int hofs = Memory.ReadU16(this.memory.IORam, Memory.BG0HOFS + (uint)bg * 4) & 0x1FF;
- int vofs = Memory.ReadU16(this.memory.IORam, Memory.BG0VOFS + (uint)bg * 4) & 0x1FF;
-
- if ((bgcnt & (1 << 7)) != 0)
- {
- // 256 color tiles
- int bgy = ((this.curLine + vofs) & (height - 1)) / 8;
-
- int tileIdx = screenBase + (((bgy & 31) * 32) * 2);
- switch ((bgcnt >> 14) & 0x3)
- {
- case 2: if (bgy >= 32) tileIdx += 32 * 32 * 2; break;
- case 3: if (bgy >= 32) tileIdx += 32 * 32 * 4; break;
- }
-
- int tileY = ((this.curLine + vofs) & 0x7) * 8;
-
- for (int i = 0; i < 240; i++)
- {
- if ((this.windowCover[i] & (1 << bg)) != 0)
- {
- int bgx = ((i + hofs) & (width - 1)) / 8;
- int tmpTileIdx = tileIdx + ((bgx & 31) * 2);
- if (bgx >= 32) tmpTileIdx += 32 * 32 * 2;
- int tileChar = vram[tmpTileIdx] | (vram[tmpTileIdx + 1] << 8);
- int x = (i + hofs) & 7;
- int y = tileY;
- if ((tileChar & (1 << 10)) != 0) x = 7 - x;
- if ((tileChar & (1 << 11)) != 0) y = 56 - y;
- int lookup = vram[charBase + ((tileChar & 0x3FF) * 64) + y + x];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[lookup * 2] | (palette[lookup * 2 + 1] << 8)));
- if ((this.windowCover[i] & (1 << 5)) != 0)
- {
- if ((this.blend[i] & this.blendTarget) != 0)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[i];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- }
- this.scanline[i] = pixelColor; this.blend[i] = blendMaskType;
-
- }
- }
- }
- }
- else
- {
- // 16 color tiles
- int bgy = ((this.curLine + vofs) & (height - 1)) / 8;
-
- int tileIdx = screenBase + (((bgy & 31) * 32) * 2);
- switch ((bgcnt >> 14) & 0x3)
- {
- case 2: if (bgy >= 32) tileIdx += 32 * 32 * 2; break;
- case 3: if (bgy >= 32) tileIdx += 32 * 32 * 4; break;
- }
-
- int tileY = ((this.curLine + vofs) & 0x7) * 4;
-
- for (int i = 0; i < 240; i++)
- {
- if ((this.windowCover[i] & (1 << bg)) != 0)
- {
- int bgx = ((i + hofs) & (width - 1)) / 8;
- int tmpTileIdx = tileIdx + ((bgx & 31) * 2);
- if (bgx >= 32) tmpTileIdx += 32 * 32 * 2;
- int tileChar = vram[tmpTileIdx] | (vram[tmpTileIdx + 1] << 8);
- int x = (i + hofs) & 7;
- int y = tileY;
- if ((tileChar & (1 << 10)) != 0) x = 7 - x;
- if ((tileChar & (1 << 11)) != 0) y = 28 - y;
- int lookup = vram[charBase + ((tileChar & 0x3FF) * 32) + y + (x / 2)];
- if ((x & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- int palNum = ((tileChar >> 12) & 0xf) * 16 * 2;
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palNum + lookup * 2] | (palette[palNum + lookup * 2 + 1] << 8)));
- if ((this.windowCover[i] & (1 << 5)) != 0)
- {
- if ((this.blend[i] & this.blendTarget) != 0)
- {
- uint r = ((pixelColor & 0xFF) * this.blendA) >> 4;
- uint g = (((pixelColor >> 8) & 0xFF) * this.blendA) >> 4;
- uint b = (((pixelColor >> 16) & 0xFF) * this.blendA) >> 4;
- uint sourceValue = this.scanline[i];
- r += ((sourceValue & 0xFF) * this.blendB) >> 4;
- g += (((sourceValue >> 8) & 0xFF) * this.blendB) >> 4;
- b += (((sourceValue >> 16) & 0xFF) * this.blendB) >> 4;
- if (r > 0xff) r = 0xff;
- if (g > 0xff) g = 0xff;
- if (b > 0xff) b = 0xff;
- pixelColor = r | (g << 8) | (b << 16);
- }
- }
- this.scanline[i] = pixelColor; this.blend[i] = blendMaskType;
-
- }
- }
- }
- }
- }
- private void RenderTextBgWindowBrightInc(int bg)
- {
- byte[] palette = this.memory.PaletteRam;
- byte[] vram = this.memory.VideoRam;
-
- byte blendMaskType = (byte)(1 << bg);
-
- ushort bgcnt = Memory.ReadU16(this.memory.IORam, Memory.BG0CNT + 0x2 * (uint)bg);
-
- int width = 0, height = 0;
- switch ((bgcnt >> 14) & 0x3)
- {
- case 0: width = 256; height = 256; break;
- case 1: width = 512; height = 256; break;
- case 2: width = 256; height = 512; break;
- case 3: width = 512; height = 512; break;
- }
-
- int screenBase = ((bgcnt >> 8) & 0x1F) * 0x800;
- int charBase = ((bgcnt >> 2) & 0x3) * 0x4000;
-
- int hofs = Memory.ReadU16(this.memory.IORam, Memory.BG0HOFS + (uint)bg * 4) & 0x1FF;
- int vofs = Memory.ReadU16(this.memory.IORam, Memory.BG0VOFS + (uint)bg * 4) & 0x1FF;
-
- if ((bgcnt & (1 << 7)) != 0)
- {
- // 256 color tiles
- int bgy = ((this.curLine + vofs) & (height - 1)) / 8;
-
- int tileIdx = screenBase + (((bgy & 31) * 32) * 2);
- switch ((bgcnt >> 14) & 0x3)
- {
- case 2: if (bgy >= 32) tileIdx += 32 * 32 * 2; break;
- case 3: if (bgy >= 32) tileIdx += 32 * 32 * 4; break;
- }
-
- int tileY = ((this.curLine + vofs) & 0x7) * 8;
-
- for (int i = 0; i < 240; i++)
- {
- if ((this.windowCover[i] & (1 << bg)) != 0)
- {
- int bgx = ((i + hofs) & (width - 1)) / 8;
- int tmpTileIdx = tileIdx + ((bgx & 31) * 2);
- if (bgx >= 32) tmpTileIdx += 32 * 32 * 2;
- int tileChar = vram[tmpTileIdx] | (vram[tmpTileIdx + 1] << 8);
- int x = (i + hofs) & 7;
- int y = tileY;
- if ((tileChar & (1 << 10)) != 0) x = 7 - x;
- if ((tileChar & (1 << 11)) != 0) y = 56 - y;
- int lookup = vram[charBase + ((tileChar & 0x3FF) * 64) + y + x];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[lookup * 2] | (palette[lookup * 2 + 1] << 8)));
- if ((this.windowCover[i] & (1 << 5)) != 0)
- {
- uint r = pixelColor & 0xFF;
- uint g = (pixelColor >> 8) & 0xFF;
- uint b = (pixelColor >> 16) & 0xFF;
- r = r + (((0xFF - r) * this.blendY) >> 4);
- g = g + (((0xFF - g) * this.blendY) >> 4);
- b = b + (((0xFF - b) * this.blendY) >> 4);
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[i] = pixelColor; this.blend[i] = blendMaskType;
-
- }
- }
- }
- }
- else
- {
- // 16 color tiles
- int bgy = ((this.curLine + vofs) & (height - 1)) / 8;
-
- int tileIdx = screenBase + (((bgy & 31) * 32) * 2);
- switch ((bgcnt >> 14) & 0x3)
- {
- case 2: if (bgy >= 32) tileIdx += 32 * 32 * 2; break;
- case 3: if (bgy >= 32) tileIdx += 32 * 32 * 4; break;
- }
-
- int tileY = ((this.curLine + vofs) & 0x7) * 4;
-
- for (int i = 0; i < 240; i++)
- {
- if ((this.windowCover[i] & (1 << bg)) != 0)
- {
- int bgx = ((i + hofs) & (width - 1)) / 8;
- int tmpTileIdx = tileIdx + ((bgx & 31) * 2);
- if (bgx >= 32) tmpTileIdx += 32 * 32 * 2;
- int tileChar = vram[tmpTileIdx] | (vram[tmpTileIdx + 1] << 8);
- int x = (i + hofs) & 7;
- int y = tileY;
- if ((tileChar & (1 << 10)) != 0) x = 7 - x;
- if ((tileChar & (1 << 11)) != 0) y = 28 - y;
- int lookup = vram[charBase + ((tileChar & 0x3FF) * 32) + y + (x / 2)];
- if ((x & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- int palNum = ((tileChar >> 12) & 0xf) * 16 * 2;
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palNum + lookup * 2] | (palette[palNum + lookup * 2 + 1] << 8)));
- if ((this.windowCover[i] & (1 << 5)) != 0)
- {
- uint r = pixelColor & 0xFF;
- uint g = (pixelColor >> 8) & 0xFF;
- uint b = (pixelColor >> 16) & 0xFF;
- r = r + (((0xFF - r) * this.blendY) >> 4);
- g = g + (((0xFF - g) * this.blendY) >> 4);
- b = b + (((0xFF - b) * this.blendY) >> 4);
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[i] = pixelColor; this.blend[i] = blendMaskType;
-
- }
- }
- }
- }
- }
- private void RenderTextBgWindowBrightDec(int bg)
- {
- byte[] palette = this.memory.PaletteRam;
- byte[] vram = this.memory.VideoRam;
-
- byte blendMaskType = (byte)(1 << bg);
-
- ushort bgcnt = Memory.ReadU16(this.memory.IORam, Memory.BG0CNT + 0x2 * (uint)bg);
-
- int width = 0, height = 0;
- switch ((bgcnt >> 14) & 0x3)
- {
- case 0: width = 256; height = 256; break;
- case 1: width = 512; height = 256; break;
- case 2: width = 256; height = 512; break;
- case 3: width = 512; height = 512; break;
- }
-
- int screenBase = ((bgcnt >> 8) & 0x1F) * 0x800;
- int charBase = ((bgcnt >> 2) & 0x3) * 0x4000;
-
- int hofs = Memory.ReadU16(this.memory.IORam, Memory.BG0HOFS + (uint)bg * 4) & 0x1FF;
- int vofs = Memory.ReadU16(this.memory.IORam, Memory.BG0VOFS + (uint)bg * 4) & 0x1FF;
-
- if ((bgcnt & (1 << 7)) != 0)
- {
- // 256 color tiles
- int bgy = ((this.curLine + vofs) & (height - 1)) / 8;
-
- int tileIdx = screenBase + (((bgy & 31) * 32) * 2);
- switch ((bgcnt >> 14) & 0x3)
- {
- case 2: if (bgy >= 32) tileIdx += 32 * 32 * 2; break;
- case 3: if (bgy >= 32) tileIdx += 32 * 32 * 4; break;
- }
-
- int tileY = ((this.curLine + vofs) & 0x7) * 8;
-
- for (int i = 0; i < 240; i++)
- {
- if ((this.windowCover[i] & (1 << bg)) != 0)
- {
- int bgx = ((i + hofs) & (width - 1)) / 8;
- int tmpTileIdx = tileIdx + ((bgx & 31) * 2);
- if (bgx >= 32) tmpTileIdx += 32 * 32 * 2;
- int tileChar = vram[tmpTileIdx] | (vram[tmpTileIdx + 1] << 8);
- int x = (i + hofs) & 7;
- int y = tileY;
- if ((tileChar & (1 << 10)) != 0) x = 7 - x;
- if ((tileChar & (1 << 11)) != 0) y = 56 - y;
- int lookup = vram[charBase + ((tileChar & 0x3FF) * 64) + y + x];
- if (lookup != 0)
- {
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[lookup * 2] | (palette[lookup * 2 + 1] << 8)));
- if ((this.windowCover[i] & (1 << 5)) != 0)
- {
- uint r = pixelColor & 0xFF;
- uint g = (pixelColor >> 8) & 0xFF;
- uint b = (pixelColor >> 16) & 0xFF;
- r = r - ((r * this.blendY) >> 4);
- g = g - ((g * this.blendY) >> 4);
- b = b - ((b * this.blendY) >> 4);
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[i] = pixelColor; this.blend[i] = blendMaskType;
-
- }
- }
- }
- }
- else
- {
- // 16 color tiles
- int bgy = ((this.curLine + vofs) & (height - 1)) / 8;
-
- int tileIdx = screenBase + (((bgy & 31) * 32) * 2);
- switch ((bgcnt >> 14) & 0x3)
- {
- case 2: if (bgy >= 32) tileIdx += 32 * 32 * 2; break;
- case 3: if (bgy >= 32) tileIdx += 32 * 32 * 4; break;
- }
-
- int tileY = ((this.curLine + vofs) & 0x7) * 4;
-
- for (int i = 0; i < 240; i++)
- {
- if ((this.windowCover[i] & (1 << bg)) != 0)
- {
- int bgx = ((i + hofs) & (width - 1)) / 8;
- int tmpTileIdx = tileIdx + ((bgx & 31) * 2);
- if (bgx >= 32) tmpTileIdx += 32 * 32 * 2;
- int tileChar = vram[tmpTileIdx] | (vram[tmpTileIdx + 1] << 8);
- int x = (i + hofs) & 7;
- int y = tileY;
- if ((tileChar & (1 << 10)) != 0) x = 7 - x;
- if ((tileChar & (1 << 11)) != 0) y = 28 - y;
- int lookup = vram[charBase + ((tileChar & 0x3FF) * 32) + y + (x / 2)];
- if ((x & 1) == 0)
- {
- lookup &= 0xf;
- }
- else
- {
- lookup >>= 4;
- }
- if (lookup != 0)
- {
- int palNum = ((tileChar >> 12) & 0xf) * 16 * 2;
- uint pixelColor = Renderer.GbaTo32((ushort)(palette[palNum + lookup * 2] | (palette[palNum + lookup * 2 + 1] << 8)));
- if ((this.windowCover[i] & (1 << 5)) != 0)
- {
- uint r = pixelColor & 0xFF;
- uint g = (pixelColor >> 8) & 0xFF;
- uint b = (pixelColor >> 16) & 0xFF;
- r = r - ((r * this.blendY) >> 4);
- g = g - ((g * this.blendY) >> 4);
- b = b - ((b * this.blendY) >> 4);
- pixelColor = r | (g << 8) | (b << 16);
- }
- this.scanline[i] = pixelColor; this.blend[i] = blendMaskType;
-
- }
- }
- }
- }
- }
- #endregion Text Bg
- }
-}
diff --git a/attic/GarboDev/SoundManager.cs b/attic/GarboDev/SoundManager.cs
deleted file mode 100644
index 5679202345..0000000000
--- a/attic/GarboDev/SoundManager.cs
+++ /dev/null
@@ -1,191 +0,0 @@
-namespace GarboDev
-{
- using System;
- using System.Collections.Generic;
- using System.Text;
-
- public class SoundManager
- {
- private Memory memory = null;
- private Queue[] soundQueue = new Queue[2];
- private byte latchedA, latchedB;
- private int frequency, cyclesPerSample;
- private int leftover = 0;
-
- private short[] soundBuffer = new short[40000];
- private int soundBufferPos = 0;
- private int lastSoundBufferPos = 0;
-
- public SoundManager(Memory memory, int frequency)
- {
- this.Frequency = frequency;
-
- this.memory = memory;
- this.memory.SoundManager = this;
-
- this.soundQueue[0] = new Queue(32);
- this.soundQueue[1] = new Queue(32);
- }
-
- #region Public Properties
- public int Frequency
- {
- get { return this.frequency; }
- set
- {
- this.frequency = value;
- this.cyclesPerSample = (GbaManager.cpuFreq << 5) / this.frequency;
- }
- }
-
- public int QueueSizeA
- {
- get { return this.soundQueue[0].Count; }
- }
-
- public int QueueSizeB
- {
- get { return this.soundQueue[1].Count; }
- }
-
- public int SamplesMixed
- {
- get
- {
- int value = this.soundBufferPos - this.lastSoundBufferPos;
- if (value < 0) value += this.soundBuffer.Length;
- return value;
- }
- }
- #endregion
-
- #region Public Methods
- public void GetSamples(short[] buffer, int length)
- {
- for (int i = 0; i < length; i++)
- {
- if (this.lastSoundBufferPos == this.soundBuffer.Length)
- {
- this.lastSoundBufferPos = 0;
- }
- buffer[i] = this.soundBuffer[this.lastSoundBufferPos++];
- }
- }
-
- public void Mix(int cycles)
- {
- ushort soundCntH = Memory.ReadU16(this.memory.IORam, Memory.SOUNDCNT_H);
- ushort soundCntX = Memory.ReadU16(this.memory.IORam, Memory.SOUNDCNT_X);
-
- cycles <<= 5;
- cycles += this.leftover;
-
- if (cycles > 0)
- {
- // Precompute loop invariants
- short directA = (short)(sbyte)(this.latchedA);
- short directB = (short)(sbyte)(this.latchedB);
-
- if ((soundCntH & (1 << 2)) == 0)
- {
- directA >>= 1;
- }
- if ((soundCntH & (1 << 3)) == 0)
- {
- directB >>= 1;
- }
-
- while (cycles > 0)
- {
- short l = 0, r = 0;
-
- cycles -= this.cyclesPerSample;
-
- // Mixing
- if ((soundCntX & (1 << 7)) != 0)
- {
- if ((soundCntH & (1 << 8)) != 0)
- {
- r += directA;
- }
- if ((soundCntH & (1 << 9)) != 0)
- {
- l += directA;
- }
- if ((soundCntH & (1 << 12)) != 0)
- {
- r += directB;
- }
- if ((soundCntH & (1 << 13)) != 0)
- {
- l += directB;
- }
- }
-
- if (this.soundBufferPos == this.soundBuffer.Length)
- {
- this.soundBufferPos = 0;
- }
-
- this.soundBuffer[this.soundBufferPos++] = (short)(l << 6);
- this.soundBuffer[this.soundBufferPos++] = (short)(r << 6);
- }
- }
-
- this.leftover = cycles;
- }
-
- public void ResetFifoA()
- {
- this.soundQueue[0].Clear();
- this.latchedA = 0;
- }
-
- public void ResetFifoB()
- {
- this.soundQueue[1].Clear();
- this.latchedB = 0;
- }
-
- public void IncrementFifoA()
- {
- for (int i = 0; i < 4; i++)
- {
- this.EnqueueDSoundSample(0, this.memory.IORam[Memory.FIFO_A_L + i]);
- }
- }
-
- public void IncrementFifoB()
- {
- for (int i = 0; i < 4; i++)
- {
- this.EnqueueDSoundSample(1, this.memory.IORam[Memory.FIFO_B_L + i]);
- }
- }
-
- public void DequeueA()
- {
- if (this.soundQueue[0].Count > 0)
- {
- this.latchedA = this.soundQueue[0].Dequeue();
- }
- }
-
- public void DequeueB()
- {
- if (this.soundQueue[1].Count > 0)
- {
- this.latchedB = this.soundQueue[1].Dequeue();
- }
- }
- #endregion Public Methods
-
- private void EnqueueDSoundSample(int channel, byte sample)
- {
- if (this.soundQueue[channel].Count < 32)
- {
- this.soundQueue[channel].Enqueue(sample);
- }
- }
- }
-}
diff --git a/attic/GarboDev/ThumbCore.cs b/attic/GarboDev/ThumbCore.cs
deleted file mode 100644
index ca17f233c2..0000000000
--- a/attic/GarboDev/ThumbCore.cs
+++ /dev/null
@@ -1,981 +0,0 @@
-//#define ARM_DEBUG
-
-namespace GarboDev
-{
- using System;
- using System.Collections.Generic;
- using System.Text;
-
- public class ThumbCore
- {
- private const int COND_EQ = 0; // Z set
- private const int COND_NE = 1; // Z clear
- private const int COND_CS = 2; // C set
- private const int COND_CC = 3; // C clear
- private const int COND_MI = 4; // N set
- private const int COND_PL = 5; // N clear
- private const int COND_VS = 6; // V set
- private const int COND_VC = 7; // V clear
- private const int COND_HI = 8; // C set and Z clear
- private const int COND_LS = 9; // C clear or Z set
- private const int COND_GE = 10; // N equals V
- private const int COND_LT = 11; // N not equal to V
- private const int COND_GT = 12; // Z clear AND (N equals V)
- private const int COND_LE = 13; // Z set OR (N not equal to V)
- private const int COND_AL = 14; // Always
- private const int COND_NV = 15; // Never execute
-
- private const int OP_AND = 0x0;
- private const int OP_EOR = 0x1;
- private const int OP_LSL = 0x2;
- private const int OP_LSR = 0x3;
- private const int OP_ASR = 0x4;
- private const int OP_ADC = 0x5;
- private const int OP_SBC = 0x6;
- private const int OP_ROR = 0x7;
- private const int OP_TST = 0x8;
- private const int OP_NEG = 0x9;
- private const int OP_CMP = 0xA;
- private const int OP_CMN = 0xB;
- private const int OP_ORR = 0xC;
- private const int OP_MUL = 0xD;
- private const int OP_BIC = 0xE;
- private const int OP_MVN = 0xF;
-
- private Arm7Processor parent;
- private Memory memory;
- private uint[] registers;
-
- // CPU flags
- private uint zero, carry, negative, overflow;
- private ushort curInstruction, instructionQueue;
-
- private delegate void ExecuteInstruction();
- private ExecuteInstruction[] NormalOps = null;
-
- public ThumbCore(Arm7Processor parent, Memory memory)
- {
- this.parent = parent;
- this.memory = memory;
- this.registers = this.parent.Registers;
-
- this.NormalOps = new ExecuteInstruction[256]
- {
- OpLslImm, OpLslImm, OpLslImm, OpLslImm, OpLslImm, OpLslImm, OpLslImm, OpLslImm,
- OpLsrImm, OpLsrImm, OpLsrImm, OpLsrImm, OpLsrImm, OpLsrImm, OpLsrImm, OpLsrImm,
- OpAsrImm, OpAsrImm, OpAsrImm, OpAsrImm, OpAsrImm, OpAsrImm, OpAsrImm, OpAsrImm,
- OpAddRegReg, OpAddRegReg, OpSubRegReg, OpSubRegReg, OpAddRegImm, OpAddRegImm, OpSubRegImm, OpSubRegImm,
- OpMovImm, OpMovImm, OpMovImm, OpMovImm, OpMovImm, OpMovImm, OpMovImm, OpMovImm,
- OpCmpImm, OpCmpImm, OpCmpImm, OpCmpImm, OpCmpImm, OpCmpImm, OpCmpImm, OpCmpImm,
- OpAddImm, OpAddImm, OpAddImm, OpAddImm, OpAddImm, OpAddImm, OpAddImm, OpAddImm,
- OpSubImm, OpSubImm, OpSubImm, OpSubImm, OpSubImm, OpSubImm, OpSubImm, OpSubImm,
- OpArith, OpArith, OpArith, OpArith, OpAddHi, OpCmpHi, OpMovHi, OpBx,
- OpLdrPc, OpLdrPc, OpLdrPc, OpLdrPc, OpLdrPc, OpLdrPc, OpLdrPc, OpLdrPc,
- OpStrReg, OpStrReg, OpStrhReg, OpStrhReg, OpStrbReg, OpStrbReg, OpLdrsbReg, OpLdrsbReg,
- OpLdrReg, OpLdrReg, OpLdrhReg, OpLdrhReg, OpLdrbReg, OpLdrbReg, OpLdrshReg, OpLdrshReg,
- OpStrImm, OpStrImm, OpStrImm, OpStrImm, OpStrImm, OpStrImm, OpStrImm, OpStrImm,
- OpLdrImm, OpLdrImm, OpLdrImm, OpLdrImm, OpLdrImm, OpLdrImm, OpLdrImm, OpLdrImm,
- OpStrbImm, OpStrbImm, OpStrbImm, OpStrbImm, OpStrbImm, OpStrbImm, OpStrbImm, OpStrbImm,
- OpLdrbImm, OpLdrbImm, OpLdrbImm, OpLdrbImm, OpLdrbImm, OpLdrbImm, OpLdrbImm, OpLdrbImm,
- OpStrhImm, OpStrhImm, OpStrhImm, OpStrhImm, OpStrhImm, OpStrhImm, OpStrhImm, OpStrhImm,
- OpLdrhImm, OpLdrhImm, OpLdrhImm, OpLdrhImm, OpLdrhImm, OpLdrhImm, OpLdrhImm, OpLdrhImm,
- OpStrSp, OpStrSp, OpStrSp, OpStrSp, OpStrSp, OpStrSp, OpStrSp, OpStrSp,
- OpLdrSp, OpLdrSp, OpLdrSp, OpLdrSp, OpLdrSp, OpLdrSp, OpLdrSp, OpLdrSp,
- OpAddPc, OpAddPc, OpAddPc, OpAddPc, OpAddPc, OpAddPc, OpAddPc, OpAddPc,
- OpAddSp, OpAddSp, OpAddSp, OpAddSp, OpAddSp, OpAddSp, OpAddSp, OpAddSp,
- OpSubSp, OpUnd, OpUnd, OpUnd, OpPush, OpPushLr, OpUnd, OpUnd,
- OpUnd, OpUnd, OpUnd, OpUnd, OpPop, OpPopPc, OpUnd, OpUnd,
- OpStmia, OpStmia, OpStmia, OpStmia, OpStmia, OpStmia, OpStmia, OpStmia,
- OpLdmia, OpLdmia, OpLdmia, OpLdmia, OpLdmia, OpLdmia, OpLdmia, OpLdmia,
- OpBCond, OpBCond, OpBCond, OpBCond, OpBCond, OpBCond, OpBCond, OpBCond,
- OpBCond, OpBCond, OpBCond, OpBCond, OpBCond, OpBCond, OpUnd, OpSwi,
- OpB, OpB, OpB, OpB, OpB, OpB, OpB, OpB,
- OpUnd, OpUnd, OpUnd, OpUnd, OpUnd, OpUnd, OpUnd, OpUnd,
- OpBl1, OpBl1, OpBl1, OpBl1, OpBl1, OpBl1, OpBl1, OpBl1,
- OpBl2, OpBl2, OpBl2, OpBl2, OpBl2, OpBl2, OpBl2, OpBl2
- };
- }
-
- public void BeginExecution()
- {
- this.FlushQueue();
- }
-
- public void Step()
- {
- this.UnpackFlags();
-
- this.curInstruction = this.instructionQueue;
- this.instructionQueue = this.memory.ReadU16(registers[15]);
- registers[15] += 2;
-
- // Execute the instruction
- this.NormalOps[this.curInstruction >> 8]();
-
- this.parent.Cycles -= this.memory.WaitCycles;
-
- if ((this.parent.CPSR & Arm7Processor.T_MASK) != Arm7Processor.T_MASK)
- {
- if ((this.curInstruction >> 8) != 0xDF) this.parent.ReloadQueue();
- }
-
- this.PackFlags();
- }
-
- public void Execute()
- {
- this.UnpackFlags();
-
- while (this.parent.Cycles > 0)
- {
- this.curInstruction = this.instructionQueue;
- this.instructionQueue = this.memory.ReadU16(registers[15]);
- registers[15] += 2;
-
- // Execute the instruction
- this.NormalOps[this.curInstruction >> 8]();
-
- this.parent.Cycles -= this.memory.WaitCycles;
-
- if ((this.parent.CPSR & Arm7Processor.T_MASK) != Arm7Processor.T_MASK)
- {
- if ((this.curInstruction >> 8) != 0xDF) this.parent.ReloadQueue();
- break;
- }
-
- // Check the current PC
-#if ARM_DEBUG
- if (this.parent.Breakpoints.ContainsKey(registers[15] - 2U))
- {
- this.parent.BreakpointHit = true;
- break;
- }
-#endif
- }
-
- this.PackFlags();
- }
-
- #region Flag helpers
- public void OverflowCarryAdd(uint a, uint b, uint r)
- {
- overflow = ((a & b & ~r) | (~a & ~b & r)) >> 31;
- carry = ((a & b) | (a & ~r) | (b & ~r)) >> 31;
- }
-
- public void OverflowCarrySub(uint a, uint b, uint r)
- {
- overflow = ((a & ~b & ~r) | (~a & b & r)) >> 31;
- carry = ((a & ~b) | (a & ~r) | (~b & ~r)) >> 31;
- }
- #endregion
-
- #region Opcodes
- private void OpLslImm()
- {
- // 0x00 - 0x07
- // lsl rd, rm, #immed
- int rd = this.curInstruction & 0x7;
- int rm = (this.curInstruction >> 3) & 0x7;
- int immed = (this.curInstruction >> 6) & 0x1F;
-
- if (immed == 0)
- {
- registers[rd] = registers[rm];
- } else
- {
- carry = (registers[rm] >> (32 - immed)) & 0x1;
- registers[rd] = registers[rm] << immed;
- }
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- }
-
- private void OpLsrImm()
- {
- // 0x08 - 0x0F
- // lsr rd, rm, #immed
- int rd = this.curInstruction & 0x7;
- int rm = (this.curInstruction >> 3) & 0x7;
- int immed = (this.curInstruction >> 6) & 0x1F;
-
- if (immed == 0)
- {
- carry = registers[rm] >> 31;
- registers[rd] = 0;
- }
- else
- {
- carry = (registers[rm] >> (immed - 1)) & 0x1;
- registers[rd] = registers[rm] >> immed;
- }
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- }
-
- private void OpAsrImm()
- {
- // asr rd, rm, #immed
- int rd = this.curInstruction & 0x7;
- int rm = (this.curInstruction >> 3) & 0x7;
- int immed = (this.curInstruction >> 6) & 0x1F;
-
- if (immed == 0)
- {
- carry = registers[rm] >> 31;
- if (carry == 1) registers[rd] = 0xFFFFFFFF;
- else registers[rd] = 0;
- }
- else
- {
- carry = (registers[rm] >> (immed - 1)) & 0x1;
- registers[rd] = (uint)(((int)registers[rm]) >> immed);
- }
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- }
-
- private void OpAddRegReg()
- {
- // add rd, rn, rm
- int rd = this.curInstruction & 0x7;
- int rn = (this.curInstruction >> 3) & 0x7;
- int rm = (this.curInstruction >> 6) & 0x7;
-
- uint orn = registers[rn];
- uint orm = registers[rm];
-
- registers[rd] = orn + orm;
-
- this.OverflowCarryAdd(orn, orm, registers[rd]);
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- }
-
- private void OpSubRegReg()
- {
- // sub rd, rn, rm
- int rd = this.curInstruction & 0x7;
- int rn = (this.curInstruction >> 3) & 0x7;
- int rm = (this.curInstruction >> 6) & 0x7;
-
- uint orn = registers[rn];
- uint orm = registers[rm];
-
- registers[rd] = orn - orm;
-
- this.OverflowCarrySub(orn, orm, registers[rd]);
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- }
-
- private void OpAddRegImm()
- {
- // add rd, rn, #immed
- int rd = this.curInstruction & 0x7;
- int rn = (this.curInstruction >> 3) & 0x7;
- uint immed = (uint)((this.curInstruction >> 6) & 0x7);
-
- uint orn = registers[rn];
-
- registers[rd] = orn + immed;
-
- this.OverflowCarryAdd(orn, immed, registers[rd]);
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- }
-
- private void OpSubRegImm()
- {
- // sub rd, rn, #immed
- int rd = this.curInstruction & 0x7;
- int rn = (this.curInstruction >> 3) & 0x7;
- uint immed = (uint)((this.curInstruction >> 6) & 0x7);
-
- uint orn = registers[rn];
-
- registers[rd] = orn - immed;
-
- this.OverflowCarrySub(orn, immed, registers[rd]);
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- }
-
- private void OpMovImm()
- {
- // mov rd, #immed
- int rd = (this.curInstruction >> 8) & 0x7;
-
- registers[rd] = (uint)(this.curInstruction & 0xFF);
-
- negative = 0;
- zero = registers[rd] == 0 ? 1U : 0U;
- }
-
- private void OpCmpImm()
- {
- // cmp rn, #immed
- int rn = (this.curInstruction >> 8) & 0x7;
-
- uint alu = registers[rn] - (uint)(this.curInstruction & 0xFF);
-
- this.OverflowCarrySub(registers[rn], (uint)(this.curInstruction & 0xFF), alu);
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- }
-
- private void OpAddImm()
- {
- // add rd, #immed
- int rd = (this.curInstruction >> 8) & 0x7;
-
- uint ord = registers[rd];
-
- registers[rd] += (uint)(this.curInstruction & 0xFF);
-
- this.OverflowCarryAdd(ord, (uint)(this.curInstruction & 0xFF), registers[rd]);
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- }
-
- private void OpSubImm()
- {
- // sub rd, #immed
- int rd = (this.curInstruction >> 8) & 0x7;
-
- uint ord = registers[rd];
-
- registers[rd] -= (uint)(this.curInstruction & 0xFF);
-
- this.OverflowCarrySub(ord, (uint)(this.curInstruction & 0xFF), registers[rd]);
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- }
-
- private void OpArith()
- {
- int rd = this.curInstruction & 0x7;
- uint rn = registers[(this.curInstruction >> 3) & 0x7];
-
- uint orig, alu;
- int shiftAmt;
-
- switch ((this.curInstruction >> 6) & 0xF)
- {
- case OP_ADC:
- orig = registers[rd];
- registers[rd] += rn + carry;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarryAdd(orig, rn, registers[rd]);
- break;
-
- case OP_AND:
- registers[rd] &= rn;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- break;
-
- case OP_ASR:
- shiftAmt = (int)(rn & 0xFF);
- if (shiftAmt == 0)
- {
- // Do nothing
- }
- else if (shiftAmt < 32)
- {
- carry = (registers[rd] >> (shiftAmt - 1)) & 0x1;
- registers[rd] = (uint)(((int)registers[rd]) >> shiftAmt);
- }
- else
- {
- carry = (registers[rd] >> 31) & 1;
- if (carry == 1) registers[rd] = 0xFFFFFFFF;
- else registers[rd] = 0;
- }
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- break;
-
- case OP_BIC:
- registers[rd] &= ~rn;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- break;
-
- case OP_CMN:
- alu = registers[rd] + rn;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarryAdd(registers[rd], rn, alu);
- break;
-
- case OP_CMP:
- alu = registers[rd] - rn;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarrySub(registers[rd], rn, alu);
- break;
-
- case OP_EOR:
- registers[rd] ^= rn;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- break;
-
- case OP_LSL:
- shiftAmt = (int)(rn & 0xFF);
- if (shiftAmt == 0)
- {
- // Do nothing
- }
- else if (shiftAmt < 32)
- {
- carry = (registers[rd] >> (32 - shiftAmt)) & 0x1;
- registers[rd] <<= shiftAmt;
- }
- else if (shiftAmt == 32)
- {
- carry = registers[rd] & 0x1;
- registers[rd] = 0;
- }
- else
- {
- carry = 0;
- registers[rd] = 0;
- }
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- break;
-
- case OP_LSR:
- shiftAmt = (int)(rn & 0xFF);
- if (shiftAmt == 0)
- {
- // Do nothing
- }
- else if (shiftAmt < 32)
- {
- carry = (registers[rd] >> (shiftAmt - 1)) & 0x1;
- registers[rd] >>= shiftAmt;
- }
- else if (shiftAmt == 32)
- {
- carry = (registers[rd] >> 31) & 0x1;
- registers[rd] = 0;
- }
- else
- {
- carry = 0;
- registers[rd] = 0;
- }
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- break;
-
- case OP_MUL:
- int mulCycles = 4;
- // Multiply cycle calculations
- if ((rn & 0xFFFFFF00) == 0 || (rn & 0xFFFFFF00) == 0xFFFFFF00)
- {
- mulCycles = 1;
- }
- else if ((rn & 0xFFFF0000) == 0 || (rn & 0xFFFF0000) == 0xFFFF0000)
- {
- mulCycles = 2;
- }
- else if ((rn & 0xFF000000) == 0 || (rn & 0xFF000000) == 0xFF000000)
- {
- mulCycles = 3;
- }
-
- this.parent.Cycles -= mulCycles;
-
- registers[rd] *= rn;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- break;
-
- case OP_MVN:
- registers[rd] = ~rn;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- break;
-
- case OP_NEG:
- registers[rd] = 0 - rn;
-
- this.OverflowCarrySub(0, rn, registers[rd]);
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- break;
-
- case OP_ORR:
- registers[rd] |= rn;
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- break;
-
- case OP_ROR:
- shiftAmt = (int)(rn & 0xFF);
- if (shiftAmt == 0)
- {
- // Do nothing
- }
- else if ((shiftAmt & 0x1F) == 0)
- {
- carry = registers[rd] >> 31;
- }
- else
- {
- shiftAmt &= 0x1F;
- carry = (registers[rd] >> (shiftAmt - 1)) & 0x1;
- registers[rd] = (registers[rd] >> shiftAmt) | (registers[rd] << (32 - shiftAmt));
- }
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- break;
-
- case OP_SBC:
- orig = registers[rd];
- registers[rd] = (registers[rd] - rn) - (1U - carry);
-
- negative = registers[rd] >> 31;
- zero = registers[rd] == 0 ? 1U : 0U;
- this.OverflowCarrySub(orig, rn, registers[rd]);
- break;
-
- case OP_TST:
- alu = registers[rd] & rn;
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- break;
-
- default:
- throw new Exception("The coder screwed up on the thumb alu op...");
- }
- }
-
- private void OpAddHi()
- {
- int rd = ((this.curInstruction & (1 << 7)) >> 4) | (this.curInstruction & 0x7);
- int rm = (this.curInstruction >> 3) & 0xF;
-
- registers[rd] += registers[rm];
-
- if (rd == 15)
- {
- registers[rd] &= ~1U;
- this.FlushQueue();
- }
- }
-
- private void OpCmpHi()
- {
- int rd = ((this.curInstruction & (1 << 7)) >> 4) | (this.curInstruction & 0x7);
- int rm = (this.curInstruction >> 3) & 0xF;
-
- uint alu = registers[rd] - registers[rm];
-
- negative = alu >> 31;
- zero = alu == 0 ? 1U : 0U;
- this.OverflowCarrySub(registers[rd], registers[rm], alu);
- }
-
- private void OpMovHi()
- {
- int rd = ((this.curInstruction & (1 << 7)) >> 4) | (this.curInstruction & 0x7);
- int rm = (this.curInstruction >> 3) & 0xF;
-
- registers[rd] = registers[rm];
-
- if (rd == 15)
- {
- registers[rd] &= ~1U;
- this.FlushQueue();
- }
- }
-
- private void OpBx()
- {
- int rm = (this.curInstruction >> 3) & 0xf;
-
- this.PackFlags();
-
- this.parent.CPSR &= ~Arm7Processor.T_MASK;
- this.parent.CPSR |= (registers[rm] & 1) << Arm7Processor.T_BIT;
-
- registers[15] = registers[rm] & (~1U);
-
- this.UnpackFlags();
-
- // Check for branch back to Arm Mode
- if ((this.parent.CPSR & Arm7Processor.T_MASK) != Arm7Processor.T_MASK)
- {
- return;
- }
-
- this.FlushQueue();
- }
-
- private void OpLdrPc()
- {
- int rd = (this.curInstruction >> 8) & 0x7;
-
- registers[rd] = this.memory.ReadU32((registers[15] & ~2U) + (uint)((this.curInstruction & 0xFF) * 4));
-
- this.parent.Cycles--;
- }
-
- private void OpStrReg()
- {
- this.memory.WriteU32(registers[(this.curInstruction >> 3) & 0x7] + registers[(this.curInstruction >> 6) & 0x7],
- registers[this.curInstruction & 0x7]);
- }
-
- private void OpStrhReg()
- {
- this.memory.WriteU16(registers[(this.curInstruction >> 3) & 0x7] + registers[(this.curInstruction >> 6) & 0x7],
- (ushort)(registers[this.curInstruction & 0x7] & 0xFFFF));
- }
-
- private void OpStrbReg()
- {
- this.memory.WriteU8(registers[(this.curInstruction >> 3) & 0x7] + registers[(this.curInstruction >> 6) & 0x7],
- (byte)(registers[this.curInstruction & 0x7] & 0xFF));
- }
-
- private void OpLdrsbReg()
- {
- registers[this.curInstruction & 0x7] =
- this.memory.ReadU8(registers[(this.curInstruction >> 3) & 0x7] + registers[(this.curInstruction >> 6) & 0x7]);
-
- if ((registers[this.curInstruction & 0x7] & (1 << 7)) != 0)
- {
- registers[this.curInstruction & 0x7] |= 0xFFFFFF00;
- }
-
- this.parent.Cycles--;
- }
-
- private void OpLdrReg()
- {
- registers[this.curInstruction & 0x7] =
- this.memory.ReadU32(registers[(this.curInstruction >> 3) & 0x7] + registers[(this.curInstruction >> 6) & 0x7]);
-
- this.parent.Cycles--;
- }
-
- private void OpLdrhReg()
- {
- registers[this.curInstruction & 0x7] =
- this.memory.ReadU16(registers[(this.curInstruction >> 3) & 0x7] + registers[(this.curInstruction >> 6) & 0x7]);
-
- this.parent.Cycles--;
- }
-
- private void OpLdrbReg()
- {
- registers[this.curInstruction & 0x7] =
- this.memory.ReadU8(registers[(this.curInstruction >> 3) & 0x7] + registers[(this.curInstruction >> 6) & 0x7]);
-
- this.parent.Cycles--;
- }
-
- private void OpLdrshReg()
- {
- registers[this.curInstruction & 0x7] =
- this.memory.ReadU16(registers[(this.curInstruction >> 3) & 0x7] + registers[(this.curInstruction >> 6) & 0x7]);
-
- if ((registers[this.curInstruction & 0x7] & (1 << 15)) != 0)
- {
- registers[this.curInstruction & 0x7] |= 0xFFFF0000;
- }
-
- this.parent.Cycles--;
- }
-
- private void OpStrImm()
- {
- this.memory.WriteU32(registers[(this.curInstruction >> 3) & 0x7] + (uint)(((this.curInstruction >> 6) & 0x1F) * 4),
- registers[this.curInstruction & 0x7]);
- }
-
- private void OpLdrImm()
- {
- registers[this.curInstruction & 0x7] =
- this.memory.ReadU32(registers[(this.curInstruction >> 3) & 0x7] + (uint)(((this.curInstruction >> 6) & 0x1F) * 4));
-
- this.parent.Cycles--;
- }
-
- private void OpStrbImm()
- {
- this.memory.WriteU8(registers[(this.curInstruction >> 3) & 0x7] + (uint)((this.curInstruction >> 6) & 0x1F),
- (byte)(registers[this.curInstruction & 0x7] & 0xFF));
- }
-
- private void OpLdrbImm()
- {
- registers[this.curInstruction & 0x7] =
- this.memory.ReadU8(registers[(this.curInstruction >> 3) & 0x7] + (uint)((this.curInstruction >> 6) & 0x1F));
-
- this.parent.Cycles--;
- }
-
- private void OpStrhImm()
- {
- this.memory.WriteU16(registers[(this.curInstruction >> 3) & 0x7] + (uint)(((this.curInstruction >> 6) & 0x1F) * 2),
- (ushort)(registers[this.curInstruction & 0x7] & 0xFFFF));
- }
-
- private void OpLdrhImm()
- {
- registers[this.curInstruction & 0x7] =
- this.memory.ReadU16(registers[(this.curInstruction >> 3) & 0x7] + (uint)(((this.curInstruction >> 6) & 0x1F) * 2));
-
- this.parent.Cycles--;
- }
-
- private void OpStrSp()
- {
- this.memory.WriteU32(registers[13] + (uint)((this.curInstruction & 0xFF) * 4),
- registers[(this.curInstruction >> 8) & 0x7]);
- }
-
- private void OpLdrSp()
- {
- registers[(this.curInstruction >> 8) & 0x7] =
- this.memory.ReadU32(registers[13] + (uint)((this.curInstruction & 0xFF) * 4));
- }
-
- private void OpAddPc()
- {
- registers[(this.curInstruction >> 8) & 0x7] =
- (registers[15] & ~2U) + (uint)((this.curInstruction & 0xFF) * 4);
- }
-
- private void OpAddSp()
- {
- registers[(this.curInstruction >> 8) & 0x7] =
- registers[13] + (uint)((this.curInstruction & 0xFF) * 4);
- }
-
- private void OpSubSp()
- {
- if ((this.curInstruction & (1 << 7)) != 0)
- registers[13] -= (uint)((this.curInstruction & 0x7F) * 4);
- else
- registers[13] += (uint)((this.curInstruction & 0x7F) * 4);
- }
-
- private void OpPush()
- {
- for (int i = 7; i >= 0; i--)
- {
- if (((this.curInstruction >> i) & 1) != 0)
- {
- registers[13] -= 4;
- this.memory.WriteU32(registers[13], registers[i]);
- }
- }
- }
-
- private void OpPushLr()
- {
- registers[13] -= 4;
- this.memory.WriteU32(registers[13], registers[14]);
-
- for (int i = 7; i >= 0; i--)
- {
- if (((this.curInstruction >> i) & 1) != 0)
- {
- registers[13] -= 4;
- this.memory.WriteU32(registers[13], registers[i]);
- }
- }
- }
-
- private void OpPop()
- {
- for (int i = 0; i < 8; i++)
- {
- if (((this.curInstruction >> i) & 1) != 0)
- {
- registers[i] = this.memory.ReadU32(registers[13]);
- registers[13] += 4;
- }
- }
-
- this.parent.Cycles--;
- }
-
- private void OpPopPc()
- {
- for (int i = 0; i < 8; i++)
- {
- if (((this.curInstruction >> i) & 1) != 0)
- {
- registers[i] = this.memory.ReadU32(registers[13]);
- registers[13] += 4;
- }
- }
-
- registers[15] = this.memory.ReadU32(registers[13]) & (~1U);
- registers[13] += 4;
-
- // ARM9 check here
-
- this.FlushQueue();
-
- this.parent.Cycles--;
- }
-
- private void OpStmia()
- {
- int rn = (this.curInstruction >> 8) & 0x7;
-
- for (int i = 0; i < 8; i++)
- {
- if (((this.curInstruction >> i) & 1) != 0)
- {
- this.memory.WriteU32(registers[rn] & (~3U), registers[i]);
- registers[rn] += 4;
- }
- }
- }
-
- private void OpLdmia()
- {
- int rn = (this.curInstruction >> 8) & 0x7;
-
- uint address = registers[rn];
-
- for (int i = 0; i < 8; i++)
- {
- if (((this.curInstruction >> i) & 1) != 0)
- {
- registers[i] = this.memory.ReadU32Aligned(address & (~3U));
- address += 4;
- }
- }
-
- if (((this.curInstruction >> rn) & 1) == 0)
- {
- registers[rn] = address;
- }
- }
-
- private void OpBCond()
- {
- uint cond = 0;
- switch ((this.curInstruction >> 8) & 0xF)
- {
- case COND_AL: cond = 1; break;
- case COND_EQ: cond = zero; break;
- case COND_NE: cond = 1 - zero; break;
- case COND_CS: cond = carry; break;
- case COND_CC: cond = 1 - carry; break;
- case COND_MI: cond = negative; break;
- case COND_PL: cond = 1 - negative; break;
- case COND_VS: cond = overflow; break;
- case COND_VC: cond = 1 - overflow; break;
- case COND_HI: cond = carry & (1 - zero); break;
- case COND_LS: cond = (1 - carry) | zero; break;
- case COND_GE: cond = (1 - negative) ^ overflow; break;
- case COND_LT: cond = negative ^ overflow; break;
- case COND_GT: cond = (1 - zero) & (negative ^ (1 - overflow)); break;
- case COND_LE: cond = (negative ^ overflow) | zero; break;
- }
-
- if (cond == 1)
- {
- uint offset = (uint)(this.curInstruction & 0xFF);
- if ((offset & (1 << 7)) != 0) offset |= 0xFFFFFF00;
-
- registers[15] += offset << 1;
-
- this.FlushQueue();
- }
- }
-
- private void OpSwi()
- {
- registers[15] -= 4U;
- this.parent.EnterException(Arm7Processor.SVC, 0x8, false, false);
- }
-
- private void OpB()
- {
- uint offset = (uint)(this.curInstruction & 0x7FF);
- if ((offset & (1 << 10)) != 0) offset |= 0xFFFFF800;
-
- registers[15] += offset << 1;
-
- this.FlushQueue();
- }
-
- private void OpBl1()
- {
- uint offset = (uint)(this.curInstruction & 0x7FF);
- if ((offset & (1 << 10)) != 0) offset |= 0xFFFFF800;
-
- registers[14] = registers[15] + (offset << 12);
- }
-
- private void OpBl2()
- {
- uint tmp = registers[15];
- registers[15] = registers[14] + (uint)((this.curInstruction & 0x7FF) << 1);
- registers[14] = (tmp - 2U) | 1;
-
- this.FlushQueue();
- }
-
- private void OpUnd()
- {
- throw new Exception("Unknown opcode");
- }
- #endregion
-
- private void PackFlags()
- {
- this.parent.CPSR &= 0x0FFFFFFF;
- this.parent.CPSR |= this.negative << Arm7Processor.N_BIT;
- this.parent.CPSR |= this.zero << Arm7Processor.Z_BIT;
- this.parent.CPSR |= this.carry << Arm7Processor.C_BIT;
- this.parent.CPSR |= this.overflow << Arm7Processor.V_BIT;
- }
-
- private void UnpackFlags()
- {
- this.negative = (this.parent.CPSR >> Arm7Processor.N_BIT) & 1;
- this.zero = (this.parent.CPSR >> Arm7Processor.Z_BIT) & 1;
- this.carry = (this.parent.CPSR >> Arm7Processor.C_BIT) & 1;
- this.overflow = (this.parent.CPSR >> Arm7Processor.V_BIT) & 1;
- }
-
- private void FlushQueue()
- {
- this.instructionQueue = this.memory.ReadU16(registers[15]);
- registers[15] += 2;
- }
- }
-}
diff --git a/attic/GarboDev/VideoManager.cs b/attic/GarboDev/VideoManager.cs
deleted file mode 100644
index 328702d8fa..0000000000
--- a/attic/GarboDev/VideoManager.cs
+++ /dev/null
@@ -1,164 +0,0 @@
-namespace GarboDev
-{
- public class VideoManager
- {
- public delegate void OnPresent(uint[] data);
-
- private Memory memory = null;
- private IRenderer renderer = null;
- private OnPresent presenter;
- private GbaManager gbaManager;
- private int curLine;
-
- public Memory Memory
- {
- set{ this.memory = value; }
- }
-
- public IRenderer Renderer
- {
- set
- {
- this.renderer = value;
- this.renderer.Memory = this.memory;
- }
- }
-
- public OnPresent Presenter
- {
- set { this.presenter = value; }
- }
-
- public VideoManager(GbaManager gbaManager)
- {
- this.gbaManager = gbaManager;
- }
-
- public void Reset()
- {
- this.curLine = 0;
-
- this.renderer.Memory = memory;
- this.renderer.Reset();
- }
-
- private void EnterVBlank(Arm7Processor processor)
- {
- ushort dispstat = Memory.ReadU16(this.memory.IORam, Memory.DISPSTAT);
- dispstat |= 1;
- Memory.WriteU16(this.memory.IORam, Memory.DISPSTAT, dispstat);
-
- // Render the frame
- this.gbaManager.FramesRendered++;
- this.presenter(this.renderer.ShowFrame());
-
- if ((dispstat & (1 << 3)) != 0)
- {
- // Fire the vblank irq
- processor.RequestIrq(0);
- }
-
- // Check for DMA triggers
- this.memory.VBlankDma();
- }
-
- private void LeaveVBlank(Arm7Processor processor)
- {
- ushort dispstat = Memory.ReadU16(this.memory.IORam, Memory.DISPSTAT);
- dispstat &= 0xFFFE;
- Memory.WriteU16(this.memory.IORam, Memory.DISPSTAT, dispstat);
-
- processor.UpdateKeyState();
-
- // Update the rot/scale values
- this.memory.Bgx[0] = (int)Memory.ReadU32(this.memory.IORam, Memory.BG2X_L);
- this.memory.Bgx[1] = (int)Memory.ReadU32(this.memory.IORam, Memory.BG3X_L);
- this.memory.Bgy[0] = (int)Memory.ReadU32(this.memory.IORam, Memory.BG2Y_L);
- this.memory.Bgy[1] = (int)Memory.ReadU32(this.memory.IORam, Memory.BG3Y_L);
- }
-
- public void EnterHBlank(Arm7Processor processor)
- {
- ushort dispstat = Memory.ReadU16(this.memory.IORam, Memory.DISPSTAT);
- dispstat |= 1 << 1;
- Memory.WriteU16(this.memory.IORam, Memory.DISPSTAT, dispstat);
-
- // Advance the bgx registers
- for (int bg = 0; bg <= 1; bg++)
- {
- short dmx = (short)Memory.ReadU16(this.memory.IORam, Memory.BG2PB + (uint)bg * 0x10);
- short dmy = (short)Memory.ReadU16(this.memory.IORam, Memory.BG2PD + (uint)bg * 0x10);
- this.memory.Bgx[bg] += dmx;
- this.memory.Bgy[bg] += dmy;
- }
-
- if (this.curLine < 160)
- {
- this.memory.HBlankDma();
-
- // Trigger hblank irq
- if ((dispstat & (1 << 4)) != 0)
- {
- processor.RequestIrq(1);
- }
- }
- }
-
- ///
- ///
- ///
- ///
- /// true if end of frame
- public bool LeaveHBlank(Arm7Processor processor)
- {
- bool ret = false;
- ushort dispstat = Memory.ReadU16(this.memory.IORam, Memory.DISPSTAT);
- dispstat &= 0xFFF9;
- Memory.WriteU16(this.memory.IORam, Memory.DISPSTAT, dispstat);
-
- // Move to the next line
- this.curLine++;
-
- if (this.curLine >= 228)
- {
- // Start again at the beginning
- this.curLine = 0;
- }
-
- // Update registers
- Memory.WriteU16(this.memory.IORam, Memory.VCOUNT, (ushort)this.curLine);
-
- // Check for vblank
- if (this.curLine == 160)
- {
- this.EnterVBlank(processor);
- ret = true;
- }
- else if (this.curLine == 0)
- {
- this.LeaveVBlank(processor);
- }
-
- // Check y-line trigger
- if (((dispstat >> 8) & 0xff) == this.curLine)
- {
- dispstat = (ushort)(Memory.ReadU16(this.memory.IORam, Memory.DISPSTAT) | (1 << 2));
- Memory.WriteU16(this.memory.IORam, Memory.DISPSTAT, dispstat);
-
- if ((dispstat & (1 << 5)) != 0)
- {
- processor.RequestIrq(2);
- }
- }
- return ret;
- }
-
- public void RenderLine()
- {
- if (this.curLine < 160)
- {
- this.renderer.RenderLine(this.curLine);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/attic/GarboDev/readme.txt b/attic/GarboDev/readme.txt
deleted file mode 100644
index 9aec52234e..0000000000
--- a/attic/GarboDev/readme.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-garbodev with a quick iemulator binding. license uncertain.
-
-basic functionality works (gets ingame on a number of commercial titles).
-
-no GB classic sound channels.
-no savestates.
-lots of things not hooked up (saveram, etc)
diff --git a/libmeteor/Makefile b/libmeteor/Makefile
deleted file mode 100644
index 2029f11b3d..0000000000
--- a/libmeteor/Makefile
+++ /dev/null
@@ -1,110 +0,0 @@
-# this was modified at one point so that it would compile in our bizhawk project, but isn't in
-# use at the moment. tread carefully
-
-ifeq ($(platform),)
-platform = unix
-ifeq ($(shell uname -a),)
- platform = win
-else ifneq ($(findstring MINGW,$(shell uname -a)),)
- platform = win
-else ifneq ($(findstring Darwin,$(shell uname -a)),)
- platform = osx
-else ifneq ($(findstring win,$(shell uname -a)),)
- platform = win
-endif
-endif
-
-ifeq ($(platform), unix)
- TARGET := libmeteor.so
- fpic := -fPIC
- SHARED := -shared -Wl,--version-script=link.T -Wl,--no-undefined
-else ifeq ($(platform), osx)
- TARGET := libmeteor.dylib
- fpic := -fPIC
- SHARED := -dynamiclib
-else
- TARGET := libmeteor.dll
- CXX = g++
-# SHARED := -shared -static-libgcc -static-libstdc++ -s -Wl,--version-script=link.T -Wl,--no-undefined
- SHARED := -shared -static-libgcc -static-libstdc++ -s -Wl,--no-undefined
- CXXFLAGS += -DNO_MEMMEM
-endif
-
-#__LIBRETRO__ enables a slightly different saveram mechanism that doesn't seem to serve any useful purpose?
-#CXXFLAGS += -Wall -pedantic -I. -I../ameteor/include -pipe -D__LIBRETRO__ -Wno-parentheses -fno-exceptions -fno-rtti
-CXXFLAGS += -Wall -pedantic -I. -Iinclude -pipe -DX86_ASM -Wno-parentheses -fno-exceptions -fno-rtti
-
-ifeq ($(DEBUG), 1)
- CFLAGS += -O0 -g
- CXXFLAGS += -O0 -g
-else
- CFLAGS += -O3
- CXXFLAGS += -O3
-endif
-
-#SRCDIR := ../ameteor/source
-SRCDIR := ./source
-
-SOURCES := \
- $(SRCDIR)/audio/dsound.cpp \
- $(SRCDIR)/audio/sound1.cpp \
- $(SRCDIR)/audio/sound2.cpp \
- $(SRCDIR)/audio/sound4.cpp \
- $(SRCDIR)/audio/speaker.cpp \
- $(SRCDIR)/disassembler/argimmediate.cpp \
- $(SRCDIR)/disassembler/argmulregisters.cpp \
- $(SRCDIR)/disassembler/argpsr.cpp \
- $(SRCDIR)/disassembler/argregister.cpp \
- $(SRCDIR)/disassembler/argrelative.cpp \
- $(SRCDIR)/disassembler/argshift.cpp \
- $(SRCDIR)/disassembler/arguimmediate.cpp \
- $(SRCDIR)/disassembler/arguments.cpp \
- $(SRCDIR)/disassembler/instruction.cpp \
- $(SRCDIR)/graphics/bglayer.cpp \
- $(SRCDIR)/graphics/object.cpp \
- $(SRCDIR)/graphics/objects.cpp \
- $(SRCDIR)/graphics/renderer.cpp \
- $(SRCDIR)/graphics/screen.cpp \
- $(SRCDIR)/ameteor.cpp \
- $(SRCDIR)/bios.cpp \
- $(SRCDIR)/clock.cpp \
- $(SRCDIR)/cpu.cpp \
- $(SRCDIR)/debug.cpp \
- $(SRCDIR)/dma.cpp \
- $(SRCDIR)/eeprom.cpp \
- $(SRCDIR)/flash.cpp \
- $(SRCDIR)/cartmem.cpp \
- $(SRCDIR)/interpreter.cpp \
- $(SRCDIR)/interpreter_arm.cpp \
- $(SRCDIR)/interpreter_thumb.cpp \
- $(SRCDIR)/io.cpp \
- $(SRCDIR)/keypad.cpp \
- $(SRCDIR)/lcd.cpp \
- $(SRCDIR)/memory.cpp \
- $(SRCDIR)/sound.cpp \
- $(SRCDIR)/sram.cpp \
- $(SRCDIR)/timer.cpp \
- cinterface.cpp
-# video.cpp \
-# audio.cpp \
-# input.cpp \
-# libretro.cpp
-
-OBJ := $(SOURCES:.cpp=.o)
-
-all: $(TARGET)
-
-$(TARGET): $(OBJ)
- @$(CXX) -o $@ $^ $(SHARED) $(LDFLAGS) $(LIBS)
- @echo LD $(notdir $@)
-
-%.o: %.cpp
- @$(CXX) -o $@ -c $< $(CXXFLAGS) $(fpic)
- @echo CXX $(notdir $<)
-
-clean:
- rm -f $(TARGET)
- rm -f $(OBJ)
-
-.PHONY: clean
-
diff --git a/libmeteor/cinterface.cpp b/libmeteor/cinterface.cpp
deleted file mode 100644
index 7ec62ef343..0000000000
--- a/libmeteor/cinterface.cpp
+++ /dev/null
@@ -1,246 +0,0 @@
-#include "ameteor.hpp"
-#include "ameteor/cartmem.hpp"
-#include "source/debug.hpp"
-#include
-
-#define EXPORT extern "C" __declspec(dllexport)
-
-void (*messagecallback)(const char *msg, int abort) = NULL;
-
-EXPORT void libmeteor_setmessagecallback(void (*callback)(const char *msg, int abort))
-{
- messagecallback = callback;
- print_bizhawk("libmeteor message stream operational.");
-}
-
-void print_bizhawk(const char *msg)
-{
- if (messagecallback)
- messagecallback(msg, 0);
-}
-void print_bizhawk(std::string &msg)
-{
- if (messagecallback)
- messagecallback(msg.c_str(), 0);
-}
-void abort_bizhawk(const char *msg)
-{
- if (messagecallback)
- messagecallback(msg, 1);
- AMeteor::Stop(); // makes it easy to pick apart what happened
-}
-
-uint16_t (*keycallback)() = NULL;
-
-void keyupdate_bizhawk()
-{
- if (keycallback)
- AMeteor::_keypad.SetPadState(keycallback() ^ 0x3FF);
-}
-
-EXPORT void libmeteor_setkeycallback(uint16_t (*callback)())
-{
- keycallback = callback;
-}
-
-bool traceenabled = false;
-void (*tracecallback)(const char *msg) = NULL;
-
-EXPORT void libmeteor_settracecallback(void (*callback)(const char*msg))
-{
- tracecallback = callback;
- traceenabled = tracecallback != NULL;
-}
-
-void trace_bizhawk(std::string msg)
-{
- if (tracecallback)
- tracecallback(msg.c_str());
-}
-
-EXPORT void libmeteor_hardreset()
-{
- AMeteor::Reset(AMeteor::UNIT_ALL ^ (AMeteor::UNIT_MEMORY_BIOS | AMeteor::UNIT_MEMORY_ROM));
-}
-
-uint32_t *videobuff;
-
-void videocb(const uint16_t *frame)
-{
- uint32_t *dest = videobuff;
- const uint16_t *src = frame;
- for (int i = 0; i < 240 * 160; i++, src++, dest++)
- {
- uint16_t c = *src;
- uint16_t b = c >> 10 & 31;
- uint16_t g = c >> 5 & 31;
- uint16_t r = c & 31;
- b = b << 3 | b >> 2;
- g = g << 3 | g >> 2;
- r = r << 3 | r >> 2;
- *dest = b | g << 8 | r << 16 | 0xff000000;
- }
- AMeteor::Stop(); // to the end of frame only
-}
-
-int16_t *soundbuff;
-int16_t *soundbuffcur;
-int16_t *soundbuffend;
-
-void soundcb(const int16_t *samples)
-{
- if (soundbuffcur < soundbuffend)
- {
- *soundbuffcur++ = *samples++;
- *soundbuffcur++ = *samples++;
- }
-}
-
-EXPORT unsigned libmeteor_emptysound()
-{
- unsigned ret = (soundbuffcur - soundbuff) * sizeof(int16_t);
- soundbuffcur = soundbuff;
- return ret;
-}
-
-EXPORT int libmeteor_setbuffers(uint32_t *vid, unsigned vidlen, int16_t *aud, unsigned audlen)
-{
- if (vidlen < 240 * 160 * sizeof(uint32_t))
- return 0;
- if (audlen < 4 || audlen % 4 != 0)
- return 0;
- videobuff = vid;
- soundbuff = aud;
- soundbuffend = soundbuff + audlen / sizeof(int16_t);
- libmeteor_emptysound();
- return 1;
-}
-
-EXPORT void libmeteor_init()
-{
- static bool first = true;
- if (first)
- {
- AMeteor::_lcd.GetScreen().GetRenderer().SetFrameSlot(syg::ptr_fun(videocb));
- AMeteor::_sound.GetSpeaker().SetFrameSlot(syg::ptr_fun(soundcb));
- first = false;
- }
-}
-
-EXPORT void libmeteor_frameadvance()
-{
- AMeteor::Run(10000000);
-}
-
-EXPORT void libmeteor_loadrom(const void *data, unsigned size)
-{
- AMeteor::_memory.LoadRom((const uint8_t*)data, size);
-}
-
-EXPORT void libmeteor_loadbios(const void *data, unsigned size)
-{
- AMeteor::_memory.LoadBios((const uint8_t*)data, size);
-}
-
-EXPORT uint8_t *libmeteor_getmemoryarea(int which)
-{
- if (which < 7)
- return AMeteor::_memory.GetMemoryArea(which);
- else if (which == 7)
- return AMeteor::_io.GetIoPointer();
- else
- return NULL;
-}
-
-EXPORT int libmeteor_loadsaveram(const void *data, unsigned size)
-{
- return AMeteor::_memory.LoadCart((const uint8_t*)data, size);
-}
-
-EXPORT int libmeteor_savesaveram(void **data, unsigned *size)
-{
- return AMeteor::_memory.SaveCart((uint8_t **)data, size);
-}
-
-EXPORT void libmeteor_savesaveram_destroy(void *data)
-{
- AMeteor::_memory.SaveCartDestroy((uint8_t *)data);
-}
-
-EXPORT int libmeteor_hassaveram()
-{
- return AMeteor::_memory.HasCart();
-}
-
-EXPORT void libmeteor_clearsaveram()
-{
- AMeteor::_memory.DeleteCart();
-}
-
-EXPORT int libmeteor_savestate(void **data, unsigned *size)
-{
- if (!data || !size)
- return 0;
-
- std::ostringstream ss = std::ostringstream(std::ios_base::binary);
- AMeteor::SaveState(ss);
-
- std::string s = ss.str();
-
- void *ret = std::malloc(s.size());
- if (!ret)
- return 0;
- std::memcpy(ret, s.data(), s.size());
- *data = ret;
- *size = s.size();
- return 1;
-}
-
-EXPORT void libmeteor_savestate_destroy(void *data)
-{
- std::free(data);
-}
-
-EXPORT int libmeteor_loadstate(const void *data, unsigned size)
-{
- std::istringstream ss = std::istringstream(std::string((const char*)data, size), std::ios_base::binary);
- return AMeteor::LoadState(ss);
-}
-
-// TODO: cartram memory domain, cartram in system bus memory domain
-EXPORT uint8_t libmeteor_peekbus(uint32_t addr)
-{
- return AMeteor::_memory.Peek8(addr);
-}
-
-EXPORT void libmeteor_writebus(uint32_t addr, uint8_t val)
-{
- AMeteor::_memory.Write8(addr, val);
-}
-
-int slcallbackline = 400;
-void (*slcallback)() = NULL;
-
-EXPORT void libmeteor_setscanlinecallback(void (*callback)(), int scanline)
-{
- if (!callback)
- slcallbackline = 400;
- else
- slcallbackline = scanline;
- slcallback = callback;
-}
-
-void scanlinecallback_bizhawk()
-{
- if (slcallback)
- slcallback();
-}
-
-EXPORT void libmeteor_getregs(int *dest)
-{
- AMeteor::_cpu.UpdateCpsr();
- for (int i = 0; i < 16; i++)
- dest[i] = AMeteor::_cpu.Reg(i);
- dest[16] = AMeteor::_cpu.Cpsr().dw;
- dest[17] = AMeteor::_cpu.Spsr().dw;
-}
diff --git a/libmeteor/include/ameteor.hpp b/libmeteor/include/ameteor.hpp
deleted file mode 100644
index 27dafb1fd8..0000000000
--- a/libmeteor/include/ameteor.hpp
+++ /dev/null
@@ -1,80 +0,0 @@
-// Meteor - A Nintendo Gameboy Advance emulator
-// Copyright (C) 2009-2011 Philippe Daouadi
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see .
-
-#ifndef __AMETEOR_H__
-#define __AMETEOR_H__
-
-#include "ameteor/memory.hpp"
-#include "ameteor/io.hpp"
-#include "ameteor/dma.hpp"
-#include "ameteor/interpreter.hpp"
-#include "ameteor/lcd.hpp"
-#include "ameteor/clock.hpp"
-#include "ameteor/timer.hpp"
-#include "ameteor/sound.hpp"
-#include "ameteor/keypad.hpp"
-
-namespace AMeteor
-{
- extern Clock _clock;
- extern Io _io;
- extern Interpreter _cpu;
- extern Memory _memory;
- extern Dma _dma;
- extern Lcd _lcd;
- extern Sound _sound;
- extern Keypad _keypad;
- extern Timer _timer0;
- extern Timer _timer1;
- extern Timer _timer2;
- extern Timer _timer3;
-
- const uint32_t UNIT_CLOCK = 0x0001;
- const uint32_t UNIT_IO = 0x0002;
- const uint32_t UNIT_CPU = 0x0004;
- const uint32_t UNIT_MEMORY = 0x0008;
- const uint32_t UNIT_DMA = 0x0010;
- const uint32_t UNIT_LCD = 0x0020;
- const uint32_t UNIT_SOUND = 0x0040;
- const uint32_t UNIT_KEYPAD = 0x0080;
- const uint32_t UNIT_TIMER0 = 0x0100;
- const uint32_t UNIT_TIMER1 = 0x0200;
- const uint32_t UNIT_TIMER2 = 0x0400;
- const uint32_t UNIT_TIMER3 = 0x0800;
- const uint32_t UNIT_MEMORY_ROM = 0x1000;
- const uint32_t UNIT_MEMORY_BIOS = 0x2000;
- const uint32_t UNIT_ALL = 0x3FFF;
-
- void Reset (uint32_t units);
-
- bool SaveState (const char* filename);
- bool LoadState (const char* filename);
-
- bool SaveState (std::ostream& stream);
- bool LoadState (std::istream& stream);
-
- inline void Run (unsigned int cycles)
- {
- _cpu.Run(cycles);
- }
-
- inline void Stop ()
- {
- _cpu.Stop();
- }
-}
-
-#endif
diff --git a/libmeteor/include/ameteor/audio/dsound.hpp b/libmeteor/include/ameteor/audio/dsound.hpp
deleted file mode 100644
index 85dc320b13..0000000000
--- a/libmeteor/include/ameteor/audio/dsound.hpp
+++ /dev/null
@@ -1,78 +0,0 @@
-// Meteor - A Nintendo Gameboy Advance emulator
-// Copyright (C) 2009-2011 Philippe Daouadi
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see .
-
-#ifndef __AUDIO_D_SOUND_H__
-#define __AUDIO_D_SOUND_H__
-
-#include
-#include
-#include
-
-namespace AMeteor
-{
- namespace Audio
- {
- class DSound
- {
- public :
- static const int BUFFER_SIZE = 32;
-
- DSound ();
-
- void FillFifo (int8_t* buffer);
- void FillFifo (int8_t sample);
-
- void NextSample ()
- {
- // if the buffer is empty, there is nothing to do
- if (m_size)
- // if this was the last sample, we reset all and send 0 to all next
- // GetSample()s until the buffer is refilled
- if (--m_size == 0)
- Reset();
- // else, we go on to next sample and we go to the first if we got
- // to the last
- else if (++m_rpos >= BUFFER_SIZE)
- m_rpos = 0;
- }
-
- void Reset ()
- {
- m_buffer[0] = m_size = m_rpos = m_wpos = 0;
- }
-
- int8_t GetSample()
- {
- return m_buffer[m_rpos];
- }
-
- uint8_t GetSize ()
- {
- return m_size;
- };
-
- bool SaveState (std::ostream& stream);
- bool LoadState (std::istream& stream);
-
- private :
- int8_t m_buffer[BUFFER_SIZE];
- uint8_t m_rpos, m_wpos;
- uint8_t m_size;
- };
- }
-}
-
-#endif
diff --git a/libmeteor/include/ameteor/audio/sound1.hpp b/libmeteor/include/ameteor/audio/sound1.hpp
deleted file mode 100644
index 282ff2c125..0000000000
--- a/libmeteor/include/ameteor/audio/sound1.hpp
+++ /dev/null
@@ -1,75 +0,0 @@
-// Meteor - A Nintendo Gameboy Advance emulator
-// Copyright (C) 2009-2011 Philippe Daouadi
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see .
-
-#ifndef __AUDIO_SOUND_1_H__
-#define __AUDIO_SOUND_1_H__
-
-#include
-#include
-#include
-
-namespace AMeteor
-{
- namespace Audio
- {
- class Sound1
- {
- public :
- Sound1 (uint16_t& cntl, uint16_t& cnth, uint16_t& cntx,
- uint16_t freq);
-
- void Reset ();
-
- // call this at the frequence given in constructor
- void SoundTick ();
-
- void ResetSound ();
- void ResetEnvelope ()
- {
- m_envelope = 0;
- }
-
- int8_t GetSample () const
- {
- return m_sample;
- }
-
- bool IsOn () const
- {
- return m_on;
- }
-
- bool SaveState (std::ostream& stream);
- bool LoadState (std::istream& stream);
-
- private :
- uint16_t &m_cntl, &m_cnth, &m_cntx;
- bool m_on;
- // positions in Period, Sweep time and Envelope step time
- uint32_t m_posP, m_posS, m_posE;
- int8_t m_sample;
- // sample period in cycles
- uint16_t m_speriod;
- // envelope level
- uint8_t m_envelope;
- // sound length in cycles
- uint32_t m_length;
- bool m_timed;
- };
- }
-}
-
-#endif
diff --git a/libmeteor/include/ameteor/audio/sound2.hpp b/libmeteor/include/ameteor/audio/sound2.hpp
deleted file mode 100644
index d4c18d8aaa..0000000000
--- a/libmeteor/include/ameteor/audio/sound2.hpp
+++ /dev/null
@@ -1,70 +0,0 @@
-// Meteor - A Nintendo Gameboy Advance emulator
-// Copyright (C) 2009-2011 Philippe Daouadi
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see .
-
-#ifndef __AUDIO_SOUND_2_H__
-#define __AUDIO_SOUND_2_H__
-
-#include
-#include
-#include
-
-namespace AMeteor
-{
- namespace Audio
- {
- class Sound2
- {
- public :
- Sound2 (uint16_t& cntl, uint16_t& cnth, uint16_t freq);
-
- void Reset ();
-
- // call this at the frequence given in constructor
- void SoundTick ();
-
- void ResetSound ();
- void ResetEnvelope ()
- {
- m_envelope = 0;
- }
-
- int8_t GetSample () const
- {
- return m_sample;
- }
-
- bool IsOn () const
- {
- return m_on;
- }
-
- bool SaveState (std::ostream& stream);
- bool LoadState (std::istream& stream);
-
- private :
- uint16_t &m_cntl, &m_cnth;
- bool m_on;
- uint32_t m_posP, m_posE;
- int8_t m_sample;
- uint16_t m_speriod;
- uint8_t m_envelope;
- uint32_t m_length;
- bool m_timed;
- };
- }
-}
-
-#endif
diff --git a/libmeteor/include/ameteor/audio/sound4.hpp b/libmeteor/include/ameteor/audio/sound4.hpp
deleted file mode 100644
index ab51d627d9..0000000000
--- a/libmeteor/include/ameteor/audio/sound4.hpp
+++ /dev/null
@@ -1,78 +0,0 @@
-// Meteor - A Nintendo Gameboy Advance emulator
-// Copyright (C) 2009-2011 Philippe Daouadi
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see .
-
-#ifndef __AUDIO_SOUND_4_H__
-#define __AUDIO_SOUND_4_H__
-
-#include
-#include
-#include
-
-namespace AMeteor
-{
- namespace Audio
- {
- void InitNoise ();
-
- class Sound4
- {
- public :
- Sound4 (uint16_t& cntl, uint16_t& cnth, uint16_t freq);
-
- void Reset ();
-
- // call this at the frequence given in constructor
- void SoundTick ();
-
- void ResetSound ();
- void ResetEnvelope ()
- {
- m_envelope = 0;
- }
-
- int8_t GetSample () const
- {
- return m_sample;
- }
-
- bool IsOn () const
- {
- return m_on;
- }
-
- bool SaveState (std::ostream& stream);
- bool LoadState (std::istream& stream);
-
- private :
- uint16_t &m_cntl, &m_cnth;
- bool m_on;
- // positions in Period, position in noise and Envelope step time
- uint32_t m_posP, m_posN, m_posE;
- int8_t m_sample;
- // sample period in cycles
- uint16_t m_speriod;
- // envelope level
- uint8_t m_envelope;
- // sound length in cycles
- uint32_t m_length;
- bool m_timed;
- // clock divider
- uint8_t m_div;
- };
- }
-}
-
-#endif
diff --git a/libmeteor/include/ameteor/audio/speaker.hpp b/libmeteor/include/ameteor/audio/speaker.hpp
deleted file mode 100644
index 15d37f955b..0000000000
--- a/libmeteor/include/ameteor/audio/speaker.hpp
+++ /dev/null
@@ -1,173 +0,0 @@
-// Meteor - A Nintendo Gameboy Advance emulator
-// Copyright (C) 2009-2011 Philippe Daouadi
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see .
-
-#ifndef __AUDIO_SPEAKER_H__
-#define __AUDIO_SPEAKER_H__
-
-#include
-#include
-#include
-#include
-#include "sound1.hpp"
-#include "sound2.hpp"
-#include "sound4.hpp"
-#include "dsound.hpp"
-
-namespace AMeteor
-{
- namespace Audio
- {
- class Speaker
- {
- public :
- typedef syg::slot1 FrameSlot;
-
- Speaker (uint16_t& cnt1l, uint16_t& cnt1h, uint16_t& cnt1x,
- uint16_t& cnt2l, uint16_t& cnt2h,
- uint16_t& cnt4l, uint16_t& cnt4h,
- uint16_t& cntl, uint16_t& cnth, uint16_t& cntx, uint16_t& bias);
- ~Speaker ();
-
- inline void SetFrameSlot (const FrameSlot& slot);
-
- void Reset ();
-
- inline void ResetSound1 ();
- inline void ResetSound2 ();
- inline void ResetSound4 ();
- inline void ResetSound1Envelope ();
- inline void ResetSound2Envelope ();
- inline void ResetSound4Envelope ();
-
- inline void FillFifoA (int8_t* buffer);
- inline void FillFifoB (int8_t* buffer);
- inline void FillFifoA (int8_t sample);
- inline void FillFifoB (int8_t sample);
-
- inline void ResetFifoA ();
- inline void ResetFifoB ();
-
- inline void NextSampleA ();
- inline void NextSampleB ();
-
- inline uint8_t GetSizeA();
- inline uint8_t GetSizeB();
-
- void SoundTick ();
-
- bool SaveState (std::ostream& stream);
- bool LoadState (std::istream& stream);
-
- private :
- Sound1 m_sound1;
- Sound2 m_sound2;
- Sound4 m_sound4;
- DSound m_dsa, m_dsb;
- uint16_t &m_cntl, &m_cnth, &m_cntx, &m_bias;
-
- FrameSlot m_sig_frame;
-
- int16_t MixSample (uint16_t cntl, uint8_t cnth);
- };
-
- inline void Speaker::SetFrameSlot (const FrameSlot& slot)
- {
- m_sig_frame = slot;
- }
-
- inline void Speaker::ResetSound1 ()
- {
- m_sound1.ResetSound ();
- }
-
- inline void Speaker::ResetSound2 ()
- {
- m_sound2.ResetSound ();
- }
-
- inline void Speaker::ResetSound4 ()
- {
- m_sound4.ResetSound ();
- }
-
- inline void Speaker::ResetSound1Envelope ()
- {
- m_sound1.ResetEnvelope();
- }
-
- inline void Speaker::ResetSound2Envelope ()
- {
- m_sound2.ResetEnvelope();
- }
-
- inline void Speaker::ResetSound4Envelope ()
- {
- m_sound4.ResetEnvelope();
- }
-
- inline void Speaker::FillFifoA (int8_t* buffer)
- {
- m_dsa.FillFifo(buffer);
- }
-
- inline void Speaker::FillFifoB (int8_t* buffer)
- {
- m_dsb.FillFifo(buffer);
- }
-
- inline void Speaker::FillFifoA (int8_t sample)
- {
- m_dsa.FillFifo(sample);
- }
-
- inline void Speaker::FillFifoB (int8_t sample)
- {
- m_dsb.FillFifo(sample);
- }
-
- inline void Speaker::ResetFifoA ()
- {
- m_dsa.Reset();
- }
-
- inline void Speaker::ResetFifoB ()
- {
- m_dsb.Reset();
- }
-
- inline void Speaker::NextSampleA ()
- {
- m_dsa.NextSample();
- }
-
- inline void Speaker::NextSampleB ()
- {
- m_dsb.NextSample();
- }
-
- inline uint8_t Speaker::GetSizeA()
- {
- return m_dsa.GetSize();
- }
-
- inline uint8_t Speaker::GetSizeB()
- {
- return m_dsb.GetSize();
- }
- }
-}
-
-#endif
diff --git a/libmeteor/include/ameteor/bios.hpp b/libmeteor/include/ameteor/bios.hpp
deleted file mode 100644
index 05a3b7db70..0000000000
--- a/libmeteor/include/ameteor/bios.hpp
+++ /dev/null
@@ -1,59 +0,0 @@
-// Meteor - A Nintendo Gameboy Advance emulator
-// Copyright (C) 2009-2011 Philippe Daouadi
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see .
-
-#ifndef __BIOS_H__
-#define __BIOS_H__
-
-#include "ameteor.hpp"
-
-namespace AMeteor
-{
- namespace Bios
- {
- // Entry point
- void Bios000h ();
- // Software IRQ
- void Bios008h ();
- void Bios168h ();
- // Return from IntrWait (after the IRQ)
- void Bios338h ();
- // IRQ
- void Bios018h ();
- void Bios130h ();
-
- void SoftReset (); // 00
- void RegisterRamReset (); // 01
- void Halt (); // 02
- void IntrWait (); // 04
- void VBlankIntrWait (); // 05
- void Div (); // 06
- void DivArm (); // 07
- void Sqrt (); // 08
- void ArcTan (); // 09
- void ArcTan2 (); // 0A
- void CpuSet (); // 0B
- void CpuFastSet (); // 0C
- void BgAffineSet (); // 0E
- void ObjAffineSet (); // 0F
- void LZ77UnCompWram (); // 11
- void LZ77UnCompVram (); // 12
- void HuffUnComp (); // 13
- void RLUnCompWram (); // 14
- void RLUnCompVram (); // 15
- }
-}
-
-#endif
diff --git a/libmeteor/include/ameteor/cartmem.hpp b/libmeteor/include/ameteor/cartmem.hpp
deleted file mode 100644
index e7ee43678a..0000000000
--- a/libmeteor/include/ameteor/cartmem.hpp
+++ /dev/null
@@ -1,57 +0,0 @@
-// Meteor - A Nintendo Gameboy Advance emulator
-// Copyright (C) 2009-2011 Philippe Daouadi
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see .
-
-#ifndef __CART_MEM_H__
-#define __CART_MEM_H__
-
-#include
-#include
-#include
-#include
-
-namespace AMeteor
-{
- class CartMem
- {
- public:
- static const unsigned int MAX_SIZE = 0x20000;
-
- CartMem();
- virtual ~CartMem();
-
- virtual void Reset () = 0;
-
- virtual bool Load (std::istream& stream) = 0;
- virtual bool Save (std::ostream& stream) = 0;
-
- virtual uint8_t Read (uint16_t add) = 0;
- // returns true if memory has been updated
- virtual bool Write (uint16_t add, uint8_t val) = 0;
-
- virtual bool SaveState (std::ostream& stream);
- virtual bool LoadState (std::istream& stream);
-
- protected:
- uint8_t* m_data;
- uint32_t m_size;
- };
-
-#ifdef __LIBRETRO__
- extern uint8_t CartMemData[CartMem::MAX_SIZE+4];
-#endif
-}
-
-#endif
diff --git a/libmeteor/include/ameteor/clock.hpp b/libmeteor/include/ameteor/clock.hpp
deleted file mode 100644
index b711080538..0000000000
--- a/libmeteor/include/ameteor/clock.hpp
+++ /dev/null
@@ -1,111 +0,0 @@
-// Meteor - A Nintendo Gameboy Advance emulator
-// Copyright (C) 2009-2011 Philippe Daouadi
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see .
-
-#ifndef __CLOCK_H__
-#define __CLOCK_H__
-
-#include
-#include
-#include
-#include
-#include
-
-namespace AMeteor
-{
- class Clock
- {
- public :
- Clock ()
- {
- Reset();
- }
-
- void Reset ();
-
- void ResetCounter()
- {
- m_count = 0;
- }
- unsigned int GetCounter() const
- {
- return m_count;
- }
-
- void TimePass (unsigned short cycles)
- {
- m_cycles += cycles;
- }
- void Commit ();
- void WaitForNext ();
-
- void AddLcd (uint32_t cycles)
- {
- // The lcd clock is always enabled
- m_lcd += cycles;
- SetFirst();
- }
-
- void AddTimer (uint8_t num, uint32_t cycles)
- {
- if (m_timer[num] == INT_MAX)
- m_timer[num] = cycles;
- else
- m_timer[num] += cycles;
- SetFirst();
- }
- void SetTimer (uint8_t num, uint32_t cycles)
- {
- m_timer[num] = cycles;
- SetFirst();
- }
- void DisableTimer (uint8_t num)
- {
- m_timer[num] = INT_MAX;
- SetFirst();
- }
- int GetTimer (uint8_t num)
- {
- return m_timer[num];
- }
-
- //void SetBattery (uint32_t cycles)
- //{
- // m_battery = cycles;
- //}
- //void DisableBattery ()
- //{
- // m_battery = INT_MAX;
- // no need to SetFirst since battery will be disabled only in TimeEvent
- //}
-
- bool SaveState (std::ostream& stream);
- bool LoadState (std::istream& stream);
-
- private :
- // XXX freq
- static const int SOUND_PERIOD = 380;
-
- unsigned short m_cycles;
- unsigned short m_first;
- int m_lcd, m_timer[4], m_sound;//, m_battery;
-
- unsigned int m_count;
-
- void SetFirst ();
- };
-}
-
-#endif
diff --git a/libmeteor/include/ameteor/cpu.hpp b/libmeteor/include/ameteor/cpu.hpp
deleted file mode 100644
index 2259de832d..0000000000
--- a/libmeteor/include/ameteor/cpu.hpp
+++ /dev/null
@@ -1,148 +0,0 @@
-// Meteor - A Nintendo Gameboy Advance emulator
-// Copyright (C) 2009-2011 Philippe Daouadi
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see .
-
-#ifndef __CPU_H__
-#define __CPU_H__
-
-#include
-#include
-#include
-
-namespace AMeteor
-{
- class Cpu
- {
- public :
- union Psr
- {
- uint32_t dw;
- struct
- {
- unsigned int mode : 5;
- unsigned int thumb : 1;
- unsigned int fiq_d : 1;
- unsigned int irq_d : 1;
- unsigned int reserved : 19;
- unsigned int s_overflow : 1;
- unsigned int f_overflow : 1;
- unsigned int f_carry : 1;
- unsigned int f_zero : 1;
- unsigned int f_sign : 1;
- } b;
- };
- struct IPsr
- {
- uint8_t mode;
- bool thumb;
- bool fiq_d;
- bool irq_d;
- bool s_overflow;
- bool f_overflow;
- bool f_carry;
- bool f_zero;
- bool f_sign;
- };
- enum Modes
- {
- M_USR = 0x10,
- M_FIQ = 0x11,
- M_IRQ = 0x12,
- M_SVC = 0x13,
- M_ABT = 0x17,
- M_UND = 0x1B,
- M_SYS = 0x1F
- };
-
- Cpu ();
- virtual ~Cpu () {}
-
- virtual void Reset ();
- virtual void SoftReset ();
-
- void UpdateICpsr ();
- void UpdateCpsr ();
- void SwitchToMode (uint8_t newmode);
- void SwitchModeBack ();
-
- virtual void SendInterrupt (uint16_t interrupt) = 0;
- virtual void CheckInterrupt () = 0;
- void Interrupt ();
- void SoftwareInterrupt (uint32_t comment);
- void SoftwareInterrupt ();
-
- uint32_t& Reg(uint8_t r)
- {
- return m_st.r[r];
- }
-
- Psr& Cpsr()
- {
- return m_st.cpsr;
- }
- IPsr& ICpsr()
- {
- return m_st.icpsr;
- }
- Psr& Spsr()
- {
- return m_st.spsr;
- }
-
- bool SaveState (std::ostream& stream);
- bool LoadState (std::istream& stream);
-
- protected :
- struct CPUState
- {
- // Current registers
- uint32_t r[16];
- Psr cpsr, spsr;
- IPsr icpsr;
-
- // System/User
- uint32_t usr_r[7]; // from 8 to 14
-
- // FIQ
- uint32_t fiq_r[7]; // from 8 to 14
- Psr fiq_spsr;
-
- // Supervisor
- uint32_t svc_r[2]; // 13 and 14
- Psr svc_spsr;
-
- // Abort
- uint32_t abt_r[2]; // 13 and 14
- Psr abt_spsr;
-
- // IRQ
- uint32_t irq_r[2]; // 13 and 14
- Psr irq_spsr;
-
- // Undefined
- uint32_t und_r[2]; // 13 and 14
- Psr und_spsr;
- };
-
- CPUState m_st;
-
- virtual void SetInterrupt (bool interrupt) = 0;
-
- private :
- void SaveMode (uint8_t mode);
- };
-}
-
-#endif
diff --git a/libmeteor/include/ameteor/disassembler/argimmediate.hpp b/libmeteor/include/ameteor/disassembler/argimmediate.hpp
deleted file mode 100644
index cb372f1067..0000000000
--- a/libmeteor/include/ameteor/disassembler/argimmediate.hpp
+++ /dev/null
@@ -1,44 +0,0 @@
-// Meteor - A Nintendo Gameboy Advance emulator
-// Copyright (C) 2009-2011 Philippe Daouadi
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see .
-
-#ifndef __ARG_IMMEDIATE_H__
-#define __ARG_IMMEDIATE_H__
-
-#include "argument.hpp"
-#include
-
-namespace AMeteor
-{
- namespace Disassembler
- {
- class ArgImmediate : public Argument
- {
- public :
- ArgImmediate (int32_t imm) :
- m_imm(imm)
- { }
-
- Argument* Clone () const;
-
- std::string GetString () const;
-
- private :
- int32_t m_imm;
- };
- }
-}
-
-#endif
diff --git a/libmeteor/include/ameteor/disassembler/argmulregisters.hpp b/libmeteor/include/ameteor/disassembler/argmulregisters.hpp
deleted file mode 100644
index 73a6c241a1..0000000000
--- a/libmeteor/include/ameteor/disassembler/argmulregisters.hpp
+++ /dev/null
@@ -1,67 +0,0 @@
-// Meteor - A Nintendo Gameboy Advance emulator
-// Copyright (C) 2009-2011 Philippe Daouadi
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see .
-
-#ifndef __ARG_MUL_REGISTERS_H__
-#define __ARG_MUL_REGISTERS_H__
-
-#include "argument.hpp"
-
-#include
-#include
-
-namespace AMeteor
-{
- namespace Disassembler
- {
- enum SpecialRegister
- {
- SPREG_NONE = 0,
- SPREG_LR = 1,
- SPREG_PC = 2
- };
-
- class ArgMulRegisters : public Argument
- {
- public :
- ArgMulRegisters (bool forceuser) :
- m_lastreg(SPREG_NONE),
- m_forceuser(forceuser)
- { }
-
- Argument* Clone () const;
-
- void AddRegister(uint8_t reg)
- {
- m_regs.push_back(reg);
- }
- void AddLastRegister(SpecialRegister reg)
- {
- m_lastreg = reg;
- }
-
- std::string GetString () const;
-
- private :
- typedef std::vector Registers;
-
- Registers m_regs;
- SpecialRegister m_lastreg;
- bool m_forceuser;
- };
- }
-}
-
-#endif
diff --git a/libmeteor/include/ameteor/disassembler/argpsr.hpp b/libmeteor/include/ameteor/disassembler/argpsr.hpp
deleted file mode 100644
index 5557615a99..0000000000
--- a/libmeteor/include/ameteor/disassembler/argpsr.hpp
+++ /dev/null
@@ -1,47 +0,0 @@
-// Meteor - A Nintendo Gameboy Advance emulator
-// Copyright (C) 2009-2011 Philippe Daouadi
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see .
-
-#ifndef __ARG_PSR_H__
-#define __ARG_PSR_H__
-
-#include "argument.hpp"
-
-#include
-
-namespace AMeteor
-{
- namespace Disassembler
- {
- class ArgPsr : public Argument
- {
- public :
- ArgPsr (bool spsr, uint8_t fields = 0xFF) :
- m_spsr(spsr),
- m_fields(fields)
- { }
-
- Argument* Clone () const;
-
- std::string GetString () const;
-
- private :
- bool m_spsr;
- uint8_t m_fields;
- };
- }
-}
-
-#endif
diff --git a/libmeteor/include/ameteor/disassembler/argregister.hpp b/libmeteor/include/ameteor/disassembler/argregister.hpp
deleted file mode 100644
index 78a26b44e1..0000000000
--- a/libmeteor/include/ameteor/disassembler/argregister.hpp
+++ /dev/null
@@ -1,56 +0,0 @@
-// Meteor - A Nintendo Gameboy Advance emulator
-// Copyright (C) 2009-2011 Philippe Daouadi
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see .
-
-#ifndef __ARG_REGISTER_H__
-#define __ARG_REGISTER_H__
-
-#include "argument.hpp"
-
-#include
-
-namespace AMeteor
-{
- namespace Disassembler
- {
- class ArgRegister : public Argument
- {
- public :
- ArgRegister (uint8_t reg, bool writeback = false,
- bool special = false, bool memory = false) :
- m_reg(reg),
- m_writeback(writeback),
- m_special(special),
- m_memory(memory)
- { }
-
- Argument* Clone () const;
-
- std::string GetString () const;
- uint8_t GetRegister () const
- {
- return m_reg;
- }
-
- private :
- uint8_t m_reg;
- bool m_writeback;
- bool m_special;
- bool m_memory;
- };
- }
-}
-
-#endif
diff --git a/libmeteor/include/ameteor/disassembler/argrelative.hpp b/libmeteor/include/ameteor/disassembler/argrelative.hpp
deleted file mode 100644
index c7ccc9e212..0000000000
--- a/libmeteor/include/ameteor/disassembler/argrelative.hpp
+++ /dev/null
@@ -1,50 +0,0 @@
-// Meteor - A Nintendo Gameboy Advance emulator
-// Copyright (C) 2009-2011 Philippe Daouadi
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see .
-
-#ifndef __ARG_RELATIVE_H__
-#define __ARG_RELATIVE_H__
-
-#include "argument.hpp"
-#include "argregister.hpp"
-#include "argimmediate.hpp"
-
-namespace AMeteor
-{
- namespace Disassembler
- {
- class ArgRelative : public Argument
- {
- public :
- ArgRelative (const ArgRegister& reg, const Argument& off,
- bool pre, bool up, bool writeback);
- ArgRelative (const ArgRelative& arg);
- ~ArgRelative ();
-
- Argument* Clone () const;
-
- std::string GetString () const;
-
- private :
- ArgRegister m_reg;
- const Argument* m_off;
- bool m_pre;
- bool m_up;
- bool m_writeback;
- };
- }
-}
-
-#endif
diff --git a/libmeteor/include/ameteor/disassembler/argshift.hpp b/libmeteor/include/ameteor/disassembler/argshift.hpp
deleted file mode 100644
index 1ba586b6d7..0000000000
--- a/libmeteor/include/ameteor/disassembler/argshift.hpp
+++ /dev/null
@@ -1,56 +0,0 @@
-// Meteor - A Nintendo Gameboy Advance emulator
-// Copyright (C) 2009-2011 Philippe Daouadi
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see .
-
-#ifndef __ARG_SHIFT_H__
-#define __ARG_SHIFT_H__
-
-#include "argument.hpp"
-
-namespace AMeteor
-{
- namespace Disassembler
- {
- enum ShiftType
- {
- SHIFT_LSL = 0,
- SHIFT_LSR,
- SHIFT_ASR,
- SHIFT_ROR,
- SHIFT_RRX
- };
-
- class ArgShift : public Argument
- {
- public :
- ArgShift (const Argument& arg1, const Argument& arg2,
- ShiftType type, bool memory);
- ArgShift (const ArgShift& arg);
- ~ArgShift ();
-
- Argument* Clone () const;
-
- std::string GetString () const;
-
- private :
- const Argument* m_arg1;
- const Argument* m_arg2;
- ShiftType m_type;
- bool m_memory;
- };
- }
-}
-
-#endif
diff --git a/libmeteor/include/ameteor/disassembler/arguimmediate.hpp b/libmeteor/include/ameteor/disassembler/arguimmediate.hpp
deleted file mode 100644
index 450322eba3..0000000000
--- a/libmeteor/include/ameteor/disassembler/arguimmediate.hpp
+++ /dev/null
@@ -1,45 +0,0 @@
-// Meteor - A Nintendo Gameboy Advance emulator
-// Copyright (C) 2009-2011 Philippe Daouadi
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see .
-
-#ifndef __ARG_U_IMMEDIATE_H__
-#define __ARG_U_IMMEDIATE_H__
-
-#include "argument.hpp"
-
-#include
-
-namespace AMeteor
-{
- namespace Disassembler
- {
- class ArgUImmediate : public Argument
- {
- public :
- ArgUImmediate (uint32_t imm) :
- m_imm(imm)
- { }
-
- Argument* Clone () const;
-
- std::string GetString () const;
-
- private :
- uint32_t m_imm;
- };
- }
-}
-
-#endif
diff --git a/libmeteor/include/ameteor/disassembler/argument.hpp b/libmeteor/include/ameteor/disassembler/argument.hpp
deleted file mode 100644
index de007d0d7f..0000000000
--- a/libmeteor/include/ameteor/disassembler/argument.hpp
+++ /dev/null
@@ -1,39 +0,0 @@
-// Meteor - A Nintendo Gameboy Advance emulator
-// Copyright (C) 2009-2011 Philippe Daouadi
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see .
-
-#ifndef __ARGUMENT_H__
-#define __ARGUMENT_H__
-
-#include
-
-namespace AMeteor
-{
- namespace Disassembler
- {
- class Argument
- {
- public :
- virtual ~Argument ()
- { }
-
- virtual Argument* Clone () const = 0;
-
- virtual std::string GetString () const = 0;
- };
- }
-}
-
-#endif
diff --git a/libmeteor/include/ameteor/disassembler/arguments.hpp b/libmeteor/include/ameteor/disassembler/arguments.hpp
deleted file mode 100644
index dd078da2ef..0000000000
--- a/libmeteor/include/ameteor/disassembler/arguments.hpp
+++ /dev/null
@@ -1,48 +0,0 @@
-// Meteor - A Nintendo Gameboy Advance emulator
-// Copyright (C) 2009-2011 Philippe Daouadi
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see .
-
-#ifndef __ARGUMENTS_H__
-#define __ARGUMENTS_H__
-
-#include "argument.hpp"
-
-#include
-
-namespace AMeteor
-{
- namespace Disassembler
- {
- class Arguments
- {
- public :
- ~Arguments ();
-
- void Clear ();
-
- void AddArgument(const Argument& arg)
- {
- m_args.push_back(arg.Clone());
- }
-
- std::string GetString () const;
-
- private :
- std::vector m_args;
- };
- }
-}
-
-#endif
diff --git a/libmeteor/include/ameteor/disassembler/instruction.hpp b/libmeteor/include/ameteor/disassembler/instruction.hpp
deleted file mode 100644
index 3da87b8be1..0000000000
--- a/libmeteor/include/ameteor/disassembler/instruction.hpp
+++ /dev/null
@@ -1,76 +0,0 @@
-// Meteor - A Nintendo Gameboy Advance emulator
-// Copyright (C) 2009-2011 Philippe Daouadi
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see .
-
-#ifndef __INSTRUCTION_H__
-#define __INSTRUCTION_H__
-
-#include "arguments.hpp"
-
-#include
-#include
-
-namespace AMeteor
-{
- namespace Disassembler
- {
- class Instruction
- {
- public :
- Instruction ()
- {
- }
-
- explicit Instruction (uint32_t offset, uint32_t code)
- {
- ParseArm (offset, code);
- }
-
- explicit Instruction (uint32_t offset, uint16_t code)
- {
- ParseThumb(offset, code);
- }
-
- void Clear ();
-
- void ParseArm (uint32_t offset, uint32_t code);
- void ParseThumb (uint32_t offset, uint16_t code);
-
- const std::string& GetOperator () const
- {
- return m_operator;
- }
-
- std::string GetArguments () const
- {
- return m_args.GetString();
- }
-
- std::string ToString () const
- {
- return GetOperator() + ' ' + GetArguments();
- }
-
- private :
- std::string m_operator;
- Arguments m_args;
-
- void ParseArmDataProc (uint32_t code);
- void ParseArmCondition (uint32_t code);
- };
- }
-}
-
-#endif
diff --git a/libmeteor/include/ameteor/dma.hpp b/libmeteor/include/ameteor/dma.hpp
deleted file mode 100644
index d4e31905e5..0000000000
--- a/libmeteor/include/ameteor/dma.hpp
+++ /dev/null
@@ -1,113 +0,0 @@
-// Meteor - A Nintendo Gameboy Advance emulator
-// Copyright (C) 2009-2011 Philippe Daouadi
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see .
-
-#ifndef __DMA_H__
-#define __DMA_H__
-
-#include
-#include
-#include
-
-namespace AMeteor
-{
- class Dma
- {
- public :
- enum Reason
- {
- Immediately = 0,
- VBlank,
- HBlank,
- Special
- };
-
- Dma () :
- m_graphic(false)
- { }
-
- void Reset ();
-
- bool GraphicDma () const
- {
- return false;
- //return m_graphic;
- }
-
- void SetReload(uint8_t channum, uint16_t reload)
- {
- m_chans[channum].reload = reload;
- }
-
- void UpdateCnt (uint8_t channum);
- void Check(uint8_t channum, uint8_t reason);
- inline void CheckAll(uint8_t reason)
- {
- Check(0, reason);
- Check(1, reason);
- Check(2, reason);
- Check(3, reason);
- }
-
- bool SaveState (std::ostream& stream);
- bool LoadState (std::istream& stream);
-
- private :
- struct Channel
- {
- Channel () :
- reload(0),
- src(0),
- dest(0),
- count(0),
- control(0)
- { }
-
- uint16_t reload;
- uint32_t src;
- uint32_t dest;
- uint16_t count;
- union Control
- {
- Control(uint16_t v) :
- w(v)
- { }
-
- uint16_t w;
- struct
- {
- unsigned int unused : 5;
- unsigned int dest : 2;
- unsigned int src : 2;
- unsigned int repeat : 1;
- unsigned int type : 1;
- unsigned int drq : 1;
- unsigned int start : 2;
- unsigned int irq : 1;
- unsigned int enable : 1;
- } b;
- } control;
- };
-
- Channel m_chans[4];
- bool m_graphic;
-
- void Process(uint8_t channel);
- void Copy (uint32_t& src, uint32_t& dest, int8_t s_inc, int8_t d_inc,
- uint32_t count, bool word);
- };
-}
-
-#endif
diff --git a/libmeteor/include/ameteor/eeprom.hpp b/libmeteor/include/ameteor/eeprom.hpp
deleted file mode 100644
index 8052a5b393..0000000000
--- a/libmeteor/include/ameteor/eeprom.hpp
+++ /dev/null
@@ -1,79 +0,0 @@
-// Meteor - A Nintendo Gameboy Advance emulator
-// Copyright (C) 2009-2011 Philippe Daouadi
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see .
-
-#ifndef __EEPROM_H__
-#define __EEPROM_H__
-
-#include "cartmem.hpp"
-#include
-#include
-#include
-
-namespace AMeteor
-{
- class Eeprom : public CartMem
- {
- public :
- Eeprom (bool big);
-
- void Reset ();
-
- uint16_t GetSize () const
- {
- return m_size;
- }
-
- bool Load (std::istream& f);
- bool Save (std::ostream& f);
-
- uint8_t Read (uint16_t add);
- bool Write (uint16_t add, uint8_t val);
-
- uint16_t Read ();
- //bool Write (uint16_t val);
-
- bool Write (uint16_t* data, uint16_t size);
- //XXX
-#if 0
- void Read (uint16_t* pOut);
-#endif
-
- bool SaveState (std::ostream& stream);
- bool LoadState (std::istream& stream);
-
- private :
- enum State
- {
- IDLE,
- //WAITING,
-
- //READ_ADD,
- //READ_END,
- READ_GARBAGE,
- READ_DATA
-
- /*WRITE_ADD,
- WRITE_DATA,
- WRITE_END*/
- };
-
- uint8_t m_state;
- uint16_t m_add;
- uint8_t m_pos;
- };
-}
-
-#endif
diff --git a/libmeteor/include/ameteor/flash.hpp b/libmeteor/include/ameteor/flash.hpp
deleted file mode 100644
index 3c56d89747..0000000000
--- a/libmeteor/include/ameteor/flash.hpp
+++ /dev/null
@@ -1,63 +0,0 @@
-// Meteor - A Nintendo Gameboy Advance emulator
-// Copyright (C) 2009-2011 Philippe Daouadi
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see .
-
-#ifndef __FLASH_H__
-#define __FLASH_H__
-
-#include "cartmem.hpp"
-#include
-#include
-#include
-
-namespace AMeteor
-{
- class Flash : public CartMem
- {
- public :
- Flash (bool big);
-
- void Reset ();
-
- bool Load (std::istream& f);
- bool Save (std::ostream& f);
-
- uint8_t Read (uint16_t add);
- bool Write (uint16_t add, uint8_t val);
-
- bool SaveState (std::ostream& stream);
- bool LoadState (std::istream& stream);
-
- private :
- uint8_t m_device_id;
- uint8_t m_manufacturer_id;
-
- enum State
- {
- NORMAL,
- CMD1,
- CMD2,
- ID,
- ERASE1,
- ERASE2,
- ERASE3,
- WRITE
- };
-
- State m_state;
- };
-}
-
-#endif
diff --git a/libmeteor/include/ameteor/graphics/bglayer.hpp b/libmeteor/include/ameteor/graphics/bglayer.hpp
deleted file mode 100644
index 48d19ffe67..0000000000
--- a/libmeteor/include/ameteor/graphics/bglayer.hpp
+++ /dev/null
@@ -1,100 +0,0 @@
-// Meteor - A Nintendo Gameboy Advance emulator
-// Copyright (C) 2009-2011 Philippe Daouadi
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see .
-
-#ifndef __GRAPHICS_BG_LAYER_H__
-#define __GRAPHICS_BG_LAYER_H__
-
-#include "ameteor/memory.hpp"
-#include "ameteor/io.hpp"
-
-#include
-#include
-
-namespace AMeteor
-{
- namespace Graphics
- {
- class BgLayer
- {
- public :
- BgLayer (int8_t num, Memory& memory, Io& io, uint16_t* pPalette);
- ~BgLayer ();
-
- inline uint8_t GetNum () const;
- inline uint8_t GetPriority () const;
-
- void DrawLine0 (uint8_t line, uint16_t* ptr);
- void DrawLine2 (uint16_t* ptr,
- int32_t refX, int32_t refY,
- int16_t dx, int16_t dy);
- void DrawLine3 (uint16_t* ptr,
- int32_t refX, int32_t refY,
- int16_t dx, int16_t dy);
- void DrawLine4 (uint8_t line, uint16_t* ptr,
- int32_t curX, int32_t curY,
- int16_t dx, int16_t dmx, int16_t dy, int16_t dmy, bool frame1);
- void DrawLine5 (uint16_t* ptr,
- int32_t refX, int32_t refY,
- int16_t dx, int16_t dy, bool frame1);
- void FillList ();
-
- void UpdateCnt (uint16_t cnt);
- inline void UpdateXOff (uint16_t off);
- inline void UpdateYOff (uint16_t off);
-
- private :
- Memory& m_memory;
- Io& m_io;
-
- const uint8_t m_num;
- uint8_t m_priority;
-
- uint16_t m_cnt;
- bool m_hicolor;
- uint16_t m_xoff, m_yoff;
- // in text mode
- uint8_t m_tWidth, m_tHeight;
- // in rotation/scale mode
- uint8_t m_rWidth, m_rHeight;
-
- uint32_t m_mapAdd;
- uint32_t m_charAdd;
- uint16_t* m_pPalette;
- };
-
- inline uint8_t BgLayer::GetNum () const
- {
- return m_num;
- }
-
- inline uint8_t BgLayer::GetPriority () const
- {
- return m_priority;
- }
-
- inline void BgLayer::UpdateXOff (uint16_t off)
- {
- m_xoff = off;
- }
-
- inline void BgLayer::UpdateYOff (uint16_t off)
- {
- m_yoff = off;
- }
- }
-}
-
-#endif
diff --git a/libmeteor/include/ameteor/graphics/object.hpp b/libmeteor/include/ameteor/graphics/object.hpp
deleted file mode 100644
index c1611c149b..0000000000
--- a/libmeteor/include/ameteor/graphics/object.hpp
+++ /dev/null
@@ -1,100 +0,0 @@
-// Meteor - A Nintendo Gameboy Advance emulator
-// Copyright (C) 2009-2011 Philippe Daouadi
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see .
-
-#ifndef __GRAPHICS_OBJECT_H__
-#define __GRAPHICS_OBJECT_H__
-
-#include
-#include
-#include
-
-namespace AMeteor
-{
- namespace Graphics
- {
- class Object
- {
- public :
- static const uint8_t FLIP_HORIZONTAL = 1;
- static const uint8_t FLIP_VERTICAL = 2;
-
- Object (uint16_t* pPalette, uint8_t* pChar);
- // Warning : this copy constructor must not be used on an used object
- // use it only on just created objects
- Object (const Object& obj);
-
- inline uint8_t GetPriority () const;
- inline int8_t GetRotationParam () const;
- inline uint16_t GetTileNum () const;
- inline bool IsWindow () const;
-
- void DrawLine (uint8_t line, uint32_t* surface, bool oneDim,
- uint8_t mosaic);
- void DrawLineRot (uint8_t line, uint32_t* surface, bool oneDim,
- int16_t a, int16_t b, int16_t c, int16_t d, uint8_t mosaic);
- void DrawWindow (uint8_t line, uint8_t* surface, bool oneDim,
- uint8_t mask);
- void DrawWindowRot (uint8_t line, uint8_t* surface,
- bool oneDim, int16_t a, int16_t b, int16_t c, int16_t d,
- uint8_t mask);
-
- void UpdateAttrs (uint16_t attr0, uint16_t attr1, uint16_t attr2);
- void UpdateAttr0 (uint16_t attr);
- void UpdateAttr1 (uint16_t attr);
- void UpdateAttr2 (uint16_t attr);
-
- private :
- inline void SetSize ();
-
- enum Shape
- {
- SHAPE_SQUARE = 0,
- SHAPE_HORIZONTAL,
- SHAPE_VERTICAL,
- SHAPE_PROHIBITED
- };
-
- uint16_t m_attr0, m_attr1, m_attr2;
- uint8_t m_width, m_height;
- uint16_t* m_pPalette;
- uint8_t* m_pChar;
- uint32_t m_charBegin;
- uint32_t m_charEnd;
- };
-
- inline int8_t Object::GetRotationParam () const
- {
- return (m_attr0 & (0x1 << 8)) ? (m_attr1 >> 9) & 0x1F : -1;
- }
-
- inline uint8_t Object::GetPriority () const
- {
- return (m_attr2 >> 10) & 0x3;
- }
-
- inline bool Object::IsWindow () const
- {
- return (m_attr0 & (0x3 << 10)) == (0x2 << 10);
- }
-
- inline uint16_t Object::GetTileNum () const
- {
- return (m_attr2 & 0x3FF);
- }
- }
-}
-
-#endif
diff --git a/libmeteor/include/ameteor/graphics/objects.hpp b/libmeteor/include/ameteor/graphics/objects.hpp
deleted file mode 100644
index a398080bd7..0000000000
--- a/libmeteor/include/ameteor/graphics/objects.hpp
+++ /dev/null
@@ -1,53 +0,0 @@
-// Meteor - A Nintendo Gameboy Advance emulator
-// Copyright (C) 2009-2011 Philippe Daouadi
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see .
-
-#ifndef __GRAPHICS_OBJECTS_H__
-#define __GRAPHICS_OBJECTS_H__
-
-#include "object.hpp"
-#include "ameteor/memory.hpp"
-#include "ameteor/io.hpp"
-
-#include
-
-namespace AMeteor
-{
- namespace Graphics
- {
- class Objects
- {
- public :
- Objects (Memory& memory, Io& io, uint16_t* pPalette);
-
- void DrawLine (uint8_t line, uint32_t* surface);
- void DrawLineHighOnly (uint8_t line, uint32_t* surface);
- void DrawWindow (uint8_t line, uint8_t* surface);
-
- void OamWrite (uint32_t begin, uint32_t end);
- void OamWrite16 (uint32_t add);
- void OamWrite32 (uint32_t add);
-
- private :
- typedef std::vector