summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormrb0nk500 <b0nk@b0nk.xyz>2020-12-08 17:56:02 -0500
committermrb0nk500 <b0nk@b0nk.xyz>2020-12-08 18:07:51 -0500
commit28202af458a42e83f06415fa33d193258535a86d (patch)
tree7c285293af7679c734619c007366f4487eeaca72
parenta2dac7cb48605eec322ca825e39ff709240c17b7 (diff)
- Fixed yet another bug with the ortho extension.
-rw-r--r--disasm.c8
-rw-r--r--sux.h25
-rw-r--r--test/ortho.s1
3 files changed, 25 insertions, 9 deletions
diff --git a/disasm.c b/disasm.c
index 74dac5f..18d84bd 100644
--- a/disasm.c
+++ b/disasm.c
@@ -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) {
diff --git a/sux.h b/sux.h
index 6b8a7f6..d267755 100644
--- a/sux.h
+++ b/sux.h
@@ -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