diff options
Diffstat (limited to 'disasm.c')
-rw-r--r-- | disasm.c | 96 |
1 files changed, 59 insertions, 37 deletions
@@ -10,10 +10,11 @@ void print_regs(struct sux *cpu, uint8_t lines, uint8_t thread) { wmove(scr, lines, 1); wclrtoeol(scr); wprintw(scr, "pc: $%04"PRIX64 , cpu->pc); - wprintw(scr, ", a: $%016"PRIX64, cpu->a); - wprintw(scr, ", b: $%016"PRIX64, cpu->b); - wprintw(scr, ", x: $%016"PRIX64, cpu->x); - wprintw(scr, ", y: $%016"PRIX64, cpu->y); + wprintw(scr, ", a: $%08"PRIX64, cpu->a); + wprintw(scr, ", b: $%08"PRIX64, cpu->b); + wprintw(scr, ", x: $%08"PRIX64, cpu->x); + wprintw(scr, ", y: $%08"PRIX64, cpu->y); + wprintw(scr, ", e: $%08"PRIX64, cpu->e); wprintw(scr, ", sp: $%"PRIX64, cpu->sp); wprintw(scr, ", ps: %c%c---%c%c%c", cpu->ps.u8[thread] & N ? 'N' : '-' , cpu->ps.u8[thread] & V ? 'V' : '-' @@ -23,9 +24,9 @@ void print_regs(struct sux *cpu, uint8_t lines, uint8_t thread) { wprintw(scr, ", inst: "); } -void disasm(struct sux *cpu, uint8_t lines, uint8_t opcode, uint8_t prefix, uint8_t thread) { +void disasm(struct sux *cpu, uint8_t lines, uint8_t opcode, uint8_t prefix, uint8_t ext_prefix, uint8_t prefix2, uint8_t thread) { uint64_t value; - uint64_t address = get_addr(cpu, opcode, prefix, 0, 0, thread); + uint64_t address = get_addr(cpu, opcode, prefix, ext_prefix, 0, 0, thread); uint8_t rs = (prefix >> 4) & 3; char *postfix; char *of; @@ -35,7 +36,17 @@ void disasm(struct sux *cpu, uint8_t lines, uint8_t opcode, uint8_t prefix, uint uint8_t tmp = 0; union reg mask; mask.u64 = 0; - memcpy(op, opname[opcode], 3); + const char *inst_name; + uint8_t inst_type; + if ((ext_prefix & 0xD) == 0xD) { + switch (ext_prefix >> 4) { + case 0x0: inst_name = ext_opname[opcode]; inst_type = ext_optype[opcode]; break; + } + } else { + inst_name = opname[opcode]; + inst_type = optype[opcode]; + } + memcpy(op, inst_name, 3); op[3] = 0; switch (rs) { case 0: postfix = ""; break; @@ -53,28 +64,33 @@ void disasm(struct sux *cpu, uint8_t lines, uint8_t opcode, uint8_t prefix, uint } uint8_t addrsize = 0; char *idx; - switch (optype[opcode]) { - case IND : idx = ")"; break; - case INDX: idx = ", x)"; break; - case INDY: idx = "), y"; break; - case ZMX : idx = ", x"; break; - case ZMY : idx = ", y"; break; - default : idx = ""; break; + switch (inst_type) { + case AIND : case IND : idx = ")"; break; + case AINDX: case INDX: idx = ", x)"; break; + case AINDY: case INDY: idx = "), y"; break; + case ABSX : case ZMX : idx = ", x"; break; + case ABSY : case ZMY : idx = ", y"; break; + default: idx = ""; break; } - switch (optype[opcode]) { - case ZM : - case ZMX : - case ZMY : - case IND : - case INDX: - case INDY: addrsize = get_addrsize(prefix, ZM); break; - case ABS : addrsize = get_addrsize(prefix, ABS); break; - case IMM : - case REL : addrsize = (1 << rs)-1; break; + switch (inst_type) { + case ZM : + case ZMX : + case ZMY : + case IND : + case INDX : + case INDY : addrsize = get_addrsize(prefix, ZM); break; + case ABS : + case AIND : + case AINDX: + case AINDY: + case ABSX : + case ABSY : addrsize = get_addrsize(prefix, ABS); break; + case IMM : + case REL : addrsize = (1 << rs)-1; break; } mask.u64 = (-(uint64_t)1 >> ((7 - addrsize) * 8)); value = read_value(cpu, 0, cpu->pc, addrsize, 0, 0); - if ((prefix >> 6) == 1 || (prefix >> 6) == 2 || optype[opcode] == REL) { + if ((prefix >> 6) == 1 || (prefix >> 6) == 2 || inst_type == REL) { switch (addrsize) { case 0 : sign = ((int8_t )value < 0) ? "-" : "+"; break; case 1 : sign = ((int16_t)value < 0) ? "-" : "+"; break; @@ -87,18 +103,24 @@ void disasm(struct sux *cpu, uint8_t lines, uint8_t opcode, uint8_t prefix, uint } value = (sign[0] == '-') ? (~value + 1) & mask.u64 : value; } - switch (optype[opcode]) { - case BREG: - case IMPL: wprintw(scr, "%s%s" , opname[opcode], postfix); break; - case IMM : wprintw(scr, "%s%s #$%0*"PRIX64 , op, postfix, (addrsize+1) << 1, value); break; - case IND : - case INDX: - case INDY: ind = "("; /* Falls through. */ - case ZMX : - case ZMY : - case ZM : - case ABS : wprintw(scr, "%s%s %s%s%s$%0*" PRIX64"%s" , op, postfix, ind, of, sign, (addrsize+1) << 1, value, idx); break; - case REL : wprintw(scr, "%s%s %s$%0*"PRIX64 , op, postfix, sign, (addrsize+1) << 1, value); break; + switch (inst_type) { + case EIND : + case BREG : + case IMPL : wprintw(scr, "%s%s" , inst_name, postfix); break; + case IMM : wprintw(scr, "%s%s #$%0*"PRIX64 , op, postfix, (addrsize+1) << 1, value); break; + case AIND : + case AINDX: + case AINDY: + case IND : + case INDX : + case INDY : ind = "("; /* Falls through. */ + case ZMX : + case ZMY : + case ABSX : + case ABSY : + case ZM : + case ABS : wprintw(scr, "%s%s %s%s%s$%0*" PRIX64"%s" , op, postfix, ind, of, sign, (addrsize+1) << 1, value, idx); break; + case REL : wprintw(scr, "%s%s %s$%0*"PRIX64 , op, postfix, sign, (addrsize+1) << 1, value); break; } if (address == TX_ADDR || address == RX_ADDR) { |