/// <summary>
        /// Formats and stringifies an instruction as well as its parameters.
        /// </summary>
        /// <param name="currPgrmCtr">The value that the program counter would theoretically be at
        /// upon encountering this instruction.</param>
        /// <param name="inst">The disassembled instruction to stringify.</param>
        /// <param name="symTable">A reverse symbol table used to map addresses back to label names.</param>
        /// <returns>A string representing the instruction and its parameters that can be written to a text file.</returns>
        public string GetFormattedInstruction(int currPgrmCtr, DisassembledInstruction inst, ReverseSymbolTable symTable)
        {
            string retStr = string.Empty;

            // first, see if the program counter has a symbol mapped to it.
            if (symTable.ContainsSymbol(currPgrmCtr))
            {
                Symbol sym = symTable.GetSymbol(currPgrmCtr);
                retStr += sym.LabelName + ":\t\t";
            }
            else
            {
                retStr += "\t\t\t";
            }

            retStr += m_Name + ' ';

            if (inst.Parameters.Count() != 2)
            {
                throw new ArgumentException("U-type instruction expected 2 arguments, received " + inst.Parameters.Count());
            }

            string rd        = ReverseRegisterMap.GetStringifiedRegisterValue(inst.Parameters.ElementAt(0));
            int    immediate = inst.Parameters.ElementAt(1);

            retStr += rd + ", 0x" + immediate.ToString("X2");

            return(retStr);
        }
        /// <summary>
        /// Formats and stringifies an instruction as well as its parameters.
        /// </summary>
        /// <param name="currPgrmCtr">The value that the program counter would theoretically be at
        /// upon encountering this instruction.</param>
        /// <param name="inst">The disassembled instruction to stringify.</param>
        /// <param name="symTable">A reverse symbol table used to map addresses back to label names.</param>
        /// <returns>A string representing the instruction and its parameters that can be written to a text file.</returns>
        public string GetFormattedInstruction(int currPgrmCtr, DisassembledInstruction inst, ReverseSymbolTable symTable)
        {
            string retStr = string.Empty;

            // first, see if the program counter has a symbol mapped to it.
            if (symTable.ContainsSymbol(currPgrmCtr))
            {
                Symbol sym = symTable.GetSymbol(currPgrmCtr);
                retStr += sym.LabelName + ":\t\t";
            }
            else
            {
                retStr += "\t\t\t";
            }

            retStr += "flw ";
            if (inst.Parameters.Count() != 3)
            {
                throw new ArgumentException("Floating point I instruction expected 3 arguments, received " + inst.Parameters.Count());
            }

            string rd  = ReverseRegisterMap.GetStringifiedFloatingPtRegisterValue(inst.Parameters.ElementAt(0));
            string rs1 = ReverseRegisterMap.GetStringifiedRegisterValue(inst.Parameters.ElementAt(1));

            int offset = inst.Parameters.ElementAt(2);

            retStr += rd + ", " + offset + "(" + rs1 + ")";

            return(retStr);
        }
        public void AddRecord(ExceptionDebugInfo?context)
        {
            if (context == null)
            {
                return;
            }
            if (!acceptNewRecords)
            {
                return;
            }

            if (InvokeRequired)
            {
                Invoke((MethodInvoker)(() => AddRecord(context)));

                return;
            }

            var row = data.AsEnumerable().FirstOrDefault(r => r.Field <FoundCodeInfo>("info").DebugInfo.ExceptionAddress == context.Value.ExceptionAddress);

            if (row != null)
            {
                row["counter"] = row.Field <int>("counter") + 1;
            }
            else
            {
                var disassembler = new Disassembler(process.CoreFunctions);

                var causedByInstruction = disassembler.RemoteGetPreviousInstruction(process, context.Value.ExceptionAddress);
                if (causedByInstruction == null)
                {
                    return;
                }

                var instructions = new DisassembledInstruction[5];
                instructions[2] = causedByInstruction;
                instructions[1] = disassembler.RemoteGetPreviousInstruction(process, instructions[2].Address);
                instructions[0] = disassembler.RemoteGetPreviousInstruction(process, instructions[1].Address);

                var i = 3;
                foreach (var instruction in disassembler.RemoteDisassembleCode(process, context.Value.ExceptionAddress, 2 * Disassembler.MaximumInstructionLength, 2))
                {
                    instructions[i++] = instruction;
                }

                row                = data.NewRow();
                row["counter"]     = 1;
                row["instruction"] = causedByInstruction.Instruction;
                row["info"]        = new FoundCodeInfo
                {
                    DebugInfo    = context.Value,
                    Instructions = instructions
                };
                data.Rows.Add(row);
            }
        }
