diff options
author | Oxore <oxore@protonmail.com> | 2023-05-01 14:45:22 +0300 |
---|---|---|
committer | Oxore <oxore@protonmail.com> | 2023-05-01 14:51:49 +0300 |
commit | 00038b83f7bfc0523ef06139498eadea67b16e22 (patch) | |
tree | 05ef9beb2c457b18be415f4eada3972a2394018f | |
parent | 9f5afd04e4542fd385dbef235018b771b8f82952 (diff) |
Impl TAS and TST
-rw-r--r-- | disasm.cpp | 90 | ||||
-rw-r--r-- | test.bash | 9 |
2 files changed, 90 insertions, 9 deletions
@@ -717,6 +717,85 @@ static void chunk_mf900_v4000( node.size = kInstructionSizeStepBytes + a.Size(); } +static void disasm_trivial( + DisasmNode& node, uint16_t, const DataBuffer &, const Settings &, const char* mnemonic) +{ + node.size = kInstructionSizeStepBytes; + snprintf(node.mnemonic, kMnemonicBufferSize, mnemonic); +} + +static inline void disasm_tas( + DisasmNode& node, uint16_t instr, const DataBuffer &code, const Settings &s) +{ + const auto a = AddrModeArg::Fetch(node.offset + kInstructionSizeStepBytes, code, instr, 'w'); + switch (a.mode) { + case AddrMode::kInvalid: + return disasm_verbatim(node, instr, code, s); + case AddrMode::kDn: + break; + case AddrMode::kAn: + return disasm_verbatim(node, instr, code, s); + case AddrMode::kAnAddr: + case AddrMode::kAnAddrIncr: + case AddrMode::kAnAddrDecr: + case AddrMode::kD16AnAddr: + case AddrMode::kD8AnXiAddr: + case AddrMode::kWord: + case AddrMode::kLong: + break; + case AddrMode::kD16PCAddr: + case AddrMode::kD8PCXiAddr: + 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); + node.size = kInstructionSizeStepBytes + a.Size(); +} + +static void disasm_tst_tas_illegal( + DisasmNode& node, uint16_t instr, const DataBuffer &code, const Settings &s) +{ + const auto opsize = static_cast<OpSize>((instr >> 6) & 3); + const int m = (instr >> 3) & 7; + const int xn = instr& 7; + if (opsize == OpSize::kInvalid) { + if (m == 7 && xn == 4){ + return disasm_trivial(node, instr, code, s, "illegal"); + } + return disasm_tas(node, instr, code, s); + } + const char suffix = suffix_from_opsize(opsize); + const auto a = AddrModeArg::Fetch(node.offset + kInstructionSizeStepBytes, code, m, xn, suffix); + switch (a.mode) { + case AddrMode::kInvalid: + return disasm_verbatim(node, instr, code, s); + case AddrMode::kDn: + break; + case AddrMode::kAn: + return disasm_verbatim(node, instr, code, s); + case AddrMode::kAnAddr: + case AddrMode::kAnAddrIncr: + case AddrMode::kAnAddrDecr: + case AddrMode::kD16AnAddr: + case AddrMode::kD8AnXiAddr: + case AddrMode::kWord: + case AddrMode::kLong: + case AddrMode::kD16PCAddr: + case AddrMode::kD8PCXiAddr: + break; + 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); + node.size = kInstructionSizeStepBytes + a.Size(); +} + static void disasm_trap( DisasmNode& node, uint16_t instr, const DataBuffer &, const Settings &) { @@ -777,20 +856,13 @@ static void disasm_move_usp( } } -static void disasm_trivial( - DisasmNode& node, uint16_t, const DataBuffer &, const Settings &, const char* mnemonic) -{ - node.size = kInstructionSizeStepBytes; - snprintf(node.mnemonic, kMnemonicBufferSize, mnemonic); -} - static void chunk_mf000_v4000( DisasmNode& node, uint16_t instr, const DataBuffer &code, const Settings &s) { if ((instr & 0xf900) == 0x4000) { return chunk_mf900_v4000(node, instr, code, s); - } else if (instr == 0x4afc) { - return disasm_trivial(node, instr, code, s, "illegal"); + } else if ((instr & 0xff00) == 0x4a00) { + return disasm_tst_tas_illegal(node, instr, code, s); } else if ((instr & 0xfff0) == 0x4e40) { return disasm_trap(node, instr, code, s); } else if ((instr & 0xfff0) == 0x4e50) { @@ -93,6 +93,15 @@ run_test_iterative() { done } +# 4axx +# +run_test_simple "tas Dn" "\x4a\xc2" +run_test_simple "tstb Dn" "\x4a\x02" +run_test_simple "tstw Dn" "\x4a\x42" +run_test_simple "tstl Dn" "\x4a\x82" +run_test_expect_short "tas (d16,PC)" "\x4a\xfa\xff\xff" +run_test_expect_short "tas (d8,PC,Xi)" "\x4a\xfb\x00\x00" + # 4xxx # run_test_simple "negxb Dn" "\x40\x04" |