Commits

Kareem Callender committed 83a2169 Draft

Toms of formatting related changes and other things.
Start of implementing comments
Rule added for "default.txt"
Rule added for "settings.txt"
Started working on ImageDisplayForm.cs to fix the palette display.

  • Participants
  • Parent commits 9dfffc3

Comments (0)

Files changed (20)

gbread/ASM/GBInstructions.cs

+//Copyright © 2012 Silenthal
+
+//This file is part of LibGBasm.
+//LibGBasm is free software: you can redistribute it and/or modify
+//it under the terms of the GNU Lesser General Public License as published by
+//the Free Software Foundation, either version 3 of the License, or
+//(at your option) any later version.
+
+//LibGBasm 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 Lesser General Public License for more details.
+
+//You should have received a copy of the GNU Lesser General Public License
+//along with LibGBasm.  If not, see <http://www.gnu.org/licenses/>.
+namespace LibGBasm
+{
+	internal class GBInstructions
+	{
+		private static GBArgument BCMap = new GBArgument() { ArgType = GBArgumentType.MemMapRegisterDouble, RegDoubleArg = GBRegisterDouble.bc };
+		private static GBArgument DEMap = new GBArgument() { ArgType = GBArgumentType.MemMapRegisterDouble, RegDoubleArg = GBRegisterDouble.de };
+		private static GBArgument HLMap = new GBArgument() { ArgType = GBArgumentType.MemMapRegisterDouble, RegDoubleArg = GBRegisterDouble.hl };
+		private static GBArgument CMap = new GBArgument() { ArgType = GBArgumentType.MemMapRegisterSingle, RegSingleArg = GBRegisterSingle.c };
+
+		private static GBArgument NCCond = new GBArgument() { ArgType = GBArgumentType.Conditional, CondArg = GBConditional.nc };
+		private static GBArgument CCond = new GBArgument() { ArgType = GBArgumentType.Conditional, CondArg = GBConditional.c };
+		private static GBArgument NZCond = new GBArgument() { ArgType = GBArgumentType.Conditional, CondArg = GBConditional.nz };
+		private static GBArgument ZCond = new GBArgument() { ArgType = GBArgumentType.Conditional, CondArg = GBConditional.z };
+
+		private static GBArgument RegA = new GBArgument() { ArgType = GBArgumentType.RegisterSingle, RegSingleArg = GBRegisterSingle.a };
+		private static GBArgument RegB = new GBArgument() { ArgType = GBArgumentType.RegisterSingle, RegSingleArg = GBRegisterSingle.b };
+		private static GBArgument RegC = new GBArgument() { ArgType = GBArgumentType.RegisterSingle, RegSingleArg = GBRegisterSingle.c };
+		private static GBArgument RegD = new GBArgument() { ArgType = GBArgumentType.RegisterSingle, RegSingleArg = GBRegisterSingle.d };
+		private static GBArgument RegE = new GBArgument() { ArgType = GBArgumentType.RegisterSingle, RegSingleArg = GBRegisterSingle.e };
+		private static GBArgument RegH = new GBArgument() { ArgType = GBArgumentType.RegisterSingle, RegSingleArg = GBRegisterSingle.h };
+		private static GBArgument RegL = new GBArgument() { ArgType = GBArgumentType.RegisterSingle, RegSingleArg = GBRegisterSingle.l };
+
+		private static GBArgument RegAF = new GBArgument() { ArgType = GBArgumentType.RegisterDouble, RegDoubleArg = GBRegisterDouble.af };
+		private static GBArgument RegBC = new GBArgument() { ArgType = GBArgumentType.RegisterDouble, RegDoubleArg = GBRegisterDouble.bc };
+		private static GBArgument RegDE = new GBArgument() { ArgType = GBArgumentType.RegisterDouble, RegDoubleArg = GBRegisterDouble.de };
+		private static GBArgument RegHL = new GBArgument() { ArgType = GBArgumentType.RegisterDouble, RegDoubleArg = GBRegisterDouble.hl };
+		private static GBArgument RegSP = new GBArgument() { ArgType = GBArgumentType.RegisterDouble, RegDoubleArg = GBRegisterDouble.sp };
+
+		private static GBArgument ByteArg = new GBArgument() { ArgType = GBArgumentType.Byte };
+		private static GBArgument WordArg = new GBArgument() { ArgType = GBArgumentType.Word };
+		private static GBArgument MemMapArg = new GBArgument() { ArgType = GBArgumentType.MemMapWord };
+
+		private static GBArgument BitArg0 = new GBArgument() { ArgType = GBArgumentType.Bit, NumArg = 0 };
+		private static GBArgument BitArg1 = new GBArgument() { ArgType = GBArgumentType.Bit, NumArg = 1 };
+		private static GBArgument BitArg2 = new GBArgument() { ArgType = GBArgumentType.Bit, NumArg = 2 };
+		private static GBArgument BitArg3 = new GBArgument() { ArgType = GBArgumentType.Bit, NumArg = 3 };
+		private static GBArgument BitArg4 = new GBArgument() { ArgType = GBArgumentType.Bit, NumArg = 4 };
+		private static GBArgument BitArg5 = new GBArgument() { ArgType = GBArgumentType.Bit, NumArg = 5 };
+		private static GBArgument BitArg6 = new GBArgument() { ArgType = GBArgumentType.Bit, NumArg = 6 };
+		private static GBArgument BitArg7 = new GBArgument() { ArgType = GBArgumentType.Bit, NumArg = 7 };
+
+		#region Regular Instructions
+
+		internal static GBInstruction[] InstructionUnitTable = new GBInstruction[256]
+		{
+			#region 0x00-0x0F
+			new GBInstruction() { InstSize = 1, ArgCount = 0, InstType = InstructionType.nop },
+			new GBInstruction() { InstSize = 3, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegBC, Arg2 = WordArg },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = BCMap, Arg2 = RegA },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.inc, Arg1 = RegBC },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.inc, Arg1 = RegB },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.dec, Arg1 = RegB },
+			new GBInstruction() { InstSize = 2, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegB, Arg2 = ByteArg },
+			new GBInstruction() { InstSize = 1, ArgCount = 0, InstType = InstructionType.rlca },
+			new GBInstruction() { InstSize = 3, ArgCount = 2, InstType = InstructionType.ld, Arg1 = MemMapArg, Arg2 = RegSP },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.add, Arg1 = RegHL, Arg2 = RegBC },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegA, Arg2 = BCMap },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.dec, Arg1 = RegBC },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.inc, Arg1 = RegC },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.dec, Arg1 = RegC },
+			new GBInstruction() { InstSize = 2, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegC, Arg2 = ByteArg },
+			new GBInstruction() { InstSize = 1, ArgCount = 0, InstType = InstructionType.rrca },
+			#endregion
+			#region 0x10-0x1F
+			new GBInstruction() { InstSize = 2, ArgCount = 0, InstType = InstructionType.stop },
+			new GBInstruction() { InstSize = 3, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegDE, Arg2 = WordArg },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = DEMap, Arg2 = RegA },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.inc, Arg1 = RegDE },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.inc, Arg1 = RegD },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.dec, Arg1 = RegD },
+			new GBInstruction() { InstSize = 2, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegD, Arg2 = ByteArg },
+			new GBInstruction() { InstSize = 1, ArgCount = 0, InstType = InstructionType.rla },
+			new GBInstruction() { InstSize = 2, ArgCount = 1, InstType = InstructionType.jr, Arg1 = WordArg },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.add, Arg1 = RegHL, Arg2 = RegDE },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegA, Arg2 = DEMap },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.dec, Arg1 = RegDE },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.inc, Arg1 = RegE },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.dec, Arg1 = RegE },
+			new GBInstruction() { InstSize = 2, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegE, Arg2 = ByteArg },
+			new GBInstruction() { InstSize = 1, ArgCount = 0, InstType = InstructionType.rra },
+			#endregion
+			#region 0x20-0x2F
+			new GBInstruction() { InstSize = 2, ArgCount = 2, InstType = InstructionType.jr, Arg1 = NZCond, Arg2 = WordArg },
+			new GBInstruction() { InstSize = 3, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegHL, Arg2 = WordArg },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ldi, Arg1 = HLMap, Arg2 = RegA },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.inc, Arg1 = RegHL },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.inc, Arg1 = RegH },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.dec, Arg1 = RegH },
+			new GBInstruction() { InstSize = 2, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegH, Arg2 = ByteArg },
+			new GBInstruction() { InstSize = 1, ArgCount = 0, InstType = InstructionType.daa },
+			new GBInstruction() { InstSize = 2, ArgCount = 2, InstType = InstructionType.jr, Arg1 = ZCond, Arg2 = WordArg },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.add, Arg1 = RegHL, Arg2 = RegHL },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ldi, Arg1 = RegA, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.dec, Arg1 = RegHL },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.inc, Arg1 = RegL },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.dec, Arg1 = RegL },
+			new GBInstruction() { InstSize = 2, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegL, Arg2 = ByteArg },
+			new GBInstruction() { InstSize = 1, ArgCount = 0, InstType = InstructionType.cpl },
+			#endregion
+			#region 0x30-0x3F
+			new GBInstruction() { InstSize = 2, ArgCount = 2, InstType = InstructionType.jr, Arg1 = NCCond, Arg2 = WordArg },
+			new GBInstruction() { InstSize = 3, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegSP, Arg2 = WordArg },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ldd, Arg1 = HLMap, Arg2 = RegA },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.inc, Arg1 = RegSP },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.inc, Arg1 = HLMap },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.dec, Arg1 = HLMap },
+			new GBInstruction() { InstSize = 2, ArgCount = 2, InstType = InstructionType.ld, Arg1 = HLMap, Arg2 = ByteArg },
+			new GBInstruction() { InstSize = 1, ArgCount = 0, InstType = InstructionType.scf },
+			new GBInstruction() { InstSize = 2, ArgCount = 2, InstType = InstructionType.jr, Arg1 = CCond, Arg2 = WordArg },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.add, Arg1 = RegHL, Arg2 = RegSP },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ldd, Arg1 = RegA, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.dec, Arg1 = RegSP },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.inc, Arg1 = RegA },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.dec, Arg1 = RegA },
+			new GBInstruction() { InstSize = 2, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegA, Arg2 = ByteArg },
+			new GBInstruction() { InstSize = 1, ArgCount = 0, InstType = InstructionType.ccf },
+			#endregion
+			#region 0x40-0x4F
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegB, Arg2 = RegB },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegB, Arg2 = RegC },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegB, Arg2 = RegD },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegB, Arg2 = RegE },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegB, Arg2 = RegH },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegB, Arg2 = RegL },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegB, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegB, Arg2 = RegA },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegC, Arg2 = RegB },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegC, Arg2 = RegC },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegC, Arg2 = RegD },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegC, Arg2 = RegE },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegC, Arg2 = RegH },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegC, Arg2 = RegL },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegC, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegC, Arg2 = RegA },
+			#endregion
+			#region 0x50-0x5F
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegD, Arg2 = RegB },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegD, Arg2 = RegC },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegD, Arg2 = RegD },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegD, Arg2 = RegE },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegD, Arg2 = RegH },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegD, Arg2 = RegL },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegD, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegD, Arg2 = RegA },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegE, Arg2 = RegB },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegE, Arg2 = RegC },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegE, Arg2 = RegD },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegE, Arg2 = RegE },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegE, Arg2 = RegH },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegE, Arg2 = RegL },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegE, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegE, Arg2 = RegA },
+			#endregion
+			#region 0x60-0x6F
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegH, Arg2 = RegB },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegH, Arg2 = RegC },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegH, Arg2 = RegD },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegH, Arg2 = RegE },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegH, Arg2 = RegH },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegH, Arg2 = RegL },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegH, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegH, Arg2 = RegA },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegL, Arg2 = RegB },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegL, Arg2 = RegC },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegL, Arg2 = RegD },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegL, Arg2 = RegE },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegL, Arg2 = RegH },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegL, Arg2 = RegL },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegL, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegL, Arg2 = RegA },
+			#endregion
+			#region 0x70-0x7F
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = HLMap, Arg2 = RegB },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = HLMap, Arg2 = RegC },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = HLMap, Arg2 = RegD },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = HLMap, Arg2 = RegE },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = HLMap, Arg2 = RegH },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = HLMap, Arg2 = RegL },
+			new GBInstruction() { InstSize = 1, ArgCount = 0, InstType = InstructionType.halt },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = HLMap, Arg2 = RegA },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegA, Arg2 = RegB },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegA, Arg2 = RegC },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegA, Arg2 = RegD },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegA, Arg2 = RegE },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegA, Arg2 = RegH },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegA, Arg2 = RegL },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegA, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegA, Arg2 = RegA },
+			#endregion
+			#region 0x80-0x8F
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.add, Arg1 = RegA, Arg2 = RegB },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.add, Arg1 = RegA, Arg2 = RegC },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.add, Arg1 = RegA, Arg2 = RegD },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.add, Arg1 = RegA, Arg2 = RegE },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.add, Arg1 = RegA, Arg2 = RegH },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.add, Arg1 = RegA, Arg2 = RegL },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.add, Arg1 = RegA, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.add, Arg1 = RegA, Arg2 = RegA },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.adc, Arg1 = RegA, Arg2 = RegB },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.adc, Arg1 = RegA, Arg2 = RegC },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.adc, Arg1 = RegA, Arg2 = RegD },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.adc, Arg1 = RegA, Arg2 = RegE },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.adc, Arg1 = RegA, Arg2 = RegH },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.adc, Arg1 = RegA, Arg2 = RegL },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.adc, Arg1 = RegA, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.adc, Arg1 = RegA, Arg2 = RegA },
+			#endregion
+			#region 0x90-0x9F
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.sub, Arg1 = RegB },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.sub, Arg1 = RegC },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.sub, Arg1 = RegD },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.sub, Arg1 = RegE },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.sub, Arg1 = RegH },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.sub, Arg1 = RegL },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.sub, Arg1 = HLMap },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.sub, Arg1 = RegA },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.sbc, Arg1 = RegA, Arg2 = RegB },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.sbc, Arg1 = RegA, Arg2 = RegC },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.sbc, Arg1 = RegA, Arg2 = RegD },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.sbc, Arg1 = RegA, Arg2 = RegE },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.sbc, Arg1 = RegA, Arg2 = RegH },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.sbc, Arg1 = RegA, Arg2 = RegL },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.sbc, Arg1 = RegA, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.sbc, Arg1 = RegA, Arg2 = RegA },
+			#endregion
+			#region 0xA0-0xAF
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.and, Arg1 = RegB },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.and, Arg1 = RegC },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.and, Arg1 = RegD },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.and, Arg1 = RegE },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.and, Arg1 = RegH },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.and, Arg1 = RegL },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.and, Arg1 = HLMap },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.and, Arg1 = RegA },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.xor, Arg1 = RegB },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.xor, Arg1 = RegC },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.xor, Arg1 = RegD },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.xor, Arg1 = RegE },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.xor, Arg1 = RegH },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.xor, Arg1 = RegL },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.xor, Arg1 = HLMap },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.xor, Arg1 = RegA },
+			#endregion
+			#region 0xB0-0xBF
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.or, Arg1 = RegB },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.or, Arg1 = RegC },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.or, Arg1 = RegD },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.or, Arg1 = RegE },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.or, Arg1 = RegH },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.or, Arg1 = RegL },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.or, Arg1 = HLMap },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.or, Arg1 = RegA },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.cp, Arg1 = RegB },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.cp, Arg1 = RegC },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.cp, Arg1 = RegD },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.cp, Arg1 = RegE },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.cp, Arg1 = RegH },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.cp, Arg1 = RegL },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.cp, Arg1 = HLMap },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.cp, Arg1 = RegA },
+			#endregion
+			#region 0xC0-0xCF
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.ret, Arg1 = NZCond },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.pop, Arg1 = RegBC },
+			new GBInstruction() { InstSize = 3, ArgCount = 2, InstType = InstructionType.jp, Arg1 = NZCond, Arg2 = WordArg },
+			new GBInstruction() { InstSize = 3, ArgCount = 1, InstType = InstructionType.jp, Arg1 = WordArg },
+			new GBInstruction() { InstSize = 3, ArgCount = 2, InstType = InstructionType.call, Arg1 = NZCond, Arg2 = WordArg },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.push, Arg1 = RegBC },
+			new GBInstruction() { InstSize = 2, ArgCount = 2, InstType = InstructionType.add, Arg1 = RegA, Arg2 = ByteArg },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.rst, Arg1 = new GBArgument(){ ArgType = GBArgumentType.Byte, NumArg = 0x00 } },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.ret, Arg1 = ZCond },
+			new GBInstruction() { InstSize = 1, ArgCount = 0, InstType = InstructionType.ret },
+			new GBInstruction() { InstSize = 3, ArgCount = 2, InstType = InstructionType.jp, Arg1 = ZCond, Arg2 = WordArg },
+			new GBInstruction() { InstSize = 2, ArgCount = 0, InstType = InstructionType.cb },
+			new GBInstruction() { InstSize = 3, ArgCount = 2, InstType = InstructionType.call, Arg1 = ZCond, Arg2 = WordArg },
+			new GBInstruction() { InstSize = 3, ArgCount = 1, InstType = InstructionType.call, Arg1 = WordArg },
+			new GBInstruction() { InstSize = 2, ArgCount = 2, InstType = InstructionType.adc, Arg1 = RegA, Arg2 = ByteArg },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.rst, Arg1 = new GBArgument(){ ArgType = GBArgumentType.Byte, NumArg = 0x08 } },
+			#endregion
+			#region 0xD0-0xDF
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.ret, Arg1 = NCCond },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.pop, Arg1 = RegDE },
+			new GBInstruction() { InstSize = 3, ArgCount = 2, InstType = InstructionType.jp, Arg1 = NCCond, Arg2 = WordArg },
+			new GBInstruction() { InstSize = 1, ArgCount = 0, InstType = InstructionType.db },
+			new GBInstruction() { InstSize = 3, ArgCount = 2, InstType = InstructionType.call, Arg1 = NCCond, Arg2 = WordArg },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.push, Arg1 = RegDE },
+			new GBInstruction() { InstSize = 2, ArgCount = 1, InstType = InstructionType.sub, Arg1 = ByteArg },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.rst, Arg1 = new GBArgument(){ ArgType = GBArgumentType.Byte, NumArg = 0x10 } },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.ret, Arg1 = CCond },
+			new GBInstruction() { InstSize = 1, ArgCount = 0, InstType = InstructionType.reti },
+			new GBInstruction() { InstSize = 3, ArgCount = 2, InstType = InstructionType.jp, Arg1 = CCond, Arg2 = WordArg },
+			new GBInstruction() { InstSize = 1, ArgCount = 0, InstType = InstructionType.db },
+			new GBInstruction() { InstSize = 3, ArgCount = 2, InstType = InstructionType.call, Arg1 = CCond, Arg2 = WordArg },
+			new GBInstruction() { InstSize = 1, ArgCount = 0, InstType = InstructionType.db },
+			new GBInstruction() { InstSize = 2, ArgCount = 2, InstType = InstructionType.sbc, Arg1 = RegA, Arg2 = ByteArg },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.rst, Arg1 = new GBArgument(){ ArgType = GBArgumentType.Byte, NumArg = 0x18 } },
+			#endregion
+			#region 0xE0-0xEF
+			new GBInstruction() { InstSize = 2, ArgCount = 2, InstType = InstructionType.ld, Arg1 = MemMapArg, Arg2 = RegA },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.pop, Arg1 = RegHL },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = CMap, Arg2 = RegA },
+			new GBInstruction() { InstSize = 1, ArgCount = 0, InstType = InstructionType.db },
+			new GBInstruction() { InstSize = 1, ArgCount = 0, InstType = InstructionType.db },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.push, Arg1 = RegHL },
+			new GBInstruction() { InstSize = 2, ArgCount = 1, InstType = InstructionType.and, Arg1 = ByteArg },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.rst, Arg1 = new GBArgument(){ ArgType = GBArgumentType.Byte, NumArg = 0x20 } },
+			new GBInstruction() { InstSize = 2, ArgCount = 2, InstType = InstructionType.add, Arg1 = RegSP, Arg2 = ByteArg },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.jp, Arg1 = RegHL },
+			new GBInstruction() { InstSize = 3, ArgCount = 2, InstType = InstructionType.ld, Arg1 = MemMapArg, Arg2 = RegA },
+			new GBInstruction() { InstSize = 1, ArgCount = 0, InstType = InstructionType.db },
+			new GBInstruction() { InstSize = 1, ArgCount = 0, InstType = InstructionType.db },
+			new GBInstruction() { InstSize = 1, ArgCount = 0, InstType = InstructionType.db },
+			new GBInstruction() { InstSize = 2, ArgCount = 1, InstType = InstructionType.xor, Arg1 = ByteArg },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.rst, Arg1 = new GBArgument(){ ArgType = GBArgumentType.Byte, NumArg = 0x28 } },
+			#endregion
+			#region 0xF0-0xFF
+			new GBInstruction() { InstSize = 2, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegA, Arg2 = MemMapArg },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.pop, Arg1 = RegAF },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegA, Arg2 = CMap },
+			new GBInstruction() { InstSize = 1, ArgCount = 0, InstType = InstructionType.di },
+			new GBInstruction() { InstSize = 1, ArgCount = 0, InstType = InstructionType.db },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.push, Arg1 = RegAF },
+			new GBInstruction() { InstSize = 2, ArgCount = 1, InstType = InstructionType.or, Arg1 = ByteArg },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.rst, Arg1 = new GBArgument(){ ArgType = GBArgumentType.Byte, NumArg = 0x30 } },
+			new GBInstruction() { InstSize = 2, ArgCount = 2, InstType = InstructionType.ldhl, Arg1 = RegSP, Arg2 = ByteArg },
+			new GBInstruction() { InstSize = 1, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegSP, Arg2 = RegHL },
+			new GBInstruction() { InstSize = 3, ArgCount = 2, InstType = InstructionType.ld, Arg1 = RegA, Arg2 = MemMapArg },
+			new GBInstruction() { InstSize = 1, ArgCount = 0, InstType = InstructionType.ei },
+			new GBInstruction() { InstSize = 1, ArgCount = 0, InstType = InstructionType.db },
+			new GBInstruction() { InstSize = 1, ArgCount = 0, InstType = InstructionType.db },
+			new GBInstruction() { InstSize = 2, ArgCount = 1, InstType = InstructionType.cp, Arg1 = ByteArg },
+			new GBInstruction() { InstSize = 1, ArgCount = 1, InstType = InstructionType.rst, Arg1 = new GBArgument(){ ArgType = GBArgumentType.Byte, NumArg = 0x38 } }
+			#endregion
+		};
+
+		#endregion Regular Instructions
+
+		#region CB Instructions
+
+		internal static GBInstruction[] CBInstructionUnitTable = new GBInstruction[256]
+		{
+			//00-0F
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.rlc, ArgCount = 1, Arg1 = RegB },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.rlc, ArgCount = 1, Arg1 = RegC },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.rlc, ArgCount = 1, Arg1 = RegD },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.rlc, ArgCount = 1, Arg1 = RegE },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.rlc, ArgCount = 1, Arg1 = RegH },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.rlc, ArgCount = 1, Arg1 = RegL },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.rlc, ArgCount = 1, Arg1 = HLMap },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.rlc, ArgCount = 1, Arg1 = RegA },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.rrc, ArgCount = 1, Arg1 = RegB },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.rrc, ArgCount = 1, Arg1 = RegC },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.rrc, ArgCount = 1, Arg1 = RegD },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.rrc, ArgCount = 1, Arg1 = RegE },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.rrc, ArgCount = 1, Arg1 = RegH },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.rrc, ArgCount = 1, Arg1 = RegL },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.rrc, ArgCount = 1, Arg1 = HLMap },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.rrc, ArgCount = 1, Arg1 = RegA },
+			//10-1F
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.rl, ArgCount = 1, Arg1 = RegB },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.rl, ArgCount = 1, Arg1 = RegC },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.rl, ArgCount = 1, Arg1 = RegD },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.rl, ArgCount = 1, Arg1 = RegE },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.rl, ArgCount = 1, Arg1 = RegH },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.rl, ArgCount = 1, Arg1 = RegL },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.rl, ArgCount = 1, Arg1 = HLMap },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.rl, ArgCount = 1, Arg1 = RegA },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.rr, ArgCount = 1, Arg1 = RegB },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.rr, ArgCount = 1, Arg1 = RegC },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.rr, ArgCount = 1, Arg1 = RegD },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.rr, ArgCount = 1, Arg1 = RegE },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.rr, ArgCount = 1, Arg1 = RegH },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.rr, ArgCount = 1, Arg1 = RegL },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.rr, ArgCount = 1, Arg1 = HLMap },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.rr, ArgCount = 1, Arg1 = RegA },
+			//20-2F
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.sla, ArgCount = 1, Arg1 = RegB },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.sla, ArgCount = 1, Arg1 = RegC },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.sla, ArgCount = 1, Arg1 = RegD },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.sla, ArgCount = 1, Arg1 = RegE },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.sla, ArgCount = 1, Arg1 = RegH },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.sla, ArgCount = 1, Arg1 = RegL },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.sla, ArgCount = 1, Arg1 = HLMap },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.sla, ArgCount = 1, Arg1 = RegA },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.sra, ArgCount = 1, Arg1 = RegB },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.sra, ArgCount = 1, Arg1 = RegC },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.sra, ArgCount = 1, Arg1 = RegD },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.sra, ArgCount = 1, Arg1 = RegE },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.sra, ArgCount = 1, Arg1 = RegH },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.sra, ArgCount = 1, Arg1 = RegL },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.sra, ArgCount = 1, Arg1 = HLMap },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.sra, ArgCount = 1, Arg1 = RegA },
+			//30-3F
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.swap, ArgCount = 1, Arg1 = RegB },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.swap, ArgCount = 1, Arg1 = RegC },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.swap, ArgCount = 1, Arg1 = RegD },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.swap, ArgCount = 1, Arg1 = RegE },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.swap, ArgCount = 1, Arg1 = RegH },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.swap, ArgCount = 1, Arg1 = RegL },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.swap, ArgCount = 1, Arg1 = HLMap },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.swap, ArgCount = 1, Arg1 = RegA },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.srl, ArgCount = 1, Arg1 = RegB },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.srl, ArgCount = 1, Arg1 = RegC },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.srl, ArgCount = 1, Arg1 = RegD },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.srl, ArgCount = 1, Arg1 = RegE },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.srl, ArgCount = 1, Arg1 = RegH },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.srl, ArgCount = 1, Arg1 = RegL },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.srl, ArgCount = 1, Arg1 = HLMap },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.srl, ArgCount = 1, Arg1 = RegA },
+			//40-4F
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg0, Arg2 = RegB },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg0, Arg2 = RegC },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg0, Arg2 = RegD },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg0, Arg2 = RegE },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg0, Arg2 = RegH },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg0, Arg2 = RegL },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg0, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg0, Arg2 = RegA },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg1, Arg2 = RegB },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg1, Arg2 = RegC },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg1, Arg2 = RegD },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg1, Arg2 = RegE },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg1, Arg2 = RegH },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg1, Arg2 = RegL },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg1, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg1, Arg2 = RegA },
+			//50-5F
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg2, Arg2 = RegB },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg2, Arg2 = RegC },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg2, Arg2 = RegD },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg2, Arg2 = RegE },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg2, Arg2 = RegH },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg2, Arg2 = RegL },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg2, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg2, Arg2 = RegA },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg3, Arg2 = RegB },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg3, Arg2 = RegC },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg3, Arg2 = RegD },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg3, Arg2 = RegE },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg3, Arg2 = RegH },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg3, Arg2 = RegL },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg3, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg3, Arg2 = RegA },
+			//60-6F
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg4, Arg2 = RegB },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg4, Arg2 = RegC },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg4, Arg2 = RegD },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg4, Arg2 = RegE },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg4, Arg2 = RegH },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg4, Arg2 = RegL },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg4, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg4, Arg2 = RegA },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg5, Arg2 = RegB },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg5, Arg2 = RegC },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg5, Arg2 = RegD },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg5, Arg2 = RegE },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg5, Arg2 = RegH },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg5, Arg2 = RegL },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg5, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg5, Arg2 = RegA },
+			//70-7F
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg6, Arg2 = RegB },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg6, Arg2 = RegC },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg6, Arg2 = RegD },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg6, Arg2 = RegE },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg6, Arg2 = RegH },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg6, Arg2 = RegL },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg6, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg6, Arg2 = RegA },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg7, Arg2 = RegB },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg7, Arg2 = RegC },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg7, Arg2 = RegD },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg7, Arg2 = RegE },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg7, Arg2 = RegH },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg7, Arg2 = RegL },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg7, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.bit, ArgCount = 2, Arg1 = BitArg7, Arg2 = RegA },
+			//80-8F
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg0, Arg2 = RegB },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg0, Arg2 = RegC },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg0, Arg2 = RegD },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg0, Arg2 = RegE },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg0, Arg2 = RegH },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg0, Arg2 = RegL },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg0, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg0, Arg2 = RegA },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg1, Arg2 = RegB },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg1, Arg2 = RegC },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg1, Arg2 = RegD },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg1, Arg2 = RegE },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg1, Arg2 = RegH },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg1, Arg2 = RegL },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg1, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg1, Arg2 = RegA },
+			//90-9F
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg2, Arg2 = RegB },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg2, Arg2 = RegC },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg2, Arg2 = RegD },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg2, Arg2 = RegE },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg2, Arg2 = RegH },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg2, Arg2 = RegL },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg2, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg2, Arg2 = RegA },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg3, Arg2 = RegB },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg3, Arg2 = RegC },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg3, Arg2 = RegD },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg3, Arg2 = RegE },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg3, Arg2 = RegH },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg3, Arg2 = RegL },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg3, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg3, Arg2 = RegA },
+			//A0-AF
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg4, Arg2 = RegB },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg4, Arg2 = RegC },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg4, Arg2 = RegD },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg4, Arg2 = RegE },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg4, Arg2 = RegH },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg4, Arg2 = RegL },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg4, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg4, Arg2 = RegA },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg5, Arg2 = RegB },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg5, Arg2 = RegC },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg5, Arg2 = RegD },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg5, Arg2 = RegE },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg5, Arg2 = RegH },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg5, Arg2 = RegL },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg5, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg5, Arg2 = RegA },
+			//B0-BF
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg6, Arg2 = RegB },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg6, Arg2 = RegC },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg6, Arg2 = RegD },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg6, Arg2 = RegE },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg6, Arg2 = RegH },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg6, Arg2 = RegL },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg6, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg6, Arg2 = RegA },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg7, Arg2 = RegB },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg7, Arg2 = RegC },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg7, Arg2 = RegD },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg7, Arg2 = RegE },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg7, Arg2 = RegH },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg7, Arg2 = RegL },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg7, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.res, ArgCount = 2, Arg1 = BitArg7, Arg2 = RegA },
+			//C0-CF
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg0, Arg2 = RegB },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg0, Arg2 = RegC },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg0, Arg2 = RegD },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg0, Arg2 = RegE },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg0, Arg2 = RegH },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg0, Arg2 = RegL },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg0, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg0, Arg2 = RegA },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg1, Arg2 = RegB },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg1, Arg2 = RegC },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg1, Arg2 = RegD },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg1, Arg2 = RegE },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg1, Arg2 = RegH },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg1, Arg2 = RegL },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg1, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg1, Arg2 = RegA },
+			//D0-DF
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg2, Arg2 = RegB },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg2, Arg2 = RegC },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg2, Arg2 = RegD },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg2, Arg2 = RegE },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg2, Arg2 = RegH },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg2, Arg2 = RegL },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg2, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg2, Arg2 = RegA },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg3, Arg2 = RegB },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg3, Arg2 = RegC },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg3, Arg2 = RegD },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg3, Arg2 = RegE },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg3, Arg2 = RegH },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg3, Arg2 = RegL },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg3, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg3, Arg2 = RegA },
+			//E0-EF
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg4, Arg2 = RegB },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg4, Arg2 = RegC },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg4, Arg2 = RegD },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg4, Arg2 = RegE },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg4, Arg2 = RegH },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg4, Arg2 = RegL },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg4, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg4, Arg2 = RegA },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg5, Arg2 = RegB },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg5, Arg2 = RegC },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg5, Arg2 = RegD },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg5, Arg2 = RegE },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg5, Arg2 = RegH },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg5, Arg2 = RegL },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg5, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg5, Arg2 = RegA },
+			//F0-FF
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg6, Arg2 = RegB },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg6, Arg2 = RegC },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg6, Arg2 = RegD },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg6, Arg2 = RegE },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg6, Arg2 = RegH },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg6, Arg2 = RegL },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg6, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg6, Arg2 = RegA },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg7, Arg2 = RegB },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg7, Arg2 = RegC },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg7, Arg2 = RegD },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg7, Arg2 = RegE },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg7, Arg2 = RegH },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg7, Arg2 = RegL },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg7, Arg2 = HLMap },
+			new GBInstruction() { InstSize = 2, InstType = InstructionType.set, ArgCount = 2, Arg1 = BitArg7, Arg2 = RegA },
+		};
+
+		#endregion CB Instructions
+	}
+}