Beispiel #4
0
        protected void DumpInfo()
        {
            writer.WriteLine();
            writer.WriteLine("D0: {0}   D4: {1}   A0: {2}   A4: {3}     PC: {4}",
                             cpu.GetDataRegisterLong(0).ToString("x8", CultureInfo.InvariantCulture),
                             cpu.GetDataRegisterLong(4).ToString("x8", CultureInfo.InvariantCulture),
                             cpu.GetAddrRegisterLong(0).ToString("x8", CultureInfo.InvariantCulture),
                             cpu.GetAddrRegisterLong(4).ToString("x8", CultureInfo.InvariantCulture),
                             cpu.GetPC().ToString("x8", CultureInfo.InvariantCulture));
            writer.WriteLine("D1: {0}   D5: {1}   A1: {2}   A5: {3}     SR:  {4} {5}",
                             cpu.GetDataRegisterLong(1).ToString("x8", CultureInfo.InvariantCulture),
                             cpu.GetDataRegisterLong(5).ToString("x8", CultureInfo.InvariantCulture),
                             cpu.GetAddrRegisterLong(1).ToString("x8", CultureInfo.InvariantCulture),
                             cpu.GetAddrRegisterLong(5).ToString("x8", CultureInfo.InvariantCulture),
                             cpu.GetSR().ToString("x4", CultureInfo.InvariantCulture),
                             MakeFlagView());
            writer.WriteLine("D2: {0}   D6: {1}   A2: {2}   A6: {3}     USP: {4}",
                             cpu.GetDataRegisterLong(2).ToString("x8", CultureInfo.InvariantCulture),
                             cpu.GetDataRegisterLong(6).ToString("x8", CultureInfo.InvariantCulture),
                             cpu.GetAddrRegisterLong(2).ToString("x8", CultureInfo.InvariantCulture),
                             cpu.GetAddrRegisterLong(6).ToString("x8", CultureInfo.InvariantCulture),
                             cpu.GetUSP());
            writer.WriteLine("D3: {0}   D7: {1}   A3: {2}   A7: {3}     SSP: {4}",
                             cpu.GetDataRegisterLong(3).ToString("x8", CultureInfo.InvariantCulture),
                             cpu.GetDataRegisterLong(7).ToString("x8", CultureInfo.InvariantCulture),
                             cpu.GetAddrRegisterLong(3).ToString("x8", CultureInfo.InvariantCulture),
                             cpu.GetAddrRegisterLong(7).ToString("x8", CultureInfo.InvariantCulture),
                             cpu.GetSSP().ToString("x8", CultureInfo.InvariantCulture));
            buffer.Clear();
            int addr = cpu.GetPC();

            if (addr < 0 || addr >= memory.Size())
            {
                buffer.Append($"{addr.ToString("x8", CultureInfo.InvariantCulture)}   ????");
            }
            else
            {
                int                     opcode = cpu.ReadMemoryWord(addr);
                IInstruction            i      = cpu.GetInstructionFor(opcode);
                DisassembledInstruction di     = i.Disassemble(addr, opcode);
                if (showBytes)
                {
                    di.FormatInstruction(buffer);
                }
                else
                {
                    di.ShortFormat(buffer);
                }
            }

            writer.WriteLine($"==> {buffer}{Environment.NewLine}");
        }
Beispiel #5
0
        /// <summary>
        /// Executes the instruction pointed at by the current instruction pointer.
        /// </summary>
        public void ExecuteNextInstruction()
        {
            // make this separate so the user can figure out where the problem when wrong
            int originalPcValue = m_Ctx.UserRegisters[InterpreterCommon.PC_REGISTER].Value;

            try
            {
                DisassembledInstruction instruction = m_TextSegment.FetchInstruction(originalPcValue);
                IInstructionInterpreter interpreter = m_InterpreterFac.GetInterpreter(instruction.InstructionType);

                // if this returns false, then increment the program counter by 4. otherwise, this indicates
                // that the instruction needed to change the PC.
                if (!interpreter.InterpretInstruction(m_Ctx, instruction.Parameters.ToArray()))
                {
                    m_Ctx.UserRegisters[InterpreterCommon.PC_REGISTER].Value += sizeof(int);
                }

                // check to make sure something didn't put us in some crazy address
                int newPcValue = m_Ctx.UserRegisters[InterpreterCommon.PC_REGISTER].Value;
                if (newPcValue < m_TextSegment.StartingSegmentAddress)
                {
                    throw new Exceptions.AccessViolationException(string.Format("Program counter value 0x{0} was outside " +
                                                                                "text segment.", newPcValue.ToString("x8")));
                }
            }
            catch (Exceptions.AccessViolationException ex)
            {
                m_Terminal.PrintString("Received SIGSEGV at 0x" + originalPcValue.ToString("x8") + ": Segmentation fault\n");
                m_Terminal.PrintString(ex.Message);
                m_Environment.Terminate();
            }
            catch (Simulation.Exceptions.RuntimeSignal)
            {
                throw;
            }
            catch (RuntimeException ex)
            {
                m_Terminal.PrintString("Received SIGABRT at 0x" + originalPcValue.ToString("x8") + ": ");
                m_Terminal.PrintString(ex.Message);
                m_Environment.Terminate();
            }
            catch (Exception ex)
            {
                m_Terminal.PrintString("Received SIGABRT at 0x" + originalPcValue.ToString("x8") + ": ");
                m_Terminal.PrintString(ex.Message);
                m_Terminal.PrintString(ex.StackTrace);
                m_Environment.Terminate();
            }
        }
