diff --git a/disassembler/x65dsasm.cpp b/disassembler/x65dsasm.cpp index e8ec81d..5f1797c 100644 --- a/disassembler/x65dsasm.cpp +++ b/disassembler/x65dsasm.cpp @@ -786,7 +786,7 @@ struct dismnm a65816_ops[256] = { { "rtl", AM_NON, 0x00 }, { "adc", AM_IMM_DBL_A, 0x01 }, { "ror", AM_NON, 0x00 }, - { "???", AM_NON, 0x00 }, + { "rtl", AM_NON, 0x00 }, { "jmp", AM_REL, 0x02 }, { "adc", AM_ABS, 0x02 }, { "ror", AM_ABS, 0x02 }, @@ -967,20 +967,31 @@ std::vector refs; static int _sortRefs(const void *A, const void *B) { - return ((const RefLink*)A)->instr_addr - ((const RefLink*)B)->instr_addr; + return ((const RefAddr*)A)->address - ((const RefAddr*)B)->address; } -void GetReferences(unsigned char *mem, size_t bytes, bool acc_16, bool ind_16, int addr, const dismnm *opcodes) +void GetReferences(unsigned char *mem, size_t bytes, bool acc_16, bool ind_16, int addr, const dismnm *opcodes, int init_data) { int start_addr = addr; int end_addr = addr + (int)bytes; refs.push_back(RefAddr(start_addr)); refs[0].pRefs = new std::vector(); + if (init_data) { + refs[0].data = 1; + refs.push_back(RefAddr(start_addr+init_data)); + refs[1].pRefs = new std::vector(); + } unsigned char *mem_orig = mem; size_t bytes_orig = bytes; int addr_orig = addr; + if (size_t(init_data)>bytes) + return; + + addr += init_data; + bytes -= init_data; + while (bytes) { unsigned char op = *mem++; int curr = addr; @@ -1060,13 +1071,15 @@ void GetReferences(unsigned char *mem, size_t bytes, bool acc_16, bool ind_16, i mem = mem_orig; bytes = bytes_orig; addr = addr_orig; - int curr_label = 0; + int curr_label = init_data ? 1 : 0; int prev_addr = -1; - bool was_data = false; + bool was_data = init_data>0; refs[curr_label].data = 0; bool separator = false; int prev_op = 0xff; - while (bytes && curr_label bytes) + if (arg_size > (int)bytes) break; // ended on partial instruction addr += arg_size; bytes -= arg_size; @@ -1151,7 +1164,7 @@ void GetReferences(unsigned char *mem, size_t bytes, bool acc_16, bool ind_16, i // after a separator if there is no jmp, jsr, brl begin data block if (!was_data) { - if (op == 0x60 || op == 0x40 || op == 0x68 || op == 0x4c || op == 0x6c || + if (op == 0x60 || op == 0x40 || op == 0x6b || op == 0x4c || op == 0x6c || op == 0x7c || op == 0x5c || op == 0xdc) { // rts, rti, rtl or jmp separator = true; for (size_t i = curr_label+1; i::iterator k = refs.begin(); - if (k != refs.end()) + if (k != refs.end()) { ++k; // don't delete the initial label + if (init_data && k != refs.end()) + ++k; // don't delete the initial label + } while (k!=refs.end()) { if (k->pRefs && k->pRefs->size()==0) { delete k->pRefs; @@ -1204,7 +1220,7 @@ void GetReferences(unsigned char *mem, size_t bytes, bool acc_16, bool ind_16, i } static const char spacing[] = " "; -void Disassemble(strref filename, unsigned char *mem, size_t bytes, bool acc_16, bool ind_16, int addr, const dismnm *opcodes, bool src) +void Disassemble(strref filename, unsigned char *mem, size_t bytes, bool acc_16, bool ind_16, int addr, const dismnm *opcodes, bool src, int init_data) { FILE *f = stdout; bool opened = false; @@ -1223,17 +1239,17 @@ void Disassemble(strref filename, unsigned char *mem, size_t bytes, bool acc_16, int end_addr = addr + (int)bytes; refs.clear(); - GetReferences(mem, bytes, acc_16, ind_16, addr, opcodes); + GetReferences(mem, bytes, acc_16, ind_16, addr, opcodes, init_data); int curr_label_index = 0; bool separator = false; - bool is_data = false; + bool is_data = refs.size() ? !!refs[0].data : false; strown<256> out; int prev_op = 255; while (bytes) { bool data_to_code = false; // Determine if current address is referenced from somewhere - while (curr_label_index= refs[curr_label_index].address) { + while (curr_label_index<(int)refs.size() && addr >= refs[curr_label_index].address) { struct RefAddr &ref = refs[curr_label_index]; if (ref.pRefs) { for (size_t j = 0; jsize(); ++j) { @@ -1334,7 +1350,7 @@ void Disassemble(strref filename, unsigned char *mem, size_t bytes, bool acc_16, int reference = -1; separator = false; - if (op == 0x60 || op == 0x40 || op == 0x68 || (op == 0x4c && mem[arg_size] != 0x4c) || + if (op == 0x60 || op == 0x40 || op == 0x6b || (op == 0x4c && mem[arg_size] != 0x4c) || op == 0x6c || op == 0x7c || op == 0x5c || op == 0xdc) { // rts, rti, rtl or jmp separator = true; for (size_t i = 0; i size_t(end - skip)) bytes = size_t(end - skip); - Disassemble(out, mem + skip, bytes, acc_16, ind_16, addr, opcodes, src); + Disassemble(out, mem + skip, bytes, acc_16, ind_16, addr, opcodes, src, data); } free(mem); } diff --git a/x65.cpp b/x65.cpp index 0e148c0..3f4f509 100644 --- a/x65.cpp +++ b/x65.cpp @@ -663,7 +663,7 @@ struct mnem opcodes_65816[] = { { "jsl", AM8_JSL, { 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { "rti", AMM_NON, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { "rts", AMM_NON, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, - { "rtl", AMM_NON, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { "rtl", AMM_NON, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { "ora", AM8_ORA, { 0x01, 0x05, 0x09, 0x0d, 0x11, 0x15, 0x19, 0x1d, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x07, 0x17, 0x0f, 0x1f, 0x03, 0x13, 0x00, 0x00 } }, { "and", AM8_ORA, { 0x21, 0x25, 0x29, 0x2d, 0x31, 0x35, 0x39, 0x3d, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x27, 0x37, 0x2f, 0x3f, 0x23, 0x33, 0x00, 0x00 } }, { "eor", AM8_ORA, { 0x41, 0x45, 0x49, 0x4d, 0x51, 0x55, 0x59, 0x5d, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x47, 0x57, 0x4f, 0x5f, 0x43, 0x53, 0x00, 0x00 } }, @@ -5253,7 +5253,7 @@ StatusCode Asm::GetAddressMode(strref line, bool flipXY, unsigned int validModes if (!c) addrMode = AMB_NON; else if (!force_abs && (c == '[' || (c == '(' && - (validModes&(AMM_REL | AMM_REL_X | AMM_ZP_REL_X | AMM_ZP_Y_REL))))) { + (validModes&(AMM_REL | AMM_REL_X | AMM_ZP_REL | AMM_ZP_REL_X | AMM_ZP_Y_REL))))) { deco = line.scoped_block_skip(); line.skip_whitespace(); expression = deco.split_token_trim(','); @@ -5520,7 +5520,7 @@ StatusCode Asm::AddOpcode(strref line, int index, strref source_file) AddTriple(value); break; - case CA_TWO_ARG_BYTES: { + case CA_TWO_ARG_BYTES: { if (evalLater) AddLateEval(CurrSection().DataOffset(), CurrSection().GetPC(), scope_address[scope_depth], expression, source_file, LateEval::LET_BYTE); else if (error == STATUS_RELATIVE_SECTION) { @@ -5613,6 +5613,7 @@ StatusCode Asm::BuildLine(strref line) strref line_start = line; char char0 = line[0]; // first char including white space line.skip_whitespace(); // skip to first character + line = line.before_or_full(';'); // clip any line comments line = line.before_or_full(c_comment); line.clip_trailing_whitespace();