示例#1
0
 /// <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>Returns true if the creation was successful, and false otherwise.
 /// </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 = BitConverter.ToUInt16(baseFile, offset);
     if (address > 0x4000)
     {
         outputInstruction.Address += 0x4000;
     }
     return true;
 }
示例#2
0
 /// <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>Returns true if the creation was successful, and false otherwise.
 /// </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;
 }
示例#3
0
        /// <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>Returns true if the creation was successful, and false otherwise.
        /// </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  = BitConverter.ToUInt16(baseFile, offset);
            if (address > 0x4000)
            {
                outputInstruction.Address += 0x4000;
            }
            return(true);
        }
示例#4
0
        /// <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>Returns true if the creation was successful, and false otherwise.
        /// </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);
        }
示例#5
0
        /// <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);
            }

            // Holds the "actual" address of the instruction, in case the array provided isn't the full file.
            int  address = org + offset;
            byte inst    = baseFile[offset];

            if (inst == 0xCB)
            {
                // If the inst is a CB instruction, it's a 2-byte one, and a different table is used.
                if (offset > baseFile.Length - 2)
                {
                    // In case the inst is part of a bigger file, interpret as a DB instruction instead.
                    // Prior behavior: return false
                    return(GBASM.CreateDBInstruction(baseFile, org, offset, ref outputInstruction));
                }
                outputInstruction = GBInstructions.CBInstructionUnitTable[baseFile[offset + 1]];
            }
            else
            {
                outputInstruction = GBInstructions.InstructionUnitTable[baseFile[offset]];
            }

            // If the instruction gotten is too big, then return a DB/DW instruction, as default.
            if (offset + outputInstruction.InstSize > baseFile.Length)
            {
                int retSize = baseFile.Length - offset;
                switch (retSize)
                {
                case 1:
                {
                    return(GBASM.CreateDBInstruction(baseFile, org, offset, ref outputInstruction));
                }

                case 2:
                {
                    return(GBASM.CreateDWInstruction(baseFile, org, offset, ref outputInstruction));
                }

                default:
                {
                    return(false);
                }
                }
            }

            // Adjust the gotten inst's bank and address manually
            outputInstruction.Bank    = (byte)(address >> 14);
            outputInstruction.Address = (ushort)(address & 0x3FFF);
            if (address > 0x4000)
            {
                outputInstruction.Address += 0x4000;
            }

            // Finally, adjust the values of the arguments if they are dependant on the other bytes
            // in the instruction.
            if (outputInstruction.InstSize == 1 && outputInstruction.InstType == InstructionType.db)
            {
                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 = BitConverter.ToUInt16(baseFile, offset + 1);
                }
                else if (outputInstruction.ArgCount == 2)
                {
                    if (outputInstruction.Arg1.ArgType == GBArgumentType.MemMapWord)
                    {
                        outputInstruction.Arg1.NumArg = BitConverter.ToUInt16(baseFile, offset + 1);
                    }
                    else if (outputInstruction.Arg2.ArgType == GBArgumentType.Word ||
                             outputInstruction.Arg2.ArgType == GBArgumentType.MemMapWord)
                    {
                        outputInstruction.Arg2.NumArg = BitConverter.ToUInt16(baseFile, offset + 1);
                    }
                }
            }
            return(true);
        }
示例#6
0
        public int GuessLabelPrintLength(int offset)
        {
            int currentOffset = offset;
            int maxLength = 0x4000 - (currentOffset & 0x3FFF);
            bool done = false;
            int nopCount = 0;
            var jumpLocs = new List<int>();
            bool endpoint = false;
            while (!done)
            {
                if (currentOffset >= CoreFile.Length)
                {
                    break;
                }

                GBInstruction isu = new GBInstruction();
                GBASM.GetInstruction(CoreFile.MainFile, 0, currentOffset, ref isu);
                currentOffset += isu.InstSize;

                if (currentOffset - offset >= maxLength)
                {
                    break;
                }

                switch (isu.InstType)
                {
                    case InstructionType.nop:
                        nopCount++;
                        if (nopCount > 3)
                        {
                            endpoint = true;
                        }
                        break;

                    case InstructionType.ret:
                    case InstructionType.reti:
                        if (isu.ArgCount == 0)
                        {
                            endpoint = true;
                        }

                        break;

                    case InstructionType.jp:
                    case InstructionType.jr:
                        {
                            int jumpedOffset = 0;
                            if (isu.ArgCount == 1)
                            {
                                jumpedOffset = Utility.GetRealAddress(isu.Bank, isu.Arg1.NumArg);
                            }
                            else if (isu.ArgCount == 2)
                            {
                                jumpedOffset = Utility.GetRealAddress(isu.Bank, isu.Arg2.NumArg);
                            }
                            if (jumpedOffset > currentOffset)
                            {
                                jumpLocs.Add(jumpedOffset);
                            }
                            if (isu.ArgCount == 1)
                            {
                                endpoint = true;
                            }
                            break;
                        }
                    default:
                        break;
                }
                if (endpoint)
                {
                    if (jumpLocs.Contains(currentOffset))
                    {
                        jumpLocs.Remove(currentOffset);
                        endpoint = false;
                    }
                    else
                    {
                        done = true;
                    }
                }
            }
            return currentOffset - offset;
        }