Beispiel #6
0
        /// <summary>
        /// Formats and stringifies an instruction as well as its parameters.
        /// </summary>
        /// <param name="currPgrmCtr">The value that the program counter would theoretically be at
        /// upon encountering this instruction.</param>
        /// <param name="inst">The disassembled instruction to stringify.</param>
        /// <param name="symTable">A reverse symbol table used to map addresses back to label names.</param>
        /// <returns>A string representing the instruction and its parameters that can be written to a text file.</returns>
        public string GetFormattedInstruction(int currPgrmCtr, DisassembledInstruction inst, ReverseSymbolTable symTable)
        {
            string retStr = string.Empty;

            // first, see if the program counter has a symbol mapped to it.
            if (symTable.ContainsSymbol(currPgrmCtr))
            {
                Symbol sym = symTable.GetSymbol(currPgrmCtr);
                retStr += sym.LabelName + ":\t\t";
            }
            else
            {
                retStr += "\t\t\t";
            }

            retStr += m_Name;
            return(retStr);
        }
Beispiel #7
0
        /// <summary>
        /// Formats and stringifies an instruction as well as its parameters.
        /// </summary>
        /// <param name="currPgrmCtr">The value that the program counter would theoretically be at
        /// upon encountering this instruction.</param>
        /// <param name="inst">The disassembled instruction to stringify.</param>
        /// <param name="symTable">A reverse symbol table used to map addresses back to label names.</param>
        /// <returns>A string representing the instruction and its parameters that can be written to a text file.</returns>
        public string GetFormattedInstruction(int currPgrmCtr, DisassembledInstruction inst, ReverseSymbolTable symTable)
        {
            string retStr = string.Empty;

            // first, see if the program counter has a symbol mapped to it.
            if (symTable.ContainsSymbol(currPgrmCtr))
            {
                Symbol sym = symTable.GetSymbol(currPgrmCtr);
                retStr += sym.LabelName + ":\t\t";
            }
            else
            {
                retStr += "\t\t\t";
            }

            retStr += m_Name + ' ';
            if (inst.Parameters.Count() != 3)
            {
                throw new ArgumentException("sb instruction expected 3 arguments, received " + inst.Parameters.Count());
            }

            string rs1 = ReverseRegisterMap.GetStringifiedRegisterValue(inst.Parameters.ElementAt(0));
            string rs2 = ReverseRegisterMap.GetStringifiedRegisterValue(inst.Parameters.ElementAt(1));

            retStr += rs1 + ", " + rs2 + ", ";

            int offset = inst.Parameters.ElementAt(2);

            int address = currPgrmCtr + offset;

            // see if there's a symbol mapped to it.
            if (symTable.ContainsSymbol(address))
            {
                Symbol sym = symTable.GetSymbol(address);
                retStr += sym.LabelName;
            }
            else
            {
                retStr += "0x" + address.ToString("X2");
            }

            return(retStr);
        }
Beispiel #8
0
        private static void DoCBPrefix(ref byte[] instr, ref DisassembledInstruction disasm)
        {
            byte b = instr[1];

            disasm.Length = 2;
            switch (GetField(Field.x, b))
            {
            case 0:
                disasm.Disassembly = TableRot[GetField(Field.y, b)] + TableR[GetField(Field.z, b)];
                break;

            case 1:
                disasm.Disassembly = "BIT " + GetField(Field.y, b).ToString() + ", " + TableR[GetField(Field.z, b)];
                break;

            case 2:
                disasm.Disassembly = "RES " + GetField(Field.y, b).ToString() + ", " + TableR[GetField(Field.z, b)];
                break;

            case 3:
                disasm.Disassembly = "SET " + GetField(Field.y, b).ToString() + ", " + TableR[GetField(Field.z, b)];
                break;
            }
        }