gbread/ASM/InstructionUnit.cs

+//Copyright © 2012 Silenthal
+
+//This file is part of LibGBasm.
+//LibGBasm is free software: you can redistribute it and/or modify
+//it under the terms of the GNU Lesser General Public License as published by
+//the Free Software Foundation, either version 3 of the License, or
+//(at your option) any later version.
+
+//LibGBasm 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 Lesser General Public License for more details.
+
+//You should have received a copy of the GNU Lesser General Public License
+//along with LibGBasm.  If not, see <http://www.gnu.org/licenses/>.
+namespace LibGBasm
+{
+	/// <summary>
+	/// Represents the type of instruction.
+	/// </summary>
+	public enum InstructionType { adc, add, and, bit, call, ccf, cb, cp, cpl, db, dw, ei, daa, dec, di, halt, inc, jp, jr, ld, ldi, ldd, ldhl, nop, or, pop, push, res, ret, reti, rl, rla, rlc, rlca, rot, rr, rra, rrc, rrca, rst, sbc, scf, set, sla, sra, srl, stop, sub, swap, xor }
+
+	/// <summary>
+	/// The type of a GBArgument. Depending on the type of argument, the values within are interpreted differently.
+	/// </summary>
+	public enum GBArgumentType { None, Bit, Byte, Word, MemMapWord, Conditional, RegisterSingle, MemMapRegisterSingle, RegisterDouble, MemMapRegisterDouble }
+
+	/// <summary>
+	/// Represents a single register.
+	/// </summary>
+	public enum GBRegisterSingle { a, b, c, d, e, h, l }
+
+	//Represents a register pair.
+	public enum GBRegisterDouble { af, bc, de, hl, sp }
+
+	/// <summary>
+	/// Represents a conditional statement.
+	/// </summary>
+	public enum GBConditional { nz, z, nc, c }
+
+	/// <summary>
+	/// Represents a single GB instruction.
+	/// </summary>
+	public struct GBInstruction
+	{
+		/// <summary>
+		/// The bank containing the instruction.
+		/// </summary>
+		public byte Bank;
+		/// <summary>
+		/// The address of the instruction.
+		/// </summary>
+		public ushort Address;
+		/// <summary>
+		/// The size of the argument, in bytes.
+		/// </summary>
+		public int InstSize;
+		/// <summary>
+		/// The type of instruction.
+		/// </summary>
+		public InstructionType InstType;
+		/// <summary>
+		/// The number of arguments to this instruction.
+		/// </summary>
+		public int ArgCount;
+		/// <summary>
+		/// The first argument of the instruction.
+		/// </summary>
+		public GBArgument Arg1;
+		/// <summary>
+		/// The second argument of the instruction.
+		/// </summary>
+		public GBArgument Arg2;
+	}
+
+	/// <summary>
+	/// Represents an argument to a GB instruction.
+	/// </summary>
+	public struct GBArgument
+	{
+		/// <summary>
+		/// The type of argument.
+		/// </summary>
+		public GBArgumentType ArgType;
+		/// <summary>
+		/// The number value of the argument.
+		/// </summary>
+		public ushort NumArg;
+		/// <summary>
+		/// The RegisterSingle value of the argument, if it has one.
+		/// </summary>
+		public GBRegisterSingle RegSingleArg;
+		/// <summary>
+		/// The RegisterDouble value of the argument, if it has one.
+		/// </summary>
+		public GBRegisterDouble RegDoubleArg;
+		/// <summary>
+		/// The Conditional value of the argument, if it has one.
+		/// </summary>
+		public GBConditional CondArg;
+	}
+}

