disassembler - inline debug name support.

See IIgs technote #103.
This commit is contained in:
Kelvin Sherlock 2019-04-05 18:43:54 -04:00
parent 237577d886
commit 89d8b3efcf

View File

@ -426,6 +426,63 @@ static int is_jsr_bf00(word32 address) {
static int g_disasm_psr;
static const char *get_inline_debug_name(word32 address) {
static char buffer[256];
/* see IIgs technote #103 */
/* 82 xx xx brl pastname
71 77
name
pastname:
*/
/* uthernet uses bra ... tsk tsk. */
int match = 0;
int offset = 0;
unsigned op = get_memory_c(address, 0);
if (op == 0x82
&& get_memory_c(address + 3, 0) == 0x71
&& get_memory_c(address + 4, 0) == 0x77) {
match = 1;
address += 5;
offset = 3 + (int16_t)get_memory16_c(address + 1, 0);
offset &= 0xffff;
}
if (op == 0x80
&& get_memory_c(address + 2, 0) == 0x71
&& get_memory_c(address + 3, 0) == 0x77) {
match = 1;
address += 4;
offset = 2 + (int8_t)get_memory_c(address + 1, 0);
offset &= 0xffff;
}
if (match) {
unsigned i, n;
/* sanity check it offset */
n = get_memory_c(address++, 0);
for (i = 0; i < n; ++i) {
unsigned char c = get_memory_c(address++, 0);
if (c & 0x80) return NULL;
if (!isprint(c)) return NULL;
buffer[i] = c;
}
buffer[i] = 0;
return buffer;
}
return NULL;
}
word32 do_list(word32 address, int lines) {
unsigned char buffer2[32];
@ -578,7 +635,7 @@ word32 do_list(word32 address, int lines) {
comment = debug_tool_name(pc & 0xffff, bank);
}
uint32_t ea = 0;
switch (opcode) {
case 0xe2: /* sep */
g_disasm_psr|= operand;
@ -602,6 +659,7 @@ word32 do_list(word32 address, int lines) {
}
}
break;
#if 0
case 0xae: /* ldx ... */
case 0xbe:
case 0xa6:
@ -613,6 +671,7 @@ word32 do_list(word32 address, int lines) {
case 0xca: /* dex */
case 0xe8: /* inx */
break;
#endif
case 0x22: /* jsl */
if (operand == 0xe100a8) {
/* inline GS/OS call? */
@ -628,6 +687,8 @@ word32 do_list(word32 address, int lines) {
buffer2[bsize++] = get_memory_c(address++, 0);
}
}
} else {
ea = operand;
}
break;
case 0x20: /* jsr */
@ -643,8 +704,70 @@ word32 do_list(word32 address, int lines) {
buffer2[bsize++] = get_memory_c(address++, 0);
}
}
} else {
ea = (operand | (address & 0xff0000));
}
break;
case 0x82: {
ea = address + (int16_t)operand;
ea &= 0xffff;
ea |= pc & 0xff0000;
const char *name = get_inline_debug_name(pc);
/* start of an inline debug name? */
if (name) {
opcode_string = name;
buffer[0] = 0;
/* include the 0x77 71 magic bytes */
for (i = 0; i < 2; ++i) {
buffer2[bsize++] = get_memory_c(address++, 0);
}
address = ea;
ea = 0;
}
break;
}
case 0x80: {
ea = address + (int8_t)operand;
ea &= 0xffff;
ea |= pc & 0xff0000;
const char *name = get_inline_debug_name(pc);
/* start of an inline debug name? */
if (name) {
opcode_string = name;
buffer[0] = 0;
/* include the 0x77 71 magic bytes */
for (i = 0; i < 2; ++i) {
buffer2[bsize++] = get_memory_c(address++, 0);
}
address = ea;
ea = 0;
}
break;
}
case 0x10:
case 0x30:
case 0x50:
case 0x70:
case 0x90:
case 0xb0:
case 0xd0:
case 0xf0: {
ea = address + (int8_t)operand;
ea &= 0xffff;
ea |= pc & 0xff0000;
break;
}
}
if (ea && !comment) {
comment = get_inline_debug_name(ea);
}
n = printf("%02x/%04x: %s %s",