Beispiel #9
0
        protected void HandleDisassemble(string[] tokens)
        {
            if (tokens is null)
            {
                throw new ArgumentNullException(nameof(tokens));
            }

            int start;
            int num_instructions = 8;

            if (tokens.Length > 2)
            {
                try
                {
                    num_instructions = ParseInt(tokens[2]);
                }
                catch (FormatException)
                {
                    writer.WriteLine($"Invalid instruction count: {tokens[2]}");
                    return;
                }
            }

            if (tokens.Length > 1)
            {
                string address = tokens[1];
                try
                {
                    start = ParseInt(address);
                }
                catch (FormatException)
                {
                    writer.WriteLine($"Unknown address [{address}]");
                    return;
                }
            }
            else
            {
                start = cpu.GetPC();
            }

            int count = 0;

            buffer = new StringBuilder(80);
            while (start < memory.Size() && count < num_instructions)
            {
                buffer.Clear();
                int                     opcode = cpu.ReadMemoryWord(start);
                IInstruction            i      = cpu.GetInstructionFor(opcode);
                DisassembledInstruction di     = i.Disassemble(start, opcode);
                if (showBytes)
                {
                    di.FormatInstruction(buffer);
                }
                else
                {
                    di.ShortFormat(buffer);
                }

                writer.WriteLine(buffer.ToString());
                start += di.Size();
                count++;
            }
        }
