summaryrefslogtreecommitdiff
path: root/disasm.c
diff options
context:
space:
mode:
Diffstat (limited to 'disasm.c')
-rw-r--r--disasm.c142
1 files changed, 42 insertions, 100 deletions
diff --git a/disasm.c b/disasm.c
index 57cef04..3645ec3 100644
--- a/disasm.c
+++ b/disasm.c
@@ -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) {