diff options
Diffstat (limited to 'src/devices/cpu/capricorn/capricorn_dasm.cpp')
-rw-r--r-- | src/devices/cpu/capricorn/capricorn_dasm.cpp | 237 |
1 files changed, 115 insertions, 122 deletions
diff --git a/src/devices/cpu/capricorn/capricorn_dasm.cpp b/src/devices/cpu/capricorn/capricorn_dasm.cpp index 5a45cb2c832..1b1794a954f 100644 --- a/src/devices/cpu/capricorn/capricorn_dasm.cpp +++ b/src/devices/cpu/capricorn/capricorn_dasm.cpp @@ -5,204 +5,197 @@ // ******************************************************************************** #include "emu.h" -#include "capricorn.h" +#include "capricorn_dasm.h" -typedef offs_t (*fn_dis_param)(std::ostream &stream , offs_t pc , const uint8_t *oprom); - -typedef struct { - uint8_t m_op_mask; - uint8_t m_opcode; - const char *m_mnemonic; - bool m_has_mb; - char m_addr_mode; - fn_dis_param m_param_fn; - uint32_t m_dasm_flags; -} dis_entry_t; - -static void direct_addr(std::ostream &stream , const uint8_t *oprom) +void capricorn_disassembler::direct_addr(std::ostream &stream, offs_t pc, const data_buffer &opcodes) { - util::stream_format(stream , "$%02x%02x" , oprom[ 1 ] , oprom[ 0 ]); + util::stream_format(stream, "$%04x", opcodes.r16(pc)); } -static offs_t param_arp_drp(std::ostream &stream , offs_t pc , const uint8_t *oprom) +offs_t capricorn_disassembler::param_arp_drp(std::ostream &stream, offs_t pc, const data_buffer &opcodes) { stream << "R"; - util::stream_format(stream , "%02o" , oprom[ 0 ] & 0x3f); + util::stream_format(stream, "%02o", opcodes.r8(pc) & 0x3f); return 0; } -static offs_t param_dr(std::ostream &stream , offs_t pc , const uint8_t *oprom) +offs_t capricorn_disassembler::param_dr(std::ostream &stream, offs_t pc, const data_buffer &opcodes) { stream << "DR"; return 0; } -static offs_t param_dr_ar(std::ostream &stream , offs_t pc , const uint8_t *oprom) +offs_t capricorn_disassembler::param_dr_ar(std::ostream &stream, offs_t pc, const data_buffer &opcodes) { stream << "DR,AR"; return 0; } -static offs_t param_dr_lit(std::ostream &stream , offs_t pc , const uint8_t *oprom) +offs_t capricorn_disassembler::param_dr_lit(std::ostream &stream, offs_t pc, const data_buffer &opcodes) { stream << "DR,="; // Here we assume that multi-byte instructions operate on 2 bytes because we // have no way of knowing how many they are (the actual number of bytes is // dynamically determined by the value of DRP register at run-time) - unsigned bytes = BIT(oprom[ 0 ] , 0) ? 2 : 1; + unsigned bytes = BIT(opcodes.r8(pc), 0) ? 2 : 1; for (unsigned i = 1; i <= bytes; i++) { - util::stream_format(stream , "$%02x " , oprom[ i ]); + util::stream_format(stream, "$%02x ", opcodes.r8(pc+i)); } return bytes; } -static offs_t param_dr_lit_dir(std::ostream &stream , offs_t pc ,const uint8_t *oprom) +offs_t capricorn_disassembler::param_dr_lit_dir(std::ostream &stream, offs_t pc,const data_buffer &opcodes) { stream << "DR,="; - direct_addr(stream , &oprom[ 1 ]); + direct_addr(stream, pc+1, opcodes); return 2; } -static offs_t param_dr_idx_dir(std::ostream &stream , offs_t pc ,const uint8_t *oprom) +offs_t capricorn_disassembler::param_dr_idx_dir(std::ostream &stream, offs_t pc,const data_buffer &opcodes) { stream << "DR,XAR,"; - direct_addr(stream , &oprom[ 1 ]); + direct_addr(stream, pc+1, opcodes); return 2; } -static offs_t param_xr_lit(std::ostream &stream , offs_t pc ,const uint8_t *oprom) +offs_t capricorn_disassembler::param_xr_lit(std::ostream &stream, offs_t pc,const data_buffer &opcodes) { stream << "XR,"; - direct_addr(stream , &oprom[ 1 ]); + direct_addr(stream, pc+1, opcodes); return 2; } -static offs_t param_lit_dir(std::ostream &stream , offs_t pc ,const uint8_t *oprom) +offs_t capricorn_disassembler::param_lit_dir(std::ostream &stream, offs_t pc,const data_buffer &opcodes) { stream << "="; - direct_addr(stream , &oprom[ 1 ]); + direct_addr(stream, pc+1, opcodes); return 2; } -static offs_t param_dr_id_ar(std::ostream &stream , offs_t pc , const uint8_t *oprom) +offs_t capricorn_disassembler::param_dr_id_ar(std::ostream &stream, offs_t pc, const data_buffer &opcodes) { - stream << "DR," << (BIT(oprom[ 0 ] , 1) ? '-' : '+') << "AR"; + stream << "DR," << (BIT(opcodes.r8(pc), 1) ? '-' : '+') << "AR"; return 0; } -static offs_t param_jmp_off(std::ostream &stream , offs_t pc , const uint8_t *oprom) +offs_t capricorn_disassembler::param_jmp_off(std::ostream &stream, offs_t pc, const data_buffer &opcodes) { - uint16_t off = oprom[ 1 ]; - if (BIT(off , 7)) { + uint16_t off = opcodes.r8(pc+1); + if (BIT(off, 7)) { off -= 0x100; } - util::stream_format(stream , "$%04x" , (pc + 2 + off) & 0xffff); + util::stream_format(stream, "$%04x", (pc + 2 + off) & 0xffff); return 1; } -static const dis_entry_t dis_table[] = { - { 0xff , 0x01 , "ARP R*" , false , '\0' , nullptr , 0 }, - { 0xc0 , 0x00 , "ARP" , false , '\0' , param_arp_drp , 0 }, - { 0xff , 0x41 , "DRP R*" , false , '\0' , nullptr , 0 }, - { 0xc0 , 0x40 , "DRP" , false , '\0' , param_arp_drp , 0 }, - { 0xfe , 0x80 , "EL" , true , '\0' , param_dr , 0 }, - { 0xfe , 0x82 , "ER" , true , '\0' , param_dr , 0 }, - { 0xfe , 0x84 , "LL" , true , '\0' , param_dr , 0 }, - { 0xfe , 0x86 , "LR" , true , '\0' , param_dr , 0 }, - { 0xfe , 0x88 , "IC" , true , '\0' , param_dr , 0 }, - { 0xfe , 0x8a , "DC" , true , '\0' , param_dr , 0 }, - { 0xfe , 0x8c , "TC" , true , '\0' , param_dr , 0 }, - { 0xfe , 0x8e , "NC" , true , '\0' , param_dr , 0 }, - { 0xfe , 0x90 , "TS" , true , '\0' , param_dr , 0 }, - { 0xfe , 0x92 , "CL" , true , '\0' , param_dr , 0 }, - { 0xfe , 0x94 , "OR" , true , '\0' , param_dr_ar , 0 }, - { 0xfe , 0x96 , "XR" , true , '\0' , param_dr_ar , 0 }, - { 0xff , 0x98 , "BIN" , false , '\0' , nullptr , 0 }, - { 0xff , 0x99 , "BCD" , false , '\0' , nullptr , 0 }, - { 0xff , 0x9a , "SAD" , false , '\0' , nullptr , 0 }, - { 0xff , 0x9b , "DCE" , false , '\0' , nullptr , 0 }, - { 0xff , 0x9c , "ICE" , false , '\0' , nullptr , 0 }, - { 0xff , 0x9d , "CLE" , false , '\0' , nullptr , 0 }, - { 0xff , 0x9e , "RTN" , false , '\0' , nullptr , DASMFLAG_STEP_OUT }, - { 0xff , 0x9f , "PAD" , false , '\0' , nullptr , 0 }, - { 0xfe , 0xa0 , "LD" , true , '\0' , param_dr_ar , 0 }, - { 0xfe , 0xa2 , "ST" , true , '\0' , param_dr_ar , 0 }, - { 0xfe , 0xa4 , "LD" , true , 'D' , param_dr_ar , 0 }, - { 0xfe , 0xa6 , "ST" , true , 'D' , param_dr_ar , 0 }, - { 0xfe , 0xa8 , "LD" , true , '\0' , param_dr_lit , 0 }, - { 0xfe , 0xaa , "ST" , true , '\0' , param_dr_lit , 0 }, - { 0xfe , 0xac , "LD" , true , 'I' , param_dr_ar , 0 }, - { 0xfe , 0xae , "ST" , true , 'I' , param_dr_ar , 0 }, - { 0xfe , 0xb0 , "LD" , true , 'D' , param_dr_lit_dir , 0 }, - { 0xfe , 0xb2 , "ST" , true , 'D' , param_dr_lit_dir , 0 }, - { 0xfe , 0xb4 , "LD" , true , 'D' , param_dr_idx_dir , 0 }, - { 0xfe , 0xb6 , "ST" , true , 'D' , param_dr_idx_dir , 0 }, - { 0xfe , 0xb8 , "LD" , true , 'I' , param_dr_lit_dir , 0 }, - { 0xfe , 0xba , "ST" , true , 'I' , param_dr_lit_dir , 0 }, - { 0xfe , 0xbc , "LD" , true , 'I' , param_dr_idx_dir , 0 }, - { 0xfe , 0xbe , "ST" , true , 'I' , param_dr_idx_dir , 0 }, - { 0xfe , 0xc0 , "CM" , true , '\0' , param_dr_ar , 0 }, - { 0xfe , 0xc2 , "AD" , true , '\0' , param_dr_ar , 0 }, - { 0xfe , 0xc4 , "SB" , true , '\0' , param_dr_ar , 0 }, - { 0xff , 0xc6 , "JSB" , false , '\0' , param_xr_lit , DASMFLAG_STEP_OVER }, - { 0xff , 0xc7 , "ANM" , false , '\0' , param_dr_ar , 0 }, - { 0xfe , 0xc8 , "CM" , true , '\0' , param_dr_lit , 0 }, - { 0xfe , 0xca , "AD" , true , '\0' , param_dr_lit , 0 }, - { 0xfe , 0xcc , "SB" , true , '\0' , param_dr_lit , 0 }, - { 0xff , 0xce , "JSB" , false , '\0' , param_lit_dir , DASMFLAG_STEP_OVER }, - { 0xff , 0xcf , "ANM" , false , '\0' , param_dr_lit , 0 }, - { 0xfe , 0xd0 , "CM" , true , 'D' , param_dr_lit_dir , 0 }, - { 0xfe , 0xd2 , "AD" , true , 'D' , param_dr_lit_dir , 0 }, - { 0xfe , 0xd4 , "SB" , true , 'D' , param_dr_lit_dir , 0 }, - { 0xff , 0xd7 , "ANM" , false , 'D' , param_dr_lit_dir , 0 }, - { 0xfe , 0xd8 , "CM" , true , 'D' , param_dr_ar , 0 }, - { 0xfe , 0xda , "AD" , true , 'D' , param_dr_ar , 0 }, - { 0xfe , 0xdc , "SB" , true , 'D' , param_dr_ar , 0 }, - { 0xff , 0xdf , "ANM" , false , 'D' , param_dr_ar , 0 }, - { 0xfc , 0xe0 , "PO" , true , 'D' , param_dr_id_ar , 0 }, - { 0xfc , 0xe4 , "PU" , true , 'D' , param_dr_id_ar , 0 }, - { 0xfc , 0xe8 , "PO" , true , 'I' , param_dr_id_ar , 0 }, - { 0xfc , 0xec , "PU" , true , 'I' , param_dr_id_ar , 0 }, - { 0xff , 0xf0 , "JMP" , false , '\0' , param_jmp_off , 0 }, - { 0xff , 0xf1 , "JNO" , false , '\0' , param_jmp_off , 0 }, - { 0xff , 0xf2 , "JOD" , false , '\0' , param_jmp_off , 0 }, - { 0xff , 0xf3 , "JEV" , false , '\0' , param_jmp_off , 0 }, - { 0xff , 0xf4 , "JNG" , false , '\0' , param_jmp_off , 0 }, - { 0xff , 0xf5 , "JPS" , false , '\0' , param_jmp_off , 0 }, - { 0xff , 0xf6 , "JNZ" , false , '\0' , param_jmp_off , 0 }, - { 0xff , 0xf7 , "JZR" , false , '\0' , param_jmp_off , 0 }, - { 0xff , 0xf8 , "JEN" , false , '\0' , param_jmp_off , 0 }, - { 0xff , 0xf9 , "JEZ" , false , '\0' , param_jmp_off , 0 }, - { 0xff , 0xfa , "JNC" , false , '\0' , param_jmp_off , 0 }, - { 0xff , 0xfb , "JCY" , false , '\0' , param_jmp_off , 0 }, - { 0xff , 0xfc , "JLZ" , false , '\0' , param_jmp_off , 0 }, - { 0xff , 0xfd , "JLN" , false , '\0' , param_jmp_off , 0 }, - { 0xff , 0xfe , "JRZ" , false , '\0' , param_jmp_off , 0 }, - { 0xff , 0xff , "JRN" , false , '\0' , param_jmp_off , 0 }, +const capricorn_disassembler::dis_entry_t capricorn_disassembler::dis_table[] = { + { 0xff, 0x01, "ARP R*", false, '\0', nullptr, 0 }, + { 0xc0, 0x00, "ARP" , false, '\0', &capricorn_disassembler::param_arp_drp, 0 }, + { 0xff, 0x41, "DRP R*", false, '\0', nullptr, 0 }, + { 0xc0, 0x40, "DRP" , false, '\0', &capricorn_disassembler::param_arp_drp, 0 }, + { 0xfe, 0x80, "EL" , true , '\0', &capricorn_disassembler::param_dr, 0 }, + { 0xfe, 0x82, "ER" , true , '\0', &capricorn_disassembler::param_dr, 0 }, + { 0xfe, 0x84, "LL" , true , '\0', &capricorn_disassembler::param_dr, 0 }, + { 0xfe, 0x86, "LR" , true , '\0', &capricorn_disassembler::param_dr, 0 }, + { 0xfe, 0x88, "IC" , true , '\0', &capricorn_disassembler::param_dr, 0 }, + { 0xfe, 0x8a, "DC" , true , '\0', &capricorn_disassembler::param_dr, 0 }, + { 0xfe, 0x8c, "TC" , true , '\0', &capricorn_disassembler::param_dr, 0 }, + { 0xfe, 0x8e, "NC" , true , '\0', &capricorn_disassembler::param_dr, 0 }, + { 0xfe, 0x90, "TS" , true , '\0', &capricorn_disassembler::param_dr, 0 }, + { 0xfe, 0x92, "CL" , true , '\0', &capricorn_disassembler::param_dr, 0 }, + { 0xfe, 0x94, "OR" , true , '\0', &capricorn_disassembler::param_dr_ar, 0 }, + { 0xfe, 0x96, "XR" , true , '\0', &capricorn_disassembler::param_dr_ar, 0 }, + { 0xff, 0x98, "BIN" , false, '\0', nullptr, 0 }, + { 0xff, 0x99, "BCD" , false, '\0', nullptr, 0 }, + { 0xff, 0x9a, "SAD" , false, '\0', nullptr, 0 }, + { 0xff, 0x9b, "DCE" , false, '\0', nullptr, 0 }, + { 0xff, 0x9c, "ICE" , false, '\0', nullptr, 0 }, + { 0xff, 0x9d, "CLE" , false, '\0', nullptr, 0 }, + { 0xff, 0x9e, "RTN" , false, '\0', nullptr, STEP_OUT }, + { 0xff, 0x9f, "PAD" , false, '\0', nullptr, 0 }, + { 0xfe, 0xa0, "LD" , true , '\0', &capricorn_disassembler::param_dr_ar, 0 }, + { 0xfe, 0xa2, "ST" , true , '\0', &capricorn_disassembler::param_dr_ar, 0 }, + { 0xfe, 0xa4, "LD" , true , 'D' , &capricorn_disassembler::param_dr_ar, 0 }, + { 0xfe, 0xa6, "ST" , true , 'D' , &capricorn_disassembler::param_dr_ar, 0 }, + { 0xfe, 0xa8, "LD" , true , '\0', &capricorn_disassembler::param_dr_lit, 0 }, + { 0xfe, 0xaa, "ST" , true , '\0', &capricorn_disassembler::param_dr_lit, 0 }, + { 0xfe, 0xac, "LD" , true , 'I' , &capricorn_disassembler::param_dr_ar, 0 }, + { 0xfe, 0xae, "ST" , true , 'I' , &capricorn_disassembler::param_dr_ar, 0 }, + { 0xfe, 0xb0, "LD" , true , 'D' , &capricorn_disassembler::param_dr_lit_dir, 0 }, + { 0xfe, 0xb2, "ST" , true , 'D' , &capricorn_disassembler::param_dr_lit_dir, 0 }, + { 0xfe, 0xb4, "LD" , true , 'D' , &capricorn_disassembler::param_dr_idx_dir, 0 }, + { 0xfe, 0xb6, "ST" , true , 'D' , &capricorn_disassembler::param_dr_idx_dir, 0 }, + { 0xfe, 0xb8, "LD" , true , 'I' , &capricorn_disassembler::param_dr_lit_dir, 0 }, + { 0xfe, 0xba, "ST" , true , 'I' , &capricorn_disassembler::param_dr_lit_dir, 0 }, + { 0xfe, 0xbc, "LD" , true , 'I' , &capricorn_disassembler::param_dr_idx_dir, 0 }, + { 0xfe, 0xbe, "ST" , true , 'I' , &capricorn_disassembler::param_dr_idx_dir, 0 }, + { 0xfe, 0xc0, "CM" , true , '\0', &capricorn_disassembler::param_dr_ar, 0 }, + { 0xfe, 0xc2, "AD" , true , '\0', &capricorn_disassembler::param_dr_ar, 0 }, + { 0xfe, 0xc4, "SB" , true , '\0', &capricorn_disassembler::param_dr_ar, 0 }, + { 0xff, 0xc6, "JSB" , false, '\0', &capricorn_disassembler::param_xr_lit, STEP_OVER }, + { 0xff, 0xc7, "ANM" , false, '\0', &capricorn_disassembler::param_dr_ar, 0 }, + { 0xfe, 0xc8, "CM" , true , '\0', &capricorn_disassembler::param_dr_lit, 0 }, + { 0xfe, 0xca, "AD" , true , '\0', &capricorn_disassembler::param_dr_lit, 0 }, + { 0xfe, 0xcc, "SB" , true , '\0', &capricorn_disassembler::param_dr_lit, 0 }, + { 0xff, 0xce, "JSB" , false, '\0', &capricorn_disassembler::param_lit_dir, STEP_OVER }, + { 0xff, 0xcf, "ANM" , false, '\0', &capricorn_disassembler::param_dr_lit, 0 }, + { 0xfe, 0xd0, "CM" , true , 'D' , &capricorn_disassembler::param_dr_lit_dir, 0 }, + { 0xfe, 0xd2, "AD" , true , 'D' , &capricorn_disassembler::param_dr_lit_dir, 0 }, + { 0xfe, 0xd4, "SB" , true , 'D' , &capricorn_disassembler::param_dr_lit_dir, 0 }, + { 0xff, 0xd7, "ANM" , false, 'D' , &capricorn_disassembler::param_dr_lit_dir, 0 }, + { 0xfe, 0xd8, "CM" , true , 'D' , &capricorn_disassembler::param_dr_ar, 0 }, + { 0xfe, 0xda, "AD" , true , 'D' , &capricorn_disassembler::param_dr_ar, 0 }, + { 0xfe, 0xdc, "SB" , true , 'D' , &capricorn_disassembler::param_dr_ar, 0 }, + { 0xff, 0xdf, "ANM" , false, 'D' , &capricorn_disassembler::param_dr_ar, 0 }, + { 0xfc, 0xe0, "PO" , true , 'D' , &capricorn_disassembler::param_dr_id_ar, 0 }, + { 0xfc, 0xe4, "PU" , true , 'D' , &capricorn_disassembler::param_dr_id_ar, 0 }, + { 0xfc, 0xe8, "PO" , true , 'I' , &capricorn_disassembler::param_dr_id_ar, 0 }, + { 0xfc, 0xec, "PU" , true , 'I' , &capricorn_disassembler::param_dr_id_ar, 0 }, + { 0xff, 0xf0, "JMP" , false, '\0', &capricorn_disassembler::param_jmp_off, 0 }, + { 0xff, 0xf1, "JNO" , false, '\0', &capricorn_disassembler::param_jmp_off, 0 }, + { 0xff, 0xf2, "JOD" , false, '\0', &capricorn_disassembler::param_jmp_off, 0 }, + { 0xff, 0xf3, "JEV" , false, '\0', &capricorn_disassembler::param_jmp_off, 0 }, + { 0xff, 0xf4, "JNG" , false, '\0', &capricorn_disassembler::param_jmp_off, 0 }, + { 0xff, 0xf5, "JPS" , false, '\0', &capricorn_disassembler::param_jmp_off, 0 }, + { 0xff, 0xf6, "JNZ" , false, '\0', &capricorn_disassembler::param_jmp_off, 0 }, + { 0xff, 0xf7, "JZR" , false, '\0', &capricorn_disassembler::param_jmp_off, 0 }, + { 0xff, 0xf8, "JEN" , false, '\0', &capricorn_disassembler::param_jmp_off, 0 }, + { 0xff, 0xf9, "JEZ" , false, '\0', &capricorn_disassembler::param_jmp_off, 0 }, + { 0xff, 0xfa, "JNC" , false, '\0', &capricorn_disassembler::param_jmp_off, 0 }, + { 0xff, 0xfb, "JCY" , false, '\0', &capricorn_disassembler::param_jmp_off, 0 }, + { 0xff, 0xfc, "JLZ" , false, '\0', &capricorn_disassembler::param_jmp_off, 0 }, + { 0xff, 0xfd, "JLN" , false, '\0', &capricorn_disassembler::param_jmp_off, 0 }, + { 0xff, 0xfe, "JRZ" , false, '\0', &capricorn_disassembler::param_jmp_off, 0 }, + { 0xff, 0xff, "JRN" , false, '\0', &capricorn_disassembler::param_jmp_off, 0 }, // *** END *** - {0 , 0 , nullptr , false , 0 , nullptr , 0 } + {0, 0, nullptr, false, 0, nullptr, 0 } }; -CPU_DISASSEMBLE(capricorn) +u32 capricorn_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t capricorn_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { const dis_entry_t *p; - uint8_t opcode = oprom[ 0 ]; + uint8_t opcode = opcodes.r8(pc); for (p = dis_table; p->m_op_mask; p++) { if ((opcode & p->m_op_mask) == p->m_opcode) { - offs_t res = 1 | p->m_dasm_flags | DASMFLAG_SUPPORTED; + offs_t res = 1 | p->m_dasm_flags | SUPPORTED; stream << p->m_mnemonic; if (p->m_has_mb) { - stream << (BIT(opcode , 0) ? 'M' : 'B'); + stream << (BIT(opcode, 0) ? 'M' : 'B'); } if (p->m_addr_mode != '\0') { stream << p->m_addr_mode; } if (p->m_param_fn != nullptr) { stream << " "; - res += p->m_param_fn(stream , pc , oprom); + res += (this->*(p->m_param_fn))(stream, pc, opcodes); } return res; } @@ -210,5 +203,5 @@ CPU_DISASSEMBLE(capricorn) // Unknown opcode stream << "???"; - return 1 | DASMFLAG_SUPPORTED; + return 1 | SUPPORTED; } |