diff options
Diffstat (limited to 'src/devices/cpu/gigatron/gigatrondasm.cpp')
-rw-r--r-- | src/devices/cpu/gigatron/gigatrondasm.cpp | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/src/devices/cpu/gigatron/gigatrondasm.cpp b/src/devices/cpu/gigatron/gigatrondasm.cpp new file mode 100644 index 00000000000..e18ec7b9b59 --- /dev/null +++ b/src/devices/cpu/gigatron/gigatrondasm.cpp @@ -0,0 +1,161 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/*************************************************************************** + + Gigatron disassembler + +***************************************************************************/ + +#include "emu.h" +#include "gigatrondasm.h" + +gigatron_disassembler::gigatron_disassembler() + : util::disasm_interface() +{ +} + +const char *const gigatron_disassembler::s_ops[7] = { + "ld", + "anda", + "ora", + "xora", + "adda", + "suba", + "st" +}; + +const char *const gigatron_disassembler::s_jumps[8] = { + "jmp", + "bgt", + "blt", + "bne", + "beq", + "bge", + "ble", + "bra" +}; + +u32 gigatron_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t gigatron_disassembler::disassemble(std::ostream &stream, offs_t pc, const gigatron_disassembler::data_buffer &opcodes, const gigatron_disassembler::data_buffer ¶ms) +{ + u16 inst = opcodes.r16(pc); + u32 flags = 0; + + if (inst >= 0xe000) + { + // Jump instructions use special format + util::stream_format(stream, "%-5s", s_jumps[(inst & 0x1c00) >> 10]); + if ((inst & 0x1c00) == 0) + stream << "y,"; + + switch (inst & 0x0300) + { + case 0x0000: + if ((inst & 0x1c00) == 0) + util::stream_format(stream, "$%02x", inst & 0x00ff); + else + util::stream_format(stream, "$%04x", ((pc + 1) & 0x3f00) | (inst & 0x00ff)); + break; + + case 0x0100: + util::stream_format(stream, "[$%02x]", inst & 0x00ff); + break; + + case 0x0200: + stream << "ac"; + break; + + case 0x0300: + stream << "in"; + break; + } + + flags = STEP_OVER | step_over_extra(1); + } + else if ((inst & 0xf300) == 0x0200) + stream << "nop"; + else + { + if ((inst & 0xe300) == 0xc100) + { + // This was originally an undefined store mode + util::stream_format(stream, "%-5s", "ctrl"); + } + else + { + util::stream_format(stream, "%-5s", s_ops[(inst & 0xe000) >> 13]); + + // Bus data + switch (inst & 0x0300) + { + case 0x0000: + util::stream_format(stream, "$%02x", inst & 0x00ff); + if (inst >= 0xc000) + stream << ","; + break; + + case 0x0100: + break; + + case 0x0200: + if (inst < 0xc000) + stream << "ac"; // implicit for store instruction + break; + + case 0x0300: + stream << "in"; + if (inst >= 0xc000) + stream << ","; + break; + } + } + + // RAM source or store destination + if (inst >= 0xc000 || (inst & 0x0300) == 0x0100) + { + if ((inst & 0xe300) != 0xc100) + stream << "["; + + switch (inst & 0x1c00) + { + case 0x0000: case 0x1000: case 0x1400: case 0x1800: + util::stream_format(stream, "$%02x", inst & 0x00ff); + break; + + case 0x0400: + stream << "x"; + break; + + case 0x0800: + util::stream_format(stream, "y,$%02x", inst & 0x00ff); + break; + + case 0x0c00: + stream << "y,x"; + break; + + case 0x1c00: + stream << "y,x++"; + break; + } + + if ((inst & 0xe300) != 0xc100) + stream << "]"; + } + + // Non-accumulator destinations + if (BIT(inst, 12)) + { + if (!BIT(inst, 11)) + util::stream_format(stream, ",%c", "xy"[BIT(inst, 10)]); + else if (inst < 0xc000) + stream << ",out"; + } + } + + return 1 | flags | SUPPORTED; +} |