Beispiel #10
0
        private static void DoIndexPrefix(ref byte[] instr, ref DisassembledInstruction disasm, string indexRegister)
        {
            unchecked
            {
                byte b = instr[1];
                switch (b)
                {
                case 0x21:
                    disasm.Length      = 4;
                    disasm.Disassembly = "LD " + indexRegister + ", " + (instr[2] | (instr[3] << 8)).ToString("X4");
                    break;

                case 0x22:
                    disasm.Length      = 4;
                    disasm.Disassembly = "LD (" + (instr[2] | (instr[3] << 8)).ToString("X4") + "), " + indexRegister;
                    break;

                case 0x2A:
                    disasm.Length      = 4;
                    disasm.Disassembly = "LD " + indexRegister + ", (" + (instr[2] | (instr[3] << 8)).ToString("X4") + ")";
                    break;

                case 0x23:
                    disasm.Length      = 2;
                    disasm.Disassembly = "INC " + indexRegister;
                    break;

                case 0x2B:
                    disasm.Length      = 2;
                    disasm.Disassembly = "DEC " + indexRegister;
                    break;

                case 0x24:
                    disasm.Length      = 2;
                    disasm.Disassembly = "INC " + indexRegister + "H";
                    break;

                case 0x2C:
                    disasm.Length      = 2;
                    disasm.Disassembly = "INC " + indexRegister + "L";
                    break;

                case 0x34:
                    disasm.Length      = 3;
                    disasm.Disassembly = "INC (" + indexRegister + " + " + ((sbyte)instr[2]).ToString("X2") + ")";
                    break;

                case 0x25:
                    disasm.Length      = 2;
                    disasm.Disassembly = "DEC " + indexRegister + "H";
                    break;

                case 0x2D:
                    disasm.Length      = 2;
                    disasm.Disassembly = "DEC " + indexRegister + "L";
                    break;

                case 0x35:
                    disasm.Length      = 3;
                    disasm.Disassembly = "DEC (" + indexRegister + " + " + ((sbyte)instr[2]).ToString("X2") + ")";
                    break;

                case 0x26:
                    disasm.Length      = 3;
                    disasm.Disassembly = "LD " + indexRegister + "H, " + ((sbyte)instr[2]).ToString("X2");
                    break;

                case 0x2E:
                    disasm.Length      = 3;
                    disasm.Disassembly = "LD " + indexRegister + "L, " + ((sbyte)instr[2]).ToString("X2");
                    break;

                case 0x36:
                    disasm.Length      = 4;
                    disasm.Disassembly = "LD (" + indexRegister + " + " + ((sbyte)instr[2]).ToString("X2") + "), " + instr[3].ToString("X2");
                    break;

                case 0x09:
                    disasm.Length      = 2;
                    disasm.Disassembly = "ADD " + indexRegister + ", BC";
                    break;

                case 0x19:
                    disasm.Length      = 2;
                    disasm.Disassembly = "ADD " + indexRegister + ", DE";
                    break;

                case 0x29:
                    disasm.Length      = 2;
                    disasm.Disassembly = "ADD " + indexRegister + ", " + indexRegister;
                    break;

                case 0x39:
                    disasm.Length      = 2;
                    disasm.Disassembly = "ADD " + indexRegister + ", SP";
                    break;

                case 0x64:
                case 0x65:
                case 0x6C:
                case 0x6D:
                    disasm.Length      = 2;
                    disasm.Disassembly = "LD " + indexRegister + TableR[GetField(Field.y, b)] + ", " + indexRegister + TableR[GetField(Field.z, b)];
                    break;

                case 0x70:
                case 0x71:
                case 0x72:
                case 0x73:
                case 0x74:
                case 0x75:
                case 0x77:
                    disasm.Length      = 3;
                    disasm.Disassembly = "LD (" + indexRegister + " + " + ((sbyte)instr[2]).ToString("X2") + "), " + TableR[GetField(Field.z, b)];
                    break;

                case 0x46:
                case 0x4E:
                case 0x56:
                case 0x5E:
                case 0x66:
                case 0x6E:
                case 0x7E:
                    disasm.Length      = 3;
                    disasm.Disassembly = "LD " + TableR[GetField(Field.y, b)] + ", (" + indexRegister + " + " + ((sbyte)instr[2]).ToString("X2") + ")";
                    break;

                case 0x84:
                case 0x85:
                case 0x8C:
                case 0x8D:
                case 0x94:
                case 0x95:
                case 0x9C:
                case 0x9D:
                case 0xA4:
                case 0xA5:
                case 0xAC:
                case 0xAD:
                case 0xB4:
                case 0xB5:
                case 0xBC:
                case 0xBD:
                    disasm.Length      = 2;
                    disasm.Disassembly = TableAlu[GetField(Field.y, b)] + indexRegister + TableR[GetField(Field.z, b)];
                    break;

                case 0x86:
                case 0x8E:
                case 0x96:
                case 0x9E:
                case 0xA6:
                case 0xAE:
                case 0xB6:
                case 0xBE:
                    disasm.Length      = 3;
                    disasm.Disassembly = TableAlu[GetField(Field.y, b)] + "(" + indexRegister + " + " + ((sbyte)instr[2]).ToString("X2") + ")";
                    break;

                case 0xE1:
                    disasm.Length      = 2;
                    disasm.Disassembly = "POP " + indexRegister;
                    break;

                case 0xE9:
                    disasm.Length      = 2;
                    disasm.Disassembly = "JP (" + indexRegister + ")";
                    break;

                case 0xE3:
                    disasm.Length      = 2;
                    disasm.Disassembly = "EX (SP), " + indexRegister;
                    break;

                case 0xE5:
                    disasm.Length      = 2;
                    disasm.Disassembly = "PUSH " + indexRegister;
                    break;

                case 0xCB:
                    b             = instr[3];
                    disasm.Length = 4;
                    switch (GetField(Field.x, b))
                    {
                    case 0:
                        if (GetField(Field.z, b) != 6)
                        {
                            disasm.Disassembly = TableRot[GetField(Field.y, b)] + TableR[GetField(Field.z, b)] + ", (" + indexRegister + " + " + ((sbyte)instr[2]).ToString("X2") + ")";
                        }
                        else
                        {
                            disasm.Disassembly = TableRot[GetField(Field.y, b)] + "(" + indexRegister + " + " + ((sbyte)instr[2]).ToString("X2") + ")";
                        }
                        break;

                    case 1:
                        disasm.Disassembly = "BIT " + GetField(Field.y, b).ToString() + ", (" + indexRegister + " + " + ((sbyte)instr[2]).ToString("X2") + ")";
                        break;

                    case 2:
                        if (GetField(Field.z, b) != 6)
                        {
                            disasm.Disassembly = "RES " + TableR[GetField(Field.z, b)] + ", " + GetField(Field.y, b).ToString() + ", (" + indexRegister + " + " + ((sbyte)instr[2]).ToString("X2") + ")";
                        }
                        else
                        {
                            disasm.Disassembly = "RES " + GetField(Field.y, b).ToString() + ", (" + indexRegister + " + " + ((sbyte)instr[2]).ToString("X2") + ")";
                        }
                        break;

                    case 3:
                        if (GetField(Field.z, b) != 6)
                        {
                            disasm.Disassembly = "SET " + TableR[GetField(Field.z, b)] + ", " + GetField(Field.y, b).ToString() + ", (" + indexRegister + " + " + ((sbyte)instr[2]).ToString("X2") + ")";
                        }
                        else
                        {
                            disasm.Disassembly = "SET " + GetField(Field.y, b).ToString() + ", (" + indexRegister + " + " + ((sbyte)instr[2]).ToString("X2") + ")";
                        }
                        break;
                    }
                    break;

                case 0xF9:
                    disasm.Length      = 2;
                    disasm.Disassembly = "LD SP, " + indexRegister;
                    break;

                // No case ED; index registers forbidden on ED block.
                // No case DD or FD: Only last prefix matters.
                default:
                    disasm.Length      = 1;
                    disasm.Disassembly = "NONI";
                    break;
                }
            }
        }
