diff options
author | Oxore <oxore@protonmail.com> | 2023-05-01 14:21:15 +0300 |
---|---|---|
committer | Oxore <oxore@protonmail.com> | 2023-05-01 14:25:58 +0300 |
commit | 9f5afd04e4542fd385dbef235018b771b8f82952 (patch) | |
tree | c5c13584f8a191690e6d3789797c728231a0724f | |
parent | f279e467e38281cfdee60b197588109abd08e83d (diff) |
Impl NEGX, CLR, NEG and NOT
-rw-r--r-- | disasm.cpp | 70 | ||||
-rw-r--r-- | test.bash | 17 |
2 files changed, 80 insertions, 7 deletions
@@ -655,6 +655,68 @@ static void disasm_move_to( node.size = kInstructionSizeStepBytes + src.Size(); } +const char *mnemonic_for_chunk_mf800_v4000(const unsigned opcode) +{ + switch (opcode) { + case 0: return "negx"; + case 1: return "clr"; + case 2: return "neg"; + case 3: return "not"; + } + assert(false); + return "?"; +} + +static void chunk_mf900_v4000( + DisasmNode& node, uint16_t instr, const DataBuffer &code, const Settings &s) +{ + const auto opsize = static_cast<OpSize>((instr >> 6) & 3); + const unsigned opcode = (instr >> 9) & 3; + if (opsize == OpSize::kInvalid) { + switch (opcode) { + case 0: + return disasm_move_from_sr(node, instr, code, s); + case 1: + return disasm_verbatim(node, instr, code, s); + case 2: + return disasm_move_to(node, instr, code, s, "ccr"); + case 3: + return disasm_move_to(node, instr, code, s, "sr"); + } + assert(false); + return disasm_verbatim(node, instr, code, s); + } + const char *mnemonic = mnemonic_for_chunk_mf800_v4000(opcode); + const char suffix = suffix_from_opsize(opsize); + const auto a = AddrModeArg::Fetch( + node.offset + kInstructionSizeStepBytes, code, instr, 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: + 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, "%s%c", mnemonic, 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 &) { @@ -725,12 +787,8 @@ static void disasm_trivial( static void chunk_mf000_v4000( DisasmNode& node, uint16_t instr, const DataBuffer &code, const Settings &s) { - if ((instr & 0xffc0) == 0x40c0) { - return disasm_move_from_sr(node, instr, code, s); - } else if ((instr & 0xffc0) == 0x44c0) { - return disasm_move_to(node, instr, code, s, "ccr"); - } else if ((instr & 0xffc0) == 0x46c0) { - return disasm_move_to(node, instr, code, s, "sr"); + 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 & 0xfff0) == 0x4e40) { @@ -93,6 +93,21 @@ run_test_iterative() { done } +# 4xxx +# +run_test_simple "negxb Dn" "\x40\x04" +run_test_simple "clrb Dn" "\x42\x05" +run_test_simple "negb Dn" "\x44\x06" +run_test_simple "notb Dn" "\x46\x07" +run_test_simple "negxw Dn" "\x40\x44" +run_test_simple "clrw Dn" "\x42\x45" +run_test_simple "negw Dn" "\x44\x46" +run_test_simple "notw Dn" "\x46\x47" +run_test_simple "negxl Dn" "\x40\x84" +run_test_simple "clrl Dn" "\x42\x85" +run_test_simple "negl Dn" "\x44\x86" +run_test_simple "notl Dn" "\x46\x87" + # 4e4x # run_test_simple "trap 0" "\x4e\x40" @@ -111,7 +126,7 @@ run_test_simple "unlk" "\x4e\x5a" run_test_simple "move to USP" "\x4e\x62" run_test_simple "move from USP" "\x4e\x6f" -# 40c0..40ff +# 4xxx # run_test_simple "move from SR" "\x40\xc1" run_test_simple "move to CCR" "\x44\xc2" |