示例#7
0
 private void SearchFileRangeForVarReference(Dictionary<string, VarRefType> results, int startingOffset, int length, int searchWord)
 {
     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.ld && isu.ArgCount == 2)
         {
             if (isu.Arg1.ArgType == GBArgumentType.MemMapWord && isu.Arg1.NumArg == searchWord)
             {
                 results.Add(currentOffset.ToString("X"), VarRefType.Write);
             }
             else if (isu.Arg2.ArgType == GBArgumentType.MemMapWord && isu.Arg2.NumArg == searchWord)
             {
                 results.Add(currentOffset.ToString("X"), VarRefType.Read);
             }
             else if (isu.Arg1.ArgType == GBArgumentType.RegisterDouble && isu.Arg2.NumArg == searchWord)
             {
                 results.Add(currentOffset.ToString("X"), VarRefType.Ref);
             }
         }
         currentOffset += isu.InstSize;
     }
 }
示例#8
0
        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 = GuessLabelPrintLength(c.Offset);
                    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;
        }
示例#9
0
 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;
     }
 }
示例#10
0
 private Dictionary<string, FuncRefType> SearchForFunctionCall(FunctionLabel searchLabel, SearchOptions options)
 {
     var results = new Dictionary<string, FuncRefType>();
     var searched = new HashSet<int>();
     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;
             if (searched.Contains(currentOffset))
             {
                 continue;
             }
             else
             {
                 searched.Add(currentOffset);
             }
             int curLen = GuessLabelPrintLength(c.Offset);
             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;
     }
 }
示例#11
0
        public void AutoPopulateFunctionList()
        {
            int currentOffset = 0;
            while (currentOffset < CoreFile.Length)
            {
                if (lc.isAddressMarkedAsData(currentOffset))
                {
                    currentOffset = lc.GetNextNonDataAddress(currentOffset);
                    continue;
                }

                GBInstruction isu = new GBInstruction();
                if (!GBASM.GetInstruction(CoreFile.MainFile, 0, currentOffset, ref isu))
                {
                    return;
                }

                if (isu.InstType == InstructionType.call)
                {
                    ushort curCallAddress = (isu.ArgCount == 1) ? isu.Arg1.NumArg : isu.Arg2.NumArg;
                    if (curCallAddress < 0x4000)
                    {
                        lc.AddFuncLabel(new FunctionLabel(curCallAddress));
                    }
                    else if (currentOffset >= 0x4000)
                    {
                        int curAdjustedCallAddress = Utility.GetRealAddress(isu.Bank, curCallAddress);
                        lc.AddFuncLabel(new FunctionLabel(curAdjustedCallAddress));
                    }
                }

                currentOffset += isu.InstSize;
            }
        }
示例#12
0
        private string GetInstruction(BinFile refFile, int OrgOffset, int BinaryOffset, ref GBInstruction isu)
        {
            int currentAddress = OrgOffset + BinaryOffset;
            if (lc.isAddressMarkedAsData(currentAddress))
            {
                GBASM.CreateDBInstruction(refFile.MainFile, OrgOffset, BinaryOffset, ref isu);
            }
            else
            {
                GBASM.GetInstruction(refFile.MainFile, OrgOffset, BinaryOffset, ref isu);
            }
            StringBuilder returned = new StringBuilder();

            if (PrintOffsets || PrintBitPattern)
            {
                returned.Append("/*");
                if (PrintOffsets)
                {
                    returned.Append(AddressToString(isu));
                }
                if (PrintBitPattern)
                {
                    var bp = new string[] { "  ", "  ", "  ", "  " };
                    for (int i = 0; i < isu.InstSize; i++)
                    {
                        bp[i] = refFile.ReadByte(BinaryOffset + i).ToString("X2");
                    }
                    returned.Append(string.Join("", bp));
                }
                returned.Append("*/ ");
            }
            else
            {
                returned.Append("    ");
            }

            returned.Append(isu.InstType.ToString());
            string numArg = "";
            if (isu.ArgCount > 0)
            {
                returned.Append(" ");
                numArg = ArgumentToString(isu.Bank, isu.Address, isu.InstType, isu.Arg1);
                returned.Append(numArg);
            }
            if (isu.ArgCount == 2)
            {
                returned.Append(",");
                numArg = ArgumentToString(isu.Bank, isu.Address, isu.InstType, isu.Arg2);
                returned.Append(numArg);
            }

            #region Check comments

            if (PrintComments)
            {
                returned.Append("  ;");
                int x = refFile.ReadByte(BinaryOffset);
                if (refFile.ReadByte(BinaryOffset) == 0xCB)
                {
                    returned.AppendFormat(CBLongInst[x], numArg);
                }
                else
                {
                    returned.AppendFormat(longInst[x], numArg);
                }
            }

            #endregion Check comments

            return returned.ToString();
        }
