public OpcodeTableEntry(Action f, string d, ArgType[] a, OpcodeTable nt = null) { func = f; dasm = d; args = a; nextTable = nt; }
protected void DoExecute() { byte opCode; int offset = 0; OpcodeTableEntry operation; OpcodeTable current = opcodeTable; ushort start = pc; while (true) { if (execIntVector) { opCode = intVector; tStates += 6; } else { opCode = Read8((ushort)(pc + offset)); pc++; tStates++; } IncR(); operation = current.entries[opCode]; if (operation == null) { throw new NullReferenceException( string.Format("Operation is not implemented at 0x{0:X4}", start)); } if (operation.func != null) { pc = (ushort)(pc - offset); operation.func(); pc = (ushort)(pc + offset); break; } if (operation.nextTable != null) { current = operation.nextTable; offset = current.opcodeOffset; if (offset > 0) { DecR(); } } else { break; } } }
virtual protected void CreateTables() { // Creating tables opcodeTable = new OpcodeTable(); opcodeTableCB = new OpcodeTable(); opcodeTableDD = new OpcodeTable(); opcodeTableED = new OpcodeTable(); opcodeTableFD = new OpcodeTable(); opcodeTableDDCB = new OpcodeTable(1); opcodeTableFDCB = new OpcodeTable(1); // Linking tables opcodeTable.entries[0xCB] = new OpcodeTableEntry(null, "", null, opcodeTableCB); opcodeTable.entries[0xDD] = new OpcodeTableEntry(null, "", null, opcodeTableDD); opcodeTable.entries[0xED] = new OpcodeTableEntry(null, "", null, opcodeTableED); opcodeTable.entries[0xFD] = new OpcodeTableEntry(null, "", null, opcodeTableFD); opcodeTableDD.entries[0xCB] = new OpcodeTableEntry(null, "", null, opcodeTableDDCB); opcodeTableFD.entries[0xCB] = new OpcodeTableEntry(null, "", null, opcodeTableFDCB); opcodeTableDD.entries[0xDD] = new OpcodeTableEntry(null, "", null, opcodeTableDD); opcodeTableFD.entries[0xDD] = new OpcodeTableEntry(null, "", null, opcodeTableDD); opcodeTableDD.entries[0xFD] = new OpcodeTableEntry(null, "", null, opcodeTableFD); opcodeTableFD.entries[0xFD] = new OpcodeTableEntry(null, "", null, opcodeTableFD); }
// Disassemble(ushort addr) disassembles a single CPU operation // based at addr and puts it into result variable. Returns the addr // of the next instruction // public ushort Disassemble(ushort addr, out string result) { ushort start = addr; byte opCode; int offset = 0; OpcodeTableEntry operation; OpcodeTable current = opcodeTable; while (true) { opCode = memory.Read8((ushort)(addr + offset)); addr++; operation = current.entries[opCode]; if (operation == null) { result = string.Format("Error disassembling at 0x{0:X4}", start); return(addr); } if (operation.func != null) { addr = (ushort)(addr - offset); object[] args = new object[operation.args.Length]; for (int j = 0; j < operation.args.Length; j++) { var argType = operation.args[j]; switch (argType) { case ArgType.Byte: byte value = Read8(addr++); if (dasmMode == DisassembleMode.Dec) { args[j] = value; } else { args[j] = string.Format("${0:X2}", value); } break; case ArgType.Word: ushort value16 = Read16(addr); addr += 2; if (dasmMode == DisassembleMode.Dec) { args[j] = value16; } else { args[j] = string.Format("${0:X4}", value16); } break; case ArgType.Offset: var idxOffset = (SByte)Read8(addr++); string offFormat; if (idxOffset >= 0) { offFormat = "+{0}"; } else { offFormat = "{0}"; } args[j] = string.Format(offFormat, idxOffset); break; } } addr = (ushort)(addr + offset); result = string.Format(operation.dasm, args); return(addr); } if (operation.nextTable != null) { current = operation.nextTable; offset = current.opcodeOffset; } else { break; } } result = "Disassembler logic error"; return(addr); }