gbread/ASM/LibGBasm.cs

+//Copyright © 2012 Silenthal
+
+//This file is part of LibGBasm.
+//LibGBasm is free software: you can redistribute it and/or modify
+//it under the terms of the GNU Lesser General Public License as published by
+//the Free Software Foundation, either version 3 of the License, or
+//(at your option) any later version.
+
+//LibGBasm 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 Lesser General Public License for more details.
+
+//You should have received a copy of the GNU Lesser General Public License
+//along with LibGBasm.  If not, see <http://www.gnu.org/licenses/>.
+namespace LibGBasm
+{
+	public class GBASM
+	{
+		/// <summary>
+		/// Given a binary file and the appropriate offsets, constructs a GBInstructionUnit containing information about the instruction and its arguments.
+		/// </summary>
+		/// <param name="baseFile">The file to read from.</param>
+		/// <param name="org">The origin address of the file.</param>
+		/// <param name="offset">The offset into the file to read from.</param>
+		/// <param name="outputInstruction">The GBInstruction to write the information to.</param>
+		/// <returns>The success of the operation. Returns false if the information fetching went wrong for any reason
+		/// </returns>
+		public static bool GetInstruction(byte[] baseFile, int org, int offset, ref GBInstruction outputInstruction)
+		{
+			outputInstruction = new GBInstruction();
+			if (baseFile == null || offset > baseFile.Length - 1) return false;
+			byte inst = baseFile[offset];
+			int address = org + offset;
+			if (inst == 0xCB)
+			{
+				if (offset > baseFile.Length - 2) return false;
+				outputInstruction = GBInstructions.CBInstructionUnitTable[baseFile[offset + 1]];
+			}
+			else outputInstruction = GBInstructions.InstructionUnitTable[baseFile[offset]];
+			if (offset + outputInstruction.InstSize > baseFile.Length) return false;
+			outputInstruction.Bank = (byte)(address >> 14);
+			outputInstruction.Address = (ushort)(address & 0x3FFF);
+			if (address > 0x4000)
+			{
+				outputInstruction.Address += 0x4000;
+			}
+			if (outputInstruction.InstSize == 1 && outputInstruction.InstType == InstructionType.db)
+			{
+				outputInstruction.ArgCount = 1;
+				outputInstruction.Arg1.ArgType = GBArgumentType.Byte;
+				outputInstruction.Arg1.NumArg = baseFile[offset];
+			}
+			else if (outputInstruction.InstSize == 2 && inst != 0xCB)
+			{
+				if (outputInstruction.ArgCount == 1)
+				{
+					if (outputInstruction.InstType == InstructionType.jr)
+					{
+						//jr nn
+						int modifier = (baseFile[offset + 1] < 0x80 ? baseFile[offset + 1] : -(0x100 - baseFile[offset + 1]));
+						ushort newAddress = (ushort)(outputInstruction.Address + 2 + modifier);
+						outputInstruction.Arg1.NumArg = newAddress;
+					}
+					else
+					{
+						//and, or, sub, cp, xor nn
+						outputInstruction.Arg1.NumArg = baseFile[offset + 1];
+					}
+				}
+				else if (outputInstruction.ArgCount == 2)
+				{
+					if (outputInstruction.InstType == InstructionType.jr)
+					{
+						//jr nn
+						int modifier = (baseFile[offset + 1] < 0x80 ? baseFile[offset + 1] : -(0x100 - baseFile[offset + 1]));
+						ushort newAddress = (ushort)(outputInstruction.Address + 2 + modifier);
+						outputInstruction.Arg2.NumArg = newAddress;
+					}
+					else if (outputInstruction.Arg1.ArgType == GBArgumentType.MemMapWord)
+					{
+						outputInstruction.Arg1.NumArg = (ushort)(0xFF00 + baseFile[offset + 1]);
+					}
+					else if (outputInstruction.Arg2.ArgType == GBArgumentType.MemMapWord)
+					{
+						outputInstruction.Arg2.NumArg = (ushort)(0xFF00 + baseFile[offset + 1]);
+					}
+					else
+					{
+						outputInstruction.Arg2.NumArg = baseFile[offset + 1];
+					}
+				}
+			}
+			else if (outputInstruction.InstSize == 3)
+			{
+				if (outputInstruction.ArgCount == 1 && outputInstruction.Arg1.ArgType == GBArgumentType.Word)
+				{
+					//jp nnnn, call nnnn
+					outputInstruction.Arg1.NumArg = System.BitConverter.ToUInt16(baseFile, offset + 1);
+				}
+				else if (outputInstruction.ArgCount == 2)
+				{
+					if (outputInstruction.Arg1.ArgType == GBArgumentType.MemMapWord)
+					{
+						outputInstruction.Arg1.NumArg = System.BitConverter.ToUInt16(baseFile, offset + 1);
+					}
+					else if (outputInstruction.Arg2.ArgType == GBArgumentType.Word ||
+						outputInstruction.Arg2.ArgType == GBArgumentType.MemMapWord)
+					{
+						outputInstruction.Arg2.NumArg = System.BitConverter.ToUInt16(baseFile, offset + 1);
+					}
+				}
+			}
+			return true;
+		}
+
+		/// <summary>
+		/// Creates a byte-sized data instruction.
+		/// </summary>
+		/// <param name="baseFile">The file to read from.</param>
+		/// <param name="org">The origin address of the file.</param>
+		/// <param name="offset">The offset into the file to read from.</param>
+		/// <param name="outputInstruction">The GBInstruction to write the information to.</param>
+		/// <returns>The success of the operation. Returns false if the information fetching went wrong for any reason.
+		/// </returns>
+		public static bool CreateDBInstruction(byte[] baseFile, int org, int offset, ref GBInstruction outputInstruction)
+		{
+			outputInstruction = new GBInstruction();
+			if (baseFile == null || offset > baseFile.Length - 1) return false;
+			int address = org + offset;
+			outputInstruction.InstSize = 1;
+			outputInstruction.InstType = InstructionType.db;
+			outputInstruction.Bank = (byte)(address >> 14);
+			outputInstruction.Address = (ushort)(address & 0x3FFF);
+			outputInstruction.ArgCount = 1;
+			outputInstruction.Arg1.ArgType = GBArgumentType.Byte;
+			outputInstruction.Arg1.NumArg = baseFile[offset];
+			if (address > 0x4000)
+			{
+				outputInstruction.Address += 0x4000;
+			}
+			return true;
+		}
+
+		/// <summary>
+		/// Creates a word-sized data instruction.
+		/// </summary>
+		/// <param name="baseFile">The file to read from.</param>
+		/// <param name="org">The origin address of the file.</param>
+		/// <param name="offset">The offset into the file to read from.</param>
+		/// <param name="outputInstruction">The GBInstruction to write the information to.</param>
+		/// <returns>The success of the operation. Returns false if the information fetching went wrong for any reason.
+		/// </returns>
+		public static bool CreateDWInstruction(byte[] baseFile, int org, int offset, ref GBInstruction outputInstruction)
+		{
+			outputInstruction = new GBInstruction();
+			if (baseFile == null || offset > baseFile.Length - 2) return false;
+			int address = org + offset;
+			outputInstruction.InstSize = 2;
+			outputInstruction.InstType = InstructionType.dw;
+			outputInstruction.Bank = (byte)(address >> 14);
+			outputInstruction.Address = (ushort)(address & 0x3FFF);
+			outputInstruction.ArgCount = 1;
+			outputInstruction.Arg1.ArgType = GBArgumentType.Word;
+			outputInstruction.Arg1.NumArg = System.BitConverter.ToUInt16(baseFile, offset);
+			if (address > 0x4000)
+			{
+				outputInstruction.Address += 0x4000;
+			}
+			return true;
+		}
+	}
+}

