diff options
-rw-r--r-- | disasm.c | 8 | ||||
-rw-r--r-- | sux.h | 25 | ||||
-rw-r--r-- | test/ortho.s | 1 |
3 files changed, 25 insertions, 9 deletions
@@ -159,9 +159,11 @@ static void disasm_ortho(struct sux *cpu, uint8_t opcode, uint8_t prefix, uint8_ memset(address, 0, sizeof(address)); memset(idx, 0, sizeof(idx)); memset(scale, 0, sizeof(scale)); + for (int i = 0; i < 2; i++) { int is_ind = 0; int is_rind = 0; + uint64_t val = 0; if (op[i].type) { uint8_t addr_size = get_ortho_addrsize(prefix, op[i].id); if (addr_size != 0xFF) { @@ -170,6 +172,8 @@ static void disasm_ortho(struct sux *cpu, uint8_t opcode, uint8_t prefix, uint8_ } if (op[i].id == MEM_SIB) { sprintf(scale[i], "%u*", op[i].scale+1); + } else if (op[i].id == MEM_IMM) { + val = read_value(cpu, 0, value[i], rs-1, 0, 0); } switch (op[i].id) { case MEM_ABSR : @@ -244,7 +248,7 @@ static void disasm_ortho(struct sux *cpu, uint8_t opcode, uint8_t prefix, uint8_ case 0: sprintf(opr[i], "%s%s%s", idx[i], sign[i], address[i]); break; case 1: sprintf(opr[i], "%s%s(%s)", idx[i], sign[i], address[i]); break; case 2: sprintf(opr[i], "(%s%s%s)", idx[i], sign[i], address[i]); break; - case 3: sprintf(opr[i], "#$%*"PRIX64, rs*2, op[i].value); break; + case 3: sprintf(opr[i], "#$%0*"PRIX64, rs*2, val); break; case 4: sprintf(opr[i], "%s", reg[i]); break; } } @@ -399,7 +403,7 @@ void disasm(struct sux *cpu, uint8_t lines, uint8_t opcode, uint8_t prefix, uint } else { inst_name = ortho_opname[opcode]; memcpy(op, inst_name, 3); - disasm_ortho(cpu, opcode, prefix, prefix2, ortho_addr, op, postfix, ortho_op, rs, thread); + disasm_ortho(cpu, opcode, prefix, prefix2, ortho_addr, op, postfix, ortho_op, (1 << rs), thread); } if (address == TX_ADDR || address == RX_ADDR) { @@ -533,14 +533,20 @@ static /*inline*/ uint64_t get_ortho_addr(struct sux *cpu, uint8_t prefix, uint6 } op[i].scale = (inst_size == 2) ? tmp.u8[0] : 0; } - if (addr_size != 0xFF || (rs && op[i].id == MEM_IMM)) { - inst_size = (addr_size != 0xFF) ? addr_size+1 : rs; + if (addr_size != 0xFF) { + inst_size = addr_size+1; op[i].value = read_value(cpu, 0, address, inst_size-1, inc_clk, 0); value[i] = op[i].value; if (inc_pc) { address += inst_size; } } + if (rs && op[i].id == MEM_IMM) { + value[i] = address; + if (inc_pc) { + address += rs; + } + } if (is_rind) { for (int j = 0; j < 2 && op[i].rind[j] != 0xFF; j++) { uint64_t reg; @@ -900,7 +906,7 @@ static /*inline*/ void exec_ortho_inst(struct sux *cpu, uint8_t opcode, uint8_t operand op[2]; cpu->pc = get_ortho_addr(cpu, prefix, cpu->pc, op, address, op_type, op_id, 1, 1, thread); if (op[1].type) { - src = read_value(cpu, 0, op[1].value, size, 1, 1); + src = read_value(cpu, 0, (op[1].id != MEM_IMM) ? op[1].value : address[1], size, 1, 1); } else { switch (op[1].id) { case REG_A : src = cpu->a; break; @@ -922,7 +928,9 @@ static /*inline*/ void exec_ortho_inst(struct sux *cpu, uint8_t opcode, uint8_t } } if (op[0].type) { - dst = read_value(cpu, 0, op[0].value, size, 1, 1); + if (op[0].id != MEM_IMM) { + dst = read_value(cpu, 0, op[0].value, size, 1, 1); + } } else { switch (op[0].id) { case REG_A : dst = cpu->a; break; @@ -1043,9 +1051,10 @@ static /*inline*/ void exec_ortho_inst(struct sux *cpu, uint8_t opcode, uint8_t case ORTHO_1CC(SET, VC): dst = set(cpu, !getflag(V), thread); break; } - if (op[0].type) { - write_value(cpu, dst, op[0].value, size, 1, 1); + if (op[0].id != MEM_IMM) { + write_value(cpu, dst, op[0].value, size, 1, 1); + } } else { switch (op[0].id) { case REG_A : cpu->a = dst; break; @@ -1068,7 +1077,9 @@ static /*inline*/ void exec_ortho_inst(struct sux *cpu, uint8_t opcode, uint8_t } if (isdiv) { if (op[1].type) { - write_value(cpu, rem, op[1].value, size, 1, 1); + if (op[0].id != MEM_IMM) { + write_value(cpu, dst, op[1].value, size, 1, 1); + } } else { switch (op[1].id) { case REG_A : cpu->a = rem; break; diff --git a/test/ortho.s b/test/ortho.s index bc70d3d..83f3554 100644 --- a/test/ortho.s +++ b/test/ortho.s @@ -9,6 +9,7 @@ mem: reset: cps lds.d #$3FFFF + mov a, #10 and #0 tay xor b, b |