summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOxore <oxore@protonmail.com>2023-04-20 01:53:04 +0300
committerOxore <oxore@protonmail.com>2023-04-20 01:58:22 +0300
commit09ea96e0d2fc82147603259c3b1bcbe30f586164 (patch)
treecb24180b066ebb0b4570693f6a61819fff673799
parent088c90dc459841bd513cd8b0bf9c91d9af06ff41 (diff)
Implement brief word extension for jsr (part 1)
-rw-r--r--main.cpp36
-rw-r--r--test.bash41
2 files changed, 56 insertions, 21 deletions
diff --git a/main.cpp b/main.cpp
index 16e5ead..0e7b63d 100644
--- a/main.cpp
+++ b/main.cpp
@@ -71,7 +71,7 @@ struct DisasmNode {
static size_t disasm_verbatim(
char *out, size_t out_sz, uint16_t instr, uint32_t offset, const DataBuffer &)
{
- snprintf(out, out_sz, " .short 0x%04x | traced @%" PRIu32 "\n", instr, offset);
+ snprintf(out, out_sz, " .short 0x%04x | traced @%08" PRIx32 "\n", instr, offset);
return kInstructionSizeStepBytes;
}
@@ -83,7 +83,7 @@ static size_t disasm_mfff0_v4e70(
} else if (instr == 0x4e71) {
snprintf(out, out_sz, " nop | %04x @%04x\n", instr, offset);
} else if (instr == 0x4e72) {
- snprintf(out, out_sz, " .short 0x%04x | stop (not implemented) @%" PRIu32 "\n", instr, offset);
+ snprintf(out, out_sz, " .short 0x%04x | stop (not implemented) @%08" PRIx32 "\n", instr, offset);
} else if (instr == 0x4e73) {
snprintf(out, out_sz, " rte | %04x @%04x\n", instr, offset);
} else if (instr == 0x4e75) {
@@ -119,36 +119,48 @@ static size_t disasm_jsr(
case 1: // 4e88 .. 4e8f
return disasm_verbatim(out, out_sz, instr, offset, code);
case 2: // 4e90 .. 4e97
- snprintf(out, out_sz, " jsr %%a%d@ | %04x @%" PRIu32 "\n", xn, instr, offset);
+ snprintf(out, out_sz, " jsr %%a%d@ | %04x @%08" PRIx32 "\n", xn, instr, offset);
return kInstructionSizeStepBytes;
case 3: // 4e98 .. 4e9f
case 4: // 4ea0 .. 4ea7
return disasm_verbatim(out, out_sz, instr, offset, code);
- case 5: // 4ea8 .. 4eaf
+ case 5: // 4ea8 .. 4eaf, Displacement
{
const int16_t dispmt = GetI16BE(code.buffer + offset + kInstructionSizeStepBytes);
const uint16_t dispmt_u = static_cast<uint16_t>(dispmt);
snprintf(
out, out_sz,
- " jsr %%a%d@(%d) | %04x %04x @%" PRIu32 "\n",
+ " jsr %%a%d@(%d) | %04x %04x @%08" PRIx32 "\n",
xn, dispmt, instr, dispmt_u, offset);
return 4;
}
break;
case 6: // 4eb0 .. 4eb7, Brief Extension Word
- // TODO
+ {
+ const uint16_t briefext = GetU16BE(code.buffer + offset + kInstructionSizeStepBytes);
+ const int m_0d_1a = (briefext >> 15) & 1;
+ const int xn2 = (briefext >> 12) & 7;
+ const int s_0w_1l = (briefext >> 11) & 1;
+ const int8_t dispmt = briefext & 0xff;
+ snprintf(
+ out, out_sz,
+ " jsr %%a%d@(%d,%%%c%d:%c) | %04x %04x @%08" PRIx32 "\n",
+ xn, dispmt, m_0d_1a ? 'a' : 'd', xn2, s_0w_1l ? 'l' : 'w', instr, briefext, offset);
+ return 4;
+ }
break;
case 7: // 4eb0 .. 4eb7, some are with Brief Extension Word
switch (xn) {
- case 0:
- case 1:
- case 2:
- case 3:
+ case 0: // 4eb0
+ case 1: // 4eb1
+ case 2: // 4eb2
+ case 3: // 4eb3
+ // TODO
+ break;
case 4:
case 5:
case 6:
- // TODO
- break;
+ return disasm_verbatim(out, out_sz, instr, offset, code);
}
break;
}
diff --git a/test.bash b/test.bash
index d258bbb..5f4176d 100644
--- a/test.bash
+++ b/test.bash
@@ -20,13 +20,14 @@ run_test() {
prefix=$2
offset=$3
count=$4
- suffix=$5
+ step=$5
+ suffix=$6
file_orig_bin=${TEST_DIR}/${test_name}.orig.bin
file_asm=${TEST_DIR}/${test_name}.S
file_as_o=${TEST_DIR}/${test_name}.as.o
file_as_bin=${TEST_DIR}/${test_name}.as.bin
- for i in $(seq 0 $(( count-1 )) ); do
- echo -ne "Test ${test_name}:$i... "
+ for i in $(seq 0 $(( step )) $(( count*step-1 )) ); do
+ echo -ne "Test ${test_name}:$(( i / step ))... "
value=$(printf "%02x\n" $(( offset+i )))
echo -ne "${prefix}\x${value}${suffix}" >${file_orig_bin}
./cmake-build/m68k-disasm -t ${TRACE_FILE} -o ${file_asm} ${file_orig_bin}
@@ -41,6 +42,7 @@ run_test() {
break;
else
echo "OK"
+ cat ${file_asm}
fi
done
}
@@ -48,22 +50,43 @@ run_test() {
jsr_m2() {
# 4e90..4e97
#
- run_test ${FUNCNAME} "\x4e" 0x90 8 ""
+ # All registers
+ run_test ${FUNCNAME} "\x4e" 0x90 8 1 ""
}
-jsr_m6() {
- # (4ea8..4eaf) 0000
+jsr_m5() {
+ # (4ea8..4eaf) xxxx
#
# XXX this test fails with suffix "\x00\x00", because GNU AS makes
# optimization and inserts jsr M2/"(An)" (0x4e90) version instead. Hence the
# disassembler must generate ".short" alternative in such cases. But it may be
# irrelevant in practice if this variant simply does not exist in the wild.
#
- # Positive value
- run_test ${FUNCNAME} "\x4e" 0xa8 8 "\x00\x0a"
+ # Positive value, all registers
+ run_test ${FUNCNAME} "\x4e" 0xa8 8 1 "\x00\x0a"
+ # Negative value
+ run_test ${FUNCNAME} "\x4e" 0xa8 1 1 "\x80\x0f"
+}
+
+jsr_m6() {
+ # (4eb0..4eb7) xxxx
+ #
+ # Positive value, Arbitrary Xn register
+ run_test ${FUNCNAME} "\x4e" 0xb0 8 1 "\x00\x0f"
# Negative value
- run_test ${FUNCNAME} "\x4e" 0xa8 8 "\x80\x0f"
+ run_test ${FUNCNAME} "\x4e" 0xb0 1 1 "\x00\xf0"
+ # Zero displacement
+ run_test ${FUNCNAME} "\x4e" 0xb0 1 1 "\x00\x00"
+ # Address register
+ run_test ${FUNCNAME} "\x4e" 0xb0 1 1 "\x80\x0a"
+ # Long displacement, positive
+ run_test ${FUNCNAME} "\x4e" 0xb0 1 1 "\x08\x0c"
+ # Long displacement, negative
+ run_test ${FUNCNAME} "\x4e" 0xb0 1 1 "\x08\xb0"
+ # Arbitrary Xn2
+ run_test ${FUNCNAME} "\x4e\xb0" 0x00 8 0x10 "\x0f"
}
jsr_m2
+jsr_m5
jsr_m6