Beispiel #11
0
        private static void DoEDPrefix(ref byte[] instr, ref DisassembledInstruction disasm)
        {
            byte b = instr[1];

            switch (GetField(Field.x, b))
            {
            case 0:
            case 3:
                disasm.Length      = 2;
                disasm.Disassembly = "NONI \\ NOP";
                break;

            case 1:
                disasm.Length = 2;
                switch (GetField(Field.z, b))
                {
                case 0:
                    if (b != 0x70)
                    {
                        disasm.Disassembly = "IN " + TableR[GetField(Field.y, b)] + ", (C)";
                    }
                    else
                    {
                        disasm.Disassembly = "IN (C)";
                    }
                    break;

                case 1:
                    if (b != 0x70)
                    {
                        disasm.Disassembly = "OUT (C), " + TableR[GetField(Field.y, b)];
                    }
                    else
                    {
                        disasm.Disassembly = "OUT (C), 0";
                    }
                    break;

                case 2:
                    disasm.Length = 2;
                    if (GetField(Field.q, b) == 0)
                    {
                        disasm.Disassembly = "SBC HL, " + TableRP[GetField(Field.p, b)];
                    }
                    else
                    {
                        disasm.Disassembly = "ADC HL, " + TableRP[GetField(Field.p, b)];
                    }
                    break;

                case 3:
                    disasm.Length = 4;
                    if (GetField(Field.q, b) == 0)
                    {
                        disasm.Disassembly = "LD (" + (instr[2] | (instr[3] << 8)).ToString("X4") + "), " + TableRP[GetField(Field.p, b)];
                    }
                    else
                    {
                        disasm.Disassembly = "LD " + TableRP[GetField(Field.p, b)] + ", (" + (instr[2] | (instr[3] << 8)).ToString("X4") + ")";
                    }
                    break;

                case 4:
                    disasm.Length      = 2;
                    disasm.Disassembly = "NEG";
                    break;

                case 5:
                    disasm.Length = 2;
                    if (GetField(Field.y, b) != 1)
                    {
                        disasm.Disassembly = "RETN";
                    }
                    else
                    {
                        disasm.Disassembly = "RETI";
                    }
                    break;

                case 6:
                    disasm.Length      = 2;
                    disasm.Disassembly = "IM " + TableIM[GetField(Field.y, b)];
                    break;

                case 7:
                    disasm.Length = 2;
                    switch (GetField(Field.y, b))
                    {
                    case 0:
                        disasm.Disassembly = "LD I, A";
                        break;

                    case 1:
                        disasm.Disassembly = "LD R, A";
                        break;

                    case 2:
                        disasm.Disassembly = "LD A, I";
                        break;

                    case 3:
                        disasm.Disassembly = "LD A, R";
                        break;

                    case 4:
                        disasm.Disassembly = "RRD";
                        break;

                    case 5:
                        disasm.Disassembly = "RLD";
                        break;

                    case 6:
                    case 7:
                        disasm.Disassembly = "NOP";
                        break;
                    }
                    break;
                }
                break;

            case 2:
                disasm.Length = 2;
                switch (b)
                {
                case 0xA0:
                    disasm.Disassembly = "LDI";
                    break;

                case 0xA1:
                    disasm.Disassembly = "CPI";
                    break;

                case 0xA2:
                    disasm.Disassembly = "INI";
                    break;

                case 0xA3:
                    disasm.Disassembly = "OUTI";
                    break;

                case 0xA8:
                    disasm.Disassembly = "LDD";
                    break;

                case 0xA9:
                    disasm.Disassembly = "CPD";
                    break;

                case 0xAA:
                    disasm.Disassembly = "IND";
                    break;

                case 0xAB:
                    disasm.Disassembly = "OUTD";
                    break;

                case 0xB0:
                    disasm.Disassembly = "LDIR";
                    break;

                case 0xB1:
                    disasm.Disassembly = "CPIR";
                    break;

                case 0xB2:
                    disasm.Disassembly = "INIR";
                    break;

                case 0xB3:
                    disasm.Disassembly = "OUIR";
                    break;

                case 0xB8:
                    disasm.Disassembly = "LDDR";
                    break;

                case 0xB9:
                    disasm.Disassembly = "CPDR";
                    break;

                case 0xBA:
                    disasm.Disassembly = "INDR";
                    break;

                case 0xBC:
                    disasm.Disassembly = "OTDR";
                    break;

                default:
                    disasm.Disassembly = "NONI \\ NOP";
                    break;
                }
                break;
            }
        }
