diff options
Diffstat (limited to 'disasm.c')
-rw-r--r-- | disasm.c | 142 |
1 files changed, 42 insertions, 100 deletions
@@ -2,24 +2,25 @@ #include "disasm.h" #include <string.h> -void disasm(struct sux *cpu, uint64_t *operands, uint8_t lines, uint8_t opcode, uint8_t prefix, uint8_t thread) { - uint64_t value = operands[0]; - uint64_t address = operands[1]; - uint64_t tmpaddr = operands[2]; +void disasm(struct sux *cpu, uint8_t lines, uint8_t opcode, uint8_t prefix, uint8_t thread) { + union reg value; + uint64_t address = get_addr(cpu, opcode, prefix, 0, 0, thread); + uint8_t rs = (prefix >> 4) & 3; char *postfix; char *of; char op[4]; char *sign = ""; + char *ind = ""; uint8_t tmp = 0; union reg mask; mask.u64 = 0; memcpy(op, opname[opcode], 3); op[3] = 0; - switch ((1 << ((prefix >> 4) & 3))) { - case 1: postfix = ""; break; - case 2: postfix = ".W"; break; - case 4: postfix = ".D"; break; - case 8: postfix = ".Q"; break; + switch (rs) { + case 0: postfix = ""; break; + case 1: postfix = ".W"; break; + case 2: postfix = ".D"; break; + case 3: postfix = ".Q"; break; } if (prefix >> 6) { tmp = 0; @@ -29,7 +30,7 @@ void disasm(struct sux *cpu, uint64_t *operands, uint8_t lines, uint8_t opcode, case 1 : of = "SP"; break; case 2 : of = "PC"; break; } - uint8_t addrsize = 0xFF; + uint8_t addrsize = 0; char *idx; switch (optype[opcode]) { case IND : idx = ")"; break; @@ -39,106 +40,47 @@ void disasm(struct sux *cpu, uint64_t *operands, uint8_t lines, uint8_t opcode, case ZMY : idx = ", y"; break; default : idx = ""; break; } - if ((prefix >> 6) == 1 || (prefix >> 6) == 2) { - 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; - } - for (uint8_t i = 0; i < addrsize+1; i++) { - mask.u8[i] = (i == addrsize && addrsize != 0xFF) ? 0x7F : 0xFF; - } + 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; + } + + for (uint8_t i = 0; i < addrsize+1; i++) { + mask.u8[i] = (i == addrsize && addrsize != 0xFF) ? 0x7F : 0xFF; + } + value = read_value(cpu, cpu->pc, addrsize, 0, 0); + if ((prefix >> 6) == 1 || (prefix >> 6) == 2 || optype[opcode] == REL) { switch (addrsize) { - case 0 : sign = ((int8_t )value < 0) ? "-" : "+"; break; - case 1 : sign = ((int16_t)value < 0) ? "-" : "+"; break; + case 0 : sign = ((int8_t )value.u8 [0] < 0) ? "-" : "+"; break; + case 1 : sign = ((int16_t)value.u16[0] < 0) ? "-" : "+"; break; case 2 : - case 3 : sign = ((int32_t)value < 0) ? "-" : "+"; break; + case 3 : sign = ((int32_t)value.u32[0] < 0) ? "-" : "+"; break; case 4 : case 5 : case 6 : - case 7 : sign = ((int64_t)value < 0) ? "-" : "+"; break; + case 7 : sign = ((int64_t)value.u64 < 0) ? "-" : "+"; break; } + value.u64 &= mask.u64; } - switch (optype[opcode]) { case BREG: - case IMPL: - wprintw(scr, "%s%s" , opname[opcode], postfix); - break; - case IMM: - switch ((1 << ((prefix >> 4) & 3))) { - case 1: wprintw(scr, "%s #$%02X" , op, value); break; - case 2: wprintw(scr, "%s%s #$%04X" , op, postfix, value); break; - case 4: wprintw(scr, "%s%s #$%08X" , op, postfix, value); break; - case 8: wprintw(scr, "%s%s #$%016"PRIX64 , op, postfix, value); break; - } - break; - case ZM: - case ZMX: - case ZMY: - if ((prefix >> 6) == 1 || (prefix >> 6) == 2) { - tmpaddr &= mask.u64; - } - switch (optype[opcode]) { - case ZMX: tmpaddr = address - cpu->x; break; - case ZMY: tmpaddr = address - cpu->y; break; - } - switch ((prefix & 0x0C) >> 2) { - case 3: wprintw(scr, "%s%s %s%s$%08" PRIX64"%s" , op, postfix, of, sign, tmpaddr, idx); break; - case 2: wprintw(scr, "%s%s %s%s$%014"PRIX64"%s" , op, postfix, of, sign, tmpaddr, idx); break; - case 1: wprintw(scr, "%s%s %s%s$%06" PRIX64"%s" , op, postfix, of, sign, tmpaddr, idx); break; - case 0: wprintw(scr, "%s%s %s%s$%02" PRIX64"%s" , op, postfix, of, sign, tmpaddr, idx); break; - } - break; - case IND: + case IMPL: wprintw(scr, "%s%s" , opname[opcode], postfix); break; + case IMM : wprintw(scr, "%s%s #$%0*"PRIX64 , op, postfix, (addrsize+1) << 1, value.u64); break; + case IND : case INDX: - case INDY: - if ((prefix >> 6) == 1 || (prefix >> 6) == 2) { - tmpaddr &= mask.u64; - } - switch ((prefix & 0x0C) >> 2) { - case 3: wprintw(scr, "%s%s (%s%s$%08" PRIX64"%s", op, postfix, of, sign, tmpaddr, idx); break; - case 2: wprintw(scr, "%s%s (%s%s$%014"PRIX64"%s", op, postfix, of, sign, tmpaddr, idx); break; - case 1: wprintw(scr, "%s%s (%s%s$%06" PRIX64"%s", op, postfix, of, sign, tmpaddr, idx); break; - case 0: wprintw(scr, "%s%s (%s%s$%02" PRIX64"%s", op, postfix, of, sign, tmpaddr, idx); break; - } - break; - case ABS: - tmpaddr = address; - if ((prefix >> 6) == 1 || (prefix >> 6) == 2) { - tmpaddr &= mask.u64; - } - switch ((prefix & 0x0C) >> 2) { - case 3: wprintw(scr, "%s%s %s%s$%016"PRIX64 , op, postfix, of, sign, tmpaddr); break; - case 2: wprintw(scr, "%s%s %s%s$%014"PRIX64 , op, postfix, of, sign, tmpaddr); break; - case 1: wprintw(scr, "%s%s %s%s$%010"PRIX64 , op, postfix, of, sign, tmpaddr); break; - case 0: wprintw(scr, "%s%s %s%s$%04" PRIX64 , op, postfix, of, sign, tmpaddr); break; - } - break; - case REL: - switch((1 << ((prefix >> 4) & 3))) { - case 1: - sign = ((int8_t)value < 0) ? "-" : "+"; - wprintw(scr, "%s %s$%02X" , op, sign, value & 0x7F); - break; - case 2: - sign = ((int16_t)value < 0) ? "-" : "+"; - wprintw(scr, "%s%s %s$%04X" , op, postfix, sign, value & ~(1 << 15)); - break; - case 4: - sign = ((int32_t)value < 0) ? "-" : "+"; - wprintw(scr, "%s%s %s$%08X" , op, postfix, sign, value & ~(1 << 31)); - break; - case 8: - sign = ((int64_t)value < 0) ? "-" : "+"; - wprintw(scr, "%s%s %s$%016"PRIX64 , op, postfix, sign, value & ~((uint64_t)1 << 63)); - break; - } - break; + 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.u64, idx); break; + case REL : wprintw(scr, "%s%s %s$%0*"PRIX64 , op, postfix, sign, (addrsize+1) << 1, value.u64); break; } if (address == TX_ADDR || address == RX_ADDR) { |