oscar64/oscar64/Disassembler.cpp

865 lines
28 KiB
C++

#include "Disassembler.h"
#include "ByteCodeGenerator.h"
#include "Assembler.h"
#include "InterCode.h"
#include "Linker.h"
ByteCodeDisassembler::ByteCodeDisassembler(void)
{
}
ByteCodeDisassembler::~ByteCodeDisassembler(void)
{
}
const char* ByteCodeDisassembler::TempName(uint8 tmp, char* buffer, InterCodeProcedure* proc, Linker* linker)
{
if (tmp == BC_REG_ADDR)
return "ADDR";
else if (tmp == BC_REG_ACCU)
return "ACCU";
else if (tmp >= BC_REG_FPARAMS && tmp < BC_REG_FPARAMS_END)
{
sprintf_s(buffer, 10, "P%d", tmp - BC_REG_FPARAMS);
return buffer;
}
else if (proc && tmp >= BC_REG_TMP && tmp < BC_REG_TMP + proc->mTempSize)
{
int i = 0;
while (i < proc->mTempOffset.Size() && proc->mTempOffset[i] != tmp - BC_REG_TMP)
i++;
if (i < proc->mTempOffset.Size())
sprintf_s(buffer, 10, "T%d", i);
else
sprintf_s(buffer, 10, "$%02x", tmp);
return buffer;
}
else if (linker)
{
LinkerObject* obj = linker->FindObjectByAddr(tmp);
if (obj && obj->mIdent)
sprintf_s(buffer, 40, "$%02x; %s + %d", tmp, obj->mIdent->mString, tmp - obj->mAddress);
else
sprintf_s(buffer, 10, "$%02x", tmp);
return buffer;
}
else
{
sprintf_s(buffer, 10, "$%02x", tmp);
return buffer;
}
}
const char* ByteCodeDisassembler::AddrName(int addr, char* buffer, Linker* linker)
{
if (linker)
{
LinkerObject* obj = linker->FindObjectByAddr(addr);
if (obj && obj->mIdent)
{
sprintf_s(buffer, 160, "%s + %d", obj->mIdent->mString, addr - obj->mAddress);
return buffer;
}
}
sprintf_s(buffer, 10, "$%04x", addr);
return buffer;
}
void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int bank, int start, int size, InterCodeProcedure* proc, const Ident* ident, Linker* linker)
{
fprintf(file, "--------------------------------------------------------------------\n");
if (proc && proc->mIdent)
fprintf(file, "%s:\n", proc->mIdent->mString);
else if (ident)
fprintf(file, "%s:\n", ident->mString);
char tbuffer[160], abuffer[160];
#if 0
for (int i = 0; i < proc->mTemporaries.Size(); i++)
printf("T%d = $%.2x\n", i, BC_REG_TMP + proc->mTempOffset[i]);
#endif
int i = 0;
while (i < size)
{
ByteCode bc = ByteCode(memory[start + i] / 2);
if (bank >= 0)
fprintf(file, "%02x:", bank);
fprintf(file, "%04x:\t", start + i);
i++;
switch (bc)
{
case BC_NOP:
fprintf(file, "NOP");
break;
case BC_EXIT:
fprintf(file, "EXIT");
break;
case BC_CONST_8:
fprintf(file, "MOVB\t%s, #%d", TempName(memory[start + i], tbuffer, proc, linker), memory[start + i + 1]);
i += 2;
break;
case BC_CONST_P8:
fprintf(file, "MOV\t%s, #%d", TempName(memory[start + i], tbuffer, proc, linker), memory[start + i + 1]);
i += 2;
break;
case BC_CONST_N8:
fprintf(file, "MOV\t%s, #%d", TempName(memory[start + i], tbuffer, proc, linker), int(memory[start + i + 1]) - 0x100);
i += 2;
break;
case BC_CONST_16:
fprintf(file, "MOV\t%s, #$%04x", TempName(memory[start + i], tbuffer, proc, linker), uint16(memory[start + i + 1] + 256 * memory[start + i + 2]));
i += 3;
break;
case BC_CONST_32:
fprintf(file, "MOVD\t%s, #$%08x", TempName(memory[start + i], tbuffer, proc, linker), uint32(memory[start + i + 1] + 256 * memory[start + i + 2] + 0x10000 * memory[start + i + 3] + 0x1000000 * memory[start + i + 4]));
i += 5;
break;
case BC_LOAD_REG_8:
fprintf(file, "MOVB\tACCU, %s", TempName(memory[start + i], tbuffer, proc, linker));
i += 1;
break;
case BC_STORE_REG_8:
fprintf(file, "MOVB\t%s, ACCU", TempName(memory[start + i], tbuffer, proc, linker));
i += 1;
break;
case BC_LOAD_REG_16:
fprintf(file, "MOV\tACCU, %s", TempName(memory[start + i], tbuffer, proc, linker));
i += 1;
break;
case BC_STORE_REG_16:
fprintf(file, "MOV\t%s, ACCU", TempName(memory[start + i], tbuffer, proc, linker));
i += 1;
break;
case BC_LOAD_REG_32:
fprintf(file, "MOVD\tACCU, %s", TempName(memory[start + i], tbuffer, proc, linker));
i += 1;
break;
case BC_STORE_REG_32:
fprintf(file, "MOVD\t%s, ACCU", TempName(memory[start + i], tbuffer, proc, linker));
i += 1;
break;
case BC_ADDR_REG:
fprintf(file, "MOV\tADDR, %s", TempName(memory[start + i], tbuffer, proc, linker));
i += 1;
break;
case BC_LOAD_ABS_8:
fprintf(file, "MOVB\t%s, %s", TempName(memory[start + i + 2], tbuffer, proc, linker), AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker));
i += 3;
break;
case BC_LOAD_ABS_U8:
fprintf(file, "MOVUB\t%s, %s", TempName(memory[start + i + 2], tbuffer, proc, linker), AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker));
i += 3;
break;
case BC_LOAD_ABS_16:
fprintf(file, "MOV\t%s, %s", TempName(memory[start + i + 2], tbuffer, proc, linker), AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker));
i += 3;
break;
case BC_LOAD_ABS_32:
fprintf(file, "MOVD\t%s, %s", TempName(memory[start + i + 2], tbuffer, proc, linker), AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker));
i += 3;
break;
case BC_LOAD_ABS_ADDR:
fprintf(file, "MOV\tADDR, %s", AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker));
i += 2;
break;
case BC_LEA_ABS:
fprintf(file, "LEA\t%s, %s", TempName(memory[start + i + 0], tbuffer, proc, linker), AddrName(uint16(memory[start + i + 1] + 256 * memory[start + i + 2]), abuffer, linker));
i += 3;
break;
case BC_LEA_ABS_INDEX:
fprintf(file, "LEAX\tADDR, %s + %s", AddrName(uint16(memory[start + i + 1] + 256 * memory[start + i + 2]), abuffer, linker), TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 3;
break;
case BC_LEA_ACCU_INDEX:
fprintf(file, "LEAX\tADDR, %s + ACCU", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1;
break;
case BC_LEA_ABS_INDEX_U8:
fprintf(file, "LEAXB\tADDR, %s + %s", AddrName(uint16(memory[start + i + 1] + 256 * memory[start + i + 2]), abuffer, linker), TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 3;
break;
case BC_STORE_ABS_8:
fprintf(file, "MOVB\t%s, %s", AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker), TempName(memory[start + i + 2], tbuffer, proc, linker));
i += 3;
break;
case BC_STORE_ABS_16:
fprintf(file, "MOV\t%s, %s", AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker), TempName(memory[start + i + 2], tbuffer, proc, linker));
i += 3;
break;
case BC_STORE_ABS_32:
fprintf(file, "MOVD\t%s, %s", AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker), TempName(memory[start + i + 2], tbuffer, proc, linker));
i += 3;
break;
case BC_LOAD_LOCAL_8:
fprintf(file, "MOVB\t%s, %d(FP)", TempName(memory[start + i + 0], tbuffer, proc, linker), memory[start + i + 1]);
i += 2;
break;
case BC_LOAD_LOCAL_U8:
fprintf(file, "MOVUB\t%s, %d(FP)", TempName(memory[start + i + 0], tbuffer, proc, linker), memory[start + i + 1]);
i += 2;
break;
case BC_LOAD_LOCAL_16:
fprintf(file, "MOV\t%s, %d(FP)", TempName(memory[start + i + 0], tbuffer, proc, linker), memory[start + i + 1]);
i += 2;
break;
case BC_LOAD_LOCAL_32:
fprintf(file, "MOVD\t%s, %d(FP)", TempName(memory[start + i + 0], tbuffer, proc, linker), memory[start + i + 1]);
i += 2;
break;
case BC_STORE_LOCAL_8:
fprintf(file, "MOVB\t%d(FP), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 2;
break;
case BC_STORE_LOCAL_16:
fprintf(file, "MOV\t%d(FP), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 2;
break;
case BC_STORE_LOCAL_32:
fprintf(file, "MOVD\t%d(FP), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 2;
break;
case BC_LEA_LOCAL:
fprintf(file, "LEA\t%s, %d(FP)", TempName(memory[start + i + 0], tbuffer, proc, linker), uint16(memory[start + i + 1] + 256 * memory[start + i + 2]));
i += 3;
break;
case BC_LEA_FRAME:
fprintf(file, "LEA\t%s, %d(SP)", TempName(memory[start + i + 0], tbuffer, proc, linker), uint16(memory[start + i + 1] + 256 * memory[start + i + 2]));
i += 3;
break;
case BC_STORE_FRAME_8:
fprintf(file, "MOVB\t%d(SP), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 2;
break;
case BC_STORE_FRAME_16:
fprintf(file, "MOV\t%d(SP), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 2;
break;
case BC_STORE_FRAME_32:
fprintf(file, "MOVD\t%d(SP), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 2;
break;
case BC_BINOP_ADDR_16:
fprintf(file, "ADD\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1;
break;
case BC_BINOP_ADDA_16:
fprintf(file, "ADD\t%s, ACCU", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1;
break;
case BC_BINOP_SUBR_16:
fprintf(file, "SUB\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1;
break;
case BC_BINOP_MULR_16:
fprintf(file, "MUL\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1;
break;
case BC_BINOP_DIVR_U16:
fprintf(file, "DIVU\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1;
break;
case BC_BINOP_MODR_U16:
fprintf(file, "MODU\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1;
break;
case BC_BINOP_DIVR_I16:
fprintf(file, "DIVS\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1;
break;
case BC_BINOP_MODR_I16:
fprintf(file, "MODS\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1;
break;
case BC_BINOP_ANDR_16:
fprintf(file, "AND\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1;
break;
case BC_BINOP_ORR_16:
fprintf(file, "OR\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1;
break;
case BC_BINOP_XORR_16:
fprintf(file, "XOR\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1;
break;
case BC_BINOP_SHLR_16:
fprintf(file, "SHL\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1;
break;
case BC_BINOP_SHRR_I16:
fprintf(file, "SHRU\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1;
break;
case BC_BINOP_SHRR_U16:
fprintf(file, "SHRI\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1;
break;
case BC_BINOP_ADDI_16:
fprintf(file, "ADD\t%s, #$%04X", TempName(memory[start + i + 0], tbuffer, proc, linker), uint16(memory[start + i + 1] + 256 * memory[start + i + 2]));
i += 3;
break;
case BC_BINOP_SUBI_16:
fprintf(file, "SUBR\t%s, #$%04X", TempName(memory[start + i + 0], tbuffer, proc, linker), uint16(memory[start + i + 1] + 256 * memory[start + i + 2]));
i += 3;
break;
case BC_BINOP_ANDI_16:
fprintf(file, "AND\t%s, #$%04X", TempName(memory[start + i + 0], tbuffer, proc, linker), uint16(memory[start + i + 1] + 256 * memory[start + i + 2]));
i += 3;
break;
case BC_BINOP_ORI_16:
fprintf(file, "OR\t%s, #$%04X", TempName(memory[start + i + 0], tbuffer, proc, linker), uint16(memory[start + i + 1] + 256 * memory[start + i + 2]));
i += 3;
break;
case BC_BINOP_MULI8_16:
fprintf(file, "MUL\t%s, #%d", TempName(memory[start + i + 0], tbuffer, proc, linker), memory[start + i + 1]);
i += 2;
break;
case BC_BINOP_ADDI_8:
fprintf(file, "ADDB\t%s, #$%04X", TempName(memory[start + i + 0], tbuffer, proc, linker), memory[start + i + 1]);
i += 2;
break;
case BC_BINOP_ANDI_8:
fprintf(file, "ANDB\t%s, #$%04X", TempName(memory[start + i + 0], tbuffer, proc, linker), memory[start + i + 1]);
i += 2;
break;
case BC_BINOP_ORI_8:
fprintf(file, "ORB\t%s, #$%04X", TempName(memory[start + i + 0], tbuffer, proc, linker), memory[start + i + 1]);
i += 2;
break;
case BC_LOOP_U8:
fprintf(file, "LOOPB\t%s, #$%02X", TempName(memory[start + i + 0], tbuffer, proc, linker), memory[start + i + 1]);
i += 2;
break;
case BC_CONV_I8_I16:
fprintf(file, "SEXT8\t%s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i++;
break;
case BC_BINOP_SHLI_16:
fprintf(file, "SHL\tACCU, #%d", uint8(memory[start + i + 0]));
i += 1;
break;
case BC_BINOP_SHRI_U16:
fprintf(file, "SHRU\tACCU, #%d", uint8(memory[start + i + 0]));
i += 1;
break;
case BC_BINOP_SHRI_I16:
fprintf(file, "SHRS\tACCU, #%d", uint8(memory[start + i + 0]));
i += 1;
break;
case BC_BINOP_CMPUR_16:
fprintf(file, "CMPU\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1;
break;
case BC_BINOP_CMPSR_16:
fprintf(file, "CMPS\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1;
break;
case BC_BINOP_CMPUI_16:
fprintf(file, "CMPU\tACCU, #$%04X", uint16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 2;
break;
case BC_BINOP_CMPSI_16:
fprintf(file, "CMPS\tACCU, #$%04X", int16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 2;
break;
case BC_BINOP_CMPUR_8:
fprintf(file, "CMPUB\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1;
break;
case BC_BINOP_CMPSR_8:
fprintf(file, "CMPSB\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1;
break;
case BC_BINOP_CMPUI_8:
fprintf(file, "CMPUB\tACCU, #$%04X", uint8(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 1;
break;
case BC_BINOP_CMPSI_8:
fprintf(file, "CMPSB\tACCU, #$%04X", int8(memory[start + i + 0]));
i += 1;
break;
case BC_BINOP_ADD_F32:
fprintf(file, "ADDF\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1;
break;
case BC_BINOP_SUB_F32:
fprintf(file, "SUBF\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1;
break;
case BC_BINOP_MUL_F32:
fprintf(file, "MULF\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1;
break;
case BC_BINOP_DIV_F32:
fprintf(file, "DIVF\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1;
break;
case BC_BINOP_CMP_F32:
fprintf(file, "CMPF\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1;
break;
case BC_COPY:
fprintf(file, "COPY\t#%d", memory[start + i + 0]);
i++;
break;
case BC_STRCPY:
fprintf(file, "STRCPY");
break;
case BC_COPY_LONG:
fprintf(file, "COPYL\t#%d", uint16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 2;
break;
case BC_OP_NEGATE_16:
fprintf(file, "NEG\tACCU");
break;
case BC_OP_INVERT_16:
fprintf(file, "NOT\tACCU");
break;
case BC_OP_NEGATE_F32:
fprintf(file, "NEGF\tACCU");
break;
case BC_OP_ABS_F32:
fprintf(file, "ABSF\tACCU");
break;
case BC_OP_FLOOR_F32:
fprintf(file, "FLOORF\tACCU");
break;
case BC_OP_CEIL_F32:
fprintf(file, "CEILF\tACCU");
break;
case BC_CONV_U16_F32:
fprintf(file, "CNVUF\tACCU");
break;
case BC_CONV_I16_F32:
fprintf(file, "CNVSF\tACCU");
break;
case BC_CONV_F32_U16:
fprintf(file, "CNVFU\tACCU");
break;
case BC_CONV_F32_I16:
fprintf(file, "CNVFS\tACCU");
break;
case BC_JUMPS:
fprintf(file, "JUMP\t$%04X", start + i + 1 + int8(memory[start + i + 0]));
i++;
break;
case BC_BRANCHS_EQ:
fprintf(file, "BEQ\t$%04X", start + i + 1 + int8(memory[start + i + 0]));
i++;
break;
case BC_BRANCHS_NE:
fprintf(file, "BNE\t$%04X", start + i + 1 + int8(memory[start + i + 0]));
i++;
break;
case BC_BRANCHS_GT:
fprintf(file, "BGT\t$%04X", start + i + 1 + int8(memory[start + i + 0]));
i++;
break;
case BC_BRANCHS_GE:
fprintf(file, "BGE\t$%04X", start + i + 1 + int8(memory[start + i + 0]));
i++;
break;
case BC_BRANCHS_LT:
fprintf(file, "BLT\t$%04X", start + i + 1 + int8(memory[start + i + 0]));
i++;
break;
case BC_BRANCHS_LE:
fprintf(file, "BLE\t$%04X", start + i + 1 + int8(memory[start + i + 0]));
i++;
break;
case BC_JUMPF:
fprintf(file, "JUMPF\t$%04X", start + i + 2 + int16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 2;
break;
case BC_BRANCHF_EQ:
fprintf(file, "BEQF\t$%04X", start + i + 2 + int16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 2;
break;
case BC_BRANCHF_NE:
fprintf(file, "BNEF\t$%04X", start + i + 2 + int16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 2;
break;
case BC_BRANCHF_GT:
fprintf(file, "BGTF\t$%04X", start + i + 2 + int16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 2;
break;
case BC_BRANCHF_GE:
fprintf(file, "BGEF\t$%04X", start + i + 2 + int16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 2;
break;
case BC_BRANCHF_LT:
fprintf(file, "BLTF\t$%04X", start + i + 2 + int16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 2;
break;
case BC_BRANCHF_LE:
fprintf(file, "BLEF\t$%04X", start + i + 2 + int16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 2;
break;
case BC_ENTER:
fprintf(file, "ENTER\t%d, %d", memory[start + i + 2], uint16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 3;
break;
case BC_RETURN:
fprintf(file, "RETURN\t%d, %d", memory[start + i], uint16(memory[start + i + 1] + 256 * memory[start + i + 2]));
i += 3;
break;
case BC_CALL_ADDR:
fprintf(file, "CALL\tADDR");
break;
case BC_CALL_ABS:
fprintf(file, "CALL\t%s", AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker));
i += 2;
break;
case BC_JSR:
fprintf(file, "JSR\t%s", AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker));
i += 2;
break;
case BC_PUSH_FRAME:
fprintf(file, "PUSH\t#$%04X", uint16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 2;
break;
case BC_POP_FRAME:
fprintf(file, "POP\t#$%04X", uint16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 2;
break;
case BC_LOAD_ADDR_8:
fprintf(file, "MOVB\t%s, %d(ADDR)", TempName(memory[start + i + 0], tbuffer, proc, linker), memory[start + i + 1]);
i += 2;
break;
case BC_LOAD_ADDR_U8:
fprintf(file, "MOVUB\t%s, %d(ADDR)", TempName(memory[start + i + 0], tbuffer, proc, linker), memory[start + i + 1]);
i += 2;
break;
case BC_LOAD_ADDR_16:
fprintf(file, "MOV\t%s, %d(ADDR)", TempName(memory[start + i + 0], tbuffer, proc, linker), memory[start + i + 1]);
i += 2;
break;
case BC_LOAD_ADDR_32:
fprintf(file, "MOVD\t%s, %d(ADDR)", TempName(memory[start + i + 0], tbuffer, proc, linker), memory[start + i + 1]);
i += 2;
break;
case BC_STORE_ADDR_8:
fprintf(file, "MOVB\t%d(ADDR), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 2;
break;
case BC_STORE_ADDR_16:
fprintf(file, "MOV\t%d(ADDR), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 2;
break;
case BC_STORE_ADDR_32:
fprintf(file, "MOVD\t%d(ADDR), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 2;
break;
case BC_EXTRT:
fprintf(file, "EXTRT\t%s, %s", TempName(memory[start + i + 2], tbuffer, proc, linker), AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker));
i += 3;
break;
}
fprintf(file, "\n");
}
}
NativeCodeDisassembler::NativeCodeDisassembler(void)
{
}
NativeCodeDisassembler::~NativeCodeDisassembler(void)
{
}
void NativeCodeDisassembler::DumpMemory(FILE* file, const uint8* memory, int bank, int start, int size, InterCodeProcedure* proc, const Ident* ident, Linker* linker, LinkerObject * lobj)
{
fprintf(file, "--------------------------------------------------------------------\n");
if (proc && proc->mIdent)
fprintf(file, "%s:\n", proc->mIdent->mString);
else if (ident)
fprintf(file, "%s:\n", ident->mString);
if (lobj->mSection->mType == LST_BSS)
{
if (bank >= 0)
fprintf(file, "%02x:", bank);
fprintf(file, "%04x : __ __ __ BSS\t%d\n", start, size);
}
else
{
int ip = start;
while (ip < start + size)
{
int n = 16;
if (ip + n > start + size)
n = start + size - ip;
if (bank >= 0)
fprintf(file, "%02x:", bank);
fprintf(file, "%04x : __ __ __ BYT", ip);
for (int i = 0; i < n; i++)
fprintf(file, " %02x", memory[ip + i]);
for (int i = n; i < 16; i++)
fprintf(file, " ");
fprintf(file, " : ");
for (int i = 0; i < n; i++)
{
int k = memory[ip + i];
if (k >= 32 && k < 127)
fprintf(file, "%c", k);
else
fprintf(file, ".");
}
fprintf(file, "\n");
ip += n;
}
}
}
void NativeCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int bank, int start, int size, InterCodeProcedure* proc, const Ident * ident, Linker* linker)
{
fprintf(file, "--------------------------------------------------------------------\n");
if (proc && proc->mIdent)
fprintf(file, "%s:\n", proc->mIdent->mString);
else if (ident)
fprintf(file, "%s:\n", ident->mString);
char tbuffer[160], abuffer[160];
int ip = start;
while (ip < start + size)
{
int iip = ip;
uint8 opcode = memory[ip++];
AsmInsData d = DecInsData[opcode];
int addr = 0;
if (proc && proc->mLinkerObject)
{
int i = 0;
while (i < proc->mLinkerObject->mRanges.Size() && iip - start != proc->mLinkerObject->mRanges[i].mOffset)
i++;
if (i < proc->mLinkerObject->mRanges.Size())
fprintf(file, ".%s:\n", proc->mLinkerObject->mRanges[i].mIdent->mString);
i = 0;
while (i < proc->mLinkerObject->mCodeLocations.Size() && iip - start != proc->mLinkerObject->mCodeLocations[i].mStart)
i++;
if (i < proc->mLinkerObject->mCodeLocations.Size())
fprintf(file, ";%4d, \"%s\"\n", proc->mLinkerObject->mCodeLocations[i].mLocation.mLine, proc->mLinkerObject->mCodeLocations[i].mLocation.mFileName);
}
if (bank >= 0)
fprintf(file, "%02x:", bank);
switch (d.mMode)
{
case ASMIM_IMPLIED:
fprintf(file, "%04x : %02x __ __ %s\n", iip, memory[iip], AsmInstructionNames[d.mType]);
break;
case ASMIM_IMMEDIATE:
addr = memory[ip++];
fprintf(file, "%04x : %02x %02x __ %s #$%02x\n", iip, memory[iip], memory[iip + 1], AsmInstructionNames[d.mType], addr);
break;
case ASMIM_ZERO_PAGE:
addr = memory[ip++];
fprintf(file, "%04x : %02x %02x __ %s %s %s\n", iip, memory[iip], memory[iip + 1], AsmInstructionNames[d.mType], TempName(addr, tbuffer, proc, linker), AddrName(addr, abuffer, proc, linker));
break;
case ASMIM_ZERO_PAGE_X:
addr = memory[ip++];
fprintf(file, "%04x : %02x %02x __ %s %s,x %s\n", iip, memory[iip], memory[iip + 1], AsmInstructionNames[d.mType], TempName(addr, tbuffer, proc, linker), AddrName(addr, abuffer, proc, linker));
break;
case ASMIM_ZERO_PAGE_Y:
addr = memory[ip++];
fprintf(file, "%04x : %02x %02x __ %s %s,y %s\n", iip, memory[iip], memory[iip + 1], AsmInstructionNames[d.mType], TempName(addr, tbuffer, proc, linker), AddrName(addr, abuffer, proc, linker));
break;
case ASMIM_ABSOLUTE:
addr = memory[ip] + 256 * memory[ip + 1];
fprintf(file, "%04x : %02x %02x %02x %s $%04x %s\n", iip, memory[iip], memory[iip + 1], memory[iip + 2], AsmInstructionNames[d.mType], addr, AddrName(addr, abuffer, proc, linker));
ip += 2;
break;
case ASMIM_ABSOLUTE_X:
addr = memory[ip] + 256 * memory[ip + 1];
fprintf(file, "%04x : %02x %02x %02x %s $%04x,x %s\n", iip, memory[iip], memory[iip + 1], memory[iip + 2], AsmInstructionNames[d.mType], addr, AddrName(addr, abuffer, proc, linker));
ip += 2;
break;
case ASMIM_ABSOLUTE_Y:
addr = memory[ip] + 256 * memory[ip + 1];
fprintf(file, "%04x : %02x %02x %02x %s $%04x,y %s\n", iip, memory[iip], memory[iip + 1], memory[iip + 2], AsmInstructionNames[d.mType], addr, AddrName(addr, abuffer, proc, linker));
ip += 2;
break;
case ASMIM_INDIRECT:
addr = memory[ip] + 256 * memory[ip + 1];
ip += 2;
fprintf(file, "%04x : %02x %02x %02x %s ($%04x)\n", iip, memory[iip], memory[iip + 1], memory[iip + 2], AsmInstructionNames[d.mType], addr);
break;
case ASMIM_INDIRECT_X:
addr = memory[ip++];
fprintf(file, "%04x : %02x %02x __ %s (%s,x) %s\n", iip, memory[iip], memory[iip + 1], AsmInstructionNames[d.mType], TempName(addr, tbuffer, proc, linker), AddrName(addr, abuffer, proc, linker));
break;
case ASMIM_INDIRECT_Y:
addr = memory[ip++];
fprintf(file, "%04x : %02x %02x __ %s (%s),y %s\n", iip, memory[iip], memory[iip + 1], AsmInstructionNames[d.mType], TempName(addr, tbuffer, proc, linker), AddrName(addr, abuffer, proc, linker));
break;
case ASMIM_RELATIVE:
addr = memory[ip++];
if (addr & 0x80)
addr = addr + ip - 256;
else
addr = addr + ip;
fprintf(file, "%04x : %02x %02x __ %s $%04x %s\n", iip, memory[iip], memory[iip + 1], AsmInstructionNames[d.mType], addr, AddrName(addr, abuffer, proc, linker));
break;
}
}
}
const char* NativeCodeDisassembler::AddrName(int addr, char* buffer, InterCodeProcedure* proc, Linker* linker)
{
if (linker)
{
LinkerObject* obj;
if (proc && proc->mLinkerObject && addr < 256)
{
obj = proc->mLinkerObject;
int i = 0;
while (i < obj->mZeroPageRanges.Size() && !(addr >= obj->mZeroPageRanges[i].mOffset && addr < obj->mZeroPageRanges[i].mOffset + obj->mZeroPageRanges[i].mSize))
i++;
if (i < obj->mZeroPageRanges.Size())
{
sprintf_s(buffer, 160, "; (%s + %d)", obj->mZeroPageRanges[i].mIdent->mString, addr - obj->mZeroPageRanges[i].mOffset);
return buffer;
}
}
if (proc && proc->mLinkerObject && addr >= proc->mLinkerObject->mAddress && addr < proc->mLinkerObject->mAddress + proc->mLinkerObject->mSize)
obj = proc->mLinkerObject;
else
obj = linker->FindObjectByAddr(addr);
if (obj && obj->mIdent)
{
int i = 0;
while (i < obj->mRanges.Size() && (addr - obj->mAddress < obj->mRanges[i].mOffset || addr - obj->mAddress - obj->mRanges[i].mOffset >= obj->mRanges[i].mSize))
i++;
if (i < obj->mRanges.Size())
sprintf_s(buffer, 160, "; (%s.%s + %d)", obj->mIdent->mString, obj->mRanges[i].mIdent->mString, addr - obj->mAddress - obj->mRanges[i].mOffset);
else
sprintf_s(buffer, 160, "; (%s + %d)", obj->mIdent->mString, addr - obj->mAddress);
return buffer;
}
}
return "";
}
const char* NativeCodeDisassembler::TempName(uint8 tmp, char* buffer, InterCodeProcedure* proc, Linker * linker)
{
if (tmp >= BC_REG_ADDR && tmp <= BC_REG_ADDR + 3)
{
sprintf_s(buffer, 10, "ADDR + %d", tmp - BC_REG_ADDR);
return buffer;
}
else if (tmp >= BC_REG_ACCU && tmp <= BC_REG_ACCU + 3)
{
sprintf_s(buffer, 10, "ACCU + %d", tmp - BC_REG_ACCU);
return buffer;
}
else if (tmp >= BC_REG_WORK && tmp <= BC_REG_WORK + 7)
{
sprintf_s(buffer, 10, "WORK + %d", tmp - BC_REG_WORK);
return buffer;
}
else if (tmp >= BC_REG_STACK && tmp <= BC_REG_STACK + 1)
{
sprintf_s(buffer, 10, "SP + %d", tmp - BC_REG_STACK);
return buffer;
}
else if (tmp >= BC_REG_IP && tmp <= BC_REG_IP + 1)
{
sprintf_s(buffer, 10, "IP + %d", tmp - BC_REG_IP);
return buffer;
}
else if (tmp >= BC_REG_FPARAMS && tmp < BC_REG_FPARAMS_END)
{
sprintf_s(buffer, 10, "P%d", tmp - BC_REG_FPARAMS);
return buffer;
}
else if (tmp >= BC_REG_LOCALS && tmp <= BC_REG_LOCALS + 1)
{
sprintf_s(buffer, 10, "FP + %d", tmp - BC_REG_LOCALS);
return buffer;
}
else if (proc && tmp >= BC_REG_TMP && tmp < BC_REG_TMP + proc->mTempSize)
{
int i = 0;
while (i < proc->mTempOffset.Size() && !(tmp >= proc->mTempOffset[i] + BC_REG_TMP && tmp < proc->mTempOffset[i] + proc->mTempSizes[i] + BC_REG_TMP))
i++;
if (i < proc->mTempOffset.Size())
sprintf_s(buffer, 10, "T%d + %d", i, tmp - (proc->mTempOffset[i] + BC_REG_TMP));
else
sprintf_s(buffer, 10, "$%02x", tmp);
return buffer;
}
else
{
sprintf_s(buffer, 10, "$%02x", tmp);
return buffer;
}
}