summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.cpp74
-rw-r--r--test.bash72
2 files changed, 125 insertions, 21 deletions
diff --git a/main.cpp b/main.cpp
index 6dcb669..12fdd32 100644
--- a/main.cpp
+++ b/main.cpp
@@ -108,6 +108,14 @@ static inline int16_t GetI16BE(uint8_t *buffer)
return (static_cast<uint16_t>(buffer[0]) << 8) | static_cast<uint16_t>(buffer[1]);
}
+static inline int32_t GetI32BE(uint8_t *buffer)
+{
+ return (static_cast<uint32_t>(buffer[0]) << 24) |
+ (static_cast<uint32_t>(buffer[1]) << 16) |
+ (static_cast<uint32_t>(buffer[2]) << 8) |
+ static_cast<uint32_t>(buffer[3]);
+}
+
static size_t disasm_jsr(
char *out, size_t out_sz, uint16_t instr, uint32_t offset, const DataBuffer & code)
{
@@ -119,7 +127,7 @@ 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 @%08" PRIx32 "\n", xn, instr, offset);
+ snprintf(out, out_sz, " jsr %%a%d@ | %04x @%08x\n", xn, instr, offset);
return kInstructionSizeStepBytes;
case 3: // 4e98 .. 4e9f
case 4: // 4ea0 .. 4ea7
@@ -130,7 +138,7 @@ static size_t disasm_jsr(
const uint16_t dispmt_u = static_cast<uint16_t>(dispmt);
snprintf(
out, out_sz,
- " jsr %%a%d@(%d) | %04x %04x @%08" PRIx32 "\n",
+ " jsr %%a%d@(%d:w) | %04x %04x @%08x\n",
xn, dispmt, instr, dispmt_u, offset);
return 4;
}
@@ -144,22 +152,64 @@ static size_t disasm_jsr(
const int8_t dispmt = briefext & 0xff;
snprintf(
out, out_sz,
- " jsr %%a%d@(%d,%%%c%d:%c) | %04x %04x @%08" PRIx32 "\n",
+ " jsr %%a%d@(%d,%%%c%d:%c) | %04x %04x @%08x\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
+ case 7: // 4eb8 .. 4ebf, some are with Brief Extension Word
switch (xn) {
- case 0: // 4eb0
- case 1: // 4eb1
- case 2: // 4eb2
- case 3: // 4eb3
- // TODO
+ case 0: // 4eb8 (xxx).W
+ {
+ const int32_t dispmt = GetI16BE(code.buffer + offset + kInstructionSizeStepBytes);
+ const uint16_t dispmt_u = static_cast<uint16_t>(dispmt);
+ snprintf(
+ out, out_sz,
+ " jsr 0x%x:w | %04x %04x @%08x\n",
+ dispmt, instr, dispmt_u, offset);
+ return 4;
+ }
+ return disasm_verbatim(out, out_sz, instr, offset, code);
+ case 1: // 4eb9 (xxx).L
+ {
+ const int32_t dispmt = GetI32BE(code.buffer + offset + kInstructionSizeStepBytes);
+ const uint16_t dispmt_u_p1 = static_cast<uint16_t>(dispmt >> 16) & 0xffff;
+ const uint16_t dispmt_u_p2 = static_cast<uint16_t>(dispmt) & 0xffff;
+ snprintf(
+ out, out_sz,
+ " jsr 0x%x:l | %04x %04x %04x @%08x\n",
+ dispmt, instr, dispmt_u_p1, dispmt_u_p2, offset);
+ return 6;
+ }
+ return disasm_verbatim(out, out_sz, instr, offset, code);
+ case 2: // 4eba, 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 %%pc@(%d:w) | %04x %04x @%08x\n",
+ dispmt, instr, dispmt_u, offset);
+ return 4;
+ }
+ break;
+ case 3: // 4ebb
+ {
+ 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 %%pc@(%d,%%%c%d:%c) | %04x %04x @%08x\n",
+ dispmt, m_0d_1a ? 'a' : 'd', xn2, s_0w_1l ? 'l' : 'w', instr, briefext, offset);
+ return 4;
+ }
break;
- case 4:
- case 5:
- case 6:
+ case 4: // 4ebc
+ case 5: // 4ebd
+ case 6: // 4ebe
return disasm_verbatim(out, out_sz, instr, offset, code);
}
break;
diff --git a/test.bash b/test.bash
index 5f4176d..49a7a02 100644
--- a/test.bash
+++ b/test.bash
@@ -33,8 +33,9 @@ run_test() {
./cmake-build/m68k-disasm -t ${TRACE_FILE} -o ${file_asm} ${file_orig_bin}
${AS} -o ${file_as_o} ${file_asm}
${OBJCOPY} ${file_as_o} -O binary ${file_as_bin}
- if ! cmp ${file_orig_bin} ${file_as_bin}; then
- echo ""
+ if ! cmp ${file_orig_bin} ${file_as_bin} >/dev/null 2>&1; then
+ echo "FAIL"
+ cat ${file_asm}
echo ${file_orig_bin}
hexdump -Cv ${file_orig_bin} | head -n1
echo ${file_as_bin}
@@ -42,7 +43,7 @@ run_test() {
break;
else
echo "OK"
- cat ${file_asm}
+ #cat ${file_asm}
fi
done
}
@@ -57,11 +58,8 @@ jsr_m2() {
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.
- #
+ # Zero value
+ run_test ${FUNCNAME} "\x4e" 0xa8 8 1 "\x00\x00"
# Positive value, all registers
run_test ${FUNCNAME} "\x4e" 0xa8 8 1 "\x00\x0a"
# Negative value
@@ -71,7 +69,7 @@ jsr_m5() {
jsr_m6() {
# (4eb0..4eb7) xxxx
#
- # Positive value, Arbitrary Xn register
+ # Positive value, Arbitrary An register
run_test ${FUNCNAME} "\x4e" 0xb0 8 1 "\x00\x0f"
# Negative value
run_test ${FUNCNAME} "\x4e" 0xb0 1 1 "\x00\xf0"
@@ -87,6 +85,62 @@ jsr_m6() {
run_test ${FUNCNAME} "\x4e\xb0" 0x00 8 0x10 "\x0f"
}
+jsr_m7_xn0() {
+ # 43b8 xxxx Word displacement
+ #
+ # Zero value
+ run_test ${FUNCNAME} "\x4e\xb8\x00" 0x00 1 1 ""
+ # Positive value
+ run_test ${FUNCNAME} "\x4e\xb8\x00" 0x1f 1 1 ""
+ # Negative value
+ run_test ${FUNCNAME} "\x4e\xb8" 0x8a 1 1 "\x0c"
+}
+
+jsr_m7_xn1() {
+ # 43b9 xxxx Long displacement
+ #
+ # Zero value
+ run_test ${FUNCNAME} "\x4e\xb9\x00\x00\x00" 0x00 1 1 ""
+ # Positive value
+ run_test ${FUNCNAME} "\x4e\xb9\x10\xbb\x43" 0x1f 1 1 ""
+ # Negative value
+ run_test ${FUNCNAME} "\x4e\xb9\x80\xcc\xd9" 0x8a 1 1 ""
+}
+
+jsr_m7_xn2() {
+ # 43ba xxxx
+ #
+ # Zero value
+ run_test ${FUNCNAME} "\x4e\xba\x00" 0x00 1 1 ""
+ # Positive value
+ run_test ${FUNCNAME} "\x4e\xba\x00" 0x1f 1 1 ""
+ # Negative value
+ run_test ${FUNCNAME} "\x4e\xba" 0x8a 1 1 "\x0c"
+}
+
+jsr_m7_xn3() {
+ # 43bb xxxx
+ #
+ # Positive value, Arbitrary Xn register
+ run_test ${FUNCNAME} "\x4e\xbb" 0x00 8 0x10 "\x1a"
+ # Negative value
+ run_test ${FUNCNAME} "\x4e" 0xbb 1 1 "\x00\xf0"
+ # Zero displacement
+ run_test ${FUNCNAME} "\x4e" 0xbb 1 1 "\x00\x00"
+ # Address register
+ run_test ${FUNCNAME} "\x4e" 0xbb 1 1 "\x80\x0a"
+ # Long displacement, positive
+ run_test ${FUNCNAME} "\x4e" 0xbb 1 1 "\x08\x0c"
+ # Long displacement, negative
+ run_test ${FUNCNAME} "\x4e" 0xbb 1 1 "\x08\xb0"
+ # Arbitrary Xn2
+ run_test ${FUNCNAME} "\x4e\xbb" 0x00 8 0x10 "\x0f"
+}
+
jsr_m2
jsr_m5
jsr_m6
+jsr_m7_xn0
+jsr_m7_xn1
+jsr_m7_xn2
+jsr_m7_xn3