gbread/Base/Assembler.cs

 
 		public enum TokenType
 		{
+			EQUAL, 
+			COMMA, 
 			CONDITION,
 			INSTRUCTION,
 			LABEL,

gbread/Base/Disassembler.cs

 
 namespace GBRead.Base
 {
-	public class Disassembler
-	{
-		private BinFile CoreFile;
+    public class Disassembler
+    {
+        private BinFile CoreFile;
 
-		private LabelContainer lc;
+        private LabelContainer lc;
 
-		#region Options
+        private Dictionary<int, GBInstruction> instructionCache;
 
-		public bool PrintOffsets { get; set; }
+        #region Options
 
-		public bool PrintBitPattern { get; set; }
+        public bool PrintOffsets { get; set; }
 
-		public OffsetFormat PrintedOffsetFormat { get; set; }
+        public bool PrintBitPattern { get; set; }
 
-		public OffsetFormat InstructionNumberFormat { get; set; }
+        public OffsetFormat PrintedOffsetFormat { get; set; }
 
-		public bool PrintComments { get; set; }
+        public OffsetFormat InstructionNumberFormat { get; set; }
 
-		public bool HideDefinedFunctions { get; set; }
+        public bool PrintComments { get; set; }
 
-		public bool HideDefinedData { get; set; }
+        public bool HideDefinedFunctions { get; set; }
 
-		#endregion Options
+        public bool HideDefinedData { get; set; }
 
-		public Disassembler(BinFile cs, LabelContainer lcs)
-		{
-			CoreFile = cs;
-			lc = lcs;
-			PrintOffsets = true;
-			PrintedOffsetFormat = OffsetFormat.BBOO;
-			InstructionNumberFormat = OffsetFormat.Hex;
-			PrintBitPattern = true;
-			PrintComments = false;
-			HideDefinedData = false;
-			HideDefinedFunctions = false;
-		}
+        #endregion Options
 
-		#region Getting and Setting Options
+        public Disassembler(BinFile cs, LabelContainer lcs)
+        {
+            CoreFile = cs;
+            lc = lcs;
+            instructionCache = new Dictionary<int, GBInstruction>();
+            PrintOffsets = true;
+            PrintedOffsetFormat = OffsetFormat.BankOffset;
+            InstructionNumberFormat = OffsetFormat.Hex;
+            PrintBitPattern = true;
+            PrintComments = false;
+            HideDefinedData = false;
+            HideDefinedFunctions = false;
+        }
 
-		public void GetOptions(Options options)
-		{
-			PrintOffsets = options.Disassembler_PrintOffsets;
-			PrintBitPattern = options.Disassembler_PrintBitPattern;
-			PrintedOffsetFormat = options.Disassembler_PrintedOffsetFormat;
-			InstructionNumberFormat = options.Disassembler_InstructionNumberFormat;
-			PrintComments = options.Disassembler_PrintComments;
-			HideDefinedFunctions = options.Disassembler_HideDefinedFunctions;
-			HideDefinedData = options.Disassembler_HideDefinedData;
-		}
+        #region Getting and Setting Options
 
-		public void SetOptions(ref Options options)
-		{
-			options.Disassembler_PrintOffsets = PrintOffsets;
-			options.Disassembler_PrintBitPattern = PrintBitPattern;
-			options.Disassembler_PrintedOffsetFormat = PrintedOffsetFormat;
-			options.Disassembler_InstructionNumberFormat = InstructionNumberFormat;
-			options.Disassembler_PrintComments = PrintComments;
-			options.Disassembler_HideDefinedFunctions = HideDefinedFunctions;
-			options.Disassembler_HideDefinedData = HideDefinedData;
-		}
+        public void GetOptions(Options options)
+        {
+            PrintOffsets = options.Disassembler_PrintOffsets;
+            PrintBitPattern = options.Disassembler_PrintBitPattern;
+            PrintedOffsetFormat = options.Disassembler_PrintedOffsetFormat;
+            InstructionNumberFormat = options.Disassembler_InstructionNumberFormat;
+            PrintComments = options.Disassembler_PrintComments;
+            HideDefinedFunctions = options.Disassembler_HideDefinedFunctions;
+            HideDefinedData = options.Disassembler_HideDefinedData;
+        }
 
-		#endregion Getting and Setting Options
+        public void SetOptions(ref Options options)
+        {
+            options.Disassembler_PrintOffsets = PrintOffsets;
+            options.Disassembler_PrintBitPattern = PrintBitPattern;
+            options.Disassembler_PrintedOffsetFormat = PrintedOffsetFormat;
+            options.Disassembler_InstructionNumberFormat = InstructionNumberFormat;
+            options.Disassembler_PrintComments = PrintComments;
+            options.Disassembler_HideDefinedFunctions = HideDefinedFunctions;
+            options.Disassembler_HideDefinedData = HideDefinedData;
+        }
 
-		#region Label Display
+        #endregion Getting and Setting Options
 
-		public string ShowDataLabel(DataLabel dLabel)
-		{
-			StringBuilder ret = new StringBuilder(String.Empty);
-			int off = dLabel.Offset;
-			ret.AppendLine(dLabel.ToASMCommentString());
-			switch (dLabel.DSectionType)
-			{
-				case DataSectionType.Data:
-				case DataSectionType.Image:
-					for (int i = 0; i < dLabel.Length; i++)
-					{
-						if (i % dLabel.DataLineLength == 0) ret.Append("\tdb ");
-						byte x = (byte)CoreFile.ReadByte(off + i);
-						switch (InstructionNumberFormat)
-						{
-							case OffsetFormat.Decimal:
-								ret.Append(x.ToString());
-								break;
-							default:
-								ret.Append("$" + x.ToString("X2"));
-								break;
-						}
-						if (i % dLabel.DataLineLength == dLabel.DataLineLength - 1 || i == dLabel.Length - 1)
-						{
-							ret.AppendLine();
-						}
-						else
-						{
-							ret.Append(",");
-						}
-					}
-					break;
-				default:
-					break;
-			}
-			return ret.ToString();
-		}
+        #region Label Display
 
-		public string ShowFuncLabel(FunctionLabel cLabel)
-		{
-			StringBuilder ret = new StringBuilder(String.Empty);
-			int currentOffset = cLabel.Offset;
-			int guessedLength = GuessFunctionLength(cLabel);
-			ret.AppendLine(cLabel.ToASMCommentString());
-			while (currentOffset < cLabel.Offset + guessedLength)
-			{
-				GBInstruction isu = new GBInstruction();
-				if (lc.isAddressMarkedAsData(currentOffset))
-				{
-					DataLabel dl = (DataLabel)lc.TryGetDataLabel(currentOffset);
-					ret.Append(ShowDataLabel(dl));
-					currentOffset += dl.Length;
-					continue;
-				}
-				else
-				{
-					ret.AppendLine(GetInstruction(CoreFile, 0, currentOffset, ref isu));
-					currentOffset += isu.InstSize;
-				}
-			}
-			return ret.ToString();
-		}
+        public string ShowDataLabel(DataLabel dLabel)
+        {
+            StringBuilder ret = new StringBuilder(String.Empty);
+            int off = dLabel.Offset;
+            ret.AppendLine(dLabel.ToASMCommentString());
+            switch (dLabel.DSectionType)
+            {
+                case DataSectionType.Data:
+                case DataSectionType.Image:
+                    for (int i = 0; i < dLabel.Length; i++)
+                    {
+                        if (i % dLabel.DataLineLength == 0)
+                            ret.Append("\tdb ");
+                        byte x = (byte)CoreFile.ReadByte(off + i);
+                        switch (InstructionNumberFormat)
+                        {
+                            case OffsetFormat.Decimal:
+                                ret.Append(x.ToString());
+                                break;
+                            default:
+                                ret.Append("$" + x.ToString("X2"));
+                                break;
+                        }
+                        if (i % dLabel.DataLineLength == dLabel.DataLineLength - 1 || i == dLabel.Length - 1)
+                        {
+                            ret.AppendLine();
+                        }
+                        else
+                        {
+                            ret.Append(",");
+                        }
+                    }
+                    break;
+                default:
+                    break;
+            }
+            return ret.ToString();
+        }
 
-		public string ShowVarLabel(VarLabel vLabel)
-		{
-			StringBuilder ret = new StringBuilder();
-			ret.AppendLine(vLabel.ToDisplayString());
-			ret.AppendLine(SearchForReference(vLabel));
-			return ret.ToString();
-		}
+        public string ShowFuncLabel(FunctionLabel cLabel)
+        {
+            StringBuilder ret = new StringBuilder(String.Empty);
+            int currentOffset = cLabel.Offset;
+            int guessedLength = GuessFunctionLength(cLabel);
+            ret.AppendLine(cLabel.ToASMCommentString());
+            while (currentOffset < cLabel.Offset + guessedLength)
+            {
+                GBInstruction isu = new GBInstruction();
+                if (lc.isAddressMarkedAsData(currentOffset))
+                {
+                    DataLabel dl;
+                    lc.TryGetDataLabel(currentOffset, out dl);
+                    ret.Append(ShowDataLabel(dl));
+                    currentOffset += dl.Length;
+                    continue;
+                }
+                else
+                {
+                    ret.AppendLine(GetInstruction(CoreFile, 0, currentOffset, ref isu));
+                    currentOffset += isu.InstSize;
+                }
+            }
+            return ret.ToString();
+        }
 
-		#endregion Label Display
+        public string ShowVarLabel(VarLabel vLabel)
+        {
+            StringBuilder ret = new StringBuilder();
+            ret.AppendLine(vLabel.ToDisplayString());
+            ret.AppendLine(SearchForReference(vLabel));
+            return ret.ToString();
+        }
 
-		#region Disassembly
+        #endregion Label Display
 
-		public string PrintASM(int start, int length)
-		{
-			return PrintASM(CoreFile, 0, start, length);
-		}
+        #region Disassembly
 
-		public string PrintASM(BinFile file, int baseOffset, int start, int length)
-		{
-			StringBuilder output = new StringBuilder(String.Empty);
-			int current = start;
-			DataLabel dataSearch = new DataLabel(current);
-			FunctionLabel codeSearch = new FunctionLabel(current);
-			GBInstruction isu = new GBInstruction();
-			while (current < start + length)
-			{
-				byte currentInst = (byte)file.ReadByte(current);
-				codeSearch = lc.TryGetFuncLabel(current);
-				dataSearch = lc.TryGetDataLabel(current);
-				if (dataSearch != null)
-				{
-					if (HideDefinedData)
-					{
-						output.AppendLine(String.Format("INCBIN \"{0}.bin\"", dataSearch.Name));
-					}
-					else
-					{
-						output.Append(ShowDataLabel(dataSearch));
-					}
-					current += dataSearch.Length;
-				}
-				else if (codeSearch != null)
-				{
-					output.AppendLine(codeSearch.ToASMCommentString());
-					output.AppendLine(GetInstruction(file, baseOffset, current, ref isu));
-					current += isu.InstSize;
-				}
-				else
-				{
-					output.AppendLine(GetInstruction(file, baseOffset, current, ref isu));
-					current += isu.InstSize;
-				}
-			}
-			return output.ToString();
-		}
+        public string PrintASM(int start, int length)
+        {
+            return PrintASM(CoreFile, 0, start, length);
+        }
 
-		private string GetInstruction(BinFile refFile, int OrgOffset, int BinaryOffset, ref GBInstruction isu)
-		{
-			bool success = false;
-			if (lc.isAddressMarkedAsData(OrgOffset + BinaryOffset))
-			{
-				success = GBASM.CreateDBInstruction(refFile.MainFile, OrgOffset, BinaryOffset, ref isu);
-			}
-			else success = GBASM.GetInstruction(refFile.MainFile, OrgOffset, BinaryOffset, ref isu);
-			if (!success) return "--Error--";
-			StringBuilder returned = new StringBuilder();
+        public string PrintASM(BinFile file, int baseOffset, int start, int length)
+        {
+            StringBuilder output = new StringBuilder(String.Empty);
+            int current = start;
+            DataLabel dataSearch = new DataLabel(current);
+            FunctionLabel codeSearch = new FunctionLabel(current);
+            GBInstruction isu = new GBInstruction();
+            while (current < start + length)
+            {
+                byte currentInst = (byte)file.ReadByte(current);
+                if (lc.TryGetDataLabel(current, out dataSearch))
+                {
+                    if (HideDefinedData)
+                    {
+                        output.AppendLine(String.Format("INCBIN \"{0}.bin\"", dataSearch.Name));
+                    }
+                    else
+                    {
+                        output.Append(ShowDataLabel(dataSearch));
+                    }
+                    current += dataSearch.Length;
+                }
+                else if (lc.TryGetFuncLabel(current, out codeSearch))
+                {
+                    output.AppendLine(codeSearch.ToASMCommentString());
+                    output.AppendLine(GetInstruction(file, baseOffset, current, ref isu));
+                    current += isu.InstSize;
+                }
+                else
+                {
+                    output.AppendLine(GetInstruction(file, baseOffset, current, ref isu));
+                    current += isu.InstSize;
+                }
+            }
+            return output.ToString();
+        }
 
-			#region Check offset printing
+        private string GetInstruction(BinFile refFile, int OrgOffset, int BinaryOffset, ref GBInstruction isu)
+        {
+            if (instructionCache.ContainsKey(OrgOffset + BinaryOffset))
+            {
+                isu = instructionCache[OrgOffset + BinaryOffset];
+            }
+            else
+            {
+                bool success = false;
+                if (lc.isAddressMarkedAsData(OrgOffset + BinaryOffset))
+                {
+                    success = GBASM.CreateDBInstruction(refFile.MainFile, OrgOffset, BinaryOffset, ref isu);
+                }
+                else
+                {
+                    success = GBASM.GetInstruction(refFile.MainFile, OrgOffset, BinaryOffset, ref isu);
+                }
+                if (!success)
+                {
+                    return "--Error--";
+                }
+                instructionCache.Add(isu.Bank + isu.Address, isu);
+            }
+            StringBuilder returned = new StringBuilder();
 
-			if (PrintOffsets)
-			{
-				returned.Append(AddressToASMString(isu));
-			}
+            #region Check offset printing
 
-			#endregion Check offset printing
+            if (PrintOffsets)
+            {
+                returned.Append(AddressToASMString(isu));
+            }
 
-			#region Check bit pattern printing
+            #endregion Check offset printing
 
-			if (PrintBitPattern)
-			{
-				for (int i = 0; i < isu.InstSize; i++)
-				{
-					returned.Append(refFile.ReadByte(BinaryOffset + i).ToString("X2"));
-				}
-				switch (isu.InstSize)
-				{
-					case 2:
-						returned.Append("    ");
-						break;
-					case 1:
-						returned.Append("      ");
-						break;
-					default:
-						returned.Append("  ");
-						break;
-				}
-			}
+            #region Check bit pattern printing
 
-			#endregion Check bit pattern printing
+            if (PrintBitPattern)
+            {
+                for (int i = 0; i < isu.InstSize; i++)
+                {
+                    returned.Append(refFile.ReadByte(BinaryOffset + i).ToString("X2"));
+                }
+                switch (isu.InstSize)
+                {
+                    case 2:
+                        returned.Append("    ");
+                        break;
 
-			#region Print instruction
+                    case 1:
+                        returned.Append("      ");
+                        break;
+                    default:
+                        returned.Append("  ");
+                        break;
+                }
+            }
 
-			if (!(PrintBitPattern || PrintOffsets)) returned.Append("\t");
-			returned.Append(isu.InstType.ToString("G"));
-			string numArg = "";
-			if (isu.ArgCount > 0)
-			{
-				returned.Append(" ");
-				returned.Append(ArgumentToASMString(isu.Bank, isu.Address, isu.InstType, isu.Arg1));
-			}
-			if (isu.ArgCount == 2)
-			{
-				returned.Append(",");
-				returned.Append(ArgumentToASMString(isu.Bank, isu.Address, isu.InstType, isu.Arg2));
-			}
+            #endregion Check bit pattern printing
 
-			#endregion Print instruction
+            #region Print instruction
 
-			#region Check comments
+            if (!(PrintBitPattern || PrintOffsets))
+                returned.Append("\t");
+            returned.Append(isu.InstType.ToString("G"));
+            string numArg = "";
+            if (isu.ArgCount > 0)
+            {
+                returned.Append(" ");
+                returned.Append(ArgumentToASMString(isu.Bank, isu.Address, isu.InstType, isu.Arg1));
+            }
+            if (isu.ArgCount == 2)
+            {
+                returned.Append(",");
+                returned.Append(ArgumentToASMString(isu.Bank, isu.Address, isu.InstType, isu.Arg2));
+            }
 
-			if (PrintComments)
-			{
-				int tCount = returned.Length;
-				returned.Append("\t\t;");
-				int x = refFile.ReadByte(BinaryOffset);
-				if (refFile.ReadByte(BinaryOffset) == 0xCB)
-				{
-					returned.AppendFormat(CBLongInst[x], numArg);
-				}
-				else returned.AppendFormat(longInst[x], numArg);
-			}
+            #endregion Print instruction
 
-			#endregion Check comments
+            #region Check comments
 
-			return returned.ToString();
-		}
+            if (PrintComments)
+            {
+                int tCount = returned.Length;
+                returned.Append("\t\t;");
+                int x = refFile.ReadByte(BinaryOffset);
+                if (refFile.ReadByte(BinaryOffset) == 0xCB)
+                {
+                    returned.AppendFormat(CBLongInst[x], numArg);
+                }
+                else
+                    returned.AppendFormat(longInst[x], numArg);
+            }
 
-		public string GetFullASM()
-		{
-			StringBuilder ot = new StringBuilder();
-			bool tempHFVal, tempHDVal, tempPBVal, tempPOVal;
-			tempHFVal = HideDefinedFunctions;
-			tempHDVal = HideDefinedData;
-			tempPBVal = PrintBitPattern;
-			tempPOVal = PrintOffsets;
+            #endregion Check comments
 
-			HideDefinedFunctions = false;
-			HideDefinedData = false;
-			PrintBitPattern = false;
-			PrintOffsets = false;
+            return returned.ToString();
+        }
 
-			foreach (VarLabel v in lc.VarList)
-			{
-				ot.AppendLine(v.Name + " EQU $" + v.Variable.ToString("X"));
-			}
-			ot.AppendLine(PrintASM(0, CoreFile.Length));
+        public string GetFullASM()
+        {
+            StringBuilder ot = new StringBuilder();
+            bool tempHFVal, tempHDVal, tempPBVal, tempPOVal;
+            tempHFVal = HideDefinedFunctions;
+            tempHDVal = HideDefinedData;
+            tempPBVal = PrintBitPattern;
+            tempPOVal = PrintOffsets;
 
-			HideDefinedFunctions = tempHFVal;
-			HideDefinedData = tempHDVal;
-			PrintBitPattern = tempPBVal;
-			PrintOffsets = tempPOVal;
+            HideDefinedFunctions = false;
+            HideDefinedData = false;
+            PrintBitPattern = false;
+            PrintOffsets = false;
 
-			return ot.ToString();
-		}
+            foreach (VarLabel v in lc.VarList)
+            {
+                ot.AppendLine(v.Name + " EQU $" + v.Variable.ToString("X"));
+            }
+            ot.AppendLine(PrintASM(0, CoreFile.Length));
 
-		#endregion Disassembly
+            HideDefinedFunctions = tempHFVal;
+            HideDefinedData = tempHDVal;
+            PrintBitPattern = tempPBVal;
+            PrintOffsets = tempPOVal;
 
-		#region Searching
+            return ot.ToString();
+        }
 
-		public enum SearchOptions { InFunctions, InFile }
+        #endregion Disassembly
 
-		[Flags]
-		private enum FuncRefType { None = 0x0, Call = 0x1, Jump = 0x2 }
+        #region Searching
 
-		[Flags]
-		private enum VarRefType { None = 0x0, Read = 0x1, Write = 0x2, Ref = 0x4 };
+        public enum SearchOptions { InFunctions, InFile }
 
-		public void AutoPopulateFunctionList()
-		{
-			int currentOffset = 0;
-			while (currentOffset < CoreFile.Length)
-			{
-				int curr = CoreFile.ReadByte(currentOffset);
-				if (curr == Int32.MinValue) return;
-				byte currentInst = (byte)curr;
-				GBInstruction isu = new GBInstruction();
-				bool success = false;
-				if (lc.isAddressMarkedAsData(currentOffset))
-				{
-					currentOffset = lc.GetNextNonDataAddress(currentOffset);
-					continue;
-				}
-				else success = GBASM.GetInstruction(CoreFile.MainFile, 0, currentOffset, ref isu);
-				if (!success) return;
-				if (isu.InstType == InstructionType.call)
-				{
-					ushort curCallAddr = (isu.ArgCount == 1) ? isu.Arg1.NumArg : isu.Arg2.NumArg;
-					if (currentOffset < 0x4000)
-					{
-						if (curCallAddr < 0x4000)
-						{
-							if (lc.TryGetFuncLabel(curCallAddr) == null)
-							{
-								lc.AddFuncLabel(new FunctionLabel(curCallAddr));
-							}
-						}
-					}
-					else
-					{
-						if (curCallAddr < 0x4000)
-						{
-							if (lc.TryGetFuncLabel(curCallAddr) == null)
-							{
-								lc.AddFuncLabel(new FunctionLabel(curCallAddr));
-							}
-						}
-						else
-						{
-							int currentCall = GetBankAdjustedAddress(isu.Bank, curCallAddr);
-							if (lc.TryGetFuncLabel(currentCall) == null)
-							{
-								lc.AddFuncLabel(new FunctionLabel(currentCall));
-							}
-						}
-					}
-				}
-				currentOffset += isu.InstSize;
-			}
-		}
+        [Flags]
+        private enum FuncRefType { None = 0x0, Call = 0x1, Jump = 0x2 }
 
-		public string SearchForFunctionCall(FunctionLabel labelName)
-		{
-			StringBuilder returned = new StringBuilder();
-			Dictionary<string, FuncRefType> ifResult = SearchForFunctionCall(labelName, SearchOptions.InFunctions);
-			Dictionary<string, FuncRefType> ofResult = SearchForFunctionCall(labelName, SearchOptions.InFile);
+        [Flags]
+        private enum VarRefType { None = 0x0, Read = 0x1, Write = 0x2, Ref = 0x4 };
 
-			string functionUsedMessage = "{0} was referred to in these functions:{1}";
-			string offsetUsedMessage = "{0} was referred to at these offsets:{1}";
+        public void AutoPopulateFunctionList()
+        {
+            int currentOffset = 0;
+            while (currentOffset < CoreFile.Length)
+            {
+                int curr = CoreFile.ReadByte(currentOffset);
+                if (curr == Int32.MinValue)
+                    return;
+                byte currentInst = (byte)curr;
+                GBInstruction isu = new GBInstruction();
+                bool success = false;
+                if (lc.isAddressMarkedAsData(currentOffset))
+                {
+                    currentOffset = lc.GetNextNonDataAddress(currentOffset);
+                    continue;
+                }
+                else
+                    success = GBASM.GetInstruction(CoreFile.MainFile, 0, currentOffset, ref isu);
+                if (!success)
+                    return;
+                if (isu.InstType == InstructionType.call)
+                {
+                    ushort curCallAddr = (isu.ArgCount == 1) ? isu.Arg1.NumArg : isu.Arg2.NumArg;
+                    FunctionLabel fc = new FunctionLabel(curCallAddr);
+                    if (currentOffset < 0x4000)
+                    {
+                        if (curCallAddr < 0x4000)
+                        {
+                            if (lc.TryGetFuncLabel(curCallAddr, out fc))
+                            {
+                                lc.AddFuncLabel(new FunctionLabel(curCallAddr));
+                            }
+                        }
+                    }
+                    else
+                    {
+                        if (curCallAddr < 0x4000)
+                        {
+                            if (lc.TryGetFuncLabel(curCallAddr, out fc))
+                            {
+                                lc.AddFuncLabel(new FunctionLabel(curCallAddr));
+                            }
+                        }
+                        else
+                        {
+                            int currentCall = Utility.GetRealAddress(isu.Bank, curCallAddr);
+                            if (lc.TryGetFuncLabel(curCallAddr, out fc))
+                            {
+                                lc.AddFuncLabel(new FunctionLabel(currentCall));
+                            }
+                        }
+                    }
+                }
+                currentOffset += isu.InstSize;
+            }
+        }
 
-			if (ifResult.Count == 0)
-			{
-				returned.AppendFormat("{0} was not referred to in any of the saved functions.{1}", labelName.Name, Environment.NewLine);
-			}
-			else
-			{
-				returned.AppendFormat(functionUsedMessage, labelName.Name, Environment.NewLine);
-				foreach (KeyValuePair<string, FuncRefType> kvp in ifResult)
-				{
-					returned.AppendFormat("{0} ({1}){2}", kvp.Key, kvp.Value.ToString("G"), Environment.NewLine);
-				}
-			}
+        public string SearchForFunctionCall(FunctionLabel labelName)
+        {
+            StringBuilder returned = new StringBuilder();
+            Dictionary<string, FuncRefType> ifResult = SearchForFunctionCall(labelName, SearchOptions.InFunctions);
+            Dictionary<string, FuncRefType> ofResult = SearchForFunctionCall(labelName, SearchOptions.InFile);
 
-			if (ofResult.Count == 0)
-			{
-				returned.AppendFormat("{0} was not referred to at any offset.{1}", labelName.Name, Environment.NewLine);
-			}
-			else
-			{
-				returned.AppendFormat(offsetUsedMessage, labelName.Name, Environment.NewLine);
-				foreach (KeyValuePair<string, FuncRefType> kvp in ofResult)
-				{
-					returned.AppendFormat("{0} ({1}){2}", kvp.Key, kvp.Value.ToString("G"), Environment.NewLine);
-				}
-			}
-			return returned.ToString();
-		}
+            string functionUsedMessage = "{0} was referred to in these functions:{1}";
+            string offsetUsedMessage = "{0} was referred to at these offsets:{1}";
 
-		private Dictionary<string, FuncRefType> SearchForFunctionCall(FunctionLabel searchLabel, SearchOptions options)
-		{
-			Dictionary<string, FuncRefType> results = new Dictionary<string, FuncRefType>();
-			if (options == SearchOptions.InFile)
-			{
-				SearchFileRangeForFunctionCall(results, 0x0, CoreFile.Length, searchLabel);
-				return results;
-			}
-			else
-			{
-				foreach (FunctionLabel c in lc.FuncList)
-				{
-					FuncRefType refType = FuncRefType.None;
-					int currentOffset = c.Offset;
-					int curLen = GuessFunctionLength(c);
-					while (currentOffset < c.Offset + curLen)
-					{
-						if (currentOffset < 0x4000 && searchLabel.Offset > 0x3FFF)
-						{
-							break;
-						}
-						if (lc.isAddressMarkedAsData(currentOffset))
-						{
-							currentOffset = lc.GetNextNonDataAddress(currentOffset);
-							continue;
-						}
-						GBInstruction isu = new GBInstruction();
-						if (!GBASM.GetInstruction(CoreFile.MainFile, 0, currentOffset, ref isu)) break;
-						if (isu.InstType == InstructionType.call || isu.InstType == InstructionType.jp || isu.InstType == InstructionType.jr)
-						{
-							ushort calledAddress = isu.ArgCount == 1 ? isu.Arg1.NumArg : isu.Arg2.NumArg;
-							if (!(currentOffset < 0x4000 && calledAddress > 0x3FFF))
-							{
-								int calledNum = GetBankAdjustedAddress(isu.Bank, calledAddress);
-								if (searchLabel.Offset == calledNum)
-								{
-									if (isu.InstType == InstructionType.call) refType |= FuncRefType.Call;
-									else refType |= FuncRefType.Jump;
-								}
-							}
-						}
-						currentOffset += isu.InstSize;
-					}
-					if (refType != FuncRefType.None) results.Add(c.Name, refType);
-				}
-				return results;
-			}
-		}
+            if (ifResult.Count == 0)
+            {
+                returned.AppendFormat("{0} was not referred to in any of the saved functions.{1}", labelName.Name, Environment.NewLine);
+            }
+            else
+            {
+                returned.AppendFormat(functionUsedMessage, labelName.Name, Environment.NewLine);
+                foreach (KeyValuePair<string, FuncRefType> kvp in ifResult)
+                {
+                    returned.AppendFormat("{0} ({1}){2}", kvp.Key, kvp.Value.ToString("G"), Environment.NewLine);
+                }
+            }
 
-		private void SearchFileRangeForFunctionCall(Dictionary<string, FuncRefType> results, int startingOffset, int length, FunctionLabel searchLabel)
-		{
-			if (startingOffset < 0x4000 && searchLabel.Offset > 0x3FFF)
-			{
-				return;
-			}
-			int currentOffset = startingOffset;
-			while (currentOffset < startingOffset + length)
-			{
-				if (lc.isAddressMarkedAsData(currentOffset))
-				{
-					currentOffset = lc.GetNextNonDataAddress(currentOffset);
-					continue;
-				}
-				GBInstruction isu = new GBInstruction();
-				if (!GBASM.GetInstruction(CoreFile.MainFile, 0, currentOffset, ref isu)) break;
-				if (isu.InstType == InstructionType.call || isu.InstType == InstructionType.jp || isu.InstType == InstructionType.jr)
-				{
-					ushort calledAddress = isu.ArgCount == 1 ? isu.Arg1.NumArg : isu.Arg2.NumArg;
-					if (!(calledAddress < 0x4000 && currentOffset > 0x3FFF))
-					{
-						int calledNum = GetBankAdjustedAddress(isu.Bank, calledAddress);
-						if (searchLabel.Offset == calledNum)
-						{
-							if (isu.InstType == InstructionType.call) results.Add(currentOffset.ToString("X"), FuncRefType.Call);
-							else results.Add(currentOffset.ToString("X"), FuncRefType.Call);
-						}
-					}
-				}
-				currentOffset += isu.InstSize;
-			}
-		}
+            if (ofResult.Count == 0)
+            {
+                returned.AppendFormat("{0} was not referred to at any offset.{1}", labelName.Name, Environment.NewLine);
+            }
+            else
+            {
+                returned.AppendFormat(offsetUsedMessage, labelName.Name, Environment.NewLine);
+                foreach (KeyValuePair<string, FuncRefType> kvp in ofResult)
+                {
+                    returned.AppendFormat("{0} ({1}){2}", kvp.Key, kvp.Value.ToString("G"), Environment.NewLine);
+                }
+            }
+            return returned.ToString();
+        }
 
-		public string SearchForReference(GenericLabel search)
-		{
-			StringBuilder returned = new StringBuilder(String.Empty);
-			Dictionary<string, VarRefType> funcRefsNew = SearchFileForVarReference(search.Value, SearchOptions.InFunctions);
-			Dictionary<string, VarRefType> offRefsNew = SearchFileForVarReference(search.Value, SearchOptions.InFile);
-			string functionUsedMessage = "{0} was used in these functions:{1}";
-			string offsetUsedMessage = "{0} was used at these offsets:{1}";
+        private Dictionary<string, FuncRefType> SearchForFunctionCall(FunctionLabel searchLabel, SearchOptions options)
+        {
+            Dictionary<string, FuncRefType> results = new Dictionary<string, FuncRefType>();
+            if (options == SearchOptions.InFile)
+            {
+                SearchFileRangeForFunctionCall(results, 0x0, CoreFile.Length, searchLabel);
+                return results;
+            }
+            else
+            {
+                foreach (FunctionLabel c in lc.FuncList)
+                {
+                    FuncRefType refType = FuncRefType.None;
+                    int currentOffset = c.Offset;
+                    int curLen = GuessFunctionLength(c);
+                    while (currentOffset < c.Offset + curLen)
+                    {
+                        if (currentOffset < 0x4000 && searchLabel.Offset > 0x3FFF)
+                        {
+                            break;
+                        }
+                        if (lc.isAddressMarkedAsData(currentOffset))
+                        {
+                            currentOffset = lc.GetNextNonDataAddress(currentOffset);
+                            continue;
+                        }
+                        GBInstruction isu = new GBInstruction();
+                        if (!GBASM.GetInstruction(CoreFile.MainFile, 0, currentOffset, ref isu))
+                            break;
+                        if (isu.InstType == InstructionType.call || isu.InstType == InstructionType.jp || isu.InstType == InstructionType.jr)
+                        {
+                            ushort calledAddress = isu.ArgCount == 1 ? isu.Arg1.NumArg : isu.Arg2.NumArg;
+                            if (!(currentOffset < 0x4000 && calledAddress > 0x3FFF))
+                            {
+                                int calledNum = Utility.GetRealAddress(isu.Bank, calledAddress);
+                                if (searchLabel.Offset == calledNum)
+                                {
+                                    if (isu.InstType == InstructionType.call)
+                                        refType |= FuncRefType.Call;
+                                    else
+                                        refType |= FuncRefType.Jump;
+                                }
+                            }
+                        }
+                        currentOffset += isu.InstSize;
+                    }
+                    if (refType != FuncRefType.None)
+                        results.Add(c.Name, refType);
+                }
+                return results;
+            }
+        }
 
-			#region Var Refs in Functions
+        private void SearchFileRangeForFunctionCall(Dictionary<string, FuncRefType> results, int startingOffset, int length, FunctionLabel searchLabel)
+        {
+            if (startingOffset < 0x4000 && searchLabel.Offset > 0x3FFF)
+            {
+                return;
+            }
+            int currentOffset = startingOffset;
+            while (currentOffset < startingOffset + length)
+            {
+                if (lc.isAddressMarkedAsData(currentOffset))
+                {
+                    currentOffset = lc.GetNextNonDataAddress(currentOffset);
+                    continue;
+                }
+                GBInstruction isu = new GBInstruction();
+                if (!GBASM.GetInstruction(CoreFile.MainFile, 0, currentOffset, ref isu))
+                    break;
+                if (isu.InstType == InstructionType.call || isu.InstType == InstructionType.jp || isu.InstType == InstructionType.jr)
+                {
+                    ushort calledAddress = isu.ArgCount == 1 ? isu.Arg1.NumArg : isu.Arg2.NumArg;
+                    if (!(calledAddress < 0x4000 && currentOffset > 0x3FFF))
+                    {
+                        int calledNum = Utility.GetRealAddress(isu.Bank, calledAddress);
+                        if (searchLabel.Offset == calledNum)
+                        {
+                            if (isu.InstType == InstructionType.call)
+                                results.Add(currentOffset.ToString("X"), FuncRefType.Call);
+                            else
+                                results.Add(currentOffset.ToString("X"), FuncRefType.Call);
+                        }
+                    }
+                }
+                currentOffset += isu.InstSize;
+            }
+        }
 
-			if (funcRefsNew.Count == 0)
-			{
-				returned.AppendFormat("{0} is not referred to in any of the defined functions.{1}", search.Name, Environment.NewLine);
-			}
-			else
-			{
-				returned.AppendFormat(functionUsedMessage, search.Name, Environment.NewLine);
-				foreach (KeyValuePair<string, VarRefType> kvp in funcRefsNew)
-				{
-					returned.AppendFormat("{0} ({1}){2}", kvp.Key, kvp.Value.ToString("G"), Environment.NewLine);
-				}
-			}
+        public string SearchForReference(GenericLabel search)
+        {
+            StringBuilder returned = new StringBuilder(String.Empty);
+            Dictionary<string, VarRefType> funcRefsNew = SearchFileForVarReference(search.Value, SearchOptions.InFunctions);
+            Dictionary<string, VarRefType> offRefsNew = SearchFileForVarReference(search.Value, SearchOptions.InFile);
+            string functionUsedMessage = "{0} was used in these functions:{1}";
+            string offsetUsedMessage = "{0} was used at these offsets:{1}";
 
-			#endregion Var Refs in Functions
+            #region Var Refs in Functions
 
-			#region Var Refs out of functions
+            if (funcRefsNew.Count == 0)
+            {
+                returned.AppendFormat("{0} is not referred to in any of the defined functions.{1}", search.Name, Environment.NewLine);
+            }
+            else
+            {
+                returned.AppendFormat(functionUsedMessage, search.Name, Environment.NewLine);
+                foreach (KeyValuePair<string, VarRefType> kvp in funcRefsNew)
+                {
+                    returned.AppendFormat("{0} ({1}){2}", kvp.Key, kvp.Value.ToString("G"), Environment.NewLine);
+                }
+            }
 
-			if (offRefsNew.Count == 0)
-			{
-				returned.AppendFormat("{0} could not be found at any offset.{1}", search.Name, Environment.NewLine);
-			}
-			else
-			{
-				returned.AppendFormat(offsetUsedMessage, search.Name, Environment.NewLine);
-				foreach (KeyValuePair<string, VarRefType> kvp in offRefsNew)
-				{
-					returned.AppendFormat("{0} ({1}){2}", kvp.Key, kvp.Value.ToString("G"), Environment.NewLine);
-				}
-			}
+            #endregion Var Refs in Functions
 
-			#endregion Var Refs out of functions
+            #region Var Refs out of functions
 
-			return returned.ToString();
-		}
+            if (offRefsNew.Count == 0)
+            {
+                returned.AppendFormat("{0} could not be found at any offset.{1}", search.Name, Environment.NewLine);
+            }
+            else
+            {
+                returned.AppendFormat(offsetUsedMessage, search.Name, Environment.NewLine);
+                foreach (KeyValuePair<string, VarRefType> kvp in offRefsNew)
+                {
+                    returned.AppendFormat("{0} ({1}){2}", kvp.Key, kvp.Value.ToString("G"), Environment.NewLine);
+                }
+            }
 
-		private Dictionary<string, VarRefType> SearchFileForVarReference(int searchWord, SearchOptions options)
-		{
-			Dictionary<string, VarRefType> results = new Dictionary<string, VarRefType>();
-			if (options == SearchOptions.InFile)
-			{
-				SearchFileRangeForVarReference(results, 0, CoreFile.Length, searchWord);
-			}
-			else
-			{
-				foreach (FunctionLabel c in lc.FuncList)
-				{
-					VarRefType result = VarRefType.None;
-					int currentOffset = c.Offset;
-					int curLen = GuessFunctionLength(c);
-					while (currentOffset < c.Offset + curLen)
-					{
-						if (lc.isAddressMarkedAsData(currentOffset))
-						{
-							currentOffset = lc.GetNextNonDataAddress(currentOffset);
-							continue;
-						}
-						GBInstruction isu = new GBInstruction();
-						if (!GBASM.GetInstruction(CoreFile.MainFile, 0, currentOffset, ref isu)) break;
-						if (isu.InstType == InstructionType.ld && isu.ArgCount == 2)
-						{
-							if (isu.Arg1.ArgType == GBArgumentType.MemMapWord && isu.Arg1.NumArg == searchWord)
-							{
-								result |= VarRefType.Write;
-							}
-							else if (isu.Arg2.ArgType == GBArgumentType.MemMapWord && isu.Arg2.NumArg == searchWord)
-							{
-								result |= VarRefType.Read;
-							}
-							else if (isu.Arg1.ArgType == GBArgumentType.RegisterDouble && isu.Arg2.NumArg == searchWord)
-							{
-								result |= VarRefType.Ref;
-							}
-						}
-						currentOffset += isu.InstSize;
-					}
-					if (result != VarRefType.None) results.Add(c.Name, result);
-				}
-			}
-			return results;
-		}
+            #endregion Var Refs out of functions
 
-		private void SearchFileRangeForVarReference(Dictionary<string, VarRefType> results, int startingOffset, int length, int searchWord)