diff options
Diffstat (limited to 'src/devices/cpu/tx0/tx0dasm.cpp')
-rw-r--r-- | src/devices/cpu/tx0/tx0dasm.cpp | 739 |
1 files changed, 654 insertions, 85 deletions
diff --git a/src/devices/cpu/tx0/tx0dasm.cpp b/src/devices/cpu/tx0/tx0dasm.cpp index 34d49194ed3..2ea131211e1 100644 --- a/src/devices/cpu/tx0/tx0dasm.cpp +++ b/src/devices/cpu/tx0/tx0dasm.cpp @@ -1,5 +1,11 @@ // license:BSD-3-Clause -// copyright-holders:Raphael Nabet +// copyright-holders:AJR +/*************************************************************************** + + MIT TX-0 disassembler + +***************************************************************************/ + #include "emu.h" #include "tx0dasm.h" @@ -8,126 +14,689 @@ u32 tx0_64kw_disassembler::opcode_alignment() const return 1; } -offs_t tx0_64kw_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +u32 tx0_8kw_disassembler::opcode_alignment() const +{ + return 1; +} + +namespace { + +const std::string_view s_addressable_insts[24] = +{ + "sto", "stx", "sxa", "ado", "slr", "slx", "stz", {}, + "add", "adx", "ldx", "aux", "llr", "llx", "lda", "lax", + "trn", "tze", "tsx", "tix", "tra", "trx", "tlv", {} +}; + +const std::string_view s_tape_insts[8] = { - int md; - int x; + "bsr", "rtb", "rew", "wtb", + "bsr", "rtd", "rew", "wtd" +}; - md = opcodes.r32(pc); +} // anonymous namespace - x = md & 0177777; - switch (md >> 16) +offs_t tx0_64kw_disassembler::disassemble(std::ostream &stream, offs_t pc, const tx0_64kw_disassembler::data_buffer &opcodes, const tx0_64kw_disassembler::data_buffer ¶ms) +{ + u32 inst = opcodes.r32(pc) & 0777777; + + if (inst < 0600000) { - case 0: - util::stream_format(stream, "sto 0%06o", x); + // Addressable instructions (only 3 in this version) + util::stream_format(stream, "%s %06o", s_addressable_insts[(inst & 0600000) >> 13], inst & 0177777); + } + else switch (inst) + { + case 0600012: + stream << "cry"; break; - case 1: - util::stream_format(stream, "add 0%06o", x); + + case 0600022: + stream << "lpd"; break; - case 2: - util::stream_format(stream, "trn 0%06o", x); + + case 0600031: + stream << "cyl"; break; - case 3: - util::stream_format(stream, "opr 0%06o", x); + + case 0600032: + stream << "lad"; break; - } - return 1; -} -u32 tx0_8kw_disassembler::opcode_alignment() const -{ - return 1; -} + case 0600040: + stream << "com"; + break; -offs_t tx0_8kw_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) -{ - int md; - int x; + case 0600051: + stream << "amz"; + break; - md = opcodes.r32(pc); + case 0600100: + stream << "pen"; + break; - x = md & 0017777; - switch (md >> 13) - { - case 0: - util::stream_format(stream, "sto 0%05o", x); + case 0600200: + stream << "lro"; + break; + + case 0600201: + stream << "alr"; + break; + + case 0600221: + stream << "ala"; + break; + + case 0600261: + stream << "alc"; + break; + + case 0600400: + stream << "shr"; + break; + + case 0600600: + stream << "cyr"; + break; + + case 0622000: + stream << "dis"; break; - case 1: - util::stream_format(stream, "stx 0%05o", x); + + case 0622021: + stream << "dsa"; break; - case 2: - util::stream_format(stream, "sxa 0%05o", x); + + case 0622061: + stream << "dsc"; break; - case 3: - util::stream_format(stream, "ado 0%05o", x); + + case 0624000: + stream << "prt"; break; - case 4: - util::stream_format(stream, "slr 0%05o", x); + + case 0624021: + stream << "pna"; break; - case 5: - util::stream_format(stream, "slx 0%05o", x); + + case 0624061: + stream << "pnc"; break; - case 6: - util::stream_format(stream, "stz 0%05o", x); + + case 0624600: + stream << "pnt"; break; - case 8: - util::stream_format(stream, "add 0%05o", x); + + case 0626021: case 0627021: + util::stream_format(stream, "p%da", BIT(inst, 9) ? 7 : 6); break; - case 9: - util::stream_format(stream, "adx 0%05o", x); + + case 0626600: case 0627600: + util::stream_format(stream, "p%dh", BIT(inst, 9) ? 7 : 6); break; - case 10: - util::stream_format(stream, "ldx 0%05o", x); + + case 0630000: + stream << "hlt"; break; - case 11: - util::stream_format(stream, "aux 0%05o", x); + + case 0640000: + stream << "clr"; break; - case 12: - util::stream_format(stream, "llr 0%05o", x); + + case 0666020: case 0667020: + util::stream_format(stream, "p%do", BIT(inst, 9) ? 7 : 6); break; - case 13: - util::stream_format(stream, "llx 0%05o", x); + + case 0700000: + stream << "cll"; break; - case 14: - util::stream_format(stream, "lda 0%05o", x); + + case 0740000: + stream << "cla"; break; - case 15: - util::stream_format(stream, "lax 0%05o", x); + + case 0740004: + stream << "tac"; break; - case 16: - util::stream_format(stream, "trn 0%05o", x); + + case 0740022: + stream << "lac"; break; - case 17: - util::stream_format(stream, "tze 0%05o", x); + + case 0740023: + stream << "tbr"; break; - case 18: - util::stream_format(stream, "tsx 0%05o", x); + + case 0740040: + stream << "clc"; break; - case 19: - util::stream_format(stream, "tix 0%05o", x); + + case 0740200: + stream << "cal"; break; - case 20: - util::stream_format(stream, "tra 0%05o", x); + + case 0761000: + stream << "r1c"; break; - case 21: - util::stream_format(stream, "trx 0%05o", x); + + case 0761031: + stream << "r1l"; break; - case 22: - util::stream_format(stream, "tlv 0%05o", x); + + case 0761600: + stream << "r1r"; break; - case 24: - case 25: - case 26: - case 27: - case 28: - case 29: - case 30: - case 31: - util::stream_format(stream, "opr 0%06o", md & 0177777); + + case 0763000: + stream << "r3c"; break; + + case 0766000: + stream << "p6s"; + break; + default: - util::stream_format(stream, "illegal"); + if (inst >= 0760000) + util::stream_format(stream, "ios %o", inst & 017777); + else + util::stream_format(stream, "opr %o", inst & 0177777); break; } - return 1; + + return 1 | SUPPORTED; +} + +offs_t tx0_8kw_disassembler::disassemble(std::ostream &stream, offs_t pc, const tx0_8kw_disassembler::data_buffer &opcodes, const tx0_8kw_disassembler::data_buffer ¶ms) +{ + u32 inst = opcodes.r32(pc) & 0777777; + + if (inst < 0600000) + { + // Addressable instructions + std::string_view str = s_addressable_insts[(inst & 0760000) >> 13]; + if (str.empty()) + util::stream_format(stream, "%06o", inst); + else + { + util::stream_format(stream, "%s %05o", str, inst & 017777); + + if ((inst & 0760000) == 0440000) // tsx + return 1 | STEP_OVER | SUPPORTED; + else if ((inst & 0760000) == 0520000) // trx + return 1 | STEP_OUT | SUPPORTED; + } + } + else if ((inst & 037000) == 004000) + { + // Select class + if (BIT(inst, 15)) + stream << "claU"; + util::stream_format(stream, "%s %d", s_tape_insts[BIT(inst, 2, 3)], inst & 3); + } + else + { + if ((inst & 037000) == 02000) + { + stream << "tbr"; + if ((inst & 0100757) == 0) + return 1 | SUPPORTED; + stream << 'U'; + } + else if (inst == 0706020) + { + stream << "rpf"; + return 1 | SUPPORTED; + } + else if ((inst & 037000) == 07000) + { + if (BIT(inst, 14)) + stream << "spf"; + else + stream << "cpf"; + if ((inst & 0100777) == 0) + return 1 | SUPPORTED; + stream << 'U'; + } + else if ((inst & 037000) == 020000) + { + stream << "cpy"; + if ((inst & 0100777) == 0) + return 1 | SUPPORTED; + stream << 'U'; + } + else if ((inst & 037000) == 025000) + { + stream << "typ"; + if ((inst & 0100777) == 0) + return 1 | SUPPORTED; + stream << 'U'; + } + else if ((inst & 036777) == 026600) + { + util::stream_format(stream, "p%dh", BIT(inst, 9) ? 7 : 6); + return 1 | SUPPORTED; + } + else if ((inst & 076777) == 066020) + { + util::stream_format(stream, "p%do", BIT(inst, 9) ? 7 : 6); + return 1 | SUPPORTED; + } + else if ((inst & 037000) == 030000) + { + // HLT is actually executed last, but normally written first + stream << "hlt"; + if ((inst & 0100777) == 0) + return 1 | SUPPORTED; + stream << 'U'; + } + else if ((inst & 037000) == 031000) + { + stream << "cll"; + if ((inst & 0100777) == 0) + return 1 | SUPPORTED; + stream << 'U'; + } + else if ((inst & 037000) == 032000) + { + stream << "clr"; + if ((inst & 0100777) == 0) + return 1 | SUPPORTED; + stream << 'U'; + } + else if ((inst & 037000) != 0) + { + if (BIT(inst, 15)) + { + switch (inst & 037000) + { + case 01000: + stream << "tac"; + break; + + case 03000: + stream << "claUpen"; + break; + + case 010000: case 011000: case 012000: case 013000: case 014000: case 015000: case 016000: case 017000: + util::stream_format(stream, "claUex%d", BIT(inst, 9, 3)); + break; + + case 021000: + if ((inst & 0777) == 0600) + { + stream << "r1r"; + return 1 | SUPPORTED; + } + stream << "r1c"; + break; + + case 022000: + stream << "claUdis"; + break; + + case 023000: + stream << "r3c"; + break; + + case 024000: + stream << "claUprt"; + break; + + case 026000: + if ((inst & 040777) == 040020) + { + stream << "p6b"; + return 1 | SUPPORTED; + } + stream << "p6s"; + break; + + default: + util::stream_format(stream, "opr %o", inst & 0177777); + return 1 | SUPPORTED; + } + if ((inst & 0777) == 0) + return 1 | SUPPORTED; + inst &= 040777; + stream << 'U'; + } + else + { + switch (inst & 037000) + { + case 03000: + stream << "pen"; + break; + + case 010000: case 011000: case 012000: case 013000: case 014000: case 015000: case 016000: case 017000: + util::stream_format(stream, "ex%d", BIT(inst, 9, 3)); + break; + + case 021000: + stream << "r1l"; + break; + + case 022000: + if ((inst & 040777) == 040020) + { + stream << "dso"; + return 1 | SUPPORTED; + } + stream << "dis"; + break; + + case 023000: + stream << "r3l"; + break; + + case 024000: + if ((inst & 040777) == 040020) + { + stream << "pno"; + return 1 | SUPPORTED; + } + else if ((inst & 040777) == 040060) + { + stream << "pnc"; + return 1 | SUPPORTED; + } + else if ((inst & 0777) == 0600) + { + stream << "pnt"; + return 1 | SUPPORTED; + } + stream << "prt"; + break; + + default: + util::stream_format(stream, "opr %o", inst & 0177777); + return 1 | SUPPORTED; + } + if ((inst & 0777) == 0) + return 1 | SUPPORTED; + stream << 'U'; + } + } + else if (inst == 0600000) + { + stream << "nop"; + return 1 | SUPPORTED; + } + + switch (inst & 0140777) + { + case 0: + break; + + case 000001: + stream << "xro"; + break; + + case 000003: + stream << "lxr"; + break; + + case 000012: + stream << "cry"; + break; + + case 000022: + stream << "lpd"; + break; + + case 000031: + stream << "alx"; + break; + + case 000032: + stream << "lad"; + break; + + case 000033: + stream << "ladUxro"; + break; + + case 000040: case 040040: + stream << "com"; + break; + + case 000041: + stream << "comUxro"; + break; + + case 000043: + stream << "comUlxr"; + break; + + case 000062: + stream << "lpdUcom"; + break; + + case 000072: + stream << "lcd"; + break; + + case 000130: + stream << "xad"; + break; + + case 000170: + stream << "xcd"; + break; + + case 000200: + stream << "lro"; + break; + + case 000240: + stream << "comUlro"; + break; + + case 000272: + stream << "lcdUlro"; + break; + + case 000300: + stream << "xlr"; + break; + + case 000303: + stream << "ixl"; + break; + + case 000400: + stream << "shr"; + break; + + case 000600: + stream << "cyr"; + break; + + case 000612: + stream << "cyrUcry"; // M-5001-19 names this 'ran' (random number generator) + break; + + case 000640: + stream << "comUcyr"; + break; + + case 040001: + stream << "axr"; + break; + + case 040021: + stream << "axo"; + break; + + case 040030: + stream << "cyl"; + break; + + case 040031: + stream << "axrUcyl"; + break; + + case 040050: + stream << "amz"; + break; + + case 040061: + stream << "axc"; + break; + + case 040200: + stream << "alr"; + break; + + case 040201: + stream << "alrUaxr"; + break; + + case 040203: + stream << "rax"; + break; + + case 040205: + stream << "orl"; + break; + + case 040207: + stream << "anl"; + break; + + case 040220: + stream << "alo"; + break; + + case 040230: + stream << "all"; + break; + + case 040231: + stream << "alrUalx"; + break; + + case 040232: + stream << "iad"; + break; + + case 040240: + stream << "alrUcom"; + break; + + case 040247: + stream << "anlUcom"; + break; + + case 040260: + stream << "alc"; + break; + + case 040601: + stream << "arx"; + break; + + case 0100000: case 0140000: + stream << "cla"; + break; + + case 0100001: + stream << "cax"; + break; + + case 0100012: + stream << "lal"; + break; + + case 0100022: case 0140022: + stream << "lac"; + break; + + case 0100023: + stream << "lacUlxr"; + break; + + case 0100040: case 0140040: + stream << "clc"; + break; + + case 0100062: + stream << "lcc"; + break; + + case 0100072: + stream << "laz"; + break; + + case 0100110: + stream << "xal"; + break; + + case 0100120: + stream << "xac"; + break; + + case 0100160: + stream << "xcc"; + break; + + case 0100200: + stream << "cal"; + break; + + case 0100240: + stream << "calUcom"; + break; + + case 0100322: + stream << "rxa"; + break; + + case 0100622: + stream << "lar"; + break; + + case 0140025: + stream << "ora"; + break; + + case 0140027: + stream << "ana"; + break; + + case 0140065: + stream << "oraUcom"; // M-5001-19-1 names this 'orc' + break; + + case 0140067: + stream << "anaUcom"; // M-5001-19-1 names this 'anc' + break; + + case 0140205: + stream << "oro"; + break; + + case 0140207: + stream << "ano"; + break; + + case 0140212: + stream << "lalUalr"; // M-5001-19-1 names this 'ill' + break; + + case 0140222: + stream << "ial"; + break; + + case 0140262: + stream << "ialUcom"; + break; + + default: + util::stream_format(stream, "opr %o", inst & 0140777); + break; + } + } + + return 1 | SUPPORTED; } |