diff options
Diffstat (limited to 'disasm.c')
-rw-r--r-- | disasm.c | 187 |
1 files changed, 117 insertions, 70 deletions
@@ -1,93 +1,138 @@ #include "sux.h" #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]; - char postfix[3]; + char *postfix; char *of; char op[4]; - char sign; + char *sign = ""; uint8_t tmp = 0; - op[0] = opname[opcode][0]; - op[1] = opname[opcode][1]; - op[2] = opname[opcode][2]; - op[3] = '\0'; + union reg mask; + mask.u64 = 0; + memcpy(op, opname[opcode], 3); + op[3] = 0; switch ((1 << ((prefix >> 4) & 3))) { - case 1: postfix[0] = 0; postfix[1] = 0; postfix[2] = 0; break; - case 2: postfix[0] = '.'; postfix[1] = 'W'; postfix[2] = 0; break; - case 4: postfix[0] = '.'; postfix[1] = 'D'; postfix[2] = 0; break; - case 8: postfix[0] = '.'; postfix[1] = 'Q'; postfix[2] = 0; break; + case 1: postfix = ""; break; + case 2: postfix = ".W"; break; + case 4: postfix = ".D"; break; + case 8: postfix = ".Q"; break; } if (prefix >> 6) { tmp = 0; } switch (prefix >> 6) { default: of = ""; break; - case 1 : of = "SP, "; break; - case 2 : of = "PC, "; break; + case 1 : of = "SP"; break; + case 2 : of = "PC"; break; } + uint8_t addrsize = 0xFF; + 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; + } + 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 (addrsize) { + case 0 : sign = ((int8_t )value < 0) ? "-" : "+"; break; + case 1 : sign = ((int16_t)value < 0) ? "-" : "+"; break; + case 2 : + case 3 : sign = ((int32_t)value < 0) ? "-" : "+"; break; + case 4 : + case 5 : + case 6 : + case 7 : sign = ((int64_t)value < 0) ? "-" : "+"; break; + } + } + switch (optype[opcode]) { case IMPL: wprintw(scr, "%s%s" , opname[opcode], postfix); break; case IMM: switch ((1 << ((prefix >> 4) & 3))) { - case 1: wprintw(scr, "%s #$%02X\r" , op, value); break; - case 2: wprintw(scr, "%s%s #$%04X\r" , op, postfix, value); break; - case 4: wprintw(scr, "%s%s #$%08X\r" , op, postfix, value); break; - case 8: wprintw(scr, "%s%s #$%016"PRIX64"\r" , op, postfix, value); break; + 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$%08X%s\r" , op, postfix, of, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); break; - case 2: wprintw(scr, "%s%s %s$%014"PRIX64"%s\r" , op, postfix, of, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); break; - case 1: wprintw(scr, "%s%s %s$%06X%s\r" , op, postfix, of, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); break; - case 0: wprintw(scr, "%s%s %s$%02X%s\r" , op, postfix, of, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); break; + 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 INDX: case INDY: + if ((prefix >> 6) == 1 || (prefix >> 6) == 2) { + tmpaddr &= mask.u64; + } switch ((prefix & 0x0C) >> 2) { - case 3: wprintw(scr, "%s%s (%s$%08X%s\r", op, postfix, of, tmpaddr, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y")); break; - case 2: wprintw(scr, "%s%s (%s$%012"PRIX64"%s\r", op, postfix, of, tmpaddr, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y")); break; - case 1: wprintw(scr, "%s%s (%s$%06X%s\r", op, postfix, of, tmpaddr, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y")); break; - case 0: wprintw(scr, "%s%s (%s$%02X%s\r", op, postfix, of, tmpaddr, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y")); break; + 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$%016"PRIX64"\r" , op, postfix, of, tmpaddr); break; - case 2: wprintw(scr, "%s%s %s$%014"PRIX64"\r" , op, postfix, of, tmpaddr); break; - case 1: wprintw(scr, "%s%s %s$%010"PRIX64"\r" , op, postfix, of, tmpaddr); break; - case 0: wprintw(scr, "%s%s %s$%04" PRIX64"\r" , op, postfix, of, tmpaddr); break; + 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 %c$%02X" , op, sign, value & 0x7F); + 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 %c$%04X" , op, postfix, sign, value & ~(1 << 15)); + 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 %c$%08X" , op, postfix, sign, value & ~(1 << 31)); + 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 %c$%016"PRIX64 , op, postfix, sign, value & ~((uint64_t)1 << 63)); + sign = ((int64_t)value < 0) ? "-" : "+"; + wprintw(scr, "%s%s %s$%016"PRIX64 , op, postfix, sign, value & ~((uint64_t)1 << 63)); break; } break; @@ -97,6 +142,8 @@ void disasm(struct sux *cpu, uint64_t *operands, uint8_t lines, uint8_t opcode, wmove(scr, 27, 0); wprintw(scr, "TX_ADDR: $%02X, RX_ADDR: $%02X", addr[TX_ADDR], addr[RX_ADDR]); } + wmove(scr, 29, 0); + wprintw(scr, "address: $%04"PRIX64, address); if (subdbg) { uint8_t ln = 33; uint16_t line_idx = 0; @@ -105,41 +152,9 @@ void disasm(struct sux *cpu, uint64_t *operands, uint8_t lines, uint8_t opcode, uint8_t iscursor = 0; union reg ptr; uint32_t adr; - wmove(scr, 30, 0); - wclrtoeol(scr); - adr = 0x25; - ptr.u8[0] = addr[adr+0]; ptr.u8[1] = addr[adr+1]; - ptr.u8[2] = addr[adr+2]; ptr.u8[3] = addr[adr+3]; - ptr.u8[4] = addr[adr+4]; ptr.u8[5] = addr[adr+5]; - ptr.u8[6] = addr[adr+6]; ptr.u8[7] = addr[adr+7]; - wprintw(scr, "ptr1: $%04"PRIX64, ptr.u64); - adr = 0x2D; - ptr.u8[0] = addr[adr+0]; ptr.u8[1] = addr[adr+1]; - ptr.u8[2] = addr[adr+2]; ptr.u8[3] = addr[adr+3]; - ptr.u8[4] = addr[adr+4]; ptr.u8[5] = addr[adr+5]; - ptr.u8[6] = addr[adr+6]; ptr.u8[7] = addr[adr+7]; - wprintw(scr, ", ptr2: $%04"PRIX64, ptr.u64); - adr = 0x35; - ptr.u8[0] = addr[adr+0]; ptr.u8[1] = addr[adr+1]; - ptr.u8[2] = addr[adr+2]; ptr.u8[3] = addr[adr+3]; - ptr.u8[4] = addr[adr+4]; ptr.u8[5] = addr[adr+5]; - ptr.u8[6] = addr[adr+6]; ptr.u8[7] = addr[adr+7]; - wprintw(scr, ", ptr3: $%04"PRIX64, ptr.u64); - adr = 0x3349A; - ptr.u8[0] = addr[adr+0]; ptr.u8[1] = addr[adr+1]; - ptr.u8[2] = addr[adr+2]; ptr.u8[3] = addr[adr+3]; - ptr.u8[4] = addr[adr+4]; ptr.u8[5] = addr[adr+5]; - ptr.u8[6] = addr[adr+6]; ptr.u8[7] = addr[adr+7]; - wprintw(scr, ", idx0: $%04"PRIX64, ptr.u64); - adr = 0x334BA; - ptr.u8[0] = addr[adr+0]; ptr.u8[1] = addr[adr+1]; - ptr.u8[2] = addr[adr+2]; ptr.u8[3] = addr[adr+3]; - ptr.u8[4] = addr[adr+4]; ptr.u8[5] = addr[adr+5]; - ptr.u8[6] = addr[adr+6]; ptr.u8[7] = addr[adr+7]; - wprintw(scr, ", valbuf: $%016"PRIX64, ptr.u64); if (address == CTRL_ADDR || addr[STEP_ADDR]) { adr = 0x30000; - mvwprintw(scr, 29, 0, "address: $%04"PRIX64", scr_row: %02u, scr_col: %02u, scr_str: %02u, scr_end: %02u\r", address, addr[0], addr[1], addr[0x22], addr[0x23]); + wprintw(scr, ", scr_row: %02u, scr_col: %02u, scr_str: %02u, scr_end: %02u", addr[0], addr[1], addr[0x22], addr[0x23]); wmove(scr, 32, 0); wprintw(scr, "bitabl: "); for (uint8_t i = 0; i < 16; i++) { @@ -159,7 +174,7 @@ void disasm(struct sux *cpu, uint64_t *operands, uint8_t lines, uint8_t opcode, wmove(scr, ln++, 0); wclrtoeol(scr); wmove(scr, row+1, col-2); - wprintw(scr, "/\\\r"); + wprintw(scr, "/\\"); wmove(scr, row, col); } } @@ -172,6 +187,38 @@ void disasm(struct sux *cpu, uint64_t *operands, uint8_t lines, uint8_t opcode, wmove(scr, ln++, 0); } } + wmove(scr, 30, 0); + wclrtoeol(scr); + adr = 0x25; + ptr.u8[0] = addr[adr+0]; ptr.u8[1] = addr[adr+1]; + ptr.u8[2] = addr[adr+2]; ptr.u8[3] = addr[adr+3]; + ptr.u8[4] = addr[adr+4]; ptr.u8[5] = addr[adr+5]; + ptr.u8[6] = addr[adr+6]; ptr.u8[7] = addr[adr+7]; + wprintw(scr, "ptr1: $%04"PRIX64, ptr.u64); + adr = 0x2D; + ptr.u8[0] = addr[adr+0]; ptr.u8[1] = addr[adr+1]; + ptr.u8[2] = addr[adr+2]; ptr.u8[3] = addr[adr+3]; + ptr.u8[4] = addr[adr+4]; ptr.u8[5] = addr[adr+5]; + ptr.u8[6] = addr[adr+6]; ptr.u8[7] = addr[adr+7]; + wprintw(scr, ", ptr2: $%04"PRIX64, ptr.u64); + adr = 0x35; + ptr.u8[0] = addr[adr+0]; ptr.u8[1] = addr[adr+1]; + ptr.u8[2] = addr[adr+2]; ptr.u8[3] = addr[adr+3]; + ptr.u8[4] = addr[adr+4]; ptr.u8[5] = addr[adr+5]; + ptr.u8[6] = addr[adr+6]; ptr.u8[7] = addr[adr+7]; + wprintw(scr, ", ptr3: $%04"PRIX64, ptr.u64); + adr = 0x3349A; + ptr.u8[0] = addr[adr+0]; ptr.u8[1] = addr[adr+1]; + ptr.u8[2] = addr[adr+2]; ptr.u8[3] = addr[adr+3]; + ptr.u8[4] = addr[adr+4]; ptr.u8[5] = addr[adr+5]; + ptr.u8[6] = addr[adr+6]; ptr.u8[7] = addr[adr+7]; + wprintw(scr, ", idx0: $%04"PRIX64, ptr.u64); + adr = 0x334BA; + ptr.u8[0] = addr[adr+0]; ptr.u8[1] = addr[adr+1]; + ptr.u8[2] = addr[adr+2]; ptr.u8[3] = addr[adr+3]; + ptr.u8[4] = addr[adr+4]; ptr.u8[5] = addr[adr+5]; + ptr.u8[6] = addr[adr+6]; ptr.u8[7] = addr[adr+7]; + wprintw(scr, ", valbuf: $%016"PRIX64, ptr.u64); /* wmove(scr, 47, 0); wclrtoeol(scr); |