summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOxore <oxore@protonmail.com>2023-05-08 16:33:37 +0300
committerOxore <oxore@protonmail.com>2023-05-08 16:39:39 +0300
commit8ea1d138088f73e677d623edd8b8ad2427b4e482 (patch)
tree41d17a1a2005b3db84cb479d52b40f20b1c132d4
parentc12ef2015384fd7f35150f058dfb3b3df46dcd2c (diff)
Impl NBCD, SWAP and PEA
-rw-r--r--disasm.cpp53
-rw-r--r--test.bash16
2 files changed, 59 insertions, 10 deletions
diff --git a/disasm.cpp b/disasm.cpp
index ead5a86..ba94e3e 100644
--- a/disasm.cpp
+++ b/disasm.cpp
@@ -1011,10 +1011,8 @@ static void disasm_move_negx_clr_neg_not(
case AddrMode::kImmediate:
return disasm_verbatim(node, instr, code, s);
}
- char a_str[32]{};
- a.SNPrint(a_str, sizeof(a_str));
snprintf(node.mnemonic, kMnemonicBufferSize, "%s%c", mnemonic, suffix);
- snprintf(node.arguments, kArgsBufferSize, "%s", a_str);
+ a.SNPrint(node.arguments, kArgsBufferSize);
node.size = kInstructionSizeStepBytes + a.Size();
}
@@ -1049,10 +1047,8 @@ static inline void disasm_tas(
case AddrMode::kImmediate:
return disasm_verbatim(node, instr, code, s);
}
- char a_str[32]{};
- a.SNPrint(a_str, sizeof(a_str));
snprintf(node.mnemonic, kMnemonicBufferSize, "tas");
- snprintf(node.arguments, kArgsBufferSize, "%s", a_str);
+ a.SNPrint(node.arguments, kArgsBufferSize);
node.size = kInstructionSizeStepBytes + a.Size();
}
@@ -1090,10 +1086,8 @@ static void disasm_tst_tas_illegal(
case AddrMode::kImmediate:
return disasm_verbatim(node, instr, code, s);
}
- char a_str[32]{};
- a.SNPrint(a_str, sizeof(a_str));
snprintf(node.mnemonic, kMnemonicBufferSize, "tst%c", suffix);
- snprintf(node.arguments, kArgsBufferSize, "%s", a_str);
+ a.SNPrint(node.arguments, kArgsBufferSize);
node.size = kInstructionSizeStepBytes + a.Size();
}
@@ -1160,7 +1154,46 @@ static void disasm_move_usp(
static void disasm_nbcd_swap_pea(
DisasmNode &node, uint16_t instr, const DataBuffer &code, const Settings &s)
{
- return disasm_verbatim(node, instr, code, s);
+ const bool is_nbcd = !((instr >> 6) & 1);
+ const auto arg = AddrModeArg::Fetch(
+ node.offset + kInstructionSizeStepBytes, code, instr, 'w');
+ bool is_swap{};
+ switch (arg.mode) {
+ case AddrMode::kInvalid:
+ return disasm_verbatim(node, instr, code, s);
+ case AddrMode::kDn:
+ if (!is_nbcd) {
+ is_swap = true;
+ }
+ break;
+ case AddrMode::kAn:
+ return disasm_verbatim(node, instr, code, s);
+ case AddrMode::kAnAddr:
+ break;
+ case AddrMode::kAnAddrIncr:
+ case AddrMode::kAnAddrDecr:
+ if (!is_nbcd) {
+ return disasm_verbatim(node, instr, code, s);
+ }
+ break;
+ case AddrMode::kD16AnAddr:
+ case AddrMode::kD8AnXiAddr:
+ case AddrMode::kWord:
+ case AddrMode::kLong:
+ break;
+ case AddrMode::kD16PCAddr:
+ case AddrMode::kD8PCXiAddr:
+ if (is_nbcd) {
+ return disasm_verbatim(node, instr, code, s);
+ }
+ break;
+ case AddrMode::kImmediate:
+ return disasm_verbatim(node, instr, code, s);
+ }
+ const char *mnemonic = is_nbcd ? "nbcdb" : is_swap ? "swapw" : "peal";
+ snprintf(node.mnemonic, kMnemonicBufferSize, "%s", mnemonic);
+ arg.SNPrint(node.arguments, kArgsBufferSize);
+ node.size = kInstructionSizeStepBytes + arg.Size();
}
static void disasm_chunk_4(
diff --git a/test.bash b/test.bash
index cfa3aab..a235521 100644
--- a/test.bash
+++ b/test.bash
@@ -93,6 +93,22 @@ run_test_iterative() {
done
}
+# 48xx nbcd swap pea
+#
+run_test_simple "swapw Dn" "\x48\x47"
+run_test_simple "swapw Dn" "\x48\x42"
+run_test_simple "peal (An)" "\x48\x50"
+run_test_simple "peal (d16,An)" "\x48\x68\x80\x00"
+run_test_simple "peal (d8,An,An)" "\x48\x77\x90\xfe"
+run_test_simple "peal (d16,PC)" "\x48\x7a\x7f\xff"
+run_test_simple "peal (d8,PC,Dn)" "\x48\x7b\x68\xfe"
+run_test_simple "nbcdb Dn" "\x48\x03"
+run_test_simple "nbcdb (An)" "\x48\x14"
+run_test_simple "nbcdb (An)+" "\x48\x1c"
+run_test_simple "nbcdb -(An)" "\x48\x25"
+run_test_simple "nbcdb (d16,An)" "\x48\x28\x80\x00"
+run_test_simple "nbcdb (d8,An,An)" "\x48\x37\x90\xfe"
+
# 48xx ext
#
run_test_simple "extw %d7" "\x48\x87"