mii_emu/src/mii_65c02_disasm.c

125 lines
2.8 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mii_65c02.h"
#include "mii_65c02_ops.h"
#include "mii_65c02_disasm.h"
int
mii_cpu_disasm_one(
const uint8_t *prog,
uint16_t addr,
char *out,
size_t out_len,
uint16_t flags)
{
uint16_t pc = addr;
int i = 0;
uint8_t op = prog[i];
mii_op_desc_t d = mii_cpu_op[op].desc;
if (!d.pc)
d.pc = 1;
*out = 0;
int len = out_len;
if (flags & MII_DUMP_DIS_PC)
len -= snprintf(out + strlen(out), len, "%04X: ", pc + i);
if (flags & MII_DUMP_DIS_DUMP_HEX) {
char hex[32] = {0};
for (int oi = 0; oi < d.pc; oi++)
sprintf(hex + (oi * 3), "%02X ", prog[i + oi]);
len -= snprintf(out + strlen(out), len, "%-9s ", hex);
}
len -= snprintf(out + strlen(out), len, "%.4s ",
mii_cpu_op[op].name[0] ?
mii_cpu_op[op].name : "???");
i++;
switch (d.mode) {
case IMM:
len -= snprintf(out + strlen(out), len,
"#$%02X", prog[i++]);
break;
case BRANCH:
case ZP_REL:
if ((op & 0xf) == 0xf) {
uint16_t base = pc + i + 1;
uint16_t dest = base + (int8_t)prog[i++];
len -= snprintf(out + strlen(out), len,
"%d,$%04X", d.s_bit, dest);
} else if (d.branch) {
uint16_t base = pc + i + 1;
uint16_t dest = base + (int8_t)prog[i++];
len -= snprintf(out + strlen(out), len,
"$%04X", dest);
} else
len -= snprintf(out + strlen(out), len,
"$%02X", prog[i++]);
break;
case ZP_X:
len -= snprintf(out + strlen(out), len,
"$%02X,X", prog[i++]);
break;
case ZP_Y:
len -= snprintf(out + strlen(out), len,
"$%02X,Y", prog[i++]);
break;
case ABS:
len -= snprintf(out + strlen(out), len,
"$%02X%02X", prog[i + 1], prog[i]);
i += 2;
break;
case ABS_X:
len -= snprintf(out + strlen(out), len,
"$%02X%02X,X", prog[i + 1], prog[i]);
i += 2;
break;
case ABS_Y:
len -= snprintf(out + strlen(out), len,
"$%02X%02X,Y", prog[i + 1], prog[i]);
i += 2;
break;
case IND_X:
len -= snprintf(out + strlen(out), len,
"($%02X,X)", prog[i++]);
break;
case IND_AX:
len -= snprintf(out + strlen(out), len,
"($%02X%02X,X)", prog[i + 1], prog[i]);
i += 2;
break;
case IND_Y:
len -= snprintf(out + strlen(out), len,
"($%02X),Y", prog[i++]);
break;
case IND_Z:
len -= snprintf(out + strlen(out), len,
"($%02X)", prog[i++]);
break;
case IND:
len -= snprintf(out + strlen(out), len,
"($%02X%02X)", prog[i + 1], prog[i]);
i += 2;
break;
case IMPLIED:
break;
}
return d.pc;
}
void
mii_cpu_disasm(
const uint8_t *prog,
uint16_t addr,
uint16_t len)
{
uint16_t pc = addr;
int i = 0;
while (i < len) {
char out[256] = {0};
i += mii_cpu_disasm_one(prog + i, pc + i, out, sizeof(out),
MII_DUMP_DIS_PC | MII_DUMP_DIS_DUMP_HEX);
printf("%s\n", out);
}
}