Beispiel #12
0
        public static DisassembledInstruction DisassembleInstruction(byte[] instr, ushort baseAddress, bool hasBaseAddress)
        {
            unchecked {
                DisassembledInstruction disasm = default(DisassembledInstruction);
                disasm.Length      = 1;
                disasm.Disassembly = "ERROR";
                int b = instr[0];
                // Do you like switches? 'Cause that's kind of kinky.
                switch (GetField(Field.x, b))
                {
                case 0:
                    switch (GetField(Field.z, b))
                    {
                    case 0:
                        switch (GetField(Field.y, b))
                        {
                        case 0:
                            disasm.Length      = 1;
                            disasm.Disassembly = "NOP";
                            break;

                        case 1:
                            disasm.Length      = 1;
                            disasm.Disassembly = "EX AF, AF'";
                            break;

                        case 2:
                            disasm.Length = 2;
                            if (hasBaseAddress)
                            {
                                disasm.Disassembly = "DJNZ " + ((sbyte)instr[1] + (baseAddress + 2)).ToString("X4");
                            }
                            else
                            {
                                disasm.Disassembly = "DJNZ " + ((sbyte)instr[1]).ToString("X2");
                            }
                            break;

                        case 3:
                            disasm.Length = 2;
                            if (hasBaseAddress)
                            {
                                disasm.Disassembly = "JR " + ((sbyte)instr[1] + (baseAddress + 2)).ToString("X4");
                            }
                            else
                            {
                                disasm.Disassembly = "JR " + ((sbyte)instr[1]).ToString("X2");
                            }
                            break;

                        case 4:
                        case 5:
                        case 6:
                        case 7:
                            disasm.Length = 2;
                            if (hasBaseAddress)
                            {
                                disasm.Disassembly = "JR " + TableCC[GetField(Field.qq, b)] + ", " + ((sbyte)instr[1] + (baseAddress + 2)).ToString("X4");
                            }
                            else
                            {
                                disasm.Disassembly = "JR " + TableCC[GetField(Field.qq, b)] + ", " + ((sbyte)instr[1]).ToString("X2");
                            }
                            break;
                        }
                        break;

                    case 1:
                        switch (GetField(Field.q, b))
                        {
                        case 0:
                            disasm.Length      = 3;
                            disasm.Disassembly = "LD " + TableRP[GetField(Field.p, b)] + ", " + (instr[1] | (instr[2] << 8)).ToString("X4");
                            break;

                        case 1:
                            disasm.Length      = 1;
                            disasm.Disassembly = "ADD HL, " + TableRP[GetField(Field.p, b)];
                            break;
                        }
                        break;

                    case 2:
                        switch (GetField(Field.y, b))
                        {
                        case 0:
                            disasm.Length      = 1;
                            disasm.Disassembly = "LD (BC), A";
                            break;

                        case 1:
                            disasm.Length      = 1;
                            disasm.Disassembly = "LD A, (BC)";
                            break;

                        case 2:
                            disasm.Length      = 1;
                            disasm.Disassembly = "LD (DE), A";
                            break;

                        case 3:
                            disasm.Length      = 1;
                            disasm.Disassembly = "LD A, (DE)";
                            break;

                        case 4:
                            disasm.Length      = 3;
                            disasm.Disassembly = "LD (" + (instr[1] | (instr[2] << 8)).ToString("X4") + "), HL";
                            break;

                        case 5:
                            disasm.Length      = 3;
                            disasm.Disassembly = "LD HL, (" + (instr[1] | (instr[2] << 8)).ToString("X4") + ")";
                            break;

                        case 6:
                            disasm.Length      = 3;
                            disasm.Disassembly = "LD (" + (instr[1] | (instr[2] << 8)).ToString("X4") + "), A";
                            break;

                        case 7:
                            disasm.Length      = 3;
                            disasm.Disassembly = "LD A, (" + (instr[1] | (instr[2] << 8)).ToString("X4") + ")";
                            break;
                        }
                        break;

                    case 3:
                        disasm.Length = 1;
                        switch (GetField(Field.q, b))
                        {
                        case 0:
                            disasm.Disassembly = "INC " + TableRP[GetField(Field.p, b)];
                            break;

                        case 1:
                            disasm.Disassembly = "DEC " + TableRP[GetField(Field.p, b)];
                            break;
                        }
                        break;

                    case 4:
                        disasm.Length      = 1;
                        disasm.Disassembly = "INC " + TableR[GetField(Field.y, b)];
                        break;

                    case 5:
                        disasm.Length      = 1;
                        disasm.Disassembly = "DEC " + TableR[GetField(Field.y, b)];
                        break;

                    case 6:
                        disasm.Length      = 2;
                        disasm.Disassembly = "LD " + TableR[GetField(Field.y, b)] + ", " + instr[1].ToString("X2");
                        break;

                    case 7:
                        disasm.Length = 1;
                        switch (GetField(Field.y, b))
                        {
                        case 0:
                            disasm.Disassembly = "RLCA";
                            break;

                        case 1:
                            disasm.Disassembly = "RRCA";
                            break;

                        case 2:
                            disasm.Disassembly = "RLA";
                            break;

                        case 3:
                            disasm.Disassembly = "RRA";
                            break;

                        case 4:
                            disasm.Disassembly = "DAA";
                            break;

                        case 5:
                            disasm.Disassembly = "CPL";
                            break;

                        case 6:
                            disasm.Disassembly = "SCF";
                            break;

                        case 7:
                            disasm.Disassembly = "CCF";
                            break;
                        }
                        break;
                    }
                    break;

                case 1:
                    disasm.Length = 1;
                    if (b == 0x76)
                    {
                        disasm.Disassembly = "HALT";
                    }
                    else
                    {
                        disasm.Disassembly = "LD " + TableR[GetField(Field.y, b)] + ", " + TableR[GetField(Field.z, b)];
                    }
                    break;

                case 2:
                    disasm.Length      = 1;
                    disasm.Disassembly = TableAlu[GetField(Field.y, b)] + TableR[GetField(Field.z, b)];
                    break;

                case 3:
                    switch (GetField(Field.z, b))
                    {
                    case 0:
                        disasm.Length      = 1;
                        disasm.Disassembly = "RET " + TableCC[GetField(Field.y, b)];
                        break;

                    case 1:
                        disasm.Length = 1;
                        switch (GetField(Field.q, b))
                        {
                        case 0:
                            disasm.Disassembly = "POP " + TableRP2[GetField(Field.p, b)];
                            break;

                        case 1:
                            switch (GetField(Field.p, b))
                            {
                            case 0:
                                disasm.Disassembly = "RET";
                                break;

                            case 1:
                                disasm.Disassembly = "EXX";
                                break;

                            case 2:
                                disasm.Disassembly = "JP (HL)";
                                break;

                            case 3:
                                disasm.Disassembly = "LD SP, HL";
                                break;
                            }
                            break;
                        }
                        break;

                    case 2:
                        disasm.Length      = 3;
                        disasm.Disassembly = "JP " + TableCC[GetField(Field.y, b)] + ", " + (instr[1] | (instr[2] << 8)).ToString("X4");
                        break;

                    case 3:
                        switch (GetField(Field.y, b))
                        {
                        case 0:
                            disasm.Length      = 3;
                            disasm.Disassembly = "JP " + (instr[1] | (instr[2] << 8)).ToString("X4");
                            break;

                        case 1:             // CB Prefix
                            DoCBPrefix(ref instr, ref disasm);
                            break;

                        case 2:
                            disasm.Length      = 2;
                            disasm.Disassembly = "OUT (" + instr[1].ToString("X2") + "), A";
                            break;

                        case 3:
                            disasm.Length      = 2;
                            disasm.Disassembly = "IN A, (" + instr[1].ToString("X2") + ")";
                            break;

                        case 4:
                            disasm.Length      = 1;
                            disasm.Disassembly = "EX (SP), HL";
                            break;

                        case 5:
                            disasm.Length      = 1;
                            disasm.Disassembly = "EX DE, HL";
                            break;

                        case 6:
                            disasm.Length      = 1;
                            disasm.Disassembly = "DI";
                            break;

                        case 7:
                            disasm.Length      = 1;
                            disasm.Disassembly = "EI";
                            break;
                        }
                        break;

                    case 4:
                        disasm.Length      = 3;
                        disasm.Disassembly = "CALL " + TableCC[GetField(Field.y, b)] + ", " + (instr[1] | (instr[2] << 8)).ToString("X4");
                        break;

                    case 5:
                        switch (GetField(Field.q, b))
                        {
                        case 0:
                            disasm.Length      = 1;
                            disasm.Disassembly = "PUSH " + TableRP2[GetField(Field.p, b)];
                            break;

                        case 1:
                            switch (b)
                            {
                            case 0xCD:
                                disasm.Length      = 3;
                                disasm.Disassembly = "CALL " + (instr[1] | (instr[2] << 8)).ToString("X4");
                                break;

                            case 0xDD:
                                DoIndexPrefix(ref instr, ref disasm, "IX");
                                break;

                            case 0xED:
                                DoEDPrefix(ref instr, ref disasm);
                                break;

                            case 0xFD:
                                DoIndexPrefix(ref instr, ref disasm, "IY");
                                break;
                            }
                            break;
                        }
                        break;

                    case 6:
                        disasm.Length      = 2;
                        disasm.Disassembly = TableAlu[GetField(Field.y, b)] + instr[1].ToString("X2");
                        break;

                    case 7:
                        disasm.Length      = 1;
                        disasm.Disassembly = "RST " + (GetField(Field.y, b) * 8).ToString("X2") + "h";
                        break;
                    }
                    break;
                }
                return(disasm);
            }
        }