/// <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); } }
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}"); }
/// <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(); } }
/// <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); }
/// <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); }
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; } }
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++; } }
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; } } }
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; } }
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); } }