示例#13
0
 public string PrintASM(BinFile file, int baseOffset, int start, int length)
 {
     StringBuilder output = new StringBuilder();
     GBInstruction isu = new GBInstruction();
     int current = start;
     while (current < start + length)
     {
         var labelsAt = from s in lc.FuncList
                        where s.Offset == current
                        orderby s.Name
                        select s;
         var dataAt = from s in lc.DataList
                      where s.Offset == current
                      select s;
         foreach (var label in labelsAt)
         {
             output.AppendLine(label.ToASMString());
         }
         int advanceBy = 0;
         if (dataAt.Count() != 0)
         {
             if (HideDefinedData)
             {
                 output.AppendLine(String.Format("INCBIN \"{0}.bin\"", dataAt.First().Name));
             }
             else
             {
                 output.Append(ShowDataLabel(dataAt.First()));
             }
             advanceBy = dataAt.First().Length;
         }
         else
         {
             output.AppendLine(GetInstruction(file, baseOffset, current, ref isu));
             advanceBy = isu.InstSize;
         }
         if (lc.Comments.ContainsKey(current))
         {
             output.AppendLine(";" + lc.Comments[current].Replace("\n", "\n;"));
         }
         current += advanceBy;
     }
     return output.ToString();
 }
示例#14
0
 private string AddressToString(GBInstruction isu)
 {
     switch (PrintedOffsetFormat)
     {
         case OffsetFormat.BankOffset:
             {
                 return isu.Bank.ToString("X2") + ":" + isu.Address.ToString("X4") + "  ";
             }
         case OffsetFormat.Hex:
         case OffsetFormat.Decimal:
             {
                 int address = Utility.GetRealAddress(isu.Bank, isu.Address);
                 if (PrintedOffsetFormat == OffsetFormat.Hex)
                 {
                     return address.ToString("X6") + "   ";
                 }
                 else
                 {
                     return address.ToString("D7") + "  ";
                 }
             }
         default:
             return "";
     }
 }
示例#15
0
        /// <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;

            // Holds the "actual" address of the instruction, in case the array provided isn't the full file.
            int address = org + offset;
            byte inst = baseFile[offset];
            if (inst == 0xCB)
            {
                // If the inst is a CB instruction, it's a 2-byte one, and a different table is used.
                if (offset > baseFile.Length - 2)
                {
                    // In case the inst is part of a bigger file, interpret as a DB instruction instead.
                    // Prior behavior: return false
                    return GBASM.CreateDBInstruction(baseFile, org, offset, ref outputInstruction);
                }
                outputInstruction = GBInstructions.CBInstructionUnitTable[baseFile[offset + 1]];
            }
            else
            {
                outputInstruction = GBInstructions.InstructionUnitTable[baseFile[offset]];
            }

            // If the instruction gotten is too big, then return a DB/DW instruction, as default.
            if (offset + outputInstruction.InstSize > baseFile.Length)
            {
                int retSize = baseFile.Length - offset;
                switch (retSize)
                {
                    case 1:
                        {
                            return GBASM.CreateDBInstruction(baseFile, org, offset, ref outputInstruction);
                        }

                    case 2:
                        {
                            return GBASM.CreateDWInstruction(baseFile, org, offset, ref outputInstruction);
                        }

                    default:
                        {
                            return false;
                        }
                }
            }

            // Adjust the gotten inst's bank and address manually
            outputInstruction.Bank = (byte)(address >> 14);
            outputInstruction.Address = (ushort)(address & 0x3FFF);
            if (address > 0x4000)
            {
                outputInstruction.Address += 0x4000;
            }

            // Finally, adjust the values of the arguments if they are dependant on the other bytes
            // in the instruction.
            if (outputInstruction.InstSize == 1 && outputInstruction.InstType == InstructionType.db)
            {
                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 = BitConverter.ToUInt16(baseFile, offset + 1);
                }
                else if (outputInstruction.ArgCount == 2)
                {
                    if (outputInstruction.Arg1.ArgType == GBArgumentType.MemMapWord)
                    {
                        outputInstruction.Arg1.NumArg = BitConverter.ToUInt16(baseFile, offset + 1);
                    }
                    else if (outputInstruction.Arg2.ArgType == GBArgumentType.Word ||
                        outputInstruction.Arg2.ArgType == GBArgumentType.MemMapWord)
                    {
                        outputInstruction.Arg2.NumArg = BitConverter.ToUInt16(baseFile, offset + 1);
                    }
                }
            }
            return true;
        }