diff options
Diffstat (limited to 'src/devices/cpu')
654 files changed, 50278 insertions, 43567 deletions
diff --git a/src/devices/cpu/8x300/8x300.cpp b/src/devices/cpu/8x300/8x300.cpp index 44bb9b34fe6..575b3f2d0d0 100644 --- a/src/devices/cpu/8x300/8x300.cpp +++ b/src/devices/cpu/8x300/8x300.cpp @@ -11,6 +11,7 @@ #include "emu.h" #include "8x300.h" +#include "8x300dasm.h" #include "debugger.h" #define FETCHOP(a) (m_direct->read_word(a)) @@ -96,7 +97,7 @@ uint8_t n8x300_cpu_device::get_reg(uint8_t reg) void n8x300_cpu_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); save_item(NAME(m_PC)); @@ -590,8 +591,7 @@ void n8x300_cpu_device::execute_run() } while (m_icount > 0); } -offs_t n8x300_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *n8x300_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( n8x300 ); - return CPU_DISASSEMBLE_NAME(n8x300)(this, stream, pc, oprom, opram, options); + return new n8x300_disassembler; } diff --git a/src/devices/cpu/8x300/8x300.h b/src/devices/cpu/8x300/8x300.h index 5bba395cca6..7a36dc941a6 100644 --- a/src/devices/cpu/8x300/8x300.h +++ b/src/devices/cpu/8x300/8x300.h @@ -63,9 +63,7 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 2; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; address_space_config m_program_config; address_space_config m_io_config; @@ -74,7 +72,7 @@ protected: bool m_increment_pc; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_io; uint16_t m_PC; // Program Counter diff --git a/src/devices/cpu/8x300/8x300dasm.cpp b/src/devices/cpu/8x300/8x300dasm.cpp index a6375072a49..db231195f04 100644 --- a/src/devices/cpu/8x300/8x300dasm.cpp +++ b/src/devices/cpu/8x300/8x300dasm.cpp @@ -8,7 +8,7 @@ */ #include "emu.h" -#include "8x300.h" +#include "8x300dasm.h" #define SRC ((opcode & 0x1f00) >> 8) #define DST (opcode & 0x001f) @@ -16,7 +16,7 @@ #define IMM8 (opcode & 0x00ff) #define IMM5 (opcode & 0x001f) -static const char *reg_names[32] = +const char *const n8x300_disassembler::reg_names[32] = { "AUX", "R1", "R2", "R3", "R4", "R5", "R6", "IVL", "OVF", "R11", "Unused12", "Unused13", "Unused14", "Unused15", "Unused16", "IVR", @@ -25,7 +25,7 @@ static const char *reg_names[32] = }; // determines if right rotate or I/O field length is to be used -static inline bool is_rot(uint16_t opcode) +bool n8x300_disassembler::is_rot(uint16_t opcode) { if((opcode & 0x1000) || (opcode & 0x0010)) return false; @@ -33,7 +33,7 @@ static inline bool is_rot(uint16_t opcode) return true; } -static inline bool is_src_rot(uint16_t opcode) +bool n8x300_disassembler::is_src_rot(uint16_t opcode) { if((opcode & 0x1000)) return false; @@ -41,10 +41,15 @@ static inline bool is_src_rot(uint16_t opcode) return true; } -CPU_DISASSEMBLE(n8x300) +u32 n8x300_disassembler::opcode_alignment() const +{ + return 2; +} + +offs_t n8x300_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { unsigned startpc = pc; - uint16_t opcode = (oprom[pc - startpc] << 8) | oprom[pc+1 - startpc]; + uint16_t opcode = opcodes.r16(pc); uint8_t inst = opcode >> 13; pc+=2; diff --git a/src/devices/cpu/8x300/8x300dasm.h b/src/devices/cpu/8x300/8x300dasm.h new file mode 100644 index 00000000000..f5fe389c614 --- /dev/null +++ b/src/devices/cpu/8x300/8x300dasm.h @@ -0,0 +1,31 @@ +// license:BSD-3-Clause +// copyright-holders:Barry Rodewald +/* + * 8x300dasm.c + * Implementation of the Scientific Micro Systems SMS300 / Signetics 8X300 Microcontroller + * + * Created on: 18/12/2013 + */ + +#ifndef MAME_CPU_8X300_8X300DASM_H +#define MAME_CPU_8X300_8X300DASM_H + +#pragma once + +class n8x300_disassembler : public util::disasm_interface +{ +public: + n8x300_disassembler() = default; + virtual ~n8x300_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *const reg_names[32]; + + bool is_rot(uint16_t opcode); + bool is_src_rot(uint16_t opcode); +}; + +#endif diff --git a/src/devices/cpu/adsp2100/2100dasm.cpp b/src/devices/cpu/adsp2100/2100dasm.cpp index a126cfa0bcb..b3efa6ac6ec 100644 --- a/src/devices/cpu/adsp2100/2100dasm.cpp +++ b/src/devices/cpu/adsp2100/2100dasm.cpp @@ -1,32 +1,32 @@ // license:BSD-3-Clause // copyright-holders:Aaron Giles #include "emu.h" -#include "adsp2100.h" +#include "2100dasm.h" -static const char *const flag_change[] = { "", "TOGGLE %s ", "RESET %s ", "SET %s " }; -static const char *const mode_change[] = { "", "", "DIS %s ", "ENA %s " }; +const char *const adsp21xx_disassembler::flag_change[] = { "", "TOGGLE %s ", "RESET %s ", "SET %s " }; +const char *const adsp21xx_disassembler::mode_change[] = { "", "", "DIS %s ", "ENA %s " }; -static const char *const alu_xop[] = { "AX0", "AX1", "AR", "MR0", "MR1", "MR2", "SR0", "SR1" }; -static const char *const alu_yop[] = { "AY0", "AY1", "AF", "0" }; -static const char *const alu_dst[] = { "AR", "AF", "NONE" }; +const char *const adsp21xx_disassembler::alu_xop[] = { "AX0", "AX1", "AR", "MR0", "MR1", "MR2", "SR0", "SR1" }; +const char *const adsp21xx_disassembler::alu_yop[] = { "AY0", "AY1", "AF", "0" }; +const char *const adsp21xx_disassembler::alu_dst[] = { "AR", "AF", "NONE" }; -static const char *const mac_xop[] = { "MX0", "MX1", "AR", "MR0", "MR1", "MR2", "SR0", "SR1" }; -static const char *const mac_yop[] = { "MY0", "MY1", "MF", "0" }; -static const char *const mac_dst[] = { "MR", "MF", "NONE" }; +const char *const adsp21xx_disassembler::mac_xop[] = { "MX0", "MX1", "AR", "MR0", "MR1", "MR2", "SR0", "SR1" }; +const char *const adsp21xx_disassembler::mac_yop[] = { "MY0", "MY1", "MF", "0" }; +const char *const adsp21xx_disassembler::mac_dst[] = { "MR", "MF", "NONE" }; -static const char *const shift_xop[] = { "SI", "??", "AR", "MR0", "MR1", "MR2", "SR0", "SR1" }; +const char *const adsp21xx_disassembler::shift_xop[] = { "SI", "??", "AR", "MR0", "MR1", "MR2", "SR0", "SR1" }; -static const char *const reg_grp[][16] = +const char *const adsp21xx_disassembler::reg_grp[][16] = { { "AX0", "AX1", "MX0", "MX1", "AY0", "AY1", "MY0", "MY1", "SI", "SE", "AR", "MR0", "MR1", "MR2", "SR0", "SR1" }, { "I0", "I1", "I2", "I3", "M0", "M1", "M2", "M3", "L0", "L1", "L2", "L3", "??", "??", "PMOVLAY", "DMOVLAY" }, { "I4", "I5", "I6", "I7", "M4", "M5", "M6", "M7", "L4", "L5", "L6", "L7", "??", "??", "??", "??" }, { "ASTAT", "MSTAT", "SSTAT", "IMASK", "ICNTL", "CNTR", "SB", "PX", "RX0", "TX0", "RX1", "TX1", "IFC", "OWRCNTR", "??", "??" } }; -static const char *const dual_xreg[] = { "AX0", "AX1", "MX0", "MX1" }; -static const char *const dual_yreg[] = { "AY0", "AY1", "MY0", "MY1" }; +const char *const adsp21xx_disassembler::dual_xreg[] = { "AX0", "AX1", "MX0", "MX1" }; +const char *const adsp21xx_disassembler::dual_yreg[] = { "AY0", "AY1", "MY0", "MY1" }; -static const char *const condition[] = +const char *const adsp21xx_disassembler::condition[] = { "IF EQ ", "IF NE ", @@ -46,7 +46,7 @@ static const char *const condition[] = "" }; -static const char *const do_condition[] = +const char *const adsp21xx_disassembler::do_condition[] = { "NE", "EQ", @@ -66,7 +66,7 @@ static const char *const do_condition[] = "FOREVER" }; -static const char *const alumac_op[][2] = +const char *const adsp21xx_disassembler::alumac_op[][2] = { { "", "" }, { "%s = %s * %s (RND)", "%s = %s * %s (RND)" }, @@ -103,7 +103,7 @@ static const char *const alumac_op[][2] = { "%s = ABS %s", "%s = ABS %s" } }; -static const char *const shift_op[] = +const char *const adsp21xx_disassembler::shift_op[] = { "SR = LSHIFT %s (HI)", "SR = SR OR LSHIFT %s (HI)", @@ -123,7 +123,7 @@ static const char *const shift_op[] = "SB = EXPADJ %s", }; -static const char *const shift_by_op[] = +const char *const adsp21xx_disassembler::shift_by_op[] = { "SR = LSHIFT %s BY %d (HI)", "SR = SR OR LSHIFT %s BY %d (HI)", @@ -143,7 +143,7 @@ static const char *const shift_by_op[] = "???" }; -static const char *const constants[] = +const char *const adsp21xx_disassembler::constants[] = { "$0001", "$FFFE", @@ -180,9 +180,7 @@ static const char *const constants[] = }; - - -static void alumac(std::ostream &stream, int dest, int op) +void adsp21xx_disassembler::alumac(std::ostream &stream, int dest, int op) { int opindex = (op >> 13) & 31; const char *xop, *yop, *dst, *opstring; @@ -207,7 +205,7 @@ static void alumac(std::ostream &stream, int dest, int op) } -static void aluconst(std::ostream &stream, int dest, int op) +void adsp21xx_disassembler::aluconst(std::ostream &stream, int dest, int op) { int opindex = (op >> 13) & 31; const char *xop, *dst, *cval, *opstring; @@ -232,10 +230,9 @@ static void aluconst(std::ostream &stream, int dest, int op) } -/* execute instructions on this CPU until icount expires */ -CPU_DISASSEMBLE(adsp21xx) +offs_t adsp21xx_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - unsigned int op = oprom[0] | (oprom[1] << 8) | (oprom[2] << 16); + unsigned int op = opcodes.r32(pc); unsigned dasmflags = 0; int temp; @@ -281,7 +278,7 @@ CPU_DISASSEMBLE(adsp21xx) if (op & 1) { util::stream_format(stream, "%s", "CALL "); - dasmflags = DASMFLAG_STEP_OVER; + dasmflags = STEP_OVER; } else util::stream_format(stream, "%s", "JUMP "); @@ -295,7 +292,7 @@ CPU_DISASSEMBLE(adsp21xx) if (op & 0x000010) { util::stream_format(stream, "%s", "POP PC "); - dasmflags = DASMFLAG_STEP_OUT; + dasmflags = STEP_OUT; } if (op & 0x000008) util::stream_format(stream, "%s", "POP LOOP "); if (op & 0x000004) util::stream_format(stream, "%s", "POP CNTR "); @@ -349,7 +346,7 @@ CPU_DISASSEMBLE(adsp21xx) util::stream_format(stream, "%s", "RTI"); else util::stream_format(stream, "%s", "RTS"); - dasmflags = DASMFLAG_STEP_OUT; + dasmflags = STEP_OUT; } else util::stream_format(stream, "??? (%06X)", op); @@ -362,7 +359,7 @@ CPU_DISASSEMBLE(adsp21xx) if (op & 0x000010) { util::stream_format(stream, "CALL (I%d)", 4 + ((op >> 6) & 3)); - dasmflags = DASMFLAG_STEP_OVER; + dasmflags = STEP_OVER; } else util::stream_format(stream, "JUMP (I%d)", 4 + ((op >> 6) & 3)); @@ -440,7 +437,7 @@ CPU_DISASSEMBLE(adsp21xx) if (op & 0x040000) { util::stream_format(stream, "%sCALL $%04X", condition[op & 15], (op >> 4) & 0x3fff); - dasmflags = DASMFLAG_STEP_OVER; + dasmflags = STEP_OVER; } else util::stream_format(stream, "%sJUMP $%04X", condition[op & 15], (op >> 4) & 0x3fff); @@ -549,5 +546,10 @@ CPU_DISASSEMBLE(adsp21xx) break; } - return 1 | dasmflags | DASMFLAG_SUPPORTED; + return 1 | dasmflags | SUPPORTED; +} + +uint32_t adsp21xx_disassembler::opcode_alignment() const +{ + return 1; } diff --git a/src/devices/cpu/adsp2100/2100dasm.h b/src/devices/cpu/adsp2100/2100dasm.h new file mode 100644 index 00000000000..1c80c47a554 --- /dev/null +++ b/src/devices/cpu/adsp2100/2100dasm.h @@ -0,0 +1,43 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles + +#ifndef MAME_CPU_ADSP2100_2100DASM_H +#define MAME_CPU_ADSP2100_2100DASM_H + +#pragma once + +class adsp21xx_disassembler : public util::disasm_interface +{ +public: + adsp21xx_disassembler() = default; + virtual ~adsp21xx_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *const flag_change[]; + static const char *const mode_change[]; + static const char *const alu_xop[]; + static const char *const alu_yop[]; + static const char *const alu_dst[]; + static const char *const mac_xop[]; + static const char *const mac_yop[]; + static const char *const mac_dst[]; + static const char *const shift_xop[];; + static const char *const reg_grp[][16]; + static const char *const dual_xreg[]; + static const char *const dual_yreg[]; + static const char *const condition[]; + static const char *const do_condition[]; + static const char *const alumac_op[][2]; + static const char *const shift_op[]; + static const char *const shift_by_op[]; + static const char *const constants[]; + + void alumac(std::ostream &stream, int dest, int op); + void aluconst(std::ostream &stream, int dest, int op); + +}; + +#endif diff --git a/src/devices/cpu/adsp2100/adsp2100.cpp b/src/devices/cpu/adsp2100/adsp2100.cpp index d0c10e06dce..7c9b6da7727 100644 --- a/src/devices/cpu/adsp2100/adsp2100.cpp +++ b/src/devices/cpu/adsp2100/adsp2100.cpp @@ -100,6 +100,7 @@ #include "emu.h" #include "debugger.h" #include "adsp2100.h" +#include "2100dasm.h" // device type definitions @@ -417,7 +418,7 @@ void adsp21xx_device::device_start() // get our address spaces m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<-2>(); m_data = &space(AS_DATA); m_io = has_space(AS_IO) ? &space(AS_IO) : nullptr; @@ -758,78 +759,54 @@ void adsp21xx_device::state_string_export(const device_state_entry &entry, std:: //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t adsp21xx_device::disasm_min_opcode_bytes() const -{ - return 4; -} - - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t adsp21xx_device::disasm_max_opcode_bytes() const -{ - return 4; -} - - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t adsp21xx_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *adsp21xx_device::create_disassembler() { - extern CPU_DISASSEMBLE( adsp21xx ); - return CPU_DISASSEMBLE_NAME(adsp21xx)(this, stream, pc, oprom, opram, options); + return new adsp21xx_disassembler; } - /*************************************************************************** MEMORY ACCESSORS ***************************************************************************/ inline uint16_t adsp21xx_device::data_read(uint32_t addr) { - return m_data->read_word(addr << 1); + return m_data->read_word(addr); } inline void adsp21xx_device::data_write(uint32_t addr, uint16_t data) { - m_data->write_word(addr << 1, data); + m_data->write_word(addr, data); } inline uint16_t adsp21xx_device::io_read(uint32_t addr) { - return m_io->read_word(addr << 1); + return m_io->read_word(addr); } inline void adsp21xx_device::io_write(uint32_t addr, uint16_t data) { - m_io->write_word(addr << 1, data); + m_io->write_word(addr, data); } inline uint32_t adsp21xx_device::program_read(uint32_t addr) { - return m_program->read_dword(addr << 2); + return m_program->read_dword(addr); } inline void adsp21xx_device::program_write(uint32_t addr, uint32_t data) { - m_program->write_dword(addr << 2, data & 0xffffff); + m_program->write_dword(addr, data & 0xffffff); } inline uint32_t adsp21xx_device::opcode_read() { - return m_direct->read_dword(m_pc << 2); + return m_direct->read_dword(m_pc); } diff --git a/src/devices/cpu/adsp2100/adsp2100.h b/src/devices/cpu/adsp2100/adsp2100.h index faaddcdcc10..4b2cbcd98a8 100644 --- a/src/devices/cpu/adsp2100/adsp2100.h +++ b/src/devices/cpu/adsp2100/adsp2100.h @@ -243,9 +243,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // helpers void create_tables(); @@ -452,7 +450,7 @@ protected: address_space * m_program; address_space * m_data; address_space * m_io; - direct_read_data * m_direct; + direct_read_data<-2> *m_direct; // tables uint8_t m_condition_table[0x1000]; diff --git a/src/devices/cpu/alph8201/8201dasm.cpp b/src/devices/cpu/alph8201/8201dasm.cpp index 8e5e99ffd37..a987d5ededd 100644 --- a/src/devices/cpu/alph8201/8201dasm.cpp +++ b/src/devices/cpu/alph8201/8201dasm.cpp @@ -20,11 +20,10 @@ cpu/alph8201/ will be removed when the alpha 8304 has been dumped. ****************************************************************************/ #include "emu.h" +#include "8201dasm.h" #include <ctype.h> -typedef unsigned char byte; - #define FMT(a,b) a, b #define PTRS_PER_FORMAT 2 @@ -171,7 +170,7 @@ Notes: /****************************************************/ -static const char *const Formats[] = { +const char *const alpha8201_disassembler::Formats[] = { FMT("0000_0000", "NOP"), // 00 FMT("0000_0001", "RRCA"), // 01 FMT("0000_0010", "RLCA"), // 02 @@ -270,24 +269,10 @@ static const char *const Formats[] = { nullptr }; -#define MAX_OPS ((ARRAY_LENGTH(Formats) - 1) / PTRS_PER_FORMAT) - -struct AD8201Opcode { - byte mask; - byte bits; - byte type; - byte pmask; - byte pdown; - const char *fmt; -}; - -static AD8201Opcode Op[MAX_OPS+1]; -static int OpInizialized = 0; - -static void InitDasm8201(void) +alpha8201_disassembler::alpha8201_disassembler() { const char *p; - byte mask, bits; + u8 mask, bits; int bit; int i; char chr , type; @@ -345,11 +330,10 @@ static void InitDasm8201(void) Op[i].type |= 0x02; /* double param */ } } - - OpInizialized = 1; + op_count = i; } -CPU_DISASSEMBLE(alpha8201) +offs_t alpha8201_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { offs_t dasmflags = 0; int i; @@ -357,11 +341,9 @@ CPU_DISASSEMBLE(alpha8201) int cnt = 1; int code , disp; - if (!OpInizialized) InitDasm8201(); - - code = oprom[0]; + code = opcodes.r8(pc); op = -1; /* no matching opcode */ - for ( i = 0; i < MAX_OPS; i++) + for ( i = 0; i < op_count; i++) { if( (code & Op[i].mask) == Op[i].bits ) { @@ -382,7 +364,7 @@ CPU_DISASSEMBLE(alpha8201) if (Op[op].type & 0x10) { - disp = opram[1]; + disp = params.r8(pc+1); cnt++; } else @@ -403,13 +385,18 @@ CPU_DISASSEMBLE(alpha8201) case 0xcd: case 0xce: case 0xdf: - dasmflags = DASMFLAG_STEP_OVER; + dasmflags = STEP_OVER; break; case 0xff: - dasmflags = DASMFLAG_STEP_OUT; + dasmflags = STEP_OUT; break; } - return cnt | dasmflags | DASMFLAG_SUPPORTED; + return cnt | dasmflags | SUPPORTED; +} + +u32 alpha8201_disassembler::opcode_alignment() const +{ + return 1; } diff --git a/src/devices/cpu/alph8201/8201dasm.h b/src/devices/cpu/alph8201/8201dasm.h new file mode 100644 index 00000000000..85676c5de10 --- /dev/null +++ b/src/devices/cpu/alph8201/8201dasm.h @@ -0,0 +1,51 @@ +// license:BSD-3-Clause +// copyright-holders:Tatsuyuki Satoh +/* + +Notice: The alpha 8201 is now emulated using mame/alpha8201.* + +cpu/alph8201/ will be removed when the alpha 8304 has been dumped. + + + + +*/ + +/**************************************************************************** + Alpha 8201/8301 Disassembler + + Copyright Tatsuyuki Satoh + Originally written for the MAME project. + +****************************************************************************/ + +#ifndef MAME_CPU_ALPH8201_8201DASM_H +#define MAME_CPU_ALPH8201_8201DASM_H + +#pragma once + +class alpha8201_disassembler : public util::disasm_interface +{ +public: + alpha8201_disassembler(); + virtual ~alpha8201_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + struct AD8201Opcode { + u8 mask; + u8 bits; + u8 type; + u8 pmask; + u8 pdown; + const char *fmt; + }; + + static const char *const Formats[]; + AD8201Opcode Op[256]; + int op_count; +}; + +#endif diff --git a/src/devices/cpu/alph8201/alph8201.cpp b/src/devices/cpu/alph8201/alph8201.cpp index 5dc141d7d82..8a422d3a450 100644 --- a/src/devices/cpu/alph8201/alph8201.cpp +++ b/src/devices/cpu/alph8201/alph8201.cpp @@ -163,7 +163,7 @@ Timming #include "emu.h" #include "alph8201.h" #include "debugger.h" - +#include "8201dasm.h" DEFINE_DEVICE_TYPE(ALPHA8201L, alpha8201_cpu_device, "alpha8201l", "ALPHA-8201L") DEFINE_DEVICE_TYPE(ALPHA8301L, alpha8301_cpu_device, "alpha8301l", "ALPHA-8301L") @@ -394,7 +394,7 @@ const alpha8201_cpu_device::s_opcode alpha8201_cpu_device::opcode_8301[256]= void alpha8201_cpu_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); state_add( ALPHA8201_PC, "PC", m_pc.w.l ).callimport().mask(0x3ff).formatstr("%03X"); state_add( ALPHA8201_SP, "SP", m_sp ).callimport().callexport().formatstr("%02X"); @@ -690,9 +690,7 @@ void alpha8201_cpu_device::execute_set_input(int inputnum, int state) } } - -offs_t alpha8201_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +util::disasm_interface *alpha8201_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( alpha8201 ); - return CPU_DISASSEMBLE_NAME(alpha8201)(this, stream, pc, oprom, opram, options); + return new alpha8201_disassembler; } diff --git a/src/devices/cpu/alph8201/alph8201.h b/src/devices/cpu/alph8201/alph8201.h index 93640f17301..5627bf23068 100644 --- a/src/devices/cpu/alph8201/alph8201.h +++ b/src/devices/cpu/alph8201/alph8201.h @@ -83,9 +83,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual u32 disasm_min_opcode_bytes() const override { return 1; } - virtual u32 disasm_max_opcode_bytes() const override { return 4; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; u8 M_RDMEM(u16 A) { return m_program->read_byte(A); } void M_WRMEM(u16 A, u8 V) { m_program->write_byte(A, V); } @@ -390,7 +388,7 @@ protected: u8 m_halt; /* halt input line */ address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; int m_icount; int m_inst_cycles; diff --git a/src/devices/cpu/alto2/a2ram.cpp b/src/devices/cpu/alto2/a2ram.cpp index 39996f98fa7..3aab054871d 100644 --- a/src/devices/cpu/alto2/a2ram.cpp +++ b/src/devices/cpu/alto2/a2ram.cpp @@ -99,7 +99,7 @@ void alto2_cpu_device::rdram() #if DEBUG_RDRAM char buffer[256]; uint8_t* oprom = m_ucode_cram.get() + 4 * wordaddr; - disasm_disassemble(buffer, wordaddr, oprom, oprom, 0); + disassemble(buffer, wordaddr, oprom, oprom, 0); printf("RD CRAM_BANKSEL=%d RAM%d [%04o] upper:%06o lower:%06o value:%011o '%s'\n", GET_CRAM_BANKSEL(m_cram_addr), bank, wordaddr, m_myl, m_alu, value, buffer); @@ -144,7 +144,7 @@ void alto2_cpu_device::wrtram() #if DEBUG_WRTRAM char buffer[256]; uint8_t* oprom = m_ucode_cram.get() + 4 * wordaddr; - disasm_disassemble(buffer, wordaddr, oprom, oprom, 0); + disassemble(buffer, wordaddr, oprom, oprom, 0); printf("WR CRAM_BANKSEL=%d RAM%d [%04o] upper:%06o lower:%06o value:%011o '%s'\n", GET_CRAM_BANKSEL(m_cram_addr), bank, wordaddr, m_myl, m_alu, value, buffer); diff --git a/src/devices/cpu/alto2/alto2cpu.cpp b/src/devices/cpu/alto2/alto2cpu.cpp index fd7a1f6dede..21f9faa2625 100644 --- a/src/devices/cpu/alto2/alto2cpu.cpp +++ b/src/devices/cpu/alto2/alto2cpu.cpp @@ -7,6 +7,7 @@ *****************************************************************************/ #include "emu.h" #include "alto2cpu.h" +#include "alto2dsm.h" #include "a2roms.h" #define DEBUG_UCODE_CONST_DATA 0 //!< define to 1 to dump decoded micro code and constants @@ -2980,3 +2981,8 @@ void alto2_cpu_device::soft_reset() m_unload_time = 0; // reset the word unload timing accu m_bitclk_time = 0; // reset the bitclk timing accu } + +util::disasm_interface *alto2_cpu_device::create_disassembler() +{ + return new alto2_disassembler; +} diff --git a/src/devices/cpu/alto2/alto2cpu.h b/src/devices/cpu/alto2/alto2cpu.h index f71b183b52a..6bebea1f803 100644 --- a/src/devices/cpu/alto2/alto2cpu.h +++ b/src/devices/cpu/alto2/alto2cpu.h @@ -238,9 +238,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; //! device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 4; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 4; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: diff --git a/src/devices/cpu/alto2/alto2dsm.cpp b/src/devices/cpu/alto2/alto2dsm.cpp index b70c35d182c..c621daaf3e7 100644 --- a/src/devices/cpu/alto2/alto2dsm.cpp +++ b/src/devices/cpu/alto2/alto2dsm.cpp @@ -5,7 +5,7 @@ * **********************************************************/ #include "emu.h" -#include "alto2cpu.h" +#include "alto2dsm.h" #define loc_DASTART 0000420 // display list header #define loc_DVIBITS 0000421 // display vertical field interrupt bitword @@ -68,7 +68,7 @@ /** * @brief short names for the 16 tasks */ -static const char *taskname[16] = { +const char *const alto2_disassembler::taskname[16] = { "EMU", // emulator task "T01", "T02", @@ -90,7 +90,7 @@ static const char *taskname[16] = { /** * @brief names for the 32 R registers */ -static const char *regname[32] = { +const char *const alto2_disassembler::regname[32] = { "AC(3)", // emulator accu 3 "AC(2)", // emulator accu 2 "AC(1)", // emulator accu 1 @@ -126,7 +126,7 @@ static const char *regname[32] = { }; //! for ALUF which is the value loaded into T, if t flags is set -static const char* t_bus_alu[16] = { +const char *const alto2_disassembler::t_bus_alu[16] = { "ALU", "BUS", "ALU", @@ -148,7 +148,7 @@ static const char* t_bus_alu[16] = { /** * @brief copy of the constant PROM, which this disassembler may not have access to */ -static uint16_t const_prom[PROM_SIZE] = { +uint16_t alto2_disassembler::const_prom[PROM_SIZE] = { /* 0000 */ 0x0000, 0x0001, 0x0002, 0xfffe, 0xffff, 0xffff, 0x000f, 0xffff, /* 0008 */ 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0xfff8, 0xfff8, /* 0010 */ 0x0010, 0x001f, 0x0020, 0x003f, 0x0040, 0x007f, 0x0080, 0x0007, @@ -187,34 +187,22 @@ static uint16_t const_prom[PROM_SIZE] = { * @brief print a symbolic name for an mpc address * * @param a microcode address (mpc) - * @return pointer to const string with the address or symbolic name + * @return string with the address or symbolic name */ -static const char *addrname(int a) +std::string alto2_disassembler::addrname(int a) const { - static char buffer[4][32]; - static int which = 0; - char *dst; - - which = (which + 1) % 4; - dst = buffer[which]; - - if (a < 020) { + if (a < 020) // start value for mpc per task is the task number - snprintf(dst, sizeof(buffer[0]), "*%s", taskname[a]); - } else { - snprintf(dst, sizeof(buffer[0]), "%04o", a); - } - return dst; + return util::string_format("*%s", taskname[a]); + else + return util::string_format("%04o", a); } -offs_t alto2_cpu_device::disasm_disassemble(std::ostream &main_stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +offs_t alto2_disassembler::disassemble(std::ostream &main_stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { std::ostringstream stream; - uint32_t mir = (static_cast<uint32_t>(oprom[0]) << 24) | - (static_cast<uint32_t>(oprom[1]) << 16) | - (static_cast<uint32_t>(oprom[2]) << 8) | - (static_cast<uint32_t>(oprom[3]) << 0); + uint32_t mir = opcodes.r32(pc); int rsel = (mir >> 27) & 31; int aluf = (mir >> 23) & 15; int bs = (mir >> 20) & 7; @@ -223,17 +211,13 @@ offs_t alto2_cpu_device::disasm_disassemble(std::ostream &main_stream, offs_t pc int t = (mir >> 11) & 1; int l = (mir >> 10) & 1; offs_t next = mir & 1023; - const uint8_t* src = oprom - 4 * pc + 4 * next; - uint32_t next2 = (static_cast<uint32_t>(src[0]) << 24) | - (static_cast<uint32_t>(src[1]) << 16) | - (static_cast<uint32_t>(src[2]) << 8) | - (static_cast<uint32_t>(src[3]) << 0); + uint32_t next2 = opcodes.r32(next); uint16_t prefetch = next2 & 1023; - offs_t result = 1 | DASMFLAG_SUPPORTED; + offs_t result = 1 | SUPPORTED; uint8_t pa; if (next != pc + 1) - result |= DASMFLAG_STEP_OUT; + result |= STEP_OUT; if (t) util::stream_format(stream, "T<-%s ", t_bus_alu[aluf]); @@ -395,3 +379,9 @@ offs_t alto2_cpu_device::disasm_disassemble(std::ostream &main_stream, offs_t pc return result; } + + +u32 alto2_disassembler::opcode_alignment() const +{ + return 1; +} diff --git a/src/devices/cpu/alto2/alto2dsm.h b/src/devices/cpu/alto2/alto2dsm.h new file mode 100644 index 00000000000..cb0d734fd58 --- /dev/null +++ b/src/devices/cpu/alto2/alto2dsm.h @@ -0,0 +1,31 @@ +// license:BSD-3-Clause +// copyright-holders:Juergen Buchmueller +/********************************************************** + * Xerox AltoII disassembler + * + **********************************************************/ + +#ifndef MAME_CPU_ALTO2_ALTO2DSM_H +#define MAME_CPU_ALTO2_ALTO2DSM_H + +#pragma once + +class alto2_disassembler : public util::disasm_interface +{ +public: + alto2_disassembler() = default; + virtual ~alto2_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *const taskname[16]; + static const char *const regname[32]; + static const char *const t_bus_alu[16]; + static uint16_t const_prom[]; + + std::string addrname(int a) const; +}; + +#endif diff --git a/src/devices/cpu/am29000/am29000.cpp b/src/devices/cpu/am29000/am29000.cpp index cd0d4624d9c..fffd26c3cbc 100644 --- a/src/devices/cpu/am29000/am29000.cpp +++ b/src/devices/cpu/am29000/am29000.cpp @@ -17,6 +17,7 @@ #include "emu.h" #include "debugger.h" #include "am29000.h" +#include "am29dasm.h" DEFINE_DEVICE_TYPE(AM29000, am29000_cpu_device, "am29000", "AMC Am29000") @@ -130,9 +131,9 @@ device_memory_interface::space_config_vector am29000_cpu_device::memory_space_co void am29000_cpu_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_data = &space(AS_DATA); - m_datadirect = &m_data->direct(); + m_datadirect = m_data->direct<0>(); m_io = &space(AS_IO); m_cfg = (PRL_AM29000 | PRL_REV_D) << CFG_PRL_SHIFT; @@ -702,9 +703,7 @@ void am29000_cpu_device::execute_set_input(int inputnum, int state) // TODO : CHECK IRQs } - -offs_t am29000_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *am29000_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( am29000 ); - return CPU_DISASSEMBLE_NAME(am29000)(this, stream, pc, oprom, opram, options); + return new am29000_disassembler; } diff --git a/src/devices/cpu/am29000/am29000.h b/src/devices/cpu/am29000/am29000.h index 084b0fdd995..d7d061996e8 100644 --- a/src/devices/cpu/am29000/am29000.h +++ b/src/devices/cpu/am29000/am29000.h @@ -458,9 +458,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 4; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 4; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; void signal_exception(uint32_t type); void external_irq_check(); @@ -632,9 +630,10 @@ protected: uint32_t m_next_pc; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_data; - direct_read_data *m_datadirect; + + direct_read_data<0> *m_datadirect; address_space *m_io; typedef void ( am29000_cpu_device::*opcode_func ) (); diff --git a/src/devices/cpu/am29000/am29dasm.cpp b/src/devices/cpu/am29000/am29dasm.cpp index 8c7f832e69f..7e69544ab2c 100644 --- a/src/devices/cpu/am29000/am29dasm.cpp +++ b/src/devices/cpu/am29000/am29dasm.cpp @@ -9,7 +9,7 @@ ***************************************************************************/ #include "emu.h" -#include "am29000.h" +#include "am29dasm.h" /*************************************************************************** @@ -36,38 +36,38 @@ CODE ***************************************************************************/ -static std::string dasm_type1(uint32_t op) +std::string am29000_disassembler::dasm_type1(uint32_t op) { return (op & OP_M_BIT) ? string_format("r%d, r%d, $%02x", OP_RC, OP_RA, OP_I8) : string_format("r%d, r%d, r%d", OP_RC, OP_RA, OP_RB); } -static std::string dasm_type2(uint32_t op) +std::string am29000_disassembler::dasm_type2(uint32_t op) { return string_format("r%d, r%d, r%d", OP_RC, OP_RA, OP_RB); } -static std::string dasm_type3(uint32_t op) +std::string am29000_disassembler::dasm_type3(uint32_t op) { return string_format("r%d, $%04x", OP_RA, OP_I16); } -static std::string dasm_type4(uint32_t op, uint32_t pc) +std::string am29000_disassembler::dasm_type4(uint32_t op, uint32_t pc) { return (op & OP_M_BIT) ? string_format("r%d, $%04x", OP_RA, OP_IJMP) : string_format("r%d, $%04x", OP_RA, pc + OP_SJMP); } -static std::string dasm_type5(uint32_t op) +std::string am29000_disassembler::dasm_type5(uint32_t op) { return (op & OP_M_BIT) ? string_format("trap%d, r%d, $%02x", OP_VN, OP_RA, OP_I8) : string_format("trap%d, r%d, r%d", OP_VN, OP_RA, OP_RB); } -static std::string dasm_type6(uint32_t op) +std::string am29000_disassembler::dasm_type6(uint32_t op) { return (op & OP_M_BIT) ? string_format("%d, %x, r%d, $%02x", OP_CE, OP_CNTL, OP_RA, OP_I8) @@ -82,7 +82,7 @@ static std::string dasm_type6(uint32_t op) #define TYPE_6 dasm_type6(op) -static const char* get_spr(int spid) +const char* am29000_disassembler::get_spr(int spid) { switch (spid) { @@ -117,9 +117,14 @@ static const char* get_spr(int spid) } } -CPU_DISASSEMBLE(am29000) +u32 am29000_disassembler::opcode_alignment() const { - uint32_t op = (oprom[0] << 24) | (oprom[1] << 16) | (oprom[2] << 8) | oprom[3]; + return 4; +} + +offs_t am29000_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + uint32_t op = opcodes.r32(pc); uint32_t flags = 0; switch (op >> 24) @@ -228,5 +233,5 @@ CPU_DISASSEMBLE(am29000) default: util::stream_format(stream, "??????"); break; } - return 4 | flags | DASMFLAG_SUPPORTED; + return 4 | flags | SUPPORTED; } diff --git a/src/devices/cpu/am29000/am29dasm.h b/src/devices/cpu/am29000/am29dasm.h new file mode 100644 index 00000000000..40507a7332e --- /dev/null +++ b/src/devices/cpu/am29000/am29dasm.h @@ -0,0 +1,36 @@ +// license:BSD-3-Clause +// copyright-holders:Philip Bennett +/*************************************************************************** + + am29dasm.c + Disassembler for the portable Am29000 emulator. + Written by Phil Bennett + +***************************************************************************/ + +#ifndef MAME_CPU_AM29000_AM29DASM_H +#define MAME_CPU_AM29000_AM29DASM_H + +#pragma once + +class am29000_disassembler : public util::disasm_interface +{ +public: + am29000_disassembler() = default; + virtual ~am29000_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + std::string dasm_type1(uint32_t op); + std::string dasm_type2(uint32_t op); + std::string dasm_type3(uint32_t op); + std::string dasm_type4(uint32_t op, uint32_t pc); + std::string dasm_type5(uint32_t op); + std::string dasm_type6(uint32_t op); + const char* get_spr(int spid); + +}; + +#endif diff --git a/src/devices/cpu/amis2000/amis2000.cpp b/src/devices/cpu/amis2000/amis2000.cpp index 457a99ead5d..bd3eda7852a 100644 --- a/src/devices/cpu/amis2000/amis2000.cpp +++ b/src/devices/cpu/amis2000/amis2000.cpp @@ -20,6 +20,7 @@ #include "emu.h" #include "amis2000.h" +#include "amis2000d.h" #include "debugger.h" @@ -98,10 +99,9 @@ void amis2000_base_device::state_string_export(const device_state_entry &entry, } } -offs_t amis2000_base_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +util::disasm_interface *amis2000_base_device::create_disassembler() { - extern CPU_DISASSEMBLE(amis2000); - return CPU_DISASSEMBLE_NAME(amis2000)(this, stream, pc, oprom, opram, options); + return new amis2000_disassembler; } diff --git a/src/devices/cpu/amis2000/amis2000.h b/src/devices/cpu/amis2000/amis2000.h index e3caee13b14..1bf4bf66460 100644 --- a/src/devices/cpu/amis2000/amis2000.h +++ b/src/devices/cpu/amis2000/amis2000.h @@ -87,9 +87,7 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual u32 disasm_min_opcode_bytes() const override { return 1; } - virtual u32 disasm_max_opcode_bytes() const override { return 1; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; // device_state_interface overrides virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; diff --git a/src/devices/cpu/amis2000/amis2000d.cpp b/src/devices/cpu/amis2000/amis2000d.cpp index adf5e2ed338..cff6155fa0a 100644 --- a/src/devices/cpu/amis2000/amis2000d.cpp +++ b/src/devices/cpu/amis2000/amis2000d.cpp @@ -7,21 +7,9 @@ */ #include "emu.h" -#include "debugger.h" -#include "amis2000.h" +#include "amis2000d.h" - -enum e_mnemonics -{ - mLAB = 0, mLAE, mLAI, mLBE, mLBEP, mLBF, mLBZ, mXAB, mXABU, mXAE, - mLAM, mXC, mXCI, mXCD, mSTM, mRSM, - mADD, mADCS, mADIS, mAND, mXOR, mCMA, mSTC, mRSC, mSF1, mRF1, mSF2, mRF2, - mSAM, mSZM, mSBE, mSZC, mSOS, mSZK, mSZI, mTF1, mTF2, - mPP, mJMP, mJMS, mRT, mRTS, mNOP, mHALT, - mINP, mOUT, mDISB, mDISN, mMVS, mPSH, mPSL, mEUR -}; - -static const char *const s_mnemonics[] = +const char *const amis2000_disassembler::s_mnemonics[] = { "LAB", "LAE", "LAI", "LBE", "LBEP", "LBF", "LBZ", "XAB", "XABU", "XAE", "LAM", "XC", "XCI", "XCD", "STM", "RSM", @@ -32,7 +20,7 @@ static const char *const s_mnemonics[] = }; // number of bits per opcode parameter, negative indicates complement -static const s8 s_bits[] = +const s8 amis2000_disassembler::s_bits[] = { 0, 0, 4, 2, 2, 2, 2, 0, 0, 0, -2, -2, -2, -2, 2, 2, @@ -42,21 +30,18 @@ static const s8 s_bits[] = 0, 0, 0, 0, 0, 0, 0, 0 }; -#define _OVER DASMFLAG_STEP_OVER -#define _OUT DASMFLAG_STEP_OUT - -static const u32 s_flags[] = +const u32 amis2000_disassembler::s_flags[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, _OVER, _OUT, _OUT, 0, 0, + 0, 0, STEP_OVER, STEP_OUT, STEP_OUT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -static const u8 s2000_mnemonic[0x100] = +const u8 amis2000_disassembler::s2000_mnemonic[0x100] = { /* 0x00 */ mNOP, mHALT, mRT, mRTS, mPSH, mPSL, mAND, mSOS, @@ -98,12 +83,9 @@ static const u8 s2000_mnemonic[0x100] = mJMP, mJMP, mJMP, mJMP, mJMP, mJMP, mJMP, mJMP }; - - -CPU_DISASSEMBLE(amis2000) +offs_t amis2000_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - int pos = 0; - u8 op = oprom[pos++]; + u8 op = opcodes.r8(pc); u8 instr = s2000_mnemonic[op]; util::stream_format(stream, "%-5s ", s_mnemonics[instr]); @@ -128,5 +110,10 @@ CPU_DISASSEMBLE(amis2000) util::stream_format(stream, "$%02X", param); } - return pos | s_flags[instr] | DASMFLAG_SUPPORTED; + return 1 | s_flags[instr] | SUPPORTED; +} + +u32 amis2000_disassembler::opcode_alignment() const +{ + return 1; } diff --git a/src/devices/cpu/amis2000/amis2000d.h b/src/devices/cpu/amis2000/amis2000d.h new file mode 100644 index 00000000000..0de1a455fa8 --- /dev/null +++ b/src/devices/cpu/amis2000/amis2000d.h @@ -0,0 +1,40 @@ +// license:BSD-3-Clause +// copyright-holders:hap +/* + + AMI S2000-family disassembler + +*/ + +#ifndef MAME_CPU_AMIS2000_AMIS2000D_H +#define MAME_CPU_AMIS2000_AMIS2000D_H + +#pragma once + +class amis2000_disassembler : public util::disasm_interface +{ +public: + amis2000_disassembler() = default; + virtual ~amis2000_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum e_mnemonics + { + mLAB = 0, mLAE, mLAI, mLBE, mLBEP, mLBF, mLBZ, mXAB, mXABU, mXAE, + mLAM, mXC, mXCI, mXCD, mSTM, mRSM, + mADD, mADCS, mADIS, mAND, mXOR, mCMA, mSTC, mRSC, mSF1, mRF1, mSF2, mRF2, + mSAM, mSZM, mSBE, mSZC, mSOS, mSZK, mSZI, mTF1, mTF2, + mPP, mJMP, mJMS, mRT, mRTS, mNOP, mHALT, + mINP, mOUT, mDISB, mDISN, mMVS, mPSH, mPSL, mEUR + }; + + static const char *const s_mnemonics[]; + static const s8 s_bits[]; + static const u32 s_flags[]; + static const u8 s2000_mnemonic[0x100]; +}; + +#endif diff --git a/src/devices/cpu/apexc/apexc.cpp b/src/devices/cpu/apexc/apexc.cpp index e26c6c094b4..4278d5b2d48 100644 --- a/src/devices/cpu/apexc/apexc.cpp +++ b/src/devices/cpu/apexc/apexc.cpp @@ -327,6 +327,7 @@ field: X address D Function Y address D (part 2) #include "emu.h" #include "apexc.h" +#include "apexcdsm.h" #include "debugger.h" @@ -854,9 +855,7 @@ void apexc_cpu_device::execute_run() } while (m_icount > 0); } - -offs_t apexc_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *apexc_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( apexc ); - return CPU_DISASSEMBLE_NAME(apexc)(this, stream, pc, oprom, opram, options); + return new apexc_disassembler; } diff --git a/src/devices/cpu/apexc/apexc.h b/src/devices/cpu/apexc/apexc.h index 76a91a98207..92cc60d7f09 100644 --- a/src/devices/cpu/apexc/apexc.h +++ b/src/devices/cpu/apexc/apexc.h @@ -40,9 +40,7 @@ protected: virtual void state_import(const device_state_entry &entry) override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 4; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 4; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; inline uint32_t apexc_readmem(uint32_t address) { return m_program->read_dword((address)<<2); } inline void apexc_writemem(uint32_t address, uint32_t data) { m_program->write_dword((address)<<2, (data)); } diff --git a/src/devices/cpu/apexc/apexcdsm.cpp b/src/devices/cpu/apexc/apexcdsm.cpp index e3626a40af9..bb581dd2850 100644 --- a/src/devices/cpu/apexc/apexcdsm.cpp +++ b/src/devices/cpu/apexc/apexcdsm.cpp @@ -10,9 +10,7 @@ #include "emu.h" -#include "debugger.h" - -#include "apexc.h" +#include "apexcdsm.h" /* Here is the format used for debugger output. @@ -63,15 +61,8 @@ The X value shows where the data word is located, and the Y value is the address of the next instruction. */ -enum format_type {branch, shiftl, shiftr, multiply, store, swap, one_address, two_address}; - -struct instr_desc -{ - const char *mnemonic; - format_type format; /* -> X and Y are format */ -}; -static const instr_desc instructions[16] = +const apexc_disassembler::instr_desc apexc_disassembler::instructions[16] = { { "Stop", one_address }, { "I", one_address }, { "P", one_address }, { "B", branch }, @@ -83,7 +74,12 @@ static const instr_desc instructions[16] = { "A", store }, { "S", swap } }; -CPU_DISASSEMBLE(apexc) +u32 apexc_disassembler::opcode_alignment() const +{ + return 4; +} + +offs_t apexc_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint32_t instruction; /* 32-bit machine instruction */ int x, y, function, c6, vector; /* instruction fields */ @@ -92,7 +88,7 @@ CPU_DISASSEMBLE(apexc) char mnemonic[9]; /* storage for generated mnemonic */ /* read the instruction to disassemble */ - instruction = oprom[0] << 24 | oprom[1] << 16 | oprom[2] << 8 | oprom[3]; + instruction = opcodes.r32(pc); /* isolate the instruction fields */ x = (instruction >> 22) & 0x3FF; diff --git a/src/devices/cpu/apexc/apexcdsm.h b/src/devices/cpu/apexc/apexcdsm.h new file mode 100644 index 00000000000..b310df1f496 --- /dev/null +++ b/src/devices/cpu/apexc/apexcdsm.h @@ -0,0 +1,37 @@ +// license:BSD-3-Clause +// copyright-holders:Raphael Nabet +/* + cpu/apexc/apexcsm.c : APE(X)C CPU disassembler + + By Raphael Nabet + + see cpu/apexc.c for background and tech info +*/ + +#ifndef MAME_CPU_APEXC_APEXCDSM_H +#define MAME_CPU_APEXC_APEXCDSM_H + +#pragma once + +class apexc_disassembler : public util::disasm_interface +{ +public: + apexc_disassembler() = default; + virtual ~apexc_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum format_type {branch, shiftl, shiftr, multiply, store, swap, one_address, two_address}; + + struct instr_desc + { + const char *mnemonic; + format_type format; /* -> X and Y are format */ + }; + + static const instr_desc instructions[16]; +}; + +#endif diff --git a/src/devices/cpu/arc/arc.cpp b/src/devices/cpu/arc/arc.cpp index eb71302468a..fa421875bd1 100644 --- a/src/devices/cpu/arc/arc.cpp +++ b/src/devices/cpu/arc/arc.cpp @@ -12,6 +12,7 @@ #include "emu.h" #include "debugger.h" #include "arc.h" +#include "arcdasm.h" DEFINE_DEVICE_TYPE(ARC, arc_cpu_device, "arc_a4", "ARCtangent A4") @@ -26,13 +27,11 @@ arc_cpu_device::arc_cpu_device(const machine_config &mconfig, const char *tag, d } -offs_t arc_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *arc_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( arc ); - return CPU_DISASSEMBLE_NAME(arc)(this, stream, pc, oprom, opram, options); + return new arc_disassembler; } - /*****************************************************************************/ /*****************************************************************************/ diff --git a/src/devices/cpu/arc/arc.h b/src/devices/cpu/arc/arc.h index cf244c8f5b2..7bdf1123ec8 100644 --- a/src/devices/cpu/arc/arc.h +++ b/src/devices/cpu/arc/arc.h @@ -43,9 +43,7 @@ protected: virtual void state_export(const device_state_entry &entry) override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 4; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 4; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; diff --git a/src/devices/cpu/arc/arcdasm.cpp b/src/devices/cpu/arc/arcdasm.cpp index e8c2d425736..fa7b6f2028e 100644 --- a/src/devices/cpu/arc/arcdasm.cpp +++ b/src/devices/cpu/arc/arcdasm.cpp @@ -7,7 +7,7 @@ \*********************************/ #include "emu.h" -#include <stdarg.h> +#include "arcdasm.h" /*****************************************************************************/ @@ -15,7 +15,7 @@ /*****************************************************************************/ -static const char *basic[0x20] = +const char *const arc_disassembler::basic[0x20] = { /* 00 */ "LD r+r", /* 01 */ "LD r+o", @@ -51,7 +51,7 @@ static const char *basic[0x20] = /* 1f */ "MIN" }; -static const char *conditions[0x20] = +const char *arc_disassembler::conditions[0x20] = { /* 00 */ "AL", // (aka RA - Always) /* 01 */ "EQ", // (aka Z - Zero @@ -87,7 +87,7 @@ static const char *conditions[0x20] = /* 1f */ "0x1f Reserved" }; -static const char *delaytype[0x4] = +const char *arc_disassembler::delaytype[0x4] = { "ND", // NO DELAY - execute next instruction only when NOT jumping "D", // always execute next instruction @@ -95,7 +95,7 @@ static const char *delaytype[0x4] = "Res!", // reserved / invalid }; -static const char *regnames[0x40] = +const char *arc_disassembler::regnames[0x40] = { /* 0x00 */ "r00", /* 0x01 */ "r01", @@ -180,10 +180,14 @@ static const char *regnames[0x40] = #define ARC_REGOP_SHIMM ((op & 0x000001ff) >> 0 ) // aka D -CPU_DISASSEMBLE(arc) +u32 arc_disassembler::opcode_alignment() const { - uint32_t op = oprom[0] | (oprom[1] << 8) | (oprom[2] << 16) | (oprom[3] << 24); - op = big_endianize_int32(op); + return 4; +} + +offs_t arc_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + uint32_t op = opcodes.r32(pc); uint8_t opcode = ARC_OPERATION; @@ -205,5 +209,5 @@ CPU_DISASSEMBLE(arc) break; } - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } diff --git a/src/devices/cpu/arc/arcdasm.h b/src/devices/cpu/arc/arcdasm.h new file mode 100644 index 00000000000..a6bfe559f25 --- /dev/null +++ b/src/devices/cpu/arc/arcdasm.h @@ -0,0 +1,31 @@ +// license:BSD-3-Clause +// copyright-holders:David Haywood +/*********************************\ + + ARCtangent A4 disassembler + +\*********************************/ + +#ifndef MAME_CPU_ARC_ARCDASM_H +#define MAME_CPU_ARC_ARCDASM_H + +#pragma once + +class arc_disassembler : public util::disasm_interface +{ +public: + arc_disassembler() = default; + virtual ~arc_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *const basic[0x20]; + static const char *conditions[0x20]; + static const char *delaytype[0x4]; + static const char *regnames[0x40]; + +}; + +#endif diff --git a/src/devices/cpu/arcompact/arcompact.cpp b/src/devices/cpu/arcompact/arcompact.cpp index 79ae7c6d6c6..bffbcda8213 100644 --- a/src/devices/cpu/arcompact/arcompact.cpp +++ b/src/devices/cpu/arcompact/arcompact.cpp @@ -21,7 +21,7 @@ #include "emu.h" #include "debugger.h" #include "arcompact.h" -#include "arcompact_common.h" +#include "arcompactdasm.h" DEFINE_DEVICE_TYPE(ARCA5, arcompact_device, "arc_a5", "ARCtangent A5") @@ -64,10 +64,9 @@ device_memory_interface::space_config_vector arcompact_device::memory_space_conf }; } -offs_t arcompact_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *arcompact_device::create_disassembler() { - extern CPU_DISASSEMBLE( arcompact ); - return CPU_DISASSEMBLE_NAME(arcompact)(this, stream, pc, oprom, opram, options); + return new arcompact_disassembler; } @@ -104,7 +103,7 @@ void arcompact_device::device_start() for (int i = 0x100; i < 0x140; i++) { - state_add(i, regnames[i-0x100], m_debugger_temp).callimport().callexport().formatstr("%08X"); + state_add(i, arcompact_disassembler::regnames[i-0x100], m_debugger_temp).callimport().callexport().formatstr("%08X"); } diff --git a/src/devices/cpu/arcompact/arcompact.h b/src/devices/cpu/arcompact/arcompact.h index 0a88fc119bf..fc7d7dbe5dc 100644 --- a/src/devices/cpu/arcompact/arcompact.h +++ b/src/devices/cpu/arcompact/arcompact.h @@ -102,9 +102,7 @@ protected: virtual void state_export(const device_state_entry &entry) override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 8; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; diff --git a/src/devices/cpu/arcompact/arcompact_common.cpp b/src/devices/cpu/arcompact/arcompact_common.cpp deleted file mode 100644 index f9b74683461..00000000000 --- a/src/devices/cpu/arcompact/arcompact_common.cpp +++ /dev/null @@ -1,527 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:David Haywood -/*********************************\ - - ARCompact Core - -\*********************************/ - -// condition codes (basic ones are the same as arc -const char *conditions[0x20] = -{ - /* 00 */ "AL", // (aka RA - Always) - /* 01 */ "EQ", // (aka Z - Zero - /* 02 */ "NE", // (aka NZ - Non-Zero) - /* 03 */ "PL", // (aka P - Positive) - /* 04 */ "MI", // (aka N - Negative) - /* 05 */ "CS", // (aka C, LO - Carry set / Lower than) (unsigned) - /* 06 */ "CC", // (aka CC, NC, HS - Carry Clear / Higher or Same) (unsigned) - /* 07 */ "VS", // (aka V - Overflow set) - /* 08 */ "VC", // (aka NV - Overflow clear) - /* 09 */ "GT", // ( - Greater than) (signed) - /* 0a */ "GE", // ( - Greater than or Equal) (signed) - /* 0b */ "LT", // ( - Less than) (signed) - /* 0c */ "LE", // ( - Less than or Equal) (signed) - /* 0d */ "HI", // ( - Higher than) (unsigned) - /* 0e */ "LS", // ( - Lower or Same) (unsigned) - /* 0f */ "PNZ",// ( - Positive non-0 value) - /* 10 */ "0x10 Reserved", // possible CPU implementation specifics - /* 11 */ "0x11 Reserved", - /* 12 */ "0x12 Reserved", - /* 13 */ "0x13 Reserved", - /* 14 */ "0x14 Reserved", - /* 15 */ "0x15 Reserved", - /* 16 */ "0x16 Reserved", - /* 17 */ "0x17 Reserved", - /* 18 */ "0x18 Reserved", - /* 19 */ "0x19 Reserved", - /* 1a */ "0x1a Reserved", - /* 1b */ "0x1b Reserved", - /* 1c */ "0x1c Reserved", - /* 1d */ "0x1d Reserved", - /* 1e */ "0x1e Reserved", - /* 1f */ "0x1f Reserved" -}; - -#define UNUSED_REG "unusedreg" - -#define AUX_UNUSED_16 \ - /* 0xxx0 */ UNUSED_REG, /* 0xxx1 */ UNUSED_REG, /* 0xxx2 */ UNUSED_REG, /* 0xxx3 */ UNUSED_REG, /* 0xxx4 */ UNUSED_REG, /* 0xxx5 */ UNUSED_REG, /* 0xxx6 */ UNUSED_REG, /* 0xxx7 */ UNUSED_REG, /* 0xxx8 */ UNUSED_REG, /* 0xxx9 */ UNUSED_REG, /* 0xxxa */ UNUSED_REG, /* 0xxxb */ UNUSED_REG, /* 0xxxc */ UNUSED_REG, /* 0xxxd */ UNUSED_REG, /* 0xxxe */ UNUSED_REG, /* 0xxxf */ UNUSED_REG, - -// the Auxiliary Register set is actually a 2^32 dword address space (so 16 GB / 34-bit) -// this table just allows us to improve the debugger display for some of the common core / internal ones -const char *auxregnames[0x420] = -{ - /* 0x000 */ "STATUS", - /* 0x001 */ "SEMAPHOR", - /* 0x002 */ "LP_START", - /* 0x003 */ "LP_END", - /* 0x004 */ "IDENTITY", - /* 0x005 */ "DEBUG", - /* 0x006 */ "PC", - /* 0x007 */ UNUSED_REG, - /* 0x008 */ UNUSED_REG, - /* 0x009 */ UNUSED_REG, - /* 0x00a */ "STATUS32", - /* 0x00b */ "STATUS32_L1", - /* 0x00c */ "STATUS32_L2", - /* 0x00d */ UNUSED_REG, - /* 0x00e */ UNUSED_REG, - /* 0x00f */ UNUSED_REG, - - /* 0x010 */ UNUSED_REG, - /* 0x011 */ UNUSED_REG, - /* 0x012 */ "MULHI", // extension register - /* 0x013 */ UNUSED_REG, - /* 0x014 */ UNUSED_REG, - /* 0x015 */ UNUSED_REG, - /* 0x016 */ UNUSED_REG, - /* 0x017 */ UNUSED_REG, - /* 0x018 */ UNUSED_REG, - /* 0x019 */ UNUSED_REG, - /* 0x01a */ UNUSED_REG, - /* 0x01b */ UNUSED_REG, - /* 0x01c */ UNUSED_REG, - /* 0x01d */ UNUSED_REG, - /* 0x01e */ UNUSED_REG, - /* 0x01f */ UNUSED_REG, - - /* 0x020 */ UNUSED_REG, - /* 0x021 */ "COUNT0", - /* 0x022 */ "CONTROL0", - /* 0x023 */ "LIMIT0", - /* 0x024 */ UNUSED_REG, - /* 0x025 */ "INT_VECTOR_BASE", - /* 0x026 */ UNUSED_REG, - /* 0x027 */ UNUSED_REG, - /* 0x028 */ UNUSED_REG, - /* 0x029 */ UNUSED_REG, - /* 0x02a */ UNUSED_REG, - /* 0x02b */ UNUSED_REG, - /* 0x02c */ UNUSED_REG, - /* 0x02d */ UNUSED_REG, - /* 0x02e */ UNUSED_REG, - /* 0x02f */ UNUSED_REG, - AUX_UNUSED_16 /* 0x030 - 0x03f */ - /* 0x040 */ UNUSED_REG, - /* 0x041 */ "AUX_MACMODE", - /* 0x042 */ UNUSED_REG, - /* 0x043 */ "AUX_IRQLV12", - /* 0x044 */ UNUSED_REG, - /* 0x045 */ UNUSED_REG, - /* 0x046 */ UNUSED_REG, - /* 0x047 */ UNUSED_REG, - /* 0x048 */ UNUSED_REG, - /* 0x049 */ UNUSED_REG, - /* 0x04a */ UNUSED_REG, - /* 0x04b */ UNUSED_REG, - /* 0x04c */ UNUSED_REG, - /* 0x04d */ UNUSED_REG, - /* 0x04e */ UNUSED_REG, - /* 0x04f */ UNUSED_REG, - AUX_UNUSED_16 /* 0x050 - 0x05f */ - // build configuration registers 0x060 - 0x07f - /* 0x060 */ "RESERVED AUX 0x60",/* 0x061 */ "RESERVED AUX 0x61",/* 0x062 */ "RESERVED AUX 0x62",/* 0x063 */ "RESERVED AUX 0x63",/* 0x064 */ "RESERVED AUX 0x64",/* 0x065 */ "RESERVED AUX 0x65",/* 0x066 */ "RESERVED AUX 0x66",/* 0x067 */ "RESERVED AUX 0x67",/* 0x068 */ "RESERVED AUX 0x68",/* 0x069 */ "RESERVED AUX 0x69",/* 0x06a */ "RESERVED AUX 0x6a",/* 0x06b */ "RESERVED AUX 0x6b",/* 0x06c */ "RESERVED AUX 0x6c",/* 0x06d */ "RESERVED AUX 0x6d",/* 0x06e */ "RESERVED AUX 0x6e",/* 0x06f */ "RESERVED AUX 0x6f", - /* 0x070 */ "RESERVED AUX 0x70",/* 0x071 */ "RESERVED AUX 0x71",/* 0x072 */ "RESERVED AUX 0x72",/* 0x073 */ "RESERVED AUX 0x73",/* 0x074 */ "RESERVED AUX 0x74",/* 0x075 */ "RESERVED AUX 0x75",/* 0x076 */ "RESERVED AUX 0x76",/* 0x077 */ "RESERVED AUX 0x77",/* 0x078 */ "RESERVED AUX 0x78",/* 0x079 */ "RESERVED AUX 0x79",/* 0x07a */ "RESERVED AUX 0x7a",/* 0x07b */ "RESERVED AUX 0x7b",/* 0x07c */ "RESERVED AUX 0x7c",/* 0x07d */ "RESERVED AUX 0x7d",/* 0x07e */ "RESERVED AUX 0x7e",/* 0x07f */ "RESERVED AUX 0x7f", - AUX_UNUSED_16 /* 0x080 - 0x08f */ - AUX_UNUSED_16 /* 0x090 - 0x09f */ - AUX_UNUSED_16 /* 0x0a0 - 0x0af */ - AUX_UNUSED_16 /* 0x0b0 - 0x0bf */ - // build configuration registers 0x0c0 - 0x0ff - /* 0x0c0 */ "RESERVED AUX 0xc0",/* 0x0c1 */ "RESERVED AUX 0xc1",/* 0x0c2 */ "RESERVED AUX 0xc2",/* 0x0c3 */ "RESERVED AUX 0xc3",/* 0x0c4 */ "RESERVED AUX 0xc4",/* 0x0c5 */ "RESERVED AUX 0xc5",/* 0x0c6 */ "RESERVED AUX 0xc6",/* 0x0c7 */ "RESERVED AUX 0xc7",/* 0x0c8 */ "RESERVED AUX 0xc8",/* 0x0c9 */ "RESERVED AUX 0xc9",/* 0x0ca */ "RESERVED AUX 0xca",/* 0x0cb */ "RESERVED AUX 0xcb",/* 0x0cc */ "RESERVED AUX 0xcc",/* 0x0cd */ "RESERVED AUX 0xcd",/* 0x0ce */ "RESERVED AUX 0xce",/* 0x0cf */ "RESERVED AUX 0xcf", - /* 0x0d0 */ "RESERVED AUX 0xd0",/* 0x0d1 */ "RESERVED AUX 0xd1",/* 0x0d2 */ "RESERVED AUX 0xd2",/* 0x0d3 */ "RESERVED AUX 0xd3",/* 0x0d4 */ "RESERVED AUX 0xd4",/* 0x0d5 */ "RESERVED AUX 0xd5",/* 0x0d6 */ "RESERVED AUX 0xd6",/* 0x0d7 */ "RESERVED AUX 0xd7",/* 0x0d8 */ "RESERVED AUX 0xd8",/* 0x0d9 */ "RESERVED AUX 0xd9",/* 0x0da */ "RESERVED AUX 0xda",/* 0x0db */ "RESERVED AUX 0xdb",/* 0x0dc */ "RESERVED AUX 0xdc",/* 0x0dd */ "RESERVED AUX 0xdd",/* 0x0de */ "RESERVED AUX 0xde",/* 0x0df */ "RESERVED AUX 0xdf", - /* 0x0e0 */ "RESERVED AUX 0xe0",/* 0x0e1 */ "RESERVED AUX 0xe1",/* 0x0e2 */ "RESERVED AUX 0xe2",/* 0x0e3 */ "RESERVED AUX 0xe3",/* 0x0e4 */ "RESERVED AUX 0xe4",/* 0x0e5 */ "RESERVED AUX 0xe5",/* 0x0e6 */ "RESERVED AUX 0xe6",/* 0x0e7 */ "RESERVED AUX 0xe7",/* 0x0e8 */ "RESERVED AUX 0xe8",/* 0x0e9 */ "RESERVED AUX 0xe9",/* 0x0ea */ "RESERVED AUX 0xea",/* 0x0eb */ "RESERVED AUX 0xeb",/* 0x0ec */ "RESERVED AUX 0xec",/* 0x0ed */ "RESERVED AUX 0xed",/* 0x0ee */ "RESERVED AUX 0xee",/* 0x0ef */ "RESERVED AUX 0xef", - /* 0x0f0 */ "RESERVED AUX 0xf0",/* 0x0f1 */ "RESERVED AUX 0xf1",/* 0x0f2 */ "RESERVED AUX 0xf2",/* 0x0f3 */ "RESERVED AUX 0xf3",/* 0x0f4 */ "RESERVED AUX 0xf4",/* 0x0f5 */ "RESERVED AUX 0xf5",/* 0x0f6 */ "RESERVED AUX 0xf6",/* 0x0f7 */ "RESERVED AUX 0xf7",/* 0x0f8 */ "RESERVED AUX 0xf8",/* 0x0f9 */ "RESERVED AUX 0xf9",/* 0x0fa */ "RESERVED AUX 0xfa",/* 0x0fb */ "RESERVED AUX 0xfb",/* 0x0fc */ "RESERVED AUX 0xfc",/* 0x0fd */ "RESERVED AUX 0xfd",/* 0x0fe */ "RESERVED AUX 0xfe",/* 0x0ff */ "RESERVED AUX 0xff", - /* 0x100 */ "COUNT1", - /* 0x101 */ "CONTROL1", - /* 0x102 */ "LIMIT1", - /* 0x103 */ UNUSED_REG, - /* 0x104 */ UNUSED_REG, - /* 0x105 */ UNUSED_REG, - /* 0x106 */ UNUSED_REG, - /* 0x107 */ UNUSED_REG, - /* 0x108 */ UNUSED_REG, - /* 0x109 */ UNUSED_REG, - /* 0x10a */ UNUSED_REG, - /* 0x10b */ UNUSED_REG, - /* 0x10c */ UNUSED_REG, - /* 0x10d */ UNUSED_REG, - /* 0x10e */ UNUSED_REG, - /* 0x10f */ UNUSED_REG, - AUX_UNUSED_16 /* 0x110 - 0x11f */ - AUX_UNUSED_16 /* 0x120 - 0x12f */ - AUX_UNUSED_16 /* 0x130 - 0x13f */ - AUX_UNUSED_16 /* 0x140 - 0x14f */ - AUX_UNUSED_16 /* 0x150 - 0x15f */ - AUX_UNUSED_16 /* 0x160 - 0x16f */ - AUX_UNUSED_16 /* 0x170 - 0x17f */ - AUX_UNUSED_16 /* 0x180 - 0x18f */ - AUX_UNUSED_16 /* 0x190 - 0x19f */ - AUX_UNUSED_16 /* 0x1a0 - 0x1af */ - AUX_UNUSED_16 /* 0x1b0 - 0x1bf */ - AUX_UNUSED_16 /* 0x1c0 - 0x1cf */ - AUX_UNUSED_16 /* 0x1d0 - 0x1df */ - AUX_UNUSED_16 /* 0x1e0 - 0x1ef */ - AUX_UNUSED_16 /* 0x1f0 - 0x1ff */ - /* 0x200 */ "AUX_IRQ_LEV", - /* 0x201 */ "AUX_IRQ_HINT", - /* 0x203 */ UNUSED_REG, - /* 0x203 */ UNUSED_REG, - /* 0x204 */ UNUSED_REG, - /* 0x205 */ UNUSED_REG, - /* 0x206 */ UNUSED_REG, - /* 0x207 */ UNUSED_REG, - /* 0x208 */ UNUSED_REG, - /* 0x209 */ UNUSED_REG, - /* 0x20a */ UNUSED_REG, - /* 0x20b */ UNUSED_REG, - /* 0x20c */ UNUSED_REG, - /* 0x20d */ UNUSED_REG, - /* 0x20e */ UNUSED_REG, - /* 0x20f */ UNUSED_REG, - AUX_UNUSED_16 /* 0x210 - 0x21f */ - AUX_UNUSED_16 /* 0x220 - 0x22f */ - AUX_UNUSED_16 /* 0x230 - 0x23f */ - AUX_UNUSED_16 /* 0x240 - 0x24f */ - AUX_UNUSED_16 /* 0x250 - 0x25f */ - AUX_UNUSED_16 /* 0x260 - 0x26f */ - AUX_UNUSED_16 /* 0x270 - 0x27f */ - AUX_UNUSED_16 /* 0x280 - 0x28f */ - AUX_UNUSED_16 /* 0x290 - 0x29f */ - AUX_UNUSED_16 /* 0x2a0 - 0x2af */ - AUX_UNUSED_16 /* 0x2b0 - 0x2bf */ - AUX_UNUSED_16 /* 0x2c0 - 0x2cf */ - AUX_UNUSED_16 /* 0x2d0 - 0x2df */ - AUX_UNUSED_16 /* 0x2e0 - 0x2ef */ - AUX_UNUSED_16 /* 0x2f0 - 0x2ff */ - - AUX_UNUSED_16 /* 0x300 - 0x30f */ - AUX_UNUSED_16 /* 0x310 - 0x31f */ - AUX_UNUSED_16 /* 0x320 - 0x32f */ - AUX_UNUSED_16 /* 0x330 - 0x33f */ - AUX_UNUSED_16 /* 0x340 - 0x34f */ - AUX_UNUSED_16 /* 0x350 - 0x35f */ - AUX_UNUSED_16 /* 0x360 - 0x36f */ - AUX_UNUSED_16 /* 0x370 - 0x37f */ - AUX_UNUSED_16 /* 0x380 - 0x38f */ - AUX_UNUSED_16 /* 0x390 - 0x39f */ - AUX_UNUSED_16 /* 0x3a0 - 0x3af */ - AUX_UNUSED_16 /* 0x3b0 - 0x3bf */ - AUX_UNUSED_16 /* 0x3c0 - 0x3cf */ - AUX_UNUSED_16 /* 0x3d0 - 0x3df */ - AUX_UNUSED_16 /* 0x3e0 - 0x3ef */ - AUX_UNUSED_16 /* 0x3f0 - 0x3ff */ - - /* 0x400 */ "ERET", - /* 0x401 */ "ERBTA", - /* 0x403 */ "ERSTATUS", - /* 0x403 */ "ECR", - /* 0x404 */ "EFA", - /* 0x405 */ UNUSED_REG, - /* 0x406 */ UNUSED_REG, - /* 0x407 */ UNUSED_REG, - /* 0x408 */ UNUSED_REG, - /* 0x409 */ UNUSED_REG, - /* 0x40a */ "ICAUSE1", - /* 0x40b */ "ICAUSE2", - /* 0x40c */ "AUX_IENABLE", - /* 0x40d */ "AUX_ITRIGGER", - /* 0x40e */ UNUSED_REG, - /* 0x40f */ UNUSED_REG, - - /* 0x410 */ "XPU", - /* 0x411 */ UNUSED_REG, - /* 0x412 */ "BTA", - /* 0x413 */ "BTA_L1", - /* 0x414 */ "BTA_L2", - /* 0x415 */ "AUX_IRQ_PULSE_CANCEL", - /* 0x416 */ "AUX_IRQ_PENDING", - /* 0x417 */ UNUSED_REG, - /* 0x418 */ UNUSED_REG, - /* 0x419 */ UNUSED_REG, - /* 0x41a */ UNUSED_REG, - /* 0x41b */ UNUSED_REG, - /* 0x41c */ UNUSED_REG, - /* 0x41d */ UNUSED_REG, - /* 0x41e */ UNUSED_REG, - /* 0x41f */ UNUSED_REG -}; - -//#define EXPLICIT_EXTENSIONS - -const char *datasize[0x4] = -{ -#ifdef EXPLICIT_EXTENSIONS - /* 00 */ ".L", // Dword (default) (can use no extension, using .L to be explicit) -#else - /* 00 */ "",// Dword (default) -#endif - /* 01 */ ".B", // Byte - /* 02 */ ".W", // Word - /* 03 */ ".<illegal data size>" -}; - -const char *dataextend[0x2] = -{ -#ifdef EXPLICIT_EXTENSIONS - /* 00 */ ".ZX", // Zero Extend (can use no extension, using .ZX to be explicit) -#else - /* 00 */ "", // Zero Extend -#endif - /* 01 */ ".X" // Sign Extend -}; - -const char *addressmode[0x4] = -{ -#ifdef EXPLICIT_EXTENSIONS - /* 00 */ ".AN", // No Writeback (can use no extension, using .AN to be explicit) -#else - /* 00 */ "", // No Writeback -#endif - /* 01 */ ".AW", // Writeback pre memory access - /* 02 */ ".AB", // Writeback post memory access - /* 03 */ ".AS" // scaled -}; - -const char *cachebit[0x2] = -{ -#ifdef EXPLICIT_EXTENSIONS - /* 00 */ ".EN", // Data Cache Enabled (can use no extension, using .EN to be explicit) -#else - /* 00 */ "", // Data Cache Enabled -#endif - /* 01 */ ".DI" // Direct to Memory (Cache Bypass) -}; - -const char *flagbit[0x2] = -{ -#ifdef EXPLICIT_EXTENSIONS - /* 00 */ ".NF", // Don't Set Flags (can use no extension, using .NF to be explicit) -#else - /* 00 */ "", // Don't Set Flags -#endif - /* 01 */ ".F" // Set Flags -}; - -const char *delaybit[0x2] = -{ - /* 00 */ ".ND", // Don't execute opcode in delay slot - /* 01 */ ".D" // Execute Opcode in delay slot -}; - - -const char *regnames[0x40] = -{ - /* 00 */ "r0", - /* 01 */ "r1", - /* 02 */ "r2", - /* 03 */ "r3", - /* 04 */ "r4", - /* 05 */ "r5", - /* 06 */ "r6", - /* 07 */ "r7", - /* 08 */ "r8", - /* 09 */ "r9", - /* 0a */ "r10", - /* 0b */ "r11", - /* 0c */ "r12", - /* 0d */ "r13", - /* 0e */ "r14", - /* 0f */ "r15", - - /* 10 */ "r16", - /* 11 */ "r17", - /* 12 */ "r18", - /* 13 */ "r19", - /* 14 */ "r20", - /* 15 */ "r21", - /* 16 */ "r22", - /* 17 */ "r23", - /* 18 */ "r24", - /* 19 */ "r25", - /* 1a */ "r26_GP", - /* 1b */ "r27_FP", - /* 1c */ "r28_SP", - /* 1d */ "r29_ILINK1", - /* 1e */ "r30_ILINK2", - /* 1f */ "r31_BLINK", - - /* 20 */ "r32(ext)", - /* 21 */ "r33(ext)", - /* 22 */ "r34(ext)", - /* 23 */ "r35(ext)", - /* 24 */ "r36(ext)", - /* 25 */ "r37(ext)", - /* 26 */ "r38(ext)", - /* 27 */ "r39(ext)", - /* 28 */ "r40(ext)", - /* 29 */ "r41(ext)", - /* 2a */ "r42(ext)", - /* 2b */ "r43(ext)", - /* 2c */ "r44(ext)", - /* 2d */ "r45(ext)", - /* 2e */ "r46(ext)", - /* 2f */ "r47(ext)", - - /* 30 */ "r48(ext)", - /* 31 */ "r49(ext)", - /* 32 */ "r50(ext)", - /* 33 */ "r51(ext)", - /* 34 */ "r52(ext)", - /* 35 */ "r53(ext)", - /* 36 */ "r54(ext)", - /* 37 */ "r55(ext)", - /* 38 */ "r56(ext)", - /* 39 */ "r57(M-LO)", // MLO (result registers for optional multply functions) - /* 3a */ "r58(M-MID)", // MMID - /* 3b */ "r59(M-HI)", // MHI - /* 3c */ "r60(LP_COUNT)", - /* 3d */ "r61(reserved)", - /* 3e */ "r62(LIMM)", // use Long Immediate Data instead of register - /* 3f */ "r63(PCL)" -}; - -#if 0 -const char *opcodes_temp[0x40] = -{ - /* 00 */ "0x00", - /* 01 */ "0x01", - /* 02 */ "0x02", - /* 03 */ "0x03", - /* 04 */ "0x04", - /* 05 */ "0x05", - /* 06 */ "0x06", - /* 07 */ "0x07", - /* 08 */ "0x08", - /* 09 */ "0x09", - /* 0a */ "0x0a", - /* 0b */ "0x0b", - /* 0c */ "0x0c", - /* 0d */ "0x0d", - /* 0e */ "0x0e", - /* 0f */ "0x0f", - - /* 10 */ "0x10", - /* 11 */ "0x11", - /* 12 */ "0x12", - /* 13 */ "0x13", - /* 14 */ "0x14", - /* 15 */ "0x15", - /* 16 */ "0x16", - /* 17 */ "0x17", - /* 18 */ "0x18", - /* 19 */ "0x19", - /* 1a */ "0x1a", - /* 1b */ "0x1b", - /* 1c */ "0x1c", - /* 1d */ "0x1d", - /* 1e */ "0x1e", - /* 1f */ "0x1f", - - /* 20 */ "0x20", - /* 21 */ "0x21", - /* 22 */ "0x22", - /* 23 */ "0x23", - /* 24 */ "0x24", - /* 25 */ "0x25", - /* 26 */ "0x26", - /* 27 */ "0x27", - /* 28 */ "0x28", - /* 29 */ "0x29", - /* 2a */ "0x2a", - /* 2b */ "0x2b", - /* 2c */ "0x2c", - /* 2d */ "0x2d", - /* 2e */ "0x2e", - /* 2f */ "0x2f", - - /* 30 */ "0x30", - /* 31 */ "0x31", - /* 32 */ "0x32", - /* 33 */ "0x33", - /* 34 */ "0x34", - /* 35 */ "0x35", - /* 36 */ "0x36", - /* 37 */ "0x37", - /* 38 */ "0x38", - /* 39 */ "0x39", - /* 3a */ "0x3a", - /* 3b */ "0x3b", - /* 3c */ "0x3c", - /* 3d */ "0x3d", - /* 3e */ "0x3e", - /* 3f */ "0x3f", -}; -#endif - - -const char *opcodes_04[0x40] = -{ - /* 00 */ "ADD", - /* 01 */ "ADC", - /* 02 */ "SUB", - /* 03 */ "SBC", - /* 04 */ "AND", - /* 05 */ "OR", - /* 06 */ "BIC", - /* 07 */ "XOR", - /* 08 */ "MAX", - /* 09 */ "MIN", - /* 0a */ "MOV", - /* 0b */ "TST", - /* 0c */ "CMP", - /* 0d */ "RCMP", - /* 0e */ "RSUB", - /* 0f */ "BSET", - - /* 10 */ "BCLR", - /* 11 */ "BTST", - /* 12 */ "BXOR", - /* 13 */ "BSMK", - /* 14 */ "ADD1", - /* 15 */ "ADD2", - /* 16 */ "ADD3", - /* 17 */ "SUB1", - /* 18 */ "SUB2", - /* 19 */ "SUB3", - /* 1a */ "MPY", - /* 1b */ "MPYH", - /* 1c */ "MPYHU", - /* 1d */ "MPYU", - /* 1e */ "0x1e", - /* 1f */ "0x1f", - - /* 20 */ "Jcc", - /* 21 */ "Jcc.D", - /* 22 */ "JLcc", - /* 23 */ "JLcc.D", - /* 24 */ "0x24", - /* 25 */ "0x25", - /* 26 */ "0x26", - /* 27 */ "0x27", - /* 28 */ "LPcc", - /* 29 */ "FLAG", - /* 2a */ "LR", - /* 2b */ "SR", - /* 2c */ "0x2c", - /* 2d */ "0x2d", - /* 2e */ "0x2e", - /* 2f */ "SOP table", - - /* 30 */ "LD", - /* 31 */ "LD", - /* 32 */ "LD", - /* 33 */ "LD", - /* 34 */ "LD", - /* 35 */ "LD", - /* 36 */ "LD", - /* 37 */ "LD", - /* 38 */ "0x38", - /* 39 */ "0x39", - /* 3a */ "0x3a", - /* 3b */ "0x3b", - /* 3c */ "0x3c", - /* 3d */ "0x3d", - /* 3e */ "0x3e", - /* 3f */ "0x3f", -}; diff --git a/src/devices/cpu/arcompact/arcompact_common.h b/src/devices/cpu/arcompact/arcompact_common.h deleted file mode 100644 index 86259ba2972..00000000000 --- a/src/devices/cpu/arcompact/arcompact_common.h +++ /dev/null @@ -1,24 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:David Haywood -/*********************************\ - - ARCompact Core - -\*********************************/ - -extern const char *conditions[0x20]; -extern const char *auxregnames[0x420]; -extern const char *datasize[0x4]; -extern const char *dataextend[0x2]; -extern const char *addressmode[0x4]; -extern const char *cachebit[0x2]; -extern const char *flagbit[0x2]; -extern const char *delaybit[0x2]; -extern const char *regnames[0x40]; -extern const char *opcodes_04[0x40]; - -#define REG_BLINK (0x1f) // r31 -#define REG_SP (0x1c) // r28 -#define REG_ILINK1 (0x1d) // r29 -#define REG_ILINK2 (0x1e) // r30 -#define REG_LP_COUNT (0x3c) // r60 diff --git a/src/devices/cpu/arcompact/arcompact_execute.cpp b/src/devices/cpu/arcompact/arcompact_execute.cpp index 53d3ce742cb..fc4dcca37a6 100644 --- a/src/devices/cpu/arcompact/arcompact_execute.cpp +++ b/src/devices/cpu/arcompact/arcompact_execute.cpp @@ -4,7 +4,13 @@ #include "emu.h" #include "debugger.h" #include "arcompact.h" -#include "arcompact_common.h" +#include "arcompactdasm.h" + +#define REG_BLINK (0x1f) // r31 +#define REG_SP (0x1c) // r28 +#define REG_ILINK1 (0x1d) // r29 +#define REG_ILINK2 (0x1e) // r30 +#define REG_LP_COUNT (0x3c) // r60 #define ARCOMPACT_LOGGING 1 @@ -128,35 +134,35 @@ int arcompact_device::check_condition(uint8_t condition) case 0x00: return 1; // AL case 0x01: return CONDITION_EQ; case 0x02: return !CONDITION_EQ; // NE - case 0x03: fatalerror("unhandled condition check %s", conditions[condition]); return -1; + case 0x03: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; case 0x04: return CONDITION_MI; // MI (N) case 0x05: return CONDITION_CS; // CS (Carry Set / Lower than) - case 0x06: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x07: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x08: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x09: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x0a: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x0b: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x0c: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x0d: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x0e: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x0f: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x10: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x11: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x12: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x13: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x14: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x15: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x16: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x17: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x18: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x19: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x1a: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x1b: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x1c: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x1d: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x1e: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x1f: fatalerror("unhandled condition check %s", conditions[condition]); return -1; + case 0x06: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x07: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x08: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x09: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x0a: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x0b: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x0c: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x0d: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x0e: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x0f: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x10: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x11: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x12: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x13: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x14: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x15: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x16: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x17: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x18: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x19: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x1a: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x1b: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x1c: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x1d: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x1e: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x1f: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; } return -1; @@ -1844,58 +1850,58 @@ ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_helper(OPS_32, const char ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_01(OPS_32) { - return arcompact_handle04_helper(PARAMS, opcodes_04[0x01], /*"ADC"*/ 0,0); + return arcompact_handle04_helper(PARAMS, arcompact_disassembler::opcodes_04[0x01], /*"ADC"*/ 0,0); } ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_03(OPS_32) { - return arcompact_handle04_helper(PARAMS, opcodes_04[0x03], /*"SBC"*/ 0,0); + return arcompact_handle04_helper(PARAMS, arcompact_disassembler::opcodes_04[0x03], /*"SBC"*/ 0,0); } ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_08(OPS_32) { - return arcompact_handle04_helper(PARAMS, opcodes_04[0x08], /*"MAX"*/ 0,0); + return arcompact_handle04_helper(PARAMS, arcompact_disassembler::opcodes_04[0x08], /*"MAX"*/ 0,0); } ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_09(OPS_32) { - return arcompact_handle04_helper(PARAMS, opcodes_04[0x09], /*"MIN"*/ 0,0); + return arcompact_handle04_helper(PARAMS, arcompact_disassembler::opcodes_04[0x09], /*"MIN"*/ 0,0); } ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_0b(OPS_32) { - return arcompact_handle04_helper(PARAMS, opcodes_04[0x0b], /*"TST"*/ 1,0); + return arcompact_handle04_helper(PARAMS, arcompact_disassembler::opcodes_04[0x0b], /*"TST"*/ 1,0); } ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_0c(OPS_32) { - return arcompact_handle04_helper(PARAMS, opcodes_04[0x0c], /*"CMP"*/ 1,0); + return arcompact_handle04_helper(PARAMS, arcompact_disassembler::opcodes_04[0x0c], /*"CMP"*/ 1,0); } ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_0d(OPS_32) { - return arcompact_handle04_helper(PARAMS, opcodes_04[0x0d], /*"RCMP"*/ 1,0); + return arcompact_handle04_helper(PARAMS, arcompact_disassembler::opcodes_04[0x0d], /*"RCMP"*/ 1,0); } ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_10(OPS_32) { - return arcompact_handle04_helper(PARAMS, opcodes_04[0x10], /*"BCLR"*/ 0,0); + return arcompact_handle04_helper(PARAMS, arcompact_disassembler::opcodes_04[0x10], /*"BCLR"*/ 0,0); } ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_11(OPS_32) { - return arcompact_handle04_helper(PARAMS, opcodes_04[0x11], /*"BTST"*/ 0,0); + return arcompact_handle04_helper(PARAMS, arcompact_disassembler::opcodes_04[0x11], /*"BTST"*/ 0,0); } ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_12(OPS_32) { - return arcompact_handle04_helper(PARAMS, opcodes_04[0x12], /*"BXOR"*/ 0,0); + return arcompact_handle04_helper(PARAMS, arcompact_disassembler::opcodes_04[0x12], /*"BXOR"*/ 0,0); } @@ -1905,22 +1911,22 @@ ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_12(OPS_32) ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_1a(OPS_32) { - return arcompact_handle04_helper(PARAMS, opcodes_04[0x1a], /*"MPY"*/ 0,0); + return arcompact_handle04_helper(PARAMS, arcompact_disassembler::opcodes_04[0x1a], /*"MPY"*/ 0,0); } // * ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_1b(OPS_32) { - return arcompact_handle04_helper(PARAMS, opcodes_04[0x1b], /*"MPYH"*/ 0,0); + return arcompact_handle04_helper(PARAMS, arcompact_disassembler::opcodes_04[0x1b], /*"MPYH"*/ 0,0); } // * ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_1c(OPS_32) { - return arcompact_handle04_helper(PARAMS, opcodes_04[0x1c], /*"MPYHU"*/ 0,0); + return arcompact_handle04_helper(PARAMS, arcompact_disassembler::opcodes_04[0x1c], /*"MPYHU"*/ 0,0); } // * ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_1d(OPS_32) { - return arcompact_handle04_helper(PARAMS, opcodes_04[0x1d], /*"MPYU"*/ 0,0); + return arcompact_handle04_helper(PARAMS, arcompact_disassembler::opcodes_04[0x1d], /*"MPYU"*/ 0,0); } // * ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_20_p00(OPS_32) @@ -2202,12 +2208,12 @@ ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_21_p11_m1(OPS_32) ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_22(OPS_32) { - return arcompact_handle04_helper(PARAMS, opcodes_04[0x22], /*"JL"*/ 1,1); + return arcompact_handle04_helper(PARAMS, arcompact_disassembler::opcodes_04[0x22], /*"JL"*/ 1,1); } ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_23(OPS_32) { - return arcompact_handle04_helper(PARAMS, opcodes_04[0x23], /*"JL.D"*/ 1,1); + return arcompact_handle04_helper(PARAMS, arcompact_disassembler::opcodes_04[0x23], /*"JL.D"*/ 1,1); } @@ -2238,7 +2244,7 @@ ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_28(OPS_32) // LPcc (loop { // 0010 0RRR 1110 1000 0RRR uuuu uu1Q QQQQ COMMON32_GET_u6 COMMON32_GET_CONDITION - //arcompact_fatal("Lp conditional %s not supported %d", conditions[condition], u); + //arcompact_fatal("Lp conditional %s not supported %d", arcompact_disassembler::conditions[condition], u); // if the loop condition fails then just jump to after the end of the loop, don't set any registers if (!check_condition(condition)) @@ -2264,7 +2270,7 @@ ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_28(OPS_32) // LPcc (loop ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_29(OPS_32) { // leapster bios uses formats for FLAG that are not defined, bug I guess work anyway (P modes 0 / 1) - return arcompact_handle04_helper(PARAMS, opcodes_04[0x29], /*"FLAG"*/ 1,1); + return arcompact_handle04_helper(PARAMS, arcompact_disassembler::opcodes_04[0x29], /*"FLAG"*/ 1,1); } diff --git a/src/devices/cpu/arcompact/arcompactdasm.cpp b/src/devices/cpu/arcompact/arcompactdasm.cpp index cd557017332..7283cfd06b6 100644 --- a/src/devices/cpu/arcompact/arcompactdasm.cpp +++ b/src/devices/cpu/arcompact/arcompactdasm.cpp @@ -7,51 +7,564 @@ \*********************************/ #include "emu.h" -#include <stdarg.h> +#include "arcompactdasm.h" -#include "arcompactdasm_dispatch.h" -#include "arcompactdasm_ops.h" +u32 arcompact_disassembler::opcode_alignment() const +{ + return 2; +} + + +// condition codes (basic ones are the same as arc +const char *const arcompact_disassembler::conditions[0x20] = +{ + /* 00 */ "AL", // (aka RA - Always) + /* 01 */ "EQ", // (aka Z - Zero + /* 02 */ "NE", // (aka NZ - Non-Zero) + /* 03 */ "PL", // (aka P - Positive) + /* 04 */ "MI", // (aka N - Negative) + /* 05 */ "CS", // (aka C, LO - Carry set / Lower than) (unsigned) + /* 06 */ "CC", // (aka CC, NC, HS - Carry Clear / Higher or Same) (unsigned) + /* 07 */ "VS", // (aka V - Overflow set) + /* 08 */ "VC", // (aka NV - Overflow clear) + /* 09 */ "GT", // ( - Greater than) (signed) + /* 0a */ "GE", // ( - Greater than or Equal) (signed) + /* 0b */ "LT", // ( - Less than) (signed) + /* 0c */ "LE", // ( - Less than or Equal) (signed) + /* 0d */ "HI", // ( - Higher than) (unsigned) + /* 0e */ "LS", // ( - Lower or Same) (unsigned) + /* 0f */ "PNZ",// ( - Positive non-0 value) + /* 10 */ "0x10 Reserved", // possible CPU implementation specifics + /* 11 */ "0x11 Reserved", + /* 12 */ "0x12 Reserved", + /* 13 */ "0x13 Reserved", + /* 14 */ "0x14 Reserved", + /* 15 */ "0x15 Reserved", + /* 16 */ "0x16 Reserved", + /* 17 */ "0x17 Reserved", + /* 18 */ "0x18 Reserved", + /* 19 */ "0x19 Reserved", + /* 1a */ "0x1a Reserved", + /* 1b */ "0x1b Reserved", + /* 1c */ "0x1c Reserved", + /* 1d */ "0x1d Reserved", + /* 1e */ "0x1e Reserved", + /* 1f */ "0x1f Reserved" +}; + +#define UNUSED_REG "unusedreg" + +#define AUX_UNUSED_16 \ + /* 0xxx0 */ UNUSED_REG, /* 0xxx1 */ UNUSED_REG, /* 0xxx2 */ UNUSED_REG, /* 0xxx3 */ UNUSED_REG, /* 0xxx4 */ UNUSED_REG, /* 0xxx5 */ UNUSED_REG, /* 0xxx6 */ UNUSED_REG, /* 0xxx7 */ UNUSED_REG, /* 0xxx8 */ UNUSED_REG, /* 0xxx9 */ UNUSED_REG, /* 0xxxa */ UNUSED_REG, /* 0xxxb */ UNUSED_REG, /* 0xxxc */ UNUSED_REG, /* 0xxxd */ UNUSED_REG, /* 0xxxe */ UNUSED_REG, /* 0xxxf */ UNUSED_REG, + +// the Auxiliary Register set is actually a 2^32 dword address space (so 16 GB / 34-bit) +// this table just allows us to improve the debugger display for some of the common core / internal ones +const char *const arcompact_disassembler::auxregnames[0x420] = +{ + /* 0x000 */ "STATUS", + /* 0x001 */ "SEMAPHOR", + /* 0x002 */ "LP_START", + /* 0x003 */ "LP_END", + /* 0x004 */ "IDENTITY", + /* 0x005 */ "DEBUG", + /* 0x006 */ "PC", + /* 0x007 */ UNUSED_REG, + /* 0x008 */ UNUSED_REG, + /* 0x009 */ UNUSED_REG, + /* 0x00a */ "STATUS32", + /* 0x00b */ "STATUS32_L1", + /* 0x00c */ "STATUS32_L2", + /* 0x00d */ UNUSED_REG, + /* 0x00e */ UNUSED_REG, + /* 0x00f */ UNUSED_REG, + + /* 0x010 */ UNUSED_REG, + /* 0x011 */ UNUSED_REG, + /* 0x012 */ "MULHI", // extension register + /* 0x013 */ UNUSED_REG, + /* 0x014 */ UNUSED_REG, + /* 0x015 */ UNUSED_REG, + /* 0x016 */ UNUSED_REG, + /* 0x017 */ UNUSED_REG, + /* 0x018 */ UNUSED_REG, + /* 0x019 */ UNUSED_REG, + /* 0x01a */ UNUSED_REG, + /* 0x01b */ UNUSED_REG, + /* 0x01c */ UNUSED_REG, + /* 0x01d */ UNUSED_REG, + /* 0x01e */ UNUSED_REG, + /* 0x01f */ UNUSED_REG, + /* 0x020 */ UNUSED_REG, + /* 0x021 */ "COUNT0", + /* 0x022 */ "CONTROL0", + /* 0x023 */ "LIMIT0", + /* 0x024 */ UNUSED_REG, + /* 0x025 */ "INT_VECTOR_BASE", + /* 0x026 */ UNUSED_REG, + /* 0x027 */ UNUSED_REG, + /* 0x028 */ UNUSED_REG, + /* 0x029 */ UNUSED_REG, + /* 0x02a */ UNUSED_REG, + /* 0x02b */ UNUSED_REG, + /* 0x02c */ UNUSED_REG, + /* 0x02d */ UNUSED_REG, + /* 0x02e */ UNUSED_REG, + /* 0x02f */ UNUSED_REG, + AUX_UNUSED_16 /* 0x030 - 0x03f */ + /* 0x040 */ UNUSED_REG, + /* 0x041 */ "AUX_MACMODE", + /* 0x042 */ UNUSED_REG, + /* 0x043 */ "AUX_IRQLV12", + /* 0x044 */ UNUSED_REG, + /* 0x045 */ UNUSED_REG, + /* 0x046 */ UNUSED_REG, + /* 0x047 */ UNUSED_REG, + /* 0x048 */ UNUSED_REG, + /* 0x049 */ UNUSED_REG, + /* 0x04a */ UNUSED_REG, + /* 0x04b */ UNUSED_REG, + /* 0x04c */ UNUSED_REG, + /* 0x04d */ UNUSED_REG, + /* 0x04e */ UNUSED_REG, + /* 0x04f */ UNUSED_REG, + AUX_UNUSED_16 /* 0x050 - 0x05f */ + // build configuration registers 0x060 - 0x07f + /* 0x060 */ "RESERVED AUX 0x60",/* 0x061 */ "RESERVED AUX 0x61",/* 0x062 */ "RESERVED AUX 0x62",/* 0x063 */ "RESERVED AUX 0x63",/* 0x064 */ "RESERVED AUX 0x64",/* 0x065 */ "RESERVED AUX 0x65",/* 0x066 */ "RESERVED AUX 0x66",/* 0x067 */ "RESERVED AUX 0x67",/* 0x068 */ "RESERVED AUX 0x68",/* 0x069 */ "RESERVED AUX 0x69",/* 0x06a */ "RESERVED AUX 0x6a",/* 0x06b */ "RESERVED AUX 0x6b",/* 0x06c */ "RESERVED AUX 0x6c",/* 0x06d */ "RESERVED AUX 0x6d",/* 0x06e */ "RESERVED AUX 0x6e",/* 0x06f */ "RESERVED AUX 0x6f", + /* 0x070 */ "RESERVED AUX 0x70",/* 0x071 */ "RESERVED AUX 0x71",/* 0x072 */ "RESERVED AUX 0x72",/* 0x073 */ "RESERVED AUX 0x73",/* 0x074 */ "RESERVED AUX 0x74",/* 0x075 */ "RESERVED AUX 0x75",/* 0x076 */ "RESERVED AUX 0x76",/* 0x077 */ "RESERVED AUX 0x77",/* 0x078 */ "RESERVED AUX 0x78",/* 0x079 */ "RESERVED AUX 0x79",/* 0x07a */ "RESERVED AUX 0x7a",/* 0x07b */ "RESERVED AUX 0x7b",/* 0x07c */ "RESERVED AUX 0x7c",/* 0x07d */ "RESERVED AUX 0x7d",/* 0x07e */ "RESERVED AUX 0x7e",/* 0x07f */ "RESERVED AUX 0x7f", + AUX_UNUSED_16 /* 0x080 - 0x08f */ + AUX_UNUSED_16 /* 0x090 - 0x09f */ + AUX_UNUSED_16 /* 0x0a0 - 0x0af */ + AUX_UNUSED_16 /* 0x0b0 - 0x0bf */ + // build configuration registers 0x0c0 - 0x0ff + /* 0x0c0 */ "RESERVED AUX 0xc0",/* 0x0c1 */ "RESERVED AUX 0xc1",/* 0x0c2 */ "RESERVED AUX 0xc2",/* 0x0c3 */ "RESERVED AUX 0xc3",/* 0x0c4 */ "RESERVED AUX 0xc4",/* 0x0c5 */ "RESERVED AUX 0xc5",/* 0x0c6 */ "RESERVED AUX 0xc6",/* 0x0c7 */ "RESERVED AUX 0xc7",/* 0x0c8 */ "RESERVED AUX 0xc8",/* 0x0c9 */ "RESERVED AUX 0xc9",/* 0x0ca */ "RESERVED AUX 0xca",/* 0x0cb */ "RESERVED AUX 0xcb",/* 0x0cc */ "RESERVED AUX 0xcc",/* 0x0cd */ "RESERVED AUX 0xcd",/* 0x0ce */ "RESERVED AUX 0xce",/* 0x0cf */ "RESERVED AUX 0xcf", + /* 0x0d0 */ "RESERVED AUX 0xd0",/* 0x0d1 */ "RESERVED AUX 0xd1",/* 0x0d2 */ "RESERVED AUX 0xd2",/* 0x0d3 */ "RESERVED AUX 0xd3",/* 0x0d4 */ "RESERVED AUX 0xd4",/* 0x0d5 */ "RESERVED AUX 0xd5",/* 0x0d6 */ "RESERVED AUX 0xd6",/* 0x0d7 */ "RESERVED AUX 0xd7",/* 0x0d8 */ "RESERVED AUX 0xd8",/* 0x0d9 */ "RESERVED AUX 0xd9",/* 0x0da */ "RESERVED AUX 0xda",/* 0x0db */ "RESERVED AUX 0xdb",/* 0x0dc */ "RESERVED AUX 0xdc",/* 0x0dd */ "RESERVED AUX 0xdd",/* 0x0de */ "RESERVED AUX 0xde",/* 0x0df */ "RESERVED AUX 0xdf", + /* 0x0e0 */ "RESERVED AUX 0xe0",/* 0x0e1 */ "RESERVED AUX 0xe1",/* 0x0e2 */ "RESERVED AUX 0xe2",/* 0x0e3 */ "RESERVED AUX 0xe3",/* 0x0e4 */ "RESERVED AUX 0xe4",/* 0x0e5 */ "RESERVED AUX 0xe5",/* 0x0e6 */ "RESERVED AUX 0xe6",/* 0x0e7 */ "RESERVED AUX 0xe7",/* 0x0e8 */ "RESERVED AUX 0xe8",/* 0x0e9 */ "RESERVED AUX 0xe9",/* 0x0ea */ "RESERVED AUX 0xea",/* 0x0eb */ "RESERVED AUX 0xeb",/* 0x0ec */ "RESERVED AUX 0xec",/* 0x0ed */ "RESERVED AUX 0xed",/* 0x0ee */ "RESERVED AUX 0xee",/* 0x0ef */ "RESERVED AUX 0xef", + /* 0x0f0 */ "RESERVED AUX 0xf0",/* 0x0f1 */ "RESERVED AUX 0xf1",/* 0x0f2 */ "RESERVED AUX 0xf2",/* 0x0f3 */ "RESERVED AUX 0xf3",/* 0x0f4 */ "RESERVED AUX 0xf4",/* 0x0f5 */ "RESERVED AUX 0xf5",/* 0x0f6 */ "RESERVED AUX 0xf6",/* 0x0f7 */ "RESERVED AUX 0xf7",/* 0x0f8 */ "RESERVED AUX 0xf8",/* 0x0f9 */ "RESERVED AUX 0xf9",/* 0x0fa */ "RESERVED AUX 0xfa",/* 0x0fb */ "RESERVED AUX 0xfb",/* 0x0fc */ "RESERVED AUX 0xfc",/* 0x0fd */ "RESERVED AUX 0xfd",/* 0x0fe */ "RESERVED AUX 0xfe",/* 0x0ff */ "RESERVED AUX 0xff", + /* 0x100 */ "COUNT1", + /* 0x101 */ "CONTROL1", + /* 0x102 */ "LIMIT1", + /* 0x103 */ UNUSED_REG, + /* 0x104 */ UNUSED_REG, + /* 0x105 */ UNUSED_REG, + /* 0x106 */ UNUSED_REG, + /* 0x107 */ UNUSED_REG, + /* 0x108 */ UNUSED_REG, + /* 0x109 */ UNUSED_REG, + /* 0x10a */ UNUSED_REG, + /* 0x10b */ UNUSED_REG, + /* 0x10c */ UNUSED_REG, + /* 0x10d */ UNUSED_REG, + /* 0x10e */ UNUSED_REG, + /* 0x10f */ UNUSED_REG, + AUX_UNUSED_16 /* 0x110 - 0x11f */ + AUX_UNUSED_16 /* 0x120 - 0x12f */ + AUX_UNUSED_16 /* 0x130 - 0x13f */ + AUX_UNUSED_16 /* 0x140 - 0x14f */ + AUX_UNUSED_16 /* 0x150 - 0x15f */ + AUX_UNUSED_16 /* 0x160 - 0x16f */ + AUX_UNUSED_16 /* 0x170 - 0x17f */ + AUX_UNUSED_16 /* 0x180 - 0x18f */ + AUX_UNUSED_16 /* 0x190 - 0x19f */ + AUX_UNUSED_16 /* 0x1a0 - 0x1af */ + AUX_UNUSED_16 /* 0x1b0 - 0x1bf */ + AUX_UNUSED_16 /* 0x1c0 - 0x1cf */ + AUX_UNUSED_16 /* 0x1d0 - 0x1df */ + AUX_UNUSED_16 /* 0x1e0 - 0x1ef */ + AUX_UNUSED_16 /* 0x1f0 - 0x1ff */ + /* 0x200 */ "AUX_IRQ_LEV", + /* 0x201 */ "AUX_IRQ_HINT", + /* 0x203 */ UNUSED_REG, + /* 0x203 */ UNUSED_REG, + /* 0x204 */ UNUSED_REG, + /* 0x205 */ UNUSED_REG, + /* 0x206 */ UNUSED_REG, + /* 0x207 */ UNUSED_REG, + /* 0x208 */ UNUSED_REG, + /* 0x209 */ UNUSED_REG, + /* 0x20a */ UNUSED_REG, + /* 0x20b */ UNUSED_REG, + /* 0x20c */ UNUSED_REG, + /* 0x20d */ UNUSED_REG, + /* 0x20e */ UNUSED_REG, + /* 0x20f */ UNUSED_REG, + AUX_UNUSED_16 /* 0x210 - 0x21f */ + AUX_UNUSED_16 /* 0x220 - 0x22f */ + AUX_UNUSED_16 /* 0x230 - 0x23f */ + AUX_UNUSED_16 /* 0x240 - 0x24f */ + AUX_UNUSED_16 /* 0x250 - 0x25f */ + AUX_UNUSED_16 /* 0x260 - 0x26f */ + AUX_UNUSED_16 /* 0x270 - 0x27f */ + AUX_UNUSED_16 /* 0x280 - 0x28f */ + AUX_UNUSED_16 /* 0x290 - 0x29f */ + AUX_UNUSED_16 /* 0x2a0 - 0x2af */ + AUX_UNUSED_16 /* 0x2b0 - 0x2bf */ + AUX_UNUSED_16 /* 0x2c0 - 0x2cf */ + AUX_UNUSED_16 /* 0x2d0 - 0x2df */ + AUX_UNUSED_16 /* 0x2e0 - 0x2ef */ + AUX_UNUSED_16 /* 0x2f0 - 0x2ff */ -/*****************************************************************************/ + AUX_UNUSED_16 /* 0x300 - 0x30f */ + AUX_UNUSED_16 /* 0x310 - 0x31f */ + AUX_UNUSED_16 /* 0x320 - 0x32f */ + AUX_UNUSED_16 /* 0x330 - 0x33f */ + AUX_UNUSED_16 /* 0x340 - 0x34f */ + AUX_UNUSED_16 /* 0x350 - 0x35f */ + AUX_UNUSED_16 /* 0x360 - 0x36f */ + AUX_UNUSED_16 /* 0x370 - 0x37f */ + AUX_UNUSED_16 /* 0x380 - 0x38f */ + AUX_UNUSED_16 /* 0x390 - 0x39f */ + AUX_UNUSED_16 /* 0x3a0 - 0x3af */ + AUX_UNUSED_16 /* 0x3b0 - 0x3bf */ + AUX_UNUSED_16 /* 0x3c0 - 0x3cf */ + AUX_UNUSED_16 /* 0x3d0 - 0x3df */ + AUX_UNUSED_16 /* 0x3e0 - 0x3ef */ + AUX_UNUSED_16 /* 0x3f0 - 0x3ff */ + /* 0x400 */ "ERET", + /* 0x401 */ "ERBTA", + /* 0x403 */ "ERSTATUS", + /* 0x403 */ "ECR", + /* 0x404 */ "EFA", + /* 0x405 */ UNUSED_REG, + /* 0x406 */ UNUSED_REG, + /* 0x407 */ UNUSED_REG, + /* 0x408 */ UNUSED_REG, + /* 0x409 */ UNUSED_REG, + /* 0x40a */ "ICAUSE1", + /* 0x40b */ "ICAUSE2", + /* 0x40c */ "AUX_IENABLE", + /* 0x40d */ "AUX_ITRIGGER", + /* 0x40e */ UNUSED_REG, + /* 0x40f */ UNUSED_REG, + /* 0x410 */ "XPU", + /* 0x411 */ UNUSED_REG, + /* 0x412 */ "BTA", + /* 0x413 */ "BTA_L1", + /* 0x414 */ "BTA_L2", + /* 0x415 */ "AUX_IRQ_PULSE_CANCEL", + /* 0x416 */ "AUX_IRQ_PENDING", + /* 0x417 */ UNUSED_REG, + /* 0x418 */ UNUSED_REG, + /* 0x419 */ UNUSED_REG, + /* 0x41a */ UNUSED_REG, + /* 0x41b */ UNUSED_REG, + /* 0x41c */ UNUSED_REG, + /* 0x41d */ UNUSED_REG, + /* 0x41e */ UNUSED_REG, + /* 0x41f */ UNUSED_REG +}; + +//#define EXPLICIT_EXTENSIONS + +const char *const arcompact_disassembler::datasize[0x4] = +{ +#ifdef EXPLICIT_EXTENSIONS + /* 00 */ ".L", // Dword (default) (can use no extension, using .L to be explicit) +#else + /* 00 */ "",// Dword (default) +#endif + /* 01 */ ".B", // Byte + /* 02 */ ".W", // Word + /* 03 */ ".<illegal data size>" +}; + +const char *const arcompact_disassembler::dataextend[0x2] = +{ +#ifdef EXPLICIT_EXTENSIONS + /* 00 */ ".ZX", // Zero Extend (can use no extension, using .ZX to be explicit) +#else + /* 00 */ "", // Zero Extend +#endif + /* 01 */ ".X" // Sign Extend +}; + +const char *const arcompact_disassembler::addressmode[0x4] = +{ +#ifdef EXPLICIT_EXTENSIONS + /* 00 */ ".AN", // No Writeback (can use no extension, using .AN to be explicit) +#else + /* 00 */ "", // No Writeback +#endif + /* 01 */ ".AW", // Writeback pre memory access + /* 02 */ ".AB", // Writeback post memory access + /* 03 */ ".AS" // scaled +}; + +const char *const arcompact_disassembler::cachebit[0x2] = +{ +#ifdef EXPLICIT_EXTENSIONS + /* 00 */ ".EN", // Data Cache Enabled (can use no extension, using .EN to be explicit) +#else + /* 00 */ "", // Data Cache Enabled +#endif + /* 01 */ ".DI" // Direct to Memory (Cache Bypass) +}; + +const char *const arcompact_disassembler::flagbit[0x2] = +{ +#ifdef EXPLICIT_EXTENSIONS + /* 00 */ ".NF", // Don't Set Flags (can use no extension, using .NF to be explicit) +#else + /* 00 */ "", // Don't Set Flags +#endif + /* 01 */ ".F" // Set Flags +}; + +const char *const arcompact_disassembler::delaybit[0x2] = +{ + /* 00 */ ".ND", // Don't execute opcode in delay slot + /* 01 */ ".D" // Execute Opcode in delay slot +}; + + +const char *const arcompact_disassembler::regnames[0x40] = +{ + /* 00 */ "r0", + /* 01 */ "r1", + /* 02 */ "r2", + /* 03 */ "r3", + /* 04 */ "r4", + /* 05 */ "r5", + /* 06 */ "r6", + /* 07 */ "r7", + /* 08 */ "r8", + /* 09 */ "r9", + /* 0a */ "r10", + /* 0b */ "r11", + /* 0c */ "r12", + /* 0d */ "r13", + /* 0e */ "r14", + /* 0f */ "r15", + + /* 10 */ "r16", + /* 11 */ "r17", + /* 12 */ "r18", + /* 13 */ "r19", + /* 14 */ "r20", + /* 15 */ "r21", + /* 16 */ "r22", + /* 17 */ "r23", + /* 18 */ "r24", + /* 19 */ "r25", + /* 1a */ "r26_GP", + /* 1b */ "r27_FP", + /* 1c */ "r28_SP", + /* 1d */ "r29_ILINK1", + /* 1e */ "r30_ILINK2", + /* 1f */ "r31_BLINK", + + /* 20 */ "r32(ext)", + /* 21 */ "r33(ext)", + /* 22 */ "r34(ext)", + /* 23 */ "r35(ext)", + /* 24 */ "r36(ext)", + /* 25 */ "r37(ext)", + /* 26 */ "r38(ext)", + /* 27 */ "r39(ext)", + /* 28 */ "r40(ext)", + /* 29 */ "r41(ext)", + /* 2a */ "r42(ext)", + /* 2b */ "r43(ext)", + /* 2c */ "r44(ext)", + /* 2d */ "r45(ext)", + /* 2e */ "r46(ext)", + /* 2f */ "r47(ext)", + + /* 30 */ "r48(ext)", + /* 31 */ "r49(ext)", + /* 32 */ "r50(ext)", + /* 33 */ "r51(ext)", + /* 34 */ "r52(ext)", + /* 35 */ "r53(ext)", + /* 36 */ "r54(ext)", + /* 37 */ "r55(ext)", + /* 38 */ "r56(ext)", + /* 39 */ "r57(M-LO)", // MLO (result registers for optional multply functions) + /* 3a */ "r58(M-MID)", // MMID + /* 3b */ "r59(M-HI)", // MHI + /* 3c */ "r60(LP_COUNT)", + /* 3d */ "r61(reserved)", + /* 3e */ "r62(LIMM)", // use Long Immediate Data instead of register + /* 3f */ "r63(PCL)" +}; + +#if 0 +const char *const arcompact_disassembler::opcodes_temp[0x40] = +{ + /* 00 */ "0x00", + /* 01 */ "0x01", + /* 02 */ "0x02", + /* 03 */ "0x03", + /* 04 */ "0x04", + /* 05 */ "0x05", + /* 06 */ "0x06", + /* 07 */ "0x07", + /* 08 */ "0x08", + /* 09 */ "0x09", + /* 0a */ "0x0a", + /* 0b */ "0x0b", + /* 0c */ "0x0c", + /* 0d */ "0x0d", + /* 0e */ "0x0e", + /* 0f */ "0x0f", + + /* 10 */ "0x10", + /* 11 */ "0x11", + /* 12 */ "0x12", + /* 13 */ "0x13", + /* 14 */ "0x14", + /* 15 */ "0x15", + /* 16 */ "0x16", + /* 17 */ "0x17", + /* 18 */ "0x18", + /* 19 */ "0x19", + /* 1a */ "0x1a", + /* 1b */ "0x1b", + /* 1c */ "0x1c", + /* 1d */ "0x1d", + /* 1e */ "0x1e", + /* 1f */ "0x1f", + + /* 20 */ "0x20", + /* 21 */ "0x21", + /* 22 */ "0x22", + /* 23 */ "0x23", + /* 24 */ "0x24", + /* 25 */ "0x25", + /* 26 */ "0x26", + /* 27 */ "0x27", + /* 28 */ "0x28", + /* 29 */ "0x29", + /* 2a */ "0x2a", + /* 2b */ "0x2b", + /* 2c */ "0x2c", + /* 2d */ "0x2d", + /* 2e */ "0x2e", + /* 2f */ "0x2f", + + /* 30 */ "0x30", + /* 31 */ "0x31", + /* 32 */ "0x32", + /* 33 */ "0x33", + /* 34 */ "0x34", + /* 35 */ "0x35", + /* 36 */ "0x36", + /* 37 */ "0x37", + /* 38 */ "0x38", + /* 39 */ "0x39", + /* 3a */ "0x3a", + /* 3b */ "0x3b", + /* 3c */ "0x3c", + /* 3d */ "0x3d", + /* 3e */ "0x3e", + /* 3f */ "0x3f", +}; +#endif + + +const char *const arcompact_disassembler::opcodes_04[0x40] = +{ + /* 00 */ "ADD", + /* 01 */ "ADC", + /* 02 */ "SUB", + /* 03 */ "SBC", + /* 04 */ "AND", + /* 05 */ "OR", + /* 06 */ "BIC", + /* 07 */ "XOR", + /* 08 */ "MAX", + /* 09 */ "MIN", + /* 0a */ "MOV", + /* 0b */ "TST", + /* 0c */ "CMP", + /* 0d */ "RCMP", + /* 0e */ "RSUB", + /* 0f */ "BSET", -/*****************************************************************************/ + /* 10 */ "BCLR", + /* 11 */ "BTST", + /* 12 */ "BXOR", + /* 13 */ "BSMK", + /* 14 */ "ADD1", + /* 15 */ "ADD2", + /* 16 */ "ADD3", + /* 17 */ "SUB1", + /* 18 */ "SUB2", + /* 19 */ "SUB3", + /* 1a */ "MPY", + /* 1b */ "MPYH", + /* 1c */ "MPYHU", + /* 1d */ "MPYU", + /* 1e */ "0x1e", + /* 1f */ "0x1f", + /* 20 */ "Jcc", + /* 21 */ "Jcc.D", + /* 22 */ "JLcc", + /* 23 */ "JLcc.D", + /* 24 */ "0x24", + /* 25 */ "0x25", + /* 26 */ "0x26", + /* 27 */ "0x27", + /* 28 */ "LPcc", + /* 29 */ "FLAG", + /* 2a */ "LR", + /* 2b */ "SR", + /* 2c */ "0x2c", + /* 2d */ "0x2d", + /* 2e */ "0x2e", + /* 2f */ "SOP table", -#define ARCOMPACT_OPERATION ((op & 0xf800) >> 11) + /* 30 */ "LD", + /* 31 */ "LD", + /* 32 */ "LD", + /* 33 */ "LD", + /* 34 */ "LD", + /* 35 */ "LD", + /* 36 */ "LD", + /* 37 */ "LD", + /* 38 */ "0x38", + /* 39 */ "0x39", + /* 3a */ "0x3a", + /* 3b */ "0x3b", + /* 3c */ "0x3c", + /* 3d */ "0x3d", + /* 3e */ "0x3e", + /* 3f */ "0x3f", +}; -CPU_DISASSEMBLE(arcompact) +offs_t arcompact_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { int size; - uint32_t op = oprom[0] | (oprom[1] << 8); + uint32_t op = opcodes.r16(pc); - uint8_t instruction = ARCOMPACT_OPERATION; + uint8_t instruction = ((op & 0xf800) >> 11); if (instruction < 0x0c) { size = 4; op <<= 16; - op |= oprom[2] | (oprom[3] << 8); + op |= opcodes.r16(pc+2); op &= ~0xf8000000; switch (instruction) // 32-bit instructions (with optional extra dword for immediate data) { - case 0x00: size = arcompact_handle00_dasm(DASM_PARAMS); break; // Bcc - case 0x01: size = arcompact_handle01_dasm(DASM_PARAMS); break; // BLcc/BRcc - case 0x02: size = arcompact_handle02_dasm(DASM_PARAMS); break; // LD r+o - case 0x03: size = arcompact_handle03_dasm(DASM_PARAMS); break; // ST r+o - case 0x04: size = arcompact_handle04_dasm(DASM_PARAMS); break; // op a,b,c (basecase) - case 0x05: size = arcompact_handle05_dasm(DASM_PARAMS); break; // op a,b,c (05 ARC ext) - case 0x06: size = arcompact_handle06_dasm(DASM_PARAMS); break; // op a,b,c (06 ARC ext) - case 0x07: size = arcompact_handle07_dasm(DASM_PARAMS); break; // op a,b,c (07 User ext) - case 0x08: size = arcompact_handle08_dasm(DASM_PARAMS); break; // op a,b,c (08 User ext) - case 0x09: size = arcompact_handle09_dasm(DASM_PARAMS); break; // op a,b,c (09 Market ext) - case 0x0a: size = arcompact_handle0a_dasm(DASM_PARAMS); break; // op a,b,c (0a Market ext) - case 0x0b: size = arcompact_handle0b_dasm(DASM_PARAMS); break; // op a,b,c (0b Market ext) + case 0x00: size = handle00_dasm(stream, pc, op, opcodes); break; // Bcc + case 0x01: size = handle01_dasm(stream, pc, op, opcodes); break; // BLcc/BRcc + case 0x02: size = handle02_dasm(stream, pc, op, opcodes); break; // LD r+o + case 0x03: size = handle03_dasm(stream, pc, op, opcodes); break; // ST r+o + case 0x04: size = handle04_dasm(stream, pc, op, opcodes); break; // op a,b,c (basecase) + case 0x05: size = handle05_dasm(stream, pc, op, opcodes); break; // op a,b,c (05 ARC ext) + case 0x06: size = handle06_dasm(stream, pc, op, opcodes); break; // op a,b,c (06 ARC ext) + case 0x07: size = handle07_dasm(stream, pc, op, opcodes); break; // op a,b,c (07 User ext) + case 0x08: size = handle08_dasm(stream, pc, op, opcodes); break; // op a,b,c (08 User ext) + case 0x09: size = handle09_dasm(stream, pc, op, opcodes); break; // op a,b,c (09 Market ext) + case 0x0a: size = handle0a_dasm(stream, pc, op, opcodes); break; // op a,b,c (0a Market ext) + case 0x0b: size = handle0b_dasm(stream, pc, op, opcodes); break; // op a,b,c (0b Market ext) } } else @@ -62,28 +575,28 @@ CPU_DISASSEMBLE(arcompact) switch (instruction) // 16-bit instructions { - case 0x0c: size = arcompact_handle0c_dasm(DASM_PARAMS); break; // Load/Add reg-reg - case 0x0d: size = arcompact_handle0d_dasm(DASM_PARAMS); break; // Add/Sub/Shft imm - case 0x0e: size = arcompact_handle0e_dasm(DASM_PARAMS); break; // Mov/Cmp/Add - case 0x0f: size = arcompact_handle0f_dasm(DASM_PARAMS); break; // op_S b,b,c (single 16-bit ops) - case 0x10: size = arcompact_handle10_dasm(DASM_PARAMS); break; // LD_S - case 0x11: size = arcompact_handle11_dasm(DASM_PARAMS); break; // LDB_S - case 0x12: size = arcompact_handle12_dasm(DASM_PARAMS); break; // LDW_S - case 0x13: size = arcompact_handle13_dasm(DASM_PARAMS); break; // LSW_S.X - case 0x14: size = arcompact_handle14_dasm(DASM_PARAMS); break; // ST_S - case 0x15: size = arcompact_handle15_dasm(DASM_PARAMS); break; // STB_S - case 0x16: size = arcompact_handle16_dasm(DASM_PARAMS); break; // STW_S - case 0x17: size = arcompact_handle17_dasm(DASM_PARAMS); break; // Shift/Sub/Bit - case 0x18: size = arcompact_handle18_dasm(DASM_PARAMS); break; // Stack Instr - case 0x19: size = arcompact_handle19_dasm(DASM_PARAMS); break; // GP Instr - case 0x1a: size = arcompact_handle1a_dasm(DASM_PARAMS); break; // PCL Instr - case 0x1b: size = arcompact_handle1b_dasm(DASM_PARAMS); break; // MOV_S - case 0x1c: size = arcompact_handle1c_dasm(DASM_PARAMS); break; // ADD_S/CMP_S - case 0x1d: size = arcompact_handle1d_dasm(DASM_PARAMS); break; // BRcc_S - case 0x1e: size = arcompact_handle1e_dasm(DASM_PARAMS); break; // Bcc_S - case 0x1f: size = arcompact_handle1f_dasm(DASM_PARAMS); break; // BL_S + case 0x0c: size = handle0c_dasm(stream, pc, op, opcodes); break; // Load/Add reg-reg + case 0x0d: size = handle0d_dasm(stream, pc, op, opcodes); break; // Add/Sub/Shft imm + case 0x0e: size = handle0e_dasm(stream, pc, op, opcodes); break; // Mov/Cmp/Add + case 0x0f: size = handle0f_dasm(stream, pc, op, opcodes); break; // op_S b,b,c (single 16-bit ops) + case 0x10: size = handle10_dasm(stream, pc, op, opcodes); break; // LD_S + case 0x11: size = handle11_dasm(stream, pc, op, opcodes); break; // LDB_S + case 0x12: size = handle12_dasm(stream, pc, op, opcodes); break; // LDW_S + case 0x13: size = handle13_dasm(stream, pc, op, opcodes); break; // LSW_S.X + case 0x14: size = handle14_dasm(stream, pc, op, opcodes); break; // ST_S + case 0x15: size = handle15_dasm(stream, pc, op, opcodes); break; // STB_S + case 0x16: size = handle16_dasm(stream, pc, op, opcodes); break; // STW_S + case 0x17: size = handle17_dasm(stream, pc, op, opcodes); break; // Shift/Sub/Bit + case 0x18: size = handle18_dasm(stream, pc, op, opcodes); break; // Stack Instr + case 0x19: size = handle19_dasm(stream, pc, op, opcodes); break; // GP Instr + case 0x1a: size = handle1a_dasm(stream, pc, op, opcodes); break; // PCL Instr + case 0x1b: size = handle1b_dasm(stream, pc, op, opcodes); break; // MOV_S + case 0x1c: size = handle1c_dasm(stream, pc, op, opcodes); break; // ADD_S/CMP_S + case 0x1d: size = handle1d_dasm(stream, pc, op, opcodes); break; // BRcc_S + case 0x1e: size = handle1e_dasm(stream, pc, op, opcodes); break; // Bcc_S + case 0x1f: size = handle1f_dasm(stream, pc, op, opcodes); break; // BL_S } } - return size | DASMFLAG_SUPPORTED; + return size | SUPPORTED; } diff --git a/src/devices/cpu/arcompact/arcompactdasm.h b/src/devices/cpu/arcompact/arcompactdasm.h new file mode 100644 index 00000000000..7594c673a0d --- /dev/null +++ b/src/devices/cpu/arcompact/arcompactdasm.h @@ -0,0 +1,721 @@ +// license:BSD-3-Clause +// copyright-holders:David Haywood +/*********************************\ + + ARCompact disassembler + +\*********************************/ + + +#ifndef MAME_CPU_ARCOMPACT_ARCOMPACTDASM_H +#define MAME_CPU_ARCOMPACT_ARCOMPACTDASM_H + +#pragma once + +class arcompact_disassembler : public util::disasm_interface +{ +public: + arcompact_disassembler() = default; + virtual ~arcompact_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + + static const char *const conditions[0x20]; + static const char *const auxregnames[0x420]; + static const char *const datasize[0x4]; + static const char *const dataextend[0x2]; + static const char *const addressmode[0x4]; + static const char *const cachebit[0x2]; + static const char *const flagbit[0x2]; + static const char *const delaybit[0x2]; + static const char *const regnames[0x40]; + static const char *const opcodes_04[0x40]; + +private: + int handle01_01_00_helper(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext); + int handle01_01_01_helper(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext); + + int handle04_p00_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext, int ignore_dst, int b_reserved); + int handle04_p01_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext, int ignore_dst, int b_reserved); + int handle04_p10_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext, int b_reserved); + int handle04_p11_m0_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext, int b_reserved); + int handle04_p11_m1_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext, int b_reserved); + int handle04_p11_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext, int b_reserved); + int handle04_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext, int ignore_dst, int b_reserved); + int handle04_2f_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext); + int handle04_3x_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, int dsize, int extend); + int handle05_2f_0x_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext); + int handle0c_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext, int format); + int handle0d_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext); + int handle0e_0x_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext, int revop); + int handle0f_00_0x_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext); + int handle0f_0x_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext, int nodst); + int handle_ld_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext, int shift, int swap); + int handle_l7_0x_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext); + int handle18_0x_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext, int st, int format); + int handle19_0x_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext, int shift, int format); + int handle1d_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext); + int handle1e_0x_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext); + int handle1e_03_0x_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext); + + int handle00_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle00_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_00_00dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_00_01dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_00_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_00_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_00_02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_00_03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_00_04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_00_05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_00_0e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_00_0f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_01_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_01_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_01_02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_01_03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_01_04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_01_05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_01_0e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_01_0f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_0c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_0d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_0e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_0f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_10_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_11_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_12_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_13_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_14_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_15_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_16_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_17_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_18_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_19_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_1a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_1b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_1c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_1d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_20_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_21_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_22_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_23_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_28_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_29_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_0c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_30_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_31_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_32_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_33_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_34_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_35_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_36_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_37_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_28_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_29_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + + int handle06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + + int handle0c_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0c_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0c_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0c_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0d_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0d_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0d_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0d_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0e_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0e_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0e_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0e_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_00_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_00_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_00_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_00_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_00_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_00_07_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_00_07_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_00_07_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_00_07_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_00_07_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_00_07_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_0b_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_0c_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_0d_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_0e_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_0f_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_10_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_11_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_12_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_13_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_14_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_15_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_16_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_18_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_19_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_1a_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_1b_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_1c_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_1d_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_1e_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_1f_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle10_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle11_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle12_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle13_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle14_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle15_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle16_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle17_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle17_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle17_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle17_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle17_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle17_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle17_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle17_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_05_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_05_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_11_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_11_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle19_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle19_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle19_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle19_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1a_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1b_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1c_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1c_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1d_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1d_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1e_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1e_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1e_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1e_03_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1e_03_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1e_03_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1e_03_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1e_03_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1e_03_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1e_03_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1e_03_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1f_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + + /************************************************************************************************************************************ + * * + * illegal opcode handlers (disassembly) * + * * + ************************************************************************************************************************************/ + + int handle01_01_00_06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_00_07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_00_08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_00_09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_00_0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_00_0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_00_0c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_00_0d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + + int handle01_01_01_06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_01_07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_01_08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_01_09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_01_0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_01_0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_01_0c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_01_0d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + + + int handle04_1e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_1f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + + int handle04_24_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_25_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_26_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_27_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + + int handle04_2c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + + int handle04_2f_0d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_0e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_0f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_10_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_11_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_12_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_13_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_14_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_15_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_16_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_17_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_18_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_19_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_1a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_1b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_1c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_1d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_1e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_1f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_20_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_21_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_22_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_23_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_24_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_25_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_26_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_27_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_28_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_29_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_2a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_2b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_2c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_2d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_2e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_2f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_30_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_31_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_32_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_33_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_34_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_35_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_36_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_37_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_38_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_39_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + + int handle04_2f_3f_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_0c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_0d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_0e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_0f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_10_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_11_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_12_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_13_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_14_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_15_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_16_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_17_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_18_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_19_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_1a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_1b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_1c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_1d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_1e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_1f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_20_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_21_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_22_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_23_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_24_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_25_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_26_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_27_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_28_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_29_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_2a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_2b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_2c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_2d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_2e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_2f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_30_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_31_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_32_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_33_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_34_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_35_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_36_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_37_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_38_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_39_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_3a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_3b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_3c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_3d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_3e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_3f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + + int handle05_2f_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_0c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_0d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_0e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_0f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_10_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_11_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_12_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_13_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_14_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_15_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_16_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_17_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_18_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_19_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_1a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_1b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_1c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_1d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_1e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_1f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_20_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_21_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_22_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_23_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_24_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_25_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_26_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_27_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_28_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_29_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_2a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_2b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_2c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_2d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_2e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_2f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_30_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_31_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_32_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_33_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_34_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_35_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_36_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_37_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_38_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_39_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + + int handle05_2f_3f_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_0c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_0d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_0e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_0f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_10_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_11_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_12_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_13_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_14_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_15_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_16_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_17_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_18_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_19_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_1a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_1b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_1c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_1d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_1e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_1f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_20_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_21_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_22_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_23_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_24_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_25_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_26_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_27_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_28_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_29_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_2a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_2b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_2c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_2d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_2e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_2f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_30_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_31_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_32_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_33_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_34_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_35_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_36_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_37_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_38_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_39_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_3a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_3b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_3c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_3d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_3e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_3f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + + + int handle04_38_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_39_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_3a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_3b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_3c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_3d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_3e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_3f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + + int handle05_09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_0c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_0d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_0e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_0f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_10_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_11_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_12_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_13_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_14_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_15_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_16_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_17_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_18_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_19_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_1a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_1b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_1c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_1d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_1e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_1f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_20_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_21_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_22_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_23_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_24_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_25_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_26_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_27_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + + int handle05_2a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + + int handle05_30_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_31_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_32_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_33_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_34_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_35_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_36_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_37_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_38_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_39_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_3a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_3b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_3c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_3d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_3e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_3f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + + int handle0f_00_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_00_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_00_07_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_00_07_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_08_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_09_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_0a_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_17_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + + int handle18_05_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_05_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_05_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_05_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_05_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_05_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_08_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_09_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_0a_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_0b_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_0c_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_0d_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_0e_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_0f_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_10_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_12_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_13_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_14_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_15_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_16_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_17_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_18_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_19_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_1a_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_1b_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_1c_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_1d_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_1e_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_1f_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_08_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_09_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_0a_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_0b_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_0c_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_0d_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_0e_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_0f_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_10_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_12_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_13_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_14_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_15_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_16_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_17_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_18_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_19_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_1a_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_1b_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_1c_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_1d_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_1e_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_1f_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + + + + + int handle00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + + int handle05_2f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + + + int handle0c_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0d_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0e_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_00_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle17_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle19_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1c_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1d_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1e_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1e_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + +}; + +#endif diff --git a/src/devices/cpu/arcompact/arcompactdasm_dispatch.cpp b/src/devices/cpu/arcompact/arcompactdasm_dispatch.cpp index 769a8604fc8..f9b296baf34 100644 --- a/src/devices/cpu/arcompact/arcompactdasm_dispatch.cpp +++ b/src/devices/cpu/arcompact/arcompactdasm_dispatch.cpp @@ -7,12 +7,9 @@ \*********************************/ #include "emu.h" -#include <stdarg.h> +#include "arcompactdasm.h" -#include "arcompactdasm_dispatch.h" -#include "arcompactdasm_ops.h" - -int arcompact_handle00_dasm(DASM_OPS_32) +int arcompact_disassembler::handle00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { int size = 4; uint8_t subinstr = (op & 0x00010000) >> 16; @@ -20,14 +17,14 @@ int arcompact_handle00_dasm(DASM_OPS_32) switch (subinstr) { - case 0x00: size = arcompact_handle00_00_dasm(DASM_PARAMS); break; // Branch Conditionally - case 0x01: size = arcompact_handle00_01_dasm(DASM_PARAMS); break; // Branch Unconditionally Far + case 0x00:size = handle00_00_dasm(stream, pc, op, opcodes); break; // Branch Conditionally + case 0x01:size = handle00_01_dasm(stream, pc, op, opcodes); break; // Branch Unconditionally Far } return size; } -int arcompact_handle01_dasm(DASM_OPS_32) +int arcompact_disassembler::handle01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { int size = 4; uint8_t subinstr = (op & 0x00010000) >> 16; @@ -35,14 +32,14 @@ int arcompact_handle01_dasm(DASM_OPS_32) switch (subinstr) { - case 0x00: size = arcompact_handle01_00_dasm(DASM_PARAMS); break; // Branh & Link - case 0x01: size = arcompact_handle01_01_dasm(DASM_PARAMS); break; // Branch on Compare + case 0x00:size = handle01_00_dasm(stream, pc, op, opcodes); break; // Branh & Link + case 0x01:size = handle01_01_dasm(stream, pc, op, opcodes); break; // Branch on Compare } return size; } -int arcompact_handle01_00_dasm(DASM_OPS_32) +int arcompact_disassembler::handle01_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { int size = 4; uint8_t subinstr2 = (op & 0x00020000) >> 17; @@ -50,14 +47,14 @@ int arcompact_handle01_00_dasm(DASM_OPS_32) switch (subinstr2) { - case 0x00: size = arcompact_handle01_00_00dasm(DASM_PARAMS); break; // Branch and Link Conditionally - case 0x01: size = arcompact_handle01_00_01dasm(DASM_PARAMS); break; // Branch and Link Unconditional Far + case 0x00:size = handle01_00_00dasm(stream, pc, op, opcodes); break; // Branch and Link Conditionally + case 0x01:size = handle01_00_01dasm(stream, pc, op, opcodes); break; // Branch and Link Unconditional Far } return size; } -int arcompact_handle01_01_dasm(DASM_OPS_32) +int arcompact_disassembler::handle01_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { int size = 4; @@ -66,14 +63,14 @@ int arcompact_handle01_01_dasm(DASM_OPS_32) switch (subinstr2) { - case 0x00: size = arcompact_handle01_01_00_dasm(DASM_PARAMS); break; // Branch on Compare Register-Register - case 0x01: size = arcompact_handle01_01_01_dasm(DASM_PARAMS); break; // Branch on Compare/Bit Test Register-Immediate + case 0x00:size = handle01_01_00_dasm(stream, pc, op, opcodes); break; // Branch on Compare Register-Register + case 0x01:size = handle01_01_01_dasm(stream, pc, op, opcodes); break; // Branch on Compare/Bit Test Register-Immediate } return size; } -int arcompact_handle01_01_00_dasm(DASM_OPS_32) +int arcompact_disassembler::handle01_01_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { int size = 4; uint8_t subinstr3 = (op & 0x0000000f) >> 0; @@ -81,28 +78,28 @@ int arcompact_handle01_01_00_dasm(DASM_OPS_32) switch (subinstr3) { - case 0x00: size = arcompact_handle01_01_00_00_dasm(DASM_PARAMS); break; // BREQ (reg-reg) - case 0x01: size = arcompact_handle01_01_00_01_dasm(DASM_PARAMS); break; // BRNE (reg-reg) - case 0x02: size = arcompact_handle01_01_00_02_dasm(DASM_PARAMS); break; // BRLT (reg-reg) - case 0x03: size = arcompact_handle01_01_00_03_dasm(DASM_PARAMS); break; // BRGE (reg-reg) - case 0x04: size = arcompact_handle01_01_00_04_dasm(DASM_PARAMS); break; // BRLO (reg-reg) - case 0x05: size = arcompact_handle01_01_00_05_dasm(DASM_PARAMS); break; // BRHS (reg-reg) - case 0x06: size = arcompact_handle01_01_00_06_dasm(DASM_PARAMS); break; // reserved - case 0x07: size = arcompact_handle01_01_00_07_dasm(DASM_PARAMS); break; // reserved - case 0x08: size = arcompact_handle01_01_00_08_dasm(DASM_PARAMS); break; // reserved - case 0x09: size = arcompact_handle01_01_00_09_dasm(DASM_PARAMS); break; // reserved - case 0x0a: size = arcompact_handle01_01_00_0a_dasm(DASM_PARAMS); break; // reserved - case 0x0b: size = arcompact_handle01_01_00_0b_dasm(DASM_PARAMS); break; // reserved - case 0x0c: size = arcompact_handle01_01_00_0c_dasm(DASM_PARAMS); break; // reserved - case 0x0d: size = arcompact_handle01_01_00_0d_dasm(DASM_PARAMS); break; // reserved - case 0x0e: size = arcompact_handle01_01_00_0e_dasm(DASM_PARAMS); break; // BBIT0 (reg-reg) - case 0x0f: size = arcompact_handle01_01_00_0f_dasm(DASM_PARAMS); break; // BBIT1 (reg-reg) + case 0x00:size = handle01_01_00_00_dasm(stream, pc, op, opcodes); break; // BREQ (reg-reg) + case 0x01:size = handle01_01_00_01_dasm(stream, pc, op, opcodes); break; // BRNE (reg-reg) + case 0x02:size = handle01_01_00_02_dasm(stream, pc, op, opcodes); break; // BRLT (reg-reg) + case 0x03:size = handle01_01_00_03_dasm(stream, pc, op, opcodes); break; // BRGE (reg-reg) + case 0x04:size = handle01_01_00_04_dasm(stream, pc, op, opcodes); break; // BRLO (reg-reg) + case 0x05:size = handle01_01_00_05_dasm(stream, pc, op, opcodes); break; // BRHS (reg-reg) + case 0x06:size = handle01_01_00_06_dasm(stream, pc, op, opcodes); break; // reserved + case 0x07:size = handle01_01_00_07_dasm(stream, pc, op, opcodes); break; // reserved + case 0x08:size = handle01_01_00_08_dasm(stream, pc, op, opcodes); break; // reserved + case 0x09:size = handle01_01_00_09_dasm(stream, pc, op, opcodes); break; // reserved + case 0x0a:size = handle01_01_00_0a_dasm(stream, pc, op, opcodes); break; // reserved + case 0x0b:size = handle01_01_00_0b_dasm(stream, pc, op, opcodes); break; // reserved + case 0x0c:size = handle01_01_00_0c_dasm(stream, pc, op, opcodes); break; // reserved + case 0x0d:size = handle01_01_00_0d_dasm(stream, pc, op, opcodes); break; // reserved + case 0x0e:size = handle01_01_00_0e_dasm(stream, pc, op, opcodes); break; // BBIT0 (reg-reg) + case 0x0f:size = handle01_01_00_0f_dasm(stream, pc, op, opcodes); break; // BBIT1 (reg-reg) } return size; } -int arcompact_handle01_01_01_dasm(DASM_OPS_32) // Branch on Compare/Bit Test Register-Immediate +int arcompact_disassembler::handle01_01_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) // Branch on Compare/Bit Test Register-Immediate { int size = 4; uint8_t subinstr3 = (op & 0x0000000f) >> 0; @@ -110,28 +107,28 @@ int arcompact_handle01_01_01_dasm(DASM_OPS_32) // Branch on Compare/Bit Test Re switch (subinstr3) { - case 0x00: size = arcompact_handle01_01_01_00_dasm(DASM_PARAMS); break; // BREQ (reg-imm) - case 0x01: size = arcompact_handle01_01_01_01_dasm(DASM_PARAMS); break; // BRNE (reg-imm) - case 0x02: size = arcompact_handle01_01_01_02_dasm(DASM_PARAMS); break; // BRLT (reg-imm) - case 0x03: size = arcompact_handle01_01_01_03_dasm(DASM_PARAMS); break; // BRGE (reg-imm) - case 0x04: size = arcompact_handle01_01_01_04_dasm(DASM_PARAMS); break; // BRLO (reg-imm) - case 0x05: size = arcompact_handle01_01_01_05_dasm(DASM_PARAMS); break; // BRHS (reg-imm) - case 0x06: size = arcompact_handle01_01_01_06_dasm(DASM_PARAMS); break; // reserved - case 0x07: size = arcompact_handle01_01_01_07_dasm(DASM_PARAMS); break; // reserved - case 0x08: size = arcompact_handle01_01_01_08_dasm(DASM_PARAMS); break; // reserved - case 0x09: size = arcompact_handle01_01_01_09_dasm(DASM_PARAMS); break; // reserved - case 0x0a: size = arcompact_handle01_01_01_0a_dasm(DASM_PARAMS); break; // reserved - case 0x0b: size = arcompact_handle01_01_01_0b_dasm(DASM_PARAMS); break; // reserved - case 0x0c: size = arcompact_handle01_01_01_0c_dasm(DASM_PARAMS); break; // reserved - case 0x0d: size = arcompact_handle01_01_01_0d_dasm(DASM_PARAMS); break; // reserved - case 0x0e: size = arcompact_handle01_01_01_0e_dasm(DASM_PARAMS); break; // BBIT0 (reg-imm) - case 0x0f: size = arcompact_handle01_01_01_0f_dasm(DASM_PARAMS); break; // BBIT1 (reg-imm) + case 0x00:size = handle01_01_01_00_dasm(stream, pc, op, opcodes); break; // BREQ (reg-imm) + case 0x01:size = handle01_01_01_01_dasm(stream, pc, op, opcodes); break; // BRNE (reg-imm) + case 0x02:size = handle01_01_01_02_dasm(stream, pc, op, opcodes); break; // BRLT (reg-imm) + case 0x03:size = handle01_01_01_03_dasm(stream, pc, op, opcodes); break; // BRGE (reg-imm) + case 0x04:size = handle01_01_01_04_dasm(stream, pc, op, opcodes); break; // BRLO (reg-imm) + case 0x05:size = handle01_01_01_05_dasm(stream, pc, op, opcodes); break; // BRHS (reg-imm) + case 0x06:size = handle01_01_01_06_dasm(stream, pc, op, opcodes); break; // reserved + case 0x07:size = handle01_01_01_07_dasm(stream, pc, op, opcodes); break; // reserved + case 0x08:size = handle01_01_01_08_dasm(stream, pc, op, opcodes); break; // reserved + case 0x09:size = handle01_01_01_09_dasm(stream, pc, op, opcodes); break; // reserved + case 0x0a:size = handle01_01_01_0a_dasm(stream, pc, op, opcodes); break; // reserved + case 0x0b:size = handle01_01_01_0b_dasm(stream, pc, op, opcodes); break; // reserved + case 0x0c:size = handle01_01_01_0c_dasm(stream, pc, op, opcodes); break; // reserved + case 0x0d:size = handle01_01_01_0d_dasm(stream, pc, op, opcodes); break; // reserved + case 0x0e:size = handle01_01_01_0e_dasm(stream, pc, op, opcodes); break; // BBIT0 (reg-imm) + case 0x0f:size = handle01_01_01_0f_dasm(stream, pc, op, opcodes); break; // BBIT1 (reg-imm) } return size; } -int arcompact_handle04_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { int size = 4; // General Operations @@ -151,76 +148,76 @@ int arcompact_handle04_dasm(DASM_OPS_32) switch (subinstr) { - case 0x00: size = arcompact_handle04_00_dasm(DASM_PARAMS); break; // ADD - case 0x01: size = arcompact_handle04_01_dasm(DASM_PARAMS); break; // ADC - case 0x02: size = arcompact_handle04_02_dasm(DASM_PARAMS); break; // SUB - case 0x03: size = arcompact_handle04_03_dasm(DASM_PARAMS); break; // SBC - case 0x04: size = arcompact_handle04_04_dasm(DASM_PARAMS); break; // AND - case 0x05: size = arcompact_handle04_05_dasm(DASM_PARAMS); break; // OR - case 0x06: size = arcompact_handle04_06_dasm(DASM_PARAMS); break; // BIC - case 0x07: size = arcompact_handle04_07_dasm(DASM_PARAMS); break; // XOR - case 0x08: size = arcompact_handle04_08_dasm(DASM_PARAMS); break; // MAX - case 0x09: size = arcompact_handle04_09_dasm(DASM_PARAMS); break; // MIN - case 0x0a: size = arcompact_handle04_0a_dasm(DASM_PARAMS); break; // MOV - case 0x0b: size = arcompact_handle04_0b_dasm(DASM_PARAMS); break; // TST - case 0x0c: size = arcompact_handle04_0c_dasm(DASM_PARAMS); break; // CMP - case 0x0d: size = arcompact_handle04_0d_dasm(DASM_PARAMS); break; // RCMP - case 0x0e: size = arcompact_handle04_0e_dasm(DASM_PARAMS); break; // RSUB - case 0x0f: size = arcompact_handle04_0f_dasm(DASM_PARAMS); break; // BSET - case 0x10: size = arcompact_handle04_10_dasm(DASM_PARAMS); break; // BCLR - case 0x11: size = arcompact_handle04_11_dasm(DASM_PARAMS); break; // BTST - case 0x12: size = arcompact_handle04_12_dasm(DASM_PARAMS); break; // BXOR - case 0x13: size = arcompact_handle04_13_dasm(DASM_PARAMS); break; // BMSK - case 0x14: size = arcompact_handle04_14_dasm(DASM_PARAMS); break; // ADD1 - case 0x15: size = arcompact_handle04_15_dasm(DASM_PARAMS); break; // ADD2 - case 0x16: size = arcompact_handle04_16_dasm(DASM_PARAMS); break; // ADD3 - case 0x17: size = arcompact_handle04_17_dasm(DASM_PARAMS); break; // SUB1 - case 0x18: size = arcompact_handle04_18_dasm(DASM_PARAMS); break; // SUB2 - case 0x19: size = arcompact_handle04_19_dasm(DASM_PARAMS); break; // SUB3 - case 0x1a: size = arcompact_handle04_1a_dasm(DASM_PARAMS); break; // MPY * - case 0x1b: size = arcompact_handle04_1b_dasm(DASM_PARAMS); break; // MPYH * - case 0x1c: size = arcompact_handle04_1c_dasm(DASM_PARAMS); break; // MPYHU * - case 0x1d: size = arcompact_handle04_1d_dasm(DASM_PARAMS); break; // MPYU * - case 0x1e: size = arcompact_handle04_1e_dasm(DASM_PARAMS); break; // illegal - case 0x1f: size = arcompact_handle04_1f_dasm(DASM_PARAMS); break; // illegal - case 0x20: size = arcompact_handle04_20_dasm(DASM_PARAMS); break; // Jcc - case 0x21: size = arcompact_handle04_21_dasm(DASM_PARAMS); break; // Jcc.D - case 0x22: size = arcompact_handle04_22_dasm(DASM_PARAMS); break; // JLcc - case 0x23: size = arcompact_handle04_23_dasm(DASM_PARAMS); break; // JLcc.D - case 0x24: size = arcompact_handle04_24_dasm(DASM_PARAMS); break; // illegal - case 0x25: size = arcompact_handle04_25_dasm(DASM_PARAMS); break; // illegal - case 0x26: size = arcompact_handle04_26_dasm(DASM_PARAMS); break; // illegal - case 0x27: size = arcompact_handle04_27_dasm(DASM_PARAMS); break; // illegal - case 0x28: size = arcompact_handle04_28_dasm(DASM_PARAMS); break; // LPcc - case 0x29: size = arcompact_handle04_29_dasm(DASM_PARAMS); break; // FLAG - case 0x2a: size = arcompact_handle04_2a_dasm(DASM_PARAMS); break; // LR - case 0x2b: size = arcompact_handle04_2b_dasm(DASM_PARAMS); break; // SR - case 0x2c: size = arcompact_handle04_2c_dasm(DASM_PARAMS); break; // illegal - case 0x2d: size = arcompact_handle04_2d_dasm(DASM_PARAMS); break; // illegal - case 0x2e: size = arcompact_handle04_2e_dasm(DASM_PARAMS); break; // illegal - case 0x2f: size = arcompact_handle04_2f_dasm(DASM_PARAMS); break; // Sub Opcode - case 0x30: size = arcompact_handle04_30_dasm(DASM_PARAMS); break; // LD r-r - case 0x31: size = arcompact_handle04_31_dasm(DASM_PARAMS); break; // LD r-r - case 0x32: size = arcompact_handle04_32_dasm(DASM_PARAMS); break; // LD r-r - case 0x33: size = arcompact_handle04_33_dasm(DASM_PARAMS); break; // LD r-r - case 0x34: size = arcompact_handle04_34_dasm(DASM_PARAMS); break; // LD r-r - case 0x35: size = arcompact_handle04_35_dasm(DASM_PARAMS); break; // LD r-r - case 0x36: size = arcompact_handle04_36_dasm(DASM_PARAMS); break; // LD r-r - case 0x37: size = arcompact_handle04_37_dasm(DASM_PARAMS); break; // LD r-r - case 0x38: size = arcompact_handle04_38_dasm(DASM_PARAMS); break; // illegal - case 0x39: size = arcompact_handle04_39_dasm(DASM_PARAMS); break; // illegal - case 0x3a: size = arcompact_handle04_3a_dasm(DASM_PARAMS); break; // illegal - case 0x3b: size = arcompact_handle04_3b_dasm(DASM_PARAMS); break; // illegal - case 0x3c: size = arcompact_handle04_3c_dasm(DASM_PARAMS); break; // illegal - case 0x3d: size = arcompact_handle04_3d_dasm(DASM_PARAMS); break; // illegal - case 0x3e: size = arcompact_handle04_3e_dasm(DASM_PARAMS); break; // illegal - case 0x3f: size = arcompact_handle04_3f_dasm(DASM_PARAMS); break; // illegal + case 0x00:size = handle04_00_dasm(stream, pc, op, opcodes); break; // ADD + case 0x01:size = handle04_01_dasm(stream, pc, op, opcodes); break; // ADC + case 0x02:size = handle04_02_dasm(stream, pc, op, opcodes); break; // SUB + case 0x03:size = handle04_03_dasm(stream, pc, op, opcodes); break; // SBC + case 0x04:size = handle04_04_dasm(stream, pc, op, opcodes); break; // AND + case 0x05:size = handle04_05_dasm(stream, pc, op, opcodes); break; // OR + case 0x06:size = handle04_06_dasm(stream, pc, op, opcodes); break; // BIC + case 0x07:size = handle04_07_dasm(stream, pc, op, opcodes); break; // XOR + case 0x08:size = handle04_08_dasm(stream, pc, op, opcodes); break; // MAX + case 0x09:size = handle04_09_dasm(stream, pc, op, opcodes); break; // MIN + case 0x0a:size = handle04_0a_dasm(stream, pc, op, opcodes); break; // MOV + case 0x0b:size = handle04_0b_dasm(stream, pc, op, opcodes); break; // TST + case 0x0c:size = handle04_0c_dasm(stream, pc, op, opcodes); break; // CMP + case 0x0d:size = handle04_0d_dasm(stream, pc, op, opcodes); break; // RCMP + case 0x0e:size = handle04_0e_dasm(stream, pc, op, opcodes); break; // RSUB + case 0x0f:size = handle04_0f_dasm(stream, pc, op, opcodes); break; // BSET + case 0x10:size = handle04_10_dasm(stream, pc, op, opcodes); break; // BCLR + case 0x11:size = handle04_11_dasm(stream, pc, op, opcodes); break; // BTST + case 0x12:size = handle04_12_dasm(stream, pc, op, opcodes); break; // BXOR + case 0x13:size = handle04_13_dasm(stream, pc, op, opcodes); break; // BMSK + case 0x14:size = handle04_14_dasm(stream, pc, op, opcodes); break; // ADD1 + case 0x15:size = handle04_15_dasm(stream, pc, op, opcodes); break; // ADD2 + case 0x16:size = handle04_16_dasm(stream, pc, op, opcodes); break; // ADD3 + case 0x17:size = handle04_17_dasm(stream, pc, op, opcodes); break; // SUB1 + case 0x18:size = handle04_18_dasm(stream, pc, op, opcodes); break; // SUB2 + case 0x19:size = handle04_19_dasm(stream, pc, op, opcodes); break; // SUB3 + case 0x1a:size = handle04_1a_dasm(stream, pc, op, opcodes); break; // MPY * + case 0x1b:size = handle04_1b_dasm(stream, pc, op, opcodes); break; // MPYH * + case 0x1c:size = handle04_1c_dasm(stream, pc, op, opcodes); break; // MPYHU * + case 0x1d:size = handle04_1d_dasm(stream, pc, op, opcodes); break; // MPYU * + case 0x1e:size = handle04_1e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1f:size = handle04_1f_dasm(stream, pc, op, opcodes); break; // illegal + case 0x20:size = handle04_20_dasm(stream, pc, op, opcodes); break; // Jcc + case 0x21:size = handle04_21_dasm(stream, pc, op, opcodes); break; // Jcc.D + case 0x22:size = handle04_22_dasm(stream, pc, op, opcodes); break; // JLcc + case 0x23:size = handle04_23_dasm(stream, pc, op, opcodes); break; // JLcc.D + case 0x24:size = handle04_24_dasm(stream, pc, op, opcodes); break; // illegal + case 0x25:size = handle04_25_dasm(stream, pc, op, opcodes); break; // illegal + case 0x26:size = handle04_26_dasm(stream, pc, op, opcodes); break; // illegal + case 0x27:size = handle04_27_dasm(stream, pc, op, opcodes); break; // illegal + case 0x28:size = handle04_28_dasm(stream, pc, op, opcodes); break; // LPcc + case 0x29:size = handle04_29_dasm(stream, pc, op, opcodes); break; // FLAG + case 0x2a:size = handle04_2a_dasm(stream, pc, op, opcodes); break; // LR + case 0x2b:size = handle04_2b_dasm(stream, pc, op, opcodes); break; // SR + case 0x2c:size = handle04_2c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2d:size = handle04_2d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2e:size = handle04_2e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2f:size = handle04_2f_dasm(stream, pc, op, opcodes); break; // Sub Opcode + case 0x30:size = handle04_30_dasm(stream, pc, op, opcodes); break; // LD r-r + case 0x31:size = handle04_31_dasm(stream, pc, op, opcodes); break; // LD r-r + case 0x32:size = handle04_32_dasm(stream, pc, op, opcodes); break; // LD r-r + case 0x33:size = handle04_33_dasm(stream, pc, op, opcodes); break; // LD r-r + case 0x34:size = handle04_34_dasm(stream, pc, op, opcodes); break; // LD r-r + case 0x35:size = handle04_35_dasm(stream, pc, op, opcodes); break; // LD r-r + case 0x36:size = handle04_36_dasm(stream, pc, op, opcodes); break; // LD r-r + case 0x37:size = handle04_37_dasm(stream, pc, op, opcodes); break; // LD r-r + case 0x38:size = handle04_38_dasm(stream, pc, op, opcodes); break; // illegal + case 0x39:size = handle04_39_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3a:size = handle04_3a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3b:size = handle04_3b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3c:size = handle04_3c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3d:size = handle04_3d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3e:size = handle04_3e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3f:size = handle04_3f_dasm(stream, pc, op, opcodes); break; // illegal } return size; } -int arcompact_handle04_2f_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_2f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { int size = 4; uint8_t subinstr2 = (op & 0x0000003f) >> 0; @@ -228,77 +225,77 @@ int arcompact_handle04_2f_dasm(DASM_OPS_32) switch (subinstr2) { - case 0x00: size = arcompact_handle04_2f_00_dasm(DASM_PARAMS); break; // ASL - case 0x01: size = arcompact_handle04_2f_01_dasm(DASM_PARAMS); break; // ASR - case 0x02: size = arcompact_handle04_2f_02_dasm(DASM_PARAMS); break; // LSR - case 0x03: size = arcompact_handle04_2f_03_dasm(DASM_PARAMS); break; // ROR - case 0x04: size = arcompact_handle04_2f_04_dasm(DASM_PARAMS); break; // RCC - case 0x05: size = arcompact_handle04_2f_05_dasm(DASM_PARAMS); break; // SEXB - case 0x06: size = arcompact_handle04_2f_06_dasm(DASM_PARAMS); break; // SEXW - case 0x07: size = arcompact_handle04_2f_07_dasm(DASM_PARAMS); break; // EXTB - case 0x08: size = arcompact_handle04_2f_08_dasm(DASM_PARAMS); break; // EXTW - case 0x09: size = arcompact_handle04_2f_09_dasm(DASM_PARAMS); break; // ABS - case 0x0a: size = arcompact_handle04_2f_0a_dasm(DASM_PARAMS); break; // NOT - case 0x0b: size = arcompact_handle04_2f_0b_dasm(DASM_PARAMS); break; // RLC - case 0x0c: size = arcompact_handle04_2f_0c_dasm(DASM_PARAMS); break; // EX - case 0x0d: size = arcompact_handle04_2f_0d_dasm(DASM_PARAMS); break; // illegal - case 0x0e: size = arcompact_handle04_2f_0e_dasm(DASM_PARAMS); break; // illegal - case 0x0f: size = arcompact_handle04_2f_0f_dasm(DASM_PARAMS); break; // illegal - case 0x10: size = arcompact_handle04_2f_10_dasm(DASM_PARAMS); break; // illegal - case 0x11: size = arcompact_handle04_2f_11_dasm(DASM_PARAMS); break; // illegal - case 0x12: size = arcompact_handle04_2f_12_dasm(DASM_PARAMS); break; // illegal - case 0x13: size = arcompact_handle04_2f_13_dasm(DASM_PARAMS); break; // illegal - case 0x14: size = arcompact_handle04_2f_14_dasm(DASM_PARAMS); break; // illegal - case 0x15: size = arcompact_handle04_2f_15_dasm(DASM_PARAMS); break; // illegal - case 0x16: size = arcompact_handle04_2f_16_dasm(DASM_PARAMS); break; // illegal - case 0x17: size = arcompact_handle04_2f_17_dasm(DASM_PARAMS); break; // illegal - case 0x18: size = arcompact_handle04_2f_18_dasm(DASM_PARAMS); break; // illegal - case 0x19: size = arcompact_handle04_2f_19_dasm(DASM_PARAMS); break; // illegal - case 0x1a: size = arcompact_handle04_2f_1a_dasm(DASM_PARAMS); break; // illegal - case 0x1b: size = arcompact_handle04_2f_1b_dasm(DASM_PARAMS); break; // illegal - case 0x1c: size = arcompact_handle04_2f_1c_dasm(DASM_PARAMS); break; // illegal - case 0x1d: size = arcompact_handle04_2f_1d_dasm(DASM_PARAMS); break; // illegal - case 0x1e: size = arcompact_handle04_2f_1e_dasm(DASM_PARAMS); break; // illegal - case 0x1f: size = arcompact_handle04_2f_1f_dasm(DASM_PARAMS); break; // illegal - case 0x20: size = arcompact_handle04_2f_20_dasm(DASM_PARAMS); break; // illegal - case 0x21: size = arcompact_handle04_2f_21_dasm(DASM_PARAMS); break; // illegal - case 0x22: size = arcompact_handle04_2f_22_dasm(DASM_PARAMS); break; // illegal - case 0x23: size = arcompact_handle04_2f_23_dasm(DASM_PARAMS); break; // illegal - case 0x24: size = arcompact_handle04_2f_24_dasm(DASM_PARAMS); break; // illegal - case 0x25: size = arcompact_handle04_2f_25_dasm(DASM_PARAMS); break; // illegal - case 0x26: size = arcompact_handle04_2f_26_dasm(DASM_PARAMS); break; // illegal - case 0x27: size = arcompact_handle04_2f_27_dasm(DASM_PARAMS); break; // illegal - case 0x28: size = arcompact_handle04_2f_28_dasm(DASM_PARAMS); break; // illegal - case 0x29: size = arcompact_handle04_2f_29_dasm(DASM_PARAMS); break; // illegal - case 0x2a: size = arcompact_handle04_2f_2a_dasm(DASM_PARAMS); break; // illegal - case 0x2b: size = arcompact_handle04_2f_2b_dasm(DASM_PARAMS); break; // illegal - case 0x2c: size = arcompact_handle04_2f_2c_dasm(DASM_PARAMS); break; // illegal - case 0x2d: size = arcompact_handle04_2f_2d_dasm(DASM_PARAMS); break; // illegal - case 0x2e: size = arcompact_handle04_2f_2e_dasm(DASM_PARAMS); break; // illegal - case 0x2f: size = arcompact_handle04_2f_2f_dasm(DASM_PARAMS); break; // illegal - case 0x30: size = arcompact_handle04_2f_30_dasm(DASM_PARAMS); break; // illegal - case 0x31: size = arcompact_handle04_2f_31_dasm(DASM_PARAMS); break; // illegal - case 0x32: size = arcompact_handle04_2f_32_dasm(DASM_PARAMS); break; // illegal - case 0x33: size = arcompact_handle04_2f_33_dasm(DASM_PARAMS); break; // illegal - case 0x34: size = arcompact_handle04_2f_34_dasm(DASM_PARAMS); break; // illegal - case 0x35: size = arcompact_handle04_2f_35_dasm(DASM_PARAMS); break; // illegal - case 0x36: size = arcompact_handle04_2f_36_dasm(DASM_PARAMS); break; // illegal - case 0x37: size = arcompact_handle04_2f_37_dasm(DASM_PARAMS); break; // illegal - case 0x38: size = arcompact_handle04_2f_38_dasm(DASM_PARAMS); break; // illegal - case 0x39: size = arcompact_handle04_2f_39_dasm(DASM_PARAMS); break; // illegal - case 0x3a: size = arcompact_handle04_2f_3a_dasm(DASM_PARAMS); break; // illegal - case 0x3b: size = arcompact_handle04_2f_3b_dasm(DASM_PARAMS); break; // illegal - case 0x3c: size = arcompact_handle04_2f_3c_dasm(DASM_PARAMS); break; // illegal - case 0x3d: size = arcompact_handle04_2f_3d_dasm(DASM_PARAMS); break; // illegal - case 0x3e: size = arcompact_handle04_2f_3e_dasm(DASM_PARAMS); break; // illegal - case 0x3f: size = arcompact_handle04_2f_3f_dasm(DASM_PARAMS); break; // ZOPs (Zero Operand Opcodes) + case 0x00:size = handle04_2f_00_dasm(stream, pc, op, opcodes); break; // ASL + case 0x01:size = handle04_2f_01_dasm(stream, pc, op, opcodes); break; // ASR + case 0x02:size = handle04_2f_02_dasm(stream, pc, op, opcodes); break; // LSR + case 0x03:size = handle04_2f_03_dasm(stream, pc, op, opcodes); break; // ROR + case 0x04:size = handle04_2f_04_dasm(stream, pc, op, opcodes); break; // RCC + case 0x05:size = handle04_2f_05_dasm(stream, pc, op, opcodes); break; // SEXB + case 0x06:size = handle04_2f_06_dasm(stream, pc, op, opcodes); break; // SEXW + case 0x07:size = handle04_2f_07_dasm(stream, pc, op, opcodes); break; // EXTB + case 0x08:size = handle04_2f_08_dasm(stream, pc, op, opcodes); break; // EXTW + case 0x09:size = handle04_2f_09_dasm(stream, pc, op, opcodes); break; // ABS + case 0x0a:size = handle04_2f_0a_dasm(stream, pc, op, opcodes); break; // NOT + case 0x0b:size = handle04_2f_0b_dasm(stream, pc, op, opcodes); break; // RLC + case 0x0c:size = handle04_2f_0c_dasm(stream, pc, op, opcodes); break; // EX + case 0x0d:size = handle04_2f_0d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0e:size = handle04_2f_0e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0f:size = handle04_2f_0f_dasm(stream, pc, op, opcodes); break; // illegal + case 0x10:size = handle04_2f_10_dasm(stream, pc, op, opcodes); break; // illegal + case 0x11:size = handle04_2f_11_dasm(stream, pc, op, opcodes); break; // illegal + case 0x12:size = handle04_2f_12_dasm(stream, pc, op, opcodes); break; // illegal + case 0x13:size = handle04_2f_13_dasm(stream, pc, op, opcodes); break; // illegal + case 0x14:size = handle04_2f_14_dasm(stream, pc, op, opcodes); break; // illegal + case 0x15:size = handle04_2f_15_dasm(stream, pc, op, opcodes); break; // illegal + case 0x16:size = handle04_2f_16_dasm(stream, pc, op, opcodes); break; // illegal + case 0x17:size = handle04_2f_17_dasm(stream, pc, op, opcodes); break; // illegal + case 0x18:size = handle04_2f_18_dasm(stream, pc, op, opcodes); break; // illegal + case 0x19:size = handle04_2f_19_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1a:size = handle04_2f_1a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1b:size = handle04_2f_1b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1c:size = handle04_2f_1c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1d:size = handle04_2f_1d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1e:size = handle04_2f_1e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1f:size = handle04_2f_1f_dasm(stream, pc, op, opcodes); break; // illegal + case 0x20:size = handle04_2f_20_dasm(stream, pc, op, opcodes); break; // illegal + case 0x21:size = handle04_2f_21_dasm(stream, pc, op, opcodes); break; // illegal + case 0x22:size = handle04_2f_22_dasm(stream, pc, op, opcodes); break; // illegal + case 0x23:size = handle04_2f_23_dasm(stream, pc, op, opcodes); break; // illegal + case 0x24:size = handle04_2f_24_dasm(stream, pc, op, opcodes); break; // illegal + case 0x25:size = handle04_2f_25_dasm(stream, pc, op, opcodes); break; // illegal + case 0x26:size = handle04_2f_26_dasm(stream, pc, op, opcodes); break; // illegal + case 0x27:size = handle04_2f_27_dasm(stream, pc, op, opcodes); break; // illegal + case 0x28:size = handle04_2f_28_dasm(stream, pc, op, opcodes); break; // illegal + case 0x29:size = handle04_2f_29_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2a:size = handle04_2f_2a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2b:size = handle04_2f_2b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2c:size = handle04_2f_2c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2d:size = handle04_2f_2d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2e:size = handle04_2f_2e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2f:size = handle04_2f_2f_dasm(stream, pc, op, opcodes); break; // illegal + case 0x30:size = handle04_2f_30_dasm(stream, pc, op, opcodes); break; // illegal + case 0x31:size = handle04_2f_31_dasm(stream, pc, op, opcodes); break; // illegal + case 0x32:size = handle04_2f_32_dasm(stream, pc, op, opcodes); break; // illegal + case 0x33:size = handle04_2f_33_dasm(stream, pc, op, opcodes); break; // illegal + case 0x34:size = handle04_2f_34_dasm(stream, pc, op, opcodes); break; // illegal + case 0x35:size = handle04_2f_35_dasm(stream, pc, op, opcodes); break; // illegal + case 0x36:size = handle04_2f_36_dasm(stream, pc, op, opcodes); break; // illegal + case 0x37:size = handle04_2f_37_dasm(stream, pc, op, opcodes); break; // illegal + case 0x38:size = handle04_2f_38_dasm(stream, pc, op, opcodes); break; // illegal + case 0x39:size = handle04_2f_39_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3a:size = handle04_2f_3a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3b:size = handle04_2f_3b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3c:size = handle04_2f_3c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3d:size = handle04_2f_3d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3e:size = handle04_2f_3e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3f:size = handle04_2f_3f_dasm(stream, pc, op, opcodes); break; // ZOPs (Zero Operand Opcodes) } return size; } -int arcompact_handle05_2f_dasm(DASM_OPS_32) +int arcompact_disassembler::handle05_2f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { int size = 4; uint8_t subinstr2 = (op & 0x0000003f) >> 0; @@ -306,76 +303,76 @@ int arcompact_handle05_2f_dasm(DASM_OPS_32) switch (subinstr2) { - case 0x00: size = arcompact_handle05_2f_00_dasm(DASM_PARAMS); break; // SWAP - case 0x01: size = arcompact_handle05_2f_01_dasm(DASM_PARAMS); break; // NORM - case 0x02: size = arcompact_handle05_2f_02_dasm(DASM_PARAMS); break; // SAT16 - case 0x03: size = arcompact_handle05_2f_03_dasm(DASM_PARAMS); break; // RND16 - case 0x04: size = arcompact_handle05_2f_04_dasm(DASM_PARAMS); break; // ABSSW - case 0x05: size = arcompact_handle05_2f_05_dasm(DASM_PARAMS); break; // ABSS - case 0x06: size = arcompact_handle05_2f_06_dasm(DASM_PARAMS); break; // NEGSW - case 0x07: size = arcompact_handle05_2f_07_dasm(DASM_PARAMS); break; // NEGS - case 0x08: size = arcompact_handle05_2f_08_dasm(DASM_PARAMS); break; // NORMW - case 0x09: size = arcompact_handle05_2f_09_dasm(DASM_PARAMS); break; // illegal - case 0x0a: size = arcompact_handle05_2f_0a_dasm(DASM_PARAMS); break; // illegal - case 0x0b: size = arcompact_handle05_2f_0b_dasm(DASM_PARAMS); break; // illegal - case 0x0c: size = arcompact_handle05_2f_0c_dasm(DASM_PARAMS); break; // illegal - case 0x0d: size = arcompact_handle05_2f_0d_dasm(DASM_PARAMS); break; // illegal - case 0x0e: size = arcompact_handle05_2f_0e_dasm(DASM_PARAMS); break; // illegal - case 0x0f: size = arcompact_handle05_2f_0f_dasm(DASM_PARAMS); break; // illegal - case 0x10: size = arcompact_handle05_2f_10_dasm(DASM_PARAMS); break; // illegal - case 0x11: size = arcompact_handle05_2f_11_dasm(DASM_PARAMS); break; // illegal - case 0x12: size = arcompact_handle05_2f_12_dasm(DASM_PARAMS); break; // illegal - case 0x13: size = arcompact_handle05_2f_13_dasm(DASM_PARAMS); break; // illegal - case 0x14: size = arcompact_handle05_2f_14_dasm(DASM_PARAMS); break; // illegal - case 0x15: size = arcompact_handle05_2f_15_dasm(DASM_PARAMS); break; // illegal - case 0x16: size = arcompact_handle05_2f_16_dasm(DASM_PARAMS); break; // illegal - case 0x17: size = arcompact_handle05_2f_17_dasm(DASM_PARAMS); break; // illegal - case 0x18: size = arcompact_handle05_2f_18_dasm(DASM_PARAMS); break; // illegal - case 0x19: size = arcompact_handle05_2f_19_dasm(DASM_PARAMS); break; // illegal - case 0x1a: size = arcompact_handle05_2f_1a_dasm(DASM_PARAMS); break; // illegal - case 0x1b: size = arcompact_handle05_2f_1b_dasm(DASM_PARAMS); break; // illegal - case 0x1c: size = arcompact_handle05_2f_1c_dasm(DASM_PARAMS); break; // illegal - case 0x1d: size = arcompact_handle05_2f_1d_dasm(DASM_PARAMS); break; // illegal - case 0x1e: size = arcompact_handle05_2f_1e_dasm(DASM_PARAMS); break; // illegal - case 0x1f: size = arcompact_handle05_2f_1f_dasm(DASM_PARAMS); break; // illegal - case 0x20: size = arcompact_handle05_2f_20_dasm(DASM_PARAMS); break; // illegal - case 0x21: size = arcompact_handle05_2f_21_dasm(DASM_PARAMS); break; // illegal - case 0x22: size = arcompact_handle05_2f_22_dasm(DASM_PARAMS); break; // illegal - case 0x23: size = arcompact_handle05_2f_23_dasm(DASM_PARAMS); break; // illegal - case 0x24: size = arcompact_handle05_2f_24_dasm(DASM_PARAMS); break; // illegal - case 0x25: size = arcompact_handle05_2f_25_dasm(DASM_PARAMS); break; // illegal - case 0x26: size = arcompact_handle05_2f_26_dasm(DASM_PARAMS); break; // illegal - case 0x27: size = arcompact_handle05_2f_27_dasm(DASM_PARAMS); break; // illegal - case 0x28: size = arcompact_handle05_2f_28_dasm(DASM_PARAMS); break; // illegal - case 0x29: size = arcompact_handle05_2f_29_dasm(DASM_PARAMS); break; // illegal - case 0x2a: size = arcompact_handle05_2f_2a_dasm(DASM_PARAMS); break; // illegal - case 0x2b: size = arcompact_handle05_2f_2b_dasm(DASM_PARAMS); break; // illegal - case 0x2c: size = arcompact_handle05_2f_2c_dasm(DASM_PARAMS); break; // illegal - case 0x2d: size = arcompact_handle05_2f_2d_dasm(DASM_PARAMS); break; // illegal - case 0x2e: size = arcompact_handle05_2f_2e_dasm(DASM_PARAMS); break; // illegal - case 0x2f: size = arcompact_handle05_2f_2f_dasm(DASM_PARAMS); break; // illegal - case 0x30: size = arcompact_handle05_2f_30_dasm(DASM_PARAMS); break; // illegal - case 0x31: size = arcompact_handle05_2f_31_dasm(DASM_PARAMS); break; // illegal - case 0x32: size = arcompact_handle05_2f_32_dasm(DASM_PARAMS); break; // illegal - case 0x33: size = arcompact_handle05_2f_33_dasm(DASM_PARAMS); break; // illegal - case 0x34: size = arcompact_handle05_2f_34_dasm(DASM_PARAMS); break; // illegal - case 0x35: size = arcompact_handle05_2f_35_dasm(DASM_PARAMS); break; // illegal - case 0x36: size = arcompact_handle05_2f_36_dasm(DASM_PARAMS); break; // illegal - case 0x37: size = arcompact_handle05_2f_37_dasm(DASM_PARAMS); break; // illegal - case 0x38: size = arcompact_handle05_2f_38_dasm(DASM_PARAMS); break; // illegal - case 0x39: size = arcompact_handle05_2f_39_dasm(DASM_PARAMS); break; // illegal - case 0x3a: size = arcompact_handle05_2f_3a_dasm(DASM_PARAMS); break; // illegal - case 0x3b: size = arcompact_handle05_2f_3b_dasm(DASM_PARAMS); break; // illegal - case 0x3c: size = arcompact_handle05_2f_3c_dasm(DASM_PARAMS); break; // illegal - case 0x3d: size = arcompact_handle05_2f_3d_dasm(DASM_PARAMS); break; // illegal - case 0x3e: size = arcompact_handle05_2f_3e_dasm(DASM_PARAMS); break; // illegal - case 0x3f: size = arcompact_handle05_2f_3f_dasm(DASM_PARAMS); break; // ZOPs (Zero Operand Opcodes) + case 0x00:size = handle05_2f_00_dasm(stream, pc, op, opcodes); break; // SWAP + case 0x01:size = handle05_2f_01_dasm(stream, pc, op, opcodes); break; // NORM + case 0x02:size = handle05_2f_02_dasm(stream, pc, op, opcodes); break; // SAT16 + case 0x03:size = handle05_2f_03_dasm(stream, pc, op, opcodes); break; // RND16 + case 0x04:size = handle05_2f_04_dasm(stream, pc, op, opcodes); break; // ABSSW + case 0x05:size = handle05_2f_05_dasm(stream, pc, op, opcodes); break; // ABSS + case 0x06:size = handle05_2f_06_dasm(stream, pc, op, opcodes); break; // NEGSW + case 0x07:size = handle05_2f_07_dasm(stream, pc, op, opcodes); break; // NEGS + case 0x08:size = handle05_2f_08_dasm(stream, pc, op, opcodes); break; // NORMW + case 0x09:size = handle05_2f_09_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0a:size = handle05_2f_0a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0b:size = handle05_2f_0b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0c:size = handle05_2f_0c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0d:size = handle05_2f_0d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0e:size = handle05_2f_0e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0f:size = handle05_2f_0f_dasm(stream, pc, op, opcodes); break; // illegal + case 0x10:size = handle05_2f_10_dasm(stream, pc, op, opcodes); break; // illegal + case 0x11:size = handle05_2f_11_dasm(stream, pc, op, opcodes); break; // illegal + case 0x12:size = handle05_2f_12_dasm(stream, pc, op, opcodes); break; // illegal + case 0x13:size = handle05_2f_13_dasm(stream, pc, op, opcodes); break; // illegal + case 0x14:size = handle05_2f_14_dasm(stream, pc, op, opcodes); break; // illegal + case 0x15:size = handle05_2f_15_dasm(stream, pc, op, opcodes); break; // illegal + case 0x16:size = handle05_2f_16_dasm(stream, pc, op, opcodes); break; // illegal + case 0x17:size = handle05_2f_17_dasm(stream, pc, op, opcodes); break; // illegal + case 0x18:size = handle05_2f_18_dasm(stream, pc, op, opcodes); break; // illegal + case 0x19:size = handle05_2f_19_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1a:size = handle05_2f_1a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1b:size = handle05_2f_1b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1c:size = handle05_2f_1c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1d:size = handle05_2f_1d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1e:size = handle05_2f_1e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1f:size = handle05_2f_1f_dasm(stream, pc, op, opcodes); break; // illegal + case 0x20:size = handle05_2f_20_dasm(stream, pc, op, opcodes); break; // illegal + case 0x21:size = handle05_2f_21_dasm(stream, pc, op, opcodes); break; // illegal + case 0x22:size = handle05_2f_22_dasm(stream, pc, op, opcodes); break; // illegal + case 0x23:size = handle05_2f_23_dasm(stream, pc, op, opcodes); break; // illegal + case 0x24:size = handle05_2f_24_dasm(stream, pc, op, opcodes); break; // illegal + case 0x25:size = handle05_2f_25_dasm(stream, pc, op, opcodes); break; // illegal + case 0x26:size = handle05_2f_26_dasm(stream, pc, op, opcodes); break; // illegal + case 0x27:size = handle05_2f_27_dasm(stream, pc, op, opcodes); break; // illegal + case 0x28:size = handle05_2f_28_dasm(stream, pc, op, opcodes); break; // illegal + case 0x29:size = handle05_2f_29_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2a:size = handle05_2f_2a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2b:size = handle05_2f_2b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2c:size = handle05_2f_2c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2d:size = handle05_2f_2d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2e:size = handle05_2f_2e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2f:size = handle05_2f_2f_dasm(stream, pc, op, opcodes); break; // illegal + case 0x30:size = handle05_2f_30_dasm(stream, pc, op, opcodes); break; // illegal + case 0x31:size = handle05_2f_31_dasm(stream, pc, op, opcodes); break; // illegal + case 0x32:size = handle05_2f_32_dasm(stream, pc, op, opcodes); break; // illegal + case 0x33:size = handle05_2f_33_dasm(stream, pc, op, opcodes); break; // illegal + case 0x34:size = handle05_2f_34_dasm(stream, pc, op, opcodes); break; // illegal + case 0x35:size = handle05_2f_35_dasm(stream, pc, op, opcodes); break; // illegal + case 0x36:size = handle05_2f_36_dasm(stream, pc, op, opcodes); break; // illegal + case 0x37:size = handle05_2f_37_dasm(stream, pc, op, opcodes); break; // illegal + case 0x38:size = handle05_2f_38_dasm(stream, pc, op, opcodes); break; // illegal + case 0x39:size = handle05_2f_39_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3a:size = handle05_2f_3a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3b:size = handle05_2f_3b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3c:size = handle05_2f_3c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3d:size = handle05_2f_3d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3e:size = handle05_2f_3e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3f:size = handle05_2f_3f_dasm(stream, pc, op, opcodes); break; // ZOPs (Zero Operand Opcodes) } return size; } -int arcompact_handle04_2f_3f_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_2f_3f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { int size = 4; uint8_t subinstr3 = (op & 0x07000000) >> 24; @@ -385,77 +382,77 @@ int arcompact_handle04_2f_3f_dasm(DASM_OPS_32) switch (subinstr3) { - case 0x00: size = arcompact_handle04_2f_3f_00_dasm(DASM_PARAMS); break; // illegal - case 0x01: size = arcompact_handle04_2f_3f_01_dasm(DASM_PARAMS); break; // SLEEP - case 0x02: size = arcompact_handle04_2f_3f_02_dasm(DASM_PARAMS); break; // SWI / TRAP9 - case 0x03: size = arcompact_handle04_2f_3f_03_dasm(DASM_PARAMS); break; // SYNC - case 0x04: size = arcompact_handle04_2f_3f_04_dasm(DASM_PARAMS); break; // RTIE - case 0x05: size = arcompact_handle04_2f_3f_05_dasm(DASM_PARAMS); break; // BRK - case 0x06: size = arcompact_handle04_2f_3f_06_dasm(DASM_PARAMS); break; // illegal - case 0x07: size = arcompact_handle04_2f_3f_07_dasm(DASM_PARAMS); break; // illegal - case 0x08: size = arcompact_handle04_2f_3f_08_dasm(DASM_PARAMS); break; // illegal - case 0x09: size = arcompact_handle04_2f_3f_09_dasm(DASM_PARAMS); break; // illegal - case 0x0a: size = arcompact_handle04_2f_3f_0a_dasm(DASM_PARAMS); break; // illegal - case 0x0b: size = arcompact_handle04_2f_3f_0b_dasm(DASM_PARAMS); break; // illegal - case 0x0c: size = arcompact_handle04_2f_3f_0c_dasm(DASM_PARAMS); break; // illegal - case 0x0d: size = arcompact_handle04_2f_3f_0d_dasm(DASM_PARAMS); break; // illegal - case 0x0e: size = arcompact_handle04_2f_3f_0e_dasm(DASM_PARAMS); break; // illegal - case 0x0f: size = arcompact_handle04_2f_3f_0f_dasm(DASM_PARAMS); break; // illegal - case 0x10: size = arcompact_handle04_2f_3f_10_dasm(DASM_PARAMS); break; // illegal - case 0x11: size = arcompact_handle04_2f_3f_11_dasm(DASM_PARAMS); break; // illegal - case 0x12: size = arcompact_handle04_2f_3f_12_dasm(DASM_PARAMS); break; // illegal - case 0x13: size = arcompact_handle04_2f_3f_13_dasm(DASM_PARAMS); break; // illegal - case 0x14: size = arcompact_handle04_2f_3f_14_dasm(DASM_PARAMS); break; // illegal - case 0x15: size = arcompact_handle04_2f_3f_15_dasm(DASM_PARAMS); break; // illegal - case 0x16: size = arcompact_handle04_2f_3f_16_dasm(DASM_PARAMS); break; // illegal - case 0x17: size = arcompact_handle04_2f_3f_17_dasm(DASM_PARAMS); break; // illegal - case 0x18: size = arcompact_handle04_2f_3f_18_dasm(DASM_PARAMS); break; // illegal - case 0x19: size = arcompact_handle04_2f_3f_19_dasm(DASM_PARAMS); break; // illegal - case 0x1a: size = arcompact_handle04_2f_3f_1a_dasm(DASM_PARAMS); break; // illegal - case 0x1b: size = arcompact_handle04_2f_3f_1b_dasm(DASM_PARAMS); break; // illegal - case 0x1c: size = arcompact_handle04_2f_3f_1c_dasm(DASM_PARAMS); break; // illegal - case 0x1d: size = arcompact_handle04_2f_3f_1d_dasm(DASM_PARAMS); break; // illegal - case 0x1e: size = arcompact_handle04_2f_3f_1e_dasm(DASM_PARAMS); break; // illegal - case 0x1f: size = arcompact_handle04_2f_3f_1f_dasm(DASM_PARAMS); break; // illegal - case 0x20: size = arcompact_handle04_2f_3f_20_dasm(DASM_PARAMS); break; // illegal - case 0x21: size = arcompact_handle04_2f_3f_21_dasm(DASM_PARAMS); break; // illegal - case 0x22: size = arcompact_handle04_2f_3f_22_dasm(DASM_PARAMS); break; // illegal - case 0x23: size = arcompact_handle04_2f_3f_23_dasm(DASM_PARAMS); break; // illegal - case 0x24: size = arcompact_handle04_2f_3f_24_dasm(DASM_PARAMS); break; // illegal - case 0x25: size = arcompact_handle04_2f_3f_25_dasm(DASM_PARAMS); break; // illegal - case 0x26: size = arcompact_handle04_2f_3f_26_dasm(DASM_PARAMS); break; // illegal - case 0x27: size = arcompact_handle04_2f_3f_27_dasm(DASM_PARAMS); break; // illegal - case 0x28: size = arcompact_handle04_2f_3f_28_dasm(DASM_PARAMS); break; // illegal - case 0x29: size = arcompact_handle04_2f_3f_29_dasm(DASM_PARAMS); break; // illegal - case 0x2a: size = arcompact_handle04_2f_3f_2a_dasm(DASM_PARAMS); break; // illegal - case 0x2b: size = arcompact_handle04_2f_3f_2b_dasm(DASM_PARAMS); break; // illegal - case 0x2c: size = arcompact_handle04_2f_3f_2c_dasm(DASM_PARAMS); break; // illegal - case 0x2d: size = arcompact_handle04_2f_3f_2d_dasm(DASM_PARAMS); break; // illegal - case 0x2e: size = arcompact_handle04_2f_3f_2e_dasm(DASM_PARAMS); break; // illegal - case 0x2f: size = arcompact_handle04_2f_3f_2f_dasm(DASM_PARAMS); break; // illegal - case 0x30: size = arcompact_handle04_2f_3f_30_dasm(DASM_PARAMS); break; // illegal - case 0x31: size = arcompact_handle04_2f_3f_31_dasm(DASM_PARAMS); break; // illegal - case 0x32: size = arcompact_handle04_2f_3f_32_dasm(DASM_PARAMS); break; // illegal - case 0x33: size = arcompact_handle04_2f_3f_33_dasm(DASM_PARAMS); break; // illegal - case 0x34: size = arcompact_handle04_2f_3f_34_dasm(DASM_PARAMS); break; // illegal - case 0x35: size = arcompact_handle04_2f_3f_35_dasm(DASM_PARAMS); break; // illegal - case 0x36: size = arcompact_handle04_2f_3f_36_dasm(DASM_PARAMS); break; // illegal - case 0x37: size = arcompact_handle04_2f_3f_37_dasm(DASM_PARAMS); break; // illegal - case 0x38: size = arcompact_handle04_2f_3f_38_dasm(DASM_PARAMS); break; // illegal - case 0x39: size = arcompact_handle04_2f_3f_39_dasm(DASM_PARAMS); break; // illegal - case 0x3a: size = arcompact_handle04_2f_3f_3a_dasm(DASM_PARAMS); break; // illegal - case 0x3b: size = arcompact_handle04_2f_3f_3b_dasm(DASM_PARAMS); break; // illegal - case 0x3c: size = arcompact_handle04_2f_3f_3c_dasm(DASM_PARAMS); break; // illegal - case 0x3d: size = arcompact_handle04_2f_3f_3d_dasm(DASM_PARAMS); break; // illegal - case 0x3e: size = arcompact_handle04_2f_3f_3e_dasm(DASM_PARAMS); break; // illegal - case 0x3f: size = arcompact_handle04_2f_3f_3f_dasm(DASM_PARAMS); break; // illegal + case 0x00:size = handle04_2f_3f_00_dasm(stream, pc, op, opcodes); break; // illegal + case 0x01:size = handle04_2f_3f_01_dasm(stream, pc, op, opcodes); break; // SLEEP + case 0x02:size = handle04_2f_3f_02_dasm(stream, pc, op, opcodes); break; // SWI / TRAP9 + case 0x03:size = handle04_2f_3f_03_dasm(stream, pc, op, opcodes); break; // SYNC + case 0x04:size = handle04_2f_3f_04_dasm(stream, pc, op, opcodes); break; // RTIE + case 0x05:size = handle04_2f_3f_05_dasm(stream, pc, op, opcodes); break; // BRK + case 0x06:size = handle04_2f_3f_06_dasm(stream, pc, op, opcodes); break; // illegal + case 0x07:size = handle04_2f_3f_07_dasm(stream, pc, op, opcodes); break; // illegal + case 0x08:size = handle04_2f_3f_08_dasm(stream, pc, op, opcodes); break; // illegal + case 0x09:size = handle04_2f_3f_09_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0a:size = handle04_2f_3f_0a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0b:size = handle04_2f_3f_0b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0c:size = handle04_2f_3f_0c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0d:size = handle04_2f_3f_0d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0e:size = handle04_2f_3f_0e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0f:size = handle04_2f_3f_0f_dasm(stream, pc, op, opcodes); break; // illegal + case 0x10:size = handle04_2f_3f_10_dasm(stream, pc, op, opcodes); break; // illegal + case 0x11:size = handle04_2f_3f_11_dasm(stream, pc, op, opcodes); break; // illegal + case 0x12:size = handle04_2f_3f_12_dasm(stream, pc, op, opcodes); break; // illegal + case 0x13:size = handle04_2f_3f_13_dasm(stream, pc, op, opcodes); break; // illegal + case 0x14:size = handle04_2f_3f_14_dasm(stream, pc, op, opcodes); break; // illegal + case 0x15:size = handle04_2f_3f_15_dasm(stream, pc, op, opcodes); break; // illegal + case 0x16:size = handle04_2f_3f_16_dasm(stream, pc, op, opcodes); break; // illegal + case 0x17:size = handle04_2f_3f_17_dasm(stream, pc, op, opcodes); break; // illegal + case 0x18:size = handle04_2f_3f_18_dasm(stream, pc, op, opcodes); break; // illegal + case 0x19:size = handle04_2f_3f_19_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1a:size = handle04_2f_3f_1a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1b:size = handle04_2f_3f_1b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1c:size = handle04_2f_3f_1c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1d:size = handle04_2f_3f_1d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1e:size = handle04_2f_3f_1e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1f:size = handle04_2f_3f_1f_dasm(stream, pc, op, opcodes); break; // illegal + case 0x20:size = handle04_2f_3f_20_dasm(stream, pc, op, opcodes); break; // illegal + case 0x21:size = handle04_2f_3f_21_dasm(stream, pc, op, opcodes); break; // illegal + case 0x22:size = handle04_2f_3f_22_dasm(stream, pc, op, opcodes); break; // illegal + case 0x23:size = handle04_2f_3f_23_dasm(stream, pc, op, opcodes); break; // illegal + case 0x24:size = handle04_2f_3f_24_dasm(stream, pc, op, opcodes); break; // illegal + case 0x25:size = handle04_2f_3f_25_dasm(stream, pc, op, opcodes); break; // illegal + case 0x26:size = handle04_2f_3f_26_dasm(stream, pc, op, opcodes); break; // illegal + case 0x27:size = handle04_2f_3f_27_dasm(stream, pc, op, opcodes); break; // illegal + case 0x28:size = handle04_2f_3f_28_dasm(stream, pc, op, opcodes); break; // illegal + case 0x29:size = handle04_2f_3f_29_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2a:size = handle04_2f_3f_2a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2b:size = handle04_2f_3f_2b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2c:size = handle04_2f_3f_2c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2d:size = handle04_2f_3f_2d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2e:size = handle04_2f_3f_2e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2f:size = handle04_2f_3f_2f_dasm(stream, pc, op, opcodes); break; // illegal + case 0x30:size = handle04_2f_3f_30_dasm(stream, pc, op, opcodes); break; // illegal + case 0x31:size = handle04_2f_3f_31_dasm(stream, pc, op, opcodes); break; // illegal + case 0x32:size = handle04_2f_3f_32_dasm(stream, pc, op, opcodes); break; // illegal + case 0x33:size = handle04_2f_3f_33_dasm(stream, pc, op, opcodes); break; // illegal + case 0x34:size = handle04_2f_3f_34_dasm(stream, pc, op, opcodes); break; // illegal + case 0x35:size = handle04_2f_3f_35_dasm(stream, pc, op, opcodes); break; // illegal + case 0x36:size = handle04_2f_3f_36_dasm(stream, pc, op, opcodes); break; // illegal + case 0x37:size = handle04_2f_3f_37_dasm(stream, pc, op, opcodes); break; // illegal + case 0x38:size = handle04_2f_3f_38_dasm(stream, pc, op, opcodes); break; // illegal + case 0x39:size = handle04_2f_3f_39_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3a:size = handle04_2f_3f_3a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3b:size = handle04_2f_3f_3b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3c:size = handle04_2f_3f_3c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3d:size = handle04_2f_3f_3d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3e:size = handle04_2f_3f_3e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3f:size = handle04_2f_3f_3f_dasm(stream, pc, op, opcodes); break; // illegal } return size; } -int arcompact_handle05_2f_3f_dasm(DASM_OPS_32) // useless ZOP group, no actual opcodes +int arcompact_disassembler::handle05_2f_3f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) // useless ZOP group, no actual opcodes { int size = 4; uint8_t subinstr3 = (op & 0x07000000) >> 24; @@ -465,70 +462,70 @@ int arcompact_handle05_2f_3f_dasm(DASM_OPS_32) // useless ZOP group, no actual o switch (subinstr3) { - case 0x00: size = arcompact_handle05_2f_3f_00_dasm(DASM_PARAMS); break; // illegal - case 0x01: size = arcompact_handle05_2f_3f_01_dasm(DASM_PARAMS); break; // illegal - case 0x02: size = arcompact_handle05_2f_3f_02_dasm(DASM_PARAMS); break; // illegal - case 0x03: size = arcompact_handle05_2f_3f_03_dasm(DASM_PARAMS); break; // illegal - case 0x04: size = arcompact_handle05_2f_3f_04_dasm(DASM_PARAMS); break; // illegal - case 0x05: size = arcompact_handle05_2f_3f_05_dasm(DASM_PARAMS); break; // illegal - case 0x06: size = arcompact_handle05_2f_3f_06_dasm(DASM_PARAMS); break; // illegal - case 0x07: size = arcompact_handle05_2f_3f_07_dasm(DASM_PARAMS); break; // illegal - case 0x08: size = arcompact_handle05_2f_3f_08_dasm(DASM_PARAMS); break; // illegal - case 0x09: size = arcompact_handle05_2f_3f_09_dasm(DASM_PARAMS); break; // illegal - case 0x0a: size = arcompact_handle05_2f_3f_0a_dasm(DASM_PARAMS); break; // illegal - case 0x0b: size = arcompact_handle05_2f_3f_0b_dasm(DASM_PARAMS); break; // illegal - case 0x0c: size = arcompact_handle05_2f_3f_0c_dasm(DASM_PARAMS); break; // illegal - case 0x0d: size = arcompact_handle05_2f_3f_0d_dasm(DASM_PARAMS); break; // illegal - case 0x0e: size = arcompact_handle05_2f_3f_0e_dasm(DASM_PARAMS); break; // illegal - case 0x0f: size = arcompact_handle05_2f_3f_0f_dasm(DASM_PARAMS); break; // illegal - case 0x10: size = arcompact_handle05_2f_3f_10_dasm(DASM_PARAMS); break; // illegal - case 0x11: size = arcompact_handle05_2f_3f_11_dasm(DASM_PARAMS); break; // illegal - case 0x12: size = arcompact_handle05_2f_3f_12_dasm(DASM_PARAMS); break; // illegal - case 0x13: size = arcompact_handle05_2f_3f_13_dasm(DASM_PARAMS); break; // illegal - case 0x14: size = arcompact_handle05_2f_3f_14_dasm(DASM_PARAMS); break; // illegal - case 0x15: size = arcompact_handle05_2f_3f_15_dasm(DASM_PARAMS); break; // illegal - case 0x16: size = arcompact_handle05_2f_3f_16_dasm(DASM_PARAMS); break; // illegal - case 0x17: size = arcompact_handle05_2f_3f_17_dasm(DASM_PARAMS); break; // illegal - case 0x18: size = arcompact_handle05_2f_3f_18_dasm(DASM_PARAMS); break; // illegal - case 0x19: size = arcompact_handle05_2f_3f_19_dasm(DASM_PARAMS); break; // illegal - case 0x1a: size = arcompact_handle05_2f_3f_1a_dasm(DASM_PARAMS); break; // illegal - case 0x1b: size = arcompact_handle05_2f_3f_1b_dasm(DASM_PARAMS); break; // illegal - case 0x1c: size = arcompact_handle05_2f_3f_1c_dasm(DASM_PARAMS); break; // illegal - case 0x1d: size = arcompact_handle05_2f_3f_1d_dasm(DASM_PARAMS); break; // illegal - case 0x1e: size = arcompact_handle05_2f_3f_1e_dasm(DASM_PARAMS); break; // illegal - case 0x1f: size = arcompact_handle05_2f_3f_1f_dasm(DASM_PARAMS); break; // illegal - case 0x20: size = arcompact_handle05_2f_3f_20_dasm(DASM_PARAMS); break; // illegal - case 0x21: size = arcompact_handle05_2f_3f_21_dasm(DASM_PARAMS); break; // illegal - case 0x22: size = arcompact_handle05_2f_3f_22_dasm(DASM_PARAMS); break; // illegal - case 0x23: size = arcompact_handle05_2f_3f_23_dasm(DASM_PARAMS); break; // illegal - case 0x24: size = arcompact_handle05_2f_3f_24_dasm(DASM_PARAMS); break; // illegal - case 0x25: size = arcompact_handle05_2f_3f_25_dasm(DASM_PARAMS); break; // illegal - case 0x26: size = arcompact_handle05_2f_3f_26_dasm(DASM_PARAMS); break; // illegal - case 0x27: size = arcompact_handle05_2f_3f_27_dasm(DASM_PARAMS); break; // illegal - case 0x28: size = arcompact_handle05_2f_3f_28_dasm(DASM_PARAMS); break; // illegal - case 0x29: size = arcompact_handle05_2f_3f_29_dasm(DASM_PARAMS); break; // illegal - case 0x2a: size = arcompact_handle05_2f_3f_2a_dasm(DASM_PARAMS); break; // illegal - case 0x2b: size = arcompact_handle05_2f_3f_2b_dasm(DASM_PARAMS); break; // illegal - case 0x2c: size = arcompact_handle05_2f_3f_2c_dasm(DASM_PARAMS); break; // illegal - case 0x2d: size = arcompact_handle05_2f_3f_2d_dasm(DASM_PARAMS); break; // illegal - case 0x2e: size = arcompact_handle05_2f_3f_2e_dasm(DASM_PARAMS); break; // illegal - case 0x2f: size = arcompact_handle05_2f_3f_2f_dasm(DASM_PARAMS); break; // illegal - case 0x30: size = arcompact_handle05_2f_3f_30_dasm(DASM_PARAMS); break; // illegal - case 0x31: size = arcompact_handle05_2f_3f_31_dasm(DASM_PARAMS); break; // illegal - case 0x32: size = arcompact_handle05_2f_3f_32_dasm(DASM_PARAMS); break; // illegal - case 0x33: size = arcompact_handle05_2f_3f_33_dasm(DASM_PARAMS); break; // illegal - case 0x34: size = arcompact_handle05_2f_3f_34_dasm(DASM_PARAMS); break; // illegal - case 0x35: size = arcompact_handle05_2f_3f_35_dasm(DASM_PARAMS); break; // illegal - case 0x36: size = arcompact_handle05_2f_3f_36_dasm(DASM_PARAMS); break; // illegal - case 0x37: size = arcompact_handle05_2f_3f_37_dasm(DASM_PARAMS); break; // illegal - case 0x38: size = arcompact_handle05_2f_3f_38_dasm(DASM_PARAMS); break; // illegal - case 0x39: size = arcompact_handle05_2f_3f_39_dasm(DASM_PARAMS); break; // illegal - case 0x3a: size = arcompact_handle05_2f_3f_3a_dasm(DASM_PARAMS); break; // illegal - case 0x3b: size = arcompact_handle05_2f_3f_3b_dasm(DASM_PARAMS); break; // illegal - case 0x3c: size = arcompact_handle05_2f_3f_3c_dasm(DASM_PARAMS); break; // illegal - case 0x3d: size = arcompact_handle05_2f_3f_3d_dasm(DASM_PARAMS); break; // illegal - case 0x3e: size = arcompact_handle05_2f_3f_3e_dasm(DASM_PARAMS); break; // illegal - case 0x3f: size = arcompact_handle05_2f_3f_3f_dasm(DASM_PARAMS); break; // illegal + case 0x00:size = handle05_2f_3f_00_dasm(stream, pc, op, opcodes); break; // illegal + case 0x01:size = handle05_2f_3f_01_dasm(stream, pc, op, opcodes); break; // illegal + case 0x02:size = handle05_2f_3f_02_dasm(stream, pc, op, opcodes); break; // illegal + case 0x03:size = handle05_2f_3f_03_dasm(stream, pc, op, opcodes); break; // illegal + case 0x04:size = handle05_2f_3f_04_dasm(stream, pc, op, opcodes); break; // illegal + case 0x05:size = handle05_2f_3f_05_dasm(stream, pc, op, opcodes); break; // illegal + case 0x06:size = handle05_2f_3f_06_dasm(stream, pc, op, opcodes); break; // illegal + case 0x07:size = handle05_2f_3f_07_dasm(stream, pc, op, opcodes); break; // illegal + case 0x08:size = handle05_2f_3f_08_dasm(stream, pc, op, opcodes); break; // illegal + case 0x09:size = handle05_2f_3f_09_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0a:size = handle05_2f_3f_0a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0b:size = handle05_2f_3f_0b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0c:size = handle05_2f_3f_0c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0d:size = handle05_2f_3f_0d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0e:size = handle05_2f_3f_0e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0f:size = handle05_2f_3f_0f_dasm(stream, pc, op, opcodes); break; // illegal + case 0x10:size = handle05_2f_3f_10_dasm(stream, pc, op, opcodes); break; // illegal + case 0x11:size = handle05_2f_3f_11_dasm(stream, pc, op, opcodes); break; // illegal + case 0x12:size = handle05_2f_3f_12_dasm(stream, pc, op, opcodes); break; // illegal + case 0x13:size = handle05_2f_3f_13_dasm(stream, pc, op, opcodes); break; // illegal + case 0x14:size = handle05_2f_3f_14_dasm(stream, pc, op, opcodes); break; // illegal + case 0x15:size = handle05_2f_3f_15_dasm(stream, pc, op, opcodes); break; // illegal + case 0x16:size = handle05_2f_3f_16_dasm(stream, pc, op, opcodes); break; // illegal + case 0x17:size = handle05_2f_3f_17_dasm(stream, pc, op, opcodes); break; // illegal + case 0x18:size = handle05_2f_3f_18_dasm(stream, pc, op, opcodes); break; // illegal + case 0x19:size = handle05_2f_3f_19_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1a:size = handle05_2f_3f_1a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1b:size = handle05_2f_3f_1b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1c:size = handle05_2f_3f_1c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1d:size = handle05_2f_3f_1d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1e:size = handle05_2f_3f_1e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1f:size = handle05_2f_3f_1f_dasm(stream, pc, op, opcodes); break; // illegal + case 0x20:size = handle05_2f_3f_20_dasm(stream, pc, op, opcodes); break; // illegal + case 0x21:size = handle05_2f_3f_21_dasm(stream, pc, op, opcodes); break; // illegal + case 0x22:size = handle05_2f_3f_22_dasm(stream, pc, op, opcodes); break; // illegal + case 0x23:size = handle05_2f_3f_23_dasm(stream, pc, op, opcodes); break; // illegal + case 0x24:size = handle05_2f_3f_24_dasm(stream, pc, op, opcodes); break; // illegal + case 0x25:size = handle05_2f_3f_25_dasm(stream, pc, op, opcodes); break; // illegal + case 0x26:size = handle05_2f_3f_26_dasm(stream, pc, op, opcodes); break; // illegal + case 0x27:size = handle05_2f_3f_27_dasm(stream, pc, op, opcodes); break; // illegal + case 0x28:size = handle05_2f_3f_28_dasm(stream, pc, op, opcodes); break; // illegal + case 0x29:size = handle05_2f_3f_29_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2a:size = handle05_2f_3f_2a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2b:size = handle05_2f_3f_2b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2c:size = handle05_2f_3f_2c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2d:size = handle05_2f_3f_2d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2e:size = handle05_2f_3f_2e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2f:size = handle05_2f_3f_2f_dasm(stream, pc, op, opcodes); break; // illegal + case 0x30:size = handle05_2f_3f_30_dasm(stream, pc, op, opcodes); break; // illegal + case 0x31:size = handle05_2f_3f_31_dasm(stream, pc, op, opcodes); break; // illegal + case 0x32:size = handle05_2f_3f_32_dasm(stream, pc, op, opcodes); break; // illegal + case 0x33:size = handle05_2f_3f_33_dasm(stream, pc, op, opcodes); break; // illegal + case 0x34:size = handle05_2f_3f_34_dasm(stream, pc, op, opcodes); break; // illegal + case 0x35:size = handle05_2f_3f_35_dasm(stream, pc, op, opcodes); break; // illegal + case 0x36:size = handle05_2f_3f_36_dasm(stream, pc, op, opcodes); break; // illegal + case 0x37:size = handle05_2f_3f_37_dasm(stream, pc, op, opcodes); break; // illegal + case 0x38:size = handle05_2f_3f_38_dasm(stream, pc, op, opcodes); break; // illegal + case 0x39:size = handle05_2f_3f_39_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3a:size = handle05_2f_3f_3a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3b:size = handle05_2f_3f_3b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3c:size = handle05_2f_3f_3c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3d:size = handle05_2f_3f_3d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3e:size = handle05_2f_3f_3e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3f:size = handle05_2f_3f_3f_dasm(stream, pc, op, opcodes); break; // illegal } return size; @@ -536,7 +533,7 @@ int arcompact_handle05_2f_3f_dasm(DASM_OPS_32) // useless ZOP group, no actual o // this is an Extension ALU group, maybe optional on some CPUs? -int arcompact_handle05_dasm(DASM_OPS_32) +int arcompact_disassembler::handle05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { int size = 4; uint8_t subinstr = (op & 0x003f0000) >> 16; @@ -544,76 +541,76 @@ int arcompact_handle05_dasm(DASM_OPS_32) switch (subinstr) { - case 0x00: size = arcompact_handle05_00_dasm(DASM_PARAMS); break; // ASL - case 0x01: size = arcompact_handle05_01_dasm(DASM_PARAMS); break; // LSR - case 0x02: size = arcompact_handle05_02_dasm(DASM_PARAMS); break; // ASR - case 0x03: size = arcompact_handle05_03_dasm(DASM_PARAMS); break; // ROR - case 0x04: size = arcompact_handle05_04_dasm(DASM_PARAMS); break; // MUL64 - case 0x05: size = arcompact_handle05_05_dasm(DASM_PARAMS); break; // MULU64 - case 0x06: size = arcompact_handle05_06_dasm(DASM_PARAMS); break; // ADDS - case 0x07: size = arcompact_handle05_07_dasm(DASM_PARAMS); break; // SUBS - case 0x08: size = arcompact_handle05_08_dasm(DASM_PARAMS); break; // DIVAW - case 0x09: size = arcompact_handle05_09_dasm(DASM_PARAMS); break; // illegal - case 0x0a: size = arcompact_handle05_0a_dasm(DASM_PARAMS); break; // ASLS - case 0x0b: size = arcompact_handle05_0b_dasm(DASM_PARAMS); break; // ASRS - case 0x0c: size = arcompact_handle05_0c_dasm(DASM_PARAMS); break; // illegal - case 0x0d: size = arcompact_handle05_0d_dasm(DASM_PARAMS); break; // illegal - case 0x0e: size = arcompact_handle05_0e_dasm(DASM_PARAMS); break; // illegal - case 0x0f: size = arcompact_handle05_0f_dasm(DASM_PARAMS); break; // illegal - case 0x10: size = arcompact_handle05_10_dasm(DASM_PARAMS); break; // illegal - case 0x11: size = arcompact_handle05_11_dasm(DASM_PARAMS); break; // illegal - case 0x12: size = arcompact_handle05_12_dasm(DASM_PARAMS); break; // illegal - case 0x13: size = arcompact_handle05_13_dasm(DASM_PARAMS); break; // illegal - case 0x14: size = arcompact_handle05_14_dasm(DASM_PARAMS); break; // illegal - case 0x15: size = arcompact_handle05_15_dasm(DASM_PARAMS); break; // illegal - case 0x16: size = arcompact_handle05_16_dasm(DASM_PARAMS); break; // illegal - case 0x17: size = arcompact_handle05_17_dasm(DASM_PARAMS); break; // illegal - case 0x18: size = arcompact_handle05_18_dasm(DASM_PARAMS); break; // illegal - case 0x19: size = arcompact_handle05_19_dasm(DASM_PARAMS); break; // illegal - case 0x1a: size = arcompact_handle05_1a_dasm(DASM_PARAMS); break; // illegal - case 0x1b: size = arcompact_handle05_1b_dasm(DASM_PARAMS); break; // illegal - case 0x1c: size = arcompact_handle05_1c_dasm(DASM_PARAMS); break; // illegal - case 0x1d: size = arcompact_handle05_1d_dasm(DASM_PARAMS); break; // illegal - case 0x1e: size = arcompact_handle05_1e_dasm(DASM_PARAMS); break; // illegal - case 0x1f: size = arcompact_handle05_1f_dasm(DASM_PARAMS); break; // illegal - case 0x20: size = arcompact_handle05_20_dasm(DASM_PARAMS); break; // illegal - case 0x21: size = arcompact_handle05_21_dasm(DASM_PARAMS); break; // illegal - case 0x22: size = arcompact_handle05_22_dasm(DASM_PARAMS); break; // illegal - case 0x23: size = arcompact_handle05_23_dasm(DASM_PARAMS); break; // illegal - case 0x24: size = arcompact_handle05_24_dasm(DASM_PARAMS); break; // illegal - case 0x25: size = arcompact_handle05_25_dasm(DASM_PARAMS); break; // illegal - case 0x26: size = arcompact_handle05_26_dasm(DASM_PARAMS); break; // illegal - case 0x27: size = arcompact_handle05_27_dasm(DASM_PARAMS); break; // illegal - case 0x28: size = arcompact_handle05_28_dasm(DASM_PARAMS); break; // ADDSDW - case 0x29: size = arcompact_handle05_29_dasm(DASM_PARAMS); break; // SUBSDW - case 0x2a: size = arcompact_handle05_2a_dasm(DASM_PARAMS); break; // illegal - case 0x2b: size = arcompact_handle05_2b_dasm(DASM_PARAMS); break; // illegal - case 0x2c: size = arcompact_handle05_2c_dasm(DASM_PARAMS); break; // illegal - case 0x2d: size = arcompact_handle05_2d_dasm(DASM_PARAMS); break; // illegal - case 0x2e: size = arcompact_handle05_2e_dasm(DASM_PARAMS); break; // illegal - case 0x2f: size = arcompact_handle05_2f_dasm(DASM_PARAMS); break; // SOPs - case 0x30: size = arcompact_handle05_30_dasm(DASM_PARAMS); break; // illegal - case 0x31: size = arcompact_handle05_31_dasm(DASM_PARAMS); break; // illegal - case 0x32: size = arcompact_handle05_32_dasm(DASM_PARAMS); break; // illegal - case 0x33: size = arcompact_handle05_33_dasm(DASM_PARAMS); break; // illegal - case 0x34: size = arcompact_handle05_34_dasm(DASM_PARAMS); break; // illegal - case 0x35: size = arcompact_handle05_35_dasm(DASM_PARAMS); break; // illegal - case 0x36: size = arcompact_handle05_36_dasm(DASM_PARAMS); break; // illegal - case 0x37: size = arcompact_handle05_37_dasm(DASM_PARAMS); break; // illegal - case 0x38: size = arcompact_handle05_38_dasm(DASM_PARAMS); break; // illegal - case 0x39: size = arcompact_handle05_39_dasm(DASM_PARAMS); break; // illegal - case 0x3a: size = arcompact_handle05_3a_dasm(DASM_PARAMS); break; // illegal - case 0x3b: size = arcompact_handle05_3b_dasm(DASM_PARAMS); break; // illegal - case 0x3c: size = arcompact_handle05_3c_dasm(DASM_PARAMS); break; // illegal - case 0x3d: size = arcompact_handle05_3d_dasm(DASM_PARAMS); break; // illegal - case 0x3e: size = arcompact_handle05_3e_dasm(DASM_PARAMS); break; // illegal - case 0x3f: size = arcompact_handle05_3f_dasm(DASM_PARAMS); break; // illegal + case 0x00:size = handle05_00_dasm(stream, pc, op, opcodes); break; // ASL + case 0x01:size = handle05_01_dasm(stream, pc, op, opcodes); break; // LSR + case 0x02:size = handle05_02_dasm(stream, pc, op, opcodes); break; // ASR + case 0x03:size = handle05_03_dasm(stream, pc, op, opcodes); break; // ROR + case 0x04:size = handle05_04_dasm(stream, pc, op, opcodes); break; // MUL64 + case 0x05:size = handle05_05_dasm(stream, pc, op, opcodes); break; // MULU64 + case 0x06:size = handle05_06_dasm(stream, pc, op, opcodes); break; // ADDS + case 0x07:size = handle05_07_dasm(stream, pc, op, opcodes); break; // SUBS + case 0x08:size = handle05_08_dasm(stream, pc, op, opcodes); break; // DIVAW + case 0x09:size = handle05_09_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0a:size = handle05_0a_dasm(stream, pc, op, opcodes); break; // ASLS + case 0x0b:size = handle05_0b_dasm(stream, pc, op, opcodes); break; // ASRS + case 0x0c:size = handle05_0c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0d:size = handle05_0d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0e:size = handle05_0e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0f:size = handle05_0f_dasm(stream, pc, op, opcodes); break; // illegal + case 0x10:size = handle05_10_dasm(stream, pc, op, opcodes); break; // illegal + case 0x11:size = handle05_11_dasm(stream, pc, op, opcodes); break; // illegal + case 0x12:size = handle05_12_dasm(stream, pc, op, opcodes); break; // illegal + case 0x13:size = handle05_13_dasm(stream, pc, op, opcodes); break; // illegal + case 0x14:size = handle05_14_dasm(stream, pc, op, opcodes); break; // illegal + case 0x15:size = handle05_15_dasm(stream, pc, op, opcodes); break; // illegal + case 0x16:size = handle05_16_dasm(stream, pc, op, opcodes); break; // illegal + case 0x17:size = handle05_17_dasm(stream, pc, op, opcodes); break; // illegal + case 0x18:size = handle05_18_dasm(stream, pc, op, opcodes); break; // illegal + case 0x19:size = handle05_19_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1a:size = handle05_1a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1b:size = handle05_1b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1c:size = handle05_1c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1d:size = handle05_1d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1e:size = handle05_1e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1f:size = handle05_1f_dasm(stream, pc, op, opcodes); break; // illegal + case 0x20:size = handle05_20_dasm(stream, pc, op, opcodes); break; // illegal + case 0x21:size = handle05_21_dasm(stream, pc, op, opcodes); break; // illegal + case 0x22:size = handle05_22_dasm(stream, pc, op, opcodes); break; // illegal + case 0x23:size = handle05_23_dasm(stream, pc, op, opcodes); break; // illegal + case 0x24:size = handle05_24_dasm(stream, pc, op, opcodes); break; // illegal + case 0x25:size = handle05_25_dasm(stream, pc, op, opcodes); break; // illegal + case 0x26:size = handle05_26_dasm(stream, pc, op, opcodes); break; // illegal + case 0x27:size = handle05_27_dasm(stream, pc, op, opcodes); break; // illegal + case 0x28:size = handle05_28_dasm(stream, pc, op, opcodes); break; // ADDSDW + case 0x29:size = handle05_29_dasm(stream, pc, op, opcodes); break; // SUBSDW + case 0x2a:size = handle05_2a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2b:size = handle05_2b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2c:size = handle05_2c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2d:size = handle05_2d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2e:size = handle05_2e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2f:size = handle05_2f_dasm(stream, pc, op, opcodes); break; // SOPs + case 0x30:size = handle05_30_dasm(stream, pc, op, opcodes); break; // illegal + case 0x31:size = handle05_31_dasm(stream, pc, op, opcodes); break; // illegal + case 0x32:size = handle05_32_dasm(stream, pc, op, opcodes); break; // illegal + case 0x33:size = handle05_33_dasm(stream, pc, op, opcodes); break; // illegal + case 0x34:size = handle05_34_dasm(stream, pc, op, opcodes); break; // illegal + case 0x35:size = handle05_35_dasm(stream, pc, op, opcodes); break; // illegal + case 0x36:size = handle05_36_dasm(stream, pc, op, opcodes); break; // illegal + case 0x37:size = handle05_37_dasm(stream, pc, op, opcodes); break; // illegal + case 0x38:size = handle05_38_dasm(stream, pc, op, opcodes); break; // illegal + case 0x39:size = handle05_39_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3a:size = handle05_3a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3b:size = handle05_3b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3c:size = handle05_3c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3d:size = handle05_3d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3e:size = handle05_3e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3f:size = handle05_3f_dasm(stream, pc, op, opcodes); break; // illegal } return size; } -int arcompact_handle0c_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0c_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int size = 2; uint8_t subinstr = (op & 0x0018) >> 3; @@ -621,15 +618,15 @@ int arcompact_handle0c_dasm(DASM_OPS_16) switch (subinstr) { - case 0x00: size = arcompact_handle0c_00_dasm(DASM_PARAMS); break; // LD_S - case 0x01: size = arcompact_handle0c_01_dasm(DASM_PARAMS); break; // LDB_S - case 0x02: size = arcompact_handle0c_02_dasm(DASM_PARAMS); break; // LDW_S - case 0x03: size = arcompact_handle0c_03_dasm(DASM_PARAMS); break; // ADD_S + case 0x00:size = handle0c_00_dasm(stream, pc, op, opcodes); break; // LD_S + case 0x01:size = handle0c_01_dasm(stream, pc, op, opcodes); break; // LDB_S + case 0x02:size = handle0c_02_dasm(stream, pc, op, opcodes); break; // LDW_S + case 0x03:size = handle0c_03_dasm(stream, pc, op, opcodes); break; // ADD_S } return size; } -int arcompact_handle0d_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0d_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int size = 2; uint8_t subinstr = (op & 0x0018) >> 3; @@ -637,15 +634,15 @@ int arcompact_handle0d_dasm(DASM_OPS_16) switch (subinstr) { - case 0x00: size = arcompact_handle0d_00_dasm(DASM_PARAMS); break; // ADD_S - case 0x01: size = arcompact_handle0d_01_dasm(DASM_PARAMS); break; // SUB_S - case 0x02: size = arcompact_handle0d_02_dasm(DASM_PARAMS); break; // ASL_S - case 0x03: size = arcompact_handle0d_03_dasm(DASM_PARAMS); break; // ASR_S + case 0x00:size = handle0d_00_dasm(stream, pc, op, opcodes); break; // ADD_S + case 0x01:size = handle0d_01_dasm(stream, pc, op, opcodes); break; // SUB_S + case 0x02:size = handle0d_02_dasm(stream, pc, op, opcodes); break; // ASL_S + case 0x03:size = handle0d_03_dasm(stream, pc, op, opcodes); break; // ASR_S } return size; } -int arcompact_handle0e_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0e_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int size = 2; uint8_t subinstr = (op & 0x0018) >> 3; @@ -653,15 +650,15 @@ int arcompact_handle0e_dasm(DASM_OPS_16) switch (subinstr) { - case 0x00: size = arcompact_handle0e_00_dasm(DASM_PARAMS); break; // ADD_S - case 0x01: size = arcompact_handle0e_01_dasm(DASM_PARAMS); break; // MOV_S - case 0x02: size = arcompact_handle0e_02_dasm(DASM_PARAMS); break; // CMP_S - case 0x03: size = arcompact_handle0e_03_dasm(DASM_PARAMS); break; // MOV_S + case 0x00:size = handle0e_00_dasm(stream, pc, op, opcodes); break; // ADD_S + case 0x01:size = handle0e_01_dasm(stream, pc, op, opcodes); break; // MOV_S + case 0x02:size = handle0e_02_dasm(stream, pc, op, opcodes); break; // CMP_S + case 0x03:size = handle0e_03_dasm(stream, pc, op, opcodes); break; // MOV_S } return size; } -int arcompact_handle0f_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0f_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int size = 2; // General Register Instructions (16-bit) @@ -671,44 +668,44 @@ int arcompact_handle0f_dasm(DASM_OPS_16) switch (subinstr) { - case 0x00: size = arcompact_handle0f_00_dasm(DASM_PARAMS); break; // SOPs - case 0x01: size = arcompact_handle0f_01_dasm(DASM_PARAMS); break; // 0x01 <illegal> - case 0x02: size = arcompact_handle0f_02_dasm(DASM_PARAMS); break; // SUB_S - case 0x03: size = arcompact_handle0f_03_dasm(DASM_PARAMS); break; // 0x03 <illegal> - case 0x04: size = arcompact_handle0f_04_dasm(DASM_PARAMS); break; // AND_S - case 0x05: size = arcompact_handle0f_05_dasm(DASM_PARAMS); break; // OR_S - case 0x06: size = arcompact_handle0f_06_dasm(DASM_PARAMS); break; // BIC_S - case 0x07: size = arcompact_handle0f_07_dasm(DASM_PARAMS); break; // XOR_S - case 0x08: size = arcompact_handle0f_08_dasm(DASM_PARAMS); break; // 0x08 <illegal> - case 0x09: size = arcompact_handle0f_09_dasm(DASM_PARAMS); break; // 0x09 <illegal> - case 0x0a: size = arcompact_handle0f_0a_dasm(DASM_PARAMS); break; // 0x0a <illegal> - case 0x0b: size = arcompact_handle0f_0b_dasm(DASM_PARAMS); break; // TST_S - case 0x0c: size = arcompact_handle0f_0c_dasm(DASM_PARAMS); break; // MUL64_S - case 0x0d: size = arcompact_handle0f_0d_dasm(DASM_PARAMS); break; // SEXB_S - case 0x0e: size = arcompact_handle0f_0e_dasm(DASM_PARAMS); break; // SEXW_S - case 0x0f: size = arcompact_handle0f_0f_dasm(DASM_PARAMS); break; // EXTB_S - case 0x10: size = arcompact_handle0f_10_dasm(DASM_PARAMS); break; // EXTW_S - case 0x11: size = arcompact_handle0f_11_dasm(DASM_PARAMS); break; // ABS_S - case 0x12: size = arcompact_handle0f_12_dasm(DASM_PARAMS); break; // NOT_S - case 0x13: size = arcompact_handle0f_13_dasm(DASM_PARAMS); break; // NEG_S - case 0x14: size = arcompact_handle0f_14_dasm(DASM_PARAMS); break; // ADD1_S - case 0x15: size = arcompact_handle0f_15_dasm(DASM_PARAMS); break; // ADD2_S - case 0x16: size = arcompact_handle0f_16_dasm(DASM_PARAMS); break; // ADD3_S - case 0x17: size = arcompact_handle0f_17_dasm(DASM_PARAMS); break; // 0x17 <illegal> - case 0x18: size = arcompact_handle0f_18_dasm(DASM_PARAMS); break; // ASL_S (multiple) - case 0x19: size = arcompact_handle0f_19_dasm(DASM_PARAMS); break; // LSR_S (multiple) - case 0x1a: size = arcompact_handle0f_1a_dasm(DASM_PARAMS); break; // ASR_S (multiple) - case 0x1b: size = arcompact_handle0f_1b_dasm(DASM_PARAMS); break; // ASL_S (single) - case 0x1c: size = arcompact_handle0f_1c_dasm(DASM_PARAMS); break; // LSR_S (single) - case 0x1d: size = arcompact_handle0f_1d_dasm(DASM_PARAMS); break; // ASR_S (single) - case 0x1e: size = arcompact_handle0f_1e_dasm(DASM_PARAMS); break; // TRAP (not a5?) - case 0x1f: size = arcompact_handle0f_1f_dasm(DASM_PARAMS); break; // BRK_S ( 0x7fff only? ) + case 0x00:size = handle0f_00_dasm(stream, pc, op, opcodes); break; // SOPs + case 0x01:size = handle0f_01_dasm(stream, pc, op, opcodes); break; // 0x01 <illegal> + case 0x02:size = handle0f_02_dasm(stream, pc, op, opcodes); break; // SUB_S + case 0x03:size = handle0f_03_dasm(stream, pc, op, opcodes); break; // 0x03 <illegal> + case 0x04:size = handle0f_04_dasm(stream, pc, op, opcodes); break; // AND_S + case 0x05:size = handle0f_05_dasm(stream, pc, op, opcodes); break; // OR_S + case 0x06:size = handle0f_06_dasm(stream, pc, op, opcodes); break; // BIC_S + case 0x07:size = handle0f_07_dasm(stream, pc, op, opcodes); break; // XOR_S + case 0x08:size = handle0f_08_dasm(stream, pc, op, opcodes); break; // 0x08 <illegal> + case 0x09:size = handle0f_09_dasm(stream, pc, op, opcodes); break; // 0x09 <illegal> + case 0x0a:size = handle0f_0a_dasm(stream, pc, op, opcodes); break; // 0x0a <illegal> + case 0x0b:size = handle0f_0b_dasm(stream, pc, op, opcodes); break; // TST_S + case 0x0c:size = handle0f_0c_dasm(stream, pc, op, opcodes); break; // MUL64_S + case 0x0d:size = handle0f_0d_dasm(stream, pc, op, opcodes); break; // SEXB_S + case 0x0e:size = handle0f_0e_dasm(stream, pc, op, opcodes); break; // SEXW_S + case 0x0f:size = handle0f_0f_dasm(stream, pc, op, opcodes); break; // EXTB_S + case 0x10:size = handle0f_10_dasm(stream, pc, op, opcodes); break; // EXTW_S + case 0x11:size = handle0f_11_dasm(stream, pc, op, opcodes); break; // ABS_S + case 0x12:size = handle0f_12_dasm(stream, pc, op, opcodes); break; // NOT_S + case 0x13:size = handle0f_13_dasm(stream, pc, op, opcodes); break; // NEG_S + case 0x14:size = handle0f_14_dasm(stream, pc, op, opcodes); break; // ADD1_S + case 0x15:size = handle0f_15_dasm(stream, pc, op, opcodes); break; // ADD2_S + case 0x16:size = handle0f_16_dasm(stream, pc, op, opcodes); break; // ADD3_S + case 0x17:size = handle0f_17_dasm(stream, pc, op, opcodes); break; // 0x17 <illegal> + case 0x18:size = handle0f_18_dasm(stream, pc, op, opcodes); break; // ASL_S (multiple) + case 0x19:size = handle0f_19_dasm(stream, pc, op, opcodes); break; // LSR_S (multiple) + case 0x1a:size = handle0f_1a_dasm(stream, pc, op, opcodes); break; // ASR_S (multiple) + case 0x1b:size = handle0f_1b_dasm(stream, pc, op, opcodes); break; // ASL_S (single) + case 0x1c:size = handle0f_1c_dasm(stream, pc, op, opcodes); break; // LSR_S (single) + case 0x1d:size = handle0f_1d_dasm(stream, pc, op, opcodes); break; // ASR_S (single) + case 0x1e:size = handle0f_1e_dasm(stream, pc, op, opcodes); break; // TRAP (not a5?) + case 0x1f:size = handle0f_1f_dasm(stream, pc, op, opcodes); break; // BRK_S ( 0x7fff only? ) } return size; } -int arcompact_handle0f_00_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0f_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int size = 2; uint8_t subinstr = (op & 0x00e0) >> 5; @@ -716,21 +713,21 @@ int arcompact_handle0f_00_dasm(DASM_OPS_16) switch (subinstr) { - case 0x00: size = arcompact_handle0f_00_00_dasm(DASM_PARAMS); break; // J_S - case 0x01: size = arcompact_handle0f_00_01_dasm(DASM_PARAMS); break; // J_S.D - case 0x02: size = arcompact_handle0f_00_02_dasm(DASM_PARAMS); break; // JL_S - case 0x03: size = arcompact_handle0f_00_03_dasm(DASM_PARAMS); break; // JL_S.D - case 0x04: size = arcompact_handle0f_00_04_dasm(DASM_PARAMS); break; // 0x04 <illegal> - case 0x05: size = arcompact_handle0f_00_05_dasm(DASM_PARAMS); break; // 0x05 <illegal> - case 0x06: size = arcompact_handle0f_00_06_dasm(DASM_PARAMS); break; // SUB_S.NE - case 0x07: size = arcompact_handle0f_00_07_dasm(DASM_PARAMS); break; // ZOPs + case 0x00:size = handle0f_00_00_dasm(stream, pc, op, opcodes); break; // J_S + case 0x01:size = handle0f_00_01_dasm(stream, pc, op, opcodes); break; // J_S.D + case 0x02:size = handle0f_00_02_dasm(stream, pc, op, opcodes); break; // JL_S + case 0x03:size = handle0f_00_03_dasm(stream, pc, op, opcodes); break; // JL_S.D + case 0x04:size = handle0f_00_04_dasm(stream, pc, op, opcodes); break; // 0x04 <illegal> + case 0x05:size = handle0f_00_05_dasm(stream, pc, op, opcodes); break; // 0x05 <illegal> + case 0x06:size = handle0f_00_06_dasm(stream, pc, op, opcodes); break; // SUB_S.NE + case 0x07:size = handle0f_00_07_dasm(stream, pc, op, opcodes); break; // ZOPs } return size; } -int arcompact_handle0f_00_07_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0f_00_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int size = 2; // General Operations w/o Register @@ -740,20 +737,20 @@ int arcompact_handle0f_00_07_dasm(DASM_OPS_16) switch (subinstr3) { - case 0x00: size = arcompact_handle0f_00_07_00_dasm(DASM_PARAMS); break; // NOP_S - case 0x01: size = arcompact_handle0f_00_07_01_dasm(DASM_PARAMS); break; // UNIMP_S - case 0x02: size = arcompact_handle0f_00_07_02_dasm(DASM_PARAMS); break; // 0x02 <illegal> - case 0x03: size = arcompact_handle0f_00_07_03_dasm(DASM_PARAMS); break; // 0x03 <illegal> - case 0x04: size = arcompact_handle0f_00_07_04_dasm(DASM_PARAMS); break; // JEQ_S [BLINK] - case 0x05: size = arcompact_handle0f_00_07_05_dasm(DASM_PARAMS); break; // JNE_S [BLINK] - case 0x06: size = arcompact_handle0f_00_07_06_dasm(DASM_PARAMS); break; // J_S [BLINK] - case 0x07: size = arcompact_handle0f_00_07_07_dasm(DASM_PARAMS); break; // J_S.D [BLINK] + case 0x00:size = handle0f_00_07_00_dasm(stream, pc, op, opcodes); break; // NOP_S + case 0x01:size = handle0f_00_07_01_dasm(stream, pc, op, opcodes); break; // UNIMP_S + case 0x02:size = handle0f_00_07_02_dasm(stream, pc, op, opcodes); break; // 0x02 <illegal> + case 0x03:size = handle0f_00_07_03_dasm(stream, pc, op, opcodes); break; // 0x03 <illegal> + case 0x04:size = handle0f_00_07_04_dasm(stream, pc, op, opcodes); break; // JEQ_S [BLINK] + case 0x05:size = handle0f_00_07_05_dasm(stream, pc, op, opcodes); break; // JNE_S [BLINK] + case 0x06:size = handle0f_00_07_06_dasm(stream, pc, op, opcodes); break; // J_S [BLINK] + case 0x07:size = handle0f_00_07_07_dasm(stream, pc, op, opcodes); break; // J_S.D [BLINK] } return size; } -int arcompact_handle17_dasm(DASM_OPS_16) +int arcompact_disassembler::handle17_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int size = 2; uint8_t subinstr = (op & 0x00e0) >> 5; @@ -761,20 +758,20 @@ int arcompact_handle17_dasm(DASM_OPS_16) switch (subinstr) { - case 0x00: size = arcompact_handle17_00_dasm(DASM_PARAMS); break; // ASL_S - case 0x01: size = arcompact_handle17_01_dasm(DASM_PARAMS); break; // LSR_S - case 0x02: size = arcompact_handle17_02_dasm(DASM_PARAMS); break; // ASR_S - case 0x03: size = arcompact_handle17_03_dasm(DASM_PARAMS); break; // SUB_S - case 0x04: size = arcompact_handle17_04_dasm(DASM_PARAMS); break; // BSET_S - case 0x05: size = arcompact_handle17_05_dasm(DASM_PARAMS); break; // BCLR_S - case 0x06: size = arcompact_handle17_06_dasm(DASM_PARAMS); break; // BMSK_S - case 0x07: size = arcompact_handle17_07_dasm(DASM_PARAMS); break; // BTST_S + case 0x00:size = handle17_00_dasm(stream, pc, op, opcodes); break; // ASL_S + case 0x01:size = handle17_01_dasm(stream, pc, op, opcodes); break; // LSR_S + case 0x02:size = handle17_02_dasm(stream, pc, op, opcodes); break; // ASR_S + case 0x03:size = handle17_03_dasm(stream, pc, op, opcodes); break; // SUB_S + case 0x04:size = handle17_04_dasm(stream, pc, op, opcodes); break; // BSET_S + case 0x05:size = handle17_05_dasm(stream, pc, op, opcodes); break; // BCLR_S + case 0x06:size = handle17_06_dasm(stream, pc, op, opcodes); break; // BMSK_S + case 0x07:size = handle17_07_dasm(stream, pc, op, opcodes); break; // BTST_S } return size; } -int arcompact_handle18_dasm(DASM_OPS_16) +int arcompact_disassembler::handle18_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int size = 2; // Stack Pointer Based Instructions (16-bit) @@ -784,20 +781,20 @@ int arcompact_handle18_dasm(DASM_OPS_16) switch (subinstr) { - case 0x00: size = arcompact_handle18_00_dasm(DASM_PARAMS); break; // LD_S (SP) - case 0x01: size = arcompact_handle18_01_dasm(DASM_PARAMS); break; // LDB_S (SP) - case 0x02: size = arcompact_handle18_02_dasm(DASM_PARAMS); break; // ST_S (SP) - case 0x03: size = arcompact_handle18_03_dasm(DASM_PARAMS); break; // STB_S (SP) - case 0x04: size = arcompact_handle18_04_dasm(DASM_PARAMS); break; // ADD_S (SP) - case 0x05: size = arcompact_handle18_05_dasm(DASM_PARAMS); break; // subtable 18_05 - case 0x06: size = arcompact_handle18_06_dasm(DASM_PARAMS); break; // subtable 18_06 - case 0x07: size = arcompact_handle18_07_dasm(DASM_PARAMS); break; // subtable 18_07 + case 0x00:size = handle18_00_dasm(stream, pc, op, opcodes); break; // LD_S (SP) + case 0x01:size = handle18_01_dasm(stream, pc, op, opcodes); break; // LDB_S (SP) + case 0x02:size = handle18_02_dasm(stream, pc, op, opcodes); break; // ST_S (SP) + case 0x03:size = handle18_03_dasm(stream, pc, op, opcodes); break; // STB_S (SP) + case 0x04:size = handle18_04_dasm(stream, pc, op, opcodes); break; // ADD_S (SP) + case 0x05:size = handle18_05_dasm(stream, pc, op, opcodes); break; // subtable 18_05 + case 0x06:size = handle18_06_dasm(stream, pc, op, opcodes); break; // subtable 18_06 + case 0x07:size = handle18_07_dasm(stream, pc, op, opcodes); break; // subtable 18_07 } return size; } -int arcompact_handle18_05_dasm(DASM_OPS_16) +int arcompact_disassembler::handle18_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int size = 2; uint8_t subinstr2 = (op & 0x0700) >> 8; @@ -805,20 +802,20 @@ int arcompact_handle18_05_dasm(DASM_OPS_16) switch (subinstr2) { - case 0x00: size = arcompact_handle18_05_00_dasm(DASM_PARAMS); break; // ADD_S (SP) - case 0x01: size = arcompact_handle18_05_01_dasm(DASM_PARAMS); break; // SUB_S (SP) - case 0x02: size = arcompact_handle18_05_02_dasm(DASM_PARAMS); break; // <illegal 0x18_05_02> - case 0x03: size = arcompact_handle18_05_03_dasm(DASM_PARAMS); break; // <illegal 0x18_05_03> - case 0x04: size = arcompact_handle18_05_04_dasm(DASM_PARAMS); break; // <illegal 0x18_05_04> - case 0x05: size = arcompact_handle18_05_05_dasm(DASM_PARAMS); break; // <illegal 0x18_05_05> - case 0x06: size = arcompact_handle18_05_06_dasm(DASM_PARAMS); break; // <illegal 0x18_05_06> - case 0x07: size = arcompact_handle18_05_07_dasm(DASM_PARAMS); break; // <illegal 0x18_05_07> + case 0x00:size = handle18_05_00_dasm(stream, pc, op, opcodes); break; // ADD_S (SP) + case 0x01:size = handle18_05_01_dasm(stream, pc, op, opcodes); break; // SUB_S (SP) + case 0x02:size = handle18_05_02_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_05_02> + case 0x03:size = handle18_05_03_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_05_03> + case 0x04:size = handle18_05_04_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_05_04> + case 0x05:size = handle18_05_05_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_05_05> + case 0x06:size = handle18_05_06_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_05_06> + case 0x07:size = handle18_05_07_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_05_07> } return size; } -int arcompact_handle18_06_dasm(DASM_OPS_16) +int arcompact_disassembler::handle18_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int size = 2; uint8_t subinstr2 = (op & 0x001f) >> 0; @@ -826,44 +823,44 @@ int arcompact_handle18_06_dasm(DASM_OPS_16) switch (subinstr2) { - case 0x00: size = arcompact_handle18_06_00_dasm(DASM_PARAMS); break; // <illegal 0x18_06_00> - case 0x01: size = arcompact_handle18_06_01_dasm(DASM_PARAMS); break; // POP_S b - case 0x02: size = arcompact_handle18_06_02_dasm(DASM_PARAMS); break; // <illegal 0x18_06_02> - case 0x03: size = arcompact_handle18_06_03_dasm(DASM_PARAMS); break; // <illegal 0x18_06_03> - case 0x04: size = arcompact_handle18_06_04_dasm(DASM_PARAMS); break; // <illegal 0x18_06_04> - case 0x05: size = arcompact_handle18_06_05_dasm(DASM_PARAMS); break; // <illegal 0x18_06_05> - case 0x06: size = arcompact_handle18_06_06_dasm(DASM_PARAMS); break; // <illegal 0x18_06_06> - case 0x07: size = arcompact_handle18_06_07_dasm(DASM_PARAMS); break; // <illegal 0x18_06_07> - case 0x08: size = arcompact_handle18_06_08_dasm(DASM_PARAMS); break; // <illegal 0x18_06_08> - case 0x09: size = arcompact_handle18_06_09_dasm(DASM_PARAMS); break; // <illegal 0x18_06_09> - case 0x0a: size = arcompact_handle18_06_0a_dasm(DASM_PARAMS); break; // <illegal 0x18_06_0a> - case 0x0b: size = arcompact_handle18_06_0b_dasm(DASM_PARAMS); break; // <illegal 0x18_06_0b> - case 0x0c: size = arcompact_handle18_06_0c_dasm(DASM_PARAMS); break; // <illegal 0x18_06_0c> - case 0x0d: size = arcompact_handle18_06_0d_dasm(DASM_PARAMS); break; // <illegal 0x18_06_0d> - case 0x0e: size = arcompact_handle18_06_0e_dasm(DASM_PARAMS); break; // <illegal 0x18_06_0e> - case 0x0f: size = arcompact_handle18_06_0f_dasm(DASM_PARAMS); break; // <illegal 0x18_06_0f> - case 0x10: size = arcompact_handle18_06_10_dasm(DASM_PARAMS); break; // <illegal 0x18_06_10> - case 0x11: size = arcompact_handle18_06_11_dasm(DASM_PARAMS); break; // POP_S blink - case 0x12: size = arcompact_handle18_06_12_dasm(DASM_PARAMS); break; // <illegal 0x18_06_12> - case 0x13: size = arcompact_handle18_06_13_dasm(DASM_PARAMS); break; // <illegal 0x18_06_13> - case 0x14: size = arcompact_handle18_06_14_dasm(DASM_PARAMS); break; // <illegal 0x18_06_14> - case 0x15: size = arcompact_handle18_06_15_dasm(DASM_PARAMS); break; // <illegal 0x18_06_15> - case 0x16: size = arcompact_handle18_06_16_dasm(DASM_PARAMS); break; // <illegal 0x18_06_16> - case 0x17: size = arcompact_handle18_06_17_dasm(DASM_PARAMS); break; // <illegal 0x18_06_17> - case 0x18: size = arcompact_handle18_06_18_dasm(DASM_PARAMS); break; // <illegal 0x18_06_18> - case 0x19: size = arcompact_handle18_06_19_dasm(DASM_PARAMS); break; // <illegal 0x18_06_19> - case 0x1a: size = arcompact_handle18_06_1a_dasm(DASM_PARAMS); break; // <illegal 0x18_06_1a> - case 0x1b: size = arcompact_handle18_06_1b_dasm(DASM_PARAMS); break; // <illegal 0x18_06_1b> - case 0x1c: size = arcompact_handle18_06_1c_dasm(DASM_PARAMS); break; // <illegal 0x18_06_1c> - case 0x1d: size = arcompact_handle18_06_1d_dasm(DASM_PARAMS); break; // <illegal 0x18_06_1d> - case 0x1e: size = arcompact_handle18_06_1e_dasm(DASM_PARAMS); break; // <illegal 0x18_06_1e> - case 0x1f: size = arcompact_handle18_06_1f_dasm(DASM_PARAMS); break; // <illegal 0x18_06_1f> + case 0x00:size = handle18_06_00_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_00> + case 0x01:size = handle18_06_01_dasm(stream, pc, op, opcodes); break; // POP_S b + case 0x02:size = handle18_06_02_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_02> + case 0x03:size = handle18_06_03_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_03> + case 0x04:size = handle18_06_04_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_04> + case 0x05:size = handle18_06_05_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_05> + case 0x06:size = handle18_06_06_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_06> + case 0x07:size = handle18_06_07_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_07> + case 0x08:size = handle18_06_08_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_08> + case 0x09:size = handle18_06_09_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_09> + case 0x0a:size = handle18_06_0a_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_0a> + case 0x0b:size = handle18_06_0b_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_0b> + case 0x0c:size = handle18_06_0c_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_0c> + case 0x0d:size = handle18_06_0d_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_0d> + case 0x0e:size = handle18_06_0e_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_0e> + case 0x0f:size = handle18_06_0f_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_0f> + case 0x10:size = handle18_06_10_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_10> + case 0x11:size = handle18_06_11_dasm(stream, pc, op, opcodes); break; // POP_S blink + case 0x12:size = handle18_06_12_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_12> + case 0x13:size = handle18_06_13_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_13> + case 0x14:size = handle18_06_14_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_14> + case 0x15:size = handle18_06_15_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_15> + case 0x16:size = handle18_06_16_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_16> + case 0x17:size = handle18_06_17_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_17> + case 0x18:size = handle18_06_18_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_18> + case 0x19:size = handle18_06_19_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_19> + case 0x1a:size = handle18_06_1a_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_1a> + case 0x1b:size = handle18_06_1b_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_1b> + case 0x1c:size = handle18_06_1c_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_1c> + case 0x1d:size = handle18_06_1d_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_1d> + case 0x1e:size = handle18_06_1e_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_1e> + case 0x1f:size = handle18_06_1f_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_1f> } return size; } -int arcompact_handle18_07_dasm(DASM_OPS_16) +int arcompact_disassembler::handle18_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int size = 2; uint8_t subinstr2 = (op & 0x001f) >> 0; @@ -871,44 +868,44 @@ int arcompact_handle18_07_dasm(DASM_OPS_16) switch (subinstr2) { - case 0x00: size = arcompact_handle18_07_00_dasm(DASM_PARAMS); break; // <illegal 0x18_07_00> - case 0x01: size = arcompact_handle18_07_01_dasm(DASM_PARAMS); break; // PUSH_S b - case 0x02: size = arcompact_handle18_07_02_dasm(DASM_PARAMS); break; // <illegal 0x18_07_02> - case 0x03: size = arcompact_handle18_07_03_dasm(DASM_PARAMS); break; // <illegal 0x18_07_03> - case 0x04: size = arcompact_handle18_07_04_dasm(DASM_PARAMS); break; // <illegal 0x18_07_04> - case 0x05: size = arcompact_handle18_07_05_dasm(DASM_PARAMS); break; // <illegal 0x18_07_05> - case 0x06: size = arcompact_handle18_07_06_dasm(DASM_PARAMS); break; // <illegal 0x18_07_06> - case 0x07: size = arcompact_handle18_07_07_dasm(DASM_PARAMS); break; // <illegal 0x18_07_07> - case 0x08: size = arcompact_handle18_07_08_dasm(DASM_PARAMS); break; // <illegal 0x18_07_08> - case 0x09: size = arcompact_handle18_07_09_dasm(DASM_PARAMS); break; // <illegal 0x18_07_09> - case 0x0a: size = arcompact_handle18_07_0a_dasm(DASM_PARAMS); break; // <illegal 0x18_07_0a> - case 0x0b: size = arcompact_handle18_07_0b_dasm(DASM_PARAMS); break; // <illegal 0x18_07_0b> - case 0x0c: size = arcompact_handle18_07_0c_dasm(DASM_PARAMS); break; // <illegal 0x18_07_0c> - case 0x0d: size = arcompact_handle18_07_0d_dasm(DASM_PARAMS); break; // <illegal 0x18_07_0d> - case 0x0e: size = arcompact_handle18_07_0e_dasm(DASM_PARAMS); break; // <illegal 0x18_07_0e> - case 0x0f: size = arcompact_handle18_07_0f_dasm(DASM_PARAMS); break; // <illegal 0x18_07_0f> - case 0x10: size = arcompact_handle18_07_10_dasm(DASM_PARAMS); break; // <illegal 0x18_07_10> - case 0x11: size = arcompact_handle18_07_11_dasm(DASM_PARAMS); break; // PUSH_S blink - case 0x12: size = arcompact_handle18_07_12_dasm(DASM_PARAMS); break; // <illegal 0x18_07_12> - case 0x13: size = arcompact_handle18_07_13_dasm(DASM_PARAMS); break; // <illegal 0x18_07_13> - case 0x14: size = arcompact_handle18_07_14_dasm(DASM_PARAMS); break; // <illegal 0x18_07_14> - case 0x15: size = arcompact_handle18_07_15_dasm(DASM_PARAMS); break; // <illegal 0x18_07_15> - case 0x16: size = arcompact_handle18_07_16_dasm(DASM_PARAMS); break; // <illegal 0x18_07_16> - case 0x17: size = arcompact_handle18_07_17_dasm(DASM_PARAMS); break; // <illegal 0x18_07_17> - case 0x18: size = arcompact_handle18_07_18_dasm(DASM_PARAMS); break; // <illegal 0x18_07_18> - case 0x19: size = arcompact_handle18_07_19_dasm(DASM_PARAMS); break; // <illegal 0x18_07_19> - case 0x1a: size = arcompact_handle18_07_1a_dasm(DASM_PARAMS); break; // <illegal 0x18_07_1a> - case 0x1b: size = arcompact_handle18_07_1b_dasm(DASM_PARAMS); break; // <illegal 0x18_07_1b> - case 0x1c: size = arcompact_handle18_07_1c_dasm(DASM_PARAMS); break; // <illegal 0x18_07_1c> - case 0x1d: size = arcompact_handle18_07_1d_dasm(DASM_PARAMS); break; // <illegal 0x18_07_1d> - case 0x1e: size = arcompact_handle18_07_1e_dasm(DASM_PARAMS); break; // <illegal 0x18_07_1e> - case 0x1f: size = arcompact_handle18_07_1f_dasm(DASM_PARAMS); break; // <illegal 0x18_07_1f> + case 0x00:size = handle18_07_00_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_00> + case 0x01:size = handle18_07_01_dasm(stream, pc, op, opcodes); break; // PUSH_S b + case 0x02:size = handle18_07_02_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_02> + case 0x03:size = handle18_07_03_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_03> + case 0x04:size = handle18_07_04_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_04> + case 0x05:size = handle18_07_05_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_05> + case 0x06:size = handle18_07_06_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_06> + case 0x07:size = handle18_07_07_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_07> + case 0x08:size = handle18_07_08_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_08> + case 0x09:size = handle18_07_09_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_09> + case 0x0a:size = handle18_07_0a_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_0a> + case 0x0b:size = handle18_07_0b_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_0b> + case 0x0c:size = handle18_07_0c_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_0c> + case 0x0d:size = handle18_07_0d_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_0d> + case 0x0e:size = handle18_07_0e_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_0e> + case 0x0f:size = handle18_07_0f_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_0f> + case 0x10:size = handle18_07_10_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_10> + case 0x11:size = handle18_07_11_dasm(stream, pc, op, opcodes); break; // PUSH_S blink + case 0x12:size = handle18_07_12_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_12> + case 0x13:size = handle18_07_13_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_13> + case 0x14:size = handle18_07_14_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_14> + case 0x15:size = handle18_07_15_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_15> + case 0x16:size = handle18_07_16_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_16> + case 0x17:size = handle18_07_17_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_17> + case 0x18:size = handle18_07_18_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_18> + case 0x19:size = handle18_07_19_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_19> + case 0x1a:size = handle18_07_1a_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_1a> + case 0x1b:size = handle18_07_1b_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_1b> + case 0x1c:size = handle18_07_1c_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_1c> + case 0x1d:size = handle18_07_1d_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_1d> + case 0x1e:size = handle18_07_1e_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_1e> + case 0x1f:size = handle18_07_1f_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_1f> } return size; } -int arcompact_handle19_dasm(DASM_OPS_16) +int arcompact_disassembler::handle19_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int size = 2; uint8_t subinstr = (op & 0x0600) >> 9; @@ -916,15 +913,15 @@ int arcompact_handle19_dasm(DASM_OPS_16) switch (subinstr) { - case 0x00: size = arcompact_handle19_00_dasm(DASM_PARAMS); break; // LD_S (GP) - case 0x01: size = arcompact_handle19_01_dasm(DASM_PARAMS); break; // LDB_S (GP) - case 0x02: size = arcompact_handle19_02_dasm(DASM_PARAMS); break; // LDW_S (GP) - case 0x03: size = arcompact_handle19_03_dasm(DASM_PARAMS); break; // ADD_S (GP) + case 0x00:size = handle19_00_dasm(stream, pc, op, opcodes); break; // LD_S (GP) + case 0x01:size = handle19_01_dasm(stream, pc, op, opcodes); break; // LDB_S (GP) + case 0x02:size = handle19_02_dasm(stream, pc, op, opcodes); break; // LDW_S (GP) + case 0x03:size = handle19_03_dasm(stream, pc, op, opcodes); break; // ADD_S (GP) } return size; } -int arcompact_handle1c_dasm(DASM_OPS_16) +int arcompact_disassembler::handle1c_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int size = 2; uint8_t subinstr = (op & 0x0080) >> 7; @@ -932,13 +929,13 @@ int arcompact_handle1c_dasm(DASM_OPS_16) switch (subinstr) { - case 0x00: size = arcompact_handle1c_00_dasm(DASM_PARAMS); break; // ADD_S - case 0x01: size = arcompact_handle1c_01_dasm(DASM_PARAMS); break; // CMP_S + case 0x00:size = handle1c_00_dasm(stream, pc, op, opcodes); break; // ADD_S + case 0x01:size = handle1c_01_dasm(stream, pc, op, opcodes); break; // CMP_S } return size; } -int arcompact_handle1d_dasm(DASM_OPS_16) +int arcompact_disassembler::handle1d_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int size = 2; uint8_t subinstr = (op & 0x0080) >> 7; @@ -946,13 +943,13 @@ int arcompact_handle1d_dasm(DASM_OPS_16) switch (subinstr) { - case 0x00: size = arcompact_handle1d_00_dasm(DASM_PARAMS); break; // BREQ_S - case 0x01: size = arcompact_handle1d_01_dasm(DASM_PARAMS); break; // BRNE_S + case 0x00:size = handle1d_00_dasm(stream, pc, op, opcodes); break; // BREQ_S + case 0x01:size = handle1d_01_dasm(stream, pc, op, opcodes); break; // BRNE_S } return size; } -int arcompact_handle1e_dasm(DASM_OPS_16) +int arcompact_disassembler::handle1e_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int size = 2; uint8_t subinstr = (op & 0x0600) >> 9; @@ -960,15 +957,15 @@ int arcompact_handle1e_dasm(DASM_OPS_16) switch (subinstr) { - case 0x00: size = arcompact_handle1e_00_dasm(DASM_PARAMS); break; // B_S - case 0x01: size = arcompact_handle1e_01_dasm(DASM_PARAMS); break; // BEQ_S - case 0x02: size = arcompact_handle1e_02_dasm(DASM_PARAMS); break; // BNE_S - case 0x03: size = arcompact_handle1e_03_dasm(DASM_PARAMS); break; // Bcc_S + case 0x00:size = handle1e_00_dasm(stream, pc, op, opcodes); break; // B_S + case 0x01:size = handle1e_01_dasm(stream, pc, op, opcodes); break; // BEQ_S + case 0x02:size = handle1e_02_dasm(stream, pc, op, opcodes); break; // BNE_S + case 0x03:size = handle1e_03_dasm(stream, pc, op, opcodes); break; // Bcc_S } return size; } -int arcompact_handle1e_03_dasm(DASM_OPS_16) +int arcompact_disassembler::handle1e_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int size = 2; uint8_t subinstr2 = (op & 0x01c0) >> 6; @@ -976,14 +973,14 @@ int arcompact_handle1e_03_dasm(DASM_OPS_16) switch (subinstr2) { - case 0x00: size = arcompact_handle1e_03_00_dasm(DASM_PARAMS); break; // BGT_S - case 0x01: size = arcompact_handle1e_03_01_dasm(DASM_PARAMS); break; // BGE_S - case 0x02: size = arcompact_handle1e_03_02_dasm(DASM_PARAMS); break; // BLT_S - case 0x03: size = arcompact_handle1e_03_03_dasm(DASM_PARAMS); break; // BLE_S - case 0x04: size = arcompact_handle1e_03_04_dasm(DASM_PARAMS); break; // BHI_S - case 0x05: size = arcompact_handle1e_03_05_dasm(DASM_PARAMS); break; // BHS_S - case 0x06: size = arcompact_handle1e_03_06_dasm(DASM_PARAMS); break; // BLO_S - case 0x07: size = arcompact_handle1e_03_07_dasm(DASM_PARAMS); break; // BLS_S + case 0x00:size = handle1e_03_00_dasm(stream, pc, op, opcodes); break; // BGT_S + case 0x01:size = handle1e_03_01_dasm(stream, pc, op, opcodes); break; // BGE_S + case 0x02:size = handle1e_03_02_dasm(stream, pc, op, opcodes); break; // BLT_S + case 0x03:size = handle1e_03_03_dasm(stream, pc, op, opcodes); break; // BLE_S + case 0x04:size = handle1e_03_04_dasm(stream, pc, op, opcodes); break; // BHI_S + case 0x05:size = handle1e_03_05_dasm(stream, pc, op, opcodes); break; // BHS_S + case 0x06:size = handle1e_03_06_dasm(stream, pc, op, opcodes); break; // BLO_S + case 0x07:size = handle1e_03_07_dasm(stream, pc, op, opcodes); break; // BLS_S } return size; diff --git a/src/devices/cpu/arcompact/arcompactdasm_dispatch.h b/src/devices/cpu/arcompact/arcompactdasm_dispatch.h deleted file mode 100644 index 519f4b7ae4e..00000000000 --- a/src/devices/cpu/arcompact/arcompactdasm_dispatch.h +++ /dev/null @@ -1,50 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:David Haywood -/*********************************\ - - ARCompact disassembler - -\*********************************/ - -#define DASM_OPS_16 std::ostream &stream, offs_t pc, uint16_t op, const uint8_t* oprom -#define DASM_OPS_32 std::ostream &stream, offs_t pc, uint32_t op, const uint8_t* oprom -#define DASM_PARAMS stream, pc, op, oprom - -#define LIMM_REG 62 - -#define GET_LIMM_32 \ - limm = oprom[6] | (oprom[7] << 8); \ - limm |= (oprom[4] << 16) | (oprom[5] << 24); - - -int arcompact_handle00_dasm(DASM_OPS_32); -int arcompact_handle01_dasm(DASM_OPS_32); -int arcompact_handle01_00_dasm(DASM_OPS_32); -int arcompact_handle01_01_dasm(DASM_OPS_32); -int arcompact_handle01_01_00_dasm(DASM_OPS_32); -int arcompact_handle01_01_01_dasm(DASM_OPS_32); -int arcompact_handle04_dasm(DASM_OPS_32); -int arcompact_handle04_2f_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_dasm(DASM_OPS_32); -int arcompact_handle05_dasm(DASM_OPS_32); - -int arcompact_handle05_2f_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_dasm(DASM_OPS_32); - - -int arcompact_handle0c_dasm(DASM_OPS_16); -int arcompact_handle0d_dasm(DASM_OPS_16); -int arcompact_handle0e_dasm(DASM_OPS_16); -int arcompact_handle0f_dasm(DASM_OPS_16); -int arcompact_handle0f_00_dasm(DASM_OPS_16); -int arcompact_handle0f_00_07_dasm(DASM_OPS_16); -int arcompact_handle17_dasm(DASM_OPS_16); -int arcompact_handle18_dasm(DASM_OPS_16); -int arcompact_handle18_05_dasm(DASM_OPS_16); -int arcompact_handle18_06_dasm(DASM_OPS_16); -int arcompact_handle18_07_dasm(DASM_OPS_16); -int arcompact_handle19_dasm(DASM_OPS_16); -int arcompact_handle1c_dasm(DASM_OPS_16); -int arcompact_handle1d_dasm(DASM_OPS_16); -int arcompact_handle1e_dasm(DASM_OPS_16); -int arcompact_handle1e_03_dasm(DASM_OPS_16); diff --git a/src/devices/cpu/arcompact/arcompactdasm_ops.cpp b/src/devices/cpu/arcompact/arcompactdasm_ops.cpp index dd214e0cb02..dadc0f856a4 100644 --- a/src/devices/cpu/arcompact/arcompactdasm_ops.cpp +++ b/src/devices/cpu/arcompact/arcompactdasm_ops.cpp @@ -7,9 +7,8 @@ \*********************************/ #include "emu.h" -#include <stdarg.h> -#include "arcompactdasm_ops.h" +#include "arcompactdasm.h" #define GET_01_01_01_BRANCH_ADDR \ int32_t address = (op & 0x00fe0000) >> 17; \ @@ -79,9 +78,9 @@ // this is as messed up as the rest of the 16-bit alignment in LE mode... +#define LIMM_REG 62 #define GET_LIMM \ - limm = oprom[4] | (oprom[5] << 8); \ - limm |= (oprom[2] << 16) | (oprom[3] << 24); + limm = opcodes.r32(pc+2); #define PC_ALIGNED32 \ (pc&0xfffffffc) @@ -92,7 +91,7 @@ * * ************************************************************************************************************************************/ -int arcompact_handle00_00_dasm(DASM_OPS_32) +int arcompact_disassembler::handle00_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { int size = 4; // Branch Conditionally @@ -107,7 +106,7 @@ int arcompact_handle00_00_dasm(DASM_OPS_32) return size; } -int arcompact_handle00_01_dasm(DASM_OPS_32) +int arcompact_disassembler::handle00_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { int size = 4; // Branch Unconditionally Far @@ -125,7 +124,7 @@ int arcompact_handle00_01_dasm(DASM_OPS_32) return size; } -int arcompact_handle01_00_00dasm(DASM_OPS_32) +int arcompact_disassembler::handle01_00_00dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { int size = 4; @@ -142,7 +141,7 @@ int arcompact_handle01_00_00dasm(DASM_OPS_32) return size; } -int arcompact_handle01_00_01dasm(DASM_OPS_32) +int arcompact_disassembler::handle01_00_01dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { int size = 4; // Branch and Link Unconditionally Far @@ -162,7 +161,7 @@ int arcompact_handle01_00_01dasm(DASM_OPS_32) -int arcompact_01_01_00_helper(DASM_OPS_32, const char* optext) +int arcompact_disassembler::handle01_01_00_helper(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext) { int size = 4; @@ -184,7 +183,7 @@ int arcompact_01_01_00_helper(DASM_OPS_32, const char* optext) else { uint32_t limm; - GET_LIMM_32; + GET_LIMM; size = 8; if ((breg == LIMM_REG) && (creg != LIMM_REG)) @@ -208,16 +207,48 @@ int arcompact_01_01_00_helper(DASM_OPS_32, const char* optext) // register - register cases -int arcompact_handle01_01_00_00_dasm(DASM_OPS_32) { return arcompact_01_01_00_helper( DASM_PARAMS, "BREQ"); } -int arcompact_handle01_01_00_01_dasm(DASM_OPS_32) { return arcompact_01_01_00_helper( DASM_PARAMS, "BRNE"); } -int arcompact_handle01_01_00_02_dasm(DASM_OPS_32) { return arcompact_01_01_00_helper( DASM_PARAMS, "BRLT"); } -int arcompact_handle01_01_00_03_dasm(DASM_OPS_32) { return arcompact_01_01_00_helper( DASM_PARAMS, "BRGE"); } -int arcompact_handle01_01_00_04_dasm(DASM_OPS_32) { return arcompact_01_01_00_helper( DASM_PARAMS, "BRLO"); } -int arcompact_handle01_01_00_05_dasm(DASM_OPS_32) { return arcompact_01_01_00_helper( DASM_PARAMS, "BRHS"); } -int arcompact_handle01_01_00_0e_dasm(DASM_OPS_32) { return arcompact_01_01_00_helper( DASM_PARAMS, "BBIT0");} -int arcompact_handle01_01_00_0f_dasm(DASM_OPS_32) { return arcompact_01_01_00_helper( DASM_PARAMS, "BBIT1");} +int arcompact_disassembler::handle01_01_00_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle01_01_00_helper( stream, pc, op, opcodes, "BREQ"); +} + +int arcompact_disassembler::handle01_01_00_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle01_01_00_helper( stream, pc, op, opcodes, "BRNE"); +} + +int arcompact_disassembler::handle01_01_00_02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle01_01_00_helper( stream, pc, op, opcodes, "BRLT"); +} + +int arcompact_disassembler::handle01_01_00_03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle01_01_00_helper( stream, pc, op, opcodes, "BRGE"); +} + +int arcompact_disassembler::handle01_01_00_04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle01_01_00_helper( stream, pc, op, opcodes, "BRLO"); +} -int arcompact_01_01_01_helper(DASM_OPS_32, const char* optext) +int arcompact_disassembler::handle01_01_00_05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle01_01_00_helper( stream, pc, op, opcodes, "BRHS"); +} + +int arcompact_disassembler::handle01_01_00_0e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle01_01_00_helper( stream, pc, op, opcodes, "BBIT0"); +} + +int arcompact_disassembler::handle01_01_00_0f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle01_01_00_helper( stream, pc, op, opcodes, "BBIT1"); +} + + +int arcompact_disassembler::handle01_01_01_helper(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext) { int size = 4; @@ -240,17 +271,48 @@ int arcompact_01_01_01_helper(DASM_OPS_32, const char* optext) } // register -immediate cases -int arcompact_handle01_01_01_00_dasm(DASM_OPS_32) { return arcompact_01_01_01_helper(DASM_PARAMS, "BREQ"); } -int arcompact_handle01_01_01_01_dasm(DASM_OPS_32) { return arcompact_01_01_01_helper(DASM_PARAMS, "BRNE"); } -int arcompact_handle01_01_01_02_dasm(DASM_OPS_32) { return arcompact_01_01_01_helper(DASM_PARAMS, "BRLT"); } -int arcompact_handle01_01_01_03_dasm(DASM_OPS_32) { return arcompact_01_01_01_helper(DASM_PARAMS, "BRGE"); } -int arcompact_handle01_01_01_04_dasm(DASM_OPS_32) { return arcompact_01_01_01_helper(DASM_PARAMS, "BRLO"); } -int arcompact_handle01_01_01_05_dasm(DASM_OPS_32) { return arcompact_01_01_01_helper(DASM_PARAMS, "BRHS"); } -int arcompact_handle01_01_01_0e_dasm(DASM_OPS_32) { return arcompact_01_01_01_helper(DASM_PARAMS, "BBIT0"); } -int arcompact_handle01_01_01_0f_dasm(DASM_OPS_32) { return arcompact_01_01_01_helper(DASM_PARAMS, "BBIT1"); } +int arcompact_disassembler::handle01_01_01_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle01_01_01_helper(stream, pc, op, opcodes, "BREQ"); +} + +int arcompact_disassembler::handle01_01_01_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle01_01_01_helper(stream, pc, op, opcodes, "BRNE"); +} +int arcompact_disassembler::handle01_01_01_02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle01_01_01_helper(stream, pc, op, opcodes, "BRLT"); +} + +int arcompact_disassembler::handle01_01_01_03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle01_01_01_helper(stream, pc, op, opcodes, "BRGE"); +} + +int arcompact_disassembler::handle01_01_01_04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle01_01_01_helper(stream, pc, op, opcodes, "BRLO"); +} + +int arcompact_disassembler::handle01_01_01_05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle01_01_01_helper(stream, pc, op, opcodes, "BRHS"); +} + +int arcompact_disassembler::handle01_01_01_0e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle01_01_01_helper(stream, pc, op, opcodes, "BBIT0"); +} + +int arcompact_disassembler::handle01_01_01_0f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle01_01_01_helper(stream, pc, op, opcodes, "BBIT1"); +} -int arcompact_handle02_dasm(DASM_OPS_32) + +int arcompact_disassembler::handle02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { // bitpos // 1111 1111 1111 1111 0000 0000 0000 0000 @@ -273,7 +335,7 @@ int arcompact_handle02_dasm(DASM_OPS_32) uint32_t limm = 0; if (breg == LIMM_REG) { - GET_LIMM_32; + GET_LIMM; size = 8; } @@ -293,7 +355,7 @@ int arcompact_handle02_dasm(DASM_OPS_32) return size; } -int arcompact_handle03_dasm(DASM_OPS_32) +int arcompact_disassembler::handle03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { int size = 4; uint32_t limm = 0; @@ -317,7 +379,7 @@ int arcompact_handle03_dasm(DASM_OPS_32) if (breg == LIMM_REG) { - GET_LIMM_32; + GET_LIMM; size = 8; got_limm = 1; } @@ -339,7 +401,7 @@ int arcompact_handle03_dasm(DASM_OPS_32) { if (!got_limm) { - GET_LIMM_32; + GET_LIMM; size = 8; } util::stream_format(stream, "(%08x)", limm); @@ -356,7 +418,7 @@ int arcompact_handle03_dasm(DASM_OPS_32) return size; } -int arcompact_handle04_p00_helper_dasm(DASM_OPS_32, const char* optext, int ignore_dst, int b_reserved) +int arcompact_disassembler::handle04_p00_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext, int ignore_dst, int b_reserved) { // PP // 0010 0bbb 00ii iiii FBBB CCCC CCAA AAAA @@ -376,7 +438,7 @@ int arcompact_handle04_p00_helper_dasm(DASM_OPS_32, const char* optext, int igno if ((!b_reserved) && (breg == LIMM_REG)) { - GET_LIMM_32; + GET_LIMM; size = 8; got_limm = 1; } @@ -385,7 +447,7 @@ int arcompact_handle04_p00_helper_dasm(DASM_OPS_32, const char* optext, int igno { if (!got_limm) { - GET_LIMM_32; + GET_LIMM; size = 8; } } @@ -428,7 +490,7 @@ int arcompact_handle04_p00_helper_dasm(DASM_OPS_32, const char* optext, int igno } // like p00 but with 'u6' istead of C -int arcompact_handle04_p01_helper_dasm(DASM_OPS_32, const char* optext, int ignore_dst, int b_reserved) +int arcompact_disassembler::handle04_p01_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext, int ignore_dst, int b_reserved) { // PP // 0010 0bbb 01ii iiii FBBB uuuu uuAA AAAA @@ -448,7 +510,7 @@ int arcompact_handle04_p01_helper_dasm(DASM_OPS_32, const char* optext, int igno if ((!b_reserved) && (breg == LIMM_REG)) { - GET_LIMM_32; + GET_LIMM; size = 8; // got_limm = 1; } @@ -488,7 +550,7 @@ int arcompact_handle04_p01_helper_dasm(DASM_OPS_32, const char* optext, int igno } -int arcompact_handle04_p10_helper_dasm(DASM_OPS_32, const char* optext, int b_reserved) +int arcompact_disassembler::handle04_p10_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext, int b_reserved) { int size = 4; uint32_t limm; @@ -507,7 +569,7 @@ int arcompact_handle04_p10_helper_dasm(DASM_OPS_32, const char* optext, int b_re { if (breg == LIMM_REG) { - GET_LIMM_32; + GET_LIMM; size = 8; //got_limm = 1; util::stream_format(stream, " 0x%08x ", limm); @@ -527,7 +589,7 @@ int arcompact_handle04_p10_helper_dasm(DASM_OPS_32, const char* optext, int b_re return size; } -int arcompact_handle04_p11_m0_helper_dasm(DASM_OPS_32, const char* optext, int b_reserved) +int arcompact_disassembler::handle04_p11_m0_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext, int b_reserved) { int size = 4; uint32_t limm = 0; @@ -546,7 +608,7 @@ int arcompact_handle04_p11_m0_helper_dasm(DASM_OPS_32, const char* optext, int b { if (breg == LIMM_REG) { - GET_LIMM_32; + GET_LIMM; size = 8; got_limm = 1; util::stream_format(stream, " 0x%08x ", limm); @@ -570,7 +632,7 @@ int arcompact_handle04_p11_m0_helper_dasm(DASM_OPS_32, const char* optext, int b { if (!got_limm) { - GET_LIMM_32; + GET_LIMM; size = 8; } util::stream_format(stream, " 0x%08x ", limm); @@ -583,7 +645,7 @@ int arcompact_handle04_p11_m0_helper_dasm(DASM_OPS_32, const char* optext, int b return size; } -int arcompact_handle04_p11_m1_helper_dasm(DASM_OPS_32, const char* optext, int b_reserved) +int arcompact_disassembler::handle04_p11_m1_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext, int b_reserved) { int size = 4; uint32_t limm; @@ -602,7 +664,7 @@ int arcompact_handle04_p11_m1_helper_dasm(DASM_OPS_32, const char* optext, int b { if (breg == LIMM_REG) { - GET_LIMM_32; + GET_LIMM; size = 8; //got_limm = 1; util::stream_format(stream, " 0x%08x ", limm); @@ -627,213 +689,213 @@ int arcompact_handle04_p11_m1_helper_dasm(DASM_OPS_32, const char* optext, int b return size; } -int arcompact_handle04_p11_helper_dasm(DASM_OPS_32, const char* optext, int b_reserved) +int arcompact_disassembler::handle04_p11_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext, int b_reserved) { int M = (op & 0x00000020) >> 5; op &= ~0x00000020; switch (M) { - case 0x00: return arcompact_handle04_p11_m0_helper_dasm(DASM_PARAMS, optext, b_reserved); - case 0x01: return arcompact_handle04_p11_m1_helper_dasm(DASM_PARAMS, optext, b_reserved); + case 0x00: return handle04_p11_m0_helper_dasm(stream, pc, op, opcodes, optext, b_reserved); + case 0x01: return handle04_p11_m1_helper_dasm(stream, pc, op, opcodes, optext, b_reserved); } return 0; } -int arcompact_handle04_helper_dasm(DASM_OPS_32, const char* optext, int ignore_dst, int b_reserved) +int arcompact_disassembler::handle04_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext, int ignore_dst, int b_reserved) { COMMON32_GET_p; switch (p) { - case 0x00: return arcompact_handle04_p00_helper_dasm(DASM_PARAMS, optext, ignore_dst, b_reserved); - case 0x01: return arcompact_handle04_p01_helper_dasm(DASM_PARAMS, optext, ignore_dst, b_reserved); - case 0x02: return arcompact_handle04_p10_helper_dasm(DASM_PARAMS, optext, b_reserved); - case 0x03: return arcompact_handle04_p11_helper_dasm(DASM_PARAMS, optext, b_reserved); + case 0x00: return handle04_p00_helper_dasm(stream, pc, op, opcodes, optext, ignore_dst, b_reserved); + case 0x01: return handle04_p01_helper_dasm(stream, pc, op, opcodes, optext, ignore_dst, b_reserved); + case 0x02: return handle04_p10_helper_dasm(stream, pc, op, opcodes, optext, b_reserved); + case 0x03: return handle04_p11_helper_dasm(stream, pc, op, opcodes, optext, b_reserved); } return 0; } -int arcompact_handle04_00_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "ADD", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "ADD", 0,0); } -int arcompact_handle04_01_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "ADC", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "ADC", 0,0); } -int arcompact_handle04_02_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "SUB", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "SUB", 0,0); } -int arcompact_handle04_03_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "SBC", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "SBC", 0,0); } -int arcompact_handle04_04_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "AND", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "AND", 0,0); } -int arcompact_handle04_05_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "OR", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "OR", 0,0); } -int arcompact_handle04_06_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "BIC", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "BIC", 0,0); } -int arcompact_handle04_07_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "XOR", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "XOR", 0,0); } -int arcompact_handle04_08_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "MAX", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "MAX", 0,0); } -int arcompact_handle04_09_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "MIN", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "MIN", 0,0); } -int arcompact_handle04_0a_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "MOV", 1,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "MOV", 1,0); } -int arcompact_handle04_0b_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "TST", 1,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "TST", 1,0); } -int arcompact_handle04_0c_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_0c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "CMP", 1,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "CMP", 1,0); } -int arcompact_handle04_0d_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_0d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "RCMP", 1,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "RCMP", 1,0); } -int arcompact_handle04_0e_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_0e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "RSUB", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "RSUB", 0,0); } -int arcompact_handle04_0f_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_0f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "BSET", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "BSET", 0,0); } -int arcompact_handle04_10_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_10_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "BCLR", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "BCLR", 0,0); } -int arcompact_handle04_11_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_11_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "BTST", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "BTST", 0,0); } -int arcompact_handle04_12_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_12_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "BXOR", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "BXOR", 0,0); } -int arcompact_handle04_13_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_13_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "BMSK", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "BMSK", 0,0); } -int arcompact_handle04_14_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_14_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "ADD1", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "ADD1", 0,0); } -int arcompact_handle04_15_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_15_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "ADD2", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "ADD2", 0,0); } -int arcompact_handle04_16_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_16_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "ADD3", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "ADD3", 0,0); } -int arcompact_handle04_17_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_17_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "SUB1", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "SUB1", 0,0); } -int arcompact_handle04_18_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_18_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "SUB2", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "SUB2", 0,0); } -int arcompact_handle04_19_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_19_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "SUB3", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "SUB3", 0,0); } -int arcompact_handle04_1a_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_1a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "MPY", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "MPY", 0,0); } // * -int arcompact_handle04_1b_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_1b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "MPYH", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "MPYH", 0,0); } // * -int arcompact_handle04_1c_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_1c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "MPYHU", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "MPYHU", 0,0); } // * -int arcompact_handle04_1d_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_1d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "MPYU", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "MPYU", 0,0); } // * -int arcompact_handle04_20_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_20_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "J", 1,1); + return handle04_helper_dasm(stream, pc, op, opcodes, "J", 1,1); } -int arcompact_handle04_21_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_21_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "J.D", 1,1); + return handle04_helper_dasm(stream, pc, op, opcodes, "J.D", 1,1); } -int arcompact_handle04_22_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_22_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "JL", 1,1); + return handle04_helper_dasm(stream, pc, op, opcodes, "JL", 1,1); } -int arcompact_handle04_23_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_23_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "JL.D", 1,1); + return handle04_helper_dasm(stream, pc, op, opcodes, "JL.D", 1,1); } -int arcompact_handle04_28_dasm(DASM_OPS_32) // LPcc (loop setup) +int arcompact_disassembler::handle04_28_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) // LPcc (loop setup) { COMMON32_GET_breg; // breg is reserved COMMON32_GET_p; @@ -879,7 +941,8 @@ int arcompact_handle04_28_dasm(DASM_OPS_32) // LPcc (loop setup) } \ else \ util::stream_format(stream, "[%03x]", auxreg); -int arcompact_handle04_2a_dasm(DASM_OPS_32) // Load FROM Auxiliary register TO register + +int arcompact_disassembler::handle04_2a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) // Load FROM Auxiliary register TO register { // pp F // 0010 0bbb 0010 1010 0BBB CCCC CCRR RRRR @@ -922,7 +985,7 @@ int arcompact_handle04_2a_dasm(DASM_OPS_32) // Load FROM Auxiliary register TO { if (!got_limm) { - GET_LIMM_32; + GET_LIMM; size = 8; } @@ -962,7 +1025,7 @@ int arcompact_handle04_2a_dasm(DASM_OPS_32) // Load FROM Auxiliary register TO return size; } -int arcompact_handle04_2b_dasm(DASM_OPS_32) // Store TO Auxiliary register FROM register +int arcompact_disassembler::handle04_2b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) // Store TO Auxiliary register FROM register { // code at ~ 40073DFE in leapster bios is manually setting up a loop this way // rather than using the lPcc opcode @@ -983,7 +1046,7 @@ int arcompact_handle04_2b_dasm(DASM_OPS_32) // Store TO Auxiliary register FROM if (breg == LIMM_REG) { - GET_LIMM_32; + GET_LIMM; size = 8; got_limm = 1; util::stream_format(stream, " %08x -> ", limm); @@ -1005,7 +1068,7 @@ int arcompact_handle04_2b_dasm(DASM_OPS_32) // Store TO Auxiliary register FROM { if (!got_limm) { - GET_LIMM_32; + GET_LIMM; size = 8; } @@ -1052,14 +1115,14 @@ int arcompact_handle04_2b_dasm(DASM_OPS_32) // Store TO Auxiliary register FROM return size;} -int arcompact_handle04_29_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_29_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { // leapster bios uses formats for FLAG that are not defined, bug I guess work anyway (P modes 0 / 1) - return arcompact_handle04_helper_dasm(DASM_PARAMS, "FLAG", 1,1); + return handle04_helper_dasm(stream, pc, op, opcodes, "FLAG", 1,1); } -int arcompact_handle04_2f_helper_dasm(DASM_OPS_32, const char* optext) +int arcompact_disassembler::handle04_2f_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext) { // // 0010 0bbb pp10 1111 FBBB CCCC CCII IIII @@ -1090,7 +1153,7 @@ int arcompact_handle04_2f_helper_dasm(DASM_OPS_32, const char* optext) if (creg == LIMM_REG) { uint32_t limm; - GET_LIMM_32; + GET_LIMM; size = 8; util::stream_format(stream, "(%08x) ", limm); @@ -1119,29 +1182,106 @@ int arcompact_handle04_2f_helper_dasm(DASM_OPS_32, const char* optext) } -int arcompact_handle04_2f_00_dasm(DASM_OPS_32) { return arcompact_handle04_2f_helper_dasm(DASM_PARAMS, "ASL"); } // ASL -int arcompact_handle04_2f_01_dasm(DASM_OPS_32) { return arcompact_handle04_2f_helper_dasm(DASM_PARAMS, "ASR"); } // ASR -int arcompact_handle04_2f_02_dasm(DASM_OPS_32) { return arcompact_handle04_2f_helper_dasm(DASM_PARAMS, "LSR"); } // LSR -int arcompact_handle04_2f_03_dasm(DASM_OPS_32) { return arcompact_handle04_2f_helper_dasm(DASM_PARAMS, "ROR"); } // ROR -int arcompact_handle04_2f_04_dasm(DASM_OPS_32) { return arcompact_handle04_2f_helper_dasm(DASM_PARAMS, "RCC"); } // RCC -int arcompact_handle04_2f_05_dasm(DASM_OPS_32) { return arcompact_handle04_2f_helper_dasm(DASM_PARAMS, "SEXB"); } // SEXB -int arcompact_handle04_2f_06_dasm(DASM_OPS_32) { return arcompact_handle04_2f_helper_dasm(DASM_PARAMS, "SEXW"); } // SEXW -int arcompact_handle04_2f_07_dasm(DASM_OPS_32) { return arcompact_handle04_2f_helper_dasm(DASM_PARAMS, "EXTB"); } // EXTB +int arcompact_disassembler::handle04_2f_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_2f_helper_dasm(stream, pc, op, opcodes, "ASL"); +} // ASL + +int arcompact_disassembler::handle04_2f_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_2f_helper_dasm(stream, pc, op, opcodes, "ASR"); +} // ASR + +int arcompact_disassembler::handle04_2f_02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_2f_helper_dasm(stream, pc, op, opcodes, "LSR"); +} // LSR + +int arcompact_disassembler::handle04_2f_03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_2f_helper_dasm(stream, pc, op, opcodes, "ROR"); +} // ROR + +int arcompact_disassembler::handle04_2f_04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_2f_helper_dasm(stream, pc, op, opcodes, "RCC"); +} // RCC + +int arcompact_disassembler::handle04_2f_05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_2f_helper_dasm(stream, pc, op, opcodes, "SEXB"); +} // SEXB + +int arcompact_disassembler::handle04_2f_06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_2f_helper_dasm(stream, pc, op, opcodes, "SEXW"); +} // SEXW + +int arcompact_disassembler::handle04_2f_07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_2f_helper_dasm(stream, pc, op, opcodes, "EXTB"); +} // EXTB + + +int arcompact_disassembler::handle04_2f_08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_2f_helper_dasm(stream, pc, op, opcodes, "EXTW"); +} // EXTW + + + +int arcompact_disassembler::handle04_2f_09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_2f_helper_dasm(stream, pc, op, opcodes, "ABS"); +} // ABS + +int arcompact_disassembler::handle04_2f_0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_2f_helper_dasm(stream, pc, op, opcodes, "NOT"); +} // NOT + +int arcompact_disassembler::handle04_2f_0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_2f_helper_dasm(stream, pc, op, opcodes, "RCL"); +} // RLC + +int arcompact_disassembler::handle04_2f_0c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_2f_helper_dasm(stream, pc, op, opcodes, "EX"); +} // EX + -int arcompact_handle04_2f_08_dasm(DASM_OPS_32) { return arcompact_handle04_2f_helper_dasm(DASM_PARAMS, "EXTW"); } // EXTW +int arcompact_disassembler::handle04_2f_3f_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format( stream, "SLEEP (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format( stream, "SWI / TRAP0 (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format( stream, "SYNC (%08x)", op); + return 4; +} -int arcompact_handle04_2f_09_dasm(DASM_OPS_32) { return arcompact_handle04_2f_helper_dasm(DASM_PARAMS, "ABS"); } // ABS -int arcompact_handle04_2f_0a_dasm(DASM_OPS_32) { return arcompact_handle04_2f_helper_dasm(DASM_PARAMS, "NOT"); } // NOT -int arcompact_handle04_2f_0b_dasm(DASM_OPS_32) { return arcompact_handle04_2f_helper_dasm(DASM_PARAMS, "RCL"); } // RLC -int arcompact_handle04_2f_0c_dasm(DASM_OPS_32) { return arcompact_handle04_2f_helper_dasm(DASM_PARAMS, "EX"); } // EX +int arcompact_disassembler::handle04_2f_3f_04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format( stream, "RTIE (%08x)", op); + return 4; +} +int arcompact_disassembler::handle04_2f_3f_05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format( stream, "BRK (%08x)", op); + return 4; +} -int arcompact_handle04_2f_3f_01_dasm(DASM_OPS_32) { util::stream_format( stream, "SLEEP (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_02_dasm(DASM_OPS_32) { util::stream_format( stream, "SWI / TRAP0 (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_03_dasm(DASM_OPS_32) { util::stream_format( stream, "SYNC (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_04_dasm(DASM_OPS_32) { util::stream_format( stream, "RTIE (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_05_dasm(DASM_OPS_32) { util::stream_format( stream, "BRK (%08x)", op); return 4; } @@ -1151,7 +1291,7 @@ int arcompact_handle04_2f_3f_05_dasm(DASM_OPS_32) { util::stream_format( stream // 0010 0bbb aa11 0ZZX DBBB CCCC CCAA AAAA // note, bits 11 0ZZX are part of the sub-opcode # already - this is a special encoding -int arcompact_handle04_3x_helper_dasm(DASM_OPS_32, int dsize, int extend) +int arcompact_disassembler::handle04_3x_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, int dsize, int extend) { int size = 4; uint32_t limm=0; @@ -1174,7 +1314,7 @@ int arcompact_handle04_3x_helper_dasm(DASM_OPS_32, int dsize, int extend) if (breg == LIMM_REG) { - GET_LIMM_32; + GET_LIMM; size = 8; got_limm = 1; util::stream_format(stream, "[%08x, ", limm); @@ -1189,7 +1329,7 @@ int arcompact_handle04_3x_helper_dasm(DASM_OPS_32, int dsize, int extend) { if (!got_limm) { - GET_LIMM_32; + GET_LIMM; size = 8; } util::stream_format(stream, "(%08x)]", limm); @@ -1207,43 +1347,127 @@ int arcompact_handle04_3x_helper_dasm(DASM_OPS_32, int dsize, int extend) } -int arcompact_handle04_30_dasm(DASM_OPS_32) { return arcompact_handle04_3x_helper_dasm(DASM_PARAMS,0,0); } +int arcompact_disassembler::handle04_30_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_3x_helper_dasm(stream, pc, op, opcodes,0,0); +} + // ZZ value of 0x0 with X of 1 is illegal -int arcompact_handle04_31_dasm(DASM_OPS_32) { return arcompact_handle04_3x_helper_dasm(DASM_PARAMS,0,1); } -int arcompact_handle04_32_dasm(DASM_OPS_32) { return arcompact_handle04_3x_helper_dasm(DASM_PARAMS,1,0); } -int arcompact_handle04_33_dasm(DASM_OPS_32) { return arcompact_handle04_3x_helper_dasm(DASM_PARAMS,1,1); } -int arcompact_handle04_34_dasm(DASM_OPS_32) { return arcompact_handle04_3x_helper_dasm(DASM_PARAMS,2,0); } -int arcompact_handle04_35_dasm(DASM_OPS_32) { return arcompact_handle04_3x_helper_dasm(DASM_PARAMS,2,1); } +int arcompact_disassembler::handle04_31_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_3x_helper_dasm(stream, pc, op, opcodes,0,1); +} + +int arcompact_disassembler::handle04_32_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_3x_helper_dasm(stream, pc, op, opcodes,1,0); +} + +int arcompact_disassembler::handle04_33_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_3x_helper_dasm(stream, pc, op, opcodes,1,1); +} + +int arcompact_disassembler::handle04_34_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_3x_helper_dasm(stream, pc, op, opcodes,2,0); +} + +int arcompact_disassembler::handle04_35_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_3x_helper_dasm(stream, pc, op, opcodes,2,1); +} + // ZZ value of 0x3 is illegal -int arcompact_handle04_36_dasm(DASM_OPS_32) { return arcompact_handle04_3x_helper_dasm(DASM_PARAMS,3,0); } -int arcompact_handle04_37_dasm(DASM_OPS_32) { return arcompact_handle04_3x_helper_dasm(DASM_PARAMS,3,1); } +int arcompact_disassembler::handle04_36_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_3x_helper_dasm(stream, pc, op, opcodes,3,0); +} + +int arcompact_disassembler::handle04_37_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_3x_helper_dasm(stream, pc, op, opcodes,3,1); +} + + + + + + + +int arcompact_disassembler::handle05_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_helper_dasm(stream, pc, op, opcodes, "ASL", 0,0); +} + +int arcompact_disassembler::handle05_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_helper_dasm(stream, pc, op, opcodes, "LSR", 0,0); +} + +int arcompact_disassembler::handle05_02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_helper_dasm(stream, pc, op, opcodes, "ASR", 0,0); +} + +int arcompact_disassembler::handle05_03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_helper_dasm(stream, pc, op, opcodes, "ROR", 0,0); +} + +int arcompact_disassembler::handle05_04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_helper_dasm(stream, pc, op, opcodes, "MUL64", 2,0); +} // special + +int arcompact_disassembler::handle05_05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_helper_dasm(stream, pc, op, opcodes, "MULU64", 2,0); +} // special + +int arcompact_disassembler::handle05_06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_helper_dasm(stream, pc, op, opcodes, "ADDS", 0,0); +} + +int arcompact_disassembler::handle05_07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_helper_dasm(stream, pc, op, opcodes, "SUBS", 0,0); +} +int arcompact_disassembler::handle05_08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_helper_dasm(stream, pc, op, opcodes, "DIVAW", 0,0); +} +int arcompact_disassembler::handle05_0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_helper_dasm(stream, pc, op, opcodes, "ASLS", 0,0); +} -int arcompact_handle05_00_dasm(DASM_OPS_32) { return arcompact_handle04_helper_dasm(DASM_PARAMS, "ASL", 0,0); } -int arcompact_handle05_01_dasm(DASM_OPS_32) { return arcompact_handle04_helper_dasm(DASM_PARAMS, "LSR", 0,0); } -int arcompact_handle05_02_dasm(DASM_OPS_32) { return arcompact_handle04_helper_dasm(DASM_PARAMS, "ASR", 0,0); } -int arcompact_handle05_03_dasm(DASM_OPS_32) { return arcompact_handle04_helper_dasm(DASM_PARAMS, "ROR", 0,0); } -int arcompact_handle05_04_dasm(DASM_OPS_32) { return arcompact_handle04_helper_dasm(DASM_PARAMS, "MUL64", 2,0); } // special -int arcompact_handle05_05_dasm(DASM_OPS_32) { return arcompact_handle04_helper_dasm(DASM_PARAMS, "MULU64", 2,0);} // special -int arcompact_handle05_06_dasm(DASM_OPS_32) { return arcompact_handle04_helper_dasm(DASM_PARAMS, "ADDS", 0,0); } -int arcompact_handle05_07_dasm(DASM_OPS_32) { return arcompact_handle04_helper_dasm(DASM_PARAMS, "SUBS", 0,0); } -int arcompact_handle05_08_dasm(DASM_OPS_32) { return arcompact_handle04_helper_dasm(DASM_PARAMS, "DIVAW", 0,0); } +int arcompact_disassembler::handle05_0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_helper_dasm(stream, pc, op, opcodes, "ASRS", 0,0); +} +int arcompact_disassembler::handle05_28_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_helper_dasm(stream, pc, op, opcodes, "ADDSDW", 0,0); +} -int arcompact_handle05_0a_dasm(DASM_OPS_32) { return arcompact_handle04_helper_dasm(DASM_PARAMS, "ASLS", 0,0); } -int arcompact_handle05_0b_dasm(DASM_OPS_32) { return arcompact_handle04_helper_dasm(DASM_PARAMS, "ASRS", 0,0); } +int arcompact_disassembler::handle05_29_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_helper_dasm(stream, pc, op, opcodes, "SUBSDW", 0,0); +} -int arcompact_handle05_28_dasm(DASM_OPS_32) { return arcompact_handle04_helper_dasm(DASM_PARAMS, "ADDSDW", 0,0); } -int arcompact_handle05_29_dasm(DASM_OPS_32) { return arcompact_handle04_helper_dasm(DASM_PARAMS, "SUBSDW", 0,0); } -int arcompact_handle05_2f_0x_helper_dasm(DASM_OPS_32, const char* optext) +int arcompact_disassembler::handle05_2f_0x_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext) { // // 0010 1bbb pp10 1111 FBBB CCCC CCII IIII when pp == 0x00 @@ -1271,7 +1495,7 @@ int arcompact_handle05_2f_0x_helper_dasm(DASM_OPS_32, const char* optext) if (creg == LIMM_REG) { uint32_t limm; - GET_LIMM_32; + GET_LIMM; size = 8; util::stream_format(stream, "(%08x) ", limm); @@ -1299,48 +1523,84 @@ int arcompact_handle05_2f_0x_helper_dasm(DASM_OPS_32, const char* optext) } -int arcompact_handle05_2f_00_dasm(DASM_OPS_32) { return arcompact_handle05_2f_0x_helper_dasm(DASM_PARAMS, "SWAP"); } -int arcompact_handle05_2f_01_dasm(DASM_OPS_32) { return arcompact_handle05_2f_0x_helper_dasm(DASM_PARAMS, "NORM"); } -int arcompact_handle05_2f_02_dasm(DASM_OPS_32) { return arcompact_handle05_2f_0x_helper_dasm(DASM_PARAMS, "SAT16"); } -int arcompact_handle05_2f_03_dasm(DASM_OPS_32) { return arcompact_handle05_2f_0x_helper_dasm(DASM_PARAMS, "RND16"); } -int arcompact_handle05_2f_04_dasm(DASM_OPS_32) { return arcompact_handle05_2f_0x_helper_dasm(DASM_PARAMS, "ABSSW"); } -int arcompact_handle05_2f_05_dasm(DASM_OPS_32) { return arcompact_handle05_2f_0x_helper_dasm(DASM_PARAMS, "ABSS"); } -int arcompact_handle05_2f_06_dasm(DASM_OPS_32) { return arcompact_handle05_2f_0x_helper_dasm(DASM_PARAMS, "NEGSW"); } -int arcompact_handle05_2f_07_dasm(DASM_OPS_32) { return arcompact_handle05_2f_0x_helper_dasm(DASM_PARAMS, "NEGS"); } -int arcompact_handle05_2f_08_dasm(DASM_OPS_32) { return arcompact_handle05_2f_0x_helper_dasm(DASM_PARAMS, "NORMW"); } +int arcompact_disassembler::handle05_2f_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle05_2f_0x_helper_dasm(stream, pc, op, opcodes, "SWAP"); +} + +int arcompact_disassembler::handle05_2f_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle05_2f_0x_helper_dasm(stream, pc, op, opcodes, "NORM"); +} + +int arcompact_disassembler::handle05_2f_02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle05_2f_0x_helper_dasm(stream, pc, op, opcodes, "SAT16"); +} +int arcompact_disassembler::handle05_2f_03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle05_2f_0x_helper_dasm(stream, pc, op, opcodes, "RND16"); +} -int arcompact_handle06_dasm(DASM_OPS_32) +int arcompact_disassembler::handle05_2f_04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle05_2f_0x_helper_dasm(stream, pc, op, opcodes, "ABSSW"); +} + +int arcompact_disassembler::handle05_2f_05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle05_2f_0x_helper_dasm(stream, pc, op, opcodes, "ABSS"); +} + +int arcompact_disassembler::handle05_2f_06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle05_2f_0x_helper_dasm(stream, pc, op, opcodes, "NEGSW"); +} + +int arcompact_disassembler::handle05_2f_07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle05_2f_0x_helper_dasm(stream, pc, op, opcodes, "NEGS"); +} + +int arcompact_disassembler::handle05_2f_08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle05_2f_0x_helper_dasm(stream, pc, op, opcodes, "NORMW"); +} + + + +int arcompact_disassembler::handle06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { util::stream_format( stream, "op a,b,c (06 ARC ext) (%08x)", op ); return 4; } -int arcompact_handle07_dasm(DASM_OPS_32) +int arcompact_disassembler::handle07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { util::stream_format( stream, "op a,b,c (07 User ext) (%08x)", op ); return 4; } -int arcompact_handle08_dasm(DASM_OPS_32) +int arcompact_disassembler::handle08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { util::stream_format( stream, "op a,b,c (08 User ext) (%08x)", op ); return 4; } -int arcompact_handle09_dasm(DASM_OPS_32) +int arcompact_disassembler::handle09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { util::stream_format( stream, "op a,b,c (09 Market ext) (%08x)", op ); return 4; } -int arcompact_handle0a_dasm(DASM_OPS_32) +int arcompact_disassembler::handle0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { util::stream_format( stream, "op a,b,c (0a Market ext) (%08x)", op ); return 4; } -int arcompact_handle0b_dasm(DASM_OPS_32) +int arcompact_disassembler::handle0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { util::stream_format( stream, "op a,b,c (0b Market ext) (%08x)", op ); return 4; @@ -1348,7 +1608,7 @@ int arcompact_handle0b_dasm(DASM_OPS_32) -int arcompact_handle0c_helper_dasm(DASM_OPS_16, const char* optext, int format) +int arcompact_disassembler::handle0c_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext, int format) { int areg, breg, creg; @@ -1368,28 +1628,28 @@ int arcompact_handle0c_helper_dasm(DASM_OPS_16, const char* optext, int format) } -int arcompact_handle0c_00_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0c_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle0c_helper_dasm(DASM_PARAMS, "LD_S", 0); + return handle0c_helper_dasm(stream, pc, op, opcodes, "LD_S", 0); } -int arcompact_handle0c_01_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0c_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle0c_helper_dasm(DASM_PARAMS, "LDB_S", 0); + return handle0c_helper_dasm(stream, pc, op, opcodes, "LDB_S", 0); } -int arcompact_handle0c_02_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0c_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle0c_helper_dasm(DASM_PARAMS, "LDW_S", 0); + return handle0c_helper_dasm(stream, pc, op, opcodes, "LDW_S", 0); } -int arcompact_handle0c_03_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0c_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle0c_helper_dasm(DASM_PARAMS, "ADD_S", 1); + return handle0c_helper_dasm(stream, pc, op, opcodes, "ADD_S", 1); } -int arcompact_handle0d_helper_dasm(DASM_OPS_16, const char* optext) +int arcompact_disassembler::handle0d_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext) { int u, breg, creg; @@ -1405,29 +1665,29 @@ int arcompact_handle0d_helper_dasm(DASM_OPS_16, const char* optext) } -int arcompact_handle0d_00_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0d_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle0d_helper_dasm(DASM_PARAMS, "ADD_S"); + return handle0d_helper_dasm(stream, pc, op, opcodes, "ADD_S"); } -int arcompact_handle0d_01_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0d_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle0d_helper_dasm(DASM_PARAMS, "SUB_S"); + return handle0d_helper_dasm(stream, pc, op, opcodes, "SUB_S"); } -int arcompact_handle0d_02_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0d_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle0d_helper_dasm(DASM_PARAMS, "ASL_S"); + return handle0d_helper_dasm(stream, pc, op, opcodes, "ASL_S"); } -int arcompact_handle0d_03_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0d_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle0d_helper_dasm(DASM_PARAMS, "ASR_S"); + return handle0d_helper_dasm(stream, pc, op, opcodes, "ASR_S"); } -int arcompact_handle0e_0x_helper_dasm(DASM_OPS_16, const char* optext, int revop) +int arcompact_disassembler::handle0e_0x_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext, int revop) { int h,breg; int size = 2; @@ -1455,29 +1715,29 @@ int arcompact_handle0e_0x_helper_dasm(DASM_OPS_16, const char* optext, int revop } -int arcompact_handle0e_00_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0e_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle0e_0x_helper_dasm(DASM_PARAMS, "ADD_S", 0); + return handle0e_0x_helper_dasm(stream, pc, op, opcodes, "ADD_S", 0); } -int arcompact_handle0e_01_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0e_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle0e_0x_helper_dasm(DASM_PARAMS, "MOV_S", 0); + return handle0e_0x_helper_dasm(stream, pc, op, opcodes, "MOV_S", 0); } -int arcompact_handle0e_02_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0e_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle0e_0x_helper_dasm(DASM_PARAMS, "CMP_S", 0); + return handle0e_0x_helper_dasm(stream, pc, op, opcodes, "CMP_S", 0); } -int arcompact_handle0e_03_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0e_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle0e_0x_helper_dasm(DASM_PARAMS, "MOV_S", 1); + return handle0e_0x_helper_dasm(stream, pc, op, opcodes, "MOV_S", 1); } -int arcompact_handle0f_00_0x_helper_dasm(DASM_OPS_16, const char* optext) +int arcompact_disassembler::handle0f_00_0x_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext) { int breg; @@ -1492,28 +1752,72 @@ int arcompact_handle0f_00_0x_helper_dasm(DASM_OPS_16, const char* optext) -int arcompact_handle0f_00_00_dasm(DASM_OPS_16) { return arcompact_handle0f_00_0x_helper_dasm(DASM_PARAMS, "J_S"); } -int arcompact_handle0f_00_01_dasm(DASM_OPS_16) { return arcompact_handle0f_00_0x_helper_dasm(DASM_PARAMS, "J_S.D"); } -int arcompact_handle0f_00_02_dasm(DASM_OPS_16) { return arcompact_handle0f_00_0x_helper_dasm(DASM_PARAMS, "JL_S"); } -int arcompact_handle0f_00_03_dasm(DASM_OPS_16) { return arcompact_handle0f_00_0x_helper_dasm(DASM_PARAMS, "JL_S.D"); } -int arcompact_handle0f_00_06_dasm(DASM_OPS_16) { return arcompact_handle0f_00_0x_helper_dasm(DASM_PARAMS, "SUB_S.NE"); } +int arcompact_disassembler::handle0f_00_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_00_0x_helper_dasm(stream, pc, op, opcodes, "J_S"); +} + +int arcompact_disassembler::handle0f_00_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_00_0x_helper_dasm(stream, pc, op, opcodes, "J_S.D"); +} + +int arcompact_disassembler::handle0f_00_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_00_0x_helper_dasm(stream, pc, op, opcodes, "JL_S"); +} + +int arcompact_disassembler::handle0f_00_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_00_0x_helper_dasm(stream, pc, op, opcodes, "JL_S.D"); +} + +int arcompact_disassembler::handle0f_00_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_00_0x_helper_dasm(stream, pc, op, opcodes, "SUB_S.NE"); +} + // Zero parameters (ZOP) -int arcompact_handle0f_00_07_00_dasm(DASM_OPS_16) { util::stream_format( stream, "NOP_S"); return 2; } -int arcompact_handle0f_00_07_01_dasm(DASM_OPS_16) { util::stream_format( stream, "UNIMP_S"); return 2; } // Unimplemented Instruction, same as illegal, but recommended to fill blank space -int arcompact_handle0f_00_07_04_dasm(DASM_OPS_16) { util::stream_format( stream, "JEQ_S [blink]"); return 2; } -int arcompact_handle0f_00_07_05_dasm(DASM_OPS_16) { util::stream_format( stream, "JNE_S [blink]"); return 2; } -int arcompact_handle0f_00_07_06_dasm(DASM_OPS_16) { util::stream_format( stream, "J_S [blink]"); return 2; } -int arcompact_handle0f_00_07_07_dasm(DASM_OPS_16) { util::stream_format( stream, "J_S.D [blink]"); return 2; } +int arcompact_disassembler::handle0f_00_07_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format( stream, "NOP_S"); return 2; +} +int arcompact_disassembler::handle0f_00_07_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format( stream, "UNIMP_S"); return 2; +} // Unimplemented Instruction, same as illegal, but recommended to fill blank space +int arcompact_disassembler::handle0f_00_07_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format( stream, "JEQ_S [blink]"); return 2; +} +int arcompact_disassembler::handle0f_00_07_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format( stream, "JNE_S [blink]"); return 2; +} +int arcompact_disassembler::handle0f_00_07_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format( stream, "J_S [blink]"); return 2; +} -int arcompact_handle0f_0x_helper_dasm(DASM_OPS_16, const char* optext, int nodst) +int arcompact_disassembler::handle0f_00_07_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format( stream, "J_S.D [blink]"); return 2; +} + + + + + + +int arcompact_disassembler::handle0f_0x_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext, int nodst) { int breg, creg; @@ -1530,39 +1834,131 @@ int arcompact_handle0f_0x_helper_dasm(DASM_OPS_16, const char* optext, int nodst return 2; } -int arcompact_handle0f_02_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "SUB_S",0); } -int arcompact_handle0f_04_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "AND_S",0); } -int arcompact_handle0f_05_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "OR_S",0); } -int arcompact_handle0f_06_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "BIC_S",0); } -int arcompact_handle0f_07_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "XOR_S",0); } -int arcompact_handle0f_0b_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "TST_S",1); } -int arcompact_handle0f_0c_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "MUL64_S",2); } // actual destination is special multiply registers -int arcompact_handle0f_0d_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "SEXB_S",0); } -int arcompact_handle0f_0e_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "SEXW_S",0); } -int arcompact_handle0f_0f_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "EXTB_S",0); } -int arcompact_handle0f_10_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "EXTW_S",0); } -int arcompact_handle0f_11_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "ABS_S",0); } -int arcompact_handle0f_12_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "NOT_S",0); } -int arcompact_handle0f_13_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "NEG_S",0); } -int arcompact_handle0f_14_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "ADD1_S",0); } -int arcompact_handle0f_15_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "ADD2_S",0); } -int arcompact_handle0f_16_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "ADD3_S",0); } -int arcompact_handle0f_18_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "ASL_S",0); } -int arcompact_handle0f_19_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "LSR_S",0); } -int arcompact_handle0f_1a_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "ASR_S",0); } -int arcompact_handle0f_1b_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "ASL1_S",0); } -int arcompact_handle0f_1c_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "ASR1_S",0); } -int arcompact_handle0f_1d_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "LSR1_S",0); } - - -int arcompact_handle0f_1e_dasm(DASM_OPS_16) // special +int arcompact_disassembler::handle0f_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "SUB_S",0); +} + +int arcompact_disassembler::handle0f_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "AND_S",0); +} + +int arcompact_disassembler::handle0f_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "OR_S",0); +} + +int arcompact_disassembler::handle0f_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "BIC_S",0); +} + +int arcompact_disassembler::handle0f_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "XOR_S",0); +} + +int arcompact_disassembler::handle0f_0b_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "TST_S",1); +} + +int arcompact_disassembler::handle0f_0c_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "MUL64_S",2); +} // actual destination is special multiply registers + +int arcompact_disassembler::handle0f_0d_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "SEXB_S",0); +} + +int arcompact_disassembler::handle0f_0e_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "SEXW_S",0); +} + +int arcompact_disassembler::handle0f_0f_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "EXTB_S",0); +} + +int arcompact_disassembler::handle0f_10_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "EXTW_S",0); +} + +int arcompact_disassembler::handle0f_11_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "ABS_S",0); +} + +int arcompact_disassembler::handle0f_12_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "NOT_S",0); +} + +int arcompact_disassembler::handle0f_13_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "NEG_S",0); +} + +int arcompact_disassembler::handle0f_14_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "ADD1_S",0); +} + +int arcompact_disassembler::handle0f_15_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "ADD2_S",0); +} + +int arcompact_disassembler::handle0f_16_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "ADD3_S",0); +} + +int arcompact_disassembler::handle0f_18_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "ASL_S",0); +} + +int arcompact_disassembler::handle0f_19_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "LSR_S",0); +} + +int arcompact_disassembler::handle0f_1a_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "ASR_S",0); +} + +int arcompact_disassembler::handle0f_1b_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "ASL1_S",0); +} + +int arcompact_disassembler::handle0f_1c_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "ASR1_S",0); +} + +int arcompact_disassembler::handle0f_1d_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "LSR1_S",0); +} + + + +int arcompact_disassembler::handle0f_1e_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) // special { // 0111 1uuu uuu1 1110 int u = (op & 0x07e0)>>5; util::stream_format( stream, "TRAP_S %02x",u); return 2; } -int arcompact_handle0f_1f_dasm(DASM_OPS_16) // special +int arcompact_disassembler::handle0f_1f_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) // special { int u = (op & 0x07e0)>>5; op &= ~0x07e0; @@ -1578,7 +1974,7 @@ int arcompact_handle0f_1f_dasm(DASM_OPS_16) // special } -int arcompact_handle_ld_helper_dasm(DASM_OPS_16, const char* optext, int shift, int swap) +int arcompact_disassembler::handle_ld_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext, int shift, int swap) { int breg, creg, u; @@ -1598,43 +1994,43 @@ int arcompact_handle_ld_helper_dasm(DASM_OPS_16, const char* optext, int shift, } -int arcompact_handle10_dasm(DASM_OPS_16) +int arcompact_disassembler::handle10_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle_ld_helper_dasm(DASM_PARAMS, "LD_S", 2, 0); + return handle_ld_helper_dasm(stream, pc, op, opcodes, "LD_S", 2, 0); } -int arcompact_handle11_dasm(DASM_OPS_16) +int arcompact_disassembler::handle11_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle_ld_helper_dasm(DASM_PARAMS, "LDB_S", 0, 0); + return handle_ld_helper_dasm(stream, pc, op, opcodes, "LDB_S", 0, 0); } -int arcompact_handle12_dasm(DASM_OPS_16) +int arcompact_disassembler::handle12_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle_ld_helper_dasm(DASM_PARAMS, "LDW_S", 1, 0); + return handle_ld_helper_dasm(stream, pc, op, opcodes, "LDW_S", 1, 0); } -int arcompact_handle13_dasm(DASM_OPS_16) +int arcompact_disassembler::handle13_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle_ld_helper_dasm(DASM_PARAMS, "LDW_S.X", 1, 0); + return handle_ld_helper_dasm(stream, pc, op, opcodes, "LDW_S.X", 1, 0); } -int arcompact_handle14_dasm(DASM_OPS_16) +int arcompact_disassembler::handle14_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle_ld_helper_dasm(DASM_PARAMS, "ST_S", 2, 1); + return handle_ld_helper_dasm(stream, pc, op, opcodes, "ST_S", 2, 1); } -int arcompact_handle15_dasm(DASM_OPS_16) +int arcompact_disassembler::handle15_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle_ld_helper_dasm(DASM_PARAMS, "STB_S", 0, 1); + return handle_ld_helper_dasm(stream, pc, op, opcodes, "STB_S", 0, 1); } -int arcompact_handle16_dasm(DASM_OPS_16) +int arcompact_disassembler::handle16_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle_ld_helper_dasm(DASM_PARAMS, "STW_S", 1, 1); + return handle_ld_helper_dasm(stream, pc, op, opcodes, "STW_S", 1, 1); } -int arcompact_handle_l7_0x_helper_dasm(DASM_OPS_16, const char* optext) +int arcompact_disassembler::handle_l7_0x_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext) { int breg, u; @@ -1649,50 +2045,50 @@ int arcompact_handle_l7_0x_helper_dasm(DASM_OPS_16, const char* optext) } -int arcompact_handle17_00_dasm(DASM_OPS_16) +int arcompact_disassembler::handle17_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle_l7_0x_helper_dasm(DASM_PARAMS, "ASL_S"); + return handle_l7_0x_helper_dasm(stream, pc, op, opcodes, "ASL_S"); } -int arcompact_handle17_01_dasm(DASM_OPS_16) +int arcompact_disassembler::handle17_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle_l7_0x_helper_dasm(DASM_PARAMS, "LSR_S"); + return handle_l7_0x_helper_dasm(stream, pc, op, opcodes, "LSR_S"); } -int arcompact_handle17_02_dasm(DASM_OPS_16) +int arcompact_disassembler::handle17_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle_l7_0x_helper_dasm(DASM_PARAMS, "ASR_S"); + return handle_l7_0x_helper_dasm(stream, pc, op, opcodes, "ASR_S"); } -int arcompact_handle17_03_dasm(DASM_OPS_16) +int arcompact_disassembler::handle17_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle_l7_0x_helper_dasm(DASM_PARAMS, "SUB_S"); + return handle_l7_0x_helper_dasm(stream, pc, op, opcodes, "SUB_S"); } -int arcompact_handle17_04_dasm(DASM_OPS_16) +int arcompact_disassembler::handle17_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle_l7_0x_helper_dasm(DASM_PARAMS, "BSET_S"); + return handle_l7_0x_helper_dasm(stream, pc, op, opcodes, "BSET_S"); } -int arcompact_handle17_05_dasm(DASM_OPS_16) +int arcompact_disassembler::handle17_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle_l7_0x_helper_dasm(DASM_PARAMS, "BCLR_S"); + return handle_l7_0x_helper_dasm(stream, pc, op, opcodes, "BCLR_S"); } -int arcompact_handle17_06_dasm(DASM_OPS_16) +int arcompact_disassembler::handle17_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle_l7_0x_helper_dasm(DASM_PARAMS, "BSMK_S"); + return handle_l7_0x_helper_dasm(stream, pc, op, opcodes, "BSMK_S"); } -int arcompact_handle17_07_dasm(DASM_OPS_16) +int arcompact_disassembler::handle17_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle_l7_0x_helper_dasm(DASM_PARAMS, "BTST_S"); + return handle_l7_0x_helper_dasm(stream, pc, op, opcodes, "BTST_S"); } // op bits remaining for 0x18_xx subgroups 0x071f -int arcompact_handle18_0x_helper_dasm(DASM_OPS_16, const char* optext, int st, int format) +int arcompact_disassembler::handle18_0x_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext, int st, int format) { int breg, u; @@ -1712,33 +2108,33 @@ int arcompact_handle18_0x_helper_dasm(DASM_OPS_16, const char* optext, int st, i return 2; } -int arcompact_handle18_00_dasm(DASM_OPS_16) +int arcompact_disassembler::handle18_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle18_0x_helper_dasm(DASM_PARAMS, "LD_S", 0,0); + return handle18_0x_helper_dasm(stream, pc, op, opcodes, "LD_S", 0,0); } -int arcompact_handle18_01_dasm(DASM_OPS_16) +int arcompact_disassembler::handle18_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle18_0x_helper_dasm(DASM_PARAMS, "LDB_S", 0,0); + return handle18_0x_helper_dasm(stream, pc, op, opcodes, "LDB_S", 0,0); } -int arcompact_handle18_02_dasm(DASM_OPS_16) +int arcompact_disassembler::handle18_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle18_0x_helper_dasm(DASM_PARAMS, "ST_S", 1,0); + return handle18_0x_helper_dasm(stream, pc, op, opcodes, "ST_S", 1,0); } -int arcompact_handle18_03_dasm(DASM_OPS_16) +int arcompact_disassembler::handle18_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle18_0x_helper_dasm(DASM_PARAMS, "STB_S", 1,0); + return handle18_0x_helper_dasm(stream, pc, op, opcodes, "STB_S", 1,0); } -int arcompact_handle18_04_dasm(DASM_OPS_16) +int arcompact_disassembler::handle18_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle18_0x_helper_dasm(DASM_PARAMS, "ADD_S", 1,1); // check format + return handle18_0x_helper_dasm(stream, pc, op, opcodes, "ADD_S", 1,1); // check format } // op bits remaining for 0x18_05_xx subgroups 0x001f -int arcompact_handle18_05_00_dasm(DASM_OPS_16) +int arcompact_disassembler::handle18_05_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int u; COMMON16_GET_u5; @@ -1748,7 +2144,7 @@ int arcompact_handle18_05_00_dasm(DASM_OPS_16) } -int arcompact_handle18_05_01_dasm(DASM_OPS_16) +int arcompact_disassembler::handle18_05_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int u; COMMON16_GET_u5; @@ -1758,7 +2154,7 @@ int arcompact_handle18_05_01_dasm(DASM_OPS_16) } // op bits remaining for 0x18_06_xx subgroups 0x0700 -int arcompact_handle18_06_01_dasm(DASM_OPS_16) +int arcompact_disassembler::handle18_06_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int breg; COMMON16_GET_breg @@ -1769,7 +2165,7 @@ int arcompact_handle18_06_01_dasm(DASM_OPS_16) return 2; } -int arcompact_handle18_06_11_dasm(DASM_OPS_16) +int arcompact_disassembler::handle18_06_11_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int res = (op & 0x0700) >> 8; op &= ~0x0700; // all bits now used @@ -1783,7 +2179,7 @@ int arcompact_handle18_06_11_dasm(DASM_OPS_16) } // op bits remaining for 0x18_07_xx subgroups 0x0700 -int arcompact_handle18_07_01_dasm(DASM_OPS_16) +int arcompact_disassembler::handle18_07_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int breg; COMMON16_GET_breg @@ -1795,7 +2191,7 @@ int arcompact_handle18_07_01_dasm(DASM_OPS_16) } -int arcompact_handle18_07_11_dasm(DASM_OPS_16) +int arcompact_disassembler::handle18_07_11_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int res = (op & 0x0700) >> 8; op &= ~0x0700; // all bits now used @@ -1809,7 +2205,7 @@ int arcompact_handle18_07_11_dasm(DASM_OPS_16) } -int arcompact_handle19_0x_helper_dasm(DASM_OPS_16, const char* optext, int shift, int format) +int arcompact_disassembler::handle19_0x_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext, int shift, int format) { int s; @@ -1831,12 +2227,28 @@ int arcompact_handle19_0x_helper_dasm(DASM_OPS_16, const char* optext, int shift return 2; } -int arcompact_handle19_00_dasm(DASM_OPS_16) { return arcompact_handle19_0x_helper_dasm(DASM_PARAMS, "LD_S", 2, 0); } -int arcompact_handle19_01_dasm(DASM_OPS_16) { return arcompact_handle19_0x_helper_dasm(DASM_PARAMS, "LDB_S", 0, 0); } -int arcompact_handle19_02_dasm(DASM_OPS_16) { return arcompact_handle19_0x_helper_dasm(DASM_PARAMS, "LDW_S", 1, 0); } -int arcompact_handle19_03_dasm(DASM_OPS_16) { return arcompact_handle19_0x_helper_dasm(DASM_PARAMS, "ADD_S", 2, 1); } +int arcompact_disassembler::handle19_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle19_0x_helper_dasm(stream, pc, op, opcodes, "LD_S", 2, 0); +} + +int arcompact_disassembler::handle19_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle19_0x_helper_dasm(stream, pc, op, opcodes, "LDB_S", 0, 0); +} + +int arcompact_disassembler::handle19_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle19_0x_helper_dasm(stream, pc, op, opcodes, "LDW_S", 1, 0); +} -int arcompact_handle1a_dasm(DASM_OPS_16) +int arcompact_disassembler::handle19_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle19_0x_helper_dasm(stream, pc, op, opcodes, "ADD_S", 2, 1); +} + + +int arcompact_disassembler::handle1a_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int breg, u; COMMON16_GET_breg; @@ -1848,7 +2260,7 @@ int arcompact_handle1a_dasm(DASM_OPS_16) return 2; } -int arcompact_handle1b_dasm(DASM_OPS_16) +int arcompact_disassembler::handle1b_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int breg, u; COMMON16_GET_breg; @@ -1859,7 +2271,7 @@ int arcompact_handle1b_dasm(DASM_OPS_16) return 2; } -int arcompact_handle1c_00_dasm(DASM_OPS_16) +int arcompact_disassembler::handle1c_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int breg, u; COMMON16_GET_breg; @@ -1870,7 +2282,7 @@ int arcompact_handle1c_00_dasm(DASM_OPS_16) return 2; } -int arcompact_handle1c_01_dasm(DASM_OPS_16) +int arcompact_disassembler::handle1c_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int breg, u; COMMON16_GET_breg; @@ -1881,7 +2293,7 @@ int arcompact_handle1c_01_dasm(DASM_OPS_16) return 2; } -int arcompact_handle1d_helper_dasm(DASM_OPS_16, const char* optext) +int arcompact_disassembler::handle1d_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext) { int breg; COMMON16_GET_breg; @@ -1895,11 +2307,19 @@ int arcompact_handle1d_helper_dasm(DASM_OPS_16, const char* optext) } -int arcompact_handle1d_00_dasm(DASM_OPS_16) { return arcompact_handle1d_helper_dasm(DASM_PARAMS,"BREQ_S"); } -int arcompact_handle1d_01_dasm(DASM_OPS_16) { return arcompact_handle1d_helper_dasm(DASM_PARAMS,"BRNE_S"); } +int arcompact_disassembler::handle1d_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle1d_helper_dasm(stream, pc, op, opcodes,"BREQ_S"); +} +int arcompact_disassembler::handle1d_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle1d_helper_dasm(stream, pc, op, opcodes,"BRNE_S"); +} -int arcompact_handle1e_0x_helper_dasm(DASM_OPS_16, const char* optext) + + +int arcompact_disassembler::handle1e_0x_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext) { int s = (op & 0x01ff) >> 0; op &= ~0x01ff; if (s & 0x100) s = -0x100 + (s & 0xff); @@ -1910,11 +2330,23 @@ int arcompact_handle1e_0x_helper_dasm(DASM_OPS_16, const char* optext) -int arcompact_handle1e_00_dasm(DASM_OPS_16) { return arcompact_handle1e_0x_helper_dasm(DASM_PARAMS, "B_S"); } -int arcompact_handle1e_01_dasm(DASM_OPS_16) { return arcompact_handle1e_0x_helper_dasm(DASM_PARAMS, "BEQ_S"); } -int arcompact_handle1e_02_dasm(DASM_OPS_16) { return arcompact_handle1e_0x_helper_dasm(DASM_PARAMS, "BNE_S"); } +int arcompact_disassembler::handle1e_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle1e_0x_helper_dasm(stream, pc, op, opcodes, "B_S"); +} + +int arcompact_disassembler::handle1e_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle1e_0x_helper_dasm(stream, pc, op, opcodes, "BEQ_S"); +} + +int arcompact_disassembler::handle1e_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle1e_0x_helper_dasm(stream, pc, op, opcodes, "BNE_S"); +} + -int arcompact_handle1e_03_0x_helper_dasm(DASM_OPS_16, const char* optext) +int arcompact_disassembler::handle1e_03_0x_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext) { int s = (op & 0x003f) >> 0; op &= ~0x003f; if (s & 0x020) s = -0x20 + (s & 0x1f); @@ -1923,16 +2355,48 @@ int arcompact_handle1e_03_0x_helper_dasm(DASM_OPS_16, const char* optext) return 2; } -int arcompact_handle1e_03_00_dasm(DASM_OPS_16) { return arcompact_handle1e_03_0x_helper_dasm(DASM_PARAMS, "BGT_S"); } -int arcompact_handle1e_03_01_dasm(DASM_OPS_16) { return arcompact_handle1e_03_0x_helper_dasm(DASM_PARAMS, "BGE_S"); } -int arcompact_handle1e_03_02_dasm(DASM_OPS_16) { return arcompact_handle1e_03_0x_helper_dasm(DASM_PARAMS, "BLT_S"); } -int arcompact_handle1e_03_03_dasm(DASM_OPS_16) { return arcompact_handle1e_03_0x_helper_dasm(DASM_PARAMS, "BLE_S"); } -int arcompact_handle1e_03_04_dasm(DASM_OPS_16) { return arcompact_handle1e_03_0x_helper_dasm(DASM_PARAMS, "BHI_S"); } -int arcompact_handle1e_03_05_dasm(DASM_OPS_16) { return arcompact_handle1e_03_0x_helper_dasm(DASM_PARAMS, "BHS_S"); } -int arcompact_handle1e_03_06_dasm(DASM_OPS_16) { return arcompact_handle1e_03_0x_helper_dasm(DASM_PARAMS, "BLO_S"); } -int arcompact_handle1e_03_07_dasm(DASM_OPS_16) { return arcompact_handle1e_03_0x_helper_dasm(DASM_PARAMS, "BLS_S"); } +int arcompact_disassembler::handle1e_03_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle1e_03_0x_helper_dasm(stream, pc, op, opcodes, "BGT_S"); +} + +int arcompact_disassembler::handle1e_03_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle1e_03_0x_helper_dasm(stream, pc, op, opcodes, "BGE_S"); +} + +int arcompact_disassembler::handle1e_03_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle1e_03_0x_helper_dasm(stream, pc, op, opcodes, "BLT_S"); +} + +int arcompact_disassembler::handle1e_03_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle1e_03_0x_helper_dasm(stream, pc, op, opcodes, "BLE_S"); +} -int arcompact_handle1f_dasm(DASM_OPS_16) +int arcompact_disassembler::handle1e_03_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle1e_03_0x_helper_dasm(stream, pc, op, opcodes, "BHI_S"); +} + +int arcompact_disassembler::handle1e_03_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle1e_03_0x_helper_dasm(stream, pc, op, opcodes, "BHS_S"); +} + +int arcompact_disassembler::handle1e_03_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle1e_03_0x_helper_dasm(stream, pc, op, opcodes, "BLO_S"); +} + +int arcompact_disassembler::handle1e_03_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle1e_03_0x_helper_dasm(stream, pc, op, opcodes, "BLS_S"); +} + + +int arcompact_disassembler::handle1f_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int s = (op & 0x07ff) >> 0; op &= ~0x07ff; if (s & 0x400) s = -0x400 + (s & 0x3ff); @@ -1947,411 +2411,2340 @@ int arcompact_handle1f_dasm(DASM_OPS_16) * * ************************************************************************************************************************************/ -int arcompact_handle01_01_00_06_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 01_01_00_06> (%08x)", op); return 4; } -int arcompact_handle01_01_00_07_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 01_01_00_07> (%08x)", op); return 4; } -int arcompact_handle01_01_00_08_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 01_01_00_08> (%08x)", op); return 4; } -int arcompact_handle01_01_00_09_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 01_01_00_09> (%08x)", op); return 4; } -int arcompact_handle01_01_00_0a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 01_01_00_0a> (%08x)", op); return 4; } -int arcompact_handle01_01_00_0b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 01_01_00_0b> (%08x)", op); return 4; } -int arcompact_handle01_01_00_0c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 01_01_00_0c> (%08x)", op); return 4; } -int arcompact_handle01_01_00_0d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 01_01_00_0d> (%08x)", op); return 4; } - -int arcompact_handle01_01_01_06_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 01_01_01_06> (%08x)", op); return 4; } -int arcompact_handle01_01_01_07_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 01_01_01_07> (%08x)", op); return 4; } -int arcompact_handle01_01_01_08_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 01_01_01_08> (%08x)", op); return 4; } -int arcompact_handle01_01_01_09_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 01_01_01_09> (%08x)", op); return 4; } -int arcompact_handle01_01_01_0a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 01_01_01_0a> (%08x)", op); return 4; } -int arcompact_handle01_01_01_0b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 01_01_01_0b> (%08x)", op); return 4; } -int arcompact_handle01_01_01_0c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 01_01_01_0c> (%08x)", op); return 4; } -int arcompact_handle01_01_01_0d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 01_01_01_0d> (%08x)", op); return 4; } - - -int arcompact_handle04_1e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_1e> (%08x)", op); return 4; } -int arcompact_handle04_1f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_1f> (%08x)", op); return 4; } - -int arcompact_handle04_24_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_24> (%08x)", op); return 4; } -int arcompact_handle04_25_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_25> (%08x)", op); return 4; } -int arcompact_handle04_26_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_26> (%08x)", op); return 4; } -int arcompact_handle04_27_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_27> (%08x)", op); return 4; } - -int arcompact_handle04_2c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2c> (%08x)", op); return 4; } -int arcompact_handle04_2d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2d> (%08x)", op); return 4; } -int arcompact_handle04_2e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2e> (%08x)", op); return 4; } - -int arcompact_handle04_2f_0d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_0d> (%08x)", op); return 4; } -int arcompact_handle04_2f_0e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_0e> (%08x)", op); return 4; } -int arcompact_handle04_2f_0f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_0f> (%08x)", op); return 4; } -int arcompact_handle04_2f_10_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_10> (%08x)", op); return 4; } -int arcompact_handle04_2f_11_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_11> (%08x)", op); return 4; } -int arcompact_handle04_2f_12_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_12> (%08x)", op); return 4; } -int arcompact_handle04_2f_13_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_13> (%08x)", op); return 4; } -int arcompact_handle04_2f_14_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_14> (%08x)", op); return 4; } -int arcompact_handle04_2f_15_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_15> (%08x)", op); return 4; } -int arcompact_handle04_2f_16_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_16> (%08x)", op); return 4; } -int arcompact_handle04_2f_17_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_17> (%08x)", op); return 4; } -int arcompact_handle04_2f_18_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_18> (%08x)", op); return 4; } -int arcompact_handle04_2f_19_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_19> (%08x)", op); return 4; } -int arcompact_handle04_2f_1a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_1a> (%08x)", op); return 4; } -int arcompact_handle04_2f_1b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_1b> (%08x)", op); return 4; } -int arcompact_handle04_2f_1c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_1c> (%08x)", op); return 4; } -int arcompact_handle04_2f_1d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_1d> (%08x)", op); return 4; } -int arcompact_handle04_2f_1e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_1e> (%08x)", op); return 4; } -int arcompact_handle04_2f_1f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_1f> (%08x)", op); return 4; } -int arcompact_handle04_2f_20_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_20> (%08x)", op); return 4; } -int arcompact_handle04_2f_21_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_21> (%08x)", op); return 4; } -int arcompact_handle04_2f_22_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_22> (%08x)", op); return 4; } -int arcompact_handle04_2f_23_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_23> (%08x)", op); return 4; } -int arcompact_handle04_2f_24_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_24> (%08x)", op); return 4; } -int arcompact_handle04_2f_25_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_25> (%08x)", op); return 4; } -int arcompact_handle04_2f_26_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_26> (%08x)", op); return 4; } -int arcompact_handle04_2f_27_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_27> (%08x)", op); return 4; } -int arcompact_handle04_2f_28_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_28> (%08x)", op); return 4; } -int arcompact_handle04_2f_29_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_29> (%08x)", op); return 4; } -int arcompact_handle04_2f_2a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_2a> (%08x)", op); return 4; } -int arcompact_handle04_2f_2b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_2b> (%08x)", op); return 4; } -int arcompact_handle04_2f_2c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_2c> (%08x)", op); return 4; } -int arcompact_handle04_2f_2d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_2d> (%08x)", op); return 4; } -int arcompact_handle04_2f_2e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_2e> (%08x)", op); return 4; } -int arcompact_handle04_2f_2f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_2f> (%08x)", op); return 4; } -int arcompact_handle04_2f_30_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_30> (%08x)", op); return 4; } -int arcompact_handle04_2f_31_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_31> (%08x)", op); return 4; } -int arcompact_handle04_2f_32_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_32> (%08x)", op); return 4; } -int arcompact_handle04_2f_33_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_33> (%08x)", op); return 4; } -int arcompact_handle04_2f_34_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_34> (%08x)", op); return 4; } -int arcompact_handle04_2f_35_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_35> (%08x)", op); return 4; } -int arcompact_handle04_2f_36_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_36> (%08x)", op); return 4; } -int arcompact_handle04_2f_37_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_37> (%08x)", op); return 4; } -int arcompact_handle04_2f_38_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_38> (%08x)", op); return 4; } -int arcompact_handle04_2f_39_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_39> (%08x)", op); return 4; } -int arcompact_handle04_2f_3a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3a> (%08x)", op); return 4; } -int arcompact_handle04_2f_3b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3b> (%08x)", op); return 4; } -int arcompact_handle04_2f_3c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3c> (%08x)", op); return 4; } -int arcompact_handle04_2f_3d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3d> (%08x)", op); return 4; } -int arcompact_handle04_2f_3e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3e> (%08x)", op); return 4; } - - - -int arcompact_handle05_2f_09_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_09> (%08x)", op); return 4; } -int arcompact_handle05_2f_0a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_0a> (%08x)", op); return 4; } -int arcompact_handle05_2f_0b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_0b> (%08x)", op); return 4; } -int arcompact_handle05_2f_0c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_0c> (%08x)", op); return 4; } -int arcompact_handle05_2f_0d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_0d> (%08x)", op); return 4; } -int arcompact_handle05_2f_0e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_0e> (%08x)", op); return 4; } -int arcompact_handle05_2f_0f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_0f> (%08x)", op); return 4; } -int arcompact_handle05_2f_10_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_10> (%08x)", op); return 4; } -int arcompact_handle05_2f_11_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_11> (%08x)", op); return 4; } -int arcompact_handle05_2f_12_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_12> (%08x)", op); return 4; } -int arcompact_handle05_2f_13_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_13> (%08x)", op); return 4; } -int arcompact_handle05_2f_14_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_14> (%08x)", op); return 4; } -int arcompact_handle05_2f_15_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_15> (%08x)", op); return 4; } -int arcompact_handle05_2f_16_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_16> (%08x)", op); return 4; } -int arcompact_handle05_2f_17_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_17> (%08x)", op); return 4; } -int arcompact_handle05_2f_18_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_18> (%08x)", op); return 4; } -int arcompact_handle05_2f_19_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_19> (%08x)", op); return 4; } -int arcompact_handle05_2f_1a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_1a> (%08x)", op); return 4; } -int arcompact_handle05_2f_1b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_1b> (%08x)", op); return 4; } -int arcompact_handle05_2f_1c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_1c> (%08x)", op); return 4; } -int arcompact_handle05_2f_1d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_1d> (%08x)", op); return 4; } -int arcompact_handle05_2f_1e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_1e> (%08x)", op); return 4; } -int arcompact_handle05_2f_1f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_1f> (%08x)", op); return 4; } -int arcompact_handle05_2f_20_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_20> (%08x)", op); return 4; } -int arcompact_handle05_2f_21_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_21> (%08x)", op); return 4; } -int arcompact_handle05_2f_22_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_22> (%08x)", op); return 4; } -int arcompact_handle05_2f_23_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_23> (%08x)", op); return 4; } -int arcompact_handle05_2f_24_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_24> (%08x)", op); return 4; } -int arcompact_handle05_2f_25_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_25> (%08x)", op); return 4; } -int arcompact_handle05_2f_26_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_26> (%08x)", op); return 4; } -int arcompact_handle05_2f_27_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_27> (%08x)", op); return 4; } -int arcompact_handle05_2f_28_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_28> (%08x)", op); return 4; } -int arcompact_handle05_2f_29_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_29> (%08x)", op); return 4; } -int arcompact_handle05_2f_2a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_2a> (%08x)", op); return 4; } -int arcompact_handle05_2f_2b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_2b> (%08x)", op); return 4; } -int arcompact_handle05_2f_2c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_2c> (%08x)", op); return 4; } -int arcompact_handle05_2f_2d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_2d> (%08x)", op); return 4; } -int arcompact_handle05_2f_2e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_2e> (%08x)", op); return 4; } -int arcompact_handle05_2f_2f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_2f> (%08x)", op); return 4; } -int arcompact_handle05_2f_30_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_30> (%08x)", op); return 4; } -int arcompact_handle05_2f_31_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_31> (%08x)", op); return 4; } -int arcompact_handle05_2f_32_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_32> (%08x)", op); return 4; } -int arcompact_handle05_2f_33_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_33> (%08x)", op); return 4; } -int arcompact_handle05_2f_34_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_34> (%08x)", op); return 4; } -int arcompact_handle05_2f_35_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_35> (%08x)", op); return 4; } -int arcompact_handle05_2f_36_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_36> (%08x)", op); return 4; } -int arcompact_handle05_2f_37_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_37> (%08x)", op); return 4; } -int arcompact_handle05_2f_38_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_38> (%08x)", op); return 4; } -int arcompact_handle05_2f_39_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_39> (%08x)", op); return 4; } -int arcompact_handle05_2f_3a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3a> (%08x)", op); return 4; } -int arcompact_handle05_2f_3b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3b> (%08x)", op); return 4; } -int arcompact_handle05_2f_3c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3c> (%08x)", op); return 4; } -int arcompact_handle05_2f_3d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3d> (%08x)", op); return 4; } -int arcompact_handle05_2f_3e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3e> (%08x)", op); return 4; } - - -int arcompact_handle04_2f_3f_00_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_00> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_06_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_06> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_07_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_07> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_08_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_08> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_09_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_09> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_0a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_0a> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_0b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_0b> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_0c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_0c> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_0d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_0d> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_0e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_0e> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_0f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_0f> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_10_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_10> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_11_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_11> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_12_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_12> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_13_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_13> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_14_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_14> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_15_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_15> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_16_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_16> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_17_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_17> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_18_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_18> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_19_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_19> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_1a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_1a> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_1b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_1b> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_1c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_1c> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_1d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_1d> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_1e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_1e> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_1f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_1f> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_20_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_20> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_21_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_21> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_22_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_22> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_23_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_23> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_24_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_24> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_25_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_25> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_26_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_26> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_27_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_27> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_28_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_28> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_29_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_29> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_2a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_2a> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_2b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_2b> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_2c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_2c> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_2d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_2d> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_2e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_2e> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_2f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_2f> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_30_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_30> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_31_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_31> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_32_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_32> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_33_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_33> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_34_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_34> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_35_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_35> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_36_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_36> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_37_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_37> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_38_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_38> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_39_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_39> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_3a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_3a> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_3b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_3b> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_3c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_3c> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_3d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_3d> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_3e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_3e> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_3f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_3f> (%08x)", op); return 4; } - -int arcompact_handle05_2f_3f_00_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_00> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_01_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_01> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_02_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_02> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_03_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_03> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_04_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_04> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_05_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_05> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_06_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_06> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_07_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_07> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_08_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_08> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_09_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_09> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_0a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_0a> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_0b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_0b> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_0c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_0c> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_0d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_0d> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_0e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_0e> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_0f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_0f> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_10_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_10> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_11_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_11> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_12_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_12> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_13_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_13> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_14_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_14> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_15_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_15> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_16_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_16> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_17_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_17> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_18_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_18> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_19_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_19> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_1a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_1a> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_1b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_1b> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_1c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_1c> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_1d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_1d> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_1e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_1e> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_1f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_1f> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_20_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_20> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_21_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_21> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_22_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_22> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_23_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_23> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_24_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_24> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_25_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_25> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_26_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_26> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_27_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_27> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_28_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_28> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_29_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_29> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_2a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_2a> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_2b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_2b> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_2c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_2c> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_2d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_2d> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_2e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_2e> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_2f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_2f> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_30_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_30> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_31_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_31> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_32_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_32> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_33_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_33> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_34_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_34> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_35_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_35> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_36_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_36> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_37_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_37> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_38_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_38> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_39_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_39> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_3a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_3a> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_3b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_3b> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_3c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_3c> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_3d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_3d> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_3e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_3e> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_3f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_3f> (%08x)", op); return 4; } - - - - -int arcompact_handle04_38_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_38> (%08x)", op); return 4; } -int arcompact_handle04_39_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_39> (%08x)", op); return 4; } -int arcompact_handle04_3a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_3a> (%08x)", op); return 4; } -int arcompact_handle04_3b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_3b> (%08x)", op); return 4; } -int arcompact_handle04_3c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_3c> (%08x)", op); return 4; } -int arcompact_handle04_3d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_3d> (%08x)", op); return 4; } -int arcompact_handle04_3e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_3e> (%08x)", op); return 4; } -int arcompact_handle04_3f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_3f> (%08x)", op); return 4; } - - -int arcompact_handle05_09_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_09> (%08x)", op); return 4; } -int arcompact_handle05_0c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_0c> (%08x)", op); return 4; } -int arcompact_handle05_0d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_0d> (%08x)", op); return 4; } -int arcompact_handle05_0e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_0e> (%08x)", op); return 4; } -int arcompact_handle05_0f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_0f> (%08x)", op); return 4; } -int arcompact_handle05_10_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_10> (%08x)", op); return 4; } -int arcompact_handle05_11_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_11> (%08x)", op); return 4; } -int arcompact_handle05_12_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_12> (%08x)", op); return 4; } -int arcompact_handle05_13_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_13> (%08x)", op); return 4; } -int arcompact_handle05_14_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_14> (%08x)", op); return 4; } -int arcompact_handle05_15_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_15> (%08x)", op); return 4; } -int arcompact_handle05_16_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_16> (%08x)", op); return 4; } -int arcompact_handle05_17_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_17> (%08x)", op); return 4; } -int arcompact_handle05_18_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_18> (%08x)", op); return 4; } -int arcompact_handle05_19_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_19> (%08x)", op); return 4; } -int arcompact_handle05_1a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_1a> (%08x)", op); return 4; } -int arcompact_handle05_1b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_1b> (%08x)", op); return 4; } -int arcompact_handle05_1c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_1c> (%08x)", op); return 4; } -int arcompact_handle05_1d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_1d> (%08x)", op); return 4; } -int arcompact_handle05_1e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_1e> (%08x)", op); return 4; } -int arcompact_handle05_1f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_1f> (%08x)", op); return 4; } -int arcompact_handle05_20_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_20> (%08x)", op); return 4; } -int arcompact_handle05_21_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_21> (%08x)", op); return 4; } -int arcompact_handle05_22_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_22> (%08x)", op); return 4; } -int arcompact_handle05_23_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_23> (%08x)", op); return 4; } -int arcompact_handle05_24_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_24> (%08x)", op); return 4; } -int arcompact_handle05_25_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_25> (%08x)", op); return 4; } -int arcompact_handle05_26_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_26> (%08x)", op); return 4; } -int arcompact_handle05_27_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_27> (%08x)", op); return 4; } - -int arcompact_handle05_2a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2a> (%08x)", op); return 4; } -int arcompact_handle05_2b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2b> (%08x)", op); return 4; } -int arcompact_handle05_2c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2c> (%08x)", op); return 4; } -int arcompact_handle05_2d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2d> (%08x)", op); return 4; } -int arcompact_handle05_2e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2e> (%08x)", op); return 4; } - -int arcompact_handle05_30_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_30> (%08x)", op); return 4; } -int arcompact_handle05_31_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_31> (%08x)", op); return 4; } -int arcompact_handle05_32_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_32> (%08x)", op); return 4; } -int arcompact_handle05_33_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_33> (%08x)", op); return 4; } -int arcompact_handle05_34_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_34> (%08x)", op); return 4; } -int arcompact_handle05_35_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_35> (%08x)", op); return 4; } -int arcompact_handle05_36_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_36> (%08x)", op); return 4; } -int arcompact_handle05_37_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_37> (%08x)", op); return 4; } -int arcompact_handle05_38_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_38> (%08x)", op); return 4; } -int arcompact_handle05_39_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_39> (%08x)", op); return 4; } -int arcompact_handle05_3a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_3a> (%08x)", op); return 4; } -int arcompact_handle05_3b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_3b> (%08x)", op); return 4; } -int arcompact_handle05_3c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_3c> (%08x)", op); return 4; } -int arcompact_handle05_3d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_3d> (%08x)", op); return 4; } -int arcompact_handle05_3e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_3e> (%08x)", op); return 4; } -int arcompact_handle05_3f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_3f> (%08x)", op); return 4; } - -int arcompact_handle0f_00_04_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x0f_00_00> (%08x)", op); return 2; } -int arcompact_handle0f_00_05_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x0f_00_00> (%08x)", op); return 2; } -int arcompact_handle0f_00_07_02_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x0f_00_07_02> (%08x)", op); return 2; } -int arcompact_handle0f_00_07_03_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x0f_00_07_03> (%08x)", op); return 2; } -int arcompact_handle0f_01_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x0f_01> (%08x)", op); return 2; } -int arcompact_handle0f_03_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x0f_03> (%08x)", op); return 2; } -int arcompact_handle0f_08_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x0f_08> (%08x)", op); return 2; } -int arcompact_handle0f_09_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x0f_09> (%08x)", op); return 2; } -int arcompact_handle0f_0a_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x0f_0a> (%08x)", op); return 2; } -int arcompact_handle0f_17_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x0f_17> (%08x)", op); return 2; } - -int arcompact_handle18_05_02_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_05_02> (%04x)", op); return 2; } -int arcompact_handle18_05_03_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_05_03> (%04x)", op); return 2; } -int arcompact_handle18_05_04_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_05_04> (%04x)", op); return 2; } -int arcompact_handle18_05_05_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_05_05> (%04x)", op); return 2; } -int arcompact_handle18_05_06_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_05_06> (%04x)", op); return 2; } -int arcompact_handle18_05_07_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_05_07> (%04x)", op); return 2; } -int arcompact_handle18_06_00_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_00> (%04x)", op); return 2; } -int arcompact_handle18_06_02_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_02> (%04x)", op); return 2; } -int arcompact_handle18_06_03_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_03> (%04x)", op); return 2; } -int arcompact_handle18_06_04_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_04> (%04x)", op); return 2; } -int arcompact_handle18_06_05_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_05> (%04x)", op); return 2; } -int arcompact_handle18_06_06_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_06> (%04x)", op); return 2; } -int arcompact_handle18_06_07_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_07> (%04x)", op); return 2; } -int arcompact_handle18_06_08_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_08> (%04x)", op); return 2; } -int arcompact_handle18_06_09_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_09> (%04x)", op); return 2; } -int arcompact_handle18_06_0a_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_0a> (%04x)", op); return 2; } -int arcompact_handle18_06_0b_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_0b> (%04x)", op); return 2; } -int arcompact_handle18_06_0c_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_0c> (%04x)", op); return 2; } -int arcompact_handle18_06_0d_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_0d> (%04x)", op); return 2; } -int arcompact_handle18_06_0e_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_0e> (%04x)", op); return 2; } -int arcompact_handle18_06_0f_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_0f> (%04x)", op); return 2; } -int arcompact_handle18_06_10_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_10> (%04x)", op); return 2; } -int arcompact_handle18_06_12_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_12> (%04x)", op); return 2; } -int arcompact_handle18_06_13_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_13> (%04x)", op); return 2; } -int arcompact_handle18_06_14_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_14> (%04x)", op); return 2; } -int arcompact_handle18_06_15_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_15> (%04x)", op); return 2; } -int arcompact_handle18_06_16_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_16> (%04x)", op); return 2; } -int arcompact_handle18_06_17_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_17> (%04x)", op); return 2; } -int arcompact_handle18_06_18_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_18> (%04x)", op); return 2; } -int arcompact_handle18_06_19_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_19> (%04x)", op); return 2; } -int arcompact_handle18_06_1a_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_1a> (%04x)", op); return 2; } -int arcompact_handle18_06_1b_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_1b> (%04x)", op); return 2; } -int arcompact_handle18_06_1c_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_1c> (%04x)", op); return 2; } -int arcompact_handle18_06_1d_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_1d> (%04x)", op); return 2; } -int arcompact_handle18_06_1e_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_1e> (%04x)", op); return 2; } -int arcompact_handle18_06_1f_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_1f> (%04x)", op); return 2; } -int arcompact_handle18_07_00_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_00> (%04x)", op); return 2; } -int arcompact_handle18_07_02_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_02> (%04x)", op); return 2; } -int arcompact_handle18_07_03_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_03> (%04x)", op); return 2; } -int arcompact_handle18_07_04_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_04> (%04x)", op); return 2; } -int arcompact_handle18_07_05_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_05> (%04x)", op); return 2; } -int arcompact_handle18_07_06_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_06> (%04x)", op); return 2; } -int arcompact_handle18_07_07_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_07> (%04x)", op); return 2; } -int arcompact_handle18_07_08_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_08> (%04x)", op); return 2; } -int arcompact_handle18_07_09_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_09> (%04x)", op); return 2; } -int arcompact_handle18_07_0a_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_0a> (%04x)", op); return 2; } -int arcompact_handle18_07_0b_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_0b> (%04x)", op); return 2; } -int arcompact_handle18_07_0c_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_0c> (%04x)", op); return 2; } -int arcompact_handle18_07_0d_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_0d> (%04x)", op); return 2; } -int arcompact_handle18_07_0e_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_0e> (%04x)", op); return 2; } -int arcompact_handle18_07_0f_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_0f> (%04x)", op); return 2; } -int arcompact_handle18_07_10_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_10> (%04x)", op); return 2; } -int arcompact_handle18_07_12_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_12> (%04x)", op); return 2; } -int arcompact_handle18_07_13_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_13> (%04x)", op); return 2; } -int arcompact_handle18_07_14_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_14> (%04x)", op); return 2; } -int arcompact_handle18_07_15_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_15> (%04x)", op); return 2; } -int arcompact_handle18_07_16_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_16> (%04x)", op); return 2; } -int arcompact_handle18_07_17_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_17> (%04x)", op); return 2; } -int arcompact_handle18_07_18_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_18> (%04x)", op); return 2; } -int arcompact_handle18_07_19_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_19> (%04x)", op); return 2; } -int arcompact_handle18_07_1a_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_1a> (%04x)", op); return 2; } -int arcompact_handle18_07_1b_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_1b> (%04x)", op); return 2; } -int arcompact_handle18_07_1c_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_1c> (%04x)", op); return 2; } -int arcompact_handle18_07_1d_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_1d> (%04x)", op); return 2; } -int arcompact_handle18_07_1e_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_1e> (%04x)", op); return 2; } -int arcompact_handle18_07_1f_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_1f> (%04x)", op); return 2; } +int arcompact_disassembler::handle01_01_00_06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 01_01_00_06> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle01_01_00_07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 01_01_00_07> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle01_01_00_08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 01_01_00_08> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle01_01_00_09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 01_01_00_09> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle01_01_00_0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 01_01_00_0a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle01_01_00_0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 01_01_00_0b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle01_01_00_0c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 01_01_00_0c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle01_01_00_0d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 01_01_00_0d> (%08x)", op); + return 4; +} + + +int arcompact_disassembler::handle01_01_01_06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 01_01_01_06> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle01_01_01_07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 01_01_01_07> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle01_01_01_08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 01_01_01_08> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle01_01_01_09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 01_01_01_09> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle01_01_01_0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 01_01_01_0a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle01_01_01_0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 01_01_01_0b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle01_01_01_0c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 01_01_01_0c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle01_01_01_0d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 01_01_01_0d> (%08x)", op); + return 4; +} + + + +int arcompact_disassembler::handle04_1e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_1e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_1f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_1f> (%08x)", op); + return 4; +} + + +int arcompact_disassembler::handle04_24_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_24> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_25_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_25> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_26_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_26> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_27_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_27> (%08x)", op); + return 4; +} + + +int arcompact_disassembler::handle04_2c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2e> (%08x)", op); + return 4; +} + + +int arcompact_disassembler::handle04_2f_0d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_0d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_0e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_0e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_0f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_0f> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_10_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_10> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_11_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_11> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_12_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_12> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_13_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_13> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_14_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_14> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_15_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_15> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_16_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_16> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_17_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_17> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_18_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_18> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_19_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_19> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_1a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_1a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_1b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_1b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_1c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_1c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_1d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_1d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_1e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_1e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_1f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_1f> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_20_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_20> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_21_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_21> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_22_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_22> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_23_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_23> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_24_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_24> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_25_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_25> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_26_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_26> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_27_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_27> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_28_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_28> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_29_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_29> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_2a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_2a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_2b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_2b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_2c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_2c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_2d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_2d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_2e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_2e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_2f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_2f> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_30_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_30> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_31_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_31> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_32_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_32> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_33_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_33> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_34_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_34> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_35_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_35> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_36_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_36> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_37_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_37> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_38_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_38> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_39_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_39> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3e> (%08x)", op); + return 4; +} + + + + +int arcompact_disassembler::handle05_2f_09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_09> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_0a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_0b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_0c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_0c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_0d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_0d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_0e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_0e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_0f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_0f> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_10_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_10> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_11_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_11> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_12_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_12> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_13_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_13> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_14_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_14> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_15_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_15> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_16_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_16> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_17_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_17> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_18_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_18> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_19_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_19> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_1a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_1a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_1b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_1b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_1c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_1c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_1d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_1d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_1e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_1e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_1f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_1f> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_20_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_20> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_21_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_21> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_22_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_22> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_23_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_23> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_24_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_24> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_25_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_25> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_26_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_26> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_27_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_27> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_28_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_28> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_29_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_29> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_2a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_2a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_2b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_2b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_2c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_2c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_2d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_2d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_2e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_2e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_2f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_2f> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_30_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_30> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_31_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_31> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_32_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_32> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_33_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_33> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_34_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_34> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_35_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_35> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_36_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_36> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_37_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_37> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_38_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_38> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_39_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_39> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3e> (%08x)", op); + return 4; +} + + + +int arcompact_disassembler::handle04_2f_3f_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_00> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_06> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_07> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_08> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_09> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_0a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_0b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_0c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_0c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_0d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_0d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_0e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_0e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_0f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_0f> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_10_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_10> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_11_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_11> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_12_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_12> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_13_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_13> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_14_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_14> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_15_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_15> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_16_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_16> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_17_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_17> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_18_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_18> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_19_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_19> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_1a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_1a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_1b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_1b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_1c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_1c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_1d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_1d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_1e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_1e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_1f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_1f> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_20_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_20> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_21_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_21> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_22_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_22> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_23_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_23> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_24_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_24> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_25_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_25> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_26_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_26> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_27_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_27> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_28_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_28> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_29_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_29> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_2a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_2a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_2b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_2b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_2c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_2c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_2d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_2d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_2e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_2e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_2f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_2f> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_30_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_30> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_31_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_31> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_32_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_32> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_33_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_33> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_34_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_34> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_35_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_35> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_36_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_36> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_37_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_37> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_38_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_38> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_39_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_39> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_3a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_3a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_3b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_3b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_3c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_3c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_3d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_3d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_3e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_3e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_3f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_3f> (%08x)", op); + return 4; +} + + +int arcompact_disassembler::handle05_2f_3f_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_00> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_01> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_02> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_03> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_04> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_05> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_06> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_07> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_08> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_09> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_0a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_0b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_0c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_0c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_0d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_0d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_0e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_0e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_0f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_0f> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_10_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_10> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_11_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_11> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_12_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_12> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_13_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_13> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_14_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_14> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_15_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_15> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_16_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_16> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_17_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_17> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_18_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_18> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_19_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_19> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_1a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_1a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_1b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_1b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_1c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_1c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_1d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_1d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_1e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_1e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_1f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_1f> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_20_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_20> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_21_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_21> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_22_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_22> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_23_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_23> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_24_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_24> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_25_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_25> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_26_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_26> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_27_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_27> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_28_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_28> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_29_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_29> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_2a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_2a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_2b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_2b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_2c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_2c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_2d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_2d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_2e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_2e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_2f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_2f> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_30_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_30> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_31_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_31> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_32_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_32> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_33_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_33> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_34_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_34> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_35_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_35> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_36_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_36> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_37_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_37> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_38_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_38> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_39_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_39> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_3a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_3a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_3b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_3b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_3c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_3c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_3d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_3d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_3e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_3e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_3f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_3f> (%08x)", op); + return 4; +} + + + + + +int arcompact_disassembler::handle04_38_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_38> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_39_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_39> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_3a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_3a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_3b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_3b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_3c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_3c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_3d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_3d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_3e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_3e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_3f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_3f> (%08x)", op); + return 4; +} + + + +int arcompact_disassembler::handle05_09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_09> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_0c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_0c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_0d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_0d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_0e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_0e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_0f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_0f> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_10_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_10> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_11_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_11> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_12_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_12> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_13_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_13> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_14_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_14> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_15_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_15> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_16_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_16> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_17_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_17> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_18_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_18> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_19_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_19> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_1a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_1a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_1b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_1b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_1c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_1c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_1d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_1d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_1e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_1e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_1f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_1f> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_20_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_20> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_21_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_21> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_22_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_22> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_23_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_23> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_24_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_24> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_25_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_25> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_26_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_26> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_27_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_27> (%08x)", op); + return 4; +} + + +int arcompact_disassembler::handle05_2a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2e> (%08x)", op); + return 4; +} + + +int arcompact_disassembler::handle05_30_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_30> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_31_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_31> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_32_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_32> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_33_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_33> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_34_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_34> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_35_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_35> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_36_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_36> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_37_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_37> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_38_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_38> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_39_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_39> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_3a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_3a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_3b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_3b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_3c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_3c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_3d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_3d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_3e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_3e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_3f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_3f> (%08x)", op); + return 4; +} + + +int arcompact_disassembler::handle0f_00_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x0f_00_00> (%08x)", op); + return 2; +} + +int arcompact_disassembler::handle0f_00_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x0f_00_00> (%08x)", op); + return 2; +} + +int arcompact_disassembler::handle0f_00_07_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x0f_00_07_02> (%08x)", op); + return 2; +} + +int arcompact_disassembler::handle0f_00_07_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x0f_00_07_03> (%08x)", op); + return 2; +} + +int arcompact_disassembler::handle0f_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x0f_01> (%08x)", op); + return 2; +} + +int arcompact_disassembler::handle0f_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x0f_03> (%08x)", op); + return 2; +} + +int arcompact_disassembler::handle0f_08_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x0f_08> (%08x)", op); + return 2; +} + +int arcompact_disassembler::handle0f_09_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x0f_09> (%08x)", op); + return 2; +} + +int arcompact_disassembler::handle0f_0a_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x0f_0a> (%08x)", op); + return 2; +} + +int arcompact_disassembler::handle0f_17_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x0f_17> (%08x)", op); + return 2; +} + + +int arcompact_disassembler::handle18_05_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_05_02> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_05_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_05_03> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_05_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_05_04> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_05_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_05_05> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_05_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_05_06> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_05_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_05_07> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_00> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_02> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_03> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_04> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_05> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_06> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_07> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_08_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_08> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_09_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_09> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_0a_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_0a> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_0b_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_0b> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_0c_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_0c> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_0d_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_0d> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_0e_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_0e> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_0f_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_0f> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_10_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_10> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_12_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_12> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_13_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_13> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_14_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_14> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_15_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_15> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_16_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_16> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_17_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_17> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_18_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_18> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_19_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_19> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_1a_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_1a> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_1b_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_1b> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_1c_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_1c> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_1d_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_1d> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_1e_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_1e> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_1f_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_1f> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_00> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_02> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_03> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_04> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_05> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_06> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_07> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_08_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_08> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_09_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_09> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_0a_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_0a> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_0b_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_0b> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_0c_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_0c> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_0d_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_0d> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_0e_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_0e> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_0f_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_0f> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_10_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_10> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_12_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_12> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_13_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_13> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_14_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_14> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_15_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_15> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_16_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_16> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_17_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_17> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_18_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_18> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_19_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_19> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_1a_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_1a> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_1b_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_1b> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_1c_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_1c> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_1d_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_1d> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_1e_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_1e> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_1f_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_1f> (%04x)", op); + return 2; +} diff --git a/src/devices/cpu/arcompact/arcompactdasm_ops.h b/src/devices/cpu/arcompact/arcompactdasm_ops.h deleted file mode 100644 index 84b79e6e1e7..00000000000 --- a/src/devices/cpu/arcompact/arcompactdasm_ops.h +++ /dev/null @@ -1,642 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:David Haywood - -/************************************************************************************************************************************ -* * -* individual opcode handlers (disassembly) * -* * -************************************************************************************************************************************/ - -#include "arcompact_common.h" - -#define DASM_OPS_16 std::ostream &stream, offs_t pc, uint16_t op, const uint8_t* oprom -#define DASM_OPS_32 std::ostream &stream, offs_t pc, uint32_t op, const uint8_t* oprom -#define DASM_PARAMS stream, pc, op, oprom - -#define LIMM_REG 62 - -#define GET_LIMM_32 \ - limm = oprom[6] | (oprom[7] << 8); \ - limm |= (oprom[4] << 16) | (oprom[5] << 24); - -int arcompact_handle00_00_dasm(DASM_OPS_32); -int arcompact_handle00_01_dasm(DASM_OPS_32); -int arcompact_handle01_00_00dasm(DASM_OPS_32); -int arcompact_handle01_00_01dasm(DASM_OPS_32); -int arcompact_handle01_01_00_00_dasm(DASM_OPS_32); -int arcompact_handle01_01_00_01_dasm(DASM_OPS_32); -int arcompact_handle01_01_00_02_dasm(DASM_OPS_32); -int arcompact_handle01_01_00_03_dasm(DASM_OPS_32); -int arcompact_handle01_01_00_04_dasm(DASM_OPS_32); -int arcompact_handle01_01_00_05_dasm(DASM_OPS_32); -int arcompact_handle01_01_00_0e_dasm(DASM_OPS_32); -int arcompact_handle01_01_00_0f_dasm(DASM_OPS_32); -int arcompact_handle01_01_01_00_dasm(DASM_OPS_32); -int arcompact_handle01_01_01_01_dasm(DASM_OPS_32); -int arcompact_handle01_01_01_02_dasm(DASM_OPS_32); -int arcompact_handle01_01_01_03_dasm(DASM_OPS_32); -int arcompact_handle01_01_01_04_dasm(DASM_OPS_32); -int arcompact_handle01_01_01_05_dasm(DASM_OPS_32); -int arcompact_handle01_01_01_0e_dasm(DASM_OPS_32); -int arcompact_handle01_01_01_0f_dasm(DASM_OPS_32); -int arcompact_handle02_dasm(DASM_OPS_32); -int arcompact_handle03_dasm(DASM_OPS_32); -int arcompact_handle04_00_dasm(DASM_OPS_32); -int arcompact_handle04_01_dasm(DASM_OPS_32); -int arcompact_handle04_02_dasm(DASM_OPS_32); -int arcompact_handle04_03_dasm(DASM_OPS_32); -int arcompact_handle04_04_dasm(DASM_OPS_32); -int arcompact_handle04_05_dasm(DASM_OPS_32); -int arcompact_handle04_06_dasm(DASM_OPS_32); -int arcompact_handle04_07_dasm(DASM_OPS_32); -int arcompact_handle04_08_dasm(DASM_OPS_32); -int arcompact_handle04_09_dasm(DASM_OPS_32); -int arcompact_handle04_0a_dasm(DASM_OPS_32); -int arcompact_handle04_0b_dasm(DASM_OPS_32); -int arcompact_handle04_0c_dasm(DASM_OPS_32); -int arcompact_handle04_0d_dasm(DASM_OPS_32); -int arcompact_handle04_0e_dasm(DASM_OPS_32); -int arcompact_handle04_0f_dasm(DASM_OPS_32); -int arcompact_handle04_10_dasm(DASM_OPS_32); -int arcompact_handle04_11_dasm(DASM_OPS_32); -int arcompact_handle04_12_dasm(DASM_OPS_32); -int arcompact_handle04_13_dasm(DASM_OPS_32); -int arcompact_handle04_14_dasm(DASM_OPS_32); -int arcompact_handle04_15_dasm(DASM_OPS_32); -int arcompact_handle04_16_dasm(DASM_OPS_32); -int arcompact_handle04_17_dasm(DASM_OPS_32); -int arcompact_handle04_18_dasm(DASM_OPS_32); -int arcompact_handle04_19_dasm(DASM_OPS_32); -int arcompact_handle04_1a_dasm(DASM_OPS_32); -int arcompact_handle04_1b_dasm(DASM_OPS_32); -int arcompact_handle04_1c_dasm(DASM_OPS_32); -int arcompact_handle04_1d_dasm(DASM_OPS_32); -int arcompact_handle04_20_dasm(DASM_OPS_32); -int arcompact_handle04_21_dasm(DASM_OPS_32); -int arcompact_handle04_22_dasm(DASM_OPS_32); -int arcompact_handle04_23_dasm(DASM_OPS_32); -int arcompact_handle04_28_dasm(DASM_OPS_32); -int arcompact_handle04_29_dasm(DASM_OPS_32); -int arcompact_handle04_2a_dasm(DASM_OPS_32); -int arcompact_handle04_2b_dasm(DASM_OPS_32); -int arcompact_handle04_2f_00_dasm(DASM_OPS_32); -int arcompact_handle04_2f_01_dasm(DASM_OPS_32); -int arcompact_handle04_2f_02_dasm(DASM_OPS_32); -int arcompact_handle04_2f_03_dasm(DASM_OPS_32); -int arcompact_handle04_2f_04_dasm(DASM_OPS_32); -int arcompact_handle04_2f_05_dasm(DASM_OPS_32); -int arcompact_handle04_2f_06_dasm(DASM_OPS_32); -int arcompact_handle04_2f_07_dasm(DASM_OPS_32); -int arcompact_handle04_2f_08_dasm(DASM_OPS_32); -int arcompact_handle04_2f_09_dasm(DASM_OPS_32); -int arcompact_handle04_2f_0a_dasm(DASM_OPS_32); -int arcompact_handle04_2f_0b_dasm(DASM_OPS_32); -int arcompact_handle04_2f_0c_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_01_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_02_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_03_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_04_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_05_dasm(DASM_OPS_32); -int arcompact_handle04_30_dasm(DASM_OPS_32); -int arcompact_handle04_31_dasm(DASM_OPS_32); -int arcompact_handle04_32_dasm(DASM_OPS_32); -int arcompact_handle04_33_dasm(DASM_OPS_32); -int arcompact_handle04_34_dasm(DASM_OPS_32); -int arcompact_handle04_35_dasm(DASM_OPS_32); -int arcompact_handle04_36_dasm(DASM_OPS_32); -int arcompact_handle04_37_dasm(DASM_OPS_32); -int arcompact_handle05_00_dasm(DASM_OPS_32); -int arcompact_handle05_01_dasm(DASM_OPS_32); -int arcompact_handle05_02_dasm(DASM_OPS_32); -int arcompact_handle05_03_dasm(DASM_OPS_32); -int arcompact_handle05_04_dasm(DASM_OPS_32); -int arcompact_handle05_05_dasm(DASM_OPS_32); -int arcompact_handle05_06_dasm(DASM_OPS_32); -int arcompact_handle05_07_dasm(DASM_OPS_32); -int arcompact_handle05_08_dasm(DASM_OPS_32); -int arcompact_handle05_0a_dasm(DASM_OPS_32); -int arcompact_handle05_0b_dasm(DASM_OPS_32); -int arcompact_handle05_28_dasm(DASM_OPS_32); -int arcompact_handle05_29_dasm(DASM_OPS_32); - -int arcompact_handle06_dasm(DASM_OPS_32); -int arcompact_handle07_dasm(DASM_OPS_32); -int arcompact_handle08_dasm(DASM_OPS_32); -int arcompact_handle09_dasm(DASM_OPS_32); -int arcompact_handle0a_dasm(DASM_OPS_32); -int arcompact_handle0b_dasm(DASM_OPS_32); - -int arcompact_handle0c_00_dasm(DASM_OPS_16); -int arcompact_handle0c_01_dasm(DASM_OPS_16); -int arcompact_handle0c_02_dasm(DASM_OPS_16); -int arcompact_handle0c_03_dasm(DASM_OPS_16); -int arcompact_handle0d_00_dasm(DASM_OPS_16); -int arcompact_handle0d_01_dasm(DASM_OPS_16); -int arcompact_handle0d_02_dasm(DASM_OPS_16); -int arcompact_handle0d_03_dasm(DASM_OPS_16); -int arcompact_handle0e_00_dasm(DASM_OPS_16); -int arcompact_handle0e_01_dasm(DASM_OPS_16); -int arcompact_handle0e_02_dasm(DASM_OPS_16); -int arcompact_handle0e_03_dasm(DASM_OPS_16); -int arcompact_handle0f_00_00_dasm(DASM_OPS_16); -int arcompact_handle0f_00_01_dasm(DASM_OPS_16); -int arcompact_handle0f_00_02_dasm(DASM_OPS_16); -int arcompact_handle0f_00_03_dasm(DASM_OPS_16); -int arcompact_handle0f_00_06_dasm(DASM_OPS_16); -int arcompact_handle0f_00_07_00_dasm(DASM_OPS_16); -int arcompact_handle0f_00_07_01_dasm(DASM_OPS_16); -int arcompact_handle0f_00_07_04_dasm(DASM_OPS_16); -int arcompact_handle0f_00_07_05_dasm(DASM_OPS_16); -int arcompact_handle0f_00_07_06_dasm(DASM_OPS_16); -int arcompact_handle0f_00_07_07_dasm(DASM_OPS_16); -int arcompact_handle0f_02_dasm(DASM_OPS_16); -int arcompact_handle0f_04_dasm(DASM_OPS_16); -int arcompact_handle0f_05_dasm(DASM_OPS_16); -int arcompact_handle0f_06_dasm(DASM_OPS_16); -int arcompact_handle0f_07_dasm(DASM_OPS_16); -int arcompact_handle0f_0b_dasm(DASM_OPS_16); -int arcompact_handle0f_0c_dasm(DASM_OPS_16); -int arcompact_handle0f_0d_dasm(DASM_OPS_16); -int arcompact_handle0f_0e_dasm(DASM_OPS_16); -int arcompact_handle0f_0f_dasm(DASM_OPS_16); -int arcompact_handle0f_10_dasm(DASM_OPS_16); -int arcompact_handle0f_11_dasm(DASM_OPS_16); -int arcompact_handle0f_12_dasm(DASM_OPS_16); -int arcompact_handle0f_13_dasm(DASM_OPS_16); -int arcompact_handle0f_14_dasm(DASM_OPS_16); -int arcompact_handle0f_15_dasm(DASM_OPS_16); -int arcompact_handle0f_16_dasm(DASM_OPS_16); -int arcompact_handle0f_18_dasm(DASM_OPS_16); -int arcompact_handle0f_19_dasm(DASM_OPS_16); -int arcompact_handle0f_1a_dasm(DASM_OPS_16); -int arcompact_handle0f_1b_dasm(DASM_OPS_16); -int arcompact_handle0f_1c_dasm(DASM_OPS_16); -int arcompact_handle0f_1d_dasm(DASM_OPS_16); -int arcompact_handle0f_1e_dasm(DASM_OPS_16); -int arcompact_handle0f_1f_dasm(DASM_OPS_16); -int arcompact_handle10_dasm(DASM_OPS_16); -int arcompact_handle11_dasm(DASM_OPS_16); -int arcompact_handle12_dasm(DASM_OPS_16); -int arcompact_handle13_dasm(DASM_OPS_16); -int arcompact_handle14_dasm(DASM_OPS_16); -int arcompact_handle15_dasm(DASM_OPS_16); -int arcompact_handle16_dasm(DASM_OPS_16); -int arcompact_handle17_00_dasm(DASM_OPS_16); -int arcompact_handle17_01_dasm(DASM_OPS_16); -int arcompact_handle17_02_dasm(DASM_OPS_16); -int arcompact_handle17_03_dasm(DASM_OPS_16); -int arcompact_handle17_04_dasm(DASM_OPS_16); -int arcompact_handle17_05_dasm(DASM_OPS_16); -int arcompact_handle17_06_dasm(DASM_OPS_16); -int arcompact_handle17_07_dasm(DASM_OPS_16); -int arcompact_handle18_00_dasm(DASM_OPS_16); -int arcompact_handle18_01_dasm(DASM_OPS_16); -int arcompact_handle18_02_dasm(DASM_OPS_16); -int arcompact_handle18_03_dasm(DASM_OPS_16); -int arcompact_handle18_04_dasm(DASM_OPS_16); -int arcompact_handle18_05_00_dasm(DASM_OPS_16); -int arcompact_handle18_05_01_dasm(DASM_OPS_16); -int arcompact_handle18_06_01_dasm(DASM_OPS_16); -int arcompact_handle18_06_11_dasm(DASM_OPS_16); -int arcompact_handle18_07_01_dasm(DASM_OPS_16); -int arcompact_handle18_07_11_dasm(DASM_OPS_16); -int arcompact_handle19_00_dasm(DASM_OPS_16); -int arcompact_handle19_01_dasm(DASM_OPS_16); -int arcompact_handle19_02_dasm(DASM_OPS_16); -int arcompact_handle19_03_dasm(DASM_OPS_16); -int arcompact_handle1a_dasm(DASM_OPS_16); -int arcompact_handle1b_dasm(DASM_OPS_16); -int arcompact_handle1c_00_dasm(DASM_OPS_16); -int arcompact_handle1c_01_dasm(DASM_OPS_16); -int arcompact_handle1d_00_dasm(DASM_OPS_16); -int arcompact_handle1d_01_dasm(DASM_OPS_16); -int arcompact_handle1e_00_dasm(DASM_OPS_16); -int arcompact_handle1e_01_dasm(DASM_OPS_16); -int arcompact_handle1e_02_dasm(DASM_OPS_16); -int arcompact_handle1e_03_00_dasm(DASM_OPS_16); -int arcompact_handle1e_03_01_dasm(DASM_OPS_16); -int arcompact_handle1e_03_02_dasm(DASM_OPS_16); -int arcompact_handle1e_03_03_dasm(DASM_OPS_16); -int arcompact_handle1e_03_04_dasm(DASM_OPS_16); -int arcompact_handle1e_03_05_dasm(DASM_OPS_16); -int arcompact_handle1e_03_06_dasm(DASM_OPS_16); -int arcompact_handle1e_03_07_dasm(DASM_OPS_16); -int arcompact_handle1f_dasm(DASM_OPS_16); - -/************************************************************************************************************************************ -* * -* illegal opcode handlers (disassembly) * -* * -************************************************************************************************************************************/ - -int arcompact_handle01_01_00_06_dasm(DASM_OPS_32); -int arcompact_handle01_01_00_07_dasm(DASM_OPS_32); -int arcompact_handle01_01_00_08_dasm(DASM_OPS_32); -int arcompact_handle01_01_00_09_dasm(DASM_OPS_32); -int arcompact_handle01_01_00_0a_dasm(DASM_OPS_32); -int arcompact_handle01_01_00_0b_dasm(DASM_OPS_32); -int arcompact_handle01_01_00_0c_dasm(DASM_OPS_32); -int arcompact_handle01_01_00_0d_dasm(DASM_OPS_32); - -int arcompact_handle01_01_01_06_dasm(DASM_OPS_32); -int arcompact_handle01_01_01_07_dasm(DASM_OPS_32); -int arcompact_handle01_01_01_08_dasm(DASM_OPS_32); -int arcompact_handle01_01_01_09_dasm(DASM_OPS_32); -int arcompact_handle01_01_01_0a_dasm(DASM_OPS_32); -int arcompact_handle01_01_01_0b_dasm(DASM_OPS_32); -int arcompact_handle01_01_01_0c_dasm(DASM_OPS_32); -int arcompact_handle01_01_01_0d_dasm(DASM_OPS_32); - - -int arcompact_handle04_1e_dasm(DASM_OPS_32); -int arcompact_handle04_1f_dasm(DASM_OPS_32); - -int arcompact_handle04_24_dasm(DASM_OPS_32); -int arcompact_handle04_25_dasm(DASM_OPS_32); -int arcompact_handle04_26_dasm(DASM_OPS_32); -int arcompact_handle04_27_dasm(DASM_OPS_32); - -int arcompact_handle04_2c_dasm(DASM_OPS_32); -int arcompact_handle04_2d_dasm(DASM_OPS_32); -int arcompact_handle04_2e_dasm(DASM_OPS_32); - -int arcompact_handle04_2f_0d_dasm(DASM_OPS_32); -int arcompact_handle04_2f_0e_dasm(DASM_OPS_32); -int arcompact_handle04_2f_0f_dasm(DASM_OPS_32); -int arcompact_handle04_2f_10_dasm(DASM_OPS_32); -int arcompact_handle04_2f_11_dasm(DASM_OPS_32); -int arcompact_handle04_2f_12_dasm(DASM_OPS_32); -int arcompact_handle04_2f_13_dasm(DASM_OPS_32); -int arcompact_handle04_2f_14_dasm(DASM_OPS_32); -int arcompact_handle04_2f_15_dasm(DASM_OPS_32); -int arcompact_handle04_2f_16_dasm(DASM_OPS_32); -int arcompact_handle04_2f_17_dasm(DASM_OPS_32); -int arcompact_handle04_2f_18_dasm(DASM_OPS_32); -int arcompact_handle04_2f_19_dasm(DASM_OPS_32); -int arcompact_handle04_2f_1a_dasm(DASM_OPS_32); -int arcompact_handle04_2f_1b_dasm(DASM_OPS_32); -int arcompact_handle04_2f_1c_dasm(DASM_OPS_32); -int arcompact_handle04_2f_1d_dasm(DASM_OPS_32); -int arcompact_handle04_2f_1e_dasm(DASM_OPS_32); -int arcompact_handle04_2f_1f_dasm(DASM_OPS_32); -int arcompact_handle04_2f_20_dasm(DASM_OPS_32); -int arcompact_handle04_2f_21_dasm(DASM_OPS_32); -int arcompact_handle04_2f_22_dasm(DASM_OPS_32); -int arcompact_handle04_2f_23_dasm(DASM_OPS_32); -int arcompact_handle04_2f_24_dasm(DASM_OPS_32); -int arcompact_handle04_2f_25_dasm(DASM_OPS_32); -int arcompact_handle04_2f_26_dasm(DASM_OPS_32); -int arcompact_handle04_2f_27_dasm(DASM_OPS_32); -int arcompact_handle04_2f_28_dasm(DASM_OPS_32); -int arcompact_handle04_2f_29_dasm(DASM_OPS_32); -int arcompact_handle04_2f_2a_dasm(DASM_OPS_32); -int arcompact_handle04_2f_2b_dasm(DASM_OPS_32); -int arcompact_handle04_2f_2c_dasm(DASM_OPS_32); -int arcompact_handle04_2f_2d_dasm(DASM_OPS_32); -int arcompact_handle04_2f_2e_dasm(DASM_OPS_32); -int arcompact_handle04_2f_2f_dasm(DASM_OPS_32); -int arcompact_handle04_2f_30_dasm(DASM_OPS_32); -int arcompact_handle04_2f_31_dasm(DASM_OPS_32); -int arcompact_handle04_2f_32_dasm(DASM_OPS_32); -int arcompact_handle04_2f_33_dasm(DASM_OPS_32); -int arcompact_handle04_2f_34_dasm(DASM_OPS_32); -int arcompact_handle04_2f_35_dasm(DASM_OPS_32); -int arcompact_handle04_2f_36_dasm(DASM_OPS_32); -int arcompact_handle04_2f_37_dasm(DASM_OPS_32); -int arcompact_handle04_2f_38_dasm(DASM_OPS_32); -int arcompact_handle04_2f_39_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3a_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3b_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3c_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3d_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3e_dasm(DASM_OPS_32); - -int arcompact_handle04_2f_3f_00_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_06_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_07_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_08_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_09_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_0a_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_0b_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_0c_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_0d_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_0e_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_0f_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_10_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_11_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_12_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_13_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_14_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_15_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_16_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_17_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_18_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_19_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_1a_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_1b_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_1c_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_1d_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_1e_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_1f_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_20_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_21_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_22_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_23_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_24_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_25_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_26_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_27_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_28_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_29_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_2a_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_2b_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_2c_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_2d_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_2e_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_2f_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_30_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_31_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_32_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_33_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_34_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_35_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_36_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_37_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_38_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_39_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_3a_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_3b_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_3c_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_3d_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_3e_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_3f_dasm(DASM_OPS_32); - -int arcompact_handle05_2f_00_dasm(DASM_OPS_32); -int arcompact_handle05_2f_01_dasm(DASM_OPS_32); -int arcompact_handle05_2f_02_dasm(DASM_OPS_32); -int arcompact_handle05_2f_03_dasm(DASM_OPS_32); -int arcompact_handle05_2f_04_dasm(DASM_OPS_32); -int arcompact_handle05_2f_05_dasm(DASM_OPS_32); -int arcompact_handle05_2f_06_dasm(DASM_OPS_32); -int arcompact_handle05_2f_07_dasm(DASM_OPS_32); -int arcompact_handle05_2f_08_dasm(DASM_OPS_32); -int arcompact_handle05_2f_09_dasm(DASM_OPS_32); -int arcompact_handle05_2f_0a_dasm(DASM_OPS_32); -int arcompact_handle05_2f_0b_dasm(DASM_OPS_32); -int arcompact_handle05_2f_0c_dasm(DASM_OPS_32); -int arcompact_handle05_2f_0d_dasm(DASM_OPS_32); -int arcompact_handle05_2f_0e_dasm(DASM_OPS_32); -int arcompact_handle05_2f_0f_dasm(DASM_OPS_32); -int arcompact_handle05_2f_10_dasm(DASM_OPS_32); -int arcompact_handle05_2f_11_dasm(DASM_OPS_32); -int arcompact_handle05_2f_12_dasm(DASM_OPS_32); -int arcompact_handle05_2f_13_dasm(DASM_OPS_32); -int arcompact_handle05_2f_14_dasm(DASM_OPS_32); -int arcompact_handle05_2f_15_dasm(DASM_OPS_32); -int arcompact_handle05_2f_16_dasm(DASM_OPS_32); -int arcompact_handle05_2f_17_dasm(DASM_OPS_32); -int arcompact_handle05_2f_18_dasm(DASM_OPS_32); -int arcompact_handle05_2f_19_dasm(DASM_OPS_32); -int arcompact_handle05_2f_1a_dasm(DASM_OPS_32); -int arcompact_handle05_2f_1b_dasm(DASM_OPS_32); -int arcompact_handle05_2f_1c_dasm(DASM_OPS_32); -int arcompact_handle05_2f_1d_dasm(DASM_OPS_32); -int arcompact_handle05_2f_1e_dasm(DASM_OPS_32); -int arcompact_handle05_2f_1f_dasm(DASM_OPS_32); -int arcompact_handle05_2f_20_dasm(DASM_OPS_32); -int arcompact_handle05_2f_21_dasm(DASM_OPS_32); -int arcompact_handle05_2f_22_dasm(DASM_OPS_32); -int arcompact_handle05_2f_23_dasm(DASM_OPS_32); -int arcompact_handle05_2f_24_dasm(DASM_OPS_32); -int arcompact_handle05_2f_25_dasm(DASM_OPS_32); -int arcompact_handle05_2f_26_dasm(DASM_OPS_32); -int arcompact_handle05_2f_27_dasm(DASM_OPS_32); -int arcompact_handle05_2f_28_dasm(DASM_OPS_32); -int arcompact_handle05_2f_29_dasm(DASM_OPS_32); -int arcompact_handle05_2f_2a_dasm(DASM_OPS_32); -int arcompact_handle05_2f_2b_dasm(DASM_OPS_32); -int arcompact_handle05_2f_2c_dasm(DASM_OPS_32); -int arcompact_handle05_2f_2d_dasm(DASM_OPS_32); -int arcompact_handle05_2f_2e_dasm(DASM_OPS_32); -int arcompact_handle05_2f_2f_dasm(DASM_OPS_32); -int arcompact_handle05_2f_30_dasm(DASM_OPS_32); -int arcompact_handle05_2f_31_dasm(DASM_OPS_32); -int arcompact_handle05_2f_32_dasm(DASM_OPS_32); -int arcompact_handle05_2f_33_dasm(DASM_OPS_32); -int arcompact_handle05_2f_34_dasm(DASM_OPS_32); -int arcompact_handle05_2f_35_dasm(DASM_OPS_32); -int arcompact_handle05_2f_36_dasm(DASM_OPS_32); -int arcompact_handle05_2f_37_dasm(DASM_OPS_32); -int arcompact_handle05_2f_38_dasm(DASM_OPS_32); -int arcompact_handle05_2f_39_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3a_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3b_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3c_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3d_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3e_dasm(DASM_OPS_32); - -int arcompact_handle05_2f_3f_00_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_01_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_02_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_03_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_04_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_05_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_06_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_07_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_08_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_09_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_0a_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_0b_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_0c_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_0d_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_0e_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_0f_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_10_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_11_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_12_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_13_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_14_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_15_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_16_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_17_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_18_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_19_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_1a_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_1b_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_1c_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_1d_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_1e_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_1f_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_20_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_21_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_22_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_23_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_24_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_25_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_26_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_27_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_28_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_29_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_2a_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_2b_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_2c_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_2d_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_2e_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_2f_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_30_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_31_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_32_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_33_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_34_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_35_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_36_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_37_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_38_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_39_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_3a_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_3b_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_3c_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_3d_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_3e_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_3f_dasm(DASM_OPS_32); - - -int arcompact_handle04_38_dasm(DASM_OPS_32); -int arcompact_handle04_39_dasm(DASM_OPS_32); -int arcompact_handle04_3a_dasm(DASM_OPS_32); -int arcompact_handle04_3b_dasm(DASM_OPS_32); -int arcompact_handle04_3c_dasm(DASM_OPS_32); -int arcompact_handle04_3d_dasm(DASM_OPS_32); -int arcompact_handle04_3e_dasm(DASM_OPS_32); -int arcompact_handle04_3f_dasm(DASM_OPS_32); - -int arcompact_handle05_09_dasm(DASM_OPS_32); -int arcompact_handle05_0c_dasm(DASM_OPS_32); -int arcompact_handle05_0d_dasm(DASM_OPS_32); -int arcompact_handle05_0e_dasm(DASM_OPS_32); -int arcompact_handle05_0f_dasm(DASM_OPS_32); -int arcompact_handle05_10_dasm(DASM_OPS_32); -int arcompact_handle05_11_dasm(DASM_OPS_32); -int arcompact_handle05_12_dasm(DASM_OPS_32); -int arcompact_handle05_13_dasm(DASM_OPS_32); -int arcompact_handle05_14_dasm(DASM_OPS_32); -int arcompact_handle05_15_dasm(DASM_OPS_32); -int arcompact_handle05_16_dasm(DASM_OPS_32); -int arcompact_handle05_17_dasm(DASM_OPS_32); -int arcompact_handle05_18_dasm(DASM_OPS_32); -int arcompact_handle05_19_dasm(DASM_OPS_32); -int arcompact_handle05_1a_dasm(DASM_OPS_32); -int arcompact_handle05_1b_dasm(DASM_OPS_32); -int arcompact_handle05_1c_dasm(DASM_OPS_32); -int arcompact_handle05_1d_dasm(DASM_OPS_32); -int arcompact_handle05_1e_dasm(DASM_OPS_32); -int arcompact_handle05_1f_dasm(DASM_OPS_32); -int arcompact_handle05_20_dasm(DASM_OPS_32); -int arcompact_handle05_21_dasm(DASM_OPS_32); -int arcompact_handle05_22_dasm(DASM_OPS_32); -int arcompact_handle05_23_dasm(DASM_OPS_32); -int arcompact_handle05_24_dasm(DASM_OPS_32); -int arcompact_handle05_25_dasm(DASM_OPS_32); -int arcompact_handle05_26_dasm(DASM_OPS_32); -int arcompact_handle05_27_dasm(DASM_OPS_32); - -int arcompact_handle05_2a_dasm(DASM_OPS_32); -int arcompact_handle05_2b_dasm(DASM_OPS_32); -int arcompact_handle05_2c_dasm(DASM_OPS_32); -int arcompact_handle05_2d_dasm(DASM_OPS_32); -int arcompact_handle05_2e_dasm(DASM_OPS_32); - -int arcompact_handle05_30_dasm(DASM_OPS_32); -int arcompact_handle05_31_dasm(DASM_OPS_32); -int arcompact_handle05_32_dasm(DASM_OPS_32); -int arcompact_handle05_33_dasm(DASM_OPS_32); -int arcompact_handle05_34_dasm(DASM_OPS_32); -int arcompact_handle05_35_dasm(DASM_OPS_32); -int arcompact_handle05_36_dasm(DASM_OPS_32); -int arcompact_handle05_37_dasm(DASM_OPS_32); -int arcompact_handle05_38_dasm(DASM_OPS_32); -int arcompact_handle05_39_dasm(DASM_OPS_32); -int arcompact_handle05_3a_dasm(DASM_OPS_32); -int arcompact_handle05_3b_dasm(DASM_OPS_32); -int arcompact_handle05_3c_dasm(DASM_OPS_32); -int arcompact_handle05_3d_dasm(DASM_OPS_32); -int arcompact_handle05_3e_dasm(DASM_OPS_32); -int arcompact_handle05_3f_dasm(DASM_OPS_32); - -int arcompact_handle0f_00_04_dasm(DASM_OPS_16); -int arcompact_handle0f_00_05_dasm(DASM_OPS_16); -int arcompact_handle0f_00_07_02_dasm(DASM_OPS_16); -int arcompact_handle0f_00_07_03_dasm(DASM_OPS_16); -int arcompact_handle0f_01_dasm(DASM_OPS_16); -int arcompact_handle0f_03_dasm(DASM_OPS_16); -int arcompact_handle0f_08_dasm(DASM_OPS_16); -int arcompact_handle0f_09_dasm(DASM_OPS_16); -int arcompact_handle0f_0a_dasm(DASM_OPS_16); -int arcompact_handle0f_17_dasm(DASM_OPS_16); - -int arcompact_handle18_05_02_dasm(DASM_OPS_16); -int arcompact_handle18_05_03_dasm(DASM_OPS_16); -int arcompact_handle18_05_04_dasm(DASM_OPS_16); -int arcompact_handle18_05_05_dasm(DASM_OPS_16); -int arcompact_handle18_05_06_dasm(DASM_OPS_16); -int arcompact_handle18_05_07_dasm(DASM_OPS_16); -int arcompact_handle18_06_00_dasm(DASM_OPS_16); -int arcompact_handle18_06_02_dasm(DASM_OPS_16); -int arcompact_handle18_06_03_dasm(DASM_OPS_16); -int arcompact_handle18_06_04_dasm(DASM_OPS_16); -int arcompact_handle18_06_05_dasm(DASM_OPS_16); -int arcompact_handle18_06_06_dasm(DASM_OPS_16); -int arcompact_handle18_06_07_dasm(DASM_OPS_16); -int arcompact_handle18_06_08_dasm(DASM_OPS_16); -int arcompact_handle18_06_09_dasm(DASM_OPS_16); -int arcompact_handle18_06_0a_dasm(DASM_OPS_16); -int arcompact_handle18_06_0b_dasm(DASM_OPS_16); -int arcompact_handle18_06_0c_dasm(DASM_OPS_16); -int arcompact_handle18_06_0d_dasm(DASM_OPS_16); -int arcompact_handle18_06_0e_dasm(DASM_OPS_16); -int arcompact_handle18_06_0f_dasm(DASM_OPS_16); -int arcompact_handle18_06_10_dasm(DASM_OPS_16); -int arcompact_handle18_06_12_dasm(DASM_OPS_16); -int arcompact_handle18_06_13_dasm(DASM_OPS_16); -int arcompact_handle18_06_14_dasm(DASM_OPS_16); -int arcompact_handle18_06_15_dasm(DASM_OPS_16); -int arcompact_handle18_06_16_dasm(DASM_OPS_16); -int arcompact_handle18_06_17_dasm(DASM_OPS_16); -int arcompact_handle18_06_18_dasm(DASM_OPS_16); -int arcompact_handle18_06_19_dasm(DASM_OPS_16); -int arcompact_handle18_06_1a_dasm(DASM_OPS_16); -int arcompact_handle18_06_1b_dasm(DASM_OPS_16); -int arcompact_handle18_06_1c_dasm(DASM_OPS_16); -int arcompact_handle18_06_1d_dasm(DASM_OPS_16); -int arcompact_handle18_06_1e_dasm(DASM_OPS_16); -int arcompact_handle18_06_1f_dasm(DASM_OPS_16); -int arcompact_handle18_07_00_dasm(DASM_OPS_16); -int arcompact_handle18_07_02_dasm(DASM_OPS_16); -int arcompact_handle18_07_03_dasm(DASM_OPS_16); -int arcompact_handle18_07_04_dasm(DASM_OPS_16); -int arcompact_handle18_07_05_dasm(DASM_OPS_16); -int arcompact_handle18_07_06_dasm(DASM_OPS_16); -int arcompact_handle18_07_07_dasm(DASM_OPS_16); -int arcompact_handle18_07_08_dasm(DASM_OPS_16); -int arcompact_handle18_07_09_dasm(DASM_OPS_16); -int arcompact_handle18_07_0a_dasm(DASM_OPS_16); -int arcompact_handle18_07_0b_dasm(DASM_OPS_16); -int arcompact_handle18_07_0c_dasm(DASM_OPS_16); -int arcompact_handle18_07_0d_dasm(DASM_OPS_16); -int arcompact_handle18_07_0e_dasm(DASM_OPS_16); -int arcompact_handle18_07_0f_dasm(DASM_OPS_16); -int arcompact_handle18_07_10_dasm(DASM_OPS_16); -int arcompact_handle18_07_12_dasm(DASM_OPS_16); -int arcompact_handle18_07_13_dasm(DASM_OPS_16); -int arcompact_handle18_07_14_dasm(DASM_OPS_16); -int arcompact_handle18_07_15_dasm(DASM_OPS_16); -int arcompact_handle18_07_16_dasm(DASM_OPS_16); -int arcompact_handle18_07_17_dasm(DASM_OPS_16); -int arcompact_handle18_07_18_dasm(DASM_OPS_16); -int arcompact_handle18_07_19_dasm(DASM_OPS_16); -int arcompact_handle18_07_1a_dasm(DASM_OPS_16); -int arcompact_handle18_07_1b_dasm(DASM_OPS_16); -int arcompact_handle18_07_1c_dasm(DASM_OPS_16); -int arcompact_handle18_07_1d_dasm(DASM_OPS_16); -int arcompact_handle18_07_1e_dasm(DASM_OPS_16); -int arcompact_handle18_07_1f_dasm(DASM_OPS_16); diff --git a/src/devices/cpu/arm/arm.cpp b/src/devices/cpu/arm/arm.cpp index 077f693b144..77c8a44ac6d 100644 --- a/src/devices/cpu/arm/arm.cpp +++ b/src/devices/cpu/arm/arm.cpp @@ -20,9 +20,7 @@ #include "emu.h" #include "arm.h" #include "debugger.h" - -CPU_DISASSEMBLE( arm ); -CPU_DISASSEMBLE( arm_be ); +#include "armdasm.h" #define ARM_DEBUG_CORE 0 #define ARM_DEBUG_COPRO 0 @@ -512,7 +510,7 @@ void arm_cpu_device::execute_set_input(int irqline, int state) void arm_cpu_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); save_item(NAME(m_sArmRegister)); save_item(NAME(m_coproRegister)); @@ -1562,15 +1560,7 @@ void arm_cpu_device::HandleCoPro( uint32_t insn ) } -offs_t arm_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) -{ - extern CPU_DISASSEMBLE( arm ); - return CPU_DISASSEMBLE_NAME(arm)(this, stream, pc, oprom, opram, options); -} - - -offs_t arm_be_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *arm_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( arm_be ); - return CPU_DISASSEMBLE_NAME(arm_be)(this, stream, pc, oprom, opram, options); + return new arm_disassembler; } diff --git a/src/devices/cpu/arm/arm.h b/src/devices/cpu/arm/arm.h index 2de5fb3a39b..3cfb1386fa9 100644 --- a/src/devices/cpu/arm/arm.h +++ b/src/devices/cpu/arm/arm.h @@ -64,9 +64,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 4; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 4; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; address_space_config m_program_config; @@ -76,7 +74,7 @@ protected: uint8_t m_pendingIrq; uint8_t m_pendingFiq; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; endianness_t m_endian; copro_type m_copro_type; @@ -111,9 +109,6 @@ class arm_be_cpu_device : public arm_cpu_device public: // construction/destruction arm_be_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - -protected: - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; }; diff --git a/src/devices/cpu/arm/armdasm.cpp b/src/devices/cpu/arm/armdasm.cpp index 67d65209871..657ceb43550 100644 --- a/src/devices/cpu/arm/armdasm.cpp +++ b/src/devices/cpu/arm/armdasm.cpp @@ -7,9 +7,9 @@ */ #include "emu.h" -#include "arm.h" +#include "armdasm.h" -static void WriteImmediateOperand( std::ostream &stream, uint32_t opcode ) +void arm_disassembler::WriteImmediateOperand( std::ostream &stream, uint32_t opcode ) const { /* rrrrbbbbbbbb */ uint32_t imm; @@ -21,7 +21,7 @@ static void WriteImmediateOperand( std::ostream &stream, uint32_t opcode ) util::stream_format( stream, ", #$%x", imm ); } -static void WriteDataProcessingOperand( std::ostream &stream, uint32_t opcode, int printOp0, int printOp1, int printOp2 ) +void arm_disassembler::WriteDataProcessingOperand( std::ostream &stream, uint32_t opcode, int printOp0, int printOp1, int printOp2 ) const { /* ccccctttmmmm */ static const char *const pRegOp[4] = { "LSL","LSR","ASR","ROR" }; @@ -57,7 +57,7 @@ static void WriteDataProcessingOperand( std::ostream &stream, uint32_t opcode, i } } -static void WriteRegisterOperand1( std::ostream &stream, uint32_t opcode ) +void arm_disassembler::WriteRegisterOperand1( std::ostream &stream, uint32_t opcode ) const { /* ccccctttmmmm */ static const char *const pRegOp[4] = { "LSL","LSR","ASR","ROR" }; @@ -81,7 +81,7 @@ static void WriteRegisterOperand1( std::ostream &stream, uint32_t opcode ) } /* WriteRegisterOperand */ -static void WriteBranchAddress( std::ostream &stream, uint32_t pc, uint32_t opcode ) +void arm_disassembler::WriteBranchAddress( std::ostream &stream, uint32_t pc, uint32_t opcode ) const { opcode &= 0x00ffffff; if( opcode&0x00800000 ) @@ -92,14 +92,14 @@ static void WriteBranchAddress( std::ostream &stream, uint32_t pc, uint32_t opco util::stream_format( stream, "$%x", pc ); } /* WriteBranchAddress */ -static void WritePadding(std::ostream &stream, std::streampos start_position) +void arm_disassembler::WritePadding(std::ostream &stream, std::streampos start_position) const { std::streamoff difference = stream.tellp() - start_position; for (std::streamoff i = difference; i < 8; i++) stream << ' '; } -static uint32_t arm_disasm( std::ostream &stream, uint32_t pc, uint32_t opcode ) +offs_t arm_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { static const char *const pConditionCodeTable[16] = { @@ -119,6 +119,8 @@ static uint32_t arm_disasm( std::ostream &stream, uint32_t pc, uint32_t opcode ) uint32_t dasmflags = 0; std::streampos start_position = stream.tellp(); + u32 opcode = opcodes.r32(pc); + pConditionCode= pConditionCodeTable[opcode>>28]; if( (opcode&0x0fc000f0)==0x00000090u ) @@ -193,7 +195,7 @@ static uint32_t arm_disasm( std::ostream &stream, uint32_t pc, uint32_t opcode ) case 0x0d: /* look for mov pc,lr */ if (((opcode >> 12) & 0x0f) == 15 && ((opcode >> 0) & 0x0f) == 14 && (opcode & 0x02000000) == 0) - dasmflags = DASMFLAG_STEP_OUT; + dasmflags = STEP_OUT; case 0x0f: WriteDataProcessingOperand(stream, opcode, 1, 0, 1); break; @@ -325,7 +327,7 @@ static uint32_t arm_disasm( std::ostream &stream, uint32_t pc, uint32_t opcode ) if( opcode&0x01000000 ) { util::stream_format( stream, "BL" ); - dasmflags = DASMFLAG_STEP_OVER; + dasmflags = STEP_OVER; } else { @@ -380,24 +382,21 @@ static uint32_t arm_disasm( std::ostream &stream, uint32_t pc, uint32_t opcode ) util::stream_format( stream, "SWI%s $%x", pConditionCode, opcode&0x00ffffff ); - dasmflags = DASMFLAG_STEP_OVER; + dasmflags = STEP_OVER; } else { util::stream_format( stream, "Undefined" ); } - return dasmflags | DASMFLAG_SUPPORTED; + return 4 | dasmflags | SUPPORTED; } -CPU_DISASSEMBLE( arm ) +u32 arm_disassembler::opcode_alignment() const { - uint32_t opcode = oprom[0] | (oprom[1] << 8) | (oprom[2] << 16) | (oprom[3] << 24); - return 4 | arm_disasm(stream, pc, opcode); + return 4; } -CPU_DISASSEMBLE( arm_be ) +arm_disassembler::arm_disassembler() { - uint32_t opcode = oprom[3] | (oprom[2] << 8) | (oprom[1] << 16) | (oprom[0] << 24); - return 4 | arm_disasm(stream, pc, opcode); } diff --git a/src/devices/cpu/arm/armdasm.h b/src/devices/cpu/arm/armdasm.h new file mode 100644 index 00000000000..1e2ed19f394 --- /dev/null +++ b/src/devices/cpu/arm/armdasm.h @@ -0,0 +1,23 @@ + +#ifndef MAME_CPU_ARM_ARMDASM_H +#define MAME_CPU_ARM_ARMDASM_H + +#pragma once + +class arm_disassembler : public util::disasm_interface +{ +public: + arm_disassembler(); + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + void WriteImmediateOperand( std::ostream &stream, uint32_t opcode ) const; + void WriteDataProcessingOperand( std::ostream &stream, uint32_t opcode, int printOp0, int printOp1, int printOp2 ) const; + void WriteRegisterOperand1( std::ostream &stream, uint32_t opcode ) const; + void WriteBranchAddress( std::ostream &stream, uint32_t pc, uint32_t opcode ) const; + void WritePadding(std::ostream &stream, std::streampos start_position) const; + +}; + +#endif diff --git a/src/devices/cpu/arm7/arm7.cpp b/src/devices/cpu/arm7/arm7.cpp index 551f940f692..6538e573935 100644 --- a/src/devices/cpu/arm7/arm7.cpp +++ b/src/devices/cpu/arm7/arm7.cpp @@ -53,6 +53,7 @@ DEFINE_DEVICE_TYPE(ARM920T, arm920t_cpu_device, "arm920t", "ARM920T") DEFINE_DEVICE_TYPE(ARM946ES, arm946es_cpu_device, "arm946es", "ARM946ES") DEFINE_DEVICE_TYPE(PXA255, pxa255_cpu_device, "pxa255", "Intel XScale PXA255") DEFINE_DEVICE_TYPE(SA1110, sa1110_cpu_device, "sa1110", "Intel StrongARM SA-1110") +DEFINE_DEVICE_TYPE(IGS036, igs036_cpu_device, "igs036", "IGS036") arm7_cpu_device::arm7_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : arm7_cpu_device(mconfig, ARM7, tag, owner, clock, 4, ARCHFLAG_T, ENDIANNESS_LITTLE) @@ -62,9 +63,12 @@ arm7_cpu_device::arm7_cpu_device(const machine_config &mconfig, const char *tag, arm7_cpu_device::arm7_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t archRev, uint8_t archFlags, endianness_t endianness) : cpu_device(mconfig, type, tag, owner, clock) , m_program_config("program", endianness, 32, 32, 0) + , m_prefetch_word0_shift(endianness == ENDIANNESS_LITTLE ? 0 : 16) + , m_prefetch_word1_shift(endianness == ENDIANNESS_LITTLE ? 16 : 0) , m_endian(endianness) , m_archRev(archRev) , m_archFlags(archFlags) + , m_vectorbase(0) , m_pc(0) { memset(m_r, 0x00, sizeof(m_r)); @@ -73,6 +77,14 @@ arm7_cpu_device::arm7_cpu_device(const machine_config &mconfig, device_type type arch = ARM9_COPRO_ID_ARCH_V4T; m_copro_id = ARM9_COPRO_ID_MFR_ARM | arch | ARM9_COPRO_ID_PART_GENERICARM7; + + // TODO[RH]: Default to 3-instruction prefetch for unknown ARM variants. Derived cores should set the appropriate value in their constructors. + m_insn_prefetch_depth = 3; + + memset(m_insn_prefetch_buffer, 0, sizeof(uint32_t) * 3); + memset(m_insn_prefetch_address, 0, sizeof(uint32_t) * 3); + m_insn_prefetch_count = 0; + m_insn_prefetch_index = 0; } @@ -137,12 +149,24 @@ arm920t_cpu_device::arm920t_cpu_device(const machine_config &mconfig, const char arm946es_cpu_device::arm946es_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : arm9_cpu_device(mconfig, ARM946ES, tag, owner, clock, 5, ARCHFLAG_T | ARCHFLAG_E, ENDIANNESS_LITTLE) + : arm9_cpu_device(mconfig, ARM946ES, tag, owner, clock, 5, ARCHFLAG_T | ARCHFLAG_E, ENDIANNESS_LITTLE), + cp15_control(0x78) { m_copro_id = ARM9_COPRO_ID_MFR_ARM | ARM9_COPRO_ID_ARCH_V5TE | ARM9_COPRO_ID_PART_ARM946 | ARM9_COPRO_ID_STEP_ARM946_A0; + + memset(ITCM, 0, 0x8000); + memset(DTCM, 0, 0x4000); + + cp15_itcm_base = 0xffffffff; + cp15_itcm_size = 0; + cp15_itcm_end = 0; + cp15_dtcm_base = 0xffffffff; + cp15_dtcm_size = 0; + cp15_dtcm_end = 0; + cp15_itcm_reg = cp15_dtcm_reg = 0; } pxa255_cpu_device::pxa255_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) @@ -165,6 +189,13 @@ sa1110_cpu_device::sa1110_cpu_device(const machine_config &mconfig, const char * | ARM9_COPRO_ID_STEP_SA1110_A0; } +// unknown configuration +igs036_cpu_device::igs036_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : arm9_cpu_device(mconfig, IGS036, tag, owner, clock, 5, ARCHFLAG_T | ARCHFLAG_E, ENDIANNESS_LITTLE) +{ +} + + device_memory_interface::space_config_vector arm7_cpu_device::memory_space_config() const { return space_config_vector { @@ -334,7 +365,7 @@ int arm7_cpu_device::detect_fault(int desc_lvl1, int ap, int flags) } -bool arm7_cpu_device::arm7_tlb_translate(offs_t &addr, int flags) +bool arm7_cpu_device::arm7_tlb_translate(offs_t &addr, int flags, bool no_exception) { if (addr < 0x2000000) { @@ -366,6 +397,9 @@ bool arm7_cpu_device::arm7_tlb_translate(offs_t &addr, int flags) } else { + if (no_exception) + return false; + if (flags & ARM7_TLB_ABORT_D) { uint8_t domain = (desc_lvl1 >> 5) & 0xF; @@ -389,6 +423,9 @@ bool arm7_cpu_device::arm7_tlb_translate(offs_t &addr, int flags) } else if (tlb_type == COPRO_TLB_UNMAPPED) { + if (no_exception) + return false; + // Unmapped, generate a translation fault if (flags & ARM7_TLB_ABORT_D) { @@ -420,6 +457,9 @@ bool arm7_cpu_device::arm7_tlb_translate(offs_t &addr, int flags) switch( desc_lvl2 & 3 ) { case COPRO_TLB_UNMAPPED: + if (no_exception) + return false; + // Unmapped, generate a translation fault if (flags & ARM7_TLB_ABORT_D) { @@ -450,6 +490,10 @@ bool arm7_cpu_device::arm7_tlb_translate(offs_t &addr, int flags) { addr = ( desc_lvl2 & COPRO_TLB_SMALL_PAGE_MASK ) | ( addr & ~COPRO_TLB_SMALL_PAGE_MASK ); } + else if (no_exception) + { + return false; + } else { if (flags & ARM7_TLB_ABORT_D) @@ -511,7 +555,7 @@ bool arm7_cpu_device::memory_translate(int spacenum, int intention, offs_t &addr void arm7_cpu_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); save_item(NAME(m_r)); save_item(NAME(m_pendingIrq)); @@ -631,7 +675,7 @@ void arm7_cpu_device::device_reset() /* start up in SVC mode with interrupts disabled. */ m_r[eCPSR] = I_MASK | F_MASK | 0x10; SwitchMode(eARM7_MODE_SVC); - m_r[eR15] = 0; + m_r[eR15] = 0 | m_vectorbase; m_impstate.cache_dirty = true; } @@ -641,6 +685,73 @@ void arm7_cpu_device::device_reset() m_r[eR15] += 4; \ m_icount +=2; /* Any unexecuted instruction only takes 1 cycle (page 193) */ +void arm7_cpu_device::update_insn_prefetch(uint32_t curr_pc) +{ + curr_pc &= ~3; + if (m_insn_prefetch_address[m_insn_prefetch_index] != curr_pc) + { + m_insn_prefetch_count = 0; + m_insn_prefetch_index = 0; + } + + if (m_insn_prefetch_count == m_insn_prefetch_depth) + return; + + const uint32_t to_fetch = m_insn_prefetch_depth - m_insn_prefetch_count; + const uint32_t start_index = (m_insn_prefetch_depth + (m_insn_prefetch_index - to_fetch)) % m_insn_prefetch_depth; + //printf("need to prefetch %d instructions starting at index %d\n", to_fetch, start_index); + + uint32_t pc = curr_pc + m_insn_prefetch_count * 4; + for (uint32_t i = 0; i < to_fetch; i++) + { + uint32_t index = (i + start_index) % m_insn_prefetch_depth; + if ((m_control & COPRO_CTRL_MMU_EN) && !arm7_tlb_translate(pc, ARM7_TLB_ABORT_P | ARM7_TLB_READ, true)) + { + break; + } + uint32_t op = m_direct->read_dword(pc); + //printf("ipb[%d] <- %08x(%08x)\n", index, op, pc); + m_insn_prefetch_buffer[index] = op; + m_insn_prefetch_address[index] = pc; + m_insn_prefetch_count++; + pc += 4; + } +} + +uint16_t arm7_cpu_device::insn_fetch_thumb(uint32_t pc) +{ + if (pc & 2) + { + uint16_t insn = (uint16_t)(m_insn_prefetch_buffer[m_insn_prefetch_index] >> m_prefetch_word1_shift); + m_insn_prefetch_index = (m_insn_prefetch_index + 1) % m_insn_prefetch_count; + m_insn_prefetch_count--; + return insn; + } + return (uint16_t)(m_insn_prefetch_buffer[m_insn_prefetch_index] >> m_prefetch_word0_shift); +} + +uint32_t arm7_cpu_device::insn_fetch_arm(uint32_t pc) +{ + //printf("ipb[%d] = %08x\n", m_insn_prefetch_index, m_insn_prefetch_buffer[m_insn_prefetch_index]); + uint32_t insn = m_insn_prefetch_buffer[m_insn_prefetch_index]; + m_insn_prefetch_index = (m_insn_prefetch_index + 1) % m_insn_prefetch_count; + m_insn_prefetch_count--; + return insn; +} + +int arm7_cpu_device::get_insn_prefetch_index(uint32_t address) +{ + address &= ~3; + for (uint32_t i = 0; i < m_insn_prefetch_depth; i++) + { + if (m_insn_prefetch_address[i] == address) + { + return (int)i; + } + } + return -1; +} + void arm7_cpu_device::execute_run() { uint32_t insn; @@ -649,6 +760,8 @@ void arm7_cpu_device::execute_run() { uint32_t pc = GET_PC; + update_insn_prefetch(pc); + debugger_instruction_hook(this, pc); /* handle Thumb instructions if active */ @@ -669,7 +782,7 @@ void arm7_cpu_device::execute_run() } } - insn = m_direct->read_word(raddr); + insn = insn_fetch_thumb(raddr); (this->*thumb_handler[(insn & 0xffc0) >> 6])(pc, insn); } @@ -700,7 +813,7 @@ void arm7_cpu_device::execute_run() } #endif - insn = m_direct->read_dword(raddr); + insn = insn_fetch_arm(raddr); int op_offset = 0; /* process condition codes for this instruction */ @@ -816,27 +929,14 @@ void arm7_cpu_device::execute_set_input(int irqline, int state) } -offs_t arm7_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *arm7_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( arm7arm ); - extern CPU_DISASSEMBLE( arm7thumb ); - extern CPU_DISASSEMBLE( arm7arm_be ); - extern CPU_DISASSEMBLE( arm7thumb_be ); + return new arm7_disassembler(this); +} - if (T_IS_SET(m_r[eCPSR])) - { - if ( m_endian == ENDIANNESS_BIG ) - return CPU_DISASSEMBLE_NAME(arm7thumb_be)(this, stream, pc, oprom, opram, options); - else - return CPU_DISASSEMBLE_NAME(arm7thumb)(this, stream, pc, oprom, opram, options); - } - else - { - if ( m_endian == ENDIANNESS_BIG ) - return CPU_DISASSEMBLE_NAME(arm7arm_be)(this, stream, pc, oprom, opram, options); - else - return CPU_DISASSEMBLE_NAME(arm7arm)(this, stream, pc, oprom, opram, options); - } +bool arm7_cpu_device::get_t_flag() const +{ + return T_IS_SET(m_r[eCPSR]); } @@ -1074,6 +1174,298 @@ WRITE32_MEMBER( arm7_cpu_device::arm7_rt_w_callback ) } } +READ32_MEMBER( arm946es_cpu_device::arm7_rt_r_callback ) +{ + uint32_t opcode = offset; + uint8_t cReg = ( opcode & INSN_COPRO_CREG ) >> INSN_COPRO_CREG_SHIFT; + uint8_t op2 = ( opcode & INSN_COPRO_OP2 ) >> INSN_COPRO_OP2_SHIFT; + uint8_t op3 = opcode & INSN_COPRO_OP3; + uint8_t cpnum = (opcode & INSN_COPRO_CPNUM) >> INSN_COPRO_CPNUM_SHIFT; + uint32_t data = 0; + + //printf("arm7946: read cpnum %d cReg %d op2 %d op3 %d (%x)\n", cpnum, cReg, op2, op3, opcode); + if (cpnum == 15) + { + switch( cReg ) + { + case 0: + switch (op2) + { + case 0: // chip ID + data = 0x41059461; + break; + + case 1: // cache ID + data = 0x0f0d2112; + break; + + case 2: // TCM size + data = (6 << 6) | (5 << 18); + break; + } + break; + + case 1: + return cp15_control; + break; + + case 9: + if (op3 == 1) + { + if (op2 == 0) + { + return cp15_dtcm_reg; + } + else + { + return cp15_itcm_reg; + } + } + break; + } + } + + return data; +} + +WRITE32_MEMBER( arm946es_cpu_device::arm7_rt_w_callback ) +{ + uint32_t opcode = offset; + uint8_t cReg = ( opcode & INSN_COPRO_CREG ) >> INSN_COPRO_CREG_SHIFT; + uint8_t op2 = ( opcode & INSN_COPRO_OP2 ) >> INSN_COPRO_OP2_SHIFT; + uint8_t op3 = opcode & INSN_COPRO_OP3; + uint8_t cpnum = (opcode & INSN_COPRO_CPNUM) >> INSN_COPRO_CPNUM_SHIFT; + +// printf("arm7946: copro %d write %x to cReg %d op2 %d op3 %d (mask %08x)\n", cpnum, data, cReg, op2, op3, mem_mask); + + if (cpnum == 15) + { + switch (cReg) + { + case 1: // control + cp15_control = data; + RefreshDTCM(); + RefreshITCM(); + break; + + case 2: // Protection Unit cacheability bits + break; + + case 3: // write bufferability bits for PU + break; + + case 5: // protection unit region controls + break; + + case 6: // protection unit region controls 2 + break; + + case 7: // cache commands + break; + + case 9: // cache lockdown & TCM controls + if (op3 == 1) + { + if (op2 == 0) + { + cp15_dtcm_reg = data; + RefreshDTCM(); + } + else if (op2 == 1) + { + cp15_itcm_reg = data; + RefreshITCM(); + } + } + break; + } + } +} + +void arm946es_cpu_device::RefreshDTCM() +{ + if (cp15_control & (1<<16)) + { + cp15_dtcm_base = (cp15_dtcm_reg & ~0xfff); + cp15_dtcm_size = 512 << ((cp15_dtcm_reg & 0x3f) >> 1); + cp15_dtcm_end = cp15_dtcm_base + cp15_dtcm_size; + //printf("DTCM enabled: base %08x size %x\n", cp15_dtcm_base, cp15_dtcm_size); + } + else + { + cp15_dtcm_base = 0xffffffff; + cp15_dtcm_size = cp15_dtcm_end = 0; + } +} + +void arm946es_cpu_device::RefreshITCM() +{ + if (cp15_control & (1<<18)) + { + cp15_itcm_base = 0; //(cp15_itcm_reg & ~0xfff); + cp15_itcm_size = 512 << ((cp15_itcm_reg & 0x3f) >> 1); + cp15_itcm_end = cp15_itcm_base + cp15_itcm_size; + //printf("ITCM enabled: base %08x size %x\n", cp15_dtcm_base, cp15_dtcm_size); + } + else + { + cp15_itcm_base = 0xffffffff; + cp15_itcm_size = cp15_itcm_end = 0; + } +} + +void arm946es_cpu_device::arm7_cpu_write32(uint32_t addr, uint32_t data) +{ + addr &= ~3; + + if ((addr >= cp15_itcm_base) && (addr <= cp15_itcm_end)) + { + uint32_t *wp = (uint32_t *)&ITCM[addr&0x7fff]; + *wp = data; + return; + } + else if ((addr >= cp15_dtcm_base) && (addr <= cp15_dtcm_end)) + { + uint32_t *wp = (uint32_t *)&DTCM[addr&0x3fff]; + *wp = data; + return; + } + + m_program->write_dword(addr, data); +} + + +void arm946es_cpu_device::arm7_cpu_write16(uint32_t addr, uint16_t data) +{ + addr &= ~1; + if ((addr >= cp15_itcm_base) && (addr <= cp15_itcm_end)) + { + uint16_t *wp = (uint16_t *)&ITCM[addr&0x7fff]; + *wp = data; + return; + } + else if ((addr >= cp15_dtcm_base) && (addr <= cp15_dtcm_end)) + { + uint16_t *wp = (uint16_t *)&DTCM[addr&0x3fff]; + *wp = data; + return; + } + + m_program->write_word(addr, data); +} + +void arm946es_cpu_device::arm7_cpu_write8(uint32_t addr, uint8_t data) +{ + if ((addr >= cp15_itcm_base) && (addr <= cp15_itcm_end)) + { + ITCM[addr&0x7fff] = data; + return; + } + else if ((addr >= cp15_dtcm_base) && (addr <= cp15_dtcm_end)) + { + DTCM[addr&0x3fff] = data; + return; + } + + m_program->write_byte(addr, data); +} + +uint32_t arm946es_cpu_device::arm7_cpu_read32(uint32_t addr) +{ + uint32_t result; + + if ((addr >= cp15_itcm_base) && (addr <= cp15_itcm_end)) + { + if (addr & 3) + { + uint32_t *wp = (uint32_t *)&ITCM[(addr & ~3)&0x7fff]; + result = *wp; + result = (result >> (8 * (addr & 3))) | (result << (32 - (8 * (addr & 3)))); + } + else + { + uint32_t *wp = (uint32_t *)&ITCM[addr&0x7fff]; + result = *wp; + } + } + else if ((addr >= cp15_dtcm_base) && (addr <= cp15_dtcm_end)) + { + if (addr & 3) + { + uint32_t *wp = (uint32_t *)&DTCM[(addr & ~3)&0x3fff]; + result = *wp; + result = (result >> (8 * (addr & 3))) | (result << (32 - (8 * (addr & 3)))); + } + else + { + uint32_t *wp = (uint32_t *)&DTCM[addr&0x3fff]; + result = *wp; + } + } + else + { + if (addr & 3) + { + result = m_program->read_dword(addr & ~3); + result = (result >> (8 * (addr & 3))) | (result << (32 - (8 * (addr & 3)))); + } + else + { + result = m_program->read_dword(addr); + } + } + return result; +} + +uint16_t arm946es_cpu_device::arm7_cpu_read16(uint32_t addr) +{ + uint16_t result; + + if ((addr >= cp15_itcm_base) && (addr <= cp15_itcm_end)) + { + uint16_t *wp = (uint16_t *)&ITCM[(addr & ~1)&0x7fff]; + result = *wp; + } + else if ((addr >= cp15_dtcm_base) && (addr <= cp15_dtcm_end)) + { + uint16_t *wp = (uint16_t *)&DTCM[(addr & ~1)&0x3fff]; + result = *wp; + } + else + { + result = m_program->read_word(addr & ~1); + } + + if (addr & 1) + { + result = ((result >> 8) & 0xff) | ((result & 0xff) << 8); + } + + return result; +} + +uint8_t arm946es_cpu_device::arm7_cpu_read8(uint32_t addr) +{ + if ((addr >= cp15_itcm_base) && (addr <= cp15_itcm_end)) + { + return ITCM[addr & 0x7fff]; + } + else if ((addr >= cp15_dtcm_base) && (addr <= cp15_dtcm_end)) + { + return DTCM[addr & 0x3fff]; + } + + // Handle through normal 8 bit handler (for 32 bit cpu) + return m_program->read_byte(addr); +} + +WRITE32_MEMBER(igs036_cpu_device::arm7_rt_w_callback) +{ + arm7_cpu_device::arm7_rt_w_callback(space, offset, data, mem_mask); + /* disable the MMU for now, it doesn't seem to set up valid mappings + so could be entirely different here */ + COPRO_CTRL &= ~COPRO_CTRL_MMU_EN; +} void arm7_cpu_device::arm7_dt_r_callback(uint32_t insn, uint32_t *prn) { diff --git a/src/devices/cpu/arm7/arm7.h b/src/devices/cpu/arm7/arm7.h index 3f7f82fed8a..2fde4b1805a 100644 --- a/src/devices/cpu/arm7/arm7.h +++ b/src/devices/cpu/arm7/arm7.h @@ -23,6 +23,8 @@ #pragma once +#include "arm7dasm.h" + #include "cpu/drcfe.h" #include "cpu/drcuml.h" #include "cpu/drcumlsh.h" @@ -31,6 +33,9 @@ #define ARM7_MAX_FASTRAM 4 #define ARM7_MAX_HOTSPOTS 16 +#define MCFG_ARM_HIGH_VECTORS() \ + arm7_cpu_device::set_high_vectors(*device); + /*************************************************************************** COMPILER-SPECIFIC OPTIONS @@ -46,12 +51,18 @@ * PUBLIC FUNCTIONS ***************************************************************************************************/ -class arm7_cpu_device : public cpu_device +class arm7_cpu_device : public cpu_device, public arm7_disassembler::config { public: // construction/destruction arm7_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + static void set_high_vectors(device_t &device) + { + arm7_cpu_device &dev = downcast<arm7_cpu_device &>(device); + dev.m_vectorbase = 0xffff0000; + } + protected: enum { @@ -121,13 +132,26 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 4; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; + virtual bool get_t_flag() const override; address_space_config m_program_config; uint32_t m_r[/*NUM_REGS*/37]; + + void update_insn_prefetch(uint32_t curr_pc); + virtual uint16_t insn_fetch_thumb(uint32_t pc); + uint32_t insn_fetch_arm(uint32_t pc); + int get_insn_prefetch_index(uint32_t address); + + uint32_t m_insn_prefetch_depth; + uint32_t m_insn_prefetch_count; + uint32_t m_insn_prefetch_index; + uint32_t m_insn_prefetch_buffer[3]; + uint32_t m_insn_prefetch_address[3]; + const uint32_t m_prefetch_word0_shift; + const uint32_t m_prefetch_word1_shift; + bool m_pendingIrq; bool m_pendingFiq; bool m_pendingAbtD; @@ -138,7 +162,7 @@ protected: int m_icount; endianness_t m_endian; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; /* Coprocessor Registers */ uint32_t m_control; @@ -154,6 +178,8 @@ protected: uint8_t m_archRev; // ARM architecture revision (3, 4, and 5 are valid) uint8_t m_archFlags; // architecture flags + uint32_t m_vectorbase; + //#if ARM7_MMU_ENABLE_HACK // uint32_t mmu_enable_addr; // workaround for "MMU is enabled when PA != VA" problem //#endif @@ -201,22 +227,22 @@ protected: void arm9ops_e(uint32_t insn); void set_cpsr(uint32_t val); - bool arm7_tlb_translate(offs_t &addr, int flags); + bool arm7_tlb_translate(offs_t &addr, int flags, bool no_exception = false); uint32_t arm7_tlb_get_second_level_descriptor( uint32_t granularity, uint32_t first_desc, uint32_t vaddr ); int detect_fault(int desc_lvl1, int ap, int flags); void arm7_check_irq_state(); void update_irq_state(); - void arm7_cpu_write32(uint32_t addr, uint32_t data); - void arm7_cpu_write16(uint32_t addr, uint16_t data); - void arm7_cpu_write8(uint32_t addr, uint8_t data); - uint32_t arm7_cpu_read32(uint32_t addr); - uint16_t arm7_cpu_read16(uint32_t addr); - uint8_t arm7_cpu_read8(uint32_t addr); + virtual void arm7_cpu_write32(uint32_t addr, uint32_t data); + virtual void arm7_cpu_write16(uint32_t addr, uint16_t data); + virtual void arm7_cpu_write8(uint32_t addr, uint8_t data); + virtual uint32_t arm7_cpu_read32(uint32_t addr); + virtual uint16_t arm7_cpu_read16(uint32_t addr); + virtual uint8_t arm7_cpu_read8(uint32_t addr); // Coprocessor support DECLARE_WRITE32_MEMBER( arm7_do_callback ); - DECLARE_READ32_MEMBER( arm7_rt_r_callback ); - DECLARE_WRITE32_MEMBER( arm7_rt_w_callback ); + virtual DECLARE_READ32_MEMBER( arm7_rt_r_callback ); + virtual DECLARE_WRITE32_MEMBER( arm7_rt_w_callback ); void arm7_dt_r_callback(uint32_t insn, uint32_t *prn); void arm7_dt_w_callback(uint32_t insn, uint32_t *prn); @@ -588,6 +614,25 @@ class arm946es_cpu_device : public arm9_cpu_device public: // construction/destruction arm946es_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + // 946E-S has Protection Unit instead of ARM MMU so CP15 is quite different + virtual DECLARE_READ32_MEMBER( arm7_rt_r_callback ) override; + virtual DECLARE_WRITE32_MEMBER( arm7_rt_w_callback ) override; + + virtual void arm7_cpu_write32(uint32_t addr, uint32_t data) override; + virtual void arm7_cpu_write16(uint32_t addr, uint16_t data) override; + virtual void arm7_cpu_write8(uint32_t addr, uint8_t data) override; + virtual uint32_t arm7_cpu_read32(uint32_t addr) override; + virtual uint16_t arm7_cpu_read16(uint32_t addr) override; + virtual uint8_t arm7_cpu_read8(uint32_t addr) override; + +private: + uint32_t cp15_control, cp15_itcm_base, cp15_dtcm_base, cp15_itcm_size, cp15_dtcm_size; + uint32_t cp15_itcm_end, cp15_dtcm_end, cp15_itcm_reg, cp15_dtcm_reg; + uint8_t ITCM[0x8000], DTCM[0x4000]; + + void RefreshITCM(); + void RefreshDTCM(); }; @@ -606,6 +651,14 @@ public: sa1110_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; +class igs036_cpu_device : public arm9_cpu_device +{ +public: + // construction/destruction + igs036_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + virtual DECLARE_WRITE32_MEMBER( arm7_rt_w_callback ) override; +}; + DECLARE_DEVICE_TYPE(ARM7, arm7_cpu_device) DECLARE_DEVICE_TYPE(ARM7_BE, arm7_be_cpu_device) @@ -615,5 +668,6 @@ DECLARE_DEVICE_TYPE(ARM920T, arm920t_cpu_device) DECLARE_DEVICE_TYPE(ARM946ES, arm946es_cpu_device) DECLARE_DEVICE_TYPE(PXA255, pxa255_cpu_device) DECLARE_DEVICE_TYPE(SA1110, sa1110_cpu_device) +DECLARE_DEVICE_TYPE(IGS036, igs036_cpu_device) #endif // MAME_CPU_ARM7_ARM7_H diff --git a/src/devices/cpu/arm7/arm7core.h b/src/devices/cpu/arm7/arm7core.h index 14d6f6267e8..9ae499ae109 100644 --- a/src/devices/cpu/arm7/arm7core.h +++ b/src/devices/cpu/arm7/arm7core.h @@ -163,7 +163,7 @@ struct arm_state int m_icount; endianness_t m_endian; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; /* Coprocessor Registers */ uint32_t m_control; diff --git a/src/devices/cpu/arm7/arm7core.hxx b/src/devices/cpu/arm7/arm7core.hxx index 0e418209e73..0fbe5f00868 100644 --- a/src/devices/cpu/arm7/arm7core.hxx +++ b/src/devices/cpu/arm7/arm7core.hxx @@ -136,6 +136,7 @@ void arm7_cpu_device::arm7_check_irq_state() set_cpsr(GET_CPSR | I_MASK | F_MASK); /* Mask both IRQ & FIQ */ set_cpsr(GET_CPSR & ~T_MASK); R15 = 0x1c; /* IRQ Vector address */ + R15 |= m_vectorbase; if ((COPRO_CTRL & COPRO_CTRL_MMU_EN) && (COPRO_CTRL & COPRO_CTRL_INTVEC_ADJUST)) R15 |= 0xFFFF0000; return; } @@ -159,6 +160,7 @@ void arm7_cpu_device::arm7_check_irq_state() temp = (GET_CPSR & 0x0FFFFF3F) /* N Z C V I F */ | (R15 & 0xF0000000) /* N Z C V */ | ((R15 & 0x0C000000) >> (26 - 6)) /* I F */; set_cpsr(temp); /* Mask IRQ */ } + R15 |= m_vectorbase; if ((COPRO_CTRL & COPRO_CTRL_MMU_EN) && (COPRO_CTRL & COPRO_CTRL_INTVEC_ADJUST)) R15 |= 0xFFFF0000; return; } @@ -172,7 +174,7 @@ void arm7_cpu_device::arm7_check_irq_state() SetRegister(SPSR, cpsr); /* Save current CPSR */ set_cpsr(GET_CPSR | I_MASK); /* Mask IRQ */ set_cpsr(GET_CPSR & ~T_MASK); - R15 = 0x0c; /* IRQ Vector address */ + R15 = 0x0c | m_vectorbase; /* IRQ Vector address */ if ((COPRO_CTRL & COPRO_CTRL_MMU_EN) && (COPRO_CTRL & COPRO_CTRL_INTVEC_ADJUST)) R15 |= 0xFFFF0000; m_pendingAbtP = false; update_irq_state(); @@ -196,7 +198,7 @@ void arm7_cpu_device::arm7_check_irq_state() SetRegister(SPSR, cpsr); /* Save current CPSR */ set_cpsr(GET_CPSR | I_MASK); /* Mask IRQ */ set_cpsr(GET_CPSR & ~T_MASK); - R15 = 0x04; /* IRQ Vector address */ + R15 = 0x04 | m_vectorbase; /* IRQ Vector address */ if ((COPRO_CTRL & COPRO_CTRL_MMU_EN) && (COPRO_CTRL & COPRO_CTRL_INTVEC_ADJUST)) R15 |= 0xFFFF0000; m_pendingUnd = false; update_irq_state(); @@ -230,6 +232,7 @@ void arm7_cpu_device::arm7_check_irq_state() temp = (GET_CPSR & 0x0FFFFF3F) /* N Z C V I F */ | (R15 & 0xF0000000) /* N Z C V */ | ((R15 & 0x0C000000) >> (26 - 6)) /* I F */; set_cpsr(temp); /* Mask IRQ */ } + R15 |= m_vectorbase; if ((COPRO_CTRL & COPRO_CTRL_MMU_EN) && (COPRO_CTRL & COPRO_CTRL_INTVEC_ADJUST)) R15 |= 0xFFFF0000; m_pendingSwi = false; update_irq_state(); diff --git a/src/devices/cpu/arm7/arm7dasm.cpp b/src/devices/cpu/arm7/arm7dasm.cpp index 3d38ea29872..efe3459898c 100644 --- a/src/devices/cpu/arm7/arm7dasm.cpp +++ b/src/devices/cpu/arm7/arm7dasm.cpp @@ -23,16 +23,17 @@ ******************************************************************************/ #include "emu.h" +#include "arm7dasm.h" #include "arm7core.h" -static void WritePadding(std::ostream &stream, std::streampos start_position) +void arm7_disassembler::WritePadding(std::ostream &stream, std::streampos start_position) { std::streamoff difference = stream.tellp() - start_position; for (std::streamoff i = difference; i < 8; i++) stream << ' '; } -static void DasmCoProc_RT(std::ostream &stream, uint32_t opcode, const char *pConditionCode, std::streampos start_position) +void arm7_disassembler::DasmCoProc_RT(std::ostream &stream, uint32_t opcode, const char *pConditionCode, std::streampos start_position) { /* co processor register transfer */ /* xxxx 1110 oooL nnnn dddd cccc ppp1 mmmm */ @@ -51,7 +52,7 @@ static void DasmCoProc_RT(std::ostream &stream, uint32_t opcode, const char *pCo if((opcode>>5)&7) util::stream_format( stream, ", %d",(opcode>>5)&7); } -static void DasmCoProc_DT(std::ostream &stream, uint32_t opcode, const char *pConditionCode, std::streampos start_position) +void arm7_disassembler::DasmCoProc_DT(std::ostream &stream, uint32_t opcode, const char *pConditionCode, std::streampos start_position) { /* co processor data transfer */ /* xxxx 111P UNWL nnnn dddd pppp oooooooo */ @@ -75,7 +76,7 @@ static void DasmCoProc_DT(std::ostream &stream, uint32_t opcode, const char *pCo util::stream_format(stream, "%s%s",(opcode&0x1000000)?"]":"",(opcode&0x200000)?"{!}":""); } -static void DasmCoProc_DO(std::ostream &stream, uint32_t opcode, const char *pConditionCode, std::streampos start_position) +void arm7_disassembler::DasmCoProc_DO(std::ostream &stream, uint32_t opcode, const char *pConditionCode, std::streampos start_position) { /* co processor data operation */ /* xxxx 1110 oooo nnnn dddd cccc ppp0 mmmm */ @@ -88,7 +89,7 @@ static void DasmCoProc_DO(std::ostream &stream, uint32_t opcode, const char *pCo if((opcode>>5)&7) util::stream_format(stream, ", %d",(opcode>>5)&7); } -static void WriteImmediateOperand( std::ostream &stream, uint32_t opcode ) +void arm7_disassembler::WriteImmediateOperand( std::ostream &stream, uint32_t opcode ) { /* rrrrbbbbbbbb */ uint32_t imm; @@ -100,7 +101,7 @@ static void WriteImmediateOperand( std::ostream &stream, uint32_t opcode ) util::stream_format( stream, ", #$%x", imm ); } -static void WriteDataProcessingOperand( std::ostream &stream, uint32_t opcode, int printOp0, int printOp1, int printOp2 ) +void arm7_disassembler::WriteDataProcessingOperand( std::ostream &stream, uint32_t opcode, int printOp0, int printOp1, int printOp2 ) { /* ccccctttmmmm */ static const char *const pRegOp[4] = { "LSL","LSR","ASR","ROR" }; @@ -142,7 +143,7 @@ static void WriteDataProcessingOperand( std::ostream &stream, uint32_t opcode, i } } -static void WriteRegisterOperand1( std::ostream &stream, uint32_t opcode ) +void arm7_disassembler::WriteRegisterOperand1( std::ostream &stream, uint32_t opcode ) { /* ccccctttmmmm */ static const char *const pRegOp[4] = { "LSL","LSR","ASR","ROR" }; @@ -172,7 +173,7 @@ static void WriteRegisterOperand1( std::ostream &stream, uint32_t opcode ) } /* WriteRegisterOperand */ -static void WriteBranchAddress( std::ostream &stream, uint32_t pc, uint32_t opcode, bool h_bit ) +void arm7_disassembler::WriteBranchAddress( std::ostream &stream, uint32_t pc, uint32_t opcode, bool h_bit ) { opcode <<= 2; if (h_bit && (opcode & 0x04000000)) @@ -188,7 +189,7 @@ static void WriteBranchAddress( std::ostream &stream, uint32_t pc, uint32_t opco util::stream_format( stream, "$%x", pc ); } /* WriteBranchAddress */ -static uint32_t arm7_disasm( std::ostream &stream, uint32_t pc, uint32_t opcode ) +u32 arm7_disassembler::arm7_disasm( std::ostream &stream, uint32_t pc, uint32_t opcode ) { static const char *const pConditionCodeTable[16] = { @@ -212,14 +213,22 @@ static uint32_t arm7_disasm( std::ostream &stream, uint32_t pc, uint32_t opcode if( (opcode&0xfe000000)==0xfa000000 ) //bits 31-25 == 1111 101 (BLX - v5) { - /* BLX */ + /* BLX(1) */ util::stream_format( stream, "BLX" ); - dasmflags = DASMFLAG_STEP_OVER; + dasmflags = STEP_OVER; WritePadding(stream, start_position); WriteBranchAddress( stream, pc, opcode, true ); } + else if( (opcode&0x0ff000f0)==0x01200030 ) // (BLX - v5) + { + /* BLX(2) */ + util::stream_format( stream, "BLX" ); + dasmflags = STEP_OVER; + WritePadding(stream, start_position); + util::stream_format( stream, "R%d",(opcode&0xf)); + } else if( (opcode&0x0ffffff0)==0x012fff10 ) //bits 27-4 == 000100101111111111110001 { /* Branch and Exchange (BX) */ @@ -228,7 +237,7 @@ static uint32_t arm7_disasm( std::ostream &stream, uint32_t pc, uint32_t opcode WritePadding(stream, start_position); util::stream_format( stream, "R%d",(opcode&0xf)); if ((opcode & 0x0f) == 14) - dasmflags = DASMFLAG_STEP_OUT; + dasmflags = STEP_OUT; } else if ((opcode & 0x0ff000f0) == 0x01600010) // CLZ - v5 { @@ -492,7 +501,7 @@ static uint32_t arm7_disasm( std::ostream &stream, uint32_t pc, uint32_t opcode case 0x0d: /* look for mov pc,lr */ if (((opcode >> 12) & 0x0f) == 15 && ((opcode >> 0) & 0x0f) == 14 && (opcode & 0x02000000) == 0) - dasmflags = DASMFLAG_STEP_OUT; + dasmflags = STEP_OUT; case 0x0f: WriteDataProcessingOperand(stream, opcode, 1, 0, 1); break; @@ -641,7 +650,7 @@ static uint32_t arm7_disasm( std::ostream &stream, uint32_t pc, uint32_t opcode if( opcode&0x01000000 ) { util::stream_format( stream, "BL" ); - dasmflags = DASMFLAG_STEP_OVER; + dasmflags = STEP_OVER; } else { @@ -680,16 +689,16 @@ static uint32_t arm7_disasm( std::ostream &stream, uint32_t pc, uint32_t opcode util::stream_format( stream, "SWI%s $%x", pConditionCode, opcode&0x00ffffff ); - dasmflags = DASMFLAG_STEP_OVER; + dasmflags = STEP_OVER; } else { util::stream_format( stream, "Undefined" ); } - return dasmflags | DASMFLAG_SUPPORTED; + return 4 | dasmflags | SUPPORTED; } -static uint32_t thumb_disasm(std::ostream &stream, uint32_t pc, uint16_t opcode) +u32 arm7_disassembler::thumb_disasm(std::ostream &stream, uint32_t pc, uint16_t opcode) { std::streampos start_position = stream.tellp(); uint32_t dasmflags = 0; @@ -970,7 +979,7 @@ static uint32_t thumb_disasm(std::ostream &stream, uint32_t pc, uint16_t opcode) rd = ( ( opcode & THUMB_HIREG_RS ) >> THUMB_HIREG_RS_SHIFT ) + 8; util::stream_format( stream, "BX R%d", rd ); if (rd == 14) - dasmflags = DASMFLAG_STEP_OUT; + dasmflags = STEP_OUT; break; case 0x2: rd = ( opcode & THUMB_HIREG_RS ) >> THUMB_HIREG_RS_SHIFT; @@ -1279,7 +1288,7 @@ static uint32_t thumb_disasm(std::ostream &stream, uint32_t pc, uint16_t opcode) { addr = ( ( opcode & THUMB_BLOP_OFFS ) << 1 ) & 0xfffc; util::stream_format( stream, "BLX (LO) %08x", addr ); - dasmflags = DASMFLAG_STEP_OVER; + dasmflags = STEP_OVER; } else { @@ -1295,7 +1304,7 @@ static uint32_t thumb_disasm(std::ostream &stream, uint32_t pc, uint16_t opcode) if( opcode & THUMB_BLOP_LO ) { util::stream_format( stream, "BL (LO) %08x", ( opcode & THUMB_BLOP_OFFS ) << 1 ); - dasmflags = DASMFLAG_STEP_OVER; + dasmflags = STEP_OVER; } else { @@ -1305,7 +1314,7 @@ static uint32_t thumb_disasm(std::ostream &stream, uint32_t pc, uint16_t opcode) addr |= 0xff800000; } util::stream_format( stream, "BL (HI) %08x", addr ); - dasmflags = DASMFLAG_STEP_OVER; + dasmflags = STEP_OVER; } break; default: @@ -1313,25 +1322,22 @@ static uint32_t thumb_disasm(std::ostream &stream, uint32_t pc, uint16_t opcode) break; } - return dasmflags | DASMFLAG_SUPPORTED; + return 2 | dasmflags | SUPPORTED; } -CPU_DISASSEMBLE( arm7arm ) +arm7_disassembler::arm7_disassembler(config *conf) : m_config(conf) { - return arm7_disasm(stream, pc, oprom[0] | (oprom[1] << 8) | (oprom[2] << 16) | (oprom[3] << 24)) | 4; } -CPU_DISASSEMBLE( arm7arm_be ) +u32 arm7_disassembler::opcode_alignment() const { - return arm7_disasm(stream, pc, oprom[3] | (oprom[2] << 8) | (oprom[1] << 16) | (oprom[0] << 24)) | 4; + return m_config->get_t_flag() ? 2 : 4; } -CPU_DISASSEMBLE( arm7thumb ) +offs_t arm7_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - return thumb_disasm(stream, pc, oprom[0] | (oprom[1] << 8)) | 2; -} - -CPU_DISASSEMBLE( arm7thumb_be ) -{ - return thumb_disasm(stream, pc, oprom[1] | (oprom[0] << 8)) | 2; + if(m_config->get_t_flag()) + return thumb_disasm(stream, pc, opcodes.r16(pc)); + else + return arm7_disasm(stream, pc, opcodes.r32(pc)); } diff --git a/src/devices/cpu/arm7/arm7dasm.h b/src/devices/cpu/arm7/arm7dasm.h new file mode 100644 index 00000000000..9f90b47308f --- /dev/null +++ b/src/devices/cpu/arm7/arm7dasm.h @@ -0,0 +1,51 @@ +// license:BSD-3-Clause +// copyright-holders:Steve Ellenoff,R. Belmont,Ryan Holtz +/***************************************************************************** + * + * arm7dasm.c + * Portable ARM7TDMI Core Emulator - Disassembler + * + * Copyright Steve Ellenoff, all rights reserved. + * + * This work is based on: + * #1) 'Atmel Corporation ARM7TDMI (Thumb) Datasheet - January 1999' + * #2) Arm 2/3/6 emulator By Bryan McPhail (bmcphail@tendril.co.uk) and Phil Stroffolino (MAME CORE 0.76) + * + *****************************************************************************/ + +#ifndef MAME_CPU_ARM7_ARM7DASM_H +#define MAME_CPU_ARM7_ARM7DASM_H + +#pragma once + +class arm7_disassembler : public util::disasm_interface +{ +public: + class config { + public: + virtual ~config() = default; + virtual bool get_t_flag() const = 0; + }; + + arm7_disassembler(config *conf); + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + config *m_config; + + void WritePadding(std::ostream &stream, std::streampos start_position); + void DasmCoProc_RT(std::ostream &stream, u32 opcode, const char *pConditionCode, std::streampos start_position); + void DasmCoProc_DT(std::ostream &stream, u32 opcode, const char *pConditionCode, std::streampos start_position); + void DasmCoProc_DO(std::ostream &stream, u32 opcode, const char *pConditionCode, std::streampos start_position); + void WriteImmediateOperand( std::ostream &stream, u32 opcode ); + void WriteDataProcessingOperand( std::ostream &stream, u32 opcode, int printOp0, int printOp1, int printOp2 ); + void WriteRegisterOperand1( std::ostream &stream, u32 opcode ); + void WriteBranchAddress( std::ostream &stream, u32 pc, u32 opcode, bool h_bit ); + u32 arm7_disasm( std::ostream &stream, u32 pc, u32 opcode ); + u32 thumb_disasm(std::ostream &stream, u32 pc, u16 opcode); +}; + + +#endif diff --git a/src/devices/cpu/arm7/arm7ops.cpp b/src/devices/cpu/arm7/arm7ops.cpp index ea10a36be4d..084634a77c0 100644 --- a/src/devices/cpu/arm7/arm7ops.cpp +++ b/src/devices/cpu/arm7/arm7ops.cpp @@ -66,18 +66,12 @@ uint32_t arm7_cpu_device::decodeShift(uint32_t insn, uint32_t *pCarry) if ((insn & 0x80) == 0x80) LOG(("%08x: RegShift ERROR (p36)\n", R15)); #endif - - // see p35 for check on this - //k = GetRegister(k >> 1) & 0x1f; - // Keep only the bottom 8 bits for a Register Shift k = GetRegister(k >> 1) & 0xff; if (k == 0) /* Register shift by 0 is a no-op */ { // LOG(("%08x: NO-OP Regshift\n", R15)); - /* TODO this is wrong for at least ROR by reg with lower - * 5 bits 0 but lower 8 bits non zero */ if (pCarry) *pCarry = GET_CPSR & C_MASK; return rm; @@ -145,11 +139,19 @@ uint32_t arm7_cpu_device::decodeShift(uint32_t insn, uint32_t *pCarry) case 3: /* ROR and RRX */ if (k) { - while (k > 32) - k -= 32; - if (pCarry) - *pCarry = rm & (1 << (k - 1)); - return ROR(rm, k); + k &= 31; + if (k) + { + if (pCarry) + *pCarry = rm & (1 << (k - 1)); + return ROR(rm, k); + } + else + { + if (pCarry) + *pCarry = rm & SIGN_BIT; + return rm; + } } else { @@ -262,22 +264,13 @@ int arm7_cpu_device::storeInc(uint32_t pat, uint32_t rbv, int mode) int arm7_cpu_device::storeDec(uint32_t pat, uint32_t rbv, int mode) { - int i, result = 0, cnt; - // pre-count the # of registers being stored - for (i = 15; i >= 0; i--) - { - if ((pat >> i) & 1) - { - result++; + int const result = population_count_32(pat & 0x0000ffff); - // starting address - rbv -= 4; - } - } + // adjust starting address + rbv -= (result << 2); - cnt = 0; - for (i = 0; i <= 15; i++) + for (int i = 0; i <= 15; i++) { if ((pat >> i) & 1) { @@ -285,8 +278,8 @@ int arm7_cpu_device::storeDec(uint32_t pat, uint32_t rbv, int mode) if (i == 15) /* R15 is plus 12 from address of STM */ LOG(("%08x: StoreDec on R15\n", R15)); #endif - WRITE32(rbv + (cnt * 4), GetModeRegister(mode, i)); - cnt++; + WRITE32(rbv, GetModeRegister(mode, i)); + rbv += 4; } } return result; @@ -387,8 +380,8 @@ void arm7_cpu_device::HandleBranch(uint32_t insn, bool h_bit) off |= (insn & 0x01000000) >> 23; } - /* Save PC into LR if this is a branch with link */ - if (insn & INSN_BL) + /* Save PC into LR if this is a branch with link or a BLX */ + if ((insn & INSN_BL) || ((m_archRev >= 5) && ((insn & 0xfe000000) == 0xfa000000))) { SetRegister(14, R15 + 4); } @@ -501,6 +494,11 @@ void arm7_cpu_device::HandleMemSingle(uint32_t insn) R15 = (R15 & ~0x03FFFFFC) /* N Z C V I F M1 M0 */ | ((data - 4) & 0x03FFFFFC); // LDR, PC takes 2S + 2N + 1I (5 total cycles) ARM7_ICOUNT -= 2; + if ((data & 1) && m_archRev >= 5) + { + set_cpsr(GET_CPSR | T_MASK); + R15--; + } } else { @@ -1380,6 +1378,12 @@ void arm7_cpu_device::HandleMemBlock(uint32_t insn) SwitchMode(temp & 3); } } + else + if ((R15 & 1) && m_archRev >= 5) + { + set_cpsr(GET_CPSR | T_MASK); + R15--; + } // LDM PC - takes 2 extra cycles ARM7_ICOUNT -= 2; } @@ -1437,6 +1441,12 @@ void arm7_cpu_device::HandleMemBlock(uint32_t insn) SwitchMode(temp & 3); } } + else + if ((R15 & 1) && m_archRev >= 5) + { + set_cpsr(GET_CPSR | T_MASK); + R15--; + } // LDM PC - takes 2 extra cycles ARM7_ICOUNT -= 2; } @@ -1650,6 +1660,18 @@ void arm7_cpu_device::arm7ops_0123(uint32_t insn) R15--; } } + else if ((insn & 0x0ff000f0) == 0x01200030) // BLX Rn - v5 + { + // save link address + SetRegister(14, R15 + 4); + + R15 = GetRegister(insn & 0x0f); + // If new PC address has A0 set, switch to Thumb mode + if (R15 & 1) { + set_cpsr(GET_CPSR|T_MASK); + R15--; + } + } else if ((insn & 0x0ff000f0) == 0x01600010) // CLZ - v5 { uint32_t rm = insn&0xf; diff --git a/src/devices/cpu/arm7/arm7thmb.cpp b/src/devices/cpu/arm7/arm7thmb.cpp index 251e5b16408..0d25d62fcf3 100644 --- a/src/devices/cpu/arm7/arm7thmb.cpp +++ b/src/devices/cpu/arm7/arm7thmb.cpp @@ -1557,18 +1557,21 @@ void arm7_cpu_device::tg0e_0(uint32_t pc, uint32_t op) void arm7_cpu_device::tg0e_1(uint32_t pc, uint32_t op) { + /* BLX (LO) */ + uint32_t addr = GetRegister(14); addr += (op & THUMB_BLOP_OFFS) << 1; addr &= 0xfffffffc; - SetRegister(14, (R15 + 4) | 1); + SetRegister(14, (R15 + 2) | 1); R15 = addr; set_cpsr(GET_CPSR & ~T_MASK); } - /* BL */ void arm7_cpu_device::tg0f_0(uint32_t pc, uint32_t op) { + /* BL (HI) */ + uint32_t addr = (op & THUMB_BLOP_OFFS) << 12; if (addr & (1 << 22)) { @@ -1581,6 +1584,8 @@ void arm7_cpu_device::tg0f_0(uint32_t pc, uint32_t op) void arm7_cpu_device::tg0f_1(uint32_t pc, uint32_t op) /* BL */ { + /* BL (LO) */ + uint32_t addr = GetRegister(14) & ~1; addr += (op & THUMB_BLOP_OFFS) << 1; SetRegister(14, (R15 + 2) | 1); diff --git a/src/devices/cpu/asap/asap.cpp b/src/devices/cpu/asap/asap.cpp index e808f3fbb6c..c5d91084a83 100644 --- a/src/devices/cpu/asap/asap.cpp +++ b/src/devices/cpu/asap/asap.cpp @@ -13,6 +13,7 @@ #include "emu.h" #include "asap.h" +#include "asapdasm.h" #include "debugger.h" @@ -183,7 +184,7 @@ void asap_device::device_start() { // get our address spaces m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); // register our state for the debugger state_add(STATE_GENPC, "GENPC", m_pc).noshow(); @@ -300,40 +301,16 @@ void asap_device::state_string_export(const device_state_entry &entry, std::stri //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t asap_device::disasm_min_opcode_bytes() const -{ - return 4; -} - - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t asap_device::disasm_max_opcode_bytes() const -{ - return 12; -} - - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t asap_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *asap_device::create_disassembler() { - extern CPU_DISASSEMBLE( asap ); - return CPU_DISASSEMBLE_NAME(asap)(this, stream, pc, oprom, opram, options); + return new asap_disassembler; } - //************************************************************************** // INLINE HELPERS //************************************************************************** diff --git a/src/devices/cpu/asap/asap.h b/src/devices/cpu/asap/asap.h index 55d78d5b6cf..bfeb7c60350 100644 --- a/src/devices/cpu/asap/asap.h +++ b/src/devices/cpu/asap/asap.h @@ -89,9 +89,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // helpers inline uint32_t readop(offs_t pc); @@ -240,7 +238,7 @@ protected: uint8_t m_irq_state; int m_icount; address_space * m_program; - direct_read_data * m_direct; + direct_read_data<0> *m_direct; // src2val table, registers are at the end uint32_t m_src2val[65536]; diff --git a/src/devices/cpu/asap/asapdasm.cpp b/src/devices/cpu/asap/asapdasm.cpp index 840c50f2635..8f652b6dad4 100644 --- a/src/devices/cpu/asap/asapdasm.cpp +++ b/src/devices/cpu/asap/asapdasm.cpp @@ -9,10 +9,10 @@ ***************************************************************************/ #include "emu.h" -#include "asap.h" +#include "asapdasm.h" -static const char *const reg[32] = +const char *const asap_disassembler::reg[32] = { "0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", @@ -20,12 +20,12 @@ static const char *const reg[32] = "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31" }; -static const char *const setcond[2] = +const char *const asap_disassembler::setcond[2] = { " ", ".c" }; -static const char *const condition[16] = +const char *const asap_disassembler::condition[16] = { "sp", "mz", "gt", "le", "ge", "lt", "hi", "ls", "cc", "cs", "pl", "mi", "ne", "eq", "vc", "vs" }; @@ -35,19 +35,17 @@ static const char *const condition[16] = CODE CODE ***************************************************************************/ -static inline char *src2(uint32_t op, int scale) +std::string asap_disassembler::src2(uint32_t op, int scale) { - static char temp[20]; if ((op & 0xffe0) == 0xffe0) - sprintf(temp, "%s", reg[op & 31]); + return util::string_format("%s", reg[op & 31]); else - sprintf(temp, "$%x", (op & 0xffff) << scale); - return temp; + return util::string_format("$%x", (op & 0xffff) << scale); } -CPU_DISASSEMBLE(asap) +offs_t asap_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - uint32_t op = oprom[0] | (oprom[1] << 8) | (oprom[2] << 16) | (oprom[3] << 24); + uint32_t op = opcodes.r32(pc); int opcode = op >> 27; int cond = (op >> 21) & 1; int rdst = (op >> 22) & 31; @@ -58,21 +56,21 @@ CPU_DISASSEMBLE(asap) switch (opcode) { - case 0x00: util::stream_format(stream, "trap $00"); flags = DASMFLAG_STEP_OVER; break; + case 0x00: util::stream_format(stream, "trap $00"); flags = STEP_OVER; break; case 0x01: util::stream_format(stream, "b%s $%08x", condition[rdst & 15], pc + ((int32_t)(op << 10) >> 8)); break; case 0x02: if ((op & 0x003fffff) == 3) { - uint32_t nextop = oprom[4] | (oprom[5] << 8) | (oprom[6] << 16) | (oprom[7] << 24); + uint32_t nextop = opcodes.r32(pc+4); if ((nextop >> 27) == 0x10 && ((nextop >> 22) & 31) == rdst && (nextop & 0xffff) == 0) { - uint32_t nextnextop = oprom[8] | (oprom[9] << 8) | (oprom[10] << 16) | (oprom[11] << 24); + uint32_t nextnextop = opcodes.r32(pc+8); util::stream_format(stream, "llit%s $%08x,%s", setcond[cond], nextnextop, reg[rdst]); - return 12 | DASMFLAG_STEP_OVER | DASMFLAG_SUPPORTED; + return 12 | STEP_OVER | SUPPORTED; } } if (rdst) { - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); util::stream_format(stream, "bsr %s,$%08x", reg[rdst], pc + ((int32_t)(op << 10) >> 8)); } else @@ -123,24 +121,29 @@ CPU_DISASSEMBLE(asap) case 0x1d: util::stream_format(stream, "putps %s", src2(op,0)); break; case 0x1e: if (rdst && rsrc2_iszero) { - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); util::stream_format(stream, "jsr%s %s,%s", setcond[cond], reg[rdst], reg[rsrc1]); } else if (rdst) { - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); util::stream_format(stream, "jsr%s %s,%s[%s]", setcond[cond], reg[rdst], reg[rsrc1], src2(op,2)); } else if (rsrc2_iszero) { if (rsrc1 == 28) - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; util::stream_format(stream, "jmp%s %s", setcond[cond], reg[rsrc1]); } else util::stream_format(stream, "jmp%s %s[%s]", setcond[cond], reg[rsrc1], src2(op,2)); break; - case 0x1f: util::stream_format(stream, "trap $1f"); flags = DASMFLAG_STEP_OVER; break; + case 0x1f: util::stream_format(stream, "trap $1f"); flags = STEP_OVER; break; } - return 4 | flags | DASMFLAG_SUPPORTED; + return 4 | flags | SUPPORTED; +} + +u32 asap_disassembler::opcode_alignment() const +{ + return 4; } diff --git a/src/devices/cpu/asap/asapdasm.h b/src/devices/cpu/asap/asapdasm.h new file mode 100644 index 00000000000..45ca554368d --- /dev/null +++ b/src/devices/cpu/asap/asapdasm.h @@ -0,0 +1,33 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +/*************************************************************************** + + asapdasm.c + Disassembler for the portable ASAP emulator. + Written by Aaron Giles + +***************************************************************************/ + +#ifndef MAME_CPU_ASAP_ASAPDASM_H +#define MAME_CPU_ASAP_ASAPDASM_H + +#pragma once + +class asap_disassembler : public util::disasm_interface +{ +public: + asap_disassembler() = default; + virtual ~asap_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *const reg[32]; + static const char *const setcond[2]; + static const char *const condition[16]; + std::string src2(uint32_t op, int scale); + +}; + +#endif diff --git a/src/devices/cpu/avr8/avr8.cpp b/src/devices/cpu/avr8/avr8.cpp index 763cdad799e..2f55b4a0317 100644 --- a/src/devices/cpu/avr8/avr8.cpp +++ b/src/devices/cpu/avr8/avr8.cpp @@ -59,6 +59,7 @@ #include "emu.h" #include "avr8.h" +#include "avr8dasm.h" #include "debugger.h" #define VERBOSE_LEVEL (0) @@ -911,36 +912,13 @@ void avr8_device::state_string_export(const device_state_entry &entry, std::stri //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t avr8_device::disasm_min_opcode_bytes() const -{ - return 2; -} - - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t avr8_device::disasm_max_opcode_bytes() const -{ - return 4; -} - - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t avr8_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *avr8_device::create_disassembler() { - extern CPU_DISASSEMBLE( avr8 ); - return CPU_DISASSEMBLE_NAME(avr8)(this, stream, pc, oprom, opram, options); + return new avr8_disassembler; } diff --git a/src/devices/cpu/avr8/avr8.h b/src/devices/cpu/avr8/avr8.h index 0da73a4cc1c..f8c953a3aa3 100644 --- a/src/devices/cpu/avr8/avr8.h +++ b/src/devices/cpu/avr8/avr8.h @@ -123,9 +123,7 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // device_state_interface overrides virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; @@ -848,6 +846,4 @@ enum #define AVR8_SPCR_CPHA_MASK 0x04 #define AVR8_SPCR_SPR_MASK 0x03 -CPU_DISASSEMBLE( avr8 ); - #endif /* __AVR8_H__ */ diff --git a/src/devices/cpu/avr8/avr8dasm.cpp b/src/devices/cpu/avr8/avr8dasm.cpp index cfc99b955d3..5f47198c425 100644 --- a/src/devices/cpu/avr8/avr8dasm.cpp +++ b/src/devices/cpu/avr8/avr8dasm.cpp @@ -7,7 +7,7 @@ */ #include "emu.h" -#include "avr8.h" +#include "avr8dasm.h" #define RD2(op) (((op) >> 4) & 0x0003) #define RD3(op) (((op) >> 4) & 0x0007) @@ -25,11 +25,16 @@ #define ACONST6(op) ((((op) >> 5) & 0x0030) | ((op) & 0x000f)) #define MULCONST2(op) ((((op) >> 6) & 0x0002) | (((op) >> 3) & 0x0001)) -CPU_DISASSEMBLE(avr8) +u32 avr8_disassembler::opcode_alignment() const { - int pos = 0; - uint32_t op = oprom[pos++]; - op |= oprom[pos++] << 8; + return 2; +} + +offs_t avr8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + offs_t base_pc = pc; + uint32_t op = opcodes.r16(pc); + pc += 2; uint32_t addr; const char* register_names[0x40] = {"PINA", "DDRA", "PORTA", "PINB", "DDRB", "PORTB", "PINC", "DDRC", "PORTC", "PIND", "DDRD", "PORTD", "PINE", "DDRE", "PORTE", "PINF", "DDRF", "PORTF", "PING", "DDRG", "PORTG", "TIFR0", "TIFR1", "TIFR2","TIFR3", "TIFR4", "TIFR5", "PCIFR", "EIFR", "EIMSK", "GPIOR0", "EECR", "EEDR", "EEARL", "EEARH", "GTCCR", "TCCR0A", "TCCR0B", "TCNT0", "OCR0A", "OCR0B", "0x29", "GPIOR1", "GPIOR2", "SPCR", "SPSR", "SPDR", "0x2F", "ACSR", "OCDR", "0x32", "SMCR", "MCUSR", "MCUCR", "0x36", "SPMCSR", "0x38", "0x39", "0x3A", "RAMPZ", "EIND", "SPL", "SPH", "SREG"}; @@ -226,8 +231,8 @@ CPU_DISASSEMBLE(avr8) { case 0x0000: op <<= 16; - op |= oprom[pos++]; - op |= oprom[pos++] << 8; + op |= opcodes.r16(pc); + pc += 2; util::stream_format(stream, "LDS R%d, (0x%04x)", RD5(op >> 16), op & 0x0000ffff); break; case 0x0001: @@ -277,8 +282,8 @@ CPU_DISASSEMBLE(avr8) { case 0x0000: op <<= 16; - op |= oprom[pos++]; - op |= oprom[pos++] << 8; + op |= opcodes.r16(pc); + pc += 2; util::stream_format(stream, "STS (0x%04x), R%d", op & 0x0000ffff, RD5(op >> 16)); break; case 0x0001: @@ -410,15 +415,15 @@ CPU_DISASSEMBLE(avr8) case 0x000c: case 0x000d: addr = KCONST22(op) << 16; - addr |= oprom[pos++]; - addr |= oprom[pos++] << 8; + addr |= opcodes.r16(pc); + pc += 2; util::stream_format(stream, "JMP 0x%06x", addr << 1); break; case 0x000e: case 0x000f: addr = KCONST22(op) << 16; - addr |= oprom[pos++]; - addr |= oprom[pos++] << 8; + addr |= opcodes.r16(pc); + pc += 2; util::stream_format(stream, "CALL 0x%06x", addr << 1); break; default: @@ -505,15 +510,15 @@ CPU_DISASSEMBLE(avr8) case 0x000c: case 0x000d: op <<= 16; - op |= oprom[pos++]; - op |= oprom[pos++] << 8; + op |= opcodes.r16(pc); + pc += 2; util::stream_format(stream, "JMP 0x%06x", KCONST22(op) << 1); break; case 0x000e: case 0x000f: op <<= 16; - op |= oprom[pos++]; - op |= oprom[pos++] << 8; + op |= opcodes.r16(pc); + pc += 2; util::stream_format(stream, "CALL 0x%06x", KCONST22(op) << 1); break; } @@ -669,5 +674,5 @@ CPU_DISASSEMBLE(avr8) break; } - return pos | DASMFLAG_SUPPORTED; + return (pc - base_pc) | SUPPORTED; } diff --git a/src/devices/cpu/avr8/avr8dasm.h b/src/devices/cpu/avr8/avr8dasm.h new file mode 100644 index 00000000000..a7f55fdb86b --- /dev/null +++ b/src/devices/cpu/avr8/avr8dasm.h @@ -0,0 +1,24 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + Atmel 8-bit AVR disassembler + + Written by Ryan Holtz +*/ + +#ifndef MAME_CPU_AVR8_AVR8DASM_H +#define MAME_CPU_AVR8_AVR8DASM_H + +#pragma once + +class avr8_disassembler : public util::disasm_interface +{ +public: + avr8_disassembler() = default; + virtual ~avr8_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/capricorn/capricorn.cpp b/src/devices/cpu/capricorn/capricorn.cpp index b25800a6541..b41a3892667 100644 --- a/src/devices/cpu/capricorn/capricorn.cpp +++ b/src/devices/cpu/capricorn/capricorn.cpp @@ -7,6 +7,7 @@ // #include "emu.h" #include "capricorn.h" +#include "capricorn_dasm.h" #include "debugger.h" // Register indexes @@ -169,7 +170,7 @@ void capricorn_cpu_device::device_start() state_add(STATE_GENFLAGS , "GENFLAGS" , m_flags).noshow().formatstr("%9s"); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); save_item(NAME(m_reg)); save_item(NAME(m_arp)); @@ -237,10 +238,9 @@ void capricorn_cpu_device::state_string_export(const device_state_entry &entry, } } -offs_t capricorn_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +util::disasm_interface *capricorn_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE(capricorn); - return CPU_DISASSEMBLE_NAME(capricorn)(this, stream, pc, oprom, opram, options); + return new capricorn_disassembler; } void capricorn_cpu_device::start_mem_burst(ea_addr_t addr) diff --git a/src/devices/cpu/capricorn/capricorn.h b/src/devices/cpu/capricorn/capricorn.h index 7cf11b7f0ae..e20d6875def 100644 --- a/src/devices/cpu/capricorn/capricorn.h +++ b/src/devices/cpu/capricorn/capricorn.h @@ -39,16 +39,12 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual u32 disasm_min_opcode_bytes() const override - { return 1; } - virtual u32 disasm_max_opcode_bytes() const override - { return 9; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; int m_icount; 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; } diff --git a/src/devices/cpu/capricorn/capricorn_dasm.h b/src/devices/cpu/capricorn/capricorn_dasm.h new file mode 100644 index 00000000000..af3525fd03b --- /dev/null +++ b/src/devices/cpu/capricorn/capricorn_dasm.h @@ -0,0 +1,50 @@ +// license:BSD-3-Clause +// copyright-holders:F. Ulivi +// ******************************************************************************** +// * HP Capricorn processor disassembler +// ******************************************************************************** + +#ifndef MAME_CPU_CAPRICORN_CAPRICORN_DASM_H +#define MAME_CPU_CAPRICORN_CAPRICORN_DASM_H + +#pragma once + +class capricorn_disassembler : public util::disasm_interface +{ +public: + capricorn_disassembler() = default; + virtual ~capricorn_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + typedef offs_t (capricorn_disassembler::*fn_dis_param)(std::ostream &stream, offs_t pc, const data_buffer &opcodes); + + struct dis_entry_t { + 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; + }; + + static const dis_entry_t dis_table[]; + + void direct_addr(std::ostream &stream, offs_t pc, const data_buffer &opcodes); + offs_t param_arp_drp(std::ostream &stream, offs_t pc, const data_buffer &opcodes); + offs_t param_dr(std::ostream &stream, offs_t pc, const data_buffer &opcodes); + offs_t param_dr_ar(std::ostream &stream, offs_t pc, const data_buffer &opcodes); + offs_t param_dr_lit(std::ostream &stream, offs_t pc, const data_buffer &opcodes); + offs_t param_dr_lit_dir(std::ostream &stream, offs_t pc,const data_buffer &opcodes); + offs_t param_dr_idx_dir(std::ostream &stream, offs_t pc,const data_buffer &opcodes); + offs_t param_xr_lit(std::ostream &stream, offs_t pc,const data_buffer &opcodes); + offs_t param_lit_dir(std::ostream &stream, offs_t pc,const data_buffer &opcodes); + offs_t param_dr_id_ar(std::ostream &stream, offs_t pc, const data_buffer &opcodes); + offs_t param_jmp_off(std::ostream &stream, offs_t pc, const data_buffer &opcodes); + +}; + +#endif diff --git a/src/devices/cpu/ccpu/ccpu.cpp b/src/devices/cpu/ccpu/ccpu.cpp index cc13d8e9125..467b5eb2402 100644 --- a/src/devices/cpu/ccpu/ccpu.cpp +++ b/src/devices/cpu/ccpu/ccpu.cpp @@ -12,6 +12,7 @@ #include "emu.h" #include "ccpu.h" +#include "ccpudasm.h" #include "debugger.h" @@ -24,8 +25,8 @@ DEFINE_DEVICE_TYPE(CCPU, ccpu_cpu_device, "ccpu", "Cinematronics CPU") #define READOP(a) (m_direct->read_byte(a)) -#define RDMEM(a) (m_data->read_word((a) * 2) & 0xfff) -#define WRMEM(a,v) (m_data->write_word((a) * 2, (v))) +#define RDMEM(a) (m_data->read_word((a) & 0xfff)) +#define WRMEM(a,v) (m_data->write_word((a), (v))) #define READPORT(a) (m_io->read_byte(a)) #define WRITEPORT(a,v) (m_io->write_byte((a), (v))) @@ -106,7 +107,7 @@ void ccpu_cpu_device::device_start() assert(!m_vector_callback.isnull()); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_data = &space(AS_DATA); m_io = &space(AS_IO); @@ -695,8 +696,7 @@ void ccpu_cpu_device::execute_run() } -offs_t ccpu_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *ccpu_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( ccpu ); - return CPU_DISASSEMBLE_NAME(ccpu)(this, stream, pc, oprom, opram, options); + return new ccpu_disassembler; } diff --git a/src/devices/cpu/ccpu/ccpu.h b/src/devices/cpu/ccpu/ccpu.h index 3a74c21a1fe..4cad4d66965 100644 --- a/src/devices/cpu/ccpu/ccpu.h +++ b/src/devices/cpu/ccpu/ccpu.h @@ -78,9 +78,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 3; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; address_space_config m_program_config; address_space_config m_data_config; @@ -111,7 +109,7 @@ protected: int m_icount; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_data; address_space *m_io; diff --git a/src/devices/cpu/ccpu/ccpudasm.cpp b/src/devices/cpu/ccpu/ccpudasm.cpp index bb843374c2b..feb4ebcb58d 100644 --- a/src/devices/cpu/ccpu/ccpudasm.cpp +++ b/src/devices/cpu/ccpu/ccpudasm.cpp @@ -11,13 +11,17 @@ ***************************************************************************/ #include "emu.h" -#include "ccpu.h" +#include "ccpudasm.h" +u32 ccpu_disassembler::opcode_alignment() const +{ + return 1; +} -CPU_DISASSEMBLE(ccpu) +offs_t ccpu_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { unsigned startpc = pc; - uint8_t opcode = oprom[pc++ - startpc]; + uint8_t opcode = opcodes.r8(pc++); uint8_t tempval; switch (opcode) @@ -40,7 +44,7 @@ CPU_DISASSEMBLE(ccpu) /* A8I */ case 0x20: - util::stream_format(stream, "A8I $%X", oprom[pc++ - startpc]); + util::stream_format(stream, "A8I $%X", opcodes.r8(pc++)); break; /* A4I */ @@ -53,7 +57,7 @@ CPU_DISASSEMBLE(ccpu) /* S8I */ case 0x30: - util::stream_format(stream, "S8I $%X", oprom[pc++ - startpc]); + util::stream_format(stream, "S8I $%X", opcodes.r8(pc++)); break; /* S4I */ @@ -69,7 +73,7 @@ CPU_DISASSEMBLE(ccpu) case 0x44: case 0x45: case 0x46: case 0x47: case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f: - tempval = oprom[pc++ - startpc]; + tempval = opcodes.r8(pc++); util::stream_format(stream, "LPAI $%03X", (opcode & 0x0f) + (tempval & 0xf0) + ((tempval & 0x0f) << 8)); break; @@ -326,5 +330,5 @@ CPU_DISASSEMBLE(ccpu) break; } - return (pc - startpc) | DASMFLAG_SUPPORTED; + return (pc - startpc) | SUPPORTED; } diff --git a/src/devices/cpu/ccpu/ccpudasm.h b/src/devices/cpu/ccpu/ccpudasm.h new file mode 100644 index 00000000000..b9c4b83c6e6 --- /dev/null +++ b/src/devices/cpu/ccpu/ccpudasm.h @@ -0,0 +1,28 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +/*************************************************************************** + + ccpudasm.c + Core implementation for the portable Cinematronics CPU disassembler. + + Written by Aaron Giles + Special thanks to Zonn Moore for his detailed documentation. + +***************************************************************************/ + +#ifndef MAME_CPU_CCPU_CCPUDASM_H +#define MAME_CPU_CCPU_CCPUDASM_H + +#pragma once + +class ccpu_disassembler : public util::disasm_interface +{ +public: + ccpu_disassembler() = default; + virtual ~ccpu_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/clipper/clipper.cpp b/src/devices/cpu/clipper/clipper.cpp index c2d057d8d35..d9812b4a987 100644 --- a/src/devices/cpu/clipper/clipper.cpp +++ b/src/devices/cpu/clipper/clipper.cpp @@ -4,15 +4,13 @@ /* * An implementation of the Fairchild/Intergraph CLIPPER CPU family. * - * Primary source: http://bitsavers.trailing-edge.com/pdf/fairchild/clipper/Clipper_Instruction_Set_Oct85.pdf + * Primary source: http://bitsavers.org/pdf/fairchild/clipper/Clipper_Instruction_Set_Oct85.pdf * * TODO: * - save/restore state - * - unimplemented instructions - * - C100, C300, C400 variants + * - unimplemented C400 instructions * - correct boot logic * - condition codes for multiply instructions - * - most cpu traps/faults * - instruction timing * - big endian support (not present in the wild) */ @@ -20,11 +18,12 @@ #include "emu.h" #include "debugger.h" #include "clipper.h" +#include "clipperd.h" #define LOG_GENERAL (1U << 0) -#define LOG_INTERRUPT (1U << 1) +#define LOG_EXCEPTION (1U << 1) -//#define VERBOSE (LOG_GENERAL | LOG_INTERRUPT) +//#define VERBOSE (LOG_GENERAL | LOG_EXCEPTION) #include "logmacro.h" @@ -57,25 +56,30 @@ DEFINE_DEVICE_TYPE(CLIPPER_C300, clipper_c300_device, "clipper_c300", "C300 CLIP DEFINE_DEVICE_TYPE(CLIPPER_C400, clipper_c400_device, "clipper_c400", "C400 CLIPPER") clipper_c100_device::clipper_c100_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : clipper_device(mconfig, CLIPPER_C100, tag, owner, clock, 0) { } + : clipper_device(mconfig, CLIPPER_C100, tag, owner, clock, ENDIANNESS_LITTLE, 0) +{ +} clipper_c300_device::clipper_c300_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : clipper_device(mconfig, CLIPPER_C300, tag, owner, clock, 0) { } + : clipper_device(mconfig, CLIPPER_C300, tag, owner, clock, ENDIANNESS_LITTLE, 0) +{ +} clipper_c400_device::clipper_c400_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : clipper_device(mconfig, CLIPPER_C400, tag, owner, clock, SSW_ID_C400R4) { } - -clipper_device::clipper_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, const u32 cpuid) - : cpu_device(mconfig, type, tag, owner, clock), - m_pc(0), - m_psw(0), - m_ssw(cpuid), - m_r(m_rs), - m_insn_config("insn", ENDIANNESS_LITTLE, 32, 32, 0), - m_data_config("data", ENDIANNESS_LITTLE, 32, 32, 0), - m_insn(nullptr), - m_data(nullptr), - m_icount(0) + : clipper_device(mconfig, CLIPPER_C400, tag, owner, clock, ENDIANNESS_LITTLE, SSW_ID_C400R4) +{ +} + +clipper_device::clipper_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, const endianness_t endianness, const u32 cpuid) + : cpu_device(mconfig, type, tag, owner, clock) + , m_insn_config("insn", endianness, 32, 32, 0) + , m_data_config("data", endianness, 32, 32, 0) + , m_insn(nullptr) + , m_data(nullptr) + , m_icount(0) + , m_psw(endianness == ENDIANNESS_BIG ? PSW_BIG : 0) + , m_ssw(cpuid) + , m_r(m_rs) { } @@ -119,58 +123,29 @@ void clipper_device::device_start() save_item(NAME(m_ru)); save_item(NAME(m_rs)); save_item(NAME(m_f)); + save_item(NAME(m_fp_pc)); + save_item(NAME(m_fp_dst)); save_item(NAME(m_nmi)); save_item(NAME(m_irq)); save_item(NAME(m_ivec)); - state_add(STATE_GENPC, "GENPC", m_pc).noshow(); - state_add(STATE_GENPCBASE, "CURPC", m_pc).noshow(); + state_add(STATE_GENPC, "GENPC", m_ip).noshow(); + state_add(STATE_GENPCBASE, "CURPC", m_ip).noshow(); state_add(STATE_GENSP, "GENSP", m_r[15]).noshow(); state_add(STATE_GENFLAGS, "GENFLAGS", m_psw).mask(0xf).formatstr("%4s").noshow(); - state_add(CLIPPER_PC, "pc", m_pc); + state_add(CLIPPER_PC, "pc", m_ip); state_add(CLIPPER_PSW, "psw", m_psw); state_add(CLIPPER_SSW, "ssw", m_ssw); - state_add(CLIPPER_R0, "r0", m_r[0]); - state_add(CLIPPER_R1, "r1", m_r[1]); - state_add(CLIPPER_R2, "r2", m_r[2]); - state_add(CLIPPER_R3, "r3", m_r[3]); - state_add(CLIPPER_R4, "r4", m_r[4]); - state_add(CLIPPER_R5, "r5", m_r[5]); - state_add(CLIPPER_R6, "r6", m_r[6]); - state_add(CLIPPER_R7, "r7", m_r[7]); - state_add(CLIPPER_R8, "r8", m_r[8]); - state_add(CLIPPER_R9, "r9", m_r[9]); - state_add(CLIPPER_R10, "r10", m_r[10]); - state_add(CLIPPER_R11, "r11", m_r[11]); - state_add(CLIPPER_R12, "r12", m_r[12]); - state_add(CLIPPER_R13, "r13", m_r[13]); - state_add(CLIPPER_R14, "r14", m_r[14]); - state_add(CLIPPER_R15, "r15", m_r[15]); - - state_add(CLIPPER_F0, "f0", m_f[0]); - state_add(CLIPPER_F1, "f1", m_f[1]); - state_add(CLIPPER_F2, "f2", m_f[2]); - state_add(CLIPPER_F3, "f3", m_f[3]); - state_add(CLIPPER_F4, "f4", m_f[4]); - state_add(CLIPPER_F5, "f5", m_f[5]); - state_add(CLIPPER_F6, "f6", m_f[6]); - state_add(CLIPPER_F7, "f7", m_f[7]); - - // C400 has 8 additional floating point registers - if (type() == CLIPPER_C400) - { - state_add(CLIPPER_F8, "f8", m_f[8]); - state_add(CLIPPER_F9, "f9", m_f[9]); - state_add(CLIPPER_F10, "f10", m_f[10]); - state_add(CLIPPER_F11, "f11", m_f[11]); - state_add(CLIPPER_F12, "f12", m_f[12]); - state_add(CLIPPER_F13, "f13", m_f[13]); - state_add(CLIPPER_F14, "f14", m_f[14]); - state_add(CLIPPER_F15, "f15", m_f[15]); - } + // integer regsters + for (int i = 0; i < get_ireg_count(); i++) + state_add(CLIPPER_IREG + i, util::string_format("r%d", i).c_str(), m_r[i]); + + // floating point registers + for (int i = 0; i < get_freg_count(); i++) + state_add(CLIPPER_FREG + i, util::string_format("f%d", i).c_str(), m_f[i]); } void clipper_device::device_reset() @@ -180,20 +155,19 @@ void clipper_device::device_reset() * psw: T cleared, BIG set from hardware, others undefined * ssw: EI, TP, M, U, K, KU, UU, P cleared, ID set from hardware, others undefined */ - m_psw = 0; - set_ssw(0); - m_r = SSW(U) ? m_ru : m_rs; - - // we'll opt to clear the integer and floating point registers too - memset(m_r, 0, sizeof(s32)*16); - memset(m_f, 0, sizeof(m_f)); + // clear the psw and ssw + set_psw(0); + set_ssw(0); // FIXME: figure out how to branch to the boot code properly - m_pc = 0x7f100000; + m_pc = 0x6000; + m_ip = 0x7f100000; + m_irq = CLEAR_LINE; m_nmi = CLEAR_LINE; m_ivec = 0; + m_exception = 0; } void clipper_device::state_string_export(const device_state_entry &entry, std::string &str) const @@ -212,20 +186,18 @@ void clipper_device::state_string_export(const device_state_entry &entry, std::s void clipper_device::execute_run() { - u16 insn; - // check for non-maskable and prioritised interrupts if (m_nmi) { // acknowledge non-maskable interrupt standard_irq_callback(INPUT_LINE_NMI); - LOGMASKED(LOG_INTERRUPT, "non-maskable interrupt\n"); - m_pc = intrap(EXCEPTION_INTERRUPT_BASE, m_pc); + LOGMASKED(LOG_EXCEPTION, "non-maskable interrupt\n"); + m_ip = intrap(EXCEPTION_INTERRUPT_BASE, m_ip); } else if (SSW(EI) && m_irq) { - LOGMASKED(LOG_INTERRUPT, "received prioritised interrupt ivec 0x%02x\n", m_ivec); + LOGMASKED(LOG_EXCEPTION, "received prioritised interrupt ivec 0x%02x\n", m_ivec); // allow equal/higher priority interrupts if ((m_ivec & IVEC_LEVEL) <= SSW(IL)) @@ -233,23 +205,74 @@ void clipper_device::execute_run() // acknowledge interrupt standard_irq_callback(INPUT_LINE_IRQ0); - LOGMASKED(LOG_INTERRUPT, "transferring control to ivec 0x%02x\n", m_ivec); - m_pc = intrap(EXCEPTION_INTERRUPT_BASE + m_ivec * 8, m_pc); + LOGMASKED(LOG_EXCEPTION, "transferring control to ivec 0x%02x\n", m_ivec); + m_ip = intrap(EXCEPTION_INTERRUPT_BASE + m_ivec * 8, m_ip); } } - while (m_icount > 0) { + while (m_icount > 0) + { + debugger_instruction_hook(this, m_ip); + + // fetch and decode an instruction + if (decode_instruction()) + { + float_exception_flags = 0; - debugger_instruction_hook(this, m_pc); + // execute instruction + execute_instruction(); - // fetch instruction word - insn = m_insn->read_word(m_pc + 0); + // check floating point exceptions + if (float_exception_flags) + fp_exception(); + } - // decode instruction - decode_instruction(insn); + if (m_exception) + { + /* + * For traced instructions which are interrupted or cause traps, the TP + * flag is set by hardware when the interrupt or trap occurs to ensure + * that the trace trap will occur immediately after the interrupt or other + * trap has been serviced. + */ + // FIXME: don't know why/when the trace pending flag is needed + if (PSW(T)) + m_ssw |= SSW_TP; + + switch (m_exception) + { + // data memory trap group + case EXCEPTION_D_CORRECTED_MEMORY_ERROR: + case EXCEPTION_D_UNCORRECTABLE_MEMORY_ERROR: + case EXCEPTION_D_ALIGNMENT_FAULT: + case EXCEPTION_D_PAGE_FAULT: + case EXCEPTION_D_READ_PROTECT_FAULT: + case EXCEPTION_D_WRITE_PROTECT_FAULT: + + // instruction memory trap group + case EXCEPTION_I_CORRECTED_MEMORY_ERROR: + case EXCEPTION_I_UNCORRECTABLE_MEMORY_ERROR: + case EXCEPTION_I_ALIGNMENT_FAULT: + case EXCEPTION_I_PAGE_FAULT: + case EXCEPTION_I_EXECUTE_PROTECT_FAULT: + + // illegal operation trap group + case EXCEPTION_ILLEGAL_OPERATION: + case EXCEPTION_PRIVILEGED_INSTRUCTION: + // return address is faulting instruction + m_ip = intrap(m_exception, m_pc); + break; + + default: + // return address is following instruction + m_ip = intrap(m_exception, m_ip); + break; + } + } - // execute instruction, return next pc - m_pc = execute_instruction(); + // FIXME: trace trap logic not working properly yet + //else if (PSW(T)) + // m_ip = intrap(EXCEPTION_TRACE, m_ip); // FIXME: some instructions take longer (significantly) than one cycle // and also the timings are often slower for the C100 and C300 @@ -283,13 +306,29 @@ device_memory_interface::space_config_vector clipper_device::memory_space_config }; } +WRITE16_MEMBER(clipper_device::set_exception) +{ + LOGMASKED(LOG_EXCEPTION, "external exception 0x%04x triggered\n", data); + + // check if corrected memory errors are masked + if (!SSW(ECM) && (data == EXCEPTION_D_CORRECTED_MEMORY_ERROR || data == EXCEPTION_I_CORRECTED_MEMORY_ERROR)) + return; + + m_exception = data; +} + /* - * This function decodes instruction operands and computes effective addresses (for + * Fetch and decode an instruction and compute an effective address (for * instructions with addressing modes). The results are contained in the m_info * structure to simplify passing between here and execute_instruction(). */ -void clipper_device::decode_instruction (u16 insn) +bool clipper_device::decode_instruction() { + // fetch instruction word + u16 insn = m_insn->read_word(m_ip + 0); + if (m_exception) + return false; + // decode the primary parcel m_info.opcode = insn >> 8; m_info.subopcode = insn & 0xff; @@ -299,16 +338,20 @@ void clipper_device::decode_instruction (u16 insn) // initialise the other fields m_info.imm = 0; m_info.macro = 0; - m_info.size = 0; m_info.address = 0; + // default instruction size is 2 bytes + int size = 2; + if ((insn & 0xf800) == 0x3800) { // instruction has a 16 bit immediate operand // fetch 16 bit immediate and sign extend - m_info.imm = (s16)m_insn->read_word(m_pc + 2); - m_info.size = 4; + m_info.imm = (s16)m_insn->read_word(m_ip + 2); + if (m_exception) + return false; + size = 4; } else if ((insn & 0xd300) == 0x8300) { @@ -316,14 +359,18 @@ void clipper_device::decode_instruction (u16 insn) if (insn & 0x0080) { // fetch 16 bit immediate and sign extend - m_info.imm = (s16)m_insn->read_word(m_pc + 2); - m_info.size = 4; + m_info.imm = (s16)m_insn->read_word(m_ip + 2); + if (m_exception) + return false; + size = 4; } else { - // fetch 32 bit immediate and sign extend - m_info.imm = (s32)m_insn->read_dword_unaligned(m_pc + 2); - m_info.size = 6; + // fetch 32 bit immediate + m_info.imm = m_insn->read_dword_unaligned(m_ip + 2); + if (m_exception) + return false; + size = 6; } } else if ((insn & 0xc000) == 0x4000) @@ -337,87 +384,103 @@ void clipper_device::decode_instruction (u16 insn) switch (insn & 0x00f0) { case ADDR_MODE_PC32: - m_info.address = m_pc + (s32)m_insn->read_dword_unaligned(m_pc + 2); - m_info.size = 6; + m_info.address = m_ip + m_insn->read_dword_unaligned(m_ip + 2); + if (m_exception) + return false; + size = 6; break; case ADDR_MODE_ABS32: - m_info.address = m_insn->read_dword_unaligned(m_pc + 2); - m_info.size = 6; + m_info.address = m_insn->read_dword_unaligned(m_ip + 2); + if (m_exception) + return false; + size = 6; break; case ADDR_MODE_REL32: - m_info.r2 = m_insn->read_word(m_pc + 2) & 0xf; - m_info.address = m_r[insn & 0xf] + (s32)m_insn->read_dword_unaligned(m_pc + 4); - m_info.size = 8; + m_info.r2 = m_insn->read_word(m_ip + 2) & 0xf; + if (m_exception) + return false; + + m_info.address = m_r[insn & 0xf] + m_insn->read_dword_unaligned(m_ip + 4); + if (m_exception) + return false; + size = 8; break; case ADDR_MODE_PC16: - m_info.address = m_pc + (s16)m_insn->read_word(m_pc + 2); - m_info.size = 4; + m_info.address = m_ip + (s16)m_insn->read_word(m_ip + 2); + if (m_exception) + return false; + size = 4; break; case ADDR_MODE_REL12: - temp = m_insn->read_word(m_pc + 2); + temp = m_insn->read_word(m_ip + 2); + if (m_exception) + return false; m_info.r2 = temp & 0xf; m_info.address = m_r[insn & 0xf] + ((s16)temp >> 4); - m_info.size = 4; + size = 4; break; case ADDR_MODE_ABS16: - m_info.address = (s16)m_insn->read_word(m_pc + 2); - m_info.size = 4; + m_info.address = (s16)m_insn->read_word(m_ip + 2); + if (m_exception) + return false; + size = 4; break; case ADDR_MODE_PCX: - temp = m_insn->read_word(m_pc + 2); + temp = m_insn->read_word(m_ip + 2); + if (m_exception) + return false; m_info.r2 = temp & 0xf; - m_info.address = m_pc + m_r[(temp >> 4) & 0xf]; - m_info.size = 4; + m_info.address = m_ip + m_r[(temp >> 4) & 0xf]; + size = 4; break; case ADDR_MODE_RELX: - temp = m_insn->read_word(m_pc + 2); + temp = m_insn->read_word(m_ip + 2); + if (m_exception) + return false; m_info.r2 = temp & 0xf; m_info.address = m_r[insn & 0xf] + m_r[(temp >> 4) & 0xf]; - m_info.size = 4; + size = 4; break; default: - LOG("illegal addressing mode pc 0x%08x\n", m_pc); - machine().debug_break(); - break; + m_exception = EXCEPTION_ILLEGAL_OPERATION; + return false; } } else - { // relative addressing mode m_info.address = m_r[m_info.r1]; - m_info.size = 2; - } } else if ((insn & 0xfd00) == 0xb400) { // macro instructions - m_info.macro = m_insn->read_word(m_pc + 2); - m_info.size = 4; + m_info.macro = m_insn->read_word(m_ip + 2); + if (m_exception) + return false; + size = 4; } - else - // all other instruction formats are 16 bits - m_info.size = 2; + + // instruction fetch and decode complete + m_pc = m_ip; + m_ip = m_pc + size; + + return true; } -int clipper_device::execute_instruction () +void clipper_device::execute_instruction() { - // the address of the next instruction - u32 next_pc; - - // next instruction follows the current one by default, but - // may be changed for branch, call or trap instructions - next_pc = m_pc + m_info.size; + // memory fetch temporary + u64 temp; switch (m_info.opcode) { @@ -429,12 +492,9 @@ int clipper_device::execute_instruction () // treated as a noop if target ssw in user mode // R1 == 3 means "fast" mode - avoids pipeline flush if (R1 == 0) - m_psw = m_r[R2]; + set_psw(m_r[R2]); else if (!SSW(U) && (R1 == 1 || R1 == 3)) - { set_ssw(m_r[R2]); - m_r = SSW(U) ? m_ru : m_rs; - } // FLAGS: CVZN break; case 0x11: @@ -447,12 +507,16 @@ int clipper_device::execute_instruction () break; case 0x12: // calls: call supervisor - next_pc = intrap(EXCEPTION_SUPERVISOR_CALL_BASE + (m_info.subopcode & 0x7f) * 8, next_pc); + m_exception = EXCEPTION_SUPERVISOR_CALL_BASE + (m_info.subopcode & 0x7f) * 8; break; case 0x13: // ret: return from subroutine - next_pc = m_data->read_dword(m_r[R2]); - m_r[R2] += 4; + temp = m_data->read_dword(m_r[R2]); + if (!m_exception) + { + m_ip = temp; + m_r[R2] += 4; + } // TRAPS: C,U,A,P,R break; case 0x14: @@ -465,235 +529,244 @@ int clipper_device::execute_instruction () case 0x16: // popw: pop word m_r[R1] += 4; - m_r[R2] = m_data->read_dword(m_r[R1] - 4); + temp = m_data->read_dword(m_r[R1] - 4); + if (!m_exception) + m_r[R2] = temp; // TRAPS: C,U,A,P,R break; case 0x20: // adds: add single floating - *((float *)&m_f[R2]) += *((float *)&m_f[R1]); + set_fp(R2, float32_add(get_fp32(R2), get_fp32(R1)), F_IVUX); // TRAPS: F_IVUX break; case 0x21: // subs: subtract single floating - *((float *)&m_f[R2]) -= *((float *)&m_f[R1]); + set_fp(R2, float32_sub(get_fp32(R2), get_fp32(R1)), F_IVUX); // TRAPS: F_IVUX break; case 0x22: // addd: add double floating - m_f[R2] += m_f[R1]; + set_fp(R2, float64_add(get_fp64(R2), get_fp64(R1)), F_IVUX); // TRAPS: F_IVUX break; case 0x23: // subd: subtract double floating - m_f[R2] -= m_f[R1]; + set_fp(R2, float64_sub(get_fp64(R2), get_fp64(R1)), F_IVUX); // TRAPS: F_IVUX break; case 0x24: // movs: move single floating - *((float *)&m_f[R2]) = *((float *)&m_f[R1]); + set_fp(R2, get_fp32(R1), F_NONE); break; case 0x25: // cmps: compare single floating - FLAGS(0, 0, *((float *)&m_f[R2]) == *((float *)&m_f[R1]), *((float *)&m_f[R2]) < *((float *)&m_f[R1])) + FLAGS(0, 0, float32_eq(get_fp32(R2), get_fp32(R1)), float32_lt(get_fp32(R2), get_fp32(R1))) + // flag unordered + if (float_exception_flags & float_flag_invalid) + m_psw |= PSW_Z | PSW_N; + float_exception_flags &= F_NONE; break; case 0x26: // movd: move double floating - m_f[R2] = m_f[R1]; + set_fp(R2, get_fp64(R1), F_NONE); break; case 0x27: // cmpd: compare double floating - FLAGS(0, 0, m_f[R2] == m_f[R1], m_f[R2] < m_f[R1]) - // FLAGS: 00ZN + FLAGS(0, 0, float64_eq(get_fp64(R2), get_fp64(R1)), float64_lt(get_fp64(R2), get_fp64(R1))) + // flag unordered + if (float_exception_flags & float_flag_invalid) + m_psw |= PSW_Z | PSW_N; + float_exception_flags &= F_NONE; break; case 0x28: // muls: multiply single floating - *((float *)&m_f[R2]) *= *((float *)&m_f[R1]); + set_fp(R2, float32_mul(get_fp32(R2), get_fp32(R1)), F_IVUX); // TRAPS: F_IVUX break; case 0x29: // divs: divide single floating - *((float *)&m_f[R2]) /= *((float *)&m_f[R1]); + set_fp(R2, float32_div(get_fp32(R2), get_fp32(R1)), F_IVDUX); // TRAPS: F_IVDUX break; case 0x2a: // muld: multiply double floating - m_f[R2] *= m_f[R1]; + set_fp(R2, float64_mul(get_fp64(R2), get_fp64(R1)), F_IVUX); // TRAPS: F_IVUX break; case 0x2b: // divd: divide double floating - m_f[R2] /= m_f[R1]; + set_fp(R2, float64_div(get_fp64(R2), get_fp64(R1)), F_IVDUX); // TRAPS: F_IVDUX break; case 0x2c: // movsw: move single floating to word - m_r[R2] = *((s32 *)&m_f[R1]); + m_r[R2] = get_fp32(R1); break; case 0x2d: // movws: move word to single floating - *((s32 *)&m_f[R2]) = m_r[R1]; + set_fp(R2, m_r[R1], F_NONE); break; case 0x2e: // movdl: move double floating to longword - ((double *)m_r)[R2 >> 1] = m_f[R1]; + ((u64 *)m_r)[R2 >> 1] = get_fp64(R1); break; case 0x2f: // movld: move longword to double floating - m_f[R2] = ((double *)m_r)[R1 >> 1]; + set_fp(R2, ((u64 *)m_r)[R1 >> 1], F_NONE); break; case 0x30: // shaw: shift arithmetic word - if (m_r[R1] > 0) + if ((s32)m_r[R1] > 0) { // save the bits that will be shifted out plus new sign bit - s32 v = m_r[R2] >> (31 - m_r[R1]); + s32 v = (s32)m_r[R2] >> (31 - m_r[R1]); m_r[R2] <<= m_r[R1]; // overflow is set if sign changes during shift - FLAGS(0, v != 0 && v != -1, m_r[R2] == 0, m_r[R2] < 0) + FLAGS(0, v != 0 && v != -1, m_r[R2] == 0, (s32)m_r[R2] < 0) } else { - m_r[R2] >>= -m_r[R1]; - FLAGS(0, 0, m_r[R2] == 0, m_r[R2] < 0) + ((s32 *)m_r)[R2] >>= -m_r[R1]; + FLAGS(0, 0, m_r[R2] == 0, (s32)m_r[R2] < 0) } // FLAGS: 0VZN break; case 0x31: // shal: shift arithmetic longword - if (m_r[R1] > 0) + if ((s32)m_r[R1] > 0) { // save the bits that will be shifted out plus new sign bit s64 v = ((s64 *)m_r)[R2 >> 1] >> (63 - m_r[R1]); - ((s64 *)m_r)[R2 >> 1] <<= m_r[R1]; + ((u64 *)m_r)[R2 >> 1] <<= m_r[R1]; // overflow is set if sign changes during shift - FLAGS(0, v != 0 && v != -1, ((s64 *)m_r)[R2 >> 1] == 0, ((s64 *)m_r)[R2 >> 1] < 0) + FLAGS(0, v != 0 && v != -1, ((u64 *)m_r)[R2 >> 1] == 0, ((s64 *)m_r)[R2 >> 1] < 0) } else { ((s64 *)m_r)[R2 >> 1] >>= -m_r[R1]; - FLAGS(0, 0, ((s64 *)m_r)[R2 >> 1] == 0, ((s64 *)m_r)[R2 >> 1] < 0) + FLAGS(0, 0, ((u64 *)m_r)[R2 >> 1] == 0, ((s64 *)m_r)[R2 >> 1] < 0) } // FLAGS: 0VZN break; case 0x32: // shlw: shift logical word - if (m_r[R1] > 0) + if ((s32)m_r[R1] > 0) m_r[R2] <<= m_r[R1]; else - ((u32 *)m_r)[R2] >>= -m_r[R1]; + m_r[R2] >>= -m_r[R1]; // FLAGS: 00ZN - FLAGS(0, 0, m_r[R2] == 0, m_r[R2] < 0); + FLAGS(0, 0, m_r[R2] == 0, (s32)m_r[R2] < 0); break; case 0x33: // shll: shift logical longword - if (m_r[R1] > 0) + if ((s32)m_r[R1] > 0) ((u64 *)m_r)[R2 >> 1] <<= m_r[R1]; else ((u64 *)m_r)[R2 >> 1] >>= -m_r[R1]; // FLAGS: 00ZN - FLAGS(0, 0, ((s64 *)m_r)[R2 >> 1] == 0, ((s64 *)m_r)[R2 >> 1] < 0); + FLAGS(0, 0, ((u64 *)m_r)[R2 >> 1] == 0, ((s64 *)m_r)[R2 >> 1] < 0); break; case 0x34: // rotw: rotate word - if (m_r[R1] > 0) + if ((s32)m_r[R1] > 0) m_r[R2] = rotl32(m_r[R2], m_r[R1]); else m_r[R2] = rotr32(m_r[R2], -m_r[R1]); // FLAGS: 00ZN - FLAGS(0, 0, m_r[R2] == 0, m_r[R2] < 0); + FLAGS(0, 0, m_r[R2] == 0, (s32)m_r[R2] < 0); break; case 0x35: // rotl: rotate longword - if (m_r[R1] > 0) + if ((s32)m_r[R1] > 0) ((u64 *)m_r)[R2 >> 1] = rotl64(((u64 *)m_r)[R2 >> 1], m_r[R1]); else ((u64 *)m_r)[R2 >> 1] = rotr64(((u64 *)m_r)[R2 >> 1], -m_r[R1]); // FLAGS: 00ZN - FLAGS(0, 0, ((s64 *)m_r)[R2 >> 1] == 0, ((s64 *)m_r)[R2 >> 1] < 0); + FLAGS(0, 0, ((u64 *)m_r)[R2 >> 1] == 0, ((s64 *)m_r)[R2 >> 1] < 0); break; case 0x38: // shai: shift arithmetic immediate - if (m_info.imm > 0) + if ((s32)m_info.imm > 0) { // save the bits that will be shifted out plus new sign bit - s32 v = m_r[R2] >> (31 - m_info.imm); + s32 v = (s32)m_r[R2] >> (31 - m_info.imm); m_r[R2] <<= m_info.imm; // overflow is set if sign changes during shift - FLAGS(0, v != 0 && v != -1, m_r[R2] == 0, m_r[R2] < 0) + FLAGS(0, v != 0 && v != -1, m_r[R2] == 0, (s32)m_r[R2] < 0) } else { - m_r[R2] >>= -m_info.imm; - FLAGS(0, 0, m_r[R2] == 0, m_r[R2] < 0) + ((s32 *)m_r)[R2] >>= -m_info.imm; + FLAGS(0, 0, m_r[R2] == 0, (s32)m_r[R2] < 0) } // FLAGS: 0VZN // TRAPS: I break; case 0x39: // shali: shift arithmetic longword immediate - if (m_info.imm > 0) + if ((s32)m_info.imm > 0) { // save the bits that will be shifted out plus new sign bit s64 v = ((s64 *)m_r)[R2 >> 1] >> (63 - m_info.imm); - ((s64 *)m_r)[R2 >> 1] <<= m_info.imm; + ((u64 *)m_r)[R2 >> 1] <<= m_info.imm; // overflow is set if sign changes during shift - FLAGS(0, v != 0 && v != -1, ((s64 *)m_r)[R2 >> 1] == 0, ((s64 *)m_r)[R2 >> 1] < 0) + FLAGS(0, v != 0 && v != -1, ((u64 *)m_r)[R2 >> 1] == 0, ((s64 *)m_r)[R2 >> 1] < 0) } else { ((s64 *)m_r)[R2 >> 1] >>= -m_info.imm; - FLAGS(0, 0, ((s64 *)m_r)[R2 >> 1] == 0, ((s64 *)m_r)[R2 >> 1] < 0) + FLAGS(0, 0, ((u64 *)m_r)[R2 >> 1] == 0, ((s64 *)m_r)[R2 >> 1] < 0) } // FLAGS: 0VZN // TRAPS: I break; case 0x3a: // shli: shift logical immediate - if (m_info.imm > 0) + if ((s32)m_info.imm > 0) m_r[R2] <<= m_info.imm; else - ((u32 *)m_r)[R2] >>= -m_info.imm; - FLAGS(0, 0, m_r[R2] == 0, m_r[R2] < 0); + m_r[R2] >>= -m_info.imm; + FLAGS(0, 0, m_r[R2] == 0, (s32)m_r[R2] < 0); // FLAGS: 00ZN // TRAPS: I break; case 0x3b: // shlli: shift logical longword immediate - if (m_info.imm > 0) + if ((s32)m_info.imm > 0) ((u64 *)m_r)[R2 >> 1] <<= m_info.imm; else ((u64 *)m_r)[R2 >> 1] >>= -m_info.imm; - FLAGS(0, 0, ((s64 *)m_r)[R2 >> 1] == 0, ((s64 *)m_r)[R2 >> 1] < 0); + FLAGS(0, 0, ((u64 *)m_r)[R2 >> 1] == 0, ((s64 *)m_r)[R2 >> 1] < 0); // FLAGS: 00ZN // TRAPS: I break; case 0x3c: // roti: rotate immediate - if (m_info.imm > 0) + if ((s32)m_info.imm > 0) m_r[R2] = rotl32(m_r[R2], m_info.imm); else m_r[R2] = rotr32(m_r[R2], -m_info.imm); - FLAGS(0, 0, m_r[R2] == 0, m_r[R2] < 0); + FLAGS(0, 0, m_r[R2] == 0, (s32)m_r[R2] < 0); // FLAGS: 00ZN // TRAPS: I break; case 0x3d: // rotli: rotate longword immediate - if (m_info.imm > 0) + if ((s32)m_info.imm > 0) ((u64 *)m_r)[R2 >> 1] = rotl64(((u64 *)m_r)[R2 >> 1], m_info.imm); else ((u64 *)m_r)[R2 >> 1] = rotr64(((u64 *)m_r)[R2 >> 1], -m_info.imm); - FLAGS(0, 0, ((s64 *)m_r)[R2 >> 1] == 0, ((s64 *)m_r)[R2 >> 1] < 0); + FLAGS(0, 0, ((u64 *)m_r)[R2 >> 1] == 0, ((s64 *)m_r)[R2 >> 1] < 0); // FLAGS: 00ZN // TRAPS: I break; @@ -701,53 +774,53 @@ int clipper_device::execute_instruction () case 0x44: case 0x45: // call: call subroutine - m_r[R2] -= 4; - m_data->write_dword(m_r[R2], next_pc); - next_pc = m_info.address; + m_data->write_dword(m_r[R2] - 4, m_ip); + if (!m_exception) + { + m_ip = m_info.address; + m_r[R2] -= 4; + } // TRAPS: A,P,W break; -#ifdef UNIMPLEMENTED_C400 - case 0x46: - case 0x47: - // loadd2: - break; -#endif + case 0x48: case 0x49: // b*: branch on condition if (evaluate_branch()) - next_pc = m_info.address; + m_ip = m_info.address; // TRAPS: A,I break; -#ifdef UNIMPLEMENTED_C400 - case 0x4a: - case 0x4b: - // cdb: - break; - case 0x4c: - case 0x4d: - // cdbeq: - break; - case 0x4e: - case 0x4f: - // cdbne: - break; - case 0x50: - case 0x51: - // db*: - break; -#endif -#ifdef UNIMPLEMENTED + case 0x4c: case 0x4d: - // bf*: + // bf*: branch on floating exception + // FIXME: documentation is not clear, implementation is guesswork + switch (R2) + { + case BF_ANY: + // bfany: floating any exception + if (m_psw & (PSW_FI | PSW_FV | PSW_FD | PSW_FU | PSW_FX)) + m_ip = m_info.address; + break; + case BF_BAD: + // bfbad: floating bad result + if (m_psw & (PSW_FI | PSW_FD)) + m_ip = m_info.address; + break; + default: + // reserved + // FIXME: not sure if this should trigger an exception? + m_exception = EXCEPTION_ILLEGAL_OPERATION; + break; + } break; -#endif case 0x60: case 0x61: // loadw: load word - m_r[R2] = m_data->read_dword(m_info.address); + temp = m_data->read_dword(m_info.address); + if (!m_exception) + m_r[R2] = temp; // TRAPS: C,U,A,P,R,I break; case 0x62: @@ -759,37 +832,49 @@ int clipper_device::execute_instruction () case 0x64: case 0x65: // loads: load single floating - ((u64 *)&m_f)[R2] = m_data->read_dword(m_info.address); + temp = m_data->read_dword(m_info.address); + if (!m_exception) + set_fp(R2, (float32)temp, F_NONE); // TRAPS: C,U,A,P,R,I break; case 0x66: case 0x67: // loadd: load double floating - ((u64 *)&m_f)[R2] = m_data->read_qword(m_info.address); + temp = m_data->read_qword(m_info.address); + if (!m_exception) + set_fp(R2, (float64)temp, F_NONE); // TRAPS: C,U,A,P,R,I break; case 0x68: case 0x69: // loadb: load byte - m_r[R2] = (s8)m_data->read_byte(m_info.address); + temp = s64(s8(m_data->read_byte(m_info.address))); + if (!m_exception) + m_r[R2] = temp; // TRAPS: C,U,A,P,R,I break; case 0x6a: case 0x6b: // loadbu: load byte unsigned - m_r[R2] = m_data->read_byte(m_info.address); + temp = m_data->read_byte(m_info.address); + if (!m_exception) + m_r[R2] = temp; // TRAPS: C,U,A,P,R,I break; case 0x6c: case 0x6d: // loadh: load halfword - m_r[R2] = (s16)m_data->read_word(m_info.address); + temp = s64(s16(m_data->read_word(m_info.address))); + if (!m_exception) + m_r[R2] = temp; // TRAPS: C,U,A,P,R,I break; case 0x6e: case 0x6f: // loadhu: load halfword unsigned - m_r[R2] = m_data->read_word(m_info.address); + temp = m_data->read_word(m_info.address); + if (!m_exception) + m_r[R2] = temp; // TRAPS: C,U,A,P,R,I break; case 0x70: @@ -801,33 +886,38 @@ int clipper_device::execute_instruction () case 0x72: case 0x73: // tsts: test and set - m_r[R2] = m_data->read_dword(m_info.address); - m_data->write_dword(m_info.address, m_r[R2] | 0x80000000); + temp = m_data->read_dword(m_info.address); + if (!m_exception) + { + m_data->write_dword(m_info.address, temp | 0x80000000U); + if (!m_exception) + m_r[R2] = temp; + } // TRAPS: C,U,A,P,R,W,I break; case 0x74: case 0x75: // stors: store single floating - m_data->write_dword(m_info.address, *((u32 *)&m_f[R2])); + m_data->write_dword(m_info.address, get_fp32(R2)); // TRAPS: A,P,W,I break; case 0x76: case 0x77: // stord: store double floating - m_data->write_qword(m_info.address, *((u64 *)&m_f[R2])); + m_data->write_qword(m_info.address, get_fp64(R2)); // TRAPS: A,P,W,I break; case 0x78: case 0x79: // storb: store byte - m_data->write_byte(m_info.address, (u8)m_r[R2]); + m_data->write_byte(m_info.address, m_r[R2]); // TRAPS: A,P,W,I break; case 0x7c: case 0x7d: // storh: store halfword - m_data->write_word(m_info.address, (u16)m_r[R2]); + m_data->write_word(m_info.address, m_r[R2]); // TRAPS: A,P,W,I break; @@ -835,7 +925,7 @@ int clipper_device::execute_instruction () // addw: add word FLAGS_CV(C_ADD(m_r[R2], m_r[R1]), V_ADD(m_r[R2], m_r[R1])) m_r[R2] += m_r[R1]; - FLAGS_ZN(m_r[R2] == 0, m_r[R2] < 0) + FLAGS_ZN(m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: CVZN break; @@ -843,21 +933,21 @@ int clipper_device::execute_instruction () // addq: add quick FLAGS_CV(C_ADD(m_r[R2], R1), V_ADD(m_r[R2], R1)) m_r[R2] += R1; - FLAGS_ZN(m_r[R2] == 0, m_r[R2] < 0) + FLAGS_ZN(m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: CVZN break; case 0x83: // addi: add immediate FLAGS_CV(C_ADD(m_r[R2], m_info.imm), V_ADD(m_r[R2], m_info.imm)) m_r[R2] += m_info.imm; - FLAGS_ZN(m_r[R2] == 0, m_r[R2] < 0) + FLAGS_ZN(m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: CVZN // TRAPS: I break; case 0x84: // movw: move word m_r[R2] = m_r[R1]; - FLAGS(0, 0, m_r[R2] == 0, m_r[R2] < 0) + FLAGS(0, 0, m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: 00ZN break; @@ -870,35 +960,35 @@ int clipper_device::execute_instruction () case 0x87: // loadi: load immediate m_r[R2] = m_info.imm; - FLAGS(0, 0, m_r[R2] == 0, m_r[R2] < 0) + FLAGS(0, 0, m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: 00ZN // TRAPS: I break; case 0x88: // andw: and word m_r[R2] &= m_r[R1]; - FLAGS(0, 0, m_r[R2] == 0, m_r[R2] < 0) + FLAGS(0, 0, m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: 00ZN break; case 0x8b: // andi: and immediate m_r[R2] &= m_info.imm; - FLAGS(0, 0, m_r[R2] == 0, m_r[R2] < 0) + FLAGS(0, 0, m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: 00ZN // TRAPS: I break; case 0x8c: // orw: or word m_r[R2] |= m_r[R1]; - FLAGS(0, 0, m_r[R2] == 0, m_r[R2] < 0) + FLAGS(0, 0, m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: 00ZN break; case 0x8f: // ori: or immediate m_r[R2] |= m_info.imm; - FLAGS(0, 0, m_r[R2] == 0, m_r[R2] < 0) + FLAGS(0, 0, m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: 00ZN // TRAPS: I break; @@ -906,14 +996,14 @@ int clipper_device::execute_instruction () // addwc: add word with carry FLAGS_CV(C_ADD(m_r[R2], (m_r[R1] + (PSW(C) ? 1 : 0))), V_ADD(m_r[R2], (m_r[R1] + (PSW(C) ? 1 : 0)))) m_r[R2] += m_r[R1] + (PSW(C) ? 1 : 0); - FLAGS_ZN(m_r[R2] == 0, m_r[R2] < 0) + FLAGS_ZN(m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: CVZN break; case 0x91: // subwc: subtract word with carry FLAGS_CV(C_SUB(m_r[R2], (m_r[R1] + (PSW(C) ? 1 : 0))), V_SUB(m_r[R2], (m_r[R1] + (PSW(C) ? 1 : 0)))) m_r[R2] -= m_r[R1] + (PSW(C) ? 1 : 0); - FLAGS_ZN(m_r[R2] == 0, m_r[R2] < 0) + FLAGS_ZN(m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: CVZN break; @@ -921,13 +1011,13 @@ int clipper_device::execute_instruction () // negw: negate word FLAGS_CV(m_r[R1] != 0, m_r[R1] == INT32_MIN) m_r[R2] = -m_r[R1]; - FLAGS_ZN(m_r[R2] == 0, m_r[R2] < 0) + FLAGS_ZN(m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: CVZN break; case 0x98: // mulw: multiply word - m_r[R2] = m_r[R2] * m_r[R1]; + m_r[R2] = (s32)m_r[R2] * (s32)m_r[R1]; // FLAGS: 0V00 break; case 0x99: @@ -937,7 +1027,7 @@ int clipper_device::execute_instruction () break; case 0x9a: // mulwu: multiply word unsigned - m_r[R2] = (u32)m_r[R2] * (u32)m_r[R1]; + m_r[R2] = m_r[R2] * m_r[R1]; // FLAGS: 0V00 break; case 0x9b: @@ -949,51 +1039,55 @@ int clipper_device::execute_instruction () // divw: divide word if (m_r[R1] != 0) { + // FLAGS: 0V00 FLAGS(0, m_r[R2] == INT32_MIN && m_r[R1] == -1, 0, 0) - m_r[R2] = m_r[R2] / m_r[R1]; + m_r[R2] = (s32)m_r[R2] / (s32)m_r[R1]; } else - next_pc = intrap(EXCEPTION_INTEGER_DIVIDE_BY_ZERO, next_pc, CTS_DIVIDE_BY_ZERO); - // FLAGS: 0V00 - // TRAPS: D + // TRAPS: D + m_exception = EXCEPTION_INTEGER_DIVIDE_BY_ZERO; break; case 0x9d: // modw: modulus word if (m_r[R1] != 0) { + // FLAGS: 0V00 FLAGS(0, m_r[R2] == INT32_MIN && m_r[R1] == -1, 0, 0) - m_r[R2] = m_r[R2] % m_r[R1]; + m_r[R2] = (s32)m_r[R2] % (s32)m_r[R1]; } else - next_pc = intrap(EXCEPTION_INTEGER_DIVIDE_BY_ZERO, next_pc, CTS_DIVIDE_BY_ZERO); - // FLAGS: 0V00 - // TRAPS: D + // TRAPS: D + m_exception = EXCEPTION_INTEGER_DIVIDE_BY_ZERO; break; case 0x9e: // divwu: divide word unsigned - if ((u32)m_r[R1] != 0) - m_r[R2] = (u32)m_r[R2] / (u32)m_r[R1]; + if (m_r[R1] != 0) + { + m_r[R2] = m_r[R2] / m_r[R1]; + // FLAGS: 0000 + FLAGS(0, 0, 0, 0) + } else - next_pc = intrap(EXCEPTION_INTEGER_DIVIDE_BY_ZERO, next_pc, CTS_DIVIDE_BY_ZERO); - FLAGS(0, 0, 0, 0) - // FLAGS: 0000 - // TRAPS: D + // TRAPS: D + m_exception = EXCEPTION_INTEGER_DIVIDE_BY_ZERO; break; case 0x9f: // modwu: modulus word unsigned - if ((u32)m_r[R1] != 0) - m_r[R2] = (u32)m_r[R2] % (u32)m_r[R1]; + if (m_r[R1] != 0) + { + m_r[R2] = m_r[R2] % m_r[R1]; + // FLAGS: 0000 + FLAGS(0, 0, 0, 0) + } else - next_pc = intrap(EXCEPTION_INTEGER_DIVIDE_BY_ZERO, next_pc, CTS_DIVIDE_BY_ZERO); - FLAGS(0, 0, 0, 0) - // FLAGS: 0000 - // TRAPS: D + // TRAPS: D + m_exception = EXCEPTION_INTEGER_DIVIDE_BY_ZERO; break; case 0xa0: // subw: subtract word FLAGS_CV(C_SUB(m_r[R2], m_r[R1]), V_SUB(m_r[R2], m_r[R1])) m_r[R2] -= m_r[R1]; - FLAGS_ZN(m_r[R2] == 0, m_r[R2] < 0) + FLAGS_ZN(m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: CVZN break; @@ -1001,52 +1095,52 @@ int clipper_device::execute_instruction () // subq: subtract quick FLAGS_CV(C_SUB(m_r[R2], R1), V_SUB(m_r[R2], R1)) m_r[R2] -= R1; - FLAGS_ZN(m_r[R2] == 0, m_r[R2] < 0) + FLAGS_ZN(m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: CVZN break; case 0xa3: // subi: subtract immediate FLAGS_CV(C_SUB(m_r[R2], m_info.imm), V_SUB(m_r[R2], m_info.imm)) m_r[R2] -= m_info.imm; - FLAGS_ZN(m_r[R2] == 0, m_r[R2] < 0) + FLAGS_ZN(m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: CVZN // TRAPS: I break; case 0xa4: // cmpw: compare word - FLAGS(C_SUB(m_r[R2], m_r[R1]), V_SUB(m_r[R2], m_r[R1]), m_r[R2] == m_r[R1], m_r[R2] < m_r[R1]) + FLAGS(C_SUB(m_r[R2], m_r[R1]), V_SUB(m_r[R2], m_r[R1]), m_r[R2] == m_r[R1], (s32)m_r[R2] < (s32)m_r[R1]) // FLAGS: CVZN break; case 0xa6: // cmpq: compare quick - FLAGS(C_SUB(m_r[R2], R1), V_SUB(m_r[R2], R1), m_r[R2] == (s32)R1, m_r[R2] < (s32)R1) + FLAGS(C_SUB(m_r[R2], R1), V_SUB(m_r[R2], R1), m_r[R2] == R1, (s32)m_r[R2] < (s32)R1) // FLAGS: CVZN break; case 0xa7: // cmpi: compare immediate - FLAGS(C_SUB(m_r[R2], m_info.imm), V_SUB(m_r[R2], m_info.imm), m_r[R2] == m_info.imm, m_r[R2] < m_info.imm) + FLAGS(C_SUB(m_r[R2], m_info.imm), V_SUB(m_r[R2], m_info.imm), m_r[R2] == m_info.imm, (s32)m_r[R2] < (s32)m_info.imm) // FLAGS: CVZN // TRAPS: I break; case 0xa8: // xorw: exclusive or word m_r[R2] ^= m_r[R1]; - FLAGS(0, 0, m_r[R2] == 0, m_r[R2] < 0) + FLAGS(0, 0, m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: 00ZN break; case 0xab: // xori: exclusive or immediate m_r[R2] ^= m_info.imm; - FLAGS(0, 0, m_r[R2] == 0, m_r[R2] < 0) + FLAGS(0, 0, m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: 00ZN // TRAPS: I break; case 0xac: // notw: not word m_r[R2] = ~m_r[R1]; - FLAGS(0, 0, m_r[R2] == 0, m_r[R2] < 0) + FLAGS(0, 0, m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: 00ZN break; @@ -1057,16 +1151,6 @@ int clipper_device::execute_instruction () // FLAGS: 0001 break; -#ifdef UNIMPLEMENTED_C400 - case 0xb0: - // abss: absolute value single floating? - break; - - case 0xb2: - // absd: absolute value double floating? - break; -#endif - case 0xb4: // unprivileged macro instructions switch (m_info.subopcode) @@ -1078,11 +1162,12 @@ int clipper_device::execute_instruction () // savew0..savew12: push registers rN:r14 // store ri at sp - 4 * (15 - i) - for (int i = R2; i < 15; i++) + for (int i = R2; i < 15 && !m_exception; i++) m_data->write_dword(m_r[15] - 4 * (15 - i), m_r[i]); // decrement sp after push to allow restart on exceptions - m_r[15] -= 4 * (15 - R2); + if (!m_exception) + m_r[15] -= 4 * (15 - R2); // TRAPS: A,P,W break; // NOTE: the movc, initc and cmpc macro instructions are implemented in a very basic way because @@ -1094,7 +1179,13 @@ int clipper_device::execute_instruction () while (m_r[0]) { - m_data->write_byte(m_r[2], m_data->read_byte(m_r[1])); + const u8 byte = m_data->read_byte(m_r[1]); + if (m_exception) + break; + + m_data->write_byte(m_r[2], byte); + if (m_exception) + break; m_r[0]--; m_r[1]++; @@ -1106,7 +1197,9 @@ int clipper_device::execute_instruction () // initc: initialise r0 bytes at r1 with value in r2 while (m_r[0]) { - m_data->write_byte(m_r[1], m_r[2] & 0xff); + m_data->write_byte(m_r[1], m_r[2]); + if (m_exception) + break; m_r[0]--; m_r[1]++; @@ -1123,8 +1216,12 @@ int clipper_device::execute_instruction () while (m_r[0]) { // set condition codes and abort the loop if the current byte does not match - s32 byte1 = (s8)m_data->read_byte(m_r[1]); - s32 byte2 = (s8)m_data->read_byte(m_r[2]); + s32 byte1 = s8(m_data->read_byte(m_r[1])); + if (m_exception) + break; + s32 byte2 = s8(m_data->read_byte(m_r[2])); + if (m_exception) + break; if (byte1 != byte2) { FLAGS(C_SUB(byte2, byte1), V_SUB(byte2, byte1), byte2 == byte1, byte2 < byte1) @@ -1145,10 +1242,16 @@ int clipper_device::execute_instruction () // load ri from sp + 4 * (i - N) for (int i = R2; i < 15; i++) - m_r[i] = m_data->read_dword(m_r[15] + 4 * (i - R2)); + { + temp = m_data->read_dword(m_r[15] + 4 * (i - R2)); + if (m_exception) + break; + m_r[i] = temp; + } // increment sp after pop to allow restart on exceptions - m_r[15] += 4 * (15 - R2); + if (!m_exception) + m_r[15] += 4 * (15 - R2); // TRAPS: C,U,A,P,R break; @@ -1157,11 +1260,12 @@ int clipper_device::execute_instruction () // saved0..saved7: push registers fN:f7 // store fi at sp - 8 * (8 - i) - for (int i = R2; i < 8; i++) - m_data->write_qword(m_r[15] - 8 * (8 - i), m_f[i]); + for (int i = R2; i < 8 && !m_exception; i++) + m_data->write_qword(m_r[15] - 8 * (8 - i), get_fp64(i)); // decrement sp after push to allow restart on exceptions - m_r[15] -= 8 * (8 - R2); + if (!m_exception) + m_r[15] -= 8 * (8 - R2); // TRAPS: A,P,W break; case 0x28: case 0x29: case 0x2a: case 0x2b: @@ -1170,71 +1274,145 @@ int clipper_device::execute_instruction () // load fi from sp + 8 * (i - N) for (int i = R2; i < 8; i++) - m_f[i] = m_data->read_qword(m_r[15] + 8 * (i - R2)); + { + temp = m_data->read_qword(m_r[15] + 8 * (i - R2)); + if (m_exception) + break; + set_fp(i, (float64)temp, F_NONE); + } // increment sp after pop to allow restart on exceptions - m_r[15] += 8 * (8 - R2); + if (!m_exception) + m_r[15] += 8 * (8 - R2); // TRAPS: C,U,A,P,R break; -#ifdef UNIMPLEMENTED case 0x30: - // cnvsw + // cnvsw: convert single floating to word + m_fp_pc = m_pc; + + m_r[m_info.macro & 0xf] = float32_to_int32(get_fp32((m_info.macro >> 4) & 0xf)); + // TRAPS: F_IX + float_exception_flags &= F_IX; + break; case 0x31: - // cnvrsw + // cnvrsw: convert rounding single floating to word (non-IEEE +0.5/-0.5 rounding) + m_fp_pc = m_pc; + + if (float32_lt(get_fp32((m_info.macro >> 4) & 0xf), 0)) + m_r[m_info.macro & 0xf] = float32_to_int32_round_to_zero(float32_sub(get_fp32((m_info.macro >> 4) & 0xf), + float32_div(int32_to_float32(1), int32_to_float32(2)))); + else + m_r[m_info.macro & 0xf] = float32_to_int32_round_to_zero(float32_add(get_fp32((m_info.macro >> 4) & 0xf), + float32_div(int32_to_float32(1), int32_to_float32(2)))); // TRAPS: F_IX + float_exception_flags &= F_IX; + break; case 0x32: - // cnvtsw + // cnvtsw: convert truncating single floating to word + m_fp_pc = m_pc; + + m_r[m_info.macro & 0xf] = float32_to_int32_round_to_zero(get_fp32((m_info.macro >> 4) & 0xf)); // TRAPS: F_IX + float_exception_flags &= F_IX; + break; case 0x33: - // cnvws + // cnvws: convert word to single floating + set_fp(m_info.macro & 0xf, int32_to_float32(m_r[(m_info.macro >> 4) & 0xf]), F_X); // TRAPS: F_X + break; case 0x34: - // cnvdw + // cnvdw: convert double floating to word + m_fp_pc = m_pc; + + m_r[m_info.macro & 0xf] = float64_to_int32(get_fp64((m_info.macro >> 4) & 0xf)); // TRAPS: F_IX + float_exception_flags &= F_IX; + break; case 0x35: - // cnvrdw + // cnvrdw: convert rounding double floating to word (non-IEEE +0.5/-0.5 rounding) + m_fp_pc = m_pc; + + if (float64_lt(get_fp64((m_info.macro >> 4) & 0xf), 0)) + m_r[m_info.macro & 0xf] = float64_to_int32_round_to_zero(float64_sub(get_fp64((m_info.macro >> 4) & 0xf), + float64_div(int32_to_float64(1), int32_to_float64(2)))); + else + m_r[m_info.macro & 0xf] = float64_to_int32_round_to_zero(float64_add(get_fp64((m_info.macro >> 4) & 0xf), + float64_div(int32_to_float64(1), int32_to_float64(2)))); // TRAPS: F_IX + float_exception_flags &= F_IX; break; -#endif - case 0x36: // cnvtdw - m_r[m_info.macro & 0xf] = (s32)m_f[(m_info.macro >> 4) & 0xf]; + case 0x36: + // cnvtdw: convert truncating double floating to word + m_fp_pc = m_pc; + + m_r[m_info.macro & 0xf] = float64_to_int32_round_to_zero(get_fp64((m_info.macro >> 4) & 0xf)); // TRAPS: F_IX + float_exception_flags &= F_IX; break; - case 0x37: // cnvwd - m_f[m_info.macro & 0xf] = (double)m_r[(m_info.macro >> 4) & 0xf]; + case 0x37: + // cnvwd: convert word to double floating + set_fp(m_info.macro & 0xf, int32_to_float64(m_r[(m_info.macro >> 4) & 0xf]), F_NONE); break; -#ifdef UNIMPLEMENTED case 0x38: - // cnvsd + // cnvsd: convert single to double floating + set_fp(m_info.macro & 0xf, float32_to_float64(get_fp32((m_info.macro >> 4) & 0xf)), F_I); // TRAPS: F_I + break; case 0x39: - // cnvds + // cnvds: convert double to single floating + set_fp(m_info.macro & 0xf, float64_to_float32(get_fp64((m_info.macro >> 4) & 0xf)), F_IVUX); // TRAPS: F_IVUX + break; case 0x3a: - // negs + // negs: negate single floating + set_fp(m_info.macro & 0xf, float32_mul(get_fp32((m_info.macro >> 4) & 0xf), int32_to_float32(-1)), F_NONE); + break; case 0x3b: - // negds + // negd: negate double floating + set_fp(m_info.macro & 0xf, float64_mul(get_fp64((m_info.macro >> 4) & 0xf), int32_to_float64(-1)), F_NONE); + break; case 0x3c: - // scalbs + /* + * This implementation for scalbd and scalbs is a bit opaque, but + * essentially we check if the integer value is within range, and + * directly create a floating constant representing 2^n or NaN + * respectively, which is used as an input to a multiply, producing + * the desired result. While doing an actual multiply is both + * inefficient and unnecessary, it's a tidy way to ensure the + * correct exception flags are set. + */ + // scalbs: scale by, single floating + set_fp(m_info.macro & 0xf, float32_mul(get_fp32(m_info.macro & 0xf), + (((s32)m_r[(m_info.macro >> 4) & 0xf] > -127 && (s32)m_r[(m_info.macro >> 4) & 0xf] < 128) + ? (float32)(((s32)m_r[(m_info.macro >> 4) & 0xf] + 127) << 23) + : (float32)~u32(0))), F_IVUX); // TRAPS: F_IVUX + break; case 0x3d: - // scalbd - // FLAGS: N + // scalbd: scale by, double floating + set_fp(m_info.macro & 0xf, float64_mul(get_fp64(m_info.macro & 0xf), + ((s32)m_r[(m_info.macro >> 4) & 0xf] > -1023 && (s32)m_r[(m_info.macro >> 4) & 0xf] < 1024) + ? (float64)((u64)((s32)m_r[(m_info.macro >> 4) & 0xf] + 1023) << 52) + : (float64)~u64(0)), F_IVUX); // TRAPS: F_IVUX + break; case 0x3e: - // trapfn + // trapfn: trap floating unordered // TRAPS: I + if (PSW(Z) && PSW(N)) + m_exception = EXCEPTION_ILLEGAL_OPERATION; + break; case 0x3f: - // loadfs + // loadfs: load floating status + m_r[(m_info.macro >> 4) & 0xf] = m_fp_pc; + m_f[m_info.macro & 0xf] = m_fp_dst; + m_ssw |= SSW_FRD; break; -#endif + default: - LOG("illegal unprivileged macro opcode at 0x%08x\n", m_pc); - next_pc = intrap(EXCEPTION_ILLEGAL_OPERATION, next_pc, CTS_ILLEGAL_OPERATION); - machine().debug_break(); + m_exception = EXCEPTION_ILLEGAL_OPERATION; break; } - break; case 0xb6: @@ -1246,158 +1424,184 @@ int clipper_device::execute_instruction () case 0x00: // movus: move user to supervisor m_rs[m_info.macro & 0xf] = m_ru[(m_info.macro >> 4) & 0xf]; - FLAGS(0, 0, m_rs[m_info.macro & 0xf] == 0, m_rs[m_info.macro & 0xf] < 0) + FLAGS(0, 0, m_rs[m_info.macro & 0xf] == 0, (s32)m_rs[m_info.macro & 0xf] < 0) // FLAGS: 00ZN // TRAPS: S break; case 0x01: // movsu: move supervisor to user m_ru[m_info.macro & 0xf] = m_rs[(m_info.macro >> 4) & 0xf]; - FLAGS(0, 0, m_ru[m_info.macro & 0xf] == 0, m_ru[m_info.macro & 0xf] < 0) + FLAGS(0, 0, m_ru[m_info.macro & 0xf] == 0, (s32)m_ru[m_info.macro & 0xf] < 0) // FLAGS: 00ZN // TRAPS: S break; case 0x02: // saveur: save user registers - for (int i = 0; i < 16; i++) + for (int i = 0; i < 16 && !m_exception; i++) m_data->write_dword(m_rs[(m_info.macro >> 4) & 0xf] - 4 * (i + 1), m_ru[15 - i]); - m_rs[(m_info.macro >> 4) & 0xf] -= 64; + if (!m_exception) + m_rs[(m_info.macro >> 4) & 0xf] -= 64; // TRAPS: A,P,W,S break; case 0x03: // restur: restore user registers for (int i = 0; i < 16; i++) - m_ru[i] = m_data->read_dword(m_rs[(m_info.macro >> 4) & 0xf] + 4 * i); + { + temp = m_data->read_dword(m_rs[(m_info.macro >> 4) & 0xf] + 4 * i); + if (m_exception) + break; + m_ru[i] = temp; + } - m_rs[(m_info.macro >> 4) & 0xf] += 64; + if (!m_exception) + m_rs[(m_info.macro >> 4) & 0xf] += 64; // TRAPS: C,U,A,P,R,S break; case 0x04: // reti: restore psw, ssw and pc from supervisor stack - LOGMASKED(LOG_INTERRUPT, "reti r%d ssp 0x%08x pc 0x%08x next_pc 0x%08x\n", - (m_info.macro >> 4) & 0xf, m_rs[(m_info.macro >> 4) & 0xf], m_pc, m_data->read_dword(m_rs[(m_info.macro >> 4) & 0xf] + 8)); - - m_psw = m_data->read_dword(m_rs[(m_info.macro >> 4) & 0xf] + 0); - set_ssw(m_data->read_dword(m_rs[(m_info.macro >> 4) & 0xf] + 4)); - next_pc = m_data->read_dword(m_rs[(m_info.macro >> 4) & 0xf] + 8); - - m_rs[(m_info.macro >> 4) & 0xf] += 12; - - m_r = SSW(U) ? m_ru : m_rs; + m_ip = reti(); // TRAPS: S break; case 0x05: // wait: wait for interrupt - next_pc = m_pc; + m_ip = m_pc; // TRAPS: S break; -#ifdef UNIMPLEMENTED_C400 - case 0x07: - // loadts: unknown? - break; -#endif default: - // illegal operation - LOG("illegal privileged macro opcode at 0x%08x\n", m_pc); - next_pc = intrap(EXCEPTION_ILLEGAL_OPERATION, next_pc, CTS_ILLEGAL_OPERATION); - machine().debug_break(); + m_exception = EXCEPTION_ILLEGAL_OPERATION; break; } } else - next_pc = intrap(EXCEPTION_PRIVILEGED_INSTRUCTION, next_pc, CTS_PRIVILEGED_INSTRUCTION); - break; - -#ifdef UNIMPLEMENTED_C400 - case 0xbc: - // waitd: + m_exception = EXCEPTION_PRIVILEGED_INSTRUCTION; break; - case 0xc0: - // s*: - break; -#endif - default: - LOG("illegal opcode at 0x%08x\n", m_pc); - next_pc = intrap(EXCEPTION_ILLEGAL_OPERATION, next_pc, CTS_ILLEGAL_OPERATION); + m_exception = EXCEPTION_ILLEGAL_OPERATION; break; } +} - return next_pc; +u32 clipper_device::reti() +{ + // fetch the psw, ssw and pc from the supervisor stack + const u32 new_psw = m_data->read_dword(m_rs[(m_info.macro >> 4) & 0xf] + 0); + if (m_exception) + fatalerror("reti unrecoverable fault 0x%04x read psw address 0x%08x pc 0x%08x\n", m_exception, m_rs[(m_info.macro >> 4) & 0xf] + 0, m_pc); + + const u32 new_ssw = m_data->read_dword(m_rs[(m_info.macro >> 4) & 0xf] + 4); + if (m_exception) + fatalerror("reti unrecoverable fault 0x%04x read ssw address 0x%08x pc 0x%08x\n", m_exception, m_rs[(m_info.macro >> 4) & 0xf] + 4, m_pc); + + const u32 new_pc = m_data->read_dword(m_rs[(m_info.macro >> 4) & 0xf] + 8); + if (m_exception) + fatalerror("reti unrecoverable fault 0x%04x read pc address 0x%08x pc 0x%08x\n", m_exception, m_rs[(m_info.macro >> 4) & 0xf] + 8, m_pc); + + LOGMASKED(LOG_EXCEPTION, "reti r%d ssp 0x%08x pc 0x%08x ssw 0x%08x psw 0x%08x new_pc 0x%08x new_ssw 0x%08x new_psw 0x%08x\n", + (m_info.macro >> 4) & 0xf, m_rs[(m_info.macro >> 4) & 0xf], m_pc, m_ssw, m_psw, new_pc, new_ssw, new_psw); + + // pop the stack + m_rs[(m_info.macro >> 4) & 0xf] += 12; + + // restore the psw and ssw + set_psw(new_psw); + set_ssw(new_ssw); + + // return the restored pc + return new_pc; } /* -* Common entry point for transferring control in the event of an interrupt or exception. -*/ -u32 clipper_device::intrap(u32 vector, u32 pc, u32 cts, u32 mts) + * Common entry point for transferring control in the event of an interrupt or + * exception. Reading between the lines, it appears this logic was implemented + * using the macro instruction ROM and a special macro instruction (intrap). + */ +u32 clipper_device::intrap(const u16 vector, const u32 old_pc) { - // fetch pc and ssw from interrupt vector - u32 next_pc = m_data->read_dword(vector + 0); - u32 next_ssw = m_data->read_dword(vector + 4); + const u32 old_ssw = m_ssw; + const u32 old_psw = m_psw; - LOGMASKED(LOG_INTERRUPT, "intrap vector 0x%08x pc 0x%08x next_pc 0x%08x ssp 0x%08x\n", vector, pc, next_pc, m_rs[15]); + // clear ssw bits to enable supervisor memory access + m_ssw &= ~(SSW_U | SSW_K | SSW_UU | SSW_KU); - // set cts and mts to indicate source of exception - m_psw = (m_psw & ~(PSW_CTS | PSW_MTS)) | mts | cts; + // clear exception state + m_exception = 0; - // push pc, ssw and psw onto supervisor stack - m_data->write_dword(m_rs[15] - 0x4, pc); - m_data->write_dword(m_rs[15] - 0x8, m_ssw); - m_data->write_dword(m_rs[15] - 0xc, m_psw); + // fetch next pc and ssw from interrupt vector + const u32 new_pc = m_data->read_dword(vector + get_evpc_offset()); + if (m_exception) + fatalerror("intrap unrecoverable fault 0x%04x read pc address 0x%08x pc 0x%08x\n", m_exception, vector + get_evpc_offset(), old_pc); - // decrement supervisor stack pointer - m_rs[15] -= 12; - - // load ssw from trap vector and set previous mode - set_ssw((next_ssw & ~(SSW(P))) | (SSW(U) << 1)); + const u32 new_ssw = m_data->read_dword(vector + get_evssw_offset()); + if (m_exception) + fatalerror("intrap unrecoverable fault 0x%04x read ssw address 0x%08x pc 0x%08x\n", m_exception, vector + get_evssw_offset(), old_pc); - // clear psw - m_psw = 0; + LOGMASKED(LOG_EXCEPTION, "intrap vector 0x%04x pc 0x%08x ssp 0x%08x new_pc 0x%08x new_ssw 0x%08x\n", vector, old_pc, m_rs[15], new_pc, new_ssw); - m_r = SSW(U) ? m_ru : m_rs; + // derive cts and mts from vector + u32 source = 0; + switch (vector) + { + // data memory trap group + case EXCEPTION_D_CORRECTED_MEMORY_ERROR: + case EXCEPTION_D_UNCORRECTABLE_MEMORY_ERROR: + case EXCEPTION_D_ALIGNMENT_FAULT: + case EXCEPTION_D_PAGE_FAULT: + case EXCEPTION_D_READ_PROTECT_FAULT: + case EXCEPTION_D_WRITE_PROTECT_FAULT: - // return new pc from trap vector - return next_pc; -} + // instruction memory trap group + case EXCEPTION_I_CORRECTED_MEMORY_ERROR: + case EXCEPTION_I_UNCORRECTABLE_MEMORY_ERROR: + case EXCEPTION_I_ALIGNMENT_FAULT: + case EXCEPTION_I_PAGE_FAULT: + case EXCEPTION_I_EXECUTE_PROTECT_FAULT: + source = (vector & MTS_VMASK) << (MTS_SHIFT - MTS_VSHIFT); + break; -u32 clipper_c400_device::intrap(u32 vector, u32 pc, u32 cts, u32 mts) -{ - // C400 reverses order of pc and ssw in interrupt vector - u32 next_pc = m_data->read_dword(vector + 4); - u32 next_ssw = m_data->read_dword(vector + 0); + // integer arithmetic trap group + case EXCEPTION_INTEGER_DIVIDE_BY_ZERO: + source = CTS_DIVIDE_BY_ZERO; + break; - LOGMASKED(LOG_INTERRUPT, "intrap vector 0x%08x pc 0x%08x next_pc 0x%08x ssp 0x%08x\n", vector, pc, next_pc, m_rs[15]); + // illegal operation trap group + case EXCEPTION_ILLEGAL_OPERATION: + source = CTS_ILLEGAL_OPERATION; + break; + case EXCEPTION_PRIVILEGED_INSTRUCTION: + source = CTS_PRIVILEGED_INSTRUCTION; + break; - // set cts and mts to indicate source of exception - m_psw = (m_psw & ~(PSW_CTS | PSW_MTS)) | mts | cts; + // diagnostic trap group + case EXCEPTION_TRACE: + source = CTS_TRACE_TRAP; + break; + } // push pc, ssw and psw onto supervisor stack - m_data->write_dword(m_rs[15] - 0x4, pc); - m_data->write_dword(m_rs[15] - 0x8, m_ssw); - m_data->write_dword(m_rs[15] - 0xc, m_psw); + m_data->write_dword(m_rs[15] - 0x4, old_pc); + if (m_exception) + fatalerror("intrap unrecoverable fault 0x%04x write pc address 0x%08x pc 0x%08x\n", m_exception, m_rs[15] - 0x4, old_pc); + m_data->write_dword(m_rs[15] - 0x8, old_ssw); + if (m_exception) + fatalerror("intrap unrecoverable fault 0x%04x write ssw address 0x%08x pc 0x%08x\n", m_exception, m_rs[15] - 0x8, old_pc); + m_data->write_dword(m_rs[15] - 0xc, (old_psw & ~(PSW_CTS | PSW_MTS)) | source); + if (m_exception) + fatalerror("intrap unrecoverable fault 0x%04x write psw address 0x%08x pc 0x%08x\n", m_exception, m_rs[15] - 0xc, old_pc); // decrement supervisor stack pointer + m_rs[15] -= get_eframe_size(); - // NOTE: while not explicitly stated anywhere, it seems the InterPro C400 boot code has been - // developed with the assumption that the SSP is decremented by 24 bytes during an exception, - // rather than the 12 bytes for the InterPro C300 version. This means the exception handler - // code must explicitly increment the SSP by 12 prior to executing the RETI instruction, - // as otherwise the SSP will not be pointing at a valid return frame. - m_rs[15] -= 24; - - // load ssw from trap vector and set previous mode - set_ssw((next_ssw & ~(SSW(P))) | (SSW(U) << 1)); + // set ssw from vector and previous mode + set_ssw((new_ssw & ~SSW_P) | (old_ssw & SSW_U) << 1); // clear psw - m_psw = 0; - - m_r = SSW(U) ? m_ru : m_rs; + set_psw(0); // return new pc from trap vector - return next_pc; + return new_pc; } bool clipper_device::evaluate_branch() const @@ -1460,7 +1664,140 @@ bool clipper_device::evaluate_branch() const return false; } -offs_t clipper_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +void clipper_device::set_psw(const u32 psw) +{ + // retain read-only endianness field + m_psw = (m_psw & PSW_BIG) | (psw & ~PSW_BIG); + + // set the softfloat rounding mode based on the psw rounding mode + switch (PSW(FR)) + { + case FR_0: float_rounding_mode = float_round_nearest_even; break; + case FR_1: float_rounding_mode = float_round_up; break; + case FR_2: float_rounding_mode = float_round_down; break; + case FR_3: float_rounding_mode = float_round_to_zero; break; + } +} + +void clipper_device::set_ssw(const u32 ssw) +{ + // retain read-only id field + m_ssw = (m_ssw & SSW_ID) | (ssw & ~SSW_ID); + + // select the register file + m_r = SSW(U) ? m_ru : m_rs; +} + +void clipper_device::fp_exception() +{ + u16 exception = 0; + + /* + * Set the psw floating exception flags, and identify any enabled + * exceptions. The order here is important, but since the documentation + * doesn't explicitly specify, this is a guess. Simply put, exceptions + * are considered in sequence with an increasing order of priority. + */ + if (float_exception_flags & float_flag_inexact) + { + m_psw |= PSW_FX; + if (PSW(EFX)) + exception = EXCEPTION_FLOATING_INEXACT; + } + if (float_exception_flags & float_flag_underflow) + { + m_psw |= PSW_FU; + if (PSW(EFU)) + exception = EXCEPTION_FLOATING_UNDERFLOW; + } + if (float_exception_flags & float_flag_overflow) + { + m_psw |= PSW_FV; + if (PSW(EFV)) + exception = EXCEPTION_FLOATING_OVERFLOW; + } + if (float_exception_flags & float_flag_divbyzero) + { + m_psw |= PSW_FD; + if (PSW(EFD)) + exception = EXCEPTION_FLOATING_DIVIDE_BY_ZERO; + } + if (float_exception_flags & float_flag_invalid) + { + m_psw |= PSW_FI; + if (PSW(EFI)) + exception = EXCEPTION_FLOATING_INVALID_OPERATION; + } + + // trigger a floating point exception + if (PSW(EFT) && exception) + m_exception = exception; +} + +void clipper_c400_device::execute_instruction() +{ + switch (m_info.opcode) + { +#ifdef UNIMPLEMENTED_C400 + case 0x46: + case 0x47: + // loadd2: + break; + + case 0x4a: + case 0x4b: + // cdb: + break; + case 0x4c: + case 0x4d: + // cdbeq: + break; + case 0x4e: + case 0x4f: + // cdbne: + break; + case 0x50: + case 0x51: + // db*: + break; + + case 0xb0: + // abss: absolute value single floating? + break; + + case 0xb2: + // absd: absolute value double floating? + break; + + case 0xb6: + // privileged macro instructions + if (!SSW(U)) + { + switch (m_info.subopcode) + { + case 0x07: + // loadts: unknown? + break; + } + } + break; + + case 0xbc: + // waitd: + break; + + case 0xc0: + // s*: + break; +#endif + + default: + clipper_device::execute_instruction(); + break; + } +} + +util::disasm_interface *clipper_device::create_disassembler() { - return CPU_DISASSEMBLE_NAME(clipper)(this, stream, pc, oprom, opram, options); + return new clipper_disassembler; } diff --git a/src/devices/cpu/clipper/clipper.h b/src/devices/cpu/clipper/clipper.h index 27624b4e05a..1781401fece 100644 --- a/src/devices/cpu/clipper/clipper.h +++ b/src/devices/cpu/clipper/clipper.h @@ -7,6 +7,8 @@ #pragma once #include <limits.h> +#include "softfloat/milieu.h" +#include "softfloat/softfloat.h" // convenience macros for dealing with the psw and ssw #define PSW(mask) (m_psw & PSW_##mask) @@ -17,55 +19,48 @@ class clipper_device : public cpu_device public: DECLARE_READ32_MEMBER(get_ssw) const { return m_ssw; } DECLARE_WRITE8_MEMBER(set_ivec) { m_ivec = data; } + DECLARE_WRITE16_MEMBER(set_exception); -protected: - enum registers + enum addressing_modes : u8 { - CLIPPER_R0, CLIPPER_R1, CLIPPER_R2, CLIPPER_R3, CLIPPER_R4, CLIPPER_R5, CLIPPER_R6, CLIPPER_R7, - CLIPPER_R8, CLIPPER_R9, CLIPPER_R10, CLIPPER_R11, CLIPPER_R12, CLIPPER_R13, CLIPPER_R14, CLIPPER_R15, - - CLIPPER_F0, CLIPPER_F1, CLIPPER_F2, CLIPPER_F3, CLIPPER_F4, CLIPPER_F5, CLIPPER_F6, CLIPPER_F7, - CLIPPER_F8, CLIPPER_F9, CLIPPER_F10, CLIPPER_F11, CLIPPER_F12, CLIPPER_F13, CLIPPER_F14, CLIPPER_F15, - - CLIPPER_PSW, - CLIPPER_SSW, - CLIPPER_PC, + ADDR_MODE_PC32 = 0x10, // pc relative with 32 bit displacement + ADDR_MODE_ABS32 = 0x30, // 32 bit absolute + ADDR_MODE_REL32 = 0x60, // relative with 32 bit displacement + ADDR_MODE_PC16 = 0x90, // pc relative with 16 bit displacement + ADDR_MODE_REL12 = 0xa0, // relative with 12 bit displacement + ADDR_MODE_ABS16 = 0xb0, // 16 bit absolute + ADDR_MODE_PCX = 0xd0, // pc indexed + ADDR_MODE_RELX = 0xe0 // relative indexed }; - enum addressing_modes + // branch conditions (first description for comparison, second for move/logical) + enum branch_conditions : u8 { - ADDR_MODE_PC32 = 0x10, - ADDR_MODE_ABS32 = 0x30, - ADDR_MODE_REL32 = 0x60, - ADDR_MODE_PC16 = 0x90, - ADDR_MODE_REL12 = 0xa0, - ADDR_MODE_ABS16 = 0xb0, - ADDR_MODE_PCX = 0xd0, - ADDR_MODE_RELX = 0xe0, + BRANCH_T = 0x0, // always + BRANCH_LT = 0x1, // less than greater than + BRANCH_LE = 0x2, // less or equal greater or equal + BRANCH_EQ = 0x3, // equal + BRANCH_GT = 0x4, // greater than less than + BRANCH_GE = 0x5, // greater or equal less or equal + BRANCH_NE = 0x6, // not equal + BRANCH_LTU = 0x7, // less than unsigned greater than unsigned + BRANCH_LEU = 0x8, // less or equal unsigned greater or equal unsigned + BRANCH_GTU = 0x9, // greater than unsigned less than unsigned + BRANCH_GEU = 0xa, // greater or equal unsigned less or equal unsigned + BRANCH_V = 0xb, // overflow + BRANCH_NV = 0xc, // not overflow + BRANCH_N = 0xd, // negative + BRANCH_NN = 0xe, // not negative + BRANCH_FN = 0xf // floating unordered }; - // branch conditions - enum branch_conditions + enum bf_conditions : u8 { - BRANCH_T = 0x0, - BRANCH_LT = 0x1, - BRANCH_LE = 0x2, - BRANCH_EQ = 0x3, - BRANCH_GT = 0x4, - BRANCH_GE = 0x5, - BRANCH_NE = 0x6, - BRANCH_LTU = 0x7, - BRANCH_LEU = 0x8, - BRANCH_GTU = 0x9, - BRANCH_GEU = 0xa, - BRANCH_V = 0xb, - BRANCH_NV = 0xc, - BRANCH_N = 0xd, - BRANCH_NN = 0xe, - BRANCH_FN = 0xf, + BF_ANY = 0x0, // floating any exception + BF_BAD = 0x1 // floating bad result }; - enum psw + enum psw : u32 { PSW_N = 0x00000001, // negative PSW_Z = 0x00000002, // zero @@ -88,29 +83,37 @@ protected: PSW_BIG = 0x00400000, // c400 - big endian (hardware) PSW_T = 0x00800000, // trace trap PSW_CTS = 0x0f000000, // cpu trap status (4 bits) - PSW_MTS = 0xf0000000, // memory trap status (4 bits) + PSW_MTS = 0xf0000000 // memory trap status (4 bits) }; - enum clipper_ssw + enum psw_fr : u32 + { + FR_0 = 0x00000000, // round to nearest + FR_1 = 0x00008000, // round toward + infinity + FR_2 = 0x00010000, // round toward - infinity + FR_3 = 0x00018000 // round toward zero + }; + + enum ssw : u32 { SSW_IN = 0x0000000f, // interrupt number (4 bits) SSW_IL = 0x000000f0, // interrupt level (4 bits) SSW_EI = 0x00000100, // enable interrupts SSW_ID = 0x0001fe00, // cpu rev # and type (8 bits) - // unused (5 bits) + // unused (5 bits) SSW_FRD = 0x00400000, // floating registers dirty SSW_TP = 0x00800000, // trace trap pending - SSW_ECM = 0x01000000, // enabled corrected memory error + SSW_ECM = 0x01000000, // enable corrected memory error SSW_DF = 0x02000000, // fpu disabled SSW_M = 0x04000000, // mapped mode SSW_KU = 0x08000000, // user protect key SSW_UU = 0x10000000, // user data mode SSW_K = 0x20000000, // protect key SSW_U = 0x40000000, // user mode - SSW_P = 0x80000000, // previous mode + SSW_P = 0x80000000 // previous mode }; - enum clipper_ssw_id + enum ssw_id : u32 { SSW_ID_C400R0 = 0x00000, SSW_ID_C400R1 = 0x04000, @@ -119,7 +122,7 @@ protected: SSW_ID_C400R4 = 0x10000 }; - enum exception_vectors + enum exception_vectors : u16 { // data memory trap group EXCEPTION_D_CORRECTED_MEMORY_ERROR = 0x108, @@ -157,37 +160,55 @@ protected: EXCEPTION_SUPERVISOR_CALL_BASE = 0x400, // prioritized interrupts (0x800-0xff8) - EXCEPTION_INTERRUPT_BASE = 0x800, + EXCEPTION_INTERRUPT_BASE = 0x800 }; // trap source values are shifted into the correct field in the psw - enum cpu_trap_sources + static const int CTS_SHIFT = 24; + enum cpu_trap_sources : u32 { - CTS_NO_CPU_TRAP = 0 << 24, - CTS_DIVIDE_BY_ZERO = 2 << 24, - CTS_ILLEGAL_OPERATION = 4 << 24, - CTS_PRIVILEGED_INSTRUCTION = 5 << 24, - CTS_TRACE_TRAP = 7 << 24, + CTS_NO_CPU_TRAP = 0 << CTS_SHIFT, + CTS_DIVIDE_BY_ZERO = 2 << CTS_SHIFT, + CTS_ILLEGAL_OPERATION = 4 << CTS_SHIFT, + CTS_PRIVILEGED_INSTRUCTION = 5 << CTS_SHIFT, + CTS_TRACE_TRAP = 7 << CTS_SHIFT }; - enum memory_trap_sources + static const int MTS_SHIFT = 28; + enum memory_trap_sources : u32 { - MTS_NO_MEMORY_TRAP = 0 << 28, - MTS_CORRECTED_MEMORY_ERROR = 1 << 28, - MTS_UNCORRECTABLE_MEMORY_ERROR = 2 << 28, - MTS_ALIGNMENT_FAULT = 4 << 28, - MTS_PAGE_FAULT = 5 << 28, - MTS_READ_OR_EXECUTE_PROTECT_FAULT = 6 << 28, - MTS_WRITE_PROTECT_FAULT = 7 << 28, + MTS_NO_MEMORY_TRAP = 0 << MTS_SHIFT, + MTS_CORRECTED_MEMORY_ERROR = 1 << MTS_SHIFT, + MTS_UNCORRECTABLE_MEMORY_ERROR = 2 << MTS_SHIFT, + MTS_ALIGNMENT_FAULT = 4 << MTS_SHIFT, + MTS_PAGE_FAULT = 5 << MTS_SHIFT, + MTS_READ_OR_EXECUTE_PROTECT_FAULT = 6 << MTS_SHIFT, + MTS_WRITE_PROTECT_FAULT = 7 << MTS_SHIFT }; - enum ivec_mask + // extract an mts code from a vector + static const u32 MTS_VMASK = 0x00000038; + static const int MTS_VSHIFT = 3; + + enum ivec_mask : u8 { IVEC_NUMBER = 0x0f, IVEC_LEVEL = 0xf0 }; - clipper_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, const u32 cpuid); + // combinations of floating point exceptions (from softfloat flags) + enum fp_exception_mask : u8 + { + F_NONE = (0), + F_I = (float_flag_invalid), + F_X = (float_flag_inexact), + F_IX = (float_flag_invalid | float_flag_inexact), + F_IVUX = (float_flag_invalid | float_flag_overflow | float_flag_underflow | float_flag_inexact), + F_IVDUX = (float_flag_invalid | float_flag_overflow | float_flag_divbyzero | float_flag_underflow | float_flag_inexact) + }; + +protected: + clipper_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, const endianness_t endianness, const u32 cpuid); // device-level overrides virtual void device_start() override; @@ -204,67 +225,147 @@ protected: virtual space_config_vector memory_space_config() const override; // device_state_interface overrides -#if 0 - virtual void state_import(const device_state_entry &entry) override; - virtual void state_export(const device_state_entry &entry) override; -#endif virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; } // smallest instruction - virtual uint32_t disasm_max_opcode_bytes() const override { return 8; } // largest instruction - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; - void set_ssw(u32 data) { m_ssw = (m_ssw & SSW(ID)) | (data & ~SSW(ID)); } + // cpu execution logic + bool decode_instruction(); + virtual void execute_instruction(); + bool evaluate_branch() const; + + // exception entry and return helpers + u32 intrap(const u16 vector, const u32 old_pc); + u32 reti(); - // core registers - u32 m_pc; - u32 m_psw; - u32 m_ssw; + // cpu state helpers + void set_psw(const u32 psw); + void set_ssw(const u32 ssw); + void fp_exception(); - // integer registers - s32 *m_r; // active registers - s32 m_ru[16]; // user registers - s32 m_rs[16]; // supervisor registers + // register count helpers + virtual int get_ireg_count() const { return 16; } + virtual int get_freg_count() const { return 8; } - // floating registers - double m_f[16]; + // exception vector and frame helpers + virtual int get_eframe_size() const { return 12; } + virtual int get_evpc_offset() const { return 0; } + virtual int get_evssw_offset() const { return 4; } + // floating point helpers + float32 get_fp32(const u8 reg) const { return m_f[reg & 0xf]; } + float64 get_fp64(const u8 reg) const { return m_f[reg & 0xf]; } + template <typename T> void set_fp(const u8 reg, const T data, const fp_exception_mask exception_mask) + { + // suppress unexpected exceptions + float_exception_flags &= exception_mask; + + // save floating exception state + m_fp_pc = m_pc; + m_fp_dst = m_f[reg & 0xf]; + + // assign data + if (float_exception_flags & float_flag_overflow && PSW(EFV)) + { + /* + * If the EFV flag is set, the computed result is delivered to the + * destination with the normalized rounded fraction of the true + * result (though the delivered exponent is usually wrong because + * of missing additional leading bits in the exponent field). For + * single-precision overflows, if the biased exponent of the true + * result is 255, then biased exponent 255 is delivered to the + * destination. If the true biased exponent of the result is + * 256..408, then the true biased exponent minus 256 is delivered + * to the destination. Note that this is not the exponent wrapped + * result called for by the IEEE 754 specification; the wrap must + * be adjusted by system software before delivery to a user's trap + * handler. This is done to allow the user to provide software that + * handles traps in an application-specific way. For double- + * precision, the overflow exponents (biased) lie in the range + * 2047..3120. These are mapped to 2047 and 0..1072 respectively. + * These must be adjusted by (3/4)x2^11 (1536) to obtain the IEEE + * Standard wrapped exponent. + */ + // FIXME: implement non-IEEE behaviour described above + m_f[reg & 0xf] = data; + } + else if (float_exception_flags & float_flag_underflow && PSW(EFU)) + { + /* + * If EFU is set, the floating underflow exception is signalled + * when the result of an operation (before rounding) has a biased + * exponent less than the minimum representable biased exponent for + * a normalized number. If the true biased exponent of the result + * is zero, then biased exponent zero is delivered to the + * destination. If the true biased exponent is less than zero, then + * the exponent delivered to the destination is true biased + * exponent plus 256 (2048 for double). The exponent must be + * adjusted by system software before delivery to the program's + * trap handler in order to conform to the IEEE 754 specification. + * The range of underflowed biased exponents for single-precision + * is 0..-275; for double-precision the range is 0..-1125. + */ + // FIXME: implement non-IEEE behaviour described above + m_f[reg & 0xf] = data; + } + else + m_f[reg & 0xf] = data; + + // set floating dirty flag + m_ssw |= SSW_FRD; + }; + + // emulation state address_space_config m_insn_config; address_space_config m_data_config; address_space *m_insn; address_space *m_data; -private: - int m_icount; - - int m_irq; - int m_nmi; - u8 m_ivec; - - // decoded instruction information - struct + enum registers { - u8 opcode, subopcode; - u8 r1, r2; + CLIPPER_IREG = 0, + CLIPPER_FREG = 16, + CLIPPER_PSW = 32, + CLIPPER_SSW = 33, + CLIPPER_PC = 34, + }; - s32 imm; - u16 macro; + int m_icount; // instruction cycle count - // total size of instruction in bytes - u32 size; + // program-visible cpu state + u32 m_pc; // current instruction address + u32 m_psw; // program status word + u32 m_ssw; // system status word - // computed effective address - u32 address; - } m_info; + u32 *m_r; // active registers + u32 m_ru[16]; // user registers + u32 m_rs[16]; // supervisor registers - void decode_instruction(u16 insn); - int execute_instruction(); - bool evaluate_branch() const; + u64 m_f[16]; // floating point registers + u32 m_fp_pc; // address of floating point instruction causing exception + u64 m_fp_dst; // original value of destination register during fp exception -protected: - virtual uint32_t intrap(u32 vector, u32 pc, u32 cts = CTS_NO_CPU_TRAP, u32 mts = MTS_NO_MEMORY_TRAP); + // non-visible cpu state + u32 m_ip; // next instruction address + int m_irq; // interrupt request state + int m_nmi; // non-maskable interrupt state + u8 m_ivec; // interrupt vector + u16 m_exception; // pending exception + + // decoded instruction information + struct decode + { + u8 opcode; // primary instruction opcode + u8 subopcode; // secondary instruction opcode + u8 r1; // r1 instruction operand + u8 r2; // r2 instruction operand + u32 imm; // immediate value operand + u16 macro; // macro instruction operands + u32 address; // computed effective address + } + m_info; }; class clipper_c100_device : public clipper_device @@ -285,13 +386,23 @@ public: clipper_c400_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); protected: - virtual uint32_t intrap(u32 vector, u32 pc, u32 cts = CTS_NO_CPU_TRAP, u32 mts = MTS_NO_MEMORY_TRAP) override; + // C400 has additional 8 floating point registers + virtual int get_freg_count() const override { return 16; } + + // C400 creates a 24 byte exception frame (C100/C300 is 12 bytes), but the + // service routine must increment sp by 12 prior to executing reti + // exception frame size + virtual int get_eframe_size() const override { return 24; } + + // C400 pc and ssw are reversed in exception vector compared to C100/C300 + virtual int get_evpc_offset() const override { return 4; } + virtual int get_evssw_offset() const override { return 0; } + + virtual void execute_instruction() override; }; DECLARE_DEVICE_TYPE(CLIPPER_C100, clipper_c100_device) DECLARE_DEVICE_TYPE(CLIPPER_C300, clipper_c300_device) DECLARE_DEVICE_TYPE(CLIPPER_C400, clipper_c400_device) -extern CPU_DISASSEMBLE(clipper); - #endif // MAME_CPU_CLIPPER_CLIPPER_H diff --git a/src/devices/cpu/clipper/clipperd.cpp b/src/devices/cpu/clipper/clipperd.cpp index 521f13d1c8d..d328d3b4631 100644 --- a/src/devices/cpu/clipper/clipperd.cpp +++ b/src/devices/cpu/clipper/clipperd.cpp @@ -2,6 +2,7 @@ // copyright-holders:Patrick Mackinlay #include "emu.h" +#include "clipperd.h" /* * TODO @@ -14,33 +15,20 @@ // enable C400 instruction decoding #define C400_INSTRUCTIONS 1 -// the CLIPPER addressing modes (unshifted) -enum -{ - ADDR_MODE_PC32 = 0x10, - ADDR_MODE_ABS32 = 0x30, - ADDR_MODE_REL32 = 0x60, - ADDR_MODE_PC16 = 0x90, - ADDR_MODE_REL12 = 0xa0, - ADDR_MODE_ABS16 = 0xb0, - ADDR_MODE_PCX = 0xd0, - ADDR_MODE_RELX = 0xe0 -}; - // macros for decoding various operand fields -#define R1 ((insn[0] & 0x00f0) >> 4) -#define R2 (insn[0] & 0x000f) +#define R1 ((opcodes.r16(pc) & 0x00f0) >> 4) +#define R2 (opcodes.r16(pc) & 0x000f) -#define I16 ((int16_t)insn[1]) -#define I32 (*(int32_t *)&insn[1]) -#define IMM_VALUE (insn[0] & 0x0080 ? I16 : I32) -#define IMM_SIZE (insn[0] & 0x0080 ? 2 : 4) +#define I16 (int16_t(opcodes.r16(pc+2))) +#define I32 (int32_t(opcodes.r32(pc+2))) +#define IMM_VALUE (opcodes.r16(pc) & 0x0080 ? I16 : I32) +#define IMM_SIZE (opcodes.r16(pc) & 0x0080 ? 2 : 4) -#define ADDR_MODE (insn[0] & 0x00f0) -#define ADDR_R2 ((insn[0] & 0x0050) == 0x0010 ? (insn[0] & 0x000f) : (insn[1] & 0x000f)) +#define ADDR_MODE (opcodes.r16(pc) & 0x00f0) +#define ADDR_R2 ((opcodes.r16(pc) & 0x0050) == 0x0010 ? (opcodes.r16(pc) & 0x000f) : (opcodes.r16(pc+2) & 0x000f)) #define ADDR_SIZE (ADDR_MODE > ADDR_MODE_REL32 ? 2 : ADDR_MODE == ADDR_MODE_REL32 ? 6 : 4) -#define ADDR_RX ((insn[1] & 0xf0) >> 4) -#define ADDR_I12 (((int16_t)insn[1]) >> 4) +#define ADDR_RX ((opcodes.r16(pc+2) & 0xf0) >> 4) +#define ADDR_I12 (((int16_t)opcodes.r16(pc+2)) >> 4) /* * Branch condition code mnemonics - the forms beginning with 'c' are @@ -49,7 +37,7 @@ enum * instructions. We use the first form because we can't know which type * should be used without some kind of dynamic information. */ -static const char *const cc[] = +const char *const clipper_disassembler::cc[] = { "", "clt", // rgt @@ -72,13 +60,13 @@ static const char *const cc[] = /* * Decode an addressing mode into a string. */ -std::string address (offs_t pc, u16 *insn) +std::string clipper_disassembler::address (offs_t pc, const data_buffer &opcodes) { switch (ADDR_MODE) { case ADDR_MODE_PC32: return util::string_format("0x%x", pc + I32); case ADDR_MODE_ABS32: return util::string_format("0x%x", I32); - case ADDR_MODE_REL32: return util::string_format("%d(r%d)", *(int32_t *)&insn[2], R2); + case ADDR_MODE_REL32: return util::string_format("%d(r%d)", opcodes.r32(pc+4), R2); case ADDR_MODE_PC16: return util::string_format("0x%x", pc + I16); case ADDR_MODE_REL12: return util::string_format("%d(r%d)", ADDR_I12, R2); case ADDR_MODE_ABS16: return util::string_format("0x%x", I16); @@ -96,26 +84,30 @@ std::string address (offs_t pc, u16 *insn) * an on-CPU macro instruction ROM. It appears at least some of these macro instructions were removed * from the C400 and generate traps which can be used to implement them in software instead. */ -CPU_DISASSEMBLE(clipper) +u32 clipper_disassembler::opcode_alignment() const +{ + return 2; +} + +offs_t clipper_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - u16 *insn = (u16 *)oprom; - u32 flags = DASMFLAG_SUPPORTED; + u32 flags = SUPPORTED; offs_t bytes; - switch (insn[0] >> 8) + switch (opcodes.r16(pc) >> 8) { case 0x00: - if (oprom[0] == 0) + if (opcodes.r16(pc) == 0) util::stream_format(stream, "noop"); else - util::stream_format(stream, "noop $%d", oprom[0]); + util::stream_format(stream, "noop $%d", opcodes.r16(pc)); bytes = 2; break; case 0x10: util::stream_format(stream, "movwp r%d,%s", R2, R1 == 0 ? "psw" : R1 == 1 ? "ssw" : "sswf"); bytes = 2; break; case 0x11: util::stream_format(stream, "movpw %s,r%d", R1 == 0 ? "psw" : "ssw", R2); bytes = 2; break; - case 0x12: util::stream_format(stream, "calls $%d", insn[0] & 0x7F); bytes = 2; flags |= DASMFLAG_STEP_OVER; break; - case 0x13: util::stream_format(stream, "ret r%d", R2); bytes = 2; flags |= DASMFLAG_STEP_OUT; break; + case 0x12: util::stream_format(stream, "calls $%d", opcodes.r16(pc) & 0x7F); bytes = 2; flags |= STEP_OVER; break; + case 0x13: util::stream_format(stream, "ret r%d", R2); bytes = 2; flags |= STEP_OUT; break; case 0x14: util::stream_format(stream, "pushw r%d,r%d", R2, R1); bytes = 2; break; case 0x16: util::stream_format(stream, "popw r%d,r%d", R1, R2); bytes = 2; break; @@ -151,60 +143,60 @@ CPU_DISASSEMBLE(clipper) case 0x3c: util::stream_format(stream, "roti $%d,r%d", I16, R2); bytes = 4; break; case 0x3d: util::stream_format(stream, "rotli $%d,r%d:r%d", I16, R2 + 0, R2 + 1); bytes = 4; break; - case 0x44: util::stream_format(stream, "call r%d,(r%d)", R2, R1); bytes = 2; flags |= DASMFLAG_STEP_OVER; break; - case 0x45: util::stream_format(stream, "call r%d,%s", ADDR_R2, address(pc, insn)); bytes = 2 + ADDR_SIZE; flags |= DASMFLAG_STEP_OVER; break; + case 0x44: util::stream_format(stream, "call r%d,(r%d)", R2, R1); bytes = 2; flags |= STEP_OVER; break; + case 0x45: util::stream_format(stream, "call r%d,%s", ADDR_R2, address(pc, opcodes)); bytes = 2 + ADDR_SIZE; flags |= STEP_OVER; break; #if C400_INSTRUCTIONS case 0x46: util::stream_format(stream, "loadd2 (r%d),f%d", R1, R2); bytes = 2; break; - case 0x47: util::stream_format(stream, "loadd2 %s,f%d", address(pc, insn), ADDR_R2); bytes = 2 + ADDR_SIZE; break; + case 0x47: util::stream_format(stream, "loadd2 %s,f%d", address(pc, opcodes), ADDR_R2); bytes = 2 + ADDR_SIZE; break; #endif case 0x48: util::stream_format(stream, "b%-4s (r%d)", cc[R2], R1); bytes = 2; break; - case 0x49: util::stream_format(stream, "b%-4s %s", cc[ADDR_R2], address(pc, insn)); bytes = 2 + ADDR_SIZE; break; + case 0x49: util::stream_format(stream, "b%-4s %s", cc[ADDR_R2], address(pc, opcodes)); bytes = 2 + ADDR_SIZE; break; #if C400_INSTRUCTIONS // delayed branches case 0x4a: util::stream_format(stream, "cdb r%d,(r%d)", R2, R1); bytes = 2; break; - case 0x4b: util::stream_format(stream, "cdb r%d,%s", ADDR_R2, address(pc, insn)); bytes = 2 + ADDR_SIZE; break; + case 0x4b: util::stream_format(stream, "cdb r%d,%s", ADDR_R2, address(pc, opcodes)); bytes = 2 + ADDR_SIZE; break; case 0x4c: util::stream_format(stream, "cdbeq r%d,(r%d)", R2, R1); bytes = 2; break; - case 0x4d: util::stream_format(stream, "cdbeq r%d,%s", ADDR_R2, address(pc, insn)); bytes = 2 + ADDR_SIZE; break; + case 0x4d: util::stream_format(stream, "cdbeq r%d,%s", ADDR_R2, address(pc, opcodes)); bytes = 2 + ADDR_SIZE; break; case 0x4e: util::stream_format(stream, "cdbne r%d,(r%d)", R2, R1); bytes = 2; break; - case 0x4f: util::stream_format(stream, "cdbne r%d,%s", ADDR_R2, address(pc, insn)); bytes = 2 + ADDR_SIZE; break; + case 0x4f: util::stream_format(stream, "cdbne r%d,%s", ADDR_R2, address(pc, opcodes)); bytes = 2 + ADDR_SIZE; break; case 0x50: util::stream_format(stream, "db%-4s (r%d)", cc[R2], R1); bytes = 2; break; - case 0x51: util::stream_format(stream, "db%-4s %s", cc[ADDR_R2], address(pc, insn)); bytes = 2 + ADDR_SIZE; break; + case 0x51: util::stream_format(stream, "db%-4s %s", cc[ADDR_R2], address(pc, opcodes)); bytes = 2 + ADDR_SIZE; break; #else // these instructions are in the C300 documentation, but appear to be replaced in the C400 case 0x4c: util::stream_format(stream, "bf%s (r%d)", R2 == 0 ? "any" : "bad", R1); bytes = 2; break; - case 0x4d: util::stream_format(stream, "bf%s %s", ADDR_R2 == 0 ? "any" : "bad", address(pc, insn)); bytes = 2 + ADDR_SIZE; break; + case 0x4d: util::stream_format(stream, "bf%s %s", ADDR_R2 == 0 ? "any" : "bad", address(pc, opcodes)); bytes = 2 + ADDR_SIZE; break; #endif case 0x60: util::stream_format(stream, "loadw (r%d),r%d", R1, R2); bytes = 2; break; - case 0x61: util::stream_format(stream, "loadw %s,r%d", address(pc, insn), ADDR_R2); bytes = 2 + ADDR_SIZE; break; + case 0x61: util::stream_format(stream, "loadw %s,r%d", address(pc, opcodes), ADDR_R2); bytes = 2 + ADDR_SIZE; break; case 0x62: util::stream_format(stream, "loada (r%d),r%d", R1, R2); bytes = 2; break; - case 0x63: util::stream_format(stream, "loada %s,r%d", address(pc, insn), ADDR_R2); bytes = 2 + ADDR_SIZE; break; + case 0x63: util::stream_format(stream, "loada %s,r%d", address(pc, opcodes), ADDR_R2); bytes = 2 + ADDR_SIZE; break; case 0x64: util::stream_format(stream, "loads (r%d),f%d", R1, R2); bytes = 2; break; - case 0x65: util::stream_format(stream, "loads %s,f%d", address(pc, insn), ADDR_R2); bytes = 2 + ADDR_SIZE; break; + case 0x65: util::stream_format(stream, "loads %s,f%d", address(pc, opcodes), ADDR_R2); bytes = 2 + ADDR_SIZE; break; case 0x66: util::stream_format(stream, "loadd (r%d),f%d", R1, R2); bytes = 2; break; - case 0x67: util::stream_format(stream, "loadd %s,f%d", address(pc, insn), ADDR_R2); bytes = 2 + ADDR_SIZE; break; + case 0x67: util::stream_format(stream, "loadd %s,f%d", address(pc, opcodes), ADDR_R2); bytes = 2 + ADDR_SIZE; break; case 0x68: util::stream_format(stream, "loadb (r%d),r%d", R1, R2); bytes = 2; break; - case 0x69: util::stream_format(stream, "loadb %s,r%d", address(pc, insn), ADDR_R2); bytes = 2 + ADDR_SIZE; break; + case 0x69: util::stream_format(stream, "loadb %s,r%d", address(pc, opcodes), ADDR_R2); bytes = 2 + ADDR_SIZE; break; case 0x6a: util::stream_format(stream, "loadbu (r%d),r%d", R1, R2); bytes = 2; break; - case 0x6b: util::stream_format(stream, "loadbu %s,r%d", address(pc, insn), ADDR_R2); bytes = 2 + ADDR_SIZE; break; + case 0x6b: util::stream_format(stream, "loadbu %s,r%d", address(pc, opcodes), ADDR_R2); bytes = 2 + ADDR_SIZE; break; case 0x6c: util::stream_format(stream, "loadh (r%d),r%d", R1, R2); bytes = 2; break; - case 0x6d: util::stream_format(stream, "loadh %s,r%d", address(pc, insn), ADDR_R2); bytes = 2 + ADDR_SIZE; break; + case 0x6d: util::stream_format(stream, "loadh %s,r%d", address(pc, opcodes), ADDR_R2); bytes = 2 + ADDR_SIZE; break; case 0x6e: util::stream_format(stream, "loadhu (r%d),r%d", R1, R2); bytes = 2; break; - case 0x6f: util::stream_format(stream, "loadhu %s,r%d", address(pc, insn), ADDR_R2); bytes = 2 + ADDR_SIZE; break; + case 0x6f: util::stream_format(stream, "loadhu %s,r%d", address(pc, opcodes), ADDR_R2); bytes = 2 + ADDR_SIZE; break; case 0x70: util::stream_format(stream, "storw r%d,(r%d)", R2, R1); bytes = 2; break; - case 0x71: util::stream_format(stream, "storw r%d,%s", ADDR_R2, address(pc, insn)); bytes = 2 + ADDR_SIZE; break; + case 0x71: util::stream_format(stream, "storw r%d,%s", ADDR_R2, address(pc, opcodes)); bytes = 2 + ADDR_SIZE; break; case 0x72: util::stream_format(stream, "tsts (r%d),r%d", R1, R2); bytes = 2; break; - case 0x73: util::stream_format(stream, "tsts %s,r%d", address(pc, insn), ADDR_R2); bytes = 2 + ADDR_SIZE; break; + case 0x73: util::stream_format(stream, "tsts %s,r%d", address(pc, opcodes), ADDR_R2); bytes = 2 + ADDR_SIZE; break; case 0x74: util::stream_format(stream, "stors f%d,(r%d)", R2, R1); bytes = 2; break; - case 0x75: util::stream_format(stream, "stors f%d,%s", ADDR_R2, address(pc, insn)); bytes = 2 + ADDR_SIZE; break; + case 0x75: util::stream_format(stream, "stors f%d,%s", ADDR_R2, address(pc, opcodes)); bytes = 2 + ADDR_SIZE; break; case 0x76: util::stream_format(stream, "stord f%d,(r%d)", R2, R1); bytes = 2; break; - case 0x77: util::stream_format(stream, "stord f%d,%s", ADDR_R2, address(pc, insn)); bytes = 2 + ADDR_SIZE; break; + case 0x77: util::stream_format(stream, "stord f%d,%s", ADDR_R2, address(pc, opcodes)); bytes = 2 + ADDR_SIZE; break; case 0x78: util::stream_format(stream, "storb r%d,(r%d)", R2, R1); bytes = 2; break; - case 0x79: util::stream_format(stream, "storb r%d,%s", ADDR_R2, address(pc, insn)); bytes = 2 + ADDR_SIZE; break; + case 0x79: util::stream_format(stream, "storb r%d,%s", ADDR_R2, address(pc, opcodes)); bytes = 2 + ADDR_SIZE; break; case 0x7c: util::stream_format(stream, "storh r%d,(r%d)", R2, R1); bytes = 2; break; - case 0x7d: util::stream_format(stream, "storh r%d,%s", ADDR_R2, address(pc, insn)); bytes = 2 + ADDR_SIZE; break; + case 0x7d: util::stream_format(stream, "storh r%d,%s", ADDR_R2, address(pc, opcodes)); bytes = 2 + ADDR_SIZE; break; case 0x80: util::stream_format(stream, "addw r%d,r%d", R1, R2); bytes = 2; break; @@ -258,7 +250,7 @@ CPU_DISASSEMBLE(clipper) case 0xb4: case 0xb5: // unprivileged macro instructions - switch (insn[0] & 0xff) + switch (opcodes.r16(pc) & 0xff) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: @@ -288,25 +280,25 @@ CPU_DISASSEMBLE(clipper) util::stream_format(stream, "restd%d", R2); break; - case 0x30: util::stream_format(stream, "cnvsw f%d,r%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; - case 0x31: util::stream_format(stream, "cnvrsw f%d,r%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; - case 0x32: util::stream_format(stream, "cnvtsw f%d,r%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; - case 0x33: util::stream_format(stream, "cnvws r%d,f%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; - case 0x34: util::stream_format(stream, "cnvdw f%d,r%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; - case 0x35: util::stream_format(stream, "cnvrdw f%d,r%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; - case 0x36: util::stream_format(stream, "cnvtdw f%d,r%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; - case 0x37: util::stream_format(stream, "cnvwd r%d,f%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; - case 0x38: util::stream_format(stream, "cnvsd f%d,f%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; - case 0x39: util::stream_format(stream, "cnvds f%d,f%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; - case 0x3a: util::stream_format(stream, "negs f%d,f%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; - case 0x3b: util::stream_format(stream, "negd f%d,f%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; - case 0x3c: util::stream_format(stream, "scalbs r%d,f%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; - case 0x3d: util::stream_format(stream, "scalbd r%d,f%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; + case 0x30: util::stream_format(stream, "cnvsw f%d,r%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; + case 0x31: util::stream_format(stream, "cnvrsw f%d,r%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; + case 0x32: util::stream_format(stream, "cnvtsw f%d,r%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; + case 0x33: util::stream_format(stream, "cnvws r%d,f%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; + case 0x34: util::stream_format(stream, "cnvdw f%d,r%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; + case 0x35: util::stream_format(stream, "cnvrdw f%d,r%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; + case 0x36: util::stream_format(stream, "cnvtdw f%d,r%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; + case 0x37: util::stream_format(stream, "cnvwd r%d,f%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; + case 0x38: util::stream_format(stream, "cnvsd f%d,f%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; + case 0x39: util::stream_format(stream, "cnvds f%d,f%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; + case 0x3a: util::stream_format(stream, "negs f%d,f%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; + case 0x3b: util::stream_format(stream, "negd f%d,f%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; + case 0x3c: util::stream_format(stream, "scalbs r%d,f%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; + case 0x3d: util::stream_format(stream, "scalbd r%d,f%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; case 0x3e: util::stream_format(stream, "trapfn"); break; - case 0x3f: util::stream_format(stream, "loadfs r%d,f%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; + case 0x3f: util::stream_format(stream, "loadfs r%d,f%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; default: - util::stream_format(stream, "macro 0x%04x 0x%04x", insn[0], insn[1]); + util::stream_format(stream, "macro 0x%04x 0x%04x", opcodes.r16(pc), opcodes.r16(pc+2)); break; } bytes = 4; @@ -314,19 +306,19 @@ CPU_DISASSEMBLE(clipper) case 0xb6: case 0xb7: // privileged macro instructions - switch (insn[0] & 0xff) + switch (opcodes.r16(pc) & 0xff) { - case 0x00: util::stream_format(stream, "movus r%d,r%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; - case 0x01: util::stream_format(stream, "movsu r%d,r%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; - case 0x02: util::stream_format(stream, "saveur r%d", (insn[1] & 0xf0) >> 4); break; - case 0x03: util::stream_format(stream, "restur r%d", (insn[1] & 0xf0) >> 4); break; - case 0x04: util::stream_format(stream, "reti r%d", (insn[1] & 0xf0) >> 4); flags |= DASMFLAG_STEP_OUT; break; + case 0x00: util::stream_format(stream, "movus r%d,r%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; + case 0x01: util::stream_format(stream, "movsu r%d,r%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; + case 0x02: util::stream_format(stream, "saveur r%d", (opcodes.r16(pc+2) & 0xf0) >> 4); break; + case 0x03: util::stream_format(stream, "restur r%d", (opcodes.r16(pc+2) & 0xf0) >> 4); break; + case 0x04: util::stream_format(stream, "reti r%d", (opcodes.r16(pc+2) & 0xf0) >> 4); flags |= STEP_OUT; break; case 0x05: util::stream_format(stream, "wait"); break; #if C400_INSTRUCTIONS - case 0x07: util::stream_format(stream, "loadts r%d,f%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; + case 0x07: util::stream_format(stream, "loadts r%d,f%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; #endif default: - util::stream_format(stream, "macro 0x%04x 0x%04x", insn[0], insn[1]); + util::stream_format(stream, "macro 0x%04x 0x%04x", opcodes.r16(pc), opcodes.r16(pc+2)); break; } bytes = 4; @@ -338,7 +330,7 @@ CPU_DISASSEMBLE(clipper) #endif default: - util::stream_format(stream, ".word 0x%04x", insn[0]); + util::stream_format(stream, ".word 0x%04x", opcodes.r16(pc)); bytes = 2; break; } diff --git a/src/devices/cpu/clipper/clipperd.h b/src/devices/cpu/clipper/clipperd.h new file mode 100644 index 00000000000..1dd757fde63 --- /dev/null +++ b/src/devices/cpu/clipper/clipperd.h @@ -0,0 +1,37 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay + +#ifndef MAME_CPU_CLIPPER_CLIPPERDASM_H +#define MAME_CPU_CLIPPER_CLIPPERDASM_H + +#pragma once + +class clipper_disassembler : public util::disasm_interface +{ +public: + clipper_disassembler() = default; + virtual ~clipper_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum addressing_modes : u8 + { + ADDR_MODE_PC32 = 0x10, // pc relative with 32 bit displacement + ADDR_MODE_ABS32 = 0x30, // 32 bit absolute + ADDR_MODE_REL32 = 0x60, // relative with 32 bit displacement + ADDR_MODE_PC16 = 0x90, // pc relative with 16 bit displacement + ADDR_MODE_REL12 = 0xa0, // relative with 12 bit displacement + ADDR_MODE_ABS16 = 0xb0, // 16 bit absolute + ADDR_MODE_PCX = 0xd0, // pc indexed + ADDR_MODE_RELX = 0xe0 // relative indexed + }; + + static const char *const cc[]; + std::string address (offs_t pc, const data_buffer &opcodes); + + +}; + +#endif diff --git a/src/devices/cpu/cop400/cop400.cpp b/src/devices/cpu/cop400/cop400.cpp index 30b1680150a..03416a54b28 100644 --- a/src/devices/cpu/cop400/cop400.cpp +++ b/src/devices/cpu/cop400/cop400.cpp @@ -56,6 +56,10 @@ #include "emu.h" #include "debugger.h" #include "cop400.h" +#include "cop410ds.h" +#include "cop420ds.h" +#include "cop424ds.h" +#include "cop444ds.h" DEFINE_DEVICE_TYPE(COP401, cop401_cpu_device, "cop401", "COP401") @@ -1064,7 +1068,7 @@ void cop400_cpu_device::device_start() { /* find address spaces */ m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_data = &space(AS_DATA); /* find i/o handlers */ @@ -1117,9 +1121,10 @@ void cop400_cpu_device::device_start() // setup debugger state display offs_t pc_mask = m_program->addrmask(); + using namespace std::placeholders; state_add(STATE_GENPC, "GENPC", m_pc).mask(pc_mask).noshow(); state_add(STATE_GENPCBASE, "CURPC", m_prevpc).mask(pc_mask).noshow(); - state_add(STATE_GENFLAGS, "GENFLAGS", m_flags).mask(0x7).callimport().callexport().noshow().formatstr("%3s"); + state_add<uint8_t>(STATE_GENFLAGS, "GENFLAGS", std::bind(&cop400_cpu_device::get_flags, this), std::bind(&cop400_cpu_device::set_flags, this, _1)).mask(0x7).noshow().formatstr("%3s"); state_add(COP400_PC, "PC", m_pc).mask(pc_mask); state_add(COP400_SA, "SA", m_sa).mask(pc_mask); state_add(COP400_SB, "SB", m_sb).mask(pc_mask); @@ -1127,7 +1132,7 @@ void cop400_cpu_device::device_start() state_add(COP400_SC, "SC", m_sc).mask(pc_mask); state_add(COP400_B, "B", m_b); state_add(COP400_A, "A", m_a).mask(0xf); - state_add(COP400_M, "M", m_temp_m).mask(0xf).callimport().callexport(); + state_add<uint8_t>(COP400_M, "M", std::bind(&cop400_cpu_device::get_m, this), std::bind(&cop400_cpu_device::set_m, this, _1)).mask(0xf); state_add(COP400_G, "G", m_g).mask(0xf); state_add(COP400_Q, "Q", m_q); state_add(COP400_SIO, "SIO", m_sio).mask(0xf).formatstr("%4s"); @@ -1145,8 +1150,6 @@ void cop400_cpu_device::device_start() m_sb = 0; m_sc = 0; m_sio = 0; - m_flags = 0; - m_temp_m = 0; m_il = 0; m_in[0] = m_in[1] = m_in[2] = m_in[3] = 0; m_si = 0; @@ -1309,36 +1312,28 @@ void cop400_cpu_device::execute_run() GENERAL CONTEXT ACCESS ***************************************************************************/ -void cop400_cpu_device::state_import(const device_state_entry &entry) +uint8_t cop400_cpu_device::get_flags() const { - switch (entry.index()) - { - case STATE_GENFLAGS: - m_skt_latch = BIT(m_flags, 2); - m_c = BIT(m_flags, 1); - m_skl = BIT(m_flags, 0); - break; + return (m_skt_latch ? 0x04 : 0x00) | (m_c ? 0x02 : 0x00) | (m_skl ? 0x01 : 0x00); +} - case COP400_M: - auto dis = machine().disable_side_effect(); - RAM_W(B, m_temp_m); - break; - } +void cop400_cpu_device::set_flags(uint8_t flags) +{ + m_skt_latch = BIT(flags, 2); + m_c = BIT(flags, 1); + m_skl = BIT(flags, 0); } -void cop400_cpu_device::state_export(const device_state_entry &entry) +uint8_t cop400_cpu_device::get_m() const { - switch (entry.index()) - { - case STATE_GENFLAGS: - m_flags = (m_skt_latch ? 0x04 : 0x00) | (m_c ? 0x02 : 0x00) | (m_skl ? 0x01 : 0x00); - break; + auto dis = machine().disable_side_effect(); + return RAM_R(B); +} - case COP400_M: - auto dis = machine().disable_side_effect(); - m_temp_m = RAM_R(B); - break; - } +void cop400_cpu_device::set_m(uint8_t m) +{ + auto dis = machine().disable_side_effect(); + RAM_W(B, m); } void cop400_cpu_device::state_string_export(const device_state_entry &entry, std::string &str) const @@ -1371,29 +1366,24 @@ void cop400_cpu_device::state_string_export(const device_state_entry &entry, std } -offs_t cop400_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *cop400_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( cop410 ); - extern CPU_DISASSEMBLE( cop420 ); - extern CPU_DISASSEMBLE( cop444 ); - extern CPU_DISASSEMBLE( cop424 ); - if ( m_featuremask & COP424C_FEATURE ) { - return CPU_DISASSEMBLE_NAME(cop424)(this, stream, pc, oprom, opram, options); + return new cop424_disassembler; } if ( m_featuremask & COP444L_FEATURE ) { - return CPU_DISASSEMBLE_NAME(cop444)(this, stream, pc, oprom, opram, options); + return new cop444_disassembler; } if ( m_featuremask & COP420_FEATURE ) { - return CPU_DISASSEMBLE_NAME(cop420)(this, stream, pc, oprom, opram, options); + return new cop420_disassembler; } - return CPU_DISASSEMBLE_NAME(cop410)(this, stream, pc, oprom, opram, options); + return new cop410_disassembler; } READ8_MEMBER( cop400_cpu_device::microbus_rd ) diff --git a/src/devices/cpu/cop400/cop400.h b/src/devices/cpu/cop400/cop400.h index 13461ffe583..d98d7bbbc6f 100644 --- a/src/devices/cpu/cop400/cop400.h +++ b/src/devices/cpu/cop400/cop400.h @@ -162,14 +162,10 @@ protected: virtual space_config_vector memory_space_config() const override; // device_state_interface overrides - virtual void state_import(const device_state_entry &entry) override; - virtual void state_export(const device_state_entry &entry) override; virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 2; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; address_space_config m_program_config; address_space_config m_data_config; @@ -209,7 +205,7 @@ protected: bool m_has_inil; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_data; uint8_t m_featuremask; @@ -226,8 +222,6 @@ protected: uint16_t m_sa, m_sb, m_sc; /* subroutine save registers */ uint8_t m_sio; /* 4-bit shift register and counter */ int m_skl; /* 1-bit latch for SK output */ - uint8_t m_flags; // used for debugger state only - uint8_t m_temp_m; // 4-bit RAM at B (for debugger state only) /* counter */ uint8_t m_t; /* 8-bit timer */ @@ -289,6 +283,11 @@ protected: void skip(); void sk_update(); + uint8_t get_flags() const; + void set_flags(uint8_t flags); + uint8_t get_m() const; + void set_m(uint8_t m); + void illegal(uint8_t operand); void asc(uint8_t operand); void add(uint8_t operand); diff --git a/src/devices/cpu/cop400/cop410ds.cpp b/src/devices/cpu/cop400/cop410ds.cpp index 4570417538f..9da69df8034 100644 --- a/src/devices/cpu/cop400/cop410ds.cpp +++ b/src/devices/cpu/cop400/cop410ds.cpp @@ -9,11 +9,17 @@ ***************************************************************************/ #include "emu.h" +#include "cop410ds.h" -CPU_DISASSEMBLE(cop410) +u32 cop410_disassembler::opcode_alignment() const { - uint8_t opcode = oprom[0]; - uint8_t next_opcode = oprom[1]; + return 1; +} + +offs_t cop410_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + uint8_t opcode = opcodes.r8(pc); + uint8_t next_opcode = opcodes.r8(pc+1); uint16_t address; uint32_t flags = 0; int bytes = 1; @@ -38,7 +44,7 @@ CPU_DISASSEMBLE(cop410) { address = (uint16_t)(0x80 | (opcode & 0x3F)); util::stream_format(stream, "JSRP %03X", address); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; } } } @@ -72,7 +78,7 @@ CPU_DISASSEMBLE(cop410) { address = ((opcode & 0x01) << 8) | next_opcode; util::stream_format(stream, "JSR %03X", address); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; bytes = 2; } else if (opcode >= 0x70 && opcode <= 0x7F) @@ -302,12 +308,12 @@ CPU_DISASSEMBLE(cop410) case 0x48: util::stream_format(stream, "RET"); - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; case 0x49: util::stream_format(stream, "RETSK"); - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; case 0x4B: @@ -348,5 +354,5 @@ CPU_DISASSEMBLE(cop410) } } - return bytes | flags | DASMFLAG_SUPPORTED; + return bytes | flags | SUPPORTED; } diff --git a/src/devices/cpu/cop400/cop410ds.h b/src/devices/cpu/cop400/cop410ds.h new file mode 100644 index 00000000000..c1841ec996c --- /dev/null +++ b/src/devices/cpu/cop400/cop410ds.h @@ -0,0 +1,26 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/*************************************************************************** + + cop410ds.c + + National Semiconductor COP410 Emulator. + +***************************************************************************/ + +#ifndef MAME_CPU_COP410_COP410DS_H +#define MAME_CPU_COP410_COP410DS_H + +#pragma once + +class cop410_disassembler : public util::disasm_interface +{ +public: + cop410_disassembler() = default; + virtual ~cop410_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/cop400/cop420ds.cpp b/src/devices/cpu/cop400/cop420ds.cpp index 39ea87ba9b4..f8f910f174b 100644 --- a/src/devices/cpu/cop400/cop420ds.cpp +++ b/src/devices/cpu/cop400/cop420ds.cpp @@ -9,11 +9,17 @@ ***************************************************************************/ #include "emu.h" +#include "cop420ds.h" -CPU_DISASSEMBLE(cop420) +u32 cop420_disassembler::opcode_alignment() const { - uint8_t opcode = oprom[0]; - uint8_t next_opcode = oprom[1]; + return 1; +} + +offs_t cop420_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + uint8_t opcode = opcodes.r8(pc); + uint8_t next_opcode = opcodes.r8(pc+1); uint16_t address; uint32_t flags = 0; int bytes = 1; @@ -38,7 +44,7 @@ CPU_DISASSEMBLE(cop420) { address = (uint16_t)(0x80 | (opcode & 0x3F)); util::stream_format(stream, "JSRP %03X", address); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; } } } @@ -72,7 +78,7 @@ CPU_DISASSEMBLE(cop420) { address = ((opcode & 0x03) << 8) | next_opcode; util::stream_format(stream, "JSR %03X", address); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; bytes = 2; } else if (opcode >= 0x70 && opcode <= 0x7F) @@ -346,12 +352,12 @@ CPU_DISASSEMBLE(cop420) case 0x48: util::stream_format(stream, "RET"); - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; case 0x49: util::stream_format(stream, "RETSK"); - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; case 0x4A: @@ -396,5 +402,5 @@ CPU_DISASSEMBLE(cop420) } } - return bytes | flags | DASMFLAG_SUPPORTED; + return bytes | flags | SUPPORTED; } diff --git a/src/devices/cpu/cop400/cop420ds.h b/src/devices/cpu/cop400/cop420ds.h new file mode 100644 index 00000000000..a92ba84a54f --- /dev/null +++ b/src/devices/cpu/cop400/cop420ds.h @@ -0,0 +1,26 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/*************************************************************************** + + cop420ds.c + + National Semiconductor COP420 Emulator. + +***************************************************************************/ + +#ifndef MAME_CPU_COP420_COP420DS_H +#define MAME_CPU_COP420_COP420DS_H + +#pragma once + +class cop420_disassembler : public util::disasm_interface +{ +public: + cop420_disassembler() = default; + virtual ~cop420_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/cop400/cop424ds.cpp b/src/devices/cpu/cop400/cop424ds.cpp index fc8396f4903..e42c5dc3120 100644 --- a/src/devices/cpu/cop400/cop424ds.cpp +++ b/src/devices/cpu/cop400/cop424ds.cpp @@ -9,11 +9,17 @@ ***************************************************************************/ #include "emu.h" +#include "cop424ds.h" -CPU_DISASSEMBLE(cop424) +u32 cop424_disassembler::opcode_alignment() const { - uint8_t opcode = oprom[0]; - uint8_t next_opcode = oprom[1]; + return 1; +} + +offs_t cop424_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + uint8_t opcode = opcodes.r8(pc); + uint8_t next_opcode = opcodes.r8(pc+1); uint16_t address; uint32_t flags = 0; int bytes = 1; @@ -38,7 +44,7 @@ CPU_DISASSEMBLE(cop424) { address = (uint16_t)(0x80 | (opcode & 0x3F)); util::stream_format(stream, "JSRP %03X", address); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; } } } @@ -72,7 +78,7 @@ CPU_DISASSEMBLE(cop424) { address = ((opcode & 0x07) << 8) | next_opcode; util::stream_format(stream, "JSR %03X", address); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; bytes = 2; } else if (opcode >= 0x70 && opcode <= 0x7F) @@ -347,12 +353,12 @@ CPU_DISASSEMBLE(cop424) case 0x48: util::stream_format(stream, "RET"); - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; case 0x49: util::stream_format(stream, "RETSK"); - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; case 0x4A: @@ -397,5 +403,5 @@ CPU_DISASSEMBLE(cop424) } } - return bytes | flags | DASMFLAG_SUPPORTED; + return bytes | flags | SUPPORTED; } diff --git a/src/devices/cpu/cop400/cop424ds.h b/src/devices/cpu/cop400/cop424ds.h new file mode 100644 index 00000000000..e093568a913 --- /dev/null +++ b/src/devices/cpu/cop400/cop424ds.h @@ -0,0 +1,26 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/*************************************************************************** + + cop424ds.c + + National Semiconductor COP424 Emulator. + +***************************************************************************/ + +#ifndef MAME_CPU_COP424_COP424DS_H +#define MAME_CPU_COP424_COP424DS_H + +#pragma once + +class cop424_disassembler : public util::disasm_interface +{ +public: + cop424_disassembler() = default; + virtual ~cop424_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/cop400/cop444ds.cpp b/src/devices/cpu/cop400/cop444ds.cpp index cae2274546c..23e6cd23cec 100644 --- a/src/devices/cpu/cop400/cop444ds.cpp +++ b/src/devices/cpu/cop400/cop444ds.cpp @@ -9,11 +9,17 @@ ***************************************************************************/ #include "emu.h" +#include "cop444ds.h" -CPU_DISASSEMBLE(cop444) +u32 cop444_disassembler::opcode_alignment() const { - uint8_t opcode = oprom[0]; - uint8_t next_opcode = oprom[1]; + return 1; +} + +offs_t cop444_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + uint8_t opcode = opcodes.r8(pc); + uint8_t next_opcode = opcodes.r8(pc+1); uint16_t address; uint32_t flags = 0; int bytes = 1; @@ -38,7 +44,7 @@ CPU_DISASSEMBLE(cop444) { address = (uint16_t)(0x80 | (opcode & 0x3F)); util::stream_format(stream, "JSRP %03X", address); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; } } } @@ -72,7 +78,7 @@ CPU_DISASSEMBLE(cop444) { address = ((opcode & 0x07) << 8) | next_opcode; util::stream_format(stream, "JSR %03X", address); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; bytes = 2; } else if (opcode >= 0x70 && opcode <= 0x7F) @@ -330,12 +336,12 @@ CPU_DISASSEMBLE(cop444) case 0x48: util::stream_format(stream, "RET"); - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; case 0x49: util::stream_format(stream, "RETSK"); - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; case 0x4A: @@ -380,5 +386,5 @@ CPU_DISASSEMBLE(cop444) } } - return bytes | flags | DASMFLAG_SUPPORTED; + return bytes | flags | SUPPORTED; } diff --git a/src/devices/cpu/cop400/cop444ds.h b/src/devices/cpu/cop400/cop444ds.h new file mode 100644 index 00000000000..c268616f846 --- /dev/null +++ b/src/devices/cpu/cop400/cop444ds.h @@ -0,0 +1,26 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/*************************************************************************** + + cop444ds.c + + National Semiconductor COP444 Emulator. + +***************************************************************************/ + +#ifndef MAME_CPU_COP444_COP444DS_H +#define MAME_CPU_COP444_COP444DS_H + +#pragma once + +class cop444_disassembler : public util::disasm_interface +{ +public: + cop444_disassembler() = default; + virtual ~cop444_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/cosmac/cosdasm.cpp b/src/devices/cpu/cosmac/cosdasm.cpp index 72f039037b5..c818fd2c9a9 100644 --- a/src/devices/cpu/cosmac/cosdasm.cpp +++ b/src/devices/cpu/cosmac/cosdasm.cpp @@ -10,56 +10,62 @@ ***************************************************************************/ #include "emu.h" - -enum -{ - TYPE_1801, - TYPE_1802 -}; +#include "cosdasm.h" #define CDP1801_OPCODE(...) \ util::stream_format(stream, __VA_ARGS__) #define CDP1802_OPCODE(...) \ - if (variant < TYPE_1802) stream << "illegal"; else util::stream_format(stream, __VA_ARGS__) + if (m_variant < TYPE_1802) stream << "illegal"; else util::stream_format(stream, __VA_ARGS__) -static offs_t implied(const uint8_t opcode) +offs_t cosmac_disassembler::implied(const uint8_t opcode) { return opcode & 0x0f; } -static offs_t immediate(const uint8_t **opram) +offs_t cosmac_disassembler::immediate(offs_t &pc, const data_buffer ¶ms) { - return *(*opram)++; + return params.r8(pc++); } -static offs_t short_branch(offs_t pc, const uint8_t **opram) +offs_t cosmac_disassembler::short_branch(offs_t base_pc, offs_t &pc, const data_buffer ¶ms) { - return (pc & 0xff00) | immediate(opram); + return (base_pc & 0xff00) | immediate(pc, params); } -static offs_t long_branch(const uint8_t **opram) +offs_t cosmac_disassembler::long_branch(offs_t &pc, const data_buffer ¶ms) { - return (immediate(opram) << 8) | immediate(opram); + u16 res = params.r16(pc); + pc += 2; + return res; } -static offs_t short_skip(offs_t pc) +offs_t cosmac_disassembler::short_skip(offs_t pc) { return pc + 2; } -static offs_t long_skip(offs_t pc) +offs_t cosmac_disassembler::long_skip(offs_t pc) { return pc + 3; } -static uint32_t disassemble(device_t *device, std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t variant) + +u32 cosmac_disassembler::opcode_alignment() const +{ + return 1; +} + +cosmac_disassembler::cosmac_disassembler(int variant) : m_variant(variant) +{ +} + +offs_t cosmac_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - const uint8_t *startram = opram; + offs_t base_pc = pc; uint32_t flags = 0; - opram++; - uint8_t opcode = *oprom++; + uint8_t opcode = opcodes.r8(pc++); switch (opcode) { @@ -73,20 +79,20 @@ static uint32_t disassemble(device_t *device, std::ostream &stream, offs_t pc, c case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f: CDP1801_OPCODE("DEC R%01X", implied(opcode)); break; - case 0x30: CDP1801_OPCODE("BR %04X", short_branch(pc, &opram)); break; - case 0x32: CDP1801_OPCODE("BZ %04X", short_branch(pc, &opram)); break; - case 0x33: CDP1801_OPCODE("BDF %04X", short_branch(pc, &opram)); break; - case 0x34: CDP1801_OPCODE("B1 %04X", short_branch(pc, &opram)); break; - case 0x35: CDP1801_OPCODE("B2 %04X", short_branch(pc, &opram)); break; - case 0x36: CDP1801_OPCODE("B3 %04X", short_branch(pc, &opram)); break; - case 0x37: CDP1801_OPCODE("B4 %04X", short_branch(pc, &opram)); break; + case 0x30: CDP1801_OPCODE("BR %04X", short_branch(base_pc, pc, params)); break; + case 0x32: CDP1801_OPCODE("BZ %04X", short_branch(base_pc, pc, params)); break; + case 0x33: CDP1801_OPCODE("BDF %04X", short_branch(base_pc, pc, params)); break; + case 0x34: CDP1801_OPCODE("B1 %04X", short_branch(base_pc, pc, params)); break; + case 0x35: CDP1801_OPCODE("B2 %04X", short_branch(base_pc, pc, params)); break; + case 0x36: CDP1801_OPCODE("B3 %04X", short_branch(base_pc, pc, params)); break; + case 0x37: CDP1801_OPCODE("B4 %04X", short_branch(base_pc, pc, params)); break; case 0x38: CDP1801_OPCODE("SKP %04X", short_skip(pc)); break; - case 0x3a: CDP1801_OPCODE("BNZ %04X", short_branch(pc, &opram)); break; - case 0x3b: CDP1801_OPCODE("BNF %04X", short_branch(pc, &opram)); break; - case 0x3c: CDP1801_OPCODE("BN1 %04X", short_branch(pc, &opram)); break; - case 0x3d: CDP1801_OPCODE("BN2 %04X", short_branch(pc, &opram)); break; - case 0x3e: CDP1801_OPCODE("BN3 %04X", short_branch(pc, &opram)); break; - case 0x3f: CDP1801_OPCODE("BN4 %04X", short_branch(pc, &opram)); break; + case 0x3a: CDP1801_OPCODE("BNZ %04X", short_branch(base_pc, pc, params)); break; + case 0x3b: CDP1801_OPCODE("BNF %04X", short_branch(base_pc, pc, params)); break; + case 0x3c: CDP1801_OPCODE("BN1 %04X", short_branch(base_pc, pc, params)); break; + case 0x3d: CDP1801_OPCODE("BN2 %04X", short_branch(base_pc, pc, params)); break; + case 0x3e: CDP1801_OPCODE("BN3 %04X", short_branch(base_pc, pc, params)); break; + case 0x3f: CDP1801_OPCODE("BN4 %04X", short_branch(base_pc, pc, params)); break; case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f: CDP1801_OPCODE("LDA R%01X", implied(opcode)); break; @@ -107,8 +113,8 @@ static uint32_t disassemble(device_t *device, std::ostream &stream, offs_t pc, c case 0x6d: CDP1801_OPCODE("INP 5"); break; case 0x6e: CDP1801_OPCODE("INP 6"); break; case 0x6f: CDP1801_OPCODE("INP 7"); break; - case 0x70: CDP1801_OPCODE("RET"); flags = DASMFLAG_STEP_OUT; break; - case 0x71: CDP1801_OPCODE("DIS"); flags = DASMFLAG_STEP_OUT; break; + case 0x70: CDP1801_OPCODE("RET"); flags = STEP_OUT; break; + case 0x71: CDP1801_OPCODE("DIS"); flags = STEP_OUT; break; case 0x78: CDP1801_OPCODE("SAV"); break; case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87: case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f: @@ -124,7 +130,7 @@ static uint32_t disassemble(device_t *device, std::ostream &stream, offs_t pc, c CDP1801_OPCODE("PHI R%01X", implied(opcode)); break; case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: - CDP1801_OPCODE("SEP R%01X", implied(opcode)); flags = DASMFLAG_STEP_OVER; break; + CDP1801_OPCODE("SEP R%01X", implied(opcode)); flags = STEP_OVER; break; case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7: case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef: CDP1801_OPCODE("SEX R%01X", implied(opcode)); break; @@ -136,16 +142,16 @@ static uint32_t disassemble(device_t *device, std::ostream &stream, offs_t pc, c case 0xf5: CDP1801_OPCODE("SD"); break; case 0xf6: CDP1801_OPCODE("SHR"); break; case 0xf7: CDP1801_OPCODE("SM"); break; - case 0xf8: CDP1801_OPCODE("LDI #%02X", immediate(&opram)); break; - case 0xf9: CDP1801_OPCODE("ORI #%02X", immediate(&opram)); break; - case 0xfa: CDP1801_OPCODE("ANI #%02X", immediate(&opram)); break; - case 0xfb: CDP1801_OPCODE("XRI #%02X", immediate(&opram)); break; - case 0xfc: CDP1801_OPCODE("ADI #%02X", immediate(&opram)); break; - case 0xfd: CDP1801_OPCODE("SDI #%02X", immediate(&opram)); break; - case 0xff: CDP1801_OPCODE("SMI #%02X", immediate(&opram)); break; + case 0xf8: CDP1801_OPCODE("LDI #%02X", immediate(pc, params)); break; + case 0xf9: CDP1801_OPCODE("ORI #%02X", immediate(pc, params)); break; + case 0xfa: CDP1801_OPCODE("ANI #%02X", immediate(pc, params)); break; + case 0xfb: CDP1801_OPCODE("XRI #%02X", immediate(pc, params)); break; + case 0xfc: CDP1801_OPCODE("ADI #%02X", immediate(pc, params)); break; + case 0xfd: CDP1801_OPCODE("SDI #%02X", immediate(pc, params)); break; + case 0xff: CDP1801_OPCODE("SMI #%02X", immediate(pc, params)); break; // CDP1802 - case 0x31: CDP1802_OPCODE("BQ %04X", short_branch(pc, &opram)); break; - case 0x39: CDP1802_OPCODE("BNQ %04X", short_branch(pc, &opram)); break; + case 0x31: CDP1802_OPCODE("BQ %04X", short_branch(base_pc, pc, params)); break; + case 0x39: CDP1802_OPCODE("BNQ %04X", short_branch(base_pc, pc, params)); break; case 0x60: CDP1802_OPCODE("IRX"); break; case 0x72: CDP1802_OPCODE("LDXA"); break; case 0x73: CDP1802_OPCODE("STXD"); break; @@ -156,14 +162,14 @@ static uint32_t disassemble(device_t *device, std::ostream &stream, offs_t pc, c case 0x79: CDP1802_OPCODE("MARK"); break; case 0x7a: CDP1802_OPCODE("REQ"); break; case 0x7b: CDP1802_OPCODE("SEQ"); break; - case 0x7c: CDP1802_OPCODE("ADCI #%02X", immediate(&opram)); break; - case 0x7d: CDP1802_OPCODE("SDBI #%02X", immediate(&opram)); break; + case 0x7c: CDP1802_OPCODE("ADCI #%02X", immediate(pc, params)); break; + case 0x7d: CDP1802_OPCODE("SDBI #%02X", immediate(pc, params)); break; case 0x7e: CDP1802_OPCODE("SHLC"); break; - case 0x7f: CDP1802_OPCODE("SMBI #%02X", immediate(&opram)); break; - case 0xc0: CDP1802_OPCODE("LBR %04X", long_branch(&opram)); break; - case 0xc1: CDP1802_OPCODE("LBQ %04X", long_branch(&opram)); break; - case 0xc2: CDP1802_OPCODE("LBZ %04X", long_branch(&opram)); break; - case 0xc3: CDP1802_OPCODE("LBDF %04X", long_branch(&opram)); break; + case 0x7f: CDP1802_OPCODE("SMBI #%02X", immediate(pc, params)); break; + case 0xc0: CDP1802_OPCODE("LBR %04X", long_branch(pc, params)); break; + case 0xc1: CDP1802_OPCODE("LBQ %04X", long_branch(pc, params)); break; + case 0xc2: CDP1802_OPCODE("LBZ %04X", long_branch(pc, params)); break; + case 0xc3: CDP1802_OPCODE("LBDF %04X", long_branch(pc, params)); break; case 0xc4: CDP1802_OPCODE("NOP"); break; case 0xc5: CDP1802_OPCODE("LSNQ %04X", long_skip(pc)); break; case 0xc6: CDP1802_OPCODE("LSNZ %04X", long_skip(pc)); break; @@ -181,17 +187,5 @@ static uint32_t disassemble(device_t *device, std::ostream &stream, offs_t pc, c default: CDP1801_OPCODE("illegal"); break; } - return (opram - startram) | flags | DASMFLAG_SUPPORTED; -} - - -CPU_DISASSEMBLE( cdp1801 ) -{ - return disassemble(device, stream, pc, oprom, opram, TYPE_1801); -} - - -CPU_DISASSEMBLE( cdp1802 ) -{ - return disassemble(device, stream, pc, oprom, opram, TYPE_1802); + return (pc - base_pc) | flags | SUPPORTED; } diff --git a/src/devices/cpu/cosmac/cosdasm.h b/src/devices/cpu/cosmac/cosdasm.h new file mode 100644 index 00000000000..38011b792c6 --- /dev/null +++ b/src/devices/cpu/cosmac/cosdasm.h @@ -0,0 +1,43 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/*************************************************************************** + + cosdasm.c + + Simple RCA COSMAC disassembler. + Written by Curt Coder + +***************************************************************************/ + +#ifndef MAME_CPU_COSMAC_COSDASM_H +#define MAME_CPU_COSMAC_COSDASM_H + +#pragma once + +class cosmac_disassembler : public util::disasm_interface +{ +public: + enum + { + TYPE_1801, + TYPE_1802 + }; + + cosmac_disassembler(int variant); + virtual ~cosmac_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + int m_variant; + + offs_t implied(const uint8_t opcode); + offs_t immediate(offs_t &pc, const data_buffer ¶ms); + offs_t short_branch(offs_t base_pc, offs_t &pc, const data_buffer ¶ms); + offs_t long_branch(offs_t &pc, const data_buffer ¶ms); + offs_t short_skip(offs_t pc); + offs_t long_skip(offs_t pc); +}; + +#endif diff --git a/src/devices/cpu/cosmac/cosmac.cpp b/src/devices/cpu/cosmac/cosmac.cpp index feff0141494..60b28dee897 100644 --- a/src/devices/cpu/cosmac/cosmac.cpp +++ b/src/devices/cpu/cosmac/cosmac.cpp @@ -9,6 +9,7 @@ #include "emu.h" #include "debugger.h" #include "cosmac.h" +#include "cosdasm.h" #include "coreutil.h" // permit our enums to be saved @@ -324,8 +325,8 @@ cdp1802_device::cdp1802_device(const machine_config &mconfig, const char *tag, d void cosmac_device::device_start() { // resolve callbacks - m_read_wait.resolve_safe(0); - m_read_clear.resolve_safe(0); + m_read_wait.resolve(); + m_read_clear.resolve(); m_read_ef1.resolve(); m_read_ef2.resolve(); m_read_ef3.resolve(); @@ -337,7 +338,7 @@ void cosmac_device::device_start() // get our address spaces m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); // register our state for the debugger @@ -479,45 +480,21 @@ void cosmac_device::state_string_export(const device_state_entry &entry, std::st //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t cosmac_device::disasm_min_opcode_bytes() const -{ - return 1; -} - - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t cosmac_device::disasm_max_opcode_bytes() const -{ - return 3; -} - - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t cdp1801_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *cdp1801_device::create_disassembler() { - extern CPU_DISASSEMBLE( cdp1801 ); - return CPU_DISASSEMBLE_NAME( cdp1801 )(this, stream, pc, oprom, opram, options); + return new cosmac_disassembler(cosmac_disassembler::TYPE_1801); } -offs_t cdp1802_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) + +util::disasm_interface *cdp1802_device::create_disassembler() { - extern CPU_DISASSEMBLE( cdp1802 ); - return CPU_DISASSEMBLE_NAME( cdp1802 )(this, stream, pc, oprom, opram, options); + return new cosmac_disassembler(cosmac_disassembler::TYPE_1802); } - //************************************************************************** // INLINE HELPERS //************************************************************************** @@ -648,6 +625,14 @@ void cosmac_device::execute_set_input(int inputnum, int state) case COSMAC_INPUT_LINE_EF4: EF[inputnum - COSMAC_INPUT_LINE_EF1] = state; break; + + case COSMAC_INPUT_LINE_CLEAR: + m_clear = state; + break; + + case COSMAC_INPUT_LINE_WAIT: + m_wait = state; + break; } } @@ -792,11 +777,11 @@ inline void cosmac_device::debug() inline void cosmac_device::sample_wait_clear() { - int wait = m_read_wait(); - int clear = m_read_clear(); + if (!m_read_wait.isnull()) m_wait = m_read_wait(); + if (!m_read_clear.isnull()) m_clear = m_read_clear(); m_pmode = m_mode; - m_mode = (cosmac_mode) ((clear << 1) | wait); + m_mode = (cosmac_mode) ((m_clear << 1) | m_wait); } diff --git a/src/devices/cpu/cosmac/cosmac.h b/src/devices/cpu/cosmac/cosmac.h index 649a3ca6a2b..515dde74d45 100644 --- a/src/devices/cpu/cosmac/cosmac.h +++ b/src/devices/cpu/cosmac/cosmac.h @@ -126,7 +126,9 @@ // input lines enum { - COSMAC_INPUT_LINE_INT = 0, + COSMAC_INPUT_LINE_WAIT = 0, + COSMAC_INPUT_LINE_CLEAR, + COSMAC_INPUT_LINE_INT, COSMAC_INPUT_LINE_DMAIN, COSMAC_INPUT_LINE_DMAOUT, COSMAC_INPUT_LINE_EF1, @@ -205,6 +207,8 @@ public: // public interfaces offs_t get_memory_address(); + DECLARE_WRITE_LINE_MEMBER( wait_w ) { set_input_line(COSMAC_INPUT_LINE_WAIT, state); } + DECLARE_WRITE_LINE_MEMBER( clear_w ) { set_input_line(COSMAC_INPUT_LINE_CLEAR, state); } DECLARE_WRITE_LINE_MEMBER( int_w ) { set_input_line(COSMAC_INPUT_LINE_INT, state); } DECLARE_WRITE_LINE_MEMBER( dma_in_w ) { set_input_line(COSMAC_INPUT_LINE_DMAIN, state); } DECLARE_WRITE_LINE_MEMBER( dma_out_w ) { set_input_line(COSMAC_INPUT_LINE_DMAOUT, state); } @@ -236,10 +240,6 @@ protected: virtual void state_export(const device_state_entry &entry) override; virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; - // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - // helpers inline uint8_t read_opcode(offs_t pc); inline uint8_t read_byte(offs_t address); @@ -411,6 +411,8 @@ protected: cosmac_state m_state; // state cosmac_mode m_mode; // control mode cosmac_mode m_pmode; // previous control mode + bool m_wait; + bool m_clear; int m_irq; // interrupt request int m_dmain; // DMA input request int m_dmaout; // DMA output request @@ -435,7 +437,7 @@ protected: int m_icount; address_space * m_program; address_space * m_io; - direct_read_data * m_direct; + direct_read_data<0> *m_direct; // opcode/condition tables typedef void (cosmac_device::*ophandler)(); @@ -453,7 +455,7 @@ public: protected: // device_disasm_interface overrides - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual cosmac_device::ophandler get_ophandler(uint8_t opcode) override; @@ -471,7 +473,7 @@ public: protected: // device_disasm_interface overrides - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual cosmac_device::ophandler get_ophandler(uint8_t opcode) override; diff --git a/src/devices/cpu/cp1610/1610dasm.cpp b/src/devices/cpu/cp1610/1610dasm.cpp index 0e9ed461dd3..112bbda6523 100644 --- a/src/devices/cpu/cp1610/1610dasm.cpp +++ b/src/devices/cpu/cp1610/1610dasm.cpp @@ -1,12 +1,16 @@ // license:BSD-3-Clause // copyright-holders:Frank Palazzolo #include "emu.h" -#include "debugger.h" -#include "cp1610.h" +#include "1610dasm.h" -CPU_DISASSEMBLE(cp1610) +u32 cp1610_disassembler::opcode_alignment() const { - uint16_t oprom16[4]={ static_cast<uint16_t>((oprom[0] << 8) | oprom[1]), static_cast<uint16_t>((oprom[2] << 8) | oprom[3]), static_cast<uint16_t>((oprom[4] << 8) | oprom[5]), static_cast<uint16_t>((oprom[6] << 8) | oprom[7]) }; + return 1; +} + +offs_t cp1610_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + uint16_t oprom16[4]={ opcodes.r16(pc), opcodes.r16(pc+1), opcodes.r16(pc+2), opcodes.r16(pc+3) }; uint16_t op = oprom16[0]; uint16_t subop; uint16_t ea, ea1, ea2; unsigned size = 1; diff --git a/src/devices/cpu/cp1610/1610dasm.h b/src/devices/cpu/cp1610/1610dasm.h new file mode 100644 index 00000000000..59cc61b36f9 --- /dev/null +++ b/src/devices/cpu/cp1610/1610dasm.h @@ -0,0 +1,19 @@ +// license:BSD-3-Clause +// copyright-holders:Frank Palazzolo + +#ifndef MAME_CPU_CP1610_CP1610DASM_H +#define MAME_CPU_CP1610_CP1610DASM_H + +#pragma once + +class cp1610_disassembler : public util::disasm_interface +{ +public: + cp1610_disassembler() = default; + virtual ~cp1610_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/cp1610/cp1610.cpp b/src/devices/cpu/cp1610/cp1610.cpp index 5a113b4e954..aafbe86fbe9 100644 --- a/src/devices/cpu/cp1610/cp1610.cpp +++ b/src/devices/cpu/cp1610/cp1610.cpp @@ -16,7 +16,7 @@ #include "emu.h" #include "cp1610.h" #include "debugger.h" - +#include "1610dasm.h" DEFINE_DEVICE_TYPE(CP1610, cp1610_cpu_device, "cp1610", "GI CP1610") @@ -27,9 +27,9 @@ DEFINE_DEVICE_TYPE(CP1610, cp1610_cpu_device, "cp1610", "GI CP1610") #define C 0x10 -#define cp1610_readop(A) m_program->read_word((A)<<1) -#define cp1610_readmem16(A) m_program->read_word((A)<<1) -#define cp1610_writemem16(A,B) m_program->write_word((A)<<1,B) +#define cp1610_readop(A) m_program->read_word(A) +#define cp1610_readmem16(A) m_program->read_word(A) +#define cp1610_writemem16(A,B) m_program->write_word(A,B) /* clear all flags */ #define CLR_SZOC \ @@ -3422,9 +3422,7 @@ void cp1610_cpu_device::state_string_export(const device_state_entry &entry, std } } - -offs_t cp1610_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *cp1610_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( cp1610 ); - return CPU_DISASSEMBLE_NAME(cp1610)(this, stream, pc, oprom, opram, options); + return new cp1610_disassembler; } diff --git a/src/devices/cpu/cp1610/cp1610.h b/src/devices/cpu/cp1610/cp1610.h index c3a844189e3..54daa10b4bc 100644 --- a/src/devices/cpu/cp1610/cp1610.h +++ b/src/devices/cpu/cp1610/cp1610.h @@ -60,9 +60,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 8; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -211,7 +209,4 @@ private: DECLARE_DEVICE_TYPE(CP1610, cp1610_cpu_device) - -CPU_DISASSEMBLE( cp1610 ); - #endif // MAME_CPU_CP1610_CP1610_H diff --git a/src/devices/cpu/cubeqcpu/cubedasm.cpp b/src/devices/cpu/cubeqcpu/cubedasm.cpp index 20fd5a266d0..2bfb3ac0431 100644 --- a/src/devices/cpu/cubeqcpu/cubedasm.cpp +++ b/src/devices/cpu/cubeqcpu/cubedasm.cpp @@ -9,7 +9,7 @@ ***************************************************************************/ #include "emu.h" -#include "cubeqcpu.h" +#include "cubedasm.h" /*************************************************************************** @@ -17,7 +17,7 @@ ***************************************************************************/ /* Am2901 Instruction Fields */ -static const char *const ins[] = +const char *const cubeq_disassembler::ins[] = { "ADD ", "SUBR ", @@ -29,7 +29,7 @@ static const char *const ins[] = "EXNOR", }; -static const char *const src[] = +const char *const cubeq_disassembler::src[] = { "A,Q", "A,B", @@ -41,7 +41,7 @@ static const char *const src[] = "D,0", }; -static const char *const dst[] = +const char *const cubeq_disassembler::dst[] = { "QREG ", "NOP ", @@ -53,12 +53,16 @@ static const char *const dst[] = "RAMU ", }; +u32 cubeq_disassembler::opcode_alignment() const +{ + return 1; +} /*************************************************************************** SOUND DISASSEMBLY HOOK ***************************************************************************/ -CPU_DISASSEMBLE(cquestsnd) +offs_t cquestsnd_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { static const char *const jmps[] = { @@ -81,7 +85,7 @@ CPU_DISASSEMBLE(cquestsnd) " ", }; - uint64_t inst = big_endianize_int64(*(uint64_t *)oprom); + uint64_t inst = opcodes.r64(pc); uint32_t inslow = inst & 0xffffffff; uint32_t inshig = inst >> 32; @@ -121,7 +125,7 @@ CPU_DISASSEMBLE(cquestsnd) _ipwrt ? ' ' : 'W', inca ? 'I' : ' '); - return 1 | DASMFLAG_SUPPORTED; + return 1 | SUPPORTED; } @@ -129,7 +133,7 @@ CPU_DISASSEMBLE(cquestsnd) ROTATE DISASSEMBLY HOOK ***************************************************************************/ -CPU_DISASSEMBLE(cquestrot) +offs_t cquestrot_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { static const char *const jmps[] = { @@ -185,7 +189,7 @@ CPU_DISASSEMBLE(cquestrot) "??? " }; - uint64_t inst = big_endianize_int64(*(uint64_t *)oprom); + uint64_t inst = opcodes.r64(pc); uint32_t inslow = inst & 0xffffffff; uint32_t inshig = inst >> 32; @@ -217,7 +221,7 @@ CPU_DISASSEMBLE(cquestrot) spfs[spf], t); - return 1 | DASMFLAG_SUPPORTED; + return 1 | SUPPORTED; } @@ -225,7 +229,7 @@ CPU_DISASSEMBLE(cquestrot) LINE DRAWER DISASSEMBLY HOOK ***************************************************************************/ -CPU_DISASSEMBLE(cquestlin) +offs_t cquestlin_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { static const char *const jmps[] = { @@ -272,7 +276,7 @@ CPU_DISASSEMBLE(cquestlin) "BRES ", }; - uint64_t inst = big_endianize_int64(*(uint64_t *)oprom); + uint64_t inst = opcodes.r64(pc); uint32_t inslow = inst & 0xffffffff; uint32_t inshig = inst >> 32; @@ -303,5 +307,5 @@ CPU_DISASSEMBLE(cquestlin) _pbcs ? " " : "PB", spfs[spf]); - return 1 | DASMFLAG_SUPPORTED; + return 1 | SUPPORTED; } diff --git a/src/devices/cpu/cubeqcpu/cubedasm.h b/src/devices/cpu/cubeqcpu/cubedasm.h new file mode 100644 index 00000000000..e43018a1998 --- /dev/null +++ b/src/devices/cpu/cubeqcpu/cubedasm.h @@ -0,0 +1,54 @@ +// license:BSD-3-Clause +// copyright-holders:Philip Bennett +/*************************************************************************** + + cubedasm.c + + Implementation of the Cube Quest AM2901-based CPUs + +***************************************************************************/ + +#ifndef MAME_CPU_CUBEQCPU_CUBEDASM_H +#define MAME_CPU_CUBEQCPU_CUBEDASM_H + +#pragma once + +class cubeq_disassembler : public util::disasm_interface +{ +public: + cubeq_disassembler() = default; + virtual ~cubeq_disassembler() = default; + + virtual u32 opcode_alignment() const override; + +protected: + static const char *const ins[]; + static const char *const src[]; + static const char *const dst[]; +}; + +class cquestsnd_disassembler : public cubeq_disassembler +{ +public: + cquestsnd_disassembler() = default; + virtual ~cquestsnd_disassembler() = default; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +class cquestrot_disassembler : public cubeq_disassembler +{ +public: + cquestrot_disassembler() = default; + virtual ~cquestrot_disassembler() = default; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +class cquestlin_disassembler : public cubeq_disassembler +{ +public: + cquestlin_disassembler() = default; + virtual ~cquestlin_disassembler() = default; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/cubeqcpu/cubeqcpu.cpp b/src/devices/cpu/cubeqcpu/cubeqcpu.cpp index 9c3652fd40e..f00ed3eefa0 100644 --- a/src/devices/cpu/cubeqcpu/cubeqcpu.cpp +++ b/src/devices/cpu/cubeqcpu/cubeqcpu.cpp @@ -16,6 +16,7 @@ #include "emu.h" #include "debugger.h" #include "cubeqcpu.h" +#include "cubedasm.h" /*************************************************************************** @@ -91,10 +92,9 @@ device_memory_interface::space_config_vector cquestsnd_cpu_device::memory_space_ } -offs_t cquestsnd_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *cquestsnd_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( cquestsnd ); - return CPU_DISASSEMBLE_NAME(cquestsnd)(this, stream, pc, oprom, opram, options); + return new cquestsnd_disassembler; } @@ -112,10 +112,9 @@ READ16_MEMBER( cquestrot_cpu_device::linedata_r ) } -offs_t cquestrot_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *cquestrot_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( cquestrot ); - return CPU_DISASSEMBLE_NAME(cquestrot)(this, stream, pc, oprom, opram, options); + return new cquestsnd_disassembler; } @@ -135,10 +134,9 @@ device_memory_interface::space_config_vector cquestlin_cpu_device::memory_space_ }; } -offs_t cquestlin_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *cquestlin_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( cquestlin ); - return CPU_DISASSEMBLE_NAME(cquestlin)(this, stream, pc, oprom, opram, options); + return new cquestlin_disassembler; } @@ -185,7 +183,7 @@ void cquestsnd_cpu_device::device_start() m_sound_data = (uint16_t*)machine().root_device().memregion(m_sound_region_tag)->base(); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<-3>(); memset(m_ram, 0, sizeof(m_ram)); m_q = 0; @@ -264,7 +262,7 @@ void cquestrot_cpu_device::device_start() m_linedata_w.resolve_safe(); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<-3>(); memset(m_ram, 0, sizeof(m_ram)); m_q = 0; @@ -395,7 +393,7 @@ void cquestlin_cpu_device::device_start() m_linedata_r.resolve_safe(0); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<-3>(); memset(m_ram, 0, sizeof(m_ram)); m_q = 0; @@ -544,7 +542,7 @@ void cquestsnd_cpu_device::execute_run() do { /* Decode the instruction */ - uint64_t inst = m_direct->read_qword(SND_PC << 3); + uint64_t inst = m_direct->read_qword(SND_PC); uint32_t inslow = inst & 0xffffffff; uint32_t inshig = inst >> 32; @@ -800,7 +798,7 @@ void cquestrot_cpu_device::execute_run() do { /* Decode the instruction */ - uint64_t inst = m_direct->read_qword(ROT_PC << 3); + uint64_t inst = m_direct->read_qword(ROT_PC); uint32_t inslow = inst & 0xffffffff; uint32_t inshig = inst >> 32; @@ -1220,7 +1218,7 @@ void cquestlin_cpu_device::execute_run() int prog = (m_clkcnt & 3) ? BACKGROUND : FOREGROUND; m_curpc = LINE_PC; - uint64_t inst = m_direct->read_qword(LINE_PC << 3); + uint64_t inst = m_direct->read_qword(LINE_PC); uint32_t inslow = inst & 0xffffffff; uint32_t inshig = inst >> 32; diff --git a/src/devices/cpu/cubeqcpu/cubeqcpu.h b/src/devices/cpu/cubeqcpu/cubeqcpu.h index de80a2830d5..46b3235c6be 100644 --- a/src/devices/cpu/cubeqcpu/cubeqcpu.h +++ b/src/devices/cpu/cubeqcpu/cubeqcpu.h @@ -87,9 +87,7 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 8; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 8; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -120,7 +118,7 @@ private: uint16_t *m_sound_data; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<-3> *m_direct; int m_icount; int do_sndjmp(int jmp); @@ -190,9 +188,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 8; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 8; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -231,7 +227,7 @@ private: uint8_t m_clkcnt; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<-3> *m_direct; int m_icount; // For the debugger @@ -304,9 +300,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 8; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 8; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -350,7 +344,7 @@ private: uint32_t m_o_stack[32768]; /* Stack DRAM: 32kx20 */ address_space *m_program; - direct_read_data *m_direct; + direct_read_data<-3> *m_direct; int m_icount; // For the debugger diff --git a/src/devices/cpu/drcbex64.cpp b/src/devices/cpu/drcbex64.cpp index 1950799624f..1f85f470cd3 100644 --- a/src/devices/cpu/drcbex64.cpp +++ b/src/devices/cpu/drcbex64.cpp @@ -635,10 +635,10 @@ drcbe_x64::drcbe_x64(drcuml_state &drcuml, device_t &device, drc_cache &cache, u // build up necessary arrays static const uint32_t sse_control[4] = { - 0xffc0, // ROUND_TRUNC - 0x9fc0, // ROUND_ROUND - 0xdfc0, // ROUND_CEIL - 0xbfc0 // ROUND_FLOOR + 0xff80, // ROUND_TRUNC + 0x9f80, // ROUND_ROUND + 0xdf80, // ROUND_CEIL + 0xbf80 // ROUND_FLOOR }; memcpy(m_near.ssecontrol, sse_control, sizeof(m_near.ssecontrol)); m_near.single1 = 1.0f; diff --git a/src/devices/cpu/dsp16/dsp16.cpp b/src/devices/cpu/dsp16/dsp16.cpp index 4426502cdf7..33c25a32dc6 100644 --- a/src/devices/cpu/dsp16/dsp16.cpp +++ b/src/devices/cpu/dsp16/dsp16.cpp @@ -11,6 +11,7 @@ #include "emu.h" #include "debugger.h" #include "dsp16.h" +#include "dsp16dis.h" // // TODO: @@ -161,7 +162,7 @@ void dsp16_device::device_start() // get our address spaces m_program = &space(AS_PROGRAM); m_data = &space(AS_DATA); - m_direct = &m_program->direct(); + m_direct = m_program->direct<-1>(); // set our instruction counter m_icountptr = &m_icount; @@ -321,60 +322,35 @@ void dsp16_device::state_string_export(const device_state_entry &entry, std::str } } - -//------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t dsp16_device::disasm_min_opcode_bytes() const -{ - return 2; -} - - //------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t dsp16_device::disasm_max_opcode_bytes() const -{ - return 4; -} - - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t dsp16_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *dsp16_device::create_disassembler() { - extern CPU_DISASSEMBLE( dsp16a ); - return CPU_DISASSEMBLE_NAME(dsp16a)(this, stream, pc, oprom, opram, options); + return new dsp16a_disassembler; } - /*************************************************************************** MEMORY ACCESSORS ***************************************************************************/ inline uint32_t dsp16_device::data_read(const uint16_t& addr) { - return m_data->read_word(addr << 1); + return m_data->read_word(addr); } inline void dsp16_device::data_write(const uint16_t& addr, const uint16_t& data) { - m_data->write_word(addr << 1, data & 0xffff); + m_data->write_word(addr, data & 0xffff); } inline uint32_t dsp16_device::opcode_read(const uint8_t pcOffset) { const uint16_t readPC = m_pc + pcOffset; - return m_direct->read_dword(readPC << 1); + return m_direct->read_dword(readPC); } diff --git a/src/devices/cpu/dsp16/dsp16.h b/src/devices/cpu/dsp16/dsp16.h index fd41dd03ef1..2dcf6892833 100644 --- a/src/devices/cpu/dsp16/dsp16.h +++ b/src/devices/cpu/dsp16/dsp16.h @@ -83,9 +83,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // address spaces const address_space_config m_program_config; @@ -148,7 +146,7 @@ protected: // address spaces address_space* m_program; address_space* m_data; - direct_read_data* m_direct; + direct_read_data<-1> *m_direct; // other internal states int m_icount; diff --git a/src/devices/cpu/dsp16/dsp16dis.cpp b/src/devices/cpu/dsp16/dsp16dis.cpp index eb371719cb6..40e122741e3 100644 --- a/src/devices/cpu/dsp16/dsp16dis.cpp +++ b/src/devices/cpu/dsp16/dsp16dis.cpp @@ -1,9 +1,9 @@ // license:BSD-3-Clause // copyright-holders:Andrew Gardner #include "emu.h" -#include "dsp16.h" +#include "dsp16dis.h" -std::string disasmF1Field(const uint8_t& F1, const uint8_t& D, const uint8_t& S) +std::string dsp16a_disassembler::disasmF1Field(const uint8_t& F1, const uint8_t& D, const uint8_t& S) { switch (F1) { @@ -28,7 +28,7 @@ std::string disasmF1Field(const uint8_t& F1, const uint8_t& D, const uint8_t& S) } } -std::string disasmYField(const uint8_t& Y) +std::string dsp16a_disassembler::disasmYField(const uint8_t& Y) { switch (Y) { @@ -58,7 +58,7 @@ std::string disasmYField(const uint8_t& Y) //return ""; } -std::string disasmZField(const uint8_t& Z) +std::string dsp16a_disassembler::disasmZField(const uint8_t& Z) { switch (Z) { @@ -88,7 +88,7 @@ std::string disasmZField(const uint8_t& Z) //return ""; } -std::string disasmF2Field(const uint8_t& F2, const uint8_t& D, const uint8_t& S) +std::string dsp16a_disassembler::disasmF2Field(const uint8_t& F2, const uint8_t& D, const uint8_t& S) { std::string ret = ""; switch (F2) @@ -116,7 +116,7 @@ std::string disasmF2Field(const uint8_t& F2, const uint8_t& D, const uint8_t& S) return ret; } -std::string disasmCONField(const uint8_t& CON) +std::string dsp16a_disassembler::disasmCONField(const uint8_t& CON) { switch (CON) { @@ -145,7 +145,7 @@ std::string disasmCONField(const uint8_t& CON) //return ""; } -std::string disasmBField(const uint8_t& B) +std::string dsp16a_disassembler::disasmBField(const uint8_t& B) { switch (B) { @@ -164,7 +164,7 @@ std::string disasmBField(const uint8_t& B) //return ""; } -std::string disasmRImmediateField(const uint8_t& R) +std::string dsp16a_disassembler::disasmRImmediateField(const uint8_t& R) { switch (R) { @@ -183,7 +183,7 @@ std::string disasmRImmediateField(const uint8_t& R) //return ""; } -std::string disasmRField(const uint8_t& R) +std::string dsp16a_disassembler::disasmRField(const uint8_t& R) { switch (R) { @@ -222,7 +222,7 @@ std::string disasmRField(const uint8_t& R) //return ""; } -std::string disasmIField(const uint8_t& I) +std::string dsp16a_disassembler::disasmIField(const uint8_t& I) { switch (I) { @@ -237,7 +237,7 @@ std::string disasmIField(const uint8_t& I) //return ""; } -bool disasmSIField(const uint8_t& SI) +bool dsp16a_disassembler::disasmSIField(const uint8_t& SI) { switch (SI) { @@ -248,12 +248,17 @@ bool disasmSIField(const uint8_t& SI) } -CPU_DISASSEMBLE(dsp16a) +u32 dsp16a_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t dsp16a_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint8_t opSize = 1; uint32_t dasmflags = 0; - uint16_t op = oprom[0] | (oprom[1] << 8); - uint16_t op2 = oprom[2] | (oprom[3] << 8); + uint16_t op = opcodes.r16(pc); + uint16_t op2 = opcodes.r16(pc+1); // TODO: Test for previous "if CON" instruction and tab the next instruction in? @@ -582,5 +587,5 @@ CPU_DISASSEMBLE(dsp16a) } } - return opSize | dasmflags | DASMFLAG_SUPPORTED; + return opSize | dasmflags | SUPPORTED; } diff --git a/src/devices/cpu/dsp16/dsp16dis.h b/src/devices/cpu/dsp16/dsp16dis.h new file mode 100644 index 00000000000..9d5361e75ae --- /dev/null +++ b/src/devices/cpu/dsp16/dsp16dis.h @@ -0,0 +1,32 @@ +// license:BSD-3-Clause +// copyright-holders:Andrew Gardner + +#ifndef MAME_CPU_DSP16_DSP16DIS_H +#define MAME_CPU_DSP16_DSP16DIS_H + +#pragma once + +class dsp16a_disassembler : public util::disasm_interface +{ +public: + dsp16a_disassembler() = default; + virtual ~dsp16a_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + std::string disasmF1Field(const uint8_t& F1, const uint8_t& D, const uint8_t& S); + std::string disasmYField(const uint8_t& Y); + std::string disasmZField(const uint8_t& Z); + std::string disasmF2Field(const uint8_t& F2, const uint8_t& D, const uint8_t& S); + std::string disasmCONField(const uint8_t& CON); + std::string disasmBField(const uint8_t& B); + std::string disasmRImmediateField(const uint8_t& R); + std::string disasmRField(const uint8_t& R); + std::string disasmIField(const uint8_t& I); + bool disasmSIField(const uint8_t& SI); + +}; + +#endif diff --git a/src/devices/cpu/dsp32/dsp32.cpp b/src/devices/cpu/dsp32/dsp32.cpp index e91a0fddf29..e700edd0075 100644 --- a/src/devices/cpu/dsp32/dsp32.cpp +++ b/src/devices/cpu/dsp32/dsp32.cpp @@ -30,6 +30,7 @@ #include "emu.h" #include "dsp32.h" +#include "dsp32dis.h" #include "debugger.h" @@ -191,7 +192,7 @@ void dsp32c_device::device_start() // get our address spaces m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); // register our state for the debugger state_add(STATE_GENPC, "GENPC", m_r[15]).noshow(); @@ -397,41 +398,17 @@ void dsp32c_device::state_string_export(const device_state_entry &entry, std::st //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t dsp32c_device::disasm_min_opcode_bytes() const -{ - return 4; -} - - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t dsp32c_device::disasm_max_opcode_bytes() const -{ - return 4; -} - - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t dsp32c_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *dsp32c_device::create_disassembler() { - extern CPU_DISASSEMBLE( dsp32c ); - return CPU_DISASSEMBLE_NAME(dsp32c)(this, stream, pc, oprom, opram, options); + return new dsp32c_disassembler; } - //************************************************************************** // MEMORY ACCESSORS //************************************************************************** diff --git a/src/devices/cpu/dsp32/dsp32.h b/src/devices/cpu/dsp32/dsp32.h index b11f5ad1d89..8f8ad369736 100644 --- a/src/devices/cpu/dsp32/dsp32.h +++ b/src/devices/cpu/dsp32/dsp32.h @@ -126,9 +126,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // memory accessors uint32_t ROPCODE(offs_t pc); @@ -423,7 +421,7 @@ protected: uint8_t m_lastpins; uint32_t m_ppc; address_space * m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; devcb_write32 m_output_pins_changed; // tables diff --git a/src/devices/cpu/dsp32/dsp32dis.cpp b/src/devices/cpu/dsp32/dsp32dis.cpp index 88399882df9..8748b2b55ab 100644 --- a/src/devices/cpu/dsp32/dsp32dis.cpp +++ b/src/devices/cpu/dsp32/dsp32dis.cpp @@ -9,7 +9,7 @@ ***************************************************************************/ #include "emu.h" -#include "dsp32.h" +#include "dsp32dis.h" /*************************************************************************** @@ -23,17 +23,17 @@ CODE CODE ***************************************************************************/ -static const char *const sizesuffix[] = { "", "e" }; -static const char *const unarysign[] = { "", "-" }; -static const char *const sign[] = { "+", "-" }; -static const char *const aMvals[] = { "a0", "a1", "a2", "a3", "0.0", "1.0", "Format 4", "Reserved" }; -static const char *const memsuffix[] = { "h", "l", "", "e" }; -static const char *const functable[] = +const char *const dsp32c_disassembler::sizesuffix[] = { "", "e" }; +const char *const dsp32c_disassembler::unarysign[] = { "", "-" }; +const char *const dsp32c_disassembler::sign[] = { "+", "-" }; +const char *const dsp32c_disassembler::aMvals[] = { "a0", "a1", "a2", "a3", "0.0", "1.0", "Format 4", "Reserved" }; +const char *const dsp32c_disassembler::memsuffix[] = { "h", "l", "", "e" }; +const char *const dsp32c_disassembler::functable[] = { "ic", "oc", "float", "int", "round", "ifalt", "ifaeq", "ifagt", "reserved8", "reserved9", "float24", "int24", "ieee", "dsp", "seed", "reservedf" }; -static const char *const condtable[] = +const char *const dsp32c_disassembler::condtable[] = { "false", "true", "pl", "mi", @@ -68,14 +68,14 @@ static const char *const condtable[] = "!?1e", "?1e", "!?1f", "?1f" }; -static const char *const regname[] = +const char *const dsp32c_disassembler::regname[] = { "0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc", "0", "r15", "r16", "r17", "r18", "r19", "-1", "1", "r20", "r21", "dauc", "ioc", "res1c", "r22", "pcsh", "res1f" }; -static const char *const regnamee[] = +const char *const dsp32c_disassembler::regnamee[] = { "0", "r1e", "r2e", "r3e", "r4e", "r5e", "r6e", "r7e", "r8e", "r9e", "r10e", "r11e", "r12e", "r13e", "r14e", "pce", @@ -83,48 +83,39 @@ static const char *const regnamee[] = "r20e", "r21e", "dauce", "ioce", "res1ce", "r22e", "pcshe", "res1fe" }; -static inline char *signed_16bit_unary(int16_t val) +std::string dsp32c_disassembler::signed_16bit_unary(int16_t val) { - static char temp[10]; if (val < 0) - sprintf(temp, "-$%x", -val); + return util::string_format("-$%x", -val); else - sprintf(temp, "$%x", val); - return temp; + return util::string_format("$%x", val); } -static inline char *signed_16bit_sep(int16_t val) +std::string dsp32c_disassembler::signed_16bit_sep(int16_t val) { - static char temp[10]; if (val < 0) - sprintf(temp, " - $%x", -val); + return util::string_format(" - $%x", -val); else - sprintf(temp, " + $%x", val); - return temp; + return util::string_format(" + $%x", val); } -static inline char *signed_16bit_sep_nospace(int16_t val) +std::string dsp32c_disassembler::signed_16bit_sep_nospace(int16_t val) { - static char temp[10]; if (val < 0) - sprintf(temp, "-$%x", -val); + return util::string_format("-$%x", -val); else - sprintf(temp, "+$%x", val); - return temp; + return util::string_format("+$%x", val); } -static inline char *unsigned_16bit_size(int16_t val, uint8_t size) +std::string dsp32c_disassembler::unsigned_16bit_size(int16_t val, uint8_t size) { - static char temp[10]; if (size) - sprintf(temp, "$%06x", (int32_t)val & 0xffffff); + return util::string_format("$%06x", (int32_t)val & 0xffffff); else - sprintf(temp, "$%04x", val & 0xffff); - return temp; + return util::string_format("$%04x", val & 0xffff); } -static uint8_t lastp; -static std::string dasm_XYZ(uint8_t bits) +std::string dsp32c_disassembler::dasm_XYZ(uint8_t bits) { std::string buffer; uint8_t p = bits >> 3; @@ -164,7 +155,7 @@ static std::string dasm_XYZ(uint8_t bits) } -static std::string dasm_PI(uint16_t bits) +std::string dsp32c_disassembler::dasm_PI(uint16_t bits) { std::string buffer; uint8_t p = bits >> 5; @@ -199,10 +190,11 @@ static std::string dasm_PI(uint16_t bits) } -static unsigned dasm_dsp32(std::ostream &stream, unsigned pc, uint32_t op) +offs_t dsp32c_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint32_t flags = 0; + uint32_t op = opcodes.r32(pc); switch (op >> 25) { /* DA format 1 */ @@ -344,7 +336,7 @@ static unsigned dasm_dsp32(std::ostream &stream, unsigned pc, uint32_t op) else { if (((op >> 16) & 0x1f) == 20) - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; util::stream_format(stream, "goto %s", rH); } } @@ -359,7 +351,7 @@ static unsigned dasm_dsp32(std::ostream &stream, unsigned pc, uint32_t op) else { if (((op >> 16) & 0x1f) == 20) - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; util::stream_format(stream, "if (%s) goto %s", condtable[C], rH); } } @@ -377,7 +369,7 @@ static unsigned dasm_dsp32(std::ostream &stream, unsigned pc, uint32_t op) { util::stream_format(stream, "if (%s-- >= 0) goto %s%s [%x]", rM, rH, signed_16bit_sep_nospace(N), (pc + 8 + N) & 0xffffff); if (((pc + 8 + N) & 0xffffff) < pc) - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; } else if (N && rH[0] != '0') util::stream_format(stream, "if (%s-- >= 0) goto %s%s", rM, rH, signed_16bit_sep_nospace(N)); @@ -385,13 +377,13 @@ static unsigned dasm_dsp32(std::ostream &stream, unsigned pc, uint32_t op) { util::stream_format(stream, "if (%s-- >= 0) goto $%x", rM, ((int32_t)N & 0xffffff)); if (((int32_t)N & 0xffffff) < pc) - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; } else { util::stream_format(stream, "if (%s-- >= 0) goto %s", rM, rH); if (((op >> 16) & 0x1f) == 20) - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; } break; } @@ -419,7 +411,7 @@ static unsigned dasm_dsp32(std::ostream &stream, unsigned pc, uint32_t op) util::stream_format(stream, "call $%x (%s)", ((int32_t)N & 0xffffff), rM); else util::stream_format(stream, "call %s (%s)", rH, rM); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; } @@ -659,7 +651,7 @@ static unsigned dasm_dsp32(std::ostream &stream, unsigned pc, uint32_t op) else { if (((op >> 16) & 0x1f) == 20) - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; util::stream_format(stream, "goto %s", rH); } break; @@ -685,20 +677,15 @@ static unsigned dasm_dsp32(std::ostream &stream, unsigned pc, uint32_t op) int32_t N = (op & 0xffff) | ((int32_t)((op & 0x1fe00000) << 3) >> 8); const char *rM = regname[(op >> 16) & 0x1f]; util::stream_format(stream, "call $%x (%s)", N & 0xffffff, rM); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; } } - return 4 | flags | DASMFLAG_SUPPORTED; + return 4 | flags | SUPPORTED; } - -/*************************************************************************** - DISASSEMBLY HOOK -***************************************************************************/ - -CPU_DISASSEMBLE( dsp32c ) +uint32_t dsp32c_disassembler::opcode_alignment() const { - return dasm_dsp32(stream, pc, oprom[0] | (oprom[1] << 8) | (oprom[2] << 16) | (oprom[3] << 24)); + return 4; } diff --git a/src/devices/cpu/dsp32/dsp32dis.h b/src/devices/cpu/dsp32/dsp32dis.h new file mode 100644 index 00000000000..96a36de954c --- /dev/null +++ b/src/devices/cpu/dsp32/dsp32dis.h @@ -0,0 +1,45 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +/*************************************************************************** + + dsp32dis.c + Disassembler for the portable AT&T/Lucent DSP32C emulator. + Written by Aaron Giles + +***************************************************************************/ + +#ifndef MAME_CPU_DSP32_DSP32DIS_H +#define MAME_CPU_DSP32_DSP32DIS_H + +#pragma once + +class dsp32c_disassembler : public util::disasm_interface +{ +public: + dsp32c_disassembler() = default; + virtual ~dsp32c_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *const sizesuffix[]; + static const char *const unarysign[]; + static const char *const sign[]; + static const char *const aMvals[]; + static const char *const memsuffix[]; + static const char *const functable[]; + static const char *const condtable[]; + static const char *const regname[]; + static const char *const regnamee[]; + std::string signed_16bit_unary(int16_t val); + std::string signed_16bit_sep(int16_t val); + std::string signed_16bit_sep_nospace(int16_t val); + std::string unsigned_16bit_size(int16_t val, uint8_t size); + std::string dasm_XYZ(uint8_t bits); + std::string dasm_PI(uint16_t bits); + + uint8_t lastp; +}; + +#endif diff --git a/src/devices/cpu/dsp56k/dsp56dsm.cpp b/src/devices/cpu/dsp56k/dsp56dsm.cpp index 5ca4aab30a0..847a4bda6a0 100644 --- a/src/devices/cpu/dsp56k/dsp56dsm.cpp +++ b/src/devices/cpu/dsp56k/dsp56dsm.cpp @@ -10,22 +10,25 @@ #include "emu.h" #include "opcode.h" +#include "dsp56dsm.h" -#include "emu.h" -#include "dsp56k.h" +u32 dsp56k_disassembler::opcode_alignment() const +{ + return 1; +} /*****************************/ /* Main disassembly function */ /*****************************/ -CPU_DISASSEMBLE(dsp56k) +offs_t dsp56k_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - const uint16_t w0 = oprom[0] | (oprom[1] << 8); - const uint16_t w1 = oprom[2] | (oprom[3] << 8); + const uint16_t w0 = opcodes.r16(pc); + const uint16_t w1 = opcodes.r16(pc+1); // Decode and disassemble. DSP56K::Opcode op(w0, w1); stream << op.disassemble(); const unsigned size = op.size(); - return (size | DASMFLAG_SUPPORTED); + return (size | SUPPORTED); } diff --git a/src/devices/cpu/dsp56k/dsp56dsm.h b/src/devices/cpu/dsp56k/dsp56dsm.h new file mode 100644 index 00000000000..3e0f7cb87ff --- /dev/null +++ b/src/devices/cpu/dsp56k/dsp56dsm.h @@ -0,0 +1,26 @@ +// license:BSD-3-Clause +// copyright-holders:Andrew Gardner +/*************************************************************************** + + dsp56dsm.c + Disassembler for the portable Motorola/Freescale dsp56k emulator. + Written by Andrew Gardner + +***************************************************************************/ + +#ifndef MAME_CPU_DSP56K_DSP56DSM_H +#define MAME_CPU_DSP56K_DSP56DSM_H + +#pragma once + +class dsp56k_disassembler : public util::disasm_interface +{ +public: + dsp56k_disassembler() = default; + virtual ~dsp56k_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/dsp56k/dsp56k.cpp b/src/devices/cpu/dsp56k/dsp56k.cpp index c84948701ef..132ccb55c98 100644 --- a/src/devices/cpu/dsp56k/dsp56k.cpp +++ b/src/devices/cpu/dsp56k/dsp56k.cpp @@ -33,6 +33,7 @@ #include "emu.h" #include "dsp56k.h" +#include "dsp56dsm.h" #include "opcode.h" @@ -289,7 +290,7 @@ void dsp56k_device::device_start() save_item(NAME(m_dsp56k_core.peripheral_ram)); m_dsp56k_core.program = &space(AS_PROGRAM); - m_dsp56k_core.direct = &m_dsp56k_core.program->direct(); + m_dsp56k_core.direct = m_dsp56k_core.program->direct<-1>(); m_dsp56k_core.data = &space(AS_DATA); state_add(DSP56K_PC, "PC", m_dsp56k_core.PCU.pc).formatstr("%04X"); @@ -463,9 +464,9 @@ static size_t execute_one_new(dsp56k_core* cpustate) cpustate->ppc = PC; debugger_instruction_hook(cpustate->device, PC); - cpustate->op = ROPCODE(ADDRESS(PC)); - uint16_t w0 = ROPCODE(ADDRESS(PC)); - uint16_t w1 = ROPCODE(ADDRESS(PC) + ADDRESS(1)); + cpustate->op = ROPCODE(PC); + uint16_t w0 = ROPCODE(PC); + uint16_t w1 = ROPCODE(PC + 1); Opcode op(w0, w1); op.evaluate(cpustate); @@ -503,9 +504,9 @@ void dsp56k_device::execute_run() } -offs_t dsp56k_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *dsp56k_device::create_disassembler() { - return CPU_DISASSEMBLE_NAME(dsp56k)(this, stream, pc, oprom, opram, options); + return new dsp56k_disassembler; } } // namespace DSP56K diff --git a/src/devices/cpu/dsp56k/dsp56k.h b/src/devices/cpu/dsp56k/dsp56k.h index 4ab93b9b9ca..43e94e60442 100644 --- a/src/devices/cpu/dsp56k/dsp56k.h +++ b/src/devices/cpu/dsp56k/dsp56k.h @@ -192,7 +192,7 @@ struct dsp56k_core void (*output_pins_changed)(uint32_t pins); cpu_device *device; address_space *program; - direct_read_data *direct; + direct_read_data<-1> *direct; address_space *data; uint16_t peripheral_ram[0x40]; @@ -235,9 +235,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 4; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -256,6 +254,4 @@ private: DECLARE_DEVICE_TYPE_NS(DSP56156, DSP56K, dsp56k_device) using DSP56K::dsp56k_device; -extern CPU_DISASSEMBLE( dsp56k ); - #endif // MAME_CPU_DSP56K_DSP56K_H diff --git a/src/devices/cpu/dsp56k/dsp56ops.hxx b/src/devices/cpu/dsp56k/dsp56ops.hxx index 0c898e7c674..a7815da5a4d 100644 --- a/src/devices/cpu/dsp56k/dsp56ops.hxx +++ b/src/devices/cpu/dsp56k/dsp56ops.hxx @@ -42,7 +42,6 @@ struct typed_pointer char data_type; }; -//#define ADDRESS(X) (X<<1) #define BITS(CUR,MASK) (Dsp56kOpMask(CUR,MASK)) /*********************/ @@ -243,10 +242,10 @@ static void execute_one(dsp56k_core* cpustate) cpustate->ppc = PC; debugger_instruction_hook(cpustate->device, PC); - cpustate->op = ROPCODE(ADDRESS(PC)); + cpustate->op = ROPCODE(PC); /* The words we're going to be working with */ - op = ROPCODE(ADDRESS(PC)); - op2 = ROPCODE(ADDRESS(PC) + ADDRESS(1)); + op = ROPCODE(PC); + op2 = ROPCODE(PC + 1); /* DECODE */ @@ -2308,7 +2307,7 @@ static size_t dsp56k_op_bfop(dsp56k_core* cpustate, const uint16_t op, const uin decode_BBB_bitmask(cpustate, BITS(op2,0xe000), &iVal); workAddr = assemble_address_from_Pppppp_table(cpustate, BITS(op,0x0020), BITS(op,0x001f)); - previousValue = cpustate->data->read_word(ADDRESS(workAddr)); + previousValue = cpustate->data->read_word(workAddr); workingWord = previousValue; switch(BITS(op2, 0x1f00)) @@ -2332,7 +2331,7 @@ static size_t dsp56k_op_bfop(dsp56k_core* cpustate, const uint16_t op, const uin tempTP.addr = &workingWord; tempTP.data_type = DT_WORD; - SetDataMemoryValue(cpustate, tempTP, ADDRESS(workAddr)); + SetDataMemoryValue(cpustate, tempTP, workAddr); /* S L E U N Z V C */ /* - * - - - - - ? */ @@ -2374,7 +2373,7 @@ static size_t dsp56k_op_bfop_1(dsp56k_core* cpustate, const uint16_t op, const u decode_RR_table(cpustate, BITS(op,0x0003), &R); workAddr = *((uint16_t*)R.addr); - previousValue = cpustate->data->read_word(ADDRESS(workAddr)); + previousValue = cpustate->data->read_word(workAddr); workingWord = previousValue; switch(BITS(op2, 0x1f00)) @@ -2398,7 +2397,7 @@ static size_t dsp56k_op_bfop_1(dsp56k_core* cpustate, const uint16_t op, const u tempTP.addr = &workingWord; tempTP.data_type = DT_WORD; - SetDataMemoryValue(cpustate, tempTP, ADDRESS(workAddr)); + SetDataMemoryValue(cpustate, tempTP, workAddr); /* S L E U N Z V C */ /* - * - - - - - ? */ @@ -3112,7 +3111,7 @@ static size_t dsp56k_op_jsr(dsp56k_core* cpustate, const uint16_t op, const uint PC += 2; /* TODO: This is a hacky implementation of Long vs Fast Interrupts. Do it right someday! */ - if (PC < ADDRESS(0x40)) + if (PC < 0x80) { /* Long interrupt gets the previous PC, not the current one */ SP++; @@ -3265,7 +3264,7 @@ static size_t dsp56k_op_movec(dsp56k_core* cpustate, const uint16_t op, uint8_t* if (W) { /* Write D */ - uint16_t value = cpustate->data->read_word(ADDRESS(*((uint16_t*)R.addr))) ; + uint16_t value = cpustate->data->read_word(*((uint16_t*)R.addr)) ; typed_pointer temp_src = { &value, DT_WORD }; SetDestinationValue(temp_src, SD); } @@ -3273,7 +3272,7 @@ static size_t dsp56k_op_movec(dsp56k_core* cpustate, const uint16_t op, uint8_t* { /* Read S */ uint16_t dataMemOffset = *((uint16_t*)R.addr); - SetDataMemoryValue(cpustate, SD, ADDRESS(dataMemOffset)); + SetDataMemoryValue(cpustate, SD, dataMemOffset); } execute_MM_table(cpustate, BITS(op,0x0003), BITS(op,0x000c)); @@ -3307,7 +3306,7 @@ static size_t dsp56k_op_movec_1(dsp56k_core* cpustate, const uint16_t op, uint8_ if (W) { /* Write D */ - uint16_t tempData = cpustate->data->read_word(ADDRESS(memOffset)); + uint16_t tempData = cpustate->data->read_word(memOffset); typed_pointer temp_src = { (void*)&tempData, DT_WORD }; SetDestinationValue(temp_src, SD); } @@ -3316,7 +3315,7 @@ static size_t dsp56k_op_movec_1(dsp56k_core* cpustate, const uint16_t op, uint8_ /* Read S */ uint16_t tempData = *((uint16_t*)SD.addr); typed_pointer temp_src = { (void*)&tempData, DT_WORD }; - SetDataMemoryValue(cpustate, temp_src, ADDRESS(memOffset)); + SetDataMemoryValue(cpustate, temp_src, memOffset); } /* S L E U N Z V C */ @@ -3351,7 +3350,7 @@ static size_t dsp56k_op_movec_2(dsp56k_core* cpustate, const uint16_t op, uint8_ if (W) { /* Write D */ - uint16_t tempData = cpustate->data->read_word(ADDRESS(memOffset)); + uint16_t tempData = cpustate->data->read_word(memOffset); typed_pointer temp_src = { (void*)&tempData, DT_WORD }; SetDestinationValue(temp_src, SD); } @@ -3360,7 +3359,7 @@ static size_t dsp56k_op_movec_2(dsp56k_core* cpustate, const uint16_t op, uint8_ /* Read S */ uint16_t tempData = *((uint16_t*)SD.addr); typed_pointer temp_src = { (void*)&tempData, DT_WORD }; - SetDataMemoryValue(cpustate, temp_src, ADDRESS(memOffset)); + SetDataMemoryValue(cpustate, temp_src, memOffset); } @@ -3402,7 +3401,7 @@ static size_t dsp56k_op_movec_3(dsp56k_core* cpustate, const uint16_t op, const else { /* 16-bit long address */ - uint16_t tempD = cpustate->data->read_word(ADDRESS(op2)); + uint16_t tempD = cpustate->data->read_word(op2); typed_pointer tempTP = {&tempD, DT_WORD}; SetDestinationValue(tempTP, SD); } @@ -3418,7 +3417,7 @@ static size_t dsp56k_op_movec_3(dsp56k_core* cpustate, const uint16_t op, const else { /* 16-bit long address */ - SetDataMemoryValue(cpustate, SD, ADDRESS(op2)); + SetDataMemoryValue(cpustate, SD, op2); } } @@ -3480,7 +3479,7 @@ static size_t dsp56k_op_movec_5(dsp56k_core* cpustate, const uint16_t op, const if (W) { /* Write D */ - uint16_t tempData = cpustate->data->read_word(ADDRESS(memOffset)); + uint16_t tempData = cpustate->data->read_word(memOffset); typed_pointer temp_src = { (void*)&tempData, DT_WORD }; SetDestinationValue(temp_src, SD); } @@ -3489,7 +3488,7 @@ static size_t dsp56k_op_movec_5(dsp56k_core* cpustate, const uint16_t op, const /* Read S */ uint16_t tempData = *((uint16_t*)SD.addr); typed_pointer temp_src = { (void*)&tempData, DT_WORD }; - SetDataMemoryValue(cpustate, temp_src, ADDRESS(memOffset)); + SetDataMemoryValue(cpustate, temp_src, memOffset); } /* S L E U N Z V C */ @@ -3543,7 +3542,7 @@ static size_t dsp56k_op_movem(dsp56k_core* cpustate, const uint16_t op, uint8_t* { /* Read from Program Memory */ typed_pointer data; - uint16_t ldata = cpustate->program->read_word(ADDRESS(*((uint16_t*)R.addr))); + uint16_t ldata = cpustate->program->read_word(*((uint16_t*)R.addr)); data.addr = &ldata; data.data_type = DT_WORD; @@ -3552,7 +3551,7 @@ static size_t dsp56k_op_movem(dsp56k_core* cpustate, const uint16_t op, uint8_t* else { /* Write to Program Memory */ - SetProgramMemoryValue(cpustate, SD, ADDRESS(*((uint16_t*)R.addr))) ; + SetProgramMemoryValue(cpustate, SD, *((uint16_t*)R.addr)) ; } execute_MM_table(cpustate, BITS(op,0x00c0), BITS(op,0x0018)); @@ -3597,7 +3596,7 @@ static size_t dsp56k_op_movep(dsp56k_core* cpustate, const uint16_t op, uint8_t* if (W) { - uint16_t data = cpustate->data->read_word(ADDRESS(pp)); + uint16_t data = cpustate->data->read_word(pp); typed_pointer tempTP; tempTP.addr = &data; @@ -3607,7 +3606,7 @@ static size_t dsp56k_op_movep(dsp56k_core* cpustate, const uint16_t op, uint8_t* } else { - SetDataMemoryValue(cpustate, SD, ADDRESS(pp)); + SetDataMemoryValue(cpustate, SD, pp); } /* S L E U N Z V C */ @@ -3636,13 +3635,13 @@ static size_t dsp56k_op_movep_1(dsp56k_core* cpustate, const uint16_t op, uint8_ /* A little different than most W if's - opposite read and write */ if (W) { - uint16_t data = cpustate->data->read_word(ADDRESS(*((uint16_t*)SD.addr))); + uint16_t data = cpustate->data->read_word(*((uint16_t*)SD.addr)); typed_pointer tempTP; tempTP.addr = &data; tempTP.data_type = DT_WORD; - SetDataMemoryValue(cpustate, tempTP, ADDRESS(pp)); + SetDataMemoryValue(cpustate, tempTP, pp); } else { @@ -3770,7 +3769,7 @@ static size_t dsp56k_op_rep_1(dsp56k_core* cpustate, const uint16_t op, uint8_t* LC = iVal; cpustate->repFlag = 1; - cpustate->repAddr = PC + ADDRESS(1); + cpustate->repAddr = PC + 2; cycles += 4; /* TODO: + mv oscillator clock cycles */ } @@ -3806,7 +3805,7 @@ static size_t dsp56k_op_rep_2(dsp56k_core* cpustate, const uint16_t op, uint8_t* LC = repValue; cpustate->repFlag = 1; - cpustate->repAddr = PC + ADDRESS(1); + cpustate->repAddr = PC + 2; cycles += 4; /* TODO: + mv oscillator clock cycles */ } @@ -4663,7 +4662,7 @@ static void execute_x_memory_data_move(dsp56k_core* cpustate, const uint16_t op, if (W) { /* From X:<ea> to SD */ - uint16_t data = cpustate->data->read_word(ADDRESS(*((uint16_t*)R.addr))); + uint16_t data = cpustate->data->read_word(*((uint16_t*)R.addr)); typed_pointer tempTP; tempTP.addr = &data; @@ -4681,11 +4680,11 @@ static void execute_x_memory_data_move(dsp56k_core* cpustate, const uint16_t op, tempTP.addr = prev_accum_value; tempTP.data_type = DT_LONG_WORD; - SetDataMemoryValue(cpustate, tempTP, ADDRESS(*((uint16_t*)R.addr))) ; + SetDataMemoryValue(cpustate, tempTP, *((uint16_t*)R.addr)) ; } else { - SetDataMemoryValue(cpustate, SD, ADDRESS(*((uint16_t*)R.addr))) ; + SetDataMemoryValue(cpustate, SD, *((uint16_t*)R.addr)) ; } } @@ -4711,14 +4710,14 @@ static void execute_x_memory_data_move2(dsp56k_core* cpustate, const uint16_t op if (W) { /* Write D */ - uint16_t value = cpustate->data->read_word(ADDRESS(*mem_offset)); + uint16_t value = cpustate->data->read_word(*mem_offset); typed_pointer tempV = {&value, DT_WORD}; SetDestinationValue(tempV, SD); } else { /* Read S */ - SetDataMemoryValue(cpustate, SD, ADDRESS(*mem_offset)); + SetDataMemoryValue(cpustate, SD, *mem_offset); } } @@ -4739,7 +4738,7 @@ static void execute_x_memory_data_move_with_short_displacement(dsp56k_core* cpus if (W) { /* Write D */ - uint16_t tempData = cpustate->data->read_word(ADDRESS(memOffset)); + uint16_t tempData = cpustate->data->read_word(memOffset); typed_pointer temp_src = { (void*)&tempData, DT_WORD }; SetDestinationValue(temp_src, SD); } @@ -4748,7 +4747,7 @@ static void execute_x_memory_data_move_with_short_displacement(dsp56k_core* cpus /* Read S */ uint16_t tempData = *((uint16_t*)SD.addr); typed_pointer temp_src = { (void*)&tempData, DT_WORD }; - SetDataMemoryValue(cpustate, temp_src, ADDRESS(memOffset)); + SetDataMemoryValue(cpustate, temp_src, memOffset); } } @@ -4775,13 +4774,13 @@ static void execute_dual_x_memory_data_read(dsp56k_core* cpustate, const uint16_ fatalerror("Dsp56k: Unimplemented access to external X Data Memory >= 0xffc0 in Dual X Memory Data Read.\n"); /* First memmove */ - srcVal1 = cpustate->data->read_word(ADDRESS(*((uint16_t*)R.addr))); + srcVal1 = cpustate->data->read_word(*((uint16_t*)R.addr)); tempV.addr = &srcVal1; tempV.data_type = DT_WORD; SetDestinationValue(tempV, D1); /* Second memmove */ - srcVal2 = cpustate->data->read_word(ADDRESS(R3)); + srcVal2 = cpustate->data->read_word(R3); tempV.addr = &srcVal2; tempV.data_type = DT_WORD; SetDestinationValue(tempV, D2); diff --git a/src/devices/cpu/dsp56k/inst.h b/src/devices/cpu/dsp56k/inst.h index 91a624f030a..d2db2a013e9 100644 --- a/src/devices/cpu/dsp56k/inst.h +++ b/src/devices/cpu/dsp56k/inst.h @@ -15,7 +15,6 @@ // namespace DSP56K { -#define ADDRESS(X) ((X)<<1) #define UNIMPLEMENTED_OPCODE() osd_printf_error("Unimplemented opcode: PC=%04x | %s;\n", PC, __PRETTY_FUNCTION__); class Opcode; @@ -759,7 +758,7 @@ public: void evaluate(dsp56k_core* cpustate) override {} size_t size() const override { return 2; } size_t accumulatorBitsModified() const override { return BM_HIGH | BM_MIDDLE | BM_LOW; } - size_t flags() const override { return DASMFLAG_STEP_OVER; } + size_t flags() const override { return util::disasm_interface::STEP_OVER; } private: op_mnem m_mnem; @@ -790,7 +789,7 @@ public: void evaluate(dsp56k_core* cpustate) override {} size_t size() const override { return 1; } size_t accumulatorBitsModified() const override { return BM_HIGH | BM_MIDDLE | BM_LOW; } - size_t flags() const override { return DASMFLAG_STEP_OVER; } + size_t flags() const override { return util::disasm_interface::STEP_OVER; } private: op_mnem m_mnem; @@ -821,7 +820,7 @@ public: void evaluate(dsp56k_core* cpustate) override {} size_t size() const override { return 2; } size_t accumulatorBitsModified() const override { return BM_HIGH | BM_MIDDLE | BM_LOW; } - size_t flags() const override { return DASMFLAG_STEP_OVER; } + size_t flags() const override { return util::disasm_interface::STEP_OVER; } private: int16_t m_immediate; @@ -847,7 +846,7 @@ public: void evaluate(dsp56k_core* cpustate) override {} size_t size() const override { return 1; } size_t accumulatorBitsModified() const override { return BM_HIGH | BM_MIDDLE | BM_LOW; } - size_t flags() const override { return DASMFLAG_STEP_OVER; } + size_t flags() const override { return util::disasm_interface::STEP_OVER; } }; // CHKAAU : 0000 0000 0000 0100 : A-58 ///////////////////////////////////////// @@ -1597,7 +1596,7 @@ public: void evaluate(dsp56k_core* cpustate) override {} size_t size() const override { return 2; } size_t accumulatorBitsModified() const override { return BM_HIGH | BM_MIDDLE | BM_LOW; } - size_t flags() const override { return DASMFLAG_STEP_OVER; } + size_t flags() const override { return util::disasm_interface::STEP_OVER; } private: op_mnem m_mnem; @@ -1628,7 +1627,7 @@ public: void evaluate(dsp56k_core* cpustate) override {} size_t size() const override { return 1; } size_t accumulatorBitsModified() const override { return BM_HIGH | BM_MIDDLE | BM_LOW; } - size_t flags() const override { return DASMFLAG_STEP_OVER; } + size_t flags() const override { return util::disasm_interface::STEP_OVER; } private: op_mnem m_mnem; @@ -1658,7 +1657,7 @@ public: void evaluate(dsp56k_core* cpustate) override {} size_t size() const override { return 2; } size_t accumulatorBitsModified() const override { return BM_HIGH | BM_MIDDLE | BM_LOW; } - size_t flags() const override { return DASMFLAG_STEP_OVER; } + size_t flags() const override { return util::disasm_interface::STEP_OVER; } private: uint16_t m_displacement; @@ -1688,7 +1687,7 @@ public: void evaluate(dsp56k_core* cpustate) override {} size_t size() const override { return 1; } size_t accumulatorBitsModified() const override { return BM_HIGH | BM_MIDDLE | BM_LOW; } - size_t flags() const override { return DASMFLAG_STEP_OVER; } + size_t flags() const override { return util::disasm_interface::STEP_OVER; } private: uint8_t m_bAddr; @@ -1714,7 +1713,7 @@ public: void evaluate(dsp56k_core* cpustate) override {} size_t size() const override { return 1; } size_t accumulatorBitsModified() const override { return BM_HIGH | BM_MIDDLE | BM_LOW; } - size_t flags() const override { return DASMFLAG_STEP_OVER; } + size_t flags() const override { return util::disasm_interface::STEP_OVER; } }; // LEA : 0000 0001 11TT MMRR : A-116 /////////////////////////////////////////// @@ -3236,7 +3235,7 @@ public: void evaluate(dsp56k_core* cpustate) override {} size_t size() const override { return 1; } size_t accumulatorBitsModified() const override { return BM_HIGH | BM_MIDDLE | BM_LOW; } - size_t flags() const override { return DASMFLAG_STEP_OUT; } + size_t flags() const override { return util::disasm_interface::STEP_OUT; } }; // RTS : 0000 0000 0000 0110 : A-196 /////////////////////////////////////////// @@ -3258,7 +3257,7 @@ public: void evaluate(dsp56k_core* cpustate) override {} size_t size() const override { return 1; } size_t accumulatorBitsModified() const override { return BM_HIGH | BM_MIDDLE | BM_LOW; } - size_t flags() const override { return DASMFLAG_STEP_OUT; } + size_t flags() const override { return util::disasm_interface::STEP_OUT; } }; // SBC : .... .... 0101 F01J : A-198 /////////////////////////////////////////// diff --git a/src/devices/cpu/e0c6200/e0c6200.cpp b/src/devices/cpu/e0c6200/e0c6200.cpp index ad4e99ba8c6..4deadeb6bff 100644 --- a/src/devices/cpu/e0c6200/e0c6200.cpp +++ b/src/devices/cpu/e0c6200/e0c6200.cpp @@ -20,6 +20,7 @@ #include "emu.h" #include "e0c6200.h" +#include "e0c6200d.h" #include "debugger.h" @@ -49,10 +50,9 @@ void e0c6200_cpu_device::state_string_export(const device_state_entry &entry, st } } -offs_t e0c6200_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +util::disasm_interface *e0c6200_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE(e0c6200); - return CPU_DISASSEMBLE_NAME(e0c6200)(this, stream, pc, oprom, opram, options); + return new e0c6200_disassembler; } @@ -211,7 +211,7 @@ void e0c6200_cpu_device::execute_run() // fetch next opcode debugger_instruction_hook(this, m_pc); - m_op = m_program->read_word(m_pc << 1) & 0xfff; + m_op = m_program->read_word(m_pc) & 0xfff; m_pc = (m_pc & 0x1000) | ((m_pc + 1) & 0x0fff); // minimal opcode time is 5 clock cycles, opcodes take 5, 7, or 12 clock cycles diff --git a/src/devices/cpu/e0c6200/e0c6200.h b/src/devices/cpu/e0c6200/e0c6200.h index 2a8c02734ec..9328aed7cf1 100644 --- a/src/devices/cpu/e0c6200/e0c6200.h +++ b/src/devices/cpu/e0c6200/e0c6200.h @@ -34,9 +34,8 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual u32 disasm_min_opcode_bytes() const override { return 2; } - virtual u32 disasm_max_opcode_bytes() const override { return 2; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; + virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; address_space_config m_program_config; diff --git a/src/devices/cpu/e0c6200/e0c6200d.cpp b/src/devices/cpu/e0c6200/e0c6200d.cpp index fde754ef051..be2a4ea4d6d 100644 --- a/src/devices/cpu/e0c6200/e0c6200d.cpp +++ b/src/devices/cpu/e0c6200/e0c6200d.cpp @@ -7,21 +7,9 @@ */ #include "emu.h" -#include "debugger.h" -#include "e0c6200.h" +#include "e0c6200d.h" -// opcode mnemonics -enum e_mnemonics -{ - em_JP, em_RETD, em_CALL, em_CALZ, - em_LD, em_LBPX, em_ADC, em_CP, em_ADD, em_SUB, em_SBC, em_AND, em_OR, em_XOR, - em_RLC, em_FAN, em_PSET, em_LDPX, em_LDPY, em_SET, em_RST, em_INC, em_DEC, - em_RRC, em_ACPX, em_ACPY, em_SCPX, em_SCPY, em_PUSH, em_POP, - em_RETS, em_RET, em_JPBA, em_HALT, em_SLP, em_NOP5, em_NOP7, - em_NOT, em_SCF, em_SZF, em_SDF, em_EI, em_DI, em_RDF, em_RZF, em_RCF, em_ILL -}; - -static const char *const em_name[] = +const char *const e0c6200_disassembler::em_name[] = { "JP", "RETD", "CALL", "CALZ", "LD", "LBPX", "ADC", "CP", "ADD", "SUB", "SBC", "AND", "OR", "XOR", @@ -31,32 +19,20 @@ static const char *const em_name[] = "NOT", "SCF", "SZF", "SDF", "EI", "DI", "RDF", "RZF", "RCF", "?" }; -#define _OVER DASMFLAG_STEP_OVER -#define _OUT DASMFLAG_STEP_OUT - -static const u32 em_flags[] = +const u32 e0c6200_disassembler::em_flags[] = { - 0, _OUT, _OVER, _OVER, + 0, STEP_OUT, STEP_OVER, STEP_OVER, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - _OUT, _OUT, 0, _OVER, _OVER, 0, 0, + STEP_OUT, STEP_OUT, 0, STEP_OVER, STEP_OVER, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -// opcode params -enum e_params -{ - ep_S, ep_E, ep_I, ep_R0, ep_R2, ep_R4, ep_Q, - ep_cC, ep_cNC, ep_cZ, ep_cNZ, - ep_A, ep_B, ep_X, ep_Y, ep_MX, ep_MY, ep_XP, ep_XH, ep_XL, ep_YP, ep_YH, ep_YL, - ep_P, ep_F, ep_MN, ep_SP, ep_SPH, ep_SPL -}; - // 0-digit is number of bits per opcode parameter, 0 bits is literal, // 0x10-digit is for shift-right, 0x100-digit is special flag for r/q param -static const u16 ep_bits[] = +const u16 e0c6200_disassembler::ep_bits[] = { 8, 8, 4, 0x102, 0x122, 0x142, 0x102, 0, 0, 0, 0, @@ -65,10 +41,10 @@ static const u16 ep_bits[] = }; // redirect for r/q param -static const u8 ep_redirect_r[4] = { ep_A, ep_B, ep_MX, ep_MY }; +const u8 e0c6200_disassembler::ep_redirect_r[4] = { ep_A, ep_B, ep_MX, ep_MY }; // literal opcode parameter -static const char *const ep_name[] = +const char *const e0c6200_disassembler::ep_name[] = { " ", " ", " ", " ", " ", " ", " ", "C", "NC", "Z", "NZ", @@ -77,7 +53,7 @@ static const char *const ep_name[] = }; -static char* decode_param(u16 opcode, int param, char* buffer) +std::string e0c6200_disassembler::decode_param(u16 opcode, int param) { int bits = ep_bits[param] & 0xf; int shift = ep_bits[param] >> 4 & 0xf; @@ -89,30 +65,22 @@ static char* decode_param(u16 opcode, int param, char* buffer) // literal param if (ep_bits[param] == 0) - { - strcpy(buffer, ep_name[param]); - return buffer; - } + return ep_name[param]; // print value like how it's documented in the manual - char val[10]; - if (bits > 4 || opmask > 9) - sprintf(val, "%02XH", opmask); - else - sprintf(val, "%d", opmask); + std::string val = (bits > 4 || opmask > 9) ? + util::string_format("%02XH", opmask) : + util::string_format("%d", opmask); if (param == ep_MN) - sprintf(buffer, "M%s", val); + return 'M' + val; else - strcpy(buffer, val); - - return buffer; + return val; } - -CPU_DISASSEMBLE(e0c6200) +offs_t e0c6200_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - u16 op = (oprom[1] | oprom[0] << 8) & 0xfff; + u16 op = opcodes.r16(pc) & 0xfff; int m; int p1 = -1; @@ -693,15 +661,34 @@ CPU_DISASSEMBLE(e0c6200) util::stream_format(stream, "%-6s", em_name[m]); // fetch param(s) - char pbuffer[10]; if (p1 != -1) { - util::stream_format(stream, "%s", decode_param(op, p1, pbuffer)); + util::stream_format(stream, "%s", decode_param(op, p1)); if (p2 != -1) { - util::stream_format(stream, ",%s", decode_param(op, p2, pbuffer)); + util::stream_format(stream, ",%s", decode_param(op, p2)); } } - return 1 | em_flags[m] | DASMFLAG_SUPPORTED; + return 1 | em_flags[m] | SUPPORTED; +} + +u32 e0c6200_disassembler::opcode_alignment() const +{ + return 1; +} + +u32 e0c6200_disassembler::interface_flags() const +{ + return PAGED2LEVEL; +} + +u32 e0c6200_disassembler::page_address_bits() const +{ + return 8; +} + +u32 e0c6200_disassembler::page2_address_bits() const +{ + return 4; } diff --git a/src/devices/cpu/e0c6200/e0c6200d.h b/src/devices/cpu/e0c6200/e0c6200d.h new file mode 100644 index 00000000000..d2555c4ead8 --- /dev/null +++ b/src/devices/cpu/e0c6200/e0c6200d.h @@ -0,0 +1,55 @@ +// license:BSD-3-Clause +// copyright-holders:hap +/* + + Seiko Epson E0C6200 disassembler + +*/ + +#ifndef MAME_CPU_E0C6200_E0C6200D_H +#define MAME_CPU_E0C6200_E0C6200D_H + +#pragma once + +class e0c6200_disassembler : public util::disasm_interface +{ +public: + e0c6200_disassembler() = default; + virtual ~e0c6200_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual u32 interface_flags() const override; + virtual u32 page_address_bits() const override; + virtual u32 page2_address_bits() const override; + + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum e_mnemonics + { + em_JP, em_RETD, em_CALL, em_CALZ, + em_LD, em_LBPX, em_ADC, em_CP, em_ADD, em_SUB, em_SBC, em_AND, em_OR, em_XOR, + em_RLC, em_FAN, em_PSET, em_LDPX, em_LDPY, em_SET, em_RST, em_INC, em_DEC, + em_RRC, em_ACPX, em_ACPY, em_SCPX, em_SCPY, em_PUSH, em_POP, + em_RETS, em_RET, em_JPBA, em_HALT, em_SLP, em_NOP5, em_NOP7, + em_NOT, em_SCF, em_SZF, em_SDF, em_EI, em_DI, em_RDF, em_RZF, em_RCF, em_ILL + }; + + enum e_params + { + ep_S, ep_E, ep_I, ep_R0, ep_R2, ep_R4, ep_Q, + ep_cC, ep_cNC, ep_cZ, ep_cNZ, + ep_A, ep_B, ep_X, ep_Y, ep_MX, ep_MY, ep_XP, ep_XH, ep_XL, ep_YP, ep_YH, ep_YL, + ep_P, ep_F, ep_MN, ep_SP, ep_SPH, ep_SPL + }; + + static const char *const em_name[]; + static const u32 em_flags[]; + static const u16 ep_bits[]; + static const u8 ep_redirect_r[4]; + static const char *const ep_name[]; + + std::string decode_param(u16 opcode, int param); +}; + +#endif diff --git a/src/devices/cpu/e132xs/32xsdasm.cpp b/src/devices/cpu/e132xs/32xsdasm.cpp index ec853983346..2060350c5b8 100644 --- a/src/devices/cpu/e132xs/32xsdasm.cpp +++ b/src/devices/cpu/e132xs/32xsdasm.cpp @@ -8,13 +8,11 @@ */ #include "emu.h" -#include "e132xs.h" -#include "debugger.h" - +#include "32xsdasm.h" #include "32xsdefs.h" -static const char *const L_REG[] = +const char *const hyperstone_disassembler::L_REG[] = { "L0", "L1", "L2", "L3", "L4", "L5", "L6", "L7", "L8", "L9", "L10", "L11", "L12", "L13", "L14", "L15", "L16", "L17", "L18", "L19", @@ -25,7 +23,7 @@ static const char *const L_REG[] = "L60", "L61", "L62", "L63" }; -static const char *const G_REG[] = +const char *const hyperstone_disassembler::G_REG[] = { "PC", "SR", "FER", "G03", "G04", "G05", "G06", "G07", "G08", "G09", "G10", "G11", "G12", "G13", "G14", "G15", "G16", "G17", "SP", "UB", @@ -33,7 +31,7 @@ static const char *const G_REG[] = "G30", "G31" }; -static const char *const SETxx[] = +const char *const hyperstone_disassembler::SETxx[] = { "SETADR", "Reserved", "SET1", "SET0", "SETLE", "SETGT", "SETLT", "SETGE", "SETSE", "SETHT", "SETST", "SETHE", "SETE", "SETNE", "SETV", "SETNV", @@ -49,20 +47,13 @@ static const char *const SETxx[] = #define N_VALUE(op) ((((op & 0x100) >> 8) << 4 ) | (op & 0x0f)) -static int size, global_fp; - -static offs_t base_pc; -static const uint8_t *base_oprom; -#define READ_OP_DASM(p) ((base_oprom[(p) - base_pc] << 8) | base_oprom[(p) + 1 - base_pc]) - - -static void LL_format(char *source, char *dest, uint16_t op) +void hyperstone_disassembler::LL_format(char *source, char *dest, uint16_t op) { strcpy(source, L_REG[(SOURCECODE(op)+global_fp)%64]); strcpy(dest, L_REG[(DESTCODE(op)+global_fp)%64]); } -static void LR_format(char *source, char *dest, uint16_t op) +void hyperstone_disassembler::LR_format(char *source, char *dest, uint16_t op) { if( SOURCEBIT(op) ) { @@ -76,7 +67,7 @@ static void LR_format(char *source, char *dest, uint16_t op) strcpy(dest, L_REG[(DESTCODE(op)+global_fp)%64]); } -static void RR_format(char *source, char *dest, uint16_t op, unsigned h_flag) +void hyperstone_disassembler::RR_format(char *source, char *dest, uint16_t op, unsigned h_flag) { if( SOURCEBIT(op) ) { @@ -97,7 +88,7 @@ static void RR_format(char *source, char *dest, uint16_t op, unsigned h_flag) } } -static uint32_t LRconst_format(char *source, char *dest, uint16_t op, unsigned *pc) +uint32_t hyperstone_disassembler::LRconst_format(char *source, char *dest, uint16_t op, offs_t &pc, const data_buffer &opcodes) { uint16_t next_op; uint32_t const_val; @@ -115,8 +106,8 @@ static uint32_t LRconst_format(char *source, char *dest, uint16_t op, unsigned * size = 4; - *pc += 2; - next_op = READ_OP_DASM(*pc); + pc += 2; + next_op = opcodes.r16(pc); if( E_BIT(next_op) ) { @@ -124,8 +115,8 @@ static uint32_t LRconst_format(char *source, char *dest, uint16_t op, unsigned * size = 6; - *pc += 2; - next_op2 = READ_OP_DASM(*pc); + pc += 2; + next_op2 = opcodes.r16(pc); const_val = next_op2; const_val |= ((next_op & 0x3fff) << 16 ); @@ -147,7 +138,7 @@ static uint32_t LRconst_format(char *source, char *dest, uint16_t op, unsigned * return const_val; } -static uint32_t RRconst_format(char *source, char *dest, uint16_t op, unsigned *pc) +uint32_t hyperstone_disassembler::RRconst_format(char *source, char *dest, uint16_t op, offs_t &pc, const data_buffer &opcodes) { uint16_t next_op; uint32_t const_val; @@ -172,8 +163,8 @@ static uint32_t RRconst_format(char *source, char *dest, uint16_t op, unsigned * size = 4; - *pc += 2; - next_op = READ_OP_DASM(*pc); + pc += 2; + next_op = opcodes.r16(pc); if( E_BIT(next_op) ) { @@ -181,8 +172,8 @@ static uint32_t RRconst_format(char *source, char *dest, uint16_t op, unsigned * size = 6; - *pc += 2; - next_op2 = READ_OP_DASM(*pc); + pc += 2; + next_op2 = opcodes.r16(pc); const_val = next_op2; const_val |= ((next_op & 0x3fff) << 16 ); @@ -204,7 +195,7 @@ static uint32_t RRconst_format(char *source, char *dest, uint16_t op, unsigned * return const_val; } -static int32_t Rimm_format(char *dest, uint16_t op, unsigned *pc, unsigned h_flag) +int32_t hyperstone_disassembler::Rimm_format(char *dest, uint16_t op, offs_t &pc, const data_buffer &opcodes, unsigned h_flag) { uint16_t imm1, imm2; int32_t ret; @@ -227,10 +218,10 @@ static int32_t Rimm_format(char *dest, uint16_t op, unsigned *pc, unsigned h_fla return n; case 17: - *pc += 2; - imm1 = READ_OP_DASM(*pc); - *pc += 2; - imm2 = READ_OP_DASM(*pc); + pc += 2; + imm1 = opcodes.r16(pc); + pc += 2; + imm2 = opcodes.r16(pc); ret = (imm1 << 16) | imm2; size = 6; @@ -238,15 +229,15 @@ static int32_t Rimm_format(char *dest, uint16_t op, unsigned *pc, unsigned h_fla case 18: - *pc += 2; - ret = READ_OP_DASM(*pc); + pc += 2; + ret = opcodes.r16(pc); size = 4; return ret; case 19: - *pc += 2; - ret = (int32_t) (0xffff0000 | READ_OP_DASM(*pc)); + pc += 2; + ret = (int32_t) (0xffff0000 | opcodes.r16(pc)); size = 4; return ret; @@ -292,14 +283,14 @@ static int32_t Rimm_format(char *dest, uint16_t op, unsigned *pc, unsigned h_fla } } -static uint8_t Ln_format(char *dest, uint16_t op) +uint8_t hyperstone_disassembler::Ln_format(char *dest, uint16_t op) { strcpy(dest, L_REG[(DESTCODE(op)+global_fp)%64]); return N_VALUE(op); } -static uint8_t Rn_format(char *dest, uint16_t op) +uint8_t hyperstone_disassembler::Rn_format(char *dest, uint16_t op) { if( DESTBIT(op) ) { @@ -313,7 +304,7 @@ static uint8_t Rn_format(char *dest, uint16_t op) return N_VALUE(op); } -static int32_t PCrel_format(uint16_t op, unsigned pc) +int32_t hyperstone_disassembler::PCrel_format(uint16_t op, offs_t pc, const data_buffer &opcodes) { int32_t ret; @@ -325,7 +316,7 @@ static int32_t PCrel_format(uint16_t op, unsigned pc) pc += 2; - next = READ_OP_DASM(pc); + next = opcodes.r16(pc); ret = (op & 0x7f) << 16; @@ -345,7 +336,7 @@ static int32_t PCrel_format(uint16_t op, unsigned pc) return (pc + ret); } -static uint32_t RRdis_format(char *source, char *dest, uint16_t op, uint16_t next_op, unsigned pc) +uint32_t hyperstone_disassembler::RRdis_format(char *source, char *dest, uint16_t op, uint16_t next_op, offs_t pc, const data_buffer &opcodes) { uint32_t ret; @@ -373,7 +364,7 @@ static uint32_t RRdis_format(char *source, char *dest, uint16_t op, uint16_t nex size = 6; - next = READ_OP_DASM(pc + 4); + next = opcodes.r16(pc + 4); ret = next; ret |= ( ( next_op & 0xfff ) << 16 ); @@ -395,7 +386,15 @@ static uint32_t RRdis_format(char *source, char *dest, uint16_t op, uint16_t nex return ret; } -unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom, unsigned h_flag, int private_fp) +u32 hyperstone_disassembler::opcode_alignment() const +{ + return 2; +} + +/*****************************/ +/* Main disassembly function */ +/*****************************/ +offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint16_t op; uint8_t op_num; @@ -405,10 +404,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom char source[5] = "\0", dest[5] = "\0"; uint32_t flags = 0; - base_pc = pc; - base_oprom = oprom; - - op = READ_OP_DASM(pc); + op = opcodes.r16(pc); size = 2; @@ -417,7 +413,8 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom source_bit = SOURCEBIT(op); dest_bit = DESTBIT(op); - global_fp = private_fp; + global_fp = 0; + int h_flag = 0; op_num = (op & 0xff00) >> 8; @@ -456,7 +453,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom global_fp = 0; RR_format(source, dest, op, 0); util::stream_format(stream, "RET PC, %s", source); - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; } else if( source_code == SR_REGISTER && !source_bit ) { @@ -495,7 +492,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom size = 4; pc += 2; - op = READ_OP_DASM(pc); + op = opcodes.r16(pc); xcode = X_CODE(op); @@ -510,7 +507,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom size = 6; pc += 2; - next_op = READ_OP_DASM(pc); + next_op = opcodes.r16(pc); lim = ((op & 0xfff) << 16) | next_op; } @@ -533,7 +530,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // MASK case 0x14: case 0x15: case 0x16: case 0x17: { - uint32_t const_val = RRconst_format(source, dest, op, &pc); + uint32_t const_val = RRconst_format(source, dest, op, pc, opcodes); util::stream_format(stream, "MASK %s, %s, $%x", dest, source, const_val); @@ -543,7 +540,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // SUM case 0x18: case 0x19: case 0x1a: case 0x1b: { - uint32_t const_val = RRconst_format(source, dest, op, &pc); + uint32_t const_val = RRconst_format(source, dest, op, pc, opcodes); if( source_code == SR_REGISTER && !source_bit ) { @@ -560,7 +557,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // SUMS case 0x1c: case 0x1d: case 0x1e: case 0x1f: { - uint32_t const_val = RRconst_format(source, dest, op, &pc); + uint32_t const_val = RRconst_format(source, dest, op, pc, opcodes); if( source_code == SR_REGISTER && !source_bit ) { @@ -778,7 +775,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // CMPI case 0x60: case 0x61: case 0x62: case 0x63: { - uint32_t imm = Rimm_format(dest, op, &pc, 0); + uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0); util::stream_format(stream, "CMPI %s, $%x", dest, imm); @@ -788,7 +785,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // MOVI case 0x64: case 0x65: case 0x66: case 0x67: { - uint32_t imm = Rimm_format(dest, op, &pc, h_flag); + uint32_t imm = Rimm_format(dest, op, pc, opcodes, h_flag); util::stream_format(stream, "MOVI %s, $%x", dest, imm); @@ -798,7 +795,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // ADDI case 0x68: case 0x69: case 0x6a: case 0x6b: { - uint32_t imm = Rimm_format(dest, op, &pc, 0); + uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0); if( !N_VALUE(op) ) { @@ -815,7 +812,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // ADDSI case 0x6c: case 0x6d: case 0x6e: case 0x6f: { - uint32_t imm = Rimm_format(dest, op, &pc, 0); + uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0); if( !N_VALUE(op) ) { @@ -832,7 +829,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // CMPBI case 0x70: case 0x71: case 0x72: case 0x73: { - uint32_t imm = Rimm_format(dest, op, &pc, 0); + uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0); if( !N_VALUE(op) ) { @@ -852,7 +849,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // ANDNI case 0x74: case 0x75: case 0x76: case 0x77: { - uint32_t imm = Rimm_format(dest, op, &pc, 0); + uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0); if( N_VALUE(op) == 31 ) imm = 0x7fffffff; //bit 31 = 0, others = 1 @@ -865,7 +862,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // ORI case 0x78: case 0x79: case 0x7a: case 0x7b: { - uint32_t imm = Rimm_format(dest, op, &pc, 0); + uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0); util::stream_format(stream, "ORI %s, $%x", dest, imm); @@ -875,7 +872,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // XORI case 0x7c: case 0x7d: case 0x7e: case 0x7f: { - uint32_t imm = Rimm_format(dest, op, &pc, 0); + uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0); util::stream_format(stream, "XORI %s, $%x", dest, imm); @@ -995,8 +992,8 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // LDxx.D/A/IOD/IOA case 0x90: case 0x91: case 0x92: case 0x93: { - uint16_t next_op = READ_OP_DASM(pc + 2); - uint32_t dis = RRdis_format(source, dest, op, next_op, pc); + uint16_t next_op = opcodes.r16(pc + 2); + uint32_t dis = RRdis_format(source, dest, op, next_op, pc, opcodes); if( size == 2 ) size = 4; @@ -1113,8 +1110,8 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // LDxx.N/S case 0x94: case 0x95: case 0x96: case 0x97: { - uint16_t next_op = READ_OP_DASM(pc + 2); - uint32_t dis = RRdis_format(source, dest, op, next_op, pc); + uint16_t next_op = opcodes.r16(pc + 2); + uint32_t dis = RRdis_format(source, dest, op, next_op, pc, opcodes); if( size == 2 ) size = 4; @@ -1182,8 +1179,8 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // STxx.D/A/IOD/IOA case 0x98: case 0x99: case 0x9a: case 0x9b: { - uint16_t next_op = READ_OP_DASM(pc + 2); - uint32_t dis = RRdis_format(source, dest, op, next_op, pc); + uint16_t next_op = opcodes.r16(pc + 2); + uint32_t dis = RRdis_format(source, dest, op, next_op, pc, opcodes); if( size == 2 ) size = 4; @@ -1303,8 +1300,8 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // STxx.N/S case 0x9c: case 0x9d: case 0x9e: case 0x9f: { - uint16_t next_op = READ_OP_DASM(pc + 2); - uint32_t dis = RRdis_format(source, dest, op, next_op, pc); + uint16_t next_op = opcodes.r16(pc + 2); + uint32_t dis = RRdis_format(source, dest, op, next_op, pc, opcodes); if( size == 2 ) size = 4; @@ -1584,7 +1581,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom LL_format(source, dest, op); pc += 2; - extended_op = READ_OP_DASM(pc); + extended_op = opcodes.r16(pc); size = 4; @@ -1752,10 +1749,10 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // DBV case 0xe0: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "DBV $%x", rel); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; } @@ -1763,10 +1760,10 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // DBNV case 0xe1: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "DBNV $%x", rel); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; } @@ -1774,10 +1771,10 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // DBE case 0xe2: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "DBE $%x", rel); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; } @@ -1785,10 +1782,10 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // DBNE case 0xe3: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "DBNE $%x", rel); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; } @@ -1796,10 +1793,10 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // DBC case 0xe4: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "DBC $%x", rel); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; } @@ -1807,10 +1804,10 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // DBNC case 0xe5: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "DBNC $%x", rel); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; } @@ -1818,10 +1815,10 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // DBSE case 0xe6: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "DBSE $%x", rel); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; } @@ -1829,10 +1826,10 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // DBHT case 0xe7: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "DBHT $%x", rel); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; } @@ -1840,10 +1837,10 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // DBN case 0xe8: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "DBN $%x", rel); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; } @@ -1851,10 +1848,10 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // DBNN case 0xe9: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "DBNN $%x", rel); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; } @@ -1862,10 +1859,10 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // DBLE case 0xea: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "DBLE $%x", rel); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; } @@ -1873,10 +1870,10 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // DBGT case 0xeb: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "DBGT $%x", rel); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; } @@ -1884,10 +1881,10 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // DBR case 0xec: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "DBR $%x", rel); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; } @@ -1905,17 +1902,17 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // CALL case 0xee: case 0xef: { - uint32_t const_val = LRconst_format(source, dest, op, &pc); + uint32_t const_val = LRconst_format(source, dest, op, pc, opcodes); if( source_code == SR_REGISTER && !source_bit ) { util::stream_format(stream, "CALL %s, 0, $%x", dest, const_val); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; } else { util::stream_format(stream, "CALL %s, %s, $%x", dest, source, const_val); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; } break; @@ -1924,7 +1921,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // BV case 0xf0: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "BV $%x", rel); @@ -1934,7 +1931,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // BNV case 0xf1: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "BNV $%x", rel); @@ -1944,7 +1941,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // BE case 0xf2: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "BE $%x", rel); @@ -1954,7 +1951,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // BNE case 0xf3: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "BNE $%x", rel); @@ -1964,7 +1961,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // BC case 0xf4: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "BC $%x", rel); @@ -1974,7 +1971,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // BNC case 0xf5: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "BNC $%x", rel); @@ -1984,7 +1981,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // BSE case 0xf6: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "BSE $%x", rel); @@ -1994,7 +1991,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // BHT case 0xf7: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "BHT $%x", rel); @@ -2004,7 +2001,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // BN case 0xf8: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "BN $%x", rel); @@ -2014,7 +2011,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // BNN case 0xf9: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "BNN $%x", rel); @@ -2024,7 +2021,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // BLE case 0xfa: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "BLE $%x", rel); @@ -2034,7 +2031,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // BGT case 0xfb: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "BGT $%x", rel); @@ -2044,7 +2041,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // BR case 0xfc: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "BR $%x", rel); @@ -2061,73 +2058,73 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom { case TRAPLE: util::stream_format(stream, "TRAPLE %d", trapno); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case TRAPGT: util::stream_format(stream, "TRAPGT %d", trapno); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case TRAPLT: util::stream_format(stream, "TRAPLT %d", trapno); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case TRAPGE: util::stream_format(stream, "TRAPGE %d", trapno); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case TRAPSE: util::stream_format(stream, "TRAPSE %d", trapno); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case TRAPHT: util::stream_format(stream, "TRAPHT %d", trapno); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case TRAPST: util::stream_format(stream, "TRAPST %d", trapno); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case TRAPHE: util::stream_format(stream, "TRAPHE %d", trapno); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case TRAPE: util::stream_format(stream, "TRAPE %d", trapno); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case TRAPNE: util::stream_format(stream, "TRAPNE %d", trapno); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case TRAPV: util::stream_format(stream, "TRAPV %d", trapno); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case TRAP: util::stream_format(stream, "TRAP %d", trapno); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; } @@ -2136,10 +2133,5 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom } } - return size | flags | DASMFLAG_SUPPORTED; -} - -CPU_DISASSEMBLE( hyperstone_generic ) -{ - return dasm_hyperstone( stream, pc, oprom, 0, 0 ); + return size | flags | SUPPORTED; } diff --git a/src/devices/cpu/e132xs/32xsdasm.h b/src/devices/cpu/e132xs/32xsdasm.h new file mode 100644 index 00000000000..6c5b0fa4482 --- /dev/null +++ b/src/devices/cpu/e132xs/32xsdasm.h @@ -0,0 +1,43 @@ +// license:BSD-3-Clause +// copyright-holders:Pierpaolo Prazzoli +/* + + Hyperstone disassembler + written by Pierpaolo Prazzoli + +*/ + +#ifndef MAME_CPU_E132XS_32XSDASM_H +#define MAME_CPU_E132XS_32XSDASM_H + +#pragma once + +class hyperstone_disassembler : public util::disasm_interface +{ +public: + hyperstone_disassembler() = default; + virtual ~hyperstone_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *const L_REG[]; + static const char *const G_REG[]; + static const char *const SETxx[]; + + int size, global_fp; + + void LL_format(char *source, char *dest, uint16_t op); + void LR_format(char *source, char *dest, uint16_t op); + void RR_format(char *source, char *dest, uint16_t op, unsigned h_flag); + uint32_t LRconst_format(char *source, char *dest, uint16_t op, offs_t &pc, const data_buffer &opcodes); + uint32_t RRconst_format(char *source, char *dest, uint16_t op, offs_t &pc, const data_buffer &opcodes); + int32_t Rimm_format(char *dest, uint16_t op, offs_t &pc, const data_buffer &opcodes, unsigned h_flag); + uint8_t Ln_format(char *dest, uint16_t op); + uint8_t Rn_format(char *dest, uint16_t op); + int32_t PCrel_format(uint16_t op, offs_t pc, const data_buffer &opcodes); + uint32_t RRdis_format(char *source, char *dest, uint16_t op, uint16_t next_op, offs_t pc, const data_buffer &opcodes); +}; + +#endif diff --git a/src/devices/cpu/e132xs/32xsdefs.h b/src/devices/cpu/e132xs/32xsdefs.h index 164377f0060..a4a5ff876df 100644 --- a/src/devices/cpu/e132xs/32xsdefs.h +++ b/src/devices/cpu/e132xs/32xsdefs.h @@ -9,10 +9,13 @@ #define PC_REGISTER 0 #define SR_REGISTER 1 +#define SP_REGISTER 18 +#define UB_REGISTER 19 #define BCR_REGISTER 20 #define TPR_REGISTER 21 #define TCR_REGISTER 22 #define TR_REGISTER 23 +#define WCR_REGISTER 24 #define ISR_REGISTER 25 #define FCR_REGISTER 26 #define MCR_REGISTER 27 @@ -39,10 +42,6 @@ #define EHCFFTD 0x096 #define EHCFFTSD 0x296 -/* Delay values */ -#define NO_DELAY 0 -#define DELAY_EXECUTE 1 - /* IRQ numbers */ #define IRQ_INT1 0 #define IRQ_INT2 1 @@ -93,4 +92,146 @@ #define E132XS_ENTRY_IRAM 3 #define E132XS_ENTRY_MEM3 7 +/* Memory access */ +/* read byte */ +#define READ_B(addr) m_program->read_byte((addr)) +/* read half-word */ +#define READ_HW(addr) m_program->read_word((addr) & ~1) +/* read word */ +#define READ_W(addr) m_program->read_dword((addr) & ~3) + +/* write byte */ +#define WRITE_B(addr, data) m_program->write_byte(addr, data) +/* write half-word */ +#define WRITE_HW(addr, data) m_program->write_word((addr) & ~1, data) +/* write word */ +#define WRITE_W(addr, data) m_program->write_dword((addr) & ~3, data) + + +/* I/O access */ +/* read word */ +#define IO_READ_W(addr) m_io->read_dword(((addr) >> 11) & 0x7ffc) +/* write word */ +#define IO_WRITE_W(addr, data) m_io->write_dword(((addr) >> 11) & 0x7ffc, data) + + +#define READ_OP(addr) m_direct->read_word((addr), m_opcodexor) + +// set C in adds/addsi/subs/sums +#define SETCARRYS 0 +#define MISSIONCRAFT_FLAGS 1 + +/* Registers */ + +/* Internal registers */ + +#define SREG decode.src_value +#define SREGF decode.next_src_value +#define DREG decode.dst_value +#define DREGF decode.next_dst_value +#define EXTRA_U decode.extra.u +#define EXTRA_S decode.extra.s + +#define SET_SREG( _data_ ) (decode.src_is_local ? set_local_register(decode.src, (uint32_t)_data_) : set_global_register(decode.src, (uint32_t)_data_)) +#define SET_SREGF( _data_ ) (decode.src_is_local ? set_local_register(decode.src + 1, (uint32_t)_data_) : set_global_register(decode.src + 1, (uint32_t)_data_)) +#define SET_DREG( _data_ ) (decode.dst_is_local ? set_local_register(decode.dst, (uint32_t)_data_) : set_global_register(decode.dst, (uint32_t)_data_)) +#define SET_DREGF( _data_ ) (decode.dst_is_local ? set_local_register(decode.dst + 1, (uint32_t)_data_) : set_global_register(decode.dst + 1, (uint32_t)_data_)) + +#define SRC_IS_PC (!decode.src_is_local && decode.src == PC_REGISTER) +#define DST_IS_PC (!decode.dst_is_local && decode.dst == PC_REGISTER) +#define SRC_IS_SR (!decode.src_is_local && decode.src == SR_REGISTER) +#define DST_IS_SR (!decode.dst_is_local && decode.dst == SR_REGISTER) +#define SAME_SRC_DST decode.same_src_dst +#define SAME_SRC_DSTF decode.same_src_dstf +#define SAME_SRCF_DST decode.same_srcf_dst + + +#define OP m_op +#define PC m_global_regs[0] //Program Counter +#define SR m_global_regs[1] //Status Register +#define FER m_global_regs[2] //Floating-Point Exception Register +// 03 - 15 General Purpose Registers +// 16 - 17 Reserved +#define SP m_global_regs[18] //Stack Pointer +#define UB m_global_regs[19] //Upper Stack Bound +#define BCR m_global_regs[20] //Bus Control Register +#define TPR m_global_regs[21] //Timer Prescaler Register +#define TCR m_global_regs[22] //Timer Compare Register +#define TR compute_tr() //Timer Register +#define WCR m_global_regs[24] //Watchdog Compare Register +#define ISR m_global_regs[25] //Input Status Register +#define FCR m_global_regs[26] //Function Control Register +#define MCR m_global_regs[27] //Memory Control Register +// 28 - 31 Reserved + +#define C_MASK 0x00000001 +#define Z_MASK 0x00000002 +#define N_MASK 0x00000004 +#define V_MASK 0x00000008 +#define M_MASK 0x00000010 +#define H_MASK 0x00000020 +#define I_MASK 0x00000080 +#define L_MASK 0x00008000 +#define T_MASK 0x00010000 +#define P_MASK 0x00020000 +#define S_MASK 0x00040000 + +/* SR flags */ +#define GET_C ( SR & C_MASK) // bit 0 //CARRY +#define GET_Z ((SR & Z_MASK)>>1) // bit 1 //ZERO +#define GET_N ((SR & N_MASK)>>2) // bit 2 //NEGATIVE +#define GET_V ((SR & V_MASK)>>3) // bit 3 //OVERFLOW +#define GET_M ((SR & M_MASK)>>4) // bit 4 //CACHE-MODE +#define GET_H ((SR & H_MASK)>>5) // bit 5 //HIGHGLOBAL +// bit 6 RESERVED (always 0) +#define GET_I ((SR & I_MASK)>>7) // bit 7 //INTERRUPT-MODE +#define GET_FTE ((SR & 0x00001f00)>>8) // bits 12 - 8 //Floating-Point Trap Enable +#define GET_FRM ((SR & 0x00006000)>>13) // bits 14 - 13 //Floating-Point Rounding Mode +#define GET_L ((SR & L_MASK)>>15) // bit 15 //INTERRUPT-LOCK +#define GET_T ((SR & T_MASK)>>16) // bit 16 //TRACE-MODE +#define GET_P ((SR & P_MASK)>>17) // bit 17 //TRACE PENDING +#define GET_S ((SR & S_MASK)>>18) // bit 18 //SUPERVISOR STATE +#define GET_ILC ((SR & 0x00180000)>>19) // bits 20 - 19 //INSTRUCTION-LENGTH +/* if FL is zero it is always interpreted as 16 */ +#define GET_FL m_fl_lut[((SR >> 21) & 0xf)] // bits 24 - 21 //FRAME LENGTH +#define GET_FP ((SR & 0xfe000000)>>25) // bits 31 - 25 //FRAME POINTER + +#define SET_C(val) (SR = (SR & ~C_MASK) | (val)) +#define SET_Z(val) (SR = (SR & ~Z_MASK) | ((val) << 1)) +#define SET_N(val) (SR = (SR & ~N_MASK) | ((val) << 2)) +#define SET_V(val) (SR = (SR & ~V_MASK) | ((val) << 3)) +#define SET_M(val) (SR = (SR & ~M_MASK) | ((val) << 4)) +#define SET_H(val) (SR = (SR & ~H_MASK) | ((val) << 5)) +#define SET_I(val) (SR = (SR & ~I_MASK) | ((val) << 7)) +#define SET_FTE(val) (SR = (SR & ~0x00001f00) | ((val) << 8)) +#define SET_FRM(val) (SR = (SR & ~0x00006000) | ((val) << 13)) +#define SET_L(val) (SR = (SR & ~L_MASK) | ((val) << 15)) +#define SET_T(val) (SR = (SR & ~T_MASK) | ((val) << 16)) +#define SET_P(val) (SR = (SR & ~P_MASK) | ((val) << 17)) +#define SET_S(val) (SR = (SR & ~S_MASK) | ((val) << 18)) +#define SET_ILC(val) (SR = (SR & 0xffe7ffff) | (val)) +#define SET_FL(val) (SR = (SR & ~0x01e00000) | ((val) << 21)) +#define SET_FP(val) (SR = (SR & ~0xfe000000) | ((val) << 25)) + +#define SET_PC(val) PC = ((val) & 0xfffffffe) //PC(0) = 0 +#define SET_SP(val) SP = ((val) & 0xfffffffc) //SP(0) = SP(1) = 0 +#define SET_UB(val) UB = ((val) & 0xfffffffc) //UB(0) = UB(1) = 0 + +#define SET_LOW_SR(val) (SR = (SR & 0xffff0000) | ((val) & 0x0000ffff)) // when SR is addressed, only low 16 bits can be changed + + +#define CHECK_C(x) (SR = (SR & ~0x00000001) | (uint32_t)((x & 0x100000000L) >> 32)) +#define CHECK_VADD(x,y,z) (SR = (SR & ~0x00000008) | ((((x) ^ (z)) & ((y) ^ (z)) & 0x80000000) >> 29)) +#define CHECK_VADD3(x,y,w,z) (SR = (SR & ~0x00000008) | ((((x) ^ (z)) & ((y) ^ (z)) & ((w) ^ (z)) & 0x80000000) >> 29)) +#define CHECK_VSUB(x,y,z) (SR = (SR & ~0x00000008) | (((z ^ y) & (y ^ x) & 0x80000000) >> 29)) + + +/* FER flags */ +#define GET_ACCRUED (FER & 0x0000001f) //bits 4 - 0 //Floating-Point Accrued Exceptions +#define GET_ACTUAL (FER & 0x00001f00) //bits 12 - 8 //Floating-Point Actual Exceptions +//other bits are reversed, in particular 7 - 5 for the operating system. +//the user program can only changes the above 2 flags + + #endif // MAME_CPU_E132XS_XS32DEFS_H + diff --git a/src/devices/cpu/e132xs/e132xs.cpp b/src/devices/cpu/e132xs/e132xs.cpp index bfd8de0fc9a..73725ec8a25 100644 --- a/src/devices/cpu/e132xs/e132xs.cpp +++ b/src/devices/cpu/e132xs/e132xs.cpp @@ -32,7 +32,7 @@ TODO: - some wrong cycle counts - + - verify register wrapping with sregf/dregf on hardware CHANGELOG: Pierpaolo Prazzoli @@ -101,10 +101,6 @@ Pierpaolo Prazzoli - Same fix in get_const - Ryan Holtz - 02/27/04 - - Fixed delayed branching - - const_val for CALL should always have bit 0 clear - Pierpaolo Prazzoli - 02/25/04 - Fixed some wrong addresses to address local registers instead of memory - Fixed FRAME and RET instruction @@ -133,84 +129,16 @@ (From the doc: A Call, Trap or Software instruction increments the FP and sets FL to 6, thus creating a new stack frame with the length of 6 registers). - Ryan Holtz - 10/25/03 - - Fixed CALL enough that it at least jumps to the right address, no word - yet as to whether or not it's working enough to return. - - Added get_lrconst() to get the const value for the CALL operand, since - apparently using immediate_value() was wrong. The code is ugly, but it - works properly. Vampire 1/2 now gets far enough to try to test its RAM. - - Just from looking at it, CALL apparently doesn't frame properly. I'm not - sure about FRAME, but perhaps it doesn't work properly - I'm not entirely - positive. The return address when vamphalf's memory check routine is - called at FFFFFD7E is stored in register L8, and then the RET instruction - at the end of the routine uses L1 as the return address, so that might - provide some clues as to how it works. - - I'd almost be willing to bet money that there's no framing at all since - the values in L0 - L15 as displayed by the debugger would change during a - CALL or FRAME operation. I'll look when I'm in the mood. - - The mood struck me, and I took a look at SET_L_REG and GET_L_REG. - Apparently no matter what the current frame pointer is they'll always use - local_regs[0] through local_regs[15]. - - Ryan Holtz - 08/20/03 - - Added H flag support for MOV and MOVI - - Changed init routine to set S flag on boot. Apparently the CPU defaults to - supervisor mode as opposed to user mode when it powers on, as shown by the - vamphalf power-on routines. Makes sense, too, since if the machine booted - in user mode, it would be impossible to get into supervisor mode. - Pierpaolo Prazzoli - 08/19/03 - Added check for D_BIT and S_BIT where PC or SR must or must not be denoted. (movd, divu, divs, ldxx1, ldxx2, stxx1, stxx2, mulu, muls, set, mul call, chk) - Ryan Holtz - 08/17/03 - - Working on support for H flag, nothing quite done yet - - Added trap Range Error for CHK PC, PC - - Fixed relative jumps, they have to be taken from the opcode following the - jump instead of the jump opcode itself. - Pierpaolo Prazzoli - 08/17/03 - Fixed get_pcrel() when OP & 0x80 is set. - Decremented PC by 2 also in MOV, ADD, ADDI, SUM, SUB and added the check if D_BIT is not set. (when pc is changed they are implicit branch) - Ryan Holtz - 08/17/03 - - Implemented a crude hack to set FL in the SR to 6, since according to the docs - that's supposed to happen each time a trap occurs, apparently including when - the processor starts up. The 3rd opcode executed in vamphalf checks to see if - the FL flag in SR 6, so it's apparently the "correct" behaviour despite the - docs not saying anything on it. If FL is not 6, the branch falls through and - encounters a CHK PC, L2, which at that point will always throw a range trap. - The range trap vector contains 00000000 (CHK PC, PC), which according to the - docs will always throw a range trap (which would effectively lock the system). - This revealed a bug: CHK PC, PC apparently does not throw a range trap, which - needs to be fixed. Now that the "correct" behaviour is hacked in with the FL - flags, it reveals yet another bug in that the branch is interpreted as being - +0x8700. This means that the PC then wraps around to 000082B0, give or take - a few bytes. While it does indeed branch to valid code, I highly doubt that - this is the desired effect. Check for signed/unsigned relative branch, maybe? - - Ryan Holtz - 08/16/03 - - Fixed the debugger at least somewhat so that it displays hex instead of decimal, - and so that it disassembles opcodes properly. - - Fixed hyperstone_execute() to increment PC *after* executing the opcode instead of - before. This is probably why vamphalf was booting to fffffff8, but executing at - fffffffa instead. - - Changed execute_trap to decrement PC by 2 so that the next opcode isn't skipped - after a trap - - Changed execute_br to decrement PC by 2 so that the next opcode isn't skipped - after a branch - - Changed hyperstone_movi to decrement PC by 2 when G0 (PC) is modified so that the - next opcode isn't skipped after a branch - - Changed hyperstone_movi to default to a uint32_t being moved into the register - as opposed to a uint8_t. This is wrong, the bit width is quite likely to be - dependent on the n field in the Rimm instruction type. However, vamphalf uses - MOVI G0,[FFFF]FBAC (n=$13) since there's apparently no absolute branch opcode. - What kind of CPU is this that it doesn't have an absolute jump in its branch - instructions and you have to use an immediate MOV to do an abs. jump!? - - Replaced usage of logerror() with smf's verboselog() - *********************************************************************/ #include "emu.h" @@ -219,91 +147,10 @@ #include "debugger.h" #include "32xsdefs.h" +#include "32xsdasm.h" -#ifdef MAME_DEBUG -#define DEBUG_PRINTF(x) do { osd_printf_debug x; } while (0) -#else -#define DEBUG_PRINTF(x) do { } while (0) -#endif - -/* Memory access */ -/* read byte */ -#define READ_B(addr) m_program->read_byte((addr)) -/* read half-word */ -#define READ_HW(addr) m_program->read_word((addr) & ~1) -/* read word */ -#define READ_W(addr) m_program->read_dword((addr) & ~3) - -/* write byte */ -#define WRITE_B(addr, data) m_program->write_byte(addr, data) -/* write half-word */ -#define WRITE_HW(addr, data) m_program->write_word((addr) & ~1, data) -/* write word */ -#define WRITE_W(addr, data) m_program->write_dword((addr) & ~3, data) - - -/* I/O access */ -/* read word */ -#define IO_READ_W(addr) m_io->read_dword(((addr) >> 11) & 0x7ffc) -/* write word */ -#define IO_WRITE_W(addr, data) m_io->write_dword(((addr) >> 11) & 0x7ffc, data) - - -#define READ_OP(addr) m_direct->read_word((addr), m_opcodexor) - -// set C in adds/addsi/subs/sums -#define SETCARRYS 0 -#define MISSIONCRAFT_FLAGS 1 - -/* Registers */ - -/* Internal registers */ - -#define SREG (decode)->src_value -#define SREGF (decode)->next_src_value -#define DREG (decode)->dst_value -#define DREGF (decode)->next_dst_value -#define EXTRA_U (decode)->extra.u -#define EXTRA_S (decode)->extra.s - -#define SET_SREG( _data_ ) ((decode)->src_is_local ? set_local_register((decode)->src, (uint32_t)_data_) : set_global_register((decode)->src, (uint32_t)_data_)) -#define SET_SREGF( _data_ ) ((decode)->src_is_local ? set_local_register((decode)->src + 1, (uint32_t)_data_) : set_global_register((decode)->src + 1, (uint32_t)_data_)) -#define SET_DREG( _data_ ) ((decode)->dst_is_local ? set_local_register((decode)->dst, (uint32_t)_data_) : set_global_register((decode)->dst, (uint32_t)_data_)) -#define SET_DREGF( _data_ ) ((decode)->dst_is_local ? set_local_register((decode)->dst + 1, (uint32_t)_data_) : set_global_register((decode)->dst + 1, (uint32_t)_data_)) - -#define SRC_IS_PC (!(decode)->src_is_local && (decode)->src == PC_REGISTER) -#define DST_IS_PC (!(decode)->dst_is_local && (decode)->dst == PC_REGISTER) -#define SRC_IS_SR (!(decode)->src_is_local && (decode)->src == SR_REGISTER) -#define DST_IS_SR (!(decode)->dst_is_local && (decode)->dst == SR_REGISTER) -#define SAME_SRC_DST (decode)->same_src_dst -#define SAME_SRC_DSTF (decode)->same_src_dstf -#define SAME_SRCF_DST (decode)->same_srcf_dst - - -/* Memory access */ -/* read byte */ -#define READ_B(addr) m_program->read_byte((addr)) -/* read half-word */ -#define READ_HW(addr) m_program->read_word((addr) & ~1) -/* read word */ -#define READ_W(addr) m_program->read_dword((addr) & ~3) - -/* write byte */ -#define WRITE_B(addr, data) m_program->write_byte(addr, data) -/* write half-word */ -#define WRITE_HW(addr, data) m_program->write_word((addr) & ~1, data) -/* write word */ -#define WRITE_W(addr, data) m_program->write_dword((addr) & ~3, data) - - -/* I/O access */ -/* read word */ -#define IO_READ_W(addr) m_io->read_dword(((addr) >> 11) & 0x7ffc) -/* write word */ -#define IO_WRITE_W(addr, data) m_io->write_dword(((addr) >> 11) & 0x7ffc, data) - - -#define READ_OP(addr) m_direct->read_word((addr), m_opcodexor) +//#define VERBOSE 1 +#include "logmacro.h" //************************************************************************** // INTERNAL ADDRESS MAP @@ -353,9 +200,6 @@ hyperstone_device::hyperstone_device(const machine_config &mconfig, const char * m_io_config("io", ENDIANNESS_BIG, io_data_width, 15), m_icount(0) { - // build the opcode table - for (int op = 0; op < 256; op++) - m_opcode[op] = s_opcodetable[op]; } @@ -555,87 +399,11 @@ void hyperstone_device::hyperstone_set_trap_entry(int which) break; default: - DEBUG_PRINTF(("Set entry point to a reserved value: %d\n", which)); + LOG("Set entry point to a reserved value: %d\n", which); break; } } -#define OP m_op -#define PPC m_ppc //previous pc -#define PC m_global_regs[0] //Program Counter -#define SR m_global_regs[1] //Status Register -#define FER m_global_regs[2] //Floating-Point Exception Register -// 03 - 15 General Purpose Registers -// 16 - 17 Reserved -#define SP m_global_regs[18] //Stack Pointer -#define UB m_global_regs[19] //Upper Stack Bound -#define BCR m_global_regs[20] //Bus Control Register -#define TPR m_global_regs[21] //Timer Prescaler Register -#define TCR m_global_regs[22] //Timer Compare Register -#define TR compute_tr() //Timer Register -#define WCR m_global_regs[24] //Watchdog Compare Register -#define ISR m_global_regs[25] //Input Status Register -#define FCR m_global_regs[26] //Function Control Register -#define MCR m_global_regs[27] //Memory Control Register -// 28 - 31 Reserved - -/* SR flags */ -#define GET_C ( SR & 0x00000001) // bit 0 //CARRY -#define GET_Z ((SR & 0x00000002)>>1) // bit 1 //ZERO -#define GET_N ((SR & 0x00000004)>>2) // bit 2 //NEGATIVE -#define GET_V ((SR & 0x00000008)>>3) // bit 3 //OVERFLOW -#define GET_M ((SR & 0x00000010)>>4) // bit 4 //CACHE-MODE -#define GET_H ((SR & 0x00000020)>>5) // bit 5 //HIGHGLOBAL -// bit 6 RESERVED (always 0) -#define GET_I ((SR & 0x00000080)>>7) // bit 7 //INTERRUPT-MODE -#define GET_FTE ((SR & 0x00001f00)>>8) // bits 12 - 8 //Floating-Point Trap Enable -#define GET_FRM ((SR & 0x00006000)>>13) // bits 14 - 13 //Floating-Point Rounding Mode -#define GET_L ((SR & 0x00008000)>>15) // bit 15 //INTERRUPT-LOCK -#define GET_T ((SR & 0x00010000)>>16) // bit 16 //TRACE-MODE -#define GET_P ((SR & 0x00020000)>>17) // bit 17 //TRACE PENDING -#define GET_S ((SR & 0x00040000)>>18) // bit 18 //SUPERVISOR STATE -#define GET_ILC ((SR & 0x00180000)>>19) // bits 20 - 19 //INSTRUCTION-LENGTH -/* if FL is zero it is always interpreted as 16 */ -#define GET_FL ((SR & 0x01e00000) ? ((SR & 0x01e00000)>>21) : 16) // bits 24 - 21 //FRAME LENGTH -#define GET_FP ((SR & 0xfe000000)>>25) // bits 31 - 25 //FRAME POINTER - -#define SET_C(val) (SR = (SR & ~0x00000001) | (val)) -#define SET_Z(val) (SR = (SR & ~0x00000002) | ((val) << 1)) -#define SET_N(val) (SR = (SR & ~0x00000004) | ((val) << 2)) -#define SET_V(val) (SR = (SR & ~0x00000008) | ((val) << 3)) -#define SET_M(val) (SR = (SR & ~0x00000010) | ((val) << 4)) -#define SET_H(val) (SR = (SR & ~0x00000020) | ((val) << 5)) -#define SET_I(val) (SR = (SR & ~0x00000080) | ((val) << 7)) -#define SET_FTE(val) (SR = (SR & ~0x00001f00) | ((val) << 8)) -#define SET_FRM(val) (SR = (SR & ~0x00006000) | ((val) << 13)) -#define SET_L(val) (SR = (SR & ~0x00008000) | ((val) << 15)) -#define SET_T(val) (SR = (SR & ~0x00010000) | ((val) << 16)) -#define SET_P(val) (SR = (SR & ~0x00020000) | ((val) << 17)) -#define SET_S(val) (SR = (SR & ~0x00040000) | ((val) << 18)) -#define SET_ILC(val) (SR = (SR & ~0x00180000) | ((val) << 19)) -#define SET_FL(val) (SR = (SR & ~0x01e00000) | ((val) << 21)) -#define SET_FP(val) (SR = (SR & ~0xfe000000) | ((val) << 25)) - -#define SET_PC(val) PC = ((val) & 0xfffffffe) //PC(0) = 0 -#define SET_SP(val) SP = ((val) & 0xfffffffc) //SP(0) = SP(1) = 0 -#define SET_UB(val) UB = ((val) & 0xfffffffc) //UB(0) = UB(1) = 0 - -#define SET_LOW_SR(val) (SR = (SR & 0xffff0000) | ((val) & 0x0000ffff)) // when SR is addressed, only low 16 bits can be changed - - -#define CHECK_C(x) (SR = (SR & ~0x00000001) | (((x) & (((uint64_t)1) << 32)) ? 1 : 0 )) -#define CHECK_VADD(x,y,z) (SR = (SR & ~0x00000008) | ((((x) ^ (z)) & ((y) ^ (z)) & 0x80000000) ? 8: 0)) -#define CHECK_VADD3(x,y,w,z) (SR = (SR & ~0x00000008) | ((((x) ^ (z)) & ((y) ^ (z)) & ((w) ^ (z)) & 0x80000000) ? 8: 0)) -#define CHECK_VSUB(x,y,z) (SR = (SR & ~0x00000008) | ((((z) ^ (y)) & ((y) ^ (x)) & 0x80000000) ? 8: 0)) - - -/* FER flags */ -#define GET_ACCRUED (FER & 0x0000001f) //bits 4 - 0 //Floating-Point Accrued Exceptions -#define GET_ACTUAL (FER & 0x00001f00) //bits 12 - 8 //Floating-Point Actual Exceptions -//other bits are reversed, in particular 7 - 5 for the operating system. -//the user program can only changes the above 2 flags - - uint32_t hyperstone_device::compute_tr() { uint64_t cycles_since_base = total_cycles() - m_tr_base_cycles; @@ -650,6 +418,7 @@ void hyperstone_device::update_timer_prescale() m_clck_scale = (TPR >> 26) & m_clock_scale_mask; m_clock_cycles_1 = 1 << m_clck_scale; m_clock_cycles_2 = 2 << m_clck_scale; + m_clock_cycles_3 = 3 << m_clck_scale; m_clock_cycles_4 = 4 << m_clck_scale; m_clock_cycles_6 = 6 << m_clck_scale; m_tr_clocks_per_tick = ((TPR >> 16) & 0xff) + 2; @@ -730,23 +499,23 @@ uint32_t hyperstone_device::get_global_register(uint8_t code) case 29: case 30: case 31: - DEBUG_PRINTF(("read _Reserved_ Global Register %d @ %08X\n",code,PC)); + LOG("read _Reserved_ Global Register %d @ %08X\n",code,PC); break; case BCR_REGISTER: - DEBUG_PRINTF(("read write-only BCR register @ %08X\n",PC)); + LOG("read write-only BCR register @ %08X\n",PC); return 0; case TPR_REGISTER: - DEBUG_PRINTF(("read write-only TPR register @ %08X\n",PC)); + LOG("read write-only TPR register @ %08X\n",PC); return 0; case FCR_REGISTER: - DEBUG_PRINTF(("read write-only FCR register @ %08X\n",PC)); + LOG("read write-only FCR register @ %08X\n",PC); return 0; case MCR_REGISTER: - DEBUG_PRINTF(("read write-only MCR register @ %08X\n",PC)); + LOG("read write-only MCR register @ %08X\n",PC); return 0; } } @@ -758,585 +527,253 @@ uint32_t hyperstone_device::get_global_register(uint8_t code) m_icount -= m_tr_clocks_per_tick / 2; return compute_tr(); } - return m_global_regs[code]; + return m_global_regs[code & 0x1f]; } void hyperstone_device::set_local_register(uint8_t code, uint32_t val) { - uint8_t new_code = (code + GET_FP) % 64; - - m_local_regs[new_code] = val; + m_local_regs[(code + GET_FP) & 0x3f] = val; } void hyperstone_device::set_global_register(uint8_t code, uint32_t val) { //TODO: add correct FER set instruction - - if( code == PC_REGISTER ) - { - SET_PC(val); - } - else if( code == SR_REGISTER ) - { - SET_LOW_SR(val); // only a RET instruction can change the full content of SR - SR &= ~0x40; //reserved bit 6 always zero - if (m_intblock < 1) - m_intblock = 1; - } - else - { - uint32_t oldval = m_global_regs[code]; - if( code != ISR_REGISTER ) + code &= 0x1f; + switch (code) + { + case PC_REGISTER: + SET_PC(val); + return; + case SR_REGISTER: + SET_LOW_SR(val); // only a RET instruction can change the full content of SR + SR &= ~0x40; //reserved bit 6 always zero + if (m_intblock < 1) + m_intblock = 1; + return; + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + // are the below ones set only when privilege bit is set? + case 17: m_global_regs[code] = val; - else - DEBUG_PRINTF(("Written to ISR register. PC = %08X\n", PC)); - - //are these set only when privilege bit is set? - if( code >= 16 ) - { - switch( code ) + return; + case SP_REGISTER: + case UB_REGISTER: + m_global_regs[code] = val & ~3; + return; + case BCR_REGISTER: + m_global_regs[code] = val; + return; + case TPR_REGISTER: + m_global_regs[code] = val; + if (!(val & 0x80000000)) /* change immediately */ + update_timer_prescale(); + adjust_timer_interrupt(); + return; + case TCR_REGISTER: + if (m_global_regs[code] != val) { - case 18: - SET_SP(val); - break; - - case 19: - SET_UB(val); - break; -/* - case ISR_REGISTER: - DEBUG_PRINTF(("written %08X to read-only ISR register\n",val)); - break; - - case TCR_REGISTER: -// DEBUG_PRINTF(("written %08X to TCR register\n",val)); - break; - - case 23: -// DEBUG_PRINTF(("written %08X to TR register\n",val)); - break; - - case 24: -// DEBUG_PRINTF(("written %08X to WCR register\n",val)); - break; - - case 16: - case 17: - case 28: - case 29: - case 30: - case 31: - DEBUG_PRINTF(("written %08X to _Reserved_ Global Register %d\n",val,code)); - break; - - case BCR_REGISTER: - break; -*/ - case TR_REGISTER: - m_tr_base_value = val; - m_tr_base_cycles = total_cycles(); - adjust_timer_interrupt(); - break; - - case TPR_REGISTER: - if (!(val & 0x80000000)) /* change immediately */ - update_timer_prescale(); + m_global_regs[code] = val; adjust_timer_interrupt(); - break; - - case TCR_REGISTER: - if (oldval != val) - { - adjust_timer_interrupt(); - if (m_intblock < 1) - m_intblock = 1; - } - break; - - case FCR_REGISTER: - if ((oldval ^ val) & 0x00800000) - adjust_timer_interrupt(); if (m_intblock < 1) m_intblock = 1; - break; - - case MCR_REGISTER: - // bits 14..12 EntryTableMap - hyperstone_set_trap_entry((val & 0x7000) >> 12); - break; } - } + return; + case TR_REGISTER: + m_global_regs[code] = val; + m_tr_base_value = val; + m_tr_base_cycles = total_cycles(); + adjust_timer_interrupt(); + return; + case WCR_REGISTER: + m_global_regs[code] = val; + return; + case ISR_REGISTER: + return; + case FCR_REGISTER: + if ((m_global_regs[code] ^ val) & 0x00800000) + adjust_timer_interrupt(); + m_global_regs[code] = val; + if (m_intblock < 1) + m_intblock = 1; + return; + case MCR_REGISTER: + // bits 14..12 EntryTableMap + hyperstone_set_trap_entry((val & 0x7000) >> 12); + m_global_regs[code] = val; + return; + case 28: + case 29: + case 30: + case 31: + m_global_regs[code] = val; + return; } } -#define GET_ABS_L_REG(code) m_local_regs[code] -#define SET_L_REG(code, val) set_local_register(code, val) -#define SET_ABS_L_REG(code, val) m_local_regs[code] = val -#define GET_G_REG(code) get_global_register(code) -#define SET_G_REG(code, val) set_global_register(code, val) - #define S_BIT ((OP & 0x100) >> 8) -#define N_BIT S_BIT #define D_BIT ((OP & 0x200) >> 9) -#define N_VALUE ((N_BIT << 4) | (OP & 0x0f)) +#define N_VALUE (((OP & 0x100) >> 4) | (OP & 0x0f)) +#define HI_N_VALUE (0x10 | (OP & 0x0f)) +#define LO_N_VALUE (OP & 0x0f) +#define N_OP_MASK (m_op & 0x10f) #define DST_CODE ((OP & 0xf0) >> 4) #define SRC_CODE (OP & 0x0f) #define SIGN_BIT(val) ((val & 0x80000000) >> 31) +#define SIGN_TO_N(val) ((val & 0x80000000) >> 29) -#define LOCAL 1 - -static const int32_t immediate_values[32] = +static constexpr int32_t immediate_values[32] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 0, 0, 0, 32, 64, 128, static_cast<int32_t>(0x80000000), + 16, 0, 0, 0, 32, 64, 128, int32_t(0x80000000), -8, -7, -6, -5, -4, -3, -2, -1 }; -#define WRITE_ONLY_REGMASK ((1 << BCR_REGISTER) | (1 << TPR_REGISTER) | (1 << FCR_REGISTER) | (1 << MCR_REGISTER)) - -#define decode_source(decode, local, hflag) \ -do \ -{ \ - if(local) \ - { \ - uint8_t code = (decode)->src; \ - (decode)->src_is_local = 1; \ - code = ((decode)->src + GET_FP) % 64; /* registers offset by frame pointer */\ - SREG = m_local_regs[code]; \ - code = ((decode)->src + 1 + GET_FP) % 64; \ - SREGF = m_local_regs[code]; \ - } \ - else \ - { \ - (decode)->src_is_local = 0; \ - \ - if (!hflag) \ - { \ - SREG = get_global_register((decode)->src); \ - \ - /* bound safe */ \ - if ((decode)->src != 15) \ - SREGF = get_global_register((decode)->src + 1); \ - } \ - else \ - { \ - (decode)->src += 16; \ - \ - SREG = get_global_register((decode)->src); \ - if ((WRITE_ONLY_REGMASK >> (decode)->src) & 1) \ - SREG = 0; /* write-only registers */ \ - else if ((decode)->src == ISR_REGISTER) \ - DEBUG_PRINTF(("read src ISR. PC = %08X\n",PPC)); \ - \ - /* bound safe */ \ - if ((decode)->src != 31) \ - SREGF = get_global_register((decode)->src + 1); \ - } \ - } \ -} while (0) - -#define decode_dest(decode, local, hflag) \ -do \ -{ \ - if(local) \ - { \ - uint8_t code = (decode)->dst; \ - (decode)->dst_is_local = 1; \ - code = ((decode)->dst + GET_FP) % 64; /* registers offset by frame pointer */\ - DREG = m_local_regs[code]; \ - code = ((decode)->dst + 1 + GET_FP) % 64; \ - DREGF = m_local_regs[code]; \ - } \ - else \ - { \ - (decode)->dst_is_local = 0; \ - \ - if (!hflag) \ - { \ - DREG = get_global_register((decode)->dst); \ - \ - /* bound safe */ \ - if ((decode)->dst != 15) \ - DREGF = get_global_register((decode)->dst + 1); \ - } \ - else \ - { \ - (decode)->dst += 16; \ - \ - DREG = get_global_register((decode)->dst); \ - if( (decode)->dst == ISR_REGISTER ) \ - DEBUG_PRINTF(("read dst ISR. PC = %08X\n",PPC)); \ - \ - /* bound safe */ \ - if ((decode)->dst != 31) \ - DREGF = get_global_register((decode)->dst + 1); \ - } \ - } \ -} while (0) - -#define decode_RR(decode, dlocal, slocal) \ -do \ -{ \ - (decode)->src = SRC_CODE; \ - (decode)->dst = DST_CODE; \ - decode_source(decode, slocal, 0); \ - decode_dest(decode, dlocal, 0); \ - \ - if( (slocal) == (dlocal) && SRC_CODE == DST_CODE ) \ - SAME_SRC_DST = 1; \ - \ - if( (slocal) == LOCAL && (dlocal) == LOCAL ) \ - { \ - if( SRC_CODE == ((DST_CODE + 1) % 64) ) \ - SAME_SRC_DSTF = 1; \ - \ - if( ((SRC_CODE + 1) % 64) == DST_CODE ) \ - SAME_SRCF_DST = 1; \ - } \ - else if( (slocal) == 0 && (dlocal) == 0 ) \ - { \ - if( SRC_CODE == (DST_CODE + 1) ) \ - SAME_SRC_DSTF = 1; \ - \ - if( (SRC_CODE + 1) == DST_CODE ) \ - SAME_SRCF_DST = 1; \ - } \ -} while (0) - -#define decode_LL(decode) \ -do \ -{ \ - (decode)->src = SRC_CODE; \ - (decode)->dst = DST_CODE; \ - decode_source(decode, LOCAL, 0); \ - decode_dest(decode, LOCAL, 0); \ - \ - if( SRC_CODE == DST_CODE ) \ - SAME_SRC_DST = 1; \ - \ - if( SRC_CODE == ((DST_CODE + 1) % 64) ) \ - SAME_SRC_DSTF = 1; \ -} while (0) - -#define decode_LR(decode, slocal) \ -do \ -{ \ - (decode)->src = SRC_CODE; \ - (decode)->dst = DST_CODE; \ - decode_source(decode, slocal, 0); \ - decode_dest(decode, LOCAL, 0); \ - \ - if( ((SRC_CODE + 1) % 64) == DST_CODE && slocal == LOCAL ) \ - SAME_SRCF_DST = 1; \ -} while (0) +constexpr uint32_t WRITE_ONLY_REGMASK = (1 << BCR_REGISTER) | (1 << TPR_REGISTER) | (1 << FCR_REGISTER) | (1 << MCR_REGISTER); #define check_delay_PC() \ do \ { \ /* if PC is used in a delay instruction, the delayed PC should be used */ \ - if( m_delay.delay_cmd == DELAY_EXECUTE ) \ + if (m_delay_slot) \ { \ - PC = m_delay.delay_pc; \ - m_delay.delay_cmd = NO_DELAY; \ + PC = m_delay_pc; \ + m_delay_slot = false; \ } \ } while (0) -#define decode_immediate(decode, nbit) \ -do \ -{ \ - if (!nbit) \ - EXTRA_U = immediate_values[OP & 0x0f]; \ - else \ - switch( OP & 0x0f ) \ - { \ - default: \ - EXTRA_U = immediate_values[0x10 + (OP & 0x0f)]; \ - break; \ - \ - case 1: \ - m_instruction_length = 3; \ - EXTRA_U = (READ_OP(PC) << 16) | READ_OP(PC + 2); \ - PC += 4; \ - break; \ - \ - case 2: \ - m_instruction_length = 2; \ - EXTRA_U = READ_OP(PC); \ - PC += 2; \ - break; \ - \ - case 3: \ - m_instruction_length = 2; \ - EXTRA_U = 0xffff0000 | READ_OP(PC); \ - PC += 2; \ - break; \ - } \ -} while (0) - -#define decode_const(decode) \ -do \ -{ \ - uint16_t imm_1 = READ_OP(PC); \ - \ - PC += 2; \ - m_instruction_length = 2; \ - \ - if( E_BIT(imm_1) ) \ - { \ - uint16_t imm_2 = READ_OP(PC); \ - \ - PC += 2; \ - m_instruction_length = 3; \ - \ - EXTRA_S = imm_2; \ - EXTRA_S |= ((imm_1 & 0x3fff) << 16); \ - \ - if( S_BIT_CONST(imm_1) ) \ - { \ - EXTRA_S |= 0xc0000000; \ - } \ - } \ - else \ - { \ - EXTRA_S = imm_1 & 0x3fff; \ - \ - if( S_BIT_CONST(imm_1) ) \ - { \ - EXTRA_S |= 0xffffc000; \ - } \ - } \ -} while (0) - -#define decode_pcrel(decode) \ -do \ -{ \ - if( OP & 0x80 ) \ - { \ - uint16_t next = READ_OP(PC); \ - \ - PC += 2; \ - m_instruction_length = 2; \ - \ - EXTRA_S = (OP & 0x7f) << 16; \ - EXTRA_S |= (next & 0xfffe); \ - \ - if( next & 1 ) \ - EXTRA_S |= 0xff800000; \ - } \ - else \ - { \ - EXTRA_S = OP & 0x7e; \ - \ - if( OP & 1 ) \ - EXTRA_S |= 0xffffff80; \ - } \ -} while (0) - -#define decode_dis(decode) \ -do \ -{ \ - uint16_t next_1 = READ_OP(PC); \ - \ - PC += 2; \ - m_instruction_length = 2; \ - \ - (decode)->sub_type = DD(next_1); \ - \ - if( E_BIT(next_1) ) \ - { \ - uint16_t next_2 = READ_OP(PC); \ - \ - PC += 2; \ - m_instruction_length = 3; \ - \ - EXTRA_S = next_2; \ - EXTRA_S |= ((next_1 & 0xfff) << 16); \ - \ - if( S_BIT_CONST(next_1) ) \ - { \ - EXTRA_S |= 0xf0000000; \ - } \ - } \ - else \ - { \ - EXTRA_S = next_1 & 0xfff; \ - \ - if( S_BIT_CONST(next_1) ) \ - { \ - EXTRA_S |= 0xfffff000; \ - } \ - } \ -} while (0) - -#define decode_lim(decode) \ -do \ -{ \ - uint32_t next = READ_OP(PC); \ - PC += 2; \ - m_instruction_length = 2; \ - \ - (decode)->sub_type = X_CODE(next); \ - \ - if( E_BIT(next) ) \ - { \ - EXTRA_U = ((next & 0xfff) << 16) | READ_OP(PC); \ - PC += 2; \ - m_instruction_length = 3; \ - } \ - else \ - { \ - EXTRA_U = next & 0xfff; \ - } \ -} while (0) - -#define RRdecode(decode, dlocal, slocal) \ -do \ -{ \ - check_delay_PC(); \ - decode_RR(decode, dlocal, slocal); \ -} while (0) - -#define RRlimdecode(decode, dlocal, slocal) \ -do \ -{ \ - decode_lim(decode); \ - check_delay_PC(); \ - decode_RR(decode, dlocal, slocal); \ -} while (0) +void hyperstone_device::ignore_immediate_s() +{ + static const uint32_t lengths[16] = { 1<<19, 3<<19, 2<<19, 2<<19, 1<<19, 1<<19, 1<<19, 1<<19, 1<<19, 1<<19, 1<<19, 1<<19, 1<<19, 1<<19, 1<<19, 1<<19 }; + static const uint32_t offsets[16] = { 0, 4, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + const uint8_t nybble = m_op & 0x0f; + m_instruction_length = lengths[nybble]; + PC += offsets[nybble]; +} -#define RRconstdecode(decode, dlocal, slocal) \ -do \ -{ \ - decode_const(decode); \ - check_delay_PC(); \ - decode_RR(decode, dlocal, slocal); \ -} while (0) +uint32_t hyperstone_device::decode_immediate_s() +{ + const uint8_t nybble = m_op & 0x0f; + switch (nybble) + { + case 0: + default: + return immediate_values[0x10 + nybble]; + case 1: + { + m_instruction_length = (3<<19); + uint32_t extra_u = (READ_OP(PC) << 16) | READ_OP(PC + 2); + PC += 4; + return extra_u; + } + case 2: + { + m_instruction_length = (2<<19); + uint32_t extra_u = READ_OP(PC); + PC += 2; + return extra_u; + } + case 3: + { + m_instruction_length = (2<<19); + uint32_t extra_u = 0xffff0000 | READ_OP(PC); + PC += 2; + return extra_u; + } + } +} -#define RRdisdecode(decode, dlocal, slocal) \ -do \ -{ \ - decode_dis(decode); \ - check_delay_PC(); \ - decode_RR(decode, dlocal, slocal); \ -} while (0) +uint32_t hyperstone_device::decode_const() +{ + const uint16_t imm_1 = READ_OP(PC); -#define RRdecodewithHflag(decode, dlocal, slocal) \ -do \ -{ \ - check_delay_PC(); \ - (decode)->src = SRC_CODE; \ - (decode)->dst = DST_CODE; \ - decode_source(decode, slocal, GET_H); \ - decode_dest(decode, dlocal, GET_H); \ - \ - if(GET_H) \ - if(slocal == 0 && dlocal == 0) \ - DEBUG_PRINTF(("MOV with hflag and 2 GRegs! PC = %08X\n",PPC)); \ -} while (0) + PC += 2; + m_instruction_length = (2<<19); -#define Rimmdecode(decode, dlocal, nbit) \ -do \ -{ \ - decode_immediate(decode, nbit); \ - check_delay_PC(); \ - (decode)->dst = DST_CODE; \ - decode_dest(decode, dlocal, 0); \ -} while (0) + if (imm_1 & 0x8000) + { + const uint16_t imm_2 = READ_OP(PC); -#define Rndecode(decode, dlocal) \ -do \ -{ \ - check_delay_PC(); \ - (decode)->dst = DST_CODE; \ - decode_dest(decode, dlocal, 0); \ -} while (0) + PC += 2; + m_instruction_length = (3<<19); -#define RimmdecodewithHflag(decode, dlocal, nbit) \ -do \ -{ \ - decode_immediate(decode, nbit); \ - check_delay_PC(); \ - (decode)->dst = DST_CODE; \ - decode_dest(decode, dlocal, GET_H); \ -} while (0) + uint32_t imm = imm_2; + imm |= ((imm_1 & 0x3fff) << 16); -#define Lndecode(decode) \ -do \ -{ \ - check_delay_PC(); \ - (decode)->dst = DST_CODE; \ - decode_dest(decode, LOCAL, 0); \ -} while (0) + if (imm_1 & 0x4000) + imm |= 0xc0000000; + return imm; + } + else + { + uint32_t imm = imm_1 & 0x3fff; -#define LLdecode(decode) \ -do \ -{ \ - check_delay_PC(); \ - decode_LL(decode); \ -} while (0) + if (imm_1 & 0x4000) + imm |= 0xffffc000; + return imm; + } +} -#define LLextdecode(decode) \ -do \ -{ \ - m_instruction_length = 2; \ - EXTRA_U = READ_OP(PC); \ - PC += 2; \ - check_delay_PC(); \ - decode_LL(decode); \ -} while (0) +int32_t hyperstone_device::decode_pcrel() +{ + if (OP & 0x80) + { + uint16_t next = READ_OP(PC); -#define LRdecode(decode, slocal) \ -do \ -{ \ - check_delay_PC(); \ - decode_LR(decode, slocal); \ -} while (0) + PC += 2; + m_instruction_length = (2<<19); -#define LRconstdecode(decode, slocal) \ -do \ -{ \ - decode_const(decode); \ - check_delay_PC(); \ - decode_LR(decode, slocal); \ -} while (0) + int32_t offset = (OP & 0x7f) << 16; + offset |= (next & 0xfffe); -#define PCreldecode(decode) \ -do \ -{ \ - decode_pcrel(decode); \ - check_delay_PC(); \ -} while (0) + if (next & 1) + offset |= 0xff800000; -#define PCadrdecode(decode) \ -do \ -{ \ - check_delay_PC(); \ -} while (0) + return offset; + } + else + { + int32_t offset = OP & 0x7e; -#define no_decode(decode) \ -do \ -{ \ -} while (0) + if (OP & 1) + offset |= 0xffffff80; + return offset; + } +} -void hyperstone_device::execute_br(struct hyperstone_device::regs_decode *decode) +void hyperstone_device::ignore_pcrel() { - PPC = PC; - PC += EXTRA_S; - SET_M(0); - - m_icount -= m_clock_cycles_2; + if (m_op & 0x80) + { + PC += 2; + m_instruction_length = (2<<19); + } } -void hyperstone_device::execute_dbr(struct hyperstone_device::regs_decode *decode) +void hyperstone_device::execute_br() { - m_delay.delay_cmd = DELAY_EXECUTE; - m_delay.delay_pc = PC + EXTRA_S; + const int32_t offset = decode_pcrel(); + check_delay_PC(); - m_intblock = 3; -} + PC += offset; + SR &= ~M_MASK; + m_icount -= m_clock_cycles_2; +} void hyperstone_device::execute_trap(uint32_t addr) { @@ -1344,22 +781,21 @@ void hyperstone_device::execute_trap(uint32_t addr) uint32_t oldSR; reg = GET_FP + GET_FL; - SET_ILC(m_instruction_length & 3); + SET_ILC(m_instruction_length); oldSR = SR; SET_FL(6); SET_FP(reg); - SET_L_REG(0, (PC & 0xfffffffe) | GET_S); - SET_L_REG(1, oldSR); + set_local_register(0, (PC & 0xfffffffe) | GET_S); + set_local_register(1, oldSR); SET_M(0); SET_T(0); SET_L(1); SET_S(1); - PPC = PC; PC = addr; m_icount -= m_clock_cycles_2; @@ -1368,27 +804,19 @@ void hyperstone_device::execute_trap(uint32_t addr) void hyperstone_device::execute_int(uint32_t addr) { - uint8_t reg; - uint32_t oldSR; - reg = GET_FP + GET_FL; - - SET_ILC(m_instruction_length & 3); - - oldSR = SR; + const uint8_t reg = GET_FP + GET_FL; + SET_ILC(m_instruction_length); + const uint32_t oldSR = SR; SET_FL(2); SET_FP(reg); - SET_L_REG(0, (PC & 0xfffffffe) | GET_S); - SET_L_REG(1, oldSR); + m_local_regs[(0 + reg) & 0x3f] = (PC & ~1) | GET_S; + m_local_regs[(1 + reg) & 0x3f] = oldSR; - SET_M(0); - SET_T(0); - SET_L(1); - SET_S(1); - SET_I(1); + SR &= ~(M_MASK | T_MASK); + SR |= (L_MASK | S_MASK | I_MASK); - PPC = PC; PC = addr; m_icount -= m_clock_cycles_2; @@ -1397,66 +825,60 @@ void hyperstone_device::execute_int(uint32_t addr) /* TODO: mask Parity Error and Extended Overflow exceptions */ void hyperstone_device::execute_exception(uint32_t addr) { - uint8_t reg; - uint32_t oldSR; - reg = GET_FP + GET_FL; - - SET_ILC(m_instruction_length & 3); - - oldSR = SR; + const uint8_t reg = GET_FP + GET_FL; + SET_ILC(m_instruction_length); + const uint32_t oldSR = SR; SET_FP(reg); SET_FL(2); - SET_L_REG(0, (PC & 0xfffffffe) | GET_S); - SET_L_REG(1, oldSR); + m_local_regs[(0 + reg) & 0x3f] = (PC & ~1) | GET_S; + m_local_regs[(1 + reg) & 0x3f] = oldSR; - SET_M(0); - SET_T(0); - SET_L(1); - SET_S(1); + SR &= ~(M_MASK | T_MASK); + SR |= (L_MASK | S_MASK); - PPC = PC; PC = addr; - DEBUG_PRINTF(("EXCEPTION! PPC = %08X PC = %08X\n",PPC-2,PC-2)); m_icount -= m_clock_cycles_2; } -void hyperstone_device::execute_software(struct hyperstone_device::regs_decode *decode) +void hyperstone_device::execute_software() { - uint8_t reg; - uint32_t oldSR; - uint32_t addr; - uint32_t stack_of_dst; + check_delay_PC(); - SET_ILC(1); + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_CODE; + const uint32_t sreg = m_local_regs[(src_code + fp) & 0x3f]; + const uint32_t sregf = m_local_regs[(src_code + 1 + fp) & 0x3f]; - addr = get_emu_code_addr((OP & 0xff00) >> 8); - reg = GET_FP + GET_FL; + SET_ILC(1<<19); + + const uint32_t addr = get_emu_code_addr((m_op & 0xff00) >> 8); + const uint8_t reg = fp + GET_FL; //since it's sure the register is in the register part of the stack, //set the stack address to a value above the highest address //that can be set by a following frame instruction - stack_of_dst = (SP & ~0xff) + 64*4 + (((GET_FP + decode->dst) % 64) * 4); //converted to 32bits offset + const uint32_t stack_of_dst = (SP & ~0xff) + 64*4 + (((fp + DST_CODE) % 64) * 4); //converted to 32bits offset - oldSR = SR; + const uint32_t oldSR = SR; SET_FL(6); SET_FP(reg); - SET_L_REG(0, stack_of_dst); - SET_L_REG(1, SREG); - SET_L_REG(2, SREGF); - SET_L_REG(3, (PC & 0xfffffffe) | GET_S); - SET_L_REG(4, oldSR); + m_local_regs[(reg + 0) & 0x3f] = stack_of_dst; + m_local_regs[(reg + 1) & 0x3f] = sreg; + m_local_regs[(reg + 2) & 0x3f] = sregf; + m_local_regs[(reg + 3) & 0x3f] = (PC & ~1) | GET_S; + m_local_regs[(reg + 4) & 0x3f] = oldSR; - SET_M(0); - SET_T(0); - SET_L(1); + SR &= ~(M_MASK | T_MASK); + SR |= L_MASK; - PPC = PC; PC = addr; + + m_icount -= m_clock_cycles_6; } @@ -1588,7 +1010,6 @@ void hyperstone_device::init(int scale_mask) { memset(m_global_regs, 0, sizeof(uint32_t) * 32); memset(m_local_regs, 0, sizeof(uint32_t) * 64); - m_ppc = 0; m_op = 0; m_trap_entry = 0; m_clock_scale_mask = 0; @@ -1609,12 +1030,17 @@ void hyperstone_device::init(int scale_mask) m_icount = 0; m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); m_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(hyperstone_device::timer_callback), this)); m_clock_scale_mask = scale_mask; + for (uint8_t i = 0; i < 16; i++) + { + m_fl_lut[i] = (i ? i : 16); + } + // register our state for the debugger state_add(STATE_GENPC, "GENPC", m_global_regs[0]).noshow(); state_add(STATE_GENPCBASE, "CURPC", m_global_regs[0]).noshow(); @@ -1734,12 +1160,11 @@ void hyperstone_device::init(int scale_mask) save_item(NAME(m_global_regs)); save_item(NAME(m_local_regs)); - save_item(NAME(m_ppc)); save_item(NAME(m_trap_entry)); - save_item(NAME(m_delay.delay_pc)); + save_item(NAME(m_delay_pc)); save_item(NAME(m_instruction_length)); save_item(NAME(m_intblock)); - save_item(NAME(m_delay.delay_cmd)); + save_item(NAME(m_delay_slot)); save_item(NAME(m_tr_clocks_per_tick)); save_item(NAME(m_tr_base_value)); save_item(NAME(m_tr_base_cycles)); @@ -1844,7 +1269,7 @@ void hyperstone_device::device_reset() //TODO: Add different reset initializations for BCR, MCR, FCR, TPR m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); m_tr_clocks_per_tick = 2; @@ -1866,15 +1291,14 @@ void hyperstone_device::device_reset() SET_L(1); SET_S(1); - SET_L_REG(0, (PC & 0xfffffffe) | GET_S); - SET_L_REG(1, SR); + set_local_register(0, (PC & 0xfffffffe) | GET_S); + set_local_register(1, SR); m_icount -= m_clock_cycles_2; } void hyperstone_device::device_stop() { - // nothing to do } @@ -1926,2993 +1350,84 @@ void hyperstone_device::state_string_export(const device_state_entry &entry, std //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t hyperstone_device::disasm_min_opcode_bytes() const -{ - return 2; -} - - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t hyperstone_device::disasm_max_opcode_bytes() const -{ - return 6; -} - - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t hyperstone_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *hyperstone_device::create_disassembler() { - extern CPU_DISASSEMBLE( hyperstone ); - return dasm_hyperstone(stream, pc, oprom, GET_H, GET_FP); + return new hyperstone_disassembler; } /* Opcodes */ -void hyperstone_device::hyperstone_chk(struct hyperstone_device::regs_decode *decode) -{ - uint32_t addr = get_trap_addr(TRAPNO_RANGE_ERROR); - - if( SRC_IS_SR ) - { - if( DREG == 0 ) - execute_exception(addr); - } - else - { - if( SRC_IS_PC ) - { - if( DREG >= SREG ) - execute_exception(addr); - } - else - { - if( DREG > SREG ) - execute_exception(addr); - } - } - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_movd(struct hyperstone_device::regs_decode *decode) -{ - if( DST_IS_PC ) // Rd denotes PC - { - // RET instruction - - uint8_t old_s, old_l; - int8_t difference; // really it's 7 bits - - if( SRC_IS_PC || SRC_IS_SR ) - { - DEBUG_PRINTF(("Denoted PC or SR in RET instruction. PC = %08X\n", PC)); - } - else - { - old_s = GET_S; - old_l = GET_L; - PPC = PC; - - SET_PC(SREG); - SR = (SREGF & 0xffe00000) | ((SREG & 0x01) << 18 ) | (SREGF & 0x3ffff); - if (m_intblock < 1) - m_intblock = 1; - - m_instruction_length = 0; // undefined - - if( (!old_s && GET_S) || (!GET_S && !old_l && GET_L)) - { - uint32_t addr = get_trap_addr(TRAPNO_PRIVILEGE_ERROR); - execute_exception(addr); - } - - difference = GET_FP - ((SP & 0x1fc) >> 2); - - /* convert to 8 bits */ - if(difference > 63) - difference = (int8_t)(difference|0x80); - else if( difference < -64 ) - difference = difference & 0x7f; - - if( difference < 0 ) //else it's finished - { - do - { - SP -= 4; - SET_ABS_L_REG(((SP & 0xfc) >> 2), READ_W(SP)); - difference++; - - } while(difference != 0); - } - } - - //TODO: no 1! - m_icount -= m_clock_cycles_1; - } - else if( SRC_IS_SR ) // Rd doesn't denote PC and Rs denotes SR - { - SET_DREG(0); - SET_DREGF(0); - SET_Z(1); - SET_N(0); - - m_icount -= m_clock_cycles_2; - } - else // Rd doesn't denote PC and Rs doesn't denote SR - { - uint64_t tmp; - - SET_DREG(SREG); - SET_DREGF(SREGF); - - tmp = concat_64(SREG, SREGF); - SET_Z( tmp == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(SREG) ); - - m_icount -= m_clock_cycles_2; - } -} - -void hyperstone_device::hyperstone_divu(struct hyperstone_device::regs_decode *decode) -{ - if( SAME_SRC_DST || SAME_SRC_DSTF ) - { - DEBUG_PRINTF(("Denoted the same register code in hyperstone_divu instruction. PC = %08X\n", PC)); - } - else - { - if( SRC_IS_PC || SRC_IS_SR ) - { - DEBUG_PRINTF(("Denoted PC or SR as source register in hyperstone_divu instruction. PC = %08X\n", PC)); - } - else - { - uint64_t dividend; - - dividend = concat_64(DREG, DREGF); - - if( SREG == 0 ) - { - //Rd//Rdf -> undefined - //Z -> undefined - //N -> undefined - uint32_t addr; - SET_V(1); - addr = get_trap_addr(TRAPNO_RANGE_ERROR); - execute_exception(addr); - } - else - { - uint32_t quotient, remainder; - - /* TODO: add quotient overflow */ - quotient = dividend / SREG; - remainder = dividend % SREG; - - SET_DREG(remainder); - SET_DREGF(quotient); - - SET_Z( quotient == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(quotient) ); - SET_V(0); - } - } - } - - m_icount -= 36 << m_clck_scale; -} - -void hyperstone_device::hyperstone_divs(struct hyperstone_device::regs_decode *decode) -{ - if( SAME_SRC_DST || SAME_SRC_DSTF ) - { - DEBUG_PRINTF(("Denoted the same register code in hyperstone_divs instruction. PC = %08X\n", PC)); - } - else - { - if( SRC_IS_PC || SRC_IS_SR ) - { - DEBUG_PRINTF(("Denoted PC or SR as source register in hyperstone_divs instruction. PC = %08X\n", PC)); - } - else - { - int64_t dividend; - - dividend = (int64_t) concat_64(DREG, DREGF); - - if( SREG == 0 || (DREG & 0x80000000) ) - { - //Rd//Rdf -> undefined - //Z -> undefined - //N -> undefined - uint32_t addr; - SET_V(1); - addr = get_trap_addr(TRAPNO_RANGE_ERROR); - execute_exception(addr); - } - else - { - int32_t quotient, remainder; - - /* TODO: add quotient overflow */ - quotient = dividend / ((int32_t)(SREG)); - remainder = dividend % ((int32_t)(SREG)); - - SET_DREG(remainder); - SET_DREGF(quotient); - - SET_Z( quotient == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(quotient) ); - SET_V(0); - } - } - } - - m_icount -= 36 << m_clck_scale; -} - -void hyperstone_device::hyperstone_xm(struct hyperstone_device::regs_decode *decode) -{ - if( SRC_IS_SR || DST_IS_SR || DST_IS_PC ) - { - DEBUG_PRINTF(("Denoted PC or SR in hyperstone_xm. PC = %08X\n", PC)); - } - else - { - switch( decode->sub_type ) // x_code - { - case 0: - case 1: - case 2: - case 3: - if( !SRC_IS_PC && (SREG > EXTRA_U) ) - { - uint32_t addr = get_trap_addr(TRAPNO_RANGE_ERROR); - execute_exception(addr); - } - else if( SRC_IS_PC && (SREG >= EXTRA_U) ) - { - uint32_t addr = get_trap_addr(TRAPNO_RANGE_ERROR); - execute_exception(addr); - } - else - { - SREG <<= decode->sub_type; - } - - break; - - case 4: - case 5: - case 6: - case 7: - decode->sub_type -= 4; - SREG <<= decode->sub_type; - - break; - } - - SET_DREG(SREG); - } - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_mask(struct hyperstone_device::regs_decode *decode) -{ - DREG = SREG & EXTRA_U; - - SET_DREG(DREG); - SET_Z( DREG == 0 ? 1 : 0 ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_sum(struct hyperstone_device::regs_decode *decode) -{ - uint64_t tmp; - - if( SRC_IS_SR ) - SREG = GET_C; - - tmp = (uint64_t)(SREG) + (uint64_t)(EXTRA_U); - CHECK_C(tmp); - CHECK_VADD(SREG,EXTRA_U,tmp); - - DREG = SREG + EXTRA_U; - - SET_DREG(DREG); - - if( DST_IS_PC ) - SET_M(0); - - SET_Z( DREG == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(DREG) ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_sums(struct hyperstone_device::regs_decode *decode) -{ - int32_t res; - int64_t tmp; - - if( SRC_IS_SR ) - SREG = GET_C; - - tmp = (int64_t)((int32_t)(SREG)) + (int64_t)(EXTRA_S); - CHECK_VADD(SREG,EXTRA_S,tmp); - -//#if SETCARRYS -// CHECK_C(tmp); -//#endif - - res = (int32_t)(SREG) + EXTRA_S; - - SET_DREG(res); - - SET_Z( res == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(res) ); - - m_icount -= m_clock_cycles_1; - - if( GET_V && !SRC_IS_SR ) - { - uint32_t addr = get_trap_addr(TRAPNO_RANGE_ERROR); - execute_exception(addr); - } -} - -void hyperstone_device::hyperstone_cmp(struct hyperstone_device::regs_decode *decode) -{ - uint64_t tmp; - - if( SRC_IS_SR ) - SREG = GET_C; - - if( DREG == SREG ) - SET_Z(1); - else - SET_Z(0); - - if( (int32_t) DREG < (int32_t) SREG ) - SET_N(1); - else - SET_N(0); - - tmp = (uint64_t)(DREG) - (uint64_t)(SREG); - CHECK_VSUB(SREG,DREG,tmp); - - if( DREG < SREG ) - SET_C(1); - else - SET_C(0); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_mov(struct hyperstone_device::regs_decode *decode) -{ - if( !GET_S && decode->dst >= 16 ) - { - uint32_t addr = get_trap_addr(TRAPNO_PRIVILEGE_ERROR); - execute_exception(addr); - } - - SET_DREG(SREG); - - if( DST_IS_PC ) - SET_M(0); - - SET_Z( SREG == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(SREG) ); - - m_icount -= m_clock_cycles_1; -} - - -void hyperstone_device::hyperstone_add(struct hyperstone_device::regs_decode *decode) -{ - uint64_t tmp; - - if( SRC_IS_SR ) - SREG = GET_C; - - tmp = (uint64_t)(SREG) + (uint64_t)(DREG); - CHECK_C(tmp); - CHECK_VADD(SREG,DREG,tmp); - - DREG = SREG + DREG; - SET_DREG(DREG); - - if( DST_IS_PC ) - SET_M(0); - - SET_Z( DREG == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(DREG) ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_adds(struct hyperstone_device::regs_decode *decode) +void hyperstone_device::hyperstone_trap() { - int32_t res; - int64_t tmp; - - if( SRC_IS_SR ) - SREG = GET_C; - - tmp = (int64_t)((int32_t)(SREG)) + (int64_t)((int32_t)(DREG)); - - CHECK_VADD(SREG,DREG,tmp); - -//#if SETCARRYS -// CHECK_C(tmp); -//#endif + check_delay_PC(); - res = (int32_t)(SREG) + (int32_t)(DREG); + const uint8_t trapno = (m_op & 0xfc) >> 2; + const uint32_t addr = get_trap_addr(trapno); + const uint8_t code = ((m_op & 0x300) >> 6) | (m_op & 0x03); - SET_DREG(res); - SET_Z( res == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(res) ); - - m_icount -= m_clock_cycles_1; - - if( GET_V ) - { - uint32_t addr = get_trap_addr(TRAPNO_RANGE_ERROR); - execute_exception(addr); - } -} - -void hyperstone_device::hyperstone_cmpb(struct hyperstone_device::regs_decode *decode) -{ - SET_Z( (DREG & SREG) == 0 ? 1 : 0 ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_andn(struct hyperstone_device::regs_decode *decode) -{ - DREG = DREG & ~SREG; - - SET_DREG(DREG); - SET_Z( DREG == 0 ? 1 : 0 ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_or(struct hyperstone_device::regs_decode *decode) -{ - DREG = DREG | SREG; - - SET_DREG(DREG); - SET_Z( DREG == 0 ? 1 : 0 ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_xor(struct hyperstone_device::regs_decode *decode) -{ - DREG = DREG ^ SREG; - - SET_DREG(DREG); - SET_Z( DREG == 0 ? 1 : 0 ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_subc(struct hyperstone_device::regs_decode *decode) -{ - uint64_t tmp; - - if( SRC_IS_SR ) - { - tmp = (uint64_t)(DREG) - (uint64_t)(GET_C); - CHECK_VSUB(GET_C,DREG,tmp); - } - else - { - tmp = (uint64_t)(DREG) - ((uint64_t)(SREG) + (uint64_t)(GET_C)); - //CHECK! - CHECK_VSUB(SREG + GET_C,DREG,tmp); - } - - - if( SRC_IS_SR ) - { - DREG = DREG - GET_C; - } - else - { - DREG = DREG - (SREG + GET_C); - } - - CHECK_C(tmp); - - SET_DREG(DREG); - - SET_Z( GET_Z & (DREG == 0 ? 1 : 0) ); - SET_N( SIGN_BIT(DREG) ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_not(struct hyperstone_device::regs_decode *decode) -{ - SET_DREG(~SREG); - SET_Z( ~SREG == 0 ? 1 : 0 ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_sub(struct hyperstone_device::regs_decode *decode) -{ - uint64_t tmp; - - if( SRC_IS_SR ) - SREG = GET_C; - - tmp = (uint64_t)(DREG) - (uint64_t)(SREG); - CHECK_C(tmp); - CHECK_VSUB(SREG,DREG,tmp); - - DREG = DREG - SREG; - SET_DREG(DREG); - - if( DST_IS_PC ) - SET_M(0); - - SET_Z( DREG == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(DREG) ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_subs(struct hyperstone_device::regs_decode *decode) -{ - int32_t res; - int64_t tmp; - - if( SRC_IS_SR ) - SREG = GET_C; - - tmp = (int64_t)((int32_t)(DREG)) - (int64_t)((int32_t)(SREG)); - -//#ifdef SETCARRYS -// CHECK_C(tmp); -//#endif - - CHECK_VSUB(SREG,DREG,tmp); - - res = (int32_t)(DREG) - (int32_t)(SREG); - - SET_DREG(res); - - SET_Z( res == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(res) ); - - m_icount -= m_clock_cycles_1; - - if( GET_V ) - { - uint32_t addr = get_trap_addr(TRAPNO_RANGE_ERROR); - execute_exception(addr); - } -} - -void hyperstone_device::hyperstone_addc(struct hyperstone_device::regs_decode *decode) -{ - uint64_t tmp; - - if( SRC_IS_SR ) - { - tmp = (uint64_t)(DREG) + (uint64_t)(GET_C); - CHECK_VADD(DREG,GET_C,tmp); - } - else - { - tmp = (uint64_t)(SREG) + (uint64_t)(DREG) + (uint64_t)(GET_C); - - //CHECK! - //CHECK_VADD1: V = (DREG == 0x7FFF) && (C == 1); - //OVERFLOW = CHECK_VADD1(DREG, C, DREG+C) | CHECK_VADD(SREG, DREG+C, SREG+DREG+C) - /* check if DREG + GET_C overflows */ -// if( (DREG == 0x7FFFFFFF) && (GET_C == 1) ) -// SET_V(1); -// else -// CHECK_VADD(SREG,DREG + GET_C,tmp); - - CHECK_VADD3(SREG,DREG,GET_C,tmp); - } - - - - if( SRC_IS_SR ) - DREG = DREG + GET_C; - else - DREG = SREG + DREG + GET_C; - - CHECK_C(tmp); - - SET_DREG(DREG); - SET_Z( GET_Z & (DREG == 0 ? 1 : 0) ); - SET_N( SIGN_BIT(DREG) ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_and(struct hyperstone_device::regs_decode *decode) -{ - DREG = DREG & SREG; - - SET_DREG(DREG); - SET_Z( DREG == 0 ? 1 : 0 ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_neg(struct hyperstone_device::regs_decode *decode) -{ - uint64_t tmp; - - if( SRC_IS_SR ) - SREG = GET_C; - - tmp = -(uint64_t)(SREG); - CHECK_C(tmp); - CHECK_VSUB(SREG,0,tmp); - - DREG = -SREG; - - SET_DREG(DREG); - - SET_Z( DREG == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(DREG) ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_negs(struct hyperstone_device::regs_decode *decode) -{ - int32_t res; - int64_t tmp; - - if( SRC_IS_SR ) - SREG = GET_C; - - tmp = -(int64_t)((int32_t)(SREG)); - CHECK_VSUB(SREG,0,tmp); - -//#if SETCARRYS -// CHECK_C(tmp); -//#endif - - res = -(int32_t)(SREG); - - SET_DREG(res); - - SET_Z( res == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(res) ); - - - m_icount -= m_clock_cycles_1; - - if( GET_V && !SRC_IS_SR ) //trap doesn't occur when source is SR - { - uint32_t addr = get_trap_addr(TRAPNO_RANGE_ERROR); - execute_exception(addr); - } -} - -void hyperstone_device::hyperstone_cmpi(struct hyperstone_device::regs_decode *decode) -{ - uint64_t tmp; - - tmp = (uint64_t)(DREG) - (uint64_t)(EXTRA_U); - CHECK_VSUB(EXTRA_U,DREG,tmp); - - if( DREG == EXTRA_U ) - SET_Z(1); - else - SET_Z(0); - - if( (int32_t) DREG < (int32_t) EXTRA_U ) - SET_N(1); - else - SET_N(0); - - if( DREG < EXTRA_U ) - SET_C(1); - else - SET_C(0); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_movi(struct hyperstone_device::regs_decode *decode) -{ - if( !GET_S && decode->dst >= 16 ) - { - uint32_t addr = get_trap_addr(TRAPNO_PRIVILEGE_ERROR); - execute_exception(addr); - } - - SET_DREG(EXTRA_U); - - if( DST_IS_PC ) - SET_M(0); - - SET_Z( EXTRA_U == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(EXTRA_U) ); - -#if MISSIONCRAFT_FLAGS - SET_V(0); // or V undefined ? -#endif - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_addi(struct hyperstone_device::regs_decode *decode) -{ - uint32_t imm; - uint64_t tmp; - - if( N_VALUE ) - imm = EXTRA_U; - else - imm = GET_C & ((GET_Z == 0 ? 1 : 0) | (DREG & 0x01)); - - - tmp = (uint64_t)(imm) + (uint64_t)(DREG); - CHECK_C(tmp); - CHECK_VADD(imm,DREG,tmp); - - DREG = imm + DREG; - SET_DREG(DREG); - - if( DST_IS_PC ) - SET_M(0); - - SET_Z( DREG == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(DREG) ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_addsi(struct hyperstone_device::regs_decode *decode) -{ - int32_t imm, res; - int64_t tmp; - - if( N_VALUE ) - imm = EXTRA_S; - else - imm = GET_C & ((GET_Z == 0 ? 1 : 0) | (DREG & 0x01)); - - tmp = (int64_t)(imm) + (int64_t)((int32_t)(DREG)); - CHECK_VADD(imm,DREG,tmp); - -//#if SETCARRYS -// CHECK_C(tmp); -//#endif - - res = imm + (int32_t)(DREG); - - SET_DREG(res); - - SET_Z( res == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(res) ); - - m_icount -= m_clock_cycles_1; - - if( GET_V ) - { - uint32_t addr = get_trap_addr(TRAPNO_RANGE_ERROR); - execute_exception(addr); - } -} - -void hyperstone_device::hyperstone_cmpbi(struct hyperstone_device::regs_decode *decode) -{ - uint32_t imm; - - if( N_VALUE ) - { - if( N_VALUE == 31 ) - { - imm = 0x7fffffff; // bit 31 = 0, others = 1 - } - else - { - imm = EXTRA_U; - } - - SET_Z( (DREG & imm) == 0 ? 1 : 0 ); - } - else - { - if( (DREG & 0xff000000) == 0 || (DREG & 0x00ff0000) == 0 || - (DREG & 0x0000ff00) == 0 || (DREG & 0x000000ff) == 0 ) - SET_Z(1); - else - SET_Z(0); - } - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_andni(struct hyperstone_device::regs_decode *decode) -{ - uint32_t imm; - - if( N_VALUE == 31 ) - imm = 0x7fffffff; // bit 31 = 0, others = 1 - else - imm = EXTRA_U; - - DREG = DREG & ~imm; - - SET_DREG(DREG); - SET_Z( DREG == 0 ? 1 : 0 ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_ori(struct hyperstone_device::regs_decode *decode) -{ - DREG = DREG | EXTRA_U; - - SET_DREG(DREG); - SET_Z( DREG == 0 ? 1 : 0 ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_xori(struct hyperstone_device::regs_decode *decode) -{ - DREG = DREG ^ EXTRA_U; - - SET_DREG(DREG); - SET_Z( DREG == 0 ? 1 : 0 ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_shrdi(struct hyperstone_device::regs_decode *decode) -{ - uint32_t low_order, high_order; - uint64_t val; - - high_order = DREG; - low_order = DREGF; - - val = concat_64(high_order, low_order); - - if( N_VALUE ) - SET_C((val >> (N_VALUE - 1)) & 1); - else - SET_C(0); - - val >>= N_VALUE; - - high_order = extract_64hi(val); - low_order = extract_64lo(val); - - SET_DREG(high_order); - SET_DREGF(low_order); - SET_Z( val == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(high_order) ); - - m_icount -= m_clock_cycles_2; -} - -void hyperstone_device::hyperstone_shrd(struct hyperstone_device::regs_decode *decode) -{ - uint32_t low_order, high_order; - uint64_t val; - uint8_t n = SREG & 0x1f; - - // result undefined if Ls denotes the same register as Ld or Ldf - if( SAME_SRC_DST || SAME_SRC_DSTF ) - { - DEBUG_PRINTF(("Denoted same registers in hyperstone_shrd. PC = %08X\n", PC)); - } - else - { - high_order = DREG; - low_order = DREGF; - - val = concat_64(high_order, low_order); - - if( n ) - SET_C((val >> (n - 1)) & 1); - else - SET_C(0); - - val >>= n; - - high_order = extract_64hi(val); - low_order = extract_64lo(val); - - SET_DREG(high_order); - SET_DREGF(low_order); - - SET_Z( val == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(high_order) ); - } - - m_icount -= m_clock_cycles_2; -} - -void hyperstone_device::hyperstone_shr(struct hyperstone_device::regs_decode *decode) -{ - uint32_t ret; - uint8_t n; - - n = SREG & 0x1f; - ret = DREG; - - if( n ) - SET_C((ret >> (n - 1)) & 1); - else - SET_C(0); - - ret >>= n; - - SET_DREG(ret); - SET_Z( ret == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(ret) ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_sardi(struct hyperstone_device::regs_decode *decode) -{ - uint32_t low_order, high_order; - uint64_t val; - uint8_t sign_bit; - - high_order = DREG; - low_order = DREGF; - - val = concat_64(high_order, low_order); - - if( N_VALUE ) - SET_C((val >> (N_VALUE - 1)) & 1); - else - SET_C(0); - - sign_bit = val >> 63; - val >>= N_VALUE; - - if( sign_bit ) - { - int i; - for( i = 0; i < N_VALUE; i++ ) - { - val |= (0x8000000000000000U >> i); - } - } - - high_order = val >> 32; - low_order = val & 0xffffffff; - - SET_DREG(high_order); - SET_DREGF(low_order); - - SET_Z( val == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(high_order) ); - - m_icount -= m_clock_cycles_2; -} - -void hyperstone_device::hyperstone_sard(struct hyperstone_device::regs_decode *decode) -{ - uint32_t low_order, high_order; - uint64_t val; - uint8_t n, sign_bit; - - n = SREG & 0x1f; - - // result undefined if Ls denotes the same register as Ld or Ldf - if( SAME_SRC_DST || SAME_SRC_DSTF ) - { - DEBUG_PRINTF(("Denoted same registers in hyperstone_sard. PC = %08X\n", PC)); - } - else - { - high_order = DREG; - low_order = DREGF; - - val = concat_64(high_order, low_order); - - if( n ) - SET_C((val >> (n - 1)) & 1); - else - SET_C(0); - - sign_bit = val >> 63; - - val >>= n; - - if( sign_bit ) - { - int i; - for( i = 0; i < n; i++ ) - { - val |= (0x8000000000000000U >> i); - } - } - - high_order = val >> 32; - low_order = val & 0xffffffff; - - SET_DREG(high_order); - SET_DREGF(low_order); - SET_Z( val == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(high_order) ); - } - - m_icount -= m_clock_cycles_2; -} - -void hyperstone_device::hyperstone_sar(struct hyperstone_device::regs_decode *decode) -{ - uint32_t ret; - uint8_t n, sign_bit; - - n = SREG & 0x1f; - ret = DREG; - sign_bit = (ret & 0x80000000) >> 31; - - if( n ) - SET_C((ret >> (n - 1)) & 1); - else - SET_C(0); - - ret >>= n; - - if( sign_bit ) - { - int i; - for( i = 0; i < n; i++ ) - { - ret |= (0x80000000 >> i); - } - } - - SET_DREG(ret); - SET_Z( ret == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(ret) ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_shldi(struct hyperstone_device::regs_decode *decode) -{ - uint32_t low_order, high_order, tmp; - uint64_t val, mask; - - high_order = DREG; - low_order = DREGF; - - val = concat_64(high_order, low_order); - SET_C( (N_VALUE)?(((val<<(N_VALUE-1))&0x8000000000000000U)?1:0):0); - mask = ((((uint64_t)1) << (32 - N_VALUE)) - 1) ^ 0xffffffff; - tmp = high_order << N_VALUE; - - if( ((high_order & mask) && (!(tmp & 0x80000000))) || - (((high_order & mask) ^ mask) && (tmp & 0x80000000)) ) - SET_V(1); - else - SET_V(0); - - val <<= N_VALUE; - - high_order = extract_64hi(val); - low_order = extract_64lo(val); - - SET_DREG(high_order); - SET_DREGF(low_order); - - SET_Z( val == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(high_order) ); - - m_icount -= m_clock_cycles_2; -} - -void hyperstone_device::hyperstone_shld(struct hyperstone_device::regs_decode *decode) -{ - uint32_t low_order, high_order, tmp, n; - uint64_t val, mask; - - n = SREG & 0x1f; - - // result undefined if Ls denotes the same register as Ld or Ldf - if( SAME_SRC_DST || SAME_SRC_DSTF ) - { - DEBUG_PRINTF(("Denoted same registers in hyperstone_shld. PC = %08X\n", PC)); - } - else - { - high_order = DREG; - low_order = DREGF; - - mask = ((((uint64_t)1) << (32 - n)) - 1) ^ 0xffffffff; - - val = concat_64(high_order, low_order); - SET_C( (n)?(((val<<(n-1))&0x8000000000000000U)?1:0):0); - tmp = high_order << n; - - if( ((high_order & mask) && (!(tmp & 0x80000000))) || - (((high_order & mask) ^ mask) && (tmp & 0x80000000)) ) - SET_V(1); - else - SET_V(0); - - val <<= n; - - high_order = extract_64hi(val); - low_order = extract_64lo(val); - - SET_DREG(high_order); - SET_DREGF(low_order); - - SET_Z( val == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(high_order) ); - } - - m_icount -= m_clock_cycles_2; -} - -void hyperstone_device::hyperstone_shl(struct hyperstone_device::regs_decode *decode) -{ - uint32_t base, ret, n; - uint64_t mask; - - n = SREG & 0x1f; - base = DREG; - mask = ((((uint64_t)1) << (32 - n)) - 1) ^ 0xffffffff; - SET_C( (n)?(((base<<(n-1))&0x80000000)?1:0):0); - ret = base << n; - - if( ((base & mask) && (!(ret & 0x80000000))) || - (((base & mask) ^ mask) && (ret & 0x80000000)) ) - SET_V(1); - else - SET_V(0); - - SET_DREG(ret); - SET_Z( ret == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(ret) ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::reserved(struct hyperstone_device::regs_decode *decode) -{ - DEBUG_PRINTF(("Executed Reserved opcode. PC = %08X OP = %04X\n", PC, OP)); -} - -void hyperstone_device::hyperstone_testlz(struct hyperstone_device::regs_decode *decode) -{ - uint8_t zeros = 0; - uint32_t mask; - - for( mask = 0x80000000; ; mask >>= 1 ) - { - if( SREG & mask ) - break; - else - zeros++; - - if( zeros == 32 ) - break; - } - - SET_DREG(zeros); - - m_icount -= m_clock_cycles_2; -} - -void hyperstone_device::hyperstone_rol(struct hyperstone_device::regs_decode *decode) -{ - uint32_t val, base; - uint8_t n; - uint64_t mask; - - n = SREG & 0x1f; - - val = base = DREG; - - mask = ((((uint64_t)1) << (32 - n)) - 1) ^ 0xffffffff; - - while( n > 0 ) - { - val = (val << 1) | ((val & 0x80000000) >> 31); - n--; - } - -#ifdef MISSIONCRAFT_FLAGS - - if( ((base & mask) && (!(val & 0x80000000))) || - (((base & mask) ^ mask) && (val & 0x80000000)) ) - SET_V(1); - else - SET_V(0); - -#endif - - SET_DREG(val); - - SET_Z( val == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(val) ); - - m_icount -= m_clock_cycles_1; -} - -//TODO: add trap error -void hyperstone_device::hyperstone_ldxx1(struct hyperstone_device::regs_decode *decode) -{ - uint32_t load; - - if( DST_IS_SR ) - { - switch( decode->sub_type ) - { - case 0: // LDBS.A - - load = READ_B(EXTRA_S); - load |= (load & 0x80) ? 0xffffff00 : 0; - SET_SREG(load); - - break; - - case 1: // LDBU.A - - load = READ_B(EXTRA_S); - SET_SREG(load); - - break; - - case 2: - - load = READ_HW(EXTRA_S); - - if( EXTRA_S & 1 ) // LDHS.A - { - load |= (load & 0x8000) ? 0xffff0000 : 0; - } - /* - else // LDHU.A - { - // nothing more - } - */ - - SET_SREG(load); - - break; - - case 3: - - if( (EXTRA_S & 3) == 3 ) // LDD.IOA - { - load = IO_READ_W(EXTRA_S & ~3); - SET_SREG(load); - - load = IO_READ_W((EXTRA_S & ~3) + 4); - SET_SREGF(load); - - m_icount -= m_clock_cycles_1; // extra cycle - } - else if( (EXTRA_S & 3) == 2 ) // LDW.IOA - { - load = IO_READ_W(EXTRA_S & ~3); - SET_SREG(load); - } - else if( (EXTRA_S & 3) == 1 ) // LDD.A - { - load = READ_W(EXTRA_S & ~1); - SET_SREG(load); - - load = READ_W((EXTRA_S & ~1) + 4); - SET_SREGF(load); - - m_icount -= m_clock_cycles_1; // extra cycle - } - else // LDW.A - { - load = READ_W(EXTRA_S & ~1); - SET_SREG(load); - } - - break; - } - } - else - { - switch( decode->sub_type ) - { - case 0: // LDBS.D - - load = READ_B(DREG + EXTRA_S); - load |= (load & 0x80) ? 0xffffff00 : 0; - SET_SREG(load); - - break; - - case 1: // LDBU.D - - load = READ_B(DREG + EXTRA_S); - SET_SREG(load); - - break; - - case 2: - - load = READ_HW(DREG + (EXTRA_S & ~1)); - - if( EXTRA_S & 1 ) // LDHS.D - { - load |= (load & 0x8000) ? 0xffff0000 : 0; - } - /* - else // LDHU.D - { - // nothing more - } - */ - - SET_SREG(load); - - break; - - case 3: - - if( (EXTRA_S & 3) == 3 ) // LDD.IOD - { - load = IO_READ_W(DREG + (EXTRA_S & ~3)); - SET_SREG(load); - - load = IO_READ_W(DREG + (EXTRA_S & ~3) + 4); - SET_SREGF(load); - - m_icount -= m_clock_cycles_1; // extra cycle - } - else if( (EXTRA_S & 3) == 2 ) // LDW.IOD - { - load = IO_READ_W(DREG + (EXTRA_S & ~3)); - SET_SREG(load); - } - else if( (EXTRA_S & 3) == 1 ) // LDD.D - { - load = READ_W(DREG + (EXTRA_S & ~1)); - SET_SREG(load); - - load = READ_W(DREG + (EXTRA_S & ~1) + 4); - SET_SREGF(load); - - m_icount -= m_clock_cycles_1; // extra cycle - } - else // LDW.D - { - load = READ_W(DREG + (EXTRA_S & ~1)); - SET_SREG(load); - } - - break; - } - } - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_ldxx2(struct hyperstone_device::regs_decode *decode) -{ - uint32_t load; - - if( DST_IS_PC || DST_IS_SR ) - { - DEBUG_PRINTF(("Denoted PC or SR in hyperstone_ldxx2. PC = %08X\n", PC)); - } - else - { - switch( decode->sub_type ) - { - case 0: // LDBS.N - - if(SAME_SRC_DST) - DEBUG_PRINTF(("LDBS.N denoted same regs @ %08X",PPC)); - - load = READ_B(DREG); - load |= (load & 0x80) ? 0xffffff00 : 0; - SET_SREG(load); - - if(!SAME_SRC_DST) - SET_DREG(DREG + EXTRA_S); - - break; - - case 1: // LDBU.N - - if(SAME_SRC_DST) - DEBUG_PRINTF(("LDBU.N denoted same regs @ %08X",PPC)); - - load = READ_B(DREG); - SET_SREG(load); - - if(!SAME_SRC_DST) - SET_DREG(DREG + EXTRA_S); - - break; - - case 2: - - load = READ_HW(DREG); - - if( EXTRA_S & 1 ) // LDHS.N - { - load |= (load & 0x8000) ? 0xffff0000 : 0; - - if(SAME_SRC_DST) - DEBUG_PRINTF(("LDHS.N denoted same regs @ %08X",PPC)); - } - /* - else // LDHU.N - { - // nothing more - } - */ - - SET_SREG(load); - - if(!SAME_SRC_DST) - SET_DREG(DREG + (EXTRA_S & ~1)); - - break; - - case 3: - - if( (EXTRA_S & 3) == 3 ) // LDW.S - { - if(SAME_SRC_DST) - DEBUG_PRINTF(("LDW.S denoted same regs @ %08X",PPC)); - - if(DREG < SP) - SET_SREG(READ_W(DREG)); - else - SET_SREG(GET_ABS_L_REG((DREG & 0xfc) >> 2)); - - if(!SAME_SRC_DST) - SET_DREG(DREG + (EXTRA_S & ~3)); - - m_icount -= m_clock_cycles_2; // extra cycles - } - else if( (EXTRA_S & 3) == 2 ) // Reserved - { - DEBUG_PRINTF(("Executed Reserved instruction in hyperstone_ldxx2. PC = %08X\n", PC)); - } - else if( (EXTRA_S & 3) == 1 ) // LDD.N - { - if(SAME_SRC_DST || SAME_SRCF_DST) - DEBUG_PRINTF(("LDD.N denoted same regs @ %08X",PPC)); - - load = READ_W(DREG); - SET_SREG(load); - - load = READ_W(DREG + 4); - SET_SREGF(load); - - if(!SAME_SRC_DST && !SAME_SRCF_DST) - SET_DREG(DREG + (EXTRA_S & ~1)); - - m_icount -= m_clock_cycles_1; // extra cycle - } - else // LDW.N - { - if(SAME_SRC_DST) - DEBUG_PRINTF(("LDW.N denoted same regs @ %08X",PPC)); - - load = READ_W(DREG); - SET_SREG(load); - - if(!SAME_SRC_DST) - SET_DREG(DREG + (EXTRA_S & ~1)); - } - - break; - } - } - - m_icount -= m_clock_cycles_1; -} - -//TODO: add trap error -void hyperstone_device::hyperstone_stxx1(struct hyperstone_device::regs_decode *decode) -{ - if( SRC_IS_SR ) - SREG = SREGF = 0; - - if( DST_IS_SR ) - { - switch( decode->sub_type ) - { - case 0: // STBS.A - - /* TODO: missing trap on range error */ - WRITE_B(EXTRA_S, SREG & 0xff); - - break; - - case 1: // STBU.A - - WRITE_B(EXTRA_S, SREG & 0xff); - - break; - - case 2: - - WRITE_HW(EXTRA_S, SREG & 0xffff); - - /* - if( EXTRA_S & 1 ) // STHS.A - { - // TODO: missing trap on range error - } - else // STHU.A - { - // nothing more - } - */ - - break; - - case 3: - - if( (EXTRA_S & 3) == 3 ) // STD.IOA - { - IO_WRITE_W(EXTRA_S & ~3, SREG); - IO_WRITE_W((EXTRA_S & ~3) + 4, SREGF); - - m_icount -= m_clock_cycles_1; // extra cycle - } - else if( (EXTRA_S & 3) == 2 ) // STW.IOA - { - IO_WRITE_W(EXTRA_S & ~3, SREG); - } - else if( (EXTRA_S & 3) == 1 ) // STD.A - { - WRITE_W(EXTRA_S & ~1, SREG); - WRITE_W((EXTRA_S & ~1) + 4, SREGF); - - m_icount -= m_clock_cycles_1; // extra cycle - } - else // STW.A - { - WRITE_W(EXTRA_S & ~1, SREG); - } - - break; - } - } - else - { - switch( decode->sub_type ) - { - case 0: // STBS.D - - /* TODO: missing trap on range error */ - WRITE_B(DREG + EXTRA_S, SREG & 0xff); - - break; - - case 1: // STBU.D - - WRITE_B(DREG + EXTRA_S, SREG & 0xff); - - break; - - case 2: - - WRITE_HW(DREG + (EXTRA_S & ~1), SREG & 0xffff); - - /* - if( EXTRA_S & 1 ) // STHS.D - { - // TODO: missing trap on range error - } - else // STHU.D - { - // nothing more - } - */ - - break; - - case 3: - - if( (EXTRA_S & 3) == 3 ) // STD.IOD - { - IO_WRITE_W(DREG + (EXTRA_S & ~3), SREG); - IO_WRITE_W(DREG + (EXTRA_S & ~3) + 4, SREGF); - - m_icount -= m_clock_cycles_1; // extra cycle - } - else if( (EXTRA_S & 3) == 2 ) // STW.IOD - { - IO_WRITE_W(DREG + (EXTRA_S & ~3), SREG); - } - else if( (EXTRA_S & 3) == 1 ) // STD.D - { - WRITE_W(DREG + (EXTRA_S & ~1), SREG); - WRITE_W(DREG + (EXTRA_S & ~1) + 4, SREGF); - - m_icount -= m_clock_cycles_1; // extra cycle - } - else // STW.D - { - WRITE_W(DREG + (EXTRA_S & ~1), SREG); - } - - break; - } - } - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_stxx2(struct hyperstone_device::regs_decode *decode) -{ - if( SRC_IS_SR ) - SREG = SREGF = 0; - - if( DST_IS_PC || DST_IS_SR ) - { - DEBUG_PRINTF(("Denoted PC or SR in hyperstone_stxx2. PC = %08X\n", PC)); - } - else - { - switch( decode->sub_type ) - { - case 0: // STBS.N - - /* TODO: missing trap on range error */ - WRITE_B(DREG, SREG & 0xff); - SET_DREG(DREG + EXTRA_S); - - break; - - case 1: // STBU.N - - WRITE_B(DREG, SREG & 0xff); - SET_DREG(DREG + EXTRA_S); - - break; - - case 2: - - WRITE_HW(DREG, SREG & 0xffff); - SET_DREG(DREG + (EXTRA_S & ~1)); - - /* - if( EXTRA_S & 1 ) // STHS.N - { - // TODO: missing trap on range error - } - else // STHU.N - { - // nothing more - } - */ - - break; - - case 3: - - if( (EXTRA_S & 3) == 3 ) // STW.S - { - if(DREG < SP) - WRITE_W(DREG, SREG); - else - { - if(((DREG & 0xfc) >> 2) == ((decode->src + GET_FP) % 64) && S_BIT == LOCAL) - DEBUG_PRINTF(("STW.S denoted the same local register @ %08X\n",PPC)); - - SET_ABS_L_REG((DREG & 0xfc) >> 2,SREG); - } - - SET_DREG(DREG + (EXTRA_S & ~3)); - - m_icount -= m_clock_cycles_2; // extra cycles - - } - else if( (EXTRA_S & 3) == 2 ) // Reserved - { - DEBUG_PRINTF(("Executed Reserved instruction in hyperstone_stxx2. PC = %08X\n", PC)); - } - else if( (EXTRA_S & 3) == 1 ) // STD.N - { - WRITE_W(DREG, SREG); - SET_DREG(DREG + (EXTRA_S & ~1)); - - if( SAME_SRCF_DST ) - WRITE_W(DREG + 4, SREGF + (EXTRA_S & ~1)); // because DREG == SREGF and DREG has been incremented - else - WRITE_W(DREG + 4, SREGF); - - m_icount -= m_clock_cycles_1; // extra cycle - } - else // STW.N - { - WRITE_W(DREG, SREG); - SET_DREG(DREG + (EXTRA_S & ~1)); - } - - break; - } - } - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_shri(struct hyperstone_device::regs_decode *decode) -{ - uint32_t val; - - val = DREG; - - if( N_VALUE ) - SET_C((val >> (N_VALUE - 1)) & 1); - else - SET_C(0); - - val >>= N_VALUE; - - SET_DREG(val); - SET_Z( val == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(val) ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_sari(struct hyperstone_device::regs_decode *decode) -{ - uint32_t val; - uint8_t sign_bit; - - val = DREG; - sign_bit = (val & 0x80000000) >> 31; - - if( N_VALUE ) - SET_C((val >> (N_VALUE - 1)) & 1); - else - SET_C(0); - - val >>= N_VALUE; - - if( sign_bit ) - { - int i; - for( i = 0; i < N_VALUE; i++ ) - { - val |= (0x80000000 >> i); - } - } - - SET_DREG(val); - SET_Z( val == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(val) ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_shli(struct hyperstone_device::regs_decode *decode) -{ - uint32_t val, val2; - uint64_t mask; - - val = DREG; - SET_C( (N_VALUE)?(((val<<(N_VALUE-1))&0x80000000)?1:0):0); - mask = ((((uint64_t)1) << (32 - N_VALUE)) - 1) ^ 0xffffffff; - val2 = val << N_VALUE; - - if( ((val & mask) && (!(val2 & 0x80000000))) || - (((val & mask) ^ mask) && (val2 & 0x80000000)) ) - SET_V(1); - else - SET_V(0); - - SET_DREG(val2); - SET_Z( val2 == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(val2) ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_mulu(struct hyperstone_device::regs_decode *decode) -{ - uint32_t low_order, high_order; - uint64_t double_word; - - // PC or SR aren't denoted, else result is undefined - if( SRC_IS_PC || SRC_IS_SR || DST_IS_PC || DST_IS_SR ) - { - DEBUG_PRINTF(("Denoted PC or SR in hyperstone_mulu instruction. PC = %08X\n", PC)); - } - else - { - double_word = (uint64_t)SREG *(uint64_t)DREG; - - low_order = double_word & 0xffffffff; - high_order = double_word >> 32; - - SET_DREG(high_order); - SET_DREGF(low_order); - - SET_Z( double_word == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(high_order) ); - } - - if(SREG <= 0xffff && DREG <= 0xffff) - m_icount -= m_clock_cycles_4; - else - m_icount -= m_clock_cycles_6; -} - -void hyperstone_device::hyperstone_muls(struct hyperstone_device::regs_decode *decode) -{ - uint32_t low_order, high_order; - int64_t double_word; - - // PC or SR aren't denoted, else result is undefined - if( SRC_IS_PC || SRC_IS_SR || DST_IS_PC || DST_IS_SR ) - { - DEBUG_PRINTF(("Denoted PC or SR in hyperstone_muls instruction. PC = %08X\n", PC)); - } - else - { - double_word = (int64_t)(int32_t)(SREG) * (int64_t)(int32_t)(DREG); - low_order = double_word & 0xffffffff; - high_order = double_word >> 32; - - SET_DREG(high_order); - SET_DREGF(low_order); - - SET_Z( double_word == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(high_order) ); - } - - if((SREG >= 0xffff8000 && SREG <= 0x7fff) && (DREG >= 0xffff8000 && DREG <= 0x7fff)) - m_icount -= m_clock_cycles_4; - else - m_icount -= m_clock_cycles_6; -} - -void hyperstone_device::hyperstone_set(struct hyperstone_device::regs_decode *decode) -{ - int n = N_VALUE; - - if( DST_IS_PC ) - { - DEBUG_PRINTF(("Denoted PC in hyperstone_set. PC = %08X\n", PC)); - } - else if( DST_IS_SR ) - { - //TODO: add fetch opcode when there's the pipeline - - //TODO: no 1! - m_icount -= m_clock_cycles_1; - } - else - { - switch( n ) - { - // SETADR - case 0: - { - uint32_t val; - val = (SP & 0xfffffe00) | (GET_FP << 2); - - //plus carry into bit 9 - val += (( (SP & 0x100) && (SIGN_BIT(SR) == 0) ) ? 1 : 0); - - SET_DREG(val); - - break; - } - // Reserved - case 1: - case 16: - case 17: - case 19: - DEBUG_PRINTF(("Used reserved N value (%d) in hyperstone_set. PC = %08X\n", n, PC)); - break; - - // SETxx - case 2: - SET_DREG(1); - break; - - case 3: - SET_DREG(0); - break; - - case 4: - if( GET_N || GET_Z ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 5: - if( !GET_N && !GET_Z ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 6: - if( GET_N ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 7: - if( !GET_N ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 8: - if( GET_C || GET_Z ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 9: - if( !GET_C && !GET_Z ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 10: - if( GET_C ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 11: - if( !GET_C ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 12: - if( GET_Z ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 13: - if( !GET_Z ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 14: - if( GET_V ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 15: - if( !GET_V ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 18: - SET_DREG(-1); - break; - - case 20: - if( GET_N || GET_Z ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - - case 21: - if( !GET_N && !GET_Z ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - - case 22: - if( GET_N ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - - case 23: - if( !GET_N ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - - case 24: - if( GET_C || GET_Z ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - - case 25: - if( !GET_C && !GET_Z ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - - case 26: - if( GET_C ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - - case 27: - if( !GET_C ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - - case 28: - if( GET_Z ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - - case 29: - if( !GET_Z ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - - case 30: - if( GET_V ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - - case 31: - if( !GET_V ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - } - - m_icount -= m_clock_cycles_1; - } -} - -void hyperstone_device::hyperstone_mul(struct hyperstone_device::regs_decode *decode) -{ - uint32_t single_word; - - // PC or SR aren't denoted, else result is undefined - if( SRC_IS_PC || SRC_IS_SR || DST_IS_PC || DST_IS_SR ) - { - DEBUG_PRINTF(("Denoted PC or SR in hyperstone_mul instruction. PC = %08X\n", PC)); - } - else - { - single_word = (SREG * DREG);// & 0xffffffff; // only the low-order word is taken - - SET_DREG(single_word); - - SET_Z( single_word == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(single_word) ); - } - - if((SREG >= 0xffff8000 && SREG <= 0x7fff) && (DREG >= 0xffff8000 && DREG <= 0x7fff)) - m_icount -= 3 << m_clck_scale; - else - m_icount -= 5 << m_clck_scale; -} - -void hyperstone_device::hyperstone_fadd(struct hyperstone_device::regs_decode *decode) -{ - execute_software(decode); - m_icount -= m_clock_cycles_6; -} - -void hyperstone_device::hyperstone_faddd(struct hyperstone_device::regs_decode *decode) -{ - execute_software(decode); - m_icount -= m_clock_cycles_6; -} - -void hyperstone_device::hyperstone_fsub(struct hyperstone_device::regs_decode *decode) -{ - execute_software(decode); - m_icount -= m_clock_cycles_6; -} - -void hyperstone_device::hyperstone_fsubd(struct hyperstone_device::regs_decode *decode) -{ - execute_software(decode); - m_icount -= m_clock_cycles_6; -} - -void hyperstone_device::hyperstone_fmul(struct hyperstone_device::regs_decode *decode) -{ - execute_software(decode); - m_icount -= m_clock_cycles_6; -} - -void hyperstone_device::hyperstone_fmuld(struct hyperstone_device::regs_decode *decode) -{ - execute_software(decode); - m_icount -= m_clock_cycles_6; -} - -void hyperstone_device::hyperstone_fdiv(struct hyperstone_device::regs_decode *decode) -{ - execute_software(decode); - m_icount -= m_clock_cycles_6; -} - -void hyperstone_device::hyperstone_fdivd(struct hyperstone_device::regs_decode *decode) -{ - execute_software(decode); - m_icount -= m_clock_cycles_6; -} - -void hyperstone_device::hyperstone_fcmp(struct hyperstone_device::regs_decode *decode) -{ - execute_software(decode); - m_icount -= m_clock_cycles_6; -} - -void hyperstone_device::hyperstone_fcmpd(struct hyperstone_device::regs_decode *decode) -{ - execute_software(decode); - m_icount -= m_clock_cycles_6; -} - -void hyperstone_device::hyperstone_fcmpu(struct hyperstone_device::regs_decode *decode) -{ - execute_software(decode); - m_icount -= m_clock_cycles_6; -} - -void hyperstone_device::hyperstone_fcmpud(struct hyperstone_device::regs_decode *decode) -{ - execute_software(decode); - m_icount -= m_clock_cycles_6; -} - -void hyperstone_device::hyperstone_fcvt(struct hyperstone_device::regs_decode *decode) -{ - execute_software(decode); - m_icount -= m_clock_cycles_6; -} - -void hyperstone_device::hyperstone_fcvtd(struct hyperstone_device::regs_decode *decode) -{ - execute_software(decode); - m_icount -= m_clock_cycles_6; -} - -void hyperstone_device::hyperstone_extend(struct hyperstone_device::regs_decode *decode) -{ - //TODO: add locks, overflow error and other things - uint32_t vals, vald; - - vals = SREG; - vald = DREG; - - switch( EXTRA_U ) // extended opcode - { - // signed or unsigned multiplication, single word product - case EMUL: - case 0x100: // used in "N" type cpu - { - uint32_t result; - - result = vals * vald; - SET_G_REG(15, result); - - break; - } - // unsigned multiplication, double word product - case EMULU: - { - uint64_t result; - - result = (uint64_t)vals * (uint64_t)vald; - vals = result >> 32; - vald = result & 0xffffffff; - SET_G_REG(14, vals); - SET_G_REG(15, vald); - - break; - } - // signed multiplication, double word product - case EMULS: - { - int64_t result; - - result = (int64_t)(int32_t)(vals) * (int64_t)(int32_t)(vald); - vals = result >> 32; - vald = result & 0xffffffff; - SET_G_REG(14, vals); - SET_G_REG(15, vald); - - break; - } - // signed multiply/add, single word product sum - case EMAC: - { - int32_t result; - - result = (int32_t)GET_G_REG(15) + ((int32_t)(vals) * (int32_t)(vald)); - SET_G_REG(15, result); - - break; - } - // signed multiply/add, double word product sum - case EMACD: - { - int64_t result; - - result = (int64_t)concat_64(GET_G_REG(14), GET_G_REG(15)) + (int64_t)((int64_t)(int32_t)(vals) * (int64_t)(int32_t)(vald)); - - vals = result >> 32; - vald = result & 0xffffffff; - SET_G_REG(14, vals); - SET_G_REG(15, vald); - - break; - } - // signed multiply/substract, single word product difference - case EMSUB: - { - int32_t result; - - result = (int32_t)GET_G_REG(15) - ((int32_t)(vals) * (int32_t)(vald)); - SET_G_REG(15, result); - - break; - } - // signed multiply/substract, double word product difference - case EMSUBD: - { - int64_t result; - - result = (int64_t)concat_64(GET_G_REG(14), GET_G_REG(15)) - (int64_t)((int64_t)(int32_t)(vals) * (int64_t)(int32_t)(vald)); - - vals = result >> 32; - vald = result & 0xffffffff; - SET_G_REG(14, vals); - SET_G_REG(15, vald); - - break; - } - // signed half-word multiply/add, single word product sum - case EHMAC: - { - int32_t result; - - result = (int32_t)GET_G_REG(15) + ((int32_t)((vald & 0xffff0000) >> 16) * (int32_t)((vals & 0xffff0000) >> 16)) + ((int32_t)(vald & 0xffff) * (int32_t)(vals & 0xffff)); - SET_G_REG(15, result); - - break; - } - // signed half-word multiply/add, double word product sum - case EHMACD: - { - int64_t result; - - result = (int64_t)concat_64(GET_G_REG(14), GET_G_REG(15)) + (int64_t)((int64_t)(int32_t)((vald & 0xffff0000) >> 16) * (int64_t)(int32_t)((vals & 0xffff0000) >> 16)) + ((int64_t)(int32_t)(vald & 0xffff) * (int64_t)(int32_t)(vals & 0xffff)); - - vals = result >> 32; - vald = result & 0xffffffff; - SET_G_REG(14, vals); - SET_G_REG(15, vald); - - break; - } - // half-word complex multiply - case EHCMULD: - { - uint32_t result; - - result = (((vald & 0xffff0000) >> 16) * ((vals & 0xffff0000) >> 16)) - ((vald & 0xffff) * (vals & 0xffff)); - SET_G_REG(14, result); - - result = (((vald & 0xffff0000) >> 16) * (vals & 0xffff)) + ((vald & 0xffff) * ((vals & 0xffff0000) >> 16)); - SET_G_REG(15, result); - - break; - } - // half-word complex multiply/add - case EHCMACD: - { - uint32_t result; - - result = GET_G_REG(14) + (((vald & 0xffff0000) >> 16) * ((vals & 0xffff0000) >> 16)) - ((vald & 0xffff) * (vals & 0xffff)); - SET_G_REG(14, result); - - result = GET_G_REG(15) + (((vald & 0xffff0000) >> 16) * (vals & 0xffff)) + ((vald & 0xffff) * ((vals & 0xffff0000) >> 16)); - SET_G_REG(15, result); - - break; - } - // half-word (complex) add/substract - // Ls is not used and should denote the same register as Ld - case EHCSUMD: - { - uint32_t result; - - result = ((((vals & 0xffff0000) >> 16) + GET_G_REG(14)) << 16) & 0xffff0000; - result |= ((vals & 0xffff) + GET_G_REG(15)) & 0xffff; - SET_G_REG(14, result); - - result = ((((vals & 0xffff0000) >> 16) - GET_G_REG(14)) << 16) & 0xffff0000; - result |= ((vals & 0xffff) - GET_G_REG(15)) & 0xffff; - SET_G_REG(15, result); - - break; - } - // half-word (complex) add/substract with fixed point adjustment - // Ls is not used and should denote the same register as Ld - case EHCFFTD: - { - uint32_t result; - - result = ((((vals & 0xffff0000) >> 16) + (GET_G_REG(14) >> 15)) << 16) & 0xffff0000; - result |= ((vals & 0xffff) + (GET_G_REG(15) >> 15)) & 0xffff; - SET_G_REG(14, result); - - result = ((((vals & 0xffff0000) >> 16) - (GET_G_REG(14) >> 15)) << 16) & 0xffff0000; - result |= ((vals & 0xffff) - (GET_G_REG(15) >> 15)) & 0xffff; - SET_G_REG(15, result); - - break; - } - // half-word (complex) add/substract with fixed point adjustment and shift - // Ls is not used and should denote the same register as Ld - case EHCFFTSD: - { - uint32_t result; - - result = (((((vals & 0xffff0000) >> 16) + (GET_G_REG(14) >> 15)) >> 1) << 16) & 0xffff0000; - result |= ((((vals & 0xffff) + (GET_G_REG(15) >> 15)) >> 1) & 0xffff); - SET_G_REG(14, result); - - result = (((((vals & 0xffff0000) >> 16) - (GET_G_REG(14) >> 15)) >> 1) << 16) & 0xffff0000; - result |= ((((vals & 0xffff) - (GET_G_REG(15) >> 15)) >> 1) & 0xffff); - SET_G_REG(15, result); - - break; - } - default: - DEBUG_PRINTF(("Executed Illegal extended opcode (%X). PC = %08X\n", EXTRA_U, PC)); - break; - } - - m_icount -= m_clock_cycles_1; //TODO: with the latency it can change -} - -void hyperstone_device::hyperstone_do(struct hyperstone_device::regs_decode *decode) -{ - fatalerror("Executed hyperstone_do instruction. PC = %08X\n", PPC); -} - -void hyperstone_device::hyperstone_ldwr(struct hyperstone_device::regs_decode *decode) -{ - SET_SREG(READ_W(DREG)); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_lddr(struct hyperstone_device::regs_decode *decode) -{ - SET_SREG(READ_W(DREG)); - SET_SREGF(READ_W(DREG + 4)); - - m_icount -= m_clock_cycles_2; -} - -void hyperstone_device::hyperstone_ldwp(struct hyperstone_device::regs_decode *decode) -{ - SET_SREG(READ_W(DREG)); - - // post increment the destination register if it's different from the source one - // (needed by Hidden Catch) - if(!(decode->src == decode->dst && S_BIT == LOCAL)) - SET_DREG(DREG + 4); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_lddp(struct hyperstone_device::regs_decode *decode) -{ - SET_SREG(READ_W(DREG)); - SET_SREGF(READ_W(DREG + 4)); - - // post increment the destination register if it's different from the source one - // and from the "next source" one - if(!(decode->src == decode->dst && S_BIT == LOCAL) && !SAME_SRCF_DST ) - { - SET_DREG(DREG + 8); - } - else - { - DEBUG_PRINTF(("LDD.P denoted same regs @ %08X",PPC)); - } - - m_icount -= m_clock_cycles_2; -} - -void hyperstone_device::hyperstone_stwr(struct hyperstone_device::regs_decode *decode) -{ - if( SRC_IS_SR ) - SREG = 0; - - WRITE_W(DREG, SREG); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_stdr(struct hyperstone_device::regs_decode *decode) -{ - if( SRC_IS_SR ) - SREG = SREGF = 0; - - WRITE_W(DREG, SREG); - WRITE_W(DREG + 4, SREGF); - - m_icount -= m_clock_cycles_2; -} - -void hyperstone_device::hyperstone_stwp(struct hyperstone_device::regs_decode *decode) -{ - if( SRC_IS_SR ) - SREG = 0; - - WRITE_W(DREG, SREG); - SET_DREG(DREG + 4); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_stdp(struct hyperstone_device::regs_decode *decode) -{ - if( SRC_IS_SR ) - SREG = SREGF = 0; - - WRITE_W(DREG, SREG); - SET_DREG(DREG + 8); - - if( SAME_SRCF_DST ) - WRITE_W(DREG + 4, SREGF + 8); // because DREG == SREGF and DREG has been incremented - else - WRITE_W(DREG + 4, SREGF); - - m_icount -= m_clock_cycles_2; -} - -void hyperstone_device::hyperstone_dbv(struct hyperstone_device::regs_decode *decode) -{ - if( GET_V ) - execute_dbr(decode); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_dbnv(struct hyperstone_device::regs_decode *decode) -{ - if( !GET_V ) - execute_dbr(decode); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_dbe(struct hyperstone_device::regs_decode *decode) //or DBZ -{ - if( GET_Z ) - execute_dbr(decode); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_dbne(struct hyperstone_device::regs_decode *decode) //or DBNZ -{ - if( !GET_Z ) - execute_dbr(decode); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_dbc(struct hyperstone_device::regs_decode *decode) //or DBST -{ - if( GET_C ) - execute_dbr(decode); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_dbnc(struct hyperstone_device::regs_decode *decode) //or DBHE -{ - if( !GET_C ) - execute_dbr(decode); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_dbse(struct hyperstone_device::regs_decode *decode) -{ - if( GET_C || GET_Z ) - execute_dbr(decode); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_dbht(struct hyperstone_device::regs_decode *decode) -{ - if( !GET_C && !GET_Z ) - execute_dbr(decode); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_dbn(struct hyperstone_device::regs_decode *decode) //or DBLT -{ - if( GET_N ) - execute_dbr(decode); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_dbnn(struct hyperstone_device::regs_decode *decode) //or DBGE -{ - if( !GET_N ) - execute_dbr(decode); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_dble(struct hyperstone_device::regs_decode *decode) -{ - if( GET_N || GET_Z ) - execute_dbr(decode); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_dbgt(struct hyperstone_device::regs_decode *decode) -{ - if( !GET_N && !GET_Z ) - execute_dbr(decode); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_dbr(struct hyperstone_device::regs_decode *decode) -{ - execute_dbr(decode); -} - -void hyperstone_device::hyperstone_frame(struct hyperstone_device::regs_decode *decode) -{ - int8_t difference; // really it's 7 bits - uint8_t realfp = GET_FP - SRC_CODE; - - SET_FP(realfp); - SET_FL(DST_CODE); - SET_M(0); - - difference = ((SP & 0x1fc) >> 2) + (64 - 10) - (realfp + GET_FL); - - /* convert to 8 bits */ - if(difference > 63) - difference = (int8_t)(difference|0x80); - else if( difference < -64 ) - difference = difference & 0x7f; - - if( difference < 0 ) // else it's finished - { - uint8_t tmp_flag; - - tmp_flag = ( SP >= UB ? 1 : 0 ); - - do - { - WRITE_W(SP, GET_ABS_L_REG((SP & 0xfc) >> 2)); - SP += 4; - difference++; - - } while(difference != 0); - - if( tmp_flag ) - { - uint32_t addr = get_trap_addr(TRAPNO_FRAME_ERROR); - execute_exception(addr); - } - } - - //TODO: no 1! - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_call(struct hyperstone_device::regs_decode *decode) -{ - if( SRC_IS_SR ) - SREG = 0; - - if( !DST_CODE ) - decode->dst = 16; - - EXTRA_S = (EXTRA_S & ~1) + SREG; - - SET_ILC(m_instruction_length & 3); - - SET_DREG((PC & 0xfffffffe) | GET_S); - SET_DREGF(SR); - - SET_FP(GET_FP + decode->dst); - - SET_FL(6); //default value for call - SET_M(0); - - PPC = PC; - PC = EXTRA_S; // const value - - m_intblock = 2; - - //TODO: add interrupt locks, errors, .... - - //TODO: no 1! - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_bv(struct hyperstone_device::regs_decode *decode) -{ - if( GET_V ) - execute_br(decode); - else - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_bnv(struct hyperstone_device::regs_decode *decode) -{ - if( !GET_V ) - execute_br(decode); - else - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_be(struct hyperstone_device::regs_decode *decode) //or BZ -{ - if( GET_Z ) - execute_br(decode); - else - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_bne(struct hyperstone_device::regs_decode *decode) //or BNZ -{ - if( !GET_Z ) - execute_br(decode); - else - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_bc(struct hyperstone_device::regs_decode *decode) //or BST -{ - if( GET_C ) - execute_br(decode); - else - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_bnc(struct hyperstone_device::regs_decode *decode) //or BHE -{ - if( !GET_C ) - execute_br(decode); - else - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_bse(struct hyperstone_device::regs_decode *decode) -{ - if( GET_C || GET_Z ) - execute_br(decode); - else - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_bht(struct hyperstone_device::regs_decode *decode) -{ - if( !GET_C && !GET_Z ) - execute_br(decode); - else - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_bn(struct hyperstone_device::regs_decode *decode) //or BLT -{ - if( GET_N ) - execute_br(decode); - else - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_bnn(struct hyperstone_device::regs_decode *decode) //or BGE -{ - if( !GET_N ) - execute_br(decode); - else - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_ble(struct hyperstone_device::regs_decode *decode) -{ - if( GET_N || GET_Z ) - execute_br(decode); - else - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_bgt(struct hyperstone_device::regs_decode *decode) -{ - if( !GET_N && !GET_Z ) - execute_br(decode); - else - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_br(struct hyperstone_device::regs_decode *decode) -{ - execute_br(decode); -} - -void hyperstone_device::hyperstone_trap(struct hyperstone_device::regs_decode *decode) -{ - uint8_t code, trapno; - uint32_t addr; - - trapno = (OP & 0xfc) >> 2; - - addr = get_trap_addr(trapno); - code = ((OP & 0x300) >> 6) | (OP & 0x03); - - switch( code ) + switch (code) { case TRAPLE: - if( GET_N || GET_Z ) + if (SR & (N_MASK | Z_MASK)) execute_trap(addr); - break; case TRAPGT: - if( !GET_N && !GET_Z ) + if(!(SR & (N_MASK | Z_MASK))) execute_trap(addr); - break; case TRAPLT: - if( GET_N ) + if (SR & N_MASK) execute_trap(addr); - break; case TRAPGE: - if( !GET_N ) + if (!(SR & N_MASK)) execute_trap(addr); - break; case TRAPSE: - if( GET_C || GET_Z ) + if (SR & (C_MASK | Z_MASK)) execute_trap(addr); - break; case TRAPHT: - if( !GET_C && !GET_Z ) + if (!(SR & (C_MASK | Z_MASK))) execute_trap(addr); - break; case TRAPST: - if( GET_C ) + if (SR & C_MASK) execute_trap(addr); - break; case TRAPHE: - if( !GET_C ) + if (!(SR & C_MASK)) execute_trap(addr); - break; case TRAPE: - if( GET_Z ) + if (SR & Z_MASK) execute_trap(addr); - break; case TRAPNE: - if( !GET_Z ) + if (!(SR & Z_MASK)) execute_trap(addr); - break; case TRAPV: - if( GET_V ) + if (SR & V_MASK) execute_trap(addr); - break; case TRAP: execute_trap(addr); - break; } @@ -4967,6 +1482,15 @@ void hyperstone_device::execute_set_input(int inputnum, int state) ISR &= ~(1 << inputnum); } +void hyperstone_device::hyperstone_reserved() +{ + LOG("Executed Reserved opcode. PC = %08X OP = %04X\n", PC, OP); +} + +void hyperstone_device::hyperstone_do() +{ + fatalerror("Executed hyperstone_do instruction. PC = %08X\n", PC-4); +} //------------------------------------------------- // execute_run - execute a timeslice's worth of @@ -4984,23 +1508,279 @@ void hyperstone_device::execute_run() { uint32_t oldh = SR & 0x00000020; - PPC = PC; /* copy PC to previous PC */ debugger_instruction_hook(this, PC); OP = READ_OP(PC); PC += 2; - m_instruction_length = 1; + m_instruction_length = (1<<19); - /* execute opcode */ - (this->*m_opcode[(OP & 0xff00) >> 8])(); + switch ((OP >> 8) & 0x00ff) + { + case 0x00: hyperstone_chk<GLOBAL, GLOBAL>(); break; + case 0x01: hyperstone_chk<GLOBAL, LOCAL>(); break; + case 0x02: hyperstone_chk<LOCAL, GLOBAL>(); break; + case 0x03: hyperstone_chk<LOCAL, LOCAL>(); break; + case 0x04: hyperstone_movd<GLOBAL, GLOBAL>(); break; + case 0x05: hyperstone_movd<GLOBAL, LOCAL>(); break; + case 0x06: hyperstone_movd<LOCAL, GLOBAL>(); break; + case 0x07: hyperstone_movd<LOCAL, LOCAL>(); break; + case 0x08: hyperstone_divsu<GLOBAL, GLOBAL, IS_UNSIGNED>(); break; + case 0x09: hyperstone_divsu<GLOBAL, LOCAL, IS_UNSIGNED>(); break; + case 0x0a: hyperstone_divsu<LOCAL, GLOBAL, IS_UNSIGNED>(); break; + case 0x0b: hyperstone_divsu<LOCAL, LOCAL, IS_UNSIGNED>(); break; + case 0x0c: hyperstone_divsu<GLOBAL, GLOBAL, IS_SIGNED>(); break; + case 0x0d: hyperstone_divsu<GLOBAL, LOCAL, IS_SIGNED>(); break; + case 0x0e: hyperstone_divsu<LOCAL, GLOBAL, IS_SIGNED>(); break; + case 0x0f: hyperstone_divsu<LOCAL, LOCAL, IS_SIGNED>(); break; + case 0x10: hyperstone_xm<GLOBAL, GLOBAL>(); break; + case 0x11: hyperstone_xm<GLOBAL, LOCAL>(); break; + case 0x12: hyperstone_xm<LOCAL, GLOBAL>(); break; + case 0x13: hyperstone_xm<LOCAL, LOCAL>(); break; + case 0x14: hyperstone_mask<GLOBAL, GLOBAL>(); break; + case 0x15: hyperstone_mask<GLOBAL, LOCAL>(); break; + case 0x16: hyperstone_mask<LOCAL, GLOBAL>(); break; + case 0x17: hyperstone_mask<LOCAL, LOCAL>(); break; + case 0x18: hyperstone_sum<GLOBAL, GLOBAL>(); break; + case 0x19: hyperstone_sum<GLOBAL, LOCAL>(); break; + case 0x1a: hyperstone_sum<LOCAL, GLOBAL>(); break; + case 0x1b: hyperstone_sum<LOCAL, LOCAL>(); break; + case 0x1c: hyperstone_sums<GLOBAL, GLOBAL>(); break; + case 0x1d: hyperstone_sums<GLOBAL, LOCAL>(); break; + case 0x1e: hyperstone_sums<LOCAL, GLOBAL>(); break; + case 0x1f: hyperstone_sums<LOCAL, LOCAL>(); break; + case 0x20: hyperstone_cmp<GLOBAL, GLOBAL>(); break; + case 0x21: hyperstone_cmp<GLOBAL, LOCAL>(); break; + case 0x22: hyperstone_cmp<LOCAL, GLOBAL>(); break; + case 0x23: hyperstone_cmp<LOCAL, LOCAL>(); break; + case 0x24: hyperstone_mov<GLOBAL, GLOBAL>(); break; + case 0x25: hyperstone_mov<GLOBAL, LOCAL>(); break; + case 0x26: hyperstone_mov<LOCAL, GLOBAL>(); break; + case 0x27: hyperstone_mov<LOCAL, LOCAL>(); break; + case 0x28: hyperstone_add<GLOBAL, GLOBAL>(); break; + case 0x29: hyperstone_add<GLOBAL, LOCAL>(); break; + case 0x2a: hyperstone_add<LOCAL, GLOBAL>(); break; + case 0x2b: hyperstone_add<LOCAL, LOCAL>(); break; + case 0x2c: hyperstone_adds<GLOBAL, GLOBAL>(); break; + case 0x2d: hyperstone_adds<GLOBAL, LOCAL>(); break; + case 0x2e: hyperstone_adds<LOCAL, GLOBAL>(); break; + case 0x2f: hyperstone_adds<LOCAL, LOCAL>(); break; + case 0x30: hyperstone_cmpb<GLOBAL, GLOBAL>(); break; + case 0x31: hyperstone_cmpb<GLOBAL, LOCAL>(); break; + case 0x32: hyperstone_cmpb<LOCAL, GLOBAL>(); break; + case 0x33: hyperstone_cmpb<LOCAL, LOCAL>(); break; + case 0x34: hyperstone_andn<GLOBAL, GLOBAL>(); break; + case 0x35: hyperstone_andn<GLOBAL, LOCAL>(); break; + case 0x36: hyperstone_andn<LOCAL, GLOBAL>(); break; + case 0x37: hyperstone_andn<LOCAL, LOCAL>(); break; + case 0x38: hyperstone_or<GLOBAL, GLOBAL>(); break; + case 0x39: hyperstone_or<GLOBAL, LOCAL>(); break; + case 0x3a: hyperstone_or<LOCAL, GLOBAL>(); break; + case 0x3b: hyperstone_or<LOCAL, LOCAL>(); break; + case 0x3c: hyperstone_xor<GLOBAL, GLOBAL>(); break; + case 0x3d: hyperstone_xor<GLOBAL, LOCAL>(); break; + case 0x3e: hyperstone_xor<LOCAL, GLOBAL>(); break; + case 0x3f: hyperstone_xor<LOCAL, LOCAL>(); break; + case 0x40: hyperstone_subc<GLOBAL, GLOBAL>(); break; + case 0x41: hyperstone_subc<GLOBAL, LOCAL>(); break; + case 0x42: hyperstone_subc<LOCAL, GLOBAL>(); break; + case 0x43: hyperstone_subc<LOCAL, LOCAL>(); break; + case 0x44: hyperstone_not<GLOBAL, GLOBAL>(); break; + case 0x45: hyperstone_not<GLOBAL, LOCAL>(); break; + case 0x46: hyperstone_not<LOCAL, GLOBAL>(); break; + case 0x47: hyperstone_not<LOCAL, LOCAL>(); break; + case 0x48: hyperstone_sub<GLOBAL, GLOBAL>(); break; + case 0x49: hyperstone_sub<GLOBAL, LOCAL>(); break; + case 0x4a: hyperstone_sub<LOCAL, GLOBAL>(); break; + case 0x4b: hyperstone_sub<LOCAL, LOCAL>(); break; + case 0x4c: hyperstone_subs<GLOBAL, GLOBAL>(); break; + case 0x4d: hyperstone_subs<GLOBAL, LOCAL>(); break; + case 0x4e: hyperstone_subs<LOCAL, GLOBAL>(); break; + case 0x4f: hyperstone_subs<LOCAL, LOCAL>(); break; + case 0x50: hyperstone_addc<GLOBAL, GLOBAL>(); break; + case 0x51: hyperstone_addc<GLOBAL, LOCAL>(); break; + case 0x52: hyperstone_addc<LOCAL, GLOBAL>(); break; + case 0x53: hyperstone_addc<LOCAL, LOCAL>(); break; + case 0x54: hyperstone_and<GLOBAL, GLOBAL>(); break; + case 0x55: hyperstone_and<GLOBAL, LOCAL>(); break; + case 0x56: hyperstone_and<LOCAL, GLOBAL>(); break; + case 0x57: hyperstone_and<LOCAL, LOCAL>(); break; + case 0x58: hyperstone_neg<GLOBAL, GLOBAL>(); break; + case 0x59: hyperstone_neg<GLOBAL, LOCAL>(); break; + case 0x5a: hyperstone_neg<LOCAL, GLOBAL>(); break; + case 0x5b: hyperstone_neg<LOCAL, LOCAL>(); break; + case 0x5c: hyperstone_negs<GLOBAL, GLOBAL>(); break; + case 0x5d: hyperstone_negs<GLOBAL, LOCAL>(); break; + case 0x5e: hyperstone_negs<LOCAL, GLOBAL>(); break; + case 0x5f: hyperstone_negs<LOCAL, LOCAL>(); break; + case 0x60: hyperstone_cmpi<GLOBAL, SIMM>(); break; + case 0x61: hyperstone_cmpi<GLOBAL, LIMM>(); break; + case 0x62: hyperstone_cmpi<LOCAL, SIMM>(); break; + case 0x63: hyperstone_cmpi<LOCAL, LIMM>(); break; + case 0x64: hyperstone_movi<GLOBAL, SIMM>(); break; + case 0x65: hyperstone_movi<GLOBAL, LIMM>(); break; + case 0x66: hyperstone_movi<LOCAL, SIMM>(); break; + case 0x67: hyperstone_movi<LOCAL, LIMM>(); break; + case 0x68: hyperstone_addi<GLOBAL, SIMM>(); break; + case 0x69: hyperstone_addi<GLOBAL, LIMM>(); break; + case 0x6a: hyperstone_addi<LOCAL, SIMM>(); break; + case 0x6b: hyperstone_addi<LOCAL, LIMM>(); break; + case 0x6c: hyperstone_addsi<GLOBAL, SIMM>(); break; + case 0x6d: hyperstone_addsi<GLOBAL, LIMM>(); break; + case 0x6e: hyperstone_addsi<LOCAL, SIMM>(); break; + case 0x6f: hyperstone_addsi<LOCAL, LIMM>(); break; + case 0x70: hyperstone_cmpbi<GLOBAL, SIMM>(); break; + case 0x71: hyperstone_cmpbi<GLOBAL, LIMM>(); break; + case 0x72: hyperstone_cmpbi<LOCAL, SIMM>(); break; + case 0x73: hyperstone_cmpbi<LOCAL, LIMM>(); break; + case 0x74: hyperstone_andni<GLOBAL, SIMM>(); break; + case 0x75: hyperstone_andni<GLOBAL, LIMM>(); break; + case 0x76: hyperstone_andni<LOCAL, SIMM>(); break; + case 0x77: hyperstone_andni<LOCAL, LIMM>(); break; + case 0x78: hyperstone_ori<GLOBAL, SIMM>(); break; + case 0x79: hyperstone_ori<GLOBAL, LIMM>(); break; + case 0x7a: hyperstone_ori<LOCAL, SIMM>(); break; + case 0x7b: hyperstone_ori<LOCAL, LIMM>(); break; + case 0x7c: hyperstone_xori<GLOBAL, SIMM>(); break; + case 0x7d: hyperstone_xori<GLOBAL, LIMM>(); break; + case 0x7e: hyperstone_xori<LOCAL, SIMM>(); break; + case 0x7f: hyperstone_xori<LOCAL, LIMM>(); break; + case 0x80: hyperstone_shrdi<N_LO>(); break; + case 0x81: hyperstone_shrdi<N_HI>(); break; + case 0x82: hyperstone_shrd(); break; + case 0x83: hyperstone_shr(); break; + case 0x84: hyperstone_sardi<N_LO>(); break; + case 0x85: hyperstone_sardi<N_HI>(); break; + case 0x86: hyperstone_sard(); break; + case 0x87: hyperstone_sar(); break; + case 0x88: hyperstone_shldi<N_LO>(); break; + case 0x89: hyperstone_shldi<N_HI>(); break; + case 0x8a: hyperstone_shld(); break; + case 0x8b: hyperstone_shl(); break; + case 0x8c: hyperstone_reserved(); break; + case 0x8d: hyperstone_reserved(); break; + case 0x8e: hyperstone_testlz(); break; + case 0x8f: hyperstone_rol(); break; + case 0x90: hyperstone_ldxx1<GLOBAL, GLOBAL>(); break; + case 0x91: hyperstone_ldxx1<GLOBAL, LOCAL>(); break; + case 0x92: hyperstone_ldxx1<LOCAL, GLOBAL>(); break; + case 0x93: hyperstone_ldxx1<LOCAL, LOCAL>(); break; + case 0x94: hyperstone_ldxx2<GLOBAL, GLOBAL>(); break; + case 0x95: hyperstone_ldxx2<GLOBAL, LOCAL>(); break; + case 0x96: hyperstone_ldxx2<LOCAL, GLOBAL>(); break; + case 0x97: hyperstone_ldxx2<LOCAL, LOCAL>(); break; + case 0x98: hyperstone_stxx1<GLOBAL, GLOBAL>(); break; + case 0x99: hyperstone_stxx1<GLOBAL, LOCAL>(); break; + case 0x9a: hyperstone_stxx1<LOCAL, GLOBAL>(); break; + case 0x9b: hyperstone_stxx1<LOCAL, LOCAL>(); break; + case 0x9c: hyperstone_stxx2<GLOBAL, GLOBAL>(); break; + case 0x9d: hyperstone_stxx2<GLOBAL, LOCAL>(); break; + case 0x9e: hyperstone_stxx2<LOCAL, GLOBAL>(); break; + case 0x9f: hyperstone_stxx2<LOCAL, LOCAL>(); break; + case 0xa0: hyperstone_shri<N_LO, GLOBAL>(); break; + case 0xa1: hyperstone_shri<N_HI, GLOBAL>(); break; + case 0xa2: hyperstone_shri<N_LO, LOCAL>(); break; + case 0xa3: hyperstone_shri<N_HI, LOCAL>(); break; + case 0xa4: hyperstone_sari<N_LO, GLOBAL>(); break; + case 0xa5: hyperstone_sari<N_HI, GLOBAL>(); break; + case 0xa6: hyperstone_sari<N_LO, LOCAL>(); break; + case 0xa7: hyperstone_sari<N_HI, LOCAL>(); break; + case 0xa8: hyperstone_shli<N_LO, GLOBAL>(); break; + case 0xa9: hyperstone_shli<N_HI, GLOBAL>(); break; + case 0xaa: hyperstone_shli<N_LO, LOCAL>(); break; + case 0xab: hyperstone_shli<N_HI, LOCAL>(); break; + case 0xac: hyperstone_reserved(); break; + case 0xad: hyperstone_reserved(); break; + case 0xae: hyperstone_reserved(); break; + case 0xaf: hyperstone_reserved(); break; + case 0xb0: hyperstone_mulsu<GLOBAL, GLOBAL, IS_UNSIGNED>(); break; + case 0xb1: hyperstone_mulsu<GLOBAL, LOCAL, IS_UNSIGNED>(); break; + case 0xb2: hyperstone_mulsu<LOCAL, GLOBAL, IS_UNSIGNED>(); break; + case 0xb3: hyperstone_mulsu<LOCAL, LOCAL, IS_UNSIGNED>(); break; + case 0xb4: hyperstone_mulsu<GLOBAL, GLOBAL, IS_SIGNED>(); break; + case 0xb5: hyperstone_mulsu<GLOBAL, LOCAL, IS_SIGNED>(); break; + case 0xb6: hyperstone_mulsu<LOCAL, GLOBAL, IS_SIGNED>(); break; + case 0xb7: hyperstone_mulsu<LOCAL, LOCAL, IS_SIGNED>(); break; + case 0xb8: hyperstone_set<N_LO, GLOBAL>(); break; + case 0xb9: hyperstone_set<N_HI, GLOBAL>(); break; + case 0xba: hyperstone_set<N_LO, LOCAL>(); break; + case 0xbb: hyperstone_set<N_HI, LOCAL>(); break; + case 0xbc: hyperstone_mul<GLOBAL, GLOBAL>(); break; + case 0xbd: hyperstone_mul<GLOBAL, LOCAL>(); break; + case 0xbe: hyperstone_mul<LOCAL, GLOBAL>(); break; + case 0xbf: hyperstone_mul<LOCAL, LOCAL>(); break; + case 0xc0: execute_software(); break; // fadd + case 0xc1: execute_software(); break; // faddd + case 0xc2: execute_software(); break; // fsub + case 0xc3: execute_software(); break; // fsubd + case 0xc4: execute_software(); break; // fmul + case 0xc5: execute_software(); break; // fmuld + case 0xc6: execute_software(); break; // fdiv + case 0xc7: execute_software(); break; // fdivd + case 0xc8: execute_software(); break; // fcmp + case 0xc9: execute_software(); break; // fcmpd + case 0xca: execute_software(); break; // fcmpu + case 0xcb: execute_software(); break; // fcmpud + case 0xcc: execute_software(); break; // fcvt + case 0xcd: execute_software(); break; // fcvtd + case 0xce: hyperstone_extend(); break; + case 0xcf: hyperstone_do(); break; + case 0xd0: hyperstone_ldwr<GLOBAL>(); break; + case 0xd1: hyperstone_ldwr<LOCAL>(); break; + case 0xd2: hyperstone_lddr<GLOBAL>(); break; + case 0xd3: hyperstone_lddr<LOCAL>(); break; + case 0xd4: hypesrtone_ldwp<GLOBAL>(); break; + case 0xd5: hypesrtone_ldwp<LOCAL>(); break; + case 0xd6: hyperstone_lddp<GLOBAL>(); break; + case 0xd7: hyperstone_lddp<LOCAL>(); break; + case 0xd8: hyperstone_stwr<GLOBAL>(); break; + case 0xd9: hyperstone_stwr<LOCAL>(); break; + case 0xda: hyperstone_stdr<GLOBAL>(); break; + case 0xdb: hyperstone_stdr<LOCAL>(); break; + case 0xdc: hyperstone_stwp<GLOBAL>(); break; + case 0xdd: hyperstone_stwp<LOCAL>(); break; + case 0xde: hyperstone_stdp<GLOBAL>(); break; + case 0xdf: hyperstone_stdp<LOCAL>(); break; + case 0xe0: hyperstone_dbv(); break; + case 0xe1: hyperstone_dbnv(); break; + case 0xe2: hyperstone_dbe(); break; + case 0xe3: hyperstone_dbne(); break; + case 0xe4: hyperstone_dbc(); break; + case 0xe5: hyperstone_dbnc(); break; + case 0xe6: hyperstone_dbse(); break; + case 0xe7: hyperstone_dbht(); break; + case 0xe8: hyperstone_dbn(); break; + case 0xe9: hyperstone_dbnn(); break; + case 0xea: hyperstone_dble(); break; + case 0xeb: hyperstone_dbgt(); break; + case 0xec: hyperstone_dbr(); break; + case 0xed: hyperstone_frame(); break; + case 0xee: hyperstone_call_global(); break; + case 0xef: hyperstone_call_local(); break; + case 0xf0: hyperstone_bv(); break; + case 0xf1: hyperstone_bnv(); break; + case 0xf2: hyperstone_be(); break; + case 0xf3: hyperstone_bne(); break; + case 0xf4: hyperstone_bc(); break; + case 0xf5: hyperstone_bnc(); break; + case 0xf6: hyperstone_bse(); break; + case 0xf7: hyperstone_bht(); break; + case 0xf8: hyperstone_bn(); break; + case 0xf9: hyperstone_bnn(); break; + case 0xfa: hyperstone_ble(); break; + case 0xfb: hyperstone_bgt(); break; + case 0xfc: execute_br(); break; + case 0xfd: hyperstone_trap(); break; + case 0xfe: hyperstone_trap(); break; + case 0xff: hyperstone_trap(); break; + } /* clear the H state if it was previously set */ SR ^= oldh; - SET_ILC(m_instruction_length & 3); + SET_ILC(m_instruction_length); - if( GET_T && GET_P && m_delay.delay_cmd == NO_DELAY ) /* Not in a Delayed Branch instructions */ + if (GET_T && GET_P && !m_delay_slot) /* Not in a Delayed Branch instructions */ { uint32_t addr = get_trap_addr(TRAPNO_TRACE_EXCEPTION); execute_exception(addr); diff --git a/src/devices/cpu/e132xs/e132xs.h b/src/devices/cpu/e132xs/e132xs.h index fd168d9eb75..81575c4f0cf 100644 --- a/src/devices/cpu/e132xs/e132xs.h +++ b/src/devices/cpu/e132xs/e132xs.h @@ -24,12 +24,6 @@ /* Functions */ -/*************************************************************************** - REGISTER ENUMERATION -***************************************************************************/ - -extern unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom, unsigned h_flag, int private_fp); - //************************************************************************** // TYPE DEFINITIONS //************************************************************************** @@ -96,6 +90,30 @@ protected: E132XS_L60, E132XS_L61, E132XS_L62, E132XS_L63 }; + enum reg_bank + { + LOCAL = 0, + GLOBAL = 1 + }; + + enum imm_size + { + SIMM = 0, + LIMM = 1 + }; + + enum shift_type + { + N_LO = 0, + N_HI = 1 + }; + + enum sign_mode + { + IS_UNSIGNED = 0, + IS_SIGNED = 1 + }; + // construction/destruction hyperstone_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const device_type type, uint32_t prg_data_width, uint32_t io_data_width, address_map_constructor internal_map); @@ -118,9 +136,7 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // device_state_interface overrides virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; @@ -129,22 +145,14 @@ protected: const address_space_config m_program_config; const address_space_config m_io_config; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_io; - /* Delay information */ - struct delay_info - { - int32_t delay_cmd; - uint32_t delay_pc; - }; - // CPU registers uint32_t m_global_regs[32]; uint32_t m_local_regs[64]; /* internal stuff */ - uint32_t m_ppc; // previous pc uint16_t m_op; // opcode uint32_t m_trap_entry; // entry point to get trap address @@ -152,6 +160,7 @@ protected: uint8_t m_clck_scale; uint8_t m_clock_cycles_1; uint8_t m_clock_cycles_2; + uint8_t m_clock_cycles_3; uint8_t m_clock_cycles_4; uint8_t m_clock_cycles_6; @@ -161,7 +170,8 @@ protected: uint8_t m_timer_int_pending; emu_timer *m_timer; - delay_info m_delay; + uint32_t m_delay_pc; + bool m_delay_slot; uint32_t m_opcodexor; @@ -171,33 +181,9 @@ protected: // other internal state int m_icount; - typedef void (hyperstone_device::*ophandler)(); - - ophandler m_opcode[256]; - - static const ophandler s_opcodetable[256]; + uint8_t m_fl_lut[16]; private: - struct regs_decode - { - uint8_t src, dst; // destination and source register code - uint32_t src_value; // current source register value - uint32_t next_src_value; // current next source register value - uint32_t dst_value; // current destination register value - uint32_t next_dst_value; // current next destination register value - uint8_t sub_type; // sub type opcode (for DD and X_CODE bits) - union - { - uint32_t u; - int32_t s; - } extra; // extra value such as immediate value, const, pcrel, ... - uint8_t src_is_local; - uint8_t dst_is_local; - uint8_t same_src_dst; - uint8_t same_src_dstf; - uint8_t same_srcf_dst; - }; - // internal functions void check_interrupts(); @@ -215,165 +201,267 @@ private: TIMER_CALLBACK_MEMBER(timer_callback); - void execute_br(struct regs_decode *decode); - void execute_dbr(struct regs_decode *decode); + void execute_br(); void execute_trap(uint32_t addr); void execute_int(uint32_t addr); void execute_exception(uint32_t addr); - void execute_software(struct regs_decode *decode); - - void hyperstone_chk(struct regs_decode *decode); - void hyperstone_movd(struct regs_decode *decode); - void hyperstone_divu(struct regs_decode *decode); - void hyperstone_divs(struct regs_decode *decode); - void hyperstone_xm(struct regs_decode *decode); - void hyperstone_mask(struct regs_decode *decode); - void hyperstone_sum(struct regs_decode *decode); - void hyperstone_sums(struct regs_decode *decode); - void hyperstone_cmp(struct regs_decode *decode); - void hyperstone_mov(struct regs_decode *decode); - void hyperstone_add(struct regs_decode *decode); - void hyperstone_adds(struct regs_decode *decode); - void hyperstone_cmpb(struct regs_decode *decode); - void hyperstone_andn(struct regs_decode *decode); - void hyperstone_or(struct regs_decode *decode); - void hyperstone_xor(struct regs_decode *decode); - void hyperstone_subc(struct regs_decode *decode); - void hyperstone_not(struct regs_decode *decode); - void hyperstone_sub(struct regs_decode *decode); - void hyperstone_subs(struct regs_decode *decode); - void hyperstone_addc(struct regs_decode *decode); - void hyperstone_and(struct regs_decode *decode); - void hyperstone_neg(struct regs_decode *decode); - void hyperstone_negs(struct regs_decode *decode); - void hyperstone_cmpi(struct regs_decode *decode); - void hyperstone_movi(struct regs_decode *decode); - void hyperstone_addi(struct regs_decode *decode); - void hyperstone_addsi(struct regs_decode *decode); - void hyperstone_cmpbi(struct regs_decode *decode); - void hyperstone_andni(struct regs_decode *decode); - void hyperstone_ori(struct regs_decode *decode); - void hyperstone_xori(struct regs_decode *decode); - void hyperstone_shrdi(struct regs_decode *decode); - void hyperstone_shrd(struct regs_decode *decode); - void hyperstone_shr(struct regs_decode *decode); - void hyperstone_shri(struct regs_decode *decode); - void hyperstone_sardi(struct regs_decode *decode); - void hyperstone_sard(struct regs_decode *decode); - void hyperstone_sar(struct regs_decode *decode); - void hyperstone_sari(struct regs_decode *decode); - void hyperstone_shldi(struct regs_decode *decode); - void hyperstone_shld(struct regs_decode *decode); - void hyperstone_shl(struct regs_decode *decode); - void hyperstone_shli(struct regs_decode *decode); - void hyperstone_testlz(struct regs_decode *decode); - void hyperstone_rol(struct regs_decode *decode); - void hyperstone_ldxx1(struct regs_decode *decode); - void hyperstone_ldxx2(struct regs_decode *decode); - void hyperstone_stxx1(struct regs_decode *decode); - void hyperstone_stxx2(struct regs_decode *decode); - void hyperstone_mulu(struct regs_decode *decode); - void hyperstone_muls(struct regs_decode *decode); - void hyperstone_mul(struct regs_decode *decode); - void hyperstone_set(struct regs_decode *decode); - - void hyperstone_fadd(struct regs_decode *decode); - void hyperstone_faddd(struct regs_decode *decode); - void hyperstone_fsub(struct regs_decode *decode); - void hyperstone_fsubd(struct regs_decode *decode); - void hyperstone_fmul(struct regs_decode *decode); - void hyperstone_fmuld(struct regs_decode *decode); - void hyperstone_fdiv(struct regs_decode *decode); - void hyperstone_fdivd(struct regs_decode *decode); - - void hyperstone_fcmp(struct regs_decode *decode); - void hyperstone_fcmpd(struct regs_decode *decode); - void hyperstone_fcmpu(struct regs_decode *decode); - void hyperstone_fcmpud(struct regs_decode *decode); - - void hyperstone_fcvt(struct regs_decode *decode); - void hyperstone_fcvtd(struct regs_decode *decode); - - void hyperstone_extend(struct regs_decode *decode); - - void hyperstone_ldwr(struct regs_decode *decode); - void hyperstone_lddr(struct regs_decode *decode); - void hyperstone_ldwp(struct regs_decode *decode); - void hyperstone_lddp(struct regs_decode *decode); - - void hyperstone_stwr(struct regs_decode *decode); - void hyperstone_stdr(struct regs_decode *decode); - void hyperstone_stwp(struct regs_decode *decode); - void hyperstone_stdp(struct regs_decode *decode); - - void hyperstone_dbv(struct regs_decode *decode); - void hyperstone_dbnv(struct regs_decode *decode); - void hyperstone_dbe(struct regs_decode *decode); - void hyperstone_dbne(struct regs_decode *decode); - void hyperstone_dbc(struct regs_decode *decode); - void hyperstone_dbnc(struct regs_decode *decode); - void hyperstone_dbse(struct regs_decode *decode); - void hyperstone_dbht(struct regs_decode *decode); - void hyperstone_dbn(struct regs_decode *decode); - void hyperstone_dbnn(struct regs_decode *decode); - void hyperstone_dble(struct regs_decode *decode); - void hyperstone_dbgt(struct regs_decode *decode); - void hyperstone_dbr(struct regs_decode *decode); - - void hyperstone_frame(struct regs_decode *decode); - void hyperstone_call(struct regs_decode *decode); - - void hyperstone_bv(struct regs_decode *decode); - void hyperstone_bnv(struct regs_decode *decode); - void hyperstone_be(struct regs_decode *decode); - void hyperstone_bne(struct regs_decode *decode); - void hyperstone_bc(struct regs_decode *decode); - void hyperstone_bnc(struct regs_decode *decode); - void hyperstone_bse(struct regs_decode *decode); - void hyperstone_bht(struct regs_decode *decode); - void hyperstone_bn(struct regs_decode *decode); - void hyperstone_bnn(struct regs_decode *decode); - void hyperstone_ble(struct regs_decode *decode); - void hyperstone_bgt(struct regs_decode *decode); - void hyperstone_br(struct regs_decode *decode); - - void hyperstone_trap(struct regs_decode *decode); - void hyperstone_do(struct regs_decode *decode); - - void reserved(struct regs_decode *decode); - - void op00(); void op01(); void op02(); void op03(); void op04(); void op05(); void op06(); void op07(); - void op08(); void op09(); void op0a(); void op0b(); void op0c(); void op0d(); void op0e(); void op0f(); - void op10(); void op11(); void op12(); void op13(); void op14(); void op15(); void op16(); void op17(); - void op18(); void op19(); void op1a(); void op1b(); void op1c(); void op1d(); void op1e(); void op1f(); - void op20(); void op21(); void op22(); void op23(); void op24(); void op25(); void op26(); void op27(); - void op28(); void op29(); void op2a(); void op2b(); void op2c(); void op2d(); void op2e(); void op2f(); - void op30(); void op31(); void op32(); void op33(); void op34(); void op35(); void op36(); void op37(); - void op38(); void op39(); void op3a(); void op3b(); void op3c(); void op3d(); void op3e(); void op3f(); - void op40(); void op41(); void op42(); void op43(); void op44(); void op45(); void op46(); void op47(); - void op48(); void op49(); void op4a(); void op4b(); void op4c(); void op4d(); void op4e(); void op4f(); - void op50(); void op51(); void op52(); void op53(); void op54(); void op55(); void op56(); void op57(); - void op58(); void op59(); void op5a(); void op5b(); void op5c(); void op5d(); void op5e(); void op5f(); - void op60(); void op61(); void op62(); void op63(); void op64(); void op65(); void op66(); void op67(); - void op68(); void op69(); void op6a(); void op6b(); void op6c(); void op6d(); void op6e(); void op6f(); - void op70(); void op71(); void op72(); void op73(); void op74(); void op75(); void op76(); void op77(); - void op78(); void op79(); void op7a(); void op7b(); void op7c(); void op7d(); void op7e(); void op7f(); - void op80(); void op81(); void op82(); void op83(); void op84(); void op85(); void op86(); void op87(); - void op88(); void op89(); void op8a(); void op8b(); void op8c(); void op8d(); void op8e(); void op8f(); - void op90(); void op91(); void op92(); void op93(); void op94(); void op95(); void op96(); void op97(); - void op98(); void op99(); void op9a(); void op9b(); void op9c(); void op9d(); void op9e(); void op9f(); - void opa0(); void opa1(); void opa2(); void opa3(); void opa4(); void opa5(); void opa6(); void opa7(); - void opa8(); void opa9(); void opaa(); void opab(); void opac(); void opad(); void opae(); void opaf(); - void opb0(); void opb1(); void opb2(); void opb3(); void opb4(); void opb5(); void opb6(); void opb7(); - void opb8(); void opb9(); void opba(); void opbb(); void opbc(); void opbd(); void opbe(); void opbf(); - void opc0(); void opc1(); void opc2(); void opc3(); void opc4(); void opc5(); void opc6(); void opc7(); - void opc8(); void opc9(); void opca(); void opcb(); void opcc(); void opcd(); void opce(); void opcf(); - void opd0(); void opd1(); void opd2(); void opd3(); void opd4(); void opd5(); void opd6(); void opd7(); - void opd8(); void opd9(); void opda(); void opdb(); void opdc(); void opdd(); void opde(); void opdf(); - void ope0(); void ope1(); void ope2(); void ope3(); void ope4(); void ope5(); void ope6(); void ope7(); - void ope8(); void ope9(); void opea(); void opeb(); void opec(); void oped(); void opee(); void opef(); - void opf0(); void opf1(); void opf2(); void opf3(); void opf4(); void opf5(); void opf6(); void opf7(); - void opf8(); void opf9(); void opfa(); void opfb(); void opfc(); void opfd(); void opfe(); void opff(); + void execute_software(); + + void ignore_immediate_s(); + uint32_t decode_immediate_s(); + uint32_t decode_const(); + + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_chk(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_movd(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL, sign_mode SIGNED> void hyperstone_divsu(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_xm(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_mask(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_sum(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_sums(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_cmp(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_mov(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_add(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_adds(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_cmpb(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_subc(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_sub(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_subs(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_addc(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_neg(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_negs(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_and(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_andn(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_or(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_xor(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_not(); + template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void hyperstone_cmpi(); + template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void hyperstone_movi(); + template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void hyperstone_addi(); + template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void hyperstone_addsi(); + template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void hyperstone_cmpbi(); + template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void hyperstone_andni(); + template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void hyperstone_ori(); + template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void hyperstone_xori(); + template <shift_type HI_N> void hyperstone_shrdi(); + void hyperstone_shrd(); + void hyperstone_shr(); + template <shift_type HI_N, reg_bank DST_GLOBAL> void hyperstone_shri(); + template <shift_type HI_N> void hyperstone_sardi(); + void hyperstone_sard(); + void hyperstone_sar(); + template <shift_type HI_N, reg_bank DST_GLOBAL> void hyperstone_sari(); + template <shift_type HI_N> void hyperstone_shldi(); + void hyperstone_shld(); + void hyperstone_shl(); + template <shift_type HI_N, reg_bank DST_GLOBAL> void hyperstone_shli(); + void hyperstone_testlz(); + void hyperstone_rol(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_ldxx1(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_ldxx2(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_stxx1(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_stxx2(); + + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL, sign_mode SIGNED> void hyperstone_mulsu(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_mul(); + + template <shift_type HI_N, reg_bank DST_GLOBAL> void hyperstone_set(); + + template <reg_bank SRC_GLOBAL> void hyperstone_ldwr(); + template <reg_bank SRC_GLOBAL> void hyperstone_lddr(); + template <reg_bank SRC_GLOBAL> void hypesrtone_ldwp(); + template <reg_bank SRC_GLOBAL> void hyperstone_lddp(); + + template <reg_bank SRC_GLOBAL> void hyperstone_stwr(); + template <reg_bank SRC_GLOBAL> void hyperstone_stdr(); + template <reg_bank SRC_GLOBAL> void hyperstone_stwp(); + template <reg_bank SRC_GLOBAL> void hyperstone_stdp(); + + void hyperstone_dbv(); + void hyperstone_dbnv(); + void hyperstone_dbe(); + void hyperstone_dbne(); + void hyperstone_dbc(); + void hyperstone_dbnc(); + void hyperstone_dbse(); + void hyperstone_dbht(); + void hyperstone_dbn(); + void hyperstone_dbnn(); + void hyperstone_dble(); + void hyperstone_dbgt(); + void hyperstone_dbr(); + + void hyperstone_frame(); + void hyperstone_call_global(); + void hyperstone_call_local(); + + void hyperstone_bv(); + void hyperstone_bnv(); + void hyperstone_be(); + void hyperstone_bne(); + void hyperstone_bc(); + void hyperstone_bnc(); + void hyperstone_bse(); + void hyperstone_bht(); + void hyperstone_bn(); + void hyperstone_bnn(); + void hyperstone_ble(); + void hyperstone_bgt(); + + void hyperstone_trap(); + void hyperstone_extend(); + + void hyperstone_reserved(); + void hyperstone_do(); + + int32_t decode_pcrel(); + void ignore_pcrel(); + +#if 0 + void execute_run_drc(); + void flush_drc_cache(); + void code_flush_cache(); + void code_compile_block(offs_t pc); + inline void ccfunc_unimplemented(); + void static_generate_entry_point(); + void static_generate_nocode_handler(); + void static_generate_out_of_cycles(); + void static_generate_memory_accessor(int size, int iswrite, const char *name, code_handle *&handleptr); + void generate_update_cycles(drcuml_block *block, compiler_state *compiler, uml::parameter param, bool allow_exception); + void generate_checksum_block(drcuml_block *block, compiler_state *compiler, const opcode_desc *seqhead, const opcode_desc *seqlast); + void generate_sequence_instruction(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + bool generate_opcode(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); +#endif + +#if 0 + void generate_op00(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op01(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op02(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op03(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op04(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op05(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op06(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op07(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op08(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op09(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op0a(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op0b(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op0c(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op0d(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op0e(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op0f(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op10(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op11(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op12(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op13(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op14(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op15(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op16(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op17(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op18(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op19(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op1a(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op1b(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op1c(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op1d(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op1e(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op1f(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op20(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op21(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op22(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op23(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op24(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op25(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op26(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op27(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op28(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op29(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op2a(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op2b(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op2c(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op2d(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op2e(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op2f(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op30(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op31(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op32(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op33(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op34(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op35(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op36(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op37(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op38(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op39(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op3a(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op3b(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op3c(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op3d(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op3e(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op3f(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op40(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op41(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op42(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op43(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op44(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op45(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op46(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op47(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op48(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op49(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op4a(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op4b(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op4c(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op4d(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op4e(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op4f(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op50(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op51(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op52(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op53(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op54(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op55(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op56(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op57(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op58(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op59(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op5a(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op5b(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op5c(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op5d(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op5e(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op5f(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op60(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op61(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op62(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op63(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op64(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op65(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op66(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op67(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op68(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op69(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op6a(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op6b(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op6c(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op6d(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op6e(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op6f(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op70(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op71(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op72(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op73(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op74(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op75(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op76(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op77(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op78(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op79(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op7a(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op7b(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op7c(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op7d(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op7e(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op7f(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op80(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op81(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op82(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op83(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op84(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op85(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op86(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op87(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op88(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op89(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op8a(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op8b(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op8c(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op8d(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op8e(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op8f(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op90(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op91(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op92(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op93(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op94(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op95(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op96(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op97(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op98(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op99(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op9a(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op9b(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op9c(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op9d(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_op9e(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op9f(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opa0(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opa1(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opa2(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opa3(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opa4(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opa5(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opa6(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opa7(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opa8(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opa9(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opaa(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opab(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opac(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opad(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opae(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opaf(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opb0(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opb1(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opb2(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opb3(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opb4(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opb5(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opb6(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opb7(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opb8(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opb9(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opba(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opbb(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opbc(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opbd(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opbe(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opbf(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opc0(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opc1(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opc2(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opc3(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opc4(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opc5(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opc6(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opc7(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opc8(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opc9(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opca(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opcb(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opcc(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opcd(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opce(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opcf(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opd0(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opd1(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opd2(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opd3(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opd4(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opd5(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opd6(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opd7(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opd8(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opd9(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opda(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opdb(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opdc(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opdd(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opde(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opdf(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_ope0(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_ope1(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_ope2(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_ope3(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_ope4(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_ope5(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_ope6(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_ope7(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_ope8(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_ope9(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opea(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opeb(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opec(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_oped(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opee(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opef(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opf0(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opf1(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opf2(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opf3(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opf4(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opf5(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opf6(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opf7(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opf8(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opf9(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opfa(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opfb(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opfc(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opfd(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_opfe(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_opff(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); +#endif }; // device type definition diff --git a/src/devices/cpu/e132xs/e132xsop.hxx b/src/devices/cpu/e132xs/e132xsop.hxx index e37ef914246..acaa1d99aa9 100644 --- a/src/devices/cpu/e132xs/e132xsop.hxx +++ b/src/devices/cpu/e132xs/e132xsop.hxx @@ -1,1925 +1,3205 @@ // license:BSD-3-Clause // copyright-holders:Pierpaolo Prazzoli -#define LOCAL_DECODE_INIT \ - struct regs_decode decode_state; \ - struct regs_decode *decode = &decode_state; \ -\ - /* clear 'current regs / flags' */ \ - decode->src = 0; \ - decode->dst = 0; \ - decode->src_value = 0; \ - decode->next_src_value = 0; \ - decode->dst_value = 0; \ - decode->next_dst_value = 0; \ - decode->sub_type = 0; \ - decode->extra.u = 0; \ - decode->src_is_local = 0; \ - decode->dst_is_local = 0; \ - decode->same_src_dst = 0; \ - decode->same_src_dstf = 0; \ - decode->same_srcf_dst = 0; +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_chk() +{ + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t dreg = DST_GLOBAL ? m_global_regs[DST_CODE] : m_local_regs[(DST_CODE + fp) & 0x3f]; + + if (SRC_GLOBAL && (src_code == SR_REGISTER)) + { + if (dreg == 0) + execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR)); + } + else + { + const uint32_t sreg = (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code]; + if ((SRC_GLOBAL && (src_code == PC_REGISTER)) ? (dreg >= sreg) : (dreg > sreg)) + execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR)); + } + + m_icount -= m_clock_cycles_1; +} + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_movd() +{ + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t srcf_code = SRC_GLOBAL ? (src_code + 1) : ((src_code + 1) & 0x3f); + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f); + const uint32_t dstf_code = DST_GLOBAL ? (dst_code + 1) : ((dst_code + 1) & 0x3f); + + const uint32_t sreg = (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code]; + const uint32_t sregf = (SRC_GLOBAL ? m_global_regs : m_local_regs)[srcf_code]; + + if (DST_GLOBAL && (dst_code == PC_REGISTER)) + { + // RET instruction + if (SRC_GLOBAL && src_code < 2) + { + LOG("Denoted PC or SR in RET instruction. PC = %08X\n", PC); + m_icount -= m_clock_cycles_1; + return; + } + + const uint32_t old_s = SR & S_MASK; + const uint32_t old_l = SR & L_MASK; + PC = sreg & ~1; + SR = (sregf & 0xffe00000) | ((sreg & 0x01) << 18 ) | (sregf & 0x3ffff); + if (m_intblock < 1) + m_intblock = 1; + + m_instruction_length = 0; // undefined + + const uint32_t new_s = SR & S_MASK; + const uint32_t new_l = SR & L_MASK; + if( (!old_s && new_s) || (!new_s && !old_l && new_l)) + execute_exception(get_trap_addr(TRAPNO_PRIVILEGE_ERROR)); + + int8_t difference = GET_FP - ((SP & 0x1fc) >> 2); + + /* convert to 8 bits */ + if(difference > 63) + difference = (int8_t)(difference|0x80); + else if( difference < -64 ) + difference = difference & 0x7f; + + for (; difference < 0; difference++) + { + SP -= 4; + m_local_regs[(SP & 0xfc) >> 2] = READ_W(SP); + } + + //TODO: no 1! + m_icount -= m_clock_cycles_1; + } + else if (SRC_GLOBAL && (src_code == SR_REGISTER)) // Rd doesn't denote PC and Rs denotes SR + { + if (DST_GLOBAL) + { + set_global_register(dst_code, 0); + set_global_register(dstf_code, 0); + } + else + { + m_local_regs[dst_code] = 0; + m_local_regs[dstf_code] = 0; + } + SR |= Z_MASK; + SR &= ~N_MASK; + + m_icount -= m_clock_cycles_2; + } + else // Rd doesn't denote PC and Rs doesn't denote SR + { + if (DST_GLOBAL) + { + set_global_register(dst_code, sreg); + set_global_register(dstf_code, sregf); + } + else + { + m_local_regs[dst_code] = sreg; + m_local_regs[dstf_code] = sregf; + } + + SR &= ~(Z_MASK | N_MASK); + if (concat_64(sreg, sregf) == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(sreg); + + m_icount -= m_clock_cycles_2; + } +} + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL, hyperstone_device::sign_mode SIGNED> +void hyperstone_device::hyperstone_divsu() +{ + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f); + const uint32_t dstf_code = DST_GLOBAL ? (dst_code + 1) : ((dst_code + 1) & 0x3f); + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + + if ((SRC_GLOBAL == DST_GLOBAL && (src_code == dst_code || src_code == dstf_code)) || (SRC_GLOBAL && src_code < 2)) + { + LOG("Denoted the same register code or PC/SR as source in hyperstone_divu instruction. PC = %08X\n", PC); + m_icount -= 36 << m_clck_scale; + return; + } + + const uint32_t sreg = (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code]; + const uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; + const uint32_t dregf = (DST_GLOBAL ? m_global_regs : m_local_regs)[dstf_code]; + const uint64_t dividend = concat_64(dreg, dregf); + + if (sreg == 0 || (SIGNED && (dividend & 0x8000000000000000U))) + { + //Rd//Rdf -> undefined + //Z -> undefined + //N -> undefined + SR |= V_MASK; + execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR)); + } + else + { + /* TODO: add quotient overflow */ + const uint32_t quotient = SIGNED ? (uint32_t)((int64_t)dividend / (int32_t)sreg) : (dividend / sreg); + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] = SIGNED ? (uint32_t)((int64_t)dividend % (int32_t)sreg) : (dividend % sreg); + (DST_GLOBAL ? m_global_regs : m_local_regs)[dstf_code] = (uint32_t)quotient; + SR &= ~(V_MASK | Z_MASK | N_MASK); + if (quotient == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(quotient); + } + + m_icount -= 36 << m_clck_scale; +} + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_xm() +{ + const uint32_t next = READ_OP(PC); + PC += 2; + + const uint8_t sub_type = (next & 0x7000) >> 12; + + uint32_t extra_u = next & 0xfff; + if (next & 0x8000) + { + extra_u = ((extra_u & 0xfff) << 16) | READ_OP(PC); + PC += 2; + m_instruction_length = (3<<19); + } + else + { + m_instruction_length = (2<<19); + } + + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f); + + if ((SRC_GLOBAL && (src_code == SR_REGISTER)) || (DST_GLOBAL && (dst_code < 2))) + { + LOG("Denoted PC or SR in hyperstone_xm. PC = %08X\n", PC); + m_icount -= m_clock_cycles_1; + return; + } -void hyperstone_device::op00() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_chk(decode); -} + uint32_t sreg = (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code]; -void hyperstone_device::op01() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_chk(decode); -} + if (sub_type < 4) + { + if ((SRC_GLOBAL && (src_code == PC_REGISTER)) ? (sreg >= extra_u) : (sreg > extra_u)) + execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR)); + else + sreg <<= sub_type; + } + else + { + sreg <<= (sub_type - 4); + } -void hyperstone_device::op02() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_chk(decode); -} + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] = sreg; -void hyperstone_device::op03() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_chk(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op04() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_mask() { - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_movd(decode); -} + const uint32_t extra_u = decode_const(); -void hyperstone_device::op05() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_movd(decode); -} + check_delay_PC(); -void hyperstone_device::op06() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_movd(decode); -} + const uint32_t dreg = (SRC_GLOBAL ? m_global_regs[SRC_CODE] : m_local_regs[(SRC_CODE + GET_FP) & 0x3f]) & extra_u; + if (DST_GLOBAL) + set_global_register(DST_CODE, dreg); + else + m_local_regs[(DST_CODE + GET_FP) & 0x3f] = dreg; -void hyperstone_device::op07() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_movd(decode); -} + if (dreg == 0) + SR |= Z_MASK; + else + SR &= ~Z_MASK; -void hyperstone_device::op08() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_divu(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op09() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_sum() { - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_divu(decode); -} + const uint32_t extra_u = decode_const(); -void hyperstone_device::op0a() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_divu(decode); -} + check_delay_PC(); -void hyperstone_device::op0b() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_divu(decode); -} + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t sreg = SRC_GLOBAL ? ((src_code == SR_REGISTER) ? GET_C : m_global_regs[src_code]) : m_local_regs[src_code]; -void hyperstone_device::op0c() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_divs(decode); -} + const uint64_t tmp = uint64_t(sreg) + uint64_t(extra_u); + SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); -void hyperstone_device::op0d() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_divs(decode); -} + SR |= (tmp & 0x100000000) >> 32; + SR |= ((sreg ^ tmp) & (extra_u ^ tmp) & 0x80000000) >> 28; -void hyperstone_device::op0e() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_divs(decode); + const uint32_t dreg = sreg + extra_u; + if (DST_GLOBAL) + set_global_register(DST_CODE, dreg); + else + m_local_regs[(DST_CODE + fp) & 0x3f] = dreg; + + if (dreg == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(dreg); + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op0f() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_sums() { - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_divs(decode); -} + const int32_t extra_s = decode_const(); + check_delay_PC(); + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const int32_t sreg = int32_t(SRC_GLOBAL ? ((src_code == SR_REGISTER) ? GET_C : m_global_regs[src_code]) : m_local_regs[src_code]); -void hyperstone_device::op10() -{ - LOCAL_DECODE_INIT; - RRlimdecode(decode, 0, 0); - hyperstone_xm(decode); -} + const int64_t tmp = int64_t(sreg) + int64_t(extra_s); + SR |= ((sreg ^ tmp) & (extra_s ^ tmp) & 0x80000000) >> 28; -void hyperstone_device::op11() -{ - LOCAL_DECODE_INIT; - RRlimdecode(decode, 0, 1); - hyperstone_xm(decode); -} +//#if SETCARRYS +// CHECK_C(tmp); +//#endif -void hyperstone_device::op12() -{ - LOCAL_DECODE_INIT; - RRlimdecode(decode, 1, 0); - hyperstone_xm(decode); -} + const int32_t res = sreg + extra_s; + if (DST_GLOBAL) + set_global_register(DST_CODE, res); + else + m_local_regs[(DST_CODE + fp) & 0x3f] = res; -void hyperstone_device::op13() -{ - LOCAL_DECODE_INIT; - RRlimdecode(decode, 1, 1); - hyperstone_xm(decode); -} + if (res == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(res); -void hyperstone_device::op14() -{ - LOCAL_DECODE_INIT; - RRconstdecode(decode, 0, 0); - hyperstone_mask(decode); -} + m_icount -= m_clock_cycles_1; -void hyperstone_device::op15() -{ - LOCAL_DECODE_INIT; - RRconstdecode(decode, 0, 1); - hyperstone_mask(decode); + if ((SR & V_MASK) && src_code != SR_REGISTER) + execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR)); } -void hyperstone_device::op16() -{ - LOCAL_DECODE_INIT; - RRconstdecode(decode, 1, 0); - hyperstone_mask(decode); -} -void hyperstone_device::op17() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_cmp() { - LOCAL_DECODE_INIT; - RRconstdecode(decode, 1, 1); - hyperstone_mask(decode); -} + check_delay_PC(); -void hyperstone_device::op18() -{ - LOCAL_DECODE_INIT; - RRconstdecode(decode, 0, 0); - hyperstone_sum(decode); -} + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f); -void hyperstone_device::op19() -{ - LOCAL_DECODE_INIT; - RRconstdecode(decode, 0, 1); - hyperstone_sum(decode); -} + const uint32_t sreg = SRC_GLOBAL ? ((src_code == SR_REGISTER) ? GET_C : m_global_regs[src_code]) : m_local_regs[src_code]; + uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; -void hyperstone_device::op1a() -{ - LOCAL_DECODE_INIT; - RRconstdecode(decode, 1, 0); - hyperstone_sum(decode); -} + const uint64_t tmp = uint64_t(dreg) - uint64_t(sreg); -void hyperstone_device::op1b() -{ - LOCAL_DECODE_INIT; - RRconstdecode(decode, 1, 1); - hyperstone_sum(decode); -} + SR &= ~(Z_MASK | N_MASK | V_MASK | C_MASK); + SR |= ((tmp ^ dreg) & (dreg ^ sreg) & 0x80000000) >> 28; -void hyperstone_device::op1c() -{ - LOCAL_DECODE_INIT; - RRconstdecode(decode, 0, 0); - hyperstone_sums(decode); -} + if (dreg == sreg) + SR |= Z_MASK; -void hyperstone_device::op1d() -{ - LOCAL_DECODE_INIT; - RRconstdecode(decode, 0, 1); - hyperstone_sums(decode); -} + if (int32_t(dreg) < int32_t(sreg)) + SR |= N_MASK; -void hyperstone_device::op1e() -{ - LOCAL_DECODE_INIT; - RRconstdecode(decode, 1, 0); - hyperstone_sums(decode); + if (dreg < sreg) + SR |= C_MASK; + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op1f() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_mov() { - LOCAL_DECODE_INIT; - RRconstdecode(decode, 1, 1); - hyperstone_sums(decode); -} + check_delay_PC(); + const bool h = (SR & H_MASK) != 0; + if (DST_GLOBAL && h && !(SR & S_MASK)) + { + execute_exception(get_trap_addr(TRAPNO_PRIVILEGE_ERROR)); + } + else + { + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? (SRC_CODE + (h ? 16 : 0)) : ((SRC_CODE + fp) & 0x3f); + const uint32_t sreg = SRC_GLOBAL ? ((WRITE_ONLY_REGMASK & (1 << src_code)) ? 0 : get_global_register(src_code)) : m_local_regs[src_code]; + if (DST_GLOBAL) + { + const uint32_t dst_code = DST_CODE + (h ? 16 : 0); + set_global_register(dst_code, sreg); -void hyperstone_device::op20() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_cmp(decode); -} + if (dst_code == PC_REGISTER) + SR &= ~M_MASK; + } + else + { + m_local_regs[(DST_CODE + fp) & 0x3f] = sreg; + } -void hyperstone_device::op21() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_cmp(decode); -} + SR &= ~(Z_MASK | N_MASK); + if (sreg == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(sreg); + } -void hyperstone_device::op22() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_cmp(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op23() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_add() { - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_cmp(decode); -} + check_delay_PC(); -void hyperstone_device::op24() -{ - LOCAL_DECODE_INIT; - RRdecodewithHflag(decode, 0, 0); - hyperstone_mov(decode); -} + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f); -void hyperstone_device::op25() -{ - LOCAL_DECODE_INIT; - RRdecodewithHflag(decode, 0, 1); - hyperstone_mov(decode); -} + const uint32_t sreg = SRC_GLOBAL ? ((src_code == SR_REGISTER) ? GET_C : m_global_regs[src_code]) : m_local_regs[src_code]; + uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; -void hyperstone_device::op26() -{ - LOCAL_DECODE_INIT; - RRdecodewithHflag(decode, 1, 0); - hyperstone_mov(decode); -} + const uint64_t tmp = uint64_t(sreg) + uint64_t(dreg); -void hyperstone_device::op27() -{ - LOCAL_DECODE_INIT; - RRdecodewithHflag(decode, 1, 1); - hyperstone_mov(decode); -} + SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); -void hyperstone_device::op28() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_add(decode); -} + SR |= (tmp & 0x100000000) >> 32; + SR |= ((sreg ^ tmp) & (dreg ^ tmp) & 0x80000000) >> 28; -void hyperstone_device::op29() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_add(decode); -} + dreg += sreg; + if (DST_GLOBAL) + { + set_global_register(dst_code, dreg); -void hyperstone_device::op2a() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_add(decode); -} + if (dst_code == 0) + SR &= ~M_MASK; + } + else + { + m_local_regs[dst_code] = dreg; + } -void hyperstone_device::op2b() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_add(decode); -} + if (dreg == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(dreg); -void hyperstone_device::op2c() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_adds(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op2d() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_adds() { - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_adds(decode); -} + check_delay_PC(); -void hyperstone_device::op2e() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_adds(decode); -} + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f); -void hyperstone_device::op2f() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_adds(decode); -} + const int32_t sreg = int32_t(SRC_GLOBAL ? ((src_code == SR_REGISTER) ? GET_C : m_global_regs[src_code]) : m_local_regs[src_code]); + int32_t dreg = int32_t((DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]); + const int64_t tmp = int64_t(sreg) + int64_t(dreg); + SR &= ~(V_MASK | Z_MASK | N_MASK); + SR |= ((sreg ^ tmp) & (dreg ^ tmp) & 0x80000000) >> 28; +//#if SETCARRYS +// CHECK_C(tmp); +//#endif -void hyperstone_device::op30() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_cmpb(decode); -} + const int32_t res = sreg + dreg; + if (DST_GLOBAL) + set_global_register(dst_code, res); + else + m_local_regs[dst_code] = res; -void hyperstone_device::op31() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_cmpb(decode); -} + if (res == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(res); -void hyperstone_device::op32() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_cmpb(decode); -} + m_icount -= m_clock_cycles_1; -void hyperstone_device::op33() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_cmpb(decode); + if (SR & V_MASK) + execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR)); } -void hyperstone_device::op34() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_andn(decode); -} -void hyperstone_device::op35() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_andn(decode); -} -void hyperstone_device::op36() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_cmpb() { - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_andn(decode); -} + check_delay_PC(); -void hyperstone_device::op37() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_andn(decode); -} + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f); -void hyperstone_device::op38() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_or(decode); -} + const uint32_t sreg = (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code]; + const uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; -void hyperstone_device::op39() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_or(decode); -} + if (dreg & sreg) + SR &= ~Z_MASK; + else + SR |= Z_MASK; -void hyperstone_device::op3a() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_or(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op3b() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_andn() { - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_or(decode); -} + check_delay_PC(); -void hyperstone_device::op3c() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_xor(decode); -} + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f); + const uint32_t sreg = SRC_GLOBAL ? m_global_regs[SRC_CODE] : m_local_regs[(SRC_CODE + GET_FP) & 0x3f]; + const uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] & ~sreg; + if (DST_GLOBAL) + set_global_register(dst_code, dreg); + else + m_local_regs[dst_code] = dreg; -void hyperstone_device::op3d() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_xor(decode); -} + if (dreg == 0) + SR |= Z_MASK; + else + SR &= ~Z_MASK; -void hyperstone_device::op3e() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_xor(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op3f() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_or() { - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_xor(decode); -} + check_delay_PC(); + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f); + const uint32_t sreg = SRC_GLOBAL ? m_global_regs[SRC_CODE] : m_local_regs[(SRC_CODE + GET_FP) & 0x3f]; + const uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] | sreg; + if (DST_GLOBAL) + set_global_register(dst_code, dreg); + else + m_local_regs[dst_code] = dreg; + if (dreg == 0) + SR |= Z_MASK; + else + SR &= ~Z_MASK; -void hyperstone_device::op40() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_subc(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op41() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_xor() { - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_subc(decode); -} + check_delay_PC(); -void hyperstone_device::op42() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_subc(decode); -} + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f); + const uint32_t sreg = SRC_GLOBAL ? m_global_regs[SRC_CODE] : m_local_regs[(SRC_CODE + GET_FP) & 0x3f]; + const uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] ^ sreg; + if (DST_GLOBAL) + set_global_register(dst_code, dreg); + else + m_local_regs[dst_code] = dreg; -void hyperstone_device::op43() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_subc(decode); -} + if (dreg == 0) + SR |= Z_MASK; + else + SR &= ~Z_MASK; -void hyperstone_device::op44() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_not(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op45() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_not(decode); -} -void hyperstone_device::op46() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_not(decode); -} -void hyperstone_device::op47() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_subc() { - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_not(decode); -} + check_delay_PC(); -void hyperstone_device::op48() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_sub(decode); -} + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f); -void hyperstone_device::op49() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_sub(decode); -} + uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; + const uint32_t c = GET_C; -void hyperstone_device::op4a() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_sub(decode); -} + uint32_t old_z = SR & Z_MASK; + SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); -void hyperstone_device::op4b() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_sub(decode); -} + if (SRC_GLOBAL && (src_code == SR_REGISTER)) + { + const uint64_t tmp = uint64_t(dreg) - uint64_t(c); + SR |= ((tmp ^ dreg) & dreg & 0x80000000) >> 28; + SR |= (tmp & 0x100000000) >> 32; + dreg -= c; + } + else + { + const uint32_t sreg = (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code]; + const uint64_t tmp = uint64_t(dreg) - (uint64_t(sreg) + uint64_t(c)); + //CHECK! + const uint32_t sreg_c = sreg + c; + SR |= ((tmp ^ dreg) & (dreg ^ sreg_c) & 0x80000000) >> 28; + SR |= (tmp & 0x100000000) >> 32; + dreg -= sreg_c; + } -void hyperstone_device::op4c() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_subs(decode); -} + if (DST_GLOBAL) + set_global_register(DST_CODE, dreg); + else + m_local_regs[dst_code] = dreg; -void hyperstone_device::op4d() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_subs(decode); -} + if (old_z && dreg == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(dreg); -void hyperstone_device::op4e() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_subs(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op4f() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_not() { - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_subs(decode); -} + check_delay_PC(); + const uint32_t dreg = ~(SRC_GLOBAL ? m_global_regs[SRC_CODE] : m_local_regs[(SRC_CODE + GET_FP) & 0x3f]); + if (DST_GLOBAL) + set_global_register(DST_CODE, dreg); + else + m_local_regs[(DST_CODE + GET_FP) & 0x3f] = dreg; + if (dreg == 0) + SR |= Z_MASK; + else + SR &= ~Z_MASK; -void hyperstone_device::op50() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_addc(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op51() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_sub() { - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_addc(decode); -} + check_delay_PC(); -void hyperstone_device::op52() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_addc(decode); -} + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f); -void hyperstone_device::op53() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_addc(decode); -} + const uint32_t sreg = SRC_GLOBAL ? ((src_code == SR_REGISTER) ? GET_C : m_global_regs[src_code]) : m_local_regs[src_code]; + uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; -void hyperstone_device::op54() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_and(decode); -} + const uint64_t tmp = uint64_t(dreg) - uint64_t(sreg); -void hyperstone_device::op55() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_and(decode); -} + SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); -void hyperstone_device::op56() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_and(decode); -} + SR |= (tmp & 0x100000000) >> 32; + SR |= ((tmp ^ dreg) & (dreg ^ sreg) & 0x80000000) >> 28; -void hyperstone_device::op57() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_and(decode); -} + dreg -= sreg; + if (DST_GLOBAL) + { + set_global_register(dst_code, dreg); -void hyperstone_device::op58() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_neg(decode); -} + if (dst_code == PC_REGISTER) + SR &= ~M_MASK; + } + else + { + m_local_regs[dst_code] = dreg; + } -void hyperstone_device::op59() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_neg(decode); -} + if (dreg == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(dreg); -void hyperstone_device::op5a() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_neg(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op5b() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_subs() { - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_neg(decode); -} + check_delay_PC(); -void hyperstone_device::op5c() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_negs(decode); -} + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f); -void hyperstone_device::op5d() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_negs(decode); -} + const int32_t sreg = int32_t(SRC_GLOBAL ? ((src_code == SR_REGISTER) ? GET_C : m_global_regs[src_code]) : m_local_regs[src_code]); + int32_t dreg = int32_t((DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]); + const int64_t tmp = int64_t(dreg) - int64_t(sreg); -void hyperstone_device::op5e() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_negs(decode); -} + SR &= ~(V_MASK | Z_MASK | N_MASK); -void hyperstone_device::op5f() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_negs(decode); -} +//#ifdef SETCARRYS +// CHECK_C(tmp); +//#endif + SR |= ((tmp ^ dreg) & (dreg ^ sreg) & 0x80000000) >> 28; + const int32_t res = dreg - sreg; + if (DST_GLOBAL) + set_global_register(dst_code, res); + else + m_local_regs[dst_code] = res; -void hyperstone_device::op60() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 0, 0); - hyperstone_cmpi(decode); -} + if (res == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(res); -void hyperstone_device::op61() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 0, 1); - hyperstone_cmpi(decode); -} + m_icount -= m_clock_cycles_1; -void hyperstone_device::op62() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 1, 0); - hyperstone_cmpi(decode); + if (SR & V_MASK) + execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR)); } -void hyperstone_device::op63() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 1, 1); - hyperstone_cmpi(decode); -} -void hyperstone_device::op64() -{ - LOCAL_DECODE_INIT; - RimmdecodewithHflag(decode, 0, 0); - hyperstone_movi(decode); -} -void hyperstone_device::op65() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_addc() { - LOCAL_DECODE_INIT; - RimmdecodewithHflag(decode, 0, 1); - hyperstone_movi(decode); -} + check_delay_PC(); -void hyperstone_device::op66() -{ - LOCAL_DECODE_INIT; - RimmdecodewithHflag(decode, 1, 0); - hyperstone_movi(decode); -} + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f); -void hyperstone_device::op67() -{ - LOCAL_DECODE_INIT; - RimmdecodewithHflag(decode, 1, 1); - hyperstone_movi(decode); -} + const uint32_t sreg = (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code]; + uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; -void hyperstone_device::op68() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 0, 0); - hyperstone_addi(decode); -} + const bool old_z = (SR & Z_MASK) != 0; + const uint32_t c = GET_C; -void hyperstone_device::op69() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 0, 1); - hyperstone_addi(decode); -} + SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); -void hyperstone_device::op6a() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 1, 0); - hyperstone_addi(decode); -} + uint64_t tmp; + if (SRC_GLOBAL && (src_code == SR_REGISTER)) + { + tmp = uint64_t(dreg) + uint64_t(c); + SR |= ((dreg ^ tmp) & (c ^ tmp) & 0x80000000) >> 28; + dreg += c; + } + else + { + tmp = uint64_t(sreg) + uint64_t(dreg) + uint64_t(c); + SR |= ((sreg ^ tmp) & (dreg ^ tmp) & (c ^ tmp) & 0x80000000) >> 28; + dreg += sreg + c; + } -void hyperstone_device::op6b() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 1, 1); - hyperstone_addi(decode); -} + SR |= (tmp & 0x100000000) >> 32; -void hyperstone_device::op6c() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 0, 0); - hyperstone_addsi(decode); -} + if (DST_GLOBAL) + set_global_register(dst_code, dreg); + else + m_local_regs[dst_code] = dreg; -void hyperstone_device::op6d() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 0, 1); - hyperstone_addsi(decode); -} + if (dreg == 0 && old_z) + SR |= Z_MASK; + SR |= SIGN_TO_N(dreg); -void hyperstone_device::op6e() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 1, 0); - hyperstone_addsi(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op6f() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_and() { - LOCAL_DECODE_INIT; - Rimmdecode(decode, 1, 1); - hyperstone_addsi(decode); -} + check_delay_PC(); + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f); + const uint32_t sreg = SRC_GLOBAL ? m_global_regs[SRC_CODE] : m_local_regs[(SRC_CODE + GET_FP) & 0x3f]; + const uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] & sreg; + if (DST_GLOBAL) + set_global_register(dst_code, dreg); + else + m_local_regs[dst_code] = dreg; + if (dreg == 0) + SR |= Z_MASK; + else + SR &= ~Z_MASK; -void hyperstone_device::op70() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 0, 0); - hyperstone_cmpbi(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op71() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_neg() { - LOCAL_DECODE_INIT; - Rimmdecode(decode, 0, 1); - hyperstone_cmpbi(decode); -} + check_delay_PC(); -void hyperstone_device::op72() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 1, 0); - hyperstone_cmpbi(decode); -} + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); -void hyperstone_device::op73() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 1, 1); - hyperstone_cmpbi(decode); -} + const uint32_t sreg = SRC_GLOBAL ? ((src_code == SR_REGISTER) ? GET_C : m_global_regs[src_code]) : m_local_regs[src_code]; + const uint64_t tmp = -uint64_t(sreg); -void hyperstone_device::op74() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 0, 0); - hyperstone_andni(decode); -} + SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); + SR |= (tmp & 0x100000000) >> 32; + SR |= (tmp & sreg & 0x80000000) >> 28; -void hyperstone_device::op75() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 0, 1); - hyperstone_andni(decode); -} + const uint32_t dreg = -sreg; + if (DST_GLOBAL) + set_global_register(DST_CODE, dreg); + else + m_local_regs[(DST_CODE + fp) & 0x3f] = dreg; -void hyperstone_device::op76() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 1, 0); - hyperstone_andni(decode); -} + if (dreg == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(dreg); -void hyperstone_device::op77() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 1, 1); - hyperstone_andni(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op78() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_negs() { - LOCAL_DECODE_INIT; - Rimmdecode(decode, 0, 0); - hyperstone_ori(decode); -} + check_delay_PC(); -void hyperstone_device::op79() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 0, 1); - hyperstone_ori(decode); -} + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); -void hyperstone_device::op7a() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 1, 0); - hyperstone_ori(decode); -} + const int32_t sreg = int32_t(SRC_GLOBAL ? ((src_code == SR_REGISTER) ? GET_C : m_global_regs[src_code]) : m_local_regs[src_code]); + const int64_t tmp = -int64_t(sreg); -void hyperstone_device::op7b() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 1, 1); - hyperstone_ori(decode); -} + SR &= ~(V_MASK | Z_MASK | N_MASK); -void hyperstone_device::op7c() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 0, 0); - hyperstone_xori(decode); -} + if (tmp & sreg & 0x80000000) + SR |= V_MASK; -void hyperstone_device::op7d() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 0, 1); - hyperstone_xori(decode); -} +//#if SETCARRYS +// CHECK_C(tmp); +//#endif -void hyperstone_device::op7e() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 1, 0); - hyperstone_xori(decode); -} + const int32_t res = -sreg; + if (DST_GLOBAL) + set_global_register(DST_CODE, res); + else + m_local_regs[(DST_CODE + fp) & 0x3f] = res; -void hyperstone_device::op7f() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 1, 1); - hyperstone_xori(decode); + if (res == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(res); + + m_icount -= m_clock_cycles_1; + + if (GET_V) + execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR)); } -void hyperstone_device::op80() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG> +void hyperstone_device::hyperstone_cmpi() { - LOCAL_DECODE_INIT; - Lndecode(decode); - hyperstone_shrdi(decode); -} + uint32_t imm; + if (IMM_LONG) + imm = decode_immediate_s(); -void hyperstone_device::op81() -{ - LOCAL_DECODE_INIT; - Lndecode(decode); - hyperstone_shrdi(decode); -} + check_delay_PC(); -void hyperstone_device::op82() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_shrd(decode); -} + if (!IMM_LONG) + imm = immediate_values[m_op & 0x0f]; + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f); + const uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; -void hyperstone_device::op83() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_shr(decode); -} + SR &= ~(V_MASK | Z_MASK | N_MASK | C_MASK); -void hyperstone_device::op84() -{ - LOCAL_DECODE_INIT; - Lndecode(decode); - hyperstone_sardi(decode); -} + uint64_t tmp = (uint64_t)dreg - (uint64_t)imm; + SR |= ((tmp ^ dreg) & (dreg ^ imm) & 0x80000000) >> 28; -void hyperstone_device::op85() -{ - LOCAL_DECODE_INIT; - Lndecode(decode); - hyperstone_sardi(decode); -} + if (dreg == imm) + SR |= Z_MASK; -void hyperstone_device::op86() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_sard(decode); -} + if ((int32_t)dreg < (int32_t)imm) + SR |= N_MASK; -void hyperstone_device::op87() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_sar(decode); -} + if (dreg < imm) + SR |= C_MASK; -void hyperstone_device::op88() -{ - LOCAL_DECODE_INIT; - Lndecode(decode); - hyperstone_shldi(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op89() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG> +void hyperstone_device::hyperstone_movi() { - LOCAL_DECODE_INIT; - Lndecode(decode); - hyperstone_shldi(decode); -} + uint32_t imm; + if (IMM_LONG) + imm = decode_immediate_s(); + check_delay_PC(); -void hyperstone_device::op8a() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_shld(decode); -} + if (!IMM_LONG) + imm = immediate_values[m_op & 0x0f]; -void hyperstone_device::op8b() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_shl(decode); -} + const bool h = (SR & H_MASK) != 0; + if (DST_GLOBAL && h && !(SR & S_MASK)) + { + execute_exception(get_trap_addr(TRAPNO_PRIVILEGE_ERROR)); + } + else + { + if (DST_GLOBAL) + { + const uint32_t dst_code = DST_CODE + (h ? 16 : 0); + set_global_register(dst_code, imm); -void hyperstone_device::op8c() -{ - LOCAL_DECODE_INIT; - no_decode(decode); - reserved(decode); -} + if (dst_code == PC_REGISTER) + SR &= ~M_MASK; + } + else + { + m_local_regs[(DST_CODE + GET_FP) & 0x3f] = imm; + } -void hyperstone_device::op8d() -{ - LOCAL_DECODE_INIT; - no_decode(decode); - reserved(decode); -} + SR &= ~(Z_MASK | N_MASK); + if (imm == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(imm); -void hyperstone_device::op8e() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_testlz(decode); +#if MISSIONCRAFT_FLAGS + SR &= ~V_MASK; // or V undefined ? +#endif + } + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op8f() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG> +void hyperstone_device::hyperstone_addi() { - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_rol(decode); -} + uint32_t imm; + if (IMM_LONG) + imm = decode_immediate_s(); + check_delay_PC(); + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f); + uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; + if (!N_OP_MASK) + imm = GET_C & (((SR & Z_MASK) ? 0 : 1) | (dreg & 0x01)); + else if (!IMM_LONG) + imm = immediate_values[m_op & 0x0f]; -void hyperstone_device::op90() -{ - LOCAL_DECODE_INIT; - RRdisdecode(decode, 0, 0); - hyperstone_ldxx1(decode); -} + SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); -void hyperstone_device::op91() -{ - LOCAL_DECODE_INIT; - RRdisdecode(decode, 0, 1); - hyperstone_ldxx1(decode); -} + const uint64_t tmp = (uint64_t)imm + (uint64_t)dreg; -void hyperstone_device::op92() -{ - LOCAL_DECODE_INIT; - RRdisdecode(decode, 1, 0); - hyperstone_ldxx1(decode); -} + SR |= (tmp & 0x100000000) >> 32; + SR |= ((imm ^ tmp) & (dreg ^ tmp) & 0x80000000) >> 28; -void hyperstone_device::op93() -{ - LOCAL_DECODE_INIT; - RRdisdecode(decode, 1, 1); - hyperstone_ldxx1(decode); -} + dreg += imm; + if (DST_GLOBAL) + { + set_global_register(dst_code, dreg); -void hyperstone_device::op94() -{ - LOCAL_DECODE_INIT; - RRdisdecode(decode, 0, 0); - hyperstone_ldxx2(decode); -} + if (dst_code == 0) + SR &= ~M_MASK; + } + else + { + m_local_regs[dst_code] = dreg; + } + + if (dreg == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(dreg); + + m_icount -= m_clock_cycles_1; +} + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG> +void hyperstone_device::hyperstone_addsi() +{ + if (!IMM_LONG) + check_delay_PC(); + + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f); + const int32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; + + int32_t imm; + if (N_OP_MASK) + { + if (IMM_LONG) + { + imm = decode_immediate_s(); + check_delay_PC(); + } + else + { + imm = immediate_values[m_op & 0x0f]; + } + } + else + { + if (IMM_LONG) + { + ignore_immediate_s(); + check_delay_PC(); + } + imm = SR & (((SR & Z_MASK) ? 0 : 1) | (dreg & 0x01)); + } + + SR &= ~(V_MASK | Z_MASK | N_MASK); + + const int64_t tmp = (int64_t)imm + (int64_t)(int32_t)dreg; + SR |= ((imm ^ tmp) & (dreg ^ tmp) & 0x80000000) >> 28; + +//#if SETCARRYS +// CHECK_C(tmp); +//#endif + + const int32_t res = imm + (int32_t)dreg; + + if (DST_GLOBAL) + set_global_register(dst_code, res); + else + m_local_regs[dst_code] = res; + + if (res == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(res); + + m_icount -= m_clock_cycles_1; + + if (SR & V_MASK) + execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR)); +} + + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG> +void hyperstone_device::hyperstone_cmpbi() +{ + if (!IMM_LONG) + check_delay_PC(); + + const uint32_t dreg = DST_GLOBAL ? m_global_regs[DST_CODE] : m_local_regs[(DST_CODE + GET_FP) & 0x3f]; + + const uint32_t n = N_VALUE; + if (n) + { + uint32_t imm; + if (n == 31) + { + if (IMM_LONG) + { + ignore_immediate_s(); + check_delay_PC(); + } + imm = 0x7fffffff; // bit 31 = 0, others = 1 + } + else + { + if (IMM_LONG) + { + imm = decode_immediate_s(); + check_delay_PC(); + } + else + { + imm = immediate_values[m_op & 0x0f]; + } + } + + if (dreg & imm) + SR &= ~Z_MASK; + else + SR |= Z_MASK; + } + else + { + if (IMM_LONG) + { + ignore_immediate_s(); + check_delay_PC(); + } + if ((dreg & 0xff000000) == 0 || (dreg & 0x00ff0000) == 0 || (dreg & 0x0000ff00) == 0 || (dreg & 0x000000ff) == 0) + SR |= Z_MASK; + else + SR &= ~Z_MASK; + } + + m_icount -= m_clock_cycles_1; +} + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG> +void hyperstone_device::hyperstone_andni() +{ + uint32_t imm; + if (IMM_LONG) + imm = decode_immediate_s(); + + check_delay_PC(); + + if (N_OP_MASK == 0x10f) + imm = 0x7fffffff; // bit 31 = 0, others = 1 + else if (!IMM_LONG) + imm = immediate_values[m_op & 0x0f]; + + uint32_t dreg; + if (DST_GLOBAL) + { + const uint32_t dst_code = DST_CODE; + dreg = m_global_regs[dst_code] & ~imm; + set_global_register(dst_code, dreg); + } + else + { + const uint32_t dst_code = (DST_CODE + GET_FP) & 0x3f; + dreg = m_local_regs[dst_code] & ~imm; + m_local_regs[dst_code] = dreg; + } + + if (dreg == 0) + SR |= Z_MASK; + else + SR &= ~Z_MASK; + + m_icount -= m_clock_cycles_1; +} + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG> +void hyperstone_device::hyperstone_ori() +{ + uint32_t imm; + if (IMM_LONG) + imm = decode_immediate_s(); + + check_delay_PC(); + + if (!IMM_LONG) + imm = immediate_values[m_op & 0x0f]; + uint32_t dreg; + if (DST_GLOBAL) + { + const uint32_t dst_code = DST_CODE; + dreg = m_global_regs[dst_code] | imm; + set_global_register(dst_code, dreg); + } + else + { + const uint32_t dst_code = (DST_CODE + GET_FP) & 0x3f; + dreg = m_local_regs[dst_code] |= imm; + } + + if (dreg) + SR &= ~Z_MASK; + else + SR |= Z_MASK; + + m_icount -= m_clock_cycles_1; +} + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG> +void hyperstone_device::hyperstone_xori() +{ + uint32_t imm; + if (IMM_LONG) + imm = decode_immediate_s(); -void hyperstone_device::op95() -{ - LOCAL_DECODE_INIT; - RRdisdecode(decode, 0, 1); - hyperstone_ldxx2(decode); -} + check_delay_PC(); -void hyperstone_device::op96() -{ - LOCAL_DECODE_INIT; - RRdisdecode(decode, 1, 0); - hyperstone_ldxx2(decode); -} + if (!IMM_LONG) + imm = immediate_values[m_op & 0x0f]; + uint32_t dreg; + if (DST_GLOBAL) + { + const uint32_t dst_code = DST_CODE; + dreg = m_global_regs[dst_code] ^ imm; + set_global_register(dst_code, dreg); + } + else + { + const uint32_t dst_code = (DST_CODE + GET_FP) & 0x3f; + dreg = m_local_regs[dst_code] ^= imm; + } -void hyperstone_device::op97() -{ - LOCAL_DECODE_INIT; - RRdisdecode(decode, 1, 1); - hyperstone_ldxx2(decode); -} + if (dreg) + SR &= ~Z_MASK; + else + SR |= Z_MASK; -void hyperstone_device::op98() -{ - LOCAL_DECODE_INIT; - RRdisdecode(decode, 0, 0); - hyperstone_stxx1(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op99() -{ - LOCAL_DECODE_INIT; - RRdisdecode(decode, 0, 1); - hyperstone_stxx1(decode); -} -void hyperstone_device::op9a() +template <hyperstone_device::shift_type HI_N> +void hyperstone_device::hyperstone_shrdi() { - LOCAL_DECODE_INIT; - RRdisdecode(decode, 1, 0); - hyperstone_stxx1(decode); -} + check_delay_PC(); -void hyperstone_device::op9b() -{ - LOCAL_DECODE_INIT; - RRdisdecode(decode, 1, 1); - hyperstone_stxx1(decode); -} + const uint32_t fp = GET_FP; + const uint32_t code = DST_CODE; + const uint32_t dst_code = (code + fp) & 0x3f; + const uint32_t dstf_code = (code + 1 + fp) & 0x3f; + uint32_t high_order = m_local_regs[dst_code]; + const uint32_t low_order = m_local_regs[dstf_code]; -void hyperstone_device::op9c() -{ - LOCAL_DECODE_INIT; - RRdisdecode(decode, 0, 0); - hyperstone_stxx2(decode); -} + uint64_t val = concat_64(high_order, low_order); -void hyperstone_device::op9d() -{ - LOCAL_DECODE_INIT; - RRdisdecode(decode, 0, 1); - hyperstone_stxx2(decode); -} + SR &= ~(C_MASK | Z_MASK | N_MASK); -void hyperstone_device::op9e() -{ - LOCAL_DECODE_INIT; - RRdisdecode(decode, 1, 0); - hyperstone_stxx2(decode); -} + const uint32_t n = HI_N ? HI_N_VALUE : LO_N_VALUE; + if (HI_N || n) + { + SR |= (val >> (n - 1)) & 1; -void hyperstone_device::op9f() -{ - LOCAL_DECODE_INIT; - RRdisdecode(decode, 1, 1); - hyperstone_stxx2(decode); -} + val >>= n; + } + high_order = extract_64hi(val); + m_local_regs[dst_code] = high_order; + m_local_regs[dstf_code] = extract_64lo(val); -void hyperstone_device::opa0() -{ - LOCAL_DECODE_INIT; - Rndecode(decode, 0); - hyperstone_shri(decode); -} + if (val == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(high_order); -void hyperstone_device::opa1() -{ - LOCAL_DECODE_INIT; - Rndecode(decode, 0); - hyperstone_shri(decode); + m_icount -= m_clock_cycles_2; } -void hyperstone_device::opa2() -{ - LOCAL_DECODE_INIT; - Rndecode(decode, 1); - hyperstone_shri(decode); -} -void hyperstone_device::opa3() +void hyperstone_device::hyperstone_shrd() { - LOCAL_DECODE_INIT; - Rndecode(decode, 1); - hyperstone_shri(decode); -} + check_delay_PC(); -void hyperstone_device::opa4() -{ - LOCAL_DECODE_INIT; - Rndecode(decode, 0); - hyperstone_sari(decode); -} + const uint32_t fp = GET_FP; + const uint32_t src_code = (SRC_CODE + fp) & 0x3f; + const uint32_t d_code = DST_CODE; + const uint32_t dst_code = (d_code + fp) & 0x3f; + const uint32_t dstf_code = (d_code + 1 + fp) & 0x3f; -void hyperstone_device::opa5() -{ - LOCAL_DECODE_INIT; - Rndecode(decode, 0); - hyperstone_sari(decode); -} + if (src_code == dst_code || src_code == dstf_code) + { + m_icount -= m_clock_cycles_2; + return; + } -void hyperstone_device::opa6() -{ - LOCAL_DECODE_INIT; - Rndecode(decode, 1); - hyperstone_sari(decode); -} + uint64_t val = concat_64(m_local_regs[dst_code], m_local_regs[dstf_code]); -void hyperstone_device::opa7() -{ - LOCAL_DECODE_INIT; - Rndecode(decode, 1); - hyperstone_sari(decode); -} + SR &= ~(C_MASK | Z_MASK | N_MASK); -void hyperstone_device::opa8() -{ - LOCAL_DECODE_INIT; - Rndecode(decode, 0); - hyperstone_shli(decode); -} + const uint32_t n = m_local_regs[src_code] & 0x1f; -void hyperstone_device::opa9() -{ - LOCAL_DECODE_INIT; - Rndecode(decode, 0); - hyperstone_shli(decode); -} + if (n) + { + SR |= (val >> (n - 1)) & 1; + val >>= n; + } -void hyperstone_device::opaa() -{ - LOCAL_DECODE_INIT; - Rndecode(decode, 1); - hyperstone_shli(decode); -} + m_local_regs[dst_code] = (uint32_t)(val >> 32); + m_local_regs[dstf_code] = (uint32_t)val; -void hyperstone_device::opab() -{ - LOCAL_DECODE_INIT; - Rndecode(decode, 1); - hyperstone_shli(decode); -} + if (val == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(m_local_regs[dst_code]); -void hyperstone_device::opac() -{ - LOCAL_DECODE_INIT; - no_decode(decode); - reserved(decode); + m_icount -= m_clock_cycles_2; } -void hyperstone_device::opad() +void hyperstone_device::hyperstone_shr() { - LOCAL_DECODE_INIT; - no_decode(decode); - reserved(decode); -} + check_delay_PC(); -void hyperstone_device::opae() -{ - LOCAL_DECODE_INIT; - no_decode(decode); - reserved(decode); -} + const uint32_t fp = GET_FP; + const uint32_t dst_code = (DST_CODE + fp) & 0x3f; + const uint32_t n = m_local_regs[(SRC_CODE + fp) & 0x3f] & 0x1f; + uint32_t dreg = m_local_regs[dst_code]; -void hyperstone_device::opaf() -{ - LOCAL_DECODE_INIT; - no_decode(decode); - reserved(decode); -} + SR &= ~(C_MASK | Z_MASK | N_MASK); + if (n && (dreg & (1 << (n - 1)))) + SR |= C_MASK; + dreg >>= n; -void hyperstone_device::opb0() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_mulu(decode); -} + m_local_regs[dst_code] = dreg; + if (dreg == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(dreg); -void hyperstone_device::opb1() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_mulu(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::opb2() +template <hyperstone_device::shift_type HI_N> +void hyperstone_device::hyperstone_sardi() { - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_mulu(decode); -} + check_delay_PC(); -void hyperstone_device::opb3() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_mulu(decode); -} + const uint32_t dst_code = (DST_CODE + GET_FP) & 0x3f; + const uint32_t dstf_code = (dst_code + 1) & 0x3f; -void hyperstone_device::opb4() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_muls(decode); -} + uint64_t val = concat_64(m_local_regs[dst_code], m_local_regs[dstf_code]); -void hyperstone_device::opb5() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_muls(decode); -} + SR &= ~(C_MASK | Z_MASK | N_MASK); -void hyperstone_device::opb6() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_muls(decode); -} + const uint32_t n = HI_N ? HI_N_VALUE : LO_N_VALUE; + if (HI_N || n) + { + SR |= (val >> (n - 1)) & 1; -void hyperstone_device::opb7() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_muls(decode); -} + const uint64_t sign_bit = val >> 63; + val >>= n; -void hyperstone_device::opb8() -{ - LOCAL_DECODE_INIT; - Rndecode(decode, 0); - hyperstone_set(decode); -} + if (sign_bit) + val |= 0xffffffff00000000U << (32 - n); + } -void hyperstone_device::opb9() -{ - LOCAL_DECODE_INIT; - Rndecode(decode, 0); - hyperstone_set(decode); -} + m_local_regs[dst_code] = (uint32_t)(val >> 32); + m_local_regs[dstf_code] = (uint32_t)val; -void hyperstone_device::opba() -{ - LOCAL_DECODE_INIT; - Rndecode(decode, 1); - hyperstone_set(decode); -} + if (val == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(m_local_regs[dst_code]); -void hyperstone_device::opbb() -{ - LOCAL_DECODE_INIT; - Rndecode(decode, 1); - hyperstone_set(decode); + m_icount -= m_clock_cycles_2; } -void hyperstone_device::opbc() +void hyperstone_device::hyperstone_sard() { - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_mul(decode); -} + check_delay_PC(); -void hyperstone_device::opbd() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_mul(decode); -} + const uint32_t fp = GET_FP; + const uint32_t src_code = (SRC_CODE + fp) & 0x3f; + const uint32_t d_code = DST_CODE; + const uint32_t dst_code = (d_code + fp) & 0x3f; + const uint32_t dstf_code = (d_code + 1 + fp) & 0x3f; -void hyperstone_device::opbe() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_mul(decode); -} + if (src_code == dst_code || src_code == dstf_code) + { + m_icount -= m_clock_cycles_2; + return; + } -void hyperstone_device::opbf() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_mul(decode); -} + uint64_t val = concat_64(m_local_regs[dst_code], m_local_regs[dstf_code]); + SR &= ~(C_MASK | Z_MASK | N_MASK); + const uint32_t n = m_local_regs[src_code] & 0x1f; + if (n) + { + SR |= (val >> (n - 1)) & 1; -void hyperstone_device::opc0() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_fadd(decode); -} + uint32_t sign_bit = val >> 63; -void hyperstone_device::opc1() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_faddd(decode); -} + val >>= n; -void hyperstone_device::opc2() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_fsub(decode); -} + if (sign_bit) + { + val |= 0xffffffff00000000L << (32 - n); + } + } -void hyperstone_device::opc3() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_fsubd(decode); -} + m_local_regs[dst_code] = (uint32_t)(val >> 32); + m_local_regs[dstf_code] = (uint32_t)val; + if (val == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(m_local_regs[dst_code]); -void hyperstone_device::opc4() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_fmul(decode); + m_icount -= m_clock_cycles_2; } -void hyperstone_device::opc5() +void hyperstone_device::hyperstone_sar() { - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_fmuld(decode); -} + check_delay_PC(); -void hyperstone_device::opc6() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_fdiv(decode); -} + const uint32_t fp = GET_FP; + const uint32_t dst_code = (DST_CODE + fp) & 0x3f; -void hyperstone_device::opc7() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_fdivd(decode); -} + const uint32_t n = m_local_regs[(SRC_CODE + fp) & 0x3f] & 0x1f; + uint32_t ret = m_local_regs[dst_code]; -void hyperstone_device::opc8() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_fcmp(decode); -} + SR &= ~(C_MASK | Z_MASK | N_MASK); -void hyperstone_device::opc9() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_fcmpd(decode); -} + if (n) + { + const uint32_t sign_bit = ret & 0x80000000; -void hyperstone_device::opca() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_fcmpu(decode); -} + SR |= (ret >> (n - 1)) & 1; -void hyperstone_device::opcb() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_fcmpud(decode); -} + ret >>= n; -void hyperstone_device::opcc() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_fcvt(decode); -} + if (sign_bit) + ret |= 0xffffffff << (32 - n); + } -void hyperstone_device::opcd() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_fcvtd(decode); -} + m_local_regs[dst_code] = ret; -void hyperstone_device::opce() -{ - LOCAL_DECODE_INIT; - LLextdecode(decode); - hyperstone_extend(decode); + if (ret == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(ret); + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::opcf() +template <hyperstone_device::shift_type HI_N> +void hyperstone_device::hyperstone_shldi() { - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_do(decode); -} + check_delay_PC(); + const uint32_t fp = GET_FP; + const uint32_t code = DST_CODE; + const uint32_t dst_code = (code + fp) & 0x3f; + const uint32_t dstf_code = (code + 1 + fp) & 0x3f; + uint32_t high_order = m_local_regs[dst_code]; + uint32_t low_order = m_local_regs[dstf_code]; + uint64_t val = concat_64(high_order, low_order); -void hyperstone_device::opd0() -{ - LOCAL_DECODE_INIT; - LRdecode(decode, 0); - hyperstone_ldwr(decode); -} + SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); -void hyperstone_device::opd1() -{ - LOCAL_DECODE_INIT; - LRdecode(decode, 1); - hyperstone_ldwr(decode); -} + const uint32_t n = HI_N ? HI_N_VALUE : LO_N_VALUE; + if ((HI_N || n) && ((val << (n - 1)) & 0x8000000000000000U)) + SR |= C_MASK; -void hyperstone_device::opd2() -{ - LOCAL_DECODE_INIT; - LRdecode(decode, 0); - hyperstone_lddr(decode); -} + const uint64_t mask = ((1U << (32 - n)) - 1) ^ 0xffffffff; + const uint32_t tmp = high_order << n; -void hyperstone_device::opd3() -{ - LOCAL_DECODE_INIT; - LRdecode(decode, 1); - hyperstone_lddr(decode); -} + if (((high_order & mask) && (!(tmp & 0x80000000))) || (((high_order & mask) ^ mask) && (tmp & 0x80000000))) + SR |= V_MASK; -void hyperstone_device::opd4() -{ - LOCAL_DECODE_INIT; - LRdecode(decode, 0); - hyperstone_ldwp(decode); -} + val <<= n; -void hyperstone_device::opd5() -{ - LOCAL_DECODE_INIT; - LRdecode(decode, 1); - hyperstone_ldwp(decode); -} + high_order = extract_64hi(val); -void hyperstone_device::opd6() -{ - LOCAL_DECODE_INIT; - LRdecode(decode, 0); - hyperstone_lddp(decode); -} + m_local_regs[dst_code] = high_order; + m_local_regs[dstf_code] = extract_64lo(val); -void hyperstone_device::opd7() -{ - LOCAL_DECODE_INIT; - LRdecode(decode, 1); - hyperstone_lddp(decode); -} + if (val == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(high_order); -void hyperstone_device::opd8() -{ - LOCAL_DECODE_INIT; - LRdecode(decode, 0); - hyperstone_stwr(decode); + m_icount -= m_clock_cycles_2; } -void hyperstone_device::opd9() +void hyperstone_device::hyperstone_shld() { - LOCAL_DECODE_INIT; - LRdecode(decode, 1); - hyperstone_stwr(decode); -} + check_delay_PC(); -void hyperstone_device::opda() -{ - LOCAL_DECODE_INIT; - LRdecode(decode, 0); - hyperstone_stdr(decode); -} + const uint32_t fp = GET_FP; + const uint32_t d_code = DST_CODE; + uint32_t src_code = (SRC_CODE + fp) & 0x3f; + uint32_t dst_code = (d_code + fp) & 0x3f; + uint32_t dstf_code = (d_code + fp + 1) & 0x3f; -void hyperstone_device::opdb() -{ - LOCAL_DECODE_INIT; - LRdecode(decode, 1); - hyperstone_stdr(decode); -} + // result undefined if Ls denotes the same register as Ld or Ldf + if (src_code == dst_code || src_code == dstf_code) + { + LOG("Denoted same registers in hyperstone_shld. PC = %08X\n", PC); + m_icount -= m_clock_cycles_2; + return; + } -void hyperstone_device::opdc() -{ - LOCAL_DECODE_INIT; - LRdecode(decode, 0); - hyperstone_stwp(decode); -} + uint32_t n = m_local_regs[src_code & 0x3f] & 0x1f; + uint32_t high_order = m_local_regs[dst_code]; /* registers offset by frame pointer */ + uint32_t low_order = m_local_regs[dstf_code]; -void hyperstone_device::opdd() -{ - LOCAL_DECODE_INIT; - LRdecode(decode, 1); - hyperstone_stwp(decode); -} + uint64_t mask = ((((uint64_t)1) << (32 - n)) - 1) ^ 0xffffffff; -void hyperstone_device::opde() -{ - LOCAL_DECODE_INIT; - LRdecode(decode, 0); - hyperstone_stdp(decode); -} + uint64_t val = concat_64(high_order, low_order); -void hyperstone_device::opdf() -{ - LOCAL_DECODE_INIT; - LRdecode(decode, 1); - hyperstone_stdp(decode); -} + SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); + SR |= (n)?(((val<<(n-1))&0x8000000000000000U)?1:0):0; + uint32_t tmp = high_order << n; + if (((high_order & mask) && (!(tmp & 0x80000000))) || (((high_order & mask) ^ mask) && (tmp & 0x80000000))) + SR |= V_MASK; + val <<= n; -void hyperstone_device::ope0() -{ - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_dbv(decode); -} + m_local_regs[dst_code] = extract_64hi(val); + m_local_regs[dstf_code] = extract_64lo(val); -void hyperstone_device::ope1() -{ - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_dbnv(decode); -} + if (val == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(m_local_regs[dst_code]); -void hyperstone_device::ope2() -{ - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_dbe(decode); + m_icount -= m_clock_cycles_2; } -void hyperstone_device::ope3() +void hyperstone_device::hyperstone_shl() { - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_dbne(decode); -} + check_delay_PC(); -void hyperstone_device::ope4() -{ - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_dbc(decode); -} + const uint32_t fp = GET_FP; + uint32_t src_code = SRC_CODE + fp; + uint32_t dst_code = DST_CODE + fp; -void hyperstone_device::ope5() -{ - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_dbnc(decode); -} + uint32_t n = m_local_regs[src_code & 0x3f] & 0x1f; + uint32_t base = m_local_regs[dst_code & 0x3f]; /* registers offset by frame pointer */ + uint64_t mask = ((((uint64_t)1) << (32 - n)) - 1) ^ 0xffffffff; -void hyperstone_device::ope6() -{ - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_dbse(decode); -} + SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); -void hyperstone_device::ope7() -{ - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_dbht(decode); -} + SR |= (n)?(((base<<(n-1))&0x80000000)?1:0):0; + uint32_t ret = base << n; -void hyperstone_device::ope8() -{ - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_dbn(decode); -} + if (((base & mask) && (!(ret & 0x80000000))) || (((base & mask) ^ mask) && (ret & 0x80000000))) + SR |= V_MASK; -void hyperstone_device::ope9() -{ - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_dbnn(decode); -} + m_local_regs[dst_code & 0x3f] = ret; -void hyperstone_device::opea() -{ - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_dble(decode); + if (ret == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(ret); + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::opeb() +void hyperstone_device::hyperstone_testlz() { - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_dbgt(decode); + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t sreg = m_local_regs[(SRC_CODE + fp) & 0x3f]; + uint32_t zeros = 0; + for (uint32_t mask = 0x80000000; mask != 0; mask >>= 1 ) + { + if (sreg & mask) + break; + else + zeros++; + } + + m_local_regs[(DST_CODE + fp) & 0x3f] = zeros; + + m_icount -= m_clock_cycles_2; } -void hyperstone_device::opec() +void hyperstone_device::hyperstone_rol() { - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_dbr(decode); + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t dst_code = (DST_CODE + fp) & 0x3f; + + uint32_t n = m_local_regs[(SRC_CODE + fp) & 0x3f] & 0x1f; + uint32_t val = m_local_regs[dst_code]; + +#ifdef MISSIONCRAFT_FLAGS + const uint32_t base = val; + const uint64_t mask = ((1U << (32 - n)) - 1) ^ 0xffffffff; +#endif + + if (n) + val = (val << n) | (val >> (32 - n)); + +#ifdef MISSIONCRAFT_FLAGS + SR &= ~(V_MASK | Z_MASK | C_MASK); + if (((base & mask) && (!(val & 0x80000000))) || (((base & mask) ^ mask) && (val & 0x80000000))) + SR |= V_MASK; +#else + SR &= ~(Z_MASK | C_MASK | N_MASK); +#endif + + m_local_regs[dst_code] = val; + + if (val == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(val); + + m_icount -= m_clock_cycles_1; +} + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_ldxx1() +{ + uint16_t next_1 = READ_OP(PC); + PC += 2; + + const uint16_t sub_type = (next_1 & 0x3000) >> 12; + + uint32_t extra_s; + if (next_1 & 0x8000) + { + const uint16_t next_2 = READ_OP(PC); + PC += 2; + m_instruction_length = (3<<19); + + extra_s = next_2; + extra_s |= ((next_1 & 0xfff) << 16); + + if (next_1 & 0x4000) + extra_s |= 0xf0000000; + } + else + { + m_instruction_length = (2<<19); + extra_s = next_1 & 0xfff; + + if (next_1 & 0x4000) + extra_s |= 0xfffff000; + } + + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t srcf_code = SRC_GLOBAL ? (src_code + 1) : ((src_code + 1) & 0x3f); + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f); + + if (DST_GLOBAL && dst_code == SR_REGISTER) + { + switch (sub_type) + { + case 0: // LDBS.A + if (SRC_GLOBAL) + set_global_register(src_code, (int32_t)(int8_t)READ_B(extra_s)); + else + m_local_regs[src_code] = (int32_t)(int8_t)READ_B(extra_s); + break; + + case 1: // LDBU.A + if (SRC_GLOBAL) + m_global_regs[src_code] = READ_B(extra_s); + else + m_local_regs[src_code] = READ_B(extra_s); + break; + + case 2: + if (SRC_GLOBAL) + { + if (extra_s & 1) // LDHS.A + set_global_register(src_code, (int32_t)(int16_t)READ_HW(extra_s)); + else // LDHU.A + set_global_register(src_code, READ_HW(extra_s)); + } + else + { + if (extra_s & 1) // LDHS.A + m_local_regs[src_code] = (int32_t)(int16_t)READ_HW(extra_s); + else // LDHU.A + m_local_regs[src_code] = READ_HW(extra_s); + } + break; + + case 3: + switch (extra_s & 3) + { + case 0: // LDW.A + if (SRC_GLOBAL) + set_global_register(src_code, READ_W(extra_s)); + else + m_local_regs[src_code] = READ_W(extra_s); + break; + case 1: // LDD.A + if (SRC_GLOBAL) + { + set_global_register(src_code, READ_W(extra_s)); + set_global_register(srcf_code, READ_W(extra_s + 4)); + } + else + { + m_local_regs[src_code] = READ_W(extra_s); + m_local_regs[srcf_code] = READ_W(extra_s + 4); + } + m_icount -= m_clock_cycles_1; // extra cycle + break; + case 2: // LDW.IOA + if (SRC_GLOBAL) + set_global_register(src_code, IO_READ_W(extra_s)); + else + m_local_regs[src_code] = IO_READ_W(extra_s); + break; + case 3: // LDD.IOA + if (SRC_GLOBAL) + { + set_global_register(src_code, IO_READ_W(extra_s)); + set_global_register(srcf_code, IO_READ_W(extra_s + 4)); + } + else + { + m_local_regs[src_code] = IO_READ_W(extra_s); + m_local_regs[srcf_code] = IO_READ_W(extra_s + 4); + } + m_icount -= m_clock_cycles_1; // extra cycle + break; + } + break; + } + } + else + { + const uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; + switch (sub_type) + { + case 0: // LDBS.D + if (SRC_GLOBAL) + set_global_register(src_code, (int32_t)(int8_t)READ_B(dreg + extra_s)); + else + m_local_regs[src_code] = (int32_t)(int8_t)READ_B(dreg + extra_s); + break; + + case 1: // LDBU.D + if (SRC_GLOBAL) + set_global_register(src_code, READ_B(dreg + extra_s)); + else + m_local_regs[src_code] = READ_B(dreg + extra_s); + break; + + case 2: + if (SRC_GLOBAL) + { + if (extra_s & 1) + set_global_register(src_code, (int32_t)(int16_t)READ_HW(dreg + (extra_s & ~1))); + else + set_global_register(src_code, READ_HW(dreg + (extra_s & ~1))); + } + else + { + if (extra_s & 1) + m_local_regs[src_code] = (int32_t)(int16_t)READ_HW(dreg + (extra_s & ~1)); + else + m_local_regs[src_code] = READ_HW(dreg + (extra_s & ~1)); + } + break; + + case 3: + switch (extra_s & 3) + { + case 0: // LDW.D + if (SRC_GLOBAL) + set_global_register(src_code, READ_W(dreg + extra_s)); + else + m_local_regs[src_code] = READ_W(dreg + extra_s); + break; + case 1: // LDD.D + if (SRC_GLOBAL) + { + set_global_register(src_code, READ_W(dreg + (extra_s & ~1))); + set_global_register(srcf_code, READ_W(dreg + (extra_s & ~1) + 4)); + } + else + { + m_local_regs[src_code] = READ_W(dreg + (extra_s & ~1)); + m_local_regs[srcf_code] = READ_W(dreg + (extra_s & ~1) + 4); + } + m_icount -= m_clock_cycles_1; // extra cycle + break; + case 2: // LDW.IOD + if (SRC_GLOBAL) + set_global_register(src_code, IO_READ_W(dreg + (extra_s & ~3))); + else + m_local_regs[src_code] = IO_READ_W(dreg + (extra_s & ~3)); + break; + case 3: // LDD.IOD + if (SRC_GLOBAL) + { + set_global_register(src_code, IO_READ_W(dreg + (extra_s & ~3))); + set_global_register(srcf_code, IO_READ_W(dreg + (extra_s & ~3) + 4)); + } + else + { + m_local_regs[src_code] = IO_READ_W(dreg + (extra_s & ~3)); + m_local_regs[srcf_code] = IO_READ_W(dreg + (extra_s & ~3) + 4); + } + m_icount -= m_clock_cycles_1; // extra cycle + break; + } + break; + } + } + + m_icount -= m_clock_cycles_1; +} + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_ldxx2() +{ + uint16_t next_1 = READ_OP(PC); + PC += 2; + + const uint16_t sub_type = (next_1 & 0x3000) >> 12; + + uint32_t extra_s; + if (next_1 & 0x8000) + { + const uint16_t next_2 = READ_OP(PC); + PC += 2; + m_instruction_length = (3<<19); + + extra_s = next_2; + extra_s |= ((next_1 & 0xfff) << 16); + + if (next_1 & 0x4000) + extra_s |= 0xf0000000; + } + else + { + m_instruction_length = (2<<19); + extra_s = next_1 & 0xfff; + + if (next_1 & 0x4000) + extra_s |= 0xfffff000; + } + + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : (DST_CODE + fp) & 0x3f; + + if (DST_GLOBAL && dst_code < 2) + { + m_icount -= m_clock_cycles_1; + LOG("Denoted PC or SR in hyperstone_ldxx2. PC = %08X\n", PC); + return; + } + + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : (SRC_CODE + fp) & 0x3f; + const uint32_t srcf_code = SRC_GLOBAL ? (src_code + 1) : ((src_code + 1) & 0x3f); + const uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; + + switch (sub_type) + { + case 0: // LDBS.N + if (SRC_GLOBAL) + set_global_register(src_code, (int32_t)(int8_t)READ_B(dreg)); + else + m_local_regs[src_code] = (int32_t)(int8_t)READ_B(dreg); + if (DST_GLOBAL != SRC_GLOBAL || src_code != dst_code) + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] += extra_s; + break; + + case 1: // LDBU.N + if (SRC_GLOBAL) + set_global_register(src_code, READ_B(dreg)); + else + m_local_regs[src_code] = READ_B(dreg); + if(DST_GLOBAL != SRC_GLOBAL || src_code != dst_code) + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] += extra_s; + break; + + case 2: + if (SRC_GLOBAL) + { + if (extra_s & 1) // LDHS.N + set_global_register(src_code, (int32_t)(int16_t)READ_HW(dreg)); + else // LDHU.N + set_global_register(src_code, READ_HW(dreg)); + } + else + { + if (extra_s & 1) // LDHS.N + m_local_regs[src_code] = (int32_t)(int16_t)READ_HW(dreg); + else // LDHU.N + m_local_regs[src_code] = READ_HW(dreg); + } + + if(DST_GLOBAL != SRC_GLOBAL || src_code != dst_code) + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] += (extra_s & ~1); + break; + + case 3: + switch (extra_s & 3) + { + case 0: // LDW.N + if (SRC_GLOBAL) + set_global_register(src_code, READ_W(dreg)); + else + m_local_regs[src_code] = READ_W(dreg); + if(DST_GLOBAL != SRC_GLOBAL || src_code != dst_code) + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] += extra_s; + break; + case 1: // LDD.N + if (SRC_GLOBAL) + { + set_global_register(src_code, READ_W(dreg)); + set_global_register(srcf_code, READ_W(dreg + 4)); + } + else + { + m_local_regs[src_code] = READ_W(dreg); + m_local_regs[srcf_code] = READ_W(dreg + 4); + } + + if (DST_GLOBAL != SRC_GLOBAL || (src_code != dst_code && srcf_code != dst_code)) + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] += extra_s & ~1; + + m_icount -= m_clock_cycles_1; // extra cycle + break; + case 2: // Reserved + LOG("Executed Reserved instruction in hyperstone_ldxx2. PC = %08X\n", PC); + break; + case 3: // LDW.S + if (SRC_GLOBAL) + { + if (dreg < SP) + set_global_register(src_code, READ_W(dreg)); + else + set_global_register(src_code, m_local_regs[(dreg & 0xfc) >> 2]); + } + else + { + if (dreg < SP) + m_local_regs[src_code] = READ_W(dreg); + else + m_local_regs[src_code] = m_local_regs[(dreg & 0xfc) >> 2]; + } + + if (DST_GLOBAL != SRC_GLOBAL || src_code != dst_code) + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] += extra_s & ~3; + + m_icount -= m_clock_cycles_2; // extra cycles + break; + } + break; + } + + m_icount -= m_clock_cycles_1; +} + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_stxx1() +{ + uint16_t next_1 = READ_OP(PC); + PC += 2; + + const uint16_t sub_type = (next_1 & 0x3000) >> 12; + + uint32_t extra_s; + if (next_1 & 0x8000) + { + const uint16_t next_2 = READ_OP(PC); + PC += 2; + m_instruction_length = (3<<19); + + extra_s = next_2; + extra_s |= ((next_1 & 0xfff) << 16); + + if (next_1 & 0x4000) + extra_s |= 0xf0000000; + } + else + { + m_instruction_length = (2<<19); + extra_s = next_1 & 0xfff; + + if (next_1 & 0x4000) + extra_s |= 0xfffff000; + } + + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f); + const uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; + const uint32_t sreg = ((SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code]); + + if (DST_GLOBAL && dst_code == SR_REGISTER) + { + switch (sub_type) + { + case 0: // STBS.A + // TODO: missing trap on range error + WRITE_B(extra_s, (uint8_t)sreg); + break; + + case 1: // STBU.A + WRITE_B(extra_s, (uint8_t)sreg); + break; + + case 2: // STHS.A, STHU.A + WRITE_HW(extra_s, (uint16_t)sreg); + // TODO: missing trap on range error with STHS.A + break; + + case 3: + switch (extra_s & 3) + { + case 0: // STW.A + WRITE_W(extra_s & ~1, sreg); + break; + case 1: // STD.A + { + const uint32_t srcf_code = SRC_GLOBAL ? (src_code + 1) : ((src_code + 1) & 0x3f); + const uint32_t sregf = ((SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[srcf_code]); + extra_s &= ~1; + WRITE_W(extra_s, sreg); + WRITE_W(extra_s + 4, sregf); + m_icount -= m_clock_cycles_1; // extra cycle + break; + } + case 2: // STW.IOA + IO_WRITE_W(extra_s & ~3, sreg); + break; + case 3: // STD.IOA + { + const uint32_t srcf_code = SRC_GLOBAL ? (src_code + 1) : ((src_code + 1) & 0x3f); + const uint32_t sregf = ((SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[srcf_code]); + extra_s &= ~3; + IO_WRITE_W(extra_s, sreg); + IO_WRITE_W(extra_s + 4, sregf); + m_icount -= m_clock_cycles_1; // extra cycle + break; + } + } + break; + } + } + else + { + switch (sub_type) + { + case 0: // STBS.D + // TODO: missing trap on range error + WRITE_B(dreg + extra_s, (uint8_t)sreg); + break; + + case 1: // STBU.D + WRITE_B(dreg + extra_s, (uint8_t)sreg); + break; + + case 2: // STHS.D, STHU.D + WRITE_HW(dreg + (extra_s & ~1), (uint16_t)sreg); + // TODO: missing trap on range error with STHS.D + break; + + case 3: + switch (extra_s & 3) + { + case 0: // STW.D + WRITE_W(dreg + (extra_s & ~1), sreg); + break; + case 1: // STD.D + { + const uint32_t srcf_code = SRC_GLOBAL ? (src_code + 1) : ((src_code + 1) & 0x3f); + const uint32_t sregf = ((SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[srcf_code]); + extra_s &= ~1; + WRITE_W(dreg + extra_s, sreg); + WRITE_W(dreg + extra_s + 4, sregf); + m_icount -= m_clock_cycles_1; // extra cycle + break; + } + case 2: // STW.IOD + IO_WRITE_W(dreg + (extra_s & ~3), sreg); + break; + case 3: // STD.IOD + { + const uint32_t srcf_code = SRC_GLOBAL ? (src_code + 1) : ((src_code + 1) & 0x3f); + const uint32_t sregf = ((SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[srcf_code]); + extra_s &= ~3; + IO_WRITE_W(dreg + extra_s, sreg); + IO_WRITE_W(dreg + extra_s + 4, sregf); + m_icount -= m_clock_cycles_1; // extra cycle + break; + } + } + break; + } + } + + m_icount -= m_clock_cycles_1; +} + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_stxx2() +{ + uint16_t next_1 = READ_OP(PC); + PC += 2; + + const uint16_t sub_type = (next_1 & 0x3000) >> 12; + + uint32_t extra_s; + if (next_1 & 0x8000) + { + const uint16_t next_2 = READ_OP(PC); + PC += 2; + m_instruction_length = (3<<19); + + extra_s = next_2; + extra_s |= ((next_1 & 0xfff) << 16); + + if (next_1 & 0x4000) + extra_s |= 0xf0000000; + } + else + { + m_instruction_length = (2<<19); + extra_s = next_1 & 0xfff; + + if (next_1 & 0x4000) + extra_s |= 0xfffff000; + } + + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t sreg = (SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code]; + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f); + const uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; + + if (DST_GLOBAL && dst_code < 2) + { + m_icount -= m_clock_cycles_1; + return; + } + + switch (sub_type) + { + case 0: // STBS.N + // TODO: missing trap on range error + WRITE_B(dreg, (uint8_t)sreg); + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] += extra_s; + break; + + case 1: // STBU.N + WRITE_B(dreg, (uint8_t)sreg); + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] += extra_s; + break; + + case 2: // STHS.N, STHU.N + WRITE_HW(dreg, (uint16_t)sreg); + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] += extra_s & ~1; + // TODO: missing trap on range error with STHS.N + break; + + case 3: + switch (extra_s & 3) + { + case 0: // STW.N + WRITE_W(dreg, sreg); + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] += extra_s; + break; + case 1: // STD.N + { + const uint32_t srcf_code = SRC_GLOBAL ? (src_code + 1) : ((src_code + 1) & 0x3f); + const uint32_t sregf = (SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[srcf_code]; + WRITE_W(dreg, sreg); + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] += extra_s & ~1; + + if(DST_GLOBAL == SRC_GLOBAL && (src_code + 1) == dst_code) + WRITE_W(dreg + 4, sregf + (extra_s & ~1)); // because DREG == SREGF and DREG has been incremented + else + WRITE_W(dreg + 4, sregf); + + m_icount -= m_clock_cycles_1; // extra cycle + break; + } + case 2: // Reserved + LOG("Executed Reserved instruction in hyperstone_stxx2. PC = %08X\n", PC); + break; + case 3: // STW.S + if(dreg < SP) + WRITE_W(dreg, sreg); + else + m_local_regs[(dreg & 0xfc) >> 2] = sreg; + + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] += (extra_s & ~3); + + m_icount -= m_clock_cycles_2; // extra cycles + break; + } + break; + } + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::oped() +template <hyperstone_device::shift_type HI_N, hyperstone_device::reg_bank DST_GLOBAL> +void hyperstone_device::hyperstone_shri() { - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_frame(decode); + check_delay_PC(); + + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f); + uint32_t val = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; + + SR &= ~(C_MASK | Z_MASK | N_MASK); + + const uint32_t n = HI_N ? HI_N_VALUE : LO_N_VALUE; + if (HI_N || n) + SR |= (val >> (n - 1)) & 1; + + val >>= n; + + if (DST_GLOBAL) + set_global_register(dst_code, val); + else + m_local_regs[dst_code] = val; + + if (val == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(val); + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::opee() +template <hyperstone_device::shift_type HI_N, hyperstone_device::reg_bank DST_GLOBAL> +void hyperstone_device::hyperstone_sari() { - LOCAL_DECODE_INIT; - LRconstdecode(decode, 0); - hyperstone_call(decode); + check_delay_PC(); + + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f); + uint32_t val = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; + + const uint32_t n = HI_N ? HI_N_VALUE : LO_N_VALUE; + SR &= ~(C_MASK | Z_MASK | N_MASK); + + if (HI_N || n) + { + SR |= (val >> (n - 1)) & 1; + + uint32_t sign_bit = val & 0x80000000; + val >>= n; + + if (sign_bit) + val |= 0xffffffff << (32 - n); + } + + if (DST_GLOBAL) + set_global_register(dst_code, val); + else + m_local_regs[dst_code] = val; + + if (val == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(val); + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::opef() +template <hyperstone_device::shift_type HI_N, hyperstone_device::reg_bank DST_GLOBAL> +void hyperstone_device::hyperstone_shli() { - LOCAL_DECODE_INIT; - LRconstdecode(decode, 1); - hyperstone_call(decode); -} + check_delay_PC(); + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f); + uint32_t val = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; + const uint32_t n = HI_N ? HI_N_VALUE : LO_N_VALUE; + SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); + SR |= (HI_N || n) ? (((val << (n - 1)) & 0x80000000) ? 1 : 0) : 0; + uint64_t mask = ((1U << (32 - n)) - 1) ^ 0xffffffff; + uint32_t val2 = val << n; -void hyperstone_device::opf0() -{ - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_bv(decode); + if (((val & mask) && (!(val2 & 0x80000000))) || (((val & mask) ^ mask) && (val2 & 0x80000000))) + SR |= V_MASK; + + if (DST_GLOBAL) + set_global_register(dst_code, val2); + else + m_local_regs[dst_code] = val2; + + if (val2 == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(val2); + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::opf1() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL, hyperstone_device::sign_mode SIGNED> +void hyperstone_device::hyperstone_mulsu() { - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_bnv(decode); + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f); + const uint32_t dstf_code = DST_GLOBAL ? (dst_code + 1) : ((dst_code + 1) & 0x3f); + + if ((SRC_GLOBAL && src_code < 2) || (DST_GLOBAL && dst_code < 2)) + { + LOG("Denoted PC or SR in hyperstone_muls/u instruction. PC = %08X\n", PC); + return; + } + + const uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; + const uint32_t sreg = (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code]; + const uint64_t double_word = SIGNED ? (uint64_t)((int64_t)(int32_t)sreg * (int64_t)(int32_t)dreg) : ((uint64_t)sreg *(uint64_t)dreg); + + const uint32_t high_order = (uint32_t)(double_word >> 32); + + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] = high_order; + (DST_GLOBAL ? m_global_regs : m_local_regs)[dstf_code] = (uint32_t)double_word; + + SR &= ~(Z_MASK | N_MASK); + if (double_word == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(high_order); + + if(SIGNED == IS_SIGNED && (sreg >= 0xffff8000 && sreg <= 0x7fff) && (dreg >= 0xffff8000 && dreg <= 0x7fff)) + m_icount -= m_clock_cycles_4; + else if(SIGNED == IS_UNSIGNED && sreg <= 0xffff && dreg <= 0xffff) + m_icount -= m_clock_cycles_4; + else + m_icount -= m_clock_cycles_6; } -void hyperstone_device::opf2() -{ - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_be(decode); +template <hyperstone_device::shift_type HI_N, hyperstone_device::reg_bank DST_GLOBAL> +void hyperstone_device::hyperstone_set() +{ + check_delay_PC(); + + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f); + const uint32_t n = LO_N_VALUE; + + if (DST_GLOBAL && dst_code < 2) + { + m_icount -= m_clock_cycles_1; + return; + } + + if (HI_N) + { + if (n >= 4 || n == 2) + { + static const uint32_t set_result[16] = { 0, 0, 0, 0, 0xffffffff, 0, 0xffffffff, 0, 0xffffffff, 0, 0xffffffff, 0, 0xffffffff, 0, 0xffffffff, 0 }; + static const uint32_t unset_result[16] = { 0, 0, 0xffffffff, 0, 0, 0xffffffff, 0, 0xffffffff, 0, 0xffffffff, 0, 0xffffffff, 0, 0xffffffff, 0, 0xffffffff }; + static const uint32_t mask[16] = { 0, 0, 0, 0, (N_MASK | Z_MASK), (N_MASK | Z_MASK), N_MASK, N_MASK, + (C_MASK | Z_MASK), (C_MASK | Z_MASK), C_MASK, C_MASK, Z_MASK, Z_MASK, V_MASK, V_MASK }; + + if (SR & mask[n]) + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] = set_result[n]; + else + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] = unset_result[n]; + } + else + { + LOG("Used reserved N value (%d) in hyperstone_set. PC = %08X\n", n, PC); + } + } + else + { + if (n == 0) + { + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] = (SP & 0xfffffe00) | (GET_FP << 2) | (((SP & 0x100) && (SIGN_BIT(SR) == 0)) ? 1 : 0); + } + else if (n >= 2) + { + static const uint32_t set_result[16] = { 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 }; + static const uint32_t unset_result[16] = { 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 }; + static const uint32_t mask[16] = { 0, 0, 0, 0, (N_MASK | Z_MASK), (N_MASK | Z_MASK), N_MASK, N_MASK, + (C_MASK | Z_MASK), (C_MASK | Z_MASK), C_MASK, C_MASK, Z_MASK, Z_MASK, V_MASK, V_MASK }; + + if (SR & mask[n]) + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] = set_result[n]; + else + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] = unset_result[n]; + } + else + { + LOG("Used reserved N value (%d) in hyperstone_set. PC = %08X\n", n, PC); + } + } + + m_icount -= m_clock_cycles_1; +} + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_mul() +{ + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f); + + if ((SRC_GLOBAL && src_code < 2) || (DST_GLOBAL && dst_code < 2)) + { + LOG("Denoted PC or SR in hyperstone_mul instruction. PC = %08X\n", PC); + return; + } + + const uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; + const uint32_t sreg = (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code]; + const uint32_t result = sreg * dreg; + + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] = result; + + SR &= ~(Z_MASK | N_MASK); + if (result == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(result); + + if ((sreg >= 0xffff8000 && sreg <= 0x7fff) && (dreg >= 0xffff8000 && dreg <= 0x7fff)) + m_icount -= 3 << m_clck_scale; + else + m_icount -= 5 << m_clck_scale; +} + +void hyperstone_device::hyperstone_extend() +{ + m_instruction_length = (2<<19); + const uint32_t func = READ_OP(PC); + PC += 2; + check_delay_PC(); + + //TODO: add locks, overflow error and other things + const uint32_t fp = GET_FP; + const uint32_t vals = m_local_regs[(SRC_CODE + fp) & 0x3f]; + const uint32_t vald = m_local_regs[(DST_CODE + fp) & 0x3f]; + + switch (func) // extended opcode + { + // signed or unsigned multiplication, single word product + case EMUL: + case 0x100: // used in "N" type cpu + m_global_regs[15] = (uint32_t)(vals * vald); + break; + + // unsigned multiplication, double word product + case EMULU: + { + const uint64_t result = (uint64_t)vals * (uint64_t)vald; + m_global_regs[14] = (uint32_t)(result >> 32); + m_global_regs[15] = (uint32_t)result; + break; + } + // signed multiplication, double word product + case EMULS: + { + const int64_t result = (int64_t)(int32_t)vals * (int64_t)(int32_t)vald; + m_global_regs[14] = (uint32_t)(result >> 32); + m_global_regs[15] = (uint32_t)result; + + break; + } + + // signed multiply/add, single word product sum + case EMAC: + m_global_regs[15] += (int32_t)vals * (int32_t)vald; + break; + + // signed multiply/add, double word product sum + case EMACD: + { + int64_t result = (int64_t)concat_64(m_global_regs[14], m_global_regs[15]) + (int64_t)((int64_t)(int32_t)vals * (int64_t)(int32_t)vald); + m_global_regs[14] = (uint32_t)(result >> 32); + m_global_regs[15] = (uint32_t)result; + break; + } + // signed multiply/substract, single word product difference + case EMSUB: + m_global_regs[15] = (int32_t)m_global_regs[15] - ((int32_t)vals * (int32_t)vald); + break; + + // signed multiply/substract, double word product difference + case EMSUBD: + { + int64_t result = (int64_t)concat_64(m_global_regs[14], m_global_regs[15]) - (int64_t)((int64_t)(int32_t)vals * (int64_t)(int32_t)vald); + m_global_regs[14] = (uint32_t)(result >> 32); + m_global_regs[15] = (uint32_t)result; + + break; + } + + // signed half-word multiply/add, single word product sum + case EHMAC: + m_global_regs[15] = (int32_t)m_global_regs[15] + ((int32_t)((vald & 0xffff0000) >> 16) * (int32_t)((vals & 0xffff0000) >> 16)) + ((int32_t)(vald & 0xffff) * (int32_t)(vals & 0xffff)); + break; + + // signed half-word multiply/add, double word product sum + case EHMACD: + { + int64_t result = (int64_t)concat_64(m_global_regs[14], m_global_regs[15]) + (int64_t)((int64_t)(int32_t)((vald & 0xffff0000) >> 16) * (int64_t)(int32_t)((vals & 0xffff0000) >> 16)) + ((int64_t)(int32_t)(vald & 0xffff) * (int64_t)(int32_t)(vals & 0xffff)); + m_global_regs[14] = (uint32_t)(result >> 32); + m_global_regs[15] = (uint32_t)result; + break; + } + + // half-word complex multiply + case EHCMULD: + m_global_regs[14] = (((vald & 0xffff0000) >> 16) * ((vals & 0xffff0000) >> 16)) - ((vald & 0xffff) * (vals & 0xffff)); + m_global_regs[15] = (((vald & 0xffff0000) >> 16) * (vals & 0xffff)) + ((vald & 0xffff) * ((vals & 0xffff0000) >> 16)); + break; + + // half-word complex multiply/add + case EHCMACD: + m_global_regs[14] += (((vald & 0xffff0000) >> 16) * ((vals & 0xffff0000) >> 16)) - ((vald & 0xffff) * (vals & 0xffff)); + m_global_regs[15] += (((vald & 0xffff0000) >> 16) * (vals & 0xffff)) + ((vald & 0xffff) * ((vals & 0xffff0000) >> 16)); + break; + + // half-word (complex) add/substract + // Ls is not used and should denote the same register as Ld + case EHCSUMD: + { + const uint32_t r14 = m_global_regs[14]; + const uint32_t r15 = m_global_regs[15]; + m_global_regs[14] = (((((vals & 0xffff0000) >> 16) + r14) << 16) & 0xffff0000) | (((vals & 0xffff) + r15) & 0xffff); + m_global_regs[15] = (((((vals & 0xffff0000) >> 16) - r14) << 16) & 0xffff0000) | (((vals & 0xffff) - r15) & 0xffff); + break; + } + + // half-word (complex) add/substract with fixed point adjustment + // Ls is not used and should denote the same register as Ld + case EHCFFTD: + { + const uint32_t r14 = m_global_regs[14]; + const uint32_t r15 = m_global_regs[15]; + m_global_regs[14] = (((((vals & 0xffff0000) >> 16) + (r14 >> 15)) << 16) & 0xffff0000) | (((vals & 0xffff) + (r15 >> 15)) & 0xffff); + m_global_regs[15] = (((((vals & 0xffff0000) >> 16) - (r14 >> 15)) << 16) & 0xffff0000) | (((vals & 0xffff) - (r15 >> 15)) & 0xffff); + break; + } + + // half-word (complex) add/substract with fixed point adjustment and shift + // Ls is not used and should denote the same register as Ld + case EHCFFTSD: + { + const uint32_t r14 = m_global_regs[14]; + const uint32_t r15 = m_global_regs[15]; + m_global_regs[14] = ((((((vals & 0xffff0000) >> 16) + (r14 >> 15)) >> 1) << 16) & 0xffff0000) | (((((vals & 0xffff) + (r15 >> 15)) >> 1) & 0xffff)); + m_global_regs[15] = ((((((vals & 0xffff0000) >> 16) - (r14 >> 15)) >> 1) << 16) & 0xffff0000) | (((((vals & 0xffff) - (r15 >> 15)) >> 1) & 0xffff)); + break; + } + + default: + LOG("Executed Illegal extended opcode (%X). PC = %08X\n", func, PC); + break; + } + + m_icount -= m_clock_cycles_1; //TODO: with the latency it can change +} + + +template <hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_ldwr() +{ + check_delay_PC(); + const uint32_t fp = GET_FP; + if (SRC_GLOBAL) + set_global_register(SRC_CODE, READ_W(m_local_regs[(DST_CODE + fp) & 0x3f])); + else + m_local_regs[(SRC_CODE + fp) & 0x3f] = READ_W(m_local_regs[(DST_CODE + fp) & 0x3f]); + m_icount -= m_clock_cycles_1; +} + +template <hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_lddr() +{ + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t dreg = m_local_regs[(DST_CODE + fp) & 0x3f]; + + if (SRC_GLOBAL) + { + set_global_register(src_code, READ_W(dreg)); + set_global_register(src_code + 1, READ_W(dreg + 4)); + } + else + { + m_local_regs[src_code] = READ_W(dreg); + m_local_regs[(src_code + 1) & 0x3f] = READ_W(dreg + 4); + } + + m_icount -= m_clock_cycles_2; +} + +template <hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hypesrtone_ldwp() +{ + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t dst_code = (DST_CODE + fp) & 0x3f; + + if (SRC_GLOBAL) + { + set_global_register(SRC_CODE, READ_W(m_local_regs[dst_code])); + m_local_regs[dst_code] += 4; + } + else + { + const uint32_t src_code = (SRC_CODE + fp) & 0x3f; + m_local_regs[src_code] = READ_W(m_local_regs[dst_code]); + // post increment the destination register if it's different from the source one + // (needed by Hidden Catch) + if (src_code != dst_code) + m_local_regs[dst_code] += 4; + } + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::opf3() +template <hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_lddp() { - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_bne(decode); + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t dst_code = (DST_CODE + fp) & 0x3f; + const uint32_t dreg = m_local_regs[dst_code]; + + if (SRC_GLOBAL) + { + set_global_register(src_code, READ_W(dreg)); + set_global_register(src_code + 1, READ_W(dreg + 4)); + m_local_regs[dst_code] += 8; + } + else + { + const uint32_t srcf_code = (src_code + 1) & 0x3f; + m_local_regs[src_code] = READ_W(dreg); + m_local_regs[srcf_code] = READ_W(dreg + 4); + + // post increment the destination register if it's different from the source one + // and from the "next source" one + if (src_code != dst_code && srcf_code != dst_code) + m_local_regs[dst_code] += 8; + } + + m_icount -= m_clock_cycles_2; } -void hyperstone_device::opf4() +template <hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_stwr() { - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_bc(decode); + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t sreg = (SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code]; + WRITE_W(m_local_regs[(DST_CODE + fp) & 0x3f], sreg); + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::opf5() +template <hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_stdr() { - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_bnc(decode); + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t srcf_code = SRC_GLOBAL ? (SRC_CODE + 1) : ((src_code + 1) & 0x3f); + const uint32_t sreg = (SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code]; + const uint32_t sregf = (SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[srcf_code]; + + const uint32_t dreg = m_local_regs[(DST_CODE + GET_FP) & 0x3f]; + + WRITE_W(dreg, sreg); + WRITE_W(dreg + 4, sregf); + + m_icount -= m_clock_cycles_2; } -void hyperstone_device::opf6() +template <hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_stwp() { - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_bse(decode); + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t sreg = (SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code]; + + const uint32_t dst_code = (DST_CODE + fp) & 0x3f; + const uint32_t dreg = m_local_regs[dst_code]; + + WRITE_W(dreg, sreg); + m_local_regs[dst_code] += 4; + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::opf7() +template <hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_stdp() { - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_bht(decode); + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t srcf_code = SRC_GLOBAL ? (src_code + 1) : ((src_code + 1) & 0x3f); + const uint32_t sreg = (SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code]; + const uint32_t sregf = (SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[srcf_code]; + + const uint32_t dst_code = (DST_CODE + fp) & 0x3f; + const uint32_t dreg = m_local_regs[dst_code]; + + WRITE_W(dreg, sreg); + + m_local_regs[dst_code] += 8; + + if (SRC_GLOBAL || srcf_code != dst_code) + WRITE_W(dreg + 4, sregf); + else + WRITE_W(dreg + 4, sregf + 8); // because DREG == SREGF and DREG has been incremented + + m_icount -= m_clock_cycles_2; } -void hyperstone_device::opf8() +void hyperstone_device::hyperstone_dbv() { - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_bn(decode); + if (SR & V_MASK) + { + const int32_t offset = decode_pcrel(); + check_delay_PC(); + m_delay_slot = true; + m_delay_pc = PC + offset; + m_intblock = 3; + } + else + { + ignore_pcrel(); + check_delay_PC(); + } + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::opf9() +void hyperstone_device::hyperstone_dbnv() { - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_bnn(decode); + if (SR & V_MASK) + { + ignore_pcrel(); + check_delay_PC(); + } + else + { + const int32_t offset = decode_pcrel(); + check_delay_PC(); + m_delay_slot = true; + m_delay_pc = PC + offset; + m_intblock = 3; + } + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::opfa() +void hyperstone_device::hyperstone_dbe() { - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_ble(decode); + if (SR & Z_MASK) + { + const int32_t offset = decode_pcrel(); + check_delay_PC(); + m_delay_slot = true; + m_delay_pc = PC + offset; + m_intblock = 3; + } + else + { + ignore_pcrel(); + check_delay_PC(); + } + + m_icount -= m_clock_cycles_1; +} + +void hyperstone_device::hyperstone_dbne() +{ + if (SR & Z_MASK) + { + ignore_pcrel(); + check_delay_PC(); + } + else + { + const int32_t offset = decode_pcrel(); + check_delay_PC(); + m_delay_slot = true; + m_delay_pc = PC + offset; + m_intblock = 3; + } + m_icount -= m_clock_cycles_1; +} + +void hyperstone_device::hyperstone_dbc() +{ + if (SR & C_MASK) + { + const int32_t offset = decode_pcrel(); + check_delay_PC(); + m_delay_slot = true; + m_delay_pc = PC + offset; + m_intblock = 3; + } + else + { + ignore_pcrel(); + check_delay_PC(); + } + + m_icount -= m_clock_cycles_1; +} + +void hyperstone_device::hyperstone_dbnc() +{ + if (SR & C_MASK) + { + ignore_pcrel(); + check_delay_PC(); + } + else + { + const int32_t offset = decode_pcrel(); + check_delay_PC(); + m_delay_slot = true; + m_delay_pc = PC + offset; + m_intblock = 3; + } + + m_icount -= m_clock_cycles_1; +} + +void hyperstone_device::hyperstone_dbse() +{ + if (SR & (C_MASK | Z_MASK)) + { + const int32_t offset = decode_pcrel(); + check_delay_PC(); + m_delay_slot = true; + m_delay_pc = PC + offset; + m_intblock = 3; + } + else + { + ignore_pcrel(); + check_delay_PC(); + } + + m_icount -= m_clock_cycles_1; +} + +void hyperstone_device::hyperstone_dbht() +{ + if (SR & (C_MASK | Z_MASK)) + { + ignore_pcrel(); + check_delay_PC(); + } + else + { + const int32_t offset = decode_pcrel(); + check_delay_PC(); + m_delay_slot = true; + m_delay_pc = PC + offset; + m_intblock = 3; + } + + m_icount -= m_clock_cycles_1; +} + +void hyperstone_device::hyperstone_dbn() +{ + if (SR & N_MASK) + { + const int32_t offset = decode_pcrel(); + check_delay_PC(); + m_delay_slot = true; + m_delay_pc = PC + offset; + m_intblock = 3; + } + else + { + ignore_pcrel(); + check_delay_PC(); + } + + m_icount -= m_clock_cycles_1; +} + +void hyperstone_device::hyperstone_dbnn() +{ + if (SR & N_MASK) + { + ignore_pcrel(); + check_delay_PC(); + } + else + { + const int32_t offset = decode_pcrel(); + check_delay_PC(); + m_delay_slot = true; + m_delay_pc = PC + offset; + m_intblock = 3; + } + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::opfb() +void hyperstone_device::hyperstone_dble() { - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_bgt(decode); + if (SR & (N_MASK | Z_MASK)) + { + const int32_t offset = decode_pcrel(); + check_delay_PC(); + m_delay_slot = true; + m_delay_pc = PC + offset; + m_intblock = 3; + } + else + { + ignore_pcrel(); + check_delay_PC(); + } + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::opfc() +void hyperstone_device::hyperstone_dbgt() { - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_br(decode); + if (SR & (N_MASK | Z_MASK)) + { + ignore_pcrel(); + check_delay_PC(); + } + else + { + const int32_t offset = decode_pcrel(); + check_delay_PC(); + m_delay_slot = true; + m_delay_pc = PC + offset; + m_intblock = 3; + } + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::opfd() +void hyperstone_device::hyperstone_dbr() { - LOCAL_DECODE_INIT; - PCadrdecode(decode); - hyperstone_trap(decode); + const int32_t offset = decode_pcrel(); + check_delay_PC(); + + m_delay_slot = true; + m_delay_pc = PC + offset; + m_intblock = 3; } -void hyperstone_device::opfe() +void hyperstone_device::hyperstone_frame() { - LOCAL_DECODE_INIT; - PCadrdecode(decode); - hyperstone_trap(decode); + check_delay_PC(); + + uint8_t realfp = GET_FP - SRC_CODE; + uint8_t dst_code = DST_CODE; + + SET_FP(realfp); + SET_FL(dst_code); + SR &= ~M_MASK; + + int8_t difference = ((SP & 0x1fc) >> 2) + (64 - 10) - (realfp + GET_FL); // really it's 7 bits + + /* convert to 8 bits */ + if(difference > 63) + difference = (int8_t)(difference|0x80); + else if( difference < -64 ) + difference = difference & 0x7f; + + if (difference < 0) // else it's finished + { + bool tmp_flag = SP >= UB; + + for (; difference < 0; difference++) + { + WRITE_W(SP, m_local_regs[(SP & 0xfc) >> 2]); + SP += 4; + } + + if (tmp_flag) + { + uint32_t addr = get_trap_addr(TRAPNO_FRAME_ERROR); + execute_exception(addr); + } + } + + //TODO: no 1! + m_icount -= m_clock_cycles_1; } -void hyperstone_device::opff() +void hyperstone_device::hyperstone_call_global() { - LOCAL_DECODE_INIT; - PCadrdecode(decode); - hyperstone_trap(decode); + uint16_t imm_1 = READ_OP(PC); + PC += 2; + + int32_t extra_s = 0; + + if (E_BIT(imm_1)) + { + uint16_t imm_2 = READ_OP(PC); + + PC += 2; + SET_ILC(3<<19); + + extra_s = imm_2; + extra_s |= ((imm_1 & 0x3fff) << 16); + + if (S_BIT_CONST(imm_1)) + extra_s |= 0xc0000000; + } + else + { + extra_s = imm_1 & 0x3fff; + + SET_ILC(2<<19); + + if (S_BIT_CONST(imm_1)) + extra_s |= 0xffffc000; + } + + check_delay_PC(); + + uint32_t src_code = SRC_CODE; + uint32_t dst_code = DST_CODE; + + uint32_t sreg = m_global_regs[src_code]; + + if (src_code == SR_REGISTER) + sreg = 0; + + if (!DST_CODE) + dst_code = 16; + + uint32_t fp = GET_FP; + uint32_t dreg_index = dst_code + fp; + m_local_regs[dreg_index & 0x3f] = (PC & ~1) | GET_S; + m_local_regs[(dreg_index + 1) & 0x3f] = SR; + + SET_FP(fp + dst_code); + SET_FL(6); //default value for call + SR &= ~M_MASK; + + PC = (extra_s & ~1) + sreg; + + m_intblock = 2; + + //TODO: add interrupt locks, errors, .... + + //TODO: no 1! + m_icount -= m_clock_cycles_1; } -const hyperstone_device::ophandler hyperstone_device::s_opcodetable[256] = +void hyperstone_device::hyperstone_call_local() { - &hyperstone_device::op00, &hyperstone_device::op01, &hyperstone_device::op02, &hyperstone_device::op03, - &hyperstone_device::op04, &hyperstone_device::op05, &hyperstone_device::op06, &hyperstone_device::op07, - &hyperstone_device::op08, &hyperstone_device::op09, &hyperstone_device::op0a, &hyperstone_device::op0b, - &hyperstone_device::op0c, &hyperstone_device::op0d, &hyperstone_device::op0e, &hyperstone_device::op0f, + uint16_t imm_1 = READ_OP(PC); + PC += 2; + + int32_t extra_s = 0; - &hyperstone_device::op10, &hyperstone_device::op11, &hyperstone_device::op12, &hyperstone_device::op13, - &hyperstone_device::op14, &hyperstone_device::op15, &hyperstone_device::op16, &hyperstone_device::op17, - &hyperstone_device::op18, &hyperstone_device::op19, &hyperstone_device::op1a, &hyperstone_device::op1b, - &hyperstone_device::op1c, &hyperstone_device::op1d, &hyperstone_device::op1e, &hyperstone_device::op1f, + if (E_BIT(imm_1)) + { + uint16_t imm_2 = READ_OP(PC); - &hyperstone_device::op20, &hyperstone_device::op21, &hyperstone_device::op22, &hyperstone_device::op23, - &hyperstone_device::op24, &hyperstone_device::op25, &hyperstone_device::op26, &hyperstone_device::op27, - &hyperstone_device::op28, &hyperstone_device::op29, &hyperstone_device::op2a, &hyperstone_device::op2b, - &hyperstone_device::op2c, &hyperstone_device::op2d, &hyperstone_device::op2e, &hyperstone_device::op2f, + PC += 2; + SET_ILC(3<<19); - &hyperstone_device::op30, &hyperstone_device::op31, &hyperstone_device::op32, &hyperstone_device::op33, - &hyperstone_device::op34, &hyperstone_device::op35, &hyperstone_device::op36, &hyperstone_device::op37, - &hyperstone_device::op38, &hyperstone_device::op39, &hyperstone_device::op3a, &hyperstone_device::op3b, - &hyperstone_device::op3c, &hyperstone_device::op3d, &hyperstone_device::op3e, &hyperstone_device::op3f, + extra_s = imm_2; + extra_s |= ((imm_1 & 0x3fff) << 16); - &hyperstone_device::op40, &hyperstone_device::op41, &hyperstone_device::op42, &hyperstone_device::op43, - &hyperstone_device::op44, &hyperstone_device::op45, &hyperstone_device::op46, &hyperstone_device::op47, - &hyperstone_device::op48, &hyperstone_device::op49, &hyperstone_device::op4a, &hyperstone_device::op4b, - &hyperstone_device::op4c, &hyperstone_device::op4d, &hyperstone_device::op4e, &hyperstone_device::op4f, + if (S_BIT_CONST(imm_1)) + extra_s |= 0xc0000000; + } + else + { + extra_s = imm_1 & 0x3fff; - &hyperstone_device::op50, &hyperstone_device::op51, &hyperstone_device::op52, &hyperstone_device::op53, - &hyperstone_device::op54, &hyperstone_device::op55, &hyperstone_device::op56, &hyperstone_device::op57, - &hyperstone_device::op58, &hyperstone_device::op59, &hyperstone_device::op5a, &hyperstone_device::op5b, - &hyperstone_device::op5c, &hyperstone_device::op5d, &hyperstone_device::op5e, &hyperstone_device::op5f, + SET_ILC(2<<19); - &hyperstone_device::op60, &hyperstone_device::op61, &hyperstone_device::op62, &hyperstone_device::op63, - &hyperstone_device::op64, &hyperstone_device::op65, &hyperstone_device::op66, &hyperstone_device::op67, - &hyperstone_device::op68, &hyperstone_device::op69, &hyperstone_device::op6a, &hyperstone_device::op6b, - &hyperstone_device::op6c, &hyperstone_device::op6d, &hyperstone_device::op6e, &hyperstone_device::op6f, + if (S_BIT_CONST(imm_1)) + extra_s |= 0xffffc000; + } - &hyperstone_device::op70, &hyperstone_device::op71, &hyperstone_device::op72, &hyperstone_device::op73, - &hyperstone_device::op74, &hyperstone_device::op75, &hyperstone_device::op76, &hyperstone_device::op77, - &hyperstone_device::op78, &hyperstone_device::op79, &hyperstone_device::op7a, &hyperstone_device::op7b, - &hyperstone_device::op7c, &hyperstone_device::op7d, &hyperstone_device::op7e, &hyperstone_device::op7f, + check_delay_PC(); - &hyperstone_device::op80, &hyperstone_device::op81, &hyperstone_device::op82, &hyperstone_device::op83, - &hyperstone_device::op84, &hyperstone_device::op85, &hyperstone_device::op86, &hyperstone_device::op87, - &hyperstone_device::op88, &hyperstone_device::op89, &hyperstone_device::op8a, &hyperstone_device::op8b, - &hyperstone_device::op8c, &hyperstone_device::op8d, &hyperstone_device::op8e, &hyperstone_device::op8f, + uint32_t src_code = SRC_CODE; + uint32_t dst_code = DST_CODE; - &hyperstone_device::op90, &hyperstone_device::op91, &hyperstone_device::op92, &hyperstone_device::op93, - &hyperstone_device::op94, &hyperstone_device::op95, &hyperstone_device::op96, &hyperstone_device::op97, - &hyperstone_device::op98, &hyperstone_device::op99, &hyperstone_device::op9a, &hyperstone_device::op9b, - &hyperstone_device::op9c, &hyperstone_device::op9d, &hyperstone_device::op9e, &hyperstone_device::op9f, + if (!DST_CODE) + dst_code = 16; - &hyperstone_device::opa0, &hyperstone_device::opa1, &hyperstone_device::opa2, &hyperstone_device::opa3, - &hyperstone_device::opa4, &hyperstone_device::opa5, &hyperstone_device::opa6, &hyperstone_device::opa7, - &hyperstone_device::opa8, &hyperstone_device::opa9, &hyperstone_device::opaa, &hyperstone_device::opab, - &hyperstone_device::opac, &hyperstone_device::opad, &hyperstone_device::opae, &hyperstone_device::opaf, + uint32_t fp = GET_FP; + extra_s = (extra_s & ~1) + m_local_regs[(src_code + fp) & 0x3f]; - &hyperstone_device::opb0, &hyperstone_device::opb1, &hyperstone_device::opb2, &hyperstone_device::opb3, - &hyperstone_device::opb4, &hyperstone_device::opb5, &hyperstone_device::opb6, &hyperstone_device::opb7, - &hyperstone_device::opb8, &hyperstone_device::opb9, &hyperstone_device::opba, &hyperstone_device::opbb, - &hyperstone_device::opbc, &hyperstone_device::opbd, &hyperstone_device::opbe, &hyperstone_device::opbf, + uint32_t dreg_index = dst_code + fp; + m_local_regs[dreg_index & 0x3f] = (PC & ~1) | GET_S; + m_local_regs[(dreg_index + 1) & 0x3f] = SR; - &hyperstone_device::opc0, &hyperstone_device::opc1, &hyperstone_device::opc2, &hyperstone_device::opc3, - &hyperstone_device::opc4, &hyperstone_device::opc5, &hyperstone_device::opc6, &hyperstone_device::opc7, - &hyperstone_device::opc8, &hyperstone_device::opc9, &hyperstone_device::opca, &hyperstone_device::opcb, - &hyperstone_device::opcc, &hyperstone_device::opcd, &hyperstone_device::opce, &hyperstone_device::opcf, + SET_FP(fp + dst_code); + SET_FL(6); //default value for call + SR &= ~M_MASK; - &hyperstone_device::opd0, &hyperstone_device::opd1, &hyperstone_device::opd2, &hyperstone_device::opd3, - &hyperstone_device::opd4, &hyperstone_device::opd5, &hyperstone_device::opd6, &hyperstone_device::opd7, - &hyperstone_device::opd8, &hyperstone_device::opd9, &hyperstone_device::opda, &hyperstone_device::opdb, - &hyperstone_device::opdc, &hyperstone_device::opdd, &hyperstone_device::opde, &hyperstone_device::opdf, + PC = extra_s; + + m_intblock = 2; + + //TODO: add interrupt locks, errors, .... + + //TODO: no 1! + m_icount -= m_clock_cycles_1; +} - &hyperstone_device::ope0, &hyperstone_device::ope1, &hyperstone_device::ope2, &hyperstone_device::ope3, - &hyperstone_device::ope4, &hyperstone_device::ope5, &hyperstone_device::ope6, &hyperstone_device::ope7, - &hyperstone_device::ope8, &hyperstone_device::ope9, &hyperstone_device::opea, &hyperstone_device::opeb, - &hyperstone_device::opec, &hyperstone_device::oped, &hyperstone_device::opee, &hyperstone_device::opef, - &hyperstone_device::opf0, &hyperstone_device::opf1, &hyperstone_device::opf2, &hyperstone_device::opf3, - &hyperstone_device::opf4, &hyperstone_device::opf5, &hyperstone_device::opf6, &hyperstone_device::opf7, - &hyperstone_device::opf8, &hyperstone_device::opf9, &hyperstone_device::opfa, &hyperstone_device::opfb, - &hyperstone_device::opfc, &hyperstone_device::opfd, &hyperstone_device::opfe, &hyperstone_device::opff -}; + +void hyperstone_device::hyperstone_bv() +{ + if (SR & V_MASK) + { + execute_br(); + } + else + { + ignore_pcrel(); + check_delay_PC(); + m_icount -= m_clock_cycles_1; + } +} + +void hyperstone_device::hyperstone_bnv() +{ + if (SR & V_MASK) + { + ignore_pcrel(); + check_delay_PC(); + m_icount -= m_clock_cycles_1; + } + else + { + execute_br(); + } +} + +void hyperstone_device::hyperstone_be() +{ + if (SR & Z_MASK) + { + execute_br(); + } + else + { + ignore_pcrel(); + check_delay_PC(); + m_icount -= m_clock_cycles_1; + } +} + +void hyperstone_device::hyperstone_bne() +{ + if (SR & Z_MASK) + { + ignore_pcrel(); + check_delay_PC(); + m_icount -= m_clock_cycles_1; + } + else + { + execute_br(); + } +} + +void hyperstone_device::hyperstone_bc() +{ + if (SR & C_MASK) + { + execute_br(); + } + else + { + ignore_pcrel(); + check_delay_PC(); + m_icount -= m_clock_cycles_1; + } +} + +void hyperstone_device::hyperstone_bnc() +{ + if (SR & C_MASK) + { + ignore_pcrel(); + check_delay_PC(); + m_icount -= m_clock_cycles_1; + } + else + { + execute_br(); + } +} + +void hyperstone_device::hyperstone_bse() +{ + if (SR & (C_MASK | Z_MASK)) + { + execute_br(); + } + else + { + ignore_pcrel(); + check_delay_PC(); + m_icount -= m_clock_cycles_1; + } +} + +void hyperstone_device::hyperstone_bht() +{ + if (SR & (C_MASK | Z_MASK)) + { + ignore_pcrel(); + check_delay_PC(); + m_icount -= m_clock_cycles_1; + } + else + { + execute_br(); + } +} + +void hyperstone_device::hyperstone_bn() +{ + if (SR & N_MASK) + { + execute_br(); + } + else + { + ignore_pcrel(); + check_delay_PC(); + m_icount -= m_clock_cycles_1; + } +} + +void hyperstone_device::hyperstone_bnn() +{ + if (SR & N_MASK) + { + ignore_pcrel(); + check_delay_PC(); + m_icount -= m_clock_cycles_1; + } + else + { + execute_br(); + } +} + +void hyperstone_device::hyperstone_ble() +{ + if (SR & (N_MASK | Z_MASK)) + { + execute_br(); + } + else + { + ignore_pcrel(); + check_delay_PC(); + m_icount -= m_clock_cycles_1; + } +} + +void hyperstone_device::hyperstone_bgt() +{ + if (SR & (N_MASK | Z_MASK)) + { + ignore_pcrel(); + check_delay_PC(); + m_icount -= m_clock_cycles_1; + } + else + { + execute_br(); + } +} diff --git a/src/devices/cpu/es5510/es5510.cpp b/src/devices/cpu/es5510/es5510.cpp index 5848ccc05e2..61a94d8316f 100644 --- a/src/devices/cpu/es5510/es5510.cpp +++ b/src/devices/cpu/es5510/es5510.cpp @@ -9,6 +9,7 @@ #include "emu.h" #include "es5510.h" +#include "es5510d.h" #include "cpu/m68000/m68000.h" #include "debugger.h" @@ -924,19 +925,9 @@ void es5510_device::execute_run() { } } -uint32_t es5510_device::disasm_min_opcode_bytes() const +util::disasm_interface *es5510_device::create_disassembler() { - return 6; -} - -uint32_t es5510_device::disasm_max_opcode_bytes() const -{ - return 6; -} - -offs_t es5510_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) -{ - return pc; + return new es5510_disassembler; } #if VERBOSE_EXEC diff --git a/src/devices/cpu/es5510/es5510.h b/src/devices/cpu/es5510/es5510.h index 56045a4e769..0fd41807684 100644 --- a/src/devices/cpu/es5510/es5510.h +++ b/src/devices/cpu/es5510/es5510.h @@ -131,10 +131,8 @@ protected: virtual uint32_t execute_max_cycles() const override; virtual uint32_t execute_input_lines() const override; virtual void execute_run() override; - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; virtual void execute_set_input(int linenum, int state) override; + virtual util::disasm_interface *create_disassembler() override; int32_t alu_operation(uint8_t op, int32_t aValue, int32_t bValue, uint8_t &flags); void alu_operation_end(); diff --git a/src/devices/cpu/es5510/es5510d.cpp b/src/devices/cpu/es5510/es5510d.cpp new file mode 100644 index 00000000000..d563019f486 --- /dev/null +++ b/src/devices/cpu/es5510/es5510d.cpp @@ -0,0 +1,21 @@ +// license:BSD-3-Clause +// copyright-holders:Christian Brunschen +/*************************************************************************** + * + * es5510.c - Ensoniq ES5510 (ESP) emulation + * by Christian Brunschen + * + ***************************************************************************/ + +#include "emu.h" +#include "es5510d.h" + +u32 es5510_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t es5510_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + return 1; +} diff --git a/src/devices/cpu/es5510/es5510d.h b/src/devices/cpu/es5510/es5510d.h new file mode 100644 index 00000000000..e80b4a3fe36 --- /dev/null +++ b/src/devices/cpu/es5510/es5510d.h @@ -0,0 +1,25 @@ +// license:BSD-3-Clause +// copyright-holders:Christian Brunschen +/*************************************************************************** + * + * es5510.c - Ensoniq ES5510 (ESP) emulation + * by Christian Brunschen + * + ***************************************************************************/ + +#ifndef MAME_CPU_ES5510_ES5510DASM_H +#define MAME_CPU_ES5510_ES5510DASM_H + +#pragma once + +class es5510_disassembler : public util::disasm_interface +{ +public: + es5510_disassembler() = default; + virtual ~es5510_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/esrip/esrip.cpp b/src/devices/cpu/esrip/esrip.cpp index ee8416304c7..e87fd1821d6 100644 --- a/src/devices/cpu/esrip/esrip.cpp +++ b/src/devices/cpu/esrip/esrip.cpp @@ -11,6 +11,7 @@ #include "emu.h" #include "esrip.h" +#include "esripdsm.h" #include "debugger.h" #include "screen.h" @@ -192,7 +193,7 @@ void esrip_device::device_start() m_ipt_ram.resize(IPT_RAM_SIZE/2); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<-3>(); // register our state for the debugger state_add(STATE_GENPC, "GENPC", m_rip_pc).noshow(); @@ -372,39 +373,15 @@ void esrip_device::state_string_export(const device_state_entry &entry, std::str //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t esrip_device::disasm_min_opcode_bytes() const -{ - return 8; -} - - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t esrip_device::disasm_max_opcode_bytes() const -{ - return 8; -} - - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t esrip_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *esrip_device::create_disassembler() { - extern CPU_DISASSEMBLE( esrip ); - return CPU_DISASSEMBLE_NAME(esrip)(this, stream, pc, oprom, opram, options); + return new esrip_disassembler; } - /*************************************************************************** PRIVATE FUNCTIONS ***************************************************************************/ @@ -1901,7 +1878,7 @@ void esrip_device::execute_run() m_pl7 = m_l7; /* Latch instruction */ - inst = m_direct->read_qword(RIP_PC << 3); + inst = m_direct->read_qword(RIP_PC); in_h = inst >> 32; in_l = inst & 0xffffffff; diff --git a/src/devices/cpu/esrip/esrip.h b/src/devices/cpu/esrip/esrip.h index 8aaa0f1d071..ed2fadd98e9 100644 --- a/src/devices/cpu/esrip/esrip.h +++ b/src/devices/cpu/esrip/esrip.h @@ -136,9 +136,7 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // device_state_interface overrides virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; @@ -195,7 +193,7 @@ protected: uint8_t *m_lbrm; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<-3> *m_direct; int m_icount; @@ -266,7 +264,4 @@ private: void am29116_execute(uint16_t inst, int _sre); }; - -CPU_DISASSEMBLE( esrip ); - #endif // MAME_CPU_ESRIP_ESRIP_H diff --git a/src/devices/cpu/esrip/esripdsm.cpp b/src/devices/cpu/esrip/esripdsm.cpp index 04890fba2e4..43ecd616539 100644 --- a/src/devices/cpu/esrip/esripdsm.cpp +++ b/src/devices/cpu/esrip/esripdsm.cpp @@ -10,14 +10,18 @@ ***************************************************************************/ #include "emu.h" -#include "debugger.h" +#include "esripdsm.h" +u32 esrip_disassembler::opcode_alignment() const +{ + return 1; +} /*************************************************************************** DISASSEMBLY HOOK (TODO: FINISH) ***************************************************************************/ -CPU_DISASSEMBLE(esrip) +offs_t esrip_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { #if 0 static const char* const jmp_types[] = @@ -45,7 +49,7 @@ CPU_DISASSEMBLE(esrip) }; #endif - uint64_t inst = big_endianize_int64(*(uint64_t *)oprom); + uint64_t inst = opcodes.r64(pc); uint32_t inst_hi = inst >> 32; uint32_t inst_lo = inst & 0xffffffff; @@ -91,5 +95,5 @@ CPU_DISASSEMBLE(esrip) ctrl3 & 0x80 ? ' ' : '7' ); - return 1 | DASMFLAG_SUPPORTED; + return 1 | SUPPORTED; } diff --git a/src/devices/cpu/esrip/esripdsm.h b/src/devices/cpu/esrip/esripdsm.h new file mode 100644 index 00000000000..0491a02bf29 --- /dev/null +++ b/src/devices/cpu/esrip/esripdsm.h @@ -0,0 +1,27 @@ +// license:BSD-3-Clause +// copyright-holders:Philip Bennett +/*************************************************************************** + + esripdsm.c + + Implementation of the Entertainment Sciences + AM29116-based Real Time Image Processor + +***************************************************************************/ + +#ifndef MAME_CPU_ESRIP_ESRIPDSM_H +#define MAME_CPU_ESRIP_ESRIPDSM_H + +#pragma once + +class esrip_disassembler : public util::disasm_interface +{ +public: + esrip_disassembler() = default; + virtual ~esrip_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/f8/f8.cpp b/src/devices/cpu/f8/f8.cpp index 4d5f420fe62..ba386a1af13 100644 --- a/src/devices/cpu/f8/f8.cpp +++ b/src/devices/cpu/f8/f8.cpp @@ -16,6 +16,7 @@ #include "emu.h" #include "f8.h" +#include "f8dasm.h" #include "debugger.h" #define S 0x01 @@ -1958,7 +1959,7 @@ void f8_cpu_device::device_start() { // TODO register debug state m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_iospace = &space(AS_IO); save_item(NAME(m_pc0)); @@ -2070,10 +2071,9 @@ void f8_cpu_device::state_string_export(const device_state_entry &entry, std::st } -offs_t f8_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *f8_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( f8 ); - return CPU_DISASSEMBLE_NAME(f8)(this, stream, pc, oprom, opram, options); + return new f8_disassembler; } diff --git a/src/devices/cpu/f8/f8.h b/src/devices/cpu/f8/f8.h index 5be9090ec2b..287f7a9fbf3 100644 --- a/src/devices/cpu/f8/f8.h +++ b/src/devices/cpu/f8/f8.h @@ -54,9 +54,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 3; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -73,7 +71,7 @@ private: uint16_t m_io; /* last I/O address */ uint16_t m_irq_vector; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_iospace; int m_icount; uint8_t m_r[64]; /* scratchpad RAM */ diff --git a/src/devices/cpu/f8/f8dasm.cpp b/src/devices/cpu/f8/f8dasm.cpp index 4c44aa2c424..49827760cd7 100644 --- a/src/devices/cpu/f8/f8dasm.cpp +++ b/src/devices/cpu/f8/f8dasm.cpp @@ -1,18 +1,22 @@ // license:BSD-3-Clause // copyright-holders:Juergen Buchmueller #include "emu.h" -#include "debugger.h" -#include "f8.h" +#include "f8dasm.h" -static const char *const rname[16] = { +const char *const f8_disassembler::rname[16] = { "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "J", "HU", "HL", "KU", "KL", "QU", "QL" }; -CPU_DISASSEMBLE(f8) +u32 f8_disassembler::opcode_alignment() const { - unsigned size = 0; - uint8_t op = oprom[size++]; + return 1; +} + +offs_t f8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + offs_t base_pc = pc; + uint8_t op = opcodes.r8(pc++); switch( op ) { @@ -116,40 +120,40 @@ CPU_DISASSEMBLE(f8) util::stream_format(stream, "INC"); break; case 0x20: /* 0010 0000 */ - util::stream_format(stream, "LI $%02X", oprom[size++]); + util::stream_format(stream, "LI $%02X", opcodes.r8(pc++)); break; case 0x21: /* 0010 0001 */ - util::stream_format(stream, "NI $%02X", oprom[size++]); + util::stream_format(stream, "NI $%02X", opcodes.r8(pc++)); break; case 0x22: /* 0010 0010 */ - util::stream_format(stream, "OI $%02X", oprom[size++]); + util::stream_format(stream, "OI $%02X", opcodes.r8(pc++)); break; case 0x23: /* 0010 0011 */ - util::stream_format(stream, "XI $%02X", oprom[size++]); + util::stream_format(stream, "XI $%02X", opcodes.r8(pc++)); break; case 0x24: /* 0010 0100 */ - util::stream_format(stream, "AI $%02X", oprom[size++]); + util::stream_format(stream, "AI $%02X", opcodes.r8(pc++)); break; case 0x25: /* 0010 0101 */ - util::stream_format(stream, "CI $%02X", oprom[size++]); + util::stream_format(stream, "CI $%02X", opcodes.r8(pc++)); break; case 0x26: /* 0010 0110 */ - util::stream_format(stream, "IN $%02X", oprom[size++]); + util::stream_format(stream, "IN $%02X", opcodes.r8(pc++)); break; case 0x27: /* 0010 0111 */ - util::stream_format(stream, "OUT $%02X", oprom[size++]); + util::stream_format(stream, "OUT $%02X", opcodes.r8(pc++)); break; case 0x28: /* 0010 1000 */ - util::stream_format(stream, "PI $%02X%02X", oprom[size + 0], oprom[size + 1]); - size += 2; + util::stream_format(stream, "PI $%02X%02X", opcodes.r16(pc)); + pc += 2; break; case 0x29: /* 0010 1001 */ - util::stream_format(stream, "JMP $%02X%02X", oprom[size + 0], oprom[size + 1]); - size += 2; + util::stream_format(stream, "JMP $%02X%02X", opcodes.r16(pc)); + pc += 2; break; case 0x2a: /* 0010 1010 */ - util::stream_format(stream, "DCI $%02X%02X", oprom[size + 0], oprom[size + 1]); - size += 2; + util::stream_format(stream, "DCI $%02X%02X", opcodes.r16(pc)); + pc += 2; break; case 0x2b: /* 0010 1011 */ util::stream_format(stream, "NOP"); @@ -286,22 +290,22 @@ CPU_DISASSEMBLE(f8) case 0x81: /* 1000 0001 */ case 0x85: /* 1000 0101 */ - util::stream_format(stream, "BP $%04X", pc + (int8_t)oprom[size++] + 1); + util::stream_format(stream, "BP $%04X", base_pc + (int8_t)opcodes.r8(pc++) + 1); break; case 0x82: /* 1000 0010 */ - util::stream_format(stream, "BC $%04X", pc + (int8_t)oprom[size++] + 1); + util::stream_format(stream, "BC $%04X", base_pc + (int8_t)opcodes.r8(pc++) + 1); break; case 0x84: /* 1000 0100 */ - util::stream_format(stream, "BZ $%04X", pc + (int8_t)oprom[size++] + 1); + util::stream_format(stream, "BZ $%04X", base_pc + (int8_t)opcodes.r8(pc++) + 1); break; case 0x80: /* 1000 0000 */ case 0x83: /* 1000 0011 */ case 0x86: /* 1000 0110 */ case 0x87: /* 1000 0111 */ - util::stream_format(stream, "BT $%02X,$%04X", op & 0x07, pc + (int8_t)oprom[size++] + 1); + util::stream_format(stream, "BT $%02X,$%04X", op & 0x07, base_pc + (int8_t)opcodes.r8(pc++) + 1); break; case 0x88: /* 1000 1000 */ @@ -333,28 +337,28 @@ CPU_DISASSEMBLE(f8) break; case 0x8f: /* 1000 1111 */ - util::stream_format(stream, "BR7 $%04X", pc + (int8_t)oprom[size++] + 1); + util::stream_format(stream, "BR7 $%04X", base_pc + (int8_t)opcodes.r8(pc++) + 1); break; case 0x90: /* 1001 0000 */ - util::stream_format(stream, "BR $%04X", pc + (int8_t)oprom[size++] + 1); + util::stream_format(stream, "BR $%04X", base_pc + (int8_t)opcodes.r8(pc++) + 1); break; case 0x91: /* 1001 0001 */ case 0x95: /* 1001 0101 */ - util::stream_format(stream, "BM $%04X", pc + (int8_t)oprom[size++] + 1); + util::stream_format(stream, "BM $%04X", base_pc + (int8_t)opcodes.r8(pc++) + 1); break; case 0x92: /* 1001 0010 */ - util::stream_format(stream, "BNC $%04X", pc + (int8_t)oprom[size++] + 1); + util::stream_format(stream, "BNC $%04X", base_pc + (int8_t)opcodes.r8(pc++) + 1); break; case 0x94: /* 1001 0100 */ - util::stream_format(stream, "BNZ $%04X", pc + (int8_t)oprom[size++] + 1); + util::stream_format(stream, "BNZ $%04X", base_pc + (int8_t)opcodes.r8(pc++) + 1); break; case 0x98: /* 1001 1000 */ - util::stream_format(stream, "BNO $%04X", pc + (int8_t)oprom[size++] + 1); + util::stream_format(stream, "BNO $%04X", base_pc + (int8_t)opcodes.r8(pc++) + 1); break; case 0x93: /* 1001 0011 */ @@ -367,7 +371,7 @@ CPU_DISASSEMBLE(f8) case 0x9d: /* 1001 1101 */ case 0x9e: /* 1001 1110 */ case 0x9f: /* 1001 1111 */ - util::stream_format(stream, "BF $%02X,$%04X", op & 0x0f, pc + (int8_t)oprom[size++] + 1); + util::stream_format(stream, "BF $%02X,$%04X", op & 0x0f, base_pc + (int8_t)opcodes.r8(pc++) + 1); break; case 0xa0: /* 1010 0000 */ @@ -530,5 +534,5 @@ CPU_DISASSEMBLE(f8) break; } - return size; + return pc - base_pc; } diff --git a/src/devices/cpu/f8/f8dasm.h b/src/devices/cpu/f8/f8dasm.h new file mode 100644 index 00000000000..112cf35dc0f --- /dev/null +++ b/src/devices/cpu/f8/f8dasm.h @@ -0,0 +1,21 @@ +// license:BSD-3-Clause +// copyright-holders:Juergen Buchmueller + +#ifndef MAME_CPU_F8_F8DASM_H +#define MAME_CPU_F8_F8DASM_H + +#pragma once + +class f8_disassembler : public util::disasm_interface +{ +public: + f8_disassembler() = default; + virtual ~f8_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +private: + static const char *const rname[16]; +}; + +#endif diff --git a/src/devices/cpu/g65816/g65816.cpp b/src/devices/cpu/g65816/g65816.cpp index b121fba081a..6514f113b05 100644 --- a/src/devices/cpu/g65816/g65816.cpp +++ b/src/devices/cpu/g65816/g65816.cpp @@ -767,18 +767,19 @@ void g65816_device::execute_set_input(int line, int state) (this->*FTABLE_SET_LINE)(line, state); } -/* Disassemble an instruction */ -#include "g65816ds.h" - +util::disasm_interface *g65816_device::create_disassembler() +{ + return new g65816_disassembler(this); +} -offs_t g65816_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +bool g65816_device::get_m_flag() const { - return g65816_disassemble(stream, (pc & 0x00ffff), (pc & 0xff0000) >> 16, oprom, FLAG_M, FLAG_X); + return FLAG_M; } -CPU_DISASSEMBLE( g65816 ) +bool g65816_device::get_x_flag() const { - return g65816_disassemble(stream, (pc & 0x00ffff), (pc & 0xff0000) >> 16, oprom, 0/*FLAG_M*/, 0/*FLAG_X*/); + return FLAG_X; } void g65816_device::g65816_restore_state() diff --git a/src/devices/cpu/g65816/g65816.h b/src/devices/cpu/g65816/g65816.h index 67f21b780bc..cfacba32927 100644 --- a/src/devices/cpu/g65816/g65816.h +++ b/src/devices/cpu/g65816/g65816.h @@ -5,6 +5,7 @@ #pragma once +#include "g65816ds.h" #include "g65816cm.h" /* ======================================================================== */ @@ -45,7 +46,7 @@ enum #define G65816_INT_NMI G65816_LINE_NMI -class g65816_device : public cpu_device +class g65816_device : public cpu_device, public g65816_disassembler::config { public: // construction/destruction @@ -85,9 +86,9 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 4; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; + virtual bool get_m_flag() const override; + virtual bool get_x_flag() const override; address_space_config m_program_config; diff --git a/src/devices/cpu/g65816/g65816ds.cpp b/src/devices/cpu/g65816/g65816ds.cpp index aad24ceb545..5fde19e4218 100644 --- a/src/devices/cpu/g65816/g65816ds.cpp +++ b/src/devices/cpu/g65816/g65816ds.cpp @@ -12,102 +12,55 @@ All rights reserved. */ - #include "emu.h" #include "g65816ds.h" -#ifdef SEC -#undef SEC -#endif - -#define ADDRESS_65816(A) ((A)&0xffffff) - - -namespace { - -class g65816_opcode_struct +g65816_disassembler::g65816_disassembler(config *conf) : m_config(conf) { -public: - const char *name() const - { - return s_opnames[unsigned(m_name)]; - } +} - bool is_call() const - { - switch (m_name) - { - case op::JSR: - case op::JSL: - return true; - default: - return false; - } - } +u32 g65816_disassembler::opcode_alignment() const +{ + return 1; +} - bool is_return() const - { - switch (m_name) - { - case op::RTI: - case op::RTL: - case op::RTS: - return true; - default: - return false; - } - } +const char *g65816_disassembler::opcode_struct::name() const +{ + return g65816_disassembler::s_opnames[unsigned(m_name)]; +} - static const g65816_opcode_struct &get(unsigned char ins) +bool g65816_disassembler::opcode_struct::is_call() const +{ + switch (m_name) { - return s_opcodes[ins]; + case op::JSR: + case op::JSL: + return true; + default: + return false; } +} - unsigned char flag; - unsigned char ea; - -protected: - enum class op : unsigned - { - ADC , AND , ASL , BCC , BCS , BEQ , BIT , BMI , BNE , BPL , BRA , - BRK , BRL , BVC , BVS , CLC , CLD , CLI , CLV , CMP , COP , CPX , - CPY , DEA , DEC , DEX , DEY , EOR , INA , INC , INX , INY , JML , - JMP , JSL , JSR , LDA , LDX , LDY , LSR , MVN , MVP , NOP , ORA , - PEA , PEI , PER , PHA , PHB , PHD , PHK , PHP , PHX , PHY , PLA , - PLB , PLD , PLP , PLX , PLY , REP , ROL , ROR , RTI , RTL , RTS , - SBC , SEC , SED , SEI , SEP , STA , STP , STX , STY , STZ , TAX , - TAY , TCS , TCD , TDC , TRB , TSB , TSC , TSX , TXA , TXS , TXY , - TYA , TYX , WAI , WDM , XBA , XCE - }; - - g65816_opcode_struct(op n, unsigned char f, unsigned char e) - : flag(f) - , ea(e) - , m_name(n) +bool g65816_disassembler::opcode_struct::is_return() const +{ + switch (m_name) { + case op::RTI: + case op::RTL: + case op::RTS: + return true; + default: + return false; } +} - op m_name; - - static const char *const s_opnames[]; - static const g65816_opcode_struct s_opcodes[256]; -}; - -enum +g65816_disassembler::opcode_struct::opcode_struct(op n, u8 f, u8 e) : m_name(n), flag(f), ea(e) { - IMP , ACC , RELB, RELW, IMM , A , AI , AL , ALX , AX , AXI , - AY , D , DI , DIY , DLI , DLIY, DX , DXI , DY , S , SIY , - SIG , MVN , MVP , PEA , PEI , PER -}; +} + -enum -{ - I, /* ignore */ - M, /* check m bit */ - X /* check x bit */ -}; -const char *const g65816_opcode_struct::s_opnames[] = +const char *const g65816_disassembler::s_opnames[] = { "ADC", "AND", "ASL", "BCC", "BCS", "BEQ", "BIT", "BMI", "BNE", "BPL", "BRA", "BRK", "BRL", "BVC", "BVS", "CLC", "CLD", "CLI", "CLV", "CMP", "COP", "CPX", @@ -120,7 +73,7 @@ const char *const g65816_opcode_struct::s_opnames[] = "TYA", "TYX", "WAI", "WDM", "XBA", "XCE" }; -const g65816_opcode_struct g65816_opcode_struct::s_opcodes[256] = +const g65816_disassembler::opcode_struct g65816_disassembler::s_opcodes[256] = { {op::BRK, I, SIG }, {op::ORA, M, DXI }, {op::COP, I, SIG }, {op::ORA, M, S }, {op::TSB, M, D }, {op::ORA, M, D }, {op::ASL, M, D }, {op::ORA, M, DLI }, @@ -188,83 +141,38 @@ const g65816_opcode_struct g65816_opcode_struct::s_opcodes[256] = {op::JSR, I, AXI }, {op::SBC, M, AX }, {op::INC, M, AX }, {op::SBC, M, ALX } }; -} // anonymous namespace - -static const uint8_t *base_oprom; -static uint32_t base_pc; - -static inline unsigned int read_8(unsigned int address) -{ - address = ADDRESS_65816(address); - return base_oprom[address - base_pc]; -} - -static inline unsigned int read_16(unsigned int address) -{ - unsigned int val = read_8(address); - return val | (read_8(address+1)<<8); -} - -static inline unsigned int read_24(unsigned int address) -{ - unsigned int val = read_8(address); - val |= (read_8(address+1)<<8); - return val | (read_8(address+2)<<16); -} - -static inline char* int_8_str(unsigned int val) +std::string g65816_disassembler::int_8_str(u8 val) { - static char str[20]; - - val &= 0xff; - if(val & 0x80) - sprintf(str, "-$%x", (0-val) & 0x7f); + return util::string_format("-$%x", (0-val) & 0x7f); else - sprintf(str, "$%x", val & 0x7f); - - return str; + return util::string_format("$%x", val & 0x7f); } -static inline char* int_16_str(unsigned int val) +std::string g65816_disassembler::int_16_str(u16 val) { - static char str[20]; - - val &= 0xffff; - if(val & 0x8000) - sprintf(str, "-$%x", (0-val) & 0x7fff); + return util::string_format("-$%x", (0-val) & 0x7fff); else - sprintf(str, "$%x", val & 0x7fff); - - return str; + return util::string_format("$%x", val & 0x7fff); } -unsigned g65816_disassemble(std::ostream &stream, unsigned int pc, unsigned int pb, const uint8_t *oprom, int m_flag, int x_flag) +offs_t g65816_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - unsigned int instruction; - const g65816_opcode_struct* opcode; int var; int length = 1; - unsigned int address; - unsigned dasm_flags; - - pb <<= 16; - address = pc | pb; - - base_oprom = oprom; - base_pc = address; + offs_t dasm_flags; - instruction = read_8(address); - opcode = &g65816_opcode_struct::get(instruction); + u8 instruction = opcodes.r8(pc & 0xffffff); + const opcode_struct *opcode = &s_opcodes[instruction]; stream << opcode->name(); if (opcode->is_call()) - dasm_flags = DASMFLAG_STEP_OVER; + dasm_flags = STEP_OVER; else if (opcode->is_return()) - dasm_flags = DASMFLAG_STEP_OUT; + dasm_flags = STEP_OUT; else dasm_flags = 0; @@ -276,113 +184,108 @@ unsigned g65816_disassemble(std::ostream &stream, unsigned int pc, unsigned int util::stream_format(stream, "A"); break; case RELB: - var = (int8_t) read_8(address+1); + var = (int8_t) opcodes.r8((pc+1) & 0xffffff); length++; - util::stream_format(stream, " %06x (%s)", pb | ((pc + length + var)&0xffff), int_8_str(var)); + util::stream_format(stream, " %06x (%s)", (pc & 0xff0000) | ((pc + length + var)&0xffff), int_8_str(var)); break; case RELW: case PER : - var = read_16(address+1); + var = opcodes.r16((pc+1) & 0xffffff); length += 2; - util::stream_format(stream, " %06x (%s)", pb | ((pc + length + var)&0xffff), int_16_str(var)); + util::stream_format(stream, " %06x (%s)", (pc & 0xff0000) | ((pc + length + var)&0xffff), int_16_str(var)); break; case IMM : - if((opcode->flag == M && !m_flag) || (opcode->flag == X && !x_flag)) + if((opcode->flag == M && !m_config->get_m_flag()) || (opcode->flag == X && !m_config->get_x_flag())) { - util::stream_format(stream, " #$%04x", read_16(address+1)); + util::stream_format(stream, " #$%04x", opcodes.r16((pc+1) & 0xffffff)); length += 2; } else { - util::stream_format(stream, " #$%02x", read_8(address+1)); + util::stream_format(stream, " #$%02x", opcodes.r8((pc+1) & 0xffffff)); length++; } break; case A : case PEA : - util::stream_format(stream, " $%04x", read_16(address+1)); + util::stream_format(stream, " $%04x", opcodes.r16((pc+1) & 0xffffff)); length += 2; break; case AI : - util::stream_format(stream, " ($%04x)", read_16(address+1)); + util::stream_format(stream, " ($%04x)", opcodes.r16((pc+1) & 0xffffff)); length += 2; break; case AL : - util::stream_format(stream, " $%06x", read_24(address+1)); + util::stream_format(stream, " $%06x", opcodes.r32((pc+1) & 0xffffff) & 0xffffff); length += 3; break; case ALX : - util::stream_format(stream, " $%06x,X", read_24(address+1)); + util::stream_format(stream, " $%06x,X", opcodes.r32((pc+1) & 0xffffff) & 0xffffff); length += 3; break; case AX : - util::stream_format(stream, " $%04x,X", read_16(address+1)); + util::stream_format(stream, " $%04x,X", opcodes.r16((pc+1) & 0xffffff)); length += 2; break; case AXI : - util::stream_format(stream, " ($%04x,X)", read_16(address+1)); + util::stream_format(stream, " ($%04x,X)", opcodes.r16((pc+1) & 0xffffff)); length += 2; break; case AY : - util::stream_format(stream, " $%04x,Y", read_16(address+1)); + util::stream_format(stream, " $%04x,Y", opcodes.r16((pc+1) & 0xffffff)); length += 2; break; case D : - util::stream_format(stream, " $%02x", read_8(address+1)); + util::stream_format(stream, " $%02x", opcodes.r8((pc+1) & 0xffffff)); length++; break; case DI : case PEI : - util::stream_format(stream, " ($%02x)", read_8(address+1)); + util::stream_format(stream, " ($%02x)", opcodes.r8((pc+1) & 0xffffff)); length++; break; case DIY : - util::stream_format(stream, " ($%02x),Y", read_8(address+1)); + util::stream_format(stream, " ($%02x),Y", opcodes.r8((pc+1) & 0xffffff)); length++; break; case DLI : - util::stream_format(stream, " [$%02x]", read_8(address+1)); + util::stream_format(stream, " [$%02x]", opcodes.r8((pc+1) & 0xffffff)); length++; break; case DLIY: - util::stream_format(stream, " [$%02x],Y", read_8(address+1)); + util::stream_format(stream, " [$%02x],Y", opcodes.r8((pc+1) & 0xffffff)); length++; break; case DX : - util::stream_format(stream, " $%02x,X", read_8(address+1)); + util::stream_format(stream, " $%02x,X", opcodes.r8((pc+1) & 0xffffff)); length++; break; case DXI : - util::stream_format(stream, " ($%02x,X)", read_8(address+1)); + util::stream_format(stream, " ($%02x,X)", opcodes.r8((pc+1) & 0xffffff)); length++; break; case DY : - util::stream_format(stream, " $%02x,Y", read_8(address+1)); + util::stream_format(stream, " $%02x,Y", opcodes.r8((pc+1) & 0xffffff)); length++; break; case S : - util::stream_format(stream, " %s,S", int_8_str(read_8(address+1))); + util::stream_format(stream, " %s,S", int_8_str(opcodes.r8((pc+1) & 0xffffff))); length++; break; case SIY : - util::stream_format(stream, " (%s,S),Y", int_8_str(read_8(address+1))); + util::stream_format(stream, " (%s,S),Y", int_8_str(opcodes.r8((pc+1) & 0xffffff))); length++; break; case SIG : - util::stream_format(stream, " #$%02x", read_8(address+1)); + util::stream_format(stream, " #$%02x", opcodes.r8((pc+1) & 0xffffff)); length++; break; case MVN : case MVP : - util::stream_format(stream, " $%02x, $%02x", read_8(address+2), read_8(address+1)); + util::stream_format(stream, " $%02x, $%02x", opcodes.r8((pc+2) & 0xffffff), opcodes.r8((pc+1) & 0xffffff)); length += 2; break; } - return length | DASMFLAG_SUPPORTED | dasm_flags; -} - -CPU_DISASSEMBLE( g65816_generic ) -{ - return g65816_disassemble(stream, (pc & 0x00ffff), (pc & 0xff0000) >> 16, oprom, 0, 0); + return length | SUPPORTED | dasm_flags; } diff --git a/src/devices/cpu/g65816/g65816ds.h b/src/devices/cpu/g65816/g65816ds.h index 892dd065a10..832754de4cd 100644 --- a/src/devices/cpu/g65816/g65816ds.h +++ b/src/devices/cpu/g65816/g65816ds.h @@ -16,7 +16,68 @@ All rights reserved. */ -unsigned g65816_disassemble(std::ostream &stream, unsigned int pc, unsigned int pb, const uint8_t *oprom, int m_flag, int x_flag); +class g65816_disassembler : public util::disasm_interface +{ +public: + class config { + public: + virtual ~config() = default; + virtual bool get_m_flag() const = 0; + virtual bool get_x_flag() const = 0; + }; + g65816_disassembler(config *conf); + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum class op : unsigned + { + ADC , AND , ASL , BCC , BCS , BEQ , BIT , BMI , BNE , BPL , BRA , + BRK , BRL , BVC , BVS , CLC , CLD , CLI , CLV , CMP , COP , CPX , + CPY , DEA , DEC , DEX , DEY , EOR , INA , INC , INX , INY , JML , + JMP , JSL , JSR , LDA , LDX , LDY , LSR , MVN , MVP , NOP , ORA , + PEA , PEI , PER , PHA , PHB , PHD , PHK , PHP , PHX , PHY , PLA , + PLB , PLD , PLP , PLX , PLY , REP , ROL , ROR , RTI , RTL , RTS , + SBC , SEC , SED , SEI , SEP , STA , STP , STX , STY , STZ , TAX , + TAY , TCS , TCD , TDC , TRB , TSB , TSC , TSX , TXA , TXS , TXY , + TYA , TYX , WAI , WDM , XBA , XCE + }; + + enum + { + IMP , ACC , RELB, RELW, IMM , A , AI , AL , ALX , AX , AXI , + AY , D , DI , DIY , DLI , DLIY, DX , DXI , DY , S , SIY , + SIG , MVN , MVP , PEA , PEI , PER + }; + + enum + { + I, /* ignore */ + M, /* check m bit */ + X /* check x bit */ + }; + + class opcode_struct { + public: + op m_name; + u8 flag; + u8 ea; + + opcode_struct(op n, u8 f, u8 e); + const char *name() const; + bool is_call() const; + bool is_return() const; + }; + + static const char *const s_opnames[]; + static const opcode_struct s_opcodes[256]; + + config *m_config; + + std::string int_8_str(u8 val); + std::string int_16_str(u16 val); +}; #endif /* __G65816DS_H__ */ diff --git a/src/devices/cpu/h6280/6280dasm.cpp b/src/devices/cpu/h6280/6280dasm.cpp index c214a058c52..35b1b60c165 100644 --- a/src/devices/cpu/h6280/6280dasm.cpp +++ b/src/devices/cpu/h6280/6280dasm.cpp @@ -18,69 +18,10 @@ ******************************************************************************/ -#ifdef __OS2__ -/* To avoid name clash of _brk */ -#define __STRICT_ANSI__ -#endif - #include "emu.h" +#include "6280dasm.h" -#define RDOP(addr) (oprom[addr - pc]) -#define RDBYTE(addr) (opram[addr - pc]) -#define RDWORD(addr) (opram[addr - pc] | ( oprom[(addr) + 1 - pc] << 8 )) - -enum addr_mode { - _non=0, /* no additional arguments */ - _acc, /* accumulator */ - _imp, /* implicit */ - _imm, /* immediate */ - _abs, /* absolute */ - _zpg, /* zero page */ - _zpx, /* zero page + X */ - _zpy, /* zero page + Y */ - _zpi, /* zero page indirect */ - _abx, /* absolute + X */ - _aby, /* absolute + Y */ - _rel, /* relative */ - _idx, /* zero page pre indexed */ - _idy, /* zero page post indexed */ - _ind, /* indirect */ - _iax, /* indirect + X */ - _blk, /* block */ - _zrl, /* zero page relative */ - _imz, /* immediate, zero page */ - _izx, /* immediate, zero page + X */ - _ima, /* immediate, absolute */ - _imx /* immediate, absolute + X */ -}; - -enum opcodes { - /* 6502 opcodes */ - _adc=0,_and, _asl, _bcc, _bcs, _beq, _bit, _bmi, - _bne, _bpl, _brk, _bvc, _bvs, _clc, _cld, _cli, - _clv, _cmp, _cpx, _cpy, _dec, _dex, _dey, _eor, - _inc, _inx, _iny, _jmp, _jsr, _lda, _ldx, _ldy, - _lsr, _nop, _ora, _pha, _php, _pla, _plp, _rol, - _ror, _rti, _rts, _sbc, _sec, _sed, _sei, _sta, - _stx, _sty, _tax, _tay, _tsx, _txa, _txs, _tya, - _ill, - - /* Hu6280 extensions */ - _bra, _stz, _trb, _tsb, _dea, _ina, _sax, _bsr, - _phx, _phy, _plx, _ply, _csh, _csl, _tam, _tma, - _cla, _cly, _clx, _st0, _st1, _st2, _tst, _set, - _tdd, _tia, _tii, _tin, _tai, _say, _sxy, - - _sm0, _sm1, _sm2, _sm3, _sm4, _sm5, _sm6, _sm7, - _rm0, _rm1, _rm2, _rm3, _rm4, _rm5, _rm6, _rm7, - - _bs0, _bs1, _bs2, _bs3, _bs4, _bs5, _bs6, _bs7, - _br0, _br1, _br2, _br3, _br4, _br5, _br6, _br7 - -}; - - -static const char *const token[]= +const char *const h6280_disassembler::token[]= { /* 6502 opcodes */ "adc", "and", "asl", "bcc", "bcs", "beq", "bit", "bmi", @@ -105,7 +46,7 @@ static const char *const token[]= "bbr0", "bbr1", "bbr2", "bbr3", "bbr4", "bbr5", "bbr6", "bbr7" }; -static const unsigned char op6280[512]= +const unsigned char h6280_disassembler::op6280[512]= { _brk,_imp, _ora,_idx, _sxy,_imp, _st0,_imm, _tsb,_zpg, _ora,_zpg, _asl,_zpg, _rm0,_zpg, /* 00 */ _php,_imp, _ora,_imm, _asl,_acc, _ill,_non, _tsb,_abs, _ora,_abs, _asl,_abs, _br0,_zrl, @@ -141,16 +82,22 @@ static const unsigned char op6280[512]= _sed,_imp, _sbc,_aby, _plx,_imp, _ill,_non, _ill,_non, _sbc,_abx, _inc,_abx, _bs7,_zrl }; +u32 h6280_disassembler::opcode_alignment() const +{ + return 1; +} + /***************************************************************************** * Disassemble a single command and return the number of bytes it uses. *****************************************************************************/ -CPU_DISASSEMBLE(h6280) +offs_t h6280_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint32_t flags = 0; - int PC, OP, opc, arg; + offs_t PC; + int OP, opc, arg; PC = pc; - OP = RDOP(PC); + OP = opcodes.r8(PC); OP = OP << 1; PC++; @@ -158,9 +105,9 @@ CPU_DISASSEMBLE(h6280) arg = op6280[OP+1]; if (opc == _jsr || opc == _bsr) - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; else if (opc == _rts) - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; switch(arg) { @@ -171,84 +118,84 @@ CPU_DISASSEMBLE(h6280) util::stream_format(stream, "%s", token[opc]); break; case _rel: - util::stream_format(stream, "%-5s$%04X", token[opc], (PC + 1 + (signed char)RDBYTE(PC)) & 0xffff); + util::stream_format(stream, "%-5s$%04X", token[opc], (PC + 1 + (signed char)params.r8(PC)) & 0xffff); PC+=1; break; case _imm: - util::stream_format(stream, "%-5s#$%02X", token[opc], RDBYTE(PC)); + util::stream_format(stream, "%-5s#$%02X", token[opc], params.r8(PC)); PC+=1; break; case _zpg: - util::stream_format(stream, "%-5s$%02X", token[opc], RDBYTE(PC)); + util::stream_format(stream, "%-5s$%02X", token[opc], params.r8(PC)); PC+=1; break; case _zpx: - util::stream_format(stream, "%-5s$%02X,x", token[opc], RDBYTE(PC)); + util::stream_format(stream, "%-5s$%02X,x", token[opc], params.r8(PC)); PC+=1; break; case _zpy: - util::stream_format(stream, "%-5s$%02X,y", token[opc], RDBYTE(PC)); + util::stream_format(stream, "%-5s$%02X,y", token[opc], params.r8(PC)); PC+=1; break; case _idx: - util::stream_format(stream, "%-5s($%02X,x)", token[opc], RDBYTE(PC)); + util::stream_format(stream, "%-5s($%02X,x)", token[opc], params.r8(PC)); PC+=1; break; case _idy: - util::stream_format(stream, "%-5s($%02X),y", token[opc], RDBYTE(PC)); + util::stream_format(stream, "%-5s($%02X),y", token[opc], params.r8(PC)); PC+=1; break; case _zpi: - util::stream_format(stream, "%-5s($%02X)", token[opc], RDBYTE(PC)); + util::stream_format(stream, "%-5s($%02X)", token[opc], params.r8(PC)); PC+=1; break; case _abs: - util::stream_format(stream, "%-5s$%04X", token[opc], RDWORD(PC)); + util::stream_format(stream, "%-5s$%04X", token[opc], params.r16(PC)); PC+=2; break; case _abx: - util::stream_format(stream, "%-5s$%04X,x", token[opc], RDWORD(PC)); + util::stream_format(stream, "%-5s$%04X,x", token[opc], params.r16(PC)); PC+=2; break; case _aby: - util::stream_format(stream, "%-5s$%04X,y", token[opc], RDWORD(PC)); + util::stream_format(stream, "%-5s$%04X,y", token[opc], params.r16(PC)); PC+=2; break; case _ind: - util::stream_format(stream, "%-5s($%04X)", token[opc], RDWORD(PC)); + util::stream_format(stream, "%-5s($%04X)", token[opc], params.r16(PC)); PC+=2; break; case _iax: - util::stream_format(stream, "%-5s($%04X),X", token[opc], RDWORD(PC)); + util::stream_format(stream, "%-5s($%04X),X", token[opc], params.r16(PC)); PC+=2; break; case _blk: - util::stream_format(stream, "%-5s$%04X $%04X $%04X", token[opc], RDWORD(PC), RDWORD(PC+2), RDWORD(PC+4)); + util::stream_format(stream, "%-5s$%04X $%04X $%04X", token[opc], params.r16(PC), params.r16(PC+2), params.r16(PC+4)); PC+=6; break; case _zrl: - util::stream_format(stream, "%-5s$%02X $%04X", token[opc], RDBYTE(PC), (PC + 2 + (signed char)RDBYTE(PC+1)) & 0xffff); + util::stream_format(stream, "%-5s$%02X $%04X", token[opc], params.r8(PC), (PC + 2 + (signed char)params.r8(PC+1)) & 0xffff); PC+=2; break; case _imz: - util::stream_format(stream, "%-5s#$%02X $%02X", token[opc], RDBYTE(PC), RDBYTE(PC+1)); + util::stream_format(stream, "%-5s#$%02X $%02X", token[opc], params.r8(PC), params.r8(PC+1)); PC+=2; break; case _izx: - util::stream_format(stream, "%-5s#$%02X $%02X,x", token[opc], RDBYTE(PC), RDBYTE(PC+1)); + util::stream_format(stream, "%-5s#$%02X $%02X,x", token[opc], params.r8(PC), params.r8(PC+1)); PC+=2; break; case _ima: - util::stream_format(stream, "%-5s#$%02X $%04X", token[opc], RDBYTE(PC), RDWORD(PC+1)); + util::stream_format(stream, "%-5s#$%02X $%04X", token[opc], params.r8(PC), params.r16(PC+1)); PC+=3; break; case _imx: - util::stream_format(stream, "%-5s#$%02X $%04X,x", token[opc], RDBYTE(PC), RDWORD(PC+1)); + util::stream_format(stream, "%-5s#$%02X $%04X,x", token[opc], params.r8(PC), params.r16(PC+1)); PC+=3; break; default: util::stream_format(stream, "%-5s$%02X", token[opc], OP >> 1); } - return (PC - pc) | flags | DASMFLAG_SUPPORTED; + return (PC - pc) | flags | SUPPORTED; } diff --git a/src/devices/cpu/h6280/6280dasm.h b/src/devices/cpu/h6280/6280dasm.h new file mode 100644 index 00000000000..5186720dfa8 --- /dev/null +++ b/src/devices/cpu/h6280/6280dasm.h @@ -0,0 +1,90 @@ +// license:BSD-3-Clause +// copyright-holders:Bryan McPhail +/***************************************************************************** + + 6280dasm.c Hudsonsoft Hu6280 (HuC6280/Hu6280a) disassembler + + Copyright Bryan McPhail, mish@tendril.co.uk + + This source code is based (with permission!) on the 6502 emulator by + Juergen Buchmueller. It is released as part of the Mame emulator project. + Let me know if you intend to use this code in any other project. + + + Notes relating to Mame: + + The dasm window shows 'real' memory, as executed by the cpu + The data windows show 'physical' memory, as defined in the memory map + +******************************************************************************/ + +#ifndef MAME_CPU_H6280_6280DASM_H +#define MAME_CPU_H6280_6280DASM_H + +#pragma once + +class h6280_disassembler : public util::disasm_interface +{ +public: + h6280_disassembler() = default; + virtual ~h6280_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum addr_mode { + _non=0, /* no additional arguments */ + _acc, /* accumulator */ + _imp, /* implicit */ + _imm, /* immediate */ + _abs, /* absolute */ + _zpg, /* zero page */ + _zpx, /* zero page + X */ + _zpy, /* zero page + Y */ + _zpi, /* zero page indirect */ + _abx, /* absolute + X */ + _aby, /* absolute + Y */ + _rel, /* relative */ + _idx, /* zero page pre indexed */ + _idy, /* zero page post indexed */ + _ind, /* indirect */ + _iax, /* indirect + X */ + _blk, /* block */ + _zrl, /* zero page relative */ + _imz, /* immediate, zero page */ + _izx, /* immediate, zero page + X */ + _ima, /* immediate, absolute */ + _imx /* immediate, absolute + X */ + }; + + enum opcodes { + /* 6502 opcodes */ + _adc=0,_and, _asl, _bcc, _bcs, _beq, _bit, _bmi, + _bne, _bpl, _brk, _bvc, _bvs, _clc, _cld, _cli, + _clv, _cmp, _cpx, _cpy, _dec, _dex, _dey, _eor, + _inc, _inx, _iny, _jmp, _jsr, _lda, _ldx, _ldy, + _lsr, _nop, _ora, _pha, _php, _pla, _plp, _rol, + _ror, _rti, _rts, _sbc, _sec, _sed, _sei, _sta, + _stx, _sty, _tax, _tay, _tsx, _txa, _txs, _tya, + _ill, + + /* Hu6280 extensions */ + _bra, _stz, _trb, _tsb, _dea, _ina, _sax, _bsr, + _phx, _phy, _plx, _ply, _csh, _csl, _tam, _tma, + _cla, _cly, _clx, _st0, _st1, _st2, _tst, _set, + _tdd, _tia, _tii, _tin, _tai, _say, _sxy, + + _sm0, _sm1, _sm2, _sm3, _sm4, _sm5, _sm6, _sm7, + _rm0, _rm1, _rm2, _rm3, _rm4, _rm5, _rm6, _rm7, + + _bs0, _bs1, _bs2, _bs3, _bs4, _bs5, _bs6, _bs7, + _br0, _br1, _br2, _br3, _br4, _br5, _br6, _br7 + }; + + static const char *const token[]; + static const unsigned char op6280[512]; + +}; + +#endif diff --git a/src/devices/cpu/h6280/h6280.cpp b/src/devices/cpu/h6280/h6280.cpp index c8a81af0532..c47ed31a70f 100644 --- a/src/devices/cpu/h6280/h6280.cpp +++ b/src/devices/cpu/h6280/h6280.cpp @@ -112,6 +112,7 @@ #include "emu.h" #include "h6280.h" +#include "6280dasm.h" #include "debugger.h" /* 6280 flags */ @@ -300,7 +301,7 @@ void h6280_device::device_reset() m_io_buffer = 0; m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); /* set I and B flags */ @@ -948,7 +949,7 @@ inline void h6280_device::bpl() ***************************************************************/ inline void h6280_device::brk() { - logerror("BRK %04xn",PCW); + logerror("BRK %04x\n",PCW); clear_t(); PCW++; push(PCH); @@ -2220,36 +2221,13 @@ void h6280_device::state_string_export(const device_state_entry &entry, std::str //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t h6280_device::disasm_min_opcode_bytes() const -{ - return 1; -} - - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t h6280_device::disasm_max_opcode_bytes() const -{ - return 7; -} - - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t h6280_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *h6280_device::create_disassembler() { - extern CPU_DISASSEMBLE( h6280 ); - return CPU_DISASSEMBLE_NAME(h6280)(this, stream, pc, oprom, opram, options); + return new h6280_disassembler; } diff --git a/src/devices/cpu/h6280/h6280.h b/src/devices/cpu/h6280/h6280.h index dc6a3ddb47f..e744247e8cb 100644 --- a/src/devices/cpu/h6280/h6280.h +++ b/src/devices/cpu/h6280/h6280.h @@ -89,9 +89,7 @@ protected: virtual bool memory_translate(int spacenum, int intention, offs_t &address) override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // device_state_interface overrides virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; @@ -359,7 +357,7 @@ protected: // address spaces address_space *m_program; address_space *m_io; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; typedef void (h6280_device::*ophandler)(); diff --git a/src/devices/cpu/h8/h8.cpp b/src/devices/cpu/h8/h8.cpp index 516c2253496..e54155b120d 100644 --- a/src/devices/cpu/h8/h8.cpp +++ b/src/devices/cpu/h8/h8.cpp @@ -14,6 +14,7 @@ #include "h8.h" #include "h8_dma.h" #include "h8_dtc.h" +#include "h8d.h" h8_device::h8_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, bool mode_a16, address_map_delegate map_delegate) : cpu_device(mconfig, type, tag, owner, clock), @@ -31,7 +32,7 @@ h8_device::h8_device(const machine_config &mconfig, device_type type, const char void h8_device::device_start() { program = &space(AS_PROGRAM); - direct = &program->direct(); + direct = program->direct<0>(); io = &space(AS_IO); state_add(STATE_GENPC, "GENPC", NPC).noshow(); @@ -324,256 +325,6 @@ void h8_device::state_string_export(const device_state_entry &entry, std::string } } - -uint32_t h8_device::disasm_min_opcode_bytes() const -{ - return 2; -} - -uint32_t h8_device::disasm_max_opcode_bytes() const -{ - return 10; -} - -void h8_device::disassemble_am(std::ostream &stream, int am, offs_t pc, const uint8_t *oprom, uint32_t opcode, int slot, int offset) -{ - static const char *const r8_names[16] = { - "r0h", "r1h", "r2h", "r3h", "r4h", "r5h", "r6h", "r7h", - "r0l", "r1l", "r2l", "r3l", "r4l", "r5l", "r6l", "r7l" - }; - - static const char *const r16_names[16] = { - "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", - "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7", - }; - - static const char *const r32_names[8] = { - "er0", "er1", "er2", "er3", "er4", "er5", "er6", "sp", - }; - - switch(am) { - case DASM_r8l: - util::stream_format(stream, "%s", r8_names[opcode & 15]); - break; - - case DASM_r8h: - util::stream_format(stream, "%s", r8_names[(opcode >> 4) & 15]); - break; - - case DASM_r8u: - util::stream_format(stream, "%s", r8_names[(opcode >> 8) & 15]); - break; - - case DASM_r16l: - util::stream_format(stream, "%s", r16_names[opcode & 15]); - break; - - case DASM_r16h: - util::stream_format(stream, "%s", r16_names[(opcode >> 4) & 15]); - break; - - case DASM_r32l: - util::stream_format(stream, "%s", r32_names[opcode & 7]); - break; - - case DASM_r32h: - util::stream_format(stream, "%s", r32_names[(opcode >> 4) & 7]); - break; - - case DASM_r16ih: - util::stream_format(stream, "@%s", r16_names[(opcode >> 4) & 7]); - break; - - case DASM_r16ihh: - util::stream_format(stream, "@%s", r16_names[(opcode >> 20) & 7]); - break; - - case DASM_pr16h: - util::stream_format(stream, "@-%s", r16_names[(opcode >> 4) & 7]); - break; - - case DASM_r16ph: - util::stream_format(stream, "@%s+", r16_names[(opcode >> 4) & 7]); - break; - - case DASM_r16d16h: - util::stream_format(stream, "@(%x, %s)", (oprom[offset-2] << 8) | oprom[offset-1], r16_names[(opcode >> 4) & 7]); - break; - - case DASM_r32ih: - util::stream_format(stream, "@%s", r32_names[(opcode >> 4) & 7]); - break; - - case DASM_r32ihh: - util::stream_format(stream, "@%s", r32_names[(opcode >> 20) & 7]); - break; - - case DASM_pr32h: - util::stream_format(stream, "@-%s", r32_names[(opcode >> 4) & 7]); - break; - - case DASM_r32pl: - util::stream_format(stream, "@%s+", r32_names[opcode & 7]); - break; - - case DASM_r32ph: - util::stream_format(stream, "@%s+", r32_names[(opcode >> 4) & 7]); - break; - - case DASM_r32d16h: - util::stream_format(stream, "@(%x, %s)", (oprom[offset-2] << 8) | oprom[offset-1], r32_names[(opcode >> 4) & 7]); - break; - - case DASM_r32d32hh: - util::stream_format(stream, "@(%x, %s)", (oprom[offset-4] << 24) | (oprom[offset-3] << 16) | (oprom[offset-2] << 8) | oprom[offset-1], r32_names[(opcode >> 20) & 7]); - break; - - case DASM_psp: - util::stream_format(stream, "@-sp"); - break; - - case DASM_spp: - util::stream_format(stream, "@sp+"); - break; - - case DASM_r32n2l: - util::stream_format(stream, "%s-%s", r32_names[opcode & 6], r32_names[(opcode & 6) + 1]); - break; - - case DASM_r32n3l: - util::stream_format(stream, "%s-%s", r32_names[opcode & 4], r32_names[(opcode & 4) + 2]); - break; - - case DASM_r32n4l: - util::stream_format(stream, "%s-%s", r32_names[opcode & 4], r32_names[(opcode & 4) + 3]); - break; - - case DASM_abs8: - util::stream_format(stream, "@%08x", 0xffffff00 | oprom[1]); - break; - - case DASM_abs16: - if(offset >= 6) - util::stream_format(stream, "@%08x", int16_t((oprom[offset-4] << 8) | oprom[offset-3])); - else - util::stream_format(stream, "@%08x", int16_t((oprom[offset-2] << 8) | oprom[offset-1])); - break; - - case DASM_abs32: - if(slot == 3) - util::stream_format(stream, "@%08x", (oprom[offset-6] << 24) | (oprom[offset-5] << 16) | (oprom[offset-4] << 8) | oprom[offset-3]); - else - util::stream_format(stream, "@%08x", (oprom[offset-4] << 24) | (oprom[offset-3] << 16) | (oprom[offset-2] << 8) | oprom[offset-1]); - break; - - case DASM_abs8i: - util::stream_format(stream, "@%02x", oprom[1]); - break; - - case DASM_abs16e: - util::stream_format(stream, "%04x", (oprom[2] << 8) | oprom[3]); - break; - - case DASM_abs24e: - util::stream_format(stream, "%08x", (oprom[1] << 16) | (oprom[2] << 8) | oprom[3]); - break; - - case DASM_rel8: - util::stream_format(stream, "%08x", pc + 2 + int8_t(oprom[1])); - break; - - case DASM_rel16: - util::stream_format(stream, "%08x", pc + 4 + int16_t((oprom[2] << 8) | oprom[3])); - break; - - case DASM_one: - util::stream_format(stream, "#1"); - break; - - case DASM_two: - util::stream_format(stream, "#2"); - break; - - case DASM_four: - util::stream_format(stream, "#4"); - break; - - case DASM_imm2: - util::stream_format(stream, "#%x", (opcode >> 4) & 3); - break; - - case DASM_imm3: - util::stream_format(stream, "#%x", (opcode >> 4) & 7); - break; - - case DASM_imm8: - util::stream_format(stream, "#%02x", oprom[1]); - break; - - case DASM_imm16: - util::stream_format(stream, "#%04x", (oprom[2] << 8) | oprom[3]); - break; - - case DASM_imm32: - util::stream_format(stream, "#%08x", (oprom[2] << 16) | (oprom[3] << 16) | (oprom[4] << 8) | oprom[5]); - break; - - case DASM_ccr: - util::stream_format(stream, "ccr"); - break; - - case DASM_exr: - util::stream_format(stream, "exr"); - break; - - case DASM_macl: - util::stream_format(stream, "macl"); - break; - - case DASM_mach: - util::stream_format(stream, "mach"); - break; - - default: - util::stream_format(stream, "<%d>", am); - break; - } -} - -offs_t h8_device::disassemble_generic(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options, const disasm_entry *table) -{ - uint32_t slot[5]; - slot[0] = (oprom[0] << 8) | oprom[1]; - slot[1] = (oprom[0] << 24) | (oprom[1] << 16) | (oprom[2] << 8) | oprom[3]; - slot[2] = (oprom[0] << 24) | (oprom[1] << 16) | (oprom[4] << 8) | oprom[5]; - slot[3] = (oprom[0] << 24) | (oprom[1] << 16) | (oprom[6] << 8) | oprom[7]; - slot[4] = (oprom[2] << 24) | (oprom[3] << 16) | (oprom[4] << 8) | oprom[5]; - - int inst; - for(inst=0;; inst++) { - const disasm_entry &e = table[inst]; - if((slot[e.slot] & e.mask) == e.val && (slot[0] & e.mask0) == e.val0) - break; - } - const disasm_entry &e = table[inst]; - stream << e.opcode; - - if(e.am1 != DASM_none) { - stream << ' '; - disassemble_am(stream, e.am1, pc, oprom, slot[e.slot], e.slot, e.flags & DASMFLAG_LENGTHMASK); - } - if(e.am2 != DASM_none) { - stream << ", "; - disassemble_am(stream, e.am2, pc, oprom, slot[e.slot], e.slot, e.flags & DASMFLAG_LENGTHMASK); - } - return e.flags | DASMFLAG_SUPPORTED; -} - -offs_t h8_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) -{ - return disassemble_generic(stream, pc, oprom, opram, options, disasm_entries); -} - uint16_t h8_device::read16i(uint32_t adr) { icount--; @@ -1592,4 +1343,9 @@ void h8_device::set_nz32(uint32_t v) CCR |= F_N; } +util::disasm_interface *h8_device::create_disassembler() +{ + return new h8_disassembler; +} + #include "cpu/h8/h8.hxx" diff --git a/src/devices/cpu/h8/h8.h b/src/devices/cpu/h8/h8.h index 3df33f8de1b..78ce598bb84 100644 --- a/src/devices/cpu/h8/h8.h +++ b/src/devices/cpu/h8/h8.h @@ -72,15 +72,6 @@ public: bool access_is_dma() const { return inst_state == STATE_DMA || inst_state == STATE_DTC; } protected: - struct disasm_entry { - int slot; - uint32_t val, mask; - uint16_t val0, mask0; - const char *opcode; - int am1, am2; - offs_t flags; - }; - enum { F_I = 0x80, F_UI = 0x40, @@ -96,64 +87,6 @@ protected: EXR_I = 0x07 }; - enum { - DASM_none, /* no additional arguments */ - - DASM_r8l, /* 8-bits register in bits 0-3 */ - DASM_r8h, /* 8-bits register in bits 4-7 */ - DASM_r8u, /* 8-bits register in bits 8-15 */ - DASM_r16l, /* 16-bits register in bits 0-3 */ - DASM_r16h, /* 16-bits register in bits 4-7 */ - DASM_r32l, /* 32-bits register in bits 0-3 */ - DASM_r32h, /* 32-bits register in bits 4-7 */ - - DASM_r16ih, /* indexed through 16-bits register in bits 4-6 */ - DASM_r16ihh, /* indexed through 16-bits register in bits 4-6 in 4-bytes instruction */ - DASM_pr16h, /* indexed through predecremented 16-bits register in bits 4-6 */ - DASM_r16ph, /* indexed through postincremented 16-bits register in bits 4-6 */ - DASM_r16d16h, /* indexed through 16-bits register in bits 4-6 with 16-bits displacement at end of instruction */ - - DASM_r32ih, /* indexed through 32-bits register in bits 4-6 */ - DASM_r32ihh, /* indexed through 32-bits register in bits 4-6 in 4-bytes instruction */ - DASM_pr32h, /* indexed through predecremented 32-bits register in bits 4-6 */ - DASM_r32pl, /* indexed through postincremented 32-bits register in bits 0-2 */ - DASM_r32ph, /* indexed through postincremented 32-bits register in bits 4-6 */ - DASM_r32d16h, /* indexed through 32-bits register in bits 4-6 with 16-bits displacement at end of instruction */ - DASM_r32d32hh, /* indexed through 32-bits register in bits 20-22 with 32-bits displacement at end of instruction */ - - DASM_psp, /* indexed through predecremented stack pointer */ - DASM_spp, /* indexed through postincremented stack pointer */ - - DASM_r32n2l, /* Block of 2 registers */ - DASM_r32n3l, /* Block of 3 registers */ - DASM_r32n4l, /* Block of 4 registers */ - - DASM_abs8, /* 8-bit address present at +1 */ - DASM_abs16, /* 16-bit address present at end of instruction */ - DASM_abs32, /* 32-bit address present at end of instruction */ - DASM_abs8i, /* 8-bit indirect jump address present at +1 */ - DASM_abs16e, /* 16-bit jump address present at +2 */ - DASM_abs24e, /* 24-bit jump address present at +1 */ - - DASM_rel8, /* 8-bit pc-relative jump address at +1, offset=2 */ - DASM_rel16, /* 16-bit pc-relative jump address at +2, offset=4 */ - - DASM_one, /* immediate value 1 */ - DASM_two, /* immediate value 2 */ - DASM_four, /* immediate value 4 */ - - DASM_imm2, /* 2-bit immediate in bits 4-5 (trapa) */ - DASM_imm3, /* 3-bit immediate in bits 4-6 (bit selection */ - DASM_imm8, /* 8-bit immediate at +1 */ - DASM_imm16, /* 16-bit immediate at +2 */ - DASM_imm32, /* 32-bit immediate at +2 */ - - DASM_ccr, /* internal register ccr */ - DASM_exr, /* internal register exr */ - DASM_macl, /* internal register macl */ - DASM_mach /* internal register mach */ - }; - h8_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, bool mode_a16, address_map_delegate map_delegate); // device-level overrides @@ -175,13 +108,11 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; address_space_config program_config, io_config; address_space *program, *io; - direct_read_data *direct; + direct_read_data<0> *direct; h8_dma_device *dma_device; h8_dtc_device *dtc_device; h8_dma_state *current_dma; @@ -208,11 +139,6 @@ protected: int irq_level, taken_irq_level; bool irq_required, irq_nmi; - static const disasm_entry disasm_entries[]; - - offs_t disassemble_generic(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options, const disasm_entry *table); - void disassemble_am(std::ostream &stream, int am, offs_t pc, const uint8_t *oprom, uint32_t opcode, int slot, int offset); - virtual void do_exec_full(); virtual void do_exec_partial(); static void add_event(uint64_t &event_time, uint64_t new_event); diff --git a/src/devices/cpu/h8/h8_adc.cpp b/src/devices/cpu/h8/h8_adc.cpp index 979b13fe631..76b03584e6d 100644 --- a/src/devices/cpu/h8/h8_adc.cpp +++ b/src/devices/cpu/h8/h8_adc.cpp @@ -168,7 +168,7 @@ void h8_adc_device::conversion_wait(bool first, bool poweron, uint64_t current_t void h8_adc_device::buffer_value(int port, int buffer) { - buf[buffer] = io->read_word(2*(h8_device::ADC_0 + port)); + buf[buffer] = io->read_word(h8_device::ADC_0 + port); if(V>=1) logerror("adc buffer %d -> %d:%03x\n", port, buffer, buf[buffer]); } diff --git a/src/devices/cpu/h8/h8_port.cpp b/src/devices/cpu/h8/h8_port.cpp index ae63eedad51..bc21c99d6df 100644 --- a/src/devices/cpu/h8/h8_port.cpp +++ b/src/devices/cpu/h8/h8_port.cpp @@ -13,7 +13,7 @@ h8_port_device::h8_port_device(const machine_config &mconfig, const char *tag, d void h8_port_device::set_info(int _address, uint8_t _default_ddr, uint8_t _mask) { - address = 2*_address; + address = _address; default_ddr = _default_ddr; mask = _mask; } diff --git a/src/devices/cpu/h8/h8d.cpp b/src/devices/cpu/h8/h8d.cpp new file mode 100644 index 00000000000..b157aedd3c7 --- /dev/null +++ b/src/devices/cpu/h8/h8d.cpp @@ -0,0 +1,262 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + h8d.h + + H8-300 base cpu emulation, disassembler + +***************************************************************************/ + +#include "emu.h" +#include "h8d.h" +#include "cpu/h8/h8d.hxx" + +h8_disassembler::h8_disassembler(const disasm_entry *_table) : table(_table) +{ +} + +h8_disassembler::h8_disassembler() : h8_disassembler(disasm_entries) +{ +} + +u32 h8_disassembler::opcode_alignment() const +{ + return 2; +} + +void h8_disassembler::disassemble_am(std::ostream &stream, int am, offs_t pc, const data_buffer &opcodes, u32 opcode, int slot, int offset) +{ + static const char *const r8_names[16] = { + "r0h", "r1h", "r2h", "r3h", "r4h", "r5h", "r6h", "r7h", + "r0l", "r1l", "r2l", "r3l", "r4l", "r5l", "r6l", "r7l" + }; + + static const char *const r16_names[16] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7", + }; + + static const char *const r32_names[8] = { + "er0", "er1", "er2", "er3", "er4", "er5", "er6", "sp", + }; + + offs_t epc = pc + offset; + + switch(am) { + case DASM_r8l: + util::stream_format(stream, "%s", r8_names[opcode & 15]); + break; + + case DASM_r8h: + util::stream_format(stream, "%s", r8_names[(opcode >> 4) & 15]); + break; + + case DASM_r8u: + util::stream_format(stream, "%s", r8_names[(opcode >> 8) & 15]); + break; + + case DASM_r16l: + util::stream_format(stream, "%s", r16_names[opcode & 15]); + break; + + case DASM_r16h: + util::stream_format(stream, "%s", r16_names[(opcode >> 4) & 15]); + break; + + case DASM_r32l: + util::stream_format(stream, "%s", r32_names[opcode & 7]); + break; + + case DASM_r32h: + util::stream_format(stream, "%s", r32_names[(opcode >> 4) & 7]); + break; + + case DASM_r16ih: + util::stream_format(stream, "@%s", r16_names[(opcode >> 4) & 7]); + break; + + case DASM_r16ihh: + util::stream_format(stream, "@%s", r16_names[(opcode >> 20) & 7]); + break; + + case DASM_pr16h: + util::stream_format(stream, "@-%s", r16_names[(opcode >> 4) & 7]); + break; + + case DASM_r16ph: + util::stream_format(stream, "@%s+", r16_names[(opcode >> 4) & 7]); + break; + + case DASM_r16d16h: + util::stream_format(stream, "@(%x, %s)", opcodes.r16(epc-2), r16_names[(opcode >> 4) & 7]); + break; + + case DASM_r32ih: + util::stream_format(stream, "@%s", r32_names[(opcode >> 4) & 7]); + break; + + case DASM_r32ihh: + util::stream_format(stream, "@%s", r32_names[(opcode >> 20) & 7]); + break; + + case DASM_pr32h: + util::stream_format(stream, "@-%s", r32_names[(opcode >> 4) & 7]); + break; + + case DASM_r32pl: + util::stream_format(stream, "@%s+", r32_names[opcode & 7]); + break; + + case DASM_r32ph: + util::stream_format(stream, "@%s+", r32_names[(opcode >> 4) & 7]); + break; + + case DASM_r32d16h: + util::stream_format(stream, "@(%x, %s)", opcodes.r16(epc-2), r32_names[(opcode >> 4) & 7]); + break; + + case DASM_r32d32hh: + util::stream_format(stream, "@(%x, %s)", opcodes.r32(epc-4), r32_names[(opcode >> 20) & 7]); + break; + + case DASM_psp: + util::stream_format(stream, "@-sp"); + break; + + case DASM_spp: + util::stream_format(stream, "@sp+"); + break; + + case DASM_r32n2l: + util::stream_format(stream, "%s-%s", r32_names[opcode & 6], r32_names[(opcode & 6) + 1]); + break; + + case DASM_r32n3l: + util::stream_format(stream, "%s-%s", r32_names[opcode & 4], r32_names[(opcode & 4) + 2]); + break; + + case DASM_r32n4l: + util::stream_format(stream, "%s-%s", r32_names[opcode & 4], r32_names[(opcode & 4) + 3]); + break; + + case DASM_abs8: + util::stream_format(stream, "@%08x", 0xffffff00 | opcodes.r8(pc+1)); + break; + + case DASM_abs16: + if(offset >= 6) + util::stream_format(stream, "@%08x", s16(opcodes.r16(epc-4))); + else + util::stream_format(stream, "@%08x", s16(opcodes.r16(epc-2))); + break; + + case DASM_abs32: + if(slot == 3) + util::stream_format(stream, "@%08x", opcodes.r32(epc-6)); + else + util::stream_format(stream, "@%08x", opcodes.r32(epc-4)); + break; + + case DASM_abs8i: + util::stream_format(stream, "@%02x", opcodes.r8(pc+1)); + break; + + case DASM_abs16e: + util::stream_format(stream, "%04x", opcodes.r16(pc+2)); + break; + + case DASM_abs24e: + util::stream_format(stream, "%08x", opcodes.r32(pc) & 0xffffff); + break; + + case DASM_rel8: + util::stream_format(stream, "%08x", pc + 2 + s8(opcodes.r8(pc+1))); + break; + + case DASM_rel16: + util::stream_format(stream, "%08x", pc + 4 + s16(opcodes.r16(pc+2))); + break; + + case DASM_one: + util::stream_format(stream, "#1"); + break; + + case DASM_two: + util::stream_format(stream, "#2"); + break; + + case DASM_four: + util::stream_format(stream, "#4"); + break; + + case DASM_imm2: + util::stream_format(stream, "#%x", (opcode >> 4) & 3); + break; + + case DASM_imm3: + util::stream_format(stream, "#%x", (opcode >> 4) & 7); + break; + + case DASM_imm8: + util::stream_format(stream, "#%02x", opcodes.r8(pc+1)); + break; + + case DASM_imm16: + util::stream_format(stream, "#%04x", opcodes.r16(pc+2)); + break; + + case DASM_imm32: + util::stream_format(stream, "#%08x", opcodes.r32(pc+2)); + break; + + case DASM_ccr: + util::stream_format(stream, "ccr"); + break; + + case DASM_exr: + util::stream_format(stream, "exr"); + break; + + case DASM_macl: + util::stream_format(stream, "macl"); + break; + + case DASM_mach: + util::stream_format(stream, "mach"); + break; + + default: + util::stream_format(stream, "<%d>", am); + break; + } +} + +offs_t h8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + u32 slot[5]; + slot[0] = opcodes.r16(pc); + slot[1] = opcodes.r32(pc); + slot[2] = (opcodes.r16(pc) << 16) | opcodes.r16(pc+4); + slot[3] = (opcodes.r16(pc) << 16) | opcodes.r16(pc+6); + slot[4] = opcodes.r32(pc+2); + + int inst; + for(inst=0;; inst++) { + const disasm_entry &e = table[inst]; + if((slot[e.slot] & e.mask) == e.val && (slot[0] & e.mask0) == e.val0) + break; + } + const disasm_entry &e = table[inst]; + stream << e.opcode; + + if(e.am1 != DASM_none) { + stream << ' '; + disassemble_am(stream, e.am1, pc, opcodes, slot[e.slot], e.slot, e.flags & LENGTHMASK); + } + if(e.am2 != DASM_none) { + stream << ", "; + disassemble_am(stream, e.am2, pc, opcodes, slot[e.slot], e.slot, e.flags & LENGTHMASK); + } + return e.flags | SUPPORTED; +} diff --git a/src/devices/cpu/h8/h8d.h b/src/devices/cpu/h8/h8d.h new file mode 100644 index 00000000000..65ba1d7fd97 --- /dev/null +++ b/src/devices/cpu/h8/h8d.h @@ -0,0 +1,101 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + h8d.h + + H8-300 base cpu emulation, disassembler + +***************************************************************************/ + +#ifndef MAME_CPU_H8_H8D_H +#define MAME_CPU_H8_H8D_H + +#pragma once + +class h8_disassembler : public util::disasm_interface +{ +protected: + struct disasm_entry { + int slot; + u32 val, mask; + u16 val0, mask0; + const char *opcode; + int am1, am2; + offs_t flags; + }; + +public: + h8_disassembler(const disasm_entry *_table); + h8_disassembler(); + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +protected: + enum { + DASM_none, /* no additional arguments */ + + DASM_r8l, /* 8-bits register in bits 0-3 */ + DASM_r8h, /* 8-bits register in bits 4-7 */ + DASM_r8u, /* 8-bits register in bits 8-15 */ + DASM_r16l, /* 16-bits register in bits 0-3 */ + DASM_r16h, /* 16-bits register in bits 4-7 */ + DASM_r32l, /* 32-bits register in bits 0-3 */ + DASM_r32h, /* 32-bits register in bits 4-7 */ + + DASM_r16ih, /* indexed through 16-bits register in bits 4-6 */ + DASM_r16ihh, /* indexed through 16-bits register in bits 4-6 in 4-bytes instruction */ + DASM_pr16h, /* indexed through predecremented 16-bits register in bits 4-6 */ + DASM_r16ph, /* indexed through postincremented 16-bits register in bits 4-6 */ + DASM_r16d16h, /* indexed through 16-bits register in bits 4-6 with 16-bits displacement at end of instruction */ + + DASM_r32ih, /* indexed through 32-bits register in bits 4-6 */ + DASM_r32ihh, /* indexed through 32-bits register in bits 4-6 in 4-bytes instruction */ + DASM_pr32h, /* indexed through predecremented 32-bits register in bits 4-6 */ + DASM_r32pl, /* indexed through postincremented 32-bits register in bits 0-2 */ + DASM_r32ph, /* indexed through postincremented 32-bits register in bits 4-6 */ + DASM_r32d16h, /* indexed through 32-bits register in bits 4-6 with 16-bits displacement at end of instruction */ + DASM_r32d32hh, /* indexed through 32-bits register in bits 20-22 with 32-bits displacement at end of instruction */ + + DASM_psp, /* indexed through predecremented stack pointer */ + DASM_spp, /* indexed through postincremented stack pointer */ + + DASM_r32n2l, /* Block of 2 registers */ + DASM_r32n3l, /* Block of 3 registers */ + DASM_r32n4l, /* Block of 4 registers */ + + DASM_abs8, /* 8-bit address present at +1 */ + DASM_abs16, /* 16-bit address present at end of instruction */ + DASM_abs32, /* 32-bit address present at end of instruction */ + DASM_abs8i, /* 8-bit indirect jump address present at +1 */ + DASM_abs16e, /* 16-bit jump address present at +2 */ + DASM_abs24e, /* 24-bit jump address present at +1 */ + + DASM_rel8, /* 8-bit pc-relative jump address at +1, offset=2 */ + DASM_rel16, /* 16-bit pc-relative jump address at +2, offset=4 */ + + DASM_one, /* immediate value 1 */ + DASM_two, /* immediate value 2 */ + DASM_four, /* immediate value 4 */ + + DASM_imm2, /* 2-bit immediate in bits 4-5 (trapa) */ + DASM_imm3, /* 3-bit immediate in bits 4-6 (bit selection */ + DASM_imm8, /* 8-bit immediate at +1 */ + DASM_imm16, /* 16-bit immediate at +2 */ + DASM_imm32, /* 32-bit immediate at +2 */ + + DASM_ccr, /* internal register ccr */ + DASM_exr, /* internal register exr */ + DASM_macl, /* internal register macl */ + DASM_mach /* internal register mach */ + }; + + void disassemble_am(std::ostream &stream, int am, offs_t pc, const data_buffer &opcodes, u32 opcode, int slot, int offset); + + const disasm_entry *table; + + static const disasm_entry disasm_entries[]; +}; + +#endif diff --git a/src/devices/cpu/h8/h8h.cpp b/src/devices/cpu/h8/h8h.cpp index 37756da3d12..97b945d8166 100644 --- a/src/devices/cpu/h8/h8h.cpp +++ b/src/devices/cpu/h8/h8h.cpp @@ -2,6 +2,7 @@ // copyright-holders:Olivier Galibert #include "emu.h" #include "h8h.h" +#include "h8hd.h" h8h_device::h8h_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_delegate map_delegate) : h8_device(mconfig, type, tag, owner, clock, false, map_delegate) @@ -10,9 +11,9 @@ h8h_device::h8h_device(const machine_config &mconfig, device_type type, const ch mode_advanced = true; } -offs_t h8h_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *h8h_device::create_disassembler() { - return disassemble_generic(stream, pc, oprom, opram, options, disasm_entries); + return new h8h_disassembler; } #include "cpu/h8/h8h.hxx" diff --git a/src/devices/cpu/h8/h8h.h b/src/devices/cpu/h8/h8h.h index 460ddcefc3a..4c8c226a516 100644 --- a/src/devices/cpu/h8/h8h.h +++ b/src/devices/cpu/h8/h8h.h @@ -20,11 +20,9 @@ class h8h_device : public h8_device { protected: - static const disasm_entry disasm_entries[]; - h8h_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_delegate map_delegate); - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void do_exec_full() override; virtual void do_exec_partial() override; diff --git a/src/devices/cpu/h8/h8hd.cpp b/src/devices/cpu/h8/h8hd.cpp new file mode 100644 index 00000000000..c6cb3238784 --- /dev/null +++ b/src/devices/cpu/h8/h8hd.cpp @@ -0,0 +1,17 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + h8d.h + + H8-300H base cpu emulation, disassembler + +***************************************************************************/ + +#include "emu.h" +#include "h8hd.h" +#include "cpu/h8/h8hd.hxx" + +h8h_disassembler::h8h_disassembler() : h8_disassembler(disasm_entries) +{ +} diff --git a/src/devices/cpu/h8/h8hd.h b/src/devices/cpu/h8/h8hd.h new file mode 100644 index 00000000000..5123ee32563 --- /dev/null +++ b/src/devices/cpu/h8/h8hd.h @@ -0,0 +1,28 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + h8hd.h + + H8-300H base cpu emulation, disassembler + +***************************************************************************/ + +#ifndef MAME_CPU_H8_H8HD_H +#define MAME_CPU_H8_H8HD_H + +#pragma once + +#include "h8d.h" + +class h8h_disassembler : public h8_disassembler +{ +public: + h8h_disassembler(); + virtual ~h8h_disassembler() = default; + +protected: + static const disasm_entry disasm_entries[]; +}; + +#endif diff --git a/src/devices/cpu/h8/h8make.py b/src/devices/cpu/h8/h8make.py index e5aee1dbb96..99883e92c2a 100644 --- a/src/devices/cpu/h8/h8make.py +++ b/src/devices/cpu/h8/h8make.py @@ -5,7 +5,7 @@ from __future__ import print_function USAGE = """ Usage: -%s h8.lst <type> h8.inc (type = o/h/s20/s26) +%s h8.lst <mode> <type> h8.inc (mode = s/d, type = o/h/s20/s26) """ import sys @@ -21,14 +21,23 @@ def name_to_type(name): sys.stderr.write("Unknown chip type name %s\n" % name) sys.exit(1) -def type_to_device(dtype): - if dtype == 0: - return "h8_device" - if dtype == 1: - return "h8h_device" - if dtype == 2: - return "h8s2000_device" - return "h8s2600_device" +def type_to_device(dtype, mode): + if mode == 's': + if dtype == 0: + return "h8_device" + if dtype == 1: + return "h8h_device" + if dtype == 2: + return "h8s2000_device" + return "h8s2600_device" + else: + if dtype == 0: + return "h8_disassembler" + if dtype == 1: + return "h8h_disassembler" + if dtype == 2: + return "h8s2000_disassembler" + return "h8s2600_disassembler" def hexsplit(str): res = [] @@ -182,9 +191,9 @@ class Opcode: size = len(self.val) + 2*self.skip + 2*self.extra_words if self.name == "jsr" or self.name == "bsr": - flags = "%d | DASMFLAG_STEP_OVER" % size + flags = "%d | STEP_OVER" % size elif self.name == "rts" or self.name == "rte": - flags = "%d | DASMFLAG_STEP_OUT" % size + flags = "%d | STEP_OUT" % size else: flags = "%d" % size @@ -445,28 +454,31 @@ class OpcodeList: print("}", file=f) def main(argv): - if len(argv) != 4: + if len(argv) != 5: print(USAGE % argv[0]) return 1 - dtype = name_to_type(argv[2]) - dname = type_to_device(dtype) + mode = argv[2] + dtype = name_to_type(argv[3]) + dname = type_to_device(dtype, mode) opcodes = OpcodeList(argv[1], dtype) try: - f = open(argv[3], "w") + f = open(argv[4], "w") except Exception: err = sys.exc_info()[1] - sys.stderr.write("cannot write file %s [%s]\n" % (argv[3], err)) + sys.stderr.write("cannot write file %s [%s]\n" % (argv[4], err)) sys.exit(1) - opcodes.build_dispatch() - opcodes.save_dasm(f, dname) - opcodes.save_opcodes(f, dname) - if dtype == 0: - opcodes.save_dispatch(f, dname) - opcodes.save_exec(f, dname, dtype, "full") - opcodes.save_exec(f, dname, dtype, "partial") + if mode == 's': + opcodes.build_dispatch() + opcodes.save_opcodes(f, dname) + if dtype == 0: + opcodes.save_dispatch(f, dname) + opcodes.save_exec(f, dname, dtype, "full") + opcodes.save_exec(f, dname, dtype, "partial") + else: + opcodes.save_dasm(f, dname) f.close() # ====================================================================== diff --git a/src/devices/cpu/h8/h8s2000.cpp b/src/devices/cpu/h8/h8s2000.cpp index 2af090f5867..95e10cc2c50 100644 --- a/src/devices/cpu/h8/h8s2000.cpp +++ b/src/devices/cpu/h8/h8s2000.cpp @@ -2,6 +2,7 @@ // copyright-holders:Olivier Galibert #include "emu.h" #include "h8s2000.h" +#include "h8s2000d.h" h8s2000_device::h8s2000_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_delegate map_delegate) : h8h_device(mconfig, type, tag, owner, clock, map_delegate) @@ -9,9 +10,9 @@ h8s2000_device::h8s2000_device(const machine_config &mconfig, device_type type, has_exr = true; } -offs_t h8s2000_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *h8s2000_device::create_disassembler() { - return disassemble_generic(stream, pc, oprom, opram, options, disasm_entries); + return new h8s2000_disassembler; } #include "cpu/h8/h8s2000.hxx" diff --git a/src/devices/cpu/h8/h8s2000.h b/src/devices/cpu/h8/h8s2000.h index e28e640baec..8aa195df7ad 100644 --- a/src/devices/cpu/h8/h8s2000.h +++ b/src/devices/cpu/h8/h8s2000.h @@ -24,9 +24,7 @@ class h8s2000_device : public h8h_device { protected: h8s2000_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_delegate map_delegate); - static const disasm_entry disasm_entries[]; - - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void do_exec_full() override; virtual void do_exec_partial() override; diff --git a/src/devices/cpu/h8/h8s2000d.cpp b/src/devices/cpu/h8/h8s2000d.cpp new file mode 100644 index 00000000000..1e0b3830f53 --- /dev/null +++ b/src/devices/cpu/h8/h8s2000d.cpp @@ -0,0 +1,17 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + h8d.h + + H8S-2000 base cpu emulation, disassembler + +***************************************************************************/ + +#include "emu.h" +#include "h8s2000d.h" +#include "cpu/h8/h8s2000d.hxx" + +h8s2000_disassembler::h8s2000_disassembler() : h8_disassembler(disasm_entries) +{ +} diff --git a/src/devices/cpu/h8/h8s2000d.h b/src/devices/cpu/h8/h8s2000d.h new file mode 100644 index 00000000000..cf6bc5bfa9e --- /dev/null +++ b/src/devices/cpu/h8/h8s2000d.h @@ -0,0 +1,28 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + h8s2000d.h + + H8S-2000 base cpu emulation, disassembler + +***************************************************************************/ + +#ifndef MAME_CPU_H8_H8S2000D_H +#define MAME_CPU_H8_H8S2000D_H + +#pragma once + +#include "h8d.h" + +class h8s2000_disassembler : public h8_disassembler +{ +public: + h8s2000_disassembler(); + virtual ~h8s2000_disassembler() = default; + +protected: + static const disasm_entry disasm_entries[]; +}; + +#endif diff --git a/src/devices/cpu/h8/h8s2600.cpp b/src/devices/cpu/h8/h8s2600.cpp index 188f879279d..171dfef2d9b 100644 --- a/src/devices/cpu/h8/h8s2600.cpp +++ b/src/devices/cpu/h8/h8s2600.cpp @@ -2,15 +2,16 @@ // copyright-holders:Olivier Galibert #include "emu.h" #include "h8s2600.h" +#include "h8s2600d.h" h8s2600_device::h8s2600_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_delegate map_delegate) : h8s2000_device(mconfig, type, tag, owner, clock, map_delegate) { } -offs_t h8s2600_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *h8s2600_device::create_disassembler() { - return disassemble_generic(stream, pc, oprom, opram, options, disasm_entries); + return new h8s2600_disassembler; } #include "cpu/h8/h8s2600.hxx" diff --git a/src/devices/cpu/h8/h8s2600.h b/src/devices/cpu/h8/h8s2600.h index 45b84bb2f8c..e3b4b7e44a9 100644 --- a/src/devices/cpu/h8/h8s2600.h +++ b/src/devices/cpu/h8/h8s2600.h @@ -20,11 +20,9 @@ class h8s2600_device : public h8s2000_device { protected: - static const disasm_entry disasm_entries[]; - h8s2600_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_delegate map_delegate); - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void do_exec_full() override; virtual void do_exec_partial() override; diff --git a/src/devices/cpu/h8/h8s2600d.cpp b/src/devices/cpu/h8/h8s2600d.cpp new file mode 100644 index 00000000000..7e55784bed0 --- /dev/null +++ b/src/devices/cpu/h8/h8s2600d.cpp @@ -0,0 +1,17 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + h8d.h + + H8S-2600 base cpu emulation, disassembler + +***************************************************************************/ + +#include "emu.h" +#include "h8s2600d.h" +#include "cpu/h8/h8s2600d.hxx" + +h8s2600_disassembler::h8s2600_disassembler() : h8_disassembler(disasm_entries) +{ +} diff --git a/src/devices/cpu/h8/h8s2600d.h b/src/devices/cpu/h8/h8s2600d.h new file mode 100644 index 00000000000..3ee3fbfe133 --- /dev/null +++ b/src/devices/cpu/h8/h8s2600d.h @@ -0,0 +1,28 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + h8s2600d.h + + H8S-2600 base cpu emulation, disassembler + +***************************************************************************/ + +#ifndef MAME_CPU_H8_H8S2600D_H +#define MAME_CPU_H8_H8S2600D_H + +#pragma once + +#include "h8d.h" + +class h8s2600_disassembler : public h8_disassembler +{ +public: + h8s2600_disassembler(); + virtual ~h8s2600_disassembler() = default; + +protected: + static const disasm_entry disasm_entries[]; +}; + +#endif diff --git a/src/devices/cpu/hcd62121/hcd62121.cpp b/src/devices/cpu/hcd62121/hcd62121.cpp index 92f3deaac88..efdb53ba2cd 100644 --- a/src/devices/cpu/hcd62121/hcd62121.cpp +++ b/src/devices/cpu/hcd62121/hcd62121.cpp @@ -1,5 +1,5 @@ // license:BSD-3-Clause -// copyright-holders:Wilbert Pol +// copyright-holders:Wilbert Pol, Ricardo Barreira /********************************************************************** Hitachi hcd62121 cpu core emulation. @@ -7,9 +7,12 @@ The Hitachi hcd62121 is the custom cpu which was used in the Casio CFX-9850 (and maybe some other things too). -This CPU core is based on the information provided by Martin Poupe. +This CPU core is mainly based on the information provided by Martin Poupe. Martin Poupe's site can be found at http://martin.poupe.org/casio/ +Other contributors to reverse-engineering this CPU include Petr Pfeifer +who hacked the hardware, Uwe Ryssel, Brad O'Dell and Ricardo Barreira. + TODO: - instruction timings - unknown instructions @@ -18,6 +21,7 @@ TODO: #include "emu.h" #include "hcd62121.h" +#include "hcd62121d.h" #include "debugger.h" @@ -38,11 +42,11 @@ enum }; +constexpr u8 FLAG_CL = 0x10; constexpr u8 FLAG_Z = 0x08; -constexpr u8 FLAG_C = 0x02; -constexpr u8 FLAG_ZL = 0x04; -constexpr u8 FLAG_CL = 0x01; -constexpr u8 FLAG_ZH = 0x10; +constexpr u8 FLAG_C = 0x04; +constexpr u8 FLAG_ZL = 0x02; +constexpr u8 FLAG_ZH = 0x01; DEFINE_DEVICE_TYPE(HCD62121, hcd62121_cpu_device, "hcd62121_cpu_device", "Hitachi HCD62121") @@ -110,12 +114,12 @@ void hcd62121_cpu_device::read_reg(int size, u8 op1) if (op1 & 0x80) { for (int i = 0; i < size; i++) - m_temp1[i] = m_reg[(op1 - i) & 0x7f]; + m_temp1[i] = m_reg[(op1 - i) & 0x7f]; // TODO - is this really how wrap-around for registers works? } else { for (int i = 0; i < size; i++) - m_temp1[i] = m_reg[(op1 + i) & 0x7f]; + m_temp1[i] = m_reg[(op1 + i) & 0x7f]; // TODO - is this really how wrap-around for registers works? } } @@ -134,8 +138,7 @@ void hcd62121_cpu_device::write_reg(int size, u8 op1) } } - -void hcd62121_cpu_device::read_regreg(int size, u8 op1, u8 op2, bool op_is_logical) +void hcd62121_cpu_device::read_regreg(int size, u8 op1, u8 op2, bool copy_extend_immediate) { for (int i = 0; i < size; i++) m_temp1[i] = m_reg[(op1 + i) & 0x7f]; @@ -145,7 +148,7 @@ void hcd62121_cpu_device::read_regreg(int size, u8 op1, u8 op2, bool op_is_logic /* Second operand is an immediate value */ m_temp2[0] = op2; for (int i = 1; i < size; i++) - m_temp2[i] = op_is_logical ? op2 : 0; + m_temp2[i] = copy_extend_immediate ? op2 : 0; } else { @@ -154,7 +157,7 @@ void hcd62121_cpu_device::read_regreg(int size, u8 op1, u8 op2, bool op_is_logic m_temp2[i] = m_reg[(op2 + i) & 0x7f]; } - if (!(op1 & 0x80) && !(op2 & 0x80)) + if (!(op1 & 0x80)) { /* We need to swap parameters */ for (int i = 0; i < size; i++) @@ -167,24 +170,24 @@ void hcd62121_cpu_device::read_regreg(int size, u8 op1, u8 op2, bool op_is_logic } -void hcd62121_cpu_device::write_regreg(int size, u8 op1, u8 op2) +void hcd62121_cpu_device::write_regreg(int size, u8 arg1, u8 arg2) { - if ((op1 & 0x80) || (op2 & 0x80)) + if ((arg1 & 0x80)) { - /* store in reg1 */ + /* store in arg1 */ for (int i = 0; i < size; i++) - m_reg[(op1 + i) & 0x7f] = m_temp1[i]; + m_reg[(arg1 + i) & 0x7f] = m_temp1[i]; } else { - /* store in reg2 */ + /* store in arg2 */ for (int i = 0; i < size; i++) - m_reg[(op2 + i) & 0x7f] = m_temp1[i]; + m_reg[(arg2 + i) & 0x7f] = m_temp1[i]; } } -void hcd62121_cpu_device::read_iregreg(int size, u8 op1, u8 op2) +void hcd62121_cpu_device::read_iregreg(int size, u8 op1, u8 op2, bool copy_extend_immediate) { u16 ad = m_reg[(0x40 | op1) & 0x7f ] | (m_reg[(0x40 | (op1 + 1)) & 0x7f] << 8); @@ -197,12 +200,14 @@ void hcd62121_cpu_device::read_iregreg(int size, u8 op1, u8 op2) if (op1 & 0x80) { + /* Second operand is an immediate value */ m_temp2[0] = op2; for (int i = 1; i < size; i++) - m_temp2[i] = 0; + m_temp2[i] = copy_extend_immediate ? op2 : 0; } else { + /* Second operand is a register */ for (int i = 0; i < size; i++) m_temp2[i] = m_reg[(op2 + i) & 0x7f]; } @@ -282,11 +287,11 @@ bool hcd62121_cpu_device::check_cond(u8 op) case 0x03: /* Z set */ return (m_f & FLAG_Z); - case 0x04: /* Z or C set */ - return (m_f & (FLAG_Z | FLAG_C)); + case 0x04: /* ZH not set */ + return (!(m_f & FLAG_ZH)); - case 0x05: /* CL set */ - return (m_f & FLAG_CL); + case 0x05: /* ZL not set */ + return (!(m_f & FLAG_ZL)); case 0x06: /* C clear */ return (!(m_f & FLAG_C)); @@ -575,169 +580,217 @@ inline void hcd62121_cpu_device::set_cl_flag(bool is_cl) inline void hcd62121_cpu_device::op_msk(int size) { - bool mskres = true; + bool zero_high = true; + bool zero_low = true; for (int i = 0; i < size; i++) { - if ((m_temp1[i] & m_temp2[i]) != m_temp2[i]) - mskres = false; + if ((m_temp1[i] & m_temp2[i] & 0xf0) != (m_temp2[i] & 0xf0)) + zero_high = false; + if ((m_temp1[i] & m_temp2[i] & 0x0f) != (m_temp2[i] & 0x0f)) + zero_low = false; } - set_zero_flag(!mskres); -} - - -inline void hcd62121_cpu_device::op_imsk(int size) -{ - bool mskres = true; - bool set_zero = false; + set_zero_flag(zero_high && zero_low); + set_zh_flag(zero_high); + set_zl_flag(zero_low); - for (int i = 0; i < size; i++) - { - if ((m_temp1[i] & ~m_temp2[i]) != ~m_temp2[i]) - mskres = false; - if (m_temp1[i] | m_temp2[i]) - set_zero = true; - } - - set_zero_flag(set_zero); - set_carry_flag(!mskres); + set_cl_flag(false); + set_carry_flag(false); } inline void hcd62121_cpu_device::op_and(int size) { - bool is_zero = true; + bool zero_high = true; + bool zero_low = true; for (int i = 0; i < size; i++) { m_temp1[i] = m_temp1[i] & m_temp2[i]; - if (m_temp1[i]) - is_zero = false; + if (m_temp1[i] & 0xf0) + zero_high = false; + if (m_temp1[i] & 0x0f) + zero_low = false; } - set_zero_flag(is_zero); - set_zl_flag((m_temp1[0] & 0x0f) == 0); - set_zh_flag((m_temp1[0] & 0xf0) == 0); + set_zero_flag(zero_high && zero_low); + set_zh_flag(zero_high); + set_zl_flag(zero_low); + set_cl_flag(false); + set_carry_flag(false); } inline void hcd62121_cpu_device::op_or(int size) { - bool is_zero = true; + bool zero_high = true; + bool zero_low = true; for (int i = 0; i < size; i++) { m_temp1[i] = m_temp1[i] | m_temp2[i]; - if (m_temp1[i]) - is_zero = false; + if (m_temp1[i] & 0xf0) + zero_high = false; + if (m_temp1[i] & 0x0f) + zero_low = false; } - set_zero_flag(is_zero); - set_zl_flag((m_temp1[0] & 0x0f) == 0); - set_zh_flag((m_temp1[0] & 0xf0) == 0); + set_zero_flag(zero_high && zero_low); + set_zh_flag(zero_high); + set_zl_flag(zero_low); + set_cl_flag(false); + set_carry_flag(false); } inline void hcd62121_cpu_device::op_xor(int size) { - bool is_zero = true; + bool zero_high = true; + bool zero_low = true; for (int i = 0; i < size; i++) { m_temp1[i] = m_temp1[i] ^ m_temp2[i]; - if (m_temp1[i]) - is_zero = false; + if (m_temp1[i] & 0xf0) + zero_high = false; + if (m_temp1[i] & 0x0f) + zero_low = false; } - set_zero_flag(is_zero); - set_zl_flag((m_temp1[0] & 0x0f) == 0); - set_zh_flag((m_temp1[0] & 0xf0) == 0); + set_zero_flag(zero_high && zero_low); + set_zh_flag(zero_high); + set_zl_flag(zero_low); + set_cl_flag(false); + set_carry_flag(false); } inline void hcd62121_cpu_device::op_add(int size) { - bool is_zero = true; + bool zero_high = true; + bool zero_low = true; u8 carry = 0; - set_cl_flag((m_temp1[0] & 0x0f) + (m_temp2[0] & 0x0f) > 15); - for (int i = 0; i < size; i++) { - u16 res = m_temp1[i] + m_temp2[i] + carry; + if (i == size - 1) { + set_cl_flag((m_temp1[i] & 0x0f) + (m_temp2[i] & 0x0f) + carry > 0x0f); + } + u16 res = m_temp1[i] + m_temp2[i] + carry; m_temp1[i] = res & 0xff; - if (m_temp1[i]) - is_zero = false; - carry = (res & 0xff00) ? 1 : 0; + + if (m_temp1[i] & 0xf0) + zero_high = false; + if (m_temp1[i] & 0x0f) + zero_low = false; } - set_zero_flag(is_zero); + set_zero_flag(zero_high && zero_low); + set_zh_flag(zero_high); + set_zl_flag(zero_low); set_carry_flag(carry); - set_zl_flag((m_temp1[0] & 0x0f) == 0); - set_zh_flag((m_temp1[0] & 0xf0) == 0); } // BCD ADD inline void hcd62121_cpu_device::op_addb(int size) { - bool is_zero = true; + bool zero_high = true; + bool zero_low = true; u8 carry = 0; - set_cl_flag((m_temp1[0] & 0x0f) + (m_temp2[0] & 0x0f) > 9); - for (int i = 0; i < size; i++) { - u16 res = (m_temp1[i] & 0x0f) + (m_temp2[i] & 0x0f) + carry; - - if (res > 9) - { - res += 6; + if (i == size - 1) { + set_cl_flag((m_temp1[i] & 0x0f) + (m_temp2[i] & 0x0f) + carry > 9); } - res += (m_temp1[i] & 0xf0) + (m_temp2[i] & 0xf0); - if (res > 0x9f) - { - res += 0x60; + + int num1 = (m_temp1[i] & 0x0f) + ((m_temp1[i] & 0xf0) >> 4) * 10; + int num2 = (m_temp2[i] & 0x0f) + ((m_temp2[i] & 0xf0) >> 4) * 10; + + int result = num1 + num2 + carry; + carry = (result > 99); + if (result > 99) + result -= 100; + m_temp1[i] = (result % 10) | ((result / 10) << 4); + + if (m_temp1[i] & 0xf0) + zero_high = false; + if (m_temp1[i] & 0x0f) + zero_low = false; + } + + set_zero_flag(zero_high && zero_low); + set_zh_flag(zero_high); + set_zl_flag(zero_low); + set_carry_flag(carry); +} + + +// BCD SUBTRACT +inline void hcd62121_cpu_device::op_subb(int size) +{ + bool zero_high = true; + bool zero_low = true; + u8 carry = 0; + + for (int i = 0; i < size; i++) + { + if (i == size - 1) { + set_cl_flag((m_temp1[i] & 0x0f) - (m_temp2[i] & 0x0f) - carry < 0); } - m_temp1[i] = res & 0xff; - if (m_temp1[i]) - is_zero = false; - carry = (res & 0xff00) ? 1 : 0; + int num1 = (m_temp1[i] & 0x0f) + ((m_temp1[i] & 0xf0) >> 4) * 10; + int num2 = (m_temp2[i] & 0x0f) + ((m_temp2[i] & 0xf0) >> 4) * 10; + + int result = num1 - num2 - carry; + carry = (result < 0); + if (result < 0) + result += 100; + m_temp1[i] = (result % 10) | ((result / 10) << 4); + + if (m_temp1[i] & 0xf0) + zero_high = false; + if (m_temp1[i] & 0x0f) + zero_low = false; } - set_zero_flag(is_zero); + set_zero_flag(zero_high && zero_low); + set_zh_flag(zero_high); + set_zl_flag(zero_low); set_carry_flag(carry); - set_zl_flag((m_temp1[0] & 0x0f) == 0); - set_zh_flag((m_temp1[0] & 0xf0) == 0); } inline void hcd62121_cpu_device::op_sub(int size) { - bool is_zero = true; + bool zero_high = true; + bool zero_low = true; u8 carry = 0; - set_cl_flag((m_temp1[0] & 0x0f) < (m_temp2[0] & 0x0f)); - for (int i = 0; i < size; i++) { - u16 res = m_temp1[i] - m_temp2[i] - carry; + if (i == size - 1) { + set_cl_flag((m_temp1[i] & 0x0f) - (m_temp2[i] & 0x0f) - carry < 0); + } + u16 res = m_temp1[i] - m_temp2[i] - carry; m_temp1[i] = res & 0xff; - if (m_temp1[i]) - is_zero = false; - carry = ( res & 0xff00 ) ? 1 : 0; + + if (m_temp1[i] & 0xf0) + zero_high = false; + if (m_temp1[i] & 0x0f) + zero_low = false; } - set_zero_flag(is_zero); + set_zero_flag(zero_high && zero_low); + set_zh_flag(zero_high); + set_zl_flag(zero_low); set_carry_flag(carry); - set_zl_flag((m_temp1[0] & 0x0f) == 0); - set_zh_flag((m_temp1[0] & 0xf0) == 0); } @@ -774,48 +827,36 @@ void hcd62121_cpu_device::execute_run() // actual instruction timings unknown m_icount -= 4; - switch (op) { - case 0x00: /* rorb/rolb r1,4 */ - case 0x01: /* rorw/rolw r1,4 */ - case 0x02: /* rorq/rolq r1,4 */ - case 0x03: /* rort/rolt r1,4 */ - /* Nibble rotate */ + case 0x00: /* shrb/shlb r1,8 */ // Yes, this just sets a register to 0! + case 0x01: /* shrw/shlw r1,8 */ + case 0x02: /* shrq/shlq r1,8 */ + case 0x03: /* shrt/shlt r1,8 */ { int size = datasize(op); u8 reg1 = read_op(); - u8 d1 = 0, d2 = 0; - read_reg(size, reg1); - - if (reg1 & 0x80) - { - // rotate right - d2 = (m_temp1[size-1] & 0x0f) << 4; - for (int i = 0; i < size; i++) - { - d1 = (m_temp1[i] & 0x0f) << 4; - m_temp1[i] = (m_temp1[i] >> 4) | d2; - d2 = d1; + // TODO - read_reg should support reading this + if (reg1 & 0x80) { + read_reg(size, (reg1 & 0x7f) - size + 1); + for (int i=0; i < size - 1; i++) { + m_temp1[i] = m_temp1[i + 1]; } + m_temp1[size-1] = 0; + write_reg(size, (reg1 & 0x7f) - size + 1); } else { - // rotate left - d2 = (m_temp1[size-1] & 0xf0) >> 4; - for (int i = 0; i < size; i++) - { - d1 = (m_temp1[i] & 0xf0) >> 4; - m_temp1[i] = (m_temp1[i] << 4) | d2; - d2 = d1; + read_reg(size, reg1); + for (int i = size-1; i > 0; i--) { + m_temp1[i] = m_temp1[i - 1]; } + m_temp1[0] = 0; + write_reg(size, reg1); } - - write_reg(size, reg1); } break; - case 0x04: /* mskb r1,r2 */ case 0x05: /* mskw r1,r2 */ case 0x06: /* mskq r1,r2 */ @@ -825,7 +866,7 @@ void hcd62121_cpu_device::execute_run() u8 reg1 = read_op(); u8 reg2 = read_op(); - read_regreg(size, reg1, reg2, false); + read_regreg(size, reg1, reg2, true); op_msk(size); } @@ -877,7 +918,7 @@ void hcd62121_cpu_device::execute_run() u8 reg1 = read_op(); u8 reg2 = read_op(); - read_regreg(size, reg1, reg2, false); + read_regreg(size, reg1, reg2, true); op_and(size); } @@ -892,7 +933,7 @@ void hcd62121_cpu_device::execute_run() u8 reg1 = read_op(); u8 reg2 = read_op(); - read_regreg(size, reg1, reg2, false); + read_regreg(size, reg1, reg2, true); op_xor(size); @@ -933,10 +974,10 @@ void hcd62121_cpu_device::execute_run() } break; - case 0x1C: /* imskb r1,r2 */ - case 0x1D: /* imskw r1,r2 */ - case 0x1E: /* imskq r1,r2 */ - case 0x1F: /* imskt r1,r2 */ + case 0x1C: /* cmpaddb r1,r2 */ + case 0x1D: /* cmpaddw r1,r2 */ + case 0x1E: /* cmpaddq r1,r2 */ + case 0x1F: /* cmpaddt r1,r2 */ { int size = datasize(op); u8 reg1 = read_op(); @@ -944,46 +985,42 @@ void hcd62121_cpu_device::execute_run() read_regreg(size, reg1, reg2, false); - op_imsk(size); + op_add(size); } break; - case 0x20: /* rorb/rolb r1 */ - case 0x21: /* rorw/rolw r1 */ - case 0x22: /* rorq/rolq r1 */ - case 0x23: /* rort/rolt r1 */ - /* Single bit rotate */ + case 0x20: /* shrb r1,1 */ + case 0x21: /* shrw r1,1 */ + case 0x22: /* shrq r1,1 */ + case 0x23: /* shrt r1,1 */ { int size = datasize(op); u8 reg1 = read_op(); u8 d1 = 0, d2 = 0; + bool zero_high = true; + bool zero_low = true; read_reg(size, reg1); - if (reg1 & 0x80) - { - // rotate right - d2 = (m_temp1[size-1] & 0x01) << 7; - for (int i = 0; i < size; i++) - { - d1 = (m_temp1[i] & 0x01) << 7; - m_temp1[i] = (m_temp1[i] >> 1) | d2; - d2 = d1; - } - } - else + d2 = 0; + set_cl_flag ((m_temp1[0] & (1U<<4)) != 0U); + for (int i = 0; i < size; i++) { - // rotate left - d2 = (m_temp1[size-1] & 0x80) >> 7; - for (int i = 0; i < size; i++) - { - d1 = (m_temp1[i] & 0x80) >> 7; - m_temp1[i] = (m_temp1[i] << 1) | d2; - d2 = d1; - } + d1 = (m_temp1[i] & 0x01) << 7; + m_temp1[i] = (m_temp1[i] >> 1) | d2; + d2 = d1; + if (m_temp1[i] & 0xf0) + zero_high = false; + if (m_temp1[i] & 0x0f) + zero_low = false; } write_reg(size, reg1); + + set_zero_flag(zero_high && zero_low); + set_zh_flag(zero_high); + set_zl_flag(zero_low); + set_carry_flag (d2 != 0); } break; @@ -996,7 +1033,7 @@ void hcd62121_cpu_device::execute_run() u8 reg1 = read_op(); u8 reg2 = read_op(); - read_regreg(size, reg1, reg2, false); + read_regreg(size, reg1, reg2, true); op_or(size); @@ -1004,40 +1041,37 @@ void hcd62121_cpu_device::execute_run() } break; - case 0x28: /* shrb/shlb r1 */ - case 0x29: /* shrw/shlw r1 */ - case 0x2A: /* shrq/shlq r1 */ - case 0x2B: /* shrt/shlt r1 */ - /* Single bit shift */ + case 0x28: /* shlb r1,1 */ + case 0x29: /* shlw r1,1 */ + case 0x2A: /* shlq r1,1 */ + case 0x2B: /* shlt r1,1 */ { int size = datasize(op); u8 reg1 = read_op(); u8 d1 = 0, d2 = 0; + bool zero_high = true; + bool zero_low = true; read_reg(size, reg1); - if (reg1 & 0x80) - { - // shift right - for (int i = 0; i < size; i++) - { - d1 = (m_temp1[i] & 0x01) << 7; - m_temp1[i] = (m_temp1[i] >> 1) | d2; - d2 = d1; - } - } - else + set_cl_flag ((m_temp1[0] & (1U<<3)) != 0U); + for (int i = 0; i < size; i++) { - // shift left - for (int i = 0; i < size; i++) - { - d1 = (m_temp1[i] & 0x80) >> 7; - m_temp1[i] = (m_temp1[i] << 1) | d2; - d2 = d1; - } + d1 = (m_temp1[i] & 0x80) >> 7; + m_temp1[i] = (m_temp1[i] << 1) | d2; + d2 = d1; + + if (m_temp1[i] & 0xf0) + zero_high = false; + if (m_temp1[i] & 0x0f) + zero_low = false; } write_reg(size, reg1); + set_zero_flag(zero_high && zero_low); + set_zh_flag(zero_high); + set_zl_flag(zero_low); + set_carry_flag (d2 != 0); } break; @@ -1058,6 +1092,23 @@ void hcd62121_cpu_device::execute_run() } break; + case 0x30: /* subbb r1,r2 */ + case 0x31: /* subbw r1,r2 */ + case 0x32: /* subbq r1,r2 */ + case 0x33: /* subbt r1,r2 */ + { + int size = datasize(op); + u8 reg1 = read_op(); + u8 reg2 = read_op(); + + read_regreg(size, reg1, reg2, false); + + op_subb(size); + + write_regreg(size, reg1, reg2); + } + break; + case 0x34: /* subb r1,r2 */ case 0x35: /* subw r1,r2 */ case 0x36: /* subq r1,r2 */ @@ -1118,7 +1169,7 @@ void hcd62121_cpu_device::execute_run() u8 reg1 = read_op(); u8 reg2 = read_op(); - read_iregreg(size, reg1, reg2); + read_iregreg(size, reg1, reg2, true); op_and(size); } @@ -1133,7 +1184,7 @@ void hcd62121_cpu_device::execute_run() u8 reg1 = read_op(); u8 reg2 = read_op(); - read_iregreg(size, reg1, reg2); + read_iregreg(size, reg1, reg2, false); op_sub(size); } @@ -1148,7 +1199,7 @@ void hcd62121_cpu_device::execute_run() u8 reg1 = read_op(); u8 reg2 = read_op(); - read_iregreg(size, reg1, reg2); + read_iregreg(size, reg1, reg2, false); for (int i = 0; i < size; i++) m_temp1[i] = m_temp2[i]; @@ -1157,6 +1208,21 @@ void hcd62121_cpu_device::execute_run() } break; + case 0x5C: /* cmpaddb ir1,r2 */ + case 0x5D: /* cmpaddw ir1,r2 */ + case 0x5E: /* cmpaddq ir1,r2 */ + case 0x5F: /* cmpaddt ir1,r2 */ + { + int size = datasize(op); + u8 reg1 = read_op(); + u8 reg2 = read_op(); + + read_iregreg(size, reg1, reg2, false); + + op_add(size); + } + break; + case 0x64: /* orb ir1,r2 */ case 0x65: /* orb ir1,r2 */ case 0x66: /* orb ir1,r2 */ @@ -1166,7 +1232,7 @@ void hcd62121_cpu_device::execute_run() u8 reg1 = read_op(); u8 reg2 = read_op(); - read_iregreg(size, reg1, reg2); + read_iregreg(size, reg1, reg2, true); op_or(size); @@ -1183,7 +1249,7 @@ void hcd62121_cpu_device::execute_run() u8 reg1 = read_op(); u8 reg2 = read_op(); - read_iregreg(size, reg1, reg2); + read_iregreg(size, reg1, reg2, true); op_and(size); @@ -1191,6 +1257,40 @@ void hcd62121_cpu_device::execute_run() } break; + case 0x74: /* subb ir1,r2 */ + case 0x75: /* subw ir1,r2 */ + case 0x76: /* subq ir1,r2 */ + case 0x77: /* subt ir1,r2 */ + { + int size = datasize(op); + u8 reg1 = read_op(); + u8 reg2 = read_op(); + + read_iregreg(size, reg1, reg2, false); + + op_sub(size); + + write_iregreg(size, reg1, reg2); + } + break; + + case 0x78: /* adbb ir1,r2 */ + case 0x79: /* adbw ir1,r2 */ + case 0x7A: /* adbq ir1,r2 */ + case 0x7B: /* adbt ir1,r2 */ + { + int size = datasize(op); + u8 reg1 = read_op(); + u8 reg2 = read_op(); + + read_iregreg(size, reg1, reg2, false); + + op_addb(size); + + write_iregreg(size, reg1, reg2); + } + break; + case 0x7C: /* addb ir1,r2 */ case 0x7D: /* addw ir1,r2 */ case 0x7E: /* addq ir1,r2 */ @@ -1200,7 +1300,7 @@ void hcd62121_cpu_device::execute_run() u8 reg1 = read_op(); u8 reg2 = read_op(); - read_iregreg(size, reg1, reg2); + read_iregreg(size, reg1, reg2, false); op_add(size); @@ -1209,7 +1309,11 @@ void hcd62121_cpu_device::execute_run() break; case 0x88: /* jump _a16 */ - m_ip = (read_op() << 8) | read_op(); + { + u8 a1 = read_op(); + u8 a2 = read_op(); + m_ip = (a1 << 8) | a2; + } break; case 0x89: /* jumpf cs:a16 */ @@ -1234,8 +1338,30 @@ void hcd62121_cpu_device::execute_run() } break; - case 0x8C: /* unk_8C */ - case 0x8D: /* unk_8D */ + case 0x8C: /* bstack_to_dmem */ + { + int size = m_dsize + 1; + for (int i=0; i < size; i++) { + u8 byte = m_program->read_byte((m_sseg << 16) | m_sp); + m_program->write_byte((m_dseg << 16) | m_lar, byte); + m_sp--; + m_lar--; + } + } + break; + + case 0x8D: /* fstack_to_dmem */ + { + int size = m_dsize + 1; + for (int i=0; i < size; i++) { + u8 byte = m_program->read_byte((m_sseg << 16) | m_sp); + m_program->write_byte((m_dseg << 16) | m_lar, byte); + m_sp++; + m_lar++; + } + } + break; + case 0x8E: /* unk_8E */ logerror("%02x:%04x: unimplemented instruction %02x encountered\n", m_cseg, m_ip-1, op); break; @@ -1244,8 +1370,8 @@ void hcd62121_cpu_device::execute_run() case 0x91: /* retzl */ case 0x92: /* retc */ case 0x93: /* retz */ - case 0x94: /* retzc */ - case 0x95: /* retcl */ + case 0x94: /* retnzh */ + case 0x95: /* retnzl */ case 0x96: /* retnc */ case 0x97: /* retnz */ if (check_cond(op)) @@ -1274,8 +1400,8 @@ void hcd62121_cpu_device::execute_run() case 0xA1: /* jmpzl a16 */ case 0xA2: /* jmpc a16 */ case 0xA3: /* jmpz a16 */ - case 0xA4: /* jmpzc a16 */ - case 0xA5: /* jmpcl a16 */ + case 0xA4: /* jmpnzh a16 */ + case 0xA5: /* jmpnzl a16 */ case 0xA6: /* jmpnc a16 */ case 0xA7: /* jmpnz a16 */ { @@ -1291,8 +1417,8 @@ void hcd62121_cpu_device::execute_run() case 0xA9: /* callzl a16 */ case 0xAA: /* callc a16 */ case 0xAB: /* callz a16 */ - case 0xAC: /* callzc a16 */ - case 0xAD: /* callcl a16 */ + case 0xAC: /* callnzh a16 */ + case 0xAD: /* callnzl a16 */ case 0xAE: /* callnc a16 */ case 0xAF: /* callnz a16 */ { @@ -1335,7 +1461,7 @@ void hcd62121_cpu_device::execute_run() read_op(); break; - case 0xBB: /* jmpcl? a16 */ + case 0xBB: /* jmpcl a16 */ logerror("%02x:%04x: unimplemented instruction %02x encountered\n", m_cseg, m_ip-1, op); { u8 a1 = read_op(); @@ -1346,12 +1472,7 @@ void hcd62121_cpu_device::execute_run() } break; - case 0xBC: /* unk_BC reg/i8 */ - logerror("%02x:%04x: unimplemented instruction %02x encountered\n", m_cseg, m_ip-1, op); - read_op(); - break; - - case 0xBF: /* jmpncl? a16 */ + case 0xBF: /* jmpncl a16 */ logerror("%02x:%04x: unimplemented instruction %02x encountered\n", m_cseg, m_ip-1, op); { u8 a1 = read_op(); @@ -1362,14 +1483,17 @@ void hcd62121_cpu_device::execute_run() } break; - case 0xC0: /* movb reg,i8 */ + //case 0xC0: /* movb reg,i8 */ // TODO - test case 0xC1: /* movw reg,i16 */ - case 0xC2: /* movw reg,i64 */ - case 0xC3: /* movw reg,i80 */ + //case 0xC2: /* movw reg,i64 */ // TODO - test + //case 0xC3: /* movw reg,i80 */ // TODO - test { int size = datasize(op); u8 reg = read_op(); + if (reg & 0x80) + fatalerror("%02x:%04x: unimplemented instruction %02x encountered with (arg & 0x80) != 0\n", m_cseg, m_ip-1, op); + for (int i = 0; i < size; i++) { m_reg[(reg + i) & 0x7f] = read_op(); @@ -1383,12 +1507,12 @@ void hcd62121_cpu_device::execute_run() case 0xC7: /* movt (lar),r1 / r1,(lar) */ { int size = datasize(op); - u8 reg1 = read_op(); - u8 reg2 = read_op(); + u8 arg1 = read_op(); + u8 arg2 = read_op(); int pre_inc = 0; int post_inc = 1; - switch (reg1 & 0x60) + switch (arg1 & 0x60) { case 0x00: pre_inc = 0; @@ -1408,23 +1532,29 @@ void hcd62121_cpu_device::execute_run() break; } - if ((reg1 & 0x80) || (reg2 & 0x80)) + if ((arg1 & 0x80) || (arg2 & 0x80)) { - /* (lar) <- r1 */ + /* (lar) <- r2 (immediate or register) */ for (int i = 0; i < size; i++) { m_lar += pre_inc; - m_program->write_byte((m_dseg << 16) | m_lar, m_reg[(reg2 + i) & 0x7f]); + if (arg1 & 0x80) { + m_program->write_byte((m_dseg << 16) | m_lar, arg2); + } + else + { + m_program->write_byte((m_dseg << 16) | m_lar, m_reg[(arg2 + i) & 0x7f]); + } m_lar += post_inc; } } else { - /* r1 <- (lar) */ + /* r2 <- (lar) */ for (int i = 0; i < size; i++) { m_lar += pre_inc; - m_reg[(reg2 + i) & 0x7f] = m_program->read_byte((m_dseg << 16) | m_lar); + m_reg[(arg2 + i) & 0x7f] = m_program->read_byte((m_dseg << 16) | m_lar); m_lar += post_inc; } } @@ -1440,7 +1570,11 @@ void hcd62121_cpu_device::execute_run() u8 reg1 = read_op(); u8 reg2 = read_op(); - read_iregreg(size, reg1, reg2); + if (reg1 & 0x80) { + fatalerror("%02x:%04x: unimplemented swap with immediate encountered\n", m_cseg, m_ip-1); + } + + read_iregreg(size, reg1, reg2, false); for (int i = 0; i < size; i++) { @@ -1451,6 +1585,7 @@ void hcd62121_cpu_device::execute_run() write_iregreg(size, reg1, reg2); write_iregreg2(size, reg1, reg2); + // TODO - are flags affected? } break; @@ -1492,11 +1627,11 @@ void hcd62121_cpu_device::execute_run() break; case 0xD8: /* movb f,reg */ - m_f = m_reg[read_op() & 0x7f]; + m_f = m_reg[read_op() & 0x7f] & 0x3f; break; case 0xD9: /* movb f,i8 */ - m_f = read_op(); + m_f = read_op() & 0x3f; break; case 0xDC: /* movb ds,reg */ @@ -1515,6 +1650,10 @@ void hcd62121_cpu_device::execute_run() } break; + case 0xDF: /* movw lar,i8 */ + m_lar = read_op(); + break; + case 0xE0: /* in0 reg */ { logerror("%06x: in0 read\n", (m_cseg << 16) | m_ip); @@ -1532,16 +1671,26 @@ void hcd62121_cpu_device::execute_run() m_reg[read_op() & 0x7f] = m_ki_cb(); break; - case 0xE6: /* movb reg,PORT */ - m_reg[read_op() & 0x7f] = m_port; + case 0xE3: /* movb reg,dsize */ + { + u8 reg = read_op(); + if (reg & 0x80) + fatalerror("%02x:%04x: unimplemented instruction %02x encountered with (arg & 0x80) != 0\n", m_cseg, m_ip-1, op); + m_reg[reg & 0x7f] = m_dsize; + } break; - case 0xE3: /* unk_e3 reg/i8 (in?) */ - case 0xE4: /* unk_e4 reg/i8 (in?) */ - case 0xE5: /* unk_e5 reg/i8 (in?) */ - case 0xE7: /* unk_e7 reg/i8 (in?) */ - logerror("%02x:%04x: unimplemented instruction %02x encountered\n", m_cseg, m_ip-1, op); - read_op(); + case 0xE4: /* movb reg,f */ + { + u8 reg = read_op(); + if (reg & 0x80) + fatalerror("%02x:%04x: unimplemented instruction %02x encountered with (arg & 0x80) != 0\n", m_cseg, m_ip-1, op); + m_reg[reg & 0x7f] = m_f; + } + break; + + case 0xE6: /* movb reg,PORT */ + m_reg[read_op() & 0x7f] = m_port; break; case 0xE8: /* movw r1,lar */ @@ -1553,7 +1702,7 @@ void hcd62121_cpu_device::execute_run() } break; - case 0xEB: /* movw reg,ss */ + case 0xEB: /* movw reg,sp */ { u8 reg1 = read_op(); @@ -1578,9 +1727,7 @@ void hcd62121_cpu_device::execute_run() case 0xF1: /* unk_F1 reg/i8 (out?) */ case 0xF3: /* unk_F3 reg/i8 (out?) */ - case 0xF4: /* unk_F4 reg/i8 (out?) */ case 0xF5: /* unk_F5 reg/i8 (out?) */ - case 0xF6: /* unk_F6 reg/i8 (out?) */ case 0xF7: /* unk_F7 reg/i8 (out?) */ logerror("%02x:%04x: unimplemented instruction %02x encountered\n", m_cseg, m_ip-1, op); read_op(); @@ -1589,6 +1736,9 @@ void hcd62121_cpu_device::execute_run() case 0xFC: /* unk_FC - disable interrupts/stop timer?? */ case 0xFD: /* unk_FD */ case 0xFE: /* unk_FE - wait for/start timer */ + if (op == 0xFE) + m_icount -= 75000; // TODO: temporary value that makes emulation speed acceptable + logerror("%02x:%04x: unimplemented instruction %02x encountered\n", m_cseg, m_ip-1, op); break; @@ -1602,9 +1752,7 @@ void hcd62121_cpu_device::execute_run() } while (m_icount > 0); } - -offs_t hcd62121_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, uint32_t options) +util::disasm_interface *hcd62121_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE(hcd62121); - return CPU_DISASSEMBLE_NAME(hcd62121)(this, stream, pc, oprom, opram, options); + return new hcd62121_disassembler; } diff --git a/src/devices/cpu/hcd62121/hcd62121.h b/src/devices/cpu/hcd62121/hcd62121.h index ff43a2ac1dc..1b7fb74feba 100644 --- a/src/devices/cpu/hcd62121/hcd62121.h +++ b/src/devices/cpu/hcd62121/hcd62121.h @@ -61,18 +61,16 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual u32 disasm_min_opcode_bytes() const override { return 1; } - virtual u32 disasm_max_opcode_bytes() const override { return 18; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; private: u8 read_op(); u8 datasize(u8 op); void read_reg(int size, u8 op1); void write_reg(int size, u8 op1); - void read_regreg(int size, u8 op1, u8 op2, bool op_is_logical); + void read_regreg(int size, u8 op1, u8 op2, bool copy_extend_immediate); void write_regreg(int size, u8 op1, u8 op2); - void read_iregreg(int size, u8 op1, u8 op2); + void read_iregreg(int size, u8 op1, u8 op2, bool copy_extend_immediate); void write_iregreg(int size, u8 op1, u8 op2); void write_iregreg2(int size, u8 op1, u8 op2); bool check_cond(u8 op); @@ -82,12 +80,12 @@ private: void set_zh_flag(bool is_zh); void set_cl_flag(bool is_cl); void op_msk(int size); - void op_imsk(int size); void op_and(int size); void op_or(int size); void op_xor(int size); void op_add(int size); void op_addb(int size); + void op_subb(int size); void op_sub(int size); void op_pushw(u16 source); u16 op_popw(); diff --git a/src/devices/cpu/hcd62121/hcd62121d.cpp b/src/devices/cpu/hcd62121/hcd62121d.cpp index b6598127a55..2b7ea7b1150 100644 --- a/src/devices/cpu/hcd62121/hcd62121d.cpp +++ b/src/devices/cpu/hcd62121/hcd62121d.cpp @@ -2,56 +2,17 @@ // copyright-holders:Wilbert Pol #include "emu.h" +#include "hcd62121d.h" -enum -{ - ARG_NONE=0, /* no argument or unknown */ - ARG_REG, /* register */ - ARG_REGREG, /* register1, register2, or register2, register1 or register1, imm byte */ - ARG_IRG, /* register indirect */ - ARG_IRGREG, /* 2 register indirect */ - ARG_A16, /* 16bit address */ - ARG_A24, /* seg:address */ - ARG_F, /* flag register */ - ARG_CS, /* cs register */ - ARG_DS, /* ds register */ - ARG_SS, /* ss register */ - ARG_PC, /* program counter */ - ARG_SP, /* stack pointer */ - ARG_I8, /* immediate 8 bit value */ - ARG_I16, /* immediate 16 bit value */ - ARG_I64, /* immediate 64 bit value */ - ARG_I80, /* immediate 80 bit value */ - ARG_ILR, /* indirect last address register access */ - ARG_LAR, /* last address register */ - ARG_DSZ, /* dsize register? */ - ARG_OPT, /* OPTx (output) pins */ - ARG_PORT, /* PORTx (output) pins */ - ARG_TIM, /* timing related register? */ - ARG_KLO, /* KO1 - KO8 output lines */ - ARG_KHI, /* KO9 - KO14(?) output lines */ - ARG_KI, /* K input lines */ - ARG_RS, /* rotate/shift */ - ARG_RS4 /* nibble rotate/shift */ -}; - -struct hcd62121_dasm -{ - const char *str; - u8 arg1; - u8 arg2; -}; - - -static const hcd62121_dasm hcd62121_ops[256] = +const hcd62121_disassembler::dasm hcd62121_disassembler::ops[256] = { /* 0x00 */ - { "ro?b", ARG_REG, ARG_RS4 }, { "ro?w", ARG_REG, ARG_RS4 }, - { "ro?q", ARG_REG, ARG_RS4 }, { "ro?t", ARG_REG, ARG_RS4 }, + { "sh?b", ARG_REG, ARG_S8 }, { "sh?w", ARG_REG, ARG_S8 }, + { "sh?q", ARG_REG, ARG_S8 }, { "sh?t", ARG_REG, ARG_S8 }, { "mskb", ARG_REGREG, ARG_NONE }, { "mskw", ARG_REGREG, ARG_NONE }, { "mskq", ARG_REGREG, ARG_NONE }, { "mskt", ARG_REGREG, ARG_NONE }, - { "sh?b", ARG_REG, ARG_RS4 }, { "sh?w", ARG_REG, ARG_RS4 }, - { "sh?q", ARG_REG, ARG_RS4 }, { "sh?t", ARG_REG, ARG_RS4 }, + { "sh?b", ARG_REG, ARG_S4 }, { "sh?w", ARG_REG, ARG_S4 }, + { "sh?q", ARG_REG, ARG_S4 }, { "sh?t", ARG_REG, ARG_S4 }, { "tstb", ARG_REGREG, ARG_NONE }, { "tstw", ARG_REGREG, ARG_NONE }, { "tstq", ARG_REGREG, ARG_NONE }, { "tstt", ARG_REGREG, ARG_NONE }, @@ -62,16 +23,16 @@ static const hcd62121_dasm hcd62121_ops[256] = { "cmpq", ARG_REGREG, ARG_NONE }, { "cmpt", ARG_REGREG, ARG_NONE }, { "movb", ARG_REGREG, ARG_NONE }, { "movw", ARG_REGREG, ARG_NONE }, { "movq", ARG_REGREG, ARG_NONE }, { "movt", ARG_REGREG, ARG_NONE }, - { "imskb", ARG_REGREG, ARG_NONE }, { "imskw", ARG_REGREG, ARG_NONE }, - { "imskq", ARG_REGREG, ARG_NONE }, { "imskt", ARG_REGREG, ARG_NONE }, + { "cmpaddb", ARG_REGREG, ARG_NONE }, { "cmpaddw", ARG_REGREG, ARG_NONE }, + { "cmpaddq", ARG_REGREG, ARG_NONE }, { "cmpaddt", ARG_REGREG, ARG_NONE }, /* 0x20 */ - { "ro?b", ARG_REG, ARG_RS }, { "ro?w", ARG_REG, ARG_RS }, - { "ro?q", ARG_REG, ARG_RS }, { "ro?t", ARG_REG, ARG_RS }, + { "shrb", ARG_REG, ARG_S1 }, { "shrw", ARG_REG, ARG_S1 }, + { "shrq", ARG_REG, ARG_S1 }, { "shrt", ARG_REG, ARG_S1 }, { "orb", ARG_REGREG, ARG_NONE }, { "orw", ARG_REGREG, ARG_NONE }, { "orq", ARG_REGREG, ARG_NONE }, { "ort", ARG_REGREG, ARG_NONE }, - { "sh?b", ARG_REG, ARG_RS }, { "sh?w", ARG_REG, ARG_RS }, - { "sh?q", ARG_REG, ARG_RS }, { "sh?t", ARG_REG, ARG_RS }, + { "shlb", ARG_REG, ARG_S1 }, { "shlw", ARG_REG, ARG_S1 }, + { "shlq", ARG_REG, ARG_S1 }, { "shlt", ARG_REG, ARG_S1 }, { "andb", ARG_REGREG, ARG_NONE }, { "andw", ARG_REGREG, ARG_NONE }, { "andq", ARG_REGREG, ARG_NONE }, { "andt", ARG_REGREG, ARG_NONE }, @@ -86,12 +47,12 @@ static const hcd62121_dasm hcd62121_ops[256] = { "addq", ARG_REGREG, ARG_NONE }, { "addt", ARG_REGREG, ARG_NONE }, /* 0x40 */ - { "ro?b", ARG_IRG, ARG_RS4 }, { "ro?w", ARG_IRG, ARG_RS4 }, - { "ro?q", ARG_IRG, ARG_RS4 }, { "ro?t", ARG_IRG, ARG_RS4 }, + { "sh?b", ARG_IRG, ARG_S8 }, { "sh?w", ARG_IRG, ARG_S8 }, + { "sh?q", ARG_IRG, ARG_S8 }, { "sh?t", ARG_IRG, ARG_S8 }, { "mskb", ARG_IRGREG, ARG_NONE }, { "mskw", ARG_IRGREG, ARG_NONE }, { "mskq", ARG_IRGREG, ARG_NONE }, { "mskt", ARG_IRGREG, ARG_NONE }, - { "sh?b", ARG_IRG, ARG_RS4 }, { "sh?w", ARG_IRG, ARG_RS4 }, - { "sh?q", ARG_IRG, ARG_RS4 }, { "sh?t", ARG_IRG, ARG_RS4 }, + { "sh?b", ARG_IRG, ARG_S4 }, { "sh?w", ARG_IRG, ARG_S4 }, + { "sh?q", ARG_IRG, ARG_S4 }, { "sh?t", ARG_IRG, ARG_S4 }, { "tstb", ARG_IRGREG, ARG_NONE }, { "tstw", ARG_IRGREG, ARG_NONE }, { "tstq", ARG_IRGREG, ARG_NONE }, { "tstt", ARG_IRGREG, ARG_NONE }, @@ -102,16 +63,16 @@ static const hcd62121_dasm hcd62121_ops[256] = { "cmpq", ARG_IRGREG, ARG_NONE }, { "cmpt", ARG_IRGREG, ARG_NONE }, { "movb", ARG_IRGREG, ARG_NONE }, { "movw", ARG_IRGREG, ARG_NONE }, { "movq", ARG_IRGREG, ARG_NONE }, { "movt", ARG_IRGREG, ARG_NONE }, - { "imskb", ARG_IRGREG, ARG_NONE }, { "imskw", ARG_IRGREG, ARG_NONE }, - { "imskq", ARG_IRGREG, ARG_NONE }, { "imskt", ARG_IRGREG, ARG_NONE }, + { "cmpaddb", ARG_IRGREG, ARG_NONE }, { "cmpaddw", ARG_IRGREG, ARG_NONE }, + { "cmpaddq", ARG_IRGREG, ARG_NONE }, { "cmpaddt", ARG_IRGREG, ARG_NONE }, /* 0x60 */ - { "ro?b", ARG_IRG, ARG_RS }, { "ro?w", ARG_IRG, ARG_RS }, - { "ro?q", ARG_IRG, ARG_RS }, { "ro?t", ARG_IRG, ARG_RS }, + { "shrb", ARG_IRG, ARG_S1 }, { "shrw", ARG_IRG, ARG_S1 }, + { "shrq", ARG_IRG, ARG_S1 }, { "shrt", ARG_IRG, ARG_S1 }, { "orb", ARG_IRGREG, ARG_NONE }, { "orw", ARG_IRGREG, ARG_NONE }, { "orq", ARG_IRGREG, ARG_NONE }, { "ort", ARG_IRGREG, ARG_NONE }, - { "sh?b", ARG_IRG, ARG_RS }, { "sh?w", ARG_IRG, ARG_RS }, - { "sh?q", ARG_IRG, ARG_RS }, { "sh?t", ARG_IRG, ARG_RS }, + { "shlb", ARG_IRG, ARG_S1 }, { "shlw", ARG_IRG, ARG_S1 }, + { "shlq", ARG_IRG, ARG_S1 }, { "shlt", ARG_IRG, ARG_S1 }, { "andb", ARG_IRGREG, ARG_NONE }, { "andw", ARG_IRGREG, ARG_NONE }, { "andq", ARG_IRGREG, ARG_NONE }, { "andt", ARG_IRGREG, ARG_NONE }, @@ -132,13 +93,13 @@ static const hcd62121_dasm hcd62121_ops[256] = { "un86?", ARG_NONE, ARG_NONE }, { "un87?", ARG_NONE, ARG_NONE }, { "jump", ARG_A16, ARG_NONE }, { "jump", ARG_A24, ARG_NONE }, { "call", ARG_A16, ARG_NONE }, { "un8b?", ARG_NONE, ARG_NONE }, - { "un8C?", ARG_NONE, ARG_NONE }, { "un8D?", ARG_NONE, ARG_NONE }, + { "bstack_to_dmem", ARG_NONE, ARG_NONE }, { "fstack_to_dmem", ARG_NONE, ARG_NONE }, { "un8E?", ARG_NONE, ARG_NONE }, { "un8F?", ARG_NONE, ARG_NONE }, /* 0x90 */ { "retzh", ARG_NONE, ARG_NONE }, { "retzl", ARG_NONE, ARG_NONE }, { "retc", ARG_NONE, ARG_NONE }, { "retz", ARG_NONE, ARG_NONE }, - { "retzc", ARG_NONE, ARG_NONE }, { "retcl", ARG_NONE, ARG_NONE }, + { "retnzh", ARG_NONE, ARG_NONE }, { "retnzl", ARG_NONE, ARG_NONE }, { "retnc", ARG_NONE, ARG_NONE }, { "retnz", ARG_NONE, ARG_NONE }, { "jump", ARG_IRG, ARG_NONE }, { "un99?", ARG_NONE, ARG_NONE }, { "un9A?", ARG_NONE, ARG_NONE }, { "un9b?", ARG_NONE, ARG_NONE }, @@ -148,11 +109,11 @@ static const hcd62121_dasm hcd62121_ops[256] = /* 0xa0 */ { "jmpzh", ARG_A16, ARG_NONE }, { "jmpzl", ARG_A16, ARG_NONE }, { "jmpc", ARG_A16, ARG_NONE }, { "jmpz", ARG_A16, ARG_NONE }, - { "jmpzc", ARG_A16, ARG_NONE }, { "jmpcl", ARG_A16, ARG_NONE }, + { "jmpnzh", ARG_A16, ARG_NONE }, { "jmpnzl", ARG_A16, ARG_NONE }, { "jmpnc", ARG_A16, ARG_NONE }, { "jmpnz", ARG_A16, ARG_NONE }, { "callzh", ARG_A16, ARG_NONE }, { "callzl", ARG_A16, ARG_NONE }, { "callc", ARG_A16, ARG_NONE }, { "callz", ARG_A16, ARG_NONE }, - { "callzc", ARG_A16, ARG_NONE }, { "callcl", ARG_A16, ARG_NONE }, + { "callnzh", ARG_A16, ARG_NONE }, { "callnzl", ARG_A16, ARG_NONE }, { "callnc", ARG_A16, ARG_NONE }, { "callnz", ARG_A16, ARG_NONE }, /* 0xb0 */ @@ -161,9 +122,9 @@ static const hcd62121_dasm hcd62121_ops[256] = { "out", ARG_KHI, ARG_REG }, { "out", ARG_KHI, ARG_I8 }, { "out", ARG_KLO, ARG_REG }, { "out", ARG_KLO, ARG_I8 }, { "unB8?", ARG_NONE, ARG_NONE }, { "unB9?", ARG_I8, ARG_NONE }, - { "unBA?", ARG_NONE, ARG_NONE }, { "jmpcl?", ARG_A16, ARG_NONE }, + { "unBA?", ARG_NONE, ARG_NONE }, { "jmpcl", ARG_A16, ARG_NONE }, { "unBC?", ARG_I8, ARG_NONE }, { "unBD?", ARG_NONE, ARG_NONE }, - { "unBE?", ARG_NONE, ARG_NONE }, { "jmpncl?", ARG_A16, ARG_NONE }, + { "unBE?", ARG_NONE, ARG_NONE }, { "jmpncl", ARG_A16, ARG_NONE }, /* 0xc0 */ { "movb", ARG_REG, ARG_I8 }, { "movw", ARG_REG, ARG_I16 }, @@ -183,7 +144,7 @@ static const hcd62121_dasm hcd62121_ops[256] = { "movb", ARG_F, ARG_REG }, { "movb", ARG_F, ARG_I8 }, { "unDA?", ARG_NONE, ARG_NONE }, { "unDb?", ARG_NONE, ARG_NONE }, { "movb", ARG_DS, ARG_REG }, { "movb", ARG_DS, ARG_I8 }, - { "movw", ARG_LAR, ARG_REG }, { "movw?", ARG_LAR, ARG_I8 }, + { "movw", ARG_LAR, ARG_REG }, { "movb", ARG_LAR, ARG_I8 }, /* 0xe0 */ { "in0", ARG_REG, ARG_NONE }, { "movb", ARG_REG, ARG_OPT }, @@ -206,30 +167,34 @@ static const hcd62121_dasm hcd62121_ops[256] = { "unFE?", ARG_NONE, ARG_NONE }, { "nop", ARG_NONE, ARG_NONE } }; +u32 hcd62121_disassembler::opcode_alignment() const +{ + return 1; +} -CPU_DISASSEMBLE(hcd62121) +offs_t hcd62121_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { u8 op; u8 op1; u8 op2; - u32 pos = 0; - const hcd62121_dasm *inst; + offs_t base_pc = pc; + const dasm *inst; - op = oprom[pos++]; + op = opcodes.r8(pc++); - inst = &hcd62121_ops[op]; + inst = &ops[op]; /* Special cases for shift and rotate instructions */ - if (inst->arg2 == ARG_RS || inst->arg2 == ARG_RS4) - util::stream_format(stream, "%c%c%c%c ", inst->str[0], inst->str[1], (oprom[pos] & 0x80) ? 'r' : 'l', inst->str[3]); + if (inst->arg2 == ARG_S4 || inst->arg2 == ARG_S8) + util::stream_format(stream, "%c%c%c%c ", inst->str[0], inst->str[1], (opcodes.r8(pc) & 0x80) ? 'r' : 'l', inst->str[3]); else util::stream_format(stream, "%-8s", inst->str); switch(inst->arg1) { case ARG_REGREG: - op1 = oprom[pos++]; - op2 = oprom[pos++]; + op1 = opcodes.r8(pc++); + op2 = opcodes.r8(pc++); if (op1 & 0x80) { util::stream_format(stream, "r%02x,0x%02x", op1 & 0x7f, op2); @@ -243,12 +208,12 @@ CPU_DISASSEMBLE(hcd62121) } break; case ARG_REG: - util::stream_format(stream, "r%02x", oprom[pos++] & 0x7f); + util::stream_format(stream, "r%02x", opcodes.r8(pc++) & 0x7f); break; case ARG_IRGREG: /* bit 6 = direction. 0 - regular, 1 - reverse */ - op1 = oprom[pos++]; - op2 = oprom[pos++]; + op1 = opcodes.r8(pc++); + op2 = opcodes.r8(pc++); if (op1 & 0x80) { util::stream_format(stream, "(r%02x),0x%02x", 0x40 | (op1 & 0x3f), op2); @@ -263,7 +228,7 @@ CPU_DISASSEMBLE(hcd62121) break; case ARG_IRG: /* bit 6 = direction. 0 - regular, 1 - reverse */ - op1 = oprom[pos++]; + op1 = opcodes.r8(pc++); util::stream_format(stream, "(r%02x%s)", 0x40 | (op1 & 0x3f), (op1 & 0x40) ? ".r" : ""); break; case ARG_F: @@ -285,47 +250,55 @@ CPU_DISASSEMBLE(hcd62121) util::stream_format(stream, "SP"); break; case ARG_I8: - util::stream_format(stream, "0x%02x", oprom[pos++]); + util::stream_format(stream, "0x%02x", opcodes.r8(pc++)); break; case ARG_I16: case ARG_A16: - util::stream_format(stream, "0x%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); + util::stream_format(stream, "0x%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); break; case ARG_I64: - util::stream_format(stream, "0x%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); + util::stream_format(stream, "0x%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); break; case ARG_I80: - util::stream_format(stream, "0x%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); + util::stream_format(stream, "0x%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); break; case ARG_A24: - util::stream_format(stream, "0x%02x:", oprom[pos++]); - util::stream_format(stream, "0x%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); + util::stream_format(stream, "0x%02x:", opcodes.r8(pc++)); + util::stream_format(stream, "0x%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); break; case ARG_ILR: - op1 = oprom[pos++]; - op2 = oprom[pos++]; + op1 = opcodes.r8(pc++); + op2 = opcodes.r8(pc++); if ((op1 & 0x80) || (op2 & 0x80)) { - /* (lar),reg */ - util::stream_format(stream, "(%slar%s),r%02x", (op1 & 0x20) ? ((op1 & 0x40) ? "--" : "++") : "", (op1 & 0x20) ? "" : ((op1 & 0x40) ? "--" : "++"), op2 & 0x7f); + if (op1 & 0x80) + { + /* (lar),imm */ + util::stream_format(stream, "(%slar%s), %02x", (op1 & 0x20) ? ((op1 & 0x40) ? "--" : "++") : "", (op1 & 0x20) ? "" : ((op1 & 0x40) ? "--" : "++"), op2); + } + else + { + /* (lar),reg */ + util::stream_format(stream, "(%slar%s),r%02x", (op1 & 0x20) ? ((op1 & 0x40) ? "--" : "++") : "", (op1 & 0x20) ? "" : ((op1 & 0x40) ? "--" : "++"), op2 & 0x7f); + } } else { @@ -361,7 +334,7 @@ CPU_DISASSEMBLE(hcd62121) switch(inst->arg2) { case ARG_REG: - util::stream_format(stream, ",r%02x", oprom[pos++] & 0x7f); + util::stream_format(stream, ",r%02x", opcodes.r8(pc++) & 0x7f); break; case ARG_F: util::stream_format(stream, ",F"); @@ -382,43 +355,43 @@ CPU_DISASSEMBLE(hcd62121) util::stream_format(stream, ",SP"); break; case ARG_I8: - util::stream_format(stream, ",0x%02x", oprom[pos++]); + util::stream_format(stream, ",0x%02x", opcodes.r8(pc++)); break; case ARG_I16: - util::stream_format(stream, ",0x%02x", oprom[pos+1]); - util::stream_format(stream, "%02x", oprom[pos]); - pos += 2; + util::stream_format(stream, ",0x%02x", opcodes.r8(pc+1)); + util::stream_format(stream, "%02x", opcodes.r8(pc)); + pc += 2; break; case ARG_A16: - util::stream_format(stream, ",0x%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); + util::stream_format(stream, ",0x%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); break; case ARG_I64: - util::stream_format(stream, ",0x%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); + util::stream_format(stream, ",0x%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); break; case ARG_I80: - util::stream_format(stream, ",0x%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); + util::stream_format(stream, ",0x%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); break; case ARG_A24: - util::stream_format(stream, ",0x%02x:", oprom[pos++]); - util::stream_format(stream, "0x%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); + util::stream_format(stream, ",0x%02x:", opcodes.r8(pc++)); + util::stream_format(stream, "0x%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); break; case ARG_ILR: /* Implemented by ARG_ILR section for arg1 */ @@ -441,13 +414,16 @@ CPU_DISASSEMBLE(hcd62121) case ARG_KI: util::stream_format(stream, ",KI"); break; - case ARG_RS4: + case ARG_S4: util::stream_format(stream, ",4"); break; + case ARG_S8: + util::stream_format(stream, ",8"); + break; default: break; } - return pos | DASMFLAG_SUPPORTED; + return (pc - base_pc) | SUPPORTED; } diff --git a/src/devices/cpu/hcd62121/hcd62121d.h b/src/devices/cpu/hcd62121/hcd62121d.h new file mode 100644 index 00000000000..c03d10dd410 --- /dev/null +++ b/src/devices/cpu/hcd62121/hcd62121d.h @@ -0,0 +1,62 @@ +// license:BSD-3-Clause +// copyright-holders:Wilbert Pol + +#ifndef MAME_CPU_HCD62121_HCD62121D_H +#define MAME_CPU_HCD62121_HCD62121D_H + +#pragma once + +class hcd62121_disassembler : public util::disasm_interface +{ +public: + hcd62121_disassembler() = default; + virtual ~hcd62121_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + struct dasm + { + const char *str; + u8 arg1; + u8 arg2; + }; + + enum + { + ARG_NONE=0, /* no argument or unknown */ + ARG_REG, /* register */ + ARG_REGREG, /* register1, register2, or register2, register1 or register1, imm byte */ + ARG_IRG, /* register indirect */ + ARG_IRGREG, /* 2 register indirect */ + ARG_A16, /* 16bit address */ + ARG_A24, /* seg:address */ + ARG_F, /* flag register */ + ARG_CS, /* cs register */ + ARG_DS, /* ds register */ + ARG_SS, /* ss register */ + ARG_PC, /* program counter */ + ARG_SP, /* stack pointer */ + ARG_I8, /* immediate 8 bit value */ + ARG_I16, /* immediate 16 bit value */ + ARG_I64, /* immediate 64 bit value */ + ARG_I80, /* immediate 80 bit value */ + ARG_ILR, /* indirect last address register access */ + ARG_LAR, /* last address register */ + ARG_DSZ, /* dsize register? */ + ARG_OPT, /* OPTx (output) pins */ + ARG_PORT, /* PORTx (output) pins */ + ARG_TIM, /* timing related register? */ + ARG_KLO, /* KO1 - KO8 output lines */ + ARG_KHI, /* KO9 - KO14(?) output lines */ + ARG_KI, /* K input lines */ + ARG_S1, /* shift by 1 */ + ARG_S4, /* shift by 4 */ + ARG_S8, /* shift by 8 */ + }; + + static const dasm ops[256]; +}; + +#endif diff --git a/src/devices/cpu/hd61700/hd61700.cpp b/src/devices/cpu/hd61700/hd61700.cpp index cc27d85850f..1c6225a9d79 100644 --- a/src/devices/cpu/hd61700/hd61700.cpp +++ b/src/devices/cpu/hd61700/hd61700.cpp @@ -24,6 +24,7 @@ #include "emu.h" #include "hd61700.h" +#include "hd61700d.h" #include "debugger.h" @@ -296,18 +297,15 @@ void hd61700_cpu_device::state_string_export(const device_state_entry &entry, st //------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t hd61700_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *hd61700_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( hd61700 ); - return CPU_DISASSEMBLE_NAME(hd61700)(this, stream, pc, oprom, opram, options); + return new hd61700_disassembler; } - - //------------------------------------------------- // check_irqs - check if need interrupts //------------------------------------------------- @@ -2756,7 +2754,7 @@ inline uint8_t hd61700_cpu_device::read_op() if (m_pc <= INT_ROM) { - data = m_program->read_word(addr18<<1); + data = m_program->read_word(addr18); if (!(m_fetch_addr&1)) data = (data>>8) ; @@ -2764,9 +2762,9 @@ inline uint8_t hd61700_cpu_device::read_op() else { if (m_fetch_addr&1) - data = m_program->read_word((addr18+1)<<1); + data = m_program->read_word(addr18 + 1); else - data = m_program->read_word((addr18+0)<<1); + data = m_program->read_word(addr18 + 0); } m_fetch_addr += ((m_pc > INT_ROM) ? 2 : 1); @@ -2782,12 +2780,12 @@ inline uint8_t hd61700_cpu_device::read_op() inline uint8_t hd61700_cpu_device::mem_readbyte(uint8_t segment, uint16_t offset) { - return m_program->read_word(make_18bit_addr(segment, offset)<<1) & 0xff; + return m_program->read_word(make_18bit_addr(segment, offset)) & 0xff; } inline void hd61700_cpu_device::mem_writebyte(uint8_t segment, uint16_t offset, uint8_t data) { - m_program->write_word(make_18bit_addr(segment, offset)<<1, data); + m_program->write_word(make_18bit_addr(segment, offset), data); } inline uint32_t hd61700_cpu_device::make_18bit_addr(uint8_t segment, uint16_t offset) diff --git a/src/devices/cpu/hd61700/hd61700.h b/src/devices/cpu/hd61700/hd61700.h index dba81ba0205..12da10dece3 100644 --- a/src/devices/cpu/hd61700/hd61700.h +++ b/src/devices/cpu/hd61700/hd61700.h @@ -90,9 +90,7 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 16; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // interrupts bool check_irqs(); diff --git a/src/devices/cpu/hd61700/hd61700d.cpp b/src/devices/cpu/hd61700/hd61700d.cpp index 53a98be2145..44bbcd5b1a5 100644 --- a/src/devices/cpu/hd61700/hd61700d.cpp +++ b/src/devices/cpu/hd61700/hd61700d.cpp @@ -1,55 +1,15 @@ // license:BSD-3-Clause // copyright-holders:Sandro Ronco -#include "emu.h" -#include "debugger.h" -#include "hd61700.h" - -#define EXT_ROM (pc > 0x0c00) -#define INC_POS pos += (type+1) -#define POS (pos + type) -static const char *const reg_5b[4] = {"sx", "sy", "sz", "sz"}; -static const char *const reg_8b[8] = {"pe", "pd", "ib", "ua", "ia", "ie", "tm", "tm"}; -static const char *const reg_16b[8] = {"ix", "iy", "iz", "us", "ss", "ky", "ky", "ky"}; -static const char *const jp_cond[8] = {"z", "nc", "lz", "uz", "nz", "c", "nlz"}; - -enum -{ - OP_NULL=0, - OP_IM16, - OP_IM16A, - OP_IM3, - OP_IM5, - OP_IM7, - OP_IM8, - OP_IM8I, - OP_IM8_, - OP_IR_IM3, - OP_IR_IM8, - OP_IR_IM8_, - OP_JX_COND, - OP_MREG, - OP_MREG2, - OP_MR_SIR, - OP_MR_SIRI, - OP_REG16, - OP_REG16_, - OP_REG8, - OP_REG8_, - OP_REGIM8, - OP_RMSIM3, - OP_RSIR -}; +#include "emu.h" +#include "hd61700d.h" -struct hd61700_dasm -{ - const char *str; - uint8_t arg1; - uint8_t arg2; - bool optjr; -}; +const char *const hd61700_disassembler::reg_5b[4] = {"sx", "sy", "sz", "sz"}; +const char *const hd61700_disassembler::reg_8b[8] = {"pe", "pd", "ib", "ua", "ia", "ie", "tm", "tm"}; +const char *const hd61700_disassembler::reg_16b[8] = {"ix", "iy", "iz", "us", "ss", "ky", "ky", "ky"}; +const char *const hd61700_disassembler::jp_cond[8] = {"z", "nc", "lz", "uz", "nz", "c", "nlz"}; -static const hd61700_dasm hd61700_ops[256] = +const hd61700_disassembler::dasm hd61700_disassembler::ops[256] = { // 0x00 { "adc", OP_MREG, OP_MR_SIR, 1 }, { "sbc", OP_MREG, OP_MR_SIR, 1 }, @@ -212,13 +172,20 @@ static const hd61700_dasm hd61700_ops[256] = { "off", OP_NULL, OP_NULL, 0 }, { "trp", OP_NULL, OP_NULL, 0 }, }; +u8 hd61700_disassembler::opread(offs_t pc, offs_t pos, const data_buffer &opcodes) +{ + if(pc >= 0x0c00) + return opcodes.r16(pc + pos) & 0xff; + else + return pos & 1 ? opcodes.r16(pc + (pos >> 1)) & 0xff : opcodes.r16(pc + (pos >> 1)) >> 8; +} -static void dasm_im8(std::ostream &stream, uint16_t pc, int arg, const uint8_t *oprom, int &pos, int type) +void hd61700_disassembler::dasm_im8(std::ostream &stream, offs_t pc, int arg, offs_t &pos, const data_buffer &opcodes) { if (((arg>>5) & 0x03) == 0x03) { - INC_POS; - util::stream_format(stream, "0x%02x", oprom[POS] & 0x1f); + pos ++; + util::stream_format(stream, "0x%02x", opread(pc, pos, opcodes) & 0x1f); } else { @@ -227,7 +194,7 @@ static void dasm_im8(std::ostream &stream, uint16_t pc, int arg, const uint8_t * } -static void dasm_im8(std::ostream &stream, uint16_t pc, int arg, int arg1, const uint8_t *oprom, int &pos) +void hd61700_disassembler::dasm_im8(std::ostream &stream, offs_t pc, int arg, int arg1, offs_t &pos, const data_buffer &opcodes) { if (((arg>>5) & 0x03) == 0x03) { @@ -240,57 +207,55 @@ static void dasm_im8(std::ostream &stream, uint16_t pc, int arg, int arg1, const } -static void dasm_arg(std::ostream &stream, uint8_t op, uint16_t pc, int arg, const uint8_t *oprom, int &pos) +void hd61700_disassembler::dasm_arg(std::ostream &stream, uint8_t op, offs_t pc, int arg, offs_t &pos, const data_buffer &opcodes) { - int type = EXT_ROM; - switch( arg ) { case OP_MREG: case OP_MREG2: - util::stream_format( stream, "$%02u", oprom[POS] & 0x1f ); - if (arg == OP_MREG2) INC_POS; + util::stream_format( stream, "$%02u", opread(pc, pos, opcodes) & 0x1f ); + if (arg == OP_MREG2) pos ++; break; case OP_RSIR: - util::stream_format( stream, "%s", reg_5b[(oprom[POS]>>5) & 0x03] ); + util::stream_format( stream, "%s", reg_5b[(opread(pc, pos, opcodes)>>5) & 0x03] ); break; case OP_REG8: case OP_REG8_: - util::stream_format( stream, "%s", reg_8b[(BIT(op,0)<<2) + ((oprom[POS]>>5&3))]); - if (arg == OP_REG8_) INC_POS; + util::stream_format( stream, "%s", reg_8b[(BIT(op,0)<<2) + ((opread(pc, pos, opcodes)>>5&3))]); + if (arg == OP_REG8_) pos ++; break; case OP_MR_SIR: - dasm_im8(stream, pc, oprom[POS], oprom, pos, type); - INC_POS; + dasm_im8(stream, pc, opread(pc, pos, opcodes), pos, opcodes); + pos ++; break; case OP_IR_IM8: case OP_IR_IM8_: - util::stream_format( stream, "(%s%s", (op&1) ? "iz": "ix", (oprom[POS]&0x80) ? "-": "+"); - dasm_im8(stream, pc, oprom[POS], oprom, pos, type); + util::stream_format( stream, "(%s%s", (op&1) ? "iz": "ix", (opread(pc, pos, opcodes)&0x80) ? "-": "+"); + dasm_im8(stream, pc, opread(pc, pos, opcodes), pos, opcodes); util::stream_format( stream, ")"); - if (arg == OP_IR_IM8_) INC_POS; + if (arg == OP_IR_IM8_) pos ++; break; case OP_IM8_: - INC_POS; + pos ++; case OP_IM8: - util::stream_format( stream, "0x%02x", oprom[POS] ); - INC_POS; + util::stream_format( stream, "0x%02x", opread(pc, pos, opcodes) ); + pos ++; break; case OP_IM8I: - util::stream_format( stream, "(0x%02x)", oprom[POS] ); - INC_POS; + util::stream_format( stream, "(0x%02x)", opread(pc, pos, opcodes) ); + pos ++; break; case OP_REGIM8: - util::stream_format( stream, "(%s%s", (op&1) ? "iz": "ix", (oprom[POS]&0x80) ? "-": "+"); - util::stream_format( stream, "%x)", oprom[POS] & 0x1f); - INC_POS; + util::stream_format( stream, "(%s%s", (op&1) ? "iz": "ix", (opread(pc, pos, opcodes)&0x80) ? "-": "+"); + util::stream_format( stream, "%x)", opread(pc, pos, opcodes) & 0x1f); + pos ++; break; case OP_JX_COND: @@ -300,67 +265,67 @@ static void dasm_arg(std::ostream &stream, uint8_t op, uint16_t pc, int arg, con case OP_RMSIM3: { - uint8_t tmp = oprom[POS]; - INC_POS; - dasm_im8(stream, pc, tmp, oprom[POS], oprom, pos); + uint8_t tmp = opread(pc, pos, opcodes); + pos ++; + dasm_im8(stream, pc, tmp, opread(pc, pos, opcodes), pos, opcodes); util::stream_format( stream, ", 0x%02x", ((tmp>>5)&7)+1); - INC_POS; + pos ++; } break; case OP_IR_IM3: { - uint8_t tmp = oprom[POS]; - INC_POS; + uint8_t tmp = opread(pc, pos, opcodes); + pos ++; util::stream_format( stream, "(%s%s", (op&1) ? "iz": "ix", (tmp&0x80) ? "-": "+"); - dasm_im8(stream, pc, tmp, oprom[POS], oprom, pos); - util::stream_format( stream, "), 0x%02x", ((oprom[POS]>>5)&7)+1 ); - INC_POS; + dasm_im8(stream, pc, tmp, opread(pc, pos, opcodes), pos, opcodes); + util::stream_format( stream, "), 0x%02x", ((opread(pc, pos, opcodes)>>5)&7)+1 ); + pos ++; } break; case OP_IM3: - util::stream_format( stream, "0x%02x", ((oprom[POS]>>5)&7)+1 ); - INC_POS; + util::stream_format( stream, "0x%02x", ((opread(pc, pos, opcodes)>>5)&7)+1 ); + pos ++; break; case OP_MR_SIRI: util::stream_format( stream, "("); - dasm_im8(stream, pc, oprom[POS], oprom, pos, type); + dasm_im8(stream, pc, opread(pc, pos, opcodes), pos, opcodes); util::stream_format( stream, ")"); - INC_POS; + pos ++; break; case OP_IM7: { - int tmp = oprom[POS]; + int tmp = opread(pc, pos, opcodes); if (tmp&0x80) tmp = 0x80 - tmp; - util::stream_format( stream, "0x%04x", (pc + tmp + EXT_ROM) & 0xffff ); - INC_POS; + util::stream_format( stream, "0x%04x", (pc + tmp + (pc >= 0x0c00)) & 0xffff ); + pos ++; } break; case OP_IM5: - util::stream_format( stream, "0x%02x", oprom[POS]&0x1f ); - INC_POS; + util::stream_format( stream, "0x%02x", opread(pc, pos, opcodes)&0x1f ); + pos ++; break; case OP_REG16: case OP_REG16_: - util::stream_format(stream, "%s", reg_16b[(BIT(op,0)<<2) + ((oprom[POS]>>5&3))]); - if (arg == OP_REG16_) INC_POS; + util::stream_format(stream, "%s", reg_16b[(BIT(op,0)<<2) + ((opread(pc, pos, opcodes)>>5&3))]); + if (arg == OP_REG16_) pos ++; break; case OP_IM16: case OP_IM16A: { - uint8_t tmp1 = oprom[POS]; - INC_POS; - if (!EXT_ROM && arg == OP_IM16A) INC_POS; - uint8_t tmp2 = oprom[POS]; + uint8_t tmp1 = opread(pc, pos, opcodes); + pos ++; + if (pc < 0x0c00 && arg == OP_IM16A) pos ++; + uint8_t tmp2 = opread(pc, pos, opcodes); util::stream_format(stream, "0x%04x", ((tmp2<<8) | tmp1)); - INC_POS; + pos ++; } break; @@ -369,7 +334,7 @@ static void dasm_arg(std::ostream &stream, uint8_t op, uint16_t pc, int arg, con } } -uint32_t get_dasmflags(uint8_t op) +uint32_t hd61700_disassembler::get_dasmflags(uint8_t op) { switch (op) { @@ -381,55 +346,61 @@ uint32_t get_dasmflags(uint8_t op) case 0xb4: case 0xb5: case 0xb6: case 0xb7: //jr case 0xde: //jp case 0xdf: //jp - return DASMFLAG_STEP_OVER; + return STEP_OVER; case 0xf0: case 0xf1: case 0xf2: case 0xf3: //rtn case 0xf4: case 0xf5: case 0xf6: case 0xf7: //rtn case 0xfd: //rtni - return DASMFLAG_STEP_OUT; + return STEP_OUT; } return 0; } +u32 hd61700_disassembler::opcode_alignment() const +{ + return 1; +} -CPU_DISASSEMBLE(hd61700) +offs_t hd61700_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - const hd61700_dasm *inst; + const dasm *inst; uint32_t dasmflags; uint8_t op, op1; - int pos = 0, type = EXT_ROM; + offs_t pos = 0; + int type = pc >= 0x0c00; - op = oprom[POS]; - INC_POS; + op = opread(pc, pos, opcodes); + pos++; dasmflags = get_dasmflags(op); - op1 = oprom[POS]; + op1 = opread(pc, pos, opcodes); + pos++; - inst = &hd61700_ops[op]; + inst = &ops[op]; util::stream_format(stream, "%-8s", inst->str); //dasm first arg - dasm_arg(stream, op, pc, inst->arg1, oprom, pos); + dasm_arg(stream, op, pc, inst->arg1, pos, opcodes); //if present dasm second arg if (inst->arg2 != OP_NULL) { util::stream_format(stream, ", "); - dasm_arg(stream, op, pc, inst->arg2, oprom, pos); + dasm_arg(stream, op, pc, inst->arg2, pos, opcodes); } //if required add the optional jr if (inst->optjr == true && BIT(op1, 7)) { util::stream_format(stream, ", jr "); - dasm_arg(stream, op, pc+1, OP_IM7, oprom, pos); + dasm_arg(stream, op, pc+1, OP_IM7, pos, opcodes); - dasmflags = DASMFLAG_STEP_OVER; + dasmflags = STEP_OVER; } - if (pos&1) INC_POS; + if (pos&1) pos += type+1; - return (pos>>1) | dasmflags | DASMFLAG_SUPPORTED; + return (pos>>1) | dasmflags | SUPPORTED; } diff --git a/src/devices/cpu/hd61700/hd61700d.h b/src/devices/cpu/hd61700/hd61700d.h new file mode 100644 index 00000000000..f951bf540c8 --- /dev/null +++ b/src/devices/cpu/hd61700/hd61700d.h @@ -0,0 +1,70 @@ +// license:BSD-3-Clause +// copyright-holders:Sandro Ronco + + +#ifndef MAME_CPU_HD61700_HD61700D_H +#define MAME_CPU_HD61700_HD61700D_H + +#pragma once + +class hd61700_disassembler : public util::disasm_interface +{ +public: + hd61700_disassembler() = default; + virtual ~hd61700_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + struct dasm + { + const char *str; + uint8_t arg1; + uint8_t arg2; + bool optjr; + }; + + enum + { + OP_NULL=0, + OP_IM16, + OP_IM16A, + OP_IM3, + OP_IM5, + OP_IM7, + OP_IM8, + OP_IM8I, + OP_IM8_, + OP_IR_IM3, + OP_IR_IM8, + OP_IR_IM8_, + OP_JX_COND, + OP_MREG, + OP_MREG2, + OP_MR_SIR, + OP_MR_SIRI, + OP_REG16, + OP_REG16_, + OP_REG8, + OP_REG8_, + OP_REGIM8, + OP_RMSIM3, + OP_RSIR + }; + + static const char *const reg_5b[4]; + static const char *const reg_8b[8]; + static const char *const reg_16b[8]; + static const char *const jp_cond[8]; + + static const dasm ops[256]; + + u8 opread(offs_t pc, offs_t pos, const data_buffer &opcodes); + void dasm_im8(std::ostream &stream, offs_t pc, int arg, offs_t &pos, const data_buffer &opcodes); + void dasm_im8(std::ostream &stream, offs_t pc, int arg, int arg1, offs_t &pos, const data_buffer &opcodes); + void dasm_arg(std::ostream &stream, uint8_t op, offs_t pc, int arg, offs_t &pos, const data_buffer &opcodes); + uint32_t get_dasmflags(uint8_t op); +}; + +#endif diff --git a/src/devices/cpu/hmcs40/hmcs40.cpp b/src/devices/cpu/hmcs40/hmcs40.cpp index 2bc1860917c..a80c067aaeb 100644 --- a/src/devices/cpu/hmcs40/hmcs40.cpp +++ b/src/devices/cpu/hmcs40/hmcs40.cpp @@ -14,6 +14,7 @@ #include "emu.h" #include "hmcs40.h" #include "debugger.h" +#include "hmcs40d.h" #define IS_PMOS 0 #define IS_CMOS ~0 @@ -173,14 +174,12 @@ void hmcs40_cpu_device::state_string_export(const device_state_entry &entry, std } } -offs_t hmcs40_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +util::disasm_interface *hmcs40_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE(hmcs40); - return CPU_DISASSEMBLE_NAME(hmcs40)(this, stream, pc, oprom, opram, options); + return new hmcs40_disassembler; } - //------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- @@ -620,7 +619,7 @@ void hmcs40_cpu_device::execute_run() // fetch next opcode debugger_instruction_hook(this, m_pc); m_icount--; - m_op = m_program->read_word(m_pc << 1) & 0x3ff; + m_op = m_program->read_word(m_pc) & 0x3ff; m_i = BITSWAP8(m_op,7,6,5,4,0,1,2,3) & 0xf; // reversed bit-order for 4-bit immediate param (except for XAMR) increment_pc(); diff --git a/src/devices/cpu/hmcs40/hmcs40.h b/src/devices/cpu/hmcs40/hmcs40.h index 33e439fc1f5..ca5f238ad9a 100644 --- a/src/devices/cpu/hmcs40/hmcs40.h +++ b/src/devices/cpu/hmcs40/hmcs40.h @@ -158,9 +158,7 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual u32 disasm_min_opcode_bytes() const override { return 2; } - virtual u32 disasm_max_opcode_bytes() const override { return 2; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; address_space_config m_program_config; diff --git a/src/devices/cpu/hmcs40/hmcs40d.cpp b/src/devices/cpu/hmcs40/hmcs40d.cpp index 7074bf5283a..48ae33ccfaa 100644 --- a/src/devices/cpu/hmcs40/hmcs40d.cpp +++ b/src/devices/cpu/hmcs40/hmcs40d.cpp @@ -9,27 +9,9 @@ */ #include "emu.h" -#include "debugger.h" -#include "hmcs40.h" +#include "hmcs40d.h" - -enum e_mnemonics -{ - mILL, - mLAB, mLBA, mLAY, mLASPX, mLASPY, mXAMR, - mLXA, mLYA, mLXI, mLYI, mIY, mDY, mAYY, mSYY, mXSP, - mLAM, mLBM, mXMA, mXMB, mLMAIY, mLMADY, - mLMIIY, mLAI, mLBI, - mAI, mIB, mDB, mAMC, mSMC, mAM, mDAA, mDAS, mNEGA, mCOMB, mSEC, mREC, mTC, mROTL, mROTR, mOR, - mMNEI, mYNEI, mANEM, mBNEM, mALEI, mALEM, mBLEM, - mSEM, mREM, mTM, - mBR, mCAL, mLPU, mTBR, mRTN, - mSEIE, mSEIF0, mSEIF1, mSETF, mSECF, mREIE, mREIF0, mREIF1, mRETF, mRECF, mTI0, mTI1, mTIF0, mTIF1, mTTF, mLTI, mLTA, mLAT, mRTNI, - mSED, mRED, mTD, mSEDD, mREDD, mLAR, mLBR, mLRA, mLRB, mP, - mNOP -}; - -static const char *const s_mnemonics[] = +const char *const hmcs40_disassembler::s_mnemonics[] = { "?", "LAB", "LBA", "LAY", "LASPX", "LASPY", "XAMR", @@ -46,7 +28,7 @@ static const char *const s_mnemonics[] = }; // number of bits per opcode parameter, 99 means (XY) parameter, negative means reversed bit-order -static const s8 s_bits[] = +const s8 hmcs40_disassembler::s_bits[] = { 0, 0, 0, 0, 0, 0, 4, @@ -62,10 +44,7 @@ static const s8 s_bits[] = 0 }; -#define _OVER DASMFLAG_STEP_OVER -#define _OUT DASMFLAG_STEP_OUT - -static const u32 s_flags[] = +const u32 hmcs40_disassembler::s_flags[] = { 0, 0, 0, 0, 0, 0, 0, @@ -75,14 +54,13 @@ static const u32 s_flags[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, _OVER, 0, 0, _OUT, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _OUT, + 0, STEP_OVER, 0, 0, STEP_OUT, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, STEP_OUT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - -static const u8 hmcs40_mnemonic[0x400] = +const u8 hmcs40_disassembler::hmcs40_mnemonic[0x400] = { /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ /* 0x000 */ @@ -175,9 +153,9 @@ static const u8 hmcs40_mnemonic[0x400] = -CPU_DISASSEMBLE(hmcs40) +offs_t hmcs40_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - u16 op = (oprom[0] | oprom[1] << 8) & 0x3ff; + u16 op = opcodes.r16(pc) & 0x3ff; u8 instr = hmcs40_mnemonic[op]; s8 bits = s_bits[instr]; @@ -217,5 +195,43 @@ CPU_DISASSEMBLE(hmcs40) } } - return 1 | s_flags[instr] | DASMFLAG_SUPPORTED; + return 1 | s_flags[instr] | SUPPORTED; +} + +u32 hmcs40_disassembler::opcode_alignment() const +{ + return 1; +} + +u32 hmcs40_disassembler::interface_flags() const +{ + return NONLINEAR_PC | PAGED; +} + +u32 hmcs40_disassembler::page_address_bits() const +{ + return 6; } + +offs_t hmcs40_disassembler::pc_linear_to_real(offs_t pc) const +{ + static const u8 l2r[64] = { + 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x3e, 0x3d, 0x3b, 0x37, 0x2f, 0x1e, 0x3c, 0x39, 0x33, + 0x27, 0x0e, 0x1d, 0x3a, 0x35, 0x2b, 0x16, 0x2c, 0x18, 0x30, 0x21, 0x02, 0x05, 0x0b, 0x17, 0x2e, + 0x1c, 0x38, 0x31, 0x23, 0x06, 0x0d, 0x1b, 0x36, 0x2d, 0x1a, 0x34, 0x29, 0x12, 0x24, 0x08, 0x11, + 0x22, 0x04, 0x09, 0x13, 0x26, 0x0c, 0x19, 0x32, 0x25, 0x0a, 0x15, 0x2a, 0x14, 0x28, 0x10, 0x20, + }; + return (pc & ~0x3f) | l2r[pc & 0x3f]; +} + +offs_t hmcs40_disassembler::pc_real_to_linear(offs_t pc) const +{ + static const u8 r2l[64] = { + 0x00, 0x01, 0x1b, 0x02, 0x31, 0x1c, 0x24, 0x03, 0x2e, 0x32, 0x39, 0x1d, 0x35, 0x25, 0x11, 0x04, + 0x3e, 0x2f, 0x2c, 0x33, 0x3c, 0x3a, 0x16, 0x1e, 0x18, 0x36, 0x29, 0x26, 0x20, 0x12, 0x0c, 0x05, + 0x3f, 0x1a, 0x30, 0x23, 0x2d, 0x38, 0x34, 0x10, 0x3d, 0x2b, 0x3b, 0x15, 0x17, 0x28, 0x1f, 0x0b, + 0x19, 0x22, 0x37, 0x0f, 0x2a, 0x14, 0x27, 0x0a, 0x21, 0x0e, 0x13, 0x09, 0x0d, 0x08, 0x07, 0x06, + }; + return (pc & ~0x3f) | r2l[pc & 0x3f]; +} + diff --git a/src/devices/cpu/hmcs40/hmcs40d.h b/src/devices/cpu/hmcs40/hmcs40d.h new file mode 100644 index 00000000000..04f534bdc4c --- /dev/null +++ b/src/devices/cpu/hmcs40/hmcs40d.h @@ -0,0 +1,50 @@ +// license:BSD-3-Clause +// copyright-holders:hap +/* + + Hitachi HMCS40 MCU family disassembler + +*/ + +#ifndef MAME_CPU_HMCS40_HMCS40D_H +#define MAME_CPU_HMCS40_HMCS40D_H + +#pragma once + +class hmcs40_disassembler : public util::disasm_interface +{ +public: + hmcs40_disassembler() = default; + virtual ~hmcs40_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual u32 interface_flags() const override; + virtual u32 page_address_bits() const override; + virtual offs_t pc_linear_to_real(offs_t pc) const override; + virtual offs_t pc_real_to_linear(offs_t pc) const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum e_mnemonics + { + mILL, + mLAB, mLBA, mLAY, mLASPX, mLASPY, mXAMR, + mLXA, mLYA, mLXI, mLYI, mIY, mDY, mAYY, mSYY, mXSP, + mLAM, mLBM, mXMA, mXMB, mLMAIY, mLMADY, + mLMIIY, mLAI, mLBI, + mAI, mIB, mDB, mAMC, mSMC, mAM, mDAA, mDAS, mNEGA, mCOMB, mSEC, mREC, mTC, mROTL, mROTR, mOR, + mMNEI, mYNEI, mANEM, mBNEM, mALEI, mALEM, mBLEM, + mSEM, mREM, mTM, + mBR, mCAL, mLPU, mTBR, mRTN, + mSEIE, mSEIF0, mSEIF1, mSETF, mSECF, mREIE, mREIF0, mREIF1, mRETF, mRECF, mTI0, mTI1, mTIF0, mTIF1, mTTF, mLTI, mLTA, mLAT, mRTNI, + mSED, mRED, mTD, mSEDD, mREDD, mLAR, mLBR, mLRA, mLRB, mP, + mNOP + }; + + static const char *const s_mnemonics[]; + static const s8 s_bits[]; + static const u32 s_flags[]; + static const u8 hmcs40_mnemonic[0x400]; +}; + +#endif diff --git a/src/devices/cpu/hmcs40/hmcs40op.cpp b/src/devices/cpu/hmcs40/hmcs40op.cpp index 2c28d4cb54e..2078d5e765b 100644 --- a/src/devices/cpu/hmcs40/hmcs40op.cpp +++ b/src/devices/cpu/hmcs40/hmcs40op.cpp @@ -663,7 +663,7 @@ void hmcs40_cpu_device::op_p() // P p: Pattern Generation m_icount--; u16 address = m_a | m_b << 4 | m_c << 8 | (m_op & 7) << 9 | (m_pc & ~0x3f); - u16 o = m_program->read_word((address & m_prgmask) << 1); + u16 o = m_program->read_word(address & m_prgmask); // destination is determined by the 2 highest bits if (o & 0x100) diff --git a/src/devices/cpu/hphybrid/hphybrid.cpp b/src/devices/cpu/hphybrid/hphybrid.cpp index 6eb3f4b83d6..9e8457b255d 100644 --- a/src/devices/cpu/hphybrid/hphybrid.cpp +++ b/src/devices/cpu/hphybrid/hphybrid.cpp @@ -33,6 +33,7 @@ #include "emu.h" #include "hphybrid.h" +#include "hphybrid_dasm.h" #include "debugger.h" #include "hphybrid_defs.h" @@ -201,7 +202,7 @@ void hp_hybrid_cpu_device::device_start() } m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<-1>(); m_io = &space(AS_IO); save_item(NAME(m_reg_A)); @@ -296,808 +297,809 @@ uint16_t hp_hybrid_cpu_device::execute_one(uint16_t opcode) */ uint16_t hp_hybrid_cpu_device::execute_one_sub(uint16_t opcode) { - uint32_t ea; - uint16_t tmp; - - switch (opcode & 0x7800) { - case 0x0000: - // LDA - m_icount -= 13; - m_reg_A = RM(get_ea(opcode)); - break; - - case 0x0800: - // LDB - m_icount -= 13; - m_reg_B = RM(get_ea(opcode)); - break; - - case 0x1000: - // CPA - m_icount -= 16; - if (m_reg_A != RM(get_ea(opcode))) { - // Skip next instruction - return m_reg_P + 2; - } - break; - - case 0x1800: - // CPB - m_icount -= 16; - if (m_reg_B != RM(get_ea(opcode))) { - // Skip next instruction - return m_reg_P + 2; - } - break; - - case 0x2000: - // ADA - m_icount -= 13; - do_add(m_reg_A , RM(get_ea(opcode))); - break; - - case 0x2800: - // ADB - m_icount -= 13; - do_add(m_reg_B , RM(get_ea(opcode))); - break; - - case 0x3000: - // STA - m_icount -= 13; - WM(get_ea(opcode) , m_reg_A); - break; - - case 0x3800: - // STB - m_icount -= 13; - WM(get_ea(opcode) , m_reg_B); - break; - - case 0x4000: - // JSM - m_icount -= 17; - WM(AEC_CASE_C , ++m_reg_R , m_reg_P); - return remove_mae(get_ea(opcode)); - - case 0x4800: - // ISZ - m_icount -= 19; - ea = get_ea(opcode); - tmp = RM(ea) + 1; - WM(ea , tmp); - if (tmp == 0) { - // Skip next instruction - return m_reg_P + 2; - } - break; - - case 0x5000: - // AND - m_icount -= 13; - m_reg_A &= RM(get_ea(opcode)); - break; - - case 0x5800: - // DSZ - m_icount -= 19; - ea = get_ea(opcode); - tmp = RM(ea) - 1; - WM(ea , tmp); - if (tmp == 0) { - // Skip next instruction - return m_reg_P + 2; - } - break; - - case 0x6000: - // IOR - m_icount -= 13; - m_reg_A |= RM(get_ea(opcode)); - break; - - case 0x6800: - // JMP - m_icount -= 8; - return remove_mae(get_ea(opcode)); + uint32_t ea; + uint16_t tmp; + + switch (opcode & 0x7800) { + case 0x0000: + // LDA + m_icount -= 13; + m_reg_A = RM(get_ea(opcode)); + break; + + case 0x0800: + // LDB + m_icount -= 13; + m_reg_B = RM(get_ea(opcode)); + break; + + case 0x1000: + // CPA + m_icount -= 16; + if (m_reg_A != RM(get_ea(opcode))) { + // Skip next instruction + return m_reg_P + 2; + } + break; + + case 0x1800: + // CPB + m_icount -= 16; + if (m_reg_B != RM(get_ea(opcode))) { + // Skip next instruction + return m_reg_P + 2; + } + break; + + case 0x2000: + // ADA + m_icount -= 13; + do_add(m_reg_A , RM(get_ea(opcode))); + break; + + case 0x2800: + // ADB + m_icount -= 13; + do_add(m_reg_B , RM(get_ea(opcode))); + break; + + case 0x3000: + // STA + m_icount -= 13; + WM(get_ea(opcode) , m_reg_A); + break; + + case 0x3800: + // STB + m_icount -= 13; + WM(get_ea(opcode) , m_reg_B); + break; + + case 0x4000: + // JSM + m_icount -= 17; + WM(AEC_CASE_C , ++m_reg_R , m_reg_P); + return remove_mae(get_ea(opcode)); + + case 0x4800: + // ISZ + m_icount -= 19; + ea = get_ea(opcode); + tmp = RM(ea) + 1; + WM(ea , tmp); + if (tmp == 0) { + // Skip next instruction + return m_reg_P + 2; + } + break; + + case 0x5000: + // AND + m_icount -= 13; + m_reg_A &= RM(get_ea(opcode)); + break; + + case 0x5800: + // DSZ + m_icount -= 19; + ea = get_ea(opcode); + tmp = RM(ea) - 1; + WM(ea , tmp); + if (tmp == 0) { + // Skip next instruction + return m_reg_P + 2; + } + break; + + case 0x6000: + // IOR + m_icount -= 13; + m_reg_A |= RM(get_ea(opcode)); + break; + + case 0x6800: + // JMP + m_icount -= 8; + return remove_mae(get_ea(opcode)); + + default: + switch (opcode & 0xfec0) { + case 0x7400: + // RZA + // SZA + m_icount -= 14; + return get_skip_addr(opcode , m_reg_A == 0); + + case 0x7440: + // RIA + // SIA + m_icount -= 14; + return get_skip_addr(opcode , m_reg_A++ == 0); + + case 0x7480: + // SFS + // SFC + m_icount -= 14; + return get_skip_addr(opcode , !BIT(m_flags , HPHYBRID_FLG_BIT)); + + case 0x7C00: + // RZB + // SZB + m_icount -= 14; + return get_skip_addr(opcode , m_reg_B == 0); + + case 0x7C40: + // RIB + // SIB + m_icount -= 14; + return get_skip_addr(opcode , m_reg_B++ == 0); + + case 0x7c80: + // SSS + // SSC + m_icount -= 14; + return get_skip_addr(opcode , !BIT(m_flags , HPHYBRID_STS_BIT)); + + case 0x7cc0: + // SHS + // SHC + m_icount -= 14; + return get_skip_addr(opcode , !BIT(m_flags , HPHYBRID_HALT_BIT)); + + default: + switch (opcode & 0xfe00) { + case 0x7600: + // SLA + // RLA + m_icount -= 14; + return get_skip_addr_sc(opcode , m_reg_A , 0); + + case 0x7e00: + // SLB + // RLB + m_icount -= 14; + return get_skip_addr_sc(opcode , m_reg_B , 0); + + case 0xf400: + // SAP + // SAM + m_icount -= 14; + return get_skip_addr_sc(opcode , m_reg_A , 15); + + case 0xf600: + // SOC + // SOS + m_icount -= 14; + return get_skip_addr_sc(opcode , m_flags , HPHYBRID_O_BIT); + + case 0xfc00: + // SBP + // SBM + m_icount -= 14; + return get_skip_addr_sc(opcode , m_reg_B , 15); + + case 0xfe00: + // SEC + // SES + m_icount -= 14; + return get_skip_addr_sc(opcode , m_flags , HPHYBRID_C_BIT); + + default: + switch (opcode & 0xfff0) { + case 0xf100: + // AAR + tmp = (opcode & 0xf) + 1; + m_icount -= (9 + tmp); + // A shift by 16 positions is equivalent to a shift by 15 + tmp = tmp > 15 ? 15 : tmp; + m_reg_A = ((m_reg_A ^ 0x8000) >> tmp) - (0x8000 >> tmp); + break; + + case 0xf900: + // ABR + tmp = (opcode & 0xf) + 1; + m_icount -= (9 + tmp); + tmp = tmp > 15 ? 15 : tmp; + m_reg_B = ((m_reg_B ^ 0x8000) >> tmp) - (0x8000 >> tmp); + break; + + case 0xf140: + // SAR + tmp = (opcode & 0xf) + 1; + m_icount -= (9 + tmp); + m_reg_A >>= tmp; + break; + + case 0xf940: + // SBR + tmp = (opcode & 0xf) + 1; + m_icount -= (9 + tmp); + m_reg_B >>= tmp; + break; + + case 0xf180: + // SAL + tmp = (opcode & 0xf) + 1; + m_icount -= (9 + tmp); + m_reg_A <<= tmp; + break; + + case 0xf980: + // SBL + tmp = (opcode & 0xf) + 1; + m_icount -= (9 + tmp); + m_reg_B <<= tmp; + break; + + case 0xf1c0: + // RAR + tmp = (opcode & 0xf) + 1; + m_icount -= (9 + tmp); + m_reg_A = (m_reg_A >> tmp) | (m_reg_A << (16 - tmp)); + break; + + case 0xf9c0: + // RBR + tmp = (opcode & 0xf) + 1; + m_icount -= (9 + tmp); + m_reg_B = (m_reg_B >> tmp) | (m_reg_B << (16 - tmp)); + break; default: - switch (opcode & 0xfec0) { - case 0x7400: - // RZA - // SZA - m_icount -= 14; - return get_skip_addr(opcode , m_reg_A == 0); - - case 0x7440: - // RIA - // SIA - m_icount -= 14; - return get_skip_addr(opcode , m_reg_A++ == 0); - - case 0x7480: - // SFS - // SFC - m_icount -= 14; - return get_skip_addr(opcode , !BIT(m_flags , HPHYBRID_FLG_BIT)); - - case 0x7C00: - // RZB - // SZB - m_icount -= 14; - return get_skip_addr(opcode , m_reg_B == 0); - - case 0x7C40: - // RIB - // SIB - m_icount -= 14; - return get_skip_addr(opcode , m_reg_B++ == 0); - - case 0x7c80: - // SSS - // SSC - m_icount -= 14; - return get_skip_addr(opcode , !BIT(m_flags , HPHYBRID_STS_BIT)); - - case 0x7cc0: - // SHS - // SHC - m_icount -= 14; - return get_skip_addr(opcode , !BIT(m_flags , HPHYBRID_HALT_BIT)); - - default: - switch (opcode & 0xfe00) { - case 0x7600: - // SLA - // RLA - m_icount -= 14; - return get_skip_addr_sc(opcode , m_reg_A , 0); - - case 0x7e00: - // SLB - // RLB - m_icount -= 14; - return get_skip_addr_sc(opcode , m_reg_B , 0); - - case 0xf400: - // SAP - // SAM - m_icount -= 14; - return get_skip_addr_sc(opcode , m_reg_A , 15); - - case 0xf600: - // SOC - // SOS - m_icount -= 14; - return get_skip_addr_sc(opcode , m_flags , HPHYBRID_O_BIT); - - case 0xfc00: - // SBP - // SBM - m_icount -= 14; - return get_skip_addr_sc(opcode , m_reg_B , 15); - - case 0xfe00: - // SEC - // SES - m_icount -= 14; - return get_skip_addr_sc(opcode , m_flags , HPHYBRID_C_BIT); - - default: - switch (opcode & 0xfff0) { - case 0xf100: - // AAR - tmp = (opcode & 0xf) + 1; - m_icount -= (9 + tmp); - // A shift by 16 positions is equivalent to a shift by 15 - tmp = tmp > 15 ? 15 : tmp; - m_reg_A = ((m_reg_A ^ 0x8000) >> tmp) - (0x8000 >> tmp); - break; - - case 0xf900: - // ABR - tmp = (opcode & 0xf) + 1; - m_icount -= (9 + tmp); - tmp = tmp > 15 ? 15 : tmp; - m_reg_B = ((m_reg_B ^ 0x8000) >> tmp) - (0x8000 >> tmp); - break; - - case 0xf140: - // SAR - tmp = (opcode & 0xf) + 1; - m_icount -= (9 + tmp); - m_reg_A >>= tmp; - break; - - case 0xf940: - // SBR - tmp = (opcode & 0xf) + 1; - m_icount -= (9 + tmp); - m_reg_B >>= tmp; - break; - - case 0xf180: - // SAL - tmp = (opcode & 0xf) + 1; - m_icount -= (9 + tmp); - m_reg_A <<= tmp; - break; - - case 0xf980: - // SBL - tmp = (opcode & 0xf) + 1; - m_icount -= (9 + tmp); - m_reg_B <<= tmp; - break; - - case 0xf1c0: - // RAR - tmp = (opcode & 0xf) + 1; - m_icount -= (9 + tmp); - m_reg_A = (m_reg_A >> tmp) | (m_reg_A << (16 - tmp)); - break; - - case 0xf9c0: - // RBR - tmp = (opcode & 0xf) + 1; - m_icount -= (9 + tmp); - m_reg_B = (m_reg_B >> tmp) | (m_reg_B << (16 - tmp)); - break; - - default: - if ((opcode & 0xf760) == 0x7160) { - // Place/withdraw instructions - m_icount -= 23; - do_pw(opcode); - } else if ((opcode & 0xff80) == 0xf080) { - // RET - m_icount -= 16; - if (BIT(opcode , 6)) { - // Pop PA stack - if (BIT(m_flags , HPHYBRID_IRH_SVC_BIT)) { - BIT_CLR(m_flags , HPHYBRID_IRH_SVC_BIT); - memmove(&m_reg_PA[ 0 ] , &m_reg_PA[ 1 ] , HPHYBRID_INT_LVLS); - m_pa_changed_func((uint8_t)CURRENT_PA); - } else if (BIT(m_flags , HPHYBRID_IRL_SVC_BIT)) { - BIT_CLR(m_flags , HPHYBRID_IRL_SVC_BIT); - memmove(&m_reg_PA[ 0 ] , &m_reg_PA[ 1 ] , HPHYBRID_INT_LVLS); - m_pa_changed_func((uint8_t)CURRENT_PA); - } - tmp = RM(AEC_CASE_C , m_reg_R--) + (opcode & 0x1f); - BIT_CLR(m_flags, HPHYBRID_IM_BIT); - } else { - tmp = RM(AEC_CASE_C , m_reg_R--) + (opcode & 0x1f); - } - return BIT(opcode , 5) ? tmp - 0x20 : tmp; - } else { - switch (opcode) { - case 0x7100: - // SDO - m_icount -= 12; - BIT_SET(m_flags , HPHYBRID_DMADIR_BIT); - break; - - case 0x7108: - // SDI - m_icount -= 12; - BIT_CLR(m_flags , HPHYBRID_DMADIR_BIT); - break; - - case 0x7110: - // EIR - m_icount -= 12; - BIT_SET(m_flags , HPHYBRID_INTEN_BIT); - break; - - case 0x7118: - // DIR - m_icount -= 12; - BIT_CLR(m_flags , HPHYBRID_INTEN_BIT); - break; - - case 0x7120: - // DMA - m_icount -= 12; - BIT_SET(m_flags , HPHYBRID_DMAEN_BIT); - break; - - case 0x7138: - // DDR - m_icount -= 12; - BIT_CLR(m_flags , HPHYBRID_DMAEN_BIT); - break; - - case 0x7140: - // DBL - m_icount -= 12; - BIT_CLR(m_flags , HPHYBRID_DB_BIT); - break; - - case 0x7148: - // CBL - m_icount -= 12; - BIT_CLR(m_flags , HPHYBRID_CB_BIT); - break; - - case 0x7150: - // DBU - m_icount -= 12; - BIT_SET(m_flags , HPHYBRID_DB_BIT); - break; - - case 0x7158: - // CBU - m_icount -= 12; - BIT_SET(m_flags , HPHYBRID_CB_BIT); - break; - - case 0xf020: - // TCA - m_icount -= 9; - m_reg_A = ~m_reg_A; - do_add(m_reg_A , 1); - break; - - case 0xf060: - // CMA - m_icount -= 9; - m_reg_A = ~m_reg_A; - break; - - case 0xf820: - // TCB - m_icount -= 9; - m_reg_B = ~m_reg_B; - do_add(m_reg_B , 1); - break; - - case 0xf860: - // CMB - m_icount -= 9; - m_reg_B = ~m_reg_B; - break; - - default: - // Unrecognized instruction: pass it on for further processing (by EMC if present) - return execute_no_bpc_ioc(opcode); - } - } - } - } - } - } - - return m_reg_P + 1; + if ((opcode & 0xf760) == 0x7160) { + // Place/withdraw instructions + m_icount -= 23; + do_pw(opcode); + } else if ((opcode & 0xff80) == 0xf080) { + // RET + m_icount -= 16; + if (BIT(opcode , 6)) { + // Pop PA stack + if (BIT(m_flags , HPHYBRID_IRH_SVC_BIT)) { + BIT_CLR(m_flags , HPHYBRID_IRH_SVC_BIT); + memmove(&m_reg_PA[ 0 ] , &m_reg_PA[ 1 ] , HPHYBRID_INT_LVLS); + m_pa_changed_func((uint8_t)CURRENT_PA); + } else if (BIT(m_flags , HPHYBRID_IRL_SVC_BIT)) { + BIT_CLR(m_flags , HPHYBRID_IRL_SVC_BIT); + memmove(&m_reg_PA[ 0 ] , &m_reg_PA[ 1 ] , HPHYBRID_INT_LVLS); + m_pa_changed_func((uint8_t)CURRENT_PA); + } + tmp = RM(AEC_CASE_C , m_reg_R--) + (opcode & 0x1f); + BIT_CLR(m_flags, HPHYBRID_IM_BIT); + } else { + tmp = RM(AEC_CASE_C , m_reg_R--) + (opcode & 0x1f); + } + return BIT(opcode , 5) ? tmp - 0x20 : tmp; + } else { + switch (opcode) { + case 0x7100: + // SDO + m_icount -= 12; + BIT_SET(m_flags , HPHYBRID_DMADIR_BIT); + break; + + case 0x7108: + // SDI + m_icount -= 12; + BIT_CLR(m_flags , HPHYBRID_DMADIR_BIT); + break; + + case 0x7110: + // EIR + m_icount -= 12; + BIT_SET(m_flags , HPHYBRID_INTEN_BIT); + break; + + case 0x7118: + // DIR + m_icount -= 12; + BIT_CLR(m_flags , HPHYBRID_INTEN_BIT); + break; + + case 0x7120: + // DMA + m_icount -= 12; + BIT_SET(m_flags , HPHYBRID_DMAEN_BIT); + break; + + case 0x7138: + // DDR + m_icount -= 12; + BIT_CLR(m_flags , HPHYBRID_DMAEN_BIT); + break; + + case 0x7140: + // DBL + m_icount -= 12; + BIT_CLR(m_flags , HPHYBRID_DB_BIT); + break; + + case 0x7148: + // CBL + m_icount -= 12; + BIT_CLR(m_flags , HPHYBRID_CB_BIT); + break; + + case 0x7150: + // DBU + m_icount -= 12; + BIT_SET(m_flags , HPHYBRID_DB_BIT); + break; + + case 0x7158: + // CBU + m_icount -= 12; + BIT_SET(m_flags , HPHYBRID_CB_BIT); + break; + + case 0xf020: + // TCA + m_icount -= 9; + m_reg_A = ~m_reg_A; + do_add(m_reg_A , 1); + break; + + case 0xf060: + // CMA + m_icount -= 9; + m_reg_A = ~m_reg_A; + break; + + case 0xf820: + // TCB + m_icount -= 9; + m_reg_B = ~m_reg_B; + do_add(m_reg_B , 1); + break; + + case 0xf860: + // CMB + m_icount -= 9; + m_reg_B = ~m_reg_B; + break; + + default: + // Unrecognized instruction: pass it on for further processing (by EMC if present) + return execute_no_bpc_ioc(opcode); + } + } + } + } + } + } + + return m_reg_P + 1; } void hp_hybrid_cpu_device::state_string_export(const device_state_entry &entry, std::string &str) const { if (entry.index() == STATE_GENFLAGS) { str = string_format("%s %s %c %c", - BIT(m_flags , HPHYBRID_DB_BIT) ? "Db":"..", - BIT(m_flags , HPHYBRID_CB_BIT) ? "Cb":"..", - BIT(m_flags , HPHYBRID_O_BIT) ? 'O':'.', - BIT(m_flags , HPHYBRID_C_BIT) ? 'E':'.'); + BIT(m_flags , HPHYBRID_DB_BIT) ? "Db":"..", + BIT(m_flags , HPHYBRID_CB_BIT) ? "Cb":"..", + BIT(m_flags , HPHYBRID_O_BIT) ? 'O':'.', + BIT(m_flags , HPHYBRID_C_BIT) ? 'E':'.'); } } -offs_t hp_hybrid_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *hp_hybrid_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE(hp_hybrid); - return CPU_DISASSEMBLE_NAME(hp_hybrid)(this, stream, pc, oprom, opram, options); + return new hp_hybrid_disassembler; } uint16_t hp_hybrid_cpu_device::remove_mae(uint32_t addr) { - return (uint16_t)(addr & 0xffff); + return (uint16_t)(addr & 0xffff); } uint16_t hp_hybrid_cpu_device::RM(aec_cases_t aec_case , uint16_t addr) { - return RM(add_mae(aec_case , addr)); + return RM(add_mae(aec_case , addr)); } uint16_t hp_hybrid_cpu_device::RM(uint32_t addr) { - uint16_t tmp; - uint16_t addr_wo_bsc = remove_mae(addr); + uint16_t tmp; + uint16_t addr_wo_bsc = remove_mae(addr); - if (addr_wo_bsc <= HP_REG_LAST_ADDR) { - // Any access to internal registers removes forcing of BSC 2x - m_forced_bsc_25 = false; + if (addr_wo_bsc <= HP_REG_LAST_ADDR) { + // Any access to internal registers removes forcing of BSC 2x + m_forced_bsc_25 = false; - // Memory mapped registers that are present in both 3001 & 3011 - switch (addr_wo_bsc) { - case HP_REG_A_ADDR: - return m_reg_A; + // Memory mapped registers that are present in both 3001 & 3011 + switch (addr_wo_bsc) { + case HP_REG_A_ADDR: + return m_reg_A; - case HP_REG_B_ADDR: - return m_reg_B; + case HP_REG_B_ADDR: + return m_reg_B; - case HP_REG_P_ADDR: - return m_reg_P; + case HP_REG_P_ADDR: + return m_reg_P; - case HP_REG_R_ADDR: - return m_reg_R; + case HP_REG_R_ADDR: + return m_reg_R; - case HP_REG_R4_ADDR: - case HP_REG_R5_ADDR: - case HP_REG_R6_ADDR: - case HP_REG_R7_ADDR: - return RIO(CURRENT_PA , addr_wo_bsc - HP_REG_R4_ADDR); + case HP_REG_R4_ADDR: + case HP_REG_R5_ADDR: + case HP_REG_R6_ADDR: + case HP_REG_R7_ADDR: + return RIO(CURRENT_PA , addr_wo_bsc - HP_REG_R4_ADDR); - case HP_REG_IV_ADDR: - return m_reg_IV; + case HP_REG_IV_ADDR: + return m_reg_IV; - case HP_REG_PA_ADDR: - return CURRENT_PA; + case HP_REG_PA_ADDR: + return CURRENT_PA; - case HP_REG_W_ADDR: - return m_reg_W; + case HP_REG_W_ADDR: + return m_reg_W; - case HP_REG_DMAPA_ADDR: - tmp = m_dmapa & HP_REG_PA_MASK; - if (BIT(m_flags , HPHYBRID_CB_BIT)) { - BIT_SET(tmp , 15); - } - if (BIT(m_flags , HPHYBRID_DB_BIT)) { - BIT_SET(tmp , 14); - } - return tmp; + case HP_REG_DMAPA_ADDR: + tmp = m_dmapa & HP_REG_PA_MASK; + if (BIT(m_flags , HPHYBRID_CB_BIT)) { + BIT_SET(tmp , 15); + } + if (BIT(m_flags , HPHYBRID_DB_BIT)) { + BIT_SET(tmp , 14); + } + return tmp; - case HP_REG_DMAMA_ADDR: - return m_dmama; + case HP_REG_DMAMA_ADDR: + return m_dmama; - case HP_REG_DMAC_ADDR: - return m_dmac; + case HP_REG_DMAC_ADDR: + return m_dmac; - case HP_REG_C_ADDR: - return m_reg_C; + case HP_REG_C_ADDR: + return m_reg_C; - case HP_REG_D_ADDR: - return m_reg_D; + case HP_REG_D_ADDR: + return m_reg_D; - default: - return read_non_common_reg(addr_wo_bsc); - } - } else { - return m_direct->read_word(addr << 1); + default: + return read_non_common_reg(addr_wo_bsc); } + } else { + return m_direct->read_word(addr << 1); + } } void hp_hybrid_cpu_device::WM(aec_cases_t aec_case , uint16_t addr , uint16_t v) { - WM(add_mae(aec_case , addr) , v); + WM(add_mae(aec_case , addr) , v); } void hp_hybrid_cpu_device::WM(uint32_t addr , uint16_t v) { - uint16_t addr_wo_bsc = remove_mae(addr); - - if (addr_wo_bsc <= HP_REG_LAST_ADDR) { - // Any access to internal registers removes forcing of BSC 2x - m_forced_bsc_25 = false; - - // Memory mapped registers - switch (addr_wo_bsc) { - case HP_REG_A_ADDR: - m_reg_A = v; - break; - - case HP_REG_B_ADDR: - m_reg_B = v; - break; - - case HP_REG_P_ADDR: - m_reg_P = v; - break; - - case HP_REG_R_ADDR: - m_reg_R = v; - break; - - case HP_REG_R4_ADDR: - case HP_REG_R5_ADDR: - case HP_REG_R6_ADDR: - case HP_REG_R7_ADDR: - WIO(CURRENT_PA , addr_wo_bsc - HP_REG_R4_ADDR , v); - break; - - case HP_REG_IV_ADDR: - m_reg_IV = v & HP_REG_IV_MASK; - break; - - case HP_REG_PA_ADDR: - CURRENT_PA = v & HP_REG_PA_MASK; - m_pa_changed_func((uint8_t)CURRENT_PA); - break; - - case HP_REG_W_ADDR: - m_reg_W = v; - break; - - case HP_REG_DMAPA_ADDR: - m_dmapa = v & HP_REG_PA_MASK; - break; - - case HP_REG_DMAMA_ADDR: - m_dmama = v; - break; - - case HP_REG_DMAC_ADDR: - m_dmac = v; - break; - - case HP_REG_C_ADDR: - m_reg_C = v; - break; - - case HP_REG_D_ADDR: - m_reg_D = v; - break; + uint16_t addr_wo_bsc = remove_mae(addr); - default: - write_non_common_reg(addr_wo_bsc , v); - break; - } - } else { - m_program->write_word(addr << 1 , v); + if (addr_wo_bsc <= HP_REG_LAST_ADDR) { + // Any access to internal registers removes forcing of BSC 2x + m_forced_bsc_25 = false; + + // Memory mapped registers + switch (addr_wo_bsc) { + case HP_REG_A_ADDR: + m_reg_A = v; + break; + + case HP_REG_B_ADDR: + m_reg_B = v; + break; + + case HP_REG_P_ADDR: + m_reg_P = v; + break; + + case HP_REG_R_ADDR: + m_reg_R = v; + break; + + case HP_REG_R4_ADDR: + case HP_REG_R5_ADDR: + case HP_REG_R6_ADDR: + case HP_REG_R7_ADDR: + WIO(CURRENT_PA , addr_wo_bsc - HP_REG_R4_ADDR , v); + break; + + case HP_REG_IV_ADDR: + m_reg_IV = v & HP_REG_IV_MASK; + break; + + case HP_REG_PA_ADDR: + CURRENT_PA = v & HP_REG_PA_MASK; + m_pa_changed_func((uint8_t)CURRENT_PA); + break; + + case HP_REG_W_ADDR: + m_reg_W = v; + break; + + case HP_REG_DMAPA_ADDR: + m_dmapa = v & HP_REG_PA_MASK; + break; + + case HP_REG_DMAMA_ADDR: + m_dmama = v; + break; + + case HP_REG_DMAC_ADDR: + m_dmac = v; + break; + + case HP_REG_C_ADDR: + m_reg_C = v; + break; + + case HP_REG_D_ADDR: + m_reg_D = v; + break; + + default: + write_non_common_reg(addr_wo_bsc , v); + break; } + } else { + m_program->write_word(addr , v); + } } uint16_t hp_hybrid_cpu_device::fetch(void) { - m_genpc = add_mae(AEC_CASE_A , m_reg_P); - return RM(m_genpc); + m_genpc = add_mae(AEC_CASE_A , m_reg_P); + return RM(m_genpc); } uint32_t hp_hybrid_cpu_device::get_ea(uint16_t opcode) { - uint16_t base; - uint16_t off; - aec_cases_t aec; - - if (BIT(opcode , 10)) { - // Current page - base = m_reg_P; - aec = AEC_CASE_A; - } else { - // Base page - base = 0; - aec = AEC_CASE_B; - } + uint16_t base; + uint16_t off; + aec_cases_t aec; + + if (BIT(opcode , 10)) { + // Current page + base = m_reg_P; + aec = AEC_CASE_A; + } else { + // Base page + base = 0; + aec = AEC_CASE_B; + } - off = opcode & 0x3ff; - if (off & 0x200) { - off -= 0x400; - } + off = opcode & 0x3ff; + if (off & 0x200) { + off -= 0x400; + } - base += off; + base += off; - if (BIT(opcode , 15)) { - // Indirect addressing - m_icount -= 6; - return add_mae(AEC_CASE_C , RM(aec , base)); - } else { - // Direct addressing - return add_mae(aec , base); - } + if (BIT(opcode , 15)) { + // Indirect addressing + m_icount -= 6; + return add_mae(AEC_CASE_C , RM(aec , base)); + } else { + // Direct addressing + return add_mae(aec , base); + } } void hp_hybrid_cpu_device::do_add(uint16_t& addend1 , uint16_t addend2) { - uint32_t tmp = addend1 + addend2; + uint32_t tmp = addend1 + addend2; - if (BIT(tmp , 16)) { - // Carry - BIT_SET(m_flags , HPHYBRID_C_BIT); - } + if (BIT(tmp , 16)) { + // Carry + BIT_SET(m_flags , HPHYBRID_C_BIT); + } - if (BIT((tmp ^ addend1) & (tmp ^ addend2) , 15)) { - // Overflow - BIT_SET(m_flags , HPHYBRID_O_BIT); - } + if (BIT((tmp ^ addend1) & (tmp ^ addend2) , 15)) { + // Overflow + BIT_SET(m_flags , HPHYBRID_O_BIT); + } - addend1 = (uint16_t)tmp; + addend1 = (uint16_t)tmp; } uint16_t hp_hybrid_cpu_device::get_skip_addr(uint16_t opcode , bool condition) const { - bool skip_val = BIT(opcode , 8) != 0; + bool skip_val = BIT(opcode , 8) != 0; - if (condition == skip_val) { - uint16_t off = opcode & 0x1f; + if (condition == skip_val) { + uint16_t off = opcode & 0x1f; - if (BIT(opcode , 5)) { - off -= 0x20; - } - return m_reg_P + off; - } else { - return m_reg_P + 1; - } + if (BIT(opcode , 5)) { + off -= 0x20; + } + return m_reg_P + off; + } else { + return m_reg_P + 1; + } } uint16_t hp_hybrid_cpu_device::get_skip_addr_sc(uint16_t opcode , uint16_t& v , unsigned n) { - bool val = BIT(v , n); - - if (BIT(opcode , 7)) { - if (BIT(opcode , 6)) { - BIT_SET(v , n); - } else { - BIT_CLR(v , n); - } - } + bool val = BIT(v , n); - return get_skip_addr(opcode , val); + if (BIT(opcode , 7)) { + if (BIT(opcode , 6)) { + BIT_SET(v , n); + } else { + BIT_CLR(v , n); + } + } + + return get_skip_addr(opcode , val); } uint16_t hp_hybrid_cpu_device::get_skip_addr_sc(uint16_t opcode , uint32_t& v , unsigned n) { - bool val = BIT(v , n); + bool val = BIT(v , n); - if (BIT(opcode , 7)) { - if (BIT(opcode , 6)) { - BIT_SET(v , n); - } else { - BIT_CLR(v , n); - } + if (BIT(opcode , 7)) { + if (BIT(opcode , 6)) { + BIT_SET(v , n); + } else { + BIT_CLR(v , n); } + } - return get_skip_addr(opcode , val); + return get_skip_addr(opcode , val); } void hp_hybrid_cpu_device::do_pw(uint16_t opcode) { - uint16_t tmp; - uint16_t reg_addr = opcode & 7; - uint16_t *ptr_reg; - uint16_t b_mask; - - if (BIT(opcode , 3)) { - ptr_reg = &m_reg_D; - b_mask = BIT_MASK(HPHYBRID_DB_BIT); - } else { - ptr_reg = &m_reg_C; - b_mask = BIT_MASK(HPHYBRID_CB_BIT); - } + uint16_t tmp; + uint16_t reg_addr = opcode & 7; + uint16_t *ptr_reg; + uint16_t b_mask; - if (BIT(opcode , 4)) { - // Withdraw - if (BIT(opcode , 11)) { - // Byte - uint32_t tmp_addr = (uint32_t)(*ptr_reg); - if (m_flags & b_mask) { - tmp_addr |= 0x10000; - } - tmp = RM(AEC_CASE_C , (uint16_t)(tmp_addr >> 1)); - if (BIT(tmp_addr , 0)) { - tmp &= 0xff; - } else { - tmp >>= 8; - } - } else { - // Word - tmp = RM(AEC_CASE_C , *ptr_reg); - } - WM(reg_addr , tmp); - - if (BIT(opcode , 7)) { - // Post-decrement - if ((*ptr_reg)-- == 0) { - m_flags ^= b_mask; - } - } else { - // Post-increment - if (++(*ptr_reg) == 0) { - m_flags ^= b_mask; - } - } + if (BIT(opcode , 3)) { + ptr_reg = &m_reg_D; + b_mask = BIT_MASK(HPHYBRID_DB_BIT); + } else { + ptr_reg = &m_reg_C; + b_mask = BIT_MASK(HPHYBRID_CB_BIT); + } + + if (BIT(opcode , 4)) { + // Withdraw + if (BIT(opcode , 11)) { + // Byte + uint32_t tmp_addr = (uint32_t)(*ptr_reg); + if (m_flags & b_mask) { + tmp_addr |= 0x10000; + } + tmp = RM(AEC_CASE_C , (uint16_t)(tmp_addr >> 1)); + if (BIT(tmp_addr , 0)) { + tmp &= 0xff; + } else { + tmp >>= 8; + } + } else { + // Word + tmp = RM(AEC_CASE_C , *ptr_reg); + } + WM(reg_addr , tmp); + + if (BIT(opcode , 7)) { + // Post-decrement + if ((*ptr_reg)-- == 0) { + m_flags ^= b_mask; + } + } else { + // Post-increment + if (++(*ptr_reg) == 0) { + m_flags ^= b_mask; + } + } + } else { + // Place + if (BIT(opcode , 7)) { + // Pre-decrement + if ((*ptr_reg)-- == 0) { + m_flags ^= b_mask; + } + } else { + // Pre-increment + if (++(*ptr_reg) == 0) { + m_flags ^= b_mask; + } + } + tmp = RM(reg_addr); + if (BIT(opcode , 11)) { + // Byte + uint32_t tmp_addr = (uint32_t)(*ptr_reg); + if (m_flags & b_mask) { + tmp_addr |= 0x10000; + } + if (tmp_addr <= (HP_REG_LAST_ADDR * 2 + 1)) { + // Single bytes can be written to registers. + // The addressed register gets the written byte in the proper position + // and a 0 in the other byte because access to registers is always done in + // 16 bits units. + if (BIT(tmp_addr , 0)) { + tmp &= 0xff; } else { - // Place - if (BIT(opcode , 7)) { - // Pre-decrement - if ((*ptr_reg)-- == 0) { - m_flags ^= b_mask; - } - } else { - // Pre-increment - if (++(*ptr_reg) == 0) { - m_flags ^= b_mask; - } - } - tmp = RM(reg_addr); - if (BIT(opcode , 11)) { - // Byte - uint32_t tmp_addr = (uint32_t)(*ptr_reg); - if (m_flags & b_mask) { - tmp_addr |= 0x10000; - } - if (tmp_addr <= (HP_REG_LAST_ADDR * 2 + 1)) { - // Single bytes can be written to registers. - // The addressed register gets the written byte in the proper position - // and a 0 in the other byte because access to registers is always done in - // 16 bits units. - if (BIT(tmp_addr , 0)) { - tmp &= 0xff; - } else { - tmp <<= 8; - } - WM(tmp_addr >> 1 , tmp); - } else { - // Extend address, preserve LSB & form byte address - tmp_addr = (add_mae(AEC_CASE_C , tmp_addr >> 1) << 1) | (tmp_addr & 1); - m_program->write_byte(tmp_addr , (uint8_t)tmp); - } - } else { - // Word - WM(AEC_CASE_C , *ptr_reg , tmp); - } + tmp <<= 8; } + WM(tmp_addr >> 1 , tmp); + } else { + // Extend address, form byte address + uint16_t val = (tmp_addr & 1) ? uint8_t(tmp) << 8 : uint8_t(tmp); + uint16_t mask = (tmp_addr & 1) ? 0xff00 : 0x00ff; + tmp_addr = add_mae(AEC_CASE_C , tmp_addr >> 1); + m_program->write_word(tmp_addr , val, mask); + } + } else { + // Word + WM(AEC_CASE_C , *ptr_reg , tmp); + } + } } void hp_hybrid_cpu_device::check_for_interrupts(void) { - if (!BIT(m_flags , HPHYBRID_INTEN_BIT) || BIT(m_flags , HPHYBRID_IRH_SVC_BIT) || BIT(m_flags , HPHYBRID_IM_BIT)) { - return; - } + if (!BIT(m_flags , HPHYBRID_INTEN_BIT) || BIT(m_flags , HPHYBRID_IRH_SVC_BIT) || BIT(m_flags , HPHYBRID_IM_BIT)) { + return; + } - int irqline; - - if (BIT(m_flags , HPHYBRID_IRH_BIT)) { - // Service high-level interrupt - BIT_SET(m_flags , HPHYBRID_IRH_SVC_BIT); - irqline = HPHYBRID_IRH; - if (BIT(m_flags , HPHYBRID_IRL_SVC_BIT)) { - logerror("H pre-empted L @ %06x\n" , m_genpc); - } - } else if (BIT(m_flags , HPHYBRID_IRL_BIT) && !BIT(m_flags , HPHYBRID_IRL_SVC_BIT)) { - // Service low-level interrupt - BIT_SET(m_flags , HPHYBRID_IRL_SVC_BIT); - irqline = HPHYBRID_IRL; - } else { - return; - } + int irqline; - // Get interrupt vector in low byte - uint8_t vector = (uint8_t)standard_irq_callback(irqline); - uint8_t new_PA; + if (BIT(m_flags , HPHYBRID_IRH_BIT)) { + // Service high-level interrupt + BIT_SET(m_flags , HPHYBRID_IRH_SVC_BIT); + irqline = HPHYBRID_IRH; + if (BIT(m_flags , HPHYBRID_IRL_SVC_BIT)) { + logerror("H pre-empted L @ %06x\n" , m_genpc); + } + } else if (BIT(m_flags , HPHYBRID_IRL_BIT) && !BIT(m_flags , HPHYBRID_IRL_SVC_BIT)) { + // Service low-level interrupt + BIT_SET(m_flags , HPHYBRID_IRL_SVC_BIT); + irqline = HPHYBRID_IRL; + } else { + return; + } - // Get highest numbered 1 - // Don't know what happens if vector is 0, here we assume bit 7 = 1 - if (vector == 0) { - new_PA = 7; - } else { - for (new_PA = 7; new_PA && !BIT(vector , 7); new_PA--, vector <<= 1) { - } - } - if (irqline == HPHYBRID_IRH) { - BIT_SET(new_PA , 3); - } + // Get interrupt vector in low byte + uint8_t vector = (uint8_t)standard_irq_callback(irqline); + uint8_t new_PA; - // Push PA stack - memmove(&m_reg_PA[ 1 ] , &m_reg_PA[ 0 ] , HPHYBRID_INT_LVLS); + // Get highest numbered 1 + // Don't know what happens if vector is 0, here we assume bit 7 = 1 + if (vector == 0) { + new_PA = 7; + } else { + for (new_PA = 7; new_PA && !BIT(vector , 7); new_PA--, vector <<= 1) { + } + } + if (irqline == HPHYBRID_IRH) { + BIT_SET(new_PA , 3); + } - CURRENT_PA = new_PA; + // Push PA stack + memmove(&m_reg_PA[ 1 ] , &m_reg_PA[ 0 ] , HPHYBRID_INT_LVLS); - m_pa_changed_func((uint8_t)CURRENT_PA); + CURRENT_PA = new_PA; + + m_pa_changed_func((uint8_t)CURRENT_PA); - // Is this correct? Patent @ pg 210 suggests that the whole interrupt recognition sequence - // lasts for 32 cycles - m_icount -= 32; + // Is this correct? Patent @ pg 210 suggests that the whole interrupt recognition sequence + // lasts for 32 cycles + m_icount -= 32; - // Allow special processing in 5061-3001 - enter_isr(); + // Allow special processing in 5061-3001 + enter_isr(); - // Do a double-indirect JSM IV,I instruction - WM(AEC_CASE_C , ++m_reg_R , m_reg_P); - m_reg_P = RM(AEC_CASE_C , m_reg_IV + CURRENT_PA); - m_reg_I = fetch(); + // Do a double-indirect JSM IV,I instruction + WM(AEC_CASE_C , ++m_reg_R , m_reg_P); + m_reg_P = RM(AEC_CASE_C , m_reg_IV + CURRENT_PA); + m_reg_I = fetch(); } void hp_hybrid_cpu_device::enter_isr(void) { - // Do nothing special + // Do nothing special } void hp_hybrid_cpu_device::handle_dma(void) @@ -1108,7 +1110,7 @@ void hp_hybrid_cpu_device::handle_dma(void) if (BIT(m_flags , HPHYBRID_DMADIR_BIT)) { // "Outward" DMA: memory -> peripheral - tmp = RM(AEC_CASE_D , m_dmama++); + tmp = RM(AEC_CASE_D , m_dmama++); WIO(m_dmapa , tc ? 2 : 0 , tmp); m_icount -= 10; } else { @@ -1397,16 +1399,16 @@ uint16_t hp_5061_3001_cpu_device::execute_no_bpc_ioc(uint16_t opcode) break; case 0x7280: - // FXA - m_icount -= 40; - tmp_ar2 = get_ar2(); - carry = do_dec_add(BIT(m_flags , HPHYBRID_DC_BIT) , tmp_ar2 , get_ar1()); - set_ar2(tmp_ar2); - if (carry) - BIT_SET(m_flags, HPHYBRID_DC_BIT); - else - BIT_CLR(m_flags, HPHYBRID_DC_BIT); - break; + // FXA + m_icount -= 40; + tmp_ar2 = get_ar2(); + carry = do_dec_add(BIT(m_flags , HPHYBRID_DC_BIT) , tmp_ar2 , get_ar1()); + set_ar2(tmp_ar2); + if (carry) + BIT_SET(m_flags, HPHYBRID_DC_BIT); + else + BIT_CLR(m_flags, HPHYBRID_DC_BIT); + break; case 0x7340: // NRM @@ -1539,10 +1541,9 @@ uint16_t hp_5061_3001_cpu_device::execute_no_bpc_ioc(uint16_t opcode) return m_reg_P + 1; } -offs_t hp_5061_3001_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *hp_5061_3001_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE(hp_5061_3001); - return CPU_DISASSEMBLE_NAME(hp_5061_3001)(this, stream, pc, oprom, opram, options); + return new hp_5061_3001_disassembler; } uint32_t hp_5061_3001_cpu_device::add_mae(aec_cases_t aec_case , uint16_t addr) @@ -1599,7 +1600,7 @@ uint32_t hp_5061_3001_cpu_device::add_mae(aec_cases_t aec_case , uint16_t addr) case AEC_CASE_D: bsc_reg = top_half ? m_reg_aec[ HP_REG_R32_ADDR - HP_REG_R32_ADDR ] : m_reg_aec[ HP_REG_R37_ADDR - HP_REG_R32_ADDR ]; - break; + break; default: logerror("hphybrid: aec_case=%d\n" , aec_case); diff --git a/src/devices/cpu/hphybrid/hphybrid.h b/src/devices/cpu/hphybrid/hphybrid.h index 5962942b64c..bd362d710ee 100644 --- a/src/devices/cpu/hphybrid/hphybrid.h +++ b/src/devices/cpu/hphybrid/hphybrid.h @@ -85,9 +85,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 2; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // Different cases of memory access // See patent @ pg 361 @@ -142,7 +140,7 @@ private: address_space_config m_io_config; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<-1> *m_direct; address_space *m_io; uint32_t get_ea(uint16_t opcode); @@ -181,7 +179,7 @@ protected: void do_mpy(); virtual uint16_t execute_no_bpc_ioc(uint16_t opcode) override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t add_mae(aec_cases_t aec_case, uint16_t addr) override; virtual uint16_t read_non_common_reg(uint16_t addr) override; virtual void write_non_common_reg(uint16_t addr , uint16_t v) override; diff --git a/src/devices/cpu/hphybrid/hphybrid_dasm.cpp b/src/devices/cpu/hphybrid/hphybrid_dasm.cpp index 58d800a3722..74d833803c0 100644 --- a/src/devices/cpu/hphybrid/hphybrid_dasm.cpp +++ b/src/devices/cpu/hphybrid/hphybrid_dasm.cpp @@ -5,23 +5,10 @@ // ******************************************************************************** #include "emu.h" -#include "hphybrid.h" -#include "debugger.h" - +#include "hphybrid_dasm.h" #include "hphybrid_defs.h" - -typedef void (*fn_dis_param)(std::ostream &stream , offs_t pc , uint16_t opcode , bool is_3001); - -typedef struct { - uint16_t m_op_mask; - uint16_t m_opcode; - const char *m_mnemonic; - fn_dis_param m_param_fn; - uint32_t m_dasm_flags; -} dis_entry_t; - -static void addr_2_str(std::ostream &stream, uint16_t addr , bool indirect , bool is_3001) +void hp_hybrid_disassembler::addr_2_str(std::ostream &stream, uint16_t addr , bool indirect , bool is_3001) { util::stream_format(stream, "$%04x" , addr); @@ -168,11 +155,11 @@ static void addr_2_str(std::ostream &stream, uint16_t addr , bool indirect , boo } } -static void param_none(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001) +void hp_hybrid_disassembler::param_none(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001) { } -static void param_loc(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001) +void hp_hybrid_disassembler::param_loc(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001) { uint16_t base; uint16_t off; @@ -193,12 +180,12 @@ static void param_loc(std::ostream &stream, offs_t pc , uint16_t opcode , bool i addr_2_str(stream, base + off , (opcode & 0x8000) != 0 , is_3001); } -static void param_addr32(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001) +void hp_hybrid_disassembler::param_addr32(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001) { addr_2_str(stream, opcode & 0x1f , (opcode & 0x8000) != 0 , is_3001); } -static void param_skip(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001) +void hp_hybrid_disassembler::param_skip(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001) { uint16_t off = opcode & 0x3f; if (off & 0x20) { @@ -207,7 +194,7 @@ static void param_skip(std::ostream &stream, offs_t pc , uint16_t opcode , bool addr_2_str(stream , pc + off , false , is_3001); } -static void param_skip_sc(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001) +void hp_hybrid_disassembler::param_skip_sc(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001) { param_skip(stream, pc, opcode , is_3001); @@ -220,7 +207,7 @@ static void param_skip_sc(std::ostream &stream, offs_t pc , uint16_t opcode , bo } } -static void param_ret(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001) +void hp_hybrid_disassembler::param_ret(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001) { int off = opcode & 0x3f; @@ -234,12 +221,12 @@ static void param_ret(std::ostream &stream, offs_t pc , uint16_t opcode , bool i } } -static void param_n16(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001) +void hp_hybrid_disassembler::param_n16(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001) { util::stream_format(stream , "%u" , (opcode & 0xf) + 1); } -static void param_reg_id(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001) +void hp_hybrid_disassembler::param_reg_id(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001) { addr_2_str(stream, opcode & 7, false , is_3001); @@ -250,133 +237,133 @@ static void param_reg_id(std::ostream &stream, offs_t pc , uint16_t opcode , boo } } -static const dis_entry_t dis_table[] = { +const hp_hybrid_disassembler::dis_entry_t hp_hybrid_disassembler::dis_table[] = { // *** BPC Instructions *** - {0xffff , 0x0000 , "NOP" , param_none , 0 }, - {0x7800 , 0x0000 , "LDA" , param_loc , 0 }, - {0x7800 , 0x0800 , "LDB" , param_loc , 0 }, - {0x7800 , 0x1000 , "CPA" , param_loc , 0 }, - {0x7800 , 0x1800 , "CPB" , param_loc , 0 }, - {0x7800 , 0x2000 , "ADA" , param_loc , 0 }, - {0x7800 , 0x2800 , "ADB" , param_loc , 0 }, - {0x7800 , 0x3000 , "STA" , param_loc , 0 }, - {0x7800 , 0x3800 , "STB" , param_loc , 0 }, - {0x7800 , 0x4000 , "JSM" , param_loc , DASMFLAG_STEP_OVER }, - {0x7800 , 0x4800 , "ISZ" , param_loc , 0 }, - {0x7800 , 0x5000 , "AND" , param_loc , 0 }, - {0x7800 , 0x5800 , "DSZ" , param_loc , 0 }, - {0x7800 , 0x6000 , "IOR" , param_loc , 0 }, - {0x7800 , 0x6800 , "JMP" , param_loc , 0 }, - {0x7fe0 , 0x7000 , "EXE" , param_addr32 , 0 }, - {0xffc0 , 0x7400 , "RZA" , param_skip , 0 }, - {0xffc0 , 0x7C00 , "RZB" , param_skip , 0 }, - {0xffc0 , 0x7440 , "RIA" , param_skip , 0 }, - {0xffc0 , 0x7C40 , "RIB" , param_skip , 0 }, - {0xffc0 , 0x7500 , "SZA" , param_skip , 0 }, - {0xffc0 , 0x7D00 , "SZB" , param_skip , 0 }, - {0xffc0 , 0x7540 , "SIA" , param_skip , 0 }, - {0xffc0 , 0x7D40 , "SIB" , param_skip , 0 }, - {0xffc0 , 0x7480 , "SFS" , param_skip , 0 }, - {0xffc0 , 0x7580 , "SFC" , param_skip , 0 }, - {0xffc0 , 0x7c80 , "SSS" , param_skip , 0 }, - {0xffc0 , 0x7d80 , "SSC" , param_skip , 0 }, - {0xffc0 , 0x7cc0 , "SHS" , param_skip , 0 }, - {0xffc0 , 0x7dc0 , "SHC" , param_skip , 0 }, - {0xff00 , 0x7600 , "SLA" , param_skip_sc , 0 }, - {0xff00 , 0x7e00 , "SLB" , param_skip_sc , 0 }, - {0xff00 , 0x7700 , "RLA" , param_skip_sc , 0 }, - {0xff00 , 0x7f00 , "RLB" , param_skip_sc , 0 }, - {0xff00 , 0xf400 , "SAP" , param_skip_sc , 0 }, - {0xff00 , 0xfc00 , "SBP" , param_skip_sc , 0 }, - {0xff00 , 0xf500 , "SAM" , param_skip_sc , 0 }, - {0xff00 , 0xfd00 , "SBM" , param_skip_sc , 0 }, - {0xff00 , 0xf600 , "SOC" , param_skip_sc , 0 }, - {0xff00 , 0xf700 , "SOS" , param_skip_sc , 0 }, - {0xff00 , 0xfe00 , "SEC" , param_skip_sc , 0 }, - {0xff00 , 0xff00 , "SES" , param_skip_sc , 0 }, - {0xffff , 0xf020 , "TCA" , param_none , 0 }, - {0xffff , 0xf820 , "TCB" , param_none , 0 }, - {0xffff , 0xf060 , "CMA" , param_none , 0 }, - {0xffff , 0xf860 , "CMB" , param_none , 0 }, - {0xff80 , 0xf080 , "RET" , param_ret , DASMFLAG_STEP_OUT }, - {0xfff0 , 0xf100 , "AAR" , param_n16 , 0 }, - {0xfff0 , 0xf900 , "ABR" , param_n16 , 0 }, - {0xffff , 0xf14f , "CLA" , param_none , 0 }, - {0xfff0 , 0xf140 , "SAR" , param_n16 , 0 }, - {0xffff , 0xf94f , "CLB" , param_none , 0 }, - {0xfff0 , 0xf940 , "SBR" , param_n16 , 0 }, - {0xfff0 , 0xf180 , "SAL" , param_n16 , 0 }, - {0xfff0 , 0xf980 , "SBL" , param_n16 , 0 }, - {0xfff0 , 0xf1c0 , "RAR" , param_n16 , 0 }, - {0xfff0 , 0xf9c0 , "RBR" , param_n16 , 0 }, + {0xffff , 0x0000 , "NOP" , &hp_hybrid_disassembler::param_none , 0 }, + {0x7800 , 0x0000 , "LDA" , &hp_hybrid_disassembler::param_loc , 0 }, + {0x7800 , 0x0800 , "LDB" , &hp_hybrid_disassembler::param_loc , 0 }, + {0x7800 , 0x1000 , "CPA" , &hp_hybrid_disassembler::param_loc , 0 }, + {0x7800 , 0x1800 , "CPB" , &hp_hybrid_disassembler::param_loc , 0 }, + {0x7800 , 0x2000 , "ADA" , &hp_hybrid_disassembler::param_loc , 0 }, + {0x7800 , 0x2800 , "ADB" , &hp_hybrid_disassembler::param_loc , 0 }, + {0x7800 , 0x3000 , "STA" , &hp_hybrid_disassembler::param_loc , 0 }, + {0x7800 , 0x3800 , "STB" , &hp_hybrid_disassembler::param_loc , 0 }, + {0x7800 , 0x4000 , "JSM" , &hp_hybrid_disassembler::param_loc , STEP_OVER }, + {0x7800 , 0x4800 , "ISZ" , &hp_hybrid_disassembler::param_loc , 0 }, + {0x7800 , 0x5000 , "AND" , &hp_hybrid_disassembler::param_loc , 0 }, + {0x7800 , 0x5800 , "DSZ" , &hp_hybrid_disassembler::param_loc , 0 }, + {0x7800 , 0x6000 , "IOR" , &hp_hybrid_disassembler::param_loc , 0 }, + {0x7800 , 0x6800 , "JMP" , &hp_hybrid_disassembler::param_loc , 0 }, + {0x7fe0 , 0x7000 , "EXE" , &hp_hybrid_disassembler::param_addr32 , 0 }, + {0xffc0 , 0x7400 , "RZA" , &hp_hybrid_disassembler::param_skip , 0 }, + {0xffc0 , 0x7C00 , "RZB" , &hp_hybrid_disassembler::param_skip , 0 }, + {0xffc0 , 0x7440 , "RIA" , &hp_hybrid_disassembler::param_skip , 0 }, + {0xffc0 , 0x7C40 , "RIB" , &hp_hybrid_disassembler::param_skip , 0 }, + {0xffc0 , 0x7500 , "SZA" , &hp_hybrid_disassembler::param_skip , 0 }, + {0xffc0 , 0x7D00 , "SZB" , &hp_hybrid_disassembler::param_skip , 0 }, + {0xffc0 , 0x7540 , "SIA" , &hp_hybrid_disassembler::param_skip , 0 }, + {0xffc0 , 0x7D40 , "SIB" , &hp_hybrid_disassembler::param_skip , 0 }, + {0xffc0 , 0x7480 , "SFS" , &hp_hybrid_disassembler::param_skip , 0 }, + {0xffc0 , 0x7580 , "SFC" , &hp_hybrid_disassembler::param_skip , 0 }, + {0xffc0 , 0x7c80 , "SSS" , &hp_hybrid_disassembler::param_skip , 0 }, + {0xffc0 , 0x7d80 , "SSC" , &hp_hybrid_disassembler::param_skip , 0 }, + {0xffc0 , 0x7cc0 , "SHS" , &hp_hybrid_disassembler::param_skip , 0 }, + {0xffc0 , 0x7dc0 , "SHC" , &hp_hybrid_disassembler::param_skip , 0 }, + {0xff00 , 0x7600 , "SLA" , &hp_hybrid_disassembler::param_skip_sc , 0 }, + {0xff00 , 0x7e00 , "SLB" , &hp_hybrid_disassembler::param_skip_sc , 0 }, + {0xff00 , 0x7700 , "RLA" , &hp_hybrid_disassembler::param_skip_sc , 0 }, + {0xff00 , 0x7f00 , "RLB" , &hp_hybrid_disassembler::param_skip_sc , 0 }, + {0xff00 , 0xf400 , "SAP" , &hp_hybrid_disassembler::param_skip_sc , 0 }, + {0xff00 , 0xfc00 , "SBP" , &hp_hybrid_disassembler::param_skip_sc , 0 }, + {0xff00 , 0xf500 , "SAM" , &hp_hybrid_disassembler::param_skip_sc , 0 }, + {0xff00 , 0xfd00 , "SBM" , &hp_hybrid_disassembler::param_skip_sc , 0 }, + {0xff00 , 0xf600 , "SOC" , &hp_hybrid_disassembler::param_skip_sc , 0 }, + {0xff00 , 0xf700 , "SOS" , &hp_hybrid_disassembler::param_skip_sc , 0 }, + {0xff00 , 0xfe00 , "SEC" , &hp_hybrid_disassembler::param_skip_sc , 0 }, + {0xff00 , 0xff00 , "SES" , &hp_hybrid_disassembler::param_skip_sc , 0 }, + {0xffff , 0xf020 , "TCA" , &hp_hybrid_disassembler::param_none , 0 }, + {0xffff , 0xf820 , "TCB" , &hp_hybrid_disassembler::param_none , 0 }, + {0xffff , 0xf060 , "CMA" , &hp_hybrid_disassembler::param_none , 0 }, + {0xffff , 0xf860 , "CMB" , &hp_hybrid_disassembler::param_none , 0 }, + {0xff80 , 0xf080 , "RET" , &hp_hybrid_disassembler::param_ret , STEP_OUT }, + {0xfff0 , 0xf100 , "AAR" , &hp_hybrid_disassembler::param_n16 , 0 }, + {0xfff0 , 0xf900 , "ABR" , &hp_hybrid_disassembler::param_n16 , 0 }, + {0xffff , 0xf14f , "CLA" , &hp_hybrid_disassembler::param_none , 0 }, + {0xfff0 , 0xf140 , "SAR" , &hp_hybrid_disassembler::param_n16 , 0 }, + {0xffff , 0xf94f , "CLB" , &hp_hybrid_disassembler::param_none , 0 }, + {0xfff0 , 0xf940 , "SBR" , &hp_hybrid_disassembler::param_n16 , 0 }, + {0xfff0 , 0xf180 , "SAL" , &hp_hybrid_disassembler::param_n16 , 0 }, + {0xfff0 , 0xf980 , "SBL" , &hp_hybrid_disassembler::param_n16 , 0 }, + {0xfff0 , 0xf1c0 , "RAR" , &hp_hybrid_disassembler::param_n16 , 0 }, + {0xfff0 , 0xf9c0 , "RBR" , &hp_hybrid_disassembler::param_n16 , 0 }, // *** IOC Instructions *** - {0xffff , 0x7100 , "SDO" , param_none , 0 }, - {0xffff , 0x7108 , "SDI" , param_none , 0 }, - {0xffff , 0x7110 , "EIR" , param_none , 0 }, - {0xffff , 0x7118 , "DIR" , param_none , 0 }, - {0xffff , 0x7120 , "DMA" , param_none , 0 }, - {0xffff , 0x7128 , "PCM" , param_none , 0 }, - {0xffff , 0x7138 , "DDR" , param_none , 0 }, - {0xffff , 0x7140 , "DBL" , param_none , 0 }, - {0xffff , 0x7148 , "CBL" , param_none , 0 }, - {0xffff , 0x7150 , "DBU" , param_none , 0 }, - {0xffff , 0x7158 , "CBU" , param_none , 0 }, - {0xff78 , 0x7160 , "PWC" , param_reg_id , 0 }, - {0xff78 , 0x7168 , "PWD" , param_reg_id , 0 }, - {0xff78 , 0x7960 , "PBC" , param_reg_id , 0 }, - {0xff78 , 0x7968 , "PBD" , param_reg_id , 0 }, - {0xff78 , 0x7170 , "WWC" , param_reg_id , 0 }, - {0xff78 , 0x7178 , "WWD" , param_reg_id , 0 }, - {0xff78 , 0x7970 , "WBC" , param_reg_id , 0 }, - {0xff78 , 0x7978 , "WBD" , param_reg_id , 0 }, + {0xffff , 0x7100 , "SDO" , &hp_hybrid_disassembler::param_none , 0 }, + {0xffff , 0x7108 , "SDI" , &hp_hybrid_disassembler::param_none , 0 }, + {0xffff , 0x7110 , "EIR" , &hp_hybrid_disassembler::param_none , 0 }, + {0xffff , 0x7118 , "DIR" , &hp_hybrid_disassembler::param_none , 0 }, + {0xffff , 0x7120 , "DMA" , &hp_hybrid_disassembler::param_none , 0 }, + {0xffff , 0x7128 , "PCM" , &hp_hybrid_disassembler::param_none , 0 }, + {0xffff , 0x7138 , "DDR" , &hp_hybrid_disassembler::param_none , 0 }, + {0xffff , 0x7140 , "DBL" , &hp_hybrid_disassembler::param_none , 0 }, + {0xffff , 0x7148 , "CBL" , &hp_hybrid_disassembler::param_none , 0 }, + {0xffff , 0x7150 , "DBU" , &hp_hybrid_disassembler::param_none , 0 }, + {0xffff , 0x7158 , "CBU" , &hp_hybrid_disassembler::param_none , 0 }, + {0xff78 , 0x7160 , "PWC" , &hp_hybrid_disassembler::param_reg_id , 0 }, + {0xff78 , 0x7168 , "PWD" , &hp_hybrid_disassembler::param_reg_id , 0 }, + {0xff78 , 0x7960 , "PBC" , &hp_hybrid_disassembler::param_reg_id , 0 }, + {0xff78 , 0x7968 , "PBD" , &hp_hybrid_disassembler::param_reg_id , 0 }, + {0xff78 , 0x7170 , "WWC" , &hp_hybrid_disassembler::param_reg_id , 0 }, + {0xff78 , 0x7178 , "WWD" , &hp_hybrid_disassembler::param_reg_id , 0 }, + {0xff78 , 0x7970 , "WBC" , &hp_hybrid_disassembler::param_reg_id , 0 }, + {0xff78 , 0x7978 , "WBD" , &hp_hybrid_disassembler::param_reg_id , 0 }, // *** END *** {0 , 0 , nullptr , nullptr , 0 } }; -static const dis_entry_t dis_table_emc[] = { +const hp_hybrid_disassembler::dis_entry_t hp_5061_3001_disassembler::dis_table_emc[] = { // *** EMC Instructions *** - {0xffff , 0x7200 , "MWA" , param_none , 0 }, - {0xffff , 0x7220 , "CMY" , param_none , 0 }, - {0xffff , 0x7260 , "CMX" , param_none , 0 }, - {0xffff , 0x7280 , "FXA" , param_none , 0 }, - {0xfff0 , 0x7300 , "XFR" , param_n16 , 0 }, - {0xffff , 0x7340 , "NRM" , param_none , 0 }, - {0xfff0 , 0x7380 , "CLR" , param_n16 , 0 }, - {0xffff , 0x73c0 , "CDC" , param_none , 0 }, - {0xffc0 , 0x74c0 , "SDS" , param_skip , 0 }, - {0xffc0 , 0x75c0 , "SDC" , param_skip , 0 }, - {0xffff , 0x7a00 , "FMP" , param_none , 0 }, - {0xffff , 0x7a21 , "FDV" , param_none , 0 }, - {0xffff , 0x7b00 , "MRX" , param_none , 0 }, - {0xffff , 0x7b21 , "DRS" , param_none , 0 }, - {0xffff , 0x7b40 , "MRY" , param_none , 0 }, - {0xffff , 0x7b61 , "MLY" , param_none , 0 }, - {0xffff , 0x7b8f , "MPY" , param_none , 0 }, + {0xffff , 0x7200 , "MWA" , &hp_5061_3001_disassembler::param_none , 0 }, + {0xffff , 0x7220 , "CMY" , &hp_5061_3001_disassembler::param_none , 0 }, + {0xffff , 0x7260 , "CMX" , &hp_5061_3001_disassembler::param_none , 0 }, + {0xffff , 0x7280 , "FXA" , &hp_5061_3001_disassembler::param_none , 0 }, + {0xfff0 , 0x7300 , "XFR" , &hp_5061_3001_disassembler::param_n16 , 0 }, + {0xffff , 0x7340 , "NRM" , &hp_5061_3001_disassembler::param_none , 0 }, + {0xfff0 , 0x7380 , "CLR" , &hp_5061_3001_disassembler::param_n16 , 0 }, + {0xffff , 0x73c0 , "CDC" , &hp_5061_3001_disassembler::param_none , 0 }, + {0xffc0 , 0x74c0 , "SDS" , &hp_5061_3001_disassembler::param_skip , 0 }, + {0xffc0 , 0x75c0 , "SDC" , &hp_5061_3001_disassembler::param_skip , 0 }, + {0xffff , 0x7a00 , "FMP" , &hp_5061_3001_disassembler::param_none , 0 }, + {0xffff , 0x7a21 , "FDV" , &hp_5061_3001_disassembler::param_none , 0 }, + {0xffff , 0x7b00 , "MRX" , &hp_5061_3001_disassembler::param_none , 0 }, + {0xffff , 0x7b21 , "DRS" , &hp_5061_3001_disassembler::param_none , 0 }, + {0xffff , 0x7b40 , "MRY" , &hp_5061_3001_disassembler::param_none , 0 }, + {0xffff , 0x7b61 , "MLY" , &hp_5061_3001_disassembler::param_none , 0 }, + {0xffff , 0x7b8f , "MPY" , &hp_5061_3001_disassembler::param_none , 0 }, // *** Undocumented instructions of 5061-3001 *** - {0xffff , 0x7026 , "CIM" , param_none , 0 }, - {0xffff , 0x7027 , "SIM" , param_none , 0 }, + {0xffff , 0x7026 , "CIM" , &hp_5061_3001_disassembler::param_none , 0 }, + {0xffff , 0x7027 , "SIM" , &hp_5061_3001_disassembler::param_none , 0 }, // *** END *** {0 , 0 , nullptr , nullptr , 0 } }; -static offs_t disassemble_table(uint16_t opcode , offs_t pc , const dis_entry_t *table , bool is_3001 , std::ostream &stream) +offs_t hp_hybrid_disassembler::disassemble_table(uint16_t opcode , offs_t pc , const dis_entry_t *table , bool is_3001 , std::ostream &stream) { const dis_entry_t *p; for (p = table; p->m_op_mask; p++) { if ((opcode & p->m_op_mask) == p->m_opcode) { stream << p->m_mnemonic << " "; - p->m_param_fn(stream , pc , opcode , is_3001); - return 1 | p->m_dasm_flags | DASMFLAG_SUPPORTED; + (this->*(p->m_param_fn))(stream , pc , opcode , is_3001); + return 1 | p->m_dasm_flags | SUPPORTED; } } return 0; } -CPU_DISASSEMBLE(hp_hybrid) +offs_t hp_hybrid_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - uint16_t opcode = ((uint16_t)oprom[ 0 ] << 8) | oprom[ 1 ]; + uint16_t opcode = opcodes.r16(pc); offs_t res; res = disassemble_table(opcode, pc, dis_table, false, stream); @@ -385,15 +372,15 @@ CPU_DISASSEMBLE(hp_hybrid) { // Unknown opcode stream << "???"; - res = 1 | DASMFLAG_SUPPORTED; + res = 1 | SUPPORTED; } return res; } -CPU_DISASSEMBLE(hp_5061_3001) +offs_t hp_5061_3001_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - uint16_t opcode = ((uint16_t)oprom[ 0 ] << 8) | oprom[ 1 ]; + uint16_t opcode = opcodes.r16(pc); offs_t res; res = disassemble_table(opcode, pc, dis_table_emc, true, stream); @@ -407,8 +394,13 @@ CPU_DISASSEMBLE(hp_5061_3001) { // Unknown opcode stream << "???"; - res = 1 | DASMFLAG_SUPPORTED; + res = 1 | SUPPORTED; } return res; } + +u32 hp_hybrid_disassembler::opcode_alignment() const +{ + return 1; +} diff --git a/src/devices/cpu/hphybrid/hphybrid_dasm.h b/src/devices/cpu/hphybrid/hphybrid_dasm.h new file mode 100644 index 00000000000..96994ae0632 --- /dev/null +++ b/src/devices/cpu/hphybrid/hphybrid_dasm.h @@ -0,0 +1,59 @@ +// license:BSD-3-Clause +// copyright-holders:F. Ulivi +// ******************************************************************************** +// * HP "hybrid" processor disassembler +// ******************************************************************************** + +#ifndef MAME_CPU_HPHYBRID_HPHYBRID_DASM_H +#define MAME_CPU_HPHYBRID_HPHYBRID_DASM_H + +#pragma once + +class hp_hybrid_disassembler : public util::disasm_interface +{ +public: + hp_hybrid_disassembler() = default; + virtual ~hp_hybrid_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +protected: + typedef void (hp_hybrid_disassembler::*fn_dis_param)(std::ostream &stream , offs_t pc , uint16_t opcode , bool is_3001); + + typedef struct { + uint16_t m_op_mask; + uint16_t m_opcode; + const char *m_mnemonic; + fn_dis_param m_param_fn; + uint32_t m_dasm_flags; + } dis_entry_t; + + static const dis_entry_t dis_table[]; + + void addr_2_str(std::ostream &stream, uint16_t addr , bool indirect , bool is_3001); + void param_none(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001); + void param_loc(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001); + void param_addr32(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001); + void param_skip(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001); + void param_skip_sc(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001); + void param_ret(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001); + void param_n16(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001); + void param_reg_id(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001); + + offs_t disassemble_table(uint16_t opcode , offs_t pc , const dis_entry_t *table , bool is_3001 , std::ostream &stream); +}; + +class hp_5061_3001_disassembler : public hp_hybrid_disassembler +{ +public: + hp_5061_3001_disassembler() = default; + virtual ~hp_5061_3001_disassembler() = default; + + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +protected: + static const dis_entry_t dis_table_emc[]; +}; + +#endif diff --git a/src/devices/cpu/i386/i386.cpp b/src/devices/cpu/i386/i386.cpp index 4b4b8286818..637af658c6e 100644 --- a/src/devices/cpu/i386/i386.cpp +++ b/src/devices/cpu/i386/i386.cpp @@ -2199,10 +2199,10 @@ void i386_device::i386_protected_mode_retf(uint8_t count, uint8_t operand32) FAULT(FAULT_SS,0) } } - if(operand32 == 0) - REG16(SP) += (4+count); + if(STACK_32BIT) + REG32(ESP) += (operand32 ? 8 : 4) + count; else - REG32(ESP) += (8+count); + REG16(SP) += (operand32 ? 8 : 4) + count; } else if(RPL > CPL) { @@ -3244,7 +3244,7 @@ void i386_device::i386_common_init() } m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); m_smi = false; m_debugger_temp = 0; @@ -4021,11 +4021,15 @@ bool i386_device::memory_translate(int spacenum, int intention, offs_t &address) return ret; } -offs_t i386_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +int i386_device::get_mode() const { - return i386_dasm_one(stream, pc, oprom, m_sreg[CS].d ? 32 : 16); + return m_sreg[CS].d ? 32 : 16; } +util::disasm_interface *i386_device::create_disassembler() +{ + return new i386_disassembler(this); +} /*****************************************************************************/ /* Intel 486 */ diff --git a/src/devices/cpu/i386/i386.h b/src/devices/cpu/i386/i386.h index 3701f6c6704..93c5df1c122 100644 --- a/src/devices/cpu/i386/i386.h +++ b/src/devices/cpu/i386/i386.h @@ -15,6 +15,7 @@ #include "debug/debugcpu.h" #include "divtlb.h" +#include "i386dasm.h" #define INPUT_LINE_A20 1 #define INPUT_LINE_SMI 2 @@ -29,7 +30,7 @@ #define X86_NUM_CPUS 4 -class i386_device : public cpu_device, public device_vtlb_interface +class i386_device : public cpu_device, public device_vtlb_interface, public i386_disassembler::config { public: // construction/destruction @@ -68,9 +69,8 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 15; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; + virtual int get_mode() const override; address_space_config m_program_config; address_space_config m_io_config; @@ -212,7 +212,7 @@ protected: uint8_t m_irq_state; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_io; uint32_t m_a20_mask; diff --git a/src/devices/cpu/i386/i386dasm.cpp b/src/devices/cpu/i386/i386dasm.cpp index 3c815612ffa..e201c4c02a4 100644 --- a/src/devices/cpu/i386/i386dasm.cpp +++ b/src/devices/cpu/i386/i386dasm.cpp @@ -7,117 +7,9 @@ */ #include "emu.h" +#include "i386dasm.h" -enum -{ - PARAM_REG = 1, /* 16 or 32-bit register */ - PARAM_REG8, /* 8-bit register */ - PARAM_REG16, /* 16-bit register */ - PARAM_REG32, /* 32-bit register */ - PARAM_REG3264, /* 32-bit or 64-bit register */ - PARAM_REG2_32, /* 32-bit register */ - PARAM_MMX, /* MMX register */ - PARAM_MMX2, /* MMX register in modrm */ - PARAM_XMM, /* XMM register */ - PARAM_RM, /* 16 or 32-bit memory or register */ - PARAM_RM8, /* 8-bit memory or register */ - PARAM_RM16, /* 16-bit memory or register */ - PARAM_RM32, /* 32-bit memory or register */ - PARAM_RMPTR, /* 16 or 32-bit memory or register */ - PARAM_RMPTR8, /* 8-bit memory or register */ - PARAM_RMPTR16, /* 16-bit memory or register */ - PARAM_RMPTR32, /* 32-bit memory or register */ - PARAM_RMXMM, /* 32 or 64-bit memory or register */ - PARAM_REGORXMM, /* 32 or 64-bit register or XMM register */ - PARAM_M64, /* 64-bit memory */ - PARAM_M64PTR, /* 64-bit memory */ - PARAM_MMXM, /* 64-bit memory or MMX register */ - PARAM_XMMM, /* 128-bit memory or XMM register */ - PARAM_I4, /* 4-bit signed immediate */ - PARAM_I8, /* 8-bit signed immediate */ - PARAM_I16, /* 16-bit signed immediate */ - PARAM_UI8, /* 8-bit unsigned immediate */ - PARAM_UI16, /* 16-bit unsigned immediate */ - PARAM_IMM, /* 16 or 32-bit immediate */ - PARAM_IMM64, /* 16, 32 or 64-bit immediate */ - PARAM_ADDR, /* 16:16 or 16:32 address */ - PARAM_REL, /* 16 or 32-bit PC-relative displacement */ - PARAM_REL8, /* 8-bit PC-relative displacement */ - PARAM_MEM_OFFS, /* 16 or 32-bit mem offset */ - PARAM_PREIMP, /* prefix with implicit register */ - PARAM_SREG, /* segment register */ - PARAM_CREG, /* control register */ - PARAM_DREG, /* debug register */ - PARAM_TREG, /* test register */ - PARAM_1, /* used by shift/rotate instructions */ - PARAM_AL, - PARAM_CL, - PARAM_DL, - PARAM_BL, - PARAM_AH, - PARAM_CH, - PARAM_DH, - PARAM_BH, - PARAM_DX, - PARAM_EAX, /* EAX or AX */ - PARAM_ECX, /* ECX or CX */ - PARAM_EDX, /* EDX or DX */ - PARAM_EBX, /* EBX or BX */ - PARAM_ESP, /* ESP or SP */ - PARAM_EBP, /* EBP or BP */ - PARAM_ESI, /* ESI or SI */ - PARAM_EDI, /* EDI or DI */ - PARAM_XMM0, - PARAM_XMM64, /* 64-bit memory or XMM register */ - PARAM_XMM32, /* 32-bit memory or XMM register */ - PARAM_XMM16 /* 16-bit memory or XMM register */ -}; - -enum -{ - MODRM = 1, - GROUP, - FPU, - OP_SIZE, - ADDR_SIZE, - TWO_BYTE, - PREFIX, - SEG_CS, - SEG_DS, - SEG_ES, - SEG_FS, - SEG_GS, - SEG_SS, - ISREX, - THREE_BYTE /* [prefix] 0f op1 op2 and then mod/rm */ -}; - -#define FLAGS_MASK 0x0ff -#define VAR_NAME 0x100 -#define VAR_NAME4 0x200 -#define ALWAYS64 0x400 -#define SPECIAL64 0x800 -#define SPECIAL64_ENT(x) (SPECIAL64 | ((x) << 24)) -#define GROUP_MOD 0x1000 - -struct I386_OPCODE { - const char *mnemonic; - uint32_t flags; - uint32_t param1; - uint32_t param2; - uint32_t param3; - offs_t dasm_flags; -}; - -struct GROUP_OP { - char mnemonic[32]; - const I386_OPCODE *opcode; -}; - -static const uint8_t *opcode_ptr; -static const uint8_t *opcode_ptr_base; - -static const I386_OPCODE i386_opcode_table1[256] = +const i386_disassembler::I386_OPCODE i386_disassembler::i386_opcode_table1[256] = { // 0x00 {"add", MODRM, PARAM_RM8, PARAM_REG8, 0 }, @@ -283,7 +175,7 @@ static const I386_OPCODE i386_opcode_table1[256] = {"xchg", 0, PARAM_EAX, PARAM_EDI, 0 }, {"cbw\0cwde\0cdqe", VAR_NAME, 0, 0, 0 }, {"cwd\0cdq\0cqo", VAR_NAME, 0, 0, 0 }, - {"call", ALWAYS64, PARAM_ADDR, 0, 0, DASMFLAG_STEP_OVER}, + {"call", ALWAYS64, PARAM_ADDR, 0, 0, STEP_OVER}, {"wait", 0, 0, 0, 0 }, {"pushf\0pushfd\0pushfq",VAR_NAME, 0, 0, 0 }, {"popf\0popfd\0popfq",VAR_NAME, 0, 0, 0 }, @@ -326,20 +218,20 @@ static const I386_OPCODE i386_opcode_table1[256] = // 0xc0 {"groupC0", GROUP, 0, 0, 0 }, {"groupC1", GROUP, 0, 0, 0 }, - {"ret", 0, PARAM_UI16, 0, 0, DASMFLAG_STEP_OUT}, - {"ret", 0, 0, 0, 0, DASMFLAG_STEP_OUT}, + {"ret", 0, PARAM_UI16, 0, 0, STEP_OUT}, + {"ret", 0, 0, 0, 0, STEP_OUT}, {"les", MODRM, PARAM_REG, PARAM_RM, 0 }, {"lds", MODRM, PARAM_REG, PARAM_RM, 0 }, {"mov", MODRM, PARAM_RMPTR8, PARAM_UI8, 0 }, {"mov", MODRM, PARAM_RMPTR, PARAM_IMM, 0 }, {"enter", 0, PARAM_UI16, PARAM_UI8, 0 }, {"leave", 0, 0, 0, 0 }, - {"retf", 0, PARAM_UI16, 0, 0, DASMFLAG_STEP_OUT}, - {"retf", 0, 0, 0, 0, DASMFLAG_STEP_OUT}, - {"int 3", 0, 0, 0, 0, DASMFLAG_STEP_OVER}, - {"int", 0, PARAM_UI8, 0, 0, DASMFLAG_STEP_OVER}, + {"retf", 0, PARAM_UI16, 0, 0, STEP_OUT}, + {"retf", 0, 0, 0, 0, STEP_OUT}, + {"int 3", 0, 0, 0, 0, STEP_OVER}, + {"int", 0, PARAM_UI8, 0, 0, STEP_OVER}, {"into", 0, 0, 0, 0 }, - {"iret", 0, 0, 0, 0, DASMFLAG_STEP_OUT}, + {"iret", 0, 0, 0, 0, STEP_OUT}, // 0xd0 {"groupD0", GROUP, 0, 0, 0 }, {"groupD1", GROUP, 0, 0, 0 }, @@ -358,15 +250,15 @@ static const I386_OPCODE i386_opcode_table1[256] = {"escape", FPU, 0, 0, 0 }, {"escape", FPU, 0, 0, 0 }, // 0xe0 - {"loopne", 0, PARAM_REL8, 0, 0, DASMFLAG_STEP_OVER}, - {"loopz", 0, PARAM_REL8, 0, 0, DASMFLAG_STEP_OVER}, - {"loop", 0, PARAM_REL8, 0, 0, DASMFLAG_STEP_OVER}, + {"loopne", 0, PARAM_REL8, 0, 0, STEP_OVER}, + {"loopz", 0, PARAM_REL8, 0, 0, STEP_OVER}, + {"loop", 0, PARAM_REL8, 0, 0, STEP_OVER}, {"jcxz\0jecxz\0jrcxz",VAR_NAME, PARAM_REL8, 0, 0 }, {"in", 0, PARAM_AL, PARAM_UI8, 0 }, {"in", 0, PARAM_EAX, PARAM_UI8, 0 }, {"out", 0, PARAM_UI8, PARAM_AL, 0 }, {"out", 0, PARAM_UI8, PARAM_EAX, 0 }, - {"call", 0, PARAM_REL, 0, 0, DASMFLAG_STEP_OVER}, + {"call", 0, PARAM_REL, 0, 0, STEP_OVER}, {"jmp", 0, PARAM_REL, 0, 0 }, {"jmp", 0, PARAM_ADDR, 0, 0 }, {"jmp", 0, PARAM_REL8, 0, 0 }, @@ -393,12 +285,12 @@ static const I386_OPCODE i386_opcode_table1[256] = {"groupFF", GROUP, 0, 0, 0 } }; -static const I386_OPCODE x64_opcode_alt[] = +const i386_disassembler::I386_OPCODE i386_disassembler::x64_opcode_alt[] = { {"movsxd", MODRM | ALWAYS64,PARAM_REG, PARAM_RMPTR32, 0 }, }; -static const I386_OPCODE i386_opcode_table2[256] = +const i386_disassembler::I386_OPCODE i386_disassembler::i386_opcode_table2[256] = { // 0x00 {"group0F00", GROUP, 0, 0, 0 }, @@ -724,7 +616,7 @@ static const I386_OPCODE i386_opcode_table2[256] = {"bsr\0" "???\0" "???\0" - "lzcnt", MODRM|VAR_NAME4, PARAM_REG, PARAM_RM, 0, DASMFLAG_STEP_OVER}, + "lzcnt", MODRM|VAR_NAME4, PARAM_REG, PARAM_RM, 0, STEP_OVER}, {"movsx", MODRM, PARAM_REG, PARAM_RMPTR8, 0 }, {"movsx", MODRM, PARAM_REG, PARAM_RMPTR16, 0 }, // 0xc0 @@ -821,7 +713,7 @@ static const I386_OPCODE i386_opcode_table2[256] = {"???", 0, 0, 0, 0 } }; -static const I386_OPCODE i386_opcode_table0F38[256] = +const i386_disassembler::I386_OPCODE i386_disassembler::i386_opcode_table0F38[256] = { // 0x00 {"pshufb\0" @@ -1265,7 +1157,7 @@ static const I386_OPCODE i386_opcode_table0F38[256] = {"???", 0, 0, 0, 0 }, }; -static const I386_OPCODE i386_opcode_table0F3A[256] = +const i386_disassembler::I386_OPCODE i386_disassembler::i386_opcode_table0F3A[256] = { // 0x00 {"???", 0, 0, 0, 0 }, @@ -1613,7 +1505,7 @@ static const I386_OPCODE i386_opcode_table0F3A[256] = {"???", 0, 0, 0, 0 }, }; -static const I386_OPCODE group80_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::group80_table[8] = { {"add", 0, PARAM_RMPTR8, PARAM_UI8, 0 }, {"or", 0, PARAM_RMPTR8, PARAM_UI8, 0 }, @@ -1625,7 +1517,7 @@ static const I386_OPCODE group80_table[8] = {"cmp", 0, PARAM_RMPTR8, PARAM_UI8, 0 } }; -static const I386_OPCODE group81_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::group81_table[8] = { {"add", 0, PARAM_RMPTR, PARAM_IMM, 0 }, {"or", 0, PARAM_RMPTR, PARAM_IMM, 0 }, @@ -1637,7 +1529,7 @@ static const I386_OPCODE group81_table[8] = {"cmp", 0, PARAM_RMPTR, PARAM_IMM, 0 } }; -static const I386_OPCODE group83_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::group83_table[8] = { {"add", 0, PARAM_RMPTR, PARAM_I8, 0 }, {"or", 0, PARAM_RMPTR, PARAM_I8, 0 }, @@ -1649,7 +1541,7 @@ static const I386_OPCODE group83_table[8] = {"cmp", 0, PARAM_RMPTR, PARAM_I8, 0 } }; -static const I386_OPCODE groupC0_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::groupC0_table[8] = { {"rol", 0, PARAM_RMPTR8, PARAM_UI8, 0 }, {"ror", 0, PARAM_RMPTR8, PARAM_UI8, 0 }, @@ -1661,7 +1553,7 @@ static const I386_OPCODE groupC0_table[8] = {"sar", 0, PARAM_RMPTR8, PARAM_UI8, 0 } }; -static const I386_OPCODE groupC1_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::groupC1_table[8] = { {"rol", 0, PARAM_RMPTR, PARAM_UI8, 0 }, {"ror", 0, PARAM_RMPTR, PARAM_UI8, 0 }, @@ -1673,7 +1565,7 @@ static const I386_OPCODE groupC1_table[8] = {"sar", 0, PARAM_RMPTR, PARAM_UI8, 0 } }; -static const I386_OPCODE groupD0_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::groupD0_table[8] = { {"rol", 0, PARAM_RMPTR8, PARAM_1, 0 }, {"ror", 0, PARAM_RMPTR8, PARAM_1, 0 }, @@ -1685,7 +1577,7 @@ static const I386_OPCODE groupD0_table[8] = {"sar", 0, PARAM_RMPTR8, PARAM_1, 0 } }; -static const I386_OPCODE groupD1_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::groupD1_table[8] = { {"rol", 0, PARAM_RMPTR, PARAM_1, 0 }, {"ror", 0, PARAM_RMPTR, PARAM_1, 0 }, @@ -1697,7 +1589,7 @@ static const I386_OPCODE groupD1_table[8] = {"sar", 0, PARAM_RMPTR, PARAM_1, 0 } }; -static const I386_OPCODE groupD2_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::groupD2_table[8] = { {"rol", 0, PARAM_RMPTR8, PARAM_CL, 0 }, {"ror", 0, PARAM_RMPTR8, PARAM_CL, 0 }, @@ -1709,7 +1601,7 @@ static const I386_OPCODE groupD2_table[8] = {"sar", 0, PARAM_RMPTR8, PARAM_CL, 0 } }; -static const I386_OPCODE groupD3_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::groupD3_table[8] = { {"rol", 0, PARAM_RMPTR, PARAM_CL, 0 }, {"ror", 0, PARAM_RMPTR, PARAM_CL, 0 }, @@ -1721,7 +1613,7 @@ static const I386_OPCODE groupD3_table[8] = {"sar", 0, PARAM_RMPTR, PARAM_CL, 0 } }; -static const I386_OPCODE groupF6_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::groupF6_table[8] = { {"test", 0, PARAM_RMPTR8, PARAM_UI8, 0 }, {"test", 0, PARAM_RMPTR8, PARAM_UI8, 0 }, @@ -1733,7 +1625,7 @@ static const I386_OPCODE groupF6_table[8] = {"idiv", 0, PARAM_RMPTR8, 0, 0 } }; -static const I386_OPCODE groupF7_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::groupF7_table[8] = { {"test", 0, PARAM_RMPTR, PARAM_IMM, 0 }, {"test", 0, PARAM_RMPTR, PARAM_IMM, 0 }, @@ -1745,7 +1637,7 @@ static const I386_OPCODE groupF7_table[8] = {"idiv", 0, PARAM_RMPTR, 0, 0 } }; -static const I386_OPCODE groupFE_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::groupFE_table[8] = { {"inc", 0, PARAM_RMPTR8, 0, 0 }, {"dec", 0, PARAM_RMPTR8, 0, 0 }, @@ -1757,19 +1649,19 @@ static const I386_OPCODE groupFE_table[8] = {"???", 0, 0, 0, 0 } }; -static const I386_OPCODE groupFF_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::groupFF_table[8] = { {"inc", 0, PARAM_RMPTR, 0, 0 }, {"dec", 0, PARAM_RMPTR, 0, 0 }, - {"call", ALWAYS64, PARAM_RMPTR, 0, 0, DASMFLAG_STEP_OVER}, - {"call far ptr ",0, PARAM_RM, 0, 0, DASMFLAG_STEP_OVER}, + {"call", ALWAYS64, PARAM_RMPTR, 0, 0, STEP_OVER}, + {"call far ptr ",0, PARAM_RM, 0, 0, STEP_OVER}, {"jmp", ALWAYS64, PARAM_RMPTR, 0, 0 }, {"jmp far ptr ",0, PARAM_RM, 0, 0 }, {"push", 0, PARAM_RMPTR, 0, 0 }, {"???", 0, 0, 0, 0 } }; -static const I386_OPCODE group0F00_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::group0F00_table[8] = { {"sldt", 0, PARAM_RM, 0, 0 }, {"str", 0, PARAM_RM, 0, 0 }, @@ -1781,7 +1673,7 @@ static const I386_OPCODE group0F00_table[8] = {"???", 0, 0, 0, 0 } }; -static const I386_OPCODE group0F01_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::group0F01_table[8] = { {"sgdt", 0, PARAM_RM, 0, 0 }, {"sidt", 0, PARAM_RM, 0, 0 }, @@ -1793,7 +1685,7 @@ static const I386_OPCODE group0F01_table[8] = {"invlpg", 0, PARAM_RM, 0, 0 } }; -static const I386_OPCODE group0F0D_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::group0F0D_table[8] = { {"prefetch", 0, PARAM_RM8, 0, 0 }, {"prefetchw", 0, PARAM_RM8, 0, 0 }, @@ -1805,7 +1697,7 @@ static const I386_OPCODE group0F0D_table[8] = {"???", 0, 0, 0, 0 } }; -static const I386_OPCODE group0F12_table[4] = +const i386_disassembler::I386_OPCODE i386_disassembler::group0F12_table[4] = { { "movlps\0" "movlpd\0" @@ -1825,7 +1717,7 @@ static const I386_OPCODE group0F12_table[4] = "movsldup", VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 } }; -static const I386_OPCODE group0F16_table[4] = +const i386_disassembler::I386_OPCODE i386_disassembler::group0F16_table[4] = { { "movhps\0" "movhpd\0" @@ -1845,7 +1737,7 @@ static const I386_OPCODE group0F16_table[4] = "movshdup", VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 } }; -static const I386_OPCODE group0F18_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::group0F18_table[8] = { {"prefetchnta", 0, PARAM_RM8, 0, 0 }, {"prefetch0", 0, PARAM_RM8, 0, 0 }, @@ -1857,7 +1749,7 @@ static const I386_OPCODE group0F18_table[8] = {"???", 0, 0, 0, 0 } }; -static const I386_OPCODE group0F71_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::group0F71_table[8] = { {"???", 0, 0, 0, 0 }, {"???", 0, 0, 0, 0 }, @@ -1869,7 +1761,7 @@ static const I386_OPCODE group0F71_table[8] = {"???", 0, 0, 0, 0 } }; -static const I386_OPCODE group0F72_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::group0F72_table[8] = { {"???", 0, 0, 0, 0 }, {"???", 0, 0, 0, 0 }, @@ -1881,7 +1773,7 @@ static const I386_OPCODE group0F72_table[8] = {"???", 0, 0, 0, 0 } }; -static const I386_OPCODE group0F73_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::group0F73_table[8] = { {"???", 0, 0, 0, 0 }, {"???", 0, 0, 0, 0 }, @@ -1893,7 +1785,7 @@ static const I386_OPCODE group0F73_table[8] = {"pslldq", 0, PARAM_MMX2, PARAM_UI8, 0 }, }; -static const I386_OPCODE group0FAE_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::group0FAE_table[8] = { {"fxsave", 0, PARAM_RM, 0, 0 }, {"fxrstor", 0, PARAM_RM, 0, 0 }, @@ -1906,7 +1798,7 @@ static const I386_OPCODE group0FAE_table[8] = }; -static const I386_OPCODE group0FBA_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::group0FBA_table[8] = { {"???", 0, 0, 0, 0 }, {"???", 0, 0, 0, 0 }, @@ -1918,7 +1810,7 @@ static const I386_OPCODE group0FBA_table[8] = {"btc", 0, PARAM_RM, PARAM_UI8, 0 } }; -static const I386_OPCODE group0FC7_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::group0FC7_table[8] = { {"???", 0, 0, 0, 0 }, {"cmpxchg8b", MODRM, PARAM_M64PTR, 0, 0 }, @@ -1933,7 +1825,7 @@ static const I386_OPCODE group0FC7_table[8] = {"vmptrtst", MODRM, PARAM_M64PTR, 0, 0 } }; -static const GROUP_OP group_op_table[] = +const i386_disassembler::GROUP_OP i386_disassembler::group_op_table[] = { { "group80", group80_table }, { "group81", group81_table }, @@ -1964,98 +1856,60 @@ static const GROUP_OP group_op_table[] = -static const char *const i386_reg[3][16] = +const char *const i386_disassembler::i386_reg[3][16] = { {"ax", "cx", "dx", "bx", "sp", "bp", "si", "di", "r8w", "r9w", "r10w","r11w","r12w","r13w","r14w","r15w"}, {"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "r8d", "r9d", "r10d","r11d","r12d","r13d","r14d","r15d"}, {"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"} }; -static const char *const i386_reg8[8] = {"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"}; -static const char *const i386_reg8rex[16] = {"al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil", "r8l", "r9l", "r10l", "r11l", "r12l", "r13l", "r14l", "r15l"}; -static const char *const i386_sreg[8] = {"es", "cs", "ss", "ds", "fs", "gs", "???", "???"}; - -static int address_size; -static int operand_size; -static int address_prefix; -static int operand_prefix; -static int max_length; -static uint64_t pc; -static uint8_t modrm; -static uint32_t segment; -static offs_t dasm_flags; -static std::string modrm_string; -static uint8_t rex, regex, sibex, rmex; -static uint8_t pre0f; -static uint8_t curmode; - -#define MODRM_REG1 ((modrm >> 3) & 0x7) -#define MODRM_REG2 (modrm & 0x7) -#define MODRM_MOD ((modrm >> 6) & 0x3) - -static inline uint8_t FETCH(void) +const char *const i386_disassembler::i386_reg8[8] = {"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"}; +const char *const i386_disassembler::i386_reg8rex[16] = {"al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil", "r8l", "r9l", "r10l", "r11l", "r12l", "r13l", "r14l", "r15l"}; +const char *const i386_disassembler::i386_sreg[8] = {"es", "cs", "ss", "ds", "fs", "gs", "???", "???"}; + +inline uint8_t i386_disassembler::FETCH(offs_t base_pc, offs_t &pc, const data_buffer &opcodes) { - if ((opcode_ptr - opcode_ptr_base) + 1 > max_length) + if ((pc - base_pc) + 1 > max_length) return 0xff; + uint8_t d = opcodes.r8(pc); pc++; - return *opcode_ptr++; + return d; } -#if 0 -static inline uint16_t FETCH16(void) +inline uint16_t i386_disassembler::FETCH16(offs_t base_pc, offs_t &pc, const data_buffer &opcodes) { - uint16_t d; - if ((opcode_ptr - opcode_ptr_base) + 2 > max_length) + if ((pc - base_pc) + 2 > max_length) return 0xffff; - d = opcode_ptr[0] | (opcode_ptr[1] << 8); - opcode_ptr += 2; + uint16_t d = opcodes.r16(pc); pc += 2; return d; } -#endif -static inline uint32_t FETCH32(void) +inline uint32_t i386_disassembler::FETCH32(offs_t base_pc, offs_t &pc, const data_buffer &opcodes) { - uint32_t d; - if ((opcode_ptr - opcode_ptr_base) + 4 > max_length) + if ((pc - base_pc) + 4 > max_length) return 0xffffffff; - d = opcode_ptr[0] | (opcode_ptr[1] << 8) | (opcode_ptr[2] << 16) | (opcode_ptr[3] << 24); - opcode_ptr += 4; + uint32_t d = opcodes.r32(pc); pc += 4; return d; } -static inline uint8_t FETCHD(void) +inline uint8_t i386_disassembler::FETCHD(offs_t base_pc, offs_t &pc, const data_buffer &opcodes) { - if ((opcode_ptr - opcode_ptr_base) + 1 > max_length) - return 0xff; - pc++; - return *opcode_ptr++; + return FETCH(base_pc, pc, opcodes); } -static inline uint16_t FETCHD16(void) +inline uint16_t i386_disassembler::FETCHD16(offs_t base_pc, offs_t &pc, const data_buffer &opcodes) { - uint16_t d; - if ((opcode_ptr - opcode_ptr_base) + 2 > max_length) - return 0xffff; - d = opcode_ptr[0] | (opcode_ptr[1] << 8); - opcode_ptr += 2; - pc += 2; - return d; + return FETCH16(base_pc, pc, opcodes); } -static inline uint32_t FETCHD32(void) +inline uint32_t i386_disassembler::FETCHD32(offs_t base_pc, offs_t &pc, const data_buffer &opcodes) { - uint32_t d; - if ((opcode_ptr - opcode_ptr_base) + 4 > max_length) - return 0xffffffff; - d = opcode_ptr[0] | (opcode_ptr[1] << 8) | (opcode_ptr[2] << 16) | (opcode_ptr[3] << 24); - opcode_ptr += 4; - pc += 4; - return d; + return FETCH32(base_pc, pc, opcodes); } -static char *hexstring(uint32_t value, int digits) +char *i386_disassembler::hexstring(uint32_t value, int digits) { static char buffer[20]; buffer[0] = '0'; @@ -2066,7 +1920,7 @@ static char *hexstring(uint32_t value, int digits) return (buffer[1] >= '0' && buffer[1] <= '9') ? &buffer[1] : &buffer[0]; } -static char *hexstring64(uint32_t lo, uint32_t hi) +char *i386_disassembler::hexstring64(uint32_t lo, uint32_t hi) { static char buffer[40]; buffer[0] = '0'; @@ -2077,15 +1931,15 @@ static char *hexstring64(uint32_t lo, uint32_t hi) return (buffer[1] >= '0' && buffer[1] <= '9') ? &buffer[1] : &buffer[0]; } -static char *hexstringpc(uint64_t pc) +char *i386_disassembler::hexstringpc(uint64_t pc) { - if (curmode == 64) + if (m_config->get_mode() == 64) return hexstring64((uint32_t)pc, (uint32_t)(pc >> 32)); else return hexstring((uint32_t)pc, 0); } -static char *shexstring(uint32_t value, int digits, bool always) +char *i386_disassembler::shexstring(uint32_t value, int digits, bool always) { static char buffer[20]; if (value >= 0x80000000) @@ -2097,18 +1951,18 @@ static char *shexstring(uint32_t value, int digits, bool always) return buffer; } -static void handle_sib_byte(std::ostream &stream, uint8_t mod) +void i386_disassembler::handle_sib_byte(std::ostream &stream, uint8_t mod, offs_t base_pc, offs_t &pc, const data_buffer &opcodes) { uint32_t i32; uint8_t scale, i, base; - uint8_t sib = FETCHD(); + uint8_t sib = FETCHD(base_pc, pc, opcodes); scale = (sib >> 6) & 0x3; i = ((sib >> 3) & 0x7) | sibex; base = (sib & 0x7) | rmex; if (base == 5 && mod == 0) { - i32 = FETCH32(); + i32 = FETCHD32(base_pc, pc, opcodes); util::stream_format(stream, "%s", hexstring(i32, 0)); } else if (base != 5 || mod != 3) util::stream_format(stream, "%s", i386_reg[address_size][base]); @@ -2120,14 +1974,14 @@ static void handle_sib_byte(std::ostream &stream, uint8_t mod) } } -static void handle_modrm(std::ostream &stream) +void i386_disassembler::handle_modrm(std::ostream &stream, offs_t base_pc, offs_t &pc, const data_buffer &opcodes) { int8_t disp8; int16_t disp16; int32_t disp32; uint8_t mod, rm; - modrm = FETCHD(); + modrm = FETCHD(base_pc, pc, opcodes); mod = (modrm >> 6) & 0x3; rm = (modrm & 0x7) | rmex; @@ -2147,38 +2001,38 @@ static void handle_modrm(std::ostream &stream) util::stream_format(stream, "[" ); if( address_size == 2 ) { if ((rm & 7) == 4) - handle_sib_byte(stream, mod ); + handle_sib_byte(stream, mod, base_pc, pc, opcodes); else if ((rm & 7) == 5 && mod == 0) { - disp32 = FETCHD32(); + disp32 = FETCHD32(base_pc, pc, opcodes); util::stream_format(stream, "rip%s", shexstring(disp32, 0, true)); } else util::stream_format(stream, "%s", i386_reg[2][rm]); if( mod == 1 ) { - disp8 = FETCHD(); + disp8 = FETCHD(base_pc, pc, opcodes); if (disp8 != 0) util::stream_format(stream, "%s", shexstring((int32_t)disp8, 0, true) ); } else if( mod == 2 ) { - disp32 = FETCHD32(); + disp32 = FETCHD32(base_pc, pc, opcodes); if (disp32 != 0) util::stream_format(stream, "%s", shexstring(disp32, 0, true) ); } } else if (address_size == 1) { if ((rm & 7) == 4) - handle_sib_byte(stream, mod ); + handle_sib_byte(stream, mod, base_pc, pc, opcodes); else if ((rm & 7) == 5 && mod == 0) { - disp32 = FETCHD32(); - if (curmode == 64) + disp32 = FETCHD32(base_pc, pc, opcodes); + if (m_config->get_mode() == 64) util::stream_format(stream, "eip%s", shexstring(disp32, 0, true) ); else util::stream_format(stream, "%s", hexstring(disp32, 0) ); } else util::stream_format(stream, "%s", i386_reg[1][rm]); if( mod == 1 ) { - disp8 = FETCHD(); + disp8 = FETCHD(base_pc, pc, opcodes); if (disp8 != 0) util::stream_format(stream, "%s", shexstring((int32_t)disp8, 0, true) ); } else if( mod == 2 ) { - disp32 = FETCHD32(); + disp32 = FETCHD32(base_pc, pc, opcodes); if (disp32 != 0) util::stream_format(stream, "%s", shexstring(disp32, 0, true) ); } @@ -2193,7 +2047,7 @@ static void handle_modrm(std::ostream &stream) case 5: util::stream_format(stream, "di" ); break; case 6: if( mod == 0 ) { - disp16 = FETCHD16(); + disp16 = FETCHD16(base_pc, pc, opcodes); util::stream_format(stream, "%s", hexstring((unsigned) (uint16_t) disp16, 0) ); } else { util::stream_format(stream, "bp" ); @@ -2202,11 +2056,11 @@ static void handle_modrm(std::ostream &stream) case 7: util::stream_format(stream, "bx" ); break; } if( mod == 1 ) { - disp8 = FETCHD(); + disp8 = FETCHD(base_pc, pc, opcodes); if (disp8 != 0) util::stream_format(stream, "%s", shexstring((int32_t)disp8, 0, true) ); } else if( mod == 2 ) { - disp16 = FETCHD16(); + disp16 = FETCHD16(base_pc, pc, opcodes); if (disp16 != 0) util::stream_format(stream, "%s", shexstring((int32_t)disp16, 0, true) ); } @@ -2214,14 +2068,14 @@ static void handle_modrm(std::ostream &stream) util::stream_format(stream, "]" ); } -static void handle_modrm(std::string &buffer) +void i386_disassembler::handle_modrm(std::string &buffer, offs_t base_pc, offs_t &pc, const data_buffer &opcodes) { std::stringstream stream; - handle_modrm(stream); + handle_modrm(stream, base_pc, pc, opcodes); buffer = stream.str(); } -static void handle_param(std::ostream &stream, uint32_t param) +void i386_disassembler::handle_param(std::ostream &stream, uint32_t param, offs_t base_pc, offs_t &pc, const data_buffer &opcodes) { uint8_t i8; uint16_t i16; @@ -2235,58 +2089,58 @@ static void handle_param(std::ostream &stream, uint32_t param) switch(param) { case PARAM_REG: - util::stream_format(stream, "%s", i386_reg[operand_size][MODRM_REG1 | regex] ); + util::stream_format(stream, "%s", i386_reg[operand_size][MODRM_REG1() | regex] ); break; case PARAM_REG8: - util::stream_format(stream, "%s", (rex ? i386_reg8rex : i386_reg8)[MODRM_REG1 | regex] ); + util::stream_format(stream, "%s", (rex ? i386_reg8rex : i386_reg8)[MODRM_REG1() | regex] ); break; case PARAM_REG16: - util::stream_format(stream, "%s", i386_reg[0][MODRM_REG1 | regex] ); + util::stream_format(stream, "%s", i386_reg[0][MODRM_REG1() | regex] ); break; case PARAM_REG32: - util::stream_format(stream, "%s", i386_reg[1][MODRM_REG1 | regex] ); + util::stream_format(stream, "%s", i386_reg[1][MODRM_REG1() | regex] ); break; case PARAM_REG3264: - util::stream_format(stream, "%s", i386_reg[(operand_size == 2) ? 2 : 1][MODRM_REG1 | regex] ); + util::stream_format(stream, "%s", i386_reg[(operand_size == 2) ? 2 : 1][MODRM_REG1() | regex] ); break; case PARAM_MMX: if (pre0f == 0x66 || pre0f == 0xf2 || pre0f == 0xf3) - util::stream_format(stream, "xmm%d", MODRM_REG1 | regex ); + util::stream_format(stream, "xmm%d", MODRM_REG1() | regex ); else - util::stream_format(stream, "mm%d", MODRM_REG1 | regex ); + util::stream_format(stream, "mm%d", MODRM_REG1() | regex ); break; case PARAM_MMX2: if (pre0f == 0x66 || pre0f == 0xf2 || pre0f == 0xf3) - util::stream_format(stream, "xmm%d", MODRM_REG2 | regex ); + util::stream_format(stream, "xmm%d", MODRM_REG2() | regex ); else - util::stream_format(stream, "mm%d", MODRM_REG2 | regex ); + util::stream_format(stream, "mm%d", MODRM_REG2() | regex ); break; case PARAM_XMM: - util::stream_format(stream, "xmm%d", MODRM_REG1 | regex ); + util::stream_format(stream, "xmm%d", MODRM_REG1() | regex ); break; case PARAM_REGORXMM: if (pre0f != 0xf2 && pre0f != 0xf3) - util::stream_format(stream, "xmm%d", MODRM_REG1 | regex ); + util::stream_format(stream, "xmm%d", MODRM_REG1() | regex ); else - util::stream_format(stream, "%s", i386_reg[(operand_size == 2) ? 2 : 1][MODRM_REG1 | regex] ); + util::stream_format(stream, "%s", i386_reg[(operand_size == 2) ? 2 : 1][MODRM_REG1() | regex] ); break; case PARAM_REG2_32: - util::stream_format(stream, "%s", i386_reg[1][MODRM_REG2 | rmex] ); + util::stream_format(stream, "%s", i386_reg[1][MODRM_REG2() | rmex] ); break; case PARAM_RM: case PARAM_RMPTR: if( modrm >= 0xc0 ) { - util::stream_format(stream, "%s", i386_reg[operand_size][MODRM_REG2 | rmex] ); + util::stream_format(stream, "%s", i386_reg[operand_size][MODRM_REG2() | rmex] ); } else { if (param == PARAM_RMPTR) { @@ -2304,7 +2158,7 @@ static void handle_param(std::ostream &stream, uint32_t param) case PARAM_RM8: case PARAM_RMPTR8: if( modrm >= 0xc0 ) { - util::stream_format(stream, "%s", (rex ? i386_reg8rex : i386_reg8)[MODRM_REG2 | rmex] ); + util::stream_format(stream, "%s", (rex ? i386_reg8rex : i386_reg8)[MODRM_REG2() | rmex] ); } else { if (param == PARAM_RMPTR8) util::stream_format(stream, "byte ptr " ); @@ -2315,7 +2169,7 @@ static void handle_param(std::ostream &stream, uint32_t param) case PARAM_RM16: case PARAM_RMPTR16: if( modrm >= 0xc0 ) { - util::stream_format(stream, "%s", i386_reg[0][MODRM_REG2 | rmex] ); + util::stream_format(stream, "%s", i386_reg[0][MODRM_REG2() | rmex] ); } else { if (param == PARAM_RMPTR16) util::stream_format(stream, "word ptr " ); @@ -2326,7 +2180,7 @@ static void handle_param(std::ostream &stream, uint32_t param) case PARAM_RM32: case PARAM_RMPTR32: if( modrm >= 0xc0 ) { - util::stream_format(stream, "%s", i386_reg[1][MODRM_REG2 | rmex] ); + util::stream_format(stream, "%s", i386_reg[1][MODRM_REG2() | rmex] ); } else { if (param == PARAM_RMPTR32) util::stream_format(stream, "dword ptr " ); @@ -2337,9 +2191,9 @@ static void handle_param(std::ostream &stream, uint32_t param) case PARAM_RMXMM: if( modrm >= 0xc0 ) { if (pre0f != 0xf2 && pre0f != 0xf3) - util::stream_format(stream, "xmm%d", MODRM_REG2 | rmex ); + util::stream_format(stream, "xmm%d", MODRM_REG2() | rmex ); else - util::stream_format(stream, "%s", i386_reg[(operand_size == 2) ? 2 : 1][MODRM_REG2 | rmex] ); + util::stream_format(stream, "%s", i386_reg[(operand_size == 2) ? 2 : 1][MODRM_REG2() | rmex] ); } else { if (param == PARAM_RMPTR32) util::stream_format(stream, "dword ptr " ); @@ -2361,9 +2215,9 @@ static void handle_param(std::ostream &stream, uint32_t param) case PARAM_MMXM: if( modrm >= 0xc0 ) { if (pre0f == 0x66 || pre0f == 0xf2 || pre0f == 0xf3) - util::stream_format(stream, "xmm%d", MODRM_REG2 | rmex ); + util::stream_format(stream, "xmm%d", MODRM_REG2() | rmex ); else - util::stream_format(stream, "mm%d", MODRM_REG2 | rmex ); + util::stream_format(stream, "mm%d", MODRM_REG2() | rmex ); } else { util::stream_format(stream, "%s", modrm_string ); } @@ -2371,70 +2225,70 @@ static void handle_param(std::ostream &stream, uint32_t param) case PARAM_XMMM: if( modrm >= 0xc0 ) { - util::stream_format(stream, "xmm%d", MODRM_REG2 | rmex ); + util::stream_format(stream, "xmm%d", MODRM_REG2() | rmex ); } else { util::stream_format(stream, "%s", modrm_string ); } break; case PARAM_I4: - i8 = FETCHD(); + i8 = FETCHD(base_pc, pc, opcodes); util::stream_format(stream, "%d", i8 & 0x0f ); break; case PARAM_I8: - i8 = FETCHD(); + i8 = FETCHD(base_pc, pc, opcodes); util::stream_format(stream, "%s", shexstring((int8_t)i8, 0, false) ); break; case PARAM_I16: - i16 = FETCHD16(); + i16 = FETCHD16(base_pc, pc, opcodes); util::stream_format(stream, "%s", shexstring((int16_t)i16, 0, false) ); break; case PARAM_UI8: - i8 = FETCHD(); + i8 = FETCHD(base_pc, pc, opcodes); util::stream_format(stream, "%s", shexstring((uint8_t)i8, 0, false) ); break; case PARAM_UI16: - i16 = FETCHD16(); + i16 = FETCHD16(base_pc, pc, opcodes); util::stream_format(stream, "%s", shexstring((uint16_t)i16, 0, false) ); break; case PARAM_IMM64: if (operand_size == 2) { - uint32_t lo32 = FETCHD32(); - i32 = FETCHD32(); + uint32_t lo32 = FETCHD32(base_pc, pc, opcodes); + i32 = FETCHD32(base_pc, pc, opcodes); util::stream_format(stream, "%s", hexstring64(lo32, i32) ); } else if( operand_size ) { - i32 = FETCHD32(); + i32 = FETCHD32(base_pc, pc, opcodes); util::stream_format(stream, "%s", hexstring(i32, 0) ); } else { - i16 = FETCHD16(); + i16 = FETCHD16(base_pc, pc, opcodes); util::stream_format(stream, "%s", hexstring(i16, 0) ); } break; case PARAM_IMM: if( operand_size ) { - i32 = FETCHD32(); + i32 = FETCHD32(base_pc, pc, opcodes); util::stream_format(stream, "%s", hexstring(i32, 0) ); } else { - i16 = FETCHD16(); + i16 = FETCHD16(base_pc, pc, opcodes); util::stream_format(stream, "%s", hexstring(i16, 0) ); } break; case PARAM_ADDR: if( operand_size ) { - addr = FETCHD32(); - ptr = FETCHD16(); + addr = FETCHD32(base_pc, pc, opcodes); + ptr = FETCHD16(base_pc, pc, opcodes); util::stream_format(stream, "%s:", hexstring(ptr, 4) ); util::stream_format(stream, "%s", hexstring(addr, 0) ); } else { - addr = FETCHD16(); - ptr = FETCHD16(); + addr = FETCHD16(base_pc, pc, opcodes); + ptr = FETCHD16(base_pc, pc, opcodes); util::stream_format(stream, "%s:", hexstring(ptr, 4) ); util::stream_format(stream, "%s", hexstring(addr, 0) ); } @@ -2442,17 +2296,17 @@ static void handle_param(std::ostream &stream, uint32_t param) case PARAM_REL: if( operand_size ) { - d32 = FETCHD32(); + d32 = FETCHD32(base_pc, pc, opcodes); util::stream_format(stream, "%s", hexstringpc(pc + d32) ); } else { /* make sure to keep the relative offset within the segment */ - d16 = FETCHD16(); + d16 = FETCHD16(base_pc, pc, opcodes); util::stream_format(stream, "%s", hexstringpc((pc & 0xFFFF0000) | ((pc + d16) & 0x0000FFFF)) ); } break; case PARAM_REL8: - d8 = FETCHD(); + d8 = FETCHD(base_pc, pc, opcodes); util::stream_format(stream, "%s", hexstringpc(pc + d8) ); break; @@ -2468,10 +2322,10 @@ static void handle_param(std::ostream &stream, uint32_t param) } if( address_size ) { - i32 = FETCHD32(); + i32 = FETCHD32(base_pc, pc, opcodes); util::stream_format(stream, "[%s]", hexstring(i32, 0) ); } else { - i16 = FETCHD16(); + i16 = FETCHD16(base_pc, pc, opcodes); util::stream_format(stream, "[%s]", hexstring(i16, 0) ); } break; @@ -2489,19 +2343,19 @@ static void handle_param(std::ostream &stream, uint32_t param) break; case PARAM_SREG: - util::stream_format(stream, "%s", i386_sreg[MODRM_REG1] ); + util::stream_format(stream, "%s", i386_sreg[MODRM_REG1()] ); break; case PARAM_CREG: - util::stream_format(stream, "cr%d", MODRM_REG1 | regex ); + util::stream_format(stream, "cr%d", MODRM_REG1() | regex ); break; case PARAM_TREG: - util::stream_format(stream, "tr%d", MODRM_REG1 | regex ); + util::stream_format(stream, "tr%d", MODRM_REG1() | regex ); break; case PARAM_DREG: - util::stream_format(stream, "dr%d", MODRM_REG1 | regex ); + util::stream_format(stream, "dr%d", MODRM_REG1() | regex ); break; case PARAM_1: @@ -2536,7 +2390,7 @@ static void handle_param(std::ostream &stream, uint32_t param) } } -static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) +void i386_disassembler::handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2, offs_t base_pc, offs_t &pc, const data_buffer &opcodes) { switch (op1 & 0x7) { @@ -2545,8 +2399,7 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) if (op2 < 0xc0) { pc--; // adjust fetch pointer, so modrm byte read again - opcode_ptr--; - handle_modrm( modrm_string ); + handle_modrm(modrm_string, base_pc, pc, opcodes); switch ((op2 >> 3) & 0x7) { case 0: util::stream_format(stream, "fadd dword ptr %s", modrm_string); break; @@ -2581,8 +2434,7 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) if (op2 < 0xc0) { pc--; // adjust fetch pointer, so modrm byte read again - opcode_ptr--; - handle_modrm( modrm_string ); + handle_modrm(modrm_string, base_pc, pc, opcodes); switch ((op2 >> 3) & 0x7) { case 0: util::stream_format(stream, "fld dword ptr %s", modrm_string); break; @@ -2645,8 +2497,7 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) if (op2 < 0xc0) { pc--; // adjust fetch pointer, so modrm byte read again - opcode_ptr--; - handle_modrm( modrm_string ); + handle_modrm(modrm_string, base_pc, pc, opcodes); switch ((op2 >> 3) & 0x7) { case 0: util::stream_format(stream, "fiadd dword ptr %s", modrm_string); break; @@ -2689,8 +2540,7 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) if (op2 < 0xc0) { pc--; // adjust fetch pointer, so modrm byte read again - opcode_ptr--; - handle_modrm( modrm_string ); + handle_modrm(modrm_string, base_pc, pc, opcodes); switch ((op2 >> 3) & 0x7) { case 0: util::stream_format(stream, "fild dword ptr %s", modrm_string); break; @@ -2739,8 +2589,7 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) if (op2 < 0xc0) { pc--; // adjust fetch pointer, so modrm byte read again - opcode_ptr--; - handle_modrm( modrm_string ); + handle_modrm(modrm_string, base_pc, pc, opcodes); switch ((op2 >> 3) & 0x7) { case 0: util::stream_format(stream, "fadd qword ptr %s", modrm_string); break; @@ -2786,8 +2635,7 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) if (op2 < 0xc0) { pc--; // adjust fetch pointer, so modrm byte read again - opcode_ptr--; - handle_modrm( modrm_string ); + handle_modrm(modrm_string, base_pc, pc, opcodes); switch ((op2 >> 3) & 0x7) { case 0: util::stream_format(stream, "fld qword ptr %s", modrm_string); break; @@ -2830,8 +2678,7 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) if (op2 < 0xc0) { pc--; // adjust fetch pointer, so modrm byte read again - opcode_ptr--; - handle_modrm( modrm_string ); + handle_modrm(modrm_string, base_pc, pc, opcodes); switch ((op2 >> 3) & 0x7) { case 0: util::stream_format(stream, "fiadd word ptr %s", modrm_string); break; @@ -2879,8 +2726,7 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) if (op2 < 0xc0) { pc--; // adjust fetch pointer, so modrm byte read again - opcode_ptr--; - handle_modrm( modrm_string ); + handle_modrm(modrm_string, base_pc, pc, opcodes); switch ((op2 >> 3) & 0x7) { case 0: util::stream_format(stream, "fild word ptr %s", modrm_string); break; @@ -2913,7 +2759,7 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) } } -static void decode_opcode(std::ostream &stream, const I386_OPCODE *op, uint8_t op1) +void i386_disassembler::decode_opcode(std::ostream &stream, const I386_OPCODE *op, uint8_t op1, offs_t base_pc, offs_t &pc, const data_buffer &opcodes) { int i; uint8_t op2; @@ -2924,15 +2770,15 @@ static void decode_opcode(std::ostream &stream, const I386_OPCODE *op, uint8_t o switch( op->flags & FLAGS_MASK ) { case ISREX: - if (curmode == 64) + if (m_config->get_mode() == 64) { rex = op1; operand_size = (op1 & 8) ? 2 : 1; regex = (op1 << 1) & 8; sibex = (op1 << 2) & 8; rmex = (op1 << 3) & 8; - op2 = FETCH(); - decode_opcode(stream, &i386_opcode_table1[op2], op1 ); + op2 = FETCH(base_pc, pc, opcodes); + decode_opcode(stream, &i386_opcode_table1[op2], op1, base_pc, pc, opcodes); return; } break; @@ -2944,37 +2790,37 @@ static void decode_opcode(std::ostream &stream, const I386_OPCODE *op, uint8_t o operand_size ^= 1; operand_prefix = 1; } - op2 = FETCH(); - decode_opcode(stream, &i386_opcode_table1[op2], op2 ); + op2 = FETCH(base_pc, pc, opcodes); + decode_opcode(stream, &i386_opcode_table1[op2], op2, base_pc, pc, opcodes); return; case ADDR_SIZE: rex = regex = sibex = rmex = 0; if(address_prefix == 0) { - if (curmode != 64) + if (m_config->get_mode() != 64) address_size ^= 1; else address_size ^= 3; address_prefix = 1; } - op2 = FETCH(); - decode_opcode(stream, &i386_opcode_table1[op2], op2 ); + op2 = FETCH(base_pc, pc, opcodes); + decode_opcode(stream, &i386_opcode_table1[op2], op2, base_pc, pc, opcodes); return; case TWO_BYTE: - if (&opcode_ptr[-2] >= opcode_ptr_base) - pre0f = opcode_ptr[-2]; - op2 = FETCHD(); - decode_opcode(stream, &i386_opcode_table2[op2], op1 ); + if (pc - 2 >= base_pc) + pre0f = opcodes.r8(pc-2); + op2 = FETCHD(base_pc, pc, opcodes); + decode_opcode(stream, &i386_opcode_table2[op2], op1, base_pc, pc, opcodes); return; case THREE_BYTE: - op2 = FETCHD(); - if (opcode_ptr[-2] == 0x38) - decode_opcode(stream, &i386_opcode_table0F38[op2], op1 ); + op2 = FETCHD(base_pc, pc, opcodes); + if (opcodes.r8(pc-2) == 0x38) + decode_opcode(stream, &i386_opcode_table0F38[op2], op1, base_pc, pc, opcodes); else - decode_opcode(stream, &i386_opcode_table0F3A[op2], op1 ); + decode_opcode(stream, &i386_opcode_table0F3A[op2], op1, base_pc, pc, opcodes); return; case SEG_CS: @@ -2985,43 +2831,43 @@ static void decode_opcode(std::ostream &stream, const I386_OPCODE *op, uint8_t o case SEG_SS: rex = regex = sibex = rmex = 0; segment = op->flags; - op2 = FETCH(); - decode_opcode(stream, &i386_opcode_table1[op2], op2 ); + op2 = FETCH(base_pc, pc, opcodes); + decode_opcode(stream, &i386_opcode_table1[op2], op2, base_pc, pc, opcodes); return; case PREFIX: - op2 = FETCH(); + op2 = FETCH(base_pc, pc, opcodes); if ((op2 != 0x0f) && (op2 != 0x90)) util::stream_format(stream, "%-7s ", op->mnemonic ); if ((op2 == 0x90) && !pre0f) pre0f = op1; - decode_opcode(stream, &i386_opcode_table1[op2], op2 ); + decode_opcode(stream, &i386_opcode_table1[op2], op2, base_pc, pc, opcodes); return; case GROUP: - handle_modrm( modrm_string ); + handle_modrm(modrm_string, base_pc, pc, opcodes); for( i=0; i < ARRAY_LENGTH(group_op_table); i++ ) { if( strcmp(op->mnemonic, group_op_table[i].mnemonic) == 0 ) { if (op->flags & GROUP_MOD) - decode_opcode(stream, &group_op_table[i].opcode[MODRM_MOD], op1 ); + decode_opcode(stream, &group_op_table[i].opcode[MODRM_MOD()], op1, base_pc, pc, opcodes); else - decode_opcode(stream, &group_op_table[i].opcode[MODRM_REG1], op1 ); + decode_opcode(stream, &group_op_table[i].opcode[MODRM_REG1()], op1, base_pc, pc, opcodes); return; } } goto handle_unknown; case FPU: - op2 = FETCHD(); - handle_fpu(stream, op1, op2); + op2 = FETCHD(base_pc, pc, opcodes); + handle_fpu(stream, op1, op2, base_pc, pc, opcodes); return; case MODRM: - handle_modrm( modrm_string ); + handle_modrm(modrm_string, base_pc, pc, opcodes); break; } - if ((op->flags & ALWAYS64) && curmode == 64) + if ((op->flags & ALWAYS64) && m_config->get_mode() == 64) operand_size = 2; if ((op->flags & VAR_NAME) && operand_size > 0) @@ -3044,17 +2890,17 @@ static void decode_opcode(std::ostream &stream, const I386_OPCODE *op, uint8_t o dasm_flags = op->dasm_flags; if( op->param1 != 0 ) { - handle_param(stream, op->param1 ); + handle_param(stream, op->param1, base_pc, pc, opcodes); } if( op->param2 != 0 ) { util::stream_format(stream, "," ); - handle_param(stream, op->param2 ); + handle_param(stream, op->param2, base_pc, pc, opcodes); } if( op->param3 != 0 ) { util::stream_format(stream, "," ); - handle_param(stream, op->param3 ); + handle_param(stream, op->param3, base_pc, pc, opcodes); } return; @@ -3062,12 +2908,12 @@ handle_unknown: util::stream_format(stream, "???"); } -int i386_dasm_one_ex(std::ostream &stream, uint64_t eip, const uint8_t *oprom, int mode) +offs_t i386_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { + offs_t base_pc = pc; uint8_t op; - opcode_ptr = opcode_ptr_base = oprom; - switch(mode) + switch(m_config->get_mode()) { case 1: /* 8086/8088/80186/80188 */ address_size = 0; @@ -3095,37 +2941,24 @@ int i386_dasm_one_ex(std::ostream &stream, uint64_t eip, const uint8_t *oprom, i max_length = 15; break; } - pc = eip; dasm_flags = 0; segment = 0; - curmode = mode; pre0f = 0; rex = regex = sibex = rmex = 0; address_prefix = 0; operand_prefix = 0; - op = FETCH(); + op = FETCH(base_pc, pc, opcodes); - decode_opcode( stream, &i386_opcode_table1[op], op ); - return (pc-eip) | dasm_flags | DASMFLAG_SUPPORTED; -} - -int i386_dasm_one(std::ostream &stream, offs_t eip, const uint8_t *oprom, int mode) -{ - return i386_dasm_one_ex(stream, eip, oprom, mode); -} - -CPU_DISASSEMBLE( x86_16 ) -{ - return i386_dasm_one_ex(stream, pc, oprom, 16); + decode_opcode( stream, &i386_opcode_table1[op], op, base_pc, pc, opcodes); + return (pc-base_pc) | dasm_flags | SUPPORTED; } -CPU_DISASSEMBLE( x86_32 ) +i386_disassembler::i386_disassembler(config *conf) : m_config(conf) { - return i386_dasm_one_ex(stream, pc, oprom, 32); } -CPU_DISASSEMBLE( x86_64 ) +u32 i386_disassembler::opcode_alignment() const { - return i386_dasm_one_ex(stream, pc, oprom, 64); + return 1; } diff --git a/src/devices/cpu/i386/i386dasm.h b/src/devices/cpu/i386/i386dasm.h index 42142bee675..25f5ec0d4d6 100644 --- a/src/devices/cpu/i386/i386dasm.h +++ b/src/devices/cpu/i386/i386dasm.h @@ -1,5 +1,216 @@ // license:BSD-3-Clause // copyright-holders:Ville Linde, Peter Ferrie -extern int i386_dasm_one(std::ostream &stream, uint32_t pc, const uint8_t *oprom, int mode); -extern int i386_dasm_one_ex(std::ostream &stream, uint64_t eip, const uint8_t *oprom, int mode); +#ifndef MAME_CPU_I386_I386DASM_H +#define MAME_CPU_I386_I386DASM_H + +#pragma once + +class i386_disassembler : public util::disasm_interface +{ +public: + class config { + public: + virtual ~config() = default; + virtual int get_mode() const = 0; + }; + + i386_disassembler(config *conf); + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum + { + PARAM_REG = 1, /* 16 or 32-bit register */ + PARAM_REG8, /* 8-bit register */ + PARAM_REG16, /* 16-bit register */ + PARAM_REG32, /* 32-bit register */ + PARAM_REG3264, /* 32-bit or 64-bit register */ + PARAM_REG2_32, /* 32-bit register */ + PARAM_MMX, /* MMX register */ + PARAM_MMX2, /* MMX register in modrm */ + PARAM_XMM, /* XMM register */ + PARAM_RM, /* 16 or 32-bit memory or register */ + PARAM_RM8, /* 8-bit memory or register */ + PARAM_RM16, /* 16-bit memory or register */ + PARAM_RM32, /* 32-bit memory or register */ + PARAM_RMPTR, /* 16 or 32-bit memory or register */ + PARAM_RMPTR8, /* 8-bit memory or register */ + PARAM_RMPTR16, /* 16-bit memory or register */ + PARAM_RMPTR32, /* 32-bit memory or register */ + PARAM_RMXMM, /* 32 or 64-bit memory or register */ + PARAM_REGORXMM, /* 32 or 64-bit register or XMM register */ + PARAM_M64, /* 64-bit memory */ + PARAM_M64PTR, /* 64-bit memory */ + PARAM_MMXM, /* 64-bit memory or MMX register */ + PARAM_XMMM, /* 128-bit memory or XMM register */ + PARAM_I4, /* 4-bit signed immediate */ + PARAM_I8, /* 8-bit signed immediate */ + PARAM_I16, /* 16-bit signed immediate */ + PARAM_UI8, /* 8-bit unsigned immediate */ + PARAM_UI16, /* 16-bit unsigned immediate */ + PARAM_IMM, /* 16 or 32-bit immediate */ + PARAM_IMM64, /* 16, 32 or 64-bit immediate */ + PARAM_ADDR, /* 16:16 or 16:32 address */ + PARAM_REL, /* 16 or 32-bit PC-relative displacement */ + PARAM_REL8, /* 8-bit PC-relative displacement */ + PARAM_MEM_OFFS, /* 16 or 32-bit mem offset */ + PARAM_PREIMP, /* prefix with implicit register */ + PARAM_SREG, /* segment register */ + PARAM_CREG, /* control register */ + PARAM_DREG, /* debug register */ + PARAM_TREG, /* test register */ + PARAM_1, /* used by shift/rotate instructions */ + PARAM_AL, + PARAM_CL, + PARAM_DL, + PARAM_BL, + PARAM_AH, + PARAM_CH, + PARAM_DH, + PARAM_BH, + PARAM_DX, + PARAM_EAX, /* EAX or AX */ + PARAM_ECX, /* ECX or CX */ + PARAM_EDX, /* EDX or DX */ + PARAM_EBX, /* EBX or BX */ + PARAM_ESP, /* ESP or SP */ + PARAM_EBP, /* EBP or BP */ + PARAM_ESI, /* ESI or SI */ + PARAM_EDI, /* EDI or DI */ + PARAM_XMM0, + PARAM_XMM64, /* 64-bit memory or XMM register */ + PARAM_XMM32, /* 32-bit memory or XMM register */ + PARAM_XMM16 /* 16-bit memory or XMM register */ + }; + + enum + { + MODRM = 1, + GROUP, + FPU, + OP_SIZE, + ADDR_SIZE, + TWO_BYTE, + PREFIX, + SEG_CS, + SEG_DS, + SEG_ES, + SEG_FS, + SEG_GS, + SEG_SS, + ISREX, + THREE_BYTE /* [prefix] 0f op1 op2 and then mod/rm */ + }; + + enum { + FLAGS_MASK = 0x0ff, + VAR_NAME = 0x100, + VAR_NAME4 = 0x200, + ALWAYS64 = 0x400, + SPECIAL64 = 0x800, + GROUP_MOD = 0x1000 + }; + + struct I386_OPCODE { + const char *mnemonic; + u32 flags; + u32 param1; + u32 param2; + u32 param3; + offs_t dasm_flags; + }; + + struct GROUP_OP { + char mnemonic[32]; + const I386_OPCODE *opcode; + }; + + static constexpr u32 SPECIAL64_ENT(u32 x) { + return SPECIAL64 | (x << 24); + } + + static const I386_OPCODE i386_opcode_table1[256]; + static const I386_OPCODE x64_opcode_alt[]; + static const I386_OPCODE i386_opcode_table2[256]; + static const I386_OPCODE i386_opcode_table0F38[256]; + static const I386_OPCODE i386_opcode_table0F3A[256]; + static const I386_OPCODE group80_table[8]; + static const I386_OPCODE group81_table[8]; + static const I386_OPCODE group83_table[8]; + static const I386_OPCODE groupC0_table[8]; + static const I386_OPCODE groupC1_table[8]; + static const I386_OPCODE groupD0_table[8]; + static const I386_OPCODE groupD1_table[8]; + static const I386_OPCODE groupD2_table[8]; + static const I386_OPCODE groupD3_table[8]; + static const I386_OPCODE groupF6_table[8]; + static const I386_OPCODE groupF7_table[8]; + static const I386_OPCODE groupFE_table[8]; + static const I386_OPCODE groupFF_table[8]; + static const I386_OPCODE group0F00_table[8]; + static const I386_OPCODE group0F01_table[8]; + static const I386_OPCODE group0F0D_table[8]; + static const I386_OPCODE group0F12_table[4]; + static const I386_OPCODE group0F16_table[4]; + static const I386_OPCODE group0F18_table[8]; + static const I386_OPCODE group0F71_table[8]; + static const I386_OPCODE group0F72_table[8]; + static const I386_OPCODE group0F73_table[8]; + static const I386_OPCODE group0FAE_table[8]; + static const I386_OPCODE group0FBA_table[8]; + static const I386_OPCODE group0FC7_table[8]; + static const GROUP_OP group_op_table[]; + static const char *const i386_reg[3][16]; + static const char *const i386_reg8[8]; + static const char *const i386_reg8rex[16]; + static const char *const i386_sreg[8]; + + config *m_config; + + int address_size; + int operand_size; + int address_prefix; + int operand_prefix; + int max_length; + uint8_t modrm; + uint32_t segment; + offs_t dasm_flags; + std::string modrm_string; + uint8_t rex, regex, sibex, rmex; + uint8_t pre0f; + + inline u8 MODRM_REG1() const { + return (modrm >> 3) & 0x7; + } + + inline u8 MODRM_REG2() const { + return modrm & 0x7; + } + + inline u8 MODRM_MOD() const { + return (modrm >> 6) & 0x7; + } + + inline uint8_t FETCH(offs_t base_pc, offs_t &pc, const data_buffer &opcodes); + inline uint16_t FETCH16(offs_t base_pc, offs_t &pc, const data_buffer &opcodes); + inline uint32_t FETCH32(offs_t base_pc, offs_t &pc, const data_buffer &opcodes); + inline uint8_t FETCHD(offs_t base_pc, offs_t &pc, const data_buffer &opcodes); + inline uint16_t FETCHD16(offs_t base_pc, offs_t &pc, const data_buffer &opcodes); + inline uint32_t FETCHD32(offs_t base_pc, offs_t &pc, const data_buffer &opcodes); + + char *hexstring(uint32_t value, int digits); + char *hexstring64(uint32_t lo, uint32_t hi); + char *hexstringpc(uint64_t pc); + char *shexstring(uint32_t value, int digits, bool always); + void handle_sib_byte(std::ostream &stream, uint8_t mod, offs_t base_pc, offs_t &pc, const data_buffer &opcodes); + void handle_modrm(std::ostream &stream, offs_t base_pc, offs_t &pc, const data_buffer &opcodes); + void handle_modrm(std::string &buffer, offs_t base_pc, offs_t &pc, const data_buffer &opcodes); + void handle_param(std::ostream &stream, uint32_t param, offs_t base_pc, offs_t &pc, const data_buffer &opcodes); + void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2, offs_t base_pc, offs_t &pc, const data_buffer &opcodes); + void decode_opcode(std::ostream &stream, const I386_OPCODE *op, uint8_t op1, offs_t base_pc, offs_t &pc, const data_buffer &opcodes); +}; + +#endif diff --git a/src/devices/cpu/i8008/8008dasm.cpp b/src/devices/cpu/i8008/8008dasm.cpp index 66be08a40b7..88d2cacf88b 100644 --- a/src/devices/cpu/i8008/8008dasm.cpp +++ b/src/devices/cpu/i8008/8008dasm.cpp @@ -9,18 +9,21 @@ *****************************************************************************/ #include "emu.h" +#include "8008dasm.h" -#define OP(A) oprom[(A) - PC] -#define ARG(A) opram[(A) - PC] +const char i8008_disassembler::reg[] = { 'a', 'b', 'c', 'd', 'e', 'h', 'l', 'm' }; +const char i8008_disassembler::flag_names[] = { 'c', 'z', 's', 'p' }; -static const char reg[] = { 'a', 'b', 'c', 'd', 'e', 'h', 'l', 'm' }; -static const char flag_names[] = { 'c', 'z', 's', 'p' }; +u32 i8008_disassembler::opcode_alignment() const +{ + return 1; +} -CPU_DISASSEMBLE(i8008) +offs_t i8008_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint32_t flags = 0; unsigned PC = pc; - uint8_t op = OP(pc++); + uint8_t op = opcodes.r8(pc++); switch (op >> 6) { case 0x03: // starting with 11 @@ -65,28 +68,28 @@ CPU_DISASSEMBLE(i8008) case 3 : util::stream_format(stream, "r%c%c",(BIT(op,5) ? 't' : 'f'),flag_names[(op>>3)&3]); break; case 4 : { switch((op >> 3) & 7) { - case 0 : util::stream_format(stream, "adi %02x",ARG(pc)); pc++; break; - case 1 : util::stream_format(stream, "aci %02x",ARG(pc)); pc++; break; - case 2 : util::stream_format(stream, "sui %02x",ARG(pc)); pc++; break; - case 3 : util::stream_format(stream, "sbi %02x",ARG(pc)); pc++; break; - case 4 : util::stream_format(stream, "ndi %02x",ARG(pc)); pc++; break; - case 5 : util::stream_format(stream, "xri %02x",ARG(pc)); pc++; break; - case 6 : util::stream_format(stream, "ori %02x",ARG(pc)); pc++; break; - case 7 : util::stream_format(stream, "cpi %02x",ARG(pc)); pc++; break; + case 0 : util::stream_format(stream, "adi %02x",params.r8(pc)); pc++; break; + case 1 : util::stream_format(stream, "aci %02x",params.r8(pc)); pc++; break; + case 2 : util::stream_format(stream, "sui %02x",params.r8(pc)); pc++; break; + case 3 : util::stream_format(stream, "sbi %02x",params.r8(pc)); pc++; break; + case 4 : util::stream_format(stream, "ndi %02x",params.r8(pc)); pc++; break; + case 5 : util::stream_format(stream, "xri %02x",params.r8(pc)); pc++; break; + case 6 : util::stream_format(stream, "ori %02x",params.r8(pc)); pc++; break; + case 7 : util::stream_format(stream, "cpi %02x",params.r8(pc)); pc++; break; } } break; case 5 : util::stream_format(stream, "rst %02x",(op>>3) & 7); break; - case 6 : util::stream_format(stream, "l%ci %02x",reg[(op >> 3) & 7],ARG(pc)); pc++; break; + case 6 : util::stream_format(stream, "l%ci %02x",reg[(op >> 3) & 7],params.r8(pc)); pc++; break; case 7 : util::stream_format(stream, "ret"); break; } break; case 0x01: // starting with 01 switch(op & 7) { - case 0 : util::stream_format(stream, "j%c%c %02x%02x",(BIT(op,5)? 't' : 'f'),flag_names[(op>>3)&3], ARG(pc+1) & 0x3f,ARG(pc)); pc+=2; break; - case 2 : util::stream_format(stream, "c%c%c %02x%02x",(BIT(op,5)? 't' : 'f'),flag_names[(op>>3)&3], ARG(pc+1) & 0x3f,ARG(pc)); pc+=2; break; - case 4 : util::stream_format(stream, "jmp %02x%02x",ARG(pc+1) & 0x3f,ARG(pc)); pc+=2; break; - case 6 : util::stream_format(stream, "cal %02x%02x",ARG(pc+1) & 0x3f,ARG(pc)); pc+=2; break; + case 0 : util::stream_format(stream, "j%c%c %02x%02x",(BIT(op,5)? 't' : 'f'),flag_names[(op>>3)&3], params.r8(pc+1) & 0x3f,params.r8(pc)); pc+=2; break; + case 2 : util::stream_format(stream, "c%c%c %02x%02x",(BIT(op,5)? 't' : 'f'),flag_names[(op>>3)&3], params.r8(pc+1) & 0x3f,params.r8(pc)); pc+=2; break; + case 4 : util::stream_format(stream, "jmp %02x%02x",params.r8(pc+1) & 0x3f,params.r8(pc)); pc+=2; break; + case 6 : util::stream_format(stream, "cal %02x%02x",params.r8(pc+1) & 0x3f,params.r8(pc)); pc+=2; break; case 1 : case 3 : case 5 : @@ -111,5 +114,5 @@ CPU_DISASSEMBLE(i8008) } break; } - return (pc - PC) | flags | DASMFLAG_SUPPORTED; + return (pc - PC) | flags | SUPPORTED; } diff --git a/src/devices/cpu/i8008/8008dasm.h b/src/devices/cpu/i8008/8008dasm.h new file mode 100644 index 00000000000..a5cb209dda6 --- /dev/null +++ b/src/devices/cpu/i8008/8008dasm.h @@ -0,0 +1,31 @@ +// license:BSD-3-Clause +// copyright-holders:Miodrag Milanovic +/***************************************************************************** + * + * 8008dasm.c + * + * Intel 8008 CPU Disassembly + * + *****************************************************************************/ + +#ifndef MAME_CPU_I8008_8008DASM_H +#define MAME_CPU_I8008_8008DASM_H + +#pragma once + +class i8008_disassembler : public util::disasm_interface +{ +public: + i8008_disassembler() = default; + virtual ~i8008_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char reg[]; + static const char flag_names[]; + +}; + +#endif diff --git a/src/devices/cpu/i8008/i8008.cpp b/src/devices/cpu/i8008/i8008.cpp index 6baa28a766b..9b687eec92a 100644 --- a/src/devices/cpu/i8008/i8008.cpp +++ b/src/devices/cpu/i8008/i8008.cpp @@ -9,6 +9,7 @@ *****************************************************************************/ #include "emu.h" #include "i8008.h" +#include "8008dasm.h" #include "debugger.h" //************************************************************************** @@ -52,7 +53,7 @@ void i8008_device::device_start() { // find address spaces m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); // save state @@ -203,34 +204,13 @@ void i8008_device::state_string_export(const device_state_entry &entry, std::str } //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t i8008_device::disasm_min_opcode_bytes() const -{ - return 1; -} - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t i8008_device::disasm_max_opcode_bytes() const -{ - return 3; -} - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t i8008_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *i8008_device::create_disassembler() { - extern CPU_DISASSEMBLE( i8008 ); - return CPU_DISASSEMBLE_NAME(i8008)(this, stream, pc, oprom, opram, options); + return new i8008_disassembler; } //************************************************************************** diff --git a/src/devices/cpu/i8008/i8008.h b/src/devices/cpu/i8008/i8008.h index b6450fcf5e5..ea473df22af 100644 --- a/src/devices/cpu/i8008/i8008.h +++ b/src/devices/cpu/i8008/i8008.h @@ -42,11 +42,8 @@ protected: virtual void state_export(const device_state_entry &entry) override; virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; - // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void execute_one(int opcode); @@ -86,7 +83,7 @@ protected: address_space *m_program; address_space *m_io; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; }; // device type definition diff --git a/src/devices/cpu/i8085/8085dasm.cpp b/src/devices/cpu/i8085/8085dasm.cpp index 5f898c86464..36d4640afb5 100644 --- a/src/devices/cpu/i8085/8085dasm.cpp +++ b/src/devices/cpu/i8085/8085dasm.cpp @@ -2,544 +2,284 @@ // copyright-holders:Juergen Buchmueller /***************************************************************************** * - * 8085dasm.c * Portable I8085A disassembler * + * TODO: + * - add I8080? + * *****************************************************************************/ #include "emu.h" +#include "8085dasm.h" -/* 8080/8085A mnemonics were more irritation than information - What would you guess "CP $3456" to mean? It's not compare, - but call if plus ... therefore: */ -//#define Z80_MNEMONICS - -#define OP(A) oprom[(A) - PC] -#define ARG(A) opram[(A) - PC] -#define ARGW(A) (opram[(A) - PC] | (opram[(A) + 1 - PC] << 8)) +u32 i8085_disassembler::opcode_alignment() const +{ + return 1; +} -CPU_DISASSEMBLE(i8085) +offs_t i8085_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - uint32_t flags = 0; + offs_t flags = 0; uint8_t op; - unsigned PC = pc; - switch (op = OP(pc++)) + unsigned prevpc = pc; + switch (op = opcodes.r8(pc++)) { -#ifdef Z80_MNEMONICS - case 0x00: util::stream_format(stream, "nop"); break; - case 0x01: util::stream_format(stream, "ld bc,$%04x", ARGW(pc)); pc+=2; break; - case 0x02: util::stream_format(stream, "ld (bc),a"); break; - case 0x03: util::stream_format(stream, "inc bc"); break; - case 0x04: util::stream_format(stream, "inc b"); break; - case 0x05: util::stream_format(stream, "dec b"); break; - case 0x06: util::stream_format(stream, "ld b,$%02x", ARG(pc)); pc++; break; - case 0x07: util::stream_format(stream, "rlca"); break; - case 0x08: util::stream_format(stream, "sub hl,bc (*)"); break; - case 0x09: util::stream_format(stream, "add hl,bc"); break; - case 0x0a: util::stream_format(stream, "ld a,(bc)"); break; - case 0x0b: util::stream_format(stream, "dec bc"); break; - case 0x0c: util::stream_format(stream, "inc c"); break; - case 0x0d: util::stream_format(stream, "dec c"); break; - case 0x0e: util::stream_format(stream, "ld c,$%02x", ARG(pc)); pc++; break; - case 0x0f: util::stream_format(stream, "rrca"); break; - case 0x10: util::stream_format(stream, "sra hl (*)"); break; - case 0x11: util::stream_format(stream, "ld de,$%04x", ARGW(pc)); pc+=2; break; - case 0x12: util::stream_format(stream, "ld (de),a"); break; - case 0x13: util::stream_format(stream, "inc de"); break; - case 0x14: util::stream_format(stream, "inc d"); break; - case 0x15: util::stream_format(stream, "dec d"); break; - case 0x16: util::stream_format(stream, "ld d,$%02x", ARG(pc)); pc++; break; - case 0x17: util::stream_format(stream, "rla"); break; - case 0x18: util::stream_format(stream, "rl de (*)"); break; - case 0x19: util::stream_format(stream, "add hl,de"); break; - case 0x1a: util::stream_format(stream, "ld a,(de)"); break; - case 0x1b: util::stream_format(stream, "dec de"); break; - case 0x1c: util::stream_format(stream, "inc e"); break; - case 0x1d: util::stream_format(stream, "dec e"); break; - case 0x1e: util::stream_format(stream, "ld e,$%02x", ARG(pc)); pc++; break; - case 0x1f: util::stream_format(stream, "rra"); break; - case 0x20: util::stream_format(stream, "rim"); break; - case 0x21: util::stream_format(stream, "ld hl,$%04x", ARGW(pc)); pc+=2; break; - case 0x22: util::stream_format(stream, "ld ($%04x),hl", ARGW(pc)); pc+=2;break; - case 0x23: util::stream_format(stream, "inc hl"); break; - case 0x24: util::stream_format(stream, "inc h"); break; - case 0x25: util::stream_format(stream, "dec h"); break; - case 0x26: util::stream_format(stream, "ld h,$%02x", ARG(pc)); pc++; break; - case 0x27: util::stream_format(stream, "daa"); break; - case 0x28: util::stream_format(stream, "ld de,hl+$%02x (*)",ARG(pc));pc++;break; - case 0x29: util::stream_format(stream, "add hl,hl"); break; - case 0x2a: util::stream_format(stream, "ld hl,($%04x)", ARGW(pc)); pc+=2;break; - case 0x2b: util::stream_format(stream, "dec hl"); break; - case 0x2c: util::stream_format(stream, "inc l"); break; - case 0x2d: util::stream_format(stream, "dec l"); break; - case 0x2e: util::stream_format(stream, "ld l,$%02x", ARG(pc)); pc++; break; - case 0x2f: util::stream_format(stream, "cpl"); break; - case 0x30: util::stream_format(stream, "sim"); break; - case 0x31: util::stream_format(stream, "ld sp,$%04x", ARGW(pc)); pc+=2; break; - case 0x32: util::stream_format(stream, "ld ($%04x),a", ARGW(pc)); pc+=2; break; - case 0x33: util::stream_format(stream, "inc sp"); break; - case 0x34: util::stream_format(stream, "inc (hl)"); break; - case 0x35: util::stream_format(stream, "dec (hl)"); break; - case 0x36: util::stream_format(stream, "ld (hl),$%02x", ARG(pc)); pc++; break; - case 0x37: util::stream_format(stream, "scf"); break; - case 0x38: util::stream_format(stream, "ld de,sp+$%02x (*)",ARG(pc));pc++;break; - case 0x39: util::stream_format(stream, "add hl,sp"); break; - case 0x3a: util::stream_format(stream, "ld a,($%04x)", ARGW(pc)); pc+=2; break; - case 0x3b: util::stream_format(stream, "dec sp"); break; - case 0x3c: util::stream_format(stream, "inc a"); break; - case 0x3d: util::stream_format(stream, "dec a"); break; - case 0x3e: util::stream_format(stream, "ld a,$%02x", ARG(pc)); pc++; break; - case 0x3f: util::stream_format(stream, "ccf"); break; - case 0x40: util::stream_format(stream, "ld b,b"); break; - case 0x41: util::stream_format(stream, "ld b,c"); break; - case 0x42: util::stream_format(stream, "ld b,d"); break; - case 0x43: util::stream_format(stream, "ld b,e"); break; - case 0x44: util::stream_format(stream, "ld b,h"); break; - case 0x45: util::stream_format(stream, "ld b,l"); break; - case 0x46: util::stream_format(stream, "ld b,(hl)"); break; - case 0x47: util::stream_format(stream, "ld b,a"); break; - case 0x48: util::stream_format(stream, "ld c,b"); break; - case 0x49: util::stream_format(stream, "ld c,c"); break; - case 0x4a: util::stream_format(stream, "ld c,d"); break; - case 0x4b: util::stream_format(stream, "ld c,e"); break; - case 0x4c: util::stream_format(stream, "ld c,h"); break; - case 0x4d: util::stream_format(stream, "ld c,l"); break; - case 0x4e: util::stream_format(stream, "ld c,(hl)"); break; - case 0x4f: util::stream_format(stream, "ld c,a"); break; - case 0x50: util::stream_format(stream, "ld d,b"); break; - case 0x51: util::stream_format(stream, "ld d,c"); break; - case 0x52: util::stream_format(stream, "ld d,d"); break; - case 0x53: util::stream_format(stream, "ld d,e"); break; - case 0x54: util::stream_format(stream, "ld d,h"); break; - case 0x55: util::stream_format(stream, "ld d,l"); break; - case 0x56: util::stream_format(stream, "ld d,(hl)"); break; - case 0x57: util::stream_format(stream, "ld d,a"); break; - case 0x58: util::stream_format(stream, "ld e,b"); break; - case 0x59: util::stream_format(stream, "ld e,c"); break; - case 0x5a: util::stream_format(stream, "ld e,d"); break; - case 0x5b: util::stream_format(stream, "ld e,e"); break; - case 0x5c: util::stream_format(stream, "ld e,h"); break; - case 0x5d: util::stream_format(stream, "ld e,l"); break; - case 0x5e: util::stream_format(stream, "ld e,(hl)"); break; - case 0x5f: util::stream_format(stream, "ld e,a"); break; - case 0x60: util::stream_format(stream, "ld h,b"); break; - case 0x61: util::stream_format(stream, "ld h,c"); break; - case 0x62: util::stream_format(stream, "ld h,d"); break; - case 0x63: util::stream_format(stream, "ld h,e"); break; - case 0x64: util::stream_format(stream, "ld h,h"); break; - case 0x65: util::stream_format(stream, "ld h,l"); break; - case 0x66: util::stream_format(stream, "ld h,(hl)"); break; - case 0x67: util::stream_format(stream, "ld h,a"); break; - case 0x68: util::stream_format(stream, "ld l,b"); break; - case 0x69: util::stream_format(stream, "ld l,c"); break; - case 0x6a: util::stream_format(stream, "ld l,d"); break; - case 0x6b: util::stream_format(stream, "ld l,e"); break; - case 0x6c: util::stream_format(stream, "ld l,h"); break; - case 0x6d: util::stream_format(stream, "ld l,l"); break; - case 0x6e: util::stream_format(stream, "ld l,(hl)"); break; - case 0x6f: util::stream_format(stream, "ld l,a"); break; - case 0x70: util::stream_format(stream, "ld (hl),b"); break; - case 0x71: util::stream_format(stream, "ld (hl),c"); break; - case 0x72: util::stream_format(stream, "ld (hl),d"); break; - case 0x73: util::stream_format(stream, "ld (hl),e"); break; - case 0x74: util::stream_format(stream, "ld (hl),h"); break; - case 0x75: util::stream_format(stream, "ld (hl),l"); break; - case 0x76: util::stream_format(stream, "halt"); break; - case 0x77: util::stream_format(stream, "ld (hl),a"); break; - case 0x78: util::stream_format(stream, "ld a,b"); break; - case 0x79: util::stream_format(stream, "ld a,c"); break; - case 0x7a: util::stream_format(stream, "ld a,d"); break; - case 0x7b: util::stream_format(stream, "ld a,e"); break; - case 0x7c: util::stream_format(stream, "ld a,h"); break; - case 0x7d: util::stream_format(stream, "ld a,l"); break; - case 0x7e: util::stream_format(stream, "ld a,(hl)"); break; - case 0x7f: util::stream_format(stream, "ld a,a"); break; - case 0x80: util::stream_format(stream, "add a,b"); break; - case 0x81: util::stream_format(stream, "add a,c"); break; - case 0x82: util::stream_format(stream, "add a,d"); break; - case 0x83: util::stream_format(stream, "add a,e"); break; - case 0x84: util::stream_format(stream, "add a,h"); break; - case 0x85: util::stream_format(stream, "add a,l"); break; - case 0x86: util::stream_format(stream, "add a,(hl)"); break; - case 0x87: util::stream_format(stream, "add a,a"); break; - case 0x88: util::stream_format(stream, "adc a,b"); break; - case 0x89: util::stream_format(stream, "adc a,c"); break; - case 0x8a: util::stream_format(stream, "adc a,d"); break; - case 0x8b: util::stream_format(stream, "adc a,e"); break; - case 0x8c: util::stream_format(stream, "adc a,h"); break; - case 0x8d: util::stream_format(stream, "adc a,l"); break; - case 0x8e: util::stream_format(stream, "adc a,(hl)"); break; - case 0x8f: util::stream_format(stream, "adc a,a"); break; - case 0x90: util::stream_format(stream, "sub b"); break; - case 0x91: util::stream_format(stream, "sub c"); break; - case 0x92: util::stream_format(stream, "sub d"); break; - case 0x93: util::stream_format(stream, "sub e"); break; - case 0x94: util::stream_format(stream, "sub h"); break; - case 0x95: util::stream_format(stream, "sub l"); break; - case 0x96: util::stream_format(stream, "sub (hl)"); break; - case 0x97: util::stream_format(stream, "sub a"); break; - case 0x98: util::stream_format(stream, "sbc a,b"); break; - case 0x99: util::stream_format(stream, "sbc a,c"); break; - case 0x9a: util::stream_format(stream, "sbc a,d"); break; - case 0x9b: util::stream_format(stream, "sbc a,e"); break; - case 0x9c: util::stream_format(stream, "sbc a,h"); break; - case 0x9d: util::stream_format(stream, "sbc a,l"); break; - case 0x9e: util::stream_format(stream, "sbc a,(hl)"); break; - case 0x9f: util::stream_format(stream, "sbc a,a"); break; - case 0xa0: util::stream_format(stream, "and b"); break; - case 0xa1: util::stream_format(stream, "and c"); break; - case 0xa2: util::stream_format(stream, "and d"); break; - case 0xa3: util::stream_format(stream, "and e"); break; - case 0xa4: util::stream_format(stream, "and h"); break; - case 0xa5: util::stream_format(stream, "and l"); break; - case 0xa6: util::stream_format(stream, "and (hl)"); break; - case 0xa7: util::stream_format(stream, "and a"); break; - case 0xa8: util::stream_format(stream, "xor b"); break; - case 0xa9: util::stream_format(stream, "xor c"); break; - case 0xaa: util::stream_format(stream, "xor d"); break; - case 0xab: util::stream_format(stream, "xor e"); break; - case 0xac: util::stream_format(stream, "xor h"); break; - case 0xad: util::stream_format(stream, "xor l"); break; - case 0xae: util::stream_format(stream, "xor (hl)"); break; - case 0xaf: util::stream_format(stream, "xor a"); break; - case 0xb0: util::stream_format(stream, "or b"); break; - case 0xb1: util::stream_format(stream, "or c"); break; - case 0xb2: util::stream_format(stream, "or d"); break; - case 0xb3: util::stream_format(stream, "or e"); break; - case 0xb4: util::stream_format(stream, "or h"); break; - case 0xb5: util::stream_format(stream, "or l"); break; - case 0xb6: util::stream_format(stream, "or (hl)"); break; - case 0xb7: util::stream_format(stream, "or a"); break; - case 0xb8: util::stream_format(stream, "cp b"); break; - case 0xb9: util::stream_format(stream, "cp c"); break; - case 0xba: util::stream_format(stream, "cp d"); break; - case 0xbb: util::stream_format(stream, "cp e"); break; - case 0xbc: util::stream_format(stream, "cp h"); break; - case 0xbd: util::stream_format(stream, "cp l"); break; - case 0xbe: util::stream_format(stream, "cp (hl)"); break; - case 0xbf: util::stream_format(stream, "cp a"); break; - case 0xc0: util::stream_format(stream, "ret nz"); flags = DASMFLAG_STEP_OUT; break; - case 0xc1: util::stream_format(stream, "pop bc"); break; - case 0xc2: util::stream_format(stream, "jp nz,$%04x", ARGW(pc)); pc+=2; break; - case 0xc3: util::stream_format(stream, "jp $%04x", ARGW(pc)); pc+=2; break; - case 0xc4: util::stream_format(stream, "call nz,$%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break; - case 0xc5: util::stream_format(stream, "push bc"); break; - case 0xc6: util::stream_format(stream, "add a,$%02x", ARG(pc)); pc++; break; - case 0xc7: util::stream_format(stream, "rst $00"); flags = DASMFLAG_STEP_OVER; break; - case 0xc8: util::stream_format(stream, "ret z"); flags = DASMFLAG_STEP_OUT; break; - case 0xc9: util::stream_format(stream, "ret"); flags = DASMFLAG_STEP_OUT; break; - case 0xca: util::stream_format(stream, "jp z,$%04x", ARGW(pc)); pc+=2; break; - case 0xcb: util::stream_format(stream, "rst v,$40 (*)"); flags = DASMFLAG_STEP_OVER; break; - case 0xcc: util::stream_format(stream, "call z,$%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break; - case 0xcd: util::stream_format(stream, "call $%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break; - case 0xce: util::stream_format(stream, "adc a,$%02x", ARG(pc)); pc++; break; - case 0xcf: util::stream_format(stream, "rst $08"); flags = DASMFLAG_STEP_OVER; break; - case 0xd0: util::stream_format(stream, "ret nc"); flags = DASMFLAG_STEP_OUT; break; - case 0xd1: util::stream_format(stream, "pop de"); break; - case 0xd2: util::stream_format(stream, "jp nc,$%04x", ARGW(pc)); pc+=2; break; - case 0xd3: util::stream_format(stream, "out ($%02x),a", ARG(pc)); pc++; break; - case 0xd4: util::stream_format(stream, "call nc,$%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break; - case 0xd5: util::stream_format(stream, "push de"); break; - case 0xd6: util::stream_format(stream, "sub $%02x", ARG(pc)); pc++; break; - case 0xd7: util::stream_format(stream, "rst $10"); flags = DASMFLAG_STEP_OVER; break; - case 0xd8: util::stream_format(stream, "ret c"); break; - case 0xd9: util::stream_format(stream, "ld (de),hl (*)"); break; - case 0xda: util::stream_format(stream, "jp c,$%04x", ARGW(pc)); pc+=2; break; - case 0xdb: util::stream_format(stream, "in a,($%02x)", ARG(pc)); pc++; break; - case 0xdc: util::stream_format(stream, "call c,$%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break; - case 0xdd: util::stream_format(stream, "jp nx,$%04x (*)",ARGW(pc));pc+=2;break; - case 0xde: util::stream_format(stream, "sub $%02x", ARG(pc)); pc++; break; - case 0xdf: util::stream_format(stream, "rst $18"); flags = DASMFLAG_STEP_OVER; break; - case 0xe0: util::stream_format(stream, "ret pe"); break; - case 0xe1: util::stream_format(stream, "pop hl"); break; - case 0xe2: util::stream_format(stream, "jp pe,$%04x", ARGW(pc)); pc+=2; break; - case 0xe3: util::stream_format(stream, "ex (sp),hl"); break; - case 0xe4: util::stream_format(stream, "call pe,$%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break; - case 0xe5: util::stream_format(stream, "push hl"); break; - case 0xe6: util::stream_format(stream, "and $%02x", ARG(pc)); pc++; break; - case 0xe7: util::stream_format(stream, "rst $20"); flags = DASMFLAG_STEP_OVER; break; - case 0xe8: util::stream_format(stream, "ret po"); break; - case 0xe9: util::stream_format(stream, "jp (hl)"); break; - case 0xea: util::stream_format(stream, "jp po,$%04x", ARGW(pc)); pc+=2; break; - case 0xeb: util::stream_format(stream, "ex de,hl"); break; - case 0xec: util::stream_format(stream, "call po,$%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break; - case 0xed: util::stream_format(stream, "ld hl,(de) (*)"); break; - case 0xee: util::stream_format(stream, "xor $%02x", ARG(pc)); pc++; break; - case 0xef: util::stream_format(stream, "rst $28"); flags = DASMFLAG_STEP_OVER; break; - case 0xf0: util::stream_format(stream, "ret p"); break; - case 0xf1: util::stream_format(stream, "pop af"); break; - case 0xf2: util::stream_format(stream, "jp p,$%04x", ARGW(pc)); pc+=2; break; - case 0xf3: util::stream_format(stream, "di"); break; - case 0xf4: util::stream_format(stream, "cp $%04x", ARGW(pc)); pc+=2; break; - case 0xf5: util::stream_format(stream, "push af"); break; - case 0xf6: util::stream_format(stream, "or $%02x", ARG(pc)); pc++; break; - case 0xf7: util::stream_format(stream, "rst $30"); flags = DASMFLAG_STEP_OVER; break; - case 0xf8: util::stream_format(stream, "ret m"); break; - case 0xf9: util::stream_format(stream, "ld sp,hl"); break; - case 0xfa: util::stream_format(stream, "jp m,$%04x", ARGW(pc)); pc+=2; break; - case 0xfb: util::stream_format(stream, "ei"); break; - case 0xfc: util::stream_format(stream, "call m,$%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break; - case 0xfd: util::stream_format(stream, "jp x,$%04x (*)",ARGW(pc));pc+=2; break; - case 0xfe: util::stream_format(stream, "cp $%02x", ARG(pc)); pc++; break; - case 0xff: util::stream_format(stream, "rst $38"); flags = DASMFLAG_STEP_OVER; break; -#else - case 0x00: util::stream_format(stream, "nop"); break; - case 0x01: util::stream_format(stream, "lxi b,$%04x", ARGW(pc)); pc+=2; break; - case 0x02: util::stream_format(stream, "stax b"); break; - case 0x03: util::stream_format(stream, "inx b"); break; - case 0x04: util::stream_format(stream, "inr b"); break; - case 0x05: util::stream_format(stream, "dcr b"); break; - case 0x06: util::stream_format(stream, "mvi b,$%02x", ARG(pc)); pc++; break; - case 0x07: util::stream_format(stream, "rlc"); break; - case 0x08: util::stream_format(stream, "dsub (*)"); break; - case 0x09: util::stream_format(stream, "dad b"); break; - case 0x0a: util::stream_format(stream, "ldax b"); break; - case 0x0b: util::stream_format(stream, "dcx b"); break; - case 0x0c: util::stream_format(stream, "inr c"); break; - case 0x0d: util::stream_format(stream, "dcr c"); break; - case 0x0e: util::stream_format(stream, "mvi c,$%02x", ARG(pc)); pc++; break; - case 0x0f: util::stream_format(stream, "rrc"); break; - case 0x10: util::stream_format(stream, "asrh (*)"); break; - case 0x11: util::stream_format(stream, "lxi d,$%04x", ARGW(pc)); pc+=2; break; - case 0x12: util::stream_format(stream, "stax d"); break; - case 0x13: util::stream_format(stream, "inx d"); break; - case 0x14: util::stream_format(stream, "inr d"); break; - case 0x15: util::stream_format(stream, "dcr d"); break; - case 0x16: util::stream_format(stream, "mvi d,$%02x", ARG(pc)); pc++; break; - case 0x17: util::stream_format(stream, "ral"); break; - case 0x18: util::stream_format(stream, "rlde (*)"); break; - case 0x19: util::stream_format(stream, "dad d"); break; - case 0x1a: util::stream_format(stream, "ldax d"); break; - case 0x1b: util::stream_format(stream, "dcx d"); break; - case 0x1c: util::stream_format(stream, "inr e"); break; - case 0x1d: util::stream_format(stream, "dcr e"); break; - case 0x1e: util::stream_format(stream, "mvi e,$%02x", ARG(pc)); pc++; break; - case 0x1f: util::stream_format(stream, "rar"); break; - case 0x20: util::stream_format(stream, "rim"); break; - case 0x21: util::stream_format(stream, "lxi h,$%04x", ARGW(pc)); pc+=2; break; - case 0x22: util::stream_format(stream, "shld $%04x", ARGW(pc)); pc+=2; break; - case 0x23: util::stream_format(stream, "inx h"); break; - case 0x24: util::stream_format(stream, "inr h"); break; - case 0x25: util::stream_format(stream, "dcr h"); break; - case 0x26: util::stream_format(stream, "mvi h,$%02x", ARG(pc)); pc++; break; - case 0x27: util::stream_format(stream, "daa"); break; - case 0x28: util::stream_format(stream, "ldeh $%02x (*)", ARG(pc)); pc++; break; - case 0x29: util::stream_format(stream, "dad h"); break; - case 0x2a: util::stream_format(stream, "lhld $%04x", ARGW(pc)); pc+=2; break; - case 0x2b: util::stream_format(stream, "dcx h"); break; - case 0x2c: util::stream_format(stream, "inr l"); break; - case 0x2d: util::stream_format(stream, "dcr l"); break; - case 0x2e: util::stream_format(stream, "mvi l,$%02x", ARG(pc)); pc++; break; - case 0x2f: util::stream_format(stream, "cma"); break; - case 0x30: util::stream_format(stream, "sim"); break; - case 0x31: util::stream_format(stream, "lxi sp,$%04x", ARGW(pc)); pc+=2; break; - case 0x32: util::stream_format(stream, "stax $%04x", ARGW(pc)); pc+=2; break; - case 0x33: util::stream_format(stream, "inx sp"); break; - case 0x34: util::stream_format(stream, "inr m"); break; - case 0x35: util::stream_format(stream, "dcr m"); break; - case 0x36: util::stream_format(stream, "mvi m,$%02x", ARG(pc)); pc++; break; - case 0x37: util::stream_format(stream, "stc"); break; - case 0x38: util::stream_format(stream, "ldes $%02x (*)", ARG(pc)); pc++; break; - case 0x39: util::stream_format(stream, "dad sp"); break; - case 0x3a: util::stream_format(stream, "ldax $%04x", ARGW(pc)); pc+=2; break; - case 0x3b: util::stream_format(stream, "dcx sp"); break; - case 0x3c: util::stream_format(stream, "inr a"); break; - case 0x3d: util::stream_format(stream, "dcr a"); break; - case 0x3e: util::stream_format(stream, "mvi a,$%02x", ARG(pc)); pc++; break; - case 0x3f: util::stream_format(stream, "cmc"); break; - case 0x40: util::stream_format(stream, "mov b,b"); break; - case 0x41: util::stream_format(stream, "mov b,c"); break; - case 0x42: util::stream_format(stream, "mov b,d"); break; - case 0x43: util::stream_format(stream, "mov b,e"); break; - case 0x44: util::stream_format(stream, "mov b,h"); break; - case 0x45: util::stream_format(stream, "mov b,l"); break; - case 0x46: util::stream_format(stream, "mov b,m"); break; - case 0x47: util::stream_format(stream, "mov b,a"); break; - case 0x48: util::stream_format(stream, "mov c,b"); break; - case 0x49: util::stream_format(stream, "mov c,c"); break; - case 0x4a: util::stream_format(stream, "mov c,d"); break; - case 0x4b: util::stream_format(stream, "mov c,e"); break; - case 0x4c: util::stream_format(stream, "mov c,h"); break; - case 0x4d: util::stream_format(stream, "mov c,l"); break; - case 0x4e: util::stream_format(stream, "mov c,m"); break; - case 0x4f: util::stream_format(stream, "mov c,a"); break; - case 0x50: util::stream_format(stream, "mov d,b"); break; - case 0x51: util::stream_format(stream, "mov d,c"); break; - case 0x52: util::stream_format(stream, "mov d,d"); break; - case 0x53: util::stream_format(stream, "mov d,e"); break; - case 0x54: util::stream_format(stream, "mov d,h"); break; - case 0x55: util::stream_format(stream, "mov d,l"); break; - case 0x56: util::stream_format(stream, "mov d,m"); break; - case 0x57: util::stream_format(stream, "mov d,a"); break; - case 0x58: util::stream_format(stream, "mov e,b"); break; - case 0x59: util::stream_format(stream, "mov e,c"); break; - case 0x5a: util::stream_format(stream, "mov e,d"); break; - case 0x5b: util::stream_format(stream, "mov e,e"); break; - case 0x5c: util::stream_format(stream, "mov e,h"); break; - case 0x5d: util::stream_format(stream, "mov e,l"); break; - case 0x5e: util::stream_format(stream, "mov e,m"); break; - case 0x5f: util::stream_format(stream, "mov e,a"); break; - case 0x60: util::stream_format(stream, "mov h,b"); break; - case 0x61: util::stream_format(stream, "mov h,c"); break; - case 0x62: util::stream_format(stream, "mov h,d"); break; - case 0x63: util::stream_format(stream, "mov h,e"); break; - case 0x64: util::stream_format(stream, "mov h,h"); break; - case 0x65: util::stream_format(stream, "mov h,l"); break; - case 0x66: util::stream_format(stream, "mov h,m"); break; - case 0x67: util::stream_format(stream, "mov h,a"); break; - case 0x68: util::stream_format(stream, "mov l,b"); break; - case 0x69: util::stream_format(stream, "mov l,c"); break; - case 0x6a: util::stream_format(stream, "mov l,d"); break; - case 0x6b: util::stream_format(stream, "mov l,e"); break; - case 0x6c: util::stream_format(stream, "mov l,h"); break; - case 0x6d: util::stream_format(stream, "mov l,l"); break; - case 0x6e: util::stream_format(stream, "mov l,m"); break; - case 0x6f: util::stream_format(stream, "mov l,a"); break; - case 0x70: util::stream_format(stream, "mov m,b"); break; - case 0x71: util::stream_format(stream, "mov m,c"); break; - case 0x72: util::stream_format(stream, "mov m,d"); break; - case 0x73: util::stream_format(stream, "mov m,e"); break; - case 0x74: util::stream_format(stream, "mov m,h"); break; - case 0x75: util::stream_format(stream, "mov m,l"); break; - case 0x76: util::stream_format(stream, "hlt"); break; - case 0x77: util::stream_format(stream, "mov m,a"); break; - case 0x78: util::stream_format(stream, "mov a,b"); break; - case 0x79: util::stream_format(stream, "mov a,c"); break; - case 0x7a: util::stream_format(stream, "mov a,d"); break; - case 0x7b: util::stream_format(stream, "mov a,e"); break; - case 0x7c: util::stream_format(stream, "mov a,h"); break; - case 0x7d: util::stream_format(stream, "mov a,l"); break; - case 0x7e: util::stream_format(stream, "mov a,m"); break; - case 0x7f: util::stream_format(stream, "mov a,a"); break; - case 0x80: util::stream_format(stream, "add b"); break; - case 0x81: util::stream_format(stream, "add c"); break; - case 0x82: util::stream_format(stream, "add d"); break; - case 0x83: util::stream_format(stream, "add e"); break; - case 0x84: util::stream_format(stream, "add h"); break; - case 0x85: util::stream_format(stream, "add l"); break; - case 0x86: util::stream_format(stream, "add m"); break; - case 0x87: util::stream_format(stream, "add a"); break; - case 0x88: util::stream_format(stream, "adc b"); break; - case 0x89: util::stream_format(stream, "adc c"); break; - case 0x8a: util::stream_format(stream, "adc d"); break; - case 0x8b: util::stream_format(stream, "adc e"); break; - case 0x8c: util::stream_format(stream, "adc h"); break; - case 0x8d: util::stream_format(stream, "adc l"); break; - case 0x8e: util::stream_format(stream, "adc m"); break; - case 0x8f: util::stream_format(stream, "adc a"); break; - case 0x90: util::stream_format(stream, "sub b"); break; - case 0x91: util::stream_format(stream, "sub c"); break; - case 0x92: util::stream_format(stream, "sub d"); break; - case 0x93: util::stream_format(stream, "sub e"); break; - case 0x94: util::stream_format(stream, "sub h"); break; - case 0x95: util::stream_format(stream, "sub l"); break; - case 0x96: util::stream_format(stream, "sub m"); break; - case 0x97: util::stream_format(stream, "sub a"); break; - case 0x98: util::stream_format(stream, "sbb b"); break; - case 0x99: util::stream_format(stream, "sbb c"); break; - case 0x9a: util::stream_format(stream, "sbb d"); break; - case 0x9b: util::stream_format(stream, "sbb e"); break; - case 0x9c: util::stream_format(stream, "sbb h"); break; - case 0x9d: util::stream_format(stream, "sbb l"); break; - case 0x9e: util::stream_format(stream, "sbb m"); break; - case 0x9f: util::stream_format(stream, "sbb a"); break; - case 0xa0: util::stream_format(stream, "ana b"); break; - case 0xa1: util::stream_format(stream, "ana c"); break; - case 0xa2: util::stream_format(stream, "ana d"); break; - case 0xa3: util::stream_format(stream, "ana e"); break; - case 0xa4: util::stream_format(stream, "ana h"); break; - case 0xa5: util::stream_format(stream, "ana l"); break; - case 0xa6: util::stream_format(stream, "ana m"); break; - case 0xa7: util::stream_format(stream, "ana a"); break; - case 0xa8: util::stream_format(stream, "xra b"); break; - case 0xa9: util::stream_format(stream, "xra c"); break; - case 0xaa: util::stream_format(stream, "xra d"); break; - case 0xab: util::stream_format(stream, "xra e"); break; - case 0xac: util::stream_format(stream, "xra h"); break; - case 0xad: util::stream_format(stream, "xra l"); break; - case 0xae: util::stream_format(stream, "xra m"); break; - case 0xaf: util::stream_format(stream, "xra a"); break; - case 0xb0: util::stream_format(stream, "ora b"); break; - case 0xb1: util::stream_format(stream, "ora c"); break; - case 0xb2: util::stream_format(stream, "ora d"); break; - case 0xb3: util::stream_format(stream, "ora e"); break; - case 0xb4: util::stream_format(stream, "ora h"); break; - case 0xb5: util::stream_format(stream, "ora l"); break; - case 0xb6: util::stream_format(stream, "ora m"); break; - case 0xb7: util::stream_format(stream, "ora a"); break; - case 0xb8: util::stream_format(stream, "cmp b"); break; - case 0xb9: util::stream_format(stream, "cmp c"); break; - case 0xba: util::stream_format(stream, "cmp d"); break; - case 0xbb: util::stream_format(stream, "cmp e"); break; - case 0xbc: util::stream_format(stream, "cmp h"); break; - case 0xbd: util::stream_format(stream, "cmp l"); break; - case 0xbe: util::stream_format(stream, "cmp m"); break; - case 0xbf: util::stream_format(stream, "cmp a"); break; - case 0xc0: util::stream_format(stream, "rnz"); flags = DASMFLAG_STEP_OUT; break; - case 0xc1: util::stream_format(stream, "pop b"); break; - case 0xc2: util::stream_format(stream, "jnz $%04x", ARGW(pc)); pc+=2; break; - case 0xc3: util::stream_format(stream, "jmp $%04x", ARGW(pc)); pc+=2; break; - case 0xc4: util::stream_format(stream, "cnz $%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break; - case 0xc5: util::stream_format(stream, "push b"); break; - case 0xc6: util::stream_format(stream, "adi $%02x", ARG(pc)); pc++; break; - case 0xc7: util::stream_format(stream, "rst 0"); flags = DASMFLAG_STEP_OVER; break; - case 0xc8: util::stream_format(stream, "rz"); flags = DASMFLAG_STEP_OUT; break; - case 0xc9: util::stream_format(stream, "ret"); flags = DASMFLAG_STEP_OUT; break; - case 0xca: util::stream_format(stream, "jz $%04x", ARGW(pc)); pc+=2; break; - case 0xcb: util::stream_format(stream, "rstv 8 (*)"); flags = DASMFLAG_STEP_OVER; break; - case 0xcc: util::stream_format(stream, "cz $%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break; - case 0xcd: util::stream_format(stream, "call $%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break; - case 0xce: util::stream_format(stream, "aci $%02x", ARG(pc)); pc++; break; - case 0xcf: util::stream_format(stream, "rst 1"); flags = DASMFLAG_STEP_OVER; break; - case 0xd0: util::stream_format(stream, "rnc"); flags = DASMFLAG_STEP_OUT; break; - case 0xd1: util::stream_format(stream, "pop d"); break; - case 0xd2: util::stream_format(stream, "jnc $%04x", ARGW(pc)); pc+=2; break; - case 0xd3: util::stream_format(stream, "out $%02x", ARG(pc)); pc++; break; - case 0xd4: util::stream_format(stream, "cnc $%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break; - case 0xd5: util::stream_format(stream, "push d"); break; - case 0xd6: util::stream_format(stream, "sui $%02x", ARG(pc)); pc++; break; - case 0xd7: util::stream_format(stream, "rst 2"); flags = DASMFLAG_STEP_OVER; break; - case 0xd8: util::stream_format(stream, "rc"); flags = DASMFLAG_STEP_OUT; break; - case 0xd9: util::stream_format(stream, "shlx d (*)"); break; - case 0xda: util::stream_format(stream, "jc $%04x", ARGW(pc)); pc+=2; break; - case 0xdb: util::stream_format(stream, "in $%02x", ARG(pc)); pc++; break; - case 0xdc: util::stream_format(stream, "cc $%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break; - case 0xdd: util::stream_format(stream, "jnx $%04x (*)", ARGW(pc)); pc+=2; break; - case 0xde: util::stream_format(stream, "sbi $%02x", ARG(pc)); pc++; break; - case 0xdf: util::stream_format(stream, "rst 3"); flags = DASMFLAG_STEP_OVER; break; - case 0xe0: util::stream_format(stream, "rpo"); flags = DASMFLAG_STEP_OUT; break; - case 0xe1: util::stream_format(stream, "pop h"); break; - case 0xe2: util::stream_format(stream, "jpo $%04x", ARGW(pc)); pc+=2; break; - case 0xe3: util::stream_format(stream, "xthl"); break; - case 0xe4: util::stream_format(stream, "cpo $%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break; - case 0xe5: util::stream_format(stream, "push h"); break; - case 0xe6: util::stream_format(stream, "ani $%02x", ARG(pc)); pc++; break; - case 0xe7: util::stream_format(stream, "rst 4"); flags = DASMFLAG_STEP_OVER; break; - case 0xe8: util::stream_format(stream, "rpe"); flags = DASMFLAG_STEP_OUT; break; - case 0xe9: util::stream_format(stream, "pchl"); break; - case 0xea: util::stream_format(stream, "jpe $%04x", ARGW(pc)); pc+=2; break; - case 0xeb: util::stream_format(stream, "xchg"); break; - case 0xec: util::stream_format(stream, "cpe $%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break; - case 0xed: util::stream_format(stream, "lhlx d (*)"); break; - case 0xee: util::stream_format(stream, "xri $%02x", ARG(pc)); pc++; break; - case 0xef: util::stream_format(stream, "rst 5"); flags = DASMFLAG_STEP_OVER; break; - case 0xf0: util::stream_format(stream, "rp"); flags = DASMFLAG_STEP_OUT; break; - case 0xf1: util::stream_format(stream, "pop psw"); break; - case 0xf2: util::stream_format(stream, "jp $%04x", ARGW(pc)); pc+=2; break; - case 0xf3: util::stream_format(stream, "di"); break; - case 0xf4: util::stream_format(stream, "cp $%04x", ARGW(pc)); pc+=2; break; - case 0xf5: util::stream_format(stream, "push psw"); break; - case 0xf6: util::stream_format(stream, "ori $%02x", ARG(pc)); pc++; break; - case 0xf7: util::stream_format(stream, "rst 6"); flags = DASMFLAG_STEP_OVER; break; - case 0xf8: util::stream_format(stream, "rm"); flags = DASMFLAG_STEP_OUT; break; - case 0xf9: util::stream_format(stream, "sphl"); break; - case 0xfa: util::stream_format(stream, "jm $%04x", ARGW(pc)); pc+=2; break; - case 0xfb: util::stream_format(stream, "ei"); break; - case 0xfc: util::stream_format(stream, "cm $%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break; - case 0xfd: util::stream_format(stream, "jx $%04x (*)", ARGW(pc)); pc+=2; break; - case 0xfe: util::stream_format(stream, "cpi $%02x", ARG(pc)); pc++; break; - case 0xff: util::stream_format(stream, "rst 7"); flags = DASMFLAG_STEP_OVER; break; -#endif + case 0x00: util::stream_format(stream, "nop"); break; + case 0x01: util::stream_format(stream, "lxi b,$%04x", params.r16(pc)); pc+=2; break; + case 0x02: util::stream_format(stream, "stax b"); break; + case 0x03: util::stream_format(stream, "inx b"); break; + case 0x04: util::stream_format(stream, "inr b"); break; + case 0x05: util::stream_format(stream, "dcr b"); break; + case 0x06: util::stream_format(stream, "mvi b,$%02x", params.r8(pc)); pc++; break; + case 0x07: util::stream_format(stream, "rlc"); break; + case 0x08: util::stream_format(stream, "dsub (*)"); break; + case 0x09: util::stream_format(stream, "dad b"); break; + case 0x0a: util::stream_format(stream, "ldax b"); break; + case 0x0b: util::stream_format(stream, "dcx b"); break; + case 0x0c: util::stream_format(stream, "inr c"); break; + case 0x0d: util::stream_format(stream, "dcr c"); break; + case 0x0e: util::stream_format(stream, "mvi c,$%02x", params.r8(pc)); pc++; break; + case 0x0f: util::stream_format(stream, "rrc"); break; + case 0x10: util::stream_format(stream, "asrh (*)"); break; + case 0x11: util::stream_format(stream, "lxi d,$%04x", params.r16(pc)); pc+=2; break; + case 0x12: util::stream_format(stream, "stax d"); break; + case 0x13: util::stream_format(stream, "inx d"); break; + case 0x14: util::stream_format(stream, "inr d"); break; + case 0x15: util::stream_format(stream, "dcr d"); break; + case 0x16: util::stream_format(stream, "mvi d,$%02x", params.r8(pc)); pc++; break; + case 0x17: util::stream_format(stream, "ral"); break; + case 0x18: util::stream_format(stream, "rlde (*)"); break; + case 0x19: util::stream_format(stream, "dad d"); break; + case 0x1a: util::stream_format(stream, "ldax d"); break; + case 0x1b: util::stream_format(stream, "dcx d"); break; + case 0x1c: util::stream_format(stream, "inr e"); break; + case 0x1d: util::stream_format(stream, "dcr e"); break; + case 0x1e: util::stream_format(stream, "mvi e,$%02x", params.r8(pc)); pc++; break; + case 0x1f: util::stream_format(stream, "rar"); break; + case 0x20: util::stream_format(stream, "rim"); break; + case 0x21: util::stream_format(stream, "lxi h,$%04x", params.r16(pc)); pc+=2; break; + case 0x22: util::stream_format(stream, "shld $%04x", params.r16(pc)); pc+=2; break; + case 0x23: util::stream_format(stream, "inx h"); break; + case 0x24: util::stream_format(stream, "inr h"); break; + case 0x25: util::stream_format(stream, "dcr h"); break; + case 0x26: util::stream_format(stream, "mvi h,$%02x", params.r8(pc)); pc++; break; + case 0x27: util::stream_format(stream, "daa"); break; + case 0x28: util::stream_format(stream, "ldeh $%02x (*)", params.r8(pc)); pc++; break; + case 0x29: util::stream_format(stream, "dad h"); break; + case 0x2a: util::stream_format(stream, "lhld $%04x", params.r16(pc)); pc+=2; break; + case 0x2b: util::stream_format(stream, "dcx h"); break; + case 0x2c: util::stream_format(stream, "inr l"); break; + case 0x2d: util::stream_format(stream, "dcr l"); break; + case 0x2e: util::stream_format(stream, "mvi l,$%02x", params.r8(pc)); pc++; break; + case 0x2f: util::stream_format(stream, "cma"); break; + case 0x30: util::stream_format(stream, "sim"); break; + case 0x31: util::stream_format(stream, "lxi sp,$%04x", params.r16(pc)); pc+=2; break; + case 0x32: util::stream_format(stream, "stax $%04x", params.r16(pc)); pc+=2; break; + case 0x33: util::stream_format(stream, "inx sp"); break; + case 0x34: util::stream_format(stream, "inr m"); break; + case 0x35: util::stream_format(stream, "dcr m"); break; + case 0x36: util::stream_format(stream, "mvi m,$%02x", params.r8(pc)); pc++; break; + case 0x37: util::stream_format(stream, "stc"); break; + case 0x38: util::stream_format(stream, "ldes $%02x (*)", params.r8(pc)); pc++; break; + case 0x39: util::stream_format(stream, "dad sp"); break; + case 0x3a: util::stream_format(stream, "ldax $%04x", params.r16(pc)); pc+=2; break; + case 0x3b: util::stream_format(stream, "dcx sp"); break; + case 0x3c: util::stream_format(stream, "inr a"); break; + case 0x3d: util::stream_format(stream, "dcr a"); break; + case 0x3e: util::stream_format(stream, "mvi a,$%02x", params.r8(pc)); pc++; break; + case 0x3f: util::stream_format(stream, "cmc"); break; + case 0x40: util::stream_format(stream, "mov b,b"); break; + case 0x41: util::stream_format(stream, "mov b,c"); break; + case 0x42: util::stream_format(stream, "mov b,d"); break; + case 0x43: util::stream_format(stream, "mov b,e"); break; + case 0x44: util::stream_format(stream, "mov b,h"); break; + case 0x45: util::stream_format(stream, "mov b,l"); break; + case 0x46: util::stream_format(stream, "mov b,m"); break; + case 0x47: util::stream_format(stream, "mov b,a"); break; + case 0x48: util::stream_format(stream, "mov c,b"); break; + case 0x49: util::stream_format(stream, "mov c,c"); break; + case 0x4a: util::stream_format(stream, "mov c,d"); break; + case 0x4b: util::stream_format(stream, "mov c,e"); break; + case 0x4c: util::stream_format(stream, "mov c,h"); break; + case 0x4d: util::stream_format(stream, "mov c,l"); break; + case 0x4e: util::stream_format(stream, "mov c,m"); break; + case 0x4f: util::stream_format(stream, "mov c,a"); break; + case 0x50: util::stream_format(stream, "mov d,b"); break; + case 0x51: util::stream_format(stream, "mov d,c"); break; + case 0x52: util::stream_format(stream, "mov d,d"); break; + case 0x53: util::stream_format(stream, "mov d,e"); break; + case 0x54: util::stream_format(stream, "mov d,h"); break; + case 0x55: util::stream_format(stream, "mov d,l"); break; + case 0x56: util::stream_format(stream, "mov d,m"); break; + case 0x57: util::stream_format(stream, "mov d,a"); break; + case 0x58: util::stream_format(stream, "mov e,b"); break; + case 0x59: util::stream_format(stream, "mov e,c"); break; + case 0x5a: util::stream_format(stream, "mov e,d"); break; + case 0x5b: util::stream_format(stream, "mov e,e"); break; + case 0x5c: util::stream_format(stream, "mov e,h"); break; + case 0x5d: util::stream_format(stream, "mov e,l"); break; + case 0x5e: util::stream_format(stream, "mov e,m"); break; + case 0x5f: util::stream_format(stream, "mov e,a"); break; + case 0x60: util::stream_format(stream, "mov h,b"); break; + case 0x61: util::stream_format(stream, "mov h,c"); break; + case 0x62: util::stream_format(stream, "mov h,d"); break; + case 0x63: util::stream_format(stream, "mov h,e"); break; + case 0x64: util::stream_format(stream, "mov h,h"); break; + case 0x65: util::stream_format(stream, "mov h,l"); break; + case 0x66: util::stream_format(stream, "mov h,m"); break; + case 0x67: util::stream_format(stream, "mov h,a"); break; + case 0x68: util::stream_format(stream, "mov l,b"); break; + case 0x69: util::stream_format(stream, "mov l,c"); break; + case 0x6a: util::stream_format(stream, "mov l,d"); break; + case 0x6b: util::stream_format(stream, "mov l,e"); break; + case 0x6c: util::stream_format(stream, "mov l,h"); break; + case 0x6d: util::stream_format(stream, "mov l,l"); break; + case 0x6e: util::stream_format(stream, "mov l,m"); break; + case 0x6f: util::stream_format(stream, "mov l,a"); break; + case 0x70: util::stream_format(stream, "mov m,b"); break; + case 0x71: util::stream_format(stream, "mov m,c"); break; + case 0x72: util::stream_format(stream, "mov m,d"); break; + case 0x73: util::stream_format(stream, "mov m,e"); break; + case 0x74: util::stream_format(stream, "mov m,h"); break; + case 0x75: util::stream_format(stream, "mov m,l"); break; + case 0x76: util::stream_format(stream, "hlt"); break; + case 0x77: util::stream_format(stream, "mov m,a"); break; + case 0x78: util::stream_format(stream, "mov a,b"); break; + case 0x79: util::stream_format(stream, "mov a,c"); break; + case 0x7a: util::stream_format(stream, "mov a,d"); break; + case 0x7b: util::stream_format(stream, "mov a,e"); break; + case 0x7c: util::stream_format(stream, "mov a,h"); break; + case 0x7d: util::stream_format(stream, "mov a,l"); break; + case 0x7e: util::stream_format(stream, "mov a,m"); break; + case 0x7f: util::stream_format(stream, "mov a,a"); break; + case 0x80: util::stream_format(stream, "add b"); break; + case 0x81: util::stream_format(stream, "add c"); break; + case 0x82: util::stream_format(stream, "add d"); break; + case 0x83: util::stream_format(stream, "add e"); break; + case 0x84: util::stream_format(stream, "add h"); break; + case 0x85: util::stream_format(stream, "add l"); break; + case 0x86: util::stream_format(stream, "add m"); break; + case 0x87: util::stream_format(stream, "add a"); break; + case 0x88: util::stream_format(stream, "adc b"); break; + case 0x89: util::stream_format(stream, "adc c"); break; + case 0x8a: util::stream_format(stream, "adc d"); break; + case 0x8b: util::stream_format(stream, "adc e"); break; + case 0x8c: util::stream_format(stream, "adc h"); break; + case 0x8d: util::stream_format(stream, "adc l"); break; + case 0x8e: util::stream_format(stream, "adc m"); break; + case 0x8f: util::stream_format(stream, "adc a"); break; + case 0x90: util::stream_format(stream, "sub b"); break; + case 0x91: util::stream_format(stream, "sub c"); break; + case 0x92: util::stream_format(stream, "sub d"); break; + case 0x93: util::stream_format(stream, "sub e"); break; + case 0x94: util::stream_format(stream, "sub h"); break; + case 0x95: util::stream_format(stream, "sub l"); break; + case 0x96: util::stream_format(stream, "sub m"); break; + case 0x97: util::stream_format(stream, "sub a"); break; + case 0x98: util::stream_format(stream, "sbb b"); break; + case 0x99: util::stream_format(stream, "sbb c"); break; + case 0x9a: util::stream_format(stream, "sbb d"); break; + case 0x9b: util::stream_format(stream, "sbb e"); break; + case 0x9c: util::stream_format(stream, "sbb h"); break; + case 0x9d: util::stream_format(stream, "sbb l"); break; + case 0x9e: util::stream_format(stream, "sbb m"); break; + case 0x9f: util::stream_format(stream, "sbb a"); break; + case 0xa0: util::stream_format(stream, "ana b"); break; + case 0xa1: util::stream_format(stream, "ana c"); break; + case 0xa2: util::stream_format(stream, "ana d"); break; + case 0xa3: util::stream_format(stream, "ana e"); break; + case 0xa4: util::stream_format(stream, "ana h"); break; + case 0xa5: util::stream_format(stream, "ana l"); break; + case 0xa6: util::stream_format(stream, "ana m"); break; + case 0xa7: util::stream_format(stream, "ana a"); break; + case 0xa8: util::stream_format(stream, "xra b"); break; + case 0xa9: util::stream_format(stream, "xra c"); break; + case 0xaa: util::stream_format(stream, "xra d"); break; + case 0xab: util::stream_format(stream, "xra e"); break; + case 0xac: util::stream_format(stream, "xra h"); break; + case 0xad: util::stream_format(stream, "xra l"); break; + case 0xae: util::stream_format(stream, "xra m"); break; + case 0xaf: util::stream_format(stream, "xra a"); break; + case 0xb0: util::stream_format(stream, "ora b"); break; + case 0xb1: util::stream_format(stream, "ora c"); break; + case 0xb2: util::stream_format(stream, "ora d"); break; + case 0xb3: util::stream_format(stream, "ora e"); break; + case 0xb4: util::stream_format(stream, "ora h"); break; + case 0xb5: util::stream_format(stream, "ora l"); break; + case 0xb6: util::stream_format(stream, "ora m"); break; + case 0xb7: util::stream_format(stream, "ora a"); break; + case 0xb8: util::stream_format(stream, "cmp b"); break; + case 0xb9: util::stream_format(stream, "cmp c"); break; + case 0xba: util::stream_format(stream, "cmp d"); break; + case 0xbb: util::stream_format(stream, "cmp e"); break; + case 0xbc: util::stream_format(stream, "cmp h"); break; + case 0xbd: util::stream_format(stream, "cmp l"); break; + case 0xbe: util::stream_format(stream, "cmp m"); break; + case 0xbf: util::stream_format(stream, "cmp a"); break; + case 0xc0: util::stream_format(stream, "rnz"); flags = STEP_OUT; break; + case 0xc1: util::stream_format(stream, "pop b"); break; + case 0xc2: util::stream_format(stream, "jnz $%04x", params.r16(pc)); pc+=2; break; + case 0xc3: util::stream_format(stream, "jmp $%04x", params.r16(pc)); pc+=2; break; + case 0xc4: util::stream_format(stream, "cnz $%04x", params.r16(pc)); pc+=2; flags = STEP_OVER; break; + case 0xc5: util::stream_format(stream, "push b"); break; + case 0xc6: util::stream_format(stream, "adi $%02x", params.r8(pc)); pc++; break; + case 0xc7: util::stream_format(stream, "rst 0"); flags = STEP_OVER; break; + case 0xc8: util::stream_format(stream, "rz"); flags = STEP_OUT; break; + case 0xc9: util::stream_format(stream, "ret"); flags = STEP_OUT; break; + case 0xca: util::stream_format(stream, "jz $%04x", params.r16(pc)); pc+=2; break; + case 0xcb: util::stream_format(stream, "rstv 8 (*)"); flags = STEP_OVER; break; + case 0xcc: util::stream_format(stream, "cz $%04x", params.r16(pc)); pc+=2; flags = STEP_OVER; break; + case 0xcd: util::stream_format(stream, "call $%04x", params.r16(pc)); pc+=2; flags = STEP_OVER; break; + case 0xce: util::stream_format(stream, "aci $%02x", params.r8(pc)); pc++; break; + case 0xcf: util::stream_format(stream, "rst 1"); flags = STEP_OVER; break; + case 0xd0: util::stream_format(stream, "rnc"); flags = STEP_OUT; break; + case 0xd1: util::stream_format(stream, "pop d"); break; + case 0xd2: util::stream_format(stream, "jnc $%04x", params.r16(pc)); pc+=2; break; + case 0xd3: util::stream_format(stream, "out $%02x", params.r8(pc)); pc++; break; + case 0xd4: util::stream_format(stream, "cnc $%04x", params.r16(pc)); pc+=2; flags = STEP_OVER; break; + case 0xd5: util::stream_format(stream, "push d"); break; + case 0xd6: util::stream_format(stream, "sui $%02x", params.r8(pc)); pc++; break; + case 0xd7: util::stream_format(stream, "rst 2"); flags = STEP_OVER; break; + case 0xd8: util::stream_format(stream, "rc"); flags = STEP_OUT; break; + case 0xd9: util::stream_format(stream, "shlx d (*)"); break; + case 0xda: util::stream_format(stream, "jc $%04x", params.r16(pc)); pc+=2; break; + case 0xdb: util::stream_format(stream, "in $%02x", params.r8(pc)); pc++; break; + case 0xdc: util::stream_format(stream, "cc $%04x", params.r16(pc)); pc+=2; flags = STEP_OVER; break; + case 0xdd: util::stream_format(stream, "jnx $%04x (*)", params.r16(pc)); pc+=2; break; + case 0xde: util::stream_format(stream, "sbi $%02x", params.r8(pc)); pc++; break; + case 0xdf: util::stream_format(stream, "rst 3"); flags = STEP_OVER; break; + case 0xe0: util::stream_format(stream, "rpo"); flags = STEP_OUT; break; + case 0xe1: util::stream_format(stream, "pop h"); break; + case 0xe2: util::stream_format(stream, "jpo $%04x", params.r16(pc)); pc+=2; break; + case 0xe3: util::stream_format(stream, "xthl"); break; + case 0xe4: util::stream_format(stream, "cpo $%04x", params.r16(pc)); pc+=2; flags = STEP_OVER; break; + case 0xe5: util::stream_format(stream, "push h"); break; + case 0xe6: util::stream_format(stream, "ani $%02x", params.r8(pc)); pc++; break; + case 0xe7: util::stream_format(stream, "rst 4"); flags = STEP_OVER; break; + case 0xe8: util::stream_format(stream, "rpe"); flags = STEP_OUT; break; + case 0xe9: util::stream_format(stream, "pchl"); break; + case 0xea: util::stream_format(stream, "jpe $%04x", params.r16(pc)); pc+=2; break; + case 0xeb: util::stream_format(stream, "xchg"); break; + case 0xec: util::stream_format(stream, "cpe $%04x", params.r16(pc)); pc+=2; flags = STEP_OVER; break; + case 0xed: util::stream_format(stream, "lhlx d (*)"); break; + case 0xee: util::stream_format(stream, "xri $%02x", params.r8(pc)); pc++; break; + case 0xef: util::stream_format(stream, "rst 5"); flags = STEP_OVER; break; + case 0xf0: util::stream_format(stream, "rp"); flags = STEP_OUT; break; + case 0xf1: util::stream_format(stream, "pop psw"); break; + case 0xf2: util::stream_format(stream, "jp $%04x", params.r16(pc)); pc+=2; break; + case 0xf3: util::stream_format(stream, "di"); break; + case 0xf4: util::stream_format(stream, "cp $%04x", params.r16(pc)); pc+=2; break; + case 0xf5: util::stream_format(stream, "push psw"); break; + case 0xf6: util::stream_format(stream, "ori $%02x", params.r8(pc)); pc++; break; + case 0xf7: util::stream_format(stream, "rst 6"); flags = STEP_OVER; break; + case 0xf8: util::stream_format(stream, "rm"); flags = STEP_OUT; break; + case 0xf9: util::stream_format(stream, "sphl"); break; + case 0xfa: util::stream_format(stream, "jm $%04x", params.r16(pc)); pc+=2; break; + case 0xfb: util::stream_format(stream, "ei"); break; + case 0xfc: util::stream_format(stream, "cm $%04x", params.r16(pc)); pc+=2; flags = STEP_OVER; break; + case 0xfd: util::stream_format(stream, "jx $%04x (*)", params.r16(pc)); pc+=2; break; + case 0xfe: util::stream_format(stream, "cpi $%02x", params.r8(pc)); pc++; break; + case 0xff: util::stream_format(stream, "rst 7"); flags = STEP_OVER; break; } - return (pc - PC) | flags | DASMFLAG_SUPPORTED; + return (pc - prevpc) | flags | SUPPORTED; } diff --git a/src/devices/cpu/i8085/8085dasm.h b/src/devices/cpu/i8085/8085dasm.h new file mode 100644 index 00000000000..1aad019848d --- /dev/null +++ b/src/devices/cpu/i8085/8085dasm.h @@ -0,0 +1,24 @@ +// license:BSD-3-Clause +// copyright-holders:Juergen Buchmueller +/***************************************************************************** + * + * Portable I8085A disassembler + * + *****************************************************************************/ + +#ifndef MAME_CPU_I8085_8085DASM_H +#define MAME_CPU_I8085_8085DASM_H + +#pragma once + +class i8085_disassembler : public util::disasm_interface +{ +public: + i8085_disassembler() = default; + virtual ~i8085_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/i8085/i8085.cpp b/src/devices/cpu/i8085/i8085.cpp index 75a2360dc63..5e984464cf3 100644 --- a/src/devices/cpu/i8085/i8085.cpp +++ b/src/devices/cpu/i8085/i8085.cpp @@ -1,13 +1,19 @@ // license:BSD-3-Clause // copyright-holders:Juergen Buchmueller, hap +// thanks-to:Marcel De Kogel /***************************************************************************** * - * i8085.c * Portable I8085A emulator V1.2 * * Copyright Juergen Buchmueller, all rights reserved. * Partially based on information out of Z80Em by Marcel De Kogel * + * TODO: + * - 8085 DAA fails on 8080/8085 CPU Exerciser + * - not sure if 8085 DSUB H flag is correct + * + * --------------------------------------------------------------------------- + * * changes in V1.3 * - Added undocumented opcodes for the 8085A, based on a german * book about microcomputers: "Mikrocomputertechnik mit dem @@ -103,23 +109,38 @@ #include "emu.h" #include "debugger.h" #include "i8085.h" -#include "i8085cpu.h" +#include "8085dasm.h" #define VERBOSE 0 #include "logmacro.h" -#define CPUTYPE_8080 0 -#define CPUTYPE_8085 1 - - /*************************************************************************** - MACROS + CONSTANTS ***************************************************************************/ -#define IS_8080() (m_cputype == CPUTYPE_8080) -#define IS_8085() (m_cputype == CPUTYPE_8085) - +constexpr u8 SF = 0x80; +constexpr u8 ZF = 0x40; +constexpr u8 X5F = 0x20; +constexpr u8 HF = 0x10; +constexpr u8 X3F = 0x08; +constexpr u8 PF = 0x04; +constexpr u8 VF = 0x02; +constexpr u8 CF = 0x01; + +constexpr u8 IM_SID = 0x80; +constexpr u8 IM_I75 = 0x40; +constexpr u8 IM_I65 = 0x20; +constexpr u8 IM_I55 = 0x10; +constexpr u8 IM_IE = 0x08; +constexpr u8 IM_M75 = 0x04; +constexpr u8 IM_M65 = 0x02; +constexpr u8 IM_M55 = 0x01; + +constexpr u16 ADDR_TRAP = 0x0024; +constexpr u16 ADDR_RST55 = 0x002c; +constexpr u16 ADDR_RST65 = 0x0034; +constexpr u16 ADDR_RST75 = 0x003c; /*************************************************************************** @@ -127,7 +148,7 @@ ***************************************************************************/ /* cycles lookup */ -const uint8_t i8085a_cpu_device::lut_cycles_8080[256]={ +const u8 i8085a_cpu_device::lut_cycles_8080[256]={ /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ /* 0 */ 4, 10,7, 5, 5, 5, 7, 4, 4, 10,7, 5, 5, 5, 7, 4, /* 1 */ 4, 10,7, 5, 5, 5, 7, 4, 4, 10,7, 5, 5, 5, 7, 4, @@ -145,7 +166,7 @@ const uint8_t i8085a_cpu_device::lut_cycles_8080[256]={ /* D */ 5, 10,10,10,11,11,7, 11,5, 10,10,10,11,11,7, 11, /* E */ 5, 10,10,18,11,11,7, 11,5, 5, 10,5, 11,11,7, 11, /* F */ 5, 10,10,4, 11,11,7, 11,5, 5, 10,4, 11,11,7, 11 }; -const uint8_t i8085a_cpu_device::lut_cycles_8085[256]={ +const u8 i8085a_cpu_device::lut_cycles_8085[256]={ /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ /* 0 */ 4, 10,7, 6, 4, 4, 7, 4, 10,10,7, 6, 4, 4, 7, 4, /* 1 */ 7, 10,7, 6, 4, 4, 7, 4, 10,10,7, 6, 4, 4, 7, 4, @@ -165,13 +186,13 @@ const uint8_t i8085a_cpu_device::lut_cycles_8085[256]={ /* F */ 6, 10,10,4, 11,12,7, 12,6, 6, 10,4, 11,10,7, 12 }; /* special cases (partially taken care of elsewhere): - base c taken? not taken? -M_RET 8080 5 +6(11) -0 (conditional) -M_RET 8085 6 +6(12) -0 (conditional) -M_JMP 8080 10 +0 -0 -M_JMP 8085 10 +0 -3(7) -M_CALL 8080 11 +6(17) -0 -M_CALL 8085 11 +7(18) -2(9) + base c taken? not taken? +op_ret 8080 5 +6(11) -0 (conditional) +op_ret 8085 6 +6(12) -0 (conditional) +op_jmp 8080 10 +0 -0 +op_jmp 8085 10 +0 -3(7) +op_call 8080 11 +6(17) -0 +op_call 8085 11 +7(18) -2(9) */ @@ -181,16 +202,16 @@ DEFINE_DEVICE_TYPE(I8080A, i8080a_cpu_device, "i8080a", "8080A") DEFINE_DEVICE_TYPE(I8085A, i8085a_cpu_device, "i8085a", "8085A") -i8085a_cpu_device::i8085a_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : i8085a_cpu_device(mconfig, I8085A, tag, owner, clock, CPUTYPE_8085) +i8085a_cpu_device::i8085a_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : i8085a_cpu_device(mconfig, I8085A, tag, owner, clock, CPUTYPE_8085A) { } - -i8085a_cpu_device::i8085a_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int cputype) +i8085a_cpu_device::i8085a_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int cputype) : cpu_device(mconfig, type, tag, owner, clock) , m_program_config("program", ENDIANNESS_LITTLE, 8, 16, 0) , m_io_config("io", ENDIANNESS_LITTLE, 8, 8, 0) + , m_opcode_config("opcodes", ENDIANNESS_LITTLE, 8, 16, 0) , m_out_status_func(*this) , m_out_inte_func(*this) , m_in_sid_func(*this) @@ -199,21 +220,23 @@ i8085a_cpu_device::i8085a_cpu_device(const machine_config &mconfig, device_type { } - -i8080_cpu_device::i8080_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +i8080_cpu_device::i8080_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : i8085a_cpu_device(mconfig, I8080, tag, owner, clock, CPUTYPE_8080) { } - -i8080a_cpu_device::i8080a_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : i8085a_cpu_device(mconfig, I8080A, tag, owner, clock, CPUTYPE_8080) +i8080a_cpu_device::i8080a_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : i8085a_cpu_device(mconfig, I8080A, tag, owner, clock, CPUTYPE_8080A) { } device_memory_interface::space_config_vector i8085a_cpu_device::memory_space_config() const { - return space_config_vector { + return has_configured_map(AS_OPCODES) ? space_config_vector { + std::make_pair(AS_PROGRAM, &m_program_config), + std::make_pair(AS_IO, &m_io_config), + std::make_pair(AS_OPCODES, &m_opcode_config) + } : space_config_vector { std::make_pair(AS_PROGRAM, &m_program_config), std::make_pair(AS_IO, &m_io_config) }; @@ -235,664 +258,18 @@ void i8085a_cpu_device::device_clock_changed() } -void i8085a_cpu_device::set_sod(int state) -{ - if (state != 0 && m_sod_state == 0) - { - m_sod_state = 1; - m_out_sod_func(m_sod_state); - } - else if (state == 0 && m_sod_state != 0) - { - m_sod_state = 0; - m_out_sod_func(m_sod_state); - } -} - - -void i8085a_cpu_device::set_inte(int state) -{ - if (state != 0 && (m_IM & IM_IE) == 0) - { - m_IM |= IM_IE; - m_out_inte_func(1); - } - else if (state == 0 && (m_IM & IM_IE) != 0) - { - m_IM &= ~IM_IE; - m_out_inte_func(0); - } -} - - -void i8085a_cpu_device::set_status(uint8_t status) -{ - if (status != m_STATUS) - m_out_status_func(status); - - m_STATUS = status; -} - - -uint8_t i8085a_cpu_device::get_rim_value() -{ - uint8_t result = m_IM; - int sid = m_in_sid_func(); - - /* copy live RST5.5 and RST6.5 states */ - result &= ~(IM_I65 | IM_I55); - if (m_irq_state[I8085_RST65_LINE]) result |= IM_I65; - if (m_irq_state[I8085_RST55_LINE]) result |= IM_I55; - - /* fetch the SID bit if we have a callback */ - result = (result & ~IM_SID) | (sid ? IM_SID : 0); - - return result; -} - - -void i8085a_cpu_device::break_halt_for_interrupt() -{ - /* de-halt if necessary */ - if (m_HALT) - { - m_PC.w.l++; - m_HALT = 0; - set_status(0x26); /* int ack while halt */ - } - else - set_status(0x23); /* int ack */ -} - - -uint8_t i8085a_cpu_device::ROP() -{ - set_status(0xa2); // instruction fetch - return m_direct->read_byte(m_PC.w.l++); -} - -uint8_t i8085a_cpu_device::ARG() -{ - return m_direct->read_byte(m_PC.w.l++); -} - -uint16_t i8085a_cpu_device::ARG16() -{ - uint16_t w; - w = m_direct->read_byte(m_PC.d); - m_PC.w.l++; - w += m_direct->read_byte(m_PC.d) << 8; - m_PC.w.l++; - return w; -} - -uint8_t i8085a_cpu_device::RM(uint32_t a) -{ - set_status(0x82); // memory read - return m_program->read_byte(a); -} - -void i8085a_cpu_device::WM(uint32_t a, uint8_t v) -{ - set_status(0x00); // memory write - m_program->write_byte(a, v); -} - - -void i8085a_cpu_device::check_for_interrupts() -{ - /* TRAP is the highest priority */ - if (m_trap_pending) - { - /* the first RIM after a TRAP reflects the original IE state; remember it here, - setting the high bit to indicate it is valid */ - m_trap_im_copy = m_IM | 0x80; - - /* reset the pending state */ - m_trap_pending = false; - - /* break out of HALT state and call the IRQ ack callback */ - break_halt_for_interrupt(); - standard_irq_callback(INPUT_LINE_NMI); - - /* push the PC and jump to $0024 */ - M_PUSH(PC); - set_inte(0); - m_PC.w.l = ADDR_TRAP; - m_icount -= 11; - } - - /* followed by RST7.5 */ - else if ((m_IM & IM_I75) && !(m_IM & IM_M75) && (m_IM & IM_IE)) - { - /* reset the pending state (which is CPU-visible via the RIM instruction) */ - m_IM &= ~IM_I75; - - /* break out of HALT state and call the IRQ ack callback */ - break_halt_for_interrupt(); - standard_irq_callback(I8085_RST75_LINE); - - /* push the PC and jump to $003C */ - M_PUSH(PC); - set_inte(0); - m_PC.w.l = ADDR_RST75; - m_icount -= 11; - } - - /* followed by RST6.5 */ - else if (m_irq_state[I8085_RST65_LINE] && !(m_IM & IM_M65) && (m_IM & IM_IE)) - { - /* break out of HALT state and call the IRQ ack callback */ - break_halt_for_interrupt(); - standard_irq_callback(I8085_RST65_LINE); - - /* push the PC and jump to $0034 */ - M_PUSH(PC); - set_inte(0); - m_PC.w.l = ADDR_RST65; - m_icount -= 11; - } - - /* followed by RST5.5 */ - else if (m_irq_state[I8085_RST55_LINE] && !(m_IM & IM_M55) && (m_IM & IM_IE)) - { - /* break out of HALT state and call the IRQ ack callback */ - break_halt_for_interrupt(); - standard_irq_callback(I8085_RST55_LINE); - - /* push the PC and jump to $002C */ - M_PUSH(PC); - set_inte(0); - m_PC.w.l = ADDR_RST55; - m_icount -= 11; - } - - /* followed by classic INTR */ - else if (m_irq_state[I8085_INTR_LINE] && (m_IM & IM_IE)) - { - uint32_t vector; - - /* break out of HALT state and call the IRQ ack callback */ - break_halt_for_interrupt(); - vector = standard_irq_callback(I8085_INTR_LINE); - - /* use the resulting vector as an opcode to execute */ - set_inte(0); - switch (vector & 0xff0000) - { - case 0xcd0000: /* CALL nnnn */ - m_icount -= 7; - M_PUSH(PC); - case 0xc30000: /* JMP nnnn */ - m_icount -= 10; - m_PC.d = vector & 0xffff; - break; - - default: - LOG("i8085 take int $%02x\n", vector); - execute_one(vector & 0xff); - break; - } - } -} - - -void i8085a_cpu_device::execute_one(int opcode) -{ - m_icount -= lut_cycles[opcode]; - - switch (opcode) - { - case 0x00: break; /* NOP */ - case 0x01: m_BC.w.l = ARG16(); break; /* LXI B,nnnn */ - case 0x02: WM(m_BC.d, m_AF.b.h); break; /* STAX B */ - case 0x03: m_BC.w.l++; /* INX B */ - if (IS_8085()) { if (m_BC.w.l == 0x0000) m_AF.b.l |= X5F; else m_AF.b.l &= ~X5F; } - break; - case 0x04: M_INR(m_BC.b.h); break; /* INR B */ - case 0x05: M_DCR(m_BC.b.h); break; /* DCR B */ - case 0x06: M_MVI(m_BC.b.h); break; /* MVI B,nn */ - case 0x07: M_RLC; break; /* RLC */ - - case 0x08: if (IS_8085()) { M_DSUB(); } /* DSUB */ - /* else { ; } */ /* NOP undocumented */ - break; - case 0x09: M_DAD(BC); break; /* DAD B */ - case 0x0a: m_AF.b.h = RM(m_BC.d); break; /* LDAX B */ - case 0x0b: m_BC.w.l--; /* DCX B */ - if (IS_8085()) { if (m_BC.w.l == 0xffff) m_AF.b.l |= X5F; else m_AF.b.l &= ~X5F; } - break; - case 0x0c: M_INR(m_BC.b.l); break; /* INR C */ - case 0x0d: M_DCR(m_BC.b.l); break; /* DCR C */ - case 0x0e: M_MVI(m_BC.b.l); break; /* MVI C,nn */ - case 0x0f: M_RRC; break; /* RRC */ - - case 0x10: if (IS_8085()) { /* ASRH */ - m_AF.b.l = (m_AF.b.l & ~CF) | (m_HL.b.l & CF); - m_HL.w.l = (m_HL.w.l >> 1); - } /* else { ; } */ /* NOP undocumented */ - break; - case 0x11: m_DE.w.l = ARG16(); break; /* LXI D,nnnn */ - case 0x12: WM(m_DE.d, m_AF.b.h); break; /* STAX D */ - case 0x13: m_DE.w.l++; /* INX D */ - if (IS_8085()) { if (m_DE.w.l == 0x0000) m_AF.b.l |= X5F; else m_AF.b.l &= ~X5F; } - break; - case 0x14: M_INR(m_DE.b.h); break; /* INR D */ - case 0x15: M_DCR(m_DE.b.h); break; /* DCR D */ - case 0x16: M_MVI(m_DE.b.h); break; /* MVI D,nn */ - case 0x17: M_RAL; break; /* RAL */ - - case 0x18: if (IS_8085()) { /* RLDE */ - m_AF.b.l = (m_AF.b.l & ~(CF | VF)) | (m_DE.b.h >> 7); - m_DE.w.l = (m_DE.w.l << 1) | (m_DE.w.l >> 15); - if (0 != (((m_DE.w.l >> 15) ^ m_AF.b.l) & CF)) m_AF.b.l |= VF; - } /* else { ; } */ /* NOP undocumented */ - break; - case 0x19: M_DAD(DE); break; /* DAD D */ - case 0x1a: m_AF.b.h = RM(m_DE.d); break; /* LDAX D */ - case 0x1b: m_DE.w.l--; /* DCX D */ - if (IS_8085()) { if (m_DE.w.l == 0xffff) m_AF.b.l |= X5F; else m_AF.b.l &= ~X5F; } - break; - case 0x1c: M_INR(m_DE.b.l); break; /* INR E */ - case 0x1d: M_DCR(m_DE.b.l); break; /* DCR E */ - case 0x1e: M_MVI(m_DE.b.l); break; /* MVI E,nn */ - case 0x1f: M_RAR; break; /* RAR */ - - case 0x20: if (IS_8085()) { /* RIM */ - m_AF.b.h = get_rim_value(); - - /* if we have remembered state from taking a TRAP, fix up the IE flag here */ - if (m_trap_im_copy & 0x80) m_AF.b.h = (m_AF.b.h & ~IM_IE) | (m_trap_im_copy & IM_IE); - m_trap_im_copy = 0; - } /* else { ; } */ /* NOP undocumented */ - break; - case 0x21: m_HL.w.l = ARG16(); break; /* LXI H,nnnn */ - case 0x22: m_WZ.w.l = ARG16(); /* SHLD nnnn */ - WM(m_WZ.d, m_HL.b.l); m_WZ.w.l++; - WM(m_WZ.d, m_HL.b.h); - break; - case 0x23: m_HL.w.l++; /* INX H */ - if (IS_8085()) { if (m_HL.w.l == 0x0000) m_AF.b.l |= X5F; else m_AF.b.l &= ~X5F; } - break; - case 0x24: M_INR(m_HL.b.h); break; /* INR H */ - case 0x25: M_DCR(m_HL.b.h); break; /* DCR H */ - case 0x26: M_MVI(m_HL.b.h); break; /* MVI H,nn */ - case 0x27: m_WZ.b.h = m_AF.b.h; /* DAA */ - if (IS_8085() && m_AF.b.l&VF) { - if ((m_AF.b.l&HF) | ((m_AF.b.h&0xf)>9)) m_WZ.b.h-=6; - if ((m_AF.b.l&CF) | (m_AF.b.h>0x99)) m_WZ.b.h-=0x60; - } - else { - if ((m_AF.b.l&HF) | ((m_AF.b.h&0xf)>9)) m_WZ.b.h+=6; - if ((m_AF.b.l&CF) | (m_AF.b.h>0x99)) m_WZ.b.h+=0x60; - } - - m_AF.b.l=(m_AF.b.l&3) | (m_AF.b.h&0x28) | (m_AF.b.h>0x99) | ((m_AF.b.h^m_WZ.b.h)&0x10) | ZSP[m_WZ.b.h]; - m_AF.b.h=m_WZ.b.h; - break; - - case 0x28: if (IS_8085()) { /* LDEH nn */ - m_WZ.d = ARG(); - m_DE.d = (m_HL.d + m_WZ.d) & 0xffff; - } /* else { ; } */ /* NOP undocumented */ - break; - case 0x29: M_DAD(HL); break; /* DAD H */ - case 0x2a: m_WZ.d = ARG16(); /* LHLD nnnn */ - m_HL.b.l = RM(m_WZ.d); m_WZ.w.l++; - m_HL.b.h = RM(m_WZ.d); - break; - case 0x2b: m_HL.w.l--; /* DCX H */ - if (IS_8085()) { if (m_HL.w.l == 0xffff) m_AF.b.l |= X5F; else m_AF.b.l &= ~X5F; } - break; - case 0x2c: M_INR(m_HL.b.l); break; /* INR L */ - case 0x2d: M_DCR(m_HL.b.l); break; /* DCR L */ - case 0x2e: M_MVI(m_HL.b.l); break; /* MVI L,nn */ - case 0x2f: m_AF.b.h ^= 0xff; /* CMA */ - if (IS_8085()) m_AF.b.l |= HF | VF; - break; - - case 0x30: if (IS_8085()) { /* SIM */ - /* if bit 3 is set, bits 0-2 become the new masks */ - if (m_AF.b.h & 0x08) { - m_IM &= ~(IM_M55 | IM_M65 | IM_M75 | IM_I55 | IM_I65); - m_IM |= m_AF.b.h & (IM_M55 | IM_M65 | IM_M75); - - /* update live state based on the new masks */ - if ((m_IM & IM_M55) == 0 && m_irq_state[I8085_RST55_LINE]) m_IM |= IM_I55; - if ((m_IM & IM_M65) == 0 && m_irq_state[I8085_RST65_LINE]) m_IM |= IM_I65; - } - - /* bit if 4 is set, the 7.5 flip-flop is cleared */ - if (m_AF.b.h & 0x10) m_IM &= ~IM_I75; - - /* if bit 6 is set, then bit 7 is the new SOD state */ - if (m_AF.b.h & 0x40) set_sod(m_AF.b.h >> 7); - - /* check for revealed interrupts */ - check_for_interrupts(); - } /* else { ; } */ /* NOP undocumented */ - break; - case 0x31: m_SP.w.l = ARG16(); break; /* LXI SP,nnnn */ - case 0x32: m_WZ.d = ARG16(); /* STAX nnnn */ - WM(m_WZ.d, m_AF.b.h); - break; - case 0x33: m_SP.w.l++; /* INX SP */ - if (IS_8085()) { if (m_SP.w.l == 0x0000) m_AF.b.l |= X5F; else m_AF.b.l &= ~X5F; } - break; - case 0x34: m_WZ.b.l = RM(m_HL.d); /* INR M */ - M_INR(m_WZ.b.l); - WM(m_HL.d, m_WZ.b.l); - break; - case 0x35: m_WZ.b.l = RM(m_HL.d); /* DCR M */ - M_DCR(m_WZ.b.l); - WM(m_HL.d, m_WZ.b.l); - break; - case 0x36: m_WZ.b.l = ARG(); /* MVI M,nn */ - WM(m_HL.d, m_WZ.b.l); - break; - case 0x37: m_AF.b.l = (m_AF.b.l & 0xfe) | CF; break; /* STC */ - - case 0x38: if (IS_8085()) { /* LDES nn */ - m_WZ.d = ARG(); - m_DE.d = (m_SP.d + m_WZ.d) & 0xffff; - } /* else { ; } */ /* NOP undocumented */ - break; - case 0x39: M_DAD(SP); break; /* DAD SP */ - case 0x3a: m_WZ.d = ARG16(); /* LDAX nnnn */ - m_AF.b.h = RM(m_WZ.d); - break; - case 0x3b: m_SP.w.l--; /* DCX SP */ - if (IS_8085()) { if (m_SP.w.l == 0xffff) m_AF.b.l |= X5F; else m_AF.b.l &= ~X5F; } - break; - case 0x3c: M_INR(m_AF.b.h); break; /* INR A */ - case 0x3d: M_DCR(m_AF.b.h); break; /* DCR A */ - case 0x3e: M_MVI(m_AF.b.h); break; /* MVI A,nn */ - case 0x3f: m_AF.b.l = (m_AF.b.l & 0xfe) | (~m_AF.b.l & CF); break; /* CMC */ - - case 0x40: break; /* MOV B,B */ - case 0x41: m_BC.b.h = m_BC.b.l; break; /* MOV B,C */ - case 0x42: m_BC.b.h = m_DE.b.h; break; /* MOV B,D */ - case 0x43: m_BC.b.h = m_DE.b.l; break; /* MOV B,E */ - case 0x44: m_BC.b.h = m_HL.b.h; break; /* MOV B,H */ - case 0x45: m_BC.b.h = m_HL.b.l; break; /* MOV B,L */ - case 0x46: m_BC.b.h = RM(m_HL.d); break; /* MOV B,M */ - case 0x47: m_BC.b.h = m_AF.b.h; break; /* MOV B,A */ - - case 0x48: m_BC.b.l = m_BC.b.h; break; /* MOV C,B */ - case 0x49: break; /* MOV C,C */ - case 0x4a: m_BC.b.l = m_DE.b.h; break; /* MOV C,D */ - case 0x4b: m_BC.b.l = m_DE.b.l; break; /* MOV C,E */ - case 0x4c: m_BC.b.l = m_HL.b.h; break; /* MOV C,H */ - case 0x4d: m_BC.b.l = m_HL.b.l; break; /* MOV C,L */ - case 0x4e: m_BC.b.l = RM(m_HL.d); break; /* MOV C,M */ - case 0x4f: m_BC.b.l = m_AF.b.h; break; /* MOV C,A */ - - case 0x50: m_DE.b.h = m_BC.b.h; break; /* MOV D,B */ - case 0x51: m_DE.b.h = m_BC.b.l; break; /* MOV D,C */ - case 0x52: break; /* MOV D,D */ - case 0x53: m_DE.b.h = m_DE.b.l; break; /* MOV D,E */ - case 0x54: m_DE.b.h = m_HL.b.h; break; /* MOV D,H */ - case 0x55: m_DE.b.h = m_HL.b.l; break; /* MOV D,L */ - case 0x56: m_DE.b.h = RM(m_HL.d); break; /* MOV D,M */ - case 0x57: m_DE.b.h = m_AF.b.h; break; /* MOV D,A */ - - case 0x58: m_DE.b.l = m_BC.b.h; break; /* MOV E,B */ - case 0x59: m_DE.b.l = m_BC.b.l; break; /* MOV E,C */ - case 0x5a: m_DE.b.l = m_DE.b.h; break; /* MOV E,D */ - case 0x5b: break; /* MOV E,E */ - case 0x5c: m_DE.b.l = m_HL.b.h; break; /* MOV E,H */ - case 0x5d: m_DE.b.l = m_HL.b.l; break; /* MOV E,L */ - case 0x5e: m_DE.b.l = RM(m_HL.d); break; /* MOV E,M */ - case 0x5f: m_DE.b.l = m_AF.b.h; break; /* MOV E,A */ - - case 0x60: m_HL.b.h = m_BC.b.h; break; /* MOV H,B */ - case 0x61: m_HL.b.h = m_BC.b.l; break; /* MOV H,C */ - case 0x62: m_HL.b.h = m_DE.b.h; break; /* MOV H,D */ - case 0x63: m_HL.b.h = m_DE.b.l; break; /* MOV H,E */ - case 0x64: break; /* MOV H,H */ - case 0x65: m_HL.b.h = m_HL.b.l; break; /* MOV H,L */ - case 0x66: m_HL.b.h = RM(m_HL.d); break; /* MOV H,M */ - case 0x67: m_HL.b.h = m_AF.b.h; break; /* MOV H,A */ - - case 0x68: m_HL.b.l = m_BC.b.h; break; /* MOV L,B */ - case 0x69: m_HL.b.l = m_BC.b.l; break; /* MOV L,C */ - case 0x6a: m_HL.b.l = m_DE.b.h; break; /* MOV L,D */ - case 0x6b: m_HL.b.l = m_DE.b.l; break; /* MOV L,E */ - case 0x6c: m_HL.b.l = m_HL.b.h; break; /* MOV L,H */ - case 0x6d: break; /* MOV L,L */ - case 0x6e: m_HL.b.l = RM(m_HL.d); break; /* MOV L,M */ - case 0x6f: m_HL.b.l = m_AF.b.h; break; /* MOV L,A */ - - case 0x70: WM(m_HL.d, m_BC.b.h); break; /* MOV M,B */ - case 0x71: WM(m_HL.d, m_BC.b.l); break; /* MOV M,C */ - case 0x72: WM(m_HL.d, m_DE.b.h); break; /* MOV M,D */ - case 0x73: WM(m_HL.d, m_DE.b.l); break; /* MOV M,E */ - case 0x74: WM(m_HL.d, m_HL.b.h); break; /* MOV M,H */ - case 0x75: WM(m_HL.d, m_HL.b.l); break; /* MOV M,L */ - case 0x76: m_PC.w.l--; m_HALT = 1; /* HLT */ - set_status(0x8a); // halt acknowledge - break; - case 0x77: WM(m_HL.d, m_AF.b.h); break; /* MOV M,A */ - - case 0x78: m_AF.b.h = m_BC.b.h; break; /* MOV A,B */ - case 0x79: m_AF.b.h = m_BC.b.l; break; /* MOV A,C */ - case 0x7a: m_AF.b.h = m_DE.b.h; break; /* MOV A,D */ - case 0x7b: m_AF.b.h = m_DE.b.l; break; /* MOV A,E */ - case 0x7c: m_AF.b.h = m_HL.b.h; break; /* MOV A,H */ - case 0x7d: m_AF.b.h = m_HL.b.l; break; /* MOV A,L */ - case 0x7e: m_AF.b.h = RM(m_HL.d); break; /* MOV A,M */ - case 0x7f: break; /* MOV A,A */ - - case 0x80: M_ADD(m_BC.b.h); break; /* ADD B */ - case 0x81: M_ADD(m_BC.b.l); break; /* ADD C */ - case 0x82: M_ADD(m_DE.b.h); break; /* ADD D */ - case 0x83: M_ADD(m_DE.b.l); break; /* ADD E */ - case 0x84: M_ADD(m_HL.b.h); break; /* ADD H */ - case 0x85: M_ADD(m_HL.b.l); break; /* ADD L */ - case 0x86: m_WZ.b.l = RM(m_HL.d); M_ADD(m_WZ.b.l); break; /* ADD M */ - case 0x87: M_ADD(m_AF.b.h); break; /* ADD A */ - - case 0x88: M_ADC(m_BC.b.h); break; /* ADC B */ - case 0x89: M_ADC(m_BC.b.l); break; /* ADC C */ - case 0x8a: M_ADC(m_DE.b.h); break; /* ADC D */ - case 0x8b: M_ADC(m_DE.b.l); break; /* ADC E */ - case 0x8c: M_ADC(m_HL.b.h); break; /* ADC H */ - case 0x8d: M_ADC(m_HL.b.l); break; /* ADC L */ - case 0x8e: m_WZ.b.l = RM(m_HL.d); M_ADC(m_WZ.b.l); break; /* ADC M */ - case 0x8f: M_ADC(m_AF.b.h); break; /* ADC A */ - - case 0x90: M_SUB(m_BC.b.h); break; /* SUB B */ - case 0x91: M_SUB(m_BC.b.l); break; /* SUB C */ - case 0x92: M_SUB(m_DE.b.h); break; /* SUB D */ - case 0x93: M_SUB(m_DE.b.l); break; /* SUB E */ - case 0x94: M_SUB(m_HL.b.h); break; /* SUB H */ - case 0x95: M_SUB(m_HL.b.l); break; /* SUB L */ - case 0x96: m_WZ.b.l = RM(m_HL.d); M_SUB(m_WZ.b.l); break; /* SUB M */ - case 0x97: M_SUB(m_AF.b.h); break; /* SUB A */ - - case 0x98: M_SBB(m_BC.b.h); break; /* SBB B */ - case 0x99: M_SBB(m_BC.b.l); break; /* SBB C */ - case 0x9a: M_SBB(m_DE.b.h); break; /* SBB D */ - case 0x9b: M_SBB(m_DE.b.l); break; /* SBB E */ - case 0x9c: M_SBB(m_HL.b.h); break; /* SBB H */ - case 0x9d: M_SBB(m_HL.b.l); break; /* SBB L */ - case 0x9e: m_WZ.b.l = RM(m_HL.d); M_SBB(m_WZ.b.l); break; /* SBB M */ - case 0x9f: M_SBB(m_AF.b.h); break; /* SBB A */ - - case 0xa0: M_ANA(m_BC.b.h); break; /* ANA B */ - case 0xa1: M_ANA(m_BC.b.l); break; /* ANA C */ - case 0xa2: M_ANA(m_DE.b.h); break; /* ANA D */ - case 0xa3: M_ANA(m_DE.b.l); break; /* ANA E */ - case 0xa4: M_ANA(m_HL.b.h); break; /* ANA H */ - case 0xa5: M_ANA(m_HL.b.l); break; /* ANA L */ - case 0xa6: m_WZ.b.l = RM(m_HL.d); M_ANA(m_WZ.b.l); break; /* ANA M */ - case 0xa7: M_ANA(m_AF.b.h); break; /* ANA A */ - - case 0xa8: M_XRA(m_BC.b.h); break; /* XRA B */ - case 0xa9: M_XRA(m_BC.b.l); break; /* XRA C */ - case 0xaa: M_XRA(m_DE.b.h); break; /* XRA D */ - case 0xab: M_XRA(m_DE.b.l); break; /* XRA E */ - case 0xac: M_XRA(m_HL.b.h); break; /* XRA H */ - case 0xad: M_XRA(m_HL.b.l); break; /* XRA L */ - case 0xae: m_WZ.b.l = RM(m_HL.d); M_XRA(m_WZ.b.l); break; /* XRA M */ - case 0xaf: M_XRA(m_AF.b.h); break; /* XRA A */ - - case 0xb0: M_ORA(m_BC.b.h); break; /* ORA B */ - case 0xb1: M_ORA(m_BC.b.l); break; /* ORA C */ - case 0xb2: M_ORA(m_DE.b.h); break; /* ORA D */ - case 0xb3: M_ORA(m_DE.b.l); break; /* ORA E */ - case 0xb4: M_ORA(m_HL.b.h); break; /* ORA H */ - case 0xb5: M_ORA(m_HL.b.l); break; /* ORA L */ - case 0xb6: m_WZ.b.l = RM(m_HL.d); M_ORA(m_WZ.b.l); break; /* ORA M */ - case 0xb7: M_ORA(m_AF.b.h); break; /* ORA A */ - - case 0xb8: M_CMP(m_BC.b.h); break; /* CMP B */ - case 0xb9: M_CMP(m_BC.b.l); break; /* CMP C */ - case 0xba: M_CMP(m_DE.b.h); break; /* CMP D */ - case 0xbb: M_CMP(m_DE.b.l); break; /* CMP E */ - case 0xbc: M_CMP(m_HL.b.h); break; /* CMP H */ - case 0xbd: M_CMP(m_HL.b.l); break; /* CMP L */ - case 0xbe: m_WZ.b.l = RM(m_HL.d); M_CMP(m_WZ.b.l); break; /* CMP M */ - case 0xbf: M_CMP(m_AF.b.h); break; /* CMP A */ - - case 0xc0: M_RET( !(m_AF.b.l & ZF) ); break; /* RNZ */ - case 0xc1: M_POP(BC); break; /* POP B */ - case 0xc2: M_JMP( !(m_AF.b.l & ZF) ); break; /* JNZ nnnn */ - case 0xc3: M_JMP(1); break; /* JMP nnnn */ - case 0xc4: M_CALL( !(m_AF.b.l & ZF) ); break; /* CNZ nnnn */ - case 0xc5: M_PUSH(BC); break; /* PUSH B */ - case 0xc6: m_WZ.b.l = ARG(); M_ADD(m_WZ.b.l); break; /* ADI nn */ - case 0xc7: M_RST(0); break; /* RST 0 */ - - case 0xc8: M_RET( m_AF.b.l & ZF ); break; /* RZ */ - case 0xc9: M_POP(PC); break; /* RET */ - case 0xca: M_JMP( m_AF.b.l & ZF ); break; /* JZ nnnn */ - case 0xcb: if (IS_8085()) { /* RST V */ - if (m_AF.b.l & VF) { M_RST(8); } - else m_icount += 6; // RST not taken - } else { M_JMP(1); } /* JMP nnnn undocumented */ - break; - case 0xcc: M_CALL( m_AF.b.l & ZF ); break; /* CZ nnnn */ - case 0xcd: M_CALL(1); break; /* CALL nnnn */ - case 0xce: m_WZ.b.l = ARG(); M_ADC(m_WZ.b.l); break; /* ACI nn */ - case 0xcf: M_RST(1); break; /* RST 1 */ - - case 0xd0: M_RET( !(m_AF.b.l & CF) ); break; /* RNC */ - case 0xd1: M_POP(DE); break; /* POP D */ - case 0xd2: M_JMP( !(m_AF.b.l & CF) ); break; /* JNC nnnn */ - case 0xd3: M_OUT; break; /* OUT nn */ - case 0xd4: M_CALL( !(m_AF.b.l & CF) ); break; /* CNC nnnn */ - case 0xd5: M_PUSH(DE); break; /* PUSH D */ - case 0xd6: m_WZ.b.l = ARG(); M_SUB(m_WZ.b.l); break; /* SUI nn */ - case 0xd7: M_RST(2); break; /* RST 2 */ - - case 0xd8: M_RET( m_AF.b.l & CF ); break; /* RC */ - case 0xd9: if (IS_8085()) { /* SHLX */ - m_WZ.w.l = m_DE.w.l; - WM(m_WZ.d, m_HL.b.l); m_WZ.w.l++; - WM(m_WZ.d, m_HL.b.h); - } else { M_POP(PC); } /* RET undocumented */ - break; - case 0xda: M_JMP( m_AF.b.l & CF ); break; /* JC nnnn */ - case 0xdb: M_IN; break; /* IN nn */ - case 0xdc: M_CALL( m_AF.b.l & CF ); break; /* CC nnnn */ - case 0xdd: if (IS_8085()) { M_JMP( !(m_AF.b.l & X5F) ); } /* JNX nnnn */ - else { M_CALL(1); } /* CALL nnnn undocumented */ - break; - case 0xde: m_WZ.b.l = ARG(); M_SBB(m_WZ.b.l); break; /* SBI nn */ - case 0xdf: M_RST(3); break; /* RST 3 */ - - case 0xe0: M_RET( !(m_AF.b.l & PF) ); break; /* RPO */ - case 0xe1: M_POP(HL); break; /* POP H */ - case 0xe2: M_JMP( !(m_AF.b.l & PF) ); break; /* JPO nnnn */ - case 0xe3: M_POP(WZ); M_PUSH(HL); /* XTHL */ - m_HL.d = m_WZ.d; - break; - case 0xe4: M_CALL( !(m_AF.b.l & PF) ); break; /* CPO nnnn */ - case 0xe5: M_PUSH(HL); break; /* PUSH H */ - case 0xe6: m_WZ.b.l = ARG(); M_ANA(m_WZ.b.l); break; /* ANI nn */ - case 0xe7: M_RST(4); break; /* RST 4 */ - - case 0xe8: M_RET( m_AF.b.l & PF ); break; /* RPE */ - case 0xe9: m_PC.d = m_HL.w.l; break; /* PCHL */ - case 0xea: M_JMP( m_AF.b.l & PF ); break; /* JPE nnnn */ - case 0xeb: m_WZ.d = m_DE.d; /* XCHG */ - m_DE.d = m_HL.d; - m_HL.d = m_WZ.d; - break; - case 0xec: M_CALL( m_AF.b.l & PF ); break; /* CPE nnnn */ - case 0xed: if (IS_8085()) { /* LHLX */ - m_WZ.w.l = m_DE.w.l; - m_HL.b.l = RM(m_WZ.d); m_WZ.w.l++; - m_HL.b.h = RM(m_WZ.d); - } else { M_CALL(1); } /* CALL nnnn undocumented */ - break; - case 0xee: m_WZ.b.l = ARG(); M_XRA(m_WZ.b.l); break; /* XRI nn */ - case 0xef: M_RST(5); break; /* RST 5 */ - - case 0xf0: M_RET( !(m_AF.b.l&SF) ); break; /* RP */ - case 0xf1: M_POP(AF); break; /* POP A */ - case 0xf2: M_JMP( !(m_AF.b.l & SF) ); break; /* JP nnnn */ - case 0xf3: set_inte(0); break; /* DI */ - case 0xf4: M_CALL( !(m_AF.b.l & SF) ); break; /* CP nnnn */ - case 0xf5: if (IS_8080()) m_AF.b.l = (m_AF.b.l&~(X3F|X5F))|VF; // on 8080, VF=1 and X3F=0 and X5F=0 always! (we don't have to check for it elsewhere) - M_PUSH(AF); break; /* PUSH A */ - case 0xf6: m_WZ.b.l = ARG(); M_ORA(m_WZ.b.l); break; /* ORI nn */ - case 0xf7: M_RST(6); break; /* RST 6 */ - - case 0xf8: M_RET( m_AF.b.l & SF ); break; /* RM */ - case 0xf9: m_SP.d = m_HL.d; break; /* SPHL */ - case 0xfa: M_JMP( m_AF.b.l & SF ); break; /* JM nnnn */ - case 0xfb: set_inte(1); m_after_ei = 2; break; /* EI */ - case 0xfc: M_CALL( m_AF.b.l & SF ); break; /* CM nnnn */ - case 0xfd: if (IS_8085()) { M_JMP( m_AF.b.l & X5F ); } /* JX nnnn */ - else { M_CALL(1); } /* CALL nnnn undocumented */ - break; - case 0xfe: m_WZ.b.l = ARG(); M_CMP(m_WZ.b.l); break; /* CPI nn */ - case 0xff: M_RST(7); break; /* RST 7 */ - } -} - - -/*************************************************************************** - COMMON EXECUTION -***************************************************************************/ - -void i8085a_cpu_device::execute_run() -{ - /* check for TRAPs before diving in (can't do others because of after_ei) */ - if (m_trap_pending || m_after_ei == 0) - check_for_interrupts(); - - do - { - debugger_instruction_hook(this, m_PC.d); - - /* the instruction after an EI does not take an interrupt, so - we cannot check immediately; handle post-EI behavior here */ - if (m_after_ei != 0 && --m_after_ei == 0) - check_for_interrupts(); - - /* here we go... */ - execute_one(ROP()); - - } while (m_icount > 0); -} - - - /*************************************************************************** CORE INITIALIZATION ***************************************************************************/ void i8085a_cpu_device::init_tables() { - uint8_t zs; + u8 zs; int i, p; for (i = 0; i < 256; i++) { /* cycles */ - lut_cycles[i] = m_cputype?lut_cycles_8085[i]:lut_cycles_8080[i]; + lut_cycles[i] = is_8085() ? lut_cycles_8085[i] : lut_cycles_8080[i]; /* flags */ zs = 0; @@ -907,12 +284,11 @@ void i8085a_cpu_device::init_tables() if (i&32) ++p; if (i&64) ++p; if (i&128) ++p; - ZS[i] = zs; - ZSP[i] = zs | ((p&1) ? 0 : PF); + lut_zs[i] = zs; + lut_zsp[i] = zs | ((p&1) ? 0 : PF); } } - void i8085a_cpu_device::device_start() { m_PC.d = 0; @@ -922,9 +298,9 @@ void i8085a_cpu_device::device_start() m_DE.d = 0; m_HL.d = 0; m_WZ.d = 0; - m_HALT = 0; - m_IM = 0; - m_STATUS = 0; + m_halt = 0; + m_im = 0; + m_status = 0; m_after_ei = 0; m_nmi_state = 0; m_irq_state[3] = m_irq_state[2] = m_irq_state[1] = m_irq_state[0] = 0; @@ -955,14 +331,15 @@ void i8085a_cpu_device::device_start() state_add(I8085_BC, "BC", m_BC.w.l); state_add(I8085_DE, "DE", m_DE.w.l); state_add(I8085_HL, "HL", m_HL.w.l); - state_add(I8085_STATUS, "STATUS", m_STATUS); + state_add(I8085_STATUS, "STATUS", m_status); state_add(I8085_SOD, "SOD", m_sod_state).mask(0x1); state_add(I8085_SID, "SID", m_ietemp).mask(0x1).callimport().callexport(); state_add(I8085_INTE, "INTE", m_ietemp).mask(0x1).callimport().callexport(); } m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); + m_opcode_direct = has_space(AS_OPCODES) ? space(AS_OPCODES).direct<0>() : m_direct; m_io = &space(AS_IO); /* resolve callbacks */ @@ -978,9 +355,9 @@ void i8085a_cpu_device::device_start() save_item(NAME(m_BC.w.l)); save_item(NAME(m_DE.w.l)); save_item(NAME(m_HL.w.l)); - save_item(NAME(m_HALT)); - save_item(NAME(m_IM)); - save_item(NAME(m_STATUS)); + save_item(NAME(m_halt)); + save_item(NAME(m_im)); + save_item(NAME(m_status)); save_item(NAME(m_after_ei)); save_item(NAME(m_nmi_state)); save_item(NAME(m_irq_state)); @@ -999,9 +376,9 @@ void i8085a_cpu_device::device_start() void i8085a_cpu_device::device_reset() { m_PC.d = 0; - m_HALT = 0; - m_IM &= ~IM_I75; - m_IM |= IM_M55 | IM_M65 | IM_M75; + m_halt = 0; + m_im &= ~IM_I75; + m_im |= IM_M55 | IM_M65 | IM_M75; m_after_ei = false; m_trap_pending = false; m_trap_im_copy = 0; @@ -1010,7 +387,6 @@ void i8085a_cpu_device::device_reset() } - /*************************************************************************** COMMON STATE IMPORT/EXPORT ***************************************************************************/ @@ -1022,22 +398,22 @@ void i8085a_cpu_device::state_import(const device_state_entry &entry) case I8085_SID: if (m_ietemp) { - m_IM |= IM_SID; + m_im |= IM_SID; } else { - m_IM &= ~IM_SID; + m_im &= ~IM_SID; } break; case I8085_INTE: if (m_ietemp) { - m_IM |= IM_IE; + m_im |= IM_IE; } else { - m_IM &= ~IM_IE; + m_im &= ~IM_IE; } break; @@ -1046,17 +422,16 @@ void i8085a_cpu_device::state_import(const device_state_entry &entry) } } - void i8085a_cpu_device::state_export(const device_state_entry &entry) { switch (entry.index()) { case I8085_SID: - m_ietemp = ((m_IM & IM_SID) != 0) && m_in_sid_func() != 0; + m_ietemp = ((m_im & IM_SID) != 0) && m_in_sid_func() != 0; break; case I8085_INTE: - m_ietemp = ((m_IM & IM_IE) != 0); + m_ietemp = ((m_im & IM_IE) != 0); break; default: @@ -1082,6 +457,15 @@ void i8085a_cpu_device::state_string_export(const device_state_entry &entry, std } } +util::disasm_interface *i8085a_cpu_device::create_disassembler() +{ + return new i8085_disassembler; +} + + +/*************************************************************************** + INTERRUPTS +***************************************************************************/ void i8085a_cpu_device::execute_set_input(int irqline, int state) { @@ -1099,7 +483,7 @@ void i8085a_cpu_device::execute_set_input(int irqline, int state) else if (irqline == I8085_RST75_LINE) { if (!m_irq_state[I8085_RST75_LINE] && newstate) - m_IM |= IM_I75; + m_im |= IM_I75; m_irq_state[I8085_RST75_LINE] = newstate; } @@ -1108,9 +492,1133 @@ void i8085a_cpu_device::execute_set_input(int irqline, int state) m_irq_state[irqline] = state; } +void i8085a_cpu_device::break_halt_for_interrupt() +{ + /* de-halt if necessary */ + if (m_halt) + { + m_PC.w.l++; + m_halt = 0; + set_status(0x26); /* int ack while halt */ + } + else + set_status(0x23); /* int ack */ +} + +void i8085a_cpu_device::check_for_interrupts() +{ + /* TRAP is the highest priority */ + if (m_trap_pending) + { + /* the first RIM after a TRAP reflects the original IE state; remember it here, + setting the high bit to indicate it is valid */ + m_trap_im_copy = m_im | 0x80; + + /* reset the pending state */ + m_trap_pending = false; + + /* break out of HALT state and call the IRQ ack callback */ + break_halt_for_interrupt(); + standard_irq_callback(INPUT_LINE_NMI); + + /* push the PC and jump to $0024 */ + op_push(m_PC); + set_inte(0); + m_PC.w.l = ADDR_TRAP; + m_icount -= 11; + } + + /* followed by RST7.5 */ + else if ((m_im & IM_I75) && !(m_im & IM_M75) && (m_im & IM_IE)) + { + /* reset the pending state (which is CPU-visible via the RIM instruction) */ + m_im &= ~IM_I75; + + /* break out of HALT state and call the IRQ ack callback */ + break_halt_for_interrupt(); + standard_irq_callback(I8085_RST75_LINE); + + /* push the PC and jump to $003C */ + op_push(m_PC); + set_inte(0); + m_PC.w.l = ADDR_RST75; + m_icount -= 11; + } + + /* followed by RST6.5 */ + else if (m_irq_state[I8085_RST65_LINE] && !(m_im & IM_M65) && (m_im & IM_IE)) + { + /* break out of HALT state and call the IRQ ack callback */ + break_halt_for_interrupt(); + standard_irq_callback(I8085_RST65_LINE); + + /* push the PC and jump to $0034 */ + op_push(m_PC); + set_inte(0); + m_PC.w.l = ADDR_RST65; + m_icount -= 11; + } + + /* followed by RST5.5 */ + else if (m_irq_state[I8085_RST55_LINE] && !(m_im & IM_M55) && (m_im & IM_IE)) + { + /* break out of HALT state and call the IRQ ack callback */ + break_halt_for_interrupt(); + standard_irq_callback(I8085_RST55_LINE); + + /* push the PC and jump to $002C */ + op_push(m_PC); + set_inte(0); + m_PC.w.l = ADDR_RST55; + m_icount -= 11; + } + + /* followed by classic INTR */ + else if (m_irq_state[I8085_INTR_LINE] && (m_im & IM_IE)) + { + u32 vector; + + /* break out of HALT state and call the IRQ ack callback */ + break_halt_for_interrupt(); + vector = standard_irq_callback(I8085_INTR_LINE); + + /* use the resulting vector as an opcode to execute */ + set_inte(0); + switch (vector & 0xff0000) + { + case 0xcd0000: /* CALL nnnn */ + m_icount -= 7; + op_push(m_PC); + case 0xc30000: /* JMP nnnn */ + m_icount -= 10; + m_PC.d = vector & 0xffff; + break; + + default: + LOG("i8085 take int $%02x\n", vector); + execute_one(vector & 0xff); + break; + } + } +} + + +/*************************************************************************** + OPCODE HELPERS +***************************************************************************/ -offs_t i8085a_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +void i8085a_cpu_device::set_sod(int state) { - extern CPU_DISASSEMBLE( i8085 ); - return CPU_DISASSEMBLE_NAME(i8085)(this, stream, pc, oprom, opram, options); + if (state != 0 && m_sod_state == 0) + { + m_sod_state = 1; + m_out_sod_func(m_sod_state); + } + else if (state == 0 && m_sod_state != 0) + { + m_sod_state = 0; + m_out_sod_func(m_sod_state); + } +} + +void i8085a_cpu_device::set_inte(int state) +{ + if (state != 0 && (m_im & IM_IE) == 0) + { + m_im |= IM_IE; + m_out_inte_func(1); + } + else if (state == 0 && (m_im & IM_IE) != 0) + { + m_im &= ~IM_IE; + m_out_inte_func(0); + } +} + +void i8085a_cpu_device::set_status(u8 status) +{ + if (status != m_status) + m_out_status_func(status); + + m_status = status; +} + +u8 i8085a_cpu_device::get_rim_value() +{ + u8 result = m_im; + int sid = m_in_sid_func(); + + /* copy live RST5.5 and RST6.5 states */ + result &= ~(IM_I65 | IM_I55); + if (m_irq_state[I8085_RST65_LINE]) result |= IM_I65; + if (m_irq_state[I8085_RST55_LINE]) result |= IM_I55; + + /* fetch the SID bit if we have a callback */ + result = (result & ~IM_SID) | (sid ? IM_SID : 0); + + return result; +} + +// memory access +u8 i8085a_cpu_device::read_arg() +{ + return m_direct->read_byte(m_PC.w.l++); +} + +PAIR i8085a_cpu_device::read_arg16() +{ + PAIR p; + p.b.l = m_direct->read_byte(m_PC.w.l++); + p.b.h = m_direct->read_byte(m_PC.w.l++); + return p; +} + +u8 i8085a_cpu_device::read_op() +{ + set_status(0xa2); // instruction fetch + return m_opcode_direct->read_byte(m_PC.w.l++); +} + +u8 i8085a_cpu_device::read_mem(u32 a) +{ + set_status(0x82); // memory read + return m_program->read_byte(a); +} + +void i8085a_cpu_device::write_mem(u32 a, u8 v) +{ + set_status(0x00); // memory write + m_program->write_byte(a, v); +} + +void i8085a_cpu_device::op_push(PAIR p) +{ + set_status(0x04); // stack push + m_program->write_byte(--m_SP.w.l, p.b.h); + m_program->write_byte(--m_SP.w.l, p.b.l); +} + +PAIR i8085a_cpu_device::op_pop() +{ + PAIR p; + set_status(0x86); // stack pop + p.b.l = m_program->read_byte(m_SP.w.l++); + p.b.h = m_program->read_byte(m_SP.w.l++); + return p; +} + +// logical +void i8085a_cpu_device::op_ora(u8 v) +{ + m_AF.b.h |= v; + m_AF.b.l = lut_zsp[m_AF.b.h]; +} + +void i8085a_cpu_device::op_xra(u8 v) +{ + m_AF.b.h ^= v; + m_AF.b.l = lut_zsp[m_AF.b.h]; +} + +void i8085a_cpu_device::op_ana(u8 v) +{ + u8 hc = ((m_AF.b.h | v) << 1) & HF; + m_AF.b.h &= v; + m_AF.b.l = lut_zsp[m_AF.b.h]; + if (is_8085()) + m_AF.b.l |= HF; + else + m_AF.b.l |= hc; +} + +// increase / decrease +u8 i8085a_cpu_device::op_inr(u8 v) +{ + u8 hc = ((v & 0x0f) == 0x0f) ? HF : 0; + m_AF.b.l = (m_AF.b.l & CF) | lut_zsp[++v] | hc; + return v; +} + +u8 i8085a_cpu_device::op_dcr(u8 v) +{ + u8 hc = ((v & 0x0f) != 0x00) ? HF : 0; + m_AF.b.l = (m_AF.b.l & CF) | lut_zsp[--v] | hc | VF; + return v; +} + +// arithmetic +void i8085a_cpu_device::op_add(u8 v) +{ + int q = m_AF.b.h + v; + m_AF.b.l = lut_zsp[q & 0xff] | ((q >> 8) & CF) | ((m_AF.b.h ^ q ^ v) & HF); + m_AF.b.h = q; +} + +void i8085a_cpu_device::op_adc(u8 v) +{ + int q = m_AF.b.h + v + (m_AF.b.l & CF); + m_AF.b.l = lut_zsp[q & 0xff] | ((q >> 8) & CF) | ((m_AF.b.h ^ q ^ v) & HF); + m_AF.b.h = q; +} + +void i8085a_cpu_device::op_sub(u8 v) +{ + int q = m_AF.b.h - v; + m_AF.b.l = lut_zsp[q & 0xff] | ((q >> 8) & CF) | (~(m_AF.b.h ^ q ^ v) & HF) | VF; + m_AF.b.h = q; +} + +void i8085a_cpu_device::op_sbb(u8 v) +{ + int q = m_AF.b.h - v - (m_AF.b.l & CF); + m_AF.b.l = lut_zsp[q & 0xff] | ((q >> 8) & CF) | (~(m_AF.b.h ^ q ^ v) & HF) | VF; + m_AF.b.h = q; +} + +void i8085a_cpu_device::op_cmp(u8 v) +{ + int q = m_AF.b.h - v; + m_AF.b.l = lut_zsp[q & 0xff] | ((q >> 8) & CF) | (~(m_AF.b.h ^ q ^ v) & HF) | VF; +} + +void i8085a_cpu_device::op_dad(u16 v) +{ + int q = m_HL.w.l + v; + m_AF.b.l = (m_AF.b.l & ~CF) | (q >> 16 & CF); + m_HL.w.l = q; +} + +// jumps +void i8085a_cpu_device::op_jmp(int cond) +{ + // on 8085, jump if condition is not satisfied is shorter + if (cond) + m_PC = read_arg16(); + else + { + m_PC.w.l += 2; + m_icount += (is_8085()) ? 3 : 0; + } +} + +void i8085a_cpu_device::op_call(int cond) +{ + // on 8085, call if condition is not satisfied is 9 ticks + if (cond) + { + PAIR p = read_arg16(); + m_icount -= (is_8085()) ? 7 : 6 ; + op_push(m_PC); + m_PC = p; + } + else + { + m_PC.w.l += 2; + m_icount += (is_8085()) ? 2 : 0; + } +} + +void i8085a_cpu_device::op_ret(int cond) +{ + // conditional RET only + if (cond) + { + m_icount -= 6; + m_PC = op_pop(); + } +} + +void i8085a_cpu_device::op_rst(u8 v) +{ + op_push(m_PC); + m_PC.d = 8 * v; +} + + +/*************************************************************************** + COMMON EXECUTION +***************************************************************************/ + +void i8085a_cpu_device::execute_run() +{ + /* check for TRAPs before diving in (can't do others because of after_ei) */ + if (m_trap_pending || m_after_ei == 0) + check_for_interrupts(); + + do + { + debugger_instruction_hook(this, m_PC.d); + + /* the instruction after an EI does not take an interrupt, so + we cannot check immediately; handle post-EI behavior here */ + if (m_after_ei != 0 && --m_after_ei == 0) + check_for_interrupts(); + + /* here we go... */ + execute_one(read_op()); + + } while (m_icount > 0); +} + +void i8085a_cpu_device::execute_one(int opcode) +{ + m_icount -= lut_cycles[opcode]; + + switch (opcode) + { + case 0x00: // NOP + break; + case 0x01: // LXI B,nnnn + m_BC = read_arg16(); + break; + case 0x02: // STAX B + write_mem(m_BC.d, m_AF.b.h); + break; + case 0x03: // INX B + m_BC.w.l++; + if (is_8085()) + { + if (m_BC.w.l == 0x0000) + m_AF.b.l |= X5F; + else + m_AF.b.l &= ~X5F; + } + break; + case 0x04: // INR B + m_BC.b.h = op_inr(m_BC.b.h); + break; + case 0x05: // DCR B + m_BC.b.h = op_dcr(m_BC.b.h); + break; + case 0x06: // MVI B,nn + m_BC.b.h = read_arg(); + break; + case 0x07: // RLC + m_AF.b.h = (m_AF.b.h << 1) | (m_AF.b.h >> 7); + m_AF.b.l = (m_AF.b.l & 0xfe) | (m_AF.b.h & CF); + break; + + case 0x08: // 8085: DSUB, otherwise undocumented NOP + if (is_8085()) + { + int q = m_HL.b.l - m_BC.b.l; + m_AF.b.l = lut_zs[q & 0xff] | ((q >> 8) & CF) | VF | ((m_HL.b.l ^ q ^ m_BC.b.l) & HF) | (((m_BC.b.l ^ m_HL.b.l) & (m_HL.b.l ^ q) & SF) >> 5); + m_HL.b.l = q; + q = m_HL.b.h - m_BC.b.h - (m_AF.b.l & CF); + m_AF.b.l = lut_zs[q & 0xff] | ((q >> 8) & CF) | VF | ((m_HL.b.h ^ q ^ m_BC.b.h) & HF) | (((m_BC.b.h ^ m_HL.b.h) & (m_HL.b.h ^ q) & SF) >> 5); + if (m_HL.b.l != 0) + m_AF.b.l &= ~ZF; + } + break; + case 0x09: // DAD B + op_dad(m_BC.w.l); + break; + case 0x0a: // LDAX B + m_AF.b.h = read_mem(m_BC.d); + break; + case 0x0b: // DCX B + m_BC.w.l--; + if (is_8085()) + { + if (m_BC.w.l == 0xffff) + m_AF.b.l |= X5F; + else + m_AF.b.l &= ~X5F; + } + break; + case 0x0c: // INR C + m_BC.b.l = op_inr(m_BC.b.l); + break; + case 0x0d: // DCR C + m_BC.b.l = op_dcr(m_BC.b.l); + break; + case 0x0e: // MVI C,nn + m_BC.b.l = read_arg(); + break; + case 0x0f: // RRC + m_AF.b.l = (m_AF.b.l & 0xfe) | (m_AF.b.h & CF); + m_AF.b.h = (m_AF.b.h >> 1) | (m_AF.b.h << 7); + break; + + case 0x10: // 8085: ASRH, otherwise undocumented NOP + if (is_8085()) + { + m_AF.b.l = (m_AF.b.l & ~CF) | (m_HL.b.l & CF); + m_HL.w.l = (m_HL.w.l >> 1); + } + break; + case 0x11: // LXI D,nnnn + m_DE = read_arg16(); + break; + case 0x12: // STAX D + write_mem(m_DE.d, m_AF.b.h); + break; + case 0x13: // INX D + m_DE.w.l++; + if (is_8085()) + { + if (m_DE.w.l == 0x0000) + m_AF.b.l |= X5F; + else + m_AF.b.l &= ~X5F; + } + break; + case 0x14: // INR D + m_DE.b.h = op_inr(m_DE.b.h); + break; + case 0x15: // DCR D + m_DE.b.h = op_dcr(m_DE.b.h); + break; + case 0x16: // MVI D,nn + m_DE.b.h = read_arg(); + break; + case 0x17: // RAL + { + int c = m_AF.b.l & CF; + m_AF.b.l = (m_AF.b.l & 0xfe) | (m_AF.b.h >> 7); + m_AF.b.h = (m_AF.b.h << 1) | c; + break; + } + + case 0x18: // 8085: RLDE, otherwise undocumented NOP + if (is_8085()) + { + m_AF.b.l = (m_AF.b.l & ~(CF | VF)) | (m_DE.b.h >> 7); + m_DE.w.l = (m_DE.w.l << 1) | (m_DE.w.l >> 15); + if ((((m_DE.w.l >> 15) ^ m_AF.b.l) & CF) != 0) + m_AF.b.l |= VF; + } + break; + case 0x19: // DAD D + op_dad(m_DE.w.l); + break; + case 0x1a: // LDAX D + m_AF.b.h = read_mem(m_DE.d); + break; + case 0x1b: // DCX D + m_DE.w.l--; + if (is_8085()) + { + if (m_DE.w.l == 0xffff) + m_AF.b.l |= X5F; + else + m_AF.b.l &= ~X5F; + } + break; + case 0x1c: // INR E + m_DE.b.l = op_inr(m_DE.b.l); + break; + case 0x1d: // DCR E + m_DE.b.l = op_dcr(m_DE.b.l); + break; + case 0x1e: // MVI E,nn + m_DE.b.l = read_arg(); + break; + case 0x1f: // RAR + { + int c = (m_AF.b.l & CF) << 7; + m_AF.b.l = (m_AF.b.l & 0xfe) | (m_AF.b.h & CF); + m_AF.b.h = (m_AF.b.h >> 1) | c; + break; + } + + case 0x20: // 8085: RIM, otherwise undocumented NOP + if (is_8085()) + { + m_AF.b.h = get_rim_value(); + + // if we have remembered state from taking a TRAP, fix up the IE flag here + if (m_trap_im_copy & 0x80) + m_AF.b.h = (m_AF.b.h & ~IM_IE) | (m_trap_im_copy & IM_IE); + m_trap_im_copy = 0; + } + break; + case 0x21: // LXI H,nnnn + m_HL = read_arg16(); + break; + case 0x22: // SHLD nnnn + m_WZ = read_arg16(); + write_mem(m_WZ.d, m_HL.b.l); + m_WZ.w.l++; + write_mem(m_WZ.d, m_HL.b.h); + break; + case 0x23: // INX H + m_HL.w.l++; + if (is_8085()) + { + if (m_HL.w.l == 0x0000) + m_AF.b.l |= X5F; + else + m_AF.b.l &= ~X5F; + } + break; + case 0x24: // INR H + m_HL.b.h = op_inr(m_HL.b.h); + break; + case 0x25: // DCR H + m_HL.b.h = op_dcr(m_HL.b.h); + break; + case 0x26: // MVI H,nn + m_HL.b.h = read_arg(); + break; + case 0x27: // DAA + m_WZ.b.h = m_AF.b.h; + if (is_8085() && m_AF.b.l & VF) + { + if ((m_AF.b.l & HF) || ((m_AF.b.h & 0xf) > 9)) + m_WZ.b.h -= 6; + if ((m_AF.b.l & CF) || (m_AF.b.h > 0x99)) + m_WZ.b.h -= 0x60; + } + else + { + if ((m_AF.b.l & HF) || ((m_AF.b.h & 0xf) > 9)) + m_WZ.b.h += 6; + if ((m_AF.b.l & CF) || (m_AF.b.h > 0x99)) + m_WZ.b.h += 0x60; + } + + m_AF.b.l = (m_AF.b.l & 3) | (m_AF.b.h & 0x28) | ((m_AF.b.h > 0x99) ? 1 : 0) | ((m_AF.b.h ^ m_WZ.b.h) & 0x10) | lut_zsp[m_WZ.b.h]; + m_AF.b.h = m_WZ.b.h; + break; + + case 0x28: // 8085: LDEH nn, otherwise undocumented NOP + if (is_8085()) + { + m_WZ.d = read_arg(); + m_DE.d = (m_HL.d + m_WZ.d) & 0xffff; + } + break; + case 0x29: // DAD H + op_dad(m_HL.w.l); + break; + case 0x2a: // LHLD nnnn + m_WZ = read_arg16(); + m_HL.b.l = read_mem(m_WZ.d); + m_WZ.w.l++; + m_HL.b.h = read_mem(m_WZ.d); + break; + case 0x2b: // DCX H + m_HL.w.l--; + if (is_8085()) + { + if (m_HL.w.l == 0xffff) + m_AF.b.l |= X5F; + else + m_AF.b.l &= ~X5F; + } + break; + case 0x2c: // INR L + m_HL.b.l = op_inr(m_HL.b.l); + break; + case 0x2d: // DCR L + m_HL.b.l = op_dcr(m_HL.b.l); + break; + case 0x2e: // MVI L,nn + m_HL.b.l = read_arg(); + break; + case 0x2f: // CMA + m_AF.b.h ^= 0xff; + if (is_8085()) + m_AF.b.l |= HF | VF; + break; + + case 0x30: // 8085: SIM, otherwise undocumented NOP + if (is_8085()) + { + // if bit 3 is set, bits 0-2 become the new masks + if (m_AF.b.h & 0x08) + { + m_im &= ~(IM_M55 | IM_M65 | IM_M75 | IM_I55 | IM_I65); + m_im |= m_AF.b.h & (IM_M55 | IM_M65 | IM_M75); + + // update live state based on the new masks + if ((m_im & IM_M55) == 0 && m_irq_state[I8085_RST55_LINE]) + m_im |= IM_I55; + if ((m_im & IM_M65) == 0 && m_irq_state[I8085_RST65_LINE]) + m_im |= IM_I65; + } + + // bit if 4 is set, the 7.5 flip-flop is cleared + if (m_AF.b.h & 0x10) + m_im &= ~IM_I75; + + // if bit 6 is set, then bit 7 is the new SOD state + if (m_AF.b.h & 0x40) + set_sod(m_AF.b.h >> 7); + + // check for revealed interrupts + check_for_interrupts(); + } + break; + case 0x31: // LXI SP,nnnn + m_SP = read_arg16(); + break; + case 0x32: // STAX nnnn + m_WZ = read_arg16(); + write_mem(m_WZ.d, m_AF.b.h); + break; + case 0x33: // INX SP + m_SP.w.l++; + if (is_8085()) + { + if (m_SP.w.l == 0x0000) + m_AF.b.l |= X5F; + else + m_AF.b.l &= ~X5F; + } + break; + case 0x34: // INR M + m_WZ.b.l = op_inr(read_mem(m_HL.d)); + write_mem(m_HL.d, m_WZ.b.l); + break; + case 0x35: // DCR M + m_WZ.b.l = op_dcr(read_mem(m_HL.d)); + write_mem(m_HL.d, m_WZ.b.l); + break; + case 0x36: // MVI M,nn + m_WZ.b.l = read_arg(); + write_mem(m_HL.d, m_WZ.b.l); + break; + case 0x37: // STC + m_AF.b.l = (m_AF.b.l & 0xfe) | CF; + break; + + case 0x38: // 8085: LDES nn, otherwise undocumented NOP + if (is_8085()) + { + m_WZ.d = read_arg(); + m_DE.d = (m_SP.d + m_WZ.d) & 0xffff; + } + break; + case 0x39: // DAD SP + op_dad(m_SP.w.l); + break; + case 0x3a: // LDAX nnnn + m_WZ = read_arg16(); + m_AF.b.h = read_mem(m_WZ.d); + break; + case 0x3b: // DCX SP + m_SP.w.l--; + if (is_8085()) + { + if (m_SP.w.l == 0xffff) + m_AF.b.l |= X5F; + else + m_AF.b.l &= ~X5F; + } + break; + case 0x3c: // INR A + m_AF.b.h = op_inr(m_AF.b.h); + break; + case 0x3d: // DCR A + m_AF.b.h = op_dcr(m_AF.b.h); + break; + case 0x3e: // MVI A,nn + m_AF.b.h = read_arg(); + break; + case 0x3f: // CMC + m_AF.b.l = (m_AF.b.l & 0xfe) | (~m_AF.b.l & CF); + break; + + // MOV [B/C/D/E/H/L/M/A],[B/C/D/E/H/L/M/A] + case 0x40: break; // MOV B,B + case 0x41: m_BC.b.h = m_BC.b.l; break; + case 0x42: m_BC.b.h = m_DE.b.h; break; + case 0x43: m_BC.b.h = m_DE.b.l; break; + case 0x44: m_BC.b.h = m_HL.b.h; break; + case 0x45: m_BC.b.h = m_HL.b.l; break; + case 0x46: m_BC.b.h = read_mem(m_HL.d); break; + case 0x47: m_BC.b.h = m_AF.b.h; break; + + case 0x48: m_BC.b.l = m_BC.b.h; break; + case 0x49: break; // MOV C,C + case 0x4a: m_BC.b.l = m_DE.b.h; break; + case 0x4b: m_BC.b.l = m_DE.b.l; break; + case 0x4c: m_BC.b.l = m_HL.b.h; break; + case 0x4d: m_BC.b.l = m_HL.b.l; break; + case 0x4e: m_BC.b.l = read_mem(m_HL.d); break; + case 0x4f: m_BC.b.l = m_AF.b.h; break; + + case 0x50: m_DE.b.h = m_BC.b.h; break; + case 0x51: m_DE.b.h = m_BC.b.l; break; + case 0x52: break; // MOV D,D + case 0x53: m_DE.b.h = m_DE.b.l; break; + case 0x54: m_DE.b.h = m_HL.b.h; break; + case 0x55: m_DE.b.h = m_HL.b.l; break; + case 0x56: m_DE.b.h = read_mem(m_HL.d); break; + case 0x57: m_DE.b.h = m_AF.b.h; break; + + case 0x58: m_DE.b.l = m_BC.b.h; break; + case 0x59: m_DE.b.l = m_BC.b.l; break; + case 0x5a: m_DE.b.l = m_DE.b.h; break; + case 0x5b: break; // MOV E,E + case 0x5c: m_DE.b.l = m_HL.b.h; break; + case 0x5d: m_DE.b.l = m_HL.b.l; break; + case 0x5e: m_DE.b.l = read_mem(m_HL.d); break; + case 0x5f: m_DE.b.l = m_AF.b.h; break; + + case 0x60: m_HL.b.h = m_BC.b.h; break; + case 0x61: m_HL.b.h = m_BC.b.l; break; + case 0x62: m_HL.b.h = m_DE.b.h; break; + case 0x63: m_HL.b.h = m_DE.b.l; break; + case 0x64: break; // MOV H,H + case 0x65: m_HL.b.h = m_HL.b.l; break; + case 0x66: m_HL.b.h = read_mem(m_HL.d); break; + case 0x67: m_HL.b.h = m_AF.b.h; break; + + case 0x68: m_HL.b.l = m_BC.b.h; break; + case 0x69: m_HL.b.l = m_BC.b.l; break; + case 0x6a: m_HL.b.l = m_DE.b.h; break; + case 0x6b: m_HL.b.l = m_DE.b.l; break; + case 0x6c: m_HL.b.l = m_HL.b.h; break; + case 0x6d: break; // MOV L,L + case 0x6e: m_HL.b.l = read_mem(m_HL.d); break; + case 0x6f: m_HL.b.l = m_AF.b.h; break; + + case 0x70: write_mem(m_HL.d, m_BC.b.h); break; + case 0x71: write_mem(m_HL.d, m_BC.b.l); break; + case 0x72: write_mem(m_HL.d, m_DE.b.h); break; + case 0x73: write_mem(m_HL.d, m_DE.b.l); break; + case 0x74: write_mem(m_HL.d, m_HL.b.h); break; + case 0x75: write_mem(m_HL.d, m_HL.b.l); break; + case 0x76: // HLT (instead of MOV M,M) + m_PC.w.l--; + m_halt = 1; + set_status(0x8a); // halt acknowledge + break; + case 0x77: write_mem(m_HL.d, m_AF.b.h); break; + + case 0x78: m_AF.b.h = m_BC.b.h; break; + case 0x79: m_AF.b.h = m_BC.b.l; break; + case 0x7a: m_AF.b.h = m_DE.b.h; break; + case 0x7b: m_AF.b.h = m_DE.b.l; break; + case 0x7c: m_AF.b.h = m_HL.b.h; break; + case 0x7d: m_AF.b.h = m_HL.b.l; break; + case 0x7e: m_AF.b.h = read_mem(m_HL.d); break; + case 0x7f: break; // MOV A,A + + // alu op [B/C/D/E/H/L/M/A] + case 0x80: op_add(m_BC.b.h); break; + case 0x81: op_add(m_BC.b.l); break; + case 0x82: op_add(m_DE.b.h); break; + case 0x83: op_add(m_DE.b.l); break; + case 0x84: op_add(m_HL.b.h); break; + case 0x85: op_add(m_HL.b.l); break; + case 0x86: m_WZ.b.l = read_mem(m_HL.d); op_add(m_WZ.b.l); break; + case 0x87: op_add(m_AF.b.h); break; + + case 0x88: op_adc(m_BC.b.h); break; + case 0x89: op_adc(m_BC.b.l); break; + case 0x8a: op_adc(m_DE.b.h); break; + case 0x8b: op_adc(m_DE.b.l); break; + case 0x8c: op_adc(m_HL.b.h); break; + case 0x8d: op_adc(m_HL.b.l); break; + case 0x8e: m_WZ.b.l = read_mem(m_HL.d); op_adc(m_WZ.b.l); break; + case 0x8f: op_adc(m_AF.b.h); break; + + case 0x90: op_sub(m_BC.b.h); break; + case 0x91: op_sub(m_BC.b.l); break; + case 0x92: op_sub(m_DE.b.h); break; + case 0x93: op_sub(m_DE.b.l); break; + case 0x94: op_sub(m_HL.b.h); break; + case 0x95: op_sub(m_HL.b.l); break; + case 0x96: m_WZ.b.l = read_mem(m_HL.d); op_sub(m_WZ.b.l); break; + case 0x97: op_sub(m_AF.b.h); break; + + case 0x98: op_sbb(m_BC.b.h); break; + case 0x99: op_sbb(m_BC.b.l); break; + case 0x9a: op_sbb(m_DE.b.h); break; + case 0x9b: op_sbb(m_DE.b.l); break; + case 0x9c: op_sbb(m_HL.b.h); break; + case 0x9d: op_sbb(m_HL.b.l); break; + case 0x9e: m_WZ.b.l = read_mem(m_HL.d); op_sbb(m_WZ.b.l); break; + case 0x9f: op_sbb(m_AF.b.h); break; + + case 0xa0: op_ana(m_BC.b.h); break; + case 0xa1: op_ana(m_BC.b.l); break; + case 0xa2: op_ana(m_DE.b.h); break; + case 0xa3: op_ana(m_DE.b.l); break; + case 0xa4: op_ana(m_HL.b.h); break; + case 0xa5: op_ana(m_HL.b.l); break; + case 0xa6: m_WZ.b.l = read_mem(m_HL.d); op_ana(m_WZ.b.l); break; + case 0xa7: op_ana(m_AF.b.h); break; + + case 0xa8: op_xra(m_BC.b.h); break; + case 0xa9: op_xra(m_BC.b.l); break; + case 0xaa: op_xra(m_DE.b.h); break; + case 0xab: op_xra(m_DE.b.l); break; + case 0xac: op_xra(m_HL.b.h); break; + case 0xad: op_xra(m_HL.b.l); break; + case 0xae: m_WZ.b.l = read_mem(m_HL.d); op_xra(m_WZ.b.l); break; + case 0xaf: op_xra(m_AF.b.h); break; + + case 0xb0: op_ora(m_BC.b.h); break; + case 0xb1: op_ora(m_BC.b.l); break; + case 0xb2: op_ora(m_DE.b.h); break; + case 0xb3: op_ora(m_DE.b.l); break; + case 0xb4: op_ora(m_HL.b.h); break; + case 0xb5: op_ora(m_HL.b.l); break; + case 0xb6: m_WZ.b.l = read_mem(m_HL.d); op_ora(m_WZ.b.l); break; + case 0xb7: op_ora(m_AF.b.h); break; + + case 0xb8: op_cmp(m_BC.b.h); break; + case 0xb9: op_cmp(m_BC.b.l); break; + case 0xba: op_cmp(m_DE.b.h); break; + case 0xbb: op_cmp(m_DE.b.l); break; + case 0xbc: op_cmp(m_HL.b.h); break; + case 0xbd: op_cmp(m_HL.b.l); break; + case 0xbe: m_WZ.b.l = read_mem(m_HL.d); op_cmp(m_WZ.b.l); break; + case 0xbf: op_cmp(m_AF.b.h); break; + + case 0xc0: // RNZ + op_ret(!(m_AF.b.l & ZF)); + break; + case 0xc1: // POP B + m_BC = op_pop(); + break; + case 0xc2: // JNZ nnnn + op_jmp(!(m_AF.b.l & ZF)); + break; + case 0xc3: // JMP nnnn + op_jmp(1); + break; + case 0xc4: // CNZ nnnn + op_call(!(m_AF.b.l & ZF)); + break; + case 0xc5: // PUSH B + op_push(m_BC); + break; + case 0xc6: // ADI nn + m_WZ.b.l = read_arg(); + op_add(m_WZ.b.l); + break; + case 0xc7: // RST 0 + op_rst(0); + break; + + case 0xc8: // RZ + op_ret(m_AF.b.l & ZF); + break; + case 0xc9: // RET + m_PC = op_pop(); + break; + case 0xca: // JZ nnnn + op_jmp(m_AF.b.l & ZF); + break; + case 0xcb: // 8085: RST V, otherwise undocumented JMP nnnn + if (is_8085()) + { + if (m_AF.b.l & VF) + op_rst(8); + else + m_icount += 6; // RST not taken + } + else + op_jmp(1); + break; + case 0xcc: // CZ nnnn + op_call(m_AF.b.l & ZF); + break; + case 0xcd: // CALL nnnn + op_call(1); + break; + case 0xce: // ACI nn + m_WZ.b.l = read_arg(); + op_adc(m_WZ.b.l); + break; + case 0xcf: // RST 1 + op_rst(1); + break; + + case 0xd0: // RNC + op_ret(!(m_AF.b.l & CF)); + break; + case 0xd1: // POP D + m_DE = op_pop(); + break; + case 0xd2: // JNC nnnn + op_jmp(!(m_AF.b.l & CF)); + break; + case 0xd3: // OUT nn + set_status(0x10); + m_WZ.d = read_arg(); + m_io->write_byte(m_WZ.d, m_AF.b.h); + break; + case 0xd4: // CNC nnnn + op_call(!(m_AF.b.l & CF)); + break; + case 0xd5: // PUSH D + op_push(m_DE); + break; + case 0xd6: // SUI nn + m_WZ.b.l = read_arg(); + op_sub(m_WZ.b.l); + break; + case 0xd7: // RST 2 + op_rst(2); + break; + + case 0xd8: // RC + op_ret(m_AF.b.l & CF); + break; + case 0xd9: // 8085: SHLX, otherwise undocumented RET + if (is_8085()) + { + m_WZ.w.l = m_DE.w.l; + write_mem(m_WZ.d, m_HL.b.l); + m_WZ.w.l++; + write_mem(m_WZ.d, m_HL.b.h); + } + else + m_PC = op_pop(); + break; + case 0xda: // JC nnnn + op_jmp(m_AF.b.l & CF); + break; + case 0xdb: // IN nn + set_status(0x42); + m_WZ.d = read_arg(); + m_AF.b.h = m_io->read_byte(m_WZ.d); + break; + case 0xdc: // CC nnnn + op_call(m_AF.b.l & CF); + break; + case 0xdd: // 8085: JNX nnnn, otherwise undocumented CALL nnnn + if (is_8085()) + op_jmp(!(m_AF.b.l & X5F)); + else + op_call(1); + break; + case 0xde: // SBI nn + m_WZ.b.l = read_arg(); + op_sbb(m_WZ.b.l); + break; + case 0xdf: // RST 3 + op_rst(3); + break; + + case 0xe0: // RPO + op_ret(!(m_AF.b.l & PF)); + break; + case 0xe1: // POP H + m_HL = op_pop(); + break; + case 0xe2: // JPO nnnn + op_jmp(!(m_AF.b.l & PF)); + break; + case 0xe3: // XTHL + m_WZ = op_pop(); + op_push(m_HL); + m_HL.d = m_WZ.d; + break; + case 0xe4: // CPO nnnn + op_call(!(m_AF.b.l & PF)); + break; + case 0xe5: // PUSH H + op_push(m_HL); + break; + case 0xe6: // ANI nn + m_WZ.b.l = read_arg(); + op_ana(m_WZ.b.l); + break; + case 0xe7: // RST 4 + op_rst(4); + break; + + case 0xe8: // RPE + op_ret(m_AF.b.l & PF); + break; + case 0xe9: // PCHL + m_PC.d = m_HL.w.l; + break; + case 0xea: // JPE nnnn + op_jmp(m_AF.b.l & PF); + break; + case 0xeb: // XCHG + m_WZ.d = m_DE.d; + m_DE.d = m_HL.d; + m_HL.d = m_WZ.d; + break; + case 0xec: // CPE nnnn + op_call(m_AF.b.l & PF); + break; + case 0xed: // 8085: LHLX, otherwise undocumented CALL nnnn + if (is_8085()) + { + m_WZ.w.l = m_DE.w.l; + m_HL.b.l = read_mem(m_WZ.d); + m_WZ.w.l++; + m_HL.b.h = read_mem(m_WZ.d); + } + else + op_call(1); + break; + case 0xee: // XRI nn + m_WZ.b.l = read_arg(); + op_xra(m_WZ.b.l); + break; + case 0xef: // RST 5 + op_rst(5); + break; + + case 0xf0: // RP + op_ret(!(m_AF.b.l & SF)); + break; + case 0xf1: // POP A + m_AF = op_pop(); + break; + case 0xf2: // JP nnnn + op_jmp(!(m_AF.b.l & SF)); + break; + case 0xf3: // DI + set_inte(0); + break; + case 0xf4: // CP nnnn + op_call(!(m_AF.b.l & SF)); + break; + case 0xf5: // PUSH A + // on 8080, VF=1 and X3F=0 and X5F=0 always! (we don't have to check for it elsewhere) + if (is_8080()) + m_AF.b.l = (m_AF.b.l & ~(X3F | X5F)) | VF; + op_push(m_AF); + break; + case 0xf6: // ORI nn + m_WZ.b.l = read_arg(); + op_ora(m_WZ.b.l); + break; + case 0xf7: // RST 6 + op_rst(6); + break; + + case 0xf8: // RM + op_ret(m_AF.b.l & SF); + break; + case 0xf9: // SPHL + m_SP.d = m_HL.d; + break; + case 0xfa: // JM nnnn + op_jmp(m_AF.b.l & SF); + break; + case 0xfb: // EI + set_inte(1); + m_after_ei = 2; + break; + case 0xfc: // CM nnnn + op_call(m_AF.b.l & SF); + break; + case 0xfd: // 8085: JX nnnn, otherwise undocumented CALL nnnn + if (is_8085()) + op_jmp(m_AF.b.l & X5F); + else + op_call(1); + break; + case 0xfe: // CPI nn + m_WZ.b.l = read_arg(); + op_cmp(m_WZ.b.l); + break; + case 0xff: // RST 7 + op_rst(7); + break; + } // end big switch } diff --git a/src/devices/cpu/i8085/i8085.h b/src/devices/cpu/i8085/i8085.h index 41f681f8897..b4ab5901c1f 100644 --- a/src/devices/cpu/i8085/i8085.h +++ b/src/devices/cpu/i8085/i8085.h @@ -53,17 +53,17 @@ public: I8085_HALT, I8085_IM }; - static constexpr uint8_t STATUS_INTA = 0x01; - static constexpr uint8_t STATUS_WO = 0x02; - static constexpr uint8_t STATUS_STACK = 0x04; - static constexpr uint8_t STATUS_HLTA = 0x08; - static constexpr uint8_t STATUS_OUT = 0x10; - static constexpr uint8_t STATUS_M1 = 0x20; - static constexpr uint8_t STATUS_INP = 0x40; - static constexpr uint8_t STATUS_MEMR = 0x80; + static constexpr u8 STATUS_INTA = 0x01; + static constexpr u8 STATUS_WO = 0x02; + static constexpr u8 STATUS_STACK = 0x04; + static constexpr u8 STATUS_HLTA = 0x08; + static constexpr u8 STATUS_OUT = 0x10; + static constexpr u8 STATUS_M1 = 0x20; + static constexpr u8 STATUS_INP = 0x40; + static constexpr u8 STATUS_MEMR = 0x80; // construction/destruction - i8085a_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + i8085a_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); // static configuration helpers template <class Object> static devcb_base &set_out_status_func(device_t &device, Object &&cb) { return downcast<i8085a_cpu_device &>(device).m_out_status_func.set_callback(std::forward<Object>(cb)); } @@ -73,7 +73,7 @@ public: static void static_set_clk_out(device_t &device, clock_update_delegate &&clk_out) { downcast<i8085a_cpu_device &>(device).m_clk_out_func = std::move(clk_out); } protected: - i8085a_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int cputype); + i8085a_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int cputype); // device-level overrides virtual void device_config_complete() override; @@ -82,14 +82,14 @@ protected: virtual void device_reset() override; // device_execute_interface overrides - virtual uint32_t execute_min_cycles() const override { return 4; } - virtual uint32_t execute_max_cycles() const override { return 16; } - virtual uint32_t execute_input_lines() const override { return 4; } - virtual uint32_t execute_default_irq_vector() const override { return 0xff; } + virtual u32 execute_min_cycles() const override { return 4; } + virtual u32 execute_max_cycles() const override { return 16; } + virtual u32 execute_input_lines() const override { return 4; } + virtual u32 execute_default_irq_vector() const override { return 0xff; } virtual void execute_run() override; virtual void execute_set_input(int inputnum, int state) override; - virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const override { return (clocks + 2 - 1) / 2; } - virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const override { return (cycles * 2); } + virtual u64 execute_clocks_to_cycles(u64 clocks) const override { return (clocks + 2 - 1) / 2; } + virtual u64 execute_cycles_to_clocks(u64 cycles) const override { return (cycles * 2); } // device_memory_interface overrides virtual space_config_vector memory_space_config() const override; @@ -100,62 +100,89 @@ protected: virtual void state_import(const device_state_entry &entry) override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 3; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; + + enum + { + CPUTYPE_8080 = 0, + CPUTYPE_8080A, + CPUTYPE_8085A + }; private: address_space_config m_program_config; address_space_config m_io_config; + address_space_config m_opcode_config; - devcb_write8 m_out_status_func; - devcb_write_line m_out_inte_func; - devcb_read_line m_in_sid_func; - devcb_write_line m_out_sod_func; + devcb_write8 m_out_status_func; + devcb_write_line m_out_inte_func; + devcb_read_line m_in_sid_func; + devcb_write_line m_out_sod_func; clock_update_delegate m_clk_out_func; - int m_cputype; /* 0 8080, 1 8085A */ - PAIR m_PC,m_SP,m_AF,m_BC,m_DE,m_HL,m_WZ; - uint8_t m_HALT; - uint8_t m_IM; /* interrupt mask (8085A only) */ - uint8_t m_STATUS; /* status word */ + inline bool is_8080() { return m_cputype == CPUTYPE_8080 || m_cputype == CPUTYPE_8080A; } + inline bool is_8085() { return m_cputype == CPUTYPE_8085A; } + int m_cputype; + + PAIR m_PC,m_SP,m_AF,m_BC,m_DE,m_HL,m_WZ; + u8 m_halt; + u8 m_im; /* interrupt mask (8085A only) */ + u8 m_status; /* status word */ - uint8_t m_after_ei; /* post-EI processing; starts at 2, check for ints at 0 */ - uint8_t m_nmi_state; /* raw NMI line state */ - uint8_t m_irq_state[4]; /* raw IRQ line states */ - uint8_t m_trap_pending; /* TRAP interrupt latched? */ - uint8_t m_trap_im_copy; /* copy of IM register when TRAP was taken */ - uint8_t m_sod_state; /* state of the SOD line */ + u8 m_after_ei; /* post-EI processing; starts at 2, check for ints at 0 */ + u8 m_nmi_state; /* raw NMI line state */ + u8 m_irq_state[4]; /* raw IRQ line states */ + u8 m_trap_pending; /* TRAP interrupt latched? */ + u8 m_trap_im_copy; /* copy of IM register when TRAP was taken */ + u8 m_sod_state; /* state of the SOD line */ - bool m_ietemp; /* import/export temp space */ + bool m_ietemp; /* import/export temp space */ address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; + direct_read_data<0> *m_opcode_direct; address_space *m_io; - int m_icount; + int m_icount; /* cycles lookup */ - static const uint8_t lut_cycles_8080[256]; - static const uint8_t lut_cycles_8085[256]; - uint8_t lut_cycles[256]; + static const u8 lut_cycles_8080[256]; + static const u8 lut_cycles_8085[256]; + u8 lut_cycles[256]; /* flags lookup */ - uint8_t ZS[256]; - uint8_t ZSP[256]; + u8 lut_zs[256]; + u8 lut_zsp[256]; void set_sod(int state); void set_inte(int state); - void set_status(uint8_t status); - uint8_t get_rim_value(); + void set_status(u8 status); + u8 get_rim_value(); void break_halt_for_interrupt(); - uint8_t ROP(); - uint8_t ARG(); - uint16_t ARG16(); - uint8_t RM(uint32_t a); - void WM(uint32_t a, uint8_t v); + u8 read_op(); + u8 read_arg(); + PAIR read_arg16(); + u8 read_mem(u32 a); + void write_mem(u32 a, u8 v); + void op_push(PAIR p); + PAIR op_pop(); void check_for_interrupts(); void execute_one(int opcode); void init_tables(); + void op_ora(u8 v); + void op_xra(u8 v); + void op_ana(u8 v); + u8 op_inr(u8 v); + u8 op_dcr(u8 v); + void op_add(u8 v); + void op_adc(u8 v); + void op_sub(u8 v); + void op_sbb(u8 v); + void op_cmp(u8 v); + void op_dad(u16 v); + void op_jmp(int cond); + void op_call(int cond); + void op_ret(int cond); + void op_rst(u8 v); }; @@ -163,12 +190,12 @@ class i8080_cpu_device : public i8085a_cpu_device { public: // construction/destruction - i8080_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + i8080_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); protected: - virtual uint32_t execute_input_lines() const override { return 1; } - virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const override { return clocks; } - virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const override { return cycles; } + virtual u32 execute_input_lines() const override { return 1; } + virtual u64 execute_clocks_to_cycles(u64 clocks) const override { return clocks; } + virtual u64 execute_cycles_to_clocks(u64 cycles) const override { return cycles; } }; @@ -176,12 +203,12 @@ class i8080a_cpu_device : public i8085a_cpu_device { public: // construction/destruction - i8080a_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + i8080a_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); protected: - virtual uint32_t execute_input_lines() const override { return 1; } - virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const override { return clocks; } - virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const override { return cycles; } + virtual u32 execute_input_lines() const override { return 1; } + virtual u64 execute_clocks_to_cycles(u64 clocks) const override { return clocks; } + virtual u64 execute_cycles_to_clocks(u64 cycles) const override { return cycles; } }; diff --git a/src/devices/cpu/i8085/i8085cpu.h b/src/devices/cpu/i8085/i8085cpu.h deleted file mode 100644 index a41e96f06c7..00000000000 --- a/src/devices/cpu/i8085/i8085cpu.h +++ /dev/null @@ -1,188 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Juergen Buchmueller, hap -/******************************************************* - * - * Portable (hopefully ;-) 8085A emulator - * - * Written by J. Buchmueller for use with MAME - * - * Partially based on Z80Em by Marcel De Kogel - * - * CPU related macros - * - *******************************************************/ - - -#define SF 0x80 -#define ZF 0x40 -#define X5F 0x20 -#define HF 0x10 -#define X3F 0x08 -#define PF 0x04 -#define VF 0x02 -#define CF 0x01 - -#define IM_SID 0x80 -#define IM_I75 0x40 -#define IM_I65 0x20 -#define IM_I55 0x10 -#define IM_IE 0x08 -#define IM_M75 0x04 -#define IM_M65 0x02 -#define IM_M55 0x01 - -#define ADDR_TRAP 0x0024 -#define ADDR_RST55 0x002c -#define ADDR_RST65 0x0034 -#define ADDR_RST75 0x003c -#define ADDR_INTR 0x0038 - - -#define M_MVI(R) R=ARG() - -/* rotate */ -#define M_RLC { \ - m_AF.b.h = (m_AF.b.h << 1) | (m_AF.b.h >> 7); \ - m_AF.b.l = (m_AF.b.l & 0xfe) | (m_AF.b.h & CF); \ -} - -#define M_RRC { \ - m_AF.b.l = (m_AF.b.l & 0xfe) | (m_AF.b.h & CF); \ - m_AF.b.h = (m_AF.b.h >> 1) | (m_AF.b.h << 7); \ -} - -#define M_RAL { \ - int c = m_AF.b.l&CF; \ - m_AF.b.l = (m_AF.b.l & 0xfe) | (m_AF.b.h >> 7); \ - m_AF.b.h = (m_AF.b.h << 1) | c; \ -} - -#define M_RAR { \ - int c = (m_AF.b.l&CF) << 7; \ - m_AF.b.l = (m_AF.b.l & 0xfe) | (m_AF.b.h & CF); \ - m_AF.b.h = (m_AF.b.h >> 1) | c; \ -} - -/* logical */ -#define M_ORA(R) m_AF.b.h|=R; m_AF.b.l=ZSP[m_AF.b.h] -#define M_XRA(R) m_AF.b.h^=R; m_AF.b.l=ZSP[m_AF.b.h] -#define M_ANA(R) {uint8_t hc = ((m_AF.b.h | R)<<1) & HF; m_AF.b.h&=R; m_AF.b.l=ZSP[m_AF.b.h]; if(IS_8085()) { m_AF.b.l |= HF; } else {m_AF.b.l |= hc; } } - -/* increase / decrease */ -#define M_INR(R) {uint8_t hc = ((R & 0x0f) == 0x0f) ? HF : 0; ++R; m_AF.b.l= (m_AF.b.l & CF ) | ZSP[R] | hc; } -#define M_DCR(R) {uint8_t hc = ((R & 0x0f) != 0x00) ? HF : 0; --R; m_AF.b.l= (m_AF.b.l & CF ) | ZSP[R] | hc | VF; } - -/* arithmetic */ -#define M_ADD(R) { \ - int q = m_AF.b.h+R; \ - m_AF.b.l=ZSP[q&255]|((q>>8)&CF)|((m_AF.b.h^q^R)&HF); \ - m_AF.b.h=q; \ -} - -#define M_ADC(R) { \ - int q = m_AF.b.h+R+(m_AF.b.l&CF); \ - m_AF.b.l=ZSP[q&255]|((q>>8)&CF)|((m_AF.b.h^q^R)&HF); \ - m_AF.b.h=q; \ -} - -#define M_SUB(R) { \ - int q = m_AF.b.h-R; \ - m_AF.b.l=ZSP[q&255]|((q>>8)&CF)|(~(m_AF.b.h^q^R)&HF)|VF; \ - m_AF.b.h=q; \ -} - -#define M_SBB(R) { \ - int q = m_AF.b.h-R-(m_AF.b.l&CF); \ - m_AF.b.l=ZSP[q&255]|((q>>8)&CF)|(~(m_AF.b.h^q^R)&HF)|VF; \ - m_AF.b.h=q; \ -} - -#define M_CMP(R) { \ - int q = m_AF.b.h-R; \ - m_AF.b.l=ZSP[q&255]|((q>>8)&CF)|(~(m_AF.b.h^q^R)&HF)|VF; \ -} - -#define M_DAD(R) { \ - int q = m_HL.d + m_##R.d; \ - m_AF.b.l = (m_AF.b.l & ~CF) | (q>>16 & CF ); \ - m_HL.w.l = q; \ -} - -// DSUB is 8085-only, not sure if H flag handling is correct -#define M_DSUB() { \ - int q = m_HL.b.l-m_BC.b.l; \ - m_AF.b.l=ZS[q&255]|((q>>8)&CF)|VF| \ - ((m_HL.b.l^q^m_BC.b.l)&HF)| \ - (((m_BC.b.l^m_HL.b.l)&(m_HL.b.l^q)&SF)>>5); \ - m_HL.b.l=q; \ - q = m_HL.b.h-m_BC.b.h-(m_AF.b.l&CF); \ - m_AF.b.l=ZS[q&255]|((q>>8)&CF)|VF| \ - ((m_HL.b.h^q^m_BC.b.h)&HF)| \ - (((m_BC.b.h^m_HL.b.h)&(m_HL.b.h^q)&SF)>>5); \ - if (m_HL.b.l!=0) m_AF.b.l&=~ZF; \ -} - -/* i/o */ -#define M_IN \ - set_status(0x42); \ - m_WZ.d=ARG(); \ - m_AF.b.h=m_io->read_byte(m_WZ.d); - -#define M_OUT \ - set_status(0x10); \ - m_WZ.d=ARG(); \ - m_io->write_byte(m_WZ.d,m_AF.b.h) - -/* stack */ -#define M_PUSH(R) { \ - set_status(0x04); \ - m_program->write_byte(--m_SP.w.l, m_##R.b.h); \ - m_program->write_byte(--m_SP.w.l, m_##R.b.l); \ -} - -#define M_POP(R) { \ - set_status(0x86); \ - m_##R.b.l = m_program->read_byte(m_SP.w.l++); \ - m_##R.b.h = m_program->read_byte(m_SP.w.l++); \ -} - -/* jumps */ -// On 8085 jump if condition is not satisfied is shorter -#define M_JMP(cc) { \ - if (cc) { \ - m_PC.w.l = ARG16(); \ - } else { \ - m_PC.w.l += 2; \ - m_icount += (IS_8085()) ? 3 : 0; \ - } \ -} - -// On 8085 call if condition is not satisfied is 9 ticks -#define M_CALL(cc) \ -{ \ - if (cc) \ - { \ - uint16_t a = ARG16(); \ - m_icount -= (IS_8085()) ? 7 : 6 ; \ - M_PUSH(PC); \ - m_PC.d = a; \ - } else { \ - m_PC.w.l += 2; \ - m_icount += (IS_8085()) ? 2 : 0; \ - } \ -} - -// conditional RET only -#define M_RET(cc) \ -{ \ - if (cc) \ - { \ - m_icount -= 6; \ - M_POP(PC); \ - } \ -} - -#define M_RST(nn) { \ - M_PUSH(PC); \ - m_PC.d = 8 * nn; \ -} diff --git a/src/devices/cpu/i8089/i8089.cpp b/src/devices/cpu/i8089/i8089.cpp index 93a38ceea04..075cc92fb18 100644 --- a/src/devices/cpu/i8089/i8089.cpp +++ b/src/devices/cpu/i8089/i8089.cpp @@ -8,6 +8,7 @@ #include "emu.h" #include "i8089.h" +#include "i8089_dasm.h" #include "i8089_channel.h" @@ -144,13 +145,12 @@ device_memory_interface::space_config_vector i8089_device::memory_space_config() } //------------------------------------------------- -// disasm_disassemble - disassembler +// disassemble - disassembler //------------------------------------------------- -offs_t i8089_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *i8089_device::create_disassembler() { - extern CPU_DISASSEMBLE(i8089); - return CPU_DISASSEMBLE_NAME(i8089)(this, stream, pc, oprom, opram, options); + return new i8089_disassembler(); } //------------------------------------------------- diff --git a/src/devices/cpu/i8089/i8089.h b/src/devices/cpu/i8089/i8089.h index 3465c444e2a..812ae99a733 100644 --- a/src/devices/cpu/i8089/i8089.h +++ b/src/devices/cpu/i8089/i8089.h @@ -82,9 +82,7 @@ protected: address_space_config m_io_config; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 7; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // device_state_interface overrides virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; diff --git a/src/devices/cpu/i8089/i8089_dasm.cpp b/src/devices/cpu/i8089/i8089_dasm.cpp index 1159602289b..8e45053b1ba 100644 --- a/src/devices/cpu/i8089/i8089_dasm.cpp +++ b/src/devices/cpu/i8089/i8089_dasm.cpp @@ -9,439 +9,385 @@ ***************************************************************************/ #include "emu.h" +#include "i8089_dasm.h" -class i8089_instruction +const char *const i8089_disassembler::m_reg[] = { -public: - i8089_instruction(offs_t pc, const uint8_t *oprom) : - m_oprom(oprom), m_ppc(pc), m_pc(0), m_flags(DASMFLAG_SUPPORTED) - { - // instruction - m_brp = (oprom[0] >> 5) & 0x07; - m_wb = (oprom[0] >> 3) & 0x03; - m_aa = (oprom[0] >> 1) & 0x03; - m_w = (oprom[0] >> 0) & 0x01; - m_opc = (oprom[1] >> 2) & 0x3f; - m_mm = (oprom[1] >> 0) & 0x03; - - // clear buffers - memset(m_buffer, 0, sizeof(m_buffer)); - memset(m_offset, 0, sizeof(m_offset)); - - // start working - disassemble(); - } - - char *buffer() { return m_buffer; } - int length() const { return m_pc; } - int flags() const { return m_flags; } - -private: - const uint8_t *m_oprom; + "ga", "gb", "gc", "bc", "tp", "ix", "cc", "mc" +}; - char m_buffer[256]; - char m_offset[100]; - offs_t m_ppc; - int m_pc; +// fetch 1-byte value +uint8_t i8089_disassembler::fetch_value8() +{ + uint8_t i = m_opcodes->r8(m_pc); + m_pc += 1; + return i; +} - // decoded instruction - int m_brp; - int m_wb; - int m_aa; - int m_w; - int m_opc; - int m_mm; +// fetch 2-byte value +uint16_t i8089_disassembler::fetch_value16() +{ + uint16_t i = m_opcodes->r16(m_pc); + m_pc += 2; + return i; +} - // dasm flags - int m_flags; +// fetch a 1 or 2 byte immediate value +uint16_t i8089_disassembler::fetch_immediate() +{ + return (m_wb & 1) ? fetch_value8() : fetch_value16(); +} - // register names - static const char *m_reg[]; +// print memory offset +std::string i8089_disassembler::offset() +{ + const char *mm_name[] = { "ga", "gb", "gc", "pp" }; - // register index - enum + switch (m_aa) { - GA, // 20-bit general purpose address a - GB, // 20-bit general purpose address b - GC, // 20-bit general purpose address c - BC, // byte count - TP, // 20-bit task pointer - IX, // index - CC, // mask compare - MC // channel control - }; - - // fetch 1-byte value - uint8_t fetch_value8() - { - uint8_t i = m_oprom[m_pc]; - m_pc += 1; - return i; + case 0: return util::string_format("[%s]", mm_name[m_mm]); + case 1: return util::string_format("[%s].%02x", mm_name[m_mm], m_opcodes->r8(m_pc++)); + case 2: return util::string_format("[%s+ix]", mm_name[m_mm]); + case 3: return util::string_format("[%s+ix+]", mm_name[m_mm]); } + return ""; +} - // fetch 2-byte value - uint16_t fetch_value16() - { - uint16_t i = m_oprom[m_pc] | m_oprom[m_pc + 1] << 8; - m_pc += 2; - return i; - } +// invalid instruction +std::string i8089_disassembler::invalid() +{ + return "???"; +} - // fetch a 1 or 2 byte immediate value - uint16_t fetch_immediate() - { - return (m_wb & 1) ? fetch_value8() : fetch_value16(); - } +// to register or memory from immediate +std::string i8089_disassembler::from_i(std::string instr8, std::string instr16, std::string target) +{ + if (m_w == 0 && m_wb == 1) + return util::string_format("%s %s, %02x", instr8, target, fetch_immediate()); + else if (m_w == 1 && m_wb == 2) + return util::string_format("%s %s, %04x", instr16, target, fetch_immediate()); + else + return invalid(); +} - // print memory offset - void offset() - { - const char *mm_name[] = { "ga", "gb", "gc", "pp" }; +// register, immediate +std::string i8089_disassembler::inst_ri(std::string instr8, std::string instr16) +{ + if (m_mm == 0) + return from_i(instr8, instr16, m_reg[m_brp]); + else + return invalid(); +} - switch (m_aa) - { - case 0: sprintf(m_offset, "[%s]", mm_name[m_mm]); break; - case 1: sprintf(m_offset, "[%s].%02x", mm_name[m_mm], m_oprom[m_pc]); m_pc++; break; - case 2: sprintf(m_offset, "[%s+ix]", mm_name[m_mm]); break; - case 3: sprintf(m_offset, "[%s+ix+]", mm_name[m_mm]); break; - } - } +// register +std::string i8089_disassembler::inst_r(std::string instr) +{ + if (m_mm == 0 && m_w == 0 && m_aa == 0 && m_wb == 0) + return util::string_format("%s %s", instr, m_reg[m_brp]); + else + return invalid(); +} - // to register or memory from immediate - void from_i(const char *instr8, const char *instr16, const char *target) - { - if (m_w == 0 && m_wb == 1) - sprintf(m_buffer, "%s %s, %02x", instr8, target, fetch_immediate()); - else if (m_w == 1 && m_wb == 2) - sprintf(m_buffer, "%s %s, %04x", instr16, target, fetch_immediate()); - else - invalid(); - } +// jump register +std::string i8089_disassembler::inst_jr(std::string instr8, std::string instr16) +{ + uint16_t i = fetch_immediate(); + if (m_mm == 0 && m_w == 0 && m_wb == 1) + return util::string_format("%s %s, %05x", instr8, m_reg[m_brp], m_pc + (int8_t) i); + else if (m_mm == 0 && m_w == 0 && m_wb == 2) + return util::string_format("%s %s, %05x", instr16, m_reg[m_brp], m_pc + (int16_t) i); + else + return invalid(); +} - // register, immediate - void inst_ri(const char *instr8, const char *instr16) - { - if (m_mm == 0) - from_i(instr8, instr16, m_reg[m_brp]); - else - invalid(); - } +// memory immediate +std::string i8089_disassembler::inst_mi(std::string instr8, std::string instr16) +{ + std::string off = offset(); + return from_i(instr8, instr16, off); +} - // register - void inst_r(const char *instr) - { - if (m_mm == 0 && m_w == 0 && m_aa == 0 && m_wb == 0) - sprintf(m_buffer, "%s %s", instr, m_reg[m_brp]); - else - invalid(); - } +// register memory +std::string i8089_disassembler::inst_rm(std::string instr8, std::string instr16) +{ + std::string off = offset(); + if (m_w == 0 && m_wb == 0) + return util::string_format("%s %s, %s", instr8, m_reg[m_brp], off); + else if (m_w == 1 && m_wb == 0) + return util::string_format("%s %s, %s", instr16, m_reg[m_brp], off); + else + return invalid(); +} - // jump register - void inst_jr(const char *instr8, const char *instr16) - { - uint16_t i = fetch_immediate(); - if (m_mm == 0 && m_w == 0 && m_wb == 1) - sprintf(m_buffer, "%s %s, %05x", instr8, m_reg[m_brp], m_ppc + m_pc + (int8_t) i); - else if (m_mm == 0 && m_w == 0 && m_wb == 2) - sprintf(m_buffer, "%s %s, %05x", instr16, m_reg[m_brp], m_ppc + m_pc + (int16_t) i); - else - invalid(); - } +// jump memory +std::string i8089_disassembler::inst_jm(std::string jump8short, std::string jump8long) +{ + std::string off = offset(); + uint16_t i = fetch_immediate(); + if (m_w == 0 && m_wb == 1 && m_brp == 0) + return util::string_format("%s %s, %05x", jump8short, off, m_pc + (int8_t) i); + else if (m_w == 0 && m_wb == 2 && m_brp == 0) + return util::string_format("%s %s, %05x", jump8long, off, m_pc + (int16_t) i); + else + return invalid(); +} - // memory immediate - void inst_mi(const char *instr8, const char *instr16) - { - offset(); - from_i(instr8, instr16, m_offset); - } +// jump memory bit +std::string i8089_disassembler::inst_jmb(std::string jump8short, std::string jump8long) +{ + std::string off = offset(); + uint16_t i = fetch_immediate(); + if (m_w == 0 && m_wb == 1) + return util::string_format("%s %s, %d, %05x", jump8short, off, m_brp, m_pc + (int8_t) i); + else if (m_w == 0 && m_wb == 2) + return util::string_format("%s %s, %d, %05x", jump8long, off, m_brp, m_pc + (int16_t) i); + else + return invalid(); +} - // register memory - void inst_rm(const char *instr8, const char *instr16) - { - offset(); - if (m_w == 0 && m_wb == 0) - sprintf(m_buffer, "%s %s, %s", instr8, m_reg[m_brp], m_offset); - else if (m_w == 1 && m_wb == 0) - sprintf(m_buffer, "%s %s, %s", instr16, m_reg[m_brp], m_offset); - else - invalid(); - } +// memory register +std::string i8089_disassembler::inst_mr(std::string instr8, std::string instr16) +{ + std::string off = offset(); + if (m_w == 0 && m_wb == 0) + return util::string_format("%s %s, %s", instr8, off, m_reg[m_brp]); + else if (m_w == 1 && m_wb == 0) + return util::string_format("%s %s, %s", instr16, off, m_reg[m_brp]); + else + return invalid(); +} - // jump memory - void inst_jm(const char *jump8short, const char *jump8long) - { - offset(); - uint16_t i = fetch_immediate(); - if (m_w == 0 && m_wb == 1 && m_brp == 0) - sprintf(m_buffer, "%s %s, %05x", jump8short, m_offset, m_ppc + m_pc + (int8_t) i); - else if (m_w == 0 && m_wb == 2 && m_brp == 0) - sprintf(m_buffer, "%s %s, %05x", jump8long, m_offset, m_ppc + m_pc + (int16_t) i); - else - invalid(); - } +// pointer memory +std::string i8089_disassembler::inst_pm(std::string instr16) +{ + std::string off = offset(); + if (m_w == 1 && m_wb == 0) + return util::string_format("%s %s, %s", instr16, m_reg[m_brp], off); + else + return invalid(); +} - // jump memory bit - void inst_jmb(const char *jump8short, const char *jump8long) - { - offset(); - uint16_t i = fetch_immediate(); - if (m_w == 0 && m_wb == 1) - sprintf(m_buffer, "%s %s, %d, %05x", jump8short, m_offset, m_brp, m_ppc + m_pc + (int8_t) i); - else if (m_w == 0 && m_wb == 2) - sprintf(m_buffer, "%s %s, %d, %05x", jump8long, m_offset, m_brp, m_ppc + m_pc + (int16_t) i); - else - invalid(); - } +// memory pointer +std::string i8089_disassembler::inst_mp(std::string instr16) +{ + std::string off = offset(); + if (m_w == 1 && m_wb == 0) + return util::string_format("%s %s, %s", instr16, off, m_reg[m_brp]); + else + return invalid(); +} - // memory register - void inst_mr(const char *instr8, const char *instr16) - { - offset(); - if (m_w == 0 && m_wb == 0) - sprintf(m_buffer, "%s %s, %s", instr8, m_offset, m_reg[m_brp]); - else if (m_w == 1 && m_wb == 0) - sprintf(m_buffer, "%s %s, %s", instr16, m_offset, m_reg[m_brp]); - else - invalid(); - } +// jump memory +std::string i8089_disassembler::inst_j16(std::string jump8short, std::string jump16short, std::string jump8long, std::string jump16long) +{ + std::string off = offset(); + uint16_t i = fetch_immediate(); + if (m_w == 0 && m_wb == 1) + return util::string_format("%s %s, %05x", jump8short, off, m_pc + (int8_t) i); + else if (m_w == 1 && m_wb == 1) + return util::string_format("%s %s, %05x", jump16short, off, m_pc + (int8_t) i); + else if (m_w == 0 && m_wb == 2) + return util::string_format("%s %s, %05x", jump8long, off, m_pc + (int16_t) i); + else if (m_w == 1 && m_wb == 2) + return util::string_format("%s %s, %05x", jump16long, off, m_pc + (int16_t) i); + else + return invalid(); +} - // pointer memory - void inst_pm(const char *instr16) - { - offset(); - if (m_w == 1 && m_wb == 0) - sprintf(m_buffer, "%s %s, %s", instr16, m_reg[m_brp], m_offset); - else - invalid(); - } +// memory +std::string i8089_disassembler::inst_m(std::string instr8, std::string instr16) +{ + std::string off = offset(); + if (m_w == 0 && m_wb == 0) + return util::string_format("%s %s", instr8, off); + else if (m_w == 1 && m_wb == 0) + return util::string_format("%s %s", instr16, off); + else + return invalid(); +} - // memory pointer - void inst_mp(const char *instr16) - { - offset(); - if (m_w == 1 && m_wb == 0) - sprintf(m_buffer, "%s %s, %s", instr16, m_offset, m_reg[m_brp]); - else - invalid(); - } +// memory bit +std::string i8089_disassembler::inst_b(std::string instr) +{ + std::string off = offset(); + if (m_w == 0 && m_wb == 0) + return util::string_format("%s %s, %d", instr, off, m_brp); + else + return invalid(); +} - // jump memory - void inst_j16(const char *jump8short, const char *jump16short, const char *jump8long, const char *jump16long) - { - offset(); - uint16_t i = fetch_immediate(); - if (m_w == 0 && m_wb == 1) - sprintf(m_buffer, "%s %s, %05x", jump8short, m_offset, m_ppc + m_pc + (int8_t) i); - else if (m_w == 1 && m_wb == 1) - sprintf(m_buffer, "%s %s, %05x", jump16short, m_offset, m_ppc + m_pc + (int8_t) i); - else if (m_w == 0 && m_wb == 2) - sprintf(m_buffer, "%s %s, %05x", jump8long, m_offset, m_ppc + m_pc + (int16_t) i); - else if (m_w == 1 && m_wb == 2) - sprintf(m_buffer, "%s %s, %05x", jump16long, m_offset, m_ppc + m_pc + (int16_t) i); - else - invalid(); - } +u32 i8089_disassembler::opcode_alignment() const +{ + return 1; +} - // memory - void inst_m(const char *instr8, const char *instr16) - { - offset(); - if (m_w == 0 && m_wb == 0) - sprintf(m_buffer, "%s %s", instr8, m_offset); - else if (m_w == 1 && m_wb == 0) - sprintf(m_buffer, "%s %s", instr16, m_offset); - else - invalid(); - } +void i8089_disassembler::load_instruction() +{ + // instruction + m_brp = (m_opcodes->r8(m_pc) >> 5) & 0x07; + m_wb = (m_opcodes->r8(m_pc) >> 3) & 0x03; + m_aa = (m_opcodes->r8(m_pc) >> 1) & 0x03; + m_w = (m_opcodes->r8(m_pc) >> 0) & 0x01; + m_opc = (m_opcodes->r8(m_pc+1) >> 2) & 0x3f; + m_mm = (m_opcodes->r8(m_pc+1) >> 0) & 0x03; + m_pc += 2; +} - // memory bit - void inst_b(const char *instr) - { - offset(); - if (m_w == 0 && m_wb == 0) - sprintf(m_buffer, "%s %s, %d", instr, m_offset, m_brp); - else - invalid(); - } +offs_t i8089_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + m_opcodes = &opcodes; + m_pc = pc; + m_flags = SUPPORTED; - // invalid instruction - void invalid() - { - sprintf(m_buffer, "???"); - } + load_instruction(); + stream << do_disassemble(); + return (m_pc - pc) | m_flags; +} - void disassemble() +std::string i8089_disassembler::do_disassemble() +{ + switch (m_opc) { - m_pc += 2; - - switch (m_opc) + case 0x00: + if (m_mm == 0 && m_w == 0 && m_aa == 0 && m_wb == 0) { - case 0x00: - if (m_mm == 0 && m_w == 0 && m_aa == 0 && m_wb == 0) + switch (m_brp) { - switch (m_brp) - { - case 0: sprintf(m_buffer, "nop"); break; - case 1: invalid(); break; - case 2: sprintf(m_buffer, "sintr"); break; - case 3: sprintf(m_buffer, "xfer"); break; - case 4: sprintf(m_buffer, "wid 8, 8"); break; - case 5: sprintf(m_buffer, "wid 8, 16"); break; - case 6: sprintf(m_buffer, "wid 16, 8"); break; - case 7: sprintf(m_buffer, "wid 16, 16"); break; - } + case 0: return util::string_format("nop"); + case 1: return invalid(); break; + case 2: return util::string_format("sintr"); + case 3: return util::string_format("xfer"); + case 4: return util::string_format("wid 8, 8"); + case 5: return util::string_format("wid 8, 16"); + case 6: return util::string_format("wid 16, 8"); + case 7: return util::string_format("wid 16, 16"); } - else - invalid(); - break; + } + else + return invalid(); + break; - case 0x02: - if (m_w == 1 && m_aa == 0 && m_wb == 2) - { - uint16_t offs = fetch_immediate(); - uint16_t segm = fetch_immediate(); - sprintf(m_buffer, "lpdi %s, %05x", m_reg[m_brp], ((segm << 4) + offs) & 0xfffff); - } - else - invalid(); - break; + case 0x02: + if (m_w == 1 && m_aa == 0 && m_wb == 2) + { + uint16_t offs = fetch_immediate(); + uint16_t segm = fetch_immediate(); + return util::string_format("lpdi %s, %05x", m_reg[m_brp], ((segm << 4) + offs) & 0xfffff); + } + else + return invalid(); - case 0x08: - if (m_mm == 0) - { - uint16_t i = fetch_immediate(); - - if (m_w == 0 && m_aa == 0 && m_wb == 1 && m_brp == TP) - sprintf(m_buffer, "jmp %05x", m_ppc + m_pc + (int8_t) i); - else if (m_w == 1 && m_aa == 0 && m_wb == 2 && m_brp == TP) - sprintf(m_buffer, "ljmp %05x", m_ppc + m_pc + (int16_t) i); - else if (m_w == 0 && m_wb == 1) - sprintf(m_buffer, "addbi %s, %02x", m_reg[m_brp], i); - else if (m_w == 1 && m_wb == 2) - sprintf(m_buffer, "addi %s, %04x", m_reg[m_brp], i); - else - invalid(); - } - else - invalid(); - break; - - case 0x09: inst_ri("orbi", "ori"); break; - case 0x0a: inst_ri("andbi", "andi"); break; - case 0x0b: inst_r("not"); break; - case 0x0c: inst_ri("movbi", "movi"); break; - case 0x0e: inst_r("inc"); break; - case 0x0f: inst_r("dec"); break; - case 0x10: inst_jr("jnz", "ljnz"); break; - case 0x11: inst_jr("jz", "ljz"); break; - - case 0x12: - if (m_mm == 0 && m_w == 0 && m_aa == 0 && m_wb == 0 && m_brp == 1) - sprintf(m_buffer, "hlt"); + case 0x08: + if (m_mm == 0) + { + uint16_t i = fetch_immediate(); + + if (m_w == 0 && m_aa == 0 && m_wb == 1 && m_brp == TP) + return util::string_format("jmp %05x", m_pc + (int8_t) i); + else if (m_w == 1 && m_aa == 0 && m_wb == 2 && m_brp == TP) + return util::string_format("ljmp %05x", m_pc + (int16_t) i); + else if (m_w == 0 && m_wb == 1) + return util::string_format("addbi %s, %02x", m_reg[m_brp], i); + else if (m_w == 1 && m_wb == 2) + return util::string_format("addi %s, %04x", m_reg[m_brp], i); else - invalid(); - break; + return invalid(); + } + else + return invalid(); + + case 0x09: return inst_ri("orbi", "ori"); + case 0x0a: return inst_ri("andbi", "andi"); + case 0x0b: return inst_r("not"); + case 0x0c: return inst_ri("movbi", "movi"); + case 0x0e: return inst_r("inc"); + case 0x0f: return inst_r("dec"); + case 0x10: return inst_jr("jnz", "ljnz"); + case 0x11: return inst_jr("jz", "ljz"); + + case 0x12: + if (m_mm == 0 && m_w == 0 && m_aa == 0 && m_wb == 0 && m_brp == 1) + return util::string_format("hlt"); + else + return invalid(); - case 0x13: inst_mi("movbi", "movi"); break; - case 0x20: inst_rm("movb", "mov"); break; - case 0x21: inst_mr("movb", "mov"); break; - case 0x22: inst_pm("lpd"); break; - case 0x23: inst_pm("movp"); break; + case 0x13: return inst_mi("movbi", "movi"); + case 0x20: return inst_rm("movb", "mov"); + case 0x21: return inst_mr("movb", "mov"); + case 0x22: return inst_pm("lpd"); + case 0x23: return inst_pm("movp"); - case 0x24: - if (m_wb == 0) - { - offset(); + case 0x24: + if (m_wb == 0) + { + std::string off = offset(); - auto tmp = new i8089_instruction(m_pc, m_oprom + m_pc); - m_pc += tmp->length(); - std::string sub = tmp->buffer(); + load_instruction(); - if (m_w == 0) - sprintf(m_buffer, "movb %s, %s", sub.c_str(), m_offset); - else - sprintf(m_buffer, "mov %s, %s", sub.c_str(), m_offset); + if (m_opc != 0x33) + return invalid(); + std::string off2 = offset(); - delete(tmp); - } + if (m_w == 0) + return util::string_format("movb %s, %s", off2, off); else - invalid(); - break; + return util::string_format("mov %s, %s", off2, off); + } + else + return invalid(); - case 0x25: - if (m_w == 0 && m_wb == 3 && m_brp == 0) - { - offset(); - uint16_t i = fetch_immediate(); - int displacement = (int8_t) fetch_immediate(); - sprintf(m_buffer, "tsl %s, %02x, %05x", m_offset, i, m_ppc + m_pc + displacement); - } - else - invalid(); - break; + case 0x25: + if (m_w == 0 && m_wb == 3 && m_brp == 0) + { + std::string off = offset(); + uint16_t i = fetch_immediate(); + int displacement = (int8_t) fetch_immediate(); + return util::string_format("tsl %s, %02x, %05x", off, i, m_pc + displacement); + } + else + return invalid(); - case 0x26: inst_mp("movp"); break; + case 0x26: return inst_mp("movp"); - case 0x27: - if (m_w == 1 && m_brp == TP && (m_wb == 1 || m_wb == 2)) - { - offset(); - uint16_t i = fetch_immediate(); + case 0x27: + if (m_w == 1 && m_brp == TP && (m_wb == 1 || m_wb == 2)) + { + std::string off = offset(); + uint16_t i = fetch_immediate(); - if (m_wb == 1) - sprintf(m_buffer, "call %s, %05x", m_offset, m_ppc + m_pc + (int8_t) i); - else if (m_wb == 2) - sprintf(m_buffer, "lcall %s, %05x", m_offset, m_ppc + m_pc + (int16_t) i); + m_flags |= STEP_OVER; - m_flags |= DASMFLAG_STEP_OVER; - } - else - invalid(); - break; - - case 0x28: inst_rm("addb", "add"); break; - case 0x29: inst_rm("orb", "or"); break; - case 0x2a: inst_rm("andb", "and"); break; - case 0x2b: inst_rm("notb", "not"); break; - case 0x2c: inst_jm("jmce", "ljmce"); break; - case 0x2d: inst_jm("jmcne", "ljmcne"); break; - case 0x2e: inst_jmb("jnbt", "ljnbt"); break; - case 0x2f: inst_jmb("jbt", "ljbt"); break; - case 0x30: inst_mi("addbi", "addi"); break; - case 0x31: inst_mi("orbi", "ori"); break; - case 0x32: inst_mi("andbi", "andi"); break; - - case 0x33: - offset(); - sprintf(m_buffer, "%s", m_offset); - break; - - case 0x34: inst_mr("addb", "add"); break; - case 0x35: inst_mr("orb", "or"); break; - case 0x36: inst_mr("andb", "and"); break; - case 0x37: inst_mr("notb", "not"); break; - case 0x38: inst_j16("jnzb", "jnz", "ljnzb", "ljnz"); break; - case 0x39: inst_j16("jzb", "jz", "ljzb", "ljz"); break; - case 0x3a: inst_m("incb", "inc"); break; - case 0x3b: inst_m("decb", "dec"); break; - case 0x3d: inst_b("setb"); break; - case 0x3e: inst_b("clr"); break; - - default: - invalid(); + if (m_wb == 1) + return util::string_format("call %s, %05x", off, m_pc + (int8_t) i); + else if (m_wb == 2) + return util::string_format("lcall %s, %05x", off, m_pc + (int16_t) i); } + else + return invalid(); + + case 0x28: return inst_rm("addb", "add"); + case 0x29: return inst_rm("orb", "or"); + case 0x2a: return inst_rm("andb", "and"); + case 0x2b: return inst_rm("notb", "not"); + case 0x2c: return inst_jm("jmce", "ljmce"); + case 0x2d: return inst_jm("jmcne", "ljmcne"); + case 0x2e: return inst_jmb("jnbt", "ljnbt"); + case 0x2f: return inst_jmb("jbt", "ljbt"); + case 0x30: return inst_mi("addbi", "addi"); + case 0x31: return inst_mi("orbi", "ori"); + case 0x32: return inst_mi("andbi", "andi"); + + case 0x34: return inst_mr("addb", "add"); + case 0x35: return inst_mr("orb", "or"); + case 0x36: return inst_mr("andb", "and"); + case 0x37: return inst_mr("notb", "not"); + case 0x38: return inst_j16("jnzb", "jnz", "ljnzb", "ljnz"); + case 0x39: return inst_j16("jzb", "jz", "ljzb", "ljz"); + case 0x3a: return inst_m("incb", "inc"); + case 0x3b: return inst_m("decb", "dec"); + case 0x3d: return inst_b("setb"); + case 0x3e: return inst_b("clr"); } -}; -const char *i8089_instruction::m_reg[] = -{ - "ga", "gb", "gc", "bc", "tp", "ix", "cc", "mc" -}; - -CPU_DISASSEMBLE(i8089) -{ - std::unique_ptr<i8089_instruction> i = std::make_unique<i8089_instruction>(pc, oprom); - stream << i->buffer(); - offs_t result = i->length() | i->flags(); - return result; + return invalid(); } diff --git a/src/devices/cpu/i8089/i8089_dasm.h b/src/devices/cpu/i8089/i8089_dasm.h new file mode 100644 index 00000000000..cf59d4b483c --- /dev/null +++ b/src/devices/cpu/i8089/i8089_dasm.h @@ -0,0 +1,71 @@ +// license:GPL-2.0+ +// copyright-holders:Dirk Best +/*************************************************************************** + + Intel 8089 I/O Processor + + Disassembler + +***************************************************************************/ + +#ifndef MAME_CPU_I8089_I8089DASM_H +#define MAME_CPU_I8089_I8089DASM_H + +#pragma once + +class i8089_disassembler : public util::disasm_interface +{ +public: + i8089_disassembler() = default; + virtual ~i8089_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + // register index + enum + { + GA, // 20-bit general purpose address a + GB, // 20-bit general purpose address b + GC, // 20-bit general purpose address c + BC, // byte count + TP, // 20-bit task pointer + IX, // index + CC, // mask compare + MC // channel control + }; + + static const char *const m_reg[]; + + uint8_t m_brp, m_wb, m_aa, m_w, m_opc, m_mm; + offs_t m_pc, m_flags; + + const data_buffer *m_opcodes; + + uint8_t fetch_value8(); + uint16_t fetch_value16(); + uint16_t fetch_immediate(); + std::string offset(); + std::string invalid(); + + std::string from_i(std::string instr8, std::string instr16, std::string target); + std::string inst_ri(std::string instr8, std::string instr16); + std::string inst_r(std::string instr); + std::string inst_jr(std::string instr8, std::string instr16); + std::string inst_mi(std::string instr8, std::string instr16); + std::string inst_rm(std::string instr8, std::string instr16); + std::string inst_jm(std::string jump8short, std::string jump8long); + std::string inst_jmb(std::string jump8short, std::string jump8long); + std::string inst_mr(std::string instr8, std::string instr16); + std::string inst_pm(std::string instr16); + std::string inst_mp(std::string instr16); + std::string inst_j16(std::string jump8short, std::string jump16short, std::string jump8long, std::string jump16long); + std::string inst_m(std::string instr8, std::string instr16); + std::string inst_b(std::string instr); + + std::string do_disassemble(); + void load_instruction(); +}; + +#endif diff --git a/src/devices/cpu/i86/i86.cpp b/src/devices/cpu/i86/i86.cpp index 4c4cd49d6ae..9ecd0ddc99f 100644 --- a/src/devices/cpu/i86/i86.cpp +++ b/src/devices/cpu/i86/i86.cpp @@ -417,8 +417,8 @@ void i8086_common_cpu_device::device_start() m_stack = m_program; m_code = m_program; m_extra = m_program; - m_direct = &m_program->direct(); - m_direct_opcodes = &m_opcodes->direct(); + m_direct = m_program->direct<0>(); + m_direct_opcodes = m_opcodes->direct<0>(); m_io = &space(AS_IO); save_item(NAME(m_regs.w)); @@ -570,9 +570,14 @@ void i8086_common_cpu_device::execute_set_input( int inptnum, int state ) } } -offs_t i8086_common_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *i8086_common_cpu_device::create_disassembler() { - return i386_dasm_one(stream, pc, oprom, 1); + return new i386_disassembler(this); +} + +int i8086_common_cpu_device::get_mode() const +{ + return 1; } uint8_t i8086_common_cpu_device::read_port_byte(uint16_t port) diff --git a/src/devices/cpu/i86/i86.h b/src/devices/cpu/i86/i86.h index f6e177c25d9..f1dc8bc329d 100644 --- a/src/devices/cpu/i86/i86.h +++ b/src/devices/cpu/i86/i86.h @@ -5,6 +5,7 @@ #pragma once +#include <cpu/i386/i386dasm.h> ///////////////////////////////////////////////////////////////// @@ -39,7 +40,7 @@ enum }; -class i8086_common_cpu_device : public cpu_device +class i8086_common_cpu_device : public cpu_device, public i386_disassembler::config { public: template <class Object> static devcb_base &set_lock_handler(device_t &device, Object &&cb) @@ -134,9 +135,8 @@ protected: virtual void execute_set_input(int inputnum, int state) override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 8; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; + virtual int get_mode() const override; // device_state_interface overrides virtual void state_import(const device_state_entry &entry) override; @@ -314,7 +314,7 @@ protected: uint8_t m_test_state; address_space *m_program, *m_opcodes, *m_stack, *m_code, *m_extra; - direct_read_data *m_direct, *m_direct_opcodes; + direct_read_data<0> *m_direct, *m_direct_opcodes; address_space *m_io; offs_t m_fetch_xor; int m_icount; diff --git a/src/devices/cpu/i860/i860.cpp b/src/devices/cpu/i860/i860.cpp index eb22a347f2a..a9d8a3c78b9 100644 --- a/src/devices/cpu/i860/i860.cpp +++ b/src/devices/cpu/i860/i860.cpp @@ -18,6 +18,7 @@ TODO: Separate out i860XR and i860XP (make different types, etc). #include "emu.h" #include "debugger.h" #include "i860.h" +#include "i860dis.h" /* Control register numbers. */ @@ -231,11 +232,9 @@ void i860_cpu_device::device_reset() reset_i860(); } - -offs_t i860_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *i860_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( i860 ); - return CPU_DISASSEMBLE_NAME(i860)(this, stream, pc, oprom, opram, options); + return new i860_disassembler; } diff --git a/src/devices/cpu/i860/i860.h b/src/devices/cpu/i860/i860.h index 3387244858e..05e81407e7c 100644 --- a/src/devices/cpu/i860/i860.h +++ b/src/devices/cpu/i860/i860.h @@ -80,9 +80,7 @@ protected: virtual void state_import(const device_state_entry &entry) override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 4; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 4; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; diff --git a/src/devices/cpu/i860/i860dasm.cpp b/src/devices/cpu/i860/i860dasm.cpp deleted file mode 100644 index 03d24e2d2a8..00000000000 --- a/src/devices/cpu/i860/i860dasm.cpp +++ /dev/null @@ -1,378 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Jason Eckhardt -#include "i860.h" - -/* Sub-group decoders */ -static void i860_dasm_core_dasm(const uint32_t op, char* buffer); -static void i860_dasm_floating_point_dasm(const uint32_t op, char* buffer); -static void i860_dasm_CTRL_dasm(const uint32_t op, char* buffer); - -/* REG-Format Opcodes*/ -static void i860_dasm_ldx(const uint32_t op, char* buffer); -static void i860_dasm_stx(const uint32_t op, char* buffer); -static void i860_dasm_ixfr(const uint32_t op, char* buffer); -static void i860_dasm_fid_fst(const uint32_t op, char* buffer); -static void i860_dasm_flush(const uint32_t op, char* buffer); -static void i860_dasm_pstd(const uint32_t op, char* buffer); -static void i860_dasm_ldc_sdc(const uint32_t op, char* buffer); -static void i860_dasm_bri(const uint32_t op, char* buffer); -static void i860_dasm_trap(const uint32_t op, char* buffer); -static void i860_dasm_bte_btne(const uint32_t op, char* buffer); -static void i860_dasm_pfidy(const uint32_t op, char* buffer); -static void i860_dasm_addu_subu(const uint32_t op, char* buffer); -static void i860_dasm_shl_shr(const uint32_t op, char* buffer); -static void i860_dasm_shrd(const uint32_t op, char* buffer); -static void i860_dasm_bla(const uint32_t op, char* buffer); -static void i860_dasm_shra(const uint32_t op, char* buffer); -static void i860_dasm_and_andh(const uint32_t op, char* buffer); -static void i860_dasm_andnot_andnoth(const uint32_t op, char* buffer); -static void i860_dasm_or_orh(const uint32_t op, char* buffer); -static void i860_dasm_xor_xorh(const uint32_t op, char* buffer); - -/* CORE Escape Opcodes */ -static void i860_dasm_CORE_lock(const uint32_t op, char* buffer); -static void i860_dasm_CORE_calli(const uint32_t op, char* buffer); -static void i860_dasm_CORE_intovr(const uint32_t op, char* buffer); -static void i860_dasm_CORE_unlock(const uint32_t op, char* buffer); - -/* CTRL-Format Opcodes */ -static void i860_dasm_CTRL_br(const uint32_t op, char* buffer); -static void i860_dasm_CTRL_call(const uint32_t op, char* buffer); -static void i860_dasm_CTRL_bc_bct(const uint32_t op, char* buffer); -static void i860_dasm_CTRL_bnc_bnct(const uint32_t op, char* buffer); - -/* Floating-Point Instructions */ - - -CPU_DISASSEMBLE( i860 ) -{ - char tempB[1024] = ""; - - /* Little Endian */ - const uint32_t op = (oprom[3] << 24) | (oprom[2] << 16) | (oprom[1] << 8) | (oprom[0] << 0); - //const uint32_t op = (oprom[2] << 24) | (oprom[3] << 16) | (oprom[0] << 8) | (oprom[1] << 0); /* Mixed Endian */ - //const uint32_t op = (oprom[0] << 24) | (oprom[1] << 16) | (oprom[2] << 8) | (oprom[3] << 0); /* Big Endian */ - //const uint32_t op = (oprom[1] << 24) | (oprom[0] << 16) | (oprom[3] << 8) | (oprom[2] << 0); /* Mixed Endian */ - - /* The opcode is the top 6 bits */ - uint8_t opcode = (op >> 26) & 0x3f; - - /* DEBUG - print this out if you feel things are going a bit wonky */ - // sprintf(buffer, "%08x : oo %02x", op, opcode); - - /* Main decode */ - switch (opcode) - { - case 0x00: - case 0x01: - case 0x04: - case 0x05: i860_dasm_ldx(op, tempB); break; - - case 0x03: - case 0x07: i860_dasm_stx(op, tempB); break; - - case 0x02: i860_dasm_ixfr(op, tempB); break; - - case 0x06: sprintf(tempB, "(reserved)"); break; - - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: i860_dasm_fid_fst(op, tempB); break; - - case 0x0d: i860_dasm_flush(op, tempB); break; - - case 0x0f: i860_dasm_pstd(op, tempB); break; - - case 0x0c: - case 0x0e: i860_dasm_ldc_sdc(op, tempB); break; - - case 0x10: i860_dasm_bri(op, tempB); break; - - case 0x11: i860_dasm_trap(op, tempB); break; - - case 0x12: i860_dasm_floating_point_dasm(op, tempB); break; /* Floating point operation sub-group */ - - case 0x13: i860_dasm_core_dasm(op, tempB); break; /* Core operation sub-group */ - - case 0x14: - case 0x15: - case 0x16: - case 0x17: i860_dasm_bte_btne(op, tempB); break; - - case 0x18: - case 0x19: i860_dasm_pfidy(op, tempB); break; - - case 0x1a: - case 0x1b: - case 0x1c: - case 0x1d: - case 0x1e: - case 0x1f: i860_dasm_CTRL_dasm(op, tempB); break; /* CTRL operation sub-group */ - - case 0x20: - case 0x21: - case 0x22: - case 0x23: - case 0x24: - case 0x25: - case 0x26: - case 0x27: i860_dasm_addu_subu(op, tempB); break; - - case 0x28: - case 0x29: - case 0x2a: - case 0x2b: i860_dasm_shl_shr(op, tempB); break; - - case 0x2c: i860_dasm_shrd(op, tempB); break; - - case 0x2d: i860_dasm_bla(op, tempB); break; - - case 0x2e: - case 0x2f: i860_dasm_shra(op, tempB); break; - - case 0x30: - case 0x31: - case 0x32: - case 0x33: i860_dasm_and_andh(op, tempB); break; - - case 0x34: - case 0x35: - case 0x36: - case 0x37: i860_dasm_andnot_andnoth(op, tempB); break; - - case 0x38: - case 0x39: - case 0x3a: - case 0x3b: i860_dasm_or_orh(op, tempB); break; - - case 0x3c: - case 0x3d: - case 0x3e: - case 0x3f: i860_dasm_xor_xorh(op, tempB); break; - - default: sprintf(tempB, "(reserved)"); break; - } - - /* More Debug */ - //strcat(buffer, " : "); - //strcat(buffer, tempB); - sprintf(buffer, "%s", tempB); - - /* All opcodes are 32 bits */ - return (4 | DASMFLAG_SUPPORTED); -} - - -// BIT HELPER -// 31 27 23 19 15 11 7 3 -// 0000 0011 1111 1111 0000 0111 1110 0000 - - -/**********************/ -/* Sub-group decoders */ -/**********************/ -static void i860_dasm_core_dasm(const uint32_t op, char* buffer) -{ - //uint8_t src1 = (op >> 11) & 0x0000001f; - - /* Reserved bits must be set to 0 */ - if ( (op & 0x000007e0) || (op & 0x03ff0000) ) - { - //logerror("[i860] Reserved CORE bits must be set to 0."); - printf("CORE baddie\n"); - } - - switch(op & 0x0000001f) - { - case 0x01: i860_dasm_CORE_lock(op, buffer); break; - case 0x02: i860_dasm_CORE_calli(op, buffer); break; - case 0x04: i860_dasm_CORE_intovr(op, buffer); break; - case 0x07: i860_dasm_CORE_unlock(op, buffer); break; - - default: sprintf(buffer, "(reserved)"); break; - } -} - -static void i860_dasm_floating_point_dasm(const uint32_t op, char* buffer) -{ - sprintf(buffer, "[[F-P unit]]"); -} - -static void i860_dasm_CTRL_dasm(const uint32_t op, char* buffer) -{ - uint8_t opc = (op >> 26) & 0x07; - - switch(opc) - { - case 0x02: i860_dasm_CTRL_br(op, buffer); break; - case 0x03: i860_dasm_CTRL_call(op, buffer); break; - case 0x04: case 0x05: i860_dasm_CTRL_bc_bct(op, buffer); break; - case 0x06: case 0x07: i860_dasm_CTRL_bnc_bnct(op, buffer); break; - - default: sprintf(buffer, "(reserved)"); break; - } -} - - -/*********************/ -/* REG-Format Opcodes*/ -/*********************/ -static void i860_dasm_ldx(const uint32_t op, char* buffer) -{ - sprintf(buffer, "ldx"); -} - -static void i860_dasm_stx(const uint32_t op, char* buffer) -{ - sprintf(buffer, "stx"); -} - -static void i860_dasm_ixfr(const uint32_t op, char* buffer) -{ -// uint16_t val = op & 0x7ff; -// uint8_t opc = (op >> 26) & 0x3f; -// uint8_t src2 = (op >> 21) & 0x1f; -// uint8_t dest = (op >> 16) & 0x1f; -// uint8_t src1 = (op >> 11) & 0x1f; - - sprintf(buffer, "ixfr"); -} - -static void i860_dasm_fid_fst(const uint32_t op, char* buffer) -{ - sprintf(buffer, "fst"); -} - -static void i860_dasm_flush(const uint32_t op, char* buffer) -{ - sprintf(buffer, "flush"); -} - -static void i860_dasm_pstd(const uint32_t op, char* buffer) -{ - sprintf(buffer, "pstd"); -} - -static void i860_dasm_ldc_sdc(const uint32_t op, char* buffer) -{ - sprintf(buffer, "ldc, sdc"); -} - -static void i860_dasm_bri(const uint32_t op, char* buffer) -{ - sprintf(buffer, "bri"); -} - -static void i860_dasm_trap(const uint32_t op, char* buffer) -{ - sprintf(buffer, "trap"); -} - -static void i860_dasm_bte_btne(const uint32_t op, char* buffer) -{ - sprintf(buffer, "bte, btne"); -} - -static void i860_dasm_pfidy(const uint32_t op, char* buffer) -{ - sprintf(buffer, "pfidy"); -} - -static void i860_dasm_addu_subu(const uint32_t op, char* buffer) -{ - sprintf(buffer, "addu, subu"); -} - -static void i860_dasm_shl_shr(const uint32_t op, char* buffer) -{ - sprintf(buffer, "shl, shr"); -} - -static void i860_dasm_shrd(const uint32_t op, char* buffer) -{ - sprintf(buffer, "shrd"); -} - -static void i860_dasm_bla(const uint32_t op, char* buffer) -{ - sprintf(buffer, "bla"); -} - -static void i860_dasm_shra(const uint32_t op, char* buffer) -{ - sprintf(buffer, "shra"); -} - -static void i860_dasm_and_andh(const uint32_t op, char* buffer) -{ - sprintf(buffer, "and, andh"); -} - -static void i860_dasm_andnot_andnoth(const uint32_t op, char* buffer) -{ - sprintf(buffer, "andnot, andnoth"); -} - -static void i860_dasm_or_orh(const uint32_t op, char* buffer) -{ - sprintf(buffer, "or, orh"); -} - -static void i860_dasm_xor_xorh(const uint32_t op, char* buffer) -{ - sprintf(buffer, "xor, xorh"); -} - - -/***********************/ -/* CORE Escape Opcodes */ -/***********************/ -static void i860_dasm_CORE_lock(const uint32_t op, char* buffer) -{ - sprintf(buffer, "lock"); -} - -static void i860_dasm_CORE_calli(const uint32_t op, char* buffer) -{ - sprintf(buffer, "calli"); -} - -static void i860_dasm_CORE_intovr(const uint32_t op, char* buffer) -{ - sprintf(buffer, "intovr"); -} - -static void i860_dasm_CORE_unlock(const uint32_t op, char* buffer) -{ - sprintf(buffer, "unlock"); -} - - -/***********************/ -/* CTRL-Format Opcodes */ -/***********************/ -static void i860_dasm_CTRL_br(const uint32_t op, char* buffer) -{ - sprintf(buffer, "br"); -} - -static void i860_dasm_CTRL_call(const uint32_t op, char* buffer) -{ - sprintf(buffer, "call"); -} - -static void i860_dasm_CTRL_bc_bct(const uint32_t op, char* buffer) -{ - sprintf(buffer, "bct"); -} - -static void i860_dasm_CTRL_bnc_bnct(const uint32_t op, char* buffer) -{ - sprintf(buffer, "bnct"); -} - - -/*******************************/ -/* Floating-Point Instructions */ -/*******************************/ diff --git a/src/devices/cpu/i860/i860dis.cpp b/src/devices/cpu/i860/i860dis.cpp index a1230d570cc..5f9d08da411 100644 --- a/src/devices/cpu/i860/i860dis.cpp +++ b/src/devices/cpu/i860/i860dis.cpp @@ -11,7 +11,7 @@ ***************************************************************************/ #include "emu.h" -#include "i860.h" +#include "i860dis.h" /* Macros for accessing register fields in instruction word. */ #define get_isrc1(bits) (((bits) >> 11) & 0x1f) @@ -28,12 +28,12 @@ /* Control register names. */ -static const char *const cr2str[] = +const char *const i860_disassembler::cr2str[] = {"fir", "psr", "dirbase", "db", "fsr", "epsr", "!", "!"}; /* Sign extend N-bit number. */ -static int32_t sign_ext(uint32_t x, int n) +int32_t i860_disassembler::sign_ext(uint32_t x, int n) { int32_t t; t = x >> (n - 1); @@ -44,7 +44,7 @@ static int32_t sign_ext(uint32_t x, int n) /* Basic integer 3-address register format: * mnemonic %rs1,%rs2,%rd */ -static void int_12d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::int_12d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { /* Possibly prefix shrd with 'd.' */ if (((insn & 0xfc000000) == 0xb0000000) && (insn & 0x200)) @@ -58,7 +58,7 @@ static void int_12d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t /* Basic integer 3-address imm16 format: * mnemonic #imm16,%rs2,%rd */ -static void int_i2d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::int_i2d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { /* Sign extend the 16-bit immediate. Print as hex for the bitwise operations. */ @@ -73,21 +73,21 @@ static void int_i2d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t /* Integer (mixed) 2-address isrc1ni,fdest. */ -static void int_1d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::int_1d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { util::stream_format(stream, "%s\t%%r%d,%%f%d", mnemonic, get_isrc1 (insn), get_fdest (insn)); } /* Integer (mixed) 2-address csrc2,idest. */ -static void int_cd(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::int_cd(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { util::stream_format(stream, "%s\t%%%s,%%r%d", mnemonic, cr2str[get_creg (insn)], get_idest (insn)); } /* Integer (mixed) 2-address isrc1,csrc2. */ -static void int_1c(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::int_1c(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { util::stream_format(stream, "%s\t%%r%d,%%%s", mnemonic, get_isrc1(insn), cr2str[get_creg (insn)]); } @@ -95,7 +95,7 @@ static void int_1c(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t i /* Integer 1-address register format: * mnemonic %rs1 */ -static void int_1(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::int_1(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { util::stream_format(stream, "%s\t%%r%d", mnemonic, get_isrc1 (insn)); } @@ -103,7 +103,7 @@ static void int_1(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t in /* Integer no-address register format: * mnemonic */ -static void int_0(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::int_0(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { util::stream_format(stream, "%s", mnemonic); } @@ -111,7 +111,7 @@ static void int_0(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t in /* Basic floating-point 3-address register format: * mnemonic %fs1,%fs2,%fd */ -static void flop_12d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::flop_12d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { char newname[256]; const char *const suffix[4] = { "ss", "sd", "ds", "dd" }; @@ -165,7 +165,7 @@ static void flop_12d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t /* Floating-point 2-address register format: * mnemonic %fs1,%fd */ -static void flop_1d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::flop_1d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { const char *const suffix[4] = { "ss", "sd", "ds", "dd" }; const char *prefix_d, *prefix_p; @@ -179,7 +179,7 @@ static void flop_1d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t /* Floating-point 2-address register format: * mnemonic %fs2,%fd */ -static void flop_2d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::flop_2d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { const char *const suffix[4] = { "ss", "sd", "ds", "dd" }; const char *prefix_d; @@ -192,7 +192,7 @@ static void flop_2d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t /* Floating-point (mixed) 2-address register format: * fxfr fsrc1,idest. */ -static void flop_fxfr(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::flop_fxfr(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { const char *prefix_d = (insn & 0x200) ? "d." : ""; util::stream_format(stream, "%s%s\t%%f%d,%%r%d", prefix_d, mnemonic, get_fsrc1 (insn), @@ -202,7 +202,7 @@ static void flop_fxfr(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_ /* Branch with reg,reg,sbroff format: * mnemonic %rs1,%rs2,sbroff */ -static void int_12S(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::int_12S(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { int32_t sbroff = sign_ext ((((insn >> 5) & 0xf800) | (insn & 0x07ff)), 16); int32_t rel = (int32_t)pc + (sbroff << 2) + 4; @@ -214,7 +214,7 @@ static void int_12S(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t /* Branch with #const5,reg,sbroff format: * mnemonic #const5,%rs2,sbroff */ -static void int_i2S(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::int_i2S(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { int32_t sbroff = sign_ext ((((insn >> 5) & 0xf800) | (insn & 0x07ff)), 16); int32_t rel = (int32_t)pc + (sbroff << 2) + 4; @@ -226,7 +226,7 @@ static void int_i2S(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t /* Branch with lbroff format: * mnemonic lbroff */ -static void int_L(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::int_L(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { int32_t lbroff = sign_ext ((insn & 0x03ffffff), 26); int32_t rel = (int32_t)pc + (lbroff << 2) + 4; @@ -238,7 +238,7 @@ static void int_L(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t in /* Integer load. * ld.{b,s,l} isrc1(isrc2),idest * ld.{b,s,l} #const(isrc2),idest */ -static void int_ldx(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::int_ldx(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { /* Operand size, in bytes. */ int sizes[4] = { 1, 1, 2, 4 }; @@ -265,7 +265,7 @@ static void int_ldx(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t /* Integer store: st.b isrc1ni,#const(isrc2) */ -static void int_stx(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::int_stx(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { /* Operand size, in bytes. */ int sizes[4] = { 1, 1, 2, 4 }; @@ -291,7 +291,7 @@ static void int_stx(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t * "fst.y fdest,isrc1(isrc2)", "fst.y fdest,isrc1(isrc2)++", * "fst.y fdest,#const(isrc2)" or "fst.y fdest,#const(isrc2)++" * Where y = {l,d,q}. Note, there is no pfld.q, though. */ -static void int_fldst(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::int_fldst(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { int32_t immsrc1 = sign_ext (get_imm16 (insn), 16); /* Operand size, in bytes. */ @@ -353,7 +353,7 @@ static void int_fldst(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_ /* flush #const(isrc2)[++]. */ -static void int_flush(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::int_flush(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { const char *const auto_suff[2] = { "", "++" }; int32_t immsrc = sign_ext (get_imm16 (insn), 16); @@ -363,257 +363,234 @@ static void int_flush(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_ } -/* Flags for the decode table. */ -enum -{ - DEC_MORE = 1, /* More decoding necessary. */ - DEC_DECODED = 2 /* Fully decoded, go. */ -}; - - -struct decode_tbl_t -{ - /* Disassembly function for this opcode. - Call with buffer, mnemonic, pc, insn. */ - void (*insn_dis)(std::ostream &, char *, uint32_t, uint32_t); - - /* Flags for this opcode. */ - char flags; - - /* Mnemonic of this opcode (sometimes partial when more decode is - done in disassembly routines-- e.g., loads and stores). */ - const char *mnemonic; -}; - - /* First-level decode table (i.e., for the 6 primary opcode bits). */ -static const decode_tbl_t decode_tbl[64] = +const i860_disassembler::decode_tbl_t i860_disassembler::decode_tbl[64] = { /* A slight bit of decoding for loads and stores is done in the execution routines (operand size and addressing mode), which is why their respective entries are identical. */ - { int_ldx, DEC_DECODED, "ld." }, /* ld.b isrc1(isrc2),idest. */ - { int_ldx, DEC_DECODED, "ld." }, /* ld.b #const(isrc2),idest. */ - { int_1d, DEC_DECODED, "ixfr" }, /* ixfr isrc1ni,fdest. */ - { int_stx, DEC_DECODED, "st." }, /* st.b isrc1ni,#const(isrc2). */ - { int_ldx, DEC_DECODED, "ld." }, /* ld.{s,l} isrc1(isrc2),idest. */ - { int_ldx, DEC_DECODED, "ld." }, /* ld.{s,l} #const(isrc2),idest. */ - { nullptr, 0 , nullptr }, - { int_stx, DEC_DECODED, "st." }, /* st.{s,l} isrc1ni,#const(isrc2),idest.*/ - { int_fldst, DEC_DECODED, "fld." }, /* fld.{l,d,q} isrc1(isrc2)[++],fdest. */ - { int_fldst, DEC_DECODED, "fld." }, /* fld.{l,d,q} #const(isrc2)[++],fdest. */ - { int_fldst, DEC_DECODED, "fst." }, /* fst.{l,d,q} fdest,isrc1(isrc2)[++] */ - { int_fldst, DEC_DECODED, "fst." }, /* fst.{l,d,q} fdest,#const(isrc2)[++] */ - { int_cd, DEC_DECODED, "ld.c" }, /* ld.c csrc2,idest. */ - { int_flush, DEC_DECODED, "flush" }, /* flush #const(isrc2) (or autoinc). */ - { int_1c, DEC_DECODED, "st.c" }, /* st.c isrc1,csrc2. */ - { int_fldst, DEC_DECODED, "pstd." }, /* pst.d fdest,#const(isrc2)[++]. */ - { int_1, DEC_DECODED, "bri" }, /* bri isrc1ni. */ - { int_12d, DEC_DECODED, "trap" }, /* trap isrc1ni,isrc2,idest. */ - { nullptr, DEC_MORE, nullptr }, /* FP ESCAPE FORMAT, more decode. */ - { nullptr, DEC_MORE, nullptr }, /* CORE ESCAPE FORMAT, more decode. */ - { int_12S, DEC_DECODED, "btne" }, /* btne isrc1,isrc2,sbroff. */ - { int_i2S, DEC_DECODED, "btne" }, /* btne #const,isrc2,sbroff. */ - { int_12S, DEC_DECODED, "bte" }, /* bte isrc1,isrc2,sbroff. */ - { int_i2S, DEC_DECODED, "bte" }, /* bte #const5,isrc2,idest. */ - { int_fldst, DEC_DECODED, "pfld." }, /* pfld.{l,d,q} isrc1(isrc2)[++],fdest. */ - { int_fldst, DEC_DECODED, "pfld." }, /* pfld.{l,d,q} #const(isrc2)[++],fdest.*/ - { int_L, DEC_DECODED, "br" }, /* br lbroff. */ - { int_L, DEC_DECODED, "call" }, /* call lbroff . */ - { int_L, DEC_DECODED, "bc" }, /* bc lbroff. */ - { int_L, DEC_DECODED, "bc.t" }, /* bc.t lbroff. */ - { int_L, DEC_DECODED, "bnc" }, /* bnc lbroff. */ - { int_L, DEC_DECODED, "bnc.t" }, /* bnc.t lbroff. */ - { int_12d, DEC_DECODED, "addu" }, /* addu isrc1,isrc2,idest. */ - { int_i2d, DEC_DECODED, "addu" }, /* addu #const,isrc2,idest. */ - { int_12d, DEC_DECODED, "subu" }, /* subu isrc1,isrc2,idest. */ - { int_i2d, DEC_DECODED, "subu" }, /* subu #const,isrc2,idest. */ - { int_12d, DEC_DECODED, "adds" }, /* adds isrc1,isrc2,idest. */ - { int_i2d, DEC_DECODED, "adds" }, /* adds #const,isrc2,idest. */ - { int_12d, DEC_DECODED, "subs" }, /* subs isrc1,isrc2,idest. */ - { int_i2d, DEC_DECODED, "subs" }, /* subs #const,isrc2,idest. */ - { int_12d, DEC_DECODED, "shl" }, /* shl isrc1,isrc2,idest. */ - { int_i2d, DEC_DECODED, "shl" }, /* shl #const,isrc2,idest. */ - { int_12d, DEC_DECODED, "shr" }, /* shr isrc1,isrc2,idest. */ - { int_i2d, DEC_DECODED, "shr" }, /* shr #const,isrc2,idest. */ - { int_12d, DEC_DECODED, "shrd" }, /* shrd isrc1ni,isrc2,idest. */ - { int_12S, DEC_DECODED, "bla" }, /* bla isrc1ni,isrc2,sbroff. */ - { int_12d, DEC_DECODED, "shra" }, /* shra isrc1,isrc2,idest. */ - { int_i2d, DEC_DECODED, "shra" }, /* shra #const,isrc2,idest. */ - { int_12d, DEC_DECODED, "and" }, /* and isrc1,isrc2,idest. */ - { int_i2d, DEC_DECODED, "and" }, /* and #const,isrc2,idest. */ - { nullptr, 0 , nullptr }, - { int_i2d, DEC_DECODED, "andh" }, /* andh #const,isrc2,idest. */ - { int_12d, DEC_DECODED, "andnot" }, /* andnot isrc1,isrc2,idest. */ - { int_i2d, DEC_DECODED, "andnot" }, /* andnot #const,isrc2,idest. */ - { nullptr, 0 , nullptr }, - { int_i2d, DEC_DECODED, "andnoth" }, /* andnoth #const,isrc2,idest.*/ - { int_12d, DEC_DECODED, "or" }, /* or isrc1,isrc2,idest. */ - { int_i2d, DEC_DECODED, "or" }, /* or #const,isrc2,idest. */ - { nullptr, 0 , nullptr }, - { int_i2d, DEC_DECODED, "orh" }, /* orh #const,isrc2,idest. */ - { int_12d, DEC_DECODED, "xor" }, /* xor isrc1,isrc2,idest. */ - { int_i2d, DEC_DECODED, "xor" }, /* xor #const,isrc2,idest. */ - { nullptr, 0 , nullptr }, - { int_i2d, DEC_DECODED, "xorh" }, /* xorh #const,isrc2,idest. */ + { &i860_disassembler::int_ldx, DEC_DECODED, "ld." }, /* ld.b isrc1(isrc2),idest. */ + { &i860_disassembler::int_ldx, DEC_DECODED, "ld." }, /* ld.b #const(isrc2),idest. */ + { &i860_disassembler::int_1d, DEC_DECODED, "ixfr" }, /* ixfr isrc1ni,fdest. */ + { &i860_disassembler::int_stx, DEC_DECODED, "st." }, /* st.b isrc1ni,#const(isrc2). */ + { &i860_disassembler::int_ldx, DEC_DECODED, "ld." }, /* ld.{s,l} isrc1(isrc2),idest. */ + { &i860_disassembler::int_ldx, DEC_DECODED, "ld." }, /* ld.{s,l} #const(isrc2),idest. */ + { nullptr, 0 , nullptr }, + { &i860_disassembler::int_stx, DEC_DECODED, "st." }, /* st.{s,l} isrc1ni,#const(isrc2),idest.*/ + { &i860_disassembler::int_fldst, DEC_DECODED, "fld." }, /* fld.{l,d,q} isrc1(isrc2)[++],fdest. */ + { &i860_disassembler::int_fldst, DEC_DECODED, "fld." }, /* fld.{l,d,q} #const(isrc2)[++],fdest. */ + { &i860_disassembler::int_fldst, DEC_DECODED, "fst." }, /* fst.{l,d,q} fdest,isrc1(isrc2)[++] */ + { &i860_disassembler::int_fldst, DEC_DECODED, "fst." }, /* fst.{l,d,q} fdest,#const(isrc2)[++] */ + { &i860_disassembler::int_cd, DEC_DECODED, "ld.c" }, /* ld.c csrc2,idest. */ + { &i860_disassembler::int_flush, DEC_DECODED, "flush" }, /* flush #const(isrc2) (or autoinc). */ + { &i860_disassembler::int_1c, DEC_DECODED, "st.c" }, /* st.c isrc1,csrc2. */ + { &i860_disassembler::int_fldst, DEC_DECODED, "pstd." }, /* pst.d fdest,#const(isrc2)[++]. */ + { &i860_disassembler::int_1, DEC_DECODED, "bri" }, /* bri isrc1ni. */ + { &i860_disassembler::int_12d, DEC_DECODED, "trap" }, /* trap isrc1ni,isrc2,idest. */ + { nullptr, DEC_MORE, nullptr }, /* FP ESCAPE FORMAT, more decode. */ + { nullptr, DEC_MORE, nullptr }, /* CORE ESCAPE FORMAT, more decode. */ + { &i860_disassembler::int_12S, DEC_DECODED, "btne" }, /* btne isrc1,isrc2,sbroff. */ + { &i860_disassembler::int_i2S, DEC_DECODED, "btne" }, /* btne #const,isrc2,sbroff. */ + { &i860_disassembler::int_12S, DEC_DECODED, "bte" }, /* bte isrc1,isrc2,sbroff. */ + { &i860_disassembler::int_i2S, DEC_DECODED, "bte" }, /* bte #const5,isrc2,idest. */ + { &i860_disassembler::int_fldst, DEC_DECODED, "pfld." }, /* pfld.{l,d,q} isrc1(isrc2)[++],fdest. */ + { &i860_disassembler::int_fldst, DEC_DECODED, "pfld." }, /* pfld.{l,d,q} #const(isrc2)[++],fdest.*/ + { &i860_disassembler::int_L, DEC_DECODED, "br" }, /* br lbroff. */ + { &i860_disassembler::int_L, DEC_DECODED, "call" }, /* call lbroff . */ + { &i860_disassembler::int_L, DEC_DECODED, "bc" }, /* bc lbroff. */ + { &i860_disassembler::int_L, DEC_DECODED, "bc.t" }, /* bc.t lbroff. */ + { &i860_disassembler::int_L, DEC_DECODED, "bnc" }, /* bnc lbroff. */ + { &i860_disassembler::int_L, DEC_DECODED, "bnc.t" }, /* bnc.t lbroff. */ + { &i860_disassembler::int_12d, DEC_DECODED, "addu" }, /* addu isrc1,isrc2,idest. */ + { &i860_disassembler::int_i2d, DEC_DECODED, "addu" }, /* addu #const,isrc2,idest. */ + { &i860_disassembler::int_12d, DEC_DECODED, "subu" }, /* subu isrc1,isrc2,idest. */ + { &i860_disassembler::int_i2d, DEC_DECODED, "subu" }, /* subu #const,isrc2,idest. */ + { &i860_disassembler::int_12d, DEC_DECODED, "adds" }, /* adds isrc1,isrc2,idest. */ + { &i860_disassembler::int_i2d, DEC_DECODED, "adds" }, /* adds #const,isrc2,idest. */ + { &i860_disassembler::int_12d, DEC_DECODED, "subs" }, /* subs isrc1,isrc2,idest. */ + { &i860_disassembler::int_i2d, DEC_DECODED, "subs" }, /* subs #const,isrc2,idest. */ + { &i860_disassembler::int_12d, DEC_DECODED, "shl" }, /* shl isrc1,isrc2,idest. */ + { &i860_disassembler::int_i2d, DEC_DECODED, "shl" }, /* shl #const,isrc2,idest. */ + { &i860_disassembler::int_12d, DEC_DECODED, "shr" }, /* shr isrc1,isrc2,idest. */ + { &i860_disassembler::int_i2d, DEC_DECODED, "shr" }, /* shr #const,isrc2,idest. */ + { &i860_disassembler::int_12d, DEC_DECODED, "shrd" }, /* shrd isrc1ni,isrc2,idest. */ + { &i860_disassembler::int_12S, DEC_DECODED, "bla" }, /* bla isrc1ni,isrc2,sbroff. */ + { &i860_disassembler::int_12d, DEC_DECODED, "shra" }, /* shra isrc1,isrc2,idest. */ + { &i860_disassembler::int_i2d, DEC_DECODED, "shra" }, /* shra #const,isrc2,idest. */ + { &i860_disassembler::int_12d, DEC_DECODED, "and" }, /* and isrc1,isrc2,idest. */ + { &i860_disassembler::int_i2d, DEC_DECODED, "and" }, /* and #const,isrc2,idest. */ + { nullptr, 0 , nullptr }, + { &i860_disassembler::int_i2d, DEC_DECODED, "andh" }, /* andh #const,isrc2,idest. */ + { &i860_disassembler::int_12d, DEC_DECODED, "andnot" }, /* andnot isrc1,isrc2,idest. */ + { &i860_disassembler::int_i2d, DEC_DECODED, "andnot" }, /* andnot #const,isrc2,idest. */ + { nullptr, 0 , nullptr }, + { &i860_disassembler::int_i2d, DEC_DECODED, "andnoth" }, /* andnoth #const,isrc2,idest.*/ + { &i860_disassembler::int_12d, DEC_DECODED, "or" }, /* or isrc1,isrc2,idest. */ + { &i860_disassembler::int_i2d, DEC_DECODED, "or" }, /* or #const,isrc2,idest. */ + { nullptr, 0 , nullptr }, + { &i860_disassembler::int_i2d, DEC_DECODED, "orh" }, /* orh #const,isrc2,idest. */ + { &i860_disassembler::int_12d, DEC_DECODED, "xor" }, /* xor isrc1,isrc2,idest. */ + { &i860_disassembler::int_i2d, DEC_DECODED, "xor" }, /* xor #const,isrc2,idest. */ + { nullptr, 0 , nullptr }, + { &i860_disassembler::int_i2d, DEC_DECODED, "xorh" }, /* xorh #const,isrc2,idest. */ }; /* Second-level decode table (i.e., for the 3 core escape opcode bits). */ -static const decode_tbl_t core_esc_decode_tbl[8] = +const i860_disassembler::decode_tbl_t i860_disassembler::core_esc_decode_tbl[8] = { - { nullptr, 0 , nullptr }, - { int_0, DEC_DECODED, "lock" }, /* lock. */ - { int_1, DEC_DECODED, "calli" }, /* calli isrc1ni. */ - { nullptr, 0 , nullptr }, - { int_0, DEC_DECODED, "intovr" }, /* intovr. */ - { nullptr, 0 , nullptr }, - { nullptr, 0 , nullptr }, - { int_0, DEC_DECODED, "unlock" }, /* unlock. */ + { nullptr, 0 , nullptr }, + { &i860_disassembler::int_0, DEC_DECODED, "lock" }, /* lock. */ + { &i860_disassembler::int_1, DEC_DECODED, "calli" }, /* calli isrc1ni. */ + { nullptr, 0 , nullptr }, + { &i860_disassembler::int_0, DEC_DECODED, "intovr" }, /* intovr. */ + { nullptr, 0 , nullptr }, + { nullptr, 0 , nullptr }, + { &i860_disassembler::int_0, DEC_DECODED, "unlock" }, /* unlock. */ }; /* Second-level decode table (i.e., for the 7 FP extended opcode bits). */ -static const decode_tbl_t fp_decode_tbl[128] = +const i860_disassembler::decode_tbl_t i860_disassembler::fp_decode_tbl[128] = { /* Floating point instructions. The least significant 7 bits are the (extended) opcode and bits 10:7 are P,D,S,R respectively ([p]ipelined, [d]ual, [s]ource prec., [r]esult prec.). For some operations, I defer decoding the P,S,R bits to the emulation routine for them. */ - { flop_12d, DEC_DECODED, "r2p1." }, /* 0x00 pf[m]am */ - { flop_12d, DEC_DECODED, "r2pt." }, /* 0x01 pf[m]am */ - { flop_12d, DEC_DECODED, "r2ap1." }, /* 0x02 pf[m]am */ - { flop_12d, DEC_DECODED, "r2apt." }, /* 0x03 pf[m]am */ - { flop_12d, DEC_DECODED, "i2p1." }, /* 0x04 pf[m]am */ - { flop_12d, DEC_DECODED, "i2pt." }, /* 0x05 pf[m]am */ - { flop_12d, DEC_DECODED, "i2ap1." }, /* 0x06 pf[m]am */ - { flop_12d, DEC_DECODED, "i2apt." }, /* 0x07 pf[m]am */ - { flop_12d, DEC_DECODED, "rat1p2." }, /* 0x08 pf[m]am */ - { flop_12d, DEC_DECODED, "m12apm." }, /* 0x09 pf[m]am */ - { flop_12d, DEC_DECODED, "ra1p2." }, /* 0x0A pf[m]am */ - { flop_12d, DEC_DECODED, "m12ttpa." }, /* 0x0B pf[m]am */ - { flop_12d, DEC_DECODED, "iat1p2." }, /* 0x0C pf[m]am */ - { flop_12d, DEC_DECODED, "m12tpm." }, /* 0x0D pf[m]am */ - { flop_12d, DEC_DECODED, "ia1p2." }, /* 0x0E pf[m]am */ - { flop_12d, DEC_DECODED, "m12tpa." }, /* 0x0F pf[m]am */ - { flop_12d, DEC_DECODED, "r2s1." }, /* 0x10 pf[m]sm */ - { flop_12d, DEC_DECODED, "r2st." }, /* 0x11 pf[m]sm */ - { flop_12d, DEC_DECODED, "r2as1." }, /* 0x12 pf[m]sm */ - { flop_12d, DEC_DECODED, "r2ast." }, /* 0x13 pf[m]sm */ - { flop_12d, DEC_DECODED, "i2s1." }, /* 0x14 pf[m]sm */ - { flop_12d, DEC_DECODED, "i2st." }, /* 0x15 pf[m]sm */ - { flop_12d, DEC_DECODED, "i2as1." }, /* 0x16 pf[m]sm */ - { flop_12d, DEC_DECODED, "i2ast." }, /* 0x17 pf[m]sm */ - { flop_12d, DEC_DECODED, "rat1s2." }, /* 0x18 pf[m]sm */ - { flop_12d, DEC_DECODED, "m12asm." }, /* 0x19 pf[m]sm */ - { flop_12d, DEC_DECODED, "ra1s2." }, /* 0x1A pf[m]sm */ - { flop_12d, DEC_DECODED, "m12ttsa." }, /* 0x1B pf[m]sm */ - { flop_12d, DEC_DECODED, "iat1s2." }, /* 0x1C pf[m]sm */ - { flop_12d, DEC_DECODED, "m12tsm." }, /* 0x1D pf[m]sm */ - { flop_12d, DEC_DECODED, "ia1s2." }, /* 0x1E pf[m]sm */ - { flop_12d, DEC_DECODED, "m12tsa." }, /* 0x1F pf[m]sm */ - { flop_12d, DEC_DECODED, "fmul." }, /* 0x20 [p]fmul */ - { flop_12d, DEC_DECODED, "fmlow." }, /* 0x21 fmlow.dd */ - { flop_2d, DEC_DECODED, "frcp." }, /* 0x22 frcp.{ss,sd,dd} */ - { flop_2d, DEC_DECODED, "frsqr." }, /* 0x23 frsqr.{ss,sd,dd} */ - { flop_12d, DEC_DECODED, "pfmul3.dd" }, /* 0x24 pfmul3.dd */ - { nullptr, 0 , nullptr }, /* 0x25 */ - { nullptr, 0 , nullptr }, /* 0x26 */ - { nullptr, 0 , nullptr }, /* 0x27 */ - { nullptr, 0 , nullptr }, /* 0x28 */ - { nullptr, 0 , nullptr }, /* 0x29 */ - { nullptr, 0 , nullptr }, /* 0x2A */ - { nullptr, 0 , nullptr }, /* 0x2B */ - { nullptr, 0 , nullptr }, /* 0x2C */ - { nullptr, 0 , nullptr }, /* 0x2D */ - { nullptr, 0 , nullptr }, /* 0x2E */ - { nullptr, 0 , nullptr }, /* 0x2F */ - { flop_12d, DEC_DECODED, "fadd." }, /* 0x30, [p]fadd.{ss,sd,dd} */ - { flop_12d, DEC_DECODED, "fsub." }, /* 0x31, [p]fsub.{ss,sd,dd} */ - { flop_1d, DEC_DECODED, "fix." }, /* 0x32, [p]fix.{ss,sd,dd} */ - { flop_1d, DEC_DECODED, "famov." }, /* 0x33, [p]famov.{ss,sd,ds,dd} */ - { flop_12d, DEC_DECODED, "f{gt,le}" }, /* 0x34, pf{gt,le}.{ss,dd} */ - { flop_12d, DEC_DECODED, "feq." }, /* 0x35, pfeq.{ss,dd} */ - { nullptr, 0 , nullptr }, /* 0x36 */ - { nullptr, 0 , nullptr }, /* 0x37 */ - { nullptr, 0 , nullptr }, /* 0x38 */ - { nullptr, 0 , nullptr }, /* 0x39 */ - { flop_1d, DEC_DECODED, "ftrunc." }, /* 0x3A, [p]ftrunc.{ss,sd,dd} */ - { nullptr, 0 , nullptr }, /* 0x3B */ - { nullptr, 0 , nullptr }, /* 0x3C */ - { nullptr, 0 , nullptr }, /* 0x3D */ - { nullptr, 0 , nullptr }, /* 0x3E */ - { nullptr, 0 , nullptr }, /* 0x3F */ - { flop_fxfr, DEC_DECODED, "fxfr" }, /* 0x40, fxfr fsrc1,idest. */ - { nullptr, 0 , nullptr }, /* 0x41 */ - { nullptr, 0 , nullptr }, /* 0x42 */ - { nullptr, 0 , nullptr }, /* 0x43 */ - { nullptr, 0 , nullptr }, /* 0x44 */ - { nullptr, 0 , nullptr }, /* 0x45 */ - { nullptr, 0 , nullptr }, /* 0x46 */ - { nullptr, 0 , nullptr }, /* 0x47 */ - { nullptr, 0 , nullptr }, /* 0x48 */ - { flop_12d, DEC_DECODED, "fiadd." }, /* 0x49, [p]fiadd.{ss,dd} */ - { nullptr, 0 , nullptr }, /* 0x4A */ - { nullptr, 0 , nullptr }, /* 0x4B */ - { nullptr, 0 , nullptr }, /* 0x4C */ - { flop_12d, DEC_DECODED, "fisub." }, /* 0x4D, [p]fisub.{ss,dd} */ - { nullptr, 0 , nullptr }, /* 0x4E */ - { nullptr, 0 , nullptr }, /* 0x4F */ - { flop_12d, DEC_DECODED, "faddp" }, /* 0x50, [p]faddp */ - { flop_12d, DEC_DECODED, "faddz" }, /* 0x51, [p]faddz */ - { nullptr, 0 , nullptr }, /* 0x52 */ - { nullptr, 0 , nullptr }, /* 0x53 */ - { nullptr, 0 , nullptr }, /* 0x54 */ - { nullptr, 0 , nullptr }, /* 0x55 */ - { nullptr, 0 , nullptr }, /* 0x56 */ - { flop_12d, DEC_DECODED, "fzchkl" }, /* 0x57, [p]fzchkl */ - { nullptr, 0 , nullptr }, /* 0x58 */ - { nullptr, 0 , nullptr }, /* 0x59 */ - { flop_1d, DEC_DECODED, "form" }, /* 0x5A, [p]form.dd */ - { nullptr, 0 , nullptr }, /* 0x5B */ - { nullptr, 0 , nullptr }, /* 0x5C */ - { nullptr, 0 , nullptr }, /* 0x5D */ - { nullptr, 0 , nullptr }, /* 0x5E */ - { flop_12d, DEC_DECODED, "fzchks" }, /* 0x5F, [p]fzchks */ - { nullptr, 0 , nullptr }, /* 0x60 */ - { nullptr, 0 , nullptr }, /* 0x61 */ - { nullptr, 0 , nullptr }, /* 0x62 */ - { nullptr, 0 , nullptr }, /* 0x63 */ - { nullptr, 0 , nullptr }, /* 0x64 */ - { nullptr, 0 , nullptr }, /* 0x65 */ - { nullptr, 0 , nullptr }, /* 0x66 */ - { nullptr, 0 , nullptr }, /* 0x67 */ - { nullptr, 0 , nullptr }, /* 0x68 */ - { nullptr, 0 , nullptr }, /* 0x69 */ - { nullptr, 0 , nullptr }, /* 0x6A */ - { nullptr, 0 , nullptr }, /* 0x6B */ - { nullptr, 0 , nullptr }, /* 0x6C */ - { nullptr, 0 , nullptr }, /* 0x6D */ - { nullptr, 0 , nullptr }, /* 0x6E */ - { nullptr, 0 , nullptr }, /* 0x6F */ - { nullptr, 0 , nullptr }, /* 0x70 */ - { nullptr, 0 , nullptr }, /* 0x71 */ - { nullptr, 0 , nullptr }, /* 0x72 */ - { nullptr, 0 , nullptr }, /* 0x73 */ - { nullptr, 0 , nullptr }, /* 0x74 */ - { nullptr, 0 , nullptr }, /* 0x75 */ - { nullptr, 0 , nullptr }, /* 0x76 */ - { nullptr, 0 , nullptr }, /* 0x77 */ - { nullptr, 0 , nullptr }, /* 0x78 */ - { nullptr, 0 , nullptr }, /* 0x79 */ - { nullptr, 0 , nullptr }, /* 0x7A */ - { nullptr, 0 , nullptr }, /* 0x7B */ - { nullptr, 0 , nullptr }, /* 0x7C */ - { nullptr, 0 , nullptr }, /* 0x7D */ - { nullptr, 0 , nullptr }, /* 0x7E */ - { nullptr, 0 , nullptr }, /* 0x7F */ + { &i860_disassembler::flop_12d, DEC_DECODED, "r2p1." }, /* 0x00 pf[m]am */ + { &i860_disassembler::flop_12d, DEC_DECODED, "r2pt." }, /* 0x01 pf[m]am */ + { &i860_disassembler::flop_12d, DEC_DECODED, "r2ap1." }, /* 0x02 pf[m]am */ + { &i860_disassembler::flop_12d, DEC_DECODED, "r2apt." }, /* 0x03 pf[m]am */ + { &i860_disassembler::flop_12d, DEC_DECODED, "i2p1." }, /* 0x04 pf[m]am */ + { &i860_disassembler::flop_12d, DEC_DECODED, "i2pt." }, /* 0x05 pf[m]am */ + { &i860_disassembler::flop_12d, DEC_DECODED, "i2ap1." }, /* 0x06 pf[m]am */ + { &i860_disassembler::flop_12d, DEC_DECODED, "i2apt." }, /* 0x07 pf[m]am */ + { &i860_disassembler::flop_12d, DEC_DECODED, "rat1p2." }, /* 0x08 pf[m]am */ + { &i860_disassembler::flop_12d, DEC_DECODED, "m12apm." }, /* 0x09 pf[m]am */ + { &i860_disassembler::flop_12d, DEC_DECODED, "ra1p2." }, /* 0x0A pf[m]am */ + { &i860_disassembler::flop_12d, DEC_DECODED, "m12ttpa." }, /* 0x0B pf[m]am */ + { &i860_disassembler::flop_12d, DEC_DECODED, "iat1p2." }, /* 0x0C pf[m]am */ + { &i860_disassembler::flop_12d, DEC_DECODED, "m12tpm." }, /* 0x0D pf[m]am */ + { &i860_disassembler::flop_12d, DEC_DECODED, "ia1p2." }, /* 0x0E pf[m]am */ + { &i860_disassembler::flop_12d, DEC_DECODED, "m12tpa." }, /* 0x0F pf[m]am */ + { &i860_disassembler::flop_12d, DEC_DECODED, "r2s1." }, /* 0x10 pf[m]sm */ + { &i860_disassembler::flop_12d, DEC_DECODED, "r2st." }, /* 0x11 pf[m]sm */ + { &i860_disassembler::flop_12d, DEC_DECODED, "r2as1." }, /* 0x12 pf[m]sm */ + { &i860_disassembler::flop_12d, DEC_DECODED, "r2ast." }, /* 0x13 pf[m]sm */ + { &i860_disassembler::flop_12d, DEC_DECODED, "i2s1." }, /* 0x14 pf[m]sm */ + { &i860_disassembler::flop_12d, DEC_DECODED, "i2st." }, /* 0x15 pf[m]sm */ + { &i860_disassembler::flop_12d, DEC_DECODED, "i2as1." }, /* 0x16 pf[m]sm */ + { &i860_disassembler::flop_12d, DEC_DECODED, "i2ast." }, /* 0x17 pf[m]sm */ + { &i860_disassembler::flop_12d, DEC_DECODED, "rat1s2." }, /* 0x18 pf[m]sm */ + { &i860_disassembler::flop_12d, DEC_DECODED, "m12asm." }, /* 0x19 pf[m]sm */ + { &i860_disassembler::flop_12d, DEC_DECODED, "ra1s2." }, /* 0x1A pf[m]sm */ + { &i860_disassembler::flop_12d, DEC_DECODED, "m12ttsa." }, /* 0x1B pf[m]sm */ + { &i860_disassembler::flop_12d, DEC_DECODED, "iat1s2." }, /* 0x1C pf[m]sm */ + { &i860_disassembler::flop_12d, DEC_DECODED, "m12tsm." }, /* 0x1D pf[m]sm */ + { &i860_disassembler::flop_12d, DEC_DECODED, "ia1s2." }, /* 0x1E pf[m]sm */ + { &i860_disassembler::flop_12d, DEC_DECODED, "m12tsa." }, /* 0x1F pf[m]sm */ + { &i860_disassembler::flop_12d, DEC_DECODED, "fmul." }, /* 0x20 [p]fmul */ + { &i860_disassembler::flop_12d, DEC_DECODED, "fmlow." }, /* 0x21 fmlow.dd */ + { &i860_disassembler::flop_2d, DEC_DECODED, "frcp." }, /* 0x22 frcp.{ss,sd,dd} */ + { &i860_disassembler::flop_2d, DEC_DECODED, "frsqr." }, /* 0x23 frsqr.{ss,sd,dd} */ + { &i860_disassembler::flop_12d, DEC_DECODED, "pfmul3.dd" }, /* 0x24 pfmul3.dd */ + { nullptr, 0 , nullptr }, /* 0x25 */ + { nullptr, 0 , nullptr }, /* 0x26 */ + { nullptr, 0 , nullptr }, /* 0x27 */ + { nullptr, 0 , nullptr }, /* 0x28 */ + { nullptr, 0 , nullptr }, /* 0x29 */ + { nullptr, 0 , nullptr }, /* 0x2A */ + { nullptr, 0 , nullptr }, /* 0x2B */ + { nullptr, 0 , nullptr }, /* 0x2C */ + { nullptr, 0 , nullptr }, /* 0x2D */ + { nullptr, 0 , nullptr }, /* 0x2E */ + { nullptr, 0 , nullptr }, /* 0x2F */ + { &i860_disassembler::flop_12d, DEC_DECODED, "fadd." }, /* 0x30, [p]fadd.{ss,sd,dd} */ + { &i860_disassembler::flop_12d, DEC_DECODED, "fsub." }, /* 0x31, [p]fsub.{ss,sd,dd} */ + { &i860_disassembler::flop_1d, DEC_DECODED, "fix." }, /* 0x32, [p]fix.{ss,sd,dd} */ + { &i860_disassembler::flop_1d, DEC_DECODED, "famov." }, /* 0x33, [p]famov.{ss,sd,ds,dd} */ + { &i860_disassembler::flop_12d, DEC_DECODED, "f{gt,le}" }, /* 0x34, pf{gt,le}.{ss,dd} */ + { &i860_disassembler::flop_12d, DEC_DECODED, "feq." }, /* 0x35, pfeq.{ss,dd} */ + { nullptr, 0 , nullptr }, /* 0x36 */ + { nullptr, 0 , nullptr }, /* 0x37 */ + { nullptr, 0 , nullptr }, /* 0x38 */ + { nullptr, 0 , nullptr }, /* 0x39 */ + { &i860_disassembler::flop_1d, DEC_DECODED, "ftrunc." }, /* 0x3A, [p]ftrunc.{ss,sd,dd} */ + { nullptr, 0 , nullptr }, /* 0x3B */ + { nullptr, 0 , nullptr }, /* 0x3C */ + { nullptr, 0 , nullptr }, /* 0x3D */ + { nullptr, 0 , nullptr }, /* 0x3E */ + { nullptr, 0 , nullptr }, /* 0x3F */ + { &i860_disassembler::flop_fxfr, DEC_DECODED, "fxfr" }, /* 0x40, fxfr fsrc1,idest. */ + { nullptr, 0 , nullptr }, /* 0x41 */ + { nullptr, 0 , nullptr }, /* 0x42 */ + { nullptr, 0 , nullptr }, /* 0x43 */ + { nullptr, 0 , nullptr }, /* 0x44 */ + { nullptr, 0 , nullptr }, /* 0x45 */ + { nullptr, 0 , nullptr }, /* 0x46 */ + { nullptr, 0 , nullptr }, /* 0x47 */ + { nullptr, 0 , nullptr }, /* 0x48 */ + { &i860_disassembler::flop_12d, DEC_DECODED, "fiadd." }, /* 0x49, [p]fiadd.{ss,dd} */ + { nullptr, 0 , nullptr }, /* 0x4A */ + { nullptr, 0 , nullptr }, /* 0x4B */ + { nullptr, 0 , nullptr }, /* 0x4C */ + { &i860_disassembler::flop_12d, DEC_DECODED, "fisub." }, /* 0x4D, [p]fisub.{ss,dd} */ + { nullptr, 0 , nullptr }, /* 0x4E */ + { nullptr, 0 , nullptr }, /* 0x4F */ + { &i860_disassembler::flop_12d, DEC_DECODED, "faddp" }, /* 0x50, [p]faddp */ + { &i860_disassembler::flop_12d, DEC_DECODED, "faddz" }, /* 0x51, [p]faddz */ + { nullptr, 0 , nullptr }, /* 0x52 */ + { nullptr, 0 , nullptr }, /* 0x53 */ + { nullptr, 0 , nullptr }, /* 0x54 */ + { nullptr, 0 , nullptr }, /* 0x55 */ + { nullptr, 0 , nullptr }, /* 0x56 */ + { &i860_disassembler::flop_12d, DEC_DECODED, "fzchkl" }, /* 0x57, [p]fzchkl */ + { nullptr, 0 , nullptr }, /* 0x58 */ + { nullptr, 0 , nullptr }, /* 0x59 */ + { &i860_disassembler::flop_1d, DEC_DECODED, "form" }, /* 0x5A, [p]form.dd */ + { nullptr, 0 , nullptr }, /* 0x5B */ + { nullptr, 0 , nullptr }, /* 0x5C */ + { nullptr, 0 , nullptr }, /* 0x5D */ + { nullptr, 0 , nullptr }, /* 0x5E */ + { &i860_disassembler::flop_12d, DEC_DECODED, "fzchks" }, /* 0x5F, [p]fzchks */ + { nullptr, 0 , nullptr }, /* 0x60 */ + { nullptr, 0 , nullptr }, /* 0x61 */ + { nullptr, 0 , nullptr }, /* 0x62 */ + { nullptr, 0 , nullptr }, /* 0x63 */ + { nullptr, 0 , nullptr }, /* 0x64 */ + { nullptr, 0 , nullptr }, /* 0x65 */ + { nullptr, 0 , nullptr }, /* 0x66 */ + { nullptr, 0 , nullptr }, /* 0x67 */ + { nullptr, 0 , nullptr }, /* 0x68 */ + { nullptr, 0 , nullptr }, /* 0x69 */ + { nullptr, 0 , nullptr }, /* 0x6A */ + { nullptr, 0 , nullptr }, /* 0x6B */ + { nullptr, 0 , nullptr }, /* 0x6C */ + { nullptr, 0 , nullptr }, /* 0x6D */ + { nullptr, 0 , nullptr }, /* 0x6E */ + { nullptr, 0 , nullptr }, /* 0x6F */ + { nullptr, 0 , nullptr }, /* 0x70 */ + { nullptr, 0 , nullptr }, /* 0x71 */ + { nullptr, 0 , nullptr }, /* 0x72 */ + { nullptr, 0 , nullptr }, /* 0x73 */ + { nullptr, 0 , nullptr }, /* 0x74 */ + { nullptr, 0 , nullptr }, /* 0x75 */ + { nullptr, 0 , nullptr }, /* 0x76 */ + { nullptr, 0 , nullptr }, /* 0x77 */ + { nullptr, 0 , nullptr }, /* 0x78 */ + { nullptr, 0 , nullptr }, /* 0x79 */ + { nullptr, 0 , nullptr }, /* 0x7A */ + { nullptr, 0 , nullptr }, /* 0x7B */ + { nullptr, 0 , nullptr }, /* 0x7C */ + { nullptr, 0 , nullptr }, /* 0x7D */ + { nullptr, 0 , nullptr }, /* 0x7E */ + { nullptr, 0 , nullptr }, /* 0x7F */ }; /* Replaces tabs with spaces. */ -static void i860_dasm_tab_replacer(std::ostream &stream, const std::string &buf, int tab_size) +void i860_disassembler::i860_dasm_tab_replacer(std::ostream &stream, const std::string &buf, int tab_size) { int tab_count = 0; @@ -636,14 +613,11 @@ static void i860_dasm_tab_replacer(std::ostream &stream, const std::string &buf, } -static offs_t internal_disasm_i860(cpu_device *device, std::ostream &main_stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, int options) +offs_t i860_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - std::stringstream stream; + std::stringstream tstream; - uint32_t insn = (oprom[0] << 0) | - (oprom[1] << 8) | - (oprom[2] << 16) | - (oprom[3] << 24); + uint32_t insn = opcodes.r32(pc); int unrecognized_op = 1; int upper_6bits = (insn >> 26) & 0x3f; @@ -651,7 +625,7 @@ static offs_t internal_disasm_i860(cpu_device *device, std::ostream &main_stream if (flags & DEC_DECODED) { const char *s = decode_tbl[upper_6bits].mnemonic; - decode_tbl[upper_6bits].insn_dis (stream, (char *)s, pc, insn); + (this->*(decode_tbl[upper_6bits].insn_dis)) (tstream, (char *)s, pc, insn); unrecognized_op = 0; } else if (flags & DEC_MORE) @@ -663,7 +637,7 @@ static offs_t internal_disasm_i860(cpu_device *device, std::ostream &main_stream const char *s = fp_decode_tbl[insn & 0x7f].mnemonic; if (fp_flags & DEC_DECODED) { - fp_decode_tbl[insn & 0x7f].insn_dis (stream, (char *)s, pc, insn); + (this->*(fp_decode_tbl[insn & 0x7f].insn_dis)) (tstream, (char *)s, pc, insn); unrecognized_op = 0; } } @@ -674,25 +648,24 @@ static offs_t internal_disasm_i860(cpu_device *device, std::ostream &main_stream const char *s = core_esc_decode_tbl[insn & 0x3].mnemonic; if (esc_flags & DEC_DECODED) { - core_esc_decode_tbl[insn & 0x3].insn_dis (stream, (char *)s, pc, insn); + (this->*(core_esc_decode_tbl[insn & 0x3].insn_dis)) (tstream, (char *)s, pc, insn); unrecognized_op = 0; } } } if (unrecognized_op) - util::stream_format(stream, ".long\t%#08x", insn); + util::stream_format(tstream, ".long\t%#08x", insn); /* Replace tabs with spaces */ - i860_dasm_tab_replacer(main_stream, stream.str(), 10); + i860_dasm_tab_replacer(stream, tstream.str(), 10); /* Return number of bytes disassembled. */ /* MAME dasm flags haven't been added yet */ return (4); } - -CPU_DISASSEMBLE(i860) +u32 i860_disassembler::opcode_alignment() const { - return internal_disasm_i860(device, stream, pc, oprom, opram, options); + return 4; } diff --git a/src/devices/cpu/i860/i860dis.h b/src/devices/cpu/i860/i860dis.h new file mode 100644 index 00000000000..46847ba8648 --- /dev/null +++ b/src/devices/cpu/i860/i860dis.h @@ -0,0 +1,77 @@ +// license:BSD-3-Clause +// copyright-holders:Jason Eckhardt +/*************************************************************************** + + i860dis.c + + Disassembler for the Intel i860 emulator. + + Copyright (C) 1995-present Jason Eckhardt (jle@rice.edu) + +***************************************************************************/ + +#ifndef MAME_CPU_I860_I860DIS_H +#define MAME_CPU_I860_I860DIS_H + +#pragma once + +class i860_disassembler : public util::disasm_interface +{ +public: + i860_disassembler() = default; + virtual ~i860_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + /* Flags for the decode table. */ + enum + { + DEC_MORE = 1, /* More decoding necessary. */ + DEC_DECODED = 2 /* Fully decoded, go. */ + }; + + + struct decode_tbl_t + { + /* Disassembly function for this opcode. + Call with buffer, mnemonic, pc, insn. */ + void (i860_disassembler::*insn_dis)(std::ostream &, char *, uint32_t, uint32_t); + + /* Flags for this opcode. */ + char flags; + + /* Mnemonic of this opcode (sometimes partial when more decode is + done in disassembly routines-- e.g., loads and stores). */ + const char *mnemonic; + }; + + static const char *const cr2str[]; + static const decode_tbl_t decode_tbl[64]; + static const decode_tbl_t core_esc_decode_tbl[8]; + static const decode_tbl_t fp_decode_tbl[128]; + + int32_t sign_ext(uint32_t x, int n); + void int_12d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void int_i2d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void int_1d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void int_cd(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void int_1c(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void int_1(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void int_0(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void flop_12d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void flop_1d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void flop_2d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void flop_fxfr(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void int_12S(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void int_i2S(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void int_L(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void int_ldx(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void int_stx(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void int_fldst(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void int_flush(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void i860_dasm_tab_replacer(std::ostream &stream, const std::string &buf, int tab_size); +}; + +#endif diff --git a/src/devices/cpu/i960/i960.cpp b/src/devices/cpu/i960/i960.cpp index dcffb837f95..148cc1a8996 100644 --- a/src/devices/cpu/i960/i960.cpp +++ b/src/devices/cpu/i960/i960.cpp @@ -2,10 +2,9 @@ // copyright-holders:Farfetch'd, R. Belmont #include "emu.h" #include "i960.h" +#include "i960dis.h" #include "debugger.h" -CPU_DISASSEMBLE( i960 ); - #ifdef _MSC_VER /* logb prototype is different for MS Visual C */ #include <float.h> @@ -2104,7 +2103,7 @@ void i960_cpu_device::execute_set_input(int irqline, int state) void i960_cpu_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); save_item(NAME(m_IP)); save_item(NAME(m_PIP)); @@ -2209,9 +2208,7 @@ void i960_cpu_device::device_reset() m_rcache_pos = 0; } - -offs_t i960_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *i960_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( i960 ); - return CPU_DISASSEMBLE_NAME(i960)(this, stream, pc, oprom, opram, options); + return new i960_disassembler; } diff --git a/src/devices/cpu/i960/i960.h b/src/devices/cpu/i960/i960.h index 76d60109cf4..2b2b53e2729 100644 --- a/src/devices/cpu/i960/i960.h +++ b/src/devices/cpu/i960/i960.h @@ -97,9 +97,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 4; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 8; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -127,7 +125,7 @@ private: int m_immediate_pri; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; int m_icount; diff --git a/src/devices/cpu/i960/i960dis.cpp b/src/devices/cpu/i960/i960dis.cpp index 43f81015240..5f4991fc77b 100644 --- a/src/devices/cpu/i960/i960dis.cpp +++ b/src/devices/cpu/i960/i960dis.cpp @@ -7,17 +7,10 @@ */ #include "emu.h" -#include "i960.h" #include "i960dis.h" -struct mnemonic_t -{ - const char *mnem; - unsigned short type; -}; - -static const mnemonic_t mnemonic[256] = { +const i960_disassembler::mnemonic_t i960_disassembler::mnemonic[256] = { { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, // 00 { "b", 8 }, { "call", 8 }, { "ret", 9 }, { "bal", 8 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, @@ -67,7 +60,7 @@ static const mnemonic_t mnemonic[256] = { { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 } }; -static const mnemonic_t mnem_reg[100] = +const i960_disassembler::mnemonic_t i960_disassembler::mnem_reg[100] = { { "notbit", 0x580 }, { "and", 0x581 }, { "andnot", 0x582 }, { "setbit", 0x583 }, { "notand",0x584 }, { "xor", 0x586 }, { "or", 0x587 }, { "nor", 0x588 }, { "xnor",0x589 }, { "not",0x58a }, @@ -93,13 +86,13 @@ static const mnemonic_t mnem_reg[100] = { "ending_code",0 } }; -static const char *const constnames[32] = +const char *const i960_disassembler::constnames[32] = { "0x0", "0x1", "0x2", "0x3", "0x4", "0x5", "0x6", "0x7", "0x8", "0x9", "0xa", "0xb", "0xc", "0xd", "0xe", "0xf", "0x10", "0x11", "0x12", "0x13", "0x14", "0x15", "0x16", "0x17", "0x18", "0x19", "0x1a", "0x1b", "0x1c", "0x1d", "0x1e", "0x1f" }; -static const char *const regnames[32] = +const char *const i960_disassembler::regnames[32] = { "pfp","sp","rip","r3", "r4","r5","r6","r7", "r8","r9","r10","r11", "r12","r13","r14","r15", "g0","g1","g2","g3", "g4","g5","g6","g7", "g8","g9","g10","g11", "g12","g13","g14","fp", @@ -128,118 +121,120 @@ static const char *const regnames[32] = #define COBRSRC1 ((iCode >> 19) & 0x1f) #define COBRSRC2 ((iCode >> 14) & 0x1f) -static char *dis_decode_reg(unsigned long iCode, char* tmpStr,unsigned char cnt) +std::string i960_disassembler::dis_decode_reg(u32 iCode, unsigned char cnt) { - char src1[10]; - char src2[10]; - char dst[10]; + std::string src1, src2, dst; - if (S1) src1[0] = 0; + if (S1) + src1 = ""; else { - if(M1) sprintf(src1,"0x%lx",SRC1); - else sprintf(src1,"%s",regnames[SRC1]); + if(M1) + src1 = util::string_format("0x%lx", SRC1); + else + src1 = util::string_format("%s", regnames[SRC1]); } - if (S2) sprintf(src2,"reserved"); + + if (S2) + src2 = "reserved"; else { - if(M2) sprintf(src2,"0x%lx,",SRC2); - else sprintf(src2,"%s,",regnames[SRC2]); + if(M2) + src2 = util::string_format("0x%lx,", SRC2); + else + src2 = util::string_format("%s,", regnames[SRC2]); } - if(M3) dst[0] = 0; - else sprintf(dst,"%s,",regnames[DST]); + + if(M3) + dst = ""; + else + dst = util::string_format("%s,", regnames[DST]); + if (cnt == 1) - sprintf(tmpStr,"%s%s",dst,src1); + return util::string_format("%s%s", dst, src1); else - sprintf(tmpStr,"%s%s%s",dst,src2,src1); - return tmpStr; + return util::string_format("%s%s%s", dst, src2, src1); } -#define READ32(dis,offs) ((dis)->oprom[(offs) + 0] | ((dis)->oprom[(offs) + 1] << 8) | ((dis)->oprom[(offs) + 2] << 16) | ((dis)->oprom[(offs) + 3] << 24)) - -static void i960_disassemble(disassemble_t *diss) +offs_t i960_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - unsigned char op,op2; - unsigned char /*mode,*/ modeh, model; - unsigned char dst,abase,reg2; - unsigned short opc; - unsigned long iCode; - char tmpStr[256]; - long i; - - iCode = READ32(diss,0); - op = (unsigned char) (iCode >> 24); - op2 = (unsigned char) (iCode >> 7)&0xf; - - model = (unsigned char) (iCode >> 10) &0x3; - modeh = (unsigned char) (iCode >> 12) &0x3; + u32 IP = pc; + + u32 iCode = opcodes.r32(IP); + u8 op = (unsigned char) (iCode >> 24); + u8 op2 = (unsigned char) (iCode >> 7)&0xf; + u8 opc = 0; + u32 i = 0; + + u8 model = (unsigned char) (iCode >> 10) &0x3; + u8 modeh = (unsigned char) (iCode >> 12) &0x3; //mode = (unsigned char) (iCode >> 10) &0x7; - dst = (unsigned char) (iCode >> 19) &0x1f; - abase = (unsigned char) (iCode>>14)&0x1f; - reg2 = (unsigned char) (iCode)&0x1f; + u8 dst = (unsigned char) (iCode >> 19) &0x1f; + u8 abase = (unsigned char) (iCode>>14)&0x1f; + u8 reg2 = (unsigned char) (iCode)&0x1f; - diss->IPinc = 4; - diss->disflags = 0; + offs_t IPinc = 4; + offs_t disflags = 0; if (op == 0x09 || op == 0x0b || op == 0x66 || op == 0x85 || op == 0x86) - diss->disflags = DASMFLAG_STEP_OVER; + disflags = STEP_OVER; else if (op == 0x0a) - diss->disflags = DASMFLAG_STEP_OUT; + disflags = STEP_OUT; switch(mnemonic[op].type) { case 0: // not yet implemented - util::stream_format(diss->stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model); + util::stream_format(stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model); break; case 1: // memory access switch(modeh) { case 0: - util::stream_format(diss->stream, "%-8s%s,0x%lx",NEM,REG_DST, iCode&0xfff); + util::stream_format(stream, "%-8s%s,0x%lx",NEM,REG_DST, iCode&0xfff); break; case 1: switch (model) { case 0: - util::stream_format(diss->stream, "%-8s%s,(%s)",NEM,REG_DST, REG_ABASE); + util::stream_format(stream, "%-8s%s,(%s)",NEM,REG_DST, REG_ABASE); break; case 3: - util::stream_format(diss->stream, "%-8s%s,(%s)[%s*%ld]",NEM,REG_DST, REG_ABASE,REG_REG2,(iCode>>7)&0x7); + util::stream_format(stream, "%-8s%s,(%s)[%s*%ld]",NEM,REG_DST, REG_ABASE,REG_REG2,(iCode>>7)&0x7); break; default: - util::stream_format(diss->stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model); + util::stream_format(stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model); break; } break; case 2: - util::stream_format(diss->stream, "%-8s%s,0x%lx(%s)",NEM,REG_DST, iCode&0xfff,REG_ABASE); + util::stream_format(stream, "%-8s%s,0x%lx(%s)",NEM,REG_DST, iCode&0xfff,REG_ABASE); break; case 3: switch (model) { case 0: - util::stream_format(diss->stream, "%-8s%s,0x%x",NEM,REG_DST, READ32(diss,4)); - diss->IPinc = 8; + util::stream_format(stream, "%-8s%s,0x%x",NEM,REG_DST, opcodes.r32(IP + 4)); + IPinc = 8; break; case 1: - util::stream_format(diss->stream, "%-8s%s,0x%x(%s)",NEM,REG_DST, READ32(diss,4),REG_ABASE); - diss->IPinc = 8; + util::stream_format(stream, "%-8s%s,0x%x(%s)",NEM,REG_DST, opcodes.r32(IP + 4),REG_ABASE); + IPinc = 8; break; case 2: - util::stream_format(diss->stream, "%-8s%s,0x%x[%s*%ld]",NEM,REG_DST, READ32(diss,4),REG_REG2,(iCode>>7)&0x7); - diss->IPinc = 8; + util::stream_format(stream, "%-8s%s,0x%x[%s*%ld]",NEM,REG_DST, opcodes.r32(IP + 4),REG_REG2,(iCode>>7)&0x7); + IPinc = 8; break; case 3: - util::stream_format(diss->stream, "%-8s%s,0x%x(%s)[%s*%ld]",NEM,REG_DST, READ32(diss,4),REG_ABASE,REG_REG2,(iCode>>7)&0x7); - diss->IPinc = 8; + util::stream_format(stream, "%-8s%s,0x%x(%s)[%s*%ld]",NEM,REG_DST, opcodes.r32(IP + 4),REG_ABASE,REG_REG2,(iCode>>7)&0x7); + IPinc = 8; break; default: - util::stream_format(diss->stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model); + util::stream_format(stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model); break; } break; default: - util::stream_format(diss->stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model); + util::stream_format(stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model); break; } break; @@ -253,8 +248,8 @@ static void i960_disassemble(disassemble_t *diss) i++; } - if (mnem_reg[i].type == opc) util::stream_format(diss->stream, "%-8s%s", mnem_reg[i].mnem,dis_decode_reg(iCode,tmpStr,1)); - else util::stream_format(diss->stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model); + if (mnem_reg[i].type == opc) util::stream_format(stream, "%-8s%s", mnem_reg[i].mnem,dis_decode_reg(iCode,1)); + else util::stream_format(stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model); break; case 3: i = 0; @@ -266,38 +261,34 @@ static void i960_disassemble(disassemble_t *diss) i++; } - if (mnem_reg[i].type == opc) util::stream_format(diss->stream, "%-8s%s", mnem_reg[i].mnem,dis_decode_reg(iCode,tmpStr,0)); - else util::stream_format(diss->stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model); + if (mnem_reg[i].type == opc) util::stream_format(stream, "%-8s%s", mnem_reg[i].mnem,dis_decode_reg(iCode,0)); + else util::stream_format(stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model); break; case 6: // bitpos and branch type - util::stream_format(diss->stream, "%-8s%ld,%s,0x%lx",NEM, COBRSRC1, REG_COBR_SRC2,((((long)iCode&0x00fffffc)<<19)>>19) + (diss->IP)); + util::stream_format(stream, "%-8s%ld,%s,0x%lx",NEM, COBRSRC1, REG_COBR_SRC2,((((s32)iCode&0x00fffffc)<<19)>>19) + (IP)); break; case 7: // compare and branch type - util::stream_format(diss->stream, "%-8s%s,%s,0x%lx",NEM,REG_COBR_SRC1,REG_COBR_SRC2,((((long)iCode&0x00fffffc)<<19)>>19) + (diss->IP)); + util::stream_format(stream, "%-8s%s,%s,0x%lx",NEM,REG_COBR_SRC1,REG_COBR_SRC2,((((s32)iCode&0x00fffffc)<<19)>>19) + (IP)); break; case 8: // target type - util::stream_format(diss->stream, "%-8s%08lx",NEM,((((long)iCode&0x00fffffc)<<8)>>8) + (diss->IP)); + util::stream_format(stream, "%-8s%08lx",NEM,((((s32)iCode&0x00fffffc)<<8)>>8) + (IP)); break; case 9: // no operands - util::stream_format(diss->stream, "%s",NEM); + util::stream_format(stream, "%s",NEM); break; case 10: // TEST type: register only - util::stream_format(diss->stream, "%s %s", NEM, REG_DST); + util::stream_format(stream, "%s %s", NEM, REG_DST); break; default: - diss->stream << "???"; + stream << "???"; break; } -} - + return IPinc | disflags | SUPPORTED; +} -CPU_DISASSEMBLE(i960) +u32 i960_disassembler::opcode_alignment() const { - disassemble_t dis(stream, pc, oprom); - - i960_disassemble(&dis); - - return dis.IPinc | dis.disflags | DASMFLAG_SUPPORTED; + return 4; } diff --git a/src/devices/cpu/i960/i960dis.h b/src/devices/cpu/i960/i960dis.h index 94e364fd666..2bc52697648 100644 --- a/src/devices/cpu/i960/i960dis.h +++ b/src/devices/cpu/i960/i960dis.h @@ -1,18 +1,33 @@ // license:BSD-3-Clause // copyright-holders:Farfetch'd, R. Belmont -#ifndef __I960DIS_H__ -#define __I960DIS_H__ +#ifndef MAME_CPU_I960_I960DIS_H +#define MAME_CPU_I960_I960DIS_H -struct disassemble_t +#pragma once + +class i960_disassembler : public util::disasm_interface { - disassemble_t(std::ostream &s, unsigned long ip, const uint8_t *opr) - : stream(s), IP(ip), oprom(opr) { } - - std::ostream &stream; // output stream - unsigned long IP; - unsigned long IPinc; - const uint8_t *oprom; - uint32_t disflags; +public: + i960_disassembler() = default; + virtual ~i960_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + struct mnemonic_t + { + const char *mnem; + unsigned short type; + }; + + static const mnemonic_t mnemonic[256]; + static const mnemonic_t mnem_reg[100]; + static const char *const constnames[32]; + static const char *const regnames[32]; + + std::string dis_decode_reg(u32 iCode, unsigned char cnt); + }; -#endif /* __I960DIS_H__ */ +#endif diff --git a/src/devices/cpu/ie15/ie15.cpp b/src/devices/cpu/ie15/ie15.cpp index e09d99c51a8..80c0fecdbe7 100644 --- a/src/devices/cpu/ie15/ie15.cpp +++ b/src/devices/cpu/ie15/ie15.cpp @@ -2,6 +2,7 @@ // copyright-holders:Sergey Svishchev #include "emu.h" #include "ie15.h" +#include "ie15dasm.h" #include "debugger.h" @@ -48,7 +49,7 @@ void ie15_cpu_device::device_start() { // find address spaces m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); // save state @@ -149,34 +150,12 @@ void ie15_cpu_device::state_string_export(const device_state_entry &entry, std:: } //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes +// create_disassembler //------------------------------------------------- -uint32_t ie15_cpu_device::disasm_min_opcode_bytes() const +util::disasm_interface *ie15_cpu_device::create_disassembler() { - return 1; -} - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t ie15_cpu_device::disasm_max_opcode_bytes() const -{ - return 2; -} - -//------------------------------------------------- -// disasm_disassemble - call the disassembly -// helper function -//------------------------------------------------- - -offs_t ie15_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) -{ - extern CPU_DISASSEMBLE( ie15 ); - return CPU_DISASSEMBLE_NAME(ie15)(nullptr, stream, pc, oprom, opram, 0); + return new ie15_disassembler; } //************************************************************************** diff --git a/src/devices/cpu/ie15/ie15.h b/src/devices/cpu/ie15/ie15.h index 2a39a663fed..f919d81c211 100644 --- a/src/devices/cpu/ie15/ie15.h +++ b/src/devices/cpu/ie15/ie15.h @@ -44,9 +44,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void execute_one(int opcode); @@ -76,7 +74,7 @@ protected: address_space *m_program; address_space *m_io; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; }; // device type definition diff --git a/src/devices/cpu/ie15/ie15dasm.cpp b/src/devices/cpu/ie15/ie15dasm.cpp index f13e8f52e44..1318c58d6d5 100644 --- a/src/devices/cpu/ie15/ie15dasm.cpp +++ b/src/devices/cpu/ie15/ie15dasm.cpp @@ -1,34 +1,37 @@ // license:BSD-3-Clause // copyright-holders:Sergey Svishchev #include "emu.h" +#include "ie15dasm.h" -#define OP(A) oprom[(A) - PC] -#define ARG(A) opram[(A) - PC] +u32 ie15_disassembler::opcode_alignment() const +{ + return 1; +} -CPU_DISASSEMBLE(ie15) +offs_t ie15_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint32_t flags = 0; uint8_t op; unsigned PC = pc; - op = OP(pc++); + op = opcodes.r8(pc++); switch (op & 0xf0) { case 0x00: util::stream_format(stream, "add r%d", op & 0x0f); break; case 0x10: - util::stream_format(stream, "jmp $%04x", (((op & 0x0f) << 8) | ARG(pc)) + 1); + util::stream_format(stream, "jmp $%04x", (((op & 0x0f) << 8) | params.r8(pc)) + 1); pc+=1; break; case 0x20: - util::stream_format(stream, "ldc r%d, #$%02x", (op & 0x0f), ARG(pc)); + util::stream_format(stream, "ldc r%d, #$%02x", (op & 0x0f), params.r8(pc)); pc+=1; break; case 0x30: switch (op) { case 0x30: - util::stream_format(stream, "lca #$%02x", ARG(pc)); + util::stream_format(stream, "lca #$%02x", params.r8(pc)); pc+=1; break; case 0x33: @@ -123,5 +126,5 @@ CPU_DISASSEMBLE(ie15) break; } - return (pc - PC) | flags | DASMFLAG_SUPPORTED; + return (pc - PC) | flags | SUPPORTED; } diff --git a/src/devices/cpu/ie15/ie15dasm.h b/src/devices/cpu/ie15/ie15dasm.h new file mode 100644 index 00000000000..fb85a7a3d1c --- /dev/null +++ b/src/devices/cpu/ie15/ie15dasm.h @@ -0,0 +1,19 @@ +// license:BSD-3-Clause +// copyright-holders:Sergey Svishchev + +#ifndef MAME_CPU_IE15_IE15DASM_H +#define MAME_CPU_IE15_IE15DASM_H + +#pragma once + +class ie15_disassembler : public util::disasm_interface +{ +public: + ie15_disassembler() = default; + virtual ~ie15_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/jaguar/jagdasm.cpp b/src/devices/cpu/jaguar/jagdasm.cpp index 538f35b4b48..97c049594d6 100644 --- a/src/devices/cpu/jaguar/jagdasm.cpp +++ b/src/devices/cpu/jaguar/jagdasm.cpp @@ -9,27 +9,16 @@ ***************************************************************************/ #include "emu.h" -#include "jaguar.h" - - -/*************************************************************************** - MEMORY ACCESSORS -***************************************************************************/ - -#define ROPCODE(offs) ((oprom[offs] << 8) | oprom[(offs) + 1]) - +#include "jagdasm.h" /*************************************************************************** STATIC VARIABLES ***************************************************************************/ -static constexpr unsigned JAGUAR_VARIANT_GPU = 0; -static constexpr unsigned JAGUAR_VARIANT_DSP = 1; - -static const uint8_t convert_zero[32] = +const uint8_t jaguar_disassembler::convert_zero[32] = { 32,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 }; -static const char *const condition[32] = +const char *const jaguar_disassembler::condition[32] = { "", "nz,", @@ -72,20 +61,18 @@ static const char *const condition[32] = CODE CODE ***************************************************************************/ -static inline char *signed_16bit(int16_t val) +std::string jaguar_disassembler::signed_16bit(int16_t val) { - static char temp[10]; if (val < 0) - sprintf(temp, "-$%x", -val); + return util::string_format("-$%x", -val); else - sprintf(temp, "$%x", val); - return temp; + return util::string_format("$%x", val); } -static unsigned dasmjag(int variant, std::ostream &stream, unsigned pc, const uint8_t *oprom) +offs_t jaguar_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint32_t flags = 0; - int op = ROPCODE(0); + int op = opcodes.r16(pc); int reg1 = (op >> 5) & 31; int reg2 = op & 31; int size = 2; @@ -126,12 +113,12 @@ static unsigned dasmjag(int variant, std::ostream &stream, unsigned pc, const ui case 30: util::stream_format(stream, "cmp r%d,r%d", reg1, reg2); break; case 31: util::stream_format(stream, "cmpq %s,r%d", signed_16bit((int16_t)(reg1 << 11) >> 11), reg2);break; - case 32: if (variant == JAGUAR_VARIANT_GPU) + case 32: if (m_variant == JAGUAR_VARIANT_GPU) util::stream_format(stream, "sat8 r%d", reg2); else util::stream_format(stream, "subqmod $%x,r%d", convert_zero[reg1], reg2); break; - case 33: if (variant == JAGUAR_VARIANT_GPU) + case 33: if (m_variant == JAGUAR_VARIANT_GPU) util::stream_format(stream, "sat16 r%d", reg2); else util::stream_format(stream, "sat16s r%d", reg2); @@ -140,11 +127,11 @@ static unsigned dasmjag(int variant, std::ostream &stream, unsigned pc, const ui case 35: util::stream_format(stream, "moveq %d,r%d", reg1, reg2); break; case 36: util::stream_format(stream, "moveta r%d,r%d", reg1, reg2); break; case 37: util::stream_format(stream, "movefa r%d,r%d", reg1, reg2); break; - case 38: util::stream_format(stream, "movei $%x,r%d", ROPCODE(2) | (ROPCODE(4)<<16), reg2); size = 6; break; + case 38: util::stream_format(stream, "movei $%x,r%d", opcodes.r32(pc+2), reg2); size = 6; break; case 39: util::stream_format(stream, "loadb (r%d),r%d", reg1, reg2); break; case 40: util::stream_format(stream, "loadw (r%d),r%d", reg1, reg2); break; case 41: util::stream_format(stream, "load (r%d),r%d", reg1, reg2); break; - case 42: if (variant == JAGUAR_VARIANT_GPU) + case 42: if (m_variant == JAGUAR_VARIANT_GPU) util::stream_format(stream, "loadp (r%d),r%d", reg1, reg2); else util::stream_format(stream, "sat32s r%d", reg2); @@ -154,7 +141,7 @@ static unsigned dasmjag(int variant, std::ostream &stream, unsigned pc, const ui case 45: util::stream_format(stream, "storeb r%d,(r%d)", reg2, reg1); break; case 46: util::stream_format(stream, "storew r%d,(r%d)", reg2, reg1); break; case 47: util::stream_format(stream, "store r%d,(r%d)", reg2, reg1); break; - case 48: if (variant == JAGUAR_VARIANT_GPU) + case 48: if (m_variant == JAGUAR_VARIANT_GPU) util::stream_format(stream, "storep r%d,(r%d)", reg2, reg1); else util::stream_format(stream, "mirror r%d", reg2); @@ -172,12 +159,12 @@ static unsigned dasmjag(int variant, std::ostream &stream, unsigned pc, const ui case 59: util::stream_format(stream, "load (r15+r%d),r%d", reg1, reg2); break; case 60: util::stream_format(stream, "store r%d,(r14+r%d)", reg2, reg1); break; case 61: util::stream_format(stream, "store r%d,(r15+r%d)", reg2, reg1); break; - case 62: if (variant == JAGUAR_VARIANT_GPU) + case 62: if (m_variant == JAGUAR_VARIANT_GPU) util::stream_format(stream, "sat24 r%d", reg2); else util::stream_format(stream, "illegal"); break; - case 63: if (variant == JAGUAR_VARIANT_GPU) + case 63: if (m_variant == JAGUAR_VARIANT_GPU) util::stream_format(stream, reg1 ? "unpack r%d" : "pack r%d", reg2); @@ -186,15 +173,14 @@ static unsigned dasmjag(int variant, std::ostream &stream, unsigned pc, const ui break; } - return size | flags | DASMFLAG_SUPPORTED; + return size | flags | SUPPORTED; } -CPU_DISASSEMBLE( jaguargpu ) +jaguar_disassembler::jaguar_disassembler(u32 variant) : m_variant(variant) { - return dasmjag(JAGUAR_VARIANT_GPU, stream, pc, oprom); } -CPU_DISASSEMBLE( jaguardsp ) +uint32_t jaguar_disassembler::opcode_alignment() const { - return dasmjag(JAGUAR_VARIANT_DSP, stream, pc, oprom); + return 2; } diff --git a/src/devices/cpu/jaguar/jagdasm.h b/src/devices/cpu/jaguar/jagdasm.h new file mode 100644 index 00000000000..232fda13b1f --- /dev/null +++ b/src/devices/cpu/jaguar/jagdasm.h @@ -0,0 +1,37 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +/*************************************************************************** + + jagdasm.c + Disassembler for the portable Jaguar DSP emulator. + Written by Aaron Giles + +***************************************************************************/ + +#ifndef MAME_CPU_JAGUAR_JAGDASM_H +#define MAME_CPU_JAGUAR_JAGDASM_H + +#pragma once + +class jaguar_disassembler : public util::disasm_interface +{ +public: + static constexpr unsigned JAGUAR_VARIANT_GPU = 0; + static constexpr unsigned JAGUAR_VARIANT_DSP = 1; + + jaguar_disassembler(u32 variant); + virtual ~jaguar_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const uint8_t convert_zero[32]; + static const char *const condition[32]; + + u32 m_variant; + + static std::string signed_16bit(int16_t val); +}; + +#endif diff --git a/src/devices/cpu/jaguar/jaguar.cpp b/src/devices/cpu/jaguar/jaguar.cpp index 3b52ae1bfcc..b38f2c1fe97 100644 --- a/src/devices/cpu/jaguar/jaguar.cpp +++ b/src/devices/cpu/jaguar/jaguar.cpp @@ -11,6 +11,7 @@ #include "emu.h" #include "debugger.h" #include "jaguar.h" +#include "jagdasm.h" #define LOG_GPU_IO 0 @@ -337,7 +338,7 @@ void jaguar_cpu_device::device_start() init_tables(); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_cpu_interrupt.resolve_safe(); save_item(NAME(m_r)); @@ -1436,16 +1437,12 @@ WRITE32_MEMBER( jaguardsp_cpu_device::ctrl_w ) } } - -offs_t jaguargpu_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *jaguargpu_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( jaguargpu ); - return CPU_DISASSEMBLE_NAME(jaguargpu)(this, stream, pc, oprom, opram, options); + return new jaguar_disassembler(jaguar_disassembler::JAGUAR_VARIANT_GPU); } - -offs_t jaguardsp_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *jaguardsp_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( jaguardsp ); - return CPU_DISASSEMBLE_NAME(jaguardsp)(this, stream, pc, oprom, opram, options); + return new jaguar_disassembler(jaguar_disassembler::JAGUAR_VARIANT_DSP); } diff --git a/src/devices/cpu/jaguar/jaguar.h b/src/devices/cpu/jaguar/jaguar.h index 1bc5ddf8d64..ac7f406621d 100644 --- a/src/devices/cpu/jaguar/jaguar.h +++ b/src/devices/cpu/jaguar/jaguar.h @@ -120,10 +120,6 @@ protected: // device_state_interface overrides virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; - // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 6; } - address_space_config m_program_config; /* core registers */ @@ -143,7 +139,7 @@ protected: int m_bankswitch_icount; devcb_write_line m_cpu_interrupt; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; uint32_t m_internal_ram_start; uint32_t m_internal_ram_end; @@ -249,7 +245,7 @@ public: protected: virtual void execute_run() override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; }; @@ -266,7 +262,7 @@ protected: virtual uint32_t execute_input_lines() const override { return 6; } virtual void execute_run() override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; }; diff --git a/src/devices/cpu/lc8670/lc8670.cpp b/src/devices/cpu/lc8670/lc8670.cpp index c78a0acd4c8..34078ecb994 100644 --- a/src/devices/cpu/lc8670/lc8670.cpp +++ b/src/devices/cpu/lc8670/lc8670.cpp @@ -18,6 +18,7 @@ #include "emu.h" #include "debugger.h" #include "lc8670.h" +#include "lc8670dsm.h" //*************************************************************************** // DEBUGGING @@ -194,7 +195,7 @@ void lc8670_cpu_device::device_start() m_program = &space(AS_PROGRAM); m_data = &space(AS_DATA); m_io = &space(AS_IO); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); // set our instruction counter m_icountptr = &m_icount; @@ -1777,3 +1778,8 @@ int lc8670_cpu_device::op_xor() return 1; } + +util::disasm_interface *lc8670_cpu_device::create_disassembler() +{ + return new lc8670_disassembler; +} diff --git a/src/devices/cpu/lc8670/lc8670.h b/src/devices/cpu/lc8670/lc8670.h index a6de4f7c98a..c0fddecb60b 100644 --- a/src/devices/cpu/lc8670/lc8670.h +++ b/src/devices/cpu/lc8670/lc8670.h @@ -115,9 +115,7 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 4; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: // helpers @@ -142,7 +140,6 @@ private: void timer0_tick(bool ext_line = false); void timer1_tick(); void base_timer_tick(); - static void dasm_arg(uint8_t op, char *buffer, offs_t pc, int arg, const uint8_t *oprom, int &pos); // opcodes handlers int op_nop(); @@ -200,7 +197,7 @@ private: address_space * m_program; // program space (ROM or flash) address_space * m_data; // internal RAM/register address_space * m_io; // I/O ports - direct_read_data * m_direct; + direct_read_data<0> *m_direct; // timers static const device_timer_id BASE_TIMER = 1; @@ -240,33 +237,6 @@ private: // opcodes table typedef int (lc8670_cpu_device::*op_handler)(); static const op_handler s_opcode_table[80]; - - // disassembler - enum - { - OP_NULL, - OP_R8, - OP_R8RI, - OP_R16, - OP_RI, - OP_A12, - OP_A16, - OP_I8, - OP_B3, - OP_D9, - OP_D9B3, - OP_RII8 - }; - - // disasm table - struct dasm_entry - { - const char *str; - uint8_t arg1; - uint8_t arg2; - bool inv; - }; - static const dasm_entry s_dasm_table[80]; }; DECLARE_DEVICE_TYPE(LC8670, lc8670_cpu_device) diff --git a/src/devices/cpu/lc8670/lc8670dsm.cpp b/src/devices/cpu/lc8670/lc8670dsm.cpp index d1a223fc3a8..540b4d55377 100644 --- a/src/devices/cpu/lc8670/lc8670dsm.cpp +++ b/src/devices/cpu/lc8670/lc8670dsm.cpp @@ -7,10 +7,14 @@ ******************************************************************************/ #include "emu.h" -#include "debugger.h" -#include "lc8670.h" +#include "lc8670dsm.h" -const lc8670_cpu_device::dasm_entry lc8670_cpu_device::s_dasm_table[] = +u32 lc8670_disassembler::opcode_alignment() const +{ + return 1; +} + +const lc8670_disassembler::dasm_entry lc8670_disassembler::s_dasm_table[] = { { "NOP" , OP_NULL, OP_NULL, 0 }, // 0x0* { "BR" , OP_R8 , OP_NULL, 0 }, @@ -94,7 +98,7 @@ const lc8670_cpu_device::dasm_entry lc8670_cpu_device::s_dasm_table[] = { "SET1", OP_D9B3, OP_NULL, 0 }, }; -void lc8670_cpu_device::dasm_arg(uint8_t op, char *buffer, offs_t pc, int arg, const uint8_t *oprom, int &pos) +void lc8670_disassembler::dasm_arg(uint8_t op, char *buffer, offs_t pc, int arg, const data_buffer &opcodes, offs_t &pos) { switch( arg ) { @@ -105,71 +109,88 @@ void lc8670_cpu_device::dasm_arg(uint8_t op, char *buffer, offs_t pc, int arg, c pc++; // fall through case OP_R8RI: - buffer += sprintf(buffer, "%04x", (pc + 1 + oprom[pos] - (oprom[pos]&0x80 ? 0x100 : 0)) & 0xffff); + buffer += sprintf(buffer, "%04x", (pc + 1 + opcodes.r8(pos) - (opcodes.r8(pos)&0x80 ? 0x100 : 0)) & 0xffff); pos++; break; case OP_R16: - buffer += sprintf(buffer, "%04x", (pc + 2 + ((oprom[pos+1]<<8) | oprom[pos])) & 0xffff); + buffer += sprintf(buffer, "%04x", (pc + 2 + ((opcodes.r8(pos+1)<<8) | opcodes.r8(pos))) & 0xffff); pos += 2; break; case OP_RI: buffer += sprintf(buffer, "@%x", op & 0x03); break; case OP_A12: - buffer += sprintf(buffer, "%04x", ((pc + 2) & 0xf000) | ((op & 0x10)<<7) | ((op & 0x07)<<8) | oprom[pos]); + buffer += sprintf(buffer, "%04x", ((pc + 2) & 0xf000) | ((op & 0x10)<<7) | ((op & 0x07)<<8) | opcodes.r8(pos)); pos++; break; case OP_A16: - buffer += sprintf(buffer, "%04x", (oprom[pos]<<8) | oprom[pos+1]); + buffer += sprintf(buffer, "%04x", (opcodes.r8(pos)<<8) | opcodes.r8(pos+1)); pos += 2; break; case OP_I8: - buffer += sprintf(buffer, "#$%02x", oprom[pos++]); + buffer += sprintf(buffer, "#$%02x", opcodes.r8(pos++)); break; case OP_B3: buffer += sprintf(buffer, "%x", op & 0x07); break; case OP_D9: - buffer += sprintf(buffer, "($%03x)", ((op & 0x01)<<8) | oprom[pos]); + buffer += sprintf(buffer, "($%03x)", ((op & 0x01)<<8) | opcodes.r8(pos)); pos++; break; case OP_D9B3: - buffer += sprintf(buffer, "($%03x)", ((op & 0x10)<<4) | oprom[pos]); + buffer += sprintf(buffer, "($%03x)", ((op & 0x10)<<4) | opcodes.r8(pos)); buffer += sprintf(buffer, ",%x", op & 0x07); pos++; break; case OP_RII8: buffer += sprintf(buffer, "@%x", op & 0x03); - buffer += sprintf(buffer, ",#$%02x", oprom[pos]); + buffer += sprintf(buffer, ",#$%02x", opcodes.r8(pos)); pos++; break; } } //------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t lc8670_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +offs_t lc8670_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - int pos = 0; + offs_t pos = pc; char arg1[16], arg2[16]; - uint8_t op = oprom[pos++]; + uint8_t op = opcodes.r8(pos); + + int idx; + switch (op & 0x0f) + { + case 0: case 1: + idx = op & 0x0f; + break; + case 2: case 3: + idx = 2; + break; + case 4: case 5: case 6: case 7: + idx = 3; + break; + default: + idx = 4; + break; + } - int op_idx = decode_op(op); + int op_idx = ((op>>4) & 0x0f) * 5 + idx; const dasm_entry *inst = &s_dasm_table[op_idx]; util::stream_format(stream, "%-8s", inst->str); - dasm_arg(op, inst->inv ? arg2 : arg1, pc+0, inst->arg1, oprom, pos); - dasm_arg(op, inst->inv ? arg1 : arg2, pc+1, inst->arg2, oprom, pos); + dasm_arg(op, inst->inv ? arg2 : arg1, pc+0, inst->arg1, opcodes, pos); + dasm_arg(op, inst->inv ? arg1 : arg2, pc+1, inst->arg2, opcodes, pos); stream << arg1; if (inst->arg2 != OP_NULL) stream << "," << arg2; - return pos; + return pos - pc; } diff --git a/src/devices/cpu/lc8670/lc8670dsm.h b/src/devices/cpu/lc8670/lc8670dsm.h new file mode 100644 index 00000000000..c59da2add6d --- /dev/null +++ b/src/devices/cpu/lc8670/lc8670dsm.h @@ -0,0 +1,54 @@ +// license:BSD-3-Clause +// copyright-holders:Sandro Ronco +/****************************************************************************** + + Sanyo LC8670 disassembler + +******************************************************************************/ + +#ifndef MAME_CPU_LC8670_LC8670DSM_H +#define MAME_CPU_LC8670_LC8670DSM_H + +#pragma once + +class lc8670_disassembler : public util::disasm_interface +{ +public: + lc8670_disassembler() = default; + virtual ~lc8670_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + // disassembler + enum + { + OP_NULL, + OP_R8, + OP_R8RI, + OP_R16, + OP_RI, + OP_A12, + OP_A16, + OP_I8, + OP_B3, + OP_D9, + OP_D9B3, + OP_RII8 + }; + + // disasm table + struct dasm_entry + { + const char *str; + uint8_t arg1; + uint8_t arg2; + bool inv; + }; + static const dasm_entry s_dasm_table[80]; + + void dasm_arg(uint8_t op, char *buffer, offs_t pc, int arg, const data_buffer &opcodes, offs_t &pos); +}; + +#endif diff --git a/src/devices/cpu/lh5801/5801dasm.cpp b/src/devices/cpu/lh5801/5801dasm.cpp index 2cf6f105b8d..f289f4760a0 100644 --- a/src/devices/cpu/lh5801/5801dasm.cpp +++ b/src/devices/cpu/lh5801/5801dasm.cpp @@ -9,104 +9,14 @@ *****************************************************************************/ #include "emu.h" -#include "debugger.h" - -#include "lh5801.h" +#include "5801dasm.h" #if defined(SEC) #undef SEC #endif -namespace { - -class Entry -{ -public: - enum Ins - { - ILL, ILL2, PREFD, NOP, - - LDA, STA, LDI, LDX, STX, - LDE, SDE, LIN, SIN, - TIN, // (x++)->(y++) - ADC, ADI, ADR, SBC, SBI, - DCA, DCS, // bcd add and sub - CPA, CPI, CIN, // A compared with (x++) - AND, ANI, ORA, ORI, EOR, EAI, BIT, BII, - INC, DEC, - DRL, DRR, // digit rotates - ROL, ROR, - SHL, SHR, - AEX, // A nibble swap - - BCR, BCS, BHR, BHS, BZR, BZS, BVR, BVS, - BCH, LOP, // loop with ul - JMP, SJP, RTN, RTI, HLT, - VCR, VCS, VHR, VHS, VVS, VZR, VZS, - VMJ, VEJ, - PSH, POP, ATT, TTA, - REC, SEC, RIE, SIE, - - AM0, AM1, // load timer reg - ITA, // reads input port - ATP, // akku send to data bus - CDV, // clears internal divider - OFF, // clears bf flip flop - RDP, SDP,// reset display flip flop - RPU, SPU,// flip flop pu off - RPV, SPV // flip flop pv off - }; - - enum Adr - { - Imp, - Reg, - Vec, // imm byte (vector at 0xffxx) - Vej, - Imm, - RegImm, - Imm16, - RegImm16, - ME0, - ME0Imm, - Abs, - AbsImm, - ME1, - ME1Imm, - ME1Abs, - ME1AbsImm, - RelP, - RelM - }; - - enum Regs - { - RegNone, - A, - XL, XH, X, - YL, YH, Y, - UL, UH, U, - P, S - }; - const char *ins_name() const { return ins_names[ins]; } - const char *reg_name() const { return reg_names[reg]; } - - Ins ins; - Adr adr; - Regs reg; - - static const Entry table[0x100]; - static const Entry table_fd[0x100]; - -protected: - Entry(Ins i, Adr a = Imp, Regs r = RegNone) : ins(i), adr(a), reg(r) { } - - static const char *const ins_names[]; - static const char *const reg_names[]; -}; - -const char *const Entry::ins_names[]={ +const char *const lh5801_disassembler::ins_names[]={ "ILL", "ILL", nullptr, "NOP", "LDA", "STA", "LDI", "LDX", "STX", "LDE", "SDE", "LIN", "SIN", @@ -138,11 +48,11 @@ const char *const Entry::ins_names[]={ "RPV", "SPV", }; -const char *const Entry::reg_names[]= { +const char *const lh5801_disassembler::reg_names[]= { nullptr, "A", "XL", "XH", "X", "YL", "YH", "Y", "UL", "UH", "U", "P", "S" }; -const Entry Entry::table[0x100]={ +const lh5801_disassembler::Entry lh5801_disassembler::table[0x100]={ { SBC, Reg, XL }, // 0 { SBC, ME0, X }, { ADC, Reg, XL }, @@ -401,7 +311,7 @@ const Entry Entry::table[0x100]={ { ILL } }; -const Entry Entry::table_fd[0x100]={ +const lh5801_disassembler::Entry lh5801_disassembler::table_fd[0x100]={ { ILL2 }, // 0x00 { SBC, ME1, X }, { ILL2 }, @@ -660,90 +570,93 @@ const Entry Entry::table_fd[0x100]={ { ILL2 } }; -} // anonymous namespace +u32 lh5801_disassembler::opcode_alignment() const +{ + return 1; +} -CPU_DISASSEMBLE(lh5801) +offs_t lh5801_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - int pos = 0; + offs_t pos = pc; int oper; uint16_t absolut; const Entry *entry; int temp; - oper=oprom[pos++]; - entry=Entry::table+oper; + oper=opcodes.r8(pos++); + entry=table+oper; - if (Entry::table[oper].ins==Entry::PREFD) { - oper=oprom[pos++]; - entry=Entry::table_fd+oper; + if (table[oper].ins==PREFD) { + oper=opcodes.r8(pos++); + entry=table_fd+oper; } switch (entry->ins) { - case Entry::ILL: + case ILL: util::stream_format(stream, "%s %02x", entry->ins_name(), oper);break; - case Entry::ILL2: + case ILL2: util::stream_format(stream, "%s fd%02x", entry->ins_name(), oper);break; default: switch(entry->adr) { - case Entry::Imp: + case Imp: util::stream_format(stream, "%s", entry->ins_name());break; - case Entry::Reg: + case Reg: util::stream_format(stream, "%s %s", entry->ins_name(),entry->reg_name());break; - case Entry::RegImm: + case RegImm: util::stream_format(stream, "%s %s,%02x", entry->ins_name(), - entry->reg_name(), oprom[pos++]); + entry->reg_name(), opcodes.r8(pos++)); break; - case Entry::RegImm16: - absolut=oprom[pos++]<<8; - absolut|=oprom[pos++]; + case RegImm16: + absolut=opcodes.r8(pos++)<<8; + absolut|=opcodes.r8(pos++); util::stream_format(stream, "%s %s,%04x", entry->ins_name(),entry->reg_name(),absolut ); break; - case Entry::Vec: - util::stream_format(stream, "%s (ff%02x)", entry->ins_name(),oprom[pos++]);break; - case Entry::Vej: + case Vec: + util::stream_format(stream, "%s (ff%02x)", entry->ins_name(),opcodes.r8(pos++));break; + case Vej: util::stream_format(stream, "%s (ff%02x)", entry->ins_name(), oper);break; - case Entry::Imm: - util::stream_format(stream, "%s %02x", entry->ins_name(),oprom[pos++]);break; - case Entry::Imm16: - absolut=oprom[pos++]<<8; - absolut|=oprom[pos++]; + case Imm: + util::stream_format(stream, "%s %02x", entry->ins_name(),opcodes.r8(pos++));break; + case Imm16: + absolut=opcodes.r8(pos++)<<8; + absolut|=opcodes.r8(pos++); util::stream_format(stream, "%s %04x", entry->ins_name(),absolut);break; - case Entry::RelP: - temp=oprom[pos++]; + case RelP: + temp=opcodes.r8(pos++); util::stream_format(stream, "%s %04x", entry->ins_name(),pc+pos+temp);break; - case Entry::RelM: - temp=oprom[pos++]; + case RelM: + temp=opcodes.r8(pos++); util::stream_format(stream, "%s %04x", entry->ins_name(),pc+pos-temp);break; - case Entry::Abs: - absolut=oprom[pos++]<<8; - absolut|=oprom[pos++]; + case Abs: + absolut=opcodes.r8(pos++)<<8; + absolut|=opcodes.r8(pos++); util::stream_format(stream, "%s (%04x)", entry->ins_name(),absolut);break; - case Entry::ME1Abs: - absolut=oprom[pos++]<<8; - absolut|=oprom[pos++]; + case ME1Abs: + absolut=opcodes.r8(pos++)<<8; + absolut|=opcodes.r8(pos++); util::stream_format(stream, "%s #(%04x)", entry->ins_name(),absolut);break; - case Entry::AbsImm: - absolut=oprom[pos++]<<8; - absolut|=oprom[pos++]; + case AbsImm: + absolut=opcodes.r8(pos++)<<8; + absolut|=opcodes.r8(pos++); util::stream_format(stream, "%s (%04x),%02x", entry->ins_name(),absolut, - oprom[pos++]);break; - case Entry::ME1AbsImm: - absolut=oprom[pos++]<<8; - absolut|=oprom[pos++]; + opcodes.r8(pos++));break; + case ME1AbsImm: + absolut=opcodes.r8(pos++)<<8; + absolut|=opcodes.r8(pos++); util::stream_format(stream, "%s #(%04x),%02x", entry->ins_name(),absolut, - oprom[pos++]);break; - case Entry::ME0: + opcodes.r8(pos++));break; + case ME0: util::stream_format(stream, "%s (%s)", entry->ins_name(),entry->reg_name());break; - case Entry::ME0Imm: - util::stream_format(stream, "%s (%s),%02x", entry->ins_name(),entry->reg_name(),oprom[pos++]); + case ME0Imm: + util::stream_format(stream, "%s (%s),%02x", entry->ins_name(),entry->reg_name(),opcodes.r8(pos++)); break; - case Entry::ME1: + case ME1: util::stream_format(stream, "%s #(%s)", entry->ins_name(),entry->reg_name());break; - case Entry::ME1Imm: - util::stream_format(stream, "%s #(%s),%02x", entry->ins_name(),entry->reg_name(),oprom[pos++]); + case ME1Imm: + util::stream_format(stream, "%s #(%s),%02x", entry->ins_name(),entry->reg_name(),opcodes.r8(pos++)); break; } } - return pos; + return pos - pc; } diff --git a/src/devices/cpu/lh5801/5801dasm.h b/src/devices/cpu/lh5801/5801dasm.h new file mode 100644 index 00000000000..9a6b66b0c5b --- /dev/null +++ b/src/devices/cpu/lh5801/5801dasm.h @@ -0,0 +1,110 @@ +// license:BSD-3-Clause +// copyright-holders:Peter Trauner +/***************************************************************************** + * + * disasm.c + * portable lh5801 emulator interface + * + * + *****************************************************************************/ + +#ifndef MAME_CPU_LH5801_5801DASM_H +#define MAME_CPU_LH5801_5801DASM_H + +#pragma once + +class lh5801_disassembler : public util::disasm_interface +{ +public: + lh5801_disassembler() = default; + virtual ~lh5801_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum Ins + { + ILL, ILL2, PREFD, NOP, + + LDA, STA, LDI, LDX, STX, + LDE, SDE, LIN, SIN, + TIN, // (x++)->(y++) + ADC, ADI, ADR, SBC, SBI, + DCA, DCS, // bcd add and sub + CPA, CPI, CIN, // A compared with (x++) + AND, ANI, ORA, ORI, EOR, EAI, BIT, BII, + INC, DEC, + DRL, DRR, // digit rotates + ROL, ROR, + SHL, SHR, + AEX, // A nibble swap + + BCR, BCS, BHR, BHS, BZR, BZS, BVR, BVS, + BCH, LOP, // loop with ul + JMP, SJP, RTN, RTI, HLT, + VCR, VCS, VHR, VHS, VVS, VZR, VZS, + VMJ, VEJ, + PSH, POP, ATT, TTA, + REC, SEC, RIE, SIE, + + AM0, AM1, // load timer reg + ITA, // reads input port + ATP, // akku send to data bus + CDV, // clears internal divider + OFF, // clears bf flip flop + RDP, SDP,// reset display flip flop + RPU, SPU,// flip flop pu off + RPV, SPV // flip flop pv off + }; + + enum Adr + { + Imp, + Reg, + Vec, // imm byte (vector at 0xffxx) + Vej, + Imm, + RegImm, + Imm16, + RegImm16, + ME0, + ME0Imm, + Abs, + AbsImm, + ME1, + ME1Imm, + ME1Abs, + ME1AbsImm, + RelP, + RelM + }; + + enum Regs + { + RegNone, + A, + XL, XH, X, + YL, YH, Y, + UL, UH, U, + P, S + }; + + struct Entry { + Ins ins; + Adr adr; + Regs reg; + + const char *ins_name() const { return ins_names[ins]; } + const char *reg_name() const { return reg_names[reg]; } + Entry(Ins i, Adr a = Imp, Regs r = RegNone) : ins(i), adr(a), reg(r) { } + }; + + static const char *const ins_names[]; + static const char *const reg_names[]; + + static const Entry table[0x100]; + static const Entry table_fd[0x100]; +}; + +#endif diff --git a/src/devices/cpu/lh5801/lh5801.cpp b/src/devices/cpu/lh5801/lh5801.cpp index 2b4a3708e44..6ba677d1e17 100644 --- a/src/devices/cpu/lh5801/lh5801.cpp +++ b/src/devices/cpu/lh5801/lh5801.cpp @@ -16,6 +16,7 @@ #include "emu.h" #include "lh5801.h" +#include "5801dasm.h" #include "debugger.h" @@ -91,7 +92,7 @@ void lh5801_cpu_device::device_start() { m_program = &space(AS_PROGRAM); m_io = &space(AS_IO); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_in_func.resolve_safe(0); @@ -256,8 +257,7 @@ void lh5801_cpu_device::execute_set_input(int irqline, int state) } } -offs_t lh5801_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *lh5801_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( lh5801 ); - return CPU_DISASSEMBLE_NAME(lh5801)(this, stream, pc, oprom, opram, options); + return new lh5801_disassembler; } diff --git a/src/devices/cpu/lh5801/lh5801.h b/src/devices/cpu/lh5801/lh5801.h index bc9ce08cdd6..2981bda7d0f 100644 --- a/src/devices/cpu/lh5801/lh5801.h +++ b/src/devices/cpu/lh5801/lh5801.h @@ -93,9 +93,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 5; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -105,7 +103,7 @@ private: address_space *m_program; //ME0 address_space *m_io; //ME1 - direct_read_data *m_direct; + direct_read_data<0> *m_direct; PAIR m_s; PAIR m_p; diff --git a/src/devices/cpu/lr35902/lr35902.cpp b/src/devices/cpu/lr35902/lr35902.cpp index cab2e820802..95a20eeaaf3 100644 --- a/src/devices/cpu/lr35902/lr35902.cpp +++ b/src/devices/cpu/lr35902/lr35902.cpp @@ -41,6 +41,7 @@ #include "emu.h" #include "lr35902.h" +#include "lr35902d.h" #include "debugger.h" /* Flag bit definitions */ @@ -231,14 +232,11 @@ void lr35902_cpu_device::device_reset() m_entering_halt = false; } - -offs_t lr35902_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *lr35902_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( lr35902 ); - return CPU_DISASSEMBLE_NAME(lr35902)(this, stream, pc, oprom, opram, options); + return new lr35902_disassembler; } - void lr35902_cpu_device::check_interrupts() { uint8_t irq = m_IE & m_IF; diff --git a/src/devices/cpu/lr35902/lr35902.h b/src/devices/cpu/lr35902/lr35902.h index 9364599be27..0d33bbbe548 100644 --- a/src/devices/cpu/lr35902/lr35902.h +++ b/src/devices/cpu/lr35902/lr35902.h @@ -89,9 +89,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 4; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; inline void cycles_passed(uint8_t cycles); inline uint8_t mem_read_byte(uint16_t addr); diff --git a/src/devices/cpu/lr35902/lr35902d.cpp b/src/devices/cpu/lr35902/lr35902d.cpp index a723cac408d..5b27f37778e 100644 --- a/src/devices/cpu/lr35902/lr35902d.cpp +++ b/src/devices/cpu/lr35902/lr35902d.cpp @@ -8,21 +8,9 @@ *****************************************************************************/ #include "emu.h" -#include "debugger.h" -#include "lr35902.h" +#include "lr35902d.h" -enum e_mnemonics -{ - zADC, zADD, zAND, zBIT, zCALL, zCCF, zCP, - zCPL, zDAA, zDB, zDEC, zDI, zEI, zHLT, - zIN, zINC, zJP, zJR, zLD, zNOP, zOR, - zPOP, zPUSH, zRES, zRET, zRETI, zRL, zRLA, - zRLC, zRLCA, zRR, zRRA, zRRC, zRRCA, zRST, - zSBC, zSCF, zSET, zSLA, zSLL, zSRA, zSRL, - zSTOP, zSUB, zXOR, zSWAP -}; - -static const char *const s_mnemonic[] = +const char *const lr35902_disassembler::s_mnemonic[] = { "adc", "add", "and", "bit", "call","ccf", "cp", "cpl", "daa", "db", "dec", "di", "ei", "halt", @@ -33,26 +21,17 @@ static const char *const s_mnemonic[] = "stop","sub", "xor", "swap" }; -#define _OVER DASMFLAG_STEP_OVER -#define _OUT DASMFLAG_STEP_OUT - -static const uint32_t s_flags[] = { - 0 ,0 ,0 ,0 ,_OVER,0 ,0 , - 0 ,0 ,0 ,0 ,0 ,0 ,_OVER, - 0 ,0 ,0 ,0 ,0 ,0 ,0 , - 0 ,0 ,0 ,_OUT ,_OUT ,0 ,0 , - 0 ,0 ,0 ,0 ,0 ,0 ,_OVER, - 0 ,0 ,0 ,0 ,0 ,0 ,0 , - _OVER,0 ,0 ,0 -}; - -struct lr35902dasm -{ - uint8_t mnemonic; - const char *arguments; +const uint32_t lr35902_disassembler::s_flags[] = { + 0 ,0 ,0 ,0 ,STEP_OVER,0 ,0 , + 0 ,0 ,0 ,0 ,0 ,0 ,STEP_OVER, + 0 ,0 ,0 ,0 ,0 ,0 ,0 , + 0 ,0 ,0 ,STEP_OUT ,STEP_OUT ,0 ,0 , + 0 ,0 ,0 ,0 ,0 ,0 ,STEP_OVER, + 0 ,0 ,0 ,0 ,0 ,0 ,0 , + STEP_OVER,0 ,0 ,0 }; -static const lr35902dasm mnemonic_cb[256] = { +const lr35902_disassembler::lr35902dasm lr35902_disassembler::mnemonic_cb[256] = { {zRLC,"b"}, {zRLC,"c"}, {zRLC,"d"}, {zRLC,"e"}, {zRLC,"h"}, {zRLC,"l"}, {zRLC,"(hl)"}, {zRLC,"a"}, {zRRC,"b"}, {zRRC,"c"}, {zRRC,"d"}, {zRRC,"e"}, @@ -119,7 +98,7 @@ static const lr35902dasm mnemonic_cb[256] = { {zSET,"7,h"}, {zSET,"7,l"}, {zSET,"7,(hl)"},{zSET,"7,a"} }; -static const lr35902dasm mnemonic_main[256]= { +const lr35902_disassembler::lr35902dasm lr35902_disassembler::mnemonic_main[256]= { {zNOP,nullptr}, {zLD,"bc,N"}, {zLD,"(bc),a"}, {zINC,"bc"}, {zINC,"b"}, {zDEC,"b"}, {zLD,"b,B"}, {zRLCA,nullptr}, {zLD,"(W),sp"}, {zADD,"hl,bc"}, {zLD,"a,(bc)"}, {zDEC,"bc"}, @@ -186,11 +165,16 @@ static const lr35902dasm mnemonic_main[256]= { {zDB,"fc"}, {zDB,"fd"}, {zCP,"B"}, {zRST,"V"} }; +u32 lr35902_disassembler::opcode_alignment() const +{ + return 1; +} + /**************************************************************************** * Disassemble opcode at PC and return number of bytes it takes ****************************************************************************/ -CPU_DISASSEMBLE(lr35902) +offs_t lr35902_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { const lr35902dasm *d; const char /* *symbol,*/ *src; @@ -201,11 +185,11 @@ CPU_DISASSEMBLE(lr35902) //symbol = nullptr; - op = oprom[pos++]; + op = opcodes.r8(pos++); op1 = 0; /* keep GCC happy */ if( op == 0xcb ) { - op = oprom[pos++]; + op = opcodes.r8(pos++); d = &mnemonic_cb[op]; } else { d = &mnemonic_main[op]; @@ -220,12 +204,12 @@ CPU_DISASSEMBLE(lr35902) util::stream_format(stream, "$%02X,$%02X", op, op1); break; case 'A': - ea = opram[pos] + (opram[pos+1] << 8); + ea = params.r16(pos); pos += 2; util::stream_format(stream, "$%04X", ea); break; case 'B': /* Byte op arg */ - ea = opram[pos++]; + ea = params.r8(pos++); util::stream_format(stream, "$%02X", ea); break; case '(': /* Memory byte at (...) */ @@ -235,7 +219,7 @@ CPU_DISASSEMBLE(lr35902) } else if( !strncmp( src, "(hl)", 4) ) { } else if( !strncmp( src, "(sp)", 4) ) { } else if( !strncmp( src, "(F)", 3) ) { - ea = 0xFF00 + opram[pos++]; + ea = 0xFF00 + params.r8(pos++); util::stream_format(stream, "$%02X", ea); src++; } else if( !strncmp( src, "(C)", 3) ) { @@ -244,12 +228,12 @@ CPU_DISASSEMBLE(lr35902) } break; case 'N': /* Immediate 16 bit */ - ea = opram[pos] + (opram[pos+1] << 8); + ea = params.r16(pos); pos += 2; util::stream_format(stream, "$%04X", ea); break; case 'O': /* Offset relative to PC */ - offset = (int8_t) opram[pos++]; + offset = (int8_t) params.r8(pos++); util::stream_format(stream, "$%04X", pc + offset + 2); break; case 'V': /* Restart vector */ @@ -257,7 +241,7 @@ CPU_DISASSEMBLE(lr35902) util::stream_format(stream, "$%02X", ea); break; case 'W': /* Memory address word */ - ea = opram[pos] + (opram[pos+1] << 8); + ea = params.r16(pos); pos += 2; util::stream_format(stream, "$%04X", ea); break; @@ -271,5 +255,5 @@ CPU_DISASSEMBLE(lr35902) util::stream_format(stream, "%s", s_mnemonic[d->mnemonic]); } - return pos | s_flags[d->mnemonic] | DASMFLAG_SUPPORTED; + return pos | s_flags[d->mnemonic] | SUPPORTED; } diff --git a/src/devices/cpu/lr35902/lr35902d.h b/src/devices/cpu/lr35902/lr35902d.h new file mode 100644 index 00000000000..550a8bdaef8 --- /dev/null +++ b/src/devices/cpu/lr35902/lr35902d.h @@ -0,0 +1,48 @@ +// license:BSD-3-Clause +// copyright-holders:Wilbert Pol +/***************************************************************************** + * + * lr35902d.c + * Portable Sharp LR35902 disassembler + * + *****************************************************************************/ + +#ifndef MAME_CPU_LR35902_LR35902DASM_H +#define MAME_CPU_LR35902_LR35902DASM_H + +#pragma once + +class lr35902_disassembler : public util::disasm_interface +{ +public: + lr35902_disassembler() = default; + virtual ~lr35902_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum e_mnemonics + { + zADC, zADD, zAND, zBIT, zCALL, zCCF, zCP, + zCPL, zDAA, zDB, zDEC, zDI, zEI, zHLT, + zIN, zINC, zJP, zJR, zLD, zNOP, zOR, + zPOP, zPUSH, zRES, zRET, zRETI, zRL, zRLA, + zRLC, zRLCA, zRR, zRRA, zRRC, zRRCA, zRST, + zSBC, zSCF, zSET, zSLA, zSLL, zSRA, zSRL, + zSTOP, zSUB, zXOR, zSWAP + }; + + struct lr35902dasm + { + uint8_t mnemonic; + const char *arguments; + }; + + static const char *const s_mnemonic[]; + static const uint32_t s_flags[]; + static const lr35902dasm mnemonic_cb[256]; + static const lr35902dasm mnemonic_main[256]; +}; + +#endif diff --git a/src/devices/cpu/m37710/m37710.cpp b/src/devices/cpu/m37710/m37710.cpp index 1c6b78f1b06..53bb01301eb 100644 --- a/src/devices/cpu/m37710/m37710.cpp +++ b/src/devices/cpu/m37710/m37710.cpp @@ -939,21 +939,20 @@ void m37710_cpu_device::m37710_set_irq_line(int line, int state) (this->*m_set_line)(line, state); } -/* Disassemble an instruction */ -#include "m7700ds.h" - - -CPU_DISASSEMBLE( m37710 ) +bool m37710_cpu_device::get_m_flag() const { - return m7700_disassemble(stream, (pc&0xffff), pc>>16, oprom, 0, 0); + return FLAG_M; } - -offs_t m37710_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +bool m37710_cpu_device::get_x_flag() const { - return m7700_disassemble(stream, (pc&0xffff), pc>>16, oprom, FLAG_M, FLAG_X); + return FLAG_X; } +util::disasm_interface *m37710_cpu_device::create_disassembler() +{ + return new m7700_disassembler(this); +} void m37710_cpu_device::m37710_restore_state() { @@ -999,7 +998,7 @@ void m37710_cpu_device::device_start() memset(m_m37710_regs, 0, sizeof(m_m37710_regs)); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); m_ICount = 0; diff --git a/src/devices/cpu/m37710/m37710.h b/src/devices/cpu/m37710/m37710.h index 69e2ccffb26..4a52bfd8bcc 100644 --- a/src/devices/cpu/m37710/m37710.h +++ b/src/devices/cpu/m37710/m37710.h @@ -12,6 +12,9 @@ M37710 CPU Emulator v0.1 */ +#include "m7700ds.h" + + /* ======================================================================== */ /* =============================== DEFINES ================================ */ /* ======================================================================== */ @@ -94,7 +97,7 @@ enum #define M37710_INTERNAL_ROM_REGION "internal" #define M37710_INTERNAL_ROM(_tag) (_tag ":" M37710_INTERNAL_ROM_REGION) -class m37710_cpu_device : public cpu_device +class m37710_cpu_device : public cpu_device, public m7700_disassembler::config { public: DECLARE_READ8_MEMBER( m37710_internal_r ); @@ -124,9 +127,9 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 6; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; + virtual bool get_m_flag() const override; + virtual bool get_x_flag() const override; private: address_space_config m_program_config; @@ -168,7 +171,7 @@ private: uint32_t m_source; /* temp register */ uint32_t m_destination; /* temp register */ address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_io; uint32_t m_stopped; /* Sets how the CPU is stopped */ diff --git a/src/devices/cpu/m37710/m7700ds.cpp b/src/devices/cpu/m37710/m7700ds.cpp index ed81e320a3c..bf8f791935b 100644 --- a/src/devices/cpu/m37710/m7700ds.cpp +++ b/src/devices/cpu/m37710/m7700ds.cpp @@ -12,76 +12,9 @@ Based on G65C816 CPU Emulator by Karl Stenerud #include "emu.h" #include "m7700ds.h" -#ifdef SEC -#undef SEC -#endif - #define ADDRESS_24BIT(A) ((A)&0xffffff) -namespace { - -class m7700_opcode_struct -{ -public: - bool is_call() const { return m_name == op::JSR; } - bool is_return() const { return (m_name == op::RTS) || (m_name == op::RTI); } - const char *name() const { return s_opnames[unsigned(m_name)]; } - - static const m7700_opcode_struct &get(unsigned char ins) { return s_opcodes[ins]; } - static const m7700_opcode_struct &get_prefix42(unsigned char ins) { return s_opcodes_prefix42[ins]; } - static const m7700_opcode_struct &get_prefix89(unsigned char ins) { return s_opcodes_prefix89[ins]; } - - unsigned char flag; - unsigned char ea; - -protected: - enum class op : unsigned - { - ADC , AND , ASL , BCC , BCS , BEQ , BIT , BMI , BNE , BPL , BRA , - BRK , BRL , BVC , BVS , CLC , CLD , CLI , CLV , CMP , COP , CPX , - CPY , DEA , DEC , DEX , DEY , EOR , INA , INC , INX , INY , JML , - JMP , JSL , JSR , LDA , LDX , LDY , LSR , MVN , MVP , NOP , ORA , - PEA , PEI , PER , PHA , PHT , PHD , PHK , PHP , PHX , PHY , PLA , - PLB , PLD , PLP , PLX , PLY , CLP , ROL , ROR , RTI , RTL , RTS , - SBC , SEC , SED , SEI , SEP , STA , STP , STX , STY , STZ , TAX , - TAY , TCS , TCD , TDC , TRB , TSB , TSC , TSX , TXA , TXS , TXY , - TYA , TYX , WAI , WDM , XBA , XCE , MPY , DIV , MPYS, DIVS, RLA , - EXTS, EXTZ , LDT , LDM , UNK , SEB , SEM , CLM , STB , LDB , ADCB , - SBCB, EORB , TBX , CMPB, INB , DEB , TXB , TYB , LSRB, ORB , CLB , - BBC, BBS, TBY, ANDB, PUL , PSH , PLAB, XAB , PHB - }; - - m7700_opcode_struct(op n, unsigned char f, unsigned char e) - : flag(f) - , ea(e) - , m_name(n) - { - } - - op m_name; - - static const char *const s_opnames[]; - static const m7700_opcode_struct s_opcodes[256]; - static const m7700_opcode_struct s_opcodes_prefix42[256]; - static const m7700_opcode_struct s_opcodes_prefix89[256]; -}; - -enum -{ - IMP , ACC , RELB, RELW, IMM , A , AI , AL , ALX , AX , AXI , - AY , D , DI , DIY , DLI , DLIY, DX , DXI , DY , S , SIY , - SIG , MVN , MVP , PEA , PEI , PER , LDM4, LDM5, LDM4X, LDM5X, - BBCD, BBCA, ACCB -}; - -enum -{ - I, /* ignore */ - M, /* check m bit */ - X /* check x bit */ -}; - -const char *const m7700_opcode_struct::s_opnames[] = +const char *const m7700_disassembler::s_opnames[] = { "ADC", "AND", "ASL", "BCC", "BCS", "BEQ", "BIT", "BMI", "BNE", "BPL", "BRA", "BRK", "BRL", "BVC", "BVS", "CLC", "CLD", "CLI", "CLV", "CMP", "COP", "CPX", @@ -97,7 +30,7 @@ const char *const m7700_opcode_struct::s_opnames[] = "BBC", "BBS", "TBY", "ANDB","PUL", "PSH", "PLB", "XAB", "PHB", }; -const m7700_opcode_struct m7700_opcode_struct::s_opcodes[256] = +const m7700_disassembler::m7700_opcode_struct m7700_disassembler::s_opcodes[256] = { {op::BRK, I, SIG }, {op::ORA, M, DXI }, {op::UNK, I, SIG }, {op::ORA, M, S }, {op::SEB, M, LDM4 }, {op::ORA, M, D }, {op::ASL, M, D }, {op::ORA, M, DLI }, @@ -180,7 +113,7 @@ const m7700_opcode_struct m7700_opcode_struct::s_opcodes[256] = {op::JSR, I, AXI }, {op::SBC, M, AX }, {op::INC, M, AX }, {op::SBC, M, ALX } }; -const m7700_opcode_struct m7700_opcode_struct::s_opcodes_prefix42[256] = +const m7700_disassembler::m7700_opcode_struct m7700_disassembler::s_opcodes_prefix42[256] = { {op::BRK, I, SIG }, {op::ORB, M, DXI }, {op::COP, I, SIG }, {op::ORB, M, S }, {op::TSB, M, D }, {op::ORB, M, D }, {op::ASL, M, D }, {op::ORB, M, DLI }, @@ -263,7 +196,7 @@ const m7700_opcode_struct m7700_opcode_struct::s_opcodes_prefix42[256] = {op::JSR, I, AXI }, {op::SBCB,M, AX }, {op::INC, M, AX }, {op::SBCB, M, ALX } }; -const m7700_opcode_struct m7700_opcode_struct::s_opcodes_prefix89[256] = +const m7700_disassembler::m7700_opcode_struct m7700_disassembler::s_opcodes_prefix89[256] = { {op::BRK, I, SIG }, {op::MPY, M, DXI }, {op::COP, I, SIG }, {op::MPY, M, S }, {op::TSB, M, D }, {op::MPY, M, D }, {op::ASL, M, D }, {op::MPY, M, DLI }, @@ -346,71 +279,54 @@ const m7700_opcode_struct m7700_opcode_struct::s_opcodes_prefix89[256] = {op::JSR, I, AXI }, {op::SBC, M, AX }, {op::INC, M, AX }, {op::SBC, M, ALX } }; -} // anonymous namespace - -static inline unsigned int read_8(const uint8_t *oprom, unsigned int offset) +inline std::string m7700_disassembler::int_8_str(unsigned int val) { - return oprom[offset]; -} - -static inline unsigned int read_16(const uint8_t *oprom, unsigned int offset) -{ - unsigned int val = read_8(oprom, offset); - return val | (read_8(oprom, offset+1)<<8); -} - -static inline unsigned int read_24(const uint8_t *oprom, unsigned int offset) -{ - unsigned int val = read_8(oprom, offset); - val |= (read_8(oprom, offset+1)<<8); - return val | (read_8(oprom, offset+2)<<16); -} - -static inline char* int_8_str(unsigned int val) -{ - static char str[20]; - val &= 0xff; if(val & 0x80) - sprintf(str, "-$%x", (0-val) & 0x7f); + return util::string_format("-$%x", (0-val) & 0xff); else - sprintf(str, "$%x", val & 0x7f); - - return str; + return util::string_format("$%x", val & 0xff); } -static inline char* int_16_str(unsigned int val) +inline std::string m7700_disassembler::int_16_str(unsigned int val) { - static char str[20]; - val &= 0xffff; if(val & 0x8000) - sprintf(str, "-$%x", (0-val) & 0x7fff); + return util::string_format("-$%x", (0-val) & 0xffff); else - sprintf(str, "$%x", val & 0x7fff); + return util::string_format("$%x", val & 0xffff); +} - return str; +m7700_disassembler::m7700_disassembler(config *conf) : m_config(conf) +{ } +u32 m7700_disassembler::opcode_alignment() const +{ + return 1; +} -int m7700_disassemble(std::ostream &stream, unsigned int pc, unsigned int pb, const uint8_t *oprom, int m_flag, int x_flag) +offs_t m7700_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { unsigned int instruction; const m7700_opcode_struct *opcode; int var; signed char varS; int length = 1; - unsigned int address; //unsigned int start; uint32_t flags = 0; - pb <<= 16; + offs_t address = pc; + u32 pb = pc & 0xffff0000; + pc &= 0xffff; address = pc | pb; - //start = address; - instruction = read_8(oprom,0); + instruction = opcodes.r8(address); + + int m_flag = m_config->get_m_flag(); + int x_flag = m_config->get_x_flag(); // check for prefixes switch (instruction) @@ -418,16 +334,14 @@ int m7700_disassemble(std::ostream &stream, unsigned int pc, unsigned int pb, co case 0x42: address++; length++; - oprom++; - instruction = read_8(oprom,0); + instruction = opcodes.r8(address); opcode = &m7700_opcode_struct::get_prefix42(instruction); break; case 0x89: address++; length++; - oprom++; - instruction = read_8(oprom,0); + instruction = opcodes.r8(address); opcode = &m7700_opcode_struct::get_prefix89(instruction); break; @@ -437,9 +351,9 @@ int m7700_disassemble(std::ostream &stream, unsigned int pc, unsigned int pb, co } if (opcode->is_call()) - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; else if (opcode->is_return()) - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; stream << opcode->name(); @@ -454,189 +368,184 @@ int m7700_disassemble(std::ostream &stream, unsigned int pc, unsigned int pb, co util::stream_format(stream, " B"); break; case RELB: - varS = read_8(oprom,1); + varS = opcodes.r8(address + 1); length++; util::stream_format(stream, " %06x (%s)", pb | ((pc + length + varS)&0xffff), int_8_str(varS)); break; case RELW: case PER : - var = read_16(oprom,1); + var = opcodes.r16(address + 1); length += 2; util::stream_format(stream, " %06x (%s)", pb | ((pc + length + var)&0xffff), int_16_str(var)); break; case IMM : if((opcode->flag == M && !m_flag) || (opcode->flag == X && !x_flag)) { - util::stream_format(stream, " #$%04x", read_16(oprom,1)); + util::stream_format(stream, " #$%04x", opcodes.r16(address + 1)); length += 2; } else { - util::stream_format(stream, " #$%02x", read_8(oprom,1)); + util::stream_format(stream, " #$%02x", opcodes.r8(address + 1)); length++; } break; case BBCD: if((opcode->flag == M && !m_flag) || (opcode->flag == X && !x_flag)) { - varS = read_8(oprom,4); + varS = opcodes.r8(address + 4); length += 4; - util::stream_format(stream, " #$%04x, $%02x, %06x (%s)", read_16(oprom,2), read_8(oprom,1), pb | ((pc + length + varS)&0xffff), int_8_str(varS)); + util::stream_format(stream, " #$%04x, $%02x, %06x (%s)", opcodes.r16(address + 2), opcodes.r8(address + 1), pb | ((pc + length + varS)&0xffff), int_8_str(varS)); } else { - varS = read_8(oprom,3); + varS = opcodes.r8(address + 3); length += 3; - util::stream_format(stream, " #$%02x, $%02x, %06x (%s)", read_8(oprom,2), read_8(oprom,1), pb | ((pc + length + varS)&0xffff), int_8_str(varS)); + util::stream_format(stream, " #$%02x, $%02x, %06x (%s)", opcodes.r8(address + 2), opcodes.r8(address + 1), pb | ((pc + length + varS)&0xffff), int_8_str(varS)); } break; case BBCA: if((opcode->flag == M && !m_flag) || (opcode->flag == X && !x_flag)) { length += 5; - varS = read_8(oprom,5); - util::stream_format(stream, " #$%04x, $%04x, %06x (%s)", read_16(oprom,3), read_16(oprom,1), pb | ((pc + length + varS)&0xffff), int_8_str(varS)); + varS = opcodes.r8(address + 5); + util::stream_format(stream, " #$%04x, $%04x, %06x (%s)", opcodes.r16(address + 3), opcodes.r16(address + 1), pb | ((pc + length + varS)&0xffff), int_8_str(varS)); } else { length += 4; - varS = read_8(oprom,4); - util::stream_format(stream, " #$%02x, $%04x, %06x (%s)", read_8(oprom,3), read_16(oprom,1), pb | ((pc + length + varS)&0xffff), int_8_str(varS)); + varS = opcodes.r8(address + 4); + util::stream_format(stream, " #$%02x, $%04x, %06x (%s)", opcodes.r8(address + 3), opcodes.r16(address + 1), pb | ((pc + length + varS)&0xffff), int_8_str(varS)); } break; case LDM4: if((opcode->flag == M && !m_flag) || (opcode->flag == X && !x_flag)) { - util::stream_format(stream, " #$%04x, $%02x", read_16(oprom,2), read_8(oprom,1)); + util::stream_format(stream, " #$%04x, $%02x", opcodes.r16(address + 2), opcodes.r8(address + 1)); length += 3; } else { - util::stream_format(stream, " #$%02x, $%02x", read_8(oprom,2), read_8(oprom,1)); + util::stream_format(stream, " #$%02x, $%02x", opcodes.r8(address + 2), opcodes.r8(address + 1)); length += 2; } break; case LDM5: if((opcode->flag == M && !m_flag) || (opcode->flag == X && !x_flag)) { - util::stream_format(stream, " #$%04x, $%04x", read_16(oprom,3), read_16(oprom,1)); + util::stream_format(stream, " #$%04x, $%04x", opcodes.r16(address + 3), opcodes.r16(address + 1)); length += 4; } else { - util::stream_format(stream, " #$%02x, $%04x", read_8(oprom,3), read_16(oprom,1)); + util::stream_format(stream, " #$%02x, $%04x", opcodes.r8(address + 3), opcodes.r16(address + 1)); length += 3; } break; case LDM4X: if((opcode->flag == M && !m_flag) || (opcode->flag == X && !x_flag)) { - util::stream_format(stream, " #$%04x, $%02x, X", read_16(oprom,2), read_8(oprom,1)); + util::stream_format(stream, " #$%04x, $%02x, X", opcodes.r16(address + 2), opcodes.r8(address + 1)); length += 3; } else { - util::stream_format(stream, " #$%02x, $%02x, X", read_8(oprom,2), read_8(oprom,1)); + util::stream_format(stream, " #$%02x, $%02x, X", opcodes.r8(address + 2), opcodes.r8(address + 1)); length += 2; } break; case LDM5X: if((opcode->flag == M && !m_flag) || (opcode->flag == X && !x_flag)) { - util::stream_format(stream, " #$%04x, $%04x, X", read_16(oprom,3), read_16(oprom,1)); + util::stream_format(stream, " #$%04x, $%04x, X", opcodes.r16(address + 3), opcodes.r16(address + 1)); length += 4; } else { - util::stream_format(stream, " #$%02x, $%04x, X", read_8(oprom,3), read_16(oprom,1)); + util::stream_format(stream, " #$%02x, $%04x, X", opcodes.r8(address + 3), opcodes.r16(address + 1)); length += 3; } break; case A : case PEA : - util::stream_format(stream, " $%04x", read_16(oprom,1)); + util::stream_format(stream, " $%04x", opcodes.r16(address + 1)); length += 2; break; case AI : - util::stream_format(stream, " ($%04x)", read_16(oprom,1)); + util::stream_format(stream, " ($%04x)", opcodes.r16(address + 1)); length += 2; break; case AL : - util::stream_format(stream, " $%06x", read_24(oprom,1)); + util::stream_format(stream, " $%06x", opcodes.r32(address + 1) & 0xffffff); length += 3; break; case ALX : - util::stream_format(stream, " $%06x,X", read_24(oprom,1)); + util::stream_format(stream, " $%06x,X", opcodes.r32(address + 1) & 0xffffff); length += 3; break; case AX : - util::stream_format(stream, " $%04x,X", read_16(oprom,1)); + util::stream_format(stream, " $%04x,X", opcodes.r16(address + 1)); length += 2; break; case AXI : - util::stream_format(stream, " ($%04x,X)", read_16(oprom,1)); + util::stream_format(stream, " ($%04x,X)", opcodes.r16(address + 1)); length += 2; break; case AY : - util::stream_format(stream, " $%04x,Y", read_16(oprom,1)); + util::stream_format(stream, " $%04x,Y", opcodes.r16(address + 1)); length += 2; break; case D : - util::stream_format(stream, " $%02x", read_8(oprom,1)); + util::stream_format(stream, " $%02x", opcodes.r8(address + 1)); length++; break; case DI : case PEI : - util::stream_format(stream, " ($%02x)", read_8(oprom,1)); + util::stream_format(stream, " ($%02x)", opcodes.r8(address + 1)); length++; break; case DIY : - util::stream_format(stream, " ($%02x),Y", read_8(oprom,1)); + util::stream_format(stream, " ($%02x),Y", opcodes.r8(address + 1)); length++; break; case DLI : - util::stream_format(stream, " [$%02x]", read_8(oprom,1)); + util::stream_format(stream, " [$%02x]", opcodes.r8(address + 1)); length++; break; case DLIY: - util::stream_format(stream, " [$%02x],Y", read_8(oprom,1)); + util::stream_format(stream, " [$%02x],Y", opcodes.r8(address + 1)); length++; break; case DX : - util::stream_format(stream, " $%02x,X", read_8(oprom,1)); + util::stream_format(stream, " $%02x,X", opcodes.r8(address + 1)); length++; break; case DXI : - util::stream_format(stream, " ($%02x,X)", read_8(oprom,1)); + util::stream_format(stream, " ($%02x,X)", opcodes.r8(address + 1)); length++; break; case DY : - util::stream_format(stream, " $%02x,Y", read_8(oprom,1)); + util::stream_format(stream, " $%02x,Y", opcodes.r8(address + 1)); length++; break; case S : - util::stream_format(stream, " %s,S", int_8_str(read_8(oprom,1))); + util::stream_format(stream, " %s,S", int_8_str(opcodes.r8(address + 1))); length++; break; case SIY : - util::stream_format(stream, " (%s,S),Y", int_8_str(read_8(oprom,1))); + util::stream_format(stream, " (%s,S),Y", int_8_str(opcodes.r8(address + 1))); length++; break; case SIG : - util::stream_format(stream, " #$%02x", read_8(oprom,1)); + util::stream_format(stream, " #$%02x", opcodes.r8(address + 1)); length++; break; case MVN : case MVP : - util::stream_format(stream, " $%02x, $%02x", read_8(oprom,2), read_8(oprom,1)); + util::stream_format(stream, " $%02x, $%02x", opcodes.r8(address + 2), opcodes.r8(address + 1)); length += 2; break; } - return length | flags | DASMFLAG_SUPPORTED; -} - -CPU_DISASSEMBLE(m37710_generic) -{ - return m7700_disassemble(stream, (pc&0xffff), pc>>16, oprom, 0, 0); + return length | flags | SUPPORTED; } diff --git a/src/devices/cpu/m37710/m7700ds.h b/src/devices/cpu/m37710/m7700ds.h index 061070bf407..6a30eb1af61 100644 --- a/src/devices/cpu/m37710/m7700ds.h +++ b/src/devices/cpu/m37710/m7700ds.h @@ -18,6 +18,86 @@ All rights reserved. */ -int m7700_disassemble(std::ostream &stream, unsigned int pc, unsigned int pb, const uint8_t *oprom, int m_flag, int x_flag); +class m7700_disassembler : public util::disasm_interface +{ +public: + struct config { + virtual ~config() = default; + + virtual bool get_m_flag() const = 0; + virtual bool get_x_flag() const = 0; + }; + + m7700_disassembler(config *conf); + virtual ~m7700_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum class op : unsigned + { + ADC , AND , ASL , BCC , BCS , BEQ , BIT , BMI , BNE , BPL , BRA , + BRK , BRL , BVC , BVS , CLC , CLD , CLI , CLV , CMP , COP , CPX , + CPY , DEA , DEC , DEX , DEY , EOR , INA , INC , INX , INY , JML , + JMP , JSL , JSR , LDA , LDX , LDY , LSR , MVN , MVP , NOP , ORA , + PEA , PEI , PER , PHA , PHT , PHD , PHK , PHP , PHX , PHY , PLA , + PLB , PLD , PLP , PLX , PLY , CLP , ROL , ROR , RTI , RTL , RTS , + SBC , SEC , SED , SEI , SEP , STA , STP , STX , STY , STZ , TAX , + TAY , TCS , TCD , TDC , TRB , TSB , TSC , TSX , TXA , TXS , TXY , + TYA , TYX , WAI , WDM , XBA , XCE , MPY , DIV , MPYS, DIVS, RLA , + EXTS, EXTZ , LDT , LDM , UNK , SEB , SEM , CLM , STB , LDB , ADCB , + SBCB, EORB , TBX , CMPB, INB , DEB , TXB , TYB , LSRB, ORB , CLB , + BBC, BBS, TBY, ANDB, PUL , PSH , PLAB, XAB , PHB + }; + + enum + { + IMP , ACC , RELB, RELW, IMM , A , AI , AL , ALX , AX , AXI , + AY , D , DI , DIY , DLI , DLIY, DX , DXI , DY , S , SIY , + SIG , MVN , MVP , PEA , PEI , PER , LDM4, LDM5, LDM4X, LDM5X, + BBCD, BBCA, ACCB + }; + + enum + { + I, /* ignore */ + M, /* check m bit */ + X /* check x bit */ + }; + + class m7700_opcode_struct + { + public: + bool is_call() const { return m_name == op::JSR; } + bool is_return() const { return (m_name == op::RTS) || (m_name == op::RTI); } + const char *name() const { return s_opnames[unsigned(m_name)]; } + + static const m7700_opcode_struct &get(unsigned char ins) { return s_opcodes[ins]; } + static const m7700_opcode_struct &get_prefix42(unsigned char ins) { return s_opcodes_prefix42[ins]; } + static const m7700_opcode_struct &get_prefix89(unsigned char ins) { return s_opcodes_prefix89[ins]; } + + unsigned char flag; + unsigned char ea; + op m_name; + + m7700_opcode_struct(op n, unsigned char f, unsigned char e) + : flag(f) + , ea(e) + , m_name(n) + { + } + }; + + static const char *const s_opnames[]; + static const m7700_opcode_struct s_opcodes[256]; + static const m7700_opcode_struct s_opcodes_prefix42[256]; + static const m7700_opcode_struct s_opcodes_prefix89[256]; + + config *m_config; + + std::string int_8_str(unsigned int val); + std::string int_16_str(unsigned int val); +}; #endif /* __M7700DS_H__ */ diff --git a/src/devices/cpu/m6502/deco16.cpp b/src/devices/cpu/m6502/deco16.cpp index 163403228d9..e5121676253 100644 --- a/src/devices/cpu/m6502/deco16.cpp +++ b/src/devices/cpu/m6502/deco16.cpp @@ -10,6 +10,7 @@ #include "emu.h" #include "deco16.h" +#include "deco16d.h" #define DECO16_VERBOSE 1 @@ -22,12 +23,11 @@ deco16_device::deco16_device(const machine_config &mconfig, const char *tag, dev { } -offs_t deco16_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *deco16_device::create_disassembler() { - return disassemble_generic(stream, pc, oprom, opram, options, disasm_entries); + return new deco16_disassembler; } - void deco16_device::device_start() { if(direct_disabled) diff --git a/src/devices/cpu/m6502/deco16.h b/src/devices/cpu/m6502/deco16.h index c3f55764553..1c980b2e4c6 100644 --- a/src/devices/cpu/m6502/deco16.h +++ b/src/devices/cpu/m6502/deco16.h @@ -12,14 +12,14 @@ #define MAME_CPU_M6502_DECO16_H #include "m6502.h" +#include "deco16d.h" class deco16_device : public m6502_device { public: deco16_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - static const disasm_entry disasm_entries[0x100]; + virtual util::disasm_interface *create_disassembler() override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; virtual void do_exec_full() override; virtual void do_exec_partial() override; diff --git a/src/devices/cpu/m6502/deco16d.cpp b/src/devices/cpu/m6502/deco16d.cpp new file mode 100644 index 00000000000..8f126ef3023 --- /dev/null +++ b/src/devices/cpu/m6502/deco16d.cpp @@ -0,0 +1,17 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + deco16d.cpp + + 6502, reverse-engineered DECO variant, disassembler + +***************************************************************************/ + +#include "emu.h" +#include "deco16d.h" +#include "cpu/m6502/deco16d.hxx" + +deco16_disassembler::deco16_disassembler() : m6502_base_disassembler(disasm_entries) +{ +} diff --git a/src/devices/cpu/m6502/deco16d.h b/src/devices/cpu/m6502/deco16d.h new file mode 100644 index 00000000000..3658da9ea9a --- /dev/null +++ b/src/devices/cpu/m6502/deco16d.h @@ -0,0 +1,28 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + deco16d.h + + 6502, reverse-engineered DECO variant, disassembler + +***************************************************************************/ + +#ifndef MAME_CPU_M6502_DECO16D_H +#define MAME_CPU_M6502_DECO16D_H + +#pragma once + +#include "m6502d.h" + +class deco16_disassembler : public m6502_base_disassembler +{ +public: + deco16_disassembler(); + virtual ~deco16_disassembler() = default; + +private: + static const disasm_entry disasm_entries[0x100]; +}; + +#endif diff --git a/src/devices/cpu/m6502/m4510.cpp b/src/devices/cpu/m6502/m4510.cpp index 852d3e5807a..5848f66970d 100644 --- a/src/devices/cpu/m6502/m4510.cpp +++ b/src/devices/cpu/m6502/m4510.cpp @@ -10,6 +10,7 @@ #include "emu.h" #include "m4510.h" +#include "m4510d.h" DEFINE_DEVICE_TYPE(M4510, m4510_device, "m4510", "M4510") @@ -26,9 +27,9 @@ m4510_device::m4510_device(const machine_config &mconfig, const char *tag, devic sprogram_config.m_page_shift = 13; } -offs_t m4510_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *m4510_device::create_disassembler() { - return disassemble_generic(stream, pc, oprom, opram, options, disasm_entries); + return new m4510_disassembler; } void m4510_device::device_start() diff --git a/src/devices/cpu/m6502/m4510.h b/src/devices/cpu/m6502/m4510.h index b093c8aeb56..a41a0620c93 100644 --- a/src/devices/cpu/m6502/m4510.h +++ b/src/devices/cpu/m6502/m4510.h @@ -19,9 +19,8 @@ class m4510_device : public m65ce02_device { public: m4510_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - static const disasm_entry disasm_entries[0x100]; + virtual util::disasm_interface *create_disassembler() override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; virtual void do_exec_full() override; virtual void do_exec_partial() override; diff --git a/src/devices/cpu/m6502/m4510d.cpp b/src/devices/cpu/m6502/m4510d.cpp new file mode 100644 index 00000000000..896a3f78124 --- /dev/null +++ b/src/devices/cpu/m6502/m4510d.cpp @@ -0,0 +1,17 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + m4510d.cpp + + 65ce02 with a mmu and a port, disassembler + +***************************************************************************/ + +#include "emu.h" +#include "m4510d.h" +#include "cpu/m6502/m4510d.hxx" + +m4510_disassembler::m4510_disassembler() : m6502_base_disassembler(disasm_entries) +{ +} diff --git a/src/devices/cpu/m6502/m4510d.h b/src/devices/cpu/m6502/m4510d.h new file mode 100644 index 00000000000..1c025cfb8e7 --- /dev/null +++ b/src/devices/cpu/m6502/m4510d.h @@ -0,0 +1,28 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + m4510d.h + + 65ce02 with a mmu and a port, disassembler + +***************************************************************************/ + +#ifndef MAME_CPU_M6502_M4510D_H +#define MAME_CPU_M6502_M4510D_H + +#pragma once + +#include "m6502d.h" + +class m4510_disassembler : public m6502_base_disassembler +{ +public: + m4510_disassembler(); + virtual ~m4510_disassembler() = default; + +private: + static const disasm_entry disasm_entries[0x100]; +}; + +#endif diff --git a/src/devices/cpu/m6502/m6502.cpp b/src/devices/cpu/m6502/m6502.cpp index f498ca87771..2cbded54949 100644 --- a/src/devices/cpu/m6502/m6502.cpp +++ b/src/devices/cpu/m6502/m6502.cpp @@ -11,6 +11,7 @@ #include "emu.h" #include "debugger.h" #include "m6502.h" +#include "m6502d.h" DEFINE_DEVICE_TYPE(M6502, m6502_device, "m6502", "M6502") @@ -44,8 +45,8 @@ void m6502_device::init() mintf->program = &space(AS_PROGRAM); mintf->sprogram = has_space(AS_OPCODES) ? &space(AS_OPCODES) : mintf->program; - mintf->direct = &mintf->program->direct(); - mintf->sdirect = &mintf->sprogram->direct(); + mintf->direct = mintf->program->direct<0>(); + mintf->sdirect = mintf->sprogram->direct<0>(); sync_w.resolve_safe(); @@ -453,179 +454,6 @@ void m6502_device::state_string_export(const device_state_entry &entry, std::str } } - -uint32_t m6502_device::disasm_min_opcode_bytes() const -{ - return 1; -} - -uint32_t m6502_device::disasm_max_opcode_bytes() const -{ - return 4; -} - -offs_t m6502_device::disassemble_generic(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options, const disasm_entry *table) -{ - const disasm_entry &e = table[oprom[0] | inst_state_base]; - uint32_t flags = e.flags | DASMFLAG_SUPPORTED; - util::stream_format(stream, "%s", e.opcode); - - switch(e.mode) { - case DASM_non: - flags |= 1; - break; - - case DASM_aba: - util::stream_format(stream, " $%02x%02x", opram[2], opram[1]); - flags |= 3; - break; - - case DASM_abx: - util::stream_format(stream, " $%02x%02x, x", opram[2], opram[1]); - flags |= 3; - break; - - case DASM_aby: - util::stream_format(stream, " $%02x%02x, y", opram[2], opram[1]); - flags |= 3; - break; - - case DASM_acc: - util::stream_format(stream, " a"); - flags |= 1; - break; - - case DASM_adr: - util::stream_format(stream, " $%02x%02x", opram[2], opram[1]); - flags |= 3; - break; - - case DASM_bzp: - util::stream_format(stream, "%d $%02x", (oprom[0] >> 4) & 7, opram[1]); - flags |= 2; - break; - - case DASM_iax: - util::stream_format(stream, " ($%02x%02x, x)", opram[2], opram[1]); - flags |= 3; - break; - - case DASM_idx: - util::stream_format(stream, " ($%02x, x)", opram[1]); - flags |= 2; - break; - - case DASM_idy: - util::stream_format(stream, " ($%02x), y", opram[1]); - flags |= 2; - break; - - case DASM_idz: - util::stream_format(stream, " ($%02x), z", opram[1]); - flags |= 2; - break; - - case DASM_imm: - util::stream_format(stream, " #$%02x", opram[1]); - flags |= 2; - break; - - case DASM_imp: - flags |= 1; - break; - - case DASM_ind: - util::stream_format(stream, " ($%02x%02x)", opram[2], opram[1]); - flags |= 3; - break; - - case DASM_isy: - util::stream_format(stream, " ($%02x, s), y", opram[1]); - flags |= 2; - break; - - case DASM_iw2: - util::stream_format(stream, " #$%02x%02x", opram[2], opram[1]); - flags |= 3; - break; - - case DASM_iw3: - util::stream_format(stream, " #$%02x%02x%02x", opram[3], opram[2], opram[1]); - flags |= 4; - break; - - case DASM_rel: - util::stream_format(stream, " $%04x", (pc & 0xf0000) | uint16_t(pc + 2 + int8_t(opram[1]))); - flags |= 2; - break; - - case DASM_rw2: - util::stream_format(stream, " $%04x", (pc & 0xf0000) | uint16_t(pc + 2 + int16_t((opram[2] << 8) | opram[1]))); - flags |= 3; - break; - - case DASM_zpb: - util::stream_format(stream, "%d $%02x, $%04x", (oprom[0] >> 4) & 7, opram[1], (pc & 0xf0000) | uint16_t(pc + 3 + int8_t(opram[2]))); - flags |= 3; - break; - - case DASM_zpg: - util::stream_format(stream, " $%02x", opram[1]); - flags |= 2; - break; - - case DASM_zpi: - util::stream_format(stream, " ($%02x)", opram[1]); - flags |= 2; - break; - - case DASM_zpx: - util::stream_format(stream, " $%02x, x", opram[1]); - flags |= 2; - break; - - case DASM_zpy: - util::stream_format(stream, " $%02x, y", opram[1]); - flags |= 2; - break; - - case DASM_imz: - util::stream_format(stream, " #$%02x, $%02x", opram[1], opram[2]); - flags |= 3; - break; - - case DASM_spg: - util::stream_format(stream, " \\$%02x", opram[1]); - flags |= 2; - break; - - case DASM_biz: - util::stream_format(stream, " %d, $%02x", (opram[0] >> 5) & 7, opram[1]); - flags |= 2; - break; - - case DASM_bzr: - util::stream_format(stream, " %d, $%02x, $%04x", (opram[0] >> 5) & 7, opram[1], (pc & 0xf0000) | uint16_t(pc + 3 + int8_t(opram[2]))); - flags |= 3; - break; - - case DASM_bar: - util::stream_format(stream, " %d, a, $%04x", (opram[0] >> 5) & 7, (pc & 0xf0000) | uint16_t(pc + 3 + int8_t(opram[1]))); - flags |= 2; - break; - - case DASM_bac: - util::stream_format(stream, " %d, a", (opram[0] >> 5) & 7); - flags |= 1; - break; - - default: - fprintf(stderr, "Unhandled dasm mode %d\n", e.mode); - abort(); - } - return flags; -} - void m6502_device::prefetch() { sync = true; @@ -662,12 +490,11 @@ void m6502_device::set_nz(uint8_t v) P |= F_Z; } -offs_t m6502_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *m6502_device::create_disassembler() { - return disassemble_generic(stream, pc, oprom, opram, options, disasm_entries); + return new m6502_disassembler; } - uint8_t m6502_device::memory_interface::read_9(uint16_t adr) { return read(adr); diff --git a/src/devices/cpu/m6502/m6502.h b/src/devices/cpu/m6502/m6502.h index 71bc63a534e..8f5236818f9 100644 --- a/src/devices/cpu/m6502/m6502.h +++ b/src/devices/cpu/m6502/m6502.h @@ -41,7 +41,7 @@ protected: class memory_interface { public: address_space *program, *sprogram; - direct_read_data *direct, *sdirect; + direct_read_data<0> *direct, *sdirect; virtual ~memory_interface() {} virtual uint8_t read(uint16_t adr) = 0; @@ -68,50 +68,11 @@ protected: virtual uint8_t read_arg(uint16_t adr) override; }; - struct disasm_entry { - const char *opcode; - int mode; - offs_t flags; - }; - enum { STATE_RESET = 0xff00 }; enum { - DASM_non, /* no additional arguments */ - DASM_aba, /* absolute */ - DASM_abx, /* absolute + X */ - DASM_aby, /* absolute + Y */ - DASM_acc, /* accumulator */ - DASM_adr, /* absolute address (jmp,jsr) */ - DASM_bzp, /* zero page with bit selection */ - DASM_iax, /* indirect + X (65c02 jmp) */ - DASM_idx, /* zero page pre indexed */ - DASM_idy, /* zero page post indexed */ - DASM_idz, /* zero page post indexed (65ce02) */ - DASM_imm, /* immediate */ - DASM_imp, /* implicit */ - DASM_ind, /* indirect (jmp) */ - DASM_isy, /* zero page pre indexed sp and post indexed Y (65ce02) */ - DASM_iw2, /* immediate word (65ce02) */ - DASM_iw3, /* augment (65ce02) */ - DASM_rel, /* relative */ - DASM_rw2, /* relative word (65cs02, 65ce02) */ - DASM_zpb, /* zero page and branch (65c02 bbr, bbs) */ - DASM_zpg, /* zero page */ - DASM_zpi, /* zero page indirect (65c02) */ - DASM_zpx, /* zero page + X */ - DASM_zpy, /* zero page + Y */ - DASM_imz, /* load immediate byte, store to zero page address (M740) */ - DASM_spg, /* "special page": implied FF00 OR immediate value (M740)*/ - DASM_biz, /* bit, zero page (M740) */ - DASM_bzr, /* bit, zero page, relative offset (M740) */ - DASM_bar, /* bit, accumulator, relative offset (M740) */ - DASM_bac /* bit, accumulator (M740) */ - }; - - enum { F_N = 0x80, F_V = 0x40, F_E = 0x20, // 65ce02 @@ -145,9 +106,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; address_space_config program_config, sprogram_config; @@ -170,9 +129,6 @@ protected: bool nmi_state, irq_state, apu_irq_state, v_state; bool irq_taken, sync, direct_disabled, inhibit_interrupts; - static const disasm_entry disasm_entries[0x100]; - - offs_t disassemble_generic(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options, const disasm_entry *table); uint8_t read(uint16_t adr) { return mintf->read(adr); } uint8_t read_9(uint16_t adr) { return mintf->read_9(adr); } void write(uint16_t adr, uint8_t val) { mintf->write(adr, val); } diff --git a/src/devices/cpu/m6502/m6502d.cpp b/src/devices/cpu/m6502/m6502d.cpp new file mode 100644 index 00000000000..89763113cde --- /dev/null +++ b/src/devices/cpu/m6502/m6502d.cpp @@ -0,0 +1,193 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + m6502d.cpp + + Mostek 6502, original NMOS variant, disassembler + +***************************************************************************/ + +#include "emu.h" +#include "m6502d.h" +#include "cpu/m6502/m6502d.hxx" + +m6502_base_disassembler::m6502_base_disassembler(const disasm_entry *_table) : table(_table) +{ +} + +u32 m6502_base_disassembler::get_instruction_bank() const +{ + return 0; +} + +u32 m6502_base_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t m6502_base_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + const disasm_entry &e = table[opcodes.r8(pc) | get_instruction_bank()]; + uint32_t flags = e.flags | SUPPORTED; + util::stream_format(stream, "%s", e.opcode); + + switch(e.mode) { + case DASM_non: + flags |= 1; + break; + + case DASM_aba: + util::stream_format(stream, " $%02x%02x", params.r8(pc+2), params.r8(pc+1)); + flags |= 3; + break; + + case DASM_abx: + util::stream_format(stream, " $%02x%02x, x", params.r8(pc+2), params.r8(pc+1)); + flags |= 3; + break; + + case DASM_aby: + util::stream_format(stream, " $%02x%02x, y", params.r8(pc+2), params.r8(pc+1)); + flags |= 3; + break; + + case DASM_acc: + util::stream_format(stream, " a"); + flags |= 1; + break; + + case DASM_adr: + util::stream_format(stream, " $%02x%02x", params.r8(pc+2), params.r8(pc+1)); + flags |= 3; + break; + + case DASM_bzp: + util::stream_format(stream, "%d $%02x", (opcodes.r8(pc) >> 4) & 7, params.r8(pc+1)); + flags |= 2; + break; + + case DASM_iax: + util::stream_format(stream, " ($%02x%02x, x)", params.r8(pc+2), params.r8(pc+1)); + flags |= 3; + break; + + case DASM_idx: + util::stream_format(stream, " ($%02x, x)", params.r8(pc+1)); + flags |= 2; + break; + + case DASM_idy: + util::stream_format(stream, " ($%02x), y", params.r8(pc+1)); + flags |= 2; + break; + + case DASM_idz: + util::stream_format(stream, " ($%02x), z", params.r8(pc+1)); + flags |= 2; + break; + + case DASM_imm: + util::stream_format(stream, " #$%02x", params.r8(pc+1)); + flags |= 2; + break; + + case DASM_imp: + flags |= 1; + break; + + case DASM_ind: + util::stream_format(stream, " ($%02x%02x)", params.r8(pc+2), params.r8(pc+1)); + flags |= 3; + break; + + case DASM_isy: + util::stream_format(stream, " ($%02x, s), y", params.r8(pc+1)); + flags |= 2; + break; + + case DASM_iw2: + util::stream_format(stream, " #$%02x%02x", params.r8(pc+2), params.r8(pc+1)); + flags |= 3; + break; + + case DASM_iw3: + util::stream_format(stream, " #$%02x%02x%02x", params.r8(pc+3), params.r8(pc+2), params.r8(pc+1)); + flags |= 4; + break; + + case DASM_rel: + util::stream_format(stream, " $%04x", (pc & 0xf0000) | uint16_t(pc + 2 + int8_t(params.r8(pc+1)))); + flags |= 2; + break; + + case DASM_rw2: + util::stream_format(stream, " $%04x", (pc & 0xf0000) | uint16_t(pc + 2 + int16_t((params.r8(pc+2) << 8) | params.r8(pc+1)))); + flags |= 3; + break; + + case DASM_zpb: + util::stream_format(stream, "%d $%02x, $%04x", (opcodes.r8(pc) >> 4) & 7, params.r8(pc+1), (pc & 0xf0000) | uint16_t(pc + 3 + int8_t(params.r8(pc+2)))); + flags |= 3; + break; + + case DASM_zpg: + util::stream_format(stream, " $%02x", params.r8(pc+1)); + flags |= 2; + break; + + case DASM_zpi: + util::stream_format(stream, " ($%02x)", params.r8(pc+1)); + flags |= 2; + break; + + case DASM_zpx: + util::stream_format(stream, " $%02x, x", params.r8(pc+1)); + flags |= 2; + break; + + case DASM_zpy: + util::stream_format(stream, " $%02x, y", params.r8(pc+1)); + flags |= 2; + break; + + case DASM_imz: + util::stream_format(stream, " #$%02x, $%02x", params.r8(pc+1), params.r8(pc+2)); + flags |= 3; + break; + + case DASM_spg: + util::stream_format(stream, " \\$%02x", params.r8(pc+1)); + flags |= 2; + break; + + case DASM_biz: + util::stream_format(stream, " %d, $%02x", (opcodes.r8(pc) >> 5) & 7, params.r8(pc+1)); + flags |= 2; + break; + + case DASM_bzr: + util::stream_format(stream, " %d, $%02x, $%04x", (opcodes.r8(pc) >> 5) & 7, params.r8(pc+1), (pc & 0xf0000) | uint16_t(pc + 3 + int8_t(params.r8(pc+2)))); + flags |= 3; + break; + + case DASM_bar: + util::stream_format(stream, " %d, a, $%04x", (opcodes.r8(pc) >> 5) & 7, (pc & 0xf0000) | uint16_t(pc + 3 + int8_t(params.r8(pc+1)))); + flags |= 2; + break; + + case DASM_bac: + util::stream_format(stream, " %d, a", (opcodes.r8(pc) >> 5) & 7); + flags |= 1; + break; + + default: + fprintf(stderr, "Unhandled dasm mode %d\n", e.mode); + abort(); + } + return flags; +} + +m6502_disassembler::m6502_disassembler() : m6502_base_disassembler(disasm_entries) +{ +} diff --git a/src/devices/cpu/m6502/m6502d.h b/src/devices/cpu/m6502/m6502d.h new file mode 100644 index 00000000000..7b23417f753 --- /dev/null +++ b/src/devices/cpu/m6502/m6502d.h @@ -0,0 +1,81 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + m6502d.h + + Mostek 6502, original NMOS variant, disassembler + +***************************************************************************/ + +#ifndef MAME_CPU_M6502_M6502D_H +#define MAME_CPU_M6502_M6502D_H + +#pragma once + +class m6502_base_disassembler : public util::disasm_interface +{ +public: + struct disasm_entry { + const char *opcode; + int mode; + offs_t flags; + }; + + m6502_base_disassembler(const disasm_entry *table); + virtual ~m6502_base_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +protected: + enum { + DASM_non, /* no additional arguments */ + DASM_aba, /* absolute */ + DASM_abx, /* absolute + X */ + DASM_aby, /* absolute + Y */ + DASM_acc, /* accumulator */ + DASM_adr, /* absolute address (jmp,jsr) */ + DASM_bzp, /* zero page with bit selection */ + DASM_iax, /* indirect + X (65c02 jmp) */ + DASM_idx, /* zero page pre indexed */ + DASM_idy, /* zero page post indexed */ + DASM_idz, /* zero page post indexed (65ce02) */ + DASM_imm, /* immediate */ + DASM_imp, /* implicit */ + DASM_ind, /* indirect (jmp) */ + DASM_isy, /* zero page pre indexed sp and post indexed Y (65ce02) */ + DASM_iw2, /* immediate word (65ce02) */ + DASM_iw3, /* augment (65ce02) */ + DASM_rel, /* relative */ + DASM_rw2, /* relative word (65cs02, 65ce02) */ + DASM_zpb, /* zero page and branch (65c02 bbr, bbs) */ + DASM_zpg, /* zero page */ + DASM_zpi, /* zero page indirect (65c02) */ + DASM_zpx, /* zero page + X */ + DASM_zpy, /* zero page + Y */ + DASM_imz, /* load immediate byte, store to zero page address (M740) */ + DASM_spg, /* "special page": implied FF00 OR immediate value (M740)*/ + DASM_biz, /* bit, zero page (M740) */ + DASM_bzr, /* bit, zero page, relative offset (M740) */ + DASM_bar, /* bit, accumulator, relative offset (M740) */ + DASM_bac /* bit, accumulator (M740) */ + }; + + virtual u32 get_instruction_bank() const; + +private: + const disasm_entry *table; +}; + +class m6502_disassembler : public m6502_base_disassembler +{ +public: + m6502_disassembler(); + virtual ~m6502_disassembler() = default; + +private: + static const disasm_entry disasm_entries[0x100]; +}; + +#endif diff --git a/src/devices/cpu/m6502/m6502make.py b/src/devices/cpu/m6502/m6502make.py index 8bcd85f8e21..b874b7c5ba9 100755 --- a/src/devices/cpu/m6502/m6502make.py +++ b/src/devices/cpu/m6502/m6502make.py @@ -6,7 +6,7 @@ from __future__ import print_function USAGE = """ Usage: -%s device_name {opc.lst|-} disp.lst device.inc +%s prefix {opc.lst|-} disp.lst device.inc deviced.inc """ import sys import logging @@ -59,7 +59,7 @@ def emit(f, text): print(text, file=f) FULL_PROLOG="""\ -void %(device)s::%(opcode)s_full() +void %(device)s_device::%(opcode)s_full() { """ @@ -82,7 +82,7 @@ FULL_NONE="""\ """ PARTIAL_PROLOG="""\ -void %(device)s::%(opcode)s_partial() +void %(device)s_device::%(opcode)s_partial() { switch(inst_substate) { case 0: @@ -158,7 +158,7 @@ def save_opcodes(f, device, opcodes): DO_EXEC_FULL_PROLOG="""\ -void %(device)s::do_exec_full() +void %(device)s_device::do_exec_full() { \tswitch(inst_state) { """ @@ -169,7 +169,7 @@ DO_EXEC_FULL_EPILOG="""\ """ DO_EXEC_PARTIAL_PROLOG="""\ -void %(device)s::do_exec_partial() +void %(device)s_device::do_exec_partial() { \tswitch(inst_state) { """ @@ -180,7 +180,7 @@ DO_EXEC_PARTIAL_EPILOG="""\ """ DISASM_PROLOG="""\ -const %(device)s::disasm_entry %(device)s::disasm_entries[0x%(disasm_count)x] = { +const %(device)s_disassembler::disasm_entry %(device)s_disassembler::disasm_entries[0x%(disasm_count)x] = { """ DISASM_EPILOG="""\ @@ -194,25 +194,31 @@ def save_tables(f, device, states): "disasm_count": total_states-1 } - emit(f, DO_EXEC_FULL_PROLOG % d) for n, state in enumerate(states): if state == ".": continue if n < total_states - 1: - emit(f, "\tcase 0x%02x: %s_full(); break;\n" % (n, state)) + emit(f, "\tcase 0x%02x: %s_full(); break;" % (n, state)) else: - emit(f, "\tcase %s: %s_full(); break;\n" % ("STATE_RESET", state)) + emit(f, "\tcase %s: %s_full(); break;" % ("STATE_RESET", state)) emit(f, DO_EXEC_FULL_EPILOG % d) emit(f, DO_EXEC_PARTIAL_PROLOG % d) for n, state in enumerate(states): if state == ".": continue if n < total_states - 1: - emit(f, "\tcase 0x%02x: %s_partial(); break;\n" % (n, state)) + emit(f, "\tcase 0x%02x: %s_partial(); break;" % (n, state)) else: - emit(f, "\tcase %s: %s_partial(); break;\n" % ("STATE_RESET", state)) + emit(f, "\tcase %s: %s_partial(); break;" % ("STATE_RESET", state)) emit(f, DO_EXEC_PARTIAL_EPILOG % d) +def save_dasm(f, device, states): + total_states = len(states) + + d = { "device": device, + "disasm_count": total_states-1 + } + emit(f, DISASM_PROLOG % d ) for n, state in enumerate(states): if state == ".": continue @@ -222,13 +228,13 @@ def save_tables(f, device, states): mode = tokens[-1] extra = "0" if opc in ["jsr", "bsr"]: - extra = "DASMFLAG_STEP_OVER" + extra = "STEP_OVER" elif opc in ["rts", "rti", "rtn"]: - extra = "DASMFLAG_STEP_OUT" - emit(f, '\t{ "%s", DASM_%s, %s },\n' % (opc, mode, extra)) + extra = "STEP_OUT" + emit(f, '\t{ "%s", DASM_%s, %s },' % (opc, mode, extra)) emit(f, DISASM_EPILOG % d) -def save(fname, device, opcodes, states): +def saves(fname, device, opcodes, states): logging.info("saving: %s", fname) try: f = open(fname, "w") @@ -236,12 +242,24 @@ def save(fname, device, opcodes, states): err = sys.exc_info()[1] logging.error("cannot write file %s [%s]", fname, err) sys.exit(1) - save_opcodes(f,device, opcodes) + save_opcodes(f, device, opcodes) emit(f, "\n") save_tables(f, device, states) f.close() +def saved(fname, device, opcodes, states): + logging.info("saving: %s", fname) + try: + f = open(fname, "w") + except Exception: + err = sys.exc_info()[1] + logging.error("cannot write file %s [%s]", fname, err) + sys.exit(1) + save_dasm(f, device, states) + f.close() + + def main(argv): debug = False logformat=("%(levelname)s:" @@ -255,25 +273,29 @@ def main(argv): logging.basicConfig(level=logging.WARNING, format=logformat) - if len(argv) != 5: + if len(argv) != 6: print(USAGE % argv[0]) return 1 - device_name = argv[1] + mode = argv[1] + device_name = argv[2] opcodes = [] - if argv[2] != "-": - opcodes = load_opcodes(argv[2]) + if argv[3] != "-": + opcodes = load_opcodes(argv[3]) logging.info("found %d opcodes", len(opcodes)) else: logging.info("skipping opcode reading") - states = load_disp(argv[3]) + states = load_disp(argv[4]) logging.info("loaded %s states", len(states)) assert (len(states) & 0xff) == 1 - save(argv[4], device_name, opcodes, states) + if mode == 's': + saves(argv[5], device_name, opcodes, states) + else: + saved(argv[5], device_name, opcodes, states) # ====================================================================== diff --git a/src/devices/cpu/m6502/m6509.cpp b/src/devices/cpu/m6502/m6509.cpp index 729b919fb50..e1af60eac4b 100644 --- a/src/devices/cpu/m6502/m6509.cpp +++ b/src/devices/cpu/m6502/m6509.cpp @@ -10,6 +10,7 @@ #include "emu.h" #include "m6509.h" +#include "m6509d.h" DEFINE_DEVICE_TYPE(M6509, m6509_device, "m6509", "M6509") @@ -54,12 +55,11 @@ void m6509_device::state_export(const device_state_entry &entry) } } -offs_t m6509_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *m6509_device::create_disassembler() { - return disassemble_generic(stream, pc, oprom, opram, options, disasm_entries); + return new m6509_disassembler; } - m6509_device::mi_6509_normal::mi_6509_normal(m6509_device *_base) { base = _base; diff --git a/src/devices/cpu/m6502/m6509.h b/src/devices/cpu/m6502/m6509.h index 0057f900c83..c8fa2ba937e 100644 --- a/src/devices/cpu/m6502/m6509.h +++ b/src/devices/cpu/m6502/m6509.h @@ -17,9 +17,7 @@ class m6509_device : public m6502_device { public: m6509_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - static const disasm_entry disasm_entries[0x100]; - - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void do_exec_full() override; virtual void do_exec_partial() override; diff --git a/src/devices/cpu/m6502/m6509d.cpp b/src/devices/cpu/m6502/m6509d.cpp new file mode 100644 index 00000000000..e7a27d9e1ce --- /dev/null +++ b/src/devices/cpu/m6502/m6509d.cpp @@ -0,0 +1,17 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + m6509d.cpp + + 6502 with banking and extended address bus, disassembler + +***************************************************************************/ + +#include "emu.h" +#include "m6509d.h" +#include "cpu/m6502/m6509d.hxx" + +m6509_disassembler::m6509_disassembler() : m6502_base_disassembler(disasm_entries) +{ +} diff --git a/src/devices/cpu/m6502/m6509d.h b/src/devices/cpu/m6502/m6509d.h new file mode 100644 index 00000000000..196b2d66de2 --- /dev/null +++ b/src/devices/cpu/m6502/m6509d.h @@ -0,0 +1,28 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + m6509d.h + + 6502 with banking and extended address bus, disassembler + +***************************************************************************/ + +#ifndef MAME_CPU_M6502_M6509D_H +#define MAME_CPU_M6502_M6509D_H + +#pragma once + +#include "m6502d.h" + +class m6509_disassembler : public m6502_base_disassembler +{ +public: + m6509_disassembler(); + virtual ~m6509_disassembler() = default; + +private: + static const disasm_entry disasm_entries[0x100]; +}; + +#endif diff --git a/src/devices/cpu/m6502/m6510.cpp b/src/devices/cpu/m6502/m6510.cpp index e4b4585eaaa..a8fb427210b 100644 --- a/src/devices/cpu/m6502/m6510.cpp +++ b/src/devices/cpu/m6502/m6510.cpp @@ -10,6 +10,7 @@ #include "emu.h" #include "m6510.h" +#include "m6510d.h" DEFINE_DEVICE_TYPE(M6510, m6510_device, "m6510", "M6510") @@ -33,9 +34,9 @@ void m6510_device::set_pulls(uint8_t _pullup, uint8_t _floating) floating = _floating; } -offs_t m6510_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *m6510_device::create_disassembler() { - return disassemble_generic(stream, pc, oprom, opram, options, disasm_entries); + return new m6510_disassembler; } void m6510_device::device_start() diff --git a/src/devices/cpu/m6502/m6510.h b/src/devices/cpu/m6502/m6510.h index d3819f4899f..84f2cea32c7 100644 --- a/src/devices/cpu/m6502/m6510.h +++ b/src/devices/cpu/m6502/m6510.h @@ -32,9 +32,7 @@ public: write_port.set_callback(wr); } - static const disasm_entry disasm_entries[0x100]; - - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void do_exec_full() override; virtual void do_exec_partial() override; diff --git a/src/devices/cpu/m6502/m6510d.cpp b/src/devices/cpu/m6502/m6510d.cpp new file mode 100644 index 00000000000..78be285262a --- /dev/null +++ b/src/devices/cpu/m6502/m6510d.cpp @@ -0,0 +1,17 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + m6510d.cpp + + 6502 with 6 i/o pins, also known as 8500, disassembler + +***************************************************************************/ + +#include "emu.h" +#include "m6510d.h" +#include "cpu/m6502/m6510d.hxx" + +m6510_disassembler::m6510_disassembler() : m6502_base_disassembler(disasm_entries) +{ +} diff --git a/src/devices/cpu/m6502/m6510d.h b/src/devices/cpu/m6502/m6510d.h new file mode 100644 index 00000000000..ddf94f93626 --- /dev/null +++ b/src/devices/cpu/m6502/m6510d.h @@ -0,0 +1,28 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + m6510d.h + + 6502 with 6 i/o pins, also known as 8500, disassembler + +***************************************************************************/ + +#ifndef MAME_CPU_M6502_M6510D_H +#define MAME_CPU_M6502_M6510D_H + +#pragma once + +#include "m6502d.h" + +class m6510_disassembler : public m6502_base_disassembler +{ +public: + m6510_disassembler(); + virtual ~m6510_disassembler() = default; + +private: + static const disasm_entry disasm_entries[0x100]; +}; + +#endif diff --git a/src/devices/cpu/m6502/m65c02.cpp b/src/devices/cpu/m6502/m65c02.cpp index d109cc502bf..bc79ea84231 100644 --- a/src/devices/cpu/m6502/m65c02.cpp +++ b/src/devices/cpu/m6502/m65c02.cpp @@ -11,6 +11,7 @@ #include "emu.h" #include "m65c02.h" +#include "m65c02d.h" DEFINE_DEVICE_TYPE(M65C02, m65c02_device, "m65c02", "M65C02") @@ -24,9 +25,9 @@ m65c02_device::m65c02_device(const machine_config &mconfig, device_type type, co { } -offs_t m65c02_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *m65c02_device::create_disassembler() { - return disassemble_generic(stream, pc, oprom, opram, options, disasm_entries); + return new m65c02_disassembler; } #include "cpu/m6502/m65c02.hxx" diff --git a/src/devices/cpu/m6502/m65c02.h b/src/devices/cpu/m6502/m65c02.h index 828556e5f83..c1898912b03 100644 --- a/src/devices/cpu/m6502/m65c02.h +++ b/src/devices/cpu/m6502/m65c02.h @@ -19,9 +19,7 @@ class m65c02_device : public m6502_device { public: m65c02_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - static const disasm_entry disasm_entries[0x100]; - - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void do_exec_full() override; virtual void do_exec_partial() override; diff --git a/src/devices/cpu/m6502/m65c02d.cpp b/src/devices/cpu/m6502/m65c02d.cpp new file mode 100644 index 00000000000..7a78219f129 --- /dev/null +++ b/src/devices/cpu/m6502/m65c02d.cpp @@ -0,0 +1,18 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + m65c02d.cpp + + Mostek 6502, CMOS variant with some additional instructions (but + not the bitwise ones), disassembler + +***************************************************************************/ + +#include "emu.h" +#include "m65c02d.h" +#include "cpu/m6502/m65c02d.hxx" + +m65c02_disassembler::m65c02_disassembler() : m6502_base_disassembler(disasm_entries) +{ +} diff --git a/src/devices/cpu/m6502/m65c02d.h b/src/devices/cpu/m6502/m65c02d.h new file mode 100644 index 00000000000..d9599e548bb --- /dev/null +++ b/src/devices/cpu/m6502/m65c02d.h @@ -0,0 +1,29 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + m65c02d.h + + Mostek 6502, CMOS variant with some additional instructions (but + not the bitwise ones), disassembler + +***************************************************************************/ + +#ifndef MAME_CPU_M6502_M65C02D_H +#define MAME_CPU_M6502_M65C02D_H + +#pragma once + +#include "m6502d.h" + +class m65c02_disassembler : public m6502_base_disassembler +{ +public: + m65c02_disassembler(); + virtual ~m65c02_disassembler() = default; + +private: + static const disasm_entry disasm_entries[0x100]; +}; + +#endif diff --git a/src/devices/cpu/m6502/m65ce02.cpp b/src/devices/cpu/m6502/m65ce02.cpp index 239e900ed6d..e416cfa0089 100644 --- a/src/devices/cpu/m6502/m65ce02.cpp +++ b/src/devices/cpu/m6502/m65ce02.cpp @@ -10,6 +10,7 @@ #include "emu.h" #include "m65ce02.h" +#include "m65ce02d.h" DEFINE_DEVICE_TYPE(M65CE02, m65ce02_device, "m65ce02", "M65CE02") @@ -23,9 +24,9 @@ m65ce02_device::m65ce02_device(const machine_config &mconfig, device_type type, { } -offs_t m65ce02_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *m65ce02_device::create_disassembler() { - return disassemble_generic(stream, pc, oprom, opram, options, disasm_entries); + return new m65ce02_disassembler; } void m65ce02_device::init() diff --git a/src/devices/cpu/m6502/m65ce02.h b/src/devices/cpu/m6502/m65ce02.h index 191123683f6..e3c7a440ca8 100644 --- a/src/devices/cpu/m6502/m65ce02.h +++ b/src/devices/cpu/m6502/m65ce02.h @@ -18,9 +18,7 @@ class m65ce02_device : public m65c02_device { public: m65ce02_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - static const disasm_entry disasm_entries[0x100]; - - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void do_exec_full() override; virtual void do_exec_partial() override; diff --git a/src/devices/cpu/m6502/m65ce02d.cpp b/src/devices/cpu/m6502/m65ce02d.cpp new file mode 100644 index 00000000000..f815eae4b5a --- /dev/null +++ b/src/devices/cpu/m6502/m65ce02d.cpp @@ -0,0 +1,17 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + m65ce02d.cpp + + 6502 with Z register and some more stuff, disassembler + +***************************************************************************/ + +#include "emu.h" +#include "m65ce02d.h" +#include "cpu/m6502/m65ce02d.hxx" + +m65ce02_disassembler::m65ce02_disassembler() : m6502_base_disassembler(disasm_entries) +{ +} diff --git a/src/devices/cpu/m6502/m65ce02d.h b/src/devices/cpu/m6502/m65ce02d.h new file mode 100644 index 00000000000..ea5cd8f072f --- /dev/null +++ b/src/devices/cpu/m6502/m65ce02d.h @@ -0,0 +1,28 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + m65ce02d.h + + 6502 with Z register and some more stuff, disassembler + +***************************************************************************/ + +#ifndef MAME_CPU_M6502_M65CE02D_H +#define MAME_CPU_M6502_M65CE02D_H + +#pragma once + +#include "m6502d.h" + +class m65ce02_disassembler : public m6502_base_disassembler +{ +public: + m65ce02_disassembler(); + virtual ~m65ce02_disassembler() = default; + +private: + static const disasm_entry disasm_entries[0x100]; +}; + +#endif diff --git a/src/devices/cpu/m6502/m740.cpp b/src/devices/cpu/m6502/m740.cpp index 807eac55b09..cce9289b1de 100644 --- a/src/devices/cpu/m6502/m740.cpp +++ b/src/devices/cpu/m6502/m740.cpp @@ -23,9 +23,14 @@ m740_device::m740_device(const machine_config &mconfig, device_type type, const { } -offs_t m740_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +u32 m740_device::get_state_base() const { - return disassemble_generic(stream, pc, oprom, opram, options, disasm_entries); + return inst_state_base; +} + +util::disasm_interface *m740_device::create_disassembler() +{ + return new m740_disassembler(this); } void m740_device::device_start() diff --git a/src/devices/cpu/m6502/m740.h b/src/devices/cpu/m6502/m740.h index 350ea8bced6..be7245e328c 100644 --- a/src/devices/cpu/m6502/m740.h +++ b/src/devices/cpu/m6502/m740.h @@ -12,8 +12,9 @@ #define MAME_CPU_M6502_M740_H #include "m6502.h" +#include "m740d.h" -class m740_device : public m6502_device { +class m740_device : public m6502_device, public m740_disassembler::config { public: enum { @@ -41,11 +42,9 @@ public: virtual void device_start() override; virtual void device_reset() override; - static const disasm_entry disasm_entries[0x200]; - virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void do_exec_full() override; virtual void do_exec_partial() override; virtual void execute_set_input(int inputnum, int state) override; @@ -55,6 +54,9 @@ protected: #define O(o) void o ## _full(); void o ## _partial() + u32 inst_state_base; /* Current instruction bank */ + virtual u32 get_state_base() const override; + uint8_t do_clb(uint8_t in, uint8_t bit); uint8_t do_seb(uint8_t in, uint8_t bit); uint8_t do_rrf(uint8_t in); diff --git a/src/devices/cpu/m6502/m740d.cpp b/src/devices/cpu/m6502/m740d.cpp new file mode 100644 index 00000000000..5da5ef53020 --- /dev/null +++ b/src/devices/cpu/m6502/m740d.cpp @@ -0,0 +1,22 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + m740d.cpp + + Mitsubishi M740 series (M507xx/M509xx), disassembler + +***************************************************************************/ + +#include "emu.h" +#include "m740d.h" +#include "cpu/m6502/m740d.hxx" + +m740_disassembler::m740_disassembler(config *_conf) : m6502_base_disassembler(disasm_entries), conf(_conf) +{ +} + +u32 m740_disassembler::get_instruction_bank() const +{ + return conf->get_state_base(); +} diff --git a/src/devices/cpu/m6502/m740d.h b/src/devices/cpu/m6502/m740d.h new file mode 100644 index 00000000000..80029cc56a8 --- /dev/null +++ b/src/devices/cpu/m6502/m740d.h @@ -0,0 +1,37 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + m740d.h + + Mitsubishi M740 series (M507xx/M509xx), disassembler + +***************************************************************************/ + +#ifndef MAME_CPU_M6502_M740D_H +#define MAME_CPU_M6502_M740D_H + +#pragma once + +#include "m6502d.h" + +class m740_disassembler : public m6502_base_disassembler +{ +public: + struct config { + virtual ~config() = default; + virtual u32 get_state_base() const = 0; + }; + + m740_disassembler(config *conf); + virtual ~m740_disassembler() = default; + +protected: + virtual u32 get_instruction_bank() const override; + +private: + static const disasm_entry disasm_entries[0x200]; + config *conf; +}; + +#endif diff --git a/src/devices/cpu/m6502/n2a03.cpp b/src/devices/cpu/m6502/n2a03.cpp index ca3a8a9b87b..f989d8d50f3 100644 --- a/src/devices/cpu/m6502/n2a03.cpp +++ b/src/devices/cpu/m6502/n2a03.cpp @@ -10,6 +10,7 @@ #include "emu.h" #include "n2a03.h" +#include "n2a03d.h" DEFINE_DEVICE_TYPE(N2A03, n2a03_device, "n2a03", "N2A03") @@ -56,9 +57,9 @@ n2a03_device::n2a03_device(const machine_config &mconfig, const char *tag, devic program_config.m_internal_map = ADDRESS_MAP_NAME(n2a03_map); } -offs_t n2a03_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *n2a03_device::create_disassembler() { - return disassemble_generic(stream, pc, oprom, opram, options, disasm_entries); + return new n2a03_disassembler; } void n2a03_device::device_start() diff --git a/src/devices/cpu/m6502/n2a03.h b/src/devices/cpu/m6502/n2a03.h index 0a4cf346797..42e5eac8257 100644 --- a/src/devices/cpu/m6502/n2a03.h +++ b/src/devices/cpu/m6502/n2a03.h @@ -19,9 +19,8 @@ class n2a03_device : public m6502_device { public: n2a03_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - static const disasm_entry disasm_entries[0x100]; + virtual util::disasm_interface *create_disassembler() override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; virtual void do_exec_full() override; virtual void do_exec_partial() override; virtual void device_clock_changed() override; diff --git a/src/devices/cpu/m6502/n2a03d.cpp b/src/devices/cpu/m6502/n2a03d.cpp new file mode 100644 index 00000000000..bedb062f018 --- /dev/null +++ b/src/devices/cpu/m6502/n2a03d.cpp @@ -0,0 +1,17 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + n2a03d.cpp + + 6502, NES variant, disassembler + +***************************************************************************/ + +#include "emu.h" +#include "n2a03d.h" +#include "cpu/m6502/n2a03d.hxx" + +n2a03_disassembler::n2a03_disassembler() : m6502_base_disassembler(disasm_entries) +{ +} diff --git a/src/devices/cpu/m6502/n2a03d.h b/src/devices/cpu/m6502/n2a03d.h new file mode 100644 index 00000000000..568df91c23a --- /dev/null +++ b/src/devices/cpu/m6502/n2a03d.h @@ -0,0 +1,28 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + n2a03d.h + + 6502, NES variant, disassembler + +***************************************************************************/ + +#ifndef MAME_CPU_M6502_N2A03D_H +#define MAME_CPU_M6502_N2A03D_H + +#pragma once + +#include "m6502d.h" + +class n2a03_disassembler : public m6502_base_disassembler +{ +public: + n2a03_disassembler(); + virtual ~n2a03_disassembler() = default; + +private: + static const disasm_entry disasm_entries[0x100]; +}; + +#endif diff --git a/src/devices/cpu/m6502/or65c02.lst b/src/devices/cpu/m6502/or65c02.lst new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/src/devices/cpu/m6502/or65c02.lst diff --git a/src/devices/cpu/m6502/r65c02.cpp b/src/devices/cpu/m6502/r65c02.cpp index 53c5b40b662..ab7bb936876 100644 --- a/src/devices/cpu/m6502/r65c02.cpp +++ b/src/devices/cpu/m6502/r65c02.cpp @@ -10,6 +10,7 @@ #include "emu.h" #include "r65c02.h" +#include "r65c02d.h" DEFINE_DEVICE_TYPE(R65C02, r65c02_device, "r65c02", "R65C02") @@ -23,9 +24,9 @@ r65c02_device::r65c02_device(const machine_config &mconfig, device_type type, co { } -offs_t r65c02_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *r65c02_device::create_disassembler() { - return disassemble_generic(stream, pc, oprom, opram, options, disasm_entries); + return new r65c02_disassembler; } #include "cpu/m6502/r65c02.hxx" diff --git a/src/devices/cpu/m6502/r65c02.h b/src/devices/cpu/m6502/r65c02.h index 41cea972944..d6c88417bd6 100644 --- a/src/devices/cpu/m6502/r65c02.h +++ b/src/devices/cpu/m6502/r65c02.h @@ -17,9 +17,7 @@ class r65c02_device : public m65c02_device { public: r65c02_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - static const disasm_entry disasm_entries[0x100]; - - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void do_exec_full() override; virtual void do_exec_partial() override; diff --git a/src/devices/cpu/m6502/r65c02d.cpp b/src/devices/cpu/m6502/r65c02d.cpp new file mode 100644 index 00000000000..20eae90c9bc --- /dev/null +++ b/src/devices/cpu/m6502/r65c02d.cpp @@ -0,0 +1,17 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + r65c02d.cpp + + Rockwell 65c02, CMOS variant with bitwise instructions, disassembler + +***************************************************************************/ + +#include "emu.h" +#include "r65c02d.h" +#include "cpu/m6502/r65c02d.hxx" + +r65c02_disassembler::r65c02_disassembler() : m6502_base_disassembler(disasm_entries) +{ +} diff --git a/src/devices/cpu/m6502/r65c02d.h b/src/devices/cpu/m6502/r65c02d.h new file mode 100644 index 00000000000..5f5f3a4a58a --- /dev/null +++ b/src/devices/cpu/m6502/r65c02d.h @@ -0,0 +1,28 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + r65c02d.h + + Rockwell 65c02, CMOS variant with bitwise instructions, disassembler + +***************************************************************************/ + +#ifndef MAME_CPU_M6502_R65C02D_H +#define MAME_CPU_M6502_R65C02D_H + +#pragma once + +#include "m6502d.h" + +class r65c02_disassembler : public m6502_base_disassembler +{ +public: + r65c02_disassembler(); + virtual ~r65c02_disassembler() = default; + +private: + static const disasm_entry disasm_entries[0x100]; +}; + +#endif diff --git a/src/devices/cpu/m6800/6800dasm.cpp b/src/devices/cpu/m6800/6800dasm.cpp index 781af28f468..dcd174e0cba 100644 --- a/src/devices/cpu/m6800/6800dasm.cpp +++ b/src/devices/cpu/m6800/6800dasm.cpp @@ -20,43 +20,9 @@ */ #include "emu.h" -#include "debugger.h" -#include "m6800.h" +#include "6800dasm.h" -enum addr_mode { - inh, /* inherent */ - rel, /* relative */ - imb, /* immediate (byte) */ - imw, /* immediate (word) */ - dir, /* direct address */ - imd, /* HD63701YO: immediate, direct address */ - ext, /* extended address */ - idx, /* x + byte offset */ - imx, /* HD63701YO: immediate, x + byte offset */ - sx1 /* HD63701YO: undocumented opcodes: byte from (s+1) */ -}; - -enum op_names { - aba=0, abx, adca, adcb, adda, addb, addd, aim, - anda, andb, asl, asla, aslb, asld, asr, asra, - asrb, bcc, bcs, beq, bge, bgt, bhi, bita, - bitb, ble, bls, blt, bmi, bne, bpl, bra, - brn, bsr, bvc, bvs, cba, clc, cli, clr, - clra, clrb, clv, cmpa, cmpb, cmpx, com, coma, - comb, daa, dec, deca, decb, des, dex, eim, - eora, eorb, ill, inc, inca, incb, ins, inx, - jmp, jsr, lda, ldb, ldd, lds, ldx, lsr, - lsra, lsrb, lsrd, mul, neg, nega, negb, nop, - oim, ora, orb, psha, pshb, pshx, pula, pulb, - pulx, rol, rola, rolb, ror, rora, rorb, rti, - rts, sba, sbca, sbcb, sec, sev, sta, stb, - _std, sei, sts, stx, suba, subb, subd, swi, - wai, tab, tap, tba, tim, tpa, tst, tsta, - tstb, tsx, txs, asx1, asx2, xgdx, addx, adcx, - bitx -}; - -static const char *const op_name_str[] = { +const char *const m680x_disassembler::op_name_str[] = { "aba", "abx", "adca", "adcb", "adda", "addb", "addd", "aim", "anda", "andb", "asl", "asla", "aslb", "asld", "asr", "asra", "asrb", "bcc", "bcs", "beq", "bge", "bgt", "bhi", "bita", @@ -84,7 +50,7 @@ static const char *const op_name_str[] = { * 2 invalid opcode for 1:6800/6802/6808, 2:6801/6803, 4:HD63701 */ -static const uint8_t table[0x104][3] = { +const uint8_t m680x_disassembler::table[0x104][3] = { {ill, inh,7},{nop, inh,0},{ill, inh,7},{ill, inh,7},/* 00 */ {lsrd,inh,1},{asld,inh,1},{tap, inh,0},{tpa, inh,0}, {inx, inh,0},{dex, inh,0},{clv, inh,0},{sev, inh,0}, @@ -160,20 +126,23 @@ static const uint8_t table[0x104][3] = { {stx,imx,0} }; -/* some macros to keep things short */ -#define OP oprom[0] -#define ARG1 opram[1] -#define ARG2 opram[2] -#define ARGW (opram[1]<<8) + opram[2] +m680x_disassembler::m680x_disassembler(int subtype) : m_subtype(subtype) +{ +} + +u32 m680x_disassembler::opcode_alignment() const +{ + return 1; +} -static unsigned Dasm680x (int subtype, std::ostream &stream, unsigned pc, const uint8_t *oprom, const uint8_t *opram) +offs_t m680x_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - uint32_t flags = 0; + offs_t flags = 0; int invalid_mask; - int code = OP; + int code = opcodes.r8(pc); uint8_t opcode, args, invalid; - switch( subtype ) + switch( m_subtype ) { case 6800: case 6802: case 6808: case 8105: invalid_mask = 1; @@ -186,14 +155,14 @@ static unsigned Dasm680x (int subtype, std::ostream &stream, unsigned pc, const } /* NSC-8105 is a special case */ - if (subtype == 8105) + if (m_subtype == 8105) { /* swap bits */ code = (code & 0x3c) | ((code & 0x41) << 1) | ((code & 0x82) >> 1); /* and check for extra instruction */ - if (code == 0xfc) code = 0x0100; - if (code == 0xec) code = 0x0101; + if (code == 0xfc) code = 0x0100; + if (code == 0xec) code = 0x0101; if (code == 0x7b) code = 0x0102; if (code == 0x71) code = 0x0103; } @@ -203,14 +172,14 @@ static unsigned Dasm680x (int subtype, std::ostream &stream, unsigned pc, const invalid = table[code][2]; if (opcode == bsr || opcode == jsr) - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; else if (opcode == rti || opcode == rts) - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; if ( invalid & invalid_mask ) /* invalid for this cpu type ? */ { stream << "illegal"; - return 1 | flags | DASMFLAG_SUPPORTED; + return 1 | flags | SUPPORTED; } util::stream_format(stream, "%-5s", op_name_str[opcode]); @@ -218,73 +187,33 @@ static unsigned Dasm680x (int subtype, std::ostream &stream, unsigned pc, const switch( args ) { case rel: /* relative */ - util::stream_format(stream, "$%04X", pc + (int8_t)ARG1 + 2); - return 2 | flags | DASMFLAG_SUPPORTED; + util::stream_format(stream, "$%04X", pc + (int8_t)params.r8(pc+1) + 2); + return 2 | flags | SUPPORTED; case imb: /* immediate (byte) */ - util::stream_format(stream, "#$%02X", ARG1); - return 2 | flags | DASMFLAG_SUPPORTED; + util::stream_format(stream, "#$%02X", params.r8(pc+1)); + return 2 | flags | SUPPORTED; case imw: /* immediate (word) */ - util::stream_format(stream, "#$%04X", ARGW); - return 3 | flags | DASMFLAG_SUPPORTED; + util::stream_format(stream, "#$%04X", params.r16(pc+1)); + return 3 | flags | SUPPORTED; case idx: /* indexed + byte offset */ - util::stream_format(stream, "(x+$%02X)", ARG1); - return 2 | flags | DASMFLAG_SUPPORTED; + util::stream_format(stream, "(x+$%02X)", params.r8(pc+1)); + return 2 | flags | SUPPORTED; case imx: /* immediate, indexed + byte offset */ - util::stream_format(stream, "#$%02X,(x+$%02x)", ARG1, ARG2); - return 3 | flags | DASMFLAG_SUPPORTED; + util::stream_format(stream, "#$%02X,(x+$%02x)", params.r8(pc+1), params.r8(pc+2)); + return 3 | flags | SUPPORTED; case dir: /* direct address */ - util::stream_format(stream, "$%02X", ARG1); - return 2 | flags | DASMFLAG_SUPPORTED; + util::stream_format(stream, "$%02X", params.r8(pc+1)); + return 2 | flags | SUPPORTED; case imd: /* immediate, direct address */ - util::stream_format(stream, "#$%02X,$%02X", ARG1, ARG2); - return 3 | flags | DASMFLAG_SUPPORTED; + util::stream_format(stream, "#$%02X,$%02X", params.r8(pc+1), params.r8(pc+2)); + return 3 | flags | SUPPORTED; case ext: /* extended address */ - util::stream_format(stream, "$%04X", ARGW); - return 3 | flags | DASMFLAG_SUPPORTED; + util::stream_format(stream, "$%04X", params.r16(pc+1)); + return 3 | flags | SUPPORTED; case sx1: /* byte from address (s + 1) */ util::stream_format(stream, "(s+1)"); - return 1 | flags | DASMFLAG_SUPPORTED; + return 1 | flags | SUPPORTED; default: - return 1 | flags | DASMFLAG_SUPPORTED; + return 1 | flags | SUPPORTED; } } - -CPU_DISASSEMBLE( m6800 ) -{ - return Dasm680x(6800,stream,pc,oprom,opram); -} - -CPU_DISASSEMBLE( m6801 ) -{ - return Dasm680x(6801,stream,pc,oprom,opram); -} - -CPU_DISASSEMBLE( m6802 ) -{ - return Dasm680x(6802,stream,pc,oprom,opram); -} - -CPU_DISASSEMBLE( m6803 ) -{ - return Dasm680x(6803,stream,pc,oprom,opram); -} - -CPU_DISASSEMBLE( m6808 ) -{ - return Dasm680x(6808,stream,pc,oprom,opram); -} - -CPU_DISASSEMBLE( hd6301 ) -{ - return Dasm680x(6301,stream,pc,oprom,opram); -} - -CPU_DISASSEMBLE( hd63701 ) -{ - return Dasm680x(63701,stream,pc,oprom,opram); -} - -CPU_DISASSEMBLE( nsc8105 ) -{ - return Dasm680x(8105,stream,pc,oprom,opram); -} diff --git a/src/devices/cpu/m6800/6800dasm.h b/src/devices/cpu/m6800/6800dasm.h new file mode 100644 index 00000000000..a535e1299c0 --- /dev/null +++ b/src/devices/cpu/m6800/6800dasm.h @@ -0,0 +1,76 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +/* + * A quick-hack 6803/6808 disassembler + * + * Note: this is not the good and proper way to disassemble anything, but it works + * + * I'm afraid to put my name on it, but I feel obligated: + * This code written by Aaron Giles (agiles@sirius.com) for the MAME project + * + * History: + * 990314 HJB + * The disassembler knows about valid opcodes for M6800/1/2/3/8 and HD63701. + * 990302 HJB + * Changed the string array into a table of opcode names (or tokens) and + * argument types. This second try should give somewhat better results. + * Named the undocumented HD63701YO opcodes $12 and $13 'asx1' and 'asx2', + * since 'add contents of stack to x register' is what they do. + * + */ + +#ifndef MAME_CPU_M6800_6800DASM_H +#define MAME_CPU_M6800_6800DASM_H + +#pragma once + +class m680x_disassembler : public util::disasm_interface +{ +public: + m680x_disassembler(int subtype); + virtual ~m680x_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum addr_mode { + inh, /* inherent */ + rel, /* relative */ + imb, /* immediate (byte) */ + imw, /* immediate (word) */ + dir, /* direct address */ + imd, /* HD63701YO: immediate, direct address */ + ext, /* extended address */ + idx, /* x + byte offset */ + imx, /* HD63701YO: immediate, x + byte offset */ + sx1 /* HD63701YO: undocumented opcodes: byte from (s+1) */ + }; + + enum op_names { + aba=0, abx, adca, adcb, adda, addb, addd, aim, + anda, andb, asl, asla, aslb, asld, asr, asra, + asrb, bcc, bcs, beq, bge, bgt, bhi, bita, + bitb, ble, bls, blt, bmi, bne, bpl, bra, + brn, bsr, bvc, bvs, cba, clc, cli, clr, + clra, clrb, clv, cmpa, cmpb, cmpx, com, coma, + comb, daa, dec, deca, decb, des, dex, eim, + eora, eorb, ill, inc, inca, incb, ins, inx, + jmp, jsr, lda, ldb, ldd, lds, ldx, lsr, + lsra, lsrb, lsrd, mul, neg, nega, negb, nop, + oim, ora, orb, psha, pshb, pshx, pula, pulb, + pulx, rol, rola, rolb, ror, rora, rorb, rti, + rts, sba, sbca, sbcb, sec, sev, sta, stb, + _std, sei, sts, stx, suba, subb, subd, swi, + wai, tab, tap, tba, tim, tpa, tst, tsta, + tstb, tsx, txs, asx1, asx2, xgdx, addx, adcx, + bitx + }; + + static const char *const op_name_str[]; + static const uint8_t table[0x104][3]; + + int m_subtype; +}; + +#endif diff --git a/src/devices/cpu/m6800/m6800.cpp b/src/devices/cpu/m6800/m6800.cpp index c640a5ce3f2..856172ee368 100644 --- a/src/devices/cpu/m6800/m6800.cpp +++ b/src/devices/cpu/m6800/m6800.cpp @@ -464,9 +464,9 @@ void m6800_cpu_device::EAT_CYCLES() void m6800_cpu_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_decrypted_opcodes = has_space(AS_OPCODES) ? &space(AS_OPCODES) : m_program; - m_decrypted_opcodes_direct = &m_decrypted_opcodes->direct(); + m_decrypted_opcodes_direct = m_decrypted_opcodes->direct<0>(); m_pc.d = 0; m_s.d = 0; @@ -579,30 +579,22 @@ void m6800_cpu_device::execute_run() } while( m_icount>0 ); } - -offs_t m6800_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *m6800_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( m6800 ); - return CPU_DISASSEMBLE_NAME(m6800)(this, stream, pc, oprom, opram, options); + return new m680x_disassembler(6800); } - -offs_t m6802_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *m6802_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( m6802 ); - return CPU_DISASSEMBLE_NAME(m6802)(this, stream, pc, oprom, opram, options); + return new m680x_disassembler(6802); } - -offs_t m6808_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *m6808_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( m6808 ); - return CPU_DISASSEMBLE_NAME(m6808)(this, stream, pc, oprom, opram, options); + return new m680x_disassembler(6808); } - -offs_t nsc8105_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *nsc8105_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( nsc8105 ); - return CPU_DISASSEMBLE_NAME(nsc8105)(this, stream, pc, oprom, opram, options); + return new m680x_disassembler(8105); } diff --git a/src/devices/cpu/m6800/m6800.h b/src/devices/cpu/m6800/m6800.h index d541deba9ac..38679e32e2b 100644 --- a/src/devices/cpu/m6800/m6800.h +++ b/src/devices/cpu/m6800/m6800.h @@ -7,6 +7,7 @@ #pragma once +#include "6800dasm.h" enum { @@ -65,9 +66,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 4; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; address_space_config m_program_config; address_space_config m_decrypted_opcodes_config; @@ -86,7 +85,7 @@ protected: /* Memory spaces */ address_space *m_program, *m_decrypted_opcodes; - direct_read_data *m_direct, *m_decrypted_opcodes_direct; + direct_read_data<0> *m_direct, *m_decrypted_opcodes_direct; const op_func *m_insn; const uint8_t *m_cycles; /* clock cycle of instruction table */ @@ -374,7 +373,7 @@ protected: virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const override { return (clocks + 4 - 1) / 4; } virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const override { return (cycles * 4); } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; }; @@ -384,7 +383,7 @@ public: m6808_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); protected: - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; }; @@ -394,7 +393,7 @@ public: nsc8105_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); protected: - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; }; diff --git a/src/devices/cpu/m6800/m6801.cpp b/src/devices/cpu/m6800/m6801.cpp index 87e2ce5e47c..3a32726e345 100644 --- a/src/devices/cpu/m6800/m6801.cpp +++ b/src/devices/cpu/m6800/m6801.cpp @@ -1259,32 +1259,24 @@ void m6801_cpu_device::m6801_clock_serial() } } - -offs_t m6801_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *m6801_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( m6801 ); - return CPU_DISASSEMBLE_NAME(m6801)(this, stream, pc, oprom, opram, options); + return new m680x_disassembler(6801); } - -offs_t m6803_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *m6803_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( m6803 ); - return CPU_DISASSEMBLE_NAME(m6803)(this, stream, pc, oprom, opram, options); + return new m680x_disassembler(6803); } - -offs_t hd6301_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *hd6301_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( hd6301 ); - return CPU_DISASSEMBLE_NAME(hd6301)(this, stream, pc, oprom, opram, options); + return new m680x_disassembler(6301); } - -offs_t hd63701_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *hd63701_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( hd63701 ); - return CPU_DISASSEMBLE_NAME(hd63701)(this, stream, pc, oprom, opram, options); + return new m680x_disassembler(63701); } void hd63701_cpu_device::TAKE_TRAP() diff --git a/src/devices/cpu/m6800/m6801.h b/src/devices/cpu/m6800/m6801.h index 3d2098d1f94..f071e3d75c5 100644 --- a/src/devices/cpu/m6800/m6801.h +++ b/src/devices/cpu/m6800/m6801.h @@ -87,7 +87,7 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; address_space_config m_io_config; @@ -158,7 +158,7 @@ public: m6803_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); protected: - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; }; @@ -170,7 +170,7 @@ public: protected: hd6301_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; }; @@ -180,7 +180,7 @@ public: hd63701_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); protected: - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void TAKE_TRAP() override; }; diff --git a/src/devices/cpu/m68000/m68000.h b/src/devices/cpu/m68000/m68000.h index 776f097967c..a6a885d6f54 100644 --- a/src/devices/cpu/m68000/m68000.h +++ b/src/devices/cpu/m68000/m68000.h @@ -110,8 +110,6 @@ enum M68K_FPSR, M68K_FPCR }; -unsigned int m68k_disassemble_raw(std::ostream &stream, unsigned int pc, const unsigned char* opdata, const unsigned char* argdata, unsigned int cpu_type); - class m68000_base_device; @@ -129,12 +127,8 @@ public: void clear_all(void); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 10; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; - - - + // device_disasm_interface overrides + virtual util::disasm_interface *create_disassembler() override; // device_execute_interface overrides virtual uint32_t execute_min_cycles() const override { return 4; }; @@ -318,7 +312,7 @@ public: // m68k_memory_interface memory; address_space *m_space, *m_ospace; - direct_read_data *m_direct, *m_odirect; + direct_read_data<0> *m_direct, *m_odirect; uint32_t iotemp; @@ -407,9 +401,7 @@ public: m68000_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 10; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 4; }; virtual uint32_t execute_max_cycles() const override { return 158; }; @@ -432,9 +424,7 @@ public: // construction/destruction m68301_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 10; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 4; }; virtual uint32_t execute_max_cycles() const override { return 158; }; @@ -454,9 +444,7 @@ public: // construction/destruction m68008_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 10; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 4; }; virtual uint32_t execute_max_cycles() const override { return 158; }; @@ -473,9 +461,7 @@ public: // construction/destruction m68008plcc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 10; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 4; }; virtual uint32_t execute_max_cycles() const override { return 158; }; @@ -492,9 +478,7 @@ public: // construction/destruction m68010_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 10; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 4; }; virtual uint32_t execute_max_cycles() const override { return 158; }; @@ -511,9 +495,7 @@ public: // construction/destruction m68ec020_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 20; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 2; }; virtual uint32_t execute_max_cycles() const override { return 158; }; @@ -530,9 +512,7 @@ public: // construction/destruction m68020_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 20; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 2; }; virtual uint32_t execute_max_cycles() const override { return 158; }; @@ -549,9 +529,7 @@ public: // construction/destruction m68020fpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 20; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 2; }; virtual uint32_t execute_max_cycles() const override { return 158; }; @@ -568,9 +546,7 @@ public: // construction/destruction m68020pmmu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 20; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 2; }; virtual uint32_t execute_max_cycles() const override { return 158; }; @@ -587,9 +563,7 @@ public: // construction/destruction m68020hmmu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 20; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 2; }; virtual uint32_t execute_max_cycles() const override { return 158; }; @@ -608,9 +582,7 @@ public: // construction/destruction m68ec030_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 20; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 2; }; virtual uint32_t execute_max_cycles() const override { return 158; }; @@ -627,9 +599,7 @@ public: // construction/destruction m68030_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 20; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 2; }; virtual uint32_t execute_max_cycles() const override { return 158; }; @@ -646,9 +616,7 @@ public: // construction/destruction m68ec040_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 20; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 2; }; virtual uint32_t execute_max_cycles() const override { return 158; }; @@ -665,9 +633,7 @@ public: // construction/destruction m68lc040_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 20; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 2; }; virtual uint32_t execute_max_cycles() const override { return 158; }; @@ -684,9 +650,7 @@ public: // construction/destruction m68040_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 20; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 2; }; virtual uint32_t execute_max_cycles() const override { return 158; }; @@ -703,9 +667,7 @@ public: // construction/destruction scc68070_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 10; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 4; }; virtual uint32_t execute_max_cycles() const override { return 158; }; @@ -725,9 +687,7 @@ public: // construction/destruction fscpu32_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 20; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 2; }; virtual uint32_t execute_max_cycles() const override { return 158; }; @@ -750,9 +710,7 @@ public: // construction/destruction mcf5206e_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 20; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 2; }; virtual uint32_t execute_max_cycles() const override { return 158; }; diff --git a/src/devices/cpu/m68000/m68kcpu.cpp b/src/devices/cpu/m68000/m68kcpu.cpp index c4199ecdf15..e387f946784 100644 --- a/src/devices/cpu/m68000/m68kcpu.cpp +++ b/src/devices/cpu/m68000/m68kcpu.cpp @@ -31,6 +31,7 @@ static const char copyright_notice[] = #include "m68kfpu.hxx" #include "m68kmmu.h" +#include "m68kdasm.h" extern void m68040_fpu_op0(m68000_base_device *m68k); extern void m68040_fpu_op1(m68000_base_device *m68k); @@ -1235,9 +1236,9 @@ uint16_t m68000_base_device::m68008_read_immediate_16(offs_t address) void m68000_base_device::init8(address_space &space, address_space &ospace) { m_space = &space; - m_direct = &space.direct(); + m_direct = space.direct<0>(); m_ospace = &ospace; - m_odirect = &ospace.direct(); + m_odirect = ospace.direct<0>(); // m_cpustate = this; opcode_xor = 0; @@ -1274,9 +1275,9 @@ void m68000_base_device::m68000_write_byte(offs_t address, uint8_t data) void m68000_base_device::init16(address_space &space, address_space &ospace) { m_space = &space; - m_direct = &space.direct(); + m_direct = space.direct<0>(); m_ospace = &ospace; - m_odirect = &ospace.direct(); + m_odirect = ospace.direct<0>(); opcode_xor = 0; @@ -1301,9 +1302,9 @@ void m68000_base_device::init16(address_space &space, address_space &ospace) void m68000_base_device::init32(address_space &space, address_space &ospace) { m_space = &space; - m_direct = &space.direct(); + m_direct = space.direct<0>(); m_ospace = &ospace; - m_odirect = &ospace.direct(); + m_odirect = ospace.direct<0>(); opcode_xor = WORD_XOR_BE(0); readimm16 = m68k_readimm16_delegate(&m68000_base_device::read_immediate_16, this); @@ -1520,9 +1521,9 @@ void m68000_base_device::writelong_d32_mmu(offs_t address, uint32_t data) void m68000_base_device::init32mmu(address_space &space, address_space &ospace) { m_space = &space; - m_direct = &space.direct(); + m_direct = space.direct<0>(); m_ospace = &ospace; - m_odirect = &ospace.direct(); + m_odirect = ospace.direct<0>(); opcode_xor = WORD_XOR_BE(0); readimm16 = m68k_readimm16_delegate(&m68000_base_device::read_immediate_16_mmu, this); @@ -1648,9 +1649,9 @@ void m68000_base_device::writelong_d32_hmmu(offs_t address, uint32_t data) void m68000_base_device::init32hmmu(address_space &space, address_space &ospace) { m_space = &space; - m_direct = &space.direct(); + m_direct = space.direct<0>(); m_ospace = &ospace; - m_odirect = &ospace.direct(); + m_odirect = ospace.direct<0>(); opcode_xor = WORD_XOR_BE(0); readimm16 = m68k_readimm16_delegate(&m68000_base_device::read_immediate_16_hmmu, this); @@ -1714,6 +1715,7 @@ void m68000_base_device::define_state(void) state_add(M68K_USP, "USP", iotemp).callimport().callexport(); if (cpu_type & MASK_020_OR_LATER) state_add(M68K_MSP, "MSP", iotemp).callimport().callexport(); + state_add(M68K_SR, "SR", iotemp).noshow().callimport().callexport(); for (int regnum = 0; regnum < 8; regnum++) { state_add(M68K_D0 + regnum, string_format("D%d", regnum).c_str(), dar[regnum]); @@ -2133,80 +2135,100 @@ void m68000_base_device::init_cpu_coldfire(void) define_state(); } -CPU_DISASSEMBLE( dasm_m68000 ) +util::disasm_interface *m68000_base_device::create_disassembler() { - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_68000); + return new m68k_disassembler(m68k_disassembler::TYPE_68000); } -CPU_DISASSEMBLE( dasm_m68008 ) +util::disasm_interface *m68000_device::create_disassembler() { - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_68008); + return new m68k_disassembler(m68k_disassembler::TYPE_68000); } -CPU_DISASSEMBLE( dasm_m68010 ) +util::disasm_interface *m68301_device::create_disassembler() { - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_68010); + return new m68k_disassembler(m68k_disassembler::TYPE_68000); } -CPU_DISASSEMBLE( dasm_m68020 ) +util::disasm_interface *m68008_device::create_disassembler() { - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_68020); + return new m68k_disassembler(m68k_disassembler::TYPE_68008); } -CPU_DISASSEMBLE( dasm_m68030 ) +util::disasm_interface *m68008plcc_device::create_disassembler() { - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_68030); + return new m68k_disassembler(m68k_disassembler::TYPE_68008); } -CPU_DISASSEMBLE( dasm_m68ec030 ) +util::disasm_interface *m68010_device::create_disassembler() { - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_68EC030); + return new m68k_disassembler(m68k_disassembler::TYPE_68010); } -CPU_DISASSEMBLE( dasm_m68040 ) +util::disasm_interface *m68ec020_device::create_disassembler() { - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_68040); + return new m68k_disassembler(m68k_disassembler::TYPE_68020); } -CPU_DISASSEMBLE( dasm_m68ec040 ) +util::disasm_interface *m68020_device::create_disassembler() { - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_68EC040); + return new m68k_disassembler(m68k_disassembler::TYPE_68020); } -CPU_DISASSEMBLE( dasm_m68lc040 ) +util::disasm_interface *m68020fpu_device::create_disassembler() { - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_68LC040); + return new m68k_disassembler(m68k_disassembler::TYPE_68020); } -CPU_DISASSEMBLE( dasm_fscpu32 ) +util::disasm_interface *m68020pmmu_device::create_disassembler() { - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_FSCPU32); + return new m68k_disassembler(m68k_disassembler::TYPE_68020); } -CPU_DISASSEMBLE( dasm_coldfire ) +util::disasm_interface *m68020hmmu_device::create_disassembler() { - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_COLDFIRE); + return new m68k_disassembler(m68k_disassembler::TYPE_68020); } -offs_t m68000_base_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_m68000)(this, stream, pc, oprom, opram, options); } -offs_t m68000_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_m68000)(this, stream, pc, oprom, opram, options); } -offs_t m68301_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_m68000)(this, stream, pc, oprom, opram, options); } -offs_t m68008_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_m68008)(this, stream, pc, oprom, opram, options); } -offs_t m68008plcc_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_m68008)(this, stream, pc, oprom, opram, options); } -offs_t m68010_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_m68010)(this, stream, pc, oprom, opram, options); } -offs_t m68ec020_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_m68020)(this, stream, pc, oprom, opram, options); } -offs_t m68020_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_m68020)(this, stream, pc, oprom, opram, options); } -offs_t m68020fpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_m68020)(this, stream, pc, oprom, opram, options); } -offs_t m68020pmmu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_m68020)(this, stream, pc, oprom, opram, options); } -offs_t m68020hmmu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_m68020)(this, stream, pc, oprom, opram, options); } -offs_t m68ec030_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_m68ec030)(this, stream, pc, oprom, opram, options); } -offs_t m68030_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_m68030)(this, stream, pc, oprom, opram, options); } -offs_t m68ec040_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_m68ec040)(this, stream, pc, oprom, opram, options); } -offs_t m68lc040_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_m68lc040)(this, stream, pc, oprom, opram, options); } -offs_t m68040_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_m68040)(this, stream, pc, oprom, opram, options); } -offs_t scc68070_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_m68000)(this, stream, pc, oprom, opram, options); } -offs_t fscpu32_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_fscpu32)(this, stream, pc, oprom, opram, options); } -offs_t mcf5206e_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_coldfire)(this, stream, pc, oprom, opram, options); } +util::disasm_interface *m68ec030_device::create_disassembler() +{ + return new m68k_disassembler(m68k_disassembler::TYPE_68030); +} + +util::disasm_interface *m68030_device::create_disassembler() +{ + return new m68k_disassembler(m68k_disassembler::TYPE_68030); +} + +util::disasm_interface *m68ec040_device::create_disassembler() +{ + return new m68k_disassembler(m68k_disassembler::TYPE_68040); +} + +util::disasm_interface *m68lc040_device::create_disassembler() +{ + return new m68k_disassembler(m68k_disassembler::TYPE_68040); +} + +util::disasm_interface *m68040_device::create_disassembler() +{ + return new m68k_disassembler(m68k_disassembler::TYPE_68040); +} + +util::disasm_interface *scc68070_device::create_disassembler() +{ + return new m68k_disassembler(m68k_disassembler::TYPE_68000); +} + +util::disasm_interface *fscpu32_device::create_disassembler() +{ + return new m68k_disassembler(m68k_disassembler::TYPE_68340); +} + +util::disasm_interface *mcf5206e_device::create_disassembler() +{ + return new m68k_disassembler(m68k_disassembler::TYPE_COLDFIRE); +} /* Service an interrupt request and start exception processing */ diff --git a/src/devices/cpu/m68000/m68kcpu.h b/src/devices/cpu/m68000/m68kcpu.h index df2a754a13f..dce0c2205a8 100644 --- a/src/devices/cpu/m68000/m68kcpu.h +++ b/src/devices/cpu/m68000/m68kcpu.h @@ -1672,8 +1672,24 @@ static inline void m68ki_exception_address_error(m68000_base_device *m68k) } m68k->run_mode = RUN_MODE_BERR_AERR_RESET; - /* Note: This is implemented for 68000 only! */ - m68ki_stack_frame_buserr(m68k, sr); + if (!CPU_TYPE_IS_010_PLUS(m68k->cpu_type)) + { + /* Note: This is implemented for 68000 only! */ + m68ki_stack_frame_buserr(m68k, sr); + } + else if (CPU_TYPE_IS_010(m68k->cpu_type)) + { + /* only the 68010 throws this unique type-1000 frame */ + m68ki_stack_frame_1000(m68k, REG_PPC(m68k), sr, EXCEPTION_BUS_ERROR); + } + else if (m68k->mmu_tmp_buserror_address == REG_PPC(m68k)) + { + m68ki_stack_frame_1010(m68k, sr, EXCEPTION_BUS_ERROR, REG_PPC(m68k), m68k->mmu_tmp_buserror_address); + } + else + { + m68ki_stack_frame_1011(m68k, sr, EXCEPTION_BUS_ERROR, REG_PPC(m68k), m68k->mmu_tmp_buserror_address); + } m68ki_jump_vector(m68k, EXCEPTION_ADDRESS_ERROR); diff --git a/src/devices/cpu/m68000/m68kdasm.cpp b/src/devices/cpu/m68000/m68kdasm.cpp index 5bd074f731e..73850c1b082 100644 --- a/src/devices/cpu/m68000/m68kdasm.cpp +++ b/src/devices/cpu/m68000/m68kdasm.cpp @@ -18,640 +18,321 @@ /* ================================ INCLUDES ============================== */ /* ======================================================================== */ -#define m68ki_cpu_core void #include "emu.h" -#include "m68000.h" +#include "m68kdasm.h" -#ifndef DECL_SPEC -#define DECL_SPEC -#endif - -/* ======================================================================== */ -/* ============================ GENERAL DEFINES =========================== */ -/* ======================================================================== */ - -/* unsigned int and int must be at least 32 bits wide */ -#undef uint32_t -#define uint32_t unsigned int - -/* Bit Isolation Functions */ -#define BIT_0(A) ((A) & 0x00000001) -#define BIT_1(A) ((A) & 0x00000002) -#define BIT_2(A) ((A) & 0x00000004) -#define BIT_3(A) ((A) & 0x00000008) -#define BIT_4(A) ((A) & 0x00000010) -#define BIT_5(A) ((A) & 0x00000020) -#define BIT_6(A) ((A) & 0x00000040) -#define BIT_7(A) ((A) & 0x00000080) -#define BIT_8(A) ((A) & 0x00000100) -#define BIT_9(A) ((A) & 0x00000200) -#define BIT_A(A) ((A) & 0x00000400) -#define BIT_B(A) ((A) & 0x00000800) -#define BIT_C(A) ((A) & 0x00001000) -#define BIT_D(A) ((A) & 0x00002000) -#define BIT_E(A) ((A) & 0x00004000) -#define BIT_F(A) ((A) & 0x00008000) -#define BIT_10(A) ((A) & 0x00010000) -#define BIT_11(A) ((A) & 0x00020000) -#define BIT_12(A) ((A) & 0x00040000) -#define BIT_13(A) ((A) & 0x00080000) -#define BIT_14(A) ((A) & 0x00100000) -#define BIT_15(A) ((A) & 0x00200000) -#define BIT_16(A) ((A) & 0x00400000) -#define BIT_17(A) ((A) & 0x00800000) -#define BIT_18(A) ((A) & 0x01000000) -#define BIT_19(A) ((A) & 0x02000000) -#define BIT_1A(A) ((A) & 0x04000000) -#define BIT_1B(A) ((A) & 0x08000000) -#define BIT_1C(A) ((A) & 0x10000000) -#define BIT_1D(A) ((A) & 0x20000000) -#define BIT_1E(A) ((A) & 0x40000000) -#define BIT_1F(A) ((A) & 0x80000000) - -/* These are the CPU types understood by this disassembler */ -#define TYPE_68000 1 -#define TYPE_68008 2 -#define TYPE_68010 4 -#define TYPE_68020 8 -#define TYPE_68030 16 -#define TYPE_68040 32 -#define TYPE_68340 64 // (CPU32) -#define TYPE_COLDFIRE 128 - -#define M68000_ONLY (TYPE_68000 | TYPE_68008) - -#define M68010_ONLY TYPE_68010 -#define M68010_LESS (TYPE_68000 | TYPE_68008 | TYPE_68010) -#define M68010_PLUS (TYPE_68010 | TYPE_68020 | TYPE_68030 | TYPE_68040 | TYPE_68340 | TYPE_COLDFIRE) - -#define M68020_ONLY (TYPE_68020 | TYPE_68340) -#define M68020_LESS (TYPE_68010 | TYPE_68020 | TYPE_68340) -#define M68020_PLUS (TYPE_68020 | TYPE_68030 | TYPE_68040 | TYPE_68340 | TYPE_COLDFIRE) - -#define M68030_ONLY TYPE_68030 -#define M68030_LESS (TYPE_68010 | TYPE_68020 | TYPE_68030 | TYPE_68340 ) -#define M68030_PLUS (TYPE_68030 | TYPE_68040) - -#define M68040_PLUS TYPE_68040 - -#define COLDFIRE TYPE_COLDFIRE - -/* Extension word formats */ -#define EXT_8BIT_DISPLACEMENT(A) ((A)&0xff) -#define EXT_FULL(A) BIT_8(A) -#define EXT_EFFECTIVE_ZERO(A) (((A)&0xe4) == 0xc4 || ((A)&0xe2) == 0xc0) -#define EXT_BASE_REGISTER_PRESENT(A) (!BIT_7(A)) -#define EXT_INDEX_REGISTER_PRESENT(A) (!BIT_6(A)) -#define EXT_INDEX_REGISTER(A) (((A)>>12)&7) -#define EXT_INDEX_PRE_POST(A) (EXT_INDEX_PRESENT(A) && (A)&3) -#define EXT_INDEX_PRE(A) (EXT_INDEX_PRESENT(A) && ((A)&7) < 4 && ((A)&7) != 0) -#define EXT_INDEX_POST(A) (EXT_INDEX_PRESENT(A) && ((A)&7) > 4) -#define EXT_INDEX_SCALE(A) (((A)>>9)&3) -#define EXT_INDEX_LONG(A) BIT_B(A) -#define EXT_INDEX_AR(A) BIT_F(A) -#define EXT_BASE_DISPLACEMENT_PRESENT(A) (((A)&0x30) > 0x10) -#define EXT_BASE_DISPLACEMENT_WORD(A) (((A)&0x30) == 0x20) -#define EXT_BASE_DISPLACEMENT_LONG(A) (((A)&0x30) == 0x30) -#define EXT_OUTER_DISPLACEMENT_PRESENT(A) (((A)&3) > 1 && ((A)&0x47) < 0x44) -#define EXT_OUTER_DISPLACEMENT_WORD(A) (((A)&3) == 2 && ((A)&0x47) < 0x44) -#define EXT_OUTER_DISPLACEMENT_LONG(A) (((A)&3) == 3 && ((A)&0x47) < 0x44) - - -/* Opcode flags */ -#define SET_OPCODE_FLAGS(x) g_opcode_type = x; -#define COMBINE_OPCODE_FLAGS(x) ((x) | g_opcode_type | DASMFLAG_SUPPORTED) - - -/* ======================================================================== */ -/* =============================== PROTOTYPES ============================= */ -/* ======================================================================== */ - -/* Read data at the PC and increment PC */ -uint32_t read_imm_8(void); -uint32_t read_imm_16(void); -uint32_t read_imm_32(void); - -/* Read data at the PC but don't imcrement the PC */ -uint32_t peek_imm_8(void); -uint32_t peek_imm_16(void); -uint32_t peek_imm_32(void); - -/* make signed integers 100% portably */ -static int make_int_8(int value); -static int make_int_16(int value); -static int make_int_32(int value); - -/* make a string of a hex value */ -static char* make_signed_hex_str_8(uint32_t val); -static char* make_signed_hex_str_16(uint32_t val); -static char* make_signed_hex_str_32(uint32_t val); - -/* make string of ea mode */ -static char* get_ea_mode_str(uint32_t instruction, uint32_t size); - -char* get_ea_mode_str_8(uint32_t instruction); -char* get_ea_mode_str_16(uint32_t instruction); -char* get_ea_mode_str_32(uint32_t instruction); - -/* make string of immediate value */ -static char* get_imm_str_s(uint32_t size); -static char* get_imm_str_u(uint32_t size); - -char* get_imm_str_s8(void); -char* get_imm_str_s16(void); -char* get_imm_str_s32(void); - -/* Stuff to build the opcode handler jump table */ -static void build_opcode_table(void); -static int valid_ea(uint32_t opcode, uint32_t mask); -static int DECL_SPEC compare_nof_true_bits(const void *aptr, const void *bptr); - -/* used to build opcode handler jump table */ -struct opcode_struct -{ - void (*opcode_handler)(void); /* handler function */ - uint32_t mask; /* mask on opcode */ - uint32_t match; /* what to match after masking */ - uint32_t ea_mask; /* what ea modes are allowed */ -}; - - - -/* ======================================================================== */ -/* ================================= DATA ================================= */ -/* ======================================================================== */ - -/* Opcode handler jump table */ -static void (*g_instruction_table[0x10000])(void); -/* Flag if disassembler initialized */ -static int g_initialized = 0; - -static char g_dasm_str[100]; /* string to hold disassembly */ -static char g_helper_str[100]; /* string to hold helpful info */ -static uint32_t g_cpu_pc; /* program counter */ -static uint32_t g_cpu_ir; /* instruction register */ -static uint32_t g_cpu_type; -static uint32_t g_opcode_type; -static const unsigned char* g_rawop; -static uint32_t g_rawbasepc; - -/* used by ops like asr, ror, addq, etc */ -static const uint32_t g_3bit_qdata_table[8] = {8, 1, 2, 3, 4, 5, 6, 7}; - -static const uint32_t g_5bit_data_table[32] = -{ - 32, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 -}; - -static const char *const g_cc[16] = -{"t", "f", "hi", "ls", "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi", "ge", "lt", "gt", "le"}; - -static const char *const g_cpcc[64] = -{/* 000 001 010 011 100 101 110 111 */ - "f", "eq", "ogt", "oge", "olt", "ole", "ogl", "or", /* 000 */ - "un", "ueq", "ugt", "uge", "ult", "ule", "ne", "t", /* 001 */ - "sf", "seq", "gt", "ge", "lt", "le", "gl" "gle", /* 010 */ - "ngle", "ngl", "nle", "nlt", "nge", "ngt", "sne", "st", /* 011 */ - "?", "?", "?", "?", "?", "?", "?", "?", /* 100 */ - "?", "?", "?", "?", "?", "?", "?", "?", /* 101 */ - "?", "?", "?", "?", "?", "?", "?", "?", /* 110 */ - "?", "?", "?", "?", "?", "?", "?", "?" /* 111 */ -}; - -static const char *const g_mmuregs[8] = -{ - "tc", "drp", "srp", "crp", "cal", "val", "sccr", "acr" -}; - -static const char *const g_mmucond[16] = -{ - "bs", "bc", "ls", "lc", "ss", "sc", "as", "ac", - "ws", "wc", "is", "ic", "gs", "gc", "cs", "cc" -}; - -/* ======================================================================== */ -/* =========================== UTILITY FUNCTIONS ========================== */ -/* ======================================================================== */ - -#define LIMIT_CPU_TYPES(ALLOWED_CPU_TYPES) \ - if(!(g_cpu_type & ALLOWED_CPU_TYPES)) \ - { \ - if((g_cpu_ir & 0xf000) == 0xf000) \ - d68000_1111(); \ - else d68000_illegal(); \ - return; \ - } - -static uint32_t dasm_read_imm_8(uint32_t advance) -{ - uint32_t result; - result = g_rawop[g_cpu_pc + 1 - g_rawbasepc]; - g_cpu_pc += advance; - return result; -} - -static uint32_t dasm_read_imm_16(uint32_t advance) -{ - uint32_t result; - result = (g_rawop[g_cpu_pc + 0 - g_rawbasepc] << 8) | - g_rawop[g_cpu_pc + 1 - g_rawbasepc]; - g_cpu_pc += advance; - return result; -} - -static uint32_t dasm_read_imm_32(uint32_t advance) -{ - uint32_t result; - result = (g_rawop[g_cpu_pc + 0 - g_rawbasepc] << 24) | - (g_rawop[g_cpu_pc + 1 - g_rawbasepc] << 16) | - (g_rawop[g_cpu_pc + 2 - g_rawbasepc] << 8) | - g_rawop[g_cpu_pc + 3 - g_rawbasepc]; - g_cpu_pc += advance; - return result; -} - -#define read_imm_8() dasm_read_imm_8(2) -#define read_imm_16() dasm_read_imm_16(2) -#define read_imm_32() dasm_read_imm_32(4) - -#define peek_imm_8() dasm_read_imm_8(0) -#define peek_imm_16() dasm_read_imm_16(0) -#define peek_imm_32() dasm_read_imm_32(0) - -/* Fake a split interface */ -#define get_ea_mode_str_8(instruction) get_ea_mode_str(instruction, 0) -#define get_ea_mode_str_16(instruction) get_ea_mode_str(instruction, 1) -#define get_ea_mode_str_32(instruction) get_ea_mode_str(instruction, 2) - -#define get_imm_str_s8() get_imm_str_s(0) -#define get_imm_str_s16() get_imm_str_s(1) -#define get_imm_str_s32() get_imm_str_s(2) - -#define get_imm_str_u8() get_imm_str_u(0) -#define get_imm_str_u16() get_imm_str_u(1) -#define get_imm_str_u32() get_imm_str_u(2) - -static int sext_7bit_int(int value) -{ - return (value & 0x40) ? (value | 0xffffff80) : (value & 0x7f); -} - - -/* 100% portable signed int generators */ -static int make_int_8(int value) -{ - return (value & 0x80) ? value | ~0xff : value & 0xff; -} - -static int make_int_16(int value) -{ - return (value & 0x8000) ? value | ~0xffff : value & 0xffff; -} - -static int make_int_32(int value) -{ - return (value & 0x80000000) ? value | ~0xffffffff : value & 0xffffffff; -} - -/* Get string representation of hex values */ -static char* make_signed_hex_str_8(uint32_t val) +std::string m68k_disassembler::make_signed_hex_str_8(u8 val) { - static char str[20]; - - val &= 0xff; - if(val == 0x80) - sprintf(str, "-$80"); + return "-$80"; else if(val & 0x80) - sprintf(str, "-$%x", (0-val) & 0x7f); + return util::string_format("-$%x", (-val) & 0x7f); else - sprintf(str, "$%x", val & 0x7f); - - return str; + return util::string_format("$%x", val & 0x7f); } -static char* make_signed_hex_str_16(uint32_t val) +std::string m68k_disassembler::make_signed_hex_str_16(u16 val) { - static char str[20]; - - val &= 0xffff; - if(val == 0x8000) - sprintf(str, "-$8000"); + return "-$8000"; else if(val & 0x8000) - sprintf(str, "-$%x", (0-val) & 0x7fff); + return util::string_format("-$%x", (-val) & 0x7fff); else - sprintf(str, "$%x", val & 0x7fff); - - return str; + return util::string_format("$%x", val & 0x7fff); } -static char* make_signed_hex_str_32(uint32_t val) +std::string m68k_disassembler::make_signed_hex_str_32(u32 val) { - static char str[20]; - - val &= 0xffffffff; - if(val == 0x80000000) - sprintf(str, "-$80000000"); + return "-$80000000"; else if(val & 0x80000000) - sprintf(str, "-$%x", (0-val) & 0x7fffffff); + return util::string_format("-$%x", (-val) & 0x7fffffff); else - sprintf(str, "$%x", val & 0x7fffffff); - - return str; + return util::string_format("$%x", val & 0x7fffffff); } - -/* make string of immediate value */ -static char* get_imm_str_s(uint32_t size) +std::string m68k_disassembler::get_imm_str_s(u32 size) { - static char str[15]; - if(size == 0) - sprintf(str, "#%s", make_signed_hex_str_8(read_imm_8())); - else if(size == 1) - sprintf(str, "#%s", make_signed_hex_str_16(read_imm_16())); - else - sprintf(str, "#%s", make_signed_hex_str_32(read_imm_32())); - return str; + switch(size) { + case 0: return util::string_format("#%s", make_signed_hex_str_8(read_imm_8())); + case 1: return util::string_format("#%s", make_signed_hex_str_16(read_imm_16())); + case 2: return util::string_format("#%s", make_signed_hex_str_32(read_imm_32())); + default: abort(); + } } -static char* get_imm_str_u(uint32_t size) +std::string m68k_disassembler::get_imm_str_u(u32 size) { - static char str[15]; - if(size == 0) - sprintf(str, "#$%x", read_imm_8() & 0xff); - else if(size == 1) - sprintf(str, "#$%x", read_imm_16() & 0xffff); - else - sprintf(str, "#$%x", read_imm_32() & 0xffffffff); - return str; -} - -/* Make string of effective address mode */ -static char* get_ea_mode_str(uint32_t instruction, uint32_t size) -{ - static char b1[64]; - static char b2[64]; - static char* mode = b2; - uint32_t extension; - uint32_t base; - uint32_t outer; - char base_reg[4]; - char index_reg[8]; - uint32_t preindex; - uint32_t postindex; - uint32_t comma = 0; - uint32_t temp_value; - char invalid_mode = 0; - - /* Switch buffers so we don't clobber on a double-call to this function */ - mode = mode == b1 ? b2 : b1; + switch(size) { + case 0: return util::string_format("#$%x", read_imm_8()); + case 1: return util::string_format("#$%x", read_imm_16()); + case 2: return util::string_format("#$%x", read_imm_32()); + default: abort(); + } +} +std::string m68k_disassembler::get_ea_mode_str(u16 instruction, u32 size) +{ switch(instruction & 0x3f) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: /* data register direct */ - sprintf(mode, "D%d", instruction&7); + return util::string_format("D%d", instruction&7); break; case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: /* address register direct */ - sprintf(mode, "A%d", instruction&7); + return util::string_format("A%d", instruction&7); break; case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: /* address register indirect */ - sprintf(mode, "(A%d)", instruction&7); + return util::string_format("(A%d)", instruction&7); break; case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: /* address register indirect with postincrement */ - sprintf(mode, "(A%d)+", instruction&7); + return util::string_format("(A%d)+", instruction&7); break; case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: /* address register indirect with predecrement */ - sprintf(mode, "-(A%d)", instruction&7); + return util::string_format("-(A%d)", instruction&7); break; case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f: /* address register indirect with displacement*/ - sprintf(mode, "(%s,A%d)", make_signed_hex_str_16(read_imm_16()), instruction&7); + return util::string_format("(%s,A%d)", make_signed_hex_str_16(read_imm_16()), instruction&7); break; case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: + { /* address register indirect with index */ - extension = read_imm_16(); + u16 extension = read_imm_16(); - if((g_cpu_type & M68010_LESS) && EXT_INDEX_SCALE(extension)) - { - invalid_mode = 1; + if((m_cpu_type & M68010_LESS) && ext_index_scale(extension)) break; - } - if(EXT_FULL(extension)) + if(ext_full(extension)) { - if(g_cpu_type & M68010_LESS) - { - invalid_mode = 1; + if(m_cpu_type & M68010_LESS) break; - } - if(EXT_EFFECTIVE_ZERO(extension)) - { - strcpy(mode, "0"); - break; - } + if(ext_effective_zero(extension)) + return "0"; - base = EXT_BASE_DISPLACEMENT_PRESENT(extension) ? (EXT_BASE_DISPLACEMENT_LONG(extension) ? read_imm_32() : read_imm_16()) : 0; - outer = EXT_OUTER_DISPLACEMENT_PRESENT(extension) ? (EXT_OUTER_DISPLACEMENT_LONG(extension) ? read_imm_32() : read_imm_16()) : 0; - if(EXT_BASE_REGISTER_PRESENT(extension)) - sprintf(base_reg, "A%d", instruction&7); - else - *base_reg = 0; - if(EXT_INDEX_REGISTER_PRESENT(extension)) - { - sprintf(index_reg, "%c%d.%c", EXT_INDEX_AR(extension) ? 'A' : 'D', EXT_INDEX_REGISTER(extension), EXT_INDEX_LONG(extension) ? 'l' : 'w'); - if(EXT_INDEX_SCALE(extension)) - sprintf(index_reg+strlen(index_reg), "*%d", 1 << EXT_INDEX_SCALE(extension)); - } - else - *index_reg = 0; - preindex = (extension&7) > 0 && (extension&7) < 4; - postindex = (extension&7) > 4; + u32 base = ext_base_displacement_present(extension) ? (ext_base_displacement_long(extension) ? read_imm_32() : read_imm_16()) : 0; + u32 outer = ext_outer_displacement_present(extension) ? (ext_outer_displacement_long(extension) ? read_imm_32() : read_imm_16()) : 0; + std::string base_reg = ext_base_register_present(extension) ? util::string_format("A%d", instruction&7) : ""; + std::string index_reg = ext_index_register_present(extension) ? + util::string_format("%c%d.%c%s", ext_index_ar(extension) ? 'A' : 'D', ext_index_register(extension), ext_index_long(extension) ? 'l' : 'w', + ext_index_scale(extension) ? util::string_format("*%d", 1 << ext_index_scale(extension)) : "") + : ""; + + bool preindex = (extension&7) > 0 && (extension&7) < 4; + bool postindex = (extension&7) > 4; - strcpy(mode, "("); + std::string mode = "("; if(preindex || postindex) - strcat(mode, "["); + mode += '['; + bool comma = false; if(base) { - if (EXT_BASE_DISPLACEMENT_LONG(extension)) - { - strcat(mode, make_signed_hex_str_32(base)); - } + if(ext_base_displacement_long(extension)) + mode += make_signed_hex_str_32(base); else - { - strcat(mode, make_signed_hex_str_16(base)); - } - comma = 1; + mode += make_signed_hex_str_16(base); + comma = true; } - if(*base_reg) + if(!base_reg.empty()) { if(comma) - strcat(mode, ","); - strcat(mode, base_reg); - comma = 1; + mode += ','; + mode += base_reg; + comma = true; } if(postindex) { - strcat(mode, "]"); - comma = 1; + mode += ']'; + comma = true; } - if(*index_reg) + if(!index_reg.empty()) { if(comma) - strcat(mode, ","); - strcat(mode, index_reg); - comma = 1; + mode += ','; + mode += index_reg; + comma = true; } if(preindex) { - strcat(mode, "]"); - comma = 1; + mode += ']'; } if(outer) { if(comma) - strcat(mode, ","); - strcat(mode, make_signed_hex_str_16(outer)); + mode += ','; + mode += make_signed_hex_str_16(outer); } - strcat(mode, ")"); - break; + mode += ')'; + return mode; } - if(EXT_8BIT_DISPLACEMENT(extension) == 0) - sprintf(mode, "(A%d,%c%d.%c", instruction&7, EXT_INDEX_AR(extension) ? 'A' : 'D', EXT_INDEX_REGISTER(extension), EXT_INDEX_LONG(extension) ? 'l' : 'w'); - else - sprintf(mode, "(%s,A%d,%c%d.%c", make_signed_hex_str_8(extension), instruction&7, EXT_INDEX_AR(extension) ? 'A' : 'D', EXT_INDEX_REGISTER(extension), EXT_INDEX_LONG(extension) ? 'l' : 'w'); - if(EXT_INDEX_SCALE(extension)) - sprintf(mode+strlen(mode), "*%d", 1 << EXT_INDEX_SCALE(extension)); - strcat(mode, ")"); - break; + std::string mode = ext_8bit_displacement(extension) ? + util::string_format("(%s,A%d,%c%d.%c", make_signed_hex_str_8(extension), instruction&7, ext_index_ar(extension) ? 'A' : 'D', ext_index_register(extension), ext_index_long(extension) ? 'l' : 'w') : + util::string_format("(A%d,%c%d.%c", instruction&7, ext_index_ar(extension) ? 'A' : 'D', ext_index_register(extension), ext_index_long(extension) ? 'l' : 'w'); + if(ext_index_scale(extension)) + mode += util::string_format("*%d", 1 << ext_index_scale(extension)); + mode += ')'; + return mode; + } case 0x38: /* absolute short address */ - sprintf(mode, "$%x.w", read_imm_16()); + return util::string_format("$%x.w", read_imm_16()); break; case 0x39: /* absolute long address */ - sprintf(mode, "$%x.l", read_imm_32()); + return util::string_format("$%x.l", read_imm_32()); break; case 0x3a: + { /* program counter with displacement */ - temp_value = read_imm_16(); - sprintf(mode, "(%s,PC)", make_signed_hex_str_16(temp_value)); - sprintf(g_helper_str, "; ($%x)", (make_int_16(temp_value) + g_cpu_pc-2) & 0xffffffff); - break; + u16 temp_value = read_imm_16(); + return util::string_format("(%s,PC) ; ($%x)", make_signed_hex_str_16(temp_value), + (make_int_16(temp_value) + m_cpu_pc-2) & 0xffffffff); + } case 0x3b: + { /* program counter with index */ - extension = read_imm_16(); + u16 extension = read_imm_16(); - if((g_cpu_type & M68010_LESS) && EXT_INDEX_SCALE(extension)) - { - invalid_mode = 1; + if((m_cpu_type & M68010_LESS) && ext_index_scale(extension)) break; - } - if(EXT_FULL(extension)) + if(ext_full(extension)) { - if(g_cpu_type & M68010_LESS) - { - invalid_mode = 1; - break; - } - - if(EXT_EFFECTIVE_ZERO(extension)) - { - strcpy(mode, "0"); + if(m_cpu_type & M68010_LESS) break; - } - base = EXT_BASE_DISPLACEMENT_PRESENT(extension) ? (EXT_BASE_DISPLACEMENT_LONG(extension) ? read_imm_32() : read_imm_16()) : 0; - outer = EXT_OUTER_DISPLACEMENT_PRESENT(extension) ? (EXT_OUTER_DISPLACEMENT_LONG(extension) ? read_imm_32() : read_imm_16()) : 0; - if(EXT_BASE_REGISTER_PRESENT(extension)) - strcpy(base_reg, "PC"); - else - *base_reg = 0; - if(EXT_INDEX_REGISTER_PRESENT(extension)) - { - sprintf(index_reg, "%c%d.%c", EXT_INDEX_AR(extension) ? 'A' : 'D', EXT_INDEX_REGISTER(extension), EXT_INDEX_LONG(extension) ? 'l' : 'w'); - if(EXT_INDEX_SCALE(extension)) - sprintf(index_reg+strlen(index_reg), "*%d", 1 << EXT_INDEX_SCALE(extension)); - } - else - *index_reg = 0; - preindex = (extension&7) > 0 && (extension&7) < 4; - postindex = (extension&7) > 4; - strcpy(mode, "("); + if(ext_effective_zero(extension)) + return "0"; + + u32 base = ext_base_displacement_present(extension) ? (ext_base_displacement_long(extension) ? read_imm_32() : read_imm_16()) : 0; + u32 outer = ext_outer_displacement_present(extension) ? (ext_outer_displacement_long(extension) ? read_imm_32() : read_imm_16()) : 0; + std::string base_reg = ext_base_register_present(extension) ? "PC" : ""; + std::string index_reg = + ext_index_register_present(extension) ? + util::string_format("%c%d.%c%s", ext_index_ar(extension) ? 'A' : 'D', ext_index_register(extension), ext_index_long(extension) ? 'l' : 'w', + ext_index_scale(extension) ? + util::string_format("*%d", 1 << ext_index_scale(extension)) : "") : ""; + bool preindex = (extension&7) > 0 && (extension&7) < 4; + bool postindex = (extension&7) > 4; + + bool comma = false; + std::string mode = "("; if(preindex || postindex) - strcat(mode, "["); + mode += '['; if(base) { - strcat(mode, make_signed_hex_str_16(base)); - comma = 1; + mode += make_signed_hex_str_16(base); + comma = true; } - if(*base_reg) + if(!base_reg.empty()) { if(comma) - strcat(mode, ","); - strcat(mode, base_reg); - comma = 1; + mode += ','; + mode += base_reg; + comma = true; } if(postindex) { - strcat(mode, "]"); - comma = 1; + mode += ']'; + comma = true; } - if(*index_reg) + if(!index_reg.empty()) { if(comma) - strcat(mode, ","); - strcat(mode, index_reg); - comma = 1; + mode += ','; + mode += index_reg; + comma = true; } if(preindex) { - strcat(mode, "]"); - comma = 1; + mode += ']'; + comma = true; } if(outer) { if(comma) - strcat(mode, ","); - strcat(mode, make_signed_hex_str_16(outer)); + mode += ','; + mode += make_signed_hex_str_16(outer); } - strcat(mode, ")"); - break; + mode += ')'; + return mode; } - if(EXT_8BIT_DISPLACEMENT(extension) == 0) - sprintf(mode, "(PC,%c%d.%c", EXT_INDEX_AR(extension) ? 'A' : 'D', EXT_INDEX_REGISTER(extension), EXT_INDEX_LONG(extension) ? 'l' : 'w'); - else - sprintf(mode, "(%s,PC,%c%d.%c", make_signed_hex_str_8(extension), EXT_INDEX_AR(extension) ? 'A' : 'D', EXT_INDEX_REGISTER(extension), EXT_INDEX_LONG(extension) ? 'l' : 'w'); - if(EXT_INDEX_SCALE(extension)) - sprintf(mode+strlen(mode), "*%d", 1 << EXT_INDEX_SCALE(extension)); - strcat(mode, ")"); - break; + std::string mode = ext_8bit_displacement(extension) ? + util::string_format("(%s,PC,%c%d.%c", make_signed_hex_str_8(extension), ext_index_ar(extension) ? 'A' : 'D', ext_index_register(extension), ext_index_long(extension) ? 'l' : 'w') : + util::string_format("(PC,%c%d.%c", ext_index_ar(extension) ? 'A' : 'D', ext_index_register(extension), ext_index_long(extension) ? 'l' : 'w'); + + if(ext_index_scale(extension)) + mode += util::string_format("*%d", 1 << ext_index_scale(extension)); + mode += ')'; + return mode; + } case 0x3c: /* Immediate */ - sprintf(mode, "%s", get_imm_str_u(size)); - break; - default: - invalid_mode = 1; + return get_imm_str_u(size); } - if(invalid_mode) - sprintf(mode, "INVALID %x", instruction & 0x3f); - - return mode; + return util::string_format("INVALID %x", instruction & 0x3f); } +/* ======================================================================== */ +/* ================================= DATA ================================= */ +/* ======================================================================== */ + +/* used by ops like asr, ror, addq, etc */ +const u32 m68k_disassembler::m_3bit_qdata_table[8] = {8, 1, 2, 3, 4, 5, 6, 7}; + +const u32 m68k_disassembler::m_5bit_data_table[32] = +{ + 32, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 +}; + +const char *const m68k_disassembler::m_cc[16] = +{ + "t", "f", "hi", "ls", "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi", "ge", "lt", "gt", "le" +}; + +const char *const m68k_disassembler::m_cpcc[64] = +{/* 000 001 010 011 100 101 110 111 */ + "f", "eq", "ogt", "oge", "olt", "ole", "ogl", "or", /* 000 */ + "un", "ueq", "ugt", "uge", "ult", "ule", "ne", "t", /* 001 */ + "sf", "seq", "gt", "ge", "lt", "le", "gl" "gle", /* 010 */ + "ngle", "ngl", "nle", "nlt", "nge", "ngt", "sne", "st", /* 011 */ + "?", "?", "?", "?", "?", "?", "?", "?", /* 100 */ + "?", "?", "?", "?", "?", "?", "?", "?", /* 101 */ + "?", "?", "?", "?", "?", "?", "?", "?", /* 110 */ + "?", "?", "?", "?", "?", "?", "?", "?" /* 111 */ +}; + +const char *const m68k_disassembler::m_mmuregs[8] = +{ + "tc", "drp", "srp", "crp", "cal", "val", "sccr", "acr" +}; + +const char *const m68k_disassembler::m_mmucond[16] = +{ + "bs", "bc", "ls", "lc", "ss", "sc", "as", "ac", + "ws", "wc", "is", "ic", "gs", "gc", "cs", "cc" +}; +std::pair<bool, std::string> m68k_disassembler::limit_cpu_types(u32 allowed) +{ + if(!(m_cpu_type & allowed)) + { + if((m_cpu_ir & 0xf000) == 0xf000) + return std::make_pair(true, d68000_1111()); + else + return std::make_pair(true, d68000_illegal()); + } + return std::make_pair(false, std::string()); +} /* ======================================================================== */ /* ========================= INSTRUCTION HANDLERS ========================= */ @@ -691,578 +372,534 @@ static char* get_ea_mode_str(uint32_t instruction, uint32_t size) * al : absolute long */ -static void d68000_illegal(void) +std::string m68k_disassembler::d68000_illegal() { - sprintf(g_dasm_str, "dc.w $%04x; ILLEGAL", g_cpu_ir); + return util::string_format("dc.w $%04x; ILLEGAL", m_cpu_ir); } -static void d68000_1010(void) +std::string m68k_disassembler::d68000_1010() { - sprintf(g_dasm_str, "dc.w $%04x; opcode 1010", g_cpu_ir); + return util::string_format("dc.w $%04x; opcode 1010", m_cpu_ir); } -static void d68000_1111(void) +std::string m68k_disassembler::d68000_1111() { - sprintf(g_dasm_str, "dc.w $%04x; opcode 1111", g_cpu_ir); + return util::string_format("dc.w $%04x; opcode 1111", m_cpu_ir); } -static void d68000_abcd_rr(void) +std::string m68k_disassembler::d68000_abcd_rr() { - sprintf(g_dasm_str, "abcd D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("abcd D%d, D%d", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_abcd_mm(void) +std::string m68k_disassembler::d68000_abcd_mm() { - sprintf(g_dasm_str, "abcd -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("abcd -(A%d), -(A%d)", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_add_er_8(void) +std::string m68k_disassembler::d68000_add_er_8() { - sprintf(g_dasm_str, "add.b %s, D%d", get_ea_mode_str_8(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("add.b %s, D%d", get_ea_mode_str_8(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_add_er_16(void) +std::string m68k_disassembler::d68000_add_er_16() { - sprintf(g_dasm_str, "add.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("add.w %s, D%d", get_ea_mode_str_16(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_add_er_32(void) +std::string m68k_disassembler::d68000_add_er_32() { - sprintf(g_dasm_str, "add.l %s, D%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("add.l %s, D%d", get_ea_mode_str_32(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_add_re_8(void) +std::string m68k_disassembler::d68000_add_re_8() { - sprintf(g_dasm_str, "add.b D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("add.b D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_add_re_16(void) +std::string m68k_disassembler::d68000_add_re_16() { - sprintf(g_dasm_str, "add.w D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("add.w D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_add_re_32(void) +std::string m68k_disassembler::d68000_add_re_32() { - sprintf(g_dasm_str, "add.l D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("add.l D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_adda_16(void) +std::string m68k_disassembler::d68000_adda_16() { - sprintf(g_dasm_str, "adda.w %s, A%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("adda.w %s, A%d", get_ea_mode_str_16(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_adda_32(void) +std::string m68k_disassembler::d68000_adda_32() { - sprintf(g_dasm_str, "adda.l %s, A%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("adda.l %s, A%d", get_ea_mode_str_32(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_addi_8(void) +std::string m68k_disassembler::d68000_addi_8() { - char* str = get_imm_str_s8(); - sprintf(g_dasm_str, "addi.b %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); + std::string str = get_imm_str_s8(); + return util::string_format("addi.b %s, %s", str, get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_addi_16(void) +std::string m68k_disassembler::d68000_addi_16() { - char* str = get_imm_str_s16(); - sprintf(g_dasm_str, "addi.w %s, %s", str, get_ea_mode_str_16(g_cpu_ir)); + std::string str = get_imm_str_s16(); + return util::string_format("addi.w %s, %s", str, get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_addi_32(void) +std::string m68k_disassembler::d68000_addi_32() { - char* str = get_imm_str_s32(); - sprintf(g_dasm_str, "addi.l %s, %s", str, get_ea_mode_str_32(g_cpu_ir)); + std::string str = get_imm_str_s32(); + return util::string_format("addi.l %s, %s", str, get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_addq_8(void) +std::string m68k_disassembler::d68000_addq_8() { - sprintf(g_dasm_str, "addq.b #%d, %s", g_3bit_qdata_table[(g_cpu_ir>>9)&7], get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("addq.b #%d, %s", m_3bit_qdata_table[(m_cpu_ir>>9)&7], get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_addq_16(void) +std::string m68k_disassembler::d68000_addq_16() { - sprintf(g_dasm_str, "addq.w #%d, %s", g_3bit_qdata_table[(g_cpu_ir>>9)&7], get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("addq.w #%d, %s", m_3bit_qdata_table[(m_cpu_ir>>9)&7], get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_addq_32(void) +std::string m68k_disassembler::d68000_addq_32() { - sprintf(g_dasm_str, "addq.l #%d, %s", g_3bit_qdata_table[(g_cpu_ir>>9)&7], get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("addq.l #%d, %s", m_3bit_qdata_table[(m_cpu_ir>>9)&7], get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_addx_rr_8(void) +std::string m68k_disassembler::d68000_addx_rr_8() { - sprintf(g_dasm_str, "addx.b D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("addx.b D%d, D%d", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_addx_rr_16(void) +std::string m68k_disassembler::d68000_addx_rr_16() { - sprintf(g_dasm_str, "addx.w D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("addx.w D%d, D%d", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_addx_rr_32(void) +std::string m68k_disassembler::d68000_addx_rr_32() { - sprintf(g_dasm_str, "addx.l D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("addx.l D%d, D%d", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_addx_mm_8(void) +std::string m68k_disassembler::d68000_addx_mm_8() { - sprintf(g_dasm_str, "addx.b -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("addx.b -(A%d), -(A%d)", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_addx_mm_16(void) +std::string m68k_disassembler::d68000_addx_mm_16() { - sprintf(g_dasm_str, "addx.w -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("addx.w -(A%d), -(A%d)", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_addx_mm_32(void) +std::string m68k_disassembler::d68000_addx_mm_32() { - sprintf(g_dasm_str, "addx.l -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("addx.l -(A%d), -(A%d)", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_and_er_8(void) +std::string m68k_disassembler::d68000_and_er_8() { - sprintf(g_dasm_str, "and.b %s, D%d", get_ea_mode_str_8(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("and.b %s, D%d", get_ea_mode_str_8(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_and_er_16(void) +std::string m68k_disassembler::d68000_and_er_16() { - sprintf(g_dasm_str, "and.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("and.w %s, D%d", get_ea_mode_str_16(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_and_er_32(void) +std::string m68k_disassembler::d68000_and_er_32() { - sprintf(g_dasm_str, "and.l %s, D%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("and.l %s, D%d", get_ea_mode_str_32(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_and_re_8(void) +std::string m68k_disassembler::d68000_and_re_8() { - sprintf(g_dasm_str, "and.b D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("and.b D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_and_re_16(void) +std::string m68k_disassembler::d68000_and_re_16() { - sprintf(g_dasm_str, "and.w D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("and.w D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_and_re_32(void) +std::string m68k_disassembler::d68000_and_re_32() { - sprintf(g_dasm_str, "and.l D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("and.l D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_andi_8(void) +std::string m68k_disassembler::d68000_andi_8() { - char* str = get_imm_str_u8(); - sprintf(g_dasm_str, "andi.b %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); + std::string str = get_imm_str_u8(); + return util::string_format("andi.b %s, %s", str, get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_andi_16(void) +std::string m68k_disassembler::d68000_andi_16() { - char* str = get_imm_str_u16(); - sprintf(g_dasm_str, "andi.w %s, %s", str, get_ea_mode_str_16(g_cpu_ir)); + std::string str = get_imm_str_u16(); + return util::string_format("andi.w %s, %s", str, get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_andi_32(void) +std::string m68k_disassembler::d68000_andi_32() { - char* str = get_imm_str_u32(); - sprintf(g_dasm_str, "andi.l %s, %s", str, get_ea_mode_str_32(g_cpu_ir)); + std::string str = get_imm_str_u32(); + return util::string_format("andi.l %s, %s", str, get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_andi_to_ccr(void) +std::string m68k_disassembler::d68000_andi_to_ccr() { - sprintf(g_dasm_str, "andi %s, CCR", get_imm_str_u8()); + return util::string_format("andi %s, CCR", get_imm_str_u8()); } -static void d68000_andi_to_sr(void) +std::string m68k_disassembler::d68000_andi_to_sr() { - sprintf(g_dasm_str, "andi %s, SR", get_imm_str_u16()); + return util::string_format("andi %s, SR", get_imm_str_u16()); } -static void d68000_asr_s_8(void) +std::string m68k_disassembler::d68000_asr_s_8() { - sprintf(g_dasm_str, "asr.b #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("asr.b #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_asr_s_16(void) +std::string m68k_disassembler::d68000_asr_s_16() { - sprintf(g_dasm_str, "asr.w #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("asr.w #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_asr_s_32(void) +std::string m68k_disassembler::d68000_asr_s_32() { - sprintf(g_dasm_str, "asr.l #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("asr.l #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_asr_r_8(void) +std::string m68k_disassembler::d68000_asr_r_8() { - sprintf(g_dasm_str, "asr.b D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("asr.b D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_asr_r_16(void) +std::string m68k_disassembler::d68000_asr_r_16() { - sprintf(g_dasm_str, "asr.w D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("asr.w D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_asr_r_32(void) +std::string m68k_disassembler::d68000_asr_r_32() { - sprintf(g_dasm_str, "asr.l D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("asr.l D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_asr_ea(void) +std::string m68k_disassembler::d68000_asr_ea() { - sprintf(g_dasm_str, "asr.w %s", get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("asr.w %s", get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_asl_s_8(void) +std::string m68k_disassembler::d68000_asl_s_8() { - sprintf(g_dasm_str, "asl.b #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("asl.b #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_asl_s_16(void) +std::string m68k_disassembler::d68000_asl_s_16() { - sprintf(g_dasm_str, "asl.w #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("asl.w #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_asl_s_32(void) +std::string m68k_disassembler::d68000_asl_s_32() { - sprintf(g_dasm_str, "asl.l #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("asl.l #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_asl_r_8(void) +std::string m68k_disassembler::d68000_asl_r_8() { - sprintf(g_dasm_str, "asl.b D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("asl.b D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_asl_r_16(void) +std::string m68k_disassembler::d68000_asl_r_16() { - sprintf(g_dasm_str, "asl.w D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("asl.w D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_asl_r_32(void) +std::string m68k_disassembler::d68000_asl_r_32() { - sprintf(g_dasm_str, "asl.l D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("asl.l D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_asl_ea(void) +std::string m68k_disassembler::d68000_asl_ea() { - sprintf(g_dasm_str, "asl.w %s", get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("asl.w %s", get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_bcc_8(void) +std::string m68k_disassembler::d68000_bcc_8() { - uint32_t temp_pc = g_cpu_pc; - sprintf(g_dasm_str, "b%-2s $%x", g_cc[(g_cpu_ir>>8)&0xf], temp_pc + make_int_8(g_cpu_ir)); + u32 temp_pc = m_cpu_pc; + return util::string_format("b%-2s $%x", m_cc[(m_cpu_ir>>8)&0xf], temp_pc + make_int_8(m_cpu_ir)); } -static void d68000_bcc_16(void) +std::string m68k_disassembler::d68000_bcc_16() { - uint32_t temp_pc = g_cpu_pc; - sprintf(g_dasm_str, "b%-2s $%x", g_cc[(g_cpu_ir>>8)&0xf], temp_pc + make_int_16(read_imm_16())); + u32 temp_pc = m_cpu_pc; + return util::string_format("b%-2s $%x", m_cc[(m_cpu_ir>>8)&0xf], temp_pc + make_int_16(read_imm_16())); } -static void d68020_bcc_32(void) +std::string m68k_disassembler::d68020_bcc_32() { - uint32_t temp_pc = g_cpu_pc; - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "b%-2s $%x; (2+)", g_cc[(g_cpu_ir>>8)&0xf], temp_pc + read_imm_32()); + u32 temp_pc = m_cpu_pc; + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("b%-2s $%x; (2+)", m_cc[(m_cpu_ir>>8)&0xf], temp_pc + read_imm_32()); } -static void d68000_bchg_r(void) +std::string m68k_disassembler::d68000_bchg_r() { - sprintf(g_dasm_str, "bchg D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("bchg D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_bchg_s(void) +std::string m68k_disassembler::d68000_bchg_s() { - char* str = get_imm_str_u8(); - sprintf(g_dasm_str, "bchg %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); + std::string str = get_imm_str_u8(); + return util::string_format("bchg %s, %s", str, get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_bclr_r(void) +std::string m68k_disassembler::d68000_bclr_r() { - sprintf(g_dasm_str, "bclr D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("bclr D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_bclr_s(void) +std::string m68k_disassembler::d68000_bclr_s() { - char* str = get_imm_str_u8(); - sprintf(g_dasm_str, "bclr %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); + std::string str = get_imm_str_u8(); + return util::string_format("bclr %s, %s", str, get_ea_mode_str_8(m_cpu_ir)); } -static void d68010_bkpt(void) +std::string m68k_disassembler::d68010_bkpt() { - LIMIT_CPU_TYPES(M68010_PLUS); - sprintf(g_dasm_str, "bkpt #%d; (1+)", g_cpu_ir&7); + auto limit = limit_cpu_types(M68010_PLUS); + if(limit.first) + return limit.second; + return util::string_format("bkpt #%d; (1+)", m_cpu_ir&7); } -static void d68020_bfchg(void) +std::string m68k_disassembler::d68020_bfchg() { - uint32_t extension; - char offset[3]; - char width[3]; + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; - LIMIT_CPU_TYPES(M68020_PLUS); + u16 extension = read_imm_16(); - extension = read_imm_16(); + std::string offset = BIT(extension, 11) ? util::string_format("D%d", (extension>>6)&7) : util::string_format("%d", (extension>>6)&31); - if(BIT_B(extension)) - sprintf(offset, "D%d", (extension>>6)&7); - else - sprintf(offset, "%d", (extension>>6)&31); - if(BIT_5(extension)) - sprintf(width, "D%d", extension&7); - else - sprintf(width, "%d", g_5bit_data_table[extension&31]); - sprintf(g_dasm_str, "bfchg %s {%s:%s}; (2+)", get_ea_mode_str_8(g_cpu_ir), offset, width); + std::string width = BIT(extension, 5) ? util::string_format("D%d", extension&7) : util::string_format("%d", m_5bit_data_table[extension&31]); + return util::string_format("bfchg %s {%s:%s}; (2+)", get_ea_mode_str_8(m_cpu_ir), offset, width); } -static void d68020_bfclr(void) +std::string m68k_disassembler::d68020_bfclr() { - uint32_t extension; - char offset[3]; - char width[3]; + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; - LIMIT_CPU_TYPES(M68020_PLUS); + u16 extension = read_imm_16(); - extension = read_imm_16(); + std::string offset = BIT(extension, 11) ? util::string_format("D%d", (extension>>6)&7) : util::string_format("%d", (extension>>6)&31); - if(BIT_B(extension)) - sprintf(offset, "D%d", (extension>>6)&7); - else - sprintf(offset, "%d", (extension>>6)&31); - if(BIT_5(extension)) - sprintf(width, "D%d", extension&7); - else - sprintf(width, "%d", g_5bit_data_table[extension&31]); - sprintf(g_dasm_str, "bfclr %s {%s:%s}; (2+)", get_ea_mode_str_8(g_cpu_ir), offset, width); + std::string width = BIT(extension, 5) ? util::string_format("D%d", extension&7) : util::string_format("%d", m_5bit_data_table[extension&31]); + return util::string_format("bfclr %s {%s:%s}; (2+)", get_ea_mode_str_8(m_cpu_ir), offset, width); } -static void d68020_bfexts(void) +std::string m68k_disassembler::d68020_bfexts() { - uint32_t extension; - char offset[3]; - char width[3]; + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; - LIMIT_CPU_TYPES(M68020_PLUS); + u16 extension = read_imm_16(); - extension = read_imm_16(); + std::string offset = BIT(extension, 11) ? util::string_format("D%d", (extension>>6)&7) : util::string_format("%d", (extension>>6)&31); - if(BIT_B(extension)) - sprintf(offset, "D%d", (extension>>6)&7); - else - sprintf(offset, "%d", (extension>>6)&31); - if(BIT_5(extension)) - sprintf(width, "D%d", extension&7); - else - sprintf(width, "%d", g_5bit_data_table[extension&31]); - sprintf(g_dasm_str, "bfexts D%d, %s {%s:%s}; (2+)", (extension>>12)&7, get_ea_mode_str_8(g_cpu_ir), offset, width); + std::string width = BIT(extension, 5) ? util::string_format("D%d", extension&7) : util::string_format("%d", m_5bit_data_table[extension&31]); + return util::string_format("bfexts D%d, %s {%s:%s}; (2+)", (extension>>12)&7, get_ea_mode_str_8(m_cpu_ir), offset, width); } -static void d68020_bfextu(void) +std::string m68k_disassembler::d68020_bfextu() { - uint32_t extension; - char offset[3]; - char width[3]; + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; - LIMIT_CPU_TYPES(M68020_PLUS); + u16 extension = read_imm_16(); - extension = read_imm_16(); + std::string offset = BIT(extension, 11) ? util::string_format("D%d", (extension>>6)&7) : util::string_format("%d", (extension>>6)&31); - if(BIT_B(extension)) - sprintf(offset, "D%d", (extension>>6)&7); - else - sprintf(offset, "%d", (extension>>6)&31); - if(BIT_5(extension)) - sprintf(width, "D%d", extension&7); - else - sprintf(width, "%d", g_5bit_data_table[extension&31]); - sprintf(g_dasm_str, "bfextu D%d, %s {%s:%s}; (2+)", (extension>>12)&7, get_ea_mode_str_8(g_cpu_ir), offset, width); + std::string width = BIT(extension, 5) ? util::string_format("D%d", extension&7) : util::string_format("%d", m_5bit_data_table[extension&31]); + return util::string_format("bfextu D%d, %s {%s:%s}; (2+)", (extension>>12)&7, get_ea_mode_str_8(m_cpu_ir), offset, width); } -static void d68020_bfffo(void) +std::string m68k_disassembler::d68020_bfffo() { - uint32_t extension; - char offset[3]; - char width[3]; + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; - LIMIT_CPU_TYPES(M68020_PLUS); + u16 extension = read_imm_16(); - extension = read_imm_16(); + std::string offset = BIT(extension, 11) ? util::string_format("D%d", (extension>>6)&7) : util::string_format("%d", (extension>>6)&31); - if(BIT_B(extension)) - sprintf(offset, "D%d", (extension>>6)&7); - else - sprintf(offset, "%d", (extension>>6)&31); - if(BIT_5(extension)) - sprintf(width, "D%d", extension&7); - else - sprintf(width, "%d", g_5bit_data_table[extension&31]); - sprintf(g_dasm_str, "bfffo D%d, %s {%s:%s}; (2+)", (extension>>12)&7, get_ea_mode_str_8(g_cpu_ir), offset, width); + std::string width = BIT(extension, 5) ? util::string_format("D%d", extension&7) : util::string_format("%d", m_5bit_data_table[extension&31]); + return util::string_format("bfffo D%d, %s {%s:%s}; (2+)", (extension>>12)&7, get_ea_mode_str_8(m_cpu_ir), offset, width); } -static void d68020_bfins(void) +std::string m68k_disassembler::d68020_bfins() { - uint32_t extension; - char offset[3]; - char width[3]; + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; - LIMIT_CPU_TYPES(M68020_PLUS); + u16 extension = read_imm_16(); - extension = read_imm_16(); + std::string offset = BIT(extension, 11) ? util::string_format("D%d", (extension>>6)&7) : util::string_format("%d", (extension>>6)&31); - if(BIT_B(extension)) - sprintf(offset, "D%d", (extension>>6)&7); - else - sprintf(offset, "%d", (extension>>6)&31); - if(BIT_5(extension)) - sprintf(width, "D%d", extension&7); - else - sprintf(width, "%d", g_5bit_data_table[extension&31]); - sprintf(g_dasm_str, "bfins D%d, %s {%s:%s}; (2+)", (extension>>12)&7, get_ea_mode_str_8(g_cpu_ir), offset, width); + std::string width = BIT(extension, 5) ? util::string_format("D%d", extension&7) : util::string_format("%d", m_5bit_data_table[extension&31]); + return util::string_format("bfins D%d, %s {%s:%s}; (2+)", (extension>>12)&7, get_ea_mode_str_8(m_cpu_ir), offset, width); } -static void d68020_bfset(void) +std::string m68k_disassembler::d68020_bfset() { - uint32_t extension; - char offset[3]; - char width[3]; + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; - LIMIT_CPU_TYPES(M68020_PLUS); + u16 extension = read_imm_16(); - extension = read_imm_16(); + std::string offset = BIT(extension, 11) ? util::string_format("D%d", (extension>>6)&7) : util::string_format("%d", (extension>>6)&31); - if(BIT_B(extension)) - sprintf(offset, "D%d", (extension>>6)&7); - else - sprintf(offset, "%d", (extension>>6)&31); - if(BIT_5(extension)) - sprintf(width, "D%d", extension&7); - else - sprintf(width, "%d", g_5bit_data_table[extension&31]); - sprintf(g_dasm_str, "bfset %s {%s:%s}; (2+)", get_ea_mode_str_8(g_cpu_ir), offset, width); + std::string width = BIT(extension, 5) ? util::string_format("D%d", extension&7) : util::string_format("%d", m_5bit_data_table[extension&31]); + return util::string_format("bfset %s {%s:%s}; (2+)", get_ea_mode_str_8(m_cpu_ir), offset, width); } -static void d68020_bftst(void) +std::string m68k_disassembler::d68020_bftst() { - uint32_t extension; - char offset[3]; - char width[3]; + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; - LIMIT_CPU_TYPES(M68020_PLUS); + u16 extension = read_imm_16(); - extension = read_imm_16(); + std::string offset = BIT(extension, 11) ? util::string_format("D%d", (extension>>6)&7) : util::string_format("%d", (extension>>6)&31); - if(BIT_B(extension)) - sprintf(offset, "D%d", (extension>>6)&7); - else - sprintf(offset, "%d", (extension>>6)&31); - if(BIT_5(extension)) - sprintf(width, "D%d", extension&7); - else - sprintf(width, "%d", g_5bit_data_table[extension&31]); - sprintf(g_dasm_str, "bftst %s {%s:%s}; (2+)", get_ea_mode_str_8(g_cpu_ir), offset, width); + std::string width = BIT(extension, 5) ? util::string_format("D%d", extension&7) : util::string_format("%d", m_5bit_data_table[extension&31]); + return util::string_format("bftst %s {%s:%s}; (2+)", get_ea_mode_str_8(m_cpu_ir), offset, width); } -static void d68000_bra_8(void) +std::string m68k_disassembler::d68000_bra_8() { - uint32_t temp_pc = g_cpu_pc; - sprintf(g_dasm_str, "bra $%x", temp_pc + make_int_8(g_cpu_ir)); + u32 temp_pc = m_cpu_pc; + return util::string_format("bra $%x", temp_pc + make_int_8(m_cpu_ir)); } -static void d68000_bra_16(void) +std::string m68k_disassembler::d68000_bra_16() { - uint32_t temp_pc = g_cpu_pc; - sprintf(g_dasm_str, "bra $%x", temp_pc + make_int_16(read_imm_16())); + u32 temp_pc = m_cpu_pc; + return util::string_format("bra $%x", temp_pc + make_int_16(read_imm_16())); } -static void d68020_bra_32(void) +std::string m68k_disassembler::d68020_bra_32() { - uint32_t temp_pc = g_cpu_pc; - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "bra $%x; (2+)", temp_pc + read_imm_32()); + u32 temp_pc = m_cpu_pc; + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("bra $%x; (2+)", temp_pc + read_imm_32()); } -static void d68000_bset_r(void) +std::string m68k_disassembler::d68000_bset_r() { - sprintf(g_dasm_str, "bset D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("bset D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_bset_s(void) +std::string m68k_disassembler::d68000_bset_s() { - char* str = get_imm_str_u8(); - sprintf(g_dasm_str, "bset %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); + std::string str = get_imm_str_u8(); + return util::string_format("bset %s, %s", str, get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_bsr_8(void) +std::string m68k_disassembler::d68000_bsr_8() { - uint32_t temp_pc = g_cpu_pc; - sprintf(g_dasm_str, "bsr $%x", temp_pc + make_int_8(g_cpu_ir)); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + u32 temp_pc = m_cpu_pc; + m_flags = STEP_OVER; + return util::string_format("bsr $%x", temp_pc + make_int_8(m_cpu_ir)); } -static void d68000_bsr_16(void) +std::string m68k_disassembler::d68000_bsr_16() { - uint32_t temp_pc = g_cpu_pc; - sprintf(g_dasm_str, "bsr $%x", temp_pc + make_int_16(read_imm_16())); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + u32 temp_pc = m_cpu_pc; + m_flags = STEP_OVER; + return util::string_format("bsr $%x", temp_pc + make_int_16(read_imm_16())); } -static void d68020_bsr_32(void) +std::string m68k_disassembler::d68020_bsr_32() { - uint32_t temp_pc = g_cpu_pc; - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "bsr $%x; (2+)", temp_pc + read_imm_32()); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + u32 temp_pc = m_cpu_pc; + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + m_flags = STEP_OVER; + return util::string_format("bsr $%x; (2+)", temp_pc + read_imm_32()); } -static void d68000_btst_r(void) +std::string m68k_disassembler::d68000_btst_r() { - sprintf(g_dasm_str, "btst D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("btst D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_btst_s(void) +std::string m68k_disassembler::d68000_btst_s() { - char* str = get_imm_str_u8(); - sprintf(g_dasm_str, "btst %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); + std::string str = get_imm_str_u8(); + return util::string_format("btst %s, %s", str, get_ea_mode_str_8(m_cpu_ir)); } -static void d68020_callm(void) +std::string m68k_disassembler::d68020_callm() { - char* str; - LIMIT_CPU_TYPES(M68020_ONLY); - str = get_imm_str_u8(); + auto limit = limit_cpu_types(M68020_ONLY); + if(limit.first) + return limit.second; + std::string str = get_imm_str_u8(); - sprintf(g_dasm_str, "callm %s, %s; (2)", str, get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("callm %s, %s; (2)", str, get_ea_mode_str_8(m_cpu_ir)); } -static void d68020_cas_8(void) +std::string m68k_disassembler::d68020_cas_8() { - uint32_t extension; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); - sprintf(g_dasm_str, "cas.b D%d, D%d, %s; (2+)", extension&7, (extension>>8)&7, get_ea_mode_str_8(g_cpu_ir)); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + u16 extension = read_imm_16(); + return util::string_format("cas.b D%d, D%d, %s; (2+)", extension&7, (extension>>8)&7, get_ea_mode_str_8(m_cpu_ir)); } -static void d68020_cas_16(void) +std::string m68k_disassembler::d68020_cas_16() { - uint32_t extension; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); - sprintf(g_dasm_str, "cas.w D%d, D%d, %s; (2+)", extension&7, (extension>>8)&7, get_ea_mode_str_16(g_cpu_ir)); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + u16 extension = read_imm_16(); + return util::string_format("cas.w D%d, D%d, %s; (2+)", extension&7, (extension>>8)&7, get_ea_mode_str_16(m_cpu_ir)); } -static void d68020_cas_32(void) +std::string m68k_disassembler::d68020_cas_32() { - uint32_t extension; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); - sprintf(g_dasm_str, "cas.l D%d, D%d, %s; (2+)", extension&7, (extension>>8)&7, get_ea_mode_str_32(g_cpu_ir)); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + u16 extension = read_imm_16(); + return util::string_format("cas.l D%d, D%d, %s; (2+)", extension&7, (extension>>8)&7, get_ea_mode_str_32(m_cpu_ir)); } -static void d68020_cas2_16(void) +std::string m68k_disassembler::d68020_cas2_16() { /* CAS2 Dc1:Dc2,Du1:Dc2:(Rn1):(Rn2) f e d c b a 9 8 7 6 5 4 3 2 1 0 @@ -1270,495 +907,520 @@ f e d c b a 9 8 7 6 5 4 3 2 1 0 DARn2 0 0 0 Du2 0 0 0 Dc2 */ - uint32_t extension; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_32(); - sprintf(g_dasm_str, "cas2.w D%d:D%d:D%d:D%d, (%c%d):(%c%d); (2+)", + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + u32 extension = read_imm_32(); + return util::string_format("cas2.w D%d:D%d:D%d:D%d, (%c%d):(%c%d); (2+)", (extension>>16)&7, extension&7, (extension>>22)&7, (extension>>6)&7, - BIT_1F(extension) ? 'A' : 'D', (extension>>28)&7, - BIT_F(extension) ? 'A' : 'D', (extension>>12)&7); + BIT(extension, 31) ? 'A' : 'D', (extension>>28)&7, + BIT(extension, 15) ? 'A' : 'D', (extension>>12)&7); } -static void d68020_cas2_32(void) +std::string m68k_disassembler::d68020_cas2_32() { - uint32_t extension; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_32(); - sprintf(g_dasm_str, "cas2.l D%d:D%d:D%d:D%d, (%c%d):(%c%d); (2+)", + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + u32 extension = read_imm_32(); + return util::string_format("cas2.l D%d:D%d:D%d:D%d, (%c%d):(%c%d); (2+)", (extension>>16)&7, extension&7, (extension>>22)&7, (extension>>6)&7, - BIT_1F(extension) ? 'A' : 'D', (extension>>28)&7, - BIT_F(extension) ? 'A' : 'D', (extension>>12)&7); + BIT(extension, 31) ? 'A' : 'D', (extension>>28)&7, + BIT(extension, 15) ? 'A' : 'D', (extension>>12)&7); } -static void d68000_chk_16(void) +std::string m68k_disassembler::d68000_chk_16() { - sprintf(g_dasm_str, "chk.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + m_flags = STEP_OVER; + return util::string_format("chk.w %s, D%d", get_ea_mode_str_16(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68020_chk_32(void) +std::string m68k_disassembler::d68020_chk_32() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "chk.l %s, D%d; (2+)", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + m_flags = STEP_OVER; + return util::string_format("chk.l %s, D%d; (2+)", get_ea_mode_str_32(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68020_chk2_cmp2_8(void) +std::string m68k_disassembler::d68020_chk2_cmp2_8() { - uint32_t extension; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); - sprintf(g_dasm_str, "%s.b %s, %c%d; (2+)", BIT_B(extension) ? "chk2" : "cmp2", get_ea_mode_str_8(g_cpu_ir), BIT_F(extension) ? 'A' : 'D', (extension>>12)&7); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + u16 extension = read_imm_16(); + return util::string_format("%s.b %s, %c%d; (2+)", BIT(extension, 11) ? "chk2" : "cmp2", get_ea_mode_str_8(m_cpu_ir), BIT(extension, 15) ? 'A' : 'D', (extension>>12)&7); } -static void d68020_chk2_cmp2_16(void) +std::string m68k_disassembler::d68020_chk2_cmp2_16() { - uint32_t extension; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); - sprintf(g_dasm_str, "%s.w %s, %c%d; (2+)", BIT_B(extension) ? "chk2" : "cmp2", get_ea_mode_str_16(g_cpu_ir), BIT_F(extension) ? 'A' : 'D', (extension>>12)&7); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + u16 extension = read_imm_16(); + return util::string_format("%s.w %s, %c%d; (2+)", BIT(extension, 11) ? "chk2" : "cmp2", get_ea_mode_str_16(m_cpu_ir), BIT(extension, 15) ? 'A' : 'D', (extension>>12)&7); } -static void d68020_chk2_cmp2_32(void) +std::string m68k_disassembler::d68020_chk2_cmp2_32() { - uint32_t extension; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); - sprintf(g_dasm_str, "%s.l %s, %c%d; (2+)", BIT_B(extension) ? "chk2" : "cmp2", get_ea_mode_str_32(g_cpu_ir), BIT_F(extension) ? 'A' : 'D', (extension>>12)&7); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + u16 extension = read_imm_16(); + return util::string_format("%s.l %s, %c%d; (2+)", BIT(extension, 11) ? "chk2" : "cmp2", get_ea_mode_str_32(m_cpu_ir), BIT(extension, 15) ? 'A' : 'D', (extension>>12)&7); } -static void d68040_cinv(void) +std::string m68k_disassembler::d68040_cinv() { - LIMIT_CPU_TYPES(M68040_PLUS); + auto limit = limit_cpu_types(M68040_PLUS); + if(limit.first) + return limit.second; static const char *cachetype[4] = { "nop", "data", "inst", "both" }; - switch((g_cpu_ir>>3)&3) + switch((m_cpu_ir>>3)&3) { case 0: - sprintf(g_dasm_str, "cinv (illegal scope); (4)"); + return util::string_format("cinv (illegal scope); (4)"); break; case 1: - sprintf(g_dasm_str, "cinvl %s, (A%d); (4)", cachetype[(g_cpu_ir>>6)&3], g_cpu_ir&7); + return util::string_format("cinvl %s, (A%d); (4)", cachetype[(m_cpu_ir>>6)&3], m_cpu_ir&7); break; case 2: - sprintf(g_dasm_str, "cinvp %s, (A%d); (4)", cachetype[(g_cpu_ir>>6)&3], g_cpu_ir&7); + return util::string_format("cinvp %s, (A%d); (4)", cachetype[(m_cpu_ir>>6)&3], m_cpu_ir&7); break; - case 3: - sprintf(g_dasm_str, "cinva %s; (4)", cachetype[(g_cpu_ir>>6)&3]); + case 3: default: + return util::string_format("cinva %s; (4)", cachetype[(m_cpu_ir>>6)&3]); break; } } -static void d68000_clr_8(void) +std::string m68k_disassembler::d68000_clr_8() { - sprintf(g_dasm_str, "clr.b %s", get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("clr.b %s", get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_clr_16(void) +std::string m68k_disassembler::d68000_clr_16() { - sprintf(g_dasm_str, "clr.w %s", get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("clr.w %s", get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_clr_32(void) +std::string m68k_disassembler::d68000_clr_32() { - sprintf(g_dasm_str, "clr.l %s", get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("clr.l %s", get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_cmp_8(void) +std::string m68k_disassembler::d68000_cmp_8() { - sprintf(g_dasm_str, "cmp.b %s, D%d", get_ea_mode_str_8(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("cmp.b %s, D%d", get_ea_mode_str_8(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_cmp_16(void) +std::string m68k_disassembler::d68000_cmp_16() { - sprintf(g_dasm_str, "cmp.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("cmp.w %s, D%d", get_ea_mode_str_16(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_cmp_32(void) +std::string m68k_disassembler::d68000_cmp_32() { - sprintf(g_dasm_str, "cmp.l %s, D%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("cmp.l %s, D%d", get_ea_mode_str_32(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_cmpa_16(void) +std::string m68k_disassembler::d68000_cmpa_16() { - sprintf(g_dasm_str, "cmpa.w %s, A%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("cmpa.w %s, A%d", get_ea_mode_str_16(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_cmpa_32(void) +std::string m68k_disassembler::d68000_cmpa_32() { - sprintf(g_dasm_str, "cmpa.l %s, A%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("cmpa.l %s, A%d", get_ea_mode_str_32(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_cmpi_8(void) +std::string m68k_disassembler::d68000_cmpi_8() { - char* str = get_imm_str_s8(); - sprintf(g_dasm_str, "cmpi.b %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); + std::string str = get_imm_str_s8(); + return util::string_format("cmpi.b %s, %s", str, get_ea_mode_str_8(m_cpu_ir)); } -static void d68020_cmpi_pcdi_8(void) +std::string m68k_disassembler::d68020_cmpi_pcdi_8() { - char* str; - LIMIT_CPU_TYPES(M68010_PLUS); - str = get_imm_str_s8(); - sprintf(g_dasm_str, "cmpi.b %s, %s; (2+)", str, get_ea_mode_str_8(g_cpu_ir)); + auto limit = limit_cpu_types(M68010_PLUS); + if(limit.first) + return limit.second; + std::string str = get_imm_str_s8(); + return util::string_format("cmpi.b %s, %s; (2+)", str, get_ea_mode_str_8(m_cpu_ir)); } -static void d68020_cmpi_pcix_8(void) +std::string m68k_disassembler::d68020_cmpi_pcix_8() { - char* str; - LIMIT_CPU_TYPES(M68010_PLUS); - str = get_imm_str_s8(); - sprintf(g_dasm_str, "cmpi.b %s, %s; (2+)", str, get_ea_mode_str_8(g_cpu_ir)); + auto limit = limit_cpu_types(M68010_PLUS); + if(limit.first) + return limit.second; + std::string str = get_imm_str_s8(); + return util::string_format("cmpi.b %s, %s; (2+)", str, get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_cmpi_16(void) +std::string m68k_disassembler::d68000_cmpi_16() { - char* str; - str = get_imm_str_s16(); - sprintf(g_dasm_str, "cmpi.w %s, %s", str, get_ea_mode_str_16(g_cpu_ir)); + std::string str = get_imm_str_s16(); + return util::string_format("cmpi.w %s, %s", str, get_ea_mode_str_16(m_cpu_ir)); } -static void d68020_cmpi_pcdi_16(void) +std::string m68k_disassembler::d68020_cmpi_pcdi_16() { - char* str; - LIMIT_CPU_TYPES(M68010_PLUS); - str = get_imm_str_s16(); - sprintf(g_dasm_str, "cmpi.w %s, %s; (2+)", str, get_ea_mode_str_16(g_cpu_ir)); + auto limit = limit_cpu_types(M68010_PLUS); + if(limit.first) + return limit.second; + std::string str = get_imm_str_s16(); + return util::string_format("cmpi.w %s, %s; (2+)", str, get_ea_mode_str_16(m_cpu_ir)); } -static void d68020_cmpi_pcix_16(void) +std::string m68k_disassembler::d68020_cmpi_pcix_16() { - char* str; - LIMIT_CPU_TYPES(M68010_PLUS); - str = get_imm_str_s16(); - sprintf(g_dasm_str, "cmpi.w %s, %s; (2+)", str, get_ea_mode_str_16(g_cpu_ir)); + auto limit = limit_cpu_types(M68010_PLUS); + if(limit.first) + return limit.second; + std::string str = get_imm_str_s16(); + return util::string_format("cmpi.w %s, %s; (2+)", str, get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_cmpi_32(void) +std::string m68k_disassembler::d68000_cmpi_32() { - char* str; - str = get_imm_str_s32(); - sprintf(g_dasm_str, "cmpi.l %s, %s", str, get_ea_mode_str_32(g_cpu_ir)); + std::string str = get_imm_str_s32(); + return util::string_format("cmpi.l %s, %s", str, get_ea_mode_str_32(m_cpu_ir)); } -static void d68020_cmpi_pcdi_32(void) +std::string m68k_disassembler::d68020_cmpi_pcdi_32() { - char* str; - LIMIT_CPU_TYPES(M68010_PLUS); - str = get_imm_str_s32(); - sprintf(g_dasm_str, "cmpi.l %s, %s; (2+)", str, get_ea_mode_str_32(g_cpu_ir)); + auto limit = limit_cpu_types(M68010_PLUS); + if(limit.first) + return limit.second; + std::string str = get_imm_str_s32(); + return util::string_format("cmpi.l %s, %s; (2+)", str, get_ea_mode_str_32(m_cpu_ir)); } -static void d68020_cmpi_pcix_32(void) +std::string m68k_disassembler::d68020_cmpi_pcix_32() { - char* str; - LIMIT_CPU_TYPES(M68010_PLUS); - str = get_imm_str_s32(); - sprintf(g_dasm_str, "cmpi.l %s, %s; (2+)", str, get_ea_mode_str_32(g_cpu_ir)); + auto limit = limit_cpu_types(M68010_PLUS); + if(limit.first) + return limit.second; + std::string str = get_imm_str_s32(); + return util::string_format("cmpi.l %s, %s; (2+)", str, get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_cmpm_8(void) +std::string m68k_disassembler::d68000_cmpm_8() { - sprintf(g_dasm_str, "cmpm.b (A%d)+, (A%d)+", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("cmpm.b (A%d)+, (A%d)+", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_cmpm_16(void) +std::string m68k_disassembler::d68000_cmpm_16() { - sprintf(g_dasm_str, "cmpm.w (A%d)+, (A%d)+", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("cmpm.w (A%d)+, (A%d)+", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_cmpm_32(void) +std::string m68k_disassembler::d68000_cmpm_32() { - sprintf(g_dasm_str, "cmpm.l (A%d)+, (A%d)+", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("cmpm.l (A%d)+, (A%d)+", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68020_cpbcc_16(void) +std::string m68k_disassembler::d68020_cpbcc_16() { - uint32_t extension; - uint32_t new_pc = g_cpu_pc; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + u32 new_pc = m_cpu_pc; + u16 extension = read_imm_16(); new_pc += make_int_16(read_imm_16()); - sprintf(g_dasm_str, "%db%-4s %s; %x (extension = %x) (2-3)", (g_cpu_ir>>9)&7, g_cpcc[g_cpu_ir&0x3f], get_imm_str_s16(), new_pc, extension); + return util::string_format("%db%-4s %s; %x (extension = %x) (2-3)", (m_cpu_ir>>9)&7, m_cpcc[m_cpu_ir&0x3f], get_imm_str_s16(), new_pc, extension); } -static void d68020_cpbcc_32(void) +std::string m68k_disassembler::d68020_cpbcc_32() { - uint32_t extension; - uint32_t new_pc = g_cpu_pc; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + u32 new_pc = m_cpu_pc; + u16 extension = read_imm_16(); new_pc += read_imm_32(); - sprintf(g_dasm_str, "%db%-4s %s; %x (extension = %x) (2-3)", (g_cpu_ir>>9)&7, g_cpcc[g_cpu_ir&0x3f], get_imm_str_s16(), new_pc, extension); + return util::string_format("%db%-4s %s; %x (extension = %x) (2-3)", (m_cpu_ir>>9)&7, m_cpcc[m_cpu_ir&0x3f], get_imm_str_s16(), new_pc, extension); } -static void d68020_cpdbcc(void) +std::string m68k_disassembler::d68020_cpdbcc() { - uint32_t extension1; - uint32_t extension2; - uint32_t new_pc = g_cpu_pc; - LIMIT_CPU_TYPES(M68020_PLUS); - extension1 = read_imm_16(); - extension2 = read_imm_16(); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + u32 new_pc = m_cpu_pc; + u16 extension1 = read_imm_16(); + u16 extension2 = read_imm_16(); new_pc += make_int_16(read_imm_16()); - sprintf(g_dasm_str, "%ddb%-4s D%d,%s; %x (extension = %x) (2-3)", (g_cpu_ir>>9)&7, g_cpcc[extension1&0x3f], g_cpu_ir&7, get_imm_str_s16(), new_pc, extension2); + return util::string_format("%ddb%-4s D%d,%s; %x (extension = %x) (2-3)", (m_cpu_ir>>9)&7, m_cpcc[extension1&0x3f], m_cpu_ir&7, get_imm_str_s16(), new_pc, extension2); } -static void d68020_cpgen(void) +std::string m68k_disassembler::d68020_cpgen() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "%dgen %s; (2-3)", (g_cpu_ir>>9)&7, get_imm_str_u32()); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("%dgen %s; (2-3)", (m_cpu_ir>>9)&7, get_imm_str_u32()); } -static void d68020_cprestore(void) +std::string m68k_disassembler::d68020_cprestore() { - LIMIT_CPU_TYPES(M68020_PLUS); - if (((g_cpu_ir>>9)&7) == 1) + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + if (((m_cpu_ir>>9)&7) == 1) { - sprintf(g_dasm_str, "frestore %s", get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("frestore %s", get_ea_mode_str_8(m_cpu_ir)); } else { - sprintf(g_dasm_str, "%drestore %s; (2-3)", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("%drestore %s; (2-3)", (m_cpu_ir>>9)&7, get_ea_mode_str_8(m_cpu_ir)); } } -static void d68020_cpsave(void) +std::string m68k_disassembler::d68020_cpsave() { - LIMIT_CPU_TYPES(M68020_PLUS); - if (((g_cpu_ir>>9)&7) == 1) + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + if (((m_cpu_ir>>9)&7) == 1) { - sprintf(g_dasm_str, "fsave %s", get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("fsave %s", get_ea_mode_str_8(m_cpu_ir)); } else { - sprintf(g_dasm_str, "%dsave %s; (2-3)", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("%dsave %s; (2-3)", (m_cpu_ir>>9)&7, get_ea_mode_str_8(m_cpu_ir)); } } -static void d68020_cpscc(void) +std::string m68k_disassembler::d68020_cpscc() { - uint32_t extension1; - uint32_t extension2; - LIMIT_CPU_TYPES(M68020_PLUS); - extension1 = read_imm_16(); - extension2 = read_imm_16(); - sprintf(g_dasm_str, "%ds%-4s %s; (extension = %x) (2-3)", (g_cpu_ir>>9)&7, g_cpcc[extension1&0x3f], get_ea_mode_str_8(g_cpu_ir), extension2); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + u16 extension1 = read_imm_16(); + u16 extension2 = read_imm_16(); + return util::string_format("%ds%-4s %s; (extension = %x) (2-3)", (m_cpu_ir>>9)&7, m_cpcc[extension1&0x3f], get_ea_mode_str_8(m_cpu_ir), extension2); } -static void d68020_cptrapcc_0(void) +std::string m68k_disassembler::d68020_cptrapcc_0() { - uint32_t extension1; - uint32_t extension2; - LIMIT_CPU_TYPES(M68020_PLUS); - extension1 = read_imm_16(); - extension2 = read_imm_16(); - sprintf(g_dasm_str, "%dtrap%-4s; (extension = %x) (2-3)", (g_cpu_ir>>9)&7, g_cpcc[extension1&0x3f], extension2); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + u16 extension1 = read_imm_16(); + u16 extension2 = read_imm_16(); + return util::string_format("%dtrap%-4s; (extension = %x) (2-3)", (m_cpu_ir>>9)&7, m_cpcc[extension1&0x3f], extension2); } -static void d68020_cptrapcc_16(void) +std::string m68k_disassembler::d68020_cptrapcc_16() { - uint32_t extension1; - uint32_t extension2; - LIMIT_CPU_TYPES(M68020_PLUS); - extension1 = read_imm_16(); - extension2 = read_imm_16(); - sprintf(g_dasm_str, "%dtrap%-4s %s; (extension = %x) (2-3)", (g_cpu_ir>>9)&7, g_cpcc[extension1&0x3f], get_imm_str_u16(), extension2); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + u16 extension1 = read_imm_16(); + u16 extension2 = read_imm_16(); + return util::string_format("%dtrap%-4s %s; (extension = %x) (2-3)", (m_cpu_ir>>9)&7, m_cpcc[extension1&0x3f], get_imm_str_u16(), extension2); } -static void d68020_cptrapcc_32(void) +std::string m68k_disassembler::d68020_cptrapcc_32() { - uint32_t extension1; - uint32_t extension2; - LIMIT_CPU_TYPES(M68020_PLUS); - extension1 = read_imm_16(); - extension2 = read_imm_16(); - sprintf(g_dasm_str, "%dtrap%-4s %s; (extension = %x) (2-3)", (g_cpu_ir>>9)&7, g_cpcc[extension1&0x3f], get_imm_str_u32(), extension2); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + u16 extension1 = read_imm_16(); + u16 extension2 = read_imm_16(); + return util::string_format("%dtrap%-4s %s; (extension = %x) (2-3)", (m_cpu_ir>>9)&7, m_cpcc[extension1&0x3f], get_imm_str_u32(), extension2); } -static void d68040_cpush(void) +std::string m68k_disassembler::d68040_cpush() { + auto limit = limit_cpu_types(M68040_PLUS); + if(limit.first) + return limit.second; + static const char *cachetype[4] = { "nop", "data", "inst", "both" }; - LIMIT_CPU_TYPES(M68040_PLUS); - switch((g_cpu_ir>>3)&3) + switch((m_cpu_ir>>3)&3) { case 0: - sprintf(g_dasm_str, "cpush (illegal scope); (4)"); + return util::string_format("cpush (illegal scope); (4)"); break; case 1: - sprintf(g_dasm_str, "cpushl %s, (A%d); (4)", cachetype[(g_cpu_ir>>6)&3], g_cpu_ir&7); + return util::string_format("cpushl %s, (A%d); (4)", cachetype[(m_cpu_ir>>6)&3], m_cpu_ir&7); break; case 2: - sprintf(g_dasm_str, "cpushp %s, (A%d); (4)", cachetype[(g_cpu_ir>>6)&3], g_cpu_ir&7); + return util::string_format("cpushp %s, (A%d); (4)", cachetype[(m_cpu_ir>>6)&3], m_cpu_ir&7); break; - case 3: - sprintf(g_dasm_str, "cpusha %s; (4)", cachetype[(g_cpu_ir>>6)&3]); + case 3: default: + return util::string_format("cpusha %s; (4)", cachetype[(m_cpu_ir>>6)&3]); break; } } -static void d68000_dbra(void) +std::string m68k_disassembler::d68000_dbra() { - uint32_t temp_pc = g_cpu_pc; - sprintf(g_dasm_str, "dbra D%d, $%x", g_cpu_ir & 7, temp_pc + make_int_16(read_imm_16())); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + u32 temp_pc = m_cpu_pc; + m_flags = STEP_OVER; + return util::string_format("dbra D%d, $%x", m_cpu_ir & 7, temp_pc + make_int_16(read_imm_16())); } -static void d68000_dbcc(void) +std::string m68k_disassembler::d68000_dbcc() { - uint32_t temp_pc = g_cpu_pc; - sprintf(g_dasm_str, "db%-2s D%d, $%x", g_cc[(g_cpu_ir>>8)&0xf], g_cpu_ir & 7, temp_pc + make_int_16(read_imm_16())); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + u32 temp_pc = m_cpu_pc; + m_flags = STEP_OVER; + return util::string_format("db%-2s D%d, $%x", m_cc[(m_cpu_ir>>8)&0xf], m_cpu_ir & 7, temp_pc + make_int_16(read_imm_16())); } -static void d68000_divs(void) +std::string m68k_disassembler::d68000_divs() { - sprintf(g_dasm_str, "divs.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("divs.w %s, D%d", get_ea_mode_str_16(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_divu(void) +std::string m68k_disassembler::d68000_divu() { - sprintf(g_dasm_str, "divu.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("divu.w %s, D%d", get_ea_mode_str_16(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68020_divl(void) +std::string m68k_disassembler::d68020_divl() { - uint32_t extension; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; - if(BIT_A(extension)) - sprintf(g_dasm_str, "div%c.l %s, D%d:D%d; (2+)", BIT_B(extension) ? 's' : 'u', get_ea_mode_str_32(g_cpu_ir), extension&7, (extension>>12)&7); + u16 extension = read_imm_16(); + + if(BIT(extension, 10)) + return util::string_format("div%c.l %s, D%d:D%d; (2+)", BIT(extension, 11) ? 's' : 'u', get_ea_mode_str_32(m_cpu_ir), extension&7, (extension>>12)&7); else if((extension&7) == ((extension>>12)&7)) - sprintf(g_dasm_str, "div%c.l %s, D%d; (2+)", BIT_B(extension) ? 's' : 'u', get_ea_mode_str_32(g_cpu_ir), (extension>>12)&7); + return util::string_format("div%c.l %s, D%d; (2+)", BIT(extension, 11) ? 's' : 'u', get_ea_mode_str_32(m_cpu_ir), (extension>>12)&7); else - sprintf(g_dasm_str, "div%cl.l %s, D%d:D%d; (2+)", BIT_B(extension) ? 's' : 'u', get_ea_mode_str_32(g_cpu_ir), extension&7, (extension>>12)&7); + return util::string_format("div%cl.l %s, D%d:D%d; (2+)", BIT(extension, 11) ? 's' : 'u', get_ea_mode_str_32(m_cpu_ir), extension&7, (extension>>12)&7); } -static void d68000_eor_8(void) +std::string m68k_disassembler::d68000_eor_8() { - sprintf(g_dasm_str, "eor.b D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("eor.b D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_eor_16(void) +std::string m68k_disassembler::d68000_eor_16() { - sprintf(g_dasm_str, "eor.w D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("eor.w D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_eor_32(void) +std::string m68k_disassembler::d68000_eor_32() { - sprintf(g_dasm_str, "eor.l D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("eor.l D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_eori_8(void) +std::string m68k_disassembler::d68000_eori_8() { - char* str = get_imm_str_u8(); - sprintf(g_dasm_str, "eori.b %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); + std::string str = get_imm_str_u8(); + return util::string_format("eori.b %s, %s", str, get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_eori_16(void) +std::string m68k_disassembler::d68000_eori_16() { - char* str = get_imm_str_u16(); - sprintf(g_dasm_str, "eori.w %s, %s", str, get_ea_mode_str_16(g_cpu_ir)); + std::string str = get_imm_str_u16(); + return util::string_format("eori.w %s, %s", str, get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_eori_32(void) +std::string m68k_disassembler::d68000_eori_32() { - char* str = get_imm_str_u32(); - sprintf(g_dasm_str, "eori.l %s, %s", str, get_ea_mode_str_32(g_cpu_ir)); + std::string str = get_imm_str_u32(); + return util::string_format("eori.l %s, %s", str, get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_eori_to_ccr(void) +std::string m68k_disassembler::d68000_eori_to_ccr() { - sprintf(g_dasm_str, "eori %s, CCR", get_imm_str_u8()); + return util::string_format("eori %s, CCR", get_imm_str_u8()); } -static void d68000_eori_to_sr(void) +std::string m68k_disassembler::d68000_eori_to_sr() { - sprintf(g_dasm_str, "eori %s, SR", get_imm_str_u16()); + return util::string_format("eori %s, SR", get_imm_str_u16()); } -static void d68000_exg_dd(void) +std::string m68k_disassembler::d68000_exg_dd() { - sprintf(g_dasm_str, "exg D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("exg D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_exg_aa(void) +std::string m68k_disassembler::d68000_exg_aa() { - sprintf(g_dasm_str, "exg A%d, A%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("exg A%d, A%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_exg_da(void) +std::string m68k_disassembler::d68000_exg_da() { - sprintf(g_dasm_str, "exg D%d, A%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("exg D%d, A%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_ext_16(void) +std::string m68k_disassembler::d68000_ext_16() { - sprintf(g_dasm_str, "ext.w D%d", g_cpu_ir&7); + return util::string_format("ext.w D%d", m_cpu_ir&7); } -static void d68000_ext_32(void) +std::string m68k_disassembler::d68000_ext_32() { - sprintf(g_dasm_str, "ext.l D%d", g_cpu_ir&7); + return util::string_format("ext.l D%d", m_cpu_ir&7); } -static void d68020_extb_32(void) +std::string m68k_disassembler::d68020_extb_32() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "extb.l D%d; (2+)", g_cpu_ir&7); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("extb.l D%d; (2+)", m_cpu_ir&7); } -static void d68881_ftrap(void) +std::string m68k_disassembler::d68881_ftrap() { - uint16_t w2, w3; - uint32_t l2; - - LIMIT_CPU_TYPES(M68020_PLUS); - w2 = read_imm_16(); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + u16 w2 = read_imm_16(); - switch (g_cpu_ir & 0x7) + switch (m_cpu_ir & 0x7) { case 2: // word operand - w3 = read_imm_16(); - sprintf(g_dasm_str, "ftrap%s.w $%04x", g_cpcc[w2 & 0x3f], w3); - break; + return util::string_format("ftrap%s.w $%04x", m_cpcc[w2 & 0x3f], read_imm_16()); case 3: // long word operand - l2 = read_imm_32(); - sprintf(g_dasm_str, "ftrap%s.l $%08x", g_cpcc[w2 & 0x3f], l2); - break; + return util::string_format("ftrap%s.l $%08x", m_cpcc[w2 & 0x3f], read_imm_32()); case 4: // no operand - sprintf(g_dasm_str, "ftrap%s", g_cpcc[w2 & 0x3f]); - break; + return util::string_format("ftrap%s", m_cpcc[w2 & 0x3f]); } + return util::string_format("ftrap%s<%d>?", m_cpcc[w2 & 0x3f], m_cpu_ir & 7); + } -static void d68040_fpu(void) +std::string m68k_disassembler::d68040_fpu() { char float_data_format[8][3] = { ".l", ".s", ".x", ".p", ".w", ".d", ".b", ".p" }; - char mnemonic[40]; - uint32_t w2, src, dst_reg; - LIMIT_CPU_TYPES(M68020_PLUS); - w2 = read_imm_16(); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + + u16 w2 = read_imm_16(); - src = (w2 >> 10) & 0x7; - dst_reg = (w2 >> 7) & 0x7; + u16 src = (w2 >> 10) & 0x7; + u16 dst_reg = (w2 >> 7) & 0x7; // special override for FMOVECR if ((((w2 >> 13) & 0x7) == 2) && (((w2>>10)&0x7) == 7)) { - sprintf(g_dasm_str, "fmovecr #$%0x, fp%d", (w2&0x7f), dst_reg); - return; + return util::string_format("fmovecr #$%0x, fp%d", (w2&0x7f), dst_reg); } + std::string mnemonic; switch ((w2 >> 13) & 0x7) { case 0x0: @@ -1766,72 +1428,71 @@ static void d68040_fpu(void) { switch(w2 & 0x7f) { - case 0x00: sprintf(mnemonic, "fmove"); break; - case 0x01: sprintf(mnemonic, "fint"); break; - case 0x02: sprintf(mnemonic, "fsinh"); break; - case 0x03: sprintf(mnemonic, "fintrz"); break; - case 0x04: sprintf(mnemonic, "fsqrt"); break; - case 0x06: sprintf(mnemonic, "flognp1"); break; - case 0x08: sprintf(mnemonic, "fetoxm1"); break; - case 0x09: sprintf(mnemonic, "ftanh1"); break; - case 0x0a: sprintf(mnemonic, "fatan"); break; - case 0x0c: sprintf(mnemonic, "fasin"); break; - case 0x0d: sprintf(mnemonic, "fatanh"); break; - case 0x0e: sprintf(mnemonic, "fsin"); break; - case 0x0f: sprintf(mnemonic, "ftan"); break; - case 0x10: sprintf(mnemonic, "fetox"); break; - case 0x11: sprintf(mnemonic, "ftwotox"); break; - case 0x12: sprintf(mnemonic, "ftentox"); break; - case 0x14: sprintf(mnemonic, "flogn"); break; - case 0x15: sprintf(mnemonic, "flog10"); break; - case 0x16: sprintf(mnemonic, "flog2"); break; - case 0x18: sprintf(mnemonic, "fabs"); break; - case 0x19: sprintf(mnemonic, "fcosh"); break; - case 0x1a: sprintf(mnemonic, "fneg"); break; - case 0x1c: sprintf(mnemonic, "facos"); break; - case 0x1d: sprintf(mnemonic, "fcos"); break; - case 0x1e: sprintf(mnemonic, "fgetexp"); break; - case 0x1f: sprintf(mnemonic, "fgetman"); break; - case 0x20: sprintf(mnemonic, "fdiv"); break; - case 0x21: sprintf(mnemonic, "fmod"); break; - case 0x22: sprintf(mnemonic, "fadd"); break; - case 0x23: sprintf(mnemonic, "fmul"); break; - case 0x24: sprintf(mnemonic, "fsgldiv"); break; - case 0x25: sprintf(mnemonic, "frem"); break; - case 0x26: sprintf(mnemonic, "fscale"); break; - case 0x27: sprintf(mnemonic, "fsglmul"); break; - case 0x28: sprintf(mnemonic, "fsub"); break; + case 0x00: mnemonic = "fmove"; break; + case 0x01: mnemonic = "fint"; break; + case 0x02: mnemonic = "fsinh"; break; + case 0x03: mnemonic = "fintrz"; break; + case 0x04: mnemonic = "fsqrt"; break; + case 0x06: mnemonic = "flognp1"; break; + case 0x08: mnemonic = "fetoxm1"; break; + case 0x09: mnemonic = "ftanh1"; break; + case 0x0a: mnemonic = "fatan"; break; + case 0x0c: mnemonic = "fasin"; break; + case 0x0d: mnemonic = "fatanh"; break; + case 0x0e: mnemonic = "fsin"; break; + case 0x0f: mnemonic = "ftan"; break; + case 0x10: mnemonic = "fetox"; break; + case 0x11: mnemonic = "ftwotox"; break; + case 0x12: mnemonic = "ftentox"; break; + case 0x14: mnemonic = "flogn"; break; + case 0x15: mnemonic = "flog10"; break; + case 0x16: mnemonic = "flog2"; break; + case 0x18: mnemonic = "fabs"; break; + case 0x19: mnemonic = "fcosh"; break; + case 0x1a: mnemonic = "fneg"; break; + case 0x1c: mnemonic = "facos"; break; + case 0x1d: mnemonic = "fcos"; break; + case 0x1e: mnemonic = "fgetexp"; break; + case 0x1f: mnemonic = "fgetman"; break; + case 0x20: mnemonic = "fdiv"; break; + case 0x21: mnemonic = "fmod"; break; + case 0x22: mnemonic = "fadd"; break; + case 0x23: mnemonic = "fmul"; break; + case 0x24: mnemonic = "fsgldiv"; break; + case 0x25: mnemonic = "frem"; break; + case 0x26: mnemonic = "fscale"; break; + case 0x27: mnemonic = "fsglmul"; break; + case 0x28: mnemonic = "fsub"; break; case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: - sprintf(mnemonic, "fsincos"); break; - case 0x38: sprintf(mnemonic, "fcmp"); break; - case 0x3a: sprintf(mnemonic, "ftst"); break; - case 0x41: sprintf(mnemonic, "fssqrt"); break; - case 0x45: sprintf(mnemonic, "fdsqrt"); break; - case 0x58: sprintf(mnemonic, "fsabs"); break; - case 0x5a: sprintf(mnemonic, "fsneg"); break; - case 0x5c: sprintf(mnemonic, "fdabs"); break; - case 0x5e: sprintf(mnemonic, "fdneg"); break; - case 0x60: sprintf(mnemonic, "fsdiv"); break; - case 0x62: sprintf(mnemonic, "fsadd"); break; - case 0x63: sprintf(mnemonic, "fsmul"); break; - case 0x64: sprintf(mnemonic, "fddiv"); break; - case 0x66: sprintf(mnemonic, "fdadd"); break; - case 0x67: sprintf(mnemonic, "fdmul"); break; - case 0x68: sprintf(mnemonic, "fssub"); break; - case 0x6c: sprintf(mnemonic, "fdsub"); break; - - default: sprintf(mnemonic, "FPU (?)"); break; + mnemonic = "fsincos"; break; + case 0x38: mnemonic = "fcmp"; break; + case 0x3a: mnemonic = "ftst"; break; + case 0x41: mnemonic = "fssqrt"; break; + case 0x45: mnemonic = "fdsqrt"; break; + case 0x58: mnemonic = "fsabs"; break; + case 0x5a: mnemonic = "fsneg"; break; + case 0x5c: mnemonic = "fdabs"; break; + case 0x5e: mnemonic = "fdneg"; break; + case 0x60: mnemonic = "fsdiv"; break; + case 0x62: mnemonic = "fsadd"; break; + case 0x63: mnemonic = "fsmul"; break; + case 0x64: mnemonic = "fddiv"; break; + case 0x66: mnemonic = "fdadd"; break; + case 0x67: mnemonic = "fdmul"; break; + case 0x68: mnemonic = "fssub"; break; + case 0x6c: mnemonic = "fdsub"; break; + + default: mnemonic = "FPU (?)"; break; } if (w2 & 0x4000) { - sprintf(g_dasm_str, "%s%s %s, FP%d", mnemonic, float_data_format[src], get_ea_mode_str_32(g_cpu_ir), dst_reg); + return util::string_format("%s%s %s, FP%d", mnemonic, float_data_format[src], get_ea_mode_str_32(m_cpu_ir), dst_reg); } else { - sprintf(g_dasm_str, "%s.x FP%d, FP%d", mnemonic, src, dst_reg); + return util::string_format("%s.x FP%d, FP%d", mnemonic, src, dst_reg); } - break; } case 0x3: @@ -1839,15 +1500,13 @@ static void d68040_fpu(void) switch ((w2>>10)&7) { case 3: // packed decimal w/fixed k-factor - sprintf(g_dasm_str, "fmove%s FP%d, %s {#%d}", float_data_format[(w2>>10)&7], dst_reg, get_ea_mode_str_32(g_cpu_ir), sext_7bit_int(w2&0x7f)); - break; + return util::string_format("fmove%s FP%d, %s {#%d}", float_data_format[(w2>>10)&7], dst_reg, get_ea_mode_str_32(m_cpu_ir), sext_7bit_int(w2&0x7f)); case 7: // packed decimal w/dynamic k-factor (register) - sprintf(g_dasm_str, "fmove%s FP%d, %s {D%d}", float_data_format[(w2>>10)&7], dst_reg, get_ea_mode_str_32(g_cpu_ir), (w2>>4)&7); - break; + return util::string_format("fmove%s FP%d, %s {D%d}", float_data_format[(w2>>10)&7], dst_reg, get_ea_mode_str_32(m_cpu_ir), (w2>>4)&7); default: - sprintf(g_dasm_str, "fmove%s FP%d, %s", float_data_format[(w2>>10)&7], dst_reg, get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("fmove%s FP%d, %s", float_data_format[(w2>>10)&7], dst_reg, get_ea_mode_str_32(m_cpu_ir)); break; } break; @@ -1855,264 +1514,250 @@ static void d68040_fpu(void) case 0x4: // ea to control { - sprintf(g_dasm_str, "fmovem.l %s, ", get_ea_mode_str_32(g_cpu_ir)); - if (w2 & 0x1000) strcat(g_dasm_str, "fpcr"); - if (w2 & 0x0800) strcat(g_dasm_str, "/fpsr"); - if (w2 & 0x0400) strcat(g_dasm_str, "/fpiar"); - break; + std::string dasm = util::string_format("fmovem.l %s, ", get_ea_mode_str_32(m_cpu_ir)); + if (w2 & 0x1000) return dasm + "fpcr"; + if (w2 & 0x0800) return dasm + "/fpsr"; + if (w2 & 0x0400) return dasm + "/fpiar"; + return dasm; } case 0x5: // control to ea { - strcpy(g_dasm_str, "fmovem.l "); - if (w2 & 0x1000) strcat(g_dasm_str, "fpcr"); - if (w2 & 0x0800) strcat(g_dasm_str, "/fpsr"); - if (w2 & 0x0400) strcat(g_dasm_str, "/fpiar"); - strcat(g_dasm_str, ", "); - strcat(g_dasm_str, get_ea_mode_str_32(g_cpu_ir)); - break; + std::string dasm = "fmovem.l "; + if (w2 & 0x1000) dasm += "fpcr"; + if (w2 & 0x0800) dasm += "/fpsr"; + if (w2 & 0x0400) dasm += "/fpiar"; + return dasm + ", " + get_ea_mode_str_32(m_cpu_ir); } case 0x6: // memory to FPU, list { - char temp[32]; - if ((w2>>11) & 1) // dynamic register list { - sprintf(g_dasm_str, "fmovem.x %s, D%d", get_ea_mode_str_32(g_cpu_ir), (w2>>4)&7); + return util::string_format("fmovem.x %s, D%d", get_ea_mode_str_32(m_cpu_ir), (w2>>4)&7); } else // static register list { - int i; - - sprintf(g_dasm_str, "fmovem.x %s, ", get_ea_mode_str_32(g_cpu_ir)); + std::string dasm = util::string_format("fmovem.x %s, ", get_ea_mode_str_32(m_cpu_ir)); - for (i = 0; i < 8; i++) + for (int i = 0; i < 8; i++) { if (w2 & (1<<i)) { if ((w2>>12) & 1) // postincrement or control { - sprintf(temp, "FP%d ", 7-i); + dasm += util::string_format("FP%d ", 7-i); } else // predecrement { - sprintf(temp, "FP%d ", i); + dasm += util::string_format("FP%d ", i); } - strcat(g_dasm_str, temp); } } + return dasm; } - break; } case 0x7: // FPU to memory, list { - char temp[32]; - if ((w2>>11) & 1) // dynamic register list { - sprintf(g_dasm_str, "fmovem.x D%d, %s", (w2>>4)&7, get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("fmovem.x D%d, %s", (w2>>4)&7, get_ea_mode_str_32(m_cpu_ir)); } else // static register list { - int i; + std::string dasm = util::string_format("fmovem.x "); - sprintf(g_dasm_str, "fmovem.x "); - - for (i = 0; i < 8; i++) + for (int i = 0; i < 8; i++) { if (w2 & (1<<i)) { if ((w2>>12) & 1) // postincrement or control { - sprintf(temp, "FP%d ", 7-i); + dasm += util::string_format("FP%d ", 7-i); } else // predecrement { - sprintf(temp, "FP%d ", i); + dasm += util::string_format("FP%d ", i); } - strcat(g_dasm_str, temp); } } - strcat(g_dasm_str, ", "); - strcat(g_dasm_str, get_ea_mode_str_32(g_cpu_ir)); + return dasm + ", " + get_ea_mode_str_32(m_cpu_ir); } - break; - } - - default: - { - sprintf(g_dasm_str, "FPU (?) "); - break; } } + return util::string_format("FPU (?) "); } -static void d68000_jmp(void) +std::string m68k_disassembler::d68000_jmp() { - sprintf(g_dasm_str, "jmp %s", get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("jmp %s", get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_jsr(void) +std::string m68k_disassembler::d68000_jsr() { - sprintf(g_dasm_str, "jsr %s", get_ea_mode_str_32(g_cpu_ir)); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + m_flags = STEP_OVER; + return util::string_format("jsr %s", get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_lea(void) +std::string m68k_disassembler::d68000_lea() { - sprintf(g_dasm_str, "lea %s, A%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("lea %s, A%d", get_ea_mode_str_32(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_link_16(void) +std::string m68k_disassembler::d68000_link_16() { - sprintf(g_dasm_str, "link A%d, %s", g_cpu_ir&7, get_imm_str_s16()); + return util::string_format("link A%d, %s", m_cpu_ir&7, get_imm_str_s16()); } -static void d68020_link_32(void) +std::string m68k_disassembler::d68020_link_32() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "link A%d, %s; (2+)", g_cpu_ir&7, get_imm_str_s32()); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("link A%d, %s; (2+)", m_cpu_ir&7, get_imm_str_s32()); } -static void d68000_lsr_s_8(void) +std::string m68k_disassembler::d68000_lsr_s_8() { - sprintf(g_dasm_str, "lsr.b #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("lsr.b #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_lsr_s_16(void) +std::string m68k_disassembler::d68000_lsr_s_16() { - sprintf(g_dasm_str, "lsr.w #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("lsr.w #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_lsr_s_32(void) +std::string m68k_disassembler::d68000_lsr_s_32() { - sprintf(g_dasm_str, "lsr.l #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("lsr.l #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_lsr_r_8(void) +std::string m68k_disassembler::d68000_lsr_r_8() { - sprintf(g_dasm_str, "lsr.b D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("lsr.b D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_lsr_r_16(void) +std::string m68k_disassembler::d68000_lsr_r_16() { - sprintf(g_dasm_str, "lsr.w D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("lsr.w D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_lsr_r_32(void) +std::string m68k_disassembler::d68000_lsr_r_32() { - sprintf(g_dasm_str, "lsr.l D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("lsr.l D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_lsr_ea(void) +std::string m68k_disassembler::d68000_lsr_ea() { - sprintf(g_dasm_str, "lsr.w %s", get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("lsr.w %s", get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_lsl_s_8(void) +std::string m68k_disassembler::d68000_lsl_s_8() { - sprintf(g_dasm_str, "lsl.b #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("lsl.b #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_lsl_s_16(void) +std::string m68k_disassembler::d68000_lsl_s_16() { - sprintf(g_dasm_str, "lsl.w #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("lsl.w #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_lsl_s_32(void) +std::string m68k_disassembler::d68000_lsl_s_32() { - sprintf(g_dasm_str, "lsl.l #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("lsl.l #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_lsl_r_8(void) +std::string m68k_disassembler::d68000_lsl_r_8() { - sprintf(g_dasm_str, "lsl.b D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("lsl.b D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_lsl_r_16(void) +std::string m68k_disassembler::d68000_lsl_r_16() { - sprintf(g_dasm_str, "lsl.w D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("lsl.w D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_lsl_r_32(void) +std::string m68k_disassembler::d68000_lsl_r_32() { - sprintf(g_dasm_str, "lsl.l D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("lsl.l D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_lsl_ea(void) +std::string m68k_disassembler::d68000_lsl_ea() { - sprintf(g_dasm_str, "lsl.w %s", get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("lsl.w %s", get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_move_8(void) +std::string m68k_disassembler::d68000_move_8() { - char* str = get_ea_mode_str_8(g_cpu_ir); - sprintf(g_dasm_str, "move.b %s, %s", str, get_ea_mode_str_8(((g_cpu_ir>>9) & 7) | ((g_cpu_ir>>3) & 0x38))); + std::string str = get_ea_mode_str_8(m_cpu_ir); + return util::string_format("move.b %s, %s", str, get_ea_mode_str_8(((m_cpu_ir>>9) & 7) | ((m_cpu_ir>>3) & 0x38))); } -static void d68000_move_16(void) +std::string m68k_disassembler::d68000_move_16() { - char* str = get_ea_mode_str_16(g_cpu_ir); - sprintf(g_dasm_str, "move.w %s, %s", str, get_ea_mode_str_16(((g_cpu_ir>>9) & 7) | ((g_cpu_ir>>3) & 0x38))); + std::string str = get_ea_mode_str_16(m_cpu_ir); + return util::string_format("move.w %s, %s", str, get_ea_mode_str_16(((m_cpu_ir>>9) & 7) | ((m_cpu_ir>>3) & 0x38))); } -static void d68000_move_32(void) +std::string m68k_disassembler::d68000_move_32() { - char* str = get_ea_mode_str_32(g_cpu_ir); - sprintf(g_dasm_str, "move.l %s, %s", str, get_ea_mode_str_32(((g_cpu_ir>>9) & 7) | ((g_cpu_ir>>3) & 0x38))); + std::string str = get_ea_mode_str_32(m_cpu_ir); + return util::string_format("move.l %s, %s", str, get_ea_mode_str_32(((m_cpu_ir>>9) & 7) | ((m_cpu_ir>>3) & 0x38))); } -static void d68000_movea_16(void) +std::string m68k_disassembler::d68000_movea_16() { - sprintf(g_dasm_str, "movea.w %s, A%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("movea.w %s, A%d", get_ea_mode_str_16(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_movea_32(void) +std::string m68k_disassembler::d68000_movea_32() { - sprintf(g_dasm_str, "movea.l %s, A%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("movea.l %s, A%d", get_ea_mode_str_32(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_move_to_ccr(void) +std::string m68k_disassembler::d68000_move_to_ccr() { - sprintf(g_dasm_str, "move %s, CCR", get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("move %s, CCR", get_ea_mode_str_8(m_cpu_ir)); } -static void d68010_move_fr_ccr(void) +std::string m68k_disassembler::d68010_move_fr_ccr() { - LIMIT_CPU_TYPES(M68010_PLUS); - sprintf(g_dasm_str, "move CCR, %s; (1+)", get_ea_mode_str_8(g_cpu_ir)); + auto limit = limit_cpu_types(M68010_PLUS); + if(limit.first) + return limit.second; + return util::string_format("move CCR, %s; (1+)", get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_move_fr_sr(void) +std::string m68k_disassembler::d68000_move_fr_sr() { - sprintf(g_dasm_str, "move SR, %s", get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("move SR, %s", get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_move_to_sr(void) +std::string m68k_disassembler::d68000_move_to_sr() { - sprintf(g_dasm_str, "move %s, SR", get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("move %s, SR", get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_move_fr_usp(void) +std::string m68k_disassembler::d68000_move_fr_usp() { - sprintf(g_dasm_str, "move USP, A%d", g_cpu_ir&7); + return util::string_format("move USP, A%d", m_cpu_ir&7); } -static void d68000_move_to_usp(void) +std::string m68k_disassembler::d68000_move_to_usp() { - sprintf(g_dasm_str, "move A%d, USP", g_cpu_ir&7); + return util::string_format("move A%d, USP", m_cpu_ir&7); } -static void d68010_movec(void) +std::string m68k_disassembler::d68010_movec() { - uint32_t extension; - const char* reg_name; - const char* processor; - LIMIT_CPU_TYPES(M68010_PLUS); - extension = read_imm_16(); + auto limit = limit_cpu_types(M68010_PLUS); + if(limit.first) + return limit.second; + + std::string reg_name, processor; + u16 extension = read_imm_16(); switch(extension & 0xfff) { @@ -2153,7 +1798,7 @@ static void d68010_movec(void) processor = "4+"; break; case 0x004: - if(g_cpu_type & COLDFIRE) + if(m_cpu_type & COLDFIRE) { reg_name = "ACR0"; processor = "CF"; @@ -2165,7 +1810,7 @@ static void d68010_movec(void) } break; case 0x005: - if(g_cpu_type & COLDFIRE) + if(m_cpu_type & COLDFIRE) { reg_name = "ACR1"; processor = "CF"; @@ -2177,7 +1822,7 @@ static void d68010_movec(void) } break; case 0x006: - if(g_cpu_type & COLDFIRE) + if(m_cpu_type & COLDFIRE) { reg_name = "ACR2"; processor = "CF"; @@ -2189,7 +1834,7 @@ static void d68010_movec(void) } break; case 0x007: - if(g_cpu_type & COLDFIRE) + if(m_cpu_type & COLDFIRE) { reg_name = "ACR3"; processor = "CF"; @@ -2249,994 +1894,1026 @@ static void d68010_movec(void) processor = "?"; } - if(BIT_0(g_cpu_ir)) - sprintf(g_dasm_str, "movec %c%d, %s; (%s)", BIT_F(extension) ? 'A' : 'D', (extension>>12)&7, reg_name, processor); + if(BIT(m_cpu_ir, 0)) + return util::string_format("movec %c%d, %s; (%s)", BIT(extension, 15) ? 'A' : 'D', (extension>>12)&7, reg_name, processor); else - sprintf(g_dasm_str, "movec %s, %c%d; (%s)", reg_name, BIT_F(extension) ? 'A' : 'D', (extension>>12)&7, processor); + return util::string_format("movec %s, %c%d; (%s)", reg_name, BIT(extension, 15) ? 'A' : 'D', (extension>>12)&7, processor); } -static void d68000_movem_pd_16(void) +std::string m68k_disassembler::d68000_movem_pd_16() { - uint32_t data = read_imm_16(); - char buffer[40]; - uint32_t first; - uint32_t run_length; - uint32_t i; + u32 data = read_imm_16(); - buffer[0] = 0; - for(i=0;i<8;i++) + std::string regs; + for(int i=0;i<8;i++) { if(data&(1<<(15-i))) { - first = i; - run_length = 0; + int first = i; + int run_length = 0; while(i<7 && (data&(1<<(15-(i+1))))) { i++; run_length++; } - if(buffer[0] != 0) - strcat(buffer, "/"); - sprintf(buffer+strlen(buffer), "D%d", first); + if(!regs.empty()) + regs += '/'; + regs += util::string_format("D%d", first); if(run_length > 0) - sprintf(buffer+strlen(buffer), "-D%d", first + run_length); + regs += util::string_format("-D%d", first + run_length); } } - for(i=0;i<8;i++) + for(int i=0;i<8;i++) { if(data&(1<<(7-i))) { - first = i; - run_length = 0; + int first = i; + int run_length = 0; while(i<7 && (data&(1<<(7-(i+1))))) { i++; run_length++; } - if(buffer[0] != 0) - strcat(buffer, "/"); - sprintf(buffer+strlen(buffer), "A%d", first); + if(!regs.empty()) + regs += '/'; + regs += util::string_format("A%d", first); if(run_length > 0) - sprintf(buffer+strlen(buffer), "-A%d", first + run_length); + regs += util::string_format("-A%d", first + run_length); } } - sprintf(g_dasm_str, "movem.w %s, %s", buffer, get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("movem.w %s, %s", regs, get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_movem_pd_32(void) +std::string m68k_disassembler::d68000_movem_pd_32() { - uint32_t data = read_imm_16(); - char buffer[40]; - uint32_t first; - uint32_t run_length; - uint32_t i; + u32 data = read_imm_16(); - buffer[0] = 0; - for(i=0;i<8;i++) + std::string regs; + for(int i=0;i<8;i++) { if(data&(1<<(15-i))) { - first = i; - run_length = 0; + int first = i; + int run_length = 0; while(i<7 && (data&(1<<(15-(i+1))))) { i++; run_length++; } - if(buffer[0] != 0) - strcat(buffer, "/"); - sprintf(buffer+strlen(buffer), "D%d", first); + if(!regs.empty()) + regs += '/'; + regs += util::string_format("D%d", first); if(run_length > 0) - sprintf(buffer+strlen(buffer), "-D%d", first + run_length); + regs += util::string_format("-D%d", first + run_length); } } - for(i=0;i<8;i++) + for(int i=0;i<8;i++) { if(data&(1<<(7-i))) { - first = i; - run_length = 0; + int first = i; + int run_length = 0; while(i<7 && (data&(1<<(7-(i+1))))) { i++; run_length++; } - if(buffer[0] != 0) - strcat(buffer, "/"); - sprintf(buffer+strlen(buffer), "A%d", first); + if(!regs.empty()) + regs += '/'; + regs += util::string_format("A%d", first); if(run_length > 0) - sprintf(buffer+strlen(buffer), "-A%d", first + run_length); + regs += util::string_format("-A%d", first + run_length); } } - sprintf(g_dasm_str, "movem.l %s, %s", buffer, get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("movem.l %s, %s", regs, get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_movem_er_16(void) +std::string m68k_disassembler::d68000_movem_er_16() { - uint32_t data = read_imm_16(); - char buffer[40]; - uint32_t first; - uint32_t run_length; - uint32_t i; + u32 data = read_imm_16(); - buffer[0] = 0; - for(i=0;i<8;i++) + std::string regs; + for(int i=0;i<8;i++) { if(data&(1<<i)) { - first = i; - run_length = 0; + int first = i; + int run_length = 0; while(i<7 && (data&(1<<(i+1)))) { i++; run_length++; } - if(buffer[0] != 0) - strcat(buffer, "/"); - sprintf(buffer+strlen(buffer), "D%d", first); + if(!regs.empty()) + regs += '/'; + regs += util::string_format("D%d", first); if(run_length > 0) - sprintf(buffer+strlen(buffer), "-D%d", first + run_length); + regs += util::string_format("-D%d", first + run_length); } } - for(i=0;i<8;i++) + for(int i=0;i<8;i++) { if(data&(1<<(i+8))) { - first = i; - run_length = 0; + int first = i; + int run_length = 0; while(i<7 && (data&(1<<(i+8+1)))) { i++; run_length++; } - if(buffer[0] != 0) - strcat(buffer, "/"); - sprintf(buffer+strlen(buffer), "A%d", first); + if(!regs.empty()) + regs += '/'; + regs += util::string_format("A%d", first); if(run_length > 0) - sprintf(buffer+strlen(buffer), "-A%d", first + run_length); + regs += util::string_format("-A%d", first + run_length); } } - sprintf(g_dasm_str, "movem.w %s, %s", get_ea_mode_str_16(g_cpu_ir), buffer); + return util::string_format("movem.w %s, %s", get_ea_mode_str_16(m_cpu_ir), regs); } -static void d68000_movem_er_32(void) +std::string m68k_disassembler::d68000_movem_er_32() { - uint32_t data = read_imm_16(); - char buffer[40]; - uint32_t first; - uint32_t run_length; - uint32_t i; + u32 data = read_imm_16(); - buffer[0] = 0; - for(i=0;i<8;i++) + std::string regs; + for(int i=0;i<8;i++) { if(data&(1<<i)) { - first = i; - run_length = 0; + int first = i; + int run_length = 0; while(i<7 && (data&(1<<(i+1)))) { i++; run_length++; } - if(buffer[0] != 0) - strcat(buffer, "/"); - sprintf(buffer+strlen(buffer), "D%d", first); + if(!regs.empty()) + regs += '/'; + regs += util::string_format("D%d", first); if(run_length > 0) - sprintf(buffer+strlen(buffer), "-D%d", first + run_length); + regs += util::string_format("-D%d", first + run_length); } } - for(i=0;i<8;i++) + for(int i=0;i<8;i++) { if(data&(1<<(i+8))) { - first = i; - run_length = 0; + int first = i; + int run_length = 0; while(i<7 && (data&(1<<(i+8+1)))) { i++; run_length++; } - if(buffer[0] != 0) - strcat(buffer, "/"); - sprintf(buffer+strlen(buffer), "A%d", first); + if(!regs.empty()) + regs += '/'; + regs += util::string_format("A%d", first); if(run_length > 0) - sprintf(buffer+strlen(buffer), "-A%d", first + run_length); + regs += util::string_format("-A%d", first + run_length); } } - sprintf(g_dasm_str, "movem.l %s, %s", get_ea_mode_str_32(g_cpu_ir), buffer); + return util::string_format("movem.l %s, %s", get_ea_mode_str_32(m_cpu_ir), regs); } -static void d68000_movem_re_16(void) +std::string m68k_disassembler::d68000_movem_re_16() { - uint32_t data = read_imm_16(); - char buffer[40]; - uint32_t first; - uint32_t run_length; - uint32_t i; + u32 data = read_imm_16(); - buffer[0] = 0; - for(i=0;i<8;i++) + std::string regs; + for(int i=0;i<8;i++) { if(data&(1<<i)) { - first = i; - run_length = 0; + int first = i; + int run_length = 0; while(i<7 && (data&(1<<(i+1)))) { i++; run_length++; } - if(buffer[0] != 0) - strcat(buffer, "/"); - sprintf(buffer+strlen(buffer), "D%d", first); + if(!regs.empty()) + regs += '/'; + regs += util::string_format("D%d", first); if(run_length > 0) - sprintf(buffer+strlen(buffer), "-D%d", first + run_length); + regs += util::string_format("-D%d", first + run_length); } } - for(i=0;i<8;i++) + for(int i=0;i<8;i++) { if(data&(1<<(i+8))) { - first = i; - run_length = 0; + int first = i; + int run_length = 0; while(i<7 && (data&(1<<(i+8+1)))) { i++; run_length++; } - if(buffer[0] != 0) - strcat(buffer, "/"); - sprintf(buffer+strlen(buffer), "A%d", first); + if(!regs.empty()) + regs += '/'; + regs += util::string_format("A%d", first); if(run_length > 0) - sprintf(buffer+strlen(buffer), "-A%d", first + run_length); + regs += util::string_format("-A%d", first + run_length); } } - sprintf(g_dasm_str, "movem.w %s, %s", buffer, get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("movem.w %s, %s", regs, get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_movem_re_32(void) +std::string m68k_disassembler::d68000_movem_re_32() { - uint32_t data = read_imm_16(); - char buffer[40]; - uint32_t first; - uint32_t run_length; - uint32_t i; + u32 data = read_imm_16(); - buffer[0] = 0; - for(i=0;i<8;i++) + std::string regs; + for(int i=0;i<8;i++) { if(data&(1<<i)) { - first = i; - run_length = 0; + int first = i; + int run_length = 0; while(i<7 && (data&(1<<(i+1)))) { i++; run_length++; } - if(buffer[0] != 0) - strcat(buffer, "/"); - sprintf(buffer+strlen(buffer), "D%d", first); + if(!regs.empty()) + regs += '/'; + regs += util::string_format("D%d", first); if(run_length > 0) - sprintf(buffer+strlen(buffer), "-D%d", first + run_length); + regs += util::string_format("-D%d", first + run_length); } } - for(i=0;i<8;i++) + for(int i=0;i<8;i++) { if(data&(1<<(i+8))) { - first = i; - run_length = 0; + int first = i; + int run_length = 0; while(i<7 && (data&(1<<(i+8+1)))) { i++; run_length++; } - if(buffer[0] != 0) - strcat(buffer, "/"); - sprintf(buffer+strlen(buffer), "A%d", first); + if(!regs.empty()) + regs += '/'; + regs += util::string_format("A%d", first); if(run_length > 0) - sprintf(buffer+strlen(buffer), "-A%d", first + run_length); + regs += util::string_format("-A%d", first + run_length); } } - sprintf(g_dasm_str, "movem.l %s, %s", buffer, get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("movem.l %s, %s", regs, get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_movep_re_16(void) +std::string m68k_disassembler::d68000_movep_re_16() { - sprintf(g_dasm_str, "movep.w D%d, ($%x,A%d)", (g_cpu_ir>>9)&7, read_imm_16(), g_cpu_ir&7); + return util::string_format("movep.w D%d, ($%x,A%d)", (m_cpu_ir>>9)&7, read_imm_16(), m_cpu_ir&7); } -static void d68000_movep_re_32(void) +std::string m68k_disassembler::d68000_movep_re_32() { - sprintf(g_dasm_str, "movep.l D%d, ($%x,A%d)", (g_cpu_ir>>9)&7, read_imm_16(), g_cpu_ir&7); + return util::string_format("movep.l D%d, ($%x,A%d)", (m_cpu_ir>>9)&7, read_imm_16(), m_cpu_ir&7); } -static void d68000_movep_er_16(void) +std::string m68k_disassembler::d68000_movep_er_16() { - sprintf(g_dasm_str, "movep.w ($%x,A%d), D%d", read_imm_16(), g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("movep.w ($%x,A%d), D%d", read_imm_16(), m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_movep_er_32(void) +std::string m68k_disassembler::d68000_movep_er_32() { - sprintf(g_dasm_str, "movep.l ($%x,A%d), D%d", read_imm_16(), g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("movep.l ($%x,A%d), D%d", read_imm_16(), m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68010_moves_8(void) +std::string m68k_disassembler::d68010_moves_8() { - uint32_t extension; - LIMIT_CPU_TYPES(M68010_PLUS); - extension = read_imm_16(); - if(BIT_B(extension)) - sprintf(g_dasm_str, "moves.b %c%d, %s; (1+)", BIT_F(extension) ? 'A' : 'D', (extension>>12)&7, get_ea_mode_str_8(g_cpu_ir)); + auto limit = limit_cpu_types(M68010_PLUS); + if(limit.first) + return limit.second; + u16 extension = read_imm_16(); + if(BIT(extension, 11)) + return util::string_format("moves.b %c%d, %s; (1+)", BIT(extension, 15) ? 'A' : 'D', (extension>>12)&7, get_ea_mode_str_8(m_cpu_ir)); else - sprintf(g_dasm_str, "moves.b %s, %c%d; (1+)", get_ea_mode_str_8(g_cpu_ir), BIT_F(extension) ? 'A' : 'D', (extension>>12)&7); + return util::string_format("moves.b %s, %c%d; (1+)", get_ea_mode_str_8(m_cpu_ir), BIT(extension, 15) ? 'A' : 'D', (extension>>12)&7); } -static void d68010_moves_16(void) +std::string m68k_disassembler::d68010_moves_16() { - uint32_t extension; - LIMIT_CPU_TYPES(M68010_PLUS); - extension = read_imm_16(); - if(BIT_B(extension)) - sprintf(g_dasm_str, "moves.w %c%d, %s; (1+)", BIT_F(extension) ? 'A' : 'D', (extension>>12)&7, get_ea_mode_str_16(g_cpu_ir)); + auto limit = limit_cpu_types(M68010_PLUS); + if(limit.first) + return limit.second; + u16 extension = read_imm_16(); + if(BIT(extension, 11)) + return util::string_format("moves.w %c%d, %s; (1+)", BIT(extension, 15) ? 'A' : 'D', (extension>>12)&7, get_ea_mode_str_16(m_cpu_ir)); else - sprintf(g_dasm_str, "moves.w %s, %c%d; (1+)", get_ea_mode_str_16(g_cpu_ir), BIT_F(extension) ? 'A' : 'D', (extension>>12)&7); + return util::string_format("moves.w %s, %c%d; (1+)", get_ea_mode_str_16(m_cpu_ir), BIT(extension, 15) ? 'A' : 'D', (extension>>12)&7); } -static void d68010_moves_32(void) +std::string m68k_disassembler::d68010_moves_32() { - uint32_t extension; - LIMIT_CPU_TYPES(M68010_PLUS); - extension = read_imm_16(); - if(BIT_B(extension)) - sprintf(g_dasm_str, "moves.l %c%d, %s; (1+)", BIT_F(extension) ? 'A' : 'D', (extension>>12)&7, get_ea_mode_str_32(g_cpu_ir)); + auto limit = limit_cpu_types(M68010_PLUS); + if(limit.first) + return limit.second; + u16 extension = read_imm_16(); + if(BIT(extension, 11)) + return util::string_format("moves.l %c%d, %s; (1+)", BIT(extension, 15) ? 'A' : 'D', (extension>>12)&7, get_ea_mode_str_32(m_cpu_ir)); else - sprintf(g_dasm_str, "moves.l %s, %c%d; (1+)", get_ea_mode_str_32(g_cpu_ir), BIT_F(extension) ? 'A' : 'D', (extension>>12)&7); + return util::string_format("moves.l %s, %c%d; (1+)", get_ea_mode_str_32(m_cpu_ir), BIT(extension, 15) ? 'A' : 'D', (extension>>12)&7); } -static void d68000_moveq(void) +std::string m68k_disassembler::d68000_moveq() { - sprintf(g_dasm_str, "moveq #%s, D%d", make_signed_hex_str_8(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("moveq #%s, D%d", make_signed_hex_str_8(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68040_move16_pi_pi(void) +std::string m68k_disassembler::d68040_move16_pi_pi() { - LIMIT_CPU_TYPES(M68040_PLUS); - sprintf(g_dasm_str, "move16 (A%d)+, (A%d)+; (4)", g_cpu_ir&7, (read_imm_16()>>12)&7); + auto limit = limit_cpu_types(M68040_PLUS); + if(limit.first) + return limit.second; + return util::string_format("move16 (A%d)+, (A%d)+; (4)", m_cpu_ir&7, (read_imm_16()>>12)&7); } -static void d68040_move16_pi_al(void) +std::string m68k_disassembler::d68040_move16_pi_al() { - LIMIT_CPU_TYPES(M68040_PLUS); - sprintf(g_dasm_str, "move16 (A%d)+, %s; (4)", g_cpu_ir&7, get_imm_str_u32()); + auto limit = limit_cpu_types(M68040_PLUS); + if(limit.first) + return limit.second; + return util::string_format("move16 (A%d)+, %s; (4)", m_cpu_ir&7, get_imm_str_u32()); } -static void d68040_move16_al_pi(void) +std::string m68k_disassembler::d68040_move16_al_pi() { - LIMIT_CPU_TYPES(M68040_PLUS); - sprintf(g_dasm_str, "move16 %s, (A%d)+; (4)", get_imm_str_u32(), g_cpu_ir&7); + auto limit = limit_cpu_types(M68040_PLUS); + if(limit.first) + return limit.second; + return util::string_format("move16 %s, (A%d)+; (4)", get_imm_str_u32(), m_cpu_ir&7); } -static void d68040_move16_ai_al(void) +std::string m68k_disassembler::d68040_move16_ai_al() { - LIMIT_CPU_TYPES(M68040_PLUS); - sprintf(g_dasm_str, "move16 (A%d), %s; (4)", g_cpu_ir&7, get_imm_str_u32()); + auto limit = limit_cpu_types(M68040_PLUS); + if(limit.first) + return limit.second; + return util::string_format("move16 (A%d), %s; (4)", m_cpu_ir&7, get_imm_str_u32()); } -static void d68040_move16_al_ai(void) +std::string m68k_disassembler::d68040_move16_al_ai() { - LIMIT_CPU_TYPES(M68040_PLUS); - sprintf(g_dasm_str, "move16 %s, (A%d); (4)", get_imm_str_u32(), g_cpu_ir&7); + auto limit = limit_cpu_types(M68040_PLUS); + if(limit.first) + return limit.second; + return util::string_format("move16 %s, (A%d); (4)", get_imm_str_u32(), m_cpu_ir&7); } -static void d68000_muls(void) +std::string m68k_disassembler::d68000_muls() { - sprintf(g_dasm_str, "muls.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("muls.w %s, D%d", get_ea_mode_str_16(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_mulu(void) +std::string m68k_disassembler::d68000_mulu() { - sprintf(g_dasm_str, "mulu.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("mulu.w %s, D%d", get_ea_mode_str_16(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68020_mull(void) +std::string m68k_disassembler::d68020_mull() { - uint32_t extension; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + u16 extension = read_imm_16(); - if(BIT_A(extension)) - sprintf(g_dasm_str, "mul%c.l %s, D%d-D%d; (2+)", BIT_B(extension) ? 's' : 'u', get_ea_mode_str_32(g_cpu_ir), extension&7, (extension>>12)&7); + if(BIT(extension, 10)) + return util::string_format("mul%c.l %s, D%d-D%d; (2+)", BIT(extension, 11) ? 's' : 'u', get_ea_mode_str_32(m_cpu_ir), extension&7, (extension>>12)&7); else - sprintf(g_dasm_str, "mul%c.l %s, D%d; (2+)", BIT_B(extension) ? 's' : 'u', get_ea_mode_str_32(g_cpu_ir), (extension>>12)&7); + return util::string_format("mul%c.l %s, D%d; (2+)", BIT(extension, 11) ? 's' : 'u', get_ea_mode_str_32(m_cpu_ir), (extension>>12)&7); } -static void d68000_nbcd(void) +std::string m68k_disassembler::d68000_nbcd() { - sprintf(g_dasm_str, "nbcd %s", get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("nbcd %s", get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_neg_8(void) +std::string m68k_disassembler::d68000_neg_8() { - sprintf(g_dasm_str, "neg.b %s", get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("neg.b %s", get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_neg_16(void) +std::string m68k_disassembler::d68000_neg_16() { - sprintf(g_dasm_str, "neg.w %s", get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("neg.w %s", get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_neg_32(void) +std::string m68k_disassembler::d68000_neg_32() { - sprintf(g_dasm_str, "neg.l %s", get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("neg.l %s", get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_negx_8(void) +std::string m68k_disassembler::d68000_negx_8() { - sprintf(g_dasm_str, "negx.b %s", get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("negx.b %s", get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_negx_16(void) +std::string m68k_disassembler::d68000_negx_16() { - sprintf(g_dasm_str, "negx.w %s", get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("negx.w %s", get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_negx_32(void) +std::string m68k_disassembler::d68000_negx_32() { - sprintf(g_dasm_str, "negx.l %s", get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("negx.l %s", get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_nop(void) +std::string m68k_disassembler::d68000_nop() { - sprintf(g_dasm_str, "nop"); + return util::string_format("nop"); } -static void d68000_not_8(void) +std::string m68k_disassembler::d68000_not_8() { - sprintf(g_dasm_str, "not.b %s", get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("not.b %s", get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_not_16(void) +std::string m68k_disassembler::d68000_not_16() { - sprintf(g_dasm_str, "not.w %s", get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("not.w %s", get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_not_32(void) +std::string m68k_disassembler::d68000_not_32() { - sprintf(g_dasm_str, "not.l %s", get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("not.l %s", get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_or_er_8(void) +std::string m68k_disassembler::d68000_or_er_8() { - sprintf(g_dasm_str, "or.b %s, D%d", get_ea_mode_str_8(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("or.b %s, D%d", get_ea_mode_str_8(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_or_er_16(void) +std::string m68k_disassembler::d68000_or_er_16() { - sprintf(g_dasm_str, "or.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("or.w %s, D%d", get_ea_mode_str_16(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_or_er_32(void) +std::string m68k_disassembler::d68000_or_er_32() { - sprintf(g_dasm_str, "or.l %s, D%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("or.l %s, D%d", get_ea_mode_str_32(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_or_re_8(void) +std::string m68k_disassembler::d68000_or_re_8() { - sprintf(g_dasm_str, "or.b D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("or.b D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_or_re_16(void) +std::string m68k_disassembler::d68000_or_re_16() { - sprintf(g_dasm_str, "or.w D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("or.w D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_or_re_32(void) +std::string m68k_disassembler::d68000_or_re_32() { - sprintf(g_dasm_str, "or.l D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("or.l D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_ori_8(void) +std::string m68k_disassembler::d68000_ori_8() { - char* str = get_imm_str_u8(); - sprintf(g_dasm_str, "ori.b %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); + std::string str = get_imm_str_u8(); + return util::string_format("ori.b %s, %s", str, get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_ori_16(void) +std::string m68k_disassembler::d68000_ori_16() { - char* str = get_imm_str_u16(); - sprintf(g_dasm_str, "ori.w %s, %s", str, get_ea_mode_str_16(g_cpu_ir)); + std::string str = get_imm_str_u16(); + return util::string_format("ori.w %s, %s", str, get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_ori_32(void) +std::string m68k_disassembler::d68000_ori_32() { - char* str = get_imm_str_u32(); - sprintf(g_dasm_str, "ori.l %s, %s", str, get_ea_mode_str_32(g_cpu_ir)); + std::string str = get_imm_str_u32(); + return util::string_format("ori.l %s, %s", str, get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_ori_to_ccr(void) +std::string m68k_disassembler::d68000_ori_to_ccr() { - sprintf(g_dasm_str, "ori %s, CCR", get_imm_str_u8()); + return util::string_format("ori %s, CCR", get_imm_str_u8()); } -static void d68000_ori_to_sr(void) +std::string m68k_disassembler::d68000_ori_to_sr() { - sprintf(g_dasm_str, "ori %s, SR", get_imm_str_u16()); + return util::string_format("ori %s, SR", get_imm_str_u16()); } -static void d68020_pack_rr(void) +std::string m68k_disassembler::d68020_pack_rr() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "pack D%d, D%d, %s; (2+)", g_cpu_ir&7, (g_cpu_ir>>9)&7, get_imm_str_u16()); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("pack D%d, D%d, %s; (2+)", m_cpu_ir&7, (m_cpu_ir>>9)&7, get_imm_str_u16()); } -static void d68020_pack_mm(void) +std::string m68k_disassembler::d68020_pack_mm() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "pack -(A%d), -(A%d), %s; (2+)", g_cpu_ir&7, (g_cpu_ir>>9)&7, get_imm_str_u16()); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("pack -(A%d), -(A%d), %s; (2+)", m_cpu_ir&7, (m_cpu_ir>>9)&7, get_imm_str_u16()); } -static void d68000_pea(void) +std::string m68k_disassembler::d68000_pea() { - sprintf(g_dasm_str, "pea %s", get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("pea %s", get_ea_mode_str_32(m_cpu_ir)); } // this is a 68040-specific form of PFLUSH -static void d68040_pflush(void) +std::string m68k_disassembler::d68040_pflush() { - LIMIT_CPU_TYPES(M68040_PLUS); + auto limit = limit_cpu_types(M68040_PLUS); + if(limit.first) + return limit.second; - if (g_cpu_ir & 0x10) + if (m_cpu_ir & 0x10) { - sprintf(g_dasm_str, "pflusha%s", (g_cpu_ir & 8) ? "" : "n"); + return util::string_format("pflusha%s", (m_cpu_ir & 8) ? "" : "n"); } else { - sprintf(g_dasm_str, "pflush%s(A%d)", (g_cpu_ir & 8) ? "" : "n", g_cpu_ir & 7); + return util::string_format("pflush%s(A%d)", (m_cpu_ir & 8) ? "" : "n", m_cpu_ir & 7); } } -static void d68000_reset(void) +std::string m68k_disassembler::d68000_reset() { - sprintf(g_dasm_str, "reset"); + return util::string_format("reset"); } -static void d68000_ror_s_8(void) +std::string m68k_disassembler::d68000_ror_s_8() { - sprintf(g_dasm_str, "ror.b #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("ror.b #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_ror_s_16(void) +std::string m68k_disassembler::d68000_ror_s_16() { - sprintf(g_dasm_str, "ror.w #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7],g_cpu_ir&7); + return util::string_format("ror.w #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7],m_cpu_ir&7); } -static void d68000_ror_s_32(void) +std::string m68k_disassembler::d68000_ror_s_32() { - sprintf(g_dasm_str, "ror.l #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("ror.l #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_ror_r_8(void) +std::string m68k_disassembler::d68000_ror_r_8() { - sprintf(g_dasm_str, "ror.b D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("ror.b D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_ror_r_16(void) +std::string m68k_disassembler::d68000_ror_r_16() { - sprintf(g_dasm_str, "ror.w D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("ror.w D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_ror_r_32(void) +std::string m68k_disassembler::d68000_ror_r_32() { - sprintf(g_dasm_str, "ror.l D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("ror.l D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_ror_ea(void) +std::string m68k_disassembler::d68000_ror_ea() { - sprintf(g_dasm_str, "ror.w %s", get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("ror.w %s", get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_rol_s_8(void) +std::string m68k_disassembler::d68000_rol_s_8() { - sprintf(g_dasm_str, "rol.b #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("rol.b #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_rol_s_16(void) +std::string m68k_disassembler::d68000_rol_s_16() { - sprintf(g_dasm_str, "rol.w #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("rol.w #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_rol_s_32(void) +std::string m68k_disassembler::d68000_rol_s_32() { - sprintf(g_dasm_str, "rol.l #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("rol.l #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_rol_r_8(void) +std::string m68k_disassembler::d68000_rol_r_8() { - sprintf(g_dasm_str, "rol.b D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("rol.b D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_rol_r_16(void) +std::string m68k_disassembler::d68000_rol_r_16() { - sprintf(g_dasm_str, "rol.w D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("rol.w D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_rol_r_32(void) +std::string m68k_disassembler::d68000_rol_r_32() { - sprintf(g_dasm_str, "rol.l D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("rol.l D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_rol_ea(void) +std::string m68k_disassembler::d68000_rol_ea() { - sprintf(g_dasm_str, "rol.w %s", get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("rol.w %s", get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_roxr_s_8(void) +std::string m68k_disassembler::d68000_roxr_s_8() { - sprintf(g_dasm_str, "roxr.b #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("roxr.b #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_roxr_s_16(void) +std::string m68k_disassembler::d68000_roxr_s_16() { - sprintf(g_dasm_str, "roxr.w #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("roxr.w #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_roxr_s_32(void) +std::string m68k_disassembler::d68000_roxr_s_32() { - sprintf(g_dasm_str, "roxr.l #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("roxr.l #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_roxr_r_8(void) +std::string m68k_disassembler::d68000_roxr_r_8() { - sprintf(g_dasm_str, "roxr.b D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("roxr.b D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_roxr_r_16(void) +std::string m68k_disassembler::d68000_roxr_r_16() { - sprintf(g_dasm_str, "roxr.w D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("roxr.w D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_roxr_r_32(void) +std::string m68k_disassembler::d68000_roxr_r_32() { - sprintf(g_dasm_str, "roxr.l D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("roxr.l D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_roxr_ea(void) +std::string m68k_disassembler::d68000_roxr_ea() { - sprintf(g_dasm_str, "roxr.w %s", get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("roxr.w %s", get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_roxl_s_8(void) +std::string m68k_disassembler::d68000_roxl_s_8() { - sprintf(g_dasm_str, "roxl.b #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("roxl.b #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_roxl_s_16(void) +std::string m68k_disassembler::d68000_roxl_s_16() { - sprintf(g_dasm_str, "roxl.w #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("roxl.w #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_roxl_s_32(void) +std::string m68k_disassembler::d68000_roxl_s_32() { - sprintf(g_dasm_str, "roxl.l #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("roxl.l #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_roxl_r_8(void) +std::string m68k_disassembler::d68000_roxl_r_8() { - sprintf(g_dasm_str, "roxl.b D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("roxl.b D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_roxl_r_16(void) +std::string m68k_disassembler::d68000_roxl_r_16() { - sprintf(g_dasm_str, "roxl.w D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("roxl.w D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_roxl_r_32(void) +std::string m68k_disassembler::d68000_roxl_r_32() { - sprintf(g_dasm_str, "roxl.l D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("roxl.l D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_roxl_ea(void) +std::string m68k_disassembler::d68000_roxl_ea() { - sprintf(g_dasm_str, "roxl.w %s", get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("roxl.w %s", get_ea_mode_str_32(m_cpu_ir)); } -static void d68010_rtd(void) +std::string m68k_disassembler::d68010_rtd() { - LIMIT_CPU_TYPES(M68010_PLUS); - sprintf(g_dasm_str, "rtd %s; (1+)", get_imm_str_s16()); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OUT); + auto limit = limit_cpu_types(M68010_PLUS); + if(limit.first) + return limit.second; + m_flags = STEP_OUT; + return util::string_format("rtd %s; (1+)", get_imm_str_s16()); } -static void d68000_rte(void) +std::string m68k_disassembler::d68000_rte() { - sprintf(g_dasm_str, "rte"); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OUT); + m_flags = STEP_OUT; + return util::string_format("rte"); } -static void d68020_rtm(void) +std::string m68k_disassembler::d68020_rtm() { - LIMIT_CPU_TYPES(M68020_ONLY); - sprintf(g_dasm_str, "rtm %c%d; (2+)", BIT_3(g_cpu_ir) ? 'A' : 'D', g_cpu_ir&7); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OUT); + auto limit = limit_cpu_types(M68020_ONLY); + if(limit.first) + return limit.second; + m_flags = STEP_OUT; + return util::string_format("rtm %c%d; (2+)", BIT(m_cpu_ir, 3) ? 'A' : 'D', m_cpu_ir&7); } -static void d68000_rtr(void) +std::string m68k_disassembler::d68000_rtr() { - sprintf(g_dasm_str, "rtr"); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OUT); + m_flags = STEP_OUT; + return util::string_format("rtr"); } -static void d68000_rts(void) +std::string m68k_disassembler::d68000_rts() { - sprintf(g_dasm_str, "rts"); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OUT); + m_flags = STEP_OUT; + return util::string_format("rts"); } -static void d68000_sbcd_rr(void) +std::string m68k_disassembler::d68000_sbcd_rr() { - sprintf(g_dasm_str, "sbcd D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("sbcd D%d, D%d", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_sbcd_mm(void) +std::string m68k_disassembler::d68000_sbcd_mm() { - sprintf(g_dasm_str, "sbcd -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("sbcd -(A%d), -(A%d)", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_scc(void) +std::string m68k_disassembler::d68000_scc() { - sprintf(g_dasm_str, "s%-2s %s", g_cc[(g_cpu_ir>>8)&0xf], get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("s%-2s %s", m_cc[(m_cpu_ir>>8)&0xf], get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_stop(void) +std::string m68k_disassembler::d68000_stop() { - sprintf(g_dasm_str, "stop %s", get_imm_str_s16()); + return util::string_format("stop %s", get_imm_str_s16()); } -static void d68000_sub_er_8(void) +std::string m68k_disassembler::d68000_sub_er_8() { - sprintf(g_dasm_str, "sub.b %s, D%d", get_ea_mode_str_8(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("sub.b %s, D%d", get_ea_mode_str_8(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_sub_er_16(void) +std::string m68k_disassembler::d68000_sub_er_16() { - sprintf(g_dasm_str, "sub.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("sub.w %s, D%d", get_ea_mode_str_16(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_sub_er_32(void) +std::string m68k_disassembler::d68000_sub_er_32() { - sprintf(g_dasm_str, "sub.l %s, D%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("sub.l %s, D%d", get_ea_mode_str_32(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_sub_re_8(void) +std::string m68k_disassembler::d68000_sub_re_8() { - sprintf(g_dasm_str, "sub.b D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("sub.b D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_sub_re_16(void) +std::string m68k_disassembler::d68000_sub_re_16() { - sprintf(g_dasm_str, "sub.w D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("sub.w D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_sub_re_32(void) +std::string m68k_disassembler::d68000_sub_re_32() { - sprintf(g_dasm_str, "sub.l D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("sub.l D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_suba_16(void) +std::string m68k_disassembler::d68000_suba_16() { - sprintf(g_dasm_str, "suba.w %s, A%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("suba.w %s, A%d", get_ea_mode_str_16(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_suba_32(void) +std::string m68k_disassembler::d68000_suba_32() { - sprintf(g_dasm_str, "suba.l %s, A%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("suba.l %s, A%d", get_ea_mode_str_32(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_subi_8(void) +std::string m68k_disassembler::d68000_subi_8() { - char* str = get_imm_str_s8(); - sprintf(g_dasm_str, "subi.b %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); + std::string str = get_imm_str_s8(); + return util::string_format("subi.b %s, %s", str, get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_subi_16(void) +std::string m68k_disassembler::d68000_subi_16() { - char* str = get_imm_str_s16(); - sprintf(g_dasm_str, "subi.w %s, %s", str, get_ea_mode_str_16(g_cpu_ir)); + std::string str = get_imm_str_s16(); + return util::string_format("subi.w %s, %s", str, get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_subi_32(void) +std::string m68k_disassembler::d68000_subi_32() { - char* str = get_imm_str_s32(); - sprintf(g_dasm_str, "subi.l %s, %s", str, get_ea_mode_str_32(g_cpu_ir)); + std::string str = get_imm_str_s32(); + return util::string_format("subi.l %s, %s", str, get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_subq_8(void) +std::string m68k_disassembler::d68000_subq_8() { - sprintf(g_dasm_str, "subq.b #%d, %s", g_3bit_qdata_table[(g_cpu_ir>>9)&7], get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("subq.b #%d, %s", m_3bit_qdata_table[(m_cpu_ir>>9)&7], get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_subq_16(void) +std::string m68k_disassembler::d68000_subq_16() { - sprintf(g_dasm_str, "subq.w #%d, %s", g_3bit_qdata_table[(g_cpu_ir>>9)&7], get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("subq.w #%d, %s", m_3bit_qdata_table[(m_cpu_ir>>9)&7], get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_subq_32(void) +std::string m68k_disassembler::d68000_subq_32() { - sprintf(g_dasm_str, "subq.l #%d, %s", g_3bit_qdata_table[(g_cpu_ir>>9)&7], get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("subq.l #%d, %s", m_3bit_qdata_table[(m_cpu_ir>>9)&7], get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_subx_rr_8(void) +std::string m68k_disassembler::d68000_subx_rr_8() { - sprintf(g_dasm_str, "subx.b D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("subx.b D%d, D%d", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_subx_rr_16(void) +std::string m68k_disassembler::d68000_subx_rr_16() { - sprintf(g_dasm_str, "subx.w D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("subx.w D%d, D%d", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_subx_rr_32(void) +std::string m68k_disassembler::d68000_subx_rr_32() { - sprintf(g_dasm_str, "subx.l D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("subx.l D%d, D%d", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_subx_mm_8(void) +std::string m68k_disassembler::d68000_subx_mm_8() { - sprintf(g_dasm_str, "subx.b -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("subx.b -(A%d), -(A%d)", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_subx_mm_16(void) +std::string m68k_disassembler::d68000_subx_mm_16() { - sprintf(g_dasm_str, "subx.w -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("subx.w -(A%d), -(A%d)", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_subx_mm_32(void) +std::string m68k_disassembler::d68000_subx_mm_32() { - sprintf(g_dasm_str, "subx.l -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("subx.l -(A%d), -(A%d)", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_swap(void) +std::string m68k_disassembler::d68000_swap() { - sprintf(g_dasm_str, "swap D%d", g_cpu_ir&7); + return util::string_format("swap D%d", m_cpu_ir&7); } -static void d68000_tas(void) +std::string m68k_disassembler::d68000_tas() { - sprintf(g_dasm_str, "tas %s", get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("tas %s", get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_trap(void) +std::string m68k_disassembler::d68000_trap() { - sprintf(g_dasm_str, "trap #$%x", g_cpu_ir&0xf); + return util::string_format("trap #$%x", m_cpu_ir&0xf); } -static void d68020_trapcc_0(void) +std::string m68k_disassembler::d68020_trapcc_0() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "trap%-2s; (2+)", g_cc[(g_cpu_ir>>8)&0xf]); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + m_flags = STEP_OVER; + return util::string_format("trap%-2s; (2+)", m_cc[(m_cpu_ir>>8)&0xf]); } -static void d68020_trapcc_16(void) +std::string m68k_disassembler::d68020_trapcc_16() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "trap%-2s %s; (2+)", g_cc[(g_cpu_ir>>8)&0xf], get_imm_str_u16()); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + m_flags = STEP_OVER; + return util::string_format("trap%-2s %s; (2+)", m_cc[(m_cpu_ir>>8)&0xf], get_imm_str_u16()); } -static void d68020_trapcc_32(void) +std::string m68k_disassembler::d68020_trapcc_32() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "trap%-2s %s; (2+)", g_cc[(g_cpu_ir>>8)&0xf], get_imm_str_u32()); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + m_flags = STEP_OVER; + return util::string_format("trap%-2s %s; (2+)", m_cc[(m_cpu_ir>>8)&0xf], get_imm_str_u32()); } -static void d68000_trapv(void) +std::string m68k_disassembler::d68000_trapv() { - sprintf(g_dasm_str, "trapv"); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + m_flags = STEP_OVER; + return util::string_format("trapv"); } -static void d68000_tst_8(void) +std::string m68k_disassembler::d68000_tst_8() { - sprintf(g_dasm_str, "tst.b %s", get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("tst.b %s", get_ea_mode_str_8(m_cpu_ir)); } -static void d68020_tst_pcdi_8(void) +std::string m68k_disassembler::d68020_tst_pcdi_8() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "tst.b %s; (2+)", get_ea_mode_str_8(g_cpu_ir)); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("tst.b %s; (2+)", get_ea_mode_str_8(m_cpu_ir)); } -static void d68020_tst_pcix_8(void) +std::string m68k_disassembler::d68020_tst_pcix_8() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "tst.b %s; (2+)", get_ea_mode_str_8(g_cpu_ir)); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("tst.b %s; (2+)", get_ea_mode_str_8(m_cpu_ir)); } -static void d68020_tst_i_8(void) +std::string m68k_disassembler::d68020_tst_i_8() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "tst.b %s; (2+)", get_ea_mode_str_8(g_cpu_ir)); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("tst.b %s; (2+)", get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_tst_16(void) +std::string m68k_disassembler::d68000_tst_16() { - sprintf(g_dasm_str, "tst.w %s", get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("tst.w %s", get_ea_mode_str_16(m_cpu_ir)); } -static void d68020_tst_a_16(void) +std::string m68k_disassembler::d68020_tst_a_16() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "tst.w %s; (2+)", get_ea_mode_str_16(g_cpu_ir)); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("tst.w %s; (2+)", get_ea_mode_str_16(m_cpu_ir)); } -static void d68020_tst_pcdi_16(void) +std::string m68k_disassembler::d68020_tst_pcdi_16() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "tst.w %s; (2+)", get_ea_mode_str_16(g_cpu_ir)); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("tst.w %s; (2+)", get_ea_mode_str_16(m_cpu_ir)); } -static void d68020_tst_pcix_16(void) +std::string m68k_disassembler::d68020_tst_pcix_16() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "tst.w %s; (2+)", get_ea_mode_str_16(g_cpu_ir)); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("tst.w %s; (2+)", get_ea_mode_str_16(m_cpu_ir)); } -static void d68020_tst_i_16(void) +std::string m68k_disassembler::d68020_tst_i_16() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "tst.w %s; (2+)", get_ea_mode_str_16(g_cpu_ir)); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("tst.w %s; (2+)", get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_tst_32(void) +std::string m68k_disassembler::d68000_tst_32() { - sprintf(g_dasm_str, "tst.l %s", get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("tst.l %s", get_ea_mode_str_32(m_cpu_ir)); } -static void d68020_tst_a_32(void) +std::string m68k_disassembler::d68020_tst_a_32() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "tst.l %s; (2+)", get_ea_mode_str_32(g_cpu_ir)); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("tst.l %s; (2+)", get_ea_mode_str_32(m_cpu_ir)); } -static void d68020_tst_pcdi_32(void) +std::string m68k_disassembler::d68020_tst_pcdi_32() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "tst.l %s; (2+)", get_ea_mode_str_32(g_cpu_ir)); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("tst.l %s; (2+)", get_ea_mode_str_32(m_cpu_ir)); } -static void d68020_tst_pcix_32(void) +std::string m68k_disassembler::d68020_tst_pcix_32() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "tst.l %s; (2+)", get_ea_mode_str_32(g_cpu_ir)); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("tst.l %s; (2+)", get_ea_mode_str_32(m_cpu_ir)); } -static void d68020_tst_i_32(void) +std::string m68k_disassembler::d68020_tst_i_32() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "tst.l %s; (2+)", get_ea_mode_str_32(g_cpu_ir)); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("tst.l %s; (2+)", get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_unlk(void) +std::string m68k_disassembler::d68000_unlk() { - sprintf(g_dasm_str, "unlk A%d", g_cpu_ir&7); + return util::string_format("unlk A%d", m_cpu_ir&7); } -static void d68020_unpk_rr(void) +std::string m68k_disassembler::d68020_unpk_rr() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "unpk D%d, D%d, %s; (2+)", g_cpu_ir&7, (g_cpu_ir>>9)&7, get_imm_str_u16()); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("unpk D%d, D%d, %s; (2+)", m_cpu_ir&7, (m_cpu_ir>>9)&7, get_imm_str_u16()); } -static void d68020_unpk_mm(void) +std::string m68k_disassembler::d68020_unpk_mm() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "unpk -(A%d), -(A%d), %s; (2+)", g_cpu_ir&7, (g_cpu_ir>>9)&7, get_imm_str_u16()); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("unpk -(A%d), -(A%d), %s; (2+)", m_cpu_ir&7, (m_cpu_ir>>9)&7, get_imm_str_u16()); } @@ -3249,54 +2926,48 @@ static void d68020_unpk_mm(void) // PMOVE 3: 011xxxx000000000 // PTEST: 100xxxxxxxxxxxxx // PFLUSHR: 1010000000000000 -static void d68851_p000(void) +std::string m68k_disassembler::d68851_p000() { - char* str; - uint16_t modes = read_imm_16(); + u16 modes = read_imm_16(); // do this after fetching the second PMOVE word so we properly get the 3rd if necessary - str = get_ea_mode_str_32(g_cpu_ir); + std::string str = get_ea_mode_str_32(m_cpu_ir); if ((modes & 0xfde0) == 0x2000) // PLOAD { if (modes & 0x0200) { - sprintf(g_dasm_str, "pload #%d, %s", (modes>>10)&7, str); + return util::string_format("pload #%d, %s", (modes>>10)&7, str); } else { - sprintf(g_dasm_str, "pload %s, #%d", str, (modes>>10)&7); + return util::string_format("pload %s, #%d", str, (modes>>10)&7); } - return; } if ((modes & 0xe200) == 0x2000) // PFLUSH { - sprintf(g_dasm_str, "pflushr %x, %x, %s", modes & 0x1f, (modes>>5)&0xf, str); - return; + return util::string_format("pflushr %x, %x, %s", modes & 0x1f, (modes>>5)&0xf, str); } if (modes == 0xa000) // PFLUSHR { - sprintf(g_dasm_str, "pflushr %s", str); + return util::string_format("pflushr %s", str); } if (modes == 0x2800) // PVALID (FORMAT 1) { - sprintf(g_dasm_str, "pvalid VAL, %s", str); - return; + return util::string_format("pvalid VAL, %s", str); } if ((modes & 0xfff8) == 0x2c00) // PVALID (FORMAT 2) { - sprintf(g_dasm_str, "pvalid A%d, %s", modes & 0xf, str); - return; + return util::string_format("pvalid A%d, %s", modes & 0xf, str); } if ((modes & 0xe000) == 0x8000) // PTEST { - sprintf(g_dasm_str, "ptest #%d, %s", modes & 0x1f, str); - return; + return util::string_format("ptest #%d, %s", modes & 0x1f, str); } switch ((modes>>13) & 0x7) @@ -3307,22 +2978,22 @@ static void d68851_p000(void) { if (modes & 0x0200) { - sprintf(g_dasm_str, "pmovefd %s, %s", g_mmuregs[(modes>>10)&7], str); + return util::string_format("pmovefd %s, %s", m_mmuregs[(modes>>10)&7], str); } else { - sprintf(g_dasm_str, "pmovefd %s, %s", str, g_mmuregs[(modes>>10)&7]); + return util::string_format("pmovefd %s, %s", str, m_mmuregs[(modes>>10)&7]); } } else { if (modes & 0x0200) { - sprintf(g_dasm_str, "pmove %s, %s", g_mmuregs[(modes>>10)&7], str); + return util::string_format("pmove %s, %s", m_mmuregs[(modes>>10)&7], str); } else { - sprintf(g_dasm_str, "pmove %s, %s", str, g_mmuregs[(modes>>10)&7]); + return util::string_format("pmove %s, %s", str, m_mmuregs[(modes>>10)&7]); } } break; @@ -3330,63 +3001,65 @@ static void d68851_p000(void) case 3: // MC68030 to/from status reg if (modes & 0x0200) { - sprintf(g_dasm_str, "pmove mmusr, %s", str); + return util::string_format("pmove mmusr, %s", str); } else { - sprintf(g_dasm_str, "pmove %s, mmusr", str); + return util::string_format("pmove %s, mmusr", str); } break; - default: - sprintf(g_dasm_str, "pmove [unknown form] %s", str); - break; } + return util::string_format("pmove [unknown form] %s", str); } -static void d68851_pbcc16(void) +std::string m68k_disassembler::d68851_pbcc16() { - uint32_t temp_pc = g_cpu_pc; + u32 temp_pc = m_cpu_pc; - sprintf(g_dasm_str, "pb%s %x", g_mmucond[g_cpu_ir&0xf], temp_pc + make_int_16(read_imm_16())); + return util::string_format("pb%s %x", m_mmucond[m_cpu_ir&0xf], temp_pc + make_int_16(read_imm_16())); } -static void d68851_pbcc32(void) +std::string m68k_disassembler::d68851_pbcc32() { - uint32_t temp_pc = g_cpu_pc; + u32 temp_pc = m_cpu_pc; - sprintf(g_dasm_str, "pb%s %x", g_mmucond[g_cpu_ir&0xf], temp_pc + make_int_32(read_imm_32())); + return util::string_format("pb%s %x", m_mmucond[m_cpu_ir&0xf], temp_pc + make_int_32(read_imm_32())); } -static void d68851_pdbcc(void) +std::string m68k_disassembler::d68851_pdbcc() { - uint32_t temp_pc = g_cpu_pc; + u32 temp_pc = m_cpu_pc; uint16_t modes = read_imm_16(); - sprintf(g_dasm_str, "pb%s %x", g_mmucond[modes&0xf], temp_pc + make_int_16(read_imm_16())); + return util::string_format("pb%s %x", m_mmucond[modes&0xf], temp_pc + make_int_16(read_imm_16())); } // PScc: 0000000000xxxxxx -static void d68851_p001(void) +std::string m68k_disassembler::d68851_p001() { - sprintf(g_dasm_str, "MMU 001 group"); + return util::string_format("MMU 001 group"); } // fbcc is 68040 and 68881 -static void d68040_fbcc_16() +std::string m68k_disassembler::d68040_fbcc_16() { - LIMIT_CPU_TYPES(M68030_PLUS); - uint32_t temp_pc = g_cpu_pc; + auto limit = limit_cpu_types(M68030_PLUS); + if(limit.first) + return limit.second; + u32 temp_pc = m_cpu_pc; int16_t disp = make_int_16(read_imm_16()); - sprintf(g_dasm_str, "fb%-s $%x", g_cpcc[g_cpu_ir & 0x3f], temp_pc + disp); + return util::string_format("fb%-s $%x", m_cpcc[m_cpu_ir & 0x3f], temp_pc + disp); } -static void d68040_fbcc_32() +std::string m68k_disassembler::d68040_fbcc_32() { - LIMIT_CPU_TYPES(M68030_PLUS); - uint32_t temp_pc = g_cpu_pc; - uint32_t disp = read_imm_32(); - sprintf(g_dasm_str, "fb%-s $%x", g_cpcc[g_cpu_ir & 0x3f], temp_pc + disp); + auto limit = limit_cpu_types(M68030_PLUS); + if(limit.first) + return limit.second; + u32 temp_pc = m_cpu_pc; + u32 disp = read_imm_32(); + return util::string_format("fb%-s $%x", m_cpcc[m_cpu_ir & 0x3f], temp_pc + disp); } /* ======================================================================== */ @@ -3408,325 +3081,325 @@ static void d68040_fbcc_32() 1 = pc idx */ -static const opcode_struct g_opcode_info[] = +const m68k_disassembler::opcode_struct m68k_disassembler::m_opcode_info[] = { /* opcode handler mask match ea mask */ - {d68000_1010 , 0xf000, 0xa000, 0x000}, - {d68000_1111 , 0xf000, 0xf000, 0x000}, - {d68000_abcd_rr , 0xf1f8, 0xc100, 0x000}, - {d68000_abcd_mm , 0xf1f8, 0xc108, 0x000}, - {d68000_add_er_8 , 0xf1c0, 0xd000, 0xbff}, - {d68000_add_er_16 , 0xf1c0, 0xd040, 0xfff}, - {d68000_add_er_32 , 0xf1c0, 0xd080, 0xfff}, - {d68000_add_re_8 , 0xf1c0, 0xd100, 0x3f8}, - {d68000_add_re_16 , 0xf1c0, 0xd140, 0x3f8}, - {d68000_add_re_32 , 0xf1c0, 0xd180, 0x3f8}, - {d68000_adda_16 , 0xf1c0, 0xd0c0, 0xfff}, - {d68000_adda_32 , 0xf1c0, 0xd1c0, 0xfff}, - {d68000_addi_8 , 0xffc0, 0x0600, 0xbf8}, - {d68000_addi_16 , 0xffc0, 0x0640, 0xbf8}, - {d68000_addi_32 , 0xffc0, 0x0680, 0xbf8}, - {d68000_addq_8 , 0xf1c0, 0x5000, 0xbf8}, - {d68000_addq_16 , 0xf1c0, 0x5040, 0xff8}, - {d68000_addq_32 , 0xf1c0, 0x5080, 0xff8}, - {d68000_addx_rr_8 , 0xf1f8, 0xd100, 0x000}, - {d68000_addx_rr_16 , 0xf1f8, 0xd140, 0x000}, - {d68000_addx_rr_32 , 0xf1f8, 0xd180, 0x000}, - {d68000_addx_mm_8 , 0xf1f8, 0xd108, 0x000}, - {d68000_addx_mm_16 , 0xf1f8, 0xd148, 0x000}, - {d68000_addx_mm_32 , 0xf1f8, 0xd188, 0x000}, - {d68000_and_er_8 , 0xf1c0, 0xc000, 0xbff}, - {d68000_and_er_16 , 0xf1c0, 0xc040, 0xbff}, - {d68000_and_er_32 , 0xf1c0, 0xc080, 0xbff}, - {d68000_and_re_8 , 0xf1c0, 0xc100, 0x3f8}, - {d68000_and_re_16 , 0xf1c0, 0xc140, 0x3f8}, - {d68000_and_re_32 , 0xf1c0, 0xc180, 0x3f8}, - {d68000_andi_to_ccr , 0xffff, 0x023c, 0x000}, - {d68000_andi_to_sr , 0xffff, 0x027c, 0x000}, - {d68000_andi_8 , 0xffc0, 0x0200, 0xbf8}, - {d68000_andi_16 , 0xffc0, 0x0240, 0xbf8}, - {d68000_andi_32 , 0xffc0, 0x0280, 0xbf8}, - {d68000_asr_s_8 , 0xf1f8, 0xe000, 0x000}, - {d68000_asr_s_16 , 0xf1f8, 0xe040, 0x000}, - {d68000_asr_s_32 , 0xf1f8, 0xe080, 0x000}, - {d68000_asr_r_8 , 0xf1f8, 0xe020, 0x000}, - {d68000_asr_r_16 , 0xf1f8, 0xe060, 0x000}, - {d68000_asr_r_32 , 0xf1f8, 0xe0a0, 0x000}, - {d68000_asr_ea , 0xffc0, 0xe0c0, 0x3f8}, - {d68000_asl_s_8 , 0xf1f8, 0xe100, 0x000}, - {d68000_asl_s_16 , 0xf1f8, 0xe140, 0x000}, - {d68000_asl_s_32 , 0xf1f8, 0xe180, 0x000}, - {d68000_asl_r_8 , 0xf1f8, 0xe120, 0x000}, - {d68000_asl_r_16 , 0xf1f8, 0xe160, 0x000}, - {d68000_asl_r_32 , 0xf1f8, 0xe1a0, 0x000}, - {d68000_asl_ea , 0xffc0, 0xe1c0, 0x3f8}, - {d68000_bcc_8 , 0xf000, 0x6000, 0x000}, - {d68000_bcc_16 , 0xf0ff, 0x6000, 0x000}, - {d68020_bcc_32 , 0xf0ff, 0x60ff, 0x000}, - {d68000_bchg_r , 0xf1c0, 0x0140, 0xbf8}, - {d68000_bchg_s , 0xffc0, 0x0840, 0xbf8}, - {d68000_bclr_r , 0xf1c0, 0x0180, 0xbf8}, - {d68000_bclr_s , 0xffc0, 0x0880, 0xbf8}, - {d68020_bfchg , 0xffc0, 0xeac0, 0xa78}, - {d68020_bfclr , 0xffc0, 0xecc0, 0xa78}, - {d68020_bfexts , 0xffc0, 0xebc0, 0xa7b}, - {d68020_bfextu , 0xffc0, 0xe9c0, 0xa7b}, - {d68020_bfffo , 0xffc0, 0xedc0, 0xa7b}, - {d68020_bfins , 0xffc0, 0xefc0, 0xa78}, - {d68020_bfset , 0xffc0, 0xeec0, 0xa78}, - {d68020_bftst , 0xffc0, 0xe8c0, 0xa7b}, - {d68881_ftrap , 0xfff8, 0xf278, 0x000}, - {d68010_bkpt , 0xfff8, 0x4848, 0x000}, - {d68000_bra_8 , 0xff00, 0x6000, 0x000}, - {d68000_bra_16 , 0xffff, 0x6000, 0x000}, - {d68020_bra_32 , 0xffff, 0x60ff, 0x000}, - {d68000_bset_r , 0xf1c0, 0x01c0, 0xbf8}, - {d68000_bset_s , 0xffc0, 0x08c0, 0xbf8}, - {d68000_bsr_8 , 0xff00, 0x6100, 0x000}, - {d68000_bsr_16 , 0xffff, 0x6100, 0x000}, - {d68020_bsr_32 , 0xffff, 0x61ff, 0x000}, - {d68000_btst_r , 0xf1c0, 0x0100, 0xbff}, - {d68000_btst_s , 0xffc0, 0x0800, 0xbfb}, - {d68020_callm , 0xffc0, 0x06c0, 0x27b}, - {d68020_cas_8 , 0xffc0, 0x0ac0, 0x3f8}, - {d68020_cas_16 , 0xffc0, 0x0cc0, 0x3f8}, - {d68020_cas_32 , 0xffc0, 0x0ec0, 0x3f8}, - {d68020_cas2_16 , 0xffff, 0x0cfc, 0x000}, - {d68020_cas2_32 , 0xffff, 0x0efc, 0x000}, - {d68000_chk_16 , 0xf1c0, 0x4180, 0xbff}, - {d68020_chk_32 , 0xf1c0, 0x4100, 0xbff}, - {d68020_chk2_cmp2_8 , 0xffc0, 0x00c0, 0x27b}, - {d68020_chk2_cmp2_16 , 0xffc0, 0x02c0, 0x27b}, - {d68020_chk2_cmp2_32 , 0xffc0, 0x04c0, 0x27b}, - {d68040_cinv , 0xff20, 0xf400, 0x000}, - {d68000_clr_8 , 0xffc0, 0x4200, 0xbf8}, - {d68000_clr_16 , 0xffc0, 0x4240, 0xbf8}, - {d68000_clr_32 , 0xffc0, 0x4280, 0xbf8}, - {d68000_cmp_8 , 0xf1c0, 0xb000, 0xbff}, - {d68000_cmp_16 , 0xf1c0, 0xb040, 0xfff}, - {d68000_cmp_32 , 0xf1c0, 0xb080, 0xfff}, - {d68000_cmpa_16 , 0xf1c0, 0xb0c0, 0xfff}, - {d68000_cmpa_32 , 0xf1c0, 0xb1c0, 0xfff}, - {d68000_cmpi_8 , 0xffc0, 0x0c00, 0xbf8}, - {d68020_cmpi_pcdi_8 , 0xffff, 0x0c3a, 0x000}, - {d68020_cmpi_pcix_8 , 0xffff, 0x0c3b, 0x000}, - {d68000_cmpi_16 , 0xffc0, 0x0c40, 0xbf8}, - {d68020_cmpi_pcdi_16 , 0xffff, 0x0c7a, 0x000}, - {d68020_cmpi_pcix_16 , 0xffff, 0x0c7b, 0x000}, - {d68000_cmpi_32 , 0xffc0, 0x0c80, 0xbf8}, - {d68020_cmpi_pcdi_32 , 0xffff, 0x0cba, 0x000}, - {d68020_cmpi_pcix_32 , 0xffff, 0x0cbb, 0x000}, - {d68000_cmpm_8 , 0xf1f8, 0xb108, 0x000}, - {d68000_cmpm_16 , 0xf1f8, 0xb148, 0x000}, - {d68000_cmpm_32 , 0xf1f8, 0xb188, 0x000}, - {d68020_cpbcc_16 , 0xf1c0, 0xf080, 0x000}, - {d68020_cpbcc_32 , 0xf1c0, 0xf0c0, 0x000}, - {d68020_cpdbcc , 0xf1f8, 0xf048, 0x000}, - {d68020_cpgen , 0xf1c0, 0xf000, 0x000}, - {d68020_cprestore , 0xf1c0, 0xf140, 0x37f}, - {d68020_cpsave , 0xf1c0, 0xf100, 0x2f8}, - {d68020_cpscc , 0xf1c0, 0xf040, 0xbf8}, - {d68020_cptrapcc_0 , 0xf1ff, 0xf07c, 0x000}, - {d68020_cptrapcc_16 , 0xf1ff, 0xf07a, 0x000}, - {d68020_cptrapcc_32 , 0xf1ff, 0xf07b, 0x000}, - {d68040_cpush , 0xff20, 0xf420, 0x000}, - {d68000_dbcc , 0xf0f8, 0x50c8, 0x000}, - {d68000_dbra , 0xfff8, 0x51c8, 0x000}, - {d68000_divs , 0xf1c0, 0x81c0, 0xbff}, - {d68000_divu , 0xf1c0, 0x80c0, 0xbff}, - {d68020_divl , 0xffc0, 0x4c40, 0xbff}, - {d68000_eor_8 , 0xf1c0, 0xb100, 0xbf8}, - {d68000_eor_16 , 0xf1c0, 0xb140, 0xbf8}, - {d68000_eor_32 , 0xf1c0, 0xb180, 0xbf8}, - {d68000_eori_to_ccr , 0xffff, 0x0a3c, 0x000}, - {d68000_eori_to_sr , 0xffff, 0x0a7c, 0x000}, - {d68000_eori_8 , 0xffc0, 0x0a00, 0xbf8}, - {d68000_eori_16 , 0xffc0, 0x0a40, 0xbf8}, - {d68000_eori_32 , 0xffc0, 0x0a80, 0xbf8}, - {d68000_exg_dd , 0xf1f8, 0xc140, 0x000}, - {d68000_exg_aa , 0xf1f8, 0xc148, 0x000}, - {d68000_exg_da , 0xf1f8, 0xc188, 0x000}, - {d68020_extb_32 , 0xfff8, 0x49c0, 0x000}, - {d68000_ext_16 , 0xfff8, 0x4880, 0x000}, - {d68000_ext_32 , 0xfff8, 0x48c0, 0x000}, - {d68040_fpu , 0xffc0, 0xf200, 0x000}, - {d68000_illegal , 0xffff, 0x4afc, 0x000}, - {d68000_jmp , 0xffc0, 0x4ec0, 0x27b}, - {d68000_jsr , 0xffc0, 0x4e80, 0x27b}, - {d68000_lea , 0xf1c0, 0x41c0, 0x27b}, - {d68000_link_16 , 0xfff8, 0x4e50, 0x000}, - {d68020_link_32 , 0xfff8, 0x4808, 0x000}, - {d68000_lsr_s_8 , 0xf1f8, 0xe008, 0x000}, - {d68000_lsr_s_16 , 0xf1f8, 0xe048, 0x000}, - {d68000_lsr_s_32 , 0xf1f8, 0xe088, 0x000}, - {d68000_lsr_r_8 , 0xf1f8, 0xe028, 0x000}, - {d68000_lsr_r_16 , 0xf1f8, 0xe068, 0x000}, - {d68000_lsr_r_32 , 0xf1f8, 0xe0a8, 0x000}, - {d68000_lsr_ea , 0xffc0, 0xe2c0, 0x3f8}, - {d68000_lsl_s_8 , 0xf1f8, 0xe108, 0x000}, - {d68000_lsl_s_16 , 0xf1f8, 0xe148, 0x000}, - {d68000_lsl_s_32 , 0xf1f8, 0xe188, 0x000}, - {d68000_lsl_r_8 , 0xf1f8, 0xe128, 0x000}, - {d68000_lsl_r_16 , 0xf1f8, 0xe168, 0x000}, - {d68000_lsl_r_32 , 0xf1f8, 0xe1a8, 0x000}, - {d68000_lsl_ea , 0xffc0, 0xe3c0, 0x3f8}, - {d68000_move_8 , 0xf000, 0x1000, 0xbff}, - {d68000_move_16 , 0xf000, 0x3000, 0xfff}, - {d68000_move_32 , 0xf000, 0x2000, 0xfff}, - {d68000_movea_16 , 0xf1c0, 0x3040, 0xfff}, - {d68000_movea_32 , 0xf1c0, 0x2040, 0xfff}, - {d68000_move_to_ccr , 0xffc0, 0x44c0, 0xbff}, - {d68010_move_fr_ccr , 0xffc0, 0x42c0, 0xbf8}, - {d68000_move_to_sr , 0xffc0, 0x46c0, 0xbff}, - {d68000_move_fr_sr , 0xffc0, 0x40c0, 0xbf8}, - {d68000_move_to_usp , 0xfff8, 0x4e60, 0x000}, - {d68000_move_fr_usp , 0xfff8, 0x4e68, 0x000}, - {d68010_movec , 0xfffe, 0x4e7a, 0x000}, - {d68000_movem_pd_16 , 0xfff8, 0x48a0, 0x000}, - {d68000_movem_pd_32 , 0xfff8, 0x48e0, 0x000}, - {d68000_movem_re_16 , 0xffc0, 0x4880, 0x2f8}, - {d68000_movem_re_32 , 0xffc0, 0x48c0, 0x2f8}, - {d68000_movem_er_16 , 0xffc0, 0x4c80, 0x37b}, - {d68000_movem_er_32 , 0xffc0, 0x4cc0, 0x37b}, - {d68000_movep_er_16 , 0xf1f8, 0x0108, 0x000}, - {d68000_movep_er_32 , 0xf1f8, 0x0148, 0x000}, - {d68000_movep_re_16 , 0xf1f8, 0x0188, 0x000}, - {d68000_movep_re_32 , 0xf1f8, 0x01c8, 0x000}, - {d68010_moves_8 , 0xffc0, 0x0e00, 0x3f8}, - {d68010_moves_16 , 0xffc0, 0x0e40, 0x3f8}, - {d68010_moves_32 , 0xffc0, 0x0e80, 0x3f8}, - {d68000_moveq , 0xf100, 0x7000, 0x000}, - {d68040_move16_pi_pi , 0xfff8, 0xf620, 0x000}, - {d68040_move16_pi_al , 0xfff8, 0xf600, 0x000}, - {d68040_move16_al_pi , 0xfff8, 0xf608, 0x000}, - {d68040_move16_ai_al , 0xfff8, 0xf610, 0x000}, - {d68040_move16_al_ai , 0xfff8, 0xf618, 0x000}, - {d68000_muls , 0xf1c0, 0xc1c0, 0xbff}, - {d68000_mulu , 0xf1c0, 0xc0c0, 0xbff}, - {d68020_mull , 0xffc0, 0x4c00, 0xbff}, - {d68000_nbcd , 0xffc0, 0x4800, 0xbf8}, - {d68000_neg_8 , 0xffc0, 0x4400, 0xbf8}, - {d68000_neg_16 , 0xffc0, 0x4440, 0xbf8}, - {d68000_neg_32 , 0xffc0, 0x4480, 0xbf8}, - {d68000_negx_8 , 0xffc0, 0x4000, 0xbf8}, - {d68000_negx_16 , 0xffc0, 0x4040, 0xbf8}, - {d68000_negx_32 , 0xffc0, 0x4080, 0xbf8}, - {d68000_nop , 0xffff, 0x4e71, 0x000}, - {d68000_not_8 , 0xffc0, 0x4600, 0xbf8}, - {d68000_not_16 , 0xffc0, 0x4640, 0xbf8}, - {d68000_not_32 , 0xffc0, 0x4680, 0xbf8}, - {d68000_or_er_8 , 0xf1c0, 0x8000, 0xbff}, - {d68000_or_er_16 , 0xf1c0, 0x8040, 0xbff}, - {d68000_or_er_32 , 0xf1c0, 0x8080, 0xbff}, - {d68000_or_re_8 , 0xf1c0, 0x8100, 0x3f8}, - {d68000_or_re_16 , 0xf1c0, 0x8140, 0x3f8}, - {d68000_or_re_32 , 0xf1c0, 0x8180, 0x3f8}, - {d68000_ori_to_ccr , 0xffff, 0x003c, 0x000}, - {d68000_ori_to_sr , 0xffff, 0x007c, 0x000}, - {d68000_ori_8 , 0xffc0, 0x0000, 0xbf8}, - {d68000_ori_16 , 0xffc0, 0x0040, 0xbf8}, - {d68000_ori_32 , 0xffc0, 0x0080, 0xbf8}, - {d68020_pack_rr , 0xf1f8, 0x8140, 0x000}, - {d68020_pack_mm , 0xf1f8, 0x8148, 0x000}, - {d68000_pea , 0xffc0, 0x4840, 0x27b}, - {d68040_pflush , 0xffe0, 0xf500, 0x000}, - {d68000_reset , 0xffff, 0x4e70, 0x000}, - {d68000_ror_s_8 , 0xf1f8, 0xe018, 0x000}, - {d68000_ror_s_16 , 0xf1f8, 0xe058, 0x000}, - {d68000_ror_s_32 , 0xf1f8, 0xe098, 0x000}, - {d68000_ror_r_8 , 0xf1f8, 0xe038, 0x000}, - {d68000_ror_r_16 , 0xf1f8, 0xe078, 0x000}, - {d68000_ror_r_32 , 0xf1f8, 0xe0b8, 0x000}, - {d68000_ror_ea , 0xffc0, 0xe6c0, 0x3f8}, - {d68000_rol_s_8 , 0xf1f8, 0xe118, 0x000}, - {d68000_rol_s_16 , 0xf1f8, 0xe158, 0x000}, - {d68000_rol_s_32 , 0xf1f8, 0xe198, 0x000}, - {d68000_rol_r_8 , 0xf1f8, 0xe138, 0x000}, - {d68000_rol_r_16 , 0xf1f8, 0xe178, 0x000}, - {d68000_rol_r_32 , 0xf1f8, 0xe1b8, 0x000}, - {d68000_rol_ea , 0xffc0, 0xe7c0, 0x3f8}, - {d68000_roxr_s_8 , 0xf1f8, 0xe010, 0x000}, - {d68000_roxr_s_16 , 0xf1f8, 0xe050, 0x000}, - {d68000_roxr_s_32 , 0xf1f8, 0xe090, 0x000}, - {d68000_roxr_r_8 , 0xf1f8, 0xe030, 0x000}, - {d68000_roxr_r_16 , 0xf1f8, 0xe070, 0x000}, - {d68000_roxr_r_32 , 0xf1f8, 0xe0b0, 0x000}, - {d68000_roxr_ea , 0xffc0, 0xe4c0, 0x3f8}, - {d68000_roxl_s_8 , 0xf1f8, 0xe110, 0x000}, - {d68000_roxl_s_16 , 0xf1f8, 0xe150, 0x000}, - {d68000_roxl_s_32 , 0xf1f8, 0xe190, 0x000}, - {d68000_roxl_r_8 , 0xf1f8, 0xe130, 0x000}, - {d68000_roxl_r_16 , 0xf1f8, 0xe170, 0x000}, - {d68000_roxl_r_32 , 0xf1f8, 0xe1b0, 0x000}, - {d68000_roxl_ea , 0xffc0, 0xe5c0, 0x3f8}, - {d68010_rtd , 0xffff, 0x4e74, 0x000}, - {d68000_rte , 0xffff, 0x4e73, 0x000}, - {d68020_rtm , 0xfff0, 0x06c0, 0x000}, - {d68000_rtr , 0xffff, 0x4e77, 0x000}, - {d68000_rts , 0xffff, 0x4e75, 0x000}, - {d68000_sbcd_rr , 0xf1f8, 0x8100, 0x000}, - {d68000_sbcd_mm , 0xf1f8, 0x8108, 0x000}, - {d68000_scc , 0xf0c0, 0x50c0, 0xbf8}, - {d68000_stop , 0xffff, 0x4e72, 0x000}, - {d68000_sub_er_8 , 0xf1c0, 0x9000, 0xbff}, - {d68000_sub_er_16 , 0xf1c0, 0x9040, 0xfff}, - {d68000_sub_er_32 , 0xf1c0, 0x9080, 0xfff}, - {d68000_sub_re_8 , 0xf1c0, 0x9100, 0x3f8}, - {d68000_sub_re_16 , 0xf1c0, 0x9140, 0x3f8}, - {d68000_sub_re_32 , 0xf1c0, 0x9180, 0x3f8}, - {d68000_suba_16 , 0xf1c0, 0x90c0, 0xfff}, - {d68000_suba_32 , 0xf1c0, 0x91c0, 0xfff}, - {d68000_subi_8 , 0xffc0, 0x0400, 0xbf8}, - {d68000_subi_16 , 0xffc0, 0x0440, 0xbf8}, - {d68000_subi_32 , 0xffc0, 0x0480, 0xbf8}, - {d68000_subq_8 , 0xf1c0, 0x5100, 0xbf8}, - {d68000_subq_16 , 0xf1c0, 0x5140, 0xff8}, - {d68000_subq_32 , 0xf1c0, 0x5180, 0xff8}, - {d68000_subx_rr_8 , 0xf1f8, 0x9100, 0x000}, - {d68000_subx_rr_16 , 0xf1f8, 0x9140, 0x000}, - {d68000_subx_rr_32 , 0xf1f8, 0x9180, 0x000}, - {d68000_subx_mm_8 , 0xf1f8, 0x9108, 0x000}, - {d68000_subx_mm_16 , 0xf1f8, 0x9148, 0x000}, - {d68000_subx_mm_32 , 0xf1f8, 0x9188, 0x000}, - {d68000_swap , 0xfff8, 0x4840, 0x000}, - {d68000_tas , 0xffc0, 0x4ac0, 0xbf8}, - {d68000_trap , 0xfff0, 0x4e40, 0x000}, - {d68020_trapcc_0 , 0xf0ff, 0x50fc, 0x000}, - {d68020_trapcc_16 , 0xf0ff, 0x50fa, 0x000}, - {d68020_trapcc_32 , 0xf0ff, 0x50fb, 0x000}, - {d68000_trapv , 0xffff, 0x4e76, 0x000}, - {d68000_tst_8 , 0xffc0, 0x4a00, 0xbf8}, - {d68020_tst_pcdi_8 , 0xffff, 0x4a3a, 0x000}, - {d68020_tst_pcix_8 , 0xffff, 0x4a3b, 0x000}, - {d68020_tst_i_8 , 0xffff, 0x4a3c, 0x000}, - {d68000_tst_16 , 0xffc0, 0x4a40, 0xbf8}, - {d68020_tst_a_16 , 0xfff8, 0x4a48, 0x000}, - {d68020_tst_pcdi_16 , 0xffff, 0x4a7a, 0x000}, - {d68020_tst_pcix_16 , 0xffff, 0x4a7b, 0x000}, - {d68020_tst_i_16 , 0xffff, 0x4a7c, 0x000}, - {d68000_tst_32 , 0xffc0, 0x4a80, 0xbf8}, - {d68020_tst_a_32 , 0xfff8, 0x4a88, 0x000}, - {d68020_tst_pcdi_32 , 0xffff, 0x4aba, 0x000}, - {d68020_tst_pcix_32 , 0xffff, 0x4abb, 0x000}, - {d68020_tst_i_32 , 0xffff, 0x4abc, 0x000}, - {d68000_unlk , 0xfff8, 0x4e58, 0x000}, - {d68020_unpk_rr , 0xf1f8, 0x8180, 0x000}, - {d68020_unpk_mm , 0xf1f8, 0x8188, 0x000}, - {d68851_p000 , 0xffc0, 0xf000, 0x000}, - {d68851_pbcc16 , 0xffc0, 0xf080, 0x000}, - {d68851_pbcc32 , 0xffc0, 0xf0c0, 0x000}, - {d68851_pdbcc , 0xfff8, 0xf048, 0x000}, - {d68851_p001 , 0xffc0, 0xf040, 0x000}, - {d68040_fbcc_16 , 0xffc0, 0xf280, 0x000}, - {d68040_fbcc_32 , 0xffc0, 0xf2c0, 0x000}, + {&m68k_disassembler::d68000_1010 , 0xf000, 0xa000, 0x000}, + {&m68k_disassembler::d68000_1111 , 0xf000, 0xf000, 0x000}, + {&m68k_disassembler::d68000_abcd_rr , 0xf1f8, 0xc100, 0x000}, + {&m68k_disassembler::d68000_abcd_mm , 0xf1f8, 0xc108, 0x000}, + {&m68k_disassembler::d68000_add_er_8 , 0xf1c0, 0xd000, 0xbff}, + {&m68k_disassembler::d68000_add_er_16 , 0xf1c0, 0xd040, 0xfff}, + {&m68k_disassembler::d68000_add_er_32 , 0xf1c0, 0xd080, 0xfff}, + {&m68k_disassembler::d68000_add_re_8 , 0xf1c0, 0xd100, 0x3f8}, + {&m68k_disassembler::d68000_add_re_16 , 0xf1c0, 0xd140, 0x3f8}, + {&m68k_disassembler::d68000_add_re_32 , 0xf1c0, 0xd180, 0x3f8}, + {&m68k_disassembler::d68000_adda_16 , 0xf1c0, 0xd0c0, 0xfff}, + {&m68k_disassembler::d68000_adda_32 , 0xf1c0, 0xd1c0, 0xfff}, + {&m68k_disassembler::d68000_addi_8 , 0xffc0, 0x0600, 0xbf8}, + {&m68k_disassembler::d68000_addi_16 , 0xffc0, 0x0640, 0xbf8}, + {&m68k_disassembler::d68000_addi_32 , 0xffc0, 0x0680, 0xbf8}, + {&m68k_disassembler::d68000_addq_8 , 0xf1c0, 0x5000, 0xbf8}, + {&m68k_disassembler::d68000_addq_16 , 0xf1c0, 0x5040, 0xff8}, + {&m68k_disassembler::d68000_addq_32 , 0xf1c0, 0x5080, 0xff8}, + {&m68k_disassembler::d68000_addx_rr_8 , 0xf1f8, 0xd100, 0x000}, + {&m68k_disassembler::d68000_addx_rr_16 , 0xf1f8, 0xd140, 0x000}, + {&m68k_disassembler::d68000_addx_rr_32 , 0xf1f8, 0xd180, 0x000}, + {&m68k_disassembler::d68000_addx_mm_8 , 0xf1f8, 0xd108, 0x000}, + {&m68k_disassembler::d68000_addx_mm_16 , 0xf1f8, 0xd148, 0x000}, + {&m68k_disassembler::d68000_addx_mm_32 , 0xf1f8, 0xd188, 0x000}, + {&m68k_disassembler::d68000_and_er_8 , 0xf1c0, 0xc000, 0xbff}, + {&m68k_disassembler::d68000_and_er_16 , 0xf1c0, 0xc040, 0xbff}, + {&m68k_disassembler::d68000_and_er_32 , 0xf1c0, 0xc080, 0xbff}, + {&m68k_disassembler::d68000_and_re_8 , 0xf1c0, 0xc100, 0x3f8}, + {&m68k_disassembler::d68000_and_re_16 , 0xf1c0, 0xc140, 0x3f8}, + {&m68k_disassembler::d68000_and_re_32 , 0xf1c0, 0xc180, 0x3f8}, + {&m68k_disassembler::d68000_andi_to_ccr , 0xffff, 0x023c, 0x000}, + {&m68k_disassembler::d68000_andi_to_sr , 0xffff, 0x027c, 0x000}, + {&m68k_disassembler::d68000_andi_8 , 0xffc0, 0x0200, 0xbf8}, + {&m68k_disassembler::d68000_andi_16 , 0xffc0, 0x0240, 0xbf8}, + {&m68k_disassembler::d68000_andi_32 , 0xffc0, 0x0280, 0xbf8}, + {&m68k_disassembler::d68000_asr_s_8 , 0xf1f8, 0xe000, 0x000}, + {&m68k_disassembler::d68000_asr_s_16 , 0xf1f8, 0xe040, 0x000}, + {&m68k_disassembler::d68000_asr_s_32 , 0xf1f8, 0xe080, 0x000}, + {&m68k_disassembler::d68000_asr_r_8 , 0xf1f8, 0xe020, 0x000}, + {&m68k_disassembler::d68000_asr_r_16 , 0xf1f8, 0xe060, 0x000}, + {&m68k_disassembler::d68000_asr_r_32 , 0xf1f8, 0xe0a0, 0x000}, + {&m68k_disassembler::d68000_asr_ea , 0xffc0, 0xe0c0, 0x3f8}, + {&m68k_disassembler::d68000_asl_s_8 , 0xf1f8, 0xe100, 0x000}, + {&m68k_disassembler::d68000_asl_s_16 , 0xf1f8, 0xe140, 0x000}, + {&m68k_disassembler::d68000_asl_s_32 , 0xf1f8, 0xe180, 0x000}, + {&m68k_disassembler::d68000_asl_r_8 , 0xf1f8, 0xe120, 0x000}, + {&m68k_disassembler::d68000_asl_r_16 , 0xf1f8, 0xe160, 0x000}, + {&m68k_disassembler::d68000_asl_r_32 , 0xf1f8, 0xe1a0, 0x000}, + {&m68k_disassembler::d68000_asl_ea , 0xffc0, 0xe1c0, 0x3f8}, + {&m68k_disassembler::d68000_bcc_8 , 0xf000, 0x6000, 0x000}, + {&m68k_disassembler::d68000_bcc_16 , 0xf0ff, 0x6000, 0x000}, + {&m68k_disassembler::d68020_bcc_32 , 0xf0ff, 0x60ff, 0x000}, + {&m68k_disassembler::d68000_bchg_r , 0xf1c0, 0x0140, 0xbf8}, + {&m68k_disassembler::d68000_bchg_s , 0xffc0, 0x0840, 0xbf8}, + {&m68k_disassembler::d68000_bclr_r , 0xf1c0, 0x0180, 0xbf8}, + {&m68k_disassembler::d68000_bclr_s , 0xffc0, 0x0880, 0xbf8}, + {&m68k_disassembler::d68020_bfchg , 0xffc0, 0xeac0, 0xa78}, + {&m68k_disassembler::d68020_bfclr , 0xffc0, 0xecc0, 0xa78}, + {&m68k_disassembler::d68020_bfexts , 0xffc0, 0xebc0, 0xa7b}, + {&m68k_disassembler::d68020_bfextu , 0xffc0, 0xe9c0, 0xa7b}, + {&m68k_disassembler::d68020_bfffo , 0xffc0, 0xedc0, 0xa7b}, + {&m68k_disassembler::d68020_bfins , 0xffc0, 0xefc0, 0xa78}, + {&m68k_disassembler::d68020_bfset , 0xffc0, 0xeec0, 0xa78}, + {&m68k_disassembler::d68020_bftst , 0xffc0, 0xe8c0, 0xa7b}, + {&m68k_disassembler::d68881_ftrap , 0xfff8, 0xf278, 0x000}, + {&m68k_disassembler::d68010_bkpt , 0xfff8, 0x4848, 0x000}, + {&m68k_disassembler::d68000_bra_8 , 0xff00, 0x6000, 0x000}, + {&m68k_disassembler::d68000_bra_16 , 0xffff, 0x6000, 0x000}, + {&m68k_disassembler::d68020_bra_32 , 0xffff, 0x60ff, 0x000}, + {&m68k_disassembler::d68000_bset_r , 0xf1c0, 0x01c0, 0xbf8}, + {&m68k_disassembler::d68000_bset_s , 0xffc0, 0x08c0, 0xbf8}, + {&m68k_disassembler::d68000_bsr_8 , 0xff00, 0x6100, 0x000}, + {&m68k_disassembler::d68000_bsr_16 , 0xffff, 0x6100, 0x000}, + {&m68k_disassembler::d68020_bsr_32 , 0xffff, 0x61ff, 0x000}, + {&m68k_disassembler::d68000_btst_r , 0xf1c0, 0x0100, 0xbff}, + {&m68k_disassembler::d68000_btst_s , 0xffc0, 0x0800, 0xbfb}, + {&m68k_disassembler::d68020_callm , 0xffc0, 0x06c0, 0x27b}, + {&m68k_disassembler::d68020_cas_8 , 0xffc0, 0x0ac0, 0x3f8}, + {&m68k_disassembler::d68020_cas_16 , 0xffc0, 0x0cc0, 0x3f8}, + {&m68k_disassembler::d68020_cas_32 , 0xffc0, 0x0ec0, 0x3f8}, + {&m68k_disassembler::d68020_cas2_16 , 0xffff, 0x0cfc, 0x000}, + {&m68k_disassembler::d68020_cas2_32 , 0xffff, 0x0efc, 0x000}, + {&m68k_disassembler::d68000_chk_16 , 0xf1c0, 0x4180, 0xbff}, + {&m68k_disassembler::d68020_chk_32 , 0xf1c0, 0x4100, 0xbff}, + {&m68k_disassembler::d68020_chk2_cmp2_8 , 0xffc0, 0x00c0, 0x27b}, + {&m68k_disassembler::d68020_chk2_cmp2_16 , 0xffc0, 0x02c0, 0x27b}, + {&m68k_disassembler::d68020_chk2_cmp2_32 , 0xffc0, 0x04c0, 0x27b}, + {&m68k_disassembler::d68040_cinv , 0xff20, 0xf400, 0x000}, + {&m68k_disassembler::d68000_clr_8 , 0xffc0, 0x4200, 0xbf8}, + {&m68k_disassembler::d68000_clr_16 , 0xffc0, 0x4240, 0xbf8}, + {&m68k_disassembler::d68000_clr_32 , 0xffc0, 0x4280, 0xbf8}, + {&m68k_disassembler::d68000_cmp_8 , 0xf1c0, 0xb000, 0xbff}, + {&m68k_disassembler::d68000_cmp_16 , 0xf1c0, 0xb040, 0xfff}, + {&m68k_disassembler::d68000_cmp_32 , 0xf1c0, 0xb080, 0xfff}, + {&m68k_disassembler::d68000_cmpa_16 , 0xf1c0, 0xb0c0, 0xfff}, + {&m68k_disassembler::d68000_cmpa_32 , 0xf1c0, 0xb1c0, 0xfff}, + {&m68k_disassembler::d68000_cmpi_8 , 0xffc0, 0x0c00, 0xbf8}, + {&m68k_disassembler::d68020_cmpi_pcdi_8 , 0xffff, 0x0c3a, 0x000}, + {&m68k_disassembler::d68020_cmpi_pcix_8 , 0xffff, 0x0c3b, 0x000}, + {&m68k_disassembler::d68000_cmpi_16 , 0xffc0, 0x0c40, 0xbf8}, + {&m68k_disassembler::d68020_cmpi_pcdi_16 , 0xffff, 0x0c7a, 0x000}, + {&m68k_disassembler::d68020_cmpi_pcix_16 , 0xffff, 0x0c7b, 0x000}, + {&m68k_disassembler::d68000_cmpi_32 , 0xffc0, 0x0c80, 0xbf8}, + {&m68k_disassembler::d68020_cmpi_pcdi_32 , 0xffff, 0x0cba, 0x000}, + {&m68k_disassembler::d68020_cmpi_pcix_32 , 0xffff, 0x0cbb, 0x000}, + {&m68k_disassembler::d68000_cmpm_8 , 0xf1f8, 0xb108, 0x000}, + {&m68k_disassembler::d68000_cmpm_16 , 0xf1f8, 0xb148, 0x000}, + {&m68k_disassembler::d68000_cmpm_32 , 0xf1f8, 0xb188, 0x000}, + {&m68k_disassembler::d68020_cpbcc_16 , 0xf1c0, 0xf080, 0x000}, + {&m68k_disassembler::d68020_cpbcc_32 , 0xf1c0, 0xf0c0, 0x000}, + {&m68k_disassembler::d68020_cpdbcc , 0xf1f8, 0xf048, 0x000}, + {&m68k_disassembler::d68020_cpgen , 0xf1c0, 0xf000, 0x000}, + {&m68k_disassembler::d68020_cprestore , 0xf1c0, 0xf140, 0x37f}, + {&m68k_disassembler::d68020_cpsave , 0xf1c0, 0xf100, 0x2f8}, + {&m68k_disassembler::d68020_cpscc , 0xf1c0, 0xf040, 0xbf8}, + {&m68k_disassembler::d68020_cptrapcc_0 , 0xf1ff, 0xf07c, 0x000}, + {&m68k_disassembler::d68020_cptrapcc_16 , 0xf1ff, 0xf07a, 0x000}, + {&m68k_disassembler::d68020_cptrapcc_32 , 0xf1ff, 0xf07b, 0x000}, + {&m68k_disassembler::d68040_cpush , 0xff20, 0xf420, 0x000}, + {&m68k_disassembler::d68000_dbcc , 0xf0f8, 0x50c8, 0x000}, + {&m68k_disassembler::d68000_dbra , 0xfff8, 0x51c8, 0x000}, + {&m68k_disassembler::d68000_divs , 0xf1c0, 0x81c0, 0xbff}, + {&m68k_disassembler::d68000_divu , 0xf1c0, 0x80c0, 0xbff}, + {&m68k_disassembler::d68020_divl , 0xffc0, 0x4c40, 0xbff}, + {&m68k_disassembler::d68000_eor_8 , 0xf1c0, 0xb100, 0xbf8}, + {&m68k_disassembler::d68000_eor_16 , 0xf1c0, 0xb140, 0xbf8}, + {&m68k_disassembler::d68000_eor_32 , 0xf1c0, 0xb180, 0xbf8}, + {&m68k_disassembler::d68000_eori_to_ccr , 0xffff, 0x0a3c, 0x000}, + {&m68k_disassembler::d68000_eori_to_sr , 0xffff, 0x0a7c, 0x000}, + {&m68k_disassembler::d68000_eori_8 , 0xffc0, 0x0a00, 0xbf8}, + {&m68k_disassembler::d68000_eori_16 , 0xffc0, 0x0a40, 0xbf8}, + {&m68k_disassembler::d68000_eori_32 , 0xffc0, 0x0a80, 0xbf8}, + {&m68k_disassembler::d68000_exg_dd , 0xf1f8, 0xc140, 0x000}, + {&m68k_disassembler::d68000_exg_aa , 0xf1f8, 0xc148, 0x000}, + {&m68k_disassembler::d68000_exg_da , 0xf1f8, 0xc188, 0x000}, + {&m68k_disassembler::d68020_extb_32 , 0xfff8, 0x49c0, 0x000}, + {&m68k_disassembler::d68000_ext_16 , 0xfff8, 0x4880, 0x000}, + {&m68k_disassembler::d68000_ext_32 , 0xfff8, 0x48c0, 0x000}, + {&m68k_disassembler::d68040_fpu , 0xffc0, 0xf200, 0x000}, + {&m68k_disassembler::d68000_illegal , 0xffff, 0x4afc, 0x000}, + {&m68k_disassembler::d68000_jmp , 0xffc0, 0x4ec0, 0x27b}, + {&m68k_disassembler::d68000_jsr , 0xffc0, 0x4e80, 0x27b}, + {&m68k_disassembler::d68000_lea , 0xf1c0, 0x41c0, 0x27b}, + {&m68k_disassembler::d68000_link_16 , 0xfff8, 0x4e50, 0x000}, + {&m68k_disassembler::d68020_link_32 , 0xfff8, 0x4808, 0x000}, + {&m68k_disassembler::d68000_lsr_s_8 , 0xf1f8, 0xe008, 0x000}, + {&m68k_disassembler::d68000_lsr_s_16 , 0xf1f8, 0xe048, 0x000}, + {&m68k_disassembler::d68000_lsr_s_32 , 0xf1f8, 0xe088, 0x000}, + {&m68k_disassembler::d68000_lsr_r_8 , 0xf1f8, 0xe028, 0x000}, + {&m68k_disassembler::d68000_lsr_r_16 , 0xf1f8, 0xe068, 0x000}, + {&m68k_disassembler::d68000_lsr_r_32 , 0xf1f8, 0xe0a8, 0x000}, + {&m68k_disassembler::d68000_lsr_ea , 0xffc0, 0xe2c0, 0x3f8}, + {&m68k_disassembler::d68000_lsl_s_8 , 0xf1f8, 0xe108, 0x000}, + {&m68k_disassembler::d68000_lsl_s_16 , 0xf1f8, 0xe148, 0x000}, + {&m68k_disassembler::d68000_lsl_s_32 , 0xf1f8, 0xe188, 0x000}, + {&m68k_disassembler::d68000_lsl_r_8 , 0xf1f8, 0xe128, 0x000}, + {&m68k_disassembler::d68000_lsl_r_16 , 0xf1f8, 0xe168, 0x000}, + {&m68k_disassembler::d68000_lsl_r_32 , 0xf1f8, 0xe1a8, 0x000}, + {&m68k_disassembler::d68000_lsl_ea , 0xffc0, 0xe3c0, 0x3f8}, + {&m68k_disassembler::d68000_move_8 , 0xf000, 0x1000, 0xbff}, + {&m68k_disassembler::d68000_move_16 , 0xf000, 0x3000, 0xfff}, + {&m68k_disassembler::d68000_move_32 , 0xf000, 0x2000, 0xfff}, + {&m68k_disassembler::d68000_movea_16 , 0xf1c0, 0x3040, 0xfff}, + {&m68k_disassembler::d68000_movea_32 , 0xf1c0, 0x2040, 0xfff}, + {&m68k_disassembler::d68000_move_to_ccr , 0xffc0, 0x44c0, 0xbff}, + {&m68k_disassembler::d68010_move_fr_ccr , 0xffc0, 0x42c0, 0xbf8}, + {&m68k_disassembler::d68000_move_to_sr , 0xffc0, 0x46c0, 0xbff}, + {&m68k_disassembler::d68000_move_fr_sr , 0xffc0, 0x40c0, 0xbf8}, + {&m68k_disassembler::d68000_move_to_usp , 0xfff8, 0x4e60, 0x000}, + {&m68k_disassembler::d68000_move_fr_usp , 0xfff8, 0x4e68, 0x000}, + {&m68k_disassembler::d68010_movec , 0xfffe, 0x4e7a, 0x000}, + {&m68k_disassembler::d68000_movem_pd_16 , 0xfff8, 0x48a0, 0x000}, + {&m68k_disassembler::d68000_movem_pd_32 , 0xfff8, 0x48e0, 0x000}, + {&m68k_disassembler::d68000_movem_re_16 , 0xffc0, 0x4880, 0x2f8}, + {&m68k_disassembler::d68000_movem_re_32 , 0xffc0, 0x48c0, 0x2f8}, + {&m68k_disassembler::d68000_movem_er_16 , 0xffc0, 0x4c80, 0x37b}, + {&m68k_disassembler::d68000_movem_er_32 , 0xffc0, 0x4cc0, 0x37b}, + {&m68k_disassembler::d68000_movep_er_16 , 0xf1f8, 0x0108, 0x000}, + {&m68k_disassembler::d68000_movep_er_32 , 0xf1f8, 0x0148, 0x000}, + {&m68k_disassembler::d68000_movep_re_16 , 0xf1f8, 0x0188, 0x000}, + {&m68k_disassembler::d68000_movep_re_32 , 0xf1f8, 0x01c8, 0x000}, + {&m68k_disassembler::d68010_moves_8 , 0xffc0, 0x0e00, 0x3f8}, + {&m68k_disassembler::d68010_moves_16 , 0xffc0, 0x0e40, 0x3f8}, + {&m68k_disassembler::d68010_moves_32 , 0xffc0, 0x0e80, 0x3f8}, + {&m68k_disassembler::d68000_moveq , 0xf100, 0x7000, 0x000}, + {&m68k_disassembler::d68040_move16_pi_pi , 0xfff8, 0xf620, 0x000}, + {&m68k_disassembler::d68040_move16_pi_al , 0xfff8, 0xf600, 0x000}, + {&m68k_disassembler::d68040_move16_al_pi , 0xfff8, 0xf608, 0x000}, + {&m68k_disassembler::d68040_move16_ai_al , 0xfff8, 0xf610, 0x000}, + {&m68k_disassembler::d68040_move16_al_ai , 0xfff8, 0xf618, 0x000}, + {&m68k_disassembler::d68000_muls , 0xf1c0, 0xc1c0, 0xbff}, + {&m68k_disassembler::d68000_mulu , 0xf1c0, 0xc0c0, 0xbff}, + {&m68k_disassembler::d68020_mull , 0xffc0, 0x4c00, 0xbff}, + {&m68k_disassembler::d68000_nbcd , 0xffc0, 0x4800, 0xbf8}, + {&m68k_disassembler::d68000_neg_8 , 0xffc0, 0x4400, 0xbf8}, + {&m68k_disassembler::d68000_neg_16 , 0xffc0, 0x4440, 0xbf8}, + {&m68k_disassembler::d68000_neg_32 , 0xffc0, 0x4480, 0xbf8}, + {&m68k_disassembler::d68000_negx_8 , 0xffc0, 0x4000, 0xbf8}, + {&m68k_disassembler::d68000_negx_16 , 0xffc0, 0x4040, 0xbf8}, + {&m68k_disassembler::d68000_negx_32 , 0xffc0, 0x4080, 0xbf8}, + {&m68k_disassembler::d68000_nop , 0xffff, 0x4e71, 0x000}, + {&m68k_disassembler::d68000_not_8 , 0xffc0, 0x4600, 0xbf8}, + {&m68k_disassembler::d68000_not_16 , 0xffc0, 0x4640, 0xbf8}, + {&m68k_disassembler::d68000_not_32 , 0xffc0, 0x4680, 0xbf8}, + {&m68k_disassembler::d68000_or_er_8 , 0xf1c0, 0x8000, 0xbff}, + {&m68k_disassembler::d68000_or_er_16 , 0xf1c0, 0x8040, 0xbff}, + {&m68k_disassembler::d68000_or_er_32 , 0xf1c0, 0x8080, 0xbff}, + {&m68k_disassembler::d68000_or_re_8 , 0xf1c0, 0x8100, 0x3f8}, + {&m68k_disassembler::d68000_or_re_16 , 0xf1c0, 0x8140, 0x3f8}, + {&m68k_disassembler::d68000_or_re_32 , 0xf1c0, 0x8180, 0x3f8}, + {&m68k_disassembler::d68000_ori_to_ccr , 0xffff, 0x003c, 0x000}, + {&m68k_disassembler::d68000_ori_to_sr , 0xffff, 0x007c, 0x000}, + {&m68k_disassembler::d68000_ori_8 , 0xffc0, 0x0000, 0xbf8}, + {&m68k_disassembler::d68000_ori_16 , 0xffc0, 0x0040, 0xbf8}, + {&m68k_disassembler::d68000_ori_32 , 0xffc0, 0x0080, 0xbf8}, + {&m68k_disassembler::d68020_pack_rr , 0xf1f8, 0x8140, 0x000}, + {&m68k_disassembler::d68020_pack_mm , 0xf1f8, 0x8148, 0x000}, + {&m68k_disassembler::d68000_pea , 0xffc0, 0x4840, 0x27b}, + {&m68k_disassembler::d68040_pflush , 0xffe0, 0xf500, 0x000}, + {&m68k_disassembler::d68000_reset , 0xffff, 0x4e70, 0x000}, + {&m68k_disassembler::d68000_ror_s_8 , 0xf1f8, 0xe018, 0x000}, + {&m68k_disassembler::d68000_ror_s_16 , 0xf1f8, 0xe058, 0x000}, + {&m68k_disassembler::d68000_ror_s_32 , 0xf1f8, 0xe098, 0x000}, + {&m68k_disassembler::d68000_ror_r_8 , 0xf1f8, 0xe038, 0x000}, + {&m68k_disassembler::d68000_ror_r_16 , 0xf1f8, 0xe078, 0x000}, + {&m68k_disassembler::d68000_ror_r_32 , 0xf1f8, 0xe0b8, 0x000}, + {&m68k_disassembler::d68000_ror_ea , 0xffc0, 0xe6c0, 0x3f8}, + {&m68k_disassembler::d68000_rol_s_8 , 0xf1f8, 0xe118, 0x000}, + {&m68k_disassembler::d68000_rol_s_16 , 0xf1f8, 0xe158, 0x000}, + {&m68k_disassembler::d68000_rol_s_32 , 0xf1f8, 0xe198, 0x000}, + {&m68k_disassembler::d68000_rol_r_8 , 0xf1f8, 0xe138, 0x000}, + {&m68k_disassembler::d68000_rol_r_16 , 0xf1f8, 0xe178, 0x000}, + {&m68k_disassembler::d68000_rol_r_32 , 0xf1f8, 0xe1b8, 0x000}, + {&m68k_disassembler::d68000_rol_ea , 0xffc0, 0xe7c0, 0x3f8}, + {&m68k_disassembler::d68000_roxr_s_8 , 0xf1f8, 0xe010, 0x000}, + {&m68k_disassembler::d68000_roxr_s_16 , 0xf1f8, 0xe050, 0x000}, + {&m68k_disassembler::d68000_roxr_s_32 , 0xf1f8, 0xe090, 0x000}, + {&m68k_disassembler::d68000_roxr_r_8 , 0xf1f8, 0xe030, 0x000}, + {&m68k_disassembler::d68000_roxr_r_16 , 0xf1f8, 0xe070, 0x000}, + {&m68k_disassembler::d68000_roxr_r_32 , 0xf1f8, 0xe0b0, 0x000}, + {&m68k_disassembler::d68000_roxr_ea , 0xffc0, 0xe4c0, 0x3f8}, + {&m68k_disassembler::d68000_roxl_s_8 , 0xf1f8, 0xe110, 0x000}, + {&m68k_disassembler::d68000_roxl_s_16 , 0xf1f8, 0xe150, 0x000}, + {&m68k_disassembler::d68000_roxl_s_32 , 0xf1f8, 0xe190, 0x000}, + {&m68k_disassembler::d68000_roxl_r_8 , 0xf1f8, 0xe130, 0x000}, + {&m68k_disassembler::d68000_roxl_r_16 , 0xf1f8, 0xe170, 0x000}, + {&m68k_disassembler::d68000_roxl_r_32 , 0xf1f8, 0xe1b0, 0x000}, + {&m68k_disassembler::d68000_roxl_ea , 0xffc0, 0xe5c0, 0x3f8}, + {&m68k_disassembler::d68010_rtd , 0xffff, 0x4e74, 0x000}, + {&m68k_disassembler::d68000_rte , 0xffff, 0x4e73, 0x000}, + {&m68k_disassembler::d68020_rtm , 0xfff0, 0x06c0, 0x000}, + {&m68k_disassembler::d68000_rtr , 0xffff, 0x4e77, 0x000}, + {&m68k_disassembler::d68000_rts , 0xffff, 0x4e75, 0x000}, + {&m68k_disassembler::d68000_sbcd_rr , 0xf1f8, 0x8100, 0x000}, + {&m68k_disassembler::d68000_sbcd_mm , 0xf1f8, 0x8108, 0x000}, + {&m68k_disassembler::d68000_scc , 0xf0c0, 0x50c0, 0xbf8}, + {&m68k_disassembler::d68000_stop , 0xffff, 0x4e72, 0x000}, + {&m68k_disassembler::d68000_sub_er_8 , 0xf1c0, 0x9000, 0xbff}, + {&m68k_disassembler::d68000_sub_er_16 , 0xf1c0, 0x9040, 0xfff}, + {&m68k_disassembler::d68000_sub_er_32 , 0xf1c0, 0x9080, 0xfff}, + {&m68k_disassembler::d68000_sub_re_8 , 0xf1c0, 0x9100, 0x3f8}, + {&m68k_disassembler::d68000_sub_re_16 , 0xf1c0, 0x9140, 0x3f8}, + {&m68k_disassembler::d68000_sub_re_32 , 0xf1c0, 0x9180, 0x3f8}, + {&m68k_disassembler::d68000_suba_16 , 0xf1c0, 0x90c0, 0xfff}, + {&m68k_disassembler::d68000_suba_32 , 0xf1c0, 0x91c0, 0xfff}, + {&m68k_disassembler::d68000_subi_8 , 0xffc0, 0x0400, 0xbf8}, + {&m68k_disassembler::d68000_subi_16 , 0xffc0, 0x0440, 0xbf8}, + {&m68k_disassembler::d68000_subi_32 , 0xffc0, 0x0480, 0xbf8}, + {&m68k_disassembler::d68000_subq_8 , 0xf1c0, 0x5100, 0xbf8}, + {&m68k_disassembler::d68000_subq_16 , 0xf1c0, 0x5140, 0xff8}, + {&m68k_disassembler::d68000_subq_32 , 0xf1c0, 0x5180, 0xff8}, + {&m68k_disassembler::d68000_subx_rr_8 , 0xf1f8, 0x9100, 0x000}, + {&m68k_disassembler::d68000_subx_rr_16 , 0xf1f8, 0x9140, 0x000}, + {&m68k_disassembler::d68000_subx_rr_32 , 0xf1f8, 0x9180, 0x000}, + {&m68k_disassembler::d68000_subx_mm_8 , 0xf1f8, 0x9108, 0x000}, + {&m68k_disassembler::d68000_subx_mm_16 , 0xf1f8, 0x9148, 0x000}, + {&m68k_disassembler::d68000_subx_mm_32 , 0xf1f8, 0x9188, 0x000}, + {&m68k_disassembler::d68000_swap , 0xfff8, 0x4840, 0x000}, + {&m68k_disassembler::d68000_tas , 0xffc0, 0x4ac0, 0xbf8}, + {&m68k_disassembler::d68000_trap , 0xfff0, 0x4e40, 0x000}, + {&m68k_disassembler::d68020_trapcc_0 , 0xf0ff, 0x50fc, 0x000}, + {&m68k_disassembler::d68020_trapcc_16 , 0xf0ff, 0x50fa, 0x000}, + {&m68k_disassembler::d68020_trapcc_32 , 0xf0ff, 0x50fb, 0x000}, + {&m68k_disassembler::d68000_trapv , 0xffff, 0x4e76, 0x000}, + {&m68k_disassembler::d68000_tst_8 , 0xffc0, 0x4a00, 0xbf8}, + {&m68k_disassembler::d68020_tst_pcdi_8 , 0xffff, 0x4a3a, 0x000}, + {&m68k_disassembler::d68020_tst_pcix_8 , 0xffff, 0x4a3b, 0x000}, + {&m68k_disassembler::d68020_tst_i_8 , 0xffff, 0x4a3c, 0x000}, + {&m68k_disassembler::d68000_tst_16 , 0xffc0, 0x4a40, 0xbf8}, + {&m68k_disassembler::d68020_tst_a_16 , 0xfff8, 0x4a48, 0x000}, + {&m68k_disassembler::d68020_tst_pcdi_16 , 0xffff, 0x4a7a, 0x000}, + {&m68k_disassembler::d68020_tst_pcix_16 , 0xffff, 0x4a7b, 0x000}, + {&m68k_disassembler::d68020_tst_i_16 , 0xffff, 0x4a7c, 0x000}, + {&m68k_disassembler::d68000_tst_32 , 0xffc0, 0x4a80, 0xbf8}, + {&m68k_disassembler::d68020_tst_a_32 , 0xfff8, 0x4a88, 0x000}, + {&m68k_disassembler::d68020_tst_pcdi_32 , 0xffff, 0x4aba, 0x000}, + {&m68k_disassembler::d68020_tst_pcix_32 , 0xffff, 0x4abb, 0x000}, + {&m68k_disassembler::d68020_tst_i_32 , 0xffff, 0x4abc, 0x000}, + {&m68k_disassembler::d68000_unlk , 0xfff8, 0x4e58, 0x000}, + {&m68k_disassembler::d68020_unpk_rr , 0xf1f8, 0x8180, 0x000}, + {&m68k_disassembler::d68020_unpk_mm , 0xf1f8, 0x8188, 0x000}, + {&m68k_disassembler::d68851_p000 , 0xffc0, 0xf000, 0x000}, + {&m68k_disassembler::d68851_pbcc16 , 0xffc0, 0xf080, 0x000}, + {&m68k_disassembler::d68851_pbcc32 , 0xffc0, 0xf0c0, 0x000}, + {&m68k_disassembler::d68851_pdbcc , 0xfff8, 0xf048, 0x000}, + {&m68k_disassembler::d68851_p001 , 0xffc0, 0xf040, 0x000}, + {&m68k_disassembler::d68040_fbcc_16 , 0xffc0, 0xf280, 0x000}, + {&m68k_disassembler::d68040_fbcc_32 , 0xffc0, 0xf2c0, 0x000}, {nullptr, 0, 0, 0} }; /* Check if opcode is using a valid ea mode */ -static int valid_ea(uint32_t opcode, uint32_t mask) +bool m68k_disassembler::valid_ea(u32 opcode, u32 mask) { if(mask == 0) - return 1; + return true; switch(opcode & 0x3f) { @@ -3762,15 +3435,14 @@ static int valid_ea(uint32_t opcode, uint32_t mask) case 0x3c: return (mask & 0x004) != 0; } - return 0; - + return false; } /* Used by qsort */ -static int DECL_SPEC compare_nof_true_bits(const void *aptr, const void *bptr) +bool m68k_disassembler::compare_nof_true_bits(const opcode_struct *aptr, const opcode_struct *bptr) { - uint32_t a = ((const opcode_struct*)aptr)->mask; - uint32_t b = ((const opcode_struct*)bptr)->mask; + u32 a = aptr->mask; + u32 b = bptr->mask; a = ((a & 0xAAAA) >> 1) + (a & 0x5555); a = ((a & 0xCCCC) >> 2) + (a & 0x3333); @@ -3782,39 +3454,35 @@ static int DECL_SPEC compare_nof_true_bits(const void *aptr, const void *bptr) b = ((b & 0xF0F0) >> 4) + (b & 0x0F0F); b = ((b & 0xFF00) >> 8) + (b & 0x00FF); - return b - a; /* reversed to get greatest to least sorting */ + return b < a; /* reversed to get greatest to least sorting */ } /* build the opcode handler jump table */ -static void build_opcode_table(void) +void m68k_disassembler::build_opcode_table() { - uint32_t i; - uint32_t opcode; - opcode_struct* ostruct; - opcode_struct opcode_info[ARRAY_LENGTH(g_opcode_info)]; + std::vector<const opcode_struct *> opcode_info; + for(unsigned int i=0; m_opcode_info[i].handler; i++) + opcode_info.push_back(m_opcode_info + i); + std::sort(opcode_info.begin(), opcode_info.end(), compare_nof_true_bits); - memcpy(opcode_info, g_opcode_info, sizeof(g_opcode_info)); - qsort((void *)opcode_info, ARRAY_LENGTH(opcode_info)-1, sizeof(opcode_info[0]), compare_nof_true_bits); - - for(i=0;i<0x10000;i++) + for(u32 opcode = 0; opcode != 0x10000; opcode++) { - g_instruction_table[i] = d68000_illegal; /* default to illegal */ - opcode = i; + m_instruction_table[opcode] = &m68k_disassembler::d68000_illegal; /* default to illegal */ /* search through opcode info for a match */ - for(ostruct = opcode_info;ostruct->opcode_handler != nullptr;ostruct++) + for(const opcode_struct *ostruct : opcode_info) { /* match opcode mask and allowed ea modes */ if((opcode & ostruct->mask) == ostruct->match) { /* Handle destination ea for move instructions */ - if((ostruct->opcode_handler == d68000_move_8 || - ostruct->opcode_handler == d68000_move_16 || - ostruct->opcode_handler == d68000_move_32) && - !valid_ea(((opcode>>9)&7) | ((opcode>>3)&0x38), 0xbf8)) - continue; + if((ostruct->handler == &m68k_disassembler::d68000_move_8 || + ostruct->handler == &m68k_disassembler::d68000_move_16 || + ostruct->handler == &m68k_disassembler::d68000_move_32) && + !valid_ea(((opcode>>9)&7) | ((opcode>>3)&0x38), 0xbf8)) + continue; if(valid_ea(opcode, ostruct->ea_mask)) { - g_instruction_table[i] = ostruct->opcode_handler; + m_instruction_table[opcode] = ostruct->handler; break; } } @@ -3828,330 +3496,22 @@ static void build_opcode_table(void) /* ================================= API ================================== */ /* ======================================================================== */ -/* Disasemble one instruction at pc and store in str_buff */ -static unsigned int m68k_disassemble(std::ostream &stream, unsigned int pc, unsigned int cpu_type) +m68k_disassembler::m68k_disassembler(u32 type) : m_cpu_type(type) { - if(!g_initialized) - { - build_opcode_table(); - g_initialized = 1; - } - switch(cpu_type) - { - case M68K_CPU_TYPE_68000: - g_cpu_type = TYPE_68000; - break; - case M68K_CPU_TYPE_68008: - g_cpu_type = TYPE_68008; - break; - case M68K_CPU_TYPE_68010: - g_cpu_type = TYPE_68010; - break; - case M68K_CPU_TYPE_68EC020: - case M68K_CPU_TYPE_68020: - g_cpu_type = TYPE_68020; - break; - case M68K_CPU_TYPE_68EC030: - case M68K_CPU_TYPE_68030: - g_cpu_type = TYPE_68030; - break; - case M68K_CPU_TYPE_68040: - case M68K_CPU_TYPE_68EC040: - case M68K_CPU_TYPE_68LC040: - g_cpu_type = TYPE_68040; - break; - case M68K_CPU_TYPE_FSCPU32: - g_cpu_type = TYPE_68340; - break; - case M68K_CPU_TYPE_COLDFIRE: - g_cpu_type = TYPE_COLDFIRE; - break; - default: - return 0; - } - - g_cpu_pc = pc; - g_helper_str[0] = 0; - g_cpu_ir = read_imm_16(); - g_opcode_type = 0; - g_instruction_table[g_cpu_ir](); - util::stream_format(stream, "%s%s", g_dasm_str, g_helper_str); - return COMBINE_OPCODE_FLAGS(g_cpu_pc - pc); + build_opcode_table(); } -#ifdef UNUSED_FUNCTION -char* m68ki_disassemble_quick(unsigned int pc, unsigned int cpu_type) +u32 m68k_disassembler::opcode_alignment() const { - static char buff[100]; - buff[0] = 0; - m68k_disassemble(buff, pc, cpu_type); - return buff; + return 2; } -#endif -unsigned int m68k_disassemble_raw(std::ostream &stream, unsigned int pc, const unsigned char* opdata, const unsigned char* argdata, unsigned int cpu_type) +offs_t m68k_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - unsigned int result; - - g_rawop = opdata; - g_rawbasepc = pc; - result = m68k_disassemble(stream, pc, cpu_type); - g_rawop = nullptr; - return result; + m_cpu_pc = pc; + m_buffer = &opcodes; + m_cpu_ir = read_imm_16(); + m_flags = 0; + stream << (this->*m_instruction_table[m_cpu_ir])(); + return (m_cpu_pc - pc) | m_flags | SUPPORTED; } - -#ifdef UNUSED_FUNCTION -/* Check if the instruction is a valid one */ -unsigned int m68k_is_valid_instruction(unsigned int instruction, unsigned int cpu_type) -{ - if(!g_initialized) - { - build_opcode_table(); - g_initialized = 1; - } - - instruction &= 0xffff; - if(g_instruction_table[instruction] == d68000_illegal) - return 0; - - switch(cpu_type) - { - case M68K_CPU_TYPE_68000: - case M68K_CPU_TYPE_68008: - if(g_instruction_table[instruction] == d68010_bkpt) - return 0; - if(g_instruction_table[instruction] == d68010_move_fr_ccr) - return 0; - if(g_instruction_table[instruction] == d68010_movec) - return 0; - if(g_instruction_table[instruction] == d68010_moves_8) - return 0; - if(g_instruction_table[instruction] == d68010_moves_16) - return 0; - if(g_instruction_table[instruction] == d68010_moves_32) - return 0; - if(g_instruction_table[instruction] == d68010_rtd) - return 0; - case M68K_CPU_TYPE_68010: - if(g_instruction_table[instruction] == d68020_bcc_32) - return 0; - if(g_instruction_table[instruction] == d68020_bfchg) - return 0; - if(g_instruction_table[instruction] == d68020_bfclr) - return 0; - if(g_instruction_table[instruction] == d68020_bfexts) - return 0; - if(g_instruction_table[instruction] == d68020_bfextu) - return 0; - if(g_instruction_table[instruction] == d68020_bfffo) - return 0; - if(g_instruction_table[instruction] == d68020_bfins) - return 0; - if(g_instruction_table[instruction] == d68020_bfset) - return 0; - if(g_instruction_table[instruction] == d68020_bftst) - return 0; - if(g_instruction_table[instruction] == d68020_bra_32) - return 0; - if(g_instruction_table[instruction] == d68020_bsr_32) - return 0; - if(g_instruction_table[instruction] == d68020_callm) - return 0; - if(g_instruction_table[instruction] == d68020_cas_8) - return 0; - if(g_instruction_table[instruction] == d68020_cas_16) - return 0; - if(g_instruction_table[instruction] == d68020_cas_32) - return 0; - if(g_instruction_table[instruction] == d68020_cas2_16) - return 0; - if(g_instruction_table[instruction] == d68020_cas2_32) - return 0; - if(g_instruction_table[instruction] == d68020_chk_32) - return 0; - if(g_instruction_table[instruction] == d68020_chk2_cmp2_8) - return 0; - if(g_instruction_table[instruction] == d68020_chk2_cmp2_16) - return 0; - if(g_instruction_table[instruction] == d68020_chk2_cmp2_32) - return 0; - if(g_instruction_table[instruction] == d68020_cmpi_pcdi_8) - return 0; - if(g_instruction_table[instruction] == d68020_cmpi_pcix_8) - return 0; - if(g_instruction_table[instruction] == d68020_cmpi_pcdi_16) - return 0; - if(g_instruction_table[instruction] == d68020_cmpi_pcix_16) - return 0; - if(g_instruction_table[instruction] == d68020_cmpi_pcdi_32) - return 0; - if(g_instruction_table[instruction] == d68020_cmpi_pcix_32) - return 0; - if(g_instruction_table[instruction] == d68020_cpbcc_16) - return 0; - if(g_instruction_table[instruction] == d68020_cpbcc_32) - return 0; - if(g_instruction_table[instruction] == d68020_cpdbcc) - return 0; - if(g_instruction_table[instruction] == d68020_cpgen) - return 0; - if(g_instruction_table[instruction] == d68020_cprestore) - return 0; - if(g_instruction_table[instruction] == d68020_cpsave) - return 0; - if(g_instruction_table[instruction] == d68020_cpscc) - return 0; - if(g_instruction_table[instruction] == d68020_cptrapcc_0) - return 0; - if(g_instruction_table[instruction] == d68020_cptrapcc_16) - return 0; - if(g_instruction_table[instruction] == d68020_cptrapcc_32) - return 0; - if(g_instruction_table[instruction] == d68020_divl) - return 0; - if(g_instruction_table[instruction] == d68020_extb_32) - return 0; - if(g_instruction_table[instruction] == d68020_link_32) - return 0; - if(g_instruction_table[instruction] == d68020_mull) - return 0; - if(g_instruction_table[instruction] == d68020_pack_rr) - return 0; - if(g_instruction_table[instruction] == d68020_pack_mm) - return 0; - if(g_instruction_table[instruction] == d68020_rtm) - return 0; - if(g_instruction_table[instruction] == d68020_trapcc_0) - return 0; - if(g_instruction_table[instruction] == d68020_trapcc_16) - return 0; - if(g_instruction_table[instruction] == d68020_trapcc_32) - return 0; - if(g_instruction_table[instruction] == d68020_tst_pcdi_8) - return 0; - if(g_instruction_table[instruction] == d68020_tst_pcix_8) - return 0; - if(g_instruction_table[instruction] == d68020_tst_i_8) - return 0; - if(g_instruction_table[instruction] == d68020_tst_a_16) - return 0; - if(g_instruction_table[instruction] == d68020_tst_pcdi_16) - return 0; - if(g_instruction_table[instruction] == d68020_tst_pcix_16) - return 0; - if(g_instruction_table[instruction] == d68020_tst_i_16) - return 0; - if(g_instruction_table[instruction] == d68020_tst_a_32) - return 0; - if(g_instruction_table[instruction] == d68020_tst_pcdi_32) - return 0; - if(g_instruction_table[instruction] == d68020_tst_pcix_32) - return 0; - if(g_instruction_table[instruction] == d68020_tst_i_32) - return 0; - if(g_instruction_table[instruction] == d68020_unpk_rr) - return 0; - if(g_instruction_table[instruction] == d68020_unpk_mm) - return 0; - if(g_instruction_table[instruction] == d68040_fbcc_16) - return 0; - if(g_instruction_table[instruction] == d68040_fbcc_32) - return 0; - case M68K_CPU_TYPE_68EC020: - case M68K_CPU_TYPE_68020: - case M68K_CPU_TYPE_68030: - case M68K_CPU_TYPE_68EC030: - case M68K_CPU_TYPE_FSCPU32: - case M68K_CPU_TYPE_COLDFIRE: - if(g_instruction_table[instruction] == d68040_cinv) - return 0; - if(g_instruction_table[instruction] == d68040_cpush) - return 0; - if(g_instruction_table[instruction] == d68040_move16_pi_pi) - return 0; - if(g_instruction_table[instruction] == d68040_move16_pi_al) - return 0; - if(g_instruction_table[instruction] == d68040_move16_al_pi) - return 0; - if(g_instruction_table[instruction] == d68040_move16_ai_al) - return 0; - if(g_instruction_table[instruction] == d68040_move16_al_ai) - return 0; - case M68K_CPU_TYPE_68040: - case M68K_CPU_TYPE_68EC040: - case M68K_CPU_TYPE_68LC040: - if(g_instruction_table[instruction] == d68020_cpbcc_16) - return 0; - if(g_instruction_table[instruction] == d68020_cpbcc_32) - return 0; - if(g_instruction_table[instruction] == d68020_cpdbcc) - return 0; - if(g_instruction_table[instruction] == d68020_cpgen) - return 0; - if(g_instruction_table[instruction] == d68020_cprestore) - return 0; - if(g_instruction_table[instruction] == d68020_cpsave) - return 0; - if(g_instruction_table[instruction] == d68020_cpscc) - return 0; - if(g_instruction_table[instruction] == d68020_cptrapcc_0) - return 0; - if(g_instruction_table[instruction] == d68020_cptrapcc_16) - return 0; - if(g_instruction_table[instruction] == d68020_cptrapcc_32) - return 0; - if(g_instruction_table[instruction] == d68040_pflush) - return 0; - } - if(cpu_type != M68K_CPU_TYPE_68020 && cpu_type != M68K_CPU_TYPE_68EC020 && - (g_instruction_table[instruction] == d68020_callm || - g_instruction_table[instruction] == d68020_rtm)) - return 0; - - return 1; -} -#endif - -CPU_DISASSEMBLE( m68000 ) -{ - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_68000); -} - -CPU_DISASSEMBLE( m68008 ) -{ - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_68008); -} - -CPU_DISASSEMBLE( m68010 ) -{ - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_68010); -} - -CPU_DISASSEMBLE( m68020 ) -{ - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_68020); -} - -CPU_DISASSEMBLE( m68030 ) -{ - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_68030); -} - -CPU_DISASSEMBLE( m68040 ) -{ - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_68040); -} - -CPU_DISASSEMBLE( m68340 ) -{ - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_FSCPU32); -} - -CPU_DISASSEMBLE( coldfire ) -{ - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_COLDFIRE); -} - -/* ======================================================================== */ -/* ============================== END OF FILE ============================= */ -/* ======================================================================== */ diff --git a/src/devices/cpu/m68000/m68kdasm.h b/src/devices/cpu/m68000/m68kdasm.h new file mode 100644 index 00000000000..43dfd144980 --- /dev/null +++ b/src/devices/cpu/m68000/m68kdasm.h @@ -0,0 +1,454 @@ +// license:BSD-3-Clause +// copyright-holders:Karl Stenerud +/* ======================================================================== */ +/* ========================= LICENSING & COPYRIGHT ======================== */ +/* ======================================================================== */ +/* + * MUSASHI + * Version 3.32 + * + * A portable Motorola M680x0 processor emulation engine. + * Copyright Karl Stenerud. All rights reserved. + * + */ + +#ifndef MAME_CPU_M68000_M68KDASM_H +#define MAME_CPU_M68000_M68KDASM_H + +#pragma once + +class m68k_disassembler : public util::disasm_interface +{ +public: + enum { + TYPE_68000 = 1, + TYPE_68008 = 2, + TYPE_68010 = 4, + TYPE_68020 = 8, + TYPE_68030 = 16, + TYPE_68040 = 32, + TYPE_68340 = 64, // (CPU32) + TYPE_COLDFIRE = 128, + }; + + m68k_disassembler(u32 type); + virtual ~m68k_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +protected: + enum { + M68000_ONLY = (TYPE_68000 | TYPE_68008), + M68010_ONLY = TYPE_68010, + M68010_LESS = (TYPE_68000 | TYPE_68008 | TYPE_68010), + M68010_PLUS = (TYPE_68010 | TYPE_68020 | TYPE_68030 | TYPE_68040 | TYPE_68340 | TYPE_COLDFIRE), + M68020_ONLY = (TYPE_68020 | TYPE_68340), + M68020_LESS = (TYPE_68010 | TYPE_68020 | TYPE_68340), + M68020_PLUS = (TYPE_68020 | TYPE_68030 | TYPE_68040 | TYPE_68340 | TYPE_COLDFIRE), + + M68030_ONLY = TYPE_68030, + M68030_LESS = (TYPE_68010 | TYPE_68020 | TYPE_68030 | TYPE_68340 ), + M68030_PLUS = (TYPE_68030 | TYPE_68040), + M68040_PLUS = TYPE_68040, + + COLDFIRE = TYPE_COLDFIRE + }; + + typedef std::string (m68k_disassembler::*opcode_handler)(); + + struct opcode_struct { + opcode_handler handler; /* handler function */ + u32 mask; /* mask on opcode */ + u32 match; /* what to match after masking */ + u32 ea_mask; /* what ea modes are allowed */ + }; + + /* Extension word formats */ + static inline u32 ext_8bit_displacement(u32 A) { return ((A)&0xff); } + static inline u32 ext_full(u32 A) { return BIT(A, 8); } + static inline u32 ext_effective_zero(u32 A) { return (((A)&0xe4) == 0xc4 || ((A)&0xe2) == 0xc0); } + static inline u32 ext_base_register_present(u32 A) { return (!BIT(A, 7)); } + static inline u32 ext_index_register_present(u32 A) { return (!BIT(A, 6)); } + static inline u32 ext_index_register(u32 A) { return (((A)>>12)&7); } + static inline u32 ext_index_scale(u32 A) { return (((A)>>9)&3); } + static inline u32 ext_index_long(u32 A) { return BIT(A, 11); } + static inline u32 ext_index_ar(u32 A) { return BIT(A, 15); } + static inline u32 ext_base_displacement_present(u32 A) { return (((A)&0x30) > 0x10); } + static inline u32 ext_base_displacement_word(u32 A) { return (((A)&0x30) == 0x20); } + static inline u32 ext_base_displacement_long(u32 A) { return (((A)&0x30) == 0x30); } + static inline u32 ext_outer_displacement_present(u32 A) { return (((A)&3) > 1 && ((A)&0x47) < 0x44); } + static inline u32 ext_outer_displacement_word(u32 A) { return (((A)&3) == 2 && ((A)&0x47) < 0x44); } + static inline u32 ext_outer_displacement_long(u32 A) { return (((A)&3) == 3 && ((A)&0x47) < 0x44); } + + static inline s32 sext_7bit_int(u32 value) { return (value & 0x40) ? (value | 0xffffff80) : (value & 0x7f); } + static inline s32 make_int_8(u8 value) { return s8(value); } + static inline s32 make_int_16(u16 value) { return s16(value); } + static inline s32 make_int_32(u32 value) { return s32(value); } + + static std::string make_signed_hex_str_8(u8 val); + static std::string make_signed_hex_str_16(u16 val); + static std::string make_signed_hex_str_32(u32 val); + + inline u32 read_imm_8 (u32 advance) { u32 result = m_buffer->r8 (m_cpu_pc + 1); m_cpu_pc += advance; return result; } + inline u32 read_imm_16(u32 advance) { u32 result = m_buffer->r16(m_cpu_pc); m_cpu_pc += advance; return result; } + inline u32 read_imm_32(u32 advance) { u32 result = m_buffer->r32(m_cpu_pc); m_cpu_pc += advance; return result; } + + inline u32 read_imm_8 () { return read_imm_8 (2); } // 2 to keep alignement + inline u32 read_imm_16() { return read_imm_16(2); } + inline u32 read_imm_32() { return read_imm_32(4); } + + inline u32 peek_imm_8 () { return read_imm_8 (0); } + inline u32 peek_imm_16() { return read_imm_16(0); } + inline u32 peek_imm_32() { return read_imm_32(0); } + + std::string get_imm_str_s(u32 size); + inline std::string get_imm_str_s8 () { return get_imm_str_s(0); } + inline std::string get_imm_str_s16() { return get_imm_str_s(1); } + inline std::string get_imm_str_s32() { return get_imm_str_s(2); } + + std::string get_imm_str_u(u32 size); + inline std::string get_imm_str_u8 () { return get_imm_str_u(0); } + inline std::string get_imm_str_u16() { return get_imm_str_u(1); } + inline std::string get_imm_str_u32() { return get_imm_str_u(2); } + + std::string get_ea_mode_str(u16 instruction, u32 size); + inline std::string get_ea_mode_str_8 (u16 instruction) { return get_ea_mode_str(instruction, 0); } + inline std::string get_ea_mode_str_16(u16 instruction) { return get_ea_mode_str(instruction, 1); } + inline std::string get_ea_mode_str_32(u16 instruction) { return get_ea_mode_str(instruction, 2); } + + inline std::pair<bool, std::string> limit_cpu_types(u32 allowed); + + std::string d68000_illegal(); + std::string d68000_1010(); + std::string d68000_1111(); + std::string d68000_abcd_rr(); + std::string d68000_abcd_mm(); + std::string d68000_add_er_8(); + std::string d68000_add_er_16(); + std::string d68000_add_er_32(); + std::string d68000_add_re_8(); + std::string d68000_add_re_16(); + std::string d68000_add_re_32(); + std::string d68000_adda_16(); + std::string d68000_adda_32(); + std::string d68000_addi_8(); + std::string d68000_addi_16(); + std::string d68000_addi_32(); + std::string d68000_addq_8(); + std::string d68000_addq_16(); + std::string d68000_addq_32(); + std::string d68000_addx_rr_8(); + std::string d68000_addx_rr_16(); + std::string d68000_addx_rr_32(); + std::string d68000_addx_mm_8(); + std::string d68000_addx_mm_16(); + std::string d68000_addx_mm_32(); + std::string d68000_and_er_8(); + std::string d68000_and_er_16(); + std::string d68000_and_er_32(); + std::string d68000_and_re_8(); + std::string d68000_and_re_16(); + std::string d68000_and_re_32(); + std::string d68000_andi_8(); + std::string d68000_andi_16(); + std::string d68000_andi_32(); + std::string d68000_andi_to_ccr(); + std::string d68000_andi_to_sr(); + std::string d68000_asr_s_8(); + std::string d68000_asr_s_16(); + std::string d68000_asr_s_32(); + std::string d68000_asr_r_8(); + std::string d68000_asr_r_16(); + std::string d68000_asr_r_32(); + std::string d68000_asr_ea(); + std::string d68000_asl_s_8(); + std::string d68000_asl_s_16(); + std::string d68000_asl_s_32(); + std::string d68000_asl_r_8(); + std::string d68000_asl_r_16(); + std::string d68000_asl_r_32(); + std::string d68000_asl_ea(); + std::string d68000_bcc_8(); + std::string d68000_bcc_16(); + std::string d68020_bcc_32(); + std::string d68000_bchg_r(); + std::string d68000_bchg_s(); + std::string d68000_bclr_r(); + std::string d68000_bclr_s(); + std::string d68010_bkpt(); + std::string d68020_bfchg(); + std::string d68020_bfclr(); + std::string d68020_bfexts(); + std::string d68020_bfextu(); + std::string d68020_bfffo(); + std::string d68020_bfins(); + std::string d68020_bfset(); + std::string d68020_bftst(); + std::string d68000_bra_8(); + std::string d68000_bra_16(); + std::string d68020_bra_32(); + std::string d68000_bset_r(); + std::string d68000_bset_s(); + std::string d68000_bsr_8(); + std::string d68000_bsr_16(); + std::string d68020_bsr_32(); + std::string d68000_btst_r(); + std::string d68000_btst_s(); + std::string d68020_callm(); + std::string d68020_cas_8(); + std::string d68020_cas_16(); + std::string d68020_cas_32(); + std::string d68020_cas2_16(); + std::string d68020_cas2_32(); + std::string d68000_chk_16(); + std::string d68020_chk_32(); + std::string d68020_chk2_cmp2_8(); + std::string d68020_chk2_cmp2_16(); + std::string d68020_chk2_cmp2_32(); + std::string d68040_cinv(); + std::string d68000_clr_8(); + std::string d68000_clr_16(); + std::string d68000_clr_32(); + std::string d68000_cmp_8(); + std::string d68000_cmp_16(); + std::string d68000_cmp_32(); + std::string d68000_cmpa_16(); + std::string d68000_cmpa_32(); + std::string d68000_cmpi_8(); + std::string d68020_cmpi_pcdi_8(); + std::string d68020_cmpi_pcix_8(); + std::string d68000_cmpi_16(); + std::string d68020_cmpi_pcdi_16(); + std::string d68020_cmpi_pcix_16(); + std::string d68000_cmpi_32(); + std::string d68020_cmpi_pcdi_32(); + std::string d68020_cmpi_pcix_32(); + std::string d68000_cmpm_8(); + std::string d68000_cmpm_16(); + std::string d68000_cmpm_32(); + std::string d68020_cpbcc_16(); + std::string d68020_cpbcc_32(); + std::string d68020_cpdbcc(); + std::string d68020_cpgen(); + std::string d68020_cprestore(); + std::string d68020_cpsave(); + std::string d68020_cpscc(); + std::string d68020_cptrapcc_0(); + std::string d68020_cptrapcc_16(); + std::string d68020_cptrapcc_32(); + std::string d68040_cpush(); + std::string d68000_dbra(); + std::string d68000_dbcc(); + std::string d68000_divs(); + std::string d68000_divu(); + std::string d68020_divl(); + std::string d68000_eor_8(); + std::string d68000_eor_16(); + std::string d68000_eor_32(); + std::string d68000_eori_8(); + std::string d68000_eori_16(); + std::string d68000_eori_32(); + std::string d68000_eori_to_ccr(); + std::string d68000_eori_to_sr(); + std::string d68000_exg_dd(); + std::string d68000_exg_aa(); + std::string d68000_exg_da(); + std::string d68000_ext_16(); + std::string d68000_ext_32(); + std::string d68020_extb_32(); + std::string d68881_ftrap(); + std::string d68040_fpu(); + std::string d68000_jmp(); + std::string d68000_jsr(); + std::string d68000_lea(); + std::string d68000_link_16(); + std::string d68020_link_32(); + std::string d68000_lsr_s_8(); + std::string d68000_lsr_s_16(); + std::string d68000_lsr_s_32(); + std::string d68000_lsr_r_8(); + std::string d68000_lsr_r_16(); + std::string d68000_lsr_r_32(); + std::string d68000_lsr_ea(); + std::string d68000_lsl_s_8(); + std::string d68000_lsl_s_16(); + std::string d68000_lsl_s_32(); + std::string d68000_lsl_r_8(); + std::string d68000_lsl_r_16(); + std::string d68000_lsl_r_32(); + std::string d68000_lsl_ea(); + std::string d68000_move_8(); + std::string d68000_move_16(); + std::string d68000_move_32(); + std::string d68000_movea_16(); + std::string d68000_movea_32(); + std::string d68000_move_to_ccr(); + std::string d68010_move_fr_ccr(); + std::string d68000_move_fr_sr(); + std::string d68000_move_to_sr(); + std::string d68000_move_fr_usp(); + std::string d68000_move_to_usp(); + std::string d68010_movec(); + std::string d68000_movem_pd_16(); + std::string d68000_movem_pd_32(); + std::string d68000_movem_er_16(); + std::string d68000_movem_er_32(); + std::string d68000_movem_re_16(); + std::string d68000_movem_re_32(); + std::string d68000_movep_re_16(); + std::string d68000_movep_re_32(); + std::string d68000_movep_er_16(); + std::string d68000_movep_er_32(); + std::string d68010_moves_8(); + std::string d68010_moves_16(); + std::string d68010_moves_32(); + std::string d68000_moveq(); + std::string d68040_move16_pi_pi(); + std::string d68040_move16_pi_al(); + std::string d68040_move16_al_pi(); + std::string d68040_move16_ai_al(); + std::string d68040_move16_al_ai(); + std::string d68000_muls(); + std::string d68000_mulu(); + std::string d68020_mull(); + std::string d68000_nbcd(); + std::string d68000_neg_8(); + std::string d68000_neg_16(); + std::string d68000_neg_32(); + std::string d68000_negx_8(); + std::string d68000_negx_16(); + std::string d68000_negx_32(); + std::string d68000_nop(); + std::string d68000_not_8(); + std::string d68000_not_16(); + std::string d68000_not_32(); + std::string d68000_or_er_8(); + std::string d68000_or_er_16(); + std::string d68000_or_er_32(); + std::string d68000_or_re_8(); + std::string d68000_or_re_16(); + std::string d68000_or_re_32(); + std::string d68000_ori_8(); + std::string d68000_ori_16(); + std::string d68000_ori_32(); + std::string d68000_ori_to_ccr(); + std::string d68000_ori_to_sr(); + std::string d68020_pack_rr(); + std::string d68020_pack_mm(); + std::string d68000_pea(); + std::string d68040_pflush(); + std::string d68000_reset(); + std::string d68000_ror_s_8(); + std::string d68000_ror_s_16(); + std::string d68000_ror_s_32(); + std::string d68000_ror_r_8(); + std::string d68000_ror_r_16(); + std::string d68000_ror_r_32(); + std::string d68000_ror_ea(); + std::string d68000_rol_s_8(); + std::string d68000_rol_s_16(); + std::string d68000_rol_s_32(); + std::string d68000_rol_r_8(); + std::string d68000_rol_r_16(); + std::string d68000_rol_r_32(); + std::string d68000_rol_ea(); + std::string d68000_roxr_s_8(); + std::string d68000_roxr_s_16(); + std::string d68000_roxr_s_32(); + std::string d68000_roxr_r_8(); + std::string d68000_roxr_r_16(); + std::string d68000_roxr_r_32(); + std::string d68000_roxr_ea(); + std::string d68000_roxl_s_8(); + std::string d68000_roxl_s_16(); + std::string d68000_roxl_s_32(); + std::string d68000_roxl_r_8(); + std::string d68000_roxl_r_16(); + std::string d68000_roxl_r_32(); + std::string d68000_roxl_ea(); + std::string d68010_rtd(); + std::string d68000_rte(); + std::string d68020_rtm(); + std::string d68000_rtr(); + std::string d68000_rts(); + std::string d68000_sbcd_rr(); + std::string d68000_sbcd_mm(); + std::string d68000_scc(); + std::string d68000_stop(); + std::string d68000_sub_er_8(); + std::string d68000_sub_er_16(); + std::string d68000_sub_er_32(); + std::string d68000_sub_re_8(); + std::string d68000_sub_re_16(); + std::string d68000_sub_re_32(); + std::string d68000_suba_16(); + std::string d68000_suba_32(); + std::string d68000_subi_8(); + std::string d68000_subi_16(); + std::string d68000_subi_32(); + std::string d68000_subq_8(); + std::string d68000_subq_16(); + std::string d68000_subq_32(); + std::string d68000_subx_rr_8(); + std::string d68000_subx_rr_16(); + std::string d68000_subx_rr_32(); + std::string d68000_subx_mm_8(); + std::string d68000_subx_mm_16(); + std::string d68000_subx_mm_32(); + std::string d68000_swap(); + std::string d68000_tas(); + std::string d68000_trap(); + std::string d68020_trapcc_0(); + std::string d68020_trapcc_16(); + std::string d68020_trapcc_32(); + std::string d68000_trapv(); + std::string d68000_tst_8(); + std::string d68020_tst_pcdi_8(); + std::string d68020_tst_pcix_8(); + std::string d68020_tst_i_8(); + std::string d68000_tst_16(); + std::string d68020_tst_a_16(); + std::string d68020_tst_pcdi_16(); + std::string d68020_tst_pcix_16(); + std::string d68020_tst_i_16(); + std::string d68000_tst_32(); + std::string d68020_tst_a_32(); + std::string d68020_tst_pcdi_32(); + std::string d68020_tst_pcix_32(); + std::string d68020_tst_i_32(); + std::string d68000_unlk(); + std::string d68020_unpk_rr(); + std::string d68020_unpk_mm(); + std::string d68851_p000(); + std::string d68851_pbcc16(); + std::string d68851_pbcc32(); + std::string d68851_pdbcc(); + std::string d68851_p001(); + std::string d68040_fbcc_16(); + std::string d68040_fbcc_32(); + + static bool valid_ea(u32 opcode, u32 mask); + static bool compare_nof_true_bits(const opcode_struct *aptr, const opcode_struct *bptr); + void build_opcode_table(); + + + /* used by ops like asr, ror, addq, etc */ + static const u32 m_3bit_qdata_table[8]; + static const u32 m_5bit_data_table[32]; + + static const char *const m_cc[16]; + static const char *const m_cpcc[64]; + static const char *const m_mmuregs[8]; + static const char *const m_mmucond[16]; + + static const opcode_struct m_opcode_info[]; + opcode_handler m_instruction_table[0x10000]; + + const data_buffer *m_buffer; + u32 m_cpu_type, m_cpu_pc, m_flags; + u16 m_cpu_ir; +}; + + +#endif diff --git a/src/devices/cpu/m6805/6805dasm.cpp b/src/devices/cpu/m6805/6805dasm.cpp index e8cca5bf4e3..3f6b2fbb14b 100644 --- a/src/devices/cpu/m6805/6805dasm.cpp +++ b/src/devices/cpu/m6805/6805dasm.cpp @@ -5,56 +5,21 @@ * * Note: this is not the good and proper way to disassemble anything, but it works * + * Secondary note: it actually stopped being not nice a while ago + * * I'm afraid to put my name on it, but I feel obligated: * This code written by Aaron Giles (agiles@sirius.com) for the MAME project * */ #include "emu.h" -#include "m6805.h" - -#include "debugger.h" - -namespace { - -enum class md { - INH, // inherent - BTR, // bit test and relative - BIT, // bit set/clear - REL, // relative - IMM, // immediate - DIR, // direct address - EXT, // extended address - IDX, // indexed - IX1, // indexed + byte offset - IX2 // indexed + word offset -}; - -enum class lvl { - HMOS, - CMOS, - HC -}; - -enum class op_names { - adca, adda, anda, asl, asla, aslx, asr, asra, - asrx, bcc, bclr, bcs, beq, bhcc, bhcs, bhi, - bih, bil, bit, bls, bmc, bmi, bms, bne, - bpl, bra, brclr, brn, brset, bset, bsr, clc, - cli, clr, clra, clrx, cmpa, com, coma, comx, - cpx, dec, deca, decx, eora, ill, inc, inca, - incx, jmp, jsr, lda, ldx, lsr, lsra, lsrx, - mul, neg, nega, negx, nop, ora, rol, rola, - rolx, ror, rora, rorx, rsp, rti, rts, sbca, - sec, sei, sta, stop, stx, suba, swi, tax, - tst, tsta, tstx, txa, wait -}; +#include "6805dasm.h" #define OP(name, mode) { op_names::name, #name, md::mode, lvl::HMOS } #define OPC(name, mode) { op_names::name, #name, md::mode, lvl::CMOS } #define OPHC(name, mode) { op_names::name, #name, md::mode, lvl::HC } #define ILLEGAL { op_names::ill, nullptr, md::INH, lvl::HMOS } -struct { op_names op; char const *name; md mode; lvl level; } const disasm[0x100] = { +const m6805_base_disassembler::info m6805_base_disassembler::disasm[0x100] = { OP (brset,BTR), OP (brclr,BTR), OP (brset,BTR), OP (brclr,BTR), // 00 OP (brset,BTR), OP (brclr,BTR), OP (brset,BTR), OP (brclr,BTR), OP (brset,BTR), OP (brclr,BTR), OP (brset,BTR), OP (brclr,BTR), @@ -121,43 +86,35 @@ struct { op_names op; char const *name; md mode; lvl level; } const disasm[0x100 OP (jmp, IDX), OP (jsr, IDX), OP (ldx, IDX), OP (stx, IDX) }; +m6805_base_disassembler::m6805_base_disassembler(lvl level, std::pair<u16, char const *> const symbols[], std::size_t symbol_count) : m_level(level), m_symbols(symbols), m_symbol_count(symbol_count) +{ +} + +u32 m6805_base_disassembler::opcode_alignment() const +{ + return 1; +} -template <typename T> -void format_address( - std::ostream& stream, - T address, - std::pair<u16, char const *> const symbols[], - std::size_t symbol_count) +template <typename T> std::string m6805_base_disassembler::address(T offset) const { - auto const symbol= std::lower_bound( - &symbols[0], - &symbols[symbol_count], - address, - [] (auto const &sym, u16 addr) { return sym.first < addr; }); - if ((symbol_count != (symbol - symbols)) && (symbol->first == address)) - stream << symbol->second; + auto const symbol = std::lower_bound(m_symbols, + m_symbols + m_symbol_count, + offset, + [] (auto const &sym, u16 addr) { return sym.first < addr; }); + if ((m_symbol_count != (symbol - m_symbols)) && (symbol->first == offset)) + return symbol->second; else - util::stream_format(stream, "$%0*X", 2 * sizeof(T), address); + return util::string_format("$%0*X", 2 * sizeof(T), offset); } - -offs_t disassemble( - cpu_device *device, - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const u8 *opram, - int options, - lvl level, - std::pair<u16, char const *> const symbols[], - std::size_t symbol_count) +offs_t m6805_base_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - u8 const code = oprom[0]; + u8 const code = opcodes.r8(pc); - if (!disasm[code].name || (disasm[code].level > level)) + if (!disasm[code].name || (disasm[code].level > m_level)) { util::stream_format(stream, "%-6s$%02X", "fcb", code); - return 1 | DASMFLAG_SUPPORTED; + return 1 | SUPPORTED; } else { @@ -166,11 +123,11 @@ offs_t disassemble( { case op_names::bsr: case op_names::jsr: - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case op_names::rts: case op_names::rti: - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; default: flags = 0; @@ -178,55 +135,46 @@ offs_t disassemble( util::stream_format(stream, "%-6s", disasm[code].name); - int bit; - u16 ea; switch (disasm[code].mode) { case md::INH: // inherent - return 1 | flags | DASMFLAG_SUPPORTED; + return 1 | flags | SUPPORTED; case md::BTR: // bit test and relative branch - bit = (code >> 1) & 7; - util::stream_format(stream, "%d,", bit); - format_address(stream, opram[1], symbols, symbol_count); - util::stream_format(stream, ",$%03X", pc + 3 + s8(opram[2])); - return 3 | flags | DASMFLAG_SUPPORTED; + util::stream_format(stream, "%d, %s, $%03X", (code >> 1) & 7, address(params.r8(pc+1)), pc + 3 + s8(params.r8(pc+2))); + return 3 | flags | SUPPORTED; case md::BIT: // bit test - bit = (code >> 1) & 7; - util::stream_format(stream, "%d,", bit); - format_address(stream, opram[1], symbols, symbol_count); - return 2 | flags | DASMFLAG_SUPPORTED; + util::stream_format(stream, "%d, %s", (code >> 1) & 7, address(params.r8(pc+1))); + return 2 | flags | SUPPORTED; case md::REL: // relative - util::stream_format(stream, "$%03X", pc + 2 + s8(opram[1])); - return 2 | flags | DASMFLAG_SUPPORTED; + util::stream_format(stream, "$%03X", pc + 2 + s8(params.r8(pc+1))); + return 2 | flags | SUPPORTED; case md::IMM: // immediate - util::stream_format(stream, "#$%02X", opram[1]); - return 2 | flags | DASMFLAG_SUPPORTED; + util::stream_format(stream, "#$%02X", params.r8(pc+1)); + return 2 | flags | SUPPORTED; case md::DIR: // direct (zero page address) - format_address(stream, opram[1], symbols, symbol_count); - return 2 | flags | DASMFLAG_SUPPORTED; + util::stream_format(stream, "%s", address(params.r8(pc+1))); + return 2 | flags | SUPPORTED; case md::EXT: // extended (16 bit address) - ea = (opram[1] << 8) + opram[2]; - format_address(stream, ea, symbols, symbol_count); - return 3 | flags | DASMFLAG_SUPPORTED; + util::stream_format(stream, "%s", address(params.r16(pc+1))); + return 3 | flags | SUPPORTED; case md::IDX: // indexed util::stream_format(stream, "(x)"); - return 1 | flags | DASMFLAG_SUPPORTED; + return 1 | flags | SUPPORTED; case md::IX1: // indexed + byte (zero page) - util::stream_format(stream, "(x+$%02X)", opram[1]); - return 2 | flags | DASMFLAG_SUPPORTED; + util::stream_format(stream, "(x+$%02X)", params.r8(pc+1)); + return 2 | flags | SUPPORTED; case md::IX2: // indexed + word (16 bit address) - ea = (opram[1] << 8) + opram[2]; - util::stream_format(stream, "(x+$%04X)", ea); - return 3 | flags | DASMFLAG_SUPPORTED; + util::stream_format(stream, "(x+$%04X)", params.r16(pc+1)); + return 3 | flags | SUPPORTED; } // if we fall off the switch statement something is very wrong @@ -234,48 +182,22 @@ offs_t disassemble( } } -} // anonymous namespace - +m6805_disassembler::m6805_disassembler() : m6805_base_disassembler(lvl::HMOS) +{ +} -offs_t CPU_DISASSEMBLE_NAME(m6805)( - cpu_device *device, - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const u8 *opram, - int options, - std::pair<u16, char const *> const symbols[], - std::size_t symbol_count) +m6805_disassembler::m6805_disassembler(std::pair<u16, char const *> const symbols[], std::size_t symbol_count) : m6805_base_disassembler(lvl::HMOS, symbols, symbol_count) { - return disassemble(device, stream, pc, oprom, opram, options, lvl::HMOS, symbols, symbol_count); } -offs_t CPU_DISASSEMBLE_NAME(m146805)( - cpu_device *device, - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const u8 *opram, - int options, - std::pair<u16, char const *> const symbols[], - std::size_t symbol_count) +m146805_disassembler::m146805_disassembler() : m6805_base_disassembler(lvl::CMOS) { - return disassemble(device, stream, pc, oprom, opram, options, lvl::CMOS, symbols, symbol_count); } -offs_t CPU_DISASSEMBLE_NAME(m68hc05)( - cpu_device *device, - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const u8 *opram, - int options, - std::pair<u16, char const *> const symbols[], - std::size_t symbol_count) +m68hc05_disassembler::m68hc05_disassembler() : m6805_base_disassembler(lvl::HC) { - return disassemble(device, stream, pc, oprom, opram, options, lvl::HC, symbols, symbol_count); } -CPU_DISASSEMBLE(m6805) { return CPU_DISASSEMBLE_NAME(m6805) (device, stream, pc, oprom, opram, options, nullptr, 0); } -CPU_DISASSEMBLE(m146805) { return CPU_DISASSEMBLE_NAME(m146805)(device, stream, pc, oprom, opram, options, nullptr, 0); } -CPU_DISASSEMBLE(m68hc05) { return CPU_DISASSEMBLE_NAME(m68hc05)(device, stream, pc, oprom, opram, options, nullptr, 0); } +m68hc05_disassembler::m68hc05_disassembler(std::pair<u16, char const *> const symbols[], std::size_t symbol_count) : m6805_base_disassembler(lvl::HC, symbols, symbol_count) +{ +} diff --git a/src/devices/cpu/m6805/6805dasm.h b/src/devices/cpu/m6805/6805dasm.h new file mode 100644 index 00000000000..95a03afb61c --- /dev/null +++ b/src/devices/cpu/m6805/6805dasm.h @@ -0,0 +1,100 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert, Aaron Giles, Vas Crabb + +// 6805 disassembler interface + +#ifndef MAME_CPU_M6805_6805DASM_H +#define MAME_CPU_M6805_6805DASM_H + +#pragma once + +class m6805_base_disassembler : public util::disasm_interface +{ +public: + enum class lvl { + HMOS, + CMOS, + HC + }; + + m6805_base_disassembler(lvl level, std::pair<u16, char const *> const symbols[], std::size_t symbol_count); + + m6805_base_disassembler(lvl level) : m6805_base_disassembler(level, nullptr, 0) {} + + virtual ~m6805_base_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum class md { + INH, // inherent + BTR, // bit test and relative + BIT, // bit set/clear + REL, // relative + IMM, // immediate + DIR, // direct address + EXT, // extended address + IDX, // indexed + IX1, // indexed + byte offset + IX2 // indexed + word offset + }; + + enum class op_names { + adca, adda, anda, asl, asla, aslx, asr, asra, + asrx, bcc, bclr, bcs, beq, bhcc, bhcs, bhi, + bih, bil, bit, bls, bmc, bmi, bms, bne, + bpl, bra, brclr, brn, brset, bset, bsr, clc, + cli, clr, clra, clrx, cmpa, com, coma, comx, + cpx, dec, deca, decx, eora, ill, inc, inca, + incx, jmp, jsr, lda, ldx, lsr, lsra, lsrx, + mul, neg, nega, negx, nop, ora, rol, rola, + rolx, ror, rora, rorx, rsp, rti, rts, sbca, + sec, sei, sta, stop, stx, suba, swi, tax, + tst, tsta, tstx, txa, wait + }; + + struct info { + op_names op; + char const *name; + md mode; + lvl level; + }; + + static const info disasm[0x100]; + + lvl m_level; + std::pair<u16, char const *> const *m_symbols; + std::size_t m_symbol_count; + + template <typename T> std::string address(T offset) const; +}; + +class m6805_disassembler : public m6805_base_disassembler +{ +public: + m6805_disassembler(); + m6805_disassembler(std::pair<u16, char const *> const symbols[], std::size_t symbol_count); + template<size_t N> m6805_disassembler(std::pair<u16, char const *> const (&symbols)[N]) : m6805_disassembler(symbols, N) {} + + virtual ~m6805_disassembler() = default; +}; + +class m146805_disassembler : public m6805_base_disassembler +{ +public: + m146805_disassembler(); + virtual ~m146805_disassembler() = default; +}; + +class m68hc05_disassembler : public m6805_base_disassembler +{ +public: + m68hc05_disassembler(); + m68hc05_disassembler(std::pair<u16, char const *> const symbols[], std::size_t symbol_count); + template<size_t N> m68hc05_disassembler(std::pair<u16, char const *> const (&symbols)[N]) : m68hc05_disassembler(symbols, N) {} + virtual ~m68hc05_disassembler() = default; +}; + + +#endif diff --git a/src/devices/cpu/m6805/m6805.cpp b/src/devices/cpu/m6805/m6805.cpp index eb80246e368..0b8a9b42eb1 100644 --- a/src/devices/cpu/m6805/m6805.cpp +++ b/src/devices/cpu/m6805/m6805.cpp @@ -35,6 +35,7 @@ #include "emu.h" #include "m6805.h" #include "m6805defs.h" +#include "6805dasm.h" #include "debugger.h" @@ -262,7 +263,7 @@ m6805_base_device::m6805_base_device( void m6805_base_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); // set our instruction counter m_icountptr = &m_icount; @@ -303,9 +304,6 @@ void m6805_base_device::device_reset() m_nmi_state = 0; - m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); - /* IRQ disabled */ SEI; @@ -409,35 +407,13 @@ void m6805_base_device::interrupt() //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t m6805_base_device::disasm_min_opcode_bytes() const -{ - return 1; -} - - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t m6805_base_device::disasm_max_opcode_bytes() const -{ - return 3; -} - - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t m6805_base_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *m6805_base_device::create_disassembler() { - return CPU_DISASSEMBLE_NAME(m6805)(this, stream, pc, oprom, opram, options); + return new m6805_disassembler; } diff --git a/src/devices/cpu/m6805/m6805.h b/src/devices/cpu/m6805/m6805.h index fb8fc97dee3..643b1617991 100644 --- a/src/devices/cpu/m6805/m6805.h +++ b/src/devices/cpu/m6805/m6805.h @@ -119,9 +119,7 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // device_state_interface overrides virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; @@ -279,7 +277,7 @@ protected: // address spaces address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; }; @@ -362,8 +360,4 @@ protected: #define HD63705_INT_ADCONV 0x07 #define HD63705_INT_NMI 0x08 -CPU_DISASSEMBLE( m6805 ); -CPU_DISASSEMBLE( m146805 ); -CPU_DISASSEMBLE( m68hc05 ); - #endif // MAME_CPU_M6805_M6805_H diff --git a/src/devices/cpu/m6805/m6805defs.h b/src/devices/cpu/m6805/m6805defs.h index 670beda2683..1e5d8c6e7fb 100644 --- a/src/devices/cpu/m6805/m6805defs.h +++ b/src/devices/cpu/m6805/m6805defs.h @@ -116,73 +116,4 @@ inline void m6805_base_device::skipbyte() { rdop_arg(PC++); } /* Macros for branch instructions */ #define BRANCH(f) do { u8 t; immbyte(t); if (bool(f) == bool(C)) PC += SIGNED(t); } while (false) -offs_t CPU_DISASSEMBLE_NAME(m146805)( - cpu_device *device, - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const u8 *opram, - int options, - std::pair<u16, char const *> const symbols[], - std::size_t symbol_count); - -offs_t CPU_DISASSEMBLE_NAME(m68hc05)( - cpu_device *device, - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const u8 *opram, - int options, - std::pair<u16, char const *> const symbols[], - std::size_t symbol_count); - -offs_t CPU_DISASSEMBLE_NAME(m6805)( - cpu_device *device, - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const u8 *opram, - int options, - std::pair<u16, char const *> const symbols[], - std::size_t symbol_count); - -template <size_t N> -inline offs_t CPU_DISASSEMBLE_NAME(m6805)( - cpu_device *device, - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const u8 *opram, - int options, - std::pair<u16, char const *> const (&symbols)[N]) -{ - return CPU_DISASSEMBLE_NAME(m6805)(device, stream, pc, oprom, opram, options, symbols, N); -} - -template <size_t N> -inline offs_t CPU_DISASSEMBLE_NAME(m146805)( - cpu_device *device, - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const u8 *opram, - int options, - std::pair<u16, char const *> const (&symbols)[N]) -{ - return CPU_DISASSEMBLE_NAME(m146805)(device, stream, pc, oprom, opram, options, symbols, N); -} - -template <size_t N> -inline offs_t CPU_DISASSEMBLE_NAME(m68hc05)( - cpu_device *device, - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const u8 *opram, - int options, - std::pair<u16, char const *> const (&symbols)[N]) -{ - return CPU_DISASSEMBLE_NAME(m68hc05)(device, stream, pc, oprom, opram, options, symbols, N); -} - #endif // MAME_CPU_M6805_M6805DEFS_H diff --git a/src/devices/cpu/m6805/m68705.cpp b/src/devices/cpu/m6805/m68705.cpp index ba4dae3a39f..08e40e41d9a 100644 --- a/src/devices/cpu/m6805/m68705.cpp +++ b/src/devices/cpu/m6805/m68705.cpp @@ -3,6 +3,7 @@ #include "emu.h" #include "m68705.h" #include "m6805defs.h" +#include "6805dasm.h" /**************************************************************************** * Configurable logging @@ -697,14 +698,9 @@ void m68705p_device::device_start() state_add(M68705_MOR, "MOR", get_user_rom()[0x0784]).mask(0xff); } -offs_t m68705p_device::disasm_disassemble( - std::ostream &stream, - offs_t pc, - const uint8_t *oprom, - const uint8_t *opram, - uint32_t options) +util::disasm_interface *m68705p_device::create_disassembler() { - return CPU_DISASSEMBLE_NAME(m6805)(this, stream, pc, oprom, opram, options, m68705p_syms); + return new m6805_disassembler(m68705p_syms); } @@ -776,14 +772,9 @@ void m68705u_device::device_start() // TODO: MISC register } -offs_t m68705u_device::disasm_disassemble( - std::ostream &stream, - offs_t pc, - const uint8_t *oprom, - const uint8_t *opram, - uint32_t options) +util::disasm_interface *m68705u_device::create_disassembler() { - return CPU_DISASSEMBLE_NAME(m6805)(this, stream, pc, oprom, opram, options, m68705u_syms); + return new m6805_disassembler(m68705u_syms); } @@ -834,17 +825,11 @@ void m68705r_device::device_start() // TODO: ADC } -offs_t m68705r_device::disasm_disassemble( - std::ostream &stream, - offs_t pc, - const uint8_t *oprom, - const uint8_t *opram, - uint32_t options) +util::disasm_interface *m68705r_device::create_disassembler() { - return CPU_DISASSEMBLE_NAME(m6805)(this, stream, pc, oprom, opram, options, m68705r_syms); + return new m6805_disassembler(m68705r_syms); } - /**************************************************************************** * M68705P3 device ****************************************************************************/ diff --git a/src/devices/cpu/m6805/m68705.h b/src/devices/cpu/m6805/m68705.h index aaa2f88d693..08701917b47 100644 --- a/src/devices/cpu/m6805/m68705.h +++ b/src/devices/cpu/m6805/m68705.h @@ -202,12 +202,7 @@ protected: virtual void device_start() override; - virtual offs_t disasm_disassemble( - std::ostream &stream, - offs_t pc, - const uint8_t *oprom, - const uint8_t *opram, - uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; }; @@ -240,12 +235,7 @@ protected: virtual void device_start() override; - virtual offs_t disasm_disassemble( - std::ostream &stream, - offs_t pc, - const uint8_t *oprom, - const uint8_t *opram, - uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; }; @@ -268,12 +258,7 @@ protected: virtual void device_start() override; - virtual offs_t disasm_disassemble( - std::ostream &stream, - offs_t pc, - const uint8_t *oprom, - const uint8_t *opram, - uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; }; diff --git a/src/devices/cpu/m6805/m68hc05.cpp b/src/devices/cpu/m6805/m68hc05.cpp index 90575e98ab2..24580270a9c 100644 --- a/src/devices/cpu/m6805/m68hc05.cpp +++ b/src/devices/cpu/m6805/m68hc05.cpp @@ -18,6 +18,7 @@ certain value. #include "emu.h" #include "m68hc05.h" #include "m6805defs.h" +#include "6805dasm.h" /**************************************************************************** @@ -541,15 +542,9 @@ u64 m68hc05_device::execute_cycles_to_clocks(u64 cycles) const return cycles * 2; } - -offs_t m68hc05_device::disasm_disassemble( - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const u8 *opram, - u32 options) +util::disasm_interface *m68hc05_device::create_disassembler() { - return CPU_DISASSEMBLE_NAME(m68hc05)(this, stream, pc, oprom, opram, options); + return new m68hc05_disassembler; } @@ -777,14 +772,9 @@ void m68hc05c4_device::device_start() } -offs_t m68hc05c4_device::disasm_disassemble( - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const u8 *opram, - u32 options) +util::disasm_interface *m68hc05c4_device::create_disassembler() { - return CPU_DISASSEMBLE_NAME(m68hc05)(this, stream, pc, oprom, opram, options, m68hc05c4_syms); + return new m68hc05_disassembler(m68hc05c4_syms); } @@ -845,15 +835,10 @@ void m68hc05c8_device::device_start() } -offs_t m68hc05c8_device::disasm_disassemble( - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const u8 *opram, - u32 options) +util::disasm_interface *m68hc05c8_device::create_disassembler() { // same I/O registers as MC68HC05C4 - return CPU_DISASSEMBLE_NAME(m68hc05)(this, stream, pc, oprom, opram, options, m68hc05c4_syms); + return new m68hc05_disassembler(m68hc05c4_syms); } @@ -937,12 +922,7 @@ void m68hc705c8a_device::device_reset() } -offs_t m68hc705c8a_device::disasm_disassemble( - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const u8 *opram, - u32 options) +util::disasm_interface *m68hc705c8a_device::create_disassembler() { - return CPU_DISASSEMBLE_NAME(m68hc05)(this, stream, pc, oprom, opram, options, m68hc705c8a_syms); + return new m68hc05_disassembler(m68hc705c8a_syms); } diff --git a/src/devices/cpu/m6805/m68hc05.h b/src/devices/cpu/m6805/m68hc05.h index db61afc8b60..355a675d803 100644 --- a/src/devices/cpu/m6805/m68hc05.h +++ b/src/devices/cpu/m6805/m68hc05.h @@ -138,12 +138,7 @@ protected: virtual u64 execute_clocks_to_cycles(u64 clocks) const override; virtual u64 execute_cycles_to_clocks(u64 cycles) const override; - virtual offs_t disasm_disassemble( - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const uint8_t *opram, - u32 options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void interrupt() override; virtual bool test_il() override; @@ -229,12 +224,7 @@ protected: virtual void device_start() override; - virtual offs_t disasm_disassemble( - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const u8 *opram, - u32 options) override; + virtual util::disasm_interface *create_disassembler() override; }; @@ -250,12 +240,7 @@ protected: virtual void device_start() override; - virtual offs_t disasm_disassemble( - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const u8 *opram, - u32 options) override; + virtual util::disasm_interface *create_disassembler() override; }; @@ -274,12 +259,7 @@ protected: virtual void device_start() override; virtual void device_reset() override; - virtual offs_t disasm_disassemble( - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const u8 *opram, - u32 options) override; + virtual util::disasm_interface *create_disassembler() override; }; diff --git a/src/devices/cpu/m6809/6x09dasm.cpp b/src/devices/cpu/m6809/6x09dasm.cpp index 1b07fb3c92b..3df936df070 100644 --- a/src/devices/cpu/m6809/6x09dasm.cpp +++ b/src/devices/cpu/m6809/6x09dasm.cpp @@ -27,118 +27,41 @@ *****************************************************************************/ #include "emu.h" -#include "debugger.h" +#include "6x09dasm.h" -enum m6x09_addressing_mode -{ - INH, // Inherent - PSHS, PSHU, // Push - PULS, PULU, // Pull - DIR, // Direct - DIR_IM, // Direct in memory (6309 only) - IND, // Indexed - REL, // Relative (8 bit) - LREL, // Long relative (16 bit) - EXT, // Extended - IMM, // Immediate - IMM_RR, // Register-to-register - IMM_BW, // Bitwise operations (6309 only) - IMM_TFM, // Transfer from memory (6309 only) - PG1, // Switch to page 1 opcodes - PG2 // Switch to page 2 opcodes -}; -// General, or 6309 only? -enum m6x09_instruction_level -{ - M6x09_GENERAL, - HD6309_EXCLUSIVE -}; +const char *const m6x09_base_disassembler::m6x09_regs[5] = { "X", "Y", "U", "S", "PC" }; -// Opcode structure -class opcodeinfo -{ -public: - constexpr opcodeinfo(uint16_t opcode, uint8_t length, const char *name, m6x09_addressing_mode mode, m6x09_instruction_level level, unsigned flags = 0) - : m_opcode(opcode), m_length(length), m_mode(mode), m_level(level), m_flags(flags), m_name(name) - { - } +const char *const m6x09_base_disassembler::m6x09_btwregs[5] = { "CC", "A", "B", "inv" }; - uint16_t opcode() const { return m_opcode; } - uint8_t length() const { return m_length; } - m6x09_addressing_mode mode() const { return m_mode; } - m6x09_instruction_level level() const { return m_level; } - unsigned flags() const { return m_flags; } - const char *name() const { return m_name; } - -private: - uint16_t m_opcode; // 8-bit opcode value - uint8_t m_length; // Opcode length in bytes - m6x09_addressing_mode m_mode : 6; // Addressing mode - m6x09_instruction_level m_level : 2; // General, or 6309 only? - unsigned m_flags; // Disassembly flags - const char * m_name; // Opcode name -}; -static const char *const m6x09_regs[5] = { "X", "Y", "U", "S", "PC" }; - -static const char *const m6x09_btwregs[5] = { "CC", "A", "B", "inv" }; - -static const char *const hd6309_tfmregs[16] = { - "D", "X", "Y", "U", "S", "inv", "inv", "inv", +const char *const m6x09_base_disassembler::hd6309_tfmregs[16] = { + "D", "X", "Y", "U", "S", "inv", "inv", "inv", "inv", "inv", "inv", "inv", "inv", "inv", "inv", "inv" }; -static const char *const tfm_s[] = { "%s+,%s+", "%s-,%s-", "%s+,%s", "%s,%s+" }; +const char *const m6x09_base_disassembler::tfm_s[] = { "%s+,%s+", "%s-,%s-", "%s+,%s", "%s,%s+" }; //************************************************************************** // BASE CLASS //************************************************************************** -// ======================> m6x09_disassembler_base - -// base class for M6809/HD6309/Konami disassemblers -namespace +u32 m6x09_base_disassembler::opcode_alignment() const { - class m6x09_disassembler_base - { - public: - m6x09_disassembler_base(const opcodeinfo *opcodes, size_t opcode_count, m6x09_instruction_level level) - : m_opcodes(opcodes, opcode_count), m_level(level) - { - } - - offs_t disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram); - - protected: - virtual void indirect(std::ostream &stream, uint8_t pb, const uint8_t *opram, int &p) = 0; - virtual void register_register(std::ostream &stream, uint8_t pb) = 0; - - private: - util::contiguous_sequence_wrapper<const opcodeinfo> m_opcodes; - m6x09_instruction_level m_level; - - const opcodeinfo *fetch_opcode(const uint8_t *oprom, int &p); - - void assert_hd6309_exclusive() - { - if (m_level < HD6309_EXCLUSIVE) - throw false; - } - }; + return 1; } //------------------------------------------------- // fetch_opcode //------------------------------------------------- -const opcodeinfo *m6x09_disassembler_base::fetch_opcode(const uint8_t *oprom, int &p) +const m6x09_base_disassembler::opcodeinfo *m6x09_base_disassembler::fetch_opcode(const data_buffer &opcodes, offs_t &p) { uint16_t page = 0; const opcodeinfo *op = nullptr; while(!op) { // retrieve the opcode - uint16_t opcode = page | oprom[p++]; + uint16_t opcode = page | opcodes.r8(p++); // perform the lookup auto iter = std::find_if( @@ -179,29 +102,28 @@ const opcodeinfo *m6x09_disassembler_base::fetch_opcode(const uint8_t *oprom, in // disassemble - core of the disassembler //------------------------------------------------- -offs_t m6x09_disassembler_base::disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram) +offs_t m6x09_base_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint8_t pb; unsigned int ea; int offset; - int p = 0; + offs_t p = pc; // look up the opcode - const opcodeinfo *op = fetch_opcode(oprom, p); + const opcodeinfo *op = fetch_opcode(opcodes, p); if (!op) { stream << "Illegal Opcode"; - return p | DASMFLAG_SUPPORTED; + return (p - pc) | SUPPORTED; } // how many operands do we have? - int numoperands = (p == 1) + int numoperands = (p - pc == 1) ? op->length() - 1 : op->length() - 2; - const uint8_t *operandarray = &opram[p]; + offs_t ppc = p; p += numoperands; - pc += p; // output the base instruction name util::stream_format(stream, "%-6s", op->name()); @@ -214,7 +136,7 @@ offs_t m6x09_disassembler_base::disassemble(std::ostream &stream, offs_t pc, con case PSHS: case PSHU: - pb = operandarray[0]; + pb = params.r8(ppc); if (pb & 0x80) util::stream_format(stream, "PC"); if (pb & 0x40) @@ -235,7 +157,7 @@ offs_t m6x09_disassembler_base::disassemble(std::ostream &stream, offs_t pc, con case PULS: case PULU: - pb = operandarray[0]; + pb = params.r8(ppc); if (pb & 0x01) util::stream_format(stream, "CC"); if (pb & 0x02) @@ -255,23 +177,23 @@ offs_t m6x09_disassembler_base::disassemble(std::ostream &stream, offs_t pc, con break; case DIR: - ea = operandarray[0]; + ea = params.r8(ppc); util::stream_format(stream, "$%02X", ea); break; case DIR_IM: assert_hd6309_exclusive(); - util::stream_format(stream, "#$%02X;", operandarray[0]); - util::stream_format(stream, "$%02X", operandarray[1]); + util::stream_format(stream, "#$%02X;", params.r8(ppc)); + util::stream_format(stream, "$%02X", params.r8(ppc + 1)); break; case REL: - offset = (int8_t)operandarray[0]; + offset = (int8_t)params.r8(ppc); util::stream_format(stream, "$%04X", (pc + offset) & 0xffff); break; case LREL: - offset = (int16_t)((operandarray[0] << 8) + operandarray[1]); + offset = (int16_t)params.r16(ppc); util::stream_format(stream, "$%04X", (pc + offset) & 0xffff); break; @@ -279,13 +201,13 @@ offs_t m6x09_disassembler_base::disassemble(std::ostream &stream, offs_t pc, con if (numoperands == 3) { assert_hd6309_exclusive(); - pb = operandarray[0]; - ea = (operandarray[1] << 8) + operandarray[2]; + pb = params.r8(ppc); + ea = params.r16(ppc+1); util::stream_format(stream, "#$%02X,$%04X", pb, ea); } else if (numoperands == 2) { - ea = (operandarray[0] << 8) + operandarray[1]; + ea = params.r16(ppc); util::stream_format(stream, "$%04X", ea); } break; @@ -294,52 +216,52 @@ offs_t m6x09_disassembler_base::disassemble(std::ostream &stream, offs_t pc, con if (numoperands == 2) { assert_hd6309_exclusive(); - util::stream_format(stream, "#$%02X;", operandarray[0]); - pb = operandarray[1]; + util::stream_format(stream, "#$%02X;", params.r8(ppc)); + pb = params.r8(ppc+1); } else { - pb = operandarray[0]; + pb = params.r8(ppc); } - indirect(stream, pb, opram, p); + indirect(stream, pb, params, p); break; case IMM: if (numoperands == 4) { - ea = (operandarray[0] << 24) + (operandarray[1] << 16) + (operandarray[2] << 8) + operandarray[3]; + ea = params.r32(ppc); util::stream_format(stream, "#$%08X", ea); } else if (numoperands == 2) { - ea = (operandarray[0] << 8) + operandarray[1]; + ea = params.r16(ppc); util::stream_format(stream, "#$%04X", ea); } else if (numoperands == 1) { - ea = operandarray[0]; + ea = params.r8(ppc); util::stream_format(stream, "#$%02X", ea); } break; case IMM_RR: - pb = operandarray[0]; + pb = params.r8(ppc); register_register(stream, pb); break; case IMM_BW: - pb = operandarray[0]; + pb = params.r8(ppc); util::stream_format(stream, "%s,", m6x09_btwregs[((pb & 0xc0) >> 6)]); util::stream_format(stream, "%d,", (pb & 0x38) >> 3); util::stream_format(stream, "%d,", (pb & 0x07)); - util::stream_format(stream, "$%02X", operandarray[1]); + util::stream_format(stream, "$%02X", params.r8(ppc+1)); break; case IMM_TFM: - pb = operandarray[0]; + pb = params.r8(ppc); util::stream_format(stream, tfm_s[op->opcode() & 0x07], hd6309_tfmregs[(pb >> 4) & 0xf], hd6309_tfmregs[pb & 0xf]); break; @@ -347,7 +269,7 @@ offs_t m6x09_disassembler_base::disassemble(std::ostream &stream, offs_t pc, con throw false; } - return p | op->flags() | DASMFLAG_SUPPORTED; + return (p - pc) | op->flags() | SUPPORTED; } @@ -355,7 +277,7 @@ offs_t m6x09_disassembler_base::disassemble(std::ostream &stream, offs_t pc, con // M6809/HD6309 disassembler //************************************************************************** -static const opcodeinfo m6x09_opcodes[] = +const m6x09_base_disassembler::opcodeinfo m6x09_disassembler::m6x09_opcodes[] = { // Page 0 opcodes (single byte) { 0x00, 2, "NEG", DIR, M6x09_GENERAL }, @@ -381,7 +303,7 @@ static const opcodeinfo m6x09_opcodes[] = { 0x13, 1, "SYNC", INH, M6x09_GENERAL }, { 0x14, 1, "SEXW", INH, HD6309_EXCLUSIVE }, { 0x16, 3, "LBRA", LREL, M6x09_GENERAL }, - { 0x17, 3, "LBSR", LREL, M6x09_GENERAL, DASMFLAG_STEP_OVER }, + { 0x17, 3, "LBSR", LREL, M6x09_GENERAL, STEP_OVER }, { 0x19, 1, "DAA", INH, M6x09_GENERAL }, { 0x1A, 2, "ORCC", IMM, M6x09_GENERAL }, { 0x1C, 2, "ANDCC", IMM, M6x09_GENERAL }, @@ -491,7 +413,7 @@ static const opcodeinfo m6x09_opcodes[] = { 0x8A, 2, "ORA", IMM, M6x09_GENERAL }, { 0x8B, 2, "ADDA", IMM, M6x09_GENERAL }, { 0x8C, 3, "CMPX", IMM, M6x09_GENERAL }, - { 0x8D, 2, "BSR", REL, M6x09_GENERAL, DASMFLAG_STEP_OVER }, + { 0x8D, 2, "BSR", REL, M6x09_GENERAL, STEP_OVER }, { 0x8E, 3, "LDX", IMM, M6x09_GENERAL }, { 0x90, 2, "SUBA", DIR, M6x09_GENERAL }, @@ -507,7 +429,7 @@ static const opcodeinfo m6x09_opcodes[] = { 0x9A, 2, "ORA", DIR, M6x09_GENERAL }, { 0x9B, 2, "ADDA", DIR, M6x09_GENERAL }, { 0x9C, 2, "CMPX", DIR, M6x09_GENERAL }, - { 0x9D, 2, "JSR", DIR, M6x09_GENERAL, DASMFLAG_STEP_OVER }, + { 0x9D, 2, "JSR", DIR, M6x09_GENERAL, STEP_OVER }, { 0x9E, 2, "LDX", DIR, M6x09_GENERAL }, { 0x9F, 2, "STX", DIR, M6x09_GENERAL }, @@ -524,7 +446,7 @@ static const opcodeinfo m6x09_opcodes[] = { 0xAA, 2, "ORA", IND, M6x09_GENERAL }, { 0xAB, 2, "ADDA", IND, M6x09_GENERAL }, { 0xAC, 2, "CMPX", IND, M6x09_GENERAL }, - { 0xAD, 2, "JSR", IND, M6x09_GENERAL, DASMFLAG_STEP_OVER }, + { 0xAD, 2, "JSR", IND, M6x09_GENERAL, STEP_OVER }, { 0xAE, 2, "LDX", IND, M6x09_GENERAL }, { 0xAF, 2, "STX", IND, M6x09_GENERAL }, @@ -541,7 +463,7 @@ static const opcodeinfo m6x09_opcodes[] = { 0xBA, 3, "ORA", EXT, M6x09_GENERAL }, { 0xBB, 3, "ADDA", EXT, M6x09_GENERAL }, { 0xBC, 3, "CMPX", EXT, M6x09_GENERAL }, - { 0xBD, 3, "JSR", EXT, M6x09_GENERAL, DASMFLAG_STEP_OVER }, + { 0xBD, 3, "JSR", EXT, M6x09_GENERAL, STEP_OVER }, { 0xBE, 3, "LDX", EXT, M6x09_GENERAL }, { 0xBF, 3, "STX", EXT, M6x09_GENERAL }, @@ -875,33 +797,17 @@ static const opcodeinfo m6x09_opcodes[] = // ======================> m6x09_disassembler -// M6809/HD6309 disassembler -namespace +m6x09_disassembler::m6x09_disassembler(m6x09_instruction_level level, const char teregs[16][4]) + : m6x09_base_disassembler(m6x09_opcodes, ARRAY_LENGTH(m6x09_opcodes), level) + , m_teregs(*reinterpret_cast<const std::array<std::array<char, 4>, 16> *>(teregs)) { - class m6x09_disassembler : public m6x09_disassembler_base - { - public: - m6x09_disassembler(m6x09_instruction_level level, const char teregs[16][4]) - : m6x09_disassembler_base(m6x09_opcodes, ARRAY_LENGTH(m6x09_opcodes), level) - , m_teregs(*reinterpret_cast<const std::array<std::array<char, 4>, 16> *>(teregs)) - { - } - - protected: - virtual void indirect(std::ostream &stream, uint8_t pb, const uint8_t *opram, int &p) override; - virtual void register_register(std::ostream &stream, uint8_t pb) override; - - private: - const std::array<std::array<char, 4>, 16> &m_teregs; - }; -}; - +} //------------------------------------------------- // indirect addressing mode for M6809/HD6309 //------------------------------------------------- -void m6x09_disassembler::indirect(std::ostream &stream, uint8_t pb, const uint8_t *opram, int &p) +void m6x09_disassembler::indirect(std::ostream &stream, uint8_t pb, const data_buffer ¶ms, offs_t &p) { uint8_t reg = (pb >> 5) & 3; uint8_t pbm = pb & 0x8f; @@ -924,7 +830,7 @@ void m6x09_disassembler::indirect(std::ostream &stream, uint8_t pb, const uint8_ util::stream_format(stream, ",W"); break; case 0x01: - offset = (int16_t)((opram[p + 0] << 8) + opram[p + 1]); + offset = (int16_t)params.r16(p); p += 2; util::stream_format(stream, "%s", (offset < 0) ? "-" : ""); util::stream_format(stream, "$%04X,W", (offset < 0) ? -offset : offset); @@ -973,14 +879,14 @@ void m6x09_disassembler::indirect(std::ostream &stream, uint8_t pb, const uint8_ break; case 0x88: // (+/- 7 bit offset),R - offset = (int8_t)opram[p++]; + offset = (int8_t)params.r8(p++); util::stream_format(stream, "%s", (offset < 0) ? "-" : ""); util::stream_format(stream, "$%02X,", (offset < 0) ? -offset : offset); util::stream_format(stream, "%s", m6x09_regs[reg]); break; case 0x89: // (+/- 15 bit offset),R - offset = (int16_t)((opram[p + 0] << 8) + opram[p + 1]); + offset = (int16_t)params.r16(p); p += 2; util::stream_format(stream, "%s", (offset < 0) ? "-" : ""); util::stream_format(stream, "$%04X,", (offset < 0) ? -offset : offset); @@ -996,13 +902,13 @@ void m6x09_disassembler::indirect(std::ostream &stream, uint8_t pb, const uint8_ break; case 0x8c: // (+/- 7 bit offset),PC - offset = (int8_t)opram[p++]; + offset = (int8_t)params.r8(p); util::stream_format(stream, "%s", (offset < 0) ? "-" : ""); util::stream_format(stream, "$%02X,PC", (offset < 0) ? -offset : offset); break; case 0x8d: // (+/- 15 bit offset),PC - offset = (int16_t)((opram[p + 0] << 8) + opram[p + 1]); + offset = (int16_t)params.r16(p); p += 2; util::stream_format(stream, "%s", (offset < 0) ? "-" : ""); util::stream_format(stream, "$%04X,PC", (offset < 0) ? -offset : offset); @@ -1015,7 +921,7 @@ void m6x09_disassembler::indirect(std::ostream &stream, uint8_t pb, const uint8_ case 0x8f: // address or operations relative to W if (indirect) { - ea = (uint16_t)((opram[p + 0] << 8) + opram[p + 1]); + ea = (uint16_t)params.r16(p); p += 2; util::stream_format(stream, "$%04X", ea); break; @@ -1028,7 +934,7 @@ void m6x09_disassembler::indirect(std::ostream &stream, uint8_t pb, const uint8_ util::stream_format(stream, ",W"); break; case 0x01: - offset = (int16_t)((opram[p + 0] << 8) + opram[p + 1]); + offset = (int16_t)params.r16(p); p += 2; util::stream_format(stream, "%s", (offset < 0) ? "-" : ""); util::stream_format(stream, "$%04X,W", (offset < 0) ? -offset : offset); @@ -1075,15 +981,15 @@ void m6x09_disassembler::register_register(std::ostream &stream, uint8_t pb) // M6809 disassembler entry point //------------------------------------------------- -CPU_DISASSEMBLE(m6809) +const char m6809_disassembler::m6809_teregs[16][4] = +{ + "D", "X", "Y", "U", "S", "PC", "inv", "inv", + "A", "B", "CC", "DP", "inv", "inv", "inv", "inv" +}; + + +m6809_disassembler::m6809_disassembler() : m6x09_disassembler(M6x09_GENERAL, m6809_teregs) { - static const char m6809_teregs[16][4] = - { - "D", "X", "Y", "U", "S", "PC", "inv", "inv", - "A", "B", "CC", "DP", "inv", "inv", "inv", "inv" - }; - m6x09_disassembler disasm(M6x09_GENERAL, m6809_teregs); - return disasm.disassemble(stream, pc, oprom, opram); } @@ -1091,15 +997,14 @@ CPU_DISASSEMBLE(m6809) // HD6309 disassembler entry point //------------------------------------------------- -CPU_DISASSEMBLE(hd6309) +const char hd6309_disassembler::hd6309_teregs[16][4] = +{ + "D", "X", "Y", "U", "S", "PC", "W", "V", + "A", "B", "CC", "DP", "0", "0", "E", "F" +}; + +hd6309_disassembler::hd6309_disassembler() : m6x09_disassembler(HD6309_EXCLUSIVE, hd6309_teregs) { - static const char hd6309_teregs[16][4] = - { - "D", "X", "Y", "U", "S", "PC", "W", "V", - "A", "B", "CC", "DP", "0", "0", "E", "F" - }; - m6x09_disassembler disasm(HD6309_EXCLUSIVE, hd6309_teregs); - return disasm.disassemble(stream, pc, oprom, opram); } @@ -1107,7 +1012,7 @@ CPU_DISASSEMBLE(hd6309) // Konami disassembler //************************************************************************** -static const opcodeinfo konami_opcodes[] = +const m6x09_base_disassembler::opcodeinfo konami_disassembler::konami_opcodes[] = { { 0x08, 2, "LEAX", IND, M6x09_GENERAL }, { 0x09, 2, "LEAY", IND, M6x09_GENERAL }, @@ -1277,9 +1182,9 @@ static const opcodeinfo konami_opcodes[] = { 0xA6, 2, "ASLW", IND, M6x09_GENERAL }, { 0xA7, 2, "ROLW", IND, M6x09_GENERAL }, { 0xA8, 2, "JMP", IND, M6x09_GENERAL }, - { 0xA9, 2, "JSR", IND, M6x09_GENERAL, DASMFLAG_STEP_OVER }, - { 0xAA, 2, "BSR", REL, M6x09_GENERAL, DASMFLAG_STEP_OVER }, - { 0xAB, 3, "LBSR", LREL, M6x09_GENERAL, DASMFLAG_STEP_OVER }, + { 0xA9, 2, "JSR", IND, M6x09_GENERAL, STEP_OVER }, + { 0xAA, 2, "BSR", REL, M6x09_GENERAL, STEP_OVER }, + { 0xAB, 3, "LBSR", LREL, M6x09_GENERAL, STEP_OVER }, { 0xAC, 2, "DECB,JNZ", REL, M6x09_GENERAL }, { 0xAD, 2, "DECX,JNZ", REL, M6x09_GENERAL }, { 0xAE, 1, "NOP", INH, M6x09_GENERAL }, @@ -1324,27 +1229,15 @@ static const opcodeinfo konami_opcodes[] = // ======================> konami_disassembler -namespace +konami_disassembler::konami_disassembler() : m6x09_base_disassembler(konami_opcodes, ARRAY_LENGTH(konami_opcodes), M6x09_GENERAL) { - // Konami disassembler - class konami_disassembler : public m6x09_disassembler_base - { - public: - konami_disassembler() - : m6x09_disassembler_base(konami_opcodes, ARRAY_LENGTH(konami_opcodes), M6x09_GENERAL) { } - - protected: - virtual void indirect(std::ostream &stream, uint8_t pb, const uint8_t *opram, int &p) override; - virtual void register_register(std::ostream &stream, uint8_t pb) override; - }; -}; - +} //------------------------------------------------- // indirect addressing mode for Konami //------------------------------------------------- -void konami_disassembler::indirect(std::ostream &stream, uint8_t mode, const uint8_t *opram, int &p) +void konami_disassembler::indirect(std::ostream &stream, uint8_t mode, const data_buffer ¶ms, offs_t &p) { static const char index_reg[8][3] = { @@ -1379,7 +1272,7 @@ void konami_disassembler::indirect(std::ostream &stream, uint8_t mode, const uin break; case 0x04: /* direct - mode */ - util::stream_format(stream, "[$%02x]", opram[p++]); + util::stream_format(stream, "[$%02x]", params.r8(p++)); break; case 0x07: /* register d */ @@ -1404,7 +1297,7 @@ void konami_disassembler::indirect(std::ostream &stream, uint8_t mode, const uin break; case 0x04: /* direct - mode */ - util::stream_format(stream, "$%02x", opram[p++]); + util::stream_format(stream, "$%02x", params.r8(p++)); break; case 0x07: /* register d */ @@ -1441,7 +1334,7 @@ void konami_disassembler::indirect(std::ostream &stream, uint8_t mode, const uin break; case 4: // post byte offset - val = opram[p++]; + val = params.r8(p++); if (val & 0x80) util::stream_format(stream, "[#$-%02x,%s]", 0x100 - val, index_reg[idx]); @@ -1450,8 +1343,8 @@ void konami_disassembler::indirect(std::ostream &stream, uint8_t mode, const uin break; case 5: // post word offset - val = opram[p++] << 8; - val |= opram[p++]; + val = params.r16(p); + p += 2; if (val & 0x8000) util::stream_format(stream, "[#$-%04x,%s]", 0x10000 - val, index_reg[idx]); @@ -1464,8 +1357,8 @@ void konami_disassembler::indirect(std::ostream &stream, uint8_t mode, const uin break; case 7: // extended - val = opram[p++] << 8; - val |= opram[p++]; + val = params.r16(p); + p += 2; util::stream_format(stream, "[$%04x]", val); break; @@ -1492,7 +1385,7 @@ void konami_disassembler::indirect(std::ostream &stream, uint8_t mode, const uin break; case 4: // post byte offset - val = opram[p++]; + val = params.r8(p++); if (val & 0x80) util::stream_format(stream, "#$-%02x,%s", 0x100 - val, index_reg[idx]); @@ -1501,8 +1394,8 @@ void konami_disassembler::indirect(std::ostream &stream, uint8_t mode, const uin break; case 5: // post word offset - val = opram[p++] << 8; - val |= opram[p++]; + val = params.r16(p); + p += 2; if (val & 0x8000) util::stream_format(stream, "#$-%04x,%s", 0x10000 - val, index_reg[idx]); @@ -1515,8 +1408,8 @@ void konami_disassembler::indirect(std::ostream &stream, uint8_t mode, const uin break; case 7: // extended - val = opram[p++] << 8; - val |= opram[p++]; + val = params.r16(p); + p += 2; util::stream_format(stream, "$%04x", val); break; @@ -1540,14 +1433,3 @@ void konami_disassembler::register_register(std::ostream &stream, uint8_t pb) konami_teregs[(pb >> 0) & 0x7], konami_teregs[(pb >> 4) & 0x7]); } - - -//------------------------------------------------- -// Konami disassembler entry point -//------------------------------------------------- - -CPU_DISASSEMBLE(konami) -{ - konami_disassembler disasm; - return disasm.disassemble(stream, pc, oprom, opram); -} diff --git a/src/devices/cpu/m6809/6x09dasm.h b/src/devices/cpu/m6809/6x09dasm.h new file mode 100644 index 00000000000..4a230799801 --- /dev/null +++ b/src/devices/cpu/m6809/6x09dasm.h @@ -0,0 +1,166 @@ +// license:BSD-3-Clause +// copyright-holders:Nathan Woods,Sean Riddle,Tim Lindner +/***************************************************************************** + + 6x09dasm.cpp - a 6809/6309/Konami opcode disassembler + + Based on: + 6309dasm.c - a 6309 opcode disassembler + Version 1.0 5-AUG-2000 + Copyright Tim Lindner + + and + + 6809dasm.c - a 6809 opcode disassembler + Version 1.4 1-MAR-95 + Copyright Sean Riddle + + Thanks to Franklin Bowen for bug fixes, ideas + + Freely distributable on any medium given all copyrights are retained + by the author and no charge greater than $7.00 is made for obtaining + this software + + Please send all bug reports, update ideas and data files to: + sriddle@ionet.net and tlindner@ix.netcom.com + +*****************************************************************************/ + +#ifndef MAME_CPU_M6809_6X09DASM_H +#define MAME_CPU_M6809_6X09DASM_H + +#pragma once + +class m6x09_base_disassembler : public util::disasm_interface +{ +protected: + class opcodeinfo; + +public: + // General, or 6309 only? + enum m6x09_instruction_level + { + M6x09_GENERAL, + HD6309_EXCLUSIVE + }; + + m6x09_base_disassembler(const opcodeinfo *opcodes, size_t opcode_count, m6x09_instruction_level level) + : m_opcodes(opcodes, opcode_count), m_level(level) + { + } + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +protected: + enum m6x09_addressing_mode + { + INH, // Inherent + PSHS, PSHU, // Push + PULS, PULU, // Pull + DIR, // Direct + DIR_IM, // Direct in memory (6309 only) + IND, // Indexed + REL, // Relative (8 bit) + LREL, // Long relative (16 bit) + EXT, // Extended + IMM, // Immediate + IMM_RR, // Register-to-register + IMM_BW, // Bitwise operations (6309 only) + IMM_TFM, // Transfer from memory (6309 only) + PG1, // Switch to page 1 opcodes + PG2 // Switch to page 2 opcodes + }; + + // Opcode structure + class opcodeinfo + { + public: + constexpr opcodeinfo(uint16_t opcode, uint8_t length, const char *name, m6x09_addressing_mode mode, m6x09_instruction_level level, unsigned flags = 0) + : m_opcode(opcode), m_length(length), m_mode(mode), m_level(level), m_flags(flags), m_name(name) + { + } + + uint16_t opcode() const { return m_opcode; } + uint8_t length() const { return m_length; } + m6x09_addressing_mode mode() const { return m_mode; } + m6x09_instruction_level level() const { return m_level; } + unsigned flags() const { return m_flags; } + const char *name() const { return m_name; } + + private: + uint16_t m_opcode; // 8-bit opcode value + uint8_t m_length; // Opcode length in bytes + m6x09_addressing_mode m_mode : 6; // Addressing mode + m6x09_instruction_level m_level : 2; // General, or 6309 only? + unsigned m_flags; // Disassembly flags + const char * m_name; // Opcode name + }; + + static const char *const m6x09_regs[5]; + static const char *const m6x09_btwregs[5]; + static const char *const hd6309_tfmregs[16]; + static const char *const tfm_s[]; + + virtual void indirect(std::ostream &stream, uint8_t pb, const data_buffer ¶ms, offs_t &p) = 0; + virtual void register_register(std::ostream &stream, uint8_t pb) = 0; + +private: + util::contiguous_sequence_wrapper<const opcodeinfo> m_opcodes; + m6x09_instruction_level m_level; + + const opcodeinfo *fetch_opcode(const data_buffer &opcodes, offs_t &p); + + void assert_hd6309_exclusive() + { + if (m_level < HD6309_EXCLUSIVE) + throw false; + } +}; + +class m6x09_disassembler : public m6x09_base_disassembler +{ +public: + m6x09_disassembler(m6x09_instruction_level level, const char teregs[16][4]); + +protected: + virtual void indirect(std::ostream &stream, uint8_t pb, const data_buffer ¶ms, offs_t &p) override; + virtual void register_register(std::ostream &stream, uint8_t pb) override; + +private: + static const opcodeinfo m6x09_opcodes[]; + const std::array<std::array<char, 4>, 16> &m_teregs; +}; + + +class konami_disassembler : public m6x09_base_disassembler +{ +public: + konami_disassembler(); + +protected: + virtual void indirect(std::ostream &stream, uint8_t pb, const data_buffer ¶ms, offs_t &p) override; + virtual void register_register(std::ostream &stream, uint8_t pb) override; + +private: + static const opcodeinfo konami_opcodes[]; +}; + +class m6809_disassembler : public m6x09_disassembler +{ +public: + m6809_disassembler(); + +private: + static const char m6809_teregs[16][4]; +}; + +class hd6309_disassembler : public m6x09_disassembler +{ +public: + hd6309_disassembler(); + +private: + static const char hd6309_teregs[16][4]; +}; + +#endif diff --git a/src/devices/cpu/m6809/base6x09.ops b/src/devices/cpu/m6809/base6x09.ops index 8a36ecf2b78..2bad6eec6f8 100644 --- a/src/devices/cpu/m6809/base6x09.ops +++ b/src/devices/cpu/m6809/base6x09.ops @@ -239,8 +239,8 @@ CMP8: return; SBC8: - m_temp.w = (uint16_t)read_operand() + (m_cc & CC_C ? 1 : 0); - regop8() = set_flags(CC_NZVC, regop8(), m_temp.b.l, regop8() - m_temp.w); + m_temp.b.l = read_operand(); + regop8() = set_flags(CC_NZVC, regop8(), m_temp.b.l, regop8() - m_temp.b.l - (m_cc & CC_C ? 1 : 0)); return; AND8: @@ -259,8 +259,8 @@ EOR8: return; ADC8: - m_temp.w = (uint16_t)read_operand() + (m_cc & CC_C ? 1 : 0); - regop8() = set_flags(add8_sets_h() ? CC_HNZVC : CC_NZVC, regop8(), m_temp.b.l, regop8() + m_temp.w); + m_temp.b.l = read_operand(); + regop8() = set_flags(add8_sets_h() ? CC_HNZVC : CC_NZVC, regop8(), m_temp.b.l, regop8() + m_temp.b.l + (m_cc & CC_C ? 1 : 0)); return; OR8: @@ -332,9 +332,9 @@ SYNC: // massaging the PC this way makes the debugger's behavior more // intuitive m_pc.w--; - + @eat_remaining(); - + // unmassage... m_pc.w++; } @@ -396,7 +396,7 @@ LBSR: JSR: @eat(2); goto GOTO_SUBROUTINE; - + GOTO_SUBROUTINE: @write_memory(--m_s.w, m_pc.b.l); @write_memory(--m_s.w, m_pc.b.h); @@ -442,7 +442,7 @@ CWAI: m_pc.w -= 2; @eat_remaining(); - + // unmassage... m_pc.w += 2; } @@ -526,7 +526,7 @@ SOFTWARE_INTERRUPT: m_temp.w = entire_state_registers(); %PUSH_REGISTERS; goto INTERRUPT_VECTOR; - + DIRECT: @set_ea(((uint16_t)m_dp << 8) | read_opcode_arg()); @eat(hd6309_native_mode() ? 0 : 1); diff --git a/src/devices/cpu/m6809/hd6309.cpp b/src/devices/cpu/m6809/hd6309.cpp index 30de26db2c6..1b40d17e06f 100644 --- a/src/devices/cpu/m6809/hd6309.cpp +++ b/src/devices/cpu/m6809/hd6309.cpp @@ -118,6 +118,7 @@ March 2013 NPW: #include "debugger.h" #include "hd6309.h" #include "m6809inl.h" +#include "6x09dasm.h" //************************************************************************** @@ -285,38 +286,13 @@ void hd6309_device::device_post_load() //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t hd6309_device::disasm_min_opcode_bytes() const -{ - return 1; -} - - - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t hd6309_device::disasm_max_opcode_bytes() const -{ - return 5; -} - - - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t hd6309_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *hd6309_device::create_disassembler() { - extern CPU_DISASSEMBLE( hd6309 ); - return CPU_DISASSEMBLE_NAME(hd6309)(this, stream, pc, oprom, opram, options); + return new hd6309_disassembler; } diff --git a/src/devices/cpu/m6809/hd6309.h b/src/devices/cpu/m6809/hd6309.h index a097902da1f..8e209f9f7b2 100644 --- a/src/devices/cpu/m6809/hd6309.h +++ b/src/devices/cpu/m6809/hd6309.h @@ -42,9 +42,7 @@ protected: virtual void execute_run() override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual bool is_6809() override { return false; }; diff --git a/src/devices/cpu/m6809/konami.cpp b/src/devices/cpu/m6809/konami.cpp index 55f3a864744..cf41649a101 100644 --- a/src/devices/cpu/m6809/konami.cpp +++ b/src/devices/cpu/m6809/konami.cpp @@ -58,6 +58,7 @@ March 2013 NPW: #include "debugger.h" #include "konami.h" #include "m6809inl.h" +#include "6x09dasm.h" //************************************************************************** @@ -105,14 +106,13 @@ void konami_cpu_device::device_start() //------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t konami_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *konami_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( konami ); - return CPU_DISASSEMBLE_NAME(konami)(this, stream, pc, oprom, opram, options); + return new konami_disassembler; } diff --git a/src/devices/cpu/m6809/konami.h b/src/devices/cpu/m6809/konami.h index 1d9d900c138..216b007302a 100644 --- a/src/devices/cpu/m6809/konami.h +++ b/src/devices/cpu/m6809/konami.h @@ -46,7 +46,7 @@ protected: virtual void execute_run() override; // device_disasm_interface overrides - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: typedef m6809_base_device super; diff --git a/src/devices/cpu/m6809/m6809.cpp b/src/devices/cpu/m6809/m6809.cpp index 584af3e4912..42f64d5e5b2 100644 --- a/src/devices/cpu/m6809/m6809.cpp +++ b/src/devices/cpu/m6809/m6809.cpp @@ -83,6 +83,7 @@ March 2013 NPW: #include "debugger.h" #include "m6809.h" #include "m6809inl.h" +#include "6x09dasm.h" //************************************************************************** @@ -133,8 +134,8 @@ void m6809_base_device::device_start() m_mintf->m_program = &space(AS_PROGRAM); m_mintf->m_sprogram = has_space(AS_OPCODES) ? &space(AS_OPCODES) : m_mintf->m_program; - m_mintf->m_direct = &m_mintf->m_program->direct(); - m_mintf->m_sdirect = &m_mintf->m_sprogram->direct(); + m_mintf->m_direct = m_mintf->m_program->direct<0>(); + m_mintf->m_sdirect = m_mintf->m_sprogram->direct<0>(); m_lic_func.resolve_safe(); @@ -350,36 +351,13 @@ void m6809_base_device::state_string_export(const device_state_entry &entry, std //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t m6809_base_device::disasm_min_opcode_bytes() const -{ - return 1; -} - - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t m6809_base_device::disasm_max_opcode_bytes() const -{ - return 5; -} - - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t m6809_base_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *m6809_base_device::create_disassembler() { - extern CPU_DISASSEMBLE( m6809 ); - return CPU_DISASSEMBLE_NAME(m6809)(this, stream, pc, oprom, opram, options); + return new m6809_disassembler; } diff --git a/src/devices/cpu/m6809/m6809.h b/src/devices/cpu/m6809/m6809.h index 29d1acbcf9e..759e37113a5 100644 --- a/src/devices/cpu/m6809/m6809.h +++ b/src/devices/cpu/m6809/m6809.h @@ -34,7 +34,7 @@ protected: class memory_interface { public: address_space *m_program, *m_sprogram; - direct_read_data *m_direct, *m_sdirect; + direct_read_data<0> *m_direct, *m_sdirect; virtual ~memory_interface() {} virtual uint8_t read(uint16_t adr) = 0; @@ -71,9 +71,7 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // device_state_interface overrides virtual void state_import(const device_state_entry &entry) override; diff --git a/src/devices/cpu/mb86233/mb86233.cpp b/src/devices/cpu/mb86233/mb86233.cpp index 526ac63e208..32bdd8f2ea7 100644 --- a/src/devices/cpu/mb86233/mb86233.cpp +++ b/src/devices/cpu/mb86233/mb86233.cpp @@ -18,6 +18,7 @@ #include "emu.h" #include "debugger.h" #include "mb86233.h" +#include "mb86233d.h" DEFINE_DEVICE_TYPE(MB86233, mb86233_cpu_device, "mb86233", "MB86233") @@ -46,10 +47,9 @@ device_memory_interface::space_config_vector mb86233_cpu_device::memory_space_co } -offs_t mb86233_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *mb86233_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( mb86233 ); - return CPU_DISASSEMBLE_NAME(mb86233)(this, stream, pc, oprom, opram, options); + return new mb86233_disassembler; } @@ -79,9 +79,9 @@ offs_t mb86233_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, c #define GETBRAM() m_BRAM #define GETREPCNT() m_repcnt -#define ROPCODE(a) m_direct->read_dword(a<<2) -#define RDMEM(a) m_program->read_dword((a<<2)) -#define WRMEM(a,v) m_program->write_dword((a<<2), v) +#define ROPCODE(a) m_direct->read_dword(a) +#define RDMEM(a) m_program->read_dword(a) +#define WRMEM(a,v) m_program->write_dword((a), v) /*************************************************************************** Initialization and Shutdown @@ -110,7 +110,7 @@ void mb86233_cpu_device::device_start() m_fifo_write_cb.resolve_safe(); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<-2>(); if ( m_tablergn ) { diff --git a/src/devices/cpu/mb86233/mb86233.h b/src/devices/cpu/mb86233/mb86233.h index c60aabd987e..49ba58d7ea8 100644 --- a/src/devices/cpu/mb86233/mb86233.h +++ b/src/devices/cpu/mb86233/mb86233.h @@ -77,9 +77,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 4; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 4; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -111,7 +109,7 @@ private: uint32_t m_extport[0x30]; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<-2> *m_direct; int m_icount; /* FIFO */ diff --git a/src/devices/cpu/mb86233/mb86233d.cpp b/src/devices/cpu/mb86233/mb86233d.cpp index 0919ca1ef58..5d5c9b13a27 100644 --- a/src/devices/cpu/mb86233/mb86233d.cpp +++ b/src/devices/cpu/mb86233/mb86233d.cpp @@ -1,8 +1,7 @@ // license:BSD-3-Clause // copyright-holders:Ernesto Corvi #include "emu.h" -#include "debugger.h" -#include "mb86233.h" +#include "mb86233d.h" /* @@ -74,14 +73,14 @@ -static const char *const regnames[0x40] = { +const char *const mb86233_disassembler::regnames[0x40] = { "b0", "b1", "x0", "x1", "x2", "i0", "i1", "i2", "sp", "pag", "vsm", "dmc", "c0", "c1", "pc", "-", "a", "ah", "al", "b", "bh", "bl", "c", "ch", "cl", "d", "dh", "dl", "p", "ph", "pl", "sft", "rf0", "rf1", "rf2", "rf3", "rf4", "rf5", "rf6", "rf7", "rf8", "rf9", "rfa", "rfb", "rfc", "rfd", "rfe", "rff", "sio0", "si1", "pio", "pioa", "rpc", "r?35", "r?36", "r?37", "pad", "mod", "ear", "st", "mask", "tim", "cx", "dx" }; -static std::string condition(unsigned int cond, bool invert) +std::string mb86233_disassembler::condition(unsigned int cond, bool invert) { std::ostringstream stream; @@ -101,12 +100,12 @@ static std::string condition(unsigned int cond, bool invert) return stream.str(); } -static std::string regs(uint32_t reg) +std::string mb86233_disassembler::regs(u32 reg) { return regnames[reg & 0x3f]; } -static std::string memory(uint32_t reg, bool x1) +std::string mb86233_disassembler::memory(u32 reg, bool x1) { std::ostringstream stream; @@ -182,7 +181,7 @@ static std::string memory(uint32_t reg, bool x1) return stream.str(); } -static std::string alu0_func( uint32_t alu) +std::string mb86233_disassembler::alu0_func(u32 alu) { std::ostringstream stream; @@ -224,14 +223,16 @@ static std::string alu0_func( uint32_t alu) return stream.str(); } -static unsigned dasm_mb86233(std::ostream &stream, uint32_t opcode ) +offs_t mb86233_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { + u32 opcode = opcodes.r32(pc); + switch((opcode >> 26) & 0x3f) { case 0x00: { // Dual move AB - uint32_t r1 = opcode & 0x1ff; - uint32_t r2 = (opcode >> 9) & 0x1ff; - uint32_t alu = (opcode >> 21) & 0x1f; - uint32_t op = (opcode >> 18) & 0x7; + u32 r1 = opcode & 0x1ff; + u32 r2 = (opcode >> 9) & 0x1ff; + u32 alu = (opcode >> 21) & 0x1f; + u32 op = (opcode >> 18) & 0x7; if(alu) util::stream_format(stream, "%s : ", alu0_func(alu) ); @@ -253,10 +254,10 @@ static unsigned dasm_mb86233(std::ostream &stream, uint32_t opcode ) } case 0x07: { // LD/MOV - uint32_t r1 = opcode & 0x1ff; - uint32_t r2 = (opcode >> 9) & 0x1ff; - uint32_t alu = (opcode >> 21) & 0x1f; - uint32_t op = (opcode >> 18) & 0x7; + u32 r1 = opcode & 0x1ff; + u32 r2 = (opcode >> 9) & 0x1ff; + u32 alu = (opcode >> 21) & 0x1f; + u32 op = (opcode >> 18) & 0x7; if(alu) { util::stream_format(stream, "%s", alu0_func(alu)); @@ -345,8 +346,8 @@ static unsigned dasm_mb86233(std::ostream &stream, uint32_t opcode ) } case 0x0f: { // rep/clr0/clr1/set - uint32_t alu = (opcode >> 21) & 0x1f; - uint32_t sub2 = (opcode >> 17) & 7; + u32 alu = (opcode >> 21) & 0x1f; + u32 sub2 = (opcode >> 17) & 7; if(alu) util::stream_format(stream, "%s : ", alu0_func(alu)); @@ -400,9 +401,9 @@ static unsigned dasm_mb86233(std::ostream &stream, uint32_t opcode ) break; case 0x2f: case 0x3f: { - uint32_t cond = ( opcode >> 20 ) & 0x1f; - uint32_t subtype = ( opcode >> 17 ) & 7; - uint32_t data = opcode & 0xffff; + u32 cond = ( opcode >> 20 ) & 0x1f; + u32 subtype = ( opcode >> 17 ) & 7; + u32 data = opcode & 0xffff; bool invert = opcode & 0x40000000; switch(subtype) { @@ -454,12 +455,10 @@ static unsigned dasm_mb86233(std::ostream &stream, uint32_t opcode ) break; } - return (1 | DASMFLAG_SUPPORTED); + return 1 | SUPPORTED; } -CPU_DISASSEMBLE(mb86233) +u32 mb86233_disassembler::opcode_alignment() const { - uint32_t op = *(uint32_t *)oprom; - op = little_endianize_int32(op); - return dasm_mb86233(stream, op); + return 1; } diff --git a/src/devices/cpu/mb86233/mb86233d.h b/src/devices/cpu/mb86233/mb86233d.h new file mode 100644 index 00000000000..50a48a6f0a9 --- /dev/null +++ b/src/devices/cpu/mb86233/mb86233d.h @@ -0,0 +1,26 @@ +// license:BSD-3-Clause +// copyright-holders:Ernesto Corvi + +#ifndef MAME_CPU_MB86233_MB86233D_H +#define MAME_CPU_MB86233_MB86233D_H + +#pragma once + +class mb86233_disassembler : public util::disasm_interface +{ +public: + mb86233_disassembler() = default; + virtual ~mb86233_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *const regnames[0x40]; + static std::string condition(unsigned int cond, bool invert); + static std::string regs(u32 reg); + static std::string memory(u32 reg, bool x1); + static std::string alu0_func(u32 alu); +}; + +#endif diff --git a/src/devices/cpu/mb86235/mb86235.cpp b/src/devices/cpu/mb86235/mb86235.cpp index 223b27db6d3..77a24bc43a4 100644 --- a/src/devices/cpu/mb86235/mb86235.cpp +++ b/src/devices/cpu/mb86235/mb86235.cpp @@ -14,6 +14,7 @@ #include "emu.h" #include "mb86235.h" #include "mb86235fe.h" +#include "mb86235d.h" #include "debugger.h" @@ -56,7 +57,7 @@ void mb86235_device::execute_run() void mb86235_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<-3>(); m_dataa = &space(AS_DATA); m_datab = &space(AS_IO); @@ -234,10 +235,9 @@ void mb86235_device::state_string_export(const device_state_entry &entry, std::s } } -offs_t mb86235_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *mb86235_device::create_disassembler() { - extern CPU_DISASSEMBLE( mb86235 ); - return CPU_DISASSEMBLE_NAME(mb86235)(this, stream, pc, oprom, opram, options); + return new mb86235_disassembler; } diff --git a/src/devices/cpu/mb86235/mb86235.h b/src/devices/cpu/mb86235/mb86235.h index ebe151213da..f1845bfce6f 100644 --- a/src/devices/cpu/mb86235/mb86235.h +++ b/src/devices/cpu/mb86235/mb86235.h @@ -71,11 +71,9 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 8; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 8; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; - direct_read_data *m_direct; + direct_read_data<-3> *m_direct; private: @@ -228,7 +226,4 @@ private: DECLARE_DEVICE_TYPE(MB86235, mb86235_device) - -CPU_DISASSEMBLE( mb86235 ); - #endif // MAME_CPU_MB86235_MB86235_H diff --git a/src/devices/cpu/mb86235/mb86235d.cpp b/src/devices/cpu/mb86235/mb86235d.cpp index f32fcba8969..e705500f1cd 100644 --- a/src/devices/cpu/mb86235/mb86235d.cpp +++ b/src/devices/cpu/mb86235/mb86235d.cpp @@ -1,10 +1,9 @@ // license:BSD-3-Clause // copyright-holders:Angelo Salese, ElSemi, Ville Linde #include "emu.h" -#include "debugger.h" -#include "mb86235.h" +#include "mb86235d.h" -static const char *regname[128] = +const char *mb86235_disassembler::regname[128] = { "MA0", "MA1", "MA2", "MA3", "MA4", "MA5", "MA6", "MA7", "AA0", "AA1", "AA2", "AA3", "AA4", "AA5", "AA6", "AA7", @@ -16,7 +15,7 @@ static const char *regname[128] = "???", "???", "???", "???", "???", "???", "???", "???" }; -static const char *db_mnemonic[64] = +const char *mb86235_disassembler::db_mnemonic[64] = { "DBMN", "DBMZ", "DBMV", "DBMU", "DBZD", "DBNR", "DBIL", "DBZC", "DBAN", "DBAZ", "DBAV", "DBAU", "DBMD", "DBAD", "???", "???", @@ -28,7 +27,7 @@ static const char *db_mnemonic[64] = "???", "???", "???", "???", "???", "???", "???", "???" }; -static const char *dbn_mnemonic[64] = +const char *mb86235_disassembler::dbn_mnemonic[64] = { "DBNMN", "DBNMZ", "DBNMV", "DBNMU", "DBNZD", "DBNNR", "DBNIL", "DBNZC", "DBNAN", "DBNAZ", "DBNAV", "DBNAU", "DBNMD", "DBNAD", "???", "???", @@ -40,7 +39,7 @@ static const char *dbn_mnemonic[64] = "???", "???", "???", "???", "???", "???", "???", "???" }; -static const char *dc_mnemonic[64] = +const char *mb86235_disassembler::dc_mnemonic[64] = { "DCMN", "DCMZ", "DCMV", "DCMU", "DCZD", "DCNR", "DCIL", "DCZC", "DCAN", "DCAZ", "DCAV", "DCAU", "DCMD", "DCAD", "???", "???", @@ -52,7 +51,7 @@ static const char *dc_mnemonic[64] = "???", "???", "???", "???", "???", "???", "???", "???" }; -static const char *dcn_mnemonic[64] = +const char *mb86235_disassembler::dcn_mnemonic[64] = { "DCNMN", "DCNMZ", "DCNMV", "DCNMU", "DCNZD", "DCNNR", "DCNIL", "DCNZC", "DCNAN", "DCNAZ", "DCNAV", "DCNAU", "DCNMD", "DCNAD", "???", "???", @@ -64,29 +63,29 @@ static const char *dcn_mnemonic[64] = "???", "???", "???", "???", "???", "???", "???", "???" }; -static const char *mi1_field[16] = +const char *mb86235_disassembler::mi1_field[16] = { "MA0", "MA1", "MA2", "MA3", "MA4", "MA5", "MA6", "MA7", "MB0", "MB1", "MB2", "MB3", "MB4", "MB5", "MB6", "MB7" }; -static const char *mi2_field[32] = +const char *mb86235_disassembler::mi2_field[32] = { "MA0", "MA1", "MA2", "MA3", "MA4", "MA5", "MA6", "MA7", "MB0", "MB1", "MB2", "MB3", "MB4", "MB5", "MB6", "MB7", "PR", "PR++", "PR--", "PR#0", "???", "???", "???", "???", "-1.0E+0", "0.0E+0", "0.5E+0", "1.0E+0", "1.5E+0", "2.0E+0", "3.0E+0", "5.0E+0" }; -static const char *mo_field[32] = +const char *mb86235_disassembler::mo_field[32] = { "MA0", "MA1", "MA2", "MA3", "MA4", "MA5", "MA6", "MA7", "MB0", "MB1", "MB2", "MB3", "MB4", "MB5", "MB6", "MB7", "AA0", "AA1", "AA2", "AA3", "AA4", "AA5", "AA6", "AA7", "AB0", "AB1", "AB2", "AB3", "AB4", "AB5", "AB6", "AB7" }; -static const char *ai1_field[16] = +const char *mb86235_disassembler::ai1_field[16] = { "AA0", "AA1", "AA2", "AA3", "AA4", "AA5", "AA6", "AA7", "AB0", "AB1", "AB2", "AB3", "AB4", "AB5", "AB6", "AB7" }; -static const char *ai2_field[32] = +const char *mb86235_disassembler::ai2_field[32] = { "AA0", "AA1", "AA2", "AA3", "AA4", "AA5", "AA6", "AA7", "AB0", "AB1", "AB2", "AB3", "AB4", "AB5", "AB6", "AB7", "PR", "PR++", "PR--", "PR#0", "???", "???", "???", "???", "0", "1", "-1", "???", "???", "???", "???", "???" }; -static const char *ai2f_field[32] = +const char *mb86235_disassembler::ai2f_field[32] = { "AA0", "AA1", "AA2", "AA3", "AA4", "AA5", "AA6", "AA7", "AB0", "AB1", "AB2", "AB3", "AB4", "AB5", "AB6", "AB7", "PR", "PR++", "PR--", "PR#0", "???", "???", "???", "???", "-1.0E+0", "0.0E+0", "0.5E+0", "1.0E+0", "1.5E+0", "2.0E+0", "3.0E+0", "5.0E+0" }; -static void dasm_ea(std::ostream &stream, int md, int arx, int ary, int disp) +void mb86235_disassembler::dasm_ea(std::ostream &stream, int md, int arx, int ary, int disp) { if (arx & 0x20) stream << "B("; @@ -117,7 +116,7 @@ static void dasm_ea(std::ostream &stream, int md, int arx, int ary, int disp) stream << ')'; } -static void dasm_alu_mul(std::ostream &stream, uint64_t opcode, bool twoop) +void mb86235_disassembler::dasm_alu_mul(std::ostream &stream, uint64_t opcode, bool twoop) { int ma = (opcode & ((uint64_t)(1) << 41)) ? 1 : 0; int o = (opcode >> 42) & 0x1f; @@ -220,7 +219,7 @@ static void dasm_alu_mul(std::ostream &stream, uint64_t opcode, bool twoop) } } -static void dasm_control(std::ostream &stream, uint32_t pc, uint64_t opcode) +void mb86235_disassembler::dasm_control(std::ostream &stream, uint32_t pc, uint64_t opcode) { int ef1 = (opcode >> 16) & 0x3f; int ef2 = opcode & 0xffff; @@ -335,7 +334,7 @@ static void dasm_control(std::ostream &stream, uint32_t pc, uint64_t opcode) } } -static void dasm_double_xfer1(std::ostream &stream, uint64_t opcode) +void mb86235_disassembler::dasm_double_xfer1(std::ostream &stream, uint64_t opcode) { int sd = (opcode >> 25) & 3; @@ -413,7 +412,7 @@ static void dasm_double_xfer1(std::ostream &stream, uint64_t opcode) } } -static void dasm_xfer1(std::ostream &stream, uint64_t opcode) +void mb86235_disassembler::dasm_xfer1(std::ostream &stream, uint64_t opcode) { int dr = (opcode >> 12) & 0x7f; int sr = (opcode >> 19) & 0x7f; @@ -469,7 +468,7 @@ static void dasm_xfer1(std::ostream &stream, uint64_t opcode) } } -static void dasm_double_xfer2_field(std::ostream &stream, int sd, uint32_t field) +void mb86235_disassembler::dasm_double_xfer2_field(std::ostream &stream, int sd, uint32_t field) { switch (sd) { @@ -537,7 +536,7 @@ static void dasm_double_xfer2_field(std::ostream &stream, int sd, uint32_t field } } -static void dasm_double_xfer2(std::ostream &stream, uint64_t opcode) +void mb86235_disassembler::dasm_double_xfer2(std::ostream &stream, uint64_t opcode) { int asd = (opcode >> 38) & 3; int bsd = (opcode >> 18) & 3; @@ -583,7 +582,7 @@ static void dasm_double_xfer2(std::ostream &stream, uint64_t opcode) } } -static void dasm_xfer2(std::ostream &stream, uint64_t opcode) +void mb86235_disassembler::dasm_xfer2(std::ostream &stream, uint64_t opcode) { int op = (opcode >> 39) & 3; int trm = (opcode >> 38) & 1; @@ -652,7 +651,7 @@ static void dasm_xfer2(std::ostream &stream, uint64_t opcode) } } -static void dasm_xfer3(std::ostream &stream, uint64_t opcode) +void mb86235_disassembler::dasm_xfer3(std::ostream &stream, uint64_t opcode) { uint32_t imm = (uint32_t)(opcode >> 27); int dr = (opcode >> 19) & 0x7f; @@ -668,8 +667,9 @@ static void dasm_xfer3(std::ostream &stream, uint64_t opcode) dasm_ea(stream, md, dr, ary, disp); } -static unsigned dasm_mb86235(std::ostream &stream, uint32_t pc, uint64_t opcode) +offs_t mb86235_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { + u64 opcode = opcodes.r64(pc); switch ((opcode >> 61) & 7) { case 0: // ALU / MUL / double transfer (type 1) @@ -711,14 +711,11 @@ static unsigned dasm_mb86235(std::ostream &stream, uint32_t pc, uint64_t opcode) break; } - return (1 | DASMFLAG_SUPPORTED); + return 1 | SUPPORTED; } - -CPU_DISASSEMBLE(mb86235) +u32 mb86235_disassembler::opcode_alignment() const { - uint64_t op = *(uint64_t*)oprom; - op = little_endianize_int64(op); - - return dasm_mb86235(stream, pc, op); + return 1; } + diff --git a/src/devices/cpu/mb86235/mb86235d.h b/src/devices/cpu/mb86235/mb86235d.h new file mode 100644 index 00000000000..a29fe41f064 --- /dev/null +++ b/src/devices/cpu/mb86235/mb86235d.h @@ -0,0 +1,42 @@ +// license:BSD-3-Clause +// copyright-holders:Angelo Salese, ElSemi, Ville Linde +#ifndef MAME_CPU_MB86235_MB86235D_H +#define MAME_CPU_MB86235_MB86235D_H + +#pragma once + +class mb86235_disassembler : public util::disasm_interface +{ +public: + mb86235_disassembler() = default; + virtual ~mb86235_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *regname[128]; + static const char *db_mnemonic[64]; + static const char *dbn_mnemonic[64]; + static const char *dc_mnemonic[64]; + static const char *dcn_mnemonic[64]; + static const char *mi1_field[16]; + static const char *mi2_field[32]; + static const char *mo_field[32]; + static const char *ai1_field[16]; + static const char *ai2_field[32]; + static const char *ai2f_field[32]; + + void dasm_ea(std::ostream &stream, int md, int arx, int ary, int disp); + void dasm_alu_mul(std::ostream &stream, uint64_t opcode, bool twoop); + void dasm_control(std::ostream &stream, uint32_t pc, uint64_t opcode); + void dasm_double_xfer1(std::ostream &stream, uint64_t opcode); + void dasm_xfer1(std::ostream &stream, uint64_t opcode); + void dasm_double_xfer2_field(std::ostream &stream, int sd, uint32_t field); + void dasm_double_xfer2(std::ostream &stream, uint64_t opcode); + void dasm_xfer2(std::ostream &stream, uint64_t opcode); + void dasm_xfer3(std::ostream &stream, uint64_t opcode); + +}; + +#endif diff --git a/src/devices/cpu/mb86235/mb86235drc.cpp b/src/devices/cpu/mb86235/mb86235drc.cpp index d3fa314b0ae..fa1f829a07b 100644 --- a/src/devices/cpu/mb86235/mb86235drc.cpp +++ b/src/devices/cpu/mb86235/mb86235drc.cpp @@ -498,7 +498,6 @@ void mb86235_device::static_generate_memory_accessors() UML_CMP(block, I0, 0x400); UML_JMPc(block, COND_GE, label); // internal A-RAM - UML_SHL(block, I0, I0, 2); UML_READ(block, I1, I0, SIZE_DWORD, SPACE_DATA); UML_RET(block); // external @@ -506,7 +505,6 @@ void mb86235_device::static_generate_memory_accessors() UML_AND(block, I0, I0, 0x3fff); UML_AND(block, I2, mem(&m_core->eb), ~0x3fff); UML_OR(block, I0, I0, I2); - UML_SHL(block, I0, I0, 2); UML_READ(block, I1, I0, SIZE_DWORD, SPACE_DATA); UML_RET(block); @@ -523,7 +521,6 @@ void mb86235_device::static_generate_memory_accessors() UML_CMP(block, I0, 0x400); UML_JMPc(block, COND_GE, label); // internal A-RAM - UML_SHL(block, I0, I0, 2); UML_WRITE(block, I0, I1, SIZE_DWORD, SPACE_DATA); UML_RET(block); // external @@ -531,7 +528,6 @@ void mb86235_device::static_generate_memory_accessors() UML_AND(block, I0, I0, 0x3fff); UML_AND(block, I2, mem(&m_core->eb), ~0x3fff); UML_OR(block, I0, I0, I2); - UML_SHL(block, I0, I0, 2); UML_WRITE(block, I0, I1, SIZE_DWORD, SPACE_DATA); UML_RET(block); @@ -1666,7 +1662,6 @@ void mb86235_device::generate_xfer1(drcuml_block *block, compiler_state *compile generate_ea(block, compiler, desc, md, sr & 7, ary, disp5); if (sr & 0x20) // RAM-B { - UML_SHL(block, I0, I0, 2); UML_READ(block, I1, I0, SIZE_DWORD, SPACE_IO); } else // RAM-A @@ -1684,7 +1679,6 @@ void mb86235_device::generate_xfer1(drcuml_block *block, compiler_state *compile generate_ea(block, compiler, desc, md, dr & 7, ary, disp5); if (dr & 0x20) // RAM-B { - UML_SHL(block, I0, I0, 2); UML_WRITE(block, I0, I1, SIZE_DWORD, SPACE_IO); } else // RAM-A @@ -1743,7 +1737,6 @@ void mb86235_device::generate_xfer2(drcuml_block *block, compiler_state *compile generate_ea(block, compiler, desc, md, sr & 7, ary, disp14); if (sr & 0x20) // RAM-B { - UML_SHL(block, I0, I0, 2); UML_READ(block, I1, I0, SIZE_DWORD, SPACE_IO); } else // RAM-A @@ -1761,7 +1754,6 @@ void mb86235_device::generate_xfer2(drcuml_block *block, compiler_state *compile generate_ea(block, compiler, desc, md, dr & 7, ary, disp14); if (dr & 0x20) // RAM-B { - UML_SHL(block, I0, I0, 2); UML_WRITE(block, I0, I1, SIZE_DWORD, SPACE_IO); } else // RAM-A @@ -1779,14 +1771,12 @@ void mb86235_device::generate_xfer2(drcuml_block *block, compiler_state *compile generate_reg_read(block, compiler, desc, dr & 0x3f, I0); UML_ADD(block, I1, mem(&m_core->eb), mem(&m_core->eo)); UML_ADD(block, I1, I1, disp14); - UML_SHL(block, I1, I1, 2); UML_WRITE(block, I1, I0, SIZE_DWORD, SPACE_DATA); } else { UML_ADD(block, I1, mem(&m_core->eb), mem(&m_core->eo)); UML_ADD(block, I1, I1, disp14); - UML_SHL(block, I1, I1, 2); UML_READ(block, I0, I1, SIZE_DWORD, SPACE_DATA); generate_reg_write(block, compiler, desc, dr & 0x3f, I0); } @@ -1835,7 +1825,6 @@ void mb86235_device::generate_xfer3(drcuml_block *block, compiler_state *compile case 3: // RAM-B generate_ea(block, compiler, desc, md, dr & 7, ary, disp); - UML_SHL(block, I0, I0, 2); UML_WRITE(block, I0, imm, SIZE_DWORD, SPACE_IO); break; } diff --git a/src/devices/cpu/mb86235/mb86235fe.cpp b/src/devices/cpu/mb86235/mb86235fe.cpp index 854fd97abb7..5e60cfe6216 100644 --- a/src/devices/cpu/mb86235/mb86235fe.cpp +++ b/src/devices/cpu/mb86235/mb86235fe.cpp @@ -63,7 +63,7 @@ mb86235_frontend::mb86235_frontend(mb86235_device *core, uint32_t window_start, bool mb86235_frontend::describe(opcode_desc &desc, const opcode_desc *prev) { - uint64_t opcode = desc.opptr.q[0] = m_core->m_direct->read_qword(desc.pc * 8, 0); + uint64_t opcode = desc.opptr.q[0] = m_core->m_direct->read_qword(desc.pc, 0); desc.length = 1; desc.cycles = 1; diff --git a/src/devices/cpu/mb88xx/mb88dasm.cpp b/src/devices/cpu/mb88xx/mb88dasm.cpp index eced68233b0..2ab2856e1e8 100644 --- a/src/devices/cpu/mb88xx/mb88dasm.cpp +++ b/src/devices/cpu/mb88xx/mb88dasm.cpp @@ -10,14 +10,18 @@ *******************************************************************************/ #include "emu.h" -#include "mb88xx.h" +#include "mb88dasm.h" +u32 mb88_disassembler::opcode_alignment() const +{ + return 1; +} -CPU_DISASSEMBLE(mb88) +offs_t mb88_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { unsigned startpc = pc; - uint8_t op = oprom[pc++ - startpc]; - uint8_t arg = oprom[pc - startpc]; + uint8_t op = opcodes.r8(pc++); + uint8_t arg = opcodes.r8(pc); switch( op ) { @@ -220,5 +224,5 @@ CPU_DISASSEMBLE(mb88) break; } - return (pc - startpc) | DASMFLAG_SUPPORTED; + return (pc - startpc) | SUPPORTED; } diff --git a/src/devices/cpu/mb88xx/mb88dasm.h b/src/devices/cpu/mb88xx/mb88dasm.h new file mode 100644 index 00000000000..80a37a374c7 --- /dev/null +++ b/src/devices/cpu/mb88xx/mb88dasm.h @@ -0,0 +1,28 @@ +// license:BSD-3-Clause +// copyright-holders:Ernesto Corvi +/******************************************************************************* + + mb88dasm.c + Core implementation for the portable Fujitsu MB88xx series MCU disassembler. + + Written by Ernesto Corvi + +*******************************************************************************/ + + +#ifndef MAME_CPU_MB88XX_MB88DASM_H +#define MAME_CPU_MB88XX_MB88DASM_H + +#pragma once + +class mb88_disassembler : public util::disasm_interface +{ +public: + mb88_disassembler() = default; + virtual ~mb88_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/mb88xx/mb88xx.cpp b/src/devices/cpu/mb88xx/mb88xx.cpp index b896a07c6cf..1473a3452ae 100644 --- a/src/devices/cpu/mb88xx/mb88xx.cpp +++ b/src/devices/cpu/mb88xx/mb88xx.cpp @@ -17,6 +17,7 @@ #include "emu.h" #include "mb88xx.h" +#include "mb88dasm.h" #include "debugger.h" @@ -162,10 +163,9 @@ device_memory_interface::space_config_vector mb88_cpu_device::memory_space_confi }; } -offs_t mb88_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *mb88_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( mb88 ); - return CPU_DISASSEMBLE_NAME(mb88)(this, stream, pc, oprom, opram, options); + return new mb88_disassembler; } @@ -176,7 +176,7 @@ offs_t mb88_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, cons void mb88_cpu_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_data = &space(AS_DATA); m_read_k.resolve_safe(0); diff --git a/src/devices/cpu/mb88xx/mb88xx.h b/src/devices/cpu/mb88xx/mb88xx.h index f4485e47f26..0be1ac9b06e 100644 --- a/src/devices/cpu/mb88xx/mb88xx.h +++ b/src/devices/cpu/mb88xx/mb88xx.h @@ -122,9 +122,6 @@ enum #define MB88_IRQ_LINE 0 -CPU_DISASSEMBLE( mb88 ); - - class mb88_cpu_device : public cpu_device { public: @@ -165,9 +162,7 @@ protected: virtual void state_export(const device_state_entry &entry) override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 2; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -215,7 +210,7 @@ private: uint8_t m_pending_interrupt; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_data; int m_icount; diff --git a/src/devices/cpu/mc68hc11/hc11dasm.cpp b/src/devices/cpu/mc68hc11/hc11dasm.cpp index 20ad20c4d0a..9fdc77409fe 100644 --- a/src/devices/cpu/mc68hc11/hc11dasm.cpp +++ b/src/devices/cpu/mc68hc11/hc11dasm.cpp @@ -7,33 +7,9 @@ */ #include "emu.h" +#include "hc11dasm.h" -enum -{ - EA_IMM8 = 1, - EA_IMM16, - EA_EXT, - EA_REL, - EA_DIRECT, - EA_DIRECT_IMM8, - EA_DIRECT_IMM8_REL, - EA_IND_X, - EA_IND_X_IMM8, - EA_IND_X_IMM8_REL, - EA_IND_Y, - EA_IND_Y_IMM8, - EA_IND_Y_IMM8_REL, - PAGE2, - PAGE3, - PAGE4 -}; - -struct M68HC11_OPCODE { - char mnemonic[32]; - int address_mode; -}; - -static const M68HC11_OPCODE opcode_table[256] = +const hc11_disassembler::M68HC11_OPCODE hc11_disassembler::opcode_table[256] = { /* 0x00 - 0x0f */ { "test", 0, }, @@ -313,7 +289,7 @@ static const M68HC11_OPCODE opcode_table[256] = /*****************************************************************************/ -static const M68HC11_OPCODE opcode_table_page2[256] = +const hc11_disassembler::M68HC11_OPCODE hc11_disassembler::opcode_table_page2[256] = { /* 0x00 - 0x0f */ { "?", 0, }, @@ -593,7 +569,7 @@ static const M68HC11_OPCODE opcode_table_page2[256] = /*****************************************************************************/ -static const M68HC11_OPCODE opcode_table_page3[256] = +const hc11_disassembler::M68HC11_OPCODE hc11_disassembler::opcode_table_page3[256] = { /* 0x00 - 0x0f */ { "?", 0, }, @@ -873,7 +849,7 @@ static const M68HC11_OPCODE opcode_table_page3[256] = /*****************************************************************************/ -static const M68HC11_OPCODE opcode_table_page4[256] = +const hc11_disassembler::M68HC11_OPCODE hc11_disassembler::opcode_table_page4[256] = { /* 0x00 - 0x0f */ { "?", 0, }, @@ -1152,137 +1128,126 @@ static const M68HC11_OPCODE opcode_table_page4[256] = /*****************************************************************************/ -static const uint8_t *rombase; - -static uint8_t fetch(void) +u32 hc11_disassembler::opcode_alignment() const { - return *rombase++; + return 1; } -static uint16_t fetch16(void) +offs_t hc11_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - uint16_t w; - w = (rombase[0] << 8) | rombase[1]; - rombase+=2; - return w; -} + offs_t cpc = pc; + + uint8_t opcode = opcodes.r8(cpc++); + const M68HC11_OPCODE *op_table = &opcode_table[opcode]; -static uint32_t decode_opcode(std::ostream &stream, uint32_t pc, const M68HC11_OPCODE *op_table) -{ uint8_t imm8, mask; int8_t rel8; uint16_t imm16; uint8_t op2; uint32_t flags = 0; + loop: if (!strcmp(op_table->mnemonic, "jsr") || !strcmp(op_table->mnemonic, "bsr")) - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; else if (!strcmp(op_table->mnemonic, "rts") || !strcmp(op_table->mnemonic, "rti")) - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; switch(op_table->address_mode) { case EA_IMM8: - imm8 = fetch(); + imm8 = opcodes.r8(cpc++); util::stream_format(stream, "%s 0x%02X", op_table->mnemonic, imm8); break; case EA_IMM16: - imm16 = fetch16(); + imm16 = opcodes.r16(cpc++); + cpc += 2; util::stream_format(stream, "%s 0x%04X", op_table->mnemonic, imm16); break; case EA_DIRECT: - imm8 = fetch(); + imm8 = opcodes.r8(cpc++); util::stream_format(stream, "%s (0x%04X)", op_table->mnemonic, imm8); break; case EA_EXT: - imm16 = fetch16(); + imm16 = opcodes.r16(cpc++); + cpc += 2; util::stream_format(stream, "%s (0x%04X)", op_table->mnemonic, imm16); break; case EA_IND_X: - imm8 = fetch(); + imm8 = opcodes.r8(cpc++); util::stream_format(stream, "%s (X+0x%02X)", op_table->mnemonic, imm8); break; case EA_REL: - rel8 = fetch(); + rel8 = opcodes.r8(cpc++); util::stream_format(stream, "%s [0x%04X]", op_table->mnemonic, pc+2+rel8); break; case EA_DIRECT_IMM8: - imm8 = fetch(); - mask = fetch(); + imm8 = opcodes.r8(cpc++); + mask = opcodes.r8(cpc++); util::stream_format(stream, "%s (0x%04X), 0x%02X", op_table->mnemonic, imm8, mask); break; case EA_IND_X_IMM8: - imm8 = fetch(); - mask = fetch(); + imm8 = opcodes.r8(cpc++); + mask = opcodes.r8(cpc++); util::stream_format(stream, "%s (X+0x%02X), 0x%02X", op_table->mnemonic, imm8, mask); break; case EA_DIRECT_IMM8_REL: - imm8 = fetch(); - mask = fetch(); - rel8 = fetch(); + imm8 = opcodes.r8(cpc++); + mask = opcodes.r8(cpc++); + rel8 = opcodes.r8(cpc++); util::stream_format(stream, "%s (0x%04X), 0x%02X, [0x%04X]", op_table->mnemonic, imm8, mask, pc+4+rel8); break; case EA_IND_X_IMM8_REL: - imm8 = fetch(); - mask = fetch(); - rel8 = fetch(); + imm8 = opcodes.r8(cpc++); + mask = opcodes.r8(cpc++); + rel8 = opcodes.r8(cpc++); util::stream_format(stream, "%s (X+0x%02X), 0x%02X, [0x%04X]", op_table->mnemonic, imm8, mask, pc+4+rel8); break; case EA_IND_Y: - imm8 = fetch(); + imm8 = opcodes.r8(cpc++); util::stream_format(stream, "%s (Y+0x%02X)", op_table->mnemonic, imm8); break; case EA_IND_Y_IMM8: - imm8 = fetch(); - mask = fetch(); + imm8 = opcodes.r8(cpc++); + mask = opcodes.r8(cpc++); util::stream_format(stream, "%s (Y+0x%02X), 0x%02X", op_table->mnemonic, imm8, mask); break; case EA_IND_Y_IMM8_REL: - imm8 = fetch(); - mask = fetch(); - rel8 = fetch(); + imm8 = opcodes.r8(cpc++); + mask = opcodes.r8(cpc++); + rel8 = opcodes.r8(cpc++); util::stream_format(stream, "%s (Y+0x%02X), 0x%02X, [0x%04X]", op_table->mnemonic, imm8, mask, pc+2+rel8); break; case PAGE2: - op2 = fetch(); - return decode_opcode(stream, pc, &opcode_table_page2[op2]); + op2 = opcodes.r8(cpc++); + op_table = &opcode_table_page2[op2]; + goto loop; case PAGE3: - op2 = fetch(); - return decode_opcode(stream, pc, &opcode_table_page3[op2]); + op2 = opcodes.r8(cpc++); + op_table = &opcode_table_page3[op2]; + goto loop; case PAGE4: - op2 = fetch(); - return decode_opcode(stream, pc, &opcode_table_page4[op2]); + op2 = opcodes.r8(cpc++); + op_table = &opcode_table_page4[op2]; + goto loop; default: util::stream_format(stream, "%s", op_table->mnemonic); } - return flags; -} - -CPU_DISASSEMBLE(hc11) -{ - uint32_t flags; - uint8_t opcode; - - rombase = oprom; - - opcode = fetch(); - flags = decode_opcode(stream, pc, &opcode_table[opcode]); - return (rombase-oprom) | flags | DASMFLAG_SUPPORTED; + return (cpc - pc) | flags | SUPPORTED; } diff --git a/src/devices/cpu/mc68hc11/hc11dasm.h b/src/devices/cpu/mc68hc11/hc11dasm.h new file mode 100644 index 00000000000..d1c606a964d --- /dev/null +++ b/src/devices/cpu/mc68hc11/hc11dasm.h @@ -0,0 +1,55 @@ +// license:BSD-3-Clause +// copyright-holders:Ville Linde +/* + Motorola M68HC11 disassembler + + Written by Ville Linde +*/ + +#ifndef MAME_CPU_MC68HC11_HC11DASM_H +#define MAME_CPU_MC68HC11_HC11DASM_H + +#pragma once + +class hc11_disassembler : public util::disasm_interface +{ +public: + hc11_disassembler() = default; + virtual ~hc11_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum + { + EA_IMM8 = 1, + EA_IMM16, + EA_EXT, + EA_REL, + EA_DIRECT, + EA_DIRECT_IMM8, + EA_DIRECT_IMM8_REL, + EA_IND_X, + EA_IND_X_IMM8, + EA_IND_X_IMM8_REL, + EA_IND_Y, + EA_IND_Y_IMM8, + EA_IND_Y_IMM8_REL, + PAGE2, + PAGE3, + PAGE4 + }; + + struct M68HC11_OPCODE { + char mnemonic[32]; + int address_mode; + }; + + static const M68HC11_OPCODE opcode_table[256]; + static const M68HC11_OPCODE opcode_table_page2[256]; + static const M68HC11_OPCODE opcode_table_page3[256]; + static const M68HC11_OPCODE opcode_table_page4[256]; +}; + +#endif diff --git a/src/devices/cpu/mc68hc11/mc68hc11.cpp b/src/devices/cpu/mc68hc11/mc68hc11.cpp index 1ecd2793529..76d4ef56c56 100644 --- a/src/devices/cpu/mc68hc11/mc68hc11.cpp +++ b/src/devices/cpu/mc68hc11/mc68hc11.cpp @@ -16,6 +16,7 @@ TODO: #include "emu.h" #include "debugger.h" #include "mc68hc11.h" +#include "hc11dasm.h" enum { @@ -61,10 +62,9 @@ device_memory_interface::space_config_vector mc68hc11_cpu_device::memory_space_c }; } -offs_t mc68hc11_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *mc68hc11_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( hc11 ); - return CPU_DISASSEMBLE_NAME(hc11)(this, stream, pc, oprom, opram, options); + return new hc11_disassembler; } @@ -397,7 +397,7 @@ void mc68hc11_cpu_device::device_start() m_internal_ram.resize(m_internal_ram_size); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); save_item(NAME(m_pc)); diff --git a/src/devices/cpu/mc68hc11/mc68hc11.h b/src/devices/cpu/mc68hc11/mc68hc11.h index e2a1f52f3d7..35b0cb98170 100644 --- a/src/devices/cpu/mc68hc11/mc68hc11.h +++ b/src/devices/cpu/mc68hc11/mc68hc11.h @@ -70,9 +70,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 5; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -102,7 +100,7 @@ private: int m_ad_channel; uint8_t m_irq_state[2]; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_program; address_space *m_io; int m_icount; diff --git a/src/devices/cpu/mcs40/mcs40.cpp b/src/devices/cpu/mcs40/mcs40.cpp index 866587579d3..be4b60cde75 100644 --- a/src/devices/cpu/mcs40/mcs40.cpp +++ b/src/devices/cpu/mcs40/mcs40.cpp @@ -9,6 +9,7 @@ *****************************************************************************/ #include "emu.h" #include "mcs40.h" +#include "mcs40dasm.h" #include "debugger.h" @@ -141,7 +142,7 @@ void mcs40_cpu_device_base::device_start() m_spaces[AS_RAM_STATUS] = &space(AS_RAM_STATUS); m_spaces[AS_RAM_PORTS] = &space(AS_RAM_PORTS); m_spaces[AS_PROGRAM_MEMORY] = &space(AS_PROGRAM_MEMORY); - m_direct = &m_spaces[AS_ROM]->direct(); + m_direct = m_spaces[AS_ROM]->direct<0>(); m_bus_cycle_cb.bind_relative_to(*owner()); m_sync_cb.resolve_safe(); @@ -416,21 +417,6 @@ void mcs40_cpu_device_base::state_string_export(device_state_entry const &entry, /*********************************************************************** - device_disasm_interface implementation -***********************************************************************/ - -u32 mcs40_cpu_device_base::disasm_min_opcode_bytes() const -{ - return 1U; -} - -u32 mcs40_cpu_device_base::disasm_max_opcode_bytes() const -{ - return 2U; -} - - -/*********************************************************************** register access ***********************************************************************/ @@ -874,15 +860,9 @@ void i4004_cpu_device::execute_set_input(int inputnum, int state) device_disasm_interface implementation ***********************************************************************/ -offs_t i4004_cpu_device::disasm_disassemble( - std::ostream &stream, - offs_t pc, - uint8_t const *oprom, - uint8_t const *opram, - uint32_t options) +util::disasm_interface *i4004_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE(i4004); - return CPU_DISASSEMBLE_NAME(i4004)(this, stream, pc, oprom, opram, options); + return new i4004_disassembler; } @@ -1190,15 +1170,9 @@ void i4040_cpu_device::execute_set_input(int inputnum, int state) device_disasm_interface implementation ***********************************************************************/ -offs_t i4040_cpu_device::disasm_disassemble( - std::ostream &stream, - offs_t pc, - uint8_t const *oprom, - uint8_t const *opram, - uint32_t options) +util::disasm_interface *i4040_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE(i4040); - return CPU_DISASSEMBLE_NAME(i4040)(this, stream, pc, oprom, opram, options); + return new i4040_disassembler; } diff --git a/src/devices/cpu/mcs40/mcs40.h b/src/devices/cpu/mcs40/mcs40.h index 42302263d50..0e5b0c61126 100644 --- a/src/devices/cpu/mcs40/mcs40.h +++ b/src/devices/cpu/mcs40/mcs40.h @@ -200,10 +200,6 @@ protected: virtual void state_export(device_state_entry const &entry) override; virtual void state_string_export(device_state_entry const &entry, std::string &str) const override; - // device_disasm_interface implementation - virtual u32 disasm_min_opcode_bytes() const override; - virtual u32 disasm_max_opcode_bytes() const override; - // instruction execution virtual bool is_io_op(u8 opr) = 0; virtual cycle do_cycle1(u8 opr, u8 opa, pmem &program_op) = 0; @@ -295,7 +291,7 @@ private: // address spaces address_space_config const m_space_config[7]; address_space *m_spaces[7]; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; // bus snooping callback bus_cycle_delegate m_bus_cycle_cb; @@ -378,12 +374,7 @@ protected: virtual void execute_set_input(int inputnum, int state) override; // device_disasm_interface implementation - virtual offs_t disasm_disassemble( - std::ostream &stream, - offs_t pc, - uint8_t const *oprom, - uint8_t const *opram, - uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // mcs40_cpu_device_base implementation virtual bool is_io_op(u8 opr) override; @@ -417,12 +408,7 @@ public: protected: // device_disasm_interface implementation - virtual offs_t disasm_disassemble( - std::ostream &stream, - offs_t pc, - uint8_t const *oprom, - uint8_t const *opram, - uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // device_execute_interface implementation virtual u32 execute_input_lines() const override; diff --git a/src/devices/cpu/mcs40/mcs40dasm.cpp b/src/devices/cpu/mcs40/mcs40dasm.cpp index 3ecf5712308..d0afd6e99a4 100644 --- a/src/devices/cpu/mcs40/mcs40dasm.cpp +++ b/src/devices/cpu/mcs40/mcs40dasm.cpp @@ -9,96 +9,69 @@ *****************************************************************************/ #include "emu.h" +#include "mcs40dasm.h" -namespace { - -enum class format -{ - ILL, - SIMPLE, - IMM4, - REG, - REGPAGE, - PAIR, - PAIRIMM, - ABS, - PAGE, - COND, - EXT -}; - -enum class level -{ - I4004, - I4040 -}; - -struct op -{ - format m_format; - level m_level; - char const *m_name; - op const *m_ext; -}; #define OP(fmt, lvl, name) { format::fmt, level::lvl, #name, nullptr } #define OPX(tbl) { format::EXT, level::I4004, nullptr, f_opx_##tbl } -op const f_opx_0[16] = { +mcs40_disassembler::op const mcs40_disassembler::f_opx_0[16] = { OP(SIMPLE, I4004, nop), OP(SIMPLE, I4040, hlt), OP(SIMPLE, I4040, bbs), OP(SIMPLE, I4040, lcr), OP(SIMPLE, I4040, or4), OP(SIMPLE, I4040, or5), OP(SIMPLE, I4040, an6), OP(SIMPLE, I4040, an7), OP(SIMPLE, I4040, db0), OP(SIMPLE, I4040, db1), OP(SIMPLE, I4040, sb0), OP(SIMPLE, I4040, sb1), OP(SIMPLE, I4040, ein), OP(SIMPLE, I4040, din), OP(SIMPLE, I4040, rpm), OP(ILL, I4004, ill) }; -op const f_opx_2[16] = { +mcs40_disassembler::op const mcs40_disassembler::f_opx_2[16] = { OP(PAIRIMM, I4004, fim), OP(PAIR, I4004, src), OP(PAIRIMM, I4004, fim), OP(PAIR, I4004, src), OP(PAIRIMM, I4004, fim), OP(PAIR, I4004, src), OP(PAIRIMM, I4004, fim), OP(PAIR, I4004, src), OP(PAIRIMM, I4004, fim), OP(PAIR, I4004, src), OP(PAIRIMM, I4004, fim), OP(PAIR, I4004, src), OP(PAIRIMM, I4004, fim), OP(PAIR, I4004, src), OP(PAIRIMM, I4004, fim), OP(PAIR, I4004, src) }; -op const f_opx_3[16] = { +mcs40_disassembler::op const mcs40_disassembler::f_opx_3[16] = { OP(PAIR, I4004, fin), OP(PAIR, I4004, jin), OP(PAIR, I4004, fin), OP(PAIR, I4004, jin), OP(PAIR, I4004, fin), OP(PAIR, I4004, jin), OP(PAIR, I4004, fin), OP(PAIR, I4004, jin), OP(PAIR, I4004, fin), OP(PAIR, I4004, jin), OP(PAIR, I4004, fin), OP(PAIR, I4004, jin), OP(PAIR, I4004, fin), OP(PAIR, I4004, jin), OP(PAIR, I4004, fin), OP(PAIR, I4004, jin) }; -op const f_opx_io[16] = { +mcs40_disassembler::op const mcs40_disassembler::f_opx_io[16] = { OP(SIMPLE, I4004, wrm), OP(SIMPLE, I4004, wmp), OP(SIMPLE, I4004, wrr), OP(SIMPLE, I4004, wpm), OP(SIMPLE, I4004, wr0), OP(SIMPLE, I4004, wr1), OP(SIMPLE, I4004, wr2), OP(SIMPLE, I4004, wr3), OP(SIMPLE, I4004, sbm), OP(SIMPLE, I4004, rdm), OP(SIMPLE, I4004, rdr), OP(SIMPLE, I4004, adm), OP(SIMPLE, I4004, rd0), OP(SIMPLE, I4004, rd1), OP(SIMPLE, I4004, rd2), OP(SIMPLE, I4004, rd3) }; -op const f_opx_f[16] = { +mcs40_disassembler::op const mcs40_disassembler::f_opx_f[16] = { OP(SIMPLE, I4004, clb), OP(SIMPLE, I4004, clc), OP(SIMPLE, I4004, iac), OP(SIMPLE, I4004, cmc), OP(SIMPLE, I4004, cma), OP(SIMPLE, I4004, ral), OP(SIMPLE, I4004, rar), OP(SIMPLE, I4004, tcc), OP(SIMPLE, I4004, dac), OP(SIMPLE, I4004, tcs), OP(SIMPLE, I4004, stc), OP(SIMPLE, I4004, daa), OP(SIMPLE, I4004, kbp), OP(SIMPLE, I4004, dcl), OP(ILL, I4004, ill), OP(ILL, I4004, ill) }; -op const f_ops[16] = { +mcs40_disassembler::op const mcs40_disassembler::f_ops[16] = { OPX(0), OP(COND, I4004, jcn), OPX(2), OPX(3), OP(ABS, I4004, jun), OP(ABS, I4004, jms), OP(REG, I4004, inc), OP(REGPAGE, I4004, isz), OP(REG, I4004, add), OP(REG, I4004, sub), OP(REG, I4004, ld ), OP(REG, I4004, xch), OP(IMM4, I4004, bbl), OP(IMM4, I4004, ldm), OPX(io), OPX(f) }; -char const *const f_cond[16] = { +char const *const mcs40_disassembler::f_cond[16] = { "$0", "nt", "c", "$3", "z", "$5", "$6", "$7", "$8", "t", "nc", "$b", "nz", "$d", "$e", "$f" }; -offs_t disassemble( - cpu_device *device, - std::ostream &stream, - offs_t pc, - u8 const *oprom, - u8 const *opram, - int options, - level lvl, - unsigned pcmask) +u32 mcs40_disassembler::opcode_alignment() const +{ + return 1; +} + +mcs40_disassembler::mcs40_disassembler(level lvl, unsigned pcmask) : m_lvl(lvl), m_pcmask(pcmask) +{ + (void)m_pcmask; +} + +offs_t mcs40_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { offs_t npc(pc + 1); - u8 const opcode(oprom[0]); + u8 const opcode(opcodes.r8(pc)); op const &base_op(f_ops[(opcode >> 4) & 0x0f]); op const &ext_op((base_op.m_format == format::EXT) ? base_op.m_ext[opcode & 0x0f] : base_op); - op const desc((ext_op.m_level > lvl) ? f_opx_f[0x0f] : ext_op); + op const desc((ext_op.m_level > m_lvl) ? f_opx_f[0x0f] : ext_op); u8 const imm4(opcode & 0x0f); u8 const pair(opcode & 0x0e); @@ -118,26 +91,26 @@ offs_t disassemble( break; case format::REGPAGE: npc++; - util::stream_format(stream, "%-3s r%01x,$%03x", desc.m_name, imm4, oprom[1] | (npc & 0x0f00U)); + util::stream_format(stream, "%-3s r%01x,$%03x", desc.m_name, imm4, opcodes.r8(pc+1) | (npc & 0x0f00U)); break; case format::PAIR: util::stream_format(stream, "%-3s r%01xr%01x", desc.m_name, pair, pair + 1U); break; case format::PAIRIMM: npc++; - util::stream_format(stream, "%-3s r%01xr%01x,$%02x", desc.m_name, pair, pair + 1, oprom[1]); + util::stream_format(stream, "%-3s r%01xr%01x,$%02x", desc.m_name, pair, pair + 1, opcodes.r8(pc+1)); break; case format::ABS: npc++; - util::stream_format(stream, "%-3s $%03x", desc.m_name, ((u16(opcode) & 0x0fU) << 8) | oprom[1]); + util::stream_format(stream, "%-3s $%03x", desc.m_name, ((u16(opcode) & 0x0fU) << 8) | opcodes.r8(pc+1)); break; case format::PAGE: npc++; - util::stream_format(stream, "%-3s $%03x", desc.m_name, oprom[1] | (npc & 0x0f00U)); + util::stream_format(stream, "%-3s $%03x", desc.m_name, opcodes.r8(pc+1) | (npc & 0x0f00U)); break; case format::COND: npc++; - util::stream_format(stream, "%-3s %s,$%03x", desc.m_name, f_cond[imm4], oprom[1] | (npc & 0x0f00U)); + util::stream_format(stream, "%-3s %s,$%03x", desc.m_name, f_cond[imm4], opcodes.r8(pc+1) | (npc & 0x0f00U)); break; default: throw false; @@ -147,16 +120,19 @@ offs_t disassemble( if (format::ILL != desc.m_format) { if (0x50U == (opcode & 0xf0U)) // JMS - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; else if ((0xc0 == (opcode & 0xf0)) || (0x02 == opcode)) // BBL/BBS - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; } - return (npc - pc) | flags | DASMFLAG_SUPPORTED; + return (npc - pc) | flags | SUPPORTED; } -} // anonymous namespace +i4004_disassembler::i4004_disassembler() : mcs40_disassembler(level::I4004, 0x0fffU) +{ +} -CPU_DISASSEMBLE(i4004) { return disassemble(device, stream, pc, oprom, opram, options, level::I4004, 0x0fffU); } -CPU_DISASSEMBLE(i4040) { return disassemble(device, stream, pc, oprom, opram, options, level::I4040, 0x1fffU); } +i4040_disassembler::i4040_disassembler() : mcs40_disassembler(level::I4040, 0x1fffU) +{ +} diff --git a/src/devices/cpu/mcs40/mcs40dasm.h b/src/devices/cpu/mcs40/mcs40dasm.h new file mode 100644 index 00000000000..937b71d9358 --- /dev/null +++ b/src/devices/cpu/mcs40/mcs40dasm.h @@ -0,0 +1,81 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +/***************************************************************************** + * + * 4004dasm.cpp + * + * Intel MCS-40 CPU Disassembly + * + *****************************************************************************/ + +#ifndef MAME_CPU_MCS40_MCS40DASM_H +#define MAME_CPU_MCS40_MCS40DASM_H + +#pragma once + +class mcs40_disassembler : public util::disasm_interface +{ +public: + enum class level + { + I4004, + I4040 + }; + + mcs40_disassembler(level lvl, unsigned pcmask); + virtual ~mcs40_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum class format + { + ILL, + SIMPLE, + IMM4, + REG, + REGPAGE, + PAIR, + PAIRIMM, + ABS, + PAGE, + COND, + EXT + }; + + struct op + { + format m_format; + level m_level; + char const *m_name; + op const *m_ext; + }; + + static op const f_opx_0[16]; + static op const f_opx_2[16]; + static op const f_opx_3[16]; + static op const f_opx_io[16]; + static op const f_opx_f[16]; + static op const f_ops[16]; + static char const *const f_cond[16]; + + level m_lvl; + unsigned m_pcmask; +}; + +class i4004_disassembler : public mcs40_disassembler +{ +public: + i4004_disassembler(); + virtual ~i4004_disassembler() = default; +}; + +class i4040_disassembler : public mcs40_disassembler +{ +public: + i4040_disassembler(); + virtual ~i4040_disassembler() = default; +}; + +#endif diff --git a/src/devices/cpu/mcs48/mcs48.cpp b/src/devices/cpu/mcs48/mcs48.cpp index affcff6a09d..de499c23ac2 100644 --- a/src/devices/cpu/mcs48/mcs48.cpp +++ b/src/devices/cpu/mcs48/mcs48.cpp @@ -7,7 +7,13 @@ reimplement as a push, not a pull - T0 output clock - get rid of i/o addressmap, use devcb for mcu pins - - add CMOS devices, 1 new opcode(01 HALT) + - add CMOS devices, 1 new opcode (01 HALT) + - make timer update cleaner: + timer is updated on S4 while I/O happens on S5 + due to very bad coding, Kaypro 10 keyboard depends on being able to see T=0 before interrupt is taken + right now this is implemented with a hack in the mov_a_t handler + in theory it should also be possible to see the timer flag before the interrupt is taken + mov_t_a should also update the T register after it's incremented */ /*************************************************************************** @@ -79,6 +85,7 @@ #include "emu.h" #include "debugger.h" #include "mcs48.h" +#include "mcs48dsm.h" /*************************************************************************** @@ -121,24 +128,6 @@ MACROS ***************************************************************************/ -/* ROM is mapped to AS_PROGRAM */ -#define program_r(a) m_program->read_byte(a) - -/* RAM is mapped to AS_DATA */ -#define ram_r(a) m_data->read_byte(a) -#define ram_w(a,V) m_data->write_byte(a, V) - -/* ports are mapped to AS_IO and callbacks */ -#define ext_r(a) m_io->read_byte(a) -#define ext_w(a,V) m_io->write_byte(a, V) -#define port_r(a) m_port_in_cb[a-1]() -#define port_w(a,V) m_port_out_cb[a-1](V) -#define test_r(a) m_test_in_cb[a]() -#define test_w(a,V) m_test_out_cb[a](V) -#define bus_r() m_bus_in_cb() -#define bus_w(V) m_bus_out_cb(V) -#define prog_w(V) m_prog_out_cb(V) - /* r0-r7 map to memory via the regptr */ #define R0 m_regptr[0] #define R1 m_regptr[1] @@ -151,24 +140,24 @@ -DEFINE_DEVICE_TYPE(I8021, i8021_device, "i8021", "I8021") -DEFINE_DEVICE_TYPE(I8022, i8022_device, "i8022", "I8022") -DEFINE_DEVICE_TYPE(I8035, i8035_device, "i8035", "I8035") -DEFINE_DEVICE_TYPE(I8048, i8048_device, "i8048", "I8048") -DEFINE_DEVICE_TYPE(I8648, i8648_device, "i8648", "I8648") -DEFINE_DEVICE_TYPE(I8748, i8748_device, "i8748", "I8748") -DEFINE_DEVICE_TYPE(I8039, i8039_device, "i8039", "I8039") -DEFINE_DEVICE_TYPE(I8049, i8049_device, "i8049", "I8049") -DEFINE_DEVICE_TYPE(I8749, i8749_device, "i8749", "I8749") -DEFINE_DEVICE_TYPE(I8040, i8040_device, "i8040", "I8040") -DEFINE_DEVICE_TYPE(I8050, i8050_device, "i8050", "I8050") -DEFINE_DEVICE_TYPE(I8041, i8041_device, "i8041", "I8041") -DEFINE_DEVICE_TYPE(I8741, i8741_device, "i8741", "I8741") -DEFINE_DEVICE_TYPE(I8042, i8042_device, "i8042", "I8042") -DEFINE_DEVICE_TYPE(I8242, i8242_device, "i8242", "I8242") -DEFINE_DEVICE_TYPE(I8742, i8742_device, "i8742", "I8742") +DEFINE_DEVICE_TYPE(I8021, i8021_device, "i8021", "I8021") +DEFINE_DEVICE_TYPE(I8022, i8022_device, "i8022", "I8022") +DEFINE_DEVICE_TYPE(I8035, i8035_device, "i8035", "I8035") +DEFINE_DEVICE_TYPE(I8048, i8048_device, "i8048", "I8048") +DEFINE_DEVICE_TYPE(I8648, i8648_device, "i8648", "I8648") +DEFINE_DEVICE_TYPE(I8748, i8748_device, "i8748", "I8748") +DEFINE_DEVICE_TYPE(I8039, i8039_device, "i8039", "I8039") +DEFINE_DEVICE_TYPE(I8049, i8049_device, "i8049", "I8049") +DEFINE_DEVICE_TYPE(I8749, i8749_device, "i8749", "I8749") +DEFINE_DEVICE_TYPE(I8040, i8040_device, "i8040", "I8040") +DEFINE_DEVICE_TYPE(I8050, i8050_device, "i8050", "I8050") +DEFINE_DEVICE_TYPE(I8041, i8041_device, "i8041", "I8041") +DEFINE_DEVICE_TYPE(I8741, i8741_device, "i8741", "I8741") +DEFINE_DEVICE_TYPE(I8042, i8042_device, "i8042", "I8042") +DEFINE_DEVICE_TYPE(I8242, i8242_device, "i8242", "I8242") +DEFINE_DEVICE_TYPE(I8742, i8742_device, "i8742", "I8742") DEFINE_DEVICE_TYPE(MB8884, mb8884_device, "mb8884", "MB8884") -DEFINE_DEVICE_TYPE(N7751, n7751_device, "n7751", "N7751") +DEFINE_DEVICE_TYPE(N7751, n7751_device, "n7751", "N7751") DEFINE_DEVICE_TYPE(M58715, m58715_device, "m58715", "M58715") @@ -341,17 +330,14 @@ device_memory_interface::space_config_vector mcs48_cpu_device::memory_space_conf }; } -offs_t mcs48_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *mcs48_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( mcs48 ); - return CPU_DISASSEMBLE_NAME(mcs48)(this, stream, pc, oprom, opram, options); + return new mcs48_disassembler(false); } - -offs_t upi41_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *upi41_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( upi41 ); - return CPU_DISASSEMBLE_NAME(upi41)(this, stream, pc, oprom, opram, options); + return new mcs48_disassembler(true); } /*************************************************************************** @@ -756,7 +742,7 @@ OPHANDLER( mov_a_r6 ) { m_a = R6; return 1; } OPHANDLER( mov_a_r7 ) { m_a = R7; return 1; } OPHANDLER( mov_a_xr0 ) { m_a = ram_r(R0); return 1; } OPHANDLER( mov_a_xr1 ) { m_a = ram_r(R1); return 1; } -OPHANDLER( mov_a_t ) { m_a = m_timer; return 1; } +OPHANDLER( mov_a_t ) { m_a = m_timer + ((m_timecount_enabled & TIMER_ENABLED) ? 1 : 0); return 1; } OPHANDLER( mov_psw_a ) { m_psw = m_a; update_regptr(); return 1; } OPHANDLER( mov_sts_a ) { m_sts = (m_sts & 0x0f) | (m_a & 0xf0); return 1; } @@ -987,7 +973,7 @@ void mcs48_cpu_device::device_start() m_ea = (m_int_rom_size ? 0 : 1); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_data = &space(AS_DATA); m_io = &space(AS_IO); diff --git a/src/devices/cpu/mcs48/mcs48.h b/src/devices/cpu/mcs48/mcs48.h index 4c915256152..e0609621559 100644 --- a/src/devices/cpu/mcs48/mcs48.h +++ b/src/devices/cpu/mcs48/mcs48.h @@ -180,9 +180,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 2; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; protected: address_space_config m_program_config; @@ -230,7 +228,7 @@ protected: /* Memory spaces */ address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_data; address_space *m_io; @@ -242,6 +240,23 @@ protected: typedef int (mcs48_cpu_device::*mcs48_ophandler)(); static const mcs48_ophandler s_opcode_table[256]; + /* ROM is mapped to AS_PROGRAM */ + uint8_t program_r(offs_t a) { return m_program->read_byte(a); } + + /* RAM is mapped to AS_DATA */ + uint8_t ram_r(offs_t a) { return m_data->read_byte(a); } + void ram_w(offs_t a, uint8_t v) { m_data->write_byte(a, v); } + + /* ports are mapped to AS_IO and callbacks */ + uint8_t ext_r(offs_t a) { return m_io->read_byte(a); } + void ext_w(offs_t a, uint8_t v) { m_io->write_byte(a, v); } + uint8_t port_r(offs_t a) { return m_port_in_cb[a - 1](); } + void port_w(offs_t a, uint8_t v) { m_port_out_cb[a - 1](v); } + int test_r(offs_t a) { return m_test_in_cb[a](); } + uint8_t bus_r() { return m_bus_in_cb(); } + void bus_w(uint8_t v) { m_bus_out_cb(v); } + void prog_w(int v) { m_prog_out_cb(v); } + uint8_t opcode_fetch(); uint8_t argument_fetch(); void update_regptr(); @@ -633,7 +648,7 @@ protected: // construction/destruction upi41_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int rom_size, int ram_size); - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; TIMER_CALLBACK_MEMBER( master_callback ); }; diff --git a/src/devices/cpu/mcs48/mcs48dsm.cpp b/src/devices/cpu/mcs48/mcs48dsm.cpp index 08afa12f6b3..e265e83534e 100644 --- a/src/devices/cpu/mcs48/mcs48dsm.cpp +++ b/src/devices/cpu/mcs48/mcs48dsm.cpp @@ -10,27 +10,35 @@ ***************************************************************************/ #include "emu.h" +#include "mcs48dsm.h" +mcs48_disassembler::mcs48_disassembler(bool upi41) : m_upi41(upi41) +{ +} -static uint32_t common_dasm(device_t *device, std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, bool upi41) +u32 mcs48_disassembler::opcode_alignment() const { - const uint8_t *startram = opram; - uint32_t flags = 0; + return 1; +} - opram++; - switch (*oprom++) +offs_t mcs48_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + offs_t cpc = pc; + offs_t flags = 0; + + switch (opcodes.r8(cpc++)) { case 0x00: util::stream_format(stream, "nop"); break; - case 0x02: if (!upi41) + case 0x02: if (!m_upi41) util::stream_format(stream, "out bus,a"); else util::stream_format(stream, "out dbb,a"); break; - case 0x03: util::stream_format(stream, "add a,#$%02X", *opram++); break; - case 0x04: util::stream_format(stream, "jmp $0%02X", *opram++); break; + case 0x03: util::stream_format(stream, "add a,#$%02X", params.r8(cpc++)); break; + case 0x04: util::stream_format(stream, "jmp $0%02X", params.r8(cpc++)); break; case 0x05: util::stream_format(stream, "en i"); break; case 0x07: util::stream_format(stream, "dec a"); break; - case 0x08: if (!upi41) + case 0x08: if (!m_upi41) util::stream_format(stream, "in a,bus"); else util::stream_format(stream, "illegal"); @@ -43,11 +51,11 @@ static uint32_t common_dasm(device_t *device, std::ostream &stream, offs_t pc, c case 0x0f: util::stream_format(stream, "movd a,p7"); break; case 0x10: util::stream_format(stream, "inc @r0"); break; case 0x11: util::stream_format(stream, "inc @r1"); break; - case 0x12: util::stream_format(stream, "jb0 $%03X", (pc & 0xf00) | *opram++); break; - case 0x13: util::stream_format(stream, "addc a,#$%02X", *opram++); break; - case 0x14: util::stream_format(stream, "call $0%02X", *opram++); flags = DASMFLAG_STEP_OVER; break; + case 0x12: util::stream_format(stream, "jb0 $%03X", (pc & 0xf00) | params.r8(cpc++)); break; + case 0x13: util::stream_format(stream, "addc a,#$%02X", params.r8(cpc++)); break; + case 0x14: util::stream_format(stream, "call $0%02X", params.r8(cpc++)); flags = STEP_OVER; break; case 0x15: util::stream_format(stream, "dis i"); break; - case 0x16: util::stream_format(stream, "jtf $%03X", (pc & 0xf00) | *opram++); break; + case 0x16: util::stream_format(stream, "jtf $%03X", (pc & 0xf00) | params.r8(cpc++)); break; case 0x17: util::stream_format(stream, "inc a"); break; case 0x18: util::stream_format(stream, "inc r0"); break; case 0x19: util::stream_format(stream, "inc r1"); break; @@ -59,15 +67,15 @@ static uint32_t common_dasm(device_t *device, std::ostream &stream, offs_t pc, c case 0x1f: util::stream_format(stream, "inc r7"); break; case 0x20: util::stream_format(stream, "xch a,@r0"); break; case 0x21: util::stream_format(stream, "xch a,@r1"); break; - case 0x22: if (!upi41) + case 0x22: if (!m_upi41) util::stream_format(stream, "illegal"); else util::stream_format(stream, "in a,dbb"); break; - case 0x23: util::stream_format(stream, "mov a,#$%02X", *opram++); break; - case 0x24: util::stream_format(stream, "jmp $1%02X", *opram++); break; + case 0x23: util::stream_format(stream, "mov a,#$%02X", params.r8(cpc++)); break; + case 0x24: util::stream_format(stream, "jmp $1%02X", params.r8(cpc++)); break; case 0x25: util::stream_format(stream, "en tcnti"); break; - case 0x26: util::stream_format(stream, "jnt0 $%03X", (pc & 0xf00) | *opram++); break; + case 0x26: util::stream_format(stream, "jnt0 $%03X", (pc & 0xf00) | params.r8(cpc++)); break; case 0x27: util::stream_format(stream, "clr a"); break; case 0x28: util::stream_format(stream, "xch a,r0"); break; case 0x29: util::stream_format(stream, "xch a,r1"); break; @@ -79,10 +87,10 @@ static uint32_t common_dasm(device_t *device, std::ostream &stream, offs_t pc, c case 0x2f: util::stream_format(stream, "xch a,r7"); break; case 0x30: util::stream_format(stream, "xchd a,@r0"); break; case 0x31: util::stream_format(stream, "xchd a,@r1"); break; - case 0x32: util::stream_format(stream, "jb1 $%03X", (pc & 0xf00) | *opram++); break; - case 0x34: util::stream_format(stream, "call $1%02X", *opram++); flags = DASMFLAG_STEP_OVER; break; + case 0x32: util::stream_format(stream, "jb1 $%03X", (pc & 0xf00) | params.r8(cpc++)); break; + case 0x34: util::stream_format(stream, "call $1%02X", params.r8(cpc++)); flags = STEP_OVER; break; case 0x35: util::stream_format(stream, "dis tcnti"); break; - case 0x36: util::stream_format(stream, "jt0 $%03X", (pc & 0xf00) | *opram++); break; + case 0x36: util::stream_format(stream, "jt0 $%03X", (pc & 0xf00) | params.r8(cpc++)); break; case 0x37: util::stream_format(stream, "cpl a"); break; case 0x39: util::stream_format(stream, "outl p1,a"); break; case 0x3a: util::stream_format(stream, "outl p2,a"); break; @@ -93,10 +101,10 @@ static uint32_t common_dasm(device_t *device, std::ostream &stream, offs_t pc, c case 0x40: util::stream_format(stream, "orl a,@r0"); break; case 0x41: util::stream_format(stream, "orl a,@r1"); break; case 0x42: util::stream_format(stream, "mov a,t"); break; - case 0x43: util::stream_format(stream, "orl a,#$%02X", *opram++); break; - case 0x44: util::stream_format(stream, "jmp $2%02X", *opram++); break; + case 0x43: util::stream_format(stream, "orl a,#$%02X", params.r8(cpc++)); break; + case 0x44: util::stream_format(stream, "jmp $2%02X", params.r8(cpc++)); break; case 0x45: util::stream_format(stream, "strt cnt"); break; - case 0x46: util::stream_format(stream, "jnt1 $%03X", (pc & 0xf00) | *opram++); break; + case 0x46: util::stream_format(stream, "jnt1 $%03X", (pc & 0xf00) | params.r8(cpc++)); break; case 0x47: util::stream_format(stream, "swap a"); break; case 0x48: util::stream_format(stream, "orl a,r0"); break; case 0x49: util::stream_format(stream, "orl a,r1"); break; @@ -108,11 +116,11 @@ static uint32_t common_dasm(device_t *device, std::ostream &stream, offs_t pc, c case 0x4f: util::stream_format(stream, "orl a,r7"); break; case 0x50: util::stream_format(stream, "anl a,@r0"); break; case 0x51: util::stream_format(stream, "anl a,@r1"); break; - case 0x52: util::stream_format(stream, "jb2 $%03X", (pc & 0xf00) | *opram++); break; - case 0x53: util::stream_format(stream, "anl a,#$%02X", *opram++); break; - case 0x54: util::stream_format(stream, "call $2%02X", *opram++); flags = DASMFLAG_STEP_OVER; break; + case 0x52: util::stream_format(stream, "jb2 $%03X", (pc & 0xf00) | params.r8(cpc++)); break; + case 0x53: util::stream_format(stream, "anl a,#$%02X", params.r8(cpc++)); break; + case 0x54: util::stream_format(stream, "call $2%02X", params.r8(cpc++)); flags = STEP_OVER; break; case 0x55: util::stream_format(stream, "strt t"); break; - case 0x56: util::stream_format(stream, "jt1 $%03X", (pc & 0xf00) | *opram++); break; + case 0x56: util::stream_format(stream, "jt1 $%03X", (pc & 0xf00) | params.r8(cpc++)); break; case 0x57: util::stream_format(stream, "da a"); break; case 0x58: util::stream_format(stream, "anl a,r0"); break; case 0x59: util::stream_format(stream, "anl a,r1"); break; @@ -125,7 +133,7 @@ static uint32_t common_dasm(device_t *device, std::ostream &stream, offs_t pc, c case 0x60: util::stream_format(stream, "add a,@r0"); break; case 0x61: util::stream_format(stream, "add a,@r1"); break; case 0x62: util::stream_format(stream, "mov t,a"); break; - case 0x64: util::stream_format(stream, "jmp $3%02X", *opram++); break; + case 0x64: util::stream_format(stream, "jmp $3%02X", params.r8(cpc++)); break; case 0x65: util::stream_format(stream, "stop tcnt"); break; case 0x67: util::stream_format(stream, "rrc a"); break; case 0x68: util::stream_format(stream, "add a,r0"); break; @@ -138,14 +146,14 @@ static uint32_t common_dasm(device_t *device, std::ostream &stream, offs_t pc, c case 0x6f: util::stream_format(stream, "add a,r7"); break; case 0x70: util::stream_format(stream, "addc a,@r0"); break; case 0x71: util::stream_format(stream, "addc a,@r1"); break; - case 0x72: util::stream_format(stream, "jb3 $%03X", (pc & 0xf00) | *opram++); break; - case 0x74: util::stream_format(stream, "call $3%02X", *opram++); flags = DASMFLAG_STEP_OVER; break; - case 0x75: if (!upi41) + case 0x72: util::stream_format(stream, "jb3 $%03X", (pc & 0xf00) | params.r8(cpc++)); break; + case 0x74: util::stream_format(stream, "call $3%02X", params.r8(cpc++)); flags = STEP_OVER; break; + case 0x75: if (!m_upi41) util::stream_format(stream, "ent0 clk"); else util::stream_format(stream, "illegal"); break; - case 0x76: util::stream_format(stream, "jf1 $%03X", (pc & 0xf00) | *opram++); break; + case 0x76: util::stream_format(stream, "jf1 $%03X", (pc & 0xf00) | params.r8(cpc++)); break; case 0x77: util::stream_format(stream, "rr a"); break; case 0x78: util::stream_format(stream, "addc a,r0"); break; case 0x79: util::stream_format(stream, "addc a,r1"); break; @@ -155,58 +163,58 @@ static uint32_t common_dasm(device_t *device, std::ostream &stream, offs_t pc, c case 0x7d: util::stream_format(stream, "addc a,r5"); break; case 0x7e: util::stream_format(stream, "addc a,r6"); break; case 0x7f: util::stream_format(stream, "addc a,r7"); break; - case 0x80: if (!upi41) + case 0x80: if (!m_upi41) util::stream_format(stream, "movx a,@r0"); else util::stream_format(stream, "illegal"); break; - case 0x81: if (!upi41) + case 0x81: if (!m_upi41) util::stream_format(stream, "movx a,@r1"); else util::stream_format(stream, "illegal"); break; - case 0x83: util::stream_format(stream, "ret"); flags = DASMFLAG_STEP_OUT; break; - case 0x84: util::stream_format(stream, "jmp $4%02X", *opram++); break; + case 0x83: util::stream_format(stream, "ret"); flags = STEP_OUT; break; + case 0x84: util::stream_format(stream, "jmp $4%02X", params.r8(cpc++)); break; case 0x85: util::stream_format(stream, "clr f0"); break; - case 0x86: if (!upi41) - util::stream_format(stream, "jni $%03X", (pc & 0xf00) | *opram++); + case 0x86: if (!m_upi41) + util::stream_format(stream, "jni $%03X", (pc & 0xf00) | params.r8(cpc++)); else - util::stream_format(stream, "jobf $%03X", (pc & 0xf00) | *opram++); + util::stream_format(stream, "jobf $%03X", (pc & 0xf00) | params.r8(cpc++)); break; - case 0x88: if (!upi41) - util::stream_format(stream, "orl bus,#$%02X", *opram++); + case 0x88: if (!m_upi41) + util::stream_format(stream, "orl bus,#$%02X", params.r8(cpc++)); else util::stream_format(stream, "illegal"); break; - case 0x89: util::stream_format(stream, "orl p1,#$%02X", *opram++); break; - case 0x8a: util::stream_format(stream, "orl p2,#$%02X", *opram++); break; + case 0x89: util::stream_format(stream, "orl p1,#$%02X", params.r8(cpc++)); break; + case 0x8a: util::stream_format(stream, "orl p2,#$%02X", params.r8(cpc++)); break; case 0x8c: util::stream_format(stream, "orld p4,a"); break; case 0x8d: util::stream_format(stream, "orld p5,a"); break; case 0x8e: util::stream_format(stream, "orld p6,a"); break; case 0x8f: util::stream_format(stream, "orld p7,a"); break; - case 0x90: if (!upi41) + case 0x90: if (!m_upi41) util::stream_format(stream, "movx @r0,a"); else util::stream_format(stream, "mov sts,a"); break; - case 0x91: if (!upi41) + case 0x91: if (!m_upi41) util::stream_format(stream, "movx @r1,a"); else util::stream_format(stream, "illegal"); break; - case 0x92: util::stream_format(stream, "jb4 $%03X", (pc & 0xf00) | *opram++); break; - case 0x93: util::stream_format(stream, "retr"); flags = DASMFLAG_STEP_OUT; break; - case 0x94: util::stream_format(stream, "call $4%02X", *opram++); flags = DASMFLAG_STEP_OVER; break; + case 0x92: util::stream_format(stream, "jb4 $%03X", (pc & 0xf00) | params.r8(cpc++)); break; + case 0x93: util::stream_format(stream, "retr"); flags = STEP_OUT; break; + case 0x94: util::stream_format(stream, "call $4%02X", params.r8(cpc++)); flags = STEP_OVER; break; case 0x95: util::stream_format(stream, "cpl f0"); break; - case 0x96: util::stream_format(stream, "jnz $%03X", (pc & 0xf00) | *opram++); break; + case 0x96: util::stream_format(stream, "jnz $%03X", (pc & 0xf00) | params.r8(cpc++)); break; case 0x97: util::stream_format(stream, "clr c"); break; - case 0x98: if (!upi41) - util::stream_format(stream, "anl bus,#$%02X", *opram++); + case 0x98: if (!m_upi41) + util::stream_format(stream, "anl bus,#$%02X", params.r8(cpc++)); else util::stream_format(stream, "illegal"); break; - case 0x99: util::stream_format(stream, "anl p1,#$%02X", *opram++); break; - case 0x9a: util::stream_format(stream, "anl p2,#$%02X", *opram++); break; + case 0x99: util::stream_format(stream, "anl p1,#$%02X", params.r8(cpc++)); break; + case 0x9a: util::stream_format(stream, "anl p2,#$%02X", params.r8(cpc++)); break; case 0x9c: util::stream_format(stream, "anld p4,a"); break; case 0x9d: util::stream_format(stream, "anld p5,a"); break; case 0x9e: util::stream_format(stream, "anld p6,a"); break; @@ -214,7 +222,7 @@ static uint32_t common_dasm(device_t *device, std::ostream &stream, offs_t pc, c case 0xa0: util::stream_format(stream, "mov @r0,a"); break; case 0xa1: util::stream_format(stream, "mov @r1,a"); break; case 0xa3: util::stream_format(stream, "movp a,@a"); break; - case 0xa4: util::stream_format(stream, "jmp $5%02X", *opram++); break; + case 0xa4: util::stream_format(stream, "jmp $5%02X", params.r8(cpc++)); break; case 0xa5: util::stream_format(stream, "clr f1"); break; case 0xa7: util::stream_format(stream, "cpl c"); break; case 0xa8: util::stream_format(stream, "mov r0,a"); break; @@ -225,24 +233,24 @@ static uint32_t common_dasm(device_t *device, std::ostream &stream, offs_t pc, c case 0xad: util::stream_format(stream, "mov r5,a"); break; case 0xae: util::stream_format(stream, "mov r6,a"); break; case 0xaf: util::stream_format(stream, "mov r7,a"); break; - case 0xb0: util::stream_format(stream, "mov @r0,#$%02X", *opram++); break; - case 0xb1: util::stream_format(stream, "mov @r1,#$%02X", *opram++); break; - case 0xb2: util::stream_format(stream, "jb5 $%03X", (pc & 0xf00) | *opram++); break; + case 0xb0: util::stream_format(stream, "mov @r0,#$%02X", params.r8(cpc++)); break; + case 0xb1: util::stream_format(stream, "mov @r1,#$%02X", params.r8(cpc++)); break; + case 0xb2: util::stream_format(stream, "jb5 $%03X", (pc & 0xf00) | params.r8(cpc++)); break; case 0xb3: util::stream_format(stream, "jmpp @a"); break; - case 0xb4: util::stream_format(stream, "call $5%02X", *opram++); flags = DASMFLAG_STEP_OVER; break; + case 0xb4: util::stream_format(stream, "call $5%02X", params.r8(cpc++)); flags = STEP_OVER; break; case 0xb5: util::stream_format(stream, "cpl f1"); break; - case 0xb6: util::stream_format(stream, "jf0 $%03X", (pc & 0xf00) | *opram++); break; - case 0xb8: util::stream_format(stream, "mov r0,#$%02X", *opram++); break; - case 0xb9: util::stream_format(stream, "mov r1,#$%02X", *opram++); break; - case 0xba: util::stream_format(stream, "mov r2,#$%02X", *opram++); break; - case 0xbb: util::stream_format(stream, "mov r3,#$%02X", *opram++); break; - case 0xbc: util::stream_format(stream, "mov r4,#$%02X", *opram++); break; - case 0xbd: util::stream_format(stream, "mov r5,#$%02X", *opram++); break; - case 0xbe: util::stream_format(stream, "mov r6,#$%02X", *opram++); break; - case 0xbf: util::stream_format(stream, "mov r7,#$%02X", *opram++); break; - case 0xc4: util::stream_format(stream, "jmp $6%02X", *opram++); break; + case 0xb6: util::stream_format(stream, "jf0 $%03X", (pc & 0xf00) | params.r8(cpc++)); break; + case 0xb8: util::stream_format(stream, "mov r0,#$%02X", params.r8(cpc++)); break; + case 0xb9: util::stream_format(stream, "mov r1,#$%02X", params.r8(cpc++)); break; + case 0xba: util::stream_format(stream, "mov r2,#$%02X", params.r8(cpc++)); break; + case 0xbb: util::stream_format(stream, "mov r3,#$%02X", params.r8(cpc++)); break; + case 0xbc: util::stream_format(stream, "mov r4,#$%02X", params.r8(cpc++)); break; + case 0xbd: util::stream_format(stream, "mov r5,#$%02X", params.r8(cpc++)); break; + case 0xbe: util::stream_format(stream, "mov r6,#$%02X", params.r8(cpc++)); break; + case 0xbf: util::stream_format(stream, "mov r7,#$%02X", params.r8(cpc++)); break; + case 0xc4: util::stream_format(stream, "jmp $6%02X", params.r8(cpc++)); break; case 0xc5: util::stream_format(stream, "sel rb0"); break; - case 0xc6: util::stream_format(stream, "jz $%03X", (pc & 0xf00) | *opram++); break; + case 0xc6: util::stream_format(stream, "jz $%03X", (pc & 0xf00) | params.r8(cpc++)); break; case 0xc7: util::stream_format(stream, "mov a,psw"); break; case 0xc8: util::stream_format(stream, "dec r0"); break; case 0xc9: util::stream_format(stream, "dec r1"); break; @@ -254,14 +262,14 @@ static uint32_t common_dasm(device_t *device, std::ostream &stream, offs_t pc, c case 0xcf: util::stream_format(stream, "dec r7"); break; case 0xd0: util::stream_format(stream, "xrl a,@r0"); break; case 0xd1: util::stream_format(stream, "xrl a,@r1"); break; - case 0xd2: util::stream_format(stream, "jb6 $%03X", (pc & 0xf00) | *opram++); break; - case 0xd3: util::stream_format(stream, "xrl a,#$%02X", *opram++); break; - case 0xd4: util::stream_format(stream, "call $6%02X", *opram++); flags = DASMFLAG_STEP_OVER; break; + case 0xd2: util::stream_format(stream, "jb6 $%03X", (pc & 0xf00) | params.r8(cpc++)); break; + case 0xd3: util::stream_format(stream, "xrl a,#$%02X", params.r8(cpc++)); break; + case 0xd4: util::stream_format(stream, "call $6%02X", params.r8(cpc++)); flags = STEP_OVER; break; case 0xd5: util::stream_format(stream, "sel rb1"); break; - case 0xd6: if (!upi41) + case 0xd6: if (!m_upi41) util::stream_format(stream, "illegal"); else - util::stream_format(stream, "jnibf $%03X", (pc & 0xf00) | *opram++); + util::stream_format(stream, "jnibf $%03X", (pc & 0xf00) | params.r8(cpc++)); break; case 0xd7: util::stream_format(stream, "mov psw,a"); break; case 0xd8: util::stream_format(stream, "xrl a,r0"); break; @@ -273,32 +281,32 @@ static uint32_t common_dasm(device_t *device, std::ostream &stream, offs_t pc, c case 0xde: util::stream_format(stream, "xrl a,r6"); break; case 0xdf: util::stream_format(stream, "xrl a,r7"); break; case 0xe3: util::stream_format(stream, "movp3 a,@a"); break; - case 0xe4: util::stream_format(stream, "jmp $7%02X", *opram++); break; - case 0xe5: if (!upi41) + case 0xe4: util::stream_format(stream, "jmp $7%02X", params.r8(cpc++)); break; + case 0xe5: if (!m_upi41) util::stream_format(stream, "sel mb0"); else util::stream_format(stream, "en dma"); break; - case 0xe6: util::stream_format(stream, "jnc $%03X", (pc & 0xf00) | *opram++); break; + case 0xe6: util::stream_format(stream, "jnc $%03X", (pc & 0xf00) | params.r8(cpc++)); break; case 0xe7: util::stream_format(stream, "rl a"); break; - case 0xe8: util::stream_format(stream, "djnz r0,$%03X", (pc & 0xf00) | *opram++); flags = DASMFLAG_STEP_OVER; break; - case 0xe9: util::stream_format(stream, "djnz r1,$%03X", (pc & 0xf00) | *opram++); flags = DASMFLAG_STEP_OVER; break; - case 0xea: util::stream_format(stream, "djnz r2,$%03X", (pc & 0xf00) | *opram++); flags = DASMFLAG_STEP_OVER; break; - case 0xeb: util::stream_format(stream, "djnz r3,$%03X", (pc & 0xf00) | *opram++); flags = DASMFLAG_STEP_OVER; break; - case 0xec: util::stream_format(stream, "djnz r4,$%03X", (pc & 0xf00) | *opram++); flags = DASMFLAG_STEP_OVER; break; - case 0xed: util::stream_format(stream, "djnz r5,$%03X", (pc & 0xf00) | *opram++); flags = DASMFLAG_STEP_OVER; break; - case 0xee: util::stream_format(stream, "djnz r6,$%03X", (pc & 0xf00) | *opram++); flags = DASMFLAG_STEP_OVER; break; - case 0xef: util::stream_format(stream, "djnz r7,$%03X", (pc & 0xf00) | *opram++); flags = DASMFLAG_STEP_OVER; break; + case 0xe8: util::stream_format(stream, "djnz r0,$%03X", (pc & 0xf00) | params.r8(cpc++)); flags = STEP_OVER; break; + case 0xe9: util::stream_format(stream, "djnz r1,$%03X", (pc & 0xf00) | params.r8(cpc++)); flags = STEP_OVER; break; + case 0xea: util::stream_format(stream, "djnz r2,$%03X", (pc & 0xf00) | params.r8(cpc++)); flags = STEP_OVER; break; + case 0xeb: util::stream_format(stream, "djnz r3,$%03X", (pc & 0xf00) | params.r8(cpc++)); flags = STEP_OVER; break; + case 0xec: util::stream_format(stream, "djnz r4,$%03X", (pc & 0xf00) | params.r8(cpc++)); flags = STEP_OVER; break; + case 0xed: util::stream_format(stream, "djnz r5,$%03X", (pc & 0xf00) | params.r8(cpc++)); flags = STEP_OVER; break; + case 0xee: util::stream_format(stream, "djnz r6,$%03X", (pc & 0xf00) | params.r8(cpc++)); flags = STEP_OVER; break; + case 0xef: util::stream_format(stream, "djnz r7,$%03X", (pc & 0xf00) | params.r8(cpc++)); flags = STEP_OVER; break; case 0xf0: util::stream_format(stream, "mov a,@r0"); break; case 0xf1: util::stream_format(stream, "mov a,@r1"); break; - case 0xf2: util::stream_format(stream, "jb7 $%03X", (pc & 0xf00) | *opram++); break; - case 0xf4: util::stream_format(stream, "call $7%02X", *opram++); flags = DASMFLAG_STEP_OVER; break; - case 0xf5: if (!upi41) + case 0xf2: util::stream_format(stream, "jb7 $%03X", (pc & 0xf00) | params.r8(cpc++)); break; + case 0xf4: util::stream_format(stream, "call $7%02X", params.r8(cpc++)); flags = STEP_OVER; break; + case 0xf5: if (!m_upi41) util::stream_format(stream, "sel mb1"); else util::stream_format(stream, "en flags"); break; - case 0xf6: util::stream_format(stream, "jc $%03X", (pc & 0xf00) | *opram++); break; + case 0xf6: util::stream_format(stream, "jc $%03X", (pc & 0xf00) | params.r8(cpc++)); break; case 0xf7: util::stream_format(stream, "rlc a"); break; case 0xf8: util::stream_format(stream, "mov a,r0"); break; case 0xf9: util::stream_format(stream, "mov a,r1"); break; @@ -311,17 +319,5 @@ static uint32_t common_dasm(device_t *device, std::ostream &stream, offs_t pc, c default: util::stream_format(stream, "illegal"); break; } - return (opram - startram) | flags | DASMFLAG_SUPPORTED; -} - - -CPU_DISASSEMBLE( mcs48 ) -{ - return common_dasm(device, stream, pc, oprom, opram, false); -} - - -CPU_DISASSEMBLE( upi41 ) -{ - return common_dasm(device, stream, pc, oprom, opram, true); + return (cpc - pc) | flags | SUPPORTED; } diff --git a/src/devices/cpu/mcs48/mcs48dsm.h b/src/devices/cpu/mcs48/mcs48dsm.h new file mode 100644 index 00000000000..c4c7dde9a9c --- /dev/null +++ b/src/devices/cpu/mcs48/mcs48dsm.h @@ -0,0 +1,31 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +/*************************************************************************** + + mcs48dsm.c + + Simple MCS-48/UPI-41 disassembler. + Written by Aaron Giles + +***************************************************************************/ + + +#ifndef MAME_CPU_MCS48_MCS48DASM_H +#define MAME_CPU_MCS48_MCS48DASM_H + +#pragma once + +class mcs48_disassembler : public util::disasm_interface +{ +public: + mcs48_disassembler(bool upi41); + virtual ~mcs48_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + bool m_upi41; +}; + +#endif diff --git a/src/devices/cpu/mcs51/mcs51.cpp b/src/devices/cpu/mcs51/mcs51.cpp index 1c682e06e0e..536565bbbe7 100644 --- a/src/devices/cpu/mcs51/mcs51.cpp +++ b/src/devices/cpu/mcs51/mcs51.cpp @@ -130,6 +130,7 @@ #include "emu.h" #include "debugger.h" #include "mcs51.h" +#include "mcs51dasm.h" #define VERBOSE 0 @@ -2101,7 +2102,7 @@ uint8_t mcs51_cpu_device::sfr_read(size_t offset) void mcs51_cpu_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_data = &space(AS_DATA); m_io = &space(AS_IO); @@ -2506,45 +2507,32 @@ void ds5002fp_device::nvram_write( emu_file &file ) file.write( m_sfr_ram, 0x80 ); } - - -offs_t mcs51_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *mcs51_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( i8051 ); - return CPU_DISASSEMBLE_NAME(i8051)(this, stream, pc, oprom, opram, options); + return new i8051_disassembler; } - -offs_t i8052_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *i8052_device::create_disassembler() { - extern CPU_DISASSEMBLE( i8052 ); - return CPU_DISASSEMBLE_NAME(i8052)(this, stream, pc, oprom, opram, options); + return new i8052_disassembler; } - -offs_t i80c31_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *i80c31_device::create_disassembler() { - extern CPU_DISASSEMBLE( i80c51 ); - return CPU_DISASSEMBLE_NAME(i80c51)(this, stream, pc, oprom, opram, options); + return new i80c51_disassembler; } - -offs_t i80c51_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *i80c51_device::create_disassembler() { - extern CPU_DISASSEMBLE( i80c51 ); - return CPU_DISASSEMBLE_NAME(i80c51)(this, stream, pc, oprom, opram, options); + return new i80c51_disassembler; } - -offs_t i80c52_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *i80c52_device::create_disassembler() { - extern CPU_DISASSEMBLE( i80c52 ); - return CPU_DISASSEMBLE_NAME(i80c52)(this, stream, pc, oprom, opram, options); + return new i80c52_disassembler; } - -offs_t ds5002fp_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *ds5002fp_device::create_disassembler() { - extern CPU_DISASSEMBLE( ds5002fp ); - return CPU_DISASSEMBLE_NAME(ds5002fp)(this, stream, pc, oprom, opram, options); + return new ds5002fp_disassembler; } diff --git a/src/devices/cpu/mcs51/mcs51.h b/src/devices/cpu/mcs51/mcs51.h index 13f19d3fd28..f324e428ad5 100644 --- a/src/devices/cpu/mcs51/mcs51.h +++ b/src/devices/cpu/mcs51/mcs51.h @@ -115,9 +115,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 5; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; protected: address_space_config m_program_config; @@ -168,7 +166,7 @@ protected: /* Memory spaces */ address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_data; address_space *m_io; @@ -390,7 +388,7 @@ public: protected: i8052_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int program_width, int data_width, uint8_t features = 0); - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; /* SFR Callbacks */ virtual void sfr_write(size_t offset, uint8_t data) override; @@ -418,7 +416,7 @@ public: i80c31_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); protected: - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; }; @@ -431,7 +429,7 @@ public: protected: i80c51_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int program_width, int data_width, uint8_t features = 0); - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; }; class i87c51_device : public i80c51_device @@ -451,7 +449,7 @@ public: protected: i80c52_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int program_width, int data_width, uint8_t features = 0); - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; /* SFR Callbacks */ virtual void sfr_write(size_t offset, uint8_t data) override; @@ -522,7 +520,7 @@ public: virtual void nvram_write( emu_file &file ) override; protected: - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; /* SFR Callbacks */ virtual void sfr_write(size_t offset, uint8_t data) override; diff --git a/src/devices/cpu/mcs51/mcs51dasm.cpp b/src/devices/cpu/mcs51/mcs51dasm.cpp index b96ae46a4a1..fce9b90208f 100644 --- a/src/devices/cpu/mcs51/mcs51dasm.cpp +++ b/src/devices/cpu/mcs51/mcs51dasm.cpp @@ -24,223 +24,215 @@ *****************************************************************************/ #include "emu.h" -#include "debugger.h" -#include "mcs51.h" +#include "mcs51dasm.h" + +// Note: addresses >= 0x100 are bit addresses + +const mcs51_disassembler::mem_info mcs51_disassembler::default_names[] = { + { 0x00, "rb0r0" }, + { 0x01, "rb0r1" }, + { 0x02, "rb0r2" }, + { 0x03, "rb0r3" }, + { 0x04, "rb0r4" }, + { 0x05, "rb0r5" }, + { 0x06, "rb0r6" }, + { 0x07, "rb0r7" }, + { 0x08, "rb1r0" }, + { 0x09, "rb1r1" }, + { 0x0a, "rb1r2" }, + { 0x0b, "rb1r3" }, + { 0x0c, "rb1r4" }, + { 0x0d, "rb1r5" }, + { 0x0e, "rb1r6" }, + { 0x0f, "rb1r7" }, + { 0x10, "rb2r0" }, + { 0x11, "rb2r1" }, + { 0x12, "rb2r2" }, + { 0x13, "rb2r3" }, + { 0x14, "rb2r4" }, + { 0x15, "rb2r5" }, + { 0x16, "rb2r6" }, + { 0x17, "rb2r7" }, + { 0x18, "rb3r0" }, + { 0x19, "rb3r1" }, + { 0x1a, "rb3r2" }, + { 0x1b, "rb3r3" }, + { 0x1c, "rb3r4" }, + { 0x1d, "rb3r5" }, + { 0x1e, "rb3r6" }, + { 0x1f, "rb3r7" }, + + { 0x80, "p0" }, + { 0x81, "sp" }, + { 0x82, "dpl" }, + { 0x83, "dph" }, + { 0x87, "pcon" }, + { 0x88, "tcon" }, + { 0x89, "tmod" }, + { 0x8a, "tl0" }, + { 0x8b, "tl1" }, + { 0x8c, "th0" }, + { 0x8d, "th1" }, + { 0x90, "p1" }, + { 0x98, "scon" }, + { 0x99, "sbuf" }, + { 0xa0, "p2" }, + { 0xa8, "ie" }, + { 0xb0, "p3" }, + { 0xb8, "ip" }, + { 0xd0, "psw" }, + { 0xe0, "acc" }, + { 0xf0, "b" }, + + { 0x188, "it0" }, + { 0x189, "ie0" }, + { 0x18a, "it1" }, + { 0x18b, "ie1" }, + { 0x18c, "tr0" }, + { 0x18d, "tf0" }, + { 0x18e, "tr1" }, + { 0x18f, "tf1" }, + + { 0x198, "ri" }, + { 0x199, "ti" }, + { 0x19a, "rb8" }, + { 0x19b, "tb8" }, + { 0x19c, "ren" }, + { 0x19d, "sm2" }, + { 0x19e, "sm1" }, + { 0x19f, "sm0" }, + + { 0x1a8, "ex0" }, + { 0x1a9, "et0" }, + { 0x1aa, "ex1" }, + { 0x1ab, "et1" }, + { 0x1ac, "es" }, + { 0x1ad, "ie.5" }, + { 0x1ae, "ie.6" }, + { 0x1af, "ea" }, -enum -{ - FEATURE_NONE = 0x00, - FEATURE_I8052 = 0x01, - FEATURE_CMOS = 0x02, - FEATURE_I80C52 = 0x04, - FEATURE_DS5002FP = 0x08, - FEATURE_I83C751 = 0x08 + /* FIXME: port 3 - depends on external circuits and not really + * implemented in the core. TBD */ + { 0x1b0, "rxd" }, + { 0x1b1, "txd" }, + { 0x1b2, "int0" }, + { 0x1b3, "int1" }, + { 0x1b4, "t0" }, + { 0x1b5, "t1" }, + { 0x1b6, "wr" }, + { 0x1b7, "rd" }, + + { 0x1b8, "px0" }, + { 0x1b9, "pt0" }, + { 0x1ba, "px1" }, + { 0x1bb, "pt1" }, + { 0x1bc, "ps" }, + { 0x1bd, "ip.5" }, + { 0x1be, "ip.6" }, + { 0x1bf, "ip.7" }, + + { 0x1d0, "p" }, + { 0x1d1, "psw.1" }, + { 0x1d2, "ov" }, + { 0x1d3, "rs0" }, + { 0x1d4, "rs1" }, + { 0x1d5, "f0" }, + { 0x1d6, "ac" }, + { 0x1d7, "cy" }, + + { -1 } }; +const mcs51_disassembler::mem_info mcs51_disassembler::i8052_names[] = { + { 0xc8, "t2con" }, + { 0xca, "rcap2l" }, + { 0xcb, "rcap2h" }, + { 0xcc, "tl2" }, + { 0xcd, "th2" }, + + { 0x1ad, "et2" }, + { 0x1bd, "pt2" }, + + { 0x1c8, "cprl2" }, + { 0x1c9, "ct2" }, + { 0x1ca, "tr2" }, + { 0x1cb, "exen2" }, + { 0x1cc, "tclk" }, + { 0x1cd, "rclk" }, + { 0x1ce, "exf2" }, + { 0x1cf, "tf2" }, -#define SHOW_MEMORY_NAMES 1 + { -1 } +}; -#ifdef SHOW_MEMORY_NAMES +const mcs51_disassembler::mem_info mcs51_disassembler::i80c52_names[] = { + { 0xb7, "iph" }, + { 0xa9, "saddr" }, + { 0xb9, "saden" }, -/*Display the memory address names for data & bit address access*/ + { -1 } +}; -//SFR Names +const mcs51_disassembler::mem_info mcs51_disassembler::ds5002fp_names[] = { + { 0x8e, "pwcm" }, + { 0x8f, "pwmp" }, + { 0xc1, "crcr" }, + { 0xc2, "crcl" }, + { 0xc3, "crch" }, + { 0xc6, "mcon" }, + { 0xc7, "ta" }, + { 0xcf, "rnr" }, + { 0xd8, "rpctl" }, + { 0xd9, "rps" }, + + { 0x1d8, "rg0" }, + { 0x1d9, "rpc" }, + { 0x1da, "dma" }, + { 0x1db, "ibi" }, + { 0x1dc, "ae" }, + { 0x1dd, "exbs" }, + { 0x1de, "d8.6" }, + { 0x1df, "rnr" }, -static const struct { - int feature; - int addr; - const char *name; -} mem_name_feature[] = -{ - { FEATURE_NONE, 0x00, "rb0r0" }, - { FEATURE_NONE, 0x01, "rb0r1" }, - { FEATURE_NONE, 0x02, "rb0r2" }, - { FEATURE_NONE, 0x03, "rb0r3" }, - { FEATURE_NONE, 0x04, "rb0r4" }, - { FEATURE_NONE, 0x05, "rb0r5" }, - { FEATURE_NONE, 0x06, "rb0r6" }, - { FEATURE_NONE, 0x07, "rb0r7" }, - { FEATURE_NONE, 0x08, "rb1r0" }, - { FEATURE_NONE, 0x09, "rb1r1" }, - { FEATURE_NONE, 0x0a, "rb1r2" }, - { FEATURE_NONE, 0x0b, "rb1r3" }, - { FEATURE_NONE, 0x0c, "rb1r4" }, - { FEATURE_NONE, 0x0d, "rb1r5" }, - { FEATURE_NONE, 0x0e, "rb1r6" }, - { FEATURE_NONE, 0x0f, "rb1r7" }, - { FEATURE_NONE, 0x10, "rb2r0" }, - { FEATURE_NONE, 0x11, "rb2r1" }, - { FEATURE_NONE, 0x12, "rb2r2" }, - { FEATURE_NONE, 0x13, "rb2r3" }, - { FEATURE_NONE, 0x14, "rb2r4" }, - { FEATURE_NONE, 0x15, "rb2r5" }, - { FEATURE_NONE, 0x16, "rb2r6" }, - { FEATURE_NONE, 0x17, "rb2r7" }, - { FEATURE_NONE, 0x18, "rb3r0" }, - { FEATURE_NONE, 0x19, "rb3r1" }, - { FEATURE_NONE, 0x1a, "rb3r2" }, - { FEATURE_NONE, 0x1b, "rb3r3" }, - { FEATURE_NONE, 0x1c, "rb3r4" }, - { FEATURE_NONE, 0x1d, "rb3r5" }, - { FEATURE_NONE, 0x1e, "rb3r6" }, - { FEATURE_NONE, 0x1f, "rb3r7" }, - - { FEATURE_NONE, 0x80, "p0" }, - { FEATURE_NONE, 0x81, "sp" }, - { FEATURE_NONE, 0x82, "dpl" }, - { FEATURE_NONE, 0x83, "dph" }, - { FEATURE_NONE, 0x87, "pcon" }, - { FEATURE_NONE, 0x88, "tcon" }, - { FEATURE_NONE, 0x89, "tmod" }, - { FEATURE_NONE, 0x8a, "tl0" }, - { FEATURE_NONE, 0x8b, "tl1" }, - { FEATURE_NONE, 0x8c, "th0" }, - { FEATURE_NONE, 0x8d, "th1" }, - { FEATURE_NONE, 0x90, "p1" }, - { FEATURE_NONE, 0x98, "scon" }, - { FEATURE_NONE, 0x99, "sbuf" }, - { FEATURE_NONE, 0xa0, "p2" }, - { FEATURE_NONE, 0xa8, "ie" }, - { FEATURE_NONE, 0xb0, "p3" }, - { FEATURE_NONE, 0xb8, "ip" }, - { FEATURE_NONE, 0xd0, "psw" }, - { FEATURE_NONE, 0xe0, "acc" }, - { FEATURE_NONE, 0xf0, "b" }, - - { FEATURE_I8052, 0xc8, "t2con" }, - { FEATURE_I8052, 0xca, "rcap2l" }, - { FEATURE_I8052, 0xcb, "rcap2h" }, - { FEATURE_I8052, 0xcc, "tl2" }, - { FEATURE_I8052, 0xcd, "th2" }, - - { FEATURE_I80C52, 0xb7, "iph" }, - { FEATURE_I80C52, 0xa9, "saddr" }, - { FEATURE_I80C52, 0xb9, "saden" }, - - { FEATURE_DS5002FP, 0x8e, "pwcm" }, - { FEATURE_DS5002FP, 0x8f, "pwmp" }, - { FEATURE_DS5002FP, 0xc1, "crcr" }, - { FEATURE_DS5002FP, 0xc2, "crcl" }, - { FEATURE_DS5002FP, 0xc3, "crch" }, - { FEATURE_DS5002FP, 0xc6, "mcon" }, - { FEATURE_DS5002FP, 0xc7, "ta" }, - { FEATURE_DS5002FP, 0xcf, "rnr" }, - { FEATURE_DS5002FP, 0xd8, "rpctl" }, - { FEATURE_DS5002FP, 0xd9, "rps" }, - - { FEATURE_I83C751, 0x98, "i2con" }, - { FEATURE_I83C751, 0x99, "i2dat" }, - { FEATURE_I83C751, 0xd8, "i2cfg" }, - { FEATURE_I83C751, 0xf8, "i2sta" }, /* read only */ - - /* bit addresses */ - - { FEATURE_NONE, 0x188, "it0" }, - { FEATURE_NONE, 0x189, "ie0" }, - { FEATURE_NONE, 0x18a, "it1" }, - { FEATURE_NONE, 0x18b, "ie1" }, - { FEATURE_NONE, 0x18c, "tr0" }, - { FEATURE_NONE, 0x18d, "tf0" }, - { FEATURE_NONE, 0x18e, "tr1" }, - { FEATURE_NONE, 0x18f, "tf1" }, - - { FEATURE_NONE, 0x198, "ri" }, - { FEATURE_NONE, 0x199, "ti" }, - { FEATURE_NONE, 0x19a, "rb8" }, - { FEATURE_NONE, 0x19b, "tb8" }, - { FEATURE_NONE, 0x19c, "ren" }, - { FEATURE_NONE, 0x19d, "sm2" }, - { FEATURE_NONE, 0x19e, "sm1" }, - { FEATURE_NONE, 0x19f, "sm0" }, - - { FEATURE_I83C751, 0x198, "xstp" }, /* read: no function */ - { FEATURE_I83C751, 0x199, "xstr" }, /* read: MASTER */ - { FEATURE_I83C751, 0x19a, "cstp" }, /* read: STP */ - { FEATURE_I83C751, 0x19b, "cstr" }, /* read: STR */ - { FEATURE_I83C751, 0x19c, "carl" }, /* read: ARL */ - { FEATURE_I83C751, 0x19d, "cdr" }, /* read: DRDY */ - { FEATURE_I83C751, 0x19e, "idle" }, /* read: ATN */ - { FEATURE_I83C751, 0x19f, "cxa" }, /* read: RDAT */ - - { FEATURE_NONE, 0x1a8, "ex0" }, - { FEATURE_NONE, 0x1a9, "et0" }, - { FEATURE_NONE, 0x1aa, "ex1" }, - { FEATURE_NONE, 0x1ab, "et1" }, - { FEATURE_NONE, 0x1ac, "es" }, - { FEATURE_NONE, 0x1ad, "ie.5" }, - { FEATURE_NONE, 0x1ae, "ie.6" }, - { FEATURE_NONE, 0x1af, "ea" }, - - { FEATURE_I83C751, 0x1ac, "ei2" }, - { FEATURE_I8052, 0x1ad, "et2" }, + { -1 } +}; - /* FIXME: port 3 - depends on external circuits and not really - * implemented in the core. TBD */ - { FEATURE_NONE, 0x1b0, "rxd" }, - { FEATURE_NONE, 0x1b1, "txd" }, - { FEATURE_NONE, 0x1b2, "int0" }, - { FEATURE_NONE, 0x1b3, "int1" }, - { FEATURE_NONE, 0x1b4, "t0" }, - { FEATURE_NONE, 0x1b5, "t1" }, - { FEATURE_NONE, 0x1b6, "wr" }, - { FEATURE_NONE, 0x1b7, "rd" }, - - { FEATURE_NONE, 0x1b8, "px0" }, - { FEATURE_NONE, 0x1b9, "pt0" }, - { FEATURE_NONE, 0x1ba, "px1" }, - { FEATURE_NONE, 0x1bb, "pt1" }, - { FEATURE_NONE, 0x1bc, "ps" }, - { FEATURE_NONE, 0x1bd, "ip.5" }, - { FEATURE_NONE, 0x1be, "ip.6" }, - { FEATURE_NONE, 0x1bf, "ip.7" }, - - { FEATURE_I8052, 0x1bd, "pt2" }, - { FEATURE_I83C751, 0x1bc, "pi2" }, - - { FEATURE_I8052, 0x1c8, "cprl2" }, - { FEATURE_I8052, 0x1c9, "ct2" }, - { FEATURE_I8052, 0x1ca, "tr2" }, - { FEATURE_I8052, 0x1cb, "exen2" }, - { FEATURE_I8052, 0x1cc, "tclk" }, - { FEATURE_I8052, 0x1cd, "rclk" }, - { FEATURE_I8052, 0x1ce, "exf2" }, - { FEATURE_I8052, 0x1cf, "tf2" }, - - { FEATURE_NONE, 0x1d0, "p" }, - { FEATURE_NONE, 0x1d1, "psw.1" }, - { FEATURE_NONE, 0x1d2, "ov" }, - { FEATURE_NONE, 0x1d3, "rs0" }, - { FEATURE_NONE, 0x1d4, "rs1" }, - { FEATURE_NONE, 0x1d5, "f0" }, - { FEATURE_NONE, 0x1d6, "ac" }, - { FEATURE_NONE, 0x1d7, "cy" }, - - { FEATURE_DS5002FP, 0x1d8, "rg0" }, - { FEATURE_DS5002FP, 0x1d9, "rpc" }, - { FEATURE_DS5002FP, 0x1da, "dma" }, - { FEATURE_DS5002FP, 0x1db, "ibi" }, - { FEATURE_DS5002FP, 0x1dc, "ae" }, - { FEATURE_DS5002FP, 0x1dd, "exbs" }, - { FEATURE_DS5002FP, 0x1de, "d8.6" }, - { FEATURE_DS5002FP, 0x1df, "rnr" }, - - { FEATURE_I83C751, 0x1d8, "ct0" }, - { FEATURE_I83C751, 0x1d9, "ct1" }, - { FEATURE_I83C751, 0x1da, "i2cfg.2" }, - { FEATURE_I83C751, 0x1db, "i2cfg.3" }, - { FEATURE_I83C751, 0x1dc, "tirun" }, - { FEATURE_I83C751, 0x1dd, "clrti" }, - { FEATURE_I83C751, 0x1de, "masterq" }, - { FEATURE_I83C751, 0x1df, "slaven" }, - - { FEATURE_I83C751, 0x1f8, "xstp" }, - { FEATURE_I83C751, 0x1f9, "xstr" }, - { FEATURE_I83C751, 0x1fa, "makstp" }, - { FEATURE_I83C751, 0x1fb, "makstr" }, - { FEATURE_I83C751, 0x1fc, "xactv" }, - { FEATURE_I83C751, 0x1fd, "xdata" }, - { FEATURE_I83C751, 0x1fe, "idle" }, - { FEATURE_I83C751, 0x1ff, "i2sta.7" }, +const mcs51_disassembler::mem_info mcs51_disassembler::i8xc751_names[] = { + { 0x98, "i2con" }, + { 0x99, "i2dat" }, + { 0xd8, "i2cfg" }, + { 0xf8, "i2sta" }, /* read only */ + + { 0x198, "xstp" }, /* read: no function */ + { 0x199, "xstr" }, /* read: MASTER */ + { 0x19a, "cstp" }, /* read: STP */ + { 0x19b, "cstr" }, /* read: STR */ + { 0x19c, "carl" }, /* read: ARL */ + { 0x19d, "cdr" }, /* read: DRDY */ + { 0x19e, "idle" }, /* read: ATN */ + { 0x19f, "cxa" }, /* read: RDAT */ + + { 0x1ac, "ei2" }, + + { 0x1bc, "pi2" }, + + { 0x1d8, "ct0" }, + { 0x1d9, "ct1" }, + { 0x1da, "i2cfg.2" }, + { 0x1db, "i2cfg.3" }, + { 0x1dc, "tirun" }, + { 0x1dd, "clrti" }, + { 0x1de, "masterq" }, + { 0x1df, "slaven" }, + + { 0x1f8, "xstp" }, + { 0x1f9, "xstr" }, + { 0x1fa, "makstp" }, + { 0x1fb, "makstr" }, + { 0x1fc, "xactv" }, + { 0x1fd, "xdata" }, + { 0x1fe, "idle" }, + { 0x1ff, "i2sta.7" }, /* unknown * "ibf", "obf", "idsm", "obfc", e8 - eb @@ -250,97 +242,67 @@ static const struct { { -1 } }; -static void init_mem_names(int feature_set, const char **mem_names) +mcs51_disassembler::mcs51_disassembler() { - int i; - int feature; - - /* Set defaults / i8051 */ - for (i = 0; feature = mem_name_feature[i].feature, feature >= 0; i++) - { - if ( feature == FEATURE_NONE ) - mem_names[mem_name_feature[i].addr] = mem_name_feature[i].name; - } - - /* Set specific memory names */ - for (i = 0; feature = mem_name_feature[i].feature, feature >= 0; i++) - { - if (feature & feature_set) - mem_names[mem_name_feature[i].addr] = mem_name_feature[i].name; - } +} +void mcs51_disassembler::add_names(const mem_info *info) +{ + for(unsigned int i=0; info[i].addr >= 0; i++) + m_names[info[i].addr] = info[i].name; } -static const char *get_data_address( const char **mem_names, uint8_t arg ) +u32 mcs51_disassembler::opcode_alignment() const { - static char buffer_array[4][32]; - static int whichbuf; - char *buffer = &buffer_array[++whichbuf % 4][0]; + return 1; +} + - if (mem_names[arg] == nullptr) - sprintf(buffer,"$%02X",arg); +std::string mcs51_disassembler::get_data_address( uint8_t arg ) const +{ + auto i = m_names.find(arg); + if (i == m_names.end()) + return util::string_format("$%02X", arg); else - sprintf(buffer,"%s", mem_names[arg]); - return buffer; + return i->second; } -static const char *get_bit_address( const char **mem_names, uint8_t arg ) +std::string mcs51_disassembler::get_bit_address( uint8_t arg ) const { - static char buffer[32]; - if(arg < 0x80) { //Bit address 0-7F can be referred to as 20.0, 20.1, to 20.7 for address 0, and 2f.0,2f.1 to 2f.7 for address 7f if(arg < 0x7f) - sprintf(buffer,"$%02X.%d",(arg >> 3) | 0x20, arg & 0x07); + return util::string_format("$%02X.%d", (arg >> 3) | 0x20, arg & 0x07); else - sprintf(buffer,"$%02X",arg); + return util::string_format("$%02X", arg); } else { - if (mem_names[arg | 0x100] == nullptr) + auto i = m_names.find(arg | 0x100); + if (i == m_names.end()) { - if (mem_names[arg & 0xf8] == nullptr) - sprintf(buffer,"$%02X.%d", arg & 0xf8, arg & 0x07); + i = m_names.find(arg & 0xf8); + if (i == m_names.end()) + return util::string_format("$%02X.%d", arg & 0xf8, arg & 0x07); else - sprintf(buffer,"%s.%d", mem_names[arg & 0xf8], arg & 0x07); + return util::string_format("%s.%d", i->second, arg & 0x07); } else - sprintf(buffer,"%s", mem_names[arg | 0x100]); + return i->second; } - return buffer; } -#else - -/*Just display the actual memory address for data & bit address access*/ - -static const char *get_data_address( uint8_t arg ) -{ - static char buffer[32]; - sprintf(buffer,"$%02X",arg); - return buffer; -} - -static const char *get_bit_address( uint8_t arg ) -{ - static char buffer[32]; - sprintf(buffer,"$%02X",arg); - return buffer; -} - -#endif - -static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram) +offs_t mcs51_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint32_t flags = 0; unsigned PC = pc; - const char *sym, *sym2; + std::string sym, sym2; uint8_t op, data; uint16_t addr; int8_t rel; - op = oprom[PC++ - pc]; + op = opcodes.r8(PC++); switch( op ) { //NOP @@ -357,15 +319,15 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p case 0xa1: case 0xc1: case 0xe1: - addr = opram[PC++ - pc]; + addr = params.r8(PC++); addr|= (PC & 0xf800) | ((op & 0xe0) << 3); util::stream_format(stream, "ajmp $%04X", addr); break; //LJMP code addr case 0x02: /* 1: 0000 0010 */ - addr = (opram[PC++ - pc]<<8) & 0xff00; - addr|= opram[PC++ - pc]; + addr = (params.r8(PC++)<<8) & 0xff00; + addr|= params.r8(PC++); util::stream_format(stream, "ljmp $%04X", addr); break; @@ -381,7 +343,7 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //INC data addr case 0x05: /* 1: 0000 0101 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "inc %s", sym); break; @@ -405,8 +367,8 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //JBC bit addr, code addr case 0x10: /* 1: 0001 0000 */ - sym = get_bit_address(mem_names, opram[PC++ - pc]); - rel = opram[PC++ - pc]; + sym = get_bit_address(params.r8(PC++)); + rel = params.r8(PC++); util::stream_format(stream, "jbc %s,$%04X", sym, PC + rel); break; @@ -419,17 +381,17 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p case 0xb1: case 0xd1: case 0xf1: - util::stream_format(stream, "acall $%04X", (PC & 0xf800) | ((op & 0xe0) << 3) | opram[PC - pc]); + util::stream_format(stream, "acall $%04X", (PC & 0xf800) | ((op & 0xe0) << 3) | params.r8(PC)); PC++; - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; //LCALL code addr case 0x12: /* 1: 0001 0010 */ - addr = (opram[PC++ - pc]<<8) & 0xff00; - addr|= opram[PC++ - pc]; + addr = (params.r8(PC++)<<8) & 0xff00; + addr|= params.r8(PC++); util::stream_format(stream, "lcall $%04X", addr); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; //RRC A @@ -444,7 +406,7 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //DEC data addr case 0x15: /* 1: 0001 0101 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "dec %s", sym); break; @@ -469,15 +431,15 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //JB bit addr, code addr case 0x20: /* 1: 0010 0000 */ - sym = get_bit_address(mem_names, opram[PC++ - pc]); - rel = opram[PC++ - pc]; + sym = get_bit_address(params.r8(PC++)); + rel = params.r8(PC++); util::stream_format(stream, "jb %s,$%04X", sym, (PC + rel)); break; //RET case 0x22: /* 1: 0010 0010 */ util::stream_format(stream, "ret"); - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; //RL A @@ -487,12 +449,12 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //ADD A, #data case 0x24: /* 1: 0010 0100 */ - util::stream_format(stream, "add a,#$%02X", opram[PC++ - pc]); + util::stream_format(stream, "add a,#$%02X", params.r8(PC++)); break; //ADD A, data addr case 0x25: /* 1: 0010 0101 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "add a,%s", sym); break; @@ -517,15 +479,15 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //JNB bit addr, code addr case 0x30: /* 1: 0011 0000 */ - sym = get_bit_address(mem_names, opram[PC++ - pc]); - rel = opram[PC++ - pc]; + sym = get_bit_address(params.r8(PC++)); + rel = params.r8(PC++); util::stream_format(stream, "jnb %s,$%04X", sym, (PC + rel)); break; //RETI case 0x32: /* 1: 0011 0010 */ util::stream_format(stream, "reti"); - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; //RLC A @@ -535,12 +497,12 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //ADDC A, #data case 0x34: /* 1: 0011 0100 */ - util::stream_format(stream, "addc a,#$%02X", opram[PC++ - pc]); + util::stream_format(stream, "addc a,#$%02X", params.r8(PC++)); break; //ADDC A, data addr case 0x35: /* 1: 0011 0101 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "addc a,%s", sym); break; @@ -564,31 +526,31 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //JC code addr case 0x40: /* 1: 0100 0000 */ - rel = opram[PC++ - pc]; + rel = params.r8(PC++); util::stream_format(stream, "jc $%04X", PC + rel); break; //ORL data addr, A case 0x42: /* 1: 0100 0010 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "orl %s,a", sym); break; //ORL data addr, #data case 0x43: /* 1: 0100 0011 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); - util::stream_format(stream, "orl %s,#$%02X", sym, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); + util::stream_format(stream, "orl %s,#$%02X", sym, params.r8(PC++)); break; //Unable to Test //ORL A, #data case 0x44: /* 1: 0100 0100 */ - util::stream_format(stream, "orl a,#$%02X", opram[PC++ - pc]); + util::stream_format(stream, "orl a,#$%02X", params.r8(PC++)); break; //ORL A, data addr case 0x45: /* 1: 0100 0101 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "orl a,%s", sym); break; @@ -612,32 +574,32 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //JNC code addr case 0x50: /* 1: 0101 0000 */ - rel = opram[PC++ - pc]; + rel = params.r8(PC++); util::stream_format(stream, "jnc $%04X", PC + rel); break; //Unable to test //ANL data addr, A case 0x52: /* 1: 0101 0010 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "anl %s,a", sym); break; //Unable to test //ANL data addr, #data case 0x53: /* 1: 0101 0011 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); - util::stream_format(stream, "anl %s,#$%02X", sym, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); + util::stream_format(stream, "anl %s,#$%02X", sym, params.r8(PC++)); break; //ANL A, #data case 0x54: /* 1: 0101 0100 */ - util::stream_format(stream, "anl a,#$%02X", opram[PC++ - pc]); + util::stream_format(stream, "anl a,#$%02X", params.r8(PC++)); break; //ANL A, data addr case 0x55: /* 1: 0101 0101 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "anl a,%s", sym); break; @@ -662,31 +624,31 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //JZ code addr case 0x60: /* 1: 0110 0000 */ - rel = opram[PC++ - pc]; + rel = params.r8(PC++); util::stream_format(stream, "jz $%04X", PC + rel); break; //Unable to test //XRL data addr, A case 0x62: /* 1: 0110 0010 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "xrl %s,a", sym); break; //XRL data addr, #data case 0x63: /* 1: 0110 0011 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); - util::stream_format(stream, "xrl %s,#$%02X", sym, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); + util::stream_format(stream, "xrl %s,#$%02X", sym, params.r8(PC++)); break; //XRL A, #data case 0x64: /* 1: 0110 0100 */ - util::stream_format(stream, "xrl a,#$%02X", opram[PC++ - pc]); + util::stream_format(stream, "xrl a,#$%02X", params.r8(PC++)); break; //XRL A, data addr case 0x65: /* 1: 0110 0101 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "xrl a,%s", sym); break; @@ -711,14 +673,14 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //JNZ code addr case 0x70: /* 1: 0111 0000 */ - rel = opram[PC++ - pc]; + rel = params.r8(PC++); util::stream_format(stream, "jnz $%04X", PC + rel); break; //Unable to test //ORL C, bit addr case 0x72: /* 1: 0111 0010 */ - sym = get_bit_address(mem_names, opram[PC++ - pc]); + sym = get_bit_address(params.r8(PC++)); util::stream_format(stream, "orl c,%s", sym); break; @@ -730,20 +692,20 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //MOV A, #data case 0x74: /* 1: 0111 0100 */ - util::stream_format(stream, "mov a,#$%02X", opram[PC++ - pc]); + util::stream_format(stream, "mov a,#$%02X", params.r8(PC++)); break; //MOV data addr, #data case 0x75: /* 1: 0111 0101 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); - util::stream_format(stream, "mov %s,#$%02X", sym, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); + util::stream_format(stream, "mov %s,#$%02X", sym, params.r8(PC++)); break; //Unable to test //MOV @R0/@R1, #data /* 1: 0111 011i */ case 0x76: case 0x77: - util::stream_format(stream, "mov @r%d,#$%02X", op&1, opram[PC++ - pc]); + util::stream_format(stream, "mov @r%d,#$%02X", op&1, params.r8(PC++)); break; //MOV R0 to R7, #data /* 1: 0111 1rrr */ @@ -755,18 +717,18 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p case 0x7d: case 0x7e: case 0x7f: - util::stream_format(stream, "mov r%d,#$%02X", (op & 7), opram[PC++ - pc]); + util::stream_format(stream, "mov r%d,#$%02X", (op & 7), params.r8(PC++)); break; //SJMP code addr case 0x80: /* 1: 1000 0000 */ - rel = opram[PC++ - pc]; + rel = params.r8(PC++); util::stream_format(stream, "sjmp $%04X", PC + rel); break; //ANL C, bit addr case 0x82: /* 1: 1000 0010 */ - sym = get_bit_address(mem_names, opram[PC++ - pc]); + sym = get_bit_address(params.r8(PC++)); util::stream_format(stream, "anl c,%s", sym); break; @@ -782,8 +744,8 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //MOV data addr, data addr (Note: 1st address is src, 2nd is dst, but the mov command works as mov dst,src) case 0x85: /* 1: 1000 0101 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); - sym2 = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); + sym2 = get_data_address(params.r8(PC++)); util::stream_format(stream, "mov %s,%s", sym2, sym); break; @@ -791,7 +753,7 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //MOV data addr, @R0/@R1/* 1: 1000 011i */ case 0x86: case 0x87: - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "mov %s,@r%d", sym, op&1); break; @@ -804,20 +766,20 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p case 0x8d: case 0x8e: case 0x8f: - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "mov %s,r%d", sym, op&7); break; //MOV DPTR, #data16 case 0x90: /* 1: 1001 0000 */ - addr = (opram[PC++ - pc]<<8) & 0xff00; - addr|= opram[PC++ - pc]; + addr = (params.r8(PC++)<<8) & 0xff00; + addr|= params.r8(PC++); util::stream_format(stream, "mov dptr,#$%04X", addr); break; //MOV bit addr, C case 0x92: /* 1: 1001 0010 */ - sym = get_bit_address(mem_names, opram[PC++ - pc]); + sym = get_bit_address(params.r8(PC++)); util::stream_format(stream, "mov %s,c", sym); break; @@ -828,12 +790,12 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //SUBB A, #data case 0x94: /* 1: 1001 0100 */ - util::stream_format(stream, "subb a,#$%02X", opram[PC++ - pc]); + util::stream_format(stream, "subb a,#$%02X", params.r8(PC++)); break; //SUBB A, data addr case 0x95: /* 1: 1001 0101 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "subb a,%s", sym); break; @@ -859,13 +821,13 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //Unable to test //ORL C, /bit addr case 0xa0: /* 1: 1010 0000 */ - sym = get_bit_address(mem_names, opram[PC++ - pc]); + sym = get_bit_address(params.r8(PC++)); util::stream_format(stream, "orl c,/%s", sym); break; //MOV C, bit addr case 0xa2: /* 1: 1010 0010 */ - sym = get_bit_address(mem_names, opram[PC++ - pc]); + sym = get_bit_address(params.r8(PC++)); util::stream_format(stream, "mov c,%s", sym); break; @@ -888,7 +850,7 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //MOV @R0/@R1, data addr /* 1: 1010 011i */ case 0xa6: case 0xa7: - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "mov @r%d,%s", op&1, sym); break; @@ -901,19 +863,19 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p case 0xad: case 0xae: case 0xaf: - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "mov r%d,%s", op&7, sym); break; //ANL C,/bit addr case 0xb0: /* 1: 1011 0000 */ - sym = get_bit_address(mem_names, opram[PC++ - pc]); + sym = get_bit_address(params.r8(PC++)); util::stream_format(stream, "anl c,/%s", sym); break; //CPL bit addr case 0xb2: /* 1: 1011 0010 */ - sym = get_bit_address(mem_names, opram[PC++ - pc]); + sym = get_bit_address(params.r8(PC++)); util::stream_format(stream, "cpl %s", sym); break; @@ -925,15 +887,15 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //CJNE A, #data, code addr case 0xb4: /* 1: 1011 0100 */ - data = opram[PC++ - pc]; - rel = opram[PC++ - pc]; + data = params.r8(PC++); + rel = params.r8(PC++); util::stream_format(stream, "cjne a,#$%02X,$%04X", data, PC + rel); break; //CJNE A, data addr, code addr case 0xb5: /* 1: 1011 0101 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); - rel = opram[PC++ - pc]; + sym = get_data_address(params.r8(PC++)); + rel = params.r8(PC++); util::stream_format(stream, "cjne a,%s,$%04X", sym, PC + rel); break; @@ -941,8 +903,8 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //CJNE @R0/@R1, #data, code addr /* 1: 1011 011i */ case 0xb6: case 0xb7: - data = opram[PC++ - pc]; - rel = opram[PC++ - pc]; + data = params.r8(PC++); + rel = params.r8(PC++); util::stream_format(stream, "cjne @r%d,#$%02X,$%04X", op&1, data, PC + rel); break; @@ -955,20 +917,20 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p case 0xbd: case 0xbe: case 0xbf: - data = opram[PC++ - pc]; - rel = opram[PC++ - pc]; + data = params.r8(PC++); + rel = params.r8(PC++); util::stream_format(stream, "cjne r%d,#$%02X,$%04X", op&7, data, PC + rel); break; //PUSH data addr case 0xc0: /* 1: 1100 0000 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "push %s", sym); break; //CLR bit addr case 0xc2: /* 1: 1100 0010 */ - sym = get_bit_address(mem_names, opram[PC++ - pc]); + sym = get_bit_address(params.r8(PC++)); util::stream_format(stream, "clr %s", sym); break; @@ -984,7 +946,7 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //XCH A, data addr case 0xc5: /* 1: 1100 0101 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "xch a,%s", sym); break; @@ -1008,13 +970,13 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //POP data addr case 0xd0: /* 1: 1101 0000 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "pop %s", sym); break; //SETB bit addr case 0xd2: /* 1: 1101 0010 */ - sym = get_bit_address(mem_names, opram[PC++ - pc]); + sym = get_bit_address(params.r8(PC++)); util::stream_format(stream, "setb %s", sym); break; @@ -1031,10 +993,10 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //DJNZ data addr, code addr case 0xd5: /* 1: 1101 0101 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); - rel = opram[PC++ - pc]; + sym = get_data_address(params.r8(PC++)); + rel = params.r8(PC++); util::stream_format(stream, "djnz %s,$%04X", sym, PC + rel); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; //XCHD A, @R0/@R1 /* 1: 1101 011i */ @@ -1052,9 +1014,9 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p case 0xdd: case 0xde: case 0xdf: - rel = opram[PC++ - pc]; + rel = params.r8(PC++); util::stream_format(stream, "djnz r%d,$%04X", op&7, (PC + rel)); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; //MOVX A,@DPTR @@ -1076,7 +1038,7 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //MOV A, data addr case 0xe5: /* 1: 1110 0101 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "mov a,%s", sym); break; @@ -1118,7 +1080,7 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //MOV data addr, A case 0xf5: /* 1: 1111 0101 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "mov %s,a", sym); break; @@ -1144,70 +1106,25 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p util::stream_format(stream, "illegal"); } - return (PC - pc) | flags | DASMFLAG_SUPPORTED; + return (PC - pc) | flags | SUPPORTED; } -CPU_DISASSEMBLE( i8051 ) +i8051_disassembler::i8051_disassembler() : mcs51_disassembler(default_names) { - static const char *mem_names[0x200]; - static int mem_names_initialized = 0; - - if (!mem_names_initialized) - { - init_mem_names( FEATURE_NONE, mem_names); - mem_names_initialized = 1; - } - return mcs51_dasm(mem_names, stream, pc, oprom, opram); } -CPU_DISASSEMBLE( i8052 ) +i8052_disassembler::i8052_disassembler() : mcs51_disassembler(default_names, i8052_names) { - static const char *mem_names[0x200]; - static int mem_names_initialized = 0; - - if (!mem_names_initialized) - { - init_mem_names( FEATURE_I8052, mem_names); - mem_names_initialized = 1; - } - return mcs51_dasm(mem_names, stream, pc, oprom, opram); } -CPU_DISASSEMBLE( i80c51 ) +i80c51_disassembler::i80c51_disassembler() : mcs51_disassembler(default_names, i80c52_names) { - static const char *mem_names[0x200]; - static int mem_names_initialized = 0; - - if (!mem_names_initialized) - { - init_mem_names( FEATURE_CMOS, mem_names); - mem_names_initialized = 1; - } - return mcs51_dasm(mem_names, stream, pc, oprom, opram); } -CPU_DISASSEMBLE( i80c52 ) +i80c52_disassembler::i80c52_disassembler() : mcs51_disassembler(default_names, i80c52_names, i80c52_names) { - static const char *mem_names[0x200]; - static int mem_names_initialized = 0; - - if (!mem_names_initialized) - { - init_mem_names( FEATURE_I8052 | FEATURE_CMOS | FEATURE_I80C52, mem_names); - mem_names_initialized = 1; - } - return mcs51_dasm(mem_names, stream, pc, oprom, opram); } -CPU_DISASSEMBLE( ds5002fp ) +ds5002fp_disassembler::ds5002fp_disassembler() : mcs51_disassembler(default_names, i80c52_names, ds5002fp_names, i8xc751_names) { - static const char *mem_names[0x200]; - static int mem_names_initialized = 0; - - if (!mem_names_initialized) - { - init_mem_names( FEATURE_DS5002FP | FEATURE_CMOS, mem_names); - mem_names_initialized = 1; - } - return mcs51_dasm(mem_names, stream, pc, oprom, opram); } diff --git a/src/devices/cpu/mcs51/mcs51dasm.h b/src/devices/cpu/mcs51/mcs51dasm.h new file mode 100644 index 00000000000..98272befc89 --- /dev/null +++ b/src/devices/cpu/mcs51/mcs51dasm.h @@ -0,0 +1,106 @@ +// license:BSD-3-Clause +// copyright-holders:Steve Ellenoff +/***************************************************************************** + * + * i8051dasm.c + * Portable MCS-51 Family Emulator + * + * Chips in the family: + * 8051 Product Line (8031,8051,8751) + * 8052 Product Line (8032,8052,8752) + * 8054 Product Line (8054) + * 8058 Product Line (8058) + * + * Copyright Steve Ellenoff, all rights reserved. + * + * This work is based on: + * #1) 'Intel(tm) MC51 Microcontroller Family Users Manual' and + * #2) 8051 simulator by Travis Marlatte + * #3) Portable UPI-41/8041/8741/8042/8742 emulator V0.1 by Juergen Buchmueller (MAME CORE) + * + ***************************************************************************** + * Symbol Memory Name Tables borrowed from: + * D52 8052 Disassembler - Copyright Jeffery L. Post + *****************************************************************************/ + +#ifndef MAME_CPU_MCS51_MCS51DASM_H +#define MAME_CPU_MCS51_MCS51DASM_H + +#pragma once + +class mcs51_disassembler : public util::disasm_interface +{ +public: + struct mem_info { + int addr; + const char *name; + }; + + static const mem_info default_names[]; + static const mem_info i8052_names[]; + static const mem_info i80c52_names[]; + static const mem_info ds5002fp_names[]; + static const mem_info i8xc751_names[]; + + template<typename ...Names> mcs51_disassembler(Names &&... names) : mcs51_disassembler() { + add_names(names...); + } + + mcs51_disassembler(); + virtual ~mcs51_disassembler() = default; + + template<typename ...Names> void add_names(const mem_info *info, Names &&... names) + { + add_names(names...); + add_names(info); + } + + void add_names(const mem_info *info); + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + std::unordered_map<offs_t, const char *> m_names; + + std::string get_data_address( uint8_t arg ) const; + std::string get_bit_address( uint8_t arg ) const; +}; + +class i8051_disassembler : public mcs51_disassembler +{ +public: + i8051_disassembler(); + virtual ~i8051_disassembler() = default; +}; + +class i8052_disassembler : public mcs51_disassembler +{ +public: + i8052_disassembler(); + virtual ~i8052_disassembler() = default; +}; + +class i80c51_disassembler : public mcs51_disassembler +{ +public: + i80c51_disassembler(); + virtual ~i80c51_disassembler() = default; +}; + +class i80c52_disassembler : public mcs51_disassembler +{ +public: + i80c52_disassembler(); + virtual ~i80c52_disassembler() = default; +}; + +class ds5002fp_disassembler : public mcs51_disassembler +{ +public: + ds5002fp_disassembler(); + virtual ~ds5002fp_disassembler() = default; +}; + + +#endif diff --git a/src/devices/cpu/mcs96/i8x9x.cpp b/src/devices/cpu/mcs96/i8x9x.cpp index c3a6c7876af..cdb65bd3954 100644 --- a/src/devices/cpu/mcs96/i8x9x.cpp +++ b/src/devices/cpu/mcs96/i8x9x.cpp @@ -10,6 +10,7 @@ #include "emu.h" #include "i8x9x.h" +#include "i8x9xd.h" i8x9x_device::i8x9x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : mcs96_device(mconfig, type, tag, owner, clock, 8), @@ -18,9 +19,9 @@ i8x9x_device::i8x9x_device(const machine_config &mconfig, device_type type, cons { } -offs_t i8x9x_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *i8x9x_device::create_disassembler() { - return disasm_generic(stream, pc, oprom, opram, options, disasm_entries); + return new i8x9x_disassembler; } device_memory_interface::space_config_vector i8x9x_device::memory_space_config() const @@ -72,7 +73,7 @@ void i8x9x_device::commit_hso_cam() void i8x9x_device::ad_start(uint64_t current_time) { - ad_result = (io->read_word(2*((ad_command & 7) + A0)) << 6) | 8 | (ad_command & 7); + ad_result = (io->read_word((ad_command & 7) + A0) << 6) | 8 | (ad_command & 7); ad_done = current_time + 88; internal_update(current_time); } @@ -86,7 +87,7 @@ void i8x9x_device::serial_send(uint8_t data) void i8x9x_device::serial_send_done() { serial_send_timer = 0; - io->write_word(SERIAL*2, serial_send_buf); + io->write_word(SERIAL, serial_send_buf); pending_irq |= IRQ_SERIAL; sp_stat |= 0x20; check_irq(); @@ -133,11 +134,11 @@ void i8x9x_device::io_w8(uint8_t adr, uint8_t data) break; case 0x0f: logerror("%s: io port 1 %02x (%04x)\n", tag(), data, PPC); - io->write_word(P1*2, data); + io->write_word(P1, data); break; case 0x10: logerror("%s: io port 2 %02x (%04x)\n", tag(), data, PPC); - io->write_word(P2*2, data); + io->write_word(P2, data); break; case 0x11: logerror("%s: sp con %02x (%04x)\n", tag(), data, PPC); @@ -216,16 +217,16 @@ uint8_t i8x9x_device::io_r8(uint8_t adr) return timer_value(2, total_cycles()) >> 8; case 0x0e: { static int last = -1; - if(io->read_word(P0*2) != last) { - last = io->read_word(P0*2); + if(io->read_word(P0) != last) { + last = io->read_word(P0); logerror("%s: read p0 %02x\n", tag(), io->read_word(P0*2)); } - return io->read_word(P0*2); + return io->read_word(P0); } case 0x0f: - return io->read_word(P1*2); + return io->read_word(P1); case 0x10: - return io->read_word(P2*2); + return io->read_word(P2); case 0x11: { uint8_t res = sp_stat; sp_stat &= 0x80; diff --git a/src/devices/cpu/mcs96/i8x9x.h b/src/devices/cpu/mcs96/i8x9x.h index 8fda92de323..5684a95afc3 100644 --- a/src/devices/cpu/mcs96/i8x9x.h +++ b/src/devices/cpu/mcs96/i8x9x.h @@ -30,9 +30,8 @@ protected: virtual void device_reset() override; virtual space_config_vector memory_space_config() const override; - static const disasm_entry disasm_entries[0x100]; + virtual util::disasm_interface *create_disassembler() override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; virtual void do_exec_full() override; virtual void do_exec_partial() override; virtual void internal_update(uint64_t current_time) override; diff --git a/src/devices/cpu/mcs96/i8x9xd.cpp b/src/devices/cpu/mcs96/i8x9xd.cpp new file mode 100644 index 00000000000..40b66d9d492 --- /dev/null +++ b/src/devices/cpu/mcs96/i8x9xd.cpp @@ -0,0 +1,19 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + i8x9x.h + + MCS96, 8x9x branch, the original version + +***************************************************************************/ + +#include "emu.h" +#include "i8x9xd.h" + +i8x9x_disassembler::i8x9x_disassembler() : mcs96_disassembler(disasm_entries) +{ +} + +#include "cpu/mcs96/i8x9xd.hxx" + diff --git a/src/devices/cpu/mcs96/i8x9xd.h b/src/devices/cpu/mcs96/i8x9xd.h new file mode 100644 index 00000000000..72227f7933f --- /dev/null +++ b/src/devices/cpu/mcs96/i8x9xd.h @@ -0,0 +1,26 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + i8x9x.h + + MCS96, 8x9x branch, the original version + +***************************************************************************/ + +#ifndef MAME_CPU_MCS96_I8X9XD_H +#define MAME_CPU_MCS96_I8X9XD_H + +#include "mcs96d.h" + +class i8x9x_disassembler : public mcs96_disassembler +{ +public: + i8x9x_disassembler(); + virtual ~i8x9x_disassembler() = default; + +private: + static const disasm_entry disasm_entries[0x100]; +}; + +#endif diff --git a/src/devices/cpu/mcs96/i8xc196.cpp b/src/devices/cpu/mcs96/i8xc196.cpp index adffde72dc0..d415630f0fa 100644 --- a/src/devices/cpu/mcs96/i8xc196.cpp +++ b/src/devices/cpu/mcs96/i8xc196.cpp @@ -10,15 +10,16 @@ #include "emu.h" #include "i8xc196.h" +#include "i8xc196d.h" i8xc196_device::i8xc196_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : mcs96_device(mconfig, type, tag, owner, clock, 16) { } -offs_t i8xc196_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *i8xc196_device::create_disassembler() { - return disasm_generic(stream, pc, oprom, opram, options, disasm_entries); + return new i8xc196_disassembler; } void i8xc196_device::io_w8(uint8_t adr, uint8_t data) diff --git a/src/devices/cpu/mcs96/i8xc196.h b/src/devices/cpu/mcs96/i8xc196.h index bd5489a1721..a82c1ea0515 100644 --- a/src/devices/cpu/mcs96/i8xc196.h +++ b/src/devices/cpu/mcs96/i8xc196.h @@ -17,9 +17,8 @@ class i8xc196_device : public mcs96_device { protected: i8xc196_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); - static const disasm_entry disasm_entries[0x100]; + virtual util::disasm_interface *create_disassembler() override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; virtual void do_exec_full() override; virtual void do_exec_partial() override; diff --git a/src/devices/cpu/mcs96/i8xc196d.cpp b/src/devices/cpu/mcs96/i8xc196d.cpp new file mode 100644 index 00000000000..8d56aad09e7 --- /dev/null +++ b/src/devices/cpu/mcs96/i8xc196d.cpp @@ -0,0 +1,18 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + i8xc196.h + + MCS96, c196 branch, the enhanced 16 bits bus version + +***************************************************************************/ + +#include "emu.h" +#include "i8xc196d.h" + +i8xc196_disassembler::i8xc196_disassembler() : mcs96_disassembler(disasm_entries) +{ +} + +#include "cpu/mcs96/i8xc196d.hxx" diff --git a/src/devices/cpu/mcs96/i8xc196d.h b/src/devices/cpu/mcs96/i8xc196d.h new file mode 100644 index 00000000000..53c4f65db2f --- /dev/null +++ b/src/devices/cpu/mcs96/i8xc196d.h @@ -0,0 +1,26 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + i8xc196.h + + MCS96, c196 branch, the enhanced 16 bits bus version + +***************************************************************************/ + +#ifndef MAME_CPU_MCS96_I8XC196D_H +#define MAME_CPU_MCS96_I8XC196D_H + +#include "mcs96d.h" + +class i8xc196_disassembler : public mcs96_disassembler +{ +public: + i8xc196_disassembler(); + virtual ~i8xc196_disassembler() = default; + +private: + static const disasm_entry disasm_entries[0x100]; +}; + +#endif diff --git a/src/devices/cpu/mcs96/mcs96.cpp b/src/devices/cpu/mcs96/mcs96.cpp index 92a8ed23a37..fa7e75498b3 100644 --- a/src/devices/cpu/mcs96/mcs96.cpp +++ b/src/devices/cpu/mcs96/mcs96.cpp @@ -23,7 +23,7 @@ mcs96_device::mcs96_device(const machine_config &mconfig, device_type type, cons void mcs96_device::device_start() { program = &space(AS_PROGRAM); - direct = &program->direct(); + direct = program->direct<0>(); m_icountptr = &icount; state_add(STATE_GENPC, "GENPC", PC).noshow(); @@ -156,276 +156,6 @@ void mcs96_device::state_string_export(const device_state_entry &entry, std::str } } -std::string mcs96_device::regname(uint8_t reg) -{ - char res[32]; - switch(reg) { - case 0x18: - strcpy(res, "sp"); - break; - - case 0x19: - strcpy(res, "sph"); - break; - - default: - sprintf(res, "%02x", reg); - break; - } - return res; -} - -offs_t mcs96_device::disasm_generic(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options, const disasm_entry *entries) -{ - bool prefix_fe = false; - int off = 0; - if(oprom[0] == 0xfe && entries[oprom[1]].opcode_fe) { - prefix_fe = true; - pc++; - off++; - oprom++; - } - const disasm_entry &e = entries[oprom[0]]; - uint32_t flags = e.flags | DASMFLAG_SUPPORTED; - util::stream_format(stream, "%s", prefix_fe ? e.opcode_fe : e.opcode); - - switch(e.mode) { - case DASM_none: - flags |= 1; - break; - - case DASM_nop_2: - util::stream_format(stream, " %02x", oprom[1]); - flags |= 2; - break; - - case DASM_rel8: { - int delta = oprom[1]; - if(delta & 0x80) - delta -= 0x100; - util::stream_format(stream, " %04x", (pc+2+delta) & 0xffff); - flags |= 2; - break; - } - - case DASM_rel11: { - int delta = ((oprom[0] << 8) | oprom[1]) & 0x7ff; - if(delta & 0x400) - delta -= 0x800; - util::stream_format(stream, " %04x", (pc+2+delta) & 0xffff); - flags |= 2; - break; - } - - case DASM_rel16: { - int delta = oprom[1] | (oprom[2] << 8); - util::stream_format(stream, " %04x", (pc+3+delta) & 0xffff); - flags |= 3; - break; - } - - case DASM_rrel8: { - int delta = oprom[2]; - if(delta & 0x80) - delta -= 0x100; - util::stream_format(stream, " %s, %04x", regname(oprom[1]), (pc+3+delta) & 0xffff); - flags |= 3; - break; - } - - case DASM_brrel8: { - int delta = oprom[2]; - if(delta & 0x80) - delta -= 0x100; - util::stream_format(stream, " %d, %s, %04x", oprom[0] & 7, regname(oprom[1]), (pc+3+delta) & 0xffff); - flags |= 3; - break; - } - - case DASM_direct_1: - util::stream_format(stream, " %s", regname(oprom[1])); - flags |= 2; - break; - - case DASM_direct_2: - util::stream_format(stream, " %s, %s", regname(oprom[2]), regname(oprom[1])); - flags |= 3; - break; - - case DASM_direct_3: - util::stream_format(stream, " %s, %s, %s", regname(oprom[3]), regname(oprom[2]), regname(oprom[1])); - flags |= 4; - break; - - case DASM_immed_1b: - util::stream_format(stream, " #%02x", oprom[1]); - flags |= 2; - break; - - case DASM_immed_2b: - util::stream_format(stream, " %s, #%02x", regname(oprom[2]), oprom[1]); - flags |= 3; - break; - - case DASM_immed_or_reg_2b: - if(oprom[1] >= 0x10) - util::stream_format(stream, " %s, %s", regname(oprom[2]), regname(oprom[1])); - else - util::stream_format(stream, " %s, #%02x", regname(oprom[2]), oprom[1]); - flags |= 3; - break; - - case DASM_immed_3b: - util::stream_format(stream, " %s, %s, #%02x", regname(oprom[3]), regname(oprom[2]), oprom[1]); - flags |= 4; - break; - - case DASM_immed_1w: - util::stream_format(stream, " #%02x%02x", oprom[2], oprom[1]); - flags |= 3; - break; - - case DASM_immed_2w: - util::stream_format(stream, " %s, #%02x%02x", regname(oprom[3]), oprom[2], oprom[1]); - flags |= 4; - break; - - case DASM_immed_3w: - util::stream_format(stream, " %s, %s, #%02x%02x", regname(oprom[4]), regname(oprom[3]), oprom[2], oprom[1]); - flags |= 5; - break; - - case DASM_indirect_1n: - util::stream_format(stream, " [%s]", regname(oprom[1])); - flags |= 2; - break; - - case DASM_indirect_1: - if(oprom[1] & 0x01) { - util::stream_format(stream, " [%s]+", regname(oprom[1]-1)); - flags |= 2; - } else { - util::stream_format(stream, " [%s]", regname(oprom[1])); - flags |= 2; - } - break; - - case DASM_indirect_2: - if(oprom[1] & 0x01) { - util::stream_format(stream, " %s, [%s]+", regname(oprom[2]), regname(oprom[1]-1)); - flags |= 3; - } else { - util::stream_format(stream, " %s, [%s]", regname(oprom[2]), regname(oprom[1])); - flags |= 3; - } - break; - - case DASM_indirect_3: - if(oprom[1] & 0x01) { - util::stream_format(stream, " %s, %s, [%s]+", regname(oprom[3]), regname(oprom[2]), regname(oprom[1]-1)); - flags |= 4; - } else { - util::stream_format(stream, " %s, %s, [%s]", regname(oprom[3]), regname(oprom[2]), regname(oprom[1])); - flags |= 4; - } - break; - - case DASM_indexed_1: - if(oprom[1] & 0x01) { - if(oprom[1] == 0x01) - util::stream_format(stream, " %02x%02x", oprom[3], oprom[2]); - else - util::stream_format(stream, " %02x%02x[%s]", oprom[3], oprom[2], regname(oprom[1]-1)); - flags |= 4; - } else { - int delta = oprom[2]; - if(delta & 0x80) - delta -= 0x100; - if(oprom[1] == 0x00) { - if(delta < 0) - util::stream_format(stream, " %04x", delta & 0xffff); - else - util::stream_format(stream, " %02x", delta); - } else { - if(delta < 0) - util::stream_format(stream, " -%02x[%s]", -delta, regname(oprom[1])); - else - util::stream_format(stream, " %02x[%s]", delta, regname(oprom[1])); - } - flags |= 3; - } - break; - - case DASM_indexed_2: - if(oprom[1] & 0x01) { - if(oprom[1] == 0x01) - util::stream_format(stream, " %s, %02x%02x", regname(oprom[4]), oprom[3], oprom[2]); - else - util::stream_format(stream, " %s, %02x%02x[%s]", regname(oprom[4]), oprom[3], oprom[2], regname(oprom[1]-1)); - flags |= 5; - } else { - int delta = oprom[2]; - if(delta & 0x80) - delta -= 0x100; - if(oprom[1] == 0x00) { - if(delta < 0) - util::stream_format(stream, " %s, %04x", regname(oprom[3]), delta & 0xffff); - else - util::stream_format(stream, " %s, %02x", regname(oprom[3]), delta); - } else { - if(delta < 0) - util::stream_format(stream, " %s, -%02x[%s]", regname(oprom[3]), -delta, regname(oprom[1])); - else - util::stream_format(stream, " %s, %02x[%s]", regname(oprom[3]), delta, regname(oprom[1])); - } - flags |= 4; - } - break; - - case DASM_indexed_3: - if(oprom[1] & 0x01) { - if(oprom[1] == 0x01) - util::stream_format(stream, " %s, %s, %02x%02x", regname(oprom[5]), regname(oprom[4]), oprom[3], oprom[2]); - else - util::stream_format(stream, " %s, %s, %02x%02x[%s]", regname(oprom[5]), regname(oprom[4]), oprom[3], oprom[2], regname(oprom[1]-1)); - flags |= 6; - } else { - int delta = oprom[2]; - if(delta & 0x80) - delta -= 0x100; - if(oprom[1] == 0x00) { - if(delta < 0) - util::stream_format(stream, " %s, %s, %04x", regname(oprom[4]), regname(oprom[3]), delta & 0xffff); - else - util::stream_format(stream, " %s, %s, %02x", regname(oprom[4]), regname(oprom[3]), delta); - } else { - if(delta < 0) - util::stream_format(stream, " %s, %s, -%02x[%s]", regname(oprom[4]), regname(oprom[3]), -delta, regname(oprom[1])); - else - util::stream_format(stream, " %s, %s, %02x[%s]", regname(oprom[4]), regname(oprom[3]), delta, regname(oprom[1])); - } - flags |= 5; - } - break; - - default: - fprintf(stderr, "Unhandled dasm mode %d\n", e.mode); - abort(); - }; - - return flags+off; -} - -uint32_t mcs96_device::disasm_min_opcode_bytes() const -{ - return 1; -} - -uint32_t mcs96_device::disasm_max_opcode_bytes() const -{ - return 7; -} - void mcs96_device::io_w8(uint8_t adr, uint8_t data) { switch(adr) { diff --git a/src/devices/cpu/mcs96/mcs96.h b/src/devices/cpu/mcs96/mcs96.h index 159d04bbdc3..3ff9f02d4d2 100644 --- a/src/devices/cpu/mcs96/mcs96.h +++ b/src/devices/cpu/mcs96/mcs96.h @@ -41,38 +41,6 @@ protected: F_Z = 0x8000 }; - struct disasm_entry { - const char *opcode, *opcode_fe; - int mode; - offs_t flags; - }; - - enum { - DASM_none, /* No parameters */ - DASM_nop_2, /* One ignored parameter byte */ - DASM_rel8, /* Relative, 8 bits */ - DASM_rel11, /* Relative, 11 bits */ - DASM_rel16, /* Relative, 16 bits */ - DASM_rrel8, /* Register + relative, 8 bits */ - DASM_brrel8, /* Bit test + register + relative, 8 bits */ - DASM_direct_1, /* Register-direct references, 1 operator */ - DASM_direct_2, /* Register-direct references, 2 operators */ - DASM_direct_3, /* Register-direct references, 3 operators */ - DASM_immed_1b, /* Immediate references to byte, 1 operator */ - DASM_immed_2b, /* Immediate references to byte, 2 operators */ - DASM_immed_or_reg_2b, /* Immediate references to byte or register, 2 operators */ - DASM_immed_3b, /* Immediate references to byte, 3 operators */ - DASM_immed_1w, /* Immediate references to word, 1 operator */ - DASM_immed_2w, /* Immediate references to word, 2 operators */ - DASM_immed_3w, /* Immediate references to word, 3 operators */ - DASM_indirect_1n, /* Indirect normal, 1 operator */ - DASM_indirect_1, /* Indirect, normal or auto-incrementing, 1 operator */ - DASM_indirect_2, /* Indirect, normal or auto-incrementing, 2 operators */ - DASM_indirect_3, /* Indirect, normal or auto-incrementing, 3 operators */ - DASM_indexed_1, /* Indexed, short or long, 1 operator */ - DASM_indexed_2, /* Indexed, short or long, 2 operators */ - DASM_indexed_3 /* Indexed, short or long, 3 operators */ - }; mcs96_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int data_width); @@ -95,14 +63,9 @@ protected: virtual void state_export(const device_state_entry &entry) override; virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; - // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_generic(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options, const disasm_entry *entries); - address_space_config program_config; address_space *program; - direct_read_data *direct; + direct_read_data<0> *direct; int icount, bcount, inst_state, cycles_scaling; uint8_t pending_irq; @@ -122,7 +85,6 @@ protected: virtual uint16_t io_r16(uint8_t adr) = 0; void recompute_bcount(uint64_t event_time); - static std::string regname(uint8_t reg); inline void next(int cycles) { icount -= cycles_scaling*cycles; inst_state = STATE_FETCH; } inline void next_noirq(int cycles) { icount -= cycles_scaling*cycles; inst_state = STATE_FETCH_NOIRQ; } diff --git a/src/devices/cpu/mcs96/mcs96d.cpp b/src/devices/cpu/mcs96/mcs96d.cpp new file mode 100644 index 00000000000..1508fb3ca5f --- /dev/null +++ b/src/devices/cpu/mcs96/mcs96d.cpp @@ -0,0 +1,278 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + mcs96.h + + MCS96, 8098/8398/8798 branch + +***************************************************************************/ + +#include "emu.h" +#include "mcs96d.h" + +mcs96_disassembler::mcs96_disassembler(const disasm_entry *entries) : m_entries(entries) +{ +} + +u32 mcs96_disassembler::opcode_alignment() const +{ + return 1; +} + +std::string mcs96_disassembler::regname(uint8_t reg) +{ + switch(reg) { + case 0x18: + return "sp"; + break; + + case 0x19: + return "sph"; + break; + + default: + return util::string_format("%02x", reg); + break; + } +} + +offs_t mcs96_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + bool prefix_fe = false; + int off = 0; + if(opcodes.r8(pc) == 0xfe && m_entries[opcodes.r8(pc+1)].opcode_fe) { + prefix_fe = true; + pc++; + off++; + } + const disasm_entry &e = m_entries[opcodes.r8(pc)]; + uint32_t flags = e.flags | SUPPORTED; + util::stream_format(stream, "%s", prefix_fe ? e.opcode_fe : e.opcode); + + switch(e.mode) { + case DASM_none: + flags |= 1; + break; + + case DASM_nop_2: + util::stream_format(stream, " %02x", opcodes.r8(pc+1)); + flags |= 2; + break; + + case DASM_rel8: { + int delta = opcodes.r8(pc+1); + if(delta & 0x80) + delta -= 0x100; + util::stream_format(stream, " %04x", (pc+2+delta) & 0xffff); + flags |= 2; + break; + } + + case DASM_rel11: { + int delta = ((opcodes.r8(pc) << 8) | opcodes.r8(pc+1)) & 0x7ff; + if(delta & 0x400) + delta -= 0x800; + util::stream_format(stream, " %04x", (pc+2+delta) & 0xffff); + flags |= 2; + break; + } + + case DASM_rel16: { + int delta = opcodes.r8(pc+1) | (opcodes.r8(pc+2) << 8); + util::stream_format(stream, " %04x", (pc+3+delta) & 0xffff); + flags |= 3; + break; + } + + case DASM_rrel8: { + int delta = opcodes.r8(pc+2); + if(delta & 0x80) + delta -= 0x100; + util::stream_format(stream, " %s, %04x", regname(opcodes.r8(pc+1)), (pc+3+delta) & 0xffff); + flags |= 3; + break; + } + + case DASM_brrel8: { + int delta = opcodes.r8(pc+2); + if(delta & 0x80) + delta -= 0x100; + util::stream_format(stream, " %d, %s, %04x", opcodes.r8(pc) & 7, regname(opcodes.r8(pc+1)), (pc+3+delta) & 0xffff); + flags |= 3; + break; + } + + case DASM_direct_1: + util::stream_format(stream, " %s", regname(opcodes.r8(pc+1))); + flags |= 2; + break; + + case DASM_direct_2: + util::stream_format(stream, " %s, %s", regname(opcodes.r8(pc+2)), regname(opcodes.r8(pc+1))); + flags |= 3; + break; + + case DASM_direct_3: + util::stream_format(stream, " %s, %s, %s", regname(opcodes.r8(pc+3)), regname(opcodes.r8(pc+2)), regname(opcodes.r8(pc+1))); + flags |= 4; + break; + + case DASM_immed_1b: + util::stream_format(stream, " #%02x", opcodes.r8(pc+1)); + flags |= 2; + break; + + case DASM_immed_2b: + util::stream_format(stream, " %s, #%02x", regname(opcodes.r8(pc+2)), opcodes.r8(pc+1)); + flags |= 3; + break; + + case DASM_immed_or_reg_2b: + if(opcodes.r8(pc+1) >= 0x10) + util::stream_format(stream, " %s, %s", regname(opcodes.r8(pc+2)), regname(opcodes.r8(pc+1))); + else + util::stream_format(stream, " %s, #%02x", regname(opcodes.r8(pc+2)), opcodes.r8(pc+1)); + flags |= 3; + break; + + case DASM_immed_3b: + util::stream_format(stream, " %s, %s, #%02x", regname(opcodes.r8(pc+3)), regname(opcodes.r8(pc+2)), opcodes.r8(pc+1)); + flags |= 4; + break; + + case DASM_immed_1w: + util::stream_format(stream, " #%02x%02x", opcodes.r8(pc+2), opcodes.r8(pc+1)); + flags |= 3; + break; + + case DASM_immed_2w: + util::stream_format(stream, " %s, #%02x%02x", regname(opcodes.r8(pc+3)), opcodes.r8(pc+2), opcodes.r8(pc+1)); + flags |= 4; + break; + + case DASM_immed_3w: + util::stream_format(stream, " %s, %s, #%02x%02x", regname(opcodes.r8(pc+4)), regname(opcodes.r8(pc+3)), opcodes.r8(pc+2), opcodes.r8(pc+1)); + flags |= 5; + break; + + case DASM_indirect_1n: + util::stream_format(stream, " [%s]", regname(opcodes.r8(pc+1))); + flags |= 2; + break; + + case DASM_indirect_1: + if(opcodes.r8(pc+1) & 0x01) { + util::stream_format(stream, " [%s]+", regname(opcodes.r8(pc+1)-1)); + flags |= 2; + } else { + util::stream_format(stream, " [%s]", regname(opcodes.r8(pc+1))); + flags |= 2; + } + break; + + case DASM_indirect_2: + if(opcodes.r8(pc+1) & 0x01) { + util::stream_format(stream, " %s, [%s]+", regname(opcodes.r8(pc+2)), regname(opcodes.r8(pc+1)-1)); + flags |= 3; + } else { + util::stream_format(stream, " %s, [%s]", regname(opcodes.r8(pc+2)), regname(opcodes.r8(pc+1))); + flags |= 3; + } + break; + + case DASM_indirect_3: + if(opcodes.r8(pc+1) & 0x01) { + util::stream_format(stream, " %s, %s, [%s]+", regname(opcodes.r8(pc+3)), regname(opcodes.r8(pc+2)), regname(opcodes.r8(pc+1)-1)); + flags |= 4; + } else { + util::stream_format(stream, " %s, %s, [%s]", regname(opcodes.r8(pc+3)), regname(opcodes.r8(pc+2)), regname(opcodes.r8(pc+1))); + flags |= 4; + } + break; + + case DASM_indexed_1: + if(opcodes.r8(pc+1) & 0x01) { + if(opcodes.r8(pc+1) == 0x01) + util::stream_format(stream, " %02x%02x", opcodes.r8(pc+3), opcodes.r8(pc+2)); + else + util::stream_format(stream, " %02x%02x[%s]", opcodes.r8(pc+3), opcodes.r8(pc+2), regname(opcodes.r8(pc+1)-1)); + flags |= 4; + } else { + int delta = opcodes.r8(pc+2); + if(delta & 0x80) + delta -= 0x100; + if(opcodes.r8(pc+1) == 0x00) { + if(delta < 0) + util::stream_format(stream, " %04x", delta & 0xffff); + else + util::stream_format(stream, " %02x", delta); + } else { + if(delta < 0) + util::stream_format(stream, " -%02x[%s]", -delta, regname(opcodes.r8(pc+1))); + else + util::stream_format(stream, " %02x[%s]", delta, regname(opcodes.r8(pc+1))); + } + flags |= 3; + } + break; + + case DASM_indexed_2: + if(opcodes.r8(pc+1) & 0x01) { + if(opcodes.r8(pc+1) == 0x01) + util::stream_format(stream, " %s, %02x%02x", regname(opcodes.r8(pc+4)), opcodes.r8(pc+3), opcodes.r8(pc+2)); + else + util::stream_format(stream, " %s, %02x%02x[%s]", regname(opcodes.r8(pc+4)), opcodes.r8(pc+3), opcodes.r8(pc+2), regname(opcodes.r8(pc+1)-1)); + flags |= 5; + } else { + int delta = opcodes.r8(pc+2); + if(delta & 0x80) + delta -= 0x100; + if(opcodes.r8(pc+1) == 0x00) { + if(delta < 0) + util::stream_format(stream, " %s, %04x", regname(opcodes.r8(pc+3)), delta & 0xffff); + else + util::stream_format(stream, " %s, %02x", regname(opcodes.r8(pc+3)), delta); + } else { + if(delta < 0) + util::stream_format(stream, " %s, -%02x[%s]", regname(opcodes.r8(pc+3)), -delta, regname(opcodes.r8(pc+1))); + else + util::stream_format(stream, " %s, %02x[%s]", regname(opcodes.r8(pc+3)), delta, regname(opcodes.r8(pc+1))); + } + flags |= 4; + } + break; + + case DASM_indexed_3: + if(opcodes.r8(pc+1) & 0x01) { + if(opcodes.r8(pc+1) == 0x01) + util::stream_format(stream, " %s, %s, %02x%02x", regname(opcodes.r8(pc+5)), regname(opcodes.r8(pc+4)), opcodes.r8(pc+3), opcodes.r8(pc+2)); + else + util::stream_format(stream, " %s, %s, %02x%02x[%s]", regname(opcodes.r8(pc+5)), regname(opcodes.r8(pc+4)), opcodes.r8(pc+3), opcodes.r8(pc+2), regname(opcodes.r8(pc+1)-1)); + flags |= 6; + } else { + int delta = opcodes.r8(pc+2); + if(delta & 0x80) + delta -= 0x100; + if(opcodes.r8(pc+1) == 0x00) { + if(delta < 0) + util::stream_format(stream, " %s, %s, %04x", regname(opcodes.r8(pc+4)), regname(opcodes.r8(pc+3)), delta & 0xffff); + else + util::stream_format(stream, " %s, %s, %02x", regname(opcodes.r8(pc+4)), regname(opcodes.r8(pc+3)), delta); + } else { + if(delta < 0) + util::stream_format(stream, " %s, %s, -%02x[%s]", regname(opcodes.r8(pc+4)), regname(opcodes.r8(pc+3)), -delta, regname(opcodes.r8(pc+1))); + else + util::stream_format(stream, " %s, %s, %02x[%s]", regname(opcodes.r8(pc+4)), regname(opcodes.r8(pc+3)), delta, regname(opcodes.r8(pc+1))); + } + flags |= 5; + } + break; + + default: + fprintf(stderr, "Unhandled dasm mode %d\n", e.mode); + abort(); + }; + + return flags+off; +} diff --git a/src/devices/cpu/mcs96/mcs96d.h b/src/devices/cpu/mcs96/mcs96d.h new file mode 100644 index 00000000000..453727258bf --- /dev/null +++ b/src/devices/cpu/mcs96/mcs96d.h @@ -0,0 +1,64 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert, R. Belmont +/*************************************************************************** + + mcs96.h + + MCS96 + +***************************************************************************/ + +#ifndef MAME_CPU_MCS96_MCS96D_H +#define MAME_CPU_MCS96_MCS96D_H + +#pragma once + +class mcs96_disassembler : public util::disasm_interface +{ +public: + struct disasm_entry { + const char *opcode, *opcode_fe; + int mode; + offs_t flags; + }; + + mcs96_disassembler(const disasm_entry *entries); + virtual ~mcs96_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +protected: + enum { + DASM_none, /* No parameters */ + DASM_nop_2, /* One ignored parameter byte */ + DASM_rel8, /* Relative, 8 bits */ + DASM_rel11, /* Relative, 11 bits */ + DASM_rel16, /* Relative, 16 bits */ + DASM_rrel8, /* Register + relative, 8 bits */ + DASM_brrel8, /* Bit test + register + relative, 8 bits */ + DASM_direct_1, /* Register-direct references, 1 operator */ + DASM_direct_2, /* Register-direct references, 2 operators */ + DASM_direct_3, /* Register-direct references, 3 operators */ + DASM_immed_1b, /* Immediate references to byte, 1 operator */ + DASM_immed_2b, /* Immediate references to byte, 2 operators */ + DASM_immed_or_reg_2b, /* Immediate references to byte or register, 2 operators */ + DASM_immed_3b, /* Immediate references to byte, 3 operators */ + DASM_immed_1w, /* Immediate references to word, 1 operator */ + DASM_immed_2w, /* Immediate references to word, 2 operators */ + DASM_immed_3w, /* Immediate references to word, 3 operators */ + DASM_indirect_1n, /* Indirect normal, 1 operator */ + DASM_indirect_1, /* Indirect, normal or auto-incrementing, 1 operator */ + DASM_indirect_2, /* Indirect, normal or auto-incrementing, 2 operators */ + DASM_indirect_3, /* Indirect, normal or auto-incrementing, 3 operators */ + DASM_indexed_1, /* Indexed, short or long, 1 operator */ + DASM_indexed_2, /* Indexed, short or long, 2 operators */ + DASM_indexed_3 /* Indexed, short or long, 3 operators */ + }; + + const disasm_entry *m_entries; + + static std::string regname(uint8_t reg); +}; + +#endif diff --git a/src/devices/cpu/mcs96/mcs96make.py b/src/devices/cpu/mcs96/mcs96make.py index b4844942e3d..2a9398cd662 100644 --- a/src/devices/cpu/mcs96/mcs96make.py +++ b/src/devices/cpu/mcs96/mcs96make.py @@ -117,7 +117,7 @@ class OpcodeList: self.opcode_per_id[i] = inf def save_dasm(self, f, t): - print("const %s_device::disasm_entry %s_device::disasm_entries[0x100] = {" % (t, t), file=f) + print("const %s_disassembler::disasm_entry %s_disassembler::disasm_entries[0x100] = {" % (t, t), file=f) for i in range(0, 0x100): if i in self.opcode_per_id: opc = self.opcode_per_id[i] @@ -125,9 +125,9 @@ class OpcodeList: if i + 0xfe00 in self.opcode_per_id: alt = "\"" + self.opcode_per_id[i+0xfe00].name + "\"" if opc.name == "scall" or opc.name == "lcall": - flags = "DASMFLAG_STEP_OVER" + flags = "STEP_OVER" elif opc.name == "rts": - flags = "DASMFLAG_STEP_OUT" + flags = "STEP_OUT" else: flags = "0" print("\t{ \"%s\", %s, DASM_%s, %s }," % (opc.name, alt, opc.amode, flags), file=f) @@ -170,25 +170,26 @@ class OpcodeList: print("}", file=f) def main(argv): - if len(argv) != 4: + if len(argv) != 5: print(USAGE % argv[0]) return 1 - - t = argv[1] - opcodes = OpcodeList(argv[2], t == "i8xc196") + + m = argv[1] + t = argv[2] + opcodes = OpcodeList(argv[3], t == "i8xc196") try: - f = open(argv[3], "w") + f = open(argv[4], "w") except Exception: err = sys.exc_info()[1] - sys.stderr.write("cannot write file %s [%s]\n" % (argv[3], err)) + sys.stderr.write("cannot write file %s [%s]\n" % (argv[4], err)) sys.exit(1) - if t != "mcs96": + if t != "mcs96" and m == "d": opcodes.save_dasm(f, t) - if t != "i8x9x": + if t != "i8x9x" and m == "s": opcodes.save_opcodes(f, t) - if t != "mcs96": + if t != "mcs96" and m == "s": opcodes.save_exec(f, t) f.close() diff --git a/src/devices/cpu/melps4/m58846.cpp b/src/devices/cpu/melps4/m58846.cpp index 6f4924da86e..48c75803439 100644 --- a/src/devices/cpu/melps4/m58846.cpp +++ b/src/devices/cpu/melps4/m58846.cpp @@ -30,15 +30,6 @@ m58846_device::m58846_device(const machine_config &mconfig, const char *tag, dev { } -// disasm -offs_t m58846_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) -{ - extern CPU_DISASSEMBLE(m58846); - return CPU_DISASSEMBLE_NAME(m58846)(this, stream, pc, oprom, opram, options); -} - - - //------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- diff --git a/src/devices/cpu/melps4/m58846.h b/src/devices/cpu/melps4/m58846.h index 4a3bf8674bf..34042e6a61b 100644 --- a/src/devices/cpu/melps4/m58846.h +++ b/src/devices/cpu/melps4/m58846.h @@ -29,9 +29,6 @@ protected: // device_execute_interface overrides virtual void execute_one() override; - // device_disasm_interface overrides - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; - // timers virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; virtual void write_v(uint8_t data) override; diff --git a/src/devices/cpu/melps4/melps4.cpp b/src/devices/cpu/melps4/melps4.cpp index bf386f1e30d..a749f4bc5c6 100644 --- a/src/devices/cpu/melps4/melps4.cpp +++ b/src/devices/cpu/melps4/melps4.cpp @@ -39,6 +39,7 @@ #include "emu.h" #include "melps4.h" +#include "melps4d.h" #include "debugger.h" @@ -453,7 +454,7 @@ void melps4_cpu_device::execute_run() // fetch next opcode debugger_instruction_hook(this, m_pc); m_icount--; - m_op = m_program->read_word(m_pc << 1) & 0x1ff; + m_op = m_program->read_word(m_pc) & 0x1ff; m_bitmask = 1 << (m_op & 3); m_pc = (m_pc & ~0x7f) | ((m_pc + 1) & 0x7f); // stays in the same page @@ -471,3 +472,8 @@ void melps4_cpu_device::execute_run() execute_one(); } } + +util::disasm_interface *melps4_cpu_device::create_disassembler() +{ + return new melps4_disassembler; +} diff --git a/src/devices/cpu/melps4/melps4.h b/src/devices/cpu/melps4/melps4.h index 1f9a7752cd6..c268d74e508 100644 --- a/src/devices/cpu/melps4/melps4.h +++ b/src/devices/cpu/melps4/melps4.h @@ -135,8 +135,8 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 2; } + virtual util::disasm_interface *create_disassembler() override; + virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; address_space_config m_program_config; diff --git a/src/devices/cpu/melps4/melps4d.cpp b/src/devices/cpu/melps4/melps4d.cpp index efd199097c5..8ab9c0bd2c7 100644 --- a/src/devices/cpu/melps4/melps4d.cpp +++ b/src/devices/cpu/melps4/melps4d.cpp @@ -10,27 +10,9 @@ */ #include "emu.h" -#include "debugger.h" -#include "melps4.h" +#include "melps4d.h" - -// opcode mnemonics -enum e_mnemonics -{ - em_ILL, - em_TAB, em_TBA, em_TAY, em_TYA, em_TEAB, em_TABE, em_TEPA, em_TXA, em_TAX, - em_LXY, em_LZ, em_INY, em_DEY, em_LCPS, em_SADR, - em_TAM, em_XAM, em_XAMD, em_XAMI, - em_LA, em_AM, em_AMC, em_AMCS, em_A, em_SC, em_RC, em_SZC, em_CMA, em_RL, em_RR, - em_SB, em_RB, em_SZB, em_SEAM, em_SEY, - em_TLA, em_THA, em_TAJ, em_XAL, em_XAH, em_LC7, em_DEC, em_SHL, em_RHL, em_CPA, em_CPAS, em_CPAE, em_SZJ, - em_T1AB, em_TRAB, em_T2AB, em_TAB1, em_TABR, em_TAB2, em_TVA, em_TWA, em_SNZ1, em_SNZ2, - em_BA, em_SP, em_B, em_BM, em_RT, em_RTS, em_RTI, - em_CLD, em_CLS, em_CLDS, em_SD, em_RD, em_SZD, em_OSAB, em_OSPA, em_OSE, em_IAS, em_OFA, em_IAF, em_OGA, em_IAK, em_SZK, em_SU, em_RU, - em_EI, em_DI, em_INTH, em_INTL, em_NOP -}; - -static const char *const em_name[] = +const char *const melps4_disassembler::em_name[] = { "?", "TAB", "TBA", "TAY", "TYA", "TEAB", "TABE", "TEPA", "TXA", "TAX", @@ -46,7 +28,7 @@ static const char *const em_name[] = }; // number of bits per opcode parameter -static const uint8_t em_bits[] = +const uint8_t melps4_disassembler::em_bits[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -61,10 +43,7 @@ static const uint8_t em_bits[] = 0, 0, 0, 0, 0 }; -#define _OVER DASMFLAG_STEP_OVER -#define _OUT DASMFLAG_STEP_OUT - -static const uint32_t em_flags[] = +const uint32_t melps4_disassembler::em_flags[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -74,7 +53,7 @@ static const uint32_t em_flags[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, _OVER, _OUT, _OUT, _OUT, + 0, 0, 0, STEP_OVER, STEP_OUT, STEP_OUT, STEP_OUT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; @@ -83,7 +62,7 @@ static const uint32_t em_flags[] = // M58846 disasm -static const uint8_t m58846_opmap[0xc0] = +const uint8_t melps4_disassembler::m58846_opmap[0xc0] = { // 0 1 2 3 4 5 6 7 8 9 A B C D E F em_NOP, em_BA, em_INY, em_DEY, em_DI, em_EI, em_RU, em_SU, 0, em_TABE, em_AM, em_OSE, em_TYA, 0, 0, em_CMA, // 0x @@ -100,9 +79,9 @@ static const uint8_t m58846_opmap[0xc0] = em_LA, em_LA, em_LA, em_LA, em_LA, em_LA, em_LA, em_LA, em_LA, em_LA, em_LA, em_LA, em_LA, em_LA, em_LA, em_LA // Bx }; -CPU_DISASSEMBLE(m58846) +offs_t melps4_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - uint16_t op = (oprom[0] | oprom[1] << 8) & 0x1ff; + uint16_t op = opcodes.r16(pc) & 0x1ff; // get opcode uint8_t instr; @@ -136,5 +115,20 @@ CPU_DISASSEMBLE(m58846) util::stream_format(stream, " %d", param); } - return 1 | em_flags[instr] | DASMFLAG_SUPPORTED; + return 1 | em_flags[instr] | SUPPORTED; +} + +u32 melps4_disassembler::opcode_alignment() const +{ + return 1; +} + +u32 melps4_disassembler::interface_flags() const +{ + return PAGED; +} + +u32 melps4_disassembler::page_address_bits() const +{ + return 7; } diff --git a/src/devices/cpu/melps4/melps4d.h b/src/devices/cpu/melps4/melps4d.h new file mode 100644 index 00000000000..229358e7432 --- /dev/null +++ b/src/devices/cpu/melps4/melps4d.h @@ -0,0 +1,52 @@ +// license:BSD-3-Clause +// copyright-holders:hap +/* + + Mitsubishi MELPS 4 MCU family disassembler + + Not counting the extra opcodes for peripherals (eg. timers, A/D), + each MCU in the series has small differences in the opcode map. + +*/ + +#ifndef MAME_CPU_MELPS4_MELPS4D_H +#define MAME_CPU_MELPS4_MELPS4D_H + +#pragma once + +class melps4_disassembler : public util::disasm_interface +{ +public: + melps4_disassembler() = default; + virtual ~melps4_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual u32 interface_flags() const override; + virtual u32 page_address_bits() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + // opcode mnemonics + enum e_mnemonics + { + em_ILL, + em_TAB, em_TBA, em_TAY, em_TYA, em_TEAB, em_TABE, em_TEPA, em_TXA, em_TAX, + em_LXY, em_LZ, em_INY, em_DEY, em_LCPS, em_SADR, + em_TAM, em_XAM, em_XAMD, em_XAMI, + em_LA, em_AM, em_AMC, em_AMCS, em_A, em_SC, em_RC, em_SZC, em_CMA, em_RL, em_RR, + em_SB, em_RB, em_SZB, em_SEAM, em_SEY, + em_TLA, em_THA, em_TAJ, em_XAL, em_XAH, em_LC7, em_DEC, em_SHL, em_RHL, em_CPA, em_CPAS, em_CPAE, em_SZJ, + em_T1AB, em_TRAB, em_T2AB, em_TAB1, em_TABR, em_TAB2, em_TVA, em_TWA, em_SNZ1, em_SNZ2, + em_BA, em_SP, em_B, em_BM, em_RT, em_RTS, em_RTI, + em_CLD, em_CLS, em_CLDS, em_SD, em_RD, em_SZD, em_OSAB, em_OSPA, em_OSE, em_IAS, em_OFA, em_IAF, em_OGA, em_IAK, em_SZK, em_SU, em_RU, + em_EI, em_DI, em_INTH, em_INTL, em_NOP + }; + + static const char *const em_name[]; + static const uint8_t em_bits[]; + static const uint32_t em_flags[]; + static const uint8_t m58846_opmap[0xc0]; + +}; + +#endif diff --git a/src/devices/cpu/minx/minx.cpp b/src/devices/cpu/minx/minx.cpp index 883abb6f843..7e4a898e22c 100644 --- a/src/devices/cpu/minx/minx.cpp +++ b/src/devices/cpu/minx/minx.cpp @@ -46,6 +46,7 @@ TODO: #include "emu.h" #include "minx.h" +#include "minxd.h" #include "debugger.h" #define FLAG_I 0x80 @@ -234,8 +235,7 @@ void minx_cpu_device::execute_set_input(int inputnum, int state) } -offs_t minx_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *minx_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( minx ); - return CPU_DISASSEMBLE_NAME(minx)(this, stream, pc, oprom, opram, options); + return new minx_disassembler; } diff --git a/src/devices/cpu/minx/minx.h b/src/devices/cpu/minx/minx.h index babc3d182aa..57f0456c76b 100644 --- a/src/devices/cpu/minx/minx.h +++ b/src/devices/cpu/minx/minx.h @@ -39,9 +39,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 5; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; diff --git a/src/devices/cpu/minx/minxd.cpp b/src/devices/cpu/minx/minxd.cpp index 0e3b9d5b090..413f588369f 100644 --- a/src/devices/cpu/minx/minxd.cpp +++ b/src/devices/cpu/minx/minxd.cpp @@ -8,61 +8,10 @@ ************************************************************/ #include "emu.h" -#include "debugger.h" -#include "minx.h" +#include "minxd.h" -enum e_mnemonic { - zADD=0, zADDC, zAND, zBCDD, zBCDE, zBCDX, zCALL, zCALLC, zCALLG, zCALLGE, zCALLL, - zCALLLE, zCALLN, zCALLNC, zCALLNO, zCALLNZ, zCALLO, zCALLP, zCALLNX0, - zCALLNX1, zCALLNX2, zCALLNX3, zCALLX0, zCALLX1, zCALLX2, zCALLX3, zCALLZ, - zCMP, zCMPN, zDEC, zDIV, zEXT, zHALT, zINC, zINT, - zJC, zJDBNZ, zJG, zJGE, zJINT, zJL, zJLE, zJMP, - zJN, zJNX0, zJNX1, zJNX2, zJNX3, zJNC, zJNO, zJNZ, - zJO, zJP, zJX0, zJX1, zJX2, zJX3, zJZ, zMOV, - zMUL, zNEG, zNOP, zNOT, zOR, zPOP, zPOPA, zPOPAX, - zPOPX, zPUSH, zPUSHA, zPUSHAX, zPUSHX, zRET, zRETI, zRETSKIP, - zROL, zROLC, zROR, zRORC, zSAL, zSAR, zSHL, zSHR, zSUB, - zSUBC, zTEST, zXCHG, zXOR, zDB -}; - -enum e_operand { - R_A=1, /* A */ - R_B, /* B */ - R_L, /* L */ - R_H, /* H */ - R_N, /* N */ - R_F, /* F */ - R_SP, /* SP */ - R_BA, /* BA */ - R_HL, /* HL */ - R_X, /* X */ - R_Y, /* Y */ - R_U, /* U */ - R_V, /* V */ - R_I, /* I */ - R_XI, /* XI */ - R_YI, /* YI */ - R_PC, /* PC */ - I_8, /* 8 bit immediate */ - I_16, /* 16 bit immediate */ - D_8, /* PC + 8 bit displacement (signed) */ - D_16, /* PC + 16 bit displacement */ - S_8, /* SP + 8 bit displacement (signed) */ - M_IHL, /* [I+HL] */ - M_N8, /* [I+N+ofs8] */ - M_I16, /* [I+ofs16] */ - M_X, /* [X] */ - M_Y, /* [Y] */ - M_X8, /* [X + 8 bit displacement (signed)] */ - M_Y8, /* [Y + 8 bit displacement (signed)] */ - M_XL, /* [X + L (signed)] */ - M_YL, /* [Y + L (signed)] */ - M_16, /* [16bit] */ - M_HL, /* [HL] */ - OP, OP1 -}; -static const char *const s_mnemonic[] = { +const char *const minx_disassembler::s_mnemonic[] = { "add", "addc", "and", "bcdd", "bcde", "bcdx", "call", "callc", "callg", "callge", "calll", "callle", "calln", "callnc", "callno", "callnz", "callo", "callp", "callnx0", "callnx1", "callnx2", "callnx3", "callx0", "callx1", "callx2", "callx3", "callz", @@ -76,30 +25,21 @@ static const char *const s_mnemonic[] = { "subc", "test", "xchg", "xor", "db" }; -#define _OVER DASMFLAG_STEP_OVER -#define _OUT DASMFLAG_STEP_OUT - -static const uint32_t s_flags[] = { - 0, 0, 0, 0, 0, 0, _OVER, _OVER, _OVER, _OVER, _OVER, - _OVER, _OVER, _OVER, _OVER, _OVER, _OVER, _OVER, _OVER, - _OVER, _OVER, _OVER, _OVER, _OVER, _OVER, _OVER, _OVER, - 0, 0, 0, 0, 0, _OVER, 0, _OVER, +const uint32_t minx_disassembler::s_flags[] = { + 0, 0, 0, 0, 0, 0, STEP_OVER, STEP_OVER, STEP_OVER, STEP_OVER, STEP_OVER, + STEP_OVER, STEP_OVER, STEP_OVER, STEP_OVER, STEP_OVER, STEP_OVER, STEP_OVER, STEP_OVER, + STEP_OVER, STEP_OVER, STEP_OVER, STEP_OVER, STEP_OVER, STEP_OVER, STEP_OVER, STEP_OVER, + 0, 0, 0, 0, 0, STEP_OVER, 0, STEP_OVER, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, _OUT, _OUT, _OUT, + 0, 0, 0, 0, 0, STEP_OUT, STEP_OUT, STEP_OUT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; -struct minxdasm { - uint8_t mnemonic; - uint8_t argument1; - uint8_t argument2; -}; - -static const minxdasm mnemonic[256] = { +const minx_disassembler::minxdasm minx_disassembler::mnemonic[256] = { /* 00 - 0F */ {zADD,R_A,R_A}, {zADD,R_A,R_B}, {zADD,R_A,I_8}, {zADD,R_A,M_IHL}, {zADD,R_A,M_N8}, {zADD,R_A,M_I16}, {zADD,R_A,M_X}, {zADD,R_A,M_Y}, @@ -182,7 +122,7 @@ static const minxdasm mnemonic[256] = { {zINT,I_8,0}, {zJINT,I_8,0}, {zDB,OP,0}, {zNOP,0,0} }; -static const minxdasm mnemonic_ce[256] = { +const minx_disassembler::minxdasm minx_disassembler::mnemonic_ce[256] = { /* 00 - 0F */ {zADD,R_A,M_X8}, {zADD,R_A,M_Y8}, {zADD,R_A,M_XL}, {zADD,R_A,M_YL}, {zADD,M_IHL,R_A}, {zADD,M_IHL,I_8}, {zADD,M_IHL,M_X}, {zADD,M_IHL,M_Y}, @@ -265,7 +205,7 @@ static const minxdasm mnemonic_ce[256] = { {zCALLX0,D_8,0}, {zCALLX1,D_8,0}, {zCALLX2,D_8,0}, {zCALLX3,D_8,0} }; -static const minxdasm mnemonic_cf[256] = { +const minx_disassembler::minxdasm minx_disassembler::mnemonic_cf[256] = { /* 00 - 0F */ {zADD,R_BA,R_BA}, {zADD,R_BA,R_HL}, {zADD,R_BA,R_X}, {zADD,R_BA,R_Y}, {zADDC,R_BA,R_BA}, {zADDC,R_BA,R_HL}, {zADDC,R_BA,R_X}, {zADDC,R_BA,R_Y}, @@ -367,76 +307,81 @@ case R_XI: util::stream_format(stream, "%cXI", fill); break; \ case R_YI: util::stream_format(stream, "%cYI", fill); break; \ case R_PC: util::stream_format(stream, "%cPC", fill); break; \ case I_8: /* 8 bit immediate */ \ - ea = oprom[pos++]; \ + ea = opcodes.r8(pos++); \ util::stream_format(stream, "%c$%02X", fill, ea); \ break; \ case I_16: /* 16 bit immediate */ \ - ea = oprom[pos++]; \ - ea += oprom[pos++] << 8; \ + ea = opcodes.r8(pos++); \ + ea += opcodes.r8(pos++) << 8; \ util::stream_format(stream, "%c$%04X", fill, ea); \ break; \ case D_8: /* PC + 8 bit displacement (signed) */ \ - ofs8 = oprom[pos++]; \ + ofs8 = opcodes.r8(pos++); \ util::stream_format(stream, "%c$%04X", fill, pc + pos - 1 + ofs8); \ break; \ case D_16: /* PC + 16 bit displacement */ \ - ea = oprom[pos++]; \ - ea += oprom[pos++] << 8; \ + ea = opcodes.r8(pos++); \ + ea += opcodes.r8(pos++) << 8; \ ea = ea - 1; \ util::stream_format(stream, "%c$%04X", fill, pc + pos + ea); \ break; \ case S_8: /* SP + 8 bit displacement (signed) */ \ - ea = oprom[pos++]; \ + ea = opcodes.r8(pos++); \ util::stream_format(stream, "%cSP+$%02X", fill, ea); \ break; \ case M_IHL: util::stream_format(stream, "%c[I+HL]", fill); break; \ case M_N8: /* [I+N+ofs8] */ \ - ea = oprom[pos++]; \ + ea = opcodes.r8(pos++); \ util::stream_format(stream, "%c[I+N+$%02X]", fill, ea); \ break; \ case M_I16: /* [I+ofs16] */ \ - ea = oprom[pos++]; \ - ea += oprom[pos++] << 8; \ + ea = opcodes.r8(pos++); \ + ea += opcodes.r8(pos++) << 8; \ util::stream_format(stream, "%c[I+$%04X]", fill, ea); \ break; \ case M_X: util::stream_format(stream, "%c[X]", fill); break; \ case M_Y: util::stream_format(stream, "%c[Y]", fill); break; \ case M_X8: /* [X + 8 bit displacement (signed)] */ \ - ea = oprom[pos++]; \ + ea = opcodes.r8(pos++); \ util::stream_format(stream, "%c[X+$%02X]", fill, ea); \ break; \ case M_Y8: /* [Y + 8 bit displacement (signed)] */ \ - ea = oprom[pos++]; \ + ea = opcodes.r8(pos++); \ util::stream_format(stream, "%c[Y+$%02X]", fill, ea); \ break; \ case M_XL: util::stream_format(stream, "%c[X+L]", fill); break; \ case M_YL: util::stream_format(stream, "%c[Y+L]", fill); break; \ case M_16: /* [16bit] */ \ - ea = oprom[pos++]; \ - ea += oprom[pos++] << 8; \ + ea = opcodes.r8(pos++); \ + ea += opcodes.r8(pos++) << 8; \ util::stream_format(stream, "%c[$%04X]", fill, ea); \ break; \ case M_HL: util::stream_format(stream, "%c[HL]", fill); break; \ case OP: util::stream_format(stream, "%c$%02X", fill, op); break; \ case OP1: util::stream_format(stream, "%c$%02X", fill, op1); break; -CPU_DISASSEMBLE(minx) +u32 minx_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t minx_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { const minxdasm *instr; uint8_t op, op1; int8_t ofs8; uint16_t ea; - int pos = 0; + offs_t pos = pc; - op1 = op = oprom[pos++]; + op1 = op = opcodes.r8(pos++); switch (op) { case 0xCE: - op = oprom[pos++]; + op = opcodes.r8(pos++); instr = &mnemonic_ce[op]; break; case 0xCF: - op = oprom[pos++]; + op = opcodes.r8(pos++); instr = &mnemonic_cf[op]; break; default: @@ -460,5 +405,5 @@ CPU_DISASSEMBLE(minx) HANDLE_ARGUMENT; } } - return pos | s_flags[instr->mnemonic] | DASMFLAG_SUPPORTED; + return (pos - pc) | s_flags[instr->mnemonic] | SUPPORTED; } diff --git a/src/devices/cpu/minx/minxd.h b/src/devices/cpu/minx/minxd.h new file mode 100644 index 00000000000..bb7a6da4e0d --- /dev/null +++ b/src/devices/cpu/minx/minxd.h @@ -0,0 +1,89 @@ +// license:BSD-3-Clause +// copyright-holders:Wilbert Pol +/************************************************************ + + Nintendo Minx CPU disassembly + + +************************************************************/ + +#ifndef MAME_CPU_MINX_MINXDASM_H +#define MAME_CPU_MINX_MINXDASM_H + +#pragma once + +class minx_disassembler : public util::disasm_interface +{ +public: + minx_disassembler() = default; + virtual ~minx_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum e_mnemonic { + zADD=0, zADDC, zAND, zBCDD, zBCDE, zBCDX, zCALL, zCALLC, zCALLG, zCALLGE, zCALLL, + zCALLLE, zCALLN, zCALLNC, zCALLNO, zCALLNZ, zCALLO, zCALLP, zCALLNX0, + zCALLNX1, zCALLNX2, zCALLNX3, zCALLX0, zCALLX1, zCALLX2, zCALLX3, zCALLZ, + zCMP, zCMPN, zDEC, zDIV, zEXT, zHALT, zINC, zINT, + zJC, zJDBNZ, zJG, zJGE, zJINT, zJL, zJLE, zJMP, + zJN, zJNX0, zJNX1, zJNX2, zJNX3, zJNC, zJNO, zJNZ, + zJO, zJP, zJX0, zJX1, zJX2, zJX3, zJZ, zMOV, + zMUL, zNEG, zNOP, zNOT, zOR, zPOP, zPOPA, zPOPAX, + zPOPX, zPUSH, zPUSHA, zPUSHAX, zPUSHX, zRET, zRETI, zRETSKIP, + zROL, zROLC, zROR, zRORC, zSAL, zSAR, zSHL, zSHR, zSUB, + zSUBC, zTEST, zXCHG, zXOR, zDB + }; + + enum e_operand { + R_A=1, /* A */ + R_B, /* B */ + R_L, /* L */ + R_H, /* H */ + R_N, /* N */ + R_F, /* F */ + R_SP, /* SP */ + R_BA, /* BA */ + R_HL, /* HL */ + R_X, /* X */ + R_Y, /* Y */ + R_U, /* U */ + R_V, /* V */ + R_I, /* I */ + R_XI, /* XI */ + R_YI, /* YI */ + R_PC, /* PC */ + I_8, /* 8 bit immediate */ + I_16, /* 16 bit immediate */ + D_8, /* PC + 8 bit displacement (signed) */ + D_16, /* PC + 16 bit displacement */ + S_8, /* SP + 8 bit displacement (signed) */ + M_IHL, /* [I+HL] */ + M_N8, /* [I+N+ofs8] */ + M_I16, /* [I+ofs16] */ + M_X, /* [X] */ + M_Y, /* [Y] */ + M_X8, /* [X + 8 bit displacement (signed)] */ + M_Y8, /* [Y + 8 bit displacement (signed)] */ + M_XL, /* [X + L (signed)] */ + M_YL, /* [Y + L (signed)] */ + M_16, /* [16bit] */ + M_HL, /* [HL] */ + OP, OP1 + }; + + struct minxdasm { + uint8_t mnemonic; + uint8_t argument1; + uint8_t argument2; + }; + + static const char *const s_mnemonic[]; + static const uint32_t s_flags[]; + static const minxdasm mnemonic[256]; + static const minxdasm mnemonic_ce[256]; + static const minxdasm mnemonic_cf[256]; +}; + +#endif diff --git a/src/devices/cpu/mips/mips3.cpp b/src/devices/cpu/mips/mips3.cpp index d55d26623d1..f71f4bb738c 100644 --- a/src/devices/cpu/mips/mips3.cpp +++ b/src/devices/cpu/mips/mips3.cpp @@ -12,6 +12,7 @@ #include "debugger.h" #include "mips3.h" #include "mips3com.h" +#include "mips3dsm.h" #define ENABLE_OVERFLOWS 0 @@ -192,7 +193,10 @@ mips3_device::mips3_device(const machine_config &mconfig, device_type type, cons memset(m_hotspot, 0, sizeof(m_hotspot)); // configure the virtual TLB - set_vtlb_fixed_entries(2 * m_tlbentries + 2); + if (m_flavor == MIPS3_TYPE_TX4925) + set_vtlb_fixed_entries(2 * m_tlbentries + 3); + else + set_vtlb_fixed_entries(2 * m_tlbentries + 2); } device_memory_interface::space_config_vector mips3_device::memory_space_config() const @@ -333,7 +337,7 @@ void mips3_device::device_start() m_cpu_clock = clock(); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); /* set up the endianness */ m_program->accessors(m_memory); @@ -940,11 +944,16 @@ void mips3_device::device_reset() entry->entry_lo[1] = 0xfffffff8; vtlb_load(2 * tlbindex + 0, 0, 0, 0); vtlb_load(2 * tlbindex + 1, 0, 0, 0); + if (m_flavor == MIPS3_TYPE_TX4925) + vtlb_load(2 * tlbindex + 2, 0, 0, 0); } /* load the fixed TLB range */ vtlb_load(2 * m_tlbentries + 0, (0xa0000000 - 0x80000000) >> MIPS3_MIN_PAGE_SHIFT, 0x80000000, 0x00000000 | VTLB_READ_ALLOWED | VTLB_WRITE_ALLOWED | VTLB_FETCH_ALLOWED | VTLB_FLAG_VALID); vtlb_load(2 * m_tlbentries + 1, (0xc0000000 - 0xa0000000) >> MIPS3_MIN_PAGE_SHIFT, 0xa0000000, 0x00000000 | VTLB_READ_ALLOWED | VTLB_WRITE_ALLOWED | VTLB_FETCH_ALLOWED | VTLB_FLAG_VALID); + // TX4925 on-board peripherals pass-through + if (m_flavor == MIPS3_TYPE_TX4925) + vtlb_load(2 * m_tlbentries + 2, (0xff200000 - 0xff1f0000) >> MIPS3_MIN_PAGE_SHIFT, 0xff1f0000, 0xff1f0000 | VTLB_READ_ALLOWED | VTLB_WRITE_ALLOWED | VTLB_FETCH_ALLOWED | VTLB_FLAG_VALID); m_core->mode = (MODE_KERNEL << 1) | 0; m_cache_dirty = true; @@ -967,14 +976,9 @@ bool mips3_device::memory_translate(int spacenum, int intention, offs_t &address } -offs_t mips3_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *mips3_device::create_disassembler() { - uint32_t op = *(uint32_t *)oprom; - if (m_bigendian) - op = big_endianize_int32(op); - else - op = little_endianize_int32(op); - return dasmmips3(stream, pc, op); + return new mips3_disassembler; } @@ -985,12 +989,6 @@ offs_t mips3_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u inline bool mips3_device::RBYTE(offs_t address, uint32_t *result) { - if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) - { - *result = (*m_memory.read_byte)(*m_program, address); - return true; - } - const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_READ_ALLOWED) { @@ -1024,12 +1022,6 @@ inline bool mips3_device::RBYTE(offs_t address, uint32_t *result) inline bool mips3_device::RHALF(offs_t address, uint32_t *result) { - if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) - { - *result = (*m_memory.read_word)(*m_program, address); - return true; - } - const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_READ_ALLOWED) { @@ -1063,12 +1055,6 @@ inline bool mips3_device::RHALF(offs_t address, uint32_t *result) inline bool mips3_device::RWORD(offs_t address, uint32_t *result) { - if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) - { - *result = (*m_memory.read_dword)(*m_program, address); - return true; - } - const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_READ_ALLOWED) { @@ -1102,12 +1088,6 @@ inline bool mips3_device::RWORD(offs_t address, uint32_t *result) inline bool mips3_device::RWORD_MASKED(offs_t address, uint32_t *result, uint32_t mem_mask) { - if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) - { - *result = (*m_memory.read_dword_masked)(*m_program, address, mem_mask); - return true; - } - const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_READ_ALLOWED) { @@ -1131,11 +1111,6 @@ inline bool mips3_device::RWORD_MASKED(offs_t address, uint32_t *result, uint32_ inline bool mips3_device::RDOUBLE(offs_t address, uint64_t *result) { - if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) - { - *result = (*m_memory.read_qword)(*m_program, address); - return true; - } const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_READ_ALLOWED) { @@ -1159,12 +1134,6 @@ inline bool mips3_device::RDOUBLE(offs_t address, uint64_t *result) inline bool mips3_device::RDOUBLE_MASKED(offs_t address, uint64_t *result, uint64_t mem_mask) { - if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) - { - *result = (*m_memory.read_qword_masked)(*m_program, address, mem_mask); - return true; - } - const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_READ_ALLOWED) { @@ -1188,12 +1157,6 @@ inline bool mips3_device::RDOUBLE_MASKED(offs_t address, uint64_t *result, uint6 inline void mips3_device::WBYTE(offs_t address, uint8_t data) { - if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) - { - (*m_memory.write_byte)(*m_program, address, data); - return; - } - const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_WRITE_ALLOWED) { @@ -1228,11 +1191,6 @@ inline void mips3_device::WBYTE(offs_t address, uint8_t data) inline void mips3_device::WHALF(offs_t address, uint16_t data) { - if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) - { - (*m_memory.write_word)(*m_program, address, data); - return; - } const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_WRITE_ALLOWED) { @@ -1267,12 +1225,6 @@ inline void mips3_device::WHALF(offs_t address, uint16_t data) inline void mips3_device::WWORD(offs_t address, uint32_t data) { - if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) - { - (*m_memory.write_dword)(*m_program, address, data); - return; - } - const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_WRITE_ALLOWED) { @@ -1307,12 +1259,6 @@ inline void mips3_device::WWORD(offs_t address, uint32_t data) inline void mips3_device::WWORD_MASKED(offs_t address, uint32_t data, uint32_t mem_mask) { - if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) - { - (*m_memory.write_dword_masked)(*m_program, address, data, mem_mask); - return; - } - const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_WRITE_ALLOWED) { @@ -1337,12 +1283,6 @@ inline void mips3_device::WWORD_MASKED(offs_t address, uint32_t data, uint32_t m inline void mips3_device::WDOUBLE(offs_t address, uint64_t data) { - if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) - { - (*m_memory.write_qword)(*m_program, address, data); - return; - } - const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_WRITE_ALLOWED) { @@ -1367,12 +1307,6 @@ inline void mips3_device::WDOUBLE(offs_t address, uint64_t data) inline void mips3_device::WDOUBLE_MASKED(offs_t address, uint64_t data, uint64_t mem_mask) { - if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) - { - (*m_memory.write_qword_masked)(*m_program, address, data, mem_mask); - return; - } - const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_WRITE_ALLOWED) { diff --git a/src/devices/cpu/mips/mips3.h b/src/devices/cpu/mips/mips3.h index 6d763c8792b..dd0bac966d9 100644 --- a/src/devices/cpu/mips/mips3.h +++ b/src/devices/cpu/mips/mips3.h @@ -312,9 +312,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 4; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 4; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: @@ -374,7 +372,7 @@ private: loadstore_func m_sdr; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; uint32_t c_system_clock; uint32_t m_cpu_clock; emu_timer * m_compare_int_timer; @@ -802,11 +800,4 @@ private: #define MIPS3DRC_FASTEST_OPTIONS (0) -/*************************************************************************** - DISASSEMBLING -***************************************************************************/ - -unsigned dasmmips3(std::ostream &stream, unsigned pc, uint32_t op); - - #endif // MAME_CPU_MIPS_MIPS3_H diff --git a/src/devices/cpu/mips/mips3drc.cpp b/src/devices/cpu/mips/mips3drc.cpp index a3bd2e1469c..db90d525149 100644 --- a/src/devices/cpu/mips/mips3drc.cpp +++ b/src/devices/cpu/mips/mips3drc.cpp @@ -27,6 +27,7 @@ #include "debugger.h" #include "mips3com.h" #include "mips3fe.h" +#include "mips3dsm.h" #include "cpu/drcfe.h" #include "cpu/drcuml.h" #include "cpu/drcumlsh.h" @@ -161,12 +162,6 @@ void mips3_device::mips3drc_set_options(uint32_t options) -------------------------------------------------*/ void mips3_device::clear_fastram(uint32_t select_start) { - for (int i=select_start; i<MIPS3_MAX_FASTRAM; i++) { - m_fastram[i].start = 0; - m_fastram[i].end = 0; - m_fastram[i].readonly = false; - m_fastram[i].base = nullptr; - } m_fastram_select=select_start; // Set cache to dirty so that re-mapping occurs m_cache_dirty = true; @@ -189,6 +184,8 @@ void mips3_device::add_fastram(offs_t start, offs_t end, uint8_t readonly, void m_fastram[m_fastram_select].offset_base16 = (uint16_t*)((uint8_t*)base - start); m_fastram[m_fastram_select].offset_base32 = (uint32_t*)((uint8_t*)base - start); m_fastram_select++; + // Set cache to dirty so that re-mapping occurs + m_cache_dirty = true; } } @@ -840,69 +837,6 @@ void mips3_device::static_generate_memory_accessor(int mode, int size, int iswri UML_LABEL(block, addrok); // addrok: } - /* TX4925 on-board peripherals pass-through */ - if (m_flavor == MIPS3_TYPE_TX4925) - { - int addrok; - UML_AND(block, I3, I0, 0xffff0000); // and i3, i0, 0xffff0000 - UML_CMP(block, I3, 0xff1f0000); // cmp i3, 0xff1f0000 - UML_JMPc(block, COND_NZ, addrok = label++); - - switch (size) - { - case 1: - if (iswrite) - UML_WRITE(block, I0, I1, SIZE_BYTE, SPACE_PROGRAM); // write i0,i1,program_byte - else - UML_READ(block, I0, I0, SIZE_BYTE, SPACE_PROGRAM); // read i0,i0,program_byte - break; - - case 2: - if (iswrite) - UML_WRITE(block, I0, I1, SIZE_WORD, SPACE_PROGRAM); // write i0,i1,program_word - else - UML_READ(block, I0, I0, SIZE_WORD, SPACE_PROGRAM); // read i0,i0,program_word - break; - - case 4: - if (iswrite) - { - if (!ismasked) - UML_WRITE(block, I0, I1, SIZE_DWORD, SPACE_PROGRAM); // write i0,i1,program_dword - else - UML_WRITEM(block, I0, I1, I2, SIZE_DWORD, SPACE_PROGRAM); // writem i0,i1,i2,program_dword - } - else - { - if (!ismasked) - UML_READ(block, I0, I0, SIZE_DWORD, SPACE_PROGRAM); // read i0,i0,program_dword - else - UML_READM(block, I0, I0, I2, SIZE_DWORD, SPACE_PROGRAM); // readm i0,i0,i2,program_dword - } - break; - - case 8: - if (iswrite) - { - if (!ismasked) - UML_DWRITE(block, I0, I1, SIZE_QWORD, SPACE_PROGRAM); // dwrite i0,i1,program_qword - else - UML_DWRITEM(block, I0, I1, I2, SIZE_QWORD, SPACE_PROGRAM); // dwritem i0,i1,i2,program_qword - } - else - { - if (!ismasked) - UML_DREAD(block, I0, I0, SIZE_QWORD, SPACE_PROGRAM); // dread i0,i0,program_qword - else - UML_DREADM(block, I0, I0, I2, SIZE_QWORD, SPACE_PROGRAM); // dreadm i0,i0,i2,program_qword - } - break; - } - UML_RET(block); - - UML_LABEL(block, addrok); - } - /* general case: assume paging and perform a translation */ UML_SHR(block, I3, I0, 12); // shr i3,i0,12 UML_LOAD(block, I3, (void *)vtlb_table(), I3, SIZE_DWORD, SCALE_x4);// load i3,[vtlb_table],i3,dword @@ -911,8 +845,8 @@ void mips3_device::static_generate_memory_accessor(int mode, int size, int iswri UML_ROLINS(block, I0, I3, 0, 0xfffff000); // rolins i0,i3,0,0xfffff000 if ((machine().debug_flags & DEBUG_FLAG_ENABLED) == 0) - for (ramnum = 0; ramnum < MIPS3_MAX_FASTRAM; ramnum++) - if (m_fastram[ramnum].base != nullptr && (!iswrite || !m_fastram[ramnum].readonly)) + for (ramnum = 0; ramnum < m_fastram_select; ramnum++) + if (!(iswrite && m_fastram[ramnum].readonly)) { void *fastbase = (uint8_t *)m_fastram[ramnum].base - m_fastram[ramnum].start; uint32_t skip = label++; @@ -926,7 +860,6 @@ void mips3_device::static_generate_memory_accessor(int mode, int size, int iswri UML_CMP(block, I0, m_fastram[ramnum].start);// cmp i0,fastram_start UML_JMPc(block, COND_B, skip); // jb skip } - if (!iswrite) { if (size == 1) @@ -3354,8 +3287,9 @@ void mips3_device::log_add_disasm_comment(drcuml_block *block, uint32_t pc, uint { if (m_drcuml->logging()) { + mips3_disassembler mips3d; std::ostringstream stream; - dasmmips3(stream, pc, op); + mips3d.dasm_one(stream, pc, op); const std::string stream_string = stream.str(); block->append_comment("%08X: %s", pc, stream_string.c_str()); // comment } @@ -3493,7 +3427,10 @@ void mips3_device::log_opcode_desc(drcuml_state *drcuml, const opcode_desc *desc if (desclist->flags & OPFLAG_VIRTUAL_NOOP) buffer << "<virtual nop>"; else - dasmmips3(buffer, desclist->pc, desclist->opptr.l[0]); + { + mips3_disassembler mips3d; + mips3d.dasm_one(buffer, desclist->pc, desclist->opptr.l[0]); + } } else buffer << "???"; diff --git a/src/devices/cpu/mips/mips3dsm.cpp b/src/devices/cpu/mips/mips3dsm.cpp index acc7abbcc75..5252a552b8c 100644 --- a/src/devices/cpu/mips/mips3dsm.cpp +++ b/src/devices/cpu/mips/mips3dsm.cpp @@ -9,11 +9,12 @@ ***************************************************************************/ #include "emu.h" +#include "mips3dsm.h" #define USE_ABI_REG_NAMES (1) #if USE_ABI_REG_NAMES -static const char *const reg[32] = +const char *const mips3_disassembler::reg[32] = { "$0", "$at", "$v0", "$v1", "$a0", "$a1", "$a2", "$a3", "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7", @@ -21,7 +22,7 @@ static const char *const reg[32] = "$t8", "$t9", "$k0", "$k1", "$gp", "$sp", "$fp", "$ra" }; #else -static const char *const reg[32] = +const char *const mips3_disassembler::reg[32] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", @@ -30,7 +31,7 @@ static const char *const reg[32] = }; #endif -static const char *const cacheop[32] = +const char *const mips3_disassembler::cacheop[32] = { "I_Invd", "D_WBInvd", "Unknown 2", "Unknown 3", "I_IndexLoadTag", "D_IndexLoadTag", "Unknown 6", "Unknown 7", "I_IndexStoreTag", "D_IndexStoreTag", "Unknown 10", "Unknown 11", "Unknown 12", "D_CreateDirtyExcl", "Unknown 14", "Unknown 15", @@ -39,7 +40,7 @@ static const char *const cacheop[32] = }; -static const char *const cpreg[4][32] = +const char *const mips3_disassembler::cpreg[4][32] = { { "Index","Random","EntryLo0","EntryLo1","Context","PageMask","Wired","Error", @@ -68,7 +69,7 @@ static const char *const cpreg[4][32] = }; -static const char *const ccreg[4][32] = +const char *const mips3_disassembler::ccreg[4][32] = { { "ccr0", "ccr1", "ccr2", "ccr3", "ccr4", "ccr5", "ccr6", "ccr7", @@ -101,17 +102,15 @@ static const char *const ccreg[4][32] = CODE CODE ***************************************************************************/ -static inline char *signed_16bit(int16_t val) +inline std::string mips3_disassembler::signed_16bit(int16_t val) { - static char temp[10]; if (val < 0) - sprintf(temp, "-$%x", -val); + return util::string_format("-$%x", -val); else - sprintf(temp, "$%x", val); - return temp; + return util::string_format("$%x", val); } -static uint32_t dasm_cop0(uint32_t pc, uint32_t op, std::ostream &stream) +uint32_t mips3_disassembler::dasm_cop0(uint32_t pc, uint32_t op, std::ostream &stream) { int rt = (op >> 16) & 31; int rd = (op >> 11) & 31; @@ -157,7 +156,7 @@ static uint32_t dasm_cop0(uint32_t pc, uint32_t op, std::ostream &stream) case 0x02: util::stream_format(stream, "tlbwi"); break; case 0x06: util::stream_format(stream, "tlbwr"); break; case 0x08: util::stream_format(stream, "tlbp"); break; - case 0x10: util::stream_format(stream, "rfe"); flags = DASMFLAG_STEP_OUT; break; + case 0x10: util::stream_format(stream, "rfe"); flags = STEP_OUT; break; case 0x18: util::stream_format(stream, "eret [invalid]"); break; default: util::stream_format(stream, "cop0 $%07x", op & 0x01ffffff); break; } @@ -167,9 +166,9 @@ static uint32_t dasm_cop0(uint32_t pc, uint32_t op, std::ostream &stream) return flags; } -static uint32_t dasm_cop1(uint32_t pc, uint32_t op, std::ostream &stream) +uint32_t mips3_disassembler::dasm_cop1(uint32_t pc, uint32_t op, std::ostream &stream) { - static const char *const format_table[] = + const char *const format_table[] = { "?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?", "s","d","?","?","w","l","?","?","?","?","?","?","?","?","?","?" @@ -195,8 +194,8 @@ static uint32_t dasm_cop1(uint32_t pc, uint32_t op, std::ostream &stream) { case 0x00: util::stream_format(stream, "bc1f $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); break; case 0x01: util::stream_format(stream, "bc1t $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); break; - case 0x02: util::stream_format(stream, "bc1fl $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); break; - case 0x03: util::stream_format(stream, "bc1tl $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); break; + case 0x02: util::stream_format(stream, "bc1fl $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); flags = STEP_OVER | step_over_extra(1); break; + case 0x03: util::stream_format(stream, "bc1tl $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); flags = STEP_OVER | step_over_extra(1); break; } break; default: /* COP */ @@ -250,9 +249,9 @@ static uint32_t dasm_cop1(uint32_t pc, uint32_t op, std::ostream &stream) return flags; } -static uint32_t dasm_cop1x(uint32_t pc, uint32_t op, std::ostream &stream) +uint32_t mips3_disassembler::dasm_cop1x(uint32_t pc, uint32_t op, std::ostream &stream) { - static const char *const format3_table[] = + const char *const format3_table[] = { "s","d","?","?","w","l","?","?" }; @@ -310,7 +309,7 @@ static uint32_t dasm_cop1x(uint32_t pc, uint32_t op, std::ostream &stream) return flags; } -static uint32_t dasm_cop2(uint32_t pc, uint32_t op, std::ostream &stream) +uint32_t mips3_disassembler::dasm_cop2(uint32_t pc, uint32_t op, std::ostream &stream) { int rt = (op >> 16) & 31; int rd = (op >> 11) & 31; @@ -357,7 +356,12 @@ static uint32_t dasm_cop2(uint32_t pc, uint32_t op, std::ostream &stream) return flags; } -unsigned dasmmips3(std::ostream &stream, unsigned pc, uint32_t op) +u32 mips3_disassembler::opcode_alignment() const +{ + return 4; +} + +offs_t mips3_disassembler::dasm_one(std::ostream &stream, offs_t pc, u32 op) { int rs = (op >> 21) & 31; int rt = (op >> 16) & 31; @@ -381,17 +385,17 @@ unsigned dasmmips3(std::ostream &stream, unsigned pc, uint32_t op) case 0x04: util::stream_format(stream, "sllv %s,%s,%s", reg[rd], reg[rt], reg[rs]); break; case 0x06: util::stream_format(stream, "srlv %s,%s,%s", reg[rd], reg[rt], reg[rs]); break; case 0x07: util::stream_format(stream, "srav %s,%s,%s", reg[rd], reg[rt], reg[rs]); break; - case 0x08: util::stream_format(stream, "jr %s", reg[rs]); if (rs == 31) flags = DASMFLAG_STEP_OUT; break; + case 0x08: util::stream_format(stream, "jr %s", reg[rs]); if (rs == 31) flags = STEP_OUT; break; case 0x09: if (rd == 31) util::stream_format(stream, "jalr %s", reg[rs]); else util::stream_format(stream, "jalr %s,%s", reg[rs], reg[rd]); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; case 0x0a: util::stream_format(stream, "movz %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x0b: util::stream_format(stream, "movn %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; - case 0x0c: util::stream_format(stream, "syscall"); flags = DASMFLAG_STEP_OVER; break; - case 0x0d: util::stream_format(stream, "break"); flags = DASMFLAG_STEP_OVER; break; + case 0x0c: util::stream_format(stream, "syscall"); flags = STEP_OVER; break; + case 0x0d: util::stream_format(stream, "break"); flags = STEP_OVER; break; case 0x0f: util::stream_format(stream, "sync"); break; case 0x10: util::stream_format(stream, "mfhi %s", reg[rd]); break; case 0x11: util::stream_format(stream, "mthi %s", reg[rs]); break; @@ -422,12 +426,12 @@ unsigned dasmmips3(std::ostream &stream, unsigned pc, uint32_t op) case 0x2d: util::stream_format(stream, "daddu %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x2e: util::stream_format(stream, "dsub %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x2f: util::stream_format(stream, "dsubu %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; - case 0x30: util::stream_format(stream, "tge %s,%s", reg[rs], reg[rt]); flags = DASMFLAG_STEP_OVER; break; - case 0x31: util::stream_format(stream, "tgeu %s,%s", reg[rs], reg[rt]); flags = DASMFLAG_STEP_OVER; break; - case 0x32: util::stream_format(stream, "tlt %s,%s", reg[rs], reg[rt]); flags = DASMFLAG_STEP_OVER; break; - case 0x33: util::stream_format(stream, "tltu %s,%s", reg[rs], reg[rt]); flags = DASMFLAG_STEP_OVER; break; - case 0x34: util::stream_format(stream, "teq %s,%s", reg[rs], reg[rt]); flags = DASMFLAG_STEP_OVER; break; - case 0x36: util::stream_format(stream, "tne %s,%s", reg[rs], reg[rt]) ;flags = DASMFLAG_STEP_OVER; break; + case 0x30: util::stream_format(stream, "tge %s,%s", reg[rs], reg[rt]); flags = STEP_OVER; break; + case 0x31: util::stream_format(stream, "tgeu %s,%s", reg[rs], reg[rt]); flags = STEP_OVER; break; + case 0x32: util::stream_format(stream, "tlt %s,%s", reg[rs], reg[rt]); flags = STEP_OVER; break; + case 0x33: util::stream_format(stream, "tltu %s,%s", reg[rs], reg[rt]); flags = STEP_OVER; break; + case 0x34: util::stream_format(stream, "teq %s,%s", reg[rs], reg[rt]); flags = STEP_OVER; break; + case 0x36: util::stream_format(stream, "tne %s,%s", reg[rs], reg[rt]) ;flags = STEP_OVER; break; case 0x38: util::stream_format(stream, "dsll %s,%s,%d", reg[rd], reg[rt], shift); break; case 0x3a: util::stream_format(stream, "dsrl %s,%s,%d", reg[rd], reg[rt], shift); break; case 0x3b: util::stream_format(stream, "dsra %s,%s,%d", reg[rd], reg[rt], shift); break; @@ -445,22 +449,22 @@ unsigned dasmmips3(std::ostream &stream, unsigned pc, uint32_t op) case 0x01: util::stream_format(stream, "bgez %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); break; case 0x02: util::stream_format(stream, "bltzl %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); break; case 0x03: util::stream_format(stream, "bgezl %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); break; - case 0x08: util::stream_format(stream, "tgei %s,%s", reg[rs], signed_16bit(op)); flags = DASMFLAG_STEP_OVER; break; - case 0x09: util::stream_format(stream, "tgeiu %s,%s", reg[rs], signed_16bit(op)); flags = DASMFLAG_STEP_OVER; break; - case 0x0a: util::stream_format(stream, "tlti %s,%s", reg[rs], signed_16bit(op)); flags = DASMFLAG_STEP_OVER; break; - case 0x0b: util::stream_format(stream, "tltiu %s,%s", reg[rs], signed_16bit(op)); flags = DASMFLAG_STEP_OVER; break; - case 0x0c: util::stream_format(stream, "teqi %s,%s", reg[rs], signed_16bit(op)); flags = DASMFLAG_STEP_OVER; break; - case 0x0e: util::stream_format(stream, "tnei %s,%s", reg[rs], signed_16bit(op)); flags = DASMFLAG_STEP_OVER; break; - case 0x10: util::stream_format(stream, "bltzal %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); break; - case 0x11: util::stream_format(stream, "bgezal %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); break; - case 0x12: util::stream_format(stream, "bltzall %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); break; - case 0x13: util::stream_format(stream, "bgezall %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); break; + case 0x08: util::stream_format(stream, "tgei %s,%s", reg[rs], signed_16bit(op)); flags = STEP_OVER; break; + case 0x09: util::stream_format(stream, "tgeiu %s,%s", reg[rs], signed_16bit(op)); flags = STEP_OVER; break; + case 0x0a: util::stream_format(stream, "tlti %s,%s", reg[rs], signed_16bit(op)); flags = STEP_OVER; break; + case 0x0b: util::stream_format(stream, "tltiu %s,%s", reg[rs], signed_16bit(op)); flags = STEP_OVER; break; + case 0x0c: util::stream_format(stream, "teqi %s,%s", reg[rs], signed_16bit(op)); flags = STEP_OVER; break; + case 0x0e: util::stream_format(stream, "tnei %s,%s", reg[rs], signed_16bit(op)); flags = STEP_OVER; break; + case 0x10: util::stream_format(stream, "bltzal %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = STEP_OVER | step_over_extra(1); break; + case 0x11: util::stream_format(stream, "bgezal %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = STEP_OVER | step_over_extra(1); break; + case 0x12: util::stream_format(stream, "bltzall %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = STEP_OVER | step_over_extra(1); break; + case 0x13: util::stream_format(stream, "bgezall %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = STEP_OVER | step_over_extra(1); break; default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break; } break; case 0x02: util::stream_format(stream, "j $%08x", (pc & 0xf0000000) | ((op & 0x03ffffff) << 2)); break; - case 0x03: util::stream_format(stream, "jal $%08x", (pc & 0xf0000000) | ((op & 0x03ffffff) << 2)); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); break; + case 0x03: util::stream_format(stream, "jal $%08x", (pc & 0xf0000000) | ((op & 0x03ffffff) << 2)); flags = STEP_OVER | step_over_extra(1); break; case 0x04: if (rs == 0 && rt == 0) util::stream_format(stream, "b $%08x", pc + 4 + ((int16_t)op << 2)); else @@ -532,21 +536,11 @@ unsigned dasmmips3(std::ostream &stream, unsigned pc, uint32_t op) case 0x3f: util::stream_format(stream, "sd %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break; } - return 4 | flags | DASMFLAG_SUPPORTED; -} - - -CPU_DISASSEMBLE( mips3be ) -{ - uint32_t op = *(uint32_t *)oprom; - op = big_endianize_int32(op); - return dasmmips3(stream, pc, op); + return 4 | flags | SUPPORTED; } - -CPU_DISASSEMBLE( mips3le ) +offs_t mips3_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - uint32_t op = *(uint32_t *)oprom; - op = little_endianize_int32(op); - return dasmmips3(stream, pc, op); + u32 op = opcodes.r32(pc); + return dasm_one(stream, pc, op); } diff --git a/src/devices/cpu/mips/mips3dsm.h b/src/devices/cpu/mips/mips3dsm.h new file mode 100644 index 00000000000..a38771bbba0 --- /dev/null +++ b/src/devices/cpu/mips/mips3dsm.h @@ -0,0 +1,40 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +/*************************************************************************** + + mips3dsm.c + Disassembler for the portable MIPS 3 emulator. + Written by Aaron Giles + +***************************************************************************/ + +#ifndef MAME_CPU_MIPS_MIPS3DSM_H +#define MAME_CPU_MIPS_MIPS3DSM_H + +#pragma once + +class mips3_disassembler : public util::disasm_interface +{ +public: + mips3_disassembler() = default; + virtual ~mips3_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + + offs_t dasm_one(std::ostream &stream, offs_t pc, u32 op); + +private: + static const char *const reg[32]; + static const char *const cacheop[32]; + static const char *const cpreg[4][32]; + static const char *const ccreg[4][32]; + inline std::string signed_16bit(int16_t val); + uint32_t dasm_cop0(uint32_t pc, uint32_t op, std::ostream &stream); + uint32_t dasm_cop1(uint32_t pc, uint32_t op, std::ostream &stream); + uint32_t dasm_cop1x(uint32_t pc, uint32_t op, std::ostream &stream); + uint32_t dasm_cop2(uint32_t pc, uint32_t op, std::ostream &stream); + +}; + +#endif diff --git a/src/devices/cpu/mips/r3000.cpp b/src/devices/cpu/mips/r3000.cpp index 2e29e967747..db1a35ec370 100644 --- a/src/devices/cpu/mips/r3000.cpp +++ b/src/devices/cpu/mips/r3000.cpp @@ -10,6 +10,7 @@ #include "emu.h" #include "r3000.h" +#include "r3kdasm.h" #include "debugger.h" @@ -213,7 +214,7 @@ void r3000_device::device_start() { // get our address spaces m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); // determine the cache sizes switch (m_chip_type) @@ -453,41 +454,13 @@ void r3000_device::state_string_export(const device_state_entry &entry, std::str //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t r3000_device::disasm_min_opcode_bytes() const -{ - return 4; -} - - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t r3000_device::disasm_max_opcode_bytes() const -{ - return 4; -} - - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t r3000_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *r3000_device::create_disassembler() { - extern CPU_DISASSEMBLE( r3000le ); - extern CPU_DISASSEMBLE( r3000be ); - - if (m_endianness == ENDIANNESS_BIG) - return CPU_DISASSEMBLE_NAME(r3000be)(this, stream, pc, oprom, opram, options); - else - return CPU_DISASSEMBLE_NAME(r3000le)(this, stream, pc, oprom, opram, options); + return new r3000_disassembler; } diff --git a/src/devices/cpu/mips/r3000.h b/src/devices/cpu/mips/r3000.h index 1d458d93de9..a5f9998a23c 100644 --- a/src/devices/cpu/mips/r3000.h +++ b/src/devices/cpu/mips/r3000.h @@ -131,9 +131,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // memory accessors struct r3000_data_accessors @@ -214,7 +212,7 @@ protected: const address_space_config m_program_config_be; const address_space_config m_program_config_le; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; // configuration chip_type m_chip_type; diff --git a/src/devices/cpu/mips/r3kdasm.cpp b/src/devices/cpu/mips/r3kdasm.cpp index 1e8a2d7a16d..7e004a95068 100644 --- a/src/devices/cpu/mips/r3kdasm.cpp +++ b/src/devices/cpu/mips/r3kdasm.cpp @@ -9,9 +9,9 @@ ***************************************************************************/ #include "emu.h" +#include "r3kdasm.h" - -static const char *const reg[32] = +const char *const r3000_disassembler::reg[32] = { "0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", @@ -20,7 +20,7 @@ static const char *const reg[32] = }; -static const char *const cpreg[4][32] = +const char *const r3000_disassembler::cpreg[4][32] = { { "Index","Random","EntryLo","cpr3", "Context", "cpr5", "cpr6", "cpr7", @@ -49,7 +49,7 @@ static const char *const cpreg[4][32] = }; -static const char *const ccreg[4][32] = +const char *const r3000_disassembler::ccreg[4][32] = { { "ccr0", "ccr1", "ccr2", "ccr3", "ccr4", "ccr5", "ccr6", "ccr7", @@ -82,17 +82,15 @@ static const char *const ccreg[4][32] = CODE CODE ***************************************************************************/ -static inline char *signed_16bit(int16_t val) +std::string r3000_disassembler::signed_16bit(int16_t val) { - static char temp[10]; if (val < 0) - sprintf(temp, "-$%x", -val); + return util::string_format("-$%x", -val); else - sprintf(temp, "$%x", val); - return temp; + return util::string_format("$%x", val); } -static uint32_t dasm_cop(uint32_t pc, int cop, uint32_t op, std::ostream &stream) +uint32_t r3000_disassembler::dasm_cop(uint32_t pc, int cop, uint32_t op, std::ostream &stream) { int rt = (op >> 16) & 31; int rd = (op >> 11) & 31; @@ -152,7 +150,7 @@ static uint32_t dasm_cop(uint32_t pc, int cop, uint32_t op, std::ostream &stream return flags; } -static uint32_t dasm_cop1(uint32_t pc, uint32_t op, std::ostream &stream) +uint32_t r3000_disassembler::dasm_cop1(uint32_t pc, uint32_t op, std::ostream &stream) { static const char *const format_table[] = { @@ -180,8 +178,8 @@ static uint32_t dasm_cop1(uint32_t pc, uint32_t op, std::ostream &stream) { case 0x00: util::stream_format(stream, "bc1f $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); break; case 0x01: util::stream_format(stream, "bc1t $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); break; - case 0x02: util::stream_format(stream, "bc1fl $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); break; - case 0x03: util::stream_format(stream, "bc1tl $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); break; + case 0x02: util::stream_format(stream, "bc1fl $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); flags = STEP_OVER | step_over_extra(1); break; + case 0x03: util::stream_format(stream, "bc1tl $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); flags = STEP_OVER | step_over_extra(1); break; } break; default: /* COP */ @@ -235,8 +233,9 @@ static uint32_t dasm_cop1(uint32_t pc, uint32_t op, std::ostream &stream) return flags; } -static unsigned dasmr3k(std::ostream &stream, unsigned pc, uint32_t op) +offs_t r3000_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { + uint32_t op = opcodes.r32(pc); int rs = (op >> 21) & 31; int rt = (op >> 16) & 31; int rd = (op >> 11) & 31; @@ -258,15 +257,15 @@ static unsigned dasmr3k(std::ostream &stream, unsigned pc, uint32_t op) case 0x04: util::stream_format(stream, "sllv %s,%s,%s", reg[rd], reg[rt], reg[rs]); break; case 0x06: util::stream_format(stream, "srlv %s,%s,%s", reg[rd], reg[rt], reg[rs]); break; case 0x07: util::stream_format(stream, "srav %s,%s,%s", reg[rd], reg[rt], reg[rs]); break; - case 0x08: util::stream_format(stream, "jr %s", reg[rs]); if (rs == 31) flags = DASMFLAG_STEP_OUT; break; + case 0x08: util::stream_format(stream, "jr %s", reg[rs]); if (rs == 31) flags = STEP_OUT; break; case 0x09: if (rd == 31) util::stream_format(stream, "jalr %s", reg[rs]); else util::stream_format(stream, "jalr %s,%s", reg[rs], reg[rd]); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; - case 0x0c: util::stream_format(stream, "syscall"); flags = DASMFLAG_STEP_OVER; break; - case 0x0d: util::stream_format(stream, "break"); flags = DASMFLAG_STEP_OVER; break; + case 0x0c: util::stream_format(stream, "syscall"); flags = STEP_OVER; break; + case 0x0d: util::stream_format(stream, "break"); flags = STEP_OVER; break; case 0x0f: util::stream_format(stream, "sync [invalid]"); break; case 0x10: util::stream_format(stream, "mfhi %s", reg[rd]); break; case 0x11: util::stream_format(stream, "mthi %s", reg[rs]); break; @@ -309,8 +308,8 @@ static unsigned dasmr3k(std::ostream &stream, unsigned pc, uint32_t op) case 0x0b: util::stream_format(stream, "tltiu [invalid]"); break; case 0x0c: util::stream_format(stream, "teqi [invalid]"); break; case 0x0e: util::stream_format(stream, "tnei [invalid]"); break; - case 0x10: util::stream_format(stream, "bltzal %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); break; - case 0x11: util::stream_format(stream, "bgezal %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); break; + case 0x10: util::stream_format(stream, "bltzal %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = STEP_OVER | step_over_extra(1); break; + case 0x11: util::stream_format(stream, "bgezal %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = STEP_OVER | step_over_extra(1); break; case 0x12: util::stream_format(stream, "bltzall [invalid]"); break; case 0x13: util::stream_format(stream, "bgezall [invalid]"); break; default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break; @@ -318,7 +317,7 @@ static unsigned dasmr3k(std::ostream &stream, unsigned pc, uint32_t op) break; case 0x02: util::stream_format(stream, "j $%08x", (pc & 0xf0000000) | ((op & 0x0fffffff) << 2)); break; - case 0x03: util::stream_format(stream, "jal $%08x", (pc & 0xf0000000) | ((op & 0x0fffffff) << 2)); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); break; + case 0x03: util::stream_format(stream, "jal $%08x", (pc & 0xf0000000) | ((op & 0x0fffffff) << 2)); flags = STEP_OVER | step_over_extra(1); break; case 0x04: if (rs == 0 && rt == 0) util::stream_format(stream, "b $%08x", pc + 4 + ((int16_t)op << 2)); else @@ -374,21 +373,10 @@ static unsigned dasmr3k(std::ostream &stream, unsigned pc, uint32_t op) case 0x3f: util::stream_format(stream, "sdc3 [invalid]"); break; default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break; } - return 4 | flags | DASMFLAG_SUPPORTED; -} - - -CPU_DISASSEMBLE( r3000be ) -{ - uint32_t op = *(uint32_t *)oprom; - op = big_endianize_int32(op); - return dasmr3k(stream, pc, op); + return 4 | flags | SUPPORTED; } - -CPU_DISASSEMBLE( r3000le ) +uint32_t r3000_disassembler::opcode_alignment() const { - uint32_t op = *(uint32_t *)oprom; - op = little_endianize_int32(op); - return dasmr3k(stream, pc, op); + return 4; } diff --git a/src/devices/cpu/mips/r3kdasm.h b/src/devices/cpu/mips/r3kdasm.h new file mode 100644 index 00000000000..7eec7e7c1f8 --- /dev/null +++ b/src/devices/cpu/mips/r3kdasm.h @@ -0,0 +1,36 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +/*************************************************************************** + + r3kdasm.c + Disassembler for the portable R3000 emulator. + Written by Aaron Giles + +***************************************************************************/ + +#ifndef MAME_CPU_MIPS_R3KDASM_H +#define MAME_CPU_MIPS_R3KDASM_H + +#pragma once + +class r3000_disassembler : public util::disasm_interface +{ +public: + r3000_disassembler() = default; + virtual ~r3000_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *const reg[32]; + static const char *const cpreg[4][32]; + static const char *const ccreg[4][32]; + std::string signed_16bit(int16_t val); + uint32_t dasm_cop(uint32_t pc, int cop, uint32_t op, std::ostream &stream); + uint32_t dasm_cop1(uint32_t pc, uint32_t op, std::ostream &stream); + + +}; + +#endif diff --git a/src/devices/cpu/mn10200/mn10200.cpp b/src/devices/cpu/mn10200/mn10200.cpp index 59407b507ca..74757bd9e53 100644 --- a/src/devices/cpu/mn10200/mn10200.cpp +++ b/src/devices/cpu/mn10200/mn10200.cpp @@ -11,6 +11,7 @@ #include "emu.h" #include "debugger.h" #include "mn10200.h" +#include "mn102dis.h" #define log_write(...) #define log_event(...) @@ -88,10 +89,9 @@ void mn10200_device::state_string_export(const device_state_entry &entry, std::s } } -offs_t mn10200_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *mn10200_device::create_disassembler() { - extern CPU_DISASSEMBLE( mn10200 ); - return CPU_DISASSEMBLE_NAME(mn10200)(this, stream, pc, oprom, opram, options); + return new mn10200_disassembler; } diff --git a/src/devices/cpu/mn10200/mn10200.h b/src/devices/cpu/mn10200/mn10200.h index 307b0b4b6a9..7f3524df68c 100644 --- a/src/devices/cpu/mn10200/mn10200.h +++ b/src/devices/cpu/mn10200/mn10200.h @@ -87,9 +87,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 7; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; diff --git a/src/devices/cpu/mn10200/mn102dis.cpp b/src/devices/cpu/mn10200/mn102dis.cpp index be3fb46c0eb..8be02ad6a58 100644 --- a/src/devices/cpu/mn10200/mn102dis.cpp +++ b/src/devices/cpu/mn10200/mn102dis.cpp @@ -5,76 +5,47 @@ */ #include "emu.h" +#include "mn102dis.h" -#include <stdio.h> - -static const uint8_t *sOpROM; // current opROM pointer -static uint32_t sBasePC; - -static uint8_t program_read_byte(offs_t pc) -{ - return sOpROM[pc - sBasePC]; -} - -static uint32_t r16u(offs_t pc) -{ - return sOpROM[pc - sBasePC] | (sOpROM[pc - sBasePC + 1]<<8); -} - -static int32_t r16s(offs_t pc) -{ - return (int16_t)(sOpROM[pc - sBasePC] | (sOpROM[pc - sBasePC + 1]<<8)); -} - -static uint32_t r24u(offs_t pc) +u32 mn10200_disassembler::r24(const data_buffer &opcodes, offs_t pc) { - return sOpROM[pc - sBasePC] | (sOpROM[pc - sBasePC + 1]<<8) | (sOpROM[pc - sBasePC + 2]<<16); + return opcodes.r16(pc) | (opcodes.r8(pc+2) << 16); } -static int32_t r24s(offs_t pc) +std::string mn10200_disassembler::i8str(s8 v) { - return sOpROM[pc - sBasePC] | (sOpROM[pc - sBasePC + 1]<<8) | ((int8_t)sOpROM[pc - sBasePC + 2]<<16); -} - -static const char *i8str(int8_t v) -{ - static char res[0x10]; if(v>=0) - sprintf(res, "$%x", v); + return util::string_format("$%x", v); else - sprintf(res, "-$%x", (uint8_t)(-v)); - return res; + return util::string_format("-$%x", u8(-v)); } -static const char *i16str(int16_t v) +std::string mn10200_disassembler::i16str(int16_t v) { - static char res[0x10]; if(v>=0) - sprintf(res, "$%x", v); + return util::string_format("$%x", v); else - sprintf(res, "-$%x", (uint16_t)(-v)); - return res; + return util::string_format("-$%x", u16(-v)); } -static const char *i24str(int32_t v) -{ - static char res[0x10]; - if(v>=0) - sprintf(res, "$%x", v); +std::string mn10200_disassembler::i24str(u32 v) +{ + if(!(v & 0x800000)) + return util::string_format("$%x", v & 0xffffff); else - sprintf(res, "-$%x", -v); - return res; + return util::string_format("-$%x", (-v) & 0xffffff); } - -static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *oprom) +u32 mn10200_disassembler::opcode_alignment() const { - uint8_t opcode; + return 1; +} - sOpROM = oprom; - sBasePC = pc; +offs_t mn10200_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + u8 opcode; - opcode = program_read_byte(pc); + opcode = opcodes.r8(pc); switch(opcode) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: @@ -99,22 +70,22 @@ static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *o case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f: - util::stream_format(stream, "mov d%d, (%s, a%d)", opcode & 3, i8str(program_read_byte(pc+1)), (opcode>>2) & 3); + util::stream_format(stream, "mov d%d, (%s, a%d)", opcode & 3, i8str(opcodes.r8(pc+1)), (opcode>>2) & 3); return 2; case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57: case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f: - util::stream_format(stream, "mov a%d, (%s, a%d)", opcode & 3, i8str(program_read_byte(pc+1)), (opcode>>2) & 3); + util::stream_format(stream, "mov a%d, (%s, a%d)", opcode & 3, i8str(opcodes.r8(pc+1)), (opcode>>2) & 3); return 2; case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f: - util::stream_format(stream, "mov (%s, a%d), d%d", i8str(program_read_byte(pc+1)), (opcode>>2) & 3, opcode & 3); + util::stream_format(stream, "mov (%s, a%d), d%d", i8str(opcodes.r8(pc+1)), (opcode>>2) & 3, opcode & 3); return 2; case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77: case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f: - util::stream_format(stream, "mov (%s, a%d), a%d", i8str(program_read_byte(pc+1)), (opcode>>2) & 3, opcode & 3); + util::stream_format(stream, "mov (%s, a%d), a%d", i8str(opcodes.r8(pc+1)), (opcode>>2) & 3, opcode & 3); return 2; case 0x81: case 0x82: case 0x83: case 0x84: case 0x86: case 0x87: @@ -123,7 +94,7 @@ static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *o return 1; case 0x80: case 0x85: case 0x8a: case 0x8f: - util::stream_format(stream, "mov %s, d%d", i8str(program_read_byte(pc+1)), opcode & 3); + util::stream_format(stream, "mov %s, d%d", i8str(opcodes.r8(pc+1)), opcode & 3); return 2; case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97: @@ -153,79 +124,79 @@ static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *o return 1; case 0xc0: case 0xc1: case 0xc2: case 0xc3: - util::stream_format(stream, "mov d%d, ($%04x)", opcode & 3, r16u(pc+1)); + util::stream_format(stream, "mov d%d, ($%04x)", opcode & 3, opcodes.r16(pc+1)); return 3; case 0xc4: case 0xc5: case 0xc6: case 0xc7: - util::stream_format(stream, "movb d%d, ($%04x)", opcode & 3, r16u(pc+1)); + util::stream_format(stream, "movb d%d, ($%04x)", opcode & 3, opcodes.r16(pc+1)); return 3; case 0xc8: case 0xc9: case 0xca: case 0xcb: - util::stream_format(stream, "mov ($%04x), d%d", r16u(pc+1), opcode & 3); + util::stream_format(stream, "mov ($%04x), d%d", opcodes.r16(pc+1), opcode & 3); return 3; case 0xcc: case 0xcd: case 0xce: case 0xcf: - util::stream_format(stream, "movbu ($%04x), d%d", r16u(pc+1), opcode & 3); + util::stream_format(stream, "movbu ($%04x), d%d", opcodes.r16(pc+1), opcode & 3); return 3; case 0xd0: case 0xd1: case 0xd2: case 0xd3: - util::stream_format(stream, "add %s, a%d", i8str(program_read_byte(pc+1)), opcode & 3); + util::stream_format(stream, "add %s, a%d", i8str(opcodes.r8(pc+1)), opcode & 3); return 2; case 0xd4: case 0xd5: case 0xd6: case 0xd7: - util::stream_format(stream, "add %s, d%d", i8str(program_read_byte(pc+1)), opcode & 3); + util::stream_format(stream, "add %s, d%d", i8str(opcodes.r8(pc+1)), opcode & 3); return 2; case 0xd8: case 0xd9: case 0xda: case 0xdb: - util::stream_format(stream, "cmp %s, d%d", i8str(program_read_byte(pc+1)), opcode & 3); + util::stream_format(stream, "cmp %s, d%d", i8str(opcodes.r8(pc+1)), opcode & 3); return 2; case 0xdc: case 0xdd: case 0xde: case 0xdf: - util::stream_format(stream, "move $%04x, a%d", r16u(pc+1), opcode & 3); + util::stream_format(stream, "move $%04x, a%d", opcodes.r16(pc+1), opcode & 3); return 3; case 0xe0: - util::stream_format(stream, "blt $%x", (pc+2+(int8_t)program_read_byte(pc+1)) & 0xffffff); + util::stream_format(stream, "blt $%x", (pc+2+(s8)opcodes.r8(pc+1)) & 0xffffff); return 2; case 0xe1: - util::stream_format(stream, "bgt $%x", (pc+2+(int8_t)program_read_byte(pc+1)) & 0xffffff); + util::stream_format(stream, "bgt $%x", (pc+2+(s8)opcodes.r8(pc+1)) & 0xffffff); return 2; case 0xe2: - util::stream_format(stream, "bge $%x", (pc+2+(int8_t)program_read_byte(pc+1)) & 0xffffff); + util::stream_format(stream, "bge $%x", (pc+2+(s8)opcodes.r8(pc+1)) & 0xffffff); return 2; case 0xe3: - util::stream_format(stream, "ble $%x", (pc+2+(int8_t)program_read_byte(pc+1)) & 0xffffff); + util::stream_format(stream, "ble $%x", (pc+2+(s8)opcodes.r8(pc+1)) & 0xffffff); return 2; case 0xe4: - util::stream_format(stream, "bcs $%x", (pc+2+(int8_t)program_read_byte(pc+1)) & 0xffffff); + util::stream_format(stream, "bcs $%x", (pc+2+(s8)opcodes.r8(pc+1)) & 0xffffff); return 2; case 0xe5: - util::stream_format(stream, "bhi $%x", (pc+2+(int8_t)program_read_byte(pc+1)) & 0xffffff); + util::stream_format(stream, "bhi $%x", (pc+2+(s8)opcodes.r8(pc+1)) & 0xffffff); return 2; case 0xe6: - util::stream_format(stream, "bcc $%x", (pc+2+(int8_t)program_read_byte(pc+1)) & 0xffffff); + util::stream_format(stream, "bcc $%x", (pc+2+(s8)opcodes.r8(pc+1)) & 0xffffff); return 2; case 0xe7: - util::stream_format(stream, "bls $%x", (pc+2+(int8_t)program_read_byte(pc+1)) & 0xffffff); + util::stream_format(stream, "bls $%x", (pc+2+(s8)opcodes.r8(pc+1)) & 0xffffff); return 2; case 0xe8: - util::stream_format(stream, "beq $%x", (pc+2+(int8_t)program_read_byte(pc+1)) & 0xffffff); + util::stream_format(stream, "beq $%x", (pc+2+(s8)opcodes.r8(pc+1)) & 0xffffff); return 2; case 0xe9: - util::stream_format(stream, "bne $%x", (pc+2+(int8_t)program_read_byte(pc+1)) & 0xffffff); + util::stream_format(stream, "bne $%x", (pc+2+(s8)opcodes.r8(pc+1)) & 0xffffff); return 2; case 0xea: - util::stream_format(stream, "bra $%x", (pc+2+(int8_t)program_read_byte(pc+1)) & 0xffffff); + util::stream_format(stream, "bra $%x", (pc+2+(s8)opcodes.r8(pc+1)) & 0xffffff); return 2; case 0xeb: @@ -233,11 +204,11 @@ static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *o return 1; case 0xec: case 0xed: case 0xee: case 0xef: - util::stream_format(stream, "cmp $%04x, a%d", r16u(pc+1), opcode & 3); + util::stream_format(stream, "cmp $%04x, a%d", opcodes.r16(pc+1), opcode & 3); return 3; case 0xf0: - opcode = program_read_byte(pc+1); + opcode = opcodes.r8(pc+1); switch(opcode) { case 0x00: case 0x04: case 0x08: case 0x0c: @@ -296,7 +267,7 @@ static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *o } case 0xf1: - opcode = program_read_byte(pc+1); + opcode = opcodes.r8(pc+1); switch(opcode&0xc0) { case 0x00: @@ -318,7 +289,7 @@ static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *o break; case 0xf2: - opcode = program_read_byte(pc+1); + opcode = opcodes.r8(pc+1); switch(opcode&0xf0) { case 0x00: @@ -382,7 +353,7 @@ static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *o } case 0xf3: - opcode = program_read_byte(pc+1); + opcode = opcodes.r8(pc+1); switch(opcode) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: @@ -465,25 +436,25 @@ static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *o return 2; case 0xfe: - opcode = program_read_byte(pc+2); + opcode = opcodes.r8(pc+2); switch(opcode) { case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: - util::stream_format(stream, "tbz ($%x) %d, $%x", r24u(pc+3), opcode & 7, - (pc+7+(int8_t)program_read_byte(pc+6)) & 0xffffff); + util::stream_format(stream, "tbz ($%x) %d, $%x", r24(opcodes, pc+3), opcode & 7, + (pc+7+(s8)opcodes.r8(pc+6)) & 0xffffff); return 7; case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: - util::stream_format(stream, "tbnz ($%x) %d, $%x", r24u(pc+3), opcode & 7, - (pc+7+(int8_t)program_read_byte(pc+6)) & 0xffffff); + util::stream_format(stream, "tbnz ($%x) %d, $%x", r24(opcodes, pc+3), opcode & 7, + (pc+7+(s8)opcodes.r8(pc+6)) & 0xffffff); return 7; case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: - util::stream_format(stream, "bset ($%x) %d", r24u(pc+2), opcode & 7); + util::stream_format(stream, "bset ($%x) %d", r24(opcodes, pc+2), opcode & 7); return 6; case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: - util::stream_format(stream, "bclr ($%x) %d", r24u(pc+2), opcode & 7); + util::stream_format(stream, "bclr ($%x) %d", r24(opcodes, pc+2), opcode & 7); return 6; default: @@ -491,29 +462,29 @@ static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *o } case 0xff: - opcode = program_read_byte(pc+2); + opcode = opcodes.r8(pc+2); switch(opcode) { case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87: case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f: - util::stream_format(stream, "tbz (%s, a%d) %d, $%x", i8str(program_read_byte(pc+3)), 2+((opcode>>3)&1), opcode & 7, - (pc+5+(int8_t)program_read_byte(pc+4)) & 0xffffff); + util::stream_format(stream, "tbz (%s, a%d) %d, $%x", i8str(opcodes.r8(pc+3)), 2+((opcode>>3)&1), opcode & 7, + (pc+5+(s8)opcodes.r8(pc+4)) & 0xffffff); return 5; case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97: case 0x98: case 0x99: case 0x9a: case 0x9b: case 0x9c: case 0x9d: case 0x9e: case 0x9f: - util::stream_format(stream, "bset (%s, a%d) %d", i8str(program_read_byte(pc+3)), 2+((opcode>>3)&1), opcode & 7); + util::stream_format(stream, "bset (%s, a%d) %d", i8str(opcodes.r8(pc+3)), 2+((opcode>>3)&1), opcode & 7); return 4; case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7: case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf: - util::stream_format(stream, "tbnz (%s, a%d) %d, $%x", i8str(program_read_byte(pc+3)), 2+((opcode>>3)&1), opcode & 7, - (pc+5+(int8_t)program_read_byte(pc+4)) & 0xffffff); + util::stream_format(stream, "tbnz (%s, a%d) %d, $%x", i8str(opcodes.r8(pc+3)), 2+((opcode>>3)&1), opcode & 7, + (pc+5+(s8)opcodes.r8(pc+4)) & 0xffffff); return 5; case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf: - util::stream_format(stream, "bclr (%s, a%d) %d", i8str(program_read_byte(pc+3)), 2+((opcode>>3)&1), opcode & 7); + util::stream_format(stream, "bclr (%s, a%d) %d", i8str(opcodes.r8(pc+3)), 2+((opcode>>3)&1), opcode & 7); return 4; default: @@ -525,144 +496,144 @@ static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *o } case 0xf4: - opcode = program_read_byte(pc+1); + opcode = opcodes.r8(pc+1); switch(opcode) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: - util::stream_format(stream, "mov d%d, (%s, a%d)", opcode & 3, i24str(r24s(pc+2)), (opcode>>2) & 3); + util::stream_format(stream, "mov d%d, (%s, a%d)", opcode & 3, i24str(r24(opcodes, pc+2)), (opcode>>2) & 3); return 5; case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: - util::stream_format(stream, "mov a%d, (%s, a%d)", opcode & 3, i24str(r24s(pc+2)), (opcode>>2) & 3); + util::stream_format(stream, "mov a%d, (%s, a%d)", opcode & 3, i24str(r24(opcodes, pc+2)), (opcode>>2) & 3); return 5; case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f: - util::stream_format(stream, "movb d%d, (%s, a%d)", opcode & 3, i24str(r24s(pc+2)), (opcode>>2) & 3); + util::stream_format(stream, "movb d%d, (%s, a%d)", opcode & 3, i24str(r24(opcodes, pc+2)), (opcode>>2) & 3); return 5; case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f: - util::stream_format(stream, "movx d%d, (%s, a%d)", opcode & 3, i24str(r24s(pc+2)), (opcode>>2) & 3); + util::stream_format(stream, "movx d%d, (%s, a%d)", opcode & 3, i24str(r24(opcodes, pc+2)), (opcode>>2) & 3); return 5; case 0x40: case 0x41: case 0x42: case 0x43: - util::stream_format(stream, "mov d%d, ($%06x)", opcode & 3, r24u(pc+2)); + util::stream_format(stream, "mov d%d, ($%06x)", opcode & 3, r24(opcodes, pc+2)); return 5; case 0x44: case 0x45: case 0x46: case 0x47: - util::stream_format(stream, "movb d%d, ($%06x)", opcode & 3, r24u(pc+2)); + util::stream_format(stream, "movb d%d, ($%06x)", opcode & 3, r24(opcodes, pc+2)); return 5; case 0x4b: - util::stream_format(stream, "bset %02x, ($%06x)", program_read_byte(pc+5), r24u(pc+2)); + util::stream_format(stream, "bset %02x, ($%06x)", opcodes.r8(pc+5), r24(opcodes, pc+2)); return 6; case 0x4f: - util::stream_format(stream, "bclr %02x, ($%06x)", program_read_byte(pc+5), r24u(pc+2)); + util::stream_format(stream, "bclr %02x, ($%06x)", opcodes.r8(pc+5), r24(opcodes, pc+2)); return 6; case 0x50: case 0x51: case 0x52: case 0x53: - util::stream_format(stream, "mov a%d, ($%06x)", opcode & 3, r24u(pc+2)); + util::stream_format(stream, "mov a%d, ($%06x)", opcode & 3, r24(opcodes, pc+2)); return 5; case 0x60: case 0x61: case 0x62: case 0x63: - util::stream_format(stream, "add %s, d%d", i24str(r24s(pc+2)), opcode & 3); + util::stream_format(stream, "add %s, d%d", i24str(r24(opcodes, pc+2)), opcode & 3); return 5; case 0x64: case 0x65: case 0x66: case 0x67: - util::stream_format(stream, "add %s, a%d", i24str(r24s(pc+2)), opcode & 3); + util::stream_format(stream, "add %s, a%d", i24str(r24(opcodes, pc+2)), opcode & 3); return 5; case 0x68: case 0x69: case 0x6a: case 0x6b: - util::stream_format(stream, "sub %s, d%d", i24str(r24s(pc+2)), opcode & 3); + util::stream_format(stream, "sub %s, d%d", i24str(r24(opcodes, pc+2)), opcode & 3); return 5; case 0x6c: case 0x6d: case 0x6e: case 0x6f: - util::stream_format(stream, "sub %s, a%d", i24str(r24s(pc+2)), opcode & 3); + util::stream_format(stream, "sub %s, a%d", i24str(r24(opcodes, pc+2)), opcode & 3); return 5; case 0x70: case 0x71: case 0x72: case 0x73: - util::stream_format(stream, "mov %s, d%d", i24str(r24s(pc+2)), opcode & 3); + util::stream_format(stream, "mov %s, d%d", i24str(r24(opcodes, pc+2)), opcode & 3); return 5; case 0x74: case 0x75: case 0x76: case 0x77: - util::stream_format(stream, "mov $%06x, a%d", r24u(pc+2), opcode & 3); + util::stream_format(stream, "mov $%06x, a%d", r24(opcodes, pc+2), opcode & 3); return 5; case 0x78: case 0x79: case 0x7a: case 0x7b: - util::stream_format(stream, "cmp %s, d%d", i24str(r24s(pc+2)), opcode & 3); + util::stream_format(stream, "cmp %s, d%d", i24str(r24(opcodes, pc+2)), opcode & 3); return 5; case 0x7c: case 0x7d: case 0x7e: case 0x7f: - util::stream_format(stream, "cmp $%06x, a%d", r24u(pc+2), opcode & 3); + util::stream_format(stream, "cmp $%06x, a%d", r24(opcodes, pc+2), opcode & 3); return 5; case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87: case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f: - util::stream_format(stream, "mov (%s, a%d), d%d", i24str(r24s(pc+2)), (opcode>>2) & 3, opcode & 3); + util::stream_format(stream, "mov (%s, a%d), d%d", i24str(r24(opcodes, pc+2)), (opcode>>2) & 3, opcode & 3); return 5; case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97: case 0x98: case 0x99: case 0x9a: case 0x9b: case 0x9c: case 0x9d: case 0x9e: case 0x9f: - util::stream_format(stream, "movbu (%s, a%d), d%d", i24str(r24s(pc+2)), (opcode>>2) & 3, opcode & 3); + util::stream_format(stream, "movbu (%s, a%d), d%d", i24str(r24(opcodes, pc+2)), (opcode>>2) & 3, opcode & 3); return 5; case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7: case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf: - util::stream_format(stream, "movb (%s, a%d), d%d", i24str(r24s(pc+2)), (opcode>>2) & 3, opcode & 3); + util::stream_format(stream, "movb (%s, a%d), d%d", i24str(r24(opcodes, pc+2)), (opcode>>2) & 3, opcode & 3); return 5; case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf: - util::stream_format(stream, "movx (%s, a%d), d%d", i24str(r24s(pc+2)), (opcode>>2) & 3, opcode & 3); + util::stream_format(stream, "movx (%s, a%d), d%d", i24str(r24(opcodes, pc+2)), (opcode>>2) & 3, opcode & 3); return 5; case 0xc0: case 0xc1: case 0xc2: case 0xc3: - util::stream_format(stream, "mov ($%06x), d%d", r24u(pc+2), opcode & 3); + util::stream_format(stream, "mov ($%06x), d%d", r24(opcodes, pc+2), opcode & 3); return 5; case 0xc4: case 0xc5: case 0xc6: case 0xc7: - util::stream_format(stream, "movb ($%06x), d%d", r24u(pc+2), opcode & 3); + util::stream_format(stream, "movb ($%06x), d%d", r24(opcodes, pc+2), opcode & 3); return 5; case 0xc8: case 0xc9: case 0xca: case 0xcb: - util::stream_format(stream, "movbu ($%06x), d%d", r24u(pc+2), opcode & 3); + util::stream_format(stream, "movbu ($%06x), d%d", r24(opcodes, pc+2), opcode & 3); return 5; case 0xd0: case 0xd1: case 0xd2: case 0xd3: - util::stream_format(stream, "mov ($%06x), a%d", r24u(pc+2), opcode & 3); + util::stream_format(stream, "mov ($%06x), a%d", r24(opcodes, pc+2), opcode & 3); return 5; case 0xe0: - util::stream_format(stream, "jmp $%x", (pc+5+r24s(pc+2)) & 0xffffff); + util::stream_format(stream, "jmp $%x", (pc+5+r24(opcodes, pc+2)) & 0xffffff); return 5; case 0xe1: - util::stream_format(stream, "jsr $%x", (pc+5+r24s(pc+2)) & 0xffffff); + util::stream_format(stream, "jsr $%x", (pc+5+r24(opcodes, pc+2)) & 0xffffff); return 5; case 0xe3: - util::stream_format(stream, "bset $%02x, ($%x)", program_read_byte(pc+4), r16u(pc+2)); + util::stream_format(stream, "bset $%02x, ($%x)", opcodes.r8(pc+4), opcodes.r16(pc+2)); return 6; case 0xe7: - util::stream_format(stream, "bclr $%02x, ($%x)", program_read_byte(pc+4), r16u(pc+2)); + util::stream_format(stream, "bclr $%02x, ($%x)", opcodes.r8(pc+4), opcodes.r16(pc+2)); return 6; case 0xe8: case 0xe9: case 0xea: case 0xeb: - util::stream_format(stream, "bset $%02x, (%s, a%d)", program_read_byte(pc+3), i8str(program_read_byte(pc+2)), opcode & 3); + util::stream_format(stream, "bset $%02x, (%s, a%d)", opcodes.r8(pc+3), i8str(opcodes.r8(pc+2)), opcode & 3); return 4; case 0xec: case 0xed: case 0xee: case 0xef: - util::stream_format(stream, "bclr $%02x, (%s, a%d)", program_read_byte(pc+3), i8str(program_read_byte(pc+2)), opcode & 3); + util::stream_format(stream, "bclr $%02x, (%s, a%d)", opcodes.r8(pc+3), i8str(opcodes.r8(pc+2)), opcode & 3); return 4; case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff: - util::stream_format(stream, "mov (%s, a%d), a%d", i24str(r24s(pc+2)), (opcode>>2) & 3, opcode & 3); + util::stream_format(stream, "mov (%s, a%d), a%d", i24str(r24(opcodes, pc+2)), (opcode>>2) & 3, opcode & 3); return 5; default: @@ -670,44 +641,44 @@ static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *o } case 0xf5: - opcode = program_read_byte(pc+1); + opcode = opcodes.r8(pc+1); switch(opcode) { case 0x00: case 0x01: case 0x02: case 0x03: - util::stream_format(stream, "and $%02x, d%d", program_read_byte(pc+2), opcode & 3); + util::stream_format(stream, "and $%02x, d%d", opcodes.r8(pc+2), opcode & 3); return 3; case 0x04: case 0x05: case 0x06: case 0x07: - util::stream_format(stream, "btst $%02x, d%d", program_read_byte(pc+2), opcode & 3); + util::stream_format(stream, "btst $%02x, d%d", opcodes.r8(pc+2), opcode & 3); return 3; case 0x08: case 0x09: case 0x0a: case 0x0b: - util::stream_format(stream, "or $%02x, d%d", program_read_byte(pc+2), opcode & 3); + util::stream_format(stream, "or $%02x, d%d", opcodes.r8(pc+2), opcode & 3); return 3; case 0x0c: case 0x0d: case 0x0e: case 0x0f: - util::stream_format(stream, "addnf %s, a%d", i8str(program_read_byte(pc+2)), opcode & 3); + util::stream_format(stream, "addnf %s, a%d", i8str(opcodes.r8(pc+2)), opcode & 3); return 3; case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: - util::stream_format(stream, "movb d%d, (%s, a%d)", opcode & 3, i8str(program_read_byte(pc+2)), (opcode>>2) & 3); + util::stream_format(stream, "movb d%d, (%s, a%d)", opcode & 3, i8str(opcodes.r8(pc+2)), (opcode>>2) & 3); return 3; case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f: - util::stream_format(stream, "movb (%s, a%d), d%d", i8str(program_read_byte(pc+2)), (opcode>>2) & 3, opcode & 3); + util::stream_format(stream, "movb (%s, a%d), d%d", i8str(opcodes.r8(pc+2)), (opcode>>2) & 3, opcode & 3); return 3; case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f: - util::stream_format(stream, "movbu (%s, a%d), d%d", i8str(program_read_byte(pc+2)), (opcode>>2) & 3, opcode & 3); + util::stream_format(stream, "movbu (%s, a%d), d%d", i8str(opcodes.r8(pc+2)), (opcode>>2) & 3, opcode & 3); return 3; case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f: { - uint8_t opcode2 = program_read_byte(pc+2); + u8 opcode2 = opcodes.r8(pc+2); switch(opcode2) { case 0x00: @@ -725,13 +696,13 @@ static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *o case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57: case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f: - util::stream_format(stream, "movx d%d, (%s, a%d)", opcode & 3, i8str(program_read_byte(pc+2)), (opcode>>2) & 3); + util::stream_format(stream, "movx d%d, (%s, a%d)", opcode & 3, i8str(opcodes.r8(pc+2)), (opcode>>2) & 3); return 3; case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f: { - uint8_t opcode2 = program_read_byte(pc+2); + u8 opcode2 = opcodes.r8(pc+2); switch(opcode2) { case 0x10: @@ -745,124 +716,124 @@ static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *o case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77: case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f: - util::stream_format(stream, "movx (%s, a%d), d%d", i8str(program_read_byte(pc+2)), (opcode>>2) & 3, opcode & 3); + util::stream_format(stream, "movx (%s, a%d), d%d", i8str(opcodes.r8(pc+2)), (opcode>>2) & 3, opcode & 3); return 3; case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87: case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f: - util::stream_format(stream, "tbz (%s, a%d) %d, $%x", i8str(program_read_byte(pc+2)), (opcode>>3)&1, opcode & 7, - (pc+4+(int8_t)program_read_byte(pc+3)) & 0xffffff); + util::stream_format(stream, "tbz (%s, a%d) %d, $%x", i8str(opcodes.r8(pc+2)), (opcode>>3)&1, opcode & 7, + (pc+4+(s8)opcodes.r8(pc+3)) & 0xffffff); return 4; case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97: case 0x98: case 0x99: case 0x9a: case 0x9b: case 0x9c: case 0x9d: case 0x9e: case 0x9f: - util::stream_format(stream, "bset (%s, a%d) %d", i8str(program_read_byte(pc+2)), (opcode>>3)&1, opcode & 7); + util::stream_format(stream, "bset (%s, a%d) %d", i8str(opcodes.r8(pc+2)), (opcode>>3)&1, opcode & 7); return 3; case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7: case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf: - util::stream_format(stream, "tbnz (%s, a%d) %d, $%x", i8str(program_read_byte(pc+2)), (opcode>>3)&1, opcode & 7, - (pc+4+(int8_t)program_read_byte(pc+3)) & 0xffffff); + util::stream_format(stream, "tbnz (%s, a%d) %d, $%x", i8str(opcodes.r8(pc+2)), (opcode>>3)&1, opcode & 7, + (pc+4+(s8)opcodes.r8(pc+3)) & 0xffffff); return 4; case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf: - util::stream_format(stream, "bclr (%s, a%d) %d", i8str(program_read_byte(pc+2)), (opcode>>3)&1, opcode & 7); + util::stream_format(stream, "bclr (%s, a%d) %d", i8str(opcodes.r8(pc+2)), (opcode>>3)&1, opcode & 7); return 3; case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: - util::stream_format(stream, "tbz ($%x) %d, $%x", r16u(pc+2), opcode & 7, - (pc+5+(int8_t)program_read_byte(pc+4)) & 0xffffff); + util::stream_format(stream, "tbz ($%x) %d, $%x", opcodes.r16(pc+2), opcode & 7, + (pc+5+(s8)opcodes.r8(pc+4)) & 0xffffff); return 5; case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: - util::stream_format(stream, "tbnz ($%x) %d, $%x", r16u(pc+2), opcode & 7, - (pc+5+(int8_t)program_read_byte(pc+4)) & 0xffffff); + util::stream_format(stream, "tbnz ($%x) %d, $%x", opcodes.r16(pc+2), opcode & 7, + (pc+5+(s8)opcodes.r8(pc+4)) & 0xffffff); return 5; case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: - util::stream_format(stream, "bset ($%x) %d", r16u(pc+2), opcode & 7); + util::stream_format(stream, "bset ($%x) %d", opcodes.r16(pc+2), opcode & 7); return 4; case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: - util::stream_format(stream, "bclr ($%x) %d", r16u(pc+2), opcode & 7); + util::stream_format(stream, "bclr ($%x) %d", opcodes.r16(pc+2), opcode & 7); return 4; case 0xe0: - util::stream_format(stream, "bltx $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "bltx $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; case 0xe1: - util::stream_format(stream, "bgtx $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "bgtx $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; case 0xe2: - util::stream_format(stream, "bgex $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "bgex $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; case 0xe3: - util::stream_format(stream, "blex $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "blex $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; case 0xe4: - util::stream_format(stream, "bcsx $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "bcsx $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; case 0xe5: - util::stream_format(stream, "bhix $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "bhix $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; case 0xe6: - util::stream_format(stream, "bccx $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "bccx $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; case 0xe7: - util::stream_format(stream, "blsx $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "blsx $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; case 0xe8: - util::stream_format(stream, "beqx $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "beqx $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; case 0xe9: - util::stream_format(stream, "bnex $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "bnex $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; case 0xec: - util::stream_format(stream, "bvcx $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "bvcx $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; case 0xed: - util::stream_format(stream, "bvsx $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "bvsx $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; case 0xee: - util::stream_format(stream, "bncx $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "bncx $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; case 0xef: - util::stream_format(stream, "bnsx $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "bnsx $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: { - uint8_t opcode2 = program_read_byte(pc+2); + u8 opcode2 = opcodes.r8(pc+2); switch(opcode2) { case 0x04: - util::stream_format(stream, "mulql %s, d%d", i8str(program_read_byte(pc+3)), opcode & 3); + util::stream_format(stream, "mulql %s, d%d", i8str(opcodes.r8(pc+3)), opcode & 3); return 4; case 0x05: - util::stream_format(stream, "mulqh %s, d%d", i8str(program_read_byte(pc+3)), opcode & 3); + util::stream_format(stream, "mulqh %s, d%d", i8str(opcodes.r8(pc+3)), opcode & 3); return 4; case 0x08: - util::stream_format(stream, "mulql %s, d%d", i16str(r16s(pc+3)), opcode & 3); + util::stream_format(stream, "mulql %s, d%d", i16str(opcodes.r16(pc+3)), opcode & 3); return 5; case 0x09: - util::stream_format(stream, "mulqh %s, d%d", i16str(r16s(pc+3)), opcode & 3); + util::stream_format(stream, "mulqh %s, d%d", i16str(opcodes.r16(pc+3)), opcode & 3); return 5; default: @@ -871,19 +842,19 @@ static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *o } case 0xfc: - util::stream_format(stream, "bvc $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "bvc $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; case 0xfd: - util::stream_format(stream, "bvs $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "bvs $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; case 0xfe: - util::stream_format(stream, "bnc $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "bnc $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; case 0xff: - util::stream_format(stream, "bns $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "bns $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; default: @@ -895,104 +866,104 @@ static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *o return 1; case 0xf7: - opcode = program_read_byte(pc+1); + opcode = opcodes.r8(pc+1); switch(opcode) { case 0x00: case 0x01: case 0x02: case 0x03: - util::stream_format(stream, "and $%04x, d%d", r16u(pc+2), opcode & 3); + util::stream_format(stream, "and $%04x, d%d", opcodes.r16(pc+2), opcode & 3); return 4; case 0x04: case 0x05: case 0x06: case 0x07: - util::stream_format(stream, "btst $%04x, d%d", r16u(pc+2), opcode & 3); + util::stream_format(stream, "btst $%04x, d%d", opcodes.r16(pc+2), opcode & 3); return 4; case 0x08: case 0x09: case 0x0a: case 0x0b: - util::stream_format(stream, "add %s, a%d", i16str(r16s(pc+2)), opcode & 3); + util::stream_format(stream, "add %s, a%d", i16str(opcodes.r16(pc+2)), opcode & 3); return 4; case 0x0c: case 0x0d: case 0x0e: case 0x0f: - util::stream_format(stream, "sub %s, a%d", i16str(r16s(pc+2)), opcode & 3); + util::stream_format(stream, "sub %s, a%d", i16str(opcodes.r16(pc+2)), opcode & 3); return 4; case 0x10: - util::stream_format(stream, "and $%04x, psw", r16u(pc+2)); + util::stream_format(stream, "and $%04x, psw", opcodes.r16(pc+2)); return 4; case 0x14: - util::stream_format(stream, "or $%04x, psw", r16u(pc+2)); + util::stream_format(stream, "or $%04x, psw", opcodes.r16(pc+2)); return 4; case 0x18: case 0x19: case 0x1a: case 0x1b: - util::stream_format(stream, "add %s, d%d", i16str(r16u(pc+2)), opcode & 3); + util::stream_format(stream, "add %s, d%d", i16str(opcodes.r16(pc+2)), opcode & 3); return 4; case 0x1c: case 0x1d: case 0x1e: case 0x1f: - util::stream_format(stream, "sub %s, d%d", i16str(r16s(pc+2)), opcode & 3); + util::stream_format(stream, "sub %s, d%d", i16str(opcodes.r16(pc+2)), opcode & 3); return 4; case 0x20: case 0x21: case 0x22: case 0x23: - util::stream_format(stream, "mov a%d, ($%04x)", opcode & 3, r16u(pc+2)); + util::stream_format(stream, "mov a%d, ($%04x)", opcode & 3, opcodes.r16(pc+2)); return 4; case 0x30: case 0x31: case 0x32: case 0x33: - util::stream_format(stream, "mov ($%04x), a%d", r16u(pc+2), opcode & 3); + util::stream_format(stream, "mov ($%04x), a%d", opcodes.r16(pc+2), opcode & 3); return 4; case 0x40: case 0x41: case 0x42: case 0x43: - util::stream_format(stream, "or $%04x, d%d", r16u(pc+2), opcode & 3); + util::stream_format(stream, "or $%04x, d%d", opcodes.r16(pc+2), opcode & 3); return 4; case 0x48: case 0x49: case 0x4a: case 0x4b: - util::stream_format(stream, "cmp %s, d%d", i16str(r16u(pc+2)), opcode & 3); + util::stream_format(stream, "cmp %s, d%d", i16str(opcodes.r16(pc+2)), opcode & 3); return 4; case 0x4c: case 0x4d: case 0x4e: case 0x4f: - util::stream_format(stream, "xor $%04x, d%d", r16u(pc+2), opcode & 3); + util::stream_format(stream, "xor $%04x, d%d", opcodes.r16(pc+2), opcode & 3); return 4; case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57: case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f: - util::stream_format(stream, "movbu (%s, a%d), d%d", i16str(r16s(pc+2)), (opcode>>2) & 3, opcode & 3); + util::stream_format(stream, "movbu (%s, a%d), d%d", i16str(opcodes.r16(pc+2)), (opcode>>2) & 3, opcode & 3); return 4; case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f: - util::stream_format(stream, "movx d%d, (%s, a%d)", opcode & 3, i16str(r16s(pc+2)), (opcode>>2) & 3); + util::stream_format(stream, "movx d%d, (%s, a%d)", opcode & 3, i16str(opcodes.r16(pc+2)), (opcode>>2) & 3); return 4; case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77: case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f: - util::stream_format(stream, "movx (%s, a%d), d%d", i16str(r16s(pc+2)), (opcode>>2) & 3, opcode & 3); + util::stream_format(stream, "movx (%s, a%d), d%d", i16str(opcodes.r16(pc+2)), (opcode>>2) & 3, opcode & 3); return 4; case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87: case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f: - util::stream_format(stream, "mov d%d, (%s, a%d)", opcode & 3, i16str(r16s(pc+2)), (opcode>>2) & 3); + util::stream_format(stream, "mov d%d, (%s, a%d)", opcode & 3, i16str(opcodes.r16(pc+2)), (opcode>>2) & 3); return 4; case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97: case 0x98: case 0x99: case 0x9a: case 0x9b: case 0x9c: case 0x9d: case 0x9e: case 0x9f: - util::stream_format(stream, "movb d%d, (%s, a%d)", opcode & 3, i16str(r16s(pc+2)), (opcode>>2) & 3); + util::stream_format(stream, "movb d%d, (%s, a%d)", opcode & 3, i16str(opcodes.r16(pc+2)), (opcode>>2) & 3); return 4; case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7: case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf: - util::stream_format(stream, "mov a%d, (%s, a%d)", opcode & 3, i16str(r16s(pc+2)), (opcode>>2) & 3); + util::stream_format(stream, "mov a%d, (%s, a%d)", opcode & 3, i16str(opcodes.r16(pc+2)), (opcode>>2) & 3); return 4; case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf: - util::stream_format(stream, "mov (%s, a%d), a%d", i16str(r16s(pc+2)), (opcode>>2) & 3, opcode & 3); + util::stream_format(stream, "mov (%s, a%d), a%d", i16str(opcodes.r16(pc+2)), (opcode>>2) & 3, opcode & 3); return 4; case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: - util::stream_format(stream, "mov (%s, a%d), d%d", i16str(r16s(pc+2)), (opcode>>2) & 3, opcode & 3); + util::stream_format(stream, "mov (%s, a%d), d%d", i16str(opcodes.r16(pc+2)), (opcode>>2) & 3, opcode & 3); return 4; case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: - util::stream_format(stream, "movb (%s, a%d), d%d", i16str(r16s(pc+2)), (opcode>>2) & 3, opcode & 3); + util::stream_format(stream, "movb (%s, a%d), d%d", i16str(opcodes.r16(pc+2)), (opcode>>2) & 3, opcode & 3); return 4; default: @@ -1000,15 +971,15 @@ static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *o } case 0xf8: case 0xf9: case 0xfa: case 0xfb: - util::stream_format(stream, "mov %s, d%d", i16str(r16s(pc+1)), opcode & 3); + util::stream_format(stream, "mov %s, d%d", i16str(opcodes.r16(pc+1)), opcode & 3); return 3; case 0xfc: - util::stream_format(stream, "jmp $%x", (pc+3+r16s(pc+1)) & 0xffffff); + util::stream_format(stream, "jmp $%x", (pc+3+s16(opcodes.r16(pc+1))) & 0xffffff); return 3; case 0xfd: - util::stream_format(stream, "jsr $%x", (pc+3+r16s(pc+1)) & 0xffffff); + util::stream_format(stream, "jsr $%x", (pc+3+s16(opcodes.r16(pc+1))) & 0xffffff); return 3; case 0xfe: @@ -1020,19 +991,14 @@ static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *o }; illegal1: - util::stream_format(stream, "dc.b $%02x", program_read_byte(pc)); + util::stream_format(stream, "dc.b $%02x", opcodes.r8(pc)); return 1; illegal2: - util::stream_format(stream, "dc.b $%02x $%02x", program_read_byte(pc), program_read_byte(pc+1)); + util::stream_format(stream, "dc.b $%02x $%02x", opcodes.r8(pc), opcodes.r8(pc+1)); return 2; illegal3: - util::stream_format(stream, "dc.b $%02x $%02x $%02x", program_read_byte(pc), program_read_byte(pc+1), program_read_byte(pc+2)); + util::stream_format(stream, "dc.b $%02x $%02x $%02x", opcodes.r8(pc), opcodes.r8(pc+1), opcodes.r8(pc+2)); return 3; } - -CPU_DISASSEMBLE( mn10200 ) -{ - return mn102_disassemble(stream, pc, oprom); -} diff --git a/src/devices/cpu/mn10200/mn102dis.h b/src/devices/cpu/mn10200/mn102dis.h new file mode 100644 index 00000000000..4fa8e932812 --- /dev/null +++ b/src/devices/cpu/mn10200/mn102dis.h @@ -0,0 +1,28 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert, R. Belmont, hap +/* + Panasonic MN10200 disassembler +*/ + +#ifndef MAME_CPU_MN10200_MN102DIS_H +#define MAME_CPU_MN10200_MN102DIS_H + +#pragma once + +class mn10200_disassembler : public util::disasm_interface +{ +public: + mn10200_disassembler() = default; + virtual ~mn10200_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + u32 r24(const data_buffer &opcodes, offs_t pc); + std::string i8str(s8 v); + std::string i16str(int16_t v); + std::string i24str(u32 v); +}; + +#endif diff --git a/src/devices/cpu/nanoprocessor/nanoprocessor.cpp b/src/devices/cpu/nanoprocessor/nanoprocessor.cpp index 655dfdb6af2..8533ec2b102 100644 --- a/src/devices/cpu/nanoprocessor/nanoprocessor.cpp +++ b/src/devices/cpu/nanoprocessor/nanoprocessor.cpp @@ -3,6 +3,7 @@ #include "emu.h" #include "nanoprocessor.h" +#include "nanoprocessor_dasm.h" #include "debugger.h" // Index of state variables @@ -33,8 +34,8 @@ enum { #define BIT_MASK(n) (1U << (n)) // Macros to clear/set single bits -#define BIT_CLR(w , n) ((w) &= ~BIT_MASK(n)) -#define BIT_SET(w , n) ((w) |= BIT_MASK(n)) +#define BIT_CLR(w, n) ((w) &= ~BIT_MASK(n)) +#define BIT_SET(w, n) ((w) |= BIT_MASK(n)) // Bits in m_flags #define NANO_DC0_BIT 0 // DC0 @@ -44,42 +45,42 @@ enum { DEFINE_DEVICE_TYPE(HP_NANOPROCESSOR, hp_nanoprocessor_device, "nanoprocessor", "HP-Nanoprocessor") hp_nanoprocessor_device::hp_nanoprocessor_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - cpu_device(mconfig , HP_NANOPROCESSOR , tag , owner , clock), + cpu_device(mconfig, HP_NANOPROCESSOR, tag, owner, clock), m_dc_changed_func(*this), m_read_dc_func(*this), - m_program_config("program" , ENDIANNESS_BIG , 8 , 11), - m_io_config("io" , ENDIANNESS_BIG , 8 , 4) + m_program_config("program", ENDIANNESS_BIG, 8, 11), + m_io_config("io", ENDIANNESS_BIG, 8, 4) { } void hp_nanoprocessor_device::device_start() { - state_add(NANO_REG_A , "A" , m_reg_A); - state_add(NANO_REG_R0 , "R0" , m_reg_R[ 0 ]); - state_add(NANO_REG_R1 , "R1" , m_reg_R[ 1 ]); - state_add(NANO_REG_R2 , "R2" , m_reg_R[ 2 ]); - state_add(NANO_REG_R3 , "R3" , m_reg_R[ 3 ]); - state_add(NANO_REG_R4 , "R4" , m_reg_R[ 4 ]); - state_add(NANO_REG_R5 , "R5" , m_reg_R[ 5 ]); - state_add(NANO_REG_R6 , "R6" , m_reg_R[ 6 ]); - state_add(NANO_REG_R7 , "R7" , m_reg_R[ 7 ]); - state_add(NANO_REG_R8 , "R8" , m_reg_R[ 8 ]); - state_add(NANO_REG_R9 , "R9" , m_reg_R[ 9 ]); - state_add(NANO_REG_R10 , "R10" , m_reg_R[ 10 ]); - state_add(NANO_REG_R11 , "R11" , m_reg_R[ 11 ]); - state_add(NANO_REG_R12 , "R12" , m_reg_R[ 12 ]); - state_add(NANO_REG_R13 , "R13" , m_reg_R[ 13 ]); - state_add(NANO_REG_R14 , "R14" , m_reg_R[ 14 ]); - state_add(NANO_REG_R15 , "R15" , m_reg_R[ 15 ]); - state_add(NANO_REG_PA , "PA" , m_reg_PA).formatstr("%03X"); - state_add(STATE_GENPC , "GENPC" , m_reg_PA).noshow(); - state_add(STATE_GENPCBASE , "GENPCBASE" , m_reg_PA).noshow(); - state_add(NANO_REG_SSR , "SSR" , m_reg_SSR).formatstr("%03X"); - state_add(NANO_REG_ISR , "ISR" , m_reg_ISR).formatstr("%03X"); - state_add(STATE_GENFLAGS , "GENFLAGS" , m_flags).noshow().formatstr("%10s"); + state_add(NANO_REG_A, "A", m_reg_A); + state_add(NANO_REG_R0, "R0", m_reg_R[ 0 ]); + state_add(NANO_REG_R1, "R1", m_reg_R[ 1 ]); + state_add(NANO_REG_R2, "R2", m_reg_R[ 2 ]); + state_add(NANO_REG_R3, "R3", m_reg_R[ 3 ]); + state_add(NANO_REG_R4, "R4", m_reg_R[ 4 ]); + state_add(NANO_REG_R5, "R5", m_reg_R[ 5 ]); + state_add(NANO_REG_R6, "R6", m_reg_R[ 6 ]); + state_add(NANO_REG_R7, "R7", m_reg_R[ 7 ]); + state_add(NANO_REG_R8, "R8", m_reg_R[ 8 ]); + state_add(NANO_REG_R9, "R9", m_reg_R[ 9 ]); + state_add(NANO_REG_R10, "R10", m_reg_R[ 10 ]); + state_add(NANO_REG_R11, "R11", m_reg_R[ 11 ]); + state_add(NANO_REG_R12, "R12", m_reg_R[ 12 ]); + state_add(NANO_REG_R13, "R13", m_reg_R[ 13 ]); + state_add(NANO_REG_R14, "R14", m_reg_R[ 14 ]); + state_add(NANO_REG_R15, "R15", m_reg_R[ 15 ]); + state_add(NANO_REG_PA, "PA", m_reg_PA).formatstr("%03X"); + state_add(STATE_GENPC, "GENPC", m_reg_PA).noshow(); + state_add(STATE_GENPCBASE, "GENPCBASE", m_reg_PA).noshow(); + state_add(NANO_REG_SSR, "SSR", m_reg_SSR).formatstr("%03X"); + state_add(NANO_REG_ISR, "ISR", m_reg_ISR).formatstr("%03X"); + state_add(STATE_GENFLAGS, "GENFLAGS", m_flags).noshow().formatstr("%10s"); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); save_item(NAME(m_reg_A)); @@ -122,7 +123,7 @@ void hp_nanoprocessor_device::execute_run() // Check for interrupts (interrupt line is always enabled. Masking is done // outside of the NP, usually by ANDing the DC7 line with the interrupt // request signal) - if (BIT(m_flags , NANO_I_BIT)) { + if (BIT(m_flags, NANO_I_BIT)) { m_reg_ISR = m_reg_PA; m_reg_PA = (uint16_t)(standard_irq_callback(0) & 0xff); // Vector fetching takes 1 cycle @@ -131,7 +132,7 @@ void hp_nanoprocessor_device::execute_run() // Need this to propagate the clearing of DC7 to the clearing of int. line yield(); } else { - debugger_instruction_hook(this , m_reg_PA); + debugger_instruction_hook(this, m_reg_PA); uint8_t opcode = fetch(); execute_one(opcode); @@ -156,23 +157,22 @@ void hp_nanoprocessor_device::state_string_export(const device_state_entry &entr { if (entry.index() == STATE_GENFLAGS) { // DC7 is reported as "I" because it is usually used as interrupt enable - str = string_format("%c %c%c%c%c%c%c%c%c" , BIT(m_flags , NANO_E_BIT) ? 'E' : ' ', - BIT(m_flags , NANO_DC0_BIT + 7) ? 'I' : ' ', - BIT(m_flags , NANO_DC0_BIT + 6) ? '6' : ' ', - BIT(m_flags , NANO_DC0_BIT + 5) ? '5' : ' ', - BIT(m_flags , NANO_DC0_BIT + 4) ? '4' : ' ', - BIT(m_flags , NANO_DC0_BIT + 3) ? '3' : ' ', - BIT(m_flags , NANO_DC0_BIT + 2) ? '2' : ' ', - BIT(m_flags , NANO_DC0_BIT + 1) ? '1' : ' ', - BIT(m_flags , NANO_DC0_BIT + 0) ? '0' : ' '); + str = string_format("%c %c%c%c%c%c%c%c%c", BIT(m_flags, NANO_E_BIT) ? 'E' : ' ', + BIT(m_flags, NANO_DC0_BIT + 7) ? 'I' : ' ', + BIT(m_flags, NANO_DC0_BIT + 6) ? '6' : ' ', + BIT(m_flags, NANO_DC0_BIT + 5) ? '5' : ' ', + BIT(m_flags, NANO_DC0_BIT + 4) ? '4' : ' ', + BIT(m_flags, NANO_DC0_BIT + 3) ? '3' : ' ', + BIT(m_flags, NANO_DC0_BIT + 2) ? '2' : ' ', + BIT(m_flags, NANO_DC0_BIT + 1) ? '1' : ' ', + BIT(m_flags, NANO_DC0_BIT + 0) ? '0' : ' '); } } -offs_t hp_nanoprocessor_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *hp_nanoprocessor_device::create_disassembler() { - extern CPU_DISASSEMBLE(hp_nanoprocessor); - return CPU_DISASSEMBLE_NAME(hp_nanoprocessor)(this , stream , pc , oprom , opram , options); + return new hp_nanoprocessor_disassembler; } void hp_nanoprocessor_device::execute_one(uint8_t opcode) @@ -299,14 +299,14 @@ void hp_nanoprocessor_device::execute_one(uint8_t opcode) case 0x1f: // SES - if (BIT(m_flags , NANO_E_BIT)) { + if (BIT(m_flags, NANO_E_BIT)) { skip(); } break; case 0x3f: // SEZ - if (!BIT(m_flags , NANO_E_BIT)) { + if (!BIT(m_flags, NANO_E_BIT)) { skip(); } break; @@ -359,7 +359,7 @@ void hp_nanoprocessor_device::execute_one(uint8_t opcode) switch (opcode & 0xf8) { case 0x10: // SBS - if (BIT(m_reg_A , opcode & 7)) { + if (BIT(m_reg_A, opcode & 7)) { skip(); } break; @@ -369,7 +369,7 @@ void hp_nanoprocessor_device::execute_one(uint8_t opcode) { uint8_t tmp = m_read_dc_func(); tmp &= (uint8_t)(m_flags >> NANO_DC0_BIT); - if (BIT(tmp , opcode & 7)) { + if (BIT(tmp, opcode & 7)) { skip(); } } @@ -387,7 +387,7 @@ void hp_nanoprocessor_device::execute_one(uint8_t opcode) case 0x30: // SBZ - if (!BIT(m_reg_A , opcode & 7)) { + if (!BIT(m_reg_A, opcode & 7)) { skip(); } break; @@ -397,7 +397,7 @@ void hp_nanoprocessor_device::execute_one(uint8_t opcode) { uint8_t tmp = m_read_dc_func(); tmp &= (uint8_t)(m_flags >> NANO_DC0_BIT); - if (!BIT(tmp , opcode & 7)) { + if (!BIT(tmp, opcode & 7)) { skip(); } } @@ -459,7 +459,7 @@ void hp_nanoprocessor_device::execute_one(uint8_t opcode) case 0x50: // OTA - m_io->write_byte(opcode & 0xf , m_reg_A); + m_io->write_byte(opcode & 0xf, m_reg_A); break; case 0x60: @@ -474,7 +474,7 @@ void hp_nanoprocessor_device::execute_one(uint8_t opcode) case 0xc0: // OTR - m_io->write_byte(opcode & 0xf , fetch()); + m_io->write_byte(opcode & 0xf, fetch()); break; case 0xd0: @@ -493,7 +493,7 @@ void hp_nanoprocessor_device::execute_one(uint8_t opcode) break; default: - logerror("Unknown opcode %02x @ 0x03x\n" , opcode , m_reg_PA); + logerror("Unknown opcode %02x @ 0x03x\n", opcode, m_reg_PA); break; } } diff --git a/src/devices/cpu/nanoprocessor/nanoprocessor.h b/src/devices/cpu/nanoprocessor/nanoprocessor.h index 3518d80810b..98b717e6c07 100644 --- a/src/devices/cpu/nanoprocessor/nanoprocessor.h +++ b/src/devices/cpu/nanoprocessor/nanoprocessor.h @@ -91,9 +91,7 @@ public: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 2; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: static constexpr unsigned HP_NANO_REGS = 16; // Number of GP registers @@ -116,7 +114,7 @@ private: address_space_config m_io_config; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_io; // device_t overrides diff --git a/src/devices/cpu/nanoprocessor/nanoprocessor_dasm.cpp b/src/devices/cpu/nanoprocessor/nanoprocessor_dasm.cpp index 6ec1239dbc6..352c8fcbcf2 100644 --- a/src/devices/cpu/nanoprocessor/nanoprocessor_dasm.cpp +++ b/src/devices/cpu/nanoprocessor/nanoprocessor_dasm.cpp @@ -5,126 +5,118 @@ // ******************************* #include "emu.h" -#include "debugger.h" -#include "nanoprocessor.h" +#include "nanoprocessor_dasm.h" -typedef void (*fn_dis_param)(std::ostream& stream , uint8_t opcode , const uint8_t* opram); - -typedef struct { - uint8_t m_op_mask; - uint8_t m_opcode; - const char *m_mnemonic; - fn_dis_param m_param_fn; - uint32_t m_dasm_flags; -} dis_entry_t; - -static void param_bitno(std::ostream& stream , uint8_t opcode , const uint8_t* opram) +void hp_nanoprocessor_disassembler::param_bitno(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms) { stream << (char)('0' + (opcode & 7)); } -static void param_ds(std::ostream& stream , uint8_t opcode , const uint8_t* opram) +void hp_nanoprocessor_disassembler::param_ds(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms) { - util::stream_format(stream , "DS%u" , opcode & 0xf); + util::stream_format(stream, "DS%u", opcode & 0xf); } -static void param_reg(std::ostream& stream , uint8_t opcode , const uint8_t* opram) +void hp_nanoprocessor_disassembler::param_reg(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms) { - util::stream_format(stream , "R%u" , opcode & 0xf); + util::stream_format(stream, "R%u", opcode & 0xf); } -static void param_11bit(std::ostream& stream , uint8_t opcode , const uint8_t* opram) +void hp_nanoprocessor_disassembler::param_11bit(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms) { - unsigned tmp = ((unsigned)(opcode & 7) << 8) | *opram; - util::stream_format(stream , "$%03x" , tmp); + unsigned tmp = ((unsigned)(opcode & 7) << 8) | params.r8(pc); + util::stream_format(stream, "$%03x", tmp); } -static void param_page_no(std::ostream& stream , uint8_t opcode , const uint8_t* opram) +void hp_nanoprocessor_disassembler::param_page_no(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms) { stream << (char)('0' + (opcode & 7)); } -static void param_byte(std::ostream& stream , uint8_t opcode , const uint8_t* opram) +void hp_nanoprocessor_disassembler::param_byte(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms) { - util::stream_format(stream , "$%02x" , *opram); + util::stream_format(stream, "$%02x", params.r8(pc)); } -static void param_ds_byte(std::ostream& stream , uint8_t opcode , const uint8_t* opram) +void hp_nanoprocessor_disassembler::param_ds_byte(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms) { - util::stream_format(stream , "DS%u,$%02x" , opcode & 0xf , *opram); + util::stream_format(stream, "DS%u,$%02x", opcode & 0xf, params.r8(pc)); } -static void param_reg_byte(std::ostream& stream , uint8_t opcode , const uint8_t* opram) +void hp_nanoprocessor_disassembler::param_reg_byte(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms) { - util::stream_format(stream , "R%u,$%02x" , opcode & 0xf , *opram); + util::stream_format(stream, "R%u,$%02x", opcode & 0xf, params.r8(pc)); } -static const dis_entry_t dis_table[] = { - {0xff , 0x00 , "INB" , nullptr , 1}, - {0xff , 0x01 , "DEB" , nullptr , 1}, - {0xff , 0x02 , "IND" , nullptr , 1}, - {0xff , 0x03 , "DED" , nullptr , 1}, - {0xff , 0x04 , "CLA" , nullptr , 1}, - {0xff , 0x05 , "CMA" , nullptr , 1}, - {0xff , 0x06 , "RSA" , nullptr , 1}, - {0xff , 0x07 , "LSA" , nullptr , 1}, - {0xff , 0x08 , "SGT" , nullptr , 1}, - {0xff , 0x09 , "SLT" , nullptr , 1}, - {0xff , 0x0a , "SEQ" , nullptr , 1}, - {0xff , 0x0b , "SAZ" , nullptr , 1}, - {0xff , 0x0c , "SLE" , nullptr , 1}, - {0xff , 0x0d , "SGE" , nullptr , 1}, - {0xff , 0x0e , "SNE" , nullptr , 1}, - {0xff , 0x0f , "SAN" , nullptr , 1}, - {0xf8 , 0x10 , "SBS" , param_bitno , 1}, - {0xff , 0x1f , "SES" , nullptr , 1}, - {0xf8 , 0x18 , "SFS" , param_bitno , 1}, - {0xf8 , 0x20 , "SBN" , param_bitno , 1}, - {0xff , 0x2f , "ENI" , nullptr , 1}, - {0xf8 , 0x28 , "STC" , param_bitno , 1}, - {0xf8 , 0x30 , "SBZ" , param_bitno , 1}, - {0xff , 0x3f , "SEZ" , nullptr , 1}, - {0xf8 , 0x38 , "SFZ" , param_bitno , 1}, - {0xf0 , 0x40 , "INA" , param_ds , 1}, - {0xff , 0x5f , "NOP" , nullptr , 1}, - {0xf0 , 0x50 , "OTA" , param_ds , 1}, - {0xf0 , 0x60 , "LDA" , param_reg , 1}, - {0xf0 , 0x70 , "STA" , param_reg , 1}, - {0xf8 , 0x80 , "JMP" , param_11bit , 2}, - {0xf8 , 0x88 , "JSB" , param_11bit , 2 | DASMFLAG_STEP_OVER}, - {0xf8 , 0x90 , "JAI" , param_page_no , 1}, - {0xf8 , 0x98 , "JAS" , param_page_no , 1 | DASMFLAG_STEP_OVER}, - {0xf8 , 0xa0 , "CBN" , param_bitno , 1}, - {0xff , 0xaf , "DSI" , nullptr , 1}, - {0xf8 , 0xa8 , "CLC" , param_bitno , 1}, - {0xff , 0xb0 , "RTI" , nullptr , 1 | DASMFLAG_STEP_OUT}, - {0xff , 0xb1 , "RTE" , nullptr , 1 | DASMFLAG_STEP_OUT}, - {0xff , 0xb4 , "STE" , nullptr , 1}, - {0xff , 0xb5 , "CLE" , nullptr , 1}, - {0xff , 0xb8 , "RTS" , nullptr , 1 | DASMFLAG_STEP_OUT}, - {0xff , 0xb9 , "RSE" , nullptr , 1 | DASMFLAG_STEP_OUT}, - {0xff , 0xcf , "LDR" , param_byte , 2}, - {0xf0 , 0xc0 , "OTR" , param_ds_byte , 2}, - {0xf0 , 0xd0 , "STR" , param_reg_byte , 2}, - {0xf0 , 0xe0 , "LDI" , param_reg , 1}, - {0xf0 , 0xf0 , "STI" , param_reg , 1}, +const hp_nanoprocessor_disassembler::dis_entry_t hp_nanoprocessor_disassembler::dis_table[] = { + {0xff, 0x00, "INB", nullptr, 1}, + {0xff, 0x01, "DEB", nullptr, 1}, + {0xff, 0x02, "IND", nullptr, 1}, + {0xff, 0x03, "DED", nullptr, 1}, + {0xff, 0x04, "CLA", nullptr, 1}, + {0xff, 0x05, "CMA", nullptr, 1}, + {0xff, 0x06, "RSA", nullptr, 1}, + {0xff, 0x07, "LSA", nullptr, 1}, + {0xff, 0x08, "SGT", nullptr, 1}, + {0xff, 0x09, "SLT", nullptr, 1}, + {0xff, 0x0a, "SEQ", nullptr, 1}, + {0xff, 0x0b, "SAZ", nullptr, 1}, + {0xff, 0x0c, "SLE", nullptr, 1}, + {0xff, 0x0d, "SGE", nullptr, 1}, + {0xff, 0x0e, "SNE", nullptr, 1}, + {0xff, 0x0f, "SAN", nullptr, 1}, + {0xf8, 0x10, "SBS", &hp_nanoprocessor_disassembler::param_bitno, 1}, + {0xff, 0x1f, "SES", nullptr, 1}, + {0xf8, 0x18, "SFS", &hp_nanoprocessor_disassembler::param_bitno, 1}, + {0xf8, 0x20, "SBN", &hp_nanoprocessor_disassembler::param_bitno, 1}, + {0xff, 0x2f, "ENI", nullptr, 1}, + {0xf8, 0x28, "STC", &hp_nanoprocessor_disassembler::param_bitno, 1}, + {0xf8, 0x30, "SBZ", &hp_nanoprocessor_disassembler::param_bitno, 1}, + {0xff, 0x3f, "SEZ", nullptr, 1}, + {0xf8, 0x38, "SFZ", &hp_nanoprocessor_disassembler::param_bitno, 1}, + {0xf0, 0x40, "INA", &hp_nanoprocessor_disassembler::param_ds, 1}, + {0xff, 0x5f, "NOP", nullptr, 1}, + {0xf0, 0x50, "OTA", &hp_nanoprocessor_disassembler::param_ds, 1}, + {0xf0, 0x60, "LDA", &hp_nanoprocessor_disassembler::param_reg, 1}, + {0xf0, 0x70, "STA", &hp_nanoprocessor_disassembler::param_reg, 1}, + {0xf8, 0x80, "JMP", &hp_nanoprocessor_disassembler::param_11bit, 2}, + {0xf8, 0x88, "JSB", &hp_nanoprocessor_disassembler::param_11bit, 2 | STEP_OVER}, + {0xf8, 0x90, "JAI", &hp_nanoprocessor_disassembler::param_page_no, 1}, + {0xf8, 0x98, "JAS", &hp_nanoprocessor_disassembler::param_page_no, 1 | STEP_OVER}, + {0xf8, 0xa0, "CBN", &hp_nanoprocessor_disassembler::param_bitno, 1}, + {0xff, 0xaf, "DSI", nullptr, 1}, + {0xf8, 0xa8, "CLC", &hp_nanoprocessor_disassembler::param_bitno, 1}, + {0xff, 0xb0, "RTI", nullptr, 1 | STEP_OUT}, + {0xff, 0xb1, "RTE", nullptr, 1 | STEP_OUT}, + {0xff, 0xb4, "STE", nullptr, 1}, + {0xff, 0xb5, "CLE", nullptr, 1}, + {0xff, 0xb8, "RTS", nullptr, 1 | STEP_OUT}, + {0xff, 0xb9, "RSE", nullptr, 1 | STEP_OUT}, + {0xff, 0xcf, "LDR", &hp_nanoprocessor_disassembler::param_byte, 2}, + {0xf0, 0xc0, "OTR", &hp_nanoprocessor_disassembler::param_ds_byte, 2}, + {0xf0, 0xd0, "STR", &hp_nanoprocessor_disassembler::param_reg_byte, 2}, + {0xf0, 0xe0, "LDI", &hp_nanoprocessor_disassembler::param_reg, 1}, + {0xf0, 0xf0, "STI", &hp_nanoprocessor_disassembler::param_reg, 1}, // Catchall for undefined opcodes - {0x00 , 0x00 , "???" , nullptr , 1} + {0x00, 0x00, "???", nullptr, 1} }; -CPU_DISASSEMBLE(hp_nanoprocessor) +u32 hp_nanoprocessor_disassembler::opcode_alignment() const { - const uint8_t opcode = *oprom; + return 1; +} - opram++; +offs_t hp_nanoprocessor_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + const uint8_t opcode = opcodes.r8(pc); for (const dis_entry_t& ent : dis_table) { if ((opcode & ent.m_op_mask) == ent.m_opcode) { stream << ent.m_mnemonic << ' '; if (ent.m_param_fn != nullptr) { - ent.m_param_fn(stream , opcode , opram); + (this->*ent.m_param_fn)(stream, opcode, pc+1, params); } - return ent.m_dasm_flags | DASMFLAG_SUPPORTED; + return ent.m_dasm_flags | SUPPORTED; } } // Should never ever happen diff --git a/src/devices/cpu/nanoprocessor/nanoprocessor_dasm.h b/src/devices/cpu/nanoprocessor/nanoprocessor_dasm.h new file mode 100644 index 00000000000..1287e0db605 --- /dev/null +++ b/src/devices/cpu/nanoprocessor/nanoprocessor_dasm.h @@ -0,0 +1,44 @@ +// license:BSD-3-Clause +// copyright-holders:F. Ulivi +// ******************************* +// * HP nanoprocessor disassembler +// ******************************* + +#ifndef MAME_CPU_NANOPROCESSOR_NANOPROCESSOR_DASM_H +#define MAME_CPU_NANOPROCESSOR_NANOPROCESSOR_DASM_H + +#pragma once + +class hp_nanoprocessor_disassembler : public util::disasm_interface +{ +public: + hp_nanoprocessor_disassembler() = default; + virtual ~hp_nanoprocessor_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + typedef void (hp_nanoprocessor_disassembler::*fn_dis_param)(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms); + + typedef struct { + uint8_t m_op_mask; + uint8_t m_opcode; + const char *m_mnemonic; + fn_dis_param m_param_fn; + uint32_t m_dasm_flags; + } dis_entry_t; + + void param_bitno(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms); + void param_ds(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms); + void param_reg(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms); + void param_11bit(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms); + void param_page_no(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms); + void param_byte(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms); + void param_ds_byte(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms); + void param_reg_byte(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms); + + static const dis_entry_t dis_table[]; +}; + +#endif diff --git a/src/devices/cpu/nec/nec.cpp b/src/devices/cpu/nec/nec.cpp index a4410cc12e8..c3acf3b5be3 100644 --- a/src/devices/cpu/nec/nec.cpp +++ b/src/devices/cpu/nec/nec.cpp @@ -106,6 +106,7 @@ #include "emu.h" #include "nec.h" +#include "necdasm.h" #include "debugger.h" typedef uint8_t BOOLEAN; @@ -169,10 +170,9 @@ v33a_device::v33a_device(const machine_config &mconfig, const char *tag, device_ } -offs_t nec_common_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *nec_common_device::create_disassembler() { - extern CPU_DISASSEMBLE( nec ); - return CPU_DISASSEMBLE_NAME(nec)(this, stream, pc, oprom, opram, options); + return new nec_disassembler; } @@ -223,8 +223,8 @@ uint8_t nec_common_device::fetch() uint16_t nec_common_device::fetchword() { - uint16_t r = FETCH(); - r |= (FETCH()<<8); + uint16_t r = fetch(); + r |= (fetch()<<8); return r; } @@ -419,7 +419,7 @@ void nec_common_device::device_start() save_item(NAME(m_prefetch_reset)); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); state_add( NEC_PC, "PC", m_debugger_temp).callimport().callexport().formatstr("%05X"); diff --git a/src/devices/cpu/nec/nec.h b/src/devices/cpu/nec/nec.h index 4ec9e02459d..c868b58524e 100644 --- a/src/devices/cpu/nec/nec.h +++ b/src/devices/cpu/nec/nec.h @@ -48,9 +48,7 @@ protected: virtual void state_export(const device_state_entry &entry) override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 8; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -90,7 +88,7 @@ private: uint8_t m_halted; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_io; int m_icount; diff --git a/src/devices/cpu/nec/nec_common.h b/src/devices/cpu/nec/nec_common.h deleted file mode 100644 index 4356214a302..00000000000 --- a/src/devices/cpu/nec/nec_common.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef NEC_COMMON_H -#define NEC_COMMON_H - -#include <stdint.h> - -extern int necv_dasm_one(std::ostream &stream, uint32_t eip, const uint8_t *oprom, const uint8_t *decryption_table); -extern int necv_dasm_one(char *buffer, uint32_t eip, const uint8_t *oprom, const uint8_t *decryption_table); - -#endif // NEC_COMMON_H diff --git a/src/devices/cpu/nec/necdasm.cpp b/src/devices/cpu/nec/necdasm.cpp index d313eeaf531..36f155d2527 100644 --- a/src/devices/cpu/nec/necdasm.cpp +++ b/src/devices/cpu/nec/necdasm.cpp @@ -8,82 +8,9 @@ */ #include "emu.h" -#include "nec_common.h" +#include "necdasm.h" -static const uint8_t *Iconfig; - -enum -{ - PARAM_REG8 = 1, /* 8-bit register */ - PARAM_REG16, /* 16-bit register */ - PARAM_REG2_8, /* 8-bit register */ - PARAM_REG2_16, /* 16-bit register */ - PARAM_RM8, /* 8-bit memory or register */ - PARAM_RM16, /* 16-bit memory or register */ - PARAM_RMPTR8, /* 8-bit memory or register */ - PARAM_RMPTR16, /* 16-bit memory or register */ - PARAM_I3, /* 3-bit immediate */ - PARAM_I4, /* 4-bit immediate */ - PARAM_I8, /* 8-bit signed immediate */ - PARAM_I16, /* 16-bit signed immediate */ - PARAM_UI8, /* 8-bit unsigned immediate */ - PARAM_IMM, /* 16-bit immediate */ - PARAM_ADDR, /* 16:16 address */ - PARAM_REL8, /* 8-bit PC-relative displacement */ - PARAM_REL16, /* 16-bit PC-relative displacement */ - PARAM_MEM_OFFS, /* 16-bit mem offset */ - PARAM_SREG, /* segment register */ - PARAM_SFREG, /* V25/V35 special function register */ - PARAM_1, /* used by shift/rotate instructions */ - PARAM_AL, - PARAM_CL, - PARAM_DL, - PARAM_BL, - PARAM_AH, - PARAM_CH, - PARAM_DH, - PARAM_BH, - PARAM_AW, - PARAM_CW, - PARAM_DW, - PARAM_BW, - PARAM_SP, - PARAM_BP, - PARAM_IX, - PARAM_IY -}; - -enum -{ - MODRM = 1, - GROUP, - FPU, - TWO_BYTE, - PREFIX, - SEG_PS, - SEG_DS0, - SEG_DS1, - SEG_SS -}; - -struct NEC_I386_OPCODE { - char mnemonic[32]; - uint32_t flags; - uint32_t param1; - uint32_t param2; - uint32_t param3; - offs_t dasm_flags; -}; - -struct NEC_GROUP_OP { - char mnemonic[32]; - const NEC_I386_OPCODE *opcode; -}; - -static const uint8_t *opcode_ptr; -static const uint8_t *opcode_ptr_base; - -static const NEC_I386_OPCODE necv_opcode_table1[256] = +const nec_disassembler::NEC_I386_OPCODE nec_disassembler::necv_opcode_table1[256] = { // 0x00 {"add", MODRM, PARAM_RM8, PARAM_REG8, 0 }, @@ -191,7 +118,7 @@ static const NEC_I386_OPCODE necv_opcode_table1[256] = {"push r", 0, 0, 0, 0 }, {"pop r", 0, 0, 0, 0 }, {"chkind", MODRM, PARAM_REG16, PARAM_RM16, 0 }, - {"brkn", 0, PARAM_UI8, 0, 0, DASMFLAG_STEP_OVER}, /* V25S/V35S only */ + {"brkn", 0, PARAM_UI8, 0, 0, STEP_OVER}, /* V25S/V35S only */ {"repnc", PREFIX, 0, 0, 0 }, {"repc", PREFIX, 0, 0, 0 }, {"fpo2 0", 0, 0, 0, 0 }, /* for a coprocessor that was never made */ @@ -249,7 +176,7 @@ static const NEC_I386_OPCODE necv_opcode_table1[256] = {"xch", 0, PARAM_AW, PARAM_IY, 0 }, {"cvtbw", 0, 0, 0, 0 }, {"cvtwl", 0, 0, 0, 0 }, - {"call", 0, PARAM_ADDR, 0, 0, DASMFLAG_STEP_OVER}, + {"call", 0, PARAM_ADDR, 0, 0, STEP_OVER}, {"poll", 0, 0, 0, 0 }, {"push psw", 0, 0, 0, 0 }, {"pop psw", 0, 0, 0, 0 }, @@ -292,20 +219,20 @@ static const NEC_I386_OPCODE necv_opcode_table1[256] = // 0xc0 {"shiftbi", GROUP, 0, 0, 0 }, {"shiftwi", GROUP, 0, 0, 0 }, - {"ret", 0, PARAM_I16, 0, 0, DASMFLAG_STEP_OUT}, - {"ret", 0, 0, 0, 0, DASMFLAG_STEP_OUT}, + {"ret", 0, PARAM_I16, 0, 0, STEP_OUT}, + {"ret", 0, 0, 0, 0, STEP_OUT}, {"mov ds1,", MODRM, PARAM_REG16, PARAM_RM16, 0 }, {"mov ds0,", MODRM, PARAM_REG16, PARAM_RM16, 0 }, {"mov", MODRM, PARAM_RMPTR8, PARAM_UI8, 0 }, {"mov", MODRM, PARAM_RMPTR16, PARAM_IMM, 0 }, {"prepare", 0, PARAM_I16, PARAM_UI8, 0 }, {"dispose", 0, 0, 0, 0 }, - {"retf", 0, PARAM_I16, 0, 0, DASMFLAG_STEP_OUT}, - {"retf", 0, 0, 0, 0, DASMFLAG_STEP_OUT}, - {"brk 3", 0, 0, 0, 0, DASMFLAG_STEP_OVER}, - {"brk", 0, PARAM_UI8, 0, 0, DASMFLAG_STEP_OVER}, + {"retf", 0, PARAM_I16, 0, 0, STEP_OUT}, + {"retf", 0, 0, 0, 0, STEP_OUT}, + {"brk 3", 0, 0, 0, 0, STEP_OVER}, + {"brk", 0, PARAM_UI8, 0, 0, STEP_OVER}, {"brkv", 0, 0, 0, 0 }, - {"reti", 0, 0, 0, 0, DASMFLAG_STEP_OUT}, + {"reti", 0, 0, 0, 0, STEP_OUT}, // 0xd0 {"shiftb", GROUP, 0, 0, 0 }, {"shiftw", GROUP, 0, 0, 0 }, @@ -324,15 +251,15 @@ static const NEC_I386_OPCODE necv_opcode_table1[256] = {"escape", FPU, 0, 0, 0 }, {"escape", FPU, 0, 0, 0 }, // 0xe0 - {"dbnzne", 0, PARAM_REL8, 0, 0, DASMFLAG_STEP_OVER}, - {"dbnze", 0, PARAM_REL8, 0, 0, DASMFLAG_STEP_OVER}, - {"dbnz", 0, PARAM_REL8, 0, 0, DASMFLAG_STEP_OVER}, + {"dbnzne", 0, PARAM_REL8, 0, 0, STEP_OVER}, + {"dbnze", 0, PARAM_REL8, 0, 0, STEP_OVER}, + {"dbnz", 0, PARAM_REL8, 0, 0, STEP_OVER}, {"bcwz", 0, PARAM_REL8, 0, 0 }, {"in", 0, PARAM_AL, PARAM_UI8, 0 }, {"in", 0, PARAM_AW, PARAM_UI8, 0 }, {"out", 0, PARAM_UI8, PARAM_AL, 0 }, {"out", 0, PARAM_UI8, PARAM_AW, 0 }, - {"call", 0, PARAM_REL16, 0, 0, DASMFLAG_STEP_OVER}, + {"call", 0, PARAM_REL16, 0, 0, STEP_OVER}, {"br", 0, PARAM_REL16, 0, 0 }, {"br", 0, PARAM_ADDR, 0, 0 }, {"br", 0, PARAM_REL8, 0, 0 }, @@ -342,7 +269,7 @@ static const NEC_I386_OPCODE necv_opcode_table1[256] = {"out", 0, PARAM_DW, PARAM_AW, 0 }, // 0xf0 {"buslock", PREFIX, 0, 0, 0 }, - {"brks", 0, PARAM_UI8, 0, 0, DASMFLAG_STEP_OVER}, /* V25S/V35S only */ + {"brks", 0, PARAM_UI8, 0, 0, STEP_OVER}, /* V25S/V35S only */ {"repne", PREFIX, 0, 0, 0 }, {"rep", PREFIX, 0, 0, 0 }, {"halt", 0, 0, 0, 0 }, @@ -359,7 +286,7 @@ static const NEC_I386_OPCODE necv_opcode_table1[256] = {"group2w", GROUP, 0, 0, 0 } }; -static const NEC_I386_OPCODE necv_opcode_table2[256] = +const nec_disassembler::NEC_I386_OPCODE nec_disassembler::necv_opcode_table2[256] = { // 0x00 {"???", 0, 0, 0, 0 }, @@ -409,7 +336,7 @@ static const NEC_I386_OPCODE necv_opcode_table2[256] = {"ror4", MODRM, PARAM_RMPTR8, 0, 0 }, {"???", 0, 0, 0, 0 }, {"???", 0, 0, 0, 0 }, - {"brkcs", MODRM, PARAM_REG2_16, 0, 0, DASMFLAG_STEP_OVER}, /* V25/V35 only */ + {"brkcs", MODRM, PARAM_REG2_16, 0, 0, STEP_OVER}, /* V25/V35 only */ {"???", 0, 0, 0, 0 }, {"???", 0, 0, 0, 0 }, // 0x30 @@ -635,7 +562,7 @@ static const NEC_I386_OPCODE necv_opcode_table2[256] = {"brkem", 0, PARAM_UI8, 0, 0 } /* V20,30,40,50 only */ }; -static const NEC_I386_OPCODE immb_table[8] = +const nec_disassembler::NEC_I386_OPCODE nec_disassembler::immb_table[8] = { {"add", 0, PARAM_RMPTR8, PARAM_UI8, 0 }, {"or", 0, PARAM_RMPTR8, PARAM_UI8, 0 }, @@ -647,7 +574,7 @@ static const NEC_I386_OPCODE immb_table[8] = {"cmp", 0, PARAM_RMPTR8, PARAM_UI8, 0 } }; -static const NEC_I386_OPCODE immw_table[8] = +const nec_disassembler::NEC_I386_OPCODE nec_disassembler::immw_table[8] = { {"add", 0, PARAM_RMPTR16, PARAM_IMM, 0 }, {"or", 0, PARAM_RMPTR16, PARAM_IMM, 0 }, @@ -659,7 +586,7 @@ static const NEC_I386_OPCODE immw_table[8] = {"cmp", 0, PARAM_RMPTR16, PARAM_IMM, 0 } }; -static const NEC_I386_OPCODE immws_table[8] = +const nec_disassembler::NEC_I386_OPCODE nec_disassembler::immws_table[8] = { {"add", 0, PARAM_RMPTR16, PARAM_I8, 0 }, {"or", 0, PARAM_RMPTR16, PARAM_I8, 0 }, @@ -671,7 +598,7 @@ static const NEC_I386_OPCODE immws_table[8] = {"cmp", 0, PARAM_RMPTR16, PARAM_I8, 0 } }; -static const NEC_I386_OPCODE shiftbi_table[8] = +const nec_disassembler::NEC_I386_OPCODE nec_disassembler::shiftbi_table[8] = { {"rol", 0, PARAM_RMPTR8, PARAM_I8, 0 }, {"ror", 0, PARAM_RMPTR8, PARAM_I8, 0 }, @@ -683,7 +610,7 @@ static const NEC_I386_OPCODE shiftbi_table[8] = {"shra", 0, PARAM_RMPTR8, PARAM_I8, 0 } }; -static const NEC_I386_OPCODE shiftwi_table[8] = +const nec_disassembler::NEC_I386_OPCODE nec_disassembler::shiftwi_table[8] = { {"rol", 0, PARAM_RMPTR16, PARAM_I8, 0 }, {"ror", 0, PARAM_RMPTR16, PARAM_I8, 0 }, @@ -695,7 +622,7 @@ static const NEC_I386_OPCODE shiftwi_table[8] = {"shra", 0, PARAM_RMPTR16, PARAM_I8, 0 } }; -static const NEC_I386_OPCODE shiftb_table[8] = +const nec_disassembler::NEC_I386_OPCODE nec_disassembler::shiftb_table[8] = { {"rol", 0, PARAM_RMPTR8, PARAM_1, 0 }, {"ror", 0, PARAM_RMPTR8, PARAM_1, 0 }, @@ -707,7 +634,7 @@ static const NEC_I386_OPCODE shiftb_table[8] = {"shra", 0, PARAM_RMPTR8, PARAM_1, 0 } }; -static const NEC_I386_OPCODE shiftw_table[8] = +const nec_disassembler::NEC_I386_OPCODE nec_disassembler::shiftw_table[8] = { {"rol", 0, PARAM_RMPTR16, PARAM_1, 0 }, {"ror", 0, PARAM_RMPTR16, PARAM_1, 0 }, @@ -719,7 +646,7 @@ static const NEC_I386_OPCODE shiftw_table[8] = {"shra", 0, PARAM_RMPTR16, PARAM_1, 0 } }; -static const NEC_I386_OPCODE shiftbv_table[8] = +const nec_disassembler::NEC_I386_OPCODE nec_disassembler::shiftbv_table[8] = { {"rol", 0, PARAM_RMPTR8, PARAM_CL, 0 }, {"ror", 0, PARAM_RMPTR8, PARAM_CL, 0 }, @@ -731,7 +658,7 @@ static const NEC_I386_OPCODE shiftbv_table[8] = {"shra", 0, PARAM_RMPTR8, PARAM_CL, 0 } }; -static const NEC_I386_OPCODE shiftwv_table[8] = +const nec_disassembler::NEC_I386_OPCODE nec_disassembler::shiftwv_table[8] = { {"rol", 0, PARAM_RMPTR16, PARAM_CL, 0 }, {"ror", 0, PARAM_RMPTR16, PARAM_CL, 0 }, @@ -743,7 +670,7 @@ static const NEC_I386_OPCODE shiftwv_table[8] = {"shra", 0, PARAM_RMPTR16, PARAM_CL, 0 } }; -static const NEC_I386_OPCODE group1b_table[8] = +const nec_disassembler::NEC_I386_OPCODE nec_disassembler::group1b_table[8] = { {"test", 0, PARAM_RMPTR8, PARAM_UI8, 0 }, {"???", 0, 0, 0, 0 }, @@ -755,7 +682,7 @@ static const NEC_I386_OPCODE group1b_table[8] = {"div", 0, PARAM_RMPTR8, 0, 0 } }; -static const NEC_I386_OPCODE group1w_table[8] = +const nec_disassembler::NEC_I386_OPCODE nec_disassembler::group1w_table[8] = { {"test", 0, PARAM_RMPTR16, PARAM_IMM, 0 }, {"???", 0, 0, 0, 0 }, @@ -767,7 +694,7 @@ static const NEC_I386_OPCODE group1w_table[8] = {"div", 0, PARAM_RMPTR16, 0, 0 } }; -static const NEC_I386_OPCODE group2b_table[8] = +const nec_disassembler::NEC_I386_OPCODE nec_disassembler::group2b_table[8] = { {"inc", 0, PARAM_RMPTR8, 0, 0 }, {"dec", 0, PARAM_RMPTR8, 0, 0 }, @@ -779,19 +706,19 @@ static const NEC_I386_OPCODE group2b_table[8] = {"???", 0, 0, 0, 0 } }; -static const NEC_I386_OPCODE group2w_table[8] = +const nec_disassembler::NEC_I386_OPCODE nec_disassembler::group2w_table[8] = { {"inc", 0, PARAM_RMPTR16, 0, 0 }, {"dec", 0, PARAM_RMPTR16, 0, 0 }, - {"call", 0, PARAM_RMPTR16, 0, 0, DASMFLAG_STEP_OVER}, - {"call far ptr ",0, PARAM_RM16, 0, 0, DASMFLAG_STEP_OVER}, + {"call", 0, PARAM_RMPTR16, 0, 0, STEP_OVER}, + {"call far ptr ",0, PARAM_RM16, 0, 0, STEP_OVER}, {"br", 0, PARAM_RMPTR16, 0, 0 }, {"br far ptr ",0, PARAM_RM16, 0, 0 }, {"push", 0, PARAM_RMPTR16, 0, 0 }, {"???", 0, 0, 0, 0 } }; -static const NEC_GROUP_OP group_op_table[] = +const nec_disassembler::NEC_GROUP_OP nec_disassembler::group_op_table[] = { { "immb", immb_table }, { "immw", immw_table }, @@ -810,10 +737,10 @@ static const NEC_GROUP_OP group_op_table[] = -static const char *const nec_reg[8] = { "aw", "cw", "dw", "bw", "sp", "bp", "ix", "iy" }; -static const char *const nec_reg8[8] = { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh" }; -static const char *const nec_sreg[8] = { "ds1", "ps", "ss", "ds0", "???", "???", "???", "???" }; -static const char *const nec_sfreg[256] = +const char *const nec_disassembler::nec_reg[8] = { "aw", "cw", "dw", "bw", "sp", "bp", "ix", "iy" }; +const char *const nec_disassembler::nec_reg8[8] = { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh" }; +const char *const nec_disassembler::nec_sreg[8] = { "ds1", "ps", "ss", "ds0", "???", "???", "???", "???" }; +const char *const nec_disassembler::nec_sfreg[256] = { /* 0x00 */ "p0", "pm0", "pmc0", "???", "???", "???", "???", "???", @@ -865,130 +792,88 @@ static const char *const nec_sfreg[256] = "???", "???", "???", "???", "ispr", "???", "???", "idb" }; -static uint32_t pc; -static uint8_t modrm; -static uint32_t segment; -static offs_t dasm_flags; -static char modrm_string[256]; - -#define MODRM_REG1 ((modrm >> 3) & 0x7) -#define MODRM_REG2 (modrm & 0x7) +#define MODRM_REG1 ((m_modrm >> 3) & 0x7) +#define MODRM_REG2 (m_modrm & 0x7) #define MAX_LENGTH 8 -static inline uint8_t FETCH(void) +uint8_t nec_disassembler::FETCH(offs_t pc_base, offs_t &pc, const data_buffer &opcodes) { - if ((opcode_ptr - opcode_ptr_base) + 1 > MAX_LENGTH) + if ((pc - pc_base) + 1 > MAX_LENGTH) return 0xff; + u8 r = opcodes.r8(pc); pc++; - return *opcode_ptr++; -} - -#if 0 -static inline uint16_t FETCH16(void) -{ - uint16_t d; - if ((opcode_ptr - opcode_ptr_base) + 2 > MAX_LENGTH) - return 0xffff; - d = opcode_ptr[0] | (opcode_ptr[1] << 8); - opcode_ptr += 2; - pc += 2; - return d; + return r; } -#endif -static inline uint8_t FETCHD(void) +uint16_t nec_disassembler::FETCH16(offs_t pc_base, offs_t &pc, const data_buffer &opcodes) { - if ((opcode_ptr - opcode_ptr_base) + 1 > MAX_LENGTH) + if ((pc - pc_base) + 1 > MAX_LENGTH) return 0xff; - pc++; - return *opcode_ptr++; -} - -static inline uint16_t FETCHD16(void) -{ - uint16_t d; - if ((opcode_ptr - opcode_ptr_base) + 2 > MAX_LENGTH) - return 0xffff; - d = opcode_ptr[0] | (opcode_ptr[1] << 8); - opcode_ptr += 2; + u16 r = opcodes.r16(pc); pc += 2; - return d; + return r; } -static char *hexstring(uint32_t value, int digits) +std::string nec_disassembler::hexstring(uint32_t value, int digits) { - static char buffer[20]; - buffer[0] = '0'; + std::string buffer; if (digits) - sprintf(&buffer[1], "%0*Xh", digits, value); + buffer = string_format("%0*Xh", digits, value); else - sprintf(&buffer[1], "%Xh", value); - return (buffer[1] >= '0' && buffer[1] <= '9') ? &buffer[1] : &buffer[0]; + buffer = string_format("%Xh", value); + return buffer[0] > '9' ? '0' + buffer : buffer; } -static char *shexstring(uint32_t value, int digits, bool always) +std::string nec_disassembler::shexstring(uint32_t value, int digits, bool always) { - static char buffer[20]; if (value >= 0x80000000) - sprintf(buffer, "-%s", hexstring(-value, digits)); + return '-' + hexstring(-value, digits); else if (always) - sprintf(buffer, "+%s", hexstring(value, digits)); + return '+' + hexstring(value, digits); else return hexstring(value, digits); - return buffer; } -static void handle_modrm(char* s) +void nec_disassembler::handle_modrm(offs_t pc_base, offs_t &pc, const data_buffer ¶ms) { - int8_t disp8; - int16_t disp16; - uint8_t mod, rm; + m_modrm_string = ""; - modrm = FETCHD(); - mod = (modrm >> 6) & 0x3; - rm = (modrm & 0x7); + m_modrm = FETCH(pc_base, pc, params); + u8 mod = (m_modrm >> 6) & 0x3; + u8 rm = (m_modrm & 0x7); - if( modrm >= 0xc0 ) + if( m_modrm >= 0xc0 ) return; - switch(segment) + switch(m_segment) { - case SEG_PS: s += sprintf( s, "ps:" ); break; - case SEG_DS0: s += sprintf( s, "ds0:" ); break; - case SEG_DS1: s += sprintf( s, "ds1:" ); break; - case SEG_SS: s += sprintf( s, "ss:" ); break; + case SEG_PS: m_modrm_string += "ps:"; break; + case SEG_DS0: m_modrm_string += "ds0:"; break; + case SEG_DS1: m_modrm_string += "ds1:"; break; + case SEG_SS: m_modrm_string += "ss:"; break; } - s += sprintf( s, "[" ); + m_modrm_string += '['; switch( rm ) { - case 0: s += sprintf( s, "bw+ix" ); break; - case 1: s += sprintf( s, "bw+iy" ); break; - case 2: s += sprintf( s, "bp+ix" ); break; - case 3: s += sprintf( s, "bp+iy" ); break; - case 4: s += sprintf( s, "ix" ); break; - case 5: s += sprintf( s, "iy" ); break; - case 6: - if( mod == 0 ) { - disp16 = FETCHD16(); - s += sprintf( s, "%s", hexstring((unsigned) (uint16_t) disp16, 0) ); - } else { - s += sprintf( s, "bp" ); - } - break; - case 7: s += sprintf( s, "bw" ); break; - } - if( mod == 1 ) { - disp8 = FETCHD(); - s += sprintf( s, "%s", shexstring((int32_t)disp8, 0, true) ); - } else if( mod == 2 ) { - disp16 = FETCHD16(); - s += sprintf( s, "%s", shexstring((int32_t)disp16, 0, true) ); + case 0: m_modrm_string += "bw+ix"; break; + case 1: m_modrm_string += "bw+iy"; break; + case 2: m_modrm_string += "bp+ix"; break; + case 3: m_modrm_string += "bp+iy"; break; + case 4: m_modrm_string += "ix"; break; + case 5: m_modrm_string += "iy"; break; + case 6: m_modrm_string += mod == 0 ? hexstring(u16(FETCH16(pc_base, pc, params)), 0) : "bp"; break; + case 7: m_modrm_string += "bw"; break; } - s += sprintf( s, "]" );} + if( mod == 1 ) + m_modrm_string += shexstring(s8(FETCH(pc_base, pc, params)), 0, true); + else if( mod == 2 ) + m_modrm_string += shexstring(s16(FETCH16(pc_base, pc, params)), 0, true); + m_modrm_string += ']'; +} -static void handle_param(std::ostream &stream, uint32_t param) +void nec_disassembler::handle_param(std::ostream &stream, uint32_t param, offs_t pc_base, offs_t &pc, const data_buffer ¶ms) { uint8_t i8; uint16_t i16; @@ -1017,76 +902,76 @@ static void handle_param(std::ostream &stream, uint32_t param) case PARAM_RM8: case PARAM_RMPTR8: - if( modrm >= 0xc0 ) { + if( m_modrm >= 0xc0 ) { util::stream_format( stream, "%s", nec_reg8[MODRM_REG2] ); } else { if (param == PARAM_RMPTR8) util::stream_format( stream, "byte ptr " ); - util::stream_format( stream, "%s", modrm_string ); + util::stream_format( stream, "%s", m_modrm_string ); } break; case PARAM_RM16: case PARAM_RMPTR16: - if( modrm >= 0xc0 ) { + if( m_modrm >= 0xc0 ) { util::stream_format( stream, "%s", nec_reg[MODRM_REG2] ); } else { if (param == PARAM_RMPTR16) util::stream_format( stream, "word ptr " ); - util::stream_format( stream, "%s", modrm_string ); + util::stream_format( stream, "%s", m_modrm_string ); } break; case PARAM_I3: - i8 = FETCHD(); + i8 = FETCH(pc_base, pc, params); util::stream_format( stream, "%d", i8 & 0x07 ); break; case PARAM_I4: - i8 = FETCHD(); + i8 = FETCH(pc_base, pc, params); util::stream_format( stream, "%d", i8 & 0x0f ); break; case PARAM_I8: - i8 = FETCHD(); + i8 = FETCH(pc_base, pc, params); util::stream_format( stream, "%s", shexstring((int8_t)i8, 0, false) ); break; case PARAM_I16: - i16 = FETCHD16(); + i16 = FETCH16(pc_base, pc, params); util::stream_format( stream, "%s", shexstring((int16_t)i16, 0, false) ); break; case PARAM_UI8: - i8 = FETCHD(); + i8 = FETCH(pc_base, pc, params); util::stream_format( stream, "%s", shexstring((uint8_t)i8, 0, false) ); break; case PARAM_IMM: - i16 = FETCHD16(); + i16 = FETCH16(pc_base, pc, params); util::stream_format( stream, "%s", hexstring(i16, 0) ); break; case PARAM_ADDR: - addr = FETCHD16(); - ptr = FETCHD16(); + addr = FETCH16(pc_base, pc, params); + ptr = FETCH16(pc_base, pc, params); util::stream_format( stream, "%s:", hexstring(ptr, 4) ); util::stream_format( stream, "%s", hexstring(addr, 0) ); break; case PARAM_REL16: /* make sure to keep the relative offset within the segment */ - d16 = FETCHD16(); + d16 = FETCH16(pc_base, pc, params); util::stream_format( stream, "%s", hexstring((pc & 0xFFFF0000) | ((pc + d16) & 0x0000FFFF), 0) ); break; case PARAM_REL8: - d8 = FETCHD(); + d8 = FETCH(pc_base, pc, params); util::stream_format( stream, "%s", hexstring(pc + d8, 0) ); break; case PARAM_MEM_OFFS: - switch(segment) + switch(m_segment) { case SEG_PS: util::stream_format( stream, "ps:" ); break; case SEG_DS0: util::stream_format( stream, "ds0:" ); break; @@ -1094,7 +979,7 @@ static void handle_param(std::ostream &stream, uint32_t param) case SEG_SS: util::stream_format( stream, "ss:" ); break; } - i16 = FETCHD16(); + i16 = FETCH16(pc_base, pc, params); util::stream_format( stream, "[%s]", hexstring(i16, 0) ); break; @@ -1103,7 +988,7 @@ static void handle_param(std::ostream &stream, uint32_t param) break; case PARAM_SFREG: - i8 = FETCHD(); + i8 = FETCH(pc_base, pc, params); util::stream_format( stream, "%s", nec_sfreg[i8] ); break; @@ -1131,7 +1016,7 @@ static void handle_param(std::ostream &stream, uint32_t param) } } -static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) +void nec_disassembler::handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2, offs_t pc_base, offs_t &pc, const data_buffer ¶ms) { switch (op1 & 0x7) { @@ -1140,18 +1025,17 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) if (op2 < 0xc0) { pc--; // adjust fetch pointer, so modrm byte read again - opcode_ptr--; - handle_modrm( modrm_string ); + handle_modrm( pc_base, pc, params ); switch ((op2 >> 3) & 0x7) { - case 0: util::stream_format(stream, "fadd dword ptr %s", modrm_string); break; - case 1: util::stream_format(stream, "fmul dword ptr %s", modrm_string); break; - case 2: util::stream_format(stream, "fcom dword ptr %s", modrm_string); break; - case 3: util::stream_format(stream, "fcomp dword ptr %s", modrm_string); break; - case 4: util::stream_format(stream, "fsub dword ptr %s", modrm_string); break; - case 5: util::stream_format(stream, "fsubr dword ptr %s", modrm_string); break; - case 6: util::stream_format(stream, "fdiv dword ptr %s", modrm_string); break; - case 7: util::stream_format(stream, "fdivr dword ptr %s", modrm_string); break; + case 0: util::stream_format(stream, "fadd dword ptr %s", m_modrm_string); break; + case 1: util::stream_format(stream, "fmul dword ptr %s", m_modrm_string); break; + case 2: util::stream_format(stream, "fcom dword ptr %s", m_modrm_string); break; + case 3: util::stream_format(stream, "fcomp dword ptr %s", m_modrm_string); break; + case 4: util::stream_format(stream, "fsub dword ptr %s", m_modrm_string); break; + case 5: util::stream_format(stream, "fsubr dword ptr %s", m_modrm_string); break; + case 6: util::stream_format(stream, "fdiv dword ptr %s", m_modrm_string); break; + case 7: util::stream_format(stream, "fdivr dword ptr %s", m_modrm_string); break; } } else @@ -1176,18 +1060,17 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) if (op2 < 0xc0) { pc--; // adjust fetch pointer, so modrm byte read again - opcode_ptr--; - handle_modrm( modrm_string ); + handle_modrm( pc_base, pc, params ); switch ((op2 >> 3) & 0x7) { - case 0: util::stream_format(stream, "fld dword ptr %s", modrm_string); break; + case 0: util::stream_format(stream, "fld dword ptr %s", m_modrm_string); break; case 1: util::stream_format(stream, "??? (FPU)"); break; - case 2: util::stream_format(stream, "fst dword ptr %s", modrm_string); break; - case 3: util::stream_format(stream, "fstp dword ptr %s", modrm_string); break; - case 4: util::stream_format(stream, "fldenv word ptr %s", modrm_string); break; - case 5: util::stream_format(stream, "fldcw word ptr %s", modrm_string); break; - case 6: util::stream_format(stream, "fstenv word ptr %s", modrm_string); break; - case 7: util::stream_format(stream, "fstcw word ptr %s", modrm_string); break; + case 2: util::stream_format(stream, "fst dword ptr %s", m_modrm_string); break; + case 3: util::stream_format(stream, "fstp dword ptr %s", m_modrm_string); break; + case 4: util::stream_format(stream, "fldenv word ptr %s", m_modrm_string); break; + case 5: util::stream_format(stream, "fldcw word ptr %s", m_modrm_string); break; + case 6: util::stream_format(stream, "fstenv word ptr %s", m_modrm_string); break; + case 7: util::stream_format(stream, "fstcw word ptr %s", m_modrm_string); break; } } else @@ -1240,18 +1123,17 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) if (op2 < 0xc0) { pc--; // adjust fetch pointer, so modrm byte read again - opcode_ptr--; - handle_modrm( modrm_string ); + handle_modrm( pc_base, pc, params ); switch ((op2 >> 3) & 0x7) { - case 0: util::stream_format(stream, "fiadd dword ptr %s", modrm_string); break; - case 1: util::stream_format(stream, "fimul dword ptr %s", modrm_string); break; - case 2: util::stream_format(stream, "ficom dword ptr %s", modrm_string); break; - case 3: util::stream_format(stream, "ficomp dword ptr %s", modrm_string); break; - case 4: util::stream_format(stream, "fisub dword ptr %s", modrm_string); break; - case 5: util::stream_format(stream, "fisubr dword ptr %s", modrm_string); break; - case 6: util::stream_format(stream, "fidiv dword ptr %s", modrm_string); break; - case 7: util::stream_format(stream, "fidivr dword ptr %s", modrm_string); break; + case 0: util::stream_format(stream, "fiadd dword ptr %s", m_modrm_string); break; + case 1: util::stream_format(stream, "fimul dword ptr %s", m_modrm_string); break; + case 2: util::stream_format(stream, "ficom dword ptr %s", m_modrm_string); break; + case 3: util::stream_format(stream, "ficomp dword ptr %s", m_modrm_string); break; + case 4: util::stream_format(stream, "fisub dword ptr %s", m_modrm_string); break; + case 5: util::stream_format(stream, "fisubr dword ptr %s", m_modrm_string); break; + case 6: util::stream_format(stream, "fidiv dword ptr %s", m_modrm_string); break; + case 7: util::stream_format(stream, "fidivr dword ptr %s", m_modrm_string); break; } } else @@ -1282,18 +1164,17 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) if (op2 < 0xc0) { pc--; // adjust fetch pointer, so modrm byte read again - opcode_ptr--; - handle_modrm( modrm_string ); + handle_modrm( pc_base, pc, params ); switch ((op2 >> 3) & 0x7) { - case 0: util::stream_format(stream, "fild dword ptr %s", modrm_string); break; + case 0: util::stream_format(stream, "fild dword ptr %s", m_modrm_string); break; case 1: util::stream_format(stream, "??? (FPU)"); break; - case 2: util::stream_format(stream, "fist dword ptr %s", modrm_string); break; - case 3: util::stream_format(stream, "fistp dword ptr %s", modrm_string); break; + case 2: util::stream_format(stream, "fist dword ptr %s", m_modrm_string); break; + case 3: util::stream_format(stream, "fistp dword ptr %s", m_modrm_string); break; case 4: util::stream_format(stream, "??? (FPU)"); break; - case 5: util::stream_format(stream, "fld tword ptr %s", modrm_string); break; + case 5: util::stream_format(stream, "fld tword ptr %s", m_modrm_string); break; case 6: util::stream_format(stream, "??? (FPU)"); break; - case 7: util::stream_format(stream, "fstp tword ptr %s", modrm_string); break; + case 7: util::stream_format(stream, "fstp tword ptr %s", m_modrm_string); break; } } else @@ -1332,18 +1213,17 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) if (op2 < 0xc0) { pc--; // adjust fetch pointer, so modrm byte read again - opcode_ptr--; - handle_modrm( modrm_string ); + handle_modrm( pc_base, pc, params ); switch ((op2 >> 3) & 0x7) { - case 0: util::stream_format(stream, "fadd qword ptr %s", modrm_string); break; - case 1: util::stream_format(stream, "fmul qword ptr %s", modrm_string); break; - case 2: util::stream_format(stream, "fcom qword ptr %s", modrm_string); break; - case 3: util::stream_format(stream, "fcomp qword ptr %s", modrm_string); break; - case 4: util::stream_format(stream, "fsub qword ptr %s", modrm_string); break; - case 5: util::stream_format(stream, "fsubr qword ptr %s", modrm_string); break; - case 6: util::stream_format(stream, "fdiv qword ptr %s", modrm_string); break; - case 7: util::stream_format(stream, "fdivr qword ptr %s", modrm_string); break; + case 0: util::stream_format(stream, "fadd qword ptr %s", m_modrm_string); break; + case 1: util::stream_format(stream, "fmul qword ptr %s", m_modrm_string); break; + case 2: util::stream_format(stream, "fcom qword ptr %s", m_modrm_string); break; + case 3: util::stream_format(stream, "fcomp qword ptr %s", m_modrm_string); break; + case 4: util::stream_format(stream, "fsub qword ptr %s", m_modrm_string); break; + case 5: util::stream_format(stream, "fsubr qword ptr %s", m_modrm_string); break; + case 6: util::stream_format(stream, "fdiv qword ptr %s", m_modrm_string); break; + case 7: util::stream_format(stream, "fdivr qword ptr %s", m_modrm_string); break; } } else @@ -1379,18 +1259,17 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) if (op2 < 0xc0) { pc--; // adjust fetch pointer, so modrm byte read again - opcode_ptr--; - handle_modrm( modrm_string ); + handle_modrm( pc_base, pc, params ); switch ((op2 >> 3) & 0x7) { - case 0: util::stream_format(stream, "fld qword ptr %s", modrm_string); break; + case 0: util::stream_format(stream, "fld qword ptr %s", m_modrm_string); break; case 1: util::stream_format(stream, "??? (FPU)"); break; - case 2: util::stream_format(stream, "fst qword ptr %s", modrm_string); break; - case 3: util::stream_format(stream, "fstp qword ptr %s", modrm_string); break; - case 4: util::stream_format(stream, "frstor %s", modrm_string); break; + case 2: util::stream_format(stream, "fst qword ptr %s", m_modrm_string); break; + case 3: util::stream_format(stream, "fstp qword ptr %s", m_modrm_string); break; + case 4: util::stream_format(stream, "frstor %s", m_modrm_string); break; case 5: util::stream_format(stream, "??? (FPU)"); break; - case 6: util::stream_format(stream, "fsave %s", modrm_string); break; - case 7: util::stream_format(stream, "fstsw word ptr %s", modrm_string); break; + case 6: util::stream_format(stream, "fsave %s", m_modrm_string); break; + case 7: util::stream_format(stream, "fstsw word ptr %s", m_modrm_string); break; } } else @@ -1423,18 +1302,17 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) if (op2 < 0xc0) { pc--; // adjust fetch pointer, so modrm byte read again - opcode_ptr--; - handle_modrm( modrm_string ); + handle_modrm( pc_base, pc, params ); switch ((op2 >> 3) & 0x7) { - case 0: util::stream_format(stream, "fiadd word ptr %s", modrm_string); break; - case 1: util::stream_format(stream, "fimul word ptr %s", modrm_string); break; - case 2: util::stream_format(stream, "ficom word ptr %s", modrm_string); break; - case 3: util::stream_format(stream, "ficomp word ptr %s", modrm_string); break; - case 4: util::stream_format(stream, "fisub word ptr %s", modrm_string); break; - case 5: util::stream_format(stream, "fisubr word ptr %s", modrm_string); break; - case 6: util::stream_format(stream, "fidiv word ptr %s", modrm_string); break; - case 7: util::stream_format(stream, "fidivr word ptr %s", modrm_string); break; + case 0: util::stream_format(stream, "fiadd word ptr %s", m_modrm_string); break; + case 1: util::stream_format(stream, "fimul word ptr %s", m_modrm_string); break; + case 2: util::stream_format(stream, "ficom word ptr %s", m_modrm_string); break; + case 3: util::stream_format(stream, "ficomp word ptr %s", m_modrm_string); break; + case 4: util::stream_format(stream, "fisub word ptr %s", m_modrm_string); break; + case 5: util::stream_format(stream, "fisubr word ptr %s", m_modrm_string); break; + case 6: util::stream_format(stream, "fidiv word ptr %s", m_modrm_string); break; + case 7: util::stream_format(stream, "fidivr word ptr %s", m_modrm_string); break; } } else @@ -1472,18 +1350,17 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) if (op2 < 0xc0) { pc--; // adjust fetch pointer, so modrm byte read again - opcode_ptr--; - handle_modrm( modrm_string ); + handle_modrm( pc_base, pc, params ); switch ((op2 >> 3) & 0x7) { - case 0: util::stream_format(stream, "fild word ptr %s", modrm_string); break; + case 0: util::stream_format(stream, "fild word ptr %s", m_modrm_string); break; case 1: util::stream_format(stream, "??? (FPU)"); break; - case 2: util::stream_format(stream, "fist word ptr %s", modrm_string); break; - case 3: util::stream_format(stream, "fistp word ptr %s", modrm_string); break; - case 4: util::stream_format(stream, "fbld %s", modrm_string); break; - case 5: util::stream_format(stream, "fild qword ptr %s", modrm_string); break; - case 6: util::stream_format(stream, "fbstp %s", modrm_string); break; - case 7: util::stream_format(stream, "fistp qword ptr %s", modrm_string); break; + case 2: util::stream_format(stream, "fist word ptr %s", m_modrm_string); break; + case 3: util::stream_format(stream, "fistp word ptr %s", m_modrm_string); break; + case 4: util::stream_format(stream, "fbld %s", m_modrm_string); break; + case 5: util::stream_format(stream, "fild qword ptr %s", m_modrm_string); break; + case 6: util::stream_format(stream, "fbstp %s", m_modrm_string); break; + case 7: util::stream_format(stream, "fistp qword ptr %s", m_modrm_string); break; } } else @@ -1506,7 +1383,7 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) } } -static void decode_opcode(std::ostream &stream, const NEC_I386_OPCODE *op, uint8_t op1 ) +void nec_disassembler::decode_opcode(std::ostream &stream, const NEC_I386_OPCODE *op, uint8_t op1, offs_t pc_base, offs_t &pc, const data_buffer &opcodes, const data_buffer ¶ms) { int i; uint8_t op2; @@ -1514,63 +1391,63 @@ static void decode_opcode(std::ostream &stream, const NEC_I386_OPCODE *op, uint8 switch( op->flags ) { case TWO_BYTE: - op2 = FETCHD(); - decode_opcode( stream, &necv_opcode_table2[op2], op1 ); + op2 = FETCH(pc_base, pc, params); + decode_opcode( stream, &necv_opcode_table2[op2], op1, pc_base, pc, opcodes, params ); return; case SEG_PS: case SEG_DS0: case SEG_DS1: case SEG_SS: - segment = op->flags; - op2 = FETCH(); - if (Iconfig) op2 = Iconfig[op2]; - decode_opcode( stream, &necv_opcode_table1[op2], op1 ); + m_segment = op->flags; + op2 = FETCH(pc_base, pc, opcodes); + if (m_decryption_table) op2 = m_decryption_table[op2]; + decode_opcode( stream, &necv_opcode_table1[op2], op1, pc_base, pc, opcodes, params ); return; case PREFIX: util::stream_format( stream, "%-8s", op->mnemonic ); - op2 = FETCH(); - if (Iconfig) op2 = Iconfig[op2]; - decode_opcode( stream, &necv_opcode_table1[op2], op1 ); + op2 = FETCH(pc_base, pc, opcodes); + if (m_decryption_table) op2 = m_decryption_table[op2]; + decode_opcode( stream, &necv_opcode_table1[op2], op1, pc_base, pc, opcodes, params ); return; case GROUP: - handle_modrm( modrm_string ); + handle_modrm( pc_base, pc, params ); for( i=0; i < ARRAY_LENGTH(group_op_table); i++ ) { if( strcmp(op->mnemonic, group_op_table[i].mnemonic) == 0 ) { - decode_opcode( stream, &group_op_table[i].opcode[MODRM_REG1], op1 ); + decode_opcode( stream, &group_op_table[i].opcode[MODRM_REG1], op1, pc_base, pc, opcodes, params ); return; } } goto handle_unknown; case FPU: - op2 = FETCHD(); - handle_fpu( stream, op1, op2); + op2 = FETCH(pc_base, pc, params); + handle_fpu( stream, op1, op2, pc_base, pc, params); return; case MODRM: - handle_modrm( modrm_string ); + handle_modrm( pc_base, pc, params ); break; } util::stream_format( stream, "%-8s", op->mnemonic ); - dasm_flags = op->dasm_flags; + m_dasm_flags = op->dasm_flags; if( op->param1 != 0 ) { - handle_param(stream, op->param1); + handle_param(stream, op->param1, pc_base, pc, params); } if( op->param2 != 0 ) { util::stream_format( stream, "," ); - handle_param(stream, op->param2); + handle_param(stream, op->param2, pc_base, pc, params); } if( op->param3 != 0 ) { util::stream_format( stream, "," ); - handle_param(stream, op->param3); + handle_param(stream, op->param3, pc_base, pc, params); } return; @@ -1578,25 +1455,29 @@ handle_unknown: util::stream_format(stream, "???"); } -int necv_dasm_one(std::ostream &stream, uint32_t eip, const uint8_t *oprom, const uint8_t *decryption_table) +offs_t nec_disassembler::disassemble(std::ostream &stream, offs_t eip, const data_buffer &opcodes, const data_buffer ¶ms) { uint8_t op; - Iconfig = decryption_table; - opcode_ptr = opcode_ptr_base = oprom; - pc = eip; - dasm_flags = 0; - segment = 0; + offs_t pc = eip; + m_dasm_flags = 0; + m_segment = 0; - op = FETCH(); + op = FETCH(eip, pc, opcodes); - if (Iconfig) op = Iconfig[op]; + if (m_decryption_table) + op = m_decryption_table[op]; - decode_opcode( stream, &necv_opcode_table1[op], op ); - return (pc-eip) | dasm_flags | DASMFLAG_SUPPORTED; + decode_opcode( stream, &necv_opcode_table1[op], op, eip, pc, opcodes, params ); + return (pc-eip) | m_dasm_flags | SUPPORTED; } -CPU_DISASSEMBLE( nec ) +nec_disassembler::nec_disassembler(const u8 *decryption_table) : m_decryption_table(decryption_table) { - return necv_dasm_one(stream, pc, oprom, nullptr); } + +u32 nec_disassembler::opcode_alignment() const +{ + return 1; +} + diff --git a/src/devices/cpu/nec/necdasm.h b/src/devices/cpu/nec/necdasm.h new file mode 100644 index 00000000000..9b243ffe66f --- /dev/null +++ b/src/devices/cpu/nec/necdasm.h @@ -0,0 +1,129 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert + +// NEC disassembler interface + +#ifndef MAME_CPU_NEC_NECDASM_H +#define MAME_CPU_NEC_NECDASM_H + +#pragma once + +class nec_disassembler : public util::disasm_interface +{ +public: + nec_disassembler(const u8 *decryption_table = nullptr); + virtual ~nec_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum + { + PARAM_REG8 = 1, /* 8-bit register */ + PARAM_REG16, /* 16-bit register */ + PARAM_REG2_8, /* 8-bit register */ + PARAM_REG2_16, /* 16-bit register */ + PARAM_RM8, /* 8-bit memory or register */ + PARAM_RM16, /* 16-bit memory or register */ + PARAM_RMPTR8, /* 8-bit memory or register */ + PARAM_RMPTR16, /* 16-bit memory or register */ + PARAM_I3, /* 3-bit immediate */ + PARAM_I4, /* 4-bit immediate */ + PARAM_I8, /* 8-bit signed immediate */ + PARAM_I16, /* 16-bit signed immediate */ + PARAM_UI8, /* 8-bit unsigned immediate */ + PARAM_IMM, /* 16-bit immediate */ + PARAM_ADDR, /* 16:16 address */ + PARAM_REL8, /* 8-bit PC-relative displacement */ + PARAM_REL16, /* 16-bit PC-relative displacement */ + PARAM_MEM_OFFS, /* 16-bit mem offset */ + PARAM_SREG, /* segment register */ + PARAM_SFREG, /* V25/V35 special function register */ + PARAM_1, /* used by shift/rotate instructions */ + PARAM_AL, + PARAM_CL, + PARAM_DL, + PARAM_BL, + PARAM_AH, + PARAM_CH, + PARAM_DH, + PARAM_BH, + PARAM_AW, + PARAM_CW, + PARAM_DW, + PARAM_BW, + PARAM_SP, + PARAM_BP, + PARAM_IX, + PARAM_IY + }; + + enum + { + MODRM = 1, + GROUP, + FPU, + TWO_BYTE, + PREFIX, + SEG_PS, + SEG_DS0, + SEG_DS1, + SEG_SS + }; + + struct NEC_I386_OPCODE { + char mnemonic[32]; + uint32_t flags; + uint32_t param1; + uint32_t param2; + uint32_t param3; + offs_t dasm_flags; + }; + + struct NEC_GROUP_OP { + char mnemonic[32]; + const NEC_I386_OPCODE *opcode; + }; + + static const NEC_I386_OPCODE necv_opcode_table1[256]; + static const NEC_I386_OPCODE necv_opcode_table2[256]; + static const NEC_I386_OPCODE immb_table[8]; + static const NEC_I386_OPCODE immw_table[8]; + static const NEC_I386_OPCODE immws_table[8]; + static const NEC_I386_OPCODE shiftbi_table[8]; + static const NEC_I386_OPCODE shiftwi_table[8]; + static const NEC_I386_OPCODE shiftb_table[8]; + static const NEC_I386_OPCODE shiftw_table[8]; + static const NEC_I386_OPCODE shiftbv_table[8]; + static const NEC_I386_OPCODE shiftwv_table[8]; + static const NEC_I386_OPCODE group1b_table[8]; + static const NEC_I386_OPCODE group1w_table[8]; + static const NEC_I386_OPCODE group2b_table[8]; + static const NEC_I386_OPCODE group2w_table[8]; + static const NEC_GROUP_OP group_op_table[]; + static const char *const nec_reg[8]; + static const char *const nec_reg8[8]; + static const char *const nec_sreg[8]; + static const char *const nec_sfreg[256]; + + const u8 *m_decryption_table; + + u8 m_modrm; + u32 m_segment; + offs_t m_dasm_flags; + std::string m_modrm_string; + + inline u8 FETCH(offs_t pc_base, offs_t &pc, const data_buffer &opcodes); + inline u16 FETCH16(offs_t pc_base, offs_t &pc, const data_buffer &opcodes); + std::string hexstring(uint32_t value, int digits); + std::string shexstring(uint32_t value, int digits, bool always); + void handle_modrm(offs_t pc_base, offs_t &pc, const data_buffer ¶ms); + void handle_param(std::ostream &stream, uint32_t param, offs_t pc_base, offs_t &pc, const data_buffer ¶ms); + void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2, offs_t pc_base, offs_t &pc, const data_buffer ¶ms); + + void decode_opcode(std::ostream &stream, const NEC_I386_OPCODE *op, uint8_t op1, offs_t pc_base, offs_t &pc, const data_buffer &opcodes, const data_buffer ¶ms); +}; + + +#endif diff --git a/src/devices/cpu/nec/necea.h b/src/devices/cpu/nec/necea.h index 1a20c0cdf54..a8b42329233 100644 --- a/src/devices/cpu/nec/necea.h +++ b/src/devices/cpu/nec/necea.h @@ -7,26 +7,26 @@ uint32_t nec_common_device::EA_002() { m_EO=Wreg(BP)+Wreg(IX); m_EA=DefaultBase( uint32_t nec_common_device::EA_003() { m_EO=Wreg(BP)+Wreg(IY); m_EA=DefaultBase(SS)+m_EO; return m_EA; } uint32_t nec_common_device::EA_004() { m_EO=Wreg(IX); m_EA=DefaultBase(DS0)+m_EO; return m_EA; } uint32_t nec_common_device::EA_005() { m_EO=Wreg(IY); m_EA=DefaultBase(DS0)+m_EO; return m_EA; } -uint32_t nec_common_device::EA_006() { m_EO=FETCH(); m_EO+=FETCH()<<8; m_EA=DefaultBase(DS0)+m_EO; return m_EA; } +uint32_t nec_common_device::EA_006() { m_EO=fetch(); m_EO+=fetch()<<8; m_EA=DefaultBase(DS0)+m_EO; return m_EA; } uint32_t nec_common_device::EA_007() { m_EO=Wreg(BW); m_EA=DefaultBase(DS0)+m_EO; return m_EA; } -uint32_t nec_common_device::EA_100() { m_EO=(Wreg(BW)+Wreg(IX)+(int8_t)FETCH()); m_EA=DefaultBase(DS0)+m_EO; return m_EA; } -uint32_t nec_common_device::EA_101() { m_EO=(Wreg(BW)+Wreg(IY)+(int8_t)FETCH()); m_EA=DefaultBase(DS0)+m_EO; return m_EA; } -uint32_t nec_common_device::EA_102() { m_EO=(Wreg(BP)+Wreg(IX)+(int8_t)FETCH()); m_EA=DefaultBase(SS)+m_EO; return m_EA; } -uint32_t nec_common_device::EA_103() { m_EO=(Wreg(BP)+Wreg(IY)+(int8_t)FETCH()); m_EA=DefaultBase(SS)+m_EO; return m_EA; } -uint32_t nec_common_device::EA_104() { m_EO=(Wreg(IX)+(int8_t)FETCH()); m_EA=DefaultBase(DS0)+m_EO; return m_EA; } -uint32_t nec_common_device::EA_105() { m_EO=(Wreg(IY)+(int8_t)FETCH()); m_EA=DefaultBase(DS0)+m_EO; return m_EA; } -uint32_t nec_common_device::EA_106() { m_EO=(Wreg(BP)+(int8_t)FETCH()); m_EA=DefaultBase(SS)+m_EO; return m_EA; } -uint32_t nec_common_device::EA_107() { m_EO=(Wreg(BW)+(int8_t)FETCH()); m_EA=DefaultBase(DS0)+m_EO; return m_EA; } +uint32_t nec_common_device::EA_100() { m_EO=(Wreg(BW)+Wreg(IX)+(int8_t)fetch()); m_EA=DefaultBase(DS0)+m_EO; return m_EA; } +uint32_t nec_common_device::EA_101() { m_EO=(Wreg(BW)+Wreg(IY)+(int8_t)fetch()); m_EA=DefaultBase(DS0)+m_EO; return m_EA; } +uint32_t nec_common_device::EA_102() { m_EO=(Wreg(BP)+Wreg(IX)+(int8_t)fetch()); m_EA=DefaultBase(SS)+m_EO; return m_EA; } +uint32_t nec_common_device::EA_103() { m_EO=(Wreg(BP)+Wreg(IY)+(int8_t)fetch()); m_EA=DefaultBase(SS)+m_EO; return m_EA; } +uint32_t nec_common_device::EA_104() { m_EO=(Wreg(IX)+(int8_t)fetch()); m_EA=DefaultBase(DS0)+m_EO; return m_EA; } +uint32_t nec_common_device::EA_105() { m_EO=(Wreg(IY)+(int8_t)fetch()); m_EA=DefaultBase(DS0)+m_EO; return m_EA; } +uint32_t nec_common_device::EA_106() { m_EO=(Wreg(BP)+(int8_t)fetch()); m_EA=DefaultBase(SS)+m_EO; return m_EA; } +uint32_t nec_common_device::EA_107() { m_EO=(Wreg(BW)+(int8_t)fetch()); m_EA=DefaultBase(DS0)+m_EO; return m_EA; } -uint32_t nec_common_device::EA_200() { m_E16=FETCH(); m_E16+=FETCH()<<8; m_EO=Wreg(BW)+Wreg(IX)+(int16_t)m_E16; m_EA=DefaultBase(DS0)+m_EO; return m_EA; } -uint32_t nec_common_device::EA_201() { m_E16=FETCH(); m_E16+=FETCH()<<8; m_EO=Wreg(BW)+Wreg(IY)+(int16_t)m_E16; m_EA=DefaultBase(DS0)+m_EO; return m_EA; } -uint32_t nec_common_device::EA_202() { m_E16=FETCH(); m_E16+=FETCH()<<8; m_EO=Wreg(BP)+Wreg(IX)+(int16_t)m_E16; m_EA=DefaultBase(SS)+m_EO; return m_EA; } -uint32_t nec_common_device::EA_203() { m_E16=FETCH(); m_E16+=FETCH()<<8; m_EO=Wreg(BP)+Wreg(IY)+(int16_t)m_E16; m_EA=DefaultBase(SS)+m_EO; return m_EA; } -uint32_t nec_common_device::EA_204() { m_E16=FETCH(); m_E16+=FETCH()<<8; m_EO=Wreg(IX)+(int16_t)m_E16; m_EA=DefaultBase(DS0)+m_EO; return m_EA; } -uint32_t nec_common_device::EA_205() { m_E16=FETCH(); m_E16+=FETCH()<<8; m_EO=Wreg(IY)+(int16_t)m_E16; m_EA=DefaultBase(DS0)+m_EO; return m_EA; } -uint32_t nec_common_device::EA_206() { m_E16=FETCH(); m_E16+=FETCH()<<8; m_EO=Wreg(BP)+(int16_t)m_E16; m_EA=DefaultBase(SS)+m_EO; return m_EA; } -uint32_t nec_common_device::EA_207() { m_E16=FETCH(); m_E16+=FETCH()<<8; m_EO=Wreg(BW)+(int16_t)m_E16; m_EA=DefaultBase(DS0)+m_EO; return m_EA; } +uint32_t nec_common_device::EA_200() { m_E16=fetch(); m_E16+=fetch()<<8; m_EO=Wreg(BW)+Wreg(IX)+(int16_t)m_E16; m_EA=DefaultBase(DS0)+m_EO; return m_EA; } +uint32_t nec_common_device::EA_201() { m_E16=fetch(); m_E16+=fetch()<<8; m_EO=Wreg(BW)+Wreg(IY)+(int16_t)m_E16; m_EA=DefaultBase(DS0)+m_EO; return m_EA; } +uint32_t nec_common_device::EA_202() { m_E16=fetch(); m_E16+=fetch()<<8; m_EO=Wreg(BP)+Wreg(IX)+(int16_t)m_E16; m_EA=DefaultBase(SS)+m_EO; return m_EA; } +uint32_t nec_common_device::EA_203() { m_E16=fetch(); m_E16+=fetch()<<8; m_EO=Wreg(BP)+Wreg(IY)+(int16_t)m_E16; m_EA=DefaultBase(SS)+m_EO; return m_EA; } +uint32_t nec_common_device::EA_204() { m_E16=fetch(); m_E16+=fetch()<<8; m_EO=Wreg(IX)+(int16_t)m_E16; m_EA=DefaultBase(DS0)+m_EO; return m_EA; } +uint32_t nec_common_device::EA_205() { m_E16=fetch(); m_E16+=fetch()<<8; m_EO=Wreg(IY)+(int16_t)m_E16; m_EA=DefaultBase(DS0)+m_EO; return m_EA; } +uint32_t nec_common_device::EA_206() { m_E16=fetch(); m_E16+=fetch()<<8; m_EO=Wreg(BP)+(int16_t)m_E16; m_EA=DefaultBase(SS)+m_EO; return m_EA; } +uint32_t nec_common_device::EA_207() { m_E16=fetch(); m_E16+=fetch()<<8; m_EO=Wreg(BW)+(int16_t)m_E16; m_EA=DefaultBase(DS0)+m_EO; return m_EA; } const nec_common_device::nec_eahandler nec_common_device::s_GetEA[192]= { diff --git a/src/devices/cpu/nec/necinstr.hxx b/src/devices/cpu/nec/necinstr.hxx index 98863c4c431..0499c49c65b 100644 --- a/src/devices/cpu/nec/necinstr.hxx +++ b/src/devices/cpu/nec/necinstr.hxx @@ -19,7 +19,7 @@ OP( 0x0c, i_or_ald8 ) { DEF_ald8; ORB; Breg(AL)=dst; CLKS(4,4,2); OP( 0x0d, i_or_axd16 ) { DEF_axd16; ORW; Wreg(AW)=dst; CLKS(4,4,2); } OP( 0x0e, i_push_cs ) { PUSH(Sreg(PS)); CLKS(12,8,3); } OP( 0x0f, i_pre_nec ) { uint32_t ModRM, tmp, tmp2; - switch (FETCH()) { + switch (fetch()) { case 0x10 : BITOP_BYTE; CLKS(3,3,4); tmp2 = Breg(CL) & 0x7; m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */ case 0x11 : BITOP_WORD; CLKS(3,3,4); tmp2 = Breg(CL) & 0xf; m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */ case 0x12 : BITOP_BYTE; CLKS(5,5,4); tmp2 = Breg(CL) & 0x7; tmp &= ~(1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Clr */ @@ -29,25 +29,25 @@ OP( 0x0f, i_pre_nec ) { uint32_t ModRM, tmp, tmp2; case 0x16 : BITOP_BYTE; CLKS(4,4,4); tmp2 = Breg(CL) & 0x7; BIT_NOT; PutbackRMByte(ModRM,tmp); break; /* Not */ case 0x17 : BITOP_WORD; CLKS(4,4,4); tmp2 = Breg(CL) & 0xf; BIT_NOT; PutbackRMWord(ModRM,tmp); break; /* Not */ - case 0x18 : BITOP_BYTE; CLKS(4,4,4); tmp2 = (FETCH()) & 0x7; m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */ - case 0x19 : BITOP_WORD; CLKS(4,4,4); tmp2 = (FETCH()) & 0xf; m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */ - case 0x1a : BITOP_BYTE; CLKS(6,6,4); tmp2 = (FETCH()) & 0x7; tmp &= ~(1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Clr */ - case 0x1b : BITOP_WORD; CLKS(6,6,4); tmp2 = (FETCH()) & 0xf; tmp &= ~(1<<tmp2); PutbackRMWord(ModRM,tmp); break; /* Clr */ - case 0x1c : BITOP_BYTE; CLKS(5,5,4); tmp2 = (FETCH()) & 0x7; tmp |= (1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Set */ - case 0x1d : BITOP_WORD; CLKS(5,5,4); tmp2 = (FETCH()) & 0xf; tmp |= (1<<tmp2); PutbackRMWord(ModRM,tmp); break; /* Set */ - case 0x1e : BITOP_BYTE; CLKS(5,5,4); tmp2 = (FETCH()) & 0x7; BIT_NOT; PutbackRMByte(ModRM,tmp); break; /* Not */ - case 0x1f : BITOP_WORD; CLKS(5,5,4); tmp2 = (FETCH()) & 0xf; BIT_NOT; PutbackRMWord(ModRM,tmp); break; /* Not */ + case 0x18 : BITOP_BYTE; CLKS(4,4,4); tmp2 = (fetch()) & 0x7; m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */ + case 0x19 : BITOP_WORD; CLKS(4,4,4); tmp2 = (fetch()) & 0xf; m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */ + case 0x1a : BITOP_BYTE; CLKS(6,6,4); tmp2 = (fetch()) & 0x7; tmp &= ~(1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Clr */ + case 0x1b : BITOP_WORD; CLKS(6,6,4); tmp2 = (fetch()) & 0xf; tmp &= ~(1<<tmp2); PutbackRMWord(ModRM,tmp); break; /* Clr */ + case 0x1c : BITOP_BYTE; CLKS(5,5,4); tmp2 = (fetch()) & 0x7; tmp |= (1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Set */ + case 0x1d : BITOP_WORD; CLKS(5,5,4); tmp2 = (fetch()) & 0xf; tmp |= (1<<tmp2); PutbackRMWord(ModRM,tmp); break; /* Set */ + case 0x1e : BITOP_BYTE; CLKS(5,5,4); tmp2 = (fetch()) & 0x7; BIT_NOT; PutbackRMByte(ModRM,tmp); break; /* Not */ + case 0x1f : BITOP_WORD; CLKS(5,5,4); tmp2 = (fetch()) & 0xf; BIT_NOT; PutbackRMWord(ModRM,tmp); break; /* Not */ case 0x20 : ADD4S; CLKS(7,7,2); break; case 0x22 : SUB4S; CLKS(7,7,2); break; case 0x26 : CMP4S; CLKS(7,7,2); break; - case 0x28 : ModRM = FETCH(); tmp = GetRMByte(ModRM); tmp <<= 4; tmp |= Breg(AL) & 0xf; Breg(AL) = (Breg(AL) & 0xf0) | ((tmp>>8)&0xf); tmp &= 0xff; PutbackRMByte(ModRM,tmp); CLKM(13,13,9,28,28,15); break; - case 0x2a : ModRM = FETCH(); tmp = GetRMByte(ModRM); tmp2 = (Breg(AL) & 0xf)<<4; Breg(AL) = (Breg(AL) & 0xf0) | (tmp&0xf); tmp = tmp2 | (tmp>>4); PutbackRMByte(ModRM,tmp); CLKM(17,17,13,32,32,19); break; - case 0x31 : ModRM = FETCH(); ModRM=0; logerror("%06x: Unimplemented bitfield INS\n",PC()); break; - case 0x33 : ModRM = FETCH(); ModRM=0; logerror("%06x: Unimplemented bitfield EXT\n",PC()); break; - case 0xe0 : ModRM = FETCH(); ModRM=0; logerror("%06x: V33 unimplemented BRKXA (break to expansion address)\n",PC()); break; - case 0xf0 : ModRM = FETCH(); ModRM=0; logerror("%06x: V33 unimplemented RETXA (return from expansion address)\n",PC()); break; - case 0xff : ModRM = FETCH(); ModRM=0; logerror("%06x: unimplemented BRKEM (break to 8080 emulation mode)\n",PC()); break; + case 0x28 : ModRM = fetch(); tmp = GetRMByte(ModRM); tmp <<= 4; tmp |= Breg(AL) & 0xf; Breg(AL) = (Breg(AL) & 0xf0) | ((tmp>>8)&0xf); tmp &= 0xff; PutbackRMByte(ModRM,tmp); CLKM(13,13,9,28,28,15); break; + case 0x2a : ModRM = fetch(); tmp = GetRMByte(ModRM); tmp2 = (Breg(AL) & 0xf)<<4; Breg(AL) = (Breg(AL) & 0xf0) | (tmp&0xf); tmp = tmp2 | (tmp>>4); PutbackRMByte(ModRM,tmp); CLKM(17,17,13,32,32,19); break; + case 0x31 : ModRM = fetch(); ModRM=0; logerror("%06x: Unimplemented bitfield INS\n",PC()); break; + case 0x33 : ModRM = fetch(); ModRM=0; logerror("%06x: Unimplemented bitfield EXT\n",PC()); break; + case 0xe0 : ModRM = fetch(); ModRM=0; logerror("%06x: V33 unimplemented BRKXA (break to expansion address)\n",PC()); break; + case 0xf0 : ModRM = fetch(); ModRM=0; logerror("%06x: V33 unimplemented RETXA (return from expansion address)\n",PC()); break; + case 0xff : ModRM = fetch(); ModRM=0; logerror("%06x: unimplemented BRKEM (break to 8080 emulation mode)\n",PC()); break; default: logerror("%06x: Unknown V20 instruction\n",PC()); break; } } @@ -234,10 +234,10 @@ OP( 0x65, i_repc ) { uint32_t next = fetchop(); uint16_t c = Wreg(CW); m_seg_prefix=false; } -OP( 0x68, i_push_d16 ) { uint32_t tmp; tmp = FETCHWORD(); PUSH(tmp); CLKW(12,12,5,12,8,5,Wreg(SP)); } -OP( 0x69, i_imul_d16 ) { uint32_t tmp; DEF_r16w; tmp = FETCHWORD(); dst = (int32_t)((int16_t)src)*(int32_t)((int16_t)tmp); m_CarryVal = m_OverVal = (((int32_t)dst) >> 15 != 0) && (((int32_t)dst) >> 15 != -1); RegWord(ModRM)=(WORD)dst; m_icount-=(ModRM >=0xc0 )?38:47;} -OP( 0x6a, i_push_d8 ) { uint32_t tmp = (WORD)((int16_t)((int8_t)FETCH())); PUSH(tmp); CLKW(11,11,5,11,7,3,Wreg(SP)); } -OP( 0x6b, i_imul_d8 ) { uint32_t src2; DEF_r16w; src2= (WORD)((int16_t)((int8_t)FETCH())); dst = (int32_t)((int16_t)src)*(int32_t)((int16_t)src2); m_CarryVal = m_OverVal = (((int32_t)dst) >> 15 != 0) && (((int32_t)dst) >> 15 != -1); RegWord(ModRM)=(WORD)dst; m_icount-=(ModRM >=0xc0 )?31:39; } +OP( 0x68, i_push_d16 ) { uint32_t tmp; tmp = fetchword(); PUSH(tmp); CLKW(12,12,5,12,8,5,Wreg(SP)); } +OP( 0x69, i_imul_d16 ) { uint32_t tmp; DEF_r16w; tmp = fetchword(); dst = (int32_t)((int16_t)src)*(int32_t)((int16_t)tmp); m_CarryVal = m_OverVal = (((int32_t)dst) >> 15 != 0) && (((int32_t)dst) >> 15 != -1); RegWord(ModRM)=(WORD)dst; m_icount-=(ModRM >=0xc0 )?38:47;} +OP( 0x6a, i_push_d8 ) { uint32_t tmp = (WORD)((int16_t)((int8_t)fetch())); PUSH(tmp); CLKW(11,11,5,11,7,3,Wreg(SP)); } +OP( 0x6b, i_imul_d8 ) { uint32_t src2; DEF_r16w; src2= (WORD)((int16_t)((int8_t)fetch())); dst = (int32_t)((int16_t)src)*(int32_t)((int16_t)src2); m_CarryVal = m_OverVal = (((int32_t)dst) >> 15 != 0) && (((int32_t)dst) >> 15 != -1); RegWord(ModRM)=(WORD)dst; m_icount-=(ModRM >=0xc0 )?31:39; } OP( 0x6c, i_insb ) { PutMemB(DS1,Wreg(IY),read_port_byte(Wreg(DW))); Wreg(IY)+= -2 * m_DF + 1; CLK(8); } OP( 0x6d, i_insw ) { PutMemW(DS1,Wreg(IY),read_port_word(Wreg(DW))); Wreg(IY)+= -4 * m_DF + 2; CLKS(18,10,8); } OP( 0x6e, i_outsb ) { write_port_byte(Wreg(DW),GetMemB(DS0,Wreg(IX))); Wreg(IX)+= -2 * m_DF + 1; CLK(8); } @@ -260,7 +260,7 @@ OP( 0x7d, i_jnl ) { JMP((ZF)||(SF==OF)); CLKS(4,4,3); } OP( 0x7e, i_jle ) { JMP((ZF)||(SF!=OF)); CLKS(4,4,3); } OP( 0x7f, i_jnle ) { JMP((SF==OF)&&(!ZF)); CLKS(4,4,3); } -OP( 0x80, i_80pre ) { uint32_t dst, src; GetModRM; dst = GetRMByte(ModRM); src = FETCH(); +OP( 0x80, i_80pre ) { uint32_t dst, src; GetModRM; dst = GetRMByte(ModRM); src = fetch(); if (ModRM >=0xc0 ) CLKS(4,4,2) else if ((ModRM & 0x38)==0x38) CLKS(13,13,6) else CLKS(18,18,7) switch (ModRM & 0x38) { case 0x00: ADDB; PutbackRMByte(ModRM,dst); break; @@ -274,7 +274,7 @@ OP( 0x80, i_80pre ) { uint32_t dst, src; GetModRM; dst = GetRMByte(ModRM); src } } -OP( 0x81, i_81pre ) { uint32_t dst, src; GetModRM; dst = GetRMWord(ModRM); src = FETCH(); src+= (FETCH() << 8); +OP( 0x81, i_81pre ) { uint32_t dst, src; GetModRM; dst = GetRMWord(ModRM); src = fetch(); src+= (fetch() << 8); if (ModRM >=0xc0 ) CLKS(4,4,2) else if ((ModRM & 0x38)==0x38) CLKW(17,17,8,17,13,6,m_EA) else CLKW(26,26,11,26,18,7,m_EA) switch (ModRM & 0x38) { case 0x00: ADDW; PutbackRMWord(ModRM,dst); break; @@ -288,7 +288,7 @@ OP( 0x81, i_81pre ) { uint32_t dst, src; GetModRM; dst = GetRMWord(ModRM); src } } -OP( 0x82, i_82pre ) { uint32_t dst, src; GetModRM; dst = GetRMByte(ModRM); src = (BYTE)((int8_t)FETCH()); +OP( 0x82, i_82pre ) { uint32_t dst, src; GetModRM; dst = GetRMByte(ModRM); src = (BYTE)((int8_t)fetch()); if (ModRM >=0xc0 ) CLKS(4,4,2) else if ((ModRM & 0x38)==0x38) CLKS(13,13,6) else CLKS(18,18,7) switch (ModRM & 0x38) { case 0x00: ADDB; PutbackRMByte(ModRM,dst); break; @@ -302,7 +302,7 @@ OP( 0x82, i_82pre ) { uint32_t dst, src; GetModRM; dst = GetRMByte(ModRM); src } } -OP( 0x83, i_83pre ) { uint32_t dst, src; GetModRM; dst = GetRMWord(ModRM); src = (WORD)((int16_t)((int8_t)FETCH())); +OP( 0x83, i_83pre ) { uint32_t dst, src; GetModRM; dst = GetRMWord(ModRM); src = (WORD)((int16_t)((int8_t)fetch())); if (ModRM >=0xc0 ) CLKS(4,4,2) else if ((ModRM & 0x38)==0x38) CLKW(17,17,8,17,13,6,m_EA) else CLKW(26,26,11,26,18,7,m_EA) switch (ModRM & 0x38) { case 0x00: ADDW; PutbackRMWord(ModRM,dst); break; @@ -334,7 +334,7 @@ OP( 0x8c, i_mov_wsreg ) { GetModRM; default: logerror("%06x: MOV Sreg - Invalid register\n",PC()); } } -OP( 0x8d, i_lea ) { uint16_t ModRM = FETCH(); (void)(this->*s_GetEA[ModRM])(); RegWord(ModRM)=m_EO; CLKS(4,4,2); } +OP( 0x8d, i_lea ) { uint16_t ModRM = fetch(); (void)(this->*s_GetEA[ModRM])(); RegWord(ModRM)=m_EO; CLKS(4,4,2); } OP( 0x8e, i_mov_sregw ) { uint16_t src; GetModRM; src = GetRMWord(ModRM); CLKR(15,15,7,15,11,5,2,m_EA); switch (ModRM & 0x38) { case 0x00: Sreg(DS1) = src; break; /* mov es,ew */ @@ -357,17 +357,17 @@ OP( 0x97, i_xchg_axdi ) { XchgAWReg(IY); CLK(3); } OP( 0x98, i_cbw ) { Breg(AH) = (Breg(AL) & 0x80) ? 0xff : 0; CLK(2); } OP( 0x99, i_cwd ) { Wreg(DW) = (Breg(AH) & 0x80) ? 0xffff : 0; CLK(4); } -OP( 0x9a, i_call_far ) { uint32_t tmp, tmp2; tmp = FETCHWORD(); tmp2 = FETCHWORD(); PUSH(Sreg(PS)); PUSH(m_ip); m_ip = (WORD)tmp; Sreg(PS) = (WORD)tmp2; CHANGE_PC; CLKW(29,29,13,29,21,9,Wreg(SP)); } +OP( 0x9a, i_call_far ) { uint32_t tmp, tmp2; tmp = fetchword(); tmp2 = fetchword(); PUSH(Sreg(PS)); PUSH(m_ip); m_ip = (WORD)tmp; Sreg(PS) = (WORD)tmp2; CHANGE_PC; CLKW(29,29,13,29,21,9,Wreg(SP)); } OP( 0x9b, i_wait ) { if (!m_poll_state) m_ip--; CLK(5); } OP( 0x9c, i_pushf ) { uint16_t tmp = CompressFlags(); PUSH( tmp ); CLKS(12,8,3); } OP( 0x9d, i_popf ) { uint32_t tmp; POP(tmp); ExpandFlags(tmp); CLKS(12,8,5); if (m_TF) nec_trap(); } OP( 0x9e, i_sahf ) { uint32_t tmp = (CompressFlags() & 0xff00) | (Breg(AH) & 0xd5); ExpandFlags(tmp); CLKS(3,3,2); } OP( 0x9f, i_lahf ) { Breg(AH) = CompressFlags() & 0xff; CLKS(3,3,2); } -OP( 0xa0, i_mov_aldisp ) { uint32_t addr; addr = FETCHWORD(); Breg(AL) = GetMemB(DS0, addr); CLKS(10,10,5); } -OP( 0xa1, i_mov_axdisp ) { uint32_t addr; addr = FETCHWORD(); Wreg(AW) = GetMemW(DS0, addr); CLKW(14,14,7,14,10,5,addr); } -OP( 0xa2, i_mov_dispal ) { uint32_t addr; addr = FETCHWORD(); PutMemB(DS0, addr, Breg(AL)); CLKS(9,9,3); } -OP( 0xa3, i_mov_dispax ) { uint32_t addr; addr = FETCHWORD(); PutMemW(DS0, addr, Wreg(AW)); CLKW(13,13,5,13,9,3,addr); } +OP( 0xa0, i_mov_aldisp ) { uint32_t addr; addr = fetchword(); Breg(AL) = GetMemB(DS0, addr); CLKS(10,10,5); } +OP( 0xa1, i_mov_axdisp ) { uint32_t addr; addr = fetchword(); Wreg(AW) = GetMemW(DS0, addr); CLKW(14,14,7,14,10,5,addr); } +OP( 0xa2, i_mov_dispal ) { uint32_t addr; addr = fetchword(); PutMemB(DS0, addr, Breg(AL)); CLKS(9,9,3); } +OP( 0xa3, i_mov_dispax ) { uint32_t addr; addr = fetchword(); PutMemW(DS0, addr, Wreg(AW)); CLKW(13,13,5,13,9,3,addr); } OP( 0xa4, i_movsb ) { uint32_t tmp = GetMemB(DS0,Wreg(IX)); PutMemB(DS1,Wreg(IY), tmp); Wreg(IY) += -2 * m_DF + 1; Wreg(IX) += -2 * m_DF + 1; CLKS(8,8,6); } OP( 0xa5, i_movsw ) { uint32_t tmp = GetMemW(DS0,Wreg(IX)); PutMemW(DS1,Wreg(IY), tmp); Wreg(IY) += -4 * m_DF + 2; Wreg(IX) += -4 * m_DF + 2; CLKS(16,16,10); } OP( 0xa6, i_cmpsb ) { uint32_t src = GetMemB(DS1, Wreg(IY)); uint32_t dst = GetMemB(DS0, Wreg(IX)); SUBB; Wreg(IY) += -2 * m_DF + 1; Wreg(IX) += -2 * m_DF + 1; CLKS(14,14,14); } @@ -382,28 +382,28 @@ OP( 0xad, i_lodsw ) { Wreg(AW) = GetMemW(DS0,Wreg(IX)); Wreg(IX) += -4 * m_ OP( 0xae, i_scasb ) { uint32_t src = GetMemB(DS1, Wreg(IY)); uint32_t dst = Breg(AL); SUBB; Wreg(IY) += -2 * m_DF + 1; CLKS(4,4,3); } OP( 0xaf, i_scasw ) { uint32_t src = GetMemW(DS1, Wreg(IY)); uint32_t dst = Wreg(AW); SUBW; Wreg(IY) += -4 * m_DF + 2; CLKW(8,8,5,8,4,3,Wreg(IY)); } -OP( 0xb0, i_mov_ald8 ) { Breg(AL) = FETCH(); CLKS(4,4,2); } -OP( 0xb1, i_mov_cld8 ) { Breg(CL) = FETCH(); CLKS(4,4,2); } -OP( 0xb2, i_mov_dld8 ) { Breg(DL) = FETCH(); CLKS(4,4,2); } -OP( 0xb3, i_mov_bld8 ) { Breg(BL) = FETCH(); CLKS(4,4,2); } -OP( 0xb4, i_mov_ahd8 ) { Breg(AH) = FETCH(); CLKS(4,4,2); } -OP( 0xb5, i_mov_chd8 ) { Breg(CH) = FETCH(); CLKS(4,4,2); } -OP( 0xb6, i_mov_dhd8 ) { Breg(DH) = FETCH(); CLKS(4,4,2); } -OP( 0xb7, i_mov_bhd8 ) { Breg(BH) = FETCH(); CLKS(4,4,2); } - -OP( 0xb8, i_mov_axd16 ) { Breg(AL) = FETCH(); Breg(AH) = FETCH(); CLKS(4,4,2); } -OP( 0xb9, i_mov_cxd16 ) { Breg(CL) = FETCH(); Breg(CH) = FETCH(); CLKS(4,4,2); } -OP( 0xba, i_mov_dxd16 ) { Breg(DL) = FETCH(); Breg(DH) = FETCH(); CLKS(4,4,2); } -OP( 0xbb, i_mov_bxd16 ) { Breg(BL) = FETCH(); Breg(BH) = FETCH(); CLKS(4,4,2); } -OP( 0xbc, i_mov_spd16 ) { Wreg(SP) = FETCHWORD(); CLKS(4,4,2); } -OP( 0xbd, i_mov_bpd16 ) { Wreg(BP) = FETCHWORD(); CLKS(4,4,2); } -OP( 0xbe, i_mov_sid16 ) { Wreg(IX) = FETCHWORD(); CLKS(4,4,2); } -OP( 0xbf, i_mov_did16 ) { Wreg(IY) = FETCHWORD(); CLKS(4,4,2); } +OP( 0xb0, i_mov_ald8 ) { Breg(AL) = fetch(); CLKS(4,4,2); } +OP( 0xb1, i_mov_cld8 ) { Breg(CL) = fetch(); CLKS(4,4,2); } +OP( 0xb2, i_mov_dld8 ) { Breg(DL) = fetch(); CLKS(4,4,2); } +OP( 0xb3, i_mov_bld8 ) { Breg(BL) = fetch(); CLKS(4,4,2); } +OP( 0xb4, i_mov_ahd8 ) { Breg(AH) = fetch(); CLKS(4,4,2); } +OP( 0xb5, i_mov_chd8 ) { Breg(CH) = fetch(); CLKS(4,4,2); } +OP( 0xb6, i_mov_dhd8 ) { Breg(DH) = fetch(); CLKS(4,4,2); } +OP( 0xb7, i_mov_bhd8 ) { Breg(BH) = fetch(); CLKS(4,4,2); } + +OP( 0xb8, i_mov_axd16 ) { Breg(AL) = fetch(); Breg(AH) = fetch(); CLKS(4,4,2); } +OP( 0xb9, i_mov_cxd16 ) { Breg(CL) = fetch(); Breg(CH) = fetch(); CLKS(4,4,2); } +OP( 0xba, i_mov_dxd16 ) { Breg(DL) = fetch(); Breg(DH) = fetch(); CLKS(4,4,2); } +OP( 0xbb, i_mov_bxd16 ) { Breg(BL) = fetch(); Breg(BH) = fetch(); CLKS(4,4,2); } +OP( 0xbc, i_mov_spd16 ) { Wreg(SP) = fetchword(); CLKS(4,4,2); } +OP( 0xbd, i_mov_bpd16 ) { Wreg(BP) = fetchword(); CLKS(4,4,2); } +OP( 0xbe, i_mov_sid16 ) { Wreg(IX) = fetchword(); CLKS(4,4,2); } +OP( 0xbf, i_mov_did16 ) { Wreg(IY) = fetchword(); CLKS(4,4,2); } OP( 0xc0, i_rotshft_bd8 ) { uint32_t src, dst; uint8_t c; GetModRM; src = (unsigned)GetRMByte(ModRM); dst=src; - c=FETCH(); + c=fetch(); CLKM(7,7,2,19,19,6); if (c) switch (ModRM & 0x38) { case 0x00: do { ROL_BYTE; c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break; @@ -420,7 +420,7 @@ OP( 0xc0, i_rotshft_bd8 ) { OP( 0xc1, i_rotshft_wd8 ) { uint32_t src, dst; uint8_t c; GetModRM; src = (unsigned)GetRMWord(ModRM); dst=src; - c=FETCH(); + c=fetch(); CLKM(7,7,2,27,19,6); if (c) switch (ModRM & 0x38) { case 0x00: do { ROL_WORD; c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break; @@ -434,7 +434,7 @@ OP( 0xc1, i_rotshft_wd8 ) { } } -OP( 0xc2, i_ret_d16 ) { uint32_t count = FETCH(); count += FETCH() << 8; POP(m_ip); Wreg(SP)+=count; CHANGE_PC; CLKS(24,24,10); } +OP( 0xc2, i_ret_d16 ) { uint32_t count = fetch(); count += fetch() << 8; POP(m_ip); Wreg(SP)+=count; CHANGE_PC; CLKS(24,24,10); } OP( 0xc3, i_ret ) { POP(m_ip); CHANGE_PC; CLKS(19,19,10); } OP( 0xc4, i_les_dw ) { GetModRM; WORD tmp = GetRMWord(ModRM); RegWord(ModRM)=tmp; Sreg(DS1) = GetnextRMWord; CLKW(26,26,14,26,18,10,m_EA); } OP( 0xc5, i_lds_dw ) { GetModRM; WORD tmp = GetRMWord(ModRM); RegWord(ModRM)=tmp; Sreg(DS0) = GetnextRMWord; CLKW(26,26,14,26,18,10,m_EA); } @@ -442,12 +442,12 @@ OP( 0xc6, i_mov_bd8 ) { GetModRM; PutImmRMByte(ModRM); m_icount-=(ModRM >=0xc0 OP( 0xc7, i_mov_wd16 ) { GetModRM; PutImmRMWord(ModRM); m_icount-=(ModRM >=0xc0 )?4:15; } OP( 0xc8, i_enter ) { - uint32_t nb = FETCH(); + uint32_t nb = fetch(); uint32_t i,level; m_icount-=23; - nb += FETCH() << 8; - level = FETCH(); + nb += fetch() << 8; + level = fetch(); PUSH(Wreg(BP)); Wreg(BP)=Wreg(SP); Wreg(SP) -= nb; @@ -462,10 +462,10 @@ OP( 0xc9, i_leave ) { POP(Wreg(BP)); m_icount-=8; } -OP( 0xca, i_retf_d16 ) { uint32_t count = FETCH(); count += FETCH() << 8; POP(m_ip); POP(Sreg(PS)); Wreg(SP)+=count; CHANGE_PC; CLKS(32,32,16); } +OP( 0xca, i_retf_d16 ) { uint32_t count = fetch(); count += fetch() << 8; POP(m_ip); POP(Sreg(PS)); Wreg(SP)+=count; CHANGE_PC; CLKS(32,32,16); } OP( 0xcb, i_retf ) { POP(m_ip); POP(Sreg(PS)); CHANGE_PC; CLKS(29,29,16); } OP( 0xcc, i_int3 ) { nec_interrupt(3, BRK); CLKS(50,50,24); } -OP( 0xcd, i_int ) { nec_interrupt(FETCH(), BRK); CLKS(50,50,24); } +OP( 0xcd, i_int ) { nec_interrupt(fetch(), BRK); CLKS(50,50,24); } OP( 0xce, i_into ) { if (OF) { nec_interrupt(NEC_BRKV_VECTOR, BRK); CLKS(52,52,26); } else CLK(3); } OP( 0xcf, i_iret ) { POP(m_ip); POP(Sreg(PS)); i_popf(); CHANGE_PC; CLKS(39,39,19); } @@ -531,25 +531,25 @@ OP( 0xd3, i_rotshft_wcl ) { } } -OP( 0xd4, i_aam ) { FETCH(); Breg(AH) = Breg(AL) / 10; Breg(AL) %= 10; SetSZPF_Word(Wreg(AW)); CLKS(15,15,12); } -OP( 0xd5, i_aad ) { FETCH(); Breg(AL) = Breg(AH) * 10 + Breg(AL); Breg(AH) = 0; SetSZPF_Byte(Breg(AL)); CLKS(7,7,8); } +OP( 0xd4, i_aam ) { fetch(); Breg(AH) = Breg(AL) / 10; Breg(AL) %= 10; SetSZPF_Word(Wreg(AW)); CLKS(15,15,12); } +OP( 0xd5, i_aad ) { fetch(); Breg(AL) = Breg(AH) * 10 + Breg(AL); Breg(AH) = 0; SetSZPF_Byte(Breg(AL)); CLKS(7,7,8); } OP( 0xd6, i_setalc ) { Breg(AL) = (CF)?0xff:0x00; m_icount-=3; logerror("%06x: Undefined opcode (SETALC)\n",PC()); } OP( 0xd7, i_trans ) { uint32_t dest = (Wreg(BW)+Breg(AL))&0xffff; Breg(AL) = GetMemB(DS0, dest); CLKS(9,9,5); } OP( 0xd8, i_fpo ) { GetModRM; GetRMByte(ModRM); m_icount-=2; logerror("%06x: Unimplemented floating point control %04x\n",PC(),ModRM); } -OP( 0xe0, i_loopne ) { int8_t disp = (int8_t)FETCH(); Wreg(CW)--; if (!ZF && Wreg(CW)) { m_ip = (WORD)(m_ip+disp); /*CHANGE_PC;*/ CLKS(14,14,6); } else CLKS(5,5,3); } -OP( 0xe1, i_loope ) { int8_t disp = (int8_t)FETCH(); Wreg(CW)--; if ( ZF && Wreg(CW)) { m_ip = (WORD)(m_ip+disp); /*CHANGE_PC;*/ CLKS(14,14,6); } else CLKS(5,5,3); } -OP( 0xe2, i_loop ) { int8_t disp = (int8_t)FETCH(); Wreg(CW)--; if (Wreg(CW)) { m_ip = (WORD)(m_ip+disp); /*CHANGE_PC;*/ CLKS(13,13,6); } else CLKS(5,5,3); } -OP( 0xe3, i_jcxz ) { int8_t disp = (int8_t)FETCH(); if (Wreg(CW) == 0) { m_ip = (WORD)(m_ip+disp); /*CHANGE_PC;*/ CLKS(13,13,6); } else CLKS(5,5,3); } -OP( 0xe4, i_inal ) { uint8_t port = FETCH(); Breg(AL) = read_port_byte(port); CLKS(9,9,5); } -OP( 0xe5, i_inax ) { uint8_t port = FETCH(); Wreg(AW) = read_port_word(port); CLKW(13,13,7,13,9,5,port); } -OP( 0xe6, i_outal ) { uint8_t port = FETCH(); write_port_byte(port, Breg(AL)); CLKS(8,8,3); } -OP( 0xe7, i_outax ) { uint8_t port = FETCH(); write_port_word(port, Wreg(AW)); CLKW(12,12,5,12,8,3,port); } - -OP( 0xe8, i_call_d16 ) { uint32_t tmp; tmp = FETCHWORD(); PUSH(m_ip); m_ip = (WORD)(m_ip+(int16_t)tmp); CHANGE_PC; m_icount-=24; } -OP( 0xe9, i_jmp_d16 ) { uint32_t tmp; tmp = FETCHWORD(); m_ip = (WORD)(m_ip+(int16_t)tmp); CHANGE_PC; m_icount-=15; } -OP( 0xea, i_jmp_far ) { uint32_t tmp,tmp1; tmp = FETCHWORD(); tmp1 = FETCHWORD(); Sreg(PS) = (WORD)tmp1; m_ip = (WORD)tmp; CHANGE_PC; m_icount-=27; } -OP( 0xeb, i_jmp_d8 ) { int tmp = (int)((int8_t)FETCH()); m_icount-=12; m_ip = (WORD)(m_ip+tmp); } +OP( 0xe0, i_loopne ) { int8_t disp = (int8_t)fetch(); Wreg(CW)--; if (!ZF && Wreg(CW)) { m_ip = (WORD)(m_ip+disp); /*CHANGE_PC;*/ CLKS(14,14,6); } else CLKS(5,5,3); } +OP( 0xe1, i_loope ) { int8_t disp = (int8_t)fetch(); Wreg(CW)--; if ( ZF && Wreg(CW)) { m_ip = (WORD)(m_ip+disp); /*CHANGE_PC;*/ CLKS(14,14,6); } else CLKS(5,5,3); } +OP( 0xe2, i_loop ) { int8_t disp = (int8_t)fetch(); Wreg(CW)--; if (Wreg(CW)) { m_ip = (WORD)(m_ip+disp); /*CHANGE_PC;*/ CLKS(13,13,6); } else CLKS(5,5,3); } +OP( 0xe3, i_jcxz ) { int8_t disp = (int8_t)fetch(); if (Wreg(CW) == 0) { m_ip = (WORD)(m_ip+disp); /*CHANGE_PC;*/ CLKS(13,13,6); } else CLKS(5,5,3); } +OP( 0xe4, i_inal ) { uint8_t port = fetch(); Breg(AL) = read_port_byte(port); CLKS(9,9,5); } +OP( 0xe5, i_inax ) { uint8_t port = fetch(); Wreg(AW) = read_port_word(port); CLKW(13,13,7,13,9,5,port); } +OP( 0xe6, i_outal ) { uint8_t port = fetch(); write_port_byte(port, Breg(AL)); CLKS(8,8,3); } +OP( 0xe7, i_outax ) { uint8_t port = fetch(); write_port_word(port, Wreg(AW)); CLKW(12,12,5,12,8,3,port); } + +OP( 0xe8, i_call_d16 ) { uint32_t tmp; tmp = fetchword(); PUSH(m_ip); m_ip = (WORD)(m_ip+(int16_t)tmp); CHANGE_PC; m_icount-=24; } +OP( 0xe9, i_jmp_d16 ) { uint32_t tmp; tmp = fetchword(); m_ip = (WORD)(m_ip+(int16_t)tmp); CHANGE_PC; m_icount-=15; } +OP( 0xea, i_jmp_far ) { uint32_t tmp,tmp1; tmp = fetchword(); tmp1 = fetchword(); Sreg(PS) = (WORD)tmp1; m_ip = (WORD)tmp; CHANGE_PC; m_icount-=27; } +OP( 0xeb, i_jmp_d8 ) { int tmp = (int)((int8_t)fetch()); m_icount-=12; m_ip = (WORD)(m_ip+tmp); } OP( 0xec, i_inaldx ) { Breg(AL) = read_port_byte(Wreg(DW)); CLKS(8,8,5);} OP( 0xed, i_inaxdx ) { Wreg(AW) = read_port_word(Wreg(DW)); CLKW(12,12,7,12,8,5,Wreg(DW)); } OP( 0xee, i_outdxal ) { write_port_byte(Wreg(DW), Breg(AL)); CLKS(8,8,3); } @@ -615,7 +615,7 @@ OP( 0xf5, i_cmc ) { m_CarryVal = !CF; CLK(2); } OP( 0xf6, i_f6pre ) { uint32_t tmp; uint32_t uresult,uresult2; int32_t result,result2; GetModRM; tmp = GetRMByte(ModRM); switch (ModRM & 0x38) { - case 0x00: tmp &= FETCH(); m_CarryVal = m_OverVal = 0; SetSZPF_Byte(tmp); m_icount-=(ModRM >=0xc0 )?4:11; break; /* TEST */ + case 0x00: tmp &= fetch(); m_CarryVal = m_OverVal = 0; SetSZPF_Byte(tmp); m_icount-=(ModRM >=0xc0 )?4:11; break; /* TEST */ case 0x08: logerror("%06x: Undefined opcode 0xf6 0x08\n",PC()); break; case 0x10: PutbackRMByte(ModRM,~tmp); m_icount-=(ModRM >=0xc0 )?2:16; break; /* NOT */ case 0x18: m_CarryVal=(tmp!=0); tmp=(~tmp)+1; SetSZPF_Byte(tmp); PutbackRMByte(ModRM,tmp&0xff); m_icount-=(ModRM >=0xc0 )?2:16; break; /* NEG */ @@ -629,7 +629,7 @@ OP( 0xf6, i_f6pre ) { uint32_t tmp; uint32_t uresult,uresult2; int32_t result,re OP( 0xf7, i_f7pre ) { uint32_t tmp,tmp2; uint32_t uresult,uresult2; int32_t result,result2; GetModRM; tmp = GetRMWord(ModRM); switch (ModRM & 0x38) { - case 0x00: tmp2 = FETCHWORD(); tmp &= tmp2; m_CarryVal = m_OverVal = 0; SetSZPF_Word(tmp); m_icount-=(ModRM >=0xc0 )?4:11; break; /* TEST */ + case 0x00: tmp2 = fetchword(); tmp &= tmp2; m_CarryVal = m_OverVal = 0; SetSZPF_Word(tmp); m_icount-=(ModRM >=0xc0 )?4:11; break; /* TEST */ case 0x08: logerror("%06x: Undefined opcode 0xf7 0x08\n",PC()); break; case 0x10: PutbackRMWord(ModRM,~tmp); m_icount-=(ModRM >=0xc0 )?2:16; break; /* NOT */ case 0x18: m_CarryVal=(tmp!=0); tmp=(~tmp)+1; SetSZPF_Word(tmp); PutbackRMWord(ModRM,tmp&0xffff); m_icount-=(ModRM >=0xc0 )?2:16; break; /* NEG */ diff --git a/src/devices/cpu/nec/necmacro.h b/src/devices/cpu/nec/necmacro.h index c97f487cc2c..582c233979f 100644 --- a/src/devices/cpu/nec/necmacro.h +++ b/src/devices/cpu/nec/necmacro.h @@ -55,8 +55,8 @@ #define JMP(flag) \ int tmp; \ - EMPTY_PREFETCH(); \ - tmp = (int)((int8_t)FETCH()); \ + EMPTY_PREfetch(); \ + tmp = (int)((int8_t)fetch()); \ if (flag) \ { \ static const uint8_t table[3]={3,10,10}; \ @@ -98,7 +98,7 @@ Breg(AL) &= 0x0F #define BITOP_BYTE \ - ModRM = FETCH(); \ + ModRM = fetch(); \ if (ModRM >= 0xc0) { \ tmp=Breg(Mod_RM.RM.b[ModRM]); \ } \ @@ -108,7 +108,7 @@ } #define BITOP_WORD \ - ModRM = FETCH(); \ + ModRM = fetch(); \ if (ModRM >= 0xc0) { \ tmp=Wreg(Mod_RM.RM.w[ModRM]); \ } \ diff --git a/src/devices/cpu/nec/necmodrm.h b/src/devices/cpu/nec/necmodrm.h index 2bc3afdfd28..ac69a0010be 100644 --- a/src/devices/cpu/nec/necmodrm.h +++ b/src/devices/cpu/nec/necmodrm.h @@ -39,10 +39,10 @@ static struct { { \ WORD val; \ if (ModRM >= 0xc0) \ - Wreg(Mod_RM.RM.w[ModRM]) = FETCHWORD(); \ + Wreg(Mod_RM.RM.w[ModRM]) = fetchword(); \ else { \ (this->*s_GetEA[ModRM])(); \ - val = FETCHWORD(); \ + val = fetchword(); \ write_mem_word( m_EA , val); \ } \ } @@ -61,10 +61,10 @@ static struct { #define PutImmRMByte(ModRM) \ { \ if (ModRM >= 0xc0) \ - Breg(Mod_RM.RM.b[ModRM])=FETCH(); \ + Breg(Mod_RM.RM.b[ModRM])=fetch(); \ else { \ (this->*s_GetEA[ModRM])(); \ - write_mem_byte( m_EA , FETCH() ); \ + write_mem_byte( m_EA , fetch() ); \ } \ } @@ -77,30 +77,30 @@ static struct { } #define DEF_br8 \ - uint32_t ModRM = FETCH(),src,dst; \ + uint32_t ModRM = fetch(),src,dst; \ src = RegByte(ModRM); \ dst = GetRMByte(ModRM) #define DEF_wr16 \ - uint32_t ModRM = FETCH(),src,dst; \ + uint32_t ModRM = fetch(),src,dst; \ src = RegWord(ModRM); \ dst = GetRMWord(ModRM) #define DEF_r8b \ - uint32_t ModRM = FETCH(),src,dst; \ + uint32_t ModRM = fetch(),src,dst; \ dst = RegByte(ModRM); \ src = GetRMByte(ModRM) #define DEF_r16w \ - uint32_t ModRM = FETCH(),src,dst; \ + uint32_t ModRM = fetch(),src,dst; \ dst = RegWord(ModRM); \ src = GetRMWord(ModRM) #define DEF_ald8 \ - uint32_t src = FETCH(); \ + uint32_t src = fetch(); \ uint32_t dst = Breg(AL) #define DEF_axd16 \ - uint32_t src = FETCH(); \ + uint32_t src = fetch(); \ uint32_t dst = Wreg(AW); \ - src += (FETCH() << 8) + src += (fetch() << 8) diff --git a/src/devices/cpu/nec/necpriv.h b/src/devices/cpu/nec/necpriv.h index 2d4cb9f6b2f..459fa5017b4 100644 --- a/src/devices/cpu/nec/necpriv.h +++ b/src/devices/cpu/nec/necpriv.h @@ -64,7 +64,7 @@ enum BREGS { /************************************************************************/ -#define CHANGE_PC do { EMPTY_PREFETCH(); } while (0) +#define CHANGE_PC do { EMPTY_PREfetch(); } while (0) #define SegBase(Seg) (Sreg(Seg) << 4) @@ -78,15 +78,13 @@ enum BREGS { /* prefetch timing */ -#define FETCH() fetch() -#define FETCHWORD() fetchword() -#define EMPTY_PREFETCH() m_prefetch_reset = 1 +#define EMPTY_PREfetch() m_prefetch_reset = 1 #define PUSH(val) { Wreg(SP) -= 2; write_mem_word(((Sreg(SS)<<4)+Wreg(SP)), val); } #define POP(var) { Wreg(SP) += 2; var = read_mem_word(((Sreg(SS)<<4) + ((Wreg(SP)-2) & 0xffff))); } -#define GetModRM uint32_t ModRM=FETCH() +#define GetModRM uint32_t ModRM=fetch() /* Cycle count macros: CLK - cycle count is the same on all processors diff --git a/src/devices/cpu/nec/v25.cpp b/src/devices/cpu/nec/v25.cpp index d70bbd224c0..7c1dfb28731 100644 --- a/src/devices/cpu/nec/v25.cpp +++ b/src/devices/cpu/nec/v25.cpp @@ -44,7 +44,7 @@ typedef uint32_t DWORD; #include "v25.h" #include "v25priv.h" -#include "nec_common.h" +#include "necdasm.h" DEFINE_DEVICE_TYPE(V25, v25_device, "v25", "V25") DEFINE_DEVICE_TYPE(V35, v35_device, "v35", "V35") @@ -142,8 +142,8 @@ uint8_t v25_common_device::fetch() uint16_t v25_common_device::fetchword() { - uint16_t r = FETCH(); - r |= (FETCH()<<8); + uint16_t r = fetch(); + r |= (fetch()<<8); return r; } @@ -419,9 +419,9 @@ void v25_common_device::execute_set_input(int irqline, int state) } } -offs_t v25_common_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *v25_common_device::create_disassembler() { - return necv_dasm_one(stream, pc, oprom, m_v25v35_decryptiontable); + return new nec_disassembler(m_v25v35_decryptiontable); } void v25_common_device::device_start() @@ -511,7 +511,7 @@ void v25_common_device::device_start() save_item(NAME(m_prefetch_reset)); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); m_pt_in.resolve_safe(0xff); diff --git a/src/devices/cpu/nec/v25.h b/src/devices/cpu/nec/v25.h index f0ccda61517..cda729e88ef 100644 --- a/src/devices/cpu/nec/v25.h +++ b/src/devices/cpu/nec/v25.h @@ -93,9 +93,7 @@ protected: virtual void state_export(const device_state_entry &entry) override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 8; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -143,7 +141,7 @@ private: uint32_t m_IDB; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_io; int m_icount; diff --git a/src/devices/cpu/nec/v25instr.hxx b/src/devices/cpu/nec/v25instr.hxx index 881f2044aae..e394e9ab213 100644 --- a/src/devices/cpu/nec/v25instr.hxx +++ b/src/devices/cpu/nec/v25instr.hxx @@ -1,7 +1,7 @@ // license:BSD-3-Clause // copyright-holders:Bryan McPhail, Alex W. Jackson #define GetRB \ - ModRM = FETCH(); \ + ModRM = fetch(); \ if (ModRM >= 0xc0) \ tmp = Wreg(Mod_RM.RM.w[ModRM]) & 0x7; \ else { \ @@ -43,7 +43,7 @@ } OP( 0x0f, i_pre_v25 ) { uint32_t ModRM, tmp, tmp2; - switch (FETCH()) { + switch (fetch()) { case 0x10 : BITOP_BYTE; CLKS(3,3,4); tmp2 = Breg(CL) & 0x7; m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */ case 0x11 : BITOP_WORD; CLKS(3,3,4); tmp2 = Breg(CL) & 0xf; m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */ case 0x12 : BITOP_BYTE; CLKS(5,5,4); tmp2 = Breg(CL) & 0x7; tmp &= ~(1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Clr */ @@ -53,24 +53,24 @@ OP( 0x0f, i_pre_v25 ) { uint32_t ModRM, tmp, tmp2; case 0x16 : BITOP_BYTE; CLKS(4,4,4); tmp2 = Breg(CL) & 0x7; BIT_NOT; PutbackRMByte(ModRM,tmp); break; /* Not */ case 0x17 : BITOP_WORD; CLKS(4,4,4); tmp2 = Breg(CL) & 0xf; BIT_NOT; PutbackRMWord(ModRM,tmp); break; /* Not */ - case 0x18 : BITOP_BYTE; CLKS(4,4,4); tmp2 = (FETCH()) & 0x7; m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */ - case 0x19 : BITOP_WORD; CLKS(4,4,4); tmp2 = (FETCH()) & 0xf; m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */ - case 0x1a : BITOP_BYTE; CLKS(6,6,4); tmp2 = (FETCH()) & 0x7; tmp &= ~(1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Clr */ - case 0x1b : BITOP_WORD; CLKS(6,6,4); tmp2 = (FETCH()) & 0xf; tmp &= ~(1<<tmp2); PutbackRMWord(ModRM,tmp); break; /* Clr */ - case 0x1c : BITOP_BYTE; CLKS(5,5,4); tmp2 = (FETCH()) & 0x7; tmp |= (1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Set */ - case 0x1d : BITOP_WORD; CLKS(5,5,4); tmp2 = (FETCH()) & 0xf; tmp |= (1<<tmp2); PutbackRMWord(ModRM,tmp); break; /* Set */ - case 0x1e : BITOP_BYTE; CLKS(5,5,4); tmp2 = (FETCH()) & 0x7; BIT_NOT; PutbackRMByte(ModRM,tmp); break; /* Not */ - case 0x1f : BITOP_WORD; CLKS(5,5,4); tmp2 = (FETCH()) & 0xf; BIT_NOT; PutbackRMWord(ModRM,tmp); break; /* Not */ + case 0x18 : BITOP_BYTE; CLKS(4,4,4); tmp2 = (fetch()) & 0x7; m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */ + case 0x19 : BITOP_WORD; CLKS(4,4,4); tmp2 = (fetch()) & 0xf; m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */ + case 0x1a : BITOP_BYTE; CLKS(6,6,4); tmp2 = (fetch()) & 0x7; tmp &= ~(1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Clr */ + case 0x1b : BITOP_WORD; CLKS(6,6,4); tmp2 = (fetch()) & 0xf; tmp &= ~(1<<tmp2); PutbackRMWord(ModRM,tmp); break; /* Clr */ + case 0x1c : BITOP_BYTE; CLKS(5,5,4); tmp2 = (fetch()) & 0x7; tmp |= (1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Set */ + case 0x1d : BITOP_WORD; CLKS(5,5,4); tmp2 = (fetch()) & 0xf; tmp |= (1<<tmp2); PutbackRMWord(ModRM,tmp); break; /* Set */ + case 0x1e : BITOP_BYTE; CLKS(5,5,4); tmp2 = (fetch()) & 0x7; BIT_NOT; PutbackRMByte(ModRM,tmp); break; /* Not */ + case 0x1f : BITOP_WORD; CLKS(5,5,4); tmp2 = (fetch()) & 0xf; BIT_NOT; PutbackRMWord(ModRM,tmp); break; /* Not */ case 0x20 : ADD4S; CLKS(7,7,2); break; case 0x22 : SUB4S; CLKS(7,7,2); break; case 0x25 : MOVSPA; CLK(16); break; case 0x26 : CMP4S; CLKS(7,7,2); break; - case 0x28 : ModRM = FETCH(); tmp = GetRMByte(ModRM); tmp <<= 4; tmp |= Breg(AL) & 0xf; Breg(AL) = (Breg(AL) & 0xf0) | ((tmp>>8)&0xf); tmp &= 0xff; PutbackRMByte(ModRM,tmp); CLKM(13,13,9,28,28,15); break; - case 0x2a : ModRM = FETCH(); tmp = GetRMByte(ModRM); tmp2 = (Breg(AL) & 0xf)<<4; Breg(AL) = (Breg(AL) & 0xf0) | (tmp&0xf); tmp = tmp2 | (tmp>>4); PutbackRMByte(ModRM,tmp); CLKM(17,17,13,32,32,19); break; + case 0x28 : ModRM = fetch(); tmp = GetRMByte(ModRM); tmp <<= 4; tmp |= Breg(AL) & 0xf; Breg(AL) = (Breg(AL) & 0xf0) | ((tmp>>8)&0xf); tmp &= 0xff; PutbackRMByte(ModRM,tmp); CLKM(13,13,9,28,28,15); break; + case 0x2a : ModRM = fetch(); tmp = GetRMByte(ModRM); tmp2 = (Breg(AL) & 0xf)<<4; Breg(AL) = (Breg(AL) & 0xf0) | (tmp&0xf); tmp = tmp2 | (tmp>>4); PutbackRMByte(ModRM,tmp); CLKM(17,17,13,32,32,19); break; case 0x2d : GetRB; nec_bankswitch(tmp); CLK(15); break; - case 0x31 : ModRM = FETCH(); ModRM=0; logerror("%06x: Unimplemented bitfield INS\n",PC()); break; - case 0x33 : ModRM = FETCH(); ModRM=0; logerror("%06x: Unimplemented bitfield EXT\n",PC()); break; + case 0x31 : ModRM = fetch(); ModRM=0; logerror("%06x: Unimplemented bitfield INS\n",PC()); break; + case 0x33 : ModRM = fetch(); ModRM=0; logerror("%06x: Unimplemented bitfield EXT\n",PC()); break; case 0x91 : RETRBI; CLK(12); break; case 0x92 : FINT; CLK(2); m_no_interrupt = 1; break; case 0x94 : GetRB; TSKSW; CLK(20); break; @@ -80,5 +80,5 @@ OP( 0x0f, i_pre_v25 ) { uint32_t ModRM, tmp, tmp2; } } -OP( 0x63, i_brkn ) { nec_interrupt(FETCH(), BRKN); CLKS(50,50,24); } -OP( 0xF1, i_brks ) { nec_interrupt(FETCH(), BRKS); CLKS(50,50,24); } +OP( 0x63, i_brkn ) { nec_interrupt(fetch(), BRKN); CLKS(50,50,24); } +OP( 0xF1, i_brks ) { nec_interrupt(fetch(), BRKS); CLKS(50,50,24); } diff --git a/src/devices/cpu/nec/v25priv.h b/src/devices/cpu/nec/v25priv.h index c9022898436..eb60c8f041d 100644 --- a/src/devices/cpu/nec/v25priv.h +++ b/src/devices/cpu/nec/v25priv.h @@ -121,7 +121,7 @@ enum BREGS { /************************************************************************/ -#define CHANGE_PC do { EMPTY_PREFETCH(); } while (0) +#define CHANGE_PC do { EMPTY_PREfetch(); } while (0) #define SegBase(Seg) (Sreg(Seg) << 4) @@ -135,15 +135,13 @@ enum BREGS { /* prefetch timing */ -#define FETCH() fetch() -#define FETCHWORD() fetchword() -#define EMPTY_PREFETCH() m_prefetch_reset = 1 +#define EMPTY_PREfetch() m_prefetch_reset = 1 #define PUSH(val) { Wreg(SP) -= 2; write_mem_word(((Sreg(SS)<<4)+Wreg(SP)), val); } #define POP(var) { Wreg(SP) += 2; var = read_mem_word(((Sreg(SS)<<4) + ((Wreg(SP)-2) & 0xffff))); } -#define GetModRM uint32_t ModRM=FETCH() +#define GetModRM uint32_t ModRM=fetch() /* Cycle count macros: CLK - cycle count is the same on all processors diff --git a/src/devices/cpu/patinhofeio/patinho_feio.cpp b/src/devices/cpu/patinhofeio/patinho_feio.cpp index 6c4b84c4410..d87379cc8fb 100644 --- a/src/devices/cpu/patinhofeio/patinho_feio.cpp +++ b/src/devices/cpu/patinhofeio/patinho_feio.cpp @@ -6,6 +6,7 @@ #include "emu.h" #include "patinhofeio_cpu.h" +#include "patinho_feio_dasm.h" #include "debugger.h" #include "includes/patinhofeio.h" // FIXME: this is a dependency from devices on MAME @@ -782,8 +783,7 @@ void patinho_feio_cpu_device::execute_instruction() printf("unimplemented opcode: 0x%02X\n", m_opcode); } -offs_t patinho_feio_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *patinho_feio_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( patinho_feio ); - return CPU_DISASSEMBLE_NAME(patinho_feio)(this, stream, pc, oprom, opram, options); + return new patinho_feio_disassembler; } diff --git a/src/devices/cpu/patinhofeio/patinho_feio_dasm.cpp b/src/devices/cpu/patinhofeio/patinho_feio_dasm.cpp index c655314f348..b3f66b3ae9b 100644 --- a/src/devices/cpu/patinhofeio/patinho_feio_dasm.cpp +++ b/src/devices/cpu/patinhofeio/patinho_feio_dasm.cpp @@ -1,27 +1,32 @@ // license:GPL-2.0+ // copyright-holders:Felipe Sanches #include "emu.h" -#include "cpu/patinhofeio/patinhofeio_cpu.h" +#include "patinho_feio_dasm.h" -CPU_DISASSEMBLE(patinho_feio) +u32 patinho_feio_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t patinho_feio_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { int addr, value, n, f; - switch (oprom[0] & 0xF0) { + switch (opcodes.r8(pc) & 0xF0) { case 0x00: //PLA = "Pula": Unconditionally JUMP to effective address - addr = (oprom[0] & 0x0F) << 8 | oprom[1]; + addr = (opcodes.r8(pc) & 0x0F) << 8 | opcodes.r8(pc+1); util::stream_format(stream, "PLA /%03X", addr); return 2; case 0x10: //PLAX = "Pulo indexado": Unconditionally JUMP to indexed address - addr = (oprom[0] & 0x0F) << 8 | oprom[1]; + addr = (opcodes.r8(pc) & 0x0F) << 8 | opcodes.r8(pc+1); util::stream_format(stream, "PLAX (IDX) + /%03X", addr); return 2; case 0x20: //ARM = "Armazena": Stores the contents of the // accumulator in the given 12bit address - addr = (oprom[0] & 0x0F) << 8 | oprom[1]; + addr = (opcodes.r8(pc) & 0x0F) << 8 | opcodes.r8(pc+1); if (addr==0){ util::stream_format(stream, "ARM (IDX)"); }else{ @@ -31,13 +36,13 @@ CPU_DISASSEMBLE(patinho_feio) case 0x30: //ARMX = "Armazenamento indexado": Stores the contents of the accumulator in the // given 12bit address (indexed by IDX) - addr = (oprom[0] & 0x0F) << 8 | oprom[1]; + addr = (opcodes.r8(pc) & 0x0F) << 8 | opcodes.r8(pc+1); util::stream_format(stream, "ARMX (IDX) + /%03X", addr); return 2; case 0x40: //CAR = "Carrega": Loads the contents of the given 12bit address // into the accumulator - addr = (oprom[0] & 0x0F) << 8 | oprom[1]; + addr = (opcodes.r8(pc) & 0x0F) << 8 | opcodes.r8(pc+1); if (addr==0){ util::stream_format(stream, "CAR (IDX)"); }else{ @@ -47,39 +52,39 @@ CPU_DISASSEMBLE(patinho_feio) case 0x50: //CARX = "Carga indexada": Loads the contents of the given 12bit address // (indexed by IDX) into the accumulator - addr = (oprom[0] & 0x0F) << 8 | oprom[1]; + addr = (opcodes.r8(pc) & 0x0F) << 8 | opcodes.r8(pc+1); util::stream_format(stream, "CARX (IDX) + /%03X", addr); return 2; case 0x60: //SOM = "Soma": Adds the contents of the given 12bit address // into the accumulator - addr = (oprom[0] & 0x0F) << 8 | oprom[1]; + addr = (opcodes.r8(pc) & 0x0F) << 8 | opcodes.r8(pc+1); util::stream_format(stream, "SOM /%03X", addr); return 2; case 0x70: //SOMX = "Soma indexada": Adds the contents of the given 12bit address // (indexed by IDX) into the accumulator - addr = (oprom[0] & 0x0F) << 8 | oprom[1]; + addr = (opcodes.r8(pc) & 0x0F) << 8 | opcodes.r8(pc+1); util::stream_format(stream, "SOMX (IDX) + /%03X", addr); return 2; case 0xA0: //PLAN = "Pula se ACC for negativo": Jumps to the 12bit address // if the accumulator is negative - addr = (oprom[0] & 0x0F) << 8 | oprom[1]; + addr = (opcodes.r8(pc) & 0x0F) << 8 | opcodes.r8(pc+1); util::stream_format(stream, "PLAN /%03X", addr); return 2; case 0xB0: //PLAZ = "Pula se ACC for zero": Jumps to the 12bit address // if the accumulator is zero - addr = (oprom[0] & 0x0F) << 8 | oprom[1]; + addr = (opcodes.r8(pc) & 0x0F) << 8 | opcodes.r8(pc+1); util::stream_format(stream, "PLAZ /%03X", addr); return 2; case 0xC0: - n = (oprom[0] & 0x0F); - f = (oprom[1] & 0x0F); + n = (opcodes.r8(pc) & 0x0F); + f = (opcodes.r8(pc+1) & 0x0F); n+= (n < 10) ? '0' : 'A'-10; f+= (f < 10) ? '0' : 'A'-10; - switch(oprom[1] & 0xF0) + switch(opcodes.r8(pc+1) & 0xF0) { case 0x10: util::stream_format(stream, "FNC /%c%c", n, f); return 2; case 0x20: util::stream_format(stream, "SAL /%c%c", n, f); return 2; @@ -88,11 +93,11 @@ CPU_DISASSEMBLE(patinho_feio) } break; case 0xD0: - value = oprom[1] & 0x0F; - switch (oprom[0] & 0x0F) + value = opcodes.r8(pc+1) & 0x0F; + switch (opcodes.r8(pc) & 0x0F) { case 0x01: - switch (oprom[1] & 0xF0) + switch (opcodes.r8(pc+1) & 0xF0) { case 0x00: util::stream_format(stream, "DD /%01X", value); return 2; //DD = "Deslocamento para a direita": Shift right case 0x10: util::stream_format(stream, "DDV /%01X", value); return 2; //DDV = "Deslocamento para a direita c/ V": Shift right with carry @@ -105,25 +110,25 @@ CPU_DISASSEMBLE(patinho_feio) case 0x80: util::stream_format(stream, "DDS /%01X", value); return 2; //DDS = "Deslocamento para a direita com duplicacao de sinal": Shift right with sign duplication } break; - case 0x02: util::stream_format(stream, "XOR /%02X", oprom[1]); return 2; //Logical XOR - case 0x04: util::stream_format(stream, "NAND /%02X", oprom[1]); return 2; //Logical NAND - case 0x08: util::stream_format(stream, "SOMI /%02X", oprom[1]); return 2; //SOMI = "Soma imediata": Add immediate value into accumulator - case 0x0A: util::stream_format(stream, "CARI /%02X", oprom[1]); return 2; //CARI = "Carrega imediato": Loads an immediate value into the accumulator + case 0x02: util::stream_format(stream, "XOR /%02X", opcodes.r8(pc+1)); return 2; //Logical XOR + case 0x04: util::stream_format(stream, "NAND /%02X", opcodes.r8(pc+1)); return 2; //Logical NAND + case 0x08: util::stream_format(stream, "SOMI /%02X", opcodes.r8(pc+1)); return 2; //SOMI = "Soma imediata": Add immediate value into accumulator + case 0x0A: util::stream_format(stream, "CARI /%02X", opcodes.r8(pc+1)); return 2; //CARI = "Carrega imediato": Loads an immediate value into the accumulator } break; case 0xE0: //SUS = "Subtrai um ou salta" - addr = (oprom[0] & 0x0F) << 8 | oprom[1]; + addr = (opcodes.r8(pc) & 0x0F) << 8 | opcodes.r8(pc+1); util::stream_format(stream, "SUS /%03X", addr); return 2; case 0xF0: //PUG = "Pula e guarda" - addr = (oprom[0] & 0x0F) << 8 | oprom[1]; + addr = (opcodes.r8(pc) & 0x0F) << 8 | opcodes.r8(pc+1); util::stream_format(stream, "PUG /%03X", addr); return 2; } - switch (oprom[0]) { + switch (opcodes.r8(pc)) { case 0x80: util::stream_format(stream, "LIMPO"); return 1; case 0x81: util::stream_format(stream, "UM"); return 1; case 0x82: util::stream_format(stream, "CMP1"); return 1; diff --git a/src/devices/cpu/patinhofeio/patinho_feio_dasm.h b/src/devices/cpu/patinhofeio/patinho_feio_dasm.h new file mode 100644 index 00000000000..0d950a3689c --- /dev/null +++ b/src/devices/cpu/patinhofeio/patinho_feio_dasm.h @@ -0,0 +1,19 @@ +// license:GPL-2.0+ +// copyright-holders:Felipe Sanches + +#ifndef MAME_CPU_PATINHOFEIO_PATINHO_FEIO_DASM_H +#define MAME_CPU_PATINHOFEIO_PATINHO_FEIO_DASM_H + +#pragma once + +class patinho_feio_disassembler : public util::disasm_interface +{ +public: + patinho_feio_disassembler() = default; + virtual ~patinho_feio_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/patinhofeio/patinhofeio_cpu.h b/src/devices/cpu/patinhofeio/patinhofeio_cpu.h index 07b402871d0..008acd8e0ae 100644 --- a/src/devices/cpu/patinhofeio/patinhofeio_cpu.h +++ b/src/devices/cpu/patinhofeio/patinhofeio_cpu.h @@ -65,7 +65,7 @@ public: protected: virtual void execute_run() override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; address_space_config m_program_config; @@ -121,10 +121,6 @@ protected: // device_memory_interface overrides virtual space_config_vector memory_space_config() const override; - // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 2; } - private: void execute_instruction(); void compute_effective_address(unsigned int addr); diff --git a/src/devices/cpu/pdp1/pdp1.cpp b/src/devices/cpu/pdp1/pdp1.cpp index 2a5368ae56f..73482e5b82d 100644 --- a/src/devices/cpu/pdp1/pdp1.cpp +++ b/src/devices/cpu/pdp1/pdp1.cpp @@ -342,6 +342,7 @@ #include "emu.h" #include "debugger.h" #include "pdp1.h" +#include "pdp1dasm.h" #define LOG 0 #define LOG_EXTRA 0 @@ -418,10 +419,9 @@ void pdp1_device::device_config_complete() } -offs_t pdp1_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *pdp1_device::create_disassembler() { - extern CPU_DISASSEMBLE( pdp1 ); - return CPU_DISASSEMBLE_NAME(pdp1)(this, stream, pc, oprom, opram, options); + return new pdp1_disassembler; } diff --git a/src/devices/cpu/pdp1/pdp1.h b/src/devices/cpu/pdp1/pdp1.h index 174317d995e..5a2df5fd91e 100644 --- a/src/devices/cpu/pdp1/pdp1.h +++ b/src/devices/cpu/pdp1/pdp1.h @@ -114,9 +114,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 4; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 4; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; diff --git a/src/devices/cpu/pdp1/pdp1dasm.cpp b/src/devices/cpu/pdp1/pdp1dasm.cpp index 7376b752538..9b04c91ec87 100644 --- a/src/devices/cpu/pdp1/pdp1dasm.cpp +++ b/src/devices/cpu/pdp1/pdp1dasm.cpp @@ -1,13 +1,10 @@ // license:BSD-3-Clause // copyright-holders:Raphael Nabet #include "emu.h" -#include "cpu/pdp1/pdp1.h" +#include "pdp1dasm.h" +#include "pdp1.h" -/* PDP1 registers */ -static int ib; -static int y; - -static inline void ea (void) +inline void pdp1_disassembler::ea() { /* while (1) { @@ -20,15 +17,20 @@ static inline void ea (void) #define IN if (ib) util::stream_format(stream, " i") -CPU_DISASSEMBLE(pdp1) +u32 pdp1_disassembler::opcode_alignment() const +{ + return 4; +} + +offs_t pdp1_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { int md; //int etime = 0; - md = oprom[0] << 24 | oprom[1] << 16 | oprom[2] << 8 | oprom[3]; + md = opcodes.r32(pc); - y = md & 07777; - ib = (md >> 12) & 1; /* */ + int y = md & 07777; + int ib = (md >> 12) & 1; /* */ switch (md >> 13) { case pdp1_device::AND: diff --git a/src/devices/cpu/pdp1/pdp1dasm.h b/src/devices/cpu/pdp1/pdp1dasm.h new file mode 100644 index 00000000000..e5dd4b0f031 --- /dev/null +++ b/src/devices/cpu/pdp1/pdp1dasm.h @@ -0,0 +1,22 @@ +// license:BSD-3-Clause +// copyright-holders:Raphael Nabet + +#ifndef MAME_CPU_PDP1_PDP1DASM_H +#define MAME_CPU_PDP1_PDP1DASM_H + +#pragma once + +class pdp1_disassembler : public util::disasm_interface +{ +public: + pdp1_disassembler() = default; + virtual ~pdp1_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + void ea(); +}; + +#endif diff --git a/src/devices/cpu/pdp1/tx0.cpp b/src/devices/cpu/pdp1/tx0.cpp index 89355ee2ef8..376cf15a346 100644 --- a/src/devices/cpu/pdp1/tx0.cpp +++ b/src/devices/cpu/pdp1/tx0.cpp @@ -12,6 +12,7 @@ #include "emu.h" #include "tx0.h" +#include "tx0dasm.h" #include "debugger.h" #define LOG 0 @@ -1075,15 +1076,12 @@ void tx0_device::io_complete() } -offs_t tx0_8kw_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *tx0_8kw_device::create_disassembler() { - extern CPU_DISASSEMBLE( tx0_8kw ); - return CPU_DISASSEMBLE_NAME(tx0_8kw)(this, stream, pc, oprom, opram, options); + return new tx0_8kw_disassembler; } - -offs_t tx0_64kw_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *tx0_64kw_device::create_disassembler() { - extern CPU_DISASSEMBLE( tx0_64kw ); - return CPU_DISASSEMBLE_NAME(tx0_64kw)(this, stream, pc, oprom, opram, options); + return new tx0_64kw_disassembler; } diff --git a/src/devices/cpu/pdp1/tx0.h b/src/devices/cpu/pdp1/tx0.h index 52cc7f4091a..e9174a46413 100644 --- a/src/devices/cpu/pdp1/tx0.h +++ b/src/devices/cpu/pdp1/tx0.h @@ -67,10 +67,6 @@ protected: // device_memory_interface overrides virtual space_config_vector memory_space_config() const override; - // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 4; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 4; } - protected: address_space_config m_program_config; @@ -151,7 +147,7 @@ public: protected: virtual void execute_run() override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: void execute_instruction_8kw(); @@ -166,7 +162,7 @@ public: protected: virtual void execute_run() override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: void execute_instruction_64kw(); diff --git a/src/devices/cpu/pdp1/tx0dasm.cpp b/src/devices/cpu/pdp1/tx0dasm.cpp index cda24ed930c..34d49194ed3 100644 --- a/src/devices/cpu/pdp1/tx0dasm.cpp +++ b/src/devices/cpu/pdp1/tx0dasm.cpp @@ -1,14 +1,19 @@ // license:BSD-3-Clause // copyright-holders:Raphael Nabet #include "emu.h" -#include "cpu/pdp1/tx0.h" +#include "tx0dasm.h" -CPU_DISASSEMBLE(tx0_64kw) +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) { int md; int x; - md = oprom[0] << 24 | oprom[1] << 16 | oprom[2] << 8 | oprom[3]; + md = opcodes.r32(pc); x = md & 0177777; switch (md >> 16) @@ -29,12 +34,17 @@ CPU_DISASSEMBLE(tx0_64kw) return 1; } -CPU_DISASSEMBLE(tx0_8kw) +u32 tx0_8kw_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t tx0_8kw_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { int md; int x; - md = oprom[0] << 24 | oprom[1] << 16 | oprom[2] << 8 | oprom[3]; + md = opcodes.r32(pc); x = md & 0017777; switch (md >> 13) diff --git a/src/devices/cpu/pdp1/tx0dasm.h b/src/devices/cpu/pdp1/tx0dasm.h new file mode 100644 index 00000000000..ae97e2bcc1d --- /dev/null +++ b/src/devices/cpu/pdp1/tx0dasm.h @@ -0,0 +1,29 @@ +// license:BSD-3-Clause +// copyright-holders:Raphael Nabet + +#ifndef MAME_CPU_PDP1_TX0DASM_H +#define MAME_CPU_PDP1_TX0DASM_H + +#pragma once + +class tx0_64kw_disassembler : public util::disasm_interface +{ +public: + tx0_64kw_disassembler() = default; + virtual ~tx0_64kw_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +class tx0_8kw_disassembler : public util::disasm_interface +{ +public: + tx0_8kw_disassembler() = default; + virtual ~tx0_8kw_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/pdp8/pdp8.cpp b/src/devices/cpu/pdp8/pdp8.cpp index 1a9150a236d..b3ade64fc75 100644 --- a/src/devices/cpu/pdp8/pdp8.cpp +++ b/src/devices/cpu/pdp8/pdp8.cpp @@ -9,8 +9,7 @@ #include "emu.h" #include "debugger.h" #include "pdp8.h" - -CPU_DISASSEMBLE( pdp8 ); +#include "pdp8dasm.h" #define OP ((op >> 011) & 07) @@ -148,36 +147,13 @@ void pdp8_device::state_string_export(const device_state_entry &entry, std::stri //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t pdp8_device::disasm_min_opcode_bytes() const -{ - return 2; -} - - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t pdp8_device::disasm_max_opcode_bytes() const -{ - return 2; -} - - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t pdp8_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *pdp8_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( pdp8 ); - return CPU_DISASSEMBLE_NAME(pdp8)(this, stream, pc, oprom, opram, options); + return new pdp8_disassembler; } diff --git a/src/devices/cpu/pdp8/pdp8.h b/src/devices/cpu/pdp8/pdp8.h index b21371fd181..c6dc47ce56f 100644 --- a/src/devices/cpu/pdp8/pdp8.h +++ b/src/devices/cpu/pdp8/pdp8.h @@ -40,9 +40,7 @@ public: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // device_state_interface overrides virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; diff --git a/src/devices/cpu/pdp8/pdp8dasm.cpp b/src/devices/cpu/pdp8/pdp8dasm.cpp index 5c2219af4f8..389cf11fda7 100644 --- a/src/devices/cpu/pdp8/pdp8dasm.cpp +++ b/src/devices/cpu/pdp8/pdp8dasm.cpp @@ -7,9 +7,16 @@ */ #include "emu.h" +#include "pdp8dasm.h" -static offs_t pdp8_dasm_one(std::ostream &stream, offs_t pc, uint16_t op) +u32 pdp8_disassembler::opcode_alignment() const { + return 2; +} + +offs_t pdp8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + uint16_t op = opcodes.r16(pc); uint8_t opcode = (op >> 011) & 07; uint16_t current_page = pc & 07600; uint16_t zero_addr = op & 0177; @@ -157,15 +164,5 @@ static offs_t pdp8_dasm_one(std::ostream &stream, offs_t pc, uint16_t op) } } - return 2 | DASMFLAG_SUPPORTED; -} - - -/*****************************************************************************/ - -CPU_DISASSEMBLE( pdp8 ) -{ - uint16_t op = (*(uint8_t *)(opram + 0) << 8) | - (*(uint8_t *)(opram + 1) << 0); - return pdp8_dasm_one(stream, pc, op); + return 2 | SUPPORTED; } diff --git a/src/devices/cpu/pdp8/pdp8dasm.h b/src/devices/cpu/pdp8/pdp8dasm.h new file mode 100644 index 00000000000..df6c92e9ddb --- /dev/null +++ b/src/devices/cpu/pdp8/pdp8dasm.h @@ -0,0 +1,24 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + First-gen DEC PDP-8 disassembler + + Written by Ryan Holtz +*/ + +#ifndef MAME_CPU_PDP8_PDP8DASM_H +#define MAME_CPU_PDP8_PDP8DASM_H + +#pragma once + +class pdp8_disassembler : public util::disasm_interface +{ +public: + pdp8_disassembler() = default; + virtual ~pdp8_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/pic16c5x/16c5xdsm.cpp b/src/devices/cpu/pic16c5x/16c5xdsm.cpp index 03cd0539c8c..4768cbb12e8 100644 --- a/src/devices/cpu/pic16c5x/16c5xdsm.cpp +++ b/src/devices/cpu/pic16c5x/16c5xdsm.cpp @@ -24,86 +24,60 @@ \**************************************************************************/ #include "emu.h" +#include "16c5xdsm.h" #include <ctype.h> -static const uint8_t *rombase; -static const uint8_t *rambase; -static offs_t pcbase; -#define READOP16(A) (rombase[(A) - pcbase] | (rombase[(A) + 1 - pcbase] << 8)) -#define READARG16(A) (rambase[(A) - pcbase] | (rambase[(A) + 1 - pcbase] << 8)) - - - -typedef unsigned char byte; -typedef unsigned short int word; - -#define FMT(a,b) a, b -#define PTRS_PER_FORMAT 2 - -static const char *const regfile[32] = { "Reg$00 (IND)", "Reg$01 (TMR)", "Reg$02 (PCL)", "Reg$03 (ST)", "Reg$04 (FSR)", "Reg$05 (PTA)", "Reg$06 (PTB)", "Reg$07 (PTC)", +const char *const pic16c5x_disassembler::regfile[32] = { "Reg$00 (IND)", "Reg$01 (TMR)", "Reg$02 (PCL)", "Reg$03 (ST)", "Reg$04 (FSR)", "Reg$05 (PTA)", "Reg$06 (PTB)", "Reg$07 (PTC)", "Reg$08", "Reg$09", "Reg$0A", "Reg$0B", "Reg$0C", "Reg$0D", "Reg$0E", "Reg$0F", "Reg$10", "Reg$11", "Reg$12", "Reg$13", "Reg$14", "Reg$15", "Reg$16", "Reg$17", "Reg$18", "Reg$19", "Reg$1A", "Reg$1B", "Reg$1C", "Reg$1D", "Reg$1E", "Reg$1F" }; -static const char *const dest[2] = { "W", "Reg" }; - -static const char *const PIC16C5xFormats[] = { - FMT("000000000000", "nop"), - FMT("000000000010", "option"), - FMT("000000000011", "sleep"), - FMT("000000000100", "clrwdt"), - FMT("000000000101", "tris Port A"), - FMT("000000000110", "tris Port B"), - FMT("000000000111", "tris Port C"), - FMT("0000001fffff", "movwf %F"), - FMT("000001000000", "clrw"), - FMT("0000011fffff", "clrf %F"), - FMT("000010dfffff", "subwf %F,%D"), - FMT("000011dfffff", "decf %F,%D"), - FMT("000100dfffff", "iorwf %F,%D"), - FMT("000101dfffff", "andwf %F,%D"), - FMT("000110dfffff", "xorwf %F,%D"), - FMT("000111dfffff", "addwf %F,%D"), - FMT("001000dfffff", "movf %F,%D"), - FMT("001001dfffff", "comf %F,%D"), - FMT("001010dfffff", "incf %F,%D"), - FMT("001011dfffff", "decfsz %F,%D"), - FMT("001100dfffff", "rrf %F,%D"), - FMT("001101dfffff", "rlf %F,%D"), - FMT("001110dfffff", "swapf %F,%D"), - FMT("001111dfffff", "incfsz %F,%D"), - FMT("0100bbbfffff", "bcf %F,%B"), - FMT("0101bbbfffff", "bsf %F,%B"), - FMT("0110bbbfffff", "btfsc %F,%B"), - FMT("0111bbbfffff", "btfss %F,%B"), - FMT("1000kkkkkkkk", "retlw %K"), - FMT("1001aaaaaaaa", "call %A"), - FMT("101aaaaaaaaa", "goto %A"), - FMT("1100kkkkkkkk", "movlw %K"), - FMT("1101kkkkkkkk", "iorlw %K"), - FMT("1110kkkkkkkk", "andlw %K"), - FMT("1111kkkkkkkk", "xorlw %K"), +const char *const pic16c5x_disassembler::dest[2] = { "W", "Reg" }; + +const char *const pic16c5x_disassembler::PIC16C5xFormats[] = { + "000000000000", "nop", + "000000000010", "option", + "000000000011", "sleep", + "000000000100", "clrwdt", + "000000000101", "tris Port A", + "000000000110", "tris Port B", + "000000000111", "tris Port C", + "0000001fffff", "movwf %F", + "000001000000", "clrw", + "0000011fffff", "clrf %F", + "000010dfffff", "subwf %F,%D", + "000011dfffff", "decf %F,%D", + "000100dfffff", "iorwf %F,%D", + "000101dfffff", "andwf %F,%D", + "000110dfffff", "xorwf %F,%D", + "000111dfffff", "addwf %F,%D", + "001000dfffff", "movf %F,%D", + "001001dfffff", "comf %F,%D", + "001010dfffff", "incf %F,%D", + "001011dfffff", "decfsz %F,%D", + "001100dfffff", "rrf %F,%D", + "001101dfffff", "rlf %F,%D", + "001110dfffff", "swapf %F,%D", + "001111dfffff", "incfsz %F,%D", + "0100bbbfffff", "bcf %F,%B", + "0101bbbfffff", "bsf %F,%B", + "0110bbbfffff", "btfsc %F,%B", + "0111bbbfffff", "btfss %F,%B", + "1000kkkkkkkk", "retlw %K", + "1001aaaaaaaa", "call %A", + "101aaaaaaaaa", "goto %A", + "1100kkkkkkkk", "movlw %K", + "1101kkkkkkkk", "iorlw %K", + "1110kkkkkkkk", "andlw %K", + "1111kkkkkkkk", "xorlw %K", nullptr }; -#define MAX_OPS ((ARRAY_LENGTH(PIC16C5xFormats) - 1) / PTRS_PER_FORMAT) - -struct PIC16C5xOpcode { - word mask; /* instruction mask */ - word bits; /* constant bits */ - word extcode; /* value that gets extension code */ - const char *parse; /* how to parse bits */ - const char *fmt; /* instruction format */ -}; - -static PIC16C5xOpcode Op[MAX_OPS+1]; -static int OpInizialized = 0; - -static void InitDasm16C5x(void) +pic16c5x_disassembler::pic16c5x_disassembler() { const char *p; const char *const *ops; - word mask, bits; + u16 mask, bits; int bit; int i; @@ -136,20 +110,14 @@ static void InitDasm16C5x(void) ops[0],ops[1],bit); } while (isspace((uint8_t)*p)) p++; - if (*p) Op[i].extcode = *p; - Op[i].bits = bits; - Op[i].mask = mask; - Op[i].fmt = ops[1]; - Op[i].parse = ops[0]; + Op.emplace_back(mask, bits, *p, ops[0], ops[1]); - ops += PTRS_PER_FORMAT; + ops += 2; i++; } - - OpInizialized = 1; } -CPU_DISASSEMBLE(pic16c5x) +offs_t pic16c5x_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { int a, b, d, f, k; /* these can all be filled in by parsing an instruction */ int i; @@ -161,15 +129,9 @@ CPU_DISASSEMBLE(pic16c5x) const char *cp; /* character pointer in OpFormats */ uint32_t flags = 0; - rombase = oprom; - rambase = opram; - pcbase = 2*pc; - - if (!OpInizialized) InitDasm16C5x(); - op = -1; /* no matching opcode */ - code = READOP16(2*pc); - for ( i = 0; i < MAX_OPS; i++) + code = opcodes.r16(pc); + for ( i = 0; i < int(Op.size()); i++) { if ((code & Op[i].mask) == Op[i].bits) { @@ -184,14 +146,14 @@ CPU_DISASSEMBLE(pic16c5x) if (op == -1) { util::stream_format(stream, "???? dw %04Xh",code); - return cnt; + return cnt | SUPPORTED; } //buffertmp = buffer; if (Op[op].extcode) /* Actually, theres no double length opcodes */ { bit = 27; code <<= 16; - code |= READARG16(2*(pc+cnt)); + code |= params.r16(pc+cnt); cnt++; } else @@ -223,9 +185,9 @@ CPU_DISASSEMBLE(pic16c5x) /* now traverse format string */ cp = Op[op].fmt; if (!strncmp(cp, "call", 4)) - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; else if (!strncmp(cp, "ret", 3)) - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; while (*cp) { @@ -248,5 +210,10 @@ CPU_DISASSEMBLE(pic16c5x) stream << *cp++; } } - return cnt | flags | DASMFLAG_SUPPORTED; + return cnt | flags | SUPPORTED; +} + +uint32_t pic16c5x_disassembler::opcode_alignment() const +{ + return 1; } diff --git a/src/devices/cpu/pic16c5x/16c5xdsm.h b/src/devices/cpu/pic16c5x/16c5xdsm.h new file mode 100644 index 00000000000..de3c8b4425f --- /dev/null +++ b/src/devices/cpu/pic16c5x/16c5xdsm.h @@ -0,0 +1,58 @@ +// license:BSD-3-Clause +// copyright-holders:Tony La Porta + /**************************************************************************\ + * Microchip PIC16C5x Emulator * + * * + * Copyright Tony La Porta * + * Originally written for the MAME project. * + * * + * * + * Addressing architecture is based on the Harvard addressing scheme. * + * * + * Many thanks to those involved in the i8039 Disassembler * + * as this was based on it. * + * * + * * + * * + * A Address to jump to. * + * B Bit address within an 8-bit file register. * + * D Destination select (0 = store result in W (accumulator)) * + * (1 = store result in file register) * + * F Register file address (00-1F). * + * K Literal field, constant data. * + * * + \**************************************************************************/ + +#ifndef MAME_CPU_PIC16C5X_16C5XDSM_H +#define MAME_CPU_PIC16C5X_16C5XDSM_H + +#pragma once + +class pic16c5x_disassembler : public util::disasm_interface +{ +public: + pic16c5x_disassembler(); + virtual ~pic16c5x_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + struct PIC16C5xOpcode { + u16 mask; /* instruction mask */ + u16 bits; /* constant bits */ + u16 extcode; /* value that gets extension code */ + const char *parse; /* how to parse bits */ + const char *fmt; /* instruction format */ + + PIC16C5xOpcode(u16 m, u16 b, u16 e, const char *p, const char *f) : mask(m), bits(b), extcode(e), parse(p), fmt(f) {} + }; + + static const char *const regfile[32]; + static const char *const dest[2]; + static const char *const PIC16C5xFormats[]; + + std::vector<PIC16C5xOpcode> Op; +}; + +#endif diff --git a/src/devices/cpu/pic16c5x/dis16c5x.cpp b/src/devices/cpu/pic16c5x/dis16c5x.cpp deleted file mode 100644 index 08c7f2657df..00000000000 --- a/src/devices/cpu/pic16c5x/dis16c5x.cpp +++ /dev/null @@ -1,136 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Tony La Porta - /**************************************************************************\ - * Microchip PIC16C5x Emulator * - * * - * Copyright Tony La Porta * - * Originally written for the MAME project. * - * * - * * - * Notes : Data is expected to be read from source file as LSB first. * - * * - \**************************************************************************/ - -#include <stdio.h> -#include <string.h> - -#include "16c5xdsm.c" - - -unsigned char *Buffer; - - -int main(int argc,char *argv[]) -{ - int length=0, length_to_dump=0, offset=0, disasm_words=0; - int filelength=0, bytes_read; - int Counter=0; - - FILE *F; - char *String_Output; - - if(argc<2) - { - printf("\n"); - printf("PIC16C5x Disassembler 1.0 by Tony La Porta (C)2003+\n\n"); - printf("Usage: dis16c5x <input-file> [ <start-addr> [ <num-of-addr> ] ]\n"); - printf(" <input-file> source file data must be MSB first\n"); - printf(" <start-addr> starting address to disassemble from (decimal)\n"); - printf(" <num-of-addr> number of addresses to disassemble (decimal)\n"); - printf(" Precede values with 0x if HEX values preffered\n"); - exit(1); - } - - if(!(F=fopen(argv[1],"rb"))) - { - printf("\n%s: Can't open file %s\n",argv[0],argv[1]); - exit(2); - } - argv++; argc--; - if (argv[1]) - { - offset = strtol(argv[1],nullptr,0); - argv++; argc--; - } - if (argv[1]) - { - length = strtol(argv[1],nullptr,0); - argv++; argc--; - } - - fseek(F,0, SEEK_END); - filelength = ftell(F); - - length *= 2; - - if ((length > (filelength - (offset*2))) || (length == 0)) length = filelength - (offset*2); - printf("Length=%04Xh(words) Offset=$%04Xh filelength=%04Xh(words) %04Xh(bytes)\n",length/2,offset,filelength/2,filelength); - length_to_dump = length; - printf("Starting from %d, dumping %d opcodes (word size)\n",offset,length/2); - Buffer = calloc((filelength+1),sizeof(char)); - if (Buffer==nullptr) - { - printf("Out of Memory !!!"); - fclose(F); - exit(3); - } - String_Output = calloc(80,sizeof(char)); - if (String_Output==nullptr) - { - printf("Out of Memory !!!"); - free(Buffer); - fclose(F); - exit(4); - } - - if (fseek(F,0,SEEK_SET) != 0) - { - printf("Error seeking to beginning of file\n"); - free(String_Output); - free(Buffer); - fclose(F); - exit(5); - } - - Counter = offset; - bytes_read = fread(Buffer,sizeof(char),filelength,F); - if (bytes_read >= length) - { - for (; length > 0; length -= (disasm_words*2)) - { - int ii; - disasm_words = Dasm16C5x(String_Output,Counter); - printf("$%03X: ",Counter); - for (ii = 0; ii < disasm_words; ii++) - { - if (((Counter*2) + ii) > filelength) /* Past end of length to dump ? */ - { - sprintf(String_Output,"???? dw %02.2X%02.2Xh (Past end of disassembly !)",Buffer[((Counter-1)*2)+1],Buffer[((Counter-1)*2)]); - } - else - { - printf("%02.2x%02.2x ",Buffer[(Counter*2)+1],Buffer[(Counter*2)]); - } - Counter++ ; - } - for (; ii < 4; ii++) - { - printf(" "); - } - printf("\t%s\n",String_Output); - } - } - else - { - printf("ERROR length to dump was %d ", length_to_dump/2); - printf(", but bytes read from file were %d\n", bytes_read/2); - free(String_Output); - free(Buffer); - fclose(F); - exit(7); - } - free(String_Output); - free(Buffer); - fclose(F); - return(0); -} diff --git a/src/devices/cpu/pic16c5x/pic16c5x.cpp b/src/devices/cpu/pic16c5x/pic16c5x.cpp index 52a9beeac77..d92ae93d3c1 100644 --- a/src/devices/cpu/pic16c5x/pic16c5x.cpp +++ b/src/devices/cpu/pic16c5x/pic16c5x.cpp @@ -73,6 +73,7 @@ #include "emu.h" #include "pic16c5x.h" +#include "16c5xdsm.h" #include "debugger.h" @@ -183,10 +184,9 @@ device_memory_interface::space_config_vector pic16c5x_device::memory_space_confi }; } -offs_t pic16c5x_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *pic16c5x_device::create_disassembler() { - extern CPU_DISASSEMBLE( pic16c5x ); - return CPU_DISASSEMBLE_NAME(pic16c5x)(this, stream, pc, oprom, opram, options); + return new pic16c5x_disassembler; } @@ -197,7 +197,7 @@ void pic16c5x_device::update_internalram_ptr() -#define PIC16C5x_RDOP(A) (m_direct->read_word((A)<<1)) +#define PIC16C5x_RDOP(A) (m_direct->read_word(A)) #define PIC16C5x_RAM_RDMEM(A) ((uint8_t)m_data->read_byte(A)) #define PIC16C5x_RAM_WRMEM(A,V) (m_data->write_byte(A,V)) @@ -883,7 +883,7 @@ enum void pic16c5x_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<-1>(); m_data = &space(AS_DATA); m_read_a.resolve_safe(0); diff --git a/src/devices/cpu/pic16c5x/pic16c5x.h b/src/devices/cpu/pic16c5x/pic16c5x.h index 593397e4847..e51ef9a1c89 100644 --- a/src/devices/cpu/pic16c5x/pic16c5x.h +++ b/src/devices/cpu/pic16c5x/pic16c5x.h @@ -133,9 +133,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 2; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -169,7 +167,7 @@ private: int m_inst_cycles; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<-1> *m_direct; address_space *m_data; // i/o handlers diff --git a/src/devices/cpu/pic16c62x/16c62xdsm.cpp b/src/devices/cpu/pic16c62x/16c62xdsm.cpp index f9fb88a88d1..69072a4ada9 100644 --- a/src/devices/cpu/pic16c62x/16c62xdsm.cpp +++ b/src/devices/cpu/pic16c62x/16c62xdsm.cpp @@ -27,93 +27,68 @@ \**************************************************************************/ #include "emu.h" -#include <ctype.h> - -static const uint8_t *rombase; -static const uint8_t *rambase; -static offs_t pcbase; -#define READOP16(A) (rombase[(A) - pcbase] | (rombase[(A) + 1 - pcbase] << 8)) -#define READARG16(A) (rambase[(A) - pcbase] | (rambase[(A) + 1 - pcbase] << 8)) - - - -typedef unsigned char byte; -typedef unsigned short int word; +#include "16c62xdsm.h" -#define FMT(a,b) a, b -#define PTRS_PER_FORMAT 2 +#include <ctype.h> /* Registers bank 0/1 */ -static const char *const regfile[32] = { "Reg$00 (INDF)", "Reg$01 (TMR0/OPTION)", "Reg$02 (PCL)", "Reg$03 (STATUS)", "Reg$04 (FSR)", "Reg$05 (PORTA/TRISA)", "Reg$06 (PORTB/TRISB)", "Reg$07", +const char *const pic16c62x_disassembler::regfile[32] = { "Reg$00 (INDF)", "Reg$01 (TMR0/OPTION)", "Reg$02 (PCL)", "Reg$03 (STATUS)", "Reg$04 (FSR)", "Reg$05 (PORTA/TRISA)", "Reg$06 (PORTB/TRISB)", "Reg$07", "Reg$08", "Reg$09", "Reg$0A (PCLATH)", "Reg$0B (INTCON)", "Reg$0C (PIR1/PIE1)", "Reg$0D", "Reg$0E (none/PCON)", "Reg$0F", "Reg$10", "Reg$11", "Reg$12", "Reg$13", "Reg$14", "Reg$15", "Reg$16", "Reg$17", "Reg$18", "Reg$19", "Reg$1A", "Reg$1B", "Reg$1C", "Reg$1D", "Reg$1E", "Reg$1F (CMCON/VRCON)" }; /* Registers bank 1 */ -/*static const char *const regfile1[32] = { "Reg$00 (INDF)", "Reg$01 (OPTION)", "Reg$02 (PCL)", "Reg$03 (STATUS)", "Reg$04 (FSR)", "Reg$05 (TRISA)", "Reg$06 (TRISB)", "Reg$07", +/*const char *const regfile1[32] = { "Reg$00 (INDF)", "Reg$01 (OPTION)", "Reg$02 (PCL)", "Reg$03 (STATUS)", "Reg$04 (FSR)", "Reg$05 (TRISA)", "Reg$06 (TRISB)", "Reg$07", "Reg$08", "Reg$09", "Reg$0A (PCLATH)", "Reg$0B (INTCON)", "Reg$0C (PIE1)", "Reg$0D", "Reg$0E (PCON)", "Reg$0F", "Reg$10", "Reg$11", "Reg$12", "Reg$13", "Reg$14", "Reg$15", "Reg$16", "Reg$17", "Reg$18", "Reg$19", "Reg$1A", "Reg$1B", "Reg$1C", "Reg$1D", "Reg$1E", "Reg$1F (VRCON)" }; -static const char **regfile[2] = { regfile0, regfile1 };*/ - -static const char *const dest[2] = { "W", "Reg" }; - -static const char *const PIC16C62xFormats[] = { - FMT("0000000xx00000", "nop"), - FMT("00000000001000", "return"), - FMT("00000000001001", "retfie"), - FMT("00000001100011", "sleep"), - FMT("00000001100100", "clrwdt"), - FMT("0000001fffffff", "movwf %F"), - FMT("00000100000011", "clrw"), - FMT("0000011fffffff", "clrf %F"), - FMT("000010dfffffff", "subwf %F,%D"), - FMT("000011dfffffff", "decf %F,%D"), - FMT("000100dfffffff", "iorwf %F,%D"), - FMT("000101dfffffff", "andwf %F,%D"), - FMT("000110dfffffff", "xorwf %F,%D"), - FMT("000111dfffffff", "addwf %F,%D"), - FMT("001000dfffffff", "movf %F,%D"), - FMT("001001dfffffff", "comf %F,%D"), - FMT("001010dfffffff", "incf %F,%D"), - FMT("001011dfffffff", "decfsz %F,%D"), - FMT("001100dfffffff", "rrf %F,%D"), - FMT("001101dfffffff", "rlf %F,%D"), - FMT("001110dfffffff", "swapf %F,%D"), - FMT("001111dfffffff", "incfsz %F,%D"), - FMT("0100bbbfffffff", "bcf %F,%B"), - FMT("0101bbbfffffff", "bsf %F,%B"), - FMT("0110bbbfffffff", "btfsc %F,%B"), - FMT("0111bbbfffffff", "btfss %F,%B"), - FMT("1101xxkkkkkkkk", "retlw %K"), - FMT("100aaaaaaaaaaa", "call %A"), - FMT("101aaaaaaaaaaa", "goto %A"), - FMT("1100xxkkkkkkkk", "movlw %K"), - FMT("111000kkkkkkkk", "iorlw %K"), - FMT("111001kkkkkkkk", "andlw %K"), - FMT("111010kkkkkkkk", "xorlw %K"), - FMT("11110xkkkkkkkk", "sublw %K"), - FMT("11111xkkkkkkkk", "addlw %K"), +const char **regfile[2] = { regfile0, regfile1 };*/ + +const char *const pic16c62x_disassembler::dest[2] = { "W", "Reg" }; + +const char *const pic16c62x_disassembler::PIC16C62xFormats[] = { + "0000000xx00000", "nop", + "00000000001000", "return", + "00000000001001", "retfie", + "00000001100011", "sleep", + "00000001100100", "clrwdt", + "0000001fffffff", "movwf %F", + "00000100000011", "clrw", + "0000011fffffff", "clrf %F", + "000010dfffffff", "subwf %F,%D", + "000011dfffffff", "decf %F,%D", + "000100dfffffff", "iorwf %F,%D", + "000101dfffffff", "andwf %F,%D", + "000110dfffffff", "xorwf %F,%D", + "000111dfffffff", "addwf %F,%D", + "001000dfffffff", "movf %F,%D", + "001001dfffffff", "comf %F,%D", + "001010dfffffff", "incf %F,%D", + "001011dfffffff", "decfsz %F,%D", + "001100dfffffff", "rrf %F,%D", + "001101dfffffff", "rlf %F,%D", + "001110dfffffff", "swapf %F,%D", + "001111dfffffff", "incfsz %F,%D", + "0100bbbfffffff", "bcf %F,%B", + "0101bbbfffffff", "bsf %F,%B", + "0110bbbfffffff", "btfsc %F,%B", + "0111bbbfffffff", "btfss %F,%B", + "1101xxkkkkkkkk", "retlw %K", + "100aaaaaaaaaaa", "call %A", + "101aaaaaaaaaaa", "goto %A", + "1100xxkkkkkkkk", "movlw %K", + "111000kkkkkkkk", "iorlw %K", + "111001kkkkkkkk", "andlw %K", + "111010kkkkkkkk", "xorlw %K", + "11110xkkkkkkkk", "sublw %K", + "11111xkkkkkkkk", "addlw %K", nullptr }; -#define MAX_OPS ((ARRAY_LENGTH(PIC16C62xFormats) - 1) / PTRS_PER_FORMAT) - -struct PIC16C62xOpcode { - word mask; /* instruction mask */ - word bits; /* constant bits */ - word extcode; /* value that gets extension code */ - const char *parse; /* how to parse bits */ - const char *fmt; /* instruction format */ -}; - -static PIC16C62xOpcode Op[MAX_OPS+1]; -static int OpInizialized = 0; - -static void InitDasm16C5x(void) +pic16c62x_disassembler::pic16c62x_disassembler() { const char *p; const char *const *ops; - word mask, bits; + u16 mask, bits; int bit; int i; @@ -147,20 +122,15 @@ static void InitDasm16C5x(void) ops[0],ops[1],bit); } while (isspace((uint8_t)*p)) p++; - if (*p) Op[i].extcode = *p; - Op[i].bits = bits; - Op[i].mask = mask; - Op[i].fmt = ops[1]; - Op[i].parse = ops[0]; + Op.emplace_back(mask, bits, *p, ops[0], ops[1]); - ops += PTRS_PER_FORMAT; + ops += 2; i++; } - OpInizialized = 1; } -CPU_DISASSEMBLE(pic16c62x) +offs_t pic16c62x_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { int a, b, d, f, k; /* these can all be filled in by parsing an instruction */ int i; @@ -172,15 +142,9 @@ CPU_DISASSEMBLE(pic16c62x) const char *cp; /* character pointer in OpFormats */ uint32_t flags = 0; - rombase = oprom; - rambase = opram; - pcbase = 2*pc; - - if (!OpInizialized) InitDasm16C5x(); - op = -1; /* no matching opcode */ - code = READOP16(2*pc); - for ( i = 0; i < MAX_OPS; i++) + code = opcodes.r16(pc); + for ( i = 0; i < int(Op.size()); i++) { if ((code & Op[i].mask) == Op[i].bits) { @@ -202,7 +166,7 @@ CPU_DISASSEMBLE(pic16c62x) { bit = 29; code <<= 16; - code |= READARG16(2*(pc+cnt)); + code |= params.r16(pc+cnt); cnt++; } else @@ -234,9 +198,9 @@ CPU_DISASSEMBLE(pic16c62x) /* now traverse format string */ cp = Op[op].fmt; if (!strncmp(cp, "call", 4)) - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; else if (!strncmp(cp, "ret", 3)) - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; while (*cp) { @@ -259,5 +223,10 @@ CPU_DISASSEMBLE(pic16c62x) stream << *cp++; } } - return cnt | flags | DASMFLAG_SUPPORTED; + return cnt | flags | SUPPORTED; +} + +uint32_t pic16c62x_disassembler::opcode_alignment() const +{ + return 1; } diff --git a/src/devices/cpu/pic16c62x/16c62xdsm.h b/src/devices/cpu/pic16c62x/16c62xdsm.h new file mode 100644 index 00000000000..a6ae323a59f --- /dev/null +++ b/src/devices/cpu/pic16c62x/16c62xdsm.h @@ -0,0 +1,62 @@ +// license:BSD-3-Clause +// copyright-holders:Tony La Porta + /**************************************************************************\ + * Microchip PIC16C62X Emulator * + * * + * Based On * + * Microchip PIC16C5X Emulator * + * Copyright Tony La Porta * + * Originally written for the MAME project. * + * * + * * + * Addressing architecture is based on the Harvard addressing scheme. * + * * + * Many thanks to those involved in the i8039 Disassembler * + * as this was based on it. * + * * + * * + * * + * A Address to jump to. * + * B Bit address within an 8-bit file register. * + * D Destination select (0 = store result in W (accumulator)) * + * (1 = store result in file register) * + * F Register file address (00-1F). * + * K Literal field, constant data. * + * X Not used * + * * + \**************************************************************************/ + +#ifndef MAME_CPU_PIC16C62X_16C62XDSM_H +#define MAME_CPU_PIC16C62X_16C62XDSM_H + +#pragma once + +class pic16c62x_disassembler : public util::disasm_interface +{ +public: + pic16c62x_disassembler(); + virtual ~pic16c62x_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + struct PIC16C62xOpcode { + u16 mask; /* instruction mask */ + u16 bits; /* constant bits */ + u16 extcode; /* value that gets extension code */ + const char *parse; /* how to parse bits */ + const char *fmt; /* instruction format */ + + PIC16C62xOpcode(u16 m, u16 b, u16 e, const char *p, const char *f) : mask(m), bits(b), extcode(e), parse(p), fmt(f) {} + }; + + static const char *const regfile[32]; + static const char *const dest[2]; + static const char *const PIC16C62xFormats[]; + + std::vector<PIC16C62xOpcode> Op; + +}; + +#endif diff --git a/src/devices/cpu/pic16c62x/dis16c62x.cpp b/src/devices/cpu/pic16c62x/dis16c62x.cpp deleted file mode 100644 index 1fb91304dd2..00000000000 --- a/src/devices/cpu/pic16c62x/dis16c62x.cpp +++ /dev/null @@ -1,138 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Tony La Porta - /**************************************************************************\ - * Microchip PIC16C62X Emulator * - * * - * Based On * - * Microchip PIC16C5X Emulator * - * Copyright Tony La Porta * - * Originally written for the MAME project. * - * * - * * - * Notes : Data is expected to be read from source file as LSB first. * - * * - \**************************************************************************/ - -#include <stdio.h> -#include <string.h> - -#include "16c62xdsm.c" - - -unsigned char *Buffer; - - -int main(int argc,char *argv[]) -{ - int length=0, length_to_dump=0, offset=0, disasm_words=0; - int filelength=0, bytes_read; - int Counter=0; - - FILE *F; - char *String_Output; - - if(argc<2) - { - printf("\n"); - printf("PIC16C5x Disassembler 1.0 by Tony La Porta (C)2003+\n\n"); - printf("Usage: dis16c5x <input-file> [ <start-addr> [ <num-of-addr> ] ]\n"); - printf(" <input-file> source file data must be MSB first\n"); - printf(" <start-addr> starting address to disassemble from (decimal)\n"); - printf(" <num-of-addr> number of addresses to disassemble (decimal)\n"); - printf(" Precede values with 0x if HEX values preffered\n"); - exit(1); - } - - if(!(F=fopen(argv[1],"rb"))) - { - printf("\n%s: Can't open file %s\n",argv[0],argv[1]); - exit(2); - } - argv++; argc--; - if (argv[1]) - { - offset = strtol(argv[1],nullptr,0); - argv++; argc--; - } - if (argv[1]) - { - length = strtol(argv[1],nullptr,0); - argv++; argc--; - } - - fseek(F,0, SEEK_END); - filelength = ftell(F); - - length *= 2; - - if ((length > (filelength - (offset*2))) || (length == 0)) length = filelength - (offset*2); - printf("Length=%04Xh(words) Offset=$%04Xh filelength=%04Xh(words) %04Xh(bytes)\n",length/2,offset,filelength/2,filelength); - length_to_dump = length; - printf("Starting from %d, dumping %d opcodes (word size)\n",offset,length/2); - Buffer = calloc((filelength+1),sizeof(char)); - if (Buffer==nullptr) - { - printf("Out of Memory !!!"); - fclose(F); - exit(3); - } - String_Output = calloc(80,sizeof(char)); - if (String_Output==nullptr) - { - printf("Out of Memory !!!"); - free(Buffer); - fclose(F); - exit(4); - } - - if (fseek(F,0,SEEK_SET) != 0) - { - printf("Error seeking to beginning of file\n"); - free(String_Output); - free(Buffer); - fclose(F); - exit(5); - } - - Counter = offset; - bytes_read = fread(Buffer,sizeof(char),filelength,F); - if (bytes_read >= length) - { - for (; length > 0; length -= (disasm_words*2)) - { - int ii; - disasm_words = Dasm16C5x(String_Output,Counter); - printf("$%03X: ",Counter); - for (ii = 0; ii < disasm_words; ii++) - { - if (((Counter*2) + ii) > filelength) /* Past end of length to dump ? */ - { - sprintf(String_Output,"???? dw %02.2X%02.2Xh (Past end of disassembly !)",Buffer[((Counter-1)*2)+1],Buffer[((Counter-1)*2)]); - } - else - { - printf("%02.2x%02.2x ",Buffer[(Counter*2)+1],Buffer[(Counter*2)]); - } - Counter++ ; - } - for (; ii < 4; ii++) - { - printf(" "); - } - printf("\t%s\n",String_Output); - } - } - else - { - printf("ERROR length to dump was %d ", length_to_dump/2); - printf(", but bytes read from file were %d\n", bytes_read/2); - free(String_Output); - free(Buffer); - fclose(F); - exit(7); - } - free(String_Output); - free(Buffer); - fclose(F); - return(0); -} diff --git a/src/devices/cpu/pic16c62x/pic16c62x.cpp b/src/devices/cpu/pic16c62x/pic16c62x.cpp index c7943ad8480..e01a7fda740 100644 --- a/src/devices/cpu/pic16c62x/pic16c62x.cpp +++ b/src/devices/cpu/pic16c62x/pic16c62x.cpp @@ -54,6 +54,7 @@ #include "emu.h" #include "pic16c62x.h" +#include "16c62xdsm.h" #include "debugger.h" @@ -158,10 +159,9 @@ pic16c622a_device::pic16c622a_device(const machine_config &mconfig, const char * } -offs_t pic16c62x_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *pic16c62x_device::create_disassembler() { - extern CPU_DISASSEMBLE( pic16c62x ); - return CPU_DISASSEMBLE_NAME(pic16c62x)(this, stream, pc, oprom, opram, options); + return new pic16c62x_disassembler; } @@ -170,7 +170,7 @@ void pic16c62x_device::update_internalram_ptr() m_internalram = (uint8_t *)m_data->get_write_ptr(0x00); } -#define PIC16C62x_RDOP(A) (m_direct->read_word((A)<<1)) +#define PIC16C62x_RDOP(A) (m_direct->read_word(A)) #define PIC16C62x_RAM_RDMEM(A) ((uint8_t)m_data->read_byte(A)) #define PIC16C62x_RAM_WRMEM(A,V) (m_data->write_byte(A,V)) #define PIC16C62x_In(Port) ((uint8_t)m_io->read_byte((Port))) @@ -867,7 +867,7 @@ void pic16c62x_device::build_opcode_table(void) void pic16c62x_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<-1>(); m_data = &space(AS_DATA); m_io = &space(AS_IO); diff --git a/src/devices/cpu/pic16c62x/pic16c62x.h b/src/devices/cpu/pic16c62x/pic16c62x.h index 0c99e0e67e1..38596be6b29 100644 --- a/src/devices/cpu/pic16c62x/pic16c62x.h +++ b/src/devices/cpu/pic16c62x/pic16c62x.h @@ -79,9 +79,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 2; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -115,7 +113,7 @@ private: int m_inst_cycles; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<-1> *m_direct; address_space *m_data; address_space *m_io; diff --git a/src/devices/cpu/powerpc/ppc.h b/src/devices/cpu/powerpc/ppc.h index dd09cce15e4..ba81a6055bb 100644 --- a/src/devices/cpu/powerpc/ppc.h +++ b/src/devices/cpu/powerpc/ppc.h @@ -268,9 +268,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 4; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 4; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; /* exception types */ enum @@ -492,7 +490,7 @@ protected: int m_buffered_dma_rate[4]; /* internal stuff */ - direct_read_data *m_direct; + direct_read_data<0> *m_direct; offs_t m_codexor; uint32_t m_system_clock; uint32_t m_cpu_clock; diff --git a/src/devices/cpu/powerpc/ppc_dasm.cpp b/src/devices/cpu/powerpc/ppc_dasm.cpp index 77f01f9f552..50b015b1aff 100644 --- a/src/devices/cpu/powerpc/ppc_dasm.cpp +++ b/src/devices/cpu/powerpc/ppc_dasm.cpp @@ -16,103 +16,9 @@ */ #include "emu.h" -#include "debugger.h" +#include "ppc_dasm.h" #include "ppccom.h" -/* - * Operand Formats - * - * These convey information on what operand fields are present and how they - * ought to be printed. - * - * I'm fairly certain all of these are used, but that is not guaranteed. - */ - -enum -{ - F_NONE, // <no operands> - F_LI, // LI*4+PC if AA=0 else LI*4 - F_BCx, // BO, BI, target_addr used only by BCx - F_RT_RA_0_SIMM, // rT, rA|0, SIMM rA|0 means if rA == 0, print 0 - F_ADDIS, // rT, rA, SIMM (printed as unsigned) only used by ADDIS - F_RT_RA_SIMM, // rT, rA, SIMM - F_RA_RT_UIMM, // rA, rT, UIMM - F_CMP_SIMM, // crfD, L, A, SIMM - F_CMP_UIMM, // crfD, L, A, UIMM - F_RT_RA_0_RB, // rT, rA|0, rB - F_RT_RA_RB, // rT, rA, rB - F_RT_D_RA_0, // rT, d(rA|0) - F_RT_D_RA, // rT, d(rA) - F_RA_RT_RB, // rA, rT, rB - F_FRT_D_RA_0, // frT, d(RA|0) - F_FRT_D_RA, // frT, d(RA) - F_FRT_RA_0_RB, // frT, rA|0, rB - F_FRT_RA_RB, // frT, rA, rB - F_TWI, // TO, rA, SIMM only used by TWI instruction - F_CMP, // crfD, L, rA, rB - F_RA_RT, // rA, rT - F_RA_0_RB, // rA|0, rB - F_FRT_FRB, // frT, frB - F_FCMP, // crfD, frA, frB - F_CRFD_CRFS, // crfD, crfS - F_MCRXR, // crfD only used by MCRXR - F_RT, // rT - F_MFSR, // rT, SR only used by MFSR - F_MTSR, // SR, rT only used by MTSR - F_MFFSx, // frT only used by MFFSx - F_FCRBD, // crbD FPSCR[crbD] - F_MTFSFIx, // crfD, IMM only used by MTFSFIx - F_RB, // rB - F_TW, // TO, rA, rB only used by TW - F_RT_RA_0_NB, // rT, rA|0, NB print 32 if NB == 0 - F_SRAWIx, // rA, rT, SH only used by SRAWIx - F_BO_BI, // BO, BI - F_CRBD_CRBA_CRBB, // crbD, crbA, crbB - F_RT_SPR, // rT, SPR and TBR - F_MTSPR, // SPR, rT only used by MTSPR - F_MTCRF, // CRM, rT only used by MTCRF - F_MTFSFx, // FM, frB only used by MTFSFx - F_RT_DCR, // rT, DCR - F_MTDCR, // DCR, rT - F_RT_RA, // rT, rA - F_FRT_FRA_FRC_FRB, // frT, frA, frC, frB - F_FRT_FRA_FRB, // frT, frA, frB - F_FRT_FRA_FRC, // frT, frA, frC - F_RA_RT_SH_MB_ME, // rA, rT, SH, MB, ME - F_RLWNMx, // rT, rA, rB, MB, ME only used by RLWNMx - F_RT_RB // rT, rB -}; - -/* - * Flags - */ - -#define FL_OE (1 << 0) // if there is an OE field -#define FL_RC (1 << 1) // if there is an RC field -#define FL_LK (1 << 2) // if there is an LK field -#define FL_AA (1 << 3) // if there is an AA field -#define FL_CHECK_RA_RT (1 << 4) // assert rA!=0 and rA!=rT -#define FL_CHECK_RA (1 << 5) // assert rA!=0 -#define FL_CHECK_LSWI (1 << 6) // specific check for LSWI validity -#define FL_CHECK_LSWX (1 << 7) // specific check for LSWX validity -#define FL_SO (1 << 8) // use DASMFLAG_STEP_OUT - - -/* - * Instruction Descriptor - * - * Describes the layout of an instruction. - */ - -struct IDESCR -{ - char mnem[32]; // mnemonic - uint32_t match; // bit pattern of instruction after it has been masked - uint32_t mask; // mask of variable fields (AND with ~mask to compare w/ - // bit pattern to determine a match) - int format; // operand format - int flags; // flags -}; /* * Instruction Table @@ -121,7 +27,7 @@ struct IDESCR * and print instructions. */ -static const IDESCR itab[] = +const powerpc_disassembler::IDESCR powerpc_disassembler::itab[] = { { "add", D_OP(31)|D_XO(266), M_RT|M_RA|M_RB|M_OE|M_RC, F_RT_RA_RB, FL_OE|FL_RC }, { "addc", D_OP(31)|D_XO(10), M_RT|M_RA|M_RB|M_OE|M_RC, F_RT_RA_RB, FL_OE|FL_RC }, @@ -342,18 +248,18 @@ static const IDESCR itab[] = * Use an index of BI&3 into this table to obtain the CR field bit name. */ -static const char *const crbit[4] = { "lt", "gt", "eq", "so" }; -static const char *const crnbit[4] = { "ge", "le", "ne", "nso" }; +const char *const powerpc_disassembler::crbit[4] = { "lt", "gt", "eq", "so" }; +const char *const powerpc_disassembler::crnbit[4] = { "ge", "le", "ne", "nso" }; /* * SPR(): * - * Decode the SPR (or TBR) field and append the register name to dest. If - * no name is associated with the field value, the value itself is printed. + * Decode the SPR (or TBR) field and return the register name. If + * no name is associated with the field value, return the value itself. */ -static void SPR(char *dest, int spr_field) +std::string powerpc_disassembler::SPR(int spr_field) { int spr; @@ -371,93 +277,93 @@ static void SPR(char *dest, int spr_field) switch (spr) { /* UISA SPR register indexes */ - case SPR_XER: strcat(dest, "xer"); break; - case SPR_LR: strcat(dest, "lr"); break; - case SPR_CTR: strcat(dest, "ctr"); break; + case SPR_XER: return "xer"; + case SPR_LR: return "lr"; + case SPR_CTR: return "ctr"; /* VEA SPR register indexes */ - case SPRVEA_TBL_R: strcat(dest, "tbl"); break; - case SPRVEA_TBU_R: strcat(dest, "tbu"); break; + case SPRVEA_TBL_R: return "tbl"; + case SPRVEA_TBU_R: return "tbu"; /* OEA SPR register indexes */ - case SPROEA_DSISR: strcat(dest, "dsisr"); break; - case SPROEA_DAR: strcat(dest, "dar"); break; - case SPROEA_DEC: strcat(dest, "dec"); break; - case SPROEA_SDR1: strcat(dest, "sdr1"); break; - case SPROEA_SRR0: strcat(dest, "srr0"); break; - case SPROEA_SRR1: strcat(dest, "srr1"); break; - case SPROEA_SPRG0: strcat(dest, "sprg0"); break; - case SPROEA_SPRG1: strcat(dest, "sprg1"); break; - case SPROEA_SPRG2: strcat(dest, "sprg2"); break; - case SPROEA_SPRG3: strcat(dest, "sprg3"); break; - case SPROEA_ASR: strcat(dest, "asr"); break; - case SPROEA_EAR: strcat(dest, "ear"); break; - case SPROEA_PVR: strcat(dest, "pvr"); break; - case SPROEA_IBAT0U: strcat(dest, "ibat0u"); break; - case SPROEA_IBAT0L: strcat(dest, "ibat0l"); break; - case SPROEA_IBAT1U: strcat(dest, "ibat1u"); break; - case SPROEA_IBAT1L: strcat(dest, "ibat1l"); break; - case SPROEA_IBAT2U: strcat(dest, "ibat2u"); break; - case SPROEA_IBAT2L: strcat(dest, "ibat2l"); break; - case SPROEA_IBAT3U: strcat(dest, "ibat3u"); break; - case SPROEA_IBAT3L: strcat(dest, "ibat3l"); break; - case SPROEA_DBAT0U: strcat(dest, "dbat0u"); break; - case SPROEA_DBAT0L: strcat(dest, "dbat0l"); break; - case SPROEA_DBAT1U: strcat(dest, "dbat1u"); break; - case SPROEA_DBAT1L: strcat(dest, "dbat1l"); break; - case SPROEA_DBAT2U: strcat(dest, "dbat2u"); break; - case SPROEA_DBAT2L: strcat(dest, "dbat2l"); break; - case SPROEA_DBAT3U: strcat(dest, "dbat3u"); break; - case SPROEA_DBAT3L: strcat(dest, "dbat3l"); break; - case SPROEA_DABR: strcat(dest, "dabr/iac2"); break; // unsupported on 603e/EC603e + case SPROEA_DSISR: return "dsisr"; + case SPROEA_DAR: return "dar"; + case SPROEA_DEC: return "dec"; + case SPROEA_SDR1: return "sdr1"; + case SPROEA_SRR0: return "srr0"; + case SPROEA_SRR1: return "srr1"; + case SPROEA_SPRG0: return "sprg0"; + case SPROEA_SPRG1: return "sprg1"; + case SPROEA_SPRG2: return "sprg2"; + case SPROEA_SPRG3: return "sprg3"; + case SPROEA_ASR: return "asr"; + case SPROEA_EAR: return "ear"; + case SPROEA_PVR: return "pvr"; + case SPROEA_IBAT0U: return "ibat0u"; + case SPROEA_IBAT0L: return "ibat0l"; + case SPROEA_IBAT1U: return "ibat1u"; + case SPROEA_IBAT1L: return "ibat1l"; + case SPROEA_IBAT2U: return "ibat2u"; + case SPROEA_IBAT2L: return "ibat2l"; + case SPROEA_IBAT3U: return "ibat3u"; + case SPROEA_IBAT3L: return "ibat3l"; + case SPROEA_DBAT0U: return "dbat0u"; + case SPROEA_DBAT0L: return "dbat0l"; + case SPROEA_DBAT1U: return "dbat1u"; + case SPROEA_DBAT1L: return "dbat1l"; + case SPROEA_DBAT2U: return "dbat2u"; + case SPROEA_DBAT2L: return "dbat2l"; + case SPROEA_DBAT3U: return "dbat3u"; + case SPROEA_DBAT3L: return "dbat3l"; + case SPROEA_DABR: return "dabr/iac2"; // unsupported on 603e/EC603e /* PowerPC 603E SPR register indexes */ - case SPR603_HID0: strcat(dest, "hid0/dbsr"); break; - case SPR603_HID1: strcat(dest, "hid1"); break; - case SPR603_DMISS: strcat(dest, "dmiss"); break; - case SPR603_DCMP: strcat(dest, "dcmp"); break; - case SPR603_HASH1: strcat(dest, "hash1"); break; - case SPR603_HASH2: strcat(dest, "hash2/icdbdr"); break; - case SPR603_IMISS: strcat(dest, "imiss"); break; - case SPR603_ICMP: strcat(dest, "icmp/dear"); break; - case SPR603_RPA: strcat(dest, "rpa/evpr"); break; - case SPR603_IABR: strcat(dest, "iabr/dbcr"); break; + case SPR603_HID0: return "hid0/dbsr"; + case SPR603_HID1: return "hid1"; + case SPR603_DMISS: return "dmiss"; + case SPR603_DCMP: return "dcmp"; + case SPR603_HASH1: return "hash1"; + case SPR603_HASH2: return "hash2/icdbdr"; + case SPR603_IMISS: return "imiss"; + case SPR603_ICMP: return "icmp/dear"; + case SPR603_RPA: return "rpa/evpr"; + case SPR603_IABR: return "iabr/dbcr"; /* PowerPC 4XX SPR register indexes */ - case SPR4XX_SGR: strcat(dest, "sgr"); break; - case SPR4XX_DCWR: strcat(dest, "dcwr"); break; - case SPR4XX_PID: strcat(dest, "pid"); break; - case SPR4XX_TBHU: strcat(dest, "tbhu"); break; - case SPR4XX_TBLU: strcat(dest, "tblu"); break; -// case SPR4XX_ICDBDR: strcat(dest, "icdbdr"); break; // same as SPR603E_HASH2 -// case SPR4XX_DEAR: strcat(dest, "dear"); break; // same as SPR603E_ICMP -// case SPR4XX_EVPR: strcat(dest, "evpr"); break; // same as SPR603E_RPA - case SPR4XX_CDBCR: strcat(dest, "cdbcr"); break; - case SPR4XX_TSR: strcat(dest, "tsr"); break; - case SPR4XX_TCR: strcat(dest, "tcr"); break; - case SPR4XX_PIT: strcat(dest, "pit"); break; - case SPR4XX_TBHI: strcat(dest, "tbhi"); break; - case SPR4XX_TBLO: strcat(dest, "tblo"); break; - case SPR4XX_SRR2: strcat(dest, "srr2"); break; - case SPR4XX_SRR3: strcat(dest, "srr3"); break; -// case SPR4XX_DBSR: strcat(dest, "dbsr"); break; // same as SPR603E_HID0 -// case SPR4XX_DBCR: strcat(dest, "dbcr"); break; // same as SPR603E_IABR - case SPR4XX_IAC1: strcat(dest, "iac1"); break; -// case SPR4XX_IAC2: strcat(dest, "iac2"); break; // same as SPROEA_DABR - case SPR4XX_DAC1: strcat(dest, "dac1"); break; - case SPR4XX_DAC2: strcat(dest, "dac2"); break; - case SPR4XX_DCCR: strcat(dest, "dccr"); break; - case SPR4XX_ICCR: strcat(dest, "iccr"); break; - case SPR4XX_PBL1: strcat(dest, "pbl1"); break; - case SPR4XX_PBU1: strcat(dest, "pbu1"); break; - case SPR4XX_PBL2: strcat(dest, "pbl2"); break; - case SPR4XX_PBU2: strcat(dest, "pbu2"); break; - - default: sprintf(dest + strlen(dest), "%d", spr); break; + case SPR4XX_SGR: return "sgr"; + case SPR4XX_DCWR: return "dcwr"; + case SPR4XX_PID: return "pid"; + case SPR4XX_TBHU: return "tbhu"; + case SPR4XX_TBLU: return "tblu"; +// case SPR4XX_ICDBDR: return "icdbdr"; // same as SPR603E_HASH2 +// case SPR4XX_DEAR: return "dear"; // same as SPR603E_ICMP +// case SPR4XX_EVPR: return "evpr"; // same as SPR603E_RPA + case SPR4XX_CDBCR: return "cdbcr"; + case SPR4XX_TSR: return "tsr"; + case SPR4XX_TCR: return "tcr"; + case SPR4XX_PIT: return "pit"; + case SPR4XX_TBHI: return "tbhi"; + case SPR4XX_TBLO: return "tblo"; + case SPR4XX_SRR2: return "srr2"; + case SPR4XX_SRR3: return "srr3"; +// case SPR4XX_DBSR: return "dbsr"; // same as SPR603E_HID0 +// case SPR4XX_DBCR: return "dbcr"; // same as SPR603E_IABR + case SPR4XX_IAC1: return "iac1"; +// case SPR4XX_IAC2: return "iac2"; // same as SPROEA_DABR + case SPR4XX_DAC1: return "dac1"; + case SPR4XX_DAC2: return "dac2"; + case SPR4XX_DCCR: return "dccr"; + case SPR4XX_ICCR: return "iccr"; + case SPR4XX_PBL1: return "pbl1"; + case SPR4XX_PBU1: return "pbu1"; + case SPR4XX_PBL2: return "pbl2"; + case SPR4XX_PBU2: return "pbu2"; + + default: return util::string_format("%d", spr); } } -static void DCR(char *dest, int dcr_field) +std::string powerpc_disassembler::DCR(int dcr_field) { int dcr; @@ -474,50 +380,50 @@ static void DCR(char *dest, int dcr_field) switch (dcr) { - case 144: strcat(dest, "bear"); break; - case 145: strcat(dest, "besr"); break; - case 128: strcat(dest, "br0"); break; - case 129: strcat(dest, "br1"); break; - case 130: strcat(dest, "br2"); break; - case 131: strcat(dest, "br3"); break; - case 132: strcat(dest, "br4"); break; - case 133: strcat(dest, "br5"); break; - case 134: strcat(dest, "br6"); break; - case 135: strcat(dest, "br7"); break; - case 112: strcat(dest, "brh0"); break; - case 113: strcat(dest, "brh1"); break; - case 114: strcat(dest, "brh2"); break; - case 115: strcat(dest, "brh3"); break; - case 116: strcat(dest, "brh4"); break; - case 117: strcat(dest, "brh5"); break; - case 118: strcat(dest, "brh6"); break; - case 119: strcat(dest, "brh7"); break; - case 196: strcat(dest, "dmacc0"); break; - case 204: strcat(dest, "dmacc1"); break; - case 212: strcat(dest, "dmacc2"); break; - case 220: strcat(dest, "dmacc3"); break; - case 192: strcat(dest, "dmacr0"); break; - case 200: strcat(dest, "dmacr1"); break; - case 208: strcat(dest, "dmacr2"); break; - case 216: strcat(dest, "dmacr3"); break; - case 193: strcat(dest, "dmact0"); break; - case 201: strcat(dest, "dmact1"); break; - case 209: strcat(dest, "dmact2"); break; - case 217: strcat(dest, "dmact3"); break; - case 194: strcat(dest, "dmada0"); break; - case 202: strcat(dest, "dmada1"); break; - case 210: strcat(dest, "dmada2"); break; - case 218: strcat(dest, "dmada3"); break; - case 195: strcat(dest, "dmasa0"); break; - case 203: strcat(dest, "dmasa1"); break; - case 211: strcat(dest, "dmasa2"); break; - case 219: strcat(dest, "dmasa3"); break; - case 224: strcat(dest, "dmasr"); break; - case 66: strcat(dest, "exier"); break; - case 64: strcat(dest, "exisr"); break; - case 160: strcat(dest, "iocr"); break; - - default: sprintf(dest + strlen(dest), "%d", dcr); break; + case 144: return "bear"; + case 145: return "besr"; + case 128: return "br0"; + case 129: return "br1"; + case 130: return "br2"; + case 131: return "br3"; + case 132: return "br4"; + case 133: return "br5"; + case 134: return "br6"; + case 135: return "br7"; + case 112: return "brh0"; + case 113: return "brh1"; + case 114: return "brh2"; + case 115: return "brh3"; + case 116: return "brh4"; + case 117: return "brh5"; + case 118: return "brh6"; + case 119: return "brh7"; + case 196: return "dmacc0"; + case 204: return "dmacc1"; + case 212: return "dmacc2"; + case 220: return "dmacc3"; + case 192: return "dmacr0"; + case 200: return "dmacr1"; + case 208: return "dmacr2"; + case 216: return "dmacr3"; + case 193: return "dmact0"; + case 201: return "dmact1"; + case 209: return "dmact2"; + case 217: return "dmact3"; + case 194: return "dmada0"; + case 202: return "dmada1"; + case 210: return "dmada2"; + case 218: return "dmada3"; + case 195: return "dmasa0"; + case 203: return "dmasa1"; + case 211: return "dmasa2"; + case 219: return "dmasa3"; + case 224: return "dmasr"; + case 66: return "exier"; + case 64: return "exisr"; + case 160: return "iocr"; + + default: return util::string_format("%d", dcr); } } @@ -529,22 +435,22 @@ static void DCR(char *dest, int dcr_field) * unsigned 16-bit integer. */ -static void DecodeSigned16(char *outbuf, uint32_t op, int do_unsigned) +std::string powerpc_disassembler::DecodeSigned16(uint32_t op, int do_unsigned) { int16_t s; s = G_SIMM(op); if (do_unsigned) // sign extend to unsigned 32-bits - sprintf(outbuf, "0x%04X", (uint32_t) s); + return util::string_format("0x%04X", (uint32_t) s); else // print as signed 16 bits { if (s < 0) { s *= -1; - sprintf(outbuf, "-0x%04X", s); + return util::string_format("-0x%04X", s); } else - sprintf(outbuf, "0x%04X",s); + return util::string_format("0x%04X",s); } } @@ -554,7 +460,7 @@ static void DecodeSigned16(char *outbuf, uint32_t op, int do_unsigned) * Generate a mask from bit MB through ME (PPC-style backwards bit numbering.) */ -static uint32_t Mask(int mb, int me) +uint32_t powerpc_disassembler::Mask(int mb, int me) { uint32_t i, mask; @@ -575,76 +481,13 @@ static uint32_t Mask(int mb, int me) } /* - * Check(): - * - * Perform checks on the instruction as required by the flags. Returns 1 if - * the instruction failed. - */ - -#if 0 -static int Check(uint32_t op, int flags) -{ - int nb, rt, ra; - - if( !flags ) return 0; // nothing to check for! - - rt = G_RT(op); - ra = G_RA(op); - - if (flags & FL_CHECK_RA_RT) // invalid if rA==0 or rA==rT - { - if ((G_RA(op) == 0) || (G_RA(op) == G_RT(op))) - return 1; - } - - if (flags & FL_CHECK_RA) // invalid if rA==0 - { - if (G_RA(op) == 0) - return 1; - } - - if (flags & FL_CHECK_LSWI) - { - /* - * Check that rA is not in the range of registers to be loaded (even - * if rA == 0) - */ - - nb = G_NB(op); - - if (ra >= rt && ra <= (rt + nb - 1)) return 1; - if ((rt + nb - 1) > 31) // register wrap-around! - { - if (ra < ((rt + nb - 1) - 31)) - return 1; - } - } - - if (flags & FL_CHECK_LSWX) - { - /* - * Check that rT != rA, rT != rB, and rD and rA both do not specify - * R0. - * - * We cannot check fully whether rA or rB are in the range of - * registers specified to be loaded because that depends on XER. - */ - - if (rt == ra || rt == G_RB(op) || ((rt == 0) && (ra == 0))) - return 1; - } - - return 0; // passed checks -} -#endif -/* * Simplified(): * - * Handles all simplified instruction forms. Returns 1 if one was decoded, - * otherwise 0 to indicate disassembly should carry on as normal. + * Handles all simplified instruction forms. Returns true if one was decoded, + * otherwise false to indicate disassembly should carry on as normal. */ -static int Simplified(uint32_t op, uint32_t vpc, char *signed16, char *mnem, char *oprs) +bool powerpc_disassembler::Simplified(uint32_t op, uint32_t vpc, std::string &signed16, std::string &mnem, std::string &oprs) { uint32_t value, disp; @@ -653,96 +496,96 @@ static int Simplified(uint32_t op, uint32_t vpc, char *signed16, char *mnem, cha value |= 0xffff0000; if (op == (D_OP(24)|D_RT(0)|D_RA(0)|D_UIMM(0))) - strcat(mnem, "nop"); // ori r0,r0,0 -> nop + mnem += "nop"; // ori r0,r0,0 -> nop else if ((op & ~(M_RT|M_RA|M_RB|M_RC)) == (D_OP(31)|D_XO(444))) { if (G_RT(op) == G_RB(op)) { - strcat(mnem, "mr"); // orx rA,rT,rT -> mrx rA,rT - if (op & M_RC) strcat(mnem, "."); - sprintf(oprs, "r%d,r%d", G_RA(op), G_RT(op)); + mnem += "mr"; // orx rA,rT,rT -> mrx rA,rT + if (op & M_RC) mnem += "."; + oprs = util::string_format("r%d,r%d", G_RA(op), G_RT(op)); } else - return 0; + return false; } else if ((op & ~(M_RT|M_RA|M_RB|M_RC)) == (D_OP(31)|D_XO(124))) { if (G_RT(op) == G_RB(op)) { - strcat(mnem, "not"); // nor rA,rT,rT -> not rA,rT - if (op & M_RC) strcat(mnem, "."); - sprintf(oprs, "r%d,r%d", G_RA(op), G_RT(op)); + mnem += "not"; // nor rA,rT,rT -> not rA,rT + if (op & M_RC) mnem += "."; + oprs = util::string_format("r%d,r%d", G_RA(op), G_RT(op)); } else - return 0; + return false; } else if ((op & ~(M_RT|M_RA|M_SIMM)) == D_OP(14)) { if (G_RA(op) == 0) { - strcat(mnem, "li"); // addi rT,0,value -> li rT,value - sprintf(oprs, "r%d,0x%08X", G_RT(op), value); + mnem += "li"; // addi rT,0,value -> li rT,value + oprs = util::string_format("r%d,0x%08X", G_RT(op), value); } else - return 0; + return false; } else if ((op & ~(M_RT|M_RA|M_SIMM)) == D_OP(15)) { if (G_RA(op) == 0) { - strcat(mnem, "li"); // addis rT,0,value -> li rT,(value<<16) - sprintf(oprs, "r%d,0x%08X", G_RT(op), value << 16); + mnem += "li"; // addis rT,0,value -> li rT,(value<<16) + oprs = util::string_format("r%d,0x%08X", G_RT(op), value << 16); } else { - strcat(mnem, "addi"); // addis rT,rA,SIMM -> addi rT,rA,SIMM<<16 - sprintf(oprs, "r%d,r%d,0x%08X", G_RT(op), G_RA(op), value << 16); + mnem += "addi"; // addis rT,rA,SIMM -> addi rT,rA,SIMM<<16 + oprs = util::string_format("r%d,r%d,0x%08X", G_RT(op), G_RA(op), value << 16); } } else if ((op & ~(M_RT|M_RA|M_UIMM)) == D_OP(29)) { - strcat(mnem, "andi."); // andis. rA,rT,UIMM -> andi. rA,rT,UIMM<<16 - sprintf(oprs, "r%d,r%d,0x%08X", G_RA(op), G_RT(op), G_UIMM(op) << 16); + mnem += "andi."; // andis. rA,rT,UIMM -> andi. rA,rT,UIMM<<16 + oprs = util::string_format("r%d,r%d,0x%08X", G_RA(op), G_RT(op), G_UIMM(op) << 16); } else if ((op & ~(M_RT|M_RA|M_UIMM)) == D_OP(25)) { - strcat(mnem, "ori"); // oris rA,rT,UIMM -> ori rA,rT,UIMM<<16 - sprintf(oprs, "r%d,r%d,0x%08X", G_RA(op), G_RT(op), G_UIMM(op) << 16); + mnem += "ori"; // oris rA,rT,UIMM -> ori rA,rT,UIMM<<16 + oprs = util::string_format("r%d,r%d,0x%08X", G_RA(op), G_RT(op), G_UIMM(op) << 16); } else if ((op & ~(M_RT|M_RA|M_UIMM)) == D_OP(27)) { - strcat(mnem, "xori"); // xoris rA,rT,UIMM -> xori rA,rT,UIMM<<16 - sprintf(oprs, "r%d,r%d,0x%08X", G_RA(op), G_RT(op), G_UIMM(op) << 16); + mnem += "xori"; // xoris rA,rT,UIMM -> xori rA,rT,UIMM<<16 + oprs = util::string_format("r%d,r%d,0x%08X", G_RA(op), G_RT(op), G_UIMM(op) << 16); } else if ((op & ~(M_RT|M_RA|M_SH|M_MB|M_ME|M_RC)) == D_OP(20)) { value = Mask(G_MB(op), G_ME(op)); - strcat(mnem, "rlwimi"); // rlwimi[.] rA,rT,SH,MB,ME -> rlwimi[.] rA,rT,SH,MASK - if (op & M_RC) strcat(mnem, "."); - sprintf(oprs, "r%d,r%d,%d,0x%08X", G_RA(op), G_RT(op), G_SH(op), value); + mnem += "rlwimi"; // rlwimi[.] rA,rT,SH,MB,ME -> rlwimi[.] rA,rT,SH,MASK + if (op & M_RC) mnem += "."; + oprs = util::string_format("r%d,r%d,%d,0x%08X", G_RA(op), G_RT(op), G_SH(op), value); } else if ((op & ~(M_RT|M_RA|M_SH|M_MB|M_ME|M_RC)) == D_OP(21)) { value = Mask(G_MB(op), G_ME(op)); if (G_SH(op) == 0) // rlwinm[.] rA,rT,0,MB,ME -> and[.] rA,rT,MASK { - strcat(mnem, "and"); - if (op & M_RC) strcat(mnem, "."); - sprintf(oprs, "r%d,r%d,0x%08X", G_RA(op), G_RT(op), value); + mnem += "and"; + if (op & M_RC) mnem += "."; + oprs = util::string_format("r%d,r%d,0x%08X", G_RA(op), G_RT(op), value); } else // rlwinm[.] rA,rT,SH,MASK { - strcat(mnem, "rlwinm"); - if (op & M_RC) strcat(mnem, "."); - sprintf(oprs, "r%d,r%d,%d,0x%08X", G_RA(op), G_RT(op), G_SH(op), value); + mnem += "rlwinm"; + if (op & M_RC) mnem += "."; + oprs = util::string_format("r%d,r%d,%d,0x%08X", G_RA(op), G_RT(op), G_SH(op), value); } } else if ((op & ~(M_RT|M_RA|M_RB|M_MB|M_ME|M_RC)) == D_OP(23)) { value = Mask(G_MB(op), G_ME(op)); - strcat(mnem, "rlwnm"); // rlwnm[.] rA,rT,SH,MB,ME -> rlwnm[.] rA,rT,SH,MASK - if (op & M_RC) strcat(mnem, "."); - sprintf(oprs, "r%d,r%d,r%d,0x%08X", G_RA(op), G_RT(op), G_RB(op), value); + mnem += "rlwnm"; // rlwnm[.] rA,rT,SH,MB,ME -> rlwnm[.] rA,rT,SH,MASK + if (op & M_RC) mnem += "."; + oprs = util::string_format("r%d,r%d,r%d,0x%08X", G_RA(op), G_RT(op), G_RB(op), value); } else if ((op & ~(M_BO|M_BI|M_BD|M_AA|M_LK)) == D_OP(16)) { @@ -753,105 +596,100 @@ static int Simplified(uint32_t op, uint32_t vpc, char *signed16, char *mnem, cha switch (G_BO(op)) { case 0x04: case 0x05: case 0x06: case 0x07: - strcat(mnem, "b"); - strcat(mnem, crnbit[G_BI(op) & 3]); + mnem += "b"; + mnem += crnbit[G_BI(op) & 3]; break; case 0x0c: case 0x0d: case 0x0e: case 0x0f: - strcat(mnem, "b"); - strcat(mnem, crbit[G_BI(op) & 3]); + mnem += "b"; + mnem += crbit[G_BI(op) & 3]; break; case 0x10: case 0x11: case 0x18: case 0x19: - strcat(mnem, "bdnz"); + mnem += "bdnz"; break; case 0x12: case 0x13: case 0x1a: case 0x1b: - strcat(mnem, "bdz"); + mnem += "bdz"; break; case 0x14: case 0x15: case 0x16: case 0x17: case 0x1c: case 0x1d: case 0x1e: case 0x1f: - strcat(mnem, "b"); + mnem += "b"; break; default: - return 0; + return false; } - if (op & M_LK) strcat(mnem, "l"); - if (op & M_AA) strcat(mnem, "a"); + if (op & M_LK) mnem += "l"; + if (op & M_AA) mnem += "a"; if (!(G_BO(op) & 0x10) && G_BI(op) / 4 != 0) - sprintf(oprs, "cr%d,0x%08X", G_BI(op) / 4, disp + ((op & M_AA) ? 0 : vpc)); + oprs = util::string_format("cr%d,0x%08X", G_BI(op) / 4, disp + ((op & M_AA) ? 0 : vpc)); else - sprintf(oprs, "0x%08X", disp + ((op & M_AA) ? 0 : vpc)); + oprs = util::string_format("0x%08X", disp + ((op & M_AA) ? 0 : vpc)); } else if ((op & ~(M_BO|M_BI|M_LK)) == (D_OP(19)|D_XO(528)) || (op & ~(M_BO|M_BI|M_LK)) == (D_OP(19)|D_XO(16))) { switch (G_BO(op)) { case 0x04: case 0x05: case 0x06: case 0x07: - strcat(mnem, "b"); - strcat(mnem, crnbit[G_BI(op) & 3]); + mnem += "b"; + mnem += crnbit[G_BI(op) & 3]; break; case 0x0c: case 0x0d: case 0x0e: case 0x0f: - strcat(mnem, "b"); - strcat(mnem, crbit[G_BI(op) & 3]); + mnem += "b"; + mnem += crbit[G_BI(op) & 3]; break; case 0x10: case 0x11: case 0x18: case 0x19: - strcat(mnem, "bdnz"); + mnem += "bdnz"; break; case 0x12: case 0x13: case 0x1a: case 0x1b: - strcat(mnem, "bdz"); + mnem += "bdz"; break; case 0x14: case 0x15: case 0x16: case 0x17: case 0x1c: case 0x1d: case 0x1e: case 0x1f: - strcat(mnem, "b"); + mnem += "b"; break; default: - return 0; + return false; } - strcat(mnem, (G_XO(op) == 528) ? "ctr" : "lr"); - if (op & M_LK) strcat(mnem, "l"); - if (op & M_AA) strcat(mnem, "a"); + mnem += (G_XO(op) == 528) ? "ctr" : "lr"; + if (op & M_LK) mnem += "l"; + if (op & M_AA) mnem += "a"; if (!(G_BO(op) & 0x10) && G_BI(op) / 4 != 0) - sprintf(oprs, "cr%d", G_BI(op) / 4); + oprs = util::string_format("cr%d", G_BI(op) / 4); } else if ((op & ~(M_RT|M_RA|M_RB|M_OE|M_RC)) == (D_OP(31)|D_XO(40))) { - strcat(mnem, "sub"); - if (op & M_OE) strcat(mnem, "o"); - if (op & M_RC) strcat(mnem, "."); - sprintf(oprs, "r%d,r%d,r%d", G_RT(op), G_RB(op), G_RA(op)); + mnem += "sub"; + if (op & M_OE) mnem += "o"; + if (op & M_RC) mnem += "."; + oprs = util::string_format("r%d,r%d,r%d", G_RT(op), G_RB(op), G_RA(op)); } else if ((op & ~(M_RT|M_RA|M_RB|M_OE|M_RC)) == (D_OP(31)|D_XO(8))) { - strcat(mnem, "subc"); - if (op & M_OE) strcat(mnem, "o"); - if (op & M_RC) strcat(mnem, "."); - sprintf(oprs, "r%d,r%d,r%d", G_RT(op), G_RB(op), G_RA(op)); + mnem += "subc"; + if (op & M_OE) mnem += "o"; + if (op & M_RC) mnem += "."; + oprs = util::string_format("r%d,r%d,r%d", G_RT(op), G_RB(op), G_RA(op)); } else - return 0; // no match + return false; // no match - return 1; + return true; } -offs_t ppc_dasm_one(std::ostream &stream, uint32_t pc, uint32_t op) +offs_t powerpc_disassembler::dasm_one(std::ostream &stream, uint32_t pc, uint32_t op) { - char signed16[12]; + std::string signed16, mnem, oprs; uint32_t disp; int i,j; - char mnem[200]; - char oprs[200]; - offs_t flags = DASMFLAG_SUPPORTED; - - mnem[0] = '\0'; // so we can use strcat() - oprs[0] = '\0'; + offs_t flags = SUPPORTED; /* * Decode signed 16-bit fields (SIMM and d) to spare us the work later */ - DecodeSigned16(signed16, op, 0); + signed16 = DecodeSigned16(op, 0); /* * Try simplified forms first, then real instructions @@ -859,7 +697,7 @@ offs_t ppc_dasm_one(std::ostream &stream, uint32_t pc, uint32_t op) if( Simplified(op, pc, signed16, mnem, oprs) ) { util::stream_format(stream, "%s", mnem); - for( j = strlen(mnem); j < 10; j++ ) { + for( j = mnem.size(); j < 10; j++ ) { util::stream_format(stream, " "); } util::stream_format(stream, "%s", oprs); @@ -878,11 +716,11 @@ offs_t ppc_dasm_one(std::ostream &stream, uint32_t pc, uint32_t op) * Base mnemonic followed be O, ., L, A */ - strcat(mnem, itab[i].mnem); - if (itab[i].flags & FL_OE) if (op & M_OE) strcat(mnem, "o"); - if (itab[i].flags & FL_RC) if (op & M_RC) strcat(mnem, "."); - if (itab[i].flags & FL_LK) if (op & M_LK) strcat(mnem, "l"); - if (itab[i].flags & FL_AA) if (op & M_AA) strcat(mnem, "a"); + mnem += itab[i].mnem; + if (itab[i].flags & FL_OE) if (op & M_OE) mnem += "o"; + if (itab[i].flags & FL_RC) if (op & M_RC) mnem += "."; + if (itab[i].flags & FL_LK) if (op & M_LK) mnem += "l"; + if (itab[i].flags & FL_AA) if (op & M_AA) mnem += "a"; /* * Print operands @@ -891,44 +729,44 @@ offs_t ppc_dasm_one(std::ostream &stream, uint32_t pc, uint32_t op) switch (itab[i].format) { case F_RT_RA_RB: - sprintf(oprs, "r%d,r%d,r%d", G_RT(op), G_RA(op), G_RB(op)); + oprs = util::string_format("r%d,r%d,r%d", G_RT(op), G_RA(op), G_RB(op)); break; case F_RT_RA_0_SIMM: if (G_RA(op)) - sprintf(oprs, "r%d,r%d,%s", G_RT(op), G_RA(op), signed16); + oprs = util::string_format("r%d,r%d,%s", G_RT(op), G_RA(op), signed16); else - sprintf(oprs, "r%d,0,%s", G_RT(op), signed16); + oprs = util::string_format("r%d,0,%s", G_RT(op), signed16); break; case F_ADDIS: if (G_RA(op)) - sprintf(oprs, "r%d,r%d,0x%04X", G_RT(op), G_RA(op), G_SIMM(op)); + oprs = util::string_format("r%d,r%d,0x%04X", G_RT(op), G_RA(op), G_SIMM(op)); else - sprintf(oprs, "r%d,0,0x%04X", G_RT(op), G_SIMM(op)); + oprs = util::string_format("r%d,0,0x%04X", G_RT(op), G_SIMM(op)); break; case F_RT_RA_SIMM: - sprintf(oprs, "r%d,r%d,%s", G_RT(op), G_RA(op), signed16); + oprs = util::string_format("r%d,r%d,%s", G_RT(op), G_RA(op), signed16); break; case F_RT_RA: - sprintf(oprs, "r%d,r%d", G_RT(op), G_RA(op)); + oprs = util::string_format("r%d,r%d", G_RT(op), G_RA(op)); break; case F_RA_RT_RB: - sprintf(oprs, "r%d,r%d,r%d", G_RA(op), G_RT(op), G_RB(op)); + oprs = util::string_format("r%d,r%d,r%d", G_RA(op), G_RT(op), G_RB(op)); break; case F_RA_RT_UIMM: - sprintf(oprs, "r%d,r%d,0x%04X", G_RA(op), G_RT(op), G_UIMM(op)); + oprs = util::string_format("r%d,r%d,0x%04X", G_RA(op), G_RT(op), G_UIMM(op)); break; case F_LI: disp = G_LI(op) * 4; if (disp & 0x02000000) // sign extend disp |= 0xfc000000; - sprintf(oprs, "0x%08X", disp + ((op & M_AA) ? 0 : pc)); + oprs = util::string_format("0x%08X", disp + ((op & M_AA) ? 0 : pc)); break; case F_BCx: @@ -937,213 +775,209 @@ offs_t ppc_dasm_one(std::ostream &stream, uint32_t pc, uint32_t op) disp |= 0xffff0000; if (G_BO(op) & 0x10) // BI is ignored (don't print CR bit) - sprintf(oprs, "0x%02X,%d,0x%08X", G_BO(op), G_BI(op), disp + ((op & M_AA) ? 0 : pc)); + oprs = util::string_format("0x%02X,%d,0x%08X", G_BO(op), G_BI(op), disp + ((op & M_AA) ? 0 : pc)); else // BI gives us the condition bit - sprintf(oprs, "0x%02X,cr%d[%s],0x%08X", G_BO(op), G_BI(op) / 4, crbit[G_BI(op) & 3], disp + ((op & M_AA) ? 0 : pc)); + oprs = util::string_format("0x%02X,cr%d[%s],0x%08X", G_BO(op), G_BI(op) / 4, crbit[G_BI(op) & 3], disp + ((op & M_AA) ? 0 : pc)); break; case F_BO_BI: if (G_BO(op) & 0x10) // BI is ignored (don't print CR bit) - sprintf(oprs, "0x%02X,%d", G_BO(op), G_BI(op)); + oprs = util::string_format("0x%02X,%d", G_BO(op), G_BI(op)); else - sprintf(oprs, "0x%02X,cr%d[%s]", G_BO(op), G_BI(op) / 4, crbit[G_BI(op) & 3]); + oprs = util::string_format("0x%02X,cr%d[%s]", G_BO(op), G_BI(op) / 4, crbit[G_BI(op) & 3]); break; case F_CMP: if (G_L(op)) - strcat(mnem, "d"); + mnem += "d"; if (G_CRFD(op) == 0) - sprintf(oprs, "r%d,r%d", G_RA(op), G_RB(op)); + oprs = util::string_format("r%d,r%d", G_RA(op), G_RB(op)); else - sprintf(oprs, "cr%d,r%d,r%d", G_CRFD(op), G_RA(op), G_RB(op)); + oprs = util::string_format("cr%d,r%d,r%d", G_CRFD(op), G_RA(op), G_RB(op)); break; case F_CMP_SIMM: if (G_L(op)) - strcat(mnem, "d"); + mnem += "d"; if (G_CRFD(op) == 0) - sprintf(oprs, "r%d,%s", G_RA(op), signed16); + oprs = util::string_format("r%d,%s", G_RA(op), signed16); else - sprintf(oprs, "cr%d,r%d,%s", G_CRFD(op), G_RA(op), signed16); + oprs = util::string_format("cr%d,r%d,%s", G_CRFD(op), G_RA(op), signed16); break; case F_CMP_UIMM: if (G_L(op)) - strcat(mnem, "d"); + mnem += "d"; if (G_CRFD(op) == 0) - sprintf(oprs, "r%d,0x%04X", G_RA(op), G_UIMM(op)); + oprs = util::string_format("r%d,0x%04X", G_RA(op), G_UIMM(op)); else - sprintf(oprs, "cr%d,r%d,0x%04X", G_CRFD(op), G_RA(op), G_UIMM(op)); + oprs = util::string_format("cr%d,r%d,0x%04X", G_CRFD(op), G_RA(op), G_UIMM(op)); break; case F_RA_RT: - sprintf(oprs, "r%d,r%d", G_RA(op), G_RT(op)); + oprs = util::string_format("r%d,r%d", G_RA(op), G_RT(op)); break; case F_CRBD_CRBA_CRBB: - sprintf(oprs, "cr%d[%s],cr%d[%s],cr%d[%s]", G_CRBD(op) / 4, crbit[G_CRBD(op) & 3], G_CRBA(op) / 4, crbit[G_CRBA(op) & 3], G_CRBB(op) / 4, crbit[G_CRBB(op) & 3]); + oprs = util::string_format("cr%d[%s],cr%d[%s],cr%d[%s]", G_CRBD(op) / 4, crbit[G_CRBD(op) & 3], G_CRBA(op) / 4, crbit[G_CRBA(op) & 3], G_CRBB(op) / 4, crbit[G_CRBB(op) & 3]); break; case F_RA_0_RB: if (G_RA(op)) - sprintf(oprs, "r%d,r%d", G_RA(op), G_RB(op)); + oprs = util::string_format("r%d,r%d", G_RA(op), G_RB(op)); else - sprintf(oprs, "0,r%d", G_RB(op)); + oprs = util::string_format("0,r%d", G_RB(op)); break; case F_RT_RA_0_RB: if (G_RA(op)) - sprintf(oprs, "r%d,r%d,r%d", G_RT(op), G_RA(op), G_RB(op)); + oprs = util::string_format("r%d,r%d,r%d", G_RT(op), G_RA(op), G_RB(op)); else - sprintf(oprs, "r%d,0,r%d", G_RT(op), G_RB(op)); + oprs = util::string_format("r%d,0,r%d", G_RT(op), G_RB(op)); break; case F_FRT_FRB: - sprintf(oprs, "f%d,f%d", G_RT(op), G_RB(op)); + oprs = util::string_format("f%d,f%d", G_RT(op), G_RB(op)); break; case F_FRT_FRA_FRB: - sprintf(oprs, "f%d,f%d,f%d", G_RT(op), G_RA(op), G_RB(op)); + oprs = util::string_format("f%d,f%d,f%d", G_RT(op), G_RA(op), G_RB(op)); break; case F_FCMP: - sprintf(oprs, "cr%d,f%d,f%d", G_CRFD(op), G_RA(op), G_RB(op)); + oprs = util::string_format("cr%d,f%d,f%d", G_CRFD(op), G_RA(op), G_RB(op)); break; case F_FRT_FRA_FRC_FRB: - sprintf(oprs, "f%d,f%d,f%d,f%d", G_RT(op), G_RA(op), G_REGC(op), G_RB(op)); + oprs = util::string_format("f%d,f%d,f%d,f%d", G_RT(op), G_RA(op), G_REGC(op), G_RB(op)); break; case F_FRT_FRA_FRC: - sprintf(oprs, "f%d,f%d,f%d", G_RT(op), G_RA(op), G_REGC(op)); + oprs = util::string_format("f%d,f%d,f%d", G_RT(op), G_RA(op), G_REGC(op)); break; case F_RT_D_RA_0: if (G_RA(op)) - sprintf(oprs, "r%d,%s(r%d)", G_RT(op), signed16, G_RA(op)); + oprs = util::string_format("r%d,%s(r%d)", G_RT(op), signed16, G_RA(op)); else - sprintf(oprs, "r%d,0x%08X", G_RT(op), (uint32_t) ((int16_t) G_D(op))); + oprs = util::string_format("r%d,0x%08X", G_RT(op), (uint32_t) ((int16_t) G_D(op))); break; case F_RT_D_RA: - sprintf(oprs, "r%d,%s(r%d)", G_RT(op), signed16, G_RA(op)); + oprs = util::string_format("r%d,%s(r%d)", G_RT(op), signed16, G_RA(op)); break; case F_FRT_D_RA_0: if (G_RA(op)) - sprintf(oprs, "f%d,%s(r%d)", G_RT(op), signed16, G_RA(op)); + oprs = util::string_format("f%d,%s(r%d)", G_RT(op), signed16, G_RA(op)); else - sprintf(oprs, "f%d,0x%08X", G_RT(op), (uint32_t) ((int16_t) G_D(op))); + oprs = util::string_format("f%d,0x%08X", G_RT(op), (uint32_t) ((int16_t) G_D(op))); break; case F_FRT_D_RA: - sprintf(oprs, "f%d,%s(r%d)", G_RT(op), signed16, G_RA(op)); + oprs = util::string_format("f%d,%s(r%d)", G_RT(op), signed16, G_RA(op)); break; case F_FRT_RA_RB: - sprintf(oprs, "f%d,r%d,r%d", G_RT(op), G_RA(op), G_RB(op)); + oprs = util::string_format("f%d,r%d,r%d", G_RT(op), G_RA(op), G_RB(op)); break; case F_FRT_RA_0_RB: if (G_RA(op)) - sprintf(oprs, "f%d,r%d,r%d", G_RT(op), G_RA(op), G_RB(op)); + oprs = util::string_format("f%d,r%d,r%d", G_RT(op), G_RA(op), G_RB(op)); else - sprintf(oprs, "f%d,0,r%d", G_RT(op), G_RB(op)); + oprs = util::string_format("f%d,0,r%d", G_RT(op), G_RB(op)); break; case F_RT_RA_0_NB: if (G_RA(op)) - sprintf(oprs, "r%d,r%d,%d", G_RT(op), G_RA(op), G_NB(op) ? G_NB(op) : 32); + oprs = util::string_format("r%d,r%d,%d", G_RT(op), G_RA(op), G_NB(op) ? G_NB(op) : 32); else - sprintf(oprs, "r%d,0,%d", G_RT(op), G_NB(op) ? G_NB(op) : 32); + oprs = util::string_format("r%d,0,%d", G_RT(op), G_NB(op) ? G_NB(op) : 32); break; case F_CRFD_CRFS: - sprintf(oprs, "cr%d,cr%d", G_CRFD(op), G_CRFS(op)); + oprs = util::string_format("cr%d,cr%d", G_CRFD(op), G_CRFS(op)); break; case F_MCRXR: - sprintf(oprs, "cr%d", G_CRFD(op)); + oprs = util::string_format("cr%d", G_CRFD(op)); break; case F_RT: - sprintf(oprs, "r%d", G_RT(op)); + oprs = util::string_format("r%d", G_RT(op)); break; case F_MFFSx: - sprintf(oprs, "f%d", G_RT(op)); + oprs = util::string_format("f%d", G_RT(op)); break; case F_FCRBD: - sprintf(oprs, "fpscr[%d]", G_CRBD(op)); + oprs = util::string_format("fpscr[%d]", G_CRBD(op)); break; case F_RT_SPR: - sprintf(oprs, "r%d,", G_RT(op)); - SPR(oprs, G_SPR(op)); + oprs = util::string_format("r%d,", G_RT(op)) + SPR(G_SPR(op)); break; case F_RT_DCR: - sprintf(oprs, "r%d,", G_RT(op)); - DCR(oprs, G_DCR(op)); + oprs = util::string_format("r%d,", G_RT(op)) + DCR(G_DCR(op)); break; case F_MFSR: - sprintf(oprs, "r%d,sr%d", G_RT(op), G_SR(op)); + oprs = util::string_format("r%d,sr%d", G_RT(op), G_SR(op)); break; case F_MTCRF: - sprintf(oprs, "0x%02X,r%d", G_CRM(op), G_RT(op)); + oprs = util::string_format("0x%02X,r%d", G_CRM(op), G_RT(op)); break; case F_MTFSFx: - sprintf(oprs, "0x%02X,f%d", G_FM(op), G_RB(op)); + oprs = util::string_format("0x%02X,f%d", G_FM(op), G_RB(op)); break; case F_MTFSFIx: - sprintf(oprs, "cr%d,0x%X", G_CRFD(op), G_IMM(op)); + oprs = util::string_format("cr%d,0x%X", G_CRFD(op), G_IMM(op)); break; case F_MTSPR: - SPR(oprs, G_SPR(op)); - sprintf(oprs + strlen(oprs), ",r%d", G_RT(op)); + oprs = SPR(G_SPR(op)) + util::string_format(",r%d", G_RT(op)); break; case F_MTDCR: - DCR(oprs, G_DCR(op)); - sprintf(oprs + strlen(oprs), ",r%d", G_RT(op)); + oprs = DCR(G_DCR(op)) + util::string_format(",r%d", G_RT(op)); break; case F_MTSR: - sprintf(oprs, "sr%d,r%d", G_SR(op), G_RT(op)); + oprs = util::string_format("sr%d,r%d", G_SR(op), G_RT(op)); break; case F_RT_RB: - sprintf(oprs, "r%d,r%d", G_RT(op), G_RB(op)); + oprs = util::string_format("r%d,r%d", G_RT(op), G_RB(op)); break; case F_RA_RT_SH_MB_ME: - sprintf(oprs, "r%d,r%d,%d,%d,%d", G_RA(op), G_RT(op), G_SH(op), G_MB(op), G_ME(op)); + oprs = util::string_format("r%d,r%d,%d,%d,%d", G_RA(op), G_RT(op), G_SH(op), G_MB(op), G_ME(op)); break; case F_RLWNMx: - sprintf(oprs, "r%d,r%d,r%d,%d,%d", G_RA(op), G_RT(op), G_RB(op), G_MB(op), G_ME(op)); + oprs = util::string_format("r%d,r%d,r%d,%d,%d", G_RA(op), G_RT(op), G_RB(op), G_MB(op), G_ME(op)); break; case F_SRAWIx: - sprintf(oprs, "r%d,r%d,%d", G_RA(op), G_RT(op), G_SH(op)); + oprs = util::string_format("r%d,r%d,%d", G_RA(op), G_RT(op), G_SH(op)); break; case F_RB: - sprintf(oprs, "r%d", G_RB(op)); + oprs = util::string_format("r%d", G_RB(op)); break; case F_TW: - sprintf(oprs, "%d,r%d,r%d", G_TO(op), G_RA(op), G_RB(op)); + oprs = util::string_format("%d,r%d,r%d", G_TO(op), G_RA(op), G_RB(op)); break; case F_TWI: - sprintf(oprs, "%d,r%d,%s", G_TO(op), G_RA(op), signed16); + oprs = util::string_format("%d,r%d,%s", G_TO(op), G_RA(op), signed16); break; case F_NONE: @@ -1152,12 +986,12 @@ offs_t ppc_dasm_one(std::ostream &stream, uint32_t pc, uint32_t op) } if ((itab[i].flags & FL_LK) && (op & M_LK)) - flags |= DASMFLAG_STEP_OVER; + flags |= STEP_OVER; else if (itab[i].flags & FL_SO) - flags |= DASMFLAG_STEP_OUT; + flags |= STEP_OUT; util::stream_format(stream, "%s", mnem); - for( j = strlen(mnem); j < 10; j++ ) { + for( j = mnem.size(); j < 10; j++ ) { util::stream_format(stream, " "); } util::stream_format(stream, "%s", oprs); @@ -1169,10 +1003,12 @@ offs_t ppc_dasm_one(std::ostream &stream, uint32_t pc, uint32_t op) return 4 | flags; } +offs_t powerpc_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + return dasm_one(stream, pc, opcodes.r32(pc)); +} -CPU_DISASSEMBLE( powerpc ) +u32 powerpc_disassembler::opcode_alignment() const { - uint32_t op = *(uint32_t *)oprom; - op = big_endianize_int32(op); - return ppc_dasm_one(stream, pc, op); + return 4; } diff --git a/src/devices/cpu/powerpc/ppc_dasm.h b/src/devices/cpu/powerpc/ppc_dasm.h new file mode 100644 index 00000000000..5fab7dfe074 --- /dev/null +++ b/src/devices/cpu/powerpc/ppc_dasm.h @@ -0,0 +1,142 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +/* + * disasm.c + * + * PowerPC 603e disassembler. + * + * When possible, invalid forms of instructions are checked for. To the best + * of my knowledge, all appropriate load/store instructions are checked. I'm + * not sure whether any other kinds of instructions need checking. + */ + +/* Originally written by Bart Trzynadlowski for Supermodel project + * + * PowerPC 403 opcodes and MAME conversion by Ville Linde + */ + +#ifndef MAME_CPU_POWERPC_PPC_DASM_H +#define MAME_CPU_POWERPC_PPC_DASM_H + +#pragma once + +class powerpc_disassembler : public util::disasm_interface +{ +public: + powerpc_disassembler() = default; + virtual ~powerpc_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + static offs_t dasm_one(std::ostream &stream, uint32_t pc, uint32_t op); + +private: + /* + * Operand Formats + * + * These convey information on what operand fields are present and how they + * ought to be printed. + * + * I'm fairly certain all of these are used, but that is not guaranteed. + */ + + enum + { + F_NONE, // <no operands> + F_LI, // LI*4+PC if AA=0 else LI*4 + F_BCx, // BO, BI, target_addr used only by BCx + F_RT_RA_0_SIMM, // rT, rA|0, SIMM rA|0 means if rA == 0, print 0 + F_ADDIS, // rT, rA, SIMM (printed as unsigned) only used by ADDIS + F_RT_RA_SIMM, // rT, rA, SIMM + F_RA_RT_UIMM, // rA, rT, UIMM + F_CMP_SIMM, // crfD, L, A, SIMM + F_CMP_UIMM, // crfD, L, A, UIMM + F_RT_RA_0_RB, // rT, rA|0, rB + F_RT_RA_RB, // rT, rA, rB + F_RT_D_RA_0, // rT, d(rA|0) + F_RT_D_RA, // rT, d(rA) + F_RA_RT_RB, // rA, rT, rB + F_FRT_D_RA_0, // frT, d(RA|0) + F_FRT_D_RA, // frT, d(RA) + F_FRT_RA_0_RB, // frT, rA|0, rB + F_FRT_RA_RB, // frT, rA, rB + F_TWI, // TO, rA, SIMM only used by TWI instruction + F_CMP, // crfD, L, rA, rB + F_RA_RT, // rA, rT + F_RA_0_RB, // rA|0, rB + F_FRT_FRB, // frT, frB + F_FCMP, // crfD, frA, frB + F_CRFD_CRFS, // crfD, crfS + F_MCRXR, // crfD only used by MCRXR + F_RT, // rT + F_MFSR, // rT, SR only used by MFSR + F_MTSR, // SR, rT only used by MTSR + F_MFFSx, // frT only used by MFFSx + F_FCRBD, // crbD FPSCR[crbD] + F_MTFSFIx, // crfD, IMM only used by MTFSFIx + F_RB, // rB + F_TW, // TO, rA, rB only used by TW + F_RT_RA_0_NB, // rT, rA|0, NB print 32 if NB == 0 + F_SRAWIx, // rA, rT, SH only used by SRAWIx + F_BO_BI, // BO, BI + F_CRBD_CRBA_CRBB, // crbD, crbA, crbB + F_RT_SPR, // rT, SPR and TBR + F_MTSPR, // SPR, rT only used by MTSPR + F_MTCRF, // CRM, rT only used by MTCRF + F_MTFSFx, // FM, frB only used by MTFSFx + F_RT_DCR, // rT, DCR + F_MTDCR, // DCR, rT + F_RT_RA, // rT, rA + F_FRT_FRA_FRC_FRB, // frT, frA, frC, frB + F_FRT_FRA_FRB, // frT, frA, frB + F_FRT_FRA_FRC, // frT, frA, frC + F_RA_RT_SH_MB_ME, // rA, rT, SH, MB, ME + F_RLWNMx, // rT, rA, rB, MB, ME only used by RLWNMx + F_RT_RB // rT, rB + }; + + /* + * Flags + */ + + enum + { + FL_OE = 1 << 0, // if there is an OE field + FL_RC = 1 << 1, // if there is an RC field + FL_LK = 1 << 2, // if there is an LK field + FL_AA = 1 << 3, // if there is an AA field + FL_CHECK_RA_RT = 1 << 4, // assert rA!=0 and rA!=rT + FL_CHECK_RA = 1 << 5, // assert rA!=0 + FL_CHECK_LSWI = 1 << 6, // specific check for LSWI validity + FL_CHECK_LSWX = 1 << 7, // specific check for LSWX validity + FL_SO = 1 << 8 // use STEP_OUT + }; + + /* + * Instruction Descriptor + * + * Describes the layout of an instruction. + */ + + struct IDESCR + { + char mnem[32]; // mnemonic + uint32_t match; // bit pattern of instruction after it has been masked + uint32_t mask; // mask of variable fields (AND with ~mask to compare w/ + // bit pattern to determine a match) + int format; // operand format + int flags; // flags + }; + + static const IDESCR itab[]; + static const char *const crbit[4]; + static const char *const crnbit[4]; + + static std::string SPR(int spr_field); + static std::string DCR(int dcr_field); + static std::string DecodeSigned16(uint32_t op, int do_unsigned); + static uint32_t Mask(int mb, int me); + static bool Simplified(uint32_t op, uint32_t vpc, std::string &signed16, std::string &mnem, std::string &oprs); +}; + +#endif diff --git a/src/devices/cpu/powerpc/ppccom.cpp b/src/devices/cpu/powerpc/ppccom.cpp index 56a7325c460..9e4aecd3ee2 100644 --- a/src/devices/cpu/powerpc/ppccom.cpp +++ b/src/devices/cpu/powerpc/ppccom.cpp @@ -11,7 +11,7 @@ #include "emu.h" #include "ppccom.h" #include "ppcfe.h" - +#include "ppc_dasm.h" /*************************************************************************** DEBUGGING @@ -710,7 +710,7 @@ void ppc_device::device_start() m_cache_line_size = 32; m_cpu_clock = clock(); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_system_clock = c_bus_frequency != 0 ? c_bus_frequency : clock(); m_dcr_read_func = read32_delegate(); m_dcr_write_func = write32_delegate(); @@ -799,88 +799,14 @@ void ppc_device::device_start() state_add(PPC_TBL, "TBL", m_debugger_temp).callimport().callexport().formatstr("%08X"); state_add(PPC_DEC, "DEC", m_debugger_temp).callimport().callexport().formatstr("%08X"); - state_add(PPC_SR0, "SR0", m_core->sr[0]).formatstr("%08X"); - state_add(PPC_SR1, "SR1", m_core->sr[1]).formatstr("%08X"); - state_add(PPC_SR2, "SR2", m_core->sr[2]).formatstr("%08X"); - state_add(PPC_SR3, "SR3", m_core->sr[3]).formatstr("%08X"); - state_add(PPC_SR4, "SR4", m_core->sr[4]).formatstr("%08X"); - state_add(PPC_SR5, "SR5", m_core->sr[5]).formatstr("%08X"); - state_add(PPC_SR6, "SR6", m_core->sr[6]).formatstr("%08X"); - state_add(PPC_SR7, "SR7", m_core->sr[7]).formatstr("%08X"); - state_add(PPC_SR8, "SR8", m_core->sr[8]).formatstr("%08X"); - state_add(PPC_SR9, "SR9", m_core->sr[9]).formatstr("%08X"); - state_add(PPC_SR10, "SR10", m_core->sr[10]).formatstr("%08X"); - state_add(PPC_SR11, "SR11", m_core->sr[11]).formatstr("%08X"); - state_add(PPC_SR12, "SR12", m_core->sr[12]).formatstr("%08X"); - state_add(PPC_SR13, "SR13", m_core->sr[13]).formatstr("%08X"); - state_add(PPC_SR14, "SR14", m_core->sr[14]).formatstr("%08X"); - state_add(PPC_SR15, "SR15", m_core->sr[15]).formatstr("%08X"); - - state_add(PPC_R0, "R0", m_core->r[0]).formatstr("%08X"); - state_add(PPC_R1, "R1", m_core->r[1]).formatstr("%08X"); - state_add(PPC_R2, "R2", m_core->r[2]).formatstr("%08X"); - state_add(PPC_R3, "R3", m_core->r[3]).formatstr("%08X"); - state_add(PPC_R4, "R4", m_core->r[4]).formatstr("%08X"); - state_add(PPC_R5, "R5", m_core->r[5]).formatstr("%08X"); - state_add(PPC_R6, "R6", m_core->r[6]).formatstr("%08X"); - state_add(PPC_R7, "R7", m_core->r[7]).formatstr("%08X"); - state_add(PPC_R8, "R8", m_core->r[8]).formatstr("%08X"); - state_add(PPC_R9, "R9", m_core->r[9]).formatstr("%08X"); - state_add(PPC_R10, "R10", m_core->r[10]).formatstr("%08X"); - state_add(PPC_R11, "R11", m_core->r[11]).formatstr("%08X"); - state_add(PPC_R12, "R12", m_core->r[12]).formatstr("%08X"); - state_add(PPC_R13, "R13", m_core->r[13]).formatstr("%08X"); - state_add(PPC_R14, "R14", m_core->r[14]).formatstr("%08X"); - state_add(PPC_R15, "R15", m_core->r[15]).formatstr("%08X"); - state_add(PPC_R16, "R16", m_core->r[16]).formatstr("%08X"); - state_add(PPC_R17, "R17", m_core->r[17]).formatstr("%08X"); - state_add(PPC_R18, "R18", m_core->r[18]).formatstr("%08X"); - state_add(PPC_R19, "R19", m_core->r[19]).formatstr("%08X"); - state_add(PPC_R20, "R20", m_core->r[20]).formatstr("%08X"); - state_add(PPC_R21, "R21", m_core->r[21]).formatstr("%08X"); - state_add(PPC_R22, "R22", m_core->r[22]).formatstr("%08X"); - state_add(PPC_R23, "R23", m_core->r[23]).formatstr("%08X"); - state_add(PPC_R24, "R24", m_core->r[24]).formatstr("%08X"); - state_add(PPC_R25, "R25", m_core->r[25]).formatstr("%08X"); - state_add(PPC_R26, "R26", m_core->r[26]).formatstr("%08X"); - state_add(PPC_R27, "R27", m_core->r[27]).formatstr("%08X"); - state_add(PPC_R28, "R28", m_core->r[28]).formatstr("%08X"); - state_add(PPC_R29, "R29", m_core->r[29]).formatstr("%08X"); - state_add(PPC_R30, "R30", m_core->r[30]).formatstr("%08X"); - state_add(PPC_R31, "R31", m_core->r[31]).formatstr("%08X"); - - state_add(PPC_F0, "F0", m_core->f[0]).formatstr("%12s"); - state_add(PPC_F1, "F1", m_core->f[1]).formatstr("%12s"); - state_add(PPC_F2, "F2", m_core->f[2]).formatstr("%12s"); - state_add(PPC_F3, "F3", m_core->f[3]).formatstr("%12s"); - state_add(PPC_F4, "F4", m_core->f[4]).formatstr("%12s"); - state_add(PPC_F5, "F5", m_core->f[5]).formatstr("%12s"); - state_add(PPC_F6, "F6", m_core->f[6]).formatstr("%12s"); - state_add(PPC_F7, "F7", m_core->f[7]).formatstr("%12s"); - state_add(PPC_F8, "F8", m_core->f[8]).formatstr("%12s"); - state_add(PPC_F9, "F9", m_core->f[9]).formatstr("%12s"); - state_add(PPC_F10, "F10", m_core->f[10]).formatstr("%12s"); - state_add(PPC_F11, "F11", m_core->f[11]).formatstr("%12s"); - state_add(PPC_F12, "F12", m_core->f[12]).formatstr("%12s"); - state_add(PPC_F13, "F13", m_core->f[13]).formatstr("%12s"); - state_add(PPC_F14, "F14", m_core->f[14]).formatstr("%12s"); - state_add(PPC_F15, "F15", m_core->f[15]).formatstr("%12s"); - state_add(PPC_F16, "F16", m_core->f[16]).formatstr("%12s"); - state_add(PPC_F17, "F17", m_core->f[17]).formatstr("%12s"); - state_add(PPC_F18, "F18", m_core->f[18]).formatstr("%12s"); - state_add(PPC_F19, "F19", m_core->f[19]).formatstr("%12s"); - state_add(PPC_F20, "F20", m_core->f[20]).formatstr("%12s"); - state_add(PPC_F21, "F21", m_core->f[21]).formatstr("%12s"); - state_add(PPC_F22, "F22", m_core->f[22]).formatstr("%12s"); - state_add(PPC_F23, "F23", m_core->f[23]).formatstr("%12s"); - state_add(PPC_F24, "F24", m_core->f[24]).formatstr("%12s"); - state_add(PPC_F25, "F25", m_core->f[25]).formatstr("%12s"); - state_add(PPC_F26, "F26", m_core->f[26]).formatstr("%12s"); - state_add(PPC_F27, "F27", m_core->f[27]).formatstr("%12s"); - state_add(PPC_F28, "F28", m_core->f[28]).formatstr("%12s"); - state_add(PPC_F29, "F29", m_core->f[29]).formatstr("%12s"); - state_add(PPC_F30, "F30", m_core->f[30]).formatstr("%12s"); - state_add(PPC_F31, "F31", m_core->f[31]).formatstr("%12s"); + for (int regnum = 0; regnum < 16; regnum++) + state_add(PPC_SR0 + regnum, string_format("SR%d", regnum).c_str(), m_core->sr[regnum]).formatstr("%08X"); + + for (int regnum = 0; regnum < 32; regnum++) + state_add(PPC_R0 + regnum, string_format("R%d", regnum).c_str(), m_core->r[regnum]).formatstr("%08X"); + + for (int regnum = 0; regnum < 32; regnum++) + state_add(PPC_F0 + regnum, string_format("F%d", regnum).c_str(), m_core->f[regnum]).formatstr("%12s"); state_add(PPC_FPSCR, "FPSCR", m_core->fpscr).formatstr("%08X"); state_add(STATE_GENPC, "GENPC", m_core->pc).noshow(); @@ -1239,11 +1165,9 @@ void ppc_device::device_reset() CPU -------------------------------------------------*/ -offs_t ppc_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *ppc_device::create_disassembler() { - uint32_t op = *(uint32_t *)oprom; - op = big_endianize_int32(op); - return ppc_dasm_one(stream, pc, op); + return new powerpc_disassembler; } diff --git a/src/devices/cpu/powerpc/ppcdrc.cpp b/src/devices/cpu/powerpc/ppcdrc.cpp index 741e75f9cc2..ac587dc3259 100644 --- a/src/devices/cpu/powerpc/ppcdrc.cpp +++ b/src/devices/cpu/powerpc/ppcdrc.cpp @@ -19,6 +19,7 @@ #include "ppc.h" #include "ppccom.h" #include "ppcfe.h" +#include "ppc_dasm.h" #include "cpu/drcfe.h" #include "cpu/drcuml.h" #include "cpu/drcumlsh.h" @@ -3316,7 +3317,7 @@ bool ppc_device::generate_instruction_1f(drcuml_block *block, compiler_state *co UML_MOV(block, R32(G_RD(op)), m_flavor); // mov rd,flavor else { - generate_update_cycles(block, compiler, desc->pc, true); // <update cycles> + generate_update_cycles(block, compiler, desc->pc, false); // <update cycles> UML_MOV(block, mem(&m_core->param0), spr); // mov [param0],spr UML_CALLC(block, (c_function)cfunc_ppccom_execute_mfspr, this); // callc ppccom_execute_mfspr,ppc UML_MOV(block, R32(G_RD(op)), mem(&m_core->param1)); // mov rd,[param1] @@ -3338,7 +3339,7 @@ bool ppc_device::generate_instruction_1f(drcuml_block *block, compiler_state *co uint32_t tbr = compute_spr(G_SPR(op)); if (tbr != SPRVEA_TBL_R && tbr != SPRVEA_TBU_R) return false; - generate_update_cycles(block, compiler, desc->pc, true); // <update cycles> + generate_update_cycles(block, compiler, desc->pc, false); // <update cycles> UML_MOV(block, mem(&m_core->param0), tbr); // mov [param0],tbr UML_CALLC(block, (c_function)cfunc_ppccom_execute_mftb, this); // callc ppccom_execute_mftb,ppc UML_MOV(block, R32(G_RD(op)), mem(&m_core->param1)); // mov rd,[param1] @@ -3383,7 +3384,7 @@ bool ppc_device::generate_instruction_1f(drcuml_block *block, compiler_state *co ; // read only else { - generate_update_cycles(block, compiler, desc->pc, true); // <update cycles> + generate_update_cycles(block, compiler, desc->pc, false); // <update cycles> UML_MOV(block, mem(&m_core->param0), spr); // mov [param0],spr UML_MOV(block, mem(&m_core->param1), R32(G_RS(op))); // mov [param1],rs UML_CALLC(block, (c_function)cfunc_ppccom_execute_mtspr, this); // callc ppccom_execute_mtspr,ppc @@ -3429,7 +3430,7 @@ bool ppc_device::generate_instruction_1f(drcuml_block *block, compiler_state *co { uint32_t spr = compute_spr(G_SPR(op)); assert(m_cap & PPCCAP_4XX); - generate_update_cycles(block, compiler, desc->pc, true); // <update cycles> + generate_update_cycles(block, compiler, desc->pc, false); // <update cycles> UML_MOV(block, mem(&m_core->param0), spr); // mov [param0],spr UML_CALLC(block, (c_function)cfunc_ppccom_execute_mfdcr, this); // callc ppccom_execute_mfdcr,ppc UML_MOV(block, R32(G_RD(op)), mem(&m_core->param1)); // mov rd,[param1] @@ -3440,7 +3441,7 @@ bool ppc_device::generate_instruction_1f(drcuml_block *block, compiler_state *co { uint32_t spr = compute_spr(G_SPR(op)); assert(m_cap & PPCCAP_4XX); - generate_update_cycles(block, compiler, desc->pc, true); // <update cycles> + generate_update_cycles(block, compiler, desc->pc, false); // <update cycles> UML_MOV(block, mem(&m_core->param0), spr); // mov [param0],spr UML_MOV(block, mem(&m_core->param1), R32(G_RS(op))); // mov [param1],rs UML_CALLC(block, (c_function)cfunc_ppccom_execute_mtdcr, this); // callc ppccom_execute_mtdcr,ppc @@ -3770,10 +3771,9 @@ void ppc_device::log_add_disasm_comment(drcuml_block *block, uint32_t pc, uint32 { if (m_drcuml->logging()) { - util::ovectorstream stream; - ppc_dasm_one(stream, pc, op); - stream.put('\0'); - block->append_comment("%08X: %s", pc, &stream.vec()[0]); // comment + std::ostringstream stream; + powerpc_disassembler::dasm_one(stream, pc, op); + block->append_comment("%08X: %s", pc, stream.str()); // comment } } @@ -3961,7 +3961,7 @@ void ppc_device::log_opcode_desc(drcuml_state *drcuml, const opcode_desc *descli if (desclist->flags & OPFLAG_VIRTUAL_NOOP) buffer << "<virtual nop>"; else - ppc_dasm_one(buffer, desclist->pc, desclist->opptr.l[0]); + powerpc_disassembler::dasm_one(buffer, desclist->pc, desclist->opptr.l[0]); } else buffer << "???"; diff --git a/src/devices/cpu/pps4/pps4.cpp b/src/devices/cpu/pps4/pps4.cpp index c0b5ad60aa8..8decf412b8d 100644 --- a/src/devices/cpu/pps4/pps4.cpp +++ b/src/devices/cpu/pps4/pps4.cpp @@ -78,6 +78,7 @@ #include "emu.h" #include "pps4.h" +#include "pps4dasm.h" #include "debugger.h" @@ -139,10 +140,9 @@ void pps4_device::W(u8 data) m_SAG = 0; } -offs_t pps4_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +util::disasm_interface *pps4_device::create_disassembler() { - extern CPU_DISASSEMBLE( pps4 ); - return CPU_DISASSEMBLE_NAME(pps4)(this, stream, pc, oprom, opram, options); + return new pps4_disassembler; } /** @@ -1570,7 +1570,7 @@ void pps4_device::execute_run() void pps4_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_data = &space(AS_DATA); m_io = &space(AS_IO); diff --git a/src/devices/cpu/pps4/pps4.h b/src/devices/cpu/pps4/pps4.h index ef3c4dee977..fcf1d790756 100644 --- a/src/devices/cpu/pps4/pps4.h +++ b/src/devices/cpu/pps4/pps4.h @@ -82,9 +82,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual u32 disasm_min_opcode_bytes() const override { return 1; } - virtual u32 disasm_max_opcode_bytes() const override { return 2; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; address_space_config m_program_config; address_space_config m_data_config; @@ -95,7 +93,7 @@ protected: devcb_write8 m_do_cb; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_data; address_space *m_io; int m_icount; diff --git a/src/devices/cpu/pps4/pps4dasm.cpp b/src/devices/cpu/pps4/pps4dasm.cpp index 71bf93dcb44..edb15db12b3 100644 --- a/src/devices/cpu/pps4/pps4dasm.cpp +++ b/src/devices/cpu/pps4/pps4dasm.cpp @@ -11,36 +11,9 @@ * *****************************************************************************/ #include "emu.h" +#include "pps4dasm.h" -#define OP(A) oprom[(A) - PC] -#define ARG(A) opram[(A) - PC] - -typedef enum pps4_token_e { - t_AD, t_ADC, t_ADSK, t_ADCSK, t_ADI, - t_DC, t_AND, t_OR, t_EOR, t_COMP, - t_SC, t_RC, t_SF1, t_RF1, t_SF2, - t_RF2, t_LD, t_EX, t_EXD, t_LDI, - t_LAX, t_LXA, t_LABL, t_LBMX, t_LBUA, - t_XABL, t_XBMX, t_XAX, t_XS, t_CYS, - t_LB, t_LBL, t_INCB, t_DECB, t_T, - t_TM, t_TL, t_TML, t_SKC, t_SKZ, - t_SKBI, t_SKF1, t_SKF2, t_RTN, t_RTNSK, - t_IOL, t_DIA, t_DIB, t_DOA, t_SAG, - t_COUNT, - t_MASK = (1 << 6) - 1, - t_I3c = 1 << 6, /* immediate 3 bit constant, complemented */ - t_I4 = 1 << 7, /* immediate 4 bit constant */ - t_I4c = 1 << 8, /* immediate 4 bit constant, complemented */ - t_I4p = 1 << 9, /* immediate 4 bit offset into page 3 */ - t_I6p = 1 << 10, /* immediate 6 bit constant; address in current page */ - t_I6i = 1 << 11, /* immediate 6 bit indirect page 3 offset (16 ... 63) + followed by page 1 address */ - t_I8 = 1 << 12, /* immediate 8 bit constant (I/O port number) */ - t_I8c = 1 << 13, /* immediate 8 bit constant inverted */ - t_OVER = 1 << 14, /* Debugger step over (CALL) */ - t_OUT = 1 << 15 /* Debugger step out (RETURN) */ -} pps4_token_e; - -static const char *token_str[t_COUNT] = { +const char *pps4_disassembler::token_str[t_COUNT] = { "ad", /* add */ "adc", /* add with carry-in */ "adsk", /* add and skip on carry-out */ @@ -93,7 +66,7 @@ static const char *token_str[t_COUNT] = { "sag" /* special address generation */ }; -static const uint16_t table[] = { +const uint16_t pps4_disassembler::table[] = { /* 00 */ t_LBL | t_I8c, /* 01 */ t_TML | t_I4 | t_I8, /* 02 */ t_TML | t_I4 | t_I8, @@ -367,11 +340,16 @@ static const uint16_t table[] = { /* ff */ t_TM | t_I6i | t_OVER }; -CPU_DISASSEMBLE(pps4) +u32 pps4_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t pps4_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint32_t flags = 0; unsigned PC = pc; - uint8_t op = OP(pc++); + uint8_t op = opcodes.r8(pc++); uint32_t tok = table[op]; if (0 == (tok & t_MASK)) { @@ -422,21 +400,21 @@ CPU_DISASSEMBLE(pps4) if (tok & t_I8) { // 8 bit immediate I/O port address - uint8_t arg = ARG(pc++); + uint8_t arg = params.r8(pc++); util::stream_format(stream, "%02x", arg); } if (tok & t_I8c) { // 8 bit immediate offset into page - uint16_t arg = ~ARG(pc++) & 255; + uint16_t arg = ~params.r8(pc++) & 255; util::stream_format(stream, "%02x", arg); } if (tok & t_OVER) // TL or TML - flags |= DASMFLAG_STEP_OVER; + flags |= STEP_OVER; if (tok & t_OUT) // RTN or RTNSK - flags |= DASMFLAG_STEP_OUT; + flags |= STEP_OUT; - return (pc - PC) | flags | DASMFLAG_SUPPORTED; + return (pc - PC) | flags | SUPPORTED; } diff --git a/src/devices/cpu/pps4/pps4dasm.h b/src/devices/cpu/pps4/pps4dasm.h new file mode 100644 index 00000000000..7e0f0ab9b91 --- /dev/null +++ b/src/devices/cpu/pps4/pps4dasm.h @@ -0,0 +1,59 @@ +// license:BSD-3-Clause +// copyright-holders:Juergen Buchmueller +/***************************************************************************** + * + * pps4dasm.c + * + * Rockwell PPS-4 CPU Disassembly + * + * + * TODO: double verify all opcodes with t_Ixx flags + * + *****************************************************************************/ + +#ifndef MAME_CPU_PPS4_PPS4DASM_H +#define MAME_CPU_PPS4_PPS4DASM_H + +#pragma once + +class pps4_disassembler : public util::disasm_interface +{ +public: + pps4_disassembler() = default; + virtual ~pps4_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + typedef enum pps4_token_e { + t_AD, t_ADC, t_ADSK, t_ADCSK, t_ADI, + t_DC, t_AND, t_OR, t_EOR, t_COMP, + t_SC, t_RC, t_SF1, t_RF1, t_SF2, + t_RF2, t_LD, t_EX, t_EXD, t_LDI, + t_LAX, t_LXA, t_LABL, t_LBMX, t_LBUA, + t_XABL, t_XBMX, t_XAX, t_XS, t_CYS, + t_LB, t_LBL, t_INCB, t_DECB, t_T, + t_TM, t_TL, t_TML, t_SKC, t_SKZ, + t_SKBI, t_SKF1, t_SKF2, t_RTN, t_RTNSK, + t_IOL, t_DIA, t_DIB, t_DOA, t_SAG, + t_COUNT, + t_MASK = (1 << 6) - 1, + t_I3c = 1 << 6, /* immediate 3 bit constant, complemented */ + t_I4 = 1 << 7, /* immediate 4 bit constant */ + t_I4c = 1 << 8, /* immediate 4 bit constant, complemented */ + t_I4p = 1 << 9, /* immediate 4 bit offset into page 3 */ + t_I6p = 1 << 10, /* immediate 6 bit constant; address in current page */ + t_I6i = 1 << 11, /* immediate 6 bit indirect page 3 offset (16 ... 63) + followed by page 1 address */ + t_I8 = 1 << 12, /* immediate 8 bit constant (I/O port number) */ + t_I8c = 1 << 13, /* immediate 8 bit constant inverted */ + t_OVER = 1 << 14, /* Debugger step over (CALL) */ + t_OUT = 1 << 15 /* Debugger step out (RETURN) */ + } pps4_token_e; + + static const char *token_str[t_COUNT]; + static const uint16_t table[]; + +}; + +#endif diff --git a/src/devices/cpu/psx/dismips.cpp b/src/devices/cpu/psx/dismips.cpp deleted file mode 100644 index 2551a2d56a8..00000000000 --- a/src/devices/cpu/psx/dismips.cpp +++ /dev/null @@ -1,332 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:smf -/* - * standalone MIPS disassembler by smf - * - * based on DIS68k by Aaron Giles - * - */ - -#include "emu.h" -#include "psx.h" - -extern CPU_DISASSEMBLE( r3000le ); - -static struct -{ - uint8_t id[ 8 ]; - uint32_t text; /* SCE only */ - uint32_t data; /* SCE only */ - uint32_t pc0; - uint32_t gp0; /* SCE only */ - uint32_t t_addr; - uint32_t t_size; - uint32_t d_addr; /* SCE only */ - uint32_t d_size; /* SCE only */ - uint32_t b_addr; /* SCE only */ - uint32_t b_size; /* SCE only */ - uint32_t s_addr; - uint32_t s_size; - uint32_t SavedSP; - uint32_t SavedFP; - uint32_t SavedGP; - uint32_t SavedRA; - uint32_t SavedS0; - uint8_t dummy[ 0x800 - 76 ]; -} m_psxexe_header; - -#define FORMAT_BIN ( 0 ) -#define FORMAT_PSX ( 1 ) - -#define CPU_PSX ( 0 ) -#define CPU_R3000 ( 1 ) -#define CPU_R4000 ( 2 ) - -static uint8_t *filebuf; -static uint32_t offset; -static uint8_t order[] = { 0, 1, 2, 3 }; - -static const char *const Options[]= -{ - "begin", "end", "offset", "order", "format", "cpu", 0 -}; - -static void usage (void) -{ - fprintf( stderr, - "Usage: DISMIPS [options] <filename>\n\n" - "Available options are:\n" - " -begin - Specify begin offset in file to disassemble in bytes [0]\n" - " -end - Specify end offset in file to disassemble in bytes [none]\n" - " -offset - Specify address to load program in bytes [0]\n" - " -order - Specify byte order [0123]\n" - " -format - Specify file format bin|psx [bin]\n" - " -cpu - Specify cpu psx|r3000|r4000 [psx]\n\n" - "All values should be entered in hexadecimal\n" ); - exit( 1 ); -} - -int main( int argc, char *argv[] ) -{ - FILE *f; - uint8_t i; - uint8_t j; - uint8_t n; - uint8_t p; - uint32_t begin; - uint32_t end; - uint32_t filelen; - uint32_t len; - uint32_t pc; - char buffer[ 80 ]; - char *filename; - uint32_t format; - uint32_t cpu; - - filename = nullptr; - begin = 0; - end = 0xffffffff; - format = FORMAT_BIN; - cpu = CPU_PSX; - - n = 0; - for( i = 1; i < argc; i++ ) - { - if( argv[ i ][ 0 ] != '-' ) - { - switch( n ) - { - case 0: - filename = argv[ i ]; - break; - default: - usage(); - break; - } - n++; - } - else - { - for( j = 0; Options[ j ]; j++ ) - { - if( strcmp( argv[ i ] + 1, Options[ j ] ) == 0 ) - { - break; - } - } - switch( j ) - { - case 0: - i++; - if( i > argc ) - { - usage(); - } - begin = strtoul( argv[ i ], 0, 16 ); - break; - case 1: - i++; - if( i > argc ) - { - usage(); - } - end = strtoul( argv[ i ], 0, 16 ); - break; - case 2: - i++; - if( i > argc ) - { - usage(); - } - offset = strtoul( argv[ i ], 0, 16 ); - break; - case 3: - i++; - if( i > argc ) - { - usage(); - } - if( strlen( argv[ i ] ) != 4 ) - { - usage(); - } - for( p = 0; p < 4; p++ ) - { - if( argv[ i ][ p ] < '0' || argv[ i ][ p ] > '3' ) - { - usage(); - } - order[ p ] = argv[ i ][ p ] - '0'; - } - break; - case 4: - i++; - if( i > argc ) - { - usage(); - } - if( core_stricmp( argv[ i ], "bin" ) == 0 ) - { - format = FORMAT_BIN; - } - else if( core_stricmp( argv[ i ], "psx" ) == 0 ) - { - format = FORMAT_PSX; - } - else - { - usage(); - } - break; - case 5: - i++; - if( i > argc ) - { - usage(); - } - if( core_stricmp( argv[ i ], "psx" ) == 0 ) - { - cpu = CPU_PSX; - } - else if( core_stricmp( argv[ i ], "r3000" ) == 0 ) - { - cpu = CPU_R3000; - } - else if( core_stricmp( argv[ i ], "r4000" ) == 0 ) - { - cpu = CPU_R4000; - } - else - { - usage(); - } - break; - default: - usage(); - break; - } - } - } - - if (!filename) - { - usage(); - return 1; - } - f=fopen (filename,"rb"); - if (!f) - { - printf ("Unable to open %s\n",filename); - return 2; - } - fseek (f,0,SEEK_END); - filelen=ftell (f); - - if( format == FORMAT_PSX ) - { - fseek( f, 0, SEEK_SET ); - if( fread( &m_psxexe_header, 1, sizeof( m_psxexe_header ), f ) != sizeof( m_psxexe_header ) ) - { - fprintf( stderr, "error reading ps-x exe header\n" ); - fclose( f ); - return 3; - } - if( memcmp( m_psxexe_header.id, "PS-X EXE", sizeof( m_psxexe_header.id ) ) != 0 ) - { - fprintf( stderr, "invalid ps-x exe header\n" ); - fclose( f ); - return 3; - } - printf( "_start = $%08x\n\n", m_psxexe_header.pc0 ); - if( offset == 0 ) - { - offset = m_psxexe_header.t_addr; - } - if( begin == 0 ) - { - begin = sizeof( m_psxexe_header ); - } - if( end == 0xffffffff ) - { - end = sizeof( m_psxexe_header ) + m_psxexe_header.t_size; - } - } - - fseek (f,begin,SEEK_SET); - len=(filelen>end)? (end-begin+1):(filelen-begin); - filebuf=(uint8_t *)malloc(len+16); - if (!filebuf) - { - printf ("Memory allocation error\n"); - fclose (f); - return 3; - } - memset (filebuf,0,len+16); - if (fread(filebuf,1,len,f)!=len) - { - printf ("Read error\n"); - fclose (f); - free (filebuf); - return 4; - } - fclose (f); - - pc = 0; - while( pc < len ) - { - uint8_t op0 = filebuf[ pc + order[ 0 ] ]; - uint8_t op1 = filebuf[ pc + order[ 1 ] ]; - uint8_t op2 = filebuf[ pc + order[ 2 ] ]; - uint8_t op3 = filebuf[ pc + order[ 3 ] ]; - filebuf[ pc + 0 ] = op0; - filebuf[ pc + 1 ] = op1; - filebuf[ pc + 2 ] = op2; - filebuf[ pc + 3 ] = op3; - - pc += 4; - } - - pc = 0; - while( pc < len ) - { - switch( cpu ) - { - case CPU_PSX: - i = DasmPSXCPU( nullptr, buffer, pc + offset, filebuf + pc ); - break; - case CPU_R3000: - { - cpu_device *device = nullptr; - int options = 0; - uint8_t *opram = filebuf + pc; - uint8_t *oprom = opram; - i = CPU_DISASSEMBLE_CALL( r3000le ); - } - break; - case CPU_R4000: - { - uint8_t *opram = filebuf + pc; - uint32_t op = ( opram[ 3 ] << 24 ) | ( opram[ 2 ] << 16 ) | ( opram[ 1 ] << 8 ) | ( opram[ 0 ] << 0 ); - i = dasmmips3( buffer, pc + offset, op ); - } - break; - } - - i &= DASMFLAG_LENGTHMASK; - - printf( "%08x: ", pc + offset ); - for( j = 0; j < i; j++ ) - { - printf( "%02x ", filebuf[ pc ] ); - pc++; - } - while( j < 10 ) - { - printf( " " ); - j++; - } - printf( "%s\n", buffer ); - } - free (filebuf); - return 0; -} diff --git a/src/devices/cpu/psx/dismips.mak b/src/devices/cpu/psx/dismips.mak deleted file mode 100644 index a229a305bb4..00000000000 --- a/src/devices/cpu/psx/dismips.mak +++ /dev/null @@ -1,2 +0,0 @@ -..\..\..\..\dismips.exe: dismips.cpp psxdasm.cpp ..\mips\r3kdasm.cpp ..\mips\mips3dsm.cpp ../../../lib/util/corestr.cpp - g++ -O3 -x c++ -Wall -Wno-sign-compare -I../.. -I../../../emu -I../../../osd -I../../../lib/util -I../../../lib/expat -DINLINE="static __inline__" -DSTANDALONE -DLSB_FIRST dismips.cpp psxdasm.cpp ..\mips\r3kdasm.cpp ..\mips\mips3dsm.cpp ../../../lib/util/corestr.cpp -o../../../../dismips diff --git a/src/devices/cpu/psx/psx.cpp b/src/devices/cpu/psx/psx.cpp index 36d7c1742f4..2caef37ec85 100644 --- a/src/devices/cpu/psx/psx.cpp +++ b/src/devices/cpu/psx/psx.cpp @@ -1818,7 +1818,7 @@ void psxcpu_device::device_start() { // get our address spaces m_program = &space( AS_PROGRAM ); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); save_item( NAME( m_op ) ); save_item( NAME( m_pc ) ); @@ -2067,13 +2067,13 @@ void psxcpu_device::state_string_export( const device_state_entry &entry, std::s //------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t psxcpu_device::disasm_disassemble( std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options ) +util::disasm_interface *psxcpu_device::create_disassembler() { - return DasmPSXCPU( this, stream, pc, opram ); + return new psxcpu_disassembler(this); } diff --git a/src/devices/cpu/psx/psx.h b/src/devices/cpu/psx/psx.h index da70d2c300c..641a971c2ce 100644 --- a/src/devices/cpu/psx/psx.h +++ b/src/devices/cpu/psx/psx.h @@ -17,6 +17,7 @@ #include "gte.h" #include "irq.h" #include "sio.h" +#include "psxdasm.h" //************************************************************************** // CONSTANTS @@ -140,20 +141,9 @@ enum // TYPE DEFINITIONS //************************************************************************** -class psxcpu_state -{ -public: - virtual ~psxcpu_state() { } - - virtual uint32_t pc() = 0; - virtual uint32_t delayr() = 0; - virtual uint32_t delayv() = 0; - virtual uint32_t r(int i) = 0; -}; - // ======================> psxcpu_device -class psxcpu_device : public cpu_device, psxcpu_state +class psxcpu_device : public cpu_device, psxcpu_disassembler::config { public: // static configuration helpers @@ -229,9 +219,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 4; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 8; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // CPU registers uint32_t m_pc; @@ -246,7 +234,7 @@ protected: // address spaces const address_space_config m_program_config; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; // other internal states int m_icount; @@ -409,6 +397,4 @@ DECLARE_DEVICE_TYPE(CXD8606BQ, cxd8606bq_device) DECLARE_DEVICE_TYPE(CXD8606CQ, cxd8606cq_device) -extern unsigned DasmPSXCPU(psxcpu_state *state, std::ostream &stream, uint32_t pc, const uint8_t *opram); - #endif // MAME_CPU_PSX_PSX_H diff --git a/src/devices/cpu/psx/psxdasm.cpp b/src/devices/cpu/psx/psxdasm.cpp index 2bb38b6d407..51a62f6dc1d 100644 --- a/src/devices/cpu/psx/psxdasm.cpp +++ b/src/devices/cpu/psx/psxdasm.cpp @@ -10,25 +10,22 @@ #include "gte.h" #include "psxdefs.h" +#include "psxdasm.h" -static char *make_signed_hex_str_16( uint32_t value ) +std::string psxcpu_disassembler::make_signed_hex_str_16( uint32_t value ) { - static char s_hex[ 20 ]; - if( value & 0x8000 ) { - sprintf( s_hex, "-$%x", -value & 0xffff ); + return util::string_format("-$%x", -value & 0xffff ); } else { - sprintf( s_hex, "$%x", value & 0xffff ); + return util::string_format("$%x", value & 0xffff ); } - - return s_hex; } -static const char *const s_cpugenreg[] = +const char *const psxcpu_disassembler::s_cpugenreg[] = { "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", @@ -36,7 +33,7 @@ static const char *const s_cpugenreg[] = "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra" }; -static const char *const s_cp0genreg[] = +const char *const psxcpu_disassembler::s_cp0genreg[] = { "!Index", "!Random", "!EntryLo", "BPC", "!Context", "BDA", "TAR", "DCIC", "BadA", "BDAM", "!EntryHi", "BPCM", "SR", "Cause", "EPC", "PRId", @@ -44,7 +41,7 @@ static const char *const s_cp0genreg[] = "cp0r24", "cp0r25", "cp0r26", "cp0r27", "cp0r28", "cp0r29", "cp0r30", "cp0r31" }; -static const char *const s_cp0ctlreg[] = +const char *const psxcpu_disassembler::s_cp0ctlreg[] = { "cp0cr0", "cp0cr1", "cp0cr2", "cp0cr3", "cp0cr4", "cp0cr5", "cp0cr6", "cp0cr7", "cp0cr8", "cp0cr9", "cp0cr10", "cp0cr11", "cp0cr12", "cp0cr13", "cp0cr14", "cp0cr15", @@ -52,7 +49,7 @@ static const char *const s_cp0ctlreg[] = "cp0cr24", "cp0cr25", "cp0cr26", "cp0cr27", "cp0cr28", "cp0cr29", "cp0cr30", "cp0cr31" }; -static const char *const s_cp1genreg[] = +const char *const psxcpu_disassembler::s_cp1genreg[] = { "cp1r0", "cp1r1", "cp1r2", "cp1r3", "cp1r4", "cp1r5", "cp1r6", "cp1r7", "cp1r8", "cp1r9", "cp1r10", "cp1r11", "cp1r12", "cp1r13", "cp1r14", "cp1r15", @@ -60,7 +57,7 @@ static const char *const s_cp1genreg[] = "cp1r23", "cp1r24", "cp1r25", "cp1r26", "cp1r27", "cp1r28", "cp1r29", "cp1r30" }; -static const char *const s_cp1ctlreg[] = +const char *const psxcpu_disassembler::s_cp1ctlreg[] = { "cp1cr0", "cp1cr1", "cp1cr2", "cp1cr3", "cp1cr4", "cp1cr5", "cp1cr6", "cp1cr7", "cp1cr8", "cp1cr9", "cp1cr10", "cp1cr11", "cp1cr12", "cp1cr13", "cp1cr14", "cp1cr15", @@ -68,7 +65,7 @@ static const char *const s_cp1ctlreg[] = "cp1cr24", "cp1cr25", "cp1cr26", "cp1cr27", "cp1cr28", "cp1cr29", "cp1cr30", "cp1cr31" }; -static const char *const s_cp2genreg[] = +const char *const psxcpu_disassembler::s_cp2genreg[] = { "vxy0", "vz0", "vxy1", "vz1", "vxy2", "vz2", "rgb", "otz", "ir0", "ir1", "ir2", "ir3", "sxy0", "sxy1", "sxy2", "sxyp", @@ -76,7 +73,7 @@ static const char *const s_cp2genreg[] = "mac0", "mac1", "mac2", "mac3", "irgb", "orgb", "lzcs", "lzcr" }; -static const char *const s_cp2ctlreg[] = +const char *const psxcpu_disassembler::s_cp2ctlreg[] = { "r11r12", "r13r21", "r22r23", "r31r32", "r33", "trx", "try", "trz", "l11l12", "l13l21", "l22l23", "l31l32", "l33", "rbk", "gbk", "bbk", @@ -84,7 +81,7 @@ static const char *const s_cp2ctlreg[] = "ofx", "ofy", "h", "dqa", "dqb", "zsf3", "zsf4", "flag" }; -static const char *const s_cp3genreg[] = +const char *const psxcpu_disassembler::s_cp3genreg[] = { "cp3r0", "cp3r1", "cp3r2", "cp3r3", "cp3r4", "cp3r5", "cp3r6", "cp3r7", "cp3r8", "cp3r9", "cp3r10", "cp3r11", "cp3r12", "cp3r13", "cp3r14", "cp3r15", @@ -92,7 +89,7 @@ static const char *const s_cp3genreg[] = "cp3r23", "cp3r24", "cp3r25", "cp3r26", "cp3r27", "cp3r28", "cp3r29", "cp3r30" }; -static const char *const s_cp3ctlreg[] = +const char *const psxcpu_disassembler::s_cp3ctlreg[] = { "cp3cr0", "cp3cr1", "cp3cr2", "cp3cr3", "cp3cr4", "cp3cr5", "cp3cr6", "cp3cr7", "cp3cr8", "cp3cr9", "cp3cr10", "cp3cr11", "cp3cr12", "cp3cr13", "cp3cr14", "cp3cr15", @@ -100,101 +97,96 @@ static const char *const s_cp3ctlreg[] = "cp3cr24", "cp3cr25", "cp3cr26", "cp3cr27", "cp3cr28", "cp3cr29", "cp3cr30", "cp3cr31" }; -static const char *const s_gtesf[] = +const char *const psxcpu_disassembler::s_gtesf[] = { " sf=0", " sf=12" }; -static const char *const s_gtemx[] = +const char *const psxcpu_disassembler::s_gtemx[] = { "rm", "lm", "cm", "0" }; -static const char *const s_gtev[] = +const char *const psxcpu_disassembler::s_gtev[] = { "v0", "v1", "v2", "ir" }; -static const char *const s_gtecv[] = +const char *const psxcpu_disassembler::s_gtecv[] = { "tr", "bk", "fc", "0" }; -static const char *const s_gtelm[] = +const char *const psxcpu_disassembler::s_gtelm[] = { " lm=s16", " lm=u15" }; -static char *effective_address( psxcpu_state *state, uint32_t pc, uint32_t op ) +std::string psxcpu_disassembler::effective_address( uint32_t pc, uint32_t op ) { - static char s_address[ 30 ]; - - if( state != nullptr && state->pc() == pc ) + if( m_config && m_config->pc() == pc ) { - sprintf( s_address, "%s(%s) ; 0x%08x", make_signed_hex_str_16( INS_IMMEDIATE( op ) ), s_cpugenreg[ INS_RS( op ) ], - (uint32_t)( state->r( INS_RS( op ) ) + (int16_t)INS_IMMEDIATE( op ) ) ); - return s_address; + return util::string_format("%s(%s) ; 0x%08x", make_signed_hex_str_16( INS_IMMEDIATE( op ) ), s_cpugenreg[ INS_RS( op ) ], + (uint32_t)( m_config->r( INS_RS( op ) ) + (int16_t)INS_IMMEDIATE( op ) ) ); } - sprintf( s_address, "%s(%s)", make_signed_hex_str_16( INS_IMMEDIATE( op ) ), s_cpugenreg[ INS_RS( op ) ] ); - return s_address; + return util::string_format("%s(%s)", make_signed_hex_str_16( INS_IMMEDIATE( op ) ), s_cpugenreg[ INS_RS( op ) ] ); } -static uint32_t relative_address( psxcpu_state *state, uint32_t pc, uint32_t op ) +uint32_t psxcpu_disassembler::relative_address( uint32_t pc, uint32_t op ) { uint32_t nextpc = pc + 4; - if( state != nullptr && state->pc() == pc && state->delayr() == PSXCPU_DELAYR_PC ) + if( m_config && m_config->pc() == pc && m_config->delayr() == PSXCPU_DELAYR_PC ) { - nextpc = state->delayv(); + nextpc = m_config->delayv(); } return nextpc + ( PSXCPU_WORD_EXTEND( INS_IMMEDIATE( op ) ) << 2 ); } -static uint32_t jump_address( psxcpu_state *state, uint32_t pc, uint32_t op ) +uint32_t psxcpu_disassembler::jump_address( uint32_t pc, uint32_t op ) { uint32_t nextpc = pc + 4; - if( state != nullptr && state->pc() == pc && state->delayr() == PSXCPU_DELAYR_PC ) + if( m_config && m_config->pc() == pc && m_config->delayr() == PSXCPU_DELAYR_PC ) { - nextpc = state->delayv(); + nextpc = m_config->delayv(); } return ( nextpc & 0xf0000000 ) + ( INS_TARGET( op ) << 2 ); } -static uint32_t fetch_op( const uint8_t *opram ) -{ - return ( opram[ 3 ] << 24 ) | ( opram[ 2 ] << 16 ) | ( opram[ 1 ] << 8 ) | ( opram[ 0 ] << 0 ); -} - -static char *upper_address( uint32_t op, const uint8_t *opram ) +std::string psxcpu_disassembler::upper_address( uint32_t op, offs_t pos, const data_buffer &opcodes ) { - static char s_address[ 20 ]; - uint32_t nextop = fetch_op( opram ); + uint32_t nextop = opcodes.r32( pos ); if( INS_OP( nextop ) == OP_ORI && INS_RT( op ) == INS_RS( nextop ) ) { - sprintf( s_address, "$%04x ; 0x%08x", INS_IMMEDIATE( op ), ( INS_IMMEDIATE( op ) << 16 ) | INS_IMMEDIATE( nextop ) ); + return util::string_format("$%04x ; 0x%08x", INS_IMMEDIATE( op ), ( INS_IMMEDIATE( op ) << 16 ) | INS_IMMEDIATE( nextop ) ); } else if( INS_OP( nextop ) == OP_ADDIU && INS_RT( op ) == INS_RS( nextop ) ) { - sprintf( s_address, "$%04x ; 0x%08x", INS_IMMEDIATE( op ), ( INS_IMMEDIATE( op ) << 16 ) + (int16_t) INS_IMMEDIATE( nextop ) ); + return util::string_format("$%04x ; 0x%08x", INS_IMMEDIATE( op ), ( INS_IMMEDIATE( op ) << 16 ) + (int16_t) INS_IMMEDIATE( nextop ) ); } else { - sprintf( s_address, "$%04x", INS_IMMEDIATE( op ) ); + return util::string_format("$%04x", INS_IMMEDIATE( op ) ); } +} + +psxcpu_disassembler::psxcpu_disassembler(config *conf) : m_config(conf) +{ +} - return s_address; +u32 psxcpu_disassembler::opcode_alignment() const +{ + return 4; } -unsigned DasmPSXCPU( psxcpu_state *state, std::ostream &stream, uint32_t pc, const uint8_t *opram ) +offs_t psxcpu_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint32_t op; - const uint8_t *oldopram; uint32_t flags = 0; - - oldopram = opram; - op = fetch_op( opram ); - opram += 4; + offs_t pos = pc; + op = opcodes.r32( pos ); + pos += 4; std::streampos current_pos = stream.tellp(); @@ -233,20 +225,20 @@ unsigned DasmPSXCPU( psxcpu_state *state, std::ostream &stream, uint32_t pc, con util::stream_format( stream, "jr %s", s_cpugenreg[ INS_RS( op ) ] ); if( INS_RS( op ) == 31 ) { - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; } break; case FUNCT_JALR: util::stream_format( stream, "jalr %s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RS( op ) ] ); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA( 1 ); + flags = STEP_OVER | step_over_extra( 1 ); break; case FUNCT_SYSCALL: util::stream_format( stream, "syscall $%05x", INS_CODE( op ) ); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case FUNCT_BREAK: util::stream_format( stream, "break $%05x", INS_CODE( op ) ); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case FUNCT_MFHI: util::stream_format( stream, "mfhi %s", s_cpugenreg[ INS_RD( op ) ] ); @@ -310,45 +302,45 @@ unsigned DasmPSXCPU( psxcpu_state *state, std::ostream &stream, uint32_t pc, con case RT_BLTZ: if( INS_RT( op ) == RT_BLTZAL ) { - util::stream_format( stream, "bltzal %s,$%08x", s_cpugenreg[ INS_RS( op ) ], relative_address( state, pc, op ) ); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA( 1 ); + util::stream_format( stream, "bltzal %s,$%08x", s_cpugenreg[ INS_RS( op ) ], relative_address( pc, op ) ); + flags = STEP_OVER | step_over_extra( 1 ); } else { - util::stream_format( stream, "bltz %s,$%08x", s_cpugenreg[ INS_RS( op ) ], relative_address( state, pc, op ) ); + util::stream_format( stream, "bltz %s,$%08x", s_cpugenreg[ INS_RS( op ) ], relative_address( pc, op ) ); } break; case RT_BGEZ: if( INS_RT( op ) == RT_BGEZAL ) { - util::stream_format( stream, "bgezal %s,$%08x", s_cpugenreg[ INS_RS( op ) ], relative_address( state, pc, op ) ); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA( 1 ); + util::stream_format( stream, "bgezal %s,$%08x", s_cpugenreg[ INS_RS( op ) ], relative_address( pc, op ) ); + flags = STEP_OVER | step_over_extra( 1 ); } else { - util::stream_format( stream, "bgez %s,$%08x", s_cpugenreg[ INS_RS( op ) ], relative_address( state, pc, op ) ); + util::stream_format( stream, "bgez %s,$%08x", s_cpugenreg[ INS_RS( op ) ], relative_address( pc, op ) ); } break; } break; case OP_J: - util::stream_format( stream, "j $%08x", jump_address( state, pc, op ) ); + util::stream_format( stream, "j $%08x", jump_address( pc, op ) ); break; case OP_JAL: - util::stream_format( stream, "jal $%08x", jump_address( state, pc, op ) ); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA( 1 ); + util::stream_format( stream, "jal $%08x", jump_address( pc, op ) ); + flags = STEP_OVER | step_over_extra( 1 ); break; case OP_BEQ: - util::stream_format( stream, "beq %s,%s,$%08x", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ], relative_address( state, pc, op ) ); + util::stream_format( stream, "beq %s,%s,$%08x", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ], relative_address( pc, op ) ); break; case OP_BNE: - util::stream_format( stream, "bne %s,%s,$%08x", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ], relative_address( state, pc, op ) ); + util::stream_format( stream, "bne %s,%s,$%08x", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ], relative_address( pc, op ) ); break; case OP_BLEZ: - util::stream_format( stream, "blez %s,%s,$%08x", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ], relative_address( state, pc, op ) ); + util::stream_format( stream, "blez %s,%s,$%08x", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ], relative_address( pc, op ) ); break; case OP_BGTZ: - util::stream_format( stream, "bgtz %s,%s,$%08x", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ], relative_address( state, pc, op ) ); + util::stream_format( stream, "bgtz %s,%s,$%08x", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ], relative_address( pc, op ) ); break; case OP_ADDI: util::stream_format( stream, "addi %s,%s,%s", s_cpugenreg[ INS_RT( op ) ], s_cpugenreg[ INS_RS( op ) ], make_signed_hex_str_16( INS_IMMEDIATE( op ) ) ); @@ -372,7 +364,7 @@ unsigned DasmPSXCPU( psxcpu_state *state, std::ostream &stream, uint32_t pc, con util::stream_format( stream, "xori %s,%s,$%04x", s_cpugenreg[ INS_RT( op ) ], s_cpugenreg[ INS_RS( op ) ], INS_IMMEDIATE( op ) ); break; case OP_LUI: - util::stream_format( stream, "lui %s,%s", s_cpugenreg[ INS_RT( op ) ], upper_address( op, opram ) ); + util::stream_format( stream, "lui %s,%s", s_cpugenreg[ INS_RT( op ) ], upper_address( op, pos, opcodes ) ); break; case OP_COP0: switch( INS_RS( op ) ) @@ -394,10 +386,10 @@ unsigned DasmPSXCPU( psxcpu_state *state, std::ostream &stream, uint32_t pc, con switch( INS_BC( op ) ) { case BC_BCF: - util::stream_format( stream, "bc0f $%08x", relative_address( state, pc, op ) ); + util::stream_format( stream, "bc0f $%08x", relative_address( pc, op ) ); break; case BC_BCT: - util::stream_format( stream, "bc0t $%08x", relative_address( state, pc, op ) ); + util::stream_format( stream, "bc0t $%08x", relative_address( pc, op ) ); break; } break; @@ -451,10 +443,10 @@ unsigned DasmPSXCPU( psxcpu_state *state, std::ostream &stream, uint32_t pc, con switch( INS_BC( op ) ) { case BC_BCF: - util::stream_format( stream, "bc1f $%08x", relative_address( state, pc, op ) ); + util::stream_format( stream, "bc1f $%08x", relative_address( pc, op ) ); break; case BC_BCT: - util::stream_format( stream, "bc1t $%08x", relative_address( state, pc, op ) ); + util::stream_format( stream, "bc1t $%08x", relative_address( pc, op ) ); break; } break; @@ -488,10 +480,10 @@ unsigned DasmPSXCPU( psxcpu_state *state, std::ostream &stream, uint32_t pc, con switch( INS_BC( op ) ) { case BC_BCF: - util::stream_format( stream, "bc2f $%08x", relative_address( state, pc, op ) ); + util::stream_format( stream, "bc2f $%08x", relative_address( pc, op ) ); break; case BC_BCT: - util::stream_format( stream, "bc2t $%08x", relative_address( state, pc, op ) ); + util::stream_format( stream, "bc2t $%08x", relative_address( pc, op ) ); break; } break; @@ -598,10 +590,10 @@ unsigned DasmPSXCPU( psxcpu_state *state, std::ostream &stream, uint32_t pc, con switch( INS_BC( op ) ) { case BC_BCF: - util::stream_format( stream, "bc3f $%08x", relative_address( state, pc, op ) ); + util::stream_format( stream, "bc3f $%08x", relative_address( pc, op ) ); break; case BC_BCT: - util::stream_format( stream, "bc3t $%08x", relative_address( state, pc, op ) ); + util::stream_format( stream, "bc3t $%08x", relative_address( pc, op ) ); break; } break; @@ -616,64 +608,64 @@ unsigned DasmPSXCPU( psxcpu_state *state, std::ostream &stream, uint32_t pc, con } break; case OP_LB: - util::stream_format( stream, "lb %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "lb %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_LH: - util::stream_format( stream, "lh %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "lh %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_LWL: - util::stream_format( stream, "lwl %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "lwl %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_LW: - util::stream_format( stream, "lw %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "lw %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_LBU: - util::stream_format( stream, "lbu %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "lbu %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_LHU: - util::stream_format( stream, "lhu %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "lhu %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_LWR: - util::stream_format( stream, "lwr %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "lwr %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_SB: - util::stream_format( stream, "sb %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "sb %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_SH: - util::stream_format( stream, "sh %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "sh %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_SWL: - util::stream_format( stream, "swl %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "swl %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_SW: - util::stream_format( stream, "sw %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "sw %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_SWR: - util::stream_format( stream, "swr %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "swr %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_LWC0: - util::stream_format( stream, "lwc0 %s,%s", s_cp0genreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "lwc0 %s,%s", s_cp0genreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_LWC1: - util::stream_format( stream, "lwc1 %s,%s", s_cp1genreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "lwc1 %s,%s", s_cp1genreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_LWC2: - util::stream_format( stream, "lwc2 %s,%s", s_cp2genreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "lwc2 %s,%s", s_cp2genreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_LWC3: - util::stream_format( stream, "lwc3 %s,%s", s_cp2genreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "lwc3 %s,%s", s_cp2genreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_SWC0: - util::stream_format( stream, "swc0 %s,%s", s_cp0genreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "swc0 %s,%s", s_cp0genreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_SWC1: - util::stream_format( stream, "swc1 %s,%s", s_cp1genreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "swc1 %s,%s", s_cp1genreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_SWC2: - util::stream_format( stream, "swc2 %s,%s", s_cp2genreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "swc2 %s,%s", s_cp2genreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_SWC3: - util::stream_format( stream, "swc3 %s,%s", s_cp2genreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "swc3 %s,%s", s_cp2genreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; } @@ -683,11 +675,5 @@ unsigned DasmPSXCPU( psxcpu_state *state, std::ostream &stream, uint32_t pc, con util::stream_format(stream, "dw $%08x", op); } - return ( opram - oldopram ) | flags | DASMFLAG_SUPPORTED; -} - - -CPU_DISASSEMBLE( psxcpu_generic ) -{ - return DasmPSXCPU( nullptr, stream, pc, opram ); + return ( pos - pc ) | flags | SUPPORTED; } diff --git a/src/devices/cpu/psx/psxdasm.h b/src/devices/cpu/psx/psxdasm.h new file mode 100644 index 00000000000..d3a6199616e --- /dev/null +++ b/src/devices/cpu/psx/psxdasm.h @@ -0,0 +1,56 @@ +// license:BSD-3-Clause +// copyright-holders:smf +/* + * PSXCPU disassembler for the MAME project written by smf + * + */ + +#ifndef MAME_CPU_PSX_PSXDASM_H +#define MAME_CPU_PSX_PSXDASM_H + +#pragma once + +class psxcpu_disassembler : public util::disasm_interface +{ +public: + struct config { + virtual ~config() = default; + + virtual uint32_t pc() = 0; + virtual uint32_t delayr() = 0; + virtual uint32_t delayv() = 0; + virtual uint32_t r(int i) = 0; + }; + + psxcpu_disassembler(config *conf = nullptr); + virtual ~psxcpu_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *const s_cpugenreg[]; + static const char *const s_cp0genreg[]; + static const char *const s_cp0ctlreg[]; + static const char *const s_cp1genreg[]; + static const char *const s_cp1ctlreg[]; + static const char *const s_cp2genreg[]; + static const char *const s_cp2ctlreg[]; + static const char *const s_cp3genreg[]; + static const char *const s_cp3ctlreg[]; + static const char *const s_gtesf[]; + static const char *const s_gtemx[]; + static const char *const s_gtev[]; + static const char *const s_gtecv[]; + static const char *const s_gtelm[]; + + std::string make_signed_hex_str_16( uint32_t value ); + std::string effective_address( uint32_t pc, uint32_t op ); + uint32_t relative_address( uint32_t pc, uint32_t op ); + uint32_t jump_address( uint32_t pc, uint32_t op ); + std::string upper_address( uint32_t op, offs_t pos, const data_buffer &opcodes ); + + config *m_config; +}; + +#endif diff --git a/src/devices/cpu/rsp/rsp.cpp b/src/devices/cpu/rsp/rsp.cpp index 6565fa6924d..51e880d53d9 100644 --- a/src/devices/cpu/rsp/rsp.cpp +++ b/src/devices/cpu/rsp/rsp.cpp @@ -17,6 +17,7 @@ #include "rspdefs.h" +#include "rsp_dasm.h" DEFINE_DEVICE_TYPE(RSP, rsp_device, "rsp", "RSP") @@ -150,10 +151,9 @@ device_memory_interface::space_config_vector rsp_device::memory_space_config() c }; } -offs_t rsp_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *rsp_device::create_disassembler() { - extern CPU_DISASSEMBLE( rsp ); - return CPU_DISASSEMBLE_NAME( rsp )(this, stream, pc, oprom, opram, options); + return new rsp_disassembler; } void rsp_device::rsp_add_imem(uint32_t *base) @@ -319,10 +319,10 @@ void rsp_device::unimplemented_opcode(uint32_t op) { if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0) { - util::ovectorstream string; - rsp_dasm_one(string, m_ppc, op); - string.put('\0'); - osd_printf_debug("%08X: %s\n", m_ppc, &string.vec()[0]); + std::ostringstream string; + rsp_disassembler rspd; + rspd.dasm_one(string, m_ppc, op); + osd_printf_debug("%08X: %s\n", m_ppc, string.str().c_str()); } #if SAVE_DISASM @@ -378,7 +378,7 @@ void rsp_device::device_start() m_exec_output = fopen("rsp_execute.txt", "wt"); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); resolve_cb(); if (m_isdrc) @@ -747,13 +747,13 @@ void rsp_device::execute_run() int i, l; static uint32_t prev_regs[32]; - util::ovectorstream string; - rsp_dasm_one(string, m_ppc, op); - string.put('\0'); + rsp_disassembler rspd; + std::ostringstream string; + rspd.dasm_one(string, m_ppc, op); - fprintf(m_exec_output, "%08X: %s", m_ppc, &string.vec()[0]); + fprintf(m_exec_output, "%08X: %s", m_ppc, string.str().c_str()); - l = string.vec().size() - 1; + l = string.str().size(); if (l < 36) { for (i=l; i < 36; i++) diff --git a/src/devices/cpu/rsp/rsp.h b/src/devices/cpu/rsp/rsp.h index cf1a7019f92..5f7b9ccb001 100644 --- a/src/devices/cpu/rsp/rsp.h +++ b/src/devices/cpu/rsp/rsp.h @@ -160,9 +160,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 4; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 4; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; void unimplemented_opcode(uint32_t op); @@ -238,7 +236,7 @@ private: address_space *m_program; protected: - direct_read_data *m_direct; + direct_read_data<0> *m_direct; private: std::unique_ptr<rsp_cop2> m_cop2; @@ -299,7 +297,4 @@ private: DECLARE_DEVICE_TYPE(RSP, rsp_device) -extern offs_t rsp_dasm_one(std::ostream &stream, offs_t pc, uint32_t op); - - #endif // MAME_CPU_RSP_RSP_H diff --git a/src/devices/cpu/rsp/rsp_dasm.cpp b/src/devices/cpu/rsp/rsp_dasm.cpp index 1222c0023a4..dec44596d45 100644 --- a/src/devices/cpu/rsp/rsp_dasm.cpp +++ b/src/devices/cpu/rsp/rsp_dasm.cpp @@ -7,8 +7,9 @@ */ #include "emu.h" +#include "rsp_dasm.h" -/*static const char *const reg[32] = +/*const char *const rsp_disassembler::reg[32] = { "0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", @@ -17,7 +18,7 @@ }; */ -static const char *const reg[32] = +const char *const rsp_disassembler::reg[32] = { "$0", "$at", "$v0", "$v1", "$a0", "$a1", "$a2", "$a3", "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7", @@ -25,7 +26,7 @@ static const char *const reg[32] = "$t8", "$t9", "$k0", "$k1", "$gp", "$sp", "$fp", "$ra" }; -static const char *const vreg[32] = +const char *const rsp_disassembler::vreg[32] = { " v0", " v1", " v2", " v3", " v4", " v5", " v6", " v7", " v8", " v9", "v10", "v11", "v12", "v13", "v14", "v15", @@ -33,7 +34,7 @@ static const char *const vreg[32] = "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31" }; -static const char *const cop0_regs[32] = +const char *const rsp_disassembler::cop0_regs[32] = { "SP_MEM_ADDR", "SP_DRAM_ADDR", "SP_RD_LEN", "SP_WR_LEN", "SP_STATUS", "SP_DMA_FULL", "SP_DMA_BUSY", "SP_SEMAPHORE", @@ -45,36 +46,34 @@ static const char *const cop0_regs[32] = "???", "???", "???", "???" }; -static const char *const element[16] = +const char *const rsp_disassembler::element[16] = { "", "[???]", "[00224466]", "[11335577]", "[00004444]", "[11115555]", "[22226666]", "[33337777]", "[00000000]", "[11111111]", "[22222222]", "[33333333]", "[44444444]", "[55555555]", "[66666666]", "[77777777]" }; -static const char *const element2[16] = +const char *const rsp_disassembler::element2[16] = { "01234567", "????????", "00224466", "11335577", "00004444", "11115555", "22226666", "33337777", "00000000", "11111111", "22222222", "33333333", "44444444", "55555555", "66666666", "77777777" }; -static inline char *signed_imm16(uint32_t op) +inline std::string rsp_disassembler::signed_imm16(uint32_t op) { - static char temp[10]; int16_t value = op & 0xffff; if (value < 0) { - sprintf(temp, "-$%04x", -value); + return util::string_format("-$%04x", -value); } else { - sprintf(temp, "$%04x", value); + return util::string_format("$%04x", value); } - return temp; } -static void disasm_cop0(std::ostream &stream, uint32_t op) +void rsp_disassembler::disasm_cop0(std::ostream &stream, uint32_t op) { int rt = (op >> 16) & 31; int rd = (op >> 11) & 31; @@ -88,7 +87,7 @@ static void disasm_cop0(std::ostream &stream, uint32_t op) } } -static void disasm_cop2(std::ostream &stream, uint32_t op) +void rsp_disassembler::disasm_cop2(std::ostream &stream, uint32_t op) { int rt = (op >> 16) & 31; int rd = (op >> 11) & 31; @@ -175,7 +174,7 @@ static void disasm_cop2(std::ostream &stream, uint32_t op) } } -static void disasm_lwc2(std::ostream &stream, uint32_t op) +void rsp_disassembler::disasm_lwc2(std::ostream &stream, uint32_t op) { int dest = (op >> 16) & 0x1f; int base = (op >> 21) & 0x1f; @@ -202,7 +201,7 @@ static void disasm_lwc2(std::ostream &stream, uint32_t op) } } -static void disasm_swc2(std::ostream &stream, uint32_t op) +void rsp_disassembler::disasm_swc2(std::ostream &stream, uint32_t op) { int dest = (op >> 16) & 0x1f; int base = (op >> 21) & 0x1f; @@ -229,7 +228,12 @@ static void disasm_swc2(std::ostream &stream, uint32_t op) } } -offs_t rsp_dasm_one(std::ostream &stream, offs_t pc, uint32_t op) +u32 rsp_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t rsp_disassembler::dasm_one(std::ostream &stream, offs_t pc, u32 op) { int rs = (op >> 21) & 31; int rt = (op >> 16) & 31; @@ -260,7 +264,7 @@ offs_t rsp_dasm_one(std::ostream &stream, offs_t pc, uint32_t op) case 0x04: util::stream_format(stream, "sllv %s, %s, %s", reg[rd], reg[rt], reg[rs]); break; case 0x06: util::stream_format(stream, "srlv %s, %s, %s", reg[rd], reg[rt], reg[rs]); break; case 0x07: util::stream_format(stream, "srav %s, %s, %s", reg[rd], reg[rt], reg[rs]); break; - case 0x08: util::stream_format(stream, "jr %s", reg[rs]); if (rs == 31) flags = DASMFLAG_STEP_OUT; break; + case 0x08: util::stream_format(stream, "jr %s", reg[rs]); if (rs == 31) flags = STEP_OUT; break; case 0x09: { if (rd == 31) @@ -271,10 +275,10 @@ offs_t rsp_dasm_one(std::ostream &stream, offs_t pc, uint32_t op) { util::stream_format(stream, "jalr %s, %s", reg[rs], reg[rd]); } - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; } - case 0x0d: util::stream_format(stream, "break"); flags = DASMFLAG_STEP_OVER; break; + case 0x0d: util::stream_format(stream, "break"); flags = STEP_OVER; break; case 0x20: util::stream_format(stream, "add %s, %s, %s", reg[rd], reg[rs], reg[rt]); break; case 0x21: util::stream_format(stream, "addu %s, %s, %s", reg[rd], reg[rs], reg[rt]); break; case 0x22: util::stream_format(stream, "sub %s, %s, %s", reg[rd], reg[rs], reg[rt]); break; @@ -338,14 +342,11 @@ offs_t rsp_dasm_one(std::ostream &stream, offs_t pc, uint32_t op) default: util::stream_format(stream, "???"); break; } - return 4 | flags | DASMFLAG_SUPPORTED; + return 4 | flags | SUPPORTED; } -/*****************************************************************************/ - -CPU_DISASSEMBLE( rsp ) +offs_t rsp_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - uint32_t op = *(uint32_t *)opram; - op = big_endianize_int32(op); - return rsp_dasm_one(stream, pc, op); + u32 op = opcodes.r32(pc); + return dasm_one(stream, pc, op); } diff --git a/src/devices/cpu/rsp/rsp_dasm.h b/src/devices/cpu/rsp/rsp_dasm.h new file mode 100644 index 00000000000..72dcdaae5e6 --- /dev/null +++ b/src/devices/cpu/rsp/rsp_dasm.h @@ -0,0 +1,38 @@ +// license:BSD-3-Clause +// copyright-holders:Ville Linde, Ryan Holtz +/* + Nintendo/SGI RSP Disassembler + + Written by Ville Linde +*/ + +#ifndef MAME_CPU_RSP_RSP_DASM_H +#define MAME_CPU_RSP_RSP_DASM_H + +#pragma once + +class rsp_disassembler : public util::disasm_interface +{ +public: + rsp_disassembler() = default; + virtual ~rsp_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + + offs_t dasm_one(std::ostream &stream, offs_t pc, u32 op); + +private: + static const char *const reg[32]; + static const char *const vreg[32]; + static const char *const cop0_regs[32]; + static const char *const element[16]; + static const char *const element2[16]; + inline std::string signed_imm16(uint32_t op); + void disasm_cop0(std::ostream &stream, uint32_t op); + void disasm_cop2(std::ostream &stream, uint32_t op); + void disasm_lwc2(std::ostream &stream, uint32_t op); + void disasm_swc2(std::ostream &stream, uint32_t op); +}; + +#endif diff --git a/src/devices/cpu/rsp/rspcp2d.cpp b/src/devices/cpu/rsp/rspcp2d.cpp index 7152d6cbe59..47972b54747 100644 --- a/src/devices/cpu/rsp/rspcp2d.cpp +++ b/src/devices/cpu/rsp/rspcp2d.cpp @@ -13,6 +13,7 @@ #include "rspcp2d.h" #include "rsp.h" +#include "rsp_dasm.h" #include "rspcp2.h" #include "cpu/drcfe.h" @@ -138,8 +139,9 @@ void rsp_cop2_drc::cfunc_unimplemented_opcode() const uint32_t ppc = m_rsp.m_ppc; if ((m_machine.debug_flags & DEBUG_FLAG_ENABLED) != 0) { + rsp_disassembler rspd; std::ostringstream stream; - rsp_dasm_one(stream, ppc, m_rspcop2_state->op); + rspd.dasm_one(stream, ppc, m_rspcop2_state->op); const std::string stream_string = stream.str(); osd_printf_debug("%08X: %s\n", ppc, stream_string.c_str()); } diff --git a/src/devices/cpu/rsp/rspdrc.cpp b/src/devices/cpu/rsp/rspdrc.cpp index cdc10338571..3c7a1f2efab 100644 --- a/src/devices/cpu/rsp/rspdrc.cpp +++ b/src/devices/cpu/rsp/rspdrc.cpp @@ -20,6 +20,7 @@ #include "emu.h" #include "rsp.h" +#include "rsp_dasm.h" #include "rspfe.h" #include "rspcp2.h" @@ -34,8 +35,6 @@ using namespace uml; -CPU_DISASSEMBLE( rsp ); - /*************************************************************************** CONSTANTS ***************************************************************************/ @@ -1288,9 +1287,9 @@ void rsp_device::log_add_disasm_comment(drcuml_block *block, uint32_t pc, uint32 { if (m_drcuml->logging()) { - util::ovectorstream buffer; - rsp_dasm_one(buffer, pc, op); - buffer.put('\0'); - block->append_comment("%08X: %s", pc, &buffer.vec()[0]); // comment + rsp_disassembler rspd; + std::ostringstream buffer; + rspd.dasm_one(buffer, pc, op); + block->append_comment("%08X: %s", pc, buffer.str()); // comment } } diff --git a/src/devices/cpu/s2650/2650dasm.cpp b/src/devices/cpu/s2650/2650dasm.cpp index 872de095a3b..38f325e02c1 100644 --- a/src/devices/cpu/s2650/2650dasm.cpp +++ b/src/devices/cpu/s2650/2650dasm.cpp @@ -10,859 +10,543 @@ **************************************************************************/ #include "emu.h" - -static const uint8_t *rambase; -static offs_t pcbase; - -#define readarg(A) (rambase[(A) - pcbase]) - -/* Set this to 1 to disassemble using Z80 style mnemonics */ -#define HJB 0 - -/* Set this to 1 to give names to condition codes and flag bits */ -#define MNEMO 1 +#include "2650dasm.h" /* handy table to build relative offsets from HR (holding register) */ -static const int rel[0x100] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, +const int s2650_disassembler::rel[0x100] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, -64,-63,-62,-61,-60,-59,-58,-57,-56,-55,-54,-53,-52,-51,-50,-49, -48,-47,-46,-45,-44,-43,-42,-41,-40,-39,-38,-37,-36,-35,-34,-33, -32,-31,-30,-29,-28,-27,-26,-25,-24,-23,-22,-21,-20,-19,-18,-17, -16,-15,-14,-13,-12,-11,-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, -64,-63,-62,-61,-60,-59,-58,-57,-56,-55,-54,-53,-52,-51,-50,-49, -48,-47,-46,-45,-44,-43,-42,-41,-40,-39,-38,-37,-36,-35,-34,-33, -32,-31,-30,-29,-28,-27,-26,-25,-24,-23,-22,-21,-20,-19,-18,-17, -16,-15,-14,-13,-12,-11,-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, }; -typedef char* (*callback) (int addr); -static callback find_symbol = nullptr; - -static char *SYM(int addr) +std::string s2650_disassembler::SYM(int addr) { - static char buff[8+1]; - char * s = nullptr; - - if (find_symbol) s = (*find_symbol)(addr); - if (s) return s; - - sprintf(buff, "$%04x", addr); - return buff; + return util::string_format("$%04x", addr); } /* format an immediate */ -static char *IMM(int pc) +std::string s2650_disassembler::IMM(offs_t pc, const data_buffer ¶ms) { - static char buff[32]; - - sprintf(buff, "$%02x", readarg(pc)); - return buff; + return util::string_format("$%02x", params.r8(pc)); } -#if MNEMO -static const char cc[4] = { 'z', 'p', 'm', 'a' }; +const char s2650_disassembler::cc[4] = { 'z', 'p', 'm', 'a' }; + +void s2650_disassembler::add(std::string &buf, std::string str) +{ + if(!buf.empty()) + buf += '+'; + buf += str; +} /* format an immediate for PSL */ -static char *IMM_PSL(int pc) +std::string s2650_disassembler::IMM_PSL(offs_t pc, const data_buffer ¶ms) { - static char buff[32]; - char *p = buff; - int v = readarg(pc); + u8 v = params.r8(pc); if (v == 0xff) { - p += sprintf(p, "all"); + return "all"; + } else { + std::string buff; switch (v & 0xc0) { - case 0x40: p += sprintf(p, "p+"); break; - case 0x80: p += sprintf(p, "m+"); break; - case 0xc0: p += sprintf(p, "cc+"); break; + case 0x40: add(buff, "p"); break; + case 0x80: add(buff, "m"); break; + case 0xc0: add(buff, "cc"); break; } if (v & 0x20) /* inter digit carry */ - p += sprintf(p, "idc+"); + add(buff, "idc"); if (v & 0x10) /* register select */ - p += sprintf(p, "rs+"); + add(buff, "rs"); if (v & 0x08) /* with carry */ - p += sprintf(p, "wc+"); + add(buff, "wc"); if (v & 0x04) /* overflow */ - p += sprintf(p, "ovf+"); + add(buff, "ovf"); if (v & 0x02) /* 2's complement comparisons */ - p += sprintf(p, "com+"); + add(buff, "com"); if (v & 0x01) /* carry */ - p += sprintf(p, "c+"); - if (p > buff) - *--p = '\0'; + add(buff, "c"); + return buff; } - return buff; } /* format an immediate for PSU (processor status upper) */ -static char *IMM_PSU(int pc) +std::string s2650_disassembler::IMM_PSU(offs_t pc, const data_buffer ¶ms) { - static char buff[32]; - char *p = buff; - int v = readarg(pc); + int v = params.r8(pc); if (v == 0xff) { - p += sprintf(p, "all"); + return "all"; } else { + std::string buff; if (v & 0x80) /* sense input */ - p += sprintf(p, "si+"); + add(buff, "si"); if (v & 0x40) /* flag output */ - p += sprintf(p, "fo+"); + add(buff, "fo"); if (v & 0x20) /* interrupt inhibit */ - p += sprintf(p, "ii+"); + add(buff, "ii"); if (v & 0x10) /* unused bit 4 */ - p += sprintf(p, "4+"); + add(buff, "4"); if (v & 0x08) /* unused bit 3 */ - p += sprintf(p, "3+"); + add(buff, "3"); if (v & 0x04) /* stack pointer bit 2 */ - p += sprintf(p, "sp2+"); + add(buff, "sp2"); if (v & 0x02) /* stack pointer bit 1 */ - p += sprintf(p, "sp1+"); + add(buff, "sp1"); if (v & 0x01) /* stack pointer bit 0 */ - p += sprintf(p, "sp0+"); - if (p > buff) - *--p = '\0'; + add(buff, "sp0"); + return buff; } - return buff; } -#else -static const char cc[4] = { '0', '1', '2', '3' }; -#define IMM_PSL IMM -#define IMM_PSU IMM -#endif /* format an relative address */ -static char *REL(int pc) +std::string s2650_disassembler::REL(offs_t pc, const data_buffer ¶ms) { -static char buff[32]; -int o = readarg(pc); - sprintf(buff, "%s%s", (o&0x80)?"*":"", SYM((pc&0x6000)+((pc+1+rel[o])&0x1fff))); - return buff; + int o = params.r8(pc); + return util::string_format("%s%s", (o&0x80)?"*":"", SYM((pc&0x6000)+((pc+1+rel[o])&0x1fff))); } /* format an relative address (implicit page 0) */ -static char *REL0(int pc) +std::string s2650_disassembler::REL0(offs_t pc, const data_buffer ¶ms) { -static char buff[32]; -int o = readarg(pc); - sprintf(buff, "%s%s", (o&0x80)?"*":"", SYM((rel[o]) & 0x1fff)); - return buff; + int o = params.r8(pc); + return util::string_format("%s%s", (o&0x80)?"*":"", SYM((rel[o]) & 0x1fff)); } /* format a destination register and an absolute address */ -static char *ABS(int load, int r, int pc) +std::string s2650_disassembler::ABS(int load, int r, offs_t pc, const data_buffer ¶ms) { - static char buff[32]; - int h = readarg(pc); - int l = readarg((pc&0x6000)+((pc+1)&0x1fff)); + int h = params.r8(pc); + int l = params.r8((pc&0x6000)+((pc+1)&0x1fff)); int a = (pc & 0x6000) + ((h & 0x1f) << 8) + l; -#if HJB - if (load) { - switch (h >> 5) { - case 0: sprintf(buff, "r%d,(%s)", r, SYM(a)); break; - case 1: sprintf(buff, "r0,(%s,r%d++)", SYM(a), r); break; - case 2: sprintf(buff, "r0,(%s,r%d--)", SYM(a), r); break; - case 3: sprintf(buff, "r0,(%s,r%d)", SYM(a), r); break; - case 4: sprintf(buff, "r%d,*(%s)", r, SYM(a)); break; - case 5: sprintf(buff, "r0,*(%s,r%d++)", SYM(a), r); break; - case 6: sprintf(buff, "r0,*(%s,r%d--)", SYM(a), r); break; - case 7: sprintf(buff, "r0,*(%s,r%d)", SYM(a), r); break; + if (m_config->get_z80_mnemonics_mode()) { + if (load) { + switch (h >> 5) { + case 0: return util::string_format("r%d,(%s)", r, SYM(a)); + case 1: return util::string_format("r0,(%s,r%d++)", SYM(a), r); + case 2: return util::string_format("r0,(%s,r%d--)", SYM(a), r); + case 3: return util::string_format("r0,(%s,r%d)", SYM(a), r); + case 4: return util::string_format("r%d,*(%s)", r, SYM(a)); + case 5: return util::string_format("r0,*(%s,r%d++)", SYM(a), r); + case 6: return util::string_format("r0,*(%s,r%d--)", SYM(a), r); + case 7: return util::string_format("r0,*(%s,r%d)", SYM(a), r); + } + } else { + switch (h >> 5) { + case 0: return util::string_format("(%s),r%d", SYM(a), r); + case 1: return util::string_format("(%s,r%d++),r0", SYM(a), r); + case 2: return util::string_format("(%s,r%d--),r0", SYM(a), r); + case 3: return util::string_format("(%s,r%d),r0", SYM(a), r); + case 4: return util::string_format("*(%s),r%d", SYM(a), r); + case 5: return util::string_format("*(%s,r%d++),r0", SYM(a), r); + case 6: return util::string_format("*(%s,r%d--),r0", SYM(a), r); + case 7: return util::string_format("*(%s,r%d),r0", SYM(a), r); + } } } else { switch (h >> 5) { - case 0: sprintf(buff, "(%s),r%d", SYM(a), r); break; - case 1: sprintf(buff, "(%s,r%d++),r0", SYM(a), r); break; - case 2: sprintf(buff, "(%s,r%d--),r0", SYM(a), r); break; - case 3: sprintf(buff, "(%s,r%d),r0", SYM(a), r); break; - case 4: sprintf(buff, "*(%s),r%d", SYM(a), r); break; - case 5: sprintf(buff, "*(%s,r%d++),r0", SYM(a), r); break; - case 6: sprintf(buff, "*(%s,r%d--),r0", SYM(a), r); break; - case 7: sprintf(buff, "*(%s,r%d),r0", SYM(a), r); break; + case 0: return util::string_format("%d %s", r, SYM(a)); + case 1: return util::string_format("0 %s,r%d+", SYM(a), r); + case 2: return util::string_format("0 %s,r%d-", SYM(a), r); + case 3: return util::string_format("0 %s,r%d", SYM(a), r); + case 4: return util::string_format("%d *%s", r, SYM(a)); + case 5: return util::string_format("0 *%s,r%d+", SYM(a), r); + case 6: return util::string_format("0 *%s,r%d-", SYM(a), r); + case 7: return util::string_format("0 *%s,r%d", SYM(a), r); } } -#else - switch (h >> 5) { - case 0: sprintf(buff, "%d %s", r, SYM(a)); break; - case 1: sprintf(buff, "0 %s,r%d+", SYM(a), r); break; - case 2: sprintf(buff, "0 %s,r%d-", SYM(a), r); break; - case 3: sprintf(buff, "0 %s,r%d", SYM(a), r); break; - case 4: sprintf(buff, "%d *%s", r, SYM(a)); break; - case 5: sprintf(buff, "0 *%s,r%d+", SYM(a), r); break; - case 6: sprintf(buff, "0 *%s,r%d-", SYM(a), r); break; - case 7: sprintf(buff, "0 *%s,r%d", SYM(a), r); break; - } -#endif - return buff; + return ""; } /* format an (branch) absolute address */ -static char *ADR(int pc) +std::string s2650_disassembler::ADR(offs_t pc, const data_buffer ¶ms) { - static char buff[32]; - int h = readarg(pc); - int l = readarg((pc&0x6000)+((pc+1)&0x1fff)); + int h = params.r8(pc); + int l = params.r8((pc&0x6000)+((pc+1)&0x1fff)); int a = ((h & 0x7f) << 8) + l; if (h & 0x80) - sprintf(buff, "*%s", SYM(a)); + return util::string_format("*%s", SYM(a)); else - sprintf(buff, "%s", SYM(a)); - return buff; + return util::string_format("%s", SYM(a)); +} + +s2650_disassembler::s2650_disassembler(config *conf) : m_config(conf) +{ } /* disassemble one instruction at PC into buff. return byte size of instr */ -CPU_DISASSEMBLE(s2650) +offs_t s2650_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint32_t flags = 0; int PC = pc; - int op = oprom[0]; + int op = opcodes.r8(pc); int rv = op & 3; - rambase = opram; - pcbase = PC; + bool z80 = m_config->get_z80_mnemonics_mode(); pc += 1; switch (op) { case 0x00: case 0x01: case 0x02: case 0x03: -#if HJB - util::stream_format(stream, "ld r0,r%d", rv); -#else - util::stream_format(stream, "lodz,%d", rv); -#endif + util::stream_format(stream, z80 ? "ld r0,r%d" : "lodz,%d", rv); break; case 0x04: case 0x05: case 0x06: case 0x07: -#if HJB - util::stream_format(stream, "ld r%d,%s", rv, IMM(pc)); -#else - util::stream_format(stream, "lodi,%d %s", rv, IMM(pc)); -#endif + util::stream_format(stream, z80 ? "ld r%d,%s" : "lodi,%d %s", rv, IMM(pc, params)); pc+=1; break; case 0x08: case 0x09: case 0x0a: case 0x0b: -#if HJB - util::stream_format(stream, "ld r%d,(%s)", rv, REL(pc)); -#else - util::stream_format(stream, "lodr,%d %s", rv, REL(pc)); -#endif + util::stream_format(stream, z80 ? "ld r%d,(%s)" : "lodr,%d %s", rv, REL(pc, params)); pc+=1; break; case 0x0c: case 0x0d: case 0x0e: case 0x0f: -#if HJB - util::stream_format(stream, "ld %s", ABS(1,rv,pc)); -#else - util::stream_format(stream, "loda,%s", ABS(1,rv,pc)); -#endif + util::stream_format(stream, z80 ? "ld %s" : "loda,%s", ABS(1,rv,pc, params)); pc+=2; break; case 0x10: case 0x11: -#if HJB - util::stream_format(stream, "**** $%02X",op); -#else - util::stream_format(stream, "**** $%02X",op); -#endif + util::stream_format(stream, z80 ? "**** $%02X" : "**** $%02X",op); break; case 0x12: -#if HJB - util::stream_format(stream, "ld r0,psu"); -#else - util::stream_format(stream, "spsu"); -#endif + util::stream_format(stream, z80 ? "ld r0,psu" : "spsu"); break; case 0x13: -#if HJB - util::stream_format(stream, "ld r0,psl"); -#else - util::stream_format(stream, "spsl"); -#endif + util::stream_format(stream, z80 ? "ld r0,psl" : "spsl"); break; case 0x14: case 0x15: case 0x16: case 0x17: -#if HJB - if (rv == 3) - util::stream_format(stream, "ret"); - else - util::stream_format(stream, "ret %c", cc[rv]); -#else - util::stream_format(stream, "retc %c", cc[rv]); -#endif - flags = DASMFLAG_STEP_OUT; + if (z80) { + if (rv == 3) + util::stream_format(stream, "ret"); + else + util::stream_format(stream, "ret %c", cc[rv]); + } else + util::stream_format(stream, "retc %c", cc[rv]); + flags = STEP_OUT; break; case 0x18: case 0x19: case 0x1a: case 0x1b: -#if HJB - if (rv == 3) - util::stream_format(stream, "jr %s", REL(pc)); - else - util::stream_format(stream, "jr %c,%s", cc[rv], REL(pc)); -#else - util::stream_format(stream, "bctr,%c %s", cc[rv], REL(pc)); -#endif + if (z80) { + if (rv == 3) + util::stream_format(stream, "jr %s", REL(pc, params)); + else + util::stream_format(stream, "jr %c,%s", cc[rv], REL(pc, params)); + } else + util::stream_format(stream, "bctr,%c %s", cc[rv], REL(pc, params)); pc+=1; break; case 0x1c: case 0x1d: case 0x1e: case 0x1f: -#if HJB - if (rv == 3) - util::stream_format(stream, "jp %s", ADR(pc)); - else - util::stream_format(stream, "jp %c,%s", cc[rv], ADR(pc)); -#else - util::stream_format(stream, "bcta,%c %s", cc[rv], ADR(pc)); -#endif + if (z80) { + if (rv == 3) + util::stream_format(stream, "jp %s", ADR(pc, params)); + else + util::stream_format(stream, "jp %c,%s", cc[rv], ADR(pc, params)); + } else + util::stream_format(stream, "bcta,%c %s", cc[rv], ADR(pc, params)); pc+=2; break; case 0x20: case 0x21: case 0x22: case 0x23: -#if HJB - util::stream_format(stream, "xor r0,r%d", rv); -#else - util::stream_format(stream, "eorz,%d", rv); -#endif + util::stream_format(stream, z80 ? "xor r0,r%d" : "eorz,%d", rv); break; case 0x24: case 0x25: case 0x26: case 0x27: -#if HJB - util::stream_format(stream, "xor r%d,%s", rv, IMM(pc)); -#else - util::stream_format(stream, "eori,%d %s", rv, IMM(pc)); -#endif + util::stream_format(stream, z80 ? "xor r%d,%s" : "eori,%d %s", rv, IMM(pc, params)); pc+=1; break; case 0x28: case 0x29: case 0x2a: case 0x2b: -#if HJB - util::stream_format(stream, "xor r%d,(%s)", rv, REL(pc)); -#else - util::stream_format(stream, "eorr,%d %s", rv, REL(pc)); -#endif + util::stream_format(stream, z80 ? "xor r%d,(%s)" : "eorr,%d %s", rv, REL(pc, params)); pc+=1; break; case 0x2c: case 0x2d: case 0x2e: case 0x2f: -#if HJB - util::stream_format(stream, "xor %s", ABS(1,rv,pc)); -#else - util::stream_format(stream, "eora,%s", ABS(1,rv,pc)); -#endif + util::stream_format(stream, z80 ? "xor %s" : "eora,%s", ABS(1,rv,pc, params)); pc+=2; break; case 0x30: case 0x31: case 0x32: case 0x33: -#if HJB - util::stream_format(stream, "in r%d,(ctrl)", rv); -#else - util::stream_format(stream, "redc,%d", rv); -#endif + util::stream_format(stream, z80 ? "in r%d,(ctrl)" : "redc,%d", rv); break; case 0x34: case 0x35: case 0x36: case 0x37: -#if HJB - if (rv == 3) - util::stream_format(stream, "iret"); - else - util::stream_format(stream, "iret %c", cc[rv]); -#else - util::stream_format(stream, "rete %c", cc[rv]); -#endif - flags = DASMFLAG_STEP_OUT; + if (z80) { + if (rv == 3) + util::stream_format(stream, "iret"); + else + util::stream_format(stream, "iret %c", cc[rv]); + } else + util::stream_format(stream, "rete %c", cc[rv]); + flags = STEP_OUT; break; case 0x38: case 0x39: case 0x3a: case 0x3b: -#if HJB - if (rv == 3) - util::stream_format(stream, "calr %s", REL(pc)); - else - util::stream_format(stream, "calr %c,%s", cc[rv], REL(pc)); -#else - util::stream_format(stream, "bstr,%c %s", cc[rv], REL(pc)); -#endif + if (z80) { + if (rv == 3) + util::stream_format(stream, "calr %s", REL(pc, params)); + else + util::stream_format(stream, "calr %c,%s", cc[rv], REL(pc, params)); + } else + util::stream_format(stream, "bstr,%c %s", cc[rv], REL(pc, params)); pc+=1; - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case 0x3c: case 0x3d: case 0x3e: case 0x3f: -#if HJB - if (rv == 3) - util::stream_format(stream, "call %s", ADR(pc)); - else - util::stream_format(stream, "call %c,%s", cc[rv], ADR(pc)); -#else - util::stream_format(stream, "bsta,%c %s", cc[rv], ADR(pc)); -#endif + if (z80) { + if (rv == 3) + util::stream_format(stream, "call %s", ADR(pc, params)); + else + util::stream_format(stream, "call %c,%s", cc[rv], ADR(pc, params)); + } else + util::stream_format(stream, "bsta,%c %s", cc[rv], ADR(pc, params)); pc+=2; - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case 0x40: util::stream_format(stream, "halt"); break; case 0x41: case 0x42: case 0x43: -#if HJB - util::stream_format(stream, "and r0,r%d", rv); -#else - util::stream_format(stream, "andz,%d", rv); -#endif + util::stream_format(stream, z80 ? "and r0,r%d" : "andz,%d", rv); break; case 0x44: case 0x45: case 0x46: case 0x47: -#if HJB - util::stream_format(stream, "and r%d,%s", rv, IMM(pc)); -#else - util::stream_format(stream, "andi,%d %s", rv, IMM(pc)); -#endif + util::stream_format(stream, z80 ? "and r%d,%s" : "andi,%d %s", rv, IMM(pc, params)); pc+=1; break; case 0x48: case 0x49: case 0x4a: case 0x4b: -#if HJB - util::stream_format(stream, "and r%d,(%s)", rv, REL(pc)); -#else - util::stream_format(stream, "andr,%d %s", rv, REL(pc)); -#endif + util::stream_format(stream, z80 ? "and r%d,(%s)" : "andr,%d %s", rv, REL(pc, params)); pc+=1; break; case 0x4c: case 0x4d: case 0x4e: case 0x4f: -#if HJB - util::stream_format(stream, "and %s", ABS(1,rv,pc)); -#else - util::stream_format(stream, "anda,%s", ABS(1,rv,pc)); -#endif + util::stream_format(stream, z80 ? "and %s" : "anda,%s", ABS(1,rv,pc, params)); pc+=2; break; case 0x50: case 0x51: case 0x52: case 0x53: -#if HJB - util::stream_format(stream, "ror r%d", rv); -#else - util::stream_format(stream, "rrr,%d", rv); -#endif + util::stream_format(stream, z80 ? "ror r%d" : "rrr,%d", rv); break; case 0x54: case 0x55: case 0x56: case 0x57: -#if HJB - util::stream_format(stream, "in r%d,(%s)", rv, IMM(pc)); -#else - util::stream_format(stream, "rede,%d %s", rv, IMM(pc)); -#endif + util::stream_format(stream, z80 ? "in r%d,(%s)" : "rede,%d %s", rv, IMM(pc, params)); pc+=1; break; case 0x58: case 0x59: case 0x5a: case 0x5b: -#if HJB - util::stream_format(stream, "jrnz r%d,%s", rv, REL(pc)); -#else - util::stream_format(stream, "brnr,%d %s", rv, REL(pc)); -#endif + util::stream_format(stream, z80 ? "jrnz r%d,%s" : "brnr,%d %s", rv, REL(pc, params)); pc+=1; break; case 0x5c: case 0x5d: case 0x5e: case 0x5f: -#if HJB - util::stream_format(stream, "jpnz r%d,%s", rv, ADR(pc)); -#else - util::stream_format(stream, "brna,%d %s", rv, ADR(pc)); -#endif + util::stream_format(stream, z80 ? "jpnz r%d,%s" : "brna,%d %s", rv, ADR(pc, params)); pc+=2; break; case 0x60: case 0x61: case 0x62: case 0x63: -#if HJB - util::stream_format(stream, "or r0,r%d", rv); -#else - util::stream_format(stream, "iorz,%d", rv); -#endif + util::stream_format(stream, z80 ? "or r0,r%d" : "iorz,%d", rv); break; case 0x64: case 0x65: case 0x66: case 0x67: -#if HJB - util::stream_format(stream, "or r%d,%s", rv, IMM(pc)); -#else - util::stream_format(stream, "iori,%d %s", rv, IMM(pc)); -#endif + util::stream_format(stream, z80 ? "or r%d,%s" : "iori,%d %s", rv, IMM(pc, params)); pc+=1; break; case 0x68: case 0x69: case 0x6a: case 0x6b: -#if HJB - util::stream_format(stream, "or r%d,(%s)", rv, REL(pc)); -#else - util::stream_format(stream, "iorr,%d %s", rv, REL(pc)); -#endif + util::stream_format(stream, z80 ? "or r%d,(%s)" : "iorr,%d %s", rv, REL(pc, params)); pc+=1; break; case 0x6c: case 0x6d: case 0x6e: case 0x6f: -#if HJB - util::stream_format(stream, "or %s", ABS(1,rv,pc)); -#else - util::stream_format(stream, "iora,%s", ABS(1,rv,pc)); -#endif + util::stream_format(stream, z80 ? "or %s" : "iora,%s", ABS(1,rv,pc, params)); pc+=2; break; case 0x70: case 0x71: case 0x72: case 0x73: -#if HJB - util::stream_format(stream, "in r%d,(data)", rv); -#else - util::stream_format(stream, "redd,%d", rv); -#endif + util::stream_format(stream, z80 ? "in r%d,(data)" : "redd,%d", rv); break; case 0x74: -#if HJB - util::stream_format(stream, "res psu,%s", IMM_PSU(pc)); -#else - util::stream_format(stream, "cpsu %s", IMM_PSU(pc)); -#endif + util::stream_format(stream, z80 ? "res psu,%s" : "cpsu %s", IMM_PSU(pc, params)); pc+=1; break; case 0x75: -#if HJB - util::stream_format(stream, "res psl,%s", IMM_PSL(pc)); -#else - util::stream_format(stream, "cpsl %s", IMM_PSL(pc)); -#endif + util::stream_format(stream, z80 ? "res psl,%s" : "cpsl %s", IMM_PSL(pc, params)); pc+=1; break; case 0x76: -#if HJB - util::stream_format(stream, "set psu,%s", IMM_PSU(pc)); -#else - util::stream_format(stream, "ppsu %s", IMM_PSU(pc)); -#endif + util::stream_format(stream, z80 ? "set psu,%s" : "ppsu %s", IMM_PSU(pc, params)); pc+=1; break; case 0x77: -#if HJB - util::stream_format(stream, "set psl,%s", IMM_PSL(pc)); -#else - util::stream_format(stream, "ppsl %s", IMM_PSL(pc)); -#endif + util::stream_format(stream, z80 ? "set psl,%s" : "ppsl %s", IMM_PSL(pc, params)); pc+=1; break; case 0x78: case 0x79: case 0x7a: case 0x7b: -#if HJB - util::stream_format(stream, "call r%d-nz,%s", rv, REL(pc)); -#else - util::stream_format(stream, "bsnr,%d %s", rv, REL(pc)); -#endif + util::stream_format(stream, z80 ? "call r%d-nz,%s" : "bsnr,%d %s", rv, REL(pc, params)); pc+=1; - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case 0x7c: case 0x7d: case 0x7e: case 0x7f: -#if HJB - util::stream_format(stream, "call r%d-nz,%s", rv, ADR(pc)); -#else - util::stream_format(stream, "bsna,%d %s", rv, ADR(pc)); -#endif + util::stream_format(stream, z80 ? "call r%d-nz,%s" : "bsna,%d %s", rv, ADR(pc, params)); pc+=2; - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case 0x80: case 0x81: case 0x82: case 0x83: -#if HJB - util::stream_format(stream, "add r0,r%d", rv); -#else - util::stream_format(stream, "addz,%d", rv); -#endif + util::stream_format(stream, z80 ? "add r0,r%d" : "addz,%d", rv); break; case 0x84: case 0x85: case 0x86: case 0x87: -#if HJB - util::stream_format(stream, "add r%d,%s", rv, IMM(pc)); -#else - util::stream_format(stream, "addi,%d %s", rv, IMM(pc)); -#endif + util::stream_format(stream, z80 ? "add r%d,%s" : "addi,%d %s", rv, IMM(pc, params)); pc+=1; break; case 0x88: case 0x89: case 0x8a: case 0x8b: -#if HJB - util::stream_format(stream, "add r%d,(%s)", rv, REL(pc)); -#else - util::stream_format(stream, "addr,%d %s", rv, REL(pc)); -#endif + util::stream_format(stream, z80 ? "add r%d,(%s)" : "addr,%d %s", rv, REL(pc, params)); pc+=1; break; case 0x8c: case 0x8d: case 0x8e: case 0x8f: -#if HJB - util::stream_format(stream, "add %s", ABS(1,rv,pc)); -#else - util::stream_format(stream, "adda,%s", ABS(1,rv,pc)); -#endif + util::stream_format(stream, z80 ? "add %s" : "adda,%s", ABS(1,rv,pc, params)); pc+=2; break; case 0x90: case 0x91: -#if HJB - util::stream_format(stream, "**** $%02X",op); -#else - util::stream_format(stream, "**** $%02X",op); -#endif + util::stream_format(stream, z80 ? "**** $%02X" : "**** $%02X",op); break; case 0x92: -#if HJB - util::stream_format(stream, "ld psu,r0"); -#else - util::stream_format(stream, "lpsu"); -#endif + util::stream_format(stream, z80 ? "ld psu,r0" : "lpsu"); break; case 0x93: -#if HJB - util::stream_format(stream, "ld psl,r0"); -#else - util::stream_format(stream, "lpsl"); -#endif + util::stream_format(stream, z80 ? "ld psl,r0" : "lpsl"); break; case 0x94: case 0x95: case 0x96: case 0x97: -#if HJB - util::stream_format(stream, "daa r%d", rv); -#else - util::stream_format(stream, "dar,%d", rv); -#endif + util::stream_format(stream, z80 ? "daa r%d" : "dar,%d", rv); break; case 0x98: case 0x99: case 0x9a: -#if HJB - util::stream_format(stream, "jr n%c,%s", cc[rv], REL(pc)); -#else - util::stream_format(stream, "bcfr,%c %s", cc[rv], REL(pc)); -#endif + util::stream_format(stream, z80 ? "jr n%c,%s" : "bcfr,%c %s", cc[rv], REL(pc, params)); pc+=1; break; case 0x9b: -#if HJB - util::stream_format(stream, "jr0 %s", REL0(pc)); -#else - util::stream_format(stream, "zbrr %s", REL0(pc)); -#endif + util::stream_format(stream, z80 ? "jr0 %s" : "zbrr %s", REL0(pc, params)); pc+=1; break; case 0x9c: case 0x9d: case 0x9e: -#if HJB - util::stream_format(stream, "jp n%c,%s", cc[rv], ADR(pc)); -#else - util::stream_format(stream, "bcfa,%c %s", cc[rv], ADR(pc)); -#endif + util::stream_format(stream, z80 ? "jp n%c,%s" : "bcfa,%c %s", cc[rv], ADR(pc, params)); pc+=2; break; case 0x9f: -#if HJB - util::stream_format(stream, "jp %s+r3", ADR(pc)); -#else - util::stream_format(stream, "bxa %s", ADR(pc)); -#endif + util::stream_format(stream, z80 ? "jp %s+r3" : "bxa %s", ADR(pc, params)); pc+=2; break; case 0xa0: case 0xa1: case 0xa2: case 0xa3: -#if HJB - util::stream_format(stream, "sub r0,r%d", rv); -#else - util::stream_format(stream, "subz,%d", rv); -#endif + util::stream_format(stream, z80 ? "sub r0,r%d" : "subz,%d", rv); break; case 0xa4: case 0xa5: case 0xa6: case 0xa7: -#if HJB - util::stream_format(stream, "sub r%d,%s", rv, IMM(pc)); -#else - util::stream_format(stream, "subi,%d %s", rv, IMM(pc)); -#endif + util::stream_format(stream, z80 ? "sub r%d,%s" : "subi,%d %s", rv, IMM(pc, params)); pc+=1; break; case 0xa8: case 0xa9: case 0xaa: case 0xab: -#if HJB - util::stream_format(stream, "sub r%d,(%s)", rv, REL(pc)); -#else - util::stream_format(stream, "subr,%d %s", rv, REL(pc)); -#endif + util::stream_format(stream, z80 ? "sub r%d,(%s)" : "subr,%d %s", rv, REL(pc, params)); pc+=1; break; case 0xac: case 0xad: case 0xae: case 0xaf: -#if HJB - util::stream_format(stream, "sub %s", ABS(1,rv,pc)); -#else - util::stream_format(stream, "suba,%s", ABS(1,rv,pc)); -#endif + util::stream_format(stream, z80 ? "sub %s" : "suba,%s", ABS(1,rv,pc, params)); pc+=2; break; case 0xb0: case 0xb1: case 0xb2: case 0xb3: -#if HJB - util::stream_format(stream, "out (ctrl),r%d", rv); -#else - util::stream_format(stream, "wrtc,%d", rv); -#endif + util::stream_format(stream, z80 ? "out (ctrl),r%d" : "wrtc,%d", rv); break; case 0xb4: -#if HJB - util::stream_format(stream, "bit psu,%s", IMM_PSU(pc)); -#else - util::stream_format(stream, "tpsu %s", IMM_PSU(pc)); -#endif + util::stream_format(stream, z80 ? "bit psu,%s" : "tpsu %s", IMM_PSU(pc, params)); pc+=1; break; case 0xb5: -#if HJB - util::stream_format(stream, "bit psl,%s", IMM_PSL(pc)); -#else - util::stream_format(stream, "tpsl %s", IMM_PSL(pc)); -#endif + util::stream_format(stream, z80 ? "bit psl,%s" : "tpsl %s", IMM_PSL(pc, params)); pc+=1; break; case 0xb6: case 0xb7: -#if HJB - util::stream_format(stream, "**** $%02X",op); -#else - util::stream_format(stream, "**** $%02X",op); -#endif + util::stream_format(stream, z80 ? "**** $%02X" : "**** $%02X",op); break; case 0xb8: case 0xb9: case 0xba: -#if HJB - util::stream_format(stream, "calr n%c,%s", cc[rv], REL(pc)); -#else - util::stream_format(stream, "bsfr,%c %s", cc[rv], REL(pc)); -#endif + util::stream_format(stream, z80 ? "calr n%c,%s" : "bsfr,%c %s", cc[rv], REL(pc, params)); pc+=1; - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case 0xbb: -#if HJB - util::stream_format(stream, "cal0 %s", REL0(pc)); -#else - util::stream_format(stream, "zbsr %s", REL0(pc)); -#endif + util::stream_format(stream, z80 ? "cal0 %s" : "zbsr %s", REL0(pc, params)); pc+=1; - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case 0xbc: case 0xbd: case 0xbe: -#if HJB - util::stream_format(stream, "call n%c,%s", cc[rv], ADR(pc)); -#else - util::stream_format(stream, "bsfa,%c %s", cc[rv], ADR(pc)); -#endif + util::stream_format(stream, z80 ? "call n%c,%s" : "bsfa,%c %s", cc[rv], ADR(pc, params)); pc+=2; - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case 0xbf: -#if HJB - util::stream_format(stream, "call %s+r3", ADR(pc)); -#else - util::stream_format(stream, "bsxa %s", ADR(pc)); -#endif + util::stream_format(stream, z80 ? "call %s+r3" : "bsxa %s", ADR(pc, params)); pc+=2; - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case 0xc0: util::stream_format(stream, "nop"); break; case 0xc1: case 0xc2: case 0xc3: -#if HJB - util::stream_format(stream, "ld r%d,r0", rv); -#else - util::stream_format(stream, "strz,%d", rv); -#endif + util::stream_format(stream, z80 ? "ld r%d,r0" : "strz,%d", rv); break; case 0xc4: case 0xc5: case 0xc6: case 0xc7: -#if HJB - util::stream_format(stream, "**** $%02X",op); -#else - util::stream_format(stream, "**** $%02X",op); -#endif + util::stream_format(stream, z80 ? "**** $%02X" : "**** $%02X",op); break; case 0xc8: case 0xc9: case 0xca: case 0xcb: -#if HJB - util::stream_format(stream, "ld (%s),r%d", REL(pc), rv); -#else - util::stream_format(stream, "strr,%d %s", rv, REL(pc)); -#endif + util::stream_format(stream, z80 ? "ld (%s),r%d" : "strr,%d %s", rv, REL(pc, params)); pc+=1; break; case 0xcc: case 0xcd: case 0xce: case 0xcf: -#if HJB - util::stream_format(stream, "ld %s", ABS(0,rv,pc)); -#else - util::stream_format(stream, "stra,%s", ABS(1,rv,pc)); -#endif + util::stream_format(stream, z80 ? "ld %s" : "stra,%s", ABS(1,rv,pc, params)); pc+=2; break; case 0xd0: case 0xd1: case 0xd2: case 0xd3: -#if HJB - util::stream_format(stream, "rol r%d", rv); -#else - util::stream_format(stream, "rrl,%d", rv); -#endif + util::stream_format(stream, z80 ? "rol r%d" : "rrl,%d", rv); break; case 0xd4: case 0xd5: case 0xd6: case 0xd7: -#if HJB - util::stream_format(stream, "out (%s),r%d", IMM(pc), rv); -#else - util::stream_format(stream, "wrte,%d %s", rv, IMM(pc)); -#endif + util::stream_format(stream, z80 ? "out (%s),r%d" : "wrte,%d %s", rv, IMM(pc, params)); pc+=1; break; case 0xd8: case 0xd9: case 0xda: case 0xdb: -#if HJB - util::stream_format(stream, "ijnz r%d,%s", rv, REL(pc)); -#else - util::stream_format(stream, "birr,%d %s", rv, REL(pc)); -#endif + util::stream_format(stream, z80 ? "ijnz r%d,%s" : "birr,%d %s", rv, REL(pc, params)); pc+=1; - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case 0xdc: case 0xdd: case 0xde: case 0xdf: -#if HJB - util::stream_format(stream, "ijnz r%d,%s", rv, ADR(pc)); -#else - util::stream_format(stream, "bira,%d %s", rv, ADR(pc)); -#endif + util::stream_format(stream, z80 ? "ijnz r%d,%s" : "bira,%d %s", rv, ADR(pc, params)); pc+=2; - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case 0xe0: case 0xe1: case 0xe2: case 0xe3: -#if HJB - util::stream_format(stream, "cp r0,%d", rv); -#else - util::stream_format(stream, "comz,%d", rv); -#endif + util::stream_format(stream, z80 ? "cp r0,%d" : "comz,%d", rv); break; case 0xe4: case 0xe5: case 0xe6: case 0xe7: -#if HJB - util::stream_format(stream, "cp r%d,%s", rv, IMM(pc)); -#else - util::stream_format(stream, "comi,%d %s", rv, IMM(pc)); -#endif + util::stream_format(stream, z80 ? "cp r%d,%s" : "comi,%d %s", rv, IMM(pc, params)); pc+=1; break; case 0xe8: case 0xe9: case 0xea: case 0xeb: -#if HJB - util::stream_format(stream, "cp r%d,(%s)", rv, REL(pc)); -#else - util::stream_format(stream, "comr,%d %s", rv, REL(pc)); -#endif + util::stream_format(stream, z80 ? "cp r%d,(%s)" : "comr,%d %s", rv, REL(pc, params)); pc+=1; break; case 0xec: case 0xed: case 0xee: case 0xef: -#if HJB - util::stream_format(stream, "cp %s", ABS(1,rv,pc)); -#else - util::stream_format(stream, "coma,%s", ABS(1,rv,pc)); -#endif + util::stream_format(stream, z80 ? "cp %s" : "coma,%s", ABS(1,rv,pc, params)); pc+=2; break; case 0xf0: case 0xf1: case 0xf2: case 0xf3: -#if HJB - util::stream_format(stream, "out (data),r%d", rv); -#else - util::stream_format(stream, "wrtd,%d", rv); -#endif + util::stream_format(stream, z80 ? "out (data),r%d" : "wrtd,%d", rv); break; case 0xf4: case 0xf5: case 0xf6: case 0xf7: -#if HJB - util::stream_format(stream, "test r%d,%s", rv, IMM(pc)); -#else - util::stream_format(stream, "tmi,%d %s", rv, IMM(pc)); -#endif + util::stream_format(stream, z80 ? "test r%d,%s" : "tmi,%d %s", rv, IMM(pc, params)); pc+=1; break; case 0xf8: case 0xf9: case 0xfa: case 0xfb: -#if HJB - util::stream_format(stream, "djnz r%d,%s", rv, REL(pc)); -#else - util::stream_format(stream, "bdrr,%d %s", rv, REL(pc)); -#endif + util::stream_format(stream, z80 ? "djnz r%d,%s" : "bdrr,%d %s", rv, REL(pc, params)); pc+=1; - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case 0xfc: case 0xfd: case 0xfe: case 0xff: -#if HJB - util::stream_format(stream, "djnz r%d,%s", rv, ADR(pc)); -#else - util::stream_format(stream, "bdra,%d %s", rv, ADR(pc)); -#endif + util::stream_format(stream, z80 ? "djnz r%d,%s" : "bdra,%d %s", rv, ADR(pc, params)); pc+=2; - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; } - return (pc - PC) | flags | DASMFLAG_SUPPORTED; + return (pc - PC) | flags | SUPPORTED; +} + +u32 s2650_disassembler::opcode_alignment() const +{ + return 1; } diff --git a/src/devices/cpu/s2650/2650dasm.h b/src/devices/cpu/s2650/2650dasm.h new file mode 100644 index 00000000000..bf9523255cc --- /dev/null +++ b/src/devices/cpu/s2650/2650dasm.h @@ -0,0 +1,48 @@ +// license:BSD-3-Clause +// copyright-holders:Juergen Buchmueller +/*************************************************************************** + * + * Portable Signetics 2650 disassembler + * + * Written by J. Buchmueller (pullmoll@t-online.de) + * for the MAME project + * + **************************************************************************/ + +#ifndef MAME_CPU_S2650_2650DASM_H +#define MAME_CPU_S2650_2650DASM_H + +#pragma once + +class s2650_disassembler : public util::disasm_interface +{ +public: + struct config { + virtual ~config() = default; + virtual bool get_z80_mnemonics_mode() const = 0; + }; + + s2650_disassembler(config *conf); + virtual ~s2650_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const int rel[0x100]; + static const char cc[4]; + + void add(std::string &buf, std::string str); + std::string SYM(int addr); + std::string IMM(offs_t pc, const data_buffer ¶ms); + std::string IMM_PSL(offs_t pc, const data_buffer ¶ms); + std::string IMM_PSU(offs_t pc, const data_buffer ¶ms); + std::string REL(offs_t pc, const data_buffer ¶ms); + std::string REL0(offs_t pc, const data_buffer ¶ms); + std::string ABS(int load, int r, offs_t pc, const data_buffer ¶ms); + std::string ADR(offs_t pc, const data_buffer ¶ms); + + config *m_config; +}; + +#endif diff --git a/src/devices/cpu/s2650/s2650.cpp b/src/devices/cpu/s2650/s2650.cpp index 2afc7c5b261..7b452907e03 100644 --- a/src/devices/cpu/s2650/s2650.cpp +++ b/src/devices/cpu/s2650/s2650.cpp @@ -42,13 +42,16 @@ s2650_device::s2650_device(const machine_config &mconfig, const char *tag, devic memset(m_reg, 0x00, sizeof(m_reg)); } - -offs_t s2650_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +bool s2650_device::get_z80_mnemonics_mode() const { - extern CPU_DISASSEMBLE( s2650 ); - return CPU_DISASSEMBLE_NAME(s2650)(this, stream, pc, oprom, opram, options); + // Needs to become configurable live + return false; } +util::disasm_interface *s2650_device::create_disassembler() +{ + return new s2650_disassembler(this); +} device_memory_interface::space_config_vector s2650_device::memory_space_config() const { @@ -823,7 +826,7 @@ void s2650_device::device_start() m_flag_handler.resolve_safe(); m_intack_handler.resolve_safe(); - m_direct = &space(AS_PROGRAM).direct(); + m_direct = space(AS_PROGRAM).direct<0>(); save_item(NAME(m_ppc)); save_item(NAME(m_page)); diff --git a/src/devices/cpu/s2650/s2650.h b/src/devices/cpu/s2650/s2650.h index 4fd297b694a..e329831690c 100644 --- a/src/devices/cpu/s2650/s2650.h +++ b/src/devices/cpu/s2650/s2650.h @@ -5,6 +5,7 @@ #pragma once +#include "2650dasm.h" #define S2650_SENSE_LINE INPUT_LINE_IRQ1 @@ -35,7 +36,7 @@ DECLARE_DEVICE_TYPE(S2650, s2650_device) #define MCFG_S2650_INTACK_HANDLER(_devcb) \ devcb = &s2650_device::set_intack_handler(*device, DEVCB_##_devcb); -class s2650_device : public cpu_device + class s2650_device : public cpu_device, public s2650_disassembler::config { public: // construction/destruction @@ -68,9 +69,8 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 3; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; + virtual bool get_z80_mnemonics_mode() const override; private: address_space_config m_program_config; @@ -95,7 +95,7 @@ private: uint8_t m_irq_state; int m_icount; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; // For debugger uint16_t m_debugger_temp; diff --git a/src/devices/cpu/saturn/saturn.cpp b/src/devices/cpu/saturn/saturn.cpp index 2368c16ef19..480f10a8c1f 100644 --- a/src/devices/cpu/saturn/saturn.cpp +++ b/src/devices/cpu/saturn/saturn.cpp @@ -64,11 +64,16 @@ device_memory_interface::space_config_vector saturn_device::memory_space_config( }; } +bool saturn_device::get_nonstandard_mnemonics_mode() const +{ + // Needs to become configurable live + return false; +} + -offs_t saturn_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *saturn_device::create_disassembler() { - extern CPU_DISASSEMBLE( saturn ); - return CPU_DISASSEMBLE_NAME(saturn)(this, stream, pc, oprom, opram, options); + return new saturn_disassembler(this); } @@ -88,7 +93,7 @@ offs_t saturn_device::disasm_disassemble(std::ostream &stream, offs_t pc, const void saturn_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_out_func.resolve_safe(); m_in_func.resolve_safe(0); diff --git a/src/devices/cpu/saturn/saturn.h b/src/devices/cpu/saturn/saturn.h index d73745a31fb..bd49ad18806 100644 --- a/src/devices/cpu/saturn/saturn.h +++ b/src/devices/cpu/saturn/saturn.h @@ -32,6 +32,7 @@ HP38G 09/??/95 1LT8 Yorke #pragma once +#include "saturnds.h" #define SATURN_INT_NONE 0 #define SATURN_INT_IRQ 1 @@ -72,7 +73,7 @@ enum saturn_device::set_rsi_func(*device, DEVCB_##_rsi); -class saturn_device : public cpu_device +class saturn_device : public cpu_device, public saturn_disassembler::config { public: // construction/destruction @@ -109,9 +110,8 @@ protected: virtual void state_export(const device_state_entry &entry) override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 20; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; + virtual bool get_nonstandard_mnemonics_mode() const override; private: address_space_config m_program_config; @@ -149,7 +149,7 @@ typedef uint8_t Saturn64[16]; int m_monitor_id; int m_monitor_in; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; int m_icount; int64_t m_debugger_temp; diff --git a/src/devices/cpu/saturn/saturnds.cpp b/src/devices/cpu/saturn/saturnds.cpp index a71aec2cbf6..6d3b2767f7f 100644 --- a/src/devices/cpu/saturn/saturnds.cpp +++ b/src/devices/cpu/saturn/saturnds.cpp @@ -9,19 +9,7 @@ *****************************************************************************/ #include "emu.h" -#include "debugger.h" - -#include "saturn.h" - -#define SATURN_HP_MNEMONICS - -#if defined SATURN_HP_MNEMONICS -// class/hp mnemonics -static int set=0; -#else -// readable/normal mnemonics -static int set=1; -#endif +#include "saturnds.h" #define P "P" #define WP "WP" @@ -33,551 +21,382 @@ static int set=1; #define W "W" #define A "A" -static const char *const adr_b[]= +const char *const saturn_disassembler::adr_b[]= { P, WP, XS, X, S, M, B, W }; -static const char *const adr_af[]= +const char *const saturn_disassembler::adr_af[]= { P, WP, XS, X, S, M, B, W, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, A }; -static const char *const adr_a[]= +const char *const saturn_disassembler::adr_a[]= { P, WP, XS, X, S, M, B, W }; -static const char number_2_hex[]= +const char saturn_disassembler::number_2_hex[]= { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; -#define SATURN_PEEKOP_DIS8(v) v = (int8_t)( oprom[pos] | ( oprom[pos+1] << 4 ) ); pos+= 2; +#define SATURN_PEEKOP_DIS8(v) v = (int8_t)( opcodes.r8(pos) | ( opcodes.r8(pos+1) << 4 ) ); pos+= 2; -#define SATURN_PEEKOP_DIS12(v) v = oprom[pos] | ( oprom[pos+1] << 4 ) | ( oprom[pos+2] << 8 ); \ +#define SATURN_PEEKOP_DIS12(v) v = opcodes.r8(pos) | ( opcodes.r8(pos+1) << 4 ) | ( opcodes.r8(pos+2) << 8 ); \ pos += 3; \ if ( v & 0x0800 ) v = -0x1000 + v; -#define SATURN_PEEKOP_DIS16(v) v = (int16_t)( oprom[pos] | ( oprom[pos+1] << 4 ) | ( oprom[pos+2] << 8 ) | ( oprom[pos+3] << 12 ) ); pos += 4; - -#define SATURN_PEEKOP_ADR(v) v = oprom[pos] | ( oprom[pos+1] << 4 ) | ( oprom[pos+2] << 8 ) | ( oprom[pos+3] << 12 ) | ( oprom[pos+4] << 16 ); pos += 5; - - -// don't split branch and return, source relies on this ordering -enum MNEMONICS -{ - Return, ReturnSetXM, ReturnSetCarry, ReturnClearCarry, ReturnFromInterrupt, - jump3,jump4,jump, - call3,call4,call, - branchCarrySet, returnCarrySet, - branchCarryClear, returnCarryClear, - - outCS, outC, inA, inC, - unconfig, config, Cid, shutdown, cp1, reset, buscc, - CcopyP, PcopyC, sreq, CswapP, - - inton, AloadImm, buscb, - clearAbit, setAbit, - branchAbitclear, returnAbitclear, - branchAbitset, returnAbitset, - clearCbit, setCbit, - branchCbitclear, returnCbitclear, - branchCbitset, returnCbitset, - PCloadA, buscd, PCloadC, intoff, rsi, - - jumpA, jumpC, PCcopyA, PCcopyC, AcopyPC, CcopyPC, - - clearHST, - branchHSTclear, returnHSTclear, - - clearBitST, setBitST, - branchSTclear, returnSTclear, - branchSTset, returnSTset, - - - branchPdiffers, returnPdiffers, - branchPequals, returnPequals, - - branchAequalsB, returnAequalsB, - branchBequalsC, returnBequalsC, - branchAequalsC, returnAequalsC, - branchCequalsD, returnCequalsD, - branchAdiffersB, returnAdiffersB, - branchBdiffersC, returnBdiffersC, - branchAdiffersC, returnAdiffersC, - branchCdiffersD, returnCdiffersD, - branchAzero, returnAzero, - branchBzero, returnBzero, - branchCzero, returnCzero, - branchDzero, returnDzero, - branchAnotzero, returnAnotzero, - branchBnotzero, returnBnotzero, - branchCnotzero, returnCnotzero, - branchDnotzero, returnDnotzero, - - branchAgreaterB, returnAgreaterB, - branchBgreaterC, returnBgreaterC, - branchCgreaterA, returnCgreaterA, - branchDgreaterC, returnDgreaterC, - branchAlowerB, returnAlowerB, - branchBlowerC, returnBlowerC, - branchClowerA, returnClowerA, - branchDlowerC, returnDlowerC, - branchAnotlowerB, returnAnotlowerB, - branchBnotlowerC, returnBnotlowerC, - branchCnotlowerA, returnCnotlowerA, - branchDnotlowerC, returnDnotlowerC, - branchAnotgreaterB, returnAnotgreaterB, - branchBnotgreaterC, returnBnotgreaterC, - branchCnotgreaterA, returnCnotgreaterA, - branchDnotgreaterC, returnDnotgreaterC, - - SetHexMode, SetDecMode, - PushC, PopC, - - D0loadImm2, D0loadImm4, D0loadImm5, - D1loadImm2, D1loadImm4, D1loadImm5, - PloadImm, CloadImm, - - clearST, - CcopyST, STcopyC, - swapCST, - - incP, decP, - - R0copyA, R1copyA, R2copyA, R3copyA, R4copyA, - R0copyC, R1copyC, R2copyC, R3copyC, R4copyC, - - AcopyR0, AcopyR1, AcopyR2, AcopyR3, AcopyR4, - CcopyR0, CcopyR1, CcopyR2, CcopyR3, CcopyR4, - - D0copyA, D1copyA, D0copyC, D1copyC, - D0copyAShort, D1copyAShort, D0copyCShort, D1copyCShort, // other class mnemonic - - SwapAR0, SwapAR1, SwapAR2, SwapAR3, SwapAR4, - SwapCR0, SwapCR1, SwapCR2, SwapCR3, SwapCR4, - - SwapAD0, SwapAD1, SwapCD0, SwapCD1, - SwapAD0Short, SwapAD1Short, SwapCD0Short, SwapCD1Short, // other class mnemonic - - D0storeA, D1storeA, D0storeC, D1storeC, - AloadD0, AloadD1, CloadD0, CloadD1, - - D0addImm, D1addImm, D0subImm, D1subImm, - AaddImm, BaddImm, CaddImm, DaddImm, - AsubImm, BsubImm, CsubImm, DsubImm, - - AandB, BandC, CandA, DandC, BandA, CandB, AandC, CandD, - AorB, BorC, CorA, DorC, BorA, CorB, AorC, CorD, - - Ashiftrightbit, Bshiftrightbit, Cshiftrightbit, Dshiftrightbit, - - AshiftleftCarry, BshiftleftCarry, CshiftleftCarry, DshiftleftCarry, - AshiftrightCarry, BshiftrightCarry, CshiftrightCarry, DshiftrightCarry, - - AaddB, BaddC, CaddA, DaddC, AaddA, BaddB, CaddC, DaddD, - BaddA, CaddB, AaddC, CaddD, decA, decB, decC, decD, - - AsubB, BsubC, CsubA, DsubC, incA, incB, incC, incD, - BsubA, CsubB, AsubC, CsubD, AsubnB, BsubnC, CsubnA, DsubnC, - - clearA, clearB, clearC, clearD, - AcopyB, BcopyC, CcopyA, DcopyC, BcopyA, CcopyB, AcopyC, CcopyD, - AswapB, BswapC, CswapA, DswapC, - - Ashiftleft, Bshiftleft, Cshiftleft, Dshiftleft, - Ashiftright, Bshiftright, Cshiftright, Dshiftright, - negateA, negateB, negateC, negateD, - notA, notB, notC, notD - -}; - -static const struct { - const char *name[2]; -} mnemonics[]={ - { { "rtn", "RET" } }, - { { "rtnsXM", "RETSETXM" } }, - { { "rtnsC", "RETSETC" } }, - { { "rtncC", "RETCLRC" } }, - { { "rti", "RETI" } }, - { { "goto %05x", "JUMP.3 %05x" } }, - { { "goto %05x", "JUMP.4 %05x" } }, - { { "goto %05x", "JUMP %05x" } }, - { { "gosub %05x", "CALL.3 %05x" } }, - { { "gosub %05x", "CALL.4 %05x" } }, - { { "gosub %05x", "CALL %05x" } }, - { { "goC %05x", "BRCS %05x" } }, - { { "rtnC", "RETCS" } }, - { { "gonC %05x", "BRCC %05x" } }, - { { "rtnnC", "RETCC" } }, - - { { "OUT=CS", "OUT.S C" } }, - { { "OUT=C", "OUT.X C" } }, - { { "A=IN", "IN.4 A" } }, - { { "C=IN", "IN.4 C" } }, - { { "uncnfg", "UNCNFG" } }, - { { "config", "CONFIG" } }, - { { "C=id", "MOVE.A ID,C" } }, - { { "!shutdn", "!SHUTDN" } }, - { { "C+P+1", "ADD.A P+1,C" } }, - { { "reset", "RESET" } }, - { { "!buscc", "!BUSCC" } }, - { { "C=P %x", "MOVE.1 P,C,%x" } }, - { { "P=C %x", "MOVE.1 C,%x,P" } }, - { { "!sreq?", "!SREQ" } }, - { { "CPex %x", "SWAP.1 P,C,%x" } }, - - { { "!inton", "!INTON" } }, - { { "LA %-2x %s", "MOVE.P%-2x %s,A" } }, - { { "!buscb", "!BUSCB" } }, - { { "Abit=0 %x", "CLRB %x,A" } }, - { { "Abit=1 %x", "SETB %x,A" } }, - { { "?Abit=0 %x,%05x", "BRBC %x,A,%05x" } }, - { { "?Abit=0 %x,rtn", "RETBC %x,A" } }, - { { "?Abit=1 %x,%05x", "BRBS %x,A,%05x" } }, - { { "?Abit=1 %x,rtn", "RETBS %x,A" } }, - { { "Cbit=0 %x", "CLRB %x,C" } }, - { { "Cbit=1 %x", "SETB %x,C" } }, - { { "?Cbit=0 %x,%05x", "BRBC %x,C,%05x" } }, - { { "?Cbit=0 %x,rtn", "RETBC %x,C" } }, - { { "?Cbit=1 %x,%05x", "BRBS %x,C,%05x" } }, - { { "?Cbit=1 %x,rtn", "RETBS %x,C" } }, - { { "PC=(A)", "JUMP.A @A" } }, - { { "!buscd", "!BUSCD" } }, - { { "PC=(C)", "JUMP.A @C" } }, - { { "!intoff", "!INTOFF" } }, - { { "!rsi", "!RSI" } }, - - { { "PC=A", "JUMP.A A" } }, - { { "PC=C", "JUMP.A C" } }, - { { "A=PC", "MOVE.A PC,A" } }, - { { "C=PC", "MOVE.A PC,C" } }, - { { "APCex", "SWAP.A A,PC" } }, - { { "CPCex", "SWAP.A C,PC" } }, - - { { "HST=0 %x", "CLRHST %x" } }, - { { "?HST=0 %x,%05x", "BRBCHST %x,%05x" } }, - { { "?HST=0 %x,rtn", "RETBCHST %x" } }, - { { "ST=0 %x", "CLRB %x,ST" } }, - { { "ST=1 %x", "SETB %x,ST" } }, - { { "?ST=0 %x,%05x", "BRBC ST,%x,%05x" } }, - { { "?ST=0 %x,rtn", "RETBC ST,%x" } }, - { { "?ST=1 %x,%05x", "BRBS ST,%x,%05x" } }, - { { "?ST=1 %x,rtn", "RETBS ST,%x" } }, - { { "?P# %x,%05x", "BRNE P,%x,%05x" } }, - { { "?P# %x,rtn", "RETNE P,%x" } }, - { { "?P= %x,%05x", "BREQ P,%x,%05x" } }, - { { "?P= %x,rtn", "RETEQ P,%x" } }, - - { { "?A=B %s,%05x", "BREQ.%-2s A,B,%05x" } }, - { { "?A=B %s,rtn", "RETEQ.%-2s A,B" } }, - { { "?B=C %s,%05x", "BREQ.%-2s B,C,%05x" } }, - { { "?B=C %s,rtn", "RETEQ.%-2s B,C" } }, - { { "?A=C %s,%05x", "BREQ.%-2s A,C,%05x" } }, - { { "?A=C %s,rtn", "RETEQ.%-2s A,C" } }, - { { "?C=D %s,%05x", "BREQ.%-2s C,D,%05x" } }, - { { "?C=D %s,rtn", "RETEQ.%-2s C,D" } }, - { { "?A#B %s,%05x", "BRNE.%-2s A,B,%05x" } }, - { { "?A#B %s,rtn", "RETNE.%-2s A,B" } }, - { { "?B#C %s,%05x", "BRNE.%-2s B,C,%05x" } }, - { { "?B#C %s,rtn", "RETNE.%-2s B,C" } }, - { { "?A#C %s,%05x", "BRNE.%-2s A,C,%05x" } }, - { { "?A#C %s,rtn", "RETNE.%-2s A,C" } }, - { { "?C#D %s,%05x", "BRNE.%-2s C,D,%05x" } }, - { { "?C#D %s,rtn", "RETNE.%-2s C,D" } }, - { { "?A=0 %s,%05x", "BRZ.%-2s A,%05x" } }, - { { "?A=0 %s,rtn", "RETZ.%-2s A" } }, - { { "?B=0 %s,%05x", "BRZ.%-2s B,%05x" } }, - { { "?B=0 %s,rtn", "RETZ.%-2s B" } }, - { { "?C=0 %s,%05x", "BRZ.%-2s C,%05x" } }, - { { "?C=0 %s,rtn", "RETZ.%-2s C" } }, - { { "?D=0 %s,%05x", "BRZ.%-2s D,%05x" } }, - { { "?D=0 %s,rtn", "RETZ.%-2s D" } }, - { { "?A#0 %s,%05x", "BRNZ.%-2s A,%05x" } }, - { { "?A#0 %s,rtn", "RETNZ.%-2s A" } }, - { { "?B#0 %s,%05x", "BRNZ.%-2s B,%05x" } }, - { { "?B#0 %s,rtn", "RETNZ.%-2s B" } }, - { { "?C#0 %s,%05x", "BRNZ.%-2s C,%05x" } }, - { { "?C#0 %s,rtn", "RETNZ.%-2s C" } }, - { { "?D#0 %s,%05x", "BRNZ.%-2s D,%05x" } }, - { { "?D#0 %s,rtn", "RETNZ.%-2s D" } }, - - { { "?A>B %s,%05x", "BRGT.%-2s A,B,%05x" } }, - { { "?A>B %s,rtn", "RETGT.%-2s A,B" } }, - { { "?B>C %s,%05x", "BRGT.%-2s B,C,%05x" } }, - { { "?B>C %s,rtn", "RETGT.%-2s B,C" } }, - { { "?C>A %s,%05x", "BRGT.%-2s C,A,%05x" } }, - { { "?C>A %s,rtn", "RETGT.%-2s C,A" } }, - { { "?D>C %s,%05x", "BRGT.%-2s D,C,%05x" } }, - { { "?D>C %s,rtn", "RETGT.%-2s D,C" } }, - { { "?A<B %s,%05x", "BRLT.%-2s A,B,%05x" } }, - { { "?A<B %s,rtn", "RETLT.%-2s A,B" } }, - { { "?B<C %s,%05x", "BRLT.%-2s B,C,%05x" } }, - { { "?B<C %s,rtn", "RETLT.%-2s B,C" } }, - { { "?C<A %s,%05x", "BRLT.%-2s C,A,%05x" } }, - { { "?C<A %s,rtn", "RETLT.%-2s C,A" } }, - { { "?D<C %s,%05x", "BRLT.%-2s D,C,%05x" } }, - { { "?D<C %s,rtn", "RETLT.%-2s D,C" } }, - { { "?A>=B %s,%05x", "BRGE.%-2s A,B,%05x" } }, - { { "?A>=B %s,rtn", "RETGE.%-2s A,B" } }, - { { "?B>=C %s,%05x", "BRGE.%-2s B,C,%05x" } }, - { { "?B>=C %s,rtn", "RETGE.%-2s B,C" } }, - { { "?C>=A %s,%05x", "BRGE.%-2s C,A,%05x" } }, - { { "?C>=A %s,rtn", "RETGE.%-2s C,A" } }, - { { "?D>=C %s,%05x", "BRGE.%-2s D,C,%05x" } }, - { { "?D>=C %s,rtn", "RETGE.%-2s D,C" } }, - { { "?A<=B %s,%05x", "BRLE.%-2s A,B,%05x" } }, - { { "?A<=B %s,rtn", "RETLE.%-2s A,B" } }, - { { "?B<=C %s,%05x", "BRLE.%-2s B,C,%05x" } }, - { { "?B<=C %s,rtn", "RETLE.%-2s B,C" } }, - { { "?C<=A %s,%05x", "BRLE.%-2s C,A,%05x" } }, - { { "?C<=A %s,rtn", "RETLE.%-2s C,A" } }, - { { "?D<=C %s,%05x", "BRLE.%-2s D,C,%05x" } }, - { { "?D<=C %s,rtn", "RETLE.%-2s D,C" } }, - - { { "sethex", "SETHEX" } }, - { { "setdec", "SETDEC" } }, - { { "RSTK=C", "PUSH.A C" } }, - { { "C=RSTK", "POP.A C" } }, +#define SATURN_PEEKOP_DIS16(v) v = (int16_t)( opcodes.r8(pos) | ( opcodes.r8(pos+1) << 4 ) | ( opcodes.r8(pos+2) << 8 ) | ( opcodes.r8(pos+3) << 12 ) ); pos += 4; + +#define SATURN_PEEKOP_ADR(v) v = opcodes.r8(pos) | ( opcodes.r8(pos+1) << 4 ) | ( opcodes.r8(pos+2) << 8 ) | ( opcodes.r8(pos+3) << 12 ) | ( opcodes.r8(pos+4) << 16 ); pos += 5; + + +const char *const saturn_disassembler::mnemonics[][2] = { + { "rtn", "RET" }, + { "rtnsXM", "RETSETXM" }, + { "rtnsC", "RETSETC" }, + { "rtncC", "RETCLRC" }, + { "rti", "RETI" }, + { "goto %05x", "JUMP.3 %05x" }, + { "goto %05x", "JUMP.4 %05x" }, + { "goto %05x", "JUMP %05x" }, + { "gosub %05x", "CALL.3 %05x" }, + { "gosub %05x", "CALL.4 %05x" }, + { "gosub %05x", "CALL %05x" }, + { "goC %05x", "BRCS %05x" }, + { "rtnC", "RETCS" }, + { "gonC %05x", "BRCC %05x" }, + { "rtnnC", "RETCC" }, + + { "OUT=CS", "OUT.S C" }, + { "OUT=C", "OUT.X C" }, + { "A=IN", "IN.4 A" }, + { "C=IN", "IN.4 C" }, + { "uncnfg", "UNCNFG" }, + { "config", "CONFIG" }, + { "C=id", "MOVE.A ID,C" }, + { "!shutdn", "!SHUTDN" }, + { "C+P+1", "ADD.A P+1,C" }, + { "reset", "RESET" }, + { "!buscc", "!BUSCC" }, + { "C=P %x", "MOVE.1 P,C,%x" }, + { "P=C %x", "MOVE.1 C,%x,P" }, + { "!sreq?", "!SREQ" }, + { "CPex %x", "SWAP.1 P,C,%x" }, + + { "!inton", "!INTON" }, + { "LA %-2x %s", "MOVE.P%-2x %s,A" }, + { "!buscb", "!BUSCB" }, + { "Abit=0 %x", "CLRB %x,A" }, + { "Abit=1 %x", "SETB %x,A" }, + { "?Abit=0 %x,%05x", "BRBC %x,A,%05x" }, + { "?Abit=0 %x,rtn", "RETBC %x,A" }, + { "?Abit=1 %x,%05x", "BRBS %x,A,%05x" }, + { "?Abit=1 %x,rtn", "RETBS %x,A" }, + { "Cbit=0 %x", "CLRB %x,C" }, + { "Cbit=1 %x", "SETB %x,C" }, + { "?Cbit=0 %x,%05x", "BRBC %x,C,%05x" }, + { "?Cbit=0 %x,rtn", "RETBC %x,C" }, + { "?Cbit=1 %x,%05x", "BRBS %x,C,%05x" }, + { "?Cbit=1 %x,rtn", "RETBS %x,C" }, + { "PC=(A)", "JUMP.A @A" }, + { "!buscd", "!BUSCD" }, + { "PC=(C)", "JUMP.A @C" }, + { "!intoff", "!INTOFF" }, + { "!rsi", "!RSI" }, + + { "PC=A", "JUMP.A A" }, + { "PC=C", "JUMP.A C" }, + { "A=PC", "MOVE.A PC,A" }, + { "C=PC", "MOVE.A PC,C" }, + { "APCex", "SWAP.A A,PC" }, + { "CPCex", "SWAP.A C,PC" }, + + { "HST=0 %x", "CLRHST %x" }, + { "?HST=0 %x,%05x", "BRBCHST %x,%05x" }, + { "?HST=0 %x,rtn", "RETBCHST %x" }, + { "ST=0 %x", "CLRB %x,ST" }, + { "ST=1 %x", "SETB %x,ST" }, + { "?ST=0 %x,%05x", "BRBC ST,%x,%05x" }, + { "?ST=0 %x,rtn", "RETBC ST,%x" }, + { "?ST=1 %x,%05x", "BRBS ST,%x,%05x" }, + { "?ST=1 %x,rtn", "RETBS ST,%x" }, + { "?P# %x,%05x", "BRNE P,%x,%05x" }, + { "?P# %x,rtn", "RETNE P,%x" }, + { "?P= %x,%05x", "BREQ P,%x,%05x" }, + { "?P= %x,rtn", "RETEQ P,%x" }, + + { "?A=B %s,%05x", "BREQ.%-2s A,B,%05x" }, + { "?A=B %s,rtn", "RETEQ.%-2s A,B" }, + { "?B=C %s,%05x", "BREQ.%-2s B,C,%05x" }, + { "?B=C %s,rtn", "RETEQ.%-2s B,C" }, + { "?A=C %s,%05x", "BREQ.%-2s A,C,%05x" }, + { "?A=C %s,rtn", "RETEQ.%-2s A,C" }, + { "?C=D %s,%05x", "BREQ.%-2s C,D,%05x" }, + { "?C=D %s,rtn", "RETEQ.%-2s C,D" }, + { "?A#B %s,%05x", "BRNE.%-2s A,B,%05x" }, + { "?A#B %s,rtn", "RETNE.%-2s A,B" }, + { "?B#C %s,%05x", "BRNE.%-2s B,C,%05x" }, + { "?B#C %s,rtn", "RETNE.%-2s B,C" }, + { "?A#C %s,%05x", "BRNE.%-2s A,C,%05x" }, + { "?A#C %s,rtn", "RETNE.%-2s A,C" }, + { "?C#D %s,%05x", "BRNE.%-2s C,D,%05x" }, + { "?C#D %s,rtn", "RETNE.%-2s C,D" }, + { "?A=0 %s,%05x", "BRZ.%-2s A,%05x" }, + { "?A=0 %s,rtn", "RETZ.%-2s A" }, + { "?B=0 %s,%05x", "BRZ.%-2s B,%05x" }, + { "?B=0 %s,rtn", "RETZ.%-2s B" }, + { "?C=0 %s,%05x", "BRZ.%-2s C,%05x" }, + { "?C=0 %s,rtn", "RETZ.%-2s C" }, + { "?D=0 %s,%05x", "BRZ.%-2s D,%05x" }, + { "?D=0 %s,rtn", "RETZ.%-2s D" }, + { "?A#0 %s,%05x", "BRNZ.%-2s A,%05x" }, + { "?A#0 %s,rtn", "RETNZ.%-2s A" }, + { "?B#0 %s,%05x", "BRNZ.%-2s B,%05x" }, + { "?B#0 %s,rtn", "RETNZ.%-2s B" }, + { "?C#0 %s,%05x", "BRNZ.%-2s C,%05x" }, + { "?C#0 %s,rtn", "RETNZ.%-2s C" }, + { "?D#0 %s,%05x", "BRNZ.%-2s D,%05x" }, + { "?D#0 %s,rtn", "RETNZ.%-2s D" }, + + { "?A>B %s,%05x", "BRGT.%-2s A,B,%05x" }, + { "?A>B %s,rtn", "RETGT.%-2s A,B" }, + { "?B>C %s,%05x", "BRGT.%-2s B,C,%05x" }, + { "?B>C %s,rtn", "RETGT.%-2s B,C" }, + { "?C>A %s,%05x", "BRGT.%-2s C,A,%05x" }, + { "?C>A %s,rtn", "RETGT.%-2s C,A" }, + { "?D>C %s,%05x", "BRGT.%-2s D,C,%05x" }, + { "?D>C %s,rtn", "RETGT.%-2s D,C" }, + { "?A<B %s,%05x", "BRLT.%-2s A,B,%05x" }, + { "?A<B %s,rtn", "RETLT.%-2s A,B" }, + { "?B<C %s,%05x", "BRLT.%-2s B,C,%05x" }, + { "?B<C %s,rtn", "RETLT.%-2s B,C" }, + { "?C<A %s,%05x", "BRLT.%-2s C,A,%05x" }, + { "?C<A %s,rtn", "RETLT.%-2s C,A" }, + { "?D<C %s,%05x", "BRLT.%-2s D,C,%05x" }, + { "?D<C %s,rtn", "RETLT.%-2s D,C" }, + { "?A>=B %s,%05x", "BRGE.%-2s A,B,%05x" }, + { "?A>=B %s,rtn", "RETGE.%-2s A,B" }, + { "?B>=C %s,%05x", "BRGE.%-2s B,C,%05x" }, + { "?B>=C %s,rtn", "RETGE.%-2s B,C" }, + { "?C>=A %s,%05x", "BRGE.%-2s C,A,%05x" }, + { "?C>=A %s,rtn", "RETGE.%-2s C,A" }, + { "?D>=C %s,%05x", "BRGE.%-2s D,C,%05x" }, + { "?D>=C %s,rtn", "RETGE.%-2s D,C" }, + { "?A<=B %s,%05x", "BRLE.%-2s A,B,%05x" }, + { "?A<=B %s,rtn", "RETLE.%-2s A,B" }, + { "?B<=C %s,%05x", "BRLE.%-2s B,C,%05x" }, + { "?B<=C %s,rtn", "RETLE.%-2s B,C" }, + { "?C<=A %s,%05x", "BRLE.%-2s C,A,%05x" }, + { "?C<=A %s,rtn", "RETLE.%-2s C,A" }, + { "?D<=C %s,%05x", "BRLE.%-2s D,C,%05x" }, + { "?D<=C %s,rtn", "RETLE.%-2s D,C" }, + + { "sethex", "SETHEX" }, + { "setdec", "SETDEC" }, + { "RSTK=C", "PUSH.A C" }, + { "C=RSTK", "POP.A C" }, // load immediate - { { "D0= %02x", "MOVE.2 %02x,D0" } }, - { { "D0= %04x", "MOVE.4 %04x,D0" } }, - { { "D0= %05x", "MOVE.5 %05x,D0" } }, + { "D0= %02x", "MOVE.2 %02x,D0" }, + { "D0= %04x", "MOVE.4 %04x,D0" }, + { "D0= %05x", "MOVE.5 %05x,D0" }, - { { "D1= %02x", "MOVE.2 %02x,D1" } }, - { { "D1= %04x", "MOVE.4 %04x,D1" } }, - { { "D1= %05x", "MOVE.5 %05x,D1" } }, + { "D1= %02x", "MOVE.2 %02x,D1" }, + { "D1= %04x", "MOVE.4 %04x,D1" }, + { "D1= %05x", "MOVE.5 %05x,D1" }, - { { "P= %x", "MOVE %x,P" } }, - { { "lC %-2x %s", "MOVE.P%-2x %s,C" } }, + { "P= %x", "MOVE %x,P" }, + { "lC %-2x %s", "MOVE.P%-2x %s,C" }, - { { "clrST", "CLR.X ST" } }, - { { "C=ST", "MOVE.X ST,C" } }, - { { "ST=C", "MOVE.X C,ST" } }, - { { "CSTex", "SWAP.X C,ST" } }, + { "clrST", "CLR.X ST" }, + { "C=ST", "MOVE.X ST,C" }, + { "ST=C", "MOVE.X C,ST" }, + { "CSTex", "SWAP.X C,ST" }, - { { "P=P+1", "INC P" } }, - { { "P=P-1", "DEC P" } }, + { "P=P+1", "INC P" }, + { "P=P-1", "DEC P" }, // copy - { { "R0=A %s", "MOVE.%-2s A,R0" } }, - { { "R1=A %s", "MOVE.%-2s A,R1" } }, - { { "R2=A %s", "MOVE.%-2s A,R2" } }, - { { "R3=A %s", "MOVE.%-2s A,R3" } }, - { { "R4=A %s", "MOVE.%-2s A,R4" } }, - - { { "R0=C %s", "MOVE.%-2s C,R0" } }, - { { "R1=C %s", "MOVE.%-2s C,R1" } }, - { { "R2=C %s", "MOVE.%-2s C,R2" } }, - { { "R3=C %s", "MOVE.%-2s C,R3" } }, - { { "R4=C %s", "MOVE.%-2s C,R4" } }, - - { { "A=R0 %s", "MOVE.%-2s R0,A" } }, - { { "A=R1 %s", "MOVE.%-2s R1,A" } }, - { { "A=R2 %s", "MOVE.%-2s R2,A" } }, - { { "A=R3 %s", "MOVE.%-2s R3,A" } }, - { { "A=R4 %s", "MOVE.%-2s R4,A" } }, - - { { "C=R0 %s", "MOVE.%-2s R0,C" } }, - { { "C=R1 %s", "MOVE.%-2s R1,C" } }, - { { "C=R2 %s", "MOVE.%-2s R2,C" } }, - { { "C=R3 %s", "MOVE.%-2s R3,C" } }, - { { "C=R4 %s", "MOVE.%-2s R4,C" } }, - - { { "D0=A", "MOVE.A A,D0" } }, - { { "D1=A", "MOVE.A A,D1" } }, - { { "D0=C", "MOVE.A C,D0" } }, - { { "D1=C", "MOVE.A C,D1" } }, - { { "D0=As", "MOVE.S A,D0" } }, - { { "D1=As", "MOVE.S A,D1" } }, - { { "D0=Cs", "MOVE.S C,D0" } }, - { { "D1=Cs", "MOVE.S C,D1" } }, + { "R0=A %s", "MOVE.%-2s A,R0" }, + { "R1=A %s", "MOVE.%-2s A,R1" }, + { "R2=A %s", "MOVE.%-2s A,R2" }, + { "R3=A %s", "MOVE.%-2s A,R3" }, + { "R4=A %s", "MOVE.%-2s A,R4" }, + + { "R0=C %s", "MOVE.%-2s C,R0" }, + { "R1=C %s", "MOVE.%-2s C,R1" }, + { "R2=C %s", "MOVE.%-2s C,R2" }, + { "R3=C %s", "MOVE.%-2s C,R3" }, + { "R4=C %s", "MOVE.%-2s C,R4" }, + + { "A=R0 %s", "MOVE.%-2s R0,A" }, + { "A=R1 %s", "MOVE.%-2s R1,A" }, + { "A=R2 %s", "MOVE.%-2s R2,A" }, + { "A=R3 %s", "MOVE.%-2s R3,A" }, + { "A=R4 %s", "MOVE.%-2s R4,A" }, + + { "C=R0 %s", "MOVE.%-2s R0,C" }, + { "C=R1 %s", "MOVE.%-2s R1,C" }, + { "C=R2 %s", "MOVE.%-2s R2,C" }, + { "C=R3 %s", "MOVE.%-2s R3,C" }, + { "C=R4 %s", "MOVE.%-2s R4,C" }, + + { "D0=A", "MOVE.A A,D0" }, + { "D1=A", "MOVE.A A,D1" }, + { "D0=C", "MOVE.A C,D0" }, + { "D1=C", "MOVE.A C,D1" }, + { "D0=As", "MOVE.S A,D0" }, + { "D1=As", "MOVE.S A,D1" }, + { "D0=Cs", "MOVE.S C,D0" }, + { "D1=Cs", "MOVE.S C,D1" }, // swap operations - { { "AR0ex %s", "SWAP.%-2s A,R0" } }, - { { "AR1ex %s", "SWAP.%-2s A,R1" } }, - { { "AR2ex %s", "SWAP.%-2s A,R2" } }, - { { "AR3ex %s", "SWAP.%-2s A,R3" } }, - { { "AR4ex %s", "SWAP.%-2s A,R4" } }, - - { { "CR0ex %s", "SWAP.%-2s C,R0" } }, - { { "CR1ex %s", "SWAP.%-2s C,R1" } }, - { { "CR2ex %s", "SWAP.%-2s C,R2" } }, - { { "CR3ex %s", "SWAP.%-2s C,R3" } }, - { { "CR4ex %s", "SWAP.%-2s C,R4" } }, - - { { "AD0ex", "SWAP.A A,D0" } }, - { { "AD1ex", "SWAP.A A,D1" } }, - { { "CD0ex", "SWAP.A C,D0" } }, - { { "CD1ex", "SWAP.A C,D1" } }, - { { "AD0xs", "SWAP.S A,D0" } }, - { { "AD1xs", "SWAP.S A,D1" } }, - { { "CD0xs", "SWAP.S C,D0" } }, - { { "CD1xs", "SWAP.S C,D1" } }, + { "AR0ex %s", "SWAP.%-2s A,R0" }, + { "AR1ex %s", "SWAP.%-2s A,R1" }, + { "AR2ex %s", "SWAP.%-2s A,R2" }, + { "AR3ex %s", "SWAP.%-2s A,R3" }, + { "AR4ex %s", "SWAP.%-2s A,R4" }, + + { "CR0ex %s", "SWAP.%-2s C,R0" }, + { "CR1ex %s", "SWAP.%-2s C,R1" }, + { "CR2ex %s", "SWAP.%-2s C,R2" }, + { "CR3ex %s", "SWAP.%-2s C,R3" }, + { "CR4ex %s", "SWAP.%-2s C,R4" }, + + { "AD0ex", "SWAP.A A,D0" }, + { "AD1ex", "SWAP.A A,D1" }, + { "CD0ex", "SWAP.A C,D0" }, + { "CD1ex", "SWAP.A C,D1" }, + { "AD0xs", "SWAP.S A,D0" }, + { "AD1xs", "SWAP.S A,D1" }, + { "CD0xs", "SWAP.S C,D0" }, + { "CD1xs", "SWAP.S C,D1" }, // store - { { "Dat0=A %s", "MOVE.%-2s A,@D0" } }, - { { "Dat1=A %s", "MOVE.%-2s A,@D0" } }, - { { "Dat0=C %s", "MOVE.%-2s C,@D0" } }, - { { "Dat1=C %s", "MOVE.%-2s C,@D0" } }, + { "Dat0=A %s", "MOVE.%-2s A,@D0" }, + { "Dat1=A %s", "MOVE.%-2s A,@D0" }, + { "Dat0=C %s", "MOVE.%-2s C,@D0" }, + { "Dat1=C %s", "MOVE.%-2s C,@D0" }, // load - { { "A=Dat0 %s", "MOVE.%-2s @D0,A" } }, - { { "A=Dat1 %s", "MOVE.%-2s @D0,A" } }, - { { "C=Dat0 %s", "MOVE.%-2s @D0,C" } }, - { { "C=Dat1 %s", "MOVE.%-2s @D0,C" } }, + { "A=Dat0 %s", "MOVE.%-2s @D0,A" }, + { "A=Dat1 %s", "MOVE.%-2s @D0,A" }, + { "C=Dat0 %s", "MOVE.%-2s @D0,C" }, + { "C=Dat1 %s", "MOVE.%-2s @D0,C" }, // add/sub immediate - { { "D0=D0+ %x", "ADD.A %x,D0" } }, - { { "D1=D1+ %x", "ADD.A %x,D1" } }, - { { "D0=D0- %x", "SUB.A %x,D0" } }, - { { "D1=D1- %x", "SUB.A %x,D1" } }, - - { { "A=A+ %s,%x", "ADD.%-2s %x,A" } }, - { { "B=B+ %s,%x", "ADD.%-2s %x,B" } }, - { { "C=C+ %s,%x", "ADD.%-2s %x,C" } }, - { { "D=D+ %s,%x", "ADD.%-2s %x,D" } }, - { { "A=A- %s,%x", "SUB.%-2s %x,A" } }, - { { "B=B- %s,%x", "SUB.%-2s %x,B" } }, - { { "C=C- %s,%x", "SUB.%-2s %x,C" } }, - { { "D=D- %s,%x", "SUB.%-2s %x,D" } }, - - { { "A=A&B %s", "AND.%-2s B,A" } }, - { { "B=B&C %s", "AND.%-2s C,B" } }, - { { "C=C&A %s", "AND.%-2s A,C" } }, - { { "D=D&C %s", "AND.%-2s C,D" } }, - { { "B=B&A %s", "AND.%-2s A,B" } }, - { { "C=C&B %s", "AND.%-2s B,C" } }, - { { "A=A&C %s", "AND.%-2s C,A" } }, - { { "C=C&D %s", "AND.%-2s D,C" } }, - - { { "A=A!B %s", "OR.%-2s B,A" } }, - { { "B=B!C %s", "OR.%-2s C,B" } }, - { { "C=C!A %s", "OR.%-2s A,C" } }, - { { "D=D!C %s", "OR.%-2s C,D" } }, - { { "B=B!A %s", "OR.%-2s A,B" } }, - { { "C=C!B %s", "OR.%-2s B,C" } }, - { { "A=A!C %s", "OR.%-2s C,A" } }, - { { "C=C!D %s", "OR.%-2s D,C" } }, - - { { "Asrb %s", "SRB.%-2s A" } }, - { { "Bsrb %s", "SRB.%-2s B" } }, - { { "Csrb %s", "SRB.%-2s C" } }, - { { "Dsrb %s", "SRB.%-2s D" } }, - - { { "Aslc %s", "RLN.%-2s A" } }, - { { "Bslc %s", "RLN.%-2s B" } }, - { { "Cslc %s", "RLN.%-2s C" } }, - { { "Dslc %s", "RLN.%-2s D" } }, - { { "Asrc %s", "RRN.%-2s A" } }, - { { "Bsrc %s", "RRN.%-2s B" } }, - { { "Csrc %s", "RRN.%-2s C" } }, - { { "Dsrc %s", "RRN.%-2s D" } }, - - { { "A=A+B %s", "ADD.%-2s B,A" } }, - { { "B=B+C %s", "ADD.%-2s C,B" } }, - { { "C=C+A %s", "ADD.%-2s A,C" } }, - { { "D=D+C %s", "ADD.%-2s C,D" } }, - { { "A=A+A %s", "ADD.%-2s A,A" } }, - { { "B=B+B %s", "ADD.%-2s B,B" } }, - { { "C=C+C %s", "ADD.%-2s C,C" } }, - { { "D=D+C %s", "ADD.%-2s D,D" } }, - { { "B=B+A %s", "ADD.%-2s A,B" } }, - { { "C=C+B %s", "ADD.%-2s B,C" } }, - { { "A=A+C %s", "ADD.%-2s C,A" } }, - { { "C=C+D %s", "ADD.%-2s D,C" } }, - { { "A=A-1 %s", "DEC.%-2s A" } }, - { { "B=B-1 %s", "DEC.%-2s B" } }, - { { "C=C-1 %s", "DEC.%-2s C" } }, - { { "D=D-1 %s", "DEC.%-2s D" } }, - - { { "A=A-B %s", "ADD.%-2s B,A" } }, - { { "B=B-C %s", "ADD.%-2s C,B" } }, - { { "C=C-A %s", "ADD.%-2s A,C" } }, - { { "D=D-C %s", "ADD.%-2s C,D" } }, - { { "A=A+1 %s", "INC.%-2s A" } }, - { { "B=B+1 %s", "INC.%-2s B" } }, - { { "C=C+1 %s", "INC.%-2s C" } }, - { { "D=D+1 %s", "INC.%-2s D" } }, - { { "B=B-A %s", "SUB.%-2s A,B" } }, - { { "C=C-B %s", "SUB.%-2s B,C" } }, - { { "A=A-C %s", "SUB.%-2s C,A" } }, - { { "C=C-D %s", "SUB.%-2s D,C" } }, - { { "A=B-A %s", "SUBN.%-2s B,A" } }, - { { "B=C-B %s", "SUBN.%-2s C,B" } }, - { { "C=A-C %s", "SUBN.%-2s A,C" } }, - { { "D=C-D %s", "SUBN.%-2s C,D" } }, - - { { "A=0 %s", "CLR.%-2s A" } }, - { { "B=0 %s", "CLR.%-2s B" } }, - { { "C=0 %s", "CLR.%-2s C" } }, - { { "D=0 %s", "CLR.%-2s D" } }, - { { "A=B %s", "MOVE.%-2s B,A" } }, - { { "B=C %s", "MOVE.%-2s C,B" } }, - { { "C=A %s", "MOVE.%-2s A,C" } }, - { { "D=C %s", "MOVE.%-2s C,D" } }, - { { "B=A %s", "MOVE.%-2s A,B" } }, - { { "C=B %s", "MOVE.%-2s B,C" } }, - { { "A=C %s", "MOVE.%-2s C,A" } }, - { { "C=D %s", "MOVE.%-2s D,C" } }, - { { "ABex %s", "SWAP.%-2s A,B" } }, - { { "BCex %s", "SWAP.%-2s B,C" } }, - { { "ACex %s", "SWAP.%-2s A,C" } }, - { { "CDex %s", "SWAP.%-2s C,D" } }, - - { { "Asl %s", "SLN.%-2s A" } }, - { { "Bsl %s", "SLN.%-2s B" } }, - { { "Csl %s", "SLN.%-2s C" } }, - { { "Dsl %s", "SLN.%-2s D" } }, - { { "Asr %s", "SRN.%-2s A" } }, - { { "Bsr %s", "SRN.%-2s B" } }, - { { "Csr %s", "SRN.%-2s C" } }, - { { "Dsr %s", "SRN.%-2s D" } }, - { { "A=-A %s", "NEG.%-2s A" } }, - { { "B=-B %s", "NEG.%-2s B" } }, - { { "C=-C %s", "NEG.%-2s C" } }, - { { "D=-D %s", "NEG.%-2s D" } }, - { { "A=-A-1 %s", "NOT.%-2s A" } }, - { { "B=-B-1 %s", "NOT.%-2s B" } }, - { { "C=-C-1 %s", "NOT.%-2s C" } }, - { { "D=-D-1 %s", "NOT.%-2s D" } } - + { "D0=D0+ %x", "ADD.A %x,D0" }, + { "D1=D1+ %x", "ADD.A %x,D1" }, + { "D0=D0- %x", "SUB.A %x,D0" }, + { "D1=D1- %x", "SUB.A %x,D1" }, + + { "A=A+ %s,%x", "ADD.%-2s %x,A" }, + { "B=B+ %s,%x", "ADD.%-2s %x,B" }, + { "C=C+ %s,%x", "ADD.%-2s %x,C" }, + { "D=D+ %s,%x", "ADD.%-2s %x,D" }, + { "A=A- %s,%x", "SUB.%-2s %x,A" }, + { "B=B- %s,%x", "SUB.%-2s %x,B" }, + { "C=C- %s,%x", "SUB.%-2s %x,C" }, + { "D=D- %s,%x", "SUB.%-2s %x,D" }, + + { "A=A&B %s", "AND.%-2s B,A" }, + { "B=B&C %s", "AND.%-2s C,B" }, + { "C=C&A %s", "AND.%-2s A,C" }, + { "D=D&C %s", "AND.%-2s C,D" }, + { "B=B&A %s", "AND.%-2s A,B" }, + { "C=C&B %s", "AND.%-2s B,C" }, + { "A=A&C %s", "AND.%-2s C,A" }, + { "C=C&D %s", "AND.%-2s D,C" }, + + { "A=A!B %s", "OR.%-2s B,A" }, + { "B=B!C %s", "OR.%-2s C,B" }, + { "C=C!A %s", "OR.%-2s A,C" }, + { "D=D!C %s", "OR.%-2s C,D" }, + { "B=B!A %s", "OR.%-2s A,B" }, + { "C=C!B %s", "OR.%-2s B,C" }, + { "A=A!C %s", "OR.%-2s C,A" }, + { "C=C!D %s", "OR.%-2s D,C" }, + + { "Asrb %s", "SRB.%-2s A" }, + { "Bsrb %s", "SRB.%-2s B" }, + { "Csrb %s", "SRB.%-2s C" }, + { "Dsrb %s", "SRB.%-2s D" }, + + { "Aslc %s", "RLN.%-2s A" }, + { "Bslc %s", "RLN.%-2s B" }, + { "Cslc %s", "RLN.%-2s C" }, + { "Dslc %s", "RLN.%-2s D" }, + { "Asrc %s", "RRN.%-2s A" }, + { "Bsrc %s", "RRN.%-2s B" }, + { "Csrc %s", "RRN.%-2s C" }, + { "Dsrc %s", "RRN.%-2s D" }, + + { "A=A+B %s", "ADD.%-2s B,A" }, + { "B=B+C %s", "ADD.%-2s C,B" }, + { "C=C+A %s", "ADD.%-2s A,C" }, + { "D=D+C %s", "ADD.%-2s C,D" }, + { "A=A+A %s", "ADD.%-2s A,A" }, + { "B=B+B %s", "ADD.%-2s B,B" }, + { "C=C+C %s", "ADD.%-2s C,C" }, + { "D=D+C %s", "ADD.%-2s D,D" }, + { "B=B+A %s", "ADD.%-2s A,B" }, + { "C=C+B %s", "ADD.%-2s B,C" }, + { "A=A+C %s", "ADD.%-2s C,A" }, + { "C=C+D %s", "ADD.%-2s D,C" }, + { "A=A-1 %s", "DEC.%-2s A" }, + { "B=B-1 %s", "DEC.%-2s B" }, + { "C=C-1 %s", "DEC.%-2s C" }, + { "D=D-1 %s", "DEC.%-2s D" }, + + { "A=A-B %s", "ADD.%-2s B,A" }, + { "B=B-C %s", "ADD.%-2s C,B" }, + { "C=C-A %s", "ADD.%-2s A,C" }, + { "D=D-C %s", "ADD.%-2s C,D" }, + { "A=A+1 %s", "INC.%-2s A" }, + { "B=B+1 %s", "INC.%-2s B" }, + { "C=C+1 %s", "INC.%-2s C" }, + { "D=D+1 %s", "INC.%-2s D" }, + { "B=B-A %s", "SUB.%-2s A,B" }, + { "C=C-B %s", "SUB.%-2s B,C" }, + { "A=A-C %s", "SUB.%-2s C,A" }, + { "C=C-D %s", "SUB.%-2s D,C" }, + { "A=B-A %s", "SUBN.%-2s B,A" }, + { "B=C-B %s", "SUBN.%-2s C,B" }, + { "C=A-C %s", "SUBN.%-2s A,C" }, + { "D=C-D %s", "SUBN.%-2s C,D" }, + + { "A=0 %s", "CLR.%-2s A" }, + { "B=0 %s", "CLR.%-2s B" }, + { "C=0 %s", "CLR.%-2s C" }, + { "D=0 %s", "CLR.%-2s D" }, + { "A=B %s", "MOVE.%-2s B,A" }, + { "B=C %s", "MOVE.%-2s C,B" }, + { "C=A %s", "MOVE.%-2s A,C" }, + { "D=C %s", "MOVE.%-2s C,D" }, + { "B=A %s", "MOVE.%-2s A,B" }, + { "C=B %s", "MOVE.%-2s B,C" }, + { "A=C %s", "MOVE.%-2s C,A" }, + { "C=D %s", "MOVE.%-2s D,C" }, + { "ABex %s", "SWAP.%-2s A,B" }, + { "BCex %s", "SWAP.%-2s B,C" }, + { "ACex %s", "SWAP.%-2s A,C" }, + { "CDex %s", "SWAP.%-2s C,D" }, + + { "Asl %s", "SLN.%-2s A" }, + { "Bsl %s", "SLN.%-2s B" }, + { "Csl %s", "SLN.%-2s C" }, + { "Dsl %s", "SLN.%-2s D" }, + { "Asr %s", "SRN.%-2s A" }, + { "Bsr %s", "SRN.%-2s B" }, + { "Csr %s", "SRN.%-2s C" }, + { "Dsr %s", "SRN.%-2s D" }, + { "A=-A %s", "NEG.%-2s A" }, + { "B=-B %s", "NEG.%-2s B" }, + { "C=-C %s", "NEG.%-2s C" }, + { "D=-D %s", "NEG.%-2s D" }, + { "A=-A-1 %s", "NOT.%-2s A" }, + { "B=-B-1 %s", "NOT.%-2s B" }, + { "C=-C-1 %s", "NOT.%-2s C" }, + { "D=-D-1 %s", "NOT.%-2s D" } }; -enum opcode_sel -{ - Complete=-1, - Illegal, - Opcode0, Opcode0E, Opcode0Ea, - Opcode1, Opcode10, Opcode11, Opcode12, Opcode13, Opcode14, Opcode15, - Opcode8, Opcode80, Opcode808, Opcode8081, - Opcode81, Opcode818, Opcode818a, Opcode819, Opcode819a, - Opcode81A, Opcode81Aa, Opcode81Aa0,Opcode81Aa1, Opcode81Aa2, Opcode81B, - Opcode8A, Opcode8B, - Opcode9, Opcode9a, Opcode9b, - OpcodeA, OpcodeAa, OpcodeAb, - OpcodeB, OpcodeBa, OpcodeBb, - OpcodeC, - OpcodeD, - OpcodeE, - OpcodeF -}; - -enum opcode_adr -{ - AdrNone, - AdrAF, AdrA, AdrB, AdrCount, - BranchReturn, TestBranchRet, ImmBranch, - ABranchReturn, // address field A - xBranchReturn, // address field specified in previous opcode entry - Imm, ImmCount, ImmCload, Imm2, Imm4, Imm5, - Dis3, Dis3Call, Dis4, Dis4Call, Abs, - FieldP, FieldWP, FieldXS, FieldX, FieldS, FieldM, FieldB, FieldW, FieldA, - AdrImmCount -}; -struct OPCODE -{ - opcode_sel sel; - opcode_adr adr; - MNEMONICS mnemonic; -}; -static const char *field_2_string(int adr_enum) +const char *saturn_disassembler::field_2_string(int adr_enum) { switch (adr_enum) { case FieldP: return P; @@ -593,7 +412,7 @@ static const char *field_2_string(int adr_enum) return nullptr; } -static const OPCODE opcodes[][0x10]= { +const saturn_disassembler::OPCODE saturn_disassembler::opcs[][0x10]= { { // first digit { Opcode0 }, @@ -805,7 +624,7 @@ static const OPCODE opcodes[][0x10]= { { Complete, AdrNone, inA }, { Complete, AdrNone, inC }, { Complete, AdrNone, unconfig }, - { Complete, AdrNone, config }, + { Complete, AdrNone, xconfig }, { Complete, AdrNone, Cid }, { Complete, AdrNone, shutdown }, { Opcode808 }, @@ -1258,31 +1077,42 @@ static const OPCODE opcodes[][0x10]= { } }; -static const int field_adr_af[]= +const int saturn_disassembler::field_adr_af[]= { FieldP, FieldWP, FieldXS, FieldX, FieldS, FieldM, FieldB, FieldW, 0, 0, 0, 0, 0, 0, 0, FieldA }; -static const int field_adr_a[]= +const int saturn_disassembler::field_adr_a[]= { FieldP, FieldWP, FieldXS, FieldX, FieldS, FieldM, FieldB, FieldW}; -static const int field_adr_b[]= +const int saturn_disassembler::field_adr_b[]= { FieldP, FieldWP, FieldXS, FieldX, FieldS, FieldM, FieldB, FieldW }; -CPU_DISASSEMBLE(saturn) +saturn_disassembler::saturn_disassembler(config *conf) : m_config(conf) +{ +} + +u32 saturn_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t saturn_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { int adr=0; int cont=1; // operation still not complete disassembled char bin[10]; int binsize=0; // protocollizing fetched nibbles char number[17]; - const OPCODE *level=opcodes[0]; //pointer to current digit + const OPCODE *level=opcs[0]; //pointer to current digit int op; // currently fetched nibble - int pos = 0; + offs_t pos = pc; int i,c,v; + int mnemonics_bank = m_config->get_nonstandard_mnemonics_mode() ? 1 : 0; + while (cont) { - op = oprom[pos++] & 0xf; + op = opcodes.r8(pos++) & 0xf; level+=op; switch (level->sel) { case Illegal: @@ -1316,155 +1146,155 @@ CPU_DISASSEMBLE(saturn) cont=0; switch (level->adr==AdrNone?adr:level->adr) { case AdrNone: - stream << mnemonics[level->mnemonic].name[set]; + stream << mnemonics[level->mnemonic][mnemonics_bank]; break; case Imm: - util::stream_format(stream, mnemonics[level->mnemonic].name[set], oprom[pos++]); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], opcodes.r8(pos++)); break; case ImmCount: - util::stream_format(stream, mnemonics[level->mnemonic].name[set], oprom[pos++]+1); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], opcodes.r8(pos++)+1); break; case AdrImmCount: - util::stream_format(stream, mnemonics[level->mnemonic].name[set], field_2_string(adr), oprom[pos++]+1); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], field_2_string(adr), opcodes.r8(pos++)+1); break; case AdrCount: // mnemonics have string %s for address field - snprintf(number,sizeof(number),"%x",oprom[pos++]+1); - util::stream_format(stream, mnemonics[level->mnemonic].name[set], number); + snprintf(number,sizeof(number),"%x",opcodes.r8(pos++)+1); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], number); break; case Imm2: - v=oprom[pos++]; - v|=oprom[pos++]<<4; - util::stream_format(stream, mnemonics[level->mnemonic].name[set], v); + v=opcodes.r8(pos++); + v|=opcodes.r8(pos++)<<4; + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], v); break; case Imm4: - v=oprom[pos++]; - v|=oprom[pos++]<<4; - v|=oprom[pos++]<<8; - v|=oprom[pos++]<<12; - util::stream_format(stream, mnemonics[level->mnemonic].name[set], v); + v=opcodes.r8(pos++); + v|=opcodes.r8(pos++)<<4; + v|=opcodes.r8(pos++)<<8; + v|=opcodes.r8(pos++)<<12; + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], v); break; case Imm5: - v=oprom[pos++]; - v|=oprom[pos++]<<4; - v|=oprom[pos++]<<8; - v|=oprom[pos++]<<12; - v|=oprom[pos++]<<16; - util::stream_format(stream, mnemonics[level->mnemonic].name[set], v); + v=opcodes.r8(pos++); + v|=opcodes.r8(pos++)<<4; + v|=opcodes.r8(pos++)<<8; + v|=opcodes.r8(pos++)<<12; + v|=opcodes.r8(pos++)<<16; + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], v); break; case ImmCload: - c=i=oprom[pos++] & 0xf; + c=i=opcodes.r8(pos++) & 0xf; number[i+1]=0; - for (;i>=0; i--) number[i]=number_2_hex[oprom[pos++] & 0xf]; - util::stream_format(stream, mnemonics[level->mnemonic].name[set], c+1, number); + for (;i>=0; i--) number[i]=number_2_hex[opcodes.r8(pos++) & 0xf]; + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], c+1, number); break; case Dis3: SATURN_PEEKOP_DIS12(v); c=(pc+pos-3+v)&0xfffff; - util::stream_format(stream, mnemonics[level->mnemonic].name[set], c ); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], c ); break; case Dis3Call: SATURN_PEEKOP_DIS12(v); c=(pc+pos+v)&0xfffff; - util::stream_format(stream, mnemonics[level->mnemonic].name[set], c ); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], c ); break; case Dis4: SATURN_PEEKOP_DIS16(v); c=(pc+pos-4+v)&0xfffff; - util::stream_format(stream, mnemonics[level->mnemonic].name[set], c ); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], c ); break; case Dis4Call: SATURN_PEEKOP_DIS16(v); c=(pc+pos+v)&0xfffff; - util::stream_format(stream, mnemonics[level->mnemonic].name[set], c ); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], c ); break; case Abs: SATURN_PEEKOP_ADR(v); - util::stream_format(stream, mnemonics[level->mnemonic].name[set], v ); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], v ); break; case BranchReturn: SATURN_PEEKOP_DIS8(v); if (v==0) { - stream << mnemonics[level->mnemonic+1].name[set]; + stream << mnemonics[level->mnemonic+1][mnemonics_bank]; } else { c=(pc+pos-2+v)&0xfffff; - util::stream_format(stream, mnemonics[level->mnemonic].name[set], c); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], c); } break; case ABranchReturn: SATURN_PEEKOP_DIS8(v); if (v==0) { - util::stream_format(stream, mnemonics[level->mnemonic+1].name[set], A); + util::stream_format(stream, mnemonics[level->mnemonic+1][mnemonics_bank], A); } else { c=(pc+pos-2+v)&0xfffff; - util::stream_format(stream, mnemonics[level->mnemonic].name[set], A, c); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], A, c); } break; case xBranchReturn: SATURN_PEEKOP_DIS8(v); if (v==0) { - util::stream_format(stream, mnemonics[level->mnemonic+1].name[set], field_2_string(adr)); + util::stream_format(stream, mnemonics[level->mnemonic+1][mnemonics_bank], field_2_string(adr)); } else { c=(pc+pos-2+v)&0xfffff; - util::stream_format(stream, mnemonics[level->mnemonic].name[set], field_2_string(adr), c); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], field_2_string(adr), c); } break; case TestBranchRet: - i=oprom[pos++]; + i=opcodes.r8(pos++); SATURN_PEEKOP_DIS8(v); if (v==0) { - util::stream_format(stream, mnemonics[level->mnemonic+1].name[set], i); + util::stream_format(stream, mnemonics[level->mnemonic+1][mnemonics_bank], i); } else { c=(pc+pos-2+v)&0xfffff; - util::stream_format(stream, mnemonics[level->mnemonic].name[set], i, c); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], i, c); } break; case ImmBranch: - i=oprom[pos++]; + i=opcodes.r8(pos++); SATURN_PEEKOP_DIS8(v); c=(pc+pos-2+v)&0xfffff; - util::stream_format(stream, mnemonics[level->mnemonic].name[set], i, c); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], i, c); break; case FieldP: - util::stream_format(stream, mnemonics[level->mnemonic].name[set], P ); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], P ); break; case FieldWP: - util::stream_format(stream, mnemonics[level->mnemonic].name[set], WP ); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], WP ); break; case FieldXS: - util::stream_format(stream, mnemonics[level->mnemonic].name[set], XS ); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], XS ); break; case FieldX: - util::stream_format(stream, mnemonics[level->mnemonic].name[set], X ); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], X ); break; case FieldS: - util::stream_format(stream, mnemonics[level->mnemonic].name[set], S ); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], S ); break; case FieldM: - util::stream_format(stream, mnemonics[level->mnemonic].name[set], M ); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], M ); break; case FieldB: - util::stream_format(stream, mnemonics[level->mnemonic].name[set], B ); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], B ); break; case FieldA: - util::stream_format(stream, mnemonics[level->mnemonic].name[set], A ); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], A ); break; case FieldW: - util::stream_format(stream, mnemonics[level->mnemonic].name[set], W ); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], W ); break; case AdrA: - util::stream_format(stream, mnemonics[level->mnemonic].name[set], adr_a[oprom[pos++] & 0x7] ); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], adr_a[opcodes.r8(pos++) & 0x7] ); break; case AdrAF: - util::stream_format(stream, mnemonics[level->mnemonic].name[set], adr_af[oprom[pos++] & 0xf] ); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], adr_af[opcodes.r8(pos++) & 0xf] ); break; case AdrB: - util::stream_format(stream, mnemonics[level->mnemonic].name[set], adr_b[oprom[pos++] & 0x7] ); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], adr_b[opcodes.r8(pos++) & 0x7] ); break; } break; } - level = opcodes[level->sel]; + level = opcs[level->sel]; } - return pos; + return pos - pc; } diff --git a/src/devices/cpu/saturn/saturnds.h b/src/devices/cpu/saturn/saturnds.h new file mode 100644 index 00000000000..676f59ff290 --- /dev/null +++ b/src/devices/cpu/saturn/saturnds.h @@ -0,0 +1,215 @@ +// license:BSD-3-Clause +// copyright-holders:Peter Trauner,Antoine Mine +/***************************************************************************** + * + * saturnds.c + * portable saturn emulator interface + * (hp calculators) + * + *****************************************************************************/ + +#ifndef MAME_CPU_SATURN_SATURNDS_H +#define MAME_CPU_SATURN_SATURNDS_H + +#pragma once + +class saturn_disassembler : public util::disasm_interface +{ +public: + struct config { + virtual ~config() = default; + virtual bool get_nonstandard_mnemonics_mode() const = 0; + }; + + saturn_disassembler(config *conf); + virtual ~saturn_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + // don't split branch and return, source relies on this ordering + enum MNEMONICS + { + Return, ReturnSetXM, ReturnSetCarry, ReturnClearCarry, ReturnFromInterrupt, + jump3,jump4,jump, + call3,call4,call, + branchCarrySet, returnCarrySet, + branchCarryClear, returnCarryClear, + + outCS, outC, inA, inC, + unconfig, xconfig, Cid, shutdown, cp1, reset, buscc, + CcopyP, PcopyC, sreq, CswapP, + + inton, AloadImm, buscb, + clearAbit, setAbit, + branchAbitclear, returnAbitclear, + branchAbitset, returnAbitset, + clearCbit, setCbit, + branchCbitclear, returnCbitclear, + branchCbitset, returnCbitset, + PCloadA, buscd, PCloadC, intoff, rsi, + + jumpA, jumpC, PCcopyA, PCcopyC, AcopyPC, CcopyPC, + + clearHST, + branchHSTclear, returnHSTclear, + + clearBitST, setBitST, + branchSTclear, returnSTclear, + branchSTset, returnSTset, + + branchPdiffers, returnPdiffers, + branchPequals, returnPequals, + + branchAequalsB, returnAequalsB, + branchBequalsC, returnBequalsC, + branchAequalsC, returnAequalsC, + branchCequalsD, returnCequalsD, + branchAdiffersB, returnAdiffersB, + branchBdiffersC, returnBdiffersC, + branchAdiffersC, returnAdiffersC, + branchCdiffersD, returnCdiffersD, + branchAzero, returnAzero, + branchBzero, returnBzero, + branchCzero, returnCzero, + branchDzero, returnDzero, + branchAnotzero, returnAnotzero, + branchBnotzero, returnBnotzero, + branchCnotzero, returnCnotzero, + branchDnotzero, returnDnotzero, + + branchAgreaterB, returnAgreaterB, + branchBgreaterC, returnBgreaterC, + branchCgreaterA, returnCgreaterA, + branchDgreaterC, returnDgreaterC, + branchAlowerB, returnAlowerB, + branchBlowerC, returnBlowerC, + branchClowerA, returnClowerA, + branchDlowerC, returnDlowerC, + branchAnotlowerB, returnAnotlowerB, + branchBnotlowerC, returnBnotlowerC, + branchCnotlowerA, returnCnotlowerA, + branchDnotlowerC, returnDnotlowerC, + branchAnotgreaterB, returnAnotgreaterB, + branchBnotgreaterC, returnBnotgreaterC, + branchCnotgreaterA, returnCnotgreaterA, + branchDnotgreaterC, returnDnotgreaterC, + + SetHexMode, SetDecMode, + PushC, PopC, + + D0loadImm2, D0loadImm4, D0loadImm5, + D1loadImm2, D1loadImm4, D1loadImm5, + PloadImm, CloadImm, + + clearST, + CcopyST, STcopyC, + swapCST, + + incP, decP, + + R0copyA, R1copyA, R2copyA, R3copyA, R4copyA, + R0copyC, R1copyC, R2copyC, R3copyC, R4copyC, + + AcopyR0, AcopyR1, AcopyR2, AcopyR3, AcopyR4, + CcopyR0, CcopyR1, CcopyR2, CcopyR3, CcopyR4, + + D0copyA, D1copyA, D0copyC, D1copyC, + D0copyAShort, D1copyAShort, D0copyCShort, D1copyCShort, // other class mnemonic + + SwapAR0, SwapAR1, SwapAR2, SwapAR3, SwapAR4, + SwapCR0, SwapCR1, SwapCR2, SwapCR3, SwapCR4, + + SwapAD0, SwapAD1, SwapCD0, SwapCD1, + SwapAD0Short, SwapAD1Short, SwapCD0Short, SwapCD1Short, // other class mnemonic + + D0storeA, D1storeA, D0storeC, D1storeC, + AloadD0, AloadD1, CloadD0, CloadD1, + + D0addImm, D1addImm, D0subImm, D1subImm, + AaddImm, BaddImm, CaddImm, DaddImm, + AsubImm, BsubImm, CsubImm, DsubImm, + + AandB, BandC, CandA, DandC, BandA, CandB, AandC, CandD, + AorB, BorC, CorA, DorC, BorA, CorB, AorC, CorD, + + Ashiftrightbit, Bshiftrightbit, Cshiftrightbit, Dshiftrightbit, + + AshiftleftCarry, BshiftleftCarry, CshiftleftCarry, DshiftleftCarry, + AshiftrightCarry, BshiftrightCarry, CshiftrightCarry, DshiftrightCarry, + + AaddB, BaddC, CaddA, DaddC, AaddA, BaddB, CaddC, DaddD, + BaddA, CaddB, AaddC, CaddD, decA, decB, decC, decD, + + AsubB, BsubC, CsubA, DsubC, incA, incB, incC, incD, + BsubA, CsubB, AsubC, CsubD, AsubnB, BsubnC, CsubnA, DsubnC, + + clearA, clearB, clearC, clearD, + AcopyB, BcopyC, CcopyA, DcopyC, BcopyA, CcopyB, AcopyC, CcopyD, + AswapB, BswapC, CswapA, DswapC, + + Ashiftleft, Bshiftleft, Cshiftleft, Dshiftleft, + Ashiftright, Bshiftright, Cshiftright, Dshiftright, + negateA, negateB, negateC, negateD, + notA, notB, notC, notD + }; + + enum opcode_sel + { + Complete=-1, + Illegal, + Opcode0, Opcode0E, Opcode0Ea, + Opcode1, Opcode10, Opcode11, Opcode12, Opcode13, Opcode14, Opcode15, + Opcode8, Opcode80, Opcode808, Opcode8081, + Opcode81, Opcode818, Opcode818a, Opcode819, Opcode819a, + Opcode81A, Opcode81Aa, Opcode81Aa0,Opcode81Aa1, Opcode81Aa2, Opcode81B, + Opcode8A, Opcode8B, + Opcode9, Opcode9a, Opcode9b, + OpcodeA, OpcodeAa, OpcodeAb, + OpcodeB, OpcodeBa, OpcodeBb, + OpcodeC, + OpcodeD, + OpcodeE, + OpcodeF + }; + + enum opcode_adr + { + AdrNone, + AdrAF, AdrA, AdrB, AdrCount, + BranchReturn, TestBranchRet, ImmBranch, + ABranchReturn, // address field A + xBranchReturn, // address field specified in previous opcode entry + Imm, ImmCount, ImmCload, Imm2, Imm4, Imm5, + Dis3, Dis3Call, Dis4, Dis4Call, Abs, + FieldP, FieldWP, FieldXS, FieldX, FieldS, FieldM, FieldB, FieldW, FieldA, + AdrImmCount + }; + + struct OPCODE + { + opcode_sel sel; + opcode_adr adr; + MNEMONICS mnemonic; + }; + + config *m_config; + + static const char *const adr_b[]; + static const char *const adr_af[]; + static const char *const adr_a[]; + static const char number_2_hex[]; + + static const char *const mnemonics[][2]; + static const OPCODE opcs[][0x10]; + + static const int field_adr_af[]; + static const int field_adr_a[]; + static const int field_adr_b[]; + + const char *field_2_string(int adr_enum); + +}; + +#endif diff --git a/src/devices/cpu/sc61860/sc61860.cpp b/src/devices/cpu/sc61860/sc61860.cpp index a4f82ccdedc..7277cbc444c 100644 --- a/src/devices/cpu/sc61860/sc61860.cpp +++ b/src/devices/cpu/sc61860/sc61860.cpp @@ -19,7 +19,7 @@ #include "emu.h" #include "sc61860.h" - +#include "scdasm.h" #include "debugger.h" @@ -69,11 +69,9 @@ device_memory_interface::space_config_vector sc61860_device::memory_space_config }; } - -offs_t sc61860_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *sc61860_device::create_disassembler() { - extern CPU_DISASSEMBLE( sc61860 ); - return CPU_DISASSEMBLE_NAME(sc61860)(this, stream, pc, oprom, opram, options); + return new sc61860_disassembler; } @@ -112,7 +110,7 @@ void sc61860_device::device_start() m_2ms_tick_timer->adjust(attotime::from_hz(500), 0, attotime::from_hz(500)); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_reset.resolve(); m_brk.resolve(); m_x.resolve(); diff --git a/src/devices/cpu/sc61860/sc61860.h b/src/devices/cpu/sc61860/sc61860.h index de7653b73be..3b9e6745e4d 100644 --- a/src/devices/cpu/sc61860/sc61860.h +++ b/src/devices/cpu/sc61860/sc61860.h @@ -109,9 +109,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 4; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -137,7 +135,7 @@ private: emu_timer *m_2ms_tick_timer; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; int m_icount; uint8_t m_ram[0x100]; // internal special ram, should be 0x60, 0x100 to avoid memory corruption for now diff --git a/src/devices/cpu/sc61860/scdasm.cpp b/src/devices/cpu/sc61860/scdasm.cpp index 050dfaa3b1d..8b14a920d62 100644 --- a/src/devices/cpu/sc61860/scdasm.cpp +++ b/src/devices/cpu/sc61860/scdasm.cpp @@ -11,9 +11,7 @@ *****************************************************************************/ #include "emu.h" -#include "debugger.h" - -#include "sc61860.h" +#include "scdasm.h" /* new: @@ -67,21 +65,7 @@ ex exchange */ - -enum Adr -{ - Ill, - Imp, - Imm, ImmW, - RelP, RelM, - Abs, - Ptc, - Etc, - Cal, - Lp -}; - -static const struct { const char *mnemonic; Adr adr; } table[]={ +const sc61860_disassembler::opcode sc61860_disassembler::table[]={ { "LII", Imm }, { "LIJ", Imm }, { "LIA", Imm }, { "LIB", Imm }, { "IX", Imp }, { "DX", Imp }, { "IY", Imp }, { "DY", Imp }, { "MVW", Imp }, { "EXW", Imp }, { "MVB", Imp }, { "EXB", Imp }, @@ -152,10 +136,15 @@ static const struct { const char *mnemonic; Adr adr; } table[]={ { nullptr }, { nullptr }, { nullptr }, { nullptr }, { nullptr }, { nullptr }, { nullptr }, { nullptr }, }; -CPU_DISASSEMBLE(sc61860) +u32 sc61860_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t sc61860_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - const uint8_t *base_oprom = oprom; - int oper=*(oprom++); + offs_t pos = pc; + int oper=opcodes.r8(pos++); int t; uint16_t adr; @@ -167,32 +156,32 @@ CPU_DISASSEMBLE(sc61860) switch(oper&0xe0) { case 0xe0: util::stream_format(stream,"%-6s%04x",table[oper&0xe0].mnemonic, - *(oprom++)|((oper&0x1f)<<8)); + opcodes.r8(pos++)|((oper&0x1f)<<8)); break; default: switch (table[oper].adr) { case Ill: util::stream_format(stream,"?%02x",oper);break; case Imp: util::stream_format(stream,"%s",table[oper].mnemonic); break; - case Imm: util::stream_format(stream,"%-6s%02x",table[oper].mnemonic, *(oprom++)); break; + case Imm: util::stream_format(stream,"%-6s%02x",table[oper].mnemonic, opcodes.r8(pos++)); break; case ImmW: - adr=(oprom[0]<<8)|oprom[1];oprom+=2; + adr=opcodes.r16(pos); pos+=2; util::stream_format(stream,"%-6s%04x",table[oper].mnemonic, adr); break; case Abs: - adr=(oprom[0]<<8)|oprom[1];oprom+=2; + adr=opcodes.r16(pos); pos+=2; util::stream_format(stream,"%-6s%04x",table[oper].mnemonic, adr); break; case RelM: - adr=pc-*(oprom++); + adr=pc-opcodes.r8(pos++); util::stream_format(stream,"%-6s%04x",table[oper].mnemonic, adr&0xffff); break; case RelP: - adr=pc+*(oprom++); + adr=pc+opcodes.r8(pos++); util::stream_format(stream,"%-6s%04x",table[oper].mnemonic, adr&0xffff); break; case Ptc: - t=*(oprom++); - adr=(oprom[0]<<8)|oprom[1];oprom+=2; + t=opcodes.r8(pos++); + adr=opcodes.r16(pos); pos+=2; util::stream_format(stream,"%-6s%02x,%04x",table[oper].mnemonic,t, adr); break; case Etc: @@ -206,5 +195,5 @@ CPU_DISASSEMBLE(sc61860) } break; } - return oprom - base_oprom; + return pos - pc; } diff --git a/src/devices/cpu/sc61860/scdasm.h b/src/devices/cpu/sc61860/scdasm.h new file mode 100644 index 00000000000..575106ac2c8 --- /dev/null +++ b/src/devices/cpu/sc61860/scdasm.h @@ -0,0 +1,50 @@ +// license:BSD-3-Clause +// copyright-holders:Peter Trauner +/***************************************************************************** + * + * scdasm.c + * portable sharp 61860 emulator interface + * (sharp pocket computers) + * + * Copyright Peter Trauner, all rights reserved. + * + *****************************************************************************/ + +#ifndef MAME_CPU_SC61860_SCDASM_H +#define MAME_CPU_SC61860_SCDASM_H + +#pragma once + +class sc61860_disassembler : public util::disasm_interface +{ +public: + sc61860_disassembler() = default; + virtual ~sc61860_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum Adr + { + Ill, + Imp, + Imm, ImmW, + RelP, RelM, + Abs, + Ptc, + Etc, + Cal, + Lp + }; + + struct opcode { + const char *mnemonic; + Adr adr; + }; + + static const opcode table[]; + +}; + +#endif diff --git a/src/devices/cpu/scmp/scmp.cpp b/src/devices/cpu/scmp/scmp.cpp index 94bcb3fcf6c..f85ca4d1ba5 100644 --- a/src/devices/cpu/scmp/scmp.cpp +++ b/src/devices/cpu/scmp/scmp.cpp @@ -10,6 +10,7 @@ #include "emu.h" #include "scmp.h" +#include "scmpdasm.h" #include "debugger.h" @@ -54,10 +55,9 @@ ins8060_device::ins8060_device(const machine_config &mconfig, const char *tag, d } -offs_t scmp_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *scmp_device::create_disassembler() { - extern CPU_DISASSEMBLE( scmp ); - return CPU_DISASSEMBLE_NAME(scmp)(this, stream, pc, oprom, opram, options); + return new scmp_disassembler; } @@ -502,7 +502,7 @@ void scmp_device::device_start() } m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); /* resolve callbacks */ m_flag_out_func.resolve_safe(); diff --git a/src/devices/cpu/scmp/scmp.h b/src/devices/cpu/scmp/scmp.h index 553af2dad0f..1ca7c699af5 100644 --- a/src/devices/cpu/scmp/scmp.h +++ b/src/devices/cpu/scmp/scmp.h @@ -54,9 +54,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 2; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -70,7 +68,7 @@ private: uint8_t m_SR; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; int m_icount; devcb_write8 m_flag_out_func; diff --git a/src/devices/cpu/scmp/scmpdasm.cpp b/src/devices/cpu/scmp/scmpdasm.cpp index 2f77afc519d..1a906218a38 100644 --- a/src/devices/cpu/scmp/scmpdasm.cpp +++ b/src/devices/cpu/scmp/scmpdasm.cpp @@ -9,21 +9,24 @@ *****************************************************************************/ #include "emu.h" +#include "scmpdasm.h" -#define OP(A) oprom[(A) - PC] -#define ARG(A) opram[(A) - PC] +u32 scmp_disassembler::opcode_alignment() const +{ + return 1; +} -CPU_DISASSEMBLE(scmp) +offs_t scmp_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { unsigned PC = pc; - uint8_t op = OP(pc++); + uint8_t op = opcodes.r8(pc++); uint8_t ptr = op & 3; if (BIT(op,7)) { // two bytes instructions char as[10]; char aspr[10]; - uint8_t arg = ARG(pc); pc++; + uint8_t arg = params.r8(pc); pc++; if (arg==0x80) { sprintf(as,"E"); } else { diff --git a/src/devices/cpu/scmp/scmpdasm.h b/src/devices/cpu/scmp/scmpdasm.h new file mode 100644 index 00000000000..915f74ee848 --- /dev/null +++ b/src/devices/cpu/scmp/scmpdasm.h @@ -0,0 +1,26 @@ +// license:BSD-3-Clause +// copyright-holders:Miodrag Milanovic +/***************************************************************************** + * + * scmpdasm.c + * + * National Semiconductor SC/MP CPU Disassembly + * + *****************************************************************************/ + +#ifndef MAME_CPU_SCMP_SCMPDASM_H +#define MAME_CPU_SCMP_SCMPDASM_H + +#pragma once + +class scmp_disassembler : public util::disasm_interface +{ +public: + scmp_disassembler() = default; + virtual ~scmp_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/score/score.cpp b/src/devices/cpu/score/score.cpp index f346fd93dc1..7f4eaff51dd 100644 --- a/src/devices/cpu/score/score.cpp +++ b/src/devices/cpu/score/score.cpp @@ -10,6 +10,7 @@ #include "emu.h" #include "debugger.h" #include "score.h" +#include "scoredsm.h" //************************************************************************** @@ -72,7 +73,7 @@ void score7_cpu_device::device_start() { // find address spaces m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); // set our instruction counter m_icountptr = &m_icount; @@ -1348,3 +1349,8 @@ void score7_cpu_device::unemulated_op(const char * op) { fatalerror("%s: unemulated %s (PC=0x%08x)\n", tag(), op, m_ppc); } + +util::disasm_interface *score7_cpu_device::create_disassembler() +{ + return new score7_disassembler; +} diff --git a/src/devices/cpu/score/score.h b/src/devices/cpu/score/score.h index 48d832f3ada..392e2aaa4ac 100644 --- a/src/devices/cpu/score/score.h +++ b/src/devices/cpu/score/score.h @@ -54,9 +54,7 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 4; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: // helpers @@ -73,9 +71,6 @@ private: void check_irq(); void gen_exception(int cause, uint32_t param = 0); - offs_t disasm(std::ostream &stream, offs_t pc, uint32_t opcode); - void disasm32(std::ostream &stream, offs_t pc, uint32_t opcode); - void disasm16(std::ostream &stream, offs_t pc, uint16_t opcode); void unemulated_op(const char * op); // 32-bit opcodes @@ -113,7 +108,7 @@ private: address_space_config m_program_config; address_space * m_program; - direct_read_data * m_direct; + direct_read_data<0> * m_direct; // internal state int m_icount; @@ -130,19 +125,6 @@ private: typedef void (score7_cpu_device::*op_handler)(); static const op_handler s_opcode32_table[4*8]; static const op_handler s_opcode16_table[8]; - - // mnemonics - static const char *const m_cond[16]; - static const char *const m_tcs[4]; - static const char *const m_rix1_op[8]; - static const char *const m_rix2_op[8]; - static const char *const m_r2_op[16]; - static const char *const m_i1_op[8]; - static const char *const m_i2_op[8]; - static const char *const m_ls_op[8]; - static const char *const m_i1a_op[8]; - static const char *const m_i1b_op[8]; - static const char *const m_cr_op[2]; }; DECLARE_DEVICE_TYPE(SCORE7, score7_cpu_device) diff --git a/src/devices/cpu/score/scoredsm.cpp b/src/devices/cpu/score/scoredsm.cpp index d4b5ddbf78a..5e5b6b4e8ac 100644 --- a/src/devices/cpu/score/scoredsm.cpp +++ b/src/devices/cpu/score/scoredsm.cpp @@ -7,23 +7,29 @@ ******************************************************************************/ #include "emu.h" -#include "score.h" +#include "scoredsm.h" #include "scorem.h" -const char *const score7_cpu_device::m_cond[16] = { "cs", "cc", "gtu", "leu", "eq", "ne", "gt", "le", "ge", "lt", "mi", "pl", "vs", "vc", "cnz", "" }; -const char *const score7_cpu_device::m_tcs[4] = { "teq", "tmi", "", ""}; -const char *const score7_cpu_device::m_rix1_op[8] = { "lw" ,"lh" ,"lhu" ,"lb" ,"sw" ,"sh" ,"lbu" ,"sb" }; -const char *const score7_cpu_device::m_rix2_op[8] = { "lw", "lh", "lhu", "lb", "sw", "sh", "lbu", "sb" }; -const char *const score7_cpu_device::m_r2_op[16] = { "add", "sub", "neg", "cmp", "and", "or", "not", "xor", "lw", "lh", "pop", "lbu", "sw", "sh", "push", "sb" }; -const char *const score7_cpu_device::m_i1_op[8] = { "addi", "", "cmpi", "", "andi", "ori", "ldi", "" }; -const char *const score7_cpu_device::m_i2_op[8] = { "addis", "", "cmpis", "", "andis", "oris", "ldis", "" }; -const char *const score7_cpu_device::m_ls_op[8] = { "lw", "lh", "lhu", "lb", "sw", "sh", "lbu", "sb" }; -const char *const score7_cpu_device::m_i1a_op[8] = { "addei", "slli", "sdbbp", "srli", "bitclr", "bitset", "bittst", "" }; -const char *const score7_cpu_device::m_i1b_op[8] = { "lwp", "lhp", "", "lbup", "swp", "shp", "", "sbp" }; -const char *const score7_cpu_device::m_cr_op[2] = { "mtcr", "mfcr" }; +const char *const score7_disassembler::m_cond[16] = { "cs", "cc", "gtu", "leu", "eq", "ne", "gt", "le", "ge", "lt", "mi", "pl", "vs", "vc", "cnz", "" }; +const char *const score7_disassembler::m_tcs[4] = { "teq", "tmi", "", ""}; +const char *const score7_disassembler::m_rix1_op[8] = { "lw" ,"lh" ,"lhu" ,"lb" ,"sw" ,"sh" ,"lbu" ,"sb" }; +const char *const score7_disassembler::m_rix2_op[8] = { "lw", "lh", "lhu", "lb", "sw", "sh", "lbu", "sb" }; +const char *const score7_disassembler::m_r2_op[16] = { "add", "sub", "neg", "cmp", "and", "or", "not", "xor", "lw", "lh", "pop", "lbu", "sw", "sh", "push", "sb" }; +const char *const score7_disassembler::m_i1_op[8] = { "addi", "", "cmpi", "", "andi", "ori", "ldi", "" }; +const char *const score7_disassembler::m_i2_op[8] = { "addis", "", "cmpis", "", "andis", "oris", "ldis", "" }; +const char *const score7_disassembler::m_ls_op[8] = { "lw", "lh", "lhu", "lb", "sw", "sh", "lbu", "sb" }; +const char *const score7_disassembler::m_i1a_op[8] = { "addei", "slli", "sdbbp", "srli", "bitclr", "bitset", "bittst", "" }; +const char *const score7_disassembler::m_i1b_op[8] = { "lwp", "lhp", "", "lbup", "swp", "shp", "", "sbp" }; +const char *const score7_disassembler::m_cr_op[2] = { "mtcr", "mfcr" }; +int32_t score7_disassembler::sign_extend(uint32_t data, uint8_t len) +{ + data &= (1 << len) - 1; + uint32_t sign = 1 << (len - 1); + return (data ^ sign) - sign; +} -void score7_cpu_device::disasm32(std::ostream &stream, offs_t pc, uint32_t opcode) +void score7_disassembler::disasm32(std::ostream &stream, offs_t pc, uint32_t opcode) { switch((opcode >> 25) & 0x1f) { @@ -178,7 +184,7 @@ void score7_cpu_device::disasm32(std::ostream &stream, offs_t pc, uint32_t opcod } } -void score7_cpu_device::disasm16(std::ostream &stream, offs_t pc, uint16_t opcode) +void score7_disassembler::disasm16(std::ostream &stream, offs_t pc, uint16_t opcode) { switch((opcode >> 12) & 0x07) { @@ -252,7 +258,7 @@ void score7_cpu_device::disasm16(std::ostream &stream, offs_t pc, uint16_t opcod } } -offs_t score7_cpu_device::disasm(std::ostream &stream, offs_t pc, uint32_t opcode) +offs_t score7_disassembler::disasm(std::ostream &stream, offs_t pc, uint32_t opcode) { uint8_t p = (pc & 0x02) ? 0 : (((opcode>>30) & 2) | ((opcode>>15) & 1)); @@ -278,13 +284,16 @@ offs_t score7_cpu_device::disasm(std::ostream &stream, offs_t pc, uint32_t opcod //------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t score7_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +offs_t score7_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - uint32_t opcode = oprom[0] | (oprom[1] << 8) | (oprom[2] << 16) | (oprom[3] << 24); + return disasm(stream, pc, opcodes.r32(pc)); +} - return disasm(stream, pc, opcode); +u32 score7_disassembler::opcode_alignment() const +{ + return 2; } diff --git a/src/devices/cpu/score/scoredsm.h b/src/devices/cpu/score/scoredsm.h new file mode 100644 index 00000000000..a9f870d2b42 --- /dev/null +++ b/src/devices/cpu/score/scoredsm.h @@ -0,0 +1,43 @@ +// license:BSD-3-Clause +// copyright-holders:Sandro Ronco +/****************************************************************************** + + Sunplus Technology S+core disassembler + +******************************************************************************/ + +#ifndef MAME_CPU_SCORE_SCOREDSM_H +#define MAME_CPU_SCORE_SCOREDSM_H + +#pragma once + +class score7_disassembler : public util::disasm_interface +{ +public: + score7_disassembler() = default; + virtual ~score7_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + // mnemonics + static const char *const m_cond[16]; + static const char *const m_tcs[4]; + static const char *const m_rix1_op[8]; + static const char *const m_rix2_op[8]; + static const char *const m_r2_op[16]; + static const char *const m_i1_op[8]; + static const char *const m_i2_op[8]; + static const char *const m_ls_op[8]; + static const char *const m_i1a_op[8]; + static const char *const m_i1b_op[8]; + static const char *const m_cr_op[2]; + + int32_t sign_extend(uint32_t data, uint8_t len); + offs_t disasm(std::ostream &stream, offs_t pc, uint32_t opcode); + void disasm32(std::ostream &stream, offs_t pc, uint32_t opcode); + void disasm16(std::ostream &stream, offs_t pc, uint16_t opcode); +}; + +#endif diff --git a/src/devices/cpu/scudsp/scudsp.cpp b/src/devices/cpu/scudsp/scudsp.cpp index e9a55e3df0f..b61c4aedf6d 100644 --- a/src/devices/cpu/scudsp/scudsp.cpp +++ b/src/devices/cpu/scudsp/scudsp.cpp @@ -92,6 +92,7 @@ #include "emu.h" #include "scudsp.h" +#include "scudspdasm.h" #include "debugger.h" @@ -124,10 +125,10 @@ DEFINE_DEVICE_TYPE(SCUDSP, scudsp_cpu_device, "scudsp", "Sega SCUDSP") #define FLAGS_MASK 0x06ff8000 #define INSTA_DMA 1 -#define scudsp_readop(A) m_program->read_dword(A << 2) -#define scudsp_writeop(A, B) m_program->write_dword(A << 2, B) -#define scudsp_readmem(A,MD) m_data->read_dword((A | (MD << 6)) << 2) -#define scudsp_writemem(A,MD,B) m_data->write_dword((A | (MD << 6)) << 2, B) +#define scudsp_readop(A) m_program->read_dword(A) +#define scudsp_writeop(A, B) m_program->write_dword(A, B) +#define scudsp_readmem(A,MD) m_data->read_dword(A | (MD << 6)) +#define scudsp_writemem(A,MD,B) m_data->write_dword(A | (MD << 6), B) uint32_t scudsp_cpu_device::scudsp_get_source_mem_reg_value( uint32_t mode ) { @@ -1009,13 +1010,21 @@ void scudsp_cpu_device::execute_set_input(int irqline, int state) } } +static ADDRESS_MAP_START( program_map, AS_PROGRAM, 32, scudsp_cpu_device ) + AM_RANGE(0x00, 0xff) AM_RAM +ADDRESS_MAP_END + +static ADDRESS_MAP_START( data_map, AS_DATA, 32, scudsp_cpu_device ) + AM_RANGE(0x00, 0xff) AM_RAM +ADDRESS_MAP_END + scudsp_cpu_device::scudsp_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : cpu_device(mconfig, SCUDSP, tag, owner, clock) , m_out_irq_cb(*this) , m_in_dma_cb(*this) , m_out_dma_cb(*this) - , m_program_config("program", ENDIANNESS_BIG, 32, 8, -2) - , m_data_config("data", ENDIANNESS_BIG, 32, 8, -2) + , m_program_config("program", ENDIANNESS_BIG, 32, 8, -2, ADDRESS_MAP_NAME(program_map)) + , m_data_config("data", ENDIANNESS_BIG, 32, 8, -2, ADDRESS_MAP_NAME(data_map)) { } @@ -1042,8 +1051,7 @@ void scudsp_cpu_device::state_string_export(const device_state_entry &entry, std } -offs_t scudsp_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *scudsp_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( scudsp ); - return CPU_DISASSEMBLE_NAME(scudsp)(this, stream, pc, oprom, opram, options); + return new scudsp_disassembler; } diff --git a/src/devices/cpu/scudsp/scudsp.h b/src/devices/cpu/scudsp/scudsp.h index f0ae8df33de..866a98f7df0 100644 --- a/src/devices/cpu/scudsp/scudsp.h +++ b/src/devices/cpu/scudsp/scudsp.h @@ -88,9 +88,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 4; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 4; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; devcb_write_line m_out_irq_cb; devcb_read16 m_in_dma_cb; @@ -157,7 +155,4 @@ private: DECLARE_DEVICE_TYPE(SCUDSP, scudsp_cpu_device) - -CPU_DISASSEMBLE( scudsp ); - #endif // MAME_CPU_SCUDSP_SCUDSP_H diff --git a/src/devices/cpu/scudsp/scudspdasm.cpp b/src/devices/cpu/scudsp/scudspdasm.cpp index 584073aceca..a29712a0448 100644 --- a/src/devices/cpu/scudsp/scudspdasm.cpp +++ b/src/devices/cpu/scudsp/scudspdasm.cpp @@ -1,10 +1,9 @@ // license:BSD-3-Clause // copyright-holders:Angelo Salese, Mariusz Wojcieszek #include "emu.h" -#include "debugger.h" -#include "scudsp.h" +#include "scudspdasm.h" -static const char *const ALU_Commands[] = +const char *const scudsp_disassembler::ALU_Commands[] = { " ", /* 0000 */ "AND ", /* 0001 */ @@ -24,7 +23,7 @@ static const char *const ALU_Commands[] = "RL8 ", /* 1111 */ }; -static const char *const X_Commands[] = +const char *const scudsp_disassembler::X_Commands[] = { "", /* 000 */ "", /* 001 */ /* NOP? check instruction @ 0x0B */ @@ -33,7 +32,7 @@ static const char *const X_Commands[] = "MOV %s,X", /* 100 */ }; -static const char *const Y_Commands[] = +const char *const scudsp_disassembler::Y_Commands[] = { "", /* 000 */ "CLR A", /* 001 */ @@ -42,7 +41,7 @@ static const char *const Y_Commands[] = "MOV %s,Y", /* 100 */ }; -static const char *const D1_Commands[] = +const char *const scudsp_disassembler::D1_Commands[] = { "", /* 00 */ "MOV %I8,%d", /* 01 */ @@ -50,7 +49,7 @@ static const char *const D1_Commands[] = "MOV %S,%d", /* 11 */ }; -static const char *const SourceMemory[] = +const char *const scudsp_disassembler::SourceMemory[] = { "M0", /* 000 */ "M1", /* 001 */ @@ -62,7 +61,7 @@ static const char *const SourceMemory[] = "MC3", /* 111 */ }; -static const char *const SourceMemory2[] = +const char *const scudsp_disassembler::SourceMemory2[] = { "M0", /* 0000 */ "M1", /* 0001 */ @@ -82,7 +81,7 @@ static const char *const SourceMemory2[] = "???", /* 1111 */ }; -static const char *const DestMemory[] = +const char *const scudsp_disassembler::DestMemory[] = { "MC0", /* 0000 */ "MC1", /* 0001 */ @@ -102,7 +101,7 @@ static const char *const DestMemory[] = "CT3", /* 1111 */ }; -static const char *const DestDMAMemory[] = +const char *const scudsp_disassembler::DestDMAMemory[] = { "M0", /* 000 */ "M1", /* 001 */ @@ -114,19 +113,19 @@ static const char *const DestDMAMemory[] = "???", /* 111 */ }; -static const char *const MVI_Command[] = +const char *const scudsp_disassembler::MVI_Command[] = { "MVI %I,%d", /* 0 */ "MVI %I,%d,%f", /* 1 */ }; -static const char *const JMP_Command[] = +const char *const scudsp_disassembler::JMP_Command[] = { "JMP %IA", "JMP %f,%IA", }; -static const char *const DMA_Command[] = +const char *const scudsp_disassembler::DMA_Command[] = { "DMA%H%A D0,%M,%I", "DMA%H%A %s,D0,%I", @@ -135,8 +134,9 @@ static const char *const DMA_Command[] = }; -static void scudsp_dasm_prefix( const char* format, char* buffer, uint32_t *data ) +std::string scudsp_disassembler::scudsp_dasm_prefix( const char* format, uint32_t *data ) { + std::string result; for ( ; *format; format++ ) { if ( *format == '%' ) @@ -145,104 +145,82 @@ static void scudsp_dasm_prefix( const char* format, char* buffer, uint32_t *data { case 'H': if ( *data ) - { - strcpy( buffer, "H" ); - } - else - { - *buffer = 0; - } + result += 'H'; break; case 'A': if ( *data == 0 ) - { - strcpy( buffer, "0" ); - } - else if ( *data == 1 ) - { - *buffer = 0; - } - else - { - sprintf( buffer, "%d", 1 << (*data - 1) ); - } + result += '0'; + else if ( *data != 1 ) + result += util::string_format("%d", 1 << (*data - 1) ); break; case 's': - strcpy( buffer, SourceMemory[ *data & 0x7 ] ); + result += SourceMemory[ *data & 0x7 ]; break; case 'd': - strcpy( buffer, DestMemory[ *data & 0xf ] ); + result += DestMemory[ *data & 0xf ]; break; case 'S': - strcpy( buffer, SourceMemory2[ *data & 0xf ] ); + result += SourceMemory2[ *data & 0xf ]; break; case 'I': ++format; if ( *format == '8' ) - { - sprintf( buffer, "#$%x", *data ); - } + result += util::string_format("#$%x", *data ); else if ( *format == 'A' ) - { - sprintf( buffer, "$%X", *data ); - } + result += util::string_format("$%X", *data ); else { --format; - sprintf( buffer, "#$%X", *data ); + result += util::string_format("#$%X", *data ); } break; case 'f': if ( !(*data & 0x20) ) - { - strcpy( buffer, "N" ); - buffer++; - } + result += 'N'; switch( *data & 0xf ) { case 0x3: - strcpy( buffer, "ZS" ); + result += "ZS"; break; case 0x2: - strcpy( buffer, "S" ); + result += 'S'; break; case 0x4: - strcpy( buffer, "C" ); + result += 'C'; break; case 0x8: - strcpy( buffer, "T0" ); + result += "T0"; break; case 0x1: - strcpy( buffer, "Z" ); + result += 'Z'; break; default: - strcpy( buffer, "?" ); + result += '?'; break; } break; case 'M': - strcpy( buffer, DestDMAMemory[ *data ] ); + result += DestDMAMemory[ *data ]; break; } data++; - buffer += strlen( buffer ); } else - { - *buffer++ = *format; - } + result += *format; } - *buffer = 0; + return result; } +u32 scudsp_disassembler::opcode_alignment() const +{ + return 1; +} -CPU_DISASSEMBLE(scudsp) +offs_t scudsp_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - uint32_t op = oprom[0]<<24|oprom[1]<<16|oprom[2]<<8|oprom[3]<<0; + uint32_t op = opcodes.r32(pc); unsigned size = 1; -// const char *sym, *sym2; - char temp_buffer[64]; uint32_t data[4]; switch( op >> 30 ) @@ -260,31 +238,15 @@ CPU_DISASSEMBLE(scudsp) /* X-Bus */ data[0] = (op & 0x700000) >> 20; if ( op & 0x2000000 ) - { - scudsp_dasm_prefix( X_Commands[ 4 ], temp_buffer, data ); - } - else - { - *temp_buffer = 0; - } - util::stream_format(stream, "%s", temp_buffer); + stream << scudsp_dasm_prefix( X_Commands[ 4 ], data ); - scudsp_dasm_prefix( X_Commands[ (op & 0x1800000) >> 23 ], temp_buffer, data ); - util::stream_format(stream, "%s", temp_buffer); + stream << scudsp_dasm_prefix( X_Commands[ (op & 0x1800000) >> 23 ], data ); data[0] = (op & 0x1C000 ) >> 14 ; if ( op & 0x80000 ) - { - scudsp_dasm_prefix( Y_Commands[4], temp_buffer, data ); - } - else - { - *temp_buffer = 0; - } - util::stream_format(stream, "%s", temp_buffer); + stream << scudsp_dasm_prefix( Y_Commands[4], data ); - scudsp_dasm_prefix( Y_Commands[ (op & 0x60000) >> 17 ], temp_buffer, data ); - util::stream_format(stream, "%s", temp_buffer); + stream << scudsp_dasm_prefix( Y_Commands[ (op & 0x60000) >> 17 ], data ); /* D1-Bus */ switch( (op & 0x3000) >> 12 ) @@ -299,8 +261,7 @@ CPU_DISASSEMBLE(scudsp) break; } - scudsp_dasm_prefix( D1_Commands[ (op & 0x3000) >> 12 ], temp_buffer, data); - util::stream_format(stream, "%s", temp_buffer); + stream << scudsp_dasm_prefix( D1_Commands[ (op & 0x3000) >> 12 ], data); break; case 2: if ( (op & 0x2000000) ) @@ -308,15 +269,13 @@ CPU_DISASSEMBLE(scudsp) data[0] = op & 0x7FFFF; data[1] = (op & 0x3C000000) >> 26; data[2] = (op & 0x3F80000 ) >> 19; - scudsp_dasm_prefix( MVI_Command[1], temp_buffer, data); /* TODO: bad mem*/ - stream << temp_buffer; + stream << scudsp_dasm_prefix( MVI_Command[1], data); /* TODO: bad mem*/ } else { data[0] = op & 0x1FFFFFF; data[1] = (op & 0x3C000000) >> 26; - scudsp_dasm_prefix( MVI_Command[0], temp_buffer, data ); /* TODO: bad mem*/ - stream << temp_buffer; + stream << scudsp_dasm_prefix( MVI_Command[0], data ); /* TODO: bad mem*/ } break; case 3: @@ -327,22 +286,19 @@ CPU_DISASSEMBLE(scudsp) data[1] = (op & 0x38000) >> 15; /* A */ data[2] = (op & 0x700) >> 8; /* Mem */ data[3] = (op & 0xff); - scudsp_dasm_prefix( DMA_Command[(op & 0x3000) >> 12], temp_buffer, data ); - stream << temp_buffer; + stream << scudsp_dasm_prefix( DMA_Command[(op & 0x3000) >> 12], data ); break; case 1: if ( op & 0x3F80000 ) { data[0] = (op & 0x3F80000) >> 19; data[1] = op & 0xff; - scudsp_dasm_prefix( JMP_Command[1], temp_buffer, data ); - stream << temp_buffer; + stream << scudsp_dasm_prefix( JMP_Command[1], data ); } else { data[0] = op & 0xff; - scudsp_dasm_prefix( JMP_Command[0], temp_buffer, data ); - stream << temp_buffer; + stream << scudsp_dasm_prefix( JMP_Command[0], data ); } break; case 2: diff --git a/src/devices/cpu/scudsp/scudspdasm.h b/src/devices/cpu/scudsp/scudspdasm.h new file mode 100644 index 00000000000..7f86d0366aa --- /dev/null +++ b/src/devices/cpu/scudsp/scudspdasm.h @@ -0,0 +1,33 @@ +// license:BSD-3-Clause +// copyright-holders:Angelo Salese, Mariusz Wojcieszek + +#ifndef MAME_CPU_SCUDSP_SCUDSPDASM_H +#define MAME_CPU_SCUDSP_SCUDSPDASM_H + +#pragma once + +class scudsp_disassembler : public util::disasm_interface +{ +public: + scudsp_disassembler() = default; + virtual ~scudsp_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *const ALU_Commands[]; + static const char *const X_Commands[]; + static const char *const Y_Commands[]; + static const char *const D1_Commands[]; + static const char *const SourceMemory[]; + static const char *const SourceMemory2[]; + static const char *const DestMemory[]; + static const char *const DestDMAMemory[]; + static const char *const MVI_Command[]; + static const char *const JMP_Command[]; + static const char *const DMA_Command[]; + std::string scudsp_dasm_prefix( const char* format, uint32_t *data ); +}; + +#endif diff --git a/src/devices/cpu/se3208/se3208.cpp b/src/devices/cpu/se3208/se3208.cpp index 45bb8a30c45..fb188002bd8 100644 --- a/src/devices/cpu/se3208/se3208.cpp +++ b/src/devices/cpu/se3208/se3208.cpp @@ -2,6 +2,7 @@ // copyright-holders:ElSemi #include "emu.h" #include "se3208.h" +#include "se3208dis.h" #include "debugger.h" @@ -1720,7 +1721,7 @@ void se3208_device::device_reset() m_ER = 0; m_PPC = 0; m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_PC=SE3208_Read32(0); m_SR=0; m_IRQ=CLEAR_LINE; @@ -1785,7 +1786,7 @@ void se3208_device::device_start() BuildTable(); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); save_item(NAME(m_R)); save_item(NAME(m_PC)); @@ -1847,8 +1848,7 @@ void se3208_device::execute_set_input( int line, int state ) m_IRQ=state; } -offs_t se3208_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *se3208_device::create_disassembler() { - extern CPU_DISASSEMBLE( se3208 ); - return CPU_DISASSEMBLE_NAME(se3208)(this, stream, pc, oprom, opram, options); + return new se3208_disassembler; } diff --git a/src/devices/cpu/se3208/se3208.h b/src/devices/cpu/se3208/se3208.h index 69cddd0175b..a9fe4249922 100644 --- a/src/devices/cpu/se3208/se3208.h +++ b/src/devices/cpu/se3208/se3208.h @@ -39,9 +39,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 2; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -56,7 +54,7 @@ private: uint32_t m_PPC; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; uint8_t m_IRQ; uint8_t m_NMI; diff --git a/src/devices/cpu/se3208/se3208dis.cpp b/src/devices/cpu/se3208/se3208dis.cpp index ca7d3761d61..0ce74883cae 100644 --- a/src/devices/cpu/se3208/se3208dis.cpp +++ b/src/devices/cpu/se3208/se3208dis.cpp @@ -1,22 +1,13 @@ // license:BSD-3-Clause // copyright-holders:ElSemi #include "emu.h" -#include "debugger.h" -#include "se3208.h" - - -static struct -{ - uint32_t PC; - uint32_t SR; - uint32_t ER; -} Context; +#include "se3208dis.h" #define FLAG_E 0x0800 -#define CLRFLAG(f) Context.SR&=~(f); -#define SETFLAG(f) Context.SR|=(f); -#define TESTFLAG(f) (Context.SR&(f)) +#define CLRFLAG(f) SR&=~(f); +#define SETFLAG(f) SR|=(f); +#define TESTFLAG(f) (SR&(f)) #define EXTRACT(val,sbit,ebit) (((val)>>sbit)&((1<<((ebit-sbit)+1))-1)) #define SEX8(val) ((val&0x80)?(val|0xFFFFFF00):(val&0xFF)) @@ -25,8 +16,8 @@ static struct #define ZEX16(val) ((val)&0xFFFF) #define SEX(bits,val) ((val)&(1<<(bits-1))?((val)|(~((1<<bits)-1))):(val&((1<<bits)-1))) -typedef uint32_t (*_OP)(uint16_t Opcode, std::ostream &stream); -#define INST(a) static uint32_t a(uint16_t Opcode, std::ostream &stream) +#define INST(a) uint32_t se3208_disassembler::a(uint16_t Opcode, std::ostream &stream) + INST(INVALIDOP) @@ -42,7 +33,7 @@ INST(LDB) uint32_t SrcDst=EXTRACT(Opcode,8,10); if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); if(Index) util::stream_format(stream, "LDB (%%R%d,0x%x),%%R%d",Index,Offset,SrcDst); @@ -60,7 +51,7 @@ INST(STB) uint32_t SrcDst=EXTRACT(Opcode,8,10); if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); if(Index) util::stream_format(stream, "STB %%R%d,(%%R%d,0x%x)",SrcDst,Index,Offset); @@ -80,7 +71,7 @@ INST(LDS) Offset<<=1; if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); if(Index) util::stream_format(stream, "LDS (%%R%d,0x%x),%%R%d",Index,Offset,SrcDst); @@ -100,7 +91,7 @@ INST(STS) Offset<<=1; if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); if(Index) util::stream_format(stream, "STS %%R%d,(%%R%d,0x%x)",SrcDst,Index,Offset); @@ -120,7 +111,7 @@ INST(LD) Offset<<=2; if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); if(Index) util::stream_format(stream, "LD (%%R%d,0x%x),%%R%d",Index,Offset,SrcDst); @@ -140,7 +131,7 @@ INST(ST) Offset<<=2; if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); if(Index) util::stream_format(stream, "ST %%R%d,(%%R%d,0x%x)",SrcDst,Index,Offset); @@ -158,7 +149,7 @@ INST(LDBU) uint32_t SrcDst=EXTRACT(Opcode,8,10); if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); if(Index) util::stream_format(stream, "LDBU (%%R%d,0x%x),%%R%d",Index,Offset,SrcDst); @@ -178,7 +169,7 @@ INST(LDSU) Offset<<=1; if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); if(Index) util::stream_format(stream, "LDSU (%%R%d,0x%x),%%R%d",Index,Offset,SrcDst); @@ -195,12 +186,12 @@ INST(LERI) uint32_t Imm=EXTRACT(Opcode,0,13); if(TESTFLAG(FLAG_E)) - Context.ER=(EXTRACT(Context.ER,0,17)<<14)|Imm; + ER=(EXTRACT(ER,0,17)<<14)|Imm; else - Context.ER=SEX(14,Imm); + ER=SEX(14,Imm); - //util::stream_format(stream, "LERI 0x%x\t\tER=%08X",Imm,Context.ER); - util::stream_format(stream, "LERI 0x%x",Imm/*,Context.ER*/); + //util::stream_format(stream, "LERI 0x%x\t\tER=%08X",Imm,ER); + util::stream_format(stream, "LERI 0x%x",Imm/*,ER*/); SETFLAG(FLAG_E); return 0; @@ -214,7 +205,7 @@ INST(LDSP) Offset<<=2; if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); util::stream_format(stream, "LD (%%SP,0x%x),%%R%d",Offset,SrcDst); @@ -230,7 +221,7 @@ INST(STSP) Offset<<=2; if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); util::stream_format(stream, "ST %%R%d,(%%SP,0x%x)",SrcDst,Offset); @@ -306,7 +297,7 @@ INST(POP) if(Ret) strcat(str,"\n"); stream << str; - return Ret ? DASMFLAG_STEP_OUT : 0; + return Ret ? STEP_OUT : 0; } INST(LEATOSP) @@ -315,7 +306,7 @@ INST(LEATOSP) uint32_t Index=EXTRACT(Opcode,3,5); if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); else Offset=SEX(4,Offset); @@ -334,7 +325,7 @@ INST(LEAFROMSP) uint32_t Index=EXTRACT(Opcode,3,5); if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); else Offset=SEX(4,Offset); @@ -351,7 +342,7 @@ INST(LEASPTOSP) Offset<<=2; if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,23)<<8)|(Offset&0xff); + Offset=(EXTRACT(ER,0,23)<<8)|(Offset&0xff); else Offset=SEX(10,Offset); @@ -380,7 +371,7 @@ INST(LDI) uint32_t Imm=EXTRACT(Opcode,0,7); if(TESTFLAG(FLAG_E)) - Imm=(EXTRACT(Context.ER,0,27)<<4)|(Imm&0xf); + Imm=(EXTRACT(ER,0,27)<<4)|(Imm&0xf); else Imm=SEX8(Imm); @@ -396,7 +387,7 @@ INST(LDBSP) uint32_t SrcDst=EXTRACT(Opcode,4,6); if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); util::stream_format(stream, "LDB (%%SP,0x%x),%%R%d",Offset,SrcDst); @@ -410,7 +401,7 @@ INST(STBSP) uint32_t SrcDst=EXTRACT(Opcode,4,6); if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); util::stream_format(stream, "STB %%R%d,(%%SP,0x%x)",SrcDst,Offset); @@ -426,7 +417,7 @@ INST(LDSSP) Offset<<=1; if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); util::stream_format(stream, "LDS (%%SP,0x%x),%%R%d",Offset,SrcDst); @@ -442,7 +433,7 @@ INST(STSSP) Offset<<=1; if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); util::stream_format(stream, "STS %%R%d,(%%SP,0x%x)",SrcDst,Offset); @@ -456,7 +447,7 @@ INST(LDBUSP) uint32_t SrcDst=EXTRACT(Opcode,4,6); if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); util::stream_format(stream, "LDBU (%%SP,0x%x),%%R%d",Offset,SrcDst); @@ -472,7 +463,7 @@ INST(LDSUSP) Offset<<=1; if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); util::stream_format(stream, "LDSU (%%SP,0x%x),%%R%d",Offset,SrcDst); @@ -488,7 +479,7 @@ INST(ADDI) uint32_t Imm2=Imm; if(TESTFLAG(FLAG_E)) - Imm2=(EXTRACT(Context.ER,0,27)<<4)|(Imm2&0xf); + Imm2=(EXTRACT(ER,0,27)<<4)|(Imm2&0xf); else Imm2=SEX(4,Imm2); @@ -506,7 +497,7 @@ INST(SUBI) uint32_t Imm2=Imm; if(TESTFLAG(FLAG_E)) - Imm2=(EXTRACT(Context.ER,0,27)<<4)|(Imm2&0xf); + Imm2=(EXTRACT(ER,0,27)<<4)|(Imm2&0xf); else Imm2=SEX(4,Imm2); @@ -525,7 +516,7 @@ INST(ADCI) uint32_t Imm2=Imm; if(TESTFLAG(FLAG_E)) - Imm2=(EXTRACT(Context.ER,0,27)<<4)|(Imm2&0xf); + Imm2=(EXTRACT(ER,0,27)<<4)|(Imm2&0xf); else Imm2=SEX(4,Imm2); @@ -543,7 +534,7 @@ INST(SBCI) uint32_t Imm2=Imm; if(TESTFLAG(FLAG_E)) - Imm2=(EXTRACT(Context.ER,0,27)<<4)|(Imm2&0xf); + Imm2=(EXTRACT(ER,0,27)<<4)|(Imm2&0xf); else Imm2=SEX(4,Imm2); @@ -561,7 +552,7 @@ INST(ANDI) uint32_t Imm2=Imm; if(TESTFLAG(FLAG_E)) - Imm2=(EXTRACT(Context.ER,0,27)<<4)|(Imm2&0xf); + Imm2=(EXTRACT(ER,0,27)<<4)|(Imm2&0xf); else Imm2=SEX(4,Imm2); @@ -579,7 +570,7 @@ INST(ORI) uint32_t Imm2=Imm; if(TESTFLAG(FLAG_E)) - Imm2=(EXTRACT(Context.ER,0,27)<<4)|(Imm2&0xf); + Imm2=(EXTRACT(ER,0,27)<<4)|(Imm2&0xf); else Imm2=SEX(4,Imm2); @@ -597,7 +588,7 @@ INST(XORI) uint32_t Imm2=Imm; if(TESTFLAG(FLAG_E)) - Imm2=(EXTRACT(Context.ER,0,27)<<4)|(Imm2&0xf); + Imm2=(EXTRACT(ER,0,27)<<4)|(Imm2&0xf); else Imm2=SEX(4,Imm2); @@ -614,7 +605,7 @@ INST(CMPI) uint32_t Imm2=Imm; if(TESTFLAG(FLAG_E)) - Imm2=(EXTRACT(Context.ER,0,27)<<4)|(Imm2&0xf); + Imm2=(EXTRACT(ER,0,27)<<4)|(Imm2&0xf); else Imm2=SEX(4,Imm2); @@ -631,7 +622,7 @@ INST(TSTI) uint32_t Imm2=Imm; if(TESTFLAG(FLAG_E)) - Imm2=(EXTRACT(Context.ER,0,27)<<4)|(Imm2&0xf); + Imm2=(EXTRACT(ER,0,27)<<4)|(Imm2&0xf); else Imm2=SEX(4,Imm2); @@ -756,14 +747,14 @@ INST(CALL) uint32_t Offset2; if(TESTFLAG(FLAG_E)) - Offset2=(EXTRACT(Context.ER,0,22)<<8)|Offset; + Offset2=(EXTRACT(ER,0,22)<<8)|Offset; else Offset2=SEX(8,Offset); Offset2<<=1; - util::stream_format(stream, "CALL 0x%x",Context.PC+2+Offset2); + util::stream_format(stream, "CALL 0x%x",PC+2+Offset2); CLRFLAG(FLAG_E); - return DASMFLAG_STEP_OVER; + return STEP_OVER; } INST(JV) @@ -772,11 +763,11 @@ INST(JV) uint32_t Offset2; if(TESTFLAG(FLAG_E)) - Offset2=(EXTRACT(Context.ER,0,22)<<8)|Offset; + Offset2=(EXTRACT(ER,0,22)<<8)|Offset; else Offset2=SEX(8,Offset); Offset2<<=1; - util::stream_format(stream, "JV 0x%x",Context.PC+2+Offset2); + util::stream_format(stream, "JV 0x%x",PC+2+Offset2); CLRFLAG(FLAG_E); return 0; @@ -788,11 +779,11 @@ INST(JNV) uint32_t Offset2; if(TESTFLAG(FLAG_E)) - Offset2=(EXTRACT(Context.ER,0,22)<<8)|Offset; + Offset2=(EXTRACT(ER,0,22)<<8)|Offset; else Offset2=SEX(8,Offset); Offset2<<=1; - util::stream_format(stream, "JNV 0x%x",Context.PC+2+Offset2); + util::stream_format(stream, "JNV 0x%x",PC+2+Offset2); CLRFLAG(FLAG_E); return 0; @@ -804,11 +795,11 @@ INST(JC) uint32_t Offset2; if(TESTFLAG(FLAG_E)) - Offset2=(EXTRACT(Context.ER,0,22)<<8)|Offset; + Offset2=(EXTRACT(ER,0,22)<<8)|Offset; else Offset2=SEX(8,Offset); Offset2<<=1; - util::stream_format(stream, "JC 0x%x",Context.PC+2+Offset2); + util::stream_format(stream, "JC 0x%x",PC+2+Offset2); CLRFLAG(FLAG_E); return 0; @@ -820,11 +811,11 @@ INST(JNC) uint32_t Offset2; if(TESTFLAG(FLAG_E)) - Offset2=(EXTRACT(Context.ER,0,22)<<8)|Offset; + Offset2=(EXTRACT(ER,0,22)<<8)|Offset; else Offset2=SEX(8,Offset); Offset2<<=1; - util::stream_format(stream, "JNC 0x%x",Context.PC+2+Offset2); + util::stream_format(stream, "JNC 0x%x",PC+2+Offset2); CLRFLAG(FLAG_E); return 0; @@ -836,11 +827,11 @@ INST(JP) uint32_t Offset2; if(TESTFLAG(FLAG_E)) - Offset2=(EXTRACT(Context.ER,0,22)<<8)|Offset; + Offset2=(EXTRACT(ER,0,22)<<8)|Offset; else Offset2=SEX(8,Offset); Offset2<<=1; - util::stream_format(stream, "JP 0x%x",Context.PC+2+Offset2); + util::stream_format(stream, "JP 0x%x",PC+2+Offset2); CLRFLAG(FLAG_E); return 0; @@ -852,11 +843,11 @@ INST(JM) uint32_t Offset2; if(TESTFLAG(FLAG_E)) - Offset2=(EXTRACT(Context.ER,0,22)<<8)|Offset; + Offset2=(EXTRACT(ER,0,22)<<8)|Offset; else Offset2=SEX(8,Offset); Offset2<<=1; - util::stream_format(stream, "JM 0x%x",Context.PC+2+Offset2); + util::stream_format(stream, "JM 0x%x",PC+2+Offset2); CLRFLAG(FLAG_E); return 0; @@ -868,11 +859,11 @@ INST(JNZ) uint32_t Offset2; if(TESTFLAG(FLAG_E)) - Offset2=(EXTRACT(Context.ER,0,22)<<8)|Offset; + Offset2=(EXTRACT(ER,0,22)<<8)|Offset; else Offset2=SEX(8,Offset); Offset2<<=1; - util::stream_format(stream, "JNZ 0x%x",Context.PC+2+Offset2); + util::stream_format(stream, "JNZ 0x%x",PC+2+Offset2); CLRFLAG(FLAG_E); return 0; @@ -884,11 +875,11 @@ INST(JZ) uint32_t Offset2; if(TESTFLAG(FLAG_E)) - Offset2=(EXTRACT(Context.ER,0,22)<<8)|Offset; + Offset2=(EXTRACT(ER,0,22)<<8)|Offset; else Offset2=SEX(8,Offset); Offset2<<=1; - util::stream_format(stream, "JZ 0x%x",Context.PC+2+Offset2); + util::stream_format(stream, "JZ 0x%x",PC+2+Offset2); CLRFLAG(FLAG_E); return 0; @@ -900,11 +891,11 @@ INST(JGE) uint32_t Offset2; if(TESTFLAG(FLAG_E)) - Offset2=(EXTRACT(Context.ER,0,22)<<8)|Offset; + Offset2=(EXTRACT(ER,0,22)<<8)|Offset; else Offset2=SEX(8,Offset); Offset2<<=1; - util::stream_format(stream, "JGE 0x%x",Context.PC+2+Offset2); + util::stream_format(stream, "JGE 0x%x",PC+2+Offset2); CLRFLAG(FLAG_E); return 0; @@ -916,11 +907,11 @@ INST(JLE) uint32_t Offset2; if(TESTFLAG(FLAG_E)) - Offset2=(EXTRACT(Context.ER,0,22)<<8)|Offset; + Offset2=(EXTRACT(ER,0,22)<<8)|Offset; else Offset2=SEX(8,Offset); Offset2<<=1; - util::stream_format(stream, "JLE 0x%x",Context.PC+2+Offset2); + util::stream_format(stream, "JLE 0x%x",PC+2+Offset2); CLRFLAG(FLAG_E); return 0; @@ -932,11 +923,11 @@ INST(JHI) uint32_t Offset2; if(TESTFLAG(FLAG_E)) - Offset2=(EXTRACT(Context.ER,0,22)<<8)|Offset; + Offset2=(EXTRACT(ER,0,22)<<8)|Offset; else Offset2=SEX(8,Offset); Offset2<<=1; - util::stream_format(stream, "JHI 0x%x",Context.PC+2+Offset2); + util::stream_format(stream, "JHI 0x%x",PC+2+Offset2); CLRFLAG(FLAG_E); return 0; @@ -948,11 +939,11 @@ INST(JLS) uint32_t Offset2; if(TESTFLAG(FLAG_E)) - Offset2=(EXTRACT(Context.ER,0,22)<<8)|Offset; + Offset2=(EXTRACT(ER,0,22)<<8)|Offset; else Offset2=SEX(8,Offset); Offset2<<=1; - util::stream_format(stream, "JLS 0x%x",Context.PC+2+Offset2); + util::stream_format(stream, "JLS 0x%x",PC+2+Offset2); CLRFLAG(FLAG_E); return 0; @@ -964,11 +955,11 @@ INST(JGT) uint32_t Offset2; if(TESTFLAG(FLAG_E)) - Offset2=(EXTRACT(Context.ER,0,22)<<8)|Offset; + Offset2=(EXTRACT(ER,0,22)<<8)|Offset; else Offset2=SEX(8,Offset); Offset2<<=1; - util::stream_format(stream, "JGT 0x%x",Context.PC+2+Offset2); + util::stream_format(stream, "JGT 0x%x",PC+2+Offset2); CLRFLAG(FLAG_E); return 0; @@ -980,11 +971,11 @@ INST(JLT) uint32_t Offset2; if(TESTFLAG(FLAG_E)) - Offset2=(EXTRACT(Context.ER,0,22)<<8)|Offset; + Offset2=(EXTRACT(ER,0,22)<<8)|Offset; else Offset2=SEX(8,Offset); Offset2<<=1; - util::stream_format(stream, "JLT 0x%x",Context.PC+2+Offset2); + util::stream_format(stream, "JLT 0x%x",PC+2+Offset2); CLRFLAG(FLAG_E); return 0; @@ -998,11 +989,11 @@ INST(JMP) uint32_t Offset2; if(TESTFLAG(FLAG_E)) - Offset2=(EXTRACT(Context.ER,0,22)<<8)|Offset; + Offset2=(EXTRACT(ER,0,22)<<8)|Offset; else Offset2=SEX(8,Offset); Offset2<<=1; - util::stream_format(stream, "JMP 0x%x",Context.PC+2+Offset2); + util::stream_format(stream, "JMP 0x%x",PC+2+Offset2); CLRFLAG(FLAG_E); return 0; @@ -1025,7 +1016,7 @@ INST(CALLR) util::stream_format(stream, "CALLR %%R%d",Src); CLRFLAG(FLAG_E); - return DASMFLAG_STEP_OVER; + return STEP_OVER; } INST(ASR) @@ -1144,7 +1135,7 @@ INST(MVFC) return 0; } -static _OP DecodeOp(uint16_t Opcode) +se3208_disassembler::_OP se3208_disassembler::DecodeOp(uint16_t Opcode) { switch(EXTRACT(Opcode,14,15)) { @@ -1154,38 +1145,38 @@ static _OP DecodeOp(uint16_t Opcode) switch(Op) { case 0x0: - return LDB; + return &se3208_disassembler::LDB; case 0x1: - return LDS; + return &se3208_disassembler::LDS; case 0x2: - return LD; + return &se3208_disassembler::LD; case 0x3: - return LDBU; + return &se3208_disassembler::LDBU; case 0x4: - return STB; + return &se3208_disassembler::STB; case 0x5: - return STS; + return &se3208_disassembler::STS; case 0x6: - return ST; + return &se3208_disassembler::ST; case 0x7: - return LDSU; + return &se3208_disassembler::LDSU; } } break; case 0x1: - return LERI; + return &se3208_disassembler::LERI; case 0x2: { switch(EXTRACT(Opcode,11,13)) { case 0: - return LDSP; + return &se3208_disassembler::LDSP; case 1: - return STSP; + return &se3208_disassembler::STSP; case 2: - return PUSH; + return &se3208_disassembler::PUSH; case 3: - return POP; + return &se3208_disassembler::POP; case 4: case 5: case 6: @@ -1201,30 +1192,30 @@ static _OP DecodeOp(uint16_t Opcode) switch(EXTRACT(Opcode,6,8)) { case 0: - return ADDI; + return &se3208_disassembler::ADDI; case 1: - return ADCI; + return &se3208_disassembler::ADCI; case 2: - return SUBI; + return &se3208_disassembler::SUBI; case 3: - return SBCI; + return &se3208_disassembler::SBCI; case 4: - return ANDI; + return &se3208_disassembler::ANDI; case 5: - return ORI; + return &se3208_disassembler::ORI; case 6: - return XORI; + return &se3208_disassembler::XORI; case 7: switch(EXTRACT(Opcode,0,2)) { case 0: - return CMPI; + return &se3208_disassembler::CMPI; case 1: - return TSTI; + return &se3208_disassembler::TSTI; case 2: - return LEATOSP; + return &se3208_disassembler::LEATOSP; case 3: - return LEAFROMSP; + return &se3208_disassembler::LEAFROMSP; } break; } @@ -1239,30 +1230,30 @@ static _OP DecodeOp(uint16_t Opcode) switch(EXTRACT(Opcode,6,8)) { case 0: - return ADD; + return &se3208_disassembler::ADD; case 1: - return ADC; + return &se3208_disassembler::ADC; case 2: - return SUB; + return &se3208_disassembler::SUB; case 3: - return SBC; + return &se3208_disassembler::SBC; case 4: - return AND; + return &se3208_disassembler::AND; case 5: - return OR; + return &se3208_disassembler::OR; case 6: - return XOR; + return &se3208_disassembler::XOR; case 7: switch(EXTRACT(Opcode,0,2)) { case 0: - return CMP; + return &se3208_disassembler::CMP; case 1: - return TST; + return &se3208_disassembler::TST; case 2: - return MOV; + return &se3208_disassembler::MOV; case 3: - return NEG; + return &se3208_disassembler::NEG; } break; } @@ -1271,42 +1262,42 @@ static _OP DecodeOp(uint16_t Opcode) switch(EXTRACT(Opcode,8,11)) { case 0x0: - return JNV; + return &se3208_disassembler::JNV; case 0x1: - return JV; + return &se3208_disassembler::JV; case 0x2: - return JP; + return &se3208_disassembler::JP; case 0x3: - return JM; + return &se3208_disassembler::JM; case 0x4: - return JNZ; + return &se3208_disassembler::JNZ; case 0x5: - return JZ; + return &se3208_disassembler::JZ; case 0x6: - return JNC; + return &se3208_disassembler::JNC; case 0x7: - return JC; + return &se3208_disassembler::JC; case 0x8: - return JGT; + return &se3208_disassembler::JGT; case 0x9: - return JLT; + return &se3208_disassembler::JLT; case 0xa: - return JGE; + return &se3208_disassembler::JGE; case 0xb: - return JLE; + return &se3208_disassembler::JLE; case 0xc: - return JHI; + return &se3208_disassembler::JHI; case 0xd: - return JLS; + return &se3208_disassembler::JLS; case 0xe: - return JMP; + return &se3208_disassembler::JMP; case 0xf: - return CALL; + return &se3208_disassembler::CALL; } break; case 2: if(Opcode&(1<<11)) - return LDI; + return &se3208_disassembler::LDI; else //SP Ops { if(Opcode&(1<<10)) @@ -1314,24 +1305,24 @@ static _OP DecodeOp(uint16_t Opcode) switch(EXTRACT(Opcode,7,9)) { case 0: - return LDBSP; + return &se3208_disassembler::LDBSP; case 1: - return LDSSP; + return &se3208_disassembler::LDSSP; case 3: - return LDBUSP; + return &se3208_disassembler::LDBUSP; case 4: - return STBSP; + return &se3208_disassembler::STBSP; case 5: - return STSSP; + return &se3208_disassembler::STSSP; case 7: - return LDSUSP; + return &se3208_disassembler::LDSUSP; } } else { if(Opcode&(1<<9)) { - return LEASPTOSP; + return &se3208_disassembler::LEASPTOSP; } else { @@ -1343,21 +1334,21 @@ static _OP DecodeOp(uint16_t Opcode) switch(EXTRACT(Opcode,4,7)) { case 0: - return EXTB; + return &se3208_disassembler::EXTB; case 1: - return EXTS; + return &se3208_disassembler::EXTS; case 8: - return JR; + return &se3208_disassembler::JR; case 9: - return CALLR; + return &se3208_disassembler::CALLR; case 10: - return SET; + return &se3208_disassembler::SET; case 11: - return CLR; + return &se3208_disassembler::CLR; case 12: - return SWI; + return &se3208_disassembler::SWI; case 13: - return HALT; + return &se3208_disassembler::HALT; } } } @@ -1374,40 +1365,45 @@ static _OP DecodeOp(uint16_t Opcode) switch(EXTRACT(Opcode,3,4)) { case 0: - return ASR; + return &se3208_disassembler::ASR; case 1: - return LSR; + return &se3208_disassembler::LSR; case 2: - return ASL; + return &se3208_disassembler::ASL; //case 3: - // return LSL; + // return &se3208_disassembler::LSL; } break; case 4: - return MULS; + return &se3208_disassembler::MULS; case 6: if(Opcode&(1<<3)) - return MVFC; + return &se3208_disassembler::MVFC; else - return MVTC; + return &se3208_disassembler::MVTC; } break; } break; } - return INVALIDOP; + return &se3208_disassembler::INVALIDOP; } -CPU_DISASSEMBLE(se3208) +u32 se3208_disassembler::opcode_alignment() const +{ + return 2; +} + +offs_t se3208_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint16_t Opcode; CLRFLAG(FLAG_E); - Context.ER=0; + ER=0; - Context.PC=pc; - Opcode=oprom[0] | (oprom[1] << 8); - return 2 | ((*DecodeOp(Opcode))(Opcode, stream)) | DASMFLAG_SUPPORTED; + PC=pc; + Opcode=opcodes.r16(pc); + return 2 | ((this->*DecodeOp(Opcode))(Opcode, stream)) | SUPPORTED; } diff --git a/src/devices/cpu/se3208/se3208dis.h b/src/devices/cpu/se3208/se3208dis.h new file mode 100644 index 00000000000..ffe66c602c7 --- /dev/null +++ b/src/devices/cpu/se3208/se3208dis.h @@ -0,0 +1,103 @@ +// license:BSD-3-Clause +// copyright-holders:ElSemi + +#ifndef MAME_CPU_SE3208_SE3208DIS_H +#define MAME_CPU_SE3208_SE3208DIS_H + +#pragma once + +class se3208_disassembler : public util::disasm_interface +{ +public: + se3208_disassembler() = default; + virtual ~se3208_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + typedef uint32_t (se3208_disassembler::*_OP)(uint16_t Opcode, std::ostream &stream); + + uint32_t INVALIDOP(uint16_t Opcode, std::ostream &stream); + uint32_t LDB(uint16_t Opcode, std::ostream &stream); + uint32_t STB(uint16_t Opcode, std::ostream &stream); + uint32_t LDS(uint16_t Opcode, std::ostream &stream); + uint32_t STS(uint16_t Opcode, std::ostream &stream); + uint32_t LD(uint16_t Opcode, std::ostream &stream); + uint32_t ST(uint16_t Opcode, std::ostream &stream); + uint32_t LDBU(uint16_t Opcode, std::ostream &stream); + uint32_t LDSU(uint16_t Opcode, std::ostream &stream); + uint32_t LERI(uint16_t Opcode, std::ostream &stream); + uint32_t LDSP(uint16_t Opcode, std::ostream &stream); + uint32_t STSP(uint16_t Opcode, std::ostream &stream); + uint32_t PUSH(uint16_t Opcode, std::ostream &stream); + uint32_t POP(uint16_t Opcode, std::ostream &stream); + uint32_t LEATOSP(uint16_t Opcode, std::ostream &stream); + uint32_t LEAFROMSP(uint16_t Opcode, std::ostream &stream); + uint32_t LEASPTOSP(uint16_t Opcode, std::ostream &stream); + uint32_t MOV(uint16_t Opcode, std::ostream &stream); + uint32_t LDI(uint16_t Opcode, std::ostream &stream); + uint32_t LDBSP(uint16_t Opcode, std::ostream &stream); + uint32_t STBSP(uint16_t Opcode, std::ostream &stream); + uint32_t LDSSP(uint16_t Opcode, std::ostream &stream); + uint32_t STSSP(uint16_t Opcode, std::ostream &stream); + uint32_t LDBUSP(uint16_t Opcode, std::ostream &stream); + uint32_t LDSUSP(uint16_t Opcode, std::ostream &stream); + uint32_t ADDI(uint16_t Opcode, std::ostream &stream); + uint32_t SUBI(uint16_t Opcode, std::ostream &stream); + uint32_t ADCI(uint16_t Opcode, std::ostream &stream); + uint32_t SBCI(uint16_t Opcode, std::ostream &stream); + uint32_t ANDI(uint16_t Opcode, std::ostream &stream); + uint32_t ORI(uint16_t Opcode, std::ostream &stream); + uint32_t XORI(uint16_t Opcode, std::ostream &stream); + uint32_t CMPI(uint16_t Opcode, std::ostream &stream); + uint32_t TSTI(uint16_t Opcode, std::ostream &stream); + uint32_t ADD(uint16_t Opcode, std::ostream &stream); + uint32_t SUB(uint16_t Opcode, std::ostream &stream); + uint32_t ADC(uint16_t Opcode, std::ostream &stream); + uint32_t SBC(uint16_t Opcode, std::ostream &stream); + uint32_t AND(uint16_t Opcode, std::ostream &stream); + uint32_t OR(uint16_t Opcode, std::ostream &stream); + uint32_t XOR(uint16_t Opcode, std::ostream &stream); + uint32_t CMP(uint16_t Opcode, std::ostream &stream); + uint32_t TST(uint16_t Opcode, std::ostream &stream); + uint32_t MULS(uint16_t Opcode, std::ostream &stream); + uint32_t NEG(uint16_t Opcode, std::ostream &stream); + uint32_t CALL(uint16_t Opcode, std::ostream &stream); + uint32_t JV(uint16_t Opcode, std::ostream &stream); + uint32_t JNV(uint16_t Opcode, std::ostream &stream); + uint32_t JC(uint16_t Opcode, std::ostream &stream); + uint32_t JNC(uint16_t Opcode, std::ostream &stream); + uint32_t JP(uint16_t Opcode, std::ostream &stream); + uint32_t JM(uint16_t Opcode, std::ostream &stream); + uint32_t JNZ(uint16_t Opcode, std::ostream &stream); + uint32_t JZ(uint16_t Opcode, std::ostream &stream); + uint32_t JGE(uint16_t Opcode, std::ostream &stream); + uint32_t JLE(uint16_t Opcode, std::ostream &stream); + uint32_t JHI(uint16_t Opcode, std::ostream &stream); + uint32_t JLS(uint16_t Opcode, std::ostream &stream); + uint32_t JGT(uint16_t Opcode, std::ostream &stream); + uint32_t JLT(uint16_t Opcode, std::ostream &stream); + uint32_t JMP(uint16_t Opcode, std::ostream &stream); + uint32_t JR(uint16_t Opcode, std::ostream &stream); + uint32_t CALLR(uint16_t Opcode, std::ostream &stream); + uint32_t ASR(uint16_t Opcode, std::ostream &stream); + uint32_t LSR(uint16_t Opcode, std::ostream &stream); + uint32_t ASL(uint16_t Opcode, std::ostream &stream); + uint32_t EXTB(uint16_t Opcode, std::ostream &stream); + uint32_t EXTS(uint16_t Opcode, std::ostream &stream); + uint32_t SET(uint16_t Opcode, std::ostream &stream); + uint32_t CLR(uint16_t Opcode, std::ostream &stream); + uint32_t SWI(uint16_t Opcode, std::ostream &stream); + uint32_t HALT(uint16_t Opcode, std::ostream &stream); + uint32_t MVTC(uint16_t Opcode, std::ostream &stream); + uint32_t MVFC(uint16_t Opcode, std::ostream &stream); + + _OP DecodeOp(uint16_t Opcode); + + uint32_t PC; + uint32_t SR; + uint32_t ER; +}; + +#endif diff --git a/src/devices/cpu/sh/sh.cpp b/src/devices/cpu/sh/sh.cpp new file mode 100644 index 00000000000..f89f260c322 --- /dev/null +++ b/src/devices/cpu/sh/sh.cpp @@ -0,0 +1,4322 @@ +// license:BSD-3-Clause +// copyright-holders:David Haywood + +#include "emu.h" +#include "sh.h" +#include "sh_dasm.h" + +void sh_common_execution::device_start() +{ + /* allocate the implementation-specific state from the full cache */ + m_sh2_state = (internal_sh2_state *)m_cache.alloc_near(sizeof(internal_sh2_state)); + + save_item(NAME(m_sh2_state->pc)); + save_item(NAME(m_sh2_state->sr)); + save_item(NAME(m_sh2_state->pr)); + save_item(NAME(m_sh2_state->gbr)); + save_item(NAME(m_sh2_state->vbr)); + save_item(NAME(m_sh2_state->mach)); + save_item(NAME(m_sh2_state->macl)); + save_item(NAME(m_sh2_state->r)); + save_item(NAME(m_sh2_state->ea)); + save_item(NAME(m_sh2_state->m_delay)); + save_item(NAME(m_sh2_state->pending_irq)); + save_item(NAME(m_sh2_state->pending_nmi)); + save_item(NAME(m_sh2_state->irqline)); + save_item(NAME(m_sh2_state->evec)); + save_item(NAME(m_sh2_state->irqsr)); + save_item(NAME(m_sh2_state->target)); + save_item(NAME(m_sh2_state->internal_irq_level)); + save_item(NAME(m_sh2_state->sleep_mode)); + save_item(NAME(m_sh2_state->icount)); + + m_sh2_state->pc = 0; + m_sh2_state->pr = 0; + m_sh2_state->sr = 0; + m_sh2_state->gbr = 0; + m_sh2_state->vbr = 0; + m_sh2_state->mach = 0; + m_sh2_state->macl = 0; + memset(m_sh2_state->r, 0, sizeof(m_sh2_state->r)); + m_sh2_state->ea = 0; + m_sh2_state->m_delay = 0; + m_sh2_state->pending_irq = 0; + m_sh2_state->pending_nmi = 0; + m_sh2_state->irqline = 0; + m_sh2_state->evec = 0; + m_sh2_state->irqsr = 0; + m_sh2_state->target = 0; + m_sh2_state->internal_irq_level = 0; + m_sh2_state->icount = 0; + m_sh2_state->sleep_mode = 0; + m_sh2_state->arg0 = 0; + + state_add(SH4_PC, "PC", m_sh2_state->pc).formatstr("%08X").callimport(); + state_add(SH_SR, "SR", m_sh2_state->sr).formatstr("%08X").callimport(); + state_add(SH4_PR, "PR", m_sh2_state->pr).formatstr("%08X"); + state_add(SH4_GBR, "GBR", m_sh2_state->gbr).formatstr("%08X"); + state_add(SH4_VBR, "VBR", m_sh2_state->vbr).formatstr("%08X"); + state_add(SH4_MACH, "MACH", m_sh2_state->mach).formatstr("%08X"); + state_add(SH4_MACL, "MACL", m_sh2_state->macl).formatstr("%08X"); + state_add(SH4_R0, "R0", m_sh2_state->r[0]).formatstr("%08X"); + state_add(SH4_R1, "R1", m_sh2_state->r[1]).formatstr("%08X"); + state_add(SH4_R2, "R2", m_sh2_state->r[2]).formatstr("%08X"); + state_add(SH4_R3, "R3", m_sh2_state->r[3]).formatstr("%08X"); + state_add(SH4_R4, "R4", m_sh2_state->r[4]).formatstr("%08X"); + state_add(SH4_R5, "R5", m_sh2_state->r[5]).formatstr("%08X"); + state_add(SH4_R6, "R6", m_sh2_state->r[6]).formatstr("%08X"); + state_add(SH4_R7, "R7", m_sh2_state->r[7]).formatstr("%08X"); + state_add(SH4_R8, "R8", m_sh2_state->r[8]).formatstr("%08X"); + state_add(SH4_R9, "R9", m_sh2_state->r[9]).formatstr("%08X"); + state_add(SH4_R10, "R10", m_sh2_state->r[10]).formatstr("%08X"); + state_add(SH4_R11, "R11", m_sh2_state->r[11]).formatstr("%08X"); + state_add(SH4_R12, "R12", m_sh2_state->r[12]).formatstr("%08X"); + state_add(SH4_R13, "R13", m_sh2_state->r[13]).formatstr("%08X"); + state_add(SH4_R14, "R14", m_sh2_state->r[14]).formatstr("%08X"); + state_add(SH4_R15, "R15", m_sh2_state->r[15]).formatstr("%08X"); + state_add(SH4_EA, "EA", m_sh2_state->ea).formatstr("%08X"); + + state_add(STATE_GENSP, "GENSP", m_sh2_state->r[15]).noshow(); + state_add(STATE_GENFLAGS, "GENFLAGS", m_sh2_state->sr).formatstr("%20s").noshow(); + + m_icountptr = &m_sh2_state->icount; + + m_program = &space(AS_PROGRAM); +} + + +void sh_common_execution::drc_start() +{ + /* DRC helpers */ + memset(m_pcflushes, 0, sizeof(m_pcflushes)); + + m_fastram_select = 0; + memset(m_fastram, 0, sizeof(m_fastram)); + + /* reset per-driver pcflushes */ + m_pcfsel = 0; + + /* initialize the UML generator */ + uint32_t flags = 0; + m_drcuml = std::make_unique<drcuml_state>(*this, m_cache, flags, 1, 32, 1); + + /* add symbols for our stuff */ + m_drcuml->symbol_add(&m_sh2_state->pc, sizeof(m_sh2_state->pc), "pc"); + m_drcuml->symbol_add(&m_sh2_state->icount, sizeof(m_sh2_state->icount), "icount"); + for (int regnum = 0; regnum < 16; regnum++) + { + char buf[10]; + sprintf(buf, "r%d", regnum); + m_drcuml->symbol_add(&m_sh2_state->r[regnum], sizeof(m_sh2_state->r[regnum]), buf); + } + m_drcuml->symbol_add(&m_sh2_state->pr, sizeof(m_sh2_state->pr), "pr"); + m_drcuml->symbol_add(&m_sh2_state->sr, sizeof(m_sh2_state->sr), "sr"); + m_drcuml->symbol_add(&m_sh2_state->gbr, sizeof(m_sh2_state->gbr), "gbr"); + m_drcuml->symbol_add(&m_sh2_state->vbr, sizeof(m_sh2_state->vbr), "vbr"); + m_drcuml->symbol_add(&m_sh2_state->macl, sizeof(m_sh2_state->macl), "macl"); + m_drcuml->symbol_add(&m_sh2_state->mach, sizeof(m_sh2_state->macl), "mach"); + + /* initialize the front-end helper */ + init_drc_frontend(); + + /* compute the register parameters */ + for (int regnum = 0; regnum < 16; regnum++) + { + m_regmap[regnum] = uml::mem(&m_sh2_state->r[regnum]); + } + + /* if we have registers to spare, assign r0, r1, r2 to leftovers */ + /* WARNING: do not use synthetic registers that are mapped here! */ + if (!DISABLE_FAST_REGISTERS) + { + drcbe_info beinfo; + m_drcuml->get_backend_info(beinfo); + if (beinfo.direct_iregs > 4) + { + m_regmap[0] = uml::I4; + } + if (beinfo.direct_iregs > 5) + { + m_regmap[1] = uml::I5; + } + if (beinfo.direct_iregs > 6) + { + m_regmap[2] = uml::I6; + } + } + + /* mark the cache dirty so it is updated on next execute */ + m_cache_dirty = true; + + save_item(NAME(m_pcfsel)); + //save_item(NAME(m_maxpcfsel)); + save_item(NAME(m_pcflushes)); +} + +/* code cycles t-bit + * 0011 nnnn mmmm 1100 1 - + * ADD Rm,Rn + */ +void sh_common_execution::ADD(uint32_t m, uint32_t n) +{ + m_sh2_state->r[n] += m_sh2_state->r[m]; +} + +/* code cycles t-bit + * 0111 nnnn iiii iiii 1 - + * ADD #imm,Rn + */ +void sh_common_execution::ADDI(uint32_t i, uint32_t n) +{ + m_sh2_state->r[n] += (int32_t)(int16_t)(int8_t)i; +} + +/* code cycles t-bit + * 0011 nnnn mmmm 1110 1 carry + * ADDC Rm,Rn + */ +void sh_common_execution::ADDC(uint32_t m, uint32_t n) +{ + uint32_t tmp0, tmp1; + + tmp1 = m_sh2_state->r[n] + m_sh2_state->r[m]; + tmp0 = m_sh2_state->r[n]; + m_sh2_state->r[n] = tmp1 + (m_sh2_state->sr & SH_T); + if (tmp0 > tmp1) + m_sh2_state->sr |= SH_T; + else + m_sh2_state->sr &= ~SH_T; + if (tmp1 > m_sh2_state->r[n]) + m_sh2_state->sr |= SH_T; +} + +/* code cycles t-bit + * 0011 nnnn mmmm 1111 1 overflow + * ADDV Rm,Rn + */ +void sh_common_execution::ADDV(uint32_t m, uint32_t n) +{ + int32_t dest, src, ans; + + if ((int32_t) m_sh2_state->r[n] >= 0) + dest = 0; + else + dest = 1; + if ((int32_t) m_sh2_state->r[m] >= 0) + src = 0; + else + src = 1; + src += dest; + m_sh2_state->r[n] += m_sh2_state->r[m]; + if ((int32_t) m_sh2_state->r[n] >= 0) + ans = 0; + else + ans = 1; + ans += dest; + if (src == 0 || src == 2) + { + if (ans == 1) + m_sh2_state->sr |= SH_T; + else + m_sh2_state->sr &= ~SH_T; + } + else + m_sh2_state->sr &= ~SH_T; +} + +/* code cycles t-bit + * 0010 nnnn mmmm 1001 1 - + * AND Rm,Rn + */ +void sh_common_execution::AND(uint32_t m, uint32_t n) +{ + m_sh2_state->r[n] &= m_sh2_state->r[m]; +} + +/* code cycles t-bit + * 1100 1001 iiii iiii 1 - + * AND #imm,R0 + */ +void sh_common_execution::ANDI(uint32_t i) +{ + m_sh2_state->r[0] &= i; +} + +/* code cycles t-bit + * 1100 1101 iiii iiii 1 - + * AND.B #imm,@(R0,GBR) + */ +void sh_common_execution::ANDM(uint32_t i) +{ + uint32_t temp; + + m_sh2_state->ea = m_sh2_state->gbr + m_sh2_state->r[0]; + temp = i & RB( m_sh2_state->ea ); + WB( m_sh2_state->ea, temp ); + m_sh2_state->icount -= 2; +} + +/* code cycles t-bit + * 1000 1011 dddd dddd 3/1 - + * BF disp8 + */ +void sh_common_execution::BF(uint32_t d) +{ + if ((m_sh2_state->sr & SH_T) == 0) + { + int32_t disp = ((int32_t)d << 24) >> 24; + m_sh2_state->pc = m_sh2_state->ea = m_sh2_state->pc + disp * 2 + 2; + m_sh2_state->icount -= 2; + } +} + +/* code cycles t-bit + * 1000 1111 dddd dddd 3/1 - + * BFS disp8 + */ +void sh_common_execution::BFS(uint32_t d) +{ + if ((m_sh2_state->sr & SH_T) == 0) + { + int32_t disp = ((int32_t)d << 24) >> 24; + m_sh2_state->m_delay = m_sh2_state->ea = m_sh2_state->pc + disp * 2 + 2; + m_sh2_state->icount--; + } +} + +/* code cycles t-bit + * 1010 dddd dddd dddd 2 - + * BRA disp12 + */ +void sh_common_execution::BRA(uint32_t d) +{ + int32_t disp = ((int32_t)d << 20) >> 20; + +#if BUSY_LOOP_HACKS + if (disp == -2) + { + uint32_t next_opcode = RW(m_sh2_state->pc & AM); + /* BRA $ + * NOP + */ + if (next_opcode == 0x0009) + m_sh2_state->icount %= 3; /* cycles for BRA $ and NOP taken (3) */ + } +#endif + m_sh2_state->m_delay = m_sh2_state->ea = m_sh2_state->pc + disp * 2 + 2; + m_sh2_state->icount--; +} + +/* code cycles t-bit + * 0000 mmmm 0010 0011 2 - + * BRAF Rm + */ +void sh_common_execution::BRAF(uint32_t m) +{ + m_sh2_state->m_delay = m_sh2_state->pc + m_sh2_state->r[m] + 2; + m_sh2_state->icount--; +} + +/* code cycles t-bit + * 1011 dddd dddd dddd 2 - + * BSR disp12 + */ +void sh_common_execution::BSR(uint32_t d) +{ + int32_t disp = ((int32_t)d << 20) >> 20; + + m_sh2_state->pr = m_sh2_state->pc + 2; + m_sh2_state->m_delay = m_sh2_state->ea = m_sh2_state->pc + disp * 2 + 2; + m_sh2_state->icount--; +} + +/* code cycles t-bit + * 0000 mmmm 0000 0011 2 - + * BSRF Rm + */ +void sh_common_execution::BSRF(uint32_t m) +{ + m_sh2_state->pr = m_sh2_state->pc + 2; + m_sh2_state->m_delay = m_sh2_state->pc + m_sh2_state->r[m] + 2; + m_sh2_state->icount--; +} + +/* code cycles t-bit + * 1000 1001 dddd dddd 3/1 - + * BT disp8 + */ +void sh_common_execution::BT(uint32_t d) +{ + if ((m_sh2_state->sr & SH_T) != 0) + { + int32_t disp = ((int32_t)d << 24) >> 24; + m_sh2_state->pc = m_sh2_state->ea = m_sh2_state->pc + disp * 2 + 2; + m_sh2_state->icount -= 2; + } +} + +/* code cycles t-bit + * 1000 1101 dddd dddd 2/1 - + * BTS disp8 + */ +void sh_common_execution::BTS(uint32_t d) +{ + if ((m_sh2_state->sr & SH_T) != 0) + { + int32_t disp = ((int32_t)d << 24) >> 24; + m_sh2_state->m_delay = m_sh2_state->ea = m_sh2_state->pc + disp * 2 + 2; + m_sh2_state->icount--; + } +} + +/* code cycles t-bit + * 0000 0000 0010 1000 1 - + * CLRMAC + */ +void sh_common_execution::CLRMAC() +{ + m_sh2_state->mach = 0; + m_sh2_state->macl = 0; +} + +/* code cycles t-bit + * 0000 0000 0000 1000 1 - + * CLRT + */ +void sh_common_execution::CLRT() +{ + m_sh2_state->sr &= ~SH_T; +} + +/* code cycles t-bit + * 0011 nnnn mmmm 0000 1 comparison result + * CMP_EQ Rm,Rn + */ +void sh_common_execution::CMPEQ(uint32_t m, uint32_t n) +{ + if (m_sh2_state->r[n] == m_sh2_state->r[m]) + m_sh2_state->sr |= SH_T; + else + m_sh2_state->sr &= ~SH_T; +} + +/* code cycles t-bit + * 0011 nnnn mmmm 0011 1 comparison result + * CMP_GE Rm,Rn + */ +void sh_common_execution::CMPGE(uint32_t m, uint32_t n) +{ + if ((int32_t) m_sh2_state->r[n] >= (int32_t) m_sh2_state->r[m]) + m_sh2_state->sr |= SH_T; + else + m_sh2_state->sr &= ~SH_T; +} + +/* code cycles t-bit + * 0011 nnnn mmmm 0111 1 comparison result + * CMP_GT Rm,Rn + */ +void sh_common_execution::CMPGT(uint32_t m, uint32_t n) +{ + if ((int32_t) m_sh2_state->r[n] > (int32_t) m_sh2_state->r[m]) + m_sh2_state->sr |= SH_T; + else + m_sh2_state->sr &= ~SH_T; +} + +/* code cycles t-bit + * 0011 nnnn mmmm 0110 1 comparison result + * CMP_HI Rm,Rn + */ +void sh_common_execution::CMPHI(uint32_t m, uint32_t n) +{ + if ((uint32_t) m_sh2_state->r[n] > (uint32_t) m_sh2_state->r[m]) + m_sh2_state->sr |= SH_T; + else + m_sh2_state->sr &= ~SH_T; +} + +/* code cycles t-bit + * 0011 nnnn mmmm 0010 1 comparison result + * CMP_HS Rm,Rn + */ +void sh_common_execution::CMPHS(uint32_t m, uint32_t n) +{ + if ((uint32_t) m_sh2_state->r[n] >= (uint32_t) m_sh2_state->r[m]) + m_sh2_state->sr |= SH_T; + else + m_sh2_state->sr &= ~SH_T; +} + +/* code cycles t-bit + * 0100 nnnn 0001 0101 1 comparison result + * CMP_PL Rn + */ +void sh_common_execution::CMPPL(uint32_t n) +{ + if ((int32_t) m_sh2_state->r[n] > 0) + m_sh2_state->sr |= SH_T; + else + m_sh2_state->sr &= ~SH_T; +} + +/* code cycles t-bit + * 0100 nnnn 0001 0001 1 comparison result + * CMP_PZ Rn + */ +void sh_common_execution::CMPPZ(uint32_t n) +{ + if ((int32_t) m_sh2_state->r[n] >= 0) + m_sh2_state->sr |= SH_T; + else + m_sh2_state->sr &= ~SH_T; +} + +/* code cycles t-bit + * 0010 nnnn mmmm 1100 1 comparison result + * CMP_STR Rm,Rn + */ +void sh_common_execution::CMPSTR(uint32_t m, uint32_t n) +{ + uint32_t temp; + int32_t HH, HL, LH, LL; + temp = m_sh2_state->r[n] ^ m_sh2_state->r[m]; + HH = (temp >> 24) & 0xff; + HL = (temp >> 16) & 0xff; + LH = (temp >> 8) & 0xff; + LL = temp & 0xff; + if (HH && HL && LH && LL) + m_sh2_state->sr &= ~SH_T; + else + m_sh2_state->sr |= SH_T; +} + +/* code cycles t-bit + * 1000 1000 iiii iiii 1 comparison result + * CMP/EQ #imm,R0 + */ +void sh_common_execution::CMPIM(uint32_t i) +{ + uint32_t imm = (uint32_t)(int32_t)(int16_t)(int8_t)i; + + if (m_sh2_state->r[0] == imm) + m_sh2_state->sr |= SH_T; + else + m_sh2_state->sr &= ~SH_T; +} + +/* code cycles t-bit + * 0010 nnnn mmmm 0111 1 calculation result + * DIV0S Rm,Rn + */ +void sh_common_execution::DIV0S(uint32_t m, uint32_t n) +{ + if ((m_sh2_state->r[n] & 0x80000000) == 0) + m_sh2_state->sr &= ~SH_Q; + else + m_sh2_state->sr |= SH_Q; + if ((m_sh2_state->r[m] & 0x80000000) == 0) + m_sh2_state->sr &= ~SH_M; + else + m_sh2_state->sr |= SH_M; + if ((m_sh2_state->r[m] ^ m_sh2_state->r[n]) & 0x80000000) + m_sh2_state->sr |= SH_T; + else + m_sh2_state->sr &= ~SH_T; +} + +/* code cycles t-bit + * 0000 0000 0001 1001 1 0 + * DIV0U + */ +void sh_common_execution::DIV0U() +{ + m_sh2_state->sr &= ~(SH_M | SH_Q | SH_T); +} + +/* code cycles t-bit + * 0011 nnnn mmmm 0100 1 calculation result + * DIV1 Rm,Rn + */ +void sh_common_execution::DIV1(uint32_t m, uint32_t n) +{ + uint32_t tmp0; + uint32_t old_q; + + old_q = m_sh2_state->sr & SH_Q; + if (0x80000000 & m_sh2_state->r[n]) + m_sh2_state->sr |= SH_Q; + else + m_sh2_state->sr &= ~SH_Q; + + m_sh2_state->r[n] = (m_sh2_state->r[n] << 1) | (m_sh2_state->sr & SH_T); + + if (!old_q) + { + if (!(m_sh2_state->sr & SH_M)) + { + tmp0 = m_sh2_state->r[n]; + m_sh2_state->r[n] -= m_sh2_state->r[m]; + if(!(m_sh2_state->sr & SH_Q)) + if(m_sh2_state->r[n] > tmp0) + m_sh2_state->sr |= SH_Q; + else + m_sh2_state->sr &= ~SH_Q; + else + if(m_sh2_state->r[n] > tmp0) + m_sh2_state->sr &= ~SH_Q; + else + m_sh2_state->sr |= SH_Q; + } + else + { + tmp0 = m_sh2_state->r[n]; + m_sh2_state->r[n] += m_sh2_state->r[m]; + if(!(m_sh2_state->sr & SH_Q)) + { + if(m_sh2_state->r[n] < tmp0) + m_sh2_state->sr &= ~SH_Q; + else + m_sh2_state->sr |= SH_Q; + } + else + { + if(m_sh2_state->r[n] < tmp0) + m_sh2_state->sr |= SH_Q; + else + m_sh2_state->sr &= ~SH_Q; + } + } + } + else + { + if (!(m_sh2_state->sr & SH_M)) + { + tmp0 = m_sh2_state->r[n]; + m_sh2_state->r[n] += m_sh2_state->r[m]; + if(!(m_sh2_state->sr & SH_Q)) + if(m_sh2_state->r[n] < tmp0) + m_sh2_state->sr |= SH_Q; + else + m_sh2_state->sr &= ~SH_Q; + else + if(m_sh2_state->r[n] < tmp0) + m_sh2_state->sr &= ~SH_Q; + else + m_sh2_state->sr |= SH_Q; + } + else + { + tmp0 = m_sh2_state->r[n]; + m_sh2_state->r[n] -= m_sh2_state->r[m]; + if(!(m_sh2_state->sr & SH_Q)) + if(m_sh2_state->r[n] > tmp0) + m_sh2_state->sr &= ~SH_Q; + else + m_sh2_state->sr |= SH_Q; + else + if(m_sh2_state->r[n] > tmp0) + m_sh2_state->sr |= SH_Q; + else + m_sh2_state->sr &= ~SH_Q; + } + } + + tmp0 = (m_sh2_state->sr & (SH_Q | SH_M)); + if((!tmp0) || (tmp0 == 0x300)) /* if Q == M set T else clear T */ + m_sh2_state->sr |= SH_T; + else + m_sh2_state->sr &= ~SH_T; +} + +/* DMULS.L Rm,Rn */ +void sh_common_execution::DMULS(uint32_t m, uint32_t n) +{ + uint32_t RnL, RnH, RmL, RmH, Res0, Res1, Res2; + uint32_t temp0, temp1, temp2, temp3; + int32_t tempm, tempn, fnLmL; + + tempn = (int32_t) m_sh2_state->r[n]; + tempm = (int32_t) m_sh2_state->r[m]; + if (tempn < 0) + tempn = 0 - tempn; + if (tempm < 0) + tempm = 0 - tempm; + if ((int32_t) (m_sh2_state->r[n] ^ m_sh2_state->r[m]) < 0) + fnLmL = -1; + else + fnLmL = 0; + temp1 = (uint32_t) tempn; + temp2 = (uint32_t) tempm; + RnL = temp1 & 0x0000ffff; + RnH = (temp1 >> 16) & 0x0000ffff; + RmL = temp2 & 0x0000ffff; + RmH = (temp2 >> 16) & 0x0000ffff; + temp0 = RmL * RnL; + temp1 = RmH * RnL; + temp2 = RmL * RnH; + temp3 = RmH * RnH; + Res2 = 0; + Res1 = temp1 + temp2; + if (Res1 < temp1) + Res2 += 0x00010000; + temp1 = (Res1 << 16) & 0xffff0000; + Res0 = temp0 + temp1; + if (Res0 < temp0) + Res2++; + Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3; + if (fnLmL < 0) + { + Res2 = ~Res2; + if (Res0 == 0) + Res2++; + else + Res0 = (~Res0) + 1; + } + m_sh2_state->mach = Res2; + m_sh2_state->macl = Res0; + m_sh2_state->icount--; +} + +/* DMULU.L Rm,Rn */ +void sh_common_execution::DMULU(uint32_t m, uint32_t n) +{ + uint32_t RnL, RnH, RmL, RmH, Res0, Res1, Res2; + uint32_t temp0, temp1, temp2, temp3; + + RnL = m_sh2_state->r[n] & 0x0000ffff; + RnH = (m_sh2_state->r[n] >> 16) & 0x0000ffff; + RmL = m_sh2_state->r[m] & 0x0000ffff; + RmH = (m_sh2_state->r[m] >> 16) & 0x0000ffff; + temp0 = RmL * RnL; + temp1 = RmH * RnL; + temp2 = RmL * RnH; + temp3 = RmH * RnH; + Res2 = 0; + Res1 = temp1 + temp2; + if (Res1 < temp1) + Res2 += 0x00010000; + temp1 = (Res1 << 16) & 0xffff0000; + Res0 = temp0 + temp1; + if (Res0 < temp0) + Res2++; + Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3; + m_sh2_state->mach = Res2; + m_sh2_state->macl = Res0; + m_sh2_state->icount--; +} + +/* DT Rn */ +void sh_common_execution::DT(uint32_t n) +{ + m_sh2_state->r[n]--; + if (m_sh2_state->r[n] == 0) + m_sh2_state->sr |= SH_T; + else + m_sh2_state->sr &= ~SH_T; +#if BUSY_LOOP_HACKS + { + uint32_t next_opcode = RW(m_sh2_state->pc & AM); + /* DT Rn + * BF $-2 + */ + if (next_opcode == 0x8bfd) + { + while (m_sh2_state->r[n] > 1 && m_sh2_state->icount > 4) + { + m_sh2_state->r[n]--; + m_sh2_state->icount -= 4; /* cycles for DT (1) and BF taken (3) */ + } + } + } +#endif +} + +/* EXTS.B Rm,Rn */ +void sh_common_execution::EXTSB(uint32_t m, uint32_t n) +{ + m_sh2_state->r[n] = ((int32_t)m_sh2_state->r[m] << 24) >> 24; +} + +/* EXTS.W Rm,Rn */ +void sh_common_execution::EXTSW(uint32_t m, uint32_t n) +{ + m_sh2_state->r[n] = ((int32_t)m_sh2_state->r[m] << 16) >> 16; +} + +/* EXTU.B Rm,Rn */ +void sh_common_execution::EXTUB(uint32_t m, uint32_t n) +{ + m_sh2_state->r[n] = m_sh2_state->r[m] & 0x000000ff; +} + +/* EXTU.W Rm,Rn */ +void sh_common_execution::EXTUW(uint32_t m, uint32_t n) +{ + m_sh2_state->r[n] = m_sh2_state->r[m] & 0x0000ffff; +} + +/* JMP @Rm */ +void sh_common_execution::JMP(uint32_t m) +{ + m_sh2_state->m_delay = m_sh2_state->ea = m_sh2_state->r[m]; + //m_sh2_state->icount--; // not in SH4 implementation? +} + +/* JSR @Rm */ +void sh_common_execution::JSR(uint32_t m) +{ + m_sh2_state->pr = m_sh2_state->pc + 2; + m_sh2_state->m_delay = m_sh2_state->ea = m_sh2_state->r[m]; + m_sh2_state->icount--; +} + +/* LDC Rm,GBR */ +void sh_common_execution::LDCGBR(uint32_t m) +{ + m_sh2_state->gbr = m_sh2_state->r[m]; +} + +/* LDC Rm,VBR */ +void sh_common_execution::LDCVBR(uint32_t m) +{ + m_sh2_state->vbr = m_sh2_state->r[m]; +} + +/* LDC.L @Rm+,GBR */ +void sh_common_execution::LDCMGBR(uint32_t m) +{ + m_sh2_state->ea = m_sh2_state->r[m]; + m_sh2_state->gbr = RL( m_sh2_state->ea ); + m_sh2_state->r[m] += 4; + m_sh2_state->icount -= 2; +} + +/* LDC.L @Rm+,VBR */ +void sh_common_execution::LDCMVBR(uint32_t m) +{ + m_sh2_state->ea = m_sh2_state->r[m]; + m_sh2_state->vbr = RL( m_sh2_state->ea ); + m_sh2_state->r[m] += 4; + m_sh2_state->icount -= 2; +} + +/* LDS Rm,MACH */ +void sh_common_execution::LDSMACH(uint32_t m) +{ + m_sh2_state->mach = m_sh2_state->r[m]; +} + +/* LDS Rm,MACL */ +void sh_common_execution::LDSMACL(uint32_t m) +{ + m_sh2_state->macl = m_sh2_state->r[m]; +} + +/* LDS Rm,PR */ +void sh_common_execution::LDSPR(uint32_t m) +{ + m_sh2_state->pr = m_sh2_state->r[m]; +} + +/* LDS.L @Rm+,MACH */ +void sh_common_execution::LDSMMACH(uint32_t m) +{ + m_sh2_state->ea = m_sh2_state->r[m]; + m_sh2_state->mach = RL( m_sh2_state->ea ); + m_sh2_state->r[m] += 4; +} + +/* LDS.L @Rm+,MACL */ +void sh_common_execution::LDSMMACL(uint32_t m) +{ + m_sh2_state->ea = m_sh2_state->r[m]; + m_sh2_state->macl = RL( m_sh2_state->ea ); + m_sh2_state->r[m] += 4; +} + +/* LDS.L @Rm+,PR */ +void sh_common_execution::LDSMPR(uint32_t m) +{ + m_sh2_state->ea = m_sh2_state->r[m]; + m_sh2_state->pr = RL( m_sh2_state->ea ); + m_sh2_state->r[m] += 4; +} + +/* MAC.L @Rm+,@Rn+ */ +void sh_common_execution::MAC_L(uint32_t m, uint32_t n) +{ + uint32_t RnL, RnH, RmL, RmH, Res0, Res1, Res2; + uint32_t temp0, temp1, temp2, temp3; + int32_t tempm, tempn, fnLmL; + + tempn = (int32_t) RL( m_sh2_state->r[n] ); + m_sh2_state->r[n] += 4; + tempm = (int32_t) RL( m_sh2_state->r[m] ); + m_sh2_state->r[m] += 4; + if ((int32_t) (tempn ^ tempm) < 0) + fnLmL = -1; + else + fnLmL = 0; + if (tempn < 0) + tempn = 0 - tempn; + if (tempm < 0) + tempm = 0 - tempm; + temp1 = (uint32_t) tempn; + temp2 = (uint32_t) tempm; + RnL = temp1 & 0x0000ffff; + RnH = (temp1 >> 16) & 0x0000ffff; + RmL = temp2 & 0x0000ffff; + RmH = (temp2 >> 16) & 0x0000ffff; + temp0 = RmL * RnL; + temp1 = RmH * RnL; + temp2 = RmL * RnH; + temp3 = RmH * RnH; + Res2 = 0; + Res1 = temp1 + temp2; + if (Res1 < temp1) + Res2 += 0x00010000; + temp1 = (Res1 << 16) & 0xffff0000; + Res0 = temp0 + temp1; + if (Res0 < temp0) + Res2++; + Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3; + if (fnLmL < 0) + { + Res2 = ~Res2; + if (Res0 == 0) + Res2++; + else + Res0 = (~Res0) + 1; + } + if (m_sh2_state->sr & SH_S) + { + Res0 = m_sh2_state->macl + Res0; + if (m_sh2_state->macl > Res0) + Res2++; + Res2 += (m_sh2_state->mach & 0x0000ffff); + if (((int32_t) Res2 < 0) && (Res2 < 0xffff8000)) + { + Res2 = 0x00008000; + Res0 = 0x00000000; + } + else if (((int32_t) Res2 > 0) && (Res2 > 0x00007fff)) + { + Res2 = 0x00007fff; + Res0 = 0xffffffff; + } + m_sh2_state->mach = Res2; + m_sh2_state->macl = Res0; + } + else + { + Res0 = m_sh2_state->macl + Res0; + if (m_sh2_state->macl > Res0) + Res2++; + Res2 += m_sh2_state->mach; + m_sh2_state->mach = Res2; + m_sh2_state->macl = Res0; + } + m_sh2_state->icount -= 2; +} + +/* MAC.W @Rm+,@Rn+ */ +void sh_common_execution::MAC_W(uint32_t m, uint32_t n) +{ + int32_t tempm, tempn, dest, src, ans; + uint32_t templ; + + tempn = (int32_t) RW( m_sh2_state->r[n] ); + m_sh2_state->r[n] += 2; + tempm = (int32_t) RW( m_sh2_state->r[m] ); + m_sh2_state->r[m] += 2; + templ = m_sh2_state->macl; + tempm = ((int32_t) (short) tempn * (int32_t) (short) tempm); + if ((int32_t) m_sh2_state->macl >= 0) + dest = 0; + else + dest = 1; + if ((int32_t) tempm >= 0) + { + src = 0; + tempn = 0; + } + else + { + src = 1; + tempn = 0xffffffff; + } + src += dest; + m_sh2_state->macl += tempm; + if ((int32_t) m_sh2_state->macl >= 0) + ans = 0; + else + ans = 1; + ans += dest; + if (m_sh2_state->sr & SH_S) + { + if (ans == 1) + { + if (src == 0) + m_sh2_state->macl = 0x7fffffff; + if (src == 2) + m_sh2_state->macl = 0x80000000; + } + } + else + { + m_sh2_state->mach += tempn; + if (templ > m_sh2_state->macl) + m_sh2_state->mach += 1; + } + m_sh2_state->icount -= 2; +} + +/* MOV Rm,Rn */ +void sh_common_execution::MOV(uint32_t m, uint32_t n) +{ + m_sh2_state->r[n] = m_sh2_state->r[m]; +} + +/* MOV.B Rm,@Rn */ +void sh_common_execution::MOVBS(uint32_t m, uint32_t n) +{ + m_sh2_state->ea = m_sh2_state->r[n]; + WB( m_sh2_state->ea, m_sh2_state->r[m] & 0x000000ff); +} + +/* MOV.W Rm,@Rn */ +void sh_common_execution::MOVWS(uint32_t m, uint32_t n) +{ + m_sh2_state->ea = m_sh2_state->r[n]; + WW( m_sh2_state->ea, m_sh2_state->r[m] & 0x0000ffff); +} + +/* MOV.L Rm,@Rn */ +void sh_common_execution::MOVLS(uint32_t m, uint32_t n) +{ + m_sh2_state->ea = m_sh2_state->r[n]; + WL( m_sh2_state->ea, m_sh2_state->r[m] ); +} + +/* MOV.B @Rm,Rn */ +void sh_common_execution::MOVBL(uint32_t m, uint32_t n) +{ + m_sh2_state->ea = m_sh2_state->r[m]; + m_sh2_state->r[n] = (uint32_t)(int32_t)(int16_t)(int8_t) RB( m_sh2_state->ea ); +} + +/* MOV.W @Rm,Rn */ +void sh_common_execution::MOVWL(uint32_t m, uint32_t n) +{ + m_sh2_state->ea = m_sh2_state->r[m]; + m_sh2_state->r[n] = (uint32_t)(int32_t)(int16_t) RW( m_sh2_state->ea ); +} + +/* MOV.L @Rm,Rn */ +void sh_common_execution::MOVLL(uint32_t m, uint32_t n) +{ + m_sh2_state->ea = m_sh2_state->r[m]; + m_sh2_state->r[n] = RL( m_sh2_state->ea ); +} + +/* MOV.B Rm,@-Rn */ +void sh_common_execution::MOVBM(uint32_t m, uint32_t n) +{ + /* SMG : bug fix, was reading m_sh2_state->r[n] */ + uint32_t data = m_sh2_state->r[m] & 0x000000ff; + + m_sh2_state->r[n] -= 1; + WB( m_sh2_state->r[n], data ); +} + +/* MOV.W Rm,@-Rn */ +void sh_common_execution::MOVWM(uint32_t m, uint32_t n) +{ + uint32_t data = m_sh2_state->r[m] & 0x0000ffff; + + m_sh2_state->r[n] -= 2; + WW( m_sh2_state->r[n], data ); +} + +/* MOV.L Rm,@-Rn */ +void sh_common_execution::MOVLM(uint32_t m, uint32_t n) +{ + uint32_t data = m_sh2_state->r[m]; + + m_sh2_state->r[n] -= 4; + WL( m_sh2_state->r[n], data ); +} + +/* MOV.B @Rm+,Rn */ +void sh_common_execution::MOVBP(uint32_t m, uint32_t n) +{ + m_sh2_state->r[n] = (uint32_t)(int32_t)(int16_t)(int8_t) RB( m_sh2_state->r[m] ); + if (n != m) + m_sh2_state->r[m] += 1; +} + +/* MOV.W @Rm+,Rn */ +void sh_common_execution::MOVWP(uint32_t m, uint32_t n) +{ + m_sh2_state->r[n] = (uint32_t)(int32_t)(int16_t) RW( m_sh2_state->r[m] ); + if (n != m) + m_sh2_state->r[m] += 2; +} + +/* MOV.L @Rm+,Rn */ +void sh_common_execution::MOVLP(uint32_t m, uint32_t n) +{ + m_sh2_state->r[n] = RL( m_sh2_state->r[m] ); + if (n != m) + m_sh2_state->r[m] += 4; +} + +/* MOV.B Rm,@(R0,Rn) */ +void sh_common_execution::MOVBS0(uint32_t m, uint32_t n) +{ + m_sh2_state->ea = m_sh2_state->r[n] + m_sh2_state->r[0]; + WB( m_sh2_state->ea, m_sh2_state->r[m] & 0x000000ff ); +} + +/* MOV.W Rm,@(R0,Rn) */ +void sh_common_execution::MOVWS0(uint32_t m, uint32_t n) +{ + m_sh2_state->ea = m_sh2_state->r[n] + m_sh2_state->r[0]; + WW( m_sh2_state->ea, m_sh2_state->r[m] & 0x0000ffff ); +} + +/* MOV.L Rm,@(R0,Rn) */ +void sh_common_execution::MOVLS0(uint32_t m, uint32_t n) +{ + m_sh2_state->ea = m_sh2_state->r[n] + m_sh2_state->r[0]; + WL( m_sh2_state->ea, m_sh2_state->r[m] ); +} + +/* MOV.B @(R0,Rm),Rn */ +void sh_common_execution::MOVBL0(uint32_t m, uint32_t n) +{ + m_sh2_state->ea = m_sh2_state->r[m] + m_sh2_state->r[0]; + m_sh2_state->r[n] = (uint32_t)(int32_t)(int16_t)(int8_t) RB( m_sh2_state->ea ); +} + +/* MOV.W @(R0,Rm),Rn */ +void sh_common_execution::MOVWL0(uint32_t m, uint32_t n) +{ + m_sh2_state->ea = m_sh2_state->r[m] + m_sh2_state->r[0]; + m_sh2_state->r[n] = (uint32_t)(int32_t)(int16_t) RW( m_sh2_state->ea ); +} + +/* MOV.L @(R0,Rm),Rn */ +void sh_common_execution::MOVLL0(uint32_t m, uint32_t n) +{ + m_sh2_state->ea = m_sh2_state->r[m] + m_sh2_state->r[0]; + m_sh2_state->r[n] = RL( m_sh2_state->ea ); +} + +/* MOV #imm,Rn */ +void sh_common_execution::MOVI(uint32_t i, uint32_t n) +{ + m_sh2_state->r[n] = (uint32_t)(int32_t)(int16_t)(int8_t) i; +} + +/* MOV.W @(disp8,PC),Rn */ +void sh_common_execution::MOVWI(uint32_t d, uint32_t n) +{ + uint32_t disp = d & 0xff; + m_sh2_state->ea = m_sh2_state->pc + disp * 2 + 2; + m_sh2_state->r[n] = (uint32_t)(int32_t)(int16_t) RW( m_sh2_state->ea ); +} + +/* MOV.L @(disp8,PC),Rn */ +void sh_common_execution::MOVLI(uint32_t d, uint32_t n) +{ + uint32_t disp = d & 0xff; + m_sh2_state->ea = ((m_sh2_state->pc + 2) & ~3) + disp * 4; + m_sh2_state->r[n] = RL( m_sh2_state->ea ); +} + +/* MOV.B @(disp8,GBR),R0 */ +void sh_common_execution::MOVBLG(uint32_t d) +{ + uint32_t disp = d & 0xff; + m_sh2_state->ea = m_sh2_state->gbr + disp; + m_sh2_state->r[0] = (uint32_t)(int32_t)(int16_t)(int8_t) RB( m_sh2_state->ea ); +} + +/* MOV.W @(disp8,GBR),R0 */ +void sh_common_execution::MOVWLG(uint32_t d) +{ + uint32_t disp = d & 0xff; + m_sh2_state->ea = m_sh2_state->gbr + disp * 2; + m_sh2_state->r[0] = (int32_t)(int16_t) RW( m_sh2_state->ea ); +} + +/* MOV.L @(disp8,GBR),R0 */ +void sh_common_execution::MOVLLG(uint32_t d) +{ + uint32_t disp = d & 0xff; + m_sh2_state->ea = m_sh2_state->gbr + disp * 4; + m_sh2_state->r[0] = RL( m_sh2_state->ea ); +} + +/* MOV.B R0,@(disp8,GBR) */ +void sh_common_execution::MOVBSG(uint32_t d) +{ + uint32_t disp = d & 0xff; + m_sh2_state->ea = m_sh2_state->gbr + disp; + WB( m_sh2_state->ea, m_sh2_state->r[0] & 0x000000ff ); +} + +/* MOV.W R0,@(disp8,GBR) */ +void sh_common_execution::MOVWSG(uint32_t d) +{ + uint32_t disp = d & 0xff; + m_sh2_state->ea = m_sh2_state->gbr + disp * 2; + WW( m_sh2_state->ea, m_sh2_state->r[0] & 0x0000ffff ); +} + +/* MOV.L R0,@(disp8,GBR) */ +void sh_common_execution::MOVLSG(uint32_t d) +{ + uint32_t disp = d & 0xff; + m_sh2_state->ea = m_sh2_state->gbr + disp * 4; + WL( m_sh2_state->ea, m_sh2_state->r[0] ); +} + +/* MOV.B R0,@(disp4,Rn) */ +void sh_common_execution::MOVBS4(uint32_t d, uint32_t n) +{ + uint32_t disp = d & 0x0f; + m_sh2_state->ea = m_sh2_state->r[n] + disp; + WB( m_sh2_state->ea, m_sh2_state->r[0] & 0x000000ff ); +} + +/* MOV.W R0,@(disp4,Rn) */ +void sh_common_execution::MOVWS4(uint32_t d, uint32_t n) +{ + uint32_t disp = d & 0x0f; + m_sh2_state->ea = m_sh2_state->r[n] + disp * 2; + WW( m_sh2_state->ea, m_sh2_state->r[0] & 0x0000ffff ); +} + +/* MOV.L Rm,@(disp4,Rn) */ +void sh_common_execution::MOVLS4(uint32_t m, uint32_t d, uint32_t n) +{ + uint32_t disp = d & 0x0f; + m_sh2_state->ea = m_sh2_state->r[n] + disp * 4; + WL( m_sh2_state->ea, m_sh2_state->r[m] ); +} + +/* MOV.B @(disp4,Rm),R0 */ +void sh_common_execution::MOVBL4(uint32_t m, uint32_t d) +{ + uint32_t disp = d & 0x0f; + m_sh2_state->ea = m_sh2_state->r[m] + disp; + m_sh2_state->r[0] = (uint32_t)(int32_t)(int16_t)(int8_t) RB( m_sh2_state->ea ); +} + +/* MOV.W @(disp4,Rm),R0 */ +void sh_common_execution::MOVWL4(uint32_t m, uint32_t d) +{ + uint32_t disp = d & 0x0f; + m_sh2_state->ea = m_sh2_state->r[m] + disp * 2; + m_sh2_state->r[0] = (uint32_t)(int32_t)(int16_t) RW( m_sh2_state->ea ); +} + +/* MOV.L @(disp4,Rm),Rn */ +void sh_common_execution::MOVLL4(uint32_t m, uint32_t d, uint32_t n) +{ + uint32_t disp = d & 0x0f; + m_sh2_state->ea = m_sh2_state->r[m] + disp * 4; + m_sh2_state->r[n] = RL( m_sh2_state->ea ); +} + +/* MOVA @(disp8,PC),R0 */ +void sh_common_execution::MOVA(uint32_t d) +{ + uint32_t disp = d & 0xff; + m_sh2_state->ea = ((m_sh2_state->pc + 2) & ~3) + disp * 4; + m_sh2_state->r[0] = m_sh2_state->ea; +} + +/* MOVT Rn */ +void sh_common_execution::MOVT(uint32_t n) +{ + m_sh2_state->r[n] = m_sh2_state->sr & SH_T; +} + +/* MUL.L Rm,Rn */ +void sh_common_execution::MULL(uint32_t m, uint32_t n) +{ + m_sh2_state->macl = m_sh2_state->r[n] * m_sh2_state->r[m]; + m_sh2_state->icount--; +} + +/* MULS Rm,Rn */ +void sh_common_execution::MULS(uint32_t m, uint32_t n) +{ + m_sh2_state->macl = (int16_t) m_sh2_state->r[n] * (int16_t) m_sh2_state->r[m]; +} + +/* MULU Rm,Rn */ +void sh_common_execution::MULU(uint32_t m, uint32_t n) +{ + m_sh2_state->macl = (uint16_t) m_sh2_state->r[n] * (uint16_t) m_sh2_state->r[m]; +} + +/* NEG Rm,Rn */ +void sh_common_execution::NEG(uint32_t m, uint32_t n) +{ + m_sh2_state->r[n] = 0 - m_sh2_state->r[m]; +} + +/* NEGC Rm,Rn */ +void sh_common_execution::NEGC(uint32_t m, uint32_t n) +{ + uint32_t temp; + + temp = m_sh2_state->r[m]; + m_sh2_state->r[n] = -temp - (m_sh2_state->sr & SH_T); + if (temp || (m_sh2_state->sr & SH_T)) + m_sh2_state->sr |= SH_T; + else + m_sh2_state->sr &= ~SH_T; +} + +/* NOP */ +void sh_common_execution::NOP(void) +{ +} + +/* NOT Rm,Rn */ +void sh_common_execution::NOT(uint32_t m, uint32_t n) +{ + m_sh2_state->r[n] = ~m_sh2_state->r[m]; +} + +/* OR Rm,Rn */ +void sh_common_execution::OR(uint32_t m, uint32_t n) +{ + m_sh2_state->r[n] |= m_sh2_state->r[m]; +} + +/* OR #imm,R0 */ +void sh_common_execution::ORI(uint32_t i) +{ + m_sh2_state->r[0] |= i; + m_sh2_state->icount -= 2; // not in SH2 implementation? +} + +/* OR.B #imm,@(R0,GBR) */ +void sh_common_execution::ORM(uint32_t i) +{ + uint32_t temp; + + m_sh2_state->ea = m_sh2_state->gbr + m_sh2_state->r[0]; + temp = RB( m_sh2_state->ea ); + temp |= i; + WB( m_sh2_state->ea, temp ); + //m_sh2_state->icount -= 2; // not in SH4 implementation? +} + +/* ROTCL Rn */ +void sh_common_execution::ROTCL(uint32_t n) +{ + uint32_t temp; + + temp = (m_sh2_state->r[n] >> 31) & SH_T; + m_sh2_state->r[n] = (m_sh2_state->r[n] << 1) | (m_sh2_state->sr & SH_T); + m_sh2_state->sr = (m_sh2_state->sr & ~SH_T) | temp; +} + +/* ROTCR Rn */ +void sh_common_execution::ROTCR(uint32_t n) +{ + uint32_t temp; + temp = (m_sh2_state->sr & SH_T) << 31; + if (m_sh2_state->r[n] & SH_T) + m_sh2_state->sr |= SH_T; + else + m_sh2_state->sr &= ~SH_T; + m_sh2_state->r[n] = (m_sh2_state->r[n] >> 1) | temp; +} + +/* ROTL Rn */ +void sh_common_execution::ROTL(uint32_t n) +{ + m_sh2_state->sr = (m_sh2_state->sr & ~SH_T) | ((m_sh2_state->r[n] >> 31) & SH_T); + m_sh2_state->r[n] = (m_sh2_state->r[n] << 1) | (m_sh2_state->r[n] >> 31); +} + +/* ROTR Rn */ +void sh_common_execution::ROTR(uint32_t n) +{ + m_sh2_state->sr = (m_sh2_state->sr & ~SH_T) | (m_sh2_state->r[n] & SH_T); + m_sh2_state->r[n] = (m_sh2_state->r[n] >> 1) | (m_sh2_state->r[n] << 31); +} + +/* RTS */ +void sh_common_execution::RTS() +{ + m_sh2_state->m_delay = m_sh2_state->ea = m_sh2_state->pr; + m_sh2_state->icount--; +} + +/* SETT */ +void sh_common_execution::SETT() +{ + m_sh2_state->sr |= SH_T; +} + +/* SHAL Rn (same as SHLL) */ +void sh_common_execution::SHAL(uint32_t n) +{ + m_sh2_state->sr = (m_sh2_state->sr & ~SH_T) | ((m_sh2_state->r[n] >> 31) & SH_T); + m_sh2_state->r[n] <<= 1; +} + +/* SHAR Rn */ +void sh_common_execution::SHAR(uint32_t n) +{ + m_sh2_state->sr = (m_sh2_state->sr & ~SH_T) | (m_sh2_state->r[n] & SH_T); + m_sh2_state->r[n] = (uint32_t)((int32_t)m_sh2_state->r[n] >> 1); +} + +/* SHLL Rn (same as SHAL) */ +void sh_common_execution::SHLL(uint32_t n) +{ + m_sh2_state->sr = (m_sh2_state->sr & ~SH_T) | ((m_sh2_state->r[n] >> 31) & SH_T); + m_sh2_state->r[n] <<= 1; +} + +/* SHLL2 Rn */ +void sh_common_execution::SHLL2(uint32_t n) +{ + m_sh2_state->r[n] <<= 2; +} + +/* SHLL8 Rn */ +void sh_common_execution::SHLL8(uint32_t n) +{ + m_sh2_state->r[n] <<= 8; +} + +/* SHLL16 Rn */ +void sh_common_execution::SHLL16(uint32_t n) +{ + m_sh2_state->r[n] <<= 16; +} + +/* SHLR Rn */ +void sh_common_execution::SHLR(uint32_t n) +{ + m_sh2_state->sr = (m_sh2_state->sr & ~SH_T) | (m_sh2_state->r[n] & SH_T); + m_sh2_state->r[n] >>= 1; +} + +/* SHLR2 Rn */ +void sh_common_execution::SHLR2(uint32_t n) +{ + m_sh2_state->r[n] >>= 2; +} + +/* SHLR8 Rn */ +void sh_common_execution::SHLR8(uint32_t n) +{ + m_sh2_state->r[n] >>= 8; +} + +/* SHLR16 Rn */ +void sh_common_execution::SHLR16(uint32_t n) +{ + m_sh2_state->r[n] >>= 16; +} + + +/* STC SR,Rn */ +void sh_common_execution::STCSR(uint32_t n) +{ + m_sh2_state->r[n] = m_sh2_state->sr; +} + +/* STC GBR,Rn */ +void sh_common_execution::STCGBR(uint32_t n) +{ + m_sh2_state->r[n] = m_sh2_state->gbr; +} + +/* STC VBR,Rn */ +void sh_common_execution::STCVBR(uint32_t n) +{ + m_sh2_state->r[n] = m_sh2_state->vbr; +} + +/* STC.L SR,@-Rn */ +void sh_common_execution::STCMSR(uint32_t n) +{ + m_sh2_state->r[n] -= 4; + m_sh2_state->ea = m_sh2_state->r[n]; + WL( m_sh2_state->ea, m_sh2_state->sr ); + m_sh2_state->icount--; +} + +/* STC.L GBR,@-Rn */ +void sh_common_execution::STCMGBR(uint32_t n) +{ + m_sh2_state->r[n] -= 4; + m_sh2_state->ea = m_sh2_state->r[n]; + WL( m_sh2_state->ea, m_sh2_state->gbr ); + m_sh2_state->icount--; +} + +/* STC.L VBR,@-Rn */ +void sh_common_execution::STCMVBR(uint32_t n) +{ + m_sh2_state->r[n] -= 4; + m_sh2_state->ea = m_sh2_state->r[n]; + WL( m_sh2_state->ea, m_sh2_state->vbr ); + m_sh2_state->icount--; +} + +/* STS MACH,Rn */ +void sh_common_execution::STSMACH(uint32_t n) +{ + m_sh2_state->r[n] = m_sh2_state->mach; +} + +/* STS MACL,Rn */ +void sh_common_execution::STSMACL(uint32_t n) +{ + m_sh2_state->r[n] = m_sh2_state->macl; +} + +/* STS PR,Rn */ +void sh_common_execution::STSPR(uint32_t n) +{ + m_sh2_state->r[n] = m_sh2_state->pr; +} + +/* STS.L MACH,@-Rn */ +void sh_common_execution::STSMMACH(uint32_t n) +{ + m_sh2_state->r[n] -= 4; + m_sh2_state->ea = m_sh2_state->r[n]; + WL( m_sh2_state->ea, m_sh2_state->mach ); +} + +/* STS.L MACL,@-Rn */ +void sh_common_execution::STSMMACL(uint32_t n) +{ + m_sh2_state->r[n] -= 4; + m_sh2_state->ea = m_sh2_state->r[n]; + WL( m_sh2_state->ea, m_sh2_state->macl ); +} + +/* STS.L PR,@-Rn */ +void sh_common_execution::STSMPR(uint32_t n) +{ + m_sh2_state->r[n] -= 4; + m_sh2_state->ea = m_sh2_state->r[n]; + WL( m_sh2_state->ea, m_sh2_state->pr ); +} + +/* SUB Rm,Rn */ +void sh_common_execution::SUB(uint32_t m, uint32_t n) +{ + m_sh2_state->r[n] -= m_sh2_state->r[m]; +} + +/* SUBC Rm,Rn */ +void sh_common_execution::SUBC(uint32_t m, uint32_t n) +{ + uint32_t tmp0, tmp1; + + tmp1 = m_sh2_state->r[n] - m_sh2_state->r[m]; + tmp0 = m_sh2_state->r[n]; + m_sh2_state->r[n] = tmp1 - (m_sh2_state->sr & SH_T); + if (tmp0 < tmp1) + m_sh2_state->sr |= SH_T; + else + m_sh2_state->sr &= ~SH_T; + if (tmp1 < m_sh2_state->r[n]) + m_sh2_state->sr |= SH_T; +} + +/* SUBV Rm,Rn */ +void sh_common_execution::SUBV(uint32_t m, uint32_t n) +{ + int32_t dest, src, ans; + + if ((int32_t) m_sh2_state->r[n] >= 0) + dest = 0; + else + dest = 1; + if ((int32_t) m_sh2_state->r[m] >= 0) + src = 0; + else + src = 1; + src += dest; + m_sh2_state->r[n] -= m_sh2_state->r[m]; + if ((int32_t) m_sh2_state->r[n] >= 0) + ans = 0; + else + ans = 1; + ans += dest; + if (src == 1) + { + if (ans == 1) + m_sh2_state->sr |= SH_T; + else + m_sh2_state->sr &= ~SH_T; + } + else + m_sh2_state->sr &= ~SH_T; +} + +/* SWAP.B Rm,Rn */ +void sh_common_execution::SWAPB(uint32_t m, uint32_t n) +{ + uint32_t temp0, temp1; + + temp0 = m_sh2_state->r[m] & 0xffff0000; + temp1 = (m_sh2_state->r[m] & 0x000000ff) << 8; + m_sh2_state->r[n] = (m_sh2_state->r[m] >> 8) & 0x000000ff; + m_sh2_state->r[n] = m_sh2_state->r[n] | temp1 | temp0; +} + +/* SWAP.W Rm,Rn */ +void sh_common_execution::SWAPW(uint32_t m, uint32_t n) +{ + uint32_t temp; + + temp = (m_sh2_state->r[m] >> 16) & 0x0000ffff; + m_sh2_state->r[n] = (m_sh2_state->r[m] << 16) | temp; +} + +/* TAS.B @Rn */ +void sh_common_execution::TAS(uint32_t n) +{ + uint32_t temp; + m_sh2_state->ea = m_sh2_state->r[n]; + /* Bus Lock enable */ + temp = RB( m_sh2_state->ea ); + if (temp == 0) + m_sh2_state->sr |= SH_T; + else + m_sh2_state->sr &= ~SH_T; + temp |= 0x80; + /* Bus Lock disable */ + WB( m_sh2_state->ea, temp ); + m_sh2_state->icount -= 3; +} + +/* TST Rm,Rn */ +void sh_common_execution::TST(uint32_t m, uint32_t n) +{ + if ((m_sh2_state->r[n] & m_sh2_state->r[m]) == 0) + m_sh2_state->sr |= SH_T; + else + m_sh2_state->sr &= ~SH_T; +} + +/* TST #imm,R0 */ +void sh_common_execution::TSTI(uint32_t i) +{ + uint32_t imm = i & 0xff; + + if ((imm & m_sh2_state->r[0]) == 0) + m_sh2_state->sr |= SH_T; + else + m_sh2_state->sr &= ~SH_T; +} + +/* TST.B #imm,@(R0,GBR) */ +void sh_common_execution::TSTM(uint32_t i) +{ + uint32_t imm = i & 0xff; + + m_sh2_state->ea = m_sh2_state->gbr + m_sh2_state->r[0]; + if ((imm & RB( m_sh2_state->ea )) == 0) + m_sh2_state->sr |= SH_T; + else + m_sh2_state->sr &= ~SH_T; + m_sh2_state->icount -= 2; +} + +/* XOR Rm,Rn */ +void sh_common_execution::XOR(uint32_t m, uint32_t n) +{ + m_sh2_state->r[n] ^= m_sh2_state->r[m]; +} + +/* XOR #imm,R0 */ +void sh_common_execution::XORI(uint32_t i) +{ + uint32_t imm = i & 0xff; + m_sh2_state->r[0] ^= imm; +} + +/* XOR.B #imm,@(R0,GBR) */ +void sh_common_execution::XORM(uint32_t i) +{ + uint32_t imm = i & 0xff; + uint32_t temp; + + m_sh2_state->ea = m_sh2_state->gbr + m_sh2_state->r[0]; + temp = RB( m_sh2_state->ea ); + temp ^= imm; + WB( m_sh2_state->ea, temp ); + m_sh2_state->icount -= 2; +} + +/* XTRCT Rm,Rn */ +void sh_common_execution::XTRCT(uint32_t m, uint32_t n) +{ + uint32_t temp; + + temp = (m_sh2_state->r[m] << 16) & 0xffff0000; + m_sh2_state->r[n] = (m_sh2_state->r[n] >> 16) & 0x0000ffff; + m_sh2_state->r[n] |= temp; +} + +/* SLEEP */ +void sh_common_execution::SLEEP() +{ + /* 0 = normal mode */ + /* 1 = enters into power-down mode */ + /* 2 = go out the power-down mode after an exception */ + if(m_sh2_state->sleep_mode != 2) + m_sh2_state->pc -= 2; + m_sh2_state->icount -= 2; + /* Wait_for_exception; */ + if(m_sh2_state->sleep_mode == 0) + m_sh2_state->sleep_mode = 1; + else if(m_sh2_state->sleep_mode == 2) + m_sh2_state->sleep_mode = 0; +} + +/* Common dispatch */ + +void sh_common_execution::op0010(uint16_t opcode) +{ + switch (opcode & 15) + { + case 0: MOVBS(Rm, Rn); break; + case 1: MOVWS(Rm, Rn); break; + case 2: MOVLS(Rm, Rn); break; + case 3: ILLEGAL(); break; + case 4: MOVBM(Rm, Rn); break; + case 5: MOVWM(Rm, Rn); break; + case 6: MOVLM(Rm, Rn); break; + case 7: DIV0S(Rm, Rn); break; + case 8: TST(Rm, Rn); break; + case 9: AND(Rm, Rn); break; + case 10: XOR(Rm, Rn); break; + case 11: OR(Rm, Rn); break; + case 12: CMPSTR(Rm, Rn); break; + case 13: XTRCT(Rm, Rn); break; + case 14: MULU(Rm, Rn); break; + case 15: MULS(Rm, Rn); break; + } +} + +void sh_common_execution::op0011(uint16_t opcode) +{ + switch (opcode & 15) + { + case 0: CMPEQ(Rm, Rn); break; + case 1: ILLEGAL(); break; + case 2: CMPHS(Rm, Rn); break; + case 3: CMPGE(Rm, Rn); break; + case 4: DIV1(Rm, Rn); break; + case 5: DMULU(Rm, Rn); break; + case 6: CMPHI(Rm, Rn); break; + case 7: CMPGT(Rm, Rn); break; + case 8: SUB(Rm, Rn); break; + case 9: ILLEGAL(); break; + case 10: SUBC(Rm, Rn); break; + case 11: SUBV(Rm, Rn); break; + case 12: ADD(Rm, Rn); break; + case 13: DMULS(Rm, Rn); break; + case 14: ADDC(Rm, Rn); break; + case 15: ADDV(Rm, Rn); break; + } +} + +void sh_common_execution::op0110(uint16_t opcode) +{ + switch (opcode & 15) + { + case 0: MOVBL(Rm, Rn); break; + case 1: MOVWL(Rm, Rn); break; + case 2: MOVLL(Rm, Rn); break; + case 3: MOV(Rm, Rn); break; + case 4: MOVBP(Rm, Rn); break; + case 5: MOVWP(Rm, Rn); break; + case 6: MOVLP(Rm, Rn); break; + case 7: NOT(Rm, Rn); break; + case 8: SWAPB(Rm, Rn); break; + case 9: SWAPW(Rm, Rn); break; + case 10: NEGC(Rm, Rn); break; + case 11: NEG(Rm, Rn); break; + case 12: EXTUB(Rm, Rn); break; + case 13: EXTUW(Rm, Rn); break; + case 14: EXTSB(Rm, Rn); break; + case 15: EXTSW(Rm, Rn); break; + } +} + +void sh_common_execution::op1000(uint16_t opcode) +{ + switch ( opcode & (15<<8) ) + { + case 0 << 8: MOVBS4(opcode & 0x0f, Rm); break; + case 1 << 8: MOVWS4(opcode & 0x0f, Rm); break; + case 2<< 8: ILLEGAL(); break; + case 3<< 8: ILLEGAL(); break; + case 4<< 8: MOVBL4(Rm, opcode & 0x0f); break; + case 5<< 8: MOVWL4(Rm, opcode & 0x0f); break; + case 6<< 8: ILLEGAL(); break; + case 7<< 8: ILLEGAL(); break; + case 8<< 8: CMPIM(opcode & 0xff); break; + case 9<< 8: BT(opcode & 0xff); break; + case 10<< 8: ILLEGAL(); break; + case 11<< 8: BF(opcode & 0xff); break; + case 12<< 8: ILLEGAL(); break; + case 13<< 8: BTS(opcode & 0xff); break; + case 14<< 8: ILLEGAL(); break; + case 15<< 8: BFS(opcode & 0xff); break; + } +} + + +void sh_common_execution::op1100(uint16_t opcode) +{ + switch (opcode & (15<<8)) + { + case 0<<8: MOVBSG(opcode & 0xff); break; + case 1<<8: MOVWSG(opcode & 0xff); break; + case 2<<8: MOVLSG(opcode & 0xff); break; + case 3<<8: TRAPA(opcode & 0xff); break; // sh2/4 differ + case 4<<8: MOVBLG(opcode & 0xff); break; + case 5<<8: MOVWLG(opcode & 0xff); break; + case 6<<8: MOVLLG(opcode & 0xff); break; + case 7<<8: MOVA(opcode & 0xff); break; + case 8<<8: TSTI(opcode & 0xff); break; + case 9<<8: ANDI(opcode & 0xff); break; + case 10<<8: XORI(opcode & 0xff); break; + case 11<<8: ORI(opcode & 0xff); break; + case 12<<8: TSTM(opcode & 0xff); break; + case 13<<8: ANDM(opcode & 0xff); break; + case 14<<8: XORM(opcode & 0xff); break; + case 15<<8: ORM(opcode & 0xff); break; + } +} + +// SH4 cases fall through to here too +void sh_common_execution::execute_one_0000(uint16_t opcode) +{ + // 04,05,06,07 always the same, 0c,0d,0e,0f always the same, other change based on upper bits + + switch (opcode & 0x3F) + { + case 0x00: ILLEGAL(); break; + case 0x01: ILLEGAL(); break; + case 0x02: STCSR(Rn); break; + case 0x03: BSRF(Rn); break; + case 0x04: MOVBS0(Rm, Rn); break; + case 0x05: MOVWS0(Rm, Rn); break; + case 0x06: MOVLS0(Rm, Rn); break; + case 0x07: MULL(Rm, Rn); break; + case 0x08: CLRT(); break; + case 0x09: NOP(); break; + case 0x0a: STSMACH(Rn); break; + case 0x0b: RTS(); break; + case 0x0c: MOVBL0(Rm, Rn); break; + case 0x0d: MOVWL0(Rm, Rn); break; + case 0x0e: MOVLL0(Rm, Rn); break; + case 0x0f: MAC_L(Rm, Rn); break; + + case 0x10: ILLEGAL(); break; + case 0x11: ILLEGAL(); break; + case 0x12: STCGBR(Rn); break; + case 0x13: ILLEGAL(); break; + case 0x14: MOVBS0(Rm, Rn); break; + case 0x15: MOVWS0(Rm, Rn); break; + case 0x16: MOVLS0(Rm, Rn); break; + case 0x17: MULL(Rm, Rn); break; + case 0x18: SETT(); break; + case 0x19: DIV0U(); break; + case 0x1a: STSMACL(Rn); break; + case 0x1b: SLEEP(); break; + case 0x1c: MOVBL0(Rm, Rn); break; + case 0x1d: MOVWL0(Rm, Rn); break; + case 0x1e: MOVLL0(Rm, Rn); break; + case 0x1f: MAC_L(Rm, Rn); break; + + case 0x20: ILLEGAL(); break; + case 0x21: ILLEGAL(); break; + case 0x22: STCVBR(Rn); break; + case 0x23: BRAF(Rn); break; + case 0x24: MOVBS0(Rm, Rn); break; + case 0x25: MOVWS0(Rm, Rn); break; + case 0x26: MOVLS0(Rm, Rn); break; + case 0x27: MULL(Rm, Rn); break; + case 0x28: CLRMAC(); break; + case 0x29: MOVT(Rn); break; + case 0x2a: STSPR(Rn); break; + case 0x2b: RTE(); break; + case 0x2c: MOVBL0(Rm, Rn); break; + case 0x2d: MOVWL0(Rm, Rn); break; + case 0x2e: MOVLL0(Rm, Rn); break; + case 0x2f: MAC_L(Rm, Rn); break; + + case 0x30: ILLEGAL(); break; + case 0x31: ILLEGAL(); break; + case 0x32: ILLEGAL(); break; + case 0x33: ILLEGAL(); break; + case 0x34: MOVBS0(Rm, Rn); break; + case 0x35: MOVWS0(Rm, Rn); break; + case 0x36: MOVLS0(Rm, Rn); break; + case 0x37: MULL(Rm, Rn); break; + case 0x38: ILLEGAL(); break; + case 0x39: ILLEGAL(); break; + case 0x3a: ILLEGAL(); break; + case 0x3b: ILLEGAL(); break; + case 0x3c: MOVBL0(Rm, Rn); break; + case 0x3d: MOVWL0(Rm, Rn); break; + case 0x3e: MOVLL0(Rm, Rn); break; + case 0x3f: MAC_L(Rm, Rn); break; + } +} + +// SH4 cases fall through to here too +void sh_common_execution::execute_one_4000(uint16_t opcode) +{ + // 0f always the same, others differ + + switch (opcode & 0x3F) + { + case 0x00: SHLL(Rn); break; + case 0x01: SHLR(Rn); break; + case 0x02: STSMMACH(Rn); break; + case 0x03: STCMSR(Rn); break; + case 0x04: ROTL(Rn); break; + case 0x05: ROTR(Rn); break; + case 0x06: LDSMMACH(Rn); break; + case 0x07: LDCMSR(opcode); break; + case 0x08: SHLL2(Rn); break; + case 0x09: SHLR2(Rn); break; + case 0x0a: LDSMACH(Rn); break; + case 0x0b: JSR(Rn); break; + case 0x0c: ILLEGAL(); break; + case 0x0d: ILLEGAL(); break; + case 0x0e: LDCSR(opcode); break; + case 0x0f: MAC_W(Rm, Rn); break; + + case 0x10: DT(Rn); break; + case 0x11: CMPPZ(Rn); break; + case 0x12: STSMMACL(Rn); break; + case 0x13: STCMGBR(Rn); break; + case 0x14: ILLEGAL(); break; + case 0x15: CMPPL(Rn); break; + case 0x16: LDSMMACL(Rn); break; + case 0x17: LDCMGBR(Rn); break; + case 0x18: SHLL8(Rn); break; + case 0x19: SHLR8(Rn); break; + case 0x1a: LDSMACL(Rn); break; + case 0x1b: TAS(Rn); break; + case 0x1c: ILLEGAL(); break; + case 0x1d: ILLEGAL(); break; + case 0x1e: LDCGBR(Rn); break; + case 0x1f: MAC_W(Rm, Rn); break; + + case 0x20: SHAL(Rn); break; + case 0x21: SHAR(Rn); break; + case 0x22: STSMPR(Rn); break; + case 0x23: STCMVBR(Rn); break; + case 0x24: ROTCL(Rn); break; + case 0x25: ROTCR(Rn); break; + case 0x26: LDSMPR(Rn); break; + case 0x27: LDCMVBR(Rn); break; + case 0x28: SHLL16(Rn); break; + case 0x29: SHLR16(Rn); break; + case 0x2a: LDSPR(Rn); break; + case 0x2b: JMP(Rn); break; + case 0x2c: ILLEGAL(); break; + case 0x2d: ILLEGAL(); break; + case 0x2e: LDCVBR(Rn); break; + case 0x2f: MAC_W(Rm, Rn); break; + + case 0x30: ILLEGAL(); break; + case 0x31: ILLEGAL(); break; + case 0x32: ILLEGAL(); break; + case 0x33: ILLEGAL(); break; + case 0x34: ILLEGAL(); break; + case 0x35: ILLEGAL(); break; + case 0x36: ILLEGAL(); break; + case 0x37: ILLEGAL(); break; + case 0x38: ILLEGAL(); break; + case 0x39: ILLEGAL(); break; + case 0x3a: ILLEGAL(); break; + case 0x3b: ILLEGAL(); break; + case 0x3c: ILLEGAL(); break; + case 0x3d: ILLEGAL(); break; + case 0x3e: ILLEGAL(); break; + case 0x3f: MAC_W(Rm, Rn); break; + + } +} + +void sh_common_execution::execute_one(const uint16_t opcode) +{ + switch(opcode & 0xf000) + { + case 0x0000: execute_one_0000(opcode); break; + case 0x1000: MOVLS4(Rm, opcode & 0x0f, Rn); break; + case 0x2000: op0010(opcode); break; + case 0x3000: op0011(opcode); break; + case 0x4000: execute_one_4000(opcode); break; + case 0x5000: MOVLL4(Rm, opcode & 0x0f, Rn); break; + case 0x6000: op0110(opcode); break; + case 0x7000: ADDI(opcode & 0xff, Rn); break; + case 0x8000: op1000(opcode); break; + case 0x9000: MOVWI(opcode & 0xff, Rn); break; + case 0xa000: BRA(opcode & 0xfff); break; + case 0xb000: BSR(opcode & 0xfff); break; + case 0xc000: op1100(opcode); break; + case 0xd000: MOVLI(opcode & 0xff, Rn); break; + case 0xe000: MOVI(opcode & 0xff, Rn); break; + case 0xf000: execute_one_f000(opcode); break; + } +} + +// DRC / UML related +void cfunc_unimplemented(void *param) { ((sh_common_execution *)param)->func_unimplemented(); } +void cfunc_MAC_W(void *param) { ((sh_common_execution *)param)->func_MAC_W(); } +void cfunc_MAC_L(void *param) { ((sh_common_execution *)param)->func_MAC_L(); } +void cfunc_DIV1(void *param) { ((sh_common_execution *)param)->func_DIV1(); } +void cfunc_ADDV(void *param) { ((sh_common_execution *)param)->func_ADDV(); } +void cfunc_SUBV(void *param) { ((sh_common_execution *)param)->func_SUBV(); } +void cfunc_printf_probe(void *param) { ((sh_common_execution *)param)->func_printf_probe(); } + +/*------------------------------------------------- + sh2drc_add_fastram - add a new fastram + region +-------------------------------------------------*/ + +void sh_common_execution::sh2drc_add_fastram(offs_t start, offs_t end, uint8_t readonly, void *base) +{ + if (m_fastram_select < ARRAY_LENGTH(m_fastram)) + { + m_fastram[m_fastram_select].start = start; + m_fastram[m_fastram_select].end = end; + m_fastram[m_fastram_select].readonly = readonly; + m_fastram[m_fastram_select].base = base; + m_fastram_select++; + } +} + +using namespace uml; + +/*************************************************************************** + INLINE FUNCTIONS +***************************************************************************/ + +/*------------------------------------------------- + epc - compute the exception PC from a + descriptor +-------------------------------------------------*/ + +uint32_t sh_common_execution::epc(const opcode_desc *desc) +{ + return (desc->flags & OPFLAG_IN_DELAY_SLOT) ? (desc->pc - 1) : desc->pc; +} + +/*------------------------------------------------- + alloc_handle - allocate a handle if not + already allocated +-------------------------------------------------*/ + +void sh_common_execution::alloc_handle(drcuml_state *drcuml, code_handle **handleptr, const char *name) +{ + if (*handleptr == nullptr) + *handleptr = drcuml->handle_alloc(name); +} + +/*------------------------------------------------- + load_fast_iregs - load any fast integer + registers +-------------------------------------------------*/ + +void sh_common_execution::load_fast_iregs(drcuml_block *block) +{ + int regnum; + + for (regnum = 0; regnum < ARRAY_LENGTH(m_regmap); regnum++) + { + if (m_regmap[regnum].is_int_register()) + { + UML_MOV(block, uml::parameter::make_ireg(m_regmap[regnum].ireg()), mem(&m_sh2_state->r[regnum])); + } + } +} + + +/*------------------------------------------------- + save_fast_iregs - save any fast integer + registers +-------------------------------------------------*/ + +void sh_common_execution::save_fast_iregs(drcuml_block *block) +{ + int regnum; + + for (regnum = 0; regnum < ARRAY_LENGTH(m_regmap); regnum++) + { + if (m_regmap[regnum].is_int_register()) + { + UML_MOV(block, mem(&m_sh2_state->r[regnum]), uml::parameter::make_ireg(m_regmap[regnum].ireg())); + } + } +} + + +/*------------------------------------------------- + log_desc_flags_to_string - generate a string + representing the instruction description + flags +-------------------------------------------------*/ + +const char *sh_common_execution::log_desc_flags_to_string(uint32_t flags) +{ + static char tempbuf[30]; + char *dest = tempbuf; + + /* branches */ + if (flags & OPFLAG_IS_UNCONDITIONAL_BRANCH) + *dest++ = 'U'; + else if (flags & OPFLAG_IS_CONDITIONAL_BRANCH) + *dest++ = 'C'; + else + *dest++ = '.'; + + /* intrablock branches */ + *dest++ = (flags & OPFLAG_INTRABLOCK_BRANCH) ? 'i' : '.'; + + /* branch targets */ + *dest++ = (flags & OPFLAG_IS_BRANCH_TARGET) ? 'B' : '.'; + + /* delay slots */ + *dest++ = (flags & OPFLAG_IN_DELAY_SLOT) ? 'D' : '.'; + + /* exceptions */ + if (flags & OPFLAG_WILL_CAUSE_EXCEPTION) + *dest++ = 'E'; + else if (flags & OPFLAG_CAN_CAUSE_EXCEPTION) + *dest++ = 'e'; + else + *dest++ = '.'; + + /* read/write */ + if (flags & OPFLAG_READS_MEMORY) + *dest++ = 'R'; + else if (flags & OPFLAG_WRITES_MEMORY) + *dest++ = 'W'; + else + *dest++ = '.'; + + /* TLB validation */ + *dest++ = (flags & OPFLAG_VALIDATE_TLB) ? 'V' : '.'; + + /* TLB modification */ + *dest++ = (flags & OPFLAG_MODIFIES_TRANSLATION) ? 'T' : '.'; + + /* redispatch */ + *dest++ = (flags & OPFLAG_REDISPATCH) ? 'R' : '.'; + return tempbuf; +} + + +/*------------------------------------------------- + log_register_list - log a list of GPR registers +-------------------------------------------------*/ + +void sh_common_execution::log_register_list(drcuml_state *drcuml, const char *string, const uint32_t *reglist, const uint32_t *regnostarlist) +{ + int count = 0; + int regnum; + + /* skip if nothing */ + if (reglist[0] == 0 && reglist[1] == 0 && reglist[2] == 0) + return; + + drcuml->log_printf("[%s:", string); + + for (regnum = 0; regnum < 16; regnum++) + { + if (reglist[0] & REGFLAG_R(regnum)) + { + drcuml->log_printf("%sr%d", (count++ == 0) ? "" : ",", regnum); + if (regnostarlist != nullptr && !(regnostarlist[0] & REGFLAG_R(regnum))) + drcuml->log_printf("*"); + } + } + + if (reglist[1] & REGFLAG_PR) + { + drcuml->log_printf("%spr", (count++ == 0) ? "" : ","); + if (regnostarlist != nullptr && !(regnostarlist[1] & REGFLAG_PR)) + drcuml->log_printf("*"); + } + + if (reglist[1] & REGFLAG_SR) + { + drcuml->log_printf("%ssr", (count++ == 0) ? "" : ","); + if (regnostarlist != nullptr && !(regnostarlist[1] & REGFLAG_SR)) + drcuml->log_printf("*"); + } + + if (reglist[1] & REGFLAG_MACL) + { + drcuml->log_printf("%smacl", (count++ == 0) ? "" : ","); + if (regnostarlist != nullptr && !(regnostarlist[1] & REGFLAG_MACL)) + drcuml->log_printf("*"); + } + + if (reglist[1] & REGFLAG_MACH) + { + drcuml->log_printf("%smach", (count++ == 0) ? "" : ","); + if (regnostarlist != nullptr && !(regnostarlist[1] & REGFLAG_MACH)) + drcuml->log_printf("*"); + } + + if (reglist[1] & REGFLAG_GBR) + { + drcuml->log_printf("%sgbr", (count++ == 0) ? "" : ","); + if (regnostarlist != nullptr && !(regnostarlist[1] & REGFLAG_GBR)) + drcuml->log_printf("*"); + } + + if (reglist[1] & REGFLAG_VBR) + { + drcuml->log_printf("%svbr", (count++ == 0) ? "" : ","); + if (regnostarlist != nullptr && !(regnostarlist[1] & REGFLAG_VBR)) + drcuml->log_printf("*"); + } + + drcuml->log_printf("] "); +} + +/*------------------------------------------------- + log_opcode_desc - log a list of descriptions +-------------------------------------------------*/ + +void sh_common_execution::log_opcode_desc(drcuml_state *drcuml, const opcode_desc *desclist, int indent) +{ + /* open the file, creating it if necessary */ + if (indent == 0) + drcuml->log_printf("\nDescriptor list @ %08X\n", desclist->pc); + + /* output each descriptor */ + for ( ; desclist != nullptr; desclist = desclist->next()) + { + std::ostringstream stream; + + /* disassemle the current instruction and output it to the log */ + if (drcuml->logging() || drcuml->logging_native()) + { + if (desclist->flags & OPFLAG_VIRTUAL_NOOP) + stream << "<virtual nop>"; + else + { + sh_disassembler sh2d(false); + sh2d.dasm_one(stream, desclist->pc, desclist->opptr.w[0]); + } + } + else + stream << "???"; + drcuml->log_printf("%08X [%08X] t:%08X f:%s: %-30s", desclist->pc, desclist->physpc, desclist->targetpc, log_desc_flags_to_string(desclist->flags), stream.str().c_str()); + + /* output register states */ + log_register_list(drcuml, "use", desclist->regin, nullptr); + log_register_list(drcuml, "mod", desclist->regout, desclist->regreq); + drcuml->log_printf("\n"); + + /* if we have a delay slot, output it recursively */ + if (desclist->delay.first() != nullptr) + log_opcode_desc(drcuml, desclist->delay.first(), indent + 1); + + /* at the end of a sequence add a dividing line */ + if (desclist->flags & OPFLAG_END_SEQUENCE) + drcuml->log_printf("-----\n"); + } +} + +/*------------------------------------------------- + log_add_disasm_comment - add a comment + including disassembly of an SH2 instruction +-------------------------------------------------*/ + +void sh_common_execution::log_add_disasm_comment(drcuml_block *block, uint32_t pc, uint32_t op) +{ + if (m_drcuml->logging()) + { + sh_disassembler sh2d(false); + std::ostringstream stream; + sh2d.dasm_one(stream, pc, op); + block->append_comment("%08X: %s", pc, stream.str().c_str()); + } +} + + +/*------------------------------------------------- + code_flush_cache - flush the cache and + regenerate static code +-------------------------------------------------*/ + +void sh_common_execution::code_flush_cache() +{ + drcuml_state *drcuml = m_drcuml.get(); + + /* empty the transient cache contents */ + drcuml->reset(); + + try + { + /* generate the entry point and out-of-cycles handlers */ + static_generate_nocode_handler(); + static_generate_out_of_cycles(); + static_generate_entry_point(); + + /* add subroutines for memory accesses */ + static_generate_memory_accessor(1, false, "read8", &m_read8); + static_generate_memory_accessor(1, true, "write8", &m_write8); + static_generate_memory_accessor(2, false, "read16", &m_read16); + static_generate_memory_accessor(2, true, "write16", &m_write16); + static_generate_memory_accessor(4, false, "read32", &m_read32); + static_generate_memory_accessor(4, true, "write32", &m_write32); + } + catch (drcuml_block::abort_compilation &) + { + fatalerror("Unable to generate SH2 static code\n"); + } + + m_cache_dirty = false; +} + +/* Execute cycles - returns number of cycles actually run */ +void sh_common_execution::execute_run_drc() +{ + drcuml_state *drcuml = m_drcuml.get(); + int execute_result; + + /* reset the cache if dirty */ + if (m_cache_dirty) + code_flush_cache(); + + /* execute */ + do + { + /* run as much as we can */ + execute_result = drcuml->execute(*m_entry); + + /* if we need to recompile, do it */ + if (execute_result == EXECUTE_MISSING_CODE) + { + code_compile_block(0, m_sh2_state->pc); + } + else if (execute_result == EXECUTE_UNMAPPED_CODE) + { + fatalerror("Attempted to execute unmapped code at PC=%08X\n", m_sh2_state->pc); + } + else if (execute_result == EXECUTE_RESET_CACHE) + { + code_flush_cache(); + } + } while (execute_result != EXECUTE_OUT_OF_CYCLES); +} + + +/*------------------------------------------------- + code_compile_block - compile a block of the + given mode at the specified pc +-------------------------------------------------*/ + +void sh_common_execution::code_compile_block(uint8_t mode, offs_t pc) +{ + drcuml_state *drcuml = m_drcuml.get(); + compiler_state compiler = { 0 }; + const opcode_desc *seqhead, *seqlast; + const opcode_desc *desclist; + bool override = false; + drcuml_block *block; + + g_profiler.start(PROFILER_DRC_COMPILE); + + /* get a description of this sequence */ + desclist = get_desclist(pc); + + if (drcuml->logging() || drcuml->logging_native()) + log_opcode_desc(drcuml, desclist, 0); + + bool succeeded = false; + while (!succeeded) + { + try + { + /* start the block */ + block = drcuml->begin_block(4096); + + /* loop until we get through all instruction sequences */ + for (seqhead = desclist; seqhead != nullptr; seqhead = seqlast->next()) + { + const opcode_desc *curdesc; + uint32_t nextpc; + + /* add a code log entry */ + if (drcuml->logging()) + block->append_comment("-------------------------"); // comment + + /* determine the last instruction in this sequence */ + for (seqlast = seqhead; seqlast != nullptr; seqlast = seqlast->next()) + if (seqlast->flags & OPFLAG_END_SEQUENCE) + break; + assert(seqlast != nullptr); + + /* if we don't have a hash for this mode/pc, or if we are overriding all, add one */ + if (override || !drcuml->hash_exists(mode, seqhead->pc)) + UML_HASH(block, mode, seqhead->pc); // hash mode,pc + + /* if we already have a hash, and this is the first sequence, assume that we */ + /* are recompiling due to being out of sync and allow future overrides */ + else if (seqhead == desclist) + { + override = true; + UML_HASH(block, mode, seqhead->pc); // hash mode,pc + } + + /* otherwise, redispatch to that fixed PC and skip the rest of the processing */ + else + { + UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc | 0x80000000 + UML_HASHJMP(block, 0, seqhead->pc, *m_nocode); + // hashjmp <mode>,seqhead->pc,nocode + continue; + } + + /* validate this code block if we're not pointing into ROM */ + if (m_program->get_write_ptr(seqhead->physpc) != nullptr) + generate_checksum_block(block, &compiler, seqhead, seqlast); + + /* label this instruction, if it may be jumped to locally */ + if (seqhead->flags & OPFLAG_IS_BRANCH_TARGET) + { + UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc | 0x80000000 + } + + /* iterate over instructions in the sequence and compile them */ + for (curdesc = seqhead; curdesc != seqlast->next(); curdesc = curdesc->next()) + { + generate_sequence_instruction(block, &compiler, curdesc, 0xffffffff); + } + + /* if we need to return to the start, do it */ + if (seqlast->flags & OPFLAG_RETURN_TO_START) + { + nextpc = pc; + } + /* otherwise we just go to the next instruction */ + else + { + nextpc = seqlast->pc + (seqlast->skipslots + 1) * 2; + } + + /* count off cycles and go there */ + generate_update_cycles(block, &compiler, nextpc, true); // <subtract cycles> + + /* SH2 has no modes */ + if (seqlast->next() == nullptr || seqlast->next()->pc != nextpc) + { + UML_HASHJMP(block, 0, nextpc, *m_nocode); + } + // hashjmp <mode>,nextpc,nocode + } + + /* end the sequence */ + block->end(); + g_profiler.stop(); + succeeded = true; + } + catch (drcuml_block::abort_compilation &) + { + code_flush_cache(); + } + } +} + + +/*------------------------------------------------- + static_generate_nocode_handler - generate an + exception handler for "out of code" +-------------------------------------------------*/ + +void sh_common_execution::static_generate_nocode_handler() +{ + drcuml_state *drcuml = m_drcuml.get(); + drcuml_block *block; + + /* begin generating */ + block = drcuml->begin_block(10); + + /* generate a hash jump via the current mode and PC */ + alloc_handle(drcuml, &m_nocode, "nocode"); + UML_HANDLE(block, *m_nocode); // handle nocode + UML_GETEXP(block, I0); // getexp i0 + UML_MOV(block, mem(&m_sh2_state->pc), I0); // mov [pc],i0 + save_fast_iregs(block); + UML_EXIT(block, EXECUTE_MISSING_CODE); // exit EXECUTE_MISSING_CODE + + block->end(); +} + + +/*------------------------------------------------- + static_generate_out_of_cycles - generate an + out of cycles exception handler +-------------------------------------------------*/ + +void sh_common_execution::static_generate_out_of_cycles() +{ + drcuml_state *drcuml = m_drcuml.get(); + drcuml_block *block; + + /* begin generating */ + block = drcuml->begin_block(10); + + /* generate a hash jump via the current mode and PC */ + alloc_handle(drcuml, &m_out_of_cycles, "out_of_cycles"); + UML_HANDLE(block, *m_out_of_cycles); // handle out_of_cycles + UML_GETEXP(block, I0); // getexp i0 + UML_MOV(block, mem(&m_sh2_state->pc), I0); // mov <pc>,i0 + save_fast_iregs(block); + UML_EXIT(block, EXECUTE_OUT_OF_CYCLES); // exit EXECUTE_OUT_OF_CYCLES + + block->end(); +} + +/*------------------------------------------------- + generate_checksum_block - generate code to + validate a sequence of opcodes +-------------------------------------------------*/ + +void sh_common_execution::generate_checksum_block(drcuml_block *block, compiler_state *compiler, const opcode_desc *seqhead, const opcode_desc *seqlast) +{ + const opcode_desc *curdesc; + if (m_drcuml->logging()) + block->append_comment("[Validation for %08X]", seqhead->pc); // comment + + /* loose verify or single instruction: just compare and fail */ + if (!(m_drcoptions & SH2DRC_STRICT_VERIFY) || seqhead->next() == nullptr) + { + if (!(seqhead->flags & OPFLAG_VIRTUAL_NOOP)) + { + void *base; + if (m_xor == 0) base = m_direct->read_ptr(seqhead->physpc, SH2_CODE_XOR(0)); + else if (m_xor == 1) base = m_direct->read_ptr(seqhead->physpc, SH34LE_CODE_XOR(0)); + else base = m_direct->read_ptr(seqhead->physpc, SH34BE_CODE_XOR(0)); + + UML_LOAD(block, I0, base, 0, SIZE_WORD, SCALE_x2); // load i0,base,word + UML_CMP(block, I0, seqhead->opptr.w[0]); // cmp i0,*opptr + UML_EXHc(block, COND_NE, *m_nocode, epc(seqhead)); // exne nocode,seqhead->pc + } + } + + /* full verification; sum up everything */ + else + { + uint32_t sum = 0; + void *base; + if (m_xor == 0) base = m_direct->read_ptr(seqhead->physpc, SH2_CODE_XOR(0)); + else if (m_xor == 1) base = m_direct->read_ptr(seqhead->physpc, SH34LE_CODE_XOR(0)); + else base = m_direct->read_ptr(seqhead->physpc, SH34BE_CODE_XOR(0)); + + UML_LOAD(block, I0, base, 0, SIZE_WORD, SCALE_x4); // load i0,base,word + sum += seqhead->opptr.w[0]; + for (curdesc = seqhead->next(); curdesc != seqlast->next(); curdesc = curdesc->next()) + if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP)) + { + if (m_xor == 0) base = m_direct->read_ptr(curdesc->physpc, SH2_CODE_XOR(0)); + else if (m_xor == 1) base = m_direct->read_ptr(curdesc->physpc, SH34LE_CODE_XOR(0)); + else base = m_direct->read_ptr(curdesc->physpc, SH34BE_CODE_XOR(0)); + + UML_LOAD(block, I1, base, 0, SIZE_WORD, SCALE_x2); // load i1,*opptr,word + UML_ADD(block, I0, I0, I1); // add i0,i0,i1 + sum += curdesc->opptr.w[0]; + } + UML_CMP(block, I0, sum); // cmp i0,sum + UML_EXHc(block, COND_NE, *m_nocode, epc(seqhead)); // exne nocode,seqhead->pc + } +} + + + +/*------------------------------------------------- + generate_sequence_instruction - generate code + for a single instruction in a sequence +-------------------------------------------------*/ + +void sh_common_execution::generate_sequence_instruction(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint32_t ovrpc) +{ + offs_t expc; + + /* add an entry for the log */ + if (m_drcuml->logging() && !(desc->flags & OPFLAG_VIRTUAL_NOOP)) + log_add_disasm_comment(block, desc->pc, desc->opptr.w[0]); + + /* set the PC map variable */ + expc = (desc->flags & OPFLAG_IN_DELAY_SLOT) ? desc->pc - 1 : desc->pc; + UML_MAPVAR(block, MAPVAR_PC, expc); // mapvar PC,expc + + /* accumulate total cycles */ + compiler->cycles += desc->cycles; + + /* update the icount map variable */ + UML_MAPVAR(block, MAPVAR_CYCLES, compiler->cycles); // mapvar CYCLES,compiler->cycles + + /* if we want a probe, add it here */ + if (desc->pc == PROBE_ADDRESS) + { + UML_MOV(block, mem(&m_sh2_state->pc), desc->pc); // mov [pc],desc->pc + UML_CALLC(block, cfunc_printf_probe, this); // callc cfunc_printf_probe,sh2 + } + + /* if we are debugging, call the debugger */ + if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0) + { + UML_MOV(block, mem(&m_sh2_state->pc), desc->pc); // mov [pc],desc->pc + save_fast_iregs(block); + UML_DEBUG(block, desc->pc); // debug desc->pc + } + else // not debug, see what other reasons there are for flushing the PC + { + if (m_drcoptions & SH2DRC_FLUSH_PC) // always flush? + { + UML_MOV(block, mem(&m_sh2_state->pc), desc->pc); // mov m_sh2_state->pc, desc->pc + } + else // check for driver-selected flushes + { + int pcflush; + + for (pcflush = 0; pcflush < m_pcfsel; pcflush++) + { + if (desc->pc == m_pcflushes[pcflush]) + { + UML_MOV(block, mem(&m_sh2_state->pc), desc->pc); // mov m_sh2_state->pc, desc->pc + } + } + } + } + + + /* if we hit an unmapped address, fatal error */ + if (desc->flags & OPFLAG_COMPILER_UNMAPPED) + { + UML_MOV(block, mem(&m_sh2_state->pc), desc->pc); // mov [pc],desc->pc + save_fast_iregs(block); + UML_EXIT(block, EXECUTE_UNMAPPED_CODE); // exit EXECUTE_UNMAPPED_CODE + } + + /* if this is an invalid opcode, die */ + if (desc->flags & OPFLAG_INVALID_OPCODE) + { + fatalerror("SH2DRC: invalid opcode!\n"); + } + + /* otherwise, unless this is a virtual no-op, it's a regular instruction */ + else if (!(desc->flags & OPFLAG_VIRTUAL_NOOP)) + { + /* compile the instruction */ + if (!generate_opcode(block, compiler, desc, ovrpc)) + { + // handle an illegal op + UML_MOV(block, mem(&m_sh2_state->pc), desc->pc); // mov [pc],desc->pc + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); // mov [arg0],opcode + UML_CALLC(block, cfunc_unimplemented, this); // callc cfunc_unimplemented + } + } +} + +/*------------------------------------------------------------------ + generate_delay_slot +------------------------------------------------------------------*/ + +void sh_common_execution::generate_delay_slot(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint32_t ovrpc) +{ + compiler_state compiler_temp = *compiler; + + /* compile the delay slot using temporary compiler state */ + assert(desc->delay.first() != nullptr); + generate_sequence_instruction(block, &compiler_temp, desc->delay.first(), ovrpc); // <next instruction> + + /* update the label */ + compiler->labelnum = compiler_temp.labelnum; +} + +void sh_common_execution::func_unimplemented() +{ + // set up an invalid opcode exception + m_sh2_state->evec = RL( m_sh2_state->vbr + 4 * 4 ); + m_sh2_state->evec &= m_am; + m_sh2_state->irqsr = m_sh2_state->sr; + // claim it's an NMI, because it pretty much is + m_sh2_state->pending_nmi = 1; +} + +void sh_common_execution::func_MAC_W() +{ + uint16_t opcode; + int n, m; + + // recover the opcode + opcode = m_sh2_state->arg0; + + // extract the operands + n = Rn; + m = Rm; + + MAC_W(m, n); +} + + +void sh_common_execution::func_MAC_L() +{ + uint16_t opcode; + int n, m; + + // recover the opcode + opcode = m_sh2_state->arg0; + + // extract the operands + n = Rn; + m = Rm; + + MAC_L(m, n); +} + + +void sh_common_execution::func_DIV1() +{ + uint16_t opcode; + int n, m; + + // recover the opcode + opcode = m_sh2_state->arg0; + + // extract the operands + n = Rn; + m = Rm; + + DIV1(m, n); +} + + +void sh_common_execution::func_ADDV() +{ + uint16_t opcode; + int n, m; + + // recover the opcode + opcode = m_sh2_state->arg0; + + // extract the operands + n = Rn; + m = Rm; + + ADDV(m, n); +} + + +void sh_common_execution::func_SUBV() +{ + uint16_t opcode; + int n, m; + + // recover the opcode + opcode = m_sh2_state->arg0; + + // extract the operands + n = Rn; + m = Rm; + + SUBV(m, n); +} + + +void sh_common_execution::func_printf_probe() +{ + uint32_t pc = m_sh2_state->pc; + + printf(" PC=%08X r0=%08X r1=%08X r2=%08X\n", + pc, + (uint32_t)m_sh2_state->r[0], + (uint32_t)m_sh2_state->r[1], + (uint32_t)m_sh2_state->r[2]); + printf(" r3=%08X r4=%08X r5=%08X r6=%08X\n", + (uint32_t)m_sh2_state->r[3], + (uint32_t)m_sh2_state->r[4], + (uint32_t)m_sh2_state->r[5], + (uint32_t)m_sh2_state->r[6]); + printf(" r7=%08X r8=%08X r9=%08X r10=%08X\n", + (uint32_t)m_sh2_state->r[7], + (uint32_t)m_sh2_state->r[8], + (uint32_t)m_sh2_state->r[9], + (uint32_t)m_sh2_state->r[10]); + printf(" r11=%08X r12=%08X r13=%08X r14=%08X\n", + (uint32_t)m_sh2_state->r[11], + (uint32_t)m_sh2_state->r[12], + (uint32_t)m_sh2_state->r[13], + (uint32_t)m_sh2_state->r[14]); + printf(" r15=%08X macl=%08X mach=%08X gbr=%08X\n", + (uint32_t)m_sh2_state->r[15], + (uint32_t)m_sh2_state->macl, + (uint32_t)m_sh2_state->mach, + (uint32_t)m_sh2_state->gbr); + printf(" evec %x irqsr %x pc=%08x\n", + (uint32_t)m_sh2_state->evec, + (uint32_t)m_sh2_state->irqsr, (uint32_t)m_sh2_state->pc); +} + +/*------------------------------------------------- + generate_opcode - generate code for a specific + opcode +-------------------------------------------------*/ + +bool sh_common_execution::generate_opcode(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint32_t ovrpc) +{ + uint32_t scratch, scratch2; + int32_t disp; + uint16_t opcode = desc->opptr.w[0]; + uint8_t opswitch = opcode >> 12; + int in_delay_slot = ((desc->flags & OPFLAG_IN_DELAY_SLOT) != 0); + + //printf("generating %04x\n", opcode); + + switch (opswitch) + { + case 0: + return generate_group_0(block, compiler, desc, opcode, in_delay_slot, ovrpc); + + case 1: // MOVLS4 + scratch = (opcode & 0x0f) * 4; + UML_ADD(block, I0, R32(Rn), scratch); // add r0, Rn, scratch + UML_MOV(block, I1, R32(Rm)); // mov r1, Rm + SETEA(0); // set ea for debug + UML_CALLH(block, *m_write32); + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 2: + return generate_group_2(block, compiler, desc, opcode, in_delay_slot, ovrpc); + case 3: + return generate_group_3(block, compiler, desc, opcode, ovrpc); + case 4: + return generate_group_4(block, compiler, desc, opcode, in_delay_slot, ovrpc); + + case 5: // MOVLL4 + scratch = (opcode & 0x0f) * 4; + UML_ADD(block, I0, R32(Rm), scratch); // add r0, Rm, scratch + SETEA(0); // set ea for debug + UML_CALLH(block, *m_read32); // call read32 + UML_MOV(block, R32(Rn), I0); // mov Rn, r0 + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 6: + return generate_group_6(block, compiler, desc, opcode, in_delay_slot, ovrpc); + + case 7: // ADDI + scratch = opcode & 0xff; + scratch2 = (uint32_t)(int32_t)(int16_t)(int8_t)scratch; + UML_ADD(block, R32(Rn), R32(Rn), scratch2); // add Rn, Rn, scratch2 + return true; + + case 8: + return generate_group_8(block, compiler, desc, opcode, in_delay_slot, ovrpc); + + case 9: // MOVWI + if (ovrpc == 0xffffffff) + { + scratch = (desc->pc + 2) + ((opcode & 0xff) * 2) + 2; + } + else + { + scratch = (ovrpc + 2) + ((opcode & 0xff) * 2) + 2; + } + + if (m_drcoptions & SH2DRC_STRICT_PCREL) + { + UML_MOV(block, I0, scratch); // mov r0, scratch + SETEA(0); // set ea for debug + UML_CALLH(block, *m_read16); // read16(r0, r1) + UML_SEXT(block, R32(Rn), I0, SIZE_WORD); // sext Rn, r0, WORD + } + else + { + scratch2 = (uint32_t)(int32_t)(int16_t) RW(scratch); + UML_MOV(block, R32(Rn), scratch2); // mov Rn, scratch2 + } + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 10: // BRA + disp = ((int32_t)opcode << 20) >> 20; + m_sh2_state->ea = (desc->pc + 2) + disp * 2 + 2; // m_sh2_state->ea = pc+4 + disp*2 + 2 + + generate_delay_slot(block, compiler, desc, m_sh2_state->ea-2); + + generate_update_cycles(block, compiler, m_sh2_state->ea, true); // <subtract cycles> + UML_HASHJMP(block, 0, m_sh2_state->ea, *m_nocode); // hashjmp m_sh2_state->ea + return true; + + case 11: // BSR + // panicstr @ 403da22 relies on the delay slot clobbering the PR set by a BSR, so + // do this before running the delay slot + UML_ADD(block, mem(&m_sh2_state->pr), desc->pc, 4); // add m_pr, desc->pc, #4 (skip the current insn & delay slot) + + disp = ((int32_t)opcode << 20) >> 20; + m_sh2_state->ea = (desc->pc + 2) + disp * 2 + 2; // m_sh2_state->ea = pc+4 + disp*2 + 2 + + generate_delay_slot(block, compiler, desc, m_sh2_state->ea-2); + + generate_update_cycles(block, compiler, m_sh2_state->ea, true); // <subtract cycles> + UML_HASHJMP(block, 0, m_sh2_state->ea, *m_nocode); // hashjmp m_sh2_state->ea + return true; + + case 12: + return generate_group_12(block, compiler, desc, opcode, in_delay_slot, ovrpc); + + case 13: // MOVLI + if (ovrpc == 0xffffffff) + { + scratch = ((desc->pc + 4) & ~3) + ((opcode & 0xff) * 4); + } + else + { + scratch = ((ovrpc + 4) & ~3) + ((opcode & 0xff) * 4); + } + + if (m_drcoptions & SH2DRC_STRICT_PCREL) + { + UML_MOV(block, I0, scratch); // mov r0, scratch + UML_CALLH(block, *m_read32); // read32(r0, r1) + UML_MOV(block, R32(Rn), I0); // mov Rn, r0 + } + else + { + scratch2 = RL(scratch); + UML_MOV(block, R32(Rn), scratch2); // mov Rn, scratch2 + } + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 14: // MOVI + scratch = opcode & 0xff; + scratch2 = (uint32_t)(int32_t)(int16_t)(int8_t)scratch; + UML_MOV(block, R32(Rn), scratch2); + return true; + + case 15: + return generate_group_15(block, compiler, desc, opcode, in_delay_slot, ovrpc); + } + + return false; +} + +bool sh_common_execution::generate_group_15(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + // no ops here on sh1/2 + return false; +} + +bool sh_common_execution::generate_group_2(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + switch (opcode & 15) + { + case 0: // MOVBS(Rm, Rn); + UML_MOV(block, I0, R32(Rn)); // mov r0, Rn + UML_AND(block, I1, R32(Rm), 0xff); // and r1, Rm, 0xff + UML_CALLH(block, *m_write8); + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 1: // MOVWS(Rm, Rn); + UML_MOV(block, I0, R32(Rn)); // mov r0, Rn + UML_AND(block, I1, R32(Rm), 0xffff); // and r1, Rm, 0xffff + UML_CALLH(block, *m_write16); + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 2: // MOVLS(Rm, Rn); + UML_MOV(block, I0, R32(Rn)); // mov r0, Rn + UML_MOV(block, I1, R32(Rm)); // mov r1, Rm + UML_CALLH(block, *m_write32); + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 3: + return false; + + case 4: // MOVBM(Rm, Rn); + UML_MOV(block, I1, R32(Rm)); // mov r1, Rm + UML_SUB(block, R32(Rn), R32(Rn), 1); // sub Rn, Rn, 1 + UML_MOV(block, I0, R32(Rn)); // mov r0, Rn + UML_CALLH(block, *m_write8); // call write8 + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 5: // MOVWM(Rm, Rn); + UML_MOV(block, I1, R32(Rm)); // mov r1, Rm + UML_SUB(block, R32(Rn), R32(Rn), 2); // sub Rn, Rn, 2 + UML_MOV(block, I0, R32(Rn)); // mov r0, Rn + UML_CALLH(block, *m_write16); // call write16 + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 6: // MOVLM(Rm, Rn); + UML_MOV(block, I1, R32(Rm)); // mov r1, Rm + UML_SUB(block, R32(Rn), R32(Rn), 4); // sub Rn, Rn, 4 + UML_MOV(block, I0, R32(Rn)); // mov r0, Rn + UML_CALLH(block, *m_write32); // call write32 + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 13: // XTRCT(Rm, Rn); + UML_SHL(block, I0, R32(Rm), 16); // shl r0, Rm, #16 + UML_AND(block, I0, I0, 0xffff0000); // and r0, r0, #0xffff0000 + + UML_SHR(block, I1, R32(Rn), 16); // shr, r1, Rn, #16 + UML_AND(block, I1, I1, 0xffff); // and r1, r1, #0x0000ffff + + UML_OR(block, R32(Rn), I0, I1); // or Rn, r0, r1 + return true; + + case 7: // DIV0S(Rm, Rn); + UML_MOV(block, I0, mem(&m_sh2_state->sr)); // move r0, sr + UML_AND(block, I0, I0, ~(SH_Q|SH_M|SH_T)); // and r0, r0, ~(Q|M|T) (clear the Q,M, and T bits) + + UML_TEST(block, R32(Rn), 0x80000000); // test Rn, #0x80000000 + UML_JMPc(block, COND_Z, compiler->labelnum); // jz labelnum + + UML_OR(block, I0, I0, SH_Q); // or r0, r0, Q + UML_LABEL(block, compiler->labelnum++); // labelnum: + + UML_TEST(block, R32(Rm), 0x80000000); // test Rm, #0x80000000 + UML_JMPc(block, COND_Z, compiler->labelnum); // jz labelnum + + UML_OR(block, I0, I0, SH_M); // or r0, r0, M + UML_LABEL(block, compiler->labelnum++); // labelnum: + + UML_XOR(block, I1, R32(Rn), R32(Rm)); // xor r1, Rn, Rm + UML_TEST(block, I1, 0x80000000); // test r1, #0x80000000 + UML_JMPc(block, COND_Z, compiler->labelnum); // jz labelnum + + UML_OR(block, I0, I0, SH_T); // or r0, r0, T + UML_LABEL(block, compiler->labelnum++); // labelnum: + UML_MOV(block, mem(&m_sh2_state->sr), I0); // mov sr, r0 + return true; + + case 8: // TST(Rm, Rn); + UML_AND(block, I0, mem(&m_sh2_state->sr), ~SH_T); // and r0, sr, ~T (clear the T bit) + UML_TEST(block, R32(Rm), R32(Rn)); // test Rm, Rn + UML_JMPc(block, COND_NZ, compiler->labelnum); // jnz compiler->labelnum + + UML_OR(block, I0, I0, SH_T); // or r0, r0, T + UML_LABEL(block, compiler->labelnum++); // desc->pc: + + UML_MOV(block, mem(&m_sh2_state->sr), I0); // mov m_sh2_state->sr, r0 + return true; + + case 12: // CMPSTR(Rm, Rn); + UML_XOR(block, I0, R32(Rn), R32(Rm)); // xor r0, Rn, Rm (temp) + + UML_SHR(block, I1, I0, 24); // shr r1, r0, #24 (HH) + UML_AND(block, I1, I1, 0xff); // and r1, r1, #0xff + + UML_SHR(block, I2, I0, 16); // shr r2, r0, #16 (HL) + UML_AND(block, I2, I2, 0xff); // and r2, r2, #0xff + + UML_SHR(block, I3, I0, 8); // shr r3, r0, #8 (LH) + UML_AND(block, I3, I3, 0xff); // and r3, r3, #0xff + + UML_AND(block, I7, I0, 0xff); // and r7, r0, #0xff (LL) + + UML_AND(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), ~SH_T); // and sr, sr, ~T (clear the T bit) + + UML_CMP(block, I1, 0); // cmp r1, #0 + UML_JMPc(block, COND_Z, compiler->labelnum); // jnz labelnum + UML_CMP(block, I2, 0); // cmp r2, #0 + UML_JMPc(block, COND_Z, compiler->labelnum); // jnz labelnum + UML_CMP(block, I3, 0); // cmp r3, #0 + UML_JMPc(block, COND_Z, compiler->labelnum); // jnz labelnum + UML_CMP(block, I7, 0); // cmp r7, #0 + UML_JMPc(block, COND_NZ, compiler->labelnum+1); // jnz labelnum + + UML_LABEL(block, compiler->labelnum++); // labelnum: + UML_OR(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), SH_T); // or sr, sr, T + + UML_LABEL(block, compiler->labelnum++); // labelnum+1: + return true; + + case 9: // AND(Rm, Rn); + UML_AND(block, R32(Rn), R32(Rn), R32(Rm)); // and Rn, Rn, Rm + return true; + + case 10: // XOR(Rm, Rn); + UML_XOR(block, R32(Rn), R32(Rn), R32(Rm)); // xor Rn, Rn, Rm + return true; + + case 11: // OR(Rm, Rn); + UML_OR(block, R32(Rn), R32(Rn), R32(Rm)); // or Rn, Rn, Rm + return true; + + case 14: // MULU(Rm, Rn); + UML_AND(block, I0, R32(Rm), 0xffff); // and r0, Rm, 0xffff + UML_AND(block, I1, R32(Rn), 0xffff); // and r1, Rn, 0xffff + UML_MULU(block, mem(&m_sh2_state->macl), mem(&m_sh2_state->ea), I0, I1); // mulu macl, ea, r0, r1 + return true; + + case 15: // MULS(Rm, Rn); + UML_SEXT(block, I0, R32(Rm), SIZE_WORD); // sext r0, Rm + UML_SEXT(block, I1, R32(Rn), SIZE_WORD); // sext r1, Rn + UML_MULS(block, mem(&m_sh2_state->macl), mem(&m_sh2_state->ea), I0, I1); // muls macl, ea, r0, r1 + return true; + } + + return false; +} + + +bool sh_common_execution::generate_group_3(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, uint32_t ovrpc) +{ + switch (opcode & 15) + { + case 0: // CMPEQ(Rm, Rn); (equality) + UML_CMP(block, R32(Rn), R32(Rm)); // cmp Rn, Rm + UML_SETc(block, COND_E, I0); // set E, r0 + UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, 1); // rolins sr, r0, 0, 1 + return true; + + case 2: // CMPHS(Rm, Rn); (unsigned greater than or equal) + UML_CMP(block, R32(Rn), R32(Rm)); // cmp Rn, Rm + UML_SETc(block, COND_AE, I0); // set AE, r0 + UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, 1); // rolins sr, r0, 0, 1 + return true; + + case 3: // CMPGE(Rm, Rn); (signed greater than or equal) + UML_CMP(block, R32(Rn), R32(Rm)); // cmp Rn, Rm + UML_SETc(block, COND_GE, I0); // set GE, r0 + UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, 1); // rolins sr, r0, 0, 1 + return true; + + case 6: // CMPHI(Rm, Rn); (unsigned greater than) + UML_CMP(block, R32(Rn), R32(Rm)); // cmp Rn, Rm + UML_SETc(block, COND_A, I0); // set A, r0 + UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, 1); // rolins sr, r0, 0, 1 + return true; + + case 7: // CMPGT(Rm, Rn); (signed greater than) + UML_CMP(block, R32(Rn), R32(Rm)); // cmp Rn, Rm + UML_SETc(block, COND_G, I0); // set G, r0 + UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, 1); // rolins sr, r0, 0, 1 + return true; + + case 1: + case 9: + return false; + + case 4: // DIV1(Rm, Rn); + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_DIV1, this); + load_fast_iregs(block); + return true; + + case 5: // DMULU(Rm, Rn); + if (m_cpu_type > CPU_TYPE_SH1) + { + UML_MULU(block, mem(&m_sh2_state->macl), mem(&m_sh2_state->mach), R32(Rn), R32(Rm)); + return true; + } + break; + + case 13: // DMULS(Rm, Rn); + if (m_cpu_type > CPU_TYPE_SH1) + { + UML_MULS(block, mem(&m_sh2_state->macl), mem(&m_sh2_state->mach), R32(Rn), R32(Rm)); + return true; + } + break; + + case 8: // SUB(Rm, Rn); + UML_SUB(block, R32(Rn), R32(Rn), R32(Rm)); // sub Rn, Rn, Rm + return true; + + case 12: // ADD(Rm, Rn); + UML_ADD(block, R32(Rn), R32(Rn), R32(Rm)); // add Rn, Rn, Rm + return true; + + case 10: // SUBC(Rm, Rn); + UML_CARRY(block, mem(&m_sh2_state->sr), 0); // carry = T (T is bit 0 of SR) + UML_SUBB(block, R32(Rn), R32(Rn), R32(Rm)); // addc Rn, Rn, Rm + UML_SETc(block, COND_C, I0); // setc i0, C + UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, SH_T); // rolins sr,i0,0,T + return true; + + case 11: // SUBV(Rm, Rn); + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_SUBV, this); + load_fast_iregs(block); + return true; + + case 14: // ADDC(Rm, Rn); + UML_CARRY(block, mem(&m_sh2_state->sr), 0); // carry = T (T is bit 0 of SR) + UML_ADDC(block, R32(Rn), R32(Rn), R32(Rm)); // addc Rn, Rn, Rm + UML_SETc(block, COND_C, I0); // setc i0, C + UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, SH_T); // rolins sr,i0,0,T + return true; + + case 15: // ADDV(Rm, Rn); + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_ADDV, this); + load_fast_iregs(block); + return true; + } + return false; +} + + +bool sh_common_execution::generate_group_6(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + switch (opcode & 15) + { + case 0: // MOVBL(Rm, Rn); + UML_MOV(block, I0, R32(Rm)); // mov r0, Rm + SETEA(0); // debug: ea = r0 + UML_CALLH(block, *m_read8); // call read8 + UML_SEXT(block, R32(Rn), I0, SIZE_BYTE); // sext Rn, r0, BYTE + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 1: // MOVWL(Rm, Rn); + UML_MOV(block, I0, R32(Rm)); // mov r0, Rm + SETEA(0); // debug: ea = r0 + UML_CALLH(block, *m_read16); // call read16 + UML_SEXT(block, R32(Rn), I0, SIZE_WORD); // sext Rn, r0, WORD + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 2: // MOVLL(Rm, Rn); + UML_MOV(block, I0, R32(Rm)); // mov r0, Rm + SETEA(0); // debug: ea = r0 + UML_CALLH(block, *m_read32); // call read32 + UML_MOV(block, R32(Rn), I0); // mov Rn, r0 + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 3: // MOV(Rm, Rn); + UML_MOV(block, R32(Rn), R32(Rm)); // mov Rn, Rm + return true; + + case 7: // NOT(Rm, Rn); + UML_XOR(block, R32(Rn), R32(Rm), 0xffffffff); // xor Rn, Rm, 0xffffffff + return true; + + case 9: // SWAPW(Rm, Rn); + UML_ROL(block, R32(Rn), R32(Rm), 16); // rol Rn, Rm, 16 + return true; + + case 11: // NEG(Rm, Rn); + UML_SUB(block, R32(Rn), 0, R32(Rm)); // sub Rn, 0, Rm + return true; + + case 12: // EXTUB(Rm, Rn); + UML_AND(block, R32(Rn), R32(Rm), 0x000000ff); // and Rn, Rm, 0xff + return true; + + case 13: // EXTUW(Rm, Rn); + UML_AND(block, R32(Rn), R32(Rm), 0x0000ffff); // and Rn, Rm, 0xffff + return true; + + case 14: // EXTSB(Rm, Rn); + UML_SEXT(block, R32(Rn), R32(Rm), SIZE_BYTE); // sext Rn, Rm, BYTE + return true; + + case 15: // EXTSW(Rm, Rn); + UML_SEXT(block, R32(Rn), R32(Rm), SIZE_WORD); // sext Rn, Rm, WORD + return true; + + case 4: // MOVBP(Rm, Rn); + UML_MOV(block, I0, R32(Rm)); // mov r0, Rm + UML_CALLH(block, *m_read8); // call read8 + UML_SEXT(block, R32(Rn), I0, SIZE_BYTE); // sext Rn, r0, BYTE + + if (Rm != Rn) + UML_ADD(block, R32(Rm), R32(Rm), 1); // add Rm, Rm, #1 + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 5: // MOVWP(Rm, Rn); + UML_MOV(block, I0, R32(Rm)); // mov r0, Rm + UML_CALLH(block, *m_read16); // call read16 + UML_SEXT(block, R32(Rn), I0, SIZE_WORD); // sext Rn, r0, WORD + + if (Rm != Rn) + UML_ADD(block, R32(Rm), R32(Rm), 2); // add Rm, Rm, #2 + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 6: // MOVLP(Rm, Rn); + UML_MOV(block, I0, R32(Rm)); // mov r0, Rm + UML_CALLH(block, *m_read32); // call read32 + UML_MOV(block, R32(Rn), I0); // mov Rn, r0 + + if (Rm != Rn) + UML_ADD(block, R32(Rm), R32(Rm), 4); // add Rm, Rm, #4 + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 8: // SWAPB(Rm, Rn); + UML_AND(block, I0, R32(Rm), 0xffff0000); // and r0, Rm, #0xffff0000 + UML_AND(block, I1, R32(Rm), 0x000000ff); // and r0, Rm, #0x000000ff + UML_AND(block, I2, R32(Rm), 0x0000ff00); // and r0, Rm, #0x0000ff00 + UML_SHL(block, I1, I1, 8); // shl r1, r1, #8 + UML_SHR(block, I2, I2, 8); // shr r2, r2, #8 + UML_OR(block, I0, I0, I1); // or r0, r0, r1 + UML_OR(block, R32(Rn), I0, I2); // or Rn, r0, r2 + return true; + + case 10: // NEGC(Rm, Rn); + UML_MOV(block, I0, mem(&m_sh2_state->sr)); // mov r0, sr (save SR) + UML_AND(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), ~SH_T); // and sr, sr, ~T (clear the T bit) + UML_CARRY(block, I0, 0); // carry = T (T is bit 0 of SR) + UML_SUBB(block, R32(Rn), 0, R32(Rm)); // subb Rn, #0, Rm + + UML_JMPc(block, COND_NC, compiler->labelnum); // jnc labelnum + + UML_OR(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), SH_T); // or sr, sr, T + + UML_LABEL(block, compiler->labelnum++); // labelnum: + + return true; + } + + return false; +} + +bool sh_common_execution::generate_group_8(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + int32_t disp; + uint32_t udisp; + code_label templabel; + + switch ( opcode & (15<<8) ) + { + case 0 << 8: // MOVBS4(opcode & 0x0f, Rm); + udisp = (opcode & 0x0f); + UML_ADD(block, I0, R32(Rm), udisp); // add r0, Rm, udisp + UML_MOV(block, I1, R32(0)); // mov r1, R0 + UML_CALLH(block, *m_write8); // call write8 + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 1 << 8: // MOVWS4(opcode & 0x0f, Rm); + udisp = (opcode & 0x0f) * 2; + UML_ADD(block, I0, R32(Rm), udisp); // add r0, Rm, udisp + UML_MOV(block, I1, R32(0)); // mov r1, R0 + UML_CALLH(block, *m_write16); // call write16 + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 2<< 8: + case 3<< 8: + case 6<< 8: + case 7<< 8: + case 10<< 8: + case 12<< 8: + case 14<< 8: + return false; + + case 4<< 8: // MOVBL4(Rm, opcode & 0x0f); + udisp = opcode & 0x0f; + UML_ADD(block, I0, R32(Rm), udisp); // add r0, Rm, udisp + SETEA(0); + UML_CALLH(block, *m_read8); // call read8 + UML_SEXT(block, R32(0), I0, SIZE_BYTE); // sext R0, r0, BYTE + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 5<< 8: // MOVWL4(Rm, opcode & 0x0f); + udisp = (opcode & 0x0f)*2; + UML_ADD(block, I0, R32(Rm), udisp); // add r0, Rm, udisp + SETEA(0); + UML_CALLH(block, *m_read16); // call read16 + UML_SEXT(block, R32(0), I0, SIZE_WORD); // sext R0, r0, WORD + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 8<< 8: // CMPIM(opcode & 0xff); + UML_AND(block, I0, mem(&m_sh2_state->sr), ~SH_T); // and r0, sr, ~T (clear the T bit) + + UML_SEXT(block, I1, opcode&0xff, SIZE_BYTE); // sext r1, opcode&0xff, BYTE + UML_CMP(block, I1, R32(0)); // cmp r1, R0 + UML_JMPc(block, COND_NZ, compiler->labelnum); // jnz compiler->labelnum (if negative) + + UML_OR(block, I0, I0, SH_T); // or r0, r0, T + + UML_LABEL(block, compiler->labelnum++); // labelnum: + UML_MOV(block, mem(&m_sh2_state->sr), I0); // mov m_sh2_state->sr, r0 + return true; + + case 9<< 8: // BT(opcode & 0xff); + UML_TEST(block, mem(&m_sh2_state->sr), SH_T); // test m_sh2_state->sr, T + UML_JMPc(block, COND_Z, compiler->labelnum); // jz compiler->labelnum + + disp = ((int32_t)opcode << 24) >> 24; + m_sh2_state->ea = (desc->pc + 2) + disp * 2 + 2; // m_sh2_state->ea = destination + + generate_update_cycles(block, compiler, m_sh2_state->ea, true); // <subtract cycles> + UML_HASHJMP(block, 0, m_sh2_state->ea, *m_nocode); // jmp m_sh2_state->ea + + UML_LABEL(block, compiler->labelnum++); // labelnum: + return true; + + case 11<< 8: // BF(opcode & 0xff); + UML_TEST(block, mem(&m_sh2_state->sr), SH_T); // test m_sh2_state->sr, T + UML_JMPc(block, COND_NZ, compiler->labelnum); // jnz compiler->labelnum + + disp = ((int32_t)opcode << 24) >> 24; + m_sh2_state->ea = (desc->pc + 2) + disp * 2 + 2; // m_sh2_state->ea = destination + + generate_update_cycles(block, compiler, m_sh2_state->ea, true); // <subtract cycles> + UML_HASHJMP(block, 0, m_sh2_state->ea, *m_nocode); // jmp m_sh2_state->ea + + UML_LABEL(block, compiler->labelnum++); // labelnum: + return true; + + case 13<< 8: // BTS(opcode & 0xff); + if (m_cpu_type > CPU_TYPE_SH1) + { + UML_TEST(block, mem(&m_sh2_state->sr), SH_T); // test m_sh2_state->sr, T + UML_JMPc(block, COND_Z, compiler->labelnum); // jz compiler->labelnum + + disp = ((int32_t)opcode << 24) >> 24; + m_sh2_state->ea = (desc->pc + 2) + disp * 2 + 2; // m_sh2_state->ea = destination + + templabel = compiler->labelnum; // save our label + compiler->labelnum++; // make sure the delay slot doesn't use it + generate_delay_slot(block, compiler, desc, m_sh2_state->ea-2); + + generate_update_cycles(block, compiler, m_sh2_state->ea, true); // <subtract cycles> + UML_HASHJMP(block, 0, m_sh2_state->ea, *m_nocode); // jmp m_sh2_state->ea + + UML_LABEL(block, templabel); // labelnum: + return true; + } + break; + + case 15<< 8: // BFS(opcode & 0xff); + if (m_cpu_type > CPU_TYPE_SH1) + { + UML_TEST(block, mem(&m_sh2_state->sr), SH_T); // test m_sh2_state->sr, T + UML_JMPc(block, COND_NZ, compiler->labelnum); // jnz compiler->labelnum + + disp = ((int32_t)opcode << 24) >> 24; + m_sh2_state->ea = (desc->pc + 2) + disp * 2 + 2; // m_sh2_state->ea = destination + + templabel = compiler->labelnum; // save our label + compiler->labelnum++; // make sure the delay slot doesn't use it + generate_delay_slot(block, compiler, desc, m_sh2_state->ea-2); // delay slot only if the branch is taken + + generate_update_cycles(block, compiler, m_sh2_state->ea, true); // <subtract cycles> + UML_HASHJMP(block, 0, m_sh2_state->ea, *m_nocode); // jmp m_sh2_state->ea + + UML_LABEL(block, templabel); // labelnum: + return true; + } + break; + } + + return false; +} + +bool sh_common_execution::generate_group_12_TRAPA(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + uint32_t scratch = (opcode & 0xff) * 4; + UML_ADD(block, mem(&m_sh2_state->ea), mem(&m_sh2_state->vbr), scratch); // add ea, vbr, scratch + + UML_SUB(block, R32(15), R32(15), 4); // sub R15, R15, #4 + UML_MOV(block, I0, R32(15)); // mov r0, R15 + UML_MOV(block, I1, mem(&m_sh2_state->sr)); // mov r1, sr + UML_CALLH(block, *m_write32); // write32 + + UML_SUB(block, R32(15), R32(15), 4); // sub R15, R15, #4 + UML_MOV(block, I0, R32(15)); // mov r0, R15 + UML_MOV(block, I1, desc->pc + 2); // mov r1, pc+2 + UML_CALLH(block, *m_write32); // write32 + + UML_MOV(block, I0, mem(&m_sh2_state->ea)); // mov r0, ea + UML_CALLH(block, *m_read32); // read32 + UML_HASHJMP(block, 0, I0, *m_nocode); // jmp (r0) + + return true; +} + +bool sh_common_execution::generate_group_12(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + uint32_t scratch; + + switch (opcode & (15<<8)) + { + case 0<<8: // MOVBSG(opcode & 0xff); + scratch = (opcode & 0xff); + UML_ADD(block, I0, mem(&m_sh2_state->gbr), scratch); // add r0, gbr, scratch + UML_AND(block, I1, R32(0), 0xff); // and r1, R0, 0xff + UML_CALLH(block, *m_write8); // call write8 + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 1<<8: // MOVWSG(opcode & 0xff); + scratch = (opcode & 0xff) * 2; + UML_ADD(block, I0, mem(&m_sh2_state->gbr), scratch); // add r0, gbr, scratch + UML_AND(block, I1, R32(0), 0xffff); // and r1, R0, 0xffff + UML_CALLH(block, *m_write16); // call write16 + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 2<<8: // MOVLSG(opcode & 0xff); + scratch = (opcode & 0xff) * 4; + UML_ADD(block, I0, mem(&m_sh2_state->gbr), scratch); // add r0, gbr, scratch + UML_MOV(block, I1, R32(0)); // mov r1, R0 + UML_CALLH(block, *m_write32); // call write32 + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 3<<8: // TRAPA(opcode & 0xff); + return generate_group_12_TRAPA(block, compiler, desc, opcode, in_delay_slot, ovrpc); + + case 4<<8: // MOVBLG(opcode & 0xff); + scratch = (opcode & 0xff); + UML_ADD(block, I0, mem(&m_sh2_state->gbr), scratch); // add r0, gbr, scratch + UML_CALLH(block, *m_read8); // call read16 + UML_SEXT(block, R32(0), I0, SIZE_BYTE); // sext R0, r0, BYTE + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 5<<8: // MOVWLG(opcode & 0xff); + scratch = (opcode & 0xff) * 2; + UML_ADD(block, I0, mem(&m_sh2_state->gbr), scratch); // add r0, gbr, scratch + UML_CALLH(block, *m_read16); // call read16 + UML_SEXT(block, R32(0), I0, SIZE_WORD); // sext R0, r0, WORD + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 6<<8: // MOVLLG(opcode & 0xff); + scratch = (opcode & 0xff) * 4; + UML_ADD(block, I0, mem(&m_sh2_state->gbr), scratch); // add r0, gbr, scratch + UML_CALLH(block, *m_read32); // call read32 + UML_MOV(block, R32(0), I0); // mov R0, r0 + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 7<<8: // MOVA(opcode & 0xff); + scratch = (opcode & 0xff) * 4; + scratch += ((desc->pc + 4) & ~3); + + UML_MOV(block, R32(0), scratch); // mov R0, scratch + return true; + + case 8<<8: // TSTI(opcode & 0xff); + scratch = opcode & 0xff; + + UML_AND(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), ~SH_T); // and sr, sr, ~T (clear the T bit) + UML_AND(block, I0, R32(0), scratch); // and r0, R0, scratch + UML_CMP(block, I0, 0); // cmp r0, #0 + UML_JMPc(block, COND_NZ, compiler->labelnum); // jnz labelnum + + UML_OR(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), SH_T); // or sr, sr, T + + UML_LABEL(block, compiler->labelnum++); // labelnum: + return true; + + case 9<<8: // ANDI(opcode & 0xff); + UML_AND(block, R32(0), R32(0), opcode & 0xff); // and r0, r0, opcode & 0xff + return true; + + case 10<<8: // XORI(opcode & 0xff); + UML_XOR(block, R32(0), R32(0), opcode & 0xff); // xor r0, r0, opcode & 0xff + return true; + + case 11<<8: // ORI(opcode & 0xff); + UML_OR(block, R32(0), R32(0), opcode & 0xff); // or r0, r0, opcode & 0xff + return true; + + case 12<<8: // TSTM(opcode & 0xff); + UML_AND(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), ~SH_T); // and sr, sr, ~T (clear the T bit) + UML_ADD(block, I0, R32(0), mem(&m_sh2_state->gbr)); // add r0, R0, gbr + UML_CALLH(block, *m_read8); // read8 + + UML_AND(block, I0, I0, opcode & 0xff); + UML_CMP(block, I0, 0); // cmp r0, #0 + UML_JMPc(block, COND_NZ, compiler->labelnum); // jnz labelnum + + UML_OR(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), SH_T); // or sr, sr, T + + UML_LABEL(block, compiler->labelnum++); // labelnum: + return true; + + case 13<<8: // ANDM(opcode & 0xff); + UML_ADD(block, I0, R32(0), mem(&m_sh2_state->gbr)); // add r0, R0, gbr + UML_CALLH(block, *m_read8); // read8 + + UML_AND(block, I1, I0, opcode&0xff); // and r1, r0, #opcode&0xff + UML_ADD(block, I0, R32(0), mem(&m_sh2_state->gbr)); // add r0, R0, gbr + SETEA(0); + UML_CALLH(block, *m_write8); // write8 + return true; + + case 14<<8: // XORM(opcode & 0xff); + UML_ADD(block, I0, R32(0), mem(&m_sh2_state->gbr)); // add r0, R0, gbr + UML_CALLH(block, *m_read8); // read8 + + UML_XOR(block, I1, I0, opcode&0xff); // xor r1, r0, #opcode&0xff + UML_ADD(block, I0, R32(0), mem(&m_sh2_state->gbr)); // add r0, R0, gbr + SETEA(0); + UML_CALLH(block, *m_write8); // write8 + return true; + + case 15<<8: // ORM(opcode & 0xff); + UML_ADD(block, I0, R32(0), mem(&m_sh2_state->gbr)); // add r0, R0, gbr + UML_CALLH(block, *m_read8); // read8 + + UML_OR(block, I1, I0, opcode&0xff); // or r1, r0, #opcode&0xff + UML_ADD(block, I0, R32(0), mem(&m_sh2_state->gbr)); // add r0, R0, gbr + SETEA(0); + UML_CALLH(block, *m_write8); // write8 + return true; + } + + return false; +} + +bool sh_common_execution::generate_group_0_RTE(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + generate_delay_slot(block, compiler, desc, 0xffffffff); + + UML_MOV(block, I0, R32(15)); // mov r0, R15 + UML_CALLH(block, *m_read32); // call read32 + UML_MOV(block, mem(&m_sh2_state->pc), I0); // mov pc, r0 + UML_ADD(block, R32(15), R32(15), 4); // add R15, R15, #4 + + UML_MOV(block, I0, R32(15)); // mov r0, R15 + UML_CALLH(block, *m_read32); // call read32 + UML_MOV(block, mem(&m_sh2_state->sr), I0); // mov sr, r0 + UML_ADD(block, R32(15), R32(15), 4); // add R15, R15, #4 + + compiler->checkints = true; + UML_MOV(block, mem(&m_sh2_state->ea), mem(&m_sh2_state->pc)); // mov ea, pc + generate_update_cycles(block, compiler, mem(&m_sh2_state->ea), true); // <subtract cycles> + UML_HASHJMP(block, 0, mem(&m_sh2_state->pc), *m_nocode); // and jump to the "resume PC" + + return true; +} + + +bool sh_common_execution::generate_group_0(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + switch (opcode & 0x3F) + { + case 0x00: // these are all illegal + case 0x01: + case 0x10: + case 0x11: + case 0x13: + case 0x20: + case 0x21: + case 0x30: + case 0x31: + case 0x32: + case 0x33: + case 0x38: + case 0x39: + case 0x3a: + case 0x3b: + return false; + + case 0x09: // NOP(); + return true; + + case 0x02: // STCSR(Rn); + UML_MOV(block, R32(Rn), mem(&m_sh2_state->sr)); + return true; + + case 0x03: // BSRF(Rn); + if (m_cpu_type > CPU_TYPE_SH1) + { + UML_ADD(block, mem(&m_sh2_state->target), R32(Rn), 4); // add target, Rm, #4 + UML_ADD(block, mem(&m_sh2_state->target), mem(&m_sh2_state->target), desc->pc); // add target, target, pc + + // 32x Cosmic Carnage @ 6002cb0 relies on the delay slot + // clobbering the calculated PR, so do it first + UML_ADD(block, mem(&m_sh2_state->pr), desc->pc, 4); // add m_pr, desc->pc, #4 (skip the current insn & delay slot) + + generate_delay_slot(block, compiler, desc, m_sh2_state->target); + + generate_update_cycles(block, compiler, mem(&m_sh2_state->target), true); // <subtract cycles> + UML_HASHJMP(block, 0, mem(&m_sh2_state->target), *m_nocode); // jmp target + return true; + } + break; + + case 0x04: // MOVBS0(Rm, Rn); + case 0x14: // MOVBS0(Rm, Rn); + case 0x24: // MOVBS0(Rm, Rn); + case 0x34: // MOVBS0(Rm, Rn); + UML_ADD(block, I0, R32(0), R32(Rn)); // add r0, R0, Rn + UML_AND(block, I1, R32(Rm), 0x000000ff); // and r1, Rm, 0xff + UML_CALLH(block, *m_write8); // call write8 + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 0x05: // MOVWS0(Rm, Rn); + case 0x15: // MOVWS0(Rm, Rn); + case 0x25: // MOVWS0(Rm, Rn); + case 0x35: // MOVWS0(Rm, Rn); + UML_ADD(block, I0, R32(0), R32(Rn)); // add r0, R0, Rn + UML_AND(block, I1, R32(Rm), 0x0000ffff); // and r1, Rm, 0xffff + UML_CALLH(block, *m_write16); // call write16 + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 0x06: // MOVLS0(Rm, Rn); + case 0x16: // MOVLS0(Rm, Rn); + case 0x26: // MOVLS0(Rm, Rn); + case 0x36: // MOVLS0(Rm, Rn); + UML_ADD(block, I0, R32(0), R32(Rn)); // add r0, R0, Rn + UML_MOV(block, I1, R32(Rm)); // mov r1, Rm + UML_CALLH(block, *m_write32); // call write32 + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 0x07: // MULL(Rm, Rn); + case 0x17: // MULL(Rm, Rn); + case 0x27: // MULL(Rm, Rn); + case 0x37: // MULL(Rm, Rn); + if (m_cpu_type > CPU_TYPE_SH1) + { + UML_MULU(block, mem(&m_sh2_state->macl), mem(&m_sh2_state->ea), R32(Rn), R32(Rm)); // mulu macl, ea, Rn, Rm + return true; + } + break; + + case 0x08: // CLRT(); + UML_AND(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), ~SH_T); // and r0, sr, ~T (clear the T bit) + return true; + + case 0x0a: // STSMACH(Rn); + UML_MOV(block, R32(Rn), mem(&m_sh2_state->mach)); // mov Rn, mach + return true; + + case 0x0b: // RTS(); + UML_MOV(block, mem(&m_sh2_state->target), mem(&m_sh2_state->pr)); // mov target, pr (in case of d-slot shenanigans) + + generate_delay_slot(block, compiler, desc, m_sh2_state->target); + + generate_update_cycles(block, compiler, mem(&m_sh2_state->target), true); // <subtract cycles> + UML_HASHJMP(block, 0, mem(&m_sh2_state->target), *m_nocode); + return true; + + case 0x0c: // MOVBL0(Rm, Rn); + case 0x1c: // MOVBL0(Rm, Rn); + case 0x2c: // MOVBL0(Rm, Rn); + case 0x3c: // MOVBL0(Rm, Rn); + UML_ADD(block, I0, R32(0), R32(Rm)); // add r0, R0, Rm + UML_CALLH(block, *m_read8); // call read8 + UML_SEXT(block, R32(Rn), I0, SIZE_BYTE); // sext Rn, r0, BYTE + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 0x0d: // MOVWL0(Rm, Rn); + case 0x1d: // MOVWL0(Rm, Rn); + case 0x2d: // MOVWL0(Rm, Rn); + case 0x3d: // MOVWL0(Rm, Rn); + UML_ADD(block, I0, R32(0), R32(Rm)); // add r0, R0, Rm + UML_CALLH(block, *m_read16); // call read16 + UML_SEXT(block, R32(Rn), I0, SIZE_WORD); // sext Rn, r0, WORD + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 0x0e: // MOVLL0(Rm, Rn); + case 0x1e: // MOVLL0(Rm, Rn); + case 0x2e: // MOVLL0(Rm, Rn); + case 0x3e: // MOVLL0(Rm, Rn); + UML_ADD(block, I0, R32(0), R32(Rm)); // add r0, R0, Rm + UML_CALLH(block, *m_read32); // call read32 + UML_MOV(block, R32(Rn), I0); // mov Rn, r0 + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 0x0f: // MAC_L(Rm, Rn); + case 0x1f: // MAC_L(Rm, Rn); + case 0x2f: // MAC_L(Rm, Rn); + case 0x3f: // MAC_L(Rm, Rn); + if (m_cpu_type > CPU_TYPE_SH1) + { + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_MAC_L, this); + load_fast_iregs(block); + return true; + } + break; + + case 0x12: // STCGBR(Rn); + UML_MOV(block, R32(Rn), mem(&m_sh2_state->gbr)); // mov Rn, gbr + return true; + + case 0x18: // SETT(); + UML_OR(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), SH_T); // or sr, sr, T + return true; + + case 0x19: // DIV0U(); + UML_AND(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), ~(SH_M|SH_Q|SH_T)); // and sr, sr, ~(M|Q|T) + return true; + + case 0x1a: // STSMACL(Rn); + UML_MOV(block, R32(Rn), mem(&m_sh2_state->macl)); // mov Rn, macl + return true; + + case 0x1b: // SLEEP(); + UML_MOV(block, I0, mem(&m_sh2_state->sleep_mode)); // mov i0, sleep_mode + UML_CMP(block, I0, 0x2); // cmp i0, #2 + UML_JMPc(block, COND_E, compiler->labelnum); // beq labelnum + // sleep mode != 2 + UML_MOV(block, mem(&m_sh2_state->sleep_mode), 0x1); // mov sleep_mode, #1 + generate_update_cycles(block, compiler, desc->pc, true); // repeat this insn + UML_JMP(block, compiler->labelnum+1); // jmp labelnum+1 + + UML_LABEL(block, compiler->labelnum++); // labelnum: + // sleep_mode == 2 + UML_MOV(block, mem(&m_sh2_state->sleep_mode), 0x0); // sleep_mode = 0 + generate_update_cycles(block, compiler, desc->pc+2, true); // go to next insn + + UML_LABEL(block, compiler->labelnum++); // labelnum+1: + return true; + + case 0x22: // STCVBR(Rn); + UML_MOV(block, R32(Rn), mem(&m_sh2_state->vbr)); // mov Rn, vbr + return true; + + case 0x23: // BRAF(Rn); + if (m_cpu_type > CPU_TYPE_SH1) + { + UML_ADD(block, mem(&m_sh2_state->target), R32(Rn), desc->pc+4); // add target, Rn, pc+4 + + generate_delay_slot(block, compiler, desc, m_sh2_state->target); + + generate_update_cycles(block, compiler, mem(&m_sh2_state->target), true); // <subtract cycles> + UML_HASHJMP(block, 0, mem(&m_sh2_state->target), *m_nocode); // jmp target + return true; + } + break; + + case 0x28: // CLRMAC(); + UML_MOV(block, mem(&m_sh2_state->macl), 0); // mov macl, #0 + UML_MOV(block, mem(&m_sh2_state->mach), 0); // mov mach, #0 + return true; + + case 0x29: // MOVT(Rn); + UML_AND(block, R32(Rn), mem(&m_sh2_state->sr), SH_T); // and Rn, sr, T + return true; + + case 0x2a: // STSPR(Rn); + UML_MOV(block, R32(Rn), mem(&m_sh2_state->pr)); // mov Rn, pr + return true; + + case 0x2b: // RTE(); + return generate_group_0_RTE(block, compiler, desc, opcode, in_delay_slot, ovrpc); + } + + return false; +} + +bool sh_common_execution::generate_group_4_LDCSR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + // needs to be different on SH2 / 4 + UML_MOV(block, I0, R32(Rn)); // mov r0, Rn + UML_AND(block, I0, I0, SH_FLAGS); // and r0, r0, FLAGS + UML_MOV(block, mem(&m_sh2_state->sr), I0); + + compiler->checkints = true; + return true; +} + +bool sh_common_execution::generate_group_4_LDCMSR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + UML_MOV(block, I0, R32(Rn)); // mov r0, Rn + SETEA(0); + UML_CALLH(block, *m_read32); // call read32 + UML_ADD(block, R32(Rn), R32(Rn), 4); // add Rn, #4 + UML_MOV(block, mem(&m_sh2_state->sr), I0); // mov sr, r0 + + compiler->checkints = true; + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; +} + +bool sh_common_execution::generate_group_4(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + switch (opcode & 0x3F) + { + case 0x00: // SHLL(Rn); + UML_SHL(block, R32(Rn), R32(Rn), 1); // shl Rn, Rn, 1 + UML_SETc(block, COND_C, I0); // set i0,C + UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, SH_T); // rolins [sr],i0,0,T + return true; + + case 0x01: // SHLR(Rn); + UML_SHR(block, R32(Rn), R32(Rn), 1); // shr Rn, Rn, 1 + UML_SETc(block, COND_C, I0); // set i0,C + UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, SH_T); // rolins [sr],i0,0,T + return true; + + case 0x04: // ROTL(Rn); + UML_ROL(block, R32(Rn), R32(Rn), 1); // rol Rn, Rn, 1 + UML_SETc(block, COND_C, I0); // set i0,C + UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, SH_T); // rolins [sr],i0,0,T + return true; + + case 0x05: // ROTR(Rn); + UML_ROR(block, R32(Rn), R32(Rn), 1); // ror Rn, Rn, 1 + UML_SETc(block, COND_C, I0); // set i0,C + UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, SH_T); // rolins [sr],i0,0,T + return true; + + case 0x02: // STSMMACH(Rn); + UML_SUB(block, R32(Rn), R32(Rn), 4); // sub Rn, Rn, #4 + UML_MOV(block, I0, R32(Rn)); // mov r0, Rn + UML_MOV(block, I1, mem(&m_sh2_state->mach)); // mov r1, mach + SETEA(0); // set ea for debug + UML_CALLH(block, *m_write32); // call write32 + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 0x03: // STCMSR(Rn); + UML_SUB(block, R32(Rn), R32(Rn), 4); // sub Rn, Rn, #4 + UML_MOV(block, I0, R32(Rn)); // mov r0, Rn + UML_MOV(block, I1, mem(&m_sh2_state->sr)); // mov r1, sr + SETEA(0); // set ea for debug + UML_CALLH(block, *m_write32); // call write32 + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 0x06: // LDSMMACH(Rn); + UML_MOV(block, I0, R32(Rn)); // mov r0, Rn + SETEA(0); + UML_CALLH(block, *m_read32); // call read32 + UML_ADD(block, R32(Rn), R32(Rn), 4); // add Rn, #4 + UML_MOV(block, mem(&m_sh2_state->mach), I0); // mov mach, r0 + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 0x07: // LDCMSR(Rn); + return generate_group_4_LDCMSR(block, compiler, desc, opcode, in_delay_slot, ovrpc); + + case 0x08: // SHLL2(Rn); + UML_SHL(block, R32(Rn), R32(Rn), 2); + return true; + + case 0x09: // SHLR2(Rn); + UML_SHR(block, R32(Rn), R32(Rn), 2); + return true; + + case 0x18: // SHLL8(Rn); + UML_SHL(block, R32(Rn), R32(Rn), 8); + return true; + + case 0x19: // SHLR8(Rn); + UML_SHR(block, R32(Rn), R32(Rn), 8); + return true; + + case 0x28: // SHLL16(Rn); + UML_SHL(block, R32(Rn), R32(Rn), 16); + return true; + + case 0x29: // SHLR16(Rn); + UML_SHR(block, R32(Rn), R32(Rn), 16); + return true; + + case 0x0a: // LDSMACH(Rn); + UML_MOV(block, mem(&m_sh2_state->mach), R32(Rn)); // mov mach, Rn + return true; + + case 0x0b: // JSR(Rn); + UML_MOV(block, mem(&m_sh2_state->target), R32(Rn)); // mov target, Rn + + UML_ADD(block, mem(&m_sh2_state->pr), desc->pc, 4); // add m_pr, desc->pc, #4 (skip the current insn & delay slot) + + generate_delay_slot(block, compiler, desc, m_sh2_state->target-4); + + generate_update_cycles(block, compiler, mem(&m_sh2_state->target), true); // <subtract cycles> + UML_HASHJMP(block, 0, mem(&m_sh2_state->target), *m_nocode); // and do the jump + return true; + + case 0x0e: // LDCSR(Rn); + return generate_group_4_LDCSR(block, compiler, desc, opcode, in_delay_slot, ovrpc); + + case 0x0f: // MAC_W(Rm, Rn); + case 0x1f: // MAC_W(Rm, Rn); + case 0x2f: // MAC_W(Rm, Rn); + case 0x3f: // MAC_W(Rm, Rn); + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_MAC_W, this); + load_fast_iregs(block); + return true; + + case 0x10: // DT(Rn); + if (m_cpu_type > CPU_TYPE_SH1) + { + UML_AND(block, I0, mem(&m_sh2_state->sr), ~SH_T); // and r0, sr, ~T (clear the T bit) + UML_SUB(block, R32(Rn), R32(Rn), 1); // sub Rn, Rn, 1 + UML_JMPc(block, COND_NZ, compiler->labelnum); // jz compiler->labelnum + + UML_OR(block, I0, I0, SH_T); // or r0, r0, T + UML_LABEL(block, compiler->labelnum++); // desc->pc: + + UML_MOV(block, mem(&m_sh2_state->sr), I0); // mov m_sh2_state->sr, r0 + return true; + } + break; + + case 0x11: // CMPPZ(Rn); + UML_AND(block, I0, mem(&m_sh2_state->sr), ~SH_T); // and r0, sr, ~T (clear the T bit) + + UML_CMP(block, R32(Rn), 0); // cmp Rn, 0 + UML_JMPc(block, COND_S, compiler->labelnum); // js compiler->labelnum (if negative) + + UML_OR(block, I0, I0, SH_T); // or r0, r0, T + UML_LABEL(block, compiler->labelnum++); // desc->pc: + + UML_MOV(block, mem(&m_sh2_state->sr), I0); // mov m_sh2_state->sr, r0 + return true; + + case 0x15: // CMPPL(Rn); + UML_AND(block, I0, mem(&m_sh2_state->sr), ~SH_T); // and r0, sr, ~T (clear the T bit) + + UML_CMP(block, R32(Rn), 0); // cmp Rn, 0 + + UML_JMPc(block, COND_S, compiler->labelnum); // js compiler->labelnum (if negative) + UML_JMPc(block, COND_Z, compiler->labelnum); // jz compiler->labelnum (if zero) + + UML_OR(block, I0, I0, SH_T); // or r0, r0, T + + UML_LABEL(block, compiler->labelnum++); // desc->pc: + UML_MOV(block, mem(&m_sh2_state->sr), I0); // mov m_sh2_state->sr, r0 + return true; + + case 0x12: // STSMMACL(Rn); + UML_SUB(block, R32(Rn), R32(Rn), 4); // sub Rn, Rn, #4 + UML_MOV(block, I0, R32(Rn)); // mov r0, Rn + UML_MOV(block, I1, mem(&m_sh2_state->macl)); // mov r1, macl + SETEA(0); // set ea for debug + UML_CALLH(block, *m_write32); // call write32 + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 0x13: // STCMGBR(Rn); + UML_SUB(block, R32(Rn), R32(Rn), 4); // sub Rn, Rn, #4 + UML_MOV(block, I0, R32(Rn)); // mov r0, Rn + UML_MOV(block, I1, mem(&m_sh2_state->gbr)); // mov r1, gbr + SETEA(0); // set ea for debug + UML_CALLH(block, *m_write32); // call write32 + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 0x16: // LDSMMACL(Rn); + UML_MOV(block, I0, R32(Rn)); // mov r0, Rn + SETEA(0); + UML_CALLH(block, *m_read32); // call read32 + UML_ADD(block, R32(Rn), R32(Rn), 4); // add Rn, #4 + UML_MOV(block, mem(&m_sh2_state->macl), I0); // mov macl, r0 + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 0x17: // LDCMGBR(Rn); + UML_MOV(block, I0, R32(Rn)); // mov r0, Rn + SETEA(0); + UML_CALLH(block, *m_read32); // call read32 + UML_ADD(block, R32(Rn), R32(Rn), 4); // add Rn, #4 + UML_MOV(block, mem(&m_sh2_state->gbr), I0); // mov gbr, r0 + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 0x1a: // LDSMACL(Rn); + UML_MOV(block, mem(&m_sh2_state->macl), R32(Rn)); // mov macl, Rn + return true; + + case 0x1b: // TAS(Rn); + UML_MOV(block, I0, R32(Rn)); // mov r0, Rn + SETEA(0); + UML_CALLH(block, *m_read8); // call read8 + + UML_AND(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), ~SH_T); // and sr, sr, ~T + + UML_CMP(block, I0, 0); // cmp r0, #0 + UML_JMPc(block, COND_NZ, compiler->labelnum); // jnz labelnum + + UML_OR(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), SH_T); // or sr, sr, T + + UML_LABEL(block, compiler->labelnum++); // labelnum: + + UML_OR(block, I1, I0, 0x80); // or r1, r0, #0x80 + + UML_MOV(block, I0, R32(Rn)); // mov r0, Rn + UML_CALLH(block, *m_write8); // write the value back + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 0x1e: // LDCGBR(Rn); + UML_MOV(block, mem(&m_sh2_state->gbr), R32(Rn)); // mov gbr, Rn + return true; + + case 0x20: // SHAL(Rn); + UML_AND(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), ~SH_T); // and sr, sr, ~T + UML_SHR(block, I0, R32(Rn), 31); // shr r0, Rn, 31 + UML_AND(block, I0, I0, SH_T); // and r0, r0, T + UML_OR(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), I0); // or sr, sr, r0 + UML_SHL(block, R32(Rn), R32(Rn), 1); // shl Rn, Rn, 1 + return true; + + case 0x21: // SHAR(Rn); + UML_AND(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), ~SH_T); // and sr, sr, ~T + UML_AND(block, I0, R32(Rn), SH_T); // and r0, Rn, T + UML_OR(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), I0); // or sr, sr, r0 + UML_SAR(block, R32(Rn), R32(Rn), 1); // sar Rn, Rn, 1 + return true; + + case 0x22: // STSMPR(Rn); + UML_SUB(block, R32(Rn), R32(Rn), 4); // sub Rn, Rn, 4 + UML_MOV(block, I0, R32(Rn)); // mov r0, Rn + SETEA(0); + UML_MOV(block, I1, mem(&m_sh2_state->pr)); // mov r1, pr + UML_CALLH(block, *m_write32); // call write32 + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 0x23: // STCMVBR(Rn); + UML_SUB(block, R32(Rn), R32(Rn), 4); // sub Rn, Rn, 4 + UML_MOV(block, I0, R32(Rn)); // mov r0, Rn + SETEA(0); + UML_MOV(block, I1, mem(&m_sh2_state->vbr)); // mov r1, vbr + UML_CALLH(block, *m_write32); // call write32 + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 0x24: // ROTCL(Rn); + UML_CARRY(block, mem(&m_sh2_state->sr), 0); // carry sr,0 + UML_ROLC(block, R32(Rn), R32(Rn), 1); // rolc Rn,Rn,1 + UML_SETc(block, COND_C, I0); // set i0,C + UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, SH_T); // rolins sr,i0,0,T + return true; + + case 0x25: // ROTCR(Rn); + UML_CARRY(block, mem(&m_sh2_state->sr), 0); // carry sr,0 + UML_RORC(block, R32(Rn), R32(Rn), 1); // rorc Rn,Rn,1 + UML_SETc(block, COND_C, I0); // set i0,C + UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, SH_T); // rolins sr,i0,0,T + return true; + + case 0x26: // LDSMPR(Rn); + UML_MOV(block, I0, R32(Rn)); // mov r0, Rn + SETEA(0); + UML_CALLH(block, *m_read32); // call read32 + UML_MOV(block, mem(&m_sh2_state->pr), I0); // mov m_pr, r0 + UML_ADD(block, R32(Rn), R32(Rn), 4); // add Rn, Rn, #4 + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 0x27: // LDCMVBR(Rn); + UML_MOV(block, I0, R32(Rn)); // mov r0, Rn + SETEA(0); + UML_CALLH(block, *m_read32); // call read32 + UML_MOV(block, mem(&m_sh2_state->vbr), I0); // mov m_sh2_state->vbr, r0 + UML_ADD(block, R32(Rn), R32(Rn), 4); // add Rn, Rn, #4 + + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; + + case 0x2a: // LDSPR(Rn); + UML_MOV(block, mem(&m_sh2_state->pr), R32(Rn)); // mov m_pr, Rn + return true; + + case 0x2b: // JMP(Rn); + UML_MOV(block, mem(&m_sh2_state->target), R32(Rn)); // mov target, Rn + + generate_delay_slot(block, compiler, desc, m_sh2_state->target); + + generate_update_cycles(block, compiler, mem(&m_sh2_state->target), true); // <subtract cycles> + UML_HASHJMP(block, 0, mem(&m_sh2_state->target), *m_nocode); // jmp (target) + return true; + + case 0x2e: // LDCVBR(Rn); + UML_MOV(block, mem(&m_sh2_state->vbr), R32(Rn)); // mov vbr, Rn + return true; + + case 0x0c: + case 0x0d: + case 0x14: + case 0x1c: + case 0x1d: + case 0x2c: + case 0x2d: + case 0x30: + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + case 0x38: + case 0x39: + case 0x3a: + case 0x3b: + case 0x3c: + case 0x3d: + case 0x3e: + return false; + } + + return false; +} + + +/*************************************************************************** + CORE CALLBACKS +***************************************************************************/ + +/*------------------------------------------------- + sh2drc_set_options - configure DRC options +-------------------------------------------------*/ + +void sh_common_execution::sh2drc_set_options(uint32_t options) +{ + if (!allow_drc()) return; + m_drcoptions = options; +} + + +/*------------------------------------------------- + sh2drc_add_pcflush - add a new address where + the PC must be flushed for speedups to work +-------------------------------------------------*/ + +void sh_common_execution::sh2drc_add_pcflush(offs_t address) +{ + if (!allow_drc()) return; + + if (m_pcfsel < ARRAY_LENGTH(m_pcflushes)) + m_pcflushes[m_pcfsel++] = address; +} diff --git a/src/devices/cpu/sh/sh.h b/src/devices/cpu/sh/sh.h new file mode 100644 index 00000000000..1e41d74385b --- /dev/null +++ b/src/devices/cpu/sh/sh.h @@ -0,0 +1,469 @@ +// license:BSD-3-Clause +// copyright-holders:David Haywood + +#ifndef MAME_CPU_SH_SH_H +#define MAME_CPU_SH_SH_H + +#pragma once + +#include "cpu/drcfe.h" +#include "cpu/drcuml.h" +#include "cpu/drcumlsh.h" + +/*************************************************************************** + DEBUGGING +**************************************************************************/ + +#define DISABLE_FAST_REGISTERS (0) // set to 1 to turn off usage of register caching +#define SINGLE_INSTRUCTION_MODE (0) + +#define SET_EA (0) // makes slower but "shows work" in the EA fake register like the interpreter + +#if SET_EA +#define SETEA(x) UML_MOV(block, mem(&m_sh2_state->ea), ireg(x)) +#else +#define SETEA(x) +#endif + +/*************************************************************************** + CONSTANTS +***************************************************************************/ + +/* speed up delay loops, bail out of tight loops (can cause timer issues) */ +#define BUSY_LOOP_HACKS 0 + +/* compilation boundaries -- how far back/forward does the analysis extend? */ +#define COMPILE_BACKWARDS_BYTES 64 +#define COMPILE_FORWARDS_BYTES 256 +#define COMPILE_MAX_INSTRUCTIONS ((COMPILE_BACKWARDS_BYTES/2) + (COMPILE_FORWARDS_BYTES/2)) +#define COMPILE_MAX_SEQUENCE 64 + +#define SH2DRC_STRICT_VERIFY 0x0001 /* verify all instructions */ +#define SH2DRC_FLUSH_PC 0x0002 /* flush the PC value before each memory access */ +#define SH2DRC_STRICT_PCREL 0x0004 /* do actual loads on MOVLI/MOVWI instead of collapsing to immediates */ + +#define SH2DRC_COMPATIBLE_OPTIONS (SH2DRC_STRICT_VERIFY | SH2DRC_FLUSH_PC | SH2DRC_STRICT_PCREL) +#define SH2DRC_FASTEST_OPTIONS (0) + +/* size of the execution code cache */ +#define CACHE_SIZE (32 * 1024 * 1024) + +#define SH2_MAX_FASTRAM 4 + +/* map variables */ +#define MAPVAR_PC M0 +#define MAPVAR_CYCLES M1 + +/* exit codes */ +#define EXECUTE_OUT_OF_CYCLES 0 +#define EXECUTE_MISSING_CODE 1 +#define EXECUTE_UNMAPPED_CODE 2 +#define EXECUTE_RESET_CACHE 3 + +#define PROBE_ADDRESS ~0 + +#define CPU_TYPE_SH1 (0) +#define CPU_TYPE_SH2 (1) +#define CPU_TYPE_SH3 (2) +#define CPU_TYPE_SH4 (3) + +#define Rn ((opcode>>8)&15) +#define Rm ((opcode>>4)&15) + +/* Bits in SR */ +#define SH_T 0x00000001 +#define SH_S 0x00000002 +#define SH_I 0x000000f0 +#define SH_Q 0x00000100 +#define SH_M 0x00000200 + +#define SH_FLAGS (SH_M|SH_Q|SH_I|SH_S|SH_T) + +#define REGFLAG_R(n) (1 << (n)) + +/* register flags 1 */ +#define REGFLAG_PR (1 << 0) +#define REGFLAG_MACL (1 << 1) +#define REGFLAG_MACH (1 << 2) +#define REGFLAG_GBR (1 << 3) +#define REGFLAG_VBR (1 << 4) +#define REGFLAG_SR (1 << 5) + +/*************************************************************************** + MACROS +***************************************************************************/ + +#define SH2_CODE_XOR(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(2,0)) // sh2 +#define SH34LE_CODE_XOR(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(0,6)) // naomi +#define SH34BE_CODE_XOR(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(6,0)) // cave + +#define R32(reg) m_regmap[reg] + +enum +{ + SH4_PC = 1, SH_SR, SH4_PR, SH4_GBR, SH4_VBR, SH4_DBR, SH4_MACH, SH4_MACL, + SH4_R0, SH4_R1, SH4_R2, SH4_R3, SH4_R4, SH4_R5, SH4_R6, SH4_R7, + SH4_R8, SH4_R9, SH4_R10, SH4_R11, SH4_R12, SH4_R13, SH4_R14, SH4_R15, SH4_EA +}; + +class sh_common_execution : public cpu_device +{ + +public: + sh_common_execution(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, endianness_t endianness, address_map_constructor internal) + : cpu_device(mconfig, type, tag, owner, clock) + , m_sh2_state(nullptr) + , m_cache(CACHE_SIZE + sizeof(internal_sh2_state)) + , m_drcuml(nullptr) + , m_drcoptions(0) + , m_entry(nullptr) + , m_read8(nullptr) + , m_write8(nullptr) + , m_read16(nullptr) + , m_write16(nullptr) + , m_read32(nullptr) + , m_write32(nullptr) + , m_interrupt(nullptr) + , m_nocode(nullptr) + , m_out_of_cycles(nullptr) + , m_xor(0) + { } + + // Data that needs to be stored close to the generated DRC code + struct internal_sh2_state + { + uint32_t pc; + uint32_t pr; + uint32_t sr; + uint32_t mach; + uint32_t macl; + uint32_t r[16]; + uint32_t ea; + + uint32_t pending_irq; + uint32_t pending_nmi; + int32_t irqline; + uint32_t evec; // exception vector for DRC + uint32_t irqsr; // IRQ-time old SR for DRC + uint32_t target; // target for jmp/jsr/etc so the delay slot can't kill it + int internal_irq_level; + int icount; + uint8_t sleep_mode; + uint32_t arg0; /* print_debug argument 1 */ + uint32_t arg1; + uint32_t gbr; + uint32_t vbr; + + uint32_t m_delay; + }; + + internal_sh2_state *m_sh2_state; + + virtual uint8_t RB(offs_t A) = 0; + virtual uint16_t RW(offs_t A) = 0; + virtual uint32_t RL(offs_t A) = 0; + virtual void WB(offs_t A, uint8_t V) = 0; + virtual void WW(offs_t A, uint16_t V) = 0; + virtual void WL(offs_t A, uint32_t V) = 0; + +protected: + + void ADD(uint32_t m, uint32_t n); + void ADDI(uint32_t i, uint32_t n); + void ADDC(uint32_t m, uint32_t n); + void ADDV(uint32_t m, uint32_t n); + void AND(uint32_t m, uint32_t n); + void ANDI(uint32_t i); + void ANDM(uint32_t i); + void BF(uint32_t d); + void BFS(uint32_t d); + void BRA(uint32_t d); + void BRAF(uint32_t m); + void BSR(uint32_t d); + void BSRF(uint32_t m); + void BT(uint32_t d); + void BTS(uint32_t d); + void CLRMAC(); + void CLRT(); + void CMPEQ(uint32_t m, uint32_t n); + void CMPGE(uint32_t m, uint32_t n); + void CMPGT(uint32_t m, uint32_t n); + void CMPHI(uint32_t m, uint32_t n); + void CMPHS(uint32_t m, uint32_t n); + void CMPPL(uint32_t n); + void CMPPZ(uint32_t n); + void CMPSTR(uint32_t m, uint32_t n); + void CMPIM(uint32_t i); + void DIV0S(uint32_t m, uint32_t n); + void DIV0U(); + void DIV1(uint32_t m, uint32_t n); + void DMULS(uint32_t m, uint32_t n); + void DMULU(uint32_t m, uint32_t n); + void DT(uint32_t n); + void EXTSB(uint32_t m, uint32_t n); + void EXTSW(uint32_t m, uint32_t n); + void EXTUB(uint32_t m, uint32_t n); + void EXTUW(uint32_t m, uint32_t n); + void JMP(uint32_t m); + void JSR(uint32_t m); + void LDCGBR(uint32_t m); + void LDCVBR(uint32_t m); + void LDCMGBR(uint32_t m); + void LDCMVBR(uint32_t m); + void LDSMACH(uint32_t m); + void LDSMACL(uint32_t m); + void LDSPR(uint32_t m); + void LDSMMACH(uint32_t m); + void LDSMMACL(uint32_t m); + void LDSMPR(uint32_t m); + void MAC_L(uint32_t m, uint32_t n); + void MAC_W(uint32_t m, uint32_t n); + void MOV(uint32_t m, uint32_t n); + void MOVBS(uint32_t m, uint32_t n); + void MOVWS(uint32_t m, uint32_t n); + void MOVLS(uint32_t m, uint32_t n); + void MOVBL(uint32_t m, uint32_t n); + void MOVWL(uint32_t m, uint32_t n); + void MOVLL(uint32_t m, uint32_t n); + void MOVBM(uint32_t m, uint32_t n); + void MOVWM(uint32_t m, uint32_t n); + void MOVLM(uint32_t m, uint32_t n); + void MOVBP(uint32_t m, uint32_t n); + void MOVWP(uint32_t m, uint32_t n); + void MOVLP(uint32_t m, uint32_t n); + void MOVBS0(uint32_t m, uint32_t n); + void MOVWS0(uint32_t m, uint32_t n); + void MOVLS0(uint32_t m, uint32_t n); + void MOVBL0(uint32_t m, uint32_t n); + void MOVWL0(uint32_t m, uint32_t n); + void MOVLL0(uint32_t m, uint32_t n); + void MOVI(uint32_t i, uint32_t n); + void MOVWI(uint32_t d, uint32_t n); + void MOVLI(uint32_t d, uint32_t n); + void MOVBLG(uint32_t d); + void MOVWLG(uint32_t d); + void MOVLLG(uint32_t d); + void MOVBSG(uint32_t d); + void MOVWSG(uint32_t d); + void MOVLSG(uint32_t d); + void MOVBS4(uint32_t d, uint32_t n); + void MOVWS4(uint32_t d, uint32_t n); + void MOVLS4(uint32_t m, uint32_t d, uint32_t n); + void MOVBL4(uint32_t m, uint32_t d); + void MOVWL4(uint32_t m, uint32_t d); + void MOVLL4(uint32_t m, uint32_t d, uint32_t n); + void MOVA(uint32_t d); + void MOVT(uint32_t n); + void MULL(uint32_t m, uint32_t n); + void MULS(uint32_t m, uint32_t n); + void MULU(uint32_t m, uint32_t n); + void NEG(uint32_t m, uint32_t n); + void NEGC(uint32_t m, uint32_t n); + void NOP(void); + void NOT(uint32_t m, uint32_t n); + void OR(uint32_t m, uint32_t n); + void ORI(uint32_t i); + void ORM(uint32_t i); + void ROTCL(uint32_t n); + void ROTCR(uint32_t n); + void ROTL(uint32_t n); + void ROTR(uint32_t n); + void RTS(); + void SETT(); + void SHAL(uint32_t n); + void SHAR(uint32_t n); + void SHLL(uint32_t n); + void SHLL2(uint32_t n); + void SHLL8(uint32_t n); + void SHLL16(uint32_t n); + void SHLR(uint32_t n); + void SHLR2(uint32_t n); + void SHLR8(uint32_t n); + void SHLR16(uint32_t n); + void SLEEP(); + void STCSR(uint32_t n); + void STCGBR(uint32_t n); + void STCVBR(uint32_t n); + void STCMSR(uint32_t n); + void STCMGBR(uint32_t n); + void STCMVBR(uint32_t n); + void STSMACH(uint32_t n); + void STSMACL(uint32_t n); + void STSPR(uint32_t n); + void STSMMACH(uint32_t n); + void STSMMACL(uint32_t n); + void STSMPR(uint32_t n); + void SUB(uint32_t m, uint32_t n); + void SUBC(uint32_t m, uint32_t n); + void SUBV(uint32_t m, uint32_t n); + void SWAPB(uint32_t m, uint32_t n); + void SWAPW(uint32_t m, uint32_t n); + void TAS(uint32_t n); + void TST(uint32_t m, uint32_t n); + void TSTI(uint32_t i); + void TSTM(uint32_t i); + void XOR(uint32_t m, uint32_t n); + void XORI(uint32_t i); + void XORM(uint32_t i); + void XTRCT(uint32_t m, uint32_t n); + + void op0010(uint16_t opcode); + void op0011(uint16_t opcode); + void op0110(uint16_t opcode); + void op1000(uint16_t opcode); + void op1100(uint16_t opcode); + + void execute_one(const uint16_t opcode); + + virtual void execute_one_0000(uint16_t opcode); + virtual void execute_one_4000(uint16_t opcode); + virtual void execute_one_f000(uint16_t opcode) = 0; + + virtual void RTE() = 0; + virtual void LDCSR(const uint16_t opcode) = 0; + virtual void LDCMSR(const uint16_t opcode) = 0; + virtual void TRAPA(uint32_t i) = 0; + virtual void ILLEGAL() = 0; + + drc_cache m_cache; /* pointer to the DRC code cache */ + +public: + /* fast RAM */ + uint32_t m_fastram_select; + struct + { + offs_t start; /* start of the RAM block */ + offs_t end; /* end of the RAM block */ + bool readonly; /* true if read-only */ + void * base; /* base in memory where the RAM lives */ + } m_fastram[SH2_MAX_FASTRAM]; + + int m_pcfsel; // last pcflush entry set + uint32_t m_pcflushes[16]; // pcflush entries + + virtual void init_drc_frontend() = 0; + + void drc_start(); + + void sh2drc_add_fastram(offs_t start, offs_t end, uint8_t readonly, void *base); + + direct_read_data<0> *m_direct; + address_space *m_program; + + std::unique_ptr<drcuml_state> m_drcuml; /* DRC UML generator state */ + uint32_t m_drcoptions; /* configurable DRC options */ + + /* internal stuff */ + uint8_t m_cache_dirty; /* true if we need to flush the cache */ + + /* register mappings */ + uml::parameter m_regmap[16]; /* parameter to register mappings for all 16 integer registers */ + + uml::code_handle * m_entry; /* entry point */ + uml::code_handle * m_read8; /* read byte */ + uml::code_handle * m_write8; /* write byte */ + uml::code_handle * m_read16; /* read half */ + uml::code_handle * m_write16; /* write half */ + uml::code_handle * m_read32; /* read word */ + uml::code_handle * m_write32; /* write word */ + + uml::code_handle * m_interrupt; /* interrupt */ + uml::code_handle * m_nocode; /* nocode */ + uml::code_handle * m_out_of_cycles; /* out of cycles exception handler */ + + /* internal compiler state */ + struct compiler_state + { + uint32_t cycles; /* accumulated cycles */ + uint8_t checkints; /* need to check interrupts before next instruction */ + uml::code_label labelnum; /* index for local labels */ + }; + + virtual void sh2_exception(const char *message, int irqline) { fatalerror("sh2_exception in base classs\n"); }; + + virtual void generate_update_cycles(drcuml_block *block, compiler_state *compiler, uml::parameter param, bool allow_exception) = 0; + + virtual bool generate_group_0_RTE(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + virtual bool generate_group_4_LDCSR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + virtual bool generate_group_4_LDCMSR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + virtual bool generate_group_12_TRAPA(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + + + bool generate_opcode(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint32_t ovrpc); + virtual bool generate_group_0(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_2(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_3(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, uint32_t ovrpc); + virtual bool generate_group_4(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_6(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_8(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_12(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + virtual bool generate_group_15(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + + void func_printf_probe(); + void func_unimplemented(); + void func_MAC_W(); + void func_MAC_L(); + void func_DIV1(); + void func_ADDV(); + void func_SUBV(); + + int m_cpu_type; + uint32_t m_am; + bool m_isdrc; + int m_xor; + + void sh2drc_set_options(uint32_t options); + void sh2drc_add_pcflush(offs_t address); + + virtual void static_generate_entry_point() = 0; + virtual void static_generate_memory_accessor(int size, int iswrite, const char *name, uml::code_handle **handleptr) = 0; + virtual const opcode_desc* get_desclist(offs_t pc) = 0; + + uint32_t epc(const opcode_desc *desc); + void alloc_handle(drcuml_state *drcuml, uml::code_handle **handleptr, const char *name); + void load_fast_iregs(drcuml_block *block); + void save_fast_iregs(drcuml_block *block); + const char *log_desc_flags_to_string(uint32_t flags); + void log_register_list(drcuml_state *drcuml, const char *string, const uint32_t *reglist, const uint32_t *regnostarlist); + void log_opcode_desc(drcuml_state *drcuml, const opcode_desc *desclist, int indent); + void log_add_disasm_comment(drcuml_block *block, uint32_t pc, uint32_t op); + void generate_delay_slot(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint32_t ovrpc); + void generate_checksum_block(drcuml_block *block, compiler_state *compiler, const opcode_desc *seqhead, const opcode_desc *seqlast); + void generate_sequence_instruction(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint32_t ovrpc); + void static_generate_nocode_handler(); + void static_generate_out_of_cycles(); + void code_flush_cache(); + void execute_run_drc(); + void code_compile_block(uint8_t mode, offs_t pc); + + +protected: + // device-level overrides + virtual void device_start() override; +}; + +class sh_frontend : public drc_frontend +{ +public: + sh_frontend(sh_common_execution *device, uint32_t window_start, uint32_t window_end, uint32_t max_sequence); + +protected: + virtual uint16_t read_word(opcode_desc &desc); + virtual bool describe(opcode_desc &desc, const opcode_desc *prev) override; + +private: + bool describe_group_2(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode); + bool describe_group_3(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode); + bool describe_group_6(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode); + bool describe_group_8(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode); + bool describe_group_12(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode); + +protected: + virtual bool describe_group_0(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode); + virtual bool describe_group_4(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode); + virtual bool describe_group_15(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) = 0; + + sh_common_execution *m_sh; +}; + +#endif // MAME_CPU_SH2_SH2_H diff --git a/src/devices/cpu/sh/sh2.cpp b/src/devices/cpu/sh/sh2.cpp index 9b1cf8dcbbf..3d565fb3519 100644 --- a/src/devices/cpu/sh/sh2.cpp +++ b/src/devices/cpu/sh/sh2.cpp @@ -95,33 +95,13 @@ #include "emu.h" #include "sh2.h" #include "sh2comn.h" - +#include "sh_dasm.h" #include "debugger.h" //#define VERBOSE 1 #include "logmacro.h" -/*************************************************************************** - DEBUGGING -***************************************************************************/ - -#define DISABLE_FAST_REGISTERS (0) // set to 1 to turn off usage of register caching -#define SINGLE_INSTRUCTION_MODE (0) - - -/*************************************************************************** - CONSTANTS -***************************************************************************/ - -/* size of the execution code cache */ -#define CACHE_SIZE (32 * 1024 * 1024) - -/* compilation boundaries -- how far back/forward does the analysis extend? */ -#define COMPILE_BACKWARDS_BYTES 64 -#define COMPILE_FORWARDS_BYTES 256 -#define COMPILE_MAX_INSTRUCTIONS ((COMPILE_BACKWARDS_BYTES/2) + (COMPILE_FORWARDS_BYTES/2)) -#define COMPILE_MAX_SEQUENCE 64 DEFINE_DEVICE_TYPE(SH1, sh1_device, "sh1", "SH-1") @@ -182,30 +162,18 @@ void sh2_device::device_stop() } + + sh2_device::sh2_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int cpu_type, address_map_constructor internal_map, int addrlines) - : cpu_device(mconfig, type, tag, owner, clock) + : sh_common_execution(mconfig, type, tag, owner, clock, ENDIANNESS_BIG, internal_map) , m_program_config("program", ENDIANNESS_BIG, 32, addrlines, 0, internal_map) , m_decrypted_program_config("decrypted_opcodes", ENDIANNESS_BIG, 32, addrlines, 0) , m_is_slave(0) - , m_cpu_type(cpu_type) - , m_cache(CACHE_SIZE + sizeof(internal_sh2_state)) - , m_drcuml(nullptr) -// , m_drcuml(*this, m_cache, 0, 1, 32, 1) , m_drcfe(nullptr) - , m_drcoptions(0) - , m_sh2_state(nullptr) - , m_entry(nullptr) - , m_read8(nullptr) - , m_write8(nullptr) - , m_read16(nullptr) - , m_write16(nullptr) - , m_read32(nullptr) - , m_write32(nullptr) - , m_interrupt(nullptr) - , m_nocode(nullptr) - , m_out_of_cycles(nullptr) , m_debugger_temp(0) { + m_cpu_type = cpu_type; + m_am = SH12_AM; m_isdrc = allow_drc(); } @@ -232,20 +200,15 @@ device_memory_interface::space_config_vector sh2_device::memory_space_config() c }; } -offs_t sh2_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *sh2_device::create_disassembler() { - extern CPU_DISASSEMBLE( sh2 ); - return CPU_DISASSEMBLE_NAME( sh2 )(this, stream, pc, oprom, opram, options); + return new sh_disassembler(false); } - -/* speed up delay loops, bail out of tight loops */ -#define BUSY_LOOP_HACKS 1 - uint8_t sh2_device::RB(offs_t A) { if((A & 0xf0000000) == 0 || (A & 0xf0000000) == 0x20000000) - return m_program->read_byte(A & AM); + return m_program->read_byte(A & SH12_AM); return m_program->read_byte(A); } @@ -253,7 +216,7 @@ uint8_t sh2_device::RB(offs_t A) uint16_t sh2_device::RW(offs_t A) { if((A & 0xf0000000) == 0 || (A & 0xf0000000) == 0x20000000) - return m_program->read_word(A & AM); + return m_program->read_word(A & SH12_AM); return m_program->read_word(A); } @@ -263,7 +226,7 @@ uint32_t sh2_device::RL(offs_t A) /* 0x20000000 no Cache */ /* 0x00000000 read thru Cache if CE bit is 1 */ if((A & 0xf0000000) == 0 || (A & 0xf0000000) == 0x20000000) - return m_program->read_dword(A & AM); + return m_program->read_dword(A & SH12_AM); return m_program->read_dword(A); } @@ -272,7 +235,7 @@ void sh2_device::WB(offs_t A, uint8_t V) { if((A & 0xf0000000) == 0 || (A & 0xf0000000) == 0x20000000) { - m_program->write_byte(A & AM,V); + m_program->write_byte(A & SH12_AM,V); return; } @@ -283,7 +246,7 @@ void sh2_device::WW(offs_t A, uint16_t V) { if((A & 0xf0000000) == 0 || (A & 0xf0000000) == 0x20000000) { - m_program->write_word(A & AM,V); + m_program->write_word(A & SH12_AM,V); return; } @@ -294,7 +257,7 @@ void sh2_device::WL(offs_t A, uint32_t V) { if((A & 0xf0000000) == 0 || (A & 0xf0000000) == 0x20000000) { - m_program->write_dword(A & AM,V); + m_program->write_dword(A & SH12_AM,V); return; } @@ -303,1528 +266,42 @@ void sh2_device::WL(offs_t A, uint32_t V) m_program->write_dword(A,V); } -/* code cycles t-bit - * 0011 nnnn mmmm 1100 1 - - * ADD Rm,Rn - */ -void sh2_device::ADD(uint32_t m, uint32_t n) -{ - m_sh2_state->r[n] += m_sh2_state->r[m]; -} - -/* code cycles t-bit - * 0111 nnnn iiii iiii 1 - - * ADD #imm,Rn - */ -void sh2_device::ADDI(uint32_t i, uint32_t n) -{ - m_sh2_state->r[n] += (int32_t)(int16_t)(int8_t)i; -} - -/* code cycles t-bit - * 0011 nnnn mmmm 1110 1 carry - * ADDC Rm,Rn - */ -void sh2_device::ADDC(uint32_t m, uint32_t n) -{ - uint32_t tmp0, tmp1; - - tmp1 = m_sh2_state->r[n] + m_sh2_state->r[m]; - tmp0 = m_sh2_state->r[n]; - m_sh2_state->r[n] = tmp1 + (m_sh2_state->sr & T); - if (tmp0 > tmp1) - m_sh2_state->sr |= T; - else - m_sh2_state->sr &= ~T; - if (tmp1 > m_sh2_state->r[n]) - m_sh2_state->sr |= T; -} - -/* code cycles t-bit - * 0011 nnnn mmmm 1111 1 overflow - * ADDV Rm,Rn - */ -void sh2_device::ADDV(uint32_t m, uint32_t n) -{ - int32_t dest, src, ans; - - if ((int32_t) m_sh2_state->r[n] >= 0) - dest = 0; - else - dest = 1; - if ((int32_t) m_sh2_state->r[m] >= 0) - src = 0; - else - src = 1; - src += dest; - m_sh2_state->r[n] += m_sh2_state->r[m]; - if ((int32_t) m_sh2_state->r[n] >= 0) - ans = 0; - else - ans = 1; - ans += dest; - if (src == 0 || src == 2) - { - if (ans == 1) - m_sh2_state->sr |= T; - else - m_sh2_state->sr &= ~T; - } - else - m_sh2_state->sr &= ~T; -} - -/* code cycles t-bit - * 0010 nnnn mmmm 1001 1 - - * AND Rm,Rn - */ -void sh2_device::AND(uint32_t m, uint32_t n) -{ - m_sh2_state->r[n] &= m_sh2_state->r[m]; -} - - -/* code cycles t-bit - * 1100 1001 iiii iiii 1 - - * AND #imm,R0 - */ -void sh2_device::ANDI(uint32_t i) -{ - m_sh2_state->r[0] &= i; -} - -/* code cycles t-bit - * 1100 1101 iiii iiii 1 - - * AND.B #imm,@(R0,GBR) - */ -void sh2_device::ANDM(uint32_t i) +/* LDC.L @Rm+,SR */ +inline void sh2_device::LDCMSR(const uint16_t opcode) // passes Rn { - uint32_t temp; + uint32_t x = Rn; - m_sh2_state->ea = m_sh2_state->gbr + m_sh2_state->r[0]; - temp = i & RB( m_sh2_state->ea ); - WB( m_sh2_state->ea, temp ); + m_sh2_state->ea = m_sh2_state->r[x]; + m_sh2_state->sr = RL( m_sh2_state->ea ) & SH_FLAGS; + m_sh2_state->r[x] += 4; m_sh2_state->icount -= 2; -} - -/* code cycles t-bit - * 1000 1011 dddd dddd 3/1 - - * BF disp8 - */ -void sh2_device::BF(uint32_t d) -{ - if ((m_sh2_state->sr & T) == 0) - { - int32_t disp = ((int32_t)d << 24) >> 24; - m_sh2_state->pc = m_sh2_state->ea = m_sh2_state->pc + disp * 2 + 2; - m_sh2_state->icount -= 2; - } -} - -/* code cycles t-bit - * 1000 1111 dddd dddd 3/1 - - * BFS disp8 - */ -void sh2_device::BFS(uint32_t d) -{ - if ((m_sh2_state->sr & T) == 0) - { - int32_t disp = ((int32_t)d << 24) >> 24; - m_delay = m_sh2_state->ea = m_sh2_state->pc + disp * 2 + 2; - m_sh2_state->icount--; - } -} - -/* code cycles t-bit - * 1010 dddd dddd dddd 2 - - * BRA disp12 - */ -void sh2_device::BRA(uint32_t d) -{ - int32_t disp = ((int32_t)d << 20) >> 20; - -#if BUSY_LOOP_HACKS - if (disp == -2) - { - uint32_t next_opcode = RW(m_sh2_state->pc & AM); - /* BRA $ - * NOP - */ - if (next_opcode == 0x0009) - m_sh2_state->icount %= 3; /* cycles for BRA $ and NOP taken (3) */ - } -#endif - m_delay = m_sh2_state->ea = m_sh2_state->pc + disp * 2 + 2; - m_sh2_state->icount--; -} - -/* code cycles t-bit - * 0000 mmmm 0010 0011 2 - - * BRAF Rm - */ -void sh2_device::BRAF(uint32_t m) -{ - m_delay = m_sh2_state->pc + m_sh2_state->r[m] + 2; - m_sh2_state->icount--; -} - -/* code cycles t-bit - * 1011 dddd dddd dddd 2 - - * BSR disp12 - */ -void sh2_device::BSR(uint32_t d) -{ - int32_t disp = ((int32_t)d << 20) >> 20; - - m_sh2_state->pr = m_sh2_state->pc + 2; - m_delay = m_sh2_state->ea = m_sh2_state->pc + disp * 2 + 2; - m_sh2_state->icount--; -} - -/* code cycles t-bit - * 0000 mmmm 0000 0011 2 - - * BSRF Rm - */ -void sh2_device::BSRF(uint32_t m) -{ - m_sh2_state->pr = m_sh2_state->pc + 2; - m_delay = m_sh2_state->pc + m_sh2_state->r[m] + 2; - m_sh2_state->icount--; -} - -/* code cycles t-bit - * 1000 1001 dddd dddd 3/1 - - * BT disp8 - */ -void sh2_device::BT(uint32_t d) -{ - if ((m_sh2_state->sr & T) != 0) - { - int32_t disp = ((int32_t)d << 24) >> 24; - m_sh2_state->pc = m_sh2_state->ea = m_sh2_state->pc + disp * 2 + 2; - m_sh2_state->icount -= 2; - } -} - -/* code cycles t-bit - * 1000 1101 dddd dddd 2/1 - - * BTS disp8 - */ -void sh2_device::BTS(uint32_t d) -{ - if ((m_sh2_state->sr & T) != 0) - { - int32_t disp = ((int32_t)d << 24) >> 24; - m_delay = m_sh2_state->ea = m_sh2_state->pc + disp * 2 + 2; - m_sh2_state->icount--; - } -} - -/* code cycles t-bit - * 0000 0000 0010 1000 1 - - * CLRMAC - */ -void sh2_device::CLRMAC() -{ - m_sh2_state->mach = 0; - m_sh2_state->macl = 0; -} - -/* code cycles t-bit - * 0000 0000 0000 1000 1 - - * CLRT - */ -void sh2_device::CLRT() -{ - m_sh2_state->sr &= ~T; -} - -/* code cycles t-bit - * 0011 nnnn mmmm 0000 1 comparison result - * CMP_EQ Rm,Rn - */ -void sh2_device::CMPEQ(uint32_t m, uint32_t n) -{ - if (m_sh2_state->r[n] == m_sh2_state->r[m]) - m_sh2_state->sr |= T; - else - m_sh2_state->sr &= ~T; -} - -/* code cycles t-bit - * 0011 nnnn mmmm 0011 1 comparison result - * CMP_GE Rm,Rn - */ -void sh2_device::CMPGE(uint32_t m, uint32_t n) -{ - if ((int32_t) m_sh2_state->r[n] >= (int32_t) m_sh2_state->r[m]) - m_sh2_state->sr |= T; - else - m_sh2_state->sr &= ~T; -} - -/* code cycles t-bit - * 0011 nnnn mmmm 0111 1 comparison result - * CMP_GT Rm,Rn - */ -void sh2_device::CMPGT(uint32_t m, uint32_t n) -{ - if ((int32_t) m_sh2_state->r[n] > (int32_t) m_sh2_state->r[m]) - m_sh2_state->sr |= T; - else - m_sh2_state->sr &= ~T; -} - -/* code cycles t-bit - * 0011 nnnn mmmm 0110 1 comparison result - * CMP_HI Rm,Rn - */ -void sh2_device::CMPHI(uint32_t m, uint32_t n) -{ - if ((uint32_t) m_sh2_state->r[n] > (uint32_t) m_sh2_state->r[m]) - m_sh2_state->sr |= T; - else - m_sh2_state->sr &= ~T; -} - -/* code cycles t-bit - * 0011 nnnn mmmm 0010 1 comparison result - * CMP_HS Rm,Rn - */ -void sh2_device::CMPHS(uint32_t m, uint32_t n) -{ - if ((uint32_t) m_sh2_state->r[n] >= (uint32_t) m_sh2_state->r[m]) - m_sh2_state->sr |= T; - else - m_sh2_state->sr &= ~T; -} - - -/* code cycles t-bit - * 0100 nnnn 0001 0101 1 comparison result - * CMP_PL Rn - */ -void sh2_device::CMPPL(uint32_t n) -{ - if ((int32_t) m_sh2_state->r[n] > 0) - m_sh2_state->sr |= T; - else - m_sh2_state->sr &= ~T; -} - -/* code cycles t-bit - * 0100 nnnn 0001 0001 1 comparison result - * CMP_PZ Rn - */ -void sh2_device::CMPPZ(uint32_t n) -{ - if ((int32_t) m_sh2_state->r[n] >= 0) - m_sh2_state->sr |= T; - else - m_sh2_state->sr &= ~T; -} - -/* code cycles t-bit - * 0010 nnnn mmmm 1100 1 comparison result - * CMP_STR Rm,Rn - */ -void sh2_device::CMPSTR(uint32_t m, uint32_t n) - { - uint32_t temp; - int32_t HH, HL, LH, LL; - temp = m_sh2_state->r[n] ^ m_sh2_state->r[m]; - HH = (temp >> 24) & 0xff; - HL = (temp >> 16) & 0xff; - LH = (temp >> 8) & 0xff; - LL = temp & 0xff; - if (HH && HL && LH && LL) - m_sh2_state->sr &= ~T; - else - m_sh2_state->sr |= T; - } - - -/* code cycles t-bit - * 1000 1000 iiii iiii 1 comparison result - * CMP/EQ #imm,R0 - */ -void sh2_device::CMPIM(uint32_t i) -{ - uint32_t imm = (uint32_t)(int32_t)(int16_t)(int8_t)i; - - if (m_sh2_state->r[0] == imm) - m_sh2_state->sr |= T; - else - m_sh2_state->sr &= ~T; -} - -/* code cycles t-bit - * 0010 nnnn mmmm 0111 1 calculation result - * DIV0S Rm,Rn - */ -void sh2_device::DIV0S(uint32_t m, uint32_t n) -{ - if ((m_sh2_state->r[n] & 0x80000000) == 0) - m_sh2_state->sr &= ~Q; - else - m_sh2_state->sr |= Q; - if ((m_sh2_state->r[m] & 0x80000000) == 0) - m_sh2_state->sr &= ~M; - else - m_sh2_state->sr |= M; - if ((m_sh2_state->r[m] ^ m_sh2_state->r[n]) & 0x80000000) - m_sh2_state->sr |= T; - else - m_sh2_state->sr &= ~T; -} - -/* code cycles t-bit - * 0000 0000 0001 1001 1 0 - * DIV0U - */ -void sh2_device::DIV0U() -{ - m_sh2_state->sr &= ~(M | Q | T); -} - -/* code cycles t-bit - * 0011 nnnn mmmm 0100 1 calculation result - * DIV1 Rm,Rn - */ -void sh2_device::DIV1(uint32_t m, uint32_t n) -{ - uint32_t tmp0; - uint32_t old_q; - - old_q = m_sh2_state->sr & Q; - if (0x80000000 & m_sh2_state->r[n]) - m_sh2_state->sr |= Q; - else - m_sh2_state->sr &= ~Q; - - m_sh2_state->r[n] = (m_sh2_state->r[n] << 1) | (m_sh2_state->sr & T); - - if (!old_q) - { - if (!(m_sh2_state->sr & M)) - { - tmp0 = m_sh2_state->r[n]; - m_sh2_state->r[n] -= m_sh2_state->r[m]; - if(!(m_sh2_state->sr & Q)) - if(m_sh2_state->r[n] > tmp0) - m_sh2_state->sr |= Q; - else - m_sh2_state->sr &= ~Q; - else - if(m_sh2_state->r[n] > tmp0) - m_sh2_state->sr &= ~Q; - else - m_sh2_state->sr |= Q; - } - else - { - tmp0 = m_sh2_state->r[n]; - m_sh2_state->r[n] += m_sh2_state->r[m]; - if(!(m_sh2_state->sr & Q)) - { - if(m_sh2_state->r[n] < tmp0) - m_sh2_state->sr &= ~Q; - else - m_sh2_state->sr |= Q; - } - else - { - if(m_sh2_state->r[n] < tmp0) - m_sh2_state->sr |= Q; - else - m_sh2_state->sr &= ~Q; - } - } - } - else - { - if (!(m_sh2_state->sr & M)) - { - tmp0 = m_sh2_state->r[n]; - m_sh2_state->r[n] += m_sh2_state->r[m]; - if(!(m_sh2_state->sr & Q)) - if(m_sh2_state->r[n] < tmp0) - m_sh2_state->sr |= Q; - else - m_sh2_state->sr &= ~Q; - else - if(m_sh2_state->r[n] < tmp0) - m_sh2_state->sr &= ~Q; - else - m_sh2_state->sr |= Q; - } - else - { - tmp0 = m_sh2_state->r[n]; - m_sh2_state->r[n] -= m_sh2_state->r[m]; - if(!(m_sh2_state->sr & Q)) - if(m_sh2_state->r[n] > tmp0) - m_sh2_state->sr &= ~Q; - else - m_sh2_state->sr |= Q; - else - if(m_sh2_state->r[n] > tmp0) - m_sh2_state->sr |= Q; - else - m_sh2_state->sr &= ~Q; - } - } - - tmp0 = (m_sh2_state->sr & (Q | M)); - if((!tmp0) || (tmp0 == 0x300)) /* if Q == M set T else clear T */ - m_sh2_state->sr |= T; - else - m_sh2_state->sr &= ~T; -} - -/* DMULS.L Rm,Rn */ -void sh2_device::DMULS(uint32_t m, uint32_t n) -{ - uint32_t RnL, RnH, RmL, RmH, Res0, Res1, Res2; - uint32_t temp0, temp1, temp2, temp3; - int32_t tempm, tempn, fnLmL; - - tempn = (int32_t) m_sh2_state->r[n]; - tempm = (int32_t) m_sh2_state->r[m]; - if (tempn < 0) - tempn = 0 - tempn; - if (tempm < 0) - tempm = 0 - tempm; - if ((int32_t) (m_sh2_state->r[n] ^ m_sh2_state->r[m]) < 0) - fnLmL = -1; - else - fnLmL = 0; - temp1 = (uint32_t) tempn; - temp2 = (uint32_t) tempm; - RnL = temp1 & 0x0000ffff; - RnH = (temp1 >> 16) & 0x0000ffff; - RmL = temp2 & 0x0000ffff; - RmH = (temp2 >> 16) & 0x0000ffff; - temp0 = RmL * RnL; - temp1 = RmH * RnL; - temp2 = RmL * RnH; - temp3 = RmH * RnH; - Res2 = 0; - Res1 = temp1 + temp2; - if (Res1 < temp1) - Res2 += 0x00010000; - temp1 = (Res1 << 16) & 0xffff0000; - Res0 = temp0 + temp1; - if (Res0 < temp0) - Res2++; - Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3; - if (fnLmL < 0) - { - Res2 = ~Res2; - if (Res0 == 0) - Res2++; - else - Res0 = (~Res0) + 1; - } - m_sh2_state->mach = Res2; - m_sh2_state->macl = Res0; - m_sh2_state->icount--; -} - -/* DMULU.L Rm,Rn */ -void sh2_device::DMULU(uint32_t m, uint32_t n) -{ - uint32_t RnL, RnH, RmL, RmH, Res0, Res1, Res2; - uint32_t temp0, temp1, temp2, temp3; - - RnL = m_sh2_state->r[n] & 0x0000ffff; - RnH = (m_sh2_state->r[n] >> 16) & 0x0000ffff; - RmL = m_sh2_state->r[m] & 0x0000ffff; - RmH = (m_sh2_state->r[m] >> 16) & 0x0000ffff; - temp0 = RmL * RnL; - temp1 = RmH * RnL; - temp2 = RmL * RnH; - temp3 = RmH * RnH; - Res2 = 0; - Res1 = temp1 + temp2; - if (Res1 < temp1) - Res2 += 0x00010000; - temp1 = (Res1 << 16) & 0xffff0000; - Res0 = temp0 + temp1; - if (Res0 < temp0) - Res2++; - Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3; - m_sh2_state->mach = Res2; - m_sh2_state->macl = Res0; - m_sh2_state->icount--; -} - -/* DT Rn */ -void sh2_device::DT(uint32_t n) -{ - m_sh2_state->r[n]--; - if (m_sh2_state->r[n] == 0) - m_sh2_state->sr |= T; - else - m_sh2_state->sr &= ~T; -#if BUSY_LOOP_HACKS - { - uint32_t next_opcode = RW(m_sh2_state->pc & AM); - /* DT Rn - * BF $-2 - */ - if (next_opcode == 0x8bfd) - { - while (m_sh2_state->r[n] > 1 && m_sh2_state->icount > 4) - { - m_sh2_state->r[n]--; - m_sh2_state->icount -= 4; /* cycles for DT (1) and BF taken (3) */ - } - } - } -#endif -} - -/* EXTS.B Rm,Rn */ -void sh2_device::EXTSB(uint32_t m, uint32_t n) -{ - m_sh2_state->r[n] = ((int32_t)m_sh2_state->r[m] << 24) >> 24; -} - -/* EXTS.W Rm,Rn */ -void sh2_device::EXTSW(uint32_t m, uint32_t n) -{ - m_sh2_state->r[n] = ((int32_t)m_sh2_state->r[m] << 16) >> 16; -} - -/* EXTU.B Rm,Rn */ -void sh2_device::EXTUB(uint32_t m, uint32_t n) -{ - m_sh2_state->r[n] = m_sh2_state->r[m] & 0x000000ff; -} - -/* EXTU.W Rm,Rn */ -void sh2_device::EXTUW(uint32_t m, uint32_t n) -{ - m_sh2_state->r[n] = m_sh2_state->r[m] & 0x0000ffff; -} - -/* ILLEGAL */ -void sh2_device::ILLEGAL() -{ - logerror("SH2.%s: Illegal opcode at %08x\n", tag(), m_sh2_state->pc - 2); - m_sh2_state->r[15] -= 4; - WL( m_sh2_state->r[15], m_sh2_state->sr ); /* push SR onto stack */ - m_sh2_state->r[15] -= 4; - WL( m_sh2_state->r[15], m_sh2_state->pc - 2 ); /* push PC onto stack */ - - /* fetch PC */ - m_sh2_state->pc = RL( m_sh2_state->vbr + 4 * 4 ); - - /* TODO: timing is a guess */ - m_sh2_state->icount -= 5; -} - - -/* JMP @Rm */ -void sh2_device::JMP(uint32_t m) -{ - m_delay = m_sh2_state->ea = m_sh2_state->r[m]; - m_sh2_state->icount--; -} - -/* JSR @Rm */ -void sh2_device::JSR(uint32_t m) -{ - m_sh2_state->pr = m_sh2_state->pc + 2; - m_delay = m_sh2_state->ea = m_sh2_state->r[m]; - m_sh2_state->icount--; -} - - -/* LDC Rm,SR */ -void sh2_device::LDCSR(uint32_t m) -{ - m_sh2_state->sr = m_sh2_state->r[m] & FLAGS; m_test_irq = 1; } -/* LDC Rm,GBR */ -void sh2_device::LDCGBR(uint32_t m) -{ - m_sh2_state->gbr = m_sh2_state->r[m]; -} - -/* LDC Rm,VBR */ -void sh2_device::LDCVBR(uint32_t m) +/* LDC Rm,SR */ +inline void sh2_device::LDCSR(const uint16_t opcode) // passes Rn { - m_sh2_state->vbr = m_sh2_state->r[m]; -} + uint32_t x = Rn; -/* LDC.L @Rm+,SR */ -void sh2_device::LDCMSR(uint32_t m) -{ - m_sh2_state->ea = m_sh2_state->r[m]; - m_sh2_state->sr = RL( m_sh2_state->ea ) & FLAGS; - m_sh2_state->r[m] += 4; - m_sh2_state->icount -= 2; + m_sh2_state->sr = m_sh2_state->r[x] & SH_FLAGS; m_test_irq = 1; } -/* LDC.L @Rm+,GBR */ -void sh2_device::LDCMGBR(uint32_t m) -{ - m_sh2_state->ea = m_sh2_state->r[m]; - m_sh2_state->gbr = RL( m_sh2_state->ea ); - m_sh2_state->r[m] += 4; - m_sh2_state->icount -= 2; -} - -/* LDC.L @Rm+,VBR */ -void sh2_device::LDCMVBR(uint32_t m) -{ - m_sh2_state->ea = m_sh2_state->r[m]; - m_sh2_state->vbr = RL( m_sh2_state->ea ); - m_sh2_state->r[m] += 4; - m_sh2_state->icount -= 2; -} - -/* LDS Rm,MACH */ -void sh2_device::LDSMACH(uint32_t m) -{ - m_sh2_state->mach = m_sh2_state->r[m]; -} - -/* LDS Rm,MACL */ -void sh2_device::LDSMACL(uint32_t m) -{ - m_sh2_state->macl = m_sh2_state->r[m]; -} - -/* LDS Rm,PR */ -void sh2_device::LDSPR(uint32_t m) -{ - m_sh2_state->pr = m_sh2_state->r[m]; -} - -/* LDS.L @Rm+,MACH */ -void sh2_device::LDSMMACH(uint32_t m) -{ - m_sh2_state->ea = m_sh2_state->r[m]; - m_sh2_state->mach = RL( m_sh2_state->ea ); - m_sh2_state->r[m] += 4; -} - -/* LDS.L @Rm+,MACL */ -void sh2_device::LDSMMACL(uint32_t m) -{ - m_sh2_state->ea = m_sh2_state->r[m]; - m_sh2_state->macl = RL( m_sh2_state->ea ); - m_sh2_state->r[m] += 4; -} - -/* LDS.L @Rm+,PR */ -void sh2_device::LDSMPR(uint32_t m) -{ - m_sh2_state->ea = m_sh2_state->r[m]; - m_sh2_state->pr = RL( m_sh2_state->ea ); - m_sh2_state->r[m] += 4; -} - -/* MAC.L @Rm+,@Rn+ */ -void sh2_device::MAC_L(uint32_t m, uint32_t n) -{ - uint32_t RnL, RnH, RmL, RmH, Res0, Res1, Res2; - uint32_t temp0, temp1, temp2, temp3; - int32_t tempm, tempn, fnLmL; - - tempn = (int32_t) RL( m_sh2_state->r[n] ); - m_sh2_state->r[n] += 4; - tempm = (int32_t) RL( m_sh2_state->r[m] ); - m_sh2_state->r[m] += 4; - if ((int32_t) (tempn ^ tempm) < 0) - fnLmL = -1; - else - fnLmL = 0; - if (tempn < 0) - tempn = 0 - tempn; - if (tempm < 0) - tempm = 0 - tempm; - temp1 = (uint32_t) tempn; - temp2 = (uint32_t) tempm; - RnL = temp1 & 0x0000ffff; - RnH = (temp1 >> 16) & 0x0000ffff; - RmL = temp2 & 0x0000ffff; - RmH = (temp2 >> 16) & 0x0000ffff; - temp0 = RmL * RnL; - temp1 = RmH * RnL; - temp2 = RmL * RnH; - temp3 = RmH * RnH; - Res2 = 0; - Res1 = temp1 + temp2; - if (Res1 < temp1) - Res2 += 0x00010000; - temp1 = (Res1 << 16) & 0xffff0000; - Res0 = temp0 + temp1; - if (Res0 < temp0) - Res2++; - Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3; - if (fnLmL < 0) - { - Res2 = ~Res2; - if (Res0 == 0) - Res2++; - else - Res0 = (~Res0) + 1; - } - if (m_sh2_state->sr & S) - { - Res0 = m_sh2_state->macl + Res0; - if (m_sh2_state->macl > Res0) - Res2++; - Res2 += (m_sh2_state->mach & 0x0000ffff); - if (((int32_t) Res2 < 0) && (Res2 < 0xffff8000)) - { - Res2 = 0x00008000; - Res0 = 0x00000000; - } - else if (((int32_t) Res2 > 0) && (Res2 > 0x00007fff)) - { - Res2 = 0x00007fff; - Res0 = 0xffffffff; - } - m_sh2_state->mach = Res2; - m_sh2_state->macl = Res0; - } - else - { - Res0 = m_sh2_state->macl + Res0; - if (m_sh2_state->macl > Res0) - Res2++; - Res2 += m_sh2_state->mach; - m_sh2_state->mach = Res2; - m_sh2_state->macl = Res0; - } - m_sh2_state->icount -= 2; -} - -/* MAC.W @Rm+,@Rn+ */ -void sh2_device::MAC_W(uint32_t m, uint32_t n) -{ - int32_t tempm, tempn, dest, src, ans; - uint32_t templ; - - tempn = (int32_t) RW( m_sh2_state->r[n] ); - m_sh2_state->r[n] += 2; - tempm = (int32_t) RW( m_sh2_state->r[m] ); - m_sh2_state->r[m] += 2; - templ = m_sh2_state->macl; - tempm = ((int32_t) (short) tempn * (int32_t) (short) tempm); - if ((int32_t) m_sh2_state->macl >= 0) - dest = 0; - else - dest = 1; - if ((int32_t) tempm >= 0) - { - src = 0; - tempn = 0; - } - else - { - src = 1; - tempn = 0xffffffff; - } - src += dest; - m_sh2_state->macl += tempm; - if ((int32_t) m_sh2_state->macl >= 0) - ans = 0; - else - ans = 1; - ans += dest; - if (m_sh2_state->sr & S) - { - if (ans == 1) - { - if (src == 0) - m_sh2_state->macl = 0x7fffffff; - if (src == 2) - m_sh2_state->macl = 0x80000000; - } - } - else - { - m_sh2_state->mach += tempn; - if (templ > m_sh2_state->macl) - m_sh2_state->mach += 1; - } - m_sh2_state->icount -= 2; -} - -/* MOV Rm,Rn */ -void sh2_device::MOV(uint32_t m, uint32_t n) -{ - m_sh2_state->r[n] = m_sh2_state->r[m]; -} - -/* MOV.B Rm,@Rn */ -void sh2_device::MOVBS(uint32_t m, uint32_t n) -{ - m_sh2_state->ea = m_sh2_state->r[n]; - WB( m_sh2_state->ea, m_sh2_state->r[m] & 0x000000ff); -} - -/* MOV.W Rm,@Rn */ -void sh2_device::MOVWS(uint32_t m, uint32_t n) -{ - m_sh2_state->ea = m_sh2_state->r[n]; - WW( m_sh2_state->ea, m_sh2_state->r[m] & 0x0000ffff); -} - -/* MOV.L Rm,@Rn */ -void sh2_device::MOVLS(uint32_t m, uint32_t n) -{ - m_sh2_state->ea = m_sh2_state->r[n]; - WL( m_sh2_state->ea, m_sh2_state->r[m] ); -} - -/* MOV.B @Rm,Rn */ -void sh2_device::MOVBL(uint32_t m, uint32_t n) -{ - m_sh2_state->ea = m_sh2_state->r[m]; - m_sh2_state->r[n] = (uint32_t)(int32_t)(int16_t)(int8_t) RB( m_sh2_state->ea ); -} - -/* MOV.W @Rm,Rn */ -void sh2_device::MOVWL(uint32_t m, uint32_t n) -{ - m_sh2_state->ea = m_sh2_state->r[m]; - m_sh2_state->r[n] = (uint32_t)(int32_t)(int16_t) RW( m_sh2_state->ea ); -} - -/* MOV.L @Rm,Rn */ -void sh2_device::MOVLL(uint32_t m, uint32_t n) -{ - m_sh2_state->ea = m_sh2_state->r[m]; - m_sh2_state->r[n] = RL( m_sh2_state->ea ); -} - -/* MOV.B Rm,@-Rn */ -void sh2_device::MOVBM(uint32_t m, uint32_t n) -{ - /* SMG : bug fix, was reading m_sh2_state->r[n] */ - uint32_t data = m_sh2_state->r[m] & 0x000000ff; - - m_sh2_state->r[n] -= 1; - WB( m_sh2_state->r[n], data ); -} - -/* MOV.W Rm,@-Rn */ -void sh2_device::MOVWM(uint32_t m, uint32_t n) -{ - uint32_t data = m_sh2_state->r[m] & 0x0000ffff; - - m_sh2_state->r[n] -= 2; - WW( m_sh2_state->r[n], data ); -} - -/* MOV.L Rm,@-Rn */ -void sh2_device::MOVLM(uint32_t m, uint32_t n) -{ - uint32_t data = m_sh2_state->r[m]; - - m_sh2_state->r[n] -= 4; - WL( m_sh2_state->r[n], data ); -} - -/* MOV.B @Rm+,Rn */ -void sh2_device::MOVBP(uint32_t m, uint32_t n) -{ - m_sh2_state->r[n] = (uint32_t)(int32_t)(int16_t)(int8_t) RB( m_sh2_state->r[m] ); - if (n != m) - m_sh2_state->r[m] += 1; -} - -/* MOV.W @Rm+,Rn */ -void sh2_device::MOVWP(uint32_t m, uint32_t n) -{ - m_sh2_state->r[n] = (uint32_t)(int32_t)(int16_t) RW( m_sh2_state->r[m] ); - if (n != m) - m_sh2_state->r[m] += 2; -} - -/* MOV.L @Rm+,Rn */ -void sh2_device::MOVLP(uint32_t m, uint32_t n) -{ - m_sh2_state->r[n] = RL( m_sh2_state->r[m] ); - if (n != m) - m_sh2_state->r[m] += 4; -} - -/* MOV.B Rm,@(R0,Rn) */ -void sh2_device::MOVBS0(uint32_t m, uint32_t n) -{ - m_sh2_state->ea = m_sh2_state->r[n] + m_sh2_state->r[0]; - WB( m_sh2_state->ea, m_sh2_state->r[m] & 0x000000ff ); -} - -/* MOV.W Rm,@(R0,Rn) */ -void sh2_device::MOVWS0(uint32_t m, uint32_t n) -{ - m_sh2_state->ea = m_sh2_state->r[n] + m_sh2_state->r[0]; - WW( m_sh2_state->ea, m_sh2_state->r[m] & 0x0000ffff ); -} - -/* MOV.L Rm,@(R0,Rn) */ -void sh2_device::MOVLS0(uint32_t m, uint32_t n) -{ - m_sh2_state->ea = m_sh2_state->r[n] + m_sh2_state->r[0]; - WL( m_sh2_state->ea, m_sh2_state->r[m] ); -} - -/* MOV.B @(R0,Rm),Rn */ -void sh2_device::MOVBL0(uint32_t m, uint32_t n) -{ - m_sh2_state->ea = m_sh2_state->r[m] + m_sh2_state->r[0]; - m_sh2_state->r[n] = (uint32_t)(int32_t)(int16_t)(int8_t) RB( m_sh2_state->ea ); -} - -/* MOV.W @(R0,Rm),Rn */ -void sh2_device::MOVWL0(uint32_t m, uint32_t n) -{ - m_sh2_state->ea = m_sh2_state->r[m] + m_sh2_state->r[0]; - m_sh2_state->r[n] = (uint32_t)(int32_t)(int16_t) RW( m_sh2_state->ea ); -} - -/* MOV.L @(R0,Rm),Rn */ -void sh2_device::MOVLL0(uint32_t m, uint32_t n) -{ - m_sh2_state->ea = m_sh2_state->r[m] + m_sh2_state->r[0]; - m_sh2_state->r[n] = RL( m_sh2_state->ea ); -} - -/* MOV #imm,Rn */ -void sh2_device::MOVI(uint32_t i, uint32_t n) -{ - m_sh2_state->r[n] = (uint32_t)(int32_t)(int16_t)(int8_t) i; -} - -/* MOV.W @(disp8,PC),Rn */ -void sh2_device::MOVWI(uint32_t d, uint32_t n) -{ - uint32_t disp = d & 0xff; - m_sh2_state->ea = m_sh2_state->pc + disp * 2 + 2; - m_sh2_state->r[n] = (uint32_t)(int32_t)(int16_t) RW( m_sh2_state->ea ); -} - -/* MOV.L @(disp8,PC),Rn */ -void sh2_device::MOVLI(uint32_t d, uint32_t n) -{ - uint32_t disp = d & 0xff; - m_sh2_state->ea = ((m_sh2_state->pc + 2) & ~3) + disp * 4; - m_sh2_state->r[n] = RL( m_sh2_state->ea ); -} - -/* MOV.B @(disp8,GBR),R0 */ -void sh2_device::MOVBLG(uint32_t d) -{ - uint32_t disp = d & 0xff; - m_sh2_state->ea = m_sh2_state->gbr + disp; - m_sh2_state->r[0] = (uint32_t)(int32_t)(int16_t)(int8_t) RB( m_sh2_state->ea ); -} - -/* MOV.W @(disp8,GBR),R0 */ -void sh2_device::MOVWLG(uint32_t d) -{ - uint32_t disp = d & 0xff; - m_sh2_state->ea = m_sh2_state->gbr + disp * 2; - m_sh2_state->r[0] = (int32_t)(int16_t) RW( m_sh2_state->ea ); -} - -/* MOV.L @(disp8,GBR),R0 */ -void sh2_device::MOVLLG(uint32_t d) -{ - uint32_t disp = d & 0xff; - m_sh2_state->ea = m_sh2_state->gbr + disp * 4; - m_sh2_state->r[0] = RL( m_sh2_state->ea ); -} - -/* MOV.B R0,@(disp8,GBR) */ -void sh2_device::MOVBSG(uint32_t d) -{ - uint32_t disp = d & 0xff; - m_sh2_state->ea = m_sh2_state->gbr + disp; - WB( m_sh2_state->ea, m_sh2_state->r[0] & 0x000000ff ); -} - -/* MOV.W R0,@(disp8,GBR) */ -void sh2_device::MOVWSG(uint32_t d) -{ - uint32_t disp = d & 0xff; - m_sh2_state->ea = m_sh2_state->gbr + disp * 2; - WW( m_sh2_state->ea, m_sh2_state->r[0] & 0x0000ffff ); -} - -/* MOV.L R0,@(disp8,GBR) */ -void sh2_device::MOVLSG(uint32_t d) -{ - uint32_t disp = d & 0xff; - m_sh2_state->ea = m_sh2_state->gbr + disp * 4; - WL( m_sh2_state->ea, m_sh2_state->r[0] ); -} - -/* MOV.B R0,@(disp4,Rn) */ -void sh2_device::MOVBS4(uint32_t d, uint32_t n) -{ - uint32_t disp = d & 0x0f; - m_sh2_state->ea = m_sh2_state->r[n] + disp; - WB( m_sh2_state->ea, m_sh2_state->r[0] & 0x000000ff ); -} - -/* MOV.W R0,@(disp4,Rn) */ -void sh2_device::MOVWS4(uint32_t d, uint32_t n) -{ - uint32_t disp = d & 0x0f; - m_sh2_state->ea = m_sh2_state->r[n] + disp * 2; - WW( m_sh2_state->ea, m_sh2_state->r[0] & 0x0000ffff ); -} - -/* MOV.L Rm,@(disp4,Rn) */ -void sh2_device::MOVLS4(uint32_t m, uint32_t d, uint32_t n) -{ - uint32_t disp = d & 0x0f; - m_sh2_state->ea = m_sh2_state->r[n] + disp * 4; - WL( m_sh2_state->ea, m_sh2_state->r[m] ); -} - -/* MOV.B @(disp4,Rm),R0 */ -void sh2_device::MOVBL4(uint32_t m, uint32_t d) -{ - uint32_t disp = d & 0x0f; - m_sh2_state->ea = m_sh2_state->r[m] + disp; - m_sh2_state->r[0] = (uint32_t)(int32_t)(int16_t)(int8_t) RB( m_sh2_state->ea ); -} - -/* MOV.W @(disp4,Rm),R0 */ -void sh2_device::MOVWL4(uint32_t m, uint32_t d) -{ - uint32_t disp = d & 0x0f; - m_sh2_state->ea = m_sh2_state->r[m] + disp * 2; - m_sh2_state->r[0] = (uint32_t)(int32_t)(int16_t) RW( m_sh2_state->ea ); -} - -/* MOV.L @(disp4,Rm),Rn */ -void sh2_device::MOVLL4(uint32_t m, uint32_t d, uint32_t n) -{ - uint32_t disp = d & 0x0f; - m_sh2_state->ea = m_sh2_state->r[m] + disp * 4; - m_sh2_state->r[n] = RL( m_sh2_state->ea ); -} - -/* MOVA @(disp8,PC),R0 */ -void sh2_device::MOVA(uint32_t d) -{ - uint32_t disp = d & 0xff; - m_sh2_state->ea = ((m_sh2_state->pc + 2) & ~3) + disp * 4; - m_sh2_state->r[0] = m_sh2_state->ea; -} - -/* MOVT Rn */ -void sh2_device::MOVT(uint32_t n) -{ - m_sh2_state->r[n] = m_sh2_state->sr & T; -} - -/* MUL.L Rm,Rn */ -void sh2_device::MULL(uint32_t m, uint32_t n) -{ - m_sh2_state->macl = m_sh2_state->r[n] * m_sh2_state->r[m]; - m_sh2_state->icount--; -} - -/* MULS Rm,Rn */ -void sh2_device::MULS(uint32_t m, uint32_t n) -{ - m_sh2_state->macl = (int16_t) m_sh2_state->r[n] * (int16_t) m_sh2_state->r[m]; -} - -/* MULU Rm,Rn */ -void sh2_device::MULU(uint32_t m, uint32_t n) -{ - m_sh2_state->macl = (uint16_t) m_sh2_state->r[n] * (uint16_t) m_sh2_state->r[m]; -} - -/* NEG Rm,Rn */ -void sh2_device::NEG(uint32_t m, uint32_t n) -{ - m_sh2_state->r[n] = 0 - m_sh2_state->r[m]; -} - -/* NEGC Rm,Rn */ -void sh2_device::NEGC(uint32_t m, uint32_t n) -{ - uint32_t temp; - - temp = m_sh2_state->r[m]; - m_sh2_state->r[n] = -temp - (m_sh2_state->sr & T); - if (temp || (m_sh2_state->sr & T)) - m_sh2_state->sr |= T; - else - m_sh2_state->sr &= ~T; -} - -/* NOP */ -void sh2_device::NOP(void) -{ -} - -/* NOT Rm,Rn */ -void sh2_device::NOT(uint32_t m, uint32_t n) -{ - m_sh2_state->r[n] = ~m_sh2_state->r[m]; -} - -/* OR Rm,Rn */ -void sh2_device::OR(uint32_t m, uint32_t n) -{ - m_sh2_state->r[n] |= m_sh2_state->r[m]; -} - -/* OR #imm,R0 */ -void sh2_device::ORI(uint32_t i) -{ - m_sh2_state->r[0] |= i; -} - -/* OR.B #imm,@(R0,GBR) */ -void sh2_device::ORM(uint32_t i) -{ - uint32_t temp; - - m_sh2_state->ea = m_sh2_state->gbr + m_sh2_state->r[0]; - temp = RB( m_sh2_state->ea ); - temp |= i; - WB( m_sh2_state->ea, temp ); - m_sh2_state->icount -= 2; -} - -/* ROTCL Rn */ -void sh2_device::ROTCL(uint32_t n) -{ - uint32_t temp; - - temp = (m_sh2_state->r[n] >> 31) & T; - m_sh2_state->r[n] = (m_sh2_state->r[n] << 1) | (m_sh2_state->sr & T); - m_sh2_state->sr = (m_sh2_state->sr & ~T) | temp; -} - -/* ROTCR Rn */ -void sh2_device::ROTCR(uint32_t n) -{ - uint32_t temp; - temp = (m_sh2_state->sr & T) << 31; - if (m_sh2_state->r[n] & T) - m_sh2_state->sr |= T; - else - m_sh2_state->sr &= ~T; - m_sh2_state->r[n] = (m_sh2_state->r[n] >> 1) | temp; -} - -/* ROTL Rn */ -void sh2_device::ROTL(uint32_t n) -{ - m_sh2_state->sr = (m_sh2_state->sr & ~T) | ((m_sh2_state->r[n] >> 31) & T); - m_sh2_state->r[n] = (m_sh2_state->r[n] << 1) | (m_sh2_state->r[n] >> 31); -} - -/* ROTR Rn */ -void sh2_device::ROTR(uint32_t n) -{ - m_sh2_state->sr = (m_sh2_state->sr & ~T) | (m_sh2_state->r[n] & T); - m_sh2_state->r[n] = (m_sh2_state->r[n] >> 1) | (m_sh2_state->r[n] << 31); -} - /* RTE */ -void sh2_device::RTE() +inline void sh2_device::RTE() { m_sh2_state->ea = m_sh2_state->r[15]; - m_delay = RL( m_sh2_state->ea ); + m_sh2_state->m_delay = RL( m_sh2_state->ea ); m_sh2_state->r[15] += 4; m_sh2_state->ea = m_sh2_state->r[15]; - m_sh2_state->sr = RL( m_sh2_state->ea ) & FLAGS; + m_sh2_state->sr = RL( m_sh2_state->ea ) & SH_FLAGS; m_sh2_state->r[15] += 4; m_sh2_state->icount -= 3; m_test_irq = 1; } -/* RTS */ -void sh2_device::RTS() -{ - m_delay = m_sh2_state->ea = m_sh2_state->pr; - m_sh2_state->icount--; -} - -/* SETT */ -void sh2_device::SETT() -{ - m_sh2_state->sr |= T; -} - -/* SHAL Rn (same as SHLL) */ -void sh2_device::SHAL(uint32_t n) -{ - m_sh2_state->sr = (m_sh2_state->sr & ~T) | ((m_sh2_state->r[n] >> 31) & T); - m_sh2_state->r[n] <<= 1; -} - -/* SHAR Rn */ -void sh2_device::SHAR(uint32_t n) -{ - m_sh2_state->sr = (m_sh2_state->sr & ~T) | (m_sh2_state->r[n] & T); - m_sh2_state->r[n] = (uint32_t)((int32_t)m_sh2_state->r[n] >> 1); -} - -/* SHLL Rn (same as SHAL) */ -void sh2_device::SHLL(uint32_t n) -{ - m_sh2_state->sr = (m_sh2_state->sr & ~T) | ((m_sh2_state->r[n] >> 31) & T); - m_sh2_state->r[n] <<= 1; -} - -/* SHLL2 Rn */ -void sh2_device::SHLL2(uint32_t n) -{ - m_sh2_state->r[n] <<= 2; -} - -/* SHLL8 Rn */ -void sh2_device::SHLL8(uint32_t n) -{ - m_sh2_state->r[n] <<= 8; -} - -/* SHLL16 Rn */ -void sh2_device::SHLL16(uint32_t n) -{ - m_sh2_state->r[n] <<= 16; -} - -/* SHLR Rn */ -void sh2_device::SHLR(uint32_t n) -{ - m_sh2_state->sr = (m_sh2_state->sr & ~T) | (m_sh2_state->r[n] & T); - m_sh2_state->r[n] >>= 1; -} - -/* SHLR2 Rn */ -void sh2_device::SHLR2(uint32_t n) -{ - m_sh2_state->r[n] >>= 2; -} - -/* SHLR8 Rn */ -void sh2_device::SHLR8(uint32_t n) -{ - m_sh2_state->r[n] >>= 8; -} - -/* SHLR16 Rn */ -void sh2_device::SHLR16(uint32_t n) -{ - m_sh2_state->r[n] >>= 16; -} - -/* SLEEP */ -void sh2_device::SLEEP() -{ - if(m_sh2_state->sleep_mode != 2) - m_sh2_state->pc -= 2; - m_sh2_state->icount -= 2; - /* Wait_for_exception; */ - if(m_sh2_state->sleep_mode == 0) - m_sh2_state->sleep_mode = 1; - else if(m_sh2_state->sleep_mode == 2) - m_sh2_state->sleep_mode = 0; -} - -/* STC SR,Rn */ -void sh2_device::STCSR(uint32_t n) -{ - m_sh2_state->r[n] = m_sh2_state->sr; -} - -/* STC GBR,Rn */ -void sh2_device::STCGBR(uint32_t n) -{ - m_sh2_state->r[n] = m_sh2_state->gbr; -} - -/* STC VBR,Rn */ -void sh2_device::STCVBR(uint32_t n) -{ - m_sh2_state->r[n] = m_sh2_state->vbr; -} - -/* STC.L SR,@-Rn */ -void sh2_device::STCMSR(uint32_t n) -{ - m_sh2_state->r[n] -= 4; - m_sh2_state->ea = m_sh2_state->r[n]; - WL( m_sh2_state->ea, m_sh2_state->sr ); - m_sh2_state->icount--; -} - -/* STC.L GBR,@-Rn */ -void sh2_device::STCMGBR(uint32_t n) -{ - m_sh2_state->r[n] -= 4; - m_sh2_state->ea = m_sh2_state->r[n]; - WL( m_sh2_state->ea, m_sh2_state->gbr ); - m_sh2_state->icount--; -} - -/* STC.L VBR,@-Rn */ -void sh2_device::STCMVBR(uint32_t n) -{ - m_sh2_state->r[n] -= 4; - m_sh2_state->ea = m_sh2_state->r[n]; - WL( m_sh2_state->ea, m_sh2_state->vbr ); - m_sh2_state->icount--; -} - -/* STS MACH,Rn */ -void sh2_device::STSMACH(uint32_t n) -{ - m_sh2_state->r[n] = m_sh2_state->mach; -} - -/* STS MACL,Rn */ -void sh2_device::STSMACL(uint32_t n) -{ - m_sh2_state->r[n] = m_sh2_state->macl; -} - -/* STS PR,Rn */ -void sh2_device::STSPR(uint32_t n) -{ - m_sh2_state->r[n] = m_sh2_state->pr; -} - -/* STS.L MACH,@-Rn */ -void sh2_device::STSMMACH(uint32_t n) -{ - m_sh2_state->r[n] -= 4; - m_sh2_state->ea = m_sh2_state->r[n]; - WL( m_sh2_state->ea, m_sh2_state->mach ); -} - -/* STS.L MACL,@-Rn */ -void sh2_device::STSMMACL(uint32_t n) -{ - m_sh2_state->r[n] -= 4; - m_sh2_state->ea = m_sh2_state->r[n]; - WL( m_sh2_state->ea, m_sh2_state->macl ); -} - -/* STS.L PR,@-Rn */ -void sh2_device::STSMPR(uint32_t n) -{ - m_sh2_state->r[n] -= 4; - m_sh2_state->ea = m_sh2_state->r[n]; - WL( m_sh2_state->ea, m_sh2_state->pr ); -} - -/* SUB Rm,Rn */ -void sh2_device::SUB(uint32_t m, uint32_t n) -{ - m_sh2_state->r[n] -= m_sh2_state->r[m]; -} - -/* SUBC Rm,Rn */ -void sh2_device::SUBC(uint32_t m, uint32_t n) -{ - uint32_t tmp0, tmp1; - - tmp1 = m_sh2_state->r[n] - m_sh2_state->r[m]; - tmp0 = m_sh2_state->r[n]; - m_sh2_state->r[n] = tmp1 - (m_sh2_state->sr & T); - if (tmp0 < tmp1) - m_sh2_state->sr |= T; - else - m_sh2_state->sr &= ~T; - if (tmp1 < m_sh2_state->r[n]) - m_sh2_state->sr |= T; -} - -/* SUBV Rm,Rn */ -void sh2_device::SUBV(uint32_t m, uint32_t n) -{ - int32_t dest, src, ans; - - if ((int32_t) m_sh2_state->r[n] >= 0) - dest = 0; - else - dest = 1; - if ((int32_t) m_sh2_state->r[m] >= 0) - src = 0; - else - src = 1; - src += dest; - m_sh2_state->r[n] -= m_sh2_state->r[m]; - if ((int32_t) m_sh2_state->r[n] >= 0) - ans = 0; - else - ans = 1; - ans += dest; - if (src == 1) - { - if (ans == 1) - m_sh2_state->sr |= T; - else - m_sh2_state->sr &= ~T; - } - else - m_sh2_state->sr &= ~T; -} - -/* SWAP.B Rm,Rn */ -void sh2_device::SWAPB(uint32_t m, uint32_t n) -{ - uint32_t temp0, temp1; - - temp0 = m_sh2_state->r[m] & 0xffff0000; - temp1 = (m_sh2_state->r[m] & 0x000000ff) << 8; - m_sh2_state->r[n] = (m_sh2_state->r[m] >> 8) & 0x000000ff; - m_sh2_state->r[n] = m_sh2_state->r[n] | temp1 | temp0; -} - -/* SWAP.W Rm,Rn */ -void sh2_device::SWAPW(uint32_t m, uint32_t n) -{ - uint32_t temp; - - temp = (m_sh2_state->r[m] >> 16) & 0x0000ffff; - m_sh2_state->r[n] = (m_sh2_state->r[m] << 16) | temp; -} - -/* TAS.B @Rn */ -void sh2_device::TAS(uint32_t n) -{ - uint32_t temp; - m_sh2_state->ea = m_sh2_state->r[n]; - /* Bus Lock enable */ - temp = RB( m_sh2_state->ea ); - if (temp == 0) - m_sh2_state->sr |= T; - else - m_sh2_state->sr &= ~T; - temp |= 0x80; - /* Bus Lock disable */ - WB( m_sh2_state->ea, temp ); - m_sh2_state->icount -= 3; -} - /* TRAPA #imm */ -void sh2_device::TRAPA(uint32_t i) +inline void sh2_device::TRAPA(uint32_t i) { uint32_t imm = i & 0xff; @@ -1840,388 +317,28 @@ void sh2_device::TRAPA(uint32_t i) m_sh2_state->icount -= 7; } -/* TST Rm,Rn */ -void sh2_device::TST(uint32_t m, uint32_t n) -{ - if ((m_sh2_state->r[n] & m_sh2_state->r[m]) == 0) - m_sh2_state->sr |= T; - else - m_sh2_state->sr &= ~T; -} - -/* TST #imm,R0 */ -void sh2_device::TSTI(uint32_t i) -{ - uint32_t imm = i & 0xff; - - if ((imm & m_sh2_state->r[0]) == 0) - m_sh2_state->sr |= T; - else - m_sh2_state->sr &= ~T; -} - -/* TST.B #imm,@(R0,GBR) */ -void sh2_device::TSTM(uint32_t i) -{ - uint32_t imm = i & 0xff; - - m_sh2_state->ea = m_sh2_state->gbr + m_sh2_state->r[0]; - if ((imm & RB( m_sh2_state->ea )) == 0) - m_sh2_state->sr |= T; - else - m_sh2_state->sr &= ~T; - m_sh2_state->icount -= 2; -} - -/* XOR Rm,Rn */ -void sh2_device::XOR(uint32_t m, uint32_t n) -{ - m_sh2_state->r[n] ^= m_sh2_state->r[m]; -} - -/* XOR #imm,R0 */ -void sh2_device::XORI(uint32_t i) -{ - uint32_t imm = i & 0xff; - m_sh2_state->r[0] ^= imm; -} - -/* XOR.B #imm,@(R0,GBR) */ -void sh2_device::XORM(uint32_t i) +/* ILLEGAL */ +inline void sh2_device::ILLEGAL() { - uint32_t imm = i & 0xff; - uint32_t temp; - - m_sh2_state->ea = m_sh2_state->gbr + m_sh2_state->r[0]; - temp = RB( m_sh2_state->ea ); - temp ^= imm; - WB( m_sh2_state->ea, temp ); - m_sh2_state->icount -= 2; -} + //logerror("Illegal opcode at %08x\n", m_sh2_state->pc - 2); + m_sh2_state->r[15] -= 4; + WL( m_sh2_state->r[15], m_sh2_state->sr ); /* push SR onto stack */ + m_sh2_state->r[15] -= 4; + WL( m_sh2_state->r[15], m_sh2_state->pc - 2 ); /* push PC onto stack */ -/* XTRCT Rm,Rn */ -void sh2_device::XTRCT(uint32_t m, uint32_t n) -{ - uint32_t temp; + /* fetch PC */ + m_sh2_state->pc = RL( m_sh2_state->vbr + 4 * 4 ); - temp = (m_sh2_state->r[m] << 16) & 0xffff0000; - m_sh2_state->r[n] = (m_sh2_state->r[n] >> 16) & 0x0000ffff; - m_sh2_state->r[n] |= temp; + /* TODO: timing is a guess */ + m_sh2_state->icount -= 5; } /***************************************************************************** * OPCODE DISPATCHERS *****************************************************************************/ -void sh2_device::op0000(uint16_t opcode) -{ - switch (opcode & 0x3F) - { - case 0x00: ILLEGAL(); break; - case 0x01: ILLEGAL(); break; - case 0x02: STCSR(Rn); break; - case 0x03: BSRF(Rn); break; - case 0x04: MOVBS0(Rm, Rn); break; - case 0x05: MOVWS0(Rm, Rn); break; - case 0x06: MOVLS0(Rm, Rn); break; - case 0x07: MULL(Rm, Rn); break; - case 0x08: CLRT(); break; - case 0x09: NOP(); break; - case 0x0a: STSMACH(Rn); break; - case 0x0b: RTS(); break; - case 0x0c: MOVBL0(Rm, Rn); break; - case 0x0d: MOVWL0(Rm, Rn); break; - case 0x0e: MOVLL0(Rm, Rn); break; - case 0x0f: MAC_L(Rm, Rn); break; - - case 0x10: ILLEGAL(); break; - case 0x11: ILLEGAL(); break; - case 0x12: STCGBR(Rn); break; - case 0x13: ILLEGAL(); break; - case 0x14: MOVBS0(Rm, Rn); break; - case 0x15: MOVWS0(Rm, Rn); break; - case 0x16: MOVLS0(Rm, Rn); break; - case 0x17: MULL(Rm, Rn); break; - case 0x18: SETT(); break; - case 0x19: DIV0U(); break; - case 0x1a: STSMACL(Rn); break; - case 0x1b: SLEEP(); break; - case 0x1c: MOVBL0(Rm, Rn); break; - case 0x1d: MOVWL0(Rm, Rn); break; - case 0x1e: MOVLL0(Rm, Rn); break; - case 0x1f: MAC_L(Rm, Rn); break; - - case 0x20: ILLEGAL(); break; - case 0x21: ILLEGAL(); break; - case 0x22: STCVBR(Rn); break; - case 0x23: BRAF(Rn); break; - case 0x24: MOVBS0(Rm, Rn); break; - case 0x25: MOVWS0(Rm, Rn); break; - case 0x26: MOVLS0(Rm, Rn); break; - case 0x27: MULL(Rm, Rn); break; - case 0x28: CLRMAC(); break; - case 0x29: MOVT(Rn); break; - case 0x2a: STSPR(Rn); break; - case 0x2b: RTE(); break; - case 0x2c: MOVBL0(Rm, Rn); break; - case 0x2d: MOVWL0(Rm, Rn); break; - case 0x2e: MOVLL0(Rm, Rn); break; - case 0x2f: MAC_L(Rm, Rn); break; - - case 0x30: ILLEGAL(); break; - case 0x31: ILLEGAL(); break; - case 0x32: ILLEGAL(); break; - case 0x33: ILLEGAL(); break; - case 0x34: MOVBS0(Rm, Rn); break; - case 0x35: MOVWS0(Rm, Rn); break; - case 0x36: MOVLS0(Rm, Rn); break; - case 0x37: MULL(Rm, Rn); break; - case 0x38: ILLEGAL(); break; - case 0x39: ILLEGAL(); break; - case 0x3c: MOVBL0(Rm, Rn); break; - case 0x3d: MOVWL0(Rm, Rn); break; - case 0x3e: MOVLL0(Rm, Rn); break; - case 0x3f: MAC_L(Rm, Rn); break; - case 0x3a: ILLEGAL(); break; - case 0x3b: ILLEGAL(); break; - - - - } -} - -void sh2_device::op0001(uint16_t opcode) -{ - MOVLS4(Rm, opcode & 0x0f, Rn); -} -void sh2_device::op0010(uint16_t opcode) -{ - switch (opcode & 15) - { - case 0: MOVBS(Rm, Rn); break; - case 1: MOVWS(Rm, Rn); break; - case 2: MOVLS(Rm, Rn); break; - case 3: ILLEGAL(); break; - case 4: MOVBM(Rm, Rn); break; - case 5: MOVWM(Rm, Rn); break; - case 6: MOVLM(Rm, Rn); break; - case 7: DIV0S(Rm, Rn); break; - case 8: TST(Rm, Rn); break; - case 9: AND(Rm, Rn); break; - case 10: XOR(Rm, Rn); break; - case 11: OR(Rm, Rn); break; - case 12: CMPSTR(Rm, Rn); break; - case 13: XTRCT(Rm, Rn); break; - case 14: MULU(Rm, Rn); break; - case 15: MULS(Rm, Rn); break; - } -} - -void sh2_device::op0011(uint16_t opcode) -{ - switch (opcode & 15) - { - case 0: CMPEQ(Rm, Rn); break; - case 1: ILLEGAL(); break; - case 2: CMPHS(Rm, Rn); break; - case 3: CMPGE(Rm, Rn); break; - case 4: DIV1(Rm, Rn); break; - case 5: DMULU(Rm, Rn); break; - case 6: CMPHI(Rm, Rn); break; - case 7: CMPGT(Rm, Rn); break; - case 8: SUB(Rm, Rn); break; - case 9: ILLEGAL(); break; - case 10: SUBC(Rm, Rn); break; - case 11: SUBV(Rm, Rn); break; - case 12: ADD(Rm, Rn); break; - case 13: DMULS(Rm, Rn); break; - case 14: ADDC(Rm, Rn); break; - case 15: ADDV(Rm, Rn); break; - } -} - -void sh2_device::op0100(uint16_t opcode) -{ - switch (opcode & 0x3F) - { - case 0x00: SHLL(Rn); break; - case 0x01: SHLR(Rn); break; - case 0x02: STSMMACH(Rn); break; - case 0x03: STCMSR(Rn); break; - case 0x04: ROTL(Rn); break; - case 0x05: ROTR(Rn); break; - case 0x06: LDSMMACH(Rn); break; - case 0x07: LDCMSR(Rn); break; - case 0x08: SHLL2(Rn); break; - case 0x09: SHLR2(Rn); break; - case 0x0a: LDSMACH(Rn); break; - case 0x0b: JSR(Rn); break; - case 0x0c: ILLEGAL(); break; - case 0x0d: ILLEGAL(); break; - case 0x0e: LDCSR(Rn); break; - case 0x0f: MAC_W(Rm, Rn); break; - - case 0x10: DT(Rn); break; - case 0x11: CMPPZ(Rn); break; - case 0x12: STSMMACL(Rn); break; - case 0x13: STCMGBR(Rn); break; - case 0x14: ILLEGAL(); break; - case 0x15: CMPPL(Rn); break; - case 0x16: LDSMMACL(Rn); break; - case 0x17: LDCMGBR(Rn); break; - case 0x18: SHLL8(Rn); break; - case 0x19: SHLR8(Rn); break; - case 0x1a: LDSMACL(Rn); break; - case 0x1b: TAS(Rn); break; - case 0x1c: ILLEGAL(); break; - case 0x1d: ILLEGAL(); break; - case 0x1e: LDCGBR(Rn); break; - case 0x1f: MAC_W(Rm, Rn); break; - - case 0x20: SHAL(Rn); break; - case 0x21: SHAR(Rn); break; - case 0x22: STSMPR(Rn); break; - case 0x23: STCMVBR(Rn); break; - case 0x24: ROTCL(Rn); break; - case 0x25: ROTCR(Rn); break; - case 0x26: LDSMPR(Rn); break; - case 0x27: LDCMVBR(Rn); break; - case 0x28: SHLL16(Rn); break; - case 0x29: SHLR16(Rn); break; - case 0x2a: LDSPR(Rn); break; - case 0x2b: JMP(Rn); break; - case 0x2c: ILLEGAL(); break; - case 0x2d: ILLEGAL(); break; - case 0x2e: LDCVBR(Rn); break; - case 0x2f: MAC_W(Rm, Rn); break; - - case 0x30: ILLEGAL(); break; - case 0x31: ILLEGAL(); break; - case 0x32: ILLEGAL(); break; - case 0x33: ILLEGAL(); break; - case 0x34: ILLEGAL(); break; - case 0x35: ILLEGAL(); break; - case 0x36: ILLEGAL(); break; - case 0x37: ILLEGAL(); break; - case 0x38: ILLEGAL(); break; - case 0x39: ILLEGAL(); break; - case 0x3a: ILLEGAL(); break; - case 0x3b: ILLEGAL(); break; - case 0x3c: ILLEGAL(); break; - case 0x3d: ILLEGAL(); break; - case 0x3e: ILLEGAL(); break; - case 0x3f: MAC_W(Rm, Rn); break; - - } -} - -void sh2_device::op0101(uint16_t opcode) -{ - MOVLL4(Rm, opcode & 0x0f, Rn); -} - -void sh2_device::op0110(uint16_t opcode) -{ - switch (opcode & 15) - { - case 0: MOVBL(Rm, Rn); break; - case 1: MOVWL(Rm, Rn); break; - case 2: MOVLL(Rm, Rn); break; - case 3: MOV(Rm, Rn); break; - case 4: MOVBP(Rm, Rn); break; - case 5: MOVWP(Rm, Rn); break; - case 6: MOVLP(Rm, Rn); break; - case 7: NOT(Rm, Rn); break; - case 8: SWAPB(Rm, Rn); break; - case 9: SWAPW(Rm, Rn); break; - case 10: NEGC(Rm, Rn); break; - case 11: NEG(Rm, Rn); break; - case 12: EXTUB(Rm, Rn); break; - case 13: EXTUW(Rm, Rn); break; - case 14: EXTSB(Rm, Rn); break; - case 15: EXTSW(Rm, Rn); break; - } -} - -void sh2_device::op0111(uint16_t opcode) -{ - ADDI(opcode & 0xff, Rn); -} - -void sh2_device::op1000(uint16_t opcode) -{ - switch ( opcode & (15<<8) ) - { - case 0 << 8: MOVBS4(opcode & 0x0f, Rm); break; - case 1 << 8: MOVWS4(opcode & 0x0f, Rm); break; - case 2<< 8: ILLEGAL(); break; - case 3<< 8: ILLEGAL(); break; - case 4<< 8: MOVBL4(Rm, opcode & 0x0f); break; - case 5<< 8: MOVWL4(Rm, opcode & 0x0f); break; - case 6<< 8: ILLEGAL(); break; - case 7<< 8: ILLEGAL(); break; - case 8<< 8: CMPIM(opcode & 0xff); break; - case 9<< 8: BT(opcode & 0xff); break; - case 10<< 8: ILLEGAL(); break; - case 11<< 8: BF(opcode & 0xff); break; - case 12<< 8: ILLEGAL(); break; - case 13<< 8: BTS(opcode & 0xff); break; - case 14<< 8: ILLEGAL(); break; - case 15<< 8: BFS(opcode & 0xff); break; - } -} - - -void sh2_device::op1001(uint16_t opcode) -{ - MOVWI(opcode & 0xff, Rn); -} - -void sh2_device::op1010(uint16_t opcode) -{ - BRA(opcode & 0xfff); -} - -void sh2_device::op1011(uint16_t opcode) -{ - BSR(opcode & 0xfff); -} - -void sh2_device::op1100(uint16_t opcode) -{ - switch (opcode & (15<<8)) - { - case 0<<8: MOVBSG(opcode & 0xff); break; - case 1<<8: MOVWSG(opcode & 0xff); break; - case 2<<8: MOVLSG(opcode & 0xff); break; - case 3<<8: TRAPA(opcode & 0xff); break; - case 4<<8: MOVBLG(opcode & 0xff); break; - case 5<<8: MOVWLG(opcode & 0xff); break; - case 6<<8: MOVLLG(opcode & 0xff); break; - case 7<<8: MOVA(opcode & 0xff); break; - case 8<<8: TSTI(opcode & 0xff); break; - case 9<<8: ANDI(opcode & 0xff); break; - case 10<<8: XORI(opcode & 0xff); break; - case 11<<8: ORI(opcode & 0xff); break; - case 12<<8: TSTM(opcode & 0xff); break; - case 13<<8: ANDM(opcode & 0xff); break; - case 14<<8: XORM(opcode & 0xff); break; - case 15<<8: ORM(opcode & 0xff); break; - } -} - -void sh2_device::op1101(uint16_t opcode) -{ - MOVLI(opcode & 0xff, Rn); -} - -void sh2_device::op1110(uint16_t opcode) -{ - MOVI(opcode & 0xff, Rn); -} - -void sh2_device::op1111(uint16_t opcode) +void sh2_device::execute_one_f000(uint16_t opcode) { ILLEGAL(); } @@ -2235,9 +352,10 @@ void sh2_device::device_reset() m_sh2_state->pc = m_sh2_state->pr = m_sh2_state->sr = m_sh2_state->gbr = m_sh2_state->vbr = m_sh2_state->mach = m_sh2_state->macl = 0; m_sh2_state->evec = m_sh2_state->irqsr = 0; memset(&m_sh2_state->r[0], 0, sizeof(m_sh2_state->r[0])*16); - m_sh2_state->ea = m_delay = m_cpu_off = m_dvsr = m_dvdnth = m_dvdntl = m_dvcr = 0; + m_sh2_state->ea = m_sh2_state->m_delay = m_cpu_off = 0; + //m_dvsr = m_dvdnth = m_dvdntl = m_dvcr = 0; m_sh2_state->pending_irq = m_test_irq = 0; - memset(&m_irq_queue[0], 0, sizeof(m_irq_queue[0])*16); + //memset(&m_irq_queue[0], 0, sizeof(m_irq_queue[0])*16); memset(&m_irq_line_state[0], 0, sizeof(m_irq_line_state[0])*17); m_frc = m_ocra = m_ocrb = m_icr = 0; m_frc_base = 0; @@ -2249,7 +367,7 @@ void sh2_device::device_reset() m_sh2_state->pc = RL(0); m_sh2_state->r[15] = RL(4); - m_sh2_state->sr = I; + m_sh2_state->sr = SH_I; m_sh2_state->sleep_mode = 0; m_sh2_state->internal_irq_level = -1; @@ -2273,55 +391,23 @@ void sh2_device::execute_run() return; } - // run any active DMAs now -#ifndef USE_TIMER_FOR_DMA - for ( int i = 0; i < m_sh2_state->icount ; i++) - { - for( int dma=0;dma<1;dma++) - { - if (m_dma_timer_active[dma]) - sh2_do_dma(dma); - } - } -#endif - do { - uint32_t opcode; - debugger_instruction_hook(this, m_sh2_state->pc); - opcode = m_program->read_word(m_sh2_state->pc & AM); + const uint16_t opcode = m_program->read_word(m_sh2_state->pc & SH12_AM); - if (m_delay) + if (m_sh2_state->m_delay) { - m_sh2_state->pc = m_delay; - m_delay = 0; + m_sh2_state->pc = m_sh2_state->m_delay; + m_sh2_state->m_delay = 0; } else m_sh2_state->pc += 2; - switch (opcode & ( 15 << 12)) - { - case 0<<12: op0000(opcode); break; - case 1<<12: op0001(opcode); break; - case 2<<12: op0010(opcode); break; - case 3<<12: op0011(opcode); break; - case 4<<12: op0100(opcode); break; - case 5<<12: op0101(opcode); break; - case 6<<12: op0110(opcode); break; - case 7<<12: op0111(opcode); break; - case 8<<12: op1000(opcode); break; - case 9<<12: op1001(opcode); break; - case 10<<12: op1010(opcode); break; - case 11<<12: op1011(opcode); break; - case 12<<12: op1100(opcode); break; - case 13<<12: op1101(opcode); break; - case 14<<12: op1110(opcode); break; - default: op1111(opcode); break; - } + execute_one(opcode); - if(m_test_irq && !m_delay) + if(m_test_irq && !m_sh2_state->m_delay) { CHECK_PENDING_IRQ("mame_sh2_execute"); m_test_irq = 0; @@ -2330,10 +416,15 @@ void sh2_device::execute_run() } while( m_sh2_state->icount > 0 ); } + +void sh2_device::init_drc_frontend() +{ + m_drcfe = std::make_unique<sh2_frontend>(this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, SINGLE_INSTRUCTION_MODE ? 1 : COMPILE_MAX_SEQUENCE); +} + void sh2_device::device_start() { - /* allocate the implementation-specific state from the full cache */ - m_sh2_state = (internal_sh2_state *)m_cache.alloc_near(sizeof(internal_sh2_state)); + sh_common_execution::device_start(); m_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sh2_device::sh2_timer_callback), this)); m_timer->adjust(attotime::never); @@ -2349,41 +440,26 @@ void sh2_device::device_start() m_dma_fifo_data_available_cb.bind_relative_to(*owner()); m_ftcsr_read_cb.bind_relative_to(*owner()); - m_program = &space(AS_PROGRAM); m_decrypted_program = has_space(AS_OPCODES) ? &space(AS_OPCODES) : &space(AS_PROGRAM); - m_direct = &m_decrypted_program->direct(); + m_direct = m_decrypted_program->direct<0>(); m_internal = &space(AS_PROGRAM); - save_item(NAME(m_sh2_state->pc)); - save_item(NAME(m_sh2_state->sr)); - save_item(NAME(m_sh2_state->pr)); - save_item(NAME(m_sh2_state->gbr)); - save_item(NAME(m_sh2_state->vbr)); - save_item(NAME(m_sh2_state->mach)); - save_item(NAME(m_sh2_state->macl)); - save_item(NAME(m_sh2_state->r)); - save_item(NAME(m_sh2_state->ea)); - save_item(NAME(m_delay)); save_item(NAME(m_cpu_off)); - save_item(NAME(m_dvsr)); - save_item(NAME(m_dvdnth)); - save_item(NAME(m_dvdntl)); - save_item(NAME(m_dvcr)); - save_item(NAME(m_sh2_state->pending_irq)); + //save_item(NAME(m_dvsr)); + //save_item(NAME(m_dvdnth)); + //save_item(NAME(m_dvdntl)); + //save_item(NAME(m_dvcr)); save_item(NAME(m_test_irq)); - save_item(NAME(m_sh2_state->pending_nmi)); - save_item(NAME(m_sh2_state->irqline)); - save_item(NAME(m_sh2_state->evec)); - save_item(NAME(m_sh2_state->irqsr)); - save_item(NAME(m_sh2_state->target)); + + /* for (int i = 0; i < 16; ++i) { - save_item(NAME(m_irq_queue[i].irq_vector), i); - save_item(NAME(m_irq_queue[i].irq_priority), i); + save_item(NAME(m_irq_queue[i].irq_vector), i); + save_item(NAME(m_irq_queue[i].irq_priority), i); } - save_item(NAME(m_pcfsel)); - save_item(NAME(m_maxpcfsel)); - save_item(NAME(m_pcflushes)); + */ + + save_item(NAME(m_irq_line_state)); save_item(NAME(m_m)); save_item(NAME(m_nmi_line_state)); @@ -2393,71 +469,24 @@ void sh2_device::device_start() save_item(NAME(m_icr)); save_item(NAME(m_frc_base)); save_item(NAME(m_frt_input)); - save_item(NAME(m_sh2_state->internal_irq_level)); save_item(NAME(m_internal_irq_vector)); save_item(NAME(m_dma_timer_active)); save_item(NAME(m_dma_irq)); save_item(NAME(m_wtcnt)); save_item(NAME(m_wtcsr)); - save_item(NAME(m_sh2_state->sleep_mode)); - - state_add( STATE_GENPC, "PC", m_sh2_state->pc).mask(AM).callimport(); - state_add( SH2_SR, "SR", m_sh2_state->sr).callimport().formatstr("%08X"); - state_add( SH2_PR, "PR", m_sh2_state->pr).formatstr("%08X"); - state_add( SH2_GBR, "GBR", m_sh2_state->gbr).formatstr("%08X"); - state_add( SH2_VBR, "VBR", m_sh2_state->vbr).formatstr("%08X"); - state_add( SH2_MACH, "MACH", m_sh2_state->mach).formatstr("%08X"); - state_add( SH2_MACL, "MACL", m_sh2_state->macl).formatstr("%08X"); - state_add( SH2_R0, "R0", m_sh2_state->r[ 0]).formatstr("%08X"); - state_add( SH2_R1, "R1", m_sh2_state->r[ 1]).formatstr("%08X"); - state_add( SH2_R2, "R2", m_sh2_state->r[ 2]).formatstr("%08X"); - state_add( SH2_R3, "R3", m_sh2_state->r[ 3]).formatstr("%08X"); - state_add( SH2_R4, "R4", m_sh2_state->r[ 4]).formatstr("%08X"); - state_add( SH2_R5, "R5", m_sh2_state->r[ 5]).formatstr("%08X"); - state_add( SH2_R6, "R6", m_sh2_state->r[ 6]).formatstr("%08X"); - state_add( SH2_R7, "R7", m_sh2_state->r[ 7]).formatstr("%08X"); - state_add( SH2_R8, "R8", m_sh2_state->r[ 8]).formatstr("%08X"); - state_add( SH2_R9, "R9", m_sh2_state->r[ 9]).formatstr("%08X"); - state_add( SH2_R10, "R10", m_sh2_state->r[10]).formatstr("%08X"); - state_add( SH2_R11, "R11", m_sh2_state->r[11]).formatstr("%08X"); - state_add( SH2_R12, "R12", m_sh2_state->r[12]).formatstr("%08X"); - state_add( SH2_R13, "R13", m_sh2_state->r[13]).formatstr("%08X"); - state_add( SH2_R14, "R14", m_sh2_state->r[14]).formatstr("%08X"); - state_add( SH2_R15, "R15", m_sh2_state->r[15]).formatstr("%08X"); - state_add( SH2_EA, "EA", m_sh2_state->ea).formatstr("%08X"); + state_add( STATE_GENPC, "PC", m_sh2_state->pc).mask(SH12_AM).callimport(); state_add( STATE_GENPCBASE, "CURPC", m_sh2_state->pc ).callimport().noshow(); - state_add( STATE_GENSP, "GENSP", m_sh2_state->r[15] ).noshow(); - state_add( STATE_GENFLAGS, "GENFLAGS", m_sh2_state->sr ).formatstr("%6s").noshow(); - - m_icountptr = &m_sh2_state->icount; // Clear state - m_sh2_state->pc = 0; - m_sh2_state->pr = 0; - m_sh2_state->sr = 0; - m_sh2_state->gbr = 0; - m_sh2_state->vbr = 0; - m_sh2_state->mach = 0; - m_sh2_state->macl = 0; - memset(m_sh2_state->r, 0, sizeof(m_sh2_state->r)); - m_sh2_state->ea = 0; - m_delay = 0; m_cpu_off = 0; - m_dvsr = 0; - m_dvdnth = 0; - m_dvdntl = 0; - m_dvcr = 0; - m_sh2_state->pending_irq = 0; + //m_dvsr = 0; + //m_dvdnth = 0; + //m_dvdntl = 0; + //m_dvcr = 0; m_test_irq = 0; - m_sh2_state->pending_nmi = 0; - m_sh2_state->irqline = 0; - m_sh2_state->evec = 0; - m_sh2_state->irqsr = 0; - m_sh2_state->target = 0; - memset(m_irq_queue, 0, sizeof(m_irq_queue)); - m_maxpcfsel = 0; - memset(m_pcflushes, 0, sizeof(m_pcflushes)); + + memset(m_irq_line_state, 0, sizeof(m_irq_line_state)); memset(m_m, 0, sizeof(m_m)); m_nmi_line_state = 0; @@ -2467,9 +496,8 @@ void sh2_device::device_start() m_icr = 0; m_frc_base = 0; m_frt_input = 0; - m_sh2_state->internal_irq_level = 0; m_internal_irq_vector = 0; - m_sh2_state->icount = 0; + for ( int i = 0; i < 2; i++ ) { m_dma_timer_active[i] = 0; @@ -2484,68 +512,8 @@ void sh2_device::device_start() } m_wtcnt = 0; m_wtcsr = 0; - m_sh2_state->sleep_mode = 0; - m_numcycles = 0; - m_sh2_state->arg0 = 0; - m_arg1 = 0; - m_irq = 0; - m_fastram_select = 0; - memset(m_fastram, 0, sizeof(m_fastram)); - - /* reset per-driver pcflushes */ - m_pcfsel = 0; - - /* initialize the UML generator */ - uint32_t flags = 0; - m_drcuml = std::make_unique<drcuml_state>(*this, m_cache, flags, 1, 32, 1); - - /* add symbols for our stuff */ - m_drcuml->symbol_add(&m_sh2_state->pc, sizeof(m_sh2_state->pc), "pc"); - m_drcuml->symbol_add(&m_sh2_state->icount, sizeof(m_sh2_state->icount), "icount"); - for (int regnum = 0; regnum < 16; regnum++) - { - char buf[10]; - sprintf(buf, "r%d", regnum); - m_drcuml->symbol_add(&m_sh2_state->r[regnum], sizeof(m_sh2_state->r[regnum]), buf); - } - m_drcuml->symbol_add(&m_sh2_state->pr, sizeof(m_sh2_state->pr), "pr"); - m_drcuml->symbol_add(&m_sh2_state->sr, sizeof(m_sh2_state->sr), "sr"); - m_drcuml->symbol_add(&m_sh2_state->gbr, sizeof(m_sh2_state->gbr), "gbr"); - m_drcuml->symbol_add(&m_sh2_state->vbr, sizeof(m_sh2_state->vbr), "vbr"); - m_drcuml->symbol_add(&m_sh2_state->macl, sizeof(m_sh2_state->macl), "macl"); - m_drcuml->symbol_add(&m_sh2_state->mach, sizeof(m_sh2_state->macl), "mach"); - - /* initialize the front-end helper */ - m_drcfe = std::make_unique<sh2_frontend>(this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, SINGLE_INSTRUCTION_MODE ? 1 : COMPILE_MAX_SEQUENCE); - /* compute the register parameters */ - for (int regnum = 0; regnum < 16; regnum++) - { - m_regmap[regnum] = uml::mem(&m_sh2_state->r[regnum]); - } - - /* if we have registers to spare, assign r0, r1, r2 to leftovers */ - /* WARNING: do not use synthetic registers that are mapped here! */ - if (!DISABLE_FAST_REGISTERS) - { - drcbe_info beinfo; - m_drcuml->get_backend_info(beinfo); - if (beinfo.direct_iregs > 4) - { - m_regmap[0] = uml::I4; - } - if (beinfo.direct_iregs > 5) - { - m_regmap[1] = uml::I5; - } - if (beinfo.direct_iregs > 6) - { - m_regmap[2] = uml::I6; - } - } - - /* mark the cache dirty so it is updated on next execute */ - m_cache_dirty = true; + drc_start(); } @@ -2555,11 +523,11 @@ void sh2_device::state_string_export(const device_state_entry &entry, std::strin { case STATE_GENFLAGS: str = string_format("%c%c%d%c%c", - m_sh2_state->sr & M ? 'M':'.', - m_sh2_state->sr & Q ? 'Q':'.', - (m_sh2_state->sr & I) >> 4, - m_sh2_state->sr & S ? 'S':'.', - m_sh2_state->sr & T ? 'T':'.'); + m_sh2_state->sr & SH_M ? 'M':'.', + m_sh2_state->sr & SH_Q ? 'Q':'.', + (m_sh2_state->sr & SH_I) >> 4, + m_sh2_state->sr & SH_S ? 'S':'.', + m_sh2_state->sr & SH_T ? 'T':'.'); break; } } @@ -2571,10 +539,10 @@ void sh2_device::state_import(const device_state_entry &entry) { case STATE_GENPC: case STATE_GENPCBASE: - m_delay = 0; + m_sh2_state->m_delay = 0; break; - case SH2_SR: + case SH_SR: CHECK_PENDING_IRQ("sh2_set_reg"); break; } @@ -2622,7 +590,7 @@ void sh2_device::execute_set_input(int irqline, int state) { m_test_irq = 1; } else { - if(m_delay) + if(m_sh2_state->m_delay) m_test_irq = 1; else CHECK_PENDING_IRQ("sh2_set_irq_line"); @@ -2672,14 +640,14 @@ void sh2_device::sh2_exception(const char *message, int irqline) if (m_isdrc) { m_sh2_state->evec = RL( m_sh2_state->vbr + vector * 4 ); - m_sh2_state->evec &= AM; + m_sh2_state->evec &= SH12_AM; m_sh2_state->irqsr = m_sh2_state->sr; /* set I flags in SR */ if (irqline > SH2_INT_15) - m_sh2_state->sr = m_sh2_state->sr | I; + m_sh2_state->sr = m_sh2_state->sr | SH_I; else - m_sh2_state->sr = (m_sh2_state->sr & ~I) | (irqline << 4); + m_sh2_state->sr = (m_sh2_state->sr & ~SH_I) | (irqline << 4); // printf("sh2_exception [%s] irqline %x evec %x save SR %x new SR %x\n", message, irqline, m_sh2_state->evec, m_sh2_state->irqsr, m_sh2_state->sr); } else { @@ -2690,9 +658,9 @@ void sh2_device::sh2_exception(const char *message, int irqline) /* set I flags in SR */ if (irqline > SH2_INT_15) - m_sh2_state->sr = m_sh2_state->sr | I; + m_sh2_state->sr = m_sh2_state->sr | SH_I; else - m_sh2_state->sr = (m_sh2_state->sr & ~I) | (irqline << 4); + m_sh2_state->sr = (m_sh2_state->sr & ~SH_I) | (irqline << 4); /* fetch PC */ m_sh2_state->pc = RL( m_sh2_state->vbr + vector * 4 ); @@ -2701,4 +669,324 @@ void sh2_device::sh2_exception(const char *message, int irqline) if(m_sh2_state->sleep_mode == 1) { m_sh2_state->sleep_mode = 2; } } -#include "sh2drc.cpp" +// license:BSD-3-Clause +// copyright-holders:R. Belmont +/*************************************************************************** + + sh2drc.c + Universal machine language-based SH-2 emulator. + +***************************************************************************/ + +#include "emu.h" +#include "debugger.h" +#include "sh2.h" +#include "sh2comn.h" + + +using namespace uml; + +const opcode_desc* sh2_device::get_desclist(offs_t pc) +{ + return m_drcfe->describe_code(pc); +} + + + +/*------------------------------------------------- + static_generate_entry_point - generate a + static entry point +-------------------------------------------------*/ + +void sh2_device::func_fastirq() +{ + sh2_exception("fastirq",m_sh2_state->irqline); +} +static void cfunc_fastirq(void *param) { ((sh2_device *)param)->func_fastirq(); }; + +void sh2_device::static_generate_entry_point() +{ + drcuml_state *drcuml = m_drcuml.get(); + code_label skip = 1; + drcuml_block *block; + + /* begin generating */ + block = drcuml->begin_block(200); + + /* forward references */ + alloc_handle(drcuml, &m_nocode, "nocode"); + alloc_handle(drcuml, &m_write32, "write32"); // necessary? + alloc_handle(drcuml, &m_entry, "entry"); + UML_HANDLE(block, *m_entry); // handle entry + + /* load fast integer registers */ + load_fast_iregs(block); + + /* check for interrupts */ + UML_MOV(block, mem(&m_sh2_state->irqline), 0xffffffff); // mov irqline, #-1 + UML_CMP(block, mem(&m_sh2_state->pending_nmi), 0); // cmp pending_nmi, #0 + UML_JMPc(block, COND_Z, skip+2); // jz skip+2 + + UML_MOV(block, mem(&m_sh2_state->pending_nmi), 0); // zap pending_nmi + UML_JMP(block, skip+1); // and then go take it (evec is already set) + + UML_LABEL(block, skip+2); // skip+2: + UML_MOV(block, mem(&m_sh2_state->evec), 0xffffffff); // mov evec, -1 + UML_MOV(block, I0, 0xffffffff); // mov r0, -1 (r0 = irq) + UML_AND(block, I1, I0, 0xffff); // and r1, 0xffff + + UML_LZCNT(block, I1, mem(&m_sh2_state->pending_irq)); // lzcnt r1, r1 + UML_CMP(block, I1, 32); // cmp r1, #32 + UML_JMPc(block, COND_Z, skip+4); // jz skip+4 + + UML_SUB(block, mem(&m_sh2_state->irqline), 31, I1); // sub irqline, #31, r1 + + UML_LABEL(block, skip+4); // skip+4: + UML_CMP(block, mem(&m_sh2_state->internal_irq_level), 0xffffffff); // cmp internal_irq_level, #-1 + UML_JMPc(block, COND_Z, skip+3); // jz skip+3 + UML_CMP(block, mem(&m_sh2_state->internal_irq_level), mem(&m_sh2_state->irqline)); // cmp internal_irq_level, irqline + UML_JMPc(block, COND_LE, skip+3); // jle skip+3 + + UML_MOV(block, mem(&m_sh2_state->irqline), mem(&m_sh2_state->internal_irq_level)); // mov r0, internal_irq_level + + UML_LABEL(block, skip+3); // skip+3: + UML_CMP(block, mem(&m_sh2_state->irqline), 0xffffffff); // cmp irqline, #-1 + UML_JMPc(block, COND_Z, skip+1); // jz skip+1 + UML_CALLC(block, cfunc_fastirq, this); // callc fastirq + + UML_LABEL(block, skip+1); // skip+1: + + UML_CMP(block, mem(&m_sh2_state->evec), 0xffffffff); // cmp evec, 0xffffffff + UML_JMPc(block, COND_Z, skip); // jz skip + + UML_SUB(block, R32(15), R32(15), 4); // sub R15, R15, #4 + UML_MOV(block, I0, R32(15)); // mov r0, R15 + UML_MOV(block, I1, mem(&m_sh2_state->irqsr)); // mov r1, irqsr + UML_CALLH(block, *m_write32); // call write32 + + UML_SUB(block, R32(15), R32(15), 4); // sub R15, R15, #4 + UML_MOV(block, I0, R32(15)); // mov r0, R15 + UML_MOV(block, I1, mem(&m_sh2_state->pc)); // mov r1, pc + UML_CALLH(block, *m_write32); // call write32 + + UML_MOV(block, mem(&m_sh2_state->pc), mem(&m_sh2_state->evec)); // mov pc, evec + + UML_LABEL(block, skip); // skip: + + /* generate a hash jump via the current mode and PC */ + UML_HASHJMP(block, 0, mem(&m_sh2_state->pc), *m_nocode); // hashjmp <mode>,<pc>,nocode + + block->end(); +} + + +/*------------------------------------------------- + generate_update_cycles - generate code to + subtract cycles from the icount and generate + an exception if out +-------------------------------------------------*/ + +void sh2_device::generate_update_cycles(drcuml_block *block, compiler_state *compiler, uml::parameter param, bool allow_exception) +{ + /* check full interrupts if pending */ + if (compiler->checkints) + { + code_label skip = compiler->labelnum++; + + compiler->checkints = false; + compiler->labelnum += 4; + + /* check for interrupts */ + UML_MOV(block, mem(&m_sh2_state->irqline), 0xffffffff); // mov irqline, #-1 + UML_CMP(block, mem(&m_sh2_state->pending_nmi), 0); // cmp pending_nmi, #0 + UML_JMPc(block, COND_Z, skip+2); // jz skip+2 + + UML_MOV(block, mem(&m_sh2_state->pending_nmi), 0); // zap pending_nmi + UML_JMP(block, skip+1); // and then go take it (evec is already set) + + UML_LABEL(block, skip+2); // skip+2: + UML_MOV(block, mem(&m_sh2_state->evec), 0xffffffff); // mov evec, -1 + UML_MOV(block, I0, 0xffffffff); // mov r0, -1 (r0 = irq) + UML_AND(block, I1, I0, 0xffff); // and r1, r0, 0xffff + + UML_LZCNT(block, I1, mem(&m_sh2_state->pending_irq)); // lzcnt r1, pending_irq + UML_CMP(block, I1, 32); // cmp r1, #32 + UML_JMPc(block, COND_Z, skip+4); // jz skip+4 + + UML_SUB(block, mem(&m_sh2_state->irqline), 31, I1); // sub irqline, #31, r1 + + UML_LABEL(block, skip+4); // skip+4: + UML_CMP(block, mem(&m_sh2_state->internal_irq_level), 0xffffffff); // cmp internal_irq_level, #-1 + UML_JMPc(block, COND_Z, skip+3); // jz skip+3 + UML_CMP(block, mem(&m_sh2_state->internal_irq_level), mem(&m_sh2_state->irqline)); // cmp internal_irq_level, irqline + UML_JMPc(block, COND_LE, skip+3); // jle skip+3 + + UML_MOV(block, mem(&m_sh2_state->irqline), mem(&m_sh2_state->internal_irq_level)); // mov r0, internal_irq_level + + UML_LABEL(block, skip+3); // skip+3: + UML_CMP(block, mem(&m_sh2_state->irqline), 0xffffffff); // cmp irqline, #-1 + UML_JMPc(block, COND_Z, skip+1); // jz skip+1 + UML_CALLC(block, cfunc_fastirq, this); // callc fastirq + + UML_LABEL(block, skip+1); // skip+1: + UML_CMP(block, mem(&m_sh2_state->evec), 0xffffffff); // cmp evec, 0xffffffff + UML_JMPc(block, COND_Z, skip); // jz skip + + UML_SUB(block, R32(15), R32(15), 4); // sub R15, R15, #4 + UML_MOV(block, I0, R32(15)); // mov r0, R15 + UML_MOV(block, I1, mem(&m_sh2_state->irqsr)); // mov r1, irqsr + UML_CALLH(block, *m_write32); // call write32 + + UML_SUB(block, R32(15), R32(15), 4); // sub R15, R15, #4 + UML_MOV(block, I0, R32(15)); // mov r0, R15 + UML_MOV(block, I1, param); // mov r1, nextpc + UML_CALLH(block, *m_write32); // call write32 + + UML_HASHJMP(block, 0, mem(&m_sh2_state->evec), *m_nocode); // hashjmp m_sh2_state->evec + + UML_LABEL(block, skip); // skip: + } + + /* account for cycles */ + if (compiler->cycles > 0) + { + UML_SUB(block, mem(&m_sh2_state->icount), mem(&m_sh2_state->icount), MAPVAR_CYCLES); // sub icount,icount,cycles + UML_MAPVAR(block, MAPVAR_CYCLES, 0); // mapvar cycles,0 + if (allow_exception) + UML_EXHc(block, COND_S, *m_out_of_cycles, param); + // exh out_of_cycles,nextpc + } + compiler->cycles = 0; +} + +/*------------------------------------------------------------------ + static_generate_memory_accessor +------------------------------------------------------------------*/ + +void sh2_device::static_generate_memory_accessor(int size, int iswrite, const char *name, code_handle **handleptr) +{ + /* on entry, address is in I0; data for writes is in I1 */ + /* on exit, read result is in I0 */ + /* routine trashes I0 */ + drcuml_state *drcuml = m_drcuml.get(); + drcuml_block *block; + int label = 1; + + /* begin generating */ + block = drcuml->begin_block(1024); + + /* add a global entry for this */ + alloc_handle(drcuml, handleptr, name); + UML_HANDLE(block, **handleptr); // handle *handleptr + + // with internal handlers this becomes easier. + // if addr < 0x40000000 AND it with AM and do the read/write, else just do the read/write + UML_TEST(block, I0, 0x80000000); // test r0, #0x80000000 + UML_JMPc(block, COND_NZ, label); // if high bit is set, don't mask + + UML_CMP(block, I0, 0x40000000); // cmp #0x40000000, r0 + UML_JMPc(block, COND_AE, label); // bae label + + UML_AND(block, I0, I0, SH12_AM); // and r0, r0, #AM (0xc7ffffff) + + UML_LABEL(block, label++); // label: + + for (auto & elem : m_fastram) + { + if (elem.base != nullptr && (!iswrite || !elem.readonly)) + { + void *fastbase = (uint8_t *)elem.base - elem.start; + uint32_t skip = label++; + if (elem.end != 0xffffffff) + { + UML_CMP(block, I0, elem.end); // cmp i0,end + UML_JMPc(block, COND_A, skip); // ja skip + } + if (elem.start != 0x00000000) + { + UML_CMP(block, I0, elem.start);// cmp i0,fastram_start + UML_JMPc(block, COND_B, skip); // jb skip + } + + if (!iswrite) + { + if (size == 1) + { + UML_XOR(block, I0, I0, BYTE4_XOR_BE(0)); + UML_LOAD(block, I0, fastbase, I0, SIZE_BYTE, SCALE_x1); // load i0,fastbase,i0,byte + } + else if (size == 2) + { + UML_XOR(block, I0, I0, WORD_XOR_BE(0)); + UML_LOAD(block, I0, fastbase, I0, SIZE_WORD, SCALE_x1); // load i0,fastbase,i0,word_x1 + } + else if (size == 4) + { + UML_LOAD(block, I0, fastbase, I0, SIZE_DWORD, SCALE_x1); // load i0,fastbase,i0,dword_x1 + } + UML_RET(block); // ret + } + else + { + if (size == 1) + { + UML_XOR(block, I0, I0, BYTE4_XOR_BE(0)); + UML_STORE(block, fastbase, I0, I1, SIZE_BYTE, SCALE_x1);// store fastbase,i0,i1,byte + } + else if (size == 2) + { + UML_XOR(block, I0, I0, WORD_XOR_BE(0)); + UML_STORE(block, fastbase, I0, I1, SIZE_WORD, SCALE_x1);// store fastbase,i0,i1,word_x1 + } + else if (size == 4) + { + UML_STORE(block, fastbase, I0, I1, SIZE_DWORD, SCALE_x1); // store fastbase,i0,i1,dword_x1 + } + UML_RET(block); // ret + } + + UML_LABEL(block, skip); // skip: + } + } + + if (iswrite) + { + switch (size) + { + case 1: + UML_WRITE(block, I0, I1, SIZE_BYTE, SPACE_PROGRAM); // write r0, r1, program_byte + break; + + case 2: + UML_WRITE(block, I0, I1, SIZE_WORD, SPACE_PROGRAM); // write r0, r1, program_word + break; + + case 4: + UML_WRITE(block, I0, I1, SIZE_DWORD, SPACE_PROGRAM); // write r0, r1, program_dword + break; + } + } + else + { + switch (size) + { + case 1: + UML_READ(block, I0, I0, SIZE_BYTE, SPACE_PROGRAM); // read r0, program_byte + break; + + case 2: + UML_READ(block, I0, I0, SIZE_WORD, SPACE_PROGRAM); // read r0, program_word + break; + + case 4: + UML_READ(block, I0, I0, SIZE_DWORD, SPACE_PROGRAM); // read r0, program_dword + break; + } + } + + UML_RET(block); // ret + + block->end(); +} + + diff --git a/src/devices/cpu/sh/sh2.h b/src/devices/cpu/sh/sh2.h index 50ecf680c88..7c15b82d5e4 100644 --- a/src/devices/cpu/sh/sh2.h +++ b/src/devices/cpu/sh/sh2.h @@ -17,9 +17,8 @@ #pragma once -#include "cpu/drcfe.h" -#include "cpu/drcuml.h" +#include "sh.h" #define SH2_INT_NONE -1 #define SH2_INT_VBLIN 0 @@ -40,21 +39,12 @@ #define SH2_INT_15 15 #define SH2_INT_ABUS 16 -enum -{ - SH2_PC = STATE_GENPC, SH2_SR=1, SH2_PR, SH2_GBR, SH2_VBR, SH2_MACH, SH2_MACL, - SH2_R0, SH2_R1, SH2_R2, SH2_R3, SH2_R4, SH2_R5, SH2_R6, SH2_R7, - SH2_R8, SH2_R9, SH2_R10, SH2_R11, SH2_R12, SH2_R13, SH2_R14, SH2_R15, SH2_EA -}; - - #define SH2_DMA_KLUDGE_CB(name) int name(uint32_t src, uint32_t dst, uint32_t data, int size) #define SH2_DMA_FIFO_DATA_AVAILABLE_CB(name) int name(uint32_t src, uint32_t dst, uint32_t data, int size) #define SH2_FTCSR_READ_CB(name) void name(uint32_t data) - #define MCFG_SH2_IS_SLAVE(_slave) \ sh2_device::set_is_slave(*device, _slave); @@ -68,22 +58,9 @@ enum sh2_device::set_ftcsr_read_callback(*device, sh2_device::ftcsr_read_delegate(&_class::_method, #_class "::" #_method, downcast<_class *>(owner))); -/*************************************************************************** - COMPILER-SPECIFIC OPTIONS -***************************************************************************/ - -#define SH2DRC_STRICT_VERIFY 0x0001 /* verify all instructions */ -#define SH2DRC_FLUSH_PC 0x0002 /* flush the PC value before each memory access */ -#define SH2DRC_STRICT_PCREL 0x0004 /* do actual loads on MOVLI/MOVWI instead of collapsing to immediates */ - -#define SH2DRC_COMPATIBLE_OPTIONS (SH2DRC_STRICT_VERIFY | SH2DRC_FLUSH_PC | SH2DRC_STRICT_PCREL) -#define SH2DRC_FASTEST_OPTIONS (0) - -#define SH2_MAX_FASTRAM 4 - class sh2_frontend; -class sh2_device : public cpu_device +class sh2_device : public sh_common_execution { friend class sh2_frontend; @@ -105,11 +82,8 @@ public: DECLARE_READ32_MEMBER(sh2_internal_a5); void sh2_set_frt_input(int state); - void sh2drc_set_options(uint32_t options); - void sh2drc_add_pcflush(offs_t address); - void sh2drc_add_fastram(offs_t start, offs_t end, uint8_t readonly, void *base); - void sh2_notify_dma_data_available(); + void func_fastirq(); protected: sh2_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int cpu_type,address_map_constructor internal_map, int addrlines); @@ -135,58 +109,18 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 2; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; - address_space *m_program, *m_decrypted_program; + virtual util::disasm_interface *create_disassembler() override; + + address_space *m_decrypted_program; private: address_space_config m_program_config, m_decrypted_program_config; - // Data that needs to be stored close to the generated DRC code - struct internal_sh2_state - { - uint32_t pc; - uint32_t pr; - uint32_t sr; - uint32_t gbr; - uint32_t vbr; - uint32_t mach; - uint32_t macl; - uint32_t r[16]; - uint32_t ea; - uint32_t pending_irq; - uint32_t pending_nmi; - int32_t irqline; - uint32_t evec; // exception vector for DRC - uint32_t irqsr; // IRQ-time old SR for DRC - uint32_t target; // target for jmp/jsr/etc so the delay slot can't kill it - int internal_irq_level; - int icount; - uint8_t sleep_mode; - uint32_t arg0; /* print_debug argument 1 */ - }; - - uint32_t m_delay; uint32_t m_cpu_off; - uint32_t m_dvsr, m_dvdnth, m_dvdntl, m_dvcr; uint32_t m_test_irq; - struct - { - int irq_vector; - int irq_priority; - } m_irq_queue[16]; - - bool m_isdrc; - - int m_pcfsel; // last pcflush entry set - int m_maxpcfsel; // highest valid pcflush entry - uint32_t m_pcflushes[16]; // pcflush entries int8_t m_irq_line_state[17]; -protected: - direct_read_data *m_direct; -private: + address_space *m_internal; uint32_t m_m[0x200/4]; int8_t m_nmi_line_state; @@ -213,273 +147,46 @@ private: uint16_t m_wtcnt; uint8_t m_wtcsr; - int m_is_slave, m_cpu_type; + int m_is_slave; dma_kludge_delegate m_dma_kludge_cb; dma_fifo_data_available_delegate m_dma_fifo_data_available_cb; ftcsr_read_delegate m_ftcsr_read_cb; - drc_cache m_cache; /* pointer to the DRC code cache */ - std::unique_ptr<drcuml_state> m_drcuml; /* DRC UML generator state */ std::unique_ptr<sh2_frontend> m_drcfe; /* pointer to the DRC front-end state */ - uint32_t m_drcoptions; /* configurable DRC options */ - - internal_sh2_state *m_sh2_state; - - /* internal stuff */ - uint8_t m_cache_dirty; /* true if we need to flush the cache */ - /* parameters for subroutines */ - uint64_t m_numcycles; /* return value from gettotalcycles */ - uint32_t m_arg1; /* print_debug argument 2 */ - uint32_t m_irq; /* irq we're taking */ - - /* register mappings */ - uml::parameter m_regmap[16]; /* parameter to register mappings for all 16 integer registers */ + uint32_t m_debugger_temp; - uml::code_handle * m_entry; /* entry point */ - uml::code_handle * m_read8; /* read byte */ - uml::code_handle * m_write8; /* write byte */ - uml::code_handle * m_read16; /* read half */ - uml::code_handle * m_write16; /* write half */ - uml::code_handle * m_read32; /* read word */ - uml::code_handle * m_write32; /* write word */ + inline uint8_t RB(offs_t A) override; + inline uint16_t RW(offs_t A) override; + inline uint32_t RL(offs_t A) override; + inline void WB(offs_t A, uint8_t V) override; + inline void WW(offs_t A, uint16_t V) override; + inline void WL(offs_t A, uint32_t V) override; - uml::code_handle * m_interrupt; /* interrupt */ - uml::code_handle * m_nocode; /* nocode */ - uml::code_handle * m_out_of_cycles; /* out of cycles exception handler */ + virtual void LDCMSR(const uint16_t opcode) override; + virtual void LDCSR(const uint16_t opcode) override; + virtual void TRAPA(uint32_t i) override; + virtual void RTE() override; + virtual void ILLEGAL() override; - /* fast RAM */ - uint32_t m_fastram_select; - struct - { - offs_t start; /* start of the RAM block */ - offs_t end; /* end of the RAM block */ - bool readonly; /* true if read-only */ - void * base; /* base in memory where the RAM lives */ - } m_fastram[SH2_MAX_FASTRAM]; + virtual void execute_one_f000(uint16_t opcode) override; - uint32_t m_debugger_temp; - - inline uint8_t RB(offs_t A); - inline uint16_t RW(offs_t A); - inline uint32_t RL(offs_t A); - inline void WB(offs_t A, uint8_t V); - inline void WW(offs_t A, uint16_t V); - inline void WL(offs_t A, uint32_t V); - inline void ADD(uint32_t m, uint32_t n); - inline void ADDI(uint32_t i, uint32_t n); - inline void ADDC(uint32_t m, uint32_t n); - inline void ADDV(uint32_t m, uint32_t n); - inline void AND(uint32_t m, uint32_t n); - inline void ANDI(uint32_t i); - inline void ANDM(uint32_t i); - inline void BF(uint32_t d); - inline void BFS(uint32_t d); - inline void BRA(uint32_t d); - inline void BRAF(uint32_t m); - inline void BSR(uint32_t d); - inline void BSRF(uint32_t m); - inline void BT(uint32_t d); - inline void BTS(uint32_t d); - inline void CLRMAC(); - inline void CLRT(); - inline void CMPEQ(uint32_t m, uint32_t n); - inline void CMPGE(uint32_t m, uint32_t n); - inline void CMPGT(uint32_t m, uint32_t n); - inline void CMPHI(uint32_t m, uint32_t n); - inline void CMPHS(uint32_t m, uint32_t n); - inline void CMPPL(uint32_t n); - inline void CMPPZ(uint32_t n); - inline void CMPSTR(uint32_t m, uint32_t n); - inline void CMPIM(uint32_t i); - inline void DIV0S(uint32_t m, uint32_t n); - inline void DIV0U(); - inline void DIV1(uint32_t m, uint32_t n); - inline void DMULS(uint32_t m, uint32_t n); - inline void DMULU(uint32_t m, uint32_t n); - inline void DT(uint32_t n); - inline void EXTSB(uint32_t m, uint32_t n); - inline void EXTSW(uint32_t m, uint32_t n); - inline void EXTUB(uint32_t m, uint32_t n); - inline void EXTUW(uint32_t m, uint32_t n); - inline void ILLEGAL(); - inline void JMP(uint32_t m); - inline void JSR(uint32_t m); - inline void LDCSR(uint32_t m); - inline void LDCGBR(uint32_t m); - inline void LDCVBR(uint32_t m); - inline void LDCMSR(uint32_t m); - inline void LDCMGBR(uint32_t m); - inline void LDCMVBR(uint32_t m); - inline void LDSMACH(uint32_t m); - inline void LDSMACL(uint32_t m); - inline void LDSPR(uint32_t m); - inline void LDSMMACH(uint32_t m); - inline void LDSMMACL(uint32_t m); - inline void LDSMPR(uint32_t m); - inline void MAC_L(uint32_t m, uint32_t n); - inline void MAC_W(uint32_t m, uint32_t n); - inline void MOV(uint32_t m, uint32_t n); - inline void MOVBS(uint32_t m, uint32_t n); - inline void MOVWS(uint32_t m, uint32_t n); - inline void MOVLS(uint32_t m, uint32_t n); - inline void MOVBL(uint32_t m, uint32_t n); - inline void MOVWL(uint32_t m, uint32_t n); - inline void MOVLL(uint32_t m, uint32_t n); - inline void MOVBM(uint32_t m, uint32_t n); - inline void MOVWM(uint32_t m, uint32_t n); - inline void MOVLM(uint32_t m, uint32_t n); - inline void MOVBP(uint32_t m, uint32_t n); - inline void MOVWP(uint32_t m, uint32_t n); - inline void MOVLP(uint32_t m, uint32_t n); - inline void MOVBS0(uint32_t m, uint32_t n); - inline void MOVWS0(uint32_t m, uint32_t n); - inline void MOVLS0(uint32_t m, uint32_t n); - inline void MOVBL0(uint32_t m, uint32_t n); - inline void MOVWL0(uint32_t m, uint32_t n); - inline void MOVLL0(uint32_t m, uint32_t n); - inline void MOVI(uint32_t i, uint32_t n); - inline void MOVWI(uint32_t d, uint32_t n); - inline void MOVLI(uint32_t d, uint32_t n); - inline void MOVBLG(uint32_t d); - inline void MOVWLG(uint32_t d); - inline void MOVLLG(uint32_t d); - inline void MOVBSG(uint32_t d); - inline void MOVWSG(uint32_t d); - inline void MOVLSG(uint32_t d); - inline void MOVBS4(uint32_t d, uint32_t n); - inline void MOVWS4(uint32_t d, uint32_t n); - inline void MOVLS4(uint32_t m, uint32_t d, uint32_t n); - inline void MOVBL4(uint32_t m, uint32_t d); - inline void MOVWL4(uint32_t m, uint32_t d); - inline void MOVLL4(uint32_t m, uint32_t d, uint32_t n); - inline void MOVA(uint32_t d); - inline void MOVT(uint32_t n); - inline void MULL(uint32_t m, uint32_t n); - inline void MULS(uint32_t m, uint32_t n); - inline void MULU(uint32_t m, uint32_t n); - inline void NEG(uint32_t m, uint32_t n); - inline void NEGC(uint32_t m, uint32_t n); - inline void NOP(void); - inline void NOT(uint32_t m, uint32_t n); - inline void OR(uint32_t m, uint32_t n); - inline void ORI(uint32_t i); - inline void ORM(uint32_t i); - inline void ROTCL(uint32_t n); - inline void ROTCR(uint32_t n); - inline void ROTL(uint32_t n); - inline void ROTR(uint32_t n); - inline void RTE(); - inline void RTS(); - inline void SETT(); - inline void SHAL(uint32_t n); - inline void SHAR(uint32_t n); - inline void SHLL(uint32_t n); - inline void SHLL2(uint32_t n); - inline void SHLL8(uint32_t n); - inline void SHLL16(uint32_t n); - inline void SHLR(uint32_t n); - inline void SHLR2(uint32_t n); - inline void SHLR8(uint32_t n); - inline void SHLR16(uint32_t n); - inline void SLEEP(); - inline void STCSR(uint32_t n); - inline void STCGBR(uint32_t n); - inline void STCVBR(uint32_t n); - inline void STCMSR(uint32_t n); - inline void STCMGBR(uint32_t n); - inline void STCMVBR(uint32_t n); - inline void STSMACH(uint32_t n); - inline void STSMACL(uint32_t n); - inline void STSPR(uint32_t n); - inline void STSMMACH(uint32_t n); - inline void STSMMACL(uint32_t n); - inline void STSMPR(uint32_t n); - inline void SUB(uint32_t m, uint32_t n); - inline void SUBC(uint32_t m, uint32_t n); - inline void SUBV(uint32_t m, uint32_t n); - inline void SWAPB(uint32_t m, uint32_t n); - inline void SWAPW(uint32_t m, uint32_t n); - inline void TAS(uint32_t n); - inline void TRAPA(uint32_t i); - inline void TST(uint32_t m, uint32_t n); - inline void TSTI(uint32_t i); - inline void TSTM(uint32_t i); - inline void XOR(uint32_t m, uint32_t n); - inline void XORI(uint32_t i); - inline void XORM(uint32_t i); - inline void XTRCT(uint32_t m, uint32_t n); - inline void op0000(uint16_t opcode); - inline void op0001(uint16_t opcode); - inline void op0010(uint16_t opcode); - inline void op0011(uint16_t opcode); - inline void op0100(uint16_t opcode); - inline void op0101(uint16_t opcode); - inline void op0110(uint16_t opcode); - inline void op0111(uint16_t opcode); - inline void op1000(uint16_t opcode); - inline void op1001(uint16_t opcode); - inline void op1010(uint16_t opcode); - inline void op1011(uint16_t opcode); - inline void op1100(uint16_t opcode); - inline void op1101(uint16_t opcode); - inline void op1110(uint16_t opcode); - inline void op1111(uint16_t opcode); TIMER_CALLBACK_MEMBER( sh2_timer_callback ); TIMER_CALLBACK_MEMBER( sh2_dma_current_active_callback ); void sh2_timer_resync(); void sh2_timer_activate(); void sh2_do_dma(int dma); - void sh2_exception(const char *message, int irqline); + virtual void sh2_exception(const char *message, int irqline) override; void sh2_dmac_check(int dma); void sh2_recalc_irq(); - /* internal compiler state */ - struct compiler_state - { - uint32_t cycles; /* accumulated cycles */ - uint8_t checkints; /* need to check interrupts before next instruction */ - uml::code_label labelnum; /* index for local labels */ - }; - - inline uint32_t epc(const opcode_desc *desc); - inline void alloc_handle(drcuml_state *drcuml, uml::code_handle **handleptr, const char *name); - inline void load_fast_iregs(drcuml_block *block); - inline void save_fast_iregs(drcuml_block *block); - - void code_flush_cache(); - void execute_run_drc(); - void code_compile_block(uint8_t mode, offs_t pc); - void static_generate_entry_point(); - void static_generate_nocode_handler(); - void static_generate_out_of_cycles(); - void static_generate_memory_accessor(int size, int iswrite, const char *name, uml::code_handle **handleptr); - const char *log_desc_flags_to_string(uint32_t flags); - void log_register_list(drcuml_state *drcuml, const char *string, const uint32_t *reglist, const uint32_t *regnostarlist); - void log_opcode_desc(drcuml_state *drcuml, const opcode_desc *desclist, int indent); - void log_add_disasm_comment(drcuml_block *block, uint32_t pc, uint32_t op); - void generate_update_cycles(drcuml_block *block, compiler_state *compiler, uml::parameter param, bool allow_exception); - void generate_checksum_block(drcuml_block *block, compiler_state *compiler, const opcode_desc *seqhead, const opcode_desc *seqlast); - void generate_sequence_instruction(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint32_t ovrpc); - void generate_delay_slot(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint32_t ovrpc); - bool generate_opcode(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint32_t ovrpc); - bool generate_group_0(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); - bool generate_group_2(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); - bool generate_group_3(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, uint32_t ovrpc); - bool generate_group_4(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); - bool generate_group_6(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); - bool generate_group_8(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); - bool generate_group_12(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + virtual void init_drc_frontend() override; + virtual const opcode_desc* get_desclist(offs_t pc) override; + + virtual void generate_update_cycles(drcuml_block *block, compiler_state *compiler, uml::parameter param, bool allow_exception) override; + virtual void static_generate_entry_point() override; + virtual void static_generate_memory_accessor(int size, int iswrite, const char *name, uml::code_handle **handleptr) override; -public: - void func_printf_probe(); - void func_unimplemented(); - void func_fastirq(); - void func_MAC_W(); - void func_MAC_L(); - void func_DIV1(); - void func_ADDV(); - void func_SUBV(); }; class sh2a_device : public sh2_device @@ -528,30 +235,19 @@ private: }; -class sh2_frontend : public drc_frontend +class sh2_frontend : public sh_frontend { public: - sh2_frontend(sh2_device *device, uint32_t window_start, uint32_t window_end, uint32_t max_sequence); + sh2_frontend(sh_common_execution *device, uint32_t window_start, uint32_t window_end, uint32_t max_sequence); protected: - virtual bool describe(opcode_desc &desc, const opcode_desc *prev) override; private: - bool describe_group_0(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode); - bool describe_group_2(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode); - bool describe_group_3(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode); - bool describe_group_4(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode); - bool describe_group_6(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode); - bool describe_group_8(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode); - bool describe_group_12(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode); - - sh2_device *m_sh2; + virtual bool describe_group_15(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) override; }; - DECLARE_DEVICE_TYPE(SH1, sh1_device) DECLARE_DEVICE_TYPE(SH2, sh2_device) DECLARE_DEVICE_TYPE(SH2A, sh2a_device) - #endif // MAME_CPU_SH2_SH2_H diff --git a/src/devices/cpu/sh/sh2comn.cpp b/src/devices/cpu/sh/sh2comn.cpp index b6ac0e1cc65..fca8070c936 100644 --- a/src/devices/cpu/sh/sh2comn.cpp +++ b/src/devices/cpu/sh/sh2comn.cpp @@ -181,11 +181,8 @@ void sh2_device::sh2_do_dma(int dma) } } - #ifdef USE_TIMER_FOR_DMA - //schedule next DMA callback + //schedule next DMA callback m_dma_current_active_timer[dma]->adjust(cycles_to_attotime(2), dma); - #endif - dmadata = m_program->read_byte(tempsrc); if (!m_dma_kludge_cb.isnull()) dmadata = m_dma_kludge_cb(tempsrc, tempdst, dmadata, m_active_dma_size[dma]); @@ -229,10 +226,8 @@ void sh2_device::sh2_do_dma(int dma) } } - #ifdef USE_TIMER_FOR_DMA - //schedule next DMA callback + //schedule next DMA callback m_dma_current_active_timer[dma]->adjust(cycles_to_attotime(2), dma); - #endif // check: should this really be using read_word_32 / write_word_32? dmadata = m_program->read_word(tempsrc); @@ -276,10 +271,8 @@ void sh2_device::sh2_do_dma(int dma) } } - #ifdef USE_TIMER_FOR_DMA - //schedule next DMA callback + //schedule next DMA callback m_dma_current_active_timer[dma]->adjust(cycles_to_attotime(2), dma); - #endif dmadata = m_program->read_dword(tempsrc); if (!m_dma_kludge_cb.isnull()) dmadata = m_dma_kludge_cb(tempsrc, tempdst, dmadata, m_active_dma_size[dma]); @@ -321,10 +314,8 @@ void sh2_device::sh2_do_dma(int dma) } } - #ifdef USE_TIMER_FOR_DMA - //schedule next DMA callback + //schedule next DMA callback m_dma_current_active_timer[dma]->adjust(cycles_to_attotime(2), dma); - #endif dmadata = m_program->read_dword(tempsrc); if (!m_dma_kludge_cb.isnull()) dmadata = m_dma_kludge_cb(tempsrc, tempdst, dmadata, m_active_dma_size[dma]); @@ -409,8 +400,8 @@ void sh2_device::sh2_dmac_check(int dma) m_dma_timer_active[dma] = 1; - m_active_dma_src[dma] &= AM; - m_active_dma_dst[dma] &= AM; + m_active_dma_src[dma] &= SH12_AM; + m_active_dma_dst[dma] &= SH12_AM; switch(m_active_dma_size[dma]) { @@ -431,10 +422,6 @@ void sh2_device::sh2_dmac_check(int dma) break; } - - - -#ifdef USE_TIMER_FOR_DMA // start DMA timer // fever soccer uses cycle-stealing mode, requiring the CPU to be halted @@ -445,8 +432,6 @@ void sh2_device::sh2_dmac_check(int dma) } m_dma_current_active_timer[dma]->adjust(cycles_to_attotime(2), dma); -#endif - } } else diff --git a/src/devices/cpu/sh/sh2comn.h b/src/devices/cpu/sh/sh2comn.h index 1c859e227d6..fb1e63eac19 100644 --- a/src/devices/cpu/sh/sh2comn.h +++ b/src/devices/cpu/sh/sh2comn.h @@ -13,16 +13,6 @@ #pragma once - - -// do we use a timer for the DMA, or have it in CPU_EXECUTE -#define USE_TIMER_FOR_DMA - -#include "cpu/drcuml.h" -#include "cpu/drcumlsh.h" - -#define SH2_CODE_XOR(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(2,0)) - enum { ICF = 0x00800000, @@ -31,31 +21,7 @@ enum OVF = 0x00020000 }; -#define T 0x00000001 -#define S 0x00000002 -#define I 0x000000f0 -#define Q 0x00000100 -#define M 0x00000200 - -#define AM 0xc7ffffff - -#define FLAGS (M|Q|I|S|T) - -#define Rn ((opcode>>8)&15) -#define Rm ((opcode>>4)&15) - -#define CPU_TYPE_SH1 (0) -#define CPU_TYPE_SH2 (1) - -#define REGFLAG_R(n) (1 << (n)) - -/* register flags 1 */ -#define REGFLAG_PR (1 << 0) -#define REGFLAG_MACL (1 << 1) -#define REGFLAG_MACH (1 << 2) -#define REGFLAG_GBR (1 << 3) -#define REGFLAG_VBR (1 << 4) -#define REGFLAG_SR (1 << 5) +#define SH12_AM 0xc7ffffff #define CHECK_PENDING_IRQ(message) \ do { \ diff --git a/src/devices/cpu/sh/sh2dasm.cpp b/src/devices/cpu/sh/sh2dasm.cpp deleted file mode 100644 index ef823ee28a5..00000000000 --- a/src/devices/cpu/sh/sh2dasm.cpp +++ /dev/null @@ -1,610 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Juergen Buchmueller -#include "emu.h" -#include "debugger.h" -#include "sh2.h" - -#define SIGNX8(x) (((int32_t)(x) << 24) >> 24) -#define SIGNX12(x) (((int32_t)(x) << 20) >> 20) - -#define Rn ((opcode >> 8) & 15) -#define Rm ((opcode >> 4) & 15) - -static const char *const regname[16] = { - "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", - "R8", "R9", "R10","R11","R12","R13","R14","SP" -}; - -static uint32_t op0000(std::ostream &stream, uint32_t pc, uint16_t opcode) -{ - uint32_t flags = 0; - switch(opcode & 0x3f) - { - case 0x02: - util::stream_format(stream, "STC SR,%s", regname[Rn]); - break; - case 0x03: - util::stream_format(stream, "BSRF %s", regname[Rn]); - break; - case 0x08: - stream << "CLRT"; - break; - case 0x09: - stream << "NOP"; - break; - case 0x0A: - util::stream_format(stream, "STS MACH,%s", regname[Rn]); - break; - case 0x0B: - stream << "RTS"; - flags = DASMFLAG_STEP_OUT; - break; - case 0x12: - util::stream_format(stream, "STS GBR,%s", regname[Rn]); - break; - case 0x18: - stream << "SETT"; - break; - case 0x19: - stream << "DIV0U"; - break; - case 0x1A: - util::stream_format(stream, "STS MACL,%s", regname[Rn]); - break; - case 0x1B: - stream << "SLEEP"; - break; - case 0x22: - util::stream_format(stream, "STC VBR,%s", regname[Rn]); - break; - case 0x23: - util::stream_format(stream, "BRAF %s", regname[Rn]); - break; - case 0x28: - stream << "CLRMAC"; - break; - case 0x29: - util::stream_format(stream, "MOVT %s", regname[Rn]); - break; - case 0x2A: - util::stream_format(stream, "STS PR,%s", regname[Rn]); - break; - case 0x2B: - stream << "RTE"; - flags = DASMFLAG_STEP_OUT; - break; - default: - switch(opcode & 15) - { - case 0: - util::stream_format(stream, "?????? $%04X", opcode); - break; - case 1: - util::stream_format(stream, "?????? $%04X", opcode); - break; - case 2: - util::stream_format(stream, "?????? $%04X", opcode); - break; - case 3: - util::stream_format(stream, "?????? $%04X", opcode); - break; - case 4: - util::stream_format(stream, "MOV.B %s,@(R0,%s)", regname[Rm], regname[Rn]); - break; - case 5: - util::stream_format(stream, "MOV.W %s,@(R0,%s)", regname[Rm], regname[Rn]); - break; - case 6: - util::stream_format(stream, "MOV.L %s,@(R0,%s)", regname[Rm], regname[Rn]); - break; - case 7: - util::stream_format(stream, "MUL.L %s,%s", regname[Rm], regname[Rn]); - break; - case 8: - util::stream_format(stream, "?????? $%04X", opcode); - break; - case 9: - util::stream_format(stream, "?????? $%04X", opcode); - break; - case 10: - util::stream_format(stream, "?????? $%04X", opcode); - break; - case 11: - util::stream_format(stream, "?????? $%04X", opcode); - break; - case 12: - util::stream_format(stream, "MOV.B @(R0,%s),%s", regname[Rm], regname[Rn]); - break; - case 13: - util::stream_format(stream, "MOV.W @(R0,%s),%s", regname[Rm], regname[Rn]); - break; - case 14: - util::stream_format(stream, "MOV.L @(R0,%s),%s", regname[Rm], regname[Rn]); - break; - case 15: - util::stream_format(stream, "MAC.L @%s+,@%s+", regname[Rn], regname[Rm]); - break; - } - } - return flags; -} - -static uint32_t op0001(std::ostream &stream, uint32_t pc, uint16_t opcode) -{ - util::stream_format(stream, "MOV.L %s,@($%02X,%s)", regname[Rm], (opcode & 15) * 4, regname[Rn]); - return 0; -} - -static uint32_t op0010(std::ostream &stream, uint32_t pc, uint16_t opcode) -{ - switch (opcode & 15) - { - case 0: - util::stream_format(stream, "MOV.B %s,@%s", regname[Rm], regname[Rn]); - break; - case 1: - util::stream_format(stream, "MOV.W %s,@%s", regname[Rm], regname[Rn]); - break; - case 2: - util::stream_format(stream, "MOV.L %s,@%s", regname[Rm], regname[Rn]); - break; - case 3: - util::stream_format(stream, "?????? $%04X", opcode); - break; - case 4: - util::stream_format(stream, "MOV.B %s,@-%s", regname[Rm], regname[Rn]); - break; - case 5: - util::stream_format(stream, "MOV.W %s,@-%s", regname[Rm], regname[Rn]); - break; - case 6: - util::stream_format(stream, "MOV.L %s,@-%s", regname[Rm], regname[Rn]); - break; - case 7: - util::stream_format(stream, "DIV0S %s,%s", regname[Rm], regname[Rn]); - break; - case 8: - util::stream_format(stream, "TST %s,%s", regname[Rm], regname[Rn]); - break; - case 9: - util::stream_format(stream, "AND %s,%s", regname[Rm], regname[Rn]); - break; - case 10: - util::stream_format(stream, "XOR %s,%s", regname[Rm], regname[Rn]); - break; - case 11: - util::stream_format(stream, "OR %s,%s", regname[Rm], regname[Rn]); - break; - case 12: - util::stream_format(stream, "CMP/STR %s,%s", regname[Rm], regname[Rn]); - break; - case 13: - util::stream_format(stream, "XTRCT %s,%s", regname[Rm], regname[Rn]); - break; - case 14: - util::stream_format(stream, "MULU.W %s,%s", regname[Rm], regname[Rn]); - break; - case 15: - util::stream_format(stream, "MULS.W %s,%s", regname[Rm], regname[Rn]); - break; - } - return 0; -} - -static uint32_t op0011(std::ostream &stream, uint32_t pc, uint16_t opcode) -{ - switch (opcode & 15) - { - case 0: - util::stream_format(stream, "CMP/EQ %s,%s", regname[Rm], regname[Rn]); - break; - case 1: - util::stream_format(stream, "?????? %s,%s", regname[Rm], regname[Rn]); - break; - case 2: - util::stream_format(stream, "CMP/HS %s,%s", regname[Rm], regname[Rn]); - break; - case 3: - util::stream_format(stream, "CMP/GE %s,%s", regname[Rm], regname[Rn]); - break; - case 4: - util::stream_format(stream, "DIV1 %s,%s", regname[Rm], regname[Rn]); - break; - case 5: - util::stream_format(stream, "DMULU.L %s,%s", regname[Rm], regname[Rn]); - break; - case 6: - util::stream_format(stream, "CMP/HI %s,%s", regname[Rm], regname[Rn]); - break; - case 7: - util::stream_format(stream, "CMP/GT %s,%s", regname[Rm], regname[Rn]); - break; - case 8: - util::stream_format(stream, "SUB %s,%s", regname[Rm], regname[Rn]); - break; - case 9: - util::stream_format(stream, "?????? %s,%s", regname[Rm], regname[Rn]); - break; - case 10: - util::stream_format(stream, "SUBC %s,%s", regname[Rm], regname[Rn]); - break; - case 11: - util::stream_format(stream, "SUBV %s,%s", regname[Rm], regname[Rn]); - break; - case 12: - util::stream_format(stream, "ADD %s,%s", regname[Rm], regname[Rn]); - break; - case 13: - util::stream_format(stream, "DMULS.L %s,%s", regname[Rm], regname[Rn]); - break; - case 14: - util::stream_format(stream, "ADDC %s,%s", regname[Rm], regname[Rn]); - break; - case 15: - util::stream_format(stream, "ADDV %s,%s", regname[Rm], regname[Rn]); - break; - } - return 0; -} - -static uint32_t op0100(std::ostream &stream, uint32_t pc, uint16_t opcode) -{ - uint32_t flags = 0; - switch(opcode & 0x3F) - { - case 0x00: - util::stream_format(stream, "SHLL %s", regname[Rn]); - break; - case 0x01: - util::stream_format(stream, "SHLR %s", regname[Rn]); - break; - case 0x02: - util::stream_format(stream, "STS.L MACH,@-%s", regname[Rn]); - break; - case 0x03: - util::stream_format(stream, "STC.L SR,@-%s", regname[Rn]); - break; - case 0x04: - util::stream_format(stream, "ROTL %s", regname[Rn]); - break; - case 0x05: - util::stream_format(stream, "ROTR %s", regname[Rn]); - break; - case 0x06: - util::stream_format(stream, "LDS.L @%s+,MACH", regname[Rn]); - break; - case 0x07: - util::stream_format(stream, "LDC.L @%s+,SR", regname[Rn]); - break; - case 0x08: - util::stream_format(stream, "SHLL2 %s", regname[Rn]); - break; - case 0x09: - util::stream_format(stream, "SHLR2 %s", regname[Rn]); - break; - case 0x0a: - util::stream_format(stream, "LDS %s,MACH", regname[Rn]); - break; - case 0x0b: - util::stream_format(stream, "JSR %s", regname[Rn]); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); - break; - case 0x0e: - util::stream_format(stream, "LDC %s,SR", regname[Rn]); - break; - case 0x10: - util::stream_format(stream, "DT %s", regname[Rn]); - break; - case 0x11: - util::stream_format(stream, "CMP/PZ %s", regname[Rn]); - break; - case 0x12: - util::stream_format(stream, "STS.L MACL,@-%s", regname[Rn]); - break; - case 0x13: - util::stream_format(stream, "STC.L GBR,@-%s", regname[Rn]); - break; - case 0x15: - util::stream_format(stream, "CMP/PL %s", regname[Rn]); - break; - case 0x16: - util::stream_format(stream, "LDS.L @%s+,MACL", regname[Rn]); - break; - case 0x17: - util::stream_format(stream, "LDC.L @%s+,GBR", regname[Rn]); - break; - case 0x18: - util::stream_format(stream, "SHLL8 %s", regname[Rn]); - break; - case 0x19: - util::stream_format(stream, "SHLR8 %s", regname[Rn]); - break; - case 0x1a: - util::stream_format(stream, "LDS %s,MACL", regname[Rn]); - break; - case 0x1b: - util::stream_format(stream, "TAS %s", regname[Rn]); - break; - case 0x1e: - util::stream_format(stream, "LDC %s,GBR", regname[Rn]); - break; - case 0x20: - util::stream_format(stream, "SHAL %s", regname[Rn]); - break; - case 0x21: - util::stream_format(stream, "SHAR %s", regname[Rn]); - break; - case 0x22: - util::stream_format(stream, "STS.L PR,@-%s", regname[Rn]); - break; - case 0x23: - util::stream_format(stream, "STC.L VBR,@-%s", regname[Rn]); - break; - case 0x24: - util::stream_format(stream, "ROTCL %s", regname[Rn]); - break; - case 0x25: - util::stream_format(stream, "ROTCR %s", regname[Rn]); - break; - case 0x26: - util::stream_format(stream, "LDS.L @%s+,PR", regname[Rn]); - break; - case 0x27: - util::stream_format(stream, "LDC.L @%s+,VBR", regname[Rn]); - break; - case 0x28: - util::stream_format(stream, "SHLL16 %s", regname[Rn]); - break; - case 0x29: - util::stream_format(stream, "SHLR16 %s", regname[Rn]); - break; - case 0x2a: - util::stream_format(stream, "LDS %s,PR", regname[Rn]); - break; - case 0x2b: - util::stream_format(stream, "JMP %s", regname[Rn]); - break; - case 0x2e: - util::stream_format(stream, "LDC %s,VBR", regname[Rn]); - break; - default: - if ((opcode & 15) == 15) - util::stream_format(stream, "MAC.W @%s+,@%s+", regname[Rm], regname[Rn]); - else - util::stream_format(stream, "?????? $%04X", opcode); - } - return flags; -} - -static uint32_t op0101(std::ostream &stream, uint32_t pc, uint16_t opcode) -{ - util::stream_format(stream, "MOV.L @($%02X,%s),%s", (opcode & 15) * 4, regname[Rm], regname[Rn]); - return 0; -} - -static uint32_t op0110(std::ostream &stream, uint32_t pc, uint16_t opcode) - -{ - switch(opcode & 0xF) - { - case 0x00: - util::stream_format(stream, "MOV.B @%s,%s", regname[Rm], regname[Rn]); - break; - case 0x01: - util::stream_format(stream, "MOV.W @%s,%s", regname[Rm], regname[Rn]); - break; - case 0x02: - util::stream_format(stream, "MOV.L @%s,%s", regname[Rm], regname[Rn]); - break; - case 0x03: - util::stream_format(stream, "MOV %s,%s", regname[Rm], regname[Rn]); - break; - case 0x04: - util::stream_format(stream, "MOV.B @%s+,%s", regname[Rm], regname[Rn]); - break; - case 0x05: - util::stream_format(stream, "MOV.W @%s+,%s", regname[Rm], regname[Rn]); - break; - case 0x06: - util::stream_format(stream, "MOV.L @%s+,%s", regname[Rm], regname[Rn]); - break; - case 0x07: - util::stream_format(stream, "NOT %s,%s", regname[Rm], regname[Rn]); - break; - case 0x08: - util::stream_format(stream, "SWAP.B %s,%s", regname[Rm], regname[Rn]); - break; - case 0x09: - util::stream_format(stream, "SWAP.W %s,%s", regname[Rm], regname[Rn]); - break; - case 0x0a: - util::stream_format(stream, "NEGC %s,%s", regname[Rm], regname[Rn]); - break; - case 0x0b: - util::stream_format(stream, "NEG %s,%s", regname[Rm], regname[Rn]); - break; - case 0x0c: - util::stream_format(stream, "EXTU.B %s,%s", regname[Rm], regname[Rn]); - break; - case 0x0d: - util::stream_format(stream, "EXTU.W %s,%s", regname[Rm], regname[Rn]); - break; - case 0x0e: - util::stream_format(stream, "EXTS.B %s,%s", regname[Rm], regname[Rn]); - break; - case 0x0f: - util::stream_format(stream, "EXTS.W %s,%s", regname[Rm], regname[Rn]); - break; - } - return 0; -} - -static uint32_t op0111(std::ostream &stream, uint32_t pc, uint16_t opcode) -{ - util::stream_format(stream, "ADD #$%02X,%s", opcode & 0xff, regname[Rn]); - return 0; -} - -static uint32_t op1000(std::ostream &stream, uint32_t pc, uint16_t opcode) -{ - switch((opcode >> 8) & 15) - { - case 0: - util::stream_format(stream, "MOV.B R0,@($%02X,%s)", (opcode & 15), regname[Rm]); - break; - case 1: - util::stream_format(stream, "MOV.W R0,@($%02X,%s)", (opcode & 15) * 2, regname[Rm]); - break; - case 4: - util::stream_format(stream, "MOV.B @($%02X,%s),R0", (opcode & 15), regname[Rm]); - break; - case 5: - util::stream_format(stream, "MOV.W @($%02X,%s),R0", (opcode & 15), regname[Rm]); - break; - case 8: - util::stream_format(stream, "CMP/EQ #$%02X,R0", (opcode & 0xff)); - break; - case 9: - util::stream_format(stream, "BT $%08X", pc + SIGNX8(opcode & 0xff) * 2 + 2); - break; - case 11: - util::stream_format(stream, "BF $%08X", pc + SIGNX8(opcode & 0xff) * 2 + 2); - break; - case 13: - util::stream_format(stream, "BTS $%08X", pc + SIGNX8(opcode & 0xff) * 2 + 2); - break; - case 15: - util::stream_format(stream, "BFS $%08X", pc + SIGNX8(opcode & 0xff) * 2 + 2); - break; - default : - util::stream_format(stream, "invalid $%04X", opcode); - } - return 0; -} - -static uint32_t op1001(std::ostream &stream, uint32_t pc, uint16_t opcode) -{ - util::stream_format(stream, "MOV.W @($%04X,PC),%s [%08X]", (opcode & 0xff) * 2, regname[Rn], pc+((opcode & 0xff) * 2)+2); - return 0; -} - -static uint32_t op1010(std::ostream &stream, uint32_t pc, uint16_t opcode) -{ - util::stream_format(stream, "BRA $%08X", SIGNX12(opcode & 0xfff) * 2 + pc + 2); - return 0; -} - -static uint32_t op1011(std::ostream &stream, uint32_t pc, uint16_t opcode) -{ - util::stream_format(stream, "BSR $%08X", SIGNX12(opcode & 0xfff) * 2 + pc + 2); - return DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); -} - -static uint32_t op1100(std::ostream &stream, uint32_t pc, uint16_t opcode) -{ - uint32_t flags = 0; - switch((opcode >> 8) & 15) - { - case 0: - util::stream_format(stream, "MOV.B R0,@($%02X,GBR)", opcode & 0xff); - break; - case 1: - util::stream_format(stream, "MOV.W R0,@($%04X,GBR)", (opcode & 0xff) * 2); - break; - case 2: - util::stream_format(stream, "MOV.L R0,@($%04X,GBR)", (opcode & 0xff) * 4); - break; - case 3: - util::stream_format(stream, "TRAPA #$%02X", opcode & 0xff); - flags = DASMFLAG_STEP_OVER; - break; - case 4: - util::stream_format(stream, "MOV.B @($%02X,GBR),R0", opcode & 0xff); - break; - case 5: - util::stream_format(stream, "MOV.W @($%04X,GBR),R0", (opcode & 0xff) * 2); - break; - case 6: - util::stream_format(stream, "MOV.L @($%04X,GBR),R0", (opcode & 0xff) * 4); - break; - case 7: - util::stream_format(stream, "MOVA @($%04X,PC),R0 [%08X]", (opcode & 0xff) * 4, ((pc + 2) & ~3) + (opcode & 0xff) * 4); - break; - case 8: - util::stream_format(stream, "TST #$%02X,R0", opcode & 0xff); - break; - case 9: - util::stream_format(stream, "AND #$%02X,R0", opcode & 0xff); - break; - case 10: - util::stream_format(stream, "XOR #$%02X,R0", opcode & 0xff); - break; - case 11: - util::stream_format(stream, "OR #$%02X,R0", opcode & 0xff); - break; - case 12: - util::stream_format(stream, "TST.B #$%02X,@(R0,GBR)", opcode & 0xff); - break; - case 13: - util::stream_format(stream, "AND.B #$%02X,@(R0,GBR)", opcode & 0xff); - break; - case 14: - util::stream_format(stream, "XOR.B #$%02X,@(R0,GBR)", opcode & 0xff); - break; - case 15: - util::stream_format(stream, "OR.B #$%02X,@(R0,GBR)", opcode & 0xff); - break; - } - return flags; -} - -static uint32_t op1101(std::ostream &stream, uint32_t pc, uint16_t opcode) -{ - util::stream_format(stream, "MOV.L @($%02X,PC),%s [%08X]", (opcode * 4) & 0xff, regname[Rn], ((pc + 2) & ~3) + (opcode & 0xff) * 4); - return 0; -} - -static uint32_t op1110(std::ostream &stream, uint32_t pc, uint16_t opcode) -{ - util::stream_format(stream, "MOV #$%02X,%s", (opcode & 0xff), regname[Rn]); - return 0; -} - -static uint32_t op1111(std::ostream &stream, uint32_t pc, uint16_t opcode) -{ - util::stream_format(stream, "unknown $%04X", opcode); - return 0; -} - -unsigned DasmSH2(std::ostream &stream, unsigned pc, uint16_t opcode) -{ - uint32_t flags; - - pc += 2; - - switch ((opcode >> 12) & 15) - { - case 0: flags = op0000(stream, pc, opcode); break; - case 1: flags = op0001(stream, pc, opcode); break; - case 2: flags = op0010(stream, pc, opcode); break; - case 3: flags = op0011(stream, pc, opcode); break; - case 4: flags = op0100(stream, pc, opcode); break; - case 5: flags = op0101(stream, pc, opcode); break; - case 6: flags = op0110(stream, pc, opcode); break; - case 7: flags = op0111(stream, pc, opcode); break; - case 8: flags = op1000(stream, pc, opcode); break; - case 9: flags = op1001(stream, pc, opcode); break; - case 10: flags = op1010(stream, pc, opcode); break; - case 11: flags = op1011(stream, pc, opcode); break; - case 12: flags = op1100(stream, pc, opcode); break; - case 13: flags = op1101(stream, pc, opcode); break; - case 14: flags = op1110(stream, pc, opcode); break; - default: flags = op1111(stream, pc, opcode); break; - } - return 2 | flags | DASMFLAG_SUPPORTED; -} - -CPU_DISASSEMBLE(sh2) -{ - return DasmSH2(stream, pc, (oprom[0] << 8) | oprom[1]); -} diff --git a/src/devices/cpu/sh/sh2drc.cpp b/src/devices/cpu/sh/sh2drc.cpp index 1003463b97a..e69de29bb2d 100644 --- a/src/devices/cpu/sh/sh2drc.cpp +++ b/src/devices/cpu/sh/sh2drc.cpp @@ -1,2982 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:R. Belmont -/*************************************************************************** - - sh2drc.c - Universal machine language-based SH-2 emulator. - -***************************************************************************/ - -#include "emu.h" -#include "debugger.h" -#include "sh2.h" -#include "sh2comn.h" - -extern unsigned DasmSH2(std::ostream &stream, unsigned pc, uint16_t opcode); - -using namespace uml; - -/*************************************************************************** - DEBUGGING -***************************************************************************/ - -#define SET_EA (0) // makes slower but "shows work" in the EA fake register like the interpreter - -#define ADDSUBV_DIRECT (0) - -#if SET_EA -#define SETEA(x) UML_MOV(block, mem(&m_sh2_state->ea), ireg(x)) -#else -#define SETEA(x) -#endif - -/*************************************************************************** - CONSTANTS -***************************************************************************/ - -/* map variables */ -#define MAPVAR_PC M0 -#define MAPVAR_CYCLES M1 - -/* exit codes */ -#define EXECUTE_OUT_OF_CYCLES 0 -#define EXECUTE_MISSING_CODE 1 -#define EXECUTE_UNMAPPED_CODE 2 -#define EXECUTE_RESET_CACHE 3 - -#define PROBE_ADDRESS ~0 - - -/*************************************************************************** - MACROS -***************************************************************************/ - -#define R32(reg) m_regmap[reg] - -/*************************************************************************** - INLINE FUNCTIONS -***************************************************************************/ - -/*------------------------------------------------- - epc - compute the exception PC from a - descriptor --------------------------------------------------*/ - -uint32_t sh2_device::epc(const opcode_desc *desc) -{ - return (desc->flags & OPFLAG_IN_DELAY_SLOT) ? (desc->pc - 1) : desc->pc; -} - -/*------------------------------------------------- - alloc_handle - allocate a handle if not - already allocated --------------------------------------------------*/ - -void sh2_device::alloc_handle(drcuml_state *drcuml, code_handle **handleptr, const char *name) -{ - if (*handleptr == nullptr) - *handleptr = drcuml->handle_alloc(name); -} - -/*------------------------------------------------- - load_fast_iregs - load any fast integer - registers --------------------------------------------------*/ - -void sh2_device::load_fast_iregs(drcuml_block *block) -{ - int regnum; - - for (regnum = 0; regnum < ARRAY_LENGTH(m_regmap); regnum++) - { - if (m_regmap[regnum].is_int_register()) - { - UML_MOV(block, uml::parameter::make_ireg(m_regmap[regnum].ireg()), mem(&m_sh2_state->r[regnum])); - } - } -} - - -/*------------------------------------------------- - save_fast_iregs - save any fast integer - registers --------------------------------------------------*/ - -void sh2_device::save_fast_iregs(drcuml_block *block) -{ - int regnum; - - for (regnum = 0; regnum < ARRAY_LENGTH(m_regmap); regnum++) - { - if (m_regmap[regnum].is_int_register()) - { - UML_MOV(block, mem(&m_sh2_state->r[regnum]), uml::parameter::make_ireg(m_regmap[regnum].ireg())); - } - } -} - -/*------------------------------------------------- - cfunc_printf_probe - print the current CPU - state and return --------------------------------------------------*/ - -static void cfunc_printf_probe(void *param) -{ - ((sh2_device *)param)->func_printf_probe(); -} - -void sh2_device::func_printf_probe() -{ - uint32_t pc = m_sh2_state->pc; - - printf(" PC=%08X r0=%08X r1=%08X r2=%08X\n", - pc, - (uint32_t)m_sh2_state->r[0], - (uint32_t)m_sh2_state->r[1], - (uint32_t)m_sh2_state->r[2]); - printf(" r3=%08X r4=%08X r5=%08X r6=%08X\n", - (uint32_t)m_sh2_state->r[3], - (uint32_t)m_sh2_state->r[4], - (uint32_t)m_sh2_state->r[5], - (uint32_t)m_sh2_state->r[6]); - printf(" r7=%08X r8=%08X r9=%08X r10=%08X\n", - (uint32_t)m_sh2_state->r[7], - (uint32_t)m_sh2_state->r[8], - (uint32_t)m_sh2_state->r[9], - (uint32_t)m_sh2_state->r[10]); - printf(" r11=%08X r12=%08X r13=%08X r14=%08X\n", - (uint32_t)m_sh2_state->r[11], - (uint32_t)m_sh2_state->r[12], - (uint32_t)m_sh2_state->r[13], - (uint32_t)m_sh2_state->r[14]); - printf(" r15=%08X macl=%08X mach=%08X gbr=%08X\n", - (uint32_t)m_sh2_state->r[15], - (uint32_t)m_sh2_state->macl, - (uint32_t)m_sh2_state->mach, - (uint32_t)m_sh2_state->gbr); - printf(" evec %x irqsr %x pc=%08x\n", - (uint32_t)m_sh2_state->evec, - (uint32_t)m_sh2_state->irqsr, (uint32_t)m_sh2_state->pc); -} - -/*------------------------------------------------- - cfunc_unimplemented - handler for - unimplemented opcdes --------------------------------------------------*/ - -static void cfunc_unimplemented(void *param) -{ - ((sh2_device *)param)->func_unimplemented(); -} - -void sh2_device::func_unimplemented() -{ - // set up an invalid opcode exception - m_sh2_state->evec = RL( m_sh2_state->vbr + 4 * 4 ); - m_sh2_state->evec &= AM; - m_sh2_state->irqsr = m_sh2_state->sr; - // claim it's an NMI, because it pretty much is - m_sh2_state->pending_nmi = 1; -} - -/*------------------------------------------------- - cfunc_fastirq - checks for pending IRQs --------------------------------------------------*/ -static void cfunc_fastirq(void *param) -{ - ((sh2_device *)param)->func_fastirq(); -} - -void sh2_device::func_fastirq() -{ - sh2_exception("fastirq",m_sh2_state->irqline); -} - -/*------------------------------------------------- - cfunc_MAC_W - implementation of MAC_W Rm,Rn --------------------------------------------------*/ -static void cfunc_MAC_W(void *param) -{ - ((sh2_device *)param)->func_MAC_W(); -} - -void sh2_device::func_MAC_W() -{ - int32_t tempm, tempn, dest, src, ans; - uint32_t templ; - uint16_t opcode; - int n, m; - - // recover the opcode - opcode = m_sh2_state->arg0; - - // extract the operands - n = Rn; - m = Rm; - - tempn = (int32_t) RW( m_sh2_state->r[n] ); - m_sh2_state->r[n] += 2; - tempm = (int32_t) RW( m_sh2_state->r[m] ); - m_sh2_state->r[m] += 2; - templ = m_sh2_state->macl; - tempm = ((int32_t) (short) tempn * (int32_t) (short) tempm); - if ((int32_t) m_sh2_state->macl >= 0) - dest = 0; - else - dest = 1; - if ((int32_t) tempm >= 0) - { - src = 0; - tempn = 0; - } - else - { - src = 1; - tempn = 0xffffffff; - } - src += dest; - m_sh2_state->macl += tempm; - if ((int32_t) m_sh2_state->macl >= 0) - ans = 0; - else - ans = 1; - ans += dest; - if (m_sh2_state->sr & S) - { - if (ans == 1) - { - if ((m_cpu_type == CPU_TYPE_SH1) && ((src == 0) || (src == 2))) - { - m_sh2_state->mach |= 0x00000001; - } - - if (src == 0) - m_sh2_state->macl = 0x7fffffff; - if (src == 2) - m_sh2_state->macl = 0x80000000; - } - } - else - { - m_sh2_state->mach += tempn; - if (templ > m_sh2_state->macl) - m_sh2_state->mach += 1; - - // SH-1 has limited precision - if (m_cpu_type == CPU_TYPE_SH1) - { - if ((m_sh2_state->mach & 0x200) == 0) - { - m_sh2_state->mach &= 0x3ff; - } - else - { - m_sh2_state->mach |= 0xfffffc00; - } - } - - - } -} - -/*------------------------------------------------- - cfunc_MAC_L - implementation of MAC_L Rm,Rn --------------------------------------------------*/ -static void cfunc_MAC_L(void *param) -{ - ((sh2_device *)param)->func_MAC_L(); -} - -void sh2_device::func_MAC_L() -{ - uint32_t RnL, RnH, RmL, RmH, Res0, Res1, Res2; - uint32_t temp0, temp1, temp2, temp3; - int32_t tempm, tempn, fnLmL; - uint16_t opcode; - int n, m; - - // recover the opcode - opcode = m_sh2_state->arg0; - - // extract the operands - n = Rn; - m = Rm; - - tempn = (int32_t) RL( m_sh2_state->r[n] ); - m_sh2_state->r[n] += 4; - tempm = (int32_t) RL( m_sh2_state->r[m] ); - m_sh2_state->r[m] += 4; - if ((int32_t) (tempn ^ tempm) < 0) - fnLmL = -1; - else - fnLmL = 0; - if (tempn < 0) - tempn = 0 - tempn; - if (tempm < 0) - tempm = 0 - tempm; - temp1 = (uint32_t) tempn; - temp2 = (uint32_t) tempm; - RnL = temp1 & 0x0000ffff; - RnH = (temp1 >> 16) & 0x0000ffff; - RmL = temp2 & 0x0000ffff; - RmH = (temp2 >> 16) & 0x0000ffff; - temp0 = RmL * RnL; - temp1 = RmH * RnL; - temp2 = RmL * RnH; - temp3 = RmH * RnH; - Res2 = 0; - Res1 = temp1 + temp2; - if (Res1 < temp1) - Res2 += 0x00010000; - temp1 = (Res1 << 16) & 0xffff0000; - Res0 = temp0 + temp1; - if (Res0 < temp0) - Res2++; - Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3; - if (fnLmL < 0) - { - Res2 = ~Res2; - if (Res0 == 0) - Res2++; - else - Res0 = (~Res0) + 1; - } - if (m_sh2_state->sr & S) - { - Res0 = m_sh2_state->macl + Res0; - if (m_sh2_state->macl > Res0) - Res2++; - Res2 += (m_sh2_state->mach & 0x0000ffff); - if (((int32_t) Res2 < 0) && (Res2 < 0xffff8000)) - { - Res2 = 0x00008000; - Res0 = 0x00000000; - } - else if (((int32_t) Res2 > 0) && (Res2 > 0x00007fff)) - { - Res2 = 0x00007fff; - Res0 = 0xffffffff; - } - m_sh2_state->mach = Res2; - m_sh2_state->macl = Res0; - } - else - { - Res0 = m_sh2_state->macl + Res0; - if (m_sh2_state->macl > Res0) - Res2++; - Res2 += m_sh2_state->mach; - m_sh2_state->mach = Res2; - m_sh2_state->macl = Res0; - } -} - -/*------------------------------------------------- - cfunc_DIV1 - implementation of DIV1 Rm,Rn --------------------------------------------------*/ -static void cfunc_DIV1(void *param) -{ - ((sh2_device *)param)->func_DIV1(); -} - -void sh2_device::func_DIV1() -{ - uint32_t tmp0; - uint32_t old_q; - uint16_t opcode; - int n, m; - - // recover the opcode - opcode = m_sh2_state->arg0; - - // extract the operands - n = Rn; - m = Rm; - - old_q = m_sh2_state->sr & Q; - if (0x80000000 & m_sh2_state->r[n]) - m_sh2_state->sr |= Q; - else - m_sh2_state->sr &= ~Q; - - m_sh2_state->r[n] = (m_sh2_state->r[n] << 1) | (m_sh2_state->sr & T); - - if (!old_q) - { - if (!(m_sh2_state->sr & M)) - { - tmp0 = m_sh2_state->r[n]; - m_sh2_state->r[n] -= m_sh2_state->r[m]; - if(!(m_sh2_state->sr & Q)) - if(m_sh2_state->r[n] > tmp0) - m_sh2_state->sr |= Q; - else - m_sh2_state->sr &= ~Q; - else - if(m_sh2_state->r[n] > tmp0) - m_sh2_state->sr &= ~Q; - else - m_sh2_state->sr |= Q; - } - else - { - tmp0 = m_sh2_state->r[n]; - m_sh2_state->r[n] += m_sh2_state->r[m]; - if(!(m_sh2_state->sr & Q)) - { - if(m_sh2_state->r[n] < tmp0) - m_sh2_state->sr &= ~Q; - else - m_sh2_state->sr |= Q; - } - else - { - if(m_sh2_state->r[n] < tmp0) - m_sh2_state->sr |= Q; - else - m_sh2_state->sr &= ~Q; - } - } - } - else - { - if (!(m_sh2_state->sr & M)) - { - tmp0 = m_sh2_state->r[n]; - m_sh2_state->r[n] += m_sh2_state->r[m]; - if(!(m_sh2_state->sr & Q)) - if(m_sh2_state->r[n] < tmp0) - m_sh2_state->sr |= Q; - else - m_sh2_state->sr &= ~Q; - else - if(m_sh2_state->r[n] < tmp0) - m_sh2_state->sr &= ~Q; - else - m_sh2_state->sr |= Q; - } - else - { - tmp0 = m_sh2_state->r[n]; - m_sh2_state->r[n] -= m_sh2_state->r[m]; - if(!(m_sh2_state->sr & Q)) - if(m_sh2_state->r[n] > tmp0) - m_sh2_state->sr &= ~Q; - else - m_sh2_state->sr |= Q; - else - if(m_sh2_state->r[n] > tmp0) - m_sh2_state->sr |= Q; - else - m_sh2_state->sr &= ~Q; - } - } - - tmp0 = (m_sh2_state->sr & (Q | M)); - if((!tmp0) || (tmp0 == 0x300)) /* if Q == M set T else clear T */ - m_sh2_state->sr |= T; - else - m_sh2_state->sr &= ~T; -} - -#if (!ADDSUBV_DIRECT) -/*------------------------------------------------- - cfunc_ADDV - implementation of ADDV Rm,Rn --------------------------------------------------*/ -static void cfunc_ADDV(void *param) -{ - ((sh2_device *)param)->func_ADDV(); -} - -void sh2_device::func_ADDV() -{ - int32_t dest, src, ans; - uint16_t opcode; - int n, m; - - // recover the opcode - opcode = m_sh2_state->arg0; - - // extract the operands - n = Rn; - m = Rm; - - if ((int32_t) m_sh2_state->r[n] >= 0) - dest = 0; - else - dest = 1; - if ((int32_t) m_sh2_state->r[m] >= 0) - src = 0; - else - src = 1; - src += dest; - m_sh2_state->r[n] += m_sh2_state->r[m]; - if ((int32_t) m_sh2_state->r[n] >= 0) - ans = 0; - else - ans = 1; - ans += dest; - if (src == 0 || src == 2) - { - if (ans == 1) - m_sh2_state->sr |= T; - else - m_sh2_state->sr &= ~T; - } - else - m_sh2_state->sr &= ~T; -} - -/*------------------------------------------------- - cfunc_SUBV - implementation of SUBV Rm,Rn --------------------------------------------------*/ -static void cfunc_SUBV(void *param) -{ - ((sh2_device *)param)->func_SUBV(); -} - -void sh2_device::func_SUBV() -{ - int32_t dest, src, ans; - uint16_t opcode; - int n, m; - - // recover the opcode - opcode = m_sh2_state->arg0; - - // extract the operands - n = Rn; - m = Rm; - - if ((int32_t) m_sh2_state->r[n] >= 0) - dest = 0; - else - dest = 1; - if ((int32_t) m_sh2_state->r[m] >= 0) - src = 0; - else - src = 1; - src += dest; - m_sh2_state->r[n] -= m_sh2_state->r[m]; - if ((int32_t) m_sh2_state->r[n] >= 0) - ans = 0; - else - ans = 1; - ans += dest; - if (src == 1) - { - if (ans == 1) - m_sh2_state->sr |= T; - else - m_sh2_state->sr &= ~T; - } - else - m_sh2_state->sr &= ~T; -} -#else -void sh2_device::func_ADDV() {} -void sh2_device::func_SUBV() {} -#endif - -/*------------------------------------------------- - code_flush_cache - flush the cache and - regenerate static code --------------------------------------------------*/ - -void sh2_device::code_flush_cache() -{ - drcuml_state *drcuml = m_drcuml.get(); - - /* empty the transient cache contents */ - drcuml->reset(); - - try - { - /* generate the entry point and out-of-cycles handlers */ - static_generate_nocode_handler(); - static_generate_out_of_cycles(); - static_generate_entry_point(); - - /* add subroutines for memory accesses */ - static_generate_memory_accessor(1, false, "read8", &m_read8); - static_generate_memory_accessor(1, true, "write8", &m_write8); - static_generate_memory_accessor(2, false, "read16", &m_read16); - static_generate_memory_accessor(2, true, "write16", &m_write16); - static_generate_memory_accessor(4, false, "read32", &m_read32); - static_generate_memory_accessor(4, true, "write32", &m_write32); - } - catch (drcuml_block::abort_compilation &) - { - fatalerror("Unable to generate SH2 static code\n"); - } - - m_cache_dirty = false; -} - -/* Execute cycles - returns number of cycles actually run */ -void sh2_device::execute_run_drc() -{ - drcuml_state *drcuml = m_drcuml.get(); - int execute_result; - - // run any active DMAs now -#ifndef USE_TIMER_FOR_DMA - for ( int i = 0; i < m_sh2_state->icount ; i++) - { - for( int dma=0;dma<1;dma++) - { - if (m_dma_timer_active[dma]) - sh2_do_dma(dma); - } - } -#endif - - /* reset the cache if dirty */ - if (m_cache_dirty) - code_flush_cache(); - - /* execute */ - do - { - /* run as much as we can */ - execute_result = drcuml->execute(*m_entry); - - /* if we need to recompile, do it */ - if (execute_result == EXECUTE_MISSING_CODE) - { - code_compile_block(0, m_sh2_state->pc); - } - else if (execute_result == EXECUTE_UNMAPPED_CODE) - { - fatalerror("Attempted to execute unmapped code at PC=%08X\n", m_sh2_state->pc); - } - else if (execute_result == EXECUTE_RESET_CACHE) - { - code_flush_cache(); - } - } while (execute_result != EXECUTE_OUT_OF_CYCLES); -} - -/*------------------------------------------------- - code_compile_block - compile a block of the - given mode at the specified pc --------------------------------------------------*/ - -void sh2_device::code_compile_block(uint8_t mode, offs_t pc) -{ - drcuml_state *drcuml = m_drcuml.get(); - compiler_state compiler = { 0 }; - const opcode_desc *seqhead, *seqlast; - const opcode_desc *desclist; - bool override = false; - drcuml_block *block; - - g_profiler.start(PROFILER_DRC_COMPILE); - - /* get a description of this sequence */ - desclist = m_drcfe->describe_code(pc); - if (drcuml->logging() || drcuml->logging_native()) - log_opcode_desc(drcuml, desclist, 0); - - bool succeeded = false; - while (!succeeded) - { - try - { - /* start the block */ - block = drcuml->begin_block(4096); - - /* loop until we get through all instruction sequences */ - for (seqhead = desclist; seqhead != nullptr; seqhead = seqlast->next()) - { - const opcode_desc *curdesc; - uint32_t nextpc; - - /* add a code log entry */ - if (drcuml->logging()) - block->append_comment("-------------------------"); // comment - - /* determine the last instruction in this sequence */ - for (seqlast = seqhead; seqlast != nullptr; seqlast = seqlast->next()) - if (seqlast->flags & OPFLAG_END_SEQUENCE) - break; - assert(seqlast != nullptr); - - /* if we don't have a hash for this mode/pc, or if we are overriding all, add one */ - if (override || !drcuml->hash_exists(mode, seqhead->pc)) - UML_HASH(block, mode, seqhead->pc); // hash mode,pc - - /* if we already have a hash, and this is the first sequence, assume that we */ - /* are recompiling due to being out of sync and allow future overrides */ - else if (seqhead == desclist) - { - override = true; - UML_HASH(block, mode, seqhead->pc); // hash mode,pc - } - - /* otherwise, redispatch to that fixed PC and skip the rest of the processing */ - else - { - UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc | 0x80000000 - UML_HASHJMP(block, 0, seqhead->pc, *m_nocode); - // hashjmp <mode>,seqhead->pc,nocode - continue; - } - - /* validate this code block if we're not pointing into ROM */ - if (m_program->get_write_ptr(seqhead->physpc) != nullptr) - generate_checksum_block(block, &compiler, seqhead, seqlast); - - /* label this instruction, if it may be jumped to locally */ - if (seqhead->flags & OPFLAG_IS_BRANCH_TARGET) - { - UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc | 0x80000000 - } - - /* iterate over instructions in the sequence and compile them */ - for (curdesc = seqhead; curdesc != seqlast->next(); curdesc = curdesc->next()) - { - generate_sequence_instruction(block, &compiler, curdesc, 0xffffffff); - } - - /* if we need to return to the start, do it */ - if (seqlast->flags & OPFLAG_RETURN_TO_START) - { - nextpc = pc; - } - /* otherwise we just go to the next instruction */ - else - { - nextpc = seqlast->pc + (seqlast->skipslots + 1) * 2; - } - - /* count off cycles and go there */ - generate_update_cycles(block, &compiler, nextpc, true); // <subtract cycles> - - /* SH2 has no modes */ - if (seqlast->next() == nullptr || seqlast->next()->pc != nextpc) - { - UML_HASHJMP(block, 0, nextpc, *m_nocode); - } - // hashjmp <mode>,nextpc,nocode - } - - /* end the sequence */ - block->end(); - g_profiler.stop(); - succeeded = true; - } - catch (drcuml_block::abort_compilation &) - { - code_flush_cache(); - } - } -} - -/*------------------------------------------------- - static_generate_entry_point - generate a - static entry point --------------------------------------------------*/ - -void sh2_device::static_generate_entry_point() -{ - drcuml_state *drcuml = m_drcuml.get(); - code_label skip = 1; - drcuml_block *block; - - /* begin generating */ - block = drcuml->begin_block(200); - - /* forward references */ - alloc_handle(drcuml, &m_nocode, "nocode"); - alloc_handle(drcuml, &m_write32, "write32"); // necessary? - alloc_handle(drcuml, &m_entry, "entry"); - UML_HANDLE(block, *m_entry); // handle entry - - /* load fast integer registers */ - load_fast_iregs(block); - - /* check for interrupts */ - UML_MOV(block, mem(&m_sh2_state->irqline), 0xffffffff); // mov irqline, #-1 - UML_CMP(block, mem(&m_sh2_state->pending_nmi), 0); // cmp pending_nmi, #0 - UML_JMPc(block, COND_Z, skip+2); // jz skip+2 - - UML_MOV(block, mem(&m_sh2_state->pending_nmi), 0); // zap pending_nmi - UML_JMP(block, skip+1); // and then go take it (evec is already set) - - UML_LABEL(block, skip+2); // skip+2: - UML_MOV(block, mem(&m_sh2_state->evec), 0xffffffff); // mov evec, -1 - UML_MOV(block, I0, 0xffffffff); // mov r0, -1 (r0 = irq) - UML_AND(block, I1, I0, 0xffff); // and r1, 0xffff - - UML_LZCNT(block, I1, mem(&m_sh2_state->pending_irq)); // lzcnt r1, r1 - UML_CMP(block, I1, 32); // cmp r1, #32 - UML_JMPc(block, COND_Z, skip+4); // jz skip+4 - - UML_SUB(block, mem(&m_sh2_state->irqline), 31, I1); // sub irqline, #31, r1 - - UML_LABEL(block, skip+4); // skip+4: - UML_CMP(block, mem(&m_sh2_state->internal_irq_level), 0xffffffff); // cmp internal_irq_level, #-1 - UML_JMPc(block, COND_Z, skip+3); // jz skip+3 - UML_CMP(block, mem(&m_sh2_state->internal_irq_level), mem(&m_sh2_state->irqline)); // cmp internal_irq_level, irqline - UML_JMPc(block, COND_LE, skip+3); // jle skip+3 - - UML_MOV(block, mem(&m_sh2_state->irqline), mem(&m_sh2_state->internal_irq_level)); // mov r0, internal_irq_level - - UML_LABEL(block, skip+3); // skip+3: - UML_CMP(block, mem(&m_sh2_state->irqline), 0xffffffff); // cmp irqline, #-1 - UML_JMPc(block, COND_Z, skip+1); // jz skip+1 - UML_CALLC(block, cfunc_fastirq, this); // callc fastirq - - UML_LABEL(block, skip+1); // skip+1: - - UML_CMP(block, mem(&m_sh2_state->evec), 0xffffffff); // cmp evec, 0xffffffff - UML_JMPc(block, COND_Z, skip); // jz skip - - UML_SUB(block, R32(15), R32(15), 4); // sub R15, R15, #4 - UML_MOV(block, I0, R32(15)); // mov r0, R15 - UML_MOV(block, I1, mem(&m_sh2_state->irqsr)); // mov r1, irqsr - UML_CALLH(block, *m_write32); // call write32 - - UML_SUB(block, R32(15), R32(15), 4); // sub R15, R15, #4 - UML_MOV(block, I0, R32(15)); // mov r0, R15 - UML_MOV(block, I1, mem(&m_sh2_state->pc)); // mov r1, pc - UML_CALLH(block, *m_write32); // call write32 - - UML_MOV(block, mem(&m_sh2_state->pc), mem(&m_sh2_state->evec)); // mov pc, evec - - UML_LABEL(block, skip); // skip: - - /* generate a hash jump via the current mode and PC */ - UML_HASHJMP(block, 0, mem(&m_sh2_state->pc), *m_nocode); // hashjmp <mode>,<pc>,nocode - - block->end(); -} - -/*------------------------------------------------- - static_generate_nocode_handler - generate an - exception handler for "out of code" --------------------------------------------------*/ - -void sh2_device::static_generate_nocode_handler() -{ - drcuml_state *drcuml = m_drcuml.get(); - drcuml_block *block; - - /* begin generating */ - block = drcuml->begin_block(10); - - /* generate a hash jump via the current mode and PC */ - alloc_handle(drcuml, &m_nocode, "nocode"); - UML_HANDLE(block, *m_nocode); // handle nocode - UML_GETEXP(block, I0); // getexp i0 - UML_MOV(block, mem(&m_sh2_state->pc), I0); // mov [pc],i0 - save_fast_iregs(block); - UML_EXIT(block, EXECUTE_MISSING_CODE); // exit EXECUTE_MISSING_CODE - - block->end(); -} - - -/*------------------------------------------------- - static_generate_out_of_cycles - generate an - out of cycles exception handler --------------------------------------------------*/ - -void sh2_device::static_generate_out_of_cycles() -{ - drcuml_state *drcuml = m_drcuml.get(); - drcuml_block *block; - - /* begin generating */ - block = drcuml->begin_block(10); - - /* generate a hash jump via the current mode and PC */ - alloc_handle(drcuml, &m_out_of_cycles, "out_of_cycles"); - UML_HANDLE(block, *m_out_of_cycles); // handle out_of_cycles - UML_GETEXP(block, I0); // getexp i0 - UML_MOV(block, mem(&m_sh2_state->pc), I0); // mov <pc>,i0 - save_fast_iregs(block); - UML_EXIT(block, EXECUTE_OUT_OF_CYCLES); // exit EXECUTE_OUT_OF_CYCLES - - block->end(); -} - -/*------------------------------------------------------------------ - static_generate_memory_accessor -------------------------------------------------------------------*/ - -void sh2_device::static_generate_memory_accessor(int size, int iswrite, const char *name, code_handle **handleptr) -{ - /* on entry, address is in I0; data for writes is in I1 */ - /* on exit, read result is in I0 */ - /* routine trashes I0 */ - drcuml_state *drcuml = m_drcuml.get(); - drcuml_block *block; - int label = 1; - - /* begin generating */ - block = drcuml->begin_block(1024); - - /* add a global entry for this */ - alloc_handle(drcuml, handleptr, name); - UML_HANDLE(block, **handleptr); // handle *handleptr - - // with internal handlers this becomes easier. - // if addr < 0x40000000 AND it with AM and do the read/write, else just do the read/write - UML_TEST(block, I0, 0x80000000); // test r0, #0x80000000 - UML_JMPc(block, COND_NZ, label); // if high bit is set, don't mask - - UML_CMP(block, I0, 0x40000000); // cmp #0x40000000, r0 - UML_JMPc(block, COND_AE, label); // bae label - - UML_AND(block, I0, I0, AM); // and r0, r0, #AM (0xc7ffffff) - - UML_LABEL(block, label++); // label: - - for (auto & elem : m_fastram) - { - if (elem.base != nullptr && (!iswrite || !elem.readonly)) - { - void *fastbase = (uint8_t *)elem.base - elem.start; - uint32_t skip = label++; - if (elem.end != 0xffffffff) - { - UML_CMP(block, I0, elem.end); // cmp i0,end - UML_JMPc(block, COND_A, skip); // ja skip - } - if (elem.start != 0x00000000) - { - UML_CMP(block, I0, elem.start);// cmp i0,fastram_start - UML_JMPc(block, COND_B, skip); // jb skip - } - - if (!iswrite) - { - if (size == 1) - { - UML_XOR(block, I0, I0, BYTE4_XOR_BE(0)); - UML_LOAD(block, I0, fastbase, I0, SIZE_BYTE, SCALE_x1); // load i0,fastbase,i0,byte - } - else if (size == 2) - { - UML_XOR(block, I0, I0, WORD_XOR_BE(0)); - UML_LOAD(block, I0, fastbase, I0, SIZE_WORD, SCALE_x1); // load i0,fastbase,i0,word_x1 - } - else if (size == 4) - { - UML_LOAD(block, I0, fastbase, I0, SIZE_DWORD, SCALE_x1); // load i0,fastbase,i0,dword_x1 - } - UML_RET(block); // ret - } - else - { - if (size == 1) - { - UML_XOR(block, I0, I0, BYTE4_XOR_BE(0)); - UML_STORE(block, fastbase, I0, I1, SIZE_BYTE, SCALE_x1);// store fastbase,i0,i1,byte - } - else if (size == 2) - { - UML_XOR(block, I0, I0, WORD_XOR_BE(0)); - UML_STORE(block, fastbase, I0, I1, SIZE_WORD, SCALE_x1);// store fastbase,i0,i1,word_x1 - } - else if (size == 4) - { - UML_STORE(block, fastbase, I0, I1, SIZE_DWORD, SCALE_x1); // store fastbase,i0,i1,dword_x1 - } - UML_RET(block); // ret - } - - UML_LABEL(block, skip); // skip: - } - } - - if (iswrite) - { - switch (size) - { - case 1: - UML_WRITE(block, I0, I1, SIZE_BYTE, SPACE_PROGRAM); // write r0, r1, program_byte - break; - - case 2: - UML_WRITE(block, I0, I1, SIZE_WORD, SPACE_PROGRAM); // write r0, r1, program_word - break; - - case 4: - UML_WRITE(block, I0, I1, SIZE_DWORD, SPACE_PROGRAM); // write r0, r1, program_dword - break; - } - } - else - { - switch (size) - { - case 1: - UML_READ(block, I0, I0, SIZE_BYTE, SPACE_PROGRAM); // read r0, program_byte - break; - - case 2: - UML_READ(block, I0, I0, SIZE_WORD, SPACE_PROGRAM); // read r0, program_word - break; - - case 4: - UML_READ(block, I0, I0, SIZE_DWORD, SPACE_PROGRAM); // read r0, program_dword - break; - } - } - - UML_RET(block); // ret - - block->end(); -} - -/*------------------------------------------------- - log_desc_flags_to_string - generate a string - representing the instruction description - flags --------------------------------------------------*/ - -const char *sh2_device::log_desc_flags_to_string(uint32_t flags) -{ - static char tempbuf[30]; - char *dest = tempbuf; - - /* branches */ - if (flags & OPFLAG_IS_UNCONDITIONAL_BRANCH) - *dest++ = 'U'; - else if (flags & OPFLAG_IS_CONDITIONAL_BRANCH) - *dest++ = 'C'; - else - *dest++ = '.'; - - /* intrablock branches */ - *dest++ = (flags & OPFLAG_INTRABLOCK_BRANCH) ? 'i' : '.'; - - /* branch targets */ - *dest++ = (flags & OPFLAG_IS_BRANCH_TARGET) ? 'B' : '.'; - - /* delay slots */ - *dest++ = (flags & OPFLAG_IN_DELAY_SLOT) ? 'D' : '.'; - - /* exceptions */ - if (flags & OPFLAG_WILL_CAUSE_EXCEPTION) - *dest++ = 'E'; - else if (flags & OPFLAG_CAN_CAUSE_EXCEPTION) - *dest++ = 'e'; - else - *dest++ = '.'; - - /* read/write */ - if (flags & OPFLAG_READS_MEMORY) - *dest++ = 'R'; - else if (flags & OPFLAG_WRITES_MEMORY) - *dest++ = 'W'; - else - *dest++ = '.'; - - /* TLB validation */ - *dest++ = (flags & OPFLAG_VALIDATE_TLB) ? 'V' : '.'; - - /* TLB modification */ - *dest++ = (flags & OPFLAG_MODIFIES_TRANSLATION) ? 'T' : '.'; - - /* redispatch */ - *dest++ = (flags & OPFLAG_REDISPATCH) ? 'R' : '.'; - return tempbuf; -} - - -/*------------------------------------------------- - log_register_list - log a list of GPR registers --------------------------------------------------*/ - -void sh2_device::log_register_list(drcuml_state *drcuml, const char *string, const uint32_t *reglist, const uint32_t *regnostarlist) -{ - int count = 0; - int regnum; - - /* skip if nothing */ - if (reglist[0] == 0 && reglist[1] == 0 && reglist[2] == 0) - return; - - drcuml->log_printf("[%s:", string); - - for (regnum = 0; regnum < 16; regnum++) - { - if (reglist[0] & REGFLAG_R(regnum)) - { - drcuml->log_printf("%sr%d", (count++ == 0) ? "" : ",", regnum); - if (regnostarlist != nullptr && !(regnostarlist[0] & REGFLAG_R(regnum))) - drcuml->log_printf("*"); - } - } - - if (reglist[1] & REGFLAG_PR) - { - drcuml->log_printf("%spr", (count++ == 0) ? "" : ","); - if (regnostarlist != nullptr && !(regnostarlist[1] & REGFLAG_PR)) - drcuml->log_printf("*"); - } - - if (reglist[1] & REGFLAG_SR) - { - drcuml->log_printf("%ssr", (count++ == 0) ? "" : ","); - if (regnostarlist != nullptr && !(regnostarlist[1] & REGFLAG_SR)) - drcuml->log_printf("*"); - } - - if (reglist[1] & REGFLAG_MACL) - { - drcuml->log_printf("%smacl", (count++ == 0) ? "" : ","); - if (regnostarlist != nullptr && !(regnostarlist[1] & REGFLAG_MACL)) - drcuml->log_printf("*"); - } - - if (reglist[1] & REGFLAG_MACH) - { - drcuml->log_printf("%smach", (count++ == 0) ? "" : ","); - if (regnostarlist != nullptr && !(regnostarlist[1] & REGFLAG_MACH)) - drcuml->log_printf("*"); - } - - if (reglist[1] & REGFLAG_GBR) - { - drcuml->log_printf("%sgbr", (count++ == 0) ? "" : ","); - if (regnostarlist != nullptr && !(regnostarlist[1] & REGFLAG_GBR)) - drcuml->log_printf("*"); - } - - if (reglist[1] & REGFLAG_VBR) - { - drcuml->log_printf("%svbr", (count++ == 0) ? "" : ","); - if (regnostarlist != nullptr && !(regnostarlist[1] & REGFLAG_VBR)) - drcuml->log_printf("*"); - } - - drcuml->log_printf("] "); -} - -/*------------------------------------------------- - log_opcode_desc - log a list of descriptions --------------------------------------------------*/ - -void sh2_device::log_opcode_desc(drcuml_state *drcuml, const opcode_desc *desclist, int indent) -{ - /* open the file, creating it if necessary */ - if (indent == 0) - drcuml->log_printf("\nDescriptor list @ %08X\n", desclist->pc); - - /* output each descriptor */ - for ( ; desclist != nullptr; desclist = desclist->next()) - { - std::ostringstream stream; - - /* disassemle the current instruction and output it to the log */ - if (drcuml->logging() || drcuml->logging_native()) - { - if (desclist->flags & OPFLAG_VIRTUAL_NOOP) - stream << "<virtual nop>"; - else - DasmSH2(stream, desclist->pc, desclist->opptr.w[0]); - } - else - stream << "???"; - drcuml->log_printf("%08X [%08X] t:%08X f:%s: %-30s", desclist->pc, desclist->physpc, desclist->targetpc, log_desc_flags_to_string(desclist->flags), stream.str().c_str()); - - /* output register states */ - log_register_list(drcuml, "use", desclist->regin, nullptr); - log_register_list(drcuml, "mod", desclist->regout, desclist->regreq); - drcuml->log_printf("\n"); - - /* if we have a delay slot, output it recursively */ - if (desclist->delay.first() != nullptr) - log_opcode_desc(drcuml, desclist->delay.first(), indent + 1); - - /* at the end of a sequence add a dividing line */ - if (desclist->flags & OPFLAG_END_SEQUENCE) - drcuml->log_printf("-----\n"); - } -} - -/*------------------------------------------------- - log_add_disasm_comment - add a comment - including disassembly of an SH2 instruction --------------------------------------------------*/ - -void sh2_device::log_add_disasm_comment(drcuml_block *block, uint32_t pc, uint32_t op) -{ - if (m_drcuml->logging()) - { - std::ostringstream stream; - DasmSH2(stream, pc, op); - block->append_comment("%08X: %s", pc, stream.str().c_str()); - } -} - -/*------------------------------------------------- - generate_update_cycles - generate code to - subtract cycles from the icount and generate - an exception if out --------------------------------------------------*/ -void sh2_device::generate_update_cycles(drcuml_block *block, compiler_state *compiler, uml::parameter param, bool allow_exception) -{ - /* check full interrupts if pending */ - if (compiler->checkints) - { - code_label skip = compiler->labelnum++; - - compiler->checkints = false; - compiler->labelnum += 4; - - /* check for interrupts */ - UML_MOV(block, mem(&m_sh2_state->irqline), 0xffffffff); // mov irqline, #-1 - UML_CMP(block, mem(&m_sh2_state->pending_nmi), 0); // cmp pending_nmi, #0 - UML_JMPc(block, COND_Z, skip+2); // jz skip+2 - - UML_MOV(block, mem(&m_sh2_state->pending_nmi), 0); // zap pending_nmi - UML_JMP(block, skip+1); // and then go take it (evec is already set) - - UML_LABEL(block, skip+2); // skip+2: - UML_MOV(block, mem(&m_sh2_state->evec), 0xffffffff); // mov evec, -1 - UML_MOV(block, I0, 0xffffffff); // mov r0, -1 (r0 = irq) - UML_AND(block, I1, I0, 0xffff); // and r1, r0, 0xffff - - UML_LZCNT(block, I1, mem(&m_sh2_state->pending_irq)); // lzcnt r1, pending_irq - UML_CMP(block, I1, 32); // cmp r1, #32 - UML_JMPc(block, COND_Z, skip+4); // jz skip+4 - - UML_SUB(block, mem(&m_sh2_state->irqline), 31, I1); // sub irqline, #31, r1 - - UML_LABEL(block, skip+4); // skip+4: - UML_CMP(block, mem(&m_sh2_state->internal_irq_level), 0xffffffff); // cmp internal_irq_level, #-1 - UML_JMPc(block, COND_Z, skip+3); // jz skip+3 - UML_CMP(block, mem(&m_sh2_state->internal_irq_level), mem(&m_sh2_state->irqline)); // cmp internal_irq_level, irqline - UML_JMPc(block, COND_LE, skip+3); // jle skip+3 - - UML_MOV(block, mem(&m_sh2_state->irqline), mem(&m_sh2_state->internal_irq_level)); // mov r0, internal_irq_level - - UML_LABEL(block, skip+3); // skip+3: - UML_CMP(block, mem(&m_sh2_state->irqline), 0xffffffff); // cmp irqline, #-1 - UML_JMPc(block, COND_Z, skip+1); // jz skip+1 - UML_CALLC(block, cfunc_fastirq, this); // callc fastirq - - UML_LABEL(block, skip+1); // skip+1: - UML_CMP(block, mem(&m_sh2_state->evec), 0xffffffff); // cmp evec, 0xffffffff - UML_JMPc(block, COND_Z, skip); // jz skip - - UML_SUB(block, R32(15), R32(15), 4); // sub R15, R15, #4 - UML_MOV(block, I0, R32(15)); // mov r0, R15 - UML_MOV(block, I1, mem(&m_sh2_state->irqsr)); // mov r1, irqsr - UML_CALLH(block, *m_write32); // call write32 - - UML_SUB(block, R32(15), R32(15), 4); // sub R15, R15, #4 - UML_MOV(block, I0, R32(15)); // mov r0, R15 - UML_MOV(block, I1, param); // mov r1, nextpc - UML_CALLH(block, *m_write32); // call write32 - - UML_HASHJMP(block, 0, mem(&m_sh2_state->evec), *m_nocode); // hashjmp m_sh2_state->evec - - UML_LABEL(block, skip); // skip: - } - - /* account for cycles */ - if (compiler->cycles > 0) - { - UML_SUB(block, mem(&m_sh2_state->icount), mem(&m_sh2_state->icount), MAPVAR_CYCLES); // sub icount,icount,cycles - UML_MAPVAR(block, MAPVAR_CYCLES, 0); // mapvar cycles,0 - if (allow_exception) - UML_EXHc(block, COND_S, *m_out_of_cycles, param); - // exh out_of_cycles,nextpc - } - compiler->cycles = 0; -} - -/*------------------------------------------------- - generate_checksum_block - generate code to - validate a sequence of opcodes --------------------------------------------------*/ - -void sh2_device::generate_checksum_block(drcuml_block *block, compiler_state *compiler, const opcode_desc *seqhead, const opcode_desc *seqlast) -{ - const opcode_desc *curdesc; - if (m_drcuml->logging()) - block->append_comment("[Validation for %08X]", seqhead->pc); // comment - - /* loose verify or single instruction: just compare and fail */ - if (!(m_drcoptions & SH2DRC_STRICT_VERIFY) || seqhead->next() == nullptr) - { - if (!(seqhead->flags & OPFLAG_VIRTUAL_NOOP)) - { - void *base = m_direct->read_ptr(seqhead->physpc, SH2_CODE_XOR(0)); - UML_LOAD(block, I0, base, 0, SIZE_WORD, SCALE_x2); // load i0,base,word - UML_CMP(block, I0, seqhead->opptr.w[0]); // cmp i0,*opptr - UML_EXHc(block, COND_NE, *m_nocode, epc(seqhead)); // exne nocode,seqhead->pc - } - } - - /* full verification; sum up everything */ - else - { -#if 0 - for (curdesc = seqhead->next(); curdesc != seqlast->next(); curdesc = curdesc->next()) - if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP)) - { - base = m_direct->read_ptr(curdesc->physpc, SH2_CODE_XOR(0)); - UML_LOAD(block, I0, curdesc->opptr.w, 0, SIZE_WORD, SCALE_x2); // load i0,*opptr,0,word - UML_CMP(block, I0, curdesc->opptr.w[0]); // cmp i0,*opptr - UML_EXHc(block, COND_NE, *m_nocode, epc(seqhead)); // exne nocode,seqhead->pc - } -#else - uint32_t sum = 0; - void *base = m_direct->read_ptr(seqhead->physpc, SH2_CODE_XOR(0)); - UML_LOAD(block, I0, base, 0, SIZE_WORD, SCALE_x4); // load i0,base,word - sum += seqhead->opptr.w[0]; - for (curdesc = seqhead->next(); curdesc != seqlast->next(); curdesc = curdesc->next()) - if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP)) - { - base = m_direct->read_ptr(curdesc->physpc, SH2_CODE_XOR(0)); - UML_LOAD(block, I1, base, 0, SIZE_WORD, SCALE_x2); // load i1,*opptr,word - UML_ADD(block, I0, I0, I1); // add i0,i0,i1 - sum += curdesc->opptr.w[0]; - } - UML_CMP(block, I0, sum); // cmp i0,sum - UML_EXHc(block, COND_NE, *m_nocode, epc(seqhead)); // exne nocode,seqhead->pc -#endif - } -} - - -/*------------------------------------------------- - generate_sequence_instruction - generate code - for a single instruction in a sequence --------------------------------------------------*/ - -void sh2_device::generate_sequence_instruction(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint32_t ovrpc) -{ - offs_t expc; - - /* add an entry for the log */ - if (m_drcuml->logging() && !(desc->flags & OPFLAG_VIRTUAL_NOOP)) - log_add_disasm_comment(block, desc->pc, desc->opptr.w[0]); - - /* set the PC map variable */ - expc = (desc->flags & OPFLAG_IN_DELAY_SLOT) ? desc->pc - 1 : desc->pc; - UML_MAPVAR(block, MAPVAR_PC, expc); // mapvar PC,expc - - /* accumulate total cycles */ - compiler->cycles += desc->cycles; - - /* update the icount map variable */ - UML_MAPVAR(block, MAPVAR_CYCLES, compiler->cycles); // mapvar CYCLES,compiler->cycles - - /* if we want a probe, add it here */ - if (desc->pc == PROBE_ADDRESS) - { - UML_MOV(block, mem(&m_sh2_state->pc), desc->pc); // mov [pc],desc->pc - UML_CALLC(block, cfunc_printf_probe, this); // callc cfunc_printf_probe,sh2 - } - - /* if we are debugging, call the debugger */ - if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0) - { - UML_MOV(block, mem(&m_sh2_state->pc), desc->pc); // mov [pc],desc->pc - save_fast_iregs(block); - UML_DEBUG(block, desc->pc); // debug desc->pc - } - else // not debug, see what other reasons there are for flushing the PC - { - if (m_drcoptions & SH2DRC_FLUSH_PC) // always flush? - { - UML_MOV(block, mem(&m_sh2_state->pc), desc->pc); // mov m_sh2_state->pc, desc->pc - } - else // check for driver-selected flushes - { - int pcflush; - - for (pcflush = 0; pcflush < m_pcfsel; pcflush++) - { - if (desc->pc == m_pcflushes[pcflush]) - { - UML_MOV(block, mem(&m_sh2_state->pc), desc->pc); // mov m_sh2_state->pc, desc->pc - } - } - } - } - - - /* if we hit an unmapped address, fatal error */ - if (desc->flags & OPFLAG_COMPILER_UNMAPPED) - { - UML_MOV(block, mem(&m_sh2_state->pc), desc->pc); // mov [pc],desc->pc - save_fast_iregs(block); - UML_EXIT(block, EXECUTE_UNMAPPED_CODE); // exit EXECUTE_UNMAPPED_CODE - } - - /* if this is an invalid opcode, die */ - if (desc->flags & OPFLAG_INVALID_OPCODE) - { - fatalerror("SH2DRC: invalid opcode!\n"); - } - - /* otherwise, unless this is a virtual no-op, it's a regular instruction */ - else if (!(desc->flags & OPFLAG_VIRTUAL_NOOP)) - { - /* compile the instruction */ - if (!generate_opcode(block, compiler, desc, ovrpc)) - { - // handle an illegal op - UML_MOV(block, mem(&m_sh2_state->pc), desc->pc); // mov [pc],desc->pc - UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); // mov [arg0],opcode - UML_CALLC(block, cfunc_unimplemented, this); // callc cfunc_unimplemented - } - } -} - -/*------------------------------------------------------------------ - generate_delay_slot -------------------------------------------------------------------*/ - -void sh2_device::generate_delay_slot(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint32_t ovrpc) -{ - compiler_state compiler_temp = *compiler; - - /* compile the delay slot using temporary compiler state */ - assert(desc->delay.first() != nullptr); - generate_sequence_instruction(block, &compiler_temp, desc->delay.first(), ovrpc); // <next instruction> - - /* update the label */ - compiler->labelnum = compiler_temp.labelnum; -} - -/*------------------------------------------------- - generate_opcode - generate code for a specific - opcode --------------------------------------------------*/ - -bool sh2_device::generate_opcode(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint32_t ovrpc) -{ - uint32_t scratch, scratch2; - int32_t disp; - uint16_t opcode = desc->opptr.w[0]; - uint8_t opswitch = opcode >> 12; - int in_delay_slot = ((desc->flags & OPFLAG_IN_DELAY_SLOT) != 0); - - switch (opswitch) - { - case 0: - return generate_group_0(block, compiler, desc, opcode, in_delay_slot, ovrpc); - - case 1: // MOVLS4 - scratch = (opcode & 0x0f) * 4; - UML_ADD(block, I0, R32(Rn), scratch); // add r0, Rn, scratch - UML_MOV(block, I1, R32(Rm)); // mov r1, Rm - SETEA(0); // set ea for debug - UML_CALLH(block, *m_write32); - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 2: - return generate_group_2(block, compiler, desc, opcode, in_delay_slot, ovrpc); - case 3: - return generate_group_3(block, compiler, desc, opcode, ovrpc); - case 4: - return generate_group_4(block, compiler, desc, opcode, in_delay_slot, ovrpc); - - case 5: // MOVLL4 - scratch = (opcode & 0x0f) * 4; - UML_ADD(block, I0, R32(Rm), scratch); // add r0, Rm, scratch - SETEA(0); // set ea for debug - UML_CALLH(block, *m_read32); // call read32 - UML_MOV(block, R32(Rn), I0); // mov Rn, r0 - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 6: - return generate_group_6(block, compiler, desc, opcode, in_delay_slot, ovrpc); - - case 7: // ADDI - scratch = opcode & 0xff; - scratch2 = (uint32_t)(int32_t)(int16_t)(int8_t)scratch; - UML_ADD(block, R32(Rn), R32(Rn), scratch2); // add Rn, Rn, scratch2 - return true; - - case 8: - return generate_group_8(block, compiler, desc, opcode, in_delay_slot, ovrpc); - - case 9: // MOVWI - if (ovrpc == 0xffffffff) - { - scratch = (desc->pc + 2) + ((opcode & 0xff) * 2) + 2; - } - else - { - scratch = (ovrpc + 2) + ((opcode & 0xff) * 2) + 2; - } - - if (m_drcoptions & SH2DRC_STRICT_PCREL) - { - UML_MOV(block, I0, scratch); // mov r0, scratch - SETEA(0); // set ea for debug - UML_CALLH(block, *m_read16); // read16(r0, r1) - UML_SEXT(block, R32(Rn), I0, SIZE_WORD); // sext Rn, r0, WORD - } - else - { - scratch2 = (uint32_t)(int32_t)(int16_t) RW(scratch); - UML_MOV(block, R32(Rn), scratch2); // mov Rn, scratch2 - } - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 10: // BRA - disp = ((int32_t)opcode << 20) >> 20; - m_sh2_state->ea = (desc->pc + 2) + disp * 2 + 2; // m_sh2_state->ea = pc+4 + disp*2 + 2 - - generate_delay_slot(block, compiler, desc, m_sh2_state->ea-2); - - generate_update_cycles(block, compiler, m_sh2_state->ea, true); // <subtract cycles> - UML_HASHJMP(block, 0, m_sh2_state->ea, *m_nocode); // hashjmp m_sh2_state->ea - return true; - - case 11: // BSR - // panicstr @ 403da22 relies on the delay slot clobbering the PR set by a BSR, so - // do this before running the delay slot - UML_ADD(block, mem(&m_sh2_state->pr), desc->pc, 4); // add m_pr, desc->pc, #4 (skip the current insn & delay slot) - - disp = ((int32_t)opcode << 20) >> 20; - m_sh2_state->ea = (desc->pc + 2) + disp * 2 + 2; // m_sh2_state->ea = pc+4 + disp*2 + 2 - - generate_delay_slot(block, compiler, desc, m_sh2_state->ea-2); - - generate_update_cycles(block, compiler, m_sh2_state->ea, true); // <subtract cycles> - UML_HASHJMP(block, 0, m_sh2_state->ea, *m_nocode); // hashjmp m_sh2_state->ea - return true; - - case 12: - return generate_group_12(block, compiler, desc, opcode, in_delay_slot, ovrpc); - - case 13: // MOVLI - if (ovrpc == 0xffffffff) - { - scratch = ((desc->pc + 4) & ~3) + ((opcode & 0xff) * 4); - } - else - { - scratch = ((ovrpc + 4) & ~3) + ((opcode & 0xff) * 4); - } - - if (m_drcoptions & SH2DRC_STRICT_PCREL) - { - UML_MOV(block, I0, scratch); // mov r0, scratch - UML_CALLH(block, *m_read32); // read32(r0, r1) - UML_MOV(block, R32(Rn), I0); // mov Rn, r0 - } - else - { - scratch2 = RL(scratch); - UML_MOV(block, R32(Rn), scratch2); // mov Rn, scratch2 - } - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 14: // MOVI - scratch = opcode & 0xff; - scratch2 = (uint32_t)(int32_t)(int16_t)(int8_t)scratch; - UML_MOV(block, R32(Rn), scratch2); - return true; - - case 15: - return false; - } - - return false; -} - -bool sh2_device::generate_group_0(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) -{ - switch (opcode & 0x3F) - { - case 0x00: // these are all illegal - case 0x01: - case 0x10: - case 0x11: - case 0x13: - case 0x20: - case 0x21: - case 0x30: - case 0x31: - case 0x32: - case 0x33: - case 0x38: - case 0x39: - case 0x3a: - case 0x3b: - return false; - - case 0x09: // NOP(); - return true; - - case 0x02: // STCSR(Rn); - UML_MOV(block, R32(Rn), mem(&m_sh2_state->sr)); - return true; - - case 0x03: // BSRF(Rn); - if (m_cpu_type > CPU_TYPE_SH1) - { - UML_ADD(block, mem(&m_sh2_state->target), R32(Rn), 4); // add target, Rm, #4 - UML_ADD(block, mem(&m_sh2_state->target), mem(&m_sh2_state->target), desc->pc); // add target, target, pc - - // 32x Cosmic Carnage @ 6002cb0 relies on the delay slot - // clobbering the calculated PR, so do it first - UML_ADD(block, mem(&m_sh2_state->pr), desc->pc, 4); // add m_pr, desc->pc, #4 (skip the current insn & delay slot) - - generate_delay_slot(block, compiler, desc, m_sh2_state->target); - - generate_update_cycles(block, compiler, mem(&m_sh2_state->target), true); // <subtract cycles> - UML_HASHJMP(block, 0, mem(&m_sh2_state->target), *m_nocode); // jmp target - return true; - } - break; - - case 0x04: // MOVBS0(Rm, Rn); - case 0x14: // MOVBS0(Rm, Rn); - case 0x24: // MOVBS0(Rm, Rn); - case 0x34: // MOVBS0(Rm, Rn); - UML_ADD(block, I0, R32(0), R32(Rn)); // add r0, R0, Rn - UML_AND(block, I1, R32(Rm), 0x000000ff); // and r1, Rm, 0xff - UML_CALLH(block, *m_write8); // call write8 - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 0x05: // MOVWS0(Rm, Rn); - case 0x15: // MOVWS0(Rm, Rn); - case 0x25: // MOVWS0(Rm, Rn); - case 0x35: // MOVWS0(Rm, Rn); - UML_ADD(block, I0, R32(0), R32(Rn)); // add r0, R0, Rn - UML_AND(block, I1, R32(Rm), 0x0000ffff); // and r1, Rm, 0xffff - UML_CALLH(block, *m_write16); // call write16 - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 0x06: // MOVLS0(Rm, Rn); - case 0x16: // MOVLS0(Rm, Rn); - case 0x26: // MOVLS0(Rm, Rn); - case 0x36: // MOVLS0(Rm, Rn); - UML_ADD(block, I0, R32(0), R32(Rn)); // add r0, R0, Rn - UML_MOV(block, I1, R32(Rm)); // mov r1, Rm - UML_CALLH(block, *m_write32); // call write32 - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 0x07: // MULL(Rm, Rn); - case 0x17: // MULL(Rm, Rn); - case 0x27: // MULL(Rm, Rn); - case 0x37: // MULL(Rm, Rn); - if (m_cpu_type > CPU_TYPE_SH1) - { - UML_MULU(block, mem(&m_sh2_state->macl), mem(&m_sh2_state->ea), R32(Rn), R32(Rm)); // mulu macl, ea, Rn, Rm - return true; - } - break; - - case 0x08: // CLRT(); - UML_AND(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), ~T); // and r0, sr, ~T (clear the T bit) - return true; - - case 0x0a: // STSMACH(Rn); - UML_MOV(block, R32(Rn), mem(&m_sh2_state->mach)); // mov Rn, mach - return true; - - case 0x0b: // RTS(); - UML_MOV(block, mem(&m_sh2_state->target), mem(&m_sh2_state->pr)); // mov target, pr (in case of d-slot shenanigans) - - generate_delay_slot(block, compiler, desc, m_sh2_state->target); - - generate_update_cycles(block, compiler, mem(&m_sh2_state->target), true); // <subtract cycles> - UML_HASHJMP(block, 0, mem(&m_sh2_state->target), *m_nocode); - return true; - - case 0x0c: // MOVBL0(Rm, Rn); - case 0x1c: // MOVBL0(Rm, Rn); - case 0x2c: // MOVBL0(Rm, Rn); - case 0x3c: // MOVBL0(Rm, Rn); - UML_ADD(block, I0, R32(0), R32(Rm)); // add r0, R0, Rm - UML_CALLH(block, *m_read8); // call read8 - UML_SEXT(block, R32(Rn), I0, SIZE_BYTE); // sext Rn, r0, BYTE - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 0x0d: // MOVWL0(Rm, Rn); - case 0x1d: // MOVWL0(Rm, Rn); - case 0x2d: // MOVWL0(Rm, Rn); - case 0x3d: // MOVWL0(Rm, Rn); - UML_ADD(block, I0, R32(0), R32(Rm)); // add r0, R0, Rm - UML_CALLH(block, *m_read16); // call read16 - UML_SEXT(block, R32(Rn), I0, SIZE_WORD); // sext Rn, r0, WORD - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 0x0e: // MOVLL0(Rm, Rn); - case 0x1e: // MOVLL0(Rm, Rn); - case 0x2e: // MOVLL0(Rm, Rn); - case 0x3e: // MOVLL0(Rm, Rn); - UML_ADD(block, I0, R32(0), R32(Rm)); // add r0, R0, Rm - UML_CALLH(block, *m_read32); // call read32 - UML_MOV(block, R32(Rn), I0); // mov Rn, r0 - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 0x0f: // MAC_L(Rm, Rn); - case 0x1f: // MAC_L(Rm, Rn); - case 0x2f: // MAC_L(Rm, Rn); - case 0x3f: // MAC_L(Rm, Rn); - if (m_cpu_type > CPU_TYPE_SH1) - { - save_fast_iregs(block); - UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); - UML_CALLC(block, cfunc_MAC_L, this); - load_fast_iregs(block); - return true; - } - break; - - case 0x12: // STCGBR(Rn); - UML_MOV(block, R32(Rn), mem(&m_sh2_state->gbr)); // mov Rn, gbr - return true; - - case 0x18: // SETT(); - UML_OR(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), T); // or sr, sr, T - return true; - - case 0x19: // DIV0U(); - UML_AND(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), ~(M|Q|T)); // and sr, sr, ~(M|Q|T) - return true; - - case 0x1a: // STSMACL(Rn); - UML_MOV(block, R32(Rn), mem(&m_sh2_state->macl)); // mov Rn, macl - return true; - - case 0x1b: // SLEEP(); - UML_MOV(block, I0, mem(&m_sh2_state->sleep_mode)); // mov i0, sleep_mode - UML_CMP(block, I0, 0x2); // cmp i0, #2 - UML_JMPc(block, COND_E, compiler->labelnum); // beq labelnum - // sleep mode != 2 - UML_MOV(block, mem(&m_sh2_state->sleep_mode), 0x1); // mov sleep_mode, #1 - generate_update_cycles(block, compiler, desc->pc, true); // repeat this insn - UML_JMP(block, compiler->labelnum+1); // jmp labelnum+1 - - UML_LABEL(block, compiler->labelnum++); // labelnum: - // sleep_mode == 2 - UML_MOV(block, mem(&m_sh2_state->sleep_mode), 0x0); // sleep_mode = 0 - generate_update_cycles(block, compiler, desc->pc+2, true); // go to next insn - - UML_LABEL(block, compiler->labelnum++); // labelnum+1: - return true; - - case 0x22: // STCVBR(Rn); - UML_MOV(block, R32(Rn), mem(&m_sh2_state->vbr)); // mov Rn, vbr - return true; - - case 0x23: // BRAF(Rn); - if (m_cpu_type > CPU_TYPE_SH1) - { - UML_ADD(block, mem(&m_sh2_state->target), R32(Rn), desc->pc+4); // add target, Rn, pc+4 - - generate_delay_slot(block, compiler, desc, m_sh2_state->target); - - generate_update_cycles(block, compiler, mem(&m_sh2_state->target), true); // <subtract cycles> - UML_HASHJMP(block, 0, mem(&m_sh2_state->target), *m_nocode); // jmp target - return true; - } - break; - - case 0x28: // CLRMAC(); - UML_MOV(block, mem(&m_sh2_state->macl), 0); // mov macl, #0 - UML_MOV(block, mem(&m_sh2_state->mach), 0); // mov mach, #0 - return true; - - case 0x29: // MOVT(Rn); - UML_AND(block, R32(Rn), mem(&m_sh2_state->sr), T); // and Rn, sr, T - return true; - - case 0x2a: // STSPR(Rn); - UML_MOV(block, R32(Rn), mem(&m_sh2_state->pr)); // mov Rn, pr - return true; - - case 0x2b: // RTE(); - generate_delay_slot(block, compiler, desc, 0xffffffff); - - UML_MOV(block, I0, R32(15)); // mov r0, R15 - UML_CALLH(block, *m_read32); // call read32 - UML_MOV(block, mem(&m_sh2_state->pc), I0); // mov pc, r0 - UML_ADD(block, R32(15), R32(15), 4); // add R15, R15, #4 - - UML_MOV(block, I0, R32(15)); // mov r0, R15 - UML_CALLH(block, *m_read32); // call read32 - UML_MOV(block, mem(&m_sh2_state->sr), I0); // mov sr, r0 - UML_ADD(block, R32(15), R32(15), 4); // add R15, R15, #4 - - compiler->checkints = true; - UML_MOV(block, mem(&m_sh2_state->ea), mem(&m_sh2_state->pc)); // mov ea, pc - generate_update_cycles(block, compiler, mem(&m_sh2_state->ea), true); // <subtract cycles> - UML_HASHJMP(block, 0, mem(&m_sh2_state->pc), *m_nocode); // and jump to the "resume PC" - - return true; - } - - return false; -} - -bool sh2_device::generate_group_2(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) -{ - switch (opcode & 15) - { - case 0: // MOVBS(Rm, Rn); - UML_MOV(block, I0, R32(Rn)); // mov r0, Rn - UML_AND(block, I1, R32(Rm), 0xff); // and r1, Rm, 0xff - UML_CALLH(block, *m_write8); - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 1: // MOVWS(Rm, Rn); - UML_MOV(block, I0, R32(Rn)); // mov r0, Rn - UML_AND(block, I1, R32(Rm), 0xffff); // and r1, Rm, 0xffff - UML_CALLH(block, *m_write16); - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 2: // MOVLS(Rm, Rn); - UML_MOV(block, I0, R32(Rn)); // mov r0, Rn - UML_MOV(block, I1, R32(Rm)); // mov r1, Rm - UML_CALLH(block, *m_write32); - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 3: - return false; - - case 4: // MOVBM(Rm, Rn); - UML_MOV(block, I1, R32(Rm)); // mov r1, Rm - UML_SUB(block, R32(Rn), R32(Rn), 1); // sub Rn, Rn, 1 - UML_MOV(block, I0, R32(Rn)); // mov r0, Rn - UML_CALLH(block, *m_write8); // call write8 - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 5: // MOVWM(Rm, Rn); - UML_MOV(block, I1, R32(Rm)); // mov r1, Rm - UML_SUB(block, R32(Rn), R32(Rn), 2); // sub Rn, Rn, 2 - UML_MOV(block, I0, R32(Rn)); // mov r0, Rn - UML_CALLH(block, *m_write16); // call write16 - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 6: // MOVLM(Rm, Rn); - UML_MOV(block, I1, R32(Rm)); // mov r1, Rm - UML_SUB(block, R32(Rn), R32(Rn), 4); // sub Rn, Rn, 4 - UML_MOV(block, I0, R32(Rn)); // mov r0, Rn - UML_CALLH(block, *m_write32); // call write32 - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 13: // XTRCT(Rm, Rn); - UML_SHL(block, I0, R32(Rm), 16); // shl r0, Rm, #16 - UML_AND(block, I0, I0, 0xffff0000); // and r0, r0, #0xffff0000 - - UML_SHR(block, I1, R32(Rn), 16); // shr, r1, Rn, #16 - UML_AND(block, I1, I1, 0xffff); // and r1, r1, #0x0000ffff - - UML_OR(block, R32(Rn), I0, I1); // or Rn, r0, r1 - return true; - - case 7: // DIV0S(Rm, Rn); - UML_MOV(block, I0, mem(&m_sh2_state->sr)); // move r0, sr - UML_AND(block, I0, I0, ~(Q|M|T)); // and r0, r0, ~(Q|M|T) (clear the Q,M, and T bits) - - UML_TEST(block, R32(Rn), 0x80000000); // test Rn, #0x80000000 - UML_JMPc(block, COND_Z, compiler->labelnum); // jz labelnum - - UML_OR(block, I0, I0, Q); // or r0, r0, Q - UML_LABEL(block, compiler->labelnum++); // labelnum: - - UML_TEST(block, R32(Rm), 0x80000000); // test Rm, #0x80000000 - UML_JMPc(block, COND_Z, compiler->labelnum); // jz labelnum - - UML_OR(block, I0, I0, M); // or r0, r0, M - UML_LABEL(block, compiler->labelnum++); // labelnum: - - UML_XOR(block, I1, R32(Rn), R32(Rm)); // xor r1, Rn, Rm - UML_TEST(block, I1, 0x80000000); // test r1, #0x80000000 - UML_JMPc(block, COND_Z, compiler->labelnum); // jz labelnum - - UML_OR(block, I0, I0, T); // or r0, r0, T - UML_LABEL(block, compiler->labelnum++); // labelnum: - UML_MOV(block, mem(&m_sh2_state->sr), I0); // mov sr, r0 - return true; - - case 8: // TST(Rm, Rn); - UML_AND(block, I0, mem(&m_sh2_state->sr), ~T); // and r0, sr, ~T (clear the T bit) - UML_TEST(block, R32(Rm), R32(Rn)); // test Rm, Rn - UML_JMPc(block, COND_NZ, compiler->labelnum); // jnz compiler->labelnum - - UML_OR(block, I0, I0, T); // or r0, r0, T - UML_LABEL(block, compiler->labelnum++); // desc->pc: - - UML_MOV(block, mem(&m_sh2_state->sr), I0); // mov m_sh2_state->sr, r0 - return true; - - case 12: // CMPSTR(Rm, Rn); - UML_XOR(block, I0, R32(Rn), R32(Rm)); // xor r0, Rn, Rm (temp) - - UML_SHR(block, I1, I0, 24); // shr r1, r0, #24 (HH) - UML_AND(block, I1, I1, 0xff); // and r1, r1, #0xff - - UML_SHR(block, I2, I0, 16); // shr r2, r0, #16 (HL) - UML_AND(block, I2, I2, 0xff); // and r2, r2, #0xff - - UML_SHR(block, I3, I0, 8); // shr r3, r0, #8 (LH) - UML_AND(block, I3, I3, 0xff); // and r3, r3, #0xff - - UML_AND(block, I7, I0, 0xff); // and r7, r0, #0xff (LL) - - UML_AND(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), ~T); // and sr, sr, ~T (clear the T bit) - - UML_CMP(block, I1, 0); // cmp r1, #0 - UML_JMPc(block, COND_Z, compiler->labelnum); // jnz labelnum - UML_CMP(block, I2, 0); // cmp r2, #0 - UML_JMPc(block, COND_Z, compiler->labelnum); // jnz labelnum - UML_CMP(block, I3, 0); // cmp r3, #0 - UML_JMPc(block, COND_Z, compiler->labelnum); // jnz labelnum - UML_CMP(block, I7, 0); // cmp r7, #0 - UML_JMPc(block, COND_NZ, compiler->labelnum+1); // jnz labelnum - - UML_LABEL(block, compiler->labelnum++); // labelnum: - UML_OR(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), T); // or sr, sr, T - - UML_LABEL(block, compiler->labelnum++); // labelnum+1: - return true; - - case 9: // AND(Rm, Rn); - UML_AND(block, R32(Rn), R32(Rn), R32(Rm)); // and Rn, Rn, Rm - return true; - - case 10: // XOR(Rm, Rn); - UML_XOR(block, R32(Rn), R32(Rn), R32(Rm)); // xor Rn, Rn, Rm - return true; - - case 11: // OR(Rm, Rn); - UML_OR(block, R32(Rn), R32(Rn), R32(Rm)); // or Rn, Rn, Rm - return true; - - case 14: // MULU(Rm, Rn); - UML_AND(block, I0, R32(Rm), 0xffff); // and r0, Rm, 0xffff - UML_AND(block, I1, R32(Rn), 0xffff); // and r1, Rn, 0xffff - UML_MULU(block, mem(&m_sh2_state->macl), mem(&m_sh2_state->ea), I0, I1); // mulu macl, ea, r0, r1 - return true; - - case 15: // MULS(Rm, Rn); - UML_SEXT(block, I0, R32(Rm), SIZE_WORD); // sext r0, Rm - UML_SEXT(block, I1, R32(Rn), SIZE_WORD); // sext r1, Rn - UML_MULS(block, mem(&m_sh2_state->macl), mem(&m_sh2_state->ea), I0, I1); // muls macl, ea, r0, r1 - return true; - } - - return false; -} - -bool sh2_device::generate_group_3(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, uint32_t ovrpc) -{ - switch (opcode & 15) - { - case 0: // CMPEQ(Rm, Rn); (equality) - UML_CMP(block, R32(Rn), R32(Rm)); // cmp Rn, Rm - UML_SETc(block, COND_E, I0); // set E, r0 - UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, 1); // rolins sr, r0, 0, 1 - return true; - - case 2: // CMPHS(Rm, Rn); (unsigned greater than or equal) - UML_CMP(block, R32(Rn), R32(Rm)); // cmp Rn, Rm - UML_SETc(block, COND_AE, I0); // set AE, r0 - UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, 1); // rolins sr, r0, 0, 1 - return true; - - case 3: // CMPGE(Rm, Rn); (signed greater than or equal) - UML_CMP(block, R32(Rn), R32(Rm)); // cmp Rn, Rm - UML_SETc(block, COND_GE, I0); // set GE, r0 - UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, 1); // rolins sr, r0, 0, 1 - return true; - - case 6: // CMPHI(Rm, Rn); (unsigned greater than) - UML_CMP(block, R32(Rn), R32(Rm)); // cmp Rn, Rm - UML_SETc(block, COND_A, I0); // set A, r0 - UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, 1); // rolins sr, r0, 0, 1 - return true; - - case 7: // CMPGT(Rm, Rn); (signed greater than) - UML_CMP(block, R32(Rn), R32(Rm)); // cmp Rn, Rm - UML_SETc(block, COND_G, I0); // set G, r0 - UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, 1); // rolins sr, r0, 0, 1 - return true; - - case 1: - case 9: - return false; - - case 4: // DIV1(Rm, Rn); - save_fast_iregs(block); - UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); - UML_CALLC(block, cfunc_DIV1, this); - load_fast_iregs(block); - return true; - - case 5: // DMULU(Rm, Rn); - if (m_cpu_type > CPU_TYPE_SH1) - { - UML_MULU(block, mem(&m_sh2_state->macl), mem(&m_sh2_state->mach), R32(Rn), R32(Rm)); - return true; - } - break; - - case 13: // DMULS(Rm, Rn); - if (m_cpu_type > CPU_TYPE_SH1) - { - UML_MULS(block, mem(&m_sh2_state->macl), mem(&m_sh2_state->mach), R32(Rn), R32(Rm)); - return true; - } - break; - - case 8: // SUB(Rm, Rn); - UML_SUB(block, R32(Rn), R32(Rn), R32(Rm)); // sub Rn, Rn, Rm - return true; - - case 12: // ADD(Rm, Rn); - UML_ADD(block, R32(Rn), R32(Rn), R32(Rm)); // add Rn, Rn, Rm - return true; - - case 10: // SUBC(Rm, Rn); - UML_CARRY(block, mem(&m_sh2_state->sr), 0); // carry = T (T is bit 0 of SR) - UML_SUBB(block, R32(Rn), R32(Rn), R32(Rm)); // addc Rn, Rn, Rm - UML_SETc(block, COND_C, I0); // setc i0, C - UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, T); // rolins sr,i0,0,T - return true; - - case 11: // SUBV(Rm, Rn); -#if ADDSUBV_DIRECT - UML_SUB(block, R32(Rn), R32(Rn), R32(Rm)); // sub Rn, Rn, Rm - UML_SETc(block, COND_V, I0); // setc i0, V - UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, T); // rolins [sr],i0,0,T -#else - save_fast_iregs(block); - UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); - UML_CALLC(block, cfunc_SUBV, this); - load_fast_iregs(block); -#endif - return true; - - case 14: // ADDC(Rm, Rn); - UML_CARRY(block, mem(&m_sh2_state->sr), 0); // carry = T (T is bit 0 of SR) - UML_ADDC(block, R32(Rn), R32(Rn), R32(Rm)); // addc Rn, Rn, Rm - UML_SETc(block, COND_C, I0); // setc i0, C - UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, T); // rolins sr,i0,0,T - return true; - - case 15: // ADDV(Rm, Rn); -#if ADDSUBV_DIRECT - UML_ADD(block, R32(Rn), R32(Rn), R32(Rm)); // add Rn, Rn, Rm - UML_SETc(block, COND_V, I0); // setc i0, V - UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, T); // rolins [sr],i0,0,T -#else - save_fast_iregs(block); - UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); - UML_CALLC(block, cfunc_ADDV, this); - load_fast_iregs(block); -#endif - return true; - } - return false; -} - -bool sh2_device::generate_group_4(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) -{ - switch (opcode & 0x3F) - { - case 0x00: // SHLL(Rn); - UML_SHL(block, R32(Rn), R32(Rn), 1); // shl Rn, Rn, 1 - UML_SETc(block, COND_C, I0); // set i0,C - UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, T); // rolins [sr],i0,0,T - return true; - - case 0x01: // SHLR(Rn); - UML_SHR(block, R32(Rn), R32(Rn), 1); // shr Rn, Rn, 1 - UML_SETc(block, COND_C, I0); // set i0,C - UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, T); // rolins [sr],i0,0,T - return true; - - case 0x04: // ROTL(Rn); - UML_ROL(block, R32(Rn), R32(Rn), 1); // rol Rn, Rn, 1 - UML_SETc(block, COND_C, I0); // set i0,C - UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, T); // rolins [sr],i0,0,T - return true; - - case 0x05: // ROTR(Rn); - UML_ROR(block, R32(Rn), R32(Rn), 1); // ror Rn, Rn, 1 - UML_SETc(block, COND_C, I0); // set i0,C - UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, T); // rolins [sr],i0,0,T - return true; - - case 0x02: // STSMMACH(Rn); - UML_SUB(block, R32(Rn), R32(Rn), 4); // sub Rn, Rn, #4 - UML_MOV(block, I0, R32(Rn)); // mov r0, Rn - UML_MOV(block, I1, mem(&m_sh2_state->mach)); // mov r1, mach - SETEA(0); // set ea for debug - UML_CALLH(block, *m_write32); // call write32 - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 0x03: // STCMSR(Rn); - UML_SUB(block, R32(Rn), R32(Rn), 4); // sub Rn, Rn, #4 - UML_MOV(block, I0, R32(Rn)); // mov r0, Rn - UML_MOV(block, I1, mem(&m_sh2_state->sr)); // mov r1, sr - SETEA(0); // set ea for debug - UML_CALLH(block, *m_write32); // call write32 - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 0x06: // LDSMMACH(Rn); - UML_MOV(block, I0, R32(Rn)); // mov r0, Rn - SETEA(0); - UML_CALLH(block, *m_read32); // call read32 - UML_ADD(block, R32(Rn), R32(Rn), 4); // add Rn, #4 - UML_MOV(block, mem(&m_sh2_state->mach), I0); // mov mach, r0 - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 0x07: // LDCMSR(Rn); - UML_MOV(block, I0, R32(Rn)); // mov r0, Rn - SETEA(0); - UML_CALLH(block, *m_read32); // call read32 - UML_ADD(block, R32(Rn), R32(Rn), 4); // add Rn, #4 - UML_MOV(block, mem(&m_sh2_state->sr), I0); // mov sr, r0 - - compiler->checkints = true; - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - - case 0x08: // SHLL2(Rn); - UML_SHL(block, R32(Rn), R32(Rn), 2); - return true; - - case 0x09: // SHLR2(Rn); - UML_SHR(block, R32(Rn), R32(Rn), 2); - return true; - - case 0x18: // SHLL8(Rn); - UML_SHL(block, R32(Rn), R32(Rn), 8); - return true; - - case 0x19: // SHLR8(Rn); - UML_SHR(block, R32(Rn), R32(Rn), 8); - return true; - - case 0x28: // SHLL16(Rn); - UML_SHL(block, R32(Rn), R32(Rn), 16); - return true; - - case 0x29: // SHLR16(Rn); - UML_SHR(block, R32(Rn), R32(Rn), 16); - return true; - - case 0x0a: // LDSMACH(Rn); - UML_MOV(block, mem(&m_sh2_state->mach), R32(Rn)); // mov mach, Rn - return true; - - case 0x0b: // JSR(Rn); - UML_MOV(block, mem(&m_sh2_state->target), R32(Rn)); // mov target, Rn - - UML_ADD(block, mem(&m_sh2_state->pr), desc->pc, 4); // add m_pr, desc->pc, #4 (skip the current insn & delay slot) - - generate_delay_slot(block, compiler, desc, m_sh2_state->target-4); - - generate_update_cycles(block, compiler, mem(&m_sh2_state->target), true); // <subtract cycles> - UML_HASHJMP(block, 0, mem(&m_sh2_state->target), *m_nocode); // and do the jump - return true; - - case 0x0e: // LDCSR(Rn); - UML_MOV(block, I0, R32(Rn)); // mov r0, Rn - UML_AND(block, I0, I0, FLAGS); // and r0, r0, FLAGS - UML_MOV(block, mem(&m_sh2_state->sr), I0); - - compiler->checkints = true; - return true; - - case 0x0f: // MAC_W(Rm, Rn); - case 0x1f: // MAC_W(Rm, Rn); - case 0x2f: // MAC_W(Rm, Rn); - case 0x3f: // MAC_W(Rm, Rn); - save_fast_iregs(block); - UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); - UML_CALLC(block, cfunc_MAC_W, this); - load_fast_iregs(block); - return true; - - case 0x10: // DT(Rn); - if (m_cpu_type > CPU_TYPE_SH1) - { - UML_AND(block, I0, mem(&m_sh2_state->sr), ~T); // and r0, sr, ~T (clear the T bit) - UML_SUB(block, R32(Rn), R32(Rn), 1); // sub Rn, Rn, 1 - UML_JMPc(block, COND_NZ, compiler->labelnum); // jz compiler->labelnum - - UML_OR(block, I0, I0, T); // or r0, r0, T - UML_LABEL(block, compiler->labelnum++); // desc->pc: - - UML_MOV(block, mem(&m_sh2_state->sr), I0); // mov m_sh2_state->sr, r0 - return true; - } - break; - - case 0x11: // CMPPZ(Rn); - UML_AND(block, I0, mem(&m_sh2_state->sr), ~T); // and r0, sr, ~T (clear the T bit) - - UML_CMP(block, R32(Rn), 0); // cmp Rn, 0 - UML_JMPc(block, COND_S, compiler->labelnum); // js compiler->labelnum (if negative) - - UML_OR(block, I0, I0, T); // or r0, r0, T - UML_LABEL(block, compiler->labelnum++); // desc->pc: - - UML_MOV(block, mem(&m_sh2_state->sr), I0); // mov m_sh2_state->sr, r0 - return true; - - case 0x15: // CMPPL(Rn); - UML_AND(block, I0, mem(&m_sh2_state->sr), ~T); // and r0, sr, ~T (clear the T bit) - - UML_CMP(block, R32(Rn), 0); // cmp Rn, 0 - - UML_JMPc(block, COND_S, compiler->labelnum); // js compiler->labelnum (if negative) - UML_JMPc(block, COND_Z, compiler->labelnum); // jz compiler->labelnum (if zero) - - UML_OR(block, I0, I0, T); // or r0, r0, T - - UML_LABEL(block, compiler->labelnum++); // desc->pc: - UML_MOV(block, mem(&m_sh2_state->sr), I0); // mov m_sh2_state->sr, r0 - return true; - - case 0x12: // STSMMACL(Rn); - UML_SUB(block, R32(Rn), R32(Rn), 4); // sub Rn, Rn, #4 - UML_MOV(block, I0, R32(Rn)); // mov r0, Rn - UML_MOV(block, I1, mem(&m_sh2_state->macl)); // mov r1, macl - SETEA(0); // set ea for debug - UML_CALLH(block, *m_write32); // call write32 - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 0x13: // STCMGBR(Rn); - UML_SUB(block, R32(Rn), R32(Rn), 4); // sub Rn, Rn, #4 - UML_MOV(block, I0, R32(Rn)); // mov r0, Rn - UML_MOV(block, I1, mem(&m_sh2_state->gbr)); // mov r1, gbr - SETEA(0); // set ea for debug - UML_CALLH(block, *m_write32); // call write32 - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 0x16: // LDSMMACL(Rn); - UML_MOV(block, I0, R32(Rn)); // mov r0, Rn - SETEA(0); - UML_CALLH(block, *m_read32); // call read32 - UML_ADD(block, R32(Rn), R32(Rn), 4); // add Rn, #4 - UML_MOV(block, mem(&m_sh2_state->macl), I0); // mov macl, r0 - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 0x17: // LDCMGBR(Rn); - UML_MOV(block, I0, R32(Rn)); // mov r0, Rn - SETEA(0); - UML_CALLH(block, *m_read32); // call read32 - UML_ADD(block, R32(Rn), R32(Rn), 4); // add Rn, #4 - UML_MOV(block, mem(&m_sh2_state->gbr), I0); // mov gbr, r0 - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 0x1a: // LDSMACL(Rn); - UML_MOV(block, mem(&m_sh2_state->macl), R32(Rn)); // mov macl, Rn - return true; - - case 0x1b: // TAS(Rn); - UML_MOV(block, I0, R32(Rn)); // mov r0, Rn - SETEA(0); - UML_CALLH(block, *m_read8); // call read8 - - UML_AND(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), ~T); // and sr, sr, ~T - - UML_CMP(block, I0, 0); // cmp r0, #0 - UML_JMPc(block, COND_NZ, compiler->labelnum); // jnz labelnum - - UML_OR(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), T); // or sr, sr, T - - UML_LABEL(block, compiler->labelnum++); // labelnum: - - UML_OR(block, I1, I0, 0x80); // or r1, r0, #0x80 - - UML_MOV(block, I0, R32(Rn)); // mov r0, Rn - UML_CALLH(block, *m_write8); // write the value back - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 0x1e: // LDCGBR(Rn); - UML_MOV(block, mem(&m_sh2_state->gbr), R32(Rn)); // mov gbr, Rn - return true; - - case 0x20: // SHAL(Rn); - UML_AND(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), ~T); // and sr, sr, ~T - UML_SHR(block, I0, R32(Rn), 31); // shr r0, Rn, 31 - UML_AND(block, I0, I0, T); // and r0, r0, T - UML_OR(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), I0); // or sr, sr, r0 - UML_SHL(block, R32(Rn), R32(Rn), 1); // shl Rn, Rn, 1 - return true; - - case 0x21: // SHAR(Rn); - UML_AND(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), ~T); // and sr, sr, ~T - UML_AND(block, I0, R32(Rn), T); // and r0, Rn, T - UML_OR(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), I0); // or sr, sr, r0 - UML_SAR(block, R32(Rn), R32(Rn), 1); // sar Rn, Rn, 1 - return true; - - case 0x22: // STSMPR(Rn); - UML_SUB(block, R32(Rn), R32(Rn), 4); // sub Rn, Rn, 4 - UML_MOV(block, I0, R32(Rn)); // mov r0, Rn - SETEA(0); - UML_MOV(block, I1, mem(&m_sh2_state->pr)); // mov r1, pr - UML_CALLH(block, *m_write32); // call write32 - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 0x23: // STCMVBR(Rn); - UML_SUB(block, R32(Rn), R32(Rn), 4); // sub Rn, Rn, 4 - UML_MOV(block, I0, R32(Rn)); // mov r0, Rn - SETEA(0); - UML_MOV(block, I1, mem(&m_sh2_state->vbr)); // mov r1, vbr - UML_CALLH(block, *m_write32); // call write32 - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 0x24: // ROTCL(Rn); - UML_CARRY(block, mem(&m_sh2_state->sr), 0); // carry sr,0 - UML_ROLC(block, R32(Rn), R32(Rn), 1); // rolc Rn,Rn,1 - UML_SETc(block, COND_C, I0); // set i0,C - UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, T); // rolins sr,i0,0,T - return true; - - case 0x25: // ROTCR(Rn); - UML_CARRY(block, mem(&m_sh2_state->sr), 0); // carry sr,0 - UML_RORC(block, R32(Rn), R32(Rn), 1); // rorc Rn,Rn,1 - UML_SETc(block, COND_C, I0); // set i0,C - UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, T); // rolins sr,i0,0,T - return true; - - case 0x26: // LDSMPR(Rn); - UML_MOV(block, I0, R32(Rn)); // mov r0, Rn - SETEA(0); - UML_CALLH(block, *m_read32); // call read32 - UML_MOV(block, mem(&m_sh2_state->pr), I0); // mov m_pr, r0 - UML_ADD(block, R32(Rn), R32(Rn), 4); // add Rn, Rn, #4 - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 0x27: // LDCMVBR(Rn); - UML_MOV(block, I0, R32(Rn)); // mov r0, Rn - SETEA(0); - UML_CALLH(block, *m_read32); // call read32 - UML_MOV(block, mem(&m_sh2_state->vbr), I0); // mov m_sh2_state->vbr, r0 - UML_ADD(block, R32(Rn), R32(Rn), 4); // add Rn, Rn, #4 - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 0x2a: // LDSPR(Rn); - UML_MOV(block, mem(&m_sh2_state->pr), R32(Rn)); // mov m_pr, Rn - return true; - - case 0x2b: // JMP(Rn); - UML_MOV(block, mem(&m_sh2_state->target), R32(Rn)); // mov target, Rn - - generate_delay_slot(block, compiler, desc, m_sh2_state->target); - - generate_update_cycles(block, compiler, mem(&m_sh2_state->target), true); // <subtract cycles> - UML_HASHJMP(block, 0, mem(&m_sh2_state->target), *m_nocode); // jmp (target) - return true; - - case 0x2e: // LDCVBR(Rn); - UML_MOV(block, mem(&m_sh2_state->vbr), R32(Rn)); // mov vbr, Rn - return true; - - case 0x0c: - case 0x0d: - case 0x14: - case 0x1c: - case 0x1d: - case 0x2c: - case 0x2d: - case 0x30: - case 0x31: - case 0x32: - case 0x33: - case 0x34: - case 0x35: - case 0x36: - case 0x37: - case 0x38: - case 0x39: - case 0x3a: - case 0x3b: - case 0x3c: - case 0x3d: - case 0x3e: - return false; - } - - return false; -} - -bool sh2_device::generate_group_6(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) -{ - switch (opcode & 15) - { - case 0: // MOVBL(Rm, Rn); - UML_MOV(block, I0, R32(Rm)); // mov r0, Rm - SETEA(0); // debug: ea = r0 - UML_CALLH(block, *m_read8); // call read8 - UML_SEXT(block, R32(Rn), I0, SIZE_BYTE); // sext Rn, r0, BYTE - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 1: // MOVWL(Rm, Rn); - UML_MOV(block, I0, R32(Rm)); // mov r0, Rm - SETEA(0); // debug: ea = r0 - UML_CALLH(block, *m_read16); // call read16 - UML_SEXT(block, R32(Rn), I0, SIZE_WORD); // sext Rn, r0, WORD - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 2: // MOVLL(Rm, Rn); - UML_MOV(block, I0, R32(Rm)); // mov r0, Rm - SETEA(0); // debug: ea = r0 - UML_CALLH(block, *m_read32); // call read32 - UML_MOV(block, R32(Rn), I0); // mov Rn, r0 - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 3: // MOV(Rm, Rn); - UML_MOV(block, R32(Rn), R32(Rm)); // mov Rn, Rm - return true; - - case 7: // NOT(Rm, Rn); - UML_XOR(block, R32(Rn), R32(Rm), 0xffffffff); // xor Rn, Rm, 0xffffffff - return true; - - case 9: // SWAPW(Rm, Rn); - UML_ROL(block, R32(Rn), R32(Rm), 16); // rol Rn, Rm, 16 - return true; - - case 11: // NEG(Rm, Rn); - UML_SUB(block, R32(Rn), 0, R32(Rm)); // sub Rn, 0, Rm - return true; - - case 12: // EXTUB(Rm, Rn); - UML_AND(block, R32(Rn), R32(Rm), 0x000000ff); // and Rn, Rm, 0xff - return true; - - case 13: // EXTUW(Rm, Rn); - UML_AND(block, R32(Rn), R32(Rm), 0x0000ffff); // and Rn, Rm, 0xffff - return true; - - case 14: // EXTSB(Rm, Rn); - UML_SEXT(block, R32(Rn), R32(Rm), SIZE_BYTE); // sext Rn, Rm, BYTE - return true; - - case 15: // EXTSW(Rm, Rn); - UML_SEXT(block, R32(Rn), R32(Rm), SIZE_WORD); // sext Rn, Rm, WORD - return true; - - case 4: // MOVBP(Rm, Rn); - UML_MOV(block, I0, R32(Rm)); // mov r0, Rm - UML_CALLH(block, *m_read8); // call read8 - UML_SEXT(block, R32(Rn), I0, SIZE_BYTE); // sext Rn, r0, BYTE - - if (Rm != Rn) - UML_ADD(block, R32(Rm), R32(Rm), 1); // add Rm, Rm, #1 - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 5: // MOVWP(Rm, Rn); - UML_MOV(block, I0, R32(Rm)); // mov r0, Rm - UML_CALLH(block, *m_read16); // call read16 - UML_SEXT(block, R32(Rn), I0, SIZE_WORD); // sext Rn, r0, WORD - - if (Rm != Rn) - UML_ADD(block, R32(Rm), R32(Rm), 2); // add Rm, Rm, #2 - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 6: // MOVLP(Rm, Rn); - UML_MOV(block, I0, R32(Rm)); // mov r0, Rm - UML_CALLH(block, *m_read32); // call read32 - UML_MOV(block, R32(Rn), I0); // mov Rn, r0 - - if (Rm != Rn) - UML_ADD(block, R32(Rm), R32(Rm), 4); // add Rm, Rm, #4 - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 8: // SWAPB(Rm, Rn); - UML_AND(block, I0, R32(Rm), 0xffff0000); // and r0, Rm, #0xffff0000 - UML_AND(block, I1, R32(Rm), 0x000000ff); // and r0, Rm, #0x000000ff - UML_AND(block, I2, R32(Rm), 0x0000ff00); // and r0, Rm, #0x0000ff00 - UML_SHL(block, I1, I1, 8); // shl r1, r1, #8 - UML_SHR(block, I2, I2, 8); // shr r2, r2, #8 - UML_OR(block, I0, I0, I1); // or r0, r0, r1 - UML_OR(block, R32(Rn), I0, I2); // or Rn, r0, r2 - return true; - - case 10: // NEGC(Rm, Rn); - UML_MOV(block, I0, mem(&m_sh2_state->sr)); // mov r0, sr (save SR) - UML_AND(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), ~T); // and sr, sr, ~T (clear the T bit) - UML_CARRY(block, I0, 0); // carry = T (T is bit 0 of SR) - UML_SUBB(block, R32(Rn), 0, R32(Rm)); // subb Rn, #0, Rm - - UML_JMPc(block, COND_NC, compiler->labelnum); // jnc labelnum - - UML_OR(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), T); // or sr, sr, T - - UML_LABEL(block, compiler->labelnum++); // labelnum: - - return true; - } - - return false; -} - -bool sh2_device::generate_group_8(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) -{ - int32_t disp; - uint32_t udisp; - code_label templabel; - - switch ( opcode & (15<<8) ) - { - case 0 << 8: // MOVBS4(opcode & 0x0f, Rm); - udisp = (opcode & 0x0f); - UML_ADD(block, I0, R32(Rm), udisp); // add r0, Rm, udisp - UML_MOV(block, I1, R32(0)); // mov r1, R0 - UML_CALLH(block, *m_write8); // call write8 - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 1 << 8: // MOVWS4(opcode & 0x0f, Rm); - udisp = (opcode & 0x0f) * 2; - UML_ADD(block, I0, R32(Rm), udisp); // add r0, Rm, udisp - UML_MOV(block, I1, R32(0)); // mov r1, R0 - UML_CALLH(block, *m_write16); // call write16 - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 2<< 8: - case 3<< 8: - case 6<< 8: - case 7<< 8: - case 10<< 8: - case 12<< 8: - case 14<< 8: - return false; - - case 4<< 8: // MOVBL4(Rm, opcode & 0x0f); - udisp = opcode & 0x0f; - UML_ADD(block, I0, R32(Rm), udisp); // add r0, Rm, udisp - SETEA(0); - UML_CALLH(block, *m_read8); // call read8 - UML_SEXT(block, R32(0), I0, SIZE_BYTE); // sext R0, r0, BYTE - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 5<< 8: // MOVWL4(Rm, opcode & 0x0f); - udisp = (opcode & 0x0f)*2; - UML_ADD(block, I0, R32(Rm), udisp); // add r0, Rm, udisp - SETEA(0); - UML_CALLH(block, *m_read16); // call read16 - UML_SEXT(block, R32(0), I0, SIZE_WORD); // sext R0, r0, WORD - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 8<< 8: // CMPIM(opcode & 0xff); - UML_AND(block, I0, mem(&m_sh2_state->sr), ~T); // and r0, sr, ~T (clear the T bit) - - UML_SEXT(block, I1, opcode&0xff, SIZE_BYTE); // sext r1, opcode&0xff, BYTE - UML_CMP(block, I1, R32(0)); // cmp r1, R0 - UML_JMPc(block, COND_NZ, compiler->labelnum); // jnz compiler->labelnum (if negative) - - UML_OR(block, I0, I0, T); // or r0, r0, T - - UML_LABEL(block, compiler->labelnum++); // labelnum: - UML_MOV(block, mem(&m_sh2_state->sr), I0); // mov m_sh2_state->sr, r0 - return true; - - case 9<< 8: // BT(opcode & 0xff); - UML_TEST(block, mem(&m_sh2_state->sr), T); // test m_sh2_state->sr, T - UML_JMPc(block, COND_Z, compiler->labelnum); // jz compiler->labelnum - - disp = ((int32_t)opcode << 24) >> 24; - m_sh2_state->ea = (desc->pc + 2) + disp * 2 + 2; // m_sh2_state->ea = destination - - generate_update_cycles(block, compiler, m_sh2_state->ea, true); // <subtract cycles> - UML_HASHJMP(block, 0, m_sh2_state->ea, *m_nocode); // jmp m_sh2_state->ea - - UML_LABEL(block, compiler->labelnum++); // labelnum: - return true; - - case 11<< 8: // BF(opcode & 0xff); - UML_TEST(block, mem(&m_sh2_state->sr), T); // test m_sh2_state->sr, T - UML_JMPc(block, COND_NZ, compiler->labelnum); // jnz compiler->labelnum - - disp = ((int32_t)opcode << 24) >> 24; - m_sh2_state->ea = (desc->pc + 2) + disp * 2 + 2; // m_sh2_state->ea = destination - - generate_update_cycles(block, compiler, m_sh2_state->ea, true); // <subtract cycles> - UML_HASHJMP(block, 0, m_sh2_state->ea, *m_nocode); // jmp m_sh2_state->ea - - UML_LABEL(block, compiler->labelnum++); // labelnum: - return true; - - case 13<< 8: // BTS(opcode & 0xff); - if (m_cpu_type > CPU_TYPE_SH1) - { - UML_TEST(block, mem(&m_sh2_state->sr), T); // test m_sh2_state->sr, T - UML_JMPc(block, COND_Z, compiler->labelnum); // jz compiler->labelnum - - disp = ((int32_t)opcode << 24) >> 24; - m_sh2_state->ea = (desc->pc + 2) + disp * 2 + 2; // m_sh2_state->ea = destination - - templabel = compiler->labelnum; // save our label - compiler->labelnum++; // make sure the delay slot doesn't use it - generate_delay_slot(block, compiler, desc, m_sh2_state->ea-2); - - generate_update_cycles(block, compiler, m_sh2_state->ea, true); // <subtract cycles> - UML_HASHJMP(block, 0, m_sh2_state->ea, *m_nocode); // jmp m_sh2_state->ea - - UML_LABEL(block, templabel); // labelnum: - return true; - } - break; - - case 15<< 8: // BFS(opcode & 0xff); - if (m_cpu_type > CPU_TYPE_SH1) - { - UML_TEST(block, mem(&m_sh2_state->sr), T); // test m_sh2_state->sr, T - UML_JMPc(block, COND_NZ, compiler->labelnum); // jnz compiler->labelnum - - disp = ((int32_t)opcode << 24) >> 24; - m_sh2_state->ea = (desc->pc + 2) + disp * 2 + 2; // m_sh2_state->ea = destination - - templabel = compiler->labelnum; // save our label - compiler->labelnum++; // make sure the delay slot doesn't use it - generate_delay_slot(block, compiler, desc, m_sh2_state->ea-2); // delay slot only if the branch is taken - - generate_update_cycles(block, compiler, m_sh2_state->ea, true); // <subtract cycles> - UML_HASHJMP(block, 0, m_sh2_state->ea, *m_nocode); // jmp m_sh2_state->ea - - UML_LABEL(block, templabel); // labelnum: - return true; - } - break; - } - - return false; -} - -bool sh2_device::generate_group_12(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) -{ - uint32_t scratch; - - switch (opcode & (15<<8)) - { - case 0<<8: // MOVBSG(opcode & 0xff); - scratch = (opcode & 0xff); - UML_ADD(block, I0, mem(&m_sh2_state->gbr), scratch); // add r0, gbr, scratch - UML_AND(block, I1, R32(0), 0xff); // and r1, R0, 0xff - UML_CALLH(block, *m_write8); // call write8 - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 1<<8: // MOVWSG(opcode & 0xff); - scratch = (opcode & 0xff) * 2; - UML_ADD(block, I0, mem(&m_sh2_state->gbr), scratch); // add r0, gbr, scratch - UML_AND(block, I1, R32(0), 0xffff); // and r1, R0, 0xffff - UML_CALLH(block, *m_write16); // call write16 - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 2<<8: // MOVLSG(opcode & 0xff); - scratch = (opcode & 0xff) * 4; - UML_ADD(block, I0, mem(&m_sh2_state->gbr), scratch); // add r0, gbr, scratch - UML_MOV(block, I1, R32(0)); // mov r1, R0 - UML_CALLH(block, *m_write32); // call write32 - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 3<<8: // TRAPA(opcode & 0xff); - scratch = (opcode & 0xff) * 4; - UML_ADD(block, mem(&m_sh2_state->ea), mem(&m_sh2_state->vbr), scratch); // add ea, vbr, scratch - - UML_SUB(block, R32(15), R32(15), 4); // sub R15, R15, #4 - UML_MOV(block, I0, R32(15)); // mov r0, R15 - UML_MOV(block, I1, mem(&m_sh2_state->sr)); // mov r1, sr - UML_CALLH(block, *m_write32); // write32 - - UML_SUB(block, R32(15), R32(15), 4); // sub R15, R15, #4 - UML_MOV(block, I0, R32(15)); // mov r0, R15 - UML_MOV(block, I1, desc->pc+2); // mov r1, pc+2 - UML_CALLH(block, *m_write32); // write32 - - UML_MOV(block, I0, mem(&m_sh2_state->ea)); // mov r0, ea - UML_CALLH(block, *m_read32); // read32 - UML_HASHJMP(block, 0, I0, *m_nocode); // jmp (r0) - - return true; - - case 4<<8: // MOVBLG(opcode & 0xff); - scratch = (opcode & 0xff); - UML_ADD(block, I0, mem(&m_sh2_state->gbr), scratch); // add r0, gbr, scratch - UML_CALLH(block, *m_read8); // call read16 - UML_SEXT(block, R32(0), I0, SIZE_BYTE); // sext R0, r0, BYTE - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 5<<8: // MOVWLG(opcode & 0xff); - scratch = (opcode & 0xff) * 2; - UML_ADD(block, I0, mem(&m_sh2_state->gbr), scratch); // add r0, gbr, scratch - UML_CALLH(block, *m_read16); // call read16 - UML_SEXT(block, R32(0), I0, SIZE_WORD); // sext R0, r0, WORD - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 6<<8: // MOVLLG(opcode & 0xff); - scratch = (opcode & 0xff) * 4; - UML_ADD(block, I0, mem(&m_sh2_state->gbr), scratch); // add r0, gbr, scratch - UML_CALLH(block, *m_read32); // call read32 - UML_MOV(block, R32(0), I0); // mov R0, r0 - - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 2, true); - return true; - - case 7<<8: // MOVA(opcode & 0xff); - scratch = (opcode & 0xff) * 4; - scratch += ((desc->pc + 4) & ~3); - - UML_MOV(block, R32(0), scratch); // mov R0, scratch - return true; - - case 8<<8: // TSTI(opcode & 0xff); - scratch = opcode & 0xff; - - UML_AND(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), ~T); // and sr, sr, ~T (clear the T bit) - UML_AND(block, I0, R32(0), scratch); // and r0, R0, scratch - UML_CMP(block, I0, 0); // cmp r0, #0 - UML_JMPc(block, COND_NZ, compiler->labelnum); // jnz labelnum - - UML_OR(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), T); // or sr, sr, T - - UML_LABEL(block, compiler->labelnum++); // labelnum: - return true; - - case 9<<8: // ANDI(opcode & 0xff); - UML_AND(block, R32(0), R32(0), opcode & 0xff); // and r0, r0, opcode & 0xff - return true; - - case 10<<8: // XORI(opcode & 0xff); - UML_XOR(block, R32(0), R32(0), opcode & 0xff); // xor r0, r0, opcode & 0xff - return true; - - case 11<<8: // ORI(opcode & 0xff); - UML_OR(block, R32(0), R32(0), opcode & 0xff); // or r0, r0, opcode & 0xff - return true; - - case 12<<8: // TSTM(opcode & 0xff); - UML_AND(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), ~T); // and sr, sr, ~T (clear the T bit) - UML_ADD(block, I0, R32(0), mem(&m_sh2_state->gbr)); // add r0, R0, gbr - UML_CALLH(block, *m_read8); // read8 - - UML_AND(block, I0, I0, opcode & 0xff); - UML_CMP(block, I0, 0); // cmp r0, #0 - UML_JMPc(block, COND_NZ, compiler->labelnum); // jnz labelnum - - UML_OR(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), T); // or sr, sr, T - - UML_LABEL(block, compiler->labelnum++); // labelnum: - return true; - - case 13<<8: // ANDM(opcode & 0xff); - UML_ADD(block, I0, R32(0), mem(&m_sh2_state->gbr)); // add r0, R0, gbr - UML_CALLH(block, *m_read8); // read8 - - UML_AND(block, I1, I0, opcode&0xff); // and r1, r0, #opcode&0xff - UML_ADD(block, I0, R32(0), mem(&m_sh2_state->gbr)); // add r0, R0, gbr - SETEA(0); - UML_CALLH(block, *m_write8); // write8 - return true; - - case 14<<8: // XORM(opcode & 0xff); - UML_ADD(block, I0, R32(0), mem(&m_sh2_state->gbr)); // add r0, R0, gbr - UML_CALLH(block, *m_read8); // read8 - - UML_XOR(block, I1, I0, opcode&0xff); // xor r1, r0, #opcode&0xff - UML_ADD(block, I0, R32(0), mem(&m_sh2_state->gbr)); // add r0, R0, gbr - SETEA(0); - UML_CALLH(block, *m_write8); // write8 - return true; - - case 15<<8: // ORM(opcode & 0xff); - UML_ADD(block, I0, R32(0), mem(&m_sh2_state->gbr)); // add r0, R0, gbr - UML_CALLH(block, *m_read8); // read8 - - UML_OR(block, I1, I0, opcode&0xff); // or r1, r0, #opcode&0xff - UML_ADD(block, I0, R32(0), mem(&m_sh2_state->gbr)); // add r0, R0, gbr - SETEA(0); - UML_CALLH(block, *m_write8); // write8 - return true; - } - - return false; -} - -/*************************************************************************** - CORE CALLBACKS -***************************************************************************/ - -/*------------------------------------------------- - sh2drc_set_options - configure DRC options --------------------------------------------------*/ - -void sh2_device::sh2drc_set_options(uint32_t options) -{ - if (!allow_drc()) return; - m_drcoptions = options; -} - - -/*------------------------------------------------- - sh2drc_add_pcflush - add a new address where - the PC must be flushed for speedups to work --------------------------------------------------*/ - -void sh2_device::sh2drc_add_pcflush(offs_t address) -{ - if (!allow_drc()) return; - - if (m_pcfsel < ARRAY_LENGTH(m_pcflushes)) - m_pcflushes[m_pcfsel++] = address; -} - - -/*------------------------------------------------- - sh2drc_add_fastram - add a new fastram - region --------------------------------------------------*/ - -void sh2_device::sh2drc_add_fastram(offs_t start, offs_t end, uint8_t readonly, void *base) -{ - if (m_fastram_select < ARRAY_LENGTH(m_fastram)) - { - m_fastram[m_fastram_select].start = start; - m_fastram[m_fastram_select].end = end; - m_fastram[m_fastram_select].readonly = readonly; - m_fastram[m_fastram_select].base = base; - m_fastram_select++; - } -} diff --git a/src/devices/cpu/sh/sh2fe.cpp b/src/devices/cpu/sh/sh2fe.cpp index f6b409a0cd5..3019dc02ab7 100644 --- a/src/devices/cpu/sh/sh2fe.cpp +++ b/src/devices/cpu/sh/sh2fe.cpp @@ -18,745 +18,14 @@ INSTRUCTION PARSERS ***************************************************************************/ -sh2_frontend::sh2_frontend(sh2_device *device, uint32_t window_start, uint32_t window_end, uint32_t max_sequence) - : drc_frontend(*device, window_start, window_end, max_sequence) - , m_sh2(device) +sh2_frontend::sh2_frontend(sh_common_execution *device, uint32_t window_start, uint32_t window_end, uint32_t max_sequence) + : sh_frontend(device, window_start, window_end, max_sequence) { } -/*------------------------------------------------- - describe_instruction - build a description - of a single instruction --------------------------------------------------*/ -bool sh2_frontend::describe(opcode_desc &desc, const opcode_desc *prev) -{ - uint16_t opcode; - - /* fetch the opcode */ - opcode = desc.opptr.w[0] = m_sh2->m_direct->read_word(desc.physpc, SH2_CODE_XOR(0)); - - /* all instructions are 2 bytes and most are a single cycle */ - desc.length = 2; - desc.cycles = 1; - - switch (opcode>>12) - { - case 0: - return describe_group_0(desc, prev, opcode); - - case 1: // MOVLS4 - desc.regin[0] |= REGFLAG_R(Rn) | REGFLAG_R(Rm); - desc.flags |= OPFLAG_WRITES_MEMORY; - return true; - - case 2: - return describe_group_2(desc, prev, opcode); - - case 3: - return describe_group_3(desc, prev, opcode); - - case 4: - return describe_group_4(desc, prev, opcode); - - case 5: // MOVLL4 - desc.regin[0] |= REGFLAG_R(Rm); - desc.regout[0] |= REGFLAG_R(Rn); - desc.flags |= OPFLAG_READS_MEMORY; - return true; - - case 6: - return describe_group_6(desc, prev, opcode); - - case 7: // ADDI - desc.regin[0] |= REGFLAG_R(Rn); - desc.regout[0] |= REGFLAG_R(Rn); - return true; - - case 8: - return describe_group_8(desc, prev, opcode); - - case 9: // MOVWI - desc.regout[0] |= REGFLAG_R(Rn); - desc.flags |= OPFLAG_READS_MEMORY; - return true; - - case 11: // BSR - desc.regout[1] |= REGFLAG_PR; - // (intentional fallthrough - BSR is BRA with the addition of PR = the return address) - case 10: // BRA - { - int32_t disp = ((int32_t)opcode << 20) >> 20; - - desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; - desc.targetpc = (desc.pc + 2) + disp * 2 + 2; - desc.delayslots = 1; - desc.cycles = 2; - return true; - } - - case 12: - return describe_group_12(desc, prev, opcode); - - case 13: // MOVLI - desc.regout[0] |= REGFLAG_R(Rn); - desc.flags |= OPFLAG_READS_MEMORY; - return true; - - case 14: // MOVI - desc.regout[0] |= REGFLAG_R(Rn); - return true; - - case 15: // NOP - return true; - } - - return false; -} - -bool sh2_frontend::describe_group_0(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) -{ - switch (opcode & 0x3F) - { - case 0x00: // NOP(); - case 0x01: // NOP(); - case 0x09: // NOP(); - case 0x10: // NOP(); - case 0x11: // NOP(); - case 0x13: // NOP(); - case 0x20: // NOP(); - case 0x21: // NOP(); - case 0x30: // NOP(); - case 0x31: // NOP(); - case 0x32: // NOP(); - case 0x33: // NOP(); - case 0x38: // NOP(); - case 0x39: // NOP(); - case 0x3a: // NOP(); - case 0x3b: // NOP(); - return true; - - case 0x02: // STCSR(Rn); - desc.regout[0] |= REGFLAG_R(Rn); - return true; - - case 0x03: // BSRF(Rn); - desc.regout[1] |= REGFLAG_PR; - - desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; - desc.targetpc = BRANCH_TARGET_DYNAMIC; - desc.delayslots = 1; - - return true; - - case 0x04: // MOVBS0(Rm, Rn); - case 0x05: // MOVWS0(Rm, Rn); - case 0x06: // MOVLS0(Rm, Rn); - case 0x14: // MOVBS0(Rm, Rn); - case 0x15: // MOVWS0(Rm, Rn); - case 0x16: // MOVLS0(Rm, Rn); - case 0x24: // MOVBS0(Rm, Rn); - case 0x25: // MOVWS0(Rm, Rn); - case 0x26: // MOVLS0(Rm, Rn); - case 0x34: // MOVBS0(Rm, Rn); - case 0x35: // MOVWS0(Rm, Rn); - case 0x36: // MOVLS0(Rm, Rn); - desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn) | REGFLAG_R(0); - desc.flags |= OPFLAG_READS_MEMORY; - return true; - - case 0x07: // MULL(Rm, Rn); - case 0x17: // MULL(Rm, Rn); - case 0x27: // MULL(Rm, Rn); - case 0x37: // MULL(Rm, Rn); - desc.regin[0] |= REGFLAG_R(Rn) | REGFLAG_R(Rm); - desc.regout[1] |= REGFLAG_MACL; - desc.cycles = 2; - return true; - - case 0x08: // CLRT(); - desc.regout[1] |= REGFLAG_SR; - return true; - - case 0x0a: // STSMACH(Rn); - desc.regout[0] |= REGFLAG_R(Rn); - desc.regout[1] |= REGFLAG_MACH; - return true; - - case 0x0b: // RTS(); - desc.regin[1] |= REGFLAG_PR; - - desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; - desc.targetpc = BRANCH_TARGET_DYNAMIC; - desc.delayslots = 1; - desc.cycles = 2; - - return true; - - case 0x0c: // MOVBL0(Rm, Rn); - case 0x0d: // MOVWL0(Rm, Rn); - case 0x0e: // MOVLL0(Rm, Rn); - case 0x1c: // MOVBL0(Rm, Rn); - case 0x1d: // MOVWL0(Rm, Rn); - case 0x1e: // MOVLL0(Rm, Rn); - case 0x2c: // MOVBL0(Rm, Rn); - case 0x2d: // MOVWL0(Rm, Rn); - case 0x2e: // MOVLL0(Rm, Rn); - case 0x3c: // MOVBL0(Rm, Rn); - case 0x3d: // MOVWL0(Rm, Rn); - case 0x3e: // MOVLL0(Rm, Rn); - desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(0); - desc.regout[0] |= REGFLAG_R(Rn); - desc.flags |= OPFLAG_READS_MEMORY; - return true; - - case 0x0f: // MAC_L(Rm, Rn); - case 0x1f: // MAC_L(Rm, Rn); - case 0x2f: // MAC_L(Rm, Rn); - case 0x3f: // MAC_L(Rm, Rn); - desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn); - desc.regout[1] |= REGFLAG_MACL | REGFLAG_MACH; - desc.cycles = 3; - return true; - - case 0x12: // STCGBR(Rn); - desc.regout[0] |= REGFLAG_R(Rn); - desc.regin[1] |= REGFLAG_GBR; - return true; - - case 0x18: // SETT(); - desc.regout[1] |= REGFLAG_SR; - return true; - - case 0x19: // DIV0U(); - desc.regout[1] |= REGFLAG_SR; - return true; - - case 0x1a: // STSMACL(Rn); - desc.regin[1] |= REGFLAG_MACL; - desc.regout[0] |= REGFLAG_R(Rn); - return true; - - case 0x1b: // SLEEP(); - desc.cycles = 3; - return true; - - case 0x22: // STCVBR(Rn); - desc.regin[0] |= REGFLAG_R(Rn); - desc.regout[1] |= REGFLAG_VBR; - return true; - - case 0x23: // BRAF(Rn); - desc.regin[0] |= REGFLAG_R(Rm); - desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; - desc.targetpc = BRANCH_TARGET_DYNAMIC; - desc.delayslots = 1; - desc.cycles = 2; - return true; - - case 0x28: // CLRMAC(); - desc.regout[1] |= REGFLAG_MACL | REGFLAG_MACH; - return true; - - case 0x29: // MOVT(Rn); - desc.regin[1] |= REGFLAG_SR; - desc.regout[0] |= REGFLAG_R(Rn); - return true; - - case 0x2a: // STSPR(Rn); - desc.regin[1] |= REGFLAG_PR; - desc.regout[0] |= REGFLAG_R(Rn); - return true; - - case 0x2b: // RTE(); - desc.regin[0] |= REGFLAG_R(15); - desc.regout[0] |= REGFLAG_R(15); - - desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE | OPFLAG_CAN_EXPOSE_EXTERNAL_INT; - desc.targetpc = BRANCH_TARGET_DYNAMIC; - desc.delayslots = 1; - desc.cycles = 4; - - return true; - } - - return false; -} - -bool sh2_frontend::describe_group_2(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) -{ - switch (opcode & 15) - { - case 0: // MOVBS(Rm, Rn); - case 1: // MOVWS(Rm, Rn); - case 2: // MOVLS(Rm, Rn); - desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn); - desc.flags |= OPFLAG_WRITES_MEMORY; - return true; - - case 3: // NOP(); - return true; - - case 4: // MOVBM(Rm, Rn); - case 5: // MOVWM(Rm, Rn); - case 6: // MOVLM(Rm, Rn); - case 13: // XTRCT(Rm, Rn); - desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn); - desc.regout[0] |= REGFLAG_R(Rn); - desc.flags |= OPFLAG_WRITES_MEMORY; - return true; - - case 7: // DIV0S(Rm, Rn); - case 8: // TST(Rm, Rn); - case 12: // CMPSTR(Rm, Rn); - desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn); - desc.regout[1] |= REGFLAG_SR; - return true; - - case 9: // AND(Rm, Rn); - case 10: // XOR(Rm, Rn); - case 11: // OR(Rm, Rn); - desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn); - desc.regout[0] |= REGFLAG_R(Rn); - return true; - - case 14: // MULU(Rm, Rn); - case 15: // MULS(Rm, Rn); - desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn); - desc.regout[1] |= REGFLAG_MACL | REGFLAG_MACH; - desc.cycles = 2; - return true; - } - - return false; -} - -bool sh2_frontend::describe_group_3(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) -{ - switch (opcode & 15) - { - case 0: // CMPEQ(Rm, Rn); - case 2: // CMPHS(Rm, Rn); - case 3: // CMPGE(Rm, Rn); - case 6: // CMPHI(Rm, Rn); - case 7: // CMPGT(Rm, Rn); - desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn); - desc.regout[1] |= REGFLAG_SR; - return true; - - case 1: // NOP(); - case 9: // NOP(); - return true; - - case 4: // DIV1(Rm, Rn); - desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn); - desc.regout[0] |= REGFLAG_R(Rn); - desc.regout[1] |= REGFLAG_SR; - return true; - - case 5: // DMULU(Rm, Rn); - case 13: // DMULS(Rm, Rn); - desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn); - desc.regout[1] |= REGFLAG_MACL | REGFLAG_MACH; - desc.cycles = 2; - return true; - case 8: // SUB(Rm, Rn); - case 12: // ADD(Rm, Rn); - desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn); - desc.regout[0] |= REGFLAG_R(Rn); - return true; - - case 10: // SUBC(Rm, Rn); - case 11: // SUBV(Rm, Rn); - case 14: // ADDC(Rm, Rn); - case 15: // ADDV(Rm, Rn); - desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn); - desc.regin[1] |= REGFLAG_SR; - desc.regout[0] |= REGFLAG_R(Rn); - desc.regout[1] |= REGFLAG_SR; - return true; - } - return false; -} - -bool sh2_frontend::describe_group_4(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) +bool sh2_frontend::describe_group_15(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) { - switch (opcode & 0x3F) - { - case 0x00: // SHLL(Rn); - case 0x01: // SHLR(Rn); - case 0x04: // ROTL(Rn); - case 0x05: // ROTR(Rn); - desc.regin[0] |= REGFLAG_R(Rn); - desc.regout[0] |= REGFLAG_R(Rn); - desc.regout[1] |= REGFLAG_SR; - return true; - - case 0x02: // STSMMACH(Rn); - desc.regin[0] |= REGFLAG_R(Rn); - desc.regin[1] |= REGFLAG_MACH; - desc.regout[0] |= REGFLAG_R(Rn); - desc.flags |= OPFLAG_WRITES_MEMORY; - return true; - - case 0x03: // STCMSR(Rn); - desc.regin[0] |= REGFLAG_R(Rn); - desc.regout[0] |= REGFLAG_R(Rn); - desc.cycles = 2; - desc.flags |= OPFLAG_WRITES_MEMORY; - return true; - - case 0x06: // LDSMMACH(Rn); - desc.regin[0] |= REGFLAG_R(Rn); - desc.regout[0] |= REGFLAG_R(Rn); - desc.regout[1] |= REGFLAG_MACH; - desc.flags |= OPFLAG_READS_MEMORY; - return true; - - case 0x07: // LDCMSR(Rn); - desc.regin[0] |= REGFLAG_R(Rn); - desc.regout[0] |= REGFLAG_R(Rn); - desc.regout[1] |= REGFLAG_SR; - desc.cycles = 3; - desc.flags |= OPFLAG_READS_MEMORY | OPFLAG_CAN_EXPOSE_EXTERNAL_INT | OPFLAG_END_SEQUENCE; - return true; - - case 0x08: // SHLL2(Rn); - case 0x09: // SHLR2(Rn); - case 0x18: // SHLL8(Rn); - case 0x19: // SHLR8(Rn); - case 0x28: // SHLL16(Rn); - case 0x29: // SHLR16(Rn); - desc.regin[0] |= REGFLAG_R(Rn); - desc.regout[0] |= REGFLAG_R(Rn); - return true; - - case 0x0a: // LDSMACH(Rn); - desc.regin[0] |= REGFLAG_R(Rn); - desc.regout[1] |= REGFLAG_MACH; - return true; - - case 0x0b: // JSR(Rn); - desc.regin[0] |= REGFLAG_R(Rn); - desc.regout[1] |= REGFLAG_PR; - desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; - desc.targetpc = BRANCH_TARGET_DYNAMIC; - desc.delayslots = 1; - return true; - - case 0x0e: // LDCSR(Rn); - desc.regin[0] |= REGFLAG_R(Rn); - desc.regout[1] |= REGFLAG_SR; - desc.flags |= OPFLAG_CAN_EXPOSE_EXTERNAL_INT | OPFLAG_END_SEQUENCE; - return true; - - case 0x0f: // MAC_W(Rm, Rn); - case 0x1f: // MAC_W(Rm, Rn); - case 0x2f: // MAC_W(Rm, Rn); - case 0x3f: // MAC_W(Rm, Rn); - desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn); - desc.regin[1] |= REGFLAG_MACL | REGFLAG_MACH; - desc.regout[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn); - desc.regout[1] |= REGFLAG_MACL | REGFLAG_MACH; - desc.cycles = 3; - return true; - - case 0x10: // DT(Rn); - desc.regin[0] |= REGFLAG_R(Rn); - desc.regin[1] |= REGFLAG_SR; - desc.regout[0] |= REGFLAG_R(Rn); - desc.regout[1] |= REGFLAG_SR; - return true; - - case 0x11: // CMPPZ(Rn); - case 0x15: // CMPPL(Rn); - desc.regin[0] |= REGFLAG_R(Rn); - desc.regin[1] |= REGFLAG_SR; - desc.regout[1] |= REGFLAG_SR; - return true; - - case 0x12: // STSMMACL(Rn); - desc.regin[0] |= REGFLAG_R(Rn); - desc.regin[1] |= REGFLAG_MACL; - desc.regout[0] |= REGFLAG_R(Rn); - desc.flags |= OPFLAG_WRITES_MEMORY; - return true; - - case 0x13: // STCMGBR(Rn); - desc.regin[0] |= REGFLAG_R(Rn); - desc.regin[1] |= REGFLAG_GBR; - desc.regout[0] |= REGFLAG_R(Rn); - desc.flags |= OPFLAG_WRITES_MEMORY; - return true; - - case 0x16: // LDSMMACL(Rn); - desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn); - desc.regout[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn); - desc.regout[1] |= REGFLAG_MACL; - desc.flags |= OPFLAG_READS_MEMORY; - return true; - - case 0x17: // LDCMGBR(Rn); - desc.regin[0] |= REGFLAG_R(Rn); - desc.regout[0] |= REGFLAG_R(Rn); - desc.regout[1] |= REGFLAG_GBR; - desc.flags |= OPFLAG_READS_MEMORY; - return true; - - case 0x1a: // LDSMACL(Rn); - desc.regin[0] |= REGFLAG_R(Rn); - desc.regout[1] |= REGFLAG_MACL; - return true; - - case 0x1b: // TAS(Rn); - desc.regin[0] |= REGFLAG_R(Rn); - desc.regin[1] |= REGFLAG_SR; - desc.regout[1] |= REGFLAG_SR; - desc.cycles = 4; - desc.flags |= OPFLAG_READS_MEMORY | OPFLAG_WRITES_MEMORY; - return true; - - case 0x1e: // LDCGBR(Rn); - desc.regin[0] |= REGFLAG_R(Rn); - desc.regout[1] |= REGFLAG_GBR; - return true; - - case 0x20: // SHAL(Rn); - case 0x21: // SHAR(Rn); - desc.regin[0] |= REGFLAG_R(Rn); - desc.regout[0] |= REGFLAG_R(Rn); - desc.regout[1] |= REGFLAG_SR; - return true; - - case 0x22: // STSMPR(Rn); - desc.regin[0] |= REGFLAG_R(Rn); - desc.regin[1] |= REGFLAG_PR; - desc.regout[0] |= REGFLAG_R(Rn); - desc.flags |= OPFLAG_WRITES_MEMORY; - return true; - - case 0x23: // STCMVBR(Rn); - desc.regin[0] |= REGFLAG_R(Rn); - desc.regin[1] |= REGFLAG_VBR; - desc.regout[0] |= REGFLAG_R(Rn); - desc.flags |= OPFLAG_WRITES_MEMORY; - return true; - - case 0x24: // ROTCL(Rn); - case 0x25: // ROTCR(Rn); - desc.regin[0] |= REGFLAG_R(Rn); - desc.regin[1] |= REGFLAG_SR; - desc.regout[0] |= REGFLAG_R(Rn); - desc.regout[1] |= REGFLAG_SR; - return true; - - case 0x26: // LDSMPR(Rn); - desc.regin[0] |= REGFLAG_R(Rn); - desc.regout[0] |= REGFLAG_R(Rn); - desc.regout[1] |= REGFLAG_PR; - desc.flags |= OPFLAG_READS_MEMORY; - return true; - - case 0x27: // LDCMVBR(Rn); - desc.regin[0] |= REGFLAG_R(Rn); - desc.regout[0] |= REGFLAG_R(Rn); - desc.regout[1] |= REGFLAG_VBR; - desc.flags |= OPFLAG_READS_MEMORY; - return true; - - case 0x2a: // LDSPR(Rn); - desc.regin[0] |= REGFLAG_R(Rn); - desc.regout[1] |= REGFLAG_PR; - return true; - - case 0x2b: // JMP(Rm); - desc.regin[0] |= REGFLAG_R(Rm); - desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; - desc.targetpc = BRANCH_TARGET_DYNAMIC; - desc.delayslots = 1; - return true; - - case 0x2e: // LDCVBR(Rn); - desc.regin[0] |= REGFLAG_R(Rn); - desc.regout[1] |= REGFLAG_VBR; - return true; - - case 0x0c: // NOP(); - case 0x0d: // NOP(); - case 0x14: // NOP(); - case 0x1c: // NOP(); - case 0x1d: // NOP(); - case 0x2c: // NOP(); - case 0x2d: // NOP(); - case 0x30: // NOP(); - case 0x31: // NOP(); - case 0x32: // NOP(); - case 0x33: // NOP(); - case 0x34: // NOP(); - case 0x35: // NOP(); - case 0x36: // NOP(); - case 0x37: // NOP(); - case 0x38: // NOP(); - case 0x39: // NOP(); - case 0x3a: // NOP(); - case 0x3b: // NOP(); - case 0x3c: // NOP(); - case 0x3d: // NOP(); - case 0x3e: // NOP(); - return true; - } - - return false; -} - -bool sh2_frontend::describe_group_6(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) -{ - switch (opcode & 15) - { - case 0: // MOVBL(Rm, Rn); - case 1: // MOVWL(Rm, Rn); - case 2: // MOVLL(Rm, Rn); - case 3: // MOV(Rm, Rn); - case 7: // NOT(Rm, Rn); - case 9: // SWAPW(Rm, Rn); - case 11: // NEG(Rm, Rn); - case 12: // EXTUB(Rm, Rn); - case 13: // EXTUW(Rm, Rn); - case 14: // EXTSB(Rm, Rn); - case 15: // EXTSW(Rm, Rn); - desc.regin[0] |= REGFLAG_R(Rm); - desc.regout[0] |= REGFLAG_R(Rn); - return true; - - case 4: // MOVBP(Rm, Rn); - case 5: // MOVWP(Rm, Rn); - case 6: // MOVLP(Rm, Rn); - desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn); - desc.regout[0] |= REGFLAG_R(Rn); - desc.flags |= OPFLAG_READS_MEMORY; - return true; - - case 8: // SWAPB(Rm, Rn); - desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn); - desc.regout[0] |= REGFLAG_R(Rn); - return true; - - case 10: // NEGC(Rm, Rn); - desc.regin[0] |= REGFLAG_R(Rm); - desc.regout[0] |= REGFLAG_R(Rn); - desc.regout[1] |= REGFLAG_SR; - return true; - } - return false; -} - -bool sh2_frontend::describe_group_8(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) -{ - int32_t disp; - - switch ( opcode & (15<<8) ) - { - case 0 << 8: // MOVBS4(opcode & 0x0f, Rm); - case 1 << 8: // MOVWS4(opcode & 0x0f, Rm); - desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(0); - desc.flags |= OPFLAG_WRITES_MEMORY; - return true; - - case 2<< 8: // NOP(); - case 3<< 8: // NOP(); - case 6<< 8: // NOP(); - case 7<< 8: // NOP(); - case 10<< 8: // NOP(); - case 12<< 8: // NOP(); - case 14<< 8: // NOP(); - return true; - - case 4<< 8: // MOVBL4(Rm, opcode & 0x0f); - case 5<< 8: // MOVWL4(Rm, opcode & 0x0f); - desc.regin[0] |= REGFLAG_R(Rm); - desc.regout[0] |= REGFLAG_R(0); - desc.flags |= OPFLAG_READS_MEMORY; - return true; - - case 8<< 8: // CMPIM(opcode & 0xff); - desc.regin[0] |= REGFLAG_R(Rm); - desc.regin[1] |= REGFLAG_SR; - desc.regout[1] |= REGFLAG_SR; - return true; - - case 9<< 8: // BT(opcode & 0xff); - case 11<< 8: // BF(opcode & 0xff); - desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH; - desc.cycles = 3; - disp = ((int32_t)opcode << 24) >> 24; - desc.targetpc = (desc.pc + 2) + disp * 2 + 2; - return true; - - case 13<< 8: // BTS(opcode & 0xff); - case 15<< 8: // BFS(opcode & 0xff); - desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH; - desc.cycles = 2; - disp = ((int32_t)opcode << 24) >> 24; - desc.targetpc = (desc.pc + 2) + disp * 2 + 2; - desc.delayslots = 1; - return true; - } - - return false; -} - -bool sh2_frontend::describe_group_12(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) -{ - switch (opcode & (15<<8)) - { - case 0<<8: // MOVBSG(opcode & 0xff); - case 1<<8: // MOVWSG(opcode & 0xff); - case 2<<8: // MOVLSG(opcode & 0xff); - desc.regin[0] |= REGFLAG_R(0); - desc.flags |= OPFLAG_WRITES_MEMORY; - return true; - - case 3<<8: // TRAPA(opcode & 0xff); - desc.regin[0] |= REGFLAG_R(15); - desc.regin[1] |= REGFLAG_VBR; - desc.regout[0] |= REGFLAG_R(15); - desc.cycles = 8; - desc.targetpc = BRANCH_TARGET_DYNAMIC; - desc.flags |= OPFLAG_READS_MEMORY | OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; - return true; - - case 4<<8: // MOVBLG(opcode & 0xff); - case 5<<8: // MOVWLG(opcode & 0xff); - case 6<<8: // MOVLLG(opcode & 0xff); - case 7<<8: // MOVA(opcode & 0xff); - desc.regout[0] |= REGFLAG_R(0); - desc.flags |= OPFLAG_READS_MEMORY; - return true; - - case 8<<8: // TSTI(opcode & 0xff); - desc.regin[0] |= REGFLAG_R(0); - desc.regin[1] |= REGFLAG_SR; - desc.regout[1] |= REGFLAG_SR; - return true; - - case 9<<8: // ANDI(opcode & 0xff); - case 10<<8: // XORI(opcode & 0xff); - case 11<<8: // ORI(opcode & 0xff); - desc.regin[0] |= REGFLAG_R(0); - desc.regout[0] |= REGFLAG_R(0); - return true; - - case 12<<8: // TSTM(opcode & 0xff); - case 13<<8: // ANDM(opcode & 0xff); - case 14<<8: // XORM(opcode & 0xff); - case 15<<8: // ORM(opcode & 0xff); - desc.regin[0] |= REGFLAG_R(0); - desc.regin[1] |= REGFLAG_SR | REGFLAG_GBR; - desc.regout[1] |= REGFLAG_SR; - desc.flags |= OPFLAG_READS_MEMORY; - return true; - } - - return false; + return true; } diff --git a/src/devices/cpu/sh/sh3comn.cpp b/src/devices/cpu/sh/sh3comn.cpp index 4a50e748eb9..6871a1aef01 100644 --- a/src/devices/cpu/sh/sh3comn.cpp +++ b/src/devices/cpu/sh/sh3comn.cpp @@ -21,23 +21,23 @@ WRITE32_MEMBER( sh3_base_device::sh3_internal_high_w ) case SH3_ICR0_IPRA_ADDR: if (mem_mask & 0xffff0000) { - logerror("'%s' (%08x): INTC internal write to %08x = %08x & %08x (SH3_ICR0_IPRA_ADDR - ICR0)\n",tag(), m_pc & AM,(offset *4)+SH3_UPPER_REGBASE,data,mem_mask); + logerror("'%s' (%08x): INTC internal write to %08x = %08x & %08x (SH3_ICR0_IPRA_ADDR - ICR0)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+SH3_UPPER_REGBASE,data,mem_mask); } if (mem_mask & 0x0000ffff) { - logerror("'%s' (%08x): INTC internal write to %08x = %08x & %08x (SH3_ICR0_IPRA_ADDR - IPRA)\n",tag(), m_pc & AM,(offset *4)+SH3_UPPER_REGBASE,data,mem_mask); + logerror("'%s' (%08x): INTC internal write to %08x = %08x & %08x (SH3_ICR0_IPRA_ADDR - IPRA)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+SH3_UPPER_REGBASE,data,mem_mask); sh4_handler_ipra_w(data&0xffff,mem_mask&0xffff); } break; case SH3_IPRB_ADDR: - logerror("'%s' (%08x): INTC internal write to %08x = %08x & %08x (SH3_IPRB_ADDR)\n",tag(), m_pc & AM,(offset *4)+SH3_UPPER_REGBASE,data,mem_mask); + logerror("'%s' (%08x): INTC internal write to %08x = %08x & %08x (SH3_IPRB_ADDR)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+SH3_UPPER_REGBASE,data,mem_mask); break; case SH3_TOCR_TSTR_ADDR: - logerror("'%s' (%08x): TMU internal write to %08x = %08x & %08x (SH3_TOCR_TSTR_ADDR)\n",tag(), m_pc & AM,(offset *4)+SH3_UPPER_REGBASE,data,mem_mask); + logerror("'%s' (%08x): TMU internal write to %08x = %08x & %08x (SH3_TOCR_TSTR_ADDR)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+SH3_UPPER_REGBASE,data,mem_mask); if (mem_mask&0xff000000) { sh4_handle_tocr_addr_w((data>>24)&0xffff, (mem_mask>>24)&0xff); @@ -63,7 +63,7 @@ WRITE32_MEMBER( sh3_base_device::sh3_internal_high_w ) case SH3_TCPR2_ADDR: sh4_handle_tcpr2_addr_w(data, mem_mask);break; default: - logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (unk)\n",tag(), m_pc & AM,(offset *4)+SH3_UPPER_REGBASE,data,mem_mask); + logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (unk)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+SH3_UPPER_REGBASE,data,mem_mask); break; } @@ -80,11 +80,11 @@ READ32_MEMBER( sh3_base_device::sh3_internal_high_r ) switch (offset) { case SH3_ICR0_IPRA_ADDR: - logerror("'%s' (%08x): INTC internal read from %08x mask %08x (SH3_ICR0_IPRA_ADDR - %08x)\n",tag(), m_pc & AM,(offset *4)+SH3_UPPER_REGBASE,mem_mask, m_sh3internal_upper[offset]); + logerror("'%s' (%08x): INTC internal read from %08x mask %08x (SH3_ICR0_IPRA_ADDR - %08x)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+SH3_UPPER_REGBASE,mem_mask, m_sh3internal_upper[offset]); return (m_sh3internal_upper[offset] & 0xffff0000) | (m_SH4_IPRA & 0xffff); case SH3_IPRB_ADDR: - logerror("'%s' (%08x): INTC internal read from %08x mask %08x (SH3_IPRB_ADDR - %08x)\n",tag(), m_pc & AM,(offset *4)+SH3_UPPER_REGBASE,mem_mask, m_sh3internal_upper[offset]); + logerror("'%s' (%08x): INTC internal read from %08x mask %08x (SH3_IPRB_ADDR - %08x)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+SH3_UPPER_REGBASE,mem_mask, m_sh3internal_upper[offset]); return m_sh3internal_upper[offset]; case SH3_TOCR_TSTR_ADDR: @@ -115,22 +115,22 @@ READ32_MEMBER( sh3_base_device::sh3_internal_high_r ) case SH3_TRA_ADDR: - logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (SH3 TRA - %08x)\n",tag(), m_pc & AM,(offset *4)+SH3_UPPER_REGBASE,mem_mask, m_sh3internal_upper[offset]); + logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (SH3 TRA - %08x)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+SH3_UPPER_REGBASE,mem_mask, m_sh3internal_upper[offset]); return m_sh3internal_upper[offset]; case SH3_EXPEVT_ADDR: - logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (SH3 EXPEVT - %08x)\n",tag(), m_pc & AM,(offset *4)+SH3_UPPER_REGBASE,mem_mask, m_sh3internal_upper[offset]); + logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (SH3 EXPEVT - %08x)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+SH3_UPPER_REGBASE,mem_mask, m_sh3internal_upper[offset]); return m_sh3internal_upper[offset]; case SH3_INTEVT_ADDR: - logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (SH3 INTEVT - %08x)\n",tag(), m_pc & AM,(offset *4)+SH3_UPPER_REGBASE,mem_mask, m_sh3internal_upper[offset]); + logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (SH3 INTEVT - %08x)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+SH3_UPPER_REGBASE,mem_mask, m_sh3internal_upper[offset]); fatalerror("INTEVT unsupported on SH3\n"); // never executed //return m_sh3internal_upper[offset]; default: - logerror("'%s' (%08x): unmapped internal read from %08x mask %08x\n",tag(), m_pc & AM,(offset *4)+SH3_UPPER_REGBASE,mem_mask); + logerror("'%s' (%08x): unmapped internal read from %08x mask %08x\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+SH3_UPPER_REGBASE,mem_mask); return m_sh3internal_upper[offset]; } } @@ -163,7 +163,7 @@ READ32_MEMBER( sh3_base_device::sh3_internal_r ) case INTEVT2: { - // logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (INTEVT2)\n",tag(), m_pc & AM,(offset *4)+0x4000000,mem_mask); + // logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (INTEVT2)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,mem_mask); return m_sh3internal_lower[offset]; } @@ -173,17 +173,17 @@ READ32_MEMBER( sh3_base_device::sh3_internal_r ) { if (mem_mask & 0xff000000) { - logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (IRR0)\n",tag(), m_pc & AM,(offset *4)+0x4000000,mem_mask); + logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (IRR0)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,mem_mask); return m_sh3internal_lower[offset]; } if (mem_mask & 0x0000ff00) { - logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (IRR1)\n",tag(), m_pc & AM,(offset *4)+0x4000000,mem_mask); + logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (IRR1)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,mem_mask); return m_sh3internal_lower[offset]; } - fatalerror("'%s' (%08x): unmapped internal read from %08x mask %08x (IRR0/1 unused bits)\n",tag(), m_pc & AM,(offset *4)+0x4000000,mem_mask); + fatalerror("'%s' (%08x): unmapped internal read from %08x mask %08x (IRR0/1 unused bits)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,mem_mask); } } @@ -191,13 +191,13 @@ READ32_MEMBER( sh3_base_device::sh3_internal_r ) { if (mem_mask & 0xffff0000) { - //logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (PADR)\n",tag(), m_pc & AM,(offset *4)+0x4000000,mem_mask); + //logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (PADR)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,mem_mask); return m_io->read_qword(SH3_PORT_A)<<24; } if (mem_mask & 0x0000ffff) { - //logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (PBDR)\n",tag(), m_pc & AM,(offset *4)+0x4000000,mem_mask); + //logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (PBDR)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,mem_mask); return m_io->read_qword(SH3_PORT_B)<<8; } } @@ -207,13 +207,13 @@ READ32_MEMBER( sh3_base_device::sh3_internal_r ) { if (mem_mask & 0xffff0000) { - //logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (PCDR)\n",tag(), m_pc & AM,(offset *4)+0x4000000,mem_mask); + //logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (PCDR)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,mem_mask); return m_io->read_qword(SH3_PORT_C)<<24; } if (mem_mask & 0x0000ffff) { - //logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (PDDR)\n",tag(), m_pc & AM,(offset *4)+0x4000000,mem_mask); + //logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (PDDR)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,mem_mask); return m_io->read_qword(SH3_PORT_D)<<8; } } @@ -223,13 +223,13 @@ READ32_MEMBER( sh3_base_device::sh3_internal_r ) { if (mem_mask & 0xffff0000) { - //logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (PEDR)\n",tag(), m_pc & AM,(offset *4)+0x4000000,mem_mask); + //logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (PEDR)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,mem_mask); return m_io->read_qword(SH3_PORT_E)<<24; } if (mem_mask & 0x0000ffff) { - //logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (PFDR)\n",tag(), m_pc & AM,(offset *4)+0x4000000,mem_mask); + //logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (PFDR)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,mem_mask); return m_io->read_qword(SH3_PORT_F)<<8; } } @@ -239,13 +239,13 @@ READ32_MEMBER( sh3_base_device::sh3_internal_r ) { if (mem_mask & 0xffff0000) { - //logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (PGDR)\n",tag(), m_pc & AM,(offset *4)+0x4000000,mem_mask); + //logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (PGDR)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,mem_mask); return m_io->read_qword(SH3_PORT_G)<<24; } if (mem_mask & 0x0000ffff) { - //logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (PHDR)\n",tag(), m_pc & AM,(offset *4)+0x4000000,mem_mask); + //logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (PHDR)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,mem_mask); return m_io->read_qword(SH3_PORT_H)<<8; } } @@ -255,13 +255,13 @@ READ32_MEMBER( sh3_base_device::sh3_internal_r ) { if (mem_mask & 0xffff0000) { - //logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (PJDR)\n",tag(), m_pc & AM,(offset *4)+0x4000000,mem_mask); + //logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (PJDR)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,mem_mask); return m_io->read_qword(SH3_PORT_J)<<24; } if (mem_mask & 0x0000ffff) { - //logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (PKDR)\n",tag(), m_pc & AM,(offset *4)+0x4000000,mem_mask); + //logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (PKDR)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,mem_mask); return m_io->read_qword(SH3_PORT_K)<<8; } } @@ -271,13 +271,13 @@ READ32_MEMBER( sh3_base_device::sh3_internal_r ) { if (mem_mask & 0xffff0000) { - //logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (PLDR)\n",tag(), m_pc & AM,(offset *4)+0x4000000,mem_mask); + //logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (PLDR)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,mem_mask); return m_io->read_qword(SH3_PORT_L)<<24; } if (mem_mask & 0x0000ffff) { - logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (SCPDR)\n",tag(), m_pc & AM,(offset *4)+0x4000000,mem_mask); + logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (SCPDR)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,mem_mask); //return m_io->read_qword(SH3_PORT_K)<<8; } } @@ -288,13 +288,13 @@ READ32_MEMBER( sh3_base_device::sh3_internal_r ) { if (mem_mask & 0xff000000) { - logerror("'%s' (%08x): SCIF internal read from %08x mask %08x (SCSMR2 - Serial Mode Register 2)\n",tag(), m_pc & AM,(offset *4)+0x4000000,mem_mask); + logerror("'%s' (%08x): SCIF internal read from %08x mask %08x (SCSMR2 - Serial Mode Register 2)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,mem_mask); return m_sh3internal_lower[offset]; } if (mem_mask & 0x0000ff00) { - logerror("'%s' (%08x): SCIF internal read from %08x mask %08x (SCBRR2 - Bit Rate Register 2)\n",tag(), m_pc & AM,(offset *4)+0x4000000,mem_mask); + logerror("'%s' (%08x): SCIF internal read from %08x mask %08x (SCBRR2 - Bit Rate Register 2)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,mem_mask); return m_sh3internal_lower[offset]; } } @@ -304,13 +304,13 @@ READ32_MEMBER( sh3_base_device::sh3_internal_r ) { if (mem_mask & 0xff000000) { - logerror("'%s' (%08x): SCIF internal read from %08x mask %08x (SCSCR2 - Serial Control Register 2)\n",tag(), m_pc & AM,(offset *4)+0x4000000,mem_mask); + logerror("'%s' (%08x): SCIF internal read from %08x mask %08x (SCSCR2 - Serial Control Register 2)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,mem_mask); return m_sh3internal_lower[offset]; } if (mem_mask & 0x0000ff00) { - logerror("'%s' (%08x): SCIF internal read from %08x mask %08x (SCFTDR2 - Transmit FIFO Data Register 2)\n",tag(), m_pc & AM,(offset *4)+0x4000000,mem_mask); + logerror("'%s' (%08x): SCIF internal read from %08x mask %08x (SCFTDR2 - Transmit FIFO Data Register 2)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,mem_mask); return m_sh3internal_lower[offset]; } } @@ -320,13 +320,13 @@ READ32_MEMBER( sh3_base_device::sh3_internal_r ) { if (mem_mask & 0xffff0000) { - logerror("'%s' (%08x): SCIF internal read from %08x mask %08x (SCSSR2 - Serial Status Register 2)\n",tag(), m_pc & AM,(offset *4)+0x4000000,mem_mask); + logerror("'%s' (%08x): SCIF internal read from %08x mask %08x (SCSSR2 - Serial Status Register 2)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,mem_mask); return m_sh3internal_lower[offset]; } if (mem_mask & 0x0000ff00) { - logerror("'%s' (%08x): SCIF internal read from %08x mask %08x (SCFRDR2 - Receive FIFO Data Register 2)\n",tag(), m_pc & AM,(offset *4)+0x4000000,mem_mask); + logerror("'%s' (%08x): SCIF internal read from %08x mask %08x (SCFRDR2 - Receive FIFO Data Register 2)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,mem_mask); return m_sh3internal_lower[offset]; } } @@ -336,13 +336,13 @@ READ32_MEMBER( sh3_base_device::sh3_internal_r ) { if (mem_mask & 0xff000000) { - logerror("'%s' (%08x): SCIF internal read from %08x mask %08x (SCFCR2 - Fifo Control Register 2)\n",tag(), m_pc & AM,(offset *4)+0x4000000,mem_mask); + logerror("'%s' (%08x): SCIF internal read from %08x mask %08x (SCFCR2 - Fifo Control Register 2)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,mem_mask); return m_sh3internal_lower[offset]; } if (mem_mask & 0x0000ffff) { - logerror("'%s' (%08x): SCIF internal read from %08x mask %08x (SCFDR2 - Fifo Data Count Register 2)\n",tag(), m_pc & AM,(offset *4)+0x4000000,mem_mask); + logerror("'%s' (%08x): SCIF internal read from %08x mask %08x (SCFDR2 - Fifo Data Count Register 2)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,mem_mask); return m_sh3internal_lower[offset]; } } @@ -352,7 +352,7 @@ READ32_MEMBER( sh3_base_device::sh3_internal_r ) default: { logerror("'%s' (%08x): unmapped internal read from %08x mask %08x\n", - tag(), m_pc & AM, + tag(), m_sh2_state->pc & SH34_AM, (offset *4)+0x4000000, mem_mask); } @@ -364,7 +364,7 @@ READ32_MEMBER( sh3_base_device::sh3_internal_r ) else { logerror("'%s' (%08x): unmapped internal read from %08x mask %08x\n", - tag(), m_pc & AM, + tag(), m_sh2_state->pc & SH34_AM, (offset *4)+0x4000000, mem_mask); } @@ -407,7 +407,7 @@ WRITE32_MEMBER( sh3_base_device::sh3_internal_w ) { if (mem_mask & 0xff000000) { - logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (IRR0)\n",tag(), m_pc & AM,(offset *4)+0x4000000,data,mem_mask); + logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (IRR0)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,data,mem_mask); // not sure if this is how we should clear lines in this core... if (!(data & 0x01000000)) execute_set_input(0, CLEAR_LINE); if (!(data & 0x02000000)) execute_set_input(1, CLEAR_LINE); @@ -417,11 +417,11 @@ WRITE32_MEMBER( sh3_base_device::sh3_internal_w ) } if (mem_mask & 0x0000ff00) { - logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (IRR1)\n",tag(), m_pc & AM,(offset *4)+0x4000000,data,mem_mask); + logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (IRR1)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,data,mem_mask); } if (mem_mask & 0x00ff00ff) { - fatalerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (IRR0/1 unused bits)\n",tag(), m_pc & AM,(offset *4)+0x4000000,data,mem_mask); + fatalerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (IRR0/1 unused bits)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,data,mem_mask); } } } @@ -431,14 +431,14 @@ WRITE32_MEMBER( sh3_base_device::sh3_internal_w ) { if (mem_mask & 0xffff0000) { - logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PINTER)\n",tag(), m_pc & AM,(offset *4)+0x4000000,data,mem_mask); + logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PINTER)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,data,mem_mask); } if (mem_mask & 0x0000ffff) { data &= 0xffff; mem_mask &= 0xffff; COMBINE_DATA(&m_SH4_IPRC); - logerror("'%s' (%08x): INTC internal write to %08x = %08x & %08x (IPRC)\n",tag(), m_pc & AM,(offset *4)+0x4000000,data,mem_mask); + logerror("'%s' (%08x): INTC internal write to %08x = %08x & %08x (IPRC)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,data,mem_mask); m_exception_priority[SH4_INTC_IRL0] = INTPRI((m_SH4_IPRC & 0x000f)>>0, SH4_INTC_IRL0); m_exception_priority[SH4_INTC_IRL1] = INTPRI((m_SH4_IPRC & 0x00f0)>>4, SH4_INTC_IRL1); m_exception_priority[SH4_INTC_IRL2] = INTPRI((m_SH4_IPRC & 0x0f00)>>8, SH4_INTC_IRL2); @@ -452,12 +452,12 @@ WRITE32_MEMBER( sh3_base_device::sh3_internal_w ) { if (mem_mask & 0xffff0000) { - logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PCCR)\n",tag(), m_pc & AM,(offset *4)+0x4000000,data,mem_mask); + logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PCCR)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,data,mem_mask); } if (mem_mask & 0x0000ffff) { - logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PDCR)\n",tag(), m_pc & AM,(offset *4)+0x4000000,data,mem_mask); + logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PDCR)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,data,mem_mask); } } break; @@ -466,12 +466,12 @@ WRITE32_MEMBER( sh3_base_device::sh3_internal_w ) { if (mem_mask & 0xffff0000) { - logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PECR)\n",tag(), m_pc & AM,(offset *4)+0x4000000,data,mem_mask); + logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PECR)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,data,mem_mask); } if (mem_mask & 0x0000ffff) { - logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PFCR)\n",tag(), m_pc & AM,(offset *4)+0x4000000,data,mem_mask); + logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PFCR)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,data,mem_mask); } } break; @@ -481,12 +481,12 @@ WRITE32_MEMBER( sh3_base_device::sh3_internal_w ) { if (mem_mask & 0xffff0000) { - logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PGCR)\n",tag(), m_pc & AM,(offset *4)+0x4000000,data,mem_mask); + logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PGCR)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,data,mem_mask); } if (mem_mask & 0x0000ffff) { - logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PHCR)\n",tag(), m_pc & AM,(offset *4)+0x4000000,data,mem_mask); + logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PHCR)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,data,mem_mask); } } break; @@ -496,12 +496,12 @@ WRITE32_MEMBER( sh3_base_device::sh3_internal_w ) { if (mem_mask & 0xffff0000) { - logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PJCR)\n",tag(), m_pc & AM,(offset *4)+0x4000000,data,mem_mask); + logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PJCR)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,data,mem_mask); } if (mem_mask & 0x0000ffff) { - logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PKCR)\n",tag(), m_pc & AM,(offset *4)+0x4000000,data,mem_mask); + logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PKCR)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,data,mem_mask); } } break; @@ -511,12 +511,12 @@ WRITE32_MEMBER( sh3_base_device::sh3_internal_w ) { if (mem_mask & 0xffff0000) { - logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PLCR)\n",tag(), m_pc & AM,(offset *4)+0x4000000,data,mem_mask); + logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PLCR)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,data,mem_mask); } if (mem_mask & 0x0000ffff) { - logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (SCPCR)\n",tag(), m_pc & AM,(offset *4)+0x4000000,data,mem_mask); + logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (SCPCR)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,data,mem_mask); } } break; @@ -526,13 +526,13 @@ WRITE32_MEMBER( sh3_base_device::sh3_internal_w ) if (mem_mask & 0xffff0000) { m_io->write_qword(SH3_PORT_A, (data>>24)&0xff); - // logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PADR)\n",tag(), m_pc & AM,(offset *4)+0x4000000,data,mem_mask); + // logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PADR)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,data,mem_mask); } if (mem_mask & 0x0000ffff) { m_io->write_qword(SH3_PORT_B, (data>>8)&0xff); - // logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PBDR)\n",tag(), m_pc & AM,(offset *4)+0x4000000,data,mem_mask); + // logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PBDR)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,data,mem_mask); } } break; @@ -542,13 +542,13 @@ WRITE32_MEMBER( sh3_base_device::sh3_internal_w ) if (mem_mask & 0xffff0000) { m_io->write_qword(SH3_PORT_C, (data>>24)&0xff); - // logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PADR)\n",tag(), m_pc & AM,(offset *4)+0x4000000,data,mem_mask); + // logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PADR)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,data,mem_mask); } if (mem_mask & 0x0000ffff) { m_io->write_qword(SH3_PORT_D, (data>>8)&0xff); - // logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PBDR)\n",tag(), m_pc & AM,(offset *4)+0x4000000,data,mem_mask); + // logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PBDR)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,data,mem_mask); } } break; @@ -557,13 +557,13 @@ WRITE32_MEMBER( sh3_base_device::sh3_internal_w ) if (mem_mask & 0xffff0000) { m_io->write_qword(SH3_PORT_E, (data>>24)&0xff); - // logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PEDR)\n",tag(), m_pc & AM,(offset *4)+0x4000000,data,mem_mask); + // logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PEDR)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,data,mem_mask); } if (mem_mask & 0x0000ffff) { m_io->write_qword(SH3_PORT_F, (data>>8)&0xff); - // logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PFDR)\n",tag(), m_pc & AM,(offset *4)+0x4000000,data,mem_mask); + // logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PFDR)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,data,mem_mask); } } break; @@ -573,13 +573,13 @@ WRITE32_MEMBER( sh3_base_device::sh3_internal_w ) if (mem_mask & 0xffff0000) { m_io->write_qword(SH3_PORT_G, (data>>24)&0xff); - // logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PGDR)\n",tag(), m_pc & AM,(offset *4)+0x4000000,data,mem_mask); + // logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PGDR)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,data,mem_mask); } if (mem_mask & 0x0000ffff) { m_io->write_qword(SH3_PORT_H, (data>>8)&0xff); - // logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PHDR)\n",tag(), m_pc & AM,(offset *4)+0x4000000,data,mem_mask); + // logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PHDR)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,data,mem_mask); } } break; @@ -590,13 +590,13 @@ WRITE32_MEMBER( sh3_base_device::sh3_internal_w ) if (mem_mask & 0xffff0000) { m_io->write_qword(SH3_PORT_J, (data>>24)&0xff); - // logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PJDR)\n",tag(), m_pc & AM,(offset *4)+0x4000000,data,mem_mask); + // logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PJDR)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,data,mem_mask); } if (mem_mask & 0x0000ffff) { m_io->write_qword(SH3_PORT_K, (data>>8)&0xff); - //logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PKDR)\n",tag(), m_pc & AM,(offset *4)+0x4000000,data,mem_mask); + //logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x (PKDR)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,data,mem_mask); } } break; @@ -605,12 +605,12 @@ WRITE32_MEMBER( sh3_base_device::sh3_internal_w ) { if (mem_mask & 0xff000000) { - logerror("'%s' (%08x): SCIF internal write to %08x = %08x & %08x (SCSMR2 - Serial Mode Register 2)\n",tag(), m_pc & AM,(offset *4)+0x4000000,data,mem_mask); + logerror("'%s' (%08x): SCIF internal write to %08x = %08x & %08x (SCSMR2 - Serial Mode Register 2)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,data,mem_mask); } if (mem_mask & 0x0000ff00) { - logerror("'%s' (%08x): SCIF internal write to %08x = %08x & %08x (SCBRR2 - Bit Rate Register 2)\n",tag(), m_pc & AM,(offset *4)+0x4000000,data,mem_mask); + logerror("'%s' (%08x): SCIF internal write to %08x = %08x & %08x (SCBRR2 - Bit Rate Register 2)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,data,mem_mask); } } break; @@ -619,12 +619,12 @@ WRITE32_MEMBER( sh3_base_device::sh3_internal_w ) { if (mem_mask & 0xff000000) { - logerror("'%s' (%08x): SCIF internal write to %08x = %08x & %08x (SCSCR2 - Serial Control Register 2)\n",tag(), m_pc & AM,(offset *4)+0x4000000,data,mem_mask); + logerror("'%s' (%08x): SCIF internal write to %08x = %08x & %08x (SCSCR2 - Serial Control Register 2)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,data,mem_mask); } if (mem_mask & 0x0000ff00) { - logerror("'%s' (%08x): SCIF internal write to %08x = %08x & %08x (SCFTDR2 - Transmit FIFO Data Register 2)\n",tag(), m_pc & AM,(offset *4)+0x4000000,data,mem_mask); + logerror("'%s' (%08x): SCIF internal write to %08x = %08x & %08x (SCFTDR2 - Transmit FIFO Data Register 2)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,data,mem_mask); } } break; @@ -633,12 +633,12 @@ WRITE32_MEMBER( sh3_base_device::sh3_internal_w ) { if (mem_mask & 0xffff0000) { - logerror("'%s' (%08x): SCIF internal write to %08x = %08x & %08x (SCSSR2 - Serial Status Register 2)\n",tag(), m_pc & AM,(offset *4)+0x4000000,data,mem_mask); + logerror("'%s' (%08x): SCIF internal write to %08x = %08x & %08x (SCSSR2 - Serial Status Register 2)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,data,mem_mask); } if (mem_mask & 0x0000ff00) { - logerror("'%s' (%08x): SCIF internal write to %08x = %08x & %08x (SCFRDR2 - Receive FIFO Data Register 2)\n",tag(), m_pc & AM,(offset *4)+0x4000000,data,mem_mask); + logerror("'%s' (%08x): SCIF internal write to %08x = %08x & %08x (SCFRDR2 - Receive FIFO Data Register 2)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,data,mem_mask); } } break; @@ -647,12 +647,12 @@ WRITE32_MEMBER( sh3_base_device::sh3_internal_w ) { if (mem_mask & 0xff000000) { - logerror("'%s' (%08x): SCIF internal write to %08x = %08x & %08x (SCFCR2 - Fifo Control Register 2)\n",tag(), m_pc & AM,(offset *4)+0x4000000,data,mem_mask); + logerror("'%s' (%08x): SCIF internal write to %08x = %08x & %08x (SCFCR2 - Fifo Control Register 2)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,data,mem_mask); } if (mem_mask & 0x0000ffff) { - logerror("'%s' (%08x): SCIF internal write to %08x = %08x & %08x (SCFDR2 - Fifo Data Count Register 2)\n",tag(), m_pc & AM,(offset *4)+0x4000000,data,mem_mask); + logerror("'%s' (%08x): SCIF internal write to %08x = %08x & %08x (SCFDR2 - Fifo Data Count Register 2)\n",tag(), m_sh2_state->pc & SH34_AM,(offset *4)+0x4000000,data,mem_mask); } } break; @@ -660,7 +660,7 @@ WRITE32_MEMBER( sh3_base_device::sh3_internal_w ) default: { logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x\n", - tag(), m_pc & AM, + tag(), m_sh2_state->pc & SH34_AM, (offset *4)+0x4000000, data, mem_mask); @@ -672,7 +672,7 @@ WRITE32_MEMBER( sh3_base_device::sh3_internal_w ) else { logerror("'%s' (%08x): unmapped internal write to %08x = %08x & %08x\n", - tag(), m_pc & AM, + tag(), m_sh2_state->pc & SH34_AM, (offset *4)+0x4000000, data, mem_mask); diff --git a/src/devices/cpu/sh/sh4.cpp b/src/devices/cpu/sh/sh4.cpp index cc7c333d9cc..e4e4429c132 100644 --- a/src/devices/cpu/sh/sh4.cpp +++ b/src/devices/cpu/sh/sh4.cpp @@ -30,33 +30,10 @@ #include "sh4comn.h" #include "sh3comn.h" #include "sh4tmu.h" - +#include "sh_dasm.h" #include "debugger.h" -#if SH4_USE_FASTRAM_OPTIMIZATION -void sh34_base_device::add_fastram(offs_t start, offs_t end, uint8_t readonly, void *base) -{ - if (m_fastram_select < ARRAY_LENGTH(m_fastram)) - { - m_fastram[m_fastram_select].start = start; - m_fastram[m_fastram_select].end = end; - m_fastram[m_fastram_select].readonly = readonly; - m_fastram[m_fastram_select].base = base; - m_fastram_select++; - } -} -#else -void sh34_base_device::add_fastram(offs_t start, offs_t end, uint8_t readonly, void *base) -{ -} -#endif - - -CPU_DISASSEMBLE( sh4 ); -CPU_DISASSEMBLE( sh4be ); - - DEFINE_DEVICE_TYPE(SH3LE, sh3_device, "sh3le", "SH-3 (little)") DEFINE_DEVICE_TYPE(SH3BE, sh3be_device, "sh3be", "SH-3 (big)") DEFINE_DEVICE_TYPE(SH4LE, sh4_device, "sh4le", "SH-4 (little)") @@ -92,7 +69,7 @@ ADDRESS_MAP_END sh34_base_device::sh34_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, endianness_t endianness, address_map_constructor internal) - : cpu_device(mconfig, type, tag, owner, clock) + : sh_common_execution(mconfig, type, tag, owner, clock, endianness, internal) , m_program_config("program", endianness, 64, 32, 0, internal) , m_io_config("io", endianness, 64, 8) , c_md2(0) @@ -106,17 +83,8 @@ sh34_base_device::sh34_base_device(const machine_config &mconfig, device_type ty , c_md8(0) , c_clock(0) , m_mmuhack(1) -#if SH4_USE_FASTRAM_OPTIMIZATION , m_bigendian(endianness == ENDIANNESS_BIG) - , m_byte_xor(m_bigendian ? BYTE8_XOR_BE(0) : BYTE8_XOR_LE(0)) - , m_word_xor(m_bigendian ? WORD2_XOR_BE(0) : WORD2_XOR_LE(0)) - , m_dword_xor(m_bigendian ? DWORD_XOR_BE(0) : DWORD_XOR_LE(0)) - , m_fastram_select(0) -#endif { -#if SH4_USE_FASTRAM_OPTIMIZATION - memset(m_fastram, 0, sizeof(m_fastram)); -#endif } device_memory_interface::space_config_vector sh34_base_device::memory_space_config() const @@ -132,6 +100,7 @@ sh3_base_device::sh3_base_device(const machine_config &mconfig, device_type type : sh34_base_device(mconfig, type, tag, owner, clock, endianness, ADDRESS_MAP_NAME(sh3_internal_map)) { m_cpu_type = CPU_TYPE_SH3; + m_am = SH34_AM; } @@ -139,54 +108,41 @@ sh4_base_device::sh4_base_device(const machine_config &mconfig, device_type type : sh34_base_device(mconfig, type, tag, owner, clock, endianness, ADDRESS_MAP_NAME(sh4_internal_map)) { m_cpu_type = CPU_TYPE_SH4; + m_am = SH34_AM; } sh3_device::sh3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : sh3_base_device(mconfig, SH3LE, tag, owner, clock, ENDIANNESS_LITTLE) { + m_xor = 1; } sh3be_device::sh3be_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : sh3_base_device(mconfig, SH3BE, tag, owner, clock, ENDIANNESS_BIG) { + m_xor = 2; } sh4_device::sh4_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : sh4_base_device(mconfig, SH4LE, tag, owner, clock, ENDIANNESS_LITTLE) { + m_xor = 1; } sh4be_device::sh4be_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : sh4_base_device(mconfig, SH4BE, tag, owner, clock, ENDIANNESS_BIG) { + m_xor = 2; } -offs_t sh34_base_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) -{ - extern CPU_DISASSEMBLE( sh4 ); - - return CPU_DISASSEMBLE_NAME(sh4)(this, stream, pc, oprom, opram, options); -} - - -offs_t sh3be_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) -{ - extern CPU_DISASSEMBLE( sh4be ); - - return CPU_DISASSEMBLE_NAME(sh4be)(this, stream, pc, oprom, opram, options); -} - - -offs_t sh4be_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *sh34_base_device::create_disassembler() { - extern CPU_DISASSEMBLE( sh4be ); - - return CPU_DISASSEMBLE_NAME(sh4be)(this, stream, pc, oprom, opram, options); + return new sh_disassembler(true); } @@ -207,20 +163,20 @@ void sh4_base_device::LDTLB(const uint16_t opcode) logerror("using LDTLB to replace UTLB entry %02x\n", replace); // these come from PTEH - m_utlb[replace].VPN = (m_m[PTEH] & 0xfffffc00) >> 10; -// m_utlb[replace].D = (m_m[PTEH] & 0x00000200) >> 9; // from PTEL -// m_utlb[replace].V = (m_m[PTEH] & 0x00000100) >> 8; // from PTEL + m_utlb[replace].VPN = (m_m[PTEH] & 0xfffffc00) >> 10; + // m_utlb[replace].D = (m_m[PTEH] & 0x00000200) >> 9; // from PTEL + // m_utlb[replace].V = (m_m[PTEH] & 0x00000100) >> 8; // from PTEL m_utlb[replace].ASID = (m_m[PTEH] & 0x000000ff) >> 0; // these come from PTEL m_utlb[replace].PPN = (m_m[PTEL] & 0x1ffffc00) >> 10; - m_utlb[replace].V = (m_m[PTEL] & 0x00000100) >> 8; + m_utlb[replace].V = (m_m[PTEL] & 0x00000100) >> 8; m_utlb[replace].PSZ = (m_m[PTEL] & 0x00000080) >> 6; - m_utlb[replace].PSZ |=(m_m[PTEL] & 0x00000010) >> 4; - m_utlb[replace].PPR= (m_m[PTEL] & 0x00000060) >> 5; - m_utlb[replace].C = (m_m[PTEL] & 0x00000008) >> 3; - m_utlb[replace].D = (m_m[PTEL] & 0x00000004) >> 2; - m_utlb[replace].SH = (m_m[PTEL] & 0x00000002) >> 1; - m_utlb[replace].WT = (m_m[PTEL] & 0x00000001) >> 0; + m_utlb[replace].PSZ |= (m_m[PTEL] & 0x00000010) >> 4; + m_utlb[replace].PPR = (m_m[PTEL] & 0x00000060) >> 5; + m_utlb[replace].C = (m_m[PTEL] & 0x00000008) >> 3; + m_utlb[replace].D = (m_m[PTEL] & 0x00000004) >> 2; + m_utlb[replace].SH = (m_m[PTEL] & 0x00000002) >> 1; + m_utlb[replace].WT = (m_m[PTEL] & 0x00000001) >> 0; // these come from PTEA m_utlb[replace].TC = (m_m[PTEA] & 0x00000008) >> 3; m_utlb[replace].SA = (m_m[PTEA] & 0x00000007) >> 0; @@ -229,22 +185,22 @@ void sh4_base_device::LDTLB(const uint16_t opcode) #if 0 int sign_of(int n) { - return(m_fr[n]>>31); + return(m_fr[n] >> 31); } -void zero(int n,int sign) +void zero(int n, int sign) { -if (sign == 0) - m_fr[n] = 0x00000000; -else - m_fr[n] = 0x80000000; -if ((m_fpscr & PR) == 1) - m_fr[n+1] = 0x00000000; + if (sign == 0) + m_fr[n] = 0x00000000; + else + m_fr[n] = 0x80000000; + if ((m_fpscr & PR) == 1) + m_fr[n + 1] = 0x00000000; } int data_type_of(int n) { -uint32_t abs; + uint32_t abs; abs = m_fr[n] & 0x7fffffff; if ((m_fpscr & PR) == 0) { /* Single-precision */ @@ -253,13 +209,16 @@ uint32_t abs; if (sign_of(n) == 0) { zero(n, 0); return(SH4_FPU_PZERO); - } else { + } + else { zero(n, 1); return(SH4_FPU_NZERO); } - } else + } + else return(SH4_FPU_DENORM); - } else + } + else if (abs < 0x7f800000) return(SH4_FPU_NORM); else @@ -268,33 +227,39 @@ uint32_t abs; return(SH4_FPU_PINF); else return(SH4_FPU_NINF); - } else + } + else if (abs < 0x7fc00000) return(SH4_FPU_qNaN); else return(SH4_FPU_sNaN); - } else { /* Double-precision */ + } + else { /* Double-precision */ if (abs < 0x00100000) { - if (((m_fpscr & DN) == 1) || ((abs == 0x00000000) && (m_fr[n+1] == 0x00000000))) { - if(sign_of(n) == 0) { + if (((m_fpscr & DN) == 1) || ((abs == 0x00000000) && (m_fr[n + 1] == 0x00000000))) { + if (sign_of(n) == 0) { zero(n, 0); return(SH4_FPU_PZERO); - } else { + } + else { zero(n, 1); return(SH4_FPU_NZERO); } - } else + } + else return(SH4_FPU_DENORM); - } else + } + else if (abs < 0x7ff00000) return(SH4_FPU_NORM); else - if ((abs == 0x7ff00000) && (m_fr[n+1] == 0x00000000)) { + if ((abs == 0x7ff00000) && (m_fr[n + 1] == 0x00000000)) { if (sign_of(n) == 0) return(SH4_FPU_PINF); else return(SH4_FPU_NINF); - } else + } + else if (abs < 0x7ff80000) return(SH4_FPU_qNaN); else @@ -311,35 +276,20 @@ inline uint8_t sh34_base_device::RB(offs_t A) if (A >= 0x80000000) // P1/P2/P3 region { -#if SH4_USE_FASTRAM_OPTIMIZATION - const offs_t _A = A & AM; - for (int ramnum = 0; ramnum < m_fastram_select; ramnum++) - { - if (_A < m_fastram[ramnum].start || _A > m_fastram[ramnum].end) - { - continue; - } - uint8_t *fastbase = (uint8_t*)m_fastram[ramnum].base - m_fastram[ramnum].start; - return fastbase[_A ^ m_byte_xor]; - } - return m_program->read_byte(_A); -#else - return m_program->read_byte(A & AM); -#endif + return m_program->read_byte(A & SH34_AM); } else // P0 region { if (!m_sh4_mmu_enabled) { - return m_program->read_byte(A & AM); + return m_program->read_byte(A & SH34_AM); } else { - A = get_remap(A & AM); + A = get_remap(A & SH34_AM); return m_program->read_byte(A); } } - } inline uint16_t sh34_base_device::RW(offs_t A) @@ -349,35 +299,20 @@ inline uint16_t sh34_base_device::RW(offs_t A) if (A >= 0x80000000) // P1/P2/P3 region { -#if SH4_USE_FASTRAM_OPTIMIZATION - const offs_t _A = A & AM; - for (int ramnum = 0; ramnum < m_fastram_select; ramnum++) - { - if (_A < m_fastram[ramnum].start || _A > m_fastram[ramnum].end) - { - continue; - } - uint8_t *fastbase = (uint8_t*)m_fastram[ramnum].base - m_fastram[ramnum].start; - return ((uint16_t*)fastbase)[(_A ^ m_word_xor) >> 1]; - } - return m_program->read_word(_A); -#else - return m_program->read_word(A & AM); -#endif + return m_program->read_word(A & SH34_AM); } else { if (!m_sh4_mmu_enabled) { - return m_program->read_word(A & AM); + return m_program->read_word(A & SH34_AM); } else { - A = get_remap(A & AM); + A = get_remap(A & SH34_AM); return m_program->read_word(A); } } - } inline uint32_t sh34_base_device::RL(offs_t A) @@ -387,820 +322,136 @@ inline uint32_t sh34_base_device::RL(offs_t A) if (A >= 0x80000000) // P1/P2/P3 region { -#if SH4_USE_FASTRAM_OPTIMIZATION - const offs_t _A = A & AM; - for (int ramnum = 0; ramnum < m_fastram_select; ramnum++) - { - if (_A < m_fastram[ramnum].start || _A > m_fastram[ramnum].end) - { - continue; - } - uint8_t *fastbase = (uint8_t*)m_fastram[ramnum].base - m_fastram[ramnum].start; - return ((uint32_t*)fastbase)[(_A^m_dword_xor) >> 2]; - } - return m_program->read_dword(_A); -#else - return m_program->read_dword(A & AM); -#endif + return m_program->read_dword(A & SH34_AM); } else { if (!m_sh4_mmu_enabled) { - return m_program->read_dword(A & AM); + return m_program->read_dword(A & SH34_AM); } else { - A = get_remap(A & AM); + A = get_remap(A & SH34_AM); return m_program->read_dword(A); } } - } inline void sh34_base_device::WB(offs_t A, uint8_t V) { if (A >= 0xe0000000) { - m_program->write_byte(A,V); + m_program->write_byte(A, V); return; } if (A >= 0x80000000) // P1/P2/P3 region { -#if SH4_USE_FASTRAM_OPTIMIZATION - const offs_t _A = A & AM; - for (int ramnum = 0; ramnum < m_fastram_select; ramnum++) - { - if (m_fastram[ramnum].readonly == true || _A < m_fastram[ramnum].start || _A > m_fastram[ramnum].end) - { - continue; - } - uint8_t *fastbase = (uint8_t*)m_fastram[ramnum].base - m_fastram[ramnum].start; - fastbase[_A ^ m_byte_xor] = V; - return; - } - m_program->write_byte(_A, V); -#else - m_program->write_byte(A & AM, V); -#endif + m_program->write_byte(A & SH34_AM, V); } else { if (!m_sh4_mmu_enabled) { - m_program->write_byte(A & AM, V); + m_program->write_byte(A & SH34_AM, V); } else { - A = get_remap(A & AM); + A = get_remap(A & SH34_AM); m_program->write_byte(A, V); } } - } inline void sh34_base_device::WW(offs_t A, uint16_t V) { if (A >= 0xe0000000) { - m_program->write_word(A,V); + m_program->write_word(A, V); return; } if (A >= 0x80000000) // P1/P2/P3 region { -#if SH4_USE_FASTRAM_OPTIMIZATION - const offs_t _A = A & AM; - for (int ramnum = 0; ramnum < m_fastram_select; ramnum++) - { - if (m_fastram[ramnum].readonly == true || _A < m_fastram[ramnum].start || _A > m_fastram[ramnum].end) - { - continue; - } - void *fastbase = (uint8_t*)m_fastram[ramnum].base - m_fastram[ramnum].start; - ((uint16_t*)fastbase)[(_A ^ m_word_xor) >> 1] = V; - return; - } - m_program->write_word(_A, V); -#else - m_program->write_word(A & AM, V); -#endif + m_program->write_word(A & SH34_AM, V); } else { if (!m_sh4_mmu_enabled) { - m_program->write_word(A & AM, V); + m_program->write_word(A & SH34_AM, V); } else { - A = get_remap(A & AM); + A = get_remap(A & SH34_AM); m_program->write_word(A, V); } } - } inline void sh34_base_device::WL(offs_t A, uint32_t V) { if (A >= 0xe0000000) { - m_program->write_dword(A,V); + m_program->write_dword(A, V); return; } if (A >= 0x80000000) // P1/P2/P3 region { -#if SH4_USE_FASTRAM_OPTIMIZATION - const offs_t _A = A & AM; - for (int ramnum = 0; ramnum < m_fastram_select; ramnum++) - { - if (m_fastram[ramnum].readonly == true || _A < m_fastram[ramnum].start || _A > m_fastram[ramnum].end) - { - continue; - } - void *fastbase = (uint8_t*)m_fastram[ramnum].base - m_fastram[ramnum].start; - ((uint32_t*)fastbase)[(_A ^ m_dword_xor) >> 2] = V; - return; - } - m_program->write_dword(_A, V); -#else - m_program->write_dword(A & AM, V); -#endif + m_program->write_dword(A & SH34_AM, V); } else { if (!m_sh4_mmu_enabled) { - m_program->write_dword(A & AM, V); + m_program->write_dword(A & SH34_AM, V); } else { - A = get_remap(A & AM); + A = get_remap(A & SH34_AM); m_program->write_dword(A, V); } } - -} - -/* code cycles t-bit - * 0011 nnnn mmmm 1100 1 - - * ADD Rm,Rn - */ -inline void sh34_base_device::ADD(const uint16_t opcode) -{ - m_r[Rn] += m_r[Rm]; -} - -/* code cycles t-bit - * 0111 nnnn iiii iiii 1 - - * ADD #imm,Rn - */ -inline void sh34_base_device::ADDI(const uint16_t opcode) -{ - m_r[Rn] += (int32_t)(int16_t)(int8_t)(opcode&0xff); -} - -/* code cycles t-bit - * 0011 nnnn mmmm 1110 1 carry - * ADDC Rm,Rn - */ -inline void sh34_base_device::ADDC(const uint16_t opcode) -{ - uint32_t m = Rm; uint32_t n = Rn; - uint32_t tmp0, tmp1; - - tmp1 = m_r[n] + m_r[m]; - tmp0 = m_r[n]; - m_r[n] = tmp1 + (m_sr & T); - if (tmp0 > tmp1) - m_sr |= T; - else - m_sr &= ~T; - if (tmp1 > m_r[n]) - m_sr |= T; -} - -/* code cycles t-bit - * 0011 nnnn mmmm 1111 1 overflow - * ADDV Rm,Rn - */ -inline void sh34_base_device::ADDV(const uint16_t opcode) -{ - uint32_t m = Rm; uint32_t n = Rn; - int32_t dest, src, ans; - - if ((int32_t) m_r[n] >= 0) - dest = 0; - else - dest = 1; - if ((int32_t) m_r[m] >= 0) - src = 0; - else - src = 1; - src += dest; - m_r[n] += m_r[m]; - if ((int32_t) m_r[n] >= 0) - ans = 0; - else - ans = 1; - ans += dest; - if (src == 0 || src == 2) - { - if (ans == 1) - m_sr |= T; - else - m_sr &= ~T; - } - else - m_sr &= ~T; -} - -/* code cycles t-bit - * 0010 nnnn mmmm 1001 1 - - * AND Rm,Rn - */ -inline void sh34_base_device::AND(const uint16_t opcode) -{ - m_r[Rn] &= m_r[Rm]; -} - - -/* code cycles t-bit - * 1100 1001 iiii iiii 1 - - * AND #imm,R0 - */ -inline void sh34_base_device::ANDI(const uint16_t opcode) -{ - m_r[0] &= (opcode&0xff); -} - -/* code cycles t-bit - * 1100 1101 iiii iiii 1 - - * AND.B #imm,@(R0,GBR) - */ -inline void sh34_base_device::ANDM(const uint16_t opcode) -{ - uint32_t temp; - - m_ea = m_gbr + m_r[0]; - temp = (opcode&0xff) & RB( m_ea ); - WB(m_ea, temp ); - m_sh4_icount -= 2; -} - -/* code cycles t-bit - * 1000 1011 dddd dddd 3/1 - - * BF disp8 - */ -inline void sh34_base_device::BF(const uint16_t opcode) -{ - if ((m_sr & T) == 0) - { - int32_t disp = ((int32_t)(opcode&0xff) << 24) >> 24; - m_pc = m_ea = m_pc + disp * 2 + 2; - m_sh4_icount -= 2; - } -} - -/* code cycles t-bit - * 1000 1111 dddd dddd 3/1 - - * BFS disp8 - */ -inline void sh34_base_device::BFS(const uint16_t opcode) -{ - if ((m_sr & T) == 0) - { - int32_t disp = ((int32_t)(opcode&0xff) << 24) >> 24; - m_delay = m_ea = m_pc + disp * 2 + 2; - m_sh4_icount--; - } -} - -/* code cycles t-bit - * 1010 dddd dddd dddd 2 - - * BRA disp12 - */ -inline void sh34_base_device::BRA(const uint16_t opcode) -{ - int32_t disp = ((int32_t)(opcode&0xfff) << 20) >> 20; - -#if BUSY_LOOP_HACKS - if (disp == -2) - { - uint32_t next_opcode = RW(m_pc & AM); - /* BRA $ - * NOP - */ - if (next_opcode == 0x0009) - m_sh4_icount %= 3; /* cycles for BRA $ and NOP taken (3) */ - } -#endif - m_delay = m_ea = m_pc + disp * 2 + 2; - m_sh4_icount--; -} - -/* code cycles t-bit - * 0000 mmmm 0010 0011 2 - - * BRAF Rm - */ -inline void sh34_base_device::BRAF(const uint16_t opcode) -{ - m_delay = m_pc + m_r[Rn] + 2; - m_sh4_icount--; -} - -/* code cycles t-bit - * 1011 dddd dddd dddd 2 - - * BSR disp12 - */ -inline void sh34_base_device::BSR(const uint16_t opcode) -{ - int32_t disp = ((int32_t)(opcode&0xfff) << 20) >> 20; - - m_pr = m_pc + 2; - m_delay = m_ea = m_pc + disp * 2 + 2; - m_sh4_icount--; -} - -/* code cycles t-bit - * 0000 mmmm 0000 0011 2 - - * BSRF Rm - */ -inline void sh34_base_device::BSRF(const uint16_t opcode) -{ - m_pr = m_pc + 2; - m_delay = m_pc + m_r[Rn] + 2; - m_sh4_icount--; -} - -/* code cycles t-bit - * 1000 1001 dddd dddd 3/1 - - * BT disp8 - */ -inline void sh34_base_device::BT(const uint16_t opcode) -{ - if ((m_sr & T) != 0) - { - int32_t disp = ((int32_t)(opcode&0xff) << 24) >> 24; - m_pc = m_ea = m_pc + disp * 2 + 2; - m_sh4_icount -= 2; - } -} - -/* code cycles t-bit - * 1000 1101 dddd dddd 2/1 - - * BTS disp8 - */ -inline void sh34_base_device::BTS(const uint16_t opcode) -{ - if ((m_sr & T) != 0) - { - int32_t disp = ((int32_t)(opcode&0xff) << 24) >> 24; - m_delay = m_ea = m_pc + disp * 2 + 2; - m_sh4_icount--; - } -} - -/* code cycles t-bit - * 0000 0000 0010 1000 1 - - * CLRMAC - */ -inline void sh34_base_device::CLRMAC(const uint16_t opcode) -{ - m_mach = 0; - m_macl = 0; -} - -/* code cycles t-bit - * 0000 0000 0000 1000 1 - - * CLRT - */ -inline void sh34_base_device::CLRT(const uint16_t opcode) -{ - m_sr &= ~T; -} - -/* code cycles t-bit - * 0011 nnnn mmmm 0000 1 comparison result - * CMP_EQ Rm,Rn - */ -inline void sh34_base_device::CMPEQ(const uint16_t opcode) -{ - if (m_r[Rn] == m_r[Rm]) - m_sr |= T; - else - m_sr &= ~T; -} - -/* code cycles t-bit - * 0011 nnnn mmmm 0011 1 comparison result - * CMP_GE Rm,Rn - */ -inline void sh34_base_device::CMPGE(const uint16_t opcode) -{ - if ((int32_t) m_r[Rn] >= (int32_t) m_r[Rm]) - m_sr |= T; - else - m_sr &= ~T; -} - -/* code cycles t-bit - * 0011 nnnn mmmm 0111 1 comparison result - * CMP_GT Rm,Rn - */ -inline void sh34_base_device::CMPGT(const uint16_t opcode) -{ - if ((int32_t) m_r[Rn] > (int32_t) m_r[Rm]) - m_sr |= T; - else - m_sr &= ~T; -} - -/* code cycles t-bit - * 0011 nnnn mmmm 0110 1 comparison result - * CMP_HI Rm,Rn - */ -inline void sh34_base_device::CMPHI(const uint16_t opcode) -{ - if ((uint32_t) m_r[Rn] > (uint32_t) m_r[Rm]) - m_sr |= T; - else - m_sr &= ~T; -} - -/* code cycles t-bit - * 0011 nnnn mmmm 0010 1 comparison result - * CMP_HS Rm,Rn - */ -inline void sh34_base_device::CMPHS(const uint16_t opcode) -{ - if ((uint32_t) m_r[Rn] >= (uint32_t) m_r[Rm]) - m_sr |= T; - else - m_sr &= ~T; -} - - -/* code cycles t-bit - * 0100 nnnn 0001 0101 1 comparison result - * CMP_PL Rn - */ -inline void sh34_base_device::CMPPL(const uint16_t opcode) -{ - if ((int32_t) m_r[Rn] > 0) - m_sr |= T; - else - m_sr &= ~T; -} - -/* code cycles t-bit - * 0100 nnnn 0001 0001 1 comparison result - * CMP_PZ Rn - */ -inline void sh34_base_device::CMPPZ(const uint16_t opcode) -{ - if ((int32_t) m_r[Rn] >= 0) - m_sr |= T; - else - m_sr &= ~T; -} - -/* code cycles t-bit - * 0010 nnnn mmmm 1100 1 comparison result - * CMP_STR Rm,Rn - */ -inline void sh34_base_device::CMPSTR(const uint16_t opcode) -{ - uint32_t temp; - int32_t HH, HL, LH, LL; - temp = m_r[Rn] ^ m_r[Rm]; - HH = (temp >> 24) & 0xff; - HL = (temp >> 16) & 0xff; - LH = (temp >> 8) & 0xff; - LL = temp & 0xff; - if (HH && HL && LH && LL) - m_sr &= ~T; - else - m_sr |= T; - } - - -/* code cycles t-bit - * 1000 1000 iiii iiii 1 comparison result - * CMP/EQ #imm,R0 - */ -inline void sh34_base_device::CMPIM(const uint16_t opcode) -{ - uint32_t imm = (uint32_t)(int32_t)(int16_t)(int8_t)(opcode&0xff); - - if (m_r[0] == imm) - m_sr |= T; - else - m_sr &= ~T; -} - -/* code cycles t-bit - * 0010 nnnn mmmm 0111 1 calculation result - * DIV0S Rm,Rn - */ -inline void sh34_base_device::DIV0S(const uint16_t opcode) -{ - uint32_t m = Rm; uint32_t n = Rn; - - if ((m_r[n] & 0x80000000) == 0) - m_sr &= ~Q; - else - m_sr |= Q; - if ((m_r[m] & 0x80000000) == 0) - m_sr &= ~M; - else - m_sr |= M; - if ((m_r[m] ^ m_r[n]) & 0x80000000) - m_sr |= T; - else - m_sr &= ~T; -} - -/* code cycles t-bit - * 0000 0000 0001 1001 1 0 - * DIV0U - */ -inline void sh34_base_device::DIV0U(const uint16_t opcode) -{ - m_sr &= ~(M | Q | T); -} - -/* code cycles t-bit - * 0011 nnnn mmmm 0100 1 calculation result - * DIV1 Rm,Rn - */ -inline void sh34_base_device::DIV1(const uint16_t opcode) -{ - uint32_t m = Rm; uint32_t n = Rn; - - uint32_t tmp0; - uint32_t old_q; - - old_q = m_sr & Q; - if (0x80000000 & m_r[n]) - m_sr |= Q; - else - m_sr &= ~Q; - - m_r[n] = (m_r[n] << 1) | (m_sr & T); - - if (!old_q) - { - if (!(m_sr & M)) - { - tmp0 = m_r[n]; - m_r[n] -= m_r[m]; - if(!(m_sr & Q)) - if(m_r[n] > tmp0) - m_sr |= Q; - else - m_sr &= ~Q; - else - if(m_r[n] > tmp0) - m_sr &= ~Q; - else - m_sr |= Q; - } - else - { - tmp0 = m_r[n]; - m_r[n] += m_r[m]; - if(!(m_sr & Q)) - { - if(m_r[n] < tmp0) - m_sr &= ~Q; - else - m_sr |= Q; - } - else - { - if(m_r[n] < tmp0) - m_sr |= Q; - else - m_sr &= ~Q; - } - } - } - else - { - if (!(m_sr & M)) - { - tmp0 = m_r[n]; - m_r[n] += m_r[m]; - if(!(m_sr & Q)) - if(m_r[n] < tmp0) - m_sr |= Q; - else - m_sr &= ~Q; - else - if(m_r[n] < tmp0) - m_sr &= ~Q; - else - m_sr |= Q; - } - else - { - tmp0 = m_r[n]; - m_r[n] -= m_r[m]; - if(!(m_sr & Q)) - if(m_r[n] > tmp0) - m_sr &= ~Q; - else - m_sr |= Q; - else - if(m_r[n] > tmp0) - m_sr |= Q; - else - m_sr &= ~Q; - } - } - - tmp0 = (m_sr & (Q | M)); - if((!tmp0) || (tmp0 == 0x300)) /* if Q == M set T else clear T */ - m_sr |= T; - else - m_sr &= ~T; } -/* DMULS.L Rm,Rn */ -inline void sh34_base_device::DMULS(const uint16_t opcode) +inline void sh34_base_device::ILLEGAL() { - uint32_t m = Rm; uint32_t n = Rn; - - uint32_t RnL, RnH, RmL, RmH, Res0, Res1, Res2; - uint32_t temp0, temp1, temp2, temp3; - int32_t tempm, tempn, fnLmL; - - tempn = (int32_t) m_r[n]; - tempm = (int32_t) m_r[m]; - if (tempn < 0) - tempn = 0 - tempn; - if (tempm < 0) - tempm = 0 - tempm; - if ((int32_t) (m_r[n] ^ m_r[m]) < 0) - fnLmL = -1; - else - fnLmL = 0; - temp1 = (uint32_t) tempn; - temp2 = (uint32_t) tempm; - RnL = temp1 & 0x0000ffff; - RnH = (temp1 >> 16) & 0x0000ffff; - RmL = temp2 & 0x0000ffff; - RmH = (temp2 >> 16) & 0x0000ffff; - temp0 = RmL * RnL; - temp1 = RmH * RnL; - temp2 = RmL * RnH; - temp3 = RmH * RnH; - Res2 = 0; - Res1 = temp1 + temp2; - if (Res1 < temp1) - Res2 += 0x00010000; - temp1 = (Res1 << 16) & 0xffff0000; - Res0 = temp0 + temp1; - if (Res0 < temp0) - Res2++; - Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3; - if (fnLmL < 0) - { - Res2 = ~Res2; - if (Res0 == 0) - Res2++; - else - Res0 = (~Res0) + 1; - } - m_mach = Res2; - m_macl = Res0; - m_sh4_icount--; + NOP(); } -/* DMULU.L Rm,Rn */ -inline void sh34_base_device::DMULU(const uint16_t opcode) -{ - uint32_t m = Rm; uint32_t n = Rn; - - uint32_t RnL, RnH, RmL, RmH, Res0, Res1, Res2; - uint32_t temp0, temp1, temp2, temp3; - - RnL = m_r[n] & 0x0000ffff; - RnH = (m_r[n] >> 16) & 0x0000ffff; - RmL = m_r[m] & 0x0000ffff; - RmH = (m_r[m] >> 16) & 0x0000ffff; - temp0 = RmL * RnL; - temp1 = RmH * RnL; - temp2 = RmL * RnH; - temp3 = RmH * RnH; - Res2 = 0; - Res1 = temp1 + temp2; - if (Res1 < temp1) - Res2 += 0x00010000; - temp1 = (Res1 << 16) & 0xffff0000; - Res0 = temp0 + temp1; - if (Res0 < temp0) - Res2++; - Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3; - m_mach = Res2; - m_macl = Res0; - m_sh4_icount--; -} - -/* DT Rn */ -inline void sh34_base_device::DT(const uint16_t opcode) -{ - uint32_t n = Rn; - - m_r[n]--; - if (m_r[n] == 0) - m_sr |= T; - else - m_sr &= ~T; -#if BUSY_LOOP_HACKS - { - uint32_t next_opcode = RW(m_pc & AM); - /* DT Rn - * BF $-2 - */ - if (next_opcode == 0x8bfd) - { - while (m_r[n] > 1 && m_sh4_icount > 4) - { - m_r[n]--; - m_sh4_icount -= 4; /* cycles for DT (1) and BF taken (3) */ - } - } - } -#endif -} - -/* EXTS.B Rm,Rn */ -inline void sh34_base_device::EXTSB(const uint16_t opcode) -{ - m_r[Rn] = ((int32_t)m_r[Rm] << 24) >> 24; -} - -/* EXTS.W Rm,Rn */ -inline void sh34_base_device::EXTSW(const uint16_t opcode) -{ - m_r[Rn] = ((int32_t)m_r[Rm] << 16) >> 16; -} - -/* EXTU.B Rm,Rn */ -inline void sh34_base_device::EXTUB(const uint16_t opcode) -{ - m_r[Rn] = m_r[Rm] & 0x000000ff; -} - -/* EXTU.W Rm,Rn */ -inline void sh34_base_device::EXTUW(const uint16_t opcode) +/* MOVCA.L R0,@Rn */ +inline void sh34_base_device::MOVCAL(const uint16_t opcode) { - m_r[Rn] = m_r[Rm] & 0x0000ffff; + m_sh2_state->ea = m_sh2_state->r[Rn]; + WL(m_sh2_state->ea, m_sh2_state->r[0]); } -/* JMP @Rm */ -inline void sh34_base_device::JMP(const uint16_t opcode) +inline void sh34_base_device::CLRS(const uint16_t opcode) { - m_delay = m_ea = m_r[Rn]; + m_sh2_state->sr &= ~SH_S; } -/* JSR @Rm */ -inline void sh34_base_device::JSR(const uint16_t opcode) +inline void sh34_base_device::SETS(const uint16_t opcode) { - m_pr = m_pc + 2; - m_delay = m_ea = m_r[Rn]; - m_sh4_icount--; + m_sh2_state->sr |= SH_S; } - /* LDC Rm,SR */ inline void sh34_base_device::LDCSR(const uint16_t opcode) { - uint32_t reg; + // important to store the value now so that it doesn't get affected by the bank change + uint32_t reg = m_sh2_state->r[Rn]; - reg = m_r[Rn]; if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0) - sh4_syncronize_register_bank((m_sr & sRB) >> 29); - if ((m_r[Rn] & sRB) != (m_sr & sRB)) - sh4_change_register_bank(m_r[Rn] & sRB ? 1 : 0); - m_sr = reg & FLAGS; - sh4_exception_recompute(); -} + sh4_syncronize_register_bank((m_sh2_state->sr & sRB) >> 29); -/* LDC Rm,GBR */ -inline void sh34_base_device::LDCGBR(const uint16_t opcode) -{ - m_gbr = m_r[Rn]; -} + if ((m_sh2_state->r[Rn] & sRB) != (m_sh2_state->sr & sRB)) + sh4_change_register_bank(m_sh2_state->r[Rn] & sRB ? 1 : 0); -/* LDC Rm,VBR */ -inline void sh34_base_device::LDCVBR(const uint16_t opcode) -{ - m_vbr = m_r[Rn]; + m_sh2_state->sr = reg & SH34_FLAGS; + sh4_exception_recompute(); } /* LDC.L @Rm+,SR */ @@ -1208,924 +459,37 @@ inline void sh34_base_device::LDCMSR(const uint16_t opcode) { uint32_t old; - old = m_sr; - m_ea = m_r[Rn]; - m_sr = RL(m_ea ) & FLAGS; + old = m_sh2_state->sr; + m_sh2_state->ea = m_sh2_state->r[Rn]; + m_sh2_state->sr = RL(m_sh2_state->ea) & SH34_FLAGS; if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0) sh4_syncronize_register_bank((old & sRB) >> 29); - if ((old & sRB) != (m_sr & sRB)) - sh4_change_register_bank(m_sr & sRB ? 1 : 0); - m_r[Rn] += 4; - m_sh4_icount -= 2; + if ((old & sRB) != (m_sh2_state->sr & sRB)) + sh4_change_register_bank(m_sh2_state->sr & sRB ? 1 : 0); + m_sh2_state->r[Rn] += 4; + m_sh2_state->icount -= 2; sh4_exception_recompute(); } -/* LDC.L @Rm+,GBR */ -inline void sh34_base_device::LDCMGBR(const uint16_t opcode) -{ - m_ea = m_r[Rn]; - m_gbr = RL(m_ea ); - m_r[Rn] += 4; - m_sh4_icount -= 2; -} - -/* LDC.L @Rm+,VBR */ -inline void sh34_base_device::LDCMVBR(const uint16_t opcode) -{ - m_ea = m_r[Rn]; - m_vbr = RL(m_ea ); - m_r[Rn] += 4; - m_sh4_icount -= 2; -} - -/* LDS Rm,MACH */ -inline void sh34_base_device::LDSMACH(const uint16_t opcode) -{ - m_mach = m_r[Rn]; -} - -/* LDS Rm,MACL */ -inline void sh34_base_device::LDSMACL(const uint16_t opcode) -{ - m_macl = m_r[Rn]; -} - -/* LDS Rm,PR */ -inline void sh34_base_device::LDSPR(const uint16_t opcode) -{ - m_pr = m_r[Rn]; -} - -/* LDS.L @Rm+,MACH */ -inline void sh34_base_device::LDSMMACH(const uint16_t opcode) -{ - m_ea = m_r[Rn]; - m_mach = RL(m_ea ); - m_r[Rn] += 4; -} - -/* LDS.L @Rm+,MACL */ -inline void sh34_base_device::LDSMMACL(const uint16_t opcode) -{ - m_ea = m_r[Rn]; - m_macl = RL(m_ea ); - m_r[Rn] += 4; -} - -/* LDS.L @Rm+,PR */ -inline void sh34_base_device::LDSMPR(const uint16_t opcode) -{ - m_ea = m_r[Rn]; - m_pr = RL(m_ea ); - m_r[Rn] += 4; -} - -/* MAC.L @Rm+,@Rn+ */ -inline void sh34_base_device::MAC_L(const uint16_t opcode) -{ - uint32_t m = Rm; uint32_t n = Rn; - - uint32_t RnL, RnH, RmL, RmH, Res0, Res1, Res2; - uint32_t temp0, temp1, temp2, temp3; - int32_t tempm, tempn, fnLmL; - - tempn = (int32_t) RL(m_r[n] ); - m_r[n] += 4; - tempm = (int32_t) RL(m_r[m] ); - m_r[m] += 4; - if ((int32_t) (tempn ^ tempm) < 0) - fnLmL = -1; - else - fnLmL = 0; - if (tempn < 0) - tempn = 0 - tempn; - if (tempm < 0) - tempm = 0 - tempm; - temp1 = (uint32_t) tempn; - temp2 = (uint32_t) tempm; - RnL = temp1 & 0x0000ffff; - RnH = (temp1 >> 16) & 0x0000ffff; - RmL = temp2 & 0x0000ffff; - RmH = (temp2 >> 16) & 0x0000ffff; - temp0 = RmL * RnL; - temp1 = RmH * RnL; - temp2 = RmL * RnH; - temp3 = RmH * RnH; - Res2 = 0; - Res1 = temp1 + temp2; - if (Res1 < temp1) - Res2 += 0x00010000; - temp1 = (Res1 << 16) & 0xffff0000; - Res0 = temp0 + temp1; - if (Res0 < temp0) - Res2++; - Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3; - if (fnLmL < 0) - { - Res2 = ~Res2; - if (Res0 == 0) - Res2++; - else - Res0 = (~Res0) + 1; - } - if (m_sr & S) - { - Res0 = m_macl + Res0; - if (m_macl > Res0) - Res2++; - Res2 += (m_mach & 0x0000ffff); - if (((int32_t) Res2 < 0) && (Res2 < 0xffff8000)) - { - Res2 = 0x00008000; - Res0 = 0x00000000; - } - else if (((int32_t) Res2 > 0) && (Res2 > 0x00007fff)) - { - Res2 = 0x00007fff; - Res0 = 0xffffffff; - } - m_mach = Res2; - m_macl = Res0; - } - else - { - Res0 = m_macl + Res0; - if (m_macl > Res0) - Res2++; - Res2 += m_mach; - m_mach = Res2; - m_macl = Res0; - } - m_sh4_icount -= 2; -} - -/* MAC.W @Rm+,@Rn+ */ -inline void sh34_base_device::MAC_W(const uint16_t opcode) -{ - uint32_t m = Rm; uint32_t n = Rn; - - int32_t tempm, tempn, dest, src, ans; - uint32_t templ; - - tempn = (int32_t) RW(m_r[n] ); - m_r[n] += 2; - tempm = (int32_t) RW(m_r[m] ); - m_r[m] += 2; - templ = m_macl; - tempm = ((int32_t) (short) tempn * (int32_t) (short) tempm); - if ((int32_t) m_macl >= 0) - dest = 0; - else - dest = 1; - if ((int32_t) tempm >= 0) - { - src = 0; - tempn = 0; - } - else - { - src = 1; - tempn = 0xffffffff; - } - src += dest; - m_macl += tempm; - if ((int32_t) m_macl >= 0) - ans = 0; - else - ans = 1; - ans += dest; - if (m_sr & S) - { - if (ans == 1) - { - if (src == 0) - m_macl = 0x7fffffff; - if (src == 2) - m_macl = 0x80000000; - } - } - else - { - m_mach += tempn; - if (templ > m_macl) - m_mach += 1; - } - m_sh4_icount -= 2; -} - -/* MOV Rm,Rn */ -inline void sh34_base_device::MOV(const uint16_t opcode) -{ - m_r[Rn] = m_r[Rm]; -} - -/* MOV.B Rm,@Rn */ -inline void sh34_base_device::MOVBS(const uint16_t opcode) -{ - m_ea = m_r[Rn]; - WB(m_ea, m_r[Rm] & 0x000000ff); -} - -/* MOV.W Rm,@Rn */ -inline void sh34_base_device::MOVWS(const uint16_t opcode) -{ - m_ea = m_r[Rn]; - WW(m_ea, m_r[Rm] & 0x0000ffff); -} - -/* MOV.L Rm,@Rn */ -inline void sh34_base_device::MOVLS(const uint16_t opcode) -{ - m_ea = m_r[Rn]; - WL(m_ea, m_r[Rm] ); -} - -/* MOV.B @Rm,Rn */ -inline void sh34_base_device::MOVBL(const uint16_t opcode) -{ - m_ea = m_r[Rm]; - m_r[Rn] = (uint32_t)(int32_t)(int16_t)(int8_t) RB( m_ea ); -} - -/* MOV.W @Rm,Rn */ -inline void sh34_base_device::MOVWL(const uint16_t opcode) -{ - m_ea = m_r[Rm]; - m_r[Rn] = (uint32_t)(int32_t)(int16_t) RW(m_ea ); -} - -/* MOV.L @Rm,Rn */ -inline void sh34_base_device::MOVLL(const uint16_t opcode) -{ - m_ea = m_r[Rm]; - m_r[Rn] = RL(m_ea ); -} - -/* MOV.B Rm,@-Rn */ -inline void sh34_base_device::MOVBM(const uint16_t opcode) -{ - uint32_t data = m_r[Rm] & 0x000000ff; - - m_r[Rn] -= 1; - WB(m_r[Rn], data ); -} - -/* MOV.W Rm,@-Rn */ -inline void sh34_base_device::MOVWM(const uint16_t opcode) -{ - uint32_t data = m_r[Rm] & 0x0000ffff; - - m_r[Rn] -= 2; - WW(m_r[Rn], data ); -} - -/* MOV.L Rm,@-Rn */ -inline void sh34_base_device::MOVLM(const uint16_t opcode) -{ - uint32_t data = m_r[Rm]; - - m_r[Rn] -= 4; - WL(m_r[Rn], data ); -} - -/* MOV.B @Rm+,Rn */ -inline void sh34_base_device::MOVBP(const uint16_t opcode) -{ - uint32_t m = Rm; uint32_t n = Rn; - - m_r[n] = (uint32_t)(int32_t)(int16_t)(int8_t) RB( m_r[m] ); - if (n != m) - m_r[m] += 1; -} - -/* MOV.W @Rm+,Rn */ -inline void sh34_base_device::MOVWP(const uint16_t opcode) -{ - uint32_t m = Rm; uint32_t n = Rn; - - m_r[n] = (uint32_t)(int32_t)(int16_t) RW(m_r[m] ); - if (n != m) - m_r[m] += 2; -} - -/* MOV.L @Rm+,Rn */ -inline void sh34_base_device::MOVLP(const uint16_t opcode) -{ - uint32_t m = Rm; uint32_t n = Rn; - - m_r[n] = RL(m_r[m] ); - if (n != m) - m_r[m] += 4; -} - -/* MOV.B Rm,@(R0,Rn) */ -inline void sh34_base_device::MOVBS0(const uint16_t opcode) -{ - m_ea = m_r[Rn] + m_r[0]; - WB(m_ea, m_r[Rm] & 0x000000ff ); -} - -/* MOV.W Rm,@(R0,Rn) */ -inline void sh34_base_device::MOVWS0(const uint16_t opcode) -{ - m_ea = m_r[Rn] + m_r[0]; - WW(m_ea, m_r[Rm] & 0x0000ffff ); -} - -/* MOV.L Rm,@(R0,Rn) */ -inline void sh34_base_device::MOVLS0(const uint16_t opcode) -{ - m_ea = m_r[Rn] + m_r[0]; - WL(m_ea, m_r[Rm] ); -} - -/* MOV.B @(R0,Rm),Rn */ -inline void sh34_base_device::MOVBL0(const uint16_t opcode) -{ - m_ea = m_r[Rm] + m_r[0]; - m_r[Rn] = (uint32_t)(int32_t)(int16_t)(int8_t) RB( m_ea ); -} - -/* MOV.W @(R0,Rm),Rn */ -inline void sh34_base_device::MOVWL0(const uint16_t opcode) -{ - m_ea = m_r[Rm] + m_r[0]; - m_r[Rn] = (uint32_t)(int32_t)(int16_t) RW(m_ea ); -} - -/* MOV.L @(R0,Rm),Rn */ -inline void sh34_base_device::MOVLL0(const uint16_t opcode) -{ - m_ea = m_r[Rm] + m_r[0]; - m_r[Rn] = RL(m_ea ); -} - -/* MOV #imm,Rn */ -inline void sh34_base_device::MOVI(const uint16_t opcode) -{ - m_r[Rn] = (uint32_t)(int32_t)(int16_t)(int8_t)(opcode&0xff); -} - -/* MOV.W @(disp8,PC),Rn */ -inline void sh34_base_device::MOVWI(const uint16_t opcode) -{ - uint32_t disp = opcode & 0xff; - m_ea = m_pc + disp * 2 + 2; - m_r[Rn] = (uint32_t)(int32_t)(int16_t) RW(m_ea ); -} - -/* MOV.L @(disp8,PC),Rn */ -inline void sh34_base_device::MOVLI(const uint16_t opcode) -{ - uint32_t disp = opcode & 0xff; - m_ea = ((m_pc + 2) & ~3) + disp * 4; - m_r[Rn] = RL(m_ea ); -} - -/* MOV.B @(disp8,GBR),R0 */ -inline void sh34_base_device::MOVBLG(const uint16_t opcode) -{ - uint32_t disp = opcode & 0xff; - m_ea = m_gbr + disp; - m_r[0] = (uint32_t)(int32_t)(int16_t)(int8_t) RB( m_ea ); -} - -/* MOV.W @(disp8,GBR),R0 */ -inline void sh34_base_device::MOVWLG(const uint16_t opcode) -{ - uint32_t disp = opcode & 0xff; - m_ea = m_gbr + disp * 2; - m_r[0] = (int32_t)(int16_t) RW(m_ea ); -} - -/* MOV.L @(disp8,GBR),R0 */ -inline void sh34_base_device::MOVLLG(const uint16_t opcode) -{ - uint32_t disp = opcode & 0xff; - m_ea = m_gbr + disp * 4; - m_r[0] = RL(m_ea ); -} - -/* MOV.B R0,@(disp8,GBR) */ -inline void sh34_base_device::MOVBSG(const uint16_t opcode) -{ - uint32_t disp = opcode & 0xff; - m_ea = m_gbr + disp; - WB(m_ea, m_r[0] & 0x000000ff ); -} - -/* MOV.W R0,@(disp8,GBR) */ -inline void sh34_base_device::MOVWSG(const uint16_t opcode) -{ - uint32_t disp = opcode & 0xff; - m_ea = m_gbr + disp * 2; - WW(m_ea, m_r[0] & 0x0000ffff ); -} - -/* MOV.L R0,@(disp8,GBR) */ -inline void sh34_base_device::MOVLSG(const uint16_t opcode) -{ - uint32_t disp = opcode & 0xff; - m_ea = m_gbr + disp * 4; - WL(m_ea, m_r[0] ); -} - -/* MOV.B R0,@(disp4,Rm) */ -inline void sh34_base_device::MOVBS4(const uint16_t opcode) -{ - uint32_t disp = opcode & 0x0f; - m_ea = m_r[Rm] + disp; - WB(m_ea, m_r[0] & 0x000000ff ); -} - -/* MOV.W R0,@(disp4,Rm) */ -inline void sh34_base_device::MOVWS4(const uint16_t opcode) -{ - uint32_t disp = opcode & 0x0f; - m_ea = m_r[Rm] + disp * 2; - WW(m_ea, m_r[0] & 0x0000ffff ); -} - -/* MOV.L Rm,@(disp4,Rn) */ -inline void sh34_base_device::MOVLS4(const uint16_t opcode) -{ - uint32_t disp = opcode & 0x0f; - m_ea = m_r[Rn] + disp * 4; - WL(m_ea, m_r[Rm] ); -} - -/* MOV.B @(disp4,Rm),R0 */ -inline void sh34_base_device::MOVBL4(const uint16_t opcode) -{ - uint32_t disp = opcode & 0x0f; - m_ea = m_r[Rm] + disp; - m_r[0] = (uint32_t)(int32_t)(int16_t)(int8_t) RB( m_ea ); -} - -/* MOV.W @(disp4,Rm),R0 */ -inline void sh34_base_device::MOVWL4(const uint16_t opcode) -{ - uint32_t disp = opcode & 0x0f; - m_ea = m_r[Rm] + disp * 2; - m_r[0] = (uint32_t)(int32_t)(int16_t) RW(m_ea ); -} - -/* MOV.L @(disp4,Rm),Rn */ -inline void sh34_base_device::MOVLL4(const uint16_t opcode) -{ - uint32_t disp = opcode & 0x0f; - m_ea = m_r[Rm] + disp * 4; - m_r[Rn] = RL(m_ea ); -} - -/* MOVA @(disp8,PC),R0 */ -inline void sh34_base_device::MOVA(const uint16_t opcode) -{ - uint32_t disp = opcode & 0xff; - m_ea = ((m_pc + 2) & ~3) + disp * 4; - m_r[0] = m_ea; -} - -/* MOVT Rn */ -void sh34_base_device::MOVT(const uint16_t opcode) -{ - m_r[Rn] = m_sr & T; -} - -/* MUL.L Rm,Rn */ -inline void sh34_base_device::MULL(const uint16_t opcode) -{ - m_macl = m_r[Rn] * m_r[Rm]; - m_sh4_icount--; -} - -/* MULS Rm,Rn */ -inline void sh34_base_device::MULS(const uint16_t opcode) -{ - m_macl = (int16_t) m_r[Rn] * (int16_t) m_r[Rm]; -} - -/* MULU Rm,Rn */ -inline void sh34_base_device::MULU(const uint16_t opcode) -{ - m_macl = (uint16_t) m_r[Rn] * (uint16_t) m_r[Rm]; -} - -/* NEG Rm,Rn */ -inline void sh34_base_device::NEG(const uint16_t opcode) -{ - m_r[Rn] = 0 - m_r[Rm]; -} - -/* NEGC Rm,Rn */ -inline void sh34_base_device::NEGC(const uint16_t opcode) -{ - uint32_t temp; - - temp = m_r[Rm]; - m_r[Rn] = -temp - (m_sr & T); - if (temp || (m_sr & T)) - m_sr |= T; - else - m_sr &= ~T; -} - -/* NOP */ -inline void sh34_base_device::NOP(const uint16_t opcode) -{ -} - -/* NOT Rm,Rn */ -inline void sh34_base_device::NOT(const uint16_t opcode) -{ - m_r[Rn] = ~m_r[Rm]; -} - -/* OR Rm,Rn */ -inline void sh34_base_device::OR(const uint16_t opcode) -{ - m_r[Rn] |= m_r[Rm]; -} - -/* OR #imm,R0 */ -inline void sh34_base_device::ORI(const uint16_t opcode) -{ - m_r[0] |= (opcode&0xff); - m_sh4_icount -= 2; -} - -/* OR.B #imm,@(R0,GBR) */ -inline void sh34_base_device::ORM(const uint16_t opcode) -{ - uint32_t temp; - - m_ea = m_gbr + m_r[0]; - temp = RB( m_ea ); - temp |= (opcode&0xff); - WB(m_ea, temp ); -} - -/* ROTCL Rn */ -inline void sh34_base_device::ROTCL(const uint16_t opcode) -{ - uint32_t n = Rn; - - uint32_t temp; - - temp = (m_r[n] >> 31) & T; - m_r[n] = (m_r[n] << 1) | (m_sr & T); - m_sr = (m_sr & ~T) | temp; -} - -/* ROTCR Rn */ -inline void sh34_base_device::ROTCR(const uint16_t opcode) -{ - uint32_t n = Rn; - - uint32_t temp; - temp = (m_sr & T) << 31; - if (m_r[n] & T) - m_sr |= T; - else - m_sr &= ~T; - m_r[n] = (m_r[n] >> 1) | temp; -} - -/* ROTL Rn */ -inline void sh34_base_device::ROTL(const uint16_t opcode) -{ - uint32_t n = Rn; - - m_sr = (m_sr & ~T) | ((m_r[n] >> 31) & T); - m_r[n] = (m_r[n] << 1) | (m_r[n] >> 31); -} - -/* ROTR Rn */ -inline void sh34_base_device::ROTR(const uint16_t opcode) -{ - uint32_t n = Rn; - - m_sr = (m_sr & ~T) | (m_r[n] & T); - m_r[n] = (m_r[n] >> 1) | (m_r[n] << 31); -} - /* RTE */ -inline void sh34_base_device::RTE(const uint16_t opcode) +inline void sh34_base_device::RTE() { - m_delay = m_ea = m_spc; + m_sh2_state->m_delay = m_sh2_state->ea = m_spc; + if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0) - sh4_syncronize_register_bank((m_sr & sRB) >> 29); - if ((m_ssr & sRB) != (m_sr & sRB)) + sh4_syncronize_register_bank((m_sh2_state->sr & sRB) >> 29); + if ((m_ssr & sRB) != (m_sh2_state->sr & sRB)) sh4_change_register_bank(m_ssr & sRB ? 1 : 0); - m_sr = m_ssr; - m_sh4_icount--; - sh4_exception_recompute(); -} - -/* RTS */ -inline void sh34_base_device::RTS(const uint16_t opcode) -{ - m_delay = m_ea = m_pr; - m_sh4_icount--; -} - -/* SETT */ -inline void sh34_base_device::SETT(const uint16_t opcode) -{ - m_sr |= T; -} - -/* SHAL Rn (same as SHLL) */ -inline void sh34_base_device::SHAL(const uint16_t opcode) -{ - uint32_t n = Rn; - - m_sr = (m_sr & ~T) | ((m_r[n] >> 31) & T); - m_r[n] <<= 1; -} - -/* SHAR Rn */ -inline void sh34_base_device::SHAR(const uint16_t opcode) -{ - uint32_t n = Rn; - - m_sr = (m_sr & ~T) | (m_r[n] & T); - m_r[n] = (uint32_t)((int32_t)m_r[n] >> 1); -} - -/* SHLL Rn (same as SHAL) */ -inline void sh34_base_device::SHLL(const uint16_t opcode) -{ - uint32_t n = Rn; - - m_sr = (m_sr & ~T) | ((m_r[n] >> 31) & T); - m_r[n] <<= 1; -} - -/* SHLL2 Rn */ -inline void sh34_base_device::SHLL2(const uint16_t opcode) -{ - m_r[Rn] <<= 2; -} - -/* SHLL8 Rn */ -inline void sh34_base_device::SHLL8(const uint16_t opcode) -{ - m_r[Rn] <<= 8; -} - -/* SHLL16 Rn */ -inline void sh34_base_device::SHLL16(const uint16_t opcode) -{ - m_r[Rn] <<= 16; -} - -/* SHLR Rn */ -inline void sh34_base_device::SHLR(const uint16_t opcode) -{ - uint32_t n = Rn; - - m_sr = (m_sr & ~T) | (m_r[n] & T); - m_r[n] >>= 1; -} - -/* SHLR2 Rn */ -inline void sh34_base_device::SHLR2(const uint16_t opcode) -{ - m_r[Rn] >>= 2; -} - -/* SHLR8 Rn */ -inline void sh34_base_device::SHLR8(const uint16_t opcode) -{ - m_r[Rn] >>= 8; -} - -/* SHLR16 Rn */ -inline void sh34_base_device::SHLR16(const uint16_t opcode) -{ - m_r[Rn] >>= 16; -} - -/* SLEEP */ -inline void sh34_base_device::SLEEP(const uint16_t opcode) -{ - /* 0 = normal mode */ - /* 1 = enters into power-down mode */ - /* 2 = go out the power-down mode after an exception */ - if(m_sleep_mode != 2) - m_pc -= 2; - m_sh4_icount -= 2; - /* Wait_for_exception; */ - if(m_sleep_mode == 0) - m_sleep_mode = 1; - else if(m_sleep_mode == 2) - m_sleep_mode = 0; -} - -/* STC SR,Rn */ -inline void sh34_base_device::STCSR(const uint16_t opcode) -{ - m_r[Rn] = m_sr; -} - -/* STC GBR,Rn */ -inline void sh34_base_device::STCGBR(const uint16_t opcode) -{ - m_r[Rn] = m_gbr; -} - -/* STC VBR,Rn */ -inline void sh34_base_device::STCVBR(const uint16_t opcode) -{ - m_r[Rn] = m_vbr; -} - -/* STC.L SR,@-Rn */ -inline void sh34_base_device::STCMSR(const uint16_t opcode) -{ - uint32_t n = Rn; - - m_r[n] -= 4; - m_ea = m_r[n]; - WL(m_ea, m_sr ); - m_sh4_icount--; -} - -/* STC.L GBR,@-Rn */ -inline void sh34_base_device::STCMGBR(const uint16_t opcode) -{ - uint32_t n = Rn; - - m_r[n] -= 4; - m_ea = m_r[n]; - WL(m_ea, m_gbr ); - m_sh4_icount--; -} - -/* STC.L VBR,@-Rn */ -inline void sh34_base_device::STCMVBR(const uint16_t opcode) -{ - uint32_t n = Rn; - - m_r[n] -= 4; - m_ea = m_r[n]; - WL(m_ea, m_vbr ); - m_sh4_icount--; -} - -/* STS MACH,Rn */ -inline void sh34_base_device::STSMACH(const uint16_t opcode) -{ - m_r[Rn] = m_mach; -} - -/* STS MACL,Rn */ -inline void sh34_base_device::STSMACL(const uint16_t opcode) -{ - m_r[Rn] = m_macl; -} - -/* STS PR,Rn */ -inline void sh34_base_device::STSPR(const uint16_t opcode) -{ - m_r[Rn] = m_pr; -} - -/* STS.L MACH,@-Rn */ -inline void sh34_base_device::STSMMACH(const uint16_t opcode) -{ - uint32_t n = Rn; - - m_r[n] -= 4; - m_ea = m_r[n]; - WL(m_ea, m_mach ); -} - -/* STS.L MACL,@-Rn */ -inline void sh34_base_device::STSMMACL(const uint16_t opcode) -{ - uint32_t n = Rn; - - m_r[n] -= 4; - m_ea = m_r[n]; - WL(m_ea, m_macl ); -} - -/* STS.L PR,@-Rn */ -inline void sh34_base_device::STSMPR(const uint16_t opcode) -{ - uint32_t n = Rn; - - m_r[n] -= 4; - m_ea = m_r[n]; - WL(m_ea, m_pr ); -} - -/* SUB Rm,Rn */ -inline void sh34_base_device::SUB(const uint16_t opcode) -{ - m_r[Rn] -= m_r[Rm]; -} - -/* SUBC Rm,Rn */ -inline void sh34_base_device::SUBC(const uint16_t opcode) -{ - uint32_t m = Rm; uint32_t n = Rn; - - uint32_t tmp0, tmp1; - - tmp1 = m_r[n] - m_r[m]; - tmp0 = m_r[n]; - m_r[n] = tmp1 - (m_sr & T); - if (tmp0 < tmp1) - m_sr |= T; - else - m_sr &= ~T; - if (tmp1 < m_r[n]) - m_sr |= T; -} - -/* SUBV Rm,Rn */ -inline void sh34_base_device::SUBV(const uint16_t opcode) -{ - uint32_t m = Rm; uint32_t n = Rn; - - int32_t dest, src, ans; - - if ((int32_t) m_r[n] >= 0) - dest = 0; - else - dest = 1; - if ((int32_t) m_r[m] >= 0) - src = 0; - else - src = 1; - src += dest; - m_r[n] -= m_r[m]; - if ((int32_t) m_r[n] >= 0) - ans = 0; - else - ans = 1; - ans += dest; - if (src == 1) - { - if (ans == 1) - m_sr |= T; - else - m_sr &= ~T; - } - else - m_sr &= ~T; -} - -/* SWAP.B Rm,Rn */ -inline void sh34_base_device::SWAPB(const uint16_t opcode) -{ - uint32_t m = Rm; uint32_t n = Rn; - - uint32_t temp0, temp1; - - temp0 = m_r[m] & 0xffff0000; - temp1 = (m_r[m] & 0x000000ff) << 8; - m_r[n] = (m_r[m] >> 8) & 0x000000ff; - m_r[n] = m_r[n] | temp1 | temp0; -} - -/* SWAP.W Rm,Rn */ -inline void sh34_base_device::SWAPW(const uint16_t opcode) -{ - uint32_t m = Rm; uint32_t n = Rn; - - uint32_t temp; - temp = (m_r[m] >> 16) & 0x0000ffff; - m_r[n] = (m_r[m] << 16) | temp; -} - -/* TAS.B @Rn */ -inline void sh34_base_device::TAS(const uint16_t opcode) -{ - uint32_t n = Rn; - - uint32_t temp; - m_ea = m_r[n]; - /* Bus Lock enable */ - temp = RB( m_ea ); - if (temp == 0) - m_sr |= T; - else - m_sr &= ~T; - temp |= 0x80; - /* Bus Lock disable */ - WB(m_ea, temp ); - m_sh4_icount -= 3; + m_sh2_state->sr = m_ssr; + m_sh2_state->icount--; + sh4_exception_recompute(); } /* TRAPA #imm */ -inline void sh34_base_device::TRAPA(const uint16_t opcode) +inline void sh34_base_device::TRAPA(uint32_t i) { - uint32_t imm = opcode & 0xff; + uint32_t imm = i & 0xff; if (m_cpu_type == CPU_TYPE_SH4) { @@ -2136,18 +500,18 @@ inline void sh34_base_device::TRAPA(const uint16_t opcode) m_sh3internal_upper[SH3_TRA_ADDR] = imm << 2; } + m_ssr = m_sh2_state->sr; + m_spc = m_sh2_state->pc; - m_ssr = m_sr; - m_spc = m_pc; - m_sgr = m_r[15]; + m_sgr = m_sh2_state->r[15]; - m_sr |= MD; + m_sh2_state->sr |= MD; if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0) - sh4_syncronize_register_bank((m_sr & sRB) >> 29); - if (!(m_sr & sRB)) + sh4_syncronize_register_bank((m_sh2_state->sr & sRB) >> 29); + if (!(m_sh2_state->sr & sRB)) sh4_change_register_bank(1); - m_sr |= sRB; - m_sr |= BL; + m_sh2_state->sr |= sRB; + m_sh2_state->sr |= BL; sh4_exception_recompute(); if (m_cpu_type == CPU_TYPE_SH4) @@ -2159,116 +523,9 @@ inline void sh34_base_device::TRAPA(const uint16_t opcode) m_sh3internal_upper[SH3_EXPEVT_ADDR] = 0x00000160; } - m_pc = m_vbr + 0x00000100; - - m_sh4_icount -= 7; -} - -/* TST Rm,Rn */ -inline void sh34_base_device::TST(const uint16_t opcode) -{ - if ((m_r[Rn] & m_r[Rm]) == 0) - m_sr |= T; - else - m_sr &= ~T; -} - -/* TST #imm,R0 */ -inline void sh34_base_device::TSTI(const uint16_t opcode) -{ - uint32_t imm = opcode & 0xff; - - if ((imm & m_r[0]) == 0) - m_sr |= T; - else - m_sr &= ~T; -} - -/* TST.B #imm,@(R0,GBR) */ -inline void sh34_base_device::TSTM(const uint16_t opcode) -{ - uint32_t imm = opcode & 0xff; - - m_ea = m_gbr + m_r[0]; - if ((imm & RB( m_ea )) == 0) - m_sr |= T; - else - m_sr &= ~T; - m_sh4_icount -= 2; -} + m_sh2_state->pc = m_sh2_state->vbr + 0x00000100; -/* XOR Rm,Rn */ -inline void sh34_base_device::XOR(const uint16_t opcode) -{ - m_r[Rn] ^= m_r[Rm]; -} - -/* XOR #imm,R0 */ -inline void sh34_base_device::XORI(const uint16_t opcode) -{ - uint32_t imm = opcode & 0xff; - m_r[0] ^= imm; -} - -/* XOR.B #imm,@(R0,GBR) */ -inline void sh34_base_device::XORM(const uint16_t opcode) -{ - uint32_t imm = opcode & 0xff; - uint32_t temp; - - m_ea = m_gbr + m_r[0]; - temp = RB( m_ea ); - temp ^= imm; - WB(m_ea, temp ); - m_sh4_icount -= 2; -} - -/* XTRCT Rm,Rn */ -inline void sh34_base_device::XTRCT(const uint16_t opcode) -{ - uint32_t m = Rm; uint32_t n = Rn; - - uint32_t temp; - - temp = (m_r[m] << 16) & 0xffff0000; - m_r[n] = (m_r[n] >> 16) & 0x0000ffff; - m_r[n] |= temp; -} - -/* STC SSR,Rn */ -inline void sh34_base_device::STCSSR(const uint16_t opcode) -{ - m_r[Rn] = m_ssr; -} - -/* STC SPC,Rn */ -inline void sh34_base_device::STCSPC(const uint16_t opcode) -{ - m_r[Rn] = m_spc; -} - -/* STC SGR,Rn */ -inline void sh34_base_device::STCSGR(const uint16_t opcode) -{ - m_r[Rn] = m_sgr; -} - -/* STS FPUL,Rn */ -inline void sh34_base_device::STSFPUL(const uint16_t opcode) -{ - m_r[Rn] = m_fpul; -} - -/* STS FPSCR,Rn */ -inline void sh34_base_device::STSFPSCR(const uint16_t opcode) -{ - m_r[Rn] = m_fpscr & 0x003FFFFF; -} - -/* STC DBR,Rn */ -inline void sh34_base_device::STCDBR(const uint16_t opcode) -{ - m_r[Rn] = m_dbr; + m_sh2_state->icount -= 7; } /* STCRBANK Rm_BANK,Rn */ @@ -2276,7 +533,7 @@ inline void sh34_base_device::STCRBANK(const uint16_t opcode) { uint32_t m = Rm; - m_r[Rn] = m_rbnk[m_sr&sRB ? 0 : 1][m & 7]; + m_sh2_state->r[Rn] = m_rbnk[m_sh2_state->sr&sRB ? 0 : 1][m & 7]; } /* STCMRBANK Rm_BANK,@-Rn */ @@ -2284,27 +541,10 @@ inline void sh34_base_device::STCMRBANK(const uint16_t opcode) { uint32_t m = Rm; uint32_t n = Rn; - m_r[n] -= 4; - m_ea = m_r[n]; - WL(m_ea, m_rbnk[m_sr&sRB ? 0 : 1][m & 7]); - m_sh4_icount--; -} - -/* MOVCA.L R0,@Rn */ -inline void sh34_base_device::MOVCAL(const uint16_t opcode) -{ - m_ea = m_r[Rn]; - WL(m_ea, m_r[0] ); -} - -inline void sh34_base_device::CLRS(const uint16_t opcode) -{ - m_sr &= ~S; -} - -inline void sh34_base_device::SETS(const uint16_t opcode) -{ - m_sr |= S; + m_sh2_state->r[n] -= 4; + m_sh2_state->ea = m_sh2_state->r[n]; + WL(m_sh2_state->ea, m_rbnk[m_sh2_state->sr&sRB ? 0 : 1][m & 7]); + m_sh2_state->icount--; } /* STS.L SGR,@-Rn */ @@ -2312,9 +552,9 @@ inline void sh34_base_device::STCMSGR(const uint16_t opcode) { uint32_t n = Rn; - m_r[n] -= 4; - m_ea = m_r[n]; - WL(m_ea, m_sgr ); + m_sh2_state->r[n] -= 4; + m_sh2_state->ea = m_sh2_state->r[n]; + WL(m_sh2_state->ea, m_sgr); } /* STS.L FPUL,@-Rn */ @@ -2322,9 +562,9 @@ inline void sh34_base_device::STSMFPUL(const uint16_t opcode) { uint32_t n = Rn; - m_r[n] -= 4; - m_ea = m_r[n]; - WL(m_ea, m_fpul ); + m_sh2_state->r[n] -= 4; + m_sh2_state->ea = m_sh2_state->r[n]; + WL(m_sh2_state->ea, m_fpul); } /* STS.L FPSCR,@-Rn */ @@ -2332,9 +572,9 @@ inline void sh34_base_device::STSMFPSCR(const uint16_t opcode) { uint32_t n = Rn; - m_r[n] -= 4; - m_ea = m_r[n]; - WL(m_ea, m_fpscr & 0x003FFFFF); + m_sh2_state->r[n] -= 4; + m_sh2_state->ea = m_sh2_state->r[n]; + WL(m_sh2_state->ea, m_fpscr & 0x003FFFFF); } /* STC.L DBR,@-Rn */ @@ -2342,9 +582,9 @@ inline void sh34_base_device::STCMDBR(const uint16_t opcode) { uint32_t n = Rn; - m_r[n] -= 4; - m_ea = m_r[n]; - WL(m_ea, m_dbr ); + m_sh2_state->r[n] -= 4; + m_sh2_state->ea = m_sh2_state->r[n]; + WL(m_sh2_state->ea, m_dbr); } /* STC.L SSR,@-Rn */ @@ -2352,9 +592,9 @@ inline void sh34_base_device::STCMSSR(const uint16_t opcode) { uint32_t n = Rn; - m_r[n] -= 4; - m_ea = m_r[n]; - WL(m_ea, m_ssr ); + m_sh2_state->r[n] -= 4; + m_sh2_state->ea = m_sh2_state->r[n]; + WL(m_sh2_state->ea, m_ssr); } /* STC.L SPC,@-Rn */ @@ -2362,17 +602,17 @@ inline void sh34_base_device::STCMSPC(const uint16_t opcode) { uint32_t n = Rn; - m_r[n] -= 4; - m_ea = m_r[n]; - WL(m_ea, m_spc ); + m_sh2_state->r[n] -= 4; + m_sh2_state->ea = m_sh2_state->r[n]; + WL(m_sh2_state->ea, m_spc); } /* LDS.L @Rm+,FPUL */ inline void sh34_base_device::LDSMFPUL(const uint16_t opcode) { - m_ea = m_r[Rn]; - m_fpul = RL(m_ea ); - m_r[Rn] += 4; + m_sh2_state->ea = m_sh2_state->r[Rn]; + m_fpul = RL(m_sh2_state->ea); + m_sh2_state->r[Rn] += 4; } /* LDS.L @Rm+,FPSCR */ @@ -2381,10 +621,10 @@ inline void sh34_base_device::LDSMFPSCR(const uint16_t opcode) uint32_t s; s = m_fpscr; - m_ea = m_r[Rn]; - m_fpscr = RL(m_ea ); + m_sh2_state->ea = m_sh2_state->r[Rn]; + m_fpscr = RL(m_sh2_state->ea); m_fpscr &= 0x003FFFFF; - m_r[Rn] += 4; + m_sh2_state->r[Rn] += 4; if ((s & FR) != (m_fpscr & FR)) sh4_swap_fp_registers(); #ifdef LSB_FIRST @@ -2398,9 +638,9 @@ inline void sh34_base_device::LDSMFPSCR(const uint16_t opcode) /* LDC.L @Rm+,DBR */ inline void sh34_base_device::LDCMDBR(const uint16_t opcode) { - m_ea = m_r[Rn]; - m_dbr = RL(m_ea ); - m_r[Rn] += 4; + m_sh2_state->ea = m_sh2_state->r[Rn]; + m_dbr = RL(m_sh2_state->ea); + m_sh2_state->r[Rn] += 4; } /* LDC.L @Rn+,Rm_BANK */ @@ -2408,31 +648,31 @@ inline void sh34_base_device::LDCMRBANK(const uint16_t opcode) { uint32_t m = Rm; uint32_t n = Rn; - m_ea = m_r[n]; - m_rbnk[m_sr&sRB ? 0 : 1][m & 7] = RL(m_ea ); - m_r[n] += 4; + m_sh2_state->ea = m_sh2_state->r[n]; + m_rbnk[m_sh2_state->sr&sRB ? 0 : 1][m & 7] = RL(m_sh2_state->ea); + m_sh2_state->r[n] += 4; } /* LDC.L @Rm+,SSR */ inline void sh34_base_device::LDCMSSR(const uint16_t opcode) { - m_ea = m_r[Rn]; - m_ssr = RL(m_ea ); - m_r[Rn] += 4; + m_sh2_state->ea = m_sh2_state->r[Rn]; + m_ssr = RL(m_sh2_state->ea); + m_sh2_state->r[Rn] += 4; } /* LDC.L @Rm+,SPC */ inline void sh34_base_device::LDCMSPC(const uint16_t opcode) { - m_ea = m_r[Rn]; - m_spc = RL(m_ea ); - m_r[Rn] += 4; + m_sh2_state->ea = m_sh2_state->r[Rn]; + m_spc = RL(m_sh2_state->ea); + m_sh2_state->r[Rn] += 4; } /* LDS Rm,FPUL */ inline void sh34_base_device::LDSFPUL(const uint16_t opcode) { - m_fpul = m_r[Rn]; + m_fpul = m_sh2_state->r[Rn]; } /* LDS Rm,FPSCR */ @@ -2441,7 +681,7 @@ inline void sh34_base_device::LDSFPSCR(const uint16_t opcode) uint32_t s; s = m_fpscr; - m_fpscr = m_r[Rn] & 0x003FFFFF; + m_fpscr = m_sh2_state->r[Rn] & 0x003FFFFF; if ((s & FR) != (m_fpscr & FR)) sh4_swap_fp_registers(); #ifdef LSB_FIRST @@ -2455,7 +695,44 @@ inline void sh34_base_device::LDSFPSCR(const uint16_t opcode) /* LDC Rm,DBR */ inline void sh34_base_device::LDCDBR(const uint16_t opcode) { - m_dbr = m_r[Rn]; + m_dbr = m_sh2_state->r[Rn]; +} + + +/* STC SSR,Rn */ +inline void sh34_base_device::STCSSR(const uint16_t opcode) +{ + m_sh2_state->r[Rn] = m_ssr; +} + +/* STC SPC,Rn */ +inline void sh34_base_device::STCSPC(const uint16_t opcode) +{ + m_sh2_state->r[Rn] = m_spc; +} + +/* STC SGR,Rn */ +inline void sh34_base_device::STCSGR(const uint16_t opcode) +{ + m_sh2_state->r[Rn] = m_sgr; +} + +/* STS FPUL,Rn */ +inline void sh34_base_device::STSFPUL(const uint16_t opcode) +{ + m_sh2_state->r[Rn] = m_fpul; +} + +/* STS FPSCR,Rn */ +inline void sh34_base_device::STSFPSCR(const uint16_t opcode) +{ + m_sh2_state->r[Rn] = m_fpscr & 0x003FFFFF; +} + +/* STC DBR,Rn */ +inline void sh34_base_device::STCDBR(const uint16_t opcode) +{ + m_sh2_state->r[Rn] = m_dbr; } /* SHAD Rm,Rn */ @@ -2463,15 +740,16 @@ inline void sh34_base_device::SHAD(const uint16_t opcode) { uint32_t m = Rm; uint32_t n = Rn; - if ((m_r[m] & 0x80000000) == 0) - m_r[n] = m_r[n] << (m_r[m] & 0x1F); - else if ((m_r[m] & 0x1F) == 0) { - if ((m_r[n] & 0x80000000) == 0) - m_r[n] = 0; + if ((m_sh2_state->r[m] & 0x80000000) == 0) + m_sh2_state->r[n] = m_sh2_state->r[n] << (m_sh2_state->r[m] & 0x1F); + else if ((m_sh2_state->r[m] & 0x1F) == 0) { + if ((m_sh2_state->r[n] & 0x80000000) == 0) + m_sh2_state->r[n] = 0; else - m_r[n] = 0xFFFFFFFF; - } else - m_r[n]=(int32_t)m_r[n] >> ((~m_r[m] & 0x1F)+1); + m_sh2_state->r[n] = 0xFFFFFFFF; + } + else + m_sh2_state->r[n] = (int32_t)m_sh2_state->r[n] >> ((~m_sh2_state->r[m] & 0x1F) + 1); } /* SHLD Rm,Rn */ @@ -2479,12 +757,12 @@ inline void sh34_base_device::SHLD(const uint16_t opcode) { uint32_t m = Rm; uint32_t n = Rn; - if ((m_r[m] & 0x80000000) == 0) - m_r[n] = m_r[n] << (m_r[m] & 0x1F); - else if ((m_r[m] & 0x1F) == 0) - m_r[n] = 0; + if ((m_sh2_state->r[m] & 0x80000000) == 0) + m_sh2_state->r[n] = m_sh2_state->r[n] << (m_sh2_state->r[m] & 0x1F); + else if ((m_sh2_state->r[m] & 0x1F) == 0) + m_sh2_state->r[n] = 0; else - m_r[n] = m_r[n] >> ((~m_r[m] & 0x1F)+1); + m_sh2_state->r[n] = m_sh2_state->r[n] >> ((~m_sh2_state->r[m] & 0x1F) + 1); } /* LDCRBANK Rn,Rm_BANK */ @@ -2492,28 +770,28 @@ inline void sh34_base_device::LDCRBANK(const uint16_t opcode) { uint32_t m = Rm; - m_rbnk[m_sr&sRB ? 0 : 1][m & 7] = m_r[Rn]; + m_rbnk[m_sh2_state->sr&sRB ? 0 : 1][m & 7] = m_sh2_state->r[Rn]; } /* LDC Rm,SSR */ inline void sh34_base_device::LDCSSR(const uint16_t opcode) { - m_ssr = m_r[Rn]; + m_ssr = m_sh2_state->r[Rn]; } /* LDC Rm,SPC */ inline void sh34_base_device::LDCSPC(const uint16_t opcode) { - m_spc = m_r[Rn]; + m_spc = m_sh2_state->r[Rn]; } /* PREF @Rn */ inline void sh34_base_device::PREFM(const uint16_t opcode) { int a; - uint32_t addr,dest,sq; + uint32_t addr, dest, sq; - addr = m_r[Rn]; // address + addr = m_sh2_state->r[Rn]; // address if ((addr >= 0xE0000000) && (addr <= 0xE3FFFFFF)) { if (m_sh4_mmu_enabled) @@ -2582,28 +860,30 @@ inline void sh34_base_device::FMOVMRIFR(const uint16_t opcode) #ifdef LSB_FIRST n ^= m_fpu_pr; #endif - m_ea = m_r[m]; - m_xf[n] = RL(m_ea ); - m_r[m] += 4; - m_xf[n^1] = RL(m_ea+4 ); - m_r[m] += 4; - } else { + m_sh2_state->ea = m_sh2_state->r[m]; + m_xf[n] = RL(m_sh2_state->ea); + m_sh2_state->r[m] += 4; + m_xf[n ^ 1] = RL(m_sh2_state->ea + 4); + m_sh2_state->r[m] += 4; + } + else { #ifdef LSB_FIRST n ^= m_fpu_pr; #endif - m_ea = m_r[m]; - m_fr[n] = RL(m_ea ); - m_r[m] += 4; - m_fr[n^1] = RL(m_ea+4 ); - m_r[m] += 4; + m_sh2_state->ea = m_sh2_state->r[m]; + m_fr[n] = RL(m_sh2_state->ea); + m_sh2_state->r[m] += 4; + m_fr[n ^ 1] = RL(m_sh2_state->ea + 4); + m_sh2_state->r[m] += 4; } - } else { /* SZ = 0 */ - m_ea = m_r[m]; + } + else { /* SZ = 0 */ + m_sh2_state->ea = m_sh2_state->r[m]; #ifdef LSB_FIRST n ^= m_fpu_pr; #endif - m_fr[n] = RL(m_ea ); - m_r[m] += 4; + m_fr[n] = RL(m_sh2_state->ea); + m_sh2_state->r[m] += 4; } } @@ -2621,23 +901,25 @@ inline void sh34_base_device::FMOVFRMR(const uint16_t opcode) #ifdef LSB_FIRST m ^= m_fpu_pr; #endif - m_ea = m_r[n]; - WL(m_ea,m_xf[m] ); - WL(m_ea+4,m_xf[m^1] ); - } else { + m_sh2_state->ea = m_sh2_state->r[n]; + WL(m_sh2_state->ea, m_xf[m]); + WL(m_sh2_state->ea + 4, m_xf[m ^ 1]); + } + else { #ifdef LSB_FIRST m ^= m_fpu_pr; #endif - m_ea = m_r[n]; - WL(m_ea,m_fr[m] ); - WL(m_ea+4,m_fr[m^1] ); + m_sh2_state->ea = m_sh2_state->r[n]; + WL(m_sh2_state->ea, m_fr[m]); + WL(m_sh2_state->ea + 4, m_fr[m ^ 1]); } - } else { /* SZ = 0 */ - m_ea = m_r[n]; + } + else { /* SZ = 0 */ + m_sh2_state->ea = m_sh2_state->r[n]; #ifdef LSB_FIRST m ^= m_fpu_pr; #endif - WL(m_ea,m_fr[m] ); + WL(m_sh2_state->ea, m_fr[m]); } } @@ -2655,26 +937,28 @@ inline void sh34_base_device::FMOVFRMDR(const uint16_t opcode) #ifdef LSB_FIRST m ^= m_fpu_pr; #endif - m_r[n] -= 8; - m_ea = m_r[n]; - WL(m_ea,m_xf[m] ); - WL(m_ea+4,m_xf[m^1] ); - } else { + m_sh2_state->r[n] -= 8; + m_sh2_state->ea = m_sh2_state->r[n]; + WL(m_sh2_state->ea, m_xf[m]); + WL(m_sh2_state->ea + 4, m_xf[m ^ 1]); + } + else { #ifdef LSB_FIRST m ^= m_fpu_pr; #endif - m_r[n] -= 8; - m_ea = m_r[n]; - WL(m_ea,m_fr[m] ); - WL(m_ea+4,m_fr[m^1] ); + m_sh2_state->r[n] -= 8; + m_sh2_state->ea = m_sh2_state->r[n]; + WL(m_sh2_state->ea, m_fr[m]); + WL(m_sh2_state->ea + 4, m_fr[m ^ 1]); } - } else { /* SZ = 0 */ - m_r[n] -= 4; - m_ea = m_r[n]; + } + else { /* SZ = 0 */ + m_sh2_state->r[n] -= 4; + m_sh2_state->ea = m_sh2_state->r[n]; #ifdef LSB_FIRST m ^= m_fpu_pr; #endif - WL(m_ea,m_fr[m] ); + WL(m_sh2_state->ea, m_fr[m]); } } @@ -2692,23 +976,25 @@ inline void sh34_base_device::FMOVFRS0(const uint16_t opcode) #ifdef LSB_FIRST m ^= m_fpu_pr; #endif - m_ea = m_r[0] + m_r[n]; - WL(m_ea,m_xf[m] ); - WL(m_ea+4,m_xf[m^1] ); - } else { + m_sh2_state->ea = m_sh2_state->r[0] + m_sh2_state->r[n]; + WL(m_sh2_state->ea, m_xf[m]); + WL(m_sh2_state->ea + 4, m_xf[m ^ 1]); + } + else { #ifdef LSB_FIRST m ^= m_fpu_pr; #endif - m_ea = m_r[0] + m_r[n]; - WL(m_ea,m_fr[m] ); - WL(m_ea+4,m_fr[m^1] ); + m_sh2_state->ea = m_sh2_state->r[0] + m_sh2_state->r[n]; + WL(m_sh2_state->ea, m_fr[m]); + WL(m_sh2_state->ea + 4, m_fr[m ^ 1]); } - } else { /* SZ = 0 */ - m_ea = m_r[0] + m_r[n]; + } + else { /* SZ = 0 */ + m_sh2_state->ea = m_sh2_state->r[0] + m_sh2_state->r[n]; #ifdef LSB_FIRST m ^= m_fpu_pr; #endif - WL(m_ea,m_fr[m] ); + WL(m_sh2_state->ea, m_fr[m]); } } @@ -2726,23 +1012,25 @@ inline void sh34_base_device::FMOVS0FR(const uint16_t opcode) #ifdef LSB_FIRST n ^= m_fpu_pr; #endif - m_ea = m_r[0] + m_r[m]; - m_xf[n] = RL(m_ea ); - m_xf[n^1] = RL(m_ea+4 ); - } else { + m_sh2_state->ea = m_sh2_state->r[0] + m_sh2_state->r[m]; + m_xf[n] = RL(m_sh2_state->ea); + m_xf[n ^ 1] = RL(m_sh2_state->ea + 4); + } + else { #ifdef LSB_FIRST n ^= m_fpu_pr; #endif - m_ea = m_r[0] + m_r[m]; - m_fr[n] = RL(m_ea ); - m_fr[n^1] = RL(m_ea+4 ); + m_sh2_state->ea = m_sh2_state->r[0] + m_sh2_state->r[m]; + m_fr[n] = RL(m_sh2_state->ea); + m_fr[n ^ 1] = RL(m_sh2_state->ea + 4); } - } else { /* SZ = 0 */ - m_ea = m_r[0] + m_r[m]; + } + else { /* SZ = 0 */ + m_sh2_state->ea = m_sh2_state->r[0] + m_sh2_state->r[m]; #ifdef LSB_FIRST n ^= m_fpu_pr; #endif - m_fr[n] = RL(m_ea ); + m_fr[n] = RL(m_sh2_state->ea); } } @@ -2761,23 +1049,25 @@ inline void sh34_base_device::FMOVMRFR(const uint16_t opcode) #ifdef LSB_FIRST n ^= m_fpu_pr; #endif - m_ea = m_r[m]; - m_xf[n] = RL(m_ea ); - m_xf[n^1] = RL(m_ea+4 ); - } else { + m_sh2_state->ea = m_sh2_state->r[m]; + m_xf[n] = RL(m_sh2_state->ea); + m_xf[n ^ 1] = RL(m_sh2_state->ea + 4); + } + else { #ifdef LSB_FIRST n ^= m_fpu_pr; #endif - m_ea = m_r[m]; - m_fr[n] = RL(m_ea ); - m_fr[n^1] = RL(m_ea+4 ); + m_sh2_state->ea = m_sh2_state->r[m]; + m_fr[n] = RL(m_sh2_state->ea); + m_fr[n ^ 1] = RL(m_sh2_state->ea + 4); } - } else { /* SZ = 0 */ - m_ea = m_r[m]; + } + else { /* SZ = 0 */ + m_sh2_state->ea = m_sh2_state->r[m]; #ifdef LSB_FIRST n ^= m_fpu_pr; #endif - m_fr[n] = RL(m_ea ); + m_fr[n] = RL(m_sh2_state->ea); } } @@ -2790,7 +1080,7 @@ inline void sh34_base_device::FMOVFR(const uint16_t opcode) { uint32_t m = Rm; uint32_t n = Rn; - if (m_fpu_sz == 0) { /* SZ = 0 */ + if (m_fpu_sz == 0) { /* SZ = 0 */ #ifdef LSB_FIRST n ^= m_fpu_pr; m ^= m_fpu_pr; @@ -2802,15 +1092,18 @@ inline void sh34_base_device::FMOVFR(const uint16_t opcode) if (n & 1) { m_xf[n & 14] = m_xf[m & 14]; m_xf[n | 1] = m_xf[m | 1]; - } else { + } + else { m_fr[n] = m_xf[m & 14]; m_fr[n | 1] = m_xf[m | 1]; } - } else { + } + else { if (n & 1) { m_xf[n & 14] = m_fr[m]; m_xf[n | 1] = m_fr[m | 1]; // (a&14)+1 -> a|1 - } else { + } + else { m_fr[n] = m_fr[m]; m_fr[n | 1] = m_fr[m | 1]; } @@ -2839,7 +1132,7 @@ inline void sh34_base_device::FLDI0(const uint16_t opcode) } /* FLDS FRm,FPUL 1111mmmm00011101 */ -inline void sh34_base_device:: FLDS(const uint16_t opcode) +inline void sh34_base_device::FLDS(const uint16_t opcode) { #ifdef LSB_FIRST m_fpul = m_fr[Rn ^ m_fpu_pr]; @@ -2849,7 +1142,7 @@ inline void sh34_base_device:: FLDS(const uint16_t opcode) } /* FSTS FPUL,FRn 1111nnnn00001101 */ -inline void sh34_base_device:: FSTS(const uint16_t opcode) +inline void sh34_base_device::FSTS(const uint16_t opcode) { #ifdef LSB_FIRST m_fr[Rn ^ m_fpu_pr] = m_fpul; @@ -2879,13 +1172,14 @@ inline void sh34_base_device::FTRC(const uint16_t opcode) uint32_t n = Rn; if (m_fpu_pr) { /* PR = 1 */ - if(n & 1) - fatalerror("SH-4: FTRC opcode used with n %d",n); + if (n & 1) + fatalerror("SH-4: FTRC opcode used with n %d", n); n = n & 14; *((int32_t *)&m_fpul) = (int32_t)FP_RFD(n); - } else { /* PR = 0 */ - /* read m_fr[n] as float -> truncate -> fpul(32) */ + } + else { /* PR = 0 */ + /* read m_fr[n] as float -> truncate -> fpul(32) */ *((int32_t *)&m_fpul) = (int32_t)FP_RFS(n); } } @@ -2897,12 +1191,13 @@ inline void sh34_base_device::FLOAT(const uint16_t opcode) uint32_t n = Rn; if (m_fpu_pr) { /* PR = 1 */ - if(n & 1) - fatalerror("SH-4: FLOAT opcode used with n %d",n); + if (n & 1) + fatalerror("SH-4: FLOAT opcode used with n %d", n); n = n & 14; FP_RFD(n) = (double)*((int32_t *)&m_fpul); - } else { /* PR = 0 */ + } + else { /* PR = 0 */ FP_RFS(n) = (float)*((int32_t *)&m_fpul); } } @@ -2915,7 +1210,8 @@ inline void sh34_base_device::FNEG(const uint16_t opcode) if (m_fpu_pr) { /* PR = 1 */ FP_RFD(n) = -FP_RFD(n); - } else { /* PR = 0 */ + } + else { /* PR = 0 */ FP_RFS(n) = -FP_RFS(n); } } @@ -2934,7 +1230,8 @@ inline void sh34_base_device::FABS(const uint16_t opcode) n = n & 14; m_fr[n] = m_fr[n] & 0x7fffffff; #endif - } else { /* PR = 0 */ + } + else { /* PR = 0 */ m_fr[n] = m_fr[n] & 0x7fffffff; } } @@ -2949,14 +1246,15 @@ inline void sh34_base_device::FCMP_EQ(const uint16_t opcode) n = n & 14; m = m & 14; if (FP_RFD(n) == FP_RFD(m)) - m_sr |= T; + m_sh2_state->sr |= SH_T; else - m_sr &= ~T; - } else { /* PR = 0 */ + m_sh2_state->sr &= ~SH_T; + } + else { /* PR = 0 */ if (FP_RFS(n) == FP_RFS(m)) - m_sr |= T; + m_sh2_state->sr |= SH_T; else - m_sr &= ~T; + m_sh2_state->sr &= ~SH_T; } } @@ -2970,14 +1268,15 @@ inline void sh34_base_device::FCMP_GT(const uint16_t opcode) n = n & 14; m = m & 14; if (FP_RFD(n) > FP_RFD(m)) - m_sr |= T; + m_sh2_state->sr |= SH_T; else - m_sr &= ~T; - } else { /* PR = 0 */ + m_sh2_state->sr &= ~SH_T; + } + else { /* PR = 0 */ if (FP_RFS(n) > FP_RFS(m)) - m_sr |= T; + m_sh2_state->sr |= SH_T; else - m_sr &= ~T; + m_sh2_state->sr &= ~SH_T; } } @@ -2989,7 +1288,7 @@ inline void sh34_base_device::FCNVDS(const uint16_t opcode) if (m_fpu_pr) { /* PR = 1 */ n = n & 14; if (m_fpscr & RM) - m_fr[n | NATIVE_ENDIAN_VALUE_LE_BE(0,1)] &= 0xe0000000; /* round toward zero*/ + m_fr[n | NATIVE_ENDIAN_VALUE_LE_BE(0, 1)] &= 0xe0000000; /* round toward zero*/ *((float *)&m_fpul) = (float)FP_RFD(n); } } @@ -3015,7 +1314,8 @@ inline void sh34_base_device::FADD(const uint16_t opcode) n = n & 14; m = m & 14; FP_RFD(n) = FP_RFD(n) + FP_RFD(m); - } else { /* PR = 0 */ + } + else { /* PR = 0 */ FP_RFS(n) = FP_RFS(n) + FP_RFS(m); } } @@ -3030,7 +1330,8 @@ inline void sh34_base_device::FSUB(const uint16_t opcode) n = n & 14; m = m & 14; FP_RFD(n) = FP_RFD(n) - FP_RFD(m); - } else { /* PR = 0 */ + } + else { /* PR = 0 */ FP_RFS(n) = FP_RFS(n) - FP_RFS(m); } } @@ -3046,7 +1347,8 @@ inline void sh34_base_device::FMUL(const uint16_t opcode) n = n & 14; m = m & 14; FP_RFD(n) = FP_RFD(n) * FP_RFD(m); - } else { /* PR = 0 */ + } + else { /* PR = 0 */ FP_RFS(n) = FP_RFS(n) * FP_RFS(m); } } @@ -3063,7 +1365,8 @@ inline void sh34_base_device::FDIV(const uint16_t opcode) if (FP_RFD(m) == 0) return; FP_RFD(n) = FP_RFD(n) / FP_RFD(m); - } else { /* PR = 0 */ + } + else { /* PR = 0 */ if (FP_RFS(m) == 0) return; FP_RFS(n) = FP_RFS(n) / FP_RFS(m); @@ -3091,7 +1394,8 @@ inline void sh34_base_device::FSQRT(const uint16_t opcode) if (FP_RFD(n) < 0) return; FP_RFD(n) = sqrtf(FP_RFD(n)); - } else { /* PR = 0 */ + } + else { /* PR = 0 */ if (FP_RFS(n) < 0) return; FP_RFS(n) = sqrtf(FP_RFS(n)); @@ -3115,9 +1419,9 @@ void sh34_base_device::FSSCA(const uint16_t opcode) float angle; - angle = (((float)(m_fpul & 0xFFFF)) / 65536.0f) * 2.0f * (float) M_PI; + angle = (((float)(m_fpul & 0xFFFF)) / 65536.0f) * 2.0f * (float)M_PI; FP_RFS(n) = sinf(angle); - FP_RFS(n+1) = cosf(angle); + FP_RFS(n + 1) = cosf(angle); } /* FIPR FVm,FVn PR=0 1111nnmm11101101 */ @@ -3125,15 +1429,15 @@ inline void sh34_base_device::FIPR(const uint16_t opcode) { uint32_t n = Rn; -uint32_t m; -float ml[4]; -int a; + uint32_t m; + float ml[4]; + int a; m = (n & 3) << 2; n = n & 12; for (a = 0;a < 4;a++) - ml[a] = FP_RFS(n+a) * FP_RFS(m+a); - FP_RFS(n+3) = ml[0] + ml[1] + ml[2] + ml[3]; + ml[a] = FP_RFS(n + a) * FP_RFS(m + a); + FP_RFS(n + 3) = ml[0] + ml[1] + ml[2] + ml[3]; } /* FTRV XMTRX,FVn PR=0 1111nn0111111101 */ @@ -3141,13 +1445,13 @@ void sh34_base_device::FTRV(const uint16_t opcode) { uint32_t n = Rn; -int i,j; -float sum[4]; + int i, j; + float sum[4]; n = n & 12; for (i = 0;i < 4;i++) { sum[i] = 0; - for (j=0;j < 4;j++) + for (j = 0;j < 4;j++) sum[i] += FP_XFS((j << 2) + i)*FP_RFS(n + j); } for (i = 0;i < 4;i++) @@ -3157,25 +1461,27 @@ float sum[4]; inline void sh34_base_device::op1111_0xf13(const uint16_t opcode) { if (opcode & 0x100) { - if (opcode & 0x200) { - switch (opcode & 0xC00) - { - case 0x000: - FSCHG(); - break; - case 0x800: - FRCHG(); - break; - default: - machine().debug_break(); - break; - } - } else { - FTRV(opcode); + if (opcode & 0x200) { + switch (opcode & 0xC00) + { + case 0x000: + FSCHG(); + break; + case 0x800: + FRCHG(); + break; + default: + machine().debug_break(); + break; } - } else { - FSSCA(opcode); } + else { + FTRV(opcode); + } + } + else { + FSSCA(opcode); + } } void sh34_base_device::dbreak(const uint16_t opcode) @@ -3186,24 +1492,24 @@ void sh34_base_device::dbreak(const uint16_t opcode) inline void sh34_base_device::op1111_0x13(uint16_t opcode) { - switch((opcode >> 4) & 0x0f) + switch ((opcode >> 4) & 0x0f) { - case 0x00: FSTS(opcode); break; - case 0x01: FLDS(opcode); break; - case 0x02: FLOAT(opcode); break; - case 0x03: FTRC(opcode); break; - case 0x04: FNEG(opcode); break; - case 0x05: FABS(opcode); break; - case 0x06: FSQRT(opcode); break; - case 0x07: FSRRA(opcode); break; - case 0x08: FLDI0(opcode); break; - case 0x09: FLDI1(opcode); break; - case 0x0a: FCNVSD(opcode); break; - case 0x0b: FCNVDS(opcode); break; - case 0x0c: dbreak(opcode); break; - case 0x0d: dbreak(opcode); break; - case 0x0e: FIPR(opcode); break; - case 0x0f: op1111_0xf13(opcode); break; + case 0x00: FSTS(opcode); break; + case 0x01: FLDS(opcode); break; + case 0x02: FLOAT(opcode); break; + case 0x03: FTRC(opcode); break; + case 0x04: FNEG(opcode); break; + case 0x05: FABS(opcode); break; + case 0x06: FSQRT(opcode); break; + case 0x07: FSRRA(opcode); break; + case 0x08: FLDI0(opcode); break; + case 0x09: FLDI1(opcode); break; + case 0x0a: FCNVSD(opcode); break; + case 0x0b: FCNVDS(opcode); break; + case 0x0c: dbreak(opcode); break; + case 0x0d: dbreak(opcode); break; + case 0x0e: FIPR(opcode); break; + case 0x0f: op1111_0xf13(opcode); break; } } @@ -3215,20 +1521,20 @@ inline void sh34_base_device::op1111_0x13(uint16_t opcode) void sh34_base_device::device_reset() { m_spc = 0; - m_pr = 0; - m_sr = 0; + m_sh2_state->pr = 0; + m_sh2_state->sr = 0; m_ssr = 0; - m_gbr = 0; - m_vbr = 0; - m_mach = 0; - m_macl = 0; - memset(m_r, 0, sizeof(m_r)); + m_sh2_state->gbr = 0; + m_sh2_state->vbr = 0; + m_sh2_state->mach = 0; + m_sh2_state->macl = 0; + memset(m_sh2_state->r, 0, sizeof(m_sh2_state->r)); memset(m_rbnk, 0, sizeof(m_rbnk)); m_sgr = 0; memset(m_fr, 0, sizeof(m_fr)); memset(m_xf, 0, sizeof(m_xf)); - m_ea = 0; - m_delay = 0; + m_sh2_state->ea = 0; + m_sh2_state->m_delay = 0; m_cpu_off = 0; m_pending_irq = 0; m_test_irq = 0; @@ -3290,10 +1596,10 @@ void sh34_base_device::device_reset() m_rtc_timer->adjust(attotime::from_hz(128)); - m_pc = 0xa0000000; - m_ppc = m_pc & AM; - m_r[15] = RL(4); - m_sr = 0x700000f0; + m_sh2_state->pc = 0xa0000000; + m_ppc = m_sh2_state->pc & SH34_AM; + m_sh2_state->r[15] = RL(4); + m_sh2_state->sr = 0x700000f0; m_fpscr = 0x00040001; m_fpu_sz = (m_fpscr & SZ) ? 1 : 0; m_fpu_pr = (m_fpscr & PR) ? 1 : 0; @@ -3302,9 +1608,10 @@ void sh34_base_device::device_reset() m_internal_irq_level = -1; m_irln = 15; - m_sleep_mode = 0; + m_sh2_state->sleep_mode = 0; m_sh4_mmu_enabled = 0; + m_cache_dirty = true; } /*------------------------------------------------- @@ -3338,846 +1645,344 @@ void sh4_base_device::device_reset() inline void sh34_base_device::execute_one_0000(const uint16_t opcode) { - switch(opcode & 0xff) + switch (opcode & 0xff) { - // 0x00 - case 0x00: NOP(opcode); break; - case 0x10: NOP(opcode); break; - case 0x20: NOP(opcode); break; - case 0x30: NOP(opcode); break; - case 0x40: NOP(opcode); break; - case 0x50: NOP(opcode); break; - case 0x60: NOP(opcode); break; - case 0x70: NOP(opcode); break; - case 0x80: NOP(opcode); break; - case 0x90: NOP(opcode); break; - case 0xa0: NOP(opcode); break; - case 0xb0: NOP(opcode); break; - case 0xc0: NOP(opcode); break; - case 0xd0: NOP(opcode); break; - case 0xe0: NOP(opcode); break; - case 0xf0: NOP(opcode); break; - // 0x10 - case 0x01: NOP(opcode); break; - case 0x11: NOP(opcode); break; - case 0x21: NOP(opcode); break; - case 0x31: NOP(opcode); break; - case 0x41: NOP(opcode); break; - case 0x51: NOP(opcode); break; - case 0x61: NOP(opcode); break; - case 0x71: NOP(opcode); break; - case 0x81: NOP(opcode); break; - case 0x91: NOP(opcode); break; - case 0xa1: NOP(opcode); break; - case 0xb1: NOP(opcode); break; - case 0xc1: NOP(opcode); break; - case 0xd1: NOP(opcode); break; - case 0xe1: NOP(opcode); break; - case 0xf1: NOP(opcode); break; - // 0x20 - case 0x02: STCSR(opcode); break; - case 0x12: STCGBR(opcode); break; - case 0x22: STCVBR(opcode); break; - case 0x32: STCSSR(opcode); break; - case 0x42: STCSPC(opcode); break; - case 0x52: NOP(opcode); break; - case 0x62: NOP(opcode); break; - case 0x72: NOP(opcode); break; - case 0x82: STCRBANK(opcode); break; - case 0x92: STCRBANK(opcode); break; - case 0xa2: STCRBANK(opcode); break; - case 0xb2: STCRBANK(opcode); break; - case 0xc2: STCRBANK(opcode); break; - case 0xd2: STCRBANK(opcode); break; - case 0xe2: STCRBANK(opcode); break; - case 0xf2: STCRBANK(opcode); break; - // 0x30 - case 0x03: BSRF(opcode); break; - case 0x13: NOP(opcode); break; - case 0x23: BRAF(opcode); break; - case 0x33: NOP(opcode); break; - case 0x43: NOP(opcode); break; - case 0x53: NOP(opcode); break; - case 0x63: NOP(opcode); break; - case 0x73: NOP(opcode); break; - case 0x83: PREFM(opcode); break; - case 0x93: TODO(opcode); break; - case 0xa3: TODO(opcode); break; - case 0xb3: TODO(opcode); break; - case 0xc3: MOVCAL(opcode); break; - case 0xd3: NOP(opcode); break; - case 0xe3: NOP(opcode); break; - case 0xf3: NOP(opcode); break; - // 0x40 - case 0x04: MOVBS0(opcode); break; - case 0x14: MOVBS0(opcode); break; - case 0x24: MOVBS0(opcode); break; - case 0x34: MOVBS0(opcode); break; - case 0x44: MOVBS0(opcode); break; - case 0x54: MOVBS0(opcode); break; - case 0x64: MOVBS0(opcode); break; - case 0x74: MOVBS0(opcode); break; - case 0x84: MOVBS0(opcode); break; - case 0x94: MOVBS0(opcode); break; - case 0xa4: MOVBS0(opcode); break; - case 0xb4: MOVBS0(opcode); break; - case 0xc4: MOVBS0(opcode); break; - case 0xd4: MOVBS0(opcode); break; - case 0xe4: MOVBS0(opcode); break; - case 0xf4: MOVBS0(opcode); break; - // 0x50 - case 0x05: MOVWS0(opcode); break; - case 0x15: MOVWS0(opcode); break; - case 0x25: MOVWS0(opcode); break; - case 0x35: MOVWS0(opcode); break; - case 0x45: MOVWS0(opcode); break; - case 0x55: MOVWS0(opcode); break; - case 0x65: MOVWS0(opcode); break; - case 0x75: MOVWS0(opcode); break; - case 0x85: MOVWS0(opcode); break; - case 0x95: MOVWS0(opcode); break; - case 0xa5: MOVWS0(opcode); break; - case 0xb5: MOVWS0(opcode); break; - case 0xc5: MOVWS0(opcode); break; - case 0xd5: MOVWS0(opcode); break; - case 0xe5: MOVWS0(opcode); break; - case 0xf5: MOVWS0(opcode); break; - // 0x60 - case 0x06: MOVLS0(opcode); break; - case 0x16: MOVLS0(opcode); break; - case 0x26: MOVLS0(opcode); break; - case 0x36: MOVLS0(opcode); break; - case 0x46: MOVLS0(opcode); break; - case 0x56: MOVLS0(opcode); break; - case 0x66: MOVLS0(opcode); break; - case 0x76: MOVLS0(opcode); break; - case 0x86: MOVLS0(opcode); break; - case 0x96: MOVLS0(opcode); break; - case 0xa6: MOVLS0(opcode); break; - case 0xb6: MOVLS0(opcode); break; - case 0xc6: MOVLS0(opcode); break; - case 0xd6: MOVLS0(opcode); break; - case 0xe6: MOVLS0(opcode); break; - case 0xf6: MOVLS0(opcode); break; - // 0x70 - case 0x07: MULL(opcode); break; - case 0x17: MULL(opcode); break; - case 0x27: MULL(opcode); break; - case 0x37: MULL(opcode); break; - case 0x47: MULL(opcode); break; - case 0x57: MULL(opcode); break; - case 0x67: MULL(opcode); break; - case 0x77: MULL(opcode); break; - case 0x87: MULL(opcode); break; - case 0x97: MULL(opcode); break; - case 0xa7: MULL(opcode); break; - case 0xb7: MULL(opcode); break; - case 0xc7: MULL(opcode); break; - case 0xd7: MULL(opcode); break; - case 0xe7: MULL(opcode); break; - case 0xf7: MULL(opcode); break; - // 0x80 - case 0x08: CLRT(opcode); break; - case 0x18: SETT(opcode); break; - case 0x28: CLRMAC(opcode); break; - case 0x38: LDTLB(opcode); break; - case 0x48: CLRS(opcode); break; - case 0x58: SETS(opcode); break; - case 0x68: NOP(opcode); break; - case 0x78: NOP(opcode); break; - case 0x88: CLRT(opcode); break; - case 0x98: SETT(opcode); break; - case 0xa8: CLRMAC(opcode); break; - case 0xb8: LDTLB(opcode); break; - case 0xc8: CLRS(opcode); break; - case 0xd8: SETS(opcode); break; - case 0xe8: NOP(opcode); break; - case 0xf8: NOP(opcode); break; - // 0x90 - case 0x09: NOP(opcode); break; - case 0x19: DIV0U(opcode); break; - case 0x29: MOVT(opcode); break; - case 0x39: NOP(opcode); break; - case 0x49: NOP(opcode); break; - case 0x59: DIV0U(opcode); break; - case 0x69: MOVT(opcode); break; - case 0x79: NOP(opcode); break; - case 0x89: NOP(opcode); break; - case 0x99: DIV0U(opcode); break; - case 0xa9: MOVT(opcode); break; - case 0xb9: NOP(opcode); break; - case 0xc9: NOP(opcode); break; - case 0xd9: DIV0U(opcode); break; - case 0xe9: MOVT(opcode); break; - case 0xf9: NOP(opcode); break; - // 0xa0 - case 0x0a: STSMACH(opcode); break; - case 0x1a: STSMACL(opcode); break; - case 0x2a: STSPR(opcode); break; - case 0x3a: STCSGR(opcode); break; - case 0x4a: NOP(opcode); break; - case 0x5a: STSFPUL(opcode); break; - case 0x6a: STSFPSCR(opcode); break; - case 0x7a: STCDBR(opcode); break; - case 0x8a: STSMACH(opcode); break; - case 0x9a: STSMACL(opcode); break; - case 0xaa: STSPR(opcode); break; - case 0xba: STCSGR(opcode); break; - case 0xca: NOP(opcode); break; - case 0xda: STSFPUL(opcode); break; - case 0xea: STSFPSCR(opcode); break; - case 0xfa: STCDBR(opcode); break; - // 0xb0 - case 0x0b: RTS(opcode); break; - case 0x1b: SLEEP(opcode); break; - case 0x2b: RTE(opcode); break; - case 0x3b: NOP(opcode); break; - case 0x4b: RTS(opcode); break; - case 0x5b: SLEEP(opcode); break; - case 0x6b: RTE(opcode); break; - case 0x7b: NOP(opcode); break; - case 0x8b: RTS(opcode); break; - case 0x9b: SLEEP(opcode); break; - case 0xab: RTE(opcode); break; - case 0xbb: NOP(opcode); break; - case 0xcb: RTS(opcode); break; - case 0xdb: SLEEP(opcode); break; - case 0xeb: RTE(opcode); break; - case 0xfb: NOP(opcode); break; - // 0xc0 - case 0x0c: MOVBL0(opcode); break; - case 0x1c: MOVBL0(opcode); break; - case 0x2c: MOVBL0(opcode); break; - case 0x3c: MOVBL0(opcode); break; - case 0x4c: MOVBL0(opcode); break; - case 0x5c: MOVBL0(opcode); break; - case 0x6c: MOVBL0(opcode); break; - case 0x7c: MOVBL0(opcode); break; - case 0x8c: MOVBL0(opcode); break; - case 0x9c: MOVBL0(opcode); break; - case 0xac: MOVBL0(opcode); break; - case 0xbc: MOVBL0(opcode); break; - case 0xcc: MOVBL0(opcode); break; - case 0xdc: MOVBL0(opcode); break; - case 0xec: MOVBL0(opcode); break; - case 0xfc: MOVBL0(opcode); break; - // 0xd0 - case 0x0d: MOVWL0(opcode); break; - case 0x1d: MOVWL0(opcode); break; - case 0x2d: MOVWL0(opcode); break; - case 0x3d: MOVWL0(opcode); break; - case 0x4d: MOVWL0(opcode); break; - case 0x5d: MOVWL0(opcode); break; - case 0x6d: MOVWL0(opcode); break; - case 0x7d: MOVWL0(opcode); break; - case 0x8d: MOVWL0(opcode); break; - case 0x9d: MOVWL0(opcode); break; - case 0xad: MOVWL0(opcode); break; - case 0xbd: MOVWL0(opcode); break; - case 0xcd: MOVWL0(opcode); break; - case 0xdd: MOVWL0(opcode); break; - case 0xed: MOVWL0(opcode); break; - case 0xfd: MOVWL0(opcode); break; - // 0xe0 - case 0x0e: MOVLL0(opcode); break; - case 0x1e: MOVLL0(opcode); break; - case 0x2e: MOVLL0(opcode); break; - case 0x3e: MOVLL0(opcode); break; - case 0x4e: MOVLL0(opcode); break; - case 0x5e: MOVLL0(opcode); break; - case 0x6e: MOVLL0(opcode); break; - case 0x7e: MOVLL0(opcode); break; - case 0x8e: MOVLL0(opcode); break; - case 0x9e: MOVLL0(opcode); break; - case 0xae: MOVLL0(opcode); break; - case 0xbe: MOVLL0(opcode); break; - case 0xce: MOVLL0(opcode); break; - case 0xde: MOVLL0(opcode); break; - case 0xee: MOVLL0(opcode); break; - case 0xfe: MOVLL0(opcode); break; - // 0xf0 - case 0x0f: MAC_L(opcode); break; - case 0x1f: MAC_L(opcode); break; - case 0x2f: MAC_L(opcode); break; - case 0x3f: MAC_L(opcode); break; - case 0x4f: MAC_L(opcode); break; - case 0x5f: MAC_L(opcode); break; - case 0x6f: MAC_L(opcode); break; - case 0x7f: MAC_L(opcode); break; - case 0x8f: MAC_L(opcode); break; - case 0x9f: MAC_L(opcode); break; - case 0xaf: MAC_L(opcode); break; - case 0xbf: MAC_L(opcode); break; - case 0xcf: MAC_L(opcode); break; - case 0xdf: MAC_L(opcode); break; - case 0xef: MAC_L(opcode); break; - case 0xff: MAC_L(opcode); break; + default: + // fall through to SH2 handlers + sh_common_execution::execute_one_0000(opcode); break; + + case 0x52: + case 0x62: + case 0x43: + case 0x63: + case 0xe3: + case 0x68: + case 0xe8: + case 0x4a: + case 0xca: + ILLEGAL(); break; // illegal on sh4 + + case 0x93: + case 0xa3: + case 0xb3: + TODO(opcode); break; + + case 0x82: + case 0x92: + case 0xa2: + case 0xb2: + case 0xc2: + case 0xd2: + case 0xe2: + case 0xf2: + STCRBANK(opcode); break; // sh4 only + + case 0x32: STCSSR(opcode); break; // sh4 only + case 0x42: STCSPC(opcode); break; // sh4 only + case 0x83: PREFM(opcode); break; // sh4 only + case 0xc3: MOVCAL(opcode); break; // sh4 only + + case 0x38: + case 0xb8: + LDTLB(opcode); break; // sh4 only + + case 0x48: + case 0xc8: + CLRS(opcode); break; // sh4 only + + case 0x58: + case 0xd8: + SETS(opcode); break; // sh4 only + + case 0x3a: + case 0xba: + STCSGR(opcode); break; // sh4 only + + case 0x5a: + case 0xda: + STSFPUL(opcode); break; // sh4 only + + case 0x6a: + case 0xea: + STSFPSCR(opcode); break; // sh4 only + + case 0x7a: + case 0xfa: + STCDBR(opcode); break; // sh4 only } } inline void sh34_base_device::execute_one_4000(const uint16_t opcode) { - switch(opcode & 0xff) + switch (opcode & 0xff) { - // 0x00 - case 0x00: SHLL(opcode); break; - case 0x10: DT(opcode); break; - case 0x20: SHAL(opcode); break; - case 0x30: NOP(opcode); break; - case 0x40: SHLL(opcode); break; - case 0x50: DT(opcode); break; - case 0x60: SHAL(opcode); break; - case 0x70: NOP(opcode); break; - case 0x80: SHLL(opcode); break; - case 0x90: DT(opcode); break; - case 0xa0: SHAL(opcode); break; - case 0xb0: NOP(opcode); break; - case 0xc0: SHLL(opcode); break; - case 0xd0: DT(opcode); break; - case 0xe0: SHAL(opcode); break; - case 0xf0: NOP(opcode); break; - // 0x10 - case 0x01: SHLR(opcode); break; - case 0x11: CMPPZ(opcode); break; - case 0x21: SHAR(opcode); break; - case 0x31: NOP(opcode); break; - case 0x41: SHLR(opcode); break; - case 0x51: CMPPZ(opcode); break; - case 0x61: SHAR(opcode); break; - case 0x71: NOP(opcode); break; - case 0x81: SHLR(opcode); break; - case 0x91: CMPPZ(opcode); break; - case 0xa1: SHAR(opcode); break; - case 0xb1: NOP(opcode); break; - case 0xc1: SHLR(opcode); break; - case 0xd1: CMPPZ(opcode); break; - case 0xe1: SHAR(opcode); break; - case 0xf1: NOP(opcode); break; - // 0x20 - case 0x02: STSMMACH(opcode); break; - case 0x12: STSMMACL(opcode); break; - case 0x22: STSMPR(opcode); break; - case 0x32: STCMSGR(opcode); break; - case 0x42: NOP(opcode); break; - case 0x52: STSMFPUL(opcode); break; - case 0x62: STSMFPSCR(opcode); break; - case 0x72: NOP(opcode); break; - case 0x82: NOP(opcode); break; - case 0x92: NOP(opcode); break; - case 0xa2: NOP(opcode); break; - case 0xb2: NOP(opcode); break; - case 0xc2: NOP(opcode); break; - case 0xd2: NOP(opcode); break; - case 0xe2: NOP(opcode); break; - case 0xf2: STCMDBR(opcode); break; - // 0x30 - case 0x03: STCMSR(opcode); break; - case 0x13: STCMGBR(opcode); break; - case 0x23: STCMVBR(opcode); break; - case 0x33: STCMSSR(opcode); break; - case 0x43: STCMSPC(opcode); break; - case 0x53: NOP(opcode); break; - case 0x63: NOP(opcode); break; - case 0x73: NOP(opcode); break; - case 0x83: STCMRBANK(opcode); break; - case 0x93: STCMRBANK(opcode); break; - case 0xa3: STCMRBANK(opcode); break; - case 0xb3: STCMRBANK(opcode); break; - case 0xc3: STCMRBANK(opcode); break; - case 0xd3: STCMRBANK(opcode); break; - case 0xe3: STCMRBANK(opcode); break; - case 0xf3: STCMRBANK(opcode); break; - // 0x40 - case 0x04: ROTL(opcode); break; - case 0x14: NOP(opcode); break; - case 0x24: ROTCL(opcode); break; - case 0x34: NOP(opcode); break; - case 0x44: ROTL(opcode); break; - case 0x54: NOP(opcode); break; - case 0x64: ROTCL(opcode); break; - case 0x74: NOP(opcode); break; - case 0x84: ROTL(opcode); break; - case 0x94: NOP(opcode); break; - case 0xa4: ROTCL(opcode); break; - case 0xb4: NOP(opcode); break; - case 0xc4: ROTL(opcode); break; - case 0xd4: NOP(opcode); break; - case 0xe4: ROTCL(opcode); break; - case 0xf4: NOP(opcode); break; - // 0x50 - case 0x05: ROTR(opcode); break; - case 0x15: CMPPL(opcode); break; - case 0x25: ROTCR(opcode); break; - case 0x35: NOP(opcode); break; - case 0x45: ROTR(opcode); break; - case 0x55: CMPPL(opcode); break; - case 0x65: ROTCR(opcode); break; - case 0x75: NOP(opcode); break; - case 0x85: ROTR(opcode); break; - case 0x95: CMPPL(opcode); break; - case 0xa5: ROTCR(opcode); break; - case 0xb5: NOP(opcode); break; - case 0xc5: ROTR(opcode); break; - case 0xd5: CMPPL(opcode); break; - case 0xe5: ROTCR(opcode); break; - case 0xf5: NOP(opcode); break; - // 0x60 - case 0x06: LDSMMACH(opcode); break; - case 0x16: LDSMMACL(opcode); break; - case 0x26: LDSMPR(opcode); break; - case 0x36: NOP(opcode); break; - case 0x46: NOP(opcode); break; - case 0x56: LDSMFPUL(opcode); break; - case 0x66: LDSMFPSCR(opcode); break; - case 0x76: NOP(opcode); break; - case 0x86: NOP(opcode); break; - case 0x96: NOP(opcode); break; - case 0xa6: NOP(opcode); break; - case 0xb6: NOP(opcode); break; - case 0xc6: NOP(opcode); break; - case 0xd6: NOP(opcode); break; - case 0xe6: NOP(opcode); break; - case 0xf6: LDCMDBR(opcode); break; - // 0x70 - case 0x07: LDCMSR(opcode); break; - case 0x17: LDCMGBR(opcode); break; - case 0x27: LDCMVBR(opcode); break; - case 0x37: LDCMSSR(opcode); break; - case 0x47: LDCMSPC(opcode); break; - case 0x57: NOP(opcode); break; - case 0x67: NOP(opcode); break; - case 0x77: NOP(opcode); break; - case 0x87: LDCMRBANK(opcode); break; - case 0x97: LDCMRBANK(opcode); break; - case 0xa7: LDCMRBANK(opcode); break; - case 0xb7: LDCMRBANK(opcode); break; - case 0xc7: LDCMRBANK(opcode); break; - case 0xd7: LDCMRBANK(opcode); break; - case 0xe7: LDCMRBANK(opcode); break; - case 0xf7: LDCMRBANK(opcode); break; - // 0x80 - case 0x08: SHLL2(opcode); break; - case 0x18: SHLL8(opcode); break; - case 0x28: SHLL16(opcode); break; - case 0x38: NOP(opcode); break; - case 0x48: SHLL2(opcode); break; - case 0x58: SHLL8(opcode); break; - case 0x68: SHLL16(opcode); break; - case 0x78: NOP(opcode); break; - case 0x88: SHLL2(opcode); break; - case 0x98: SHLL8(opcode); break; - case 0xa8: SHLL16(opcode); break; - case 0xb8: NOP(opcode); break; - case 0xc8: SHLL2(opcode); break; - case 0xd8: SHLL8(opcode); break; - case 0xe8: SHLL16(opcode); break; - case 0xf8: NOP(opcode); break; - // 0x90 - case 0x09: SHLR2(opcode); break; - case 0x19: SHLR8(opcode); break; - case 0x29: SHLR16(opcode); break; - case 0x39: NOP(opcode); break; - case 0x49: SHLR2(opcode); break; - case 0x59: SHLR8(opcode); break; - case 0x69: SHLR16(opcode); break; - case 0x79: NOP(opcode); break; - case 0x89: SHLR2(opcode); break; - case 0x99: SHLR8(opcode); break; - case 0xa9: SHLR16(opcode); break; - case 0xb9: NOP(opcode); break; - case 0xc9: SHLR2(opcode); break; - case 0xd9: SHLR8(opcode); break; - case 0xe9: SHLR16(opcode); break; - case 0xf9: NOP(opcode); break; - // 0xa0 - case 0x0a: LDSMACH(opcode); break; - case 0x1a: LDSMACL(opcode); break; - case 0x2a: LDSPR(opcode); break; - case 0x3a: NOP(opcode); break; - case 0x4a: NOP(opcode); break; - case 0x5a: LDSFPUL(opcode); break; - case 0x6a: LDSFPSCR(opcode); break; - case 0x7a: NOP(opcode); break; - case 0x8a: NOP(opcode); break; - case 0x9a: NOP(opcode); break; - case 0xaa: NOP(opcode); break; - case 0xba: NOP(opcode); break; - case 0xca: NOP(opcode); break; - case 0xda: NOP(opcode); break; - case 0xea: NOP(opcode); break; - case 0xfa: LDCDBR(opcode); break; - // 0xb0 - case 0x0b: JSR(opcode); break; - case 0x1b: TAS(opcode); break; - case 0x2b: JMP(opcode); break; - case 0x3b: NOP(opcode); break; - case 0x4b: JSR(opcode); break; - case 0x5b: TAS(opcode); break; - case 0x6b: JMP(opcode); break; - case 0x7b: NOP(opcode); break; - case 0x8b: JSR(opcode); break; - case 0x9b: TAS(opcode); break; - case 0xab: JMP(opcode); break; - case 0xbb: NOP(opcode); break; - case 0xcb: JSR(opcode); break; - case 0xdb: TAS(opcode); break; - case 0xeb: JMP(opcode); break; - case 0xfb: NOP(opcode); break; - // 0xc0 - case 0x0c: SHAD(opcode); break; - case 0x1c: SHAD(opcode); break; - case 0x2c: SHAD(opcode); break; - case 0x3c: SHAD(opcode); break; - case 0x4c: SHAD(opcode); break; - case 0x5c: SHAD(opcode); break; - case 0x6c: SHAD(opcode); break; - case 0x7c: SHAD(opcode); break; - case 0x8c: SHAD(opcode); break; - case 0x9c: SHAD(opcode); break; - case 0xac: SHAD(opcode); break; - case 0xbc: SHAD(opcode); break; - case 0xcc: SHAD(opcode); break; - case 0xdc: SHAD(opcode); break; - case 0xec: SHAD(opcode); break; - case 0xfc: SHAD(opcode); break; - // 0xd0 - case 0x0d: SHLD(opcode); break; - case 0x1d: SHLD(opcode); break; - case 0x2d: SHLD(opcode); break; - case 0x3d: SHLD(opcode); break; - case 0x4d: SHLD(opcode); break; - case 0x5d: SHLD(opcode); break; - case 0x6d: SHLD(opcode); break; - case 0x7d: SHLD(opcode); break; - case 0x8d: SHLD(opcode); break; - case 0x9d: SHLD(opcode); break; - case 0xad: SHLD(opcode); break; - case 0xbd: SHLD(opcode); break; - case 0xcd: SHLD(opcode); break; - case 0xdd: SHLD(opcode); break; - case 0xed: SHLD(opcode); break; - case 0xfd: SHLD(opcode); break; - // 0xe0 - case 0x0e: LDCSR(opcode); break; - case 0x1e: LDCGBR(opcode); break; - case 0x2e: LDCVBR(opcode); break; - case 0x3e: LDCSSR(opcode); break; - case 0x4e: LDCSPC(opcode); break; - case 0x5e: NOP(opcode); break; - case 0x6e: NOP(opcode); break; - case 0x7e: NOP(opcode); break; - case 0x8e: LDCRBANK(opcode); break; - case 0x9e: LDCRBANK(opcode); break; - case 0xae: LDCRBANK(opcode); break; - case 0xbe: LDCRBANK(opcode); break; - case 0xce: LDCRBANK(opcode); break; - case 0xde: LDCRBANK(opcode); break; - case 0xee: LDCRBANK(opcode); break; - case 0xfe: LDCRBANK(opcode); break; - // 0xf0 - case 0x0f: MAC_W(opcode); break; - case 0x1f: MAC_W(opcode); break; - case 0x2f: MAC_W(opcode); break; - case 0x3f: MAC_W(opcode); break; - case 0x4f: MAC_W(opcode); break; - case 0x5f: MAC_W(opcode); break; - case 0x6f: MAC_W(opcode); break; - case 0x7f: MAC_W(opcode); break; - case 0x8f: MAC_W(opcode); break; - case 0x9f: MAC_W(opcode); break; - case 0xaf: MAC_W(opcode); break; - case 0xbf: MAC_W(opcode); break; - case 0xcf: MAC_W(opcode); break; - case 0xdf: MAC_W(opcode); break; - case 0xef: MAC_W(opcode); break; - case 0xff: MAC_W(opcode); break; - } -} - -inline void sh34_base_device::execute_one(const uint16_t opcode) -{ - switch(opcode & 0xf000) + default: // LDCMSR (0x0e) has sh2/4 flag difference + // fall through to SH2 handlers + sh_common_execution::execute_one_4000(opcode); break; + + case 0x42: + case 0x46: + case 0x4a: + case 0x53: + case 0x57: + case 0x5e: + case 0x63: + case 0x67: + case 0x6e: + case 0x82: + case 0x86: + case 0x8a: + case 0x92: + case 0x96: + case 0x9a: + case 0xa2: + case 0xa6: + case 0xaa: + case 0xc2: + case 0xc6: + case 0xca: + case 0xd2: + case 0xd6: + case 0xda: + case 0xe2: + case 0xe6: + case 0xea: + ILLEGAL(); break; // defined as illegal on SH4 + + case 0x0c: + case 0x1c: + case 0x2c: + case 0x3c: + case 0x4c: + case 0x5c: + case 0x6c: + case 0x7c: + case 0x8c: + case 0x9c: + case 0xac: + case 0xbc: + case 0xcc: + case 0xdc: + case 0xec: + case 0xfc: + SHAD(opcode); break; // sh3/4 only + + case 0x0d: + case 0x1d: + case 0x2d: + case 0x3d: + case 0x4d: + case 0x5d: + case 0x6d: + case 0x7d: + case 0x8d: + case 0x9d: + case 0xad: + case 0xbd: + case 0xcd: + case 0xdd: + case 0xed: + case 0xfd: + SHLD(opcode); break; // sh3/4 only + + case 0x8e: + case 0x9e: + case 0xae: + case 0xbe: + case 0xce: + case 0xde: + case 0xee: + case 0xfe: + LDCRBANK(opcode); break; // sh3/4 only + + case 0x83: + case 0x93: + case 0xa3: + case 0xb3: + case 0xc3: + case 0xd3: + case 0xe3: + case 0xf3: + STCMRBANK(opcode); break; // sh3/4 only + + case 0x87: + case 0x97: + case 0xa7: + case 0xb7: + case 0xc7: + case 0xd7: + case 0xe7: + case 0xf7: + LDCMRBANK(opcode); break; // sh3/4 only + + case 0x32: STCMSGR(opcode); break; // sh4 only + case 0x33: STCMSSR(opcode); break; // sh4 only + case 0x37: LDCMSSR(opcode); break; // sh4 only + case 0x3e: LDCSSR(opcode); break; // sh4 only + case 0x43: STCMSPC(opcode); break; // sh4 only + case 0x47: LDCMSPC(opcode); break; // sh4 only + case 0x4e: LDCSPC(opcode); break; // sh4 only + case 0x52: STSMFPUL(opcode); break; // sh4 only + case 0x56: LDSMFPUL(opcode); break; // sh4 only + case 0x5a: LDSFPUL(opcode); break; // sh4 only + case 0x62: STSMFPSCR(opcode); break; // sh4 only + case 0x66: LDSMFPSCR(opcode); break; // sh4 only + case 0x6a: LDSFPSCR(opcode); break; // sh4 only + case 0xf2: STCMDBR(opcode); break; // sh4 only + case 0xf6: LDCMDBR(opcode); break; // sh4 only + case 0xfa: LDCDBR(opcode); break; // sh4 only + + } +} + +inline void sh34_base_device::execute_one_f000(const uint16_t opcode) +{ + // the SH3 doesn't have these? + + switch (opcode & 0x0f) { - case 0x0000: - execute_one_0000(opcode); - break; - - case 0x1000: - MOVLS4(opcode); - break; - - case 0x2000: - switch(opcode & 0x0f) - { - case 0x00: MOVBS(opcode); break; - case 0x01: MOVWS(opcode); break; - case 0x02: MOVLS(opcode); break; - case 0x03: NOP(opcode); break; - case 0x04: MOVBM(opcode); break; - case 0x05: MOVWM(opcode); break; - case 0x06: MOVLM(opcode); break; - case 0x07: DIV0S(opcode); break; - case 0x08: TST(opcode); break; - case 0x09: AND(opcode); break; - case 0x0a: XOR(opcode); break; - case 0x0b: OR(opcode); break; - case 0x0c: CMPSTR(opcode); break; - case 0x0d: XTRCT(opcode); break; - case 0x0e: MULU(opcode); break; - case 0x0f: MULS(opcode); break; - } - break; - - case 0x3000: - switch(opcode & 0x0f) - { - case 0x00: CMPEQ(opcode); break; - case 0x01: NOP(opcode); break; - case 0x02: CMPHS(opcode); break; - case 0x03: CMPGE(opcode); break; - case 0x04: DIV1(opcode); break; - case 0x05: DMULU(opcode); break; - case 0x06: CMPHI(opcode); break; - case 0x07: CMPGT(opcode); break; - case 0x08: SUB(opcode); break; - case 0x09: NOP(opcode); break; - case 0x0a: SUBC(opcode); break; - case 0x0b: SUBV(opcode); break; - case 0x0c: ADD(opcode); break; - case 0x0d: DMULS(opcode); break; - case 0x0e: ADDC(opcode); break; - case 0x0f: ADDV(opcode); break; - } - break; - - case 0x4000: - execute_one_4000(opcode); - break; - - case 0x5000: - MOVLL4(opcode); - break; - - case 0x6000: - switch(opcode & 0x0f) - { - case 0x00: MOVBL(opcode); break; - case 0x01: MOVWL(opcode); break; - case 0x02: MOVLL(opcode); break; - case 0x03: MOV(opcode); break; - case 0x04: MOVBP(opcode); break; - case 0x05: MOVWP(opcode); break; - case 0x06: MOVLP(opcode); break; - case 0x07: NOT(opcode); break; - case 0x08: SWAPB(opcode); break; - case 0x09: SWAPW(opcode); break; - case 0x0a: NEGC(opcode); break; - case 0x0b: NEG(opcode); break; - case 0x0c: EXTUB(opcode); break; - case 0x0d: EXTUW(opcode); break; - case 0x0e: EXTSB(opcode); break; - case 0x0f: EXTSW(opcode); break; - } - break; - - case 0x7000: - ADDI(opcode); - break; - - case 0x8000: - switch((opcode >> 8) & 0x0f) - { - case 0x00: MOVBS4(opcode); break; - case 0x01: MOVWS4(opcode); break; - case 0x02: NOP(opcode); break; - case 0x03: NOP(opcode); break; - case 0x04: MOVBL4(opcode); break; - case 0x05: MOVWL4(opcode); break; - case 0x06: NOP(opcode); break; - case 0x07: NOP(opcode); break; - case 0x08: CMPIM(opcode); break; - case 0x09: BT(opcode); break; - case 0x0a: NOP(opcode); break; - case 0x0b: BF(opcode); break; - case 0x0c: NOP(opcode); break; - case 0x0d: BTS(opcode); break; - case 0x0e: NOP(opcode); break; - case 0x0f: BFS(opcode); break; - } - break; - - case 0x9000: - MOVWI(opcode); - break; - - case 0xa000: - BRA(opcode); - break; - - case 0xb000: - BSR(opcode); - break; - - case 0xc000: - switch((opcode >> 8) & 0x0f) - { - case 0x00: MOVBSG(opcode); break; - case 0x01: MOVWSG(opcode); break; - case 0x02: MOVLSG(opcode); break; - case 0x03: TRAPA(opcode); break; - case 0x04: MOVBLG(opcode); break; - case 0x05: MOVWLG(opcode); break; - case 0x06: MOVLLG(opcode); break; - case 0x07: MOVA(opcode); break; - case 0x08: TSTI(opcode); break; - case 0x09: ANDI(opcode); break; - case 0x0a: XORI(opcode); break; - case 0x0b: ORI(opcode); break; - case 0x0c: TSTM(opcode); break; - case 0x0d: ANDM(opcode); break; - case 0x0e: XORM(opcode); break; - case 0x0f: ORM(opcode); break; - } - break; - - case 0xd000: - MOVLI(opcode); - break; - - case 0xe000: - MOVI(opcode); - break; - - case 0xf000: - switch(opcode & 0x0f) - { - case 0x00: FADD(opcode); break; - case 0x01: FSUB(opcode); break; - case 0x02: FMUL(opcode); break; - case 0x03: FDIV(opcode); break; - case 0x04: FCMP_EQ(opcode); break; - case 0x05: FCMP_GT(opcode); break; - case 0x06: FMOVS0FR(opcode); break; - case 0x07: FMOVFRS0(opcode); break; - case 0x08: FMOVMRFR(opcode); break; - case 0x09: FMOVMRIFR(opcode); break; - case 0x0a: FMOVFRMR(opcode); break; - case 0x0b: FMOVFRMDR(opcode); break; - case 0x0c: FMOVFR(opcode); break; - case 0x0d: op1111_0x13(opcode); break; - case 0x0e: FMAC(opcode); break; - case 0x0f: dbreak(opcode); break; - } - break; + case 0x00: FADD(opcode); break; + case 0x01: FSUB(opcode); break; + case 0x02: FMUL(opcode); break; + case 0x03: FDIV(opcode); break; + case 0x04: FCMP_EQ(opcode); break; + case 0x05: FCMP_GT(opcode); break; + case 0x06: FMOVS0FR(opcode); break; + case 0x07: FMOVFRS0(opcode); break; + case 0x08: FMOVMRFR(opcode); break; + case 0x09: FMOVMRIFR(opcode); break; + case 0x0a: FMOVFRMR(opcode); break; + case 0x0b: FMOVFRMDR(opcode); break; + case 0x0c: FMOVFR(opcode); break; + case 0x0d: op1111_0x13(opcode); break; + case 0x0e: FMAC(opcode); break; + case 0x0f: dbreak(opcode); break; } } - /* Execute cycles - returns number of cycles actually run */ void sh34_base_device::execute_run() { + if ( m_isdrc ) + { + execute_run_drc(); + return; + } + if (m_cpu_off) { - m_sh4_icount = 0; + m_sh2_state->icount = 0; return; } do { - m_ppc = m_pc & AM; - debugger_instruction_hook(this, m_pc & AM); + m_ppc = m_sh2_state->pc & SH34_AM; + debugger_instruction_hook(this, m_sh2_state->pc & SH34_AM); uint16_t opcode; - if (!m_sh4_mmu_enabled) opcode = m_direct->read_word(m_pc & AM, WORD2_XOR_LE(0)); - else opcode = RW(m_pc); // should probably use a different function as this needs to go through the ITLB + if (!m_sh4_mmu_enabled) opcode = m_direct->read_word(m_sh2_state->pc & SH34_AM, WORD2_XOR_LE(0)); + else opcode = RW(m_sh2_state->pc); // should probably use a different function as this needs to go through the ITLB - if (m_delay) + if (m_sh2_state->m_delay) { - m_pc = m_delay; - m_delay = 0; + m_sh2_state->pc = m_sh2_state->m_delay; + m_sh2_state->m_delay = 0; } else - m_pc += 2; + m_sh2_state->pc += 2; execute_one(opcode); - if (m_test_irq && !m_delay) + if (m_test_irq && !m_sh2_state->m_delay) { sh4_check_pending_irq("mame_sh4_execute"); } - m_sh4_icount--; - } while( m_sh4_icount > 0 ); + m_sh2_state->icount--; + } while (m_sh2_state->icount > 0); } void sh3be_device::execute_run() { + if ( m_isdrc ) + { + execute_run_drc(); + return; + } + if (m_cpu_off) { - m_sh4_icount = 0; + m_sh2_state->icount = 0; return; } do { - m_ppc = m_pc & AM; - debugger_instruction_hook(this, m_pc & AM); + m_ppc = m_sh2_state->pc & SH34_AM; + debugger_instruction_hook(this, m_sh2_state->pc & SH34_AM); - const uint16_t opcode = m_direct->read_word(m_pc & AM, WORD_XOR_LE(6)); + const uint16_t opcode = m_direct->read_word(m_sh2_state->pc & SH34_AM, WORD_XOR_LE(6)); - if (m_delay) + if (m_sh2_state->m_delay) { - m_pc = m_delay; - m_delay = 0; + m_sh2_state->pc = m_sh2_state->m_delay; + m_sh2_state->m_delay = 0; } else - m_pc += 2; + m_sh2_state->pc += 2; execute_one(opcode); - if (m_test_irq && !m_delay) + if (m_test_irq && !m_sh2_state->m_delay) { sh4_check_pending_irq("mame_sh4_execute"); } - m_sh4_icount--; - } while( m_sh4_icount > 0 ); + m_sh2_state->icount--; + } while (m_sh2_state->icount > 0); } void sh4be_device::execute_run() { + if ( m_isdrc ) + { + execute_run_drc(); + return; + } + if (m_cpu_off) { - m_sh4_icount = 0; + m_sh2_state->icount = 0; return; } do { - m_ppc = m_pc & AM; - debugger_instruction_hook(this, m_pc & AM); + m_ppc = m_sh2_state->pc & SH34_AM; + debugger_instruction_hook(this, m_sh2_state->pc & SH34_AM); - const uint16_t opcode = m_direct->read_word(m_pc & AM, WORD_XOR_LE(6)); + const uint16_t opcode = m_direct->read_word(m_sh2_state->pc & SH34_AM, WORD_XOR_LE(6)); - if (m_delay) + if (m_sh2_state->m_delay) { - m_pc = m_delay; - m_delay = 0; + m_sh2_state->pc = m_sh2_state->m_delay; + m_sh2_state->m_delay = 0; } else - m_pc += 2; + m_sh2_state->pc += 2; execute_one(opcode); - if (m_test_irq && !m_delay) + if (m_test_irq && !m_sh2_state->m_delay) { sh4_check_pending_irq("mame_sh4_execute"); } - m_sh4_icount--; - } while( m_sh4_icount > 0 ); + m_sh2_state->icount--; + } while (m_sh2_state->icount > 0); } void sh4_base_device::device_start() @@ -4185,7 +1990,7 @@ void sh4_base_device::device_start() sh34_base_device::device_start(); int i; - for (i=0;i<64;i++) + for (i = 0;i < 64;i++) { m_utlb[i].ASID = 0; m_utlb[i].VPN = 0; @@ -4201,7 +2006,7 @@ void sh4_base_device::device_start() m_utlb[i].TC = 0; } - for (i=0;i<64;i++) + for (i = 0;i < 64;i++) { save_item(NAME(m_utlb[i].ASID), i); save_item(NAME(m_utlb[i].VPN), i); @@ -4216,20 +2021,23 @@ void sh4_base_device::device_start() save_item(NAME(m_utlb[i].SA), i); save_item(NAME(m_utlb[i].TC), i); } - } void sh34_base_device::device_start() { - for (int i=0; i<3; i++) + m_isdrc = allow_drc(); + + sh_common_execution::device_start(); + + for (int i = 0; i < 3; i++) { m_timer[i] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sh34_base_device::sh4_timer_callback), this)); m_timer[i]->adjust(attotime::never, i); } - for (int i=0; i<4; i++) + for (int i = 0; i < 4; i++) { m_dma_timer[i] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sh34_base_device::sh4_dmac_callback), this)); m_dma_timer[i]->adjust(attotime::never, i); @@ -4247,19 +2055,12 @@ void sh34_base_device::device_start() m_internal = &space(AS_PROGRAM); m_program = &space(AS_PROGRAM); m_io = &space(AS_IO); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); sh4_default_exception_priorities(); m_irln = 15; m_test_irq = 0; - save_item(NAME(m_pc)); - save_item(NAME(m_r)); - save_item(NAME(m_sr)); - save_item(NAME(m_pr)); - save_item(NAME(m_gbr)); - save_item(NAME(m_vbr)); - save_item(NAME(m_mach)); - save_item(NAME(m_macl)); + save_item(NAME(m_spc)); save_item(NAME(m_ssr)); save_item(NAME(m_sgr)); @@ -4267,8 +2068,7 @@ void sh34_base_device::device_start() save_item(NAME(m_rbnk)); save_item(NAME(m_fr)); save_item(NAME(m_xf)); - save_item(NAME(m_ea)); - save_item(NAME(m_delay)); + save_item(NAME(m_cpu_off)); save_item(NAME(m_pending_irq)); save_item(NAME(m_test_irq)); @@ -4306,7 +2106,7 @@ void sh34_base_device::device_start() save_item(NAME(m_SH4_DMATCR3)); save_item(NAME(m_SH4_DMAOR)); save_item(NAME(m_nmi_line_state)); - save_item(NAME(m_sleep_mode)); + save_item(NAME(m_frt_input)); save_item(NAME(m_irln)); save_item(NAME(m_internal_irq_level)); @@ -4320,11 +2120,12 @@ void sh34_base_device::device_start() save_item(NAME(m_dma_source_increment)); save_item(NAME(m_dma_destination_increment)); save_item(NAME(m_dma_mode)); - save_item(NAME(m_sh4_icount)); + + save_item(NAME(m_fpu_sz)); save_item(NAME(m_fpu_pr)); save_item(NAME(m_ioport16_pullup)); - save_item(NAME( m_ioport16_direction)); + save_item(NAME(m_ioport16_direction)); save_item(NAME(m_ioport4_pullup)); save_item(NAME(m_ioport4_direction)); save_item(NAME(m_sh4_mmu_enabled)); @@ -4333,92 +2134,70 @@ void sh34_base_device::device_start() // Debugger state - state_add(SH4_PC, "PC", m_pc).formatstr("%08X").callimport(); - state_add(SH4_SR, "SR", m_sr).formatstr("%08X").callimport(); - state_add(SH4_PR, "PR", m_pr).formatstr("%08X"); - state_add(SH4_GBR, "GBR", m_gbr).formatstr("%08X"); - state_add(SH4_VBR, "VBR", m_vbr).formatstr("%08X"); - state_add(SH4_DBR, "DBR", m_dbr).formatstr("%08X"); - state_add(SH4_MACH, "MACH", m_mach).formatstr("%08X"); - state_add(SH4_MACL, "MACL", m_macl).formatstr("%08X"); - state_add(SH4_R0, "R0", m_r[ 0]).formatstr("%08X"); - state_add(SH4_R1, "R1", m_r[ 1]).formatstr("%08X"); - state_add(SH4_R2, "R2", m_r[ 2]).formatstr("%08X"); - state_add(SH4_R3, "R3", m_r[ 3]).formatstr("%08X"); - state_add(SH4_R4, "R4", m_r[ 4]).formatstr("%08X"); - state_add(SH4_R5, "R5", m_r[ 5]).formatstr("%08X"); - state_add(SH4_R6, "R6", m_r[ 6]).formatstr("%08X"); - state_add(SH4_R7, "R7", m_r[ 7]).formatstr("%08X"); - state_add(SH4_R8, "R8", m_r[ 8]).formatstr("%08X"); - state_add(SH4_R9, "R9", m_r[ 9]).formatstr("%08X"); - state_add(SH4_R10, "R10", m_r[10]).formatstr("%08X"); - state_add(SH4_R11, "R11", m_r[11]).formatstr("%08X"); - state_add(SH4_R12, "R12", m_r[12]).formatstr("%08X"); - state_add(SH4_R13, "R13", m_r[13]).formatstr("%08X"); - state_add(SH4_R14, "R14", m_r[14]).formatstr("%08X"); - state_add(SH4_R15, "R15", m_r[15]).formatstr("%08X"); - state_add(SH4_EA, "EA", m_ea).formatstr("%08X"); - state_add(SH4_R0_BK0, "R0 BK 0", m_rbnk[0][0]).formatstr("%08X"); - state_add(SH4_R1_BK0, "R1 BK 0", m_rbnk[0][1]).formatstr("%08X"); - state_add(SH4_R2_BK0, "R2 BK 0", m_rbnk[0][2]).formatstr("%08X"); - state_add(SH4_R3_BK0, "R3 BK 0", m_rbnk[0][3]).formatstr("%08X"); - state_add(SH4_R4_BK0, "R4 BK 0", m_rbnk[0][4]).formatstr("%08X"); - state_add(SH4_R5_BK0, "R5 BK 0", m_rbnk[0][5]).formatstr("%08X"); - state_add(SH4_R6_BK0, "R6 BK 0", m_rbnk[0][6]).formatstr("%08X"); - state_add(SH4_R7_BK0, "R7 BK 0", m_rbnk[0][7]).formatstr("%08X"); - state_add(SH4_R0_BK1, "R0 BK 1", m_rbnk[1][0]).formatstr("%08X"); - state_add(SH4_R1_BK1, "R1 BK 1", m_rbnk[1][1]).formatstr("%08X"); - state_add(SH4_R2_BK1, "R2 BK 1", m_rbnk[1][2]).formatstr("%08X"); - state_add(SH4_R3_BK1, "R3 BK 1", m_rbnk[1][3]).formatstr("%08X"); - state_add(SH4_R4_BK1, "R4 BK 1", m_rbnk[1][4]).formatstr("%08X"); - state_add(SH4_R5_BK1, "R5 BK 1", m_rbnk[1][5]).formatstr("%08X"); - state_add(SH4_R6_BK1, "R6 BK 1", m_rbnk[1][6]).formatstr("%08X"); - state_add(SH4_R7_BK1, "R7 BK 1", m_rbnk[1][7]).formatstr("%08X"); - state_add(SH4_SPC, "SPC", m_spc).formatstr("%08X"); - state_add(SH4_SSR, "SSR", m_ssr).formatstr("%08X"); - state_add(SH4_SGR, "SGR", m_sgr).formatstr("%08X"); - state_add(SH4_FPSCR, "FPSCR", m_fpscr).formatstr("%08X"); - state_add(SH4_FPUL, "FPUL", m_fpul).formatstr("%08X"); - - state_add(SH4_FR0, "FR0", m_debugger_temp).callimport().formatstr("%25s"); - state_add(SH4_FR1, "FR1", m_debugger_temp).callimport().formatstr("%25s"); - state_add(SH4_FR2, "FR2", m_debugger_temp).callimport().formatstr("%25s"); - state_add(SH4_FR3, "FR3", m_debugger_temp).callimport().formatstr("%25s"); - state_add(SH4_FR4, "FR4", m_debugger_temp).callimport().formatstr("%25s"); - state_add(SH4_FR5, "FR5", m_debugger_temp).callimport().formatstr("%25s"); - state_add(SH4_FR6, "FR6", m_debugger_temp).callimport().formatstr("%25s"); - state_add(SH4_FR7, "FR7", m_debugger_temp).callimport().formatstr("%25s"); - state_add(SH4_FR8, "FR8", m_debugger_temp).callimport().formatstr("%25s"); - state_add(SH4_FR9, "FR9", m_debugger_temp).callimport().formatstr("%25s"); - state_add(SH4_FR10, "FR10", m_debugger_temp).callimport().formatstr("%25s"); - state_add(SH4_FR11, "FR11", m_debugger_temp).callimport().formatstr("%25s"); - state_add(SH4_FR12, "FR12", m_debugger_temp).callimport().formatstr("%25s"); - state_add(SH4_FR13, "FR13", m_debugger_temp).callimport().formatstr("%25s"); - state_add(SH4_FR14, "FR14", m_debugger_temp).callimport().formatstr("%25s"); - state_add(SH4_FR15, "FR15", m_debugger_temp).callimport().formatstr("%25s"); - state_add(SH4_XF0, "XF0", m_debugger_temp).callimport().formatstr("%25s"); - state_add(SH4_XF1, "XF1", m_debugger_temp).callimport().formatstr("%25s"); - state_add(SH4_XF2, "XF2", m_debugger_temp).callimport().formatstr("%25s"); - state_add(SH4_XF3, "XF3", m_debugger_temp).callimport().formatstr("%25s"); - state_add(SH4_XF4, "XF4", m_debugger_temp).callimport().formatstr("%25s"); - state_add(SH4_XF5, "XF5", m_debugger_temp).callimport().formatstr("%25s"); - state_add(SH4_XF6, "XF6", m_debugger_temp).callimport().formatstr("%25s"); - state_add(SH4_XF7, "XF7", m_debugger_temp).callimport().formatstr("%25s"); - state_add(SH4_XF8, "XF8", m_debugger_temp).callimport().formatstr("%25s"); - state_add(SH4_XF9, "XF9", m_debugger_temp).callimport().formatstr("%25s"); - state_add(SH4_XF10, "XF10", m_debugger_temp).callimport().formatstr("%25s"); - state_add(SH4_XF11, "XF11", m_debugger_temp).callimport().formatstr("%25s"); - state_add(SH4_XF12, "XF12", m_debugger_temp).callimport().formatstr("%25s"); - state_add(SH4_XF13, "XF13", m_debugger_temp).callimport().formatstr("%25s"); - state_add(SH4_XF14, "XF14", m_debugger_temp).callimport().formatstr("%25s"); - state_add(SH4_XF15, "XF15", m_debugger_temp).callimport().formatstr("%25s"); + + state_add(SH4_DBR, "DBR", m_dbr).formatstr("%08X"); + + state_add(SH4_R0_BK0, "R0 BK 0", m_rbnk[0][0]).formatstr("%08X"); + state_add(SH4_R1_BK0, "R1 BK 0", m_rbnk[0][1]).formatstr("%08X"); + state_add(SH4_R2_BK0, "R2 BK 0", m_rbnk[0][2]).formatstr("%08X"); + state_add(SH4_R3_BK0, "R3 BK 0", m_rbnk[0][3]).formatstr("%08X"); + state_add(SH4_R4_BK0, "R4 BK 0", m_rbnk[0][4]).formatstr("%08X"); + state_add(SH4_R5_BK0, "R5 BK 0", m_rbnk[0][5]).formatstr("%08X"); + state_add(SH4_R6_BK0, "R6 BK 0", m_rbnk[0][6]).formatstr("%08X"); + state_add(SH4_R7_BK0, "R7 BK 0", m_rbnk[0][7]).formatstr("%08X"); + state_add(SH4_R0_BK1, "R0 BK 1", m_rbnk[1][0]).formatstr("%08X"); + state_add(SH4_R1_BK1, "R1 BK 1", m_rbnk[1][1]).formatstr("%08X"); + state_add(SH4_R2_BK1, "R2 BK 1", m_rbnk[1][2]).formatstr("%08X"); + state_add(SH4_R3_BK1, "R3 BK 1", m_rbnk[1][3]).formatstr("%08X"); + state_add(SH4_R4_BK1, "R4 BK 1", m_rbnk[1][4]).formatstr("%08X"); + state_add(SH4_R5_BK1, "R5 BK 1", m_rbnk[1][5]).formatstr("%08X"); + state_add(SH4_R6_BK1, "R6 BK 1", m_rbnk[1][6]).formatstr("%08X"); + state_add(SH4_R7_BK1, "R7 BK 1", m_rbnk[1][7]).formatstr("%08X"); + state_add(SH4_SPC, "SPC", m_spc).formatstr("%08X"); + state_add(SH4_SSR, "SSR", m_ssr).formatstr("%08X"); + state_add(SH4_SGR, "SGR", m_sgr).formatstr("%08X"); + state_add(SH4_FPSCR, "FPSCR", m_fpscr).formatstr("%08X"); + state_add(SH4_FPUL, "FPUL", m_fpul).formatstr("%08X"); + + state_add(SH4_FR0, "FR0", m_debugger_temp).callimport().formatstr("%25s"); + state_add(SH4_FR1, "FR1", m_debugger_temp).callimport().formatstr("%25s"); + state_add(SH4_FR2, "FR2", m_debugger_temp).callimport().formatstr("%25s"); + state_add(SH4_FR3, "FR3", m_debugger_temp).callimport().formatstr("%25s"); + state_add(SH4_FR4, "FR4", m_debugger_temp).callimport().formatstr("%25s"); + state_add(SH4_FR5, "FR5", m_debugger_temp).callimport().formatstr("%25s"); + state_add(SH4_FR6, "FR6", m_debugger_temp).callimport().formatstr("%25s"); + state_add(SH4_FR7, "FR7", m_debugger_temp).callimport().formatstr("%25s"); + state_add(SH4_FR8, "FR8", m_debugger_temp).callimport().formatstr("%25s"); + state_add(SH4_FR9, "FR9", m_debugger_temp).callimport().formatstr("%25s"); + state_add(SH4_FR10, "FR10", m_debugger_temp).callimport().formatstr("%25s"); + state_add(SH4_FR11, "FR11", m_debugger_temp).callimport().formatstr("%25s"); + state_add(SH4_FR12, "FR12", m_debugger_temp).callimport().formatstr("%25s"); + state_add(SH4_FR13, "FR13", m_debugger_temp).callimport().formatstr("%25s"); + state_add(SH4_FR14, "FR14", m_debugger_temp).callimport().formatstr("%25s"); + state_add(SH4_FR15, "FR15", m_debugger_temp).callimport().formatstr("%25s"); + state_add(SH4_XF0, "XF0", m_debugger_temp).callimport().formatstr("%25s"); + state_add(SH4_XF1, "XF1", m_debugger_temp).callimport().formatstr("%25s"); + state_add(SH4_XF2, "XF2", m_debugger_temp).callimport().formatstr("%25s"); + state_add(SH4_XF3, "XF3", m_debugger_temp).callimport().formatstr("%25s"); + state_add(SH4_XF4, "XF4", m_debugger_temp).callimport().formatstr("%25s"); + state_add(SH4_XF5, "XF5", m_debugger_temp).callimport().formatstr("%25s"); + state_add(SH4_XF6, "XF6", m_debugger_temp).callimport().formatstr("%25s"); + state_add(SH4_XF7, "XF7", m_debugger_temp).callimport().formatstr("%25s"); + state_add(SH4_XF8, "XF8", m_debugger_temp).callimport().formatstr("%25s"); + state_add(SH4_XF9, "XF9", m_debugger_temp).callimport().formatstr("%25s"); + state_add(SH4_XF10, "XF10", m_debugger_temp).callimport().formatstr("%25s"); + state_add(SH4_XF11, "XF11", m_debugger_temp).callimport().formatstr("%25s"); + state_add(SH4_XF12, "XF12", m_debugger_temp).callimport().formatstr("%25s"); + state_add(SH4_XF13, "XF13", m_debugger_temp).callimport().formatstr("%25s"); + state_add(SH4_XF14, "XF14", m_debugger_temp).callimport().formatstr("%25s"); + state_add(SH4_XF15, "XF15", m_debugger_temp).callimport().formatstr("%25s"); state_add(STATE_GENPC, "GENPC", m_debugger_temp).callimport().callexport().noshow(); - state_add(STATE_GENPCBASE, "CURPC", m_ppc).noshow(); - state_add(STATE_GENSP, "GENSP", m_r[15]).noshow(); - state_add(STATE_GENFLAGS, "GENFLAGS", m_sr).formatstr("%20s").noshow(); + //state_add(STATE_GENPCBASE, "CURPC", m_ppc).noshow(); + state_add( STATE_GENPCBASE, "CURPC", m_sh2_state->pc ).callimport().noshow(); - m_icountptr = &m_sh4_icount; + + drc_start(); } void sh34_base_device::state_import(const device_state_entry &entry) @@ -4432,12 +2211,12 @@ void sh34_base_device::state_import(const device_state_entry &entry) switch (entry.index()) { case STATE_GENPC: - m_pc = m_debugger_temp; + m_sh2_state->pc = m_debugger_temp; case SH4_PC: - m_delay = 0; + m_sh2_state->m_delay = 0; break; - case SH4_SR: + case SH_SR: sh4_exception_recompute(); sh4_check_pending_irq("sh4_set_info"); break; @@ -4577,7 +2356,7 @@ void sh34_base_device::state_export(const device_state_entry &entry) switch (entry.index()) { case STATE_GENPC: - m_debugger_temp = (m_pc & AM); + m_debugger_temp = (m_sh2_state->pc & SH34_AM); break; } } @@ -4594,15 +2373,15 @@ void sh34_base_device::state_string_export(const device_state_entry &entry, std: { case STATE_GENFLAGS: str = string_format("%s%s%s%s%c%c%d%c%c", - m_sr & MD ? "MD ":" ", - m_sr & sRB ? "RB ":" ", - m_sr & BL ? "BL ":" ", - m_sr & FD ? "FD ":" ", - m_sr & M ? 'M':'.', - m_sr & Q ? 'Q':'.', - (m_sr & I) >> 4, - m_sr & S ? 'S':'.', - m_sr & T ? 'T':'.'); + m_sh2_state->sr & MD ? "MD ":" ", + m_sh2_state->sr & sRB ? "RB ":" ", + m_sh2_state->sr & BL ? "BL ":" ", + m_sh2_state->sr & FD ? "FD ":" ", + m_sh2_state->sr & SH_M ? 'M':'.', + m_sh2_state->sr & SH_Q ? 'Q':'.', + (m_sh2_state->sr & SH_I) >> 4, + m_sh2_state->sr & SH_S ? 'S':'.', + m_sh2_state->sr & SH_T ? 'T':'.'); break; case SH4_FR0: @@ -4736,8 +2515,1384 @@ void sh34_base_device::state_string_export(const device_state_entry &entry, std: } } - +/* void sh34_base_device::sh4_set_ftcsr_callback(sh4_ftcsr_callback callback) { - m_ftcsr_read_callback = callback; + m_ftcsr_read_callback = callback; +} +*/ + +using namespace uml; + +const opcode_desc* sh4be_device::get_desclist(offs_t pc) +{ + return m_drcfe->describe_code(pc); } + +void sh4be_device::init_drc_frontend() +{ + m_drcfe = std::make_unique<sh4be_frontend>(this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, SINGLE_INSTRUCTION_MODE ? 1 : COMPILE_MAX_SEQUENCE); +} + + +const opcode_desc* sh4_device::get_desclist(offs_t pc) +{ + return m_drcfe->describe_code(pc); +} + +void sh4_device::init_drc_frontend() +{ + m_drcfe = std::make_unique<sh4_frontend>(this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, SINGLE_INSTRUCTION_MODE ? 1 : COMPILE_MAX_SEQUENCE); +} + +const opcode_desc* sh3be_device::get_desclist(offs_t pc) +{ + return m_drcfe->describe_code(pc); +} + +void sh3be_device::init_drc_frontend() +{ + m_drcfe = std::make_unique<sh4be_frontend>(this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, SINGLE_INSTRUCTION_MODE ? 1 : COMPILE_MAX_SEQUENCE); +} + +const opcode_desc* sh3_device::get_desclist(offs_t pc) +{ + return m_drcfe->describe_code(pc); +} + +void sh3_device::init_drc_frontend() +{ + m_drcfe = std::make_unique<sh4_frontend>(this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, SINGLE_INSTRUCTION_MODE ? 1 : COMPILE_MAX_SEQUENCE); +} + +/*------------------------------------------------- + generate_update_cycles - generate code to + subtract cycles from the icount and generate + an exception if out +-------------------------------------------------*/ + +void sh34_base_device::func_CHECKIRQ() { if (m_test_irq) sh4_check_pending_irq("mame_sh4_execute"); } +static void cfunc_CHECKIRQ(void *param) { ((sh34_base_device *)param)->func_CHECKIRQ(); }; + +void sh34_base_device::generate_update_cycles(drcuml_block *block, compiler_state *compiler, uml::parameter param, bool allow_exception) +{ + /* check full interrupts if pending */ + if (compiler->checkints) + { + compiler->checkints = false; + + /* param is pc + 2 (the opcode after the current one) + as we're calling from opcode handlers here that will point to the current opcode instead + but I believe the exception function requires it to point to the next one so update the + local copy of the PC variable here for that? */ + UML_MOV(block, mem(&m_sh2_state->pc), param); + + // save_fast_iregs(block); + UML_CALLC(block, cfunc_CHECKIRQ, this); + load_fast_iregs(block); + + /* generate a hash jump via the current mode and PC + pc should be pointing to either the exception address + or have been left on the next PC set above? */ + UML_HASHJMP(block, 0, mem(&m_sh2_state->pc), *m_nocode); // hashjmp <mode>,<pc>,nocode + } + + /* account for cycles */ + if (compiler->cycles > 0) + { + UML_SUB(block, mem(&m_sh2_state->icount), mem(&m_sh2_state->icount), MAPVAR_CYCLES); // sub icount,icount,cycles + UML_MAPVAR(block, MAPVAR_CYCLES, 0); // mapvar cycles,0 + if (allow_exception) + UML_EXHc(block, COND_S, *m_out_of_cycles, param); + // exh out_of_cycles,nextpc + } + compiler->cycles = 0; +} + +/*------------------------------------------------- + static_generate_entry_point - generate a + static entry point +-------------------------------------------------*/ + + +void sh34_base_device::static_generate_entry_point() +{ + + drcuml_state *drcuml = m_drcuml.get(); + //code_label skip = 1; + drcuml_block *block; + + /* begin generating */ + block = drcuml->begin_block(200); + + /* forward references */ + alloc_handle(drcuml, &m_nocode, "nocode"); + alloc_handle(drcuml, &m_write32, "write32"); // necessary? + alloc_handle(drcuml, &m_entry, "entry"); + UML_HANDLE(block, *m_entry); // handle entry + + UML_CALLC(block, cfunc_CHECKIRQ, this); + load_fast_iregs(block); + + /* generate a hash jump via the current mode and PC */ + UML_HASHJMP(block, 0, mem(&m_sh2_state->pc), *m_nocode); // hashjmp <mode>,<pc>,nocode + + block->end(); + +} + + +/*------------------------------------------------------------------ + static_generate_memory_accessor +------------------------------------------------------------------*/ + +void sh34_base_device::static_generate_memory_accessor(int size, int iswrite, const char *name, code_handle **handleptr) +{ + /* on entry, address is in I0; data for writes is in I1 */ + /* on exit, read result is in I0 */ + /* routine trashes I0 */ + drcuml_state *drcuml = m_drcuml.get(); + drcuml_block *block; + int label = 1; + + /* begin generating */ + block = drcuml->begin_block(1024); + + /* add a global entry for this */ + alloc_handle(drcuml, handleptr, name); + UML_HANDLE(block, **handleptr); // handle *handleptr + +#if 0 + if (A >= 0xe0000000) + { + m_program->write_word(A, V); + return; + } + + if (A >= 0x80000000) // P1/P2/P3 region + { + m_program->write_word(A & SH34_AM, V); + } + else + { + // MMU handling + m_program->write_word(A & SH34_AM, V); + } +#endif + + UML_CMP(block, I0, 0xe0000000); + UML_JMPc(block, COND_AE, label); + + UML_AND(block, I0, I0, SH34_AM); // and r0, r0, #AM (0x1fffffff) + + UML_LABEL(block, label++); // label: + + for (auto & elem : m_fastram) + { + if (elem.base != nullptr && (!iswrite || !elem.readonly)) + { + void *fastbase = (uint8_t *)elem.base - elem.start; + uint32_t skip = label++; + if (elem.end != 0xffffffff) + { + UML_CMP(block, I0, elem.end); // cmp i0,end + UML_JMPc(block, COND_A, skip); // ja skip + } + if (elem.start != 0x00000000) + { + UML_CMP(block, I0, elem.start);// cmp i0,fastram_start + UML_JMPc(block, COND_B, skip); // jb skip + } + + if (!iswrite) + { + if (size == 1) + { + UML_XOR(block, I0, I0, m_bigendian ? BYTE8_XOR_BE(0) : BYTE8_XOR_LE(0)); + UML_LOAD(block, I0, fastbase, I0, SIZE_BYTE, SCALE_x1); // load i0,fastbase,i0,byte + } + else if (size == 2) + { + UML_XOR(block, I0, I0, m_bigendian ? WORD2_XOR_BE(0) : WORD2_XOR_LE(0)); + UML_LOAD(block, I0, fastbase, I0, SIZE_WORD, SCALE_x1); // load i0,fastbase,i0,word_x1 + } + else if (size == 4) + { + + UML_XOR(block, I0, I0, m_bigendian ? DWORD_XOR_BE(0) : DWORD_XOR_LE(0)); + UML_LOAD(block, I0, fastbase, I0, SIZE_DWORD, SCALE_x1); // load i0,fastbase,i0,dword_x1 + } + UML_RET(block); // ret + } + else + { + if (size == 1) + { + UML_XOR(block, I0, I0, m_bigendian ? BYTE8_XOR_BE(0) : BYTE8_XOR_LE(0)); + UML_STORE(block, fastbase, I0, I1, SIZE_BYTE, SCALE_x1);// store fastbase,i0,i1,byte + } + else if (size == 2) + { + UML_XOR(block, I0, I0, m_bigendian ? WORD2_XOR_BE(0) : WORD2_XOR_LE(0)); + UML_STORE(block, fastbase, I0, I1, SIZE_WORD, SCALE_x1);// store fastbase,i0,i1,word_x1 + } + else if (size == 4) + { + UML_XOR(block, I0, I0, m_bigendian ? DWORD_XOR_BE(0) : DWORD_XOR_LE(0)); + UML_STORE(block, fastbase, I0, I1, SIZE_DWORD, SCALE_x1); // store fastbase,i0,i1,dword_x1 + } + UML_RET(block); // ret + } + + UML_LABEL(block, skip); // skip: + } + } + + if (iswrite) + { + switch (size) + { + case 1: + UML_WRITE(block, I0, I1, SIZE_BYTE, SPACE_PROGRAM); // write r0, r1, program_byte + break; + + case 2: + UML_WRITE(block, I0, I1, SIZE_WORD, SPACE_PROGRAM); // write r0, r1, program_word + break; + + case 4: + UML_WRITE(block, I0, I1, SIZE_DWORD, SPACE_PROGRAM); // write r0, r1, program_dword + break; + } + } + else + { + switch (size) + { + case 1: + UML_READ(block, I0, I0, SIZE_BYTE, SPACE_PROGRAM); // read r0, program_byte + break; + + case 2: + UML_READ(block, I0, I0, SIZE_WORD, SPACE_PROGRAM); // read r0, program_word + break; + + case 4: + UML_READ(block, I0, I0, SIZE_DWORD, SPACE_PROGRAM); // read r0, program_dword + break; + } + } + + UML_RET(block); // ret + + block->end(); +} + +bool sh34_base_device::generate_group_0(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + switch (opcode & 0xff) + { + default: + // fall through to SH2 handlers + return sh_common_execution::generate_group_0(block, compiler, desc, opcode, in_delay_slot, ovrpc); + + case 0x52: + case 0x62: + case 0x43: + case 0x63: + case 0xe3: + case 0x68: + case 0xe8: + case 0x4a: + case 0xca: + return true; // ILLEGAL(); break; // illegal on sh4 + + case 0x93: + case 0xa3: + case 0xb3: + return true; // TODO(opcode); break; + + case 0x82: + case 0x92: + case 0xa2: + case 0xb2: + case 0xc2: + case 0xd2: + case 0xe2: + case 0xf2: + return generate_group_0_STCRBANK(block, compiler, desc, opcode, in_delay_slot, ovrpc); + + case 0x32: return generate_group_0_STCSSR(block, compiler, desc, opcode, in_delay_slot, ovrpc); // sh4 only + case 0x42: return generate_group_0_STCSPC(block, compiler, desc, opcode, in_delay_slot, ovrpc); // sh4 only + case 0x83: return generate_group_0_PREFM(block, compiler, desc, opcode, in_delay_slot, ovrpc); // sh4 only + case 0xc3: return generate_group_0_MOVCAL(block, compiler, desc, opcode, in_delay_slot, ovrpc); // sh4 only + + case 0x38: + case 0xb8: + return generate_group_0_LDTLB(block, compiler, desc, opcode, in_delay_slot, ovrpc); // sh4 only + + case 0x48: + case 0xc8: + return generate_group_0_CLRS(block, compiler, desc, opcode, in_delay_slot, ovrpc); // sh4 only + + case 0x58: + case 0xd8: + return generate_group_0_SETS(block, compiler, desc, opcode, in_delay_slot, ovrpc); // sh4 only + + case 0x3a: + case 0xba: + return generate_group_0_STCSGR(block, compiler, desc, opcode, in_delay_slot, ovrpc); // sh4 only + + case 0x5a: + case 0xda: + return generate_group_0_STSFPUL(block, compiler, desc, opcode, in_delay_slot, ovrpc); // sh4 only + + case 0x6a: + case 0xea: + return generate_group_0_STSFPSCR(block, compiler, desc, opcode, in_delay_slot, ovrpc); // sh4 only + + case 0x7a: + case 0xfa: + return generate_group_0_STCDBR(block, compiler, desc, opcode, in_delay_slot, ovrpc); // sh4 only + } + + return false; +} + +void sh34_base_device::func_STCRBANK() { STCRBANK(m_sh2_state->arg0); } +static void cfunc_STCRBANK(void *param) { ((sh34_base_device *)param)->func_STCRBANK(); }; + +bool sh34_base_device::generate_group_0_STCRBANK(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_STCRBANK, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_STCSSR() { STCSSR(m_sh2_state->arg0); } +static void cfunc_STCSSR(void *param) { ((sh34_base_device *)param)->func_STCSSR(); }; + +bool sh34_base_device::generate_group_0_STCSSR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_STCSSR, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_STCSPC() { STCSPC(m_sh2_state->arg0); } +static void cfunc_STCSPC(void *param) { ((sh34_base_device *)param)->func_STCSPC(); }; + +bool sh34_base_device::generate_group_0_STCSPC(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_STCSPC, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_PREFM() { PREFM(m_sh2_state->arg0); } +static void cfunc_PREFM(void *param) { ((sh34_base_device *)param)->func_PREFM(); }; + +bool sh34_base_device::generate_group_0_PREFM(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_PREFM, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_MOVCAL() { MOVCAL(m_sh2_state->arg0); } +static void cfunc_MOVCAL(void *param) { ((sh34_base_device *)param)->func_MOVCAL(); }; + +bool sh34_base_device::generate_group_0_MOVCAL(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_MOVCAL, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_LDTLB() { LDTLB(m_sh2_state->arg0); } +static void cfunc_LDTLB(void *param) { ((sh34_base_device *)param)->func_LDTLB(); }; + +bool sh34_base_device::generate_group_0_LDTLB(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_LDTLB, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_CLRS() { CLRS(m_sh2_state->arg0); } +static void cfunc_CLRS(void *param) { ((sh34_base_device *)param)->func_CLRS(); }; + +bool sh34_base_device::generate_group_0_CLRS(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_CLRS, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_SETS() { SETS(m_sh2_state->arg0); } +static void cfunc_SETS(void *param) { ((sh34_base_device *)param)->func_SETS(); }; + +bool sh34_base_device::generate_group_0_SETS(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_SETS, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_STCSGR() { STCSGR(m_sh2_state->arg0); } +static void cfunc_STCSGR(void *param) { ((sh34_base_device *)param)->func_STCSGR(); }; + +bool sh34_base_device::generate_group_0_STCSGR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_STCSGR, this); + load_fast_iregs(block); + return true; + +} + +void sh34_base_device::func_STSFPUL() { STSFPUL(m_sh2_state->arg0); } +static void cfunc_STSFPUL(void *param) { ((sh34_base_device *)param)->func_STSFPUL(); }; + +bool sh34_base_device::generate_group_0_STSFPUL(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_STSFPUL, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_STSFPSCR() { STSFPSCR(m_sh2_state->arg0); } +static void cfunc_STSFPSCR(void *param) { ((sh34_base_device *)param)->func_STSFPSCR(); }; + +bool sh34_base_device::generate_group_0_STSFPSCR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_STSFPSCR, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_STCDBR() { STCDBR(m_sh2_state->arg0); } +static void cfunc_STCDBR(void *param) { ((sh34_base_device *)param)->func_STCDBR(); }; + +bool sh34_base_device::generate_group_0_STCDBR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_STCDBR, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_RTE() { RTE(); } +static void cfunc_RTE(void *param) { ((sh34_base_device *)param)->func_RTE(); }; + +bool sh34_base_device::generate_group_0_RTE(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + generate_delay_slot(block, compiler, desc, 0xffffffff); + save_fast_iregs(block); + UML_CALLC(block, cfunc_RTE, this); + load_fast_iregs(block); + + compiler->checkints = true; + + UML_MOV(block, mem(&m_sh2_state->pc), mem(&m_sh2_state->m_delay)); + generate_update_cycles(block, compiler, mem(&m_sh2_state->ea), true); // <subtract cycles> + UML_HASHJMP(block, 0, mem(&m_sh2_state->pc), *m_nocode); // and jump to the "resume PC" + return true; +} + +void sh34_base_device::func_TRAPA() { TRAPA(m_sh2_state->arg0 & 0xff); } +static void cfunc_TRAPA(void *param) { ((sh34_base_device *)param)->func_TRAPA(); }; + +bool sh34_base_device::generate_group_12_TRAPA(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_MOV(block, mem(&m_sh2_state->pc), desc->pc + 2); // copy the PC because we need to use it + UML_CALLC(block, cfunc_TRAPA, this); + load_fast_iregs(block); + UML_HASHJMP(block, 0, mem(&m_sh2_state->pc), *m_nocode); + return true; +} + +void sh34_base_device::func_LDCSR() { LDCSR(m_sh2_state->arg0); } +static void cfunc_LDCSR(void *param) { ((sh34_base_device *)param)->func_LDCSR(); }; + +bool sh34_base_device::generate_group_4_LDCSR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_LDCSR, this); + load_fast_iregs(block); + + compiler->checkints = true; + + return true; +} + +void sh34_base_device::func_LDCMSR() { LDCMSR(m_sh2_state->arg0); } +static void cfunc_LDCMSR(void *param) { ((sh34_base_device *)param)->func_LDCMSR(); }; + +bool sh34_base_device::generate_group_4_LDCMSR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_LDCMSR, this); + load_fast_iregs(block); + + compiler->checkints = true; + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + + return true; +} + +void sh34_base_device::func_SHAD() { SHAD(m_sh2_state->arg0); } +static void cfunc_SHAD(void *param) { ((sh34_base_device *)param)->func_SHAD(); }; + +bool sh34_base_device::generate_group_4_SHAD(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_SHAD, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_SHLD() { SHLD(m_sh2_state->arg0); } +static void cfunc_SHLD(void *param) { ((sh34_base_device *)param)->func_SHLD(); }; + +bool sh34_base_device::generate_group_4_SHLD(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_SHLD, this); + load_fast_iregs(block); + return true; +} + +bool sh34_base_device::generate_group_4(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + switch (opcode & 0xff) + { + default: // LDCMSR (0x0e) has sh2/4 flag difference + // fall through to SH2 handlers + return sh_common_execution::generate_group_4(block, compiler, desc, opcode, in_delay_slot, ovrpc); break; + + case 0x42: + case 0x46: + case 0x4a: + case 0x53: + case 0x57: + case 0x5e: + case 0x63: + case 0x67: + case 0x6e: + case 0x82: + case 0x86: + case 0x8a: + case 0x92: + case 0x96: + case 0x9a: + case 0xa2: + case 0xa6: + case 0xaa: + case 0xc2: + case 0xc6: + case 0xca: + case 0xd2: + case 0xd6: + case 0xda: + case 0xe2: + case 0xe6: + case 0xea: + return true; // ILLEGAL(); break; // defined as illegal on SH4 + + case 0x0c: + case 0x1c: + case 0x2c: + case 0x3c: + case 0x4c: + case 0x5c: + case 0x6c: + case 0x7c: + case 0x8c: + case 0x9c: + case 0xac: + case 0xbc: + case 0xcc: + case 0xdc: + case 0xec: + case 0xfc: + return generate_group_4_SHAD(block, compiler, desc, opcode, in_delay_slot, ovrpc); break; + + case 0x0d: + case 0x1d: + case 0x2d: + case 0x3d: + case 0x4d: + case 0x5d: + case 0x6d: + case 0x7d: + case 0x8d: + case 0x9d: + case 0xad: + case 0xbd: + case 0xcd: + case 0xdd: + case 0xed: + case 0xfd: + return generate_group_4_SHLD(block, compiler, desc, opcode, in_delay_slot, ovrpc); break; + + case 0x8e: + case 0x9e: + case 0xae: + case 0xbe: + case 0xce: + case 0xde: + case 0xee: + case 0xfe: + return generate_group_4_LDCRBANK(block, compiler, desc, opcode, in_delay_slot, ovrpc); // sh3/4 only + + case 0x83: + case 0x93: + case 0xa3: + case 0xb3: + case 0xc3: + case 0xd3: + case 0xe3: + case 0xf3: + return generate_group_4_STCMRBANK(block, compiler, desc, opcode, in_delay_slot, ovrpc); // sh3/4 only + + case 0x87: + case 0x97: + case 0xa7: + case 0xb7: + case 0xc7: + case 0xd7: + case 0xe7: + case 0xf7: + return generate_group_4_LDCMRBANK(block, compiler, desc, opcode, in_delay_slot, ovrpc); // sh4 only + + case 0x32: return generate_group_4_STCMSGR(block, compiler, desc, opcode, in_delay_slot, ovrpc); + case 0x33: return generate_group_4_STCMSSR(block, compiler, desc, opcode, in_delay_slot, ovrpc); + case 0x37: return generate_group_4_LDCMSSR(block, compiler, desc, opcode, in_delay_slot, ovrpc); + case 0x3e: return generate_group_4_LDCSSR(block, compiler, desc, opcode, in_delay_slot, ovrpc); + case 0x43: return generate_group_4_STCMSPC(block, compiler, desc, opcode, in_delay_slot, ovrpc); + case 0x47: return generate_group_4_LDCMSPC(block, compiler, desc, opcode, in_delay_slot, ovrpc); + case 0x4e: return generate_group_4_LDCSPC(block, compiler, desc, opcode, in_delay_slot, ovrpc); + case 0x52: return generate_group_4_STSMFPUL(block, compiler, desc, opcode, in_delay_slot, ovrpc); + case 0x56: return generate_group_4_LDSMFPUL(block, compiler, desc, opcode, in_delay_slot, ovrpc); + case 0x5a: return generate_group_4_LDSFPUL(block, compiler, desc, opcode, in_delay_slot, ovrpc); + case 0x62: return generate_group_4_STSMFPSCR(block, compiler, desc, opcode, in_delay_slot, ovrpc); + case 0x66: return generate_group_4_LDSMFPSCR(block, compiler, desc, opcode, in_delay_slot, ovrpc); + case 0x6a: return generate_group_4_LDSFPSCR(block, compiler, desc, opcode, in_delay_slot, ovrpc); + case 0xf2: return generate_group_4_STCMDBR(block, compiler, desc, opcode, in_delay_slot, ovrpc); + case 0xf6: return generate_group_4_LDCMDBR(block, compiler, desc, opcode, in_delay_slot, ovrpc); + case 0xfa: return generate_group_4_LDCDBR(block, compiler, desc, opcode, in_delay_slot, ovrpc); + } + return false; +} + + +void sh34_base_device::func_LDCRBANK() { LDCRBANK(m_sh2_state->arg0); } +static void cfunc_LDCRBANK(void *param) { ((sh34_base_device *)param)->func_LDCRBANK(); }; + +bool sh34_base_device::generate_group_4_LDCRBANK(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_LDCRBANK, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_STCMRBANK() { STCMRBANK(m_sh2_state->arg0); } +static void cfunc_STCMRBANK(void *param) { ((sh34_base_device *)param)->func_STCMRBANK(); }; + +bool sh34_base_device::generate_group_4_STCMRBANK(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_STCMRBANK, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_LDCMRBANK() { LDCMRBANK(m_sh2_state->arg0); } +static void cfunc_LDCMRBANK(void *param) { ((sh34_base_device *)param)->func_LDCMRBANK(); }; + +bool sh34_base_device::generate_group_4_LDCMRBANK(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_LDCMRBANK, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_STCMSGR() { STCMSGR(m_sh2_state->arg0); } +static void cfunc_STCMSGR(void *param) { ((sh34_base_device *)param)->func_STCMSGR(); }; + +bool sh34_base_device::generate_group_4_STCMSGR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_STCMSGR, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_STCMSSR() { STCMSSR(m_sh2_state->arg0); } +static void cfunc_STCMSSR(void *param) { ((sh34_base_device *)param)->func_STCMSSR(); }; + +bool sh34_base_device::generate_group_4_STCMSSR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_STCMSSR, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_LDCMSSR() { LDCMSSR(m_sh2_state->arg0); } +static void cfunc_LDCMSSR(void *param) { ((sh34_base_device *)param)->func_LDCMSSR(); }; + +bool sh34_base_device::generate_group_4_LDCMSSR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_LDCMSSR, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_LDCSSR() { LDCSSR(m_sh2_state->arg0); } +static void cfunc_LDCSSR(void *param) { ((sh34_base_device *)param)->func_LDCSSR(); }; + +bool sh34_base_device::generate_group_4_LDCSSR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_LDCSSR, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_STCMSPC() { STCMSPC(m_sh2_state->arg0); } +static void cfunc_STCMSPC(void *param) { ((sh34_base_device *)param)->func_STCMSPC(); }; + +bool sh34_base_device::generate_group_4_STCMSPC(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_STCMSPC, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_LDCMSPC() { LDCMSPC(m_sh2_state->arg0); } +static void cfunc_LDCMSPC(void *param) { ((sh34_base_device *)param)->func_LDCMSPC(); }; + +bool sh34_base_device::generate_group_4_LDCMSPC(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_LDCMSPC, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_LDCSPC() { LDCSPC(m_sh2_state->arg0); } +static void cfunc_LDCSPC(void *param) { ((sh34_base_device *)param)->func_LDCSPC(); }; + +bool sh34_base_device::generate_group_4_LDCSPC(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_LDCSPC, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_STSMFPUL() { STSMFPUL(m_sh2_state->arg0); } +static void cfunc_STSMFPUL(void *param) { ((sh34_base_device *)param)->func_STSMFPUL(); }; + +bool sh34_base_device::generate_group_4_STSMFPUL(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_STSMFPUL, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_LDSMFPUL() { LDSMFPUL(m_sh2_state->arg0); } +static void cfunc_LDSMFPUL(void *param) { ((sh34_base_device *)param)->func_LDSMFPUL(); }; + +bool sh34_base_device::generate_group_4_LDSMFPUL(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_LDSMFPUL, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_LDSFPUL() { LDSFPUL(m_sh2_state->arg0); } +static void cfunc_LDSFPUL(void *param) { ((sh34_base_device *)param)->func_LDSFPUL(); }; + +bool sh34_base_device::generate_group_4_LDSFPUL(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_LDSFPUL, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_STSMFPSCR() { STSMFPSCR(m_sh2_state->arg0); } +static void cfunc_STSMFPSCR(void *param) { ((sh34_base_device *)param)->func_STSMFPSCR(); }; + +bool sh34_base_device::generate_group_4_STSMFPSCR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_STSMFPSCR, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_LDSMFPSCR() { LDSMFPSCR(m_sh2_state->arg0); } +static void cfunc_LDSMFPSCR(void *param) { ((sh34_base_device *)param)->func_LDSMFPSCR(); }; + + +bool sh34_base_device::generate_group_4_LDSMFPSCR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_LDSMFPSCR, this); + load_fast_iregs(block); + return true; +} + + +void sh34_base_device::func_LDSFPSCR() { LDSFPSCR(m_sh2_state->arg0); } +static void cfunc_LDSFPSCR(void *param) { ((sh34_base_device *)param)->func_LDSFPSCR(); }; + +bool sh34_base_device::generate_group_4_LDSFPSCR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_LDSFPSCR, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_STCMDBR() { STCMDBR(m_sh2_state->arg0); } +static void cfunc_STCMDBR(void *param) { ((sh34_base_device *)param)->func_STCMDBR(); }; + +bool sh34_base_device::generate_group_4_STCMDBR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_STCMDBR, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_LDCMDBR() { LDCMDBR(m_sh2_state->arg0); } +static void cfunc_LDCMDBR(void *param) { ((sh34_base_device *)param)->func_LDCMDBR(); }; + +bool sh34_base_device::generate_group_4_LDCMDBR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_LDCMDBR, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_LDCDBR() { LDCDBR(m_sh2_state->arg0); } +static void cfunc_LDCDBR(void *param) { ((sh34_base_device *)param)->func_LDCDBR(); }; + +bool sh34_base_device::generate_group_4_LDCDBR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_LDCDBR, this); + load_fast_iregs(block); + return true; +} + +bool sh34_base_device::generate_group_15(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + switch (opcode & 0x0f) + { + case 0x00: return generate_group_15_FADD(block, compiler, desc, opcode, in_delay_slot, ovrpc); + case 0x01: return generate_group_15_FSUB(block, compiler, desc, opcode, in_delay_slot, ovrpc); + case 0x02: return generate_group_15_FMUL(block, compiler, desc, opcode, in_delay_slot, ovrpc); + case 0x03: return generate_group_15_FDIV(block, compiler, desc, opcode, in_delay_slot, ovrpc); + case 0x04: return generate_group_15_FCMP_EQ(block, compiler, desc, opcode, in_delay_slot, ovrpc); + case 0x05: return generate_group_15_FCMP_GT(block, compiler, desc, opcode, in_delay_slot, ovrpc); + case 0x06: return generate_group_15_FMOVS0FR(block, compiler, desc, opcode, in_delay_slot, ovrpc); + case 0x07: return generate_group_15_FMOVFRS0(block, compiler, desc, opcode, in_delay_slot, ovrpc); + case 0x08: return generate_group_15_FMOVMRFR(block, compiler, desc, opcode, in_delay_slot, ovrpc); + case 0x09: return generate_group_15_FMOVMRIFR(block, compiler, desc, opcode, in_delay_slot, ovrpc); + case 0x0a: return generate_group_15_FMOVFRMR(block, compiler, desc, opcode, in_delay_slot, ovrpc); + case 0x0b: return generate_group_15_FMOVFRMDR(block, compiler, desc, opcode, in_delay_slot, ovrpc); + case 0x0c: return generate_group_15_FMOVFR(block, compiler, desc, opcode, in_delay_slot, ovrpc); + case 0x0d: return generate_group_15_op1111_0x13(block, compiler, desc, opcode, in_delay_slot, ovrpc); + case 0x0e: return generate_group_15_FMAC(block, compiler, desc, opcode, in_delay_slot, ovrpc); + case 0x0f: + return true; + //if (opcode == 0xffff) return true; // atomiswave uses ffff as NOP? + //return false; // dbreak(opcode); break; + } + return false; +} + +void sh34_base_device::func_FADD() { FADD(m_sh2_state->arg0); } +static void cfunc_FADD(void *param) { ((sh34_base_device *)param)->func_FADD(); }; + +bool sh34_base_device::generate_group_15_FADD(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_FADD, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_FSUB() { FSUB(m_sh2_state->arg0); } +static void cfunc_FSUB(void *param) { ((sh34_base_device *)param)->func_FSUB(); }; + +bool sh34_base_device::generate_group_15_FSUB(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_FSUB, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_FMUL() { FMUL(m_sh2_state->arg0); } +static void cfunc_FMUL(void *param) { ((sh34_base_device *)param)->func_FMUL(); }; + +bool sh34_base_device::generate_group_15_FMUL(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_FMUL, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_FDIV() { FDIV(m_sh2_state->arg0); } +static void cfunc_FDIV(void *param) { ((sh34_base_device *)param)->func_FDIV(); }; + +bool sh34_base_device::generate_group_15_FDIV(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_FDIV, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_FCMP_EQ() { FCMP_EQ(m_sh2_state->arg0); } +static void cfunc_FCMP_EQ(void *param) { ((sh34_base_device *)param)->func_FCMP_EQ(); }; + +bool sh34_base_device::generate_group_15_FCMP_EQ(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_FCMP_EQ, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_FCMP_GT() { FCMP_GT(m_sh2_state->arg0); } +static void cfunc_FCMP_GT(void *param) { ((sh34_base_device *)param)->func_FCMP_GT(); }; + +bool sh34_base_device::generate_group_15_FCMP_GT(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_FCMP_GT, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_FMOVS0FR() { FMOVS0FR(m_sh2_state->arg0); } +static void cfunc_FMOVS0FR(void *param) { ((sh34_base_device *)param)->func_FMOVS0FR(); }; + +bool sh34_base_device::generate_group_15_FMOVS0FR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_FMOVS0FR, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_FMOVFRS0() { FMOVFRS0(m_sh2_state->arg0); } +static void cfunc_FMOVFRS0(void *param) { ((sh34_base_device *)param)->func_FMOVFRS0(); }; + +bool sh34_base_device::generate_group_15_FMOVFRS0(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_FMOVFRS0, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_FMOVMRFR() { FMOVMRFR(m_sh2_state->arg0); } +static void cfunc_FMOVMRFR(void *param) { ((sh34_base_device *)param)->func_FMOVMRFR(); }; + +bool sh34_base_device::generate_group_15_FMOVMRFR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_FMOVMRFR, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_FMOVMRIFR() { FMOVMRIFR(m_sh2_state->arg0); } +static void cfunc_FMOVMRIFR(void *param) { ((sh34_base_device *)param)->func_FMOVMRIFR(); }; + +bool sh34_base_device::generate_group_15_FMOVMRIFR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_FMOVMRIFR, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_FMOVFRMR() { FMOVFRMR(m_sh2_state->arg0); } +static void cfunc_FMOVFRMR(void *param) { ((sh34_base_device *)param)->func_FMOVFRMR(); }; + +bool sh34_base_device::generate_group_15_FMOVFRMR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_FMOVFRMR, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_FMOVFRMDR() { FMOVFRMDR(m_sh2_state->arg0); } +static void cfunc_FMOVFRMDR(void *param) { ((sh34_base_device *)param)->func_FMOVFRMDR(); }; + +bool sh34_base_device::generate_group_15_FMOVFRMDR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_FMOVFRMDR, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_FMOVFR() { FMOVFR(m_sh2_state->arg0); } +static void cfunc_FMOVFR(void *param) { ((sh34_base_device *)param)->func_FMOVFR(); }; + +bool sh34_base_device::generate_group_15_FMOVFR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_FMOVFR, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_FMAC() { FMAC(m_sh2_state->arg0); } +static void cfunc_FMAC(void *param) { ((sh34_base_device *)param)->func_FMAC(); }; + +bool sh34_base_device::generate_group_15_FMAC(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_FMAC, this); + load_fast_iregs(block); + return true; +} + +bool sh34_base_device::generate_group_15_op1111_0x13(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + switch ((opcode >> 4) & 0x0f) + { + case 0x00: return generate_group_15_op1111_0x13_FSTS(block, compiler, desc, opcode, in_delay_slot, ovrpc); // FSTS(opcode); break; + case 0x01: return generate_group_15_op1111_0x13_FLDS(block, compiler, desc, opcode, in_delay_slot, ovrpc); // FLDS(opcode); break; + case 0x02: return generate_group_15_op1111_0x13_FLOAT(block, compiler, desc, opcode, in_delay_slot, ovrpc); // FLOAT(opcode); break; + case 0x03: return generate_group_15_op1111_0x13_FTRC(block, compiler, desc, opcode, in_delay_slot, ovrpc); // FTRC(opcode); break; + case 0x04: return generate_group_15_op1111_0x13_FNEG(block, compiler, desc, opcode, in_delay_slot, ovrpc); // FNEG(opcode); break; + case 0x05: return generate_group_15_op1111_0x13_FABS(block, compiler, desc, opcode, in_delay_slot, ovrpc); // FABS(opcode); break; + case 0x06: return generate_group_15_op1111_0x13_FSQRT(block, compiler, desc, opcode, in_delay_slot, ovrpc); // FSQRT(opcode); break; + case 0x07: return generate_group_15_op1111_0x13_FSRRA(block, compiler, desc, opcode, in_delay_slot, ovrpc); // FSRRA(opcode); break; + case 0x08: return generate_group_15_op1111_0x13_FLDI0(block, compiler, desc, opcode, in_delay_slot, ovrpc); // FLDI0(opcode); break; + case 0x09: return generate_group_15_op1111_0x13_FLDI1(block, compiler, desc, opcode, in_delay_slot, ovrpc); // FLDI1(opcode); break; + case 0x0a: return generate_group_15_op1111_0x13_FCNVSD(block, compiler, desc, opcode, in_delay_slot, ovrpc); // FCNVSD(opcode); break; + case 0x0b: return generate_group_15_op1111_0x13_FCNVDS(block, compiler, desc, opcode, in_delay_slot, ovrpc); // FCNVDS(opcode); break; + case 0x0c: return false; // dbreak(opcode); break; + case 0x0d: return false; //dbreak(opcode); break; + case 0x0e: return generate_group_15_op1111_0x13_FIPR(block, compiler, desc, opcode, in_delay_slot, ovrpc); // FIPR(opcode); break; + case 0x0f: return generate_group_15_op1111_0x13_op1111_0xf13(block, compiler, desc, opcode, in_delay_slot, ovrpc); // op1111_0xf13(opcode); break; + } + return false; +} + +void sh34_base_device::func_FSTS() { FSTS(m_sh2_state->arg0); } +static void cfunc_FSTS(void *param) { ((sh34_base_device *)param)->func_FSTS(); }; + +bool sh34_base_device::generate_group_15_op1111_0x13_FSTS(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_FSTS, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_FLDS() { FLDS(m_sh2_state->arg0); } +static void cfunc_FLDS(void *param) { ((sh34_base_device *)param)->func_FLDS(); }; + +bool sh34_base_device::generate_group_15_op1111_0x13_FLDS(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_FLDS, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_FLOAT() { FLOAT(m_sh2_state->arg0); } +static void cfunc_FLOAT(void *param) { ((sh34_base_device *)param)->func_FLOAT(); }; + +bool sh34_base_device::generate_group_15_op1111_0x13_FLOAT(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_FLOAT, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_FTRC() { FTRC(m_sh2_state->arg0); } +static void cfunc_FTRC(void *param) { ((sh34_base_device *)param)->func_FTRC(); }; + +bool sh34_base_device::generate_group_15_op1111_0x13_FTRC(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_FTRC, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_FNEG() { FNEG(m_sh2_state->arg0); } +static void cfunc_FNEG(void *param) { ((sh34_base_device *)param)->func_FNEG(); }; + +bool sh34_base_device::generate_group_15_op1111_0x13_FNEG(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_FNEG, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_FABS() { FABS(m_sh2_state->arg0); } +static void cfunc_FABS(void *param) { ((sh34_base_device *)param)->func_FABS(); }; + +bool sh34_base_device::generate_group_15_op1111_0x13_FABS(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_FABS, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_FSQRT() { FSQRT(m_sh2_state->arg0); } +static void cfunc_FSQRT(void *param) { ((sh34_base_device *)param)->func_FSQRT(); }; + +bool sh34_base_device::generate_group_15_op1111_0x13_FSQRT(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_FSQRT, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_FSRRA() { FSRRA(m_sh2_state->arg0); } +static void cfunc_FSRRA(void *param) { ((sh34_base_device *)param)->func_FSRRA(); }; + +bool sh34_base_device::generate_group_15_op1111_0x13_FSRRA(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_FSRRA, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_FLDI0() { FLDI0(m_sh2_state->arg0); } +static void cfunc_FLDI0(void *param) { ((sh34_base_device *)param)->func_FLDI0(); }; + +bool sh34_base_device::generate_group_15_op1111_0x13_FLDI0(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_FLDI0, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_FLDI1() { FLDI1(m_sh2_state->arg0); } +static void cfunc_FLDI1(void *param) { ((sh34_base_device *)param)->func_FLDI1(); }; + +bool sh34_base_device::generate_group_15_op1111_0x13_FLDI1(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_FLDI1, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_FCNVSD() { FCNVSD(m_sh2_state->arg0); } +static void cfunc_FCNVSD(void *param) { ((sh34_base_device *)param)->func_FCNVSD(); }; + +bool sh34_base_device::generate_group_15_op1111_0x13_FCNVSD(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_FCNVSD, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_FCNVDS() { FCNVDS(m_sh2_state->arg0); } +static void cfunc_FCNVDS(void *param) { ((sh34_base_device *)param)->func_FCNVDS(); }; + +bool sh34_base_device::generate_group_15_op1111_0x13_FCNVDS(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_FCNVDS, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_FIPR() { FIPR(m_sh2_state->arg0); } +static void cfunc_FIPR(void *param) { ((sh34_base_device *)param)->func_FIPR(); }; + +bool sh34_base_device::generate_group_15_op1111_0x13_FIPR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_FIPR, this); + load_fast_iregs(block); + return true; +} + +bool sh34_base_device::generate_group_15_op1111_0x13_op1111_0xf13(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + if (opcode & 0x100) { + if (opcode & 0x200) { + switch (opcode & 0xC00) + { + case 0x000: + return generate_group_15_op1111_0x13_op1111_0xf13_FSCHG(block, compiler, desc, opcode, in_delay_slot, ovrpc); // FSCHG(); + break; + case 0x800: + return generate_group_15_op1111_0x13_op1111_0xf13_FRCHG(block, compiler, desc, opcode, in_delay_slot, ovrpc); // FRCHG(); + break; + default: + return false; //machine().debug_break(); + break; + } + } + else { + return generate_group_15_op1111_0x13_op1111_0xf13_FTRV(block, compiler, desc, opcode, in_delay_slot, ovrpc); // FTRV(opcode); + } + } + else { + return generate_group_15_op1111_0x13_op1111_0xf13_FSSCA(block, compiler, desc, opcode, in_delay_slot, ovrpc); // FSSCA(opcode); + } + return false; +} + +void sh34_base_device::func_FSCHG() { FSCHG(); } +static void cfunc_FSCHG(void *param) { ((sh34_base_device *)param)->func_FSCHG(); }; + +bool sh34_base_device::generate_group_15_op1111_0x13_op1111_0xf13_FSCHG(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + //UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_FSCHG, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_FRCHG() { FRCHG(); } +static void cfunc_FRCHG(void *param) { ((sh34_base_device *)param)->func_FRCHG(); }; + +bool sh34_base_device::generate_group_15_op1111_0x13_op1111_0xf13_FRCHG(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + //UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_FRCHG, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_FTRV() { FTRV(m_sh2_state->arg0); } +static void cfunc_FTRV(void *param) { ((sh34_base_device *)param)->func_FTRV(); }; + +bool sh34_base_device::generate_group_15_op1111_0x13_op1111_0xf13_FTRV(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_FTRV, this); + load_fast_iregs(block); + return true; +} + +void sh34_base_device::func_FSSCA() { FSSCA(m_sh2_state->arg0); } +static void cfunc_FSSCA(void *param) { ((sh34_base_device *)param)->func_FSSCA(); }; + +bool sh34_base_device::generate_group_15_op1111_0x13_op1111_0xf13_FSSCA(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) +{ + save_fast_iregs(block); + UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_FSSCA, this); + load_fast_iregs(block); + return true; +} + diff --git a/src/devices/cpu/sh/sh4.h b/src/devices/cpu/sh/sh4.h index fad1d326750..6f3c37e862a 100644 --- a/src/devices/cpu/sh/sh4.h +++ b/src/devices/cpu/sh/sh4.h @@ -15,9 +15,7 @@ #pragma once -// doesn't actually seem to improve performance at all -#define SH4_USE_FASTRAM_OPTIMIZATION 0 -#define SH4_MAX_FASTRAM 3 +#include "sh.h" #define SH4_INT_NONE -1 enum @@ -27,10 +25,7 @@ enum enum { - SH4_PC=1, SH4_SR, SH4_PR, SH4_GBR, SH4_VBR, SH4_DBR, SH4_MACH, SH4_MACL, - SH4_R0, SH4_R1, SH4_R2, SH4_R3, SH4_R4, SH4_R5, SH4_R6, SH4_R7, - SH4_R8, SH4_R9, SH4_R10, SH4_R11, SH4_R12, SH4_R13, SH4_R14, SH4_R15, SH4_EA, - SH4_R0_BK0, SH4_R1_BK0, SH4_R2_BK0, SH4_R3_BK0, SH4_R4_BK0, SH4_R5_BK0, SH4_R6_BK0, SH4_R7_BK0, + SH4_R0_BK0 = SH4_EA+1, SH4_R1_BK0, SH4_R2_BK0, SH4_R3_BK0, SH4_R4_BK0, SH4_R5_BK0, SH4_R6_BK0, SH4_R7_BK0, SH4_R0_BK1, SH4_R1_BK1, SH4_R2_BK1, SH4_R3_BK1, SH4_R4_BK1, SH4_R5_BK1, SH4_R6_BK1, SH4_R7_BK1, SH4_SPC, SH4_SSR, SH4_SGR, SH4_FPSCR, SH4_FPUL, SH4_FR0, SH4_FR1, SH4_FR2, SH4_FR3, SH4_FR4, SH4_FR5, SH4_FR6, SH4_FR7, SH4_FR8, SH4_FR9, SH4_FR10, SH4_FR11, SH4_FR12, SH4_FR13, SH4_FR14, SH4_FR15, @@ -195,13 +190,12 @@ typedef void (*sh4_ftcsr_callback)(uint32_t); #define MCFG_MMU_HACK_TYPE(_hacktype) \ sh34_base_device::set_mmu_hacktype(*device, _hacktype); +class sh4_frontend; +class sh4be_frontend; -class sh34_base_device : public cpu_device +class sh34_base_device : public sh_common_execution { public: -//#if SH4_USE_FASTRAM_OPTIMIZATION - void add_fastram(offs_t start, offs_t end, uint8_t readonly, void *base); -//#endif static void set_md0(device_t &device, int md0) { downcast<sh34_base_device &>(device).c_md0 = md0; } static void set_md1(device_t &device, int md0) { downcast<sh34_base_device &>(device).c_md1 = md0; } @@ -223,10 +217,81 @@ public: void sh4_set_frt_input(int state); void sh4_set_irln_input(int value); - void sh4_set_ftcsr_callback(sh4_ftcsr_callback callback); + //void sh4_set_ftcsr_callback(sh4_ftcsr_callback callback); int sh4_dma_data(struct sh4_device_dma *s); void sh4_dma_ddt(struct sh4_ddt_dma *s); + // DRC C-substitute ops + void func_STCRBANK(); + void func_TRAPA(); + void func_LDCSR(); + void func_LDCMSR(); + void func_RTE(); + void func_SHAD(); + void func_SHLD(); + void func_CHECKIRQ(); + void func_LDCRBANK(); + void func_STCMSPC(); + void func_LDCMSPC(); + void func_STCMSSR(); + void func_LDCMSSR(); + void func_STCMRBANK(); + void func_LDCMRBANK(); + void func_PREFM(); + void func_FADD(); + void func_FSUB(); + void func_FMUL(); + void func_FDIV(); + void func_FCMP_EQ(); + void func_FCMP_GT(); + void func_LDSFPSCR(); + void func_LDCDBR(); + void func_FMOVMRIFR(); + void func_FRCHG(); + void func_FSCHG(); + void func_LDSMFPUL(); + void func_LDSMFPSCR(); + void func_FMOVFRMDR(); + void func_LDCSSR(); + void func_STSFPSCR(); + void func_FLDI0(); + void func_FLDI1(); + void func_FMOVFR(); + void func_FMOVFRS0(); + void func_FTRC(); + void func_FMOVMRFR(); + void func_FMOVS0FR(); + void func_STSFPUL(); + void func_FMOVFRMR(); + void func_LDSFPUL(); + void func_FLOAT(); + void func_STSMFPSCR(); + void func_STSMFPUL(); + void func_FNEG(); + void func_FMAC(); + void func_FABS(); + void func_FLDS(); + void func_FTRV(); + void func_FSTS(); + void func_FSSCA(); + void func_FCNVSD(); + void func_FIPR(); + void func_FSRRA(); + void func_FSQRT(); + void func_FCNVDS(); + void func_LDCMDBR(); + void func_STCMDBR(); + void func_LDCSPC(); + void func_STCMSGR(); + void func_STCDBR(); + void func_STCSGR(); + void func_SETS(); + void func_CLRS(); + void func_LDTLB(); + void func_MOVCAL(); + void func_STCSSR(); + void func_STCSPC(); + protected: // construction/destruction sh34_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, endianness_t endianness, address_map_constructor internal); @@ -251,9 +316,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 2; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; address_space_config m_program_config; address_space_config m_io_config; @@ -273,22 +336,12 @@ protected: int m_mmuhack; uint32_t m_ppc; - uint32_t m_pc; uint32_t m_spc; - uint32_t m_pr; - uint32_t m_sr; uint32_t m_ssr; - uint32_t m_gbr; - uint32_t m_vbr; - uint32_t m_mach; - uint32_t m_macl; - uint32_t m_r[16]; uint32_t m_rbnk[2][8]; uint32_t m_sgr; uint32_t m_fr[16]; uint32_t m_xf[16]; - uint32_t m_ea; - uint32_t m_delay; uint32_t m_cpu_off; uint32_t m_pending_irq; uint32_t m_test_irq; @@ -302,7 +355,6 @@ protected: int8_t m_irq_line_state[17]; address_space *m_internal; address_space *m_program; - direct_read_data *m_direct; address_space *m_io; // sh4 internal @@ -352,8 +404,6 @@ protected: int8_t m_nmi_line_state; - uint8_t m_sleep_mode; - int m_frt_input; int m_irln; int m_internal_irq_level; @@ -373,7 +423,6 @@ protected: int m_dma_destination_increment[4]; int m_dma_mode[4]; - int m_sh4_icount; int m_is_slave; int m_cpu_clock; int m_bus_clock; @@ -385,27 +434,25 @@ protected: int m_ioport4_pullup; int m_ioport4_direction; - void (*m_ftcsr_read_callback)(uint32_t data); + int m_willjump; + + //void (*m_ftcsr_read_callback)(uint32_t data); /* This MMU simulation is good for the simple remap used on Naomi GD-ROM SQ access *ONLY* */ uint8_t m_sh4_mmu_enabled; - int m_cpu_type; - // sh3 internal uint32_t m_sh3internal_upper[0x3000/4]; uint32_t m_sh3internal_lower[0x1000]; uint64_t m_debugger_temp; - - void execute_one_0000(const uint16_t opcode); - void execute_one_4000(const uint16_t opcode); - void execute_one(const uint16_t opcode); inline void sh4_check_pending_irq(const char *message) // look for highest priority active exception and handle it { int a,irq,z; + m_willjump = 0; // for the DRC + irq = 0; z = -1; for (a=0;a <= SH4_INTC_ROVI;a++) @@ -425,222 +472,6 @@ protected: } } - void TODO(const uint16_t opcode); - void WB(offs_t A, uint8_t V); - void WW(offs_t A, uint16_t V); - void WL(offs_t A, uint32_t V); - void ADD(const uint16_t opcode); - void ADDI(const uint16_t opcode); - void ADDC(const uint16_t opcode); - void ADDV(const uint16_t opcode); - void AND(const uint16_t opcode); - void ANDI(const uint16_t opcode); - void ANDM(const uint16_t opcode); - void BF(const uint16_t opcode); - void BFS(const uint16_t opcode); - void BRA(const uint16_t opcode); - void BRAF(const uint16_t opcode); - void BSR(const uint16_t opcode); - void BSRF(const uint16_t opcode); - void BT(const uint16_t opcode); - void BTS(const uint16_t opcode); - void CLRMAC(const uint16_t opcode); - void CLRT(const uint16_t opcode); - void CMPEQ(const uint16_t opcode); - void CMPGE(const uint16_t opcode); - void CMPGT(const uint16_t opcode); - void CMPHI(const uint16_t opcode); - void CMPHS(const uint16_t opcode); - void CMPPL(const uint16_t opcode); - void CMPPZ(const uint16_t opcode); - void CMPSTR(const uint16_t opcode); - void CMPIM(const uint16_t opcode); - void DIV0S(const uint16_t opcode); - void DIV0U(const uint16_t opcode); - void DIV1(const uint16_t opcode); - void DMULS(const uint16_t opcode); - void DMULU(const uint16_t opcode); - void DT(const uint16_t opcode); - void EXTSB(const uint16_t opcode); - void EXTSW(const uint16_t opcode); - void EXTUB(const uint16_t opcode); - void EXTUW(const uint16_t opcode); - void JMP(const uint16_t opcode); - void JSR(const uint16_t opcode); - void LDCSR(const uint16_t opcode); - void LDCGBR(const uint16_t opcode); - void LDCVBR(const uint16_t opcode); - void LDCMSR(const uint16_t opcode); - void LDCMGBR(const uint16_t opcode); - void LDCMVBR(const uint16_t opcode); - void LDSMACH(const uint16_t opcode); - void LDSMACL(const uint16_t opcode); - void LDSPR(const uint16_t opcode); - void LDSMMACH(const uint16_t opcode); - void LDSMMACL(const uint16_t opcode); - void LDSMPR(const uint16_t opcode); - virtual void LDTLB(const uint16_t opcode); - void MAC_L(const uint16_t opcode); - void MAC_W(const uint16_t opcode); - void MOV(const uint16_t opcode); - void MOVBS(const uint16_t opcode); - void MOVWS(const uint16_t opcode); - void MOVLS(const uint16_t opcode); - void MOVBL(const uint16_t opcode); - void MOVWL(const uint16_t opcode); - void MOVLL(const uint16_t opcode); - void MOVBM(const uint16_t opcode); - void MOVWM(const uint16_t opcode); - void MOVLM(const uint16_t opcode); - void MOVBP(const uint16_t opcode); - void MOVWP(const uint16_t opcode); - void MOVLP(const uint16_t opcode); - void MOVBS0(const uint16_t opcode); - void MOVWS0(const uint16_t opcode); - void MOVLS0(const uint16_t opcode); - void MOVBL0(const uint16_t opcode); - void MOVWL0(const uint16_t opcode); - void MOVLL0(const uint16_t opcode); - void MOVI(const uint16_t opcode); - void MOVWI(const uint16_t opcode); - void MOVLI(const uint16_t opcode); - void MOVBLG(const uint16_t opcode); - void MOVWLG(const uint16_t opcode); - void MOVLLG(const uint16_t opcode); - void MOVBSG(const uint16_t opcode); - void MOVWSG(const uint16_t opcode); - void MOVLSG(const uint16_t opcode); - void MOVBS4(const uint16_t opcode); - void MOVWS4(const uint16_t opcode); - void MOVLS4(const uint16_t opcode); - void MOVBL4(const uint16_t opcode); - void MOVWL4(const uint16_t opcode); - void MOVLL4(const uint16_t opcode); - void MOVA(const uint16_t opcode); - void MOVT(const uint16_t opcode); - void MULL(const uint16_t opcode); - void MULS(const uint16_t opcode); - void MULU(const uint16_t opcode); - void NEG(const uint16_t opcode); - void NEGC(const uint16_t opcode); - void NOP(const uint16_t opcode); - void NOT(const uint16_t opcode); - void OR(const uint16_t opcode); - void ORI(const uint16_t opcode); - void ORM(const uint16_t opcode); - void ROTCL(const uint16_t opcode); - void ROTCR(const uint16_t opcode); - void ROTL(const uint16_t opcode); - void ROTR(const uint16_t opcode); - void RTE(const uint16_t opcode); - void RTS(const uint16_t opcode); - void SETT(const uint16_t opcode); - void SHAL(const uint16_t opcode); - void SHAR(const uint16_t opcode); - void SHLL(const uint16_t opcode); - void SHLL2(const uint16_t opcode); - void SHLL8(const uint16_t opcode); - void SHLL16(const uint16_t opcode); - void SHLR(const uint16_t opcode); - void SHLR2(const uint16_t opcode); - void SHLR8(const uint16_t opcode); - void SHLR16(const uint16_t opcode); - void SLEEP(const uint16_t opcode); - void STCSR(const uint16_t opcode); - void STCGBR(const uint16_t opcode); - void STCVBR(const uint16_t opcode); - void STCMSR(const uint16_t opcode); - void STCMGBR(const uint16_t opcode); - void STCMVBR(const uint16_t opcode); - void STSMACH(const uint16_t opcode); - void STSMACL(const uint16_t opcode); - void STSPR(const uint16_t opcode); - void STSMMACH(const uint16_t opcode); - void STSMMACL(const uint16_t opcode); - void STSMPR(const uint16_t opcode); - void SUB(const uint16_t opcode); - void SUBC(const uint16_t opcode); - void SUBV(const uint16_t opcode); - void SWAPB(const uint16_t opcode); - void SWAPW(const uint16_t opcode); - void TAS(const uint16_t opcode); - void TRAPA(const uint16_t opcode); - void TST(const uint16_t opcode); - void TSTI(const uint16_t opcode); - void TSTM(const uint16_t opcode); - void XOR(const uint16_t opcode); - void XORI(const uint16_t opcode); - void XORM(const uint16_t opcode); - void XTRCT(const uint16_t opcode); - void STCSSR(const uint16_t opcode); - void STCSPC(const uint16_t opcode); - void STCSGR(const uint16_t opcode); - void STSFPUL(const uint16_t opcode); - void STSFPSCR(const uint16_t opcode); - void STCDBR(const uint16_t opcode); - void STCRBANK(const uint16_t opcode); - void STCMRBANK(const uint16_t opcode); - void MOVCAL(const uint16_t opcode); - void CLRS(const uint16_t opcode); - void SETS(const uint16_t opcode); - void STCMSGR(const uint16_t opcode); - void STSMFPUL(const uint16_t opcode); - void STSMFPSCR(const uint16_t opcode); - void STCMDBR(const uint16_t opcode); - void STCMSSR(const uint16_t opcode); - void STCMSPC(const uint16_t opcode); - void LDSMFPUL(const uint16_t opcode); - void LDSMFPSCR(const uint16_t opcode); - void LDCMDBR(const uint16_t opcode); - void LDCMRBANK(const uint16_t opcode); - void LDCMSSR(const uint16_t opcode); - void LDCMSPC(const uint16_t opcode); - void LDSFPUL(const uint16_t opcode); - void LDSFPSCR(const uint16_t opcode); - void LDCDBR(const uint16_t opcode); - void SHAD(const uint16_t opcode); - void SHLD(const uint16_t opcode); - void LDCRBANK(const uint16_t opcode); - void LDCSSR(const uint16_t opcode); - void LDCSPC(const uint16_t opcode); - void PREFM(const uint16_t opcode); - void FMOVMRIFR(const uint16_t opcode); - void FMOVFRMR(const uint16_t opcode); - void FMOVFRMDR(const uint16_t opcode); - void FMOVFRS0(const uint16_t opcode); - void FMOVS0FR(const uint16_t opcode); - void FMOVMRFR(const uint16_t opcode); - void FMOVFR(const uint16_t opcode); - void FLDI1(const uint16_t opcode); - void FLDI0(const uint16_t opcode); - void FLDS(const uint16_t opcode); - void FSTS(const uint16_t opcode); - void FRCHG(); - void FSCHG(); - void FTRC(const uint16_t opcode); - void FLOAT(const uint16_t opcode); - void FNEG(const uint16_t opcode); - void FABS(const uint16_t opcode); - void FCMP_EQ(const uint16_t opcode); - void FCMP_GT(const uint16_t opcode); - void FCNVDS(const uint16_t opcode); - void FCNVSD(const uint16_t opcode); - void FADD(const uint16_t opcode); - void FSUB(const uint16_t opcode); - void FMUL(const uint16_t opcode); - void FDIV(const uint16_t opcode); - void FMAC(const uint16_t opcode); - void FSQRT(const uint16_t opcode); - void FSRRA(const uint16_t opcode); - void FSSCA(const uint16_t opcode); - void FIPR(const uint16_t opcode); - void FTRV(const uint16_t opcode); - void op1111_0xf13(const uint16_t opcode); - void dbreak(const uint16_t opcode); - void op1111_0x13(uint16_t opcode); - uint8_t RB(offs_t A); - uint16_t RW(offs_t A); - uint32_t RL(offs_t A); void sh4_change_register_bank(int to); void sh4_swap_fp_registers(); void sh4_swap_fp_couples(); @@ -650,6 +481,7 @@ protected: void sh4_exception_request(int exception); void sh4_exception_unrequest(int exception); void sh4_exception_checkunrequest(int exception); + void sh4_exception_process(int exception, uint32_t vector); void sh4_exception(const char *message, int exception); uint32_t compute_ticks_refresh_timer(emu_timer *timer, int hertz, int base, int divisor); void sh4_refresh_timer_recompute(); @@ -722,21 +554,189 @@ protected: uint32_t sh4_handle_chcr3_addr_r(uint32_t mem_mask) { return m_SH4_CHCR3; } uint32_t sh4_handle_dmaor_addr_r(uint32_t mem_mask) { return m_SH4_DMAOR; } -#if SH4_USE_FASTRAM_OPTIMIZATION - /* fast RAM */ + // memory handlers + virtual uint8_t RB(offs_t A) override; + virtual uint16_t RW(offs_t A) override; + virtual uint32_t RL(offs_t A) override; + virtual void WB(offs_t A, uint8_t V) override; + virtual void WW(offs_t A, uint16_t V) override; + virtual void WL(offs_t A, uint32_t V) override; + + // regular handlers for opcodes which need to differ on sh3/4 due to different interrupt / exception handling and register banking + virtual void LDCSR(const uint16_t opcode) override; + virtual void LDCMSR(const uint16_t opcode) override; + virtual void RTE() override; + virtual void TRAPA(uint32_t i) override; + virtual void ILLEGAL() override; + + // regular handelrs for sh3/4 specific opcodes + virtual void LDTLB(const uint16_t opcode); + void TODO(const uint16_t opcode); + void MOVCAL(const uint16_t opcode); + void CLRS(const uint16_t opcode); + void SETS(const uint16_t opcode); + void STCRBANK(const uint16_t opcode); + void STCMRBANK(const uint16_t opcode); + void STCSSR(const uint16_t opcode); + void STCSPC(const uint16_t opcode); + void STCSGR(const uint16_t opcode); + void STSFPUL(const uint16_t opcode); + void STSFPSCR(const uint16_t opcode); + void STCDBR(const uint16_t opcode); + void STCMSGR(const uint16_t opcode); + void STSMFPUL(const uint16_t opcode); + void STSMFPSCR(const uint16_t opcode); + void STCMDBR(const uint16_t opcode); + void STCMSSR(const uint16_t opcode); + void STCMSPC(const uint16_t opcode); + void LDSMFPUL(const uint16_t opcode); + void LDSMFPSCR(const uint16_t opcode); + void LDCMDBR(const uint16_t opcode); + void LDCMRBANK(const uint16_t opcode); + void LDCMSSR(const uint16_t opcode); + void LDCMSPC(const uint16_t opcode); + void LDSFPUL(const uint16_t opcode); + void LDSFPSCR(const uint16_t opcode); + void LDCDBR(const uint16_t opcode); + void SHAD(const uint16_t opcode); + void SHLD(const uint16_t opcode); + void LDCRBANK(const uint16_t opcode); + void LDCSSR(const uint16_t opcode); + void LDCSPC(const uint16_t opcode); + void PREFM(const uint16_t opcode); + void FMOVMRIFR(const uint16_t opcode); + void FMOVFRMR(const uint16_t opcode); + void FMOVFRMDR(const uint16_t opcode); + void FMOVFRS0(const uint16_t opcode); + void FMOVS0FR(const uint16_t opcode); + void FMOVMRFR(const uint16_t opcode); + void FMOVFR(const uint16_t opcode); + void FLDI1(const uint16_t opcode); + void FLDI0(const uint16_t opcode); + void FLDS(const uint16_t opcode); + void FSTS(const uint16_t opcode); + void FRCHG(); + void FSCHG(); + void FTRC(const uint16_t opcode); + void FLOAT(const uint16_t opcode); + void FNEG(const uint16_t opcode); + void FABS(const uint16_t opcode); + void FCMP_EQ(const uint16_t opcode); + void FCMP_GT(const uint16_t opcode); + void FCNVDS(const uint16_t opcode); + void FCNVSD(const uint16_t opcode); + void FADD(const uint16_t opcode); + void FSUB(const uint16_t opcode); + void FMUL(const uint16_t opcode); + void FDIV(const uint16_t opcode); + void FMAC(const uint16_t opcode); + void FSQRT(const uint16_t opcode); + void FSRRA(const uint16_t opcode); + void FSSCA(const uint16_t opcode); + void FIPR(const uint16_t opcode); + void FTRV(const uint16_t opcode); + + void op1111_0xf13(const uint16_t opcode); + void dbreak(const uint16_t opcode); + void op1111_0x13(uint16_t opcode); + + // group dispatchers to allow for new opcodes + virtual void execute_one_0000(uint16_t opcode) override; + virtual void execute_one_4000(uint16_t opcode) override; + virtual void execute_one_f000(uint16_t opcode) override; + + // DRC related parts + + virtual void generate_update_cycles(drcuml_block *block, compiler_state *compiler, uml::parameter param, bool allow_exception) override; + + // code generators for sh3/4 specific opcodes + bool generate_group_0_STCRBANK(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_0_STCSSR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_0_STCSPC(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_0_PREFM(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_0_MOVCAL(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_0_LDTLB(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_0_CLRS(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_0_SETS(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_0_STCSGR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_0_STSFPUL(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_0_STSFPSCR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_0_STCDBR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + + bool generate_group_4_SHAD(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_4_SHLD(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_4_LDCRBANK(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_4_STCMRBANK(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_4_LDCMRBANK(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_4_STCMSGR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_4_STCMSSR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_4_LDCMSSR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_4_LDCSSR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_4_STCMSPC(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_4_LDCMSPC(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_4_LDCSPC(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_4_STSMFPUL(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_4_LDSMFPUL(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_4_LDSFPUL(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_4_STSMFPSCR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_4_LDSMFPSCR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_4_LDSFPSCR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_4_STCMDBR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_4_LDCMDBR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_4_LDCDBR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + + bool generate_group_15_FADD(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_15_FSUB(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_15_FMUL(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_15_FDIV(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_15_FCMP_EQ(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_15_FCMP_GT(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_15_FMOVS0FR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_15_FMOVFRS0(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_15_FMOVMRFR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_15_FMOVMRIFR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_15_FMOVFRMR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_s_0xf13_FTRVlot, uint32_t ovrpc); + bool generate_group_15_FMOVFRMDR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_15_FMOVFR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_15_op1111_0x13(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_15_FMAC(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + + bool generate_group_15_op1111_0x13_FSTS(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_15_op1111_0x13_FLDS(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_15_op1111_0x13_FLOAT(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_15_op1111_0x13_FTRC(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_15_op1111_0x13_FNEG(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_15_op1111_0x13_FABS(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_15_op1111_0x13_FSQRT(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_15_op1111_0x13_FSRRA(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_15_op1111_0x13_FLDI0(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_15_op1111_0x13_FLDI1(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_15_op1111_0x13_FCNVSD(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_15_op1111_0x13_FCNVDS(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_15_op1111_0x13_FIPR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_15_op1111_0x13_op1111_0xf13(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + + bool generate_group_15_op1111_0x13_op1111_0xf13_FSCHG(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_15_op1111_0x13_op1111_0xf13_FRCHG(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_15_op1111_0x13_op1111_0xf13_FTRV(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + bool generate_group_15_op1111_0x13_op1111_0xf13_FSSCA(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc); + + // code generators for opcodes which need to differ on sh3/4 due to different interrupt / exception handling and register banking + virtual bool generate_group_0_RTE(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) override; + virtual bool generate_group_4_LDCSR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) override; + virtual bool generate_group_4_LDCMSR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) override; + virtual bool generate_group_12_TRAPA(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) override; + + // group generators to allow for new opcodes + virtual bool generate_group_0(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) override; + virtual bool generate_group_4(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) override; + virtual bool generate_group_15(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) override; + + virtual void static_generate_entry_point() override; + virtual void static_generate_memory_accessor(int size, int iswrite, const char *name, uml::code_handle **handleptr) override; + +private: bool m_bigendian; - uint32_t m_byte_xor; - uint32_t m_word_xor; - uint32_t m_dword_xor; - uint32_t m_fastram_select; - struct - { - offs_t start; /* start of the RAM block */ - offs_t end; /* end of the RAM block */ - bool readonly; /* true if read-only */ - void * base; /* base in memory where the RAM lives */ - } m_fastram[SH4_MAX_FASTRAM]; -#endif }; @@ -787,39 +787,82 @@ protected: class sh3_device : public sh3_base_device { + friend class sh4_frontend; public: sh3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + std::unique_ptr<sh4_frontend> m_drcfe; /* pointer to the DRC front-end state */ + virtual const opcode_desc* get_desclist(offs_t pc) override; + virtual void init_drc_frontend() override; }; class sh3be_device : public sh3_base_device { + friend class sh4be_frontend; + public: sh3be_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + std::unique_ptr<sh4be_frontend> m_drcfe; /* pointer to the DRC front-end state */ + virtual const opcode_desc* get_desclist(offs_t pc) override; + virtual void init_drc_frontend() override; protected: virtual void execute_run() override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; }; class sh4_device : public sh4_base_device { + friend class sh4_frontend; + public: sh4_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + std::unique_ptr<sh4_frontend> m_drcfe; /* pointer to the DRC front-end state */ + virtual const opcode_desc* get_desclist(offs_t pc) override; + virtual void init_drc_frontend() override; + }; class sh4be_device : public sh4_base_device { + friend class sh4be_frontend; + public: sh4be_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + std::unique_ptr<sh4be_frontend> m_drcfe; /* pointer to the DRC front-end state */ + virtual const opcode_desc* get_desclist(offs_t pc) override; + virtual void init_drc_frontend() override; protected: virtual void execute_run() override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; }; +class sh4_frontend : public sh_frontend +{ +public: + sh4_frontend(sh_common_execution *device, uint32_t window_start, uint32_t window_end, uint32_t max_sequence); + +protected: + virtual uint16_t read_word(opcode_desc &desc) override; + +private: + virtual bool describe_group_0(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) override; + virtual bool describe_group_4(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) override; + virtual bool describe_group_15(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) override; + bool describe_op1111_0x13(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode); + bool describe_op1111_0xf13(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode); +}; + +class sh4be_frontend : public sh4_frontend +{ +public: + sh4be_frontend(sh_common_execution *device, uint32_t window_start, uint32_t window_end, uint32_t max_sequence) : + sh4_frontend(device, window_start, window_end, max_sequence) + {} +protected: + virtual uint16_t read_word(opcode_desc &desc) override; +}; DECLARE_DEVICE_TYPE(SH3LE, sh3_device) DECLARE_DEVICE_TYPE(SH3BE, sh3be_device) @@ -827,18 +870,4 @@ DECLARE_DEVICE_TYPE(SH4LE, sh4_device) DECLARE_DEVICE_TYPE(SH4BE, sh4be_device) -/*************************************************************************** - COMPILER-SPECIFIC OPTIONS -***************************************************************************/ - -#define SH4DRC_STRICT_VERIFY 0x0001 /* verify all instructions */ -#define SH4DRC_FLUSH_PC 0x0002 /* flush the PC value before each memory access */ -#define SH4DRC_STRICT_PCREL 0x0004 /* do actual loads on MOVLI/MOVWI instead of collapsing to immediates */ - -#define SH4DRC_COMPATIBLE_OPTIONS (SH4DRC_STRICT_VERIFY | SH4DRC_FLUSH_PC | SH4DRC_STRICT_PCREL) -#define SH4DRC_FASTEST_OPTIONS (0) - -void sh4drc_set_options(device_t *device, uint32_t options); -void sh4drc_add_pcflush(device_t *device, offs_t address); - #endif // MAME_CPU_SH4_SH4_H diff --git a/src/devices/cpu/sh/sh4comn.cpp b/src/devices/cpu/sh/sh4comn.cpp index 4f7ae411e7d..1e7061c7d54 100644 --- a/src/devices/cpu/sh/sh4comn.cpp +++ b/src/devices/cpu/sh/sh4comn.cpp @@ -233,30 +233,6 @@ static const int sh3_intevt2_exception_codes[] = -1 /* SH4_INTC_ROVI */ }; - - -void sh34_base_device::sh4_change_register_bank(int to) -{ - int s; - - if (to) // 0 -> 1 - { - for (s = 0;s < 8;s++) - { - m_rbnk[0][s] = m_r[s]; - m_r[s] = m_rbnk[1][s]; - } - } - else // 1 -> 0 - { - for (s = 0;s < 8;s++) - { - m_rbnk[1][s] = m_r[s]; - m_r[s] = m_rbnk[0][s]; - } - } -} - void sh34_base_device::sh4_swap_fp_registers() { int s; @@ -286,13 +262,36 @@ void sh34_base_device::sh4_swap_fp_couples() } } + +void sh34_base_device::sh4_change_register_bank(int to) +{ + int s; + + if (to) // 0 -> 1 + { + for (s = 0;s < 8;s++) + { + m_rbnk[0][s] = m_sh2_state->r[s]; + m_sh2_state->r[s] = m_rbnk[1][s]; + } + } + else // 1 -> 0 + { + for (s = 0;s < 8;s++) + { + m_rbnk[1][s] = m_sh2_state->r[s]; + m_sh2_state->r[s] = m_rbnk[0][s]; + } + } +} + void sh34_base_device::sh4_syncronize_register_bank(int to) { int s; for (s = 0;s < 8;s++) { - m_rbnk[to][s] = m_r[s]; + m_rbnk[to][s] = m_sh2_state->r[s]; } } @@ -317,9 +316,9 @@ void sh34_base_device::sh4_exception_recompute() // checks if there is any inter int a,z; m_test_irq = 0; - if ((!m_pending_irq) || ((m_sr & BL) && (m_exception_requesting[SH4_INTC_NMI] == 0))) + if ((!m_pending_irq) || ((m_sh2_state->sr & BL) && (m_exception_requesting[SH4_INTC_NMI] == 0))) return; - z = (m_sr >> 4) & 15; + z = (m_sh2_state->sr >> 4) & 15; for (a=0;a <= SH4_INTC_ROVI;a++) { if (m_exception_requesting[a]) @@ -367,17 +366,43 @@ void sh34_base_device::sh4_exception_checkunrequest(int exception) sh4_exception_unrequest(exception); } + +void sh34_base_device::sh4_exception_process(int exception, uint32_t vector) +{ + sh4_exception_checkunrequest(exception); + + m_spc = m_sh2_state->pc; + m_ssr = m_sh2_state->sr; + m_sgr = m_sh2_state->r[15]; + + //printf("stored m_spc %08x m_ssr %08x m_sgr %08x\n", m_spc, m_ssr, m_sgr); + + m_sh2_state->sr |= MD; + if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0) + sh4_syncronize_register_bank((m_sh2_state->sr & sRB) >> 29); + if (!(m_sh2_state->sr & sRB)) + sh4_change_register_bank(1); + m_sh2_state->sr |= sRB; + m_sh2_state->sr |= BL; + sh4_exception_recompute(); + + /* fetch PC */ + m_sh2_state->pc = m_sh2_state->vbr + vector; + m_willjump = 1; // for DRC + /* wake up if a sleep opcode is triggered */ + if(m_sh2_state->sleep_mode == 1) { m_sh2_state->sleep_mode = 2; } +} + void sh34_base_device::sh4_exception(const char *message, int exception) // handle exception { uint32_t vector; - if (m_cpu_type == CPU_TYPE_SH4) { if (exception < SH4_INTC_NMI) return; // Not yet supported if (exception == SH4_INTC_NMI) { - if ((m_sr & BL) && (!(m_m[ICR] & 0x200))) + if ((m_sh2_state->sr & BL) && (!(m_m[ICR] & 0x200))) return; m_m[ICR] &= ~0x200; @@ -390,9 +415,9 @@ void sh34_base_device::sh4_exception(const char *message, int exception) // hand } else { // if ((m_m[ICR] & 0x4000) && (m_nmi_line_state == ASSERT_LINE)) // return; - if (m_sr & BL) + if (m_sh2_state->sr & BL) return; - if (((m_exception_priority[exception] >> 8) & 255) <= ((m_sr >> 4) & 15)) + if (((m_exception_priority[exception] >> 8) & 255) <= ((m_sh2_state->sr >> 4) & 15)) return; m_m[INTEVT] = exception_codes[exception]; vector = 0x600; @@ -415,9 +440,9 @@ void sh34_base_device::sh4_exception(const char *message, int exception) // hand } else { - if (m_sr & BL) + if (m_sh2_state->sr & BL) return; - if (((m_exception_priority[exception] >> 8) & 255) <= ((m_sr >> 4) & 15)) + if (((m_exception_priority[exception] >> 8) & 255) <= ((m_sh2_state->sr >> 4) & 15)) return; @@ -440,25 +465,7 @@ void sh34_base_device::sh4_exception(const char *message, int exception) // hand /***** END ASSUME THIS TO BE WRONG FOR NOW *****/ } - sh4_exception_checkunrequest(exception); - - m_spc = m_pc; - m_ssr = m_sr; - m_sgr = m_r[15]; - - m_sr |= MD; - if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0) - sh4_syncronize_register_bank((m_sr & sRB) >> 29); - if (!(m_sr & sRB)) - sh4_change_register_bank(1); - m_sr |= sRB; - m_sr |= BL; - sh4_exception_recompute(); - - /* fetch PC */ - m_pc = m_vbr + vector; - /* wake up if a sleep opcode is triggered */ - if(m_sleep_mode == 1) { m_sleep_mode = 2; } + sh4_exception_process(exception, vector); } @@ -1098,7 +1105,7 @@ void sh34_base_device::sh4_set_frt_input(int state) sh4_timer_resync(); m_icr = m_frc; m_m[4] |= ICF; - logerror("SH4 '%s': ICF activated (%x)\n", tag(), m_pc & AM); + logerror("SH4 '%s': ICF activated (%x)\n", tag(), m_sh2_state->pc & AM); sh4_recalc_irq(); #endif } @@ -1211,7 +1218,7 @@ void sh34_base_device::execute_set_input(int irqline, int state) // set state of LOG(("SH-4 '%s' IRLn0-IRLn3 level #%d\n", tag(), m_irln)); } } - if (m_test_irq && (!m_delay)) + if (m_test_irq && (!m_sh2_state->m_delay)) sh4_check_pending_irq("sh4_set_irq_line"); } } diff --git a/src/devices/cpu/sh/sh4comn.h b/src/devices/cpu/sh/sh4comn.h index 230207652d6..ded2e5645f1 100644 --- a/src/devices/cpu/sh/sh4comn.h +++ b/src/devices/cpu/sh/sh4comn.h @@ -13,24 +13,10 @@ #ifndef __SH4COMN_H__ #define __SH4COMN_H__ -//#define USE_SH4DRC - -/* speed up delay loops, bail out of tight loops */ -#define BUSY_LOOP_HACKS 0 +#include "sh.h" #define VERBOSE 0 -#ifdef USE_SH4DRC -#include "cpu/drcfe.h" -#include "cpu/drcuml.h" -#include "cpu/drcumlsh.h" - -class sh4_frontend; -#endif - -#define CPU_TYPE_SH3 (2) -#define CPU_TYPE_SH4 (3) - #define LOG(x) do { if (VERBOSE) logerror x; } while (0) #define EXPPRI(pl,po,p,n) (((4-(pl)) << 24) | ((15-(po)) << 16) | ((p) << 8) | (255-(n))) @@ -50,74 +36,6 @@ class sh4_frontend; #define FP_XFS2(r) *( (float *)(m_xf+((r) ^ m_fpu_pr)) ) #endif - -#ifdef USE_SH4DRC -struct sh4_state -{ - int icount; - - int pcfsel; // last pcflush entry set - int maxpcfsel; // highest valid pcflush entry - uint32_t pcflushes[16]; // pcflush entries - - drc_cache * cache; /* pointer to the DRC code cache */ - drcuml_state * drcuml; /* DRC UML generator state */ - sh4_frontend * drcfe; /* pointer to the DRC front-end class */ - uint32_t drcoptions; /* configurable DRC options */ - - /* internal stuff */ - uint8_t cache_dirty; /* true if we need to flush the cache */ - - /* parameters for subroutines */ - uint64_t numcycles; /* return value from gettotalcycles */ - uint32_t arg0; /* print_debug argument 1 */ - uint32_t arg1; /* print_debug argument 2 */ - uint32_t irq; /* irq we're taking */ - - /* register mappings */ - uml::parameter regmap[16]; /* parameter to register mappings for all 16 integer registers */ - - uml::code_handle * entry; /* entry point */ - uml::code_handle * read8; /* read byte */ - uml::code_handle * write8; /* write byte */ - uml::code_handle * read16; /* read half */ - uml::code_handle * write16; /* write half */ - uml::code_handle * read32; /* read word */ - uml::code_handle * write32; /* write word */ - - uml::code_handle * interrupt; /* interrupt */ - uml::code_handle * nocode; /* nocode */ - uml::code_handle * out_of_cycles; /* out of cycles exception handler */ - - uint32_t prefadr; - uint32_t target; -}; -#endif - -#ifdef USE_SH4DRC -class sh4_frontend : public drc_frontend -{ -public: - sh4_frontend(sh4_state &state, uint32_t window_start, uint32_t window_end, uint32_t max_sequence); - -protected: - virtual bool describe(opcode_desc &desc, const opcode_desc *prev); - -private: - bool describe_group_0(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode); - bool describe_group_2(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode); - bool describe_group_3(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode); - bool describe_group_4(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode); - bool describe_group_6(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode); - bool describe_group_8(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode); - bool describe_group_12(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode); - bool describe_group_15(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode); - - sh4_state &m_context; -}; -#endif - - enum { ICF = 0x00800000, @@ -126,21 +44,15 @@ enum OVF = 0x00020000 }; -/* Bits in SR */ -#define T 0x00000001 -#define S 0x00000002 -#define I 0x000000f0 -#define Q 0x00000100 -#define M 0x00000200 #define FD 0x00008000 #define BL 0x10000000 #define sRB 0x20000000 #define MD 0x40000000 /* 29 bits */ -#define AM 0x1fffffff +#define SH34_AM 0x1fffffff -#define FLAGS (MD|sRB|BL|FD|M|Q|I|S|T) +#define SH34_FLAGS (MD|sRB|BL|FD|SH_M|SH_Q|SH_I|SH_S|SH_T) /* Bits in FPSCR */ #define RM 0x00000003 @@ -149,20 +61,9 @@ enum #define SZ 0x00100000 #define FR 0x00200000 -#define Rn ((opcode>>8)&15) -#define Rm ((opcode>>4)&15) - #define REGFLAG_R(n) (1 << (n)) -#define REGFLAG_FR(n) (1 << (n)) -#define REGFLAG_XR(n) (1 << (n)) -/* register flags 1 */ -#define REGFLAG_PR (1 << 0) -#define REGFLAG_MACL (1 << 1) -#define REGFLAG_MACH (1 << 2) -#define REGFLAG_GBR (1 << 3) -#define REGFLAG_VBR (1 << 4) -#define REGFLAG_SR (1 << 5) +/* additional register flags 1 */ #define REGFLAG_SGR (1 << 6) #define REGFLAG_FPUL (1 << 7) #define REGFLAG_FPSCR (1 << 8) @@ -170,5 +71,4 @@ enum #define REGFLAG_SSR (1 << 10) #define REGFLAG_SPC (1 << 11) - #endif /* __SH4COMN_H__ */ diff --git a/src/devices/cpu/sh/sh4dmac.cpp b/src/devices/cpu/sh/sh4dmac.cpp index c06ffb034dd..ba727d324c5 100644 --- a/src/devices/cpu/sh/sh4dmac.cpp +++ b/src/devices/cpu/sh/sh4dmac.cpp @@ -89,8 +89,8 @@ int sh34_base_device::sh4_dma_transfer(int channel, int timermode, uint32_t chcr m_dma_timer[channel]->adjust(attotime::zero, channel); } - src &= AM; - dst &= AM; + src &= SH34_AM; + dst &= SH34_AM; switch(size) { @@ -178,8 +178,8 @@ int sh34_base_device::sh4_dma_transfer(int channel, int timermode, uint32_t chcr } break; } - *sar = (*sar & ~AM) | src; - *dar = (*dar & ~AM) | dst; + *sar = (*sar & ~SH34_AM) | src; + *dar = (*dar & ~SH34_AM) | dst; *dmatcr = count; return 1; } @@ -218,8 +218,8 @@ int sh34_base_device::sh4_dma_transfer_device(int channel, uint32_t chcr, uint32 m_dma_timer_active[channel] = 1; - src &= AM; - dst &= AM; + src &= SH34_AM; + dst &= SH34_AM; // remember parameters m_dma_source[channel]=src; diff --git a/src/devices/cpu/sh/sh4fe.cpp b/src/devices/cpu/sh/sh4fe.cpp new file mode 100644 index 00000000000..ca122cd4eb4 --- /dev/null +++ b/src/devices/cpu/sh/sh4fe.cpp @@ -0,0 +1,317 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont, David Haywood +/*************************************************************************** + + sh4fe.c + + Front end for SH-4 recompiler + +***************************************************************************/ + +#include "emu.h" +#include "sh4.h" +#include "sh4comn.h" +#include "cpu/drcfe.h" + + +/*************************************************************************** + INSTRUCTION PARSERS +***************************************************************************/ + +sh4_frontend::sh4_frontend(sh_common_execution *device, uint32_t window_start, uint32_t window_end, uint32_t max_sequence) + : sh_frontend(device, window_start, window_end, max_sequence) +{ +} + +uint16_t sh4_frontend::read_word(opcode_desc &desc) +{ + if (desc.physpc >= 0xe0000000) + return m_sh->m_direct->read_word(desc.physpc, SH34LE_CODE_XOR(0)); + + return m_sh->m_direct->read_word(desc.physpc & SH34_AM, SH34LE_CODE_XOR(0)); +} + +uint16_t sh4be_frontend::read_word(opcode_desc &desc) +{ + if (desc.physpc >= 0xe0000000) + return m_sh->m_direct->read_word(desc.physpc, SH34BE_CODE_XOR(0)); + + return m_sh->m_direct->read_word(desc.physpc & SH34_AM, SH34BE_CODE_XOR(0)); +} + + +bool sh4_frontend::describe_group_0(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) +{ + switch (opcode & 0xff) + { + default: + // fall through to SH2 handlers + return sh_frontend::describe_group_0(desc, prev, opcode); + + case 0x52: + case 0x62: + case 0x43: + case 0x63: + case 0xe3: + case 0x68: + case 0xe8: + case 0x4a: + case 0xca: + return true; // ILLEGAL(); break; // illegal on sh4 + + case 0x93: + case 0xa3: + case 0xb3: + return true; // TODO(opcode); break; + + case 0x82: + case 0x92: + case 0xa2: + case 0xb2: + case 0xc2: + case 0xd2: + case 0xe2: + case 0xf2: + return true; // STC RBANK(opcode); break; // sh3/4 only + + case 0x32: return true; // STCSSR(opcode); break; // sh3/4 only + case 0x42: return true; // STCSPC(opcode); break; // sh3/4 only + case 0x83: return true; // PREFM(opcode); break; // sh3/4 only + case 0xc3: return true; // MOVCAL(opcode); break; // sh4 only + + case 0x38: + case 0xb8: + return true; // LDTLB(opcode); break; // sh3/4 only + + case 0x48: + case 0xc8: + return true; // CLRS(opcode); break; // sh3/4 only + + case 0x58: + case 0xd8: + return true; // SETS(opcode); break; // sh3/4 only + + case 0x3a: + case 0xba: + return true; // STCSGR(opcode); break; // sh4 only + + case 0x5a: + case 0xda: + return true; // STSFPUL(opcode); break; // sh4 only + + case 0x6a: + case 0xea: + return true; // STSFPSCR(opcode); break; // sh4 only + + case 0x7a: + case 0xfa: + return true; // STCDBR(opcode); break; // sh4 only + } + + return false; +} + + +bool sh4_frontend::describe_group_4(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) +{ + switch (opcode & 0xff) + { + + default: // LDCMSR (0x0e) has sh2/4 flag difference + // fall through to SH2 handlers + return sh_frontend::describe_group_4(desc, prev, opcode); + + case 0x42: + case 0x46: + case 0x4a: + case 0x53: + case 0x57: + case 0x5e: + case 0x63: + case 0x67: + case 0x6e: + case 0x82: + case 0x86: + case 0x8a: + case 0x92: + case 0x96: + case 0x9a: + case 0xa2: + case 0xa6: + case 0xaa: + case 0xc2: + case 0xc6: + case 0xca: + case 0xd2: + case 0xd6: + case 0xda: + case 0xe2: + case 0xe6: + case 0xea: + return true; // ILLEGAL(); break; // defined as illegal on SH4 + + case 0x0c: + case 0x1c: + case 0x2c: + case 0x3c: + case 0x4c: + case 0x5c: + case 0x6c: + case 0x7c: + case 0x8c: + case 0x9c: + case 0xac: + case 0xbc: + case 0xcc: + case 0xdc: + case 0xec: + case 0xfc: + return true; // SHAD(opcode); break; // sh3/4 only needed + + case 0x0d: + case 0x1d: + case 0x2d: + case 0x3d: + case 0x4d: + case 0x5d: + case 0x6d: + case 0x7d: + case 0x8d: + case 0x9d: + case 0xad: + case 0xbd: + case 0xcd: + case 0xdd: + case 0xed: + case 0xfd: + return true; // SHLD(opcode); break; // sh3/4 only needed + + case 0x8e: + case 0x9e: + case 0xae: + case 0xbe: + case 0xce: + case 0xde: + case 0xee: + case 0xfe: + return true; // LDCRBANK(opcode); break; // sh3/4 only + + case 0x83: + case 0x93: + case 0xa3: + case 0xb3: + case 0xc3: + case 0xd3: + case 0xe3: + case 0xf3: + return true; // STCMRBANK(opcode); break; // sh3/4 only + + case 0x87: + case 0x97: + case 0xa7: + case 0xb7: + case 0xc7: + case 0xd7: + case 0xe7: + case 0xf7: + return true; // LDCMRBANK(opcode); break; // sh3/4 only + + case 0x32: return true; // STCMSGR(opcode); break; // sh4 only + case 0x33: return true; // STCMSSR(opcode); break; // sh4 only + case 0x37: return true; // LDCMSSR(opcode); break; // sh3/4 only + case 0x3e: return true; // LDCSSR(opcode); break; // sh3/4 only + case 0x43: return true; // STCMSPC(opcode); break; // sh3/4 only + case 0x47: return true; // LDCMSPC(opcode); break; // sh3/4 only + case 0x4e: return true; // LDCSPC(opcode); break; // sh3/4 only + case 0x52: return true; // STSMFPUL(opcode); break; // sh4 only + case 0x56: return true; // LDSMFPUL(opcode); break; // sh4 only + case 0x5a: return true; // LDSFPUL(opcode); break; // sh4 only + case 0x62: return true; // STSMFPSCR(opcode); break; // sh4 only + case 0x66: return true; // LDSMFPSCR(opcode); break; // sh4 only + case 0x6a: return true; // LDSFPSCR(opcode); break; // sh4 only + case 0xf2: return true; // STCMDBR(opcode); break; // sh4 only + case 0xf6: return true; // LDCMDBR(opcode); break; // sh4 only + case 0xfa: return true; // LDCDBR(opcode); break; // sh4 only + } + + return false; +} + +// SH4 only (FPU ops) +bool sh4_frontend::describe_group_15(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) +{ + switch (opcode & 0x0f) + { + case 0x00: return true; // FADD(opcode); break; + case 0x01: return true; // FSUB(opcode); break; + case 0x02: return true; // FMUL(opcode); break; + case 0x03: return true; // FDIV(opcode); break; + case 0x04: return true; // FCMP_EQ(opcode); break; + case 0x05: return true; // FCMP_GT(opcode); break; + case 0x06: return true; // FMOVS0FR(opcode); break; + case 0x07: return true; // FMOVFRS0(opcode); break; + case 0x08: return true; // FMOVMRFR(opcode); break; + case 0x09: return true; // FMOVMRIFR(opcode); break; + case 0x0a: return true; // FMOVFRMR(opcode); break; + case 0x0b: return true; // FMOVFRMDR(opcode); break; + case 0x0c: return true; // FMOVFR(opcode); break; + case 0x0d: return describe_op1111_0x13(desc, prev, opcode); // break; + case 0x0e: return true; // FMAC(opcode); break; + case 0x0f: + return true; + //if (opcode == 0xffff) return true; // atomiswave uses ffff as NOP? + //return false; // dbreak(opcode); break; + } + return false; +} + +bool sh4_frontend::describe_op1111_0x13(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) +{ + switch ((opcode >> 4) & 0x0f) + { + case 0x00: return true; // FSTS(opcode); break; + case 0x01: return true; // FLDS(opcode); break; + case 0x02: return true; // FLOAT(opcode); break; + case 0x03: return true; // FTRC(opcode); break; + case 0x04: return true; // FNEG(opcode); break; + case 0x05: return true; // FABS(opcode); break; + case 0x06: return true; // FSQRT(opcode); break; + case 0x07: return true; // FSRRA(opcode); break; + case 0x08: return true; // FLDI0(opcode); break; + case 0x09: return true; // FLDI1(opcode); break; + case 0x0a: return true; // FCNVSD(opcode); break; + case 0x0b: return true; // FCNVDS(opcode); break; + case 0x0c: return false; // dbreak(opcode); break; + case 0x0d: return false; // dbreak(opcode); break; + case 0x0e: return true; // FIPR(opcode); break; + case 0x0f: return describe_op1111_0xf13(desc, prev, opcode); // break; + } + return false; +} + +bool sh4_frontend::describe_op1111_0xf13(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) +{ + if (opcode & 0x100) { + if (opcode & 0x200) { + switch (opcode & 0xC00) + { + case 0x000: + return true; //FSCHG(); + break; + case 0x800: + return true; //FRCHG(); + break; + default: + return false; //machine().debug_break(); + break; + } + } + else { + return true; // FTRV(opcode); + } + } + else { + return true; // FSSCA(opcode); + } + return false; +} diff --git a/src/devices/cpu/sh/sh4dasm.cpp b/src/devices/cpu/sh/sh_dasm.cpp index faff895f3a5..a2e6dd67496 100644 --- a/src/devices/cpu/sh/sh4dasm.cpp +++ b/src/devices/cpu/sh/sh_dasm.cpp @@ -1,21 +1,587 @@ // license:BSD-3-Clause -// copyright-holders:R. Belmont +// copyright-holders:Juergen Buchmueller, R. Belmont #include "emu.h" -#include "debugger.h" -#include "sh4.h" +#include "sh_dasm.h" #define SIGNX8(x) (((int32_t)(x) << 24) >> 24) #define SIGNX12(x) (((int32_t)(x) << 20) >> 20) +#define Rn ((opcode>>8)&15) +#define Rm ((opcode>>4)&15) -#define Rn ((opcode >> 8) & 15) -#define Rm ((opcode >> 4) & 15) - -static const char *const regname[16] = { +const char *const sh_disassembler::regname[16] = { "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", - "R8", "R9", "R10","R11","R12","R13","R14","R15" + "R8", "R9", "R10","R11","R12","R13","R14", + // The old SH2 dasm used 'SP' here, the old SH4 used 'R15' + //"SP" + "R15" }; -static uint32_t op0000(std::ostream &stream, uint32_t pc, uint16_t opcode) +uint32_t sh_disassembler::op0000(std::ostream &stream, uint32_t pc, uint16_t opcode) +{ + uint32_t flags = 0; + switch(opcode & 0x3f) + { + case 0x02: + util::stream_format(stream, "STC SR,%s", regname[Rn]); + break; + case 0x03: + util::stream_format(stream, "BSRF %s", regname[Rn]); + break; + case 0x08: + stream << "CLRT"; + break; + case 0x09: + stream << "NOP"; + break; + case 0x0A: + util::stream_format(stream, "STS MACH,%s", regname[Rn]); + break; + case 0x0B: + stream << "RTS"; + flags = STEP_OUT; + break; + case 0x12: + util::stream_format(stream, "STS GBR,%s", regname[Rn]); + break; + case 0x18: + stream << "SETT"; + break; + case 0x19: + stream << "DIV0U"; + break; + case 0x1A: + util::stream_format(stream, "STS MACL,%s", regname[Rn]); + break; + case 0x1B: + stream << "SLEEP"; + break; + case 0x22: + util::stream_format(stream, "STC VBR,%s", regname[Rn]); + break; + case 0x23: + util::stream_format(stream, "BRAF %s", regname[Rn]); + break; + case 0x28: + stream << "CLRMAC"; + break; + case 0x29: + util::stream_format(stream, "MOVT %s", regname[Rn]); + break; + case 0x2A: + util::stream_format(stream, "STS PR,%s", regname[Rn]); + break; + case 0x2B: + stream << "RTE"; + flags = STEP_OUT; + break; + default: + switch(opcode & 15) + { + case 0: + util::stream_format(stream, "?????? $%04X", opcode); + break; + case 1: + util::stream_format(stream, "?????? $%04X", opcode); + break; + case 2: + util::stream_format(stream, "?????? $%04X", opcode); + break; + case 3: + util::stream_format(stream, "?????? $%04X", opcode); + break; + case 4: + util::stream_format(stream, "MOV.B %s,@(R0,%s)", regname[Rm], regname[Rn]); + break; + case 5: + util::stream_format(stream, "MOV.W %s,@(R0,%s)", regname[Rm], regname[Rn]); + break; + case 6: + util::stream_format(stream, "MOV.L %s,@(R0,%s)", regname[Rm], regname[Rn]); + break; + case 7: + util::stream_format(stream, "MUL.L %s,%s", regname[Rm], regname[Rn]); + break; + case 8: + util::stream_format(stream, "?????? $%04X", opcode); + break; + case 9: + util::stream_format(stream, "?????? $%04X", opcode); + break; + case 10: + util::stream_format(stream, "?????? $%04X", opcode); + break; + case 11: + util::stream_format(stream, "?????? $%04X", opcode); + break; + case 12: + util::stream_format(stream, "MOV.B @(R0,%s),%s", regname[Rm], regname[Rn]); + break; + case 13: + util::stream_format(stream, "MOV.W @(R0,%s),%s", regname[Rm], regname[Rn]); + break; + case 14: + util::stream_format(stream, "MOV.L @(R0,%s),%s", regname[Rm], regname[Rn]); + break; + case 15: + util::stream_format(stream, "MAC.L @%s+,@%s+", regname[Rn], regname[Rm]); + break; + } + } + return flags; +} + +uint32_t sh_disassembler::op0001(std::ostream &stream, uint32_t pc, uint16_t opcode) +{ + util::stream_format(stream, "MOV.L %s,@($%02X,%s)", regname[Rm], (opcode & 15) * 4, regname[Rn]); + return 0; +} + +uint32_t sh_disassembler::op0010(std::ostream &stream, uint32_t pc, uint16_t opcode) +{ + switch (opcode & 15) + { + case 0: + util::stream_format(stream, "MOV.B %s,@%s", regname[Rm], regname[Rn]); + break; + case 1: + util::stream_format(stream, "MOV.W %s,@%s", regname[Rm], regname[Rn]); + break; + case 2: + util::stream_format(stream, "MOV.L %s,@%s", regname[Rm], regname[Rn]); + break; + case 3: + util::stream_format(stream, "?????? $%04X", opcode); + break; + case 4: + util::stream_format(stream, "MOV.B %s,@-%s", regname[Rm], regname[Rn]); + break; + case 5: + util::stream_format(stream, "MOV.W %s,@-%s", regname[Rm], regname[Rn]); + break; + case 6: + util::stream_format(stream, "MOV.L %s,@-%s", regname[Rm], regname[Rn]); + break; + case 7: + util::stream_format(stream, "DIV0S %s,%s", regname[Rm], regname[Rn]); + break; + case 8: + util::stream_format(stream, "TST %s,%s", regname[Rm], regname[Rn]); + break; + case 9: + util::stream_format(stream, "AND %s,%s", regname[Rm], regname[Rn]); + break; + case 10: + util::stream_format(stream, "XOR %s,%s", regname[Rm], regname[Rn]); + break; + case 11: + util::stream_format(stream, "OR %s,%s", regname[Rm], regname[Rn]); + break; + case 12: + util::stream_format(stream, "CMP/STR %s,%s", regname[Rm], regname[Rn]); + break; + case 13: + util::stream_format(stream, "XTRCT %s,%s", regname[Rm], regname[Rn]); + break; + case 14: + util::stream_format(stream, "MULU.W %s,%s", regname[Rm], regname[Rn]); + break; + case 15: + util::stream_format(stream, "MULS.W %s,%s", regname[Rm], regname[Rn]); + break; + } + return 0; +} + +uint32_t sh_disassembler::op0011(std::ostream &stream, uint32_t pc, uint16_t opcode) +{ + switch (opcode & 15) + { + case 0: + util::stream_format(stream, "CMP/EQ %s,%s", regname[Rm], regname[Rn]); + break; + case 1: + util::stream_format(stream, "?????? %s,%s", regname[Rm], regname[Rn]); + break; + case 2: + util::stream_format(stream, "CMP/HS %s,%s", regname[Rm], regname[Rn]); + break; + case 3: + util::stream_format(stream, "CMP/GE %s,%s", regname[Rm], regname[Rn]); + break; + case 4: + util::stream_format(stream, "DIV1 %s,%s", regname[Rm], regname[Rn]); + break; + case 5: + util::stream_format(stream, "DMULU.L %s,%s", regname[Rm], regname[Rn]); + break; + case 6: + util::stream_format(stream, "CMP/HI %s,%s", regname[Rm], regname[Rn]); + break; + case 7: + util::stream_format(stream, "CMP/GT %s,%s", regname[Rm], regname[Rn]); + break; + case 8: + util::stream_format(stream, "SUB %s,%s", regname[Rm], regname[Rn]); + break; + case 9: + util::stream_format(stream, "?????? %s,%s", regname[Rm], regname[Rn]); + break; + case 10: + util::stream_format(stream, "SUBC %s,%s", regname[Rm], regname[Rn]); + break; + case 11: + util::stream_format(stream, "SUBV %s,%s", regname[Rm], regname[Rn]); + break; + case 12: + util::stream_format(stream, "ADD %s,%s", regname[Rm], regname[Rn]); + break; + case 13: + util::stream_format(stream, "DMULS.L %s,%s", regname[Rm], regname[Rn]); + break; + case 14: + util::stream_format(stream, "ADDC %s,%s", regname[Rm], regname[Rn]); + break; + case 15: + util::stream_format(stream, "ADDV %s,%s", regname[Rm], regname[Rn]); + break; + } + return 0; +} + +uint32_t sh_disassembler::op0100(std::ostream &stream, uint32_t pc, uint16_t opcode) +{ + uint32_t flags = 0; + switch(opcode & 0x3F) + { + case 0x00: + util::stream_format(stream, "SHLL %s", regname[Rn]); + break; + case 0x01: + util::stream_format(stream, "SHLR %s", regname[Rn]); + break; + case 0x02: + util::stream_format(stream, "STS.L MACH,@-%s", regname[Rn]); + break; + case 0x03: + util::stream_format(stream, "STC.L SR,@-%s", regname[Rn]); + break; + case 0x04: + util::stream_format(stream, "ROTL %s", regname[Rn]); + break; + case 0x05: + util::stream_format(stream, "ROTR %s", regname[Rn]); + break; + case 0x06: + util::stream_format(stream, "LDS.L @%s+,MACH", regname[Rn]); + break; + case 0x07: + util::stream_format(stream, "LDC.L @%s+,SR", regname[Rn]); + break; + case 0x08: + util::stream_format(stream, "SHLL2 %s", regname[Rn]); + break; + case 0x09: + util::stream_format(stream, "SHLR2 %s", regname[Rn]); + break; + case 0x0a: + util::stream_format(stream, "LDS %s,MACH", regname[Rn]); + break; + case 0x0b: + util::stream_format(stream, "JSR %s", regname[Rn]); + flags = STEP_OVER | step_over_extra(1); + break; + case 0x0e: + util::stream_format(stream, "LDC %s,SR", regname[Rn]); + break; + case 0x10: + util::stream_format(stream, "DT %s", regname[Rn]); + break; + case 0x11: + util::stream_format(stream, "CMP/PZ %s", regname[Rn]); + break; + case 0x12: + util::stream_format(stream, "STS.L MACL,@-%s", regname[Rn]); + break; + case 0x13: + util::stream_format(stream, "STC.L GBR,@-%s", regname[Rn]); + break; + case 0x15: + util::stream_format(stream, "CMP/PL %s", regname[Rn]); + break; + case 0x16: + util::stream_format(stream, "LDS.L @%s+,MACL", regname[Rn]); + break; + case 0x17: + util::stream_format(stream, "LDC.L @%s+,GBR", regname[Rn]); + break; + case 0x18: + util::stream_format(stream, "SHLL8 %s", regname[Rn]); + break; + case 0x19: + util::stream_format(stream, "SHLR8 %s", regname[Rn]); + break; + case 0x1a: + util::stream_format(stream, "LDS %s,MACL", regname[Rn]); + break; + case 0x1b: + util::stream_format(stream, "TAS %s", regname[Rn]); + break; + case 0x1e: + util::stream_format(stream, "LDC %s,GBR", regname[Rn]); + break; + case 0x20: + util::stream_format(stream, "SHAL %s", regname[Rn]); + break; + case 0x21: + util::stream_format(stream, "SHAR %s", regname[Rn]); + break; + case 0x22: + util::stream_format(stream, "STS.L PR,@-%s", regname[Rn]); + break; + case 0x23: + util::stream_format(stream, "STC.L VBR,@-%s", regname[Rn]); + break; + case 0x24: + util::stream_format(stream, "ROTCL %s", regname[Rn]); + break; + case 0x25: + util::stream_format(stream, "ROTCR %s", regname[Rn]); + break; + case 0x26: + util::stream_format(stream, "LDS.L @%s+,PR", regname[Rn]); + break; + case 0x27: + util::stream_format(stream, "LDC.L @%s+,VBR", regname[Rn]); + break; + case 0x28: + util::stream_format(stream, "SHLL16 %s", regname[Rn]); + break; + case 0x29: + util::stream_format(stream, "SHLR16 %s", regname[Rn]); + break; + case 0x2a: + util::stream_format(stream, "LDS %s,PR", regname[Rn]); + break; + case 0x2b: + util::stream_format(stream, "JMP %s", regname[Rn]); + break; + case 0x2e: + util::stream_format(stream, "LDC %s,VBR", regname[Rn]); + break; + default: + if ((opcode & 15) == 15) + util::stream_format(stream, "MAC.W @%s+,@%s+", regname[Rm], regname[Rn]); + else + util::stream_format(stream, "?????? $%04X", opcode); + } + return flags; +} + +uint32_t sh_disassembler::op0101(std::ostream &stream, uint32_t pc, uint16_t opcode) +{ + util::stream_format(stream, "MOV.L @($%02X,%s),%s", (opcode & 15) * 4, regname[Rm], regname[Rn]); + return 0; +} + +uint32_t sh_disassembler::op0110(std::ostream &stream, uint32_t pc, uint16_t opcode) + +{ + switch(opcode & 0xF) + { + case 0x00: + util::stream_format(stream, "MOV.B @%s,%s", regname[Rm], regname[Rn]); + break; + case 0x01: + util::stream_format(stream, "MOV.W @%s,%s", regname[Rm], regname[Rn]); + break; + case 0x02: + util::stream_format(stream, "MOV.L @%s,%s", regname[Rm], regname[Rn]); + break; + case 0x03: + util::stream_format(stream, "MOV %s,%s", regname[Rm], regname[Rn]); + break; + case 0x04: + util::stream_format(stream, "MOV.B @%s+,%s", regname[Rm], regname[Rn]); + break; + case 0x05: + util::stream_format(stream, "MOV.W @%s+,%s", regname[Rm], regname[Rn]); + break; + case 0x06: + util::stream_format(stream, "MOV.L @%s+,%s", regname[Rm], regname[Rn]); + break; + case 0x07: + util::stream_format(stream, "NOT %s,%s", regname[Rm], regname[Rn]); + break; + case 0x08: + util::stream_format(stream, "SWAP.B %s,%s", regname[Rm], regname[Rn]); + break; + case 0x09: + util::stream_format(stream, "SWAP.W %s,%s", regname[Rm], regname[Rn]); + break; + case 0x0a: + util::stream_format(stream, "NEGC %s,%s", regname[Rm], regname[Rn]); + break; + case 0x0b: + util::stream_format(stream, "NEG %s,%s", regname[Rm], regname[Rn]); + break; + case 0x0c: + util::stream_format(stream, "EXTU.B %s,%s", regname[Rm], regname[Rn]); + break; + case 0x0d: + util::stream_format(stream, "EXTU.W %s,%s", regname[Rm], regname[Rn]); + break; + case 0x0e: + util::stream_format(stream, "EXTS.B %s,%s", regname[Rm], regname[Rn]); + break; + case 0x0f: + util::stream_format(stream, "EXTS.W %s,%s", regname[Rm], regname[Rn]); + break; + } + return 0; +} + +uint32_t sh_disassembler::op0111(std::ostream &stream, uint32_t pc, uint16_t opcode) +{ + util::stream_format(stream, "ADD #$%02X,%s", opcode & 0xff, regname[Rn]); + return 0; +} + +uint32_t sh_disassembler::op1000(std::ostream &stream, uint32_t pc, uint16_t opcode) +{ + switch((opcode >> 8) & 15) + { + case 0: + util::stream_format(stream, "MOV.B R0,@($%02X,%s)", (opcode & 15), regname[Rm]); + break; + case 1: + util::stream_format(stream, "MOV.W R0,@($%02X,%s)", (opcode & 15) * 2, regname[Rm]); + break; + case 4: + util::stream_format(stream, "MOV.B @($%02X,%s),R0", (opcode & 15), regname[Rm]); + break; + case 5: + util::stream_format(stream, "MOV.W @($%02X,%s),R0", (opcode & 15) * 2, regname[Rm]); + break; + case 8: + util::stream_format(stream, "CMP/EQ #$%02X,R0", (opcode & 0xff)); + break; + case 9: + util::stream_format(stream, "BT $%08X", pc + SIGNX8(opcode & 0xff) * 2 + 2); + break; + case 11: + util::stream_format(stream, "BF $%08X", pc + SIGNX8(opcode & 0xff) * 2 + 2); + break; + case 13: + util::stream_format(stream, "BTS $%08X", pc + SIGNX8(opcode & 0xff) * 2 + 2); + break; + case 15: + util::stream_format(stream, "BFS $%08X", pc + SIGNX8(opcode & 0xff) * 2 + 2); + break; + default : + util::stream_format(stream, "invalid $%04X", opcode); + } + return 0; +} + +uint32_t sh_disassembler::op1001(std::ostream &stream, uint32_t pc, uint16_t opcode) +{ + util::stream_format(stream, "MOV.W @($%04X,PC),%s [%08X]", (opcode & 0xff) * 2, regname[Rn], pc+((opcode & 0xff) * 2)+2); + return 0; +} + +uint32_t sh_disassembler::op1010(std::ostream &stream, uint32_t pc, uint16_t opcode) +{ + util::stream_format(stream, "BRA $%08X", SIGNX12(opcode & 0xfff) * 2 + pc + 2); + return 0; +} + +uint32_t sh_disassembler::op1011(std::ostream &stream, uint32_t pc, uint16_t opcode) +{ + util::stream_format(stream, "BSR $%08X", SIGNX12(opcode & 0xfff) * 2 + pc + 2); + return STEP_OVER | step_over_extra(1); +} + +uint32_t sh_disassembler::op1100(std::ostream &stream, uint32_t pc, uint16_t opcode) +{ + uint32_t flags = 0; + switch((opcode >> 8) & 15) + { + case 0: + util::stream_format(stream, "MOV.B R0,@($%02X,GBR)", opcode & 0xff); + break; + case 1: + util::stream_format(stream, "MOV.W R0,@($%04X,GBR)", (opcode & 0xff) * 2); + break; + case 2: + util::stream_format(stream, "MOV.L R0,@($%04X,GBR)", (opcode & 0xff) * 4); + break; + case 3: + util::stream_format(stream, "TRAPA #$%02X", opcode & 0xff); + flags = STEP_OVER; + break; + case 4: + util::stream_format(stream, "MOV.B @($%02X,GBR),R0", opcode & 0xff); + break; + case 5: + util::stream_format(stream, "MOV.W @($%04X,GBR),R0", (opcode & 0xff) * 2); + break; + case 6: + util::stream_format(stream, "MOV.L @($%04X,GBR),R0", (opcode & 0xff) * 4); + break; + case 7: + util::stream_format(stream, "MOVA @($%04X,PC),R0 [%08X]", (opcode & 0xff) * 4, ((pc + 2) & ~3) + (opcode & 0xff) * 4); + break; + case 8: + util::stream_format(stream, "TST #$%02X,R0", opcode & 0xff); + break; + case 9: + util::stream_format(stream, "AND #$%02X,R0", opcode & 0xff); + break; + case 10: + util::stream_format(stream, "XOR #$%02X,R0", opcode & 0xff); + break; + case 11: + util::stream_format(stream, "OR #$%02X,R0", opcode & 0xff); + break; + case 12: + util::stream_format(stream, "TST.B #$%02X,@(R0,GBR)", opcode & 0xff); + break; + case 13: + util::stream_format(stream, "AND.B #$%02X,@(R0,GBR)", opcode & 0xff); + break; + case 14: + util::stream_format(stream, "XOR.B #$%02X,@(R0,GBR)", opcode & 0xff); + break; + case 15: + util::stream_format(stream, "OR.B #$%02X,@(R0,GBR)", opcode & 0xff); + break; + } + return flags; +} + +uint32_t sh_disassembler::op1101(std::ostream &stream, uint32_t pc, uint16_t opcode) +{ + util::stream_format(stream, "MOV.L @($%04X,PC),%s [%08X]", (opcode & 0xff) * 4, regname[Rn], ((pc + 2) & ~3) + (opcode & 0xff) * 4); + return 0; +} + +uint32_t sh_disassembler::op1110(std::ostream &stream, uint32_t pc, uint16_t opcode) +{ + util::stream_format(stream, "MOV #$%02X,%s", (opcode & 0xff), regname[Rn]); + return 0; +} + +uint32_t sh_disassembler::op1111(std::ostream &stream, uint32_t pc, uint16_t opcode) +{ + util::stream_format(stream, "unknown $%04X", opcode); + return 0; +} + + +/* SH4 specifics */ + + +uint32_t sh_disassembler::op0000_sh34(std::ostream &stream, uint32_t pc, uint16_t opcode) { uint32_t flags = 0; switch (opcode & 0xF) @@ -142,14 +708,14 @@ static uint32_t op0000(std::ostream &stream, uint32_t pc, uint16_t opcode) { case 0x00: stream << "RTS"; - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; case 0x10: stream << "SLEEP"; break; case 0x20: stream << "RTE"; - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; } break; @@ -169,125 +735,8 @@ static uint32_t op0000(std::ostream &stream, uint32_t pc, uint16_t opcode) return flags; } -static uint32_t op0001(std::ostream &stream, uint32_t pc, uint16_t opcode) -{ - util::stream_format(stream, "MOV.L %s,@($%02X,%s)", regname[Rm], (opcode & 15) * 4, regname[Rn]); - return 0; -} -static uint32_t op0010(std::ostream &stream, uint32_t pc, uint16_t opcode) -{ - switch (opcode & 15) - { - case 0: - util::stream_format(stream, "MOV.B %s,@%s", regname[Rm], regname[Rn]); - break; - case 1: - util::stream_format(stream, "MOV.W %s,@%s", regname[Rm], regname[Rn]); - break; - case 2: - util::stream_format(stream, "MOV.L %s,@%s", regname[Rm], regname[Rn]); - break; - case 3: - util::stream_format(stream, "?????? $%04X", opcode); - break; - case 4: - util::stream_format(stream, "MOV.B %s,@-%s", regname[Rm], regname[Rn]); - break; - case 5: - util::stream_format(stream, "MOV.W %s,@-%s", regname[Rm], regname[Rn]); - break; - case 6: - util::stream_format(stream, "MOV.L %s,@-%s", regname[Rm], regname[Rn]); - break; - case 7: - util::stream_format(stream, "DIV0S %s,%s", regname[Rm], regname[Rn]); - break; - case 8: - util::stream_format(stream, "TST %s,%s", regname[Rm], regname[Rn]); - break; - case 9: - util::stream_format(stream, "AND %s,%s", regname[Rm], regname[Rn]); - break; - case 10: - util::stream_format(stream, "XOR %s,%s", regname[Rm], regname[Rn]); - break; - case 11: - util::stream_format(stream, "OR %s,%s", regname[Rm], regname[Rn]); - break; - case 12: - util::stream_format(stream, "CMP/STR %s,%s", regname[Rm], regname[Rn]); - break; - case 13: - util::stream_format(stream, "XTRCT %s,%s", regname[Rm], regname[Rn]); - break; - case 14: - util::stream_format(stream, "MULU.W %s,%s", regname[Rm], regname[Rn]); - break; - case 15: - util::stream_format(stream, "MULS.W %s,%s", regname[Rm], regname[Rn]); - break; - } - return 0; -} - -static uint32_t op0011(std::ostream &stream, uint32_t pc, uint16_t opcode) -{ - switch (opcode & 15) - { - case 0: - util::stream_format(stream, "CMP/EQ %s,%s", regname[Rm], regname[Rn]); - break; - case 1: - util::stream_format(stream, "?????? %s,%s", regname[Rm], regname[Rn]); - break; - case 2: - util::stream_format(stream, "CMP/HS %s,%s", regname[Rm], regname[Rn]); - break; - case 3: - util::stream_format(stream, "CMP/GE %s,%s", regname[Rm], regname[Rn]); - break; - case 4: - util::stream_format(stream, "DIV1 %s,%s", regname[Rm], regname[Rn]); - break; - case 5: - util::stream_format(stream, "DMULU.L %s,%s", regname[Rm], regname[Rn]); - break; - case 6: - util::stream_format(stream, "CMP/HI %s,%s", regname[Rm], regname[Rn]); - break; - case 7: - util::stream_format(stream, "CMP/GT %s,%s", regname[Rm], regname[Rn]); - break; - case 8: - util::stream_format(stream, "SUB %s,%s", regname[Rm], regname[Rn]); - break; - case 9: - util::stream_format(stream, "?????? %s,%s", regname[Rm], regname[Rn]); - break; - case 10: - util::stream_format(stream, "SUBC %s,%s", regname[Rm], regname[Rn]); - break; - case 11: - util::stream_format(stream, "SUBV %s,%s", regname[Rm], regname[Rn]); - break; - case 12: - util::stream_format(stream, "ADD %s,%s", regname[Rm], regname[Rn]); - break; - case 13: - util::stream_format(stream, "DMULS.L %s,%s", regname[Rm], regname[Rn]); - break; - case 14: - util::stream_format(stream, "ADDC %s,%s", regname[Rm], regname[Rn]); - break; - case 15: - util::stream_format(stream, "ADDV %s,%s", regname[Rm], regname[Rn]); - break; - } - return 0; -} - -static uint32_t op0100(std::ostream &stream, uint32_t pc, uint16_t opcode) +uint32_t sh_disassembler::op0100_sh34(std::ostream &stream, uint32_t pc, uint16_t opcode) { uint32_t flags = 0; switch (opcode & 0xF) @@ -498,7 +947,7 @@ static uint32_t op0100(std::ostream &stream, uint32_t pc, uint16_t opcode) { case 0x00: util::stream_format(stream, "JSR %s", regname[Rn]); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; case 0x10: util::stream_format(stream, "TAS %s", regname[Rn]); @@ -545,205 +994,8 @@ static uint32_t op0100(std::ostream &stream, uint32_t pc, uint16_t opcode) return flags; } -static uint32_t op0101(std::ostream &stream, uint32_t pc, uint16_t opcode) -{ - util::stream_format(stream, "MOV.L @($%02X,%s),%s", (opcode & 15) * 4, regname[Rm], regname[Rn]); - return 0; -} - -static uint32_t op0110(std::ostream &stream, uint32_t pc, uint16_t opcode) - -{ - switch(opcode & 0xF) - { - case 0x00: - util::stream_format(stream, "MOV.B @%s,%s", regname[Rm], regname[Rn]); - break; - case 0x01: - util::stream_format(stream, "MOV.W @%s,%s", regname[Rm], regname[Rn]); - break; - case 0x02: - util::stream_format(stream, "MOV.L @%s,%s", regname[Rm], regname[Rn]); - break; - case 0x03: - util::stream_format(stream, "MOV %s,%s", regname[Rm], regname[Rn]); - break; - case 0x04: - util::stream_format(stream, "MOV.B @%s+,%s", regname[Rm], regname[Rn]); - break; - case 0x05: - util::stream_format(stream, "MOV.W @%s+,%s", regname[Rm], regname[Rn]); - break; - case 0x06: - util::stream_format(stream, "MOV.L @%s+,%s", regname[Rm], regname[Rn]); - break; - case 0x07: - util::stream_format(stream, "NOT %s,%s", regname[Rm], regname[Rn]); - break; - case 0x08: - util::stream_format(stream, "SWAP.B %s,%s", regname[Rm], regname[Rn]); - break; - case 0x09: - util::stream_format(stream, "SWAP.W %s,%s", regname[Rm], regname[Rn]); - break; - case 0x0a: - util::stream_format(stream, "NEGC %s,%s", regname[Rm], regname[Rn]); - break; - case 0x0b: - util::stream_format(stream, "NEG %s,%s", regname[Rm], regname[Rn]); - break; - case 0x0c: - util::stream_format(stream, "EXTU.B %s,%s", regname[Rm], regname[Rn]); - break; - case 0x0d: - util::stream_format(stream, "EXTU.W %s,%s", regname[Rm], regname[Rn]); - break; - case 0x0e: - util::stream_format(stream, "EXTS.B %s,%s", regname[Rm], regname[Rn]); - break; - case 0x0f: - util::stream_format(stream, "EXTS.W %s,%s", regname[Rm], regname[Rn]); - break; - } - return 0; -} - -static uint32_t op0111(std::ostream &stream, uint32_t pc, uint16_t opcode) -{ - util::stream_format(stream, "ADD #$%02X,%s", opcode & 0xff, regname[Rn]); - return 0; -} - -static uint32_t op1000(std::ostream &stream, uint32_t pc, uint16_t opcode) -{ - switch((opcode >> 8) & 15) - { - case 0: - util::stream_format(stream, "MOV.B R0,@($%02X,%s)", (opcode & 15), regname[Rm]); - break; - case 1: - util::stream_format(stream, "MOV.W R0,@($%02X,%s)", (opcode & 15) * 2, regname[Rm]); - break; - case 4: - util::stream_format(stream, "MOV.B @($%02X,%s),R0", (opcode & 15), regname[Rm]); - break; - case 5: - util::stream_format(stream, "MOV.W @($%02X,%s),R0", (opcode & 15) * 2, regname[Rm]); - break; - case 8: - util::stream_format(stream, "CMP/EQ #$%02X,R0", (opcode & 0xff)); - break; - case 9: - util::stream_format(stream, "BT $%08X", pc + SIGNX8(opcode & 0xff) * 2 + 2); - break; - case 11: - util::stream_format(stream, "BF $%08X", pc + SIGNX8(opcode & 0xff) * 2 + 2); - break; - case 13: - util::stream_format(stream, "BTS $%08X", pc + SIGNX8(opcode & 0xff) * 2 + 2); - break; - case 15: - util::stream_format(stream, "BFS $%08X", pc + SIGNX8(opcode & 0xff) * 2 + 2); - break; - default : - util::stream_format(stream, "invalid $%04X", opcode); - } - return 0; -} - -static uint32_t op1001(std::ostream &stream, uint32_t pc, uint16_t opcode) -{ -uint32_t ea=(pc+((opcode & 0xff) * 2)+2); - - util::stream_format(stream, "MOV.W @($%04X,PC),%s [%08X]", (opcode & 0xff) * 2, regname[Rn], ea); - return 0; -} - -static uint32_t op1010(std::ostream &stream, uint32_t pc, uint16_t opcode) -{ - util::stream_format(stream, "BRA $%08X", SIGNX12(opcode & 0xfff) * 2 + pc + 2); - return 0; -} - -static uint32_t op1011(std::ostream &stream, uint32_t pc, uint16_t opcode) -{ - util::stream_format(stream, "BSR $%08X", SIGNX12(opcode & 0xfff) * 2 + pc + 2); - return DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); -} - -static uint32_t op1100(std::ostream &stream, uint32_t pc, uint16_t opcode) -{ - uint32_t flags = 0; - switch((opcode >> 8) & 15) - { - case 0: - util::stream_format(stream, "MOV.B R0,@($%02X,GBR)", opcode & 0xff); - break; - case 1: - util::stream_format(stream, "MOV.W R0,@($%04X,GBR)", (opcode & 0xff) * 2); - break; - case 2: - util::stream_format(stream, "MOV.L R0,@($%04X,GBR)", (opcode & 0xff) * 4); - break; - case 3: - util::stream_format(stream, "TRAPA #$%02X", opcode & 0xff); - flags = DASMFLAG_STEP_OVER; - break; - case 4: - util::stream_format(stream, "MOV.B @($%02X,GBR),R0", opcode & 0xff); - break; - case 5: - util::stream_format(stream, "MOV.W @($%04X,GBR),R0", (opcode & 0xff) * 2); - break; - case 6: - util::stream_format(stream, "MOV.L @($%04X,GBR),R0", (opcode & 0xff) * 4); - break; - case 7: - util::stream_format(stream, "MOVA @($%04X,PC),R0 [%08X]", (opcode & 0xff) * 4, ((pc + 2) & ~3) + (opcode & 0xff) * 4); - break; - case 8: - util::stream_format(stream, "TST #$%02X,R0", opcode & 0xff); - break; - case 9: - util::stream_format(stream, "AND #$%02X,R0", opcode & 0xff); - break; - case 10: - util::stream_format(stream, "XOR #$%02X,R0", opcode & 0xff); - break; - case 11: - util::stream_format(stream, "OR #$%02X,R0", opcode & 0xff); - break; - case 12: - util::stream_format(stream, "TST.B #$%02X,@(R0,GBR)", opcode & 0xff); - break; - case 13: - util::stream_format(stream, "AND.B #$%02X,@(R0,GBR)", opcode & 0xff); - break; - case 14: - util::stream_format(stream, "XOR.B #$%02X,@(R0,GBR)", opcode & 0xff); - break; - case 15: - util::stream_format(stream, "OR.B #$%02X,@(R0,GBR)", opcode & 0xff); - break; - } - return flags; -} - -static uint32_t op1101(std::ostream &stream, uint32_t pc, uint16_t opcode) -{ -uint32_t ea=((pc + 2) & ~3) + (opcode & 0xff) * 4; - - util::stream_format(stream, "MOV.L @($%04X,PC),%s [%08X]", (opcode & 0xff) * 4, regname[Rn], ea); - return 0; -} -static uint32_t op1110(std::ostream &stream, uint32_t pc, uint16_t opcode) -{ - util::stream_format(stream, "MOV #$%02X,%s", (opcode & 0xff), regname[Rn]); - return 0; -} - -static uint32_t op1111(std::ostream &stream, uint32_t pc, uint16_t opcode) +uint32_t sh_disassembler::op1111_sh34(std::ostream &stream, uint32_t pc, uint16_t opcode) { switch (opcode & 0xf) { @@ -866,40 +1118,73 @@ static uint32_t op1111(std::ostream &stream, uint32_t pc, uint16_t opcode) return 0; } -unsigned DasmSH4(std::ostream &stream, unsigned pc, uint16_t opcode) +offs_t sh_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + u16 opcode = opcodes.r16(pc); + return dasm_one(stream, pc, opcode); +} + +offs_t sh_disassembler::dasm_one(std::ostream &stream, offs_t pc, u16 opcode) { uint32_t flags; pc += 2; - switch ((opcode >> 12) & 15) + if (m_is_sh34) { - case 0: flags = op0000(stream, pc, opcode); break; - case 1: flags = op0001(stream, pc, opcode); break; - case 2: flags = op0010(stream, pc, opcode); break; - case 3: flags = op0011(stream, pc, opcode); break; - case 4: flags = op0100(stream, pc, opcode); break; - case 5: flags = op0101(stream, pc, opcode); break; - case 6: flags = op0110(stream, pc, opcode); break; - case 7: flags = op0111(stream, pc, opcode); break; - case 8: flags = op1000(stream, pc, opcode); break; - case 9: flags = op1001(stream, pc, opcode); break; - case 10: flags = op1010(stream, pc, opcode); break; - case 11: flags = op1011(stream, pc, opcode); break; - case 12: flags = op1100(stream, pc, opcode); break; - case 13: flags = op1101(stream, pc, opcode); break; - case 14: flags = op1110(stream, pc, opcode); break; - default: flags = op1111(stream, pc, opcode); break; + switch ((opcode >> 12) & 15) + { + case 0: flags = op0000_sh34(stream, pc, opcode); break; + case 1: flags = op0001(stream, pc, opcode); break; + case 2: flags = op0010(stream, pc, opcode); break; + case 3: flags = op0011(stream, pc, opcode); break; + case 4: flags = op0100_sh34(stream, pc, opcode); break; + case 5: flags = op0101(stream, pc, opcode); break; + case 6: flags = op0110(stream, pc, opcode); break; + case 7: flags = op0111(stream, pc, opcode); break; + case 8: flags = op1000(stream, pc, opcode); break; + case 9: flags = op1001(stream, pc, opcode); break; + case 10: flags = op1010(stream, pc, opcode); break; + case 11: flags = op1011(stream, pc, opcode); break; + case 12: flags = op1100(stream, pc, opcode); break; + case 13: flags = op1101(stream, pc, opcode); break; + case 14: flags = op1110(stream, pc, opcode); break; + default: flags = op1111_sh34(stream, pc, opcode); break; + } } - return 2 | flags | DASMFLAG_SUPPORTED; + else + { + switch ((opcode >> 12) & 15) + { + case 0: flags = op0000(stream, pc, opcode); break; + case 1: flags = op0001(stream, pc, opcode); break; + case 2: flags = op0010(stream, pc, opcode); break; + case 3: flags = op0011(stream, pc, opcode); break; + case 4: flags = op0100(stream, pc, opcode); break; + case 5: flags = op0101(stream, pc, opcode); break; + case 6: flags = op0110(stream, pc, opcode); break; + case 7: flags = op0111(stream, pc, opcode); break; + case 8: flags = op1000(stream, pc, opcode); break; + case 9: flags = op1001(stream, pc, opcode); break; + case 10: flags = op1010(stream, pc, opcode); break; + case 11: flags = op1011(stream, pc, opcode); break; + case 12: flags = op1100(stream, pc, opcode); break; + case 13: flags = op1101(stream, pc, opcode); break; + case 14: flags = op1110(stream, pc, opcode); break; + default: flags = op1111(stream, pc, opcode); break; + } + } + + return 2 | flags | SUPPORTED; } -CPU_DISASSEMBLE(sh4) + +u32 sh_disassembler::opcode_alignment() const { - return DasmSH4(stream, pc, (oprom[1] << 8) | oprom[0]); + return 2; } -CPU_DISASSEMBLE(sh4be) +sh_disassembler::sh_disassembler(bool is_sh34) : m_is_sh34(is_sh34) { - return DasmSH4(stream, pc, (oprom[0] << 8) | oprom[1]); } + diff --git a/src/devices/cpu/sh/sh_dasm.h b/src/devices/cpu/sh/sh_dasm.h new file mode 100644 index 00000000000..52d6b2eb723 --- /dev/null +++ b/src/devices/cpu/sh/sh_dasm.h @@ -0,0 +1,45 @@ +// license:BSD-3-Clause +// copyright-holders:Juergen Buchmueller, R. Belmont + +#ifndef MAME_CPU_SH_SHDASM_H +#define MAME_CPU_SH_SHDASM_H + +#pragma once + +class sh_disassembler : public util::disasm_interface +{ +public: + sh_disassembler(bool is_sh34); + virtual ~sh_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + + offs_t dasm_one(std::ostream &stream, offs_t pc, u16 opcode); + +private: + static const char *const regname[16]; + uint32_t op0000(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op0001(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op0010(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op0011(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op0100(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op0101(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op0110(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op0111(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op1000(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op1001(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op1010(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op1011(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op1100(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op1101(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op1110(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op1111(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op0000_sh34(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op0100_sh34(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op1111_sh34(std::ostream &stream, uint32_t pc, uint16_t opcode); + + bool m_is_sh34; +}; + +#endif diff --git a/src/devices/cpu/sh/sh_fe.cpp b/src/devices/cpu/sh/sh_fe.cpp new file mode 100644 index 00000000000..1abede64dc4 --- /dev/null +++ b/src/devices/cpu/sh/sh_fe.cpp @@ -0,0 +1,772 @@ +// license:BSD-3-Clause +// copyright-holders:David Haywood, R. Belmont +/*************************************************************************** + + sh_fe.c + + Front end for SH recompiler + +***************************************************************************/ + +#include "emu.h" +#include "sh2.h" +#include "sh2comn.h" +#include "cpu/drcfe.h" + + +/*************************************************************************** + INSTRUCTION PARSERS +***************************************************************************/ + +sh_frontend::sh_frontend(sh_common_execution *device, uint32_t window_start, uint32_t window_end, uint32_t max_sequence) + : drc_frontend(*device, window_start, window_end, max_sequence) + , m_sh(device) +{ +} + +/*------------------------------------------------- + describe_instruction - build a description + of a single instruction +-------------------------------------------------*/ + +inline uint16_t sh_frontend::read_word(opcode_desc &desc) +{ + return m_sh->m_direct->read_word(desc.physpc, SH2_CODE_XOR(0)); +} + +bool sh_frontend::describe(opcode_desc &desc, const opcode_desc *prev) +{ + uint16_t opcode; + + /* fetch the opcode */ + opcode = desc.opptr.w[0] = read_word(desc); + + /* all instructions are 2 bytes and most are a single cycle */ + desc.length = 2; + desc.cycles = 1; + + switch (opcode>>12) + { + case 0: + return describe_group_0(desc, prev, opcode); + + case 1: // MOVLS4 + desc.regin[0] |= REGFLAG_R(Rn) | REGFLAG_R(Rm); + desc.flags |= OPFLAG_WRITES_MEMORY; + return true; + + case 2: + return describe_group_2(desc, prev, opcode); + + case 3: + return describe_group_3(desc, prev, opcode); + + case 4: + return describe_group_4(desc, prev, opcode); + + case 5: // MOVLL4 + desc.regin[0] |= REGFLAG_R(Rm); + desc.regout[0] |= REGFLAG_R(Rn); + desc.flags |= OPFLAG_READS_MEMORY; + return true; + + case 6: + return describe_group_6(desc, prev, opcode); + + case 7: // ADDI + desc.regin[0] |= REGFLAG_R(Rn); + desc.regout[0] |= REGFLAG_R(Rn); + return true; + + case 8: + return describe_group_8(desc, prev, opcode); + + case 9: // MOVWI + desc.regout[0] |= REGFLAG_R(Rn); + desc.flags |= OPFLAG_READS_MEMORY; + return true; + + case 11: // BSR + desc.regout[1] |= REGFLAG_PR; + // (intentional fallthrough - BSR is BRA with the addition of PR = the return address) + case 10: // BRA + { + int32_t disp = ((int32_t)opcode << 20) >> 20; + + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + desc.targetpc = (desc.pc + 2) + disp * 2 + 2; + desc.delayslots = 1; + desc.cycles = 2; + return true; + } + + case 12: + return describe_group_12(desc, prev, opcode); + + case 13: // MOVLI + desc.regout[0] |= REGFLAG_R(Rn); + desc.flags |= OPFLAG_READS_MEMORY; + return true; + + case 14: // MOVI + desc.regout[0] |= REGFLAG_R(Rn); + return true; + + case 15: // NOP + return describe_group_15(desc, prev, opcode); + } + + return false; +} + + +bool sh_frontend::describe_group_2(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) +{ + switch (opcode & 15) + { + case 0: // MOVBS(Rm, Rn); + case 1: // MOVWS(Rm, Rn); + case 2: // MOVLS(Rm, Rn); + desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn); + desc.flags |= OPFLAG_WRITES_MEMORY; + return true; + + case 3: // NOP(); + return true; + + case 4: // MOVBM(Rm, Rn); + case 5: // MOVWM(Rm, Rn); + case 6: // MOVLM(Rm, Rn); + case 13: // XTRCT(Rm, Rn); + desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn); + desc.regout[0] |= REGFLAG_R(Rn); + desc.flags |= OPFLAG_WRITES_MEMORY; + return true; + + case 7: // DIV0S(Rm, Rn); + case 8: // TST(Rm, Rn); + case 12: // CMPSTR(Rm, Rn); + desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn); + desc.regout[1] |= REGFLAG_SR; + return true; + + case 9: // AND(Rm, Rn); + case 10: // XOR(Rm, Rn); + case 11: // OR(Rm, Rn); + desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn); + desc.regout[0] |= REGFLAG_R(Rn); + return true; + + case 14: // MULU(Rm, Rn); + case 15: // MULS(Rm, Rn); + desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn); + desc.regout[1] |= REGFLAG_MACL | REGFLAG_MACH; + desc.cycles = 2; + return true; + } + + return false; +} + +bool sh_frontend::describe_group_3(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) +{ + switch (opcode & 15) + { + case 0: // CMPEQ(Rm, Rn); + case 2: // CMPHS(Rm, Rn); + case 3: // CMPGE(Rm, Rn); + case 6: // CMPHI(Rm, Rn); + case 7: // CMPGT(Rm, Rn); + desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn); + desc.regout[1] |= REGFLAG_SR; + return true; + + case 1: // NOP(); + case 9: // NOP(); + return true; + + case 4: // DIV1(Rm, Rn); + desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn); + desc.regout[0] |= REGFLAG_R(Rn); + desc.regout[1] |= REGFLAG_SR; + return true; + + case 5: // DMULU(Rm, Rn); + case 13: // DMULS(Rm, Rn); + desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn); + desc.regout[1] |= REGFLAG_MACL | REGFLAG_MACH; + desc.cycles = 2; + return true; + + case 8: // SUB(Rm, Rn); + case 12: // ADD(Rm, Rn); + desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn); + desc.regout[0] |= REGFLAG_R(Rn); + return true; + + case 10: // SUBC(Rm, Rn); + case 11: // SUBV(Rm, Rn); + case 14: // ADDC(Rm, Rn); + case 15: // ADDV(Rm, Rn); + desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn); + desc.regin[1] |= REGFLAG_SR; + desc.regout[0] |= REGFLAG_R(Rn); + desc.regout[1] |= REGFLAG_SR; + return true; + } + return false; +} + + +bool sh_frontend::describe_group_6(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) +{ + switch (opcode & 15) + { + case 0: // MOVBL(Rm, Rn); + case 1: // MOVWL(Rm, Rn); + case 2: // MOVLL(Rm, Rn); + case 3: // MOV(Rm, Rn); + case 7: // NOT(Rm, Rn); + case 9: // SWAPW(Rm, Rn); + case 11: // NEG(Rm, Rn); + case 12: // EXTUB(Rm, Rn); + case 13: // EXTUW(Rm, Rn); + case 14: // EXTSB(Rm, Rn); + case 15: // EXTSW(Rm, Rn); + desc.regin[0] |= REGFLAG_R(Rm); + desc.regout[0] |= REGFLAG_R(Rn); + return true; + + case 4: // MOVBP(Rm, Rn); + case 5: // MOVWP(Rm, Rn); + case 6: // MOVLP(Rm, Rn); + desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn); + desc.regout[0] |= REGFLAG_R(Rn); + desc.flags |= OPFLAG_READS_MEMORY; + return true; + + case 8: // SWAPB(Rm, Rn); + desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn); + desc.regout[0] |= REGFLAG_R(Rn); + return true; + + case 10: // NEGC(Rm, Rn); + desc.regin[0] |= REGFLAG_R(Rm); + desc.regout[0] |= REGFLAG_R(Rn); + desc.regout[1] |= REGFLAG_SR; + return true; + } + return false; +} + +bool sh_frontend::describe_group_8(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) +{ + int32_t disp; + + switch ( opcode & (15<<8) ) + { + case 0 << 8: // MOVBS4(opcode & 0x0f, Rm); + case 1 << 8: // MOVWS4(opcode & 0x0f, Rm); + desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(0); + desc.flags |= OPFLAG_WRITES_MEMORY; + return true; + + case 2<< 8: // NOP(); + case 3<< 8: // NOP(); + case 6<< 8: // NOP(); + case 7<< 8: // NOP(); + case 10<< 8: // NOP(); + case 12<< 8: // NOP(); + case 14<< 8: // NOP(); + return true; + + case 4<< 8: // MOVBL4(Rm, opcode & 0x0f); + case 5<< 8: // MOVWL4(Rm, opcode & 0x0f); + desc.regin[0] |= REGFLAG_R(Rm); + desc.regout[0] |= REGFLAG_R(0); + desc.flags |= OPFLAG_READS_MEMORY; + return true; + + case 8<< 8: // CMPIM(opcode & 0xff); + desc.regin[0] |= REGFLAG_R(Rm); + desc.regin[1] |= REGFLAG_SR; + desc.regout[1] |= REGFLAG_SR; + return true; + + case 9<< 8: // BT(opcode & 0xff); + case 11<< 8: // BF(opcode & 0xff); + desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH; + desc.cycles = 3; + disp = ((int32_t)opcode << 24) >> 24; + desc.targetpc = (desc.pc + 2) + disp * 2 + 2; + return true; + + case 13<< 8: // BTS(opcode & 0xff); + case 15<< 8: // BFS(opcode & 0xff); + desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH; + desc.cycles = 2; + disp = ((int32_t)opcode << 24) >> 24; + desc.targetpc = (desc.pc + 2) + disp * 2 + 2; + desc.delayslots = 1; + return true; + } + + return false; +} + +bool sh_frontend::describe_group_12(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) +{ + switch (opcode & (15<<8)) + { + case 0<<8: // MOVBSG(opcode & 0xff); + case 1<<8: // MOVWSG(opcode & 0xff); + case 2<<8: // MOVLSG(opcode & 0xff); + desc.regin[0] |= REGFLAG_R(0); + desc.flags |= OPFLAG_WRITES_MEMORY; + return true; + + case 3<<8: // TRAPA(opcode & 0xff); + desc.regin[0] |= REGFLAG_R(15); + desc.regin[1] |= REGFLAG_VBR; + desc.regout[0] |= REGFLAG_R(15); + desc.cycles = 8; + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.flags |= OPFLAG_READS_MEMORY | OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + return true; + + case 4<<8: // MOVBLG(opcode & 0xff); + case 5<<8: // MOVWLG(opcode & 0xff); + case 6<<8: // MOVLLG(opcode & 0xff); + case 7<<8: // MOVA(opcode & 0xff); + desc.regout[0] |= REGFLAG_R(0); + desc.flags |= OPFLAG_READS_MEMORY; + return true; + + case 8<<8: // TSTI(opcode & 0xff); + desc.regin[0] |= REGFLAG_R(0); + desc.regin[1] |= REGFLAG_SR; + desc.regout[1] |= REGFLAG_SR; + return true; + + case 9<<8: // ANDI(opcode & 0xff); + case 10<<8: // XORI(opcode & 0xff); + case 11<<8: // ORI(opcode & 0xff); + desc.regin[0] |= REGFLAG_R(0); + desc.regout[0] |= REGFLAG_R(0); + return true; + + case 12<<8: // TSTM(opcode & 0xff); + case 13<<8: // ANDM(opcode & 0xff); + case 14<<8: // XORM(opcode & 0xff); + case 15<<8: // ORM(opcode & 0xff); + desc.regin[0] |= REGFLAG_R(0); + desc.regin[1] |= REGFLAG_SR | REGFLAG_GBR; + desc.regout[1] |= REGFLAG_SR; + desc.flags |= OPFLAG_READS_MEMORY; + return true; + } + + return false; +} + + + +bool sh_frontend::describe_group_0(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) +{ + switch (opcode & 0x3F) + { + case 0x00: // NOP(); + case 0x01: // NOP(); + case 0x09: // NOP(); + case 0x10: // NOP(); + case 0x11: // NOP(); + case 0x13: // NOP(); + case 0x20: // NOP(); + case 0x21: // NOP(); + case 0x30: // NOP(); + case 0x31: // NOP(); + case 0x32: // NOP(); + case 0x33: // NOP(); + case 0x38: // NOP(); + case 0x39: // NOP(); + case 0x3a: // NOP(); + case 0x3b: // NOP(); + return true; + + case 0x02: // STCSR(Rn); + desc.regout[0] |= REGFLAG_R(Rn); + return true; + + case 0x03: // BSRF(Rn); + desc.regout[1] |= REGFLAG_PR; + + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.delayslots = 1; + + return true; + + case 0x04: // MOVBS0(Rm, Rn); + case 0x05: // MOVWS0(Rm, Rn); + case 0x06: // MOVLS0(Rm, Rn); + case 0x14: // MOVBS0(Rm, Rn); + case 0x15: // MOVWS0(Rm, Rn); + case 0x16: // MOVLS0(Rm, Rn); + case 0x24: // MOVBS0(Rm, Rn); + case 0x25: // MOVWS0(Rm, Rn); + case 0x26: // MOVLS0(Rm, Rn); + case 0x34: // MOVBS0(Rm, Rn); + case 0x35: // MOVWS0(Rm, Rn); + case 0x36: // MOVLS0(Rm, Rn); + desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn) | REGFLAG_R(0); + desc.flags |= OPFLAG_READS_MEMORY; + return true; + + case 0x07: // MULL(Rm, Rn); + case 0x17: // MULL(Rm, Rn); + case 0x27: // MULL(Rm, Rn); + case 0x37: // MULL(Rm, Rn); + desc.regin[0] |= REGFLAG_R(Rn) | REGFLAG_R(Rm); + desc.regout[1] |= REGFLAG_MACL; + desc.cycles = 2; + return true; + + case 0x08: // CLRT(); + desc.regout[1] |= REGFLAG_SR; + return true; + + case 0x0a: // STSMACH(Rn); + desc.regout[0] |= REGFLAG_R(Rn); + desc.regout[1] |= REGFLAG_MACH; + return true; + + case 0x0b: // RTS(); + desc.regin[1] |= REGFLAG_PR; + + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.delayslots = 1; + desc.cycles = 2; + + return true; + + case 0x0c: // MOVBL0(Rm, Rn); + case 0x0d: // MOVWL0(Rm, Rn); + case 0x0e: // MOVLL0(Rm, Rn); + case 0x1c: // MOVBL0(Rm, Rn); + case 0x1d: // MOVWL0(Rm, Rn); + case 0x1e: // MOVLL0(Rm, Rn); + case 0x2c: // MOVBL0(Rm, Rn); + case 0x2d: // MOVWL0(Rm, Rn); + case 0x2e: // MOVLL0(Rm, Rn); + case 0x3c: // MOVBL0(Rm, Rn); + case 0x3d: // MOVWL0(Rm, Rn); + case 0x3e: // MOVLL0(Rm, Rn); + desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(0); + desc.regout[0] |= REGFLAG_R(Rn); + desc.flags |= OPFLAG_READS_MEMORY; + return true; + + case 0x0f: // MAC_L(Rm, Rn); + case 0x1f: // MAC_L(Rm, Rn); + case 0x2f: // MAC_L(Rm, Rn); + case 0x3f: // MAC_L(Rm, Rn); + desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn); + desc.regout[1] |= REGFLAG_MACL | REGFLAG_MACH; + desc.cycles = 3; + return true; + + case 0x12: // STCGBR(Rn); + desc.regout[0] |= REGFLAG_R(Rn); + desc.regin[1] |= REGFLAG_GBR; + return true; + + case 0x18: // SETT(); + desc.regout[1] |= REGFLAG_SR; + return true; + + case 0x19: // DIV0U(); + desc.regout[1] |= REGFLAG_SR; + return true; + + case 0x1a: // STSMACL(Rn); + desc.regin[1] |= REGFLAG_MACL; + desc.regout[0] |= REGFLAG_R(Rn); + return true; + + case 0x1b: // SLEEP(); + desc.cycles = 3; + return true; + + case 0x22: // STCVBR(Rn); + desc.regin[0] |= REGFLAG_R(Rn); + desc.regout[1] |= REGFLAG_VBR; + return true; + + case 0x23: // BRAF(Rn); + desc.regin[0] |= REGFLAG_R(Rm); + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.delayslots = 1; + desc.cycles = 2; + return true; + + case 0x28: // CLRMAC(); + desc.regout[1] |= REGFLAG_MACL | REGFLAG_MACH; + return true; + + case 0x29: // MOVT(Rn); + desc.regin[1] |= REGFLAG_SR; + desc.regout[0] |= REGFLAG_R(Rn); + return true; + + case 0x2a: // STSPR(Rn); + desc.regin[1] |= REGFLAG_PR; + desc.regout[0] |= REGFLAG_R(Rn); + return true; + + case 0x2b: // RTE(); + desc.regin[0] |= REGFLAG_R(15); + desc.regout[0] |= REGFLAG_R(15); + + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE | OPFLAG_CAN_EXPOSE_EXTERNAL_INT; + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.delayslots = 1; + desc.cycles = 4; + + return true; + } + + return false; +} + + +bool sh_frontend::describe_group_4(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) +{ + switch (opcode & 0x3F) + { + case 0x00: // SHLL(Rn); + case 0x01: // SHLR(Rn); + case 0x04: // ROTL(Rn); + case 0x05: // ROTR(Rn); + desc.regin[0] |= REGFLAG_R(Rn); + desc.regout[0] |= REGFLAG_R(Rn); + desc.regout[1] |= REGFLAG_SR; + return true; + + case 0x02: // STSMMACH(Rn); + desc.regin[0] |= REGFLAG_R(Rn); + desc.regin[1] |= REGFLAG_MACH; + desc.regout[0] |= REGFLAG_R(Rn); + desc.flags |= OPFLAG_WRITES_MEMORY; + return true; + + case 0x03: // STCMSR(Rn); + desc.regin[0] |= REGFLAG_R(Rn); + desc.regout[0] |= REGFLAG_R(Rn); + desc.cycles = 2; + desc.flags |= OPFLAG_WRITES_MEMORY; + return true; + + case 0x06: // LDSMMACH(Rn); + desc.regin[0] |= REGFLAG_R(Rn); + desc.regout[0] |= REGFLAG_R(Rn); + desc.regout[1] |= REGFLAG_MACH; + desc.flags |= OPFLAG_READS_MEMORY; + return true; + + case 0x07: // LDCMSR(Rn); + desc.regin[0] |= REGFLAG_R(Rn); + desc.regout[0] |= REGFLAG_R(Rn); + desc.regout[1] |= REGFLAG_SR; + desc.cycles = 3; + desc.flags |= OPFLAG_READS_MEMORY | OPFLAG_CAN_EXPOSE_EXTERNAL_INT | OPFLAG_END_SEQUENCE; + return true; + + case 0x08: // SHLL2(Rn); + case 0x09: // SHLR2(Rn); + case 0x18: // SHLL8(Rn); + case 0x19: // SHLR8(Rn); + case 0x28: // SHLL16(Rn); + case 0x29: // SHLR16(Rn); + desc.regin[0] |= REGFLAG_R(Rn); + desc.regout[0] |= REGFLAG_R(Rn); + return true; + + case 0x0a: // LDSMACH(Rn); + desc.regin[0] |= REGFLAG_R(Rn); + desc.regout[1] |= REGFLAG_MACH; + return true; + + case 0x0b: // JSR(Rn); + desc.regin[0] |= REGFLAG_R(Rn); + desc.regout[1] |= REGFLAG_PR; + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.delayslots = 1; + return true; + + case 0x0e: // LDCSR(Rn); + desc.regin[0] |= REGFLAG_R(Rn); + desc.regout[1] |= REGFLAG_SR; + desc.flags |= OPFLAG_CAN_EXPOSE_EXTERNAL_INT | OPFLAG_END_SEQUENCE; + return true; + + case 0x0f: // MAC_W(Rm, Rn); + case 0x1f: // MAC_W(Rm, Rn); + case 0x2f: // MAC_W(Rm, Rn); + case 0x3f: // MAC_W(Rm, Rn); + desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn); + desc.regin[1] |= REGFLAG_MACL | REGFLAG_MACH; + desc.regout[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn); + desc.regout[1] |= REGFLAG_MACL | REGFLAG_MACH; + desc.cycles = 3; + return true; + + case 0x10: // DT(Rn); + desc.regin[0] |= REGFLAG_R(Rn); + desc.regin[1] |= REGFLAG_SR; + desc.regout[0] |= REGFLAG_R(Rn); + desc.regout[1] |= REGFLAG_SR; + return true; + + case 0x11: // CMPPZ(Rn); + case 0x15: // CMPPL(Rn); + desc.regin[0] |= REGFLAG_R(Rn); + desc.regin[1] |= REGFLAG_SR; + desc.regout[1] |= REGFLAG_SR; + return true; + + case 0x12: // STSMMACL(Rn); + desc.regin[0] |= REGFLAG_R(Rn); + desc.regin[1] |= REGFLAG_MACL; + desc.regout[0] |= REGFLAG_R(Rn); + desc.flags |= OPFLAG_WRITES_MEMORY; + return true; + + case 0x13: // STCMGBR(Rn); + desc.regin[0] |= REGFLAG_R(Rn); + desc.regin[1] |= REGFLAG_GBR; + desc.regout[0] |= REGFLAG_R(Rn); + desc.flags |= OPFLAG_WRITES_MEMORY; + return true; + + case 0x16: // LDSMMACL(Rn); + desc.regin[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn); + desc.regout[0] |= REGFLAG_R(Rm) | REGFLAG_R(Rn); + desc.regout[1] |= REGFLAG_MACL; + desc.flags |= OPFLAG_READS_MEMORY; + return true; + + case 0x17: // LDCMGBR(Rn); + desc.regin[0] |= REGFLAG_R(Rn); + desc.regout[0] |= REGFLAG_R(Rn); + desc.regout[1] |= REGFLAG_GBR; + desc.flags |= OPFLAG_READS_MEMORY; + return true; + + case 0x1a: // LDSMACL(Rn); + desc.regin[0] |= REGFLAG_R(Rn); + desc.regout[1] |= REGFLAG_MACL; + return true; + + case 0x1b: // TAS(Rn); + desc.regin[0] |= REGFLAG_R(Rn); + desc.regin[1] |= REGFLAG_SR; + desc.regout[1] |= REGFLAG_SR; + desc.cycles = 4; + desc.flags |= OPFLAG_READS_MEMORY | OPFLAG_WRITES_MEMORY; + return true; + + case 0x1e: // LDCGBR(Rn); + desc.regin[0] |= REGFLAG_R(Rn); + desc.regout[1] |= REGFLAG_GBR; + return true; + + case 0x20: // SHAL(Rn); + case 0x21: // SHAR(Rn); + desc.regin[0] |= REGFLAG_R(Rn); + desc.regout[0] |= REGFLAG_R(Rn); + desc.regout[1] |= REGFLAG_SR; + return true; + + case 0x22: // STSMPR(Rn); + desc.regin[0] |= REGFLAG_R(Rn); + desc.regin[1] |= REGFLAG_PR; + desc.regout[0] |= REGFLAG_R(Rn); + desc.flags |= OPFLAG_WRITES_MEMORY; + return true; + + case 0x23: // STCMVBR(Rn); + desc.regin[0] |= REGFLAG_R(Rn); + desc.regin[1] |= REGFLAG_VBR; + desc.regout[0] |= REGFLAG_R(Rn); + desc.flags |= OPFLAG_WRITES_MEMORY; + return true; + + case 0x24: // ROTCL(Rn); + case 0x25: // ROTCR(Rn); + desc.regin[0] |= REGFLAG_R(Rn); + desc.regin[1] |= REGFLAG_SR; + desc.regout[0] |= REGFLAG_R(Rn); + desc.regout[1] |= REGFLAG_SR; + return true; + + case 0x26: // LDSMPR(Rn); + desc.regin[0] |= REGFLAG_R(Rn); + desc.regout[0] |= REGFLAG_R(Rn); + desc.regout[1] |= REGFLAG_PR; + desc.flags |= OPFLAG_READS_MEMORY; + return true; + + case 0x27: // LDCMVBR(Rn); + desc.regin[0] |= REGFLAG_R(Rn); + desc.regout[0] |= REGFLAG_R(Rn); + desc.regout[1] |= REGFLAG_VBR; + desc.flags |= OPFLAG_READS_MEMORY; + return true; + + case 0x2a: // LDSPR(Rn); + desc.regin[0] |= REGFLAG_R(Rn); + desc.regout[1] |= REGFLAG_PR; + return true; + + case 0x2b: // JMP(Rm); + desc.regin[0] |= REGFLAG_R(Rm); + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.delayslots = 1; + return true; + + case 0x2e: // LDCVBR(Rn); + desc.regin[0] |= REGFLAG_R(Rn); + desc.regout[1] |= REGFLAG_VBR; + return true; + + case 0x0c: // NOP(); + case 0x0d: // NOP(); + case 0x14: // NOP(); + case 0x1c: // NOP(); + case 0x1d: // NOP(); + case 0x2c: // NOP(); + case 0x2d: // NOP(); + case 0x30: // NOP(); + case 0x31: // NOP(); + case 0x32: // NOP(); + case 0x33: // NOP(); + case 0x34: // NOP(); + case 0x35: // NOP(); + case 0x36: // NOP(); + case 0x37: // NOP(); + case 0x38: // NOP(); + case 0x39: // NOP(); + case 0x3a: // NOP(); + case 0x3b: // NOP(); + case 0x3c: // NOP(); + case 0x3d: // NOP(); + case 0x3e: // NOP(); + return true; + } + + return false; +} diff --git a/src/devices/cpu/sharc/sharc.cpp b/src/devices/cpu/sharc/sharc.cpp index b8f3b104eb0..c85a915a2f7 100644 --- a/src/devices/cpu/sharc/sharc.cpp +++ b/src/devices/cpu/sharc/sharc.cpp @@ -8,6 +8,7 @@ #include "emu.h" #include "sharc.h" #include "sharcfe.h" +#include "sharcdsm.h" #include "debugger.h" @@ -96,10 +97,9 @@ device_memory_interface::space_config_vector adsp21062_device::memory_space_conf }; } -offs_t adsp21062_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *adsp21062_device::create_disassembler() { - extern CPU_DISASSEMBLE( sharc ); - return CPU_DISASSEMBLE_NAME(sharc)(this, stream, pc, oprom, opram, options); + return new sharc_disassembler; } void adsp21062_device::enable_recompiler() @@ -400,7 +400,7 @@ void adsp21062_device::external_iop_write(uint32_t address, uint32_t data) else { osd_printf_debug("SHARC IOP write %08X, %08X\n", address, data); - m_data->write_dword(address << 2, data); + m_data->write_dword(address, data); } } @@ -1031,7 +1031,7 @@ void adsp21062_device::execute_run() debugger_instruction_hook(this, m_core->pc); - m_core->opcode = m_program->read_qword(m_core->pc << 3); + m_core->opcode = m_program->read_qword(m_core->pc); // handle looping if (m_core->pc == m_core->laddr.addr) diff --git a/src/devices/cpu/sharc/sharc.h b/src/devices/cpu/sharc/sharc.h index 806b3053ee4..d4a56e1d525 100644 --- a/src/devices/cpu/sharc/sharc.h +++ b/src/devices/cpu/sharc/sharc.h @@ -220,10 +220,7 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - static constexpr uint32_t OPCODE_BYTES = 8; // actually 6, but emulation requires padding to 64 bits - virtual uint32_t disasm_min_opcode_bytes() const override { return OPCODE_BYTES; } - virtual uint32_t disasm_max_opcode_bytes() const override { return OPCODE_BYTES; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: struct alignas(16) SHARC_DAG diff --git a/src/devices/cpu/sharc/sharcdrc.cpp b/src/devices/cpu/sharc/sharcdrc.cpp index b8ab1a1f975..c21a1c2e997 100644 --- a/src/devices/cpu/sharc/sharcdrc.cpp +++ b/src/devices/cpu/sharc/sharcdrc.cpp @@ -307,34 +307,28 @@ void adsp21062_device::static_generate_memory_accessor(MEM_ACCESSOR_TYPE type, c switch (type) { case MEM_ACCESSOR_PM_READ48: - UML_SHL(block, I1, I1, 3); UML_DREAD(block, I0, I1, SIZE_QWORD, SPACE_PROGRAM); break; case MEM_ACCESSOR_PM_WRITE48: - UML_SHL(block, I1, I1, 3); UML_DWRITE(block, I1, I0, SIZE_QWORD, SPACE_PROGRAM); UML_MOV(block, mem(&m_core->force_recompile), 1); break; case MEM_ACCESSOR_PM_READ32: - UML_SHL(block, I1, I1, 3); UML_READ(block, I0, I1, SIZE_DWORD, SPACE_PROGRAM); break; case MEM_ACCESSOR_PM_WRITE32: - UML_SHL(block, I1, I1, 3); UML_WRITE(block, I1, I0, SIZE_DWORD, SPACE_PROGRAM); UML_MOV(block, mem(&m_core->force_recompile), 1); break; case MEM_ACCESSOR_DM_READ32: - UML_SHL(block, I1, I1, 2); UML_READ(block, I0, I1, SIZE_DWORD, SPACE_DATA); break; case MEM_ACCESSOR_DM_WRITE32: - UML_SHL(block, I1, I1, 2); UML_WRITE(block, I1, I0, SIZE_DWORD, SPACE_DATA); break; } diff --git a/src/devices/cpu/sharc/sharcdsm.cpp b/src/devices/cpu/sharc/sharcdsm.cpp index 7d570c13e87..ebab8add599 100644 --- a/src/devices/cpu/sharc/sharcdsm.cpp +++ b/src/devices/cpu/sharc/sharcdsm.cpp @@ -9,8 +9,76 @@ #include "emu.h" #include "sharcdsm.h" -static uint32_t (* sharcdasm_table[256])(uint32_t, uint64_t); -static int dasm_table_built = 0; +const char sharc_disassembler::ureg_names[256][16] = +{ + "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", + "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15", + "I0", "I1", "I2", "I3", "I4", "I5", "I6", "I7", + "I8", "I9", "I10", "I11", "I12", "I13", "I14", "I15", + "M0", "M1", "M2", "M3", "M4", "M5", "M6", "M7", + "M8", "M9", "M10", "M11", "M12", "M13", "M14", "M15", + "L0", "L1", "L2", "L3", "L4", "L5", "L6", "L7", + "L8", "L9", "L10", "L11", "L12", "L13", "L14", "L15", + "B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", + "B8", "B9", "B10", "B11", "B12", "B13", "B14", "B15", + "???", "???", "???", "???", "???", "???", "???", "???", + "???", "???", "???", "???", "???", "???", "???", "???", + "FADDR", "DADDR", "???", "PC", "PCSTK", "PCSTKP", "LADDR", "CURLCNTR", + "LCNTR", "???", "???", "???", "???", "???", "???", "???", + "USTAT1", "USTAT2", "???", "???", "???", "???", "???", "???", + "???", "IRPTL", "MODE2", "MODE1", "ASTAT", "IMASK", "STKY", "IMASKP", + "???", "???", "???", "???", "???", "???", "???", "???", + "???", "???", "???", "???", "???", "???", "???", "???", + "???", "???", "???", "???", "???", "???", "???", "???", + "???", "???", "???", "???", "???", "???", "???", "???", + "???", "???", "???", "???", "???", "???", "???", "???", + "???", "???", "???", "???", "???", "???", "???", "???", + "???", "???", "???", "???", "???", "???", "???", "???", + "???", "???", "???", "???", "???", "???", "???", "???", + "???", "???", "???", "???", "???", "???", "???", "???", + "???", "???", "???", "???", "???", "???", "???", "???", + "???", "???", "???", "???", "???", "???", "???", "???", + "???", "???", "???", "PX", "PX1", "PX2", "TPERIOD", "TCOUNT", + "???", "???", "???", "???", "???", "???", "???", "???", + "???", "???", "???", "???", "???", "???", "???", "???", + "???", "???", "???", "???", "???", "???", "???", "???", + "???", "???", "???", "???", "???", "???", "???", "???" +}; + +const char sharc_disassembler::bopnames[8][8] = +{ + "SET", "CLEAR", "TOGGLE", "???", "TEST", "XOR", "???", "???" +}; + +const char sharc_disassembler::condition_codes_if[32][32] = +{ + "EQ", "LT", "LE", "AC", + "AV", "MV", "MS", "SV", + "SZ", "FLAG0_IN", "FLAG1_IN", "FLAG2_IN", + "FLAG3_IN", "TF", "BM", "NOT LCE", + "NE", "GE", "GT", "NOT AC", + "NOT AV", "NOT MV", "NOT MS", "NOT SV", + "NOT SZ", "NOT FLAG0_IN", "NOT FLAG1_IN", "NOT FLAG2_IN", + "NOT FLAG3_IN", "NOT TF", "NBM", "" +}; + +const char sharc_disassembler::condition_codes_do[32][32] = +{ + "EQ", "LT", "LE", "AC", + "AV", "MV", "MS", "SV", + "SZ", "FLAG0_IN", "FLAG1_IN", "FLAG2_IN", + "FLAG3_IN", "TF", "BM", "LCE", + "NE", "GE", "GT", "NOT AC", + "NOT AV", "NOT MV", "NOT MS", "NOT SV", + "NOT SZ", "NOT FLAG0_IN", "NOT FLAG1_IN", "NOT FLAG2_IN", + "NOT FLAG3_IN", "NOT TF", "NBM", "FOREVER" +}; + +const char sharc_disassembler::mr_regnames[16][8] = +{ + "MR0F", "MR1F", "MR2F", "MR0B", "MR1B", "MR2B", "???", "???", + "???", "???", "???", "???", "???", "???", "???", "???" +}; #define GET_UREG(x) (ureg_names[x]) #define GET_SREG(x) (GET_UREG(0x70 | (x & 0xf))) @@ -28,19 +96,7 @@ static int dasm_table_built = 0; #define SIGN_EXTEND24(x) ((x & 0x800000) ? (0xff000000 | x) : x) -static char *output; -static void ATTR_PRINTF(1,2) print(const char *fmt, ...) -{ - va_list vl; - - va_start(vl, fmt); - output += vsprintf(output, fmt, vl); - va_end(vl); -} - - - -static void compute(uint32_t opcode) +void sharc_disassembler::compute(std::ostream &stream, uint32_t opcode) { int op = (opcode >> 12) & 0xff; int cu = (opcode >> 20) & 0x3; @@ -61,41 +117,41 @@ static void compute(uint32_t opcode) switch(multiop) { - case 0x04: print("R%d = R%d * R%d (SSFR), R%d = R%d + R%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x05: print("R%d = R%d * R%d (SSFR), R%d = R%d - R%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x06: print("R%d = R%d * R%d (SSFR), R%d = (R%d + R%d)/2", rm, rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x08: print("MRF = MRF + R%d * R%d (SSF), R%d = R%d + R%d", rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x09: print("MRF = MRF + R%d * R%d (SSF), R%d = R%d - R%d", rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x0a: print("MRF = MRF + R%d * R%d (SSF), R%d = (R%d + R%d)/2", rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x0c: print("R%d = MRF + R%d * R%d (SSFR), R%d = R%d + R%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x0d: print("R%d = MRF + R%d * R%d (SSFR), R%d = R%d - R%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x0e: print("R%d = MRF + R%d * R%d (SSFR), R%d = (R%d + R%d)/2", rm, rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x10: print("MRF = MRF - R%d * R%d (SSF), R%d = R%d + R%d", rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x11: print("MRF = MRF - R%d * R%d (SSF), R%d = R%d - R%d", rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x12: print("MRF = MRF - R%d * R%d (SSF), R%d = (R%d + R%d)/2", rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x14: print("R%d = MRF - R%d * R%d (SSFR), R%d = R%d + R%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x15: print("R%d = MRF - R%d * R%d (SSFR), R%d = R%d - R%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x16: print("R%d = MRF - R%d * R%d (SSFR), R%d = (R%d + R%d)/2", rm, rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x18: print("F%d = F%d * F%d, F%d = F%d + F%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x19: print("F%d = F%d * F%d, F%d = F%d - F%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x1a: print("F%d = F%d * F%d, F%d = FLOAT F%d BY F%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x1b: print("F%d = F%d * F%d, F%d = FIX F%d BY F%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x1c: print("F%d = F%d * F%d, F%d = (F%d + F%d)/2", rm, rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x1d: print("F%d = F%d * F%d, F%d = ABS F%d", rm, rxm, rym+4, ra, rxa+8); break; - case 0x1e: print("F%d = F%d * F%d, F%d = MAX(F%d, F%d)", rm, rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x1f: print("F%d = F%d * F%d, F%d = MIN(F%d, F%d)", rm, rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x04: util::stream_format(stream, "R%d = R%d * R%d (SSFR), R%d = R%d + R%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x05: util::stream_format(stream, "R%d = R%d * R%d (SSFR), R%d = R%d - R%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x06: util::stream_format(stream, "R%d = R%d * R%d (SSFR), R%d = (R%d + R%d)/2", rm, rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x08: util::stream_format(stream, "MRF = MRF + R%d * R%d (SSF), R%d = R%d + R%d", rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x09: util::stream_format(stream, "MRF = MRF + R%d * R%d (SSF), R%d = R%d - R%d", rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x0a: util::stream_format(stream, "MRF = MRF + R%d * R%d (SSF), R%d = (R%d + R%d)/2", rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x0c: util::stream_format(stream, "R%d = MRF + R%d * R%d (SSFR), R%d = R%d + R%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x0d: util::stream_format(stream, "R%d = MRF + R%d * R%d (SSFR), R%d = R%d - R%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x0e: util::stream_format(stream, "R%d = MRF + R%d * R%d (SSFR), R%d = (R%d + R%d)/2", rm, rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x10: util::stream_format(stream, "MRF = MRF - R%d * R%d (SSF), R%d = R%d + R%d", rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x11: util::stream_format(stream, "MRF = MRF - R%d * R%d (SSF), R%d = R%d - R%d", rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x12: util::stream_format(stream, "MRF = MRF - R%d * R%d (SSF), R%d = (R%d + R%d)/2", rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x14: util::stream_format(stream, "R%d = MRF - R%d * R%d (SSFR), R%d = R%d + R%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x15: util::stream_format(stream, "R%d = MRF - R%d * R%d (SSFR), R%d = R%d - R%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x16: util::stream_format(stream, "R%d = MRF - R%d * R%d (SSFR), R%d = (R%d + R%d)/2", rm, rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x18: util::stream_format(stream, "F%d = F%d * F%d, F%d = F%d + F%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x19: util::stream_format(stream, "F%d = F%d * F%d, F%d = F%d - F%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x1a: util::stream_format(stream, "F%d = F%d * F%d, F%d = FLOAT F%d BY F%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x1b: util::stream_format(stream, "F%d = F%d * F%d, F%d = FIX F%d BY F%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x1c: util::stream_format(stream, "F%d = F%d * F%d, F%d = (F%d + F%d)/2", rm, rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x1d: util::stream_format(stream, "F%d = F%d * F%d, F%d = ABS F%d", rm, rxm, rym+4, ra, rxa+8); break; + case 0x1e: util::stream_format(stream, "F%d = F%d * F%d, F%d = MAX(F%d, F%d)", rm, rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x1f: util::stream_format(stream, "F%d = F%d * F%d, F%d = MIN(F%d, F%d)", rm, rxm, rym+4, ra, rxa+8, rya+12); break; case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f: { - print("R%d = R%d * R%d (SSFR), R%d = R%d + R%d, R%d = R%d - R%d", rm, rxm, rym+4, ra, rxa+8, rya+12, (opcode >> 16) & 0xf, rxa+8, rya+12); + util::stream_format(stream, "R%d = R%d * R%d (SSFR), R%d = R%d + R%d, R%d = R%d - R%d", rm, rxm, rym+4, ra, rxa+8, rya+12, (opcode >> 16) & 0xf, rxa+8, rya+12); break; } case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f: { - print("F%d = F%d * F%d, F%d = F%d + F%d, F%d = F%d - F%d", rm, rxm, rym+4, ra, rxa+8, rya+12, (opcode >> 16) & 0xf, rxa+8, rya+12); + util::stream_format(stream, "F%d = F%d * F%d, F%d = F%d + F%d, F%d = F%d - F%d", rm, rxm, rym+4, ra, rxa+8, rya+12, (opcode >> 16) & 0xf, rxa+8, rya+12); break; } @@ -103,20 +159,20 @@ static void compute(uint32_t opcode) { int rk = (opcode >> 8) & 0xf; int ai = (opcode >> 12) & 0xf; - print("R%d = %s", rk, mr_regnames[ai]); + util::stream_format(stream, "R%d = %s", rk, mr_regnames[ai]); break; } case 0x01: { int rk = (opcode >> 8) & 0xf; int ai = (opcode >> 12) & 0xf; - print("%s = R%d", mr_regnames[ai], rk); + util::stream_format(stream, "%s = R%d", mr_regnames[ai], rk); break; } default: { - print("??? (COMPUTE, MULTIOP)"); + util::stream_format(stream, "??? (COMPUTE, MULTIOP)"); break; } } @@ -133,68 +189,68 @@ static void compute(uint32_t opcode) switch(op) { /* Fixed-point */ - case 0x01: print("R%d = R%d + R%d", rn, rx, ry); break; - case 0x02: print("R%d = R%d - R%d", rn, rx, ry); break; - case 0x05: print("R%d = R%d + R%d + CI", rn, rx, ry); break; - case 0x06: print("R%d = R%d - R%d + CI - 1", rn, rx, ry); break; - case 0x09: print("R%d = (R%d + R%d)/2", rn, rx, ry); break; - case 0x0a: print("COMP(R%d, R%d)", rx, ry); break; - case 0x25: print("R%d = R%d + CI", rn, rx); break; - case 0x26: print("R%d = R%d + CI - 1", rn, rx); break; - case 0x29: print("R%d = R%d + 1", rn, rx); break; - case 0x2a: print("R%d = R%d - 1", rn, rx); break; - case 0x22: print("R%d = -R%d", rn, rx); break; - case 0x30: print("R%d = ABS R%d", rn, rx); break; - case 0x21: print("R%d = PASS R%d", rn, rx); break; - case 0x40: print("R%d = R%d AND R%d", rn, rx, ry); break; - case 0x41: print("R%d = R%d OR R%d", rn, rx, ry); break; - case 0x42: print("R%d = R%d XOR R%d", rn, rx, ry); break; - case 0x43: print("R%d = NOT R%d", rn, rx); break; - case 0x61: print("R%d = MIN(R%d, R%d)", rn, rx, ry); break; - case 0x62: print("R%d = MAX(R%d, R%d)", rn, rx, ry); break; - case 0x63: print("R%d = CLIP R%d BY R%d", rn, rx, ry); break; + case 0x01: util::stream_format(stream, "R%d = R%d + R%d", rn, rx, ry); break; + case 0x02: util::stream_format(stream, "R%d = R%d - R%d", rn, rx, ry); break; + case 0x05: util::stream_format(stream, "R%d = R%d + R%d + CI", rn, rx, ry); break; + case 0x06: util::stream_format(stream, "R%d = R%d - R%d + CI - 1", rn, rx, ry); break; + case 0x09: util::stream_format(stream, "R%d = (R%d + R%d)/2", rn, rx, ry); break; + case 0x0a: util::stream_format(stream, "COMP(R%d, R%d)", rx, ry); break; + case 0x25: util::stream_format(stream, "R%d = R%d + CI", rn, rx); break; + case 0x26: util::stream_format(stream, "R%d = R%d + CI - 1", rn, rx); break; + case 0x29: util::stream_format(stream, "R%d = R%d + 1", rn, rx); break; + case 0x2a: util::stream_format(stream, "R%d = R%d - 1", rn, rx); break; + case 0x22: util::stream_format(stream, "R%d = -R%d", rn, rx); break; + case 0x30: util::stream_format(stream, "R%d = ABS R%d", rn, rx); break; + case 0x21: util::stream_format(stream, "R%d = PASS R%d", rn, rx); break; + case 0x40: util::stream_format(stream, "R%d = R%d AND R%d", rn, rx, ry); break; + case 0x41: util::stream_format(stream, "R%d = R%d OR R%d", rn, rx, ry); break; + case 0x42: util::stream_format(stream, "R%d = R%d XOR R%d", rn, rx, ry); break; + case 0x43: util::stream_format(stream, "R%d = NOT R%d", rn, rx); break; + case 0x61: util::stream_format(stream, "R%d = MIN(R%d, R%d)", rn, rx, ry); break; + case 0x62: util::stream_format(stream, "R%d = MAX(R%d, R%d)", rn, rx, ry); break; + case 0x63: util::stream_format(stream, "R%d = CLIP R%d BY R%d", rn, rx, ry); break; /* Floating-point */ - case 0x81: print("F%d = F%d + F%d", rn, rx, ry); break; - case 0x82: print("F%d = F%d - F%d", rn, rx, ry); break; - case 0x91: print("F%d = ABS(F%d + F%d)", rn, rx, ry); break; - case 0x92: print("F%d = ABS(F%d - F%d)", rn, rx, ry); break; - case 0x89: print("F%d = (F%d + F%d)/2", rn, rx, ry); break; - case 0x8a: print("COMP(F%d, F%d)", rx, ry); break; - case 0xa2: print("F%d = -F%d", rn, rx); break; - case 0xb0: print("F%d = ABS F%d", rn, rx); break; - case 0xa1: print("F%d = PASS F%d", rn, rx); break; - case 0xa5: print("F%d = RND R%d", rn, rx); break; - case 0xbd: print("F%d = SCALB F%d BY R%d", rn, rx, ry); break; - case 0xad: print("R%d = MANT F%d", rn, rx); break; - case 0xc1: print("R%d = LOGB F%d", rn, rx); break; - case 0xd9: print("R%d = FIX F%d BY R%d", rn, rx, ry); break; - case 0xc9: print("R%d = FIX F%d", rn, rx); break; - case 0xdd: print("R%d = TRUNC F%d BY R%d", rn, rx, ry); break; - case 0xcd: print("R%d = TRUNC F%d", rn, rx); break; - case 0xda: print("F%d = FLOAT R%d BY R%d", rn, rx, ry); break; - case 0xca: print("F%d = FLOAT R%d", rn, rx); break; - case 0xc4: print("F%d = RECIPS F%d", rn, rx); break; - case 0xc5: print("F%d = RSQRTS F%d", rn, rx); break; - case 0xe0: print("F%d = F%d COPYSIGN F%d", rn, rx, ry); break; - case 0xe1: print("F%d = MIN(F%d, F%d)", rn, rx, ry); break; - case 0xe2: print("F%d = MAX(F%d, F%d)", rn, rx, ry); break; - case 0xe3: print("F%d = CLIP F%d BY F%d", rn, rx, ry); break; + case 0x81: util::stream_format(stream, "F%d = F%d + F%d", rn, rx, ry); break; + case 0x82: util::stream_format(stream, "F%d = F%d - F%d", rn, rx, ry); break; + case 0x91: util::stream_format(stream, "F%d = ABS(F%d + F%d)", rn, rx, ry); break; + case 0x92: util::stream_format(stream, "F%d = ABS(F%d - F%d)", rn, rx, ry); break; + case 0x89: util::stream_format(stream, "F%d = (F%d + F%d)/2", rn, rx, ry); break; + case 0x8a: util::stream_format(stream, "COMP(F%d, F%d)", rx, ry); break; + case 0xa2: util::stream_format(stream, "F%d = -F%d", rn, rx); break; + case 0xb0: util::stream_format(stream, "F%d = ABS F%d", rn, rx); break; + case 0xa1: util::stream_format(stream, "F%d = PASS F%d", rn, rx); break; + case 0xa5: util::stream_format(stream, "F%d = RND R%d", rn, rx); break; + case 0xbd: util::stream_format(stream, "F%d = SCALB F%d BY R%d", rn, rx, ry); break; + case 0xad: util::stream_format(stream, "R%d = MANT F%d", rn, rx); break; + case 0xc1: util::stream_format(stream, "R%d = LOGB F%d", rn, rx); break; + case 0xd9: util::stream_format(stream, "R%d = FIX F%d BY R%d", rn, rx, ry); break; + case 0xc9: util::stream_format(stream, "R%d = FIX F%d", rn, rx); break; + case 0xdd: util::stream_format(stream, "R%d = TRUNC F%d BY R%d", rn, rx, ry); break; + case 0xcd: util::stream_format(stream, "R%d = TRUNC F%d", rn, rx); break; + case 0xda: util::stream_format(stream, "F%d = FLOAT R%d BY R%d", rn, rx, ry); break; + case 0xca: util::stream_format(stream, "F%d = FLOAT R%d", rn, rx); break; + case 0xc4: util::stream_format(stream, "F%d = RECIPS F%d", rn, rx); break; + case 0xc5: util::stream_format(stream, "F%d = RSQRTS F%d", rn, rx); break; + case 0xe0: util::stream_format(stream, "F%d = F%d COPYSIGN F%d", rn, rx, ry); break; + case 0xe1: util::stream_format(stream, "F%d = MIN(F%d, F%d)", rn, rx, ry); break; + case 0xe2: util::stream_format(stream, "F%d = MAX(F%d, F%d)", rn, rx, ry); break; + case 0xe3: util::stream_format(stream, "F%d = CLIP F%d BY F%d", rn, rx, ry); break; case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77: case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f: { - print("R%d = R%d + R%d, R%d = R%d - R%d", ra, rx, ry, rs, rx, ry); + util::stream_format(stream, "R%d = R%d + R%d, R%d = R%d - R%d", ra, rx, ry, rs, rx, ry); break; } case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff: { - print("F%d = F%d + F%d, F%d = F%d - F%d", ra, rx, ry, rs, rx, ry); + util::stream_format(stream, "F%d = F%d + F%d, F%d = F%d - F%d", ra, rx, ry, rs, rx, ry); break; } default: { - print("??? (COMPUTE, ALU)"); + util::stream_format(stream, "??? (COMPUTE, ALU)"); break; } } @@ -207,44 +263,44 @@ static void compute(uint32_t opcode) case 1: { if( op == 0x30 ) { - print("F%d = F%d * F%d", rn, rx, ry); + util::stream_format(stream, "F%d = F%d * F%d", rn, rx, ry); return; } switch((op >> 1) & 0x3) { case 0: - case 1: print("R%d = ", rn); break; - case 2: print("MRF = "); break; - case 3: print("MRB = "); break; + case 1: util::stream_format(stream, "R%d = ", rn); break; + case 2: util::stream_format(stream, "MRF = "); break; + case 3: util::stream_format(stream, "MRB = "); break; } switch((op >> 6) & 0x3) { case 0: switch((op >> 4) & 0x3) { - case 0: print("SAT %s", (op & 0x2) ? "MRB" : "MRF"); break; + case 0: util::stream_format(stream, "SAT %s", (op & 0x2) ? "MRB" : "MRF"); break; case 1: if (op & 0x8) { - print("RND %s", (op & 0x2) ? "MRB" : "MRF"); + util::stream_format(stream, "RND %s", (op & 0x2) ? "MRB" : "MRF"); } else { - print("0"); + util::stream_format(stream, "0"); } break; } break; case 1: - print("R%d * R%d", rx, ry); break; + util::stream_format(stream, "R%d * R%d", rx, ry); break; case 2: - print("%s +(R%d * R%d)", (op & 0x2) ? "MRB" : "MRF", rx, ry); break; + util::stream_format(stream, "%s +(R%d * R%d)", (op & 0x2) ? "MRB" : "MRF", rx, ry); break; case 3: - print("%s -(R%d * R%d)", (op & 0x2) ? "MRB" : "MRF", rx, ry); break; + util::stream_format(stream, "%s -(R%d * R%d)", (op & 0x2) ? "MRB" : "MRF", rx, ry); break; } break; } @@ -256,50 +312,50 @@ static void compute(uint32_t opcode) { switch(op) { - case 0x00: print("R%d = LSHIFT R%d BY R%d", rn, rx, ry); break; - case 0x20: print("R%d = R%d OR LSHIFT R%d BY R%d", rn, rn, rx, ry); break; - case 0x04: print("R%d = ASHIFT R%d BY R%d", rn, rx, ry); break; - case 0x24: print("R%d = R%d OR ASHIFT R%d BY R%d", rn, rn, rx, ry); break; - case 0x08: print("R%d = ROT R%d BY R%d", rn, rx, ry); break; - case 0xc4: print("R%d = BCLR R%d BY R%d", rn, rx, ry); break; - case 0xc0: print("R%d = BSET R%d BY R%d", rn, rx, ry); break; - case 0xc8: print("R%d = BTGL R%d BY R%d", rn, rx, ry); break; - case 0xcc: print("BTST R%d BY R%d", rx, ry); break; - case 0x44: print("R%d = FDEP R%d BY R%d", rn, rx, ry); break; - case 0x64: print("R%d = R%d OR FDEP R%d BY R%d", rn, rn, rx, ry); break; - case 0x4c: print("R%d = FDEP R%d BY R%d (SE)", rn, rx, ry); break; - case 0x6c: print("R%d = R%d OR FDEP R%d BY R%d (SE)", rn, rn, rx, ry); break; - case 0x40: print("R%d = FEXT R%d BY R%d", rn, rx, ry); break; - case 0x48: print("R%d = FEXT R%d BY R%d (SE)", rn, rx, ry); break; - case 0x80: print("R%d = EXP R%d", rn, rx); break; - case 0x84: print("R%d = EXP R%d (EX)", rn, rx); break; - case 0x88: print("R%d = LEFTZ R%d", rn, rx); break; - case 0x8c: print("R%d = LEFTO R%d", rn, rx); break; - case 0x90: print("R%d = FPACK F%d", rn, rx); break; - case 0x94: print("F%d = FUNPACK R%d", rn, rx); break; - default: print("??? (COMPUTE, SHIFT)"); break; + case 0x00: util::stream_format(stream, "R%d = LSHIFT R%d BY R%d", rn, rx, ry); break; + case 0x20: util::stream_format(stream, "R%d = R%d OR LSHIFT R%d BY R%d", rn, rn, rx, ry); break; + case 0x04: util::stream_format(stream, "R%d = ASHIFT R%d BY R%d", rn, rx, ry); break; + case 0x24: util::stream_format(stream, "R%d = R%d OR ASHIFT R%d BY R%d", rn, rn, rx, ry); break; + case 0x08: util::stream_format(stream, "R%d = ROT R%d BY R%d", rn, rx, ry); break; + case 0xc4: util::stream_format(stream, "R%d = BCLR R%d BY R%d", rn, rx, ry); break; + case 0xc0: util::stream_format(stream, "R%d = BSET R%d BY R%d", rn, rx, ry); break; + case 0xc8: util::stream_format(stream, "R%d = BTGL R%d BY R%d", rn, rx, ry); break; + case 0xcc: util::stream_format(stream, "BTST R%d BY R%d", rx, ry); break; + case 0x44: util::stream_format(stream, "R%d = FDEP R%d BY R%d", rn, rx, ry); break; + case 0x64: util::stream_format(stream, "R%d = R%d OR FDEP R%d BY R%d", rn, rn, rx, ry); break; + case 0x4c: util::stream_format(stream, "R%d = FDEP R%d BY R%d (SE)", rn, rx, ry); break; + case 0x6c: util::stream_format(stream, "R%d = R%d OR FDEP R%d BY R%d (SE)", rn, rn, rx, ry); break; + case 0x40: util::stream_format(stream, "R%d = FEXT R%d BY R%d", rn, rx, ry); break; + case 0x48: util::stream_format(stream, "R%d = FEXT R%d BY R%d (SE)", rn, rx, ry); break; + case 0x80: util::stream_format(stream, "R%d = EXP R%d", rn, rx); break; + case 0x84: util::stream_format(stream, "R%d = EXP R%d (EX)", rn, rx); break; + case 0x88: util::stream_format(stream, "R%d = LEFTZ R%d", rn, rx); break; + case 0x8c: util::stream_format(stream, "R%d = LEFTO R%d", rn, rx); break; + case 0x90: util::stream_format(stream, "R%d = FPACK F%d", rn, rx); break; + case 0x94: util::stream_format(stream, "F%d = FUNPACK R%d", rn, rx); break; + default: util::stream_format(stream, "??? (COMPUTE, SHIFT)"); break; } break; } default: { - print("??? (COMPUTE)"); + util::stream_format(stream, "??? (COMPUTE)"); break; } } } } -static void get_if_condition(int cond) +void sharc_disassembler::get_if_condition(std::ostream &stream, int cond) { if (cond != 31) { - print("IF %s, ", condition_codes_if[cond]); + util::stream_format(stream, "IF %s, ", condition_codes_if[cond]); } } -static void pm_dm_ureg(int g, int d, int i, int m, int ureg, int update) +void sharc_disassembler::pm_dm_ureg(std::ostream &stream, int g, int d, int i, int m, int ureg, int update) { if (update) // post-modify { @@ -307,22 +363,22 @@ static void pm_dm_ureg(int g, int d, int i, int m, int ureg, int update) { if (g) { - print("PM(%s, %s) = %s", GET_DAG2_I(i), GET_DAG2_M(m), GET_UREG(ureg)); + util::stream_format(stream, "PM(%s, %s) = %s", GET_DAG2_I(i), GET_DAG2_M(m), GET_UREG(ureg)); } else { - print("DM(%s, %s) = %s", GET_DAG1_I(i), GET_DAG1_M(m), GET_UREG(ureg)); + util::stream_format(stream, "DM(%s, %s) = %s", GET_DAG1_I(i), GET_DAG1_M(m), GET_UREG(ureg)); } } else { if (g) { - print("%s = PM(%s, %s)", GET_UREG(ureg), GET_DAG2_I(i), GET_DAG2_M(m)); + util::stream_format(stream, "%s = PM(%s, %s)", GET_UREG(ureg), GET_DAG2_I(i), GET_DAG2_M(m)); } else { - print("%s = DM(%s, %s)", GET_UREG(ureg), GET_DAG1_I(i), GET_DAG1_M(m)); + util::stream_format(stream, "%s = DM(%s, %s)", GET_UREG(ureg), GET_DAG1_I(i), GET_DAG1_M(m)); } } @@ -333,28 +389,28 @@ static void pm_dm_ureg(int g, int d, int i, int m, int ureg, int update) { if (g) { - print("PM(%s, %s) = %s", GET_DAG2_M(m), GET_DAG2_I(i), GET_UREG(ureg)); + util::stream_format(stream, "PM(%s, %s) = %s", GET_DAG2_M(m), GET_DAG2_I(i), GET_UREG(ureg)); } else { - print("DM(%s, %s) = %s", GET_DAG1_M(m), GET_DAG1_I(i), GET_UREG(ureg)); + util::stream_format(stream, "DM(%s, %s) = %s", GET_DAG1_M(m), GET_DAG1_I(i), GET_UREG(ureg)); } } else { if (g) { - print("%s = PM(%s, %s)", GET_UREG(ureg), GET_DAG2_M(m), GET_DAG2_I(i)); + util::stream_format(stream, "%s = PM(%s, %s)", GET_UREG(ureg), GET_DAG2_M(m), GET_DAG2_I(i)); } else { - print("%s = DM(%s, %s)", GET_UREG(ureg), GET_DAG1_M(m), GET_DAG1_I(i)); + util::stream_format(stream, "%s = DM(%s, %s)", GET_UREG(ureg), GET_DAG1_M(m), GET_DAG1_I(i)); } } } } -static void pm_dm_imm_dreg(int g, int d, int i, int data, int dreg, int update) +void sharc_disassembler::pm_dm_imm_dreg(std::ostream &stream, int g, int d, int i, int data, int dreg, int update) { const char *sign = ""; if (data & 0x20) @@ -369,22 +425,22 @@ static void pm_dm_imm_dreg(int g, int d, int i, int data, int dreg, int update) { if (g) { - print("PM(%s, %s0x%02X) = %s", GET_DAG2_I(i), sign, data, GET_DREG(dreg)); + util::stream_format(stream, "PM(%s, %s0x%02X) = %s", GET_DAG2_I(i), sign, data, GET_DREG(dreg)); } else { - print("DM(%s, %s0x%02X) = %s", GET_DAG1_I(i), sign, data, GET_DREG(dreg)); + util::stream_format(stream, "DM(%s, %s0x%02X) = %s", GET_DAG1_I(i), sign, data, GET_DREG(dreg)); } } else { if (g) { - print("%s = PM(%s, %s0x%02X)", GET_DREG(dreg), GET_DAG2_I(i), sign, data); + util::stream_format(stream, "%s = PM(%s, %s0x%02X)", GET_DREG(dreg), GET_DAG2_I(i), sign, data); } else { - print("%s = DM(%s, %s0x%02X)", GET_DREG(dreg), GET_DAG1_I(i), sign, data); + util::stream_format(stream, "%s = DM(%s, %s0x%02X)", GET_DREG(dreg), GET_DAG1_I(i), sign, data); } } } @@ -394,54 +450,54 @@ static void pm_dm_imm_dreg(int g, int d, int i, int data, int dreg, int update) { if (g) { - print("PM(%s0x%02X, %s) = %s", sign, data, GET_DAG2_I(i), GET_DREG(dreg)); + util::stream_format(stream, "PM(%s0x%02X, %s) = %s", sign, data, GET_DAG2_I(i), GET_DREG(dreg)); } else { - print("DM(%s0x%02X, %s) = %s", sign, data, GET_DAG1_I(i), GET_DREG(dreg)); + util::stream_format(stream, "DM(%s0x%02X, %s) = %s", sign, data, GET_DAG1_I(i), GET_DREG(dreg)); } } else { if (g) { - print("%s = PM(%s0x%02X, %s)", GET_DREG(dreg), sign, data, GET_DAG2_I(i)); + util::stream_format(stream, "%s = PM(%s0x%02X, %s)", GET_DREG(dreg), sign, data, GET_DAG2_I(i)); } else { - print("%s = DM(%s0x%02X, %s)", GET_DREG(dreg), sign, data, GET_DAG1_I(i)); + util::stream_format(stream, "%s = DM(%s0x%02X, %s)", GET_DREG(dreg), sign, data, GET_DAG1_I(i)); } } } } -static void pm_dm_dreg(int g, int d, int i, int m, int dreg) +void sharc_disassembler::pm_dm_dreg(std::ostream &stream, int g, int d, int i, int m, int dreg) { if (d) { if (g) { - print("PM(%s, %s) = %s", GET_DAG2_I(i), GET_DAG2_M(m), GET_DREG(dreg)); + util::stream_format(stream, "PM(%s, %s) = %s", GET_DAG2_I(i), GET_DAG2_M(m), GET_DREG(dreg)); } else { - print("DM(%s, %s) = %s", GET_DAG1_I(i), GET_DAG1_M(m), GET_DREG(dreg)); + util::stream_format(stream, "DM(%s, %s) = %s", GET_DAG1_I(i), GET_DAG1_M(m), GET_DREG(dreg)); } } else { if (g) { - print("%s = PM(%s, %s)", GET_DREG(dreg), GET_DAG2_I(i), GET_DAG2_M(m)); + util::stream_format(stream, "%s = PM(%s, %s)", GET_DREG(dreg), GET_DAG2_I(i), GET_DAG2_M(m)); } else { - print("%s = DM(%s, %s)", GET_DREG(dreg), GET_DAG1_I(i), GET_DAG1_M(m)); + util::stream_format(stream, "%s = DM(%s, %s)", GET_DREG(dreg), GET_DAG1_I(i), GET_DAG1_M(m)); } } } -static void shiftop(int shift, int data, int rn, int rx) +void sharc_disassembler::shiftop(std::ostream &stream, int shift, int data, int rn, int rx) { int8_t data8 = data & 0xff; int bit6 = data & 0x3f; @@ -449,36 +505,32 @@ static void shiftop(int shift, int data, int rn, int rx) switch(shift) { - case 0x00: print("R%d = LSHIFT R%d BY %d", rn, rx, data8); break; - case 0x08: print("R%d = R%d OR LSHIFT R%d BY %d", rn, rn, rx, data8); break; - case 0x01: print("R%d = ASHIFT R%d BY %d", rn, rx, data8); break; - case 0x09: print("R%d = R%d OR ASHIFT R%d BY %d", rn, rn, rx, data8); break; - case 0x02: print("R%d = ROT R%d BY %d", rn, rx, data8); break; - case 0x31: print("R%d = BCLR R%d BY %d", rn, rx, data8); break; - case 0x30: print("R%d = BSET R%d BY %d", rn, rx, data8); break; - case 0x32: print("R%d = BTGL R%d BY %d", rn, rx, data8); break; - case 0x33: print("BTST R%d BY %d", rx, data8); break; - case 0x11: print("R%d = FDEP R%d BY %d:%d", rn, rx, bit6, len); break; - case 0x19: print("R%d = R%d OR FDEP R%d BY %d:%d", rn, rn, rx, bit6, len); break; - case 0x13: print("R%d = FDEP R%d BY %d:%d (SE)", rn, rx, bit6, len); break; - case 0x1b: print("R%d = R%d OR FDEP R%d BY %d:%d (SE)", rn, rn, rx, bit6, len); break; - case 0x10: print("R%d = FEXT R%d BY %d:%d", rn, rx, bit6, len); break; - case 0x12: print("R%d = FEXT R%d BY %d:%d (SE)", rn, rx, bit6, len); break; - case 0x20: print("R%d = EXP R%d", rn, rx); break; - case 0x21: print("R%d = EXP R%d (EX)", rn, rx); break; - case 0x22: print("R%d = LEFTZ R%d", rn, rx); break; - case 0x23: print("R%d = LEFTO R%d", rn, rx); break; - case 0x24: print("R%d = FPACK F%d", rn, rx); break; - case 0x25: print("F%d = FUNPACK R%d", rn, rx); break; - default: print("??? (SHIFTOP)"); break; + case 0x00: util::stream_format(stream, "R%d = LSHIFT R%d BY %d", rn, rx, data8); break; + case 0x08: util::stream_format(stream, "R%d = R%d OR LSHIFT R%d BY %d", rn, rn, rx, data8); break; + case 0x01: util::stream_format(stream, "R%d = ASHIFT R%d BY %d", rn, rx, data8); break; + case 0x09: util::stream_format(stream, "R%d = R%d OR ASHIFT R%d BY %d", rn, rn, rx, data8); break; + case 0x02: util::stream_format(stream, "R%d = ROT R%d BY %d", rn, rx, data8); break; + case 0x31: util::stream_format(stream, "R%d = BCLR R%d BY %d", rn, rx, data8); break; + case 0x30: util::stream_format(stream, "R%d = BSET R%d BY %d", rn, rx, data8); break; + case 0x32: util::stream_format(stream, "R%d = BTGL R%d BY %d", rn, rx, data8); break; + case 0x33: util::stream_format(stream, "BTST R%d BY %d", rx, data8); break; + case 0x11: util::stream_format(stream, "R%d = FDEP R%d BY %d:%d", rn, rx, bit6, len); break; + case 0x19: util::stream_format(stream, "R%d = R%d OR FDEP R%d BY %d:%d", rn, rn, rx, bit6, len); break; + case 0x13: util::stream_format(stream, "R%d = FDEP R%d BY %d:%d (SE)", rn, rx, bit6, len); break; + case 0x1b: util::stream_format(stream, "R%d = R%d OR FDEP R%d BY %d:%d (SE)", rn, rn, rx, bit6, len); break; + case 0x10: util::stream_format(stream, "R%d = FEXT R%d BY %d:%d", rn, rx, bit6, len); break; + case 0x12: util::stream_format(stream, "R%d = FEXT R%d BY %d:%d (SE)", rn, rx, bit6, len); break; + case 0x20: util::stream_format(stream, "R%d = EXP R%d", rn, rx); break; + case 0x21: util::stream_format(stream, "R%d = EXP R%d (EX)", rn, rx); break; + case 0x22: util::stream_format(stream, "R%d = LEFTZ R%d", rn, rx); break; + case 0x23: util::stream_format(stream, "R%d = LEFTO R%d", rn, rx); break; + case 0x24: util::stream_format(stream, "R%d = FPACK F%d", rn, rx); break; + case 0x25: util::stream_format(stream, "F%d = FUNPACK R%d", rn, rx); break; + default: util::stream_format(stream, "??? (SHIFTOP)"); break; } } - - - - -static uint32_t dasm_compute_dreg_dmpm(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_compute_dreg_dmpm(std::ostream &stream, uint32_t pc, uint64_t opcode) { int dmi = (opcode >> 41) & 0x7; int dmm = (opcode >> 38) & 0x7; @@ -492,42 +544,42 @@ static uint32_t dasm_compute_dreg_dmpm(uint32_t pc, uint64_t opcode) if (comp) { - compute(comp); - print(", "); + compute(stream, comp); + util::stream_format(stream, ", "); } if (dmd) { - print("DM(%s, %s) = R%d, ", GET_DAG1_I(dmi), GET_DAG1_M(dmm), dmdreg); + util::stream_format(stream, "DM(%s, %s) = R%d, ", GET_DAG1_I(dmi), GET_DAG1_M(dmm), dmdreg); } else { - print("R%d = DM(%s, %s), ", dmdreg, GET_DAG1_I(dmi), GET_DAG1_M(dmm)); + util::stream_format(stream, "R%d = DM(%s, %s), ", dmdreg, GET_DAG1_I(dmi), GET_DAG1_M(dmm)); } if (pmd) { - print("PM(%s, %s) = R%d", GET_DAG2_I(pmi), GET_DAG2_M(pmm), pmdreg); + util::stream_format(stream, "PM(%s, %s) = R%d", GET_DAG2_I(pmi), GET_DAG2_M(pmm), pmdreg); } else { - print("R%d = PM(%s, %s)", pmdreg, GET_DAG2_I(pmi), GET_DAG2_M(pmm)); + util::stream_format(stream, "R%d = PM(%s, %s)", pmdreg, GET_DAG2_I(pmi), GET_DAG2_M(pmm)); } return 0; } -static uint32_t dasm_compute(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_compute(std::ostream &stream, uint32_t pc, uint64_t opcode) { int cond = (opcode >> 33) & 0x1f; int comp = opcode & 0x7fffff; if (comp) { - get_if_condition(cond); - compute(comp); + get_if_condition(stream, cond); + compute(stream, comp); } return 0; } -static uint32_t dasm_compute_uregdmpm_regmod(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_compute_uregdmpm_regmod(std::ostream &stream, uint32_t pc, uint64_t opcode) { int cond = (opcode >> 33) & 0x1f; int g = (opcode >> 32) & 0x1; @@ -538,17 +590,17 @@ static uint32_t dasm_compute_uregdmpm_regmod(uint32_t pc, uint64_t opcode) int ureg = (opcode >> 23) & 0xff; int comp = opcode & 0x7fffff; - get_if_condition(cond); + get_if_condition(stream, cond); if (comp) { - compute(comp); - print(", "); + compute(stream, comp); + util::stream_format(stream, ", "); } - pm_dm_ureg(g,d,i,m, ureg, u); + pm_dm_ureg(stream, g,d,i,m, ureg, u); return 0; } -static uint32_t dasm_compute_dregdmpm_immmod(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_compute_dregdmpm_immmod(std::ostream &stream, uint32_t pc, uint64_t opcode) { int cond = (opcode >> 33) & 0x1f; int g = (opcode >> 40) & 0x1; @@ -559,34 +611,34 @@ static uint32_t dasm_compute_dregdmpm_immmod(uint32_t pc, uint64_t opcode) int data = (opcode >> 27) & 0x3f; int comp = opcode & 0x7fffff; - get_if_condition(cond); + get_if_condition(stream, cond); if (comp) { - compute(comp); - print(", "); + compute(stream, comp); + util::stream_format(stream, ", "); } - pm_dm_imm_dreg(g,d,i, data, dreg, u); + pm_dm_imm_dreg(stream, g,d,i, data, dreg, u); return 0; } -static uint32_t dasm_compute_ureg_ureg(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_compute_ureg_ureg(std::ostream &stream, uint32_t pc, uint64_t opcode) { int cond = (opcode >> 31) & 0x1f; int uregs = (opcode >> 36) & 0xff; int uregd = (opcode >> 23) & 0xff; int comp = opcode & 0x7fffff; - get_if_condition(cond); + get_if_condition(stream, cond); if (comp) { - compute(comp); - print(", "); + compute(stream, comp); + util::stream_format(stream, ", "); } - print("%s = %s", GET_UREG(uregd), GET_UREG(uregs)); + util::stream_format(stream, "%s = %s", GET_UREG(uregd), GET_UREG(uregs)); return 0; } -static uint32_t dasm_immshift_dregdmpm(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_immshift_dregdmpm(std::ostream &stream, uint32_t pc, uint64_t opcode) { int cond = (opcode >> 33) & 0x1f; int g = (opcode >> 32) & 0x1; @@ -599,14 +651,14 @@ static uint32_t dasm_immshift_dregdmpm(uint32_t pc, uint64_t opcode) int dreg = (opcode >> 23) & 0xf; int data = (((opcode >> 27) & 0xf) << 8) | ((opcode >> 8) & 0xff); - get_if_condition(cond); - shiftop(shift, data, rn, rx); - print(", "); - pm_dm_dreg(g,d,i,m, dreg); + get_if_condition(stream, cond); + shiftop(stream, shift, data, rn, rx); + util::stream_format(stream, ", "); + pm_dm_dreg(stream, g,d,i,m, dreg); return 0; } -static uint32_t dasm_immshift_dregdmpm_nodata(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_immshift_dregdmpm_nodata(std::ostream &stream, uint32_t pc, uint64_t opcode) { int cond = (opcode >> 33) & 0x1f; int rn = (opcode >> 4) & 0xf; @@ -614,12 +666,12 @@ static uint32_t dasm_immshift_dregdmpm_nodata(uint32_t pc, uint64_t opcode) int shift = (opcode >> 16) & 0x3f; int data = (((opcode >> 27) & 0xf) << 8) | ((opcode >> 8) & 0xff); - get_if_condition(cond); - shiftop(shift, data, rn, rx); + get_if_condition(stream, cond); + shiftop(stream, shift, data, rn, rx); return 0; } -static uint32_t dasm_compute_modify(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_compute_modify(std::ostream &stream, uint32_t pc, uint64_t opcode) { int cond = (opcode >> 33) & 0x1f; int g = (opcode >> 38) & 0x7; @@ -627,17 +679,17 @@ static uint32_t dasm_compute_modify(uint32_t pc, uint64_t opcode) int m = (opcode >> 27) & 0x7; int comp = opcode & 0x7fffff; - get_if_condition(cond); + get_if_condition(stream, cond); if (comp) { - compute(comp); - print(", "); + compute(stream, comp); + util::stream_format(stream, ", "); } - print("MODIFY(I%d, M%d)", (g ? 8+i : i), (g ? 8+m : m)); + util::stream_format(stream, "MODIFY(I%d, M%d)", (g ? 8+i : i), (g ? 8+m : m)); return 0; } -static uint32_t dasm_direct_jump(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_direct_jump(std::ostream &stream, uint32_t pc, uint64_t opcode) { int j = (opcode >> 26) & 0x1; int cond = (opcode >> 33) & 0x1f; @@ -645,37 +697,37 @@ static uint32_t dasm_direct_jump(uint32_t pc, uint64_t opcode) uint32_t addr = opcode & 0xffffff; uint32_t flags = 0; - get_if_condition(cond); + get_if_condition(stream, cond); if (opcode & 0x8000000000U) { - print("CALL"); - flags = DASMFLAG_STEP_OVER; + util::stream_format(stream, "CALL"); + flags = STEP_OVER; } else { - print("JUMP"); + util::stream_format(stream, "JUMP"); } if (opcode & 0x10000000000U) /* PC-relative branch */ { - print(" (0x%08X)", pc + SIGN_EXTEND24(addr)); + util::stream_format(stream, " (0x%08X)", pc + SIGN_EXTEND24(addr)); } else /* Indirect branch */ { - print(" (0x%08X)", addr); + util::stream_format(stream, " (0x%08X)", addr); } if (j) { - print(" (DB)"); + util::stream_format(stream, " (DB)"); } if (ci) { - print(" (CI)"); + util::stream_format(stream, " (CI)"); } return flags; } -static uint32_t dasm_indirect_jump_compute(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_indirect_jump_compute(std::ostream &stream, uint32_t pc, uint64_t opcode) { int b = (opcode >> 39) & 0x1; int j = (opcode >> 26) & 0x1; @@ -688,48 +740,48 @@ static uint32_t dasm_indirect_jump_compute(uint32_t pc, uint64_t opcode) int comp = opcode & 0x7fffff; uint32_t flags = 0; - get_if_condition(cond); + get_if_condition(stream, cond); if (b) { - print("CALL"); - flags = DASMFLAG_STEP_OVER; + util::stream_format(stream, "CALL"); + flags = STEP_OVER; } else { - print("JUMP"); + util::stream_format(stream, "JUMP"); } if (opcode & 0x10000000000U) /* PC-relative branch */ { - print(" (0x%08X)", pc + SIGN_EXTEND6(reladdr)); + util::stream_format(stream, " (0x%08X)", pc + SIGN_EXTEND6(reladdr)); } else /* Indirect branch */ { - print(" (%s, %s)", GET_DAG2_M(pmm), GET_DAG2_I(pmi)); + util::stream_format(stream, " (%s, %s)", GET_DAG2_M(pmm), GET_DAG2_I(pmi)); } if (j) { - print(" (DB)"); + util::stream_format(stream, " (DB)"); } if (ci) { - print(" (CI)"); + util::stream_format(stream, " (CI)"); } if (comp) { - print(", "); + util::stream_format(stream, ", "); if (e) { - print("ELSE "); + util::stream_format(stream, "ELSE "); } - compute(comp); + compute(stream, comp); } return flags; } -static uint32_t dasm_indirect_jump_compute_dregdm(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_indirect_jump_compute_dregdm(std::ostream &stream, uint32_t pc, uint64_t opcode) { int d = (opcode >> 44) & 0x1; int cond = (opcode >> 33) & 0x1f; @@ -741,36 +793,36 @@ static uint32_t dasm_indirect_jump_compute_dregdm(uint32_t pc, uint64_t opcode) int dreg = (opcode >> 23) & 0xf; int comp = opcode & 0x7fffff; - get_if_condition(cond); - print("JUMP"); + get_if_condition(stream, cond); + util::stream_format(stream, "JUMP"); if (opcode & 0x200000000000U) /* PC-relative branch */ { - print(" (0x%08X)", pc + SIGN_EXTEND6(reladdr)); + util::stream_format(stream, " (0x%08X)", pc + SIGN_EXTEND6(reladdr)); } else /* Indirect branch */ { - print(" (%s, %s)", GET_DAG2_M(pmm), GET_DAG2_I(pmi)); + util::stream_format(stream, " (%s, %s)", GET_DAG2_M(pmm), GET_DAG2_I(pmi)); } - print(", ELSE "); + util::stream_format(stream, ", ELSE "); if (comp) { - compute(comp); - print(", "); + compute(stream, comp); + util::stream_format(stream, ", "); } if (d) { - print("%s = DM(%s, %s)", GET_DREG(dreg), GET_DAG1_I(dmi), GET_DAG1_M(dmm)); + util::stream_format(stream, "%s = DM(%s, %s)", GET_DREG(dreg), GET_DAG1_I(dmi), GET_DAG1_M(dmm)); } else { - print("DM(%s, %s) = %s", GET_DAG1_I(dmi), GET_DAG1_M(dmm), GET_DREG(dreg)); + util::stream_format(stream, "DM(%s, %s) = %s", GET_DAG1_I(dmi), GET_DAG1_M(dmm), GET_DREG(dreg)); } return 0; } -static uint32_t dasm_rts_compute(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_rts_compute(std::ostream &stream, uint32_t pc, uint64_t opcode) { int j = (opcode >> 26) & 0x1; int e = (opcode >> 25) & 0x1; @@ -778,40 +830,40 @@ static uint32_t dasm_rts_compute(uint32_t pc, uint64_t opcode) int cond = (opcode >> 33) & 0x1f; int comp = opcode & 0x7fffff; - get_if_condition(cond); + get_if_condition(stream, cond); if (opcode & 0x10000000000U) { - print("RTI"); + util::stream_format(stream, "RTI"); } else { - print("RTS"); + util::stream_format(stream, "RTS"); } if (j) { - print(" (DB)"); + util::stream_format(stream, " (DB)"); } if (lr) { - print(" (LR)"); + util::stream_format(stream, " (LR)"); } if (comp) { - print(", "); + util::stream_format(stream, ", "); if (e) { - print("ELSE "); + util::stream_format(stream, "ELSE "); } - compute(comp); + compute(stream, comp); } - return DASMFLAG_STEP_OUT; + return STEP_OUT; } -static uint32_t dasm_do_until_counter(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_do_until_counter(std::ostream &stream, uint32_t pc, uint64_t opcode) { int data = (opcode >> 24) & 0xffff; int ureg = (opcode >> 32) & 0xff; @@ -819,27 +871,27 @@ static uint32_t dasm_do_until_counter(uint32_t pc, uint64_t opcode) if (opcode & 0x10000000000U) /* Loop counter from universal register */ { - print("LCNTR = %s, ", GET_UREG(ureg)); - print("DO (0x%08X)", pc + SIGN_EXTEND24(addr)); + util::stream_format(stream, "LCNTR = %s, ", GET_UREG(ureg)); + util::stream_format(stream, "DO (0x%08X)", pc + SIGN_EXTEND24(addr)); } else /* Loop counter from immediate */ { - print("LCNTR = 0x%04X, ", data); - print("DO (0x%08X) UNTIL LCE", pc + SIGN_EXTEND24(addr)); + util::stream_format(stream, "LCNTR = 0x%04X, ", data); + util::stream_format(stream, "DO (0x%08X) UNTIL LCE", pc + SIGN_EXTEND24(addr)); } return 0; } -static uint32_t dasm_do_until(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_do_until(std::ostream &stream, uint32_t pc, uint64_t opcode) { int term = (opcode >> 33) & 0x1f; uint32_t addr = opcode & 0xffffff; - print("DO (0x%08X) UNTIL %s", pc + SIGN_EXTEND24(addr), condition_codes_do[term]); + util::stream_format(stream, "DO (0x%08X) UNTIL %s", pc + SIGN_EXTEND24(addr), condition_codes_do[term]); return 0; } -static uint32_t dasm_immmove_uregdmpm(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_immmove_uregdmpm(std::ostream &stream, uint32_t pc, uint64_t opcode) { int d = (opcode >> 40) & 0x1; int g = (opcode >> 41) & 0x1; @@ -850,28 +902,28 @@ static uint32_t dasm_immmove_uregdmpm(uint32_t pc, uint64_t opcode) { if (d) { - print("PM(0x%08X) = %s", addr, GET_UREG(ureg)); + util::stream_format(stream, "PM(0x%08X) = %s", addr, GET_UREG(ureg)); } else { - print("%s = PM(0x%08X)", GET_UREG(ureg), addr); + util::stream_format(stream, "%s = PM(0x%08X)", GET_UREG(ureg), addr); } } else { if (d) { - print("DM(0x%08X) = %s", addr, GET_UREG(ureg)); + util::stream_format(stream, "DM(0x%08X) = %s", addr, GET_UREG(ureg)); } else { - print("%s = DM(0x%08X)", GET_UREG(ureg), addr); + util::stream_format(stream, "%s = DM(0x%08X)", GET_UREG(ureg), addr); } } return 0; } -static uint32_t dasm_immmove_uregdmpm_indirect(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_immmove_uregdmpm_indirect(std::ostream &stream, uint32_t pc, uint64_t opcode) { int d = (opcode >> 40) & 0x1; int g = (opcode >> 44) & 0x1; @@ -883,28 +935,28 @@ static uint32_t dasm_immmove_uregdmpm_indirect(uint32_t pc, uint64_t opcode) { if (d) { - print("PM(0x%08X, %s) = %s", addr, GET_DAG2_I(i), GET_UREG(ureg)); + util::stream_format(stream, "PM(0x%08X, %s) = %s", addr, GET_DAG2_I(i), GET_UREG(ureg)); } else { - print("%s = PM(0x%08X, %s)", GET_UREG(ureg), addr, GET_DAG2_I(i)); + util::stream_format(stream, "%s = PM(0x%08X, %s)", GET_UREG(ureg), addr, GET_DAG2_I(i)); } } else { if (d) { - print("DM(0x%08X, %s) = %s", addr, GET_DAG1_I(i), GET_UREG(ureg)); + util::stream_format(stream, "DM(0x%08X, %s) = %s", addr, GET_DAG1_I(i), GET_UREG(ureg)); } else { - print("%s = DM(0x%08X, %s)", GET_UREG(ureg), addr, GET_DAG1_I(i)); + util::stream_format(stream, "%s = DM(0x%08X, %s)", GET_UREG(ureg), addr, GET_DAG1_I(i)); } } return 0; } -static uint32_t dasm_immmove_immdata_dmpm(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_immmove_immdata_dmpm(std::ostream &stream, uint32_t pc, uint64_t opcode) { int g = (opcode >> 37) & 0x1; int i = (opcode >> 41) & 0x7; @@ -913,38 +965,38 @@ static uint32_t dasm_immmove_immdata_dmpm(uint32_t pc, uint64_t opcode) if (g) { - print("PM(%s, %s) = 0x%08X", GET_DAG2_I(i), GET_DAG2_M(m), data); + util::stream_format(stream, "PM(%s, %s) = 0x%08X", GET_DAG2_I(i), GET_DAG2_M(m), data); } else { - print("DM(%s, %s) = 0x%08X", GET_DAG1_I(i), GET_DAG1_M(m), data); + util::stream_format(stream, "DM(%s, %s) = 0x%08X", GET_DAG1_I(i), GET_DAG1_M(m), data); } return 0; } -static uint32_t dasm_immmove_immdata_ureg(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_immmove_immdata_ureg(std::ostream &stream, uint32_t pc, uint64_t opcode) { int ureg = (opcode >> 32) & 0xff; uint32_t data = opcode & 0xffffffff; - print("%s = 0x%08X", GET_UREG(ureg), data); + util::stream_format(stream, "%s = 0x%08X", GET_UREG(ureg), data); return 0; } -static uint32_t dasm_sysreg_bitop(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_sysreg_bitop(std::ostream &stream, uint32_t pc, uint64_t opcode) { int bop = (opcode >> 37) & 0x7; int sreg = (opcode >> 32) & 0xf; uint32_t data = opcode & 0xffffffff; - print("BIT "); - print("%s ", bopnames[bop]); - print("%s ", GET_SREG(sreg)); - print("0x%08X", data); + util::stream_format(stream, "BIT "); + util::stream_format(stream, "%s ", bopnames[bop]); + util::stream_format(stream, "%s ", GET_SREG(sreg)); + util::stream_format(stream, "0x%08X", data); return 0; } -static uint32_t dasm_ireg_modify(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_ireg_modify(std::ostream &stream, uint32_t pc, uint64_t opcode) { int g = (opcode >> 38) & 0x1; int i = (opcode >> 32) & 0x7; @@ -954,28 +1006,28 @@ static uint32_t dasm_ireg_modify(uint32_t pc, uint64_t opcode) { if (g) { - print("BITREV (%s, 0x%08X)", GET_DAG2_I(i), data); + util::stream_format(stream, "BITREV (%s, 0x%08X)", GET_DAG2_I(i), data); } else { - print("BITREV (%s, 0x%08X)", GET_DAG1_I(i), data); + util::stream_format(stream, "BITREV (%s, 0x%08X)", GET_DAG1_I(i), data); } } else /* without bit-reverse */ { if (g) { - print("MODIFY (%s, 0x%08X)", GET_DAG2_I(i), data); + util::stream_format(stream, "MODIFY (%s, 0x%08X)", GET_DAG2_I(i), data); } else { - print("MODIFY (%s, 0x%08X)", GET_DAG1_I(i), data); + util::stream_format(stream, "MODIFY (%s, 0x%08X)", GET_DAG1_I(i), data); } } return 0; } -static uint32_t dasm_misc(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_misc(std::ostream &stream, uint32_t pc, uint64_t opcode) { int bits = (opcode >> 33) & 0x7f; int lpu = (opcode >> 39) & 0x1; @@ -988,171 +1040,169 @@ static uint32_t dasm_misc(uint32_t pc, uint64_t opcode) if (lpu) { - print("PUSH LOOP"); + util::stream_format(stream, "PUSH LOOP"); if (bits & 0x3f) { - print(", "); + util::stream_format(stream, ", "); } } if (lpo) { - print("POP LOOP"); + util::stream_format(stream, "POP LOOP"); if (bits & 0x1f) { - print(", "); + util::stream_format(stream, ", "); } } if (spu) { - print("PUSH STS"); + util::stream_format(stream, "PUSH STS"); if (bits & 0xf) { - print(", "); + util::stream_format(stream, ", "); } } if (spo) { - print("POP STS"); + util::stream_format(stream, "POP STS"); if (bits & 0x7) { - print(", "); + util::stream_format(stream, ", "); } } if (ppu) { - print("PUSH PCSTK"); + util::stream_format(stream, "PUSH PCSTK"); if (bits & 0x3) { - print(", "); + util::stream_format(stream, ", "); } } if (ppo) { - print("POP PCSTK"); + util::stream_format(stream, "POP PCSTK"); if (bits & 0x1) { - print(", "); + util::stream_format(stream, ", "); } } if (fc) { - print("FLUSH CACHE"); + util::stream_format(stream, "FLUSH CACHE"); } return 0; } -static uint32_t dasm_idlenop(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_idlenop(std::ostream &stream, uint32_t pc, uint64_t opcode) { if (opcode & 0x8000000000U) { - print("IDLE"); + util::stream_format(stream, "IDLE"); } else { - print("NOP"); + util::stream_format(stream, "NOP"); } return 0; } -#ifdef UNUSED_FUNCTION -static uint32_t dasm_cjump_rframe(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_cjump_rframe(std::ostream &stream, uint32_t pc, uint64_t opcode) { /* TODO */ if (opcode & 0x10000000000U) /* RFRAME */ { - print("TODO: RFRAME"); + util::stream_format(stream, "TODO: RFRAME"); } else { - print("TODO: CJUMP"); + util::stream_format(stream, "TODO: CJUMP"); } return 0; } -#endif -static uint32_t dasm_invalid(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_invalid(std::ostream &stream, uint32_t pc, uint64_t opcode) { - print("?"); + util::stream_format(stream, "?"); return 0; } -static const SHARC_DASM_OP sharc_dasm_ops[] = +const sharc_disassembler::SHARC_DASM_OP sharc_disassembler::sharc_dasm_ops[] = { // |0 0 1| - { 0xe000, 0x2000, dasm_compute_dreg_dmpm }, + { 0xe000, 0x2000, &sharc_disassembler::dasm_compute_dreg_dmpm }, // |0 0 0|0 0 0 0 1| - { 0xff00, 0x0100, dasm_compute }, + { 0xff00, 0x0100, &sharc_disassembler::dasm_compute }, // |0 1 0| - { 0xe000, 0x4000, dasm_compute_uregdmpm_regmod }, + { 0xe000, 0x4000, &sharc_disassembler::dasm_compute_uregdmpm_regmod }, // |0 1 1|0| - { 0xf000, 0x6000, dasm_compute_dregdmpm_immmod }, + { 0xf000, 0x6000, &sharc_disassembler::dasm_compute_dregdmpm_immmod }, // |0 1 1|1| - { 0xf000, 0x7000, dasm_compute_ureg_ureg }, + { 0xf000, 0x7000, &sharc_disassembler::dasm_compute_ureg_ureg }, // |1 0 0|0| - { 0xf000, 0x8000, dasm_immshift_dregdmpm }, + { 0xf000, 0x8000, &sharc_disassembler::dasm_immshift_dregdmpm }, // |0 0 0|0 0 0 1 0| - { 0xff00, 0x0200, dasm_immshift_dregdmpm_nodata }, + { 0xff00, 0x0200, &sharc_disassembler::dasm_immshift_dregdmpm_nodata }, // |0 0 0|0 0 1 0 0| - { 0xff00, 0x0400, dasm_compute_modify }, + { 0xff00, 0x0400, &sharc_disassembler::dasm_compute_modify }, // |0 0 0|0 0 1 1 x| - { 0xfe00, 0x0600, dasm_direct_jump }, + { 0xfe00, 0x0600, &sharc_disassembler::dasm_direct_jump }, // |0 0 0|0 1 0 0 x| - { 0xfe00, 0x0800, dasm_indirect_jump_compute }, + { 0xfe00, 0x0800, &sharc_disassembler::dasm_indirect_jump_compute }, // |1 1 x| - { 0xc000, 0xc000, dasm_indirect_jump_compute_dregdm }, + { 0xc000, 0xc000, &sharc_disassembler::dasm_indirect_jump_compute_dregdm }, // |0 0 0|0 1 0 1 x| - { 0xfe00, 0x0a00, dasm_rts_compute }, + { 0xfe00, 0x0a00, &sharc_disassembler::dasm_rts_compute }, // |0 0 0|0 1 1 0 x| - { 0xfe00, 0x0c00, dasm_do_until_counter }, + { 0xfe00, 0x0c00, &sharc_disassembler::dasm_do_until_counter }, // |0 0 0|0 1 1 1 0| - { 0xff00, 0x0e00, dasm_do_until }, + { 0xff00, 0x0e00, &sharc_disassembler::dasm_do_until }, // |0 0 0|1 0 0|x|x| - { 0xfc00, 0x1000, dasm_immmove_uregdmpm }, + { 0xfc00, 0x1000, &sharc_disassembler::dasm_immmove_uregdmpm }, // |1 0 1|x|x x x|x| - { 0xe000, 0xa000, dasm_immmove_uregdmpm_indirect }, + { 0xe000, 0xa000, &sharc_disassembler::dasm_immmove_uregdmpm_indirect }, // |1 0 0|1| - { 0xf000, 0x9000, dasm_immmove_immdata_dmpm }, + { 0xf000, 0x9000, &sharc_disassembler::dasm_immmove_immdata_dmpm }, // |0 0 0|0 1 1 1 1| - { 0xff00, 0x0f00, dasm_immmove_immdata_ureg }, + { 0xff00, 0x0f00, &sharc_disassembler::dasm_immmove_immdata_ureg }, // |0 0 0|1 0 1 0 0| - { 0xff00, 0x1400, dasm_sysreg_bitop }, + { 0xff00, 0x1400, &sharc_disassembler::dasm_sysreg_bitop }, // |0 0 0|1 0 1 1 0| - { 0xff00, 0x1600, dasm_ireg_modify }, + { 0xff00, 0x1600, &sharc_disassembler::dasm_ireg_modify }, // |0 0 0|1 0 1 1 1| - { 0xff00, 0x1700, dasm_misc }, + { 0xff00, 0x1700, &sharc_disassembler::dasm_misc }, // |0 0 0|0 0 0 0 0| - { 0xff00, 0x0000, dasm_idlenop }, + { 0xff00, 0x0000, &sharc_disassembler::dasm_idlenop }, }; -static void build_dasm_table(void) +sharc_disassembler::sharc_disassembler() { int i, j; int num_ops = sizeof(sharc_dasm_ops) / sizeof(SHARC_DASM_OP); for (i=0; i < 256; i++) { - sharcdasm_table[i] = dasm_invalid; + sharcdasm_table[i] = &sharc_disassembler::dasm_invalid; } for (i=0; i < 256; i++) @@ -1163,7 +1213,7 @@ static void build_dasm_table(void) { if ((sharc_dasm_ops[j].op_mask & op) == sharc_dasm_ops[j].op_bits) { - if (sharcdasm_table[i] != dasm_invalid) + if (sharcdasm_table[i] != &sharc_disassembler::dasm_invalid) { fatalerror("build_dasm_table: table already filled! (i=%04X, j=%d)\n", i, j); } @@ -1176,45 +1226,15 @@ static void build_dasm_table(void) } } -static uint32_t sharc_dasm_one(std::ostream &stream, offs_t pc, uint64_t opcode) +offs_t sharc_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - #define DEFAULT_DASM_WIDTH (64) - - char dasm_buffer[2000]; - int i; + u64 opcode = opcodes.r64(pc); int op = (opcode >> 40) & 0xff; - uint32_t flags; - - if (!dasm_table_built) - { - build_dasm_table(); - dasm_table_built = 1; - } - memset(dasm_buffer, 0, sizeof(dasm_buffer)); - - /* set buffer for print */ - output = dasm_buffer; - - flags = (*sharcdasm_table[op])(pc, opcode); - - for (i=0; i < DEFAULT_DASM_WIDTH && dasm_buffer[i]; i++) - { - stream << dasm_buffer[i]; - } - return flags; + return 1 | (this->*sharcdasm_table[op])(stream, pc, opcode) | SUPPORTED; } - -CPU_DISASSEMBLE( sharc ) +u32 sharc_disassembler::opcode_alignment() const { - uint64_t op; - uint32_t flags; - - op = ((uint64_t)oprom[0] << 0) | ((uint64_t)oprom[1] << 8) | - ((uint64_t)oprom[2] << 16) | ((uint64_t)oprom[3] << 24) | - ((uint64_t)oprom[4] << 32) | ((uint64_t)oprom[5] << 40); - - flags = sharc_dasm_one(stream, pc, op); - return 1 | flags | DASMFLAG_SUPPORTED; + return 1; } diff --git a/src/devices/cpu/sharc/sharcdsm.h b/src/devices/cpu/sharc/sharcdsm.h index e4a52e94ea6..f752a133d6a 100644 --- a/src/devices/cpu/sharc/sharcdsm.h +++ b/src/devices/cpu/sharc/sharcdsm.h @@ -1,79 +1,68 @@ // license:BSD-3-Clause // copyright-holders:Ville Linde -static const char ureg_names[256][16] = -{ - "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", - "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15", - "I0", "I1", "I2", "I3", "I4", "I5", "I6", "I7", - "I8", "I9", "I10", "I11", "I12", "I13", "I14", "I15", - "M0", "M1", "M2", "M3", "M4", "M5", "M6", "M7", - "M8", "M9", "M10", "M11", "M12", "M13", "M14", "M15", - "L0", "L1", "L2", "L3", "L4", "L5", "L6", "L7", - "L8", "L9", "L10", "L11", "L12", "L13", "L14", "L15", - "B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", - "B8", "B9", "B10", "B11", "B12", "B13", "B14", "B15", - "???", "???", "???", "???", "???", "???", "???", "???", - "???", "???", "???", "???", "???", "???", "???", "???", - "FADDR", "DADDR", "???", "PC", "PCSTK", "PCSTKP", "LADDR", "CURLCNTR", - "LCNTR", "???", "???", "???", "???", "???", "???", "???", - "USTAT1", "USTAT2", "???", "???", "???", "???", "???", "???", - "???", "IRPTL", "MODE2", "MODE1", "ASTAT", "IMASK", "STKY", "IMASKP", - "???", "???", "???", "???", "???", "???", "???", "???", - "???", "???", "???", "???", "???", "???", "???", "???", - "???", "???", "???", "???", "???", "???", "???", "???", - "???", "???", "???", "???", "???", "???", "???", "???", - "???", "???", "???", "???", "???", "???", "???", "???", - "???", "???", "???", "???", "???", "???", "???", "???", - "???", "???", "???", "???", "???", "???", "???", "???", - "???", "???", "???", "???", "???", "???", "???", "???", - "???", "???", "???", "???", "???", "???", "???", "???", - "???", "???", "???", "???", "???", "???", "???", "???", - "???", "???", "???", "???", "???", "???", "???", "???", - "???", "???", "???", "PX", "PX1", "PX2", "TPERIOD", "TCOUNT", - "???", "???", "???", "???", "???", "???", "???", "???", - "???", "???", "???", "???", "???", "???", "???", "???", - "???", "???", "???", "???", "???", "???", "???", "???", - "???", "???", "???", "???", "???", "???", "???", "???" -}; -static const char bopnames[8][8] = -{ - "SET", "CLEAR", "TOGGLE", "???", "TEST", "XOR", "???", "???" -}; +#ifndef MAME_CPU_SHARC_SHARCDSM_H +#define MAME_CPU_SHARC_SHARCDSM_H -static const char condition_codes_if[32][32] = -{ - "EQ", "LT", "LE", "AC", - "AV", "MV", "MS", "SV", - "SZ", "FLAG0_IN", "FLAG1_IN", "FLAG2_IN", - "FLAG3_IN", "TF", "BM", "NOT LCE", - "NE", "GE", "GT", "NOT AC", - "NOT AV", "NOT MV", "NOT MS", "NOT SV", - "NOT SZ", "NOT FLAG0_IN", "NOT FLAG1_IN", "NOT FLAG2_IN", - "NOT FLAG3_IN", "NOT TF", "NBM", "" -}; +#pragma once -static const char condition_codes_do[32][32] = +class sharc_disassembler : public util::disasm_interface { - "EQ", "LT", "LE", "AC", - "AV", "MV", "MS", "SV", - "SZ", "FLAG0_IN", "FLAG1_IN", "FLAG2_IN", - "FLAG3_IN", "TF", "BM", "LCE", - "NE", "GE", "GT", "NOT AC", - "NOT AV", "NOT MV", "NOT MS", "NOT SV", - "NOT SZ", "NOT FLAG0_IN", "NOT FLAG1_IN", "NOT FLAG2_IN", - "NOT FLAG3_IN", "NOT TF", "NBM", "FOREVER" -}; +public: + sharc_disassembler(); + virtual ~sharc_disassembler() = default; -static const char mr_regnames[16][8] = -{ - "MR0F", "MR1F", "MR2F", "MR0B", "MR1B", "MR2B", "???", "???", - "???", "???", "???", "???", "???", "???", "???", "???" -}; + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; -struct SHARC_DASM_OP -{ - uint32_t op_mask; - uint32_t op_bits; - uint32_t (* handler)(uint32_t, uint64_t); +private: + struct SHARC_DASM_OP + { + uint32_t op_mask; + uint32_t op_bits; + uint32_t (sharc_disassembler::*handler)(std::ostream &, uint32_t, uint64_t); + }; + + static const char ureg_names[256][16]; + static const char bopnames[8][8]; + static const char condition_codes_if[32][32]; + static const char condition_codes_do[32][32]; + static const char mr_regnames[16][8]; + static const SHARC_DASM_OP sharc_dasm_ops[]; + + uint32_t (sharc_disassembler::*sharcdasm_table[256])(std::ostream &, uint32_t, uint64_t); + + void compute(std::ostream &stream, uint32_t opcode); + void get_if_condition(std::ostream &stream, int cond); + void pm_dm_ureg(std::ostream &stream, int g, int d, int i, int m, int ureg, int update); + void pm_dm_imm_dreg(std::ostream &stream, int g, int d, int i, int data, int dreg, int update); + void pm_dm_dreg(std::ostream &stream, int g, int d, int i, int m, int dreg); + void shiftop(std::ostream &stream, int shift, int data, int rn, int rx); + + uint32_t dasm_compute_dreg_dmpm(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_compute(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_compute_uregdmpm_regmod(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_compute_dregdmpm_immmod(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_compute_ureg_ureg(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_immshift_dregdmpm(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_immshift_dregdmpm_nodata(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_compute_modify(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_direct_jump(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_indirect_jump_compute(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_indirect_jump_compute_dregdm(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_rts_compute(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_do_until_counter(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_do_until(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_immmove_uregdmpm(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_immmove_uregdmpm_indirect(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_immmove_immdata_dmpm(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_immmove_immdata_ureg(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_sysreg_bitop(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_ireg_modify(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_misc(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_idlenop(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_cjump_rframe(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_invalid(std::ostream &stream, uint32_t pc, uint64_t opcode); }; + +#endif diff --git a/src/devices/cpu/sharc/sharcmem.hxx b/src/devices/cpu/sharc/sharcmem.hxx index b297799c036..73bfa0e69f0 100644 --- a/src/devices/cpu/sharc/sharcmem.hxx +++ b/src/devices/cpu/sharc/sharcmem.hxx @@ -4,30 +4,30 @@ uint32_t adsp21062_device::pm_read32(uint32_t address) { - return m_program->read_dword(address << 3); + return m_program->read_dword(address); } void adsp21062_device::pm_write32(uint32_t address, uint32_t data) { - m_program->write_dword(address << 3, data); + m_program->write_dword(address, data); } uint64_t adsp21062_device::pm_read48(uint32_t address) { - return m_program->read_qword(address << 3); + return m_program->read_qword(address); } void adsp21062_device::pm_write48(uint32_t address, uint64_t data) { - m_program->write_qword(address << 3, data); + m_program->write_qword(address, data); } uint32_t adsp21062_device::dm_read32(uint32_t address) { - return m_data->read_dword(address << 2); + return m_data->read_dword(address); } void adsp21062_device::dm_write32(uint32_t address, uint32_t data) { - m_data->write_dword(address << 2, data); + m_data->write_dword(address, data); } diff --git a/src/devices/cpu/sharc/sharcops.hxx b/src/devices/cpu/sharc/sharcops.hxx index af1beed292b..8e7a03d974e 100644 --- a/src/devices/cpu/sharc/sharcops.hxx +++ b/src/devices/cpu/sharc/sharcops.hxx @@ -2721,9 +2721,5 @@ void adsp21062_device::sharcop_idle() void adsp21062_device::sharcop_unimplemented() { - extern CPU_DISASSEMBLE(sharc); - std::ostringstream dasm; - CPU_DISASSEMBLE_NAME(sharc)(nullptr, dasm, m_core->pc, nullptr, nullptr, 0); - osd_printf_debug("SHARC: %08X: %s\n", m_core->pc, dasm.str().c_str()); fatalerror("SHARC: Unimplemented opcode %04X%08X at %08X\n", (uint16_t)(m_core->opcode >> 32), (uint32_t)(m_core->opcode), m_core->pc); } diff --git a/src/devices/cpu/sm510/sm500.h b/src/devices/cpu/sm510/sm500.h index a7b9b336220..25349ecb1f2 100644 --- a/src/devices/cpu/sm510/sm500.h +++ b/src/devices/cpu/sm510/sm500.h @@ -87,7 +87,7 @@ protected: virtual void device_start() override; virtual void device_reset() override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void execute_one() override; virtual void get_opcode_param() override; virtual void clock_melody() override; @@ -155,7 +155,7 @@ public: protected: sm5a_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int stack_levels, int o_pins, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data); - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void execute_one() override; virtual int get_trs_field() override { return 1; } }; diff --git a/src/devices/cpu/sm510/sm500core.cpp b/src/devices/cpu/sm510/sm500core.cpp index daf60275680..d32fd935e4a 100644 --- a/src/devices/cpu/sm510/sm500core.cpp +++ b/src/devices/cpu/sm510/sm500core.cpp @@ -13,6 +13,7 @@ #include "emu.h" #include "sm500.h" +#include "sm510d.h" #include "debugger.h" @@ -48,10 +49,9 @@ sm500_device::sm500_device(const machine_config &mconfig, device_type type, cons // disasm -offs_t sm500_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +util::disasm_interface *sm500_device::create_disassembler() { - extern CPU_DISASSEMBLE(sm500); - return CPU_DISASSEMBLE_NAME(sm500)(this, stream, pc, oprom, opram, options); + return new sm500_disassembler; } diff --git a/src/devices/cpu/sm510/sm510.h b/src/devices/cpu/sm510/sm510.h index cb963e87fa8..f9972a0c6e7 100644 --- a/src/devices/cpu/sm510/sm510.h +++ b/src/devices/cpu/sm510/sm510.h @@ -153,10 +153,6 @@ protected: // device_memory_interface overrides virtual space_config_vector memory_space_config() const override; - // device_disasm_interface overrides - virtual u32 disasm_min_opcode_bytes() const override { return 1; } - virtual u32 disasm_max_opcode_bytes() const override { return 2; } - address_space_config m_program_config; address_space_config m_data_config; address_space *m_program; @@ -321,7 +317,7 @@ public: sm510_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); protected: - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void execute_one() override; virtual void get_opcode_param() override; @@ -342,7 +338,7 @@ protected: virtual void device_post_load() override { notify_clock_changed(); } virtual void device_reset() override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void execute_one() override; virtual void get_opcode_param() override; diff --git a/src/devices/cpu/sm510/sm510base.cpp b/src/devices/cpu/sm510/sm510base.cpp index bbf87000d3f..58b16abd11f 100644 --- a/src/devices/cpu/sm510/sm510base.cpp +++ b/src/devices/cpu/sm510/sm510base.cpp @@ -12,7 +12,6 @@ TODO: - source organiziation between files is a mess - - proper support for LFSR program counter in debugger - LCD bs pin blink mode via Y register (0.5s off, 0.5s on) - wake up after CEND doesn't work right diff --git a/src/devices/cpu/sm510/sm510core.cpp b/src/devices/cpu/sm510/sm510core.cpp index fe422988459..3540a07168f 100644 --- a/src/devices/cpu/sm510/sm510core.cpp +++ b/src/devices/cpu/sm510/sm510core.cpp @@ -11,6 +11,7 @@ #include "emu.h" #include "sm510.h" +#include "sm510d.h" #include "debugger.h" @@ -41,10 +42,9 @@ sm510_device::sm510_device(const machine_config &mconfig, const char *tag, devic // disasm -offs_t sm510_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +util::disasm_interface *sm510_device::create_disassembler() { - extern CPU_DISASSEMBLE(sm510); - return CPU_DISASSEMBLE_NAME(sm510)(this, stream, pc, oprom, opram, options); + return new sm510_disassembler; } diff --git a/src/devices/cpu/sm510/sm510d.cpp b/src/devices/cpu/sm510/sm510d.cpp index 4ec634b4771..186efde5cbc 100644 --- a/src/devices/cpu/sm510/sm510d.cpp +++ b/src/devices/cpu/sm510/sm510d.cpp @@ -7,40 +7,12 @@ */ #include "emu.h" -#include "debugger.h" -#include "sm510.h" +#include "sm510d.h" // common lookup tables -enum e_mnemonics -{ - // SM510 common - mILL /* 0! */, mEXT, - mLB, mLBL, mSBM, mEXBLA, mINCB, mDECB, - mATPL, mRTN0, mRTN1, mTL, mTML, mTM, mT, - mEXC, mBDC, mEXCI, mEXCD, mLDA, mLAX, mPTW, mWR, mWS, - mKTA, mATBP, mATX, mATL, mATFC, mATR, - mADD, mADD11, mADX, mCOMA, mROT, mRC, mSC, - mTB, mTC, mTAM, mTMI, mTA0, mTABL, mTIS, mTAL, mTF1, mTF4, - mRM, mSM, - mPRE, mSME, mRME, mTMEL, - mSKIP, mCEND, mIDIV, mDR, mDTA, mCLKLO, mCLKHI, - - // SM500 common - mCOMCB, mRTN, mRTNS, mSSR, mTR, mTRS, mRBM, - mADDC, mPDTW, mTW, mDTW, - mATS, mEXKSA, mEXKFA, - mRMF, mSMF, mCOMCN, - mTA, mTM2, mTG, - - // SM590 aliases - mNOP, mCCTRL, mINBL, mDEBL, mXBLA, mADCS, mTR7, - // SM590 uniques - mTAX, mLBLX, mMTR, mSTR, mINBM, mDEBM, mRTA, mBLTA, mEXAX, mTBA, mADS, mADC, mLBMX, mTLS -}; - -static const char *const s_mnemonics[] = +const char *const sm510_common_disassembler::s_mnemonics[] = { "?", "", "LB", "LBL", "SBM", "EXBLA", "INCB", "DECB", @@ -67,7 +39,7 @@ static const char *const s_mnemonics[] = }; // number of bits per opcode parameter, 8 or larger means 2-byte opcode -static const u8 s_bits[] = +const u8 sm510_common_disassembler::s_bits[] = { 0, 8, 4, 8, 0, 0, 0, 0, @@ -93,42 +65,39 @@ static const u8 s_bits[] = 4, 4, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 2+8 }; -#define _OVER DASMFLAG_STEP_OVER -#define _OUT DASMFLAG_STEP_OUT - -static const u32 s_flags[] = +const u32 sm510_common_disassembler::s_flags[] = { 0, 0, 0, 0, 0, 0, 0, 0, - 0, _OUT, _OUT, 0, _OVER, _OVER, 0, + 0, STEP_OUT, STEP_OUT, 0, STEP_OVER, STEP_OVER, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, _OVER, 0, 0, 0, 0, 0, + 0, STEP_OVER, 0, 0, 0, 0, 0, // - 0, _OUT, _OUT, 0, 0, _OVER, 0, + 0, STEP_OUT, STEP_OUT, 0, 0, STEP_OVER, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, _OVER, + 0, 0, 0, 0, 0, 0, STEP_OVER, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _OVER + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, STEP_OVER }; // common disasm -static offs_t sm510_common_disasm(const u8 *lut_mnemonic, const u8 *lut_extended, std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram) +offs_t sm510_common_disassembler::common_disasm(const u8 *lut_mnemonic, const u8 *lut_extended, std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms, const u8 pclen) { // get raw opcode - u8 op = oprom[0]; + u8 op = opcodes.r8(pc); u8 instr = lut_mnemonic[op]; int len = 1; @@ -137,7 +106,19 @@ static offs_t sm510_common_disasm(const u8 *lut_mnemonic, const u8 *lut_extended u16 param = mask; if (bits >= 8) { - param = oprom[1]; + if (pclen == 6) + { + int feed = ((pc >> 1 ^ pc) & 1) ? 0 : 0x20; + pc = feed | (pc >> 1 & 0x1f) | (pc & ~0x3f); + } + else if (pclen == 7) + { + int feed = ((pc >> 1 ^ pc) & 1) ? 0 : 0x40; + pc = feed | (pc >> 1 & 0x3f) | (pc & ~0x7f); + } + else + abort(); + param = params.r8(pc); len++; } @@ -169,13 +150,13 @@ static offs_t sm510_common_disasm(const u8 *lut_mnemonic, const u8 *lut_extended } } - return len | s_flags[instr] | DASMFLAG_SUPPORTED; + return len | s_flags[instr] |SUPPORTED; } // SM510 disasm -static const u8 sm510_mnemonic[0x100] = +const u8 sm510_disassembler::sm510_mnemonic[0x100] = { /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ mSKIP, mATBP, mSBM, mATPL, mRM, mRM, mRM, mRM, mADD, mADD11,mCOMA, mEXBLA,mSM, mSM, mSM, mSM, // 0 @@ -199,15 +180,15 @@ static const u8 sm510_mnemonic[0x100] = mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM // F }; -CPU_DISASSEMBLE(sm510) +offs_t sm510_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - return sm510_common_disasm(sm510_mnemonic, nullptr, stream, pc, oprom, opram); + return common_disasm(sm510_mnemonic, nullptr, stream, pc, opcodes, params, 6); } // SM511 disasm -static const u8 sm511_mnemonic[0x100] = +const u8 sm511_disassembler::sm511_mnemonic[0x100] = { /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ mROT, mDTA, mSBM, mATPL, mRM, mRM, mRM, mRM, mADD, mADD11,mCOMA, mEXBLA,mSM, mSM, mSM, mSM, // 0 @@ -231,25 +212,25 @@ static const u8 sm511_mnemonic[0x100] = mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM // F }; -static const u8 sm511_extended[0x10] = +const u8 sm511_disassembler::sm511_extended[0x10] = { mRME, mSME, mTMEL, mATFC, mBDC, mATBP, mCLKHI,mCLKLO,0, 0, 0, 0, 0, 0, 0, 0 // 60 3 }; -CPU_DISASSEMBLE(sm511) +offs_t sm511_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { // create extended opcode table u8 ext[0x100]; memset(ext, 0, 0x100); memcpy(ext + 0x30, sm511_extended, 0x10); - return sm510_common_disasm(sm511_mnemonic, ext, stream, pc, oprom, opram); + return common_disasm(sm511_mnemonic, ext, stream, pc, opcodes, params, 6); } // SM500 disasm -static const u8 sm500_mnemonic[0x100] = +const u8 sm500_disassembler::sm500_mnemonic[0x100] = { /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ mSKIP, mATR, mEXKSA,mATBP, mRM, mRM, mRM, mRM, mADD, mADDC, mCOMA, mEXBLA,mSM, mSM, mSM, mSM, // 0 @@ -273,25 +254,25 @@ static const u8 sm500_mnemonic[0x100] = mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS // F }; -static const u8 sm500_extended[0x10] = +const u8 sm500_disassembler::sm500_extended[0x10] = { mCEND, 0, 0, 0, mDTA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // 5E 0 }; -CPU_DISASSEMBLE(sm500) +offs_t sm500_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { // create extended opcode table u8 ext[0x100]; memset(ext, 0, 0x100); memcpy(ext + 0x00, sm500_extended, 0x10); - return sm510_common_disasm(sm500_mnemonic, ext, stream, pc, oprom, opram); + return common_disasm(sm500_mnemonic, ext, stream, pc, opcodes, params, 6); } // SM5A disasm -static const u8 sm5a_mnemonic[0x100] = +const u8 sm5a_disassembler::sm5a_mnemonic[0x100] = { /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ mSKIP, mATR, mSBM, mATBP, mRM, mRM, mRM, mRM, mADD, mADDC, mCOMA, mEXBLA,mSM, mSM, mSM, mSM, // 0 @@ -315,25 +296,25 @@ static const u8 sm5a_mnemonic[0x100] = mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS // F }; -static const u8 sm5a_extended[0x10] = +const u8 sm5a_disassembler::sm5a_extended[0x10] = { mCEND, 0, 0, 0, mDTA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // 5E 0 }; -CPU_DISASSEMBLE(sm5a) +offs_t sm5a_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { // create extended opcode table u8 ext[0x100]; memset(ext, 0, 0x100); memcpy(ext + 0x00, sm5a_extended, 0x10); - return sm510_common_disasm(sm5a_mnemonic, ext, stream, pc, oprom, opram); + return common_disasm(sm5a_mnemonic, ext, stream, pc, opcodes, params, 6); } // SM590 disasm -static const u8 sm590_mnemonic[0x100] = +const u8 sm590_disassembler::sm590_mnemonic[0x100] = { /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ mNOP, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, // 0 @@ -358,7 +339,90 @@ static const u8 sm590_mnemonic[0x100] = }; -CPU_DISASSEMBLE(sm590) +offs_t sm590_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + return common_disasm(sm590_mnemonic, nullptr, stream, pc, opcodes, params, 7); +} + +u32 sm510_common_disassembler::opcode_alignment() const +{ + return 1; +} + +u32 sm510_common_disassembler::interface_flags() const +{ + return NONLINEAR_PC|PAGED2LEVEL; +} + +u32 sm510_common_disassembler::page_address_bits() const +{ + return 6; +} + +u32 sm510_common_disassembler::page2_address_bits() const +{ + return 4; +} + +offs_t sm510_common_disassembler::pc_linear_to_real(offs_t pc) const +{ + static const u8 l2r[64] = { + 0x00, 0x20, 0x30, 0x38, 0x3c, 0x3e, 0x1f, 0x2f, 0x37, 0x3b, 0x3d, 0x1e, 0x0f, 0x27, 0x33, 0x39, + 0x1c, 0x2e, 0x17, 0x2b, 0x35, 0x1a, 0x0d, 0x06, 0x03, 0x21, 0x10, 0x28, 0x34, 0x3a, 0x1d, 0x0e, + 0x07, 0x23, 0x31, 0x18, 0x2c, 0x36, 0x1b, 0x2d, 0x16, 0x0b, 0x25, 0x12, 0x09, 0x04, 0x22, 0x11, + 0x08, 0x24, 0x32, 0x19, 0x0c, 0x26, 0x13, 0x29, 0x14, 0x2a, 0x15, 0x0a, 0x05, 0x02, 0x01, 0x3f, + }; + return (pc & ~0x3f) | l2r[pc & 0x3f]; +} + +offs_t sm510_common_disassembler::pc_real_to_linear(offs_t pc) const +{ + static const u8 r2l[64] = { + 0x00, 0x3e, 0x3d, 0x18, 0x2d, 0x3c, 0x17, 0x20, 0x30, 0x2c, 0x3b, 0x29, 0x34, 0x16, 0x1f, 0x0c, + 0x1a, 0x2f, 0x2b, 0x36, 0x38, 0x3a, 0x28, 0x12, 0x23, 0x33, 0x15, 0x26, 0x10, 0x1e, 0x0b, 0x06, + 0x01, 0x19, 0x2e, 0x21, 0x31, 0x2a, 0x35, 0x0d, 0x1b, 0x37, 0x39, 0x13, 0x24, 0x27, 0x11, 0x07, + 0x02, 0x22, 0x32, 0x0e, 0x1c, 0x14, 0x25, 0x08, 0x03, 0x0f, 0x1d, 0x09, 0x04, 0x0a, 0x05, 0x3f, + }; + return (pc & ~0x3f) | r2l[pc & 0x3f]; +} + +u32 sm590_disassembler::page_address_bits() const +{ + return 7; +} + +u32 sm590_disassembler::page2_address_bits() const +{ + return 2; +} + +offs_t sm590_disassembler::pc_linear_to_real(offs_t pc) const +{ + static const u8 l2r[128] = { + 0x00, 0x40, 0x60, 0x70, 0x78, 0x7c, 0x7e, 0x3f, 0x5f, 0x6f, 0x77, 0x7b, 0x7d, 0x3e, 0x1f, 0x4f, + 0x67, 0x73, 0x79, 0x3c, 0x5e, 0x2f, 0x57, 0x6b, 0x75, 0x3a, 0x1d, 0x0e, 0x07, 0x43, 0x61, 0x30, + 0x58, 0x6c, 0x76, 0x3b, 0x5d, 0x2e, 0x17, 0x4b, 0x65, 0x32, 0x19, 0x0c, 0x46, 0x23, 0x51, 0x28, + 0x54, 0x6a, 0x35, 0x1a, 0x0d, 0x06, 0x03, 0x41, 0x20, 0x50, 0x68, 0x74, 0x7a, 0x3d, 0x1e, 0x0f, + 0x47, 0x63, 0x71, 0x38, 0x5c, 0x6e, 0x37, 0x5b, 0x6d, 0x36, 0x1b, 0x4d, 0x26, 0x13, 0x49, 0x24, + 0x52, 0x29, 0x14, 0x4a, 0x25, 0x12, 0x09, 0x04, 0x42, 0x21, 0x10, 0x48, 0x64, 0x72, 0x39, 0x1c, + 0x4e, 0x27, 0x53, 0x69, 0x34, 0x5a, 0x2d, 0x16, 0x0b, 0x45, 0x22, 0x11, 0x08, 0x44, 0x62, 0x31, + 0x18, 0x4c, 0x66, 0x33, 0x59, 0x2c, 0x56, 0x2b, 0x55, 0x2a, 0x15, 0x0a, 0x05, 0x02, 0x01, 0x7f, + }; + return (pc & ~0x7f) | l2r[pc & 0x7f]; +} + +offs_t sm590_disassembler::pc_real_to_linear(offs_t pc) const { - return sm510_common_disasm(sm590_mnemonic, nullptr, stream, pc, oprom, opram); + static const u8 r2l[128] = { + 0x00, 0x7e, 0x7d, 0x36, 0x57, 0x7c, 0x35, 0x1c, 0x6c, 0x56, 0x7b, 0x68, 0x2b, 0x34, 0x1b, 0x3f, + 0x5a, 0x6b, 0x55, 0x4d, 0x52, 0x7a, 0x67, 0x26, 0x70, 0x2a, 0x33, 0x4a, 0x5f, 0x1a, 0x3e, 0x0e, + 0x38, 0x59, 0x6a, 0x2d, 0x4f, 0x54, 0x4c, 0x61, 0x2f, 0x51, 0x79, 0x77, 0x75, 0x66, 0x25, 0x15, + 0x1f, 0x6f, 0x29, 0x73, 0x64, 0x32, 0x49, 0x46, 0x43, 0x5e, 0x19, 0x23, 0x13, 0x3d, 0x0d, 0x07, + 0x01, 0x37, 0x58, 0x1d, 0x6d, 0x69, 0x2c, 0x40, 0x5b, 0x4e, 0x53, 0x27, 0x71, 0x4b, 0x60, 0x0f, + 0x39, 0x2e, 0x50, 0x62, 0x30, 0x78, 0x76, 0x16, 0x20, 0x74, 0x65, 0x47, 0x44, 0x24, 0x14, 0x08, + 0x02, 0x1e, 0x6e, 0x41, 0x5c, 0x28, 0x72, 0x10, 0x3a, 0x63, 0x31, 0x17, 0x21, 0x48, 0x45, 0x09, + 0x03, 0x42, 0x5d, 0x11, 0x3b, 0x18, 0x22, 0x0a, 0x04, 0x12, 0x3c, 0x0b, 0x05, 0x0c, 0x06, 0x7f, + }; + return (pc & ~0x7f) | r2l[pc & 0x7f]; } + diff --git a/src/devices/cpu/sm510/sm510d.h b/src/devices/cpu/sm510/sm510d.h new file mode 100644 index 00000000000..899b8815334 --- /dev/null +++ b/src/devices/cpu/sm510/sm510d.h @@ -0,0 +1,131 @@ +// license:BSD-3-Clause +// copyright-holders:hap, Jonathan Gevaryahu +/* + + Sharp SM5xx MCU family disassembler + +*/ + +#ifndef MAME_CPU_SM510_SM510D_H +#define MAME_CPU_SM510_SM510D_H + +#pragma once + +class sm510_common_disassembler : public util::disasm_interface +{ +public: + sm510_common_disassembler() = default; + virtual ~sm510_common_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual u32 interface_flags() const override; + virtual u32 page_address_bits() const override; + virtual u32 page2_address_bits() const override; + virtual offs_t pc_linear_to_real(offs_t pc) const override; + virtual offs_t pc_real_to_linear(offs_t pc) const override; + +protected: + enum e_mnemonics + { + // SM510 common + mILL /* 0! */, mEXT, + mLB, mLBL, mSBM, mEXBLA, mINCB, mDECB, + mATPL, mRTN0, mRTN1, mTL, mTML, mTM, mT, + mEXC, mBDC, mEXCI, mEXCD, mLDA, mLAX, mPTW, mWR, mWS, + mKTA, mATBP, mATX, mATL, mATFC, mATR, + mADD, mADD11, mADX, mCOMA, mROT, mRC, mSC, + mTB, mTC, mTAM, mTMI, mTA0, mTABL, mTIS, mTAL, mTF1, mTF4, + mRM, mSM, + mPRE, mSME, mRME, mTMEL, + mSKIP, mCEND, mIDIV, mDR, mDTA, mCLKLO, mCLKHI, + + // SM500 common + mCOMCB, mRTN, mRTNS, mSSR, mTR, mTRS, mRBM, + mADDC, mPDTW, mTW, mDTW, + mATS, mEXKSA, mEXKFA, + mRMF, mSMF, mCOMCN, + mTA, mTM2, mTG, + + // SM590 aliases + mNOP, mCCTRL, mINBL, mDEBL, mXBLA, mADCS, mTR7, + // SM590 uniques + mTAX, mLBLX, mMTR, mSTR, mINBM, mDEBM, mRTA, mBLTA, mEXAX, mTBA, mADS, mADC, mLBMX, mTLS + }; + + static const char *const s_mnemonics[]; + static const u8 s_bits[]; + static const u32 s_flags[]; + + offs_t common_disasm(const u8 *lut_mnemonic, const u8 *lut_extended, std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms, const u8 pclen); +}; + +class sm510_disassembler : public sm510_common_disassembler +{ +public: + sm510_disassembler() = default; + virtual ~sm510_disassembler() = default; + + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const u8 sm510_mnemonic[0x100]; + +}; + +class sm511_disassembler : public sm510_common_disassembler +{ +public: + sm511_disassembler() = default; + virtual ~sm511_disassembler() = default; + + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const u8 sm511_mnemonic[0x100]; + static const u8 sm511_extended[0x10]; +}; + +class sm500_disassembler : public sm510_common_disassembler +{ +public: + sm500_disassembler() = default; + virtual ~sm500_disassembler() = default; + + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const u8 sm500_mnemonic[0x100]; + static const u8 sm500_extended[0x10]; +}; + +class sm5a_disassembler : public sm510_common_disassembler +{ +public: + sm5a_disassembler() = default; + virtual ~sm5a_disassembler() = default; + + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const u8 sm5a_mnemonic[0x100]; + static const u8 sm5a_extended[0x10]; +}; + +class sm590_disassembler : public sm510_common_disassembler +{ +public: + sm590_disassembler() = default; + virtual ~sm590_disassembler() = default; + + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + + virtual u32 page_address_bits() const override; + virtual u32 page2_address_bits() const override; + virtual offs_t pc_linear_to_real(offs_t pc) const override; + virtual offs_t pc_real_to_linear(offs_t pc) const override; + +private: + static const u8 sm590_mnemonic[0x100]; +}; + +#endif diff --git a/src/devices/cpu/sm510/sm511core.cpp b/src/devices/cpu/sm510/sm511core.cpp index 8ba41c19089..200740ee3e6 100644 --- a/src/devices/cpu/sm510/sm511core.cpp +++ b/src/devices/cpu/sm510/sm511core.cpp @@ -15,6 +15,7 @@ #include "emu.h" #include "sm510.h" +#include "sm510d.h" #include "debugger.h" @@ -43,10 +44,9 @@ ADDRESS_MAP_END // disasm -offs_t sm511_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +util::disasm_interface *sm511_device::create_disassembler() { - extern CPU_DISASSEMBLE(sm511); - return CPU_DISASSEMBLE_NAME(sm511)(this, stream, pc, oprom, opram, options); + return new sm511_disassembler; } diff --git a/src/devices/cpu/sm510/sm590.h b/src/devices/cpu/sm510/sm590.h index bdefb277207..c91b9287d63 100644 --- a/src/devices/cpu/sm510/sm590.h +++ b/src/devices/cpu/sm510/sm590.h @@ -101,7 +101,7 @@ protected: sm590_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int stack_levels, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data); virtual void device_reset() override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; virtual bool wake_me_up() override; virtual void init_divider() override { } virtual void init_lcd_driver() override { } diff --git a/src/devices/cpu/sm510/sm590core.cpp b/src/devices/cpu/sm510/sm590core.cpp index 63544bf503f..c04e40d7461 100644 --- a/src/devices/cpu/sm510/sm590core.cpp +++ b/src/devices/cpu/sm510/sm590core.cpp @@ -13,6 +13,7 @@ #include "emu.h" #include "sm590.h" +#include "sm510d.h" #include "debugger.h" @@ -70,11 +71,9 @@ sm590_device::sm590_device(const machine_config &mconfig, device_type type, cons } -// disasm -offs_t sm590_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +util::disasm_interface *sm590_device::create_disassembler() { - extern CPU_DISASSEMBLE(sm590); - return CPU_DISASSEMBLE_NAME(sm590)(this, stream, pc, oprom, opram, options); + return new sm590_disassembler; } diff --git a/src/devices/cpu/sm510/sm5acore.cpp b/src/devices/cpu/sm510/sm5acore.cpp index 1fd23887227..427918fe1c1 100644 --- a/src/devices/cpu/sm510/sm5acore.cpp +++ b/src/devices/cpu/sm510/sm5acore.cpp @@ -11,6 +11,7 @@ #include "emu.h" #include "sm500.h" +#include "sm510d.h" #include "debugger.h" @@ -63,14 +64,12 @@ kb1013vk12_device::kb1013vk12_device(const machine_config &mconfig, const char * // disasm -offs_t sm5a_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +util::disasm_interface *sm5a_device::create_disassembler() { - extern CPU_DISASSEMBLE(sm5a); - return CPU_DISASSEMBLE_NAME(sm5a)(this, stream, pc, oprom, opram, options); + return new sm5a_disassembler; } - //------------------------------------------------- // execute //------------------------------------------------- diff --git a/src/devices/cpu/sm8500/sm8500.cpp b/src/devices/cpu/sm8500/sm8500.cpp index 654cc0d0db0..74d10aae658 100644 --- a/src/devices/cpu/sm8500/sm8500.cpp +++ b/src/devices/cpu/sm8500/sm8500.cpp @@ -21,6 +21,7 @@ they are internally. #include "emu.h" #include "sm8500.h" +#include "sm8500d.h" #include "debugger.h" @@ -348,10 +349,9 @@ void sm8500_cpu_device::process_interrupts() } -offs_t sm8500_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *sm8500_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( sm8500 ); - return CPU_DISASSEMBLE_NAME(sm8500)(this, stream, pc, oprom, opram, options); + return new sm8500_disassembler; } diff --git a/src/devices/cpu/sm8500/sm8500.h b/src/devices/cpu/sm8500/sm8500.h index 485d3a70ad8..ac9aea3fe82 100644 --- a/src/devices/cpu/sm8500/sm8500.h +++ b/src/devices/cpu/sm8500/sm8500.h @@ -74,9 +74,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 5; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; inline void get_sp(); uint8_t mem_readbyte(uint32_t offset) const; diff --git a/src/devices/cpu/sm8500/sm8500d.cpp b/src/devices/cpu/sm8500/sm8500d.cpp index 1b8b7dd2392..3d6139ef8ed 100644 --- a/src/devices/cpu/sm8500/sm8500d.cpp +++ b/src/devices/cpu/sm8500/sm8500d.cpp @@ -10,31 +10,9 @@ Sharp sm8500 CPU disassembly *******************************************************************/ #include "emu.h" -#include "debugger.h" -#include "sm8500.h" +#include "sm8500d.h" -enum e_mnemonics -{ - zADC=0, zADCW, zADD, zADDW, zAND, zANDW, zBAND, zBBC, zBBS, - zBCLR, zBCMP, zBMOV, zBOR, zBR, zBTST, zBSET, zBXOR, zCALL, zCALS, zCLR, - zCLRC, zCMP, zCMPW, zCOM, zCOMC, zDA, zDBNZ, zDEC, - zDECW, zDI, zDIV, zEI, zEXTS, zHALT, zINC, zINCW, - zIRET, zJMP, zMOV, zMOVM, zMOVW, zMULT, zNEG, zNOP, zOR, - zORW, zPOP, zPOPW, zPUSH, zPUSHW, zRET, zRL, zRLC, - zRR, zRRC, zSBC, zSBCW, zSETC, zSLL, zSRA, zSRL, zSTOP, - zSUB, zSUBW, zSWAP, zXOR, zXORW, zMOVPS0, zINVLD, zDM, -/* unknowns */ -z5A, z5B, - -/* more complicated instructions */ -z1A, z1B, z4F -}; - -/* instructions not found: -5A, 5B, -*/ - -static const char *const s_mnemonic[] = +const char *const sm8500_disassembler::s_mnemonic[] = { "adc", "adcw", "add", "addw", "and", "andw", "band", "bbc", "bbs", "bclr", "bcmp", "bmov", "bor", "br", "btst", "bset", "bxor", "call", "cals", "clr", @@ -51,45 +29,29 @@ static const char *const s_mnemonic[] = "comp1A", "comp1B", "comp4F", }; -#define _OVER DASMFLAG_STEP_OVER -#define _OUT DASMFLAG_STEP_OUT - -static const uint32_t s_flags[] = { +const uint32_t sm8500_disassembler::s_flags[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, _OVER, _OVER, 0, - 0, 0, 0, 0, 0, 0, _OVER, 0, - 0, 0, 0, 0, 0, _OVER, 0, 0, - _OUT, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, _OUT, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, STEP_OVER, STEP_OVER, 0, + 0, 0, 0, 0, 0, 0, STEP_OVER, 0, + 0, 0, 0, 0, 0, STEP_OVER, 0, 0, + STEP_OUT, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, STEP_OUT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -struct sm8500dasm -{ - uint8_t mnemonic; - uint8_t arguments; -}; - -static const char *const sm8500_cond[16] = { +const char *const sm8500_disassembler::sm8500_cond[16] = { "F", "LT", "LE", "ULE", "OV", "MI", "Z", "C", "T", "GE", "GT", "UGT", "NOV", "PL", "NZ", "NC" }; -static const uint8_t sm8500_b2w[8] = { +const uint8_t sm8500_disassembler::sm8500_b2w[8] = { 0, 8, 2, 10, 4, 12, 6, 14 }; -enum e_addrmodes { - AM_R=1, AM_rr, AM_r1, AM_S, AM_rmb, AM_mbr, AM_Ri, AM_rmw, AM_mwr, AM_smw, AM_mws, - AM_Sw, AM_iR, AM_rbr, AM_riw, AM_cjp, AM_rib, AM_pi, AM_cbr, AM_i, AM_ii, - AM_ss, AM_RR, AM_2, AM_SS, AM_bR, AM_Rbr, AM_Rb, AM_rR, AM_Rr, AM_Rii, AM_RiR, - AM_riB, AM_iS, AM_CALS, AM_bid, AM_1A, AM_1B, AM_4F -}; - -static const sm8500dasm mnemonic[256] = { +const sm8500_disassembler::sm8500dasm sm8500_disassembler::mnemonic[256] = { /* 00 - 0F */ {zCLR, AM_R}, {zNEG,AM_R}, {zCOM,AM_R}, {zRR,AM_R}, {zRL, AM_R}, {zRRC,AM_R}, {zRLC,AM_R}, {zSRL,AM_R}, @@ -173,16 +135,21 @@ static const sm8500dasm mnemonic[256] = { }; -CPU_DISASSEMBLE(sm8500) +u32 sm8500_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t sm8500_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { const sm8500dasm *instr; uint8_t op; int8_t offset; uint16_t ea; uint16_t ea2; - int pos = 0; + offs_t pos = pc; - op = oprom[pos++]; + op = opcodes.r8(pos++); instr = &mnemonic[op]; @@ -193,34 +160,34 @@ CPU_DISASSEMBLE(sm8500) } switch( instr->arguments ) { case AM_R: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "R%02Xh", ea); break; case AM_iR: - util::stream_format(stream, "R%02Xh, $%02X", oprom[pos + 1], oprom[pos + 0]); + util::stream_format(stream, "R%02Xh, $%02X", opcodes.r8(pos+1), opcodes.r8(pos)); pos += 2; break; case AM_iS: - util::stream_format(stream, "RR%02Xh, $%02X", oprom[pos + 1], oprom[pos + 0]); + util::stream_format(stream, "RR%02Xh, $%02X", opcodes.r8(pos+1), opcodes.r8(pos)); pos += 2; break; case AM_Sw: - ea2 = oprom[pos++]; - ea = oprom[pos++] << 8; - ea += oprom[pos++]; + ea2 = opcodes.r8(pos++); + ea = opcodes.r8(pos++) << 8; + ea += opcodes.r8(pos++); util::stream_format(stream, "RR%02Xh, $%04X", ea2, ea); break; case AM_rib: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "r%02Xh, $%02X", op & 0x07, ea); break; case AM_riw: - ea = oprom[pos++] << 8; - ea += oprom[pos++]; + ea = opcodes.r8(pos++) << 8; + ea += opcodes.r8(pos++); util::stream_format(stream, "rr%02Xh, $%04X", sm8500_b2w[op & 0x07], ea); break; case AM_rmb: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "r%02Xh,", ( ea >> 3 ) & 0x07); switch( ea & 0xC0 ) { case 0x00: @@ -228,7 +195,7 @@ CPU_DISASSEMBLE(sm8500) case 0x40: util::stream_format(stream, "(r%02Xh)+", ea & 0x07); break; case 0x80: - ea2 = oprom[pos++]; + ea2 = opcodes.r8(pos++); if ( ea & 0x07 ) { util::stream_format(stream, "$%02X(r%02Xh)", ea2, ea & 0x07); } else { @@ -240,14 +207,14 @@ CPU_DISASSEMBLE(sm8500) } break; case AM_mbr: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); switch( ea & 0xC0 ) { case 0x00: util::stream_format(stream, "@r%02Xh", ea & 0x07); break; case 0x40: util::stream_format(stream, "(r%02Xh)+", ea & 0x07); break; case 0x80: - ea2 = oprom[pos++]; + ea2 = opcodes.r8(pos++); if ( ea & 0x07 ) { util::stream_format(stream, "$%02X(r%02Xh)", ea2, ea & 0x07); } else { @@ -260,7 +227,7 @@ CPU_DISASSEMBLE(sm8500) util::stream_format(stream, ",r%02Xh", ( ea >> 3 ) & 0x07); break; case AM_rmw: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "r%02Xh,", ( ea >> 3 ) & 0x07); switch( ea & 0xC0 ) { case 0x00: @@ -268,8 +235,8 @@ CPU_DISASSEMBLE(sm8500) case 0x40: util::stream_format(stream, "(rr%02Xh)+", sm8500_b2w[ea & 0x07]); break; case 0x80: - ea2 = oprom[pos++] << 8; - ea2 += oprom[pos++]; + ea2 = opcodes.r8(pos++) << 8; + ea2 += opcodes.r8(pos++); if ( ea & 0x07 ) { util::stream_format(stream, "$%04X(rr%02Xh)", ea2, sm8500_b2w[ea & 0x07]); } else { @@ -281,15 +248,15 @@ CPU_DISASSEMBLE(sm8500) } break; case AM_mwr: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); switch( ea & 0xC0 ) { case 0x00: util::stream_format(stream, "@rr%02Xh", sm8500_b2w[ea & 0x07]); break; case 0x40: util::stream_format(stream, "(rr%02Xh)+", sm8500_b2w[ea & 0x07]); break; case 0x80: - ea2 = oprom[pos++] << 8; - ea2 += oprom[pos++]; + ea2 = opcodes.r8(pos++) << 8; + ea2 += opcodes.r8(pos++); if ( ea & 0x07 ) { util::stream_format(stream, "$%04X(rr%02Xh)", ea2, sm8500_b2w[ea & 0x07]); } else { @@ -302,7 +269,7 @@ CPU_DISASSEMBLE(sm8500) util::stream_format(stream, ",r%02Xh", ( ea >> 3 ) & 0x07); break; case AM_smw: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "rr%02Xh,", sm8500_b2w[( ea >> 3 ) & 0x07]); switch( ea & 0xC0 ) { case 0x00: @@ -310,8 +277,8 @@ CPU_DISASSEMBLE(sm8500) case 0x40: util::stream_format(stream, "(rr%02Xh)+", sm8500_b2w[ea & 0x07]); break; case 0x80: - ea2 = oprom[pos++] << 8; - ea2 += oprom[pos++]; + ea2 = opcodes.r8(pos++) << 8; + ea2 += opcodes.r8(pos++); if ( ea & 0x07 ) { util::stream_format(stream, "$%04X(rr%02Xh)", ea2, sm8500_b2w[ea & 0x07]); } else { @@ -323,15 +290,15 @@ CPU_DISASSEMBLE(sm8500) } break; case AM_mws: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); switch( ea & 0xC0 ) { case 0x00: util::stream_format(stream, "@rr%02Xh", sm8500_b2w[ea & 0x07]); break; case 0x40: util::stream_format(stream, "(rr%02Xh)+", sm8500_b2w[ea & 0x07]); break; case 0x80: - ea2 = oprom[pos++] << 8; - ea2 += oprom[pos++]; + ea2 = opcodes.r8(pos++) << 8; + ea2 += opcodes.r8(pos++); if ( ea & 0x07 ) { util::stream_format(stream, "$%04X(rr%02Xh)", ea2, sm8500_b2w[ea & 0x07]); } else { @@ -344,20 +311,20 @@ CPU_DISASSEMBLE(sm8500) util::stream_format(stream, ",rr%02Xh", sm8500_b2w[( ea >> 3 ) & 0x07]); break; case AM_cbr: - offset = (int8_t) oprom[pos++]; + offset = (int8_t) opcodes.r8(pos++); util::stream_format(stream, "%s,$%04X", sm8500_cond[ op & 0x0F ], pc + pos + offset); break; case AM_rbr: - offset = (int8_t) oprom[pos++]; + offset = (int8_t) opcodes.r8(pos++); util::stream_format(stream, "r%02Xh,$%04X", op & 0x07, pc + pos + offset); break; case AM_cjp: - ea = oprom[pos++] << 8; - ea += oprom[pos++]; + ea = opcodes.r8(pos++) << 8; + ea += opcodes.r8(pos++); util::stream_format(stream, "%s,$%04X", sm8500_cond[ op & 0x0F], ea); break; case AM_rr: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); switch( ea & 0xc0 ) { case 0x00: util::stream_format(stream, "r%02Xh,r%02Xh", (ea >> 3 ) & 0x07, ea & 0x07); @@ -370,7 +337,7 @@ CPU_DISASSEMBLE(sm8500) } break; case AM_r1: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); switch( ea & 0xC0 ) { case 0x00: util::stream_format(stream, "@r%02Xh", (ea >> 3 ) & 0x07); @@ -383,29 +350,29 @@ CPU_DISASSEMBLE(sm8500) } break; case AM_S: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "RR%02Xh", ea); break; case AM_pi: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "r%02Xh, $%02X", 0x10 + (op & 0x07), ea); break; case AM_Ri: - ea = oprom[pos++]; - ea2 = oprom[pos++]; + ea = opcodes.r8(pos++); + ea2 = opcodes.r8(pos++); util::stream_format(stream, "R%02Xh,$%02X", ea, ea2); break; case AM_i: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "$%02X", ea); break; case AM_ii: - ea = oprom[pos++] << 8; - ea += oprom[pos++]; + ea = opcodes.r8(pos++) << 8; + ea += opcodes.r8(pos++); util::stream_format(stream, "$%04X", ea); break; case AM_ss: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); switch( ea & 0xC0 ) { case 0x00: util::stream_format(stream, "rr%02Xh,rr%02Xh", sm8500_b2w[( ea >> 3 ) & 0x07], sm8500_b2w[ea & 0x07]); break; @@ -418,18 +385,18 @@ CPU_DISASSEMBLE(sm8500) } break; case AM_RR: - ea = oprom[pos++]; - ea2 = oprom[pos++]; + ea = opcodes.r8(pos++); + ea2 = opcodes.r8(pos++); util::stream_format(stream, "R%02Xh,R%02Xh", ea2, ea); break; case AM_2: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); switch( ea & 0xC0 ) { case 0x00: util::stream_format(stream, "rr%02Xh", sm8500_b2w[ea & 0x07]); break; case 0x40: - ea2 = oprom[pos++] << 8; - ea2 += oprom[pos++]; + ea2 = opcodes.r8(pos++) << 8; + ea2 += opcodes.r8(pos++); if ( ea & 0x38 ) { util::stream_format(stream, "@$%04X(r%02Xh)", ea2, ( ea >> 3 ) & 0x07); } else { @@ -443,13 +410,13 @@ CPU_DISASSEMBLE(sm8500) } break; case AM_SS: - ea = oprom[pos++]; - ea2 = oprom[pos++]; + ea = opcodes.r8(pos++); + ea2 = opcodes.r8(pos++); util::stream_format(stream, "RR%02Xh,RR%02Xh", ea2, ea); break; case AM_bR: - ea = oprom[pos++]; - ea2 = oprom[pos++]; + ea = opcodes.r8(pos++); + ea2 = opcodes.r8(pos++); switch( ea & 0xC0 ) { case 0x00: util::stream_format(stream, "BF,R%02Xh,#%d", ea2, ea & 0x07); break; @@ -462,41 +429,41 @@ CPU_DISASSEMBLE(sm8500) } break; case AM_Rbr: - ea = oprom[pos++]; - offset = (int8_t) oprom[pos++]; + ea = opcodes.r8(pos++); + offset = (int8_t) opcodes.r8(pos++); util::stream_format(stream, "R%02Xh,#%d,$%04X", ea, op & 0x07, pc + pos + offset); break; case AM_Rb: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "R%02Xh,#%d", ea, op&0x07); break; case AM_rR: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "r%02Xh,R%02Xh", op & 0x07, ea); break; case AM_Rr: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "R%02Xh,r%02Xh", ea, op & 0x07); break; case AM_Rii: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "R%02Xh,", ea); - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "$%02X,", ea); - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "$%02X", ea); break; case AM_RiR: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "R%02Xh,", ea); - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "$%02X,", ea); - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "R%02Xh", ea); break; case AM_riB: - ea = oprom[pos++]; - ea2 = oprom[pos++]; + ea = opcodes.r8(pos++); + ea2 = opcodes.r8(pos++); switch( ea & 0xC0 ) { case 0x00: util::stream_format(stream, "#%2x(r%02Xh),#%d", ea2, ea >> 3, ea & 0x07); @@ -510,23 +477,23 @@ CPU_DISASSEMBLE(sm8500) } break; case AM_CALS: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "$%04X", 0x1000 | ( ( op & 0x0f ) << 8 ) | ea); break; case AM_bid: - ea = oprom[pos++]; - ea2 = oprom[pos++]; + ea = opcodes.r8(pos++); + ea2 = opcodes.r8(pos++); if ( ea & 0x38 ) { util::stream_format(stream, "$%02X(r%02Xh)", ea2, ( ea >> 3 ) & 0x07); } else { util::stream_format(stream, "$%04X", 0xFF00 + ea2); } util::stream_format(stream, ",#%d,", ea & 0x07); - offset = (int8_t) oprom[pos++]; + offset = (int8_t) opcodes.r8(pos++); util::stream_format(stream, "$%04X", pc + pos + offset); break; case AM_1A: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); switch( ea & 0x07 ) { case 0x00: util::stream_format(stream, "%-4s ", s_mnemonic[ zCLR ]); break; case 0x01: util::stream_format(stream, "%-4s ", s_mnemonic[ zNEG ]); break; @@ -540,7 +507,7 @@ CPU_DISASSEMBLE(sm8500) util::stream_format(stream, "@r%02Xh", ( ea >> 3 ) & 0x07); break; case AM_1B: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); switch( ea & 0x07 ) { case 0x00: util::stream_format(stream, "%-4s ", s_mnemonic[ zINC ]); break; case 0x01: util::stream_format(stream, "%-4s ", s_mnemonic[ zDEC ]); break; @@ -554,8 +521,8 @@ CPU_DISASSEMBLE(sm8500) util::stream_format(stream, "@r%02Xh", ( ea >> 3 ) & 0x07); break; case AM_4F: - ea = oprom[pos++]; - ea2 = oprom[pos++]; + ea = opcodes.r8(pos++); + ea2 = opcodes.r8(pos++); switch( ea & 0xc0 ) { case 0x00: util::stream_format(stream, "%-4s ", s_mnemonic[ zBCMP ]); break; case 0x40: util::stream_format(stream, "%-4s ", s_mnemonic[ zBAND ]); break; @@ -577,5 +544,5 @@ CPU_DISASSEMBLE(sm8500) util::stream_format(stream, "%s", s_mnemonic[ instr->mnemonic ]); } - return pos | s_flags[instr->mnemonic] | DASMFLAG_SUPPORTED; + return (pos - pc) | s_flags[instr->mnemonic] | SUPPORTED; } diff --git a/src/devices/cpu/sm8500/sm8500d.h b/src/devices/cpu/sm8500/sm8500d.h new file mode 100644 index 00000000000..8d425b86c19 --- /dev/null +++ b/src/devices/cpu/sm8500/sm8500d.h @@ -0,0 +1,68 @@ +// license:BSD-3-Clause +// copyright-holders:Wilbert Pol +/******************************************************************* + +sm8500d.c +Sharp sm8500 CPU disassembly + + + +*******************************************************************/ + +#ifndef MAME_CPU_SM8500_SM8500D_H +#define MAME_CPU_SM8500_SM8500D_H + +#pragma once + +class sm8500_disassembler : public util::disasm_interface +{ +public: + sm8500_disassembler() = default; + virtual ~sm8500_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum e_mnemonics + { + zADC=0, zADCW, zADD, zADDW, zAND, zANDW, zBAND, zBBC, zBBS, + zBCLR, zBCMP, zBMOV, zBOR, zBR, zBTST, zBSET, zBXOR, zCALL, zCALS, zCLR, + zCLRC, zCMP, zCMPW, zCOM, zCOMC, zDA, zDBNZ, zDEC, + zDECW, zDI, zDIV, zEI, zEXTS, zHALT, zINC, zINCW, + zIRET, zJMP, zMOV, zMOVM, zMOVW, zMULT, zNEG, zNOP, zOR, + zORW, zPOP, zPOPW, zPUSH, zPUSHW, zRET, zRL, zRLC, + zRR, zRRC, zSBC, zSBCW, zSETC, zSLL, zSRA, zSRL, zSTOP, + zSUB, zSUBW, zSWAP, zXOR, zXORW, zMOVPS0, zINVLD, zDM, + /* unknowns */ + z5A, z5B, + + /* more complicated instructions */ + z1A, z1B, z4F + }; + + /* instructions not found: + 5A, 5B, + */ + + enum e_addrmodes { + AM_R=1, AM_rr, AM_r1, AM_S, AM_rmb, AM_mbr, AM_Ri, AM_rmw, AM_mwr, AM_smw, AM_mws, + AM_Sw, AM_iR, AM_rbr, AM_riw, AM_cjp, AM_rib, AM_pi, AM_cbr, AM_i, AM_ii, + AM_ss, AM_RR, AM_2, AM_SS, AM_bR, AM_Rbr, AM_Rb, AM_rR, AM_Rr, AM_Rii, AM_RiR, + AM_riB, AM_iS, AM_CALS, AM_bid, AM_1A, AM_1B, AM_4F + }; + + struct sm8500dasm + { + uint8_t mnemonic; + uint8_t arguments; + }; + + static const char *const s_mnemonic[]; + static const uint32_t s_flags[]; + static const char *const sm8500_cond[16]; + static const uint8_t sm8500_b2w[8]; + static const sm8500dasm mnemonic[256]; +}; + +#endif diff --git a/src/devices/cpu/sparc/mb86901.cpp b/src/devices/cpu/sparc/mb86901.cpp index 1f6430835f4..bf3023d8f97 100644 --- a/src/devices/cpu/sparc/mb86901.cpp +++ b/src/devices/cpu/sparc/mb86901.cpp @@ -43,7 +43,6 @@ const int mb86901_device::NWINDOWS = 7; mb86901_device::mb86901_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : cpu_device(mconfig, MB86901, tag, owner, clock) , m_program_config("program", ENDIANNESS_BIG, 32, 32) - , m_dasm(this, 7) { } @@ -257,7 +256,7 @@ void mb86901_device::device_start() state_add(SPARC_WIM, "WIM", m_wim).formatstr("%08X"); state_add(SPARC_TBR, "TBR", m_tbr).formatstr("%08X"); state_add(SPARC_Y, "Y", m_y).formatstr("%08X"); - state_add(SPARC_ANNUL, "ANNUL", m_annul).formatstr("%01d"); + state_add(SPARC_ANNUL, "ANNUL", m_annul).formatstr("%01u"); state_add(SPARC_ICC, "icc", m_icc).formatstr("%4s"); state_add(SPARC_CWP, "CWP", m_cwp).formatstr("%2d"); char regname[3] = "g0"; @@ -286,12 +285,12 @@ void mb86901_device::device_start() state_add(SPARC_I0 + i, regname, m_dbgregs[16+i]).formatstr("%08X"); } - state_add(SPARC_EC, "EC", m_ec).formatstr("%1d"); - state_add(SPARC_EF, "EF", m_ef).formatstr("%1d"); - state_add(SPARC_ET, "ET", m_et).formatstr("%1d"); + state_add(SPARC_EC, "EC", m_ec).formatstr("%1u"); + state_add(SPARC_EF, "EF", m_ef).formatstr("%1u"); + state_add(SPARC_ET, "ET", m_et).formatstr("%1u"); state_add(SPARC_PIL, "PIL", m_pil).formatstr("%2d"); - state_add(SPARC_S, "S", m_s).formatstr("%1d"); - state_add(SPARC_PS, "PS", m_ps).formatstr("%1d"); + state_add(SPARC_S, "S", m_s).formatstr("%1u"); + state_add(SPARC_PS, "PS", m_ps).formatstr("%1u"); char rname[5]; for (int i = 0; i < 120; i++) @@ -520,36 +519,15 @@ void mb86901_device::state_string_export(const device_state_entry &entry, std::s //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t mb86901_device::disasm_min_opcode_bytes() const -{ - return 4; -} - - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t mb86901_device::disasm_max_opcode_bytes() const -{ - return 4; -} - - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t mb86901_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *mb86901_device::create_disassembler() { - uint32_t op = *reinterpret_cast<const uint32_t *>(oprom); - return m_dasm.dasm(stream, pc, big_endianize_int32(op)); + auto dasm = new sparc_disassembler(this, 7); + m_asi_desc_adder(dasm); + return dasm; } diff --git a/src/devices/cpu/sparc/sparc.h b/src/devices/cpu/sparc/sparc.h index 5355a2ed005..8d91183ee1a 100644 --- a/src/devices/cpu/sparc/sparc.h +++ b/src/devices/cpu/sparc/sparc.h @@ -20,9 +20,9 @@ // TODO: when there are more SPARC CPUs, move setter to a base class #define MCFG_SPARC_ADD_ASI_DESC(desc) \ - mb86901_device::add_asi_desc(*device, desc); + mb86901_device::add_asi_desc(*device, [](sparc_disassembler *dasm) { dasm->add_asi_desc(desc); }); -class mb86901_device : public cpu_device, protected sparc_debug_state +class mb86901_device : public cpu_device, protected sparc_disassembler::config { public: mb86901_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); @@ -43,9 +43,7 @@ public: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // device_state_interface overrides virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; @@ -53,7 +51,7 @@ public: uint8_t get_asi() { return m_asi; } uint32_t pc() { return m_pc; } - template<typename T> static void add_asi_desc(device_t &device, const T &desc) { return downcast<mb86901_device &>(device).add_asi_desc(desc); } + static void add_asi_desc(device_t &device, std::function<void (sparc_disassembler *)> f) { downcast<mb86901_device &>(device).m_asi_desc_adder = f; } #if LOG_FCODES void enable_log_fcodes(bool enable) { m_log_fcodes = enable; } @@ -62,8 +60,6 @@ public: #endif protected: - template<typename T> void add_asi_desc(const T &desc) { m_dasm.add_asi_desc(desc); } - void update_gpr_pointers(); void execute_add(uint32_t op); @@ -213,7 +209,6 @@ protected: // debugger helpers uint32_t m_dbgregs[24]; - sparc_disassembler m_dasm; // address spaces address_space *m_program; @@ -230,6 +225,8 @@ protected: // processor configuration static const int NWINDOWS; + + std::function<void (sparc_disassembler *)> m_asi_desc_adder; }; // device type definition diff --git a/src/devices/cpu/sparc/sparcdasm.cpp b/src/devices/cpu/sparc/sparcdasm.cpp index 296c987a467..584b5ab427a 100644 --- a/src/devices/cpu/sparc/sparcdasm.cpp +++ b/src/devices/cpu/sparc/sparcdasm.cpp @@ -17,10 +17,10 @@ namespace { int32_t get_disp19(uint32_t op) { return DISP19; } int32_t get_disp22(uint32_t op) { return DISP19; } - const char *bicc_comment(const sparc_debug_state *state, bool use_cc, offs_t pc, uint32_t op) + const char *bicc_comment(const sparc_disassembler::config *conf, bool use_cc, offs_t pc, uint32_t op) { - if (!state || (state->get_translated_pc() != pc)) return nullptr; - auto const cc((use_cc && (BRCC & 0x2)) ? state->get_xcc() : state->get_icc()); + if (!conf || (conf->get_translated_pc() != pc)) return nullptr; + auto const cc((use_cc && (BRCC & 0x2)) ? conf->get_xcc() : conf->get_icc()); switch (COND) { case 0x0: return "will fall through"; @@ -42,10 +42,10 @@ namespace { } return nullptr; } - const char *bfcc_comment(const sparc_debug_state *state, bool use_cc, offs_t pc, uint32_t op) + const char *bfcc_comment(const sparc_disassembler::config *conf, bool use_cc, offs_t pc, uint32_t op) { - if (!state || (state->get_translated_pc() != pc)) return nullptr; - auto const fcc(state->get_fcc(use_cc ? BRCC : 0)); + if (!conf || (conf->get_translated_pc() != pc)) return nullptr; + auto const fcc(conf->get_fcc(use_cc ? BRCC : 0)); switch (COND) { case 0x0: return "will fall through"; @@ -67,10 +67,10 @@ namespace { } return nullptr; } - const char *bpr_comment(const sparc_debug_state *state, bool use_cc, offs_t pc, uint32_t op) + const char *bpr_comment(const sparc_disassembler::config *conf, bool use_cc, offs_t pc, uint32_t op) { - if (!state || (state->get_translated_pc() != pc)) return nullptr; - const int64_t reg(state->get_reg_r(RS1)); + if (!conf || (conf->get_translated_pc() != pc)) return nullptr; + const int64_t reg(conf->get_reg_r(RS1)); switch (COND) { case 1: return (reg == 0) ? "will branch" : "will fall through"; @@ -610,12 +610,12 @@ inline void sparc_disassembler::pad_op_field(std::ostream &stream, std::streampo stream << ' '; } -sparc_disassembler::sparc_disassembler(const sparc_debug_state *state, unsigned version) - : sparc_disassembler(state, version, vis_none) +sparc_disassembler::sparc_disassembler(const config *conf, unsigned version) + : sparc_disassembler(conf, version, vis_none) { } -sparc_disassembler::sparc_disassembler(const sparc_debug_state *state, unsigned version, vis_level vis) +sparc_disassembler::sparc_disassembler(const config *conf, unsigned version, vis_level vis) : m_version(version) , m_vis_level(vis) , m_op_field_width(9) @@ -722,6 +722,15 @@ sparc_disassembler::sparc_disassembler(const sparc_debug_state *state, unsigned } } +u32 sparc_disassembler::opcode_alignment() const +{ + return 4; +} + +offs_t sparc_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + return dasm(stream, pc, opcodes.r32(pc)); +} offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) const { @@ -742,10 +751,10 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co default: return dasm_branch(stream, pc, op); } - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; case 1: util::stream_format(stream, "%-*s%%pc%c0x%08x ! 0x%08x", m_op_field_width, "call", (DISP30 < 0) ? '-' : '+', std::abs(DISP30), pc + DISP30); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; case 2: switch (OP3) { @@ -754,7 +763,7 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co { if (SIMM13 == 1) util::stream_format(stream, "%-*s%s", m_op_field_width, "inc", REG_NAMES[RD]); else util::stream_format(stream, "%-*s%d,%s", m_op_field_width, "inc", SIMM13, REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x02: @@ -763,13 +772,13 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co if (USEIMM) util::stream_format(stream, "%-*s%d,%s", m_op_field_width, "mov", SIMM13, REG_NAMES[RD]); else if (RS2 == 0) util::stream_format(stream, "%-*s%s", m_op_field_width, "clr", REG_NAMES[RD]); else util::stream_format(stream, "%-*s%s,%s", m_op_field_width, "mov", REG_NAMES[RS2], REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } else if (RS1 == RD) { if (USEIMM) util::stream_format(stream, "%-*s0x%08x,%s", m_op_field_width, "bset", SIMM13, REG_NAMES[RD]); else util::stream_format(stream, "%-*s%s,%s", m_op_field_width, "bset", REG_NAMES[RS2], REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x03: @@ -777,7 +786,7 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co { if (USEIMM) util::stream_format(stream, "%-*s0x%08x,%s", m_op_field_width, "btog", SIMM13, REG_NAMES[RD]); else util::stream_format(stream, "%-*s%s,%s", m_op_field_width, "btog", REG_NAMES[RS2], REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x04: @@ -787,7 +796,7 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co { if (SIMM13 == 1) util::stream_format(stream, "%-*s%s", m_op_field_width, "dec", REG_NAMES[RD]); else util::stream_format(stream, "%-*s%d,%s", m_op_field_width, "dec", SIMM13, REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } } else @@ -796,7 +805,7 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co { if (RS2 == RD) util::stream_format(stream, "%-*s%s", m_op_field_width, "neg", REG_NAMES[RD]); else util::stream_format(stream, "%-*s%s,%s", m_op_field_width, "neg", REG_NAMES[RS2], REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } } break; @@ -805,7 +814,7 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co { if (USEIMM) util::stream_format(stream, "%-*s0x%08x,%s", m_op_field_width, "bclr", SIMM13, REG_NAMES[RD]); else util::stream_format(stream, "%-*s%s,%s", m_op_field_width, "bclr", REG_NAMES[RS2], REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x07: @@ -813,7 +822,7 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co { if (RS1 == RD) util::stream_format(stream, "%-*s%s", m_op_field_width, "not", REG_NAMES[RD]); else util::stream_format(stream, "%-*s%s,%s", m_op_field_width, "not", REG_NAMES[RS1], REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x10: @@ -821,14 +830,14 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co { if (SIMM13 == 1) util::stream_format(stream, "%-*s%s", m_op_field_width, "inccc", REG_NAMES[RD]); else util::stream_format(stream, "%-*s%d,%s", m_op_field_width, "inccc", SIMM13, REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x12: if (!USEIMM && (RS1 == 0) && (RD == 0)) { util::stream_format(stream, "%-*s%s", m_op_field_width, "tst", REG_NAMES[RS2]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x14: @@ -836,7 +845,7 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co { if (SIMM13 == 1) util::stream_format(stream, "%-*s%s", m_op_field_width, "deccc", REG_NAMES[RD]); else util::stream_format(stream, "%-*s%d,%s", m_op_field_width, "deccc", SIMM13, REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x25: @@ -851,7 +860,7 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co if (m_version <= 8) { util::stream_format(stream, "%-*s%%psr,%s", m_op_field_width, "rd", REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x2a: @@ -860,13 +869,13 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co if (V9_PRIV_REG_NAMES[RS1]) { util::stream_format(stream, "%-*s%s,%s", m_op_field_width, "rdpr", V9_PRIV_REG_NAMES[RS1], REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } } else { util::stream_format(stream, "%-*s%%wim,%s", m_op_field_width, "rd", REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x2b: @@ -875,13 +884,13 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co if (!USEIMM) { util::stream_format(stream, "flushw"); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } } else { util::stream_format(stream, "%-*s%%tbr,%s", m_op_field_width, "rd", REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x2c: @@ -891,7 +900,7 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co { if (USEIMM) util::stream_format(stream, "%-*s%d,%s", m_op_field_width, "popc", SIMM13, REG_NAMES[RD]); else util::stream_format(stream, "%-*s%s,%s", m_op_field_width, "popc", REG_NAMES[RS2], REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x2f: @@ -905,10 +914,10 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co { case 0: util::stream_format(stream, "saved"); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; case 1: util::stream_format(stream, "restored"); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } } else @@ -923,7 +932,7 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co if (USEIMM) util::stream_format(stream, "%-*s%s,0x%08x,%%psr", m_op_field_width, "wr", REG_NAMES[RS1], SIMM13); else util::stream_format(stream, "%-*s%s,%s,%%psr", m_op_field_width, "wr", REG_NAMES[RS1], REG_NAMES[RS2]); } - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x32: @@ -935,7 +944,7 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co if (!USEIMM) util::stream_format(stream, "%-*s%s,%s,%s", m_op_field_width, "wrpr", REG_NAMES[RS1], REG_NAMES[RS2], V9_PRIV_REG_NAMES[RD]); else if (RS1 == 0) util::stream_format(stream, "%-*s0x%08x,%s", m_op_field_width, "wrpr", SIMM13, V9_PRIV_REG_NAMES[RD]); else util::stream_format(stream, "%-*s%s,0x%08x,%s", m_op_field_width, "wrpr", REG_NAMES[RS1], SIMM13, V9_PRIV_REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } } else @@ -950,7 +959,7 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co if (USEIMM) util::stream_format(stream, "%-*s%s,0x%08x,%%wim", m_op_field_width, "wr", REG_NAMES[RS1], SIMM13); else util::stream_format(stream, "%-*s%s,%s,%%wim", m_op_field_width, "wr", REG_NAMES[RS1], REG_NAMES[RS2]); } - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x33: @@ -966,7 +975,7 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co if (USEIMM) util::stream_format(stream, "%-*s%s,0x%08x,%%tbr", m_op_field_width, "wr", REG_NAMES[RS1], SIMM13); else util::stream_format(stream, "%-*s%s,%s,%%tbr", m_op_field_width, "wr", REG_NAMES[RS1], REG_NAMES[RS2]); } - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x34: @@ -989,21 +998,21 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co { util::stream_format(stream, "%-*s", m_op_field_width, "flush"); dasm_address(stream, op); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x3c: if (!USEIMM && (RS1 == RS2) && (RS2 == RD) && (RD == 0)) { util::stream_format(stream, "save"); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x3d: if (!USEIMM && (RS1 == RS2) && (RS2 == RD) && (RD == 0)) { util::stream_format(stream, "restore"); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x3e: @@ -1011,8 +1020,8 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co { switch (RD) { - case 0: util::stream_format(stream, "done"); return 4 | DASMFLAG_SUPPORTED; - case 1: util::stream_format(stream, "retry"); return 4 | DASMFLAG_SUPPORTED; + case 0: util::stream_format(stream, "done"); return 4 | SUPPORTED; + case 1: util::stream_format(stream, "retry"); return 4 | SUPPORTED; } } break; @@ -1039,7 +1048,7 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co else util::stream_format(stream, "%-*s%s,%d,%s", m_op_field_width, it->second.mnemonic, REG_NAMES[RS1], SIMM13, REG_NAMES[RD]); } - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } } break; @@ -1072,7 +1081,7 @@ offs_t sparc_disassembler::dasm_invalid(std::ostream &stream, offs_t pc, uint32_ { util::stream_format(stream, "op=%x op3=%02x i=%01x rd=%d", OP, OP3, USEIMM, RD); } - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } @@ -1089,10 +1098,10 @@ offs_t sparc_disassembler::dasm_branch(std::ostream &stream, offs_t pc, uint32_t if (OP2 == 3) util::stream_format(stream, "%s,", REG_NAMES[RS1]); const int32_t disp(desc.get_disp(op)); util::stream_format(stream, "%%pc%c0x%0*x ! 0x%08x", (disp < 0) ? '-' : '+', desc.disp_width, std::abs(disp), pc + disp); - //const char * const comment(desc.get_comment ? desc.get_comment(m_state, desc.use_cc, pc, op) : nullptr); + //const char * const comment(desc.get_comment ? desc.get_comment(m_config, desc.use_cc, pc, op) : nullptr); //if (comment) util::stream_format(stream, " - %s", comment); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } @@ -1117,7 +1126,7 @@ offs_t sparc_disassembler::dasm_shift(std::ostream &stream, offs_t pc, uint32_t { util::stream_format(stream, "%-*s%s,%s,%s", m_op_field_width, mnemonic, REG_NAMES[RS1], REG_NAMES[RS2], REG_NAMES[RD]); } - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } @@ -1126,14 +1135,14 @@ offs_t sparc_disassembler::dasm_read_state_reg(std::ostream &stream, offs_t pc, if (RS1 == 0) { util::stream_format(stream, "%-*s%%y,%s", m_op_field_width, "rd", REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } else if ((m_version == 8) || ((m_version >= 9) && !USEIMM)) { if (!USEIMM && (RS1 == 15) && (RD == 0)) { util::stream_format(stream, "stbar"); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } else { @@ -1144,7 +1153,7 @@ offs_t sparc_disassembler::dasm_read_state_reg(std::ostream &stream, offs_t pc, util::stream_format(stream, "%-*s%s,%s", m_op_field_width, "rd", it->second.read_name, REG_NAMES[RD]); else util::stream_format(stream, "%-*s%%asr%d,%s ! %s", m_op_field_width, "rd", RS1, REG_NAMES[RD], (RS1 < 16) ? "reserved" : "implementation-dependent"); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } } } @@ -1166,7 +1175,7 @@ offs_t sparc_disassembler::dasm_read_state_reg(std::ostream &stream, offs_t pc, if (mask & 1) util::stream_format(stream, "#MemIssue%s", (mask >> 1) ? "|" : ""); mask >>= 1; if (mask & 1) util::stream_format(stream, "#Sync"); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } return dasm_invalid(stream, pc, op); } @@ -1186,14 +1195,14 @@ offs_t sparc_disassembler::dasm_write_state_reg(std::ostream &stream, offs_t pc, if (USEIMM) util::stream_format(stream, "%-*s%s,%08x,%%y", m_op_field_width, "wr", REG_NAMES[RS1], SIMM13); else util::stream_format(stream, "%-*s%s,%s,%%y", m_op_field_width, "wr", REG_NAMES[RS1], REG_NAMES[RS2]); } - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } else if (m_version >= 8) { if ((m_version >= 9) && USEIMM && (RS1 == 0) && (RD == 15)) { util::stream_format(stream, "%-*s%d", m_op_field_width, "sir", SIMM13); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } else { @@ -1227,7 +1236,7 @@ offs_t sparc_disassembler::dasm_write_state_reg(std::ostream &stream, offs_t pc, else util::stream_format(stream, "%-*s%s,%s,%%asr%d ! %s", m_op_field_width, "wr", REG_NAMES[RS1], REG_NAMES[RS2], RD, comment); } } - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } } } @@ -1247,7 +1256,7 @@ offs_t sparc_disassembler::dasm_move_cond(std::ostream &stream, offs_t pc, uint3 else util::stream_format(stream, "%s,%s,%s", MOVCC_CC_NAMES[MOVCC], REG_NAMES[RS2], REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } offs_t sparc_disassembler::dasm_move_reg_cond(std::ostream &stream, offs_t pc, uint32_t op) const @@ -1259,7 +1268,7 @@ offs_t sparc_disassembler::dasm_move_reg_cond(std::ostream &stream, offs_t pc, u else util::stream_format(stream, "%-*s%s,%s,%s", m_op_field_width, MOVE_INT_COND_MNEMONICS[RCOND], REG_NAMES[RS1], REG_NAMES[RS2], REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } @@ -1272,7 +1281,7 @@ offs_t sparc_disassembler::dasm_fpop1(std::ostream &stream, offs_t pc, uint32_t util::stream_format(stream, "%-*s%%f%d,%%f%d,%%f%d", m_op_field_width, it->second.mnemonic, freg(RS1, it->second.rs1_shift), freg(RS2, it->second.rs2_shift), freg(RD, it->second.rd_shift)); else util::stream_format(stream, "%-*s%%f%d,%%f%d", m_op_field_width, it->second.mnemonic, freg(RS2, it->second.rs2_shift), freg(RD, it->second.rd_shift)); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } @@ -1296,7 +1305,7 @@ offs_t sparc_disassembler::dasm_fpop2(std::ostream &stream, offs_t pc, uint32_t util::stream_format(stream, "%s%s", mnemonic, MOVCC_COND_NAMES[MOVCOND | ((OPFCC << 2) & 16)]); pad_op_field(stream, start_position); util::stream_format(stream, "%s,%%f%d,%%f%d", MOVCC_CC_NAMES[OPFCC], freg(RS2, shift), freg(RD, shift)); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } } @@ -1308,18 +1317,18 @@ offs_t sparc_disassembler::dasm_fpop2(std::ostream &stream, offs_t pc, uint32_t if (it->second.int_rs1) { util::stream_format(stream, "%-*s%s,%%f%d,%%f%d", m_op_field_width, it->second.mnemonic, REG_NAMES[RS1], freg(RS2, it->second.shift), freg(RD, it->second.shift)); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } else if (RD < 4) { util::stream_format(stream, "%-*s%%fcc%d,%%f%d,%%f%d", m_op_field_width, it->second.mnemonic, RD, freg(RS1, it->second.shift), freg(RS2, it->second.shift)); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } } else if (!it->second.int_rs1) { util::stream_format(stream, "%-*s%%f%d,%%f%d", m_op_field_width, it->second.mnemonic, freg(RS1, it->second.shift), freg(RS2, it->second.shift)); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } } @@ -1348,7 +1357,7 @@ offs_t sparc_disassembler::dasm_impdep1(std::ostream &stream, offs_t pc, uint32_ dasm_vis_arg(stream, args, it->second.rs2, RS2); } dasm_vis_arg(stream, args, it->second.rd, RD); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } switch (OPF) @@ -1357,7 +1366,7 @@ offs_t sparc_disassembler::dasm_impdep1(std::ostream &stream, offs_t pc, uint32_ if (m_vis_level >= vis_2) { util::stream_format(stream, "%-*s0x%x", m_op_field_width, "siam", IAMODE); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x151: @@ -1366,7 +1375,7 @@ offs_t sparc_disassembler::dasm_impdep1(std::ostream &stream, offs_t pc, uint32_ { const bool shift(OPF == 0x152); util::stream_format(stream, "%-*s%%fcc%d,%%f%d,%%f%d", m_op_field_width, (shift) ? "flcmpd" : "flcmps", RD & 3, freg(RS1, shift), freg(RS2, shift)); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; } @@ -1390,7 +1399,7 @@ offs_t sparc_disassembler::dasm_jmpl(std::ostream &stream, offs_t pc, uint32_t o if ((RD != 0) && (RD != 15)) util::stream_format(stream, ",%s", REG_NAMES[RD]); } - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } @@ -1398,7 +1407,7 @@ offs_t sparc_disassembler::dasm_return(std::ostream &stream, offs_t pc, uint32_t { util::stream_format(stream, "%-*s", m_op_field_width, (m_version >= 9) ? "return" : "rett"); dasm_address(stream, op); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } @@ -1431,7 +1440,7 @@ offs_t sparc_disassembler::dasm_tcc(std::ostream &stream, offs_t pc, uint32_t op else if (RS2 == 0) util::stream_format(stream, "%s", REG_NAMES[RS1]); else util::stream_format(stream, "%s,%s", REG_NAMES[RS1], REG_NAMES[RS2]); } - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } @@ -1447,7 +1456,7 @@ offs_t sparc_disassembler::dasm_ldst(std::ostream &stream, offs_t pc, uint32_t o util::stream_format(stream, "%-*s[", m_op_field_width, (RD == 1) ? "ldx" : "ld"); dasm_address(stream, op); util::stream_format(stream, "],%%fsr"); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } else if ((RD == 3) && (m_vis_level >= vis_3b)) { @@ -1462,7 +1471,7 @@ offs_t sparc_disassembler::dasm_ldst(std::ostream &stream, offs_t pc, uint32_t o util::stream_format(stream, "%-*s%%fsr,[", m_op_field_width, (RD == 1) ? "stx" : "st"); dasm_address(stream, op); stream << ']'; - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x3c: // Compare and swap word in alternate space @@ -1488,7 +1497,7 @@ offs_t sparc_disassembler::dasm_ldst(std::ostream &stream, offs_t pc, uint32_t o util::stream_format(stream, ",%s,%s", REG_NAMES[RS2], REG_NAMES[RD]); if (print_asi) dasm_asi_comment(stream, op); } - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; case 0x2d: // Prefetch data case 0x3d: // Prefetch data from alternate space { @@ -1501,7 +1510,7 @@ offs_t sparc_disassembler::dasm_ldst(std::ostream &stream, offs_t pc, uint32_t o else util::stream_format(stream, ",0x%02x", RD); if (OP3 == 0x3d) dasm_asi_comment(stream, op); } - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } } else @@ -1513,19 +1522,19 @@ offs_t sparc_disassembler::dasm_ldst(std::ostream &stream, offs_t pc, uint32_t o util::stream_format(stream, "%-*s[", m_op_field_width, "ld"); dasm_address(stream, op); util::stream_format(stream, "],%%%csr", (OP3 == 0x31) ? 'c' : 'f'); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; case 0x25: // Store Floating-point State Register case 0x35: // Store Coprocessor State Register util::stream_format(stream, "%-*s%%%csr,[", m_op_field_width, "st", (OP3 == 0x35) ? 'c' : 'f'); dasm_address(stream, op); stream << ']'; - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; case 0x26: // Store Floating-point deferred-trap Queue case 0x36: // Store Coprocessor deferred-trap Queue util::stream_format(stream, "%-*s%%%cq,[", m_op_field_width, "std", (OP3 == 0x36) ? 'c' : 'f'); dasm_address(stream, op); stream << ']'; - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } } @@ -1566,7 +1575,7 @@ offs_t sparc_disassembler::dasm_ldst(std::ostream &stream, offs_t pc, uint32_t o } if (it->second.alternate) dasm_asi_comment(stream, op); } - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } diff --git a/src/devices/cpu/sparc/sparcdasm.h b/src/devices/cpu/sparc/sparcdasm.h index f5643a0e87b..f6f0e7bc27d 100644 --- a/src/devices/cpu/sparc/sparcdasm.h +++ b/src/devices/cpu/sparc/sparcdasm.h @@ -11,24 +11,21 @@ #include <map> - -class sparc_debug_state +class sparc_disassembler : public util::disasm_interface { public: - virtual uint64_t get_reg_r(unsigned index) const = 0; - virtual uint64_t get_translated_pc() const = 0; - virtual uint8_t get_icc() const = 0; - virtual uint8_t get_xcc() const = 0; - virtual uint8_t get_fcc(unsigned index) const = 0; // ?><= - -protected: - ~sparc_debug_state() { } -}; + struct config + { + public: + virtual ~config() = default; + virtual uint64_t get_reg_r(unsigned index) const = 0; + virtual uint64_t get_translated_pc() const = 0; + virtual uint8_t get_icc() const = 0; + virtual uint8_t get_xcc() const = 0; + virtual uint8_t get_fcc(unsigned index) const = 0; // ?><= + }; -class sparc_disassembler -{ -public: enum vis_level { vis_none, vis_1, vis_2, vis_2p, vis_3, vis_3b }; struct asi_desc @@ -58,8 +55,8 @@ public: }; typedef std::map<uint8_t, prftch_desc> prftch_desc_map; - sparc_disassembler(const sparc_debug_state *state, unsigned version); - sparc_disassembler(const sparc_debug_state *state, unsigned version, vis_level vis); + sparc_disassembler(const config *conf, unsigned version); + sparc_disassembler(const config *conf, unsigned version, vis_level vis); template <typename T> void add_state_reg_desc(const T &desc) { @@ -106,13 +103,16 @@ public: } } + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + offs_t dasm(std::ostream &stream, offs_t pc, uint32_t op) const; private: struct branch_desc { int32_t (*get_disp)(uint32_t op); - const char * (*get_comment)(const sparc_debug_state *state, bool use_cc, offs_t pc, uint32_t op); + const char * (*get_comment)(const config *conf, bool use_cc, offs_t pc, uint32_t op); int disp_width; bool use_pred, use_cc; const char *reg_cc[4]; @@ -238,7 +238,7 @@ private: static const vis_op_desc_map::value_type VIS3_OP_DESC[]; static const vis_op_desc_map::value_type VIS3B_OP_DESC[]; - //const sparc_debug_state *m_state; + //const config *m_config; unsigned m_version; vis_level m_vis_level; int m_op_field_width; diff --git a/src/devices/cpu/spc700/spc700.cpp b/src/devices/cpu/spc700/spc700.cpp index cb44ce03c19..07390f03969 100644 --- a/src/devices/cpu/spc700/spc700.cpp +++ b/src/devices/cpu/spc700/spc700.cpp @@ -1353,9 +1353,9 @@ void spc700_device::execute_set_input( int inptnum, int state ) #include "spc700ds.h" -offs_t spc700_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *spc700_device::create_disassembler() { - return CPU_DISASSEMBLE_NAME(spc700)(this, stream, pc, oprom, opram, options); + return new spc700_disassembler; } //int dump_flag = 0; diff --git a/src/devices/cpu/spc700/spc700.h b/src/devices/cpu/spc700/spc700.h index 161ebea347c..6af60c16d8e 100644 --- a/src/devices/cpu/spc700/spc700.h +++ b/src/devices/cpu/spc700/spc700.h @@ -33,9 +33,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 3; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; diff --git a/src/devices/cpu/spc700/spc700ds.cpp b/src/devices/cpu/spc700/spc700ds.cpp index de7accc7cb8..9f220b02e26 100644 --- a/src/devices/cpu/spc700/spc700ds.cpp +++ b/src/devices/cpu/spc700/spc700ds.cpp @@ -15,39 +15,7 @@ All rights reserved. #include "emu.h" #include "spc700ds.h" - - -struct spc700_opcode_struct -{ - unsigned char name; - unsigned char args[2]; -}; - -enum -{ - IMP , A , X , Y , YA , SP , PSW , C , REL , UPAG, IMM , XI , - XII , YI , DP , DPX , DPY , DPI , DXI , DIY , ABS , ABX , ABY , AXI , N0 , - N1 , N2 , N3 , N4 , N5 , N6 , N7 , N8 , N9 , N10 , N11 , N12 , - N13 , N14 , N15 , DP0 , DP1 , DP2 , DP3 , DP4 , DP5 , DP6 , DP7 , MEMN, - MEMI -}; - - -enum -{ - ADC , ADDW , AND , AND1 , ASL , BBC , BBS , BCC , - BCS , BEQ , BMI , BNE , BPL , BRA , BRK , BVC , - BVS , CALL , CBNE , CLR1 , CLRC , CLRP , CLRV , CMP , - CMPW , DAA , DAS , DBNZ , DEC , DECW , DI , DIV , - EI , EOR , EOR1 , INC , INCW , JMP , LSR , MOV , - MOV1 , MOVW , MUL , NOP , NOT1 , NOTQ , NOTC , OR , - OR1 , PCALL , POP , PUSH , RET , RETI , ROL , ROR , - SBC , SET1 , SETC , SETP , SLEEP , STOP , SUBW , TCALL , - TCLR1 , TSET1 , XCN -}; - - -static const char *const g_opnames[] = +const char *const spc700_disassembler::g_opnames[] = { "ADC ", "ADDW ", "AND ", "AND1 ", "ASL ", "BBC ", "BBS ", "BCC ", "BCS ", "BEQ ", "BMI ", "BNE ", "BPL ", "BRA ", "BRK ", "BVC ", @@ -60,7 +28,7 @@ static const char *const g_opnames[] = "TCLR1", "TSET1", "XCN " }; -static const spc700_opcode_struct g_opcodes[256] = +const spc700_disassembler::spc700_opcode_struct spc700_disassembler::g_opcodes[256] = { /* 00 */ {NOP , {IMP , IMP }}, /* 01 */ {TCALL , {N0 , IMP }}, @@ -320,45 +288,44 @@ static const spc700_opcode_struct g_opcodes[256] = /* FF */ {STOP , {IMP , IMP }}, }; -static unsigned int g_pc; -static const uint8_t *rombase; +inline unsigned int spc700_disassembler::read_8_immediate(offs_t &pc, const data_buffer &opcodes) +{ + return opcodes.r8(pc++); +} -static inline unsigned int read_8_immediate(void) +inline unsigned int spc700_disassembler::read_16_immediate(offs_t &pc, const data_buffer &opcodes) { - g_pc++; - return *rombase++; + u16 r = opcodes.r16(pc); + pc += 2; + return r; } -static inline unsigned int read_16_immediate(void) +u32 spc700_disassembler::opcode_alignment() const { - unsigned int result; - g_pc += 2; - result = *rombase++; - return result | (*rombase++ << 8); + return 1; } -CPU_DISASSEMBLE(spc700) +offs_t spc700_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { const spc700_opcode_struct* opcode; uint32_t flags = 0; int var; int i; + offs_t base_pc = pc; - g_pc = pc; - rombase = oprom; - opcode = g_opcodes + read_8_immediate(); + opcode = g_opcodes + read_8_immediate(pc, opcodes); stream << g_opnames[opcode->name] << " "; if (opcode->name == CALL) - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; else if (opcode->name == RET || opcode->name == RETI) - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; if (opcode->args[0] == DP && (opcode->args[1] == DP || opcode->args[1] == IMM)) { - int src = read_8_immediate(); - int dst = read_8_immediate(); + int src = read_8_immediate(pc, opcodes); + int dst = read_8_immediate(pc, opcodes); util::stream_format(stream, "$%02x,%s$%02x", dst, (opcode->args[1] == IMM ? "#" : ""), src); } else for(i=0;i<2;i++) @@ -378,22 +345,22 @@ CPU_DISASSEMBLE(spc700) case SP: util::stream_format(stream, "SP"); break; case PSW: util::stream_format(stream, "PSW"); break; case C: util::stream_format(stream, "C"); break; - case REL: util::stream_format(stream, "%04x", ((g_pc + (char)read_8_immediate())&0xffff)); break; - case UPAG: util::stream_format(stream, "$%02x", read_8_immediate()); break; - case IMM: util::stream_format(stream, "#$%02x", read_8_immediate()); break; + case REL: util::stream_format(stream, "%04x", ((pc + (char)read_8_immediate(pc, opcodes))&0xffff)); break; + case UPAG: util::stream_format(stream, "$%02x", read_8_immediate(pc, opcodes)); break; + case IMM: util::stream_format(stream, "#$%02x", read_8_immediate(pc, opcodes)); break; case XI: util::stream_format(stream, "(X)"); break; case XII: util::stream_format(stream, "(X)+"); break; case YI: util::stream_format(stream, "(Y)"); break; - case DP: util::stream_format(stream, "$%02x", read_8_immediate()); break; - case DPX: util::stream_format(stream, "$%02x+X", read_8_immediate()); break; - case DPY: util::stream_format(stream, "$%02x+Y", read_8_immediate()); break; - case DPI: util::stream_format(stream, "($%02x)", read_8_immediate()); break; - case DXI: util::stream_format(stream, "($%02x+X)", read_8_immediate()); break; - case DIY: util::stream_format(stream, "($%02x)+Y", read_8_immediate()); break; - case ABS: util::stream_format(stream, "$%04x", read_16_immediate()); break; - case ABX: util::stream_format(stream, "$%04x+X", read_16_immediate()); break; - case ABY: util::stream_format(stream, "$%04x+Y", read_16_immediate()); break; - case AXI: util::stream_format(stream, "($%04x+X)", read_16_immediate()); break; + case DP: util::stream_format(stream, "$%02x", read_8_immediate(pc, opcodes)); break; + case DPX: util::stream_format(stream, "$%02x+X", read_8_immediate(pc, opcodes)); break; + case DPY: util::stream_format(stream, "$%02x+Y", read_8_immediate(pc, opcodes)); break; + case DPI: util::stream_format(stream, "($%02x)", read_8_immediate(pc, opcodes)); break; + case DXI: util::stream_format(stream, "($%02x+X)", read_8_immediate(pc, opcodes)); break; + case DIY: util::stream_format(stream, "($%02x)+Y", read_8_immediate(pc, opcodes)); break; + case ABS: util::stream_format(stream, "$%04x", read_16_immediate(pc, opcodes)); break; + case ABX: util::stream_format(stream, "$%04x+X", read_16_immediate(pc, opcodes)); break; + case ABY: util::stream_format(stream, "$%04x+Y", read_16_immediate(pc, opcodes)); break; + case AXI: util::stream_format(stream, "($%04x+X)", read_16_immediate(pc, opcodes)); break; case N0: util::stream_format(stream, "0"); break; case N1: util::stream_format(stream, "1"); break; case N2: util::stream_format(stream, "2"); break; @@ -410,23 +377,23 @@ CPU_DISASSEMBLE(spc700) case N13: util::stream_format(stream, "13"); break; case N14: util::stream_format(stream, "14"); break; case N15: util::stream_format(stream, "15"); break; - case DP0: util::stream_format(stream, "$%02x.0", read_8_immediate()); break; - case DP1: util::stream_format(stream, "$%02x.1", read_8_immediate()); break; - case DP2: util::stream_format(stream, "$%02x.2", read_8_immediate()); break; - case DP3: util::stream_format(stream, "$%02x.3", read_8_immediate()); break; - case DP4: util::stream_format(stream, "$%02x.4", read_8_immediate()); break; - case DP5: util::stream_format(stream, "$%02x.5", read_8_immediate()); break; - case DP6: util::stream_format(stream, "$%02x.6", read_8_immediate()); break; - case DP7: util::stream_format(stream, "$%02x.7", read_8_immediate()); break; + case DP0: util::stream_format(stream, "$%02x.0", read_8_immediate(pc, opcodes)); break; + case DP1: util::stream_format(stream, "$%02x.1", read_8_immediate(pc, opcodes)); break; + case DP2: util::stream_format(stream, "$%02x.2", read_8_immediate(pc, opcodes)); break; + case DP3: util::stream_format(stream, "$%02x.3", read_8_immediate(pc, opcodes)); break; + case DP4: util::stream_format(stream, "$%02x.4", read_8_immediate(pc, opcodes)); break; + case DP5: util::stream_format(stream, "$%02x.5", read_8_immediate(pc, opcodes)); break; + case DP6: util::stream_format(stream, "$%02x.6", read_8_immediate(pc, opcodes)); break; + case DP7: util::stream_format(stream, "$%02x.7", read_8_immediate(pc, opcodes)); break; case MEMN: - var = read_16_immediate(); + var = read_16_immediate(pc, opcodes); util::stream_format(stream, "%04x.%d", var&0x1fff, var>>13); break; case MEMI: - var = read_16_immediate(); + var = read_16_immediate(pc, opcodes); util::stream_format(stream, "/%04x.%d", var&0x1fff, var>>13); break; } } - return (g_pc - pc) | flags | DASMFLAG_SUPPORTED; + return (pc - base_pc) | flags | SUPPORTED; } diff --git a/src/devices/cpu/spc700/spc700ds.h b/src/devices/cpu/spc700/spc700ds.h index e2135526363..fdd7bbeba7b 100644 --- a/src/devices/cpu/spc700/spc700ds.h +++ b/src/devices/cpu/spc700/spc700ds.h @@ -17,8 +17,49 @@ All rights reserved. */ +class spc700_disassembler : public util::disasm_interface +{ +public: + spc700_disassembler() = default; + virtual ~spc700_disassembler() = default; -CPU_DISASSEMBLE( spc700 ); + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + struct spc700_opcode_struct + { + unsigned char name; + unsigned char args[2]; + }; + + enum + { + IMP , A , X , Y , YA , SP , PSW , C , REL , UPAG, IMM , XI , + XII , YI , DP , DPX , DPY , DPI , DXI , DIY , ABS , ABX , ABY , AXI , N0 , + N1 , N2 , N3 , N4 , N5 , N6 , N7 , N8 , N9 , N10 , N11 , N12 , + N13 , N14 , N15 , DP0 , DP1 , DP2 , DP3 , DP4 , DP5 , DP6 , DP7 , MEMN, + MEMI + }; + + enum + { + ADC , ADDW , AND , AND1 , ASL , BBC , BBS , BCC , + BCS , BEQ , BMI , BNE , BPL , BRA , BRK , BVC , + BVS , CALL , CBNE , CLR1 , CLRC , CLRP , CLRV , CMP , + CMPW , DAA , DAS , DBNZ , DEC , DECW , DI , DIV , + EI , EOR , EOR1 , INC , INCW , JMP , LSR , MOV , + MOV1 , MOVW , MUL , NOP , NOT1 , NOTQ , NOTC , OR , + OR1 , PCALL , POP , PUSH , RET , RETI , ROL , ROR , + SBC , SET1 , SETC , SETP , SLEEP , STOP , SUBW , TCALL , + TCLR1 , TSET1 , XCN + }; + + static const char *const g_opnames[]; + static const spc700_opcode_struct g_opcodes[256]; + static inline unsigned int read_8_immediate(offs_t &pc, const data_buffer &opcodes); + static inline unsigned int read_16_immediate(offs_t &pc, const data_buffer &opcodes); +}; #endif /* __SPC700DS_H__ */ diff --git a/src/devices/cpu/ssem/ssem.cpp b/src/devices/cpu/ssem/ssem.cpp index 69c6ce66571..6cfffaef83d 100644 --- a/src/devices/cpu/ssem/ssem.cpp +++ b/src/devices/cpu/ssem/ssem.cpp @@ -9,8 +9,7 @@ #include "emu.h" #include "debugger.h" #include "ssem.h" - -CPU_DISASSEMBLE( ssem ); +#include "ssemdasm.h" #define SSEM_DISASM_ON_UNIMPL 0 @@ -160,36 +159,13 @@ void ssem_device::state_string_export(const device_state_entry &entry, std::stri //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t ssem_device::disasm_min_opcode_bytes() const -{ - return 4; -} - - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t ssem_device::disasm_max_opcode_bytes() const -{ - return 4; -} - - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t ssem_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *ssem_device::create_disassembler() { - extern CPU_DISASSEMBLE( ssem ); - return CPU_DISASSEMBLE_NAME(ssem)(this, stream, pc, oprom, opram, options); + return new ssem_disassembler; } diff --git a/src/devices/cpu/ssem/ssem.h b/src/devices/cpu/ssem/ssem.h index b9485678a18..c6e396307f1 100644 --- a/src/devices/cpu/ssem/ssem.h +++ b/src/devices/cpu/ssem/ssem.h @@ -41,9 +41,7 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // device_state_interface overrides virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; @@ -82,6 +80,4 @@ enum SSEM_HALT }; -CPU_DISASSEMBLE( ssem ); - #endif // MAME_CPU_SSEM_SSEM_H diff --git a/src/devices/cpu/ssem/ssemdasm.cpp b/src/devices/cpu/ssem/ssemdasm.cpp index 8ad79f96d8c..43adb44510b 100644 --- a/src/devices/cpu/ssem/ssemdasm.cpp +++ b/src/devices/cpu/ssem/ssemdasm.cpp @@ -7,8 +7,9 @@ */ #include "emu.h" +#include "ssemdasm.h" -static inline uint32_t reverse(uint32_t v) +inline uint32_t ssem_disassembler::reverse(uint32_t v) { // Taken from http://www-graphics.stanford.edu/~seander/bithacks.html#ReverseParallel // swap odd and even bits @@ -25,8 +26,14 @@ static inline uint32_t reverse(uint32_t v) return v; } -static offs_t ssem_dasm_one(std::ostream &stream, offs_t pc, uint32_t op) +u32 ssem_disassembler::opcode_alignment() const { + return 4; +} + +offs_t ssem_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + uint32_t op = opcodes.r32(pc); uint8_t instr = (reverse(op) >> 13) & 7; uint8_t addr = reverse(op) & 0x1f; @@ -59,16 +66,5 @@ static offs_t ssem_dasm_one(std::ostream &stream, offs_t pc, uint32_t op) break; } - return 4 | DASMFLAG_SUPPORTED; -} - -/*****************************************************************************/ - -CPU_DISASSEMBLE( ssem ) -{ - uint32_t op = (*(uint8_t *)(opram + 0) << 24) | - (*(uint8_t *)(opram + 1) << 16) | - (*(uint8_t *)(opram + 2) << 8) | - (*(uint8_t *)(opram + 3) << 0); - return ssem_dasm_one(stream, pc, op); + return 4 | SUPPORTED; } diff --git a/src/devices/cpu/ssem/ssemdasm.h b/src/devices/cpu/ssem/ssemdasm.h new file mode 100644 index 00000000000..a83e38c6f8f --- /dev/null +++ b/src/devices/cpu/ssem/ssemdasm.h @@ -0,0 +1,28 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + Manchester Small-Scale Experimental Machine (SSEM) disassembler + + Written by Ryan Holtz +*/ + +#ifndef MAME_CPU_SSEM_SSEMDASM_H +#define MAME_CPU_SSEM_SSEMDASM_H + +#pragma once + +class ssem_disassembler : public util::disasm_interface +{ +public: + ssem_disassembler() = default; + virtual ~ssem_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static inline uint32_t reverse(uint32_t v); + +}; + +#endif diff --git a/src/devices/cpu/ssp1601/ssp1601.cpp b/src/devices/cpu/ssp1601/ssp1601.cpp index 0ee9139cc1c..b19766b72c5 100644 --- a/src/devices/cpu/ssp1601/ssp1601.cpp +++ b/src/devices/cpu/ssp1601/ssp1601.cpp @@ -18,6 +18,7 @@ #include "emu.h" #include "ssp1601.h" +#include "ssp1601d.h" #include "debugger.h" @@ -44,8 +45,8 @@ #define PPC m_ppc.w.h -#define FETCH() m_direct->read_word(rPC++ << 1) -#define PROGRAM_WORD(a) m_program->read_word((a) << 1) +#define FETCH() m_direct->read_word(rPC++) +#define PROGRAM_WORD(a) m_program->read_word(a) #define GET_PPC_OFFS() PPC #define REG_READ(r) (((r) <= 4) ? m_gr[r].w.h : (this->*reg_read_handlers[r])(r)) @@ -209,10 +210,9 @@ device_memory_interface::space_config_vector ssp1601_device::memory_space_config } -offs_t ssp1601_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *ssp1601_device::create_disassembler() { - extern CPU_DISASSEMBLE( ssp1601 ); - return CPU_DISASSEMBLE_NAME(ssp1601)(this, stream, pc, oprom, opram, options); + return new ssp1601_disassembler; } @@ -522,7 +522,7 @@ void ssp1601_device::device_start() m_gr[0].w.h = 0xffff; // constant reg m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<-1>(); m_io = &space(AS_IO); state_add( SSP_R0, "REG0", m_gr[0].w.h).formatstr("%04X"); diff --git a/src/devices/cpu/ssp1601/ssp1601.h b/src/devices/cpu/ssp1601/ssp1601.h index 55a1184b5bb..a44615b16f3 100644 --- a/src/devices/cpu/ssp1601/ssp1601.h +++ b/src/devices/cpu/ssp1601/ssp1601.h @@ -43,9 +43,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 4; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -74,7 +72,7 @@ private: int m_g_cycles; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<-1> *m_direct; address_space *m_io; void update_P(); diff --git a/src/devices/cpu/ssp1601/ssp1601d.cpp b/src/devices/cpu/ssp1601/ssp1601d.cpp index 465dd657d90..5b9f3c6ac27 100644 --- a/src/devices/cpu/ssp1601/ssp1601d.cpp +++ b/src/devices/cpu/ssp1601/ssp1601d.cpp @@ -9,10 +9,10 @@ */ #include "emu.h" -#include "debugger.h" +#include "ssp1601d.h" -static const char *const reg[16] = +const char *const ssp1601_disassembler::reg[16] = { "-", "X", "Y", "A", "ST", "STACK", "PC", "P", @@ -20,22 +20,22 @@ static const char *const reg[16] = "EXT4", "EXT5", "EXT6", "AL" }; -static const char *const rij[8] = +const char *const ssp1601_disassembler::rij[8] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" }; -static const char *const modifier[4] = +const char *const ssp1601_disassembler::modifier[4] = { "", "+!", "-", "+" }; -static const char *const modifier_sf[4] = +const char *const ssp1601_disassembler::modifier_sf[4] = { "|00", "|01", "|10", "|11" }; -static const char *const cond[16] = +const char *const ssp1601_disassembler::cond[16] = { "always", "RESERVED", "gpi0", "gpi1", "l", "z", "ov", "n", @@ -43,18 +43,18 @@ static const char *const cond[16] = "RESERVED", "RESERVED", "RESERVED", "RESERVED", }; -static const char *const acc_op[8] = +const char *const ssp1601_disassembler::acc_op[8] = { "ror", "rol", "shr", "shl", "inc", "dec", "neg", "abs" }; // pag. 81 uses different addresses! -static const char *const flag_op[16] = +const char *const ssp1601_disassembler::flag_op[16] = { "?", "?", "resl", "setl", "resie", "setie", "?", "?", "resop", "setop", "?", "?", "?", "?", "res", "set" }; -static const char *const arith_ops[8] = +const char *const ssp1601_disassembler::arith_ops[8] = { "", "add", "", "cmp", "add", "and", "or", "eor" }; @@ -68,27 +68,24 @@ static const char *const arith_ops[8] = #define MODIFIER_LOW MODIFIER((op >> 2) & 3, op&3) #define MODIFIER_HIGH MODIFIER((op >> 6) & 3, (op >> 4)&3) -#define READ_OP_DASM(p) ((base_oprom[p] << 8) | base_oprom[(p) + 1]) - -static char *get_cond(int op) +std::string ssp1601_disassembler::get_cond(int op) { - static char scond[16]; - if (op&0xf0) sprintf(scond, "%s=%i", cond[(op >> 4) & 0xf], BIT_B); - else sprintf(scond, "%s", cond[(op >> 4) & 0xf]); - return scond; + if (op&0xf0) return util::string_format("%s=%i", cond[(op >> 4) & 0xf], BIT_B); + else return util::string_format("%s", cond[(op >> 4) & 0xf]); } +u32 ssp1601_disassembler::opcode_alignment() const +{ + return 1; +} -static unsigned dasm_ssp1601(std::ostream &stream, unsigned pc, const uint8_t *oprom) +offs_t ssp1601_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - const uint8_t *base_oprom; uint16_t op; int size = 1; int flags = 0; - base_oprom = oprom; - - op = READ_OP_DASM(0); + op = opcodes.r16(pc); switch (op >> 9) { @@ -102,7 +99,7 @@ static unsigned dasm_ssp1601(std::ostream &stream, unsigned pc, const uint8_t *o { // ret util::stream_format(stream, "ret"); - flags |= DASMFLAG_STEP_OUT; + flags |= STEP_OUT; } else { @@ -128,7 +125,7 @@ static unsigned dasm_ssp1601(std::ostream &stream, unsigned pc, const uint8_t *o // ldi d, imm case 0x04: - util::stream_format(stream, "ld %s, %X", reg[(op >> 4) & 0xf], READ_OP_DASM(2)); + util::stream_format(stream, "ld %s, %X", reg[(op >> 4) & 0xf], opcodes.r16(pc+1)); size = 2; break; @@ -139,7 +136,7 @@ static unsigned dasm_ssp1601(std::ostream &stream, unsigned pc, const uint8_t *o // ldi (ri), imm case 0x06: - util::stream_format(stream, "ld (%s%s), %X", RIJ, MODIFIER_LOW, READ_OP_DASM(2)); + util::stream_format(stream, "ld (%s%s), %X", RIJ, MODIFIER_LOW, opcodes.r16(pc+1)); size = 2; break; @@ -203,7 +200,7 @@ static unsigned dasm_ssp1601(std::ostream &stream, unsigned pc, const uint8_t *o case 0x54: case 0x64: case 0x74: - util::stream_format(stream, "%si A, %X", arith_ops[op >> 13], READ_OP_DASM(2)); + util::stream_format(stream, "%si A, %X", arith_ops[op >> 13], opcodes.r16(pc+1)); size = 2; break; @@ -244,8 +241,8 @@ static unsigned dasm_ssp1601(std::ostream &stream, unsigned pc, const uint8_t *o // call cond, addr case 0x24: - util::stream_format(stream, "call %s, %X", get_cond(op), READ_OP_DASM(2)); - flags |= DASMFLAG_STEP_OVER; + util::stream_format(stream, "call %s, %X", get_cond(op), opcodes.r16(pc+1)); + flags |= STEP_OVER; size = 2; break; @@ -256,7 +253,7 @@ static unsigned dasm_ssp1601(std::ostream &stream, unsigned pc, const uint8_t *o // bra cond, addr case 0x26: - util::stream_format(stream, "bra %s, %X", get_cond(op), READ_OP_DASM(2)); + util::stream_format(stream, "bra %s, %X", get_cond(op), opcodes.r16(pc+1)); size = 2; break; @@ -285,14 +282,5 @@ static unsigned dasm_ssp1601(std::ostream &stream, unsigned pc, const uint8_t *o break; } - return size | flags | DASMFLAG_SUPPORTED; -} - -// vim:ts=4 - -CPU_DISASSEMBLE( ssp1601 ) -{ - //ssp1601_state_t *ssp1601_state = get_safe_token(device); - - return dasm_ssp1601(stream, pc, oprom); + return size | flags | SUPPORTED; } diff --git a/src/devices/cpu/ssp1601/ssp1601d.h b/src/devices/cpu/ssp1601/ssp1601d.h new file mode 100644 index 00000000000..9c868a5d308 --- /dev/null +++ b/src/devices/cpu/ssp1601/ssp1601d.h @@ -0,0 +1,37 @@ +// license:BSD-3-Clause +// copyright-holders:Pierpaolo Prazzoli,Grazvydas Ignotas +/* + + SSP1601 disassembler + written by Pierpaolo Prazzoli + updated for SSP1601 by Grazvydas Ignotas + +*/ + +#ifndef MAME_CPU_SSP1601_SSP1601DASM_H +#define MAME_CPU_SSP1601_SSP1601DASM_H + +#pragma once + +class ssp1601_disassembler : public util::disasm_interface +{ +public: + ssp1601_disassembler() = default; + virtual ~ssp1601_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *const reg[16]; + static const char *const rij[8]; + static const char *const modifier[4]; + static const char *const modifier_sf[4]; + static const char *const cond[16]; + static const char *const acc_op[8]; + static const char *const flag_op[16]; + static const char *const arith_ops[8]; + static std::string get_cond(int op); +}; + +#endif diff --git a/src/devices/cpu/superfx/sfx_dasm.cpp b/src/devices/cpu/superfx/sfx_dasm.cpp index a4e2855480f..58139452ea2 100644 --- a/src/devices/cpu/superfx/sfx_dasm.cpp +++ b/src/devices/cpu/superfx/sfx_dasm.cpp @@ -1,10 +1,24 @@ // license:BSD-3-Clause // copyright-holders:Ryan Holtz #include "emu.h" -#include "superfx.h" +#include "sfx_dasm.h" -offs_t superfx_dasm_one(std::ostream &stream, offs_t pc, uint8_t op, uint8_t param0, uint8_t param1, uint16_t alt) +superfx_disassembler::superfx_disassembler(config *conf) : m_config(conf) { +} + +u32 superfx_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t superfx_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + uint8_t op = opcodes.r8(pc); + uint8_t param0 = opcodes.r8(pc+1); + uint8_t param1 = opcodes.r8(pc+2); + uint16_t alt = m_config->get_alt(); + uint8_t bytes_consumed = 1; switch(op) @@ -409,5 +423,5 @@ offs_t superfx_dasm_one(std::ostream &stream, offs_t pc, uint8_t op, uint8_t par break; } - return bytes_consumed | DASMFLAG_SUPPORTED; + return bytes_consumed | SUPPORTED; } diff --git a/src/devices/cpu/superfx/sfx_dasm.h b/src/devices/cpu/superfx/sfx_dasm.h new file mode 100644 index 00000000000..4bd324c9e9d --- /dev/null +++ b/src/devices/cpu/superfx/sfx_dasm.h @@ -0,0 +1,36 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz + +#ifndef MAME_CPU_SUPERFX_SFX_DASM_H +#define MAME_CPU_SUPERFX_SFX_DASM_H + +#pragma once + +class superfx_disassembler : public util::disasm_interface +{ +public: + enum { + SUPERFX_SFR_ALT = 0x0300, // ALT Mode, both bits + SUPERFX_SFR_ALT0 = 0x0000, // ALT Mode, no bits + SUPERFX_SFR_ALT1 = 0x0100, // ALT Mode, bit 0 + SUPERFX_SFR_ALT2 = 0x0200, // ALT Mode, bit 1 + SUPERFX_SFR_ALT3 = 0x0300 // ALT Mode, both bits (convenience dupe) + }; + + struct config { + virtual ~config() = default; + + virtual u16 get_alt() const = 0; + }; + + superfx_disassembler(config *conf); + virtual ~superfx_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + config *m_config; +}; + +#endif diff --git a/src/devices/cpu/superfx/superfx.cpp b/src/devices/cpu/superfx/superfx.cpp index 2879a6faeaf..1e203a0a1f3 100644 --- a/src/devices/cpu/superfx/superfx.cpp +++ b/src/devices/cpu/superfx/superfx.cpp @@ -1445,12 +1445,12 @@ void superfx_device::execute_run() } } -offs_t superfx_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +u16 superfx_device::get_alt() const { - uint8_t op = *(uint8_t *)(opram + 0); - uint8_t param0 = *(uint8_t *)(opram + 1); - uint8_t param1 = *(uint8_t *)(opram + 2); - uint16_t alt = m_sfr & SUPERFX_SFR_ALT; + return m_sfr & SUPERFX_SFR_ALT; +} - return superfx_dasm_one(stream, pc, op, param0, param1, alt); +util::disasm_interface *superfx_device::create_disassembler() +{ + return new superfx_disassembler(this); } diff --git a/src/devices/cpu/superfx/superfx.h b/src/devices/cpu/superfx/superfx.h index 172c51eb65b..0bd060bb5fa 100644 --- a/src/devices/cpu/superfx/superfx.h +++ b/src/devices/cpu/superfx/superfx.h @@ -5,6 +5,7 @@ #pragma once +#include "sfx_dasm.h" enum { @@ -92,7 +93,7 @@ enum devcb = &superfx_device::set_out_irq_func(*device, DEVCB_##_devcb); -class superfx_device : public cpu_device +class superfx_device : public cpu_device, public superfx_disassembler::config { public: // construction/destruction @@ -107,6 +108,8 @@ public: int access_ram(); int access_rom(); + virtual u16 get_alt() const override; + protected: // device-level overrides virtual void device_start() override; @@ -126,9 +129,7 @@ protected: virtual void state_export(const device_state_entry &entry) override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 3; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -216,6 +217,4 @@ private: DECLARE_DEVICE_TYPE(SUPERFX, superfx_device) -offs_t superfx_dasm_one(std::ostream &stream, offs_t pc, uint8_t op, uint8_t param0, uint8_t param1, uint16_t alt); - #endif // MAME_CPU_SUPERFX_SUPERFX_H diff --git a/src/devices/cpu/t11/t11.cpp b/src/devices/cpu/t11/t11.cpp index dba6241b553..1747c79b64a 100644 --- a/src/devices/cpu/t11/t11.cpp +++ b/src/devices/cpu/t11/t11.cpp @@ -13,6 +13,7 @@ #include "emu.h" #include "t11.h" +#include "t11dasm.h" #include "debugger.h" @@ -260,7 +261,7 @@ void t11_device::device_start() m_initial_pc = initial_pc[c_initial_mode >> 13]; m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_out_reset_func.resolve_safe(); save_item(NAME(m_ppc.w.l)); @@ -422,9 +423,7 @@ void t11_device::execute_run() } while (m_icount > 0); } - -offs_t t11_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *t11_device::create_disassembler() { - extern CPU_DISASSEMBLE( t11 ); - return CPU_DISASSEMBLE_NAME(t11)(this, stream, pc, oprom, opram, options); + return new t11_disassembler; } diff --git a/src/devices/cpu/t11/t11.h b/src/devices/cpu/t11/t11.h index 47db0a9b144..27f1177b03f 100644 --- a/src/devices/cpu/t11/t11.h +++ b/src/devices/cpu/t11/t11.h @@ -66,9 +66,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 6; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; address_space_config m_program_config; @@ -82,7 +80,7 @@ protected: uint8_t m_irq_state; int m_icount; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; devcb_write_line m_out_reset_func; inline int ROPCODE(); diff --git a/src/devices/cpu/t11/t11dasm.cpp b/src/devices/cpu/t11/t11dasm.cpp index b1936566f9c..c99789163ac 100644 --- a/src/devices/cpu/t11/t11dasm.cpp +++ b/src/devices/cpu/t11/t11dasm.cpp @@ -10,17 +10,18 @@ */ #include "emu.h" -#include "debugger.h" -#include "t11.h" +#include "t11dasm.h" -static const char *const regs[8] = { "R0", "R1", "R2", "R3", "R4", "R5", "SP", "PC" }; +const char *const t11_disassembler::regs[8] = { "R0", "R1", "R2", "R3", "R4", "R5", "SP", "PC" }; -static const uint8_t *rombase; -static offs_t pcbase; - -#define PARAM_WORD(v) ((v) = rombase[pc - pcbase] | (rombase[pc + 1 - pcbase] << 8), pc += 2) +u16 t11_disassembler::r16p(offs_t &pc, const data_buffer &opcodes) +{ + u16 r = opcodes.r16(pc); + pc += 2; + return r; +} -static unsigned MakeEA (char *ea, int lo, unsigned pc, int width) +std::string t11_disassembler::MakeEA (int lo, offs_t &pc, int width, const data_buffer &opcodes) { int reg, pm; @@ -31,71 +32,67 @@ static unsigned MakeEA (char *ea, int lo, unsigned pc, int width) switch ((lo >> 3) & 7) { case 0: - sprintf (ea, "%s", regs[reg]); + return util::string_format ("%s", regs[reg]); break; case 1: - sprintf (ea, "(%s)", regs[reg]); + return util::string_format ("(%s)", regs[reg]); break; case 2: if (reg == 7) { - PARAM_WORD (pm); - sprintf (ea, "#$%0*X", width, pm & ((width == 2) ? 0xff : 0xffff)); + pm = r16p(pc, opcodes); + return util::string_format ("#$%0*X", width, pm & ((width == 2) ? 0xff : 0xffff)); } else { - sprintf (ea, "(%s)+", regs[reg]); + return util::string_format ("(%s)+", regs[reg]); } break; case 3: if (reg == 7) { - PARAM_WORD (pm); - sprintf (ea, "$%04X", pm &= 0xffff); + pm = r16p(pc, opcodes); + return util::string_format ( "$%04X", pm &= 0xffff); } else { - sprintf (ea, "@(%s)+", regs[reg]); + return util::string_format ("@(%s)+", regs[reg]); } break; case 4: - sprintf (ea, "-(%s)", regs[reg]); + return util::string_format ("-(%s)", regs[reg]); break; case 5: - sprintf (ea, "@-(%s)", regs[reg]); + return util::string_format ("@-(%s)", regs[reg]); break; case 6: - PARAM_WORD (pm); - sprintf(ea, "%s$%X(%s)", + pm = r16p(pc, opcodes); + return util::string_format ("%s$%X(%s)", (pm&0x8000)?"-":"", (pm&0x8000)?-(signed short)pm:pm, regs[reg]); break; case 7: - PARAM_WORD (pm); - sprintf(ea, "@%s$%X(%s)", + pm = r16p(pc, opcodes); + return util::string_format ("@%s$%X(%s)", (pm&0x8000)?"-":"", (pm&0x8000)?-(signed short)pm:pm, regs[reg]); break; } - - return pc; + return ""; } -CPU_DISASSEMBLE(t11) +offs_t t11_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - char ea1[32], ea2[32]; - unsigned PC = pc; + offs_t PC = pc; uint16_t op, lo, hi, addr; int16_t offset; uint32_t flags = 0; + std::string ea1, ea2; - rombase = oprom; - pcbase = pc; - - PARAM_WORD(op); + op = r16p(pc, opcodes); lo = op & 077; hi = (op >> 6) & 077; @@ -106,7 +103,7 @@ CPU_DISASSEMBLE(t11) { case 0x00: util::stream_format(stream, "HALT"); break; case 0x01: util::stream_format(stream, "WAIT"); break; - case 0x02: util::stream_format(stream, "RTI"); flags = DASMFLAG_STEP_OUT; break; + case 0x02: util::stream_format(stream, "RTI"); flags = STEP_OUT; break; case 0x03: util::stream_format(stream, "BPT"); break; case 0x04: util::stream_format(stream, "IOT"); break; case 0x05: util::stream_format(stream, "RESET"); break; @@ -115,7 +112,7 @@ CPU_DISASSEMBLE(t11) } break; case 0x0040: - pc = MakeEA (ea1, lo, pc, 4); + ea1 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "JMP %s", ea1); break; case 0x0080: @@ -126,7 +123,7 @@ CPU_DISASSEMBLE(t11) util::stream_format(stream, "RTS"); else util::stream_format(stream, "RTS %s", regs[lo & 7]); - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; case 040: case 050: @@ -157,7 +154,7 @@ CPU_DISASSEMBLE(t11) } break; case 0x00c0: - pc = MakeEA (ea1, lo, pc, 4); + ea1 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "SWAB %s", ea1); break; case 0x0100: case 0x0140: case 0x0180: case 0x01c0: @@ -190,66 +187,66 @@ CPU_DISASSEMBLE(t11) break; case 0x0800: case 0x0840: case 0x0880: case 0x08c0: case 0x0900: case 0x0940: case 0x0980: case 0x09c0: - pc = MakeEA (ea1, lo, pc, 4); + ea1 = MakeEA (lo, pc, 4, opcodes); if ( (hi & 7) == 7 ) util::stream_format(stream, "JSR %s", ea1); else util::stream_format(stream, "JSR %s,%s", regs[hi & 7], ea1); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case 0x0a00: - pc = MakeEA (ea1, lo, pc, 4); + ea1 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "CLR %s", ea1); break; case 0x0a40: - pc = MakeEA (ea1, lo, pc, 4); + ea1 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "COM %s", ea1); break; case 0x0a80: - pc = MakeEA (ea1, lo, pc, 4); + ea1 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "INC %s", ea1); break; case 0x0ac0: - pc = MakeEA (ea1, lo, pc, 4); + ea1 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "DEC %s", ea1); break; case 0x0b00: - pc = MakeEA (ea1, lo, pc, 4); + ea1 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "NEG %s", ea1); break; case 0x0b40: - pc = MakeEA (ea1, lo, pc, 4); + ea1 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "ADC %s", ea1); break; case 0x0b80: - pc = MakeEA (ea1, lo, pc, 4); + ea1 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "SBC %s", ea1); break; case 0x0bc0: - pc = MakeEA (ea1, lo, pc, 4); + ea1 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "TST %s", ea1); break; case 0x0c00: - pc = MakeEA (ea1, lo, pc, 4); + ea1 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "ROR %s", ea1); break; case 0x0c40: - pc = MakeEA (ea1, lo, pc, 4); + ea1 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "ROL %s", ea1); break; case 0x0c80: - pc = MakeEA (ea1, lo, pc, 4); + ea1 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "ASR %s", ea1); break; case 0x0cc0: - pc = MakeEA (ea1, lo, pc, 4); + ea1 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "ASL %s", ea1); break; /* case 0x0d00: util::stream_format(stream, "MARK #$%X", lo); break;*/ case 0x0dc0: - pc = MakeEA (ea1, lo, pc, 4); + ea1 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "SXT %s", ea1); break; case 0x1000: case 0x1040: case 0x1080: case 0x10c0: case 0x1100: case 0x1140: case 0x1180: case 0x11c0: @@ -260,8 +257,8 @@ CPU_DISASSEMBLE(t11) case 0x1a00: case 0x1a40: case 0x1a80: case 0x1ac0: case 0x1b00: case 0x1b40: case 0x1b80: case 0x1bc0: case 0x1c00: case 0x1c40: case 0x1c80: case 0x1cc0: case 0x1d00: case 0x1d40: case 0x1d80: case 0x1dc0: case 0x1e00: case 0x1e40: case 0x1e80: case 0x1ec0: case 0x1f00: case 0x1f40: case 0x1f80: case 0x1fc0: - pc = MakeEA (ea1, hi, pc, 4); - pc = MakeEA (ea2, lo, pc, 4); + ea1 = MakeEA (hi, pc, 4, opcodes); + ea2 = MakeEA (lo, pc, 4, opcodes); if (lo == 046) /* MOV src,-(SP) */ util::stream_format(stream, "PUSH %s", ea1); else @@ -278,8 +275,8 @@ CPU_DISASSEMBLE(t11) case 0x2a00: case 0x2a40: case 0x2a80: case 0x2ac0: case 0x2b00: case 0x2b40: case 0x2b80: case 0x2bc0: case 0x2c00: case 0x2c40: case 0x2c80: case 0x2cc0: case 0x2d00: case 0x2d40: case 0x2d80: case 0x2dc0: case 0x2e00: case 0x2e40: case 0x2e80: case 0x2ec0: case 0x2f00: case 0x2f40: case 0x2f80: case 0x2fc0: - pc = MakeEA (ea1, hi, pc, 4); - pc = MakeEA (ea2, lo, pc, 4); + ea1 = MakeEA (hi, pc, 4, opcodes); + ea2 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "CMP %s,%s", ea1, ea2); break; case 0x3000: case 0x3040: case 0x3080: case 0x30c0: case 0x3100: case 0x3140: case 0x3180: case 0x31c0: @@ -290,8 +287,8 @@ CPU_DISASSEMBLE(t11) case 0x3a00: case 0x3a40: case 0x3a80: case 0x3ac0: case 0x3b00: case 0x3b40: case 0x3b80: case 0x3bc0: case 0x3c00: case 0x3c40: case 0x3c80: case 0x3cc0: case 0x3d00: case 0x3d40: case 0x3d80: case 0x3dc0: case 0x3e00: case 0x3e40: case 0x3e80: case 0x3ec0: case 0x3f00: case 0x3f40: case 0x3f80: case 0x3fc0: - pc = MakeEA (ea1, hi, pc, 4); - pc = MakeEA (ea2, lo, pc, 4); + ea1 = MakeEA (hi, pc, 4, opcodes); + ea2 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "BIT %s,%s", ea1, ea2); break; case 0x4000: case 0x4040: case 0x4080: case 0x40c0: case 0x4100: case 0x4140: case 0x4180: case 0x41c0: @@ -302,8 +299,8 @@ CPU_DISASSEMBLE(t11) case 0x4a00: case 0x4a40: case 0x4a80: case 0x4ac0: case 0x4b00: case 0x4b40: case 0x4b80: case 0x4bc0: case 0x4c00: case 0x4c40: case 0x4c80: case 0x4cc0: case 0x4d00: case 0x4d40: case 0x4d80: case 0x4dc0: case 0x4e00: case 0x4e40: case 0x4e80: case 0x4ec0: case 0x4f00: case 0x4f40: case 0x4f80: case 0x4fc0: - pc = MakeEA (ea1, hi, pc, 4); - pc = MakeEA (ea2, lo, pc, 4); + ea1 = MakeEA (hi, pc, 4, opcodes); + ea2 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "BIC %s,%s", ea1, ea2); break; case 0x5000: case 0x5040: case 0x5080: case 0x50c0: case 0x5100: case 0x5140: case 0x5180: case 0x51c0: @@ -314,8 +311,8 @@ CPU_DISASSEMBLE(t11) case 0x5a00: case 0x5a40: case 0x5a80: case 0x5ac0: case 0x5b00: case 0x5b40: case 0x5b80: case 0x5bc0: case 0x5c00: case 0x5c40: case 0x5c80: case 0x5cc0: case 0x5d00: case 0x5d40: case 0x5d80: case 0x5dc0: case 0x5e00: case 0x5e40: case 0x5e80: case 0x5ec0: case 0x5f00: case 0x5f40: case 0x5f80: case 0x5fc0: - pc = MakeEA (ea1, hi, pc, 4); - pc = MakeEA (ea2, lo, pc, 4); + ea1 = MakeEA (hi, pc, 4, opcodes); + ea2 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "BIS %s,%s", ea1, ea2); break; case 0x6000: case 0x6040: case 0x6080: case 0x60c0: case 0x6100: case 0x6140: case 0x6180: case 0x61c0: @@ -326,13 +323,13 @@ CPU_DISASSEMBLE(t11) case 0x6a00: case 0x6a40: case 0x6a80: case 0x6ac0: case 0x6b00: case 0x6b40: case 0x6b80: case 0x6bc0: case 0x6c00: case 0x6c40: case 0x6c80: case 0x6cc0: case 0x6d00: case 0x6d40: case 0x6d80: case 0x6dc0: case 0x6e00: case 0x6e40: case 0x6e80: case 0x6ec0: case 0x6f00: case 0x6f40: case 0x6f80: case 0x6fc0: - pc = MakeEA (ea1, hi, pc, 4); - pc = MakeEA (ea2, lo, pc, 4); + ea1 = MakeEA (hi, pc, 4, opcodes); + ea2 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "ADD %s,%s", ea1, ea2); break; case 0x7800: case 0x7840: case 0x7880: case 0x78c0: case 0x7900: case 0x7940: case 0x7980: case 0x79c0: - pc = MakeEA (ea1, lo, pc, 4); + ea1 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "XOR %s,%s", regs[hi & 7], ea1); break; @@ -381,59 +378,59 @@ CPU_DISASSEMBLE(t11) break; case 0x8a00: - pc = MakeEA (ea1, lo, pc, 2); + ea1 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "CLRB %s", ea1); break; case 0x8a40: - pc = MakeEA (ea1, lo, pc, 2); + ea1 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "COMB %s", ea1); break; case 0x8a80: - pc = MakeEA (ea1, lo, pc, 2); + ea1 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "INCB %s", ea1); break; case 0x8ac0: - pc = MakeEA (ea1, lo, pc, 2); + ea1 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "DECB %s", ea1); break; case 0x8b00: - pc = MakeEA (ea1, lo, pc, 2); + ea1 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "NEGB %s", ea1); break; case 0x8b40: - pc = MakeEA (ea1, lo, pc, 2); + ea1 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "ADCB %s", ea1); break; case 0x8b80: - pc = MakeEA (ea1, lo, pc, 2); + ea1 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "SBCB %s", ea1); break; case 0x8bc0: - pc = MakeEA (ea1, lo, pc, 2); + ea1 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "TSTB %s", ea1); break; case 0x8c00: - pc = MakeEA (ea1, lo, pc, 2); + ea1 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "RORB %s", ea1); break; case 0x8c40: - pc = MakeEA (ea1, lo, pc, 2); + ea1 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "ROLB %s", ea1); break; case 0x8c80: - pc = MakeEA (ea1, lo, pc, 2); + ea1 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "ASRB %s", ea1); break; case 0x8cc0: - pc = MakeEA (ea1, lo, pc, 2); + ea1 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "ASLB %s", ea1); break; case 0x8d00: - pc = MakeEA (ea1, lo, pc, 2); + ea1 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "MTPS %s", ea1); break; case 0x8dc0: - pc = MakeEA (ea1, lo, pc, 2); + ea1 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "MFPS %s", ea1); break; case 0x9000: case 0x9040: case 0x9080: case 0x90c0: case 0x9100: case 0x9140: case 0x9180: case 0x91c0: @@ -444,8 +441,8 @@ CPU_DISASSEMBLE(t11) case 0x9a00: case 0x9a40: case 0x9a80: case 0x9ac0: case 0x9b00: case 0x9b40: case 0x9b80: case 0x9bc0: case 0x9c00: case 0x9c40: case 0x9c80: case 0x9cc0: case 0x9d00: case 0x9d40: case 0x9d80: case 0x9dc0: case 0x9e00: case 0x9e40: case 0x9e80: case 0x9ec0: case 0x9f00: case 0x9f40: case 0x9f80: case 0x9fc0: - pc = MakeEA (ea1, hi, pc, 2); - pc = MakeEA (ea2, lo, pc, 2); + ea1 = MakeEA (hi, pc, 2, opcodes); + ea2 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "MOVB %s,%s", ea1, ea2); break; case 0xa000: case 0xa040: case 0xa080: case 0xa0c0: case 0xa100: case 0xa140: case 0xa180: case 0xa1c0: @@ -456,8 +453,8 @@ CPU_DISASSEMBLE(t11) case 0xaa00: case 0xaa40: case 0xaa80: case 0xaac0: case 0xab00: case 0xab40: case 0xab80: case 0xabc0: case 0xac00: case 0xac40: case 0xac80: case 0xacc0: case 0xad00: case 0xad40: case 0xad80: case 0xadc0: case 0xae00: case 0xae40: case 0xae80: case 0xaec0: case 0xaf00: case 0xaf40: case 0xaf80: case 0xafc0: - pc = MakeEA (ea1, hi, pc, 2); - pc = MakeEA (ea2, lo, pc, 2); + ea1 = MakeEA (hi, pc, 2, opcodes); + ea2 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "CMPB %s,%s", ea1, ea2); break; case 0xb000: case 0xb040: case 0xb080: case 0xb0c0: case 0xb100: case 0xb140: case 0xb180: case 0xb1c0: @@ -468,8 +465,8 @@ CPU_DISASSEMBLE(t11) case 0xba00: case 0xba40: case 0xba80: case 0xbac0: case 0xbb00: case 0xbb40: case 0xbb80: case 0xbbc0: case 0xbc00: case 0xbc40: case 0xbc80: case 0xbcc0: case 0xbd00: case 0xbd40: case 0xbd80: case 0xbdc0: case 0xbe00: case 0xbe40: case 0xbe80: case 0xbec0: case 0xbf00: case 0xbf40: case 0xbf80: case 0xbfc0: - pc = MakeEA (ea1, hi, pc, 2); - pc = MakeEA (ea2, lo, pc, 2); + ea1 = MakeEA (hi, pc, 2, opcodes); + ea2 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "BITB %s,%s", ea1, ea2); break; case 0xc000: case 0xc040: case 0xc080: case 0xc0c0: case 0xc100: case 0xc140: case 0xc180: case 0xc1c0: @@ -480,8 +477,8 @@ CPU_DISASSEMBLE(t11) case 0xca00: case 0xca40: case 0xca80: case 0xcac0: case 0xcb00: case 0xcb40: case 0xcb80: case 0xcbc0: case 0xcc00: case 0xcc40: case 0xcc80: case 0xccc0: case 0xcd00: case 0xcd40: case 0xcd80: case 0xcdc0: case 0xce00: case 0xce40: case 0xce80: case 0xcec0: case 0xcf00: case 0xcf40: case 0xcf80: case 0xcfc0: - pc = MakeEA (ea1, hi, pc, 2); - pc = MakeEA (ea2, lo, pc, 2); + ea1 = MakeEA (hi, pc, 2, opcodes); + ea2 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "BICB %s,%s", ea1, ea2); break; case 0xd000: case 0xd040: case 0xd080: case 0xd0c0: case 0xd100: case 0xd140: case 0xd180: case 0xd1c0: @@ -492,8 +489,8 @@ CPU_DISASSEMBLE(t11) case 0xda00: case 0xda40: case 0xda80: case 0xdac0: case 0xdb00: case 0xdb40: case 0xdb80: case 0xdbc0: case 0xdc00: case 0xdc40: case 0xdc80: case 0xdcc0: case 0xdd00: case 0xdd40: case 0xdd80: case 0xddc0: case 0xde00: case 0xde40: case 0xde80: case 0xdec0: case 0xdf00: case 0xdf40: case 0xdf80: case 0xdfc0: - pc = MakeEA (ea1, hi, pc, 2); - pc = MakeEA (ea2, lo, pc, 2); + ea1 = MakeEA (hi, pc, 2, opcodes); + ea2 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "BISB %s,%s", ea1, ea2); break; case 0xe000: case 0xe040: case 0xe080: case 0xe0c0: case 0xe100: case 0xe140: case 0xe180: case 0xe1c0: @@ -504,8 +501,8 @@ CPU_DISASSEMBLE(t11) case 0xea00: case 0xea40: case 0xea80: case 0xeac0: case 0xeb00: case 0xeb40: case 0xeb80: case 0xebc0: case 0xec00: case 0xec40: case 0xec80: case 0xecc0: case 0xed00: case 0xed40: case 0xed80: case 0xedc0: case 0xee00: case 0xee40: case 0xee80: case 0xeec0: case 0xef00: case 0xef40: case 0xef80: case 0xefc0: - pc = MakeEA (ea1, hi, pc, 4); - pc = MakeEA (ea2, lo, pc, 4); + ea1 = MakeEA (hi, pc, 4, opcodes); + ea2 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "SUB %s,%s", ea1, ea2); break; @@ -514,5 +511,10 @@ CPU_DISASSEMBLE(t11) break; } - return (pc - PC) | flags | DASMFLAG_SUPPORTED; + return (pc - PC) | flags | SUPPORTED; +} + +u32 t11_disassembler::opcode_alignment() const +{ + return 2; } diff --git a/src/devices/cpu/t11/t11dasm.h b/src/devices/cpu/t11/t11dasm.h new file mode 100644 index 00000000000..4d51dd75777 --- /dev/null +++ b/src/devices/cpu/t11/t11dasm.h @@ -0,0 +1,33 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +/* + * A T11 disassembler + * + * Note: this is probably not the most efficient disassembler in the world :-) + * + * This code written by Aaron Giles (agiles@sirius.com) for the MAME project + * + */ + +#ifndef MAME_CPU_T11_T11DASM_H +#define MAME_CPU_T11_T11DASM_H + +#pragma once + +class t11_disassembler : public util::disasm_interface +{ +public: + t11_disassembler() = default; + virtual ~t11_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *const regs[8]; + u16 r16p(offs_t &pc, const data_buffer &opcodes); + std::string MakeEA (int lo, offs_t &pc, int width, const data_buffer &opcodes); + +}; + +#endif diff --git a/src/devices/cpu/tlcs870/tlcs870.cpp b/src/devices/cpu/tlcs870/tlcs870.cpp index c24b41da744..4488ccee744 100644 --- a/src/devices/cpu/tlcs870/tlcs870.cpp +++ b/src/devices/cpu/tlcs870/tlcs870.cpp @@ -16,86 +16,9 @@ #include "emu.h" #include "tlcs870.h" +#include "tlcs870d.h" #include "debugger.h" - -// di, ei, j, and test are just 'alias' opcodes -static const char *const op_names[] = { - "??", - "call", "callp", "callv", "clr", "cpl", - "daa", "das", "dec", /*"di",*/ "div", - /*"ei",*/ - "inc", - /*"j",*/ "jp", "jr", "jrs", - "ld", "ldw", - "mcmp", "mul", - "nop", - "pop", "push", - "ret", "reti", "retn", "rolc", "rold", "rorc", "rord", - "set", "shlc", "shrc", "swap", "swi", - /*"test",*/ "xch", - // ALU operations - "addc", - "add", - "subb", - "sub", - "and", - "xor", - "or", - "cmp", -}; - - - - -static const char *const reg8[] = { - "A", - "W", - "C", - "B", - "E", - "D", - "L", - "H" -}; - -static const char *const type_x[] = { - "(x)", - "(PC+A)", - "(DE)", - "(HL)", - "(HL+d)", - "(HL+C)", - "(HL+)", - "(-HL)", -}; - -static const char *const conditions[] = { - "EQ/Z", - "NE/NZ", - "LT/CS", - "GE/CC", - "LE", - "GT", - "T", - "F", -}; - -static const char *const reg16[] = { - "WA", - "BC", - "DE", - "HL" -}; - -#ifdef UNUSED_DEFINTION -static const char *const reg16p[] = { - "DE", - "HL" -}; -#endif - - #define IS16BIT 0x80 #define BITPOS 0x40 #define BITPOS_INDIRECT 0x20 @@ -2336,71 +2259,6 @@ bool tlcs870_device::stream_arg(std::ostream &stream, uint32_t pc, const char *p return false; } -void tlcs870_device::disasm_disassemble_param(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options, int type, uint16_t val) -{ - int basetype = type & MODE_MASK; - - if (basetype==ADDR_IN_IMM_X) util::stream_format(stream, " ($%02x)", val); // direct - if (basetype==ADDR_IN_PC_PLUS_REG_A) util::stream_format(stream, " %s", type_x[1]); - if (basetype==ADDR_IN_DE) util::stream_format(stream, " %s", type_x[2]); - if (basetype==ADDR_IN_HL) util::stream_format(stream, " %s", type_x[3]); - if (basetype==ADDR_IN_HL_PLUS_IMM_D) util::stream_format(stream, " (HL+$%04x)", val); // todo, sign extend - if (basetype==ADDR_IN_HL_PLUS_REG_C) util::stream_format(stream, " %s", type_x[5]); - if (basetype==ADDR_IN_HLINC) util::stream_format(stream, " %s", type_x[6]); - if (basetype==ADDR_IN_DECHL) util::stream_format(stream, " %s", type_x[7]); - - if (basetype==REG_8BIT) - { - if (type&IS16BIT) util::stream_format(stream, " %s", reg16[val&3]); - else util::stream_format(stream, " %s", reg8[val & 7]); - } - - if (basetype==CONDITIONAL) util::stream_format(stream, " %s", conditions[val]); - if (basetype==(STACKPOINTER & MODE_MASK)) util::stream_format(stream, " SP"); - if (basetype==REGISTERBANK) util::stream_format(stream, " RBS"); - if (basetype==PROGRAMSTATUSWORD) util::stream_format(stream, " PSW"); - if (basetype==MEMVECTOR_16BIT) util::stream_format(stream, " ($%04x)", val); - if (basetype==ABSOLUTE_VAL_8) - { - if (type&IS16BIT) util::stream_format(stream, "$%04x", val); - else util::stream_format(stream, "$%02x", val); - } - - if (basetype == (CARRYFLAG & MODE_MASK)) - { - util::stream_format(stream, " CF"); - } - else if (type&BITPOS) - { - if (type & BITPOS_INDIRECT) util::stream_format(stream, ".BIT_%s", reg8[m_bitpos&7]); - else util::stream_format(stream, ".BIT_%d", m_bitpos); - } -} - -offs_t tlcs870_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) -{ - m_addr = pc; - - decode(); - - util::stream_format (stream, "%-5s", op_names[ m_op ] ); - - if (m_param1_type) - { - disasm_disassemble_param(stream, pc, oprom, opram, options, m_param1_type, m_param1); - } - - if (m_param2_type) - { - if (m_param1_type) util::stream_format(stream, ","); - - disasm_disassemble_param(stream, pc, oprom, opram, options, m_param2_type, m_param2); - - } - - return (m_addr - pc) | DASMFLAG_SUPPORTED; -} - void tlcs870_device::execute_set_input(int inputnum, int state) { #if 0 @@ -3305,3 +3163,8 @@ void tlcs870_device::state_string_export(const device_state_entry &entry, std::s } } + +util::disasm_interface *tlcs870_device::create_disassembler() +{ + return new tlcs870_disassembler; +} diff --git a/src/devices/cpu/tlcs870/tlcs870.h b/src/devices/cpu/tlcs870/tlcs870.h index ea57533e122..ae05b38193f 100644 --- a/src/devices/cpu/tlcs870/tlcs870.h +++ b/src/devices/cpu/tlcs870/tlcs870.h @@ -106,11 +106,7 @@ protected: virtual void state_export(const device_state_entry &entry) override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 6; } - virtual void disasm_disassemble_param(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options, int type, uint16_t val); - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; - + virtual util::disasm_interface *create_disassembler() override; uint32_t m_debugger_temp; diff --git a/src/devices/cpu/tlcs870/tlcs870d.cpp b/src/devices/cpu/tlcs870/tlcs870d.cpp new file mode 100644 index 00000000000..0017caab950 --- /dev/null +++ b/src/devices/cpu/tlcs870/tlcs870d.cpp @@ -0,0 +1,2264 @@ +// license:BSD-3-Clause +// copyright-holders:David Haywood +/************************************************************************************************************* + + Toshiba TLCS-870 Series MCUs + + The TLCS-870/X expands on this instruction set using the same base encoding. + + The TLCS-870/C appears to have a completely different encoding. + + loosely baesd on the tlcs90 core by Luca Elia + +*************************************************************************************************************/ + +#include "emu.h" +#include "tlcs870d.h" + +#define IS16BIT 0x80 +#define BITPOS 0x40 +#define BITPOS_INDIRECT 0x20 + +#define ABSOLUTE_VAL_8 0x01 +#define REG_8BIT 0x02 +#define CONDITIONAL 0x03 +#define STACKPOINTER (0x04 | IS16BIT) // this is a 16-bit reg +#define CARRYFLAG (0x5 | BITPOS) // also flag as BITPOS since it's a bit operation? +#define MEMVECTOR_16BIT 0x6 +#define REGISTERBANK 0x7 +#define PROGRAMSTATUSWORD 0x8 + +#define ABSOLUTE_VAL_16 (ABSOLUTE_VAL_8|IS16BIT) +#define REG_16BIT (REG_8BIT|IS16BIT) + +#define ADDR_IN_BASE 0x10 +#define ADDR_IN_IMM_X (ADDR_IN_BASE+0x0) +#define ADDR_IN_PC_PLUS_REG_A (ADDR_IN_BASE+0x1) +#define ADDR_IN_DE (ADDR_IN_BASE+0x2) +#define ADDR_IN_HL (ADDR_IN_BASE+0x3) +#define ADDR_IN_HL_PLUS_IMM_D (ADDR_IN_BASE+0x4) +#define ADDR_IN_HL_PLUS_REG_C (ADDR_IN_BASE+0x5) +#define ADDR_IN_HLINC (ADDR_IN_BASE+0x6) +#define ADDR_IN_DECHL (ADDR_IN_BASE+0x7) + +#define MODE_MASK 0x1f + +#define FLAG_J (0x80) +#define FLAG_Z (0x40) +#define FLAG_C (0x20) +#define FLAG_H (0x10) + +u32 tlcs870_disassembler::opcode_alignment() const +{ + return 1; +} + + +uint8_t tlcs870_disassembler::READ8() +{ + uint8_t b0 = m_opcodes->r8( m_addr++ ); + m_addr &= 0xffff; + return b0; +} + +uint16_t tlcs870_disassembler::READ16() +{ + uint8_t b0 = READ8(); + return b0 | (READ8() << 8); +} + +// di, ei, j, and test are just 'alias' opcodes +const char *const tlcs870_disassembler::op_names[] = { + "??", + "call", "callp", "callv", "clr", "cpl", + "daa", "das", "dec", /*"di",*/ "div", + /*"ei",*/ + "inc", + /*"j",*/ "jp", "jr", "jrs", + "ld", "ldw", + "mcmp", "mul", + "nop", + "pop", "push", + "ret", "reti", "retn", "rolc", "rold", "rorc", "rord", + "set", "shlc", "shrc", "swap", "swi", + /*"test",*/ "xch", + // ALU operations + "addc", + "add", + "subb", + "sub", + "and", + "xor", + "or", + "cmp", +}; + + + + +const char *const tlcs870_disassembler::reg8[] = { + "A", + "W", + "C", + "B", + "E", + "D", + "L", + "H" +}; + +const char *const tlcs870_disassembler::type_x[] = { + "(x)", + "(PC+A)", + "(DE)", + "(HL)", + "(HL+d)", + "(HL+C)", + "(HL+)", + "(-HL)", +}; + +const char *const tlcs870_disassembler::conditions[] = { + "EQ/Z", + "NE/NZ", + "LT/CS", + "GE/CC", + "LE", + "GT", + "T", + "F", +}; + +const char *const tlcs870_disassembler::reg16[] = { + "WA", + "BC", + "DE", + "HL" +}; + +const char *const tlcs870_disassembler::reg16p[] = { + "DE", + "HL" +}; + +void tlcs870_disassembler::decode() +{ + m_op = 0; + m_param1_type = 0; + m_param1 = 0; + m_param2_type = 0; + m_param2 = 0; + m_bitpos = 0; + m_cycles = 1; + m_flagsaffected = 0; // needed to signal which flags to change and which to leave alone in some cases (LD operations at least) + + uint8_t b0; + uint8_t b1; + + int tmppc = m_addr; + + b0 = READ8(); + + + switch (b0) + { + case 0x00: + m_op = NOP; + // NOP; + break; + + case 0x01: + // SWAP A + m_op = SWAP; + + m_param1_type = REG_8BIT; + m_param1 = 0; // A + break; + + case 0x02: + // MUL W,A + m_op = MUL; + + m_param1_type = REG_8BIT; + m_param1 = 1; // W + + m_param2_type = REG_8BIT; + m_param2 = 0; // A + break; + + case 0x03: + // DIV WA,C + m_op = DIV; + + m_param1_type = REG_16BIT; + m_param1 = 0; // WA + + m_param2_type = REG_8BIT; + m_param2 = 2; // C + break; + + case 0x04: + // RETI + m_op = RETI; + break; + + case 0x05: + // RET + m_op = RET; + break; + + case 0x06: + // POP PSW + m_op = POP; + m_param1_type = PROGRAMSTATUSWORD; + break; + + case 0x07: + // PUSH PSW: + m_op = PUSH; + m_param1_type = PROGRAMSTATUSWORD; + break; + + case 0x08: + case 0x09: + // unused? + break; + + case 0x0a: + // DAA A + m_op = DAA; + + m_param1_type = REG_8BIT; + m_param1 = 0; // A + break; + + case 0x0b: + // DAS A + m_op = DAS; + + m_param1_type = REG_8BIT; + m_param1 = 0; // A + break; + + case 0x0c: + // CLR CF + m_op = CLR; + + m_param1_type = CARRYFLAG; // 16-bit register + //m_param1 = 0; + break; + + case 0x0d: + // SET CF + m_op = SET; + + m_param1_type = CARRYFLAG; // 16-bit register + //m_param1 = 0; + break; + + case 0x0e: + // CPL CF + m_op = CPL; + + m_param1_type = CARRYFLAG; // 16-bit register + //m_param1 = 0; + break; + + case 0x0f: + // LD RBS,n + m_op = LD; // Flags / Cycles 1--- / 2 + m_flagsaffected |= FLAG_J; + + m_param1_type = REGISTERBANK; // 4-bit register + //m_param1 = 0; + + m_param2_type = ABSOLUTE_VAL_8; + m_param2 = READ8(); + + break; + + case 0x10: + case 0x11: + case 0x12: + case 0x13: + // INC rr + m_op = INC; + + m_param1_type = REG_16BIT; // 16-bit register + m_param1 = b0&3; + + break; + + case 0x14: + case 0x15: + case 0x16: + case 0x17: + // LD rr,mn + m_op = LD; // Flags / Cycles 1--- / 3 + m_flagsaffected |= FLAG_J; + + m_param1_type = REG_16BIT; // 16-bit register + m_param1 = b0&3; + + m_param2_type = ABSOLUTE_VAL_16; // absolute value + m_param2 = READ16(); // 16-bit + + break; + + case 0x18: + case 0x19: + case 0x1a: + case 0x1b: + // DEC rr + m_op = DEC; + + m_param1_type = REG_16BIT; // 16-bit register + m_param1 = b0&3; + + break; + + case 0x1c: + // SHLC A + m_op = SHLC; + + m_param1_type = REG_8BIT; + m_param1 = 0; // A + break; + + case 0x1d: + // SHRC A + m_op = SHRC; + + m_param1_type = REG_8BIT; + m_param1 = 0; // A + break; + + case 0x1e: + // ROLC A + m_op = ROLC; + + m_param1_type = REG_8BIT; + m_param1 = 0; // A + break; + + case 0x1f: + // RORC A + m_op = RORC; + + m_param1_type = REG_8BIT; + m_param1 = 0; // A + break; + + case 0x20: + // INC (x) + m_op = INC; + m_param1_type = ADDR_IN_IMM_X; + m_param1 = READ8(); + break; + + case 0x21: + // INC (HL) + m_op = INC; + m_param1_type = ADDR_IN_HL; + //m_param1 = 0; + break; + + case 0x22: + // LD A,(x) + m_op = LD; // Flags / Cycles 1Z-- / 3 + m_flagsaffected |= FLAG_J | FLAG_Z; + + m_param1_type = REG_8BIT; + m_param1 = 0; // A + + m_param2_type = ADDR_IN_IMM_X; + m_param2 = READ8(); + break; + + case 0x23: + // LD A,(HL) + m_op = LD; // Flags / Cycles 1Z-- / 2 + m_flagsaffected |= FLAG_J | FLAG_Z; + + m_param1_type = REG_8BIT; + m_param1 = 0; // A + + m_param2_type = ADDR_IN_HL; + //m_param2 = 0; + break; + + case 0x24: + // LDW (x),mn + m_op = LDW; + m_param1_type = ADDR_IN_IMM_X; // 8-bit memory address + m_param1 = READ8(); + + m_param2_type = ABSOLUTE_VAL_16; // absolute value + m_param2 = READ16(); + break; + + case 0x25: + // LDW (HL),mn + m_op = LDW; + m_param1_type = ADDR_IN_HL; + //m_param1 = 0; + + m_param2_type = ABSOLUTE_VAL_16; + m_param2 = READ16(); + break; + + + case 0x26: + // LD (x),(y) // Flags / Cycles 1Z-- / 5 + m_op = LD; + m_flagsaffected |= FLAG_J | FLAG_Z; + + m_param2_type = ADDR_IN_IMM_X; + m_param2 = READ8(); + + m_param1_type = ADDR_IN_IMM_X; + m_param1 = READ8(); + break; + + case 0x27: + // unused + break; + + case 0x28: + // DEC (x) + m_op = DEC; + m_param1_type = ADDR_IN_IMM_X; + m_param1 = READ8(); + break; + + case 0x29: + // DEC (HL) + m_op = DEC; + m_param1_type = ADDR_IN_HL; + //m_param1 = 0; + break; + + case 0x2a: + // LD (x),A // Flags / Cycles 1Z-- / 3 + m_op = LD; + m_flagsaffected |= FLAG_J | FLAG_Z; + + m_param1_type = ADDR_IN_IMM_X; + m_param1 = READ8(); + + m_param2_type = REG_8BIT; + m_param2 = 0; // A + + break; + + case 0x2b: + // LD (HL),A // Flags / Cycles 1--- / 2 + m_op = LD; + m_flagsaffected |= FLAG_J; + + m_param1_type = ADDR_IN_HL; + //m_param1 = 0; + + m_param2_type = REG_8BIT; + m_param2 = 0; // A + break; + + case 0x2c: + // LD (x),n + m_op = LD; // Flags / Cycles 1--- / 4 + m_flagsaffected |= FLAG_J; + + m_param1_type = ADDR_IN_IMM_X; // 8-bit memory address + m_param1 = READ8(); + + m_param2_type = ABSOLUTE_VAL_8; // absolute value + m_param2 = READ8(); + + break; + + case 0x2d: + // LD (HL),n + m_op = LD; // Flags / Cycles 1--- / 3 + m_flagsaffected |= FLAG_J; + + m_param1_type = ADDR_IN_HL; // memory address in 16-bit register + //m_param1 = 3; // (HL) + + m_param2_type = ABSOLUTE_VAL_8; // absolute value + m_param2 = READ8(); + + break; + + case 0x2e: + // CLR (x) + m_op = CLR; + m_param1_type = ADDR_IN_IMM_X; // 8-bit memory address + m_param1 = READ8(); + + break; + + case 0x2f: + // CLR (HL) + m_op = CLR; + m_param1_type = ADDR_IN_HL; // memory address in 16-bit register + //m_param1 = 3; // (HL) + + break; + + case 0x30: + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + // LD r,n + + m_op = LD; // Flags / Cycles 1--- / 2 + m_flagsaffected |= FLAG_J; + + m_param1_type = REG_8BIT; // 8-bit register register + m_param1 = b0&7; + + m_param2_type = ABSOLUTE_VAL_8; // absolute value + m_param2 = READ8(); + + + break; + + case 0x38: + case 0x39: + case 0x3a: + case 0x3b: + case 0x3c: + case 0x3d: + case 0x3e: + case 0x3f: + break; + + case 0x40: + case 0x41: + case 0x42: + case 0x43: + case 0x44: + case 0x45: + case 0x46: + case 0x47: + // SET (x).b + b1 = READ8(); +#if 0 + // this is just an alias + if ((b0 == 0x40) && (b1 == 0x3a)) + { + // EI 'Assembler expansion machine instruction' + break; + } +#endif + m_op = SET; + + m_param1_type = ADDR_IN_IMM_X | BITPOS; + m_param1 = b1; + m_bitpos = b0 & 7; + + break; + + case 0x48: + case 0x49: + case 0x4a: + case 0x4b: + case 0x4c: + case 0x4d: + case 0x4e: + case 0x4f: + // CLR (x).b + b1 = READ8(); +#if 0 + // this is just an alias + if ((b0 == 0x48) && (b1 == 0x3a)) + { + // DI 'Assembler expansion machine instruction' + break; + } +#endif + m_op = CLR; + + m_param1_type = ADDR_IN_IMM_X | BITPOS; + m_param1 = b1; + m_bitpos = b0 & 7; + + break; + + case 0x50: + case 0x51: + case 0x52: + case 0x53: + case 0x54: + case 0x55: + case 0x56: + case 0x57: + // LD A,r 0101 0rrr + m_op = LD; // Flags / Cycles 1Z-- / 1 + m_flagsaffected |= FLAG_J | FLAG_Z; + + m_param1_type = REG_8BIT; + m_param1 = 0; // A + + m_param2_type = REG_8BIT; + m_param2 = b0 & 0x7; + + break; + + case 0x58: + case 0x59: + case 0x5a: + case 0x5b: + case 0x5c: + case 0x5d: + case 0x5e: + case 0x5f: + // LD r,A 0101 1rrr + m_op = LD; // Flags / Cycles 1Z-- / 1 + m_flagsaffected |= FLAG_J | FLAG_Z; + + m_param2_type = REG_8BIT; + m_param2 = 0; // A + + m_param1_type = REG_8BIT; + m_param1 = b0 & 0x7; + break; + + case 0x60: + case 0x61: + case 0x62: + case 0x63: + case 0x64: + case 0x65: + case 0x66: + case 0x67: + // INC r + m_op = INC; + m_param1_type = REG_8BIT; + m_param1 = b0 & 0x7; + break; + + case 0x68: + case 0x69: + case 0x6a: + case 0x6b: + case 0x6c: + case 0x6d: + case 0x6e: + case 0x6f: + // DEC r + m_op = DEC; + m_param1_type = REG_8BIT; + m_param1 = b0 & 0x7; + break; + + case 0x70: + case 0x71: + case 0x72: + case 0x73: + case 0x74: + case 0x75: + case 0x76: + case 0x77: + // (ALU OP) A,n + m_op = (b0 & 0x7)+ALU_ADDC; + + m_param1_type = REG_8BIT; + m_param1 = 0; // A + + m_param2_type = ABSOLUTE_VAL_8; + m_param2 = READ8(); + + break; + + case 0x78: + case 0x79: + case 0x7a: + case 0x7b: + case 0x7c: + case 0x7d: + case 0x7e: + case 0x7f: + // (ALU OP) A,(x) + m_op = (b0 & 0x7)+ALU_ADDC; + + m_param1_type = REG_8BIT; + m_param1 = 0; // A + + m_param2_type = ADDR_IN_IMM_X; + m_param2 = READ8(); + + break; + + case 0x80: + case 0x81: + case 0x82: + case 0x83: + case 0x84: + case 0x85: + case 0x86: + case 0x87: + case 0x88: + case 0x89: + case 0x8a: + case 0x8b: + case 0x8c: + case 0x8d: + case 0x8e: + case 0x8f: + case 0x90: + case 0x91: + case 0x92: + case 0x93: + case 0x94: + case 0x95: + case 0x96: + case 0x97: + case 0x98: + case 0x99: + case 0x9a: + case 0x9b: + case 0x9c: + case 0x9d: + case 0x9e: + case 0x9f: + { + // JRS T,a + m_op = JRS; + + m_param1_type = CONDITIONAL; + m_param1 = 6; + + m_param2_type = ABSOLUTE_VAL_16; + + int val = b0 & 0x1f; + if (val & 0x10) val -= 0x20; + + m_param2 = tmppc + 2 + val; + + break; + } + case 0xa0: + case 0xa1: + case 0xa2: + case 0xa3: + case 0xa4: + case 0xa5: + case 0xa6: + case 0xa7: + case 0xa8: + case 0xa9: + case 0xaa: + case 0xab: + case 0xac: + case 0xad: + case 0xae: + case 0xaf: + case 0xb0: + case 0xb1: + case 0xb2: + case 0xb3: + case 0xb4: + case 0xb5: + case 0xb6: + case 0xb7: + case 0xb8: + case 0xb9: + case 0xba: + case 0xbb: + case 0xbc: + case 0xbd: + case 0xbe: + case 0xbf: + { + // JRS F,a + m_op = JRS; + + m_param1_type = CONDITIONAL; + m_param1 = 7; + + m_param2_type = ABSOLUTE_VAL_16; + + int val = b0 & 0x1f; + if (val & 0x10) val -= 0x20; + + m_param2 = tmppc + 2 + val; + + break; + } + + case 0xc0: + case 0xc1: + case 0xc2: + case 0xc3: + case 0xc4: + case 0xc5: + case 0xc6: + case 0xc7: + case 0xc8: + case 0xc9: + case 0xca: + case 0xcb: + case 0xcc: + case 0xcd: + case 0xce: + case 0xcf: + // CALLV n + m_op = CALLV; + + m_param1_type = MEMVECTOR_16BIT; + + m_param1 = 0xffc0 + ((b0 & 0xf) * 2); + + break; + + case 0xd0: + case 0xd1: + case 0xd2: + case 0xd3: + case 0xd4: + case 0xd5: + case 0xd6: + case 0xd7: + { + // JR cc,a + + m_op = JR; + + m_param1_type = CONDITIONAL; + m_param1 = b0 & 0x7; + + m_param2_type = ABSOLUTE_VAL_16; + + int val = READ8(); + if (val & 0x80) val -= 0x100; + + m_param2 = tmppc+ 2 + val; + + break; + } + case 0xd8: + case 0xd9: + case 0xda: + case 0xdb: + case 0xdc: + case 0xdd: + case 0xde: + case 0xdf: + // LD CF, (x).b aka TEST (x).b + m_op = LD; // Flags / Cycles %-*- / 4 + m_flagsaffected |= FLAG_J | FLAG_C; + + m_param1_type = CARRYFLAG; + //m_param1 = 0; + + m_param2_type = ADDR_IN_IMM_X | BITPOS; + m_param2 = READ8(); + m_bitpos = b0 & 0x7; + break; + + case 0xe0: + // src prefix + decode_source(ADDR_IN_BASE+(b0&0x7), READ8()); + break; + + case 0xe1: + case 0xe2: + case 0xe3: + decode_source(ADDR_IN_BASE+(b0&0x7), 0); + break; + + case 0xe4: + decode_source(ADDR_IN_BASE+(b0&0x7), READ8()); + break; + + case 0xe5: + case 0xe6: + case 0xe7: + decode_source(ADDR_IN_BASE+(b0&0x7), 0); + break; + + case 0xe8: + case 0xe9: + case 0xea: + case 0xeb: + case 0xec: + case 0xed: + case 0xee: + case 0xef: + // register prefix: g/gg + decode_register_prefix(b0); + break; + + case 0xf0: // 1111 0000 xxxx xxxx 0101 0rrr + // destination memory prefix (dst) + m_param1_type = ADDR_IN_BASE+(b0&0x7); + m_param1 = READ8(); + decode_dest(b0); + break; + + case 0xf2: // 1111 001p 0101 0rrr + case 0xf3: // 1111 001p 0101 0rrr + // destination memory prefix (dst) + m_param1_type = ADDR_IN_BASE+(b0&0x7); + decode_dest(b0); + break; + + + case 0xf4: // 1111 0100 dddd dddd 0101 0rrr + // destination memory prefix (dst) + m_param1_type = ADDR_IN_BASE+(b0&0x7); + m_param1 = READ8(); + decode_dest(b0); + break; + + case 0xf6: // 1110 0110 0101 0rrr + case 0xf7: // 1111 0111 0101 0rrr + // destination memory prefix (dst) + m_param1_type = ADDR_IN_BASE+(b0&0x7); + decode_dest(b0); + break; + + case 0xf1: + case 0xf5: + // invalid dst memory prefix + break; + + + case 0xf8: + case 0xf9: + // unused + break; + + case 0xfa: + // LD SP,mn + m_op = LD; // Flags / Cycles 1--- / 3 + m_flagsaffected |= FLAG_J; + + m_param1_type = STACKPOINTER; + //m_param1 = 0; + + m_param2_type = ABSOLUTE_VAL_16; + m_param2 = READ16(); + + break; + + case 0xfb: + { + // JR a + m_op = JR; + + m_param2_type = ABSOLUTE_VAL_16; + + int val = READ8(); + if (val & 0x80) val -= 0x100; + + m_param2 = tmppc + 2 + val; + + break; + } + + break; + + case 0xfc: + // CALL mn + m_op = CALL; + + m_param1_type = ABSOLUTE_VAL_16; + m_param1 = READ16(); + break; + + case 0xfd: + // CALLP n + m_op = CALLP; + + m_param1_type = ABSOLUTE_VAL_16; + m_param1 = READ8()+0xff00; + + break; + + case 0xfe: + // JP mn + m_op = JP; + + m_param2_type = ABSOLUTE_VAL_16; + m_param2 = READ16(); + + break; + + case 0xff: + // SWI + m_op = SWI; + + break; + } +} + +// e8 - ef use this table +void tlcs870_disassembler::decode_register_prefix(uint8_t b0) +{ + uint8_t bx; + + bx = READ8(); + + switch (bx) + { + case 0x00: + // nothing + break; + + case 0x01: + // SWAP g + m_op = SWAP; + + m_param1_type = REG_8BIT; + m_param1 = b0 & 0x7; + break; + + case 0x02: + // MUL ggG, ggL + m_op = MUL; + + m_param1_type = REG_16BIT; // odd syntax + m_param1 = b0 & 0x3; + break; + + case 0x03: + // DIV gg,C + m_op = DIV; + m_param1_type = REG_16BIT; + m_param1 = b0 & 3; + + m_param2_type = REG_8BIT; + m_param2 = 2; // C + + break; + + case 0x04: + // with E8 only + // RETN + if (b0 == 0xe8) + { + m_op = RETN; + } + + break; + + case 0x05: + break; + + case 0x06: + // POP gg + m_op = POP; + m_param1_type = REG_16BIT; + m_param1 = b0 & 3; + // b0 & 4 = invalid? + + break; + + case 0x07: + // PUSH gg + m_op = PUSH; + m_param1_type = REG_16BIT; + m_param1 = b0 & 3; + // b0 & 4 = invalid? + + break; + + case 0x08: + case 0x09: + break; + + case 0x0a: + // DAA g + m_op = DAA; + + m_param1_type = REG_8BIT; + m_param1 = b0 & 0x7; + + break; + + case 0x0b: + // DAS g + m_op = DAS; + + m_param1_type = REG_8BIT; + m_param1 = b0 & 0x7; + + break; + + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + break; + + case 0x10: + case 0x11: + case 0x12: + case 0x13: + // XCH rr,gg + m_op = XCH; + + m_param1_type = REG_16BIT; + m_param1 = bx & 0x3; + + m_param2_type = REG_16BIT; + m_param2 = b0 & 0x3; + break; + + case 0x14: + case 0x15: + case 0x16: + case 0x17: + // LD rr,gg + m_op = LD; // Flags / Cycles 1--- / 2 + m_flagsaffected |= FLAG_J; + + m_param1_type = REG_16BIT; + m_param1 = bx & 0x3; + + m_param2_type = REG_16BIT; + m_param2 = b0 & 0x3; + + break; + + case 0x18: + case 0x19: + case 0x1a: + case 0x1b: + break; + + case 0x1c: + // SHLC g + m_op = SHLC; + + m_param1_type = REG_8BIT; + m_param1 = b0 & 0x7; + + break; + + case 0x1d: + // SHRC g + m_op = SHRC; + + m_param1_type = REG_8BIT; + m_param1 = b0 & 0x7; + + break; + + case 0x1e: + // ROLC g + m_op = ROLC; + + m_param1_type = REG_8BIT; + m_param1 = b0 & 0x7; + + break; + + case 0x1f: + // RORC g + m_op = RORC; + + m_param1_type = REG_8BIT; + m_param1 = b0 & 0x7; + + break; + + case 0x20: + case 0x21: + case 0x22: + case 0x23: + case 0x24: + case 0x25: + case 0x26: + case 0x27: + case 0x28: + case 0x29: + case 0x2a: + case 0x2b: + case 0x2c: + case 0x2d: + case 0x2e: + case 0x2f: + break; + + case 0x30: + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + // (ALU OP) WA,gg + m_op = (bx & 0x7)+ALU_ADDC; + + m_param1_type = REG_16BIT; + m_param1 = 0; + + m_param2_type = REG_16BIT; + m_param2 = b0 & 3; + // b0 & 4 would be invalid? + + + break; + + case 0x38: + case 0x39: + case 0x3a: + case 0x3b: + case 0x3c: + case 0x3d: + case 0x3e: + case 0x3f: + // (ALU OP) gg,mn + m_op = (bx & 0x7)+ALU_ADDC; + + m_param1_type = REG_16BIT; + m_param1 = b0 & 0x3; + + m_param2_type = ABSOLUTE_VAL_16; // absolute value + m_param2 = READ16(); // 16-bit + + break; + + case 0x40: + case 0x41: + case 0x42: + case 0x43: + case 0x44: + case 0x45: + case 0x46: + case 0x47: + // SET g.b + m_op = SET; + + m_param1_type = REG_8BIT | BITPOS; + m_param1 = b0 & 0x7; + m_bitpos = bx & 0x7; + + + break; + + case 0x48: + case 0x49: + case 0x4a: + case 0x4b: + case 0x4c: + case 0x4d: + case 0x4e: + case 0x4f: + // CLR g.b + m_op = CLR; + + m_param1_type = REG_8BIT | BITPOS; + m_param1 = b0 & 0x7; + m_bitpos = bx & 0x7; + + break; + + case 0x50: + case 0x51: + case 0x52: + case 0x53: + case 0x54: + case 0x55: + case 0x56: + case 0x57: + break; + + case 0x58: + case 0x59: + case 0x5a: + case 0x5b: + case 0x5c: + case 0x5d: + case 0x5e: + case 0x5f: + // LD r,g + m_op = LD; // Flags / Cycles 1Z-- / 2 + m_flagsaffected |= FLAG_J | FLAG_Z; + + m_param1_type = REG_8BIT; + m_param1 = bx & 0x7; + + m_param2_type = REG_8BIT; + m_param2 = b0 & 0x7; + break; + + case 0x60: + case 0x61: + case 0x62: + case 0x63: + case 0x64: + case 0x65: + case 0x66: + case 0x67: + // (ALU OP) A,g + m_op = (bx & 0x7)+ALU_ADDC; + + m_param2_type = REG_8BIT; + m_param2 = b0 & 0x7; + + m_param1_type = REG_8BIT; + m_param1 = 0; // A + break; + + case 0x68: + case 0x69: + case 0x6a: + case 0x6b: + case 0x6c: + case 0x6d: + case 0x6e: + case 0x6f: + // (ALU OP) g,A + m_op = (bx & 0x7)+ALU_ADDC; + + m_param1_type = REG_8BIT; + m_param1 = b0 & 0x7; + + m_param2_type = REG_8BIT; + m_param2 = 0; // A + break; + + case 0x70: + case 0x71: + case 0x72: + case 0x73: + case 0x74: + case 0x75: + case 0x76: + case 0x77: + // (ALU OP) g,n + m_op = (bx & 0x7)+ALU_ADDC; + + m_param1_type = REG_8BIT; + m_param1 = b0 & 0x7; + + m_param2_type = ABSOLUTE_VAL_8; + m_param2 = READ8(); + + + break; + + case 0x78: + case 0x79: + case 0x7a: + case 0x7b: + case 0x7c: + case 0x7d: + case 0x7e: + case 0x7f: + break; + + + case 0x80: + case 0x81: + break; + + case 0x82: + case 0x83: + // SET (pp).g + m_op = SET; + m_param1_type = (ADDR_IN_DE+(bx&1)) | BITPOS | BITPOS_INDIRECT; + //m_param1 = 0; + m_bitpos = b0 & 7; + break; + + case 0x84: + case 0x85: + case 0x86: + case 0x87: + break; + + case 0x88: + case 0x89: + break; + + case 0x8a: + case 0x8b: + // CLR (pp).g + m_op = CLR; + m_param1_type = (ADDR_IN_DE+(bx&1)) | BITPOS | BITPOS_INDIRECT; + //m_param1 = 0; + m_bitpos = b0 & 7; + break; + + case 0x8c: + case 0x8d: + case 0x8e: + case 0x8f: + break; + + + case 0x90: + case 0x91: + break; + + case 0x92: + case 0x93: + // CPL (pp).g + m_op = CPL; + m_param1_type = (ADDR_IN_DE+(bx&1)) | BITPOS | BITPOS_INDIRECT; + //m_param1 = 0; + m_bitpos = b0 & 7; + break; + + case 0x94: + case 0x95: + case 0x96: + case 0x97: + break; + + case 0x9a: + case 0x9b: + // LD (pp).g,CF + m_op = LD; // Flags / Cycles 1--- / 5 + m_flagsaffected |= FLAG_J; + + m_param1_type = (ADDR_IN_DE+(bx&1)) | BITPOS | BITPOS_INDIRECT; + //m_para1 = 0; + m_bitpos = b0 & 7; + + m_param2_type = CARRYFLAG; + //m_param2 = 0; + break; + + case 0x9c: + case 0x9d: + break; + + case 0x9e: + case 0x9f: + // LD CF,(pp).g aka TEST (pp).g + m_op = LD; // Flags / Cycles %-*- / 4 + m_flagsaffected |= FLAG_J | FLAG_C; + + m_param1_type = CARRYFLAG; + //m_param1 = 0; + + m_param2_type = (ADDR_IN_DE+(bx&1)) | BITPOS | BITPOS_INDIRECT; + //m_param2 = 0; + m_bitpos = b0 & 7; + break; + + case 0xa0: + case 0xa1: + case 0xa2: + case 0xa3: + case 0xa4: + case 0xa5: + case 0xa6: + case 0xa7: + break; + + case 0xb0: + case 0xb1: + case 0xb2: + case 0xb3: + case 0xb4: + case 0xb5: + case 0xb6: + case 0xb7: + case 0xb8: + case 0xb9: + case 0xba: + case 0xbb: + case 0xbc: + case 0xbd: + case 0xbe: + case 0xbf: + break; + + case 0xc0: + case 0xc1: + case 0xc2: + case 0xc3: + case 0xc4: + case 0xc5: + case 0xc6: + case 0xc7: + // CPL g.b + m_op = CPL; + + m_param1_type = REG_8BIT | BITPOS; + m_param1 = b0 & 0x7; + m_bitpos = bx & 0x7; + break; + + case 0xc8: + case 0xc9: + case 0xca: + case 0xcb: + case 0xcc: + case 0xcd: + case 0xce: + case 0xcf: + // LD g.b,CF + m_op = LD; // Flags / Cycles 1--- / 2 + m_flagsaffected |= FLAG_J; + + m_param2_type = CARRYFLAG; + //m_param2 = 0; + + m_param1_type = REG_8BIT | BITPOS; + m_param1 = b0 & 0x7; + m_bitpos = bx & 0x7; + + break; + + case 0xd0: + case 0xd1: + case 0xd2: + case 0xd3: + case 0xd4: + case 0xd5: + case 0xd6: + case 0xd7: + // XOR CF,g.b + m_op = ALU_XOR; + + m_param1_type = CARRYFLAG; + //m_param1 = 0; + + m_param2_type = REG_8BIT | BITPOS; + m_param2 = b0 & 0x7; + m_bitpos = bx & 0x7; + + break; + + case 0xd8: + case 0xd9: + case 0xda: + case 0xdb: + case 0xdc: + case 0xdd: + case 0xde: + case 0xdf: + // LD CF,g.b aka TEST g.b + m_op = LD; // Flags / Cycles %-*- / 2 + m_flagsaffected |= FLAG_J | FLAG_C; + + m_param1_type = CARRYFLAG; + //m_param1 = 0; + + m_param2_type = REG_8BIT | BITPOS; + m_param2 = b0 & 0x7; + m_bitpos = bx & 0x7; + + break; + + case 0xe0: + case 0xe1: + case 0xe2: + case 0xe3: + case 0xe4: + case 0xe5: + case 0xe6: + case 0xe7: + case 0xe8: + case 0xe9: + case 0xea: + case 0xeb: + case 0xec: + case 0xed: + case 0xee: + case 0xef: + break; + + case 0xf0: + case 0xf1: + case 0xf2: + case 0xf3: + case 0xf4: + case 0xf5: + case 0xf6: + case 0xf7: + break; + + case 0xf8: + case 0xf9: + break; + + case 0xfa: + // LD SP,gg + m_op = LD; // Flags / Cycles 1--- / 3 + m_flagsaffected |= FLAG_J; + + m_param2_type = REG_16BIT; + m_param2 = b0 & 3; + // b0 & 4 would be invalid? + + m_param1_type = STACKPOINTER; + // m_param1 = 0; + + break; + + case 0xfb: + // LD gg,SP + m_op = LD; // Flags / Cycles 1--- / 3 + m_flagsaffected |= FLAG_J; + + m_param1_type = REG_16BIT; + m_param1 = b0 & 3; + // b0 & 4 would be invalid? + + m_param2_type = STACKPOINTER; + // m_param2 = 0; + break; + + case 0xfc: + // CALL gg + m_op = CALL; + + m_param2_type = REG_16BIT; + m_param2 = b0 & 3; + // b0 & 4 would be invalid? + + break; + + case 0xfd: + break; + + case 0xfe: + // JP gg + m_op = JP; + + m_param2_type = REG_16BIT; + m_param2 = b0 & 3; + // b0 & 4 would be invalid? + + break; + + case 0xff: + break; + + } + +} + +// e0 - e7 use this table +void tlcs870_disassembler::decode_source(int type, uint16_t val) +{ + uint8_t bx; + + bx = READ8(); + + switch (bx) + { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x04: + case 0x05: + case 0x06: + case 0x07: + break; + + case 0x08: + // ROLD A,(src) + m_op = ROLD; + m_param2_type = type; + m_param2 = val; + + m_param1_type = REG_8BIT; + m_param1 = 0; // A + break; + + case 0x09: + // RORD A,(src) + m_op = RORD; + m_param2_type = type; + m_param2 = val; + + m_param1_type = REG_8BIT; + m_param1 = 0; // A + break; + + case 0x0a: + case 0x0b: + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + + case 0x10: + case 0x11: + case 0x12: + case 0x13: + // see dst + break; + + case 0x14: + case 0x15: + case 0x16: + case 0x17: + // LD rr, (src) + m_op = LD; // Flags / Cycles 1--- / x + m_flagsaffected |= FLAG_J; + + m_param1_type = REG_16BIT; + m_param1 = bx & 0x3; + + m_param2_type = type | IS16BIT; + m_param2 = val; + break; + + case 0x18: + case 0x19: + case 0x1a: + case 0x1b: + case 0x1c: + case 0x1d: + case 0x1e: + case 0x1f: + break; + + case 0x20: + // INC (src) + m_op = INC; + m_param1_type = type; + m_param1 = val; + + break; + + case 0x21: + case 0x22: + case 0x23: + case 0x24: + case 0x25: + break; + + case 0x26: // invalid if (src) is also (x) ? (not specified) + // LD (x),(src) + m_op = LD; // Flags / Cycles 1U-- / x + m_flagsaffected |= FLAG_J /*| FLAG_Z*/; // Z is undefined! + + m_param1_type = ADDR_IN_IMM_X; + m_param1 = READ8(); + + m_param2_type = type; + m_param2 = val; + break; + + case 0x27: + // LD (HL),(src) + m_op = LD; // Flags / Cycles 1Z-- / x + m_flagsaffected |= FLAG_J | FLAG_Z; + + m_param1_type = ADDR_IN_HL; + //m_param1 = 0; + + m_param2_type = type; + m_param2 = val; + break; + + + case 0x28: + // DEC (src) + m_op = DEC; + m_param1_type = type; + m_param1 = val; + + break; + + case 0x29: + case 0x2a: + case 0x2b: + case 0x2c: + case 0x2d: + case 0x2e: + break; + + case 0x2f: + // MCMP (src), n + m_op = MCMP; + m_param1_type = type; + m_param1 = val; + + m_param2_type = ABSOLUTE_VAL_8; + m_param2 = READ8(); + break; + + case 0x30: + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + case 0x38: + case 0x39: + case 0x3a: + case 0x3b: + case 0x3c: + case 0x3d: + case 0x3e: + case 0x3f: + break; + + case 0x40: + case 0x41: + case 0x42: + case 0x43: + case 0x44: + case 0x45: + case 0x46: + case 0x47: + // SET (src).b + m_op = SET; + + m_param1_type = type | BITPOS; + m_param1 = val; + m_bitpos = bx & 0x7; + break; + + case 0x48: + case 0x49: + case 0x4a: + case 0x4b: + case 0x4c: + case 0x4d: + case 0x4e: + case 0x4f: + // CLR (src).b + m_op = CLR; + + m_param1_type = type | BITPOS; + m_param1 = val; + m_bitpos = bx & 0x7; + break; + + case 0x50: + case 0x51: + case 0x52: + case 0x53: + case 0x54: + case 0x55: + case 0x56: + case 0x57: + // see dst + break; + + case 0x58: + case 0x59: + case 0x5a: + case 0x5b: + case 0x5c: + case 0x5d: + case 0x5e: + case 0x5f: + // LD r, (src) + m_op = LD; // Flags / Cycles 1Z-- / x + m_flagsaffected |= FLAG_J | FLAG_Z; + + m_param1_type = REG_8BIT; + m_param1 = bx & 0x7; + + m_param2_type = type; + m_param2 = val; + break; + + case 0x60: + case 0x61: + case 0x62: + case 0x63: + case 0x64: + case 0x65: + case 0x66: + case 0x67: + // (ALU OP) (src), (HL) + m_op = (bx & 0x7)+ALU_ADDC; + m_param1_type = type; + m_param1 = val; + + m_param2_type = ADDR_IN_HL; + //m_param2 = 0; + break; + + case 0x68: + case 0x69: + case 0x6a: + case 0x6b: + case 0x6c: + case 0x6d: + case 0x6e: + case 0x6f: + break; + + case 0x70: + case 0x71: + case 0x72: + case 0x73: + case 0x74: + case 0x75: + case 0x76: + case 0x77: + // (ALU OP) (src), n + m_op = (bx & 0x7)+ALU_ADDC; + m_param1_type = type; + m_param1 = val; + + m_param2_type = ABSOLUTE_VAL_8; + m_param2 = READ8(); + break; + + case 0x78: + case 0x79: + case 0x7a: + case 0x7b: + case 0x7c: + case 0x7d: + case 0x7e: + case 0x7f: + // (ALU OP) A, (src) + + m_op = (bx & 0x7)+ALU_ADDC; + m_param2_type = type; + m_param2 = val; + + m_param1_type = REG_8BIT; + m_param1 = 0; // A + break; + + case 0x80: + case 0x81: + case 0x82: + case 0x83: + case 0x84: + case 0x85: + case 0x86: + case 0x87: + case 0x88: + case 0x89: + case 0x8a: + case 0x8b: + case 0x8c: + case 0x8d: + case 0x8e: + case 0x8f: + break; + + case 0x90: + case 0x91: + case 0x92: + case 0x93: + case 0x94: + case 0x95: + case 0x96: + case 0x97: + case 0x98: + case 0x99: + case 0x9a: + case 0x9b: + case 0x9c: + case 0x9d: + case 0x9e: + case 0x9f: + break; + + case 0xa0: + case 0xa1: + case 0xa2: + case 0xa3: + case 0xa4: + case 0xa5: + case 0xa6: + case 0xa7: + break; + + case 0xa8: + case 0xa9: + case 0xaa: + case 0xab: + case 0xac: + case 0xad: + case 0xae: + case 0xaf: + // XCH r,(src) + m_op = XCH; + + m_param1_type = REG_8BIT; + m_param1 = bx & 0x7; + + m_param2_type = type; + m_param2 = val; + break; + + + case 0xb0: + case 0xb1: + case 0xb2: + case 0xb3: + case 0xb4: + case 0xb5: + case 0xb6: + case 0xb7: + case 0xb8: + case 0xb9: + case 0xba: + case 0xbb: + case 0xbc: + case 0xbd: + case 0xbe: + case 0xbf: + break; + + case 0xc0: + case 0xc1: + case 0xc2: + case 0xc3: + case 0xc4: + case 0xc5: + case 0xc6: + case 0xc7: + // CPL (src).b + m_op = CPL; + + m_param1_type = type | BITPOS; + m_param1 = val; + m_bitpos = bx & 0x7; + break; + + case 0xc8: + case 0xc9: + case 0xca: + case 0xcb: + case 0xcc: + case 0xcd: + case 0xce: + case 0xcf: + // LD (src).b,CF + m_op = LD; // Flags / Cycles 1--- / x + m_flagsaffected |= FLAG_J; + + m_param1_type = type | BITPOS; + m_param1 = val; + m_bitpos = bx & 0x7; + + m_param2_type = CARRYFLAG; + //m_param2 = 0; + break; + + + case 0xd0: + case 0xd1: + case 0xd2: + case 0xd3: + case 0xd4: + case 0xd5: + case 0xd6: + case 0xd7: + // XOR CF,(src).b + m_op = ALU_XOR; + m_param1_type = CARRYFLAG; + //m_param1 = 0; + + m_param2_type = type | BITPOS; + m_param2 = val; + m_bitpos = bx & 0x7; + break; + + case 0xd8: + case 0xd9: + case 0xda: + case 0xdb: + case 0xdc: + case 0xdd: + case 0xde: + case 0xdf: + // LD CF,(src).b aka TEST (src).b + m_op = LD; // Flags / Cycles %-*- / x + m_flagsaffected |= FLAG_J | FLAG_C; + + m_param2_type = type | BITPOS; + m_param2 = val; + m_bitpos = bx & 0x7; + + m_param1_type = CARRYFLAG; + //m_param1 = 0; + break; + + + case 0xe0: + case 0xe1: + case 0xe2: + case 0xe3: + case 0xe4: + case 0xe5: + case 0xe6: + case 0xe7: + case 0xe8: + case 0xe9: + case 0xea: + case 0xeb: + case 0xec: + case 0xed: + case 0xee: + case 0xef: + break; + + case 0xf0: + case 0xf1: + case 0xf2: + case 0xf3: + case 0xf4: + case 0xf5: + case 0xf6: + case 0xf7: + break; + + case 0xf8: + case 0xf9: + case 0xfa: + case 0xfb: + case 0xfc: + // CALL (src) + m_op = CALL; + m_param1_type = type; + m_param1 = val; + break; + + case 0xfd: + break; + + case 0xfe: + // JP (src) + m_op = JP; + m_param2_type = type | IS16BIT; + m_param2 = val; + break; + + case 0xff: + break; + } +} + +// f0 - f7 use this table +// note, same table is shown as above in manual, there's no overlap between src/dest, but they're not compatible +void tlcs870_disassembler::decode_dest(uint8_t b0) +{ + uint8_t bx; + + bx = READ8(); + + switch (bx) + { + case 0x10: + case 0x11: + case 0x12: + case 0x13: + // LD (dst),rr // (dst) can only be (x) (pp) or (HL+d) ? not (HL+) or (-HL) ? + m_op = LD; // Flags / Cycles 1--- / x + m_flagsaffected |= FLAG_J; + + m_param1_type |= IS16BIT; + + + m_param2_type = REG_16BIT; + m_param2 = bx&0x3; + break; + + case 0x2c: + // LD (dst),n // (dst) can only be (DE), (HL+), (-HL), or (HL+d) because (x) and (HL) are redundant encodings? + m_op = LD; // Flags / Cycles 1--- / x + m_flagsaffected |= FLAG_J; + + m_param2_type = ABSOLUTE_VAL_8; + m_param2 = READ8(); + break; + + case 0x50: + case 0x51: + case 0x52: + case 0x53: + case 0x54: + case 0x55: + case 0x56: + case 0x57: + // LD (dst),r + m_op = LD; // Flags / Cycles 1--- / x + m_flagsaffected |= FLAG_J; + + m_param2_type = REG_8BIT; + m_param2 = bx&0x7; + break; + + default: + break; + } +} + +void tlcs870_disassembler::disassemble_param(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms, int type, uint16_t val) +{ + int basetype = type & MODE_MASK; + + if (basetype==ADDR_IN_IMM_X) util::stream_format(stream, " ($%02x)", val); // direct + if (basetype==ADDR_IN_PC_PLUS_REG_A) util::stream_format(stream, " %s", type_x[1]); + if (basetype==ADDR_IN_DE) util::stream_format(stream, " %s", type_x[2]); + if (basetype==ADDR_IN_HL) util::stream_format(stream, " %s", type_x[3]); + if (basetype==ADDR_IN_HL_PLUS_IMM_D) util::stream_format(stream, " (HL+$%04x)", val); // todo, sign extend + if (basetype==ADDR_IN_HL_PLUS_REG_C) util::stream_format(stream, " %s", type_x[5]); + if (basetype==ADDR_IN_HLINC) util::stream_format(stream, " %s", type_x[6]); + if (basetype==ADDR_IN_DECHL) util::stream_format(stream, " %s", type_x[7]); + + if (basetype==REG_8BIT) + { + if (type&IS16BIT) util::stream_format(stream, " %s", reg16[val&3]); + else util::stream_format(stream, " %s", reg8[val & 7]); + } + + if (basetype==CONDITIONAL) util::stream_format(stream, " %s", conditions[val]); + if (basetype==(STACKPOINTER & MODE_MASK)) util::stream_format(stream, " SP"); + if (basetype==REGISTERBANK) util::stream_format(stream, " RBS"); + if (basetype==PROGRAMSTATUSWORD) util::stream_format(stream, " PSW"); + if (basetype==MEMVECTOR_16BIT) util::stream_format(stream, " ($%04x)", val); + if (basetype==ABSOLUTE_VAL_8) + { + if (type&IS16BIT) util::stream_format(stream, "$%04x", val); + else util::stream_format(stream, "$%02x", val); + } + + if (basetype == (CARRYFLAG & MODE_MASK)) + { + util::stream_format(stream, " CF"); + } + else if (type&BITPOS) + { + if (type & BITPOS_INDIRECT) util::stream_format(stream, ".BIT_%s", reg8[m_bitpos&7]); + else util::stream_format(stream, ".BIT_%d", m_bitpos); + } +} + +offs_t tlcs870_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + m_addr = pc; + m_opcodes = &opcodes; + + decode(); + + util::stream_format (stream, "%-5s", op_names[ m_op ] ); + + if (m_param1_type) + { + disassemble_param(stream, pc, opcodes, params, m_param1_type, m_param1); + } + + if (m_param2_type) + { + if (m_param1_type) util::stream_format(stream, ","); + + disassemble_param(stream, pc, opcodes, params, m_param2_type, m_param2); + + } + + return (m_addr - pc) | SUPPORTED; +} diff --git a/src/devices/cpu/tlcs870/tlcs870d.h b/src/devices/cpu/tlcs870/tlcs870d.h new file mode 100644 index 00000000000..64f0de84090 --- /dev/null +++ b/src/devices/cpu/tlcs870/tlcs870d.h @@ -0,0 +1,88 @@ +// license:BSD-3-Clause +// copyright-holders:David Haywood +/************************************************************************************************************* + + Toshiba TLCS-870 Series MCUs + + The TLCS-870/X expands on this instruction set using the same base encoding. + + The TLCS-870/C appears to have a completely different encoding. + + loosely baesd on the tlcs90 core by Luca Elia + +*************************************************************************************************************/ + +#ifndef MAME_CPU_TLCS870_TLCS870D_H +#define MAME_CPU_TLCS870_TLCS870D_H + +#pragma once + +class tlcs870_disassembler : public util::disasm_interface +{ +public: + tlcs870_disassembler() = default; + virtual ~tlcs870_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum _e_op { + UNKNOWN = 0x00, + CALL, CALLP, CALLV, CLR, CPL, + DAA, DAS, DEC, /*DI,*/ DIV, + /*EI,*/ + INC, + /*J,*/ JP, JR, JRS, + LD, LDW, + MCMP, MUL, + NOP, + POP, PUSH, + RET, RETI, RETN, ROLC, ROLD, RORC, RORD, + SET, SHLC, SHRC, SWAP, SWI, + /*TEST,*/ XCH, + + ALU_ADDC, + ALU_ADD, + ALU_SUBB, + ALU_SUB, + ALU_AND, + ALU_XOR, + ALU_OR, + ALU_CMP + }; + + static const char *const op_names[]; + static const char *const reg8[]; + static const char *const type_x[]; + static const char *const conditions[]; + static const char *const reg16[]; + static const char *const reg16p[]; + + uint16_t m_op; + int m_param2_type; + uint16_t m_param2; + + int m_param1_type; + uint16_t m_param1; + + uint8_t m_bitpos; + uint8_t m_flagsaffected; + uint8_t m_cycles; + + uint32_t m_addr; + + const data_buffer *m_opcodes; + + inline uint8_t READ8(); + inline uint16_t READ16(); + + void decode(); + void decode_register_prefix(uint8_t b0); + void decode_source(int type, uint16_t val); + void decode_dest(uint8_t b0); + + void disassemble_param(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms, int type, uint16_t val); +}; + +#endif diff --git a/src/devices/cpu/tlcs90/tlcs90.cpp b/src/devices/cpu/tlcs90/tlcs90.cpp index 777ecf3b412..593e454605f 100644 --- a/src/devices/cpu/tlcs90/tlcs90.cpp +++ b/src/devices/cpu/tlcs90/tlcs90.cpp @@ -15,8 +15,7 @@ #include "emu.h" #include "debugger.h" #include "tlcs90.h" - -static const char *const op_names[] = { "??", "nop", "ex", "exx", "ld", "ldw", "lda", "ldi", "ldir", "ldd", "lddr", "cpi", "cpir", "cpd", "cpdr", "push", "pop", "jp", "jr", "call", "callr", "ret", "reti", "halt", "di", "ei", "swi", "daa", "cpl", "neg", "ldar", "rcf", "scf", "ccf", "tset", "bit", "set", "res", "inc", "dec", "incx", "decx", "incw", "decw", "add", "adc", "sub", "sbc", "and", "xor", "or", "cp", "rlc", "rrc", "rl", "rr", "sla", "sra", "sll", "srl", "rld", "rrd", "djnz", "mul", "div" }; +#include "tlcs90d.h" ALLOW_SAVE_TYPE(tlcs90_device::e_mode); // allow save_item on a non-fundamental type @@ -29,6 +28,19 @@ DEFINE_DEVICE_TYPE(TMP91641, tmp91641_device, "tmp91641", "TMP91641") DEFINE_DEVICE_TYPE(TMP90PH44, tmp90ph44_device, "tmp90ph44", "TMP90PH44") +#define T90_IOBASE 0xffc0 + +enum e_ir +{ + T90_P0=T90_IOBASE, T90_P1, T90_P01CR_IRFL, T90_IRFH, T90_P2, T90_P2CR, T90_P3, T90_P3CR, + T90_P4, T90_P4CR, T90_P5, T90_SMMOD, T90_P6, T90_P7, T90_P67CR, T90_SMCR, + T90_P8, T90_P8CR, T90_WDMOD, T90_WDCR, T90_TREG0, T90_TREG1, T90_TREG2, T90_TREG3, + T90_TCLK, T90_TFFCR, T90_TMOD, T90_TRUN, T90_CAP1L, T90_CAP1H, T90_CAP2L, T90_CAL2H, + T90_TREG4L, T90_TREG4H, T90_TREG5L, T90_TREG5H, T90_T4MOD, T90_T4FFCR, T90_INTEL, T90_INTEH, + T90_DMAEH, T90_SCMOD, T90_SCCR, T90_SCBUF, T90_BX, T90_BY, T90_ADREG, T90_ADMOD +}; + + static ADDRESS_MAP_START(tmp90840_mem, AS_PROGRAM, 8, tlcs90_device) AM_RANGE( 0x0000, 0x1fff ) AM_ROM // 8KB ROM (internal) AM_RANGE( 0xfec0, 0xffbf ) AM_RAM // 256b RAM (internal) @@ -141,9 +153,6 @@ enum { #define F m_af.b.l -static const char *const r8_names[] = { "b", "c", "d", "e", "h", "l", "a" }; -static const char *const r16_names[] = { "bc", "de", "hl", "??", "ix", "iy", "sp", "af", "af'", "pc" }; - // Condition Codes #define FLS 0x0 @@ -185,8 +194,6 @@ static uint8_t SZP[256]; /* zero, sign and parity flags */ static uint8_t SZHV_inc[256]; /* zero, sign, half carry and overflow flags INC r8 */ static uint8_t SZHV_dec[256]; /* zero, sign, half carry and overflow flags DEC r8 */ -static const char *const cc_names[] = { "f", "lt", "le", "ule", "ov", "mi", "z", "c", "", "ge", "gt", "ugt", "nov", "pl", "nz", "nc" }; - // Opcodes #define OP_16 0x80 @@ -996,76 +1003,6 @@ void tlcs90_device::decode() OP( UNKNOWN,2 ) NONE( 1 ) NONE( 2 ) } -static const char *const ir_names[] = { - "P0", "P1", "P01CR/IRFL", "IRFH", "P2", "P2CR", "P3", "P3CR", - "P4", "P4CR", "P5", "SMMOD", "P6", "P7", "P67CR", "SMCR", - "P8", "P8CR", "WDMOD", "WDCR", "TREG0", "TREG1", "TREG2", "TREG3", - "TCLK", "TFFCR", "TMOD", "TRUN", "CAP1L", "CAP1H", "CAP2L", "CAL2H", - "TREG4L", "TREG4H", "TREG5L", "TREG5H", "T4MOD", "T4FFCR", "INTEL", "INTEH", - "DMAEH", "SCMOD", "SCCR", "SCBUF", "BX", "BY", "ADREG", "ADMOD" -}; - -const char *tlcs90_device::internal_registers_names(uint16_t x) -{ - int ir = x - T90_IOBASE; - if ( ir >= 0 && ir < ARRAY_LENGTH(ir_names) ) - return ir_names[ir]; - return nullptr; -} -bool tlcs90_device::stream_arg(std::ostream &stream, uint32_t pc, const char *pre, const e_mode mode, const uint16_t r, const uint16_t rb) -{ - const char *reg_name; - switch ( mode ) - { - case e_mode::NONE: return false; - - case e_mode::BIT8: util::stream_format(stream, "%s%d", pre, r ); return true; - case e_mode::I8: util::stream_format(stream, "%s$%02X", pre, r ); return true; - case e_mode::D8: util::stream_format(stream, "%s$%04X", pre, (pc+2+(r&0x7f)-(r&0x80))&0xffff ); return true; - case e_mode::I16: util::stream_format(stream, "%s$%04X", pre, r ); return true; - case e_mode::D16: util::stream_format(stream, "%s$%04X", pre, (pc+2+(r&0x7fff)-(r&0x8000))&0xffff ); return true; - case e_mode::MI16: - reg_name = internal_registers_names(r); - if (reg_name) - util::stream_format(stream, "%s(%s)", pre, reg_name); - else - util::stream_format(stream, "%s($%04X)", pre, r ); - return true; - case e_mode::R8: util::stream_format(stream, "%s%s", pre, r8_names[r] ); return true; - case e_mode::R16: util::stream_format(stream, "%s%s", pre, r16_names[r] ); return true; - case e_mode::MR16: util::stream_format(stream, "%s(%s)", pre, r16_names[r] ); return true; - - case e_mode::MR16R8: util::stream_format(stream, "%s(%s+%s)", pre, r16_names[r], r8_names[rb] ); return true; - case e_mode::MR16D8: util::stream_format(stream, "%s(%s%c$%02X)", pre, r16_names[r], (rb&0x80)?'-':'+', (rb&0x80)?((rb^0xff)+1):rb ); return true; - - case e_mode::CC: util::stream_format(stream, "%s%s", pre, cc_names[r] ); return true; - - case e_mode::R16R8: util::stream_format(stream, "%s%s+%s", pre, r16_names[r], r8_names[rb] ); return true; - case e_mode::R16D8: util::stream_format(stream, "%s%s%c$%02X", pre, r16_names[r], (rb&0x80)?'-':'+', (rb&0x80)?((rb^0xff)+1):rb ); return true; - - default: - fatalerror("%04x: unimplemented addr mode = %d\n",pc,std::underlying_type_t<e_mode>(mode)); - } - - // never executed - return false; -} - -offs_t tlcs90_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) -{ - m_addr = pc; - - decode(); - m_op &= ~OP_16; - - util::stream_format (stream, "%-5s", op_names[ m_op ] ); // strlen("callr") == 5 - bool streamed = stream_arg (stream, pc, " ", m_mode1, m_r1, m_r1b ); - stream_arg (stream, pc, streamed ?",":"", m_mode2, m_r2, m_r2b ); - - return (m_addr - pc) | DASMFLAG_SUPPORTED; -} - - uint16_t tlcs90_device::r8( const uint16_t r ) { switch( r ) @@ -2055,7 +1992,22 @@ void tlcs90_device::device_reset() dedicated input ports and CPU registers remain unchanged, but PC IFF BX BY = 0, A undefined */ - memset(m_internal_registers, 0, sizeof(m_internal_registers)); + + std::fill(std::begin(m_port_latch), std::end(m_port_latch), 0); + m_p4cr = 0; + m_p67cr = 0; + m_p8cr = 0; + m_smmod = 0; + + m_ixbase = 0; + m_iybase = 0; + + m_tmod = 0; + m_tclk = 0; + m_trun = 0; + m_t4mod = 0; + std::fill(std::begin(m_treg_8bit), std::end(m_treg_8bit), 0); + std::fill(std::begin(m_treg_16bit), std::end(m_treg_16bit), 0); } void tlcs90_device::execute_burn(int32_t cycles) @@ -2337,32 +2289,47 @@ FFED BX R/W Reset Description READ8_MEMBER( tlcs90_device::t90_internal_registers_r ) { - uint8_t data = m_internal_registers[offset]; switch ( T90_IOBASE + offset ) { case T90_P3: // 7,4,1,0 - return (data & 0x6c) | (m_port_read_cb[3]() & 0x93); + return (m_port_latch[3] & 0x6c) | (m_port_read_cb[3]() & 0x93); case T90_P4: // only output - return data & 0x0f; + return m_port_latch[4] & 0x0f; case T90_P5: return (m_port_read_cb[5]() & 0x3f); case T90_P6: - return (data & 0xf0) | (m_port_read_cb[6]() & 0x0f); + return (m_port_latch[6] & 0xf0) | (m_port_read_cb[6]() & 0x0f); case T90_P7: - return (data & 0xf0) | (m_port_read_cb[7]() & 0x0f); + return (m_port_latch[7] & 0xf0) | (m_port_read_cb[7]() & 0x0f); case T90_P8: // 2,1,0 - return (data & 0x08) | (m_port_read_cb[8]() & 0x07); + return (m_port_latch[8] & 0x08) | (m_port_read_cb[8]() & 0x07); case T90_BX: + return 0xf0 | (m_ixbase >> 16); + case T90_BY: - return 0xf0 | data; + return 0xf0 | (m_iybase >> 16); + + case T90_TMOD: + return m_tmod; + + case T90_TCLK: + return m_tclk; + + case T90_TRUN: + return m_trun; + + case T90_T4MOD: + return m_t4mod; } - return data; + + logerror("Read from unimplemented SFR at %04X\n", T90_IOBASE + offset); + return 0; } void tlcs90_device::t90_start_timer(int i) @@ -2372,7 +2339,7 @@ void tlcs90_device::t90_start_timer(int i) m_timer_value[i] = 0; - switch((m_internal_registers[ T90_TMOD - T90_IOBASE ] >> (i * 2)) & 0x03) + switch((m_tmod >> (i * 2)) & 0x03) { case 0: // 8-bit mode @@ -2388,7 +2355,7 @@ void tlcs90_device::t90_start_timer(int i) return; } - switch((m_internal_registers[ T90_TCLK - T90_IOBASE ] >> (i * 2)) & 0x03) + switch((m_tclk >> (i * 2)) & 0x03) { case 0: if (i & 1) logerror("%04X: CPU Timer %d clocked by Timer %d match signal\n", m_pc.w.l, i,i-1); else logerror("%04X: CPU Timer %d, unsupported TCLK = 0\n", m_pc.w.l, i); @@ -2414,11 +2381,11 @@ void tlcs90_device::t90_start_timer4() m_timer4_value = 0; - switch(m_internal_registers[ T90_T4MOD - T90_IOBASE ] & 0x03) + switch(m_t4mod & 0x03) { case 1: prescaler = 1; break; case 2: prescaler = 16; break; - default: logerror("%04X: CPU Timer 4, unsupported T4MOD = %d\n", m_pc.w.l,m_internal_registers[ T90_T4MOD - T90_IOBASE ] & 0x03); + default: logerror("%04X: CPU Timer 4, unsupported T4MOD = %d\n", m_pc.w.l,m_t4mod & 0x03); return; } @@ -2447,12 +2414,12 @@ TIMER_CALLBACK_MEMBER( tlcs90_device::t90_timer_callback ) int i = param; int mask = 0x20 | (1 << i); - if ( (m_internal_registers[ T90_TRUN - T90_IOBASE ] & mask) != mask ) + if ( (m_trun & mask) != mask ) return; timer_fired = 0; - mode = (m_internal_registers[ T90_TMOD - T90_IOBASE ] >> ((i & ~1) + 2)) & 0x03; + mode = (m_tmod >> ((i & ~1) + 2)) & 0x03; // Match switch (mode) { @@ -2462,7 +2429,7 @@ TIMER_CALLBACK_MEMBER( tlcs90_device::t90_timer_callback ) // TODO: hmm... case 0x00: // 8bit m_timer_value[i]++; - if ( m_timer_value[i] == m_internal_registers[ T90_TREG0+i - T90_IOBASE ] ) + if ( m_timer_value[i] == m_treg_8bit[i] ) timer_fired = 1; break; @@ -2471,8 +2438,8 @@ TIMER_CALLBACK_MEMBER( tlcs90_device::t90_timer_callback ) break; m_timer_value[i]++; if(m_timer_value[i] == 0) m_timer_value[i+1]++; - if(m_timer_value[i+1] == m_internal_registers[ T90_TREG0+i+1 - T90_IOBASE ]) - if(m_timer_value[i] == m_internal_registers[ T90_TREG0+i - T90_IOBASE ]) + if(m_timer_value[i+1] == m_treg_8bit[i+1]) + if(m_timer_value[i] == m_treg_8bit[i]) timer_fired = 1; break; } @@ -2486,7 +2453,7 @@ TIMER_CALLBACK_MEMBER( tlcs90_device::t90_timer_callback ) case 0x00: // 8bit if(i & 1) break; - if ( (m_internal_registers[ T90_TCLK - T90_IOBASE ] & (0x0C << (i * 2))) == 0 ) // T0/T1 match signal clocks T1/T3 + if ( (m_tclk & (0x0C << (i * 2))) == 0 ) // T0/T1 match signal clocks T1/T3 t90_timer_callback(ptr, i+1); break; case 0x01: // 16bit, only can happen for i=0,2 @@ -2508,16 +2475,16 @@ TIMER_CALLBACK_MEMBER( tlcs90_device::t90_timer4_callback ) // Match - if ( m_timer4_value == (m_internal_registers[ T90_TREG4L - T90_IOBASE ] + (m_internal_registers[ T90_TREG4H - T90_IOBASE ] << 8)) ) + if ( m_timer4_value == m_treg_16bit[0] ) { // logerror("CPU Timer 4 matches TREG4\n"); set_irq_line(INTT4, 1); } - if ( m_timer4_value == (m_internal_registers[ T90_TREG5L - T90_IOBASE ] + (m_internal_registers[ T90_TREG5H - T90_IOBASE ] << 8)) ) + if ( m_timer4_value == m_treg_16bit[1] ) { // logerror("CPU Timer 4 matches TREG5\n"); set_irq_line(INTT5, 1); - if (m_internal_registers[ T90_T4MOD - T90_IOBASE ] & 0x04) + if (m_t4mod & 0x04) m_timer4_value = 0; } @@ -2532,13 +2499,58 @@ TIMER_CALLBACK_MEMBER( tlcs90_device::t90_timer4_callback ) WRITE8_MEMBER( tlcs90_device::t90_internal_registers_w ) { uint8_t out_mask; - uint8_t old = m_internal_registers[offset]; + switch ( T90_IOBASE + offset ) { + case T90_TMOD: + m_tmod = data; + break; + + case T90_TCLK: + m_tclk = data; + break; + + case T90_TREG0: + m_treg_8bit[0] = data; + break; + + case T90_TREG1: + m_treg_8bit[1] = data; + break; + + case T90_TREG2: + m_treg_8bit[2] = data; + break; + + case T90_TREG3: + m_treg_8bit[3] = data; + break; + + case T90_T4MOD: + m_t4mod = data; + break; + + case T90_TREG4L: + m_treg_16bit[0] = (m_treg_16bit[0] & 0xff00) | data; + break; + + case T90_TREG4H: + m_treg_16bit[0] = (m_treg_16bit[0] & 0x00ff) | (data << 8); + break; + + case T90_TREG5L: + m_treg_16bit[1] = (m_treg_16bit[1] & 0xff00) | data; + break; + + case T90_TREG5H: + m_treg_16bit[1] = (m_treg_16bit[1] & 0x00ff) | (data << 8); + break; + case T90_TRUN: { int i; uint8_t mask; + uint8_t old = m_trun; // Timers 0-3 for (i = 0; i < 4; i++) { @@ -2557,6 +2569,8 @@ WRITE8_MEMBER( tlcs90_device::t90_internal_registers_w ) if ( (data & mask) == mask ) t90_start_timer4(); else t90_stop_timer4(); } + + m_trun = data; break; } @@ -2590,24 +2604,29 @@ WRITE8_MEMBER( tlcs90_device::t90_internal_registers_w ) ((data & 0x01) ? (1 << INTT1) : 0) ; break; + case T90_IRFH: + if (data >= int(INTSWI) + 2 && data < int(INTMAX) + 2) + m_irq_state &= ~(1 << (data - 2)); + break; + case T90_P3: - data &= 0x6c; - m_port_write_cb[3](data); + m_port_latch[3] = data & 0x6c; + m_port_write_cb[3](m_port_latch[3]); break; case T90_P4: - data &= 0x0f; - out_mask = (~m_internal_registers[ T90_P4CR - T90_IOBASE ]) & 0x0f; + m_port_latch[4] = data & 0x0f; + out_mask = ~m_p4cr & 0x0f; if (out_mask) { - data &= out_mask; - m_port_write_cb[4](data); + m_port_write_cb[4](m_port_latch[4] & out_mask); } break; case T90_P6: - out_mask = m_internal_registers[ T90_P67CR - T90_IOBASE ] & 0x0f; - switch (m_internal_registers[ T90_SMMOD - T90_IOBASE ] & 0x03) + m_port_latch[6] = data & 0x0f; + out_mask = m_p67cr & 0x0f; + switch (m_smmod & 0x03) { case 1: data &= ~0x01; @@ -2622,14 +2641,14 @@ WRITE8_MEMBER( tlcs90_device::t90_internal_registers_w ) if (out_mask) { - data &= out_mask; - m_port_write_cb[6](data); + m_port_write_cb[6](m_port_latch[6] & out_mask); } break; case T90_P7: - out_mask = (m_internal_registers[ T90_P67CR - T90_IOBASE ] & 0xf0) >> 4; - switch ((m_internal_registers[ T90_SMMOD - T90_IOBASE ]>>4) & 0x03) + m_port_latch[7] = data & 0x0f; + out_mask = m_p67cr >> 4; + switch ((m_smmod >> 4) & 0x03) { case 1: data &= ~0x01; @@ -2644,29 +2663,47 @@ WRITE8_MEMBER( tlcs90_device::t90_internal_registers_w ) if (out_mask) { - data &= out_mask; - m_port_write_cb[7](data); + m_port_write_cb[7](m_port_latch[7] & out_mask); } break; case T90_P8: - data &= 0x0f; - out_mask = (~m_internal_registers[ T90_P8CR - T90_IOBASE ]) & 0x08; + m_port_latch[8] = data & 0x0f; + out_mask = ~m_p8cr & 0x08; if (out_mask) { - data &= out_mask; - m_port_write_cb[8](data); + m_port_write_cb[8](m_port_latch[8] & out_mask); } break; + case T90_P4CR: + m_p4cr = data; + break; + + case T90_P67CR: + m_p67cr = data; + break; + + case T90_P8CR: + m_p8cr = data; + break; + + case T90_SMMOD: + m_smmod = data; + break; + case T90_BX: m_ixbase = (data & 0xf) << 16; break; + case T90_BY: m_iybase = (data & 0xf) << 16; break; + + default: + logerror("Write to unimplemented SFR at %04X\n", T90_IOBASE + offset); + break; } - m_internal_registers[offset] = data; } @@ -2696,12 +2733,22 @@ void tlcs90_device::device_start() save_item(NAME(m_irq_mask)); save_item(NAME(m_extra_cycles)); - save_item(NAME(m_internal_registers)); + save_item(NAME(m_port_latch)); + save_item(NAME(m_p4cr)); + save_item(NAME(m_p67cr)); + save_item(NAME(m_p8cr)); + save_item(NAME(m_smmod)); save_item(NAME(m_ixbase)); save_item(NAME(m_iybase)); save_item(NAME(m_timer_value)); save_item(NAME(m_timer4_value)); + save_item(NAME(m_tmod)); + save_item(NAME(m_tclk)); + save_item(NAME(m_trun)); + save_item(NAME(m_treg_8bit)); + save_item(NAME(m_t4mod)); + save_item(NAME(m_treg_16bit)); // Work registers save_item(NAME(m_op)); @@ -2745,7 +2792,6 @@ void tlcs90_device::device_start() m_halt = m_after_EI = 0; m_irq_state = m_irq_mask = 0; m_extra_cycles = 0; - memset(m_internal_registers, 0, sizeof(m_internal_registers)); m_ixbase = m_iybase = 0; m_timer_value[0] = m_timer_value[1] = m_timer_value[2] = m_timer_value[3] = 0; m_timer4_value = 0; @@ -2811,3 +2857,8 @@ void tlcs90_device::state_string_export(const device_state_entry &entry, std::st break; } } + +util::disasm_interface *tlcs90_device::create_disassembler() +{ + return new tlcs90_disassembler; +} diff --git a/src/devices/cpu/tlcs90/tlcs90.h b/src/devices/cpu/tlcs90/tlcs90.h index 6677ff7e628..589eae3025c 100644 --- a/src/devices/cpu/tlcs90/tlcs90.h +++ b/src/devices/cpu/tlcs90/tlcs90.h @@ -63,18 +63,6 @@ devcb = &tlcs90_device::set_port_write_cb(*device, 8, DEVCB_##_devcb); -#define T90_IOBASE 0xffc0 - -enum e_ir -{ - T90_P0=T90_IOBASE, T90_P1, T90_P01CR_IRFL, T90_IRFH, T90_P2, T90_P2CR, T90_P3, T90_P3CR, - T90_P4, T90_P4CR, T90_P5, T90_SMMOD, T90_P6, T90_P7, T90_P67CR, T90_SMCR, - T90_P8, T90_P8CR, T90_WDMOD, T90_WDCR, T90_TREG0, T90_TREG1, T90_TREG2, T90_TREG3, - T90_TCLK, T90_TFFCR, T90_TMOD, T90_TRUN, T90_CAP1L, T90_CAP1H, T90_CAP2L, T90_CAL2H, - T90_TREG4L, T90_TREG4H, T90_TREG5L, T90_TREG5H, T90_T4MOD, T90_T4FFCR, T90_INTEL, T90_INTEH, - T90_DMAEH, T90_SCMOD, T90_SCCR, T90_SCBUF, T90_BX, T90_BY, T90_ADREG, T90_ADMOD -}; - enum tlcs90_e_irq { INTSWI = 0, INTNMI, INTWD, INT0, INTT0, INTT1, INTT2, INTT3, INTT4, INT1, INTT5, INT2, INTRX, INTTX, INTMAX }; DECLARE_ENUM_INCDEC_OPERATORS(tlcs90_e_irq) @@ -131,9 +119,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 6; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: enum class e_mode : u8 { @@ -156,7 +142,14 @@ private: address_space *m_program; int m_icount; int m_extra_cycles; // extra cycles for interrupts - uint8_t m_internal_registers[48]; + + uint8_t m_port_latch[MAX_PORTS]; + + uint8_t m_p4cr; + uint8_t m_p67cr; + uint8_t m_p8cr; + uint8_t m_smmod; + uint32_t m_ixbase,m_iybase; // Timers: 4 x 8-bit + 1 x 16-bit @@ -164,6 +157,12 @@ private: uint8_t m_timer_value[4]; uint16_t m_timer4_value; attotime m_timer_period; + uint8_t m_tmod; + uint8_t m_tclk; + uint8_t m_trun; + uint8_t m_treg_8bit[4]; + uint8_t m_t4mod; + uint16_t m_treg_16bit[2]; // Work registers uint8_t m_op; @@ -189,8 +188,6 @@ private: inline uint8_t READ8(); inline uint16_t READ16(); void decode(); - const char *internal_registers_names(uint16_t x); - bool stream_arg(std::ostream &stream, uint32_t pc, const char *pre, const e_mode mode, const uint16_t r, const uint16_t rb); inline uint16_t r8( const uint16_t r ); inline void w8( const uint16_t r, uint16_t value ); inline uint16_t r16( const uint16_t r ); diff --git a/src/devices/cpu/tlcs90/tlcs90d.cpp b/src/devices/cpu/tlcs90/tlcs90d.cpp new file mode 100644 index 00000000000..66787e84528 --- /dev/null +++ b/src/devices/cpu/tlcs90/tlcs90d.cpp @@ -0,0 +1,952 @@ +// license:BSD-3-Clause +// copyright-holders:Luca Elia +/************************************************************************************************************* + + Toshiba TLCS-90 Series MCU's + + emulation by Luca Elia, based on the Z80 core by Juergen Buchmueller + + ChangeLog: + + 20150517 Fixed TRUN bit masking (timers start/stop handling) [Rainer Keuchel] + +*************************************************************************************************************/ + +#include "emu.h" +#include "tlcs90d.h" + +const char *const tlcs90_disassembler::op_names[] = { "??", "nop", "ex", "exx", "ld", "ldw", "lda", "ldi", "ldir", "ldd", "lddr", "cpi", "cpir", "cpd", "cpdr", "push", "pop", "jp", "jr", "call", "callr", "ret", "reti", "halt", "di", "ei", "swi", "daa", "cpl", "neg", "ldar", "rcf", "scf", "ccf", "tset", "bit", "set", "res", "inc", "dec", "incx", "decx", "incw", "decw", "add", "adc", "sub", "sbc", "and", "xor", "or", "cp", "rlc", "rrc", "rl", "rr", "sla", "sra", "sll", "srl", "rld", "rrd", "djnz", "mul", "div" }; + +const char *const tlcs90_disassembler::r8_names[] = { "b", "c", "d", "e", "h", "l", "a" }; +const char *const tlcs90_disassembler::r16_names[] = { "bc", "de", "hl", "??", "ix", "iy", "sp", "af", "af'", "pc" }; + +const char *const tlcs90_disassembler::cc_names[] = { "f", "lt", "le", "ule", "ov", "mi", "z", "c", "", "ge", "gt", "ugt", "nov", "pl", "nz", "nc" }; + +u32 tlcs90_disassembler::opcode_alignment() const +{ + return 1; +} + +const char *const tlcs90_disassembler::ir_names[] = { + "P0", "P1", "P01CR/IRFL", "IRFH", "P2", "P2CR", "P3", "P3CR", + "P4", "P4CR", "P5", "SMMOD", "P6", "P7", "P67CR", "SMCR", + "P8", "P8CR", "WDMOD", "WDCR", "TREG0", "TREG1", "TREG2", "TREG3", + "TCLK", "TFFCR", "TMOD", "TRUN", "CAP1L", "CAP1H", "CAP2L", "CAL2H", + "TREG4L", "TREG4H", "TREG5L", "TREG5H", "T4MOD", "T4FFCR", "INTEL", "INTEH", + "DMAEH", "SCMOD", "SCCR", "SCBUF", "BX", "BY", "ADREG", "ADMOD" +}; + +#define T90_IOBASE 0xffc0 + +const char *tlcs90_disassembler::internal_registers_names(uint16_t x) +{ + // FIXME: TMP90PH44 and many other models have completely different SFR maps + int ir = x - T90_IOBASE; + if ( ir >= 0 && ir < ARRAY_LENGTH(ir_names) ) + return ir_names[ir]; + return nullptr; +} + +#define B 0 +#define C 1 +#define D 2 +#define E 3 +#define H 4 +#define L 5 +#define A 6 + +#define BC 0 +#define DE 1 +#define HL 2 +// 3 +#define IX 4 +#define IY 5 +#define SP 6 + +#define AF 7 +#define AF2 8 +#define PC 9 + +#define FLS 0x0 +#define LT 0x1 +#define LE 0x2 +#define ULE 0x3 +#define OV 0x4 +#define PE 0x4 +#define MI 0x5 +#define Z 0x6 +#define EQ 0x6 +#define CR 0x7 +#define ULT 0x7 +#define T 0x8 +#define GE 0x9 +#define GT 0xa +#define UGT 0xb +#define NOV 0xc +#define PO 0xc +#define PL 0xd +#define NZ 0xe +#define NE 0xe +#define NC 0xf +#define UGE 0xf + +#define CF 0x01 +#define NF 0x02 +#define PF 0x04 +#define VF PF +#define XCF 0x08 +#define HF 0x10 +#define IF 0x20 +#define ZF 0x40 +#define SF 0x80 + +#define OP( X,CT ) m_op = X; +#define OP16( X,CT ) m_op = X; + +#define OPCC( X,CF,CT ) m_op = X; +#define OPCC16( X,CF,CT ) m_op = X; + +#define BIT8( N,I ) m_mode##N = e_mode::BIT8; m_r##N = I; +#define I8( N,I ) m_mode##N = e_mode::I8; m_r##N = I; +#define D8( N,I ) m_mode##N = e_mode::D8; m_r##N = I; +#define I16( N,I ) m_mode##N = e_mode::I16; m_r##N = I; +#define D16( N,I ) m_mode##N = e_mode::D16; m_r##N = I; +#define R8( N,R ) m_mode##N = e_mode::R8; m_r##N = R; +#define R16( N,R ) m_mode##N = e_mode::R16; m_r##N = R; +#define Q16( N,R ) m_mode##N = e_mode::R16; m_r##N = R; if (m_r##N == SP) m_r##N = AF; +#define MI16( N,I ) m_mode##N = e_mode::MI16; m_r##N = I; +#define MR16( N,R ) m_mode##N = e_mode::MR16; m_r##N = R; +#define MR16D8( N,R,I ) m_mode##N = e_mode::MR16D8; m_r##N = R; m_r##N##b = I; +#define MR16R8( N,R,g ) m_mode##N = e_mode::MR16R8; m_r##N = R; m_r##N##b = g; +#define NONE( N ) m_mode##N = e_mode::NONE; +#define CC( N,cc ) m_mode##N = e_mode::CC; m_r##N = cc; +#define R16D8( N,R,I ) m_mode##N = e_mode::R16D8; m_r##N = R; m_r##N##b = I; +#define R16R8( N,R,g ) m_mode##N = e_mode::R16R8; m_r##N = R; m_r##N##b = g; + +uint8_t tlcs90_disassembler::READ8() +{ + uint8_t b0 = m_opcodes->r8( m_addr++ ); + m_addr &= 0xffff; + return b0; +} +uint16_t tlcs90_disassembler::READ16() +{ + uint8_t b0 = READ8(); + return b0 | (READ8() << 8); +} + +void tlcs90_disassembler::decode() +{ + uint8_t b0, b1, b2, b3; + uint16_t imm16; + + b0 = READ8(); + + switch ( b0 ) + { + case 0x00: + OP( NOP,2 ) NONE( 1 ) NONE( 2 ) return; // NOP + + case 0x01: + OP( HALT,4 ) NONE( 1 ) NONE( 2 ) return; // HALT + case 0x02: + OP( DI,2 ) NONE( 1 ) NONE( 2 ) return; // DI + case 0x03: + OP( EI,2 ) NONE( 1 ) NONE( 2 ) return; // EI + + case 0x07: + OPCC( INCX,6,10 ) MI16( 1, 0xFF00|READ8() ) NONE( 2 ) return; // INCX ($FF00+n) + + case 0x08: + OP( EX,2 ) R16( 1, DE ) R16( 2, HL ) return; // EX DE,HL + case 0x09: + OP( EX,2 ) R16( 1, AF ) R16( 2, AF2 ) return; // EX AF,AF' + case 0x0a: + OP( EXX,2 ) NONE( 1 ) NONE( 2 ) return; // EXX + + case 0x0b: + OP( DAA,4 ) R8( 1, A ) NONE( 2 ) return; // DAA A + + case 0x0c: + OP( RCF,2 ) NONE( 1 ) NONE( 2 ) return; // RCF + case 0x0d: + OP( SCF,2 ) NONE( 1 ) NONE( 2 ) return; // SCF + case 0x0e: + OP( CCF,2 ) NONE( 1 ) NONE( 2 ) return; // CCF + + case 0x0f: + OPCC( DECX,6,10 ) MI16( 1, 0xFF00|READ8() ) NONE( 2 ) return; // DECX ($FF00+n) + + case 0x10: + OP( CPL,2 ) R8( 1, A ) NONE( 2 ) return; // CPL A + case 0x11: + OP( NEG,2 ) R8( 1, A ) NONE( 2 ) return; // NEG A + + case 0x12: // MUL HL,n + case 0x13: // DIV HL,n + OP( MUL+b0-0x12,16) R16( 1, HL ) I8( 2, READ8() ) return; + + case 0x14: case 0x15: case 0x16: + OP16( ADD,6 ) R16( 1, IX+b0-0x14 ) I16( 2, READ16() ) return; // ADD ix,mn + + case 0x17: + OP( LDAR,8 ) R16( 1, HL ) D16( 2, READ16() ) return; // LDAR HL,+cd + + case 0x18: + OP( DJNZ,10 ) D8( 1, READ8() ) NONE( 2 ) return; // DJNZ +d + case 0x19: + OP16( DJNZ,10 ) R16( 1, BC ) D8( 2, READ8() ) return; // DJNZ BC,+d + + case 0x1a: + OPCC( JP,8,8 ) CC( 1, T ) I16( 2, READ16() ) return; // JP T,mn + case 0x1b: + OPCC16( JR,10,10 ) CC( 1, T ) D16( 2, READ16() ) return; // JR T,+cd + + case 0x1c: + OPCC( CALL,14,14 ) CC( 1, T ) I16( 2, READ16() ) return; // CALL T,mn + case 0x1d: + OP( CALLR,16 ) D16( 1, READ16() ) NONE( 2 ) return; // CALLR +cd + + case 0x1e: + OPCC( RET,10,10 ) CC( 1, T ) NONE( 2 ) return; // RET T + case 0x1f: + OP( RETI,14 ) NONE( 1 ) NONE( 2 ) return; // RETI + + case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: + OP( LD,2 ) R8( 1, A ) R8( 2, b0 - 0x20 ) return; // LD A,r + + case 0x27: + OP( LD,8 ) R8( 1, A ) MI16( 2, 0xFF00|READ8() ) return; // LD A,($FF00+n) + + case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: + OP( LD,2 ) R8( 1, b0 - 0x28 ) R8( 2, A ) return; // LD r,A + + case 0x2f: + OP( LD,8 ) MI16( 1, 0xFF00|READ8() ) R8( 2, A ) return; // LD ($FF00+n), A + + case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: + OP( LD,4 ) R8( 1, b0 - 0x30 ) I8( 2, READ8() ) return; // LD r,n + + case 0x37: + OP( LD,10 ) MI16( 1, 0xFF00|READ8() ) I8( 2, READ8() ) return; // LD ($FF00+w),n + + case 0x38: case 0x39: case 0x3a: /*case 0x3b:*/ case 0x3c: case 0x3d: case 0x3e: + OP16( LD,6 ) R16( 1, b0 - 0x38 ) I16( 2, READ16() ) return; // LD rr,nn + + case 0x3f: + OP( LDW,14 ) MI16( 1, 0xFF00|READ8() ) I16( 2, READ16() ) return; // LDW ($FF00+w),mn + + case 0x40: case 0x41: case 0x42: /*case 0x43:*/ case 0x44: case 0x45: case 0x46: + OP16( LD,4 ) R16( 1, HL ) R16( 2, b0 - 0x40 ) return; // LD HL,rr + + case 0x47: + OP16( LD,10 ) R16( 1, HL ) MI16( 2, 0xFF00|READ8() ) return; // LD HL,($FF00+n) + + case 0x48: case 0x49: case 0x4a: /*case 0x4b:*/ case 0x4c: case 0x4d: case 0x4e: + OP16( LD,4 ) R16( 1, b0 - 0x48 ) R16( 2, HL ) return; // LD rr,HL + + case 0x4f: + OP16( LD,10 ) MI16( 1, 0xFF00|READ8() ) R16( 2, HL ) return; // LD ($FF00+n), HL + + case 0x50: case 0x51: case 0x52: /*case 0x53:*/ case 0x54: case 0x55: case 0x56: + OP( PUSH,8 ) Q16( 1, b0 - 0x50 ) NONE( 2 ) return; // PUSH qq + case 0x58: case 0x59: case 0x5a: /*case 0x5b:*/ case 0x5c: case 0x5d: case 0x5e: + OP( POP,10 ) Q16( 1, b0 - 0x58 ) NONE( 2 ) return; // POP qq + + case 0x60: // ADD A,($FF00+n) + case 0x61: // ADC A,($FF00+n) + case 0x62: // SUB A,($FF00+n) + case 0x63: // SBC A,($FF00+n) + case 0x64: // AND A,($FF00+n) + case 0x65: // XOR A,($FF00+n) + case 0x66: // OR A,($FF00+n) + case 0x67: // CP A,($FF00+n) + OP( ADD+b0-0x60,8 ) R8( 1, A ) MI16( 2, 0xFF00|READ8() ) return; + + case 0x68: // ADD A,n + case 0x69: // ADC A,n + case 0x6a: // SUB A,n + case 0x6b: // SBC A,n + case 0x6c: // AND A,n + case 0x6d: // XOR A,n + case 0x6e: // OR A,n + case 0x6f: // CP A,n + OP( ADD+b0-0x68,4 ) R8( 1, A ) I8( 2, READ8() ) return; + + case 0x70: // ADD HL,($FF00+n) + case 0x71: // ADC HL,($FF00+n) + case 0x72: // SUB HL,($FF00+n) + case 0x73: // SBC HL,($FF00+n) + case 0x74: // AND HL,($FF00+n) + case 0x75: // XOR HL,($FF00+n) + case 0x76: // OR HL,($FF00+n) + case 0x77: // CP HL,($FF00+n) + OP16( ADD+b0-0x70,10 ) R16( 1, HL ) MI16( 2, 0xFF00|READ8() ) return; + + case 0x78: // ADD HL,mn + case 0x79: // ADC HL,mn + case 0x7a: // SUB HL,mn + case 0x7b: // SBC HL,mn + case 0x7c: // AND HL,mn + case 0x7d: // XOR HL,mn + case 0x7e: // OR HL,mn + case 0x7f: // CP HL,mn + OP16( ADD+b0-0x78,6 ) R16( 1, HL ) I16( 2, READ16() ) return; + + case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: + OP( INC,2 ) R8( 1, b0 - 0x80 ) NONE( 2 ) return; // INC r + case 0x87: + OP( INC,10 ) MI16( 1, 0xFF00|READ8() ) NONE( 2 ) return; // INC ($FF00+n) + + case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: + OP( DEC,2 ) R8( 1, b0 - 0x88 ) NONE( 2 ) return; // DEC r + case 0x8f: + OP( DEC,10 ) MI16( 1, 0xFF00|READ8() ) NONE( 2 ) return; // DEC ($FF00+n) + + case 0x90: case 0x91: case 0x92: /*case 0x93:*/ case 0x94: case 0x95: case 0x96: + OP16( INC,4 ) R16( 1, b0 - 0x90 ) NONE( 2 ) return; // INC rr + case 0x97: + OP( INCW,14 ) MI16( 1, 0xFF00|READ8() ) NONE( 2 ) return; // INCW ($FF00+n) + case 0x98: case 0x99: case 0x9a: /*case 0x9b:*/ case 0x9c: case 0x9d: case 0x9e: + OP16( DEC,4 ) R16( 1, b0 - 0x98 ) NONE( 2 ) return; // DEC rr + case 0x9f: + OP( DECW,14 ) MI16( 1, 0xFF00|READ8() ) NONE( 2 ) return; // DECW ($FF00+n) + + case 0xa0: // RLC A + case 0xa1: // RRC A + case 0xa2: // RL A + case 0xa3: // RR A + case 0xa4: // SLA A + case 0xa5: // SRA A + case 0xa6: // SLL A + case 0xa7: // SRL A + OP( RLC+b0-0xa0,2 ) R8( 1, A ) NONE( 2 ) return; + + case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf: + OP( BIT,8 ) BIT8( 1, b0 - 0xa8 ) MI16( 2, 0xFF00|READ8() ) return; // BIT b,($FF00+n) + case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: + OP( RES,12 ) BIT8( 1, b0 - 0xb0 ) MI16( 2, 0xFF00|READ8() ) return; // RES b,($FF00+n) + case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf: + OP( SET,12 ) BIT8( 1, b0 - 0xb8 ) MI16( 2, 0xFF00|READ8() ) return; // SET b,($FF00+n) + + case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: + case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: + OPCC( JR,4,8 ) CC( 1, b0 - 0xc0 ) D8( 2, READ8() ) return; // JR cc,+d + + case 0xe0: case 0xe1: case 0xe2: /*case 0xe3:*/ case 0xe4: case 0xe5: case 0xe6: + b1 = READ8(); + switch ( b1 ) { + case 0x10: // RLD (gg) + case 0x11: // RRD (gg) + OP( RLD+b1-0x10,12 ) MR16( 1, b0 - 0xe0 ) NONE( 2 ) return; + + case 0x12: // MUL HL,(gg) + case 0x13: // DIV HL,(gg) + OP( MUL+b1-0x12,18 ) R16( 1, HL ) MR16( 2, b0 - 0xe0 ) return; + + case 0x14: case 0x15: case 0x16: + OP16( ADD,8 ) R16( 1, IX+b1-0x14 ) MR16( 2, b0 - 0xe0 ) return; // ADD ix,(gg) + + case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: + OP( LD,6 ) R8( 1, b1 - 0x28 ) MR16( 2, b0 - 0xe0 ) return; // LD r,(gg) + case 0x48: case 0x49: case 0x4a: /*case 0x4b:*/ case 0x4c: case 0x4d: case 0x4e: + OP16( LD,8 ) R16( 1, b1 - 0x48 ) MR16( 2, b0 - 0xe0 ) return; // LD rr,(gg) + + case 0x50: case 0x51: case 0x52: /*case 0x53:*/ case 0x54: case 0x55: case 0x56: + OP( EX,14 ) MR16( 1, b0 - 0xe0 ) R16( 2, b1 - 0x50 ) return; // EX (gg),rr + + case 0x60: // ADD A,(gg) + case 0x61: // ADC A,(gg) + case 0x62: // SUB A,(gg) + case 0x63: // SBC A,(gg) + case 0x64: // AND A,(gg) + case 0x65: // XOR A,(gg) + case 0x66: // OR A,(gg) + case 0x67: // CP A,(gg) + OP( ADD+b1-0x60,6 ) R8( 1, A ) MR16( 2, b0 - 0xe0 ) return; + + case 0x70: // ADD HL,(gg) + case 0x71: // ADC HL,(gg) + case 0x72: // SUB HL,(gg) + case 0x73: // SBC HL,(gg) + case 0x74: // AND HL,(gg) + case 0x75: // XOR HL,(gg) + case 0x76: // OR HL,(gg) + case 0x77: // CP HL,(gg) + OP16( ADD+b1-0x70,8 ) R16( 1, HL ) MR16( 2, b0 - 0xe0 ) return; + + case 0x87: + OP( INC,8 ) MR16( 1, b0 - 0xe0 ) NONE( 2 ) return; // INC (gg) + case 0x8f: + OP( DEC,8 ) MR16( 1, b0 - 0xe0 ) NONE( 2 ) return; // DEC (gg) + + case 0x97: + OP( INCW,12 ) MR16( 1, b0 - 0xe0 ) NONE( 2 ) return; // INCW (gg) + case 0x9f: + OP( DECW,12 ) MR16( 1, b0 - 0xe0 ) NONE( 2 ) return; // DECW (gg) + + case 0xa0: // RLC (gg) + case 0xa1: // RRC (gg) + case 0xa2: // RL (gg) + case 0xa3: // RR (gg) + case 0xa4: // SLA (gg) + case 0xa5: // SRA (gg) + case 0xa6: // SLL (gg) + case 0xa7: // SRL (gg) + OP( RLC+b1-0xa0,8 ) MR16( 1, b0 - 0xe0 ) NONE( 2 ) return; + + case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: + OP( TSET,12 ) BIT8( 1, b1 - 0x18 ) MR16( 2, b0 - 0xe0 ) return; // TSET b,(gg) + case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf: + OP( BIT,6 ) BIT8( 1, b1 - 0xa8 ) MR16( 2, b0 - 0xe0 ) return; // BIT b,(gg) + case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: + OP( RES,10 ) BIT8( 1, b1 - 0xb0 ) MR16( 2, b0 - 0xe0 ) return; // RES b,(gg) + case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf: + OP( SET,10 ) BIT8( 1, b1 - 0xb8 ) MR16( 2, b0 - 0xe0 ) return; // SET b,(gg) + } break; + case 0xe3: + imm16 = READ16(); + b3 = READ8(); + switch ( b3 ) { + case 0x10: // RLD (mn) + case 0x11: // RRD (mn) + OP( RLD+b3-0x10,16 ) MI16( 1, imm16 ) NONE( 2 ) return; + + case 0x12: // MUL HL,(mn) + case 0x13: // DIV HL,(mn) + OP( MUL+b3-0x12,22 ) R16( 1, HL ) MI16( 2, imm16 ) return; + + case 0x14: case 0x15: case 0x16: + OP16( ADD,12 ) R16( 1, IX+b3-0x14 ) MI16( 2, imm16 ) return; // ADD ix,(mn) + + case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: + OP( LD,10 ) R8( 1, b3 - 0x28 ) MI16( 2, imm16 ) return; // LD r,(mn) + case 0x48: case 0x49: case 0x4a: /*case 0x4b:*/ case 0x4c: case 0x4d: case 0x4e: + OP16( LD,12 ) R16( 1, b3 - 0x48 ) MI16( 2, imm16 ) return; // LD rr,(mn) + + case 0x50: case 0x51: case 0x52: /*case 0x53:*/ case 0x54: case 0x55: case 0x56: + OP( EX,18 ) MI16( 1, imm16 ) R16( 2, b3 - 0x50 ) return; // EX (mn),rr + + case 0x60: // ADD A,(mn) + case 0x61: // ADC A,(mn) + case 0x62: // SUB A,(mn) + case 0x63: // SBC A,(mn) + case 0x64: // AND A,(mn) + case 0x65: // XOR A,(mn) + case 0x66: // OR A,(mn) + case 0x67: // CP A,(mn) + OP( ADD+b3-0x60,10 ) R8( 1, A ) MI16( 2, imm16 ) return; + + case 0x70: // ADD HL,(mn) + case 0x71: // ADC HL,(mn) + case 0x72: // SUB HL,(mn) + case 0x73: // SBC HL,(mn) + case 0x74: // AND HL,(mn) + case 0x75: // XOR HL,(mn) + case 0x76: // OR HL,(mn) + case 0x77: // CP HL,(mn) + OP16( ADD+b3-0x70,12 ) R16( 1, HL ) MI16( 2, imm16 ) return; + + case 0x87: + OP( INC,12 ) MI16( 1, imm16 ) NONE( 2 ) return; // INC (mn) + case 0x8f: + OP( DEC,12 ) MI16( 1, imm16 ) NONE( 2 ) return; // DEC (mn) + + case 0x97: + OP( INCW,16 ) MI16( 1, imm16 ) NONE( 2 ) return; // INCW (mn) + case 0x9f: + OP( DECW,16 ) MI16( 1, imm16 ) NONE( 2 ) return; // DECW (mn) + + case 0xa0: // RLC (mn) + case 0xa1: // RRC (mn) + case 0xa2: // RL (mn) + case 0xa3: // RR (mn) + case 0xa4: // SLA (mn) + case 0xa5: // SRA (mn) + case 0xa6: // SLL (mn) + case 0xa7: // SRL (mn) + OP( RLC+b3-0xa0,12 ) MI16( 1, imm16 ) NONE( 2 ) return; + + case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: + OP( TSET,16 ) BIT8( 1, b3 - 0x18 ) MI16( 2, imm16 ) return; // TSET b,(mn) + case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf: + OP( BIT,10 ) BIT8( 1, b3 - 0xa8 ) MI16( 2, imm16 ) return; // BIT b,(mn) + case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: + OP( RES,14 ) BIT8( 1, b3 - 0xb0 ) MI16( 2, imm16 ) return; // RES b,(mn) + case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf: + OP( SET,14 ) BIT8( 1, b3 - 0xb8 ) MI16( 2, imm16 ) return; // SET b,(mn) + } break; + + case 0xe7: + b1 = READ8(); + b2 = READ8(); + switch ( b2 ) { + case 0x10: // RLD ($FF00+n) + case 0x11: // RRD ($FF00+n) + OP( RLD+b2-0x10,14 ) MI16( 1, 0xFF00|b1 ) NONE( 2 ) return; + + case 0x12: // MUL HL,($FF00+n) + case 0x13: // DIV HL,($FF00+n) + OP( MUL+b2-0x12,20 ) R16( 1, HL ) MI16( 2, 0xFF00|b1 ) return; + + case 0x14: case 0x15: case 0x16: + OP16( ADD,10 ) R16( 1, IX+b2-0x14 ) MI16( 2, 0xFF00|b1 ) return; // ADD ix,($FF00+n) + + case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: + OP( TSET,14 ) BIT8( 1, b2 - 0x18 ) MI16( 2, 0xFF00|b1 ) return; // TSET b,($FF00+n) + case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: + OP( LD,8 ) R8( 1, b2 - 0x28 ) MI16( 2, 0xFF00|b1 ) return; // LD r,($FF00+n) + case 0x48: case 0x49: case 0x4a: /*case 0x4b:*/ case 0x4c: case 0x4d: case 0x4e: + OP16( LD,10 ) R16( 1, b2 - 0x48 ) MI16( 2, 0xFF00|b1 ) return; // LD rr,($FF00+n) + + case 0x50: case 0x51: case 0x52: /*case 0x53:*/ case 0x54: case 0x55: case 0x56: + OP( EX,16 ) MI16( 1, 0xFF00|b1 ) R16( 2, b2 - 0x50 ) return; // EX ($FF00+n),rr + + case 0xa0: // RLC ($FF00+n) + case 0xa1: // RRC ($FF00+n) + case 0xa2: // RL ($FF00+n) + case 0xa3: // RR ($FF00+n) + case 0xa4: // SLA ($FF00+n) + case 0xa5: // SRA ($FF00+n) + case 0xa6: // SLL ($FF00+n) + case 0xa7: // SRL ($FF00+n) + OP( RLC+b2-0xa0,10 ) MI16( 1, 0xFF00|b1 ) NONE( 2 ) return; + } break; + + case 0xe8: case 0xe9: case 0xea: /*case 0xeb:*/ case 0xec: case 0xed: case 0xee: + b1 = READ8(); + switch ( b1 ) { + case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: + OP( LD,6 ) MR16( 1, b0 - 0xe8 ) R8( 2, b1 - 0x20 ) return; // LD (gg),r + case 0x37: + OP( LD,8 ) MR16( 1, b0 - 0xe8 ) I8( 2, READ8() ) return; // LD (gg),n + case 0x3f: + OP( LDW,12 ) MR16( 1, b0 - 0xe8 ) I16( 2, READ16() ) return; // LDW (gg),mn + case 0x40: case 0x41: case 0x42: /*case 0x43:*/ case 0x44: case 0x45: case 0x46: + OP16( LD,8 ) MR16( 1, b0 - 0xe8 ) R16( 2, b1 - 0x40 ) return; // LD (gg),rr + + case 0x68: // ADD (gg),n + case 0x69: // ADC (gg),n + case 0x6a: // SUB (gg),n + case 0x6b: // SBC (gg),n + case 0x6c: // AND (gg),n + case 0x6d: // XOR (gg),n + case 0x6e: // OR (gg),n + OP( ADD+b1-0x68,10 ) MR16( 1, b0 - 0xe8 ) I8( 2, READ8() ) return; + case 0x6f: // CP (gg),n + OP( CP,8 ) MR16( 1, b0 - 0xe8 ) I8( 2, READ8() ) return; + + case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: + case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: + OPCC( JP,6,8 ) CC( 1, b1 - 0xc0 ) R16( 2, b0 - 0xe8 ) return; // JP [cc,]gg + case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: + case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: + OPCC( CALL,6,14 ) CC( 1, b1 - 0xd0 ) R16( 2, b0 - 0xe8 ) return; // CALL [cc,]gg + } break; + case 0xeb: + imm16 = READ16(); + b3 = READ8(); + switch ( b3 ) { + case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: + OP( LD,10 ) MI16( 1, imm16 ) R8( 2, b3 - 0x20 ) return; // LD (mn),r + case 0x37: + OP( LD,12 ) MI16( 1, imm16 ) I8( 2, READ8() ) return; // LD (vw),n + case 0x3f: + OP( LDW,16 ) MI16( 1, imm16 ) I16( 2, READ16() ) return; // LDW (vw),mn + case 0x40: case 0x41: case 0x42: /*case 0x43:*/ case 0x44: case 0x45: case 0x46: + OP16( LD,12 ) MI16( 1, imm16 ) R16( 2, b3 - 0x40 ) return; // LD (mn),rr + + case 0x68: // ADD (vw),n + case 0x69: // ADC (vw),n + case 0x6a: // SUB (vw),n + case 0x6b: // SBC (vw),n + case 0x6c: // AND (vw),n + case 0x6d: // XOR (vw),n + case 0x6e: // OR (vw),n + OP( ADD+b3-0x68,14 ) MI16( 1, imm16 ) I8( 2, READ8() ) return; + case 0x6f: // CP (vw),n + OP( ADD+b3-0x68,12 ) MI16( 1, imm16 ) I8( 2, READ8() ) return; + + case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: + case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: + OPCC( JP,10,12 ) CC( 1, b3 - 0xc0 ) I16( 2, imm16 ) return; // JP cc,mn + case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: + case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: + OPCC( CALL,10,18 ) CC( 1, b3 - 0xd0 ) I16( 2, imm16 ) return; // CALL cc,mn + } break; + + case 0xef: + b1 = READ8(); + b2 = READ8(); + switch ( b2 ) { + case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: + OP( LD,8 ) MI16( 1, 0xFF00|b1 ) R8( 2, b2 - 0x20 ) return; // LD ($FF00+n),r + case 0x40: case 0x41: case 0x42: /*case 0x43:*/ case 0x44: case 0x45: case 0x46: + OP16( LD,10 ) MI16( 1, 0xFF00|b1 ) R16( 2, b2 - 0x40 ) return; // LD ($FF00+n),rr + + case 0x68: // ADD ($FF00+w),n + case 0x69: // ADC ($FF00+w),n + case 0x6a: // SUB ($FF00+w),n + case 0x6b: // SBC ($FF00+w),n + case 0x6c: // AND ($FF00+w),n + case 0x6d: // XOR ($FF00+w),n + case 0x6e: // OR ($FF00+w),n + OP( ADD+b2-0x68,12 ) MI16( 1, 0xFF00|b1 ) I8( 2, READ8() ) return; + case 0x6f: // CP ($FF00+w),n + OP( ADD+b2-0x68,10 ) MI16( 1, 0xFF00|b1 ) I8( 2, READ8() ) return; + } break; + + case 0xf0: case 0xf1: case 0xf2: + b1 = READ8(); + b2 = READ8(); + switch ( b2 ) { + case 0x10: // RLD (ix+d) + case 0x11: // RRD (ix+d) + OP( RLD+b2-0x10,16 ) MR16D8( 1, IX + b0 - 0xf0, b1 ) NONE( 2 ) return; + + case 0x12: // MUL HL,(ix+d) + case 0x13: // DIV HL,(ix+d) + OP( MUL+b2-0x12,22 ) R16( 1, HL ) MR16D8( 2, IX + b0 - 0xf0, b1 ) return; + + case 0x14: case 0x15: case 0x16: + OP16( ADD,12 ) R16( 1, IX+b2-0x14 ) MR16D8( 2, IX + b0 - 0xf0, b1 ) return; // ADD ix,(jx+d) + + case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: + OP( LD,10 ) R8( 1, b2 - 0x28 ) MR16D8( 2, IX + b0 - 0xf0, b1 ) return; // LD r,(ix+d) + case 0x48: case 0x49: case 0x4a: /*case 0x4b:*/ case 0x4c: case 0x4d: case 0x4e: + OP16( LD,12 ) R16( 1, b2 - 0x48 ) MR16D8( 2, IX + b0 - 0xf0, b1 ) return; // LD rr,(ix+d) + + case 0x50: case 0x51: case 0x52: /*case 0x53:*/ case 0x54: case 0x55: case 0x56: + OP( EX,18 ) MR16D8( 1, IX + b0 - 0xf0, b1 ) R16( 2, b2 - 0x50 ) return; // EX (ix+d),rr + + case 0x60: // ADD A,(ix+d) + case 0x61: // ADC A,(ix+d) + case 0x62: // SUB A,(ix+d) + case 0x63: // SBC A,(ix+d) + case 0x64: // AND A,(ix+d) + case 0x65: // XOR A,(ix+d) + case 0x66: // OR A,(ix+d) + case 0x67: // CP A,(ix+d) + OP( ADD+b2-0x60,10 ) R8( 1, A ) MR16D8( 2, IX + b0 - 0xf0, b1 ) return; + + case 0x70: // ADD HL,(ix+d) + case 0x71: // ADC HL,(ix+d) + case 0x72: // SUB HL,(ix+d) + case 0x73: // SBC HL,(ix+d) + case 0x74: // AND HL,(ix+d) + case 0x75: // XOR HL,(ix+d) + case 0x76: // OR HL,(ix+d) + case 0x77: // CP HL,(ix+d) + OP16( ADD+b2-0x70,12 ) R16( 1, HL ) MR16D8( 2, IX + b0 - 0xf0, b1 ) return; + + case 0x87: + OP( INC,12 ) MR16D8( 1, IX + b0 - 0xf0, b1 ) NONE( 2 ) return; // INC (ix+d) + case 0x8f: + OP( DEC,12 ) MR16D8( 1, IX + b0 - 0xf0, b1 ) NONE( 2 ) return; // DEC (ix+d) + + case 0x97: + OP( INCW,16 ) MR16D8( 1, IX + b0 - 0xf0, b1 ) NONE( 2 ) return; // INCW (ix+d) + case 0x9f: + OP( DECW,16 ) MR16D8( 1, IX + b0 - 0xf0, b1 ) NONE( 2 ) return; // DECW (ix+d) + + case 0xa0: // RLC (ix+d) + case 0xa1: // RRC (ix+d) + case 0xa2: // RL (ix+d) + case 0xa3: // RR (ix+d) + case 0xa4: // SLA (ix+d) + case 0xa5: // SRA (ix+d) + case 0xa6: // SLL (ix+d) + case 0xa7: // SRL (ix+d) + OP( RLC+b2-0xa0,12 ) MR16D8( 1, IX + b0 - 0xf0, b1 ) NONE( 2 ) return; + + case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: + OP( TSET,16 ) BIT8( 1, b2 - 0x18 ) MR16D8( 2, IX + b0 - 0xf0, b1 ) return; // TSET b,(ix+d) + case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf: + OP( BIT,10 ) BIT8( 1, b2 - 0xa8 ) MR16D8( 2, IX + b0 - 0xf0, b1 ) return; // BIT b,(ix+d) + case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: + OP( RES,14 ) BIT8( 1, b2 - 0xb0 ) MR16D8( 2, IX + b0 - 0xf0, b1 ) return; // RES b,(ix+d) + case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf: + OP( SET,14 ) BIT8( 1, b2 - 0xb8 ) MR16D8( 2, IX + b0 - 0xf0, b1 ) return; // SET b,(ix+d) + } break; + + case 0xf3: + b1 = READ8(); + switch ( b1 ) { + case 0x10: // RLD (HL+A) + case 0x11: // RRD (HL+A) + OP( RLD+b1-0x10,20 ) MR16R8( 1, HL, A ) NONE( 2 ) return; + + case 0x12: // MUL HL,(HL+A) + case 0x13: // DIV HL,(HL+A) + OP( MUL+b1-0x12,26 ) R16( 1, HL ) MR16R8( 2, HL, A ) return; + + case 0x14: case 0x15: case 0x16: + OP16( ADD,16 ) R16( 1, IX+b1-0x14 ) MR16R8( 2, HL, A ) return; // ADD ix,(HL+A) + + case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: + OP( LD,14 ) R8( 1, b1 - 0x28 ) MR16R8( 2, HL, A ) return; // LD r,(HL+A) + case 0x48: case 0x49: case 0x4a: /*case 0x4b:*/ case 0x4c: case 0x4d: case 0x4e: + OP16( LD,16 ) R16( 1, b1 - 0x48 ) MR16R8( 2, HL, A ) return; // LD rr,(HL+A) + + case 0x50: case 0x51: case 0x52: /*case 0x53:*/ case 0x54: case 0x55: case 0x56: + OP( EX,22 ) MR16R8( 1, HL, A ) R16( 2, b1 - 0x50 ) return; // EX (HL+A),rr + + case 0x60: // ADD A,(HL+A) + case 0x61: // ADC A,(HL+A) + case 0x62: // SUB A,(HL+A) + case 0x63: // SBC A,(HL+A) + case 0x64: // AND A,(HL+A) + case 0x65: // XOR A,(HL+A) + case 0x66: // OR A,(HL+A) + case 0x67: // CP A,(HL+A) + OP( ADD+b1-0x60,14 ) R8( 1, A ) MR16R8( 2, HL, A ) return; + + case 0x70: // ADD HL,(HL+A) + case 0x71: // ADC HL,(HL+A) + case 0x72: // SUB HL,(HL+A) + case 0x73: // SBC HL,(HL+A) + case 0x74: // AND HL,(HL+A) + case 0x75: // XOR HL,(HL+A) + case 0x76: // OR HL,(HL+A) + case 0x77: // CP HL,(HL+A) + OP16( ADD+b1-0x70,16 ) R16( 1, HL ) MR16R8( 2, HL, A ) return; + + case 0x87: + OP( INC,16 ) MR16R8( 1, HL, A ) NONE( 2 ) return; // INC (HL+A) + case 0x8f: + OP( DEC,16 ) MR16R8( 1, HL, A ) NONE( 2 ) return; // DEC (HL+A) + + case 0x97: + OP( INCW,20 ) MR16R8( 1, HL, A ) NONE( 2 ) return; // INCW (HL+A) + case 0x9f: + OP( DECW,20 ) MR16R8( 1, HL, A ) NONE( 2 ) return; // DECW (HL+A) + + case 0xa0: // RLC (HL+A) + case 0xa1: // RRC (HL+A) + case 0xa2: // RL (HL+A) + case 0xa3: // RR (HL+A) + case 0xa4: // SLA (HL+A) + case 0xa5: // SRA (HL+A) + case 0xa6: // SLL (HL+A) + case 0xa7: // SRL (HL+A) + OP( RLC+b1-0xa0,16 ) MR16R8( 1, HL, A ) NONE( 2 ) return; + + case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: + OP( TSET,20 ) BIT8( 1, b1 - 0x18 ) MR16R8( 2, HL, A ) return; // TSET b,(HL+A) + case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf: + OP( BIT,14 ) BIT8( 1, b1 - 0xa8 ) MR16R8( 2, HL, A ) return; // BIT b,(HL+A) + case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: + OP( RES,18 ) BIT8( 1, b1 - 0xb0 ) MR16R8( 2, HL, A ) return; // RES b,(HL+A) + case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf: + OP( SET,18 ) BIT8( 1, b1 - 0xb8 ) MR16R8( 2, HL, A ) return; // SET b,(HL+A) + } break; + + case 0xf4: case 0xf5: case 0xf6: + b1 = READ8(); + b2 = READ8(); + switch ( b2 ) { + case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: + OP( LD,10 ) MR16D8( 1, IX + b0 - 0xf4, b1 ) R8( 2, b2 - 0x20 ) return; // LD (ix+d),r + case 0x37: + OP( LD,12 ) MR16D8( 1, IX + b0 - 0xf4, b1 ) I8( 2, READ8() ) return; // LD (ix+d),n + case 0x38: case 0x39: case 0x3a: /*case 0x3b:*/ case 0x3c: case 0x3d: case 0x3e: + OP( LDA,10 ) R16( 1, b2 - 0x38 ) R16D8( 2, IX + b0 - 0xf4, b1 ) return; // LDA rr,ix+d + case 0x3f: + OP( LDW,16 ) MR16D8( 1, IX + b0 - 0xf4, b1 ) I16( 2, READ16() ) return; // LDW (ix+d),mn + case 0x40: case 0x41: case 0x42: /*case 0x43:*/ case 0x44: case 0x45: case 0x46: + OP16( LD,12 ) MR16D8( 1, IX + b0 - 0xf4, b1 ) R16( 2, b2 - 0x40 ) return; // LD (ix+d),rr + + case 0x68: // ADD (ix+d),n + case 0x69: // ADC (ix+d),n + case 0x6a: // SUB (ix+d),n + case 0x6b: // SBC (ix+d),n + case 0x6c: // AND (ix+d),n + case 0x6d: // XOR (ix+d),n + case 0x6e: // OR (ix+d),n + OP( ADD+b2-0x68,14) MR16D8( 1, IX + b0 - 0xf4, b1 ) I8( 2, READ8() ) return; + case 0x6f: // CP (ix+d),n + OP( ADD+b2-0x68,12) MR16D8( 1, IX + b0 - 0xf4, b1 ) I8( 2, READ8() ) return; + + case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: + case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: + OPCC( JP,10,12 ) CC( 1, b2 - 0xc0 ) R16D8( 2, IX + b0 - 0xf4, b1 ) return; // JP [cc,]ix+d + case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: + case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: + OPCC( CALL,10,18 ) CC( 1, b2 - 0xd0 ) R16D8( 2, IX + b0 - 0xf4, b1 ) return; // CALL [cc,]ix+d + } break; + + case 0xf7: + b1 = READ8(); + switch ( b1 ) { + case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: + OP( LD,14 ) MR16R8( 1, HL, A ) R8( 2, b1 - 0x20 ) return; // LD (HL+A),r + case 0x37: + OP( LD,16 ) MR16R8( 1, HL, A ) I8( 2, READ8() ) return; // LD (HL+A),n + case 0x38: case 0x39: case 0x3a: /*case 0x3b:*/ case 0x3c: case 0x3d: case 0x3e: + OP( LDA,14 ) R16( 1, b1 - 0x38 ) R16R8( 2, HL, A ) return; // LDA rr,HL+A + case 0x3f: + OP( LDW,20 ) MR16R8( 1, HL, A ) I16( 2, READ16() ) return; // LDW (HL+A),mn + case 0x40: case 0x41: case 0x42: /*case 0x43:*/ case 0x44: case 0x45: case 0x46: + OP16( LD,16 ) MR16R8( 1, HL, A ) R16( 2, b1 - 0x40 ) return; // LD (HL+A),rr + + case 0x68: // ADD (HL+A),n + case 0x69: // ADC (HL+A),n + case 0x6a: // SUB (HL+A),n + case 0x6b: // SBC (HL+A),n + case 0x6c: // AND (HL+A),n + case 0x6d: // XOR (HL+A),n + case 0x6e: // OR (HL+A),n + OP( ADD+b1-0x68,18) MR16R8( 1, HL, A ) I8( 2, READ8() ) return; + case 0x6f: // CP (HL+A),n + OP( ADD+b1-0x68,16) MR16R8( 1, HL, A ) I8( 2, READ8() ) return; + + case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: + case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: + OPCC( JP,14,16 ) CC( 1, b1 - 0xc0 ) R16R8( 2, HL, A ) return; // JP [cc,]HL+A + case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: + case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: + OPCC( CALL,14,22 ) CC( 1, b1 - 0xd0 ) R16R8( 2, HL, A ) return; // CALL [cc,]HL+A + } break; + + case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: + b1 = READ8(); + switch ( b1 ) { + case 0x12: // MUL HL,g + case 0x13: // DIV HL,g + OP( MUL+b1-0x12,18) R16( 1, HL ) R8( 2, b0 - 0xf8 ) return; + + case 0x14: case 0x15: case 0x16: + OP16( ADD,8 ) R16( 1, IX+b1-0x14 ) R16( 2, b0 - 0xf8 ) return; // ADD ix,gg + + case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: + OP( LD,4 ) R8( 1, b1 - 0x30 ) R8( 2, b0 - 0xf8 ) return; // LD r,g + case 0x38: case 0x39: case 0x3a: /*case 0x3b:*/ case 0x3c: case 0x3d: case 0x3e: + OP16( LD,6 ) R16( 1, b1 - 0x38 ) R16( 2, b0 - 0xf8 ) return; // LD rr,gg + + case 0x58: // LDI + case 0x59: // LDIR + case 0x5a: // LDD + case 0x5b: // LDDR + case 0x5c: // CPI + case 0x5d: // CPIR + case 0x5e: // CPD + case 0x5f: // CPDR + if (b0 == 0xfe) { + OPCC( LDI+b1-0x58,14,18 ) NONE( 1 ) NONE( 2 ) return; + } + + case 0x60: // ADD A,g + case 0x61: // ADC A,g + case 0x62: // SUB A,g + case 0x63: // SBC A,g + case 0x64: // AND A,g + case 0x65: // XOR A,g + case 0x66: // OR A,g + case 0x67: // CP A,g + OP( ADD+b1-0x60,4 ) R8( 1, A ) R8( 2, b0 - 0xf8 ) return; + + case 0x68: // ADD g,n + case 0x69: // ADC g,n + case 0x6a: // SUB g,n + case 0x6b: // SBC g,n + case 0x6c: // AND g,n + case 0x6d: // XOR g,n + case 0x6e: // OR g,n + case 0x6f: // CP g,n + OP( ADD+b1-0x68,6 ) R8( 1, b0 - 0xf8 ) I8( 2, READ8() ) return; + + case 0x70: // ADD HL,gg + case 0x71: // ADC HL,gg + case 0x72: // SUB HL,gg + case 0x73: // SBC HL,gg + case 0x74: // AND HL,gg + case 0x75: // XOR HL,gg + case 0x76: // OR HL,gg + case 0x77: // CP HL,gg + OP16( ADD+b1-0x70,8 ) R16( 1, HL ) R16( 2, b0 - 0xf8 ) return; + + case 0xa0: // RLC g + case 0xa1: // RRC g + case 0xa2: // RL g + case 0xa3: // RR g + case 0xa4: // SLA g + case 0xa5: // SRA g + case 0xa6: // SLL g + case 0xa7: // SRL g + OP( RLC+b1-0xa0,4 ) R8( 1, b0 - 0xf8 ) NONE( 2 ) return; + + case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: + OP( TSET,8 ) BIT8( 1, b1 - 0x18 ) R8( 2, b0 - 0xf8 ) return; // TSET b,g + case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf: + OP( BIT,4 ) BIT8( 1, b1 - 0xa8 ) R8( 2, b0 - 0xf8 ) return; // BIT b,g + case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: + OP( RES,4 ) BIT8( 1, b1 - 0xb0 ) R8( 2, b0 - 0xf8 ) return; // RES b,g + case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf: + OP( SET,4 ) BIT8( 1, b1 - 0xb8 ) R8( 2, b0 - 0xf8 ) return; // SET b,g + + case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: + case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: + if (b0 == 0xfe) { + OPCC( RET,6,14 ) CC( 1, b1 - 0xd0 ) NONE( 2 ) return; // RET cc + } + } break; + + case 0xff: + OP( SWI,20 ) NONE( 1 ) NONE( 2 ) return; // SWI + } + + OP( UNKNOWN,2 ) NONE( 1 ) NONE( 2 ) +} + +bool tlcs90_disassembler::stream_arg(std::ostream &stream, uint32_t pc, const char *pre, const e_mode mode, const uint16_t r, const uint16_t rb) +{ + const char *reg_name; + switch ( mode ) + { + case e_mode::NONE: return false; + + case e_mode::BIT8: util::stream_format(stream, "%s%d", pre, r ); return true; + case e_mode::I8: util::stream_format(stream, "%s$%02X", pre, r ); return true; + case e_mode::D8: util::stream_format(stream, "%s$%04X", pre, (pc+2+(r&0x7f)-(r&0x80))&0xffff ); return true; + case e_mode::I16: util::stream_format(stream, "%s$%04X", pre, r ); return true; + case e_mode::D16: util::stream_format(stream, "%s$%04X", pre, (pc+2+(r&0x7fff)-(r&0x8000))&0xffff ); return true; + case e_mode::MI16: + reg_name = internal_registers_names(r); + if (reg_name) + util::stream_format(stream, "%s(%s)", pre, reg_name); + else + util::stream_format(stream, "%s($%04X)", pre, r ); + return true; + case e_mode::R8: util::stream_format(stream, "%s%s", pre, r8_names[r] ); return true; + case e_mode::R16: util::stream_format(stream, "%s%s", pre, r16_names[r] ); return true; + case e_mode::MR16: util::stream_format(stream, "%s(%s)", pre, r16_names[r] ); return true; + + case e_mode::MR16R8: util::stream_format(stream, "%s(%s+%s)", pre, r16_names[r], r8_names[rb] ); return true; + case e_mode::MR16D8: util::stream_format(stream, "%s(%s%c$%02X)", pre, r16_names[r], (rb&0x80)?'-':'+', (rb&0x80)?((rb^0xff)+1):rb ); return true; + + case e_mode::CC: util::stream_format(stream, "%s%s", pre, cc_names[r] ); return true; + + case e_mode::R16R8: util::stream_format(stream, "%s%s+%s", pre, r16_names[r], r8_names[rb] ); return true; + case e_mode::R16D8: util::stream_format(stream, "%s%s%c$%02X", pre, r16_names[r], (rb&0x80)?'-':'+', (rb&0x80)?((rb^0xff)+1):rb ); return true; + + default: + fatalerror("%04x: unimplemented addr mode = %d\n",pc,std::underlying_type_t<e_mode>(mode)); + } + + // never executed + return false; +} + +offs_t tlcs90_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + m_addr = pc; + m_opcodes = &opcodes; + + decode(); + + util::stream_format (stream, "%-5s", op_names[ m_op ] ); // strlen("callr") == 5 + bool streamed = stream_arg (stream, pc, " ", m_mode1, m_r1, m_r1b ); + stream_arg (stream, pc, streamed ?",":"", m_mode2, m_r2, m_r2b ); + + return (m_addr - pc) | SUPPORTED; +} diff --git a/src/devices/cpu/tlcs90/tlcs90d.h b/src/devices/cpu/tlcs90/tlcs90d.h new file mode 100644 index 00000000000..8db7509512c --- /dev/null +++ b/src/devices/cpu/tlcs90/tlcs90d.h @@ -0,0 +1,65 @@ +// license:BSD-3-Clause +// copyright-holders:Luca Elia +/************************************************************************************************************* + + Toshiba TLCS-90 Series MCU's + + emulation by Luca Elia, based on the Z80 core by Juergen Buchmueller + + ChangeLog: + + 20150517 Fixed TRUN bit masking (timers start/stop handling) [Rainer Keuchel] + +*************************************************************************************************************/ + +#ifndef MAME_CPU_TLCS90_TLCS90D_H +#define MAME_CPU_TLCS90_TLCS90D_H + +#pragma once + +class tlcs90_disassembler : public util::disasm_interface +{ +public: + tlcs90_disassembler() = default; + virtual ~tlcs90_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum _e_op { UNKNOWN, NOP, EX, EXX, LD, LDW, LDA, LDI, LDIR, LDD, LDDR, CPI, CPIR, CPD, CPDR, PUSH, POP, JP, JR, CALL, CALLR, RET, RETI, HALT, DI, EI, SWI, DAA, CPL, NEG, LDAR, RCF, SCF, CCF, TSET, BIT, SET, RES, INC, DEC, INCX, DECX, INCW, DECW, ADD, ADC, SUB, SBC, AND, XOR, OR, CP, RLC, RRC, RL, RR, SLA, SRA, SLL, SRL, RLD, RRD, DJNZ, MUL, DIV }; + + enum class e_mode : u8 { + NONE, BIT8, CC, + I8, D8, R8, + I16, D16, R16, + MI16, MR16, MR16D8, MR16R8, + R16D8, R16R8 + }; + + static const char *const op_names[]; + static const char *const r8_names[]; + static const char *const r16_names[]; + static const char *const cc_names[]; + static const char *const ir_names[]; + + uint8_t m_op; + + e_mode m_mode1; + uint16_t m_r1,m_r1b; + + e_mode m_mode2; + uint16_t m_r2,m_r2b; + + offs_t m_addr; + const data_buffer *m_opcodes; + + inline uint8_t READ8(); + inline uint16_t READ16(); + void decode(); + + bool stream_arg(std::ostream &stream, uint32_t pc, const char *pre, const e_mode mode, const uint16_t r, const uint16_t rb); + const char *internal_registers_names(uint16_t x); +}; + +#endif diff --git a/src/devices/cpu/tlcs900/dasm900.cpp b/src/devices/cpu/tlcs900/dasm900.cpp index 64c8c6ba099..b700bf6341a 100644 --- a/src/devices/cpu/tlcs900/dasm900.cpp +++ b/src/devices/cpu/tlcs900/dasm900.cpp @@ -7,36 +7,9 @@ Toshiba TLCS-900/H disassembly *******************************************************************/ #include "emu.h" -#include "debugger.h" -#include "tlcs900.h" +#include "dasm900.h" -enum e_mnemonics -{ - M_ADC, M_ADD, M_AND, M_ANDCF, M_BIT, M_BS1B, - M_BS1F, M_CALL, M_CALR, M_CCF, M_CHG, M_CP, - M_CPD, M_CPDW, M_CPDR, M_CPDRW, M_CPI, M_CPIR, - M_CPIRW, M_CPIW, M_CPL, M_DAA, M_DB, M_DEC, - M_DECF, M_DECW, M_DIV, M_DIVS, M_DJNZ, M_EI, - M_EX, M_EXTS, M_EXTZ, M_HALT, M_INC, M_INCF, - M_INCW, M_JP, M_JR, M_JRL, M_LD, M_LDA, - M_LDC, M_LDCF, M_LDD, M_LDDR, M_LDDRW, M_LDDW, - M_LDF, M_LDI, M_LDIR, M_LDIRW, M_LDIW, M_LDW, - M_LDX, M_LINK, M_MAX, M_MDEC1, M_MDEC2, M_MDEC4, - M_MINC1, M_MINC2, M_MINC4, M_MIRR, M_MUL, M_MULA, - M_MULS, M_NEG, M_NOP, M_NORMAL, M_OR, M_ORCF, - M_PAA, M_POP, M_POPW, M_PUSH, M_PUSHW, M_RCF, - M_RES, M_RET, M_RETD, M_RETI, M_RL, M_RLC, - M_RLCW, M_RLD, M_RLW, M_RR, M_RRC, M_RRCW, - M_RRD, M_RRW, M_SBC, M_SCC, M_SCF, M_SET, - M_SLA, M_SLAW, M_SLL, M_SLLW, M_SRA, M_SRAW, - M_SRL, M_SRLW, M_STCF, M_SUB, M_SWI, M_TSET, - M_UNLK, M_XOR, M_XORCF, M_ZCF, - M_80, M_88, M_90, M_98, M_A0, M_A8, M_B0, M_B8, - M_C0, oC8, M_D0, oD8, M_E0, M_E8, M_F0 -}; - - -static const char *const s_mnemonic[] = +const char *const tlcs900_disassembler::s_mnemonic[] = { "adc", "add", "and", "andcf", "bit", "bs1b", "bs1f", "call", "calr", "ccf", "chg", "cp", @@ -62,43 +35,7 @@ static const char *const s_mnemonic[] = }; -enum e_operand -{ - O_NONE, - O_A, /* current register set register A */ - O_C8, /* current register set byte */ - O_C16, /* current register set word */ - O_C32, /* current register set long word */ - O_MC16, /* current register set mul/div register word */ - O_CC, /* condition */ - O_CR8, /* byte control register */ - O_CR16, /* word control register */ - O_CR32, /* long word control register */ - O_D8, /* byte displacement */ - O_D16, /* word displacement */ - O_F, /* F register */ - O_I3, /* immediate 3 bit (part of last byte) */ - O_I8, /* immediate byte */ - O_I16, /* immediate word */ - O_I24, /* immediate 3 byte address */ - O_I32, /* immediate long word */ - O_M, /* memory location (defined by extension) */ - O_M8, /* (8) */ - O_M16, /* (i16) */ - O_R, /* register */ - O_SR /* status register */ -}; - - -struct tlcs900inst -{ - e_mnemonics mnemonic; - e_operand operand1; - e_operand operand2; -}; - - -static const tlcs900inst mnemonic_80[256] = +const tlcs900_disassembler::tlcs900inst tlcs900_disassembler::mnemonic_80[256] = { /* 00 - 1F */ { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, @@ -182,7 +119,7 @@ static const tlcs900inst mnemonic_80[256] = }; -static const tlcs900inst mnemonic_88[256] = +const tlcs900_disassembler::tlcs900inst tlcs900_disassembler::mnemonic_88[256] = { /* 00 - 1F */ { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, @@ -266,7 +203,7 @@ static const tlcs900inst mnemonic_88[256] = }; -static const tlcs900inst mnemonic_90[256] = +const tlcs900_disassembler::tlcs900inst tlcs900_disassembler::mnemonic_90[256] = { /* 00 - 1F */ { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, @@ -350,7 +287,7 @@ static const tlcs900inst mnemonic_90[256] = }; -static const tlcs900inst mnemonic_98[256] = +const tlcs900_disassembler::tlcs900inst tlcs900_disassembler::mnemonic_98[256] = { /* 00 - 1F */ { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, @@ -434,7 +371,7 @@ static const tlcs900inst mnemonic_98[256] = }; -static const tlcs900inst mnemonic_a0[256] = +const tlcs900_disassembler::tlcs900inst tlcs900_disassembler::mnemonic_a0[256] = { /* 00 - 1F */ { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, @@ -518,7 +455,7 @@ static const tlcs900inst mnemonic_a0[256] = }; -static const tlcs900inst mnemonic_b0[256] = +const tlcs900_disassembler::tlcs900inst tlcs900_disassembler::mnemonic_b0[256] = { /* 00 - 1F */ { M_LD, O_M, O_I8 }, { M_DB, O_NONE, O_NONE }, { M_LD, O_M, O_I16 }, { M_DB, O_NONE, O_NONE }, @@ -602,7 +539,7 @@ static const tlcs900inst mnemonic_b0[256] = }; -static const tlcs900inst mnemonic_b8[256] = +const tlcs900_disassembler::tlcs900inst tlcs900_disassembler::mnemonic_b8[256] = { /* 00 - 1F */ { M_LD, O_M, O_I8 }, { M_DB, O_NONE, O_NONE }, { M_LD, O_M, O_I16 }, { M_DB, O_NONE, O_NONE }, @@ -686,7 +623,7 @@ static const tlcs900inst mnemonic_b8[256] = }; -static const tlcs900inst mnemonic_c0[256] = +const tlcs900_disassembler::tlcs900inst tlcs900_disassembler::mnemonic_c0[256] = { /* 00 - 1F */ { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, @@ -771,7 +708,7 @@ static const tlcs900inst mnemonic_c0[256] = /* TODO: M_MUL_O_I8, M_MULS_O_I8, M_DIV_O_I8, M_DIVS_O_i8 need to be fixed */ -static const tlcs900inst mnemonic_c8[256] = +const tlcs900_disassembler::tlcs900inst tlcs900_disassembler::mnemonic_c8[256] = { /* 00 - 1F */ { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_LD, O_R, O_I8 }, @@ -855,7 +792,7 @@ static const tlcs900inst mnemonic_c8[256] = }; -static const tlcs900inst mnemonic_d0[256] = +const tlcs900_disassembler::tlcs900inst tlcs900_disassembler::mnemonic_d0[256] = { /* 00 - 1F */ { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, @@ -939,7 +876,7 @@ static const tlcs900inst mnemonic_d0[256] = }; -static const tlcs900inst mnemonic_d8[256] = +const tlcs900_disassembler::tlcs900inst tlcs900_disassembler::mnemonic_d8[256] = { /* 00 - 1F */ { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_LD, O_R, O_I16 }, @@ -1023,7 +960,7 @@ static const tlcs900inst mnemonic_d8[256] = }; -static const tlcs900inst mnemonic_e0[256] = +const tlcs900_disassembler::tlcs900inst tlcs900_disassembler::mnemonic_e0[256] = { /* 00 - 1F */ { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, @@ -1107,7 +1044,7 @@ static const tlcs900inst mnemonic_e0[256] = }; -static const tlcs900inst mnemonic_e8[256] = +const tlcs900_disassembler::tlcs900inst tlcs900_disassembler::mnemonic_e8[256] = { /* 00 - 1F */ { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_LD, O_R, O_I32 }, @@ -1191,7 +1128,7 @@ static const tlcs900inst mnemonic_e8[256] = }; -static const tlcs900inst mnemonic_f0[256] = +const tlcs900_disassembler::tlcs900inst tlcs900_disassembler::mnemonic_f0[256] = { /* 00 - 1F */ { M_LD, O_M, O_I8 }, { M_DB, O_NONE, O_NONE }, { M_LD, O_M, O_I16 }, { M_DB, O_NONE, O_NONE }, @@ -1275,7 +1212,7 @@ static const tlcs900inst mnemonic_f0[256] = }; -static const tlcs900inst mnemonic[256] = +const tlcs900_disassembler::tlcs900inst tlcs900_disassembler::mnemonic[256] = { /* 00 - 1F */ { M_NOP, O_NONE, O_NONE }, { M_NORMAL, O_NONE, O_NONE }, { M_PUSH, O_SR, O_NONE }, { M_POP, O_SR, O_NONE }, @@ -1360,11 +1297,11 @@ static const tlcs900inst mnemonic[256] = -static const char *const s_reg8[8] = { "W", "A", "B", "C", "D", "E", "H", "L" }; -static const char *const s_reg16[8] = { "WA", "BC", "DE", "HL", "IX", "IY", "IZ", "SP" }; -static const char *const s_reg32[8] = { "XWA", "XBC", "XDE", "XHL", "XIX", "XIY", "XIZ", "XSP" }; -static const char *const s_mulreg16[8] = { "??", "WA", "??", "BC", "??", "DE", "??", "HL" }; -static const char *const s_allreg8[256] = +const char *const tlcs900_disassembler::s_reg8[8] = { "W", "A", "B", "C", "D", "E", "H", "L" }; +const char *const tlcs900_disassembler::s_reg16[8] = { "WA", "BC", "DE", "HL", "IX", "IY", "IZ", "SP" }; +const char *const tlcs900_disassembler::s_reg32[8] = { "XWA", "XBC", "XDE", "XHL", "XIX", "XIY", "XIZ", "XSP" }; +const char *const tlcs900_disassembler::s_mulreg16[8] = { "??", "WA", "??", "BC", "??", "DE", "??", "HL" }; +const char *const tlcs900_disassembler::s_allreg8[256] = { "RA0" ,"RW0" ,"QA0" ,"QW0" ,"RC0" ,"RB0" ,"QC0" ,"QB0" ,"RE0" ,"RD0" ,"QE0" ,"QD0" ,"RL0" ,"RH0" ,"QL0" ,"QH0" , "RA1" ,"RW1" ,"QA1" ,"QW1" ,"RC1" ,"RB1" ,"QC1" ,"QB1" ,"RE1" ,"RD1" ,"QE1" ,"QD1" ,"RL1" ,"RH1" ,"QL1" ,"QH1" , @@ -1385,7 +1322,7 @@ static const char *const s_allreg8[256] = }; -static const char *const s_allreg16[256] = +const char *const tlcs900_disassembler::s_allreg16[256] = { "RWA0","r01W","QWA0","r03W","RBC0","r05W","QBC0","r07W","RDE0","r09W","QDE0","r0BW","RHL0","r0DW","QHL0","r0FW", "RWA1","r11W","QWA1","r13W","RBC1","r15W","QBC1","r17W","RDE1","r19W","QDE1","r1BW","RHL1","r1DW","QHL1","r1FW", @@ -1406,7 +1343,7 @@ static const char *const s_allreg16[256] = }; -static const char *const s_allreg32[256] = +const char *const tlcs900_disassembler::s_allreg32[256] = { "XWA0","XWA0","XWA0","r03L","XBC0","XBC0","XBC0","r07L","XDE0","XDE0","XDE0","r0BL","XHL0","XHL0","XHL0","r0FL", "XWA1","XWA1","XWA1","r13L","XBC1","XBC1","XBC1","r17L","XDE1","XDE1","XDE1","r1BL","XHL1","XHL1","XHL1","r1FL", @@ -1427,22 +1364,27 @@ static const char *const s_allreg32[256] = }; -static const char *const s_cond[16] = +const char *const tlcs900_disassembler::s_cond[16] = { "F","LT","LE","ULE","PE/OV","M/MI","Z","C","T","GE","GT","UGT","PO/NOV","P/PL","NZ","NC" }; -CPU_DISASSEMBLE(tlcs900) +u32 tlcs900_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t tlcs900_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { const tlcs900inst *dasm; std::string buf; uint8_t op, op1; uint32_t imm; int flags = 0; - int pos = 0; + offs_t pos = pc; - op = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); dasm = &mnemonic[ op ]; @@ -1454,53 +1396,53 @@ CPU_DISASSEMBLE(tlcs900) case M_80: buf = string_format("%s", s_reg32[op & 0x07]); - op = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); dasm = &mnemonic_80[ op ]; break; case M_88: - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("%s+0x%02x", s_reg32[op & 0x07], imm); - op = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); dasm = &mnemonic_88[ op ]; break; case M_90: buf = string_format("%s", s_reg32[op & 0x07]); - op = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); dasm = &mnemonic_90[ op ]; break; case M_98: - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("%s+0x%02x", s_reg32[op & 0x07], imm); - op = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); dasm = &mnemonic_98[ op ]; break; case M_A0: buf = string_format("%s", s_reg32[op & 0x07]); - op = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); dasm = &mnemonic_a0[ op ]; break; case M_A8: - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("%s+0x%02x", s_reg32[op & 0x07], imm); - op = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); dasm = &mnemonic_a0[ op ]; break; case M_B0: buf = string_format("%s", s_reg32[op & 0x07]); - op = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); dasm = &mnemonic_b0[ op ]; break; case M_B8: - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("%s+0x%02x", s_reg32[op & 0x07], imm); - op = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); dasm = &mnemonic_b8[ op ]; break; @@ -1508,25 +1450,25 @@ CPU_DISASSEMBLE(tlcs900) switch( op & 0x07 ) { case 0x00: /* 0xC0 */ - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("0x%02x", imm); break; case 0x01: /* 0xC1 */ - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); buf = string_format("0x%04x", imm); break; case 0x02: /* 0xC2 */ - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); - imm = imm | (oprom[ pos++ ] << 16); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); + imm = imm | (opcodes.r8( pos++ ) << 16); buf = string_format("0x%06x", imm); break; case 0x03: /* 0xC3 */ - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); switch( imm & 0x03 ) { case 0x00: @@ -1535,8 +1477,8 @@ CPU_DISASSEMBLE(tlcs900) case 0x01: op = imm; - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); buf = string_format("%s+0x%04x", s_allreg32[op], imm); break; @@ -1548,20 +1490,20 @@ CPU_DISASSEMBLE(tlcs900) switch( imm ) { case 0x03: - op = oprom[ pos++ ]; - op1 = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); + op1 = opcodes.r8( pos++ ); buf = string_format("%s+%s", s_allreg32[op], s_allreg8[op1]); break; case 0x07: - op = oprom[ pos++ ]; - op1 = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); + op1 = opcodes.r8( pos++ ); buf = string_format("%s+%s", s_allreg32[op], s_allreg16[op1]); break; case 0x13: - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); buf = string_format("0x%06x", pc + pos + (int16_t)imm); break; } @@ -1570,16 +1512,16 @@ CPU_DISASSEMBLE(tlcs900) break; case 0x04: /* 0xC4 */ - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("-%s", s_allreg32[imm]); break; case 0x05: /* 0xC5 */ - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("%s+", s_allreg32[imm]); break; } - op = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); dasm = &mnemonic_c0[ op ]; break; @@ -1590,10 +1532,10 @@ CPU_DISASSEMBLE(tlcs900) } else { - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("%s", s_allreg8[imm]); } - op = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); dasm = &mnemonic_c8[ op ]; break; @@ -1601,25 +1543,25 @@ CPU_DISASSEMBLE(tlcs900) switch( op & 0x07 ) { case 0x00: /* 0xD0 */ - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("0x%02x", imm); break; case 0x01: /* 0xD1 */ - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); buf = string_format("0x%04x", imm); break; case 0x02: /* 0xD2 */ - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); - imm = imm | (oprom[ pos++ ] << 16); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); + imm = imm | (opcodes.r8( pos++ ) << 16); buf = string_format("0x%06x", imm); break; case 0x03: /* 0xD3 */ - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); switch( imm & 0x03 ) { case 0x00: @@ -1628,8 +1570,8 @@ CPU_DISASSEMBLE(tlcs900) case 0x01: op = imm; - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); buf = string_format("%s+0x%04x", s_allreg32[op], imm); break; @@ -1641,20 +1583,20 @@ CPU_DISASSEMBLE(tlcs900) switch( imm ) { case 0x03: - op = oprom[ pos++ ]; - op1 = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); + op1 = opcodes.r8( pos++ ); buf = string_format("%s+%s", s_allreg32[op], s_allreg8[op1]); break; case 0x07: - op = oprom[ pos++ ]; - op1 = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); + op1 = opcodes.r8( pos++ ); buf = string_format("%s+%s", s_allreg32[op], s_allreg16[op1]); break; case 0x13: - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); buf = string_format("0x%06x", pc + pos + (int16_t)imm); break; } @@ -1663,16 +1605,16 @@ CPU_DISASSEMBLE(tlcs900) break; case 0x04: /* 0xD4 */ - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("-%s", s_allreg32[imm]); break; case 0x05: /* 0xD5 */ - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("%s+", s_allreg32[imm]); break; } - op = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); dasm = &mnemonic_d0[ op ]; break; @@ -1683,11 +1625,11 @@ CPU_DISASSEMBLE(tlcs900) } else { - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("%s", s_allreg16[imm]); } - op = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); dasm = &mnemonic_d8[ op ]; break; @@ -1695,25 +1637,25 @@ CPU_DISASSEMBLE(tlcs900) switch( op & 0x07 ) { case 0x00: /* 0xE0 */ - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("0x%02x", imm); break; case 0x01: /* 0xE1 */ - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); buf = string_format("0x%04x", imm); break; case 0x02: /* 0xE2 */ - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); - imm = imm | (oprom[ pos++ ] << 16); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); + imm = imm | (opcodes.r8( pos++ ) << 16); buf = string_format("0x%06x", imm); break; case 0x03: /* 0xE3 */ - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); switch( imm & 0x03 ) { case 0x00: @@ -1722,8 +1664,8 @@ CPU_DISASSEMBLE(tlcs900) case 0x01: op = imm; - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); buf = string_format("%s+0x%04x", s_allreg32[op], imm); break; @@ -1735,20 +1677,20 @@ CPU_DISASSEMBLE(tlcs900) switch( imm ) { case 0x03: - op = oprom[ pos++ ]; - op1 = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); + op1 = opcodes.r8( pos++ ); buf = string_format("%s+%s", s_allreg32[op], s_allreg8[op1]); break; case 0x07: - op = oprom[ pos++ ]; - op1 = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); + op1 = opcodes.r8( pos++ ); buf = string_format("%s+%s", s_allreg32[op], s_allreg16[op1]); break; case 0x13: - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); buf = string_format("0x%06x", pc + pos + (int16_t)imm); break; } @@ -1757,16 +1699,16 @@ CPU_DISASSEMBLE(tlcs900) break; case 0x04: /* 0xE4 */ - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("-%s", s_allreg32[imm]); break; case 0x05: /* 0xE5 */ - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("%s+", s_allreg32[imm]); break; } - op = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); dasm = &mnemonic_e0[ op ]; break; @@ -1777,10 +1719,10 @@ CPU_DISASSEMBLE(tlcs900) } else { - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("%s", s_allreg32[imm]); } - op = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); dasm = &mnemonic_e8[ op ]; break; @@ -1788,25 +1730,25 @@ CPU_DISASSEMBLE(tlcs900) switch( op & 0x07 ) { case 0x00: /* 0xF0 */ - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("0x%02x", imm); break; case 0x01: /* 0xF1 */ - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); buf = string_format("0x%04x", imm); break; case 0x02: /* 0xF2 */ - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); - imm = imm | (oprom[ pos++ ] << 16); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); + imm = imm | (opcodes.r8( pos++ ) << 16); buf = string_format("0x%06x", imm); break; case 0x03: /* 0xF3 */ - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); switch( imm & 0x03 ) { case 0x00: @@ -1815,8 +1757,8 @@ CPU_DISASSEMBLE(tlcs900) case 0x01: op = imm; - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); buf = string_format("%s+0x%04x", s_allreg32[op], imm); break; @@ -1828,20 +1770,20 @@ CPU_DISASSEMBLE(tlcs900) switch( imm ) { case 0x03: - op = oprom[ pos++ ]; - op1 = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); + op1 = opcodes.r8( pos++ ); buf = string_format("%s+%s", s_allreg32[op], s_allreg8[op1]); break; case 0x07: - op = oprom[ pos++ ]; - op1 = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); + op1 = opcodes.r8( pos++ ); buf = string_format("%s+%s", s_allreg32[op], s_allreg16[op1]); break; case 0x13: - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); buf = string_format("0x%06x", pc + pos + (int16_t)imm); break; } @@ -1850,16 +1792,16 @@ CPU_DISASSEMBLE(tlcs900) break; case 0x04: /* 0xF4 */ - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("-%s", s_allreg32[imm]); break; case 0x05: /* 0xF5 */ - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("%s+", s_allreg32[imm]); break; } - op = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); dasm = &mnemonic_f0[ op ]; break; } @@ -1873,12 +1815,12 @@ CPU_DISASSEMBLE(tlcs900) break; case M_CALL: case M_CALR: - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case M_RET: case M_RETD: case M_RETI: - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; } @@ -1912,7 +1854,7 @@ CPU_DISASSEMBLE(tlcs900) break; case O_CR8: - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); switch( imm ) { case 0x22: @@ -1934,7 +1876,7 @@ CPU_DISASSEMBLE(tlcs900) break; case O_CR16: - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); switch( imm ) { case 0x20: @@ -1956,7 +1898,7 @@ CPU_DISASSEMBLE(tlcs900) break; case O_CR32: - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); switch( imm ) { case 0x00: @@ -1990,13 +1932,13 @@ CPU_DISASSEMBLE(tlcs900) break; case O_D8: - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); util::stream_format(stream, " 0x%06x", ( pc + pos + (int8_t)imm ) & 0xFFFFFF); break; case O_D16: - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); util::stream_format(stream, " 0x%06x", ( pc + pos + (int16_t)imm ) & 0xFFFFFF); break; @@ -2009,28 +1951,28 @@ CPU_DISASSEMBLE(tlcs900) break; case O_I8: - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); util::stream_format(stream, " 0x%02x", imm); break; case O_I16: - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); util::stream_format(stream, " 0x%04x", imm); break; case O_I24: - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); - imm = imm | (oprom[ pos++ ] << 16); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); + imm = imm | (opcodes.r8( pos++ ) << 16); util::stream_format(stream, " 0x%06x", imm); break; case O_I32: - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); - imm = imm | (oprom[ pos++ ] << 16); - imm = imm | (oprom[ pos++ ] << 24); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); + imm = imm | (opcodes.r8( pos++ ) << 16); + imm = imm | (opcodes.r8( pos++ ) << 24); util::stream_format(stream, "0x%08x", imm); break; @@ -2049,13 +1991,13 @@ CPU_DISASSEMBLE(tlcs900) break; case O_M8: - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); util::stream_format(stream, " (0x%02x)", imm); break; case O_M16: - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); util::stream_format(stream, " (0x%04x)", imm); break; @@ -2098,7 +2040,7 @@ CPU_DISASSEMBLE(tlcs900) break; case O_CR8: - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); switch( imm ) { case 0x22: @@ -2120,7 +2062,7 @@ CPU_DISASSEMBLE(tlcs900) break; case O_CR16: - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); switch( imm ) { case 0x20: @@ -2142,7 +2084,7 @@ CPU_DISASSEMBLE(tlcs900) break; case O_CR32: - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); switch( imm ) { case 0x00: @@ -2176,13 +2118,13 @@ CPU_DISASSEMBLE(tlcs900) break; case O_D8: - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); util::stream_format(stream, ",0x%06x", ( pc + pos + (int8_t)imm ) & 0xFFFFFF); break; case O_D16: - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); util::stream_format(stream, ",0x%06x", ( pc + pos + (int16_t)imm ) & 0xFFFFFF); break; @@ -2195,28 +2137,28 @@ CPU_DISASSEMBLE(tlcs900) break; case O_I8: - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); util::stream_format(stream, ",0x%02x", imm); break; case O_I16: - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); util::stream_format(stream, ",0x%04x", imm); break; case O_I24: - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); - imm = imm | (oprom[ pos++ ] << 16); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); + imm = imm | (opcodes.r8( pos++ ) << 16); util::stream_format(stream, ",0x%06x", imm); break; case O_I32: - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); - imm = imm | (oprom[ pos++ ] << 16); - imm = imm | (oprom[ pos++ ] << 24); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); + imm = imm | (opcodes.r8( pos++ ) << 16); + imm = imm | (opcodes.r8( pos++ ) << 24); util::stream_format(stream, ",0x%08x", imm); break; @@ -2235,13 +2177,13 @@ CPU_DISASSEMBLE(tlcs900) break; case O_M8: - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); util::stream_format(stream, ",(0x%02x)", imm); break; case O_M16: - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); util::stream_format(stream, ",(0x%04x)", imm); break; @@ -2254,5 +2196,5 @@ CPU_DISASSEMBLE(tlcs900) break; } - return pos | flags | DASMFLAG_SUPPORTED; + return (pos - pc) | flags | SUPPORTED; } diff --git a/src/devices/cpu/tlcs900/dasm900.h b/src/devices/cpu/tlcs900/dasm900.h new file mode 100644 index 00000000000..8fb067a299a --- /dev/null +++ b/src/devices/cpu/tlcs900/dasm900.h @@ -0,0 +1,111 @@ +// license:BSD-3-Clause +// copyright-holders:Wilbert Pol +/******************************************************************* + +Toshiba TLCS-900/H disassembly + +*******************************************************************/ + +#ifndef MAME_CPU_TLCS900_DASM900_H +#define MAME_CPU_TLCS900_DASM900_H + +#pragma once + +class tlcs900_disassembler : public util::disasm_interface +{ +public: + tlcs900_disassembler() = default; + virtual ~tlcs900_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum e_mnemonics + { + M_ADC, M_ADD, M_AND, M_ANDCF, M_BIT, M_BS1B, + M_BS1F, M_CALL, M_CALR, M_CCF, M_CHG, M_CP, + M_CPD, M_CPDW, M_CPDR, M_CPDRW, M_CPI, M_CPIR, + M_CPIRW, M_CPIW, M_CPL, M_DAA, M_DB, M_DEC, + M_DECF, M_DECW, M_DIV, M_DIVS, M_DJNZ, M_EI, + M_EX, M_EXTS, M_EXTZ, M_HALT, M_INC, M_INCF, + M_INCW, M_JP, M_JR, M_JRL, M_LD, M_LDA, + M_LDC, M_LDCF, M_LDD, M_LDDR, M_LDDRW, M_LDDW, + M_LDF, M_LDI, M_LDIR, M_LDIRW, M_LDIW, M_LDW, + M_LDX, M_LINK, M_MAX, M_MDEC1, M_MDEC2, M_MDEC4, + M_MINC1, M_MINC2, M_MINC4, M_MIRR, M_MUL, M_MULA, + M_MULS, M_NEG, M_NOP, M_NORMAL, M_OR, M_ORCF, + M_PAA, M_POP, M_POPW, M_PUSH, M_PUSHW, M_RCF, + M_RES, M_RET, M_RETD, M_RETI, M_RL, M_RLC, + M_RLCW, M_RLD, M_RLW, M_RR, M_RRC, M_RRCW, + M_RRD, M_RRW, M_SBC, M_SCC, M_SCF, M_SET, + M_SLA, M_SLAW, M_SLL, M_SLLW, M_SRA, M_SRAW, + M_SRL, M_SRLW, M_STCF, M_SUB, M_SWI, M_TSET, + M_UNLK, M_XOR, M_XORCF, M_ZCF, + M_80, M_88, M_90, M_98, M_A0, M_A8, M_B0, M_B8, + M_C0, oC8, M_D0, oD8, M_E0, M_E8, M_F0 + }; + + enum e_operand + { + O_NONE, + O_A, /* current register set register A */ + O_C8, /* current register set byte */ + O_C16, /* current register set word */ + O_C32, /* current register set long word */ + O_MC16, /* current register set mul/div register word */ + O_CC, /* condition */ + O_CR8, /* byte control register */ + O_CR16, /* word control register */ + O_CR32, /* long word control register */ + O_D8, /* byte displacement */ + O_D16, /* word displacement */ + O_F, /* F register */ + O_I3, /* immediate 3 bit (part of last byte) */ + O_I8, /* immediate byte */ + O_I16, /* immediate word */ + O_I24, /* immediate 3 byte address */ + O_I32, /* immediate long word */ + O_M, /* memory location (defined by extension) */ + O_M8, /* (8) */ + O_M16, /* (i16) */ + O_R, /* register */ + O_SR /* status register */ + }; + + struct tlcs900inst + { + e_mnemonics mnemonic; + e_operand operand1; + e_operand operand2; + }; + + static const char *const s_mnemonic[]; + static const tlcs900inst mnemonic_80[256]; + static const tlcs900inst mnemonic_88[256]; + static const tlcs900inst mnemonic_90[256]; + static const tlcs900inst mnemonic_98[256]; + static const tlcs900inst mnemonic_a0[256]; + static const tlcs900inst mnemonic_b0[256]; + static const tlcs900inst mnemonic_b8[256]; + static const tlcs900inst mnemonic_c0[256]; + static const tlcs900inst mnemonic_c8[256]; + static const tlcs900inst mnemonic_d0[256]; + static const tlcs900inst mnemonic_d8[256]; + static const tlcs900inst mnemonic_e0[256]; + static const tlcs900inst mnemonic_e8[256]; + static const tlcs900inst mnemonic_f0[256]; + static const tlcs900inst mnemonic[256]; + + static const char *const s_reg8[8]; + static const char *const s_reg16[8]; + static const char *const s_reg32[8]; + static const char *const s_mulreg16[8]; + static const char *const s_allreg8[256]; + static const char *const s_allreg16[256]; + static const char *const s_allreg32[256]; + static const char *const s_cond[16]; + +}; + +#endif diff --git a/src/devices/cpu/tlcs900/tlcs900.cpp b/src/devices/cpu/tlcs900/tlcs900.cpp index 69eef7121e0..26e1678078d 100644 --- a/src/devices/cpu/tlcs900/tlcs900.cpp +++ b/src/devices/cpu/tlcs900/tlcs900.cpp @@ -17,6 +17,7 @@ TODO: #include "emu.h" #include "tlcs900.h" +#include "dasm900.h" #include "debugger.h" @@ -148,10 +149,9 @@ void tmp95c063_device::device_config_complete() } -offs_t tlcs900h_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *tlcs900h_device::create_disassembler() { - extern CPU_DISASSEMBLE( tlcs900 ); - return CPU_DISASSEMBLE_NAME(tlcs900)(this, stream, pc, oprom, opram, options); + return new tlcs900_disassembler; } diff --git a/src/devices/cpu/tlcs900/tlcs900.h b/src/devices/cpu/tlcs900/tlcs900.h index 28552bd3c17..0fbedad0f23 100644 --- a/src/devices/cpu/tlcs900/tlcs900.h +++ b/src/devices/cpu/tlcs900/tlcs900.h @@ -72,9 +72,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 7; } /* FIXME */ - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; protected: int m_am8_16; diff --git a/src/devices/cpu/tms1000/tms0270.cpp b/src/devices/cpu/tms1000/tms0270.cpp index 3e66a4cf9bd..1db3bab8da2 100644 --- a/src/devices/cpu/tms1000/tms0270.cpp +++ b/src/devices/cpu/tms1000/tms0270.cpp @@ -23,7 +23,7 @@ DEFINE_DEVICE_TYPE(TMS0270, tms0270_cpu_device, "tms0270", "TMS0270") // 40-pin // internal memory maps static ADDRESS_MAP_START(program_11bit_9, AS_PROGRAM, 16, tms1k_base_device) - AM_RANGE(0x000, 0xfff) AM_ROM + AM_RANGE(0x000, 0x7ff) AM_ROM ADDRESS_MAP_END static ADDRESS_MAP_START(data_144x4, AS_DATA, 8, tms1k_base_device) @@ -34,7 +34,7 @@ ADDRESS_MAP_END // device definitions tms0270_cpu_device::tms0270_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : tms0980_cpu_device(mconfig, TMS0270, tag, owner, clock, 16 /* o pins */, 16 /* r pins */, 7 /* pc bits */, 9 /* byte width */, 4 /* x width */, 12 /* prg width */, ADDRESS_MAP_NAME(program_11bit_9), 8 /* data width */, ADDRESS_MAP_NAME(data_144x4)) + : tms0980_cpu_device(mconfig, TMS0270, tag, owner, clock, 16 /* o pins */, 16 /* r pins */, 7 /* pc bits */, 9 /* byte width */, 4 /* x width */, 11 /* prg width */, ADDRESS_MAP_NAME(program_11bit_9), 8 /* data width */, ADDRESS_MAP_NAME(data_144x4)) , m_read_ctl(*this) , m_write_ctl(*this) , m_write_pdc(*this) diff --git a/src/devices/cpu/tms1000/tms0980.cpp b/src/devices/cpu/tms1000/tms0980.cpp index 3059ff7b1d1..622d8ca5be4 100644 --- a/src/devices/cpu/tms1000/tms0980.cpp +++ b/src/devices/cpu/tms1000/tms0980.cpp @@ -8,6 +8,7 @@ #include "emu.h" #include "tms0980.h" +#include "tms1k_dasm.h" #include "debugger.h" // TMS0980 @@ -31,7 +32,7 @@ DEFINE_DEVICE_TYPE(TMS1980, tms1980_cpu_device, "tms1980", "TMS1980") // 28-pin // internal memory maps static ADDRESS_MAP_START(program_11bit_9, AS_PROGRAM, 16, tms1k_base_device) - AM_RANGE(0x000, 0xfff) AM_ROM + AM_RANGE(0x000, 0x7ff) AM_ROM ADDRESS_MAP_END static ADDRESS_MAP_START(data_144x4, AS_DATA, 8, tms1k_base_device) @@ -42,7 +43,7 @@ ADDRESS_MAP_END // device definitions tms0980_cpu_device::tms0980_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : tms0980_cpu_device(mconfig, TMS0980, tag, owner, clock, 8 /* o pins */, 9 /* r pins */, 7 /* pc bits */, 9 /* byte width */, 4 /* x width */, 12 /* prg width */, ADDRESS_MAP_NAME(program_11bit_9), 8 /* data width */, ADDRESS_MAP_NAME(data_144x4)) + : tms0980_cpu_device(mconfig, TMS0980, tag, owner, clock, 8 /* o pins */, 9 /* r pins */, 7 /* pc bits */, 9 /* byte width */, 4 /* x width */, 11 /* prg width */, ADDRESS_MAP_NAME(program_11bit_9), 8 /* data width */, ADDRESS_MAP_NAME(data_144x4)) { } @@ -52,7 +53,7 @@ tms0980_cpu_device::tms0980_cpu_device(const machine_config &mconfig, device_typ } tms1980_cpu_device::tms1980_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : tms0980_cpu_device(mconfig, TMS1980, tag, owner, clock, 7, 10, 7, 9, 4, 12, ADDRESS_MAP_NAME(program_11bit_9), 8, ADDRESS_MAP_NAME(data_144x4)) + : tms0980_cpu_device(mconfig, TMS1980, tag, owner, clock, 7, 10, 7, 9, 4, 11, ADDRESS_MAP_NAME(program_11bit_9), 8, ADDRESS_MAP_NAME(data_144x4)) { } @@ -84,10 +85,9 @@ MACHINE_CONFIG_END // disasm -offs_t tms0980_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +util::disasm_interface *tms0980_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE(tms0980); - return CPU_DISASSEMBLE_NAME(tms0980)(this, stream, pc, oprom, opram, options); + return new tms0980_disassembler; } @@ -173,8 +173,8 @@ u32 tms0980_cpu_device::read_micro() void tms0980_cpu_device::read_opcode() { - debugger_instruction_hook(this, m_rom_address << 1); - m_opcode = m_program->read_word(m_rom_address << 1) & 0x1ff; + debugger_instruction_hook(this, m_rom_address); + m_opcode = m_program->read_word(m_rom_address) & 0x1ff; m_c4 = BITSWAP8(m_opcode,7,6,5,4,0,1,2,3) & 0xf; // opcode operand is bitswapped for most opcodes m_fixed = m_fixed_decode[m_opcode]; diff --git a/src/devices/cpu/tms1000/tms0980.h b/src/devices/cpu/tms1000/tms0980.h index c258eadc12b..2a4fa810008 100644 --- a/src/devices/cpu/tms1000/tms0980.h +++ b/src/devices/cpu/tms1000/tms0980.h @@ -29,9 +29,7 @@ protected: virtual void device_add_mconfig(machine_config &config) override; - virtual u32 disasm_min_opcode_bytes() const override { return 2; } - virtual u32 disasm_max_opcode_bytes() const override { return 2; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; virtual u8 read_k_input() override; virtual void set_cki_bus() override; diff --git a/src/devices/cpu/tms1000/tms1000.cpp b/src/devices/cpu/tms1000/tms1000.cpp index 55ac2a01d8c..813f1da99f8 100644 --- a/src/devices/cpu/tms1000/tms1000.cpp +++ b/src/devices/cpu/tms1000/tms1000.cpp @@ -2,17 +2,19 @@ // copyright-holders:hap /* - TMS1000 family - TMS1000, TMS1070, TMS1040, TMS1200, TMS1700, TMS1730, + TMS1000 family - TMS1000, TMS1000C, TMS1070, TMS1040, TMS1200, TMS1700, TMS1730, and second source Motorola MC141000, MC141200. TODO: - add TMS1270 (10 O pins, how does that work?) - - add TMS1000C, TMS1200C (CMOS, and 3-level stack) + - add TMS1200C (has L input pins like TMS1600) + - add HALT input pin for TMS1000C */ #include "emu.h" #include "tms1000.h" +#include "tms1k_dasm.h" #include "debugger.h" // TMS1000 @@ -31,6 +33,10 @@ DEFINE_DEVICE_TYPE(TMS1200, tms1200_cpu_device, "tms1200", "TMS1200") // 40-p DEFINE_DEVICE_TYPE(TMS1700, tms1700_cpu_device, "tms1700", "TMS1700") // 28-pin DIP, RAM/ROM size halved, 9 R pins DEFINE_DEVICE_TYPE(TMS1730, tms1730_cpu_device, "tms1730", "TMS1730") // 20-pin DIP, same die as TMS1700, package has less pins: 6 R pins, 5 O pins (output PLA is still 8-bit, O1,O3,O5 unused) +// CMOS versions (3-level stack, HALT pin) +DEFINE_DEVICE_TYPE(TMS1000C, tms1000c_cpu_device, "tms1000c", "TMS1000C") // 28-pin SDIP, 10 R pins + +// 2nd source Motorola chips DEFINE_DEVICE_TYPE(MC141000, mc141000_cpu_device, "mc141000", "MC141000") // CMOS, pin-compatible with TMS1000(reverse polarity) DEFINE_DEVICE_TYPE(MC141200, mc141200_cpu_device, "mc141200", "MC141200") // CMOS, 40-pin DIP, 16 R pins @@ -90,6 +96,11 @@ tms1730_cpu_device::tms1730_cpu_device(const machine_config &mconfig, const char { } +tms1000c_cpu_device::tms1000c_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : tms1000_cpu_device(mconfig, TMS1000C, tag, owner, clock, 8, 10, 6, 8, 2, 10, ADDRESS_MAP_NAME(program_10bit_8), 6, ADDRESS_MAP_NAME(data_64x4)) +{ +} + mc141000_cpu_device::mc141000_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : tms1000_cpu_device(mconfig, MC141000, tag, owner, clock, 8, 11, 6, 8, 2, 10, ADDRESS_MAP_NAME(program_10bit_8), 6, ADDRESS_MAP_NAME(data_64x4)) { @@ -102,7 +113,7 @@ mc141200_cpu_device::mc141200_cpu_device(const machine_config &mconfig, const ch // machine configs - MACHINE_CONFIG_MEMBER(tms1000_cpu_device::device_add_mconfig) +MACHINE_CONFIG_MEMBER(tms1000_cpu_device::device_add_mconfig) // microinstructions PLA, output PLA MCFG_PLA_ADD("mpla", 8, 16, 30) @@ -112,10 +123,9 @@ mc141200_cpu_device::mc141200_cpu_device(const machine_config &mconfig, const ch MACHINE_CONFIG_END // disasm -offs_t tms1000_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +util::disasm_interface *tms1000_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE(tms1000); - return CPU_DISASSEMBLE_NAME(tms1000)(this, stream, pc, oprom, opram, options); + return new tms1000_disassembler; } diff --git a/src/devices/cpu/tms1000/tms1000.h b/src/devices/cpu/tms1000/tms1000.h index ae85b7ed579..9e969dfc356 100644 --- a/src/devices/cpu/tms1000/tms1000.h +++ b/src/devices/cpu/tms1000/tms1000.h @@ -26,8 +26,7 @@ protected: virtual void device_reset() override; virtual void device_add_mconfig(machine_config &config) override; - - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; }; class tms1070_cpu_device : public tms1000_cpu_device @@ -63,6 +62,19 @@ public: }; +class tms1000c_cpu_device : public tms1000_cpu_device +{ +public: + tms1000c_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + +protected: + // overrides + virtual void op_br() override { op_br3(); } // 3-level stack + virtual void op_call() override { op_call3(); } // " + virtual void op_retn() override { op_retn3(); } // " +}; + + class mc141000_cpu_device : public tms1000_cpu_device { public: @@ -77,6 +89,7 @@ public: DECLARE_DEVICE_TYPE(TMS1000, tms1000_cpu_device) +DECLARE_DEVICE_TYPE(TMS1000C, tms1000c_cpu_device) DECLARE_DEVICE_TYPE(TMS1070, tms1070_cpu_device) DECLARE_DEVICE_TYPE(TMS1040, tms1040_cpu_device) DECLARE_DEVICE_TYPE(TMS1200, tms1200_cpu_device) diff --git a/src/devices/cpu/tms1000/tms1100.cpp b/src/devices/cpu/tms1000/tms1100.cpp index a67f1261512..70c38bc72c1 100644 --- a/src/devices/cpu/tms1000/tms1100.cpp +++ b/src/devices/cpu/tms1000/tms1100.cpp @@ -8,6 +8,7 @@ #include "emu.h" #include "tms1100.h" +#include "tms1k_dasm.h" #include "debugger.h" // TMS1100 is nearly the same as TMS1000, some different opcodes, and with double the RAM and ROM @@ -55,13 +56,11 @@ tms1370_cpu_device::tms1370_cpu_device(const machine_config &mconfig, const char // disasm -offs_t tms1100_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +util::disasm_interface *tms1100_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE(tms1100); - return CPU_DISASSEMBLE_NAME(tms1100)(this, stream, pc, oprom, opram, options); + return new tms1100_disassembler; } - // device_reset void tms1100_cpu_device::device_reset() { diff --git a/src/devices/cpu/tms1000/tms1100.h b/src/devices/cpu/tms1000/tms1100.h index 26a3ffbc578..86a0028a3aa 100644 --- a/src/devices/cpu/tms1000/tms1100.h +++ b/src/devices/cpu/tms1000/tms1100.h @@ -25,7 +25,7 @@ protected: // overrides virtual void device_reset() override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void op_setr() override; virtual void op_rstr() override; diff --git a/src/devices/cpu/tms1000/tms1400.cpp b/src/devices/cpu/tms1000/tms1400.cpp index 470136a16e5..4c392ec7599 100644 --- a/src/devices/cpu/tms1000/tms1400.cpp +++ b/src/devices/cpu/tms1000/tms1400.cpp @@ -88,58 +88,3 @@ void tms1400_cpu_device::device_reset() // small differences in 00-3f area m_fixed_decode[0x0b] = F_TPC; } - - -// opcode deviations -void tms1400_cpu_device::op_br() -{ - // BR/BL: conditional branch - if (m_status) - { - m_pa = m_pb; // don't care about clatch - m_ca = m_cb; - m_pc = m_opcode & m_pc_mask; - } -} - -void tms1400_cpu_device::op_call() -{ - // CALL/CALLL: conditional call - if (m_status) - { - // 3-level stack, mask clatch 3 bits (no need to mask others) - m_clatch = (m_clatch << 1 | 1) & 7; - - m_sr = m_sr << m_pc_bits | m_pc; - m_pc = m_opcode & m_pc_mask; - - m_ps = m_ps << 4 | m_pa; - m_pa = m_pb; - - m_cs = m_cs << 2 | m_ca; - m_ca = m_cb; - } - else - { - m_pb = m_pa; - m_cb = m_ca; - } -} - -void tms1400_cpu_device::op_retn() -{ - // RETN: return from subroutine - if (m_clatch & 1) - { - m_clatch >>= 1; - - m_pc = m_sr & m_pc_mask; - m_sr >>= m_pc_bits; - - m_pa = m_pb = m_ps & 0xf; - m_ps >>= 4; - - m_ca = m_cb = m_cs & 3; - m_cs >>= 2; - } -} diff --git a/src/devices/cpu/tms1000/tms1400.h b/src/devices/cpu/tms1000/tms1400.h index 59462360457..e6213f028fc 100644 --- a/src/devices/cpu/tms1000/tms1400.h +++ b/src/devices/cpu/tms1000/tms1400.h @@ -26,9 +26,9 @@ protected: virtual void device_reset() override; virtual void device_add_mconfig(machine_config &config) override; - virtual void op_br() override; - virtual void op_call() override; - virtual void op_retn() override; + virtual void op_br() override { op_br3(); } // 3-level stack + virtual void op_call() override { op_call3(); } // " + virtual void op_retn() override { op_retn3(); } // " virtual void op_setr() override { tms1k_base_device::op_setr(); } // no anomaly with MSB of X register virtual void op_rstr() override { tms1k_base_device::op_rstr(); } // " diff --git a/src/devices/cpu/tms1000/tms1k_base.cpp b/src/devices/cpu/tms1000/tms1k_base.cpp index 985784570e8..eb389fc6bc9 100644 --- a/src/devices/cpu/tms1000/tms1k_base.cpp +++ b/src/devices/cpu/tms1000/tms1k_base.cpp @@ -5,7 +5,6 @@ TMS1000 family - base/shared TODO: - - fix debugger disasm view - INIT pin @@ -72,7 +71,7 @@ unknown cycle: CME, SSE, SSS tms1k_base_device::tms1k_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 o_pins, u8 r_pins, u8 pc_bits, u8 byte_bits, u8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data) : cpu_device(mconfig, type, tag, owner, clock) - , m_program_config("program", ENDIANNESS_BIG, byte_bits > 8 ? 16 : 8, prgwidth, 0, program) + , m_program_config("program", ENDIANNESS_BIG, byte_bits > 8 ? 16 : 8, prgwidth, byte_bits > 8 ? -1 : 0, program) , m_data_config("data", ENDIANNESS_BIG, 8, datawidth, 0, data) , m_mpla(*this, "mpla") , m_ipla(*this, "ipla") @@ -405,6 +404,62 @@ void tms1k_base_device::op_retn() } +// TMS1400/TMS1000C 3-level stack version + +void tms1k_base_device::op_br3() +{ + // BR/BL: conditional branch + if (m_status) + { + m_pa = m_pb; // don't care about clatch + m_ca = m_cb; + m_pc = m_opcode & m_pc_mask; + } +} + +void tms1k_base_device::op_call3() +{ + // CALL/CALLL: conditional call + if (m_status) + { + // mask clatch 3 bits (no need to mask others) + m_clatch = (m_clatch << 1 | 1) & 7; + + m_sr = m_sr << m_pc_bits | m_pc; + m_pc = m_opcode & m_pc_mask; + + m_ps = m_ps << 4 | m_pa; + m_pa = m_pb; + + m_cs = m_cs << 2 | m_ca; + m_ca = m_cb; + } + else + { + m_pb = m_pa; + m_cb = m_ca; + } +} + +void tms1k_base_device::op_retn3() +{ + // RETN: return from subroutine + if (m_clatch & 1) + { + m_clatch >>= 1; + + m_pc = m_sr & m_pc_mask; + m_sr >>= m_pc_bits; + + m_pa = m_pb = m_ps & 0xf; + m_ps >>= 4; + + m_ca = m_cb = m_cs & 3; + m_cs >>= 2; + } +} + + // handle other: // TMS1000/common diff --git a/src/devices/cpu/tms1000/tms1k_base.h b/src/devices/cpu/tms1000/tms1k_base.h index b8cd7e2a589..7ddff2bb68f 100644 --- a/src/devices/cpu/tms1000/tms1k_base.h +++ b/src/devices/cpu/tms1000/tms1k_base.h @@ -93,6 +93,26 @@ public: u8 debug_peek_o_index() { return m_o_index; } // get output PLA index, for debugging (don't use in emulation) +protected: + // construction/destruction + tms1k_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 o_pins, u8 r_pins, u8 pc_bits, u8 byte_bits, u8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data); + + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + // device_execute_interface overrides + virtual u32 execute_min_cycles() const override { return 1; } + virtual u32 execute_max_cycles() const override { return 6; } + virtual u32 execute_input_lines() const override { return 1; } + virtual void execute_run() override; + + // device_memory_interface overrides + virtual space_config_vector memory_space_config() const override; + + // device_state_interface overrides + virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; + // microinstructions enum { @@ -151,30 +171,6 @@ public: F_XDA = (1<<20) }; -protected: - // construction/destruction - tms1k_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 o_pins, u8 r_pins, u8 pc_bits, u8 byte_bits, u8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data); - - // device-level overrides - virtual void device_start() override; - virtual void device_reset() override; - - // device_execute_interface overrides - virtual u32 execute_min_cycles() const override { return 1; } - virtual u32 execute_max_cycles() const override { return 6; } - virtual u32 execute_input_lines() const override { return 1; } - virtual void execute_run() override; - - // device_memory_interface overrides - virtual space_config_vector memory_space_config() const override; - - // device_disasm_interface overrides - virtual u32 disasm_min_opcode_bytes() const override { return 1; } - virtual u32 disasm_max_opcode_bytes() const override { return 1; } - - // device_state_interface overrides - virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; - void next_pc(); virtual void write_o_output(u8 index); @@ -186,6 +182,9 @@ protected: virtual void op_br(); virtual void op_call(); virtual void op_retn(); + virtual void op_br3(); + virtual void op_call3(); + virtual void op_retn3(); virtual void op_sbit(); virtual void op_rbit(); diff --git a/src/devices/cpu/tms1000/tms1k_dasm.cpp b/src/devices/cpu/tms1000/tms1k_dasm.cpp index f0afd660470..1cd05a57ab3 100644 --- a/src/devices/cpu/tms1000/tms1k_dasm.cpp +++ b/src/devices/cpu/tms1000/tms1k_dasm.cpp @@ -7,23 +7,9 @@ */ #include "emu.h" -#include "debugger.h" -#include "tms1k_base.h" +#include "tms1k_dasm.h" - -enum e_mnemonics -{ - zILL = 0, - zA10AAC, zA6AAC, zA8AAC, zAC1AC, zACACC, zACNAA, zALEC, zALEM, zAMAAC, zBRANCH, zCALL, zCCLA, - zCLA, zCLO, zCOMC, zCOMX, zCOMX8, zCPAIZ, zCTMDYN, zDAN, zDMAN, zDMEA, zDNAA, - zDYN, zIA, zIMAC, zIYC, zKNEZ, zLDP, zLDX2, zLDX3, zLDX4, zMNEA, zMNEZ, - zNDMEA, zOFF, zRBIT, zREAC, zRETN, zRSTR, zSAL, zSAMAN, zSBIT, - zSBL, zSEAC, zSETR, zTAM, zTAMACS, zTAMDYN, zTAMIY, zTAMIYC, zTAMZA, - zTAY, zTBIT, zTCMIY, zTCY, zTDO, zTKA, zTKM, zTMA, - zTMY, zTYA, zXDA, zXMA, zYMCY, zYNEA, zYNEC -}; - -static const char *const s_mnemonic[] = +const char *const tms1000_base_disassembler::s_mnemonic[] = { "?", "A10AAC", "A6AAC", "A8AAC", "AC1AC", "ACACC", "ACNAA", "ALEC", "ALEM", "AMAAC", "BRANCH", "CALL", "CCLA", @@ -35,29 +21,19 @@ static const char *const s_mnemonic[] = "TMY", "TYA", "XDA", "XMA", "YMCY", "YNEA", "YNEC" }; - -#define _OVER DASMFLAG_STEP_OVER -#define _OUT DASMFLAG_STEP_OUT - -static const u32 s_flags[] = +const u32 tms1000_base_disassembler::s_flags[] = { 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _OVER, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, STEP_OVER, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, _OUT, 0, 0, 0, 0, + 0, 0, 0, 0, STEP_OUT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - -enum e_addressing -{ - zB0 = 0, zI2, zI3, zI4, zB7 -}; - -static const u8 s_addressing[] = +const u8 tms1000_base_disassembler::s_addressing[] = { zB0, zB0, zB0, zB0, zI4, zI4, zI4, zI4, zB0, zB0, zB7, zB7, zB0, @@ -73,7 +49,7 @@ static const u8 s_addressing[] = // opcode luts -static const u8 tms1000_mnemonic[256] = +const u8 tms1000_disassembler::tms1000_mnemonic[256] = { /* 0x00 */ zCOMX, zA8AAC, zYNEA, zTAM, zTAMZA, zA10AAC, zA6AAC, zDAN, zTKA, zKNEZ, zTDO, zCLO, zRSTR, zSETR, zIA, zRETN, // 0 @@ -97,7 +73,7 @@ static const u8 tms1000_mnemonic[256] = }; -static const u8 tms1100_mnemonic[256] = +const u8 tms1100_disassembler::tms1100_mnemonic[256] = { /* 0x00 */ zMNEA, zALEM, zYNEA, zXMA, zDYN, zIYC, zAMAAC, zDMAN, zTKA, zCOMX, zTDO, zCOMC, zRSTR, zSETR, zKNEZ, zRETN, // 0 @@ -121,7 +97,7 @@ static const u8 tms1100_mnemonic[256] = }; -static const u8 tms0980_mnemonic[512] = +const u8 tms0980_disassembler::tms0980_mnemonic[512] = { /* 0x000 */ zCOMX, zALEM, zYNEA, zXMA, zDYN, zIYC, zCLA, zDMAN, zTKA, zMNEA, zTKM, 0, 0, zSETR, zKNEZ, 0, // 0 @@ -163,7 +139,7 @@ static const u8 tms0980_mnemonic[512] = }; -static const u8 tp0320_mnemonic[512] = +const u8 tp0320_disassembler::tp0320_mnemonic[512] = { /* 0x000 */ 0, zALEM, zYNEA, zXMA, zDYN, zIYC, zCLA, zDMAN, zTKA, zMNEA, zTKM, 0, 0, zSETR, zKNEZ, 0, // 0 @@ -208,31 +184,27 @@ static const u8 tp0320_mnemonic[512] = // disasm -static const u8 i2_value[4] = +const u8 tms1000_base_disassembler::i2_value[4] = { 0, 2, 1, 3 }; -static const u8 i3_value[8] = +const u8 tms1000_base_disassembler::i3_value[8] = { 0, 4, 2, 6, 1, 5, 3, 7 }; -static const u8 i4_value[16] = +const u8 tms1000_base_disassembler::i4_value[16] = { 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe, 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf }; -static offs_t tms1k_dasm(std::ostream &stream, const u8 *oprom, const u8 *lut_mnemonic, u16 opcode_mask) +offs_t tms1000_base_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - // get current opcode - int pos = 0; - u16 op = oprom[pos++]; - if (opcode_mask & 0x100) - op = (op << 8 | oprom[pos++]) & 0x1ff; + u16 op = m_opcode_9bits ? opcodes.r16(pc) & 0x1ff : opcodes.r8(pc); // convert to mnemonic/param - u16 instr = lut_mnemonic[op]; + u16 instr = m_lut_mnemonic[op]; util::stream_format(stream, "%-8s ", s_mnemonic[instr]); switch( s_addressing[instr] ) @@ -247,35 +219,90 @@ static offs_t tms1k_dasm(std::ostream &stream, const u8 *oprom, const u8 *lut_mn util::stream_format(stream, "%d", i4_value[op & 0x0f]); break; case zB7: - if (opcode_mask & 0x100) - util::stream_format(stream, "$%02X", op << 1 & 0xfe); - else - util::stream_format(stream, "$%02X", op & 0x3f); + util::stream_format(stream, "$%02X", op & (m_opcode_9bits ? 0x7f : 0x3f)); break; default: break; } - return pos | s_flags[instr] | DASMFLAG_SUPPORTED; + return 1 | s_flags[instr] | SUPPORTED; } +tms1000_disassembler::tms1000_disassembler() : tms1000_base_disassembler(tms1000_mnemonic, false, 6) +{ +} -CPU_DISASSEMBLE(tms1000) +tms1100_disassembler::tms1100_disassembler() : tms1000_base_disassembler(tms1100_mnemonic, false, 6) { - return tms1k_dasm(stream, oprom, tms1000_mnemonic, 0xff); } -CPU_DISASSEMBLE(tms1100) +tms0980_disassembler::tms0980_disassembler() : tms1000_base_disassembler(tms0980_mnemonic, true, 7) { - return tms1k_dasm(stream, oprom, tms1100_mnemonic, 0xff); } -CPU_DISASSEMBLE(tms0980) +tp0320_disassembler::tp0320_disassembler() : tms1000_base_disassembler(tp0320_mnemonic, true, 7) { - return tms1k_dasm(stream, oprom, tms0980_mnemonic, 0x1ff); } -CPU_DISASSEMBLE(tp0320) +tms1000_base_disassembler::tms1000_base_disassembler(const u8 *lut_mnemonic, bool opcode_9bits, int pc_bits) : m_lut_mnemonic(lut_mnemonic), m_opcode_9bits(opcode_9bits), m_pc_bits(pc_bits) { - return tms1k_dasm(stream, oprom, tp0320_mnemonic, 0x1ff); } + +offs_t tms1000_base_disassembler::pc_linear_to_real(offs_t pc) const +{ + switch(m_pc_bits) { + case 6: { + static const u8 l2r6[64] = { + 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x3e, 0x3d, 0x3b, 0x37, 0x2f, 0x1e, 0x3c, 0x39, 0x33, + 0x27, 0x0e, 0x1d, 0x3a, 0x35, 0x2b, 0x16, 0x2c, 0x18, 0x30, 0x21, 0x02, 0x05, 0x0b, 0x17, 0x2e, + 0x1c, 0x38, 0x31, 0x23, 0x06, 0x0d, 0x1b, 0x36, 0x2d, 0x1a, 0x34, 0x29, 0x12, 0x24, 0x08, 0x11, + 0x22, 0x04, 0x09, 0x13, 0x26, 0x0c, 0x19, 0x32, 0x25, 0x0a, 0x15, 0x2a, 0x14, 0x28, 0x10, 0x20, + }; + return (pc & ~0x3f) | l2r6[pc & 0x3f]; + } + case 7: { + static const u8 l2r7[128] = { + 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0x7e, 0x7d, 0x7b, 0x77, 0x6f, 0x5f, 0x3e, 0x7c, + 0x79, 0x73, 0x67, 0x4f, 0x1e, 0x3d, 0x7a, 0x75, 0x6b, 0x57, 0x2e, 0x5c, 0x38, 0x70, 0x61, 0x43, + 0x06, 0x0d, 0x1b, 0x37, 0x6e, 0x5d, 0x3a, 0x74, 0x69, 0x53, 0x26, 0x4c, 0x18, 0x31, 0x62, 0x45, + 0x0a, 0x15, 0x2b, 0x56, 0x2c, 0x58, 0x30, 0x60, 0x41, 0x02, 0x05, 0x0b, 0x17, 0x2f, 0x5e, 0x3c, + 0x78, 0x71, 0x63, 0x47, 0x0e, 0x1d, 0x3b, 0x76, 0x6d, 0x5b, 0x36, 0x6c, 0x59, 0x32, 0x64, 0x49, + 0x12, 0x25, 0x4a, 0x14, 0x29, 0x52, 0x24, 0x48, 0x10, 0x21, 0x42, 0x04, 0x09, 0x13, 0x27, 0x4e, + 0x1c, 0x39, 0x72, 0x65, 0x4b, 0x16, 0x2d, 0x5a, 0x34, 0x68, 0x51, 0x22, 0x44, 0x08, 0x11, 0x23, + 0x46, 0x0c, 0x19, 0x33, 0x66, 0x4d, 0x1a, 0x35, 0x6a, 0x55, 0x2a, 0x54, 0x28, 0x50, 0x20, 0x40, + }; + return (pc & ~0x7f) | l2r7[pc & 0x7f]; + } + } + return 0; +} + +offs_t tms1000_base_disassembler::pc_real_to_linear(offs_t pc) const +{ + switch(m_pc_bits) { + case 6: { + static const u8 r2l6[64] = { + 0x00, 0x01, 0x1b, 0x02, 0x31, 0x1c, 0x24, 0x03, 0x2e, 0x32, 0x39, 0x1d, 0x35, 0x25, 0x11, 0x04, + 0x3e, 0x2f, 0x2c, 0x33, 0x3c, 0x3a, 0x16, 0x1e, 0x18, 0x36, 0x29, 0x26, 0x20, 0x12, 0x0c, 0x05, + 0x3f, 0x1a, 0x30, 0x23, 0x2d, 0x38, 0x34, 0x10, 0x3d, 0x2b, 0x3b, 0x15, 0x17, 0x28, 0x1f, 0x0b, + 0x19, 0x22, 0x37, 0x0f, 0x2a, 0x14, 0x27, 0x0a, 0x21, 0x0e, 0x13, 0x09, 0x0d, 0x08, 0x07, 0x06, + }; + return (pc & ~0x3f) | r2l6[pc & 0x3f]; + } + case 7: { + static const u8 r2l7[128] = { + 0x00, 0x01, 0x39, 0x02, 0x5b, 0x3a, 0x20, 0x03, 0x6d, 0x5c, 0x30, 0x3b, 0x71, 0x21, 0x44, 0x04, + 0x58, 0x6e, 0x50, 0x5d, 0x53, 0x31, 0x65, 0x3c, 0x2c, 0x72, 0x76, 0x22, 0x60, 0x45, 0x14, 0x05, + 0x7e, 0x59, 0x6b, 0x6f, 0x56, 0x51, 0x2a, 0x5e, 0x7c, 0x54, 0x7a, 0x32, 0x34, 0x66, 0x1a, 0x3d, + 0x36, 0x2d, 0x4d, 0x73, 0x68, 0x77, 0x4a, 0x23, 0x1c, 0x61, 0x26, 0x46, 0x3f, 0x15, 0x0e, 0x06, + 0x7f, 0x38, 0x5a, 0x1f, 0x6c, 0x2f, 0x70, 0x43, 0x57, 0x4f, 0x52, 0x64, 0x2b, 0x75, 0x5f, 0x13, + 0x7d, 0x6a, 0x55, 0x29, 0x7b, 0x79, 0x33, 0x19, 0x35, 0x4c, 0x67, 0x49, 0x1b, 0x25, 0x3e, 0x0d, + 0x37, 0x1e, 0x2e, 0x42, 0x4e, 0x63, 0x74, 0x12, 0x69, 0x28, 0x78, 0x18, 0x4b, 0x48, 0x24, 0x0c, + 0x1d, 0x41, 0x62, 0x11, 0x27, 0x17, 0x47, 0x0b, 0x40, 0x10, 0x16, 0x0a, 0x0f, 0x09, 0x08, 0x07, + }; + return (pc & ~0x7f) | r2l7[pc & 0x7f]; + } + } + return 0; +} + diff --git a/src/devices/cpu/tms1000/tms1k_dasm.h b/src/devices/cpu/tms1000/tms1k_dasm.h new file mode 100644 index 00000000000..64e9e6f5082 --- /dev/null +++ b/src/devices/cpu/tms1000/tms1k_dasm.h @@ -0,0 +1,100 @@ +// license:BSD-3-Clause +// copyright-holders:Wilbert Pol, hap +/* + + TMS0980/TMS1000-family disassembler + +*/ + +#ifndef MAME_CPU_TMS1000_TMS1K_DASM_H +#define MAME_CPU_TMS1000_TMS1K_DASM_H + +#pragma once + +class tms1000_base_disassembler : public util::disasm_interface +{ +public: + tms1000_base_disassembler(const u8 *lut_mnemonic, bool opcode_9bits, int pc_bits); + virtual ~tms1000_base_disassembler() = default; + + virtual u32 opcode_alignment() const override { return 1; } + virtual u32 interface_flags() const override { return NONLINEAR_PC | PAGED; } + virtual u32 page_address_bits() const override { return m_pc_bits; } + virtual offs_t pc_linear_to_real(offs_t pc) const override; + virtual offs_t pc_real_to_linear(offs_t pc) const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +protected: + enum e_mnemonics + { + zILL = 0, + zA10AAC, zA6AAC, zA8AAC, zAC1AC, zACACC, zACNAA, zALEC, zALEM, zAMAAC, zBRANCH, zCALL, zCCLA, + zCLA, zCLO, zCOMC, zCOMX, zCOMX8, zCPAIZ, zCTMDYN, zDAN, zDMAN, zDMEA, zDNAA, + zDYN, zIA, zIMAC, zIYC, zKNEZ, zLDP, zLDX2, zLDX3, zLDX4, zMNEA, zMNEZ, + zNDMEA, zOFF, zRBIT, zREAC, zRETN, zRSTR, zSAL, zSAMAN, zSBIT, + zSBL, zSEAC, zSETR, zTAM, zTAMACS, zTAMDYN, zTAMIY, zTAMIYC, zTAMZA, + zTAY, zTBIT, zTCMIY, zTCY, zTDO, zTKA, zTKM, zTMA, + zTMY, zTYA, zXDA, zXMA, zYMCY, zYNEA, zYNEC + }; + + enum e_addressing + { + zB0 = 0, zI2, zI3, zI4, zB7 + }; + + static const char *const s_mnemonic[]; + static const u32 s_flags[]; + static const u8 s_addressing[]; + static const u8 i2_value[4]; + static const u8 i3_value[8]; + static const u8 i4_value[16]; + + const u8 *m_lut_mnemonic; + bool m_opcode_9bits; + int m_pc_bits; +}; + +class tms1000_disassembler : public tms1000_base_disassembler +{ +public: + tms1000_disassembler(); + virtual ~tms1000_disassembler() = default; + +protected: + static const u8 tms1000_mnemonic[256]; +}; + +class tms1100_disassembler : public tms1000_base_disassembler +{ +public: + tms1100_disassembler(); + virtual ~tms1100_disassembler() = default; + + virtual u32 interface_flags() const override { return NONLINEAR_PC | PAGED2LEVEL; } + virtual u32 page2_address_bits() const override { return 4; } + +protected: + static const u8 tms1100_mnemonic[256]; +}; + +class tms0980_disassembler : public tms1000_base_disassembler +{ +public: + tms0980_disassembler(); + virtual ~tms0980_disassembler() = default; + +protected: + static const u8 tms0980_mnemonic[512]; +}; + +class tp0320_disassembler : public tms1000_base_disassembler +{ +public: + tp0320_disassembler(); + virtual ~tp0320_disassembler() = default; + +protected: + static const u8 tp0320_mnemonic[512]; +}; + +#endif diff --git a/src/devices/cpu/tms1000/tp0320.cpp b/src/devices/cpu/tms1000/tp0320.cpp index 02e961f6473..64ebdb3365a 100644 --- a/src/devices/cpu/tms1000/tp0320.cpp +++ b/src/devices/cpu/tms1000/tp0320.cpp @@ -11,6 +11,7 @@ #include "emu.h" #include "tp0320.h" +#include "tms1k_dasm.h" #include "debugger.h" // TP0320 is TI's first CMOS MCU with integrated LCD controller, the die is still very similar to TMS0980 @@ -27,7 +28,7 @@ DEFINE_DEVICE_TYPE(TP0320, tp0320_cpu_device, "tp0320", "TP0320") // 28-pin SDIP // internal memory maps static ADDRESS_MAP_START(program_11bit_9, AS_PROGRAM, 16, tms1k_base_device) - AM_RANGE(0x000, 0xfff) AM_ROM + AM_RANGE(0x000, 0x7ff) AM_ROM ADDRESS_MAP_END static ADDRESS_MAP_START(data_192x4, AS_DATA, 8, tms1k_base_device) @@ -38,7 +39,7 @@ ADDRESS_MAP_END // device definitions tp0320_cpu_device::tp0320_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : tms0980_cpu_device(mconfig, TP0320, tag, owner, clock, 7 /* o pins */, 10 /* r pins */, 7 /* pc bits */, 9 /* byte width */, 4 /* x width */, 12 /* prg width */, ADDRESS_MAP_NAME(program_11bit_9), 8 /* data width */, ADDRESS_MAP_NAME(data_192x4)) + : tms0980_cpu_device(mconfig, TP0320, tag, owner, clock, 7 /* o pins */, 10 /* r pins */, 7 /* pc bits */, 9 /* byte width */, 4 /* x width */, 11 /* prg width */, ADDRESS_MAP_NAME(program_11bit_9), 8 /* data width */, ADDRESS_MAP_NAME(data_192x4)) { } @@ -55,10 +56,9 @@ MACHINE_CONFIG_END // disasm -offs_t tp0320_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +util::disasm_interface *tp0320_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE(tp0320); - return CPU_DISASSEMBLE_NAME(tp0320)(this, stream, pc, oprom, opram, options); + return new tp0320_disassembler; } diff --git a/src/devices/cpu/tms1000/tp0320.h b/src/devices/cpu/tms1000/tp0320.h index e740ae83320..9b23155f1c4 100644 --- a/src/devices/cpu/tms1000/tp0320.h +++ b/src/devices/cpu/tms1000/tp0320.h @@ -26,7 +26,7 @@ protected: virtual u32 decode_fixed(u16 op) override { return 0; } // not yet virtual u32 decode_micro(u8 sel) override; virtual void device_reset() override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void device_add_mconfig(machine_config &config) override; }; diff --git a/src/devices/cpu/tms32010/32010dsm.cpp b/src/devices/cpu/tms32010/32010dsm.cpp index 040a24b11b6..a1dfade63b4 100644 --- a/src/devices/cpu/tms32010/32010dsm.cpp +++ b/src/devices/cpu/tms32010/32010dsm.cpp @@ -25,153 +25,130 @@ \**************************************************************************/ #include "emu.h" -#include "debugger.h" +#include "32010dsm.h" #include <ctype.h> -#include "tms32010.h" +const char *const tms32010_disassembler::arith[4] = { "*" , "*-" , "*+" , "??" } ; +const char *const tms32010_disassembler::nextar[4] = { ",AR0" , ",AR1" , "" , "" } ; - -typedef unsigned char byte; -typedef unsigned short int word; - -#define FMT(a,b) a, b -#define PTRS_PER_FORMAT 2 - -static const char *const arith[4] = { "*" , "*-" , "*+" , "??" } ; -static const char *const nextar[4] = { ",AR0" , ",AR1" , "" , "" } ; - - -static const char *const TMS32010Formats[] = { - FMT("0000ssss0aaaaaaa", "add %A%S"), - FMT("0000ssss10mmn00n", "add %M%S%N"), - FMT("0001ssss0aaaaaaa", "sub %A%S"), - FMT("0001ssss10mmn00n", "sub %M%S%N"), - FMT("0010ssss0aaaaaaa", "lac %A%S"), - FMT("0010ssss10mmn00n", "lac %M%S%N"), - FMT("0011000r0aaaaaaa", "sar %R,%A"), - FMT("0011000r10mmn00n", "sar %R%M%N"), - FMT("0011100r0aaaaaaa", "lar %R,%A"), - FMT("0011100r10mmn00n", "lar %R%M%N"), - FMT("01000ppp0aaaaaaa", "in %A,%P"), - FMT("01000ppp10mmn00n", "in %M,%P%N"), - FMT("01001ppp0aaaaaaa", "out %A,%P"), - FMT("01001ppp10mmn00n", "out %M,%P%N"), - FMT("01010sss0aaaaaaa", "sacl %A"), /* This instruction has a shift but */ - FMT("01010sss10mmn00n", "sacl %M%N"), /* is documented as not performed */ - FMT("01011sss0aaaaaaa", "sach %A%S"), - FMT("01011sss10mmn00n", "sach %M%S%N"), - FMT("011000000aaaaaaa", "addh %A"), - FMT("0110000010mmn00n", "addh %M%N"), - FMT("011000010aaaaaaa", "adds %A"), - FMT("0110000110mmn00n", "adds %M%N"), - FMT("011000100aaaaaaa", "subh %A"), - FMT("0110001010mmn00n", "subh %M%N"), - FMT("011000110aaaaaaa", "subs %A"), - FMT("0110001110mmn00n", "subs %M%N"), - FMT("011001000aaaaaaa", "subc %A"), - FMT("0110010010mmn00n", "subc %M%N"), - FMT("011001010aaaaaaa", "zalh %A"), - FMT("0110010110mmn00n", "zalh %M%N"), - FMT("011001100aaaaaaa", "zals %A"), - FMT("0110011010mmn00n", "zals %M%N"), - FMT("011001110aaaaaaa", "tblr %A"), - FMT("0110011110mmn00n", "tblr %M%N"), - FMT("011010001000000k", "larp %K"), - FMT("011010000aaaaaaa", "mar %A"), /* Actually this is executed as a NOP */ -/* FMT("0110100010mmn00n", "mar %M%N"), */ +const char *const tms32010_disassembler::TMS32010Formats[] = { + "0000ssss0aaaaaaa", "add %A%S", + "0000ssss10mmn00n", "add %M%S%N", + "0001ssss0aaaaaaa", "sub %A%S", + "0001ssss10mmn00n", "sub %M%S%N", + "0010ssss0aaaaaaa", "lac %A%S", + "0010ssss10mmn00n", "lac %M%S%N", + "0011000r0aaaaaaa", "sar %R,%A", + "0011000r10mmn00n", "sar %R%M%N", + "0011100r0aaaaaaa", "lar %R,%A", + "0011100r10mmn00n", "lar %R%M%N", + "01000ppp0aaaaaaa", "in %A,%P", + "01000ppp10mmn00n", "in %M,%P%N", + "01001ppp0aaaaaaa", "out %A,%P", + "01001ppp10mmn00n", "out %M,%P%N", + "01010sss0aaaaaaa", "sacl %A", /* This instruction has a shift but */ + "01010sss10mmn00n", "sacl %M%N", /* is documented as not performed */ + "01011sss0aaaaaaa", "sach %A%S", + "01011sss10mmn00n", "sach %M%S%N", + "011000000aaaaaaa", "addh %A", + "0110000010mmn00n", "addh %M%N", + "011000010aaaaaaa", "adds %A", + "0110000110mmn00n", "adds %M%N", + "011000100aaaaaaa", "subh %A", + "0110001010mmn00n", "subh %M%N", + "011000110aaaaaaa", "subs %A", + "0110001110mmn00n", "subs %M%N", + "011001000aaaaaaa", "subc %A", + "0110010010mmn00n", "subc %M%N", + "011001010aaaaaaa", "zalh %A", + "0110010110mmn00n", "zalh %M%N", + "011001100aaaaaaa", "zals %A", + "0110011010mmn00n", "zals %M%N", + "011001110aaaaaaa", "tblr %A", + "0110011110mmn00n", "tblr %M%N", + "011010001000000k", "larp %K", + "011010000aaaaaaa", "mar %A", /* Actually this is executed as a NOP */ +/* "0110100010mmn00n", "mar %M%N", */ /* MAR indirect has been expanded out to all its variations because one of */ /* its opcodes is the same as LARP (actually performs the same function) */ - FMT("0110100010001000", "mar *"), - FMT("0110100010001001", "mar *"), - FMT("0110100010010000", "mar *-,AR0"), - FMT("0110100010010001", "mar *-,AR1"), - FMT("0110100010011000", "mar *-"), - FMT("0110100010011001", "mar *-"), - FMT("0110100010100000", "mar *+,AR0"), - FMT("0110100010100001", "mar *+,AR1"), - FMT("0110100010101000", "mar *+"), - FMT("0110100010101001", "mar *+"), - FMT("0110100010110000", "mar ??,AR0"), - FMT("0110100010110001", "mar ??,AR1"), - FMT("0110100010111000", "mar ??"), - FMT("0110100010111001", "mar ??"), + "0110100010001000", "mar *", + "0110100010001001", "mar *", + "0110100010010000", "mar *-,AR0", + "0110100010010001", "mar *-,AR1", + "0110100010011000", "mar *-", + "0110100010011001", "mar *-", + "0110100010100000", "mar *+,AR0", + "0110100010100001", "mar *+,AR1", + "0110100010101000", "mar *+", + "0110100010101001", "mar *+", + "0110100010110000", "mar ??,AR0", + "0110100010110001", "mar ??,AR1", + "0110100010111000", "mar ??", + "0110100010111001", "mar ??", - FMT("011010010aaaaaaa", "dmov %A"), - FMT("0110100110mmn00n", "dmov %M%N"), - FMT("011010100aaaaaaa", "lt %A"), - FMT("0110101010mmn00n", "lt %M%N"), - FMT("011010110aaaaaaa", "ltd %A"), - FMT("0110101110mmn00n", "ltd %M%N"), - FMT("011011000aaaaaaa", "lta %A"), - FMT("0110110010mmn00n", "lta %M%N"), - FMT("011011010aaaaaaa", "mpy %A"), - FMT("0110110110mmn00n", "mpy %M%N"), - FMT("011011100000000k", "ldpk %K"), - FMT("011011110aaaaaaa", "ldp %A"), - FMT("0110111110mmn00n", "ldp %M%N"), - FMT("0111000rdddddddd", "lark %R,%D"), - FMT("011110000aaaaaaa", "xor %A"), - FMT("0111100010mmn00n", "xor %M%N"), - FMT("011110010aaaaaaa", "and %A"), - FMT("0111100110mmn00n", "and %M%N"), - FMT("011110100aaaaaaa", "or %A"), - FMT("0111101010mmn00n", "or %M%N"), - FMT("011110110aaaaaaa", "lst %A"), - FMT("0111101110mmn00n", "lst %M%N"), - FMT("011111000aaaaaaa", "sst %A"), - FMT("0111110010mmn00n", "sst %M%N"), - FMT("011111010aaaaaaa", "tblw %A"), - FMT("0111110110mmn00n", "tblw %M%N"), - FMT("01111110dddddddd", "lack %D"), - FMT("0111111110000000", "nop"), /* 7F80 */ - FMT("0111111110000001", "dint"), - FMT("0111111110000010", "eint"), - FMT("0111111110001000", "abs"), /* 7F88 */ - FMT("0111111110001001", "zac"), - FMT("0111111110001010", "rovm"), - FMT("0111111110001011", "sovm"), - FMT("0111111110001100", "cala"), - FMT("0111111110001101", "ret"), - FMT("0111111110001110", "pac"), - FMT("0111111110001111", "apac"), - FMT("0111111110010000", "spac"), - FMT("0111111110011100", "push"), - FMT("0111111110011101", "pop"), /* 7F9D */ - FMT("100wwwwwwwwwwwww", "mpyk %W"), - FMT("1111010000000000bbbbbbbbbbbbbbbb", "banz %B"), - FMT("1111010100000000bbbbbbbbbbbbbbbb", "bv %B"), - FMT("1111011000000000bbbbbbbbbbbbbbbb", "bioz %B"), - FMT("1111100000000000bbbbbbbbbbbbbbbb", "call %B"), - FMT("1111100100000000bbbbbbbbbbbbbbbb", "b %B"), - FMT("1111101000000000bbbbbbbbbbbbbbbb", "blz %B"), - FMT("1111101100000000bbbbbbbbbbbbbbbb", "blez %B"), - FMT("1111110000000000bbbbbbbbbbbbbbbb", "bgz %B"), - FMT("1111110100000000bbbbbbbbbbbbbbbb", "bgez %B"), - FMT("1111111000000000bbbbbbbbbbbbbbbb", "bnz %B"), - FMT("1111111100000000bbbbbbbbbbbbbbbb", "bz %B"), + "011010010aaaaaaa", "dmov %A", + "0110100110mmn00n", "dmov %M%N", + "011010100aaaaaaa", "lt %A", + "0110101010mmn00n", "lt %M%N", + "011010110aaaaaaa", "ltd %A", + "0110101110mmn00n", "ltd %M%N", + "011011000aaaaaaa", "lta %A", + "0110110010mmn00n", "lta %M%N", + "011011010aaaaaaa", "mpy %A", + "0110110110mmn00n", "mpy %M%N", + "011011100000000k", "ldpk %K", + "011011110aaaaaaa", "ldp %A", + "0110111110mmn00n", "ldp %M%N", + "0111000rdddddddd", "lark %R,%D", + "011110000aaaaaaa", "xor %A", + "0111100010mmn00n", "xor %M%N", + "011110010aaaaaaa", "and %A", + "0111100110mmn00n", "and %M%N", + "011110100aaaaaaa", "or %A", + "0111101010mmn00n", "or %M%N", + "011110110aaaaaaa", "lst %A", + "0111101110mmn00n", "lst %M%N", + "011111000aaaaaaa", "sst %A", + "0111110010mmn00n", "sst %M%N", + "011111010aaaaaaa", "tblw %A", + "0111110110mmn00n", "tblw %M%N", + "01111110dddddddd", "lack %D", + "0111111110000000", "nop", /* 7F80 */ + "0111111110000001", "dint", + "0111111110000010", "eint", + "0111111110001000", "abs", /* 7F88 */ + "0111111110001001", "zac", + "0111111110001010", "rovm", + "0111111110001011", "sovm", + "0111111110001100", "cala", + "0111111110001101", "ret", + "0111111110001110", "pac", + "0111111110001111", "apac", + "0111111110010000", "spac", + "0111111110011100", "push", + "0111111110011101", "pop", /* 7F9D */ + "100wwwwwwwwwwwww", "mpyk %W", + "1111010000000000bbbbbbbbbbbbbbbb", "banz %B", + "1111010100000000bbbbbbbbbbbbbbbb", "bv %B", + "1111011000000000bbbbbbbbbbbbbbbb", "bioz %B", + "1111100000000000bbbbbbbbbbbbbbbb", "call %B", + "1111100100000000bbbbbbbbbbbbbbbb", "b %B", + "1111101000000000bbbbbbbbbbbbbbbb", "blz %B", + "1111101100000000bbbbbbbbbbbbbbbb", "blez %B", + "1111110000000000bbbbbbbbbbbbbbbb", "bgz %B", + "1111110100000000bbbbbbbbbbbbbbbb", "bgez %B", + "1111111000000000bbbbbbbbbbbbbbbb", "bnz %B", + "1111111100000000bbbbbbbbbbbbbbbb", "bz %B", nullptr }; -#define MAX_OPS ((ARRAY_LENGTH(TMS32010Formats) - 1) / PTRS_PER_FORMAT) - -struct TMS32010Opcode { - word mask; /* instruction mask */ - word bits; /* constant bits */ - word extcode; /* value that gets extension code */ - const char *parse; /* how to parse bits */ - const char *fmt; /* instruction format */ -}; - -static TMS32010Opcode Op[MAX_OPS+1]; -static int OpInizialized = 0; - -static void InitDasm32010(void) +tms32010_disassembler::tms32010_disassembler() { const char *p; const char *const *ops; - word mask, bits; + u16 mask, bits; int bit; int i; @@ -209,20 +186,14 @@ static void InitDasm32010(void) ops[0],ops[1],bit); } while (isspace((uint8_t)*p)) p++; - if (*p) Op[i].extcode = *p; - Op[i].bits = bits; - Op[i].mask = mask; - Op[i].fmt = ops[1]; - Op[i].parse = ops[0]; + Op.emplace_back(mask, bits, *p, ops[0], ops[1]); - ops += PTRS_PER_FORMAT; + ops += 2; i++; } - - OpInizialized = 1; } -CPU_DISASSEMBLE(tms32010) +offs_t tms32010_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint32_t flags = 0; int a, b, d, k, m, n, p, r, s, w; /* these can all be filled in by parsing an instruction */ @@ -234,11 +205,9 @@ CPU_DISASSEMBLE(tms32010) //char *buffertmp; const char *cp; /* character pointer in OpFormats */ - if (!OpInizialized) InitDasm32010(); - op = -1; /* no matching opcode */ - code = (oprom[0] << 8) | oprom[1]; - for ( i = 0; i < MAX_OPS; i++) + code = opcodes.r16(pc); + for ( i = 0; i < int(Op.size()); i++) { if ((code & Op[i].mask) == Op[i].bits) { @@ -253,14 +222,14 @@ CPU_DISASSEMBLE(tms32010) if (op == -1) { util::stream_format(stream, "dw %04Xh *(invalid op)", code); - return cnt | DASMFLAG_SUPPORTED; + return cnt | SUPPORTED; } //buffertmp = buffer; if (Op[op].extcode) { bit = 31; code <<= 16; - code |= (opram[2] << 8) | opram[3]; + code |= opcodes.r16(pc+1); cnt++; } else @@ -298,9 +267,9 @@ CPU_DISASSEMBLE(tms32010) cp = Op[op].fmt; if (!strncmp(cp, "cal", 3)) - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; else if (!strncmp(cp, "ret", 3)) - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; while (*cp) { @@ -330,5 +299,11 @@ CPU_DISASSEMBLE(tms32010) stream << *cp++; } } - return cnt | flags | DASMFLAG_SUPPORTED; + return cnt | flags | SUPPORTED; } + +u32 tms32010_disassembler::opcode_alignment() const +{ + return 1; +} + diff --git a/src/devices/cpu/tms32010/32010dsm.h b/src/devices/cpu/tms32010/32010dsm.h new file mode 100644 index 00000000000..d2b93d5f5a4 --- /dev/null +++ b/src/devices/cpu/tms32010/32010dsm.h @@ -0,0 +1,59 @@ +// license:BSD-3-Clause +// copyright-holders:Tony La Porta + /**************************************************************************\ + * Texas Instruments TMS32010 DSP Disassembler * + * * + * Copyright Tony La Porta * + * To be used with TMS32010 DSP Emulator engine. * + * * + * Many thanks to those involved in the i8039 Disassembler * + * as this was based on it. * + * * + * * + * * + * A Memory address * + * B Branch Address for Branch instructions (Requires next opcode read) * + * D Immediate byte load * + * K Immediate bit load * + * W Immediate word load (Actually 13 bit) * + * M AR[x] register modification type (for indirect addressing) * + * N ARP register to change ARP pointer to (for indirect addressing) * + * P I/O port address number * + * R AR[R] register to use * + * S Shift ALU left * + * * + \**************************************************************************/ + +#ifndef MAME_CPU_TMS32010_DIS32010_H +#define MAME_CPU_TMS32010_DIS32010_H + +#pragma once + +class tms32010_disassembler : public util::disasm_interface +{ +public: + tms32010_disassembler(); + virtual ~tms32010_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + struct TMS32010Opcode { + u16 mask; /* instruction mask */ + u16 bits; /* constant bits */ + u16 extcode; /* value that gets extension code */ + const char *parse; /* how to parse bits */ + const char *fmt; /* instruction format */ + + TMS32010Opcode(u16 m, u16 b, u16 e, const char *p, const char *f) : mask(m), bits(b), extcode(e), parse(p), fmt(f) {} + }; + + static const char *const arith[4]; + static const char *const nextar[4]; + static const char *const TMS32010Formats[]; + + std::vector<TMS32010Opcode> Op; +}; + +#endif diff --git a/src/devices/cpu/tms32010/tms32010.cpp b/src/devices/cpu/tms32010/tms32010.cpp index 007cac7b0fc..968e7bde61f 100644 --- a/src/devices/cpu/tms32010/tms32010.cpp +++ b/src/devices/cpu/tms32010/tms32010.cpp @@ -59,6 +59,7 @@ #include "emu.h" #include "tms32010.h" +#include "32010dsm.h" #include "debugger.h" @@ -134,10 +135,9 @@ device_memory_interface::space_config_vector tms32010_device::memory_space_confi }; } -offs_t tms32010_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *tms32010_device::create_disassembler() { - extern CPU_DISASSEMBLE( tms32010 ); - return CPU_DISASSEMBLE_NAME(tms32010)(this, stream, pc, oprom, opram, options); + return new tms32010_disassembler; } @@ -165,14 +165,14 @@ offs_t tms32010_device::disasm_disassemble(std::ostream &stream, offs_t pc, cons * Input a word from given I/O port */ -#define TMS32010_In(Port) (m_io->read_word((Port)<<1)) +#define TMS32010_In(Port) (m_io->read_word(Port)) /**************************************************************************** * Output a word to given I/O port */ -#define TMS32010_Out(Port,Value) (m_io->write_word((Port)<<1,Value)) +#define TMS32010_Out(Port,Value) (m_io->write_word(Port,Value)) @@ -180,14 +180,14 @@ offs_t tms32010_device::disasm_disassemble(std::ostream &stream, offs_t pc, cons * Read a word from given ROM memory location */ -#define TMS32010_ROM_RDMEM(A) (m_program->read_word((A)<<1)) +#define TMS32010_ROM_RDMEM(A) (m_program->read_word(A)) /**************************************************************************** * Write a word to given ROM memory location */ -#define TMS32010_ROM_WRMEM(A,V) (m_program->write_word((A)<<1,V)) +#define TMS32010_ROM_WRMEM(A,V) (m_program->write_word(A,V)) @@ -195,14 +195,14 @@ offs_t tms32010_device::disasm_disassemble(std::ostream &stream, offs_t pc, cons * Read a word from given RAM memory location */ -#define TMS32010_RAM_RDMEM(A) (m_data->read_word((A)<<1)) +#define TMS32010_RAM_RDMEM(A) (m_data->read_word(A)) /**************************************************************************** * Write a word to given RAM memory location */ -#define TMS32010_RAM_WRMEM(A,V) (m_data->write_word((A)<<1,V)) +#define TMS32010_RAM_WRMEM(A,V) (m_data->write_word(A,V)) @@ -212,7 +212,7 @@ offs_t tms32010_device::disasm_disassemble(std::ostream &stream, offs_t pc, cons * used to greatly speed up emulation */ -#define TMS32010_RDOP(A) (m_direct->read_word((A)<<1)) +#define TMS32010_RDOP(A) (m_direct->read_word(A)) /**************************************************************************** @@ -221,7 +221,7 @@ offs_t tms32010_device::disasm_disassemble(std::ostream &stream, offs_t pc, cons * that use different encoding mechanisms for opcodes and opcode arguments */ -#define TMS32010_RDOP_ARG(A) (m_direct->read_word((A)<<1)) +#define TMS32010_RDOP_ARG(A) (m_direct->read_word(A)) /************************************************************************ @@ -523,7 +523,7 @@ void tms32010_device::eint() } void tms32010_device::in_p() { - m_ALU.w.l = P_IN( (m_opcode.b.h & 7) ); + m_ALU.w.l = P_IN(m_opcode.b.h & 7); putdata(m_ALU.w.l); } void tms32010_device::lac_sh() @@ -834,7 +834,7 @@ void tms32010_device::device_start() save_item(NAME(m_addr_mask)); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<-1>(); m_data = &space(AS_DATA); m_io = &space(AS_IO); diff --git a/src/devices/cpu/tms32010/tms32010.h b/src/devices/cpu/tms32010/tms32010.h index 2f2469330e5..eb1e40370e1 100644 --- a/src/devices/cpu/tms32010/tms32010.h +++ b/src/devices/cpu/tms32010/tms32010.h @@ -70,9 +70,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 4; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -109,7 +107,7 @@ private: int m_addr_mask; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<-1> *m_direct; address_space *m_data; address_space *m_io; diff --git a/src/devices/cpu/tms32025/32025dsm.cpp b/src/devices/cpu/tms32025/32025dsm.cpp index cf9a61571b5..b8ad14415c3 100644 --- a/src/devices/cpu/tms32025/32025dsm.cpp +++ b/src/devices/cpu/tms32025/32025dsm.cpp @@ -31,309 +31,286 @@ \**************************************************************************/ #include "emu.h" -#include "debugger.h" +#include "32025dsm.h" #include <ctype.h> -#include "tms32025.h" +const char *const tms32025_disassembler::arith[8] = { "*", "*-", "*+", "??", "BR0-", "*0-", "*0+", "*BR0+" } ; +const char *const tms32025_disassembler::nextar[16] = { "", "", "", "", "", "", "", "", ",AR0", ",AR1", ",AR2", ",AR3", ",AR4", ",AR5", ",AR6", ",AR7" } ; +const char *const tms32025_disassembler::cmpmode[4] = { "0 (ARx = AR0)" , "1 (ARx < AR0)" , "2 (ARx > AR0)" , "3 (ARx <> AR0)" } ; +const char *const tms32025_disassembler::TMS32025Formats[] = { + "0000tttt0aaaaaaa", "add %A,%T", /* 0xxx */ + "0000tttt1mmmnnnn", "add %M,%T%N", + "0001tttt0aaaaaaa", "sub %A,%T", /* 1xxx */ + "0001tttt1mmmnnnn", "sub %M,%T%N", + "0010tttt0aaaaaaa", "lac %A,%T", /* 2xxx */ + "0010tttt1mmmnnnn", "lac %M,%T%N", + "00110rrr0aaaaaaa", "lar %R,%A", /* 3xxx */ + "00110rrr1mmmnnnn", "lar %R%M%N", + "001110000aaaaaaa", "mpy %A", /* 38xx */ + "001110001mmmnnnn", "mpy %M%N", + "001110010aaaaaaa", "sqra %A", /* 39xx */ + "001110011mmmnnnn", "sqra %M%N", + "001110100aaaaaaa", "mpya %A", /* 3Axx */ + "001110101mmmnnnn", "mpya %M%N", + "001110110aaaaaaa", "mpys %A", /* 3Bxx */ + "001110111mmmnnnn", "mpys %M%N", + "001111000aaaaaaa", "lt %A", /* 3Cxx */ + "001111001mmmnnnn", "lt %M%N", + "001111010aaaaaaa", "lta %A", /* 3Dxx */ + "001111011mmmnnnn", "lta %M%N", + "001111100aaaaaaa", "ltp %A", /* 3Exx */ + "001111101mmmnnnn", "ltp %M%N", + "001111110aaaaaaa", "ltd %A", /* 3Fxx */ + "001111111mmmnnnn", "ltd %M%N", + "010000000aaaaaaa", "zalh %A", /* 40xx */ + "010000001mmmnnnn", "zalh %M%N", + "010000010aaaaaaa", "zals %A", /* 41xx */ + "010000011mmmnnnn", "zals %M%N", + "010000100aaaaaaa", "lact %A", /* 42xx */ + "010000101mmmnnnn", "lact %M%N", + "010000110aaaaaaa", "addc %A%S", /* 43xx */ + "010000111mmmnnnn", "addc %M%S%N", + "010001000aaaaaaa", "subh %A", /* 44xx */ + "010001001mmmnnnn", "subh %M%N", + "010001010aaaaaaa", "subs %A", /* 45xx */ + "010001011mmmnnnn", "subs %M%N", + "010001100aaaaaaa", "subt %A", /* 46xx */ + "010001101mmmnnnn", "subt %M%N", + "010001110aaaaaaa", "subc %A", /* 47xx */ + "010001111mmmnnnn", "subc %M%N", + "010010000aaaaaaa", "addh %A", /* 48xx */ + "010010001mmmnnnn", "addh %M%N", + "010010010aaaaaaa", "adds %A", /* 49xx */ + "010010011mmmnnnn", "adds %M%N", + "010010100aaaaaaa", "addt %A", /* 4Axx */ + "010010101mmmnnnn", "addt %M%N", + "010010110aaaaaaa", "rpt %A", /* 4Bxx */ + "010010111mmmnnnn", "rpt %M%N", + "010011000aaaaaaa", "xor %A", /* 4Cxx */ + "010011001mmmnnnn", "xor %M%N", + "010011010aaaaaaa", "or %A", /* 4Dxx */ + "010011011mmmnnnn", "or %M%N", + "010011100aaaaaaa", "and %A", /* 4Exx */ + "010011101mmmnnnn", "and %M%N", + "010011110aaaaaaa", "subb %A", /* 4Fxx */ + "010011111mmmnnnn", "subb %M%N", + "010100000aaaaaaa", "lst %A", /* 50xx */ + "010100001mmmnnnn", "lst %M%N", + "010100010aaaaaaa", "lst1 %A", /* 51xx */ + "010100011mmmnnnn", "lst1 %M%N", + "010100100aaaaaaa", "ldp %A", /* 52xx */ + "010100101mmmnnnn", "ldp %M%N", + "010100110aaaaaaa", "lph %A", /* 53xx */ + "010100111mmmnnnn", "lph %M%N", + "010101000aaaaaaa", "pshd %A", /* 54xx */ + "010101001mmmnnnn", "pshd %M%N", -typedef unsigned char byte; -typedef unsigned short int word; - -#define FMT(a,b) a, b -#define PTRS_PER_FORMAT 2 - -static const char *const arith[8] = { "*", "*-", "*+", "??", "BR0-", "*0-", "*0+", "*BR0+" } ; -static const char *const nextar[16] = { "", "", "", "", "", "", "", "", ",AR0", ",AR1", ",AR2", ",AR3", ",AR4", ",AR5", ",AR6", ",AR7" } ; -static const char *const cmpmode[4] = { "0 (ARx = AR0)" , "1 (ARx < AR0)" , "2 (ARx > AR0)" , "3 (ARx <> AR0)" } ; - - -static const char *const TMS32025Formats[] = { - FMT("0000tttt0aaaaaaa", "add %A,%T"), /* 0xxx */ - FMT("0000tttt1mmmnnnn", "add %M,%T%N"), - FMT("0001tttt0aaaaaaa", "sub %A,%T"), /* 1xxx */ - FMT("0001tttt1mmmnnnn", "sub %M,%T%N"), - FMT("0010tttt0aaaaaaa", "lac %A,%T"), /* 2xxx */ - FMT("0010tttt1mmmnnnn", "lac %M,%T%N"), - FMT("00110rrr0aaaaaaa", "lar %R,%A"), /* 3xxx */ - FMT("00110rrr1mmmnnnn", "lar %R%M%N"), - FMT("001110000aaaaaaa", "mpy %A"), /* 38xx */ - FMT("001110001mmmnnnn", "mpy %M%N"), - FMT("001110010aaaaaaa", "sqra %A"), /* 39xx */ - FMT("001110011mmmnnnn", "sqra %M%N"), - FMT("001110100aaaaaaa", "mpya %A"), /* 3Axx */ - FMT("001110101mmmnnnn", "mpya %M%N"), - FMT("001110110aaaaaaa", "mpys %A"), /* 3Bxx */ - FMT("001110111mmmnnnn", "mpys %M%N"), - FMT("001111000aaaaaaa", "lt %A"), /* 3Cxx */ - FMT("001111001mmmnnnn", "lt %M%N"), - FMT("001111010aaaaaaa", "lta %A"), /* 3Dxx */ - FMT("001111011mmmnnnn", "lta %M%N"), - FMT("001111100aaaaaaa", "ltp %A"), /* 3Exx */ - FMT("001111101mmmnnnn", "ltp %M%N"), - FMT("001111110aaaaaaa", "ltd %A"), /* 3Fxx */ - FMT("001111111mmmnnnn", "ltd %M%N"), - FMT("010000000aaaaaaa", "zalh %A"), /* 40xx */ - FMT("010000001mmmnnnn", "zalh %M%N"), - FMT("010000010aaaaaaa", "zals %A"), /* 41xx */ - FMT("010000011mmmnnnn", "zals %M%N"), - FMT("010000100aaaaaaa", "lact %A"), /* 42xx */ - FMT("010000101mmmnnnn", "lact %M%N"), - FMT("010000110aaaaaaa", "addc %A%S"), /* 43xx */ - FMT("010000111mmmnnnn", "addc %M%S%N"), - FMT("010001000aaaaaaa", "subh %A"), /* 44xx */ - FMT("010001001mmmnnnn", "subh %M%N"), - FMT("010001010aaaaaaa", "subs %A"), /* 45xx */ - FMT("010001011mmmnnnn", "subs %M%N"), - FMT("010001100aaaaaaa", "subt %A"), /* 46xx */ - FMT("010001101mmmnnnn", "subt %M%N"), - FMT("010001110aaaaaaa", "subc %A"), /* 47xx */ - FMT("010001111mmmnnnn", "subc %M%N"), - FMT("010010000aaaaaaa", "addh %A"), /* 48xx */ - FMT("010010001mmmnnnn", "addh %M%N"), - FMT("010010010aaaaaaa", "adds %A"), /* 49xx */ - FMT("010010011mmmnnnn", "adds %M%N"), - FMT("010010100aaaaaaa", "addt %A"), /* 4Axx */ - FMT("010010101mmmnnnn", "addt %M%N"), - FMT("010010110aaaaaaa", "rpt %A"), /* 4Bxx */ - FMT("010010111mmmnnnn", "rpt %M%N"), - FMT("010011000aaaaaaa", "xor %A"), /* 4Cxx */ - FMT("010011001mmmnnnn", "xor %M%N"), - FMT("010011010aaaaaaa", "or %A"), /* 4Dxx */ - FMT("010011011mmmnnnn", "or %M%N"), - FMT("010011100aaaaaaa", "and %A"), /* 4Exx */ - FMT("010011101mmmnnnn", "and %M%N"), - FMT("010011110aaaaaaa", "subb %A"), /* 4Fxx */ - FMT("010011111mmmnnnn", "subb %M%N"), - FMT("010100000aaaaaaa", "lst %A"), /* 50xx */ - FMT("010100001mmmnnnn", "lst %M%N"), - FMT("010100010aaaaaaa", "lst1 %A"), /* 51xx */ - FMT("010100011mmmnnnn", "lst1 %M%N"), - FMT("010100100aaaaaaa", "ldp %A"), /* 52xx */ - FMT("010100101mmmnnnn", "ldp %M%N"), - FMT("010100110aaaaaaa", "lph %A"), /* 53xx */ - FMT("010100111mmmnnnn", "lph %M%N"), - FMT("010101000aaaaaaa", "pshd %A"), /* 54xx */ - FMT("010101001mmmnnnn", "pshd %M%N"), - -/* FMT("010101010aaaaaaa", "mar %A"), 55xx */ +/* "010101010aaaaaaa", "mar %A", 55xx */ /* MAR direct has been expanded out to all its variations because one of its */ /* its opcodes is the same as NOP. Actually MAR direct just performs a NOP */ - FMT("0101010100000000", "nop"), /* 5500 */ - FMT("0101010100000001", "mar $01"), - FMT("0101010100000010", "mar $02"), - FMT("0101010100000011", "mar $03"), - FMT("0101010100000100", "mar $04"), - FMT("0101010100000101", "mar $05"), - FMT("0101010100000110", "mar $06"), - FMT("0101010100000111", "mar $07"), - FMT("0101010100001000", "mar $08"), - FMT("0101010100001001", "mar $09"), - FMT("0101010100001010", "mar $0A"), - FMT("0101010100001011", "mar $0B"), - FMT("0101010100001100", "mar $0C"), - FMT("0101010100001101", "mar $0D"), - FMT("0101010100001110", "mar $0E"), - FMT("0101010100001111", "mar $0F"), - FMT("010101010001tttt", "mar $1%T"), - FMT("010101010010tttt", "mar $2%T"), - FMT("010101010011tttt", "mar $3%T"), - FMT("010101010100tttt", "mar $4%T"), - FMT("010101010101tttt", "mar $5%T"), - FMT("010101010110tttt", "mar $6%T"), - FMT("010101010111tttt", "mar $7%T"), + "0101010100000000", "nop", /* 5500 */ + "0101010100000001", "mar $01", + "0101010100000010", "mar $02", + "0101010100000011", "mar $03", + "0101010100000100", "mar $04", + "0101010100000101", "mar $05", + "0101010100000110", "mar $06", + "0101010100000111", "mar $07", + "0101010100001000", "mar $08", + "0101010100001001", "mar $09", + "0101010100001010", "mar $0A", + "0101010100001011", "mar $0B", + "0101010100001100", "mar $0C", + "0101010100001101", "mar $0D", + "0101010100001110", "mar $0E", + "0101010100001111", "mar $0F", + "010101010001tttt", "mar $1%T", + "010101010010tttt", "mar $2%T", + "010101010011tttt", "mar $3%T", + "010101010100tttt", "mar $4%T", + "010101010101tttt", "mar $5%T", + "010101010110tttt", "mar $6%T", + "010101010111tttt", "mar $7%T", -/* FMT("010101011mmmnnnn", "mar %M%N"), 55xx */ +/* "010101011mmmnnnn", "mar %M%N", 55xx */ /* MAR indirect has been expanded out to all its variations because one of */ /* its opcodes, is the same as LARP (actually performs the same function) */ - FMT("0101010110000xxx", "mar *"), /* 558x */ - FMT("0101010110001kkk", "larp %K"), /* 558x */ - FMT("010101011001nnnn", "mar *-%N"), /* 558x */ - FMT("010101011010nnnn", "mar *+%N"), - FMT("010101011011nnnn", "mar ??%N"), - FMT("010101011100nnnn", "mar *BR0-%N"), - FMT("010101011101nnnn", "mar *0-%N"), - FMT("010101011110nnnn", "mar *0+%N"), - FMT("010101011111nnnn", "mar *BR0+%N"), + "0101010110000xxx", "mar *", /* 558x */ + "0101010110001kkk", "larp %K", /* 558x */ + "010101011001nnnn", "mar *-%N", /* 558x */ + "010101011010nnnn", "mar *+%N", + "010101011011nnnn", "mar ??%N", + "010101011100nnnn", "mar *BR0-%N", + "010101011101nnnn", "mar *0-%N", + "010101011110nnnn", "mar *0+%N", + "010101011111nnnn", "mar *BR0+%N", - FMT("010101100aaaaaaa", "dmov %A"), /* 56xx */ - FMT("010101101mmmnnnn", "dmov %M%N"), - FMT("010101110aaaaaaa", "bitt %A"), /* 57xx */ - FMT("010101111mmmnnnn", "bitt %M%N"), - FMT("010110000aaaaaaa", "tblr %A"), /* 58xx */ - FMT("010110001mmmnnnn", "tblr %M%N"), - FMT("010110010aaaaaaa", "tblw %A"), /* 59xx */ - FMT("010110011mmmnnnn", "tblw %M%N"), - FMT("010110100aaaaaaa", "sqrs %A"), /* 5Axx */ - FMT("010110101mmmnnnn", "sqrs %M%N"), - FMT("010110110aaaaaaa", "lts %A"), /* 5Bxx */ - FMT("010110111mmmnnnn", "lts %M%N"), - FMT("010111000aaaaaaabbbbbbbbbbbbbbbb", "macd %B,%A"), /* 5Cxx */ - FMT("010111001mmmnnnnbbbbbbbbbbbbbbbb", "macd %B,%M%N"), - FMT("010111010aaaaaaabbbbbbbbbbbbbbbb", "mac %B,%A"), /* 5Dxx */ - FMT("010111011mmmnnnnbbbbbbbbbbbbbbbb", "mac %B,%M%N"), - FMT("010111101mmmnnnnbbbbbbbbbbbbbbbb", "bc %B %M%N"), /* 5Exx */ - FMT("010111111mmmnnnnbbbbbbbbbbbbbbbb", "bnc %B %M%N"), /* 5Fxx */ - FMT("01100sss0aaaaaaa", "sacl %A%S"), /* 6xxx */ - FMT("01100sss1mmmnnnn", "sacl %M%S%N"), - FMT("01101sss0aaaaaaa", "sach %A%S"), /* 6Xxx */ - FMT("01101sss1mmmnnnn", "sach %M%S%N"), - FMT("01110rrr0aaaaaaa", "sar %R,%A"), /* 7xxx */ - FMT("01110rrr1mmmnnnn", "sar %R%M%N"), - FMT("011110000aaaaaaa", "sst %A"), /* 78xx */ - FMT("011110001mmmnnnn", "sst %M%N"), - FMT("011110010aaaaaaa", "sst1 %A"), /* 79xx */ - FMT("011110011mmmnnnn", "sst1 %M%N"), - FMT("011110100aaaaaaa", "popd %A"), /* 7Axx */ - FMT("011110101mmmnnnn", "popd %M%N"), - FMT("011110110aaaaaaa", "zalr %A"), /* 7Bxx */ - FMT("011110111mmmnnnn", "zalr %M%N"), - FMT("011111000aaaaaaa", "spl %A"), /* 7Cxx */ - FMT("011111001mmmnnnn", "spl %M%N"), - FMT("011111010aaaaaaa", "sph %A"), /* 7Dxx */ - FMT("011111011mmmnnnn", "sph %M%N"), - FMT("011111100aaaaaaa", "adrk %A"), /* 7Exx */ - FMT("011111101mmmnnnn", "adrk %M%N"), - FMT("011111110aaaaaaa", "sbrk %A"), /* 7Fxx */ - FMT("011111111mmmnnnn", "sbrk %M%N"), - FMT("1000pppp0aaaaaaa", "in %A,%P"), /* 8xxx */ - FMT("1000pppp1mmmnnnn", "in %M,%P%N"), - FMT("1001tttt0aaaaaaa", "bit %A,%T"), /* 9xxx */ - FMT("1001tttt1mmmnnnn", "bit %M,%T%N"), - FMT("101wwwwwwwwwwwww", "mpyk %W"), /* Axxx-Bxxx */ - FMT("11000rrrdddddddd", "lark %R,%D"), /* Cxxx */ - FMT("1100100kdddddddd", "ldpk %K%D"), /* Cxxx */ -/* FMT("11001010dddddddd", "lack %D"), CAxx */ + "010101100aaaaaaa", "dmov %A", /* 56xx */ + "010101101mmmnnnn", "dmov %M%N", + "010101110aaaaaaa", "bitt %A", /* 57xx */ + "010101111mmmnnnn", "bitt %M%N", + "010110000aaaaaaa", "tblr %A", /* 58xx */ + "010110001mmmnnnn", "tblr %M%N", + "010110010aaaaaaa", "tblw %A", /* 59xx */ + "010110011mmmnnnn", "tblw %M%N", + "010110100aaaaaaa", "sqrs %A", /* 5Axx */ + "010110101mmmnnnn", "sqrs %M%N", + "010110110aaaaaaa", "lts %A", /* 5Bxx */ + "010110111mmmnnnn", "lts %M%N", + "010111000aaaaaaabbbbbbbbbbbbbbbb", "macd %B,%A", /* 5Cxx */ + "010111001mmmnnnnbbbbbbbbbbbbbbbb", "macd %B,%M%N", + "010111010aaaaaaabbbbbbbbbbbbbbbb", "mac %B,%A", /* 5Dxx */ + "010111011mmmnnnnbbbbbbbbbbbbbbbb", "mac %B,%M%N", + "010111101mmmnnnnbbbbbbbbbbbbbbbb", "bc %B %M%N", /* 5Exx */ + "010111111mmmnnnnbbbbbbbbbbbbbbbb", "bnc %B %M%N", /* 5Fxx */ + "01100sss0aaaaaaa", "sacl %A%S", /* 6xxx */ + "01100sss1mmmnnnn", "sacl %M%S%N", + "01101sss0aaaaaaa", "sach %A%S", /* 6Xxx */ + "01101sss1mmmnnnn", "sach %M%S%N", + "01110rrr0aaaaaaa", "sar %R,%A", /* 7xxx */ + "01110rrr1mmmnnnn", "sar %R%M%N", + "011110000aaaaaaa", "sst %A", /* 78xx */ + "011110001mmmnnnn", "sst %M%N", + "011110010aaaaaaa", "sst1 %A", /* 79xx */ + "011110011mmmnnnn", "sst1 %M%N", + "011110100aaaaaaa", "popd %A", /* 7Axx */ + "011110101mmmnnnn", "popd %M%N", + "011110110aaaaaaa", "zalr %A", /* 7Bxx */ + "011110111mmmnnnn", "zalr %M%N", + "011111000aaaaaaa", "spl %A", /* 7Cxx */ + "011111001mmmnnnn", "spl %M%N", + "011111010aaaaaaa", "sph %A", /* 7Dxx */ + "011111011mmmnnnn", "sph %M%N", + "011111100aaaaaaa", "adrk %A", /* 7Exx */ + "011111101mmmnnnn", "adrk %M%N", + "011111110aaaaaaa", "sbrk %A", /* 7Fxx */ + "011111111mmmnnnn", "sbrk %M%N", + "1000pppp0aaaaaaa", "in %A,%P", /* 8xxx */ + "1000pppp1mmmnnnn", "in %M,%P%N", + "1001tttt0aaaaaaa", "bit %A,%T", /* 9xxx */ + "1001tttt1mmmnnnn", "bit %M,%T%N", + "101wwwwwwwwwwwww", "mpyk %W", /* Axxx-Bxxx */ + "11000rrrdddddddd", "lark %R,%D", /* Cxxx */ + "1100100kdddddddd", "ldpk %K%D", /* Cxxx */ +/* "11001010dddddddd", "lack %D", CAxx */ /* LACK has been expanded out to all its variations because one of its */ /* its opcodes is the same as ZAC. Actually, it performs the same function */ - FMT("1100101000000000", "zac"), /* CA00 */ - FMT("1100101000000001", "lack 01h"), /* CAxx */ - FMT("1100101000000010", "lack 02h"), - FMT("1100101000000011", "lack 03h"), - FMT("1100101000000100", "lack 04h"), - FMT("1100101000000101", "lack 05h"), - FMT("1100101000000110", "lack 06h"), - FMT("1100101000000111", "lack 07h"), - FMT("1100101000001000", "lack 08h"), - FMT("1100101000001001", "lack 09h"), - FMT("1100101000001010", "lack 0Ah"), - FMT("1100101000001011", "lack 0Bh"), - FMT("1100101000001100", "lack 0Ch"), - FMT("1100101000001101", "lack 0Dh"), - FMT("1100101000001110", "lack 0Eh"), - FMT("1100101000001111", "lack 0Fh"), - FMT("110010100001tttt", "lack 1%T"), - FMT("110010100010tttt", "lack 2%T"), - FMT("110010100011tttt", "lack 3%T"), - FMT("110010100100tttt", "lack 4%T"), - FMT("110010100101tttt", "lack 5%T"), - FMT("110010100110tttt", "lack 6%T"), - FMT("110010100111tttt", "lack 7%T"), - FMT("110010101000tttt", "lack 8%T"), - FMT("110010101001tttt", "lack 9%T"), - FMT("110010101010tttt", "lack A%T"), - FMT("110010101011tttt", "lack B%T"), - FMT("110010101100tttt", "lack C%T"), - FMT("110010101101tttt", "lack D%T"), - FMT("110010101110tttt", "lack E%T"), - FMT("110010101111tttt", "lack F%T"), + "1100101000000000", "zac", /* CA00 */ + "1100101000000001", "lack 01h", /* CAxx */ + "1100101000000010", "lack 02h", + "1100101000000011", "lack 03h", + "1100101000000100", "lack 04h", + "1100101000000101", "lack 05h", + "1100101000000110", "lack 06h", + "1100101000000111", "lack 07h", + "1100101000001000", "lack 08h", + "1100101000001001", "lack 09h", + "1100101000001010", "lack 0Ah", + "1100101000001011", "lack 0Bh", + "1100101000001100", "lack 0Ch", + "1100101000001101", "lack 0Dh", + "1100101000001110", "lack 0Eh", + "1100101000001111", "lack 0Fh", + "110010100001tttt", "lack 1%T", + "110010100010tttt", "lack 2%T", + "110010100011tttt", "lack 3%T", + "110010100100tttt", "lack 4%T", + "110010100101tttt", "lack 5%T", + "110010100110tttt", "lack 6%T", + "110010100111tttt", "lack 7%T", + "110010101000tttt", "lack 8%T", + "110010101001tttt", "lack 9%T", + "110010101010tttt", "lack A%T", + "110010101011tttt", "lack B%T", + "110010101100tttt", "lack C%T", + "110010101101tttt", "lack D%T", + "110010101110tttt", "lack E%T", + "110010101111tttt", "lack F%T", - FMT("11001011dddddddd", "rptk %D"), /* CBxx */ - FMT("11001100dddddddd", "addk %D"), /* CCxx */ - FMT("11001101dddddddd", "subk %D"), /* CDxx */ - FMT("1100111000000000", "eint"), /* CE00 */ - FMT("1100111000000001", "dint"), /* CE01 */ - FMT("1100111000000010", "rovm"), /* CE02 */ - FMT("1100111000000011", "sovm"), /* CE03 */ - FMT("1100111000000100", "cnfd"), /* CE04 */ - FMT("1100111000000101", "cnfp"), /* CE05 */ - FMT("1100111000000110", "rsxm"), /* CE06 */ - FMT("1100111000000111", "ssxm"), /* CE07 */ - FMT("11001110000010kk", "spm %K"), /* CE0x */ - FMT("1100111000001100", "rxf"), /* CE0C */ - FMT("1100111000001101", "sxf"), /* CE0D */ - FMT("110011100000111k", "fort %K"), /* CE0x */ - FMT("1100111000010100", "pac"), /* CE14 */ - FMT("1100111000010101", "apac"), /* CE15 */ - FMT("1100111000010110", "spac"), /* CE16 */ - FMT("1100111000011000", "sfl"), /* CE18 */ - FMT("1100111000011001", "sfr"), /* CE19 */ - FMT("1100111000011011", "abs"), /* CE1B */ - FMT("1100111000011100", "push"), /* CE1C */ - FMT("1100111000011101", "pop"), /* CE1D */ - FMT("1100111000011110", "trap"), /* CE1E */ - FMT("1100111000011111", "idle"), /* CE1F */ - FMT("1100111000100000", "rtxm"), /* CE20 */ - FMT("1100111000100001", "stxm"), /* CE21 */ - FMT("1100111000100011", "neg"), /* CE23 */ - FMT("1100111000100100", "cala"), /* CE24 */ - FMT("1100111000100101", "bacc"), /* CE25 */ - FMT("1100111000100110", "ret"), /* CE26 */ - FMT("1100111000100111", "cmpl"), /* CE27 */ - FMT("1100111000110000", "rc"), /* CE30 */ - FMT("1100111000110001", "sc"), /* CE31 */ - FMT("1100111000110010", "rtc"), /* CE32 */ - FMT("1100111000110011", "stc"), /* CE33 */ - FMT("1100111000110100", "rol"), /* CE34 */ - FMT("1100111000110101", "ror"), /* CE35 */ - FMT("1100111000110110", "rfsm"), /* CE36 */ - FMT("1100111000110111", "sfsm"), /* CE37 */ - FMT("1100111000111000", "rhm"), /* CE38 */ - FMT("1100111000111001", "shm"), /* CE39 */ - FMT("11001110001111kk", "conf %K"), /* CE3x */ - FMT("11001110010100cc", "cmpr %C"), /* CE5x */ - FMT("110011101mmm0010", "norm %M"), /* CEx2 */ - FMT("110011110aaaaaaa", "mpys %A"), /* CFxx */ - FMT("110011111mmmnnnn", "mpys %M%N"), - FMT("11010rrr00000000wwwwwwwwwwwwwwww", "lrlk %R,%W"), /* Dx00 */ - FMT("1101tttt00000001wwwwwwwwwwwwwwww", "lalk %W,%T"), /* Dx01 */ - FMT("1101tttt00000010wwwwwwwwwwwwwwww", "adlk %W,%T"), /* Dx02 */ - FMT("1101tttt00000011wwwwwwwwwwwwwwww", "sblk %W,%T"), /* Dx03 */ - FMT("1101tttt00000100wwwwwwwwwwwwwwww", "andk %W,%T"), /* Dx04 */ - FMT("1101tttt00000101wwwwwwwwwwwwwwww", "ork %W,%T"), /* Dx05 */ - FMT("1101tttt00000110wwwwwwwwwwwwwwww", "xork %W,%T"), /* Dx06 */ - FMT("1110pppp0aaaaaaa", "out %A,%P"), /* Exxx */ - FMT("1110pppp1mmmnnnn", "out %M,%P%N"), - FMT("111100001mmmnnnnbbbbbbbbbbbbbbbb", "bv %B %M%N"), /* F0xx */ - FMT("111100011mmmnnnnbbbbbbbbbbbbbbbb", "bgz %B %M%N"), /* F1xx */ - FMT("111100101mmmnnnnbbbbbbbbbbbbbbbb", "blez %B %M%N"), /* F2xx */ - FMT("111100111mmmnnnnbbbbbbbbbbbbbbbb", "blz %B %M%N"), /* F3xx */ - FMT("111101001mmmnnnnbbbbbbbbbbbbbbbb", "bgez %B %M%N"), /* F4xx */ - FMT("111101011mmmnnnnbbbbbbbbbbbbbbbb", "bnz %B %M%N"), /* F5xx */ - FMT("111101101mmmnnnnbbbbbbbbbbbbbbbb", "bz %B %M%N"), /* F6xx */ - FMT("111101111mmmnnnnbbbbbbbbbbbbbbbb", "bnv %B %M%N"), /* F7xx */ - FMT("111110001mmmnnnnbbbbbbbbbbbbbbbb", "bbz %B %M%N"), /* F8xx */ - FMT("111110011mmmnnnnbbbbbbbbbbbbbbbb", "bbnz %B %M%N"), /* F9xx */ - FMT("111110101mmmnnnnbbbbbbbbbbbbbbbb", "bioz %B %M%N"), /* FAxx */ - FMT("111110111mmmnnnnbbbbbbbbbbbbbbbb", "banz %B %M%N"), /* FBxx */ - FMT("111111000aaaaaaabbbbbbbbbbbbbbbb", "blkp %B,%A"), /* FCxx */ - FMT("111111001mmmnnnnbbbbbbbbbbbbbbbb", "blkp %B,%M%N"), - FMT("111111010aaaaaaabbbbbbbbbbbbbbbb", "blkd %B,%A"), /* FDxx */ - FMT("111111011mmmnnnnbbbbbbbbbbbbbbbb", "blkd %B,%M%N"), - FMT("111111101mmmnnnnbbbbbbbbbbbbbbbb", "call %B %M%N"), /* FExx */ - FMT("111111111mmmnnnnbbbbbbbbbbbbbbbb", "b %B %M%N"), /* FFxx */ + "11001011dddddddd", "rptk %D", /* CBxx */ + "11001100dddddddd", "addk %D", /* CCxx */ + "11001101dddddddd", "subk %D", /* CDxx */ + "1100111000000000", "eint", /* CE00 */ + "1100111000000001", "dint", /* CE01 */ + "1100111000000010", "rovm", /* CE02 */ + "1100111000000011", "sovm", /* CE03 */ + "1100111000000100", "cnfd", /* CE04 */ + "1100111000000101", "cnfp", /* CE05 */ + "1100111000000110", "rsxm", /* CE06 */ + "1100111000000111", "ssxm", /* CE07 */ + "11001110000010kk", "spm %K", /* CE0x */ + "1100111000001100", "rxf", /* CE0C */ + "1100111000001101", "sxf", /* CE0D */ + "110011100000111k", "fort %K", /* CE0x */ + "1100111000010100", "pac", /* CE14 */ + "1100111000010101", "apac", /* CE15 */ + "1100111000010110", "spac", /* CE16 */ + "1100111000011000", "sfl", /* CE18 */ + "1100111000011001", "sfr", /* CE19 */ + "1100111000011011", "abs", /* CE1B */ + "1100111000011100", "push", /* CE1C */ + "1100111000011101", "pop", /* CE1D */ + "1100111000011110", "trap", /* CE1E */ + "1100111000011111", "idle", /* CE1F */ + "1100111000100000", "rtxm", /* CE20 */ + "1100111000100001", "stxm", /* CE21 */ + "1100111000100011", "neg", /* CE23 */ + "1100111000100100", "cala", /* CE24 */ + "1100111000100101", "bacc", /* CE25 */ + "1100111000100110", "ret", /* CE26 */ + "1100111000100111", "cmpl", /* CE27 */ + "1100111000110000", "rc", /* CE30 */ + "1100111000110001", "sc", /* CE31 */ + "1100111000110010", "rtc", /* CE32 */ + "1100111000110011", "stc", /* CE33 */ + "1100111000110100", "rol", /* CE34 */ + "1100111000110101", "ror", /* CE35 */ + "1100111000110110", "rfsm", /* CE36 */ + "1100111000110111", "sfsm", /* CE37 */ + "1100111000111000", "rhm", /* CE38 */ + "1100111000111001", "shm", /* CE39 */ + "11001110001111kk", "conf %K", /* CE3x */ + "11001110010100cc", "cmpr %C", /* CE5x */ + "110011101mmm0010", "norm %M", /* CEx2 */ + "110011110aaaaaaa", "mpys %A", /* CFxx */ + "110011111mmmnnnn", "mpys %M%N", + "11010rrr00000000wwwwwwwwwwwwwwww", "lrlk %R,%W", /* Dx00 */ + "1101tttt00000001wwwwwwwwwwwwwwww", "lalk %W,%T", /* Dx01 */ + "1101tttt00000010wwwwwwwwwwwwwwww", "adlk %W,%T", /* Dx02 */ + "1101tttt00000011wwwwwwwwwwwwwwww", "sblk %W,%T", /* Dx03 */ + "1101tttt00000100wwwwwwwwwwwwwwww", "andk %W,%T", /* Dx04 */ + "1101tttt00000101wwwwwwwwwwwwwwww", "ork %W,%T", /* Dx05 */ + "1101tttt00000110wwwwwwwwwwwwwwww", "xork %W,%T", /* Dx06 */ + "1110pppp0aaaaaaa", "out %A,%P", /* Exxx */ + "1110pppp1mmmnnnn", "out %M,%P%N", + "111100001mmmnnnnbbbbbbbbbbbbbbbb", "bv %B %M%N", /* F0xx */ + "111100011mmmnnnnbbbbbbbbbbbbbbbb", "bgz %B %M%N", /* F1xx */ + "111100101mmmnnnnbbbbbbbbbbbbbbbb", "blez %B %M%N", /* F2xx */ + "111100111mmmnnnnbbbbbbbbbbbbbbbb", "blz %B %M%N", /* F3xx */ + "111101001mmmnnnnbbbbbbbbbbbbbbbb", "bgez %B %M%N", /* F4xx */ + "111101011mmmnnnnbbbbbbbbbbbbbbbb", "bnz %B %M%N", /* F5xx */ + "111101101mmmnnnnbbbbbbbbbbbbbbbb", "bz %B %M%N", /* F6xx */ + "111101111mmmnnnnbbbbbbbbbbbbbbbb", "bnv %B %M%N", /* F7xx */ + "111110001mmmnnnnbbbbbbbbbbbbbbbb", "bbz %B %M%N", /* F8xx */ + "111110011mmmnnnnbbbbbbbbbbbbbbbb", "bbnz %B %M%N", /* F9xx */ + "111110101mmmnnnnbbbbbbbbbbbbbbbb", "bioz %B %M%N", /* FAxx */ + "111110111mmmnnnnbbbbbbbbbbbbbbbb", "banz %B %M%N", /* FBxx */ + "111111000aaaaaaabbbbbbbbbbbbbbbb", "blkp %B,%A", /* FCxx */ + "111111001mmmnnnnbbbbbbbbbbbbbbbb", "blkp %B,%M%N", + "111111010aaaaaaabbbbbbbbbbbbbbbb", "blkd %B,%A", /* FDxx */ + "111111011mmmnnnnbbbbbbbbbbbbbbbb", "blkd %B,%M%N", + "111111101mmmnnnnbbbbbbbbbbbbbbbb", "call %B %M%N", /* FExx */ + "111111111mmmnnnnbbbbbbbbbbbbbbbb", "b %B %M%N", /* FFxx */ nullptr }; -#define MAX_OPS ((ARRAY_LENGTH(TMS32025Formats) - 1) / PTRS_PER_FORMAT) - -struct TMS32025Opcode { - word mask; /* instruction mask */ - word bits; /* constant bits */ - word extcode; /* value that gets extension code */ - const char *parse; /* how to parse bits */ - const char *fmt; /* instruction format */ -}; - -static TMS32025Opcode Op[MAX_OPS+1]; -static int OpInizialized = 0; - -static void InitDasm32025(void) +tms32025_disassembler::tms32025_disassembler() { const char *p; const char *const *ops; - word mask, bits; + u16 mask, bits; int bit; int i; @@ -374,20 +351,14 @@ static void InitDasm32025(void) ops[0],ops[1],bit); } while (isspace((uint8_t)*p)) p++; - if (*p) Op[i].extcode = *p; - Op[i].bits = bits; - Op[i].mask = mask; - Op[i].fmt = ops[1]; - Op[i].parse = ops[0]; + Op.emplace_back(mask, bits, *p, ops[0], ops[1]); - ops += PTRS_PER_FORMAT; + ops += 2; i++; } - - OpInizialized = 1; } -CPU_DISASSEMBLE(tms32025) +offs_t tms32025_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint32_t flags = 0; int a, b, c, d, k, m, n, p, r, s, t, w; /* these can all be filled in by parsing an instruction */ @@ -399,11 +370,9 @@ CPU_DISASSEMBLE(tms32025) //char *buffertmp; const char *cp; /* character pointer in OpFormats */ - if (!OpInizialized) InitDasm32025(); - op = -1; /* no matching opcode */ - code = (oprom[0] << 8) | oprom[1]; - for ( i = 0; i < MAX_OPS; i++) + code = opcodes.r16(pc); + for ( i = 0; i < int(Op.size()); i++) { if ((code & Op[i].mask) == Op[i].bits) { @@ -418,14 +387,14 @@ CPU_DISASSEMBLE(tms32025) if (op == -1) { util::stream_format(stream, "???? dw %04Xh",code); - return cnt | DASMFLAG_SUPPORTED; + return cnt | SUPPORTED; } //buffertmp = buffer; if (Op[op].extcode) { bit = 31; code <<= 16; - code |= (opram[2] << 8) | opram[3]; + code |= opcodes.r16(pc+1); cnt++; } else @@ -466,9 +435,9 @@ CPU_DISASSEMBLE(tms32025) cp = Op[op].fmt; if (!strncmp(cp, "cal", 3)) - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; else if (!strncmp(cp, "ret", 3)) - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; while (*cp) { @@ -501,5 +470,10 @@ CPU_DISASSEMBLE(tms32025) stream << *cp++; } } - return cnt | flags | DASMFLAG_SUPPORTED; + return cnt | flags | SUPPORTED; +} + +u32 tms32025_disassembler::opcode_alignment() const +{ + return 1; } diff --git a/src/devices/cpu/tms32025/32025dsm.h b/src/devices/cpu/tms32025/32025dsm.h new file mode 100644 index 00000000000..187628b09de --- /dev/null +++ b/src/devices/cpu/tms32025/32025dsm.h @@ -0,0 +1,66 @@ +// license:BSD-3-Clause +// copyright-holders:Tony La Porta, hap + /**************************************************************************\ + * Texas Instruments TMS320x25 DSP Disassembler * + * * + * Copyright Tony La Porta * + * To be used with TMS320x25 DSP Emulator engine. * + * Written for the MAME project. * + * * + * Many thanks to those involved in the i8039 Disassembler * + * as the structure here was borrowed from it. * + * * + * Note : This is a word based microcontroller, with addressing * + * architecture based on the Harvard addressing scheme. * + * * + * * + * A Memory Address * + * B Opcode Address Argument (Requires next opcode read) * + * C Compare mode * + * D Immediate byte load * + * K Immediate bit load * + * W Immediate word load * + * M AR[x] register modification type (for indirect addressing) * + * N ARP register to change ARP pointer to (for indirect addressing) * + * P I/O port address number * + * R AR[R] register to use * + * S Shift ALU left * + * T Shift ALU left (Hex) / Nibble data * + * X Don't care bit * + * * + \**************************************************************************/ + +#ifndef MAME_CPU_TMS32025_32025DSM_H +#define MAME_CPU_TMS32025_32025DSM_H + +#pragma once + +class tms32025_disassembler : public util::disasm_interface +{ +public: + tms32025_disassembler(); + virtual ~tms32025_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + struct TMS32025Opcode { + u16 mask; /* instruction mask */ + u16 bits; /* constant bits */ + u16 extcode; /* value that gets extension code */ + const char *parse; /* how to parse bits */ + const char *fmt; /* instruction format */ + + TMS32025Opcode(u16 m, u16 b, u16 e, const char *p, const char *f) : mask(m), bits(b), extcode(e), parse(p), fmt(f) {} + }; + + static const char *const arith[8]; + static const char *const nextar[16]; + static const char *const cmpmode[4]; + static const char *const TMS32025Formats[]; + + std::vector<TMS32025Opcode> Op; +}; + +#endif diff --git a/src/devices/cpu/tms32025/dis32025.cpp b/src/devices/cpu/tms32025/dis32025.cpp deleted file mode 100644 index 6df4b92707a..00000000000 --- a/src/devices/cpu/tms32025/dis32025.cpp +++ /dev/null @@ -1,137 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Tony La Porta, hap - /**************************************************************************\ - * Texas Instruments TMS320x25 DSP Disassembler * - * * - * Copyright Tony La Porta * - * Written for the MAME project. * - * * - * Notes : Data is expected to be read from source file as MSB first. * - * This is a word based microcontroller, with addressing * - * architecture based on the Harvard addressing scheme. * - * * - \**************************************************************************/ - -#include <stdio.h> -#include <string.h> - -#include "32025dsm.c" - - -unsigned char *Buffer; - - -int main(int argc,char *argv[]) -{ - int length=0, length_to_dump=0, offset=0, disasm_words=0; - int filelength=0, bytes_read; - int Counter=0; - - FILE *F; - char *String_Output; - - if(argc<2) - { - printf("\n"); - printf("TMS32025 Disassembler 1.1 by Tony La Porta (C)2001-2002+\n\n"); - printf("Usage: dis32025 <input-file> [ <start-addr> [ <num-of-addr> ] ]\n"); - printf(" <input-file> source file data must be MSB first\n"); - printf(" <start-addr> starting address to disassemble from (decimal)\n"); - printf(" <num-of-addr> number of addresses to disassemble (decimal)\n"); - printf(" Precede values with 0x if HEX values preffered\n"); - exit(1); - } - - if(!(F=fopen(argv[1],"rb"))) - { - printf("\n%s: Can't open file %s\n",argv[0],argv[1]); - exit(2); - } - argv++; argc--; - if (argv[1]) - { - offset = strtol(argv[1],nullptr,0); - argv++; argc--; - } - if (argv[1]) - { - length = strtol(argv[1],nullptr,0); - argv++; argc--; - } - - fseek(F,0, SEEK_END); - filelength = ftell(F); - - length *= 2; - - if ((length > (filelength - (offset*2))) || (length == 0)) length = filelength - (offset*2); - printf("Length=%04Xh(words) Offset=$%04Xh filelength=%04Xh(words) %04Xh(bytes)\n",length/2,offset,filelength/2,filelength); - length_to_dump = length; - printf("Starting from %d, dumping %d opcodes (word size)\n",offset,length/2); - Buffer = calloc((filelength+1),sizeof(char)); - if (Buffer==nullptr) - { - printf("Out of Memory !!!"); - fclose(F); - exit(3); - } - String_Output = calloc(80,sizeof(char)); - if (String_Output==nullptr) - { - printf("Out of Memory !!!"); - free(Buffer); - fclose(F); - exit(4); - } - - if (fseek(F,0,SEEK_SET) != 0) - { - printf("Error seeking to beginning of file\n"); - free(String_Output); - free(Buffer); - fclose(F); - exit(5); - } - - Counter = offset; - bytes_read = fread(Buffer,sizeof(char),filelength,F); - if (bytes_read >= length) - { - for (; length > 0; length -= (disasm_words*2)) - { - int ii; - disasm_words = Dasm32025(String_Output,Counter); - printf("$%04lX: ",Counter); - for (ii = 0; ii < disasm_words; ii++) - { - if (((Counter*2) + ii) > filelength) /* Past end of length to dump ? */ - { - sprintf(String_Output,"???? dw %02.2X%02.2Xh (Past end of disassembly !)",Buffer[((Counter-1)*2)],Buffer[((Counter-1)*2)+1]); - } - else - { - printf("%02.2x%02.2x ",Buffer[(Counter*2)],Buffer[(Counter*2) + 1]); - } - Counter++ ; - } - for (; ii < 4; ii++) - { - printf(" "); - } - printf("\t%s\n",String_Output); - } - } - else - { - printf("ERROR length to dump was %d ", length_to_dump/2); - printf(", but bytes read from file were %d\n", bytes_read/2); - free(String_Output); - free(Buffer); - fclose(F); - exit(7); - } - free(String_Output); - free(Buffer); - fclose(F); - return(0); -} diff --git a/src/devices/cpu/tms32025/tms32025.cpp b/src/devices/cpu/tms32025/tms32025.cpp index a9405d72f3d..74529d79894 100644 --- a/src/devices/cpu/tms32025/tms32025.cpp +++ b/src/devices/cpu/tms32025/tms32025.cpp @@ -120,6 +120,7 @@ Table 3-2. TMS32025/26 Memory Blocks #include "emu.h" #include "tms32025.h" +#include "32025dsm.h" #include "debugger.h" @@ -253,11 +254,9 @@ device_memory_interface::space_config_vector tms32025_device::memory_space_confi }; } - -offs_t tms32025_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *tms32025_device::create_disassembler() { - extern CPU_DISASSEMBLE( tms32025 ); - return CPU_DISASSEMBLE_NAME(tms32025)(this, stream, pc, oprom, opram, options); + return new tms32025_disassembler; } READ16_MEMBER( tms32025_device::drr_r) @@ -514,7 +513,7 @@ void tms32025_device::GETDATA(int shift,int signext) m_external_mem_access = 0; } - m_ALU.d = (uint16_t)m_data->read_word(m_memaccess << 1); + m_ALU.d = (uint16_t)m_data->read_word(m_memaccess); if (signext) m_ALU.d = (int16_t)m_ALU.d; m_ALU.d <<= shift; @@ -528,14 +527,14 @@ void tms32025_device::PUTDATA(uint16_t data) if (m_memaccess >= 0x800) m_external_mem_access = 1; /* Pause if hold pin is active */ else m_external_mem_access = 0; - m_data->write_word(IND << 1, data); + m_data->write_word(IND, data); MODIFY_AR_ARP(); } else { if (m_memaccess >= 0x800) m_external_mem_access = 1; /* Pause if hold pin is active */ else m_external_mem_access = 0; - m_data->write_word(DMA << 1, data); + m_data->write_word(DMA, data); } } void tms32025_device::PUTDATA_SST(uint16_t data) @@ -550,7 +549,7 @@ void tms32025_device::PUTDATA_SST(uint16_t data) m_opcode.b.l &= 0xf7; /* Stop ARP changes */ MODIFY_AR_ARP(); } - m_data->write_word(m_memaccess << 1, data); + m_data->write_word(m_memaccess, data); } @@ -638,8 +637,8 @@ void tms32025_device::addt() void tms32025_device::adlk() { m_oldacc.d = m_ACC.d; - if (SXM) m_ALU.d = (int16_t)m_direct->read_word(m_PC << 1); - else m_ALU.d = (uint16_t)m_direct->read_word(m_PC << 1); + if (SXM) m_ALU.d = (int16_t)m_direct->read_word(m_PC); + else m_ALU.d = (uint16_t)m_direct->read_word(m_PC); m_PC++; m_ALU.d <<= (m_opcode.b.h & 0xf); m_ACC.d += m_ALU.d; @@ -658,7 +657,7 @@ void tms32025_device::and_() void tms32025_device::andk() { m_oldacc.d = m_ACC.d; - m_ALU.d = (uint16_t)m_direct->read_word(m_PC << 1); + m_ALU.d = (uint16_t)m_direct->read_word(m_PC); m_PC++; m_ALU.d <<= (m_opcode.b.h & 0xf); m_ACC.d &= m_ALU.d; @@ -673,7 +672,7 @@ void tms32025_device::apac() } void tms32025_device::br() { - m_PC = m_direct->read_word(m_PC << 1); + m_PC = m_direct->read_word(m_PC); MODIFY_AR_ARP(); } void tms32025_device::bacc() @@ -682,43 +681,43 @@ void tms32025_device::bacc() } void tms32025_device::banz() { - if (m_AR[ARP]) m_PC = m_direct->read_word(m_PC << 1); + if (m_AR[ARP]) m_PC = m_direct->read_word(m_PC); else m_PC++ ; MODIFY_AR_ARP(); } void tms32025_device::bbnz() { - if (TC) m_PC = m_direct->read_word(m_PC << 1); + if (TC) m_PC = m_direct->read_word(m_PC); else m_PC++ ; MODIFY_AR_ARP(); } void tms32025_device::bbz() { - if (TC == 0) m_PC = m_direct->read_word(m_PC << 1); + if (TC == 0) m_PC = m_direct->read_word(m_PC); else m_PC++ ; MODIFY_AR_ARP(); } void tms32025_device::bc() { - if (CARRY) m_PC = m_direct->read_word(m_PC << 1); + if (CARRY) m_PC = m_direct->read_word(m_PC); else m_PC++ ; MODIFY_AR_ARP(); } void tms32025_device::bgez() { - if ( (int32_t)(m_ACC.d) >= 0 ) m_PC = m_direct->read_word(m_PC << 1); + if ( (int32_t)(m_ACC.d) >= 0 ) m_PC = m_direct->read_word(m_PC); else m_PC++ ; MODIFY_AR_ARP(); } void tms32025_device::bgz() { - if ( (int32_t)(m_ACC.d) > 0 ) m_PC = m_direct->read_word(m_PC << 1); + if ( (int32_t)(m_ACC.d) > 0 ) m_PC = m_direct->read_word(m_PC); else m_PC++ ; MODIFY_AR_ARP(); } void tms32025_device::bioz() { - if (m_bio_in() != CLEAR_LINE) m_PC = m_direct->read_word(m_PC << 1); + if (m_bio_in() != CLEAR_LINE) m_PC = m_direct->read_word(m_PC); else m_PC++ ; MODIFY_AR_ARP(); } @@ -736,17 +735,17 @@ void tms32025_device::bitt() } void tms32025_device::blez() { - if ( (int32_t)(m_ACC.d) <= 0 ) m_PC = m_direct->read_word(m_PC << 1); + if ( (int32_t)(m_ACC.d) <= 0 ) m_PC = m_direct->read_word(m_PC); else m_PC++ ; MODIFY_AR_ARP(); } void tms32025_device::blkd() { /** Fix cycle timing **/ if (m_init_load_addr) { - m_PFC = m_direct->read_word(m_PC << 1); + m_PFC = m_direct->read_word(m_PC); m_PC++; } - m_ALU.d = m_data->read_word(m_PFC << 1); + m_ALU.d = m_data->read_word(m_PFC); PUTDATA(m_ALU.d); m_PFC++; m_tms32025_dec_cycles += (1*CLK); @@ -754,29 +753,29 @@ void tms32025_device::blkd() void tms32025_device::blkp() { /** Fix cycle timing **/ if (m_init_load_addr) { - m_PFC = m_direct->read_word(m_PC << 1); + m_PFC = m_direct->read_word(m_PC); m_PC++; } - m_ALU.d = m_direct->read_word(m_PFC << 1); + m_ALU.d = m_direct->read_word(m_PFC); PUTDATA(m_ALU.d); m_PFC++; m_tms32025_dec_cycles += (2*CLK); } void tms32025_device::blz() { - if ( (int32_t)(m_ACC.d) < 0 ) m_PC = m_direct->read_word(m_PC << 1); + if ( (int32_t)(m_ACC.d) < 0 ) m_PC = m_direct->read_word(m_PC); else m_PC++ ; MODIFY_AR_ARP(); } void tms32025_device::bnc() { - if (CARRY == 0) m_PC = m_direct->read_word(m_PC << 1); + if (CARRY == 0) m_PC = m_direct->read_word(m_PC); else m_PC++ ; MODIFY_AR_ARP(); } void tms32025_device::bnv() { - if (OV == 0) m_PC = m_direct->read_word(m_PC << 1); + if (OV == 0) m_PC = m_direct->read_word(m_PC); else { m_PC++ ; CLR0(OV_FLAG); @@ -785,14 +784,14 @@ void tms32025_device::bnv() } void tms32025_device::bnz() { - if (m_ACC.d != 0) m_PC = m_direct->read_word(m_PC << 1); + if (m_ACC.d != 0) m_PC = m_direct->read_word(m_PC); else m_PC++ ; MODIFY_AR_ARP(); } void tms32025_device::bv() { if (OV) { - m_PC = m_direct->read_word(m_PC << 1); + m_PC = m_direct->read_word(m_PC); CLR0(OV_FLAG); } else m_PC++ ; @@ -800,7 +799,7 @@ void tms32025_device::bv() } void tms32025_device::bz() { - if (m_ACC.d == 0) m_PC = m_direct->read_word(m_PC << 1); + if (m_ACC.d == 0) m_PC = m_direct->read_word(m_PC); else m_PC++ ; MODIFY_AR_ARP(); } @@ -813,7 +812,7 @@ void tms32025_device::call() { m_PC++ ; PUSH_STACK(m_PC); - m_PC = m_direct->read_word((m_PC - 1) << 1); + m_PC = m_direct->read_word(m_PC - 1); MODIFY_AR_ARP(); } void tms32025_device::cmpl() @@ -916,7 +915,7 @@ void tms32025_device::dint() void tms32025_device::dmov() /** Careful with how memory is configured !! */ { GETDATA(0, 0); - m_data->write_word((m_memaccess + 1) << 1, m_ALU.w.l); + m_data->write_word(m_memaccess + 1, m_ALU.w.l); } void tms32025_device::eint() { @@ -934,7 +933,7 @@ void tms32025_device::idle() } void tms32025_device::in() { - m_ALU.w.l = m_io->read_word( (m_opcode.b.h & 0xf) << 1 ); + m_ALU.w.l = m_io->read_word(m_opcode.b.h & 0xf); PUTDATA(m_ALU.w.l); } void tms32025_device::lac() @@ -953,8 +952,8 @@ void tms32025_device::lact() } void tms32025_device::lalk() { - if (SXM) m_ALU.d = (int16_t)m_direct->read_word(m_PC << 1); - else m_ALU.d = (uint16_t)m_direct->read_word(m_PC << 1); + if (SXM) m_ALU.d = (int16_t)m_direct->read_word(m_PC); + else m_ALU.d = (uint16_t)m_direct->read_word(m_PC); m_PC++; m_ALU.d <<= (m_opcode.b.h & 0xf); m_ACC.d = m_ALU.d; @@ -991,7 +990,7 @@ void tms32025_device::lph() } void tms32025_device::lrlk() { - m_ALU.d = (uint16_t)m_direct->read_word(m_PC << 1); + m_ALU.d = (uint16_t)m_direct->read_word(m_PC); m_PC++; m_AR[m_opcode.b.h & 7] = m_ALU.w.l; } @@ -1036,7 +1035,7 @@ void tms32025_device::ltd() /** Careful with how memory is configured !! */ m_oldacc.d = m_ACC.d; GETDATA(0, 0); m_Treg = m_ALU.w.l; - m_data->write_word((m_memaccess+1) << 1, m_ALU.w.l); + m_data->write_word(m_memaccess+1, m_ALU.w.l); SHIFT_Preg_TO_ALU(); m_ACC.d += m_ALU.d; CALCULATE_ADD_OVERFLOW(m_ALU.d); @@ -1064,7 +1063,7 @@ void tms32025_device::mac() /** RAM blocks B0,B1,B2 may be important ! { /** Fix cycle timing **/ m_oldacc.d = m_ACC.d; if (m_init_load_addr) { - m_PFC = m_direct->read_word(m_PC << 1); + m_PFC = m_direct->read_word(m_PC); m_PC++; } SHIFT_Preg_TO_ALU(); @@ -1073,7 +1072,7 @@ void tms32025_device::mac() /** RAM blocks B0,B1,B2 may be important ! CALCULATE_ADD_CARRY(); GETDATA(0, 0); m_Treg = m_ALU.w.l; - m_Preg.d = ( (int16_t)m_ALU.w.l * (int16_t)m_direct->read_word(m_PFC << 1) ); + m_Preg.d = ( (int16_t)m_ALU.w.l * (int16_t)m_direct->read_word(m_PFC) ); m_PFC++; m_tms32025_dec_cycles += (2*CLK); } @@ -1081,7 +1080,7 @@ void tms32025_device::macd() /** RAM blocks B0,B1,B2 may be important ! { /** Fix cycle timing **/ m_oldacc.d = m_ACC.d; if (m_init_load_addr) { - m_PFC = m_direct->read_word(m_PC << 1); + m_PFC = m_direct->read_word(m_PC); m_PC++; } SHIFT_Preg_TO_ALU(); @@ -1090,10 +1089,10 @@ void tms32025_device::macd() /** RAM blocks B0,B1,B2 may be important ! CALCULATE_ADD_CARRY(); GETDATA(0, 0); if ( (m_opcode.b.l & 0x80) || m_init_load_addr ) { /* No writing during repetition, or DMA mode */ - m_data->write_word((m_memaccess+1) << 1, m_ALU.w.l); + m_data->write_word(m_memaccess+1, m_ALU.w.l); } m_Treg = m_ALU.w.l; - m_Preg.d = ( (int16_t)m_ALU.w.l * (int16_t)m_direct->read_word(m_PFC << 1) ); + m_Preg.d = ( (int16_t)m_ALU.w.l * (int16_t)m_direct->read_word(m_PFC) ); m_PFC++; m_tms32025_dec_cycles += (2*CLK); } @@ -1166,7 +1165,7 @@ void tms32025_device::or_() } void tms32025_device::ork() { - m_ALU.d = (uint16_t)m_direct->read_word(m_PC << 1); + m_ALU.d = (uint16_t)m_direct->read_word(m_PC); m_PC++; m_ALU.d <<= (m_opcode.b.h & 0xf); m_ACC.d |= (m_ALU.d); @@ -1174,7 +1173,7 @@ void tms32025_device::ork() void tms32025_device::out() { GETDATA(0, 0); - m_io->write_word( (m_opcode.b.h & 0xf) << 1, m_ALU.w.l ); + m_io->write_word(m_opcode.b.h & 0xf, m_ALU.w.l ); } void tms32025_device::pac() { @@ -1285,8 +1284,8 @@ void tms32025_device::sar_ar7() { PUTDATA(m_AR[7]); } void tms32025_device::sblk() { m_oldacc.d = m_ACC.d; - if (SXM) m_ALU.d = (int16_t)m_direct->read_word(m_PC << 1); - else m_ALU.d = (uint16_t)m_direct->read_word(m_PC << 1); + if (SXM) m_ALU.d = (int16_t)m_direct->read_word(m_PC); + else m_ALU.d = (uint16_t)m_direct->read_word(m_PC); m_PC++; m_ALU.d <<= (m_opcode.b.h & 0xf); m_ACC.d -= m_ALU.d; @@ -1477,7 +1476,7 @@ void tms32025_device::tblr() if (m_init_load_addr) { m_PFC = m_ACC.w.l; } - m_ALU.w.l = m_direct->read_word(m_PFC << 1); + m_ALU.w.l = m_direct->read_word(m_PFC); if ( (CNF0) && ( (uint16_t)(m_PFC) >= 0xff00 ) ) {} /** TMS32025 only */ else m_tms32025_dec_cycles += (1*CLK); PUTDATA(m_ALU.w.l); @@ -1491,7 +1490,7 @@ void tms32025_device::tblw() m_tms32025_dec_cycles += (1*CLK); GETDATA(0, 0); if (m_external_mem_access) m_tms32025_dec_cycles += (1*CLK); - m_program->write_word(m_PFC << 1, m_ALU.w.l); + m_program->write_word(m_PFC, m_ALU.w.l); m_PFC++; } void tms32025_device::trap() @@ -1506,7 +1505,7 @@ void tms32025_device::xor_() } void tms32025_device::xork() { - m_ALU.d = m_direct->read_word(m_PC << 1); + m_ALU.d = m_direct->read_word(m_PC); m_PC++; m_ALU.d <<= (m_opcode.b.h & 0xf); m_ACC.d ^= m_ALU.d; @@ -1620,7 +1619,7 @@ const tms32025_device::tms32025_opcode tms32025_device::s_opcode_Dx_subset[8]= void tms32025_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<-1>(); m_data = &space(AS_DATA); m_io = &space(AS_IO); @@ -1968,7 +1967,7 @@ void tms32025_device::execute_run() debugger_instruction_hook(this, m_PC); - m_opcode.d = m_direct->read_word(m_PC << 1); + m_opcode.d = m_direct->read_word(m_PC); m_PC++; if (m_opcode.b.h == 0xCE) /* Opcode 0xCExx has many sub-opcodes in its minor byte */ @@ -2002,7 +2001,7 @@ void tms32025_device::execute_run() debugger_instruction_hook(this, m_PC); - m_opcode.d = m_direct->read_word(m_PC << 1); + m_opcode.d = m_direct->read_word(m_PC); m_PC++; m_tms32025_dec_cycles += (1*CLK); diff --git a/src/devices/cpu/tms32025/tms32025.h b/src/devices/cpu/tms32025/tms32025.h index a9ae17576c4..66c76bc001b 100644 --- a/src/devices/cpu/tms32025/tms32025.h +++ b/src/devices/cpu/tms32025/tms32025.h @@ -125,9 +125,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 4; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; void common_reset(); @@ -141,7 +139,7 @@ protected: optional_shared_ptr<uint16_t> m_b3; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<-1> *m_direct; address_space *m_data; address_space *m_io; @@ -204,10 +202,6 @@ protected: inline void MODIFY_DP(int data); inline void MODIFY_PM(int data); inline void MODIFY_ARP(int data); - inline uint16_t M_RDROM(offs_t addr); - inline void M_WRTROM(offs_t addr, uint16_t data); - inline uint16_t M_RDRAM(offs_t addr); - inline void M_WRTRAM(offs_t addr, uint16_t data); uint16_t reverse_carry_add(uint16_t arg0, uint16_t arg1 ); inline void MODIFY_AR_ARP(); inline void CALCULATE_ADD_CARRY(); diff --git a/src/devices/cpu/tms32031/dis32031.cpp b/src/devices/cpu/tms32031/dis32031.cpp index b6012827611..6bb468e164a 100644 --- a/src/devices/cpu/tms32031/dis32031.cpp +++ b/src/devices/cpu/tms32031/dis32031.cpp @@ -9,40 +9,13 @@ ***************************************************************************/ #include "emu.h" -#include "tms32031.h" - - -/*************************************************************************** - MEMORY ACCESSORS -***************************************************************************/ - -#define INTEGER 0 -#define FLOAT 1 -#define NODEST 2 -#define NOSOURCE 4 -#define NOSOURCE1 NOSOURCE -#define NOSOURCE2 8 -#define SWAPSRCDST 16 -#define UNSIGNED 32 - +#include "dis32031.h" /*************************************************************************** CODE CODE ***************************************************************************/ -#if 0 -static inline char *signed_16bit(int16_t val) -{ - static char temp[10]; - if (val < 0) - sprintf(temp, "-$%x", -val & 0xffff); - else - sprintf(temp, "$%x", val); - return temp; -} -#endif - -static const char *const regname[32] = +const char *const tms32031_disassembler::regname[32] = { "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "AR0", "AR1", "AR2", "AR3", "AR4", "AR5", "AR6", "AR7", @@ -50,7 +23,7 @@ static const char *const regname[32] = "IOF", "RS", "RE", "RC", "??", "??", "??", "??" }; -static const char *const condition[32] = +const char *const tms32031_disassembler::condition[32] = { "U", "LO", "LS", "HI", "HS", "EQ", "NE", "LT", "LE", "GT", "GE", "??", "NV", "V", "NUF", "UF", @@ -122,7 +95,7 @@ static const char *const condition[32] = // 19 = LUF (LUF) // 20 = ZUF (Z | UF) -static void append_indirect(uint8_t ma, int8_t disp, std::ostream &stream) +void tms32031_disassembler::append_indirect(uint8_t ma, int8_t disp, std::ostream &stream) { std::string dispstr; int mode = (ma >> 3) & 0x1f; @@ -172,14 +145,14 @@ static void append_indirect(uint8_t ma, int8_t disp, std::ostream &stream) } } -static std::string get_indirect(uint8_t ma, int8_t disp) +std::string tms32031_disassembler::get_indirect(uint8_t ma, int8_t disp) { std::ostringstream stream; append_indirect(ma, disp, stream); return stream.str(); } -static void append_immediate(uint16_t data, int is_float, int is_unsigned, std::ostream &stream) +void tms32031_disassembler::append_immediate(uint16_t data, int is_float, int is_unsigned, std::ostream &stream) { if (is_float) { @@ -203,7 +176,7 @@ static void append_immediate(uint16_t data, int is_float, int is_unsigned, std:: util::stream_format(stream, "$%04X", data); } -static void disasm_general(const char *opstring, uint32_t op, int flags, std::ostream &stream) +void tms32031_disassembler::disasm_general(const char *opstring, uint32_t op, int flags, std::ostream &stream) { util::stream_format(stream, "%-6s", opstring); @@ -244,7 +217,7 @@ static void disasm_general(const char *opstring, uint32_t op, int flags, std::os } } -static void disasm_3op(const char *opstring, uint32_t op, int flags, std::ostream &stream) +void tms32031_disassembler::disasm_3op(const char *opstring, uint32_t op, int flags, std::ostream &stream) { util::stream_format(stream, "%-6s", opstring); @@ -289,7 +262,7 @@ static void disasm_3op(const char *opstring, uint32_t op, int flags, std::ostrea } } -static void disasm_conditional(const char *opstring, uint32_t op, int flags, std::ostream &stream) +void tms32031_disassembler::disasm_conditional(const char *opstring, uint32_t op, int flags, std::ostream &stream) { char temp[10]; sprintf(temp, "%s%s", opstring, condition[(op >> 23) & 31]); @@ -297,7 +270,7 @@ static void disasm_conditional(const char *opstring, uint32_t op, int flags, std } -static void disasm_parallel_3op3op(const char *opstring1, const char *opstring2, uint32_t op, int flags, const uint8_t *srctable, std::ostream &stream) +void tms32031_disassembler::disasm_parallel_3op3op(const char *opstring1, const char *opstring2, uint32_t op, int flags, const uint8_t *srctable, std::ostream &stream) { const uint8_t *s = &srctable[((op >> 24) & 3) * 4]; int d1 = (op >> 23) & 1; @@ -315,7 +288,7 @@ static void disasm_parallel_3op3op(const char *opstring1, const char *opstring2, } -static void disasm_parallel_3opstore(const char *opstring1, const char *opstring2, uint32_t op, int flags, std::ostream &stream) +void tms32031_disassembler::disasm_parallel_3opstore(const char *opstring1, const char *opstring2, uint32_t op, int flags, std::ostream &stream) { int d1 = (op >> 22) & 7; int s1 = (op >> 19) & 7; @@ -335,7 +308,7 @@ static void disasm_parallel_3opstore(const char *opstring1, const char *opstring } -static void disasm_parallel_loadload(const char *opstring1, const char *opstring2, uint32_t op, int flags, std::ostream &stream) +void tms32031_disassembler::disasm_parallel_loadload(const char *opstring1, const char *opstring2, uint32_t op, int flags, std::ostream &stream) { int d2 = (op >> 22) & 7; int d1 = (op >> 19) & 7; @@ -349,7 +322,7 @@ static void disasm_parallel_loadload(const char *opstring1, const char *opstring } -static void disasm_parallel_storestore(const char *opstring1, const char *opstring2, uint32_t op, int flags, std::ostream &stream) +void tms32031_disassembler::disasm_parallel_storestore(const char *opstring1, const char *opstring2, uint32_t op, int flags, std::ostream &stream) { int s2 = (op >> 22) & 7; int s1 = (op >> 16) & 7; @@ -364,9 +337,10 @@ static void disasm_parallel_storestore(const char *opstring1, const char *opstri -static unsigned dasm_tms3203x(std::ostream &stream, unsigned pc, uint32_t op) +offs_t tms32031_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint32_t flags = 0; + uint32_t op = opcodes.r32(pc); switch (op >> 23) { @@ -485,7 +459,7 @@ static unsigned dasm_tms3203x(std::ostream &stream, unsigned pc, uint32_t op) case 0x0c4: case 0x0c5: util::stream_format(stream, "CALL $%06X", op & 0xffffff); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; @@ -537,7 +511,7 @@ static unsigned dasm_tms3203x(std::ostream &stream, unsigned pc, uint32_t op) char temp[10]; sprintf(temp, "CALL%s", condition[(op >> 16) & 31]); util::stream_format(stream, "%-6s%s", temp, regname[op & 31]); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; } @@ -546,7 +520,7 @@ static unsigned dasm_tms3203x(std::ostream &stream, unsigned pc, uint32_t op) char temp[10]; sprintf(temp, "CALL%s", condition[(op >> 16) & 31]); util::stream_format(stream, "%-6s$%06X", temp, (pc + 1 + (int16_t)op) & 0xffffff); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; } @@ -556,19 +530,19 @@ static unsigned dasm_tms3203x(std::ostream &stream, unsigned pc, uint32_t op) char temp[10]; sprintf(temp, "TRAP%s", condition[(op >> 16) & 31]); util::stream_format(stream, "%-6s$%02X", temp, op & 31); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; } case 0x0f0: util::stream_format(stream, "RETI%s", condition[(op >> 16) & 31]); - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; case 0x0f1: util::stream_format(stream, "RETS%s", condition[(op >> 16) & 31]); - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; @@ -720,12 +694,11 @@ static unsigned dasm_tms3203x(std::ostream &stream, unsigned pc, uint32_t op) break; } - return 1 | flags | DASMFLAG_SUPPORTED; + return 1 | flags | SUPPORTED; } - -CPU_DISASSEMBLE( tms3203x ) +u32 tms32031_disassembler::opcode_alignment() const { - uint32_t op = oprom[0] | (oprom[1] << 8) | (oprom[2] << 16) | (oprom[3] << 24); - return dasm_tms3203x(stream, pc, op); + return 1; } + diff --git a/src/devices/cpu/tms32031/dis32031.h b/src/devices/cpu/tms32031/dis32031.h new file mode 100644 index 00000000000..b6e03e4f31a --- /dev/null +++ b/src/devices/cpu/tms32031/dis32031.h @@ -0,0 +1,51 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +/*************************************************************************** + + dis32031.c + Disassembler for the portable TMS32C031 emulator. + Written by Aaron Giles + +***************************************************************************/ + +#ifndef MAME_CPU_TMS32031_DIS32031_H +#define MAME_CPU_TMS32031_DIS32031_H + +#pragma once + +class tms32031_disassembler : public util::disasm_interface +{ +public: + tms32031_disassembler() = default; + virtual ~tms32031_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum { + INTEGER = 0, + FLOAT = 1, + NODEST = 2, + NOSOURCE = 4, + NOSOURCE1 = NOSOURCE, + NOSOURCE2 = 8, + SWAPSRCDST = 16, + UNSIGNED = 32 + }; + + static const char *const regname[32]; + static const char *const condition[32]; + void append_indirect(uint8_t ma, int8_t disp, std::ostream &stream); + std::string get_indirect(uint8_t ma, int8_t disp); + void append_immediate(uint16_t data, int is_float, int is_unsigned, std::ostream &stream); + void disasm_general(const char *opstring, uint32_t op, int flags, std::ostream &stream); + void disasm_3op(const char *opstring, uint32_t op, int flags, std::ostream &stream); + void disasm_conditional(const char *opstring, uint32_t op, int flags, std::ostream &stream); + void disasm_parallel_3op3op(const char *opstring1, const char *opstring2, uint32_t op, int flags, const uint8_t *srctable, std::ostream &stream); + void disasm_parallel_3opstore(const char *opstring1, const char *opstring2, uint32_t op, int flags, std::ostream &stream); + void disasm_parallel_loadload(const char *opstring1, const char *opstring2, uint32_t op, int flags, std::ostream &stream); + void disasm_parallel_storestore(const char *opstring1, const char *opstring2, uint32_t op, int flags, std::ostream &stream); +}; + +#endif diff --git a/src/devices/cpu/tms32031/tms32031.cpp b/src/devices/cpu/tms32031/tms32031.cpp index a924791cb71..6f75d3a82cb 100644 --- a/src/devices/cpu/tms32031/tms32031.cpp +++ b/src/devices/cpu/tms32031/tms32031.cpp @@ -10,6 +10,7 @@ #include "emu.h" #include "tms32031.h" +#include "dis32031.h" #include "debugger.h" @@ -328,7 +329,7 @@ inline uint32_t tms3203x_device::ROPCODE(offs_t pc) if (m_mcbl_mode && pc < 0x1000) return m_bootrom[pc]; - return m_direct->read_dword(pc << 2); + return m_direct->read_dword(pc); } @@ -341,7 +342,7 @@ inline uint32_t tms3203x_device::RMEM(offs_t addr) if (m_mcbl_mode && addr < 0x1000) return m_bootrom[addr]; - return m_program->read_dword(addr << 2); + return m_program->read_dword(addr); } @@ -351,7 +352,7 @@ inline uint32_t tms3203x_device::RMEM(offs_t addr) inline void tms3203x_device::WMEM(offs_t addr, uint32_t data) { - m_program->write_dword(addr << 2, data); + m_program->write_dword(addr, data); } @@ -363,7 +364,7 @@ void tms3203x_device::device_start() { // find address spaces m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<-2>(); // resolve devcb handlers m_xf0_cb.resolve_safe(); @@ -553,36 +554,13 @@ void tms3203x_device::state_string_export(const device_state_entry &entry, std:: //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t tms3203x_device::disasm_min_opcode_bytes() const -{ - return 4; -} - - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t tms3203x_device::disasm_max_opcode_bytes() const -{ - return 4; -} - - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t tms3203x_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *tms3203x_device::create_disassembler() { - extern CPU_DISASSEMBLE( tms3203x ); - return CPU_DISASSEMBLE_NAME(tms3203x)(this, stream, pc, oprom, opram, options); + return new tms32031_disassembler; } diff --git a/src/devices/cpu/tms32031/tms32031.h b/src/devices/cpu/tms32031/tms32031.h index e654d4f2f5e..14ac97cd6d0 100644 --- a/src/devices/cpu/tms32031/tms32031.h +++ b/src/devices/cpu/tms32031/tms32031.h @@ -182,9 +182,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // memory helpers uint32_t ROPCODE(offs_t pc); @@ -766,7 +764,7 @@ protected: uint32_t m_iotemp; address_space * m_program; - direct_read_data * m_direct; + direct_read_data<-2> *m_direct; uint32_t * m_bootrom; bool m_mcbl_mode; diff --git a/src/devices/cpu/tms32051/dis32051.cpp b/src/devices/cpu/tms32051/dis32051.cpp index b963781beeb..d634ebd37c4 100644 --- a/src/devices/cpu/tms32051/dis32051.cpp +++ b/src/devices/cpu/tms32051/dis32051.cpp @@ -1,10 +1,11 @@ // license:BSD-3-Clause // copyright-holders:Ville Linde -#include "emu.h" +#include "emu.h" +#include "dis32051.h" -static const char *const zl_condition_codes[] = +const char *const tms32051_disassembler::zl_condition_codes[] = { // bit 3, 2 (ZL), bit 1, 0 (MASK) "", // Z=0, L=0, ZM=0, ZL=0 @@ -25,7 +26,7 @@ static const char *const zl_condition_codes[] = "leq", // Z=1, L=1, ZM=1, ZL=1 }; -static const char *const cv_condition_codes[16] = +const char *const tms32051_disassembler::cv_condition_codes[16] = { "", // V=0, C=0, VM=0, CM=0 "nc", // V=0, C=0, VM=0, CM=1 @@ -45,7 +46,7 @@ static const char *const cv_condition_codes[16] = "c ov", // V=1, C=1, VM=1, CM=1 }; -static const char *const tp_condition_codes[4] = +const char *const tms32051_disassembler::tp_condition_codes[4] = { "bio", "tc", @@ -53,24 +54,13 @@ static const char *const tp_condition_codes[4] = "" }; - -static offs_t npc; -static const uint8_t *rombase; -static offs_t pcbase; - -static std::ostream *output; - -static uint16_t FETCH(void) +uint16_t tms32051_disassembler::FETCH(offs_t &npc, const data_buffer &opcodes) { - uint16_t result = rombase[(npc - pcbase) * 2 + 0] | (rombase[(npc - pcbase) * 2 + 1] << 8); - npc++; - return result; + return opcodes.r16(npc++); } -static char *GET_ADDRESS(int addr_mode, int address) +std::string tms32051_disassembler::GET_ADDRESS(int addr_mode, int address) { - static char buffer[100]; - if (addr_mode) // Indirect addressing { int nar = address & 0x7; @@ -78,48 +68,43 @@ static char *GET_ADDRESS(int addr_mode, int address) switch ((address >> 3) & 0xf) { - case 0x0: sprintf(buffer, "*"); break; - case 0x1: sprintf(buffer, "*, ar%d", nar); break; - case 0x2: sprintf(buffer, "*-"); break; - case 0x3: sprintf(buffer, "*-, ar%d", nar); break; - case 0x4: sprintf(buffer, "*+"); break; - case 0x5: sprintf(buffer, "*+, ar%d", nar); break; - case 0x8: sprintf(buffer, "*br0-"); break; - case 0x9: sprintf(buffer, "*br0-, ar%d", nar); break; - case 0xa: sprintf(buffer, "*0-"); break; - case 0xb: sprintf(buffer, "*0-, ar%d", nar); break; - case 0xc: sprintf(buffer, "*0+"); break; - case 0xd: sprintf(buffer, "*0+, ar%d", nar); break; - case 0xe: sprintf(buffer, "*br0+"); break; - case 0xf: sprintf(buffer, "*br0+, ar%d", nar); break; - - default: sprintf(buffer, "??? (indirect)"); break; + case 0x0: return util::string_format("*"); + case 0x1: return util::string_format("*, ar%d", nar); + case 0x2: return util::string_format("*-"); + case 0x3: return util::string_format("*-, ar%d", nar); + case 0x4: return util::string_format("*+"); + case 0x5: return util::string_format("*+, ar%d", nar); + case 0x8: return util::string_format("*br0-"); + case 0x9: return util::string_format("*br0-, ar%d", nar); + case 0xa: return util::string_format("*0-"); + case 0xb: return util::string_format("*0-, ar%d", nar); + case 0xc: return util::string_format("*0+"); + case 0xd: return util::string_format("*0+, ar%d", nar); + case 0xe: return util::string_format("*br0+"); + case 0xf: return util::string_format("*br0+, ar%d", nar); + + default: return util::string_format("??? (indirect)"); } } else // Direct addressing { - sprintf(buffer, "#%02X", address); + return util::string_format("#%02X", address); } - return buffer; } -static char *GET_SHIFT(int shift) +std::string tms32051_disassembler::GET_SHIFT(int shift) { - static char buffer[100]; - if (shift > 0) { - sprintf(buffer, ", %d", shift); + return util::string_format(", %d", shift); } else { - memset(buffer, 0, sizeof(buffer)); + return ""; } - - return buffer; } -static void print_condition_codes(bool pp, int zl, int cv, int tp) +void tms32051_disassembler::print_condition_codes(bool pp, int zl, int cv, int tp) { if (*(zl_condition_codes[zl]) != 0) { @@ -143,7 +128,7 @@ static void print_condition_codes(bool pp, int zl, int cv, int tp) } } -static void dasm_group_be(uint16_t opcode) +void tms32051_disassembler::dasm_group_be(uint16_t opcode, offs_t &npc, const data_buffer &opcodes) { int subop = opcode & 0xff; @@ -217,19 +202,19 @@ static void dasm_group_be(uint16_t opcode) case 0x7c: case 0x7d: case 0x7e: case 0x7f: util::stream_format(*output, "intr %d", opcode & 0x1f); break; - case 0x80: util::stream_format(*output, "mpy #%04X", FETCH()); break; - case 0x81: util::stream_format(*output, "and #%04X", FETCH() << 16); break; - case 0x82: util::stream_format(*output, "or #%04X", FETCH() << 16); break; - case 0x83: util::stream_format(*output, "xor #%04X", FETCH() << 16); break; - case 0xc4: util::stream_format(*output, "rpt #%04X", FETCH()); break; - case 0xc5: util::stream_format(*output, "rptz #%04X", FETCH()); break; - case 0xc6: util::stream_format(*output, "rptb #%04X", FETCH()); break; + case 0x80: util::stream_format(*output, "mpy #%04X", FETCH(npc, opcodes)); break; + case 0x81: util::stream_format(*output, "and #%04X", FETCH(npc, opcodes) << 16); break; + case 0x82: util::stream_format(*output, "or #%04X", FETCH(npc, opcodes) << 16); break; + case 0x83: util::stream_format(*output, "xor #%04X", FETCH(npc, opcodes) << 16); break; + case 0xc4: util::stream_format(*output, "rpt #%04X", FETCH(npc, opcodes)); break; + case 0xc5: util::stream_format(*output, "rptz #%04X", FETCH(npc, opcodes)); break; + case 0xc6: util::stream_format(*output, "rptb #%04X", FETCH(npc, opcodes)); break; default: util::stream_format(*output, "??? (group be)"); break; } } -static void dasm_group_bf(uint16_t opcode) +void tms32051_disassembler::dasm_group_bf(uint16_t opcode, offs_t &npc, const data_buffer &opcodes) { int subop = (opcode >> 4) & 0xf; int shift = opcode & 0xf; @@ -240,7 +225,7 @@ static void dasm_group_bf(uint16_t opcode) { if (opcode & 0x8) { - util::stream_format(*output, "lar ar%d, #%04X", opcode & 0x7, FETCH()); + util::stream_format(*output, "lar ar%d, #%04X", opcode & 0x7, FETCH(npc, opcodes)); } else { @@ -261,31 +246,34 @@ static void dasm_group_bf(uint16_t opcode) break; } - case 0x8: util::stream_format(*output, "lacc #%04X", FETCH() << shift); break; - case 0x9: util::stream_format(*output, "add #%04X", FETCH() << shift); break; - case 0xa: util::stream_format(*output, "sub #%04X", FETCH() << shift); break; - case 0xb: util::stream_format(*output, "and #%04X", FETCH() << shift); break; - case 0xc: util::stream_format(*output, "or #%04X", FETCH() << shift); break; - case 0xd: util::stream_format(*output, "xor #%04X", FETCH() << shift); break; + case 0x8: util::stream_format(*output, "lacc #%04X", FETCH(npc, opcodes) << shift); break; + case 0x9: util::stream_format(*output, "add #%04X", FETCH(npc, opcodes) << shift); break; + case 0xa: util::stream_format(*output, "sub #%04X", FETCH(npc, opcodes) << shift); break; + case 0xb: util::stream_format(*output, "and #%04X", FETCH(npc, opcodes) << shift); break; + case 0xc: util::stream_format(*output, "or #%04X", FETCH(npc, opcodes) << shift); break; + case 0xd: util::stream_format(*output, "xor #%04X", FETCH(npc, opcodes) << shift); break; case 0xe: util::stream_format(*output, "bsar %d", shift+1); break; default: util::stream_format(*output, "??? (group bf)"); break; } } -CPU_DISASSEMBLE(tms32051) +u32 tms32051_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t tms32051_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint32_t flags = 0; uint16_t opcode; int baseop; int address, addr_mode; - pcbase = pc; - rombase = oprom; - npc = pc; + offs_t npc = pc; output = &stream; - opcode = FETCH(); + opcode = FETCH(npc, opcodes); baseop = (opcode >> 8) & 0xff; addr_mode = (opcode >> 7) & 0x1; @@ -300,10 +288,10 @@ CPU_DISASSEMBLE(tms32051) break; } case 0x08: util::stream_format(*output, "lamm %s", GET_ADDRESS(addr_mode, address)); break; - case 0x09: util::stream_format(*output, "smmr %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH()); break; + case 0x09: util::stream_format(*output, "smmr %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH(npc, opcodes)); break; case 0x0a: util::stream_format(*output, "subc %s", GET_ADDRESS(addr_mode, address)); break; case 0x0b: util::stream_format(*output, "rpt %s", GET_ADDRESS(addr_mode, address)); break; - case 0x0c: util::stream_format(*output, "out %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH()); break; + case 0x0c: util::stream_format(*output, "out %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH(npc, opcodes)); break; case 0x0d: util::stream_format(*output, "ldp %s", GET_ADDRESS(addr_mode, address)); break; case 0x0e: util::stream_format(*output, "lst 0, %s", GET_ADDRESS(addr_mode, address)); break; case 0x0f: util::stream_format(*output, "lst 1, %s", GET_ADDRESS(addr_mode, address)); break; @@ -355,10 +343,10 @@ CPU_DISASSEMBLE(tms32051) case 0x59: util::stream_format(*output, "opl %s", GET_ADDRESS(addr_mode, address)); break; case 0x5a: util::stream_format(*output, "apl %s", GET_ADDRESS(addr_mode, address)); break; case 0x5b: util::stream_format(*output, "cpl %s", GET_ADDRESS(addr_mode, address)); break; - case 0x5c: util::stream_format(*output, "xpl %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH()); break; - case 0x5d: util::stream_format(*output, "opl %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH()); break; - case 0x5e: util::stream_format(*output, "apl %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH()); break; - case 0x5f: util::stream_format(*output, "cpl %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH()); break; + case 0x5c: util::stream_format(*output, "xpl %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH(npc, opcodes)); break; + case 0x5d: util::stream_format(*output, "opl %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH(npc, opcodes)); break; + case 0x5e: util::stream_format(*output, "apl %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH(npc, opcodes)); break; + case 0x5f: util::stream_format(*output, "cpl %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH(npc, opcodes)); break; case 0x60: util::stream_format(*output, "addc %s", GET_ADDRESS(addr_mode, address)); break; case 0x61: util::stream_format(*output, "add %s << 16", GET_ADDRESS(addr_mode, address)); break; @@ -386,13 +374,13 @@ CPU_DISASSEMBLE(tms32051) case 0x76: util::stream_format(*output, "pshd %s", GET_ADDRESS(addr_mode, address)); break; case 0x77: util::stream_format(*output, "dmov %s", GET_ADDRESS(addr_mode, address)); break; case 0x78: util::stream_format(*output, "adrk #%02X", opcode & 0xff); break; - case 0x79: util::stream_format(*output, "b %04X, %s", FETCH(), GET_ADDRESS(1, address)); break; - case 0x7a: util::stream_format(*output, "call %04X, %s", FETCH(), GET_ADDRESS(1, address)); flags = DASMFLAG_STEP_OVER; break; - case 0x7b: util::stream_format(*output, "banz %04X, %s", FETCH(), GET_ADDRESS(1, address)); break; + case 0x79: util::stream_format(*output, "b %04X, %s", FETCH(npc, opcodes), GET_ADDRESS(1, address)); break; + case 0x7a: util::stream_format(*output, "call %04X, %s", FETCH(npc, opcodes), GET_ADDRESS(1, address)); flags = STEP_OVER; break; + case 0x7b: util::stream_format(*output, "banz %04X, %s", FETCH(npc, opcodes), GET_ADDRESS(1, address)); break; case 0x7c: util::stream_format(*output, "sbrk #%02X", opcode & 0xff); break; - case 0x7d: util::stream_format(*output, "bd %04X, %s", FETCH(), GET_ADDRESS(1, address)); break; - case 0x7e: util::stream_format(*output, "calld %04X, %s", FETCH(), GET_ADDRESS(1, address)); flags = DASMFLAG_STEP_OVER; break; - case 0x7f: util::stream_format(*output, "banzd %04X, %s", FETCH(), GET_ADDRESS(1, address)); break; + case 0x7d: util::stream_format(*output, "bd %04X, %s", FETCH(npc, opcodes), GET_ADDRESS(1, address)); break; + case 0x7e: util::stream_format(*output, "calld %04X, %s", FETCH(npc, opcodes), GET_ADDRESS(1, address)); flags = STEP_OVER; break; + case 0x7f: util::stream_format(*output, "banzd %04X, %s", FETCH(npc, opcodes), GET_ADDRESS(1, address)); break; case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87: @@ -401,7 +389,7 @@ CPU_DISASSEMBLE(tms32051) break; } case 0x88: util::stream_format(*output, "samm %s", GET_ADDRESS(addr_mode, address)); break; - case 0x89: util::stream_format(*output, "lmmr %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH()); break; + case 0x89: util::stream_format(*output, "lmmr %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH(npc, opcodes)); break; case 0x8a: util::stream_format(*output, "popd %s", GET_ADDRESS(addr_mode, address)); break; case 0x8b: { @@ -433,21 +421,21 @@ CPU_DISASSEMBLE(tms32051) break; } - case 0xa0: util::stream_format(*output, "norm %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH()); break; - case 0xa2: util::stream_format(*output, "mac %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH()); break; + case 0xa0: util::stream_format(*output, "norm %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH(npc, opcodes)); break; + case 0xa2: util::stream_format(*output, "mac %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH(npc, opcodes)); break; case 0xa3: util::stream_format(*output, "macd %s", GET_ADDRESS(addr_mode, address)); break; case 0xa4: util::stream_format(*output, "blpd %s", GET_ADDRESS(addr_mode, address)); break; - case 0xa5: util::stream_format(*output, "blpd %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH()); break; + case 0xa5: util::stream_format(*output, "blpd %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH(npc, opcodes)); break; case 0xa6: util::stream_format(*output, "tblr %s", GET_ADDRESS(addr_mode, address)); break; case 0xa7: util::stream_format(*output, "tblw %s", GET_ADDRESS(addr_mode, address)); break; - case 0xa8: util::stream_format(*output, "bldd %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH()); break; - case 0xa9: util::stream_format(*output, "bldd %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH()); break; + case 0xa8: util::stream_format(*output, "bldd %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH(npc, opcodes)); break; + case 0xa9: util::stream_format(*output, "bldd %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH(npc, opcodes)); break; case 0xaa: util::stream_format(*output, "mads %s", GET_ADDRESS(addr_mode, address)); break; case 0xab: util::stream_format(*output, "madd %s", GET_ADDRESS(addr_mode, address)); break; case 0xac: util::stream_format(*output, "bldd %s", GET_ADDRESS(addr_mode, address)); break; case 0xad: util::stream_format(*output, "bldd %s", GET_ADDRESS(addr_mode, address)); break; - case 0xae: util::stream_format(*output, "splk %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH()); break; - case 0xaf: util::stream_format(*output, "in %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH()); break; + case 0xae: util::stream_format(*output, "splk %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH(npc, opcodes)); break; + case 0xaf: util::stream_format(*output, "in %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH(npc, opcodes)); break; case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: @@ -466,8 +454,8 @@ CPU_DISASSEMBLE(tms32051) util::stream_format(*output, "ldp #%03X", opcode & 0x1ff); break; } - case 0xbe: dasm_group_be(opcode); break; - case 0xbf: dasm_group_bf(opcode); break; + case 0xbe: dasm_group_be(opcode, npc, opcodes); break; + case 0xbf: dasm_group_bf(opcode, npc, opcodes); break; case 0xe0: case 0xe1: case 0xe2: case 0xe3: { @@ -477,7 +465,7 @@ CPU_DISASSEMBLE(tms32051) int cv = ((zlcv << 2) & 0xc) | (zlcvmask & 0x3); int tp = (opcode >> 8) & 0x3; - util::stream_format(*output, "bcnd %04X", FETCH()); + util::stream_format(*output, "bcnd %04X", FETCH(npc, opcodes)); print_condition_codes(true, zl, cv, tp); break; } @@ -505,7 +493,7 @@ CPU_DISASSEMBLE(tms32051) int cv = ((zlcv << 2) & 0xc) | (zlcvmask & 0x3); int tp = (opcode >> 8) & 0x3; - util::stream_format(*output, "cc %04X", FETCH()); + util::stream_format(*output, "cc %04X", FETCH(npc, opcodes)); print_condition_codes(true, zl, cv, tp); break; } @@ -527,7 +515,7 @@ CPU_DISASSEMBLE(tms32051) util::stream_format(*output, "retc "); print_condition_codes(false, zl, cv, tp); } - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; } @@ -539,7 +527,7 @@ CPU_DISASSEMBLE(tms32051) int cv = ((zlcv << 2) & 0xc) | (zlcvmask & 0x3); int tp = (opcode >> 8) & 0x3; - util::stream_format(*output, "bcndd %04X", FETCH()); + util::stream_format(*output, "bcndd %04X", FETCH(npc, opcodes)); print_condition_codes(true, zl, cv, tp); break; } @@ -552,7 +540,7 @@ CPU_DISASSEMBLE(tms32051) int cv = ((zlcv << 2) & 0xc) | (zlcvmask & 0x3); int tp = (opcode >> 8) & 0x3; - util::stream_format(*output, "ccd %04X", FETCH()); + util::stream_format(*output, "ccd %04X", FETCH(npc, opcodes)); print_condition_codes(true, zl, cv, tp); break; } @@ -574,12 +562,12 @@ CPU_DISASSEMBLE(tms32051) util::stream_format(*output, "retcd "); print_condition_codes(false, zl, cv, tp); } - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; } default: util::stream_format(*output, "??? ($%04X)", opcode); break; } - return (npc-pc) | flags | DASMFLAG_SUPPORTED; + return (npc-pc) | flags | SUPPORTED; } diff --git a/src/devices/cpu/tms32051/dis32051.h b/src/devices/cpu/tms32051/dis32051.h new file mode 100644 index 00000000000..dd170859bf3 --- /dev/null +++ b/src/devices/cpu/tms32051/dis32051.h @@ -0,0 +1,32 @@ +// license:BSD-3-Clause +// copyright-holders:Ville Linde + +#ifndef MAME_CPU_TMS32051_DIS32051_H +#define MAME_CPU_TMS32051_DIS32051_H + +#pragma once + +class tms32051_disassembler : public util::disasm_interface +{ +public: + tms32051_disassembler() = default; + virtual ~tms32051_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *const zl_condition_codes[]; + static const char *const cv_condition_codes[16]; + static const char *const tp_condition_codes[4]; + uint16_t FETCH(offs_t &npc, const data_buffer &opcodes); + std::string GET_ADDRESS(int addr_mode, int address); + std::string GET_SHIFT(int shift); + void print_condition_codes(bool pp, int zl, int cv, int tp); + void dasm_group_be(uint16_t opcode, offs_t &npc, const data_buffer &opcodes); + void dasm_group_bf(uint16_t opcode, offs_t &npc, const data_buffer &opcodes); + + std::ostream *output; +}; + +#endif diff --git a/src/devices/cpu/tms32051/tms32051.cpp b/src/devices/cpu/tms32051/tms32051.cpp index 22abad952ff..721d1fd1bcb 100644 --- a/src/devices/cpu/tms32051/tms32051.cpp +++ b/src/devices/cpu/tms32051/tms32051.cpp @@ -8,6 +8,7 @@ #include "emu.h" #include "tms32051.h" +#include "dis32051.h" #include "debugger.h" enum @@ -117,16 +118,15 @@ tms32053_device::tms32053_device(const machine_config &mconfig, const char *tag, } -offs_t tms32051_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *tms32051_device::create_disassembler() { - extern CPU_DISASSEMBLE( tms32051 ); - return CPU_DISASSEMBLE_NAME(tms32051)(this, stream, pc, oprom, opram, options); + return new tms32051_disassembler; } #define CYCLES(x) (m_icount -= x) -#define ROPCODE() m_direct->read_word((m_pc++) << 1) +#define ROPCODE() m_direct->read_word(m_pc++) void tms32051_device::CHANGE_PC(uint16_t new_pc) { @@ -135,22 +135,22 @@ void tms32051_device::CHANGE_PC(uint16_t new_pc) uint16_t tms32051_device::PM_READ16(uint16_t address) { - return m_program->read_word(address << 1); + return m_program->read_word(address); } void tms32051_device::PM_WRITE16(uint16_t address, uint16_t data) { - m_program->write_word(address << 1, data); + m_program->write_word(address, data); } uint16_t tms32051_device::DM_READ16(uint16_t address) { - return m_data->read_word(address << 1); + return m_data->read_word(address); } void tms32051_device::DM_WRITE16(uint16_t address, uint16_t data) { - m_data->write_word(address << 1, data); + m_data->write_word(address, data); } #include "32051ops.hxx" @@ -183,7 +183,7 @@ void tms32051_device::delay_slot(uint16_t startpc) void tms32051_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<-1>(); m_data = &space(AS_DATA); m_io = &space(AS_IO); @@ -515,7 +515,7 @@ READ16_MEMBER( tms32051_device::cpuregs_r ) case 0x5d: case 0x5e: case 0x5f: - return m_io->read_word(offset << 1); + return m_io->read_word(offset); default: if (!machine().side_effect_disabled()) @@ -626,7 +626,7 @@ WRITE16_MEMBER( tms32051_device::cpuregs_w ) case 0x5d: case 0x5e: case 0x5f: - m_io->write_word(offset << 1, data); + m_io->write_word(offset, data); break; default: diff --git a/src/devices/cpu/tms32051/tms32051.h b/src/devices/cpu/tms32051/tms32051.h index 880741f5a66..2f64822d62c 100644 --- a/src/devices/cpu/tms32051/tms32051.h +++ b/src/devices/cpu/tms32051/tms32051.h @@ -80,9 +80,7 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 4; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; address_space_config m_program_config; address_space_config m_data_config; @@ -161,7 +159,7 @@ protected: } m_shadow; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<-1> *m_direct; address_space *m_data; address_space *m_io; int m_icount; diff --git a/src/devices/cpu/tms32082/dis_mp.cpp b/src/devices/cpu/tms32082/dis_mp.cpp index 0bb6e45d2c5..75c63543256 100644 --- a/src/devices/cpu/tms32082/dis_mp.cpp +++ b/src/devices/cpu/tms32082/dis_mp.cpp @@ -3,12 +3,12 @@ // TMS32082 MP Disassembler #include "emu.h" - +#include "dis_mp.h" #define SIMM15(v) (int32_t)((v & 0x4000) ? (v | 0xffffe000) : (v)) #define UIMM15(v) (v) -static const char *BCND_CONDITION[32] = +const char *tms32082_mp_disassembler::BCND_CONDITION[32] = { "nev.b", "gt0.b", "eq0.b", "ge0.b", "lt0.b", "ne0.b", "le0.b", "alw.b", "nev.h", "gt0.h", "eq0.h", "ge0.h", "lt0.h", "ne0.h", "le0.h", "alw.h", @@ -16,7 +16,7 @@ static const char *BCND_CONDITION[32] = "nev.d", "gt0.d", "eq0.d", "ge0.d", "lt0.d", "ne0.d", "le0.d", "alw.d", }; -static const char *BITNUM_CONDITION[32] = +const char *tms32082_mp_disassembler::BITNUM_CONDITION[32] = { "eq.b", "ne.b", "gt.b", "le.b", "lt.b", "ge.b", "hi.b", "ls.b", "lo.b", "hs.b", "eq.h", "ne.h", "gt.h", "le.h", "lt.h", "ge.h", @@ -24,87 +24,75 @@ static const char *BITNUM_CONDITION[32] = "lt.w", "ge.w", "hi.w", "ls.w", "lo.w", "hs.w", "?", "?", }; -static const char *MEMOP_S[2] = +const char *tms32082_mp_disassembler::MEMOP_S[2] = { ":s", "" }; -static const char *MEMOP_M[2] = +const char *tms32082_mp_disassembler::MEMOP_M[2] = { ":m", "" }; -static const char *FLOATOP_PRECISION[4] = +const char *tms32082_mp_disassembler::FLOATOP_PRECISION[4] = { "s", "d", "i", "u" }; -static const char *ACC_SEL[4] = +const char *tms32082_mp_disassembler::ACC_SEL[4] = { "A0", "A1", "A2", "A3" }; -static const char *FLOATOP_ROUND[4] = +const char *tms32082_mp_disassembler::FLOATOP_ROUND[4] = { "n", "z", "p", "m" }; -static std::ostream *output; -static const uint8_t *opdata; -static int opbytes; - -static uint32_t fetch(void) +uint32_t tms32082_mp_disassembler::fetch(offs_t &pos, const data_buffer &opcodes) { - uint32_t d = ((uint32_t)(opdata[0]) << 24) | ((uint32_t)(opdata[1]) << 16) | ((uint32_t)(opdata[2]) << 8) | opdata[3]; - opdata += 4; - opbytes += 4; + uint32_t d = opcodes.r32(pos); + pos += 4; return d; } -static char* get_creg_name(uint32_t reg) +std::string tms32082_mp_disassembler::get_creg_name(uint32_t reg) { - static char buffer[64]; - switch (reg) { - case 0x0000: sprintf(buffer, "EPC"); break; - case 0x0001: sprintf(buffer, "EIP"); break; - case 0x0002: sprintf(buffer, "CONFIG"); break; - case 0x0004: sprintf(buffer, "INTPEN"); break; - case 0x0006: sprintf(buffer, "IE"); break; - case 0x0008: sprintf(buffer, "FPST"); break; - case 0x000a: sprintf(buffer, "PPERROR"); break; - case 0x000d: sprintf(buffer, "PKTREQ"); break; - case 0x000e: sprintf(buffer, "TCOUNT"); break; - case 0x000f: sprintf(buffer, "TSCALE"); break; - case 0x0010: sprintf(buffer, "FLTOP"); break; - case 0x0011: sprintf(buffer, "FLTADR"); break; - case 0x0012: sprintf(buffer, "FLTTAG"); break; - case 0x0013: sprintf(buffer, "FLTDTL"); break; - case 0x0014: sprintf(buffer, "FLTDTH"); break; - case 0x0020: sprintf(buffer, "SYSSTK"); break; - case 0x0021: sprintf(buffer, "SYSTMP"); break; - case 0x0030: sprintf(buffer, "MPC"); break; - case 0x0031: sprintf(buffer, "MIP"); break; - case 0x0033: sprintf(buffer, "ECOMCNTL"); break; - case 0x0034: sprintf(buffer, "ANASTAT"); break; - case 0x0039: sprintf(buffer, "BRK1"); break; - case 0x003a: sprintf(buffer, "BRK2"); break; - case 0x4000: sprintf(buffer, "IN0P"); break; - case 0x4001: sprintf(buffer, "IN1P"); break; - case 0x4002: sprintf(buffer, "OUTP"); break; - default: sprintf(buffer, "CR %04X", reg); + case 0x0000: return "EPC"; + case 0x0001: return "EIP"; + case 0x0002: return "CONFIG"; + case 0x0004: return "INTPEN"; + case 0x0006: return "IE"; + case 0x0008: return "FPST"; + case 0x000a: return "PPERROR"; + case 0x000d: return "PKTREQ"; + case 0x000e: return "TCOUNT"; + case 0x000f: return "TSCALE"; + case 0x0010: return "FLTOP"; + case 0x0011: return "FLTADR"; + case 0x0012: return "FLTTAG"; + case 0x0013: return "FLTDTL"; + case 0x0014: return "FLTDTH"; + case 0x0020: return "SYSSTK"; + case 0x0021: return "SYSTMP"; + case 0x0030: return "MPC"; + case 0x0031: return "MIP"; + case 0x0033: return "ECOMCNTL"; + case 0x0034: return "ANASTAT"; + case 0x0039: return "BRK1"; + case 0x003a: return "BRK2"; + case 0x4000: return "IN0P"; + case 0x4001: return "IN1P"; + case 0x4002: return "OUTP"; + default: return util::string_format("CR %04X", reg); } - - return buffer; } -static char* format_vector_op(uint32_t op, uint32_t imm32) +std::string tms32082_mp_disassembler::format_vector_op(uint32_t op, uint32_t imm32) { - static char buffer[256]; - static char dest[64]; - char *b = buffer; - + std::string result; int rd = (op >> 27) & 0x1f; int rs = (op >> 22) & 0x1f; int src1 = (op & 0x1f); @@ -121,85 +109,87 @@ static char* format_vector_op(uint32_t op, uint32_t imm32) bool regdest = (op & (1 << 10)) == 0 && (op & (1 << 6)) == 0; // accumulator or register destination - if (regdest) - sprintf(dest, "R%d", rd); - else - sprintf(dest, "A%d", acc); + std::string dest = regdest ? util::string_format("R%d", rd) : util::string_format("A%d", acc); // base op switch (subop) { - case 0xc0: b += sprintf(b, "vadd.%s%s R%d, R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], src1, rs, rs); break; - case 0xc1: b += sprintf(b, "vadd.%s%s 0x%08X, R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], imm32, rs, rs); break; - case 0xc2: b += sprintf(b, "vsub.%s%s R%d, R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], rs, src1, rs); break; - case 0xc3: b += sprintf(b, "vsub.%s%s R%d, 0x%08X, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], rs, imm32, rs); break; - case 0xc4: b += sprintf(b, "vmpy.%s%s R%d, R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], src1, rs, rs); break; - case 0xc5: b += sprintf(b, "vmpy.%s%s 0x%08X, R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], imm32, rs, rs); break; + case 0xc0: result += util::string_format("vadd.%s%s R%d, R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], src1, rs, rs); break; + case 0xc1: result += util::string_format("vadd.%s%s 0x%08X, R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], imm32, rs, rs); break; + case 0xc2: result += util::string_format("vsub.%s%s R%d, R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], rs, src1, rs); break; + case 0xc3: result += util::string_format("vsub.%s%s R%d, 0x%08X, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], rs, imm32, rs); break; + case 0xc4: result += util::string_format("vmpy.%s%s R%d, R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], src1, rs, rs); break; + case 0xc5: result += util::string_format("vmpy.%s%s 0x%08X, R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], imm32, rs, rs); break; case 0xd6: case 0xc6: - b += sprintf(b, "vmsub.s%s R%d, %s, R%d", FLOATOP_PRECISION[pd2], src1, z ? "0" : ACC_SEL[acc], rs); + result += util::string_format("vmsub.s%s R%d, %s, R%d", FLOATOP_PRECISION[pd2], src1, z ? "0" : ACC_SEL[acc], rs); break; case 0xd7: case 0xc7: - b += sprintf(b, "vmsub.s%s 0x%08X, %s, R%d", FLOATOP_PRECISION[pd2], imm32, z ? "0" : ACC_SEL[acc], rs); + result += util::string_format("vmsub.s%s 0x%08X, %s, R%d", FLOATOP_PRECISION[pd2], imm32, z ? "0" : ACC_SEL[acc], rs); break; case 0xd8: case 0xc8: - b += sprintf(b, "vrnd.%s%s R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd4], src1, rs); + result += util::string_format("vrnd.%s%s R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd4], src1, rs); break; case 0xd9: case 0xc9: - b += sprintf(b, "vrnd.%s%s 0x%08X, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd4], imm32, rs); + result += util::string_format("vrnd.%s%s 0x%08X, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd4], imm32, rs); break; - case 0xca: b += sprintf(b, "vrnd.%s%s R%d, R%d", FLOATOP_PRECISION[2 + p1], FLOATOP_PRECISION[pd2],src1, rs); break; - case 0xcb: b += sprintf(b, "vrnd.%s%s 0x%08X, R%d", FLOATOP_PRECISION[2 + p1], FLOATOP_PRECISION[pd2], imm32, rs); break; + case 0xca: result += util::string_format("vrnd.%s%s R%d, R%d", FLOATOP_PRECISION[2 + p1], FLOATOP_PRECISION[pd2],src1, rs); break; + case 0xcb: result += util::string_format("vrnd.%s%s 0x%08X, R%d", FLOATOP_PRECISION[2 + p1], FLOATOP_PRECISION[pd2], imm32, rs); break; case 0xcc: case 0xdc: - b += sprintf(b, "vmac.ss%s R%d, R%d, %s, %s", FLOATOP_PRECISION[(op >> 9) & 1], src1, rs, z ? "0" : ACC_SEL[acc], (regdest && rd == 0) ? ACC_SEL[acc] : dest); + result += util::string_format("vmac.ss%s R%d, R%d, %s, %s", FLOATOP_PRECISION[(op >> 9) & 1], src1, rs, z ? "0" : ACC_SEL[acc], (regdest && rd == 0) ? ACC_SEL[acc] : dest); break; case 0xcd: case 0xdd: - b += sprintf(b, "vmac.ss%s 0x%08X, R%d, %s, %s", FLOATOP_PRECISION[(op >> 9) & 1], imm32, rs, z ? "0" : ACC_SEL[acc], (regdest && rd == 0) ? ACC_SEL[acc] : dest); + result += util::string_format("vmac.ss%s 0x%08X, R%d, %s, %s", FLOATOP_PRECISION[(op >> 9) & 1], imm32, rs, z ? "0" : ACC_SEL[acc], (regdest && rd == 0) ? ACC_SEL[acc] : dest); break; case 0xce: case 0xde: - b += sprintf(b, "vmsc.ss%s R%d, R%d, %s, %s", FLOATOP_PRECISION[(op >> 9) & 1], src1, rs, z ? "0" : ACC_SEL[acc], (regdest && rd == 0) ? ACC_SEL[acc] : dest); + result += util::string_format("vmsc.ss%s R%d, R%d, %s, %s", FLOATOP_PRECISION[(op >> 9) & 1], src1, rs, z ? "0" : ACC_SEL[acc], (regdest && rd == 0) ? ACC_SEL[acc] : dest); break; case 0xcf: case 0xdf: - b += sprintf(b, "vmsc.ss%s 0x%08X, R%d, %s, %s", FLOATOP_PRECISION[(op >> 9) & 1], imm32, rs, z ? "0" : ACC_SEL[acc], (regdest && rd == 0) ? ACC_SEL[acc] : dest); + result += util::string_format("vmsc.ss%s 0x%08X, R%d, %s, %s", FLOATOP_PRECISION[(op >> 9) & 1], imm32, rs, z ? "0" : ACC_SEL[acc], (regdest && rd == 0) ? ACC_SEL[acc] : dest); break; - default: b += sprintf(b, "?"); break; + default: result += '?'; break; } // align the line end - int len = strlen(buffer); + int len = result.size(); if (len < 30) { for (int i=0; i < (30-len); i++) { - b += sprintf(b, " "); + result += ' '; } } // optional load/store op switch (vector_ls_bits) { - case 0x01: b += sprintf(b, "|| vst.s R%d", rd); break; - case 0x03: b += sprintf(b, "|| vst.d R%d", rd); break; - case 0x04: b += sprintf(b, "|| vld0.s R%d", rd); break; - case 0x05: b += sprintf(b, "|| vld1.s R%d", rd); break; - case 0x06: b += sprintf(b, "|| vld0.d R%d", rd); break; - case 0x07: b += sprintf(b, "|| vld1.d R%d", rd); break; + case 0x01: result += util::string_format("|| vst.s R%d", rd); break; + case 0x03: result += util::string_format("|| vst.d R%d", rd); break; + case 0x04: result += util::string_format("|| vld0.s R%d", rd); break; + case 0x05: result += util::string_format("|| vld1.s R%d", rd); break; + case 0x06: result += util::string_format("|| vld0.d R%d", rd); break; + case 0x07: result += util::string_format("|| vld1.d R%d", rd); break; } - return buffer; + return result; +} + + +u32 tms32082_mp_disassembler::opcode_alignment() const +{ + return 4; } -static offs_t tms32082_disasm_mp(std::ostream &stream, offs_t pc, const uint8_t *oprom) +offs_t tms32082_mp_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { output = &stream; - opdata = oprom; - opbytes = 0; + offs_t pos = pc; uint32_t flags = 0; - uint32_t op = fetch(); + uint32_t op = fetch(pos, opcodes); int rd = (op >> 27) & 0x1f; int link = rd; @@ -310,7 +300,7 @@ static offs_t tms32082_disasm_mp(std::ostream &stream, offs_t pc, const uint8_t uint32_t imm32 = 0; if (op & (1 << 12)) // fetch 32-bit immediate if needed - imm32 = fetch(); + imm32 = fetch(pos, opcodes); int m = op & (1 << 15) ? 0 : 1; int s = op & (1 << 11) ? 0 : 1; @@ -502,10 +492,5 @@ static offs_t tms32082_disasm_mp(std::ostream &stream, offs_t pc, const uint8_t } } - return opbytes | flags | DASMFLAG_SUPPORTED; -} - -CPU_DISASSEMBLE(tms32082_mp) -{ - return tms32082_disasm_mp(stream, pc, oprom); + return (pos - pc) | flags | SUPPORTED; } diff --git a/src/devices/cpu/tms32082/dis_mp.h b/src/devices/cpu/tms32082/dis_mp.h new file mode 100644 index 00000000000..8c3a0721c1a --- /dev/null +++ b/src/devices/cpu/tms32082/dis_mp.h @@ -0,0 +1,35 @@ +// license:BSD-3-Clause +// copyright-holders:Ville Linde +// TMS32082 MP Disassembler + +#ifndef MAME_CPU_TMS32082_DIS_MP_H +#define MAME_CPU_TMS32082_DIS_MP_H + +#pragma once + +class tms32082_mp_disassembler : public util::disasm_interface +{ +public: + tms32082_mp_disassembler() = default; + virtual ~tms32082_mp_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *BCND_CONDITION[32]; + static const char *BITNUM_CONDITION[32]; + static const char *MEMOP_S[2]; + static const char *MEMOP_M[2]; + static const char *FLOATOP_PRECISION[4]; + static const char *ACC_SEL[4]; + static const char *FLOATOP_ROUND[4]; + + std::ostream *output; + + uint32_t fetch(offs_t &pos, const data_buffer &opcodes); + std::string get_creg_name(uint32_t reg); + std::string format_vector_op(uint32_t op, uint32_t imm32); +}; + +#endif diff --git a/src/devices/cpu/tms32082/dis_pp.cpp b/src/devices/cpu/tms32082/dis_pp.cpp index b685ab54b4f..8a3a6475ba0 100644 --- a/src/devices/cpu/tms32082/dis_pp.cpp +++ b/src/devices/cpu/tms32082/dis_pp.cpp @@ -3,9 +3,9 @@ // TMS32082 PP Disassembler #include "emu.h" +#include "dis_pp.h" - -static const char *REG_NAMES[128] = +const char *tms32082_pp_disassembler::REG_NAMES[128] = { // 0 - 15 "a0", "a1", "a2", "a3", "a4", "???", "a6", "a7", @@ -33,7 +33,7 @@ static const char *REG_NAMES[128] = "???", "???", "???", "???", "tag0", "tag1", "tag2", "tag3" }; -static const char *CONDITION_CODES[16] = +const char *tms32082_pp_disassembler::CONDITION_CODES[16] = { "", "[p] ", "[ls] ", "[hi] ", "[lt] ", "[le] ", "[ge] ", "[gt] ", @@ -41,50 +41,40 @@ static const char *CONDITION_CODES[16] = "[v] ", "[nv] ", "[n] ", "[nn] " }; -static const char *TRANSFER_SIZE[4] = +const char *tms32082_pp_disassembler::TRANSFER_SIZE[4] = { "b:", "h:", "w:", "" }; - -static std::ostream *output; - -static char *format_address_mode(int mode, int areg, int s, int limx) +std::string tms32082_pp_disassembler::format_address_mode(int mode, int areg, int s, int limx) { - static char buffer[64]; - - memset(buffer, 0, sizeof(char)*64); - switch (mode) { - case 0x4: sprintf(buffer, "*(a%d++=x%d)", areg, limx); break; - case 0x5: sprintf(buffer, "*(a%d--=x%d)", areg, limx); break; - case 0x6: sprintf(buffer, "*(a%d++0x%04X)", areg, limx); break; - case 0x7: sprintf(buffer, "*(a%d--0x%04X)", areg, limx); break; - case 0x8: sprintf(buffer, "*(a%d+x%d)", areg, limx); break; - case 0x9: sprintf(buffer, "*(a%d-x%d)", areg, limx); break; - case 0xa: sprintf(buffer, "*(a%d+0x%04X)", areg, limx); break; - case 0xb: sprintf(buffer, "*(a%d-0x%04X)", areg, limx); break; - case 0xc: sprintf(buffer, "*(a%d+=x%d)", areg, limx); break; - case 0xd: sprintf(buffer, "*(a%d-=x%d)", areg, limx); break; - case 0xe: sprintf(buffer, "*(a%d+=0x%04X)", areg, limx); break; - case 0xf: sprintf(buffer, "*(a%d-=0x%04X)", areg, limx); break; + case 0x4: return util::string_format("*(a%d++=x%d)", areg, limx); + case 0x5: return util::string_format("*(a%d--=x%d)", areg, limx); + case 0x6: return util::string_format("*(a%d++0x%04X)", areg, limx); + case 0x7: return util::string_format("*(a%d--0x%04X)", areg, limx); + case 0x8: return util::string_format("*(a%d+x%d)", areg, limx); + case 0x9: return util::string_format("*(a%d-x%d)", areg, limx); + case 0xa: return util::string_format("*(a%d+0x%04X)", areg, limx); + case 0xb: return util::string_format("*(a%d-0x%04X)", areg, limx); + case 0xc: return util::string_format("*(a%d+=x%d)", areg, limx); + case 0xd: return util::string_format("*(a%d-=x%d)", areg, limx); + case 0xe: return util::string_format("*(a%d+=0x%04X)", areg, limx); + case 0xf: return util::string_format("*(a%d-=0x%04X)", areg, limx); } - return buffer; + return ""; } -static void format_transfer(uint64_t op) +void tms32082_pp_disassembler::format_transfer(uint64_t op) { - char buffer[128]; - char *b = buffer; + std::string buffer; int lmode = (op >> 35) & 0xf; int gmode = (op >> 13) & 0xf; bool is_nop = false; - memset(buffer, 0, sizeof(char)*128); - switch (lmode) { case 0x0: @@ -106,8 +96,8 @@ static void format_transfer(uint64_t op) int dreg = (dstbank << 3) | dst; int sreg = (srcbank << 3) | src; - b += sprintf(b, "%s", CONDITION_CODES[cond]); - b += sprintf(b, "%s = %s", REG_NAMES[dreg], REG_NAMES[sreg]); + buffer += util::string_format("%s", CONDITION_CODES[cond]); + buffer += util::string_format("%s = %s", REG_NAMES[dreg], REG_NAMES[sreg]); break; } case 0x01: // Format 8: Conditional DU ||Conditional Field Move @@ -122,8 +112,8 @@ static void format_transfer(uint64_t op) int dreg = (dstbank << 3) | dst; int sreg = (4 << 3) | src; - b += sprintf(b, "%s", CONDITION_CODES[cond]); - b += sprintf(b, "%s = [%s%d]%s", REG_NAMES[dreg], TRANSFER_SIZE[size], itm, REG_NAMES[sreg]); + buffer += util::string_format("%s", CONDITION_CODES[cond]); + buffer += util::string_format("%s = [%s%d]%s", REG_NAMES[dreg], TRANSFER_SIZE[size], itm, REG_NAMES[sreg]); break; } case 0x02: case 0x03: // Format 10: Conditional Non-D Data Unit @@ -142,8 +132,8 @@ static void format_transfer(uint64_t op) } else { - b += sprintf(b, "%s", CONDITION_CODES[cond]); - b += sprintf(b, "%s = %s", REG_NAMES[dreg], REG_NAMES[sreg]); + buffer += util::string_format("%s", CONDITION_CODES[cond]); + buffer += util::string_format("%s = %s", REG_NAMES[dreg], REG_NAMES[sreg]); } break; } @@ -161,14 +151,14 @@ static void format_transfer(uint64_t op) int greg = (bank << 3) | reg; - b += sprintf(b, "%s", CONDITION_CODES[cond]); + buffer += util::string_format("%s", CONDITION_CODES[cond]); switch (le) { - case 0: b += sprintf(b, "&%s%s = %s", TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, gimx), REG_NAMES[greg]); break; - case 1: b += sprintf(b, "%s = %s", REG_NAMES[greg], format_address_mode(gmode, ga, s, gimx)); break; - case 2: b += sprintf(b, "%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, gimx)); break; - case 3: b += sprintf(b, "%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, gimx)); break; + case 0: buffer += util::string_format("&%s%s = %s", TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, gimx), REG_NAMES[greg]); break; + case 1: buffer += util::string_format("%s = %s", REG_NAMES[greg], format_address_mode(gmode, ga, s, gimx)); break; + case 2: buffer += util::string_format("%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, gimx)); break; + case 3: buffer += util::string_format("%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, gimx)); break; } } else // Format 5: Global (Long Offset) @@ -190,10 +180,10 @@ static void format_transfer(uint64_t op) switch (le) { - case 0: b += sprintf(b, "&%s%s = %s", TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, offset), REG_NAMES[greg]); break; - case 1: b += sprintf(b, "%s = %s", REG_NAMES[greg], format_address_mode(gmode, ga, s, offset)); break; - case 2: b += sprintf(b, "%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, offset)); break; - case 3: b += sprintf(b, "%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, offset)); break; + case 0: buffer += util::string_format("&%s%s = %s", TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, offset), REG_NAMES[greg]); break; + case 1: buffer += util::string_format("%s = %s", REG_NAMES[greg], format_address_mode(gmode, ga, s, offset)); break; + case 2: buffer += util::string_format("%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, offset)); break; + case 3: buffer += util::string_format("%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, offset)); break; } } break; @@ -210,12 +200,12 @@ static void format_transfer(uint64_t op) { case 0x00: // Format 2: Move || Local { - b += sprintf(b, "move||local <TODO>"); + buffer += util::string_format("move||local <TODO>"); break; } case 0x01: // Format 3: Field Move || Local { - b += sprintf(b, "field move||local <TODO>"); + buffer += util::string_format("field move||local <TODO>"); break; } case 0x02: case 0x03: // Format 6: Non-D DU || Local @@ -231,10 +221,10 @@ static void format_transfer(uint64_t op) switch (le) { - case 0: b += sprintf(b, "&%s%s = %s", TRANSFER_SIZE[size], format_address_mode(lmode, la, s, limx), REG_NAMES[reg]); break; - case 1: b += sprintf(b, "%s = %s", REG_NAMES[reg], format_address_mode(lmode, la, s, limx)); break; - case 2: b += sprintf(b, "%s = &%s%s", REG_NAMES[reg], TRANSFER_SIZE[size], format_address_mode(lmode, la, s, limx)); break; - case 3: b += sprintf(b, "%s = &%s%s", REG_NAMES[reg], TRANSFER_SIZE[size], format_address_mode(lmode, la, s, limx)); break; + case 0: buffer += util::string_format("&%s%s = %s", TRANSFER_SIZE[size], format_address_mode(lmode, la, s, limx), REG_NAMES[reg]); break; + case 1: buffer += util::string_format("%s = %s", REG_NAMES[reg], format_address_mode(lmode, la, s, limx)); break; + case 2: buffer += util::string_format("%s = &%s%s", REG_NAMES[reg], TRANSFER_SIZE[size], format_address_mode(lmode, la, s, limx)); break; + case 3: buffer += util::string_format("%s = &%s%s", REG_NAMES[reg], TRANSFER_SIZE[size], format_address_mode(lmode, la, s, limx)); break; } break; } @@ -263,10 +253,10 @@ static void format_transfer(uint64_t op) switch (le) { - case 0: b += sprintf(b, "&%s%s = %s", TRANSFER_SIZE[size], format_address_mode(lmode, la, s, offset), REG_NAMES[reg]); break; - case 1: b += sprintf(b, "%s = %s", REG_NAMES[reg], format_address_mode(lmode, la, s, offset)); break; - case 2: b += sprintf(b, "%s = &%s%s", REG_NAMES[reg], TRANSFER_SIZE[size], format_address_mode(lmode, la, s, offset)); break; - case 3: b += sprintf(b, "%s = &%s%s", REG_NAMES[reg], TRANSFER_SIZE[size], format_address_mode(lmode, la, s, offset)); break; + case 0: buffer += util::string_format("&%s%s = %s", TRANSFER_SIZE[size], format_address_mode(lmode, la, s, offset), REG_NAMES[reg]); break; + case 1: buffer += util::string_format("%s = %s", REG_NAMES[reg], format_address_mode(lmode, la, s, offset)); break; + case 2: buffer += util::string_format("%s = &%s%s", REG_NAMES[reg], TRANSFER_SIZE[size], format_address_mode(lmode, la, s, offset)); break; + case 3: buffer += util::string_format("%s = &%s%s", REG_NAMES[reg], TRANSFER_SIZE[size], format_address_mode(lmode, la, s, offset)); break; } break; } @@ -294,10 +284,10 @@ static void format_transfer(uint64_t op) // local transfer switch (local_le) { - case 0: b += sprintf(b, "&%s%s = %s", TRANSFER_SIZE[local_size], format_address_mode(lmode, la, local_s, local_imx), REG_NAMES[lreg]); break; - case 1: b += sprintf(b, "%s = %s", REG_NAMES[lreg], format_address_mode(lmode, la, local_s, local_imx)); break; - case 2: b += sprintf(b, "%s = &%s%s", REG_NAMES[lreg], TRANSFER_SIZE[local_size], format_address_mode(lmode, la, local_s, local_imx)); break; - case 3: b += sprintf(b, "%s = &%s%s", REG_NAMES[lreg], TRANSFER_SIZE[local_size], format_address_mode(lmode, la, local_s, local_imx)); break; + case 0: buffer += util::string_format("&%s%s = %s", TRANSFER_SIZE[local_size], format_address_mode(lmode, la, local_s, local_imx), REG_NAMES[lreg]); break; + case 1: buffer += util::string_format("%s = %s", REG_NAMES[lreg], format_address_mode(lmode, la, local_s, local_imx)); break; + case 2: buffer += util::string_format("%s = &%s%s", REG_NAMES[lreg], TRANSFER_SIZE[local_size], format_address_mode(lmode, la, local_s, local_imx)); break; + case 3: buffer += util::string_format("%s = &%s%s", REG_NAMES[lreg], TRANSFER_SIZE[local_size], format_address_mode(lmode, la, local_s, local_imx)); break; } util::stream_format(*output, ", "); @@ -305,10 +295,10 @@ static void format_transfer(uint64_t op) // global transfer switch (global_le) { - case 0: b += sprintf(b, "&%s%s = %s", TRANSFER_SIZE[global_size], format_address_mode(gmode, ga, global_s, global_imx), REG_NAMES[greg]); break; - case 1: b += sprintf(b, "%s = %s", REG_NAMES[greg], format_address_mode(gmode, ga, global_s, global_imx)); break; - case 2: b += sprintf(b, "%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[global_size], format_address_mode(gmode, ga, global_s, global_imx)); break; - case 3: b += sprintf(b, "%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[global_size], format_address_mode(gmode, ga, global_s, global_imx)); break; + case 0: buffer += util::string_format("&%s%s = %s", TRANSFER_SIZE[global_size], format_address_mode(gmode, ga, global_s, global_imx), REG_NAMES[greg]); break; + case 1: buffer += util::string_format("%s = %s", REG_NAMES[greg], format_address_mode(gmode, ga, global_s, global_imx)); break; + case 2: buffer += util::string_format("%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[global_size], format_address_mode(gmode, ga, global_s, global_imx)); break; + case 3: buffer += util::string_format("%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[global_size], format_address_mode(gmode, ga, global_s, global_imx)); break; } break; } @@ -320,7 +310,7 @@ static void format_transfer(uint64_t op) util::stream_format(*output, " || %s", buffer); } -static void format_alu_op(int aluop, int a, const char *dst_text, const char *a_text, const char *b_text, const char *c_text) +void tms32082_pp_disassembler::format_alu_op(int aluop, int a, const char *dst_text, const char *a_text, const char *b_text, const char *c_text) { if (a) // arithmetic { @@ -409,13 +399,17 @@ static void format_alu_op(int aluop, int a, const char *dst_text, const char *a_ } } -static offs_t tms32082_disasm_pp(std::ostream &stream, offs_t pc, const uint8_t *oprom) +u32 tms32082_pp_disassembler::opcode_alignment() const +{ + return 8; +} + +offs_t tms32082_pp_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { output = &stream; uint32_t flags = 0; - uint64_t op = ((uint64_t)(oprom[0]) << 56) | ((uint64_t)(oprom[1]) << 48) | ((uint64_t)(oprom[2]) << 40) | ((uint64_t)(oprom[3]) << 32) | - ((uint64_t)(oprom[4]) << 24) | ((uint64_t)(oprom[5]) << 16) | ((uint64_t)(oprom[6]) << 8) | ((uint64_t)(oprom[7])); + uint64_t op = opcodes.r64(pc); switch (op >> 60) { @@ -695,10 +689,5 @@ static offs_t tms32082_disasm_pp(std::ostream &stream, offs_t pc, const uint8_t break; } - return 8 | flags | DASMFLAG_SUPPORTED; -} - -CPU_DISASSEMBLE(tms32082_pp) -{ - return tms32082_disasm_pp(stream, pc, oprom); + return 8 | flags | SUPPORTED; } diff --git a/src/devices/cpu/tms32082/dis_pp.h b/src/devices/cpu/tms32082/dis_pp.h new file mode 100644 index 00000000000..6541eeccb70 --- /dev/null +++ b/src/devices/cpu/tms32082/dis_pp.h @@ -0,0 +1,33 @@ +// license:BSD-3-Clause +// copyright-holders:Ville Linde +// TMS32082 PP Disassembler + +#ifndef MAME_CPU_TMS32082_DIS_PP_H +#define MAME_CPU_TMS32082_DIS_PP_H + +#pragma once + +class tms32082_pp_disassembler : public util::disasm_interface +{ +public: + tms32082_pp_disassembler() = default; + virtual ~tms32082_pp_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *REG_NAMES[128]; + static const char *CONDITION_CODES[16]; + static const char *TRANSFER_SIZE[4]; + + + std::ostream *output; + + + std::string format_address_mode(int mode, int areg, int s, int limx); + void format_transfer(uint64_t op); + void format_alu_op(int aluop, int a, const char *dst_text, const char *a_text, const char *b_text, const char *c_text); +}; + +#endif diff --git a/src/devices/cpu/tms32082/tms32082.cpp b/src/devices/cpu/tms32082/tms32082.cpp index e2a975ea995..392cd0d8738 100644 --- a/src/devices/cpu/tms32082/tms32082.cpp +++ b/src/devices/cpu/tms32082/tms32082.cpp @@ -9,11 +9,10 @@ #include "emu.h" #include "tms32082.h" +#include "dis_pp.h" +#include "dis_mp.h" #include "debugger.h" -extern CPU_DISASSEMBLE(tms32082_mp); -extern CPU_DISASSEMBLE(tms32082_pp); - DEFINE_DEVICE_TYPE(TMS32082_MP, tms32082_mp_device, "tms32082_mp", "TMS32082 MP") DEFINE_DEVICE_TYPE(TMS32082_PP, tms32082_pp_device, "tms32082_pp", "TMS32082 PP") @@ -64,13 +63,12 @@ device_memory_interface::space_config_vector tms32082_pp_device::memory_space_co }; } -offs_t tms32082_mp_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) + +util::disasm_interface *tms32082_mp_device::create_disassembler() { - return CPU_DISASSEMBLE_NAME(tms32082_mp)(this, stream, pc, oprom, opram, options); + return new tms32082_mp_disassembler; } - - void tms32082_mp_device::set_command_callback(write32_delegate callback) { m_cmd_callback = callback; @@ -223,7 +221,7 @@ void tms32082_mp_device::device_start() state_add(STATE_GENPCBASE, "CURPC", m_pc).noshow(); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_icountptr = &m_icount; } @@ -502,9 +500,9 @@ tms32082_pp_device::tms32082_pp_device(const machine_config &mconfig, const char } -offs_t tms32082_pp_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *tms32082_pp_device::create_disassembler() { - return CPU_DISASSEMBLE_NAME(tms32082_pp)(this, stream, pc, oprom, opram, options); + return new tms32082_pp_disassembler; } void tms32082_pp_device::device_start() @@ -521,7 +519,7 @@ void tms32082_pp_device::device_start() state_add(STATE_GENPCBASE, "CURPC", m_pc).noshow(); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_icountptr = &m_icount; } diff --git a/src/devices/cpu/tms32082/tms32082.h b/src/devices/cpu/tms32082/tms32082.h index c1d4674dbeb..88f968584a7 100644 --- a/src/devices/cpu/tms32082/tms32082.h +++ b/src/devices/cpu/tms32082/tms32082.h @@ -93,9 +93,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 4; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 8; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; address_space_config m_program_config; @@ -132,7 +130,7 @@ protected: int m_icount; address_space *m_program; - direct_read_data* m_direct; + direct_read_data<0> * m_direct; write32_delegate m_cmd_callback; @@ -181,9 +179,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 8; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 8; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; address_space_config m_program_config; @@ -193,7 +189,7 @@ protected: int m_icount; address_space *m_program; - direct_read_data* m_direct; + direct_read_data<0> * m_direct; }; diff --git a/src/devices/cpu/tms34010/34010dsm.cpp b/src/devices/cpu/tms34010/34010dsm.cpp index f4bad3089ee..cb2fd0ffe4e 100644 --- a/src/devices/cpu/tms34010/34010dsm.cpp +++ b/src/devices/cpu/tms34010/34010dsm.cpp @@ -8,30 +8,23 @@ */ #include "emu.h" +#include "34010dsm.h" -#ifdef STANDALONE -#define PC __pc + (offset << 3) -#define OP_WORD(v) { v = filebuf[_pc>>3]; _pc += 8; v = v | (filebuf[_pc>>3] << 8); _pc += 8;} -#define PARAM_WORD(v) { v = filebuf[_pc>>3]; _pc += 8; v = v | (filebuf[_pc>>3] << 8); _pc += 8;} -#define PARAM_LONG(v) { int v1, v2; PARAM_WORD(v1); PARAM_WORD(v2); v = v1 | (v2 << 16); } -#else -#define PC __pc -#define OP_WORD(v) { v = rombase[(__pc - pcbase) >> 3] | (rombase[(__pc + 8 - pcbase) >> 3] << 8); _pc += 16; } -#define PARAM_WORD(v) { v = rambase[(__pc + 16 - pcbase) >> 3] | (rambase[(__pc + 24 - pcbase) >> 3] << 8); _pc += 16; } -#define PARAM_LONG(v) { v = rambase[(__pc + 16 - pcbase) >> 3] | (rambase[(__pc + 24 - pcbase) >> 3] << 8) | (rambase[(__pc + 32 - pcbase) >> 3] << 16) | (rambase[(__pc + 40 - pcbase) >> 3] << 24); _pc += 32; } -#define PARM2_LONG(v) { v = rambase[(__pc + 48 - pcbase) >> 3] | (rambase[(__pc + 56 - pcbase) >> 3] << 8) | (rambase[(__pc + 64 - pcbase) >> 3] << 16) | (rambase[(__pc + 72 - pcbase) >> 3] << 24); _pc += 32; } -#endif - -static uint8_t rf; -static uint32_t __pc, _pc; -static uint16_t op,rs,rd; - -static const uint8_t *rombase; -static const uint8_t *rambase; -static offs_t pcbase; - - -static void print_reg(std::ostream &stream, uint8_t reg) +uint16_t tms34010_disassembler::r16(offs_t &pos, const data_buffer &opcodes) +{ + uint16_t r = opcodes.r16(pos); + pos += 16; + return r; +} + +uint32_t tms34010_disassembler::r32(offs_t &pos, const data_buffer &opcodes) +{ + uint32_t r = opcodes.r32(pos); + pos += 32; + return r; +} + +void tms34010_disassembler::print_reg(std::ostream &stream, uint8_t reg) { if (reg != 0x0f) { @@ -43,73 +36,51 @@ static void print_reg(std::ostream &stream, uint8_t reg) } } -static void print_src_reg(std::ostream &stream) +void tms34010_disassembler::print_src_reg(std::ostream &stream) { print_reg(stream, rs); } -static void print_des_reg(std::ostream &stream) +void tms34010_disassembler::print_des_reg(std::ostream &stream) { print_reg(stream, rd); } -static void print_src_des_reg(std::ostream &stream) +void tms34010_disassembler::print_src_des_reg(std::ostream &stream) { print_src_reg(stream); stream << ","; print_des_reg(stream); } -static void print_word_parm(std::ostream &stream) +void tms34010_disassembler::print_word_parm(std::ostream &stream, offs_t &pos, const data_buffer ¶ms) { - uint16_t w; - - PARAM_WORD(w); - - util::stream_format(stream, "%Xh", w); + util::stream_format(stream, "%Xh", r16(pos, params)); } -static void print_word_parm_1s_comp(std::ostream &stream) +void tms34010_disassembler::print_word_parm_1s_comp(std::ostream &stream, offs_t &pos, const data_buffer ¶ms) { - uint16_t w; - - PARAM_WORD(w); - w = ~w; - util::stream_format(stream, "%Xh", w); + util::stream_format(stream, "%Xh", u16(~r16(pos, params))); } -static void print_long_parm(std::ostream &stream) +void tms34010_disassembler::print_long_parm(std::ostream &stream, offs_t &pos, const data_buffer ¶ms) { - uint32_t l; - - PARAM_LONG(l); - util::stream_format(stream, "%Xh", l); -} - -static void print_long_parm2(std::ostream &stream) -{ - uint32_t l; - - PARM2_LONG(l); - util::stream_format(stream, "%Xh", l); + util::stream_format(stream, "%Xh", r32(pos, params)); } -static void print_long_parm_1s_comp(std::ostream &stream) +void tms34010_disassembler::print_long_parm_1s_comp(std::ostream &stream, offs_t &pos, const data_buffer ¶ms) { - uint32_t l; - - PARAM_LONG(l); - util::stream_format(stream, "%Xh", ~l); + util::stream_format(stream, "%Xh", u32(~r32(pos, params))); } -static void print_constant(std::ostream &stream) +void tms34010_disassembler::print_constant(std::ostream &stream) { uint8_t constant = (op >> 5) & 0x1f; util::stream_format(stream, "%Xh", constant); } -static void print_constant_1_32(std::ostream &stream) +void tms34010_disassembler::print_constant_1_32(std::ostream &stream) { uint8_t constant = (op >> 5) & 0x1f; if (!constant) constant = 0x20; @@ -117,52 +88,48 @@ static void print_constant_1_32(std::ostream &stream) util::stream_format(stream, "%Xh", constant); } -static void print_constant_1s_comp(std::ostream &stream) +void tms34010_disassembler::print_constant_1s_comp(std::ostream &stream) { uint8_t constant = (~op >> 5) & 0x1f; util::stream_format(stream, "%Xh", constant); } -static void print_constant_2s_comp(std::ostream &stream) +void tms34010_disassembler::print_constant_2s_comp(std::ostream &stream) { uint8_t constant = 32 - ((op >> 5) & 0x1f); util::stream_format(stream, "%Xh", constant); } -static void print_relative(std::ostream &stream) +void tms34010_disassembler::print_relative(std::ostream &stream, offs_t pc, offs_t &pos, const data_buffer ¶ms) { - uint16_t l; - int16_t ls; + int16_t ls = (int16_t)r16(pos, params); - PARAM_WORD(l); - ls = (int16_t)l; - - util::stream_format(stream, "%Xh", PC + 32 + (ls << 4)); + util::stream_format(stream, "%Xh", pc + 32 + (ls << 4)); } -static void print_relative_8bit(std::ostream &stream) +void tms34010_disassembler::print_relative_8bit(std::ostream &stream, offs_t pc) { int8_t ls = (int8_t)op; - util::stream_format(stream, "%Xh", PC + 16 + (ls << 4)); + util::stream_format(stream, "%Xh", pc + 16 + (ls << 4)); } -static void print_relative_5bit(std::ostream &stream) +void tms34010_disassembler::print_relative_5bit(std::ostream &stream, offs_t pc) { int8_t ls = (int8_t)((op >> 5) & 0x1f); if (op & 0x0400) ls = -ls; - util::stream_format(stream, "%Xh", PC + 16 + (ls << 4)); + util::stream_format(stream, "%Xh", pc + 16 + (ls << 4)); } -static void print_field(std::ostream &stream) +void tms34010_disassembler::print_field(std::ostream &stream) { util::stream_format(stream, "%c", (op & 0x200) ? '1' : '0'); } -static void print_condition_code(std::ostream &stream) +void tms34010_disassembler::print_condition_code(std::ostream &stream) { switch (op & 0x0f00) { @@ -185,7 +152,7 @@ static void print_condition_code(std::ostream &stream) } } -static void print_reg_list_range(std::ostream &stream, int8_t first, int8_t last) +void tms34010_disassembler::print_reg_list_range(std::ostream &stream, int8_t first, int8_t last) { if ((first != -1 ) && (first != last)) { @@ -197,13 +164,12 @@ static void print_reg_list_range(std::ostream &stream, int8_t first, int8_t last } } -static void print_reg_list(std::ostream &stream, uint16_t rev) +void tms34010_disassembler::print_reg_list(std::ostream &stream, uint16_t rev, offs_t &pos, const data_buffer ¶ms) { - uint16_t l; uint8_t i; int8_t first = -1, last = 0; - PARAM_WORD(l); + uint16_t l = r16(pos, params); for (i = 0; i < 16; i++) { @@ -241,15 +207,14 @@ static void print_reg_list(std::ostream &stream, uint16_t rev) } -static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) +offs_t tms34010_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { int flags = 0; uint8_t bad = 0; uint16_t subop; + offs_t pos = pc; - __pc = _pc = pc; - - OP_WORD(op); + op = r16(pos, opcodes); subop = (op & 0x01e0); rs = (op >> 5) & 0x0f; /* Source register */ @@ -267,21 +232,21 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) break; case 0x0040: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "IDLE "); else bad = 1; break; case 0x0080: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "MWAIT "); else bad = 1; break; case 0x00e0: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "BLMOVE %d,%d", (op >> 1) & 1, op & 1); else bad = 1; @@ -334,21 +299,21 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) switch (subop) { case 0x0040: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "SETCSP "); else bad = 1; break; case 0x0060: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "SETCDP "); else bad = 1; break; case 0x0080: - if (is_34020) + if (m_is_34020) { util::stream_format(stream, "RPIX "); print_des_reg(stream); @@ -358,7 +323,7 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) break; case 0x00a0: - if (is_34020) + if (m_is_34020) { util::stream_format(stream, "EXGPS "); print_des_reg(stream); @@ -368,7 +333,7 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) break; case 0x00c0: - if (is_34020) + if (m_is_34020) { util::stream_format(stream, "GETPS "); print_des_reg(stream); @@ -378,7 +343,7 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) break; case 0x00e0: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "SETCMP "); else bad = 1; @@ -394,9 +359,9 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) case 0x0140: util::stream_format(stream, "MOVB @"); - print_long_parm(stream); + print_long_parm(stream, pos, params); stream << ",@"; - print_long_parm2(stream); + print_long_parm(stream, pos, params); break; case 0x0160: @@ -434,10 +399,9 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) switch (subop) { case 0x0000: - if (is_34020 && (op & 0xfe00) == 0x0600) + if (m_is_34020 && (op & 0xfe00) == 0x0600) { - uint32_t x; - PARAM_LONG(x); + uint32_t x = r32(pos, params); util::stream_format(stream, "CEXEC %d,%06X,%d", (x >> 7) & 1, (x >> 8) & 0x1fffff, (x >> 29) & 7); } else @@ -445,10 +409,9 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) break; case 0x0020: - if (is_34020 && (op & 0xfe00) == 0x0600) + if (m_is_34020 && (op & 0xfe00) == 0x0600) { - uint32_t x; - PARAM_LONG(x); + uint32_t x = r32(pos, params); util::stream_format(stream, "CMOVGC "); print_des_reg(stream); util::stream_format(stream, ",%06X,%d", (x >> 8) & 0x1fffff, (x >> 29) & 7); @@ -458,10 +421,9 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) break; case 0x0040: - if (is_34020 && (op & 0xfe00) == 0x0600) + if (m_is_34020 && (op & 0xfe00) == 0x0600) { - uint32_t x; - PARAM_LONG(x); + uint32_t x = r32(pos, params); util::stream_format(stream, "CMOVGC "); print_des_reg(stream); stream << ","; @@ -474,10 +436,9 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) break; case 0x0060: - if (is_34020 && (op & 0xfe00) == 0x0600) + if (m_is_34020 && (op & 0xfe00) == 0x0600) { - uint32_t x; - PARAM_LONG(x); + uint32_t x = r32(pos, params); if (op == 0x0660 && (x & 0xff) == 0x01) { @@ -499,10 +460,9 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) break; case 0x0080: - if (is_34020 && (op & 0xfe00) == 0x0600) + if (m_is_34020 && (op & 0xfe00) == 0x0600) { - uint32_t x; - PARAM_LONG(x); + uint32_t x = r32(pos, params); util::stream_format(stream, "CMOVMC *"); rf = (x & 0x10) ? 'B' : 'A'; print_reg(stream, x & 0x0f); @@ -513,10 +473,9 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) break; case 0x00a0: - if (is_34020 && (op & 0xfe00) == 0x0600) + if (m_is_34020 && (op & 0xfe00) == 0x0600) { - uint32_t x; - PARAM_LONG(x); + uint32_t x = r32(pos, params); util::stream_format(stream, "CMOVCM *"); print_des_reg(stream); util::stream_format(stream, "+,%d,%d,%06X,%d", x & 0x1f, (x >> 7) & 1, (x >> 8) & 0x1fffff, (x >> 29) & 7); @@ -526,10 +485,9 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) break; case 0x00c0: - if (is_34020 && (op & 0xfe00) == 0x0600) + if (m_is_34020 && (op & 0xfe00) == 0x0600) { - uint32_t x; - PARAM_LONG(x); + uint32_t x = r32(pos, params); util::stream_format(stream, "CMOVCM *-"); print_des_reg(stream); util::stream_format(stream, ",%d,%d,%06X,%d", x & 0x1f, (x >> 7) & 1, (x >> 8) & 0x1fffff, (x >> 29) & 7); @@ -539,10 +497,9 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) break; case 0x00e0: - if (is_34020 && (op & 0xfe00) == 0x0600) + if (m_is_34020 && (op & 0xfe00) == 0x0600) { - uint32_t x; - PARAM_LONG(x); + uint32_t x = r32(pos, params); util::stream_format(stream, "CMOVMC *"); rf = (x & 0x10) ? 'B' : 'A'; print_reg(stream, x & 0x0f); @@ -581,14 +538,14 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) util::stream_format(stream, "MOVE "); print_des_reg(stream); stream << ",@"; - print_long_parm(stream); + print_long_parm(stream, pos, params); stream << ","; print_field(stream); break; case 0x01a0: util::stream_format(stream, "MOVE @"); - print_long_parm(stream); + print_long_parm(stream, pos, params); stream << ","; print_des_reg(stream); stream << ","; @@ -597,9 +554,9 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) case 0x01c0: util::stream_format(stream, "MOVE @"); - print_long_parm(stream); + print_long_parm(stream, pos, params); stream << ",@"; - print_long_parm2(stream); + print_long_parm(stream, pos, params); stream << ","; print_field(stream); break; @@ -608,7 +565,7 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) if (op & 0x200) { util::stream_format(stream, "MOVE @"); - print_long_parm(stream); + print_long_parm(stream, pos, params); stream << ","; print_des_reg(stream); } @@ -617,7 +574,7 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) util::stream_format(stream, "MOVB "); print_des_reg(stream); stream << ",@"; - print_long_parm(stream); + print_long_parm(stream, pos, params); } break; @@ -631,20 +588,19 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) switch (subop) { case 0x0000: - if (is_34020) + if (m_is_34020) { util::stream_format(stream, "TRAPL "); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; } else bad = 1; break; case 0x0020: - if (is_34020) + if (m_is_34020) { - uint32_t x; - PARAM_LONG(x); + uint32_t x = r32(pos, params); util::stream_format(stream, "CMOVMC *-"); rf = (x & 0x10) ? 'B' : 'A'; print_reg(stream, x & 0x0f); @@ -655,24 +611,24 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) break; case 0x0040: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "VBLT B,L"); else bad = 1; break; case 0x0060: - if (is_34020) + if (m_is_34020) { util::stream_format(stream, "RETM "); - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; } else bad = 1; break; case 0x00e0: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "CLIP "); else bad = 1; @@ -680,23 +636,23 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) case 0x0100: util::stream_format(stream, "TRAP %Xh", op & 0x1f); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case 0x0120: util::stream_format(stream, "CALL "); print_des_reg(stream); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case 0x0140: util::stream_format(stream, "RETI "); - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; case 0x0160: util::stream_format(stream, "RETS "); - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; if (op & 0x1f) { util::stream_format(stream, "%Xh", op & 0x1f); @@ -706,25 +662,25 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) case 0x0180: util::stream_format(stream, "MMTM "); print_des_reg(stream); - print_reg_list(stream, 1); + print_reg_list(stream, 1, pos, params); break; case 0x01a0: util::stream_format(stream, "MMFM "); print_des_reg(stream); - print_reg_list(stream, 0); + print_reg_list(stream, 0, pos, params); break; case 0x01c0: util::stream_format(stream, "MOVI "); - print_word_parm(stream); + print_word_parm(stream, pos, params); stream << ","; print_des_reg(stream); break; case 0x01e0: util::stream_format(stream, "MOVI "); - print_long_parm(stream); + print_long_parm(stream, pos, params); stream << ","; print_des_reg(stream); break; @@ -739,28 +695,28 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) switch (subop) { case 0x0000: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "VLCOL "); else bad = 1; break; case 0x0020: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "PFILL XY"); else bad = 1; break; case 0x0040: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "VFILL L"); else bad = 1; break; case 0x0060: - if (is_34020) + if (m_is_34020) { util::stream_format(stream, "CVMXYL "); print_des_reg(stream); @@ -770,7 +726,7 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) break; case 0x0080: - if (is_34020) + if (m_is_34020) { util::stream_format(stream, "CVDXYL "); print_des_reg(stream); @@ -780,14 +736,14 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) break; case 0x00a0: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "FPIXEQ "); else bad = 1; break; case 0x00c0: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "FPIXNE "); else bad = 1; @@ -795,56 +751,56 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) case 0x0100: util::stream_format(stream, "ADDI "); - print_word_parm(stream); + print_word_parm(stream, pos, params); stream << ","; print_des_reg(stream); break; case 0x0120: util::stream_format(stream, "ADDI "); - print_long_parm(stream); + print_long_parm(stream, pos, params); stream << ","; print_des_reg(stream); break; case 0x0140: util::stream_format(stream, "CMPI "); - print_word_parm_1s_comp(stream); + print_word_parm_1s_comp(stream, pos, params); stream << ","; print_des_reg(stream); break; case 0x0160: util::stream_format(stream, "CMPI "); - print_long_parm_1s_comp(stream); + print_long_parm_1s_comp(stream, pos, params); stream << ","; print_des_reg(stream); break; case 0x0180: util::stream_format(stream, "ANDI "); - print_long_parm_1s_comp(stream); + print_long_parm_1s_comp(stream, pos, params); stream << ","; print_des_reg(stream); break; case 0x01a0: util::stream_format(stream, "ORI "); - print_long_parm(stream); + print_long_parm(stream, pos, params); stream << ","; print_des_reg(stream); break; case 0x01c0: util::stream_format(stream, "XORI "); - print_long_parm(stream); + print_long_parm(stream, pos, params); stream << ","; print_des_reg(stream); break; case 0x01e0: util::stream_format(stream, "SUBI "); - print_word_parm_1s_comp(stream); + print_word_parm_1s_comp(stream, pos, params); stream << ","; print_des_reg(stream); break; @@ -859,10 +815,10 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) switch (subop) { case 0x0000: - if (is_34020) + if (m_is_34020) { util::stream_format(stream, "ADDXYI "); - print_long_parm(stream); + print_long_parm(stream, pos, params); stream << ","; print_des_reg(stream); } @@ -871,7 +827,7 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) break; case 0x0040: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "LINIT "); else bad = 1; @@ -879,21 +835,21 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) case 0x0100: util::stream_format(stream, "SUBI "); - print_long_parm_1s_comp(stream); + print_long_parm_1s_comp(stream, pos, params); stream << ","; print_des_reg(stream); break; case 0x0120: util::stream_format(stream, "CALLR "); - print_relative(stream); - flags = DASMFLAG_STEP_OVER; + print_relative(stream, pc, pos, params); + flags = STEP_OVER; break; case 0x0140: util::stream_format(stream, "CALLA "); - print_long_parm(stream); - flags = DASMFLAG_STEP_OVER; + print_long_parm(stream, pos, params); + flags = STEP_OVER; break; case 0x0160: @@ -904,24 +860,24 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) util::stream_format(stream, "DSJ "); print_des_reg(stream); stream << ","; - print_relative(stream); - flags = DASMFLAG_STEP_OVER; + print_relative(stream, pc, pos, params); + flags = STEP_OVER; break; case 0x01a0: util::stream_format(stream, "DSJEQ "); print_des_reg(stream); stream << ","; - print_relative(stream); - flags = DASMFLAG_STEP_OVER; + print_relative(stream, pc, pos, params); + flags = STEP_OVER; break; case 0x01c0: util::stream_format(stream, "DSJNE "); print_des_reg(stream); stream << ","; - print_relative(stream); - flags = DASMFLAG_STEP_OVER; + print_relative(stream, pc, pos, params); + flags = STEP_OVER; break; case 0x01e0: @@ -935,18 +891,18 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) case 0x0e00: - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; switch (subop) { case 0x0000: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "PIXBLT L,M,L"); else bad = 1; break; case 0x00e0: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "TFILL XY"); else bad = 1; @@ -1088,7 +1044,7 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) case 0x3400: case 0x3600: - if (is_34020) + if (m_is_34020) { util::stream_format(stream, "CMPK "); print_constant_1_32(stream); @@ -1106,8 +1062,8 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) util::stream_format(stream, "DSJS "); print_des_reg(stream); stream << ","; - print_relative_5bit(stream); - flags = DASMFLAG_STEP_OVER; + print_relative_5bit(stream, pc); + flags = STEP_OVER; break; @@ -1279,7 +1235,7 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) case 0x7a00: - if (is_34020) + if (m_is_34020) { util::stream_format(stream, "RMO "); print_src_des_reg(stream); @@ -1289,7 +1245,7 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) break; case 0x7e00: - if (is_34020) + if (m_is_34020) { util::stream_format(stream, "SWAPF *"); print_src_des_reg(stream); @@ -1423,7 +1379,7 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) stream << ",*"; print_des_reg(stream); stream << "("; - print_word_parm(stream); + print_word_parm(stream, pos, params); stream << ")"; break; @@ -1432,7 +1388,7 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) util::stream_format(stream, "MOVB *"); print_src_reg(stream); stream << "("; - print_word_parm(stream); + print_word_parm(stream, pos, params); stream << "),"; print_des_reg(stream); break; @@ -1445,7 +1401,7 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) stream << ",*"; print_des_reg(stream); stream << "("; - print_word_parm(stream); + print_word_parm(stream, pos, params); stream << "),"; print_field(stream); break; @@ -1456,7 +1412,7 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) util::stream_format(stream, "MOVE *"); print_src_reg(stream); stream << "("; - print_word_parm(stream); + print_word_parm(stream, pos, params); stream << "),"; print_des_reg(stream); stream << ","; @@ -1469,11 +1425,11 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) util::stream_format(stream, "MOVE *"); print_src_reg(stream); stream << "("; - print_word_parm(stream); + print_word_parm(stream, pos, params); stream << "),*"; print_des_reg(stream); stream << "("; - print_word_parm(stream); + print_word_parm(stream, pos, params); stream << "),"; print_field(stream); break; @@ -1483,11 +1439,11 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) util::stream_format(stream, "MOVB *"); print_src_reg(stream); stream << "("; - print_word_parm(stream); + print_word_parm(stream, pos, params); stream << "),*"; print_des_reg(stream); stream << "("; - print_word_parm(stream); + print_word_parm(stream, pos, params); stream << ")"; break; @@ -1515,15 +1471,15 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) switch (op & 0x00ff) { case 0x00: - print_relative(stream); + print_relative(stream, pc, pos, params); break; case 0x80: - print_long_parm(stream); + print_long_parm(stream, pos, params); break; default: - print_relative_8bit(stream); + print_relative_8bit(stream, pc); } break; @@ -1533,7 +1489,7 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) util::stream_format(stream, "MOVE *"); print_src_reg(stream); stream << "("; - print_word_parm(stream); + print_word_parm(stream, pos, params); stream << "),*"; print_des_reg(stream); stream << "+,"; @@ -1547,7 +1503,7 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) { case 0x0000: util::stream_format(stream, "MOVE @"); - print_long_parm(stream); + print_long_parm(stream, pos, params); stream << ",*"; print_des_reg(stream); stream << "+,"; @@ -1567,10 +1523,9 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) break; case 0xd800: - if (is_34020) + if (m_is_34020) { - uint32_t x; - PARAM_WORD(x); + uint32_t x = r16(pos, params); util::stream_format(stream, "CEXEC %d,%06X,%d", op & 1, ((x << 5) & 0x1fffe0) | ((op >> 1) & 0x1f), (x >> 13) & 7); } else @@ -1582,14 +1537,14 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) switch (subop) { case 0x0000: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "FLINE 0"); else bad = 1; break; case 0x0080: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "FLINE 1"); else bad = 1; @@ -1639,7 +1594,7 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) case 0xea00: - if (is_34020) + if (m_is_34020) { util::stream_format(stream, "CVSXYL "); print_src_des_reg(stream); @@ -1723,21 +1678,14 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) util::stream_format(stream, "DW %04Xh", op & 0xffff); } - return (_pc - __pc) | flags | DASMFLAG_SUPPORTED; + return (pos - pc) | flags | SUPPORTED; } -CPU_DISASSEMBLE( tms34010 ) +uint32_t tms34010_disassembler::opcode_alignment() const { - rombase = oprom; - rambase = opram; - pcbase = pc; - return Dasm340x0(stream, pc, false); + return 16; } -CPU_DISASSEMBLE( tms34020 ) +tms34010_disassembler::tms34010_disassembler(bool is_34020) : m_is_34020(is_34020) { - rombase = oprom; - rambase = opram; - pcbase = pc; - return Dasm340x0(stream, pc, true); } diff --git a/src/devices/cpu/tms34010/34010dsm.h b/src/devices/cpu/tms34010/34010dsm.h new file mode 100644 index 00000000000..2e8e72ee191 --- /dev/null +++ b/src/devices/cpu/tms34010/34010dsm.h @@ -0,0 +1,52 @@ +// license:BSD-3-Clause +// copyright-holders:Zsolt Vasvari +/* + * A TMS34010 disassembler + * + * This code written by Zsolt Vasvari for the MAME project + * + */ + +#ifndef MAME_CPU_TMS34010_34010DSM_H +#define MAME_CPU_TMS34010_34010DSM_H + +#pragma once + +class tms34010_disassembler : public util::disasm_interface +{ +public: + tms34010_disassembler(bool is_34020); + virtual ~tms34010_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + bool m_is_34020; + uint8_t rf; + uint16_t op,rs,rd; + + uint16_t r16(offs_t &pos, const data_buffer &opcodes); + uint32_t r32(offs_t &pos, const data_buffer &opcodes); + void print_reg(std::ostream &stream, uint8_t reg); + void print_src_reg(std::ostream &stream); + void print_des_reg(std::ostream &stream); + void print_src_des_reg(std::ostream &stream); + void print_word_parm(std::ostream &stream, offs_t &pos, const data_buffer ¶ms); + void print_word_parm_1s_comp(std::ostream &stream, offs_t &pos, const data_buffer ¶ms); + void print_long_parm(std::ostream &stream, offs_t &pos, const data_buffer ¶ms); + void print_long_parm_1s_comp(std::ostream &stream, offs_t &pos, const data_buffer ¶ms); + void print_constant(std::ostream &stream); + void print_constant_1_32(std::ostream &stream); + void print_constant_1s_comp(std::ostream &stream); + void print_constant_2s_comp(std::ostream &stream); + void print_relative(std::ostream &stream, offs_t pc, offs_t &pos, const data_buffer ¶ms); + void print_relative_8bit(std::ostream &stream, offs_t pc); + void print_relative_5bit(std::ostream &stream, offs_t pc); + void print_field(std::ostream &stream); + void print_condition_code(std::ostream &stream); + void print_reg_list_range(std::ostream &stream, int8_t first, int8_t last); + void print_reg_list(std::ostream &stream, uint16_t rev, offs_t &pos, const data_buffer ¶ms); +}; + +#endif diff --git a/src/devices/cpu/tms34010/34010fld.hxx b/src/devices/cpu/tms34010/34010fld.hxx index 7d55bca3b7b..79c2caa5c50 100644 --- a/src/devices/cpu/tms34010/34010fld.hxx +++ b/src/devices/cpu/tms34010/34010fld.hxx @@ -98,7 +98,7 @@ void tms340x0_device::wfield_16(offs_t offset, uint32_t data) } else { - TMS34010_WRMEM_WORD(TOBYTE(offset),data); + TMS34010_WRMEM_WORD(offset,data); } } @@ -313,7 +313,7 @@ uint32_t tms340x0_device::rfield_z_16(offs_t offset) } else - ret = TMS34010_RDMEM_WORD(TOBYTE(offset)); + ret = TMS34010_RDMEM_WORD(offset); return ret; } @@ -490,7 +490,7 @@ uint32_t tms340x0_device::rfield_s_08(offs_t offset) } else - ret = TMS34010_RDMEM(TOBYTE(offset)); + ret = TMS34010_RDMEM(offset); return (int32_t)(int8_t)ret; } @@ -553,7 +553,7 @@ uint32_t tms340x0_device::rfield_s_16(offs_t offset) else { - ret = TMS34010_RDMEM_WORD(TOBYTE(offset)); + ret = TMS34010_RDMEM_WORD(offset); } return (int32_t)(int16_t)ret; diff --git a/src/devices/cpu/tms34010/34010gfx.hxx b/src/devices/cpu/tms34010/34010gfx.hxx index 5c92ad36b6b..410b2d3a06a 100644 --- a/src/devices/cpu/tms34010/34010gfx.hxx +++ b/src/devices/cpu/tms34010/34010gfx.hxx @@ -207,6 +207,11 @@ int tms340x0_device::compute_pixblt_b_cycles(int left_partials, int right_partia /* Shift register handling */ void tms340x0_device::memory_w(address_space &space, offs_t offset,uint16_t data) { + logerror("memory_w %08x %04x\n", offset << 3, data); + if((offset << 3) == 0x02005010 && data == 0x0000) { + machine().debug_break(); + // abort(); + } space.write_word(offset, data); } @@ -217,8 +222,9 @@ uint16_t tms340x0_device::memory_r(address_space &space, offs_t offset) void tms340x0_device::shiftreg_w(address_space &space, offs_t offset,uint16_t data) { + logerror("shiftreg_w %08x %04x\n", offset << 3, data); if (!m_from_shiftreg_cb.isnull()) - m_from_shiftreg_cb(space, (uint32_t)(offset << 3) & ~15, &m_shiftreg[0]); + m_from_shiftreg_cb(space, offset, &m_shiftreg[0]); else logerror("From ShiftReg function not set. PC = %08X\n", m_pc); } @@ -226,7 +232,7 @@ void tms340x0_device::shiftreg_w(address_space &space, offs_t offset,uint16_t da uint16_t tms340x0_device::shiftreg_r(address_space &space, offs_t offset) { if (!m_to_shiftreg_cb.isnull()) - m_to_shiftreg_cb(space, (uint32_t)(offset << 3) & ~15, &m_shiftreg[0]); + m_to_shiftreg_cb(space, offset, &m_shiftreg[0]); else logerror("To ShiftReg function not set. PC = %08X\n", m_pc); return m_shiftreg[0]; @@ -1028,13 +1034,13 @@ void FUNCTION_NAME(tms340x0_device::pixblt)(int src_is_linear, int dst_is_linear uint32_t srcword, dstword = 0; /* fetch the initial source word */ - srcword = (this->*word_read)(*m_program, srcwordaddr++ << 1); + srcword = (this->*word_read)(*m_program, srcwordaddr++ << 4); readwrites++; /* fetch the initial dest word */ if (PIXEL_OP_REQUIRES_SOURCE || TRANSPARENCY || (daddr & 0x0f) != 0) { - dstword = (this->*word_read)(*m_program, dstwordaddr << 1); + dstword = (this->*word_read)(*m_program, dstwordaddr << 4); readwrites++; } @@ -1047,7 +1053,7 @@ void FUNCTION_NAME(tms340x0_device::pixblt)(int src_is_linear, int dst_is_linear /* fetch more words if necessary */ if (srcbit + BITS_PER_PIXEL > 16) { - srcword |= (this->*word_read)(*m_program, srcwordaddr++ << 1) << 16; + srcword |= (this->*word_read)(*m_program, srcwordaddr++ << 4) << 16; readwrites++; } @@ -1064,7 +1070,7 @@ void FUNCTION_NAME(tms340x0_device::pixblt)(int src_is_linear, int dst_is_linear if (PIXEL_OP_REQUIRES_SOURCE || TRANSPARENCY) if (dstbit + BITS_PER_PIXEL > 16) { - dstword |= (this->*word_read)(*m_program, (dstwordaddr + 1) << 1) << 16; + dstword |= (this->*word_read)(*m_program, (dstwordaddr + 1) << 4) << 16; readwrites++; } @@ -1079,7 +1085,7 @@ void FUNCTION_NAME(tms340x0_device::pixblt)(int src_is_linear, int dst_is_linear dstbit += BITS_PER_PIXEL; if (dstbit > 16) { - (this->*word_write)(*m_program, dstwordaddr++ << 1, dstword); + (this->*word_write)(*m_program, dstwordaddr++ << 4, dstword); readwrites++; dstbit -= 16; dstword >>= 16; @@ -1092,13 +1098,13 @@ void FUNCTION_NAME(tms340x0_device::pixblt)(int src_is_linear, int dst_is_linear /* if we're right-partial, read and mask the remaining bits */ if (dstbit != 16) { - uint16_t origdst = (this->*word_read)(*m_program, dstwordaddr << 1); + uint16_t origdst = (this->*word_read)(*m_program, dstwordaddr << 4); uint16_t mask = 0xffff << dstbit; dstword = (dstword & ~mask) | (origdst & mask); readwrites++; } - (this->*word_write)(*m_program, dstwordaddr++ << 1, dstword); + (this->*word_write)(*m_program, dstwordaddr++ << 4, dstword); readwrites++; } @@ -1130,14 +1136,14 @@ void FUNCTION_NAME(tms340x0_device::pixblt)(int src_is_linear, int dst_is_linear dwordaddr = daddr >> 4; /* fetch the initial source word */ - srcword = (this->*word_read)(*m_program, swordaddr++ << 1); + srcword = (this->*word_read)(*m_program, swordaddr++ << 4); srcmask = PIXEL_MASK << (saddr & 15); /* handle the left partial word */ if (left_partials != 0) { /* fetch the destination word */ - dstword = (this->*word_read)(*m_program, dwordaddr << 1); + dstword = (this->*word_read)(*m_program, dwordaddr << 4); dstmask = PIXEL_MASK << (daddr & 15); /* loop over partials */ @@ -1146,7 +1152,7 @@ void FUNCTION_NAME(tms340x0_device::pixblt)(int src_is_linear, int dst_is_linear /* fetch another word if necessary */ if (srcmask == 0) { - srcword = (this->*word_read)(*m_program, swordaddr++ << 1); + srcword = (this->*word_read)(*m_program, swordaddr++ << 4); srcmask = PIXEL_MASK; } @@ -1168,7 +1174,7 @@ void FUNCTION_NAME(tms340x0_device::pixblt)(int src_is_linear, int dst_is_linear } /* write the result */ - (this->*word_write)(*m_program, dwordaddr++ << 1, dstword); + (this->*word_write)(*m_program, dwordaddr++ << 4, dstword); } /* loop over full words */ @@ -1176,7 +1182,7 @@ void FUNCTION_NAME(tms340x0_device::pixblt)(int src_is_linear, int dst_is_linear { /* fetch the destination word (if necessary) */ if (PIXEL_OP_REQUIRES_SOURCE || TRANSPARENCY) - dstword = (this->*word_read)(*m_program, dwordaddr << 1); + dstword = (this->*word_read)(*m_program, dwordaddr << 4); else dstword = 0; dstmask = PIXEL_MASK; @@ -1187,7 +1193,7 @@ void FUNCTION_NAME(tms340x0_device::pixblt)(int src_is_linear, int dst_is_linear /* fetch another word if necessary */ if (srcmask == 0) { - srcword = (this->*word_read)(*m_program, swordaddr++ << 1); + srcword = (this->*word_read)(*m_program, swordaddr++ << 4); srcmask = PIXEL_MASK; } @@ -1209,14 +1215,14 @@ void FUNCTION_NAME(tms340x0_device::pixblt)(int src_is_linear, int dst_is_linear } /* write the result */ - (this->*word_write)(*m_program, dwordaddr++ << 1, dstword); + (this->*word_write)(*m_program, dwordaddr++ << 4, dstword); } /* handle the right partial word */ if (right_partials != 0) { /* fetch the destination word */ - dstword = (this->*word_read)(*m_program, dwordaddr << 1); + dstword = (this->*word_read)(*m_program, dwordaddr << 4); dstmask = PIXEL_MASK; /* loop over partials */ @@ -1226,7 +1232,7 @@ void FUNCTION_NAME(tms340x0_device::pixblt)(int src_is_linear, int dst_is_linear if (srcmask == 0) { LOGGFX((" right fetch @ %08x\n", swordaddr)); - srcword = (this->*word_read)(*m_program, swordaddr++ << 1); + srcword = (this->*word_read)(*m_program, swordaddr++ << 4); srcmask = PIXEL_MASK; } @@ -1248,7 +1254,7 @@ void FUNCTION_NAME(tms340x0_device::pixblt)(int src_is_linear, int dst_is_linear } /* write the result */ - (this->*word_write)(*m_program, dwordaddr++ << 1, dstword); + (this->*word_write)(*m_program, dwordaddr++ << 4, dstword); } #endif @@ -1399,14 +1405,14 @@ if ((daddr & (BITS_PER_PIXEL - 1)) != 0) osd_printf_debug("PIXBLT_R%d with odd d dwordaddr = (daddr + 15) >> 4; /* fetch the initial source word */ - srcword = (this->*word_read)(*m_program, --swordaddr << 1); + srcword = (this->*word_read)(*m_program, --swordaddr << 4); srcmask = PIXEL_MASK << ((saddr - BITS_PER_PIXEL) & 15); /* handle the right partial word */ if (right_partials != 0) { /* fetch the destination word */ - dstword = (this->*word_read)(*m_program, --dwordaddr << 1); + dstword = (this->*word_read)(*m_program, --dwordaddr << 4); dstmask = PIXEL_MASK << ((daddr - BITS_PER_PIXEL) & 15); /* loop over partials */ @@ -1415,7 +1421,7 @@ if ((daddr & (BITS_PER_PIXEL - 1)) != 0) osd_printf_debug("PIXBLT_R%d with odd d /* fetch source pixel if necessary */ if (srcmask == 0) { - srcword = (this->*word_read)(*m_program, --swordaddr << 1); + srcword = (this->*word_read)(*m_program, --swordaddr << 4); srcmask = PIXEL_MASK << (16 - BITS_PER_PIXEL); } @@ -1442,7 +1448,7 @@ if ((daddr & (BITS_PER_PIXEL - 1)) != 0) osd_printf_debug("PIXBLT_R%d with odd d } /* write the result */ - (this->*word_write)(*m_program, dwordaddr << 1, dstword); + (this->*word_write)(*m_program, dwordaddr << 4, dstword); } /* loop over full words */ @@ -1451,7 +1457,7 @@ if ((daddr & (BITS_PER_PIXEL - 1)) != 0) osd_printf_debug("PIXBLT_R%d with odd d /* fetch the destination word (if necessary) */ dwordaddr--; if (PIXEL_OP_REQUIRES_SOURCE || TRANSPARENCY) - dstword = (this->*word_read)(*m_program, dwordaddr << 1); + dstword = (this->*word_read)(*m_program, dwordaddr << 4); else dstword = 0; dstmask = PIXEL_MASK << (16 - BITS_PER_PIXEL); @@ -1462,7 +1468,7 @@ if ((daddr & (BITS_PER_PIXEL - 1)) != 0) osd_printf_debug("PIXBLT_R%d with odd d /* fetch source pixel if necessary */ if (srcmask == 0) { - srcword = (this->*word_read)(*m_program, --swordaddr << 1); + srcword = (this->*word_read)(*m_program, --swordaddr << 4); srcmask = PIXEL_MASK << (16 - BITS_PER_PIXEL); } @@ -1489,14 +1495,14 @@ if ((daddr & (BITS_PER_PIXEL - 1)) != 0) osd_printf_debug("PIXBLT_R%d with odd d } /* write the result */ - (this->*word_write)(*m_program, dwordaddr << 1, dstword); + (this->*word_write)(*m_program, dwordaddr << 4, dstword); } /* handle the left partial word */ if (left_partials != 0) { /* fetch the destination word */ - dstword = (this->*word_read)(*m_program, --dwordaddr << 1); + dstword = (this->*word_read)(*m_program, --dwordaddr << 4); dstmask = PIXEL_MASK << (16 - BITS_PER_PIXEL); /* loop over partials */ @@ -1505,7 +1511,7 @@ if ((daddr & (BITS_PER_PIXEL - 1)) != 0) osd_printf_debug("PIXBLT_R%d with odd d /* fetch the source pixel if necessary */ if (srcmask == 0) { - srcword = (this->*word_read)(*m_program, --swordaddr << 1); + srcword = (this->*word_read)(*m_program, --swordaddr << 4); srcmask = PIXEL_MASK << (16 - BITS_PER_PIXEL); } @@ -1532,7 +1538,7 @@ if ((daddr & (BITS_PER_PIXEL - 1)) != 0) osd_printf_debug("PIXBLT_R%d with odd d } /* write the result */ - (this->*word_write)(*m_program, dwordaddr << 1, dstword); + (this->*word_write)(*m_program, dwordaddr << 4, dstword); } /* update for next row */ @@ -1657,14 +1663,14 @@ void FUNCTION_NAME(tms340x0_device::pixblt_b)(int dst_is_linear) dwordaddr = daddr >> 4; /* fetch the initial source word */ - srcword = (this->*word_read)(*m_program, swordaddr++ << 1); + srcword = (this->*word_read)(*m_program, swordaddr++ << 4); srcmask = 1 << (saddr & 15); /* handle the left partial word */ if (left_partials != 0) { /* fetch the destination word */ - dstword = (this->*word_read)(*m_program, dwordaddr << 1); + dstword = (this->*word_read)(*m_program, dwordaddr << 4); dstmask = PIXEL_MASK << (daddr & 15); /* loop over partials */ @@ -1681,7 +1687,7 @@ void FUNCTION_NAME(tms340x0_device::pixblt_b)(int dst_is_linear) srcmask <<= 1; if (srcmask == 0) { - srcword = (this->*word_read)(*m_program, swordaddr++ << 1); + srcword = (this->*word_read)(*m_program, swordaddr++ << 4); srcmask = 0x0001; } @@ -1690,7 +1696,7 @@ void FUNCTION_NAME(tms340x0_device::pixblt_b)(int dst_is_linear) } /* write the result */ - (this->*word_write)(*m_program, dwordaddr++ << 1, dstword); + (this->*word_write)(*m_program, dwordaddr++ << 4, dstword); } /* loop over full words */ @@ -1698,7 +1704,7 @@ void FUNCTION_NAME(tms340x0_device::pixblt_b)(int dst_is_linear) { /* fetch the destination word (if necessary) */ if (PIXEL_OP_REQUIRES_SOURCE || TRANSPARENCY) - dstword = (this->*word_read)(*m_program, dwordaddr << 1); + dstword = (this->*word_read)(*m_program, dwordaddr << 4); else dstword = 0; dstmask = PIXEL_MASK; @@ -1717,7 +1723,7 @@ void FUNCTION_NAME(tms340x0_device::pixblt_b)(int dst_is_linear) srcmask <<= 1; if (srcmask == 0) { - srcword = (this->*word_read)(*m_program, swordaddr++ << 1); + srcword = (this->*word_read)(*m_program, swordaddr++ << 4); srcmask = 0x0001; } @@ -1726,14 +1732,14 @@ void FUNCTION_NAME(tms340x0_device::pixblt_b)(int dst_is_linear) } /* write the result */ - (this->*word_write)(*m_program, dwordaddr++ << 1, dstword); + (this->*word_write)(*m_program, dwordaddr++ << 4, dstword); } /* handle the right partial word */ if (right_partials != 0) { /* fetch the destination word */ - dstword = (this->*word_read)(*m_program, dwordaddr << 1); + dstword = (this->*word_read)(*m_program, dwordaddr << 4); dstmask = PIXEL_MASK; /* loop over partials */ @@ -1750,7 +1756,7 @@ void FUNCTION_NAME(tms340x0_device::pixblt_b)(int dst_is_linear) srcmask <<= 1; if (srcmask == 0) { - srcword = (this->*word_read)(*m_program, swordaddr++ << 1); + srcword = (this->*word_read)(*m_program, swordaddr++ << 4); srcmask = 0x0001; } @@ -1759,7 +1765,7 @@ void FUNCTION_NAME(tms340x0_device::pixblt_b)(int dst_is_linear) } /* write the result */ - (this->*word_write)(*m_program, dwordaddr++ << 1, dstword); + (this->*word_write)(*m_program, dwordaddr++ << 4, dstword); } /* update for next row */ @@ -1873,7 +1879,7 @@ void FUNCTION_NAME(tms340x0_device::fill)(int dst_is_linear) if (left_partials != 0) { /* fetch the destination word */ - dstword = (this->*word_read)(*m_program, dwordaddr << 1); + dstword = (this->*word_read)(*m_program, dwordaddr << 4); dstmask = PIXEL_MASK << (daddr & 15); /* loop over partials */ @@ -1890,7 +1896,7 @@ void FUNCTION_NAME(tms340x0_device::fill)(int dst_is_linear) } /* write the result */ - (this->*word_write)(*m_program, dwordaddr++ << 1, dstword); + (this->*word_write)(*m_program, dwordaddr++ << 4, dstword); } /* loop over full words */ @@ -1898,7 +1904,7 @@ void FUNCTION_NAME(tms340x0_device::fill)(int dst_is_linear) { /* fetch the destination word (if necessary) */ if (PIXEL_OP_REQUIRES_SOURCE || TRANSPARENCY) - dstword = (this->*word_read)(*m_program, dwordaddr << 1); + dstword = (this->*word_read)(*m_program, dwordaddr << 4); else dstword = 0; dstmask = PIXEL_MASK; @@ -1917,14 +1923,14 @@ void FUNCTION_NAME(tms340x0_device::fill)(int dst_is_linear) } /* write the result */ - (this->*word_write)(*m_program, dwordaddr++ << 1, dstword); + (this->*word_write)(*m_program, dwordaddr++ << 4, dstword); } /* handle the right partial word */ if (right_partials != 0) { /* fetch the destination word */ - dstword = (this->*word_read)(*m_program, dwordaddr << 1); + dstword = (this->*word_read)(*m_program, dwordaddr << 4); dstmask = PIXEL_MASK; /* loop over partials */ @@ -1941,7 +1947,7 @@ void FUNCTION_NAME(tms340x0_device::fill)(int dst_is_linear) } /* write the result */ - (this->*word_write)(*m_program, dwordaddr++ << 1, dstword); + (this->*word_write)(*m_program, dwordaddr++ << 4, dstword); } /* update for next row */ diff --git a/src/devices/cpu/tms34010/34010ops.h b/src/devices/cpu/tms34010/34010ops.h index 901e9b56888..41481212804 100644 --- a/src/devices/cpu/tms34010/34010ops.h +++ b/src/devices/cpu/tms34010/34010ops.h @@ -26,7 +26,7 @@ inline uint32_t tms340x0_device::TMS34010_RDMEM_DWORD(offs_t A) { uint32_t result = m_program->read_word(A); - return result | (m_program->read_word(A+2)<<16); + return result | (m_program->read_word(A+16)<<16); } #define TMS34010_WRMEM(A,V) (m_program->write_byte(A,V)) @@ -34,7 +34,7 @@ inline uint32_t tms340x0_device::TMS34010_RDMEM_DWORD(offs_t A) inline void tms340x0_device::TMS34010_WRMEM_DWORD(offs_t A, uint32_t V) { m_program->write_word(A,V); - m_program->write_word(A+2,V>>16); + m_program->write_word(A+16,V>>16); } @@ -52,36 +52,36 @@ inline void tms340x0_device::TMS34010_WRMEM_DWORD(offs_t A, uint32_t V) ***************************************************************************/ #define WFIELDMAC(MASK,MAX) \ - uint32_t shift = offset & 0x0f; \ - uint32_t masked_data = data & (MASK); \ - uint32_t old; \ + uint32_t shift = offset & 0x0f; \ + uint32_t masked_data = data & (MASK); \ + uint32_t old; \ \ - offset = TOBYTE(offset & 0xfffffff0); \ + offset = offset & 0xfffffff0; \ \ if (shift >= MAX) \ { \ - old = (uint32_t)TMS34010_RDMEM_DWORD(offset) & ~((MASK) << shift); \ + old = (uint32_t)TMS34010_RDMEM_DWORD(offset) & ~((MASK) << shift); \ TMS34010_WRMEM_DWORD(offset, (masked_data << shift) | old); \ } \ else \ { \ - old = (uint32_t)TMS34010_RDMEM_WORD(offset) & ~((MASK) << shift); \ + old = (uint32_t)TMS34010_RDMEM_WORD(offset) & ~((MASK) << shift); \ TMS34010_WRMEM_WORD(offset, ((masked_data & (MASK)) << shift) | old); \ } #define WFIELDMAC_BIG(MASK,MAX) \ - uint32_t shift = offset & 0x0f; \ - uint32_t masked_data = data & (MASK); \ - uint32_t old; \ + uint32_t shift = offset & 0x0f; \ + uint32_t masked_data = data & (MASK); \ + uint32_t old; \ \ - offset = TOBYTE(offset & 0xfffffff0); \ + offset = offset & 0xfffffff0; \ \ - old = (uint32_t)TMS34010_RDMEM_DWORD(offset) & ~(uint32_t)((MASK) << shift); \ - TMS34010_WRMEM_DWORD(offset, (uint32_t)(masked_data << shift) | old); \ + old = (uint32_t)TMS34010_RDMEM_DWORD(offset) & ~(uint32_t)((MASK) << shift); \ + TMS34010_WRMEM_DWORD(offset, (uint32_t)(masked_data << shift) | old); \ if (shift >= MAX) \ { \ shift = 32 - shift; \ - old = (uint32_t)TMS34010_RDMEM_WORD(offset + 4) & ~((MASK) >> shift); \ + old = (uint32_t)TMS34010_RDMEM_WORD(offset + 0x20) & ~((MASK) >> shift); \ TMS34010_WRMEM_WORD(offset, (masked_data >> shift) | old); \ } @@ -91,7 +91,7 @@ inline void tms340x0_device::TMS34010_WRMEM_DWORD(offs_t A, uint32_t V) WFIELDMAC(0xff,9); \ } \ else \ - TMS34010_WRMEM(TOBYTE(offset), data); + TMS34010_WRMEM(offset, data); #define RFIELDMAC_8() \ if (offset & 0x07) \ @@ -99,22 +99,22 @@ inline void tms340x0_device::TMS34010_WRMEM_DWORD(offs_t A, uint32_t V) RFIELDMAC(0xff,9); \ } \ else \ - return TMS34010_RDMEM(TOBYTE(offset)); + ret = TMS34010_RDMEM(offset); #define WFIELDMAC_32() \ if (offset & 0x0f) \ { \ - uint32_t shift = offset&0x0f; \ - uint32_t old; \ - uint32_t hiword; \ + uint32_t shift = offset&0x0f; \ + uint32_t old; \ + uint32_t hiword; \ offset &= 0xfffffff0; \ - old = ((uint32_t) TMS34010_RDMEM_DWORD (TOBYTE(offset ))&(0xffffffff>>(0x20-shift))); \ - hiword = ((uint32_t) TMS34010_RDMEM_DWORD (TOBYTE(offset+0x20))&(0xffffffff<<shift)); \ - TMS34010_WRMEM_DWORD(TOBYTE(offset ),(data<< shift) |old); \ - TMS34010_WRMEM_DWORD(TOBYTE(offset+0x20),(data>>(0x20-shift))|hiword); \ + old = ((uint32_t) TMS34010_RDMEM_DWORD (offset )&(0xffffffff>>(0x20-shift))); \ + hiword = ((uint32_t) TMS34010_RDMEM_DWORD (offset+0x20)&(0xffffffff<<shift)); \ + TMS34010_WRMEM_DWORD(offset ,(data<< shift) |old); \ + TMS34010_WRMEM_DWORD(offset+0x20,(data>>(0x20-shift))|hiword); \ } \ else \ - TMS34010_WRMEM_DWORD(TOBYTE(offset),data); + TMS34010_WRMEM_DWORD(offset,data); /*************************************************************************** @@ -122,33 +122,33 @@ inline void tms340x0_device::TMS34010_WRMEM_DWORD(offs_t A, uint32_t V) ***************************************************************************/ #define RFIELDMAC(MASK,MAX) \ - uint32_t shift = offset & 0x0f; \ - offset = TOBYTE(offset & 0xfffffff0); \ + uint32_t shift = offset & 0x0f; \ + offset = offset & 0xfffffff0; \ \ if (shift >= MAX) \ - ret = (TMS34010_RDMEM_DWORD(offset) >> shift) & (MASK); \ + ret = (TMS34010_RDMEM_DWORD(offset) >> shift) & (MASK); \ else \ ret = (TMS34010_RDMEM_WORD(offset) >> shift) & (MASK); #define RFIELDMAC_BIG(MASK,MAX) \ - uint32_t shift = offset & 0x0f; \ - offset = TOBYTE(offset & 0xfffffff0); \ + uint32_t shift = offset & 0x0f; \ + offset = offset & 0xfffffff0; \ \ - ret = (uint32_t)TMS34010_RDMEM_DWORD(offset) >> shift; \ + ret = (uint32_t)TMS34010_RDMEM_DWORD(offset) >> shift; \ if (shift >= MAX) \ - ret |= (TMS34010_RDMEM_WORD(offset + 4) << (32 - shift)); \ + ret |= (TMS34010_RDMEM_WORD(offset + 0x20) << (32 - shift)); \ ret &= MASK; #define RFIELDMAC_32() \ if (offset&0x0f) \ { \ - uint32_t shift = offset&0x0f; \ + uint32_t shift = offset&0x0f; \ offset &= 0xfffffff0; \ - return (((uint32_t)TMS34010_RDMEM_DWORD (TOBYTE(offset ))>> shift) | \ - (TMS34010_RDMEM_DWORD (TOBYTE(offset+0x20))<<(0x20-shift)));\ + return (((uint32_t)TMS34010_RDMEM_DWORD (offset )>> shift) | \ + (TMS34010_RDMEM_DWORD (offset+0x20)<<(0x20-shift))); \ } \ else \ - return TMS34010_RDMEM_DWORD(TOBYTE(offset)); + return TMS34010_RDMEM_DWORD(offset); #endif // MAME_CPU_TMS34010_34010OPS_H diff --git a/src/devices/cpu/tms34010/34010ops.hxx b/src/devices/cpu/tms34010/34010ops.hxx index 57b5cca536e..85a1b932747 100644 --- a/src/devices/cpu/tms34010/34010ops.hxx +++ b/src/devices/cpu/tms34010/34010ops.hxx @@ -80,13 +80,13 @@ void tms340x0_device::unimpl(uint16_t op) { /* kludge for Super High Impact -- this doesn't seem to cause */ /* an illegal opcode exception */ - if (m_direct->read_word(TOBYTE(m_pc - 0x10)) == 0x0007) + if (m_direct->read_word(m_pc - 0x10) == 0x0007) return; /* 9 Ball Shootout calls to FFDF7468, expecting it */ /* to execute the next instruction from FFDF7470 */ /* but the instruction at FFDF7460 is an 0x0001 */ - if (m_direct->read_word(TOBYTE(m_pc - 0x10)) == 0x0001) + if (m_direct->read_word(m_pc - 0x10) == 0x0001) return; PUSH(m_pc); @@ -96,7 +96,7 @@ void tms340x0_device::unimpl(uint16_t op) COUNT_UNKNOWN_CYCLES(16); /* extra check to prevent bad things */ - if (m_pc == 0 || s_opcode_table[m_direct->read_word(TOBYTE(m_pc)) >> 4] == &tms34010_device::unimpl) + if (m_pc == 0 || s_opcode_table[m_direct->read_word(m_pc) >> 4] == &tms34010_device::unimpl) { set_input_line(INPUT_LINE_HALT, ASSERT_LINE); machine().debug_break(); @@ -2055,7 +2055,7 @@ void tms340x0_device::blmove(uint16_t op) { while (bits >= 16 && m_icount > 0) { - TMS34010_WRMEM_WORD(TOBYTE(dst), TMS34010_RDMEM_WORD(TOBYTE(src))); + TMS34010_WRMEM_WORD(dst, TMS34010_RDMEM_WORD(src)); src += 0x10; dst += 0x10; bits -= 0x10; diff --git a/src/devices/cpu/tms34010/dis34010.cpp b/src/devices/cpu/tms34010/dis34010.cpp deleted file mode 100644 index 01aebd4a6f1..00000000000 --- a/src/devices/cpu/tms34010/dis34010.cpp +++ /dev/null @@ -1,115 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Zsolt Vasvari -/* This program is based on DIS68k by Aaron Giles */ - -#include "emu.h" - -static uint8_t *filebuf; -static uint32_t offset; - -#define STANDALONE -#include "34010dsm.c" - - -static const char *const Options[]= -{ - "begin","end","offset",0 -}; - -static void usage (void) -{ - printf ("Usage: DIS34010 [options] <filename>\n" - "Available options are:\n" - " -begin - Specify begin offset in file to disassemble in bits [0]\n" - " -end - Specify end offset in file to disassemble in bits [none]\n" - " -offset - Specify address to load program in bits [0]\n" - "All values should be entered in hexadecimal\n"); - exit (1); -} - -int main (int argc,char *argv[]) -{ - uint8_t i,j,n; - char *filename=0,buf[80]; - FILE *f; - uint32_t begin=0,end=(uint32_t)-1,filelen,len,pc; - printf ("DIS34010\n" - "Copyright Zsolt Vasvari/Aaron Giles\n"); - - for (i=1,n=0;i<argc;++i) - { - if (argv[i][0]!='-') - { - switch (++n) - { - case 1: filename=argv[i]; break; - default: usage(); - } - } - else - { - for (j=0;Options[j];++j) - if (!strcmp(argv[i]+1,Options[j])) break; - - switch (j) - { - case 0: ++i; if (i>argc) usage(); - begin=strtoul(argv[i],0,16) >> 3; - break; - case 1: ++i; if (i>argc) usage(); - end=strtoul(argv[i],0,16) >> 3; - break; - case 2: ++i; if (i>argc) usage(); - offset=strtoul(argv[i],0,16) >> 3; - break; - default: usage(); - } - } - } - - if (!filename) - { - usage(); - return 1; - } - f=fopen (filename,"rb"); - if (!f) - { - printf ("Unable to open %s\n",filename); - return 2; - } - fseek (f,0,SEEK_END); - filelen=ftell (f); - fseek (f,begin,SEEK_SET); - len=(filelen>end)? (end-begin+1):(filelen-begin); - filebuf=malloc(len+16); - if (!filebuf) - { - printf ("Memory allocation error\n"); - fclose (f); - return 3; - } - memset (filebuf,0,len+16); - if (fread(filebuf,1,len,f)!=len) - { - printf ("Read error\n"); - fclose (f); - free (filebuf); - return 4; - } - fclose (f); - pc=0; - while (pc<len-1) - { - i=(Dasm34010 (buf,pc<<3))>>3; - - printf ("%08X: ",(pc+offset) << 3); - for (j=0;j<i ;++j) printf("%02X ",filebuf[pc+j]); - for ( ;j<10;++j) printf(" "); - printf(buf); - printf ("\n"); - pc+=i; - } - free (filebuf); - return 0; -} diff --git a/src/devices/cpu/tms34010/tms34010.cpp b/src/devices/cpu/tms34010/tms34010.cpp index d442a2a2feb..770777b03fb 100644 --- a/src/devices/cpu/tms34010/tms34010.cpp +++ b/src/devices/cpu/tms34010/tms34010.cpp @@ -11,6 +11,7 @@ #include "emu.h" #include "tms34010.h" +#include "34010dsm.h" #include "debugger.h" #include "screen.h" @@ -179,34 +180,34 @@ inline void tms340x0_device::RESET_ST() /* shortcuts for reading opcodes */ inline uint32_t tms340x0_device::ROPCODE() { - uint32_t pc = TOBYTE(m_pc); + uint32_t pc = m_pc; m_pc += 2 << 3; return m_direct->read_word(pc); } inline int16_t tms340x0_device::PARAM_WORD() { - uint32_t pc = TOBYTE(m_pc); + uint32_t pc = m_pc; m_pc += 2 << 3; return m_direct->read_word(pc); } inline int32_t tms340x0_device::PARAM_LONG() { - uint32_t pc = TOBYTE(m_pc); + uint32_t pc = m_pc; m_pc += 4 << 3; - return (uint16_t)m_direct->read_word(pc) | (m_direct->read_word(pc + 2) << 16); + return (uint16_t)m_direct->read_word(pc) | (m_direct->read_word(pc + 16) << 16); } inline int16_t tms340x0_device::PARAM_WORD_NO_INC() { - return m_direct->read_word(TOBYTE(m_pc)); + return m_direct->read_word(m_pc); } inline int32_t tms340x0_device::PARAM_LONG_NO_INC() { - uint32_t pc = TOBYTE(m_pc); - return (uint16_t)m_direct->read_word(pc) | (m_direct->read_word(pc + 2) << 16); + uint32_t pc = m_pc; + return (uint16_t)m_direct->read_word(pc) | (m_direct->read_word(pc + 16) << 16); } /* read memory byte */ @@ -257,7 +258,7 @@ inline int32_t tms340x0_device::POP() #define RP(m1,m2) \ /* TODO: Plane masking */ \ - return (TMS34010_RDMEM_WORD(TOBYTE(offset & 0xfffffff0)) >> (offset & m1)) & m2; + return (TMS34010_RDMEM_WORD(offset & 0xfffffff0) >> (offset & m1)) & m2; uint32_t tms340x0_device::read_pixel_1(offs_t offset) { RP(0x0f,0x01) } uint32_t tms340x0_device::read_pixel_2(offs_t offset) { RP(0x0e,0x03) } @@ -266,12 +267,12 @@ uint32_t tms340x0_device::read_pixel_8(offs_t offset) { RP(0x08,0xff) } uint32_t tms340x0_device::read_pixel_16(offs_t offset) { /* TODO: Plane masking */ - return TMS34010_RDMEM_WORD(TOBYTE(offset & 0xfffffff0)); + return TMS34010_RDMEM_WORD(offset & 0xfffffff0); } uint32_t tms340x0_device::read_pixel_32(offs_t offset) { /* TODO: Plane masking */ - return TMS34010_RDMEM_DWORD(TOBYTE(offset & 0xffffffe0)); + return TMS34010_RDMEM_DWORD(offset & 0xffffffe0); } /* Shift register read */ @@ -292,9 +293,9 @@ uint32_t tms340x0_device::read_pixel_shiftreg(offs_t offset) /* No Raster Op + No Transparency */ #define WP(m1,m2) \ - uint32_t a = TOBYTE(offset & 0xfffffff0); \ - uint32_t pix = TMS34010_RDMEM_WORD(a); \ - uint32_t shiftcount = offset & m1; \ + uint32_t a = offset & 0xfffffff0; \ + uint32_t pix = TMS34010_RDMEM_WORD(a); \ + uint32_t shiftcount = offset & m1; \ \ /* TODO: plane masking */ \ data &= m2; \ @@ -307,9 +308,9 @@ uint32_t tms340x0_device::read_pixel_shiftreg(offs_t offset) data &= m2; \ if (data) \ { \ - uint32_t a = TOBYTE(offset & 0xfffffff0); \ - uint32_t pix = TMS34010_RDMEM_WORD(a); \ - uint32_t shiftcount = offset & m1; \ + uint32_t a = offset & 0xfffffff0; \ + uint32_t pix = TMS34010_RDMEM_WORD(a); \ + uint32_t shiftcount = offset & m1; \ \ /* TODO: plane masking */ \ pix = (pix & ~(m2 << shiftcount)) | (data << shiftcount); \ @@ -317,9 +318,9 @@ uint32_t tms340x0_device::read_pixel_shiftreg(offs_t offset) } /* Raster Op + No Transparency */ #define WP_R(m1,m2) \ - uint32_t a = TOBYTE(offset & 0xfffffff0); \ - uint32_t pix = TMS34010_RDMEM_WORD(a); \ - uint32_t shiftcount = offset & m1; \ + uint32_t a = offset & 0xfffffff0; \ + uint32_t pix = TMS34010_RDMEM_WORD(a); \ + uint32_t shiftcount = offset & m1; \ \ /* TODO: plane masking */ \ data = (this->*m_raster_op)(data & m2, (pix >> shiftcount) & m2) & m2; \ @@ -328,9 +329,9 @@ uint32_t tms340x0_device::read_pixel_shiftreg(offs_t offset) /* Raster Op + Transparency */ #define WP_R_T(m1,m2) \ - uint32_t a = TOBYTE(offset & 0xfffffff0); \ - uint32_t pix = TMS34010_RDMEM_WORD(a); \ - uint32_t shiftcount = offset & m1; \ + uint32_t a = offset & 0xfffffff0; \ + uint32_t pix = TMS34010_RDMEM_WORD(a); \ + uint32_t shiftcount = offset & m1; \ \ /* TODO: plane masking */ \ data = (this->*m_raster_op)(data & m2, (pix >> shiftcount) & m2) & m2; \ @@ -348,12 +349,12 @@ void tms340x0_device::write_pixel_8(offs_t offset, uint32_t data) { WP(0x08, 0xf void tms340x0_device::write_pixel_16(offs_t offset, uint32_t data) { /* TODO: plane masking */ - TMS34010_WRMEM_WORD(TOBYTE(offset & 0xfffffff0), data); + TMS34010_WRMEM_WORD(offset & 0xfffffff0, data); } void tms340x0_device::write_pixel_32(offs_t offset, uint32_t data) { /* TODO: plane masking */ - TMS34010_WRMEM_WORD(TOBYTE(offset & 0xffffffe0), data); + TMS34010_WRMEM_WORD(offset & 0xffffffe0, data); } /* No Raster Op + Transparency */ @@ -365,13 +366,13 @@ void tms340x0_device::write_pixel_t_16(offs_t offset, uint32_t data) { /* TODO: plane masking */ if (data) - TMS34010_WRMEM_WORD(TOBYTE(offset & 0xfffffff0), data); + TMS34010_WRMEM_WORD(offset & 0xfffffff0, data); } void tms340x0_device::write_pixel_t_32(offs_t offset, uint32_t data) { /* TODO: plane masking */ if (data) - TMS34010_WRMEM_DWORD(TOBYTE(offset & 0xffffffe0), data); + TMS34010_WRMEM_DWORD(offset & 0xffffffe0, data); } /* Raster Op + No Transparency */ @@ -382,13 +383,13 @@ void tms340x0_device::write_pixel_r_8(offs_t offset, uint32_t data) { WP_R(0x08, void tms340x0_device::write_pixel_r_16(offs_t offset, uint32_t data) { /* TODO: plane masking */ - uint32_t a = TOBYTE(offset & 0xfffffff0); + uint32_t a = offset & 0xfffffff0; TMS34010_WRMEM_WORD(a, (this->*m_raster_op)(data, TMS34010_RDMEM_WORD(a))); } void tms340x0_device::write_pixel_r_32(offs_t offset, uint32_t data) { /* TODO: plane masking */ - uint32_t a = TOBYTE(offset & 0xffffffe0); + uint32_t a = offset & 0xffffffe0; TMS34010_WRMEM_DWORD(a, (this->*m_raster_op)(data, TMS34010_RDMEM_DWORD(a))); } @@ -400,7 +401,7 @@ void tms340x0_device::write_pixel_r_t_8(offs_t offset, uint32_t data) { WP_R_T(0 void tms340x0_device::write_pixel_r_t_16(offs_t offset, uint32_t data) { /* TODO: plane masking */ - uint32_t a = TOBYTE(offset & 0xfffffff0); + uint32_t a = offset & 0xfffffff0; data = (this->*m_raster_op)(data, TMS34010_RDMEM_WORD(a)); if (data) @@ -409,7 +410,7 @@ void tms340x0_device::write_pixel_r_t_16(offs_t offset, uint32_t data) void tms340x0_device::write_pixel_r_t_32(offs_t offset, uint32_t data) { /* TODO: plane masking */ - uint32_t a = TOBYTE(offset & 0xffffffe0); + uint32_t a = offset & 0xffffffe0; data = (this->*m_raster_op)(data, TMS34010_RDMEM_DWORD(a)); if (data) @@ -587,7 +588,7 @@ void tms340x0_device::device_start() m_external_host_access = false; m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<03>(); /* set up the state table */ { @@ -1511,7 +1512,7 @@ WRITE16_MEMBER( tms340x0_device::host_w ) /* write to the address */ addr = (IOREG(REG_HSTADRH) << 16) | IOREG(REG_HSTADRL); - TMS34010_WRMEM_WORD(TOBYTE(addr & 0xfffffff0), data); + TMS34010_WRMEM_WORD(addr & 0xfffffff0, data); /* optional postincrement */ if (IOREG(REG_HSTCTLH) & 0x0800) @@ -1570,7 +1571,7 @@ READ16_MEMBER( tms340x0_device::host_r ) /* read from the address */ addr = (IOREG(REG_HSTADRH) << 16) | IOREG(REG_HSTADRL); - result = TMS34010_RDMEM_WORD(TOBYTE(addr & 0xfffffff0)); + result = TMS34010_RDMEM_WORD(addr & 0xfffffff0); /* optional postincrement (it says preincrement, but data is preloaded, so it is effectively a postincrement */ @@ -1625,18 +1626,12 @@ void tms340x0_device::state_string_export(const device_state_entry &entry, std:: } } - -offs_t tms34010_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *tms34010_device::create_disassembler() { - extern CPU_DISASSEMBLE( tms34010 ); - - return CPU_DISASSEMBLE_NAME(tms34010)(this, stream, pc, oprom, opram, options); + return new tms34010_disassembler(false); } - -offs_t tms34020_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *tms34020_device::create_disassembler() { - extern CPU_DISASSEMBLE( tms34020 ); - - return CPU_DISASSEMBLE_NAME(tms34020)(this, stream, pc, oprom, opram, options); + return new tms34010_disassembler(true); } diff --git a/src/devices/cpu/tms34010/tms34010.h b/src/devices/cpu/tms34010/tms34010.h index 9846d69625a..0f9c3a27a57 100644 --- a/src/devices/cpu/tms34010/tms34010.h +++ b/src/devices/cpu/tms34010/tms34010.h @@ -276,10 +276,6 @@ protected: // device_state_interface overrides virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; - // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 10; } - typedef void (tms340x0_device::*pixel_write_func)(offs_t offset, uint32_t data); typedef uint32_t (tms340x0_device::*pixel_read_func)(offs_t offset); typedef uint32_t (tms340x0_device::*raster_op_func)(uint32_t newpix, uint32_t oldpix); @@ -327,7 +323,7 @@ protected: uint8_t m_external_host_access; uint8_t m_executing; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<3> *m_direct; uint32_t m_pixclock; /* the pixel clock (0 means don't adjust screen size) */ int m_pixperclock; /* pixels per clock */ emu_timer *m_scantimer; @@ -1025,7 +1021,7 @@ public: protected: virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const override { return (clocks + 8 - 1) / 8; } virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const override { return (cycles * 8); } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; }; DECLARE_DEVICE_TYPE(TMS34010, tms34010_device) @@ -1042,7 +1038,7 @@ public: protected: virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const override { return (clocks + 4 - 1) / 4; } virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const override { return (cycles * 4); } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; }; DECLARE_DEVICE_TYPE(TMS34020, tms34020_device) @@ -1055,12 +1051,4 @@ DECLARE_DEVICE_TYPE(TMS34020, tms34020_device) #define TMS34010_HOST_DATA 2 #define TMS34010_HOST_CONTROL 3 -/* Use this macro in the memory definitions to specify bit-based addresses */ -#define TOBYTE(bitaddr) ((offs_t)(bitaddr) >> 3) -#define TOWORD(bitaddr) ((offs_t)(bitaddr) >> 4) - - -CPU_DISASSEMBLE( tms34010 ); -CPU_DISASSEMBLE( tms34020 ); - #endif // MAME_CPU_TMS34010_TMS34010_H diff --git a/src/devices/cpu/tms57002/57002dsm.cpp b/src/devices/cpu/tms57002/57002dsm.cpp index 0f92c9af145..b8d03ab8172 100644 --- a/src/devices/cpu/tms57002/57002dsm.cpp +++ b/src/devices/cpu/tms57002/57002dsm.cpp @@ -9,10 +9,13 @@ ***************************************************************************/ #include "emu.h" -#include "debugger.h" -#include "tms57002.h" +#include "57002dsm.h" -static std::string get_memadr(uint32_t opcode, char type) +tms57002_disassembler::tms57002_disassembler() +{ +} + +std::string tms57002_disassembler::get_memadr(uint32_t opcode, char type) { std::string buf; @@ -30,11 +33,15 @@ static std::string get_memadr(uint32_t opcode, char type) return buf; } +u32 tms57002_disassembler::opcode_alignment() const +{ + return 1; +} -CPU_DISASSEMBLE(tms57002) +offs_t tms57002_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { std::streampos original_pos = stream.tellp(); - uint32_t opcode = opram[0] | (opram[1] << 8) | (opram[2] << 16); + uint32_t opcode = opcodes.r32(pc); uint8_t fa = opcode >> 18; if(fa == 0x3f) { switch((opcode >> 11) & 0x7f) { // category 3 diff --git a/src/devices/cpu/tms57002/57002dsm.h b/src/devices/cpu/tms57002/57002dsm.h new file mode 100644 index 00000000000..56ed3d0ea25 --- /dev/null +++ b/src/devices/cpu/tms57002/57002dsm.h @@ -0,0 +1,30 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + 57002dsm.c + + TMS57002 "DASP" emulator. + +***************************************************************************/ + +#ifndef MAME_CPU_TMS57002_57002DSM_H +#define MAME_CPU_TMS57002_57002DSM_H + +#pragma once + +class tms57002_disassembler : public util::disasm_interface +{ +public: + tms57002_disassembler(); + virtual ~tms57002_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static std::string get_memadr(uint32_t opcode, char type); + +}; + +#endif diff --git a/src/devices/cpu/tms57002/tms57002.cpp b/src/devices/cpu/tms57002/tms57002.cpp index 4b88669298b..f98e0497acf 100644 --- a/src/devices/cpu/tms57002/tms57002.cpp +++ b/src/devices/cpu/tms57002/tms57002.cpp @@ -11,6 +11,7 @@ #include "emu.h" #include "tms57002.h" #include "debugger.h" +#include "57002dsm.h" DEFINE_DEVICE_TYPE(TMS57002, tms57002_device, "tms57002", "TMS57002") @@ -29,6 +30,10 @@ tms57002_device::tms57002_device(const machine_config &mconfig, const char *tag, { } +util::disasm_interface *tms57002_device::create_disassembler() +{ + return new tms57002_disassembler; +} WRITE_LINE_MEMBER(tms57002_device::pload_w) { @@ -103,7 +108,7 @@ WRITE8_MEMBER(tms57002_device::data_w) sti = (sti & ~SU_MASK) | SU_PRG; break; case SU_PRG: - program->write_dword(pc++ << 2, val); + program->write_dword(pc++, val); break; } } @@ -684,7 +689,7 @@ int tms57002_device::decode_get_pc() for(;;) { short ipc; - uint32_t opcode = program->read_dword(adr << 2); + uint32_t opcode = program->read_dword(adr); cs.inc = 0; @@ -892,22 +897,6 @@ uint32_t tms57002_device::execute_input_lines() const return 0; } -uint32_t tms57002_device::disasm_min_opcode_bytes() const -{ - return 4; -} - -uint32_t tms57002_device::disasm_max_opcode_bytes() const -{ - return 4; -} - -offs_t tms57002_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) -{ - extern CPU_DISASSEMBLE( tms57002 ); - return CPU_DISASSEMBLE_NAME(tms57002)(this, stream, pc, oprom, opram, options); -} - device_memory_interface::space_config_vector tms57002_device::memory_space_config() const { return space_config_vector { diff --git a/src/devices/cpu/tms57002/tms57002.h b/src/devices/cpu/tms57002/tms57002.h index 361c0b8a7d8..120af046362 100644 --- a/src/devices/cpu/tms57002/tms57002.h +++ b/src/devices/cpu/tms57002/tms57002.h @@ -35,9 +35,7 @@ protected: virtual uint32_t execute_max_cycles() const override; virtual uint32_t execute_input_lines() const override; virtual void execute_run() override; - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: enum { diff --git a/src/devices/cpu/tms57002/tms57kdec.cpp b/src/devices/cpu/tms57002/tms57kdec.cpp index b3b71cb58e4..8cca7ba825f 100644 --- a/src/devices/cpu/tms57002/tms57kdec.cpp +++ b/src/devices/cpu/tms57002/tms57kdec.cpp @@ -72,18 +72,11 @@ inline int tms57002_device::sfma(uint32_t st1) void tms57002_device::decode_error(uint32_t opcode) { - uint8_t opr[3]; if(unsupported_inst_warning) return; unsupported_inst_warning = 1; - opr[0] = opcode; - opr[1] = opcode >> 8; - opr[2] = opcode >> 16; - - std::stringstream stream; - disasm_disassemble(stream, pc, opr, opr, 0); - popmessage("tms57002: %s - Contact Mamedev", stream.str()); + popmessage("tms57002: %06x - Contact Mamedev", opcode); } void tms57002_device::decode_cat1(uint32_t opcode, unsigned short *op, cstate *cs) diff --git a/src/devices/cpu/tms7000/7000dasm.cpp b/src/devices/cpu/tms7000/7000dasm.cpp index 1f7f8549852..000c7ea2ea3 100644 --- a/src/devices/cpu/tms7000/7000dasm.cpp +++ b/src/devices/cpu/tms7000/7000dasm.cpp @@ -7,24 +7,9 @@ */ #include "emu.h" -#include "debugger.h" -#include "tms7000.h" +#include "7000dasm.h" -enum operandtype { DONE, NONE, UI8, I8, UI16, I16, PCREL, PCABS, TRAP }; - -struct oprandinfo { - char opstr[4][12]; - operandtype decode[4]; -}; - -struct tms7000_opcodeinfo { - int opcode; - char name[8]; - int operand; - uint32_t s_flag; -}; - -static const oprandinfo of[] = { +const tms7000_disassembler::oprandinfo tms7000_disassembler::of[] = { /* 00 */ { {" B,A", "", "", ""}, {NONE, DONE, DONE, DONE} }, /* 01 */ { {" R%u", ",A", "", ""}, {UI8, NONE, DONE, DONE} }, /* 02 */ { {" R%u", ",B", "", ""}, {UI8, NONE, DONE, DONE} }, @@ -84,7 +69,7 @@ static const oprandinfo of[] = { /* 45 */ { {" *R%u", "", "", ""}, {UI8, DONE, DONE, DONE} } }; -static const tms7000_opcodeinfo opcodes[] = { +const tms7000_disassembler::tms7000_opcodeinfo tms7000_disassembler::opcs[] = { {0x69, "ADC", 0, 0 }, {0x19, "ADC", 1, 0 }, {0x39, "ADC", 2, 0 }, @@ -141,9 +126,9 @@ static const tms7000_opcodeinfo opcodes[] = { {0x97, "BTJZP", 21, 0 }, {0xA7, "BTJZP", 22, 0 }, - {0x8E, "CALL", 43, DASMFLAG_STEP_OVER }, - {0x9E, "CALL", 45, DASMFLAG_STEP_OVER }, - {0xAE, "CALL", 12, DASMFLAG_STEP_OVER }, + {0x8E, "CALL", 43, STEP_OVER }, + {0x9E, "CALL", 45, STEP_OVER }, + {0xAE, "CALL", 12, STEP_OVER }, {0xB5, "CLR A", 23, 0 }, {0xC5, "CLR B", 23, 0 }, @@ -273,8 +258,8 @@ static const tms7000_opcodeinfo opcodes[] = { {0xD8, "PUSH", 24, 0 }, {0x0E, "PUSH ST", 23, 0 }, - {0x0B, "RETI", 23, DASMFLAG_STEP_OUT }, - {0x0A, "RETS", 23, DASMFLAG_STEP_OUT }, + {0x0B, "RETI", 23, STEP_OUT }, + {0x0A, "RETS", 23, STEP_OUT }, {0xBE, "RL A", 23, 0 }, {0xCE, "RL B", 23, 0 }, @@ -316,30 +301,30 @@ static const tms7000_opcodeinfo opcodes[] = { {0x5A, "SUB", 5, 0 }, {0x7A, "SUB", 6, 0 }, - {0xFF, "TRAP 0", 44, DASMFLAG_STEP_OVER }, - {0xFE, "TRAP 1", 44, DASMFLAG_STEP_OVER }, - {0xFD, "TRAP 2", 44, DASMFLAG_STEP_OVER }, - {0xFC, "TRAP 3", 44, DASMFLAG_STEP_OVER }, - {0xFB, "TRAP 4", 44, DASMFLAG_STEP_OVER }, - {0xFA, "TRAP 5", 44, DASMFLAG_STEP_OVER }, - {0xF9, "TRAP 6", 44, DASMFLAG_STEP_OVER }, - {0xF8, "TRAP 7", 44, DASMFLAG_STEP_OVER }, - {0xF7, "TRAP 8", 44, DASMFLAG_STEP_OVER }, - {0xF6, "TRAP 9", 44, DASMFLAG_STEP_OVER }, - {0xF5, "TRAP 10", 44, DASMFLAG_STEP_OVER }, - {0xF4, "TRAP 11", 44, DASMFLAG_STEP_OVER }, - {0xF3, "TRAP 12", 44, DASMFLAG_STEP_OVER }, - {0xF2, "TRAP 13", 44, DASMFLAG_STEP_OVER }, - {0xF1, "TRAP 14", 44, DASMFLAG_STEP_OVER }, - {0xF0, "TRAP 15", 44, DASMFLAG_STEP_OVER }, - {0xEF, "TRAP 16", 44, DASMFLAG_STEP_OVER }, - {0xEE, "TRAP 17", 44, DASMFLAG_STEP_OVER }, - {0xED, "TRAP 18", 44, DASMFLAG_STEP_OVER }, - {0xEC, "TRAP 19", 44, DASMFLAG_STEP_OVER }, - {0xEB, "TRAP 20", 44, DASMFLAG_STEP_OVER }, - {0xEA, "TRAP 21", 44, DASMFLAG_STEP_OVER }, - {0xE9, "TRAP 22", 44, DASMFLAG_STEP_OVER }, - {0xE8, "TRAP 23", 44, DASMFLAG_STEP_OVER }, + {0xFF, "TRAP 0", 44, STEP_OVER }, + {0xFE, "TRAP 1", 44, STEP_OVER }, + {0xFD, "TRAP 2", 44, STEP_OVER }, + {0xFC, "TRAP 3", 44, STEP_OVER }, + {0xFB, "TRAP 4", 44, STEP_OVER }, + {0xFA, "TRAP 5", 44, STEP_OVER }, + {0xF9, "TRAP 6", 44, STEP_OVER }, + {0xF8, "TRAP 7", 44, STEP_OVER }, + {0xF7, "TRAP 8", 44, STEP_OVER }, + {0xF6, "TRAP 9", 44, STEP_OVER }, + {0xF5, "TRAP 10", 44, STEP_OVER }, + {0xF4, "TRAP 11", 44, STEP_OVER }, + {0xF3, "TRAP 12", 44, STEP_OVER }, + {0xF2, "TRAP 13", 44, STEP_OVER }, + {0xF1, "TRAP 14", 44, STEP_OVER }, + {0xF0, "TRAP 15", 44, STEP_OVER }, + {0xEF, "TRAP 16", 44, STEP_OVER }, + {0xEE, "TRAP 17", 44, STEP_OVER }, + {0xED, "TRAP 18", 44, STEP_OVER }, + {0xEC, "TRAP 19", 44, STEP_OVER }, + {0xEB, "TRAP 20", 44, STEP_OVER }, + {0xEA, "TRAP 21", 44, STEP_OVER }, + {0xE9, "TRAP 22", 44, STEP_OVER }, + {0xE8, "TRAP 23", 44, STEP_OVER }, {0xB7, "SWAP A", 23, 0 }, {0xC7, "SWAP B", 23, 0 }, @@ -367,17 +352,22 @@ static const tms7000_opcodeinfo opcodes[] = { {0x00, "NOP", 23, 0 } }; -CPU_DISASSEMBLE(tms7000) +u32 tms7000_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t tms7000_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { int opcode, i/*, size = 1*/; - int pos = 0; + offs_t pos = pc; char tmpbuf[32]; - opcode = oprom[pos++]; + opcode = opcodes.r8(pos++); - for( i=0; i<sizeof(opcodes) / sizeof(tms7000_opcodeinfo); i++ ) + for( i=0; i<sizeof(opcs) / sizeof(tms7000_opcodeinfo); i++ ) { - if( opcode == opcodes[i].opcode ) + if( opcode == opcs[i].opcode ) { /* We found a match */ @@ -387,9 +377,9 @@ CPU_DISASSEMBLE(tms7000) uint16_t c; int16_t d; - util::stream_format(stream, "%s", opcodes[i].name); + util::stream_format(stream, "%s", opcs[i].name); - j=opcodes[i].operand; + j=opcs[i].operand; for( k=0; k<4; k++ ) { @@ -401,34 +391,34 @@ CPU_DISASSEMBLE(tms7000) util::stream_format(stream, "%s", of[j].opstr[k]); break; case UI8: - a = (uint8_t)opram[pos++]; + a = (uint8_t)params.r8(pos++); util::stream_format(stream, of[j].opstr[k], (unsigned int)a); break; case I8: - b = (int8_t)opram[pos++]; + b = (int8_t)params.r8(pos++); util::stream_format(stream, of[j].opstr[k], (int8_t)b); break; case UI16: - c = (uint16_t)opram[pos++]; + c = (uint16_t)params.r8(pos++); c <<= 8; - c += opram[pos++]; + c += params.r8(pos++); util::stream_format(stream, of[j].opstr[k], (unsigned int)c); break; case I16: - d = (int16_t)opram[pos++]; + d = (int16_t)params.r8(pos++); d <<= 8; - d += opram[pos++]; + d += params.r8(pos++); util::stream_format(stream, of[j].opstr[k], (signed int)d); break; case PCREL: - b = (int8_t)opram[pos++]; + b = (int8_t)params.r8(pos++); sprintf(tmpbuf, "$%04X", pc+2+k+b); util::stream_format(stream, of[j].opstr[k], tmpbuf); break; case PCABS: - c = (uint16_t)opram[pos++]; + c = (uint16_t)params.r8(pos++); c <<= 8; - c += opram[pos++]; + c += params.r8(pos++); sprintf(tmpbuf, "$%04X", c); util::stream_format(stream, of[j].opstr[k], tmpbuf); break; @@ -438,11 +428,11 @@ CPU_DISASSEMBLE(tms7000) break; } } - return pos | opcodes[i].s_flag | DASMFLAG_SUPPORTED; + return (pos - pc) | opcs[i].s_flag | SUPPORTED; } } /* No Match */ stream << "Illegal Opcode"; - return pos | DASMFLAG_SUPPORTED; + return (pos - pc) | SUPPORTED; } diff --git a/src/devices/cpu/tms7000/7000dasm.h b/src/devices/cpu/tms7000/7000dasm.h new file mode 100644 index 00000000000..70c01e59fe6 --- /dev/null +++ b/src/devices/cpu/tms7000/7000dasm.h @@ -0,0 +1,42 @@ +// license:BSD-3-Clause +// copyright-holders:Tim Lindner +/* + + TMS7000 disassembler + +*/ + +#ifndef MAME_CPU_TMS7000_7000DASM_H +#define MAME_CPU_TMS7000_7000DASM_H + +#pragma once + +class tms7000_disassembler : public util::disasm_interface +{ +public: + tms7000_disassembler() = default; + virtual ~tms7000_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum operandtype { DONE, NONE, UI8, I8, UI16, I16, PCREL, PCABS, TRAP }; + + struct oprandinfo { + char opstr[4][12]; + operandtype decode[4]; + }; + + struct tms7000_opcodeinfo { + int opcode; + char name[8]; + int operand; + uint32_t s_flag; + }; + + static const oprandinfo of[]; + static const tms7000_opcodeinfo opcs[]; +}; + +#endif diff --git a/src/devices/cpu/tms7000/tms7000.cpp b/src/devices/cpu/tms7000/tms7000.cpp index a54bac9e20f..25265218735 100644 --- a/src/devices/cpu/tms7000/tms7000.cpp +++ b/src/devices/cpu/tms7000/tms7000.cpp @@ -19,6 +19,7 @@ #include "emu.h" #include "tms7000.h" +#include "7000dasm.h" // TMS7000 is the most basic one, 128 bytes internal RAM and no internal ROM. // TMS7020 and TMS7040 are same, but with 2KB and 4KB internal ROM respectively. @@ -51,10 +52,6 @@ DEFINE_DEVICE_TYPE(TMS70C46, tms70c46_device, "tms70c46", "TMC70C46") // internal memory maps -static ADDRESS_MAP_START(tms7000_io, AS_IO, 8, tms7000_device) - AM_RANGE(TMS7000_PORTB, TMS7000_PORTB) AM_READNOP -ADDRESS_MAP_END - static ADDRESS_MAP_START(tms7000_mem, AS_PROGRAM, 8, tms7000_device ) AM_RANGE(0x0000, 0x007f) AM_RAM // 128 bytes internal RAM AM_RANGE(0x0080, 0x00ff) AM_READWRITE(tms7000_unmapped_rf_r, tms7000_unmapped_rf_w) @@ -114,7 +111,8 @@ tms7000_device::tms7000_device(const machine_config &mconfig, const char *tag, d tms7000_device::tms7000_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor internal, uint32_t info_flags) : cpu_device(mconfig, type, tag, owner, clock), m_program_config("program", ENDIANNESS_BIG, 8, 16, 0, internal), - m_io_config("io", ENDIANNESS_BIG, 8, 8, 0, ADDRESS_MAP_NAME(tms7000_io)), + m_port_in_cb{{*this}, {*this}, {*this}, {*this}, {*this}}, + m_port_out_cb{{*this}, {*this}, {*this}, {*this}, {*this}}, m_info_flags(info_flags) { } @@ -177,8 +175,7 @@ tms70c46_device::tms70c46_device(const machine_config &mconfig, const char *tag, device_memory_interface::space_config_vector tms7000_device::memory_space_config() const { return space_config_vector { - std::make_pair(AS_PROGRAM, &m_program_config), - std::make_pair(AS_IO, &m_io_config) + std::make_pair(AS_PROGRAM, &m_program_config) }; } @@ -191,14 +188,18 @@ void tms7000_device::device_start() { // init/zerofill m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); - m_io = &space(AS_IO); + m_direct = m_program->direct<0>(); m_icountptr = &m_icount; m_irq_state[TMS7000_INT1_LINE] = false; m_irq_state[TMS7000_INT3_LINE] = false; + for (auto &cb : m_port_in_cb) + cb.resolve_safe(0xff); + for (auto &cb : m_port_out_cb) + cb.resolve_safe(); + m_idle_state = false; m_idle_halt = false; m_pc = 0; @@ -273,10 +274,9 @@ void tms7000_device::state_string_export(const device_state_entry &entry, std::s } } -offs_t tms7000_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *tms7000_device::create_disassembler() { - extern CPU_DISASSEMBLE( tms7000 ); - return CPU_DISASSEMBLE_NAME(tms7000)(this, stream, pc, oprom, opram, options); + return new tms7000_disassembler; } @@ -512,7 +512,7 @@ READ8_MEMBER(tms7000_device::tms7000_pf_r) // note: port B is write-only, reading it returns the output value as if ddr is 0xff int port = offset / 2 - 2; if (!machine().side_effect_disabled()) - return (m_io->read_byte(port) & ~m_port_ddr[port]) | (m_port_latch[port] & m_port_ddr[port]); + return (m_port_in_cb[port]() & ~m_port_ddr[port]) | (m_port_latch[port] & m_port_ddr[port]); break; } @@ -594,7 +594,7 @@ WRITE8_MEMBER(tms7000_device::tms7000_pf_w) // note: in memory expansion modes, some port output pins are used for memory strobes. // this is currently ignored, since port writes will always be visible externally on peripheral expansion anyway. int port = offset / 2 - 2; - m_io->write_byte(port, data & m_port_ddr[port]); + m_port_out_cb[port](data & m_port_ddr[port]); m_port_latch[port] = data; break; } @@ -888,7 +888,9 @@ void tms70c46_device::device_start() void tms70c46_device::device_reset() { m_control = 0; - m_io->write_byte(TMS7000_PORTE, 0xff); + + // reset port E + m_port_out_cb[4](0xff); tms7000_device::device_reset(); } @@ -902,7 +904,7 @@ WRITE8_MEMBER(tms70c46_device::control_w) { // d5: enable external databus if (~m_control & data & 0x20) - m_io->write_byte(TMS7000_PORTE, 0xff); // go into high impedance + m_port_out_cb[4](0xff); // put port E into high impedance // d4: enable clock divider when accessing slow memory (not emulated) // known fast memory areas: internal ROM/RAM, system RAM diff --git a/src/devices/cpu/tms7000/tms7000.h b/src/devices/cpu/tms7000/tms7000.h index ef69bdb881e..bd941fbf9ca 100644 --- a/src/devices/cpu/tms7000/tms7000.h +++ b/src/devices/cpu/tms7000/tms7000.h @@ -14,6 +14,33 @@ #include "debugger.h" +// read-only on 70x0 +#define MCFG_TMS7000_IN_PORTA_CB(_devcb) \ + devcb = &tms7000_device::set_port_read_cb(*device, 0, DEVCB_##_devcb); +#define MCFG_TMS7000_OUT_PORTA_CB(_devcb) \ + devcb = &tms7000_device::set_port_write_cb(*device, 0, DEVCB_##_devcb); + +// write-only +#define MCFG_TMS7000_OUT_PORTB_CB(_devcb) \ + devcb = &tms7000_device::set_port_write_cb(*device, 1, DEVCB_##_devcb); + +#define MCFG_TMS7000_IN_PORTC_CB(_devcb) \ + devcb = &tms7000_device::set_port_read_cb(*device, 2, DEVCB_##_devcb); +#define MCFG_TMS7000_OUT_PORTC_CB(_devcb) \ + devcb = &tms7000_device::set_port_write_cb(*device, 2, DEVCB_##_devcb); + +#define MCFG_TMS7000_IN_PORTD_CB(_devcb) \ + devcb = &tms7000_device::set_port_read_cb(*device, 3, DEVCB_##_devcb); +#define MCFG_TMS7000_OUT_PORTD_CB(_devcb) \ + devcb = &tms7000_device::set_port_write_cb(*device, 3, DEVCB_##_devcb); + +// TMS70C46 only +#define MCFG_TMS7000_IN_PORTE_CB(_devcb) \ + devcb = &tms7000_device::set_port_read_cb(*device, 4, DEVCB_##_devcb); +#define MCFG_TMS7000_OUT_PORTE_CB(_devcb) \ + devcb = &tms7000_device::set_port_write_cb(*device, 4, DEVCB_##_devcb); + + enum { TMS7000_PC=1, TMS7000_SP, TMS7000_ST }; enum @@ -23,15 +50,6 @@ enum TMS7000_INT3_LINE }; -enum -{ - TMS7000_PORTA = 0, /* read-only on 70x0 */ - TMS7000_PORTB, /* write-only */ - TMS7000_PORTC, - TMS7000_PORTD, - TMS7000_PORTE /* TMS70C46 only */ -}; - class tms7000_device : public cpu_device { @@ -39,6 +57,12 @@ public: // construction/destruction tms7000_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + // static configuration + template<class Object> + static devcb_base &set_port_read_cb(device_t &device, int p, Object &&object) { return downcast<tms7000_device &>(device).m_port_in_cb[p].set_callback(std::move(object)); } + template<class Object> + static devcb_base &set_port_write_cb(device_t &device, int p, Object &&object) { return downcast<tms7000_device &>(device).m_port_out_cb[p].set_callback(std::move(object)); } + DECLARE_READ8_MEMBER(tms7000_unmapped_rf_r) { if (!machine().side_effect_disabled()) logerror("'%s' (%04X): unmapped_rf_r @ $%04x\n", tag(), m_pc, offset + 0x80); return 0; }; DECLARE_WRITE8_MEMBER(tms7000_unmapped_rf_w) { logerror("'%s' (%04X): unmapped_rf_w @ $%04x = $%02x\n", tag(), m_pc, offset + 0x80, data); }; @@ -82,22 +106,21 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 4; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; uint32_t chip_get_family() const { return m_info_flags & CHIP_FAMILY_MASK; } virtual void execute_one(uint8_t op); address_space_config m_program_config; - address_space_config m_io_config; + + devcb_read8 m_port_in_cb[5]; + devcb_write8 m_port_out_cb[5]; uint32_t m_info_flags; address_space *m_program; - direct_read_data *m_direct; - address_space *m_io; + direct_read_data<0> *m_direct; int m_icount; bool m_irq_state[2]; @@ -319,8 +342,8 @@ public: DECLARE_WRITE8_MEMBER(dockbus_data_w); // access I/O port E if databus is disabled - DECLARE_READ8_MEMBER(e_bus_data_r) { return machine().side_effect_disabled() ? 0xff : ((m_control & 0x20) ? 0xff : m_io->read_byte(TMS7000_PORTE)); } - DECLARE_WRITE8_MEMBER(e_bus_data_w) { if (~m_control & 0x20) m_io->write_byte(TMS7000_PORTE, data); } + DECLARE_READ8_MEMBER(e_bus_data_r) { return machine().side_effect_disabled() ? 0xff : ((m_control & 0x20) ? 0xff : m_port_in_cb[4]()); } + DECLARE_WRITE8_MEMBER(e_bus_data_w) { if (~m_control & 0x20) m_port_out_cb[4](data); } protected: // device-level overrides diff --git a/src/devices/cpu/tms9900/9900dasm.cpp b/src/devices/cpu/tms9900/9900dasm.cpp index 5d3eac1c105..64520815353 100644 --- a/src/devices/cpu/tms9900/9900dasm.cpp +++ b/src/devices/cpu/tms9900/9900dasm.cpp @@ -9,103 +9,14 @@ #include "emu.h" -#include "debugger.h" -#include "tms9900.h" +#include "tms99com.h" +#include "9900dasm.h" #define MASK 0x0000ffff #define BITS(val,n1,n2) ((val>>(15-(n2))) & (MASK>>(15-((n2)-(n1))))) -enum format_t -{ - format_1, /* 2 address instructions */ - format_2a, /* jump instructions */ - format_2b, /* bit I/O instructions */ - format_3_9, /* logical, multiply, and divide instructions */ - format_4, /* CRU instructions */ - format_5, /* register shift instructions */ - format_6, /* single address instructions */ - format_7, /* instructions without operands */ - format_8a, /* immediate instructions (destination register) */ - format_8b, /* immediate instructions (no destination register) */ - format_9, /* extended operation instruction */ - format_10, /* memory map file instruction */ - format_11, /* multiple precision instructions */ - format_12, /* string instructions */ - format_13, /* multiple precision shift instructions */ - format_14, /* bit testing instructions */ - format_15, /* invert order of field instruction */ - format_16, /* field instructions */ - format_17, /* alter register and jump instructions */ - format_18, /* single register operand instructions */ - format_liim,/* format for liim (looks like format 18) */ - format_19, /* move address instruction */ - format_20, /* list search instructions */ - format_21, /* extend precision instruction */ - - illegal -}; - -/* definitions for flags */ -enum -{ - /* processor set on which opcodes are available */ - ps_any = 0x01, /* every processor in the tms9900/ti990 family */ - ps_mapper = 0x02, /* processors with memory mapper (ti990/10, ti990/12, - and tms99000 with mapper coprocessor) */ - ps_tms9995 = 0x04, /* ti990/12, tms9995, and later */ - ps_tms99000 = 0x08, /* ti990/12, tms99000, and later */ - ps_ti990_12 = 0x10, /* ti990/12 only */ - - /* additional flags for special decoding */ - sd_11 = 0x100, /* bit 11 should be cleared in li, ai, andi, ori, ci, stwp, stst */ - sd_11_15 = 0x200 /* bits 11-15 should be cleared in lwpi, limi, idle, rset, rtwp, ckon, ckof, lrex */ -}; -struct description_t -{ - const char *mnemonic; - format_t format; - int flags; -}; - - -enum opcodes { - /* basic instruction set */ - _a=0, _ab, _c, _cb, _s, _sb, _soc, _socb, _szc, _szcb, - _mov, _movb, _coc, _czc, _xor, _mpy, _div, _xop, _b, _bl, - _blwp, _clr, _seto, _inv, _neg, _abs, _swpb, _inc, _inct, _dec, - _dect, _x, _ldcr, _stcr, _sbo, _sbz, _tb, _jeq, _jgt, _jh, - _jhe, _jl, _jle, _jlt, _jmp, _jnc, _jne, _jno, _joc, _jop, - _sla, _sra, _src, _srl, _ai, _andi, _ci, _li, _ori, _lwpi, - _limi, _stst, _stwp, _rtwp, _idle, _rset, _ckof, _ckon, _lrex, - - /* mapper instruction set */ - _lds, _ldd, _lmf, - - /* tms9995 instruction set */ - _divs, _mpys, _lst, _lwp, - - /* tms99000 instruction set */ - _bind, - - /* ti990/12 instruction set */ - _sram, _slam, _rto, _lto, _cnto, _slsl, _slsp, _bdc, _dbc, _swpm, - _xorm, _orm, _andm, _sm, _am, _mova, _emd, _eint, _dint, _stpc, - _cs, _seqb, _movs, _lim, _lcs, _blsk, _mvsr, _mvsk, _pops, _pshs, - - _cri, _cdi, _negr, _negd, _cre, _cde, _cer, _ced, _nrm, _tmb, - _tcmb, _tsmb, _srj, _arj, _xit, _insf, _xv, _xf, _ar, _cir, - _sr, _mr, _dr, _lr, _str, _iof, _sneb, _crc, _ts, _ad, - _cid, _sd, _md, _dd, _ld, _std, _ep, - - /* tms9940-only instruction set */ - _liim, _dca, _dcs, - - _ill -}; - - -static const description_t descriptions[144+3+1] = +const tms9900_disassembler::description_t tms9900_disassembler::descriptions[144+3+1] = { /* basic instruction set */ { "a", format_1, ps_any }, { "ab", format_1, ps_any }, @@ -203,51 +114,51 @@ static const description_t descriptions[144+3+1] = }; -static const enum opcodes ops_4000_ffff_s12[12]= +const enum tms9900_disassembler::opcodes tms9900_disassembler::ops_4000_ffff_s12[12]= { _szc, _szcb, _s, _sb, /*4000-7000*/ _c, _cb, _a, _ab, _mov, _movb, _soc, _socb /*8000-f000*/ }; -static const enum opcodes ops_2000_3fff_s10[8]= +const enum tms9900_disassembler::opcodes tms9900_disassembler::ops_2000_3fff_s10[8]= { _coc, _czc, _xor, _xop, _ldcr, _stcr, _mpy, _div /*2000-3800*/ }; -static const enum opcodes ops_1000_1fff_s8[16]= +const enum tms9900_disassembler::opcodes tms9900_disassembler::ops_1000_1fff_s8[16]= { _jmp, _jlt, _jle, _jeq, _jhe, _jgt, _jne, _jnc, /*1000-1700*/ _joc, _jno, _jl, _jh, _jop, _sbo, _sbz, _tb /*1800-1f00*/ }; -static const enum opcodes ops_0e40_0fff_s6[7]= +const enum tms9900_disassembler::opcodes tms9900_disassembler::ops_0e40_0fff_s6[7]= { _ad, _cid, _sd, _md, _dd, _ld, _std /*0e40-0fc0*/ }; -static const enum opcodes ops_0e00_0e3f_s4[4]= +const enum tms9900_disassembler::opcodes tms9900_disassembler::ops_0e00_0e3f_s4[4]= { _iof, _sneb, _crc, _ts /*0e00-0e30*/ }; -static const enum opcodes ops_0c40_0dff_s6[7]= +const enum tms9900_disassembler::opcodes tms9900_disassembler::ops_0c40_0dff_s6[7]= { _ar, _cir, _sr, _mr, _dr, _lr, _str /*0c40-0dc0*/ }; -static const enum opcodes ops_0c10_0c3f_s4[3]= +const enum tms9900_disassembler::opcodes tms9900_disassembler::ops_0c10_0c3f_s4[3]= { _insf, _xv, _xf /*0c10-0c30*/ }; -static const enum opcodes ops_0c00_0c0f_s0[16]= +const enum tms9900_disassembler::opcodes tms9900_disassembler::ops_0c00_0c0f_s0[16]= { _cri, _cdi, _negr, _negd, _cre, _cde, _cer, _ced, /*0c00-0c07*/ _nrm, _tmb, _tcmb, _tsmb, _srj, _arj, _xit, _xit /*0c08-0c0f*/ @@ -255,40 +166,40 @@ static const enum opcodes ops_0c00_0c0f_s0[16]= -static const enum opcodes ops_0800_0bff_s8[4]= +const enum tms9900_disassembler::opcodes tms9900_disassembler::ops_0800_0bff_s8[4]= { _sra, _srl, _sla, _src /*0800-0b00*/ }; -static const enum opcodes ops_0400_07ff_s6[16]= +const enum tms9900_disassembler::opcodes tms9900_disassembler::ops_0400_07ff_s6[16]= { _blwp, _b, _x, _clr, _neg, _inv, _inc, _inct, /*0400-05c0*/ _dec, _dect, _bl, _swpb, _seto, _abs, _lds, _ldd /*0600-07c0*/ }; -static const enum opcodes ops_0200_03ff_s5[16]= +const enum tms9900_disassembler::opcodes tms9900_disassembler::ops_0200_03ff_s5[16]= { _li, _ai, _andi, _ori, _ci, _stwp, _stst, _lwpi, /*0200-02e0*/ _limi, _lmf, _idle, _rset, _rtwp, _ckon, _ckof, _lrex /*0300-03e0*/ }; -static const enum opcodes ops_0100_01ff_s6[4]= +const enum tms9900_disassembler::opcodes tms9900_disassembler::ops_0100_01ff_s6[4]= { _ill, _bind, _divs, _mpys /*0100-01c0*/ }; -static const enum opcodes ops_0030_00ff_s4[13]= +const enum tms9900_disassembler::opcodes tms9900_disassembler::ops_0030_00ff_s4[13]= { _stpc, _cs, _seqb, _movs, _lim, /*0030-0070*/ _lst, _lwp, _lcs, _blsk, _mvsr, _mvsk, _pops, _pshs /*0080-00f0*/ }; -static const enum opcodes ops_001c_002f_s0[20]= +const enum tms9900_disassembler::opcodes tms9900_disassembler::ops_001c_002f_s0[20]= { _sram, _slam, _rto, _lto, /*001c-001f*/ _cnto, _slsl, _slsp, _bdc, _dbc, _swpm, _xorm, _orm, /*0020-0027*/ @@ -296,17 +207,14 @@ static const enum opcodes ops_001c_002f_s0[20]= }; - -static int PC; - - -static inline uint16_t readop_arg(const uint8_t *opram, unsigned pc) +inline uint16_t tms9900_disassembler::readop_arg(const data_buffer ¶ms, offs_t &PC) { - uint16_t result = opram[PC++ - pc] << 8; - return result | opram[PC++ - pc]; + uint16_t result = params.r16(PC); + PC += 2;; + return result; } -static void print_arg (std::ostream &stream, int mode, int arg, const uint8_t *opram, unsigned pc) +void tms9900_disassembler::print_arg (std::ostream &stream, int mode, int arg, const data_buffer ¶ms, offs_t &PC) { int base; @@ -319,7 +227,7 @@ static void print_arg (std::ostream &stream, int mode, int arg, const uint8_t *o util::stream_format(stream, "*R%d", arg); break; case 0x2: /* symbolic|indexed */ - base = readop_arg(opram, pc); + base = readop_arg(params, PC); if (arg) /* indexed */ util::stream_format(stream, "@>%04x(R%d)", base, arg); else /* symbolic (direct) */ @@ -331,11 +239,19 @@ static void print_arg (std::ostream &stream, int mode, int arg, const uint8_t *o } } +tms9900_disassembler::tms9900_disassembler(int model) : m_model_id(model) +{ +} + +u32 tms9900_disassembler::opcode_alignment() const +{ + return 2; +} /***************************************************************************** * Disassemble a single command and return the number of bytes it uses. *****************************************************************************/ -static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const uint8_t *oprom, const uint8_t *opram) +offs_t tms9900_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { int OP, OP2, opc; int sarg, darg, smode, dmode; @@ -355,26 +271,26 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const Additionally, ti990/12 and tms9995 will generate an illegal error when bits 12-15 are non-zero. */ - #define BETTER_0200_DECODING (model_id == TI990_10_ID) - #define COMPLETE_0200_DECODING (/*(model_id == TI990_12_ID) ||*/ (model_id >= TMS9995_ID)) + #define BETTER_0200_DECODING (m_model_id == TI990_10_ID) + #define COMPLETE_0200_DECODING (/*(m_model_id == TI990_12_ID) ||*/ (m_model_id >= TMS9995_ID)) int processor_mask = ps_any; - if ((model_id == TI990_10_ID) /*|| (model_id == TI990_12_ID)*/ || (model_id >= TMS99000_ID)) + if ((m_model_id == TI990_10_ID) /*|| (m_model_id == TI990_12_ID)*/ || (m_model_id >= TMS99000_ID)) processor_mask |= ps_mapper; /* processors with memory mapper (ti990/10, ti990/12, and tms99000 with mapper coprocessor) */ - if (/*(model_id == TI990_12_ID) ||*/ (model_id >= TMS9995_ID)) + if (/*(m_model_id == TI990_12_ID) ||*/ (m_model_id >= TMS9995_ID)) processor_mask |= ps_tms9995; /* ti990/12, tms9995, and later */ - if (/*(model_id == TI990_12_ID) ||*/ (model_id >= TMS99000_ID)) + if (/*(m_model_id == TI990_12_ID) ||*/ (m_model_id >= TMS99000_ID)) processor_mask |= ps_tms99000; /* ti990/12, tms99000, and later */ - /*if ((model_id == TI990_12_ID)) + /*if ((m_model_id == TI990_12_ID)) processor_mask |= ps_ti990_12;*/ /* ti990/12, tms99000, and later */ - PC = pc; - OP = oprom[PC++ - pc] << 8; - OP |= oprom[PC++ - pc]; + offs_t PC = pc; + OP = opcodes.r16(PC); + PC += 2; /* let's identify the opcode */ if (OP >= 0x4000) @@ -434,7 +350,7 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const } /* tms9940 replace a few xops with custom instructions */ - if ((opc == _xop) && ((model_id == TMS9940_ID) || (model_id == TMS9985_ID))) + if ((opc == _xop) && ((m_model_id == TMS9940_ID) || (m_model_id == TMS9985_ID))) { switch (BITS(OP,6,9)) { @@ -473,11 +389,11 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const /* bl and blwp instructions are subroutines */ if (mnemonic != nullptr && mnemonic[0] == 'b' && mnemonic[1] == 'l') - dasmflags = DASMFLAG_STEP_OVER; + dasmflags = STEP_OVER; /* b *r11 and rtwp are returns */ else if (opc == 0x045b || (mnemonic != nullptr && strcmp(mnemonic, "rtwp") == 0)) - dasmflags = DASMFLAG_STEP_OUT; + dasmflags = STEP_OUT; switch (format) { @@ -488,9 +404,9 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const darg = BITS(OP,6,9); util::stream_format(stream, "%-4s ", mnemonic); - print_arg(stream, smode, sarg, opram, pc); + print_arg(stream, smode, sarg, params, PC); util::stream_format(stream, ","); - print_arg(stream, dmode, darg, opram, pc); + print_arg(stream, dmode, darg, params, PC); break; case format_2a: /* jump instructions */ @@ -516,13 +432,13 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const if (format == format_3_9) { util::stream_format(stream, "%-4s ", mnemonic); - print_arg(stream, smode, sarg, opram, pc); + print_arg(stream, smode, sarg, params, PC); util::stream_format(stream, ",R%d", darg); } else { util::stream_format(stream, "%-4s ", mnemonic); - print_arg(stream, smode, sarg, opram, pc); + print_arg(stream, smode, sarg, params, PC); util::stream_format(stream, ",%d", darg); } break; @@ -539,7 +455,7 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const sarg = BITS(OP,12,15); util::stream_format(stream, "%-4s ", mnemonic); - print_arg(stream, smode, sarg, opram, pc); + print_arg(stream, smode, sarg, params, PC); break; case format_7: /* instructions without operands */ @@ -548,13 +464,13 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const case format_8a: /* immediate instructions (destination register) */ darg = BITS(OP,12,15); - sarg = readop_arg(opram, pc); + sarg = readop_arg(params, PC); util::stream_format(stream, "%-4s R%d,>%04x", mnemonic, darg, sarg); break; case format_8b: /* immediate instructions (no destination register) */ - sarg = readop_arg(opram, pc); + sarg = readop_arg(params, PC); util::stream_format(stream, "%-4s >%04x", mnemonic, sarg); break; @@ -567,7 +483,7 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const break; case format_11: /* multiple precision instructions */ - OP2 = readop_arg(opram, pc); + OP2 = readop_arg(params, PC); smode = BITS(OP2,10,11); sarg = BITS(OP2,12,15); @@ -576,14 +492,14 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const byte_count = BITS(OP2,0,3); util::stream_format(stream, "%-4s ", mnemonic); - print_arg(stream, smode, sarg, opram, pc); + print_arg(stream, smode, sarg, params, PC); util::stream_format(stream, ","); - print_arg(stream, dmode, darg, opram, pc); + print_arg(stream, dmode, darg, params, PC); util::stream_format(stream, byte_count ? ",%d" : ",R%d", byte_count); break; case format_12: /* string instructions */ - OP2 = readop_arg(opram, pc); + OP2 = readop_arg(params, PC); smode = BITS(OP2,10,11); sarg = BITS(OP2,12,15); @@ -593,14 +509,14 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const checkpoint = BITS(OP,12,15); util::stream_format(stream, "%-4s ", mnemonic); - print_arg(stream, smode, sarg, opram, pc); + print_arg(stream, smode, sarg, params, PC); util::stream_format(stream, ","); - print_arg(stream, dmode, darg, opram, pc); + print_arg(stream, dmode, darg, params, PC); util::stream_format(stream, byte_count ? ",%d,R%d" : ",R%d,R%d", byte_count, checkpoint); break; case format_13: /* multiple precision shift instructions */ - OP2 = readop_arg(opram, pc); + OP2 = readop_arg(params, PC); smode = BITS(OP2,10,11); sarg = BITS(OP2,12,15); @@ -608,20 +524,20 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const byte_count = BITS(OP2,0,3); util::stream_format(stream, "%-4s ", mnemonic); - print_arg(stream, smode, sarg, opram, pc); + print_arg(stream, smode, sarg, params, PC); util::stream_format(stream, byte_count ? ",%d" : ",R%d", byte_count); util::stream_format(stream, darg ? ",%d" : ",R%d", darg); break; case format_14: /* bit testing instructions */ - OP2 = readop_arg(opram, pc); + OP2 = readop_arg(params, PC); smode = BITS(OP2,10,11); sarg = BITS(OP2,12,15); darg = BITS(OP2,0,9); util::stream_format(stream, "%-4s ", mnemonic); - print_arg(stream, smode, sarg, opram, pc); + print_arg(stream, smode, sarg, params, PC); if (darg == 0x3ff) util::stream_format(stream, ",R0"); else @@ -629,7 +545,7 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const break; case format_15: /* invert order of field instruction */ - OP2 = readop_arg(opram, pc); + OP2 = readop_arg(params, PC); smode = BITS(OP2,10,11); sarg = BITS(OP2,12,15); @@ -637,13 +553,13 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const bit_width = BITS(OP,12,15); util::stream_format(stream, "%-4s ", mnemonic); - print_arg(stream, smode, sarg, opram, pc); + print_arg(stream, smode, sarg, params, PC); util::stream_format(stream, bit_position ? ",(%d," : ",(R%d,", bit_position); util::stream_format(stream, bit_width ? "%d)" : "R%d)", bit_width); break; case format_16: /* field instructions */ - OP2 = readop_arg(opram, pc); + OP2 = readop_arg(params, PC); smode = BITS(OP2,10,11); sarg = BITS(OP2,12,15); @@ -653,15 +569,15 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const bit_width = BITS(OP,12,15); util::stream_format(stream, "%-4s ", mnemonic); - print_arg(stream, smode, sarg, opram, pc); + print_arg(stream, smode, sarg, params, PC); util::stream_format(stream, ","); - print_arg(stream, dmode, darg, opram, pc); + print_arg(stream, dmode, darg, params, PC); util::stream_format(stream, bit_position ? ",(%d," : ",(%d,", bit_position); util::stream_format(stream, bit_width ? "%d)" : "R%d)", bit_width); break; case format_17: /* alter register and jump instructions */ - OP2 = readop_arg(opram, pc); + OP2 = readop_arg(params, PC); displacement = (signed char)BITS(OP2,8,15); sarg = BITS(OP2,4,7); @@ -684,7 +600,7 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const break; case format_19: /* move address instruction */ - OP2 = readop_arg(opram, pc); + OP2 = readop_arg(params, PC); smode = BITS(OP2,10,11); sarg = BITS(OP2,12,15); @@ -692,16 +608,16 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const darg = BITS(OP2,6,9); util::stream_format(stream, "%-4s ", mnemonic); - print_arg(stream, smode, sarg, opram, pc); + print_arg(stream, smode, sarg, params, PC); util::stream_format(stream, ","); - print_arg(stream, dmode, darg, opram, pc); + print_arg(stream, dmode, darg, params, PC); break; case format_20: /* list search instructions */ { const char *condition_code; - OP2 = readop_arg(opram, pc); + OP2 = readop_arg(params, PC); smode = BITS(OP2,10,11); sarg = BITS(OP2,12,15); @@ -746,9 +662,9 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const } util::stream_format(stream, "%-4s %s,", mnemonic, condition_code); - print_arg(stream, smode, sarg, opram, pc); + print_arg(stream, smode, sarg, params, PC); util::stream_format(stream, ","); - print_arg(stream, dmode, darg, opram, pc); + print_arg(stream, dmode, darg, params, PC); break; } @@ -756,7 +672,7 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const { int dest_byte_count; - OP2 = readop_arg(opram, pc); + OP2 = readop_arg(params, PC); smode = BITS(OP2,10,11); sarg = BITS(OP2,12,15); @@ -766,9 +682,9 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const dest_byte_count = BITS(OP,12,15); util::stream_format(stream, "%-4s ", mnemonic); - print_arg(stream, smode, sarg, opram, pc); + print_arg(stream, smode, sarg, params, PC); util::stream_format(stream, ","); - print_arg(stream, dmode, darg, opram, pc); + print_arg(stream, dmode, darg, params, PC); util::stream_format(stream, byte_count ? ",%d" : ",R%d", byte_count); util::stream_format(stream, dest_byte_count ? ",%d" : ",R%d", dest_byte_count); break; @@ -781,20 +697,5 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const break; } - return (PC - pc) | DASMFLAG_SUPPORTED | dasmflags; -} - -CPU_DISASSEMBLE( tms9900 ) -{ - return Dasm9900(stream, pc, TMS9900_ID, oprom, opram); -} - -CPU_DISASSEMBLE( tms9980 ) -{ - return Dasm9900(stream, pc, TMS9980_ID, oprom, opram); -} - -CPU_DISASSEMBLE( tms9995 ) -{ - return Dasm9900(stream, pc, TMS9995_ID, oprom, opram); + return (PC - pc) | SUPPORTED | dasmflags; } diff --git a/src/devices/cpu/tms9900/9900dasm.h b/src/devices/cpu/tms9900/9900dasm.h new file mode 100644 index 00000000000..53fa192284d --- /dev/null +++ b/src/devices/cpu/tms9900/9900dasm.h @@ -0,0 +1,136 @@ +// license:BSD-3-Clause +// copyright-holders:Raphael Nabet +/***************************************************************************** + * + * 9900dasm.c + * TMS 9900 family disassembler + * + *****************************************************************************/ + +#ifndef MAME_CPU_TMS9900_TMS9900DASM_H +#define MAME_CPU_TMS9900_TMS9900DASM_H + +#pragma once + +class tms9900_disassembler : public util::disasm_interface +{ +public: + tms9900_disassembler(int model); + virtual ~tms9900_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum format_t + { + format_1, /* 2 address instructions */ + format_2a, /* jump instructions */ + format_2b, /* bit I/O instructions */ + format_3_9, /* logical, multiply, and divide instructions */ + format_4, /* CRU instructions */ + format_5, /* register shift instructions */ + format_6, /* single address instructions */ + format_7, /* instructions without operands */ + format_8a, /* immediate instructions (destination register) */ + format_8b, /* immediate instructions (no destination register) */ + format_9, /* extended operation instruction */ + format_10, /* memory map file instruction */ + format_11, /* multiple precision instructions */ + format_12, /* string instructions */ + format_13, /* multiple precision shift instructions */ + format_14, /* bit testing instructions */ + format_15, /* invert order of field instruction */ + format_16, /* field instructions */ + format_17, /* alter register and jump instructions */ + format_18, /* single register operand instructions */ + format_liim,/* format for liim (looks like format 18) */ + format_19, /* move address instruction */ + format_20, /* list search instructions */ + format_21, /* extend precision instruction */ + + illegal + }; + + /* definitions for flags */ + enum + { + /* processor set on which opcodes are available */ + ps_any = 0x01, /* every processor in the tms9900/ti990 family */ + ps_mapper = 0x02, /* processors with memory mapper (ti990/10, ti990/12, + and tms99000 with mapper coprocessor) */ + ps_tms9995 = 0x04, /* ti990/12, tms9995, and later */ + ps_tms99000 = 0x08, /* ti990/12, tms99000, and later */ + ps_ti990_12 = 0x10, /* ti990/12 only */ + + /* additional flags for special decoding */ + sd_11 = 0x100, /* bit 11 should be cleared in li, ai, andi, ori, ci, stwp, stst */ + sd_11_15 = 0x200 /* bits 11-15 should be cleared in lwpi, limi, idle, rset, rtwp, ckon, ckof, lrex */ + }; + + struct description_t + { + const char *mnemonic; + format_t format; + int flags; + }; + + + enum opcodes { + /* basic instruction set */ + _a=0, _ab, _c, _cb, _s, _sb, _soc, _socb, _szc, _szcb, + _mov, _movb, _coc, _czc, _xor, _mpy, _div, _xop, _b, _bl, + _blwp, _clr, _seto, _inv, _neg, _abs, _swpb, _inc, _inct, _dec, + _dect, _x, _ldcr, _stcr, _sbo, _sbz, _tb, _jeq, _jgt, _jh, + _jhe, _jl, _jle, _jlt, _jmp, _jnc, _jne, _jno, _joc, _jop, + _sla, _sra, _src, _srl, _ai, _andi, _ci, _li, _ori, _lwpi, + _limi, _stst, _stwp, _rtwp, _idle, _rset, _ckof, _ckon, _lrex, + + /* mapper instruction set */ + _lds, _ldd, _lmf, + + /* tms9995 instruction set */ + _divs, _mpys, _lst, _lwp, + + /* tms99000 instruction set */ + _bind, + + /* ti990/12 instruction set */ + _sram, _slam, _rto, _lto, _cnto, _slsl, _slsp, _bdc, _dbc, _swpm, + _xorm, _orm, _andm, _sm, _am, _mova, _emd, _eint, _dint, _stpc, + _cs, _seqb, _movs, _lim, _lcs, _blsk, _mvsr, _mvsk, _pops, _pshs, + + _cri, _cdi, _negr, _negd, _cre, _cde, _cer, _ced, _nrm, _tmb, + _tcmb, _tsmb, _srj, _arj, _xit, _insf, _xv, _xf, _ar, _cir, + _sr, _mr, _dr, _lr, _str, _iof, _sneb, _crc, _ts, _ad, + _cid, _sd, _md, _dd, _ld, _std, _ep, + + /* tms9940-only instruction set */ + _liim, _dca, _dcs, + + _ill + }; + + static const description_t descriptions[144+3+1]; + static const enum opcodes ops_4000_ffff_s12[12]; + static const enum opcodes ops_2000_3fff_s10[8]; + static const enum opcodes ops_1000_1fff_s8[16]; + static const enum opcodes ops_0e40_0fff_s6[7]; + static const enum opcodes ops_0e00_0e3f_s4[4]; + static const enum opcodes ops_0c40_0dff_s6[7]; + static const enum opcodes ops_0c10_0c3f_s4[3]; + static const enum opcodes ops_0c00_0c0f_s0[16]; + static const enum opcodes ops_0800_0bff_s8[4]; + static const enum opcodes ops_0400_07ff_s6[16]; + static const enum opcodes ops_0200_03ff_s5[16]; + static const enum opcodes ops_0100_01ff_s6[4]; + static const enum opcodes ops_0030_00ff_s4[13]; + static const enum opcodes ops_001c_002f_s0[20]; + + int m_model_id; + + inline uint16_t readop_arg(const data_buffer ¶ms, offs_t &PC); + void print_arg (std::ostream &stream, int mode, int arg, const data_buffer ¶ms, offs_t &PC); +}; + +#endif diff --git a/src/devices/cpu/tms9900/ti990_10.cpp b/src/devices/cpu/tms9900/ti990_10.cpp index 3f9f60b4129..bcb96cb6d90 100644 --- a/src/devices/cpu/tms9900/ti990_10.cpp +++ b/src/devices/cpu/tms9900/ti990_10.cpp @@ -25,6 +25,7 @@ #include "emu.h" #include "ti990_10.h" +#include "9900dasm.h" /* The following defines can be set to 0 or 1 to disable or enable certain @@ -122,22 +123,10 @@ uint32_t ti990_10_device::execute_input_lines() const return 2; } -// device_disasm_interface overrides -uint32_t ti990_10_device::disasm_min_opcode_bytes() const -{ - return 2; -} - -uint32_t ti990_10_device::disasm_max_opcode_bytes() const -{ - return 6; -} - // TODO: check 9900dasm -offs_t ti990_10_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *ti990_10_device::create_disassembler() { - extern CPU_DISASSEMBLE( tms9900 ); - return CPU_DISASSEMBLE_NAME(tms9900)(this, stream, pc, oprom, opram, options); + return new tms9900_disassembler(TMS9900_ID); } DEFINE_DEVICE_TYPE(TI990_10, ti990_10_device, "ti990_10_cpu", "TI990/10 CPU") diff --git a/src/devices/cpu/tms9900/ti990_10.h b/src/devices/cpu/tms9900/ti990_10.h index bd2d6a65d43..6e9b945e17e 100644 --- a/src/devices/cpu/tms9900/ti990_10.h +++ b/src/devices/cpu/tms9900/ti990_10.h @@ -34,9 +34,7 @@ protected: void execute_run() override; // device_disasm_interface overrides - uint32_t disasm_min_opcode_bytes() const override; - uint32_t disasm_max_opcode_bytes() const override; - offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual space_config_vector memory_space_config() const override; diff --git a/src/devices/cpu/tms9900/tms9900.cpp b/src/devices/cpu/tms9900/tms9900.cpp index e0b207f3335..72631d68ae1 100644 --- a/src/devices/cpu/tms9900/tms9900.cpp +++ b/src/devices/cpu/tms9900/tms9900.cpp @@ -110,6 +110,7 @@ #include "emu.h" #include "tms9900.h" +#include "9900dasm.h" #define NOPRG -1 @@ -2751,20 +2752,10 @@ uint32_t tms99xx_device::execute_input_lines() const // execute_burn = nop // device_disasm_interface overrides -uint32_t tms99xx_device::disasm_min_opcode_bytes() const -{ - return 2; -} - -uint32_t tms99xx_device::disasm_max_opcode_bytes() const -{ - return 6; -} -offs_t tms99xx_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *tms99xx_device::create_disassembler() { - extern CPU_DISASSEMBLE( tms9900 ); - return CPU_DISASSEMBLE_NAME(tms9900)(this, stream, pc, oprom, opram, options); + return new tms9900_disassembler(TMS9900_ID); } diff --git a/src/devices/cpu/tms9900/tms9900.h b/src/devices/cpu/tms9900/tms9900.h index 5486043aaa1..e7a4c3ebd2a 100644 --- a/src/devices/cpu/tms9900/tms9900.h +++ b/src/devices/cpu/tms9900/tms9900.h @@ -82,9 +82,7 @@ protected: virtual void execute_run() override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual space_config_vector memory_space_config() const override; diff --git a/src/devices/cpu/tms9900/tms9980a.cpp b/src/devices/cpu/tms9900/tms9980a.cpp index b2dcc2f389a..fc1d12afbc8 100644 --- a/src/devices/cpu/tms9900/tms9980a.cpp +++ b/src/devices/cpu/tms9900/tms9980a.cpp @@ -53,6 +53,7 @@ #include "emu.h" #include "tms9980a.h" +#include "9900dasm.h" /* The following defines can be set to 0 or 1 to disable or enable certain @@ -282,20 +283,10 @@ uint32_t tms9980a_device::execute_input_lines() const // execute_burn = nop // device_disasm_interface overrides -uint32_t tms9980a_device::disasm_min_opcode_bytes() const -{ - return 2; -} - -uint32_t tms9980a_device::disasm_max_opcode_bytes() const -{ - return 6; -} -offs_t tms9980a_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *tms9980a_device::create_disassembler() { - extern CPU_DISASSEMBLE( tms9980 ); - return CPU_DISASSEMBLE_NAME(tms9980)(this, stream, pc, oprom, opram, options); + return new tms9900_disassembler(TMS9980_ID); } DEFINE_DEVICE_TYPE(TMS9980A, tms9980a_device, "tms9980a", "TMS9980A") diff --git a/src/devices/cpu/tms9900/tms9980a.h b/src/devices/cpu/tms9900/tms9980a.h index 34f6eadc434..72adcaf56c5 100644 --- a/src/devices/cpu/tms9900/tms9980a.h +++ b/src/devices/cpu/tms9900/tms9980a.h @@ -44,9 +44,8 @@ protected: uint32_t execute_input_lines() const override; void execute_set_input(int irqline, int state) override; - uint32_t disasm_min_opcode_bytes() const override; - uint32_t disasm_max_opcode_bytes() const override; - offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; + address_space_config m_program_config80; address_space_config m_io_config80; }; diff --git a/src/devices/cpu/tms9900/tms9995.cpp b/src/devices/cpu/tms9900/tms9995.cpp index d6bab5aaa4b..542f51f88ae 100644 --- a/src/devices/cpu/tms9900/tms9995.cpp +++ b/src/devices/cpu/tms9900/tms9995.cpp @@ -91,6 +91,7 @@ #include "emu.h" #include "tms9995.h" +#include "9900dasm.h" #define NOPRG -1 @@ -3514,20 +3515,9 @@ uint32_t tms9995_device::execute_input_lines() const return 2; } -uint32_t tms9995_device::disasm_min_opcode_bytes() const +util::disasm_interface *tms9995_device::create_disassembler() { - return 2; -} - -uint32_t tms9995_device::disasm_max_opcode_bytes() const -{ - return 6; -} - -offs_t tms9995_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) -{ - extern CPU_DISASSEMBLE( tms9995 ); - return CPU_DISASSEMBLE_NAME(tms9995)(this, stream, pc, oprom, opram, options); + return new tms9900_disassembler(TMS9995_ID); } diff --git a/src/devices/cpu/tms9900/tms9995.h b/src/devices/cpu/tms9900/tms9995.h index a0ffa861f8c..ff0357e74e4 100644 --- a/src/devices/cpu/tms9900/tms9995.h +++ b/src/devices/cpu/tms9900/tms9995.h @@ -94,9 +94,7 @@ protected: virtual void execute_run() override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual space_config_vector memory_space_config() const override; diff --git a/src/devices/cpu/ucom4/ucom4.cpp b/src/devices/cpu/ucom4/ucom4.cpp index 81b4e8ae913..8d1523751a9 100644 --- a/src/devices/cpu/ucom4/ucom4.cpp +++ b/src/devices/cpu/ucom4/ucom4.cpp @@ -22,6 +22,7 @@ #include "emu.h" #include "ucom4.h" +#include "ucom4d.h" #include "debugger.h" @@ -136,14 +137,12 @@ void ucom4_cpu_device::state_string_export(const device_state_entry &entry, std: } } -offs_t ucom4_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +util::disasm_interface *ucom4_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE(ucom4); - return CPU_DISASSEMBLE_NAME(ucom4)(this, stream, pc, oprom, opram, options); + return new ucom4_disassembler; } - //------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- diff --git a/src/devices/cpu/ucom4/ucom4.h b/src/devices/cpu/ucom4/ucom4.h index a442e5c676a..6db82e1a41e 100644 --- a/src/devices/cpu/ucom4/ucom4.h +++ b/src/devices/cpu/ucom4/ucom4.h @@ -134,9 +134,7 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual u32 disasm_min_opcode_bytes() const override { return 1; } - virtual u32 disasm_max_opcode_bytes() const override { return 2; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; // device_state_interface overrides virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; diff --git a/src/devices/cpu/ucom4/ucom4d.cpp b/src/devices/cpu/ucom4/ucom4d.cpp index f83801813ee..678c1952dfc 100644 --- a/src/devices/cpu/ucom4/ucom4d.cpp +++ b/src/devices/cpu/ucom4/ucom4d.cpp @@ -7,24 +7,9 @@ */ #include "emu.h" -#include "debugger.h" -#include "ucom4.h" +#include "ucom4d.h" - -enum e_mnemonics -{ - mLI, mL, mLM, mLDI, mLDZ, mS, mTAL, mTLA, - mX, mXI, mXD, mXM, mXMI, mXMD, mAD, mADC, mADS, mDAA, mDAS, - mEXL, mCLA, mCMA, mCIA, mCLC, mSTC, mTC, mINC, mDEC, mIND, mDED, - mRMB, mSMB, mREB, mSEB, mRPB, mSPB, mJMP, mJCP, mJPA, mCAL, mCZP, mRT, mRTS, - mCI, mCM, mCMB, mTAB, mCLI, mTMB, mTPA, mTPB, - mTIT, mIA, mIP, mOE, mOP, mOCD, mNOP, - mILL, - mTAW, mTAZ, mTHX, mTLY, mXAW, mXAZ, mXHR, mXHX, mXLS, mXLY, mXC, - mSFB, mRFB, mFBT, mFBF, mRAR, mINM, mDEM, mSTM, mTTM, mEI, mDI -}; - -static const char *const s_mnemonics[] = +const char *const ucom4_disassembler::s_mnemonics[] = { "LI", "L", "LM", "LDI", "LDZ", "S", "TAL", "TLA", "X", "XI", "XD", "XM", "XMI", "XMD", "AD", "ADC", "ADS", "DAA", "DAS", @@ -38,7 +23,7 @@ static const char *const s_mnemonics[] = }; // number of bits per opcode parameter, 2 digits means opcode is 2 bytes -static const u8 s_bits[] = +const u8 ucom4_disassembler::s_bits[] = { 4, 0, 2, 80, 4, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, @@ -51,15 +36,12 @@ static const u8 s_bits[] = 2, 2, 2, 2, 0, 0, 0, 80, 0, 0, 0 }; -#define _OVER DASMFLAG_STEP_OVER -#define _OUT DASMFLAG_STEP_OUT - -static const u32 s_flags[] = +const u32 ucom4_disassembler::s_flags[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, _OVER, _OVER, _OUT, _OUT, + 0, 0, 0, 0, 0, 0, 0, 0, 0, STEP_OVER, STEP_OVER, STEP_OUT, STEP_OUT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -68,7 +50,7 @@ static const u32 s_flags[] = }; -static const u8 ucom4_mnemonic[0x100] = +const u8 ucom4_disassembler::ucom4_mnemonic[0x100] = { /* 0x00 */ mNOP, mDI, mS, mTIT, mTC, mTTM, mDAA, mTAL, @@ -112,11 +94,31 @@ static const u8 ucom4_mnemonic[0x100] = }; +u32 ucom4_disassembler::opcode_alignment() const +{ + return 1; +} + +u32 ucom4_disassembler::interface_flags() const +{ + return PAGED2LEVEL; +} + +u32 ucom4_disassembler::page_address_bits() const +{ + return 6; +} + +u32 ucom4_disassembler::page2_address_bits() const +{ + return 2; +} + -CPU_DISASSEMBLE(ucom4) +offs_t ucom4_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - int pos = 0; - u8 op = oprom[pos++]; + offs_t pos = pc; + u8 op = opcodes.r8(pos++); u8 instr = ucom4_mnemonic[op]; util::stream_format(stream,"%-4s ", s_mnemonics[instr]); @@ -128,7 +130,7 @@ CPU_DISASSEMBLE(ucom4) u16 param = op & ((1 << (bits % 10)) - 1); if (bits / 10) { - u8 op2 = oprom[pos++]; + u8 op2 = opcodes.r8(pos++); param = (param << (bits / 10)) | (op2 & ((1 << (bits / 10)) - 1)); bits = (bits % 10) + (bits / 10); } @@ -148,5 +150,5 @@ CPU_DISASSEMBLE(ucom4) util::stream_format(stream, "$%03X", param); } - return pos | s_flags[instr] | DASMFLAG_SUPPORTED; + return (pos - pc) | s_flags[instr] | SUPPORTED; } diff --git a/src/devices/cpu/ucom4/ucom4d.h b/src/devices/cpu/ucom4/ucom4d.h new file mode 100644 index 00000000000..2dd3be4914b --- /dev/null +++ b/src/devices/cpu/ucom4/ucom4d.h @@ -0,0 +1,48 @@ +// license:BSD-3-Clause +// copyright-holders:hap +/* + + NEC uCOM-4 MCU family disassembler + +*/ + + +#ifndef MAME_CPU_UCOM4_UCOM4DASM_H +#define MAME_CPU_UCOM4_UCOM4DASM_H + +#pragma once + +class ucom4_disassembler : public util::disasm_interface +{ +public: + ucom4_disassembler() = default; + virtual ~ucom4_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual u32 interface_flags() const override; + virtual u32 page_address_bits() const override; + virtual u32 page2_address_bits() const override; + + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum e_mnemonics + { + mLI, mL, mLM, mLDI, mLDZ, mS, mTAL, mTLA, + mX, mXI, mXD, mXM, mXMI, mXMD, mAD, mADC, mADS, mDAA, mDAS, + mEXL, mCLA, mCMA, mCIA, mCLC, mSTC, mTC, mINC, mDEC, mIND, mDED, + mRMB, mSMB, mREB, mSEB, mRPB, mSPB, mJMP, mJCP, mJPA, mCAL, mCZP, mRT, mRTS, + mCI, mCM, mCMB, mTAB, mCLI, mTMB, mTPA, mTPB, + mTIT, mIA, mIP, mOE, mOP, mOCD, mNOP, + mILL, + mTAW, mTAZ, mTHX, mTLY, mXAW, mXAZ, mXHR, mXHX, mXLS, mXLY, mXC, + mSFB, mRFB, mFBT, mFBF, mRAR, mINM, mDEM, mSTM, mTTM, mEI, mDI + }; + + static const char *const s_mnemonics[]; + static const u8 s_bits[]; + static const u32 s_flags[]; + static const u8 ucom4_mnemonic[0x100]; +}; + +#endif diff --git a/src/devices/cpu/uml.cpp b/src/devices/cpu/uml.cpp index 5a6fe3a8b3a..c066e254d1d 100644 --- a/src/devices/cpu/uml.cpp +++ b/src/devices/cpu/uml.cpp @@ -776,6 +776,7 @@ void uml::instruction::validate() // ensure the type is valid const parameter ¶m = m_param[pnum]; assert((opinfo.param[pnum].typemask >> param.type()) & 1); + (void)param; } // make sure we aren't missing any parameters diff --git a/src/devices/cpu/unsp/unsp.cpp b/src/devices/cpu/unsp/unsp.cpp index cb14e9cdec4..8ee2111af65 100644 --- a/src/devices/cpu/unsp/unsp.cpp +++ b/src/devices/cpu/unsp/unsp.cpp @@ -10,6 +10,7 @@ #include "emu.h" #include "unsp.h" +#include "unspdasm.h" #include "debugger.h" @@ -30,10 +31,9 @@ device_memory_interface::space_config_vector unsp_device::memory_space_config() }; } -offs_t unsp_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *unsp_device::create_disassembler() { - extern CPU_DISASSEMBLE( unsp ); - return CPU_DISASSEMBLE_NAME(unsp)(this, stream, pc, oprom, opram, options); + return new unsp_disassembler; } @@ -116,12 +116,12 @@ void unsp_device::unimplemented_opcode(uint16_t op) uint16_t unsp_device::READ16(uint32_t address) { - return m_program->read_word(address<<1); + return m_program->read_word(address); } void unsp_device::WRITE16(uint32_t address, uint16_t data) { - m_program->write_word(address<<1, data); + m_program->write_word(address, data); } /*****************************************************************************/ diff --git a/src/devices/cpu/unsp/unsp.h b/src/devices/cpu/unsp/unsp.h index 5a445e05099..331bbf46786 100644 --- a/src/devices/cpu/unsp/unsp.h +++ b/src/devices/cpu/unsp/unsp.h @@ -75,9 +75,7 @@ protected: virtual void state_export(const device_state_entry &entry) override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 4; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; diff --git a/src/devices/cpu/unsp/unspdasm.cpp b/src/devices/cpu/unsp/unspdasm.cpp index 68d620fb7b6..bdea7a729a5 100644 --- a/src/devices/cpu/unsp/unspdasm.cpp +++ b/src/devices/cpu/unsp/unspdasm.cpp @@ -9,22 +9,22 @@ \**************************/ #include "emu.h" -#include <stdarg.h> +#include "unspdasm.h" /*****************************************************************************/ -static const char *reg[] = +const char *unsp_disassembler::reg[] = { "sp", "r1", "r2", "r3", "r4", "bp", "sr", "pc" }; -static const char *jmp[] = +const char *unsp_disassembler::jmp[] = { "jb", "jae", "jge", "jl", "jne", "je", "jpl", "jmi", "jbe", "ja", "jle", "jg", "jvc", "jvs", "jmp", "<inv>" }; -static const char *alu[] = +const char *unsp_disassembler::alu[] = { "add", "adc", "sub", "sbc", "cmp", "<inv>", "neg", "<inv>", @@ -44,14 +44,17 @@ static const char *alu[] = /*****************************************************************************/ -#define UNSP_DASM_OK ((OP2X ? 2 : 1) | DASMFLAG_SUPPORTED) +#define UNSP_DASM_OK ((OP2X ? 2 : 1) | SUPPORTED) -CPU_DISASSEMBLE(unsp) +u32 unsp_disassembler::opcode_alignment() const { - uint16_t op = *(uint16_t *)oprom; - uint16_t imm16 = *(uint16_t *)(oprom + 2); - op = big_endianize_int16(op); - imm16 = big_endianize_int16(imm16); + return 1; +} + +offs_t unsp_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + uint16_t op = opcodes.r16(pc); + uint16_t imm16 = opcodes.r16(pc+1); if(OP0 < 0xf && OPA == 0x7 && OP1 < 2) { diff --git a/src/devices/cpu/unsp/unspdasm.h b/src/devices/cpu/unsp/unspdasm.h new file mode 100644 index 00000000000..ef25b2a433b --- /dev/null +++ b/src/devices/cpu/unsp/unspdasm.h @@ -0,0 +1,32 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/**************************\ +* +* SunPlus u'nSP disassembler +* +* by Ryan Holtz +* +\**************************/ + + +#ifndef MAME_CPU_UNSP_UNSPDASM_H +#define MAME_CPU_UNSP_UNSPDASM_H + +#pragma once + +class unsp_disassembler : public util::disasm_interface +{ +public: + unsp_disassembler() = default; + virtual ~unsp_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *reg[]; + static const char *jmp[]; + static const char *alu[]; +}; + +#endif diff --git a/src/devices/cpu/upd7725/dasm7725.cpp b/src/devices/cpu/upd7725/dasm7725.cpp index f2e644e0bec..06a9fdd3d16 100644 --- a/src/devices/cpu/upd7725/dasm7725.cpp +++ b/src/devices/cpu/upd7725/dasm7725.cpp @@ -10,11 +10,16 @@ ***************************************************************************/ #include "emu.h" -#include "upd7725.h" +#include "dasm7725.h" -CPU_DISASSEMBLE(upd7725) +u32 necdsp_disassembler::opcode_alignment() const { - uint32_t opcode = oprom[2] | (oprom[1] << 8) | (oprom[0] << 16); + return 1; +} + +offs_t necdsp_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + uint32_t opcode = opcodes.r32(pc); uint32_t type = (opcode >> 22); // printf("dasm: PC %x opcode %08x\n", pc, opcode); @@ -220,5 +225,5 @@ CPU_DISASSEMBLE(upd7725) } } - return 1 | DASMFLAG_SUPPORTED; + return 1 | SUPPORTED; } diff --git a/src/devices/cpu/upd7725/dasm7725.h b/src/devices/cpu/upd7725/dasm7725.h new file mode 100644 index 00000000000..5280c3e4a46 --- /dev/null +++ b/src/devices/cpu/upd7725/dasm7725.h @@ -0,0 +1,27 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont,byuu +/*************************************************************************** + + dasm7725.c + Disassembler for the portable uPD7725 emulator. + Written by byuu + MAME conversion by R. Belmont + +***************************************************************************/ + +#ifndef MAME_CPU_UPD7725_DASM7725_H +#define MAME_CPU_UPD7725_DASM7725_H + +#pragma once + +class necdsp_disassembler : public util::disasm_interface +{ +public: + necdsp_disassembler() = default; + virtual ~necdsp_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/upd7725/upd7725.cpp b/src/devices/cpu/upd7725/upd7725.cpp index 7ef876613db..716fa45ccf9 100644 --- a/src/devices/cpu/upd7725/upd7725.cpp +++ b/src/devices/cpu/upd7725/upd7725.cpp @@ -14,6 +14,7 @@ #include "emu.h" #include "debugger.h" #include "upd7725.h" +#include "dasm7725.h" //************************************************************************** @@ -67,7 +68,7 @@ void necdsp_device::device_start() // get our address spaces m_program = &space(AS_PROGRAM); m_data = &space(AS_DATA); - m_direct = &m_program->direct(); + m_direct = m_program->direct<-2>(); // register our state for the debugger state_add(STATE_GENPC, "GENPC", regs.pc).noshow(); @@ -316,35 +317,13 @@ void necdsp_device::execute_set_input(int inputnum, int state) } //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t necdsp_device::disasm_min_opcode_bytes() const -{ - return 4; -} - - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t necdsp_device::disasm_max_opcode_bytes() const -{ - return 4; -} - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t necdsp_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *necdsp_device::create_disassembler() { - extern CPU_DISASSEMBLE( upd7725 ); - return CPU_DISASSEMBLE_NAME(upd7725)(this, stream, pc, oprom, opram, options); + return new necdsp_disassembler; } void necdsp_device::execute_run() @@ -361,7 +340,7 @@ void necdsp_device::execute_run() if (m_irq_firing == 0) // normal opcode { - opcode = m_direct->read_dword(regs.pc<<2)>>8; + opcode = m_direct->read_dword(regs.pc) >> 8; regs.pc++; } else if (m_irq_firing == 1) // if we're in an interrupt cycle, execute a op 'nop' first... @@ -413,7 +392,7 @@ void necdsp_device::exec_op(uint32_t opcode) { case 3: regs.idb = regs.tr; break; case 4: regs.idb = regs.dp; break; case 5: regs.idb = regs.rp; break; - case 6: regs.idb = m_data->read_word(regs.rp<<1); break; + case 6: regs.idb = m_data->read_word(regs.rp); break; case 7: regs.idb = 0x8000 - regs.flaga.s1; break; //SGN case 8: regs.idb = regs.dr; regs.sr.rqm = 1; break; case 9: regs.idb = regs.dr; break; @@ -610,7 +589,7 @@ void necdsp_device::exec_ld(uint32_t opcode) { case 8: regs.so = BITSWAP16(id, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); break; //LSB first output, output tapped at bit 15 shifting left case 9: regs.so = id; break; //MSB first output, output tapped at bit 15 shifting left case 10: regs.k = id; break; - case 11: regs.k = id; regs.l = m_data->read_word(regs.rp<<1); break; + case 11: regs.k = id; regs.l = m_data->read_word(regs.rp); break; case 12: regs.l = id; regs.k = dataRAM[regs.dp | 0x40]; break; case 13: regs.l = id; break; case 14: regs.trb = id; break; diff --git a/src/devices/cpu/upd7725/upd7725.h b/src/devices/cpu/upd7725/upd7725.h index 76cc13b9226..c52959124a1 100644 --- a/src/devices/cpu/upd7725/upd7725.h +++ b/src/devices/cpu/upd7725/upd7725.h @@ -107,9 +107,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // inline data const address_space_config m_program_config, m_data_config; @@ -191,7 +189,7 @@ private: // 2 = next opcode is the second half of int firing 'CALL 0100' int m_irq_firing; address_space *m_program, *m_data; - direct_read_data *m_direct; + direct_read_data<-2> *m_direct; protected: // device callbacks diff --git a/src/devices/cpu/upd7810/upd7810.cpp b/src/devices/cpu/upd7810/upd7810.cpp index 67b6818ec72..4871aaebcbd 100644 --- a/src/devices/cpu/upd7810/upd7810.cpp +++ b/src/devices/cpu/upd7810/upd7810.cpp @@ -374,6 +374,7 @@ STOP 01001000 10111011 12 stop #include "debugger.h" #include "upd7810_macros.h" +#include "upd7810_dasm.h" DEFINE_DEVICE_TYPE(UPD7810, upd7810_device, "upd7810", "uPD7810") @@ -519,28 +520,24 @@ device_memory_interface::space_config_vector upd7810_device::memory_space_config }; } -offs_t upd7810_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *upd7810_device::create_disassembler() { - extern CPU_DISASSEMBLE( upd7810 ); - return CPU_DISASSEMBLE_NAME(upd7810)(this, stream, pc, oprom, opram, options); + return new upd7810_disassembler; } -offs_t upd7807_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *upd7807_device::create_disassembler() { - extern CPU_DISASSEMBLE( upd7807 ); - return CPU_DISASSEMBLE_NAME(upd7807)(this, stream, pc, oprom, opram, options); + return new upd7807_disassembler; } -offs_t upd7801_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *upd7801_device::create_disassembler() { - extern CPU_DISASSEMBLE( upd7801 ); - return CPU_DISASSEMBLE_NAME(upd7801)(this, stream, pc, oprom, opram, options); + return new upd7801_disassembler; } -offs_t upd78c05_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *upd78c05_device::create_disassembler() { - extern CPU_DISASSEMBLE( upd78c05 ); - return CPU_DISASSEMBLE_NAME(upd78c05)(this, stream, pc, oprom, opram, options); + return new upd78c05_disassembler; } WRITE8_MEMBER(upd7810_device::pa_w) @@ -1571,7 +1568,7 @@ void upd78c05_device::handle_timers(int cycles) void upd7810_device::base_device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_to_func.resolve_safe(); m_co0_func.resolve_safe(); diff --git a/src/devices/cpu/upd7810/upd7810.h b/src/devices/cpu/upd7810/upd7810.h index a7d9ec13793..427a4d2d52b 100644 --- a/src/devices/cpu/upd7810/upd7810.h +++ b/src/devices/cpu/upd7810/upd7810.h @@ -227,9 +227,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 4; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void handle_timers(int cycles); virtual void upd7810_take_irq(); @@ -413,7 +411,7 @@ protected: const struct opcode_s *m_op70; const struct opcode_s *m_op74; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; int m_icount; uint8_t RP(offs_t port); @@ -1443,7 +1441,7 @@ public: upd7807_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); protected: - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void configure_ops() override; }; @@ -1457,7 +1455,7 @@ public: protected: virtual void device_reset() override; virtual void execute_set_input(int inputnum, int state) override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void handle_timers(int cycles) override; virtual void upd7810_take_irq() override; virtual void configure_ops() override; @@ -1477,7 +1475,7 @@ protected: virtual void device_reset() override; virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const override { return (clocks + 4 - 1) / 4; } virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const override { return (cycles * 4); } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void handle_timers(int cycles) override; virtual void configure_ops() override; }; diff --git a/src/devices/cpu/upd7810/upd7810_dasm.cpp b/src/devices/cpu/upd7810/upd7810_dasm.cpp index f3da1ba4160..1af4415486e 100644 --- a/src/devices/cpu/upd7810/upd7810_dasm.cpp +++ b/src/devices/cpu/upd7810/upd7810_dasm.cpp @@ -9,249 +9,52 @@ *****************************************************************************/ #include "emu.h" -#include "debugger.h" -#include "upd7810.h" +#include "upd7810_dasm.h" -namespace { +const char *upd7810_base_disassembler::dasm_s::name() const +{ + return token_names[m_token]; +} -class dasm_s +const char *upd7810_base_disassembler::dasm_s::args() const { -public: - const char *name() const { return token_names[m_token]; } - const char *args() const { return (m_token != prefix) ? reinterpret_cast<const char *>(m_args) : nullptr; } + return (m_token != prefix) ? reinterpret_cast<const char *>(m_args) : nullptr; +} - bool is_prefix() const { return m_token == prefix; } - bool is_call() const { return (m_token == CALB) || (m_token == CALF) || (m_token == CALL) || (m_token == CALT); } - bool is_return() const { return (m_token == RET) || (m_token == RETI); } +bool upd7810_base_disassembler::dasm_s::is_prefix() const +{ + return m_token == prefix; +} - const dasm_s &prefix_get(uint8_t op) const { assert(m_token == prefix); return reinterpret_cast<const dasm_s *>(m_args)[op]; } +bool upd7810_base_disassembler::dasm_s::is_call() const +{ + return (m_token == CALB) || (m_token == CALF) || (m_token == CALL) || (m_token == CALT); +} - static const dasm_s XX_7810[256]; - static const dasm_s XX_7807[256]; +bool upd7810_base_disassembler::dasm_s::is_return() const +{ + return (m_token == RET) || (m_token == RETI); +} - static const dasm_s XX_7801[256]; - static const dasm_s XX_78c05[256]; +const upd7810_base_disassembler::dasm_s &upd7810_base_disassembler::dasm_s::prefix_get(uint8_t op) const +{ + assert(m_token == prefix); + return reinterpret_cast<const dasm_s *>(m_args)[op]; +} -protected: - enum - { - prefix = 0, - illegal, - ACI, - ADC, - ADCW, - ADCX, - ADD, - ADDNC, - ADDNCW, - ADDNCX, - ADDW, - ADDX, - ADI, - ADINC, - ANA, - ANAW, - ANAX, - AND, - ANI, - ANIW, - BIT, - BLOCK, - CALB, - CALF, - CALL, - CALT, - CLC, - CLR, /* 7807 */ - CMC, /* 7807 */ - DAA, - DADC, - DADD, - DADDNC, - DAN, - DCR, - DCRW, - DCX, - DEQ, - DGT, - DI, - DIV, - DLT, - DMOV, - DNE, - DOFF, - DON, - DOR, - DRLL, - DRLR, - DSBB, - DSLL, - DSLR, - DSUB, - DSUBNB, - DXR, - EADD, - EI, - EQA, - EQAW, - EQAX, - EQI, - EQIW, - ESUB, - EX, /* 7801 */ - EXA, - EXH, - EXX, - EXR, /* 7807 */ - GTA, - GTAW, - GTAX, - GTI, - GTIW, - HALT, - IN, /* 7801 */ - INR, - INRW, - INX, - JB, - JEA, - JMP, - JR, - JRE, - LBCD, - LDAW, - LDAX, - LDEAX, - LDED, - LHLD, - LSPD, - LTA, - LTAW, - LTAX, - LTI, - LTIW, - LXI, - MOV, - MUL, - MVI, - MVIW, - MVIX, - NEA, - NEAW, - NEAX, - NEGA, - NEI, - NEIW, - NOP, - NOT, /* 7807 */ - OFFA, - OFFAW, - OFFAX, - OFFI, - OFFIW, - ONA, - ONAW, - ONAX, - ONI, - ONIW, - OR, /* 7807 */ - ORA, - ORAW, - ORAX, - ORI, - ORIW, - OUT, /* 7801 */ - PER, /* 7801 */ - PEX, /* 7801 */ - POP, - PUSH, - RET, - RETI, - RETS, - RLD, - RLL, - RLR, - RRD, - SBB, - SBBW, - SBBX, - SBCD, - SBI, - SDED, - SETB, /* 7807 */ - SHLD, - SIO, /* 7801 */ - SK, - SKIT, - SKN, - SKNIT, - SLL, - SLLC, - SLR, - SLRC, - SOFTI, - SSPD, - STAW, - STAX, - STC, - STEAX, - STM, /* 7801 */ - STOP, - SUB, - SUBNB, - SUBNBW, - SUBNBX, - SUBW, - SUBX, - SUI, - SUINB, - TABLE, - XOR, /* 7807 */ - XRA, - XRAW, - XRAX, - XRI - }; - - dasm_s() : m_token(illegal), m_args(nullptr) { } - dasm_s(uint8_t t, const char *a) : m_token(t), m_args(a) { } - dasm_s(const dasm_s (&a)[256]) : m_token(prefix), m_args(a) { } - - uint8_t m_token; - const void *m_args; - - static const char *const token_names[]; - - static const dasm_s d48_7810[256]; - static const dasm_s d48_7807[256]; - static const dasm_s d4C_7810[256]; - static const dasm_s d4C_7807[256]; - static const dasm_s d4D_7810[256]; - static const dasm_s d4D_7807[256]; - static const dasm_s d60[256]; - static const dasm_s d64_7810[256]; - static const dasm_s d64_7807[256]; - static const dasm_s d70[256]; - static const dasm_s d74[256]; - - static const dasm_s d48_7801[256]; - static const dasm_s d4C_7801[256]; - static const dasm_s d4D_7801[256]; - static const dasm_s d60_7801[256]; - static const dasm_s d64_7801[256]; - static const dasm_s d70_7801[256]; - static const dasm_s d74_7801[256]; - - static const dasm_s d48_78c05[256]; - static const dasm_s d4C_78c05[256]; - static const dasm_s d4D_78c05[256]; - static const dasm_s d60_78c05[256]; - static const dasm_s d64_78c05[256]; - static const dasm_s d70_78c05[256]; - static const dasm_s d74_78c05[256]; -}; +upd7810_base_disassembler::dasm_s::dasm_s() : m_token(illegal), m_args(nullptr) +{ +} -const char *const dasm_s::token_names[] = +upd7810_base_disassembler::dasm_s::dasm_s(uint8_t t, const char *a) : m_token(t), m_args(a) +{ +} + +upd7810_base_disassembler::dasm_s::dasm_s(const dasm_s (&a)[256]) : m_token(prefix), m_args(a) +{ +} + +const char *const upd7810_base_disassembler::dasm_s::token_names[] = { "", "illegal", @@ -431,284 +234,836 @@ const char *const dasm_s::token_names[] = "XRI" }; +// prefix 60 +const upd7810_base_disassembler::dasm_s upd7810_base_disassembler::d60[256] = +{ + { }, // 00: 0110 0000 0000 0000 + { }, // 01: 0110 0000 0000 0001 + { }, // 02: 0110 0000 0000 0010 + { }, // 03: 0110 0000 0000 0011 + { }, // 04: 0110 0000 0000 0100 + { }, // 05: 0110 0000 0000 0101 + { }, // 06: 0110 0000 0000 0110 + { }, // 07: 0110 0000 0000 0111 + {ANA, "V,A" }, // 08: 0110 0000 0000 1000 + {ANA, "A,A" }, // 09: 0110 0000 0000 1001 + {ANA, "B,A" }, // 0a: 0110 0000 0000 1010 + {ANA, "C,A" }, // 0b: 0110 0000 0000 1011 + {ANA, "D,A" }, // 0c: 0110 0000 0000 1100 + {ANA, "E,A" }, // 0d: 0110 0000 0000 1101 + {ANA, "H,A" }, // 0e: 0110 0000 0000 1110 + {ANA, "L,A" }, // 0f: 0110 0000 0000 1111 -// prefix 48 -const dasm_s dasm_s::d48_7810[256] = + {XRA, "V,A" }, // 10: 0110 0000 0001 0000 + {XRA, "A,A" }, // 11: 0110 0000 0001 0001 + {XRA, "B,A" }, // 12: 0110 0000 0001 0010 + {XRA, "C,A" }, // 13: 0110 0000 0001 0011 + {XRA, "D,A" }, // 14: 0110 0000 0001 0100 + {XRA, "E,A" }, // 15: 0110 0000 0001 0101 + {XRA, "H,A" }, // 16: 0110 0000 0001 0110 + {XRA, "L,A" }, // 17: 0110 0000 0001 0111 + {ORA, "V,A" }, // 18: 0110 0000 0001 1000 + {ORA, "A,A" }, // 19: 0110 0000 0001 1001 + {ORA, "B,A" }, // 1a: 0110 0000 0001 1010 + {ORA, "C,A" }, // 1b: 0110 0000 0001 1011 + {ORA, "D,A" }, // 1c: 0110 0000 0001 1100 + {ORA, "E,A" }, // 1d: 0110 0000 0001 1101 + {ORA, "H,A" }, // 1e: 0110 0000 0001 1110 + {ORA, "L,A" }, // 1f: 0110 0000 0001 1111 + + {ADDNC, "V,A" }, // 20: 0110 0000 0010 0000 + {ADDNC, "A,A" }, // 21: 0110 0000 0010 0001 + {ADDNC, "B,A" }, // 22: 0110 0000 0010 0010 + {ADDNC, "C,A" }, // 23: 0110 0000 0010 0011 + {ADDNC, "D,A" }, // 24: 0110 0000 0010 0100 + {ADDNC, "E,A" }, // 25: 0110 0000 0010 0101 + {ADDNC, "H,A" }, // 26: 0110 0000 0010 0110 + {ADDNC, "L,A" }, // 27: 0110 0000 0010 0111 + {GTA, "V,A" }, // 28: 0110 0000 0010 1000 + {GTA, "A,A" }, // 29: 0110 0000 0010 1001 + {GTA, "B,A" }, // 2a: 0110 0000 0010 1010 + {GTA, "C,A" }, // 2b: 0110 0000 0010 1011 + {GTA, "D,A" }, // 2c: 0110 0000 0010 1100 + {GTA, "E,A" }, // 2d: 0110 0000 0010 1101 + {GTA, "H,A" }, // 2e: 0110 0000 0010 1110 + {GTA, "L,A" }, // 2f: 0110 0000 0010 1111 + + {SUBNB, "V,A" }, // 30: 0110 0000 0011 0000 + {SUBNB, "A,A" }, // 31: 0110 0000 0011 0001 + {SUBNB, "B,A" }, // 32: 0110 0000 0011 0010 + {SUBNB, "C,A" }, // 33: 0110 0000 0011 0011 + {SUBNB, "D,A" }, // 34: 0110 0000 0011 0100 + {SUBNB, "E,A" }, // 35: 0110 0000 0011 0101 + {SUBNB, "H,A" }, // 36: 0110 0000 0011 0110 + {SUBNB, "L,A" }, // 37: 0110 0000 0011 0111 + {LTA, "V,A" }, // 38: 0110 0000 0011 1000 + {LTA, "A,A" }, // 39: 0110 0000 0011 1001 + {LTA, "B,A" }, // 3a: 0110 0000 0011 1010 + {LTA, "C,A" }, // 3b: 0110 0000 0011 1011 + {LTA, "D,A" }, // 3c: 0110 0000 0011 1100 + {LTA, "E,A" }, // 3d: 0110 0000 0011 1101 + {LTA, "H,A" }, // 3e: 0110 0000 0011 1110 + {LTA, "L,A" }, // 3f: 0110 0000 0011 1111 + + {ADD, "V,A" }, // 40: 0110 0000 0100 0000 + {ADD, "A,A" }, // 41: 0110 0000 0100 0001 + {ADD, "B,A" }, // 42: 0110 0000 0100 0010 + {ADD, "C,A" }, // 43: 0110 0000 0100 0011 + {ADD, "D,A" }, // 44: 0110 0000 0100 0100 + {ADD, "E,A" }, // 45: 0110 0000 0100 0101 + {ADD, "H,A" }, // 46: 0110 0000 0100 0110 + {ADD, "L,A" }, // 47: 0110 0000 0100 0111 + { }, // 48: 0110 0000 0100 1000 + { }, // 49: 0110 0000 0100 1001 + { }, // 4a: 0110 0000 0100 1010 + { }, // 4b: 0110 0000 0100 1011 + { }, // 4c: 0110 0000 0100 1100 + { }, // 4d: 0110 0000 0100 1101 + { }, // 4e: 0110 0000 0100 1110 + { }, // 4f: 0110 0000 0100 1111 + + {ADC, "V,A" }, // 50: 0110 0000 0101 0000 + {ADC, "A,A" }, // 51: 0110 0000 0101 0001 + {ADC, "B,A" }, // 52: 0110 0000 0101 0010 + {ADC, "C,A" }, // 53: 0110 0000 0101 0011 + {ADC, "D,A" }, // 54: 0110 0000 0101 0100 + {ADC, "E,A" }, // 55: 0110 0000 0101 0101 + {ADC, "H,A" }, // 56: 0110 0000 0101 0110 + {ADC, "L,A" }, // 57: 0110 0000 0101 0111 + { }, // 58: 0110 0000 0101 1000 + { }, // 59: 0110 0000 0101 1001 + { }, // 5a: 0110 0000 0101 1010 + { }, // 5b: 0110 0000 0101 1011 + { }, // 5c: 0110 0000 0101 1100 + { }, // 5d: 0110 0000 0101 1101 + { }, // 5e: 0110 0000 0101 1110 + { }, // 5f: 0110 0000 0101 1111 + + {SUB, "V,A" }, // 60: 0110 0000 0110 0000 + {SUB, "A,A" }, // 61: 0110 0000 0110 0001 + {SUB, "B,A" }, // 62: 0110 0000 0110 0010 + {SUB, "C,A" }, // 63: 0110 0000 0110 0011 + {SUB, "D,A" }, // 64: 0110 0000 0110 0100 + {SUB, "E,A" }, // 65: 0110 0000 0110 0101 + {SUB, "H,A" }, // 66: 0110 0000 0110 0110 + {SUB, "L,A" }, // 67: 0110 0000 0110 0111 + {NEA, "V,A" }, // 68: 0110 0000 0110 1000 + {NEA, "A,A" }, // 69: 0110 0000 0110 1001 + {NEA, "B,A" }, // 6a: 0110 0000 0110 1010 + {NEA, "C,A" }, // 6b: 0110 0000 0110 1011 + {NEA, "D,A" }, // 6c: 0110 0000 0110 1100 + {NEA, "E,A" }, // 6d: 0110 0000 0110 1101 + {NEA, "H,A" }, // 6e: 0110 0000 0110 1110 + {NEA, "L,A" }, // 6f: 0110 0000 0110 1111 + + {SBB, "V,A" }, // 70: 0110 0000 0111 0000 + {SBB, "A,A" }, // 71: 0110 0000 0111 0001 + {SBB, "B,A" }, // 72: 0110 0000 0111 0010 + {SBB, "C,A" }, // 73: 0110 0000 0111 0011 + {SBB, "D,A" }, // 74: 0110 0000 0111 0100 + {SBB, "E,A" }, // 75: 0110 0000 0111 0101 + {SBB, "H,A" }, // 76: 0110 0000 0111 0110 + {SBB, "L,A" }, // 77: 0110 0000 0111 0111 + {EQA, "V,A" }, // 78: 0110 0000 0111 1000 + {EQA, "A,A" }, // 79: 0110 0000 0111 1001 + {EQA, "B,A" }, // 7a: 0110 0000 0111 1010 + {EQA, "C,A" }, // 7b: 0110 0000 0111 1011 + {EQA, "D,A" }, // 7c: 0110 0000 0111 1100 + {EQA, "E,A" }, // 7d: 0110 0000 0111 1101 + {EQA, "H,A" }, // 7e: 0110 0000 0111 1110 + {EQA, "L,A" }, // 7f: 0110 0000 0111 1111 + + { }, // 80: 0110 0000 1000 0000 + { }, // 81: 0110 0000 1000 0001 + { }, // 82: 0110 0000 1000 0010 + { }, // 83: 0110 0000 1000 0011 + { }, // 84: 0110 0000 1000 0100 + { }, // 85: 0110 0000 1000 0101 + { }, // 86: 0110 0000 1000 0110 + { }, // 87: 0110 0000 1000 0111 + {ANA, "A,V" }, // 88: 0110 0000 1000 1000 + {ANA, "A,A" }, // 89: 0110 0000 1000 1001 + {ANA, "A,B" }, // 8a: 0110 0000 1000 1010 + {ANA, "A,C" }, // 8b: 0110 0000 1000 1011 + {ANA, "A,D" }, // 8c: 0110 0000 1000 1100 + {ANA, "A,E" }, // 8d: 0110 0000 1000 1101 + {ANA, "A,H" }, // 8e: 0110 0000 1000 1110 + {ANA, "A,L" }, // 8f: 0110 0000 1000 1111 + + {XRA, "A,V" }, // 90: 0110 0000 1001 0000 + {XRA, "A,A" }, // 91: 0110 0000 1001 0001 + {XRA, "A,B" }, // 92: 0110 0000 1001 0010 + {XRA, "A,C" }, // 93: 0110 0000 1001 0011 + {XRA, "A,D" }, // 94: 0110 0000 1001 0100 + {XRA, "A,E" }, // 95: 0110 0000 1001 0101 + {XRA, "A,H" }, // 96: 0110 0000 1001 0110 + {XRA, "A,L" }, // 97: 0110 0000 1001 0111 + {ORA, "A,V" }, // 98: 0110 0000 1001 1000 + {ORA, "A,A" }, // 99: 0110 0000 1001 1001 + {ORA, "A,B" }, // 9a: 0110 0000 1001 1010 + {ORA, "A,C" }, // 9b: 0110 0000 1001 1011 + {ORA, "A,D" }, // 9c: 0110 0000 1001 1100 + {ORA, "A,E" }, // 9d: 0110 0000 1001 1101 + {ORA, "A,H" }, // 9e: 0110 0000 1001 1110 + {ORA, "A,L" }, // 9f: 0110 0000 1001 1111 + + {ADDNC, "A,V" }, // a0: 0110 0000 1010 0000 + {ADDNC, "A,A" }, // a1: 0110 0000 1010 0001 + {ADDNC, "A,B" }, // a2: 0110 0000 1010 0010 + {ADDNC, "A,C" }, // a3: 0110 0000 1010 0011 + {ADDNC, "A,D" }, // a4: 0110 0000 1010 0100 + {ADDNC, "A,E" }, // a5: 0110 0000 1010 0101 + {ADDNC, "A,H" }, // a6: 0110 0000 1010 0110 + {ADDNC, "A,L" }, // a7: 0110 0000 1010 0111 + {GTA, "A,V" }, // a8: 0110 0000 1010 1000 + {GTA, "A,A" }, // a9: 0110 0000 1010 1001 + {GTA, "A,B" }, // aa: 0110 0000 1010 1010 + {GTA, "A,C" }, // ab: 0110 0000 1010 1011 + {GTA, "A,D" }, // ac: 0110 0000 1010 1100 + {GTA, "A,E" }, // ad: 0110 0000 1010 1101 + {GTA, "A,H" }, // ae: 0110 0000 1010 1110 + {GTA, "A,L" }, // af: 0110 0000 1010 1111 + + {SUBNB, "A,V" }, // b0: 0110 0000 1011 0000 + {SUBNB, "A,A" }, // b1: 0110 0000 1011 0001 + {SUBNB, "A,B" }, // b2: 0110 0000 1011 0010 + {SUBNB, "A,C" }, // b3: 0110 0000 1011 0011 + {SUBNB, "A,D" }, // b4: 0110 0000 1011 0100 + {SUBNB, "A,E" }, // b5: 0110 0000 1011 0101 + {SUBNB, "A,H" }, // b6: 0110 0000 1011 0110 + {SUBNB, "A,L" }, // b7: 0110 0000 1011 0111 + {LTA, "A,V" }, // b8: 0110 0000 1011 1000 + {LTA, "A,A" }, // b9: 0110 0000 1011 1001 + {LTA, "A,B" }, // ba: 0110 0000 1011 1010 + {LTA, "A,C" }, // bb: 0110 0000 1011 1011 + {LTA, "A,D" }, // bc: 0110 0000 1011 1100 + {LTA, "A,E" }, // bd: 0110 0000 1011 1101 + {LTA, "A,H" }, // be: 0110 0000 1011 1110 + {LTA, "A,L" }, // bf: 0110 0000 1011 1111 + + {ADD, "A,V" }, // c0: 0110 0000 1100 0000 + {ADD, "A,A" }, // c1: 0110 0000 1100 0001 + {ADD, "A,B" }, // c2: 0110 0000 1100 0010 + {ADD, "A,C" }, // c3: 0110 0000 1100 0011 + {ADD, "A,D" }, // c4: 0110 0000 1100 0100 + {ADD, "A,E" }, // c5: 0110 0000 1100 0101 + {ADD, "A,H" }, // c6: 0110 0000 1100 0110 + {ADD, "A,L" }, // c7: 0110 0000 1100 0111 + {ONA, "A,V" }, // c8: 0110 0000 1100 1000 + {ONA, "A,A" }, // c9: 0110 0000 1100 1001 + {ONA, "A,B" }, // ca: 0110 0000 1100 1010 + {ONA, "A,C" }, // cb: 0110 0000 1100 1011 + {ONA, "A,D" }, // cc: 0110 0000 1100 1100 + {ONA, "A,E" }, // cd: 0110 0000 1100 1101 + {ONA, "A,H" }, // ce: 0110 0000 1100 1110 + {ONA, "A,L" }, // cf: 0110 0000 1100 1111 + + {ADC, "A,V" }, // d0: 0110 0000 1101 0000 + {ADC, "A,A" }, // d1: 0110 0000 1101 0001 + {ADC, "A,B" }, // d2: 0110 0000 1101 0010 + {ADC, "A,C" }, // d3: 0110 0000 1101 0011 + {ADC, "A,D" }, // d4: 0110 0000 1101 0100 + {ADC, "A,E" }, // d5: 0110 0000 1101 0101 + {ADC, "A,H" }, // d6: 0110 0000 1101 0110 + {ADC, "A,L" }, // d7: 0110 0000 1101 0111 + {OFFA, "A,V" }, // d8: 0110 0000 1101 1000 + {OFFA, "A,A" }, // d9: 0110 0000 1101 1001 + {OFFA, "A,B" }, // da: 0110 0000 1101 1010 + {OFFA, "A,C" }, // db: 0110 0000 1101 1011 + {OFFA, "A,D" }, // dc: 0110 0000 1101 1100 + {OFFA, "A,E" }, // dd: 0110 0000 1101 1101 + {OFFA, "A,H" }, // de: 0110 0000 1101 1110 + {OFFA, "A,L" }, // df: 0110 0000 1101 1111 + + {SUB, "A,V" }, // e0: 0110 0000 1110 0000 + {SUB, "A,A" }, // e1: 0110 0000 1110 0001 + {SUB, "A,B" }, // e2: 0110 0000 1110 0010 + {SUB, "A,C" }, // e3: 0110 0000 1110 0011 + {SUB, "A,D" }, // e4: 0110 0000 1110 0100 + {SUB, "A,E" }, // e5: 0110 0000 1110 0101 + {SUB, "A,H" }, // e6: 0110 0000 1110 0110 + {SUB, "A,L" }, // e7: 0110 0000 1110 0111 + {NEA, "A,V" }, // e8: 0110 0000 1110 1000 + {NEA, "A,A" }, // e9: 0110 0000 1110 1001 + {NEA, "A,B" }, // ea: 0110 0000 1110 1010 + {NEA, "A,C" }, // eb: 0110 0000 1110 1011 + {NEA, "A,D" }, // ec: 0110 0000 1110 1100 + {NEA, "A,E" }, // ed: 0110 0000 1110 1101 + {NEA, "A,H" }, // ee: 0110 0000 1110 1110 + {NEA, "A,L" }, // ef: 0110 0000 1110 1111 + + {SBB, "A,V" }, // f0: 0110 0000 1111 0000 + {SBB, "A,A" }, // f1: 0110 0000 1111 0001 + {SBB, "A,B" }, // f2: 0110 0000 1111 0010 + {SBB, "A,C" }, // f3: 0110 0000 1111 0011 + {SBB, "A,D" }, // f4: 0110 0000 1111 0100 + {SBB, "A,E" }, // f5: 0110 0000 1111 0101 + {SBB, "A,H" }, // f6: 0110 0000 1111 0110 + {SBB, "A,L" }, // f7: 0110 0000 1111 0111 + {EQA, "A,V" }, // f8: 0110 0000 1111 1000 + {EQA, "A,A" }, // f9: 0110 0000 1111 1001 + {EQA, "A,B" }, // fa: 0110 0000 1111 1010 + {EQA, "A,C" }, // fb: 0110 0000 1111 1011 + {EQA, "A,D" }, // fc: 0110 0000 1111 1100 + {EQA, "A,E" }, // fd: 0110 0000 1111 1101 + {EQA, "A,H" }, // fe: 0110 0000 1111 1110 + {EQA, "A,L" } // ff: 0110 0000 1111 1111 +}; + +// prefix 70 +const upd7810_base_disassembler::dasm_s upd7810_base_disassembler::d70[256] = { - { }, // 00: 0100 1000 0000 0000 - {SLRC, "A" }, // 01: 0100 1000 0000 0001 - {SLRC, "B" }, // 02: 0100 1000 0000 0010 - {SLRC, "C" }, // 03: 0100 1000 0000 0011 - { }, // 04: 0100 1000 0000 0100 - {SLLC, "A" }, // 05: 0100 1000 0000 0101 - {SLLC, "B" }, // 06: 0100 1000 0000 0110 - {SLLC, "C" }, // 07: 0100 1000 0000 0111 - {SK, "NV" }, // 08: 0100 1000 0000 1000 - { }, // 09: 0100 1000 0000 1001 - {SK, "CY" }, // 0a: 0100 1000 0000 1010 - {SK, "HC" }, // 0b: 0100 1000 0000 1011 - {SK, "Z" }, // 0c: 0100 1000 0000 1100 - { }, // 0d: 0100 1000 0000 1101 - { }, // 0e: 0100 1000 0000 1110 - { }, // 0f: 0100 1000 0000 1111 + { }, // 00: 0111 0000 0000 0000 + { }, // 01: 0111 0000 0000 0001 + { }, // 02: 0111 0000 0000 0010 + { }, // 03: 0111 0000 0000 0011 + { }, // 04: 0111 0000 0000 0100 + { }, // 05: 0111 0000 0000 0101 + { }, // 06: 0111 0000 0000 0110 + { }, // 07: 0111 0000 0000 0111 + { }, // 08: 0111 0000 0000 1000 + { }, // 09: 0111 0000 0000 1001 + { }, // 0a: 0111 0000 0000 1010 + { }, // 0b: 0111 0000 0000 1011 + { }, // 0c: 0111 0000 0000 1100 + { }, // 0d: 0111 0000 0000 1101 + {SSPD, "%w" }, // 0e: 0111 0000 0000 1110 llll llll hhhh hhhh + {LSPD, "%w" }, // 0f: 0111 0000 0000 1111 llll llll hhhh hhhh - { }, // 10: 0100 1000 0001 0000 - { }, // 11: 0100 1000 0001 0001 - { }, // 12: 0100 1000 0001 0010 - { }, // 13: 0100 1000 0001 0011 - { }, // 14: 0100 1000 0001 0100 - { }, // 15: 0100 1000 0001 0101 - { }, // 16: 0100 1000 0001 0110 - { }, // 17: 0100 1000 0001 0111 - {SKN, "NV" }, // 18: 0100 1000 0001 1000 - { }, // 19: 0100 1000 0001 1001 - {SKN, "CY" }, // 1a: 0100 1000 0001 1010 - {SKN, "HC" }, // 1b: 0100 1000 0001 1011 - {SKN, "Z" }, // 1c: 0100 1000 0001 1100 - { }, // 1d: 0100 1000 0001 1101 - { }, // 1e: 0100 1000 0001 1110 - { }, // 1f: 0100 1000 0001 1111 + { }, // 10: 0111 0000 0001 0000 + { }, // 11: 0111 0000 0001 0001 + { }, // 12: 0111 0000 0001 0010 + { }, // 13: 0111 0000 0001 0011 + { }, // 14: 0111 0000 0001 0100 + { }, // 15: 0111 0000 0001 0101 + { }, // 16: 0111 0000 0001 0110 + { }, // 17: 0111 0000 0001 0111 + { }, // 18: 0111 0000 0001 1000 + { }, // 19: 0111 0000 0001 1001 + { }, // 1a: 0111 0000 0001 1010 + { }, // 1b: 0111 0000 0001 1011 + { }, // 1c: 0111 0000 0001 1100 + { }, // 1d: 0111 0000 0001 1101 + {SBCD, "%w" }, // 1e: 0111 0000 0001 1110 llll llll hhhh hhhh + {LBCD, "%w" }, // 1f: 0111 0000 0001 1111 llll llll hhhh hhhh - { }, // 20: 0100 1000 0010 0000 - {SLR, "A" }, // 21: 0100 1000 0010 0001 - {SLR, "B" }, // 22: 0100 1000 0010 0010 - {SLR, "C" }, // 23: 0100 1000 0010 0011 - { }, // 24: 0100 1000 0010 0100 - {SLL, "A" }, // 25: 0100 1000 0010 0101 - {SLL, "B" }, // 26: 0100 1000 0010 0110 - {SLL, "C" }, // 27: 0100 1000 0010 0111 - {JEA, nullptr }, // 28: 0100 1000 0010 1000 - {CALB,nullptr }, // 29: 0100 1000 0010 1001 - {CLC, nullptr }, // 2a: 0100 1000 0010 1010 - {STC, nullptr }, // 2b: 0100 1000 0010 1011 - { }, // 2c: 0100 1000 0010 1100 - {MUL, "A" }, // 2d: 0100 1000 0010 1101 - {MUL, "B" }, // 2e: 0100 1000 0010 1110 - {MUL, "C" }, // 2f: 0100 1000 0010 1111 + { }, // 20: 0111 0000 0010 0000 + { }, // 21: 0111 0000 0010 0001 + { }, // 22: 0111 0000 0010 0010 + { }, // 23: 0111 0000 0010 0011 + { }, // 24: 0111 0000 0010 0100 + { }, // 25: 0111 0000 0010 0101 + { }, // 26: 0111 0000 0010 0110 + { }, // 27: 0111 0000 0010 0111 + { }, // 28: 0111 0000 0010 1000 + { }, // 29: 0111 0000 0010 1001 + { }, // 2a: 0111 0000 0010 1010 + { }, // 2b: 0111 0000 0010 1011 + { }, // 2c: 0111 0000 0010 1100 + { }, // 2d: 0111 0000 0010 1101 + {SDED, "%w" }, // 2e: 0111 0000 0010 1110 llll llll hhhh hhhh + {LDED, "%w" }, // 2f: 0111 0000 0010 1111 llll llll hhhh hhhh - { }, // 30: 0100 1000 0011 0000 - {RLR, "A" }, // 31: 0100 1000 0011 0001 - {RLR, "B" }, // 32: 0100 1000 0011 0010 - {RLR, "C" }, // 33: 0100 1000 0011 0011 - { }, // 34: 0100 1000 0011 0100 - {RLL, "A" }, // 35: 0100 1000 0011 0101 - {RLL, "B" }, // 36: 0100 1000 0011 0110 - {RLL, "C" }, // 37: 0100 1000 0011 0111 - {RLD, nullptr }, // 38: 0100 1000 0011 1000 - {RRD, nullptr }, // 39: 0100 1000 0011 1001 - {NEGA, nullptr }, // 3a: 0100 1000 0011 1010 - {HALT, nullptr }, // 3b: 0100 1000 0011 1011 - { }, // 3c: 0100 1000 0011 1100 - {DIV, "A" }, // 3d: 0100 1000 0011 1101 - {DIV, "B" }, // 3e: 0100 1000 0011 1110 - {DIV, "C" }, // 3f: 0100 1000 0011 1111 + { }, // 30: 0111 0000 0011 0000 + { }, // 31: 0111 0000 0011 0001 + { }, // 32: 0111 0000 0011 0010 + { }, // 33: 0111 0000 0011 0011 + { }, // 34: 0111 0000 0011 0100 + { }, // 35: 0111 0000 0011 0101 + { }, // 36: 0111 0000 0011 0110 + { }, // 37: 0111 0000 0011 0111 + { }, // 38: 0111 0000 0011 1000 + { }, // 39: 0111 0000 0011 1001 + { }, // 3a: 0111 0000 0011 1010 + { }, // 3b: 0111 0000 0011 1011 + { }, // 3c: 0111 0000 0011 1100 + { }, // 3d: 0111 0000 0011 1101 + {SHLD, "%w" }, // 3e: 0111 0000 0011 1110 llll llll hhhh hhhh + {LHLD, "%w" }, // 3f: 0111 0000 0011 1111 llll llll hhhh hhhh - {SKIT, "NMI" }, // 40: 0100 1000 0100 0000 - {SKIT, "FT0" }, // 41: 0100 1000 0100 0001 - {SKIT, "FT1" }, // 42: 0100 1000 0100 0010 - {SKIT, "F1" }, // 43: 0100 1000 0100 0011 - {SKIT, "F2" }, // 44: 0100 1000 0100 0100 - {SKIT, "FE0" }, // 45: 0100 1000 0100 0101 - {SKIT, "FE1" }, // 46: 0100 1000 0100 0110 - {SKIT, "FEIN" }, // 47: 0100 1000 0100 0111 - {SKIT, "FAD" }, // 48: 0100 1000 0100 1000 - {SKIT, "FSR" }, // 49: 0100 1000 0100 1001 - {SKIT, "FST" }, // 4a: 0100 1000 0100 1010 - {SKIT, "ER" }, // 4b: 0100 1000 0100 1011 - {SKIT, "OV" }, // 4c: 0100 1000 0100 1100 - { }, // 4d: 0100 1000 0100 1101 - { }, // 4e: 0100 1000 0100 1110 - { }, // 4f: 0100 1000 0100 1111 + {EADD, "EA,V" }, // 40: 0111 0000 0100 0000 + {EADD, "EA,A" }, // 41: 0111 0000 0100 0001 + {EADD, "EA,B" }, // 42: 0111 0000 0100 0010 + {EADD, "EA,C" }, // 43: 0111 0000 0100 0011 + { }, // 44: 0111 0000 0100 0100 + { }, // 45: 0111 0000 0100 0101 + { }, // 46: 0111 0000 0100 0110 + { }, // 47: 0111 0000 0100 0111 + { }, // 48: 0111 0000 0100 1000 + { }, // 49: 0111 0000 0100 1001 + { }, // 4a: 0111 0000 0100 1010 + { }, // 4b: 0111 0000 0100 1011 + { }, // 4c: 0111 0000 0100 1100 + { }, // 4d: 0111 0000 0100 1101 + { }, // 4e: 0111 0000 0100 1110 + { }, // 4f: 0111 0000 0100 1111 - {SKIT, "AN4" }, // 50: 0100 1000 0101 0000 - {SKIT, "AN5" }, // 51: 0100 1000 0101 0001 - {SKIT, "AN6" }, // 52: 0100 1000 0101 0010 - {SKIT, "AN7" }, // 53: 0100 1000 0101 0011 - {SKIT, "SB" }, // 54: 0100 1000 0101 0100 - { }, // 55: 0100 1000 0101 0101 - { }, // 56: 0100 1000 0101 0110 - { }, // 57: 0100 1000 0101 0111 - { }, // 58: 0100 1000 0101 1000 - { }, // 59: 0100 1000 0101 1001 - { }, // 5a: 0100 1000 0101 1010 - { }, // 5b: 0100 1000 0101 1011 - { }, // 5c: 0100 1000 0101 1100 - { }, // 5d: 0100 1000 0101 1101 - { }, // 5e: 0100 1000 0101 1110 - { }, // 5f: 0100 1000 0101 1111 + { }, // 50: 0111 0000 0101 0000 + { }, // 51: 0111 0000 0101 0001 + { }, // 52: 0111 0000 0101 0010 + { }, // 53: 0111 0000 0101 0011 + { }, // 54: 0111 0000 0101 0100 + { }, // 55: 0111 0000 0101 0101 + { }, // 56: 0111 0000 0101 0110 + { }, // 57: 0111 0000 0101 0111 + { }, // 58: 0111 0000 0101 1000 + { }, // 59: 0111 0000 0101 1001 + { }, // 5a: 0111 0000 0101 1010 + { }, // 5b: 0111 0000 0101 1011 + { }, // 5c: 0111 0000 0101 1100 + { }, // 5d: 0111 0000 0101 1101 + { }, // 5e: 0111 0000 0101 1110 + { }, // 5f: 0111 0000 0101 1111 - {SKNIT, "NMI" }, // 60: 0100 1000 0110 0000 - {SKNIT, "FT0" }, // 61: 0100 1000 0110 0001 - {SKNIT, "FT1" }, // 62: 0100 1000 0110 0010 - {SKNIT, "F1" }, // 63: 0100 1000 0110 0011 - {SKNIT, "F2" }, // 64: 0100 1000 0110 0100 - {SKNIT, "FE0" }, // 65: 0100 1000 0110 0101 - {SKNIT, "FE1" }, // 66: 0100 1000 0110 0110 - {SKNIT, "FEIN" }, // 67: 0100 1000 0110 0111 - {SKNIT, "FAD" }, // 68: 0100 1000 0110 1000 - {SKNIT, "FSR" }, // 69: 0100 1000 0110 1001 - {SKNIT, "FST" }, // 6a: 0100 1000 0110 1010 - {SKNIT, "ER" }, // 6b: 0100 1000 0110 1011 - {SKNIT, "OV" }, // 6c: 0100 1000 0110 1100 - { }, // 6d: 0100 1000 0110 1101 - { }, // 6e: 0100 1000 0110 1110 - { }, // 6f: 0100 1000 0110 1111 + {ESUB, "EA,V" }, // 60: 0111 0000 0110 0000 + {ESUB, "EA,A" }, // 61: 0111 0000 0110 0001 + {ESUB, "EA,B" }, // 62: 0111 0000 0110 0010 + {ESUB, "EA,C" }, // 63: 0111 0000 0110 0011 + { }, // 64: 0111 0000 0110 0100 + { }, // 65: 0111 0000 0110 0101 + { }, // 66: 0111 0000 0110 0110 + { }, // 67: 0111 0000 0110 0111 + {MOV, "V,(%w)" }, // 68: 0111 0000 0110 1000 llll llll hhhh hhhh + {MOV, "A,(%w)" }, // 69: 0111 0000 0110 1001 llll llll hhhh hhhh + {MOV, "B,(%w)" }, // 6a: 0111 0000 0110 1010 llll llll hhhh hhhh + {MOV, "C,(%w)" }, // 6b: 0111 0000 0110 1011 llll llll hhhh hhhh + {MOV, "D,(%w)" }, // 6c: 0111 0000 0110 1100 llll llll hhhh hhhh + {MOV, "E,(%w)" }, // 6d: 0111 0000 0110 1101 llll llll hhhh hhhh + {MOV, "H,(%w)" }, // 6e: 0111 0000 0110 1110 llll llll hhhh hhhh + {MOV, "L,(%w)" }, // 6f: 0111 0000 0110 1111 llll llll hhhh hhhh - {SKNIT, "AN4" }, // 70: 0100 1000 0111 0000 - {SKNIT, "AN5" }, // 71: 0100 1000 0111 0001 - {SKNIT, "AN6" }, // 72: 0100 1000 0111 0010 - {SKNIT, "AN7" }, // 73: 0100 1000 0111 0011 - {SKNIT, "SB" }, // 74: 0100 1000 0111 0100 - { }, // 75: 0100 1000 0111 0101 - { }, // 76: 0100 1000 0111 0110 - { }, // 77: 0100 1000 0111 0111 - { }, // 78: 0100 1000 0111 1000 - { }, // 79: 0100 1000 0111 1001 - { }, // 7a: 0100 1000 0111 1010 - { }, // 7b: 0100 1000 0111 1011 - { }, // 7c: 0100 1000 0111 1100 - { }, // 7d: 0100 1000 0111 1101 - { }, // 7e: 0100 1000 0111 1110 - { }, // 7f: 0100 1000 0111 1111 + { }, // 70: 0111 0000 0111 0000 + { }, // 71: 0111 0000 0111 0001 + { }, // 72: 0111 0000 0111 0010 + { }, // 73: 0111 0000 0111 0011 + { }, // 74: 0111 0000 0111 0100 + { }, // 75: 0111 0000 0111 0101 + { }, // 76: 0111 0000 0111 0110 + { }, // 77: 0111 0000 0111 0111 + {MOV, "(%w),V" }, // 78: 0111 0000 0111 1000 llll llll hhhh hhhh + {MOV, "(%w),A" }, // 79: 0111 0000 0111 1001 llll llll hhhh hhhh + {MOV, "(%w),B" }, // 7a: 0111 0000 0111 1010 llll llll hhhh hhhh + {MOV, "(%w),C" }, // 7b: 0111 0000 0111 1011 llll llll hhhh hhhh + {MOV, "(%w),D" }, // 7c: 0111 0000 0111 1100 llll llll hhhh hhhh + {MOV, "(%w),E" }, // 7d: 0111 0000 0111 1101 llll llll hhhh hhhh + {MOV, "(%w),H" }, // 7e: 0111 0000 0111 1110 llll llll hhhh hhhh + {MOV, "(%w),L" }, // 7f: 0111 0000 0111 1111 llll llll hhhh hhhh - { }, // 80: 0100 1000 1000 0000 - { }, // 81: 0100 1000 1000 0001 - {LDEAX, "(DE)" }, // 82: 0100 1000 1000 0010 - {LDEAX, "(HL)" }, // 83: 0100 1000 1000 0011 - {LDEAX, "(DE++)" }, // 84: 0100 1000 1000 0100 - {LDEAX, "(HL++)" }, // 85: 0100 1000 1000 0101 - { }, // 86: 0100 1000 1000 0110 - { }, // 87: 0100 1000 1000 0111 - { }, // 88: 0100 1000 1000 1000 - { }, // 89: 0100 1000 1000 1001 - { }, // 8a: 0100 1000 1000 1010 - {LDEAX, "(DE+%b)" }, // 8b: 0100 1000 1000 1011 xxxx xxxx - {LDEAX, "(HL+A)" }, // 8c: 0100 1000 1000 1100 - {LDEAX, "(HL+B)" }, // 8d: 0100 1000 1000 1101 - {LDEAX, "(HL+EA)" }, // 8e: 0100 1000 1000 1110 - {LDEAX, "(HL+%b)" }, // 8f: 0100 1000 1000 1111 xxxx xxxx + { }, // 80: 0111 0000 1000 0000 + { }, // 81: 0111 0000 1000 0001 + { }, // 82: 0111 0000 1000 0010 + { }, // 83: 0111 0000 1000 0011 + { }, // 84: 0111 0000 1000 0100 + { }, // 85: 0111 0000 1000 0101 + { }, // 86: 0111 0000 1000 0110 + { }, // 87: 0111 0000 1000 0111 + { }, // 88: 0111 0000 1000 1000 + {ANAX, "(BC)" }, // 89: 0111 0000 1000 1001 + {ANAX, "(DE)" }, // 8a: 0111 0000 1000 1010 + {ANAX, "(HL)" }, // 8b: 0111 0000 1000 1011 + {ANAX, "(DE+)" }, // 8c: 0111 0000 1000 1100 + {ANAX, "(HL+)" }, // 8d: 0111 0000 1000 1101 + {ANAX, "(DE-)" }, // 8e: 0111 0000 1000 1110 + {ANAX, "(HL-)" }, // 8f: 0111 0000 1000 1111 - { }, // 90: 0100 1000 1000 0000 - { }, // 91: 0100 1000 1000 0001 - {STEAX, "(DE)" }, // 92: 0100 1000 1000 0010 - {STEAX, "(HL)" }, // 93: 0100 1000 1000 0011 - {STEAX, "(DE++)" }, // 94: 0100 1000 1000 0100 - {STEAX, "(HL++)" }, // 95: 0100 1000 1000 0101 - { }, // 96: 0100 1000 1000 0110 - { }, // 97: 0100 1000 1000 0111 - { }, // 98: 0100 1000 1000 1000 - { }, // 99: 0100 1000 1000 1001 - { }, // 9a: 0100 1000 1000 1010 - {STEAX, "(DE+%b)" }, // 9b: 0100 1000 1000 1011 xxxx xxxx - {STEAX, "(HL+A)" }, // 9c: 0100 1000 1000 1100 - {STEAX, "(HL+B)" }, // 9d: 0100 1000 1000 1101 - {STEAX, "(HL+EA)" }, // 9e: 0100 1000 1000 1110 - {STEAX, "(HL+%b)" }, // 9f: 0100 1000 1000 1111 xxxx xxxx + { }, // 90: 0111 0000 1001 0000 + {XRAX, "(BC)" }, // 91: 0111 0000 1001 0001 + {XRAX, "(DE)" }, // 92: 0111 0000 1001 0010 + {XRAX, "(HL)" }, // 93: 0111 0000 1001 0011 + {XRAX, "(DE+)" }, // 94: 0111 0000 1001 0100 + {XRAX, "(HL+)" }, // 95: 0111 0000 1001 0101 + {XRAX, "(DE-)" }, // 96: 0111 0000 1001 0110 + {XRAX, "(HL-)" }, // 97: 0111 0000 1001 0111 + { }, // 98: 0111 0000 1001 1000 + {ORAX, "(BC)" }, // 99: 0111 0000 1001 1001 + {ORAX, "(DE)" }, // 9a: 0111 0000 1001 1010 + {ORAX, "(HL)" }, // 9b: 0111 0000 1001 1011 + {ORAX, "(DE+)" }, // 9c: 0111 0000 1001 1100 + {ORAX, "(HL+)" }, // 9d: 0111 0000 1001 1101 + {ORAX, "(DE-)" }, // 9e: 0111 0000 1001 1110 + {ORAX, "(HL-)" }, // 9f: 0111 0000 1001 1111 - {DSLR, "EA" }, // a0: 0100 1000 1010 0000 - { }, // a1: 0100 1000 1010 0001 - { }, // a2: 0100 1000 1010 0010 - { }, // a3: 0100 1000 1010 0011 - {DSLL, "EA" }, // a4: 0100 1000 1010 0100 - { }, // a5: 0100 1000 1010 0101 - { }, // a6: 0100 1000 1010 0110 - { }, // a7: 0100 1000 1010 0111 - {TABLE, nullptr }, // a8: 0100 1000 1010 1000 - { }, // a9: 0100 1000 1010 1001 - { }, // aa: 0100 1000 1010 1010 - { }, // ab: 0100 1000 1010 1011 - { }, // ac: 0100 1000 1010 1100 - { }, // ad: 0100 1000 1010 1101 - { }, // ae: 0100 1000 1010 1110 - { }, // af: 0100 1000 1010 1111 + { }, // a0: 0111 0000 1010 0000 + {ADDNCX, "(BC)" }, // a1: 0111 0000 1010 0001 + {ADDNCX, "(DE)" }, // a2: 0111 0000 1010 0010 + {ADDNCX, "(HL)" }, // a3: 0111 0000 1010 0011 + {ADDNCX, "(DE+)" }, // a4: 0111 0000 1010 0100 + {ADDNCX, "(HL+)" }, // a5: 0111 0000 1010 0101 + {ADDNCX, "(DE-)" }, // a6: 0111 0000 1010 0110 + {ADDNCX, "(HL-)" }, // a7: 0111 0000 1010 0111 + { }, // a8: 0111 0000 1010 1000 + {GTAX, "(BC)" }, // a9: 0111 0000 1010 1001 + {GTAX, "(DE)" }, // aa: 0111 0000 1010 1010 + {GTAX, "(HL)" }, // ab: 0111 0000 1010 1011 + {GTAX, "(DE+)" }, // ac: 0111 0000 1010 1100 + {GTAX, "(HL+)" }, // ad: 0111 0000 1010 1101 + {GTAX, "(DE-)" }, // ae: 0111 0000 1010 1110 + {GTAX, "(HL-)" }, // af: 0111 0000 1010 1111 - {DRLR, "EA" }, // b0: 0100 1000 1011 0000 - { }, // b1: 0100 1000 1011 0001 - { }, // b2: 0100 1000 1011 0010 - { }, // b3: 0100 1000 1011 0011 - {DRLL, "EA" }, // b4: 0100 1000 1011 0100 - { }, // b5: 0100 1000 1011 0101 - { }, // b6: 0100 1000 1011 0110 - { }, // b7: 0100 1000 1011 0111 - { }, // b8: 0100 1000 1011 1000 - { }, // b9: 0100 1000 1011 1001 - { }, // ba: 0100 1000 1011 1010 - {STOP, nullptr }, // bb: 0100 1000 1011 1011 7810 - { }, // bc: 0100 1000 1011 1100 - { }, // bd: 0100 1000 1011 1101 - { }, // be: 0100 1000 1011 1110 - { }, // bf: 0100 1000 1011 1111 + { }, // b0: 0111 0000 1011 0000 + {SUBNBX, "(BC)" }, // b1: 0111 0000 1011 0001 + {SUBNBX, "(DE)" }, // b2: 0111 0000 1011 0010 + {SUBNBX, "(HL)" }, // b3: 0111 0000 1011 0011 + {SUBNBX, "(DE+)" }, // b4: 0111 0000 1011 0100 + {SUBNBX, "(HL+)" }, // b5: 0111 0000 1011 0101 + {SUBNBX, "(DE-)" }, // b6: 0111 0000 1011 0110 + {SUBNBX, "(HL-)" }, // b7: 0111 0000 1011 0111 + { }, // b8: 0111 0000 1011 1000 + {LTAX, "(BC)" }, // b9: 0111 0000 1011 1001 + {LTAX, "(DE)" }, // ba: 0111 0000 1011 1010 + {LTAX, "(HL)" }, // bb: 0111 0000 1011 1011 + {LTAX, "(DE+)" }, // bc: 0111 0000 1011 1100 + {LTAX, "(HL+)" }, // bd: 0111 0000 1011 1101 + {LTAX, "(DE-)" }, // be: 0111 0000 1011 1110 + {LTAX, "(HL-)" }, // bf: 0111 0000 1011 1111 - {DMOV, "EA,ECNT" }, // c0: 0100 1000 1100 0000 - {DMOV, "EA,ECPT" }, // c1: 0100 1000 1100 0001 7810 - { }, // c2: 0100 1000 1100 0010 - { }, // c3: 0100 1000 1100 0011 - { }, // c4: 0100 1000 1100 0100 - { }, // c5: 0100 1000 1100 0101 - { }, // c6: 0100 1000 1100 0110 - { }, // c7: 0100 1000 1100 0111 - { }, // c8: 0100 1000 1100 1000 - { }, // c9: 0100 1000 1100 1001 - { }, // ca: 0100 1000 1100 1010 - { }, // cb: 0100 1000 1100 1011 - { }, // cc: 0100 1000 1100 1100 - { }, // cd: 0100 1000 1100 1101 - { }, // ce: 0100 1000 1100 1110 - { }, // cf: 0100 1000 1100 1111 + { }, // c0: 0111 0000 1100 0000 + {ADDX, "(BC)" }, // c1: 0111 0000 1100 0001 + {ADDX, "(DE)" }, // c2: 0111 0000 1100 0010 + {ADDX, "(HL)" }, // c3: 0111 0000 1100 0011 + {ADDX, "(DE+)" }, // c4: 0111 0000 1100 0100 + {ADDX, "(HL+)" }, // c5: 0111 0000 1100 0101 + {ADDX, "(DE-)" }, // c6: 0111 0000 1100 0110 + {ADDX, "(HL-)" }, // c7: 0111 0000 1100 0111 + { }, // c8: 0111 0000 1100 1000 + {ONAX, "(BC)" }, // c9: 0111 0000 1100 1001 + {ONAX, "(DE)" }, // ca: 0111 0000 1100 1010 + {ONAX, "(HL)" }, // cb: 0111 0000 1100 1011 + {ONAX, "(DE+)" }, // cc: 0111 0000 1100 1100 + {ONAX, "(HL+)" }, // cd: 0111 0000 1100 1101 + {ONAX, "(DE-)" }, // ce: 0111 0000 1100 1110 + {ONAX, "(HL-)" }, // cf: 0111 0000 1100 1111 - { }, // d0: 0100 1000 1101 0000 - { }, // d1: 0100 1000 1101 0001 - {DMOV, "ETM0,EA" }, // d2: 0100 1000 1101 0010 - {DMOV, "ETM1,EA" }, // d3: 0100 1000 1101 0011 - { }, // d4: 0100 1000 1101 0100 - { }, // d5: 0100 1000 1101 0101 - { }, // d6: 0100 1000 1101 0110 - { }, // d7: 0100 1000 1101 0111 - { }, // d8: 0100 1000 1101 1000 - { }, // d9: 0100 1000 1101 1001 - { }, // da: 0100 1000 1101 1010 - { }, // db: 0100 1000 1101 1011 - { }, // dc: 0100 1000 1101 1100 - { }, // dd: 0100 1000 1101 1101 - { }, // de: 0100 1000 1101 1110 - { }, // df: 0100 1000 1101 1111 + { }, // d0: 0111 0000 1101 0000 + {ADCX, "(BC)" }, // d1: 0111 0000 1101 0001 + {ADCX, "(DE)" }, // d2: 0111 0000 1101 0010 + {ADCX, "(HL)" }, // d3: 0111 0000 1101 0011 + {ADCX, "(DE+)" }, // d4: 0111 0000 1101 0100 + {ADCX, "(HL+)" }, // d5: 0111 0000 1101 0101 + {ADCX, "(DE-)" }, // d6: 0111 0000 1101 0110 + {ADCX, "(HL-)" }, // d7: 0111 0000 1101 0111 + { }, // d8: 0111 0000 1101 1000 + {OFFAX, "(BC)" }, // d9: 0111 0000 1101 1001 + {OFFAX, "(DE)" }, // da: 0111 0000 1101 1010 + {OFFAX, "(HL)" }, // db: 0111 0000 1101 1011 + {OFFAX, "(DE+)" }, // dc: 0111 0000 1101 1100 + {OFFAX, "(HL+)" }, // dd: 0111 0000 1101 1101 + {OFFAX, "(DE-)" }, // de: 0111 0000 1101 1110 + {OFFAX, "(HL-)" }, // df: 0111 0000 1101 1111 - { }, // e0: 0100 1000 1110 0000 - { }, // e1: 0100 1000 1110 0001 - { }, // e2: 0100 1000 1110 0010 - { }, // e3: 0100 1000 1110 0011 - { }, // e4: 0100 1000 1110 0100 - { }, // e5: 0100 1000 1110 0101 - { }, // e6: 0100 1000 1110 0110 - { }, // e7: 0100 1000 1110 0111 - { }, // e8: 0100 1000 1110 1000 - { }, // e9: 0100 1000 1110 1001 - { }, // ea: 0100 1000 1110 1010 - { }, // eb: 0100 1000 1110 1011 - { }, // ec: 0100 1000 1110 1100 - { }, // ed: 0100 1000 1110 1101 - { }, // ee: 0100 1000 1110 1110 - { }, // ef: 0100 1000 1110 1111 + { }, // e0: 0111 0000 1110 0000 + {SUBX, "(BC)" }, // e1: 0111 0000 1110 0001 + {SUBX, "(DE)" }, // e2: 0111 0000 1110 0010 + {SUBX, "(HL)" }, // e3: 0111 0000 1110 0011 + {SUBX, "(DE+)" }, // e4: 0111 0000 1110 0100 + {SUBX, "(HL+)" }, // e5: 0111 0000 1110 0101 + {SUBX, "(DE-)" }, // e6: 0111 0000 1110 0110 + {SUBX, "(HL-)" }, // e7: 0111 0000 1110 0111 + { }, // e8: 0111 0000 1110 1000 + {NEAX, "(BC)" }, // e9: 0111 0000 1110 1001 + {NEAX, "(DE)" }, // ea: 0111 0000 1110 1010 + {NEAX, "(HL)" }, // eb: 0111 0000 1110 1011 + {NEAX, "(DE+)" }, // ec: 0111 0000 1110 1100 + {NEAX, "(HL+)" }, // ed: 0111 0000 1110 1101 + {NEAX, "(DE-)" }, // ee: 0111 0000 1110 1110 + {NEAX, "(HL-)" }, // ef: 0111 0000 1110 1111 - { }, // f0: 0100 1000 1111 0000 - { }, // f1: 0100 1000 1111 0001 - { }, // f2: 0100 1000 1111 0010 - { }, // f3: 0100 1000 1111 0011 - { }, // f4: 0100 1000 1111 0100 - { }, // f5: 0100 1000 1111 0101 - { }, // f6: 0100 1000 1111 0110 - { }, // f7: 0100 1000 1111 0111 - { }, // f8: 0100 1000 1111 1000 - { }, // f9: 0100 1000 1111 1001 - { }, // fa: 0100 1000 1111 1010 - { }, // fb: 0100 1000 1111 1011 - { }, // fc: 0100 1000 1111 1100 - { }, // fd: 0100 1000 1111 1101 - { }, // fe: 0100 1000 1111 1110 - { } // ff: 0100 1000 1111 1111 + { }, // f0: 0111 0000 1111 0000 + {SBBX, "(BC)" }, // f1: 0111 0000 1111 0001 + {SBBX, "(DE)" }, // f2: 0111 0000 1111 0010 + {SBBX, "(HL)" }, // f3: 0111 0000 1111 0011 + {SBBX, "(DE+)" }, // f4: 0111 0000 1111 0100 + {SBBX, "(HL+)" }, // f5: 0111 0000 1111 0101 + {SBBX, "(DE-)" }, // f6: 0111 0000 1111 0110 + {SBBX, "(HL-)" }, // f7: 0111 0000 1111 0111 + { }, // f8: 0111 0000 1111 1000 + {EQAX, "(BC)" }, // f9: 0111 0000 1111 1001 + {EQAX, "(DE)" }, // fa: 0111 0000 1111 1010 + {EQAX, "(HL)" }, // fb: 0111 0000 1111 1011 + {EQAX, "(DE+)" }, // fc: 0111 0000 1111 1100 + {EQAX, "(HL+)" }, // fd: 0111 0000 1111 1101 + {EQAX, "(DE-)" }, // fe: 0111 0000 1111 1110 + {EQAX, "(HL-)" } // ff: 0111 0000 1111 1111 +}; + +// prefix 74 +const upd7810_base_disassembler::dasm_s upd7810_base_disassembler::d74[256] = +{ + { }, // 00: 0111 0100 0000 0000 + { }, // 01: 0111 0100 0000 0001 + { }, // 02: 0111 0100 0000 0010 + { }, // 03: 0111 0100 0000 0011 + { }, // 04: 0111 0100 0000 0100 + { }, // 05: 0111 0100 0000 0101 + { }, // 06: 0111 0100 0000 0110 + { }, // 07: 0111 0100 0000 0111 + {ANI, "V,%b" }, // 08: 0111 0100 0000 1000 xxxx xxxx + {ANI, "A,%b" }, // 09: 0111 0100 0000 1001 xxxx xxxx + {ANI, "B,%b" }, // 0a: 0111 0100 0000 1010 xxxx xxxx + {ANI, "C,%b" }, // 0b: 0111 0100 0000 1011 xxxx xxxx + {ANI, "D,%b" }, // 0c: 0111 0100 0000 1100 xxxx xxxx + {ANI, "E,%b" }, // 0d: 0111 0100 0000 1101 xxxx xxxx + {ANI, "H,%b" }, // 0e: 0111 0100 0000 1110 xxxx xxxx + {ANI, "L,%b" }, // 0f: 0111 0100 0000 1111 xxxx xxxx + + {XRI, "V,%b" }, // 10: 0111 0100 0001 0000 xxxx xxxx + {XRI, "A,%b" }, // 11: 0111 0100 0001 0001 xxxx xxxx + {XRI, "B,%b" }, // 12: 0111 0100 0001 0010 xxxx xxxx + {XRI, "C,%b" }, // 13: 0111 0100 0001 0011 xxxx xxxx + {XRI, "D,%b" }, // 14: 0111 0100 0001 0100 xxxx xxxx + {XRI, "E,%b" }, // 15: 0111 0100 0001 0101 xxxx xxxx + {XRI, "H,%b" }, // 16: 0111 0100 0001 0110 xxxx xxxx + {XRI, "L,%b" }, // 17: 0111 0100 0001 0111 xxxx xxxx + {ORI, "V,%b" }, // 18: 0111 0100 0001 1000 xxxx xxxx + {ORI, "A,%b" }, // 19: 0111 0100 0001 1001 xxxx xxxx + {ORI, "B,%b" }, // 1a: 0111 0100 0001 1010 xxxx xxxx + {ORI, "C,%b" }, // 1b: 0111 0100 0001 1011 xxxx xxxx + {ORI, "D,%b" }, // 1c: 0111 0100 0001 1100 xxxx xxxx + {ORI, "E,%b" }, // 1d: 0111 0100 0001 1101 xxxx xxxx + {ORI, "H,%b" }, // 1e: 0111 0100 0001 1110 xxxx xxxx + {ORI, "L,%b" }, // 1f: 0111 0100 0001 1111 xxxx xxxx + + {ADINC, "V,%b" }, // 20: 0111 0100 0010 0000 xxxx xxxx + {ADINC, "A,%b" }, // 21: 0111 0100 0010 0001 xxxx xxxx + {ADINC, "B,%b" }, // 22: 0111 0100 0010 0010 xxxx xxxx + {ADINC, "C,%b" }, // 23: 0111 0100 0010 0011 xxxx xxxx + {ADINC, "D,%b" }, // 24: 0111 0100 0010 0100 xxxx xxxx + {ADINC, "E,%b" }, // 25: 0111 0100 0010 0101 xxxx xxxx + {ADINC, "H,%b" }, // 26: 0111 0100 0010 0110 xxxx xxxx + {ADINC, "L,%b" }, // 27: 0111 0100 0010 0111 xxxx xxxx + {GTI, "V,%b" }, // 28: 0111 0100 0010 1000 xxxx xxxx + {GTI, "A,%b" }, // 29: 0111 0100 0010 1001 xxxx xxxx + {GTI, "B,%b" }, // 2a: 0111 0100 0010 1010 xxxx xxxx + {GTI, "C,%b" }, // 2b: 0111 0100 0010 1011 xxxx xxxx + {GTI, "D,%b" }, // 2c: 0111 0100 0010 1100 xxxx xxxx + {GTI, "E,%b" }, // 2d: 0111 0100 0010 1101 xxxx xxxx + {GTI, "H,%b" }, // 2e: 0111 0100 0010 1110 xxxx xxxx + {GTI, "L,%b" }, // 2f: 0111 0100 0010 1111 xxxx xxxx + + {SUINB, "V,%b" }, // 30: 0111 0100 0011 0000 xxxx xxxx + {SUINB, "A,%b" }, // 31: 0111 0100 0011 0001 xxxx xxxx + {SUINB, "B,%b" }, // 32: 0111 0100 0011 0010 xxxx xxxx + {SUINB, "C,%b" }, // 33: 0111 0100 0011 0011 xxxx xxxx + {SUINB, "D,%b" }, // 34: 0111 0100 0011 0100 xxxx xxxx + {SUINB, "E,%b" }, // 35: 0111 0100 0011 0101 xxxx xxxx + {SUINB, "H,%b" }, // 36: 0111 0100 0011 0110 xxxx xxxx + {SUINB, "L,%b" }, // 37: 0111 0100 0011 0111 xxxx xxxx + {LTI, "V,%b" }, // 37: 0111 0100 0011 1000 xxxx xxxx + {LTI, "A,%b" }, // 39: 0111 0100 0011 1001 xxxx xxxx + {LTI, "B,%b" }, // 3a: 0111 0100 0011 1010 xxxx xxxx + {LTI, "C,%b" }, // 3b: 0111 0100 0011 1011 xxxx xxxx + {LTI, "D,%b" }, // 3c: 0111 0100 0011 1100 xxxx xxxx + {LTI, "E,%b" }, // 3d: 0111 0100 0011 1101 xxxx xxxx + {LTI, "H,%b" }, // 3e: 0111 0100 0011 1110 xxxx xxxx + {LTI, "L,%b" }, // 3f: 0111 0100 0011 1111 xxxx xxxx + + {ADI, "V,%b" }, // 40: 0111 0100 0100 0000 xxxx xxxx + {ADI, "A,%b" }, // 41: 0111 0100 0100 0001 xxxx xxxx + {ADI, "B,%b" }, // 42: 0111 0100 0100 0010 xxxx xxxx + {ADI, "C,%b" }, // 43: 0111 0100 0100 0011 xxxx xxxx + {ADI, "D,%b" }, // 44: 0111 0100 0100 0100 xxxx xxxx + {ADI, "E,%b" }, // 45: 0111 0100 0100 0101 xxxx xxxx + {ADI, "H,%b" }, // 46: 0111 0100 0100 0110 xxxx xxxx + {ADI, "L,%b" }, // 47: 0111 0100 0100 0111 xxxx xxxx + {ONI, "V,%b" }, // 48: 0111 0100 0100 1000 xxxx xxxx + {ONI, "A,%b" }, // 49: 0111 0100 0100 1001 xxxx xxxx + {ONI, "B,%b" }, // 4a: 0111 0100 0100 1010 xxxx xxxx + {ONI, "C,%b" }, // 4b: 0111 0100 0100 1011 xxxx xxxx + {ONI, "D,%b" }, // 4c: 0111 0100 0100 1100 xxxx xxxx + {ONI, "E,%b" }, // 4d: 0111 0100 0100 1101 xxxx xxxx + {ONI, "H,%b" }, // 4e: 0111 0100 0100 1110 xxxx xxxx + {ONI, "L,%b" }, // 4f: 0111 0100 0100 1111 xxxx xxxx + + {ACI, "V,%b" }, // 50: 0111 0100 0101 0000 xxxx xxxx + {ACI, "A,%b" }, // 51: 0111 0100 0101 0001 xxxx xxxx + {ACI, "B,%b" }, // 52: 0111 0100 0101 0010 xxxx xxxx + {ACI, "C,%b" }, // 53: 0111 0100 0101 0011 xxxx xxxx + {ACI, "D,%b" }, // 54: 0111 0100 0101 0100 xxxx xxxx + {ACI, "E,%b" }, // 55: 0111 0100 0101 0101 xxxx xxxx + {ACI, "H,%b" }, // 56: 0111 0100 0101 0110 xxxx xxxx + {ACI, "L,%b" }, // 57: 0111 0100 0101 0111 xxxx xxxx + {OFFI, "V,%b" }, // 58: 0111 0100 0101 1000 xxxx xxxx + {OFFI, "A,%b" }, // 59: 0111 0100 0101 1001 xxxx xxxx + {OFFI, "B,%b" }, // 5a: 0111 0100 0101 1010 xxxx xxxx + {OFFI, "C,%b" }, // 5b: 0111 0100 0101 1011 xxxx xxxx + {OFFI, "D,%b" }, // 5c: 0111 0100 0101 1100 xxxx xxxx + {OFFI, "E,%b" }, // 5d: 0111 0100 0101 1101 xxxx xxxx + {OFFI, "H,%b" }, // 5e: 0111 0100 0101 1110 xxxx xxxx + {OFFI, "L,%b" }, // 5f: 0111 0100 0101 1111 xxxx xxxx + + {SUI, "V,%b" }, // 60: 0111 0100 0110 0000 xxxx xxxx + {SUI, "A,%b" }, // 61: 0111 0100 0110 0001 xxxx xxxx + {SUI, "B,%b" }, // 62: 0111 0100 0110 0010 xxxx xxxx + {SUI, "C,%b" }, // 63: 0111 0100 0110 0011 xxxx xxxx + {SUI, "D,%b" }, // 64: 0111 0100 0110 0100 xxxx xxxx + {SUI, "E,%b" }, // 65: 0111 0100 0110 0101 xxxx xxxx + {SUI, "H,%b" }, // 66: 0111 0100 0110 0110 xxxx xxxx + {SUI, "L,%b" }, // 67: 0111 0100 0110 0111 xxxx xxxx + {NEI, "V,%b" }, // 68: 0111 0100 0110 1000 xxxx xxxx + {NEI, "A,%b" }, // 69: 0111 0100 0110 1001 xxxx xxxx + {NEI, "B,%b" }, // 6a: 0111 0100 0110 1010 xxxx xxxx + {NEI, "C,%b" }, // 6b: 0111 0100 0110 1011 xxxx xxxx + {NEI, "D,%b" }, // 6c: 0111 0100 0110 1100 xxxx xxxx + {NEI, "E,%b" }, // 6d: 0111 0100 0110 1101 xxxx xxxx + {NEI, "H,%b" }, // 6e: 0111 0100 0110 1110 xxxx xxxx + {NEI, "L,%b" }, // 6f: 0111 0100 0110 1111 xxxx xxxx + + {SBI, "V,%b" }, // 70: 0111 0100 0111 0000 xxxx xxxx + {SBI, "A,%b" }, // 71: 0111 0100 0111 0001 xxxx xxxx + {SBI, "B,%b" }, // 72: 0111 0100 0111 0010 xxxx xxxx + {SBI, "C,%b" }, // 73: 0111 0100 0111 0011 xxxx xxxx + {SBI, "D,%b" }, // 74: 0111 0100 0111 0100 xxxx xxxx + {SBI, "E,%b" }, // 75: 0111 0100 0111 0101 xxxx xxxx + {SBI, "H,%b" }, // 76: 0111 0100 0111 0110 xxxx xxxx + {SBI, "L,%b" }, // 77: 0111 0100 0111 0111 xxxx xxxx + {EQI, "V,%b" }, // 78: 0111 0100 0111 1000 xxxx xxxx + {EQI, "A,%b" }, // 79: 0111 0100 0111 1001 xxxx xxxx + {EQI, "B,%b" }, // 7a: 0111 0100 0111 1010 xxxx xxxx + {EQI, "C,%b" }, // 7b: 0111 0100 0111 1011 xxxx xxxx + {EQI, "D,%b" }, // 7c: 0111 0100 0111 1100 xxxx xxxx + {EQI, "E,%b" }, // 7d: 0111 0100 0111 1101 xxxx xxxx + {EQI, "H,%b" }, // 7e: 0111 0100 0111 1110 xxxx xxxx + {EQI, "L,%b" }, // 7f: 0111 0100 0111 1111 xxxx xxxx + + { }, // 80: 0111 0100 1000 0000 + { }, // 81: 0111 0100 1000 0001 + { }, // 82: 0111 0100 1000 0010 + { }, // 83: 0111 0100 1000 0011 + { }, // 84: 0111 0100 1000 0100 + { }, // 85: 0111 0100 1000 0101 + { }, // 86: 0111 0100 1000 0110 + { }, // 87: 0111 0100 1000 0111 + {ANAW, "%a" }, // 88: 0111 0100 1000 1000 oooo oooo + { }, // 89: 0111 0100 1000 1001 + { }, // 8a: 0111 0100 1000 1010 + { }, // 8b: 0111 0100 1000 1011 + { }, // 8c: 0111 0100 1000 1100 + {DAN, "EA,BC" }, // 8d: 0111 0100 1000 1101 + {DAN, "EA,DE" }, // 8e: 0111 0100 1000 1110 + {DAN, "EA,HL" }, // 8f: 0111 0100 1000 1111 + + {XRAW, "%a" }, // 90: 0111 0100 1001 0000 oooo oooo + { }, // 91: 0111 0100 1001 0001 + { }, // 92: 0111 0100 1001 0010 + { }, // 93: 0111 0100 1001 0011 + { }, // 94: 0111 0100 1001 0100 + {DXR, "EA,BC" }, // 95: 0111 0100 1001 0101 + {DXR, "EA,DE" }, // 96: 0111 0100 1001 0110 + {DXR, "EA,HL" }, // 97: 0111 0100 1001 0111 + {ORAW, "%a" }, // 98: 0111 0100 1001 1000 oooo oooo + { }, // 99: 0111 0100 1001 1001 + { }, // 9a: 0111 0100 1001 1010 + { }, // 9b: 0111 0100 1001 1011 + { }, // 9c: 0111 0100 1001 1100 + {DOR, "EA,BC" }, // 9d: 0111 0100 1001 1101 + {DOR, "EA,DE" }, // 9e: 0111 0100 1001 1110 + {DOR, "EA,HL" }, // 9f: 0111 0100 1001 1111 + + {ADDNCW, "%a" }, // a0: 0111 0100 1010 0000 oooo oooo + { }, // a1: 0111 0100 1010 0001 + { }, // a2: 0111 0100 1010 0010 + { }, // a3: 0111 0100 1010 0011 + { }, // a4: 0111 0100 1010 0100 + {DADDNC, "EA,BC" }, // a5: 0111 0100 1010 0101 + {DADDNC, "EA,DE" }, // a6: 0111 0100 1010 0110 + {DADDNC, "EA,HL" }, // a7: 0111 0100 1010 0111 + {GTAW, "%a" }, // a8: 0111 0100 1010 1000 oooo oooo + { }, // a9: 0111 0100 1010 1001 + { }, // aa: 0111 0100 1010 1010 + { }, // ab: 0111 0100 1010 1011 + { }, // ac: 0111 0100 1010 1100 + {DGT, "EA,BC" }, // ad: 0111 0100 1010 1101 + {DGT, "EA,DE" }, // ae: 0111 0100 1010 1110 + {DGT, "EA,HL" }, // af: 0111 0100 1010 1111 + + {SUBNBW, "%a" }, // b0: 0111 0100 1011 0000 oooo oooo + { }, // b1: 0111 0100 1011 0001 + { }, // b2: 0111 0100 1011 0010 + { }, // b3: 0111 0100 1011 0011 + { }, // b4: 0111 0100 1011 0100 + {DSUBNB, "EA,BC" }, // b5: 0111 0100 1011 0101 + {DSUBNB, "EA,DE" }, // b6: 0111 0100 1011 0110 + {DSUBNB, "EA,HL" }, // b7: 0111 0100 1011 0111 + {LTAW, "%a" }, // b8: 0111 0100 1011 1000 oooo oooo + { }, // b9: 0111 0100 1011 1001 + { }, // ba: 0111 0100 1011 1010 + { }, // bb: 0111 0100 1011 1011 + { }, // bc: 0111 0100 1011 1100 + {DLT, "EA,BC" }, // bd: 0111 0100 1011 1101 + {DLT, "EA,DE" }, // be: 0111 0100 1011 1110 + {DLT, "EA,HL" }, // bf: 0111 0100 1011 1111 + + {ADDW, "%a" }, // c0: 0111 0100 1100 0000 oooo oooo + { }, // c1: 0111 0100 1100 0001 + { }, // c2: 0111 0100 1100 0010 + { }, // c3: 0111 0100 1100 0011 + { }, // c4: 0111 0100 1100 0100 + {DADD, "EA,BC" }, // c5: 0111 0100 1100 0101 + {DADD, "EA,DE" }, // c6: 0111 0100 1100 0110 + {DADD, "EA,HL" }, // c7: 0111 0100 1100 0111 + {ONAW, "%a" }, // c8: 0111 0100 1100 1000 oooo oooo + { }, // c9: 0111 0100 1100 1001 + { }, // ca: 0111 0100 1100 1010 + { }, // cb: 0111 0100 1100 1011 + { }, // cc: 0111 0100 1100 1100 + {DON, "EA,BC" }, // cd: 0111 0100 1100 1101 + {DON, "EA,DE" }, // ce: 0111 0100 1100 1110 + {DON, "EA,HL" }, // cf: 0111 0100 1100 1111 + + {ADCW, "%a" }, // d0: 0111 0100 1101 0000 oooo oooo + { }, // d1: 0111 0100 1101 0001 + { }, // d2: 0111 0100 1101 0010 + { }, // d3: 0111 0100 1101 0011 + { }, // d4: 0111 0100 1101 0100 + {DADC, "EA,BC" }, // d5: 0111 0100 1101 0101 + {DADC, "EA,DE" }, // d6: 0111 0100 1101 0110 + {DADC, "EA,HL" }, // d7: 0111 0100 1101 0111 + {OFFAW, "%a" }, // d8: 0111 0100 1101 1000 oooo oooo + { }, // d9: 0111 0100 1101 1001 + { }, // da: 0111 0100 1101 1010 + { }, // db: 0111 0100 1101 1011 + { }, // dc: 0111 0100 1101 1100 + {DOFF, "EA,BC" }, // dd: 0111 0100 1101 1101 + {DOFF, "EA,DE" }, // de: 0111 0100 1101 1110 + {DOFF, "EA,HL" }, // df: 0111 0100 1101 1111 + + {SUBW, "%a" }, // e0: 0111 0100 1110 0000 oooo oooo + { }, // e1: 0111 0100 1110 0001 + { }, // e2: 0111 0100 1110 0010 + { }, // e3: 0111 0100 1110 0011 + { }, // e4: 0111 0100 1110 0100 + {DSUB, "EA,BC" }, // e5: 0111 0100 1110 0101 + {DSUB, "EA,DE" }, // e6: 0111 0100 1110 0110 + {DSUB, "EA,HL" }, // e7: 0111 0100 1110 0111 + {NEAW, "%a" }, // e8: 0111 0100 1110 1000 oooo oooo + { }, // e9: 0111 0100 1110 1001 + { }, // ea: 0111 0100 1110 1010 + { }, // eb: 0111 0100 1110 1011 + { }, // ec: 0111 0100 1110 1100 + {DNE, "EA,BC" }, // ed: 0111 0100 1110 1101 + {DNE, "EA,DE" }, // ee: 0111 0100 1110 1110 + {DNE, "EA,HL" }, // ef: 0111 0100 1110 1111 + + {SBBW, "%a" }, // f0: 0111 0100 1111 0000 oooo oooo + { }, // f1: 0111 0100 1111 0001 + { }, // f2: 0111 0100 1111 0010 + { }, // f3: 0111 0100 1111 0011 + { }, // f4: 0111 0100 1111 0100 + {DSBB, "EA,BC" }, // f5: 0111 0100 1111 0101 + {DSBB, "EA,DE" }, // f6: 0111 0100 1111 0110 + {DSBB, "EA,HL" }, // f7: 0111 0100 1111 0111 + {EQAW, "%a" }, // f8: 0111 0100 1111 1000 oooo oooo + { }, // f9: 0111 0100 1111 1001 + { }, // fa: 0111 0100 1111 1010 + { }, // fb: 0111 0100 1111 1011 + { }, // fc: 0111 0100 1111 1100 + {DEQ, "EA,BC" }, // fd: 0111 0100 1111 1101 + {DEQ, "EA,DE" }, // fe: 0111 0100 1111 1110 + {DEQ, "EA,HL" } // ff: 0111 0100 1111 1111 }; -const dasm_s dasm_s::d48_7807[256] = +// prefix 48 +const upd7810_base_disassembler::dasm_s upd7810_disassembler::d48_7810[256] = { { }, // 00: 0100 1000 0000 0000 {SLRC, "A" }, // 01: 0100 1000 0000 0001 @@ -753,7 +1108,7 @@ const dasm_s dasm_s::d48_7807[256] = {SLL, "B" }, // 26: 0100 1000 0010 0110 {SLL, "C" }, // 27: 0100 1000 0010 0111 {JEA, nullptr }, // 28: 0100 1000 0010 1000 - {CALB, nullptr }, // 29: 0100 1000 0010 1001 + {CALB,nullptr }, // 29: 0100 1000 0010 1001 {CLC, nullptr }, // 2a: 0100 1000 0010 1010 {STC, nullptr }, // 2b: 0100 1000 0010 1011 { }, // 2c: 0100 1000 0010 1100 @@ -874,11 +1229,11 @@ const dasm_s dasm_s::d48_7807[256] = { }, // 98: 0100 1000 1000 1000 { }, // 99: 0100 1000 1000 1001 { }, // 9a: 0100 1000 1000 1010 - {STEAX, "(DE+%b)" }, // 9b: 0100 1000 1000 1011 xxxx xxxx - {STEAX, "(HL+A)" }, // 9c: 0100 1000 1000 1100 - {STEAX, "(HL+B)" }, // 9d: 0100 1000 1000 1101 - {STEAX, "(HL+EA)" }, // 9e: 0100 1000 1000 1110 - {STEAX, "(HL+%b)" }, // 9f: 0100 1000 1000 1111 xxxx xxxx + {STEAX, "(DE+%b)" }, // 9b: 0100 1000 1000 1011 xxxx xxxx + {STEAX, "(HL+A)" }, // 9c: 0100 1000 1000 1100 + {STEAX, "(HL+B)" }, // 9d: 0100 1000 1000 1101 + {STEAX, "(HL+EA)" }, // 9e: 0100 1000 1000 1110 + {STEAX, "(HL+%b)" }, // 9f: 0100 1000 1000 1111 xxxx xxxx {DSLR, "EA" }, // a0: 0100 1000 1010 0000 { }, // a1: 0100 1000 1010 0001 @@ -890,12 +1245,12 @@ const dasm_s dasm_s::d48_7807[256] = { }, // a7: 0100 1000 1010 0111 {TABLE, nullptr }, // a8: 0100 1000 1010 1000 { }, // a9: 0100 1000 1010 1001 - {CMC, nullptr }, // aa: 0100 1000 1010 1010 7807 + { }, // aa: 0100 1000 1010 1010 { }, // ab: 0100 1000 1010 1011 - {EXA, nullptr }, // ac: 0100 1000 1010 1100 7807 - {EXR, nullptr }, // ad: 0100 1000 1010 1101 7807 - {EXH, nullptr }, // ae: 0100 1000 1010 1110 7807 - {EXX, nullptr }, // af: 0100 1000 1010 1111 7807 + { }, // ac: 0100 1000 1010 1100 + { }, // ad: 0100 1000 1010 1101 + { }, // ae: 0100 1000 1010 1110 + { }, // af: 0100 1000 1010 1111 {DRLR, "EA" }, // b0: 0100 1000 1011 0000 { }, // b1: 0100 1000 1011 0001 @@ -908,15 +1263,15 @@ const dasm_s dasm_s::d48_7807[256] = { }, // b8: 0100 1000 1011 1000 { }, // b9: 0100 1000 1011 1001 { }, // ba: 0100 1000 1011 1010 - { }, // bb: 0100 1000 1011 1011 + {STOP, nullptr }, // bb: 0100 1000 1011 1011 7810 { }, // bc: 0100 1000 1011 1100 { }, // bd: 0100 1000 1011 1101 { }, // be: 0100 1000 1011 1110 { }, // bf: 0100 1000 1011 1111 {DMOV, "EA,ECNT" }, // c0: 0100 1000 1100 0000 - {DMOV, "EA,ECPT0"}, // c1: 0100 1000 1100 0001 7807 - {DMOV, "EA,ECPT1"}, // c2: 0100 1000 1100 0010 7807 + {DMOV, "EA,ECPT" }, // c1: 0100 1000 1100 0001 7810 + { }, // c2: 0100 1000 1100 0010 { }, // c3: 0100 1000 1100 0011 { }, // c4: 0100 1000 1100 0100 { }, // c5: 0100 1000 1100 0101 @@ -984,7 +1339,7 @@ const dasm_s dasm_s::d48_7807[256] = }; // prefix 4C -const dasm_s dasm_s::d4C_7810[256] = +const upd7810_base_disassembler::dasm_s upd7810_disassembler::d4C_7810[256] = { { }, // 00: 0100 1100 0000 0000 { }, // 01: 0100 1100 0000 0001 @@ -1259,283 +1614,9 @@ const dasm_s dasm_s::d4C_7810[256] = { } // ff: 0100 1100 1111 1111 }; -const dasm_s dasm_s::d4C_7807[256] = -{ - { }, // 00: 0100 1100 0000 0000 - { }, // 01: 0100 1100 0000 0001 - { }, // 02: 0100 1100 0000 0010 - { }, // 03: 0100 1100 0000 0011 - { }, // 04: 0100 1100 0000 0100 - { }, // 05: 0100 1100 0000 0101 - { }, // 06: 0100 1100 0000 0110 - { }, // 07: 0100 1100 0000 0111 - { }, // 08: 0100 1100 0000 1000 - { }, // 09: 0100 1100 0000 1001 - { }, // 0a: 0100 1100 0000 1010 - { }, // 0b: 0100 1100 0000 1011 - { }, // 0c: 0100 1100 0000 1100 - { }, // 0d: 0100 1100 0000 1101 - { }, // 0e: 0100 1100 0000 1110 - { }, // 0f: 0100 1100 0000 1111 - - { }, // 10: 0100 1100 0001 0000 - { }, // 11: 0100 1100 0001 0001 - { }, // 12: 0100 1100 0001 0010 - { }, // 13: 0100 1100 0001 0011 - { }, // 14: 0100 1100 0001 0100 - { }, // 15: 0100 1100 0001 0101 - { }, // 16: 0100 1100 0001 0110 - { }, // 17: 0100 1100 0001 0111 - { }, // 18: 0100 1100 0001 1000 - { }, // 19: 0100 1100 0001 1001 - { }, // 1a: 0100 1100 0001 1010 - { }, // 1b: 0100 1100 0001 1011 - { }, // 1c: 0100 1100 0001 1100 - { }, // 1d: 0100 1100 0001 1101 - { }, // 1e: 0100 1100 0001 1110 - { }, // 1f: 0100 1100 0001 1111 - - { }, // 20: 0100 1100 0010 0000 - { }, // 21: 0100 1100 0010 0001 - { }, // 22: 0100 1100 0010 0010 - { }, // 23: 0100 1100 0010 0011 - { }, // 24: 0100 1100 0010 0100 - { }, // 25: 0100 1100 0010 0101 - { }, // 26: 0100 1100 0010 0110 - { }, // 27: 0100 1100 0010 0111 - { }, // 28: 0100 1100 0010 1000 - { }, // 29: 0100 1100 0010 1001 - { }, // 2a: 0100 1100 0010 1010 - { }, // 2b: 0100 1100 0010 1011 - { }, // 2c: 0100 1100 0010 1100 - { }, // 2d: 0100 1100 0010 1101 - { }, // 2e: 0100 1100 0010 1110 - { }, // 2f: 0100 1100 0010 1111 - - { }, // 30: 0100 1100 0011 0000 - { }, // 31: 0100 1100 0011 0001 - { }, // 32: 0100 1100 0011 0010 - { }, // 33: 0100 1100 0011 0011 - { }, // 34: 0100 1100 0011 0100 - { }, // 35: 0100 1100 0011 0101 - { }, // 36: 0100 1100 0011 0110 - { }, // 37: 0100 1100 0011 0111 - { }, // 38: 0100 1100 0011 1000 - { }, // 39: 0100 1100 0011 1001 - { }, // 3a: 0100 1100 0011 1010 - { }, // 3b: 0100 1100 0011 1011 - { }, // 3c: 0100 1100 0011 1100 - { }, // 3d: 0100 1100 0011 1101 - { }, // 3e: 0100 1100 0011 1110 - { }, // 3f: 0100 1100 0011 1111 - - { }, // 40: 0100 1100 0100 0000 - { }, // 41: 0100 1100 0100 0001 - { }, // 42: 0100 1100 0100 0010 - { }, // 43: 0100 1100 0100 0011 - { }, // 44: 0100 1100 0100 0100 - { }, // 45: 0100 1100 0100 0101 - { }, // 46: 0100 1100 0100 0110 - { }, // 47: 0100 1100 0100 0111 - { }, // 48: 0100 1100 0100 1000 - { }, // 49: 0100 1100 0100 1001 - { }, // 4a: 0100 1100 0100 1010 - { }, // 4b: 0100 1100 0100 1011 - { }, // 4c: 0100 1100 0100 1100 - { }, // 4d: 0100 1100 0100 1101 - { }, // 4e: 0100 1100 0100 1110 - { }, // 4f: 0100 1100 0100 1111 - - { }, // 50: 0100 1100 0101 0000 - { }, // 51: 0100 1100 0101 0001 - { }, // 52: 0100 1100 0101 0010 - { }, // 53: 0100 1100 0101 0011 - { }, // 54: 0100 1100 0101 0100 - { }, // 55: 0100 1100 0101 0101 - { }, // 56: 0100 1100 0101 0110 - { }, // 57: 0100 1100 0101 0111 - { }, // 58: 0100 1100 0101 1000 - { }, // 59: 0100 1100 0101 1001 - { }, // 5a: 0100 1100 0101 1010 - { }, // 5b: 0100 1100 0101 1011 - { }, // 5c: 0100 1100 0101 1100 - { }, // 5d: 0100 1100 0101 1101 - { }, // 5e: 0100 1100 0101 1110 - { }, // 5f: 0100 1100 0101 1111 - - { }, // 60: 0100 1100 0110 0000 - { }, // 61: 0100 1100 0110 0001 - { }, // 62: 0100 1100 0110 0010 - { }, // 63: 0100 1100 0110 0011 - { }, // 64: 0100 1100 0110 0100 - { }, // 65: 0100 1100 0110 0101 - { }, // 66: 0100 1100 0110 0110 - { }, // 67: 0100 1100 0110 0111 - { }, // 68: 0100 1100 0110 1000 - { }, // 69: 0100 1100 0110 1001 - { }, // 6a: 0100 1100 0110 1010 - { }, // 6b: 0100 1100 0110 1011 - { }, // 6c: 0100 1100 0110 1100 - { }, // 6d: 0100 1100 0110 1101 - { }, // 6e: 0100 1100 0110 1110 - { }, // 6f: 0100 1100 0110 1111 - - { }, // 70: 0100 1100 0111 0000 - { }, // 71: 0100 1100 0111 0001 - { }, // 72: 0100 1100 0111 0010 - { }, // 73: 0100 1100 0111 0011 - { }, // 74: 0100 1100 0111 0100 - { }, // 75: 0100 1100 0111 0101 - { }, // 76: 0100 1100 0111 0110 - { }, // 77: 0100 1100 0111 0111 - { }, // 78: 0100 1100 0111 1000 - { }, // 79: 0100 1100 0111 1001 - { }, // 7a: 0100 1100 0111 1010 - { }, // 7b: 0100 1100 0111 1011 - { }, // 7c: 0100 1100 0111 1100 - { }, // 7d: 0100 1100 0111 1101 - { }, // 7e: 0100 1100 0111 1110 - { }, // 7f: 0100 1100 0111 1111 - - { }, // 80: 0100 1100 1000 0000 - { }, // 81: 0100 1100 1000 0001 - { }, // 82: 0100 1100 1000 0010 - { }, // 83: 0100 1100 1000 0011 - { }, // 84: 0100 1100 1000 0100 - { }, // 85: 0100 1100 1000 0101 - { }, // 86: 0100 1100 1000 0110 - { }, // 87: 0100 1100 1000 0111 - { }, // 88: 0100 1100 1000 1000 - { }, // 89: 0100 1100 1000 1001 - { }, // 8a: 0100 1100 1000 1010 - { }, // 8b: 0100 1100 1000 1011 - { }, // 8c: 0100 1100 1000 1100 - { }, // 8d: 0100 1100 1000 1101 - { }, // 8e: 0100 1100 1000 1110 - { }, // 8f: 0100 1100 1000 1111 - - { }, // 90: 0100 1100 1001 0000 - { }, // 91: 0100 1100 1001 0001 - { }, // 92: 0100 1100 1001 0010 - { }, // 93: 0100 1100 1001 0011 - { }, // 94: 0100 1100 1001 0100 - { }, // 95: 0100 1100 1001 0101 - { }, // 96: 0100 1100 1001 0110 - { }, // 97: 0100 1100 1001 0111 - { }, // 98: 0100 1100 1001 1000 - { }, // 99: 0100 1100 1001 1001 - { }, // 9a: 0100 1100 1001 1010 - { }, // 9b: 0100 1100 1001 1011 - { }, // 9c: 0100 1100 1001 1100 - { }, // 9d: 0100 1100 1001 1101 - { }, // 9e: 0100 1100 1001 1110 - { }, // 9f: 0100 1100 1001 1111 - - { }, // a0: 0100 1100 1010 0000 - { }, // a1: 0100 1100 1010 0001 - { }, // a2: 0100 1100 1010 0010 - { }, // a3: 0100 1100 1010 0011 - { }, // a4: 0100 1100 1010 0100 - { }, // a5: 0100 1100 1010 0101 - { }, // a6: 0100 1100 1010 0110 - { }, // a7: 0100 1100 1010 0111 - { }, // a8: 0100 1100 1010 1000 - { }, // a9: 0100 1100 1010 1001 - { }, // aa: 0100 1100 1010 1010 - { }, // ab: 0100 1100 1010 1011 - { }, // ac: 0100 1100 1010 1100 - { }, // ad: 0100 1100 1010 1101 - { }, // ae: 0100 1100 1010 1110 - { }, // af: 0100 1100 1010 1111 - - { }, // b0: 0100 1100 1011 0000 - { }, // b1: 0100 1100 1011 0001 - { }, // b2: 0100 1100 1011 0010 - { }, // b3: 0100 1100 1011 0011 - { }, // b4: 0100 1100 1011 0100 - { }, // b5: 0100 1100 1011 0101 - { }, // b6: 0100 1100 1011 0110 - { }, // b7: 0100 1100 1011 0111 - { }, // b8: 0100 1100 1011 1000 - { }, // b9: 0100 1100 1011 1001 - { }, // ba: 0100 1100 1011 1010 - { }, // bb: 0100 1100 1011 1011 - { }, // bc: 0100 1100 1011 1100 - { }, // bd: 0100 1100 1011 1101 - { }, // be: 0100 1100 1011 1110 - { }, // bf: 0100 1100 1011 1111 - - {MOV, "A,PA" }, // c0: 0100 1100 1100 0000 - {MOV, "A,PB" }, // c1: 0100 1100 1100 0001 - {MOV, "A,PC" }, // c2: 0100 1100 1100 0010 - {MOV, "A,PD" }, // c3: 0100 1100 1100 0011 - { }, // c4: 0100 1100 1100 0100 - {MOV, "A,PF" }, // c5: 0100 1100 1100 0101 - {MOV, "A,MKH" }, // c6: 0100 1100 1100 0110 - {MOV, "A,MKL" }, // c7: 0100 1100 1100 0111 - { }, // c8: 0100 1100 1100 1000 - {MOV, "A,SMH" }, // c9: 0100 1100 1100 1001 - { }, // ca: 0100 1100 1100 1010 - {MOV, "A,EOM" }, // cb: 0100 1100 1100 1011 - { }, // cc: 0100 1100 1100 1100 - {MOV, "A,TMM" }, // cd: 0100 1100 1100 1101 - {MOV, "A,PT" }, // ce: 0100 1100 1100 1110 7807 - { }, // cf: 0100 1100 1100 1111 - - { }, // d0: 0100 1100 1101 0000 - { }, // d1: 0100 1100 1101 0001 - { }, // d2: 0100 1100 1101 0010 - { }, // d3: 0100 1100 1101 0011 - { }, // d4: 0100 1100 1101 0100 - { }, // d5: 0100 1100 1101 0101 - { }, // d6: 0100 1100 1101 0110 - { }, // d7: 0100 1100 1101 0111 - { }, // d8: 0100 1100 1101 1000 - {MOV, "A,RXB" }, // d9: 0100 1100 1101 1001 - { }, // da: 0100 1100 1101 1010 - { }, // db: 0100 1100 1101 1011 - { }, // dc: 0100 1100 1101 1100 - { }, // dd: 0100 1100 1101 1101 - { }, // de: 0100 1100 1101 1110 - { }, // df: 0100 1100 1101 1111 - - { }, // e0: 0100 1100 1110 0000 - { }, // e1: 0100 1100 1110 0001 - { }, // e2: 0100 1100 1110 0010 - { }, // e3: 0100 1100 1110 0011 - { }, // e4: 0100 1100 1110 0100 - { }, // e5: 0100 1100 1110 0101 - { }, // e6: 0100 1100 1110 0110 - { }, // e7: 0100 1100 1110 0111 - { }, // e8: 0100 1100 1110 1000 - { }, // e9: 0100 1100 1110 1001 - { }, // ea: 0100 1100 1110 1010 - { }, // eb: 0100 1100 1110 1011 - { }, // ec: 0100 1100 1110 1100 - { }, // ed: 0100 1100 1110 1101 - { }, // ee: 0100 1100 1110 1110 - { }, // ef: 0100 1100 1110 1111 - - { }, // f0: 0100 1100 1111 0000 - { }, // f1: 0100 1100 1111 0001 - { }, // f2: 0100 1100 1111 0010 - { }, // f3: 0100 1100 1111 0011 - { }, // f4: 0100 1100 1111 0100 - { }, // f5: 0100 1100 1111 0101 - { }, // f6: 0100 1100 1111 0110 - { }, // f7: 0100 1100 1111 0111 - { }, // f8: 0100 1100 1111 1000 - { }, // f9: 0100 1100 1111 1001 - { }, // fa: 0100 1100 1111 1010 - { }, // fb: 0100 1100 1111 1011 - { }, // fc: 0100 1100 1111 1100 - { }, // fd: 0100 1100 1111 1101 - { }, // fe: 0100 1100 1111 1110 - { } // ff: 0100 1100 1111 1111 -}; // prefix 4D -const dasm_s dasm_s::d4D_7810[256] = +const upd7810_base_disassembler::dasm_s upd7810_disassembler::d4D_7810[256] = { { }, // 00: 0100 1101 0000 0000 { }, // 01: 0100 1101 0000 0001 @@ -1810,559 +1891,10 @@ const dasm_s dasm_s::d4D_7810[256] = { } // ff: 0100 1101 1111 1111 }; -const dasm_s dasm_s::d4D_7807[256] = -{ - { }, // 00: 0100 1101 0000 0000 - { }, // 01: 0100 1101 0000 0001 - { }, // 02: 0100 1101 0000 0010 - { }, // 03: 0100 1101 0000 0011 - { }, // 04: 0100 1101 0000 0100 - { }, // 05: 0100 1101 0000 0101 - { }, // 06: 0100 1101 0000 0110 - { }, // 07: 0100 1101 0000 0111 - { }, // 08: 0100 1101 0000 1000 - { }, // 09: 0100 1101 0000 1001 - { }, // 0a: 0100 1101 0000 1010 - { }, // 0b: 0100 1101 0000 1011 - { }, // 0c: 0100 1101 0000 1100 - { }, // 0d: 0100 1101 0000 1101 - { }, // 0e: 0100 1101 0000 1110 - { }, // 0f: 0100 1101 0000 1111 - - { }, // 10: 0100 1101 0001 0000 - { }, // 11: 0100 1101 0001 0001 - { }, // 12: 0100 1101 0001 0010 - { }, // 13: 0100 1101 0001 0011 - { }, // 14: 0100 1101 0001 0100 - { }, // 15: 0100 1101 0001 0101 - { }, // 16: 0100 1101 0001 0110 - { }, // 17: 0100 1101 0001 0111 - { }, // 18: 0100 1101 0001 1000 - { }, // 19: 0100 1101 0001 1001 - { }, // 1a: 0100 1101 0001 1010 - { }, // 1b: 0100 1101 0001 1011 - { }, // 1c: 0100 1101 0001 1100 - { }, // 1d: 0100 1101 0001 1101 - { }, // 1e: 0100 1101 0001 1110 - { }, // 1f: 0100 1101 0001 1111 - - { }, // 20: 0100 1101 0010 0000 - { }, // 21: 0100 1101 0010 0001 - { }, // 22: 0100 1101 0010 0010 - { }, // 23: 0100 1101 0010 0011 - { }, // 24: 0100 1101 0010 0100 - { }, // 25: 0100 1101 0010 0101 - { }, // 26: 0100 1101 0010 0110 - { }, // 27: 0100 1101 0010 0111 - { }, // 28: 0100 1101 0010 1000 - { }, // 29: 0100 1101 0010 1001 - { }, // 2a: 0100 1101 0010 1010 - { }, // 2b: 0100 1101 0010 1011 - { }, // 2c: 0100 1101 0010 1100 - { }, // 2d: 0100 1101 0010 1101 - { }, // 2e: 0100 1101 0010 1110 - { }, // 2f: 0100 1101 0010 1111 - - { }, // 30: 0100 1101 0011 0000 - { }, // 31: 0100 1101 0011 0001 - { }, // 32: 0100 1101 0011 0010 - { }, // 33: 0100 1101 0011 0011 - { }, // 34: 0100 1101 0011 0100 - { }, // 35: 0100 1101 0011 0101 - { }, // 36: 0100 1101 0011 0110 - { }, // 37: 0100 1101 0011 0111 - { }, // 38: 0100 1101 0011 1000 - { }, // 39: 0100 1101 0011 1001 - { }, // 3a: 0100 1101 0011 1010 - { }, // 3b: 0100 1101 0011 1011 - { }, // 3c: 0100 1101 0011 1100 - { }, // 3d: 0100 1101 0011 1101 - { }, // 3e: 0100 1101 0011 1110 - { }, // 3f: 0100 1101 0011 1111 - - { }, // 40: 0100 1101 0100 0000 - { }, // 41: 0100 1101 0100 0001 - { }, // 42: 0100 1101 0100 0010 - { }, // 43: 0100 1101 0100 0011 - { }, // 44: 0100 1101 0100 0100 - { }, // 45: 0100 1101 0100 0101 - { }, // 46: 0100 1101 0100 0110 - { }, // 47: 0100 1101 0100 0111 - { }, // 48: 0100 1101 0100 1000 - { }, // 49: 0100 1101 0100 1001 - { }, // 4a: 0100 1101 0100 1010 - { }, // 4b: 0100 1101 0100 1011 - { }, // 4c: 0100 1101 0100 1100 - { }, // 4d: 0100 1101 0100 1101 - { }, // 4e: 0100 1101 0100 1110 - { }, // 4f: 0100 1101 0100 1111 - - { }, // 50: 0100 1101 0101 0000 - { }, // 51: 0100 1101 0101 0001 - { }, // 52: 0100 1101 0101 0010 - { }, // 53: 0100 1101 0101 0011 - { }, // 54: 0100 1101 0101 0100 - { }, // 55: 0100 1101 0101 0101 - { }, // 56: 0100 1101 0101 0110 - { }, // 57: 0100 1101 0101 0111 - { }, // 58: 0100 1101 0101 1000 - { }, // 59: 0100 1101 0101 1001 - { }, // 5a: 0100 1101 0101 1010 - { }, // 5b: 0100 1101 0101 1011 - { }, // 5c: 0100 1101 0101 1100 - { }, // 5d: 0100 1101 0101 1101 - { }, // 5e: 0100 1101 0101 1110 - { }, // 5f: 0100 1101 0101 1111 - - { }, // 60: 0100 1101 0110 0000 - { }, // 61: 0100 1101 0110 0001 - { }, // 62: 0100 1101 0110 0010 - { }, // 63: 0100 1101 0110 0011 - { }, // 64: 0100 1101 0110 0100 - { }, // 65: 0100 1101 0110 0101 - { }, // 66: 0100 1101 0110 0110 - { }, // 67: 0100 1101 0110 0111 - { }, // 68: 0100 1101 0110 1000 - { }, // 69: 0100 1101 0110 1001 - { }, // 6a: 0100 1101 0110 1010 - { }, // 6b: 0100 1101 0110 1011 - { }, // 6c: 0100 1101 0110 1100 - { }, // 6d: 0100 1101 0110 1101 - { }, // 6e: 0100 1101 0110 1110 - { }, // 6f: 0100 1101 0110 1111 - - { }, // 70: 0100 1101 0111 0000 - { }, // 71: 0100 1101 0111 0001 - { }, // 72: 0100 1101 0111 0010 - { }, // 73: 0100 1101 0111 0011 - { }, // 74: 0100 1101 0111 0100 - { }, // 75: 0100 1101 0111 0101 - { }, // 76: 0100 1101 0111 0110 - { }, // 77: 0100 1101 0111 0111 - { }, // 78: 0100 1101 0111 1000 - { }, // 79: 0100 1101 0111 1001 - { }, // 7a: 0100 1101 0111 1010 - { }, // 7b: 0100 1101 0111 1011 - { }, // 7c: 0100 1101 0111 1100 - { }, // 7d: 0100 1101 0111 1101 - { }, // 7e: 0100 1101 0111 1110 - { }, // 7f: 0100 1101 0111 1111 - - { }, // 80: 0100 1101 1000 0000 - { }, // 81: 0100 1101 1000 0001 - { }, // 82: 0100 1101 1000 0010 - { }, // 83: 0100 1101 1000 0011 - { }, // 84: 0100 1101 1000 0100 - { }, // 85: 0100 1101 1000 0101 - { }, // 86: 0100 1101 1000 0110 - { }, // 87: 0100 1101 1000 0111 - { }, // 88: 0100 1101 1000 1000 - { }, // 89: 0100 1101 1000 1001 - { }, // 8a: 0100 1101 1000 1010 - { }, // 8b: 0100 1101 1000 1011 - { }, // 8c: 0100 1101 1000 1100 - { }, // 8d: 0100 1101 1000 1101 - { }, // 8e: 0100 1101 1000 1110 - { }, // 8f: 0100 1101 1000 1111 - - { }, // 90: 0100 1101 1001 0000 - { }, // 91: 0100 1101 1001 0001 - { }, // 92: 0100 1101 1001 0010 - { }, // 93: 0100 1101 1001 0011 - { }, // 94: 0100 1101 1001 0100 - { }, // 95: 0100 1101 1001 0101 - { }, // 96: 0100 1101 1001 0110 - { }, // 97: 0100 1101 1001 0111 - { }, // 98: 0100 1101 1001 1000 - { }, // 99: 0100 1101 1001 1001 - { }, // 9a: 0100 1101 1001 1010 - { }, // 9b: 0100 1101 1001 1011 - { }, // 9c: 0100 1101 1001 1100 - { }, // 9d: 0100 1101 1001 1101 - { }, // 9e: 0100 1101 1001 1110 - { }, // 9f: 0100 1101 1001 1111 - - { }, // a0: 0100 1101 1010 0000 - { }, // a1: 0100 1101 1010 0001 - { }, // a2: 0100 1101 1010 0010 - { }, // a3: 0100 1101 1010 0011 - { }, // a4: 0100 1101 1010 0100 - { }, // a5: 0100 1101 1010 0101 - { }, // a6: 0100 1101 1010 0110 - { }, // a7: 0100 1101 1010 0111 - { }, // a8: 0100 1101 1010 1000 - { }, // a9: 0100 1101 1010 1001 - { }, // aa: 0100 1101 1010 1010 - { }, // ab: 0100 1101 1010 1011 - { }, // ac: 0100 1101 1010 1100 - { }, // ad: 0100 1101 1010 1101 - { }, // ae: 0100 1101 1010 1110 - { }, // af: 0100 1101 1010 1111 - - { }, // b0: 0100 1101 1011 0000 - { }, // b1: 0100 1101 1011 0001 - { }, // b2: 0100 1101 1011 0010 - { }, // b3: 0100 1101 1011 0011 - { }, // b4: 0100 1101 1011 0100 - { }, // b5: 0100 1101 1011 0101 - { }, // b6: 0100 1101 1011 0110 - { }, // b7: 0100 1101 1011 0111 - { }, // b8: 0100 1101 1011 1000 - { }, // b9: 0100 1101 1011 1001 - { }, // ba: 0100 1101 1011 1010 - { }, // bb: 0100 1101 1011 1011 - { }, // bc: 0100 1101 1011 1100 - { }, // bd: 0100 1101 1011 1101 - { }, // be: 0100 1101 1011 1110 - { }, // bf: 0100 1101 1011 1111 - - {MOV, "PA,A" }, // c0: 0100 1101 1100 0000 - {MOV, "PB,A" }, // c1: 0100 1101 1100 0001 - {MOV, "PC,A" }, // c2: 0100 1101 1100 0010 - {MOV, "PD,A" }, // c3: 0100 1101 1100 0011 - { }, // c4: 0100 1101 1100 0100 - {MOV, "PF,A" }, // c5: 0100 1101 1100 0101 - {MOV, "MKH,A" }, // c6: 0100 1101 1100 0110 - {MOV, "MKL,A" }, // c7: 0100 1101 1100 0111 - { }, // c8: 0100 1101 1100 1000 - {MOV, "SMH,A" }, // c9: 0100 1101 1100 1001 - {MOV, "SML,A" }, // ca: 0100 1101 1100 1010 - {MOV, "EOM,A" }, // cb: 0100 1101 1100 1011 - {MOV, "ETMM,A" }, // cc: 0100 1101 1100 1100 - {MOV, "TMM,A" }, // cd: 0100 1101 1100 1101 - { }, // ce: 0100 1101 1100 1110 - { }, // cf: 0100 1101 1100 1111 - - {MOV, "MM,A" }, // d0: 0100 1101 1101 0000 - {MOV, "MCC,A" }, // d1: 0100 1101 1101 0001 - {MOV, "MA,A" }, // d2: 0100 1101 1101 0010 - {MOV, "MB,A" }, // d3: 0100 1101 1101 0011 - {MOV, "MC,A" }, // d4: 0100 1101 1101 0100 - { }, // d5: 0100 1101 1101 0101 - { }, // d6: 0100 1101 1101 0110 - {MOV, "MF,A" }, // d7: 0100 1101 1101 0111 - {MOV, "TXB,A" }, // d8: 0100 1101 1101 1000 - { }, // d9: 0100 1101 1101 1001 - {MOV, "TM0,A" }, // da: 0100 1101 1101 1010 - {MOV, "TM1,A" }, // db: 0100 1101 1101 1011 - { }, // dc: 0100 1101 1101 1100 - { }, // dd: 0100 1101 1101 1101 - { }, // de: 0100 1101 1101 1110 - { }, // df: 0100 1101 1101 1111 - - { }, // e0: 0100 1101 1110 0000 - { }, // e1: 0100 1101 1110 0001 - { }, // e2: 0100 1101 1110 0010 - { }, // e3: 0100 1101 1110 0011 - { }, // e4: 0100 1101 1110 0100 - {MOV, "MT,A" }, // e5: 0100 1101 1110 0101 7807 - { }, // e6: 0100 1101 1110 0110 - { }, // e7: 0100 1101 1110 0111 - { }, // e8: 0100 1101 1110 1000 - { }, // e9: 0100 1101 1110 1001 - { }, // ea: 0100 1101 1110 1010 - { }, // eb: 0100 1101 1110 1011 - { }, // ec: 0100 1101 1110 1100 - { }, // ed: 0100 1101 1110 1101 - { }, // ee: 0100 1101 1110 1110 - { }, // ef: 0100 1101 1110 1111 - - { }, // f0: 0100 1101 1111 0000 - { }, // f1: 0100 1101 1111 0001 - { }, // f2: 0100 1101 1111 0010 - { }, // f3: 0100 1101 1111 0011 - { }, // f4: 0100 1101 1111 0100 - { }, // f5: 0100 1101 1111 0101 - { }, // f6: 0100 1101 1111 0110 - { }, // f7: 0100 1101 1111 0111 - { }, // f8: 0100 1101 1111 1000 - { }, // f9: 0100 1101 1111 1001 - { }, // fa: 0100 1101 1111 1010 - { }, // fb: 0100 1101 1111 1011 - { }, // fc: 0100 1101 1111 1100 - { }, // fd: 0100 1101 1111 1101 - { }, // fe: 0100 1101 1111 1110 - { } // ff: 0100 1101 1111 1111 -}; - -// prefix 60 -const dasm_s dasm_s::d60[256] = -{ - { }, // 00: 0110 0000 0000 0000 - { }, // 01: 0110 0000 0000 0001 - { }, // 02: 0110 0000 0000 0010 - { }, // 03: 0110 0000 0000 0011 - { }, // 04: 0110 0000 0000 0100 - { }, // 05: 0110 0000 0000 0101 - { }, // 06: 0110 0000 0000 0110 - { }, // 07: 0110 0000 0000 0111 - {ANA, "V,A" }, // 08: 0110 0000 0000 1000 - {ANA, "A,A" }, // 09: 0110 0000 0000 1001 - {ANA, "B,A" }, // 0a: 0110 0000 0000 1010 - {ANA, "C,A" }, // 0b: 0110 0000 0000 1011 - {ANA, "D,A" }, // 0c: 0110 0000 0000 1100 - {ANA, "E,A" }, // 0d: 0110 0000 0000 1101 - {ANA, "H,A" }, // 0e: 0110 0000 0000 1110 - {ANA, "L,A" }, // 0f: 0110 0000 0000 1111 - - {XRA, "V,A" }, // 10: 0110 0000 0001 0000 - {XRA, "A,A" }, // 11: 0110 0000 0001 0001 - {XRA, "B,A" }, // 12: 0110 0000 0001 0010 - {XRA, "C,A" }, // 13: 0110 0000 0001 0011 - {XRA, "D,A" }, // 14: 0110 0000 0001 0100 - {XRA, "E,A" }, // 15: 0110 0000 0001 0101 - {XRA, "H,A" }, // 16: 0110 0000 0001 0110 - {XRA, "L,A" }, // 17: 0110 0000 0001 0111 - {ORA, "V,A" }, // 18: 0110 0000 0001 1000 - {ORA, "A,A" }, // 19: 0110 0000 0001 1001 - {ORA, "B,A" }, // 1a: 0110 0000 0001 1010 - {ORA, "C,A" }, // 1b: 0110 0000 0001 1011 - {ORA, "D,A" }, // 1c: 0110 0000 0001 1100 - {ORA, "E,A" }, // 1d: 0110 0000 0001 1101 - {ORA, "H,A" }, // 1e: 0110 0000 0001 1110 - {ORA, "L,A" }, // 1f: 0110 0000 0001 1111 - - {ADDNC, "V,A" }, // 20: 0110 0000 0010 0000 - {ADDNC, "A,A" }, // 21: 0110 0000 0010 0001 - {ADDNC, "B,A" }, // 22: 0110 0000 0010 0010 - {ADDNC, "C,A" }, // 23: 0110 0000 0010 0011 - {ADDNC, "D,A" }, // 24: 0110 0000 0010 0100 - {ADDNC, "E,A" }, // 25: 0110 0000 0010 0101 - {ADDNC, "H,A" }, // 26: 0110 0000 0010 0110 - {ADDNC, "L,A" }, // 27: 0110 0000 0010 0111 - {GTA, "V,A" }, // 28: 0110 0000 0010 1000 - {GTA, "A,A" }, // 29: 0110 0000 0010 1001 - {GTA, "B,A" }, // 2a: 0110 0000 0010 1010 - {GTA, "C,A" }, // 2b: 0110 0000 0010 1011 - {GTA, "D,A" }, // 2c: 0110 0000 0010 1100 - {GTA, "E,A" }, // 2d: 0110 0000 0010 1101 - {GTA, "H,A" }, // 2e: 0110 0000 0010 1110 - {GTA, "L,A" }, // 2f: 0110 0000 0010 1111 - {SUBNB, "V,A" }, // 30: 0110 0000 0011 0000 - {SUBNB, "A,A" }, // 31: 0110 0000 0011 0001 - {SUBNB, "B,A" }, // 32: 0110 0000 0011 0010 - {SUBNB, "C,A" }, // 33: 0110 0000 0011 0011 - {SUBNB, "D,A" }, // 34: 0110 0000 0011 0100 - {SUBNB, "E,A" }, // 35: 0110 0000 0011 0101 - {SUBNB, "H,A" }, // 36: 0110 0000 0011 0110 - {SUBNB, "L,A" }, // 37: 0110 0000 0011 0111 - {LTA, "V,A" }, // 38: 0110 0000 0011 1000 - {LTA, "A,A" }, // 39: 0110 0000 0011 1001 - {LTA, "B,A" }, // 3a: 0110 0000 0011 1010 - {LTA, "C,A" }, // 3b: 0110 0000 0011 1011 - {LTA, "D,A" }, // 3c: 0110 0000 0011 1100 - {LTA, "E,A" }, // 3d: 0110 0000 0011 1101 - {LTA, "H,A" }, // 3e: 0110 0000 0011 1110 - {LTA, "L,A" }, // 3f: 0110 0000 0011 1111 - - {ADD, "V,A" }, // 40: 0110 0000 0100 0000 - {ADD, "A,A" }, // 41: 0110 0000 0100 0001 - {ADD, "B,A" }, // 42: 0110 0000 0100 0010 - {ADD, "C,A" }, // 43: 0110 0000 0100 0011 - {ADD, "D,A" }, // 44: 0110 0000 0100 0100 - {ADD, "E,A" }, // 45: 0110 0000 0100 0101 - {ADD, "H,A" }, // 46: 0110 0000 0100 0110 - {ADD, "L,A" }, // 47: 0110 0000 0100 0111 - { }, // 48: 0110 0000 0100 1000 - { }, // 49: 0110 0000 0100 1001 - { }, // 4a: 0110 0000 0100 1010 - { }, // 4b: 0110 0000 0100 1011 - { }, // 4c: 0110 0000 0100 1100 - { }, // 4d: 0110 0000 0100 1101 - { }, // 4e: 0110 0000 0100 1110 - { }, // 4f: 0110 0000 0100 1111 - - {ADC, "V,A" }, // 50: 0110 0000 0101 0000 - {ADC, "A,A" }, // 51: 0110 0000 0101 0001 - {ADC, "B,A" }, // 52: 0110 0000 0101 0010 - {ADC, "C,A" }, // 53: 0110 0000 0101 0011 - {ADC, "D,A" }, // 54: 0110 0000 0101 0100 - {ADC, "E,A" }, // 55: 0110 0000 0101 0101 - {ADC, "H,A" }, // 56: 0110 0000 0101 0110 - {ADC, "L,A" }, // 57: 0110 0000 0101 0111 - { }, // 58: 0110 0000 0101 1000 - { }, // 59: 0110 0000 0101 1001 - { }, // 5a: 0110 0000 0101 1010 - { }, // 5b: 0110 0000 0101 1011 - { }, // 5c: 0110 0000 0101 1100 - { }, // 5d: 0110 0000 0101 1101 - { }, // 5e: 0110 0000 0101 1110 - { }, // 5f: 0110 0000 0101 1111 - - {SUB, "V,A" }, // 60: 0110 0000 0110 0000 - {SUB, "A,A" }, // 61: 0110 0000 0110 0001 - {SUB, "B,A" }, // 62: 0110 0000 0110 0010 - {SUB, "C,A" }, // 63: 0110 0000 0110 0011 - {SUB, "D,A" }, // 64: 0110 0000 0110 0100 - {SUB, "E,A" }, // 65: 0110 0000 0110 0101 - {SUB, "H,A" }, // 66: 0110 0000 0110 0110 - {SUB, "L,A" }, // 67: 0110 0000 0110 0111 - {NEA, "V,A" }, // 68: 0110 0000 0110 1000 - {NEA, "A,A" }, // 69: 0110 0000 0110 1001 - {NEA, "B,A" }, // 6a: 0110 0000 0110 1010 - {NEA, "C,A" }, // 6b: 0110 0000 0110 1011 - {NEA, "D,A" }, // 6c: 0110 0000 0110 1100 - {NEA, "E,A" }, // 6d: 0110 0000 0110 1101 - {NEA, "H,A" }, // 6e: 0110 0000 0110 1110 - {NEA, "L,A" }, // 6f: 0110 0000 0110 1111 - - {SBB, "V,A" }, // 70: 0110 0000 0111 0000 - {SBB, "A,A" }, // 71: 0110 0000 0111 0001 - {SBB, "B,A" }, // 72: 0110 0000 0111 0010 - {SBB, "C,A" }, // 73: 0110 0000 0111 0011 - {SBB, "D,A" }, // 74: 0110 0000 0111 0100 - {SBB, "E,A" }, // 75: 0110 0000 0111 0101 - {SBB, "H,A" }, // 76: 0110 0000 0111 0110 - {SBB, "L,A" }, // 77: 0110 0000 0111 0111 - {EQA, "V,A" }, // 78: 0110 0000 0111 1000 - {EQA, "A,A" }, // 79: 0110 0000 0111 1001 - {EQA, "B,A" }, // 7a: 0110 0000 0111 1010 - {EQA, "C,A" }, // 7b: 0110 0000 0111 1011 - {EQA, "D,A" }, // 7c: 0110 0000 0111 1100 - {EQA, "E,A" }, // 7d: 0110 0000 0111 1101 - {EQA, "H,A" }, // 7e: 0110 0000 0111 1110 - {EQA, "L,A" }, // 7f: 0110 0000 0111 1111 - - { }, // 80: 0110 0000 1000 0000 - { }, // 81: 0110 0000 1000 0001 - { }, // 82: 0110 0000 1000 0010 - { }, // 83: 0110 0000 1000 0011 - { }, // 84: 0110 0000 1000 0100 - { }, // 85: 0110 0000 1000 0101 - { }, // 86: 0110 0000 1000 0110 - { }, // 87: 0110 0000 1000 0111 - {ANA, "A,V" }, // 88: 0110 0000 1000 1000 - {ANA, "A,A" }, // 89: 0110 0000 1000 1001 - {ANA, "A,B" }, // 8a: 0110 0000 1000 1010 - {ANA, "A,C" }, // 8b: 0110 0000 1000 1011 - {ANA, "A,D" }, // 8c: 0110 0000 1000 1100 - {ANA, "A,E" }, // 8d: 0110 0000 1000 1101 - {ANA, "A,H" }, // 8e: 0110 0000 1000 1110 - {ANA, "A,L" }, // 8f: 0110 0000 1000 1111 - - {XRA, "A,V" }, // 90: 0110 0000 1001 0000 - {XRA, "A,A" }, // 91: 0110 0000 1001 0001 - {XRA, "A,B" }, // 92: 0110 0000 1001 0010 - {XRA, "A,C" }, // 93: 0110 0000 1001 0011 - {XRA, "A,D" }, // 94: 0110 0000 1001 0100 - {XRA, "A,E" }, // 95: 0110 0000 1001 0101 - {XRA, "A,H" }, // 96: 0110 0000 1001 0110 - {XRA, "A,L" }, // 97: 0110 0000 1001 0111 - {ORA, "A,V" }, // 98: 0110 0000 1001 1000 - {ORA, "A,A" }, // 99: 0110 0000 1001 1001 - {ORA, "A,B" }, // 9a: 0110 0000 1001 1010 - {ORA, "A,C" }, // 9b: 0110 0000 1001 1011 - {ORA, "A,D" }, // 9c: 0110 0000 1001 1100 - {ORA, "A,E" }, // 9d: 0110 0000 1001 1101 - {ORA, "A,H" }, // 9e: 0110 0000 1001 1110 - {ORA, "A,L" }, // 9f: 0110 0000 1001 1111 - - {ADDNC, "A,V" }, // a0: 0110 0000 1010 0000 - {ADDNC, "A,A" }, // a1: 0110 0000 1010 0001 - {ADDNC, "A,B" }, // a2: 0110 0000 1010 0010 - {ADDNC, "A,C" }, // a3: 0110 0000 1010 0011 - {ADDNC, "A,D" }, // a4: 0110 0000 1010 0100 - {ADDNC, "A,E" }, // a5: 0110 0000 1010 0101 - {ADDNC, "A,H" }, // a6: 0110 0000 1010 0110 - {ADDNC, "A,L" }, // a7: 0110 0000 1010 0111 - {GTA, "A,V" }, // a8: 0110 0000 1010 1000 - {GTA, "A,A" }, // a9: 0110 0000 1010 1001 - {GTA, "A,B" }, // aa: 0110 0000 1010 1010 - {GTA, "A,C" }, // ab: 0110 0000 1010 1011 - {GTA, "A,D" }, // ac: 0110 0000 1010 1100 - {GTA, "A,E" }, // ad: 0110 0000 1010 1101 - {GTA, "A,H" }, // ae: 0110 0000 1010 1110 - {GTA, "A,L" }, // af: 0110 0000 1010 1111 - - {SUBNB, "A,V" }, // b0: 0110 0000 1011 0000 - {SUBNB, "A,A" }, // b1: 0110 0000 1011 0001 - {SUBNB, "A,B" }, // b2: 0110 0000 1011 0010 - {SUBNB, "A,C" }, // b3: 0110 0000 1011 0011 - {SUBNB, "A,D" }, // b4: 0110 0000 1011 0100 - {SUBNB, "A,E" }, // b5: 0110 0000 1011 0101 - {SUBNB, "A,H" }, // b6: 0110 0000 1011 0110 - {SUBNB, "A,L" }, // b7: 0110 0000 1011 0111 - {LTA, "A,V" }, // b8: 0110 0000 1011 1000 - {LTA, "A,A" }, // b9: 0110 0000 1011 1001 - {LTA, "A,B" }, // ba: 0110 0000 1011 1010 - {LTA, "A,C" }, // bb: 0110 0000 1011 1011 - {LTA, "A,D" }, // bc: 0110 0000 1011 1100 - {LTA, "A,E" }, // bd: 0110 0000 1011 1101 - {LTA, "A,H" }, // be: 0110 0000 1011 1110 - {LTA, "A,L" }, // bf: 0110 0000 1011 1111 - - {ADD, "A,V" }, // c0: 0110 0000 1100 0000 - {ADD, "A,A" }, // c1: 0110 0000 1100 0001 - {ADD, "A,B" }, // c2: 0110 0000 1100 0010 - {ADD, "A,C" }, // c3: 0110 0000 1100 0011 - {ADD, "A,D" }, // c4: 0110 0000 1100 0100 - {ADD, "A,E" }, // c5: 0110 0000 1100 0101 - {ADD, "A,H" }, // c6: 0110 0000 1100 0110 - {ADD, "A,L" }, // c7: 0110 0000 1100 0111 - {ONA, "A,V" }, // c8: 0110 0000 1100 1000 - {ONA, "A,A" }, // c9: 0110 0000 1100 1001 - {ONA, "A,B" }, // ca: 0110 0000 1100 1010 - {ONA, "A,C" }, // cb: 0110 0000 1100 1011 - {ONA, "A,D" }, // cc: 0110 0000 1100 1100 - {ONA, "A,E" }, // cd: 0110 0000 1100 1101 - {ONA, "A,H" }, // ce: 0110 0000 1100 1110 - {ONA, "A,L" }, // cf: 0110 0000 1100 1111 - - {ADC, "A,V" }, // d0: 0110 0000 1101 0000 - {ADC, "A,A" }, // d1: 0110 0000 1101 0001 - {ADC, "A,B" }, // d2: 0110 0000 1101 0010 - {ADC, "A,C" }, // d3: 0110 0000 1101 0011 - {ADC, "A,D" }, // d4: 0110 0000 1101 0100 - {ADC, "A,E" }, // d5: 0110 0000 1101 0101 - {ADC, "A,H" }, // d6: 0110 0000 1101 0110 - {ADC, "A,L" }, // d7: 0110 0000 1101 0111 - {OFFA, "A,V" }, // d8: 0110 0000 1101 1000 - {OFFA, "A,A" }, // d9: 0110 0000 1101 1001 - {OFFA, "A,B" }, // da: 0110 0000 1101 1010 - {OFFA, "A,C" }, // db: 0110 0000 1101 1011 - {OFFA, "A,D" }, // dc: 0110 0000 1101 1100 - {OFFA, "A,E" }, // dd: 0110 0000 1101 1101 - {OFFA, "A,H" }, // de: 0110 0000 1101 1110 - {OFFA, "A,L" }, // df: 0110 0000 1101 1111 - - {SUB, "A,V" }, // e0: 0110 0000 1110 0000 - {SUB, "A,A" }, // e1: 0110 0000 1110 0001 - {SUB, "A,B" }, // e2: 0110 0000 1110 0010 - {SUB, "A,C" }, // e3: 0110 0000 1110 0011 - {SUB, "A,D" }, // e4: 0110 0000 1110 0100 - {SUB, "A,E" }, // e5: 0110 0000 1110 0101 - {SUB, "A,H" }, // e6: 0110 0000 1110 0110 - {SUB, "A,L" }, // e7: 0110 0000 1110 0111 - {NEA, "A,V" }, // e8: 0110 0000 1110 1000 - {NEA, "A,A" }, // e9: 0110 0000 1110 1001 - {NEA, "A,B" }, // ea: 0110 0000 1110 1010 - {NEA, "A,C" }, // eb: 0110 0000 1110 1011 - {NEA, "A,D" }, // ec: 0110 0000 1110 1100 - {NEA, "A,E" }, // ed: 0110 0000 1110 1101 - {NEA, "A,H" }, // ee: 0110 0000 1110 1110 - {NEA, "A,L" }, // ef: 0110 0000 1110 1111 - - {SBB, "A,V" }, // f0: 0110 0000 1111 0000 - {SBB, "A,A" }, // f1: 0110 0000 1111 0001 - {SBB, "A,B" }, // f2: 0110 0000 1111 0010 - {SBB, "A,C" }, // f3: 0110 0000 1111 0011 - {SBB, "A,D" }, // f4: 0110 0000 1111 0100 - {SBB, "A,E" }, // f5: 0110 0000 1111 0101 - {SBB, "A,H" }, // f6: 0110 0000 1111 0110 - {SBB, "A,L" }, // f7: 0110 0000 1111 0111 - {EQA, "A,V" }, // f8: 0110 0000 1111 1000 - {EQA, "A,A" }, // f9: 0110 0000 1111 1001 - {EQA, "A,B" }, // fa: 0110 0000 1111 1010 - {EQA, "A,C" }, // fb: 0110 0000 1111 1011 - {EQA, "A,D" }, // fc: 0110 0000 1111 1100 - {EQA, "A,E" }, // fd: 0110 0000 1111 1101 - {EQA, "A,H" }, // fe: 0110 0000 1111 1110 - {EQA, "A,L" } // ff: 0110 0000 1111 1111 -}; // prefix 64 -const dasm_s dasm_s::d64_7810[256] = +const upd7810_base_disassembler::dasm_s upd7810_disassembler::d64_7810[256] = { {MVI, "PA,%b" }, // 00: 0110 0100 0000 0000 xxxx xxxx {MVI, "PB,%b" }, // 01: 0110 0100 0000 0001 xxxx xxxx @@ -2637,835 +2169,10 @@ const dasm_s dasm_s::d64_7810[256] = { } // ff: 0110 0100 1111 1111 xxxx xxxx }; -const dasm_s dasm_s::d64_7807[256] = -{ - {MVI, "PA,%b" }, // 00: 0110 0100 0000 0000 xxxx xxxx - {MVI, "PB,%b" }, // 01: 0110 0100 0000 0001 xxxx xxxx - {MVI, "PC,%b" }, // 02: 0110 0100 0000 0010 xxxx xxxx - {MVI, "PD,%b" }, // 03: 0110 0100 0000 0011 xxxx xxxx - { }, // 04: 0110 0100 0000 0100 xxxx xxxx - {MVI, "PF,%b" }, // 05: 0110 0100 0000 0101 xxxx xxxx - {MVI, "MKH,%b" }, // 06: 0110 0100 0000 0110 xxxx xxxx - {MVI, "MKL,%b" }, // 07: 0110 0100 0000 0111 xxxx xxxx - {ANI, "PA,%b" }, // 08: 0110 0100 0000 1000 xxxx xxxx - {ANI, "PB,%b" }, // 09: 0110 0100 0000 1001 xxxx xxxx - {ANI, "PC,%b" }, // 0a: 0110 0100 0000 1010 xxxx xxxx - {ANI, "PD,%b" }, // 0b: 0110 0100 0000 1011 xxxx xxxx - { }, // 0c: 0110 0100 0000 1100 xxxx xxxx - {ANI, "PF,%b" }, // 0d: 0110 0100 0000 1101 xxxx xxxx - {ANI, "MKH,%b" }, // 0e: 0110 0100 0000 1110 xxxx xxxx - {ANI, "MKL,%b" }, // 0f: 0110 0100 0000 1111 xxxx xxxx - - {XRI, "PA,%b" }, // 10: 0110 0100 0001 0000 xxxx xxxx - {XRI, "PB,%b" }, // 11: 0110 0100 0001 0001 xxxx xxxx - {XRI, "PC,%b" }, // 12: 0110 0100 0001 0010 xxxx xxxx - {XRI, "PD,%b" }, // 13: 0110 0100 0001 0011 xxxx xxxx - { }, // 14: 0110 0100 0001 0100 xxxx xxxx - {XRI, "PF,%b" }, // 15: 0110 0100 0001 0101 xxxx xxxx - {XRI, "MKH,%b" }, // 16: 0110 0100 0001 0110 xxxx xxxx - {XRI, "MKL,%b" }, // 17: 0110 0100 0001 0111 xxxx xxxx - {ORI, "PA,%b" }, // 18: 0110 0100 0001 1000 xxxx xxxx - {ORI, "PB,%b" }, // 19: 0110 0100 0001 1001 xxxx xxxx - {ORI, "PC,%b" }, // 1a: 0110 0100 0001 1010 xxxx xxxx - {ORI, "PD,%b" }, // 1b: 0110 0100 0001 1011 xxxx xxxx - { }, // 1c: 0110 0100 0001 1100 xxxx xxxx - {ORI, "PF,%b" }, // 1d: 0110 0100 0001 1101 xxxx xxxx - {ORI, "MKH,%b" }, // 1e: 0110 0100 0001 1110 xxxx xxxx - {ORI, "MKL,%b" }, // 1f: 0110 0100 0001 1111 xxxx xxxx - - {ADINC, "PA,%b" }, // 20: 0110 0100 0010 0000 xxxx xxxx - {ADINC, "PB,%b" }, // 21: 0110 0100 0010 0001 xxxx xxxx - {ADINC, "PC,%b" }, // 22: 0110 0100 0010 0010 xxxx xxxx - {ADINC, "PD,%b" }, // 23: 0110 0100 0010 0011 xxxx xxxx - { }, // 24: 0110 0100 0010 0100 xxxx xxxx - {ADINC, "PF,%b" }, // 25: 0110 0100 0010 0101 xxxx xxxx - {ADINC, "MKH,%b" }, // 26: 0110 0100 0010 0110 xxxx xxxx - {ADINC, "MKL,%b" }, // 27: 0110 0100 0010 0111 xxxx xxxx - {GTI, "PA,%b" }, // 28: 0110 0100 0010 1000 xxxx xxxx - {GTI, "PB,%b" }, // 29: 0110 0100 0010 1001 xxxx xxxx - {GTI, "PC,%b" }, // 2a: 0110 0100 0010 1010 xxxx xxxx - {GTI, "PD,%b" }, // 2b: 0110 0100 0010 1011 xxxx xxxx - { }, // 2c: 0110 0100 0010 1100 xxxx xxxx - {GTI, "PF,%b" }, // 2d: 0110 0100 0010 1101 xxxx xxxx - {GTI, "MKH,%b" }, // 2e: 0110 0100 0010 1110 xxxx xxxx - {GTI, "MKL,%b" }, // 2f: 0110 0100 0010 1111 xxxx xxxx - - {SUINB, "PA,%b" }, // 30: 0110 0100 0011 0000 xxxx xxxx - {SUINB, "PB,%b" }, // 31: 0110 0100 0011 0001 xxxx xxxx - {SUINB, "PC,%b" }, // 32: 0110 0100 0011 0010 xxxx xxxx - {SUINB, "PD,%b" }, // 33: 0110 0100 0011 0011 xxxx xxxx - { }, // 34: 0110 0100 0011 0100 xxxx xxxx - {SUINB, "PF,%b" }, // 35: 0110 0100 0011 0101 xxxx xxxx - {SUINB, "MKH,%b" }, // 36: 0110 0100 0011 0110 xxxx xxxx - {SUINB, "MKL,%b" }, // 37: 0110 0100 0011 0111 xxxx xxxx - {LTI, "PA,%b" }, // 38: 0110 0100 0011 1000 xxxx xxxx - {LTI, "PB,%b" }, // 39: 0110 0100 0011 1001 xxxx xxxx - {LTI, "PC,%b" }, // 3a: 0110 0100 0011 1010 xxxx xxxx - {LTI, "PD,%b" }, // 3b: 0110 0100 0011 1011 xxxx xxxx - { }, // 3c: 0110 0100 0011 1100 xxxx xxxx - {LTI, "PF,%b" }, // 3d: 0110 0100 0011 1101 xxxx xxxx - {LTI, "MKH,%b" }, // 3e: 0110 0100 0011 1110 xxxx xxxx - {LTI, "MKL,%b" }, // 3f: 0110 0100 0011 1111 xxxx xxxx - - {ADI, "PA,%b" }, // 40: 0110 0100 0100 0000 xxxx xxxx - {ADI, "PB,%b" }, // 41: 0110 0100 0100 0001 xxxx xxxx - {ADI, "PC,%b" }, // 42: 0110 0100 0100 0010 xxxx xxxx - {ADI, "PD,%b" }, // 43: 0110 0100 0100 0011 xxxx xxxx - { }, // 44: 0110 0100 0100 0100 xxxx xxxx - {ADI, "PF,%b" }, // 45: 0110 0100 0100 0101 xxxx xxxx - {ADI, "MKH,%b" }, // 46: 0110 0100 0100 0110 xxxx xxxx - {ADI, "MKL,%b" }, // 47: 0110 0100 0100 0111 xxxx xxxx - {ONI, "PA,%b" }, // 48: 0110 0100 0100 1000 xxxx xxxx - {ONI, "PB,%b" }, // 49: 0110 0100 0100 1001 xxxx xxxx - {ONI, "PC,%b" }, // 4a: 0110 0100 0100 1010 xxxx xxxx - {ONI, "PD,%b" }, // 4b: 0110 0100 0100 1011 xxxx xxxx - { }, // 4c: 0110 0100 0100 1100 xxxx xxxx - {ONI, "PF,%b" }, // 4d: 0110 0100 0100 1101 xxxx xxxx - {ONI, "MKH,%b" }, // 4e: 0110 0100 0100 1110 xxxx xxxx - {ONI, "MKL,%b" }, // 4f: 0110 0100 0100 1111 xxxx xxxx - - {ACI, "PA,%b" }, // 50: 0110 0100 0101 0000 xxxx xxxx - {ACI, "PB,%b" }, // 51: 0110 0100 0101 0001 xxxx xxxx - {ACI, "PC,%b" }, // 52: 0110 0100 0101 0010 xxxx xxxx - {ACI, "PD,%b" }, // 53: 0110 0100 0101 0011 xxxx xxxx - { }, // 54: 0110 0100 0101 0100 xxxx xxxx - {ACI, "PF,%b" }, // 55: 0110 0100 0101 0101 xxxx xxxx - {ACI, "MKH,%b" }, // 56: 0110 0100 0101 0110 xxxx xxxx - {ACI, "MKL,%b" }, // 57: 0110 0100 0101 0111 xxxx xxxx - {OFFI, "PA,%b" }, // 58: 0110 0100 0101 1000 xxxx xxxx - {OFFI, "PB,%b" }, // 59: 0110 0100 0101 1001 xxxx xxxx - {OFFI, "PC,%b" }, // 5a: 0110 0100 0101 1010 xxxx xxxx - {OFFI, "PD,%b" }, // 5b: 0110 0100 0101 1011 xxxx xxxx - { }, // 5c: 0110 0100 0101 1100 xxxx xxxx - {OFFI, "PF,%b" }, // 5d: 0110 0100 0101 1101 xxxx xxxx - {OFFI, "MKH,%b" }, // 5e: 0110 0100 0101 1110 xxxx xxxx - {OFFI, "MKL,%b" }, // 5f: 0110 0100 0101 1111 xxxx xxxx - - {SUI, "PA,%b" }, // 60: 0110 0100 0110 0000 xxxx xxxx - {SUI, "PB,%b" }, // 61: 0110 0100 0110 0001 xxxx xxxx - {SUI, "PC,%b" }, // 62: 0110 0100 0110 0010 xxxx xxxx - {SUI, "PD,%b" }, // 63: 0110 0100 0110 0011 xxxx xxxx - { }, // 64: 0110 0100 0110 0100 xxxx xxxx - {SUI, "PF,%b" }, // 65: 0110 0100 0110 0101 xxxx xxxx - {SUI, "MKH,%b" }, // 66: 0110 0100 0110 0110 xxxx xxxx - {SUI, "MKL,%b" }, // 67: 0110 0100 0110 0111 xxxx xxxx - {NEI, "PA,%b" }, // 68: 0110 0100 0110 1000 xxxx xxxx - {NEI, "PB,%b" }, // 69: 0110 0100 0110 1001 xxxx xxxx - {NEI, "PC,%b" }, // 6a: 0110 0100 0110 1010 xxxx xxxx - {NEI, "PD,%b" }, // 6b: 0110 0100 0110 1011 xxxx xxxx - { }, // 6c: 0110 0100 0110 1100 xxxx xxxx - {NEI, "PF,%b" }, // 6d: 0110 0100 0110 1101 xxxx xxxx - {NEI, "MKH,%b" }, // 6e: 0110 0100 0110 1110 xxxx xxxx - {NEI, "MKL,%b" }, // 6f: 0110 0100 0110 1111 xxxx xxxx - - {SBI, "PA,%b" }, // 70: 0110 0100 0111 0000 xxxx xxxx - {SBI, "PB,%b" }, // 71: 0110 0100 0111 0001 xxxx xxxx - {SBI, "PC,%b" }, // 72: 0110 0100 0111 0010 xxxx xxxx - {SBI, "PD,%b" }, // 73: 0110 0100 0111 0011 xxxx xxxx - { }, // 74: 0110 0100 0111 0100 xxxx xxxx - {SBI, "PF,%b" }, // 75: 0110 0100 0111 0101 xxxx xxxx - {SBI, "MKH,%b" }, // 76: 0110 0100 0111 0110 xxxx xxxx - {SBI, "MKL,%b" }, // 77: 0110 0100 0111 0111 xxxx xxxx - {EQI, "PA,%b" }, // 78: 0110 0100 0111 1000 xxxx xxxx - {EQI, "PB,%b" }, // 79: 0110 0100 0111 1001 xxxx xxxx - {EQI, "PC,%b" }, // 7a: 0110 0100 0111 1010 xxxx xxxx - {EQI, "PD,%b" }, // 7b: 0110 0100 0111 1011 xxxx xxxx - { }, // 7c: 0110 0100 0111 1100 xxxx xxxx - {EQI, "PF,%b" }, // 7d: 0110 0100 0111 1101 xxxx xxxx - {EQI, "MKH,%b" }, // 7e: 0110 0100 0111 1110 xxxx xxxx - {EQI, "MKL,%b" }, // 7f: 0110 0100 0111 1111 xxxx xxxx - - { }, // 80: 0110 0100 1000 0000 xxxx xxxx - {MVI, "SMH,%b" }, // 81: 0110 0100 1000 0001 xxxx xxxx - { }, // 82: 0110 0100 1000 0010 xxxx xxxx - {MVI, "EOM,%b" }, // 83: 0110 0100 1000 0011 xxxx xxxx - { }, // 84: 0110 0100 1000 0100 xxxx xxxx - {MVI, "TMM,%b" }, // 85: 0110 0100 1000 0101 xxxx xxxx - { }, // 86: 0110 0100 1000 0110 xxxx xxxx - { }, // 87: 0110 0100 1000 0111 xxxx xxxx - { }, // 88: 0110 0100 1000 1000 xxxx xxxx - {ANI, "SMH,%b" }, // 89: 0110 0100 1000 1001 xxxx xxxx - { }, // 8a: 0110 0100 1000 1010 xxxx xxxx - {ANI, "EOM,%b" }, // 8b: 0110 0100 1000 1011 xxxx xxxx - { }, // 8c: 0110 0100 1000 1100 xxxx xxxx - {ANI, "TMM,%b" }, // 8d: 0110 0100 1000 1101 xxxx xxxx - { }, // 8e: 0110 0100 1000 1110 xxxx xxxx - { }, // 8f: 0110 0100 1000 1111 xxxx xxxx - - { }, // 90: 0110 0100 1001 0000 xxxx xxxx - {XRI, "SMH,%b" }, // 91: 0110 0100 1001 0001 xxxx xxxx - { }, // 92: 0110 0100 1001 0010 xxxx xxxx - {XRI, "EOM,%b" }, // 93: 0110 0100 1001 0011 xxxx xxxx - { }, // 94: 0110 0100 1001 0100 xxxx xxxx - {XRI, "TMM,%b" }, // 95: 0110 0100 1001 0101 xxxx xxxx - { }, // 96: 0110 0100 1001 0110 xxxx xxxx - { }, // 97: 0110 0100 1001 0111 xxxx xxxx - { }, // 98: 0110 0100 1001 1000 xxxx xxxx - {ORI, "SMH,%b" }, // 99: 0110 0100 1001 1001 xxxx xxxx - { }, // 9a: 0110 0100 1001 1010 xxxx xxxx - {ORI, "EOM,%b" }, // 9b: 0110 0100 1001 1011 xxxx xxxx - { }, // 9c: 0110 0100 1001 1100 xxxx xxxx - {ORI, "TMM,%b" }, // 9d: 0110 0100 1001 1101 xxxx xxxx - { }, // 9e: 0110 0100 1001 1110 xxxx xxxx - { }, // 9f: 0110 0100 1001 1111 xxxx xxxx - - { }, // a0: 0110 0100 1010 0000 xxxx xxxx - {ADINC, "SMH,%b" }, // a1: 0110 0100 1010 0001 xxxx xxxx - { }, // a2: 0110 0100 1010 0010 xxxx xxxx - {ADINC, "EOM,%b" }, // a3: 0110 0100 1010 0011 xxxx xxxx - { }, // a4: 0110 0100 1010 0100 xxxx xxxx - {ADINC, "TMM,%b" }, // a5: 0110 0100 1010 0101 xxxx xxxx - { }, // a6: 0110 0100 1010 0110 xxxx xxxx - { }, // a7: 0110 0100 1010 0111 xxxx xxxx - { }, // a8: 0110 0100 1010 1000 xxxx xxxx - {GTI, "SMH,%b" }, // a9: 0110 0100 1010 1001 xxxx xxxx - { }, // aa: 0110 0100 1010 1010 xxxx xxxx - {GTI, "EOM,%b" }, // ab: 0110 0100 1010 1011 xxxx xxxx - { }, // ac: 0110 0100 1010 1100 xxxx xxxx - {GTI, "TMM,%b" }, // ad: 0110 0100 1010 1101 xxxx xxxx - {GTI, "PT,%b" }, // ae: 0110 0100 1010 1110 xxxx xxxx - { }, // af: 0110 0100 1010 1111 xxxx xxxx - - { }, // b0: 0110 0100 1011 0000 xxxx xxxx - {SUINB, "SMH,%b" }, // b1: 0110 0100 1011 0001 xxxx xxxx - { }, // b2: 0110 0100 1011 0010 xxxx xxxx - {SUINB, "EOM,%b" }, // b3: 0110 0100 1011 0011 xxxx xxxx - { }, // b4: 0110 0100 1011 0100 xxxx xxxx - {SUINB, "TMM,%b" }, // b5: 0110 0100 1011 0101 xxxx xxxx - { }, // b6: 0110 0100 1011 0110 xxxx xxxx - { }, // b7: 0110 0100 1011 0111 xxxx xxxx - { }, // b8: 0110 0100 1011 1000 xxxx xxxx - {LTI, "SMH,%b" }, // b9: 0110 0100 1011 1001 xxxx xxxx - { }, // ba: 0110 0100 1011 1010 xxxx xxxx - {LTI, "EOM,%b" }, // bb: 0110 0100 1011 1011 xxxx xxxx - { }, // bc: 0110 0100 1011 1100 xxxx xxxx - {LTI, "TMM,%b" }, // bd: 0110 0100 1011 1101 xxxx xxxx - {LTI, "PT,%b" }, // be: 0110 0100 1011 1110 xxxx xxxx - { }, // bf: 0110 0100 1011 1111 xxxx xxxx - - { }, // c0: 0110 0100 1100 0000 xxxx xxxx - {ADI, "SMH,%b" }, // c1: 0110 0100 1100 0001 xxxx xxxx - { }, // c2: 0110 0100 1100 0010 xxxx xxxx - {ADI, "EOM,%b" }, // c3: 0110 0100 1100 0011 xxxx xxxx - { }, // c4: 0110 0100 1100 0100 xxxx xxxx - {ADI, "TMM,%b" }, // c5: 0110 0100 1100 0101 xxxx xxxx - { }, // c6: 0110 0100 1100 0110 xxxx xxxx - { }, // c7: 0110 0100 1100 0111 xxxx xxxx - { }, // c8: 0110 0100 1100 1000 xxxx xxxx - {ONI, "SMH,%b" }, // c9: 0110 0100 1100 1001 xxxx xxxx - { }, // ca: 0110 0100 1100 1010 xxxx xxxx - {ONI, "EOM,%b" }, // cb: 0110 0100 1100 1011 xxxx xxxx - { }, // cc: 0110 0100 1100 1100 xxxx xxxx - {ONI, "TMM,%b" }, // cd: 0110 0100 1100 1101 xxxx xxxx - {ONI, "PT,%b" }, // ce: 0110 0100 1100 1110 xxxx xxxx - { }, // cf: 0110 0100 1100 1111 xxxx xxxx - - { }, // d0: 0110 0100 1101 0000 xxxx xxxx - {ACI, "SMH,%b" }, // d1: 0110 0100 1101 0001 xxxx xxxx - { }, // d2: 0110 0100 1101 0010 xxxx xxxx - {ACI, "EOM,%b" }, // d3: 0110 0100 1101 0011 xxxx xxxx - { }, // d4: 0110 0100 1101 0100 xxxx xxxx - {ACI, "TMM,%b" }, // d5: 0110 0100 1101 0101 xxxx xxxx - { }, // d6: 0110 0100 1101 0110 xxxx xxxx - { }, // d7: 0110 0100 1101 0111 xxxx xxxx - { }, // d8: 0110 0100 1101 1000 xxxx xxxx - {OFFI, "SMH,%b" }, // d9: 0110 0100 1101 1001 xxxx xxxx - { }, // da: 0110 0100 1101 1010 xxxx xxxx - {OFFI, "EOM,%b" }, // db: 0110 0100 1101 1011 xxxx xxxx - { }, // dc: 0110 0100 1101 1100 xxxx xxxx - {OFFI, "TMM,%b" }, // dd: 0110 0100 1101 1101 xxxx xxxx - {OFFI, "PT,%b" }, // de: 0110 0100 1101 1110 xxxx xxxx - { }, // df: 0110 0100 1101 1111 xxxx xxxx - - { }, // e0: 0110 0100 1110 0000 xxxx xxxx - {SUI, "SMH,%b" }, // e1: 0110 0100 1110 0001 xxxx xxxx - { }, // e2: 0110 0100 1110 0010 xxxx xxxx - {SUI, "EOM,%b" }, // e3: 0110 0100 1110 0011 xxxx xxxx - { }, // e4: 0110 0100 1110 0100 xxxx xxxx - {SUI, "TMM,%b" }, // e5: 0110 0100 1110 0101 xxxx xxxx - { }, // e6: 0110 0100 1110 0110 xxxx xxxx - { }, // e7: 0110 0100 1110 0111 xxxx xxxx - { }, // e8: 0110 0100 1110 1000 xxxx xxxx - {NEI, "SMH,%b" }, // e9: 0110 0100 1110 1001 xxxx xxxx - { }, // ea: 0110 0100 1110 1010 xxxx xxxx - {NEI, "EOM,%b" }, // eb: 0110 0100 1110 1011 xxxx xxxx - { }, // ec: 0110 0100 1110 1100 xxxx xxxx - {NEI, "TMM,%b" }, // ed: 0110 0100 1110 1101 xxxx xxxx - {NEI, "PT,%b" }, // ee: 0110 0100 1110 1110 xxxx xxxx - { }, // ef: 0110 0100 1110 1111 xxxx xxxx - - { }, // f0: 0110 0100 1111 0000 xxxx xxxx - {SBI, "SMH,%b" }, // f1: 0110 0100 1111 0001 xxxx xxxx - { }, // f2: 0110 0100 1111 0010 xxxx xxxx - {SBI, "EOM,%b" }, // f3: 0110 0100 1111 0011 xxxx xxxx - { }, // f4: 0110 0100 1111 0100 xxxx xxxx - {SBI, "TMM,%b" }, // f5: 0110 0100 1111 0101 xxxx xxxx - { }, // f6: 0110 0100 1111 0110 xxxx xxxx - { }, // f7: 0110 0100 1111 0111 xxxx xxxx - { }, // f8: 0110 0100 1111 1000 xxxx xxxx - {EQI, "SMH,%b" }, // f9: 0110 0100 1111 1001 xxxx xxxx - { }, // fa: 0110 0100 1111 1010 xxxx xxxx - {EQI, "EOM,%b" }, // fb: 0110 0100 1111 1011 xxxx xxxx - { }, // fc: 0110 0100 1111 1100 xxxx xxxx - {EQI, "TMM,%b" }, // fd: 0110 0100 1111 1101 xxxx xxxx - {EQI, "PT,%b" }, // fe: 0110 0100 1111 1110 xxxx xxxx - { } // ff: 0110 0100 1111 1111 xxxx xxxx -}; - -// prefix 70 -const dasm_s dasm_s::d70[256] = -{ - { }, // 00: 0111 0000 0000 0000 - { }, // 01: 0111 0000 0000 0001 - { }, // 02: 0111 0000 0000 0010 - { }, // 03: 0111 0000 0000 0011 - { }, // 04: 0111 0000 0000 0100 - { }, // 05: 0111 0000 0000 0101 - { }, // 06: 0111 0000 0000 0110 - { }, // 07: 0111 0000 0000 0111 - { }, // 08: 0111 0000 0000 1000 - { }, // 09: 0111 0000 0000 1001 - { }, // 0a: 0111 0000 0000 1010 - { }, // 0b: 0111 0000 0000 1011 - { }, // 0c: 0111 0000 0000 1100 - { }, // 0d: 0111 0000 0000 1101 - {SSPD, "%w" }, // 0e: 0111 0000 0000 1110 llll llll hhhh hhhh - {LSPD, "%w" }, // 0f: 0111 0000 0000 1111 llll llll hhhh hhhh - - { }, // 10: 0111 0000 0001 0000 - { }, // 11: 0111 0000 0001 0001 - { }, // 12: 0111 0000 0001 0010 - { }, // 13: 0111 0000 0001 0011 - { }, // 14: 0111 0000 0001 0100 - { }, // 15: 0111 0000 0001 0101 - { }, // 16: 0111 0000 0001 0110 - { }, // 17: 0111 0000 0001 0111 - { }, // 18: 0111 0000 0001 1000 - { }, // 19: 0111 0000 0001 1001 - { }, // 1a: 0111 0000 0001 1010 - { }, // 1b: 0111 0000 0001 1011 - { }, // 1c: 0111 0000 0001 1100 - { }, // 1d: 0111 0000 0001 1101 - {SBCD, "%w" }, // 1e: 0111 0000 0001 1110 llll llll hhhh hhhh - {LBCD, "%w" }, // 1f: 0111 0000 0001 1111 llll llll hhhh hhhh - - { }, // 20: 0111 0000 0010 0000 - { }, // 21: 0111 0000 0010 0001 - { }, // 22: 0111 0000 0010 0010 - { }, // 23: 0111 0000 0010 0011 - { }, // 24: 0111 0000 0010 0100 - { }, // 25: 0111 0000 0010 0101 - { }, // 26: 0111 0000 0010 0110 - { }, // 27: 0111 0000 0010 0111 - { }, // 28: 0111 0000 0010 1000 - { }, // 29: 0111 0000 0010 1001 - { }, // 2a: 0111 0000 0010 1010 - { }, // 2b: 0111 0000 0010 1011 - { }, // 2c: 0111 0000 0010 1100 - { }, // 2d: 0111 0000 0010 1101 - {SDED, "%w" }, // 2e: 0111 0000 0010 1110 llll llll hhhh hhhh - {LDED, "%w" }, // 2f: 0111 0000 0010 1111 llll llll hhhh hhhh - - { }, // 30: 0111 0000 0011 0000 - { }, // 31: 0111 0000 0011 0001 - { }, // 32: 0111 0000 0011 0010 - { }, // 33: 0111 0000 0011 0011 - { }, // 34: 0111 0000 0011 0100 - { }, // 35: 0111 0000 0011 0101 - { }, // 36: 0111 0000 0011 0110 - { }, // 37: 0111 0000 0011 0111 - { }, // 38: 0111 0000 0011 1000 - { }, // 39: 0111 0000 0011 1001 - { }, // 3a: 0111 0000 0011 1010 - { }, // 3b: 0111 0000 0011 1011 - { }, // 3c: 0111 0000 0011 1100 - { }, // 3d: 0111 0000 0011 1101 - {SHLD, "%w" }, // 3e: 0111 0000 0011 1110 llll llll hhhh hhhh - {LHLD, "%w" }, // 3f: 0111 0000 0011 1111 llll llll hhhh hhhh - - {EADD, "EA,V" }, // 40: 0111 0000 0100 0000 - {EADD, "EA,A" }, // 41: 0111 0000 0100 0001 - {EADD, "EA,B" }, // 42: 0111 0000 0100 0010 - {EADD, "EA,C" }, // 43: 0111 0000 0100 0011 - { }, // 44: 0111 0000 0100 0100 - { }, // 45: 0111 0000 0100 0101 - { }, // 46: 0111 0000 0100 0110 - { }, // 47: 0111 0000 0100 0111 - { }, // 48: 0111 0000 0100 1000 - { }, // 49: 0111 0000 0100 1001 - { }, // 4a: 0111 0000 0100 1010 - { }, // 4b: 0111 0000 0100 1011 - { }, // 4c: 0111 0000 0100 1100 - { }, // 4d: 0111 0000 0100 1101 - { }, // 4e: 0111 0000 0100 1110 - { }, // 4f: 0111 0000 0100 1111 - - { }, // 50: 0111 0000 0101 0000 - { }, // 51: 0111 0000 0101 0001 - { }, // 52: 0111 0000 0101 0010 - { }, // 53: 0111 0000 0101 0011 - { }, // 54: 0111 0000 0101 0100 - { }, // 55: 0111 0000 0101 0101 - { }, // 56: 0111 0000 0101 0110 - { }, // 57: 0111 0000 0101 0111 - { }, // 58: 0111 0000 0101 1000 - { }, // 59: 0111 0000 0101 1001 - { }, // 5a: 0111 0000 0101 1010 - { }, // 5b: 0111 0000 0101 1011 - { }, // 5c: 0111 0000 0101 1100 - { }, // 5d: 0111 0000 0101 1101 - { }, // 5e: 0111 0000 0101 1110 - { }, // 5f: 0111 0000 0101 1111 - - {ESUB, "EA,V" }, // 60: 0111 0000 0110 0000 - {ESUB, "EA,A" }, // 61: 0111 0000 0110 0001 - {ESUB, "EA,B" }, // 62: 0111 0000 0110 0010 - {ESUB, "EA,C" }, // 63: 0111 0000 0110 0011 - { }, // 64: 0111 0000 0110 0100 - { }, // 65: 0111 0000 0110 0101 - { }, // 66: 0111 0000 0110 0110 - { }, // 67: 0111 0000 0110 0111 - {MOV, "V,(%w)" }, // 68: 0111 0000 0110 1000 llll llll hhhh hhhh - {MOV, "A,(%w)" }, // 69: 0111 0000 0110 1001 llll llll hhhh hhhh - {MOV, "B,(%w)" }, // 6a: 0111 0000 0110 1010 llll llll hhhh hhhh - {MOV, "C,(%w)" }, // 6b: 0111 0000 0110 1011 llll llll hhhh hhhh - {MOV, "D,(%w)" }, // 6c: 0111 0000 0110 1100 llll llll hhhh hhhh - {MOV, "E,(%w)" }, // 6d: 0111 0000 0110 1101 llll llll hhhh hhhh - {MOV, "H,(%w)" }, // 6e: 0111 0000 0110 1110 llll llll hhhh hhhh - {MOV, "L,(%w)" }, // 6f: 0111 0000 0110 1111 llll llll hhhh hhhh - - { }, // 70: 0111 0000 0111 0000 - { }, // 71: 0111 0000 0111 0001 - { }, // 72: 0111 0000 0111 0010 - { }, // 73: 0111 0000 0111 0011 - { }, // 74: 0111 0000 0111 0100 - { }, // 75: 0111 0000 0111 0101 - { }, // 76: 0111 0000 0111 0110 - { }, // 77: 0111 0000 0111 0111 - {MOV, "(%w),V" }, // 78: 0111 0000 0111 1000 llll llll hhhh hhhh - {MOV, "(%w),A" }, // 79: 0111 0000 0111 1001 llll llll hhhh hhhh - {MOV, "(%w),B" }, // 7a: 0111 0000 0111 1010 llll llll hhhh hhhh - {MOV, "(%w),C" }, // 7b: 0111 0000 0111 1011 llll llll hhhh hhhh - {MOV, "(%w),D" }, // 7c: 0111 0000 0111 1100 llll llll hhhh hhhh - {MOV, "(%w),E" }, // 7d: 0111 0000 0111 1101 llll llll hhhh hhhh - {MOV, "(%w),H" }, // 7e: 0111 0000 0111 1110 llll llll hhhh hhhh - {MOV, "(%w),L" }, // 7f: 0111 0000 0111 1111 llll llll hhhh hhhh - - { }, // 80: 0111 0000 1000 0000 - { }, // 81: 0111 0000 1000 0001 - { }, // 82: 0111 0000 1000 0010 - { }, // 83: 0111 0000 1000 0011 - { }, // 84: 0111 0000 1000 0100 - { }, // 85: 0111 0000 1000 0101 - { }, // 86: 0111 0000 1000 0110 - { }, // 87: 0111 0000 1000 0111 - { }, // 88: 0111 0000 1000 1000 - {ANAX, "(BC)" }, // 89: 0111 0000 1000 1001 - {ANAX, "(DE)" }, // 8a: 0111 0000 1000 1010 - {ANAX, "(HL)" }, // 8b: 0111 0000 1000 1011 - {ANAX, "(DE+)" }, // 8c: 0111 0000 1000 1100 - {ANAX, "(HL+)" }, // 8d: 0111 0000 1000 1101 - {ANAX, "(DE-)" }, // 8e: 0111 0000 1000 1110 - {ANAX, "(HL-)" }, // 8f: 0111 0000 1000 1111 - - { }, // 90: 0111 0000 1001 0000 - {XRAX, "(BC)" }, // 91: 0111 0000 1001 0001 - {XRAX, "(DE)" }, // 92: 0111 0000 1001 0010 - {XRAX, "(HL)" }, // 93: 0111 0000 1001 0011 - {XRAX, "(DE+)" }, // 94: 0111 0000 1001 0100 - {XRAX, "(HL+)" }, // 95: 0111 0000 1001 0101 - {XRAX, "(DE-)" }, // 96: 0111 0000 1001 0110 - {XRAX, "(HL-)" }, // 97: 0111 0000 1001 0111 - { }, // 98: 0111 0000 1001 1000 - {ORAX, "(BC)" }, // 99: 0111 0000 1001 1001 - {ORAX, "(DE)" }, // 9a: 0111 0000 1001 1010 - {ORAX, "(HL)" }, // 9b: 0111 0000 1001 1011 - {ORAX, "(DE+)" }, // 9c: 0111 0000 1001 1100 - {ORAX, "(HL+)" }, // 9d: 0111 0000 1001 1101 - {ORAX, "(DE-)" }, // 9e: 0111 0000 1001 1110 - {ORAX, "(HL-)" }, // 9f: 0111 0000 1001 1111 - - { }, // a0: 0111 0000 1010 0000 - {ADDNCX, "(BC)" }, // a1: 0111 0000 1010 0001 - {ADDNCX, "(DE)" }, // a2: 0111 0000 1010 0010 - {ADDNCX, "(HL)" }, // a3: 0111 0000 1010 0011 - {ADDNCX, "(DE+)" }, // a4: 0111 0000 1010 0100 - {ADDNCX, "(HL+)" }, // a5: 0111 0000 1010 0101 - {ADDNCX, "(DE-)" }, // a6: 0111 0000 1010 0110 - {ADDNCX, "(HL-)" }, // a7: 0111 0000 1010 0111 - { }, // a8: 0111 0000 1010 1000 - {GTAX, "(BC)" }, // a9: 0111 0000 1010 1001 - {GTAX, "(DE)" }, // aa: 0111 0000 1010 1010 - {GTAX, "(HL)" }, // ab: 0111 0000 1010 1011 - {GTAX, "(DE+)" }, // ac: 0111 0000 1010 1100 - {GTAX, "(HL+)" }, // ad: 0111 0000 1010 1101 - {GTAX, "(DE-)" }, // ae: 0111 0000 1010 1110 - {GTAX, "(HL-)" }, // af: 0111 0000 1010 1111 - - { }, // b0: 0111 0000 1011 0000 - {SUBNBX, "(BC)" }, // b1: 0111 0000 1011 0001 - {SUBNBX, "(DE)" }, // b2: 0111 0000 1011 0010 - {SUBNBX, "(HL)" }, // b3: 0111 0000 1011 0011 - {SUBNBX, "(DE+)" }, // b4: 0111 0000 1011 0100 - {SUBNBX, "(HL+)" }, // b5: 0111 0000 1011 0101 - {SUBNBX, "(DE-)" }, // b6: 0111 0000 1011 0110 - {SUBNBX, "(HL-)" }, // b7: 0111 0000 1011 0111 - { }, // b8: 0111 0000 1011 1000 - {LTAX, "(BC)" }, // b9: 0111 0000 1011 1001 - {LTAX, "(DE)" }, // ba: 0111 0000 1011 1010 - {LTAX, "(HL)" }, // bb: 0111 0000 1011 1011 - {LTAX, "(DE+)" }, // bc: 0111 0000 1011 1100 - {LTAX, "(HL+)" }, // bd: 0111 0000 1011 1101 - {LTAX, "(DE-)" }, // be: 0111 0000 1011 1110 - {LTAX, "(HL-)" }, // bf: 0111 0000 1011 1111 - - { }, // c0: 0111 0000 1100 0000 - {ADDX, "(BC)" }, // c1: 0111 0000 1100 0001 - {ADDX, "(DE)" }, // c2: 0111 0000 1100 0010 - {ADDX, "(HL)" }, // c3: 0111 0000 1100 0011 - {ADDX, "(DE+)" }, // c4: 0111 0000 1100 0100 - {ADDX, "(HL+)" }, // c5: 0111 0000 1100 0101 - {ADDX, "(DE-)" }, // c6: 0111 0000 1100 0110 - {ADDX, "(HL-)" }, // c7: 0111 0000 1100 0111 - { }, // c8: 0111 0000 1100 1000 - {ONAX, "(BC)" }, // c9: 0111 0000 1100 1001 - {ONAX, "(DE)" }, // ca: 0111 0000 1100 1010 - {ONAX, "(HL)" }, // cb: 0111 0000 1100 1011 - {ONAX, "(DE+)" }, // cc: 0111 0000 1100 1100 - {ONAX, "(HL+)" }, // cd: 0111 0000 1100 1101 - {ONAX, "(DE-)" }, // ce: 0111 0000 1100 1110 - {ONAX, "(HL-)" }, // cf: 0111 0000 1100 1111 - - { }, // d0: 0111 0000 1101 0000 - {ADCX, "(BC)" }, // d1: 0111 0000 1101 0001 - {ADCX, "(DE)" }, // d2: 0111 0000 1101 0010 - {ADCX, "(HL)" }, // d3: 0111 0000 1101 0011 - {ADCX, "(DE+)" }, // d4: 0111 0000 1101 0100 - {ADCX, "(HL+)" }, // d5: 0111 0000 1101 0101 - {ADCX, "(DE-)" }, // d6: 0111 0000 1101 0110 - {ADCX, "(HL-)" }, // d7: 0111 0000 1101 0111 - { }, // d8: 0111 0000 1101 1000 - {OFFAX, "(BC)" }, // d9: 0111 0000 1101 1001 - {OFFAX, "(DE)" }, // da: 0111 0000 1101 1010 - {OFFAX, "(HL)" }, // db: 0111 0000 1101 1011 - {OFFAX, "(DE+)" }, // dc: 0111 0000 1101 1100 - {OFFAX, "(HL+)" }, // dd: 0111 0000 1101 1101 - {OFFAX, "(DE-)" }, // de: 0111 0000 1101 1110 - {OFFAX, "(HL-)" }, // df: 0111 0000 1101 1111 - - { }, // e0: 0111 0000 1110 0000 - {SUBX, "(BC)" }, // e1: 0111 0000 1110 0001 - {SUBX, "(DE)" }, // e2: 0111 0000 1110 0010 - {SUBX, "(HL)" }, // e3: 0111 0000 1110 0011 - {SUBX, "(DE+)" }, // e4: 0111 0000 1110 0100 - {SUBX, "(HL+)" }, // e5: 0111 0000 1110 0101 - {SUBX, "(DE-)" }, // e6: 0111 0000 1110 0110 - {SUBX, "(HL-)" }, // e7: 0111 0000 1110 0111 - { }, // e8: 0111 0000 1110 1000 - {NEAX, "(BC)" }, // e9: 0111 0000 1110 1001 - {NEAX, "(DE)" }, // ea: 0111 0000 1110 1010 - {NEAX, "(HL)" }, // eb: 0111 0000 1110 1011 - {NEAX, "(DE+)" }, // ec: 0111 0000 1110 1100 - {NEAX, "(HL+)" }, // ed: 0111 0000 1110 1101 - {NEAX, "(DE-)" }, // ee: 0111 0000 1110 1110 - {NEAX, "(HL-)" }, // ef: 0111 0000 1110 1111 - - { }, // f0: 0111 0000 1111 0000 - {SBBX, "(BC)" }, // f1: 0111 0000 1111 0001 - {SBBX, "(DE)" }, // f2: 0111 0000 1111 0010 - {SBBX, "(HL)" }, // f3: 0111 0000 1111 0011 - {SBBX, "(DE+)" }, // f4: 0111 0000 1111 0100 - {SBBX, "(HL+)" }, // f5: 0111 0000 1111 0101 - {SBBX, "(DE-)" }, // f6: 0111 0000 1111 0110 - {SBBX, "(HL-)" }, // f7: 0111 0000 1111 0111 - { }, // f8: 0111 0000 1111 1000 - {EQAX, "(BC)" }, // f9: 0111 0000 1111 1001 - {EQAX, "(DE)" }, // fa: 0111 0000 1111 1010 - {EQAX, "(HL)" }, // fb: 0111 0000 1111 1011 - {EQAX, "(DE+)" }, // fc: 0111 0000 1111 1100 - {EQAX, "(HL+)" }, // fd: 0111 0000 1111 1101 - {EQAX, "(DE-)" }, // fe: 0111 0000 1111 1110 - {EQAX, "(HL-)" } // ff: 0111 0000 1111 1111 -}; - -// prefix 74 -const dasm_s dasm_s::d74[256] = -{ - { }, // 00: 0111 0100 0000 0000 - { }, // 01: 0111 0100 0000 0001 - { }, // 02: 0111 0100 0000 0010 - { }, // 03: 0111 0100 0000 0011 - { }, // 04: 0111 0100 0000 0100 - { }, // 05: 0111 0100 0000 0101 - { }, // 06: 0111 0100 0000 0110 - { }, // 07: 0111 0100 0000 0111 - {ANI, "V,%b" }, // 08: 0111 0100 0000 1000 xxxx xxxx - {ANI, "A,%b" }, // 09: 0111 0100 0000 1001 xxxx xxxx - {ANI, "B,%b" }, // 0a: 0111 0100 0000 1010 xxxx xxxx - {ANI, "C,%b" }, // 0b: 0111 0100 0000 1011 xxxx xxxx - {ANI, "D,%b" }, // 0c: 0111 0100 0000 1100 xxxx xxxx - {ANI, "E,%b" }, // 0d: 0111 0100 0000 1101 xxxx xxxx - {ANI, "H,%b" }, // 0e: 0111 0100 0000 1110 xxxx xxxx - {ANI, "L,%b" }, // 0f: 0111 0100 0000 1111 xxxx xxxx - - {XRI, "V,%b" }, // 10: 0111 0100 0001 0000 xxxx xxxx - {XRI, "A,%b" }, // 11: 0111 0100 0001 0001 xxxx xxxx - {XRI, "B,%b" }, // 12: 0111 0100 0001 0010 xxxx xxxx - {XRI, "C,%b" }, // 13: 0111 0100 0001 0011 xxxx xxxx - {XRI, "D,%b" }, // 14: 0111 0100 0001 0100 xxxx xxxx - {XRI, "E,%b" }, // 15: 0111 0100 0001 0101 xxxx xxxx - {XRI, "H,%b" }, // 16: 0111 0100 0001 0110 xxxx xxxx - {XRI, "L,%b" }, // 17: 0111 0100 0001 0111 xxxx xxxx - {ORI, "V,%b" }, // 18: 0111 0100 0001 1000 xxxx xxxx - {ORI, "A,%b" }, // 19: 0111 0100 0001 1001 xxxx xxxx - {ORI, "B,%b" }, // 1a: 0111 0100 0001 1010 xxxx xxxx - {ORI, "C,%b" }, // 1b: 0111 0100 0001 1011 xxxx xxxx - {ORI, "D,%b" }, // 1c: 0111 0100 0001 1100 xxxx xxxx - {ORI, "E,%b" }, // 1d: 0111 0100 0001 1101 xxxx xxxx - {ORI, "H,%b" }, // 1e: 0111 0100 0001 1110 xxxx xxxx - {ORI, "L,%b" }, // 1f: 0111 0100 0001 1111 xxxx xxxx - - {ADINC, "V,%b" }, // 20: 0111 0100 0010 0000 xxxx xxxx - {ADINC, "A,%b" }, // 21: 0111 0100 0010 0001 xxxx xxxx - {ADINC, "B,%b" }, // 22: 0111 0100 0010 0010 xxxx xxxx - {ADINC, "C,%b" }, // 23: 0111 0100 0010 0011 xxxx xxxx - {ADINC, "D,%b" }, // 24: 0111 0100 0010 0100 xxxx xxxx - {ADINC, "E,%b" }, // 25: 0111 0100 0010 0101 xxxx xxxx - {ADINC, "H,%b" }, // 26: 0111 0100 0010 0110 xxxx xxxx - {ADINC, "L,%b" }, // 27: 0111 0100 0010 0111 xxxx xxxx - {GTI, "V,%b" }, // 28: 0111 0100 0010 1000 xxxx xxxx - {GTI, "A,%b" }, // 29: 0111 0100 0010 1001 xxxx xxxx - {GTI, "B,%b" }, // 2a: 0111 0100 0010 1010 xxxx xxxx - {GTI, "C,%b" }, // 2b: 0111 0100 0010 1011 xxxx xxxx - {GTI, "D,%b" }, // 2c: 0111 0100 0010 1100 xxxx xxxx - {GTI, "E,%b" }, // 2d: 0111 0100 0010 1101 xxxx xxxx - {GTI, "H,%b" }, // 2e: 0111 0100 0010 1110 xxxx xxxx - {GTI, "L,%b" }, // 2f: 0111 0100 0010 1111 xxxx xxxx - - {SUINB, "V,%b" }, // 30: 0111 0100 0011 0000 xxxx xxxx - {SUINB, "A,%b" }, // 31: 0111 0100 0011 0001 xxxx xxxx - {SUINB, "B,%b" }, // 32: 0111 0100 0011 0010 xxxx xxxx - {SUINB, "C,%b" }, // 33: 0111 0100 0011 0011 xxxx xxxx - {SUINB, "D,%b" }, // 34: 0111 0100 0011 0100 xxxx xxxx - {SUINB, "E,%b" }, // 35: 0111 0100 0011 0101 xxxx xxxx - {SUINB, "H,%b" }, // 36: 0111 0100 0011 0110 xxxx xxxx - {SUINB, "L,%b" }, // 37: 0111 0100 0011 0111 xxxx xxxx - {LTI, "V,%b" }, // 37: 0111 0100 0011 1000 xxxx xxxx - {LTI, "A,%b" }, // 39: 0111 0100 0011 1001 xxxx xxxx - {LTI, "B,%b" }, // 3a: 0111 0100 0011 1010 xxxx xxxx - {LTI, "C,%b" }, // 3b: 0111 0100 0011 1011 xxxx xxxx - {LTI, "D,%b" }, // 3c: 0111 0100 0011 1100 xxxx xxxx - {LTI, "E,%b" }, // 3d: 0111 0100 0011 1101 xxxx xxxx - {LTI, "H,%b" }, // 3e: 0111 0100 0011 1110 xxxx xxxx - {LTI, "L,%b" }, // 3f: 0111 0100 0011 1111 xxxx xxxx - - {ADI, "V,%b" }, // 40: 0111 0100 0100 0000 xxxx xxxx - {ADI, "A,%b" }, // 41: 0111 0100 0100 0001 xxxx xxxx - {ADI, "B,%b" }, // 42: 0111 0100 0100 0010 xxxx xxxx - {ADI, "C,%b" }, // 43: 0111 0100 0100 0011 xxxx xxxx - {ADI, "D,%b" }, // 44: 0111 0100 0100 0100 xxxx xxxx - {ADI, "E,%b" }, // 45: 0111 0100 0100 0101 xxxx xxxx - {ADI, "H,%b" }, // 46: 0111 0100 0100 0110 xxxx xxxx - {ADI, "L,%b" }, // 47: 0111 0100 0100 0111 xxxx xxxx - {ONI, "V,%b" }, // 48: 0111 0100 0100 1000 xxxx xxxx - {ONI, "A,%b" }, // 49: 0111 0100 0100 1001 xxxx xxxx - {ONI, "B,%b" }, // 4a: 0111 0100 0100 1010 xxxx xxxx - {ONI, "C,%b" }, // 4b: 0111 0100 0100 1011 xxxx xxxx - {ONI, "D,%b" }, // 4c: 0111 0100 0100 1100 xxxx xxxx - {ONI, "E,%b" }, // 4d: 0111 0100 0100 1101 xxxx xxxx - {ONI, "H,%b" }, // 4e: 0111 0100 0100 1110 xxxx xxxx - {ONI, "L,%b" }, // 4f: 0111 0100 0100 1111 xxxx xxxx - - {ACI, "V,%b" }, // 50: 0111 0100 0101 0000 xxxx xxxx - {ACI, "A,%b" }, // 51: 0111 0100 0101 0001 xxxx xxxx - {ACI, "B,%b" }, // 52: 0111 0100 0101 0010 xxxx xxxx - {ACI, "C,%b" }, // 53: 0111 0100 0101 0011 xxxx xxxx - {ACI, "D,%b" }, // 54: 0111 0100 0101 0100 xxxx xxxx - {ACI, "E,%b" }, // 55: 0111 0100 0101 0101 xxxx xxxx - {ACI, "H,%b" }, // 56: 0111 0100 0101 0110 xxxx xxxx - {ACI, "L,%b" }, // 57: 0111 0100 0101 0111 xxxx xxxx - {OFFI, "V,%b" }, // 58: 0111 0100 0101 1000 xxxx xxxx - {OFFI, "A,%b" }, // 59: 0111 0100 0101 1001 xxxx xxxx - {OFFI, "B,%b" }, // 5a: 0111 0100 0101 1010 xxxx xxxx - {OFFI, "C,%b" }, // 5b: 0111 0100 0101 1011 xxxx xxxx - {OFFI, "D,%b" }, // 5c: 0111 0100 0101 1100 xxxx xxxx - {OFFI, "E,%b" }, // 5d: 0111 0100 0101 1101 xxxx xxxx - {OFFI, "H,%b" }, // 5e: 0111 0100 0101 1110 xxxx xxxx - {OFFI, "L,%b" }, // 5f: 0111 0100 0101 1111 xxxx xxxx - - {SUI, "V,%b" }, // 60: 0111 0100 0110 0000 xxxx xxxx - {SUI, "A,%b" }, // 61: 0111 0100 0110 0001 xxxx xxxx - {SUI, "B,%b" }, // 62: 0111 0100 0110 0010 xxxx xxxx - {SUI, "C,%b" }, // 63: 0111 0100 0110 0011 xxxx xxxx - {SUI, "D,%b" }, // 64: 0111 0100 0110 0100 xxxx xxxx - {SUI, "E,%b" }, // 65: 0111 0100 0110 0101 xxxx xxxx - {SUI, "H,%b" }, // 66: 0111 0100 0110 0110 xxxx xxxx - {SUI, "L,%b" }, // 67: 0111 0100 0110 0111 xxxx xxxx - {NEI, "V,%b" }, // 68: 0111 0100 0110 1000 xxxx xxxx - {NEI, "A,%b" }, // 69: 0111 0100 0110 1001 xxxx xxxx - {NEI, "B,%b" }, // 6a: 0111 0100 0110 1010 xxxx xxxx - {NEI, "C,%b" }, // 6b: 0111 0100 0110 1011 xxxx xxxx - {NEI, "D,%b" }, // 6c: 0111 0100 0110 1100 xxxx xxxx - {NEI, "E,%b" }, // 6d: 0111 0100 0110 1101 xxxx xxxx - {NEI, "H,%b" }, // 6e: 0111 0100 0110 1110 xxxx xxxx - {NEI, "L,%b" }, // 6f: 0111 0100 0110 1111 xxxx xxxx - - {SBI, "V,%b" }, // 70: 0111 0100 0111 0000 xxxx xxxx - {SBI, "A,%b" }, // 71: 0111 0100 0111 0001 xxxx xxxx - {SBI, "B,%b" }, // 72: 0111 0100 0111 0010 xxxx xxxx - {SBI, "C,%b" }, // 73: 0111 0100 0111 0011 xxxx xxxx - {SBI, "D,%b" }, // 74: 0111 0100 0111 0100 xxxx xxxx - {SBI, "E,%b" }, // 75: 0111 0100 0111 0101 xxxx xxxx - {SBI, "H,%b" }, // 76: 0111 0100 0111 0110 xxxx xxxx - {SBI, "L,%b" }, // 77: 0111 0100 0111 0111 xxxx xxxx - {EQI, "V,%b" }, // 78: 0111 0100 0111 1000 xxxx xxxx - {EQI, "A,%b" }, // 79: 0111 0100 0111 1001 xxxx xxxx - {EQI, "B,%b" }, // 7a: 0111 0100 0111 1010 xxxx xxxx - {EQI, "C,%b" }, // 7b: 0111 0100 0111 1011 xxxx xxxx - {EQI, "D,%b" }, // 7c: 0111 0100 0111 1100 xxxx xxxx - {EQI, "E,%b" }, // 7d: 0111 0100 0111 1101 xxxx xxxx - {EQI, "H,%b" }, // 7e: 0111 0100 0111 1110 xxxx xxxx - {EQI, "L,%b" }, // 7f: 0111 0100 0111 1111 xxxx xxxx - - { }, // 80: 0111 0100 1000 0000 - { }, // 81: 0111 0100 1000 0001 - { }, // 82: 0111 0100 1000 0010 - { }, // 83: 0111 0100 1000 0011 - { }, // 84: 0111 0100 1000 0100 - { }, // 85: 0111 0100 1000 0101 - { }, // 86: 0111 0100 1000 0110 - { }, // 87: 0111 0100 1000 0111 - {ANAW, "%a" }, // 88: 0111 0100 1000 1000 oooo oooo - { }, // 89: 0111 0100 1000 1001 - { }, // 8a: 0111 0100 1000 1010 - { }, // 8b: 0111 0100 1000 1011 - { }, // 8c: 0111 0100 1000 1100 - {DAN, "EA,BC" }, // 8d: 0111 0100 1000 1101 - {DAN, "EA,DE" }, // 8e: 0111 0100 1000 1110 - {DAN, "EA,HL" }, // 8f: 0111 0100 1000 1111 - - {XRAW, "%a" }, // 90: 0111 0100 1001 0000 oooo oooo - { }, // 91: 0111 0100 1001 0001 - { }, // 92: 0111 0100 1001 0010 - { }, // 93: 0111 0100 1001 0011 - { }, // 94: 0111 0100 1001 0100 - {DXR, "EA,BC" }, // 95: 0111 0100 1001 0101 - {DXR, "EA,DE" }, // 96: 0111 0100 1001 0110 - {DXR, "EA,HL" }, // 97: 0111 0100 1001 0111 - {ORAW, "%a" }, // 98: 0111 0100 1001 1000 oooo oooo - { }, // 99: 0111 0100 1001 1001 - { }, // 9a: 0111 0100 1001 1010 - { }, // 9b: 0111 0100 1001 1011 - { }, // 9c: 0111 0100 1001 1100 - {DOR, "EA,BC" }, // 9d: 0111 0100 1001 1101 - {DOR, "EA,DE" }, // 9e: 0111 0100 1001 1110 - {DOR, "EA,HL" }, // 9f: 0111 0100 1001 1111 - - {ADDNCW, "%a" }, // a0: 0111 0100 1010 0000 oooo oooo - { }, // a1: 0111 0100 1010 0001 - { }, // a2: 0111 0100 1010 0010 - { }, // a3: 0111 0100 1010 0011 - { }, // a4: 0111 0100 1010 0100 - {DADDNC, "EA,BC" }, // a5: 0111 0100 1010 0101 - {DADDNC, "EA,DE" }, // a6: 0111 0100 1010 0110 - {DADDNC, "EA,HL" }, // a7: 0111 0100 1010 0111 - {GTAW, "%a" }, // a8: 0111 0100 1010 1000 oooo oooo - { }, // a9: 0111 0100 1010 1001 - { }, // aa: 0111 0100 1010 1010 - { }, // ab: 0111 0100 1010 1011 - { }, // ac: 0111 0100 1010 1100 - {DGT, "EA,BC" }, // ad: 0111 0100 1010 1101 - {DGT, "EA,DE" }, // ae: 0111 0100 1010 1110 - {DGT, "EA,HL" }, // af: 0111 0100 1010 1111 - {SUBNBW, "%a" }, // b0: 0111 0100 1011 0000 oooo oooo - { }, // b1: 0111 0100 1011 0001 - { }, // b2: 0111 0100 1011 0010 - { }, // b3: 0111 0100 1011 0011 - { }, // b4: 0111 0100 1011 0100 - {DSUBNB, "EA,BC" }, // b5: 0111 0100 1011 0101 - {DSUBNB, "EA,DE" }, // b6: 0111 0100 1011 0110 - {DSUBNB, "EA,HL" }, // b7: 0111 0100 1011 0111 - {LTAW, "%a" }, // b8: 0111 0100 1011 1000 oooo oooo - { }, // b9: 0111 0100 1011 1001 - { }, // ba: 0111 0100 1011 1010 - { }, // bb: 0111 0100 1011 1011 - { }, // bc: 0111 0100 1011 1100 - {DLT, "EA,BC" }, // bd: 0111 0100 1011 1101 - {DLT, "EA,DE" }, // be: 0111 0100 1011 1110 - {DLT, "EA,HL" }, // bf: 0111 0100 1011 1111 - - {ADDW, "%a" }, // c0: 0111 0100 1100 0000 oooo oooo - { }, // c1: 0111 0100 1100 0001 - { }, // c2: 0111 0100 1100 0010 - { }, // c3: 0111 0100 1100 0011 - { }, // c4: 0111 0100 1100 0100 - {DADD, "EA,BC" }, // c5: 0111 0100 1100 0101 - {DADD, "EA,DE" }, // c6: 0111 0100 1100 0110 - {DADD, "EA,HL" }, // c7: 0111 0100 1100 0111 - {ONAW, "%a" }, // c8: 0111 0100 1100 1000 oooo oooo - { }, // c9: 0111 0100 1100 1001 - { }, // ca: 0111 0100 1100 1010 - { }, // cb: 0111 0100 1100 1011 - { }, // cc: 0111 0100 1100 1100 - {DON, "EA,BC" }, // cd: 0111 0100 1100 1101 - {DON, "EA,DE" }, // ce: 0111 0100 1100 1110 - {DON, "EA,HL" }, // cf: 0111 0100 1100 1111 - - {ADCW, "%a" }, // d0: 0111 0100 1101 0000 oooo oooo - { }, // d1: 0111 0100 1101 0001 - { }, // d2: 0111 0100 1101 0010 - { }, // d3: 0111 0100 1101 0011 - { }, // d4: 0111 0100 1101 0100 - {DADC, "EA,BC" }, // d5: 0111 0100 1101 0101 - {DADC, "EA,DE" }, // d6: 0111 0100 1101 0110 - {DADC, "EA,HL" }, // d7: 0111 0100 1101 0111 - {OFFAW, "%a" }, // d8: 0111 0100 1101 1000 oooo oooo - { }, // d9: 0111 0100 1101 1001 - { }, // da: 0111 0100 1101 1010 - { }, // db: 0111 0100 1101 1011 - { }, // dc: 0111 0100 1101 1100 - {DOFF, "EA,BC" }, // dd: 0111 0100 1101 1101 - {DOFF, "EA,DE" }, // de: 0111 0100 1101 1110 - {DOFF, "EA,HL" }, // df: 0111 0100 1101 1111 - - {SUBW, "%a" }, // e0: 0111 0100 1110 0000 oooo oooo - { }, // e1: 0111 0100 1110 0001 - { }, // e2: 0111 0100 1110 0010 - { }, // e3: 0111 0100 1110 0011 - { }, // e4: 0111 0100 1110 0100 - {DSUB, "EA,BC" }, // e5: 0111 0100 1110 0101 - {DSUB, "EA,DE" }, // e6: 0111 0100 1110 0110 - {DSUB, "EA,HL" }, // e7: 0111 0100 1110 0111 - {NEAW, "%a" }, // e8: 0111 0100 1110 1000 oooo oooo - { }, // e9: 0111 0100 1110 1001 - { }, // ea: 0111 0100 1110 1010 - { }, // eb: 0111 0100 1110 1011 - { }, // ec: 0111 0100 1110 1100 - {DNE, "EA,BC" }, // ed: 0111 0100 1110 1101 - {DNE, "EA,DE" }, // ee: 0111 0100 1110 1110 - {DNE, "EA,HL" }, // ef: 0111 0100 1110 1111 - - {SBBW, "%a" }, // f0: 0111 0100 1111 0000 oooo oooo - { }, // f1: 0111 0100 1111 0001 - { }, // f2: 0111 0100 1111 0010 - { }, // f3: 0111 0100 1111 0011 - { }, // f4: 0111 0100 1111 0100 - {DSBB, "EA,BC" }, // f5: 0111 0100 1111 0101 - {DSBB, "EA,DE" }, // f6: 0111 0100 1111 0110 - {DSBB, "EA,HL" }, // f7: 0111 0100 1111 0111 - {EQAW, "%a" }, // f8: 0111 0100 1111 1000 oooo oooo - { }, // f9: 0111 0100 1111 1001 - { }, // fa: 0111 0100 1111 1010 - { }, // fb: 0111 0100 1111 1011 - { }, // fc: 0111 0100 1111 1100 - {DEQ, "EA,BC" }, // fd: 0111 0100 1111 1101 - {DEQ, "EA,DE" }, // fe: 0111 0100 1111 1110 - {DEQ, "EA,HL" } // ff: 0111 0100 1111 1111 -}; // main opcodes -const dasm_s dasm_s::XX_7810[256] = +const upd7810_base_disassembler::dasm_s upd7810_disassembler::XX_7810[256] = { {NOP, nullptr }, // 00: 0000 0000 {LDAW, "%a" }, // 01: 0000 0001 oooo oooo @@ -3740,7 +2447,1107 @@ const dasm_s dasm_s::XX_7810[256] = {JR, "%o" } // ff: 11oo oooo }; -const dasm_s dasm_s::XX_7807[256] = +const upd7810_base_disassembler::dasm_s upd7807_disassembler::d48_7807[256] = +{ + { }, // 00: 0100 1000 0000 0000 + {SLRC, "A" }, // 01: 0100 1000 0000 0001 + {SLRC, "B" }, // 02: 0100 1000 0000 0010 + {SLRC, "C" }, // 03: 0100 1000 0000 0011 + { }, // 04: 0100 1000 0000 0100 + {SLLC, "A" }, // 05: 0100 1000 0000 0101 + {SLLC, "B" }, // 06: 0100 1000 0000 0110 + {SLLC, "C" }, // 07: 0100 1000 0000 0111 + {SK, "NV" }, // 08: 0100 1000 0000 1000 + { }, // 09: 0100 1000 0000 1001 + {SK, "CY" }, // 0a: 0100 1000 0000 1010 + {SK, "HC" }, // 0b: 0100 1000 0000 1011 + {SK, "Z" }, // 0c: 0100 1000 0000 1100 + { }, // 0d: 0100 1000 0000 1101 + { }, // 0e: 0100 1000 0000 1110 + { }, // 0f: 0100 1000 0000 1111 + + { }, // 10: 0100 1000 0001 0000 + { }, // 11: 0100 1000 0001 0001 + { }, // 12: 0100 1000 0001 0010 + { }, // 13: 0100 1000 0001 0011 + { }, // 14: 0100 1000 0001 0100 + { }, // 15: 0100 1000 0001 0101 + { }, // 16: 0100 1000 0001 0110 + { }, // 17: 0100 1000 0001 0111 + {SKN, "NV" }, // 18: 0100 1000 0001 1000 + { }, // 19: 0100 1000 0001 1001 + {SKN, "CY" }, // 1a: 0100 1000 0001 1010 + {SKN, "HC" }, // 1b: 0100 1000 0001 1011 + {SKN, "Z" }, // 1c: 0100 1000 0001 1100 + { }, // 1d: 0100 1000 0001 1101 + { }, // 1e: 0100 1000 0001 1110 + { }, // 1f: 0100 1000 0001 1111 + + { }, // 20: 0100 1000 0010 0000 + {SLR, "A" }, // 21: 0100 1000 0010 0001 + {SLR, "B" }, // 22: 0100 1000 0010 0010 + {SLR, "C" }, // 23: 0100 1000 0010 0011 + { }, // 24: 0100 1000 0010 0100 + {SLL, "A" }, // 25: 0100 1000 0010 0101 + {SLL, "B" }, // 26: 0100 1000 0010 0110 + {SLL, "C" }, // 27: 0100 1000 0010 0111 + {JEA, nullptr }, // 28: 0100 1000 0010 1000 + {CALB, nullptr }, // 29: 0100 1000 0010 1001 + {CLC, nullptr }, // 2a: 0100 1000 0010 1010 + {STC, nullptr }, // 2b: 0100 1000 0010 1011 + { }, // 2c: 0100 1000 0010 1100 + {MUL, "A" }, // 2d: 0100 1000 0010 1101 + {MUL, "B" }, // 2e: 0100 1000 0010 1110 + {MUL, "C" }, // 2f: 0100 1000 0010 1111 + + { }, // 30: 0100 1000 0011 0000 + {RLR, "A" }, // 31: 0100 1000 0011 0001 + {RLR, "B" }, // 32: 0100 1000 0011 0010 + {RLR, "C" }, // 33: 0100 1000 0011 0011 + { }, // 34: 0100 1000 0011 0100 + {RLL, "A" }, // 35: 0100 1000 0011 0101 + {RLL, "B" }, // 36: 0100 1000 0011 0110 + {RLL, "C" }, // 37: 0100 1000 0011 0111 + {RLD, nullptr }, // 38: 0100 1000 0011 1000 + {RRD, nullptr }, // 39: 0100 1000 0011 1001 + {NEGA, nullptr }, // 3a: 0100 1000 0011 1010 + {HALT, nullptr }, // 3b: 0100 1000 0011 1011 + { }, // 3c: 0100 1000 0011 1100 + {DIV, "A" }, // 3d: 0100 1000 0011 1101 + {DIV, "B" }, // 3e: 0100 1000 0011 1110 + {DIV, "C" }, // 3f: 0100 1000 0011 1111 + + {SKIT, "NMI" }, // 40: 0100 1000 0100 0000 + {SKIT, "FT0" }, // 41: 0100 1000 0100 0001 + {SKIT, "FT1" }, // 42: 0100 1000 0100 0010 + {SKIT, "F1" }, // 43: 0100 1000 0100 0011 + {SKIT, "F2" }, // 44: 0100 1000 0100 0100 + {SKIT, "FE0" }, // 45: 0100 1000 0100 0101 + {SKIT, "FE1" }, // 46: 0100 1000 0100 0110 + {SKIT, "FEIN" }, // 47: 0100 1000 0100 0111 + {SKIT, "FAD" }, // 48: 0100 1000 0100 1000 + {SKIT, "FSR" }, // 49: 0100 1000 0100 1001 + {SKIT, "FST" }, // 4a: 0100 1000 0100 1010 + {SKIT, "ER" }, // 4b: 0100 1000 0100 1011 + {SKIT, "OV" }, // 4c: 0100 1000 0100 1100 + { }, // 4d: 0100 1000 0100 1101 + { }, // 4e: 0100 1000 0100 1110 + { }, // 4f: 0100 1000 0100 1111 + + {SKIT, "AN4" }, // 50: 0100 1000 0101 0000 + {SKIT, "AN5" }, // 51: 0100 1000 0101 0001 + {SKIT, "AN6" }, // 52: 0100 1000 0101 0010 + {SKIT, "AN7" }, // 53: 0100 1000 0101 0011 + {SKIT, "SB" }, // 54: 0100 1000 0101 0100 + { }, // 55: 0100 1000 0101 0101 + { }, // 56: 0100 1000 0101 0110 + { }, // 57: 0100 1000 0101 0111 + { }, // 58: 0100 1000 0101 1000 + { }, // 59: 0100 1000 0101 1001 + { }, // 5a: 0100 1000 0101 1010 + { }, // 5b: 0100 1000 0101 1011 + { }, // 5c: 0100 1000 0101 1100 + { }, // 5d: 0100 1000 0101 1101 + { }, // 5e: 0100 1000 0101 1110 + { }, // 5f: 0100 1000 0101 1111 + + {SKNIT, "NMI" }, // 60: 0100 1000 0110 0000 + {SKNIT, "FT0" }, // 61: 0100 1000 0110 0001 + {SKNIT, "FT1" }, // 62: 0100 1000 0110 0010 + {SKNIT, "F1" }, // 63: 0100 1000 0110 0011 + {SKNIT, "F2" }, // 64: 0100 1000 0110 0100 + {SKNIT, "FE0" }, // 65: 0100 1000 0110 0101 + {SKNIT, "FE1" }, // 66: 0100 1000 0110 0110 + {SKNIT, "FEIN" }, // 67: 0100 1000 0110 0111 + {SKNIT, "FAD" }, // 68: 0100 1000 0110 1000 + {SKNIT, "FSR" }, // 69: 0100 1000 0110 1001 + {SKNIT, "FST" }, // 6a: 0100 1000 0110 1010 + {SKNIT, "ER" }, // 6b: 0100 1000 0110 1011 + {SKNIT, "OV" }, // 6c: 0100 1000 0110 1100 + { }, // 6d: 0100 1000 0110 1101 + { }, // 6e: 0100 1000 0110 1110 + { }, // 6f: 0100 1000 0110 1111 + + {SKNIT, "AN4" }, // 70: 0100 1000 0111 0000 + {SKNIT, "AN5" }, // 71: 0100 1000 0111 0001 + {SKNIT, "AN6" }, // 72: 0100 1000 0111 0010 + {SKNIT, "AN7" }, // 73: 0100 1000 0111 0011 + {SKNIT, "SB" }, // 74: 0100 1000 0111 0100 + { }, // 75: 0100 1000 0111 0101 + { }, // 76: 0100 1000 0111 0110 + { }, // 77: 0100 1000 0111 0111 + { }, // 78: 0100 1000 0111 1000 + { }, // 79: 0100 1000 0111 1001 + { }, // 7a: 0100 1000 0111 1010 + { }, // 7b: 0100 1000 0111 1011 + { }, // 7c: 0100 1000 0111 1100 + { }, // 7d: 0100 1000 0111 1101 + { }, // 7e: 0100 1000 0111 1110 + { }, // 7f: 0100 1000 0111 1111 + + { }, // 80: 0100 1000 1000 0000 + { }, // 81: 0100 1000 1000 0001 + {LDEAX, "(DE)" }, // 82: 0100 1000 1000 0010 + {LDEAX, "(HL)" }, // 83: 0100 1000 1000 0011 + {LDEAX, "(DE++)" }, // 84: 0100 1000 1000 0100 + {LDEAX, "(HL++)" }, // 85: 0100 1000 1000 0101 + { }, // 86: 0100 1000 1000 0110 + { }, // 87: 0100 1000 1000 0111 + { }, // 88: 0100 1000 1000 1000 + { }, // 89: 0100 1000 1000 1001 + { }, // 8a: 0100 1000 1000 1010 + {LDEAX, "(DE+%b)" }, // 8b: 0100 1000 1000 1011 xxxx xxxx + {LDEAX, "(HL+A)" }, // 8c: 0100 1000 1000 1100 + {LDEAX, "(HL+B)" }, // 8d: 0100 1000 1000 1101 + {LDEAX, "(HL+EA)" }, // 8e: 0100 1000 1000 1110 + {LDEAX, "(HL+%b)" }, // 8f: 0100 1000 1000 1111 xxxx xxxx + + { }, // 90: 0100 1000 1000 0000 + { }, // 91: 0100 1000 1000 0001 + {STEAX, "(DE)" }, // 92: 0100 1000 1000 0010 + {STEAX, "(HL)" }, // 93: 0100 1000 1000 0011 + {STEAX, "(DE++)" }, // 94: 0100 1000 1000 0100 + {STEAX, "(HL++)" }, // 95: 0100 1000 1000 0101 + { }, // 96: 0100 1000 1000 0110 + { }, // 97: 0100 1000 1000 0111 + { }, // 98: 0100 1000 1000 1000 + { }, // 99: 0100 1000 1000 1001 + { }, // 9a: 0100 1000 1000 1010 + {STEAX, "(DE+%b)" }, // 9b: 0100 1000 1000 1011 xxxx xxxx + {STEAX, "(HL+A)" }, // 9c: 0100 1000 1000 1100 + {STEAX, "(HL+B)" }, // 9d: 0100 1000 1000 1101 + {STEAX, "(HL+EA)" }, // 9e: 0100 1000 1000 1110 + {STEAX, "(HL+%b)" }, // 9f: 0100 1000 1000 1111 xxxx xxxx + + {DSLR, "EA" }, // a0: 0100 1000 1010 0000 + { }, // a1: 0100 1000 1010 0001 + { }, // a2: 0100 1000 1010 0010 + { }, // a3: 0100 1000 1010 0011 + {DSLL, "EA" }, // a4: 0100 1000 1010 0100 + { }, // a5: 0100 1000 1010 0101 + { }, // a6: 0100 1000 1010 0110 + { }, // a7: 0100 1000 1010 0111 + {TABLE, nullptr }, // a8: 0100 1000 1010 1000 + { }, // a9: 0100 1000 1010 1001 + {CMC, nullptr }, // aa: 0100 1000 1010 1010 7807 + { }, // ab: 0100 1000 1010 1011 + {EXA, nullptr }, // ac: 0100 1000 1010 1100 7807 + {EXR, nullptr }, // ad: 0100 1000 1010 1101 7807 + {EXH, nullptr }, // ae: 0100 1000 1010 1110 7807 + {EXX, nullptr }, // af: 0100 1000 1010 1111 7807 + + {DRLR, "EA" }, // b0: 0100 1000 1011 0000 + { }, // b1: 0100 1000 1011 0001 + { }, // b2: 0100 1000 1011 0010 + { }, // b3: 0100 1000 1011 0011 + {DRLL, "EA" }, // b4: 0100 1000 1011 0100 + { }, // b5: 0100 1000 1011 0101 + { }, // b6: 0100 1000 1011 0110 + { }, // b7: 0100 1000 1011 0111 + { }, // b8: 0100 1000 1011 1000 + { }, // b9: 0100 1000 1011 1001 + { }, // ba: 0100 1000 1011 1010 + { }, // bb: 0100 1000 1011 1011 + { }, // bc: 0100 1000 1011 1100 + { }, // bd: 0100 1000 1011 1101 + { }, // be: 0100 1000 1011 1110 + { }, // bf: 0100 1000 1011 1111 + + {DMOV, "EA,ECNT" }, // c0: 0100 1000 1100 0000 + {DMOV, "EA,ECPT0"}, // c1: 0100 1000 1100 0001 7807 + {DMOV, "EA,ECPT1"}, // c2: 0100 1000 1100 0010 7807 + { }, // c3: 0100 1000 1100 0011 + { }, // c4: 0100 1000 1100 0100 + { }, // c5: 0100 1000 1100 0101 + { }, // c6: 0100 1000 1100 0110 + { }, // c7: 0100 1000 1100 0111 + { }, // c8: 0100 1000 1100 1000 + { }, // c9: 0100 1000 1100 1001 + { }, // ca: 0100 1000 1100 1010 + { }, // cb: 0100 1000 1100 1011 + { }, // cc: 0100 1000 1100 1100 + { }, // cd: 0100 1000 1100 1101 + { }, // ce: 0100 1000 1100 1110 + { }, // cf: 0100 1000 1100 1111 + + { }, // d0: 0100 1000 1101 0000 + { }, // d1: 0100 1000 1101 0001 + {DMOV, "ETM0,EA" }, // d2: 0100 1000 1101 0010 + {DMOV, "ETM1,EA" }, // d3: 0100 1000 1101 0011 + { }, // d4: 0100 1000 1101 0100 + { }, // d5: 0100 1000 1101 0101 + { }, // d6: 0100 1000 1101 0110 + { }, // d7: 0100 1000 1101 0111 + { }, // d8: 0100 1000 1101 1000 + { }, // d9: 0100 1000 1101 1001 + { }, // da: 0100 1000 1101 1010 + { }, // db: 0100 1000 1101 1011 + { }, // dc: 0100 1000 1101 1100 + { }, // dd: 0100 1000 1101 1101 + { }, // de: 0100 1000 1101 1110 + { }, // df: 0100 1000 1101 1111 + + { }, // e0: 0100 1000 1110 0000 + { }, // e1: 0100 1000 1110 0001 + { }, // e2: 0100 1000 1110 0010 + { }, // e3: 0100 1000 1110 0011 + { }, // e4: 0100 1000 1110 0100 + { }, // e5: 0100 1000 1110 0101 + { }, // e6: 0100 1000 1110 0110 + { }, // e7: 0100 1000 1110 0111 + { }, // e8: 0100 1000 1110 1000 + { }, // e9: 0100 1000 1110 1001 + { }, // ea: 0100 1000 1110 1010 + { }, // eb: 0100 1000 1110 1011 + { }, // ec: 0100 1000 1110 1100 + { }, // ed: 0100 1000 1110 1101 + { }, // ee: 0100 1000 1110 1110 + { }, // ef: 0100 1000 1110 1111 + + { }, // f0: 0100 1000 1111 0000 + { }, // f1: 0100 1000 1111 0001 + { }, // f2: 0100 1000 1111 0010 + { }, // f3: 0100 1000 1111 0011 + { }, // f4: 0100 1000 1111 0100 + { }, // f5: 0100 1000 1111 0101 + { }, // f6: 0100 1000 1111 0110 + { }, // f7: 0100 1000 1111 0111 + { }, // f8: 0100 1000 1111 1000 + { }, // f9: 0100 1000 1111 1001 + { }, // fa: 0100 1000 1111 1010 + { }, // fb: 0100 1000 1111 1011 + { }, // fc: 0100 1000 1111 1100 + { }, // fd: 0100 1000 1111 1101 + { }, // fe: 0100 1000 1111 1110 + { } // ff: 0100 1000 1111 1111 +}; + +const upd7810_base_disassembler::dasm_s upd7807_disassembler::d4C_7807[256] = +{ + { }, // 00: 0100 1100 0000 0000 + { }, // 01: 0100 1100 0000 0001 + { }, // 02: 0100 1100 0000 0010 + { }, // 03: 0100 1100 0000 0011 + { }, // 04: 0100 1100 0000 0100 + { }, // 05: 0100 1100 0000 0101 + { }, // 06: 0100 1100 0000 0110 + { }, // 07: 0100 1100 0000 0111 + { }, // 08: 0100 1100 0000 1000 + { }, // 09: 0100 1100 0000 1001 + { }, // 0a: 0100 1100 0000 1010 + { }, // 0b: 0100 1100 0000 1011 + { }, // 0c: 0100 1100 0000 1100 + { }, // 0d: 0100 1100 0000 1101 + { }, // 0e: 0100 1100 0000 1110 + { }, // 0f: 0100 1100 0000 1111 + + { }, // 10: 0100 1100 0001 0000 + { }, // 11: 0100 1100 0001 0001 + { }, // 12: 0100 1100 0001 0010 + { }, // 13: 0100 1100 0001 0011 + { }, // 14: 0100 1100 0001 0100 + { }, // 15: 0100 1100 0001 0101 + { }, // 16: 0100 1100 0001 0110 + { }, // 17: 0100 1100 0001 0111 + { }, // 18: 0100 1100 0001 1000 + { }, // 19: 0100 1100 0001 1001 + { }, // 1a: 0100 1100 0001 1010 + { }, // 1b: 0100 1100 0001 1011 + { }, // 1c: 0100 1100 0001 1100 + { }, // 1d: 0100 1100 0001 1101 + { }, // 1e: 0100 1100 0001 1110 + { }, // 1f: 0100 1100 0001 1111 + + { }, // 20: 0100 1100 0010 0000 + { }, // 21: 0100 1100 0010 0001 + { }, // 22: 0100 1100 0010 0010 + { }, // 23: 0100 1100 0010 0011 + { }, // 24: 0100 1100 0010 0100 + { }, // 25: 0100 1100 0010 0101 + { }, // 26: 0100 1100 0010 0110 + { }, // 27: 0100 1100 0010 0111 + { }, // 28: 0100 1100 0010 1000 + { }, // 29: 0100 1100 0010 1001 + { }, // 2a: 0100 1100 0010 1010 + { }, // 2b: 0100 1100 0010 1011 + { }, // 2c: 0100 1100 0010 1100 + { }, // 2d: 0100 1100 0010 1101 + { }, // 2e: 0100 1100 0010 1110 + { }, // 2f: 0100 1100 0010 1111 + + { }, // 30: 0100 1100 0011 0000 + { }, // 31: 0100 1100 0011 0001 + { }, // 32: 0100 1100 0011 0010 + { }, // 33: 0100 1100 0011 0011 + { }, // 34: 0100 1100 0011 0100 + { }, // 35: 0100 1100 0011 0101 + { }, // 36: 0100 1100 0011 0110 + { }, // 37: 0100 1100 0011 0111 + { }, // 38: 0100 1100 0011 1000 + { }, // 39: 0100 1100 0011 1001 + { }, // 3a: 0100 1100 0011 1010 + { }, // 3b: 0100 1100 0011 1011 + { }, // 3c: 0100 1100 0011 1100 + { }, // 3d: 0100 1100 0011 1101 + { }, // 3e: 0100 1100 0011 1110 + { }, // 3f: 0100 1100 0011 1111 + + { }, // 40: 0100 1100 0100 0000 + { }, // 41: 0100 1100 0100 0001 + { }, // 42: 0100 1100 0100 0010 + { }, // 43: 0100 1100 0100 0011 + { }, // 44: 0100 1100 0100 0100 + { }, // 45: 0100 1100 0100 0101 + { }, // 46: 0100 1100 0100 0110 + { }, // 47: 0100 1100 0100 0111 + { }, // 48: 0100 1100 0100 1000 + { }, // 49: 0100 1100 0100 1001 + { }, // 4a: 0100 1100 0100 1010 + { }, // 4b: 0100 1100 0100 1011 + { }, // 4c: 0100 1100 0100 1100 + { }, // 4d: 0100 1100 0100 1101 + { }, // 4e: 0100 1100 0100 1110 + { }, // 4f: 0100 1100 0100 1111 + + { }, // 50: 0100 1100 0101 0000 + { }, // 51: 0100 1100 0101 0001 + { }, // 52: 0100 1100 0101 0010 + { }, // 53: 0100 1100 0101 0011 + { }, // 54: 0100 1100 0101 0100 + { }, // 55: 0100 1100 0101 0101 + { }, // 56: 0100 1100 0101 0110 + { }, // 57: 0100 1100 0101 0111 + { }, // 58: 0100 1100 0101 1000 + { }, // 59: 0100 1100 0101 1001 + { }, // 5a: 0100 1100 0101 1010 + { }, // 5b: 0100 1100 0101 1011 + { }, // 5c: 0100 1100 0101 1100 + { }, // 5d: 0100 1100 0101 1101 + { }, // 5e: 0100 1100 0101 1110 + { }, // 5f: 0100 1100 0101 1111 + + { }, // 60: 0100 1100 0110 0000 + { }, // 61: 0100 1100 0110 0001 + { }, // 62: 0100 1100 0110 0010 + { }, // 63: 0100 1100 0110 0011 + { }, // 64: 0100 1100 0110 0100 + { }, // 65: 0100 1100 0110 0101 + { }, // 66: 0100 1100 0110 0110 + { }, // 67: 0100 1100 0110 0111 + { }, // 68: 0100 1100 0110 1000 + { }, // 69: 0100 1100 0110 1001 + { }, // 6a: 0100 1100 0110 1010 + { }, // 6b: 0100 1100 0110 1011 + { }, // 6c: 0100 1100 0110 1100 + { }, // 6d: 0100 1100 0110 1101 + { }, // 6e: 0100 1100 0110 1110 + { }, // 6f: 0100 1100 0110 1111 + + { }, // 70: 0100 1100 0111 0000 + { }, // 71: 0100 1100 0111 0001 + { }, // 72: 0100 1100 0111 0010 + { }, // 73: 0100 1100 0111 0011 + { }, // 74: 0100 1100 0111 0100 + { }, // 75: 0100 1100 0111 0101 + { }, // 76: 0100 1100 0111 0110 + { }, // 77: 0100 1100 0111 0111 + { }, // 78: 0100 1100 0111 1000 + { }, // 79: 0100 1100 0111 1001 + { }, // 7a: 0100 1100 0111 1010 + { }, // 7b: 0100 1100 0111 1011 + { }, // 7c: 0100 1100 0111 1100 + { }, // 7d: 0100 1100 0111 1101 + { }, // 7e: 0100 1100 0111 1110 + { }, // 7f: 0100 1100 0111 1111 + + { }, // 80: 0100 1100 1000 0000 + { }, // 81: 0100 1100 1000 0001 + { }, // 82: 0100 1100 1000 0010 + { }, // 83: 0100 1100 1000 0011 + { }, // 84: 0100 1100 1000 0100 + { }, // 85: 0100 1100 1000 0101 + { }, // 86: 0100 1100 1000 0110 + { }, // 87: 0100 1100 1000 0111 + { }, // 88: 0100 1100 1000 1000 + { }, // 89: 0100 1100 1000 1001 + { }, // 8a: 0100 1100 1000 1010 + { }, // 8b: 0100 1100 1000 1011 + { }, // 8c: 0100 1100 1000 1100 + { }, // 8d: 0100 1100 1000 1101 + { }, // 8e: 0100 1100 1000 1110 + { }, // 8f: 0100 1100 1000 1111 + + { }, // 90: 0100 1100 1001 0000 + { }, // 91: 0100 1100 1001 0001 + { }, // 92: 0100 1100 1001 0010 + { }, // 93: 0100 1100 1001 0011 + { }, // 94: 0100 1100 1001 0100 + { }, // 95: 0100 1100 1001 0101 + { }, // 96: 0100 1100 1001 0110 + { }, // 97: 0100 1100 1001 0111 + { }, // 98: 0100 1100 1001 1000 + { }, // 99: 0100 1100 1001 1001 + { }, // 9a: 0100 1100 1001 1010 + { }, // 9b: 0100 1100 1001 1011 + { }, // 9c: 0100 1100 1001 1100 + { }, // 9d: 0100 1100 1001 1101 + { }, // 9e: 0100 1100 1001 1110 + { }, // 9f: 0100 1100 1001 1111 + + { }, // a0: 0100 1100 1010 0000 + { }, // a1: 0100 1100 1010 0001 + { }, // a2: 0100 1100 1010 0010 + { }, // a3: 0100 1100 1010 0011 + { }, // a4: 0100 1100 1010 0100 + { }, // a5: 0100 1100 1010 0101 + { }, // a6: 0100 1100 1010 0110 + { }, // a7: 0100 1100 1010 0111 + { }, // a8: 0100 1100 1010 1000 + { }, // a9: 0100 1100 1010 1001 + { }, // aa: 0100 1100 1010 1010 + { }, // ab: 0100 1100 1010 1011 + { }, // ac: 0100 1100 1010 1100 + { }, // ad: 0100 1100 1010 1101 + { }, // ae: 0100 1100 1010 1110 + { }, // af: 0100 1100 1010 1111 + + { }, // b0: 0100 1100 1011 0000 + { }, // b1: 0100 1100 1011 0001 + { }, // b2: 0100 1100 1011 0010 + { }, // b3: 0100 1100 1011 0011 + { }, // b4: 0100 1100 1011 0100 + { }, // b5: 0100 1100 1011 0101 + { }, // b6: 0100 1100 1011 0110 + { }, // b7: 0100 1100 1011 0111 + { }, // b8: 0100 1100 1011 1000 + { }, // b9: 0100 1100 1011 1001 + { }, // ba: 0100 1100 1011 1010 + { }, // bb: 0100 1100 1011 1011 + { }, // bc: 0100 1100 1011 1100 + { }, // bd: 0100 1100 1011 1101 + { }, // be: 0100 1100 1011 1110 + { }, // bf: 0100 1100 1011 1111 + + {MOV, "A,PA" }, // c0: 0100 1100 1100 0000 + {MOV, "A,PB" }, // c1: 0100 1100 1100 0001 + {MOV, "A,PC" }, // c2: 0100 1100 1100 0010 + {MOV, "A,PD" }, // c3: 0100 1100 1100 0011 + { }, // c4: 0100 1100 1100 0100 + {MOV, "A,PF" }, // c5: 0100 1100 1100 0101 + {MOV, "A,MKH" }, // c6: 0100 1100 1100 0110 + {MOV, "A,MKL" }, // c7: 0100 1100 1100 0111 + { }, // c8: 0100 1100 1100 1000 + {MOV, "A,SMH" }, // c9: 0100 1100 1100 1001 + { }, // ca: 0100 1100 1100 1010 + {MOV, "A,EOM" }, // cb: 0100 1100 1100 1011 + { }, // cc: 0100 1100 1100 1100 + {MOV, "A,TMM" }, // cd: 0100 1100 1100 1101 + {MOV, "A,PT" }, // ce: 0100 1100 1100 1110 7807 + { }, // cf: 0100 1100 1100 1111 + + { }, // d0: 0100 1100 1101 0000 + { }, // d1: 0100 1100 1101 0001 + { }, // d2: 0100 1100 1101 0010 + { }, // d3: 0100 1100 1101 0011 + { }, // d4: 0100 1100 1101 0100 + { }, // d5: 0100 1100 1101 0101 + { }, // d6: 0100 1100 1101 0110 + { }, // d7: 0100 1100 1101 0111 + { }, // d8: 0100 1100 1101 1000 + {MOV, "A,RXB" }, // d9: 0100 1100 1101 1001 + { }, // da: 0100 1100 1101 1010 + { }, // db: 0100 1100 1101 1011 + { }, // dc: 0100 1100 1101 1100 + { }, // dd: 0100 1100 1101 1101 + { }, // de: 0100 1100 1101 1110 + { }, // df: 0100 1100 1101 1111 + + { }, // e0: 0100 1100 1110 0000 + { }, // e1: 0100 1100 1110 0001 + { }, // e2: 0100 1100 1110 0010 + { }, // e3: 0100 1100 1110 0011 + { }, // e4: 0100 1100 1110 0100 + { }, // e5: 0100 1100 1110 0101 + { }, // e6: 0100 1100 1110 0110 + { }, // e7: 0100 1100 1110 0111 + { }, // e8: 0100 1100 1110 1000 + { }, // e9: 0100 1100 1110 1001 + { }, // ea: 0100 1100 1110 1010 + { }, // eb: 0100 1100 1110 1011 + { }, // ec: 0100 1100 1110 1100 + { }, // ed: 0100 1100 1110 1101 + { }, // ee: 0100 1100 1110 1110 + { }, // ef: 0100 1100 1110 1111 + + { }, // f0: 0100 1100 1111 0000 + { }, // f1: 0100 1100 1111 0001 + { }, // f2: 0100 1100 1111 0010 + { }, // f3: 0100 1100 1111 0011 + { }, // f4: 0100 1100 1111 0100 + { }, // f5: 0100 1100 1111 0101 + { }, // f6: 0100 1100 1111 0110 + { }, // f7: 0100 1100 1111 0111 + { }, // f8: 0100 1100 1111 1000 + { }, // f9: 0100 1100 1111 1001 + { }, // fa: 0100 1100 1111 1010 + { }, // fb: 0100 1100 1111 1011 + { }, // fc: 0100 1100 1111 1100 + { }, // fd: 0100 1100 1111 1101 + { }, // fe: 0100 1100 1111 1110 + { } // ff: 0100 1100 1111 1111 +}; + +const upd7810_base_disassembler::dasm_s upd7807_disassembler::d4D_7807[256] = +{ + { }, // 00: 0100 1101 0000 0000 + { }, // 01: 0100 1101 0000 0001 + { }, // 02: 0100 1101 0000 0010 + { }, // 03: 0100 1101 0000 0011 + { }, // 04: 0100 1101 0000 0100 + { }, // 05: 0100 1101 0000 0101 + { }, // 06: 0100 1101 0000 0110 + { }, // 07: 0100 1101 0000 0111 + { }, // 08: 0100 1101 0000 1000 + { }, // 09: 0100 1101 0000 1001 + { }, // 0a: 0100 1101 0000 1010 + { }, // 0b: 0100 1101 0000 1011 + { }, // 0c: 0100 1101 0000 1100 + { }, // 0d: 0100 1101 0000 1101 + { }, // 0e: 0100 1101 0000 1110 + { }, // 0f: 0100 1101 0000 1111 + + { }, // 10: 0100 1101 0001 0000 + { }, // 11: 0100 1101 0001 0001 + { }, // 12: 0100 1101 0001 0010 + { }, // 13: 0100 1101 0001 0011 + { }, // 14: 0100 1101 0001 0100 + { }, // 15: 0100 1101 0001 0101 + { }, // 16: 0100 1101 0001 0110 + { }, // 17: 0100 1101 0001 0111 + { }, // 18: 0100 1101 0001 1000 + { }, // 19: 0100 1101 0001 1001 + { }, // 1a: 0100 1101 0001 1010 + { }, // 1b: 0100 1101 0001 1011 + { }, // 1c: 0100 1101 0001 1100 + { }, // 1d: 0100 1101 0001 1101 + { }, // 1e: 0100 1101 0001 1110 + { }, // 1f: 0100 1101 0001 1111 + + { }, // 20: 0100 1101 0010 0000 + { }, // 21: 0100 1101 0010 0001 + { }, // 22: 0100 1101 0010 0010 + { }, // 23: 0100 1101 0010 0011 + { }, // 24: 0100 1101 0010 0100 + { }, // 25: 0100 1101 0010 0101 + { }, // 26: 0100 1101 0010 0110 + { }, // 27: 0100 1101 0010 0111 + { }, // 28: 0100 1101 0010 1000 + { }, // 29: 0100 1101 0010 1001 + { }, // 2a: 0100 1101 0010 1010 + { }, // 2b: 0100 1101 0010 1011 + { }, // 2c: 0100 1101 0010 1100 + { }, // 2d: 0100 1101 0010 1101 + { }, // 2e: 0100 1101 0010 1110 + { }, // 2f: 0100 1101 0010 1111 + + { }, // 30: 0100 1101 0011 0000 + { }, // 31: 0100 1101 0011 0001 + { }, // 32: 0100 1101 0011 0010 + { }, // 33: 0100 1101 0011 0011 + { }, // 34: 0100 1101 0011 0100 + { }, // 35: 0100 1101 0011 0101 + { }, // 36: 0100 1101 0011 0110 + { }, // 37: 0100 1101 0011 0111 + { }, // 38: 0100 1101 0011 1000 + { }, // 39: 0100 1101 0011 1001 + { }, // 3a: 0100 1101 0011 1010 + { }, // 3b: 0100 1101 0011 1011 + { }, // 3c: 0100 1101 0011 1100 + { }, // 3d: 0100 1101 0011 1101 + { }, // 3e: 0100 1101 0011 1110 + { }, // 3f: 0100 1101 0011 1111 + + { }, // 40: 0100 1101 0100 0000 + { }, // 41: 0100 1101 0100 0001 + { }, // 42: 0100 1101 0100 0010 + { }, // 43: 0100 1101 0100 0011 + { }, // 44: 0100 1101 0100 0100 + { }, // 45: 0100 1101 0100 0101 + { }, // 46: 0100 1101 0100 0110 + { }, // 47: 0100 1101 0100 0111 + { }, // 48: 0100 1101 0100 1000 + { }, // 49: 0100 1101 0100 1001 + { }, // 4a: 0100 1101 0100 1010 + { }, // 4b: 0100 1101 0100 1011 + { }, // 4c: 0100 1101 0100 1100 + { }, // 4d: 0100 1101 0100 1101 + { }, // 4e: 0100 1101 0100 1110 + { }, // 4f: 0100 1101 0100 1111 + + { }, // 50: 0100 1101 0101 0000 + { }, // 51: 0100 1101 0101 0001 + { }, // 52: 0100 1101 0101 0010 + { }, // 53: 0100 1101 0101 0011 + { }, // 54: 0100 1101 0101 0100 + { }, // 55: 0100 1101 0101 0101 + { }, // 56: 0100 1101 0101 0110 + { }, // 57: 0100 1101 0101 0111 + { }, // 58: 0100 1101 0101 1000 + { }, // 59: 0100 1101 0101 1001 + { }, // 5a: 0100 1101 0101 1010 + { }, // 5b: 0100 1101 0101 1011 + { }, // 5c: 0100 1101 0101 1100 + { }, // 5d: 0100 1101 0101 1101 + { }, // 5e: 0100 1101 0101 1110 + { }, // 5f: 0100 1101 0101 1111 + + { }, // 60: 0100 1101 0110 0000 + { }, // 61: 0100 1101 0110 0001 + { }, // 62: 0100 1101 0110 0010 + { }, // 63: 0100 1101 0110 0011 + { }, // 64: 0100 1101 0110 0100 + { }, // 65: 0100 1101 0110 0101 + { }, // 66: 0100 1101 0110 0110 + { }, // 67: 0100 1101 0110 0111 + { }, // 68: 0100 1101 0110 1000 + { }, // 69: 0100 1101 0110 1001 + { }, // 6a: 0100 1101 0110 1010 + { }, // 6b: 0100 1101 0110 1011 + { }, // 6c: 0100 1101 0110 1100 + { }, // 6d: 0100 1101 0110 1101 + { }, // 6e: 0100 1101 0110 1110 + { }, // 6f: 0100 1101 0110 1111 + + { }, // 70: 0100 1101 0111 0000 + { }, // 71: 0100 1101 0111 0001 + { }, // 72: 0100 1101 0111 0010 + { }, // 73: 0100 1101 0111 0011 + { }, // 74: 0100 1101 0111 0100 + { }, // 75: 0100 1101 0111 0101 + { }, // 76: 0100 1101 0111 0110 + { }, // 77: 0100 1101 0111 0111 + { }, // 78: 0100 1101 0111 1000 + { }, // 79: 0100 1101 0111 1001 + { }, // 7a: 0100 1101 0111 1010 + { }, // 7b: 0100 1101 0111 1011 + { }, // 7c: 0100 1101 0111 1100 + { }, // 7d: 0100 1101 0111 1101 + { }, // 7e: 0100 1101 0111 1110 + { }, // 7f: 0100 1101 0111 1111 + + { }, // 80: 0100 1101 1000 0000 + { }, // 81: 0100 1101 1000 0001 + { }, // 82: 0100 1101 1000 0010 + { }, // 83: 0100 1101 1000 0011 + { }, // 84: 0100 1101 1000 0100 + { }, // 85: 0100 1101 1000 0101 + { }, // 86: 0100 1101 1000 0110 + { }, // 87: 0100 1101 1000 0111 + { }, // 88: 0100 1101 1000 1000 + { }, // 89: 0100 1101 1000 1001 + { }, // 8a: 0100 1101 1000 1010 + { }, // 8b: 0100 1101 1000 1011 + { }, // 8c: 0100 1101 1000 1100 + { }, // 8d: 0100 1101 1000 1101 + { }, // 8e: 0100 1101 1000 1110 + { }, // 8f: 0100 1101 1000 1111 + + { }, // 90: 0100 1101 1001 0000 + { }, // 91: 0100 1101 1001 0001 + { }, // 92: 0100 1101 1001 0010 + { }, // 93: 0100 1101 1001 0011 + { }, // 94: 0100 1101 1001 0100 + { }, // 95: 0100 1101 1001 0101 + { }, // 96: 0100 1101 1001 0110 + { }, // 97: 0100 1101 1001 0111 + { }, // 98: 0100 1101 1001 1000 + { }, // 99: 0100 1101 1001 1001 + { }, // 9a: 0100 1101 1001 1010 + { }, // 9b: 0100 1101 1001 1011 + { }, // 9c: 0100 1101 1001 1100 + { }, // 9d: 0100 1101 1001 1101 + { }, // 9e: 0100 1101 1001 1110 + { }, // 9f: 0100 1101 1001 1111 + + { }, // a0: 0100 1101 1010 0000 + { }, // a1: 0100 1101 1010 0001 + { }, // a2: 0100 1101 1010 0010 + { }, // a3: 0100 1101 1010 0011 + { }, // a4: 0100 1101 1010 0100 + { }, // a5: 0100 1101 1010 0101 + { }, // a6: 0100 1101 1010 0110 + { }, // a7: 0100 1101 1010 0111 + { }, // a8: 0100 1101 1010 1000 + { }, // a9: 0100 1101 1010 1001 + { }, // aa: 0100 1101 1010 1010 + { }, // ab: 0100 1101 1010 1011 + { }, // ac: 0100 1101 1010 1100 + { }, // ad: 0100 1101 1010 1101 + { }, // ae: 0100 1101 1010 1110 + { }, // af: 0100 1101 1010 1111 + + { }, // b0: 0100 1101 1011 0000 + { }, // b1: 0100 1101 1011 0001 + { }, // b2: 0100 1101 1011 0010 + { }, // b3: 0100 1101 1011 0011 + { }, // b4: 0100 1101 1011 0100 + { }, // b5: 0100 1101 1011 0101 + { }, // b6: 0100 1101 1011 0110 + { }, // b7: 0100 1101 1011 0111 + { }, // b8: 0100 1101 1011 1000 + { }, // b9: 0100 1101 1011 1001 + { }, // ba: 0100 1101 1011 1010 + { }, // bb: 0100 1101 1011 1011 + { }, // bc: 0100 1101 1011 1100 + { }, // bd: 0100 1101 1011 1101 + { }, // be: 0100 1101 1011 1110 + { }, // bf: 0100 1101 1011 1111 + + {MOV, "PA,A" }, // c0: 0100 1101 1100 0000 + {MOV, "PB,A" }, // c1: 0100 1101 1100 0001 + {MOV, "PC,A" }, // c2: 0100 1101 1100 0010 + {MOV, "PD,A" }, // c3: 0100 1101 1100 0011 + { }, // c4: 0100 1101 1100 0100 + {MOV, "PF,A" }, // c5: 0100 1101 1100 0101 + {MOV, "MKH,A" }, // c6: 0100 1101 1100 0110 + {MOV, "MKL,A" }, // c7: 0100 1101 1100 0111 + { }, // c8: 0100 1101 1100 1000 + {MOV, "SMH,A" }, // c9: 0100 1101 1100 1001 + {MOV, "SML,A" }, // ca: 0100 1101 1100 1010 + {MOV, "EOM,A" }, // cb: 0100 1101 1100 1011 + {MOV, "ETMM,A" }, // cc: 0100 1101 1100 1100 + {MOV, "TMM,A" }, // cd: 0100 1101 1100 1101 + { }, // ce: 0100 1101 1100 1110 + { }, // cf: 0100 1101 1100 1111 + + {MOV, "MM,A" }, // d0: 0100 1101 1101 0000 + {MOV, "MCC,A" }, // d1: 0100 1101 1101 0001 + {MOV, "MA,A" }, // d2: 0100 1101 1101 0010 + {MOV, "MB,A" }, // d3: 0100 1101 1101 0011 + {MOV, "MC,A" }, // d4: 0100 1101 1101 0100 + { }, // d5: 0100 1101 1101 0101 + { }, // d6: 0100 1101 1101 0110 + {MOV, "MF,A" }, // d7: 0100 1101 1101 0111 + {MOV, "TXB,A" }, // d8: 0100 1101 1101 1000 + { }, // d9: 0100 1101 1101 1001 + {MOV, "TM0,A" }, // da: 0100 1101 1101 1010 + {MOV, "TM1,A" }, // db: 0100 1101 1101 1011 + { }, // dc: 0100 1101 1101 1100 + { }, // dd: 0100 1101 1101 1101 + { }, // de: 0100 1101 1101 1110 + { }, // df: 0100 1101 1101 1111 + + { }, // e0: 0100 1101 1110 0000 + { }, // e1: 0100 1101 1110 0001 + { }, // e2: 0100 1101 1110 0010 + { }, // e3: 0100 1101 1110 0011 + { }, // e4: 0100 1101 1110 0100 + {MOV, "MT,A" }, // e5: 0100 1101 1110 0101 7807 + { }, // e6: 0100 1101 1110 0110 + { }, // e7: 0100 1101 1110 0111 + { }, // e8: 0100 1101 1110 1000 + { }, // e9: 0100 1101 1110 1001 + { }, // ea: 0100 1101 1110 1010 + { }, // eb: 0100 1101 1110 1011 + { }, // ec: 0100 1101 1110 1100 + { }, // ed: 0100 1101 1110 1101 + { }, // ee: 0100 1101 1110 1110 + { }, // ef: 0100 1101 1110 1111 + + { }, // f0: 0100 1101 1111 0000 + { }, // f1: 0100 1101 1111 0001 + { }, // f2: 0100 1101 1111 0010 + { }, // f3: 0100 1101 1111 0011 + { }, // f4: 0100 1101 1111 0100 + { }, // f5: 0100 1101 1111 0101 + { }, // f6: 0100 1101 1111 0110 + { }, // f7: 0100 1101 1111 0111 + { }, // f8: 0100 1101 1111 1000 + { }, // f9: 0100 1101 1111 1001 + { }, // fa: 0100 1101 1111 1010 + { }, // fb: 0100 1101 1111 1011 + { }, // fc: 0100 1101 1111 1100 + { }, // fd: 0100 1101 1111 1101 + { }, // fe: 0100 1101 1111 1110 + { } // ff: 0100 1101 1111 1111 +}; + +const upd7810_base_disassembler::dasm_s upd7807_disassembler::d64_7807[256] = +{ + {MVI, "PA,%b" }, // 00: 0110 0100 0000 0000 xxxx xxxx + {MVI, "PB,%b" }, // 01: 0110 0100 0000 0001 xxxx xxxx + {MVI, "PC,%b" }, // 02: 0110 0100 0000 0010 xxxx xxxx + {MVI, "PD,%b" }, // 03: 0110 0100 0000 0011 xxxx xxxx + { }, // 04: 0110 0100 0000 0100 xxxx xxxx + {MVI, "PF,%b" }, // 05: 0110 0100 0000 0101 xxxx xxxx + {MVI, "MKH,%b" }, // 06: 0110 0100 0000 0110 xxxx xxxx + {MVI, "MKL,%b" }, // 07: 0110 0100 0000 0111 xxxx xxxx + {ANI, "PA,%b" }, // 08: 0110 0100 0000 1000 xxxx xxxx + {ANI, "PB,%b" }, // 09: 0110 0100 0000 1001 xxxx xxxx + {ANI, "PC,%b" }, // 0a: 0110 0100 0000 1010 xxxx xxxx + {ANI, "PD,%b" }, // 0b: 0110 0100 0000 1011 xxxx xxxx + { }, // 0c: 0110 0100 0000 1100 xxxx xxxx + {ANI, "PF,%b" }, // 0d: 0110 0100 0000 1101 xxxx xxxx + {ANI, "MKH,%b" }, // 0e: 0110 0100 0000 1110 xxxx xxxx + {ANI, "MKL,%b" }, // 0f: 0110 0100 0000 1111 xxxx xxxx + + {XRI, "PA,%b" }, // 10: 0110 0100 0001 0000 xxxx xxxx + {XRI, "PB,%b" }, // 11: 0110 0100 0001 0001 xxxx xxxx + {XRI, "PC,%b" }, // 12: 0110 0100 0001 0010 xxxx xxxx + {XRI, "PD,%b" }, // 13: 0110 0100 0001 0011 xxxx xxxx + { }, // 14: 0110 0100 0001 0100 xxxx xxxx + {XRI, "PF,%b" }, // 15: 0110 0100 0001 0101 xxxx xxxx + {XRI, "MKH,%b" }, // 16: 0110 0100 0001 0110 xxxx xxxx + {XRI, "MKL,%b" }, // 17: 0110 0100 0001 0111 xxxx xxxx + {ORI, "PA,%b" }, // 18: 0110 0100 0001 1000 xxxx xxxx + {ORI, "PB,%b" }, // 19: 0110 0100 0001 1001 xxxx xxxx + {ORI, "PC,%b" }, // 1a: 0110 0100 0001 1010 xxxx xxxx + {ORI, "PD,%b" }, // 1b: 0110 0100 0001 1011 xxxx xxxx + { }, // 1c: 0110 0100 0001 1100 xxxx xxxx + {ORI, "PF,%b" }, // 1d: 0110 0100 0001 1101 xxxx xxxx + {ORI, "MKH,%b" }, // 1e: 0110 0100 0001 1110 xxxx xxxx + {ORI, "MKL,%b" }, // 1f: 0110 0100 0001 1111 xxxx xxxx + + {ADINC, "PA,%b" }, // 20: 0110 0100 0010 0000 xxxx xxxx + {ADINC, "PB,%b" }, // 21: 0110 0100 0010 0001 xxxx xxxx + {ADINC, "PC,%b" }, // 22: 0110 0100 0010 0010 xxxx xxxx + {ADINC, "PD,%b" }, // 23: 0110 0100 0010 0011 xxxx xxxx + { }, // 24: 0110 0100 0010 0100 xxxx xxxx + {ADINC, "PF,%b" }, // 25: 0110 0100 0010 0101 xxxx xxxx + {ADINC, "MKH,%b" }, // 26: 0110 0100 0010 0110 xxxx xxxx + {ADINC, "MKL,%b" }, // 27: 0110 0100 0010 0111 xxxx xxxx + {GTI, "PA,%b" }, // 28: 0110 0100 0010 1000 xxxx xxxx + {GTI, "PB,%b" }, // 29: 0110 0100 0010 1001 xxxx xxxx + {GTI, "PC,%b" }, // 2a: 0110 0100 0010 1010 xxxx xxxx + {GTI, "PD,%b" }, // 2b: 0110 0100 0010 1011 xxxx xxxx + { }, // 2c: 0110 0100 0010 1100 xxxx xxxx + {GTI, "PF,%b" }, // 2d: 0110 0100 0010 1101 xxxx xxxx + {GTI, "MKH,%b" }, // 2e: 0110 0100 0010 1110 xxxx xxxx + {GTI, "MKL,%b" }, // 2f: 0110 0100 0010 1111 xxxx xxxx + + {SUINB, "PA,%b" }, // 30: 0110 0100 0011 0000 xxxx xxxx + {SUINB, "PB,%b" }, // 31: 0110 0100 0011 0001 xxxx xxxx + {SUINB, "PC,%b" }, // 32: 0110 0100 0011 0010 xxxx xxxx + {SUINB, "PD,%b" }, // 33: 0110 0100 0011 0011 xxxx xxxx + { }, // 34: 0110 0100 0011 0100 xxxx xxxx + {SUINB, "PF,%b" }, // 35: 0110 0100 0011 0101 xxxx xxxx + {SUINB, "MKH,%b" }, // 36: 0110 0100 0011 0110 xxxx xxxx + {SUINB, "MKL,%b" }, // 37: 0110 0100 0011 0111 xxxx xxxx + {LTI, "PA,%b" }, // 38: 0110 0100 0011 1000 xxxx xxxx + {LTI, "PB,%b" }, // 39: 0110 0100 0011 1001 xxxx xxxx + {LTI, "PC,%b" }, // 3a: 0110 0100 0011 1010 xxxx xxxx + {LTI, "PD,%b" }, // 3b: 0110 0100 0011 1011 xxxx xxxx + { }, // 3c: 0110 0100 0011 1100 xxxx xxxx + {LTI, "PF,%b" }, // 3d: 0110 0100 0011 1101 xxxx xxxx + {LTI, "MKH,%b" }, // 3e: 0110 0100 0011 1110 xxxx xxxx + {LTI, "MKL,%b" }, // 3f: 0110 0100 0011 1111 xxxx xxxx + + {ADI, "PA,%b" }, // 40: 0110 0100 0100 0000 xxxx xxxx + {ADI, "PB,%b" }, // 41: 0110 0100 0100 0001 xxxx xxxx + {ADI, "PC,%b" }, // 42: 0110 0100 0100 0010 xxxx xxxx + {ADI, "PD,%b" }, // 43: 0110 0100 0100 0011 xxxx xxxx + { }, // 44: 0110 0100 0100 0100 xxxx xxxx + {ADI, "PF,%b" }, // 45: 0110 0100 0100 0101 xxxx xxxx + {ADI, "MKH,%b" }, // 46: 0110 0100 0100 0110 xxxx xxxx + {ADI, "MKL,%b" }, // 47: 0110 0100 0100 0111 xxxx xxxx + {ONI, "PA,%b" }, // 48: 0110 0100 0100 1000 xxxx xxxx + {ONI, "PB,%b" }, // 49: 0110 0100 0100 1001 xxxx xxxx + {ONI, "PC,%b" }, // 4a: 0110 0100 0100 1010 xxxx xxxx + {ONI, "PD,%b" }, // 4b: 0110 0100 0100 1011 xxxx xxxx + { }, // 4c: 0110 0100 0100 1100 xxxx xxxx + {ONI, "PF,%b" }, // 4d: 0110 0100 0100 1101 xxxx xxxx + {ONI, "MKH,%b" }, // 4e: 0110 0100 0100 1110 xxxx xxxx + {ONI, "MKL,%b" }, // 4f: 0110 0100 0100 1111 xxxx xxxx + + {ACI, "PA,%b" }, // 50: 0110 0100 0101 0000 xxxx xxxx + {ACI, "PB,%b" }, // 51: 0110 0100 0101 0001 xxxx xxxx + {ACI, "PC,%b" }, // 52: 0110 0100 0101 0010 xxxx xxxx + {ACI, "PD,%b" }, // 53: 0110 0100 0101 0011 xxxx xxxx + { }, // 54: 0110 0100 0101 0100 xxxx xxxx + {ACI, "PF,%b" }, // 55: 0110 0100 0101 0101 xxxx xxxx + {ACI, "MKH,%b" }, // 56: 0110 0100 0101 0110 xxxx xxxx + {ACI, "MKL,%b" }, // 57: 0110 0100 0101 0111 xxxx xxxx + {OFFI, "PA,%b" }, // 58: 0110 0100 0101 1000 xxxx xxxx + {OFFI, "PB,%b" }, // 59: 0110 0100 0101 1001 xxxx xxxx + {OFFI, "PC,%b" }, // 5a: 0110 0100 0101 1010 xxxx xxxx + {OFFI, "PD,%b" }, // 5b: 0110 0100 0101 1011 xxxx xxxx + { }, // 5c: 0110 0100 0101 1100 xxxx xxxx + {OFFI, "PF,%b" }, // 5d: 0110 0100 0101 1101 xxxx xxxx + {OFFI, "MKH,%b" }, // 5e: 0110 0100 0101 1110 xxxx xxxx + {OFFI, "MKL,%b" }, // 5f: 0110 0100 0101 1111 xxxx xxxx + + {SUI, "PA,%b" }, // 60: 0110 0100 0110 0000 xxxx xxxx + {SUI, "PB,%b" }, // 61: 0110 0100 0110 0001 xxxx xxxx + {SUI, "PC,%b" }, // 62: 0110 0100 0110 0010 xxxx xxxx + {SUI, "PD,%b" }, // 63: 0110 0100 0110 0011 xxxx xxxx + { }, // 64: 0110 0100 0110 0100 xxxx xxxx + {SUI, "PF,%b" }, // 65: 0110 0100 0110 0101 xxxx xxxx + {SUI, "MKH,%b" }, // 66: 0110 0100 0110 0110 xxxx xxxx + {SUI, "MKL,%b" }, // 67: 0110 0100 0110 0111 xxxx xxxx + {NEI, "PA,%b" }, // 68: 0110 0100 0110 1000 xxxx xxxx + {NEI, "PB,%b" }, // 69: 0110 0100 0110 1001 xxxx xxxx + {NEI, "PC,%b" }, // 6a: 0110 0100 0110 1010 xxxx xxxx + {NEI, "PD,%b" }, // 6b: 0110 0100 0110 1011 xxxx xxxx + { }, // 6c: 0110 0100 0110 1100 xxxx xxxx + {NEI, "PF,%b" }, // 6d: 0110 0100 0110 1101 xxxx xxxx + {NEI, "MKH,%b" }, // 6e: 0110 0100 0110 1110 xxxx xxxx + {NEI, "MKL,%b" }, // 6f: 0110 0100 0110 1111 xxxx xxxx + + {SBI, "PA,%b" }, // 70: 0110 0100 0111 0000 xxxx xxxx + {SBI, "PB,%b" }, // 71: 0110 0100 0111 0001 xxxx xxxx + {SBI, "PC,%b" }, // 72: 0110 0100 0111 0010 xxxx xxxx + {SBI, "PD,%b" }, // 73: 0110 0100 0111 0011 xxxx xxxx + { }, // 74: 0110 0100 0111 0100 xxxx xxxx + {SBI, "PF,%b" }, // 75: 0110 0100 0111 0101 xxxx xxxx + {SBI, "MKH,%b" }, // 76: 0110 0100 0111 0110 xxxx xxxx + {SBI, "MKL,%b" }, // 77: 0110 0100 0111 0111 xxxx xxxx + {EQI, "PA,%b" }, // 78: 0110 0100 0111 1000 xxxx xxxx + {EQI, "PB,%b" }, // 79: 0110 0100 0111 1001 xxxx xxxx + {EQI, "PC,%b" }, // 7a: 0110 0100 0111 1010 xxxx xxxx + {EQI, "PD,%b" }, // 7b: 0110 0100 0111 1011 xxxx xxxx + { }, // 7c: 0110 0100 0111 1100 xxxx xxxx + {EQI, "PF,%b" }, // 7d: 0110 0100 0111 1101 xxxx xxxx + {EQI, "MKH,%b" }, // 7e: 0110 0100 0111 1110 xxxx xxxx + {EQI, "MKL,%b" }, // 7f: 0110 0100 0111 1111 xxxx xxxx + + { }, // 80: 0110 0100 1000 0000 xxxx xxxx + {MVI, "SMH,%b" }, // 81: 0110 0100 1000 0001 xxxx xxxx + { }, // 82: 0110 0100 1000 0010 xxxx xxxx + {MVI, "EOM,%b" }, // 83: 0110 0100 1000 0011 xxxx xxxx + { }, // 84: 0110 0100 1000 0100 xxxx xxxx + {MVI, "TMM,%b" }, // 85: 0110 0100 1000 0101 xxxx xxxx + { }, // 86: 0110 0100 1000 0110 xxxx xxxx + { }, // 87: 0110 0100 1000 0111 xxxx xxxx + { }, // 88: 0110 0100 1000 1000 xxxx xxxx + {ANI, "SMH,%b" }, // 89: 0110 0100 1000 1001 xxxx xxxx + { }, // 8a: 0110 0100 1000 1010 xxxx xxxx + {ANI, "EOM,%b" }, // 8b: 0110 0100 1000 1011 xxxx xxxx + { }, // 8c: 0110 0100 1000 1100 xxxx xxxx + {ANI, "TMM,%b" }, // 8d: 0110 0100 1000 1101 xxxx xxxx + { }, // 8e: 0110 0100 1000 1110 xxxx xxxx + { }, // 8f: 0110 0100 1000 1111 xxxx xxxx + + { }, // 90: 0110 0100 1001 0000 xxxx xxxx + {XRI, "SMH,%b" }, // 91: 0110 0100 1001 0001 xxxx xxxx + { }, // 92: 0110 0100 1001 0010 xxxx xxxx + {XRI, "EOM,%b" }, // 93: 0110 0100 1001 0011 xxxx xxxx + { }, // 94: 0110 0100 1001 0100 xxxx xxxx + {XRI, "TMM,%b" }, // 95: 0110 0100 1001 0101 xxxx xxxx + { }, // 96: 0110 0100 1001 0110 xxxx xxxx + { }, // 97: 0110 0100 1001 0111 xxxx xxxx + { }, // 98: 0110 0100 1001 1000 xxxx xxxx + {ORI, "SMH,%b" }, // 99: 0110 0100 1001 1001 xxxx xxxx + { }, // 9a: 0110 0100 1001 1010 xxxx xxxx + {ORI, "EOM,%b" }, // 9b: 0110 0100 1001 1011 xxxx xxxx + { }, // 9c: 0110 0100 1001 1100 xxxx xxxx + {ORI, "TMM,%b" }, // 9d: 0110 0100 1001 1101 xxxx xxxx + { }, // 9e: 0110 0100 1001 1110 xxxx xxxx + { }, // 9f: 0110 0100 1001 1111 xxxx xxxx + + { }, // a0: 0110 0100 1010 0000 xxxx xxxx + {ADINC, "SMH,%b" }, // a1: 0110 0100 1010 0001 xxxx xxxx + { }, // a2: 0110 0100 1010 0010 xxxx xxxx + {ADINC, "EOM,%b" }, // a3: 0110 0100 1010 0011 xxxx xxxx + { }, // a4: 0110 0100 1010 0100 xxxx xxxx + {ADINC, "TMM,%b" }, // a5: 0110 0100 1010 0101 xxxx xxxx + { }, // a6: 0110 0100 1010 0110 xxxx xxxx + { }, // a7: 0110 0100 1010 0111 xxxx xxxx + { }, // a8: 0110 0100 1010 1000 xxxx xxxx + {GTI, "SMH,%b" }, // a9: 0110 0100 1010 1001 xxxx xxxx + { }, // aa: 0110 0100 1010 1010 xxxx xxxx + {GTI, "EOM,%b" }, // ab: 0110 0100 1010 1011 xxxx xxxx + { }, // ac: 0110 0100 1010 1100 xxxx xxxx + {GTI, "TMM,%b" }, // ad: 0110 0100 1010 1101 xxxx xxxx + {GTI, "PT,%b" }, // ae: 0110 0100 1010 1110 xxxx xxxx + { }, // af: 0110 0100 1010 1111 xxxx xxxx + + { }, // b0: 0110 0100 1011 0000 xxxx xxxx + {SUINB, "SMH,%b" }, // b1: 0110 0100 1011 0001 xxxx xxxx + { }, // b2: 0110 0100 1011 0010 xxxx xxxx + {SUINB, "EOM,%b" }, // b3: 0110 0100 1011 0011 xxxx xxxx + { }, // b4: 0110 0100 1011 0100 xxxx xxxx + {SUINB, "TMM,%b" }, // b5: 0110 0100 1011 0101 xxxx xxxx + { }, // b6: 0110 0100 1011 0110 xxxx xxxx + { }, // b7: 0110 0100 1011 0111 xxxx xxxx + { }, // b8: 0110 0100 1011 1000 xxxx xxxx + {LTI, "SMH,%b" }, // b9: 0110 0100 1011 1001 xxxx xxxx + { }, // ba: 0110 0100 1011 1010 xxxx xxxx + {LTI, "EOM,%b" }, // bb: 0110 0100 1011 1011 xxxx xxxx + { }, // bc: 0110 0100 1011 1100 xxxx xxxx + {LTI, "TMM,%b" }, // bd: 0110 0100 1011 1101 xxxx xxxx + {LTI, "PT,%b" }, // be: 0110 0100 1011 1110 xxxx xxxx + { }, // bf: 0110 0100 1011 1111 xxxx xxxx + + { }, // c0: 0110 0100 1100 0000 xxxx xxxx + {ADI, "SMH,%b" }, // c1: 0110 0100 1100 0001 xxxx xxxx + { }, // c2: 0110 0100 1100 0010 xxxx xxxx + {ADI, "EOM,%b" }, // c3: 0110 0100 1100 0011 xxxx xxxx + { }, // c4: 0110 0100 1100 0100 xxxx xxxx + {ADI, "TMM,%b" }, // c5: 0110 0100 1100 0101 xxxx xxxx + { }, // c6: 0110 0100 1100 0110 xxxx xxxx + { }, // c7: 0110 0100 1100 0111 xxxx xxxx + { }, // c8: 0110 0100 1100 1000 xxxx xxxx + {ONI, "SMH,%b" }, // c9: 0110 0100 1100 1001 xxxx xxxx + { }, // ca: 0110 0100 1100 1010 xxxx xxxx + {ONI, "EOM,%b" }, // cb: 0110 0100 1100 1011 xxxx xxxx + { }, // cc: 0110 0100 1100 1100 xxxx xxxx + {ONI, "TMM,%b" }, // cd: 0110 0100 1100 1101 xxxx xxxx + {ONI, "PT,%b" }, // ce: 0110 0100 1100 1110 xxxx xxxx + { }, // cf: 0110 0100 1100 1111 xxxx xxxx + + { }, // d0: 0110 0100 1101 0000 xxxx xxxx + {ACI, "SMH,%b" }, // d1: 0110 0100 1101 0001 xxxx xxxx + { }, // d2: 0110 0100 1101 0010 xxxx xxxx + {ACI, "EOM,%b" }, // d3: 0110 0100 1101 0011 xxxx xxxx + { }, // d4: 0110 0100 1101 0100 xxxx xxxx + {ACI, "TMM,%b" }, // d5: 0110 0100 1101 0101 xxxx xxxx + { }, // d6: 0110 0100 1101 0110 xxxx xxxx + { }, // d7: 0110 0100 1101 0111 xxxx xxxx + { }, // d8: 0110 0100 1101 1000 xxxx xxxx + {OFFI, "SMH,%b" }, // d9: 0110 0100 1101 1001 xxxx xxxx + { }, // da: 0110 0100 1101 1010 xxxx xxxx + {OFFI, "EOM,%b" }, // db: 0110 0100 1101 1011 xxxx xxxx + { }, // dc: 0110 0100 1101 1100 xxxx xxxx + {OFFI, "TMM,%b" }, // dd: 0110 0100 1101 1101 xxxx xxxx + {OFFI, "PT,%b" }, // de: 0110 0100 1101 1110 xxxx xxxx + { }, // df: 0110 0100 1101 1111 xxxx xxxx + + { }, // e0: 0110 0100 1110 0000 xxxx xxxx + {SUI, "SMH,%b" }, // e1: 0110 0100 1110 0001 xxxx xxxx + { }, // e2: 0110 0100 1110 0010 xxxx xxxx + {SUI, "EOM,%b" }, // e3: 0110 0100 1110 0011 xxxx xxxx + { }, // e4: 0110 0100 1110 0100 xxxx xxxx + {SUI, "TMM,%b" }, // e5: 0110 0100 1110 0101 xxxx xxxx + { }, // e6: 0110 0100 1110 0110 xxxx xxxx + { }, // e7: 0110 0100 1110 0111 xxxx xxxx + { }, // e8: 0110 0100 1110 1000 xxxx xxxx + {NEI, "SMH,%b" }, // e9: 0110 0100 1110 1001 xxxx xxxx + { }, // ea: 0110 0100 1110 1010 xxxx xxxx + {NEI, "EOM,%b" }, // eb: 0110 0100 1110 1011 xxxx xxxx + { }, // ec: 0110 0100 1110 1100 xxxx xxxx + {NEI, "TMM,%b" }, // ed: 0110 0100 1110 1101 xxxx xxxx + {NEI, "PT,%b" }, // ee: 0110 0100 1110 1110 xxxx xxxx + { }, // ef: 0110 0100 1110 1111 xxxx xxxx + + { }, // f0: 0110 0100 1111 0000 xxxx xxxx + {SBI, "SMH,%b" }, // f1: 0110 0100 1111 0001 xxxx xxxx + { }, // f2: 0110 0100 1111 0010 xxxx xxxx + {SBI, "EOM,%b" }, // f3: 0110 0100 1111 0011 xxxx xxxx + { }, // f4: 0110 0100 1111 0100 xxxx xxxx + {SBI, "TMM,%b" }, // f5: 0110 0100 1111 0101 xxxx xxxx + { }, // f6: 0110 0100 1111 0110 xxxx xxxx + { }, // f7: 0110 0100 1111 0111 xxxx xxxx + { }, // f8: 0110 0100 1111 1000 xxxx xxxx + {EQI, "SMH,%b" }, // f9: 0110 0100 1111 1001 xxxx xxxx + { }, // fa: 0110 0100 1111 1010 xxxx xxxx + {EQI, "EOM,%b" }, // fb: 0110 0100 1111 1011 xxxx xxxx + { }, // fc: 0110 0100 1111 1100 xxxx xxxx + {EQI, "TMM,%b" }, // fd: 0110 0100 1111 1101 xxxx xxxx + {EQI, "PT,%b" }, // fe: 0110 0100 1111 1110 xxxx xxxx + { } // ff: 0110 0100 1111 1111 xxxx xxxx +}; + +const upd7810_base_disassembler::dasm_s upd7807_disassembler::XX_7807[256] = { {NOP, nullptr }, // 00: 0000 0000 {LDAW, "%a" }, // 01: 0000 0001 oooo oooo @@ -4020,7 +3827,7 @@ const dasm_s dasm_s::XX_7807[256] = * *********************************************************/ -const dasm_s dasm_s::d48_7801[256] = { +const upd7810_base_disassembler::dasm_s upd7801_disassembler::d48_7801[256] = { // 0x00 - 0x3F { SKIT, "F0" }, { SKIT, "FT" }, { SKIT, "F1" }, { SKIT, "F2" }, { SKIT, "FS" }, { }, { }, { }, @@ -4106,7 +3913,7 @@ const dasm_s dasm_s::d48_7801[256] = { { }, { }, { }, { } }; -const dasm_s dasm_s::d4C_7801[256] = { +const upd7810_base_disassembler::dasm_s upd7801_disassembler::d4C_7801[256] = { // 0x00 - 0x3F { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, @@ -4192,7 +3999,7 @@ const dasm_s dasm_s::d4C_7801[256] = { { }, { }, { }, { } }; -const dasm_s dasm_s::d4D_7801[256] = { +const upd7810_base_disassembler::dasm_s upd7801_disassembler::d4D_7801[256] = { // 0x00 - 0x3F { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, @@ -4278,7 +4085,7 @@ const dasm_s dasm_s::d4D_7801[256] = { { }, { }, { }, { } }; -const dasm_s dasm_s::d60_7801[256] = { +const upd7810_base_disassembler::dasm_s upd7801_disassembler::d60_7801[256] = { // 0x00 - 0x3F { }, { }, { }, { }, { }, { }, { }, { }, @@ -4364,7 +4171,7 @@ const dasm_s dasm_s::d60_7801[256] = { { EQA, "A,D" }, { EQA, "A,E" }, { EQA, "A,H" }, { EQA, "A,L" } }; -const dasm_s dasm_s::d64_7801[256] = { +const upd7810_base_disassembler::dasm_s upd7801_disassembler::d64_7801[256] = { // 0x00 - 0x3F { }, { }, { }, { }, { }, { }, { }, { }, @@ -4450,7 +4257,7 @@ const dasm_s dasm_s::d64_7801[256] = { { }, { }, { }, { } }; -const dasm_s dasm_s::d70_7801[256] = { +const upd7810_base_disassembler::dasm_s upd7801_disassembler::d70_7801[256] = { // 0x00 - 0x3F { }, { }, { }, { }, { }, { }, { }, { }, @@ -4536,7 +4343,7 @@ const dasm_s dasm_s::d70_7801[256] = { { EQAX, "DE+" }, { EQAX, "HL+" }, { EQAX, "DE-" }, { EQAX, "HL-" }, }; -const dasm_s dasm_s::d74_7801[256] = { +const upd7810_base_disassembler::dasm_s upd7801_disassembler::d74_7801[256] = { // 0x00 - 0x3F { }, { }, { }, { }, { }, { }, { }, { }, @@ -4622,7 +4429,7 @@ const dasm_s dasm_s::d74_7801[256] = { { }, { }, { }, { } }; -const dasm_s dasm_s::XX_7801[256] = { +const upd7810_base_disassembler::dasm_s upd7801_disassembler::XX_7801[256] = { // 0x00 - 0x3F { NOP, nullptr }, { HALT, nullptr }, { INX, "SP" }, { DCX, "SP" }, { LXI, "SP,%w" }, { ANIW, "%a,%b" }, { }, { ANI, "A,%b" }, @@ -4714,7 +4521,7 @@ const dasm_s dasm_s::XX_7801[256] = { * *********************************************************/ -const dasm_s dasm_s::d48_78c05[256] = { +const upd7810_base_disassembler::dasm_s upd78c05_disassembler::d48_78c05[256] = { // 0x00 - 0x3F { SKIT, "F0" }, { SKIT, "FT" }, { SKIT, "F1" }, { }, // TODO: PDF doesn't mention SKIT and SK { SKIT, "FS" }, { }, { }, { }, @@ -4800,7 +4607,7 @@ const dasm_s dasm_s::d48_78c05[256] = { { }, { }, { }, { } }; -const dasm_s dasm_s::d4C_78c05[256] = { +const upd7810_base_disassembler::dasm_s upd78c05_disassembler::d4C_78c05[256] = { // 0x00 - 0x3F { }, { }, { }, { }, { }, { }, { }, { }, @@ -4867,7 +4674,7 @@ const dasm_s dasm_s::d4C_78c05[256] = { // 0xC0 - 0xFF { MOV, "A,PA" }, { MOV, "A,PB" }, { MOV, "A,PC" }, { MOV, "A,MK" }, { MOV, "A,MB" }, { MOV, "A,MC" }, { MOV, "A,TM0" }, { MOV, "A,TM1" }, - { MOV, "A,S" }, { }, { }, { }, // TODO: Figure out what regsiter C9 indicates + { MOV, "A,S" }, { }, { }, { }, // TODO: Figure out what register C9 indicates { }, { }, { }, { }, { }, { }, { }, { }, @@ -4886,7 +4693,7 @@ const dasm_s dasm_s::d4C_78c05[256] = { { }, { }, { }, { } }; -const dasm_s dasm_s::d4D_78c05[256] = { +const upd7810_base_disassembler::dasm_s upd78c05_disassembler::d4D_78c05[256] = { // 0x00 - 0x3F { }, { }, { }, { }, { }, { }, { }, { }, @@ -4972,7 +4779,7 @@ const dasm_s dasm_s::d4D_78c05[256] = { { }, { }, { }, { } }; -const dasm_s dasm_s::d60_78c05[256] = { +const upd7810_base_disassembler::dasm_s upd78c05_disassembler::d60_78c05[256] = { // 0x00 - 0x3F { }, { }, { }, { }, { }, { }, { }, { }, @@ -5058,7 +4865,7 @@ const dasm_s dasm_s::d60_78c05[256] = { { EQA, "A,D" }, { EQA, "A,E" }, { EQA, "A,H" }, { EQA, "A,L" } }; -const dasm_s dasm_s::d64_78c05[256] = { +const upd7810_base_disassembler::dasm_s upd78c05_disassembler::d64_78c05[256] = { // 0x00 - 0x3F { }, { }, { }, { }, { }, { }, { }, { }, @@ -5144,7 +4951,7 @@ const dasm_s dasm_s::d64_78c05[256] = { { }, { }, { }, { } }; -const dasm_s dasm_s::d70_78c05[256] = { +const upd7810_base_disassembler::dasm_s upd78c05_disassembler::d70_78c05[256] = { // 0x00 - 0x3F { }, { }, { }, { }, { }, { }, { }, { }, @@ -5230,7 +5037,7 @@ const dasm_s dasm_s::d70_78c05[256] = { { EQAX, "DE+" }, { EQAX, "HL+" }, { EQAX, "DE-" }, { EQAX, "HL-" }, }; -const dasm_s dasm_s::d74_78c05[256] = { +const upd7810_base_disassembler::dasm_s upd78c05_disassembler::d74_78c05[256] = { // 0x00 - 0x3F { }, { }, { }, { }, { }, { }, { }, { }, @@ -5316,7 +5123,7 @@ const dasm_s dasm_s::d74_78c05[256] = { { }, { }, { }, { }, }; -const dasm_s dasm_s::XX_78c05[256] = { +const upd7810_base_disassembler::dasm_s upd78c05_disassembler::XX_78c05[256] = { // 0x00 - 0x3F { NOP, nullptr }, { HALT, nullptr }, { INX, "SP" }, { DCX, "SP" }, { LXI, "SP,%w" }, { ANIW, "%a,%b" }, { }, { ANI, "A,%b" }, @@ -5404,7 +5211,7 @@ const dasm_s dasm_s::XX_78c05[256] = { // register names for bit manipulation instructions -const char *const regname[32] = +const char *const upd7810_base_disassembler::regname[32] = { "illegal", "illegal", "illegal", "illegal", "illegal", "illegal", "illegal", "illegal", @@ -5416,17 +5223,17 @@ const char *const regname[32] = "illegal", "TMM", "PT", "illegal" }; -offs_t Dasm( std::ostream &stream, offs_t pc, const dasm_s (&dasmXX)[256], const uint8_t *oprom, const uint8_t *opram, bool is_7810 ) +offs_t upd7810_base_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - unsigned idx = 0; - const uint8_t op = oprom[idx++]; - const dasm_s *desc = &dasmXX[op]; + offs_t idx = pc; + const uint8_t op = opcodes.r8(idx++); + const dasm_s *desc = &m_dasmXX[op]; if (desc->is_prefix()) - desc = &desc->prefix_get(oprom[idx++]); + desc = &desc->prefix_get(opcodes.r8(idx++)); util::stream_format(stream, "%-8.8s", desc->name()); - uint32_t flags = desc->is_call() ? DASMFLAG_STEP_OVER : desc->is_return() ? DASMFLAG_STEP_OUT : 0; + uint32_t flags = desc->is_call() ? STEP_OVER : desc->is_return() ? STEP_OUT : 0; uint8_t op2; int offset; uint16_t ea; @@ -5439,28 +5246,28 @@ offs_t Dasm( std::ostream &stream, offs_t pc, const dasm_s (&dasmXX)[256], const switch (*a) { case 'a': /* address V * 256 + offset */ - op2 = opram[idx++]; + op2 = params.r8(idx++); util::stream_format(stream, "VV:%02X", op2); break; case 'b': /* immediate byte */ - util::stream_format(stream, "$%02X", opram[idx++]); + util::stream_format(stream, "$%02X", params.r8(idx++)); break; case 'w': /* immediate word */ - ea = opram[idx++]; - ea += opram[idx++] << 8; + ea = params.r8(idx++); + ea += params.r8(idx++) << 8; util::stream_format(stream, "$%04X", ea); break; case 'd': /* JRE address */ - op2 = oprom[idx++]; + op2 = opcodes.r8(idx++); offset = (op & 1) ? -(256 - op2): + op2; util::stream_format(stream, "$%04X", ( pc + idx + offset ) & 0xFFFF ); break; case 't': /* CALT address */ - ea = 0x80 + 2 * (op & (is_7810 ? 0x1f : 0x3f)); + ea = 0x80 + 2 * (op & (m_is_7810 ? 0x1f : 0x3f)); util::stream_format(stream, "($%04X)", ea); break; case 'f': /* CALF address */ - op2 = oprom[idx++]; + op2 = opcodes.r8(idx++); ea = 0x800 + 0x100 * (op & 0x07) + op2; util::stream_format(stream, "$%04X", ea); break; @@ -5469,7 +5276,7 @@ offs_t Dasm( std::ostream &stream, offs_t pc, const dasm_s (&dasmXX)[256], const util::stream_format(stream, "$%04X", ( pc + idx + offset ) & 0xFFFF ); break; case 'i': /* bit manipulation */ - op2 = oprom[idx++]; + op2 = opcodes.r8(idx++); util::stream_format(stream, "%s,%d", regname[op2 & 0x1f], op2 >> 5); break; default: @@ -5480,27 +5287,30 @@ offs_t Dasm( std::ostream &stream, offs_t pc, const dasm_s (&dasmXX)[256], const stream << *a; } - return idx | flags | DASMFLAG_SUPPORTED; + return (idx - pc) | flags | SUPPORTED; } -} // anonymous namespace +upd7810_base_disassembler::upd7810_base_disassembler(const dasm_s *table, bool is_7810) : m_is_7810(is_7810), m_dasmXX(table) +{ +} + +uint32_t upd7810_base_disassembler::opcode_alignment() const +{ + return 1; +} -CPU_DISASSEMBLE( upd7810 ) +upd7810_disassembler::upd7810_disassembler() : upd7810_base_disassembler(XX_7810, true) { - return Dasm( stream, pc, dasm_s::XX_7810, oprom, opram, true ); } -CPU_DISASSEMBLE( upd7807 ) +upd7807_disassembler::upd7807_disassembler() : upd7810_base_disassembler(XX_7807, true) { - return Dasm( stream, pc, dasm_s::XX_7807, oprom, opram, true ); } -CPU_DISASSEMBLE( upd7801 ) +upd7801_disassembler::upd7801_disassembler() : upd7810_base_disassembler(XX_7801, false) { - return Dasm( stream, pc, dasm_s::XX_7801, oprom, opram, false ); } -CPU_DISASSEMBLE( upd78c05 ) +upd78c05_disassembler::upd78c05_disassembler() : upd7810_base_disassembler(XX_78c05, false) { - return Dasm( stream, pc, dasm_s::XX_78c05, oprom, opram, false ); } diff --git a/src/devices/cpu/upd7810/upd7810_dasm.h b/src/devices/cpu/upd7810/upd7810_dasm.h new file mode 100644 index 00000000000..a367ab24a48 --- /dev/null +++ b/src/devices/cpu/upd7810/upd7810_dasm.h @@ -0,0 +1,291 @@ +// license:BSD-3-Clause +// copyright-holders:Juergen Buchmueller +/***************************************************************************** + * + * Portable uPD7810/11, 7810H/11H, 78C10/C11/C14 disassembler + * + * NS20030112: added 7807. + * + *****************************************************************************/ + +#ifndef MAME_CPU_UPD7810_UPD7810DASM_H +#define MAME_CPU_UPD7810_UPD7810DASM_H + +#pragma once + +class upd7810_base_disassembler : public util::disasm_interface +{ +public: + struct dasm_s { + public: + dasm_s(); + dasm_s(uint8_t t, const char *a); + dasm_s(const dasm_s (&a)[256]); + + const char *name() const; + const char *args() const; + + bool is_prefix() const; + bool is_call() const; + bool is_return() const; + + const dasm_s &prefix_get(uint8_t op) const; + + uint8_t m_token; + const void *m_args; + + static const char *const token_names[]; + }; + + enum + { + prefix = 0, + illegal, + ACI, + ADC, + ADCW, + ADCX, + ADD, + ADDNC, + ADDNCW, + ADDNCX, + ADDW, + ADDX, + ADI, + ADINC, + ANA, + ANAW, + ANAX, + AND, + ANI, + ANIW, + BIT, + BLOCK, + CALB, + CALF, + CALL, + CALT, + CLC, + CLR, /* 7807 */ + CMC, /* 7807 */ + DAA, + DADC, + DADD, + DADDNC, + DAN, + DCR, + DCRW, + DCX, + DEQ, + DGT, + DI, + DIV, + DLT, + DMOV, + DNE, + DOFF, + DON, + DOR, + DRLL, + DRLR, + DSBB, + DSLL, + DSLR, + DSUB, + DSUBNB, + DXR, + EADD, + EI, + EQA, + EQAW, + EQAX, + EQI, + EQIW, + ESUB, + EX, /* 7801 */ + EXA, + EXH, + EXX, + EXR, /* 7807 */ + GTA, + GTAW, + GTAX, + GTI, + GTIW, + HALT, + IN, /* 7801 */ + INR, + INRW, + INX, + JB, + JEA, + JMP, + JR, + JRE, + LBCD, + LDAW, + LDAX, + LDEAX, + LDED, + LHLD, + LSPD, + LTA, + LTAW, + LTAX, + LTI, + LTIW, + LXI, + MOV, + MUL, + MVI, + MVIW, + MVIX, + NEA, + NEAW, + NEAX, + NEGA, + NEI, + NEIW, + NOP, + NOT, /* 7807 */ + OFFA, + OFFAW, + OFFAX, + OFFI, + OFFIW, + ONA, + ONAW, + ONAX, + ONI, + ONIW, + OR, /* 7807 */ + ORA, + ORAW, + ORAX, + ORI, + ORIW, + OUT, /* 7801 */ + PER, /* 7801 */ + PEX, /* 7801 */ + POP, + PUSH, + RET, + RETI, + RETS, + RLD, + RLL, + RLR, + RRD, + SBB, + SBBW, + SBBX, + SBCD, + SBI, + SDED, + SETB, /* 7807 */ + SHLD, + SIO, /* 7801 */ + SK, + SKIT, + SKN, + SKNIT, + SLL, + SLLC, + SLR, + SLRC, + SOFTI, + SSPD, + STAW, + STAX, + STC, + STEAX, + STM, /* 7801 */ + STOP, + SUB, + SUBNB, + SUBNBW, + SUBNBX, + SUBW, + SUBX, + SUI, + SUINB, + TABLE, + XOR, /* 7807 */ + XRA, + XRAW, + XRAX, + XRI + }; + + upd7810_base_disassembler(const dasm_s *table, bool is_7810); + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + + static const char *const regname[32]; + static const dasm_s d60[256]; + static const dasm_s d70[256]; + static const dasm_s d74[256]; + + bool m_is_7810; + const dasm_s *m_dasmXX; +}; + +class upd7810_disassembler : public upd7810_base_disassembler +{ +public: + static const dasm_s XX_7810[256]; + static const dasm_s d48_7810[256]; + static const dasm_s d4C_7810[256]; + static const dasm_s d4D_7810[256]; + static const dasm_s d64_7810[256]; + + upd7810_disassembler(); + virtual ~upd7810_disassembler() = default; +}; + +class upd7807_disassembler : public upd7810_base_disassembler +{ +public: + static const dasm_s XX_7807[256]; + static const dasm_s d48_7807[256]; + static const dasm_s d4C_7807[256]; + static const dasm_s d4D_7807[256]; + static const dasm_s d64_7807[256]; + + upd7807_disassembler(); + virtual ~upd7807_disassembler() = default; +}; + +class upd7801_disassembler : public upd7810_base_disassembler +{ +public: + static const dasm_s XX_7801[256]; + static const dasm_s d48_7801[256]; + static const dasm_s d4C_7801[256]; + static const dasm_s d4D_7801[256]; + static const dasm_s d60_7801[256]; + static const dasm_s d64_7801[256]; + static const dasm_s d70_7801[256]; + static const dasm_s d74_7801[256]; + + upd7801_disassembler(); + virtual ~upd7801_disassembler() = default; +}; + +class upd78c05_disassembler : public upd7810_base_disassembler +{ +public: + static const dasm_s XX_78c05[256]; + static const dasm_s d48_78c05[256]; + static const dasm_s d4C_78c05[256]; + static const dasm_s d4D_78c05[256]; + static const dasm_s d60_78c05[256]; + static const dasm_s d64_78c05[256]; + static const dasm_s d70_78c05[256]; + static const dasm_s d74_78c05[256]; + + upd78c05_disassembler(); + virtual ~upd78c05_disassembler() = default; +}; + +#endif diff --git a/src/devices/cpu/v30mz/v30mz.cpp b/src/devices/cpu/v30mz/v30mz.cpp index 718c07a2ec8..de393ea5f9f 100644 --- a/src/devices/cpu/v30mz/v30mz.cpp +++ b/src/devices/cpu/v30mz/v30mz.cpp @@ -44,6 +44,7 @@ #include "emu.h" #include "v30mz.h" +#include "cpu/nec/necdasm.h" #include "debugger.h" @@ -146,7 +147,7 @@ device_memory_interface::space_config_vector v30mz_cpu_device::memory_space_conf void v30mz_cpu_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); save_item(NAME(m_regs.w)); @@ -1304,10 +1305,9 @@ void v30mz_cpu_device::execute_set_input( int inptnum, int state ) } -offs_t v30mz_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *v30mz_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( nec ); - return CPU_DISASSEMBLE_NAME(nec)(this, stream, pc, oprom, opram, options); + return new nec_disassembler; } diff --git a/src/devices/cpu/v30mz/v30mz.h b/src/devices/cpu/v30mz/v30mz.h index 1b8665fd0ea..7afee5907b0 100644 --- a/src/devices/cpu/v30mz/v30mz.h +++ b/src/devices/cpu/v30mz/v30mz.h @@ -47,9 +47,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 7; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; void interrupt(int int_num); @@ -189,7 +187,7 @@ protected: uint8_t m_fire_trap; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_io; int m_icount; diff --git a/src/devices/cpu/v60/v60.cpp b/src/devices/cpu/v60/v60.cpp index dbe8ed08599..7891f5daa25 100644 --- a/src/devices/cpu/v60/v60.cpp +++ b/src/devices/cpu/v60/v60.cpp @@ -75,6 +75,7 @@ Package: 132-pin PGA, 200-pin QFP #include "emu.h" #include "v60.h" +#include "v60d.h" #include "debugger.h" DEFINE_DEVICE_TYPE(V60, v60_device, "v60", "V60") @@ -115,17 +116,9 @@ device_memory_interface::space_config_vector v60_device::memory_space_config() c } -offs_t v60_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *v60_device::create_disassembler() { - extern CPU_DISASSEMBLE( v60 ); - return CPU_DISASSEMBLE_NAME(v60)(this, stream, pc, oprom, opram, options); -} - - -offs_t v70_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) -{ - extern CPU_DISASSEMBLE( v70 ); - return CPU_DISASSEMBLE_NAME(v70)(this, stream, pc, oprom, opram, options); + return new v60_disassembler; } @@ -428,7 +421,7 @@ void v60_device::device_start() m_moddim = 0; m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); save_item(NAME(m_fetch_xor)); diff --git a/src/devices/cpu/v60/v60.h b/src/devices/cpu/v60/v60.h index b891630f048..727972d7d99 100644 --- a/src/devices/cpu/v60/v60.h +++ b/src/devices/cpu/v60/v60.h @@ -110,9 +110,7 @@ protected: virtual void state_export(const device_state_entry &entry) override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 22; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: typedef uint32_t (v60_device::*am_func)(); @@ -164,7 +162,7 @@ private: uint8_t m_irq_line; uint8_t m_nmi_line; address_space *m_program; - direct_read_data * m_direct; + direct_read_data<0> *m_direct; address_space *m_io; uint32_t m_PPC; int m_icount; @@ -777,9 +775,6 @@ class v70_device : public v60_device public: // construction/destruction v70_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - -protected: - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; }; diff --git a/src/devices/cpu/v60/v60d.cpp b/src/devices/cpu/v60/v60d.cpp index 70fcdab8296..2a14f65436f 100644 --- a/src/devices/cpu/v60/v60d.cpp +++ b/src/devices/cpu/v60/v60d.cpp @@ -2,11 +2,10 @@ // copyright-holders:Farfetch'd, R. Belmont #include "emu.h" -#include "debugger.h" -#include "v60.h" +#include "v60d.h" // Register names -static const char *const v60_reg_names[69] = { +const char *const v60_disassembler::v60_reg_names[69] = { "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10", "R11", @@ -26,39 +25,19 @@ static const char *const v60_reg_names[69] = { "ADTMR1","Reserved","Reserved","Reserved" }; -static const uint8_t *rombase; -static offs_t pcbase; - -#define readop(a) rombase[(a) - pcbase] - -static signed char read8(unsigned pc) -{ - return readop(pc); -} - -static signed short read16(unsigned pc) -{ - return readop(pc) | (readop(pc+1) << 8); -} - -static signed int read32(unsigned pc) -{ - return readop(pc) | (readop(pc+1) << 8)| (readop(pc+2) << 16)| (readop(pc+3) << 24); -} - -static void out_AM_Register(int reg, std::ostream &stream) +void v60_disassembler::out_AM_Register(int reg, std::ostream &stream) { stream << v60_reg_names[reg]; } -static void out_AM_RegisterIndirect(int reg, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_RegisterIndirect(int reg, int opsize, std::ostream &stream) { if(opsize & 0x80) stream << '@'; util::stream_format(stream, "[%s]", v60_reg_names[reg]); } -static void out_AM_RegisterIndirectIndexed(int rn, int rx, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_RegisterIndirectIndexed(int rn, int rx, int opsize, std::ostream &stream) { if(opsize & 0x80) util::stream_format(stream, "%s@[%s]", v60_reg_names[rx], v60_reg_names[rn]); @@ -67,21 +46,21 @@ static void out_AM_RegisterIndirectIndexed(int rn, int rx, int opsize, std::ostr } -static void out_AM_Autoincrement(int reg, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_Autoincrement(int reg, int opsize, std::ostream &stream) { if(opsize & 0x80) stream << '@'; util::stream_format(stream, "[%s+]", v60_reg_names[reg]); } -static void out_AM_Autodecrement(int reg, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_Autodecrement(int reg, int opsize, std::ostream &stream) { if(opsize & 0x80) stream << '@'; util::stream_format(stream, "[-%s]", v60_reg_names[reg]); } -static void out_AM_Displacement(int reg, int disp, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_Displacement(int reg, int disp, int opsize, std::ostream &stream) { util::stream_format(stream, "%s%X%s[%s]", disp >= 0 ? "" : "-", disp >= 0 ? disp : -disp, @@ -89,7 +68,7 @@ static void out_AM_Displacement(int reg, int disp, int opsize, std::ostream &str v60_reg_names[reg]); } -static void out_AM_DisplacementIndexed(int rn, int rx, int disp, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_DisplacementIndexed(int rn, int rx, int disp, int opsize, std::ostream &stream) { if(opsize & 0x80) util::stream_format(stream, "%s@%s%X[%s]", v60_reg_names[rx], disp >= 0 ? "" : "-", disp >= 0 ? disp : -disp,v60_reg_names[rn]); @@ -97,12 +76,12 @@ static void out_AM_DisplacementIndexed(int rn, int rx, int disp, int opsize, std util::stream_format(stream, "%s%X[%s](%s)", disp >= 0 ? "" : "-", disp >= 0 ? disp : -disp,v60_reg_names[rn], v60_reg_names[rx]); } -static void out_AM_PCDisplacement(unsigned pc, int disp, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_PCDisplacement(offs_t pc, int disp, int opsize, std::ostream &stream) { util::stream_format(stream, "%X%s[PC]", pc+disp, opsize & 0x80 ? "@" : ""); } -static void out_AM_PCDisplacementIndexed(unsigned pc, int disp, int rx, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_PCDisplacementIndexed(offs_t pc, int disp, int rx, int opsize, std::ostream &stream) { if(opsize & 0x80) util::stream_format(stream, "%s@%X[PC]", v60_reg_names[rx], pc+disp); @@ -110,7 +89,7 @@ static void out_AM_PCDisplacementIndexed(unsigned pc, int disp, int rx, int opsi util::stream_format(stream, "%X[PC](%s)", pc+disp, v60_reg_names[rx]); } -static void out_AM_DisplacementIndirect(int reg, int disp, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_DisplacementIndirect(int reg, int disp, int opsize, std::ostream &stream) { util::stream_format(stream, "%s[%s%X[%s]]", opsize & 0x80 ? "@" : "", @@ -118,7 +97,7 @@ static void out_AM_DisplacementIndirect(int reg, int disp, int opsize, std::ostr v60_reg_names[reg]); } -static void out_AM_DisplacementIndirectIndexed(int rn, int rx, int disp, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_DisplacementIndirectIndexed(int rn, int rx, int disp, int opsize, std::ostream &stream) { if(opsize & 0x80) util::stream_format(stream, "%s@[%s%X[%s]]", v60_reg_names[rx], disp >= 0 ? "" : "-", disp >= 0 ? disp : -disp,v60_reg_names[rn]); @@ -126,12 +105,12 @@ static void out_AM_DisplacementIndirectIndexed(int rn, int rx, int disp, int ops util::stream_format(stream, "[%s%X[%s]](%s)", disp >= 0 ? "" : "-", disp >= 0 ? disp : -disp,v60_reg_names[rn], v60_reg_names[rx]); } -static void out_AM_PCDisplacementIndirect(unsigned pc, int disp, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_PCDisplacementIndirect(offs_t pc, int disp, int opsize, std::ostream &stream) { util::stream_format(stream, "%s[%X[PC]]", opsize & 0x80 ? "@" : "", pc+disp); } -static void out_AM_PCDisplacementIndirectIndexed(unsigned pc, int disp, int rx, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_PCDisplacementIndirectIndexed(offs_t pc, int disp, int rx, int opsize, std::ostream &stream) { if(opsize & 0x80) util::stream_format(stream, "%s@[%X[PC]]", v60_reg_names[rx], pc+disp); @@ -139,7 +118,7 @@ static void out_AM_PCDisplacementIndirectIndexed(unsigned pc, int disp, int rx, util::stream_format(stream, "[%X[PC]](%s)", pc+disp, v60_reg_names[rx]); } -static void out_AM_DoubleDisplacement(int reg, int disp2, int disp1, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_DoubleDisplacement(int reg, int disp2, int disp1, int opsize, std::ostream &stream) { util::stream_format(stream, "%s%X%s[%s%X[%s]]", disp1 >= 0 ? "" : "-", disp1 >= 0 ? disp1 : -disp1, @@ -148,7 +127,7 @@ static void out_AM_DoubleDisplacement(int reg, int disp2, int disp1, int opsize, v60_reg_names[reg]); } -static void out_AM_PCDoubleDisplacement(unsigned pc, int disp2, int disp1, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_PCDoubleDisplacement(offs_t pc, int disp2, int disp1, int opsize, std::ostream &stream) { util::stream_format(stream, "%s%X%s[%X[PC]]", disp1 >= 0 ? "" : "-", disp1 >= 0 ? disp1 : -disp1, @@ -156,14 +135,14 @@ static void out_AM_PCDoubleDisplacement(unsigned pc, int disp2, int disp1, int o disp2 + pc); } -static void out_AM_DirectAddress(unsigned addr, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_DirectAddress(unsigned addr, int opsize, std::ostream &stream) { if(opsize & 0x80) stream << '@'; util::stream_format(stream, "%X", addr); } -static void out_AM_DirectAddressIndexed(unsigned addr, int rx, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_DirectAddressIndexed(unsigned addr, int rx, int opsize, std::ostream &stream) { if(opsize & 0x80) util::stream_format(stream, "%s@%X", v60_reg_names[rx], addr); @@ -171,14 +150,14 @@ static void out_AM_DirectAddressIndexed(unsigned addr, int rx, int opsize, std:: util::stream_format(stream, "%X(%s)", addr, v60_reg_names[rx]); } -static void out_AM_DirectAddressDeferred(unsigned addr, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_DirectAddressDeferred(unsigned addr, int opsize, std::ostream &stream) { if(opsize & 0x80) stream << '@'; util::stream_format(stream, "[%X]", addr); } -static void out_AM_DirectAddressDeferredIndexed(unsigned addr, int rx, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_DirectAddressDeferredIndexed(unsigned addr, int rx, int opsize, std::ostream &stream) { if(opsize & 0x80) util::stream_format(stream, "%s@[%X]", v60_reg_names[rx], addr); @@ -186,7 +165,7 @@ static void out_AM_DirectAddressDeferredIndexed(unsigned addr, int rx, int opsiz util::stream_format(stream, "[%X](%s)", addr, v60_reg_names[rx]); } -static void out_AM_Immediate(unsigned value, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_Immediate(unsigned value, int opsize, std::ostream &stream) { if(opsize == 0) value &= 0xff; @@ -196,21 +175,21 @@ static void out_AM_Immediate(unsigned value, int opsize, std::ostream &stream) util::stream_format(stream, "#%X", value); } -static int decode_AM(unsigned ipc, unsigned pc, int m, int opsize, std::ostream &stream) +u32 v60_disassembler::decode_AM(unsigned ipc, offs_t pc, int m, int opsize, const data_buffer &opcodes, std::ostream &stream) { - unsigned char mod = readop(pc); + unsigned char mod = opcodes.r8(pc); if(m) { switch(mod>>5) { case 0: // Double displacement (8 bit) - out_AM_DoubleDisplacement(mod&0x1F, read8(pc+1), read8(pc+2), opsize, stream); + out_AM_DoubleDisplacement(mod&0x1F, opcodes.r8(pc+1), opcodes.r8(pc+2), opsize, stream); return 3; case 1: // Double displacement (16 bit) - out_AM_DoubleDisplacement(mod&0x1F, read16(pc+1), read16(pc+3), opsize, stream); + out_AM_DoubleDisplacement(mod&0x1F, opcodes.r16(pc+1), opcodes.r16(pc+3), opsize, stream); return 5; case 2: // Double displacement (32 bit) - out_AM_DoubleDisplacement(mod&0x1F, read32(pc+1), read32(pc+5), opsize, stream); + out_AM_DoubleDisplacement(mod&0x1F, opcodes.r32(pc+1), opcodes.r32(pc+5), opsize, stream); return 9; case 3: // Register @@ -226,69 +205,69 @@ static int decode_AM(unsigned ipc, unsigned pc, int m, int opsize, std::ostream return 1; case 6: - switch (readop(pc+1)>>5) + switch (opcodes.r8(pc+1)>>5) { case 0: // Displacement indexed (8 bit) - out_AM_DisplacementIndexed(readop(pc+1)&0x1F, mod&0x1F, read8(pc+2), opsize, stream); + out_AM_DisplacementIndexed(opcodes.r8(pc+1)&0x1F, mod&0x1F, opcodes.r8(pc+2), opsize, stream); return 3; case 1: // Displacement indexed (16 bit) - out_AM_DisplacementIndexed(readop(pc+1)&0x1F, mod&0x1F, read16(pc+2), opsize, stream); + out_AM_DisplacementIndexed(opcodes.r8(pc+1)&0x1F, mod&0x1F, opcodes.r16(pc+2), opsize, stream); return 4; case 2: // Displacement indexed (32 bit) - out_AM_DisplacementIndexed(readop(pc+1)&0x1F, mod&0x1F, read32(pc+2), opsize, stream); + out_AM_DisplacementIndexed(opcodes.r8(pc+1)&0x1F, mod&0x1F, opcodes.r32(pc+2), opsize, stream); return 6; case 3: // Register indirect indexed - out_AM_RegisterIndirectIndexed(readop(pc+1)&0x1F, mod&0x1F, opsize, stream); + out_AM_RegisterIndirectIndexed(opcodes.r8(pc+1)&0x1F, mod&0x1F, opsize, stream); return 2; case 4: // Displacement indirect indexed (8 bit) - out_AM_DisplacementIndirectIndexed(readop(pc+1)&0x1F, mod&0x1F, read8(pc+2), opsize, stream); + out_AM_DisplacementIndirectIndexed(opcodes.r8(pc+1)&0x1F, mod&0x1F, opcodes.r8(pc+2), opsize, stream); return 3; case 5: // Displacement indirect indexed (16 bit) - out_AM_DisplacementIndirectIndexed(readop(pc+1)&0x1F, mod&0x1F, read16(pc+2), opsize, stream); + out_AM_DisplacementIndirectIndexed(opcodes.r8(pc+1)&0x1F, mod&0x1F, opcodes.r16(pc+2), opsize, stream); return 4; case 6: // Displacement indirect indexed (32 bit) - out_AM_DisplacementIndirectIndexed(readop(pc+1)&0x1F, mod&0x1F, read32(pc+2), opsize, stream); + out_AM_DisplacementIndirectIndexed(opcodes.r8(pc+1)&0x1F, mod&0x1F, opcodes.r32(pc+2), opsize, stream); return 6; case 7: - switch (readop(pc+1)&0x1F) + switch (opcodes.r8(pc+1)&0x1F) { case 16: // PC Displacement Indexed (8 bit) - out_AM_PCDisplacementIndexed(ipc, read8(pc+2), mod&0x1F, opsize, stream); + out_AM_PCDisplacementIndexed(ipc, opcodes.r8(pc+2), mod&0x1F, opsize, stream); return 3; case 17: // PC Displacement Indexed (16 bit) - out_AM_PCDisplacementIndexed(ipc, read16(pc+2), mod&0x1F, opsize, stream); + out_AM_PCDisplacementIndexed(ipc, opcodes.r16(pc+2), mod&0x1F, opsize, stream); return 4; case 18: // PC Displacement Indexed (32 bit) - out_AM_PCDisplacementIndexed(ipc, read32(pc+2), mod&0x1F, opsize, stream); + out_AM_PCDisplacementIndexed(ipc, opcodes.r32(pc+2), mod&0x1F, opsize, stream); return 6; case 19: // Direct Address Indexed - out_AM_DirectAddressIndexed(read32(pc+2), mod&0x1F, opsize, stream); + out_AM_DirectAddressIndexed(opcodes.r32(pc+2), mod&0x1F, opsize, stream); return 6; case 24: // PC Displacement Indirect Indexed(8 bit) - out_AM_PCDisplacementIndirectIndexed(ipc, read8(pc+2), mod&0x1F, opsize, stream); + out_AM_PCDisplacementIndirectIndexed(ipc, opcodes.r8(pc+2), mod&0x1F, opsize, stream); return 3; case 25: // PC Displacement Indirect Indexed (16 bit) - out_AM_PCDisplacementIndirectIndexed(ipc, read16(pc+2), mod&0x1F, opsize, stream); + out_AM_PCDisplacementIndirectIndexed(ipc, opcodes.r16(pc+2), mod&0x1F, opsize, stream); return 4; case 26: // PC Displacement Indirect Indexed (32 bit) - out_AM_PCDisplacementIndirectIndexed(ipc, read32(pc+2), mod&0x1F, opsize, stream); + out_AM_PCDisplacementIndirectIndexed(ipc, opcodes.r32(pc+2), mod&0x1F, opsize, stream); return 6; case 27: // Direct Address Deferred Indexed - out_AM_DirectAddressDeferredIndexed(read32(pc+2), mod&0x1F, opsize, stream); + out_AM_DirectAddressDeferredIndexed(opcodes.r32(pc+2), mod&0x1F, opsize, stream); return 6; default: @@ -308,15 +287,15 @@ static int decode_AM(unsigned ipc, unsigned pc, int m, int opsize, std::ostream } else { switch(mod>>5) { case 0: // Displacement (8 bit) - out_AM_Displacement(mod&0x1F, read8(pc+1), opsize, stream); + out_AM_Displacement(mod&0x1F, opcodes.r8(pc+1), opsize, stream); return 2; case 1: // Displacement (16 bit) - out_AM_Displacement(mod&0x1F, read16(pc+1), opsize, stream); + out_AM_Displacement(mod&0x1F, opcodes.r16(pc+1), opsize, stream); return 3; case 2: // Displacement (32 bit) - out_AM_Displacement(mod&0x1F, read32(pc+1), opsize, stream); + out_AM_Displacement(mod&0x1F, opcodes.r32(pc+1), opsize, stream); return 5; case 3: // Register indirect @@ -324,15 +303,15 @@ static int decode_AM(unsigned ipc, unsigned pc, int m, int opsize, std::ostream return 1; case 4: // Displacement indirect (8 bit) - out_AM_DisplacementIndirect(mod&0x1F, read8(pc+1), opsize, stream); + out_AM_DisplacementIndirect(mod&0x1F, opcodes.r8(pc+1), opsize, stream); return 2; case 5: // Displacement indirect (16 bit) - out_AM_DisplacementIndirect(mod&0x1F, read16(pc+1), opsize, stream); + out_AM_DisplacementIndirect(mod&0x1F, opcodes.r16(pc+1), opsize, stream); return 3; case 6: // Displacement indirect (32 bit) - out_AM_DisplacementIndirect(mod&0x1F, read32(pc+1), opsize, stream); + out_AM_DisplacementIndirect(mod&0x1F, opcodes.r32(pc+1), opsize, stream); return 5; case 7: @@ -357,34 +336,34 @@ static int decode_AM(unsigned ipc, unsigned pc, int m, int opsize, std::ostream return 1; case 16: // PC Displacement (8 bit) - out_AM_PCDisplacement(ipc, read8(pc+1), opsize, stream); + out_AM_PCDisplacement(ipc, opcodes.r8(pc+1), opsize, stream); return 2; case 17: // PC Displacement (16 bit) - out_AM_PCDisplacement(ipc, read16(pc+1), opsize, stream); + out_AM_PCDisplacement(ipc, opcodes.r16(pc+1), opsize, stream); return 3; case 18: // PC Displacement (32 bit) - out_AM_PCDisplacement(ipc, read32(pc+1), opsize, stream); + out_AM_PCDisplacement(ipc, opcodes.r32(pc+1), opsize, stream); return 5; case 19: // Direct Address - out_AM_DirectAddress(read32(pc+1), opsize, stream); + out_AM_DirectAddress(opcodes.r32(pc+1), opsize, stream); return 5; case 20: switch(opsize&0x7F) { case 0: // Immediate (8 bit) - out_AM_Immediate(read8(pc+1), opsize, stream); + out_AM_Immediate(opcodes.r8(pc+1), opsize, stream); return 2; case 1: // Immediate (16 bit) - out_AM_Immediate(read16(pc+1), opsize, stream); + out_AM_Immediate(opcodes.r16(pc+1), opsize, stream); return 3; case 2: // Immediate (32 bit) - out_AM_Immediate(read32(pc+1), opsize, stream); + out_AM_Immediate(opcodes.r32(pc+1), opsize, stream); return 5; default: @@ -393,31 +372,31 @@ static int decode_AM(unsigned ipc, unsigned pc, int m, int opsize, std::ostream } case 24: // PC Displacement Indirect (8 bit) - out_AM_PCDisplacementIndirect(ipc, read8(pc+1), opsize, stream); + out_AM_PCDisplacementIndirect(ipc, opcodes.r8(pc+1), opsize, stream); return 2; case 25: // PC Displacement Indirect (16 bit) - out_AM_PCDisplacementIndirect(ipc, read16(pc+1), opsize, stream); + out_AM_PCDisplacementIndirect(ipc, opcodes.r16(pc+1), opsize, stream); return 3; case 26: // PC Displacement Indirect (32 bit) - out_AM_PCDisplacementIndirect(ipc, read32(pc+1), opsize, stream); + out_AM_PCDisplacementIndirect(ipc, opcodes.r32(pc+1), opsize, stream); return 5; case 27: // Direct Address Deferred - out_AM_DirectAddressDeferred(read32(pc+1), opsize, stream); + out_AM_DirectAddressDeferred(opcodes.r32(pc+1), opsize, stream); return 5; case 28: // PC Double Displacement (8 bit) - out_AM_PCDoubleDisplacement(ipc, read8(pc+1), read8(pc+2), opsize, stream); + out_AM_PCDoubleDisplacement(ipc, opcodes.r8(pc+1), opcodes.r8(pc+2), opsize, stream); return 3; case 29: // PC Double Displacement (16 bit) - out_AM_PCDoubleDisplacement(ipc, read16(pc+1), read16(pc+3), opsize, stream); + out_AM_PCDoubleDisplacement(ipc, opcodes.r16(pc+1), opcodes.r16(pc+3), opsize, stream); return 5; case 30: // PC Double Displacement (32 bit) - out_AM_PCDoubleDisplacement(ipc, read32(pc+1), read32(pc+5), opsize, stream); + out_AM_PCDoubleDisplacement(ipc, opcodes.r32(pc+1), opcodes.r32(pc+5), opsize, stream); return 9; default: @@ -433,92 +412,92 @@ static int decode_AM(unsigned ipc, unsigned pc, int m, int opsize, std::ostream } -static int decode_F1(const char *opnm, int opsize1, int opsize2, unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::decode_F1(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { - unsigned char code = readop(pc); + unsigned char code = opcodes.r8(pc); util::stream_format(stream, "%-8s", opnm); if(code & 0x20) { - int ret = decode_AM(ipc, pc+1, code & 0x40, opsize1, stream) + 2; + int ret = decode_AM(ipc, pc+1, code & 0x40, opsize1, opcodes, stream) + 2; stream << ", "; out_AM_Register(code & 0x1f, stream); return ret; } else { out_AM_Register(code & 0x1f, stream); stream << ", "; - return decode_AM(ipc, pc+1, code & 0x40, opsize1, stream) + 2; + return decode_AM(ipc, pc+1, code & 0x40, opsize1, opcodes, stream) + 2; } } -static int decode_F2(const char *opnm, int opsize1, int opsize2, unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::decode_F2(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { int ret; - unsigned char code = readop(pc); + unsigned char code = opcodes.r8(pc); util::stream_format(stream, "%-8s", opnm); - ret = decode_AM(ipc, pc+1, code & 0x40, opsize1, stream); + ret = decode_AM(ipc, pc+1, code & 0x40, opsize1, opcodes, stream); stream << ", "; - ret += decode_AM(ipc, pc+1+ret, code & 0x20, opsize2, stream); + ret += decode_AM(ipc, pc+1+ret, code & 0x20, opsize2, opcodes, stream); return ret+2; } -static int decode_F1F2(const char *opnm, int opsize1, int opsize2, unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::decode_F1F2(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { - if(readop(pc) & 0x80) - return decode_F2(opnm, opsize1, opsize2, ipc, pc, stream); + if(opcodes.r8(pc) & 0x80) + return decode_F2(opnm, opsize1, opsize2, ipc, pc, opcodes, stream); else - return decode_F1(opnm, opsize1, opsize2, ipc, pc, stream); + return decode_F1(opnm, opsize1, opsize2, ipc, pc, opcodes, stream); } -static int decode_F3(const char *opnm, int opsize1, int opsize2, unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::decode_F3(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { util::stream_format(stream, "%-8s", opnm); - return decode_AM(ipc, pc, readop(pc-1) & 1, opsize1, stream) + 1; + return decode_AM(ipc, pc, opcodes.r8(pc-1) & 1, opsize1, opcodes, stream) + 1; } -static int decode_F4a(const char *opnm, int opsize1, int opsize2, unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::decode_F4a(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { - util::stream_format(stream, "%-8s%X", opnm, ipc+read8(pc)); + util::stream_format(stream, "%-8s%X", opnm, ipc+opcodes.r8(pc)); return 2; } -static int decode_F4b(const char *opnm, int opsize1, int opsize2, unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::decode_F4b(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { - util::stream_format(stream, "%-8s%X", opnm, ipc+read16(pc)); + util::stream_format(stream, "%-8s%X", opnm, ipc+opcodes.r16(pc)); return 3; } -static int decode_F5(const char *opnm, int opsize1, int opsize2, unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::decode_F5(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { stream << opnm; return 1; } -static int decode_F6(const char *opnm, int opsize1, int opsize2, unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::decode_F6(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { - util::stream_format(stream, "%-8s%s, %X[PC]", opnm, v60_reg_names[readop(pc) & 0x1f], ipc+read16(pc+1)); + util::stream_format(stream, "%-8s%s, %X[PC]", opnm, v60_reg_names[opcodes.r8(pc) & 0x1f], ipc+opcodes.r16(pc+1)); return 4; } -static int decode_F7a(const char *opnm, int opsize1, int opsize2, unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::decode_F7a(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { int ret; - unsigned char code = readop(pc); + unsigned char code = opcodes.r8(pc); unsigned char code2; util::stream_format(stream, "%-8s", opnm); - ret = decode_AM(ipc, pc+1, code & 0x40, opsize1, stream); + ret = decode_AM(ipc, pc+1, code & 0x40, opsize1, opcodes, stream); stream << ", "; - code2 = readop(pc+1+ret); + code2 = opcodes.r8(pc+1+ret); if(code2 & 0x80) out_AM_Register(code2 & 0x1f, stream); else out_AM_Immediate(code2, 1, stream); stream << ", "; - ret += decode_AM(ipc, pc+2+ret, code & 0x20, opsize2, stream); + ret += decode_AM(ipc, pc+2+ret, code & 0x20, opsize2, opcodes, stream); stream << ", "; - code2 = readop(pc+2+ret); + code2 = opcodes.r8(pc+2+ret); if(code2 & 0x80) out_AM_Register(code2 & 0x1f, stream); else @@ -527,42 +506,42 @@ static int decode_F7a(const char *opnm, int opsize1, int opsize2, unsigned ipc, return ret+4; } -static int decode_F7b(const char *opnm, int opsize1, int opsize2, unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::decode_F7b(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { int ret; - unsigned char code = readop(pc); + unsigned char code = opcodes.r8(pc); unsigned char code2; util::stream_format(stream, "%-8s", opnm); - ret = decode_AM(ipc, pc+1, code & 0x40, opsize1, stream); + ret = decode_AM(ipc, pc+1, code & 0x40, opsize1, opcodes, stream); stream << ", "; - code2 = readop(pc+1+ret); + code2 = opcodes.r8(pc+1+ret); if(code2 & 0x80) out_AM_Register(code2 & 0x1f, stream); else out_AM_Immediate(code2, 1, stream); stream << ", "; - ret += decode_AM(ipc, pc+2+ret, code & 0x20, opsize2, stream); + ret += decode_AM(ipc, pc+2+ret, code & 0x20, opsize2, opcodes, stream); return ret+3; } -static int decode_F7c(const char *opnm, int opsize1, int opsize2, unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::decode_F7c(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { int ret; - unsigned char code = readop(pc); + unsigned char code = opcodes.r8(pc); unsigned char code2; util::stream_format(stream, "%-8s", opnm); - ret = decode_AM(ipc, pc+1, code & 0x40, opsize1, stream); + ret = decode_AM(ipc, pc+1, code & 0x40, opsize1, opcodes, stream); stream << ", "; - ret += decode_AM(ipc, pc+1+ret, code & 0x20, opsize2, stream); + ret += decode_AM(ipc, pc+1+ret, code & 0x20, opsize2, opcodes, stream); stream << ", "; - code2 = readop(pc+1+ret); + code2 = opcodes.r8(pc+1+ret); if(code2 & 0x80) out_AM_Register(code2 & 0x1f, stream); else @@ -571,70 +550,70 @@ static int decode_F7c(const char *opnm, int opsize1, int opsize2, unsigned ipc, return ret+3; } -static int dopUNHANDLED(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dopUNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { - util::stream_format(stream, "$%02X", readop(pc)); + util::stream_format(stream, "$%02X", opcodes.r8(pc)); return 1; } -static int dop58UNHANDLED(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dop58UNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { util::stream_format(stream, "$58"); return 1; } -static int dop59UNHANDLED(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dop59UNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { util::stream_format(stream, "$59"); return 1; } -static int dop5AUNHANDLED(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dop5AUNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { util::stream_format(stream, "$5A"); return 1; } -static int dop5BUNHANDLED(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dop5BUNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { util::stream_format(stream, "$5B"); return 1; } -static int dop5CUNHANDLED(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dop5CUNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { util::stream_format(stream, "$5C"); return 1; } -static int dop5DUNHANDLED(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dop5DUNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { util::stream_format(stream, "$5D"); return 1; } -static int dop5EUNHANDLED(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dop5EUNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { util::stream_format(stream, "$5E"); return 1; } -static int dop5FUNHANDLED(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dop5FUNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { util::stream_format(stream, "$5F"); return 1; } #define DEFINE_EASY_OPCODE(name, opnm, ftype, opsize1, opsize2) \ - static int dop ## name(unsigned ipc, unsigned pc, std::ostream &stream) \ + u32 v60_disassembler::dop ## name(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) \ { \ - return decode_ ## ftype(opnm, opsize1, opsize2, ipc, pc, stream); \ + return decode_ ## ftype(opnm, opsize1, opsize2, ipc, pc, opcodes, stream); \ } #define DEFINE_EASY_OPCODE_EX(name, opnm, ftype, opsize1, opsize2, flags) \ - static int dop ## name(unsigned ipc, unsigned pc, std::ostream &stream) \ + u32 v60_disassembler::dop ## name(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) \ { \ - return decode_ ## ftype(opnm, opsize1, opsize2, ipc, pc, stream) | (flags); \ + return decode_ ## ftype(opnm, opsize1, opsize2, ipc, pc, opcodes, stream) | (flags); \ } #define DEFINE_TRIPLE_OPCODE(name, string, ftype) \ @@ -693,8 +672,8 @@ DEFINE_EASY_OPCODE(BR8, "br", F4a, 0, 0) DEFINE_EASY_OPCODE(BR16, "br", F4b, 0, 0) DEFINE_EASY_OPCODE(BRK, "brk", F5, 0, 0) DEFINE_EASY_OPCODE(BRKV, "brkv", F5, 0, 0) -DEFINE_EASY_OPCODE_EX(BSR, "bsr", F4b, 0, 0, DASMFLAG_STEP_OVER) -DEFINE_EASY_OPCODE_EX(CALL, "call", F1F2, 0, 2, DASMFLAG_STEP_OVER) +DEFINE_EASY_OPCODE_EX(BSR, "bsr", F4b, 0, 0, STEP_OVER) +DEFINE_EASY_OPCODE_EX(CALL, "call", F1F2, 0, 2, STEP_OVER) DEFINE_EASY_OPCODE(CAXI, "caxi", F1, 2, 2) DEFINE_EASY_OPCODE(CHKAR, "chkar", F1F2, 0, 0) // ? DEFINE_EASY_OPCODE(CHKAW, "chkaw", F1F2, 0, 0) // ? @@ -719,21 +698,21 @@ DEFINE_EASY_OPCODE(CVTSW, "cvt.sw", F2, 0, 2) DEFINE_EASY_OPCODE(CVTLW, "cvt.lw", F2, 1, 2) DEFINE_EASY_OPCODE(CVTDPZ, "cvtd.pz", F7c, 0, 1) DEFINE_EASY_OPCODE(CVTDZP, "cvtd.zp", F7c, 1, 0) -DEFINE_EASY_OPCODE_EX(DBGT, "dbgt", F6, 0, 0, DASMFLAG_STEP_OVER) -DEFINE_EASY_OPCODE_EX(DBGE, "dbge", F6, 0, 0, DASMFLAG_STEP_OVER) -DEFINE_EASY_OPCODE_EX(DBLT, "dbgt", F6, 0, 0, DASMFLAG_STEP_OVER) -DEFINE_EASY_OPCODE_EX(DBLE, "dbge", F6, 0, 0, DASMFLAG_STEP_OVER) -DEFINE_EASY_OPCODE_EX(DBH, "dbh", F6, 0, 0, DASMFLAG_STEP_OVER) -DEFINE_EASY_OPCODE_EX(DBNL, "dbnl", F6, 0, 0, DASMFLAG_STEP_OVER) -DEFINE_EASY_OPCODE_EX(DBL, "dbl", F6, 0, 0, DASMFLAG_STEP_OVER) -DEFINE_EASY_OPCODE_EX(DBNH, "dbnh", F6, 0, 0, DASMFLAG_STEP_OVER) -DEFINE_EASY_OPCODE_EX(DBE, "dbe", F6, 0, 0, DASMFLAG_STEP_OVER) -DEFINE_EASY_OPCODE_EX(DBNE, "dbne", F6, 0, 0, DASMFLAG_STEP_OVER) -DEFINE_EASY_OPCODE_EX(DBV, "dbe", F6, 0, 0, DASMFLAG_STEP_OVER) -DEFINE_EASY_OPCODE_EX(DBNV, "dbne", F6, 0, 0, DASMFLAG_STEP_OVER) -DEFINE_EASY_OPCODE_EX(DBN, "dbn", F6, 0, 0, DASMFLAG_STEP_OVER) -DEFINE_EASY_OPCODE_EX(DBP, "dbp", F6, 0, 0, DASMFLAG_STEP_OVER) -DEFINE_EASY_OPCODE_EX(DBR, "dbr", F6, 0, 0, DASMFLAG_STEP_OVER) +DEFINE_EASY_OPCODE_EX(DBGT, "dbgt", F6, 0, 0, STEP_OVER) +DEFINE_EASY_OPCODE_EX(DBGE, "dbge", F6, 0, 0, STEP_OVER) +DEFINE_EASY_OPCODE_EX(DBLT, "dbgt", F6, 0, 0, STEP_OVER) +DEFINE_EASY_OPCODE_EX(DBLE, "dbge", F6, 0, 0, STEP_OVER) +DEFINE_EASY_OPCODE_EX(DBH, "dbh", F6, 0, 0, STEP_OVER) +DEFINE_EASY_OPCODE_EX(DBNL, "dbnl", F6, 0, 0, STEP_OVER) +DEFINE_EASY_OPCODE_EX(DBL, "dbl", F6, 0, 0, STEP_OVER) +DEFINE_EASY_OPCODE_EX(DBNH, "dbnh", F6, 0, 0, STEP_OVER) +DEFINE_EASY_OPCODE_EX(DBE, "dbe", F6, 0, 0, STEP_OVER) +DEFINE_EASY_OPCODE_EX(DBNE, "dbne", F6, 0, 0, STEP_OVER) +DEFINE_EASY_OPCODE_EX(DBV, "dbe", F6, 0, 0, STEP_OVER) +DEFINE_EASY_OPCODE_EX(DBNV, "dbne", F6, 0, 0, STEP_OVER) +DEFINE_EASY_OPCODE_EX(DBN, "dbn", F6, 0, 0, STEP_OVER) +DEFINE_EASY_OPCODE_EX(DBP, "dbp", F6, 0, 0, STEP_OVER) +DEFINE_EASY_OPCODE_EX(DBR, "dbr", F6, 0, 0, STEP_OVER) DEFINE_TRIPLE_OPCODE(DEC, "dec", F3) DEFINE_EASY_OPCODE(DISPOSE, "dispose", F5, 0, 0) DEFINE_TRIPLE_OPCODE(DIV, "div", F1F2) @@ -754,7 +733,7 @@ DEFINE_TRIPLE_OPCODE(INC, "inc", F3) DEFINE_EASY_OPCODE(INSBFL, "insbfl", F7c, 2, 0x82) DEFINE_EASY_OPCODE(INSBFR, "insbfr", F7c, 2, 0x82) DEFINE_EASY_OPCODE(JMP, "jmp", F3, 0, 0) -DEFINE_EASY_OPCODE_EX(JSR, "jsr", F3, 0, 0, DASMFLAG_STEP_OVER) +DEFINE_EASY_OPCODE_EX(JSR, "jsr", F3, 0, 0, STEP_OVER) DEFINE_EASY_OPCODE(LDPR, "ldpr", F1F2, 2, 2) DEFINE_EASY_OPCODE(LDTASK, "ldtask", F1F2, 2, 2) DEFINE_TRIPLE_OPCODE(MOV, "mov", F1F2) @@ -804,16 +783,16 @@ DEFINE_EASY_OPCODE(PUSH, "push", F3, 2, 0) DEFINE_EASY_OPCODE(PUSHM, "pushm", F3, 2, 0) DEFINE_TRIPLE_OPCODE(REM, "rem", F1F2) DEFINE_TRIPLE_OPCODE(REMU, "remu", F1F2) -DEFINE_EASY_OPCODE_EX(RET, "ret", F3, 2, 0, DASMFLAG_STEP_OUT) -DEFINE_EASY_OPCODE_EX(RETIU, "retiu", F3, 1, 0, DASMFLAG_STEP_OUT) -DEFINE_EASY_OPCODE_EX(RETIS, "retis", F3, 1, 0, DASMFLAG_STEP_OUT) +DEFINE_EASY_OPCODE_EX(RET, "ret", F3, 2, 0, STEP_OUT) +DEFINE_EASY_OPCODE_EX(RETIU, "retiu", F3, 1, 0, STEP_OUT) +DEFINE_EASY_OPCODE_EX(RETIS, "retis", F3, 1, 0, STEP_OUT) DEFINE_EASY_OPCODE(ROTB, "rot.b", F1F2, 0, 0) DEFINE_EASY_OPCODE(ROTH, "rot.h", F1F2, 0, 1) DEFINE_EASY_OPCODE(ROTW, "rot.w", F1F2, 0, 2) DEFINE_EASY_OPCODE(ROTCB, "rotc.b", F1F2, 0, 0) DEFINE_EASY_OPCODE(ROTCH, "rotc.h", F1F2, 0, 1) DEFINE_EASY_OPCODE(ROTCW, "rotc.w", F1F2, 0, 2) -DEFINE_EASY_OPCODE_EX(RSR, "rsr", F5, 0, 0, DASMFLAG_STEP_OUT) +DEFINE_EASY_OPCODE_EX(RSR, "rsr", F5, 0, 0, STEP_OUT) DEFINE_EASY_OPCODE(RVBIT, "rvbit", F1F2, 0, 0) DEFINE_EASY_OPCODE(RVBYT, "rvbyt", F1F2, 2, 2) DEFINE_EASY_OPCODE(SCH0BSU, "sch0bsu", F7b, 0x80, 2) @@ -849,7 +828,7 @@ DEFINE_EASY_OPCODE(TASI, "tasi", F3, 0, 0) DEFINE_EASY_OPCODE(TB, "tb", F6, 0, 0) DEFINE_TRIPLE_OPCODE(TEST, "test", F3) DEFINE_EASY_OPCODE(TEST1, "test1", F1F2, 2, 2) -DEFINE_EASY_OPCODE_EX(TRAP, "trap", F3, 0, 0, DASMFLAG_STEP_OVER) +DEFINE_EASY_OPCODE_EX(TRAP, "trap", F3, 0, 0, STEP_OVER) DEFINE_EASY_OPCODE(TRAPFL, "trapfl", F5, 0, 0) DEFINE_EASY_OPCODE(UPDATE, "update", F1F2, 0, 3) // ? DEFINE_EASY_OPCODE(UPDPSWH, "updpsw.h", F1F2, 2, 2) @@ -862,638 +841,634 @@ DEFINE_EASY_OPCODE(XORBSD, "xorbsd", F7b, 0x80, 0x80) DEFINE_EASY_OPCODE(XORNBSU, "xornbsu", F7b, 0x80, 0x80) DEFINE_EASY_OPCODE(XORNBSD, "xornbsd", F7b, 0x80, 0x80) -static int (*const dasm_optable_58[32])(unsigned ipc, unsigned pc, std::ostream &stream) = -{ - /* 0x00 */ dopCMPCB, - /* 0x01 */ dopCMPCFB, - /* 0x02 */ dopCMPCSB, - /* 0x03 */ dop58UNHANDLED, - /* 0x04 */ dop58UNHANDLED, - /* 0x05 */ dop58UNHANDLED, - /* 0x06 */ dop58UNHANDLED, - /* 0x07 */ dop58UNHANDLED, - /* 0x08 */ dopMOVCUB, - /* 0x09 */ dopMOVCDB, - /* 0x0A */ dopMOVCFUB, - /* 0x0B */ dopMOVCFDB, - /* 0x0C */ dopMOVCSB, - /* 0x0D */ dop58UNHANDLED, - /* 0x0E */ dop58UNHANDLED, - /* 0x0F */ dop58UNHANDLED, - /* 0x10 */ dop58UNHANDLED, - /* 0x11 */ dop58UNHANDLED, - /* 0x12 */ dop58UNHANDLED, - /* 0x13 */ dop58UNHANDLED, - /* 0x14 */ dop58UNHANDLED, - /* 0x15 */ dop58UNHANDLED, - /* 0x16 */ dop58UNHANDLED, - /* 0x17 */ dop58UNHANDLED, - /* 0x18 */ dopSCHCUB, - /* 0x19 */ dopSCHCDB, - /* 0x1A */ dopSKPCUB, - /* 0x1B */ dopSKPCDB, - /* 0x1C */ dop58UNHANDLED, - /* 0x1D */ dop58UNHANDLED, - /* 0x1E */ dop58UNHANDLED, - /* 0x1F */ dop58UNHANDLED +u32 (v60_disassembler::*const v60_disassembler::dasm_optable_58[32])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) = +{ + /* 0x00 */ &v60_disassembler::dopCMPCB, + /* 0x01 */ &v60_disassembler::dopCMPCFB, + /* 0x02 */ &v60_disassembler::dopCMPCSB, + /* 0x03 */ &v60_disassembler::dop58UNHANDLED, + /* 0x04 */ &v60_disassembler::dop58UNHANDLED, + /* 0x05 */ &v60_disassembler::dop58UNHANDLED, + /* 0x06 */ &v60_disassembler::dop58UNHANDLED, + /* 0x07 */ &v60_disassembler::dop58UNHANDLED, + /* 0x08 */ &v60_disassembler::dopMOVCUB, + /* 0x09 */ &v60_disassembler::dopMOVCDB, + /* 0x0A */ &v60_disassembler::dopMOVCFUB, + /* 0x0B */ &v60_disassembler::dopMOVCFDB, + /* 0x0C */ &v60_disassembler::dopMOVCSB, + /* 0x0D */ &v60_disassembler::dop58UNHANDLED, + /* 0x0E */ &v60_disassembler::dop58UNHANDLED, + /* 0x0F */ &v60_disassembler::dop58UNHANDLED, + /* 0x10 */ &v60_disassembler::dop58UNHANDLED, + /* 0x11 */ &v60_disassembler::dop58UNHANDLED, + /* 0x12 */ &v60_disassembler::dop58UNHANDLED, + /* 0x13 */ &v60_disassembler::dop58UNHANDLED, + /* 0x14 */ &v60_disassembler::dop58UNHANDLED, + /* 0x15 */ &v60_disassembler::dop58UNHANDLED, + /* 0x16 */ &v60_disassembler::dop58UNHANDLED, + /* 0x17 */ &v60_disassembler::dop58UNHANDLED, + /* 0x18 */ &v60_disassembler::dopSCHCUB, + /* 0x19 */ &v60_disassembler::dopSCHCDB, + /* 0x1A */ &v60_disassembler::dopSKPCUB, + /* 0x1B */ &v60_disassembler::dopSKPCDB, + /* 0x1C */ &v60_disassembler::dop58UNHANDLED, + /* 0x1D */ &v60_disassembler::dop58UNHANDLED, + /* 0x1E */ &v60_disassembler::dop58UNHANDLED, + /* 0x1F */ &v60_disassembler::dop58UNHANDLED }; -static int (*const dasm_optable_59[32])(unsigned ipc, unsigned pc, std::ostream &stream) = -{ - /* 0x00 */ dopADDDC, - /* 0x01 */ dopSUBDC, - /* 0x02 */ dopSUBRDC, - /* 0x03 */ dop59UNHANDLED, - /* 0x04 */ dop59UNHANDLED, - /* 0x05 */ dop59UNHANDLED, - /* 0x06 */ dop59UNHANDLED, - /* 0x07 */ dop59UNHANDLED, - /* 0x08 */ dop59UNHANDLED, - /* 0x09 */ dop59UNHANDLED, - /* 0x0A */ dop59UNHANDLED, - /* 0x0B */ dop59UNHANDLED, - /* 0x0C */ dop59UNHANDLED, - /* 0x0D */ dop59UNHANDLED, - /* 0x0E */ dop59UNHANDLED, - /* 0x0F */ dop59UNHANDLED, - /* 0x10 */ dopCVTDPZ, - /* 0x11 */ dop59UNHANDLED, - /* 0x12 */ dop59UNHANDLED, - /* 0x13 */ dop59UNHANDLED, - /* 0x14 */ dop59UNHANDLED, - /* 0x15 */ dop59UNHANDLED, - /* 0x16 */ dop59UNHANDLED, - /* 0x17 */ dop59UNHANDLED, - /* 0x18 */ dopCVTDZP, - /* 0x19 */ dop59UNHANDLED, - /* 0x1A */ dop59UNHANDLED, - /* 0x1B */ dop59UNHANDLED, - /* 0x1C */ dop59UNHANDLED, - /* 0x1D */ dop59UNHANDLED, - /* 0x1E */ dop59UNHANDLED, - /* 0x1F */ dop59UNHANDLED +u32 (v60_disassembler::*const v60_disassembler::dasm_optable_59[32])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) = +{ + /* 0x00 */ &v60_disassembler::dopADDDC, + /* 0x01 */ &v60_disassembler::dopSUBDC, + /* 0x02 */ &v60_disassembler::dopSUBRDC, + /* 0x03 */ &v60_disassembler::dop59UNHANDLED, + /* 0x04 */ &v60_disassembler::dop59UNHANDLED, + /* 0x05 */ &v60_disassembler::dop59UNHANDLED, + /* 0x06 */ &v60_disassembler::dop59UNHANDLED, + /* 0x07 */ &v60_disassembler::dop59UNHANDLED, + /* 0x08 */ &v60_disassembler::dop59UNHANDLED, + /* 0x09 */ &v60_disassembler::dop59UNHANDLED, + /* 0x0A */ &v60_disassembler::dop59UNHANDLED, + /* 0x0B */ &v60_disassembler::dop59UNHANDLED, + /* 0x0C */ &v60_disassembler::dop59UNHANDLED, + /* 0x0D */ &v60_disassembler::dop59UNHANDLED, + /* 0x0E */ &v60_disassembler::dop59UNHANDLED, + /* 0x0F */ &v60_disassembler::dop59UNHANDLED, + /* 0x10 */ &v60_disassembler::dopCVTDPZ, + /* 0x11 */ &v60_disassembler::dop59UNHANDLED, + /* 0x12 */ &v60_disassembler::dop59UNHANDLED, + /* 0x13 */ &v60_disassembler::dop59UNHANDLED, + /* 0x14 */ &v60_disassembler::dop59UNHANDLED, + /* 0x15 */ &v60_disassembler::dop59UNHANDLED, + /* 0x16 */ &v60_disassembler::dop59UNHANDLED, + /* 0x17 */ &v60_disassembler::dop59UNHANDLED, + /* 0x18 */ &v60_disassembler::dopCVTDZP, + /* 0x19 */ &v60_disassembler::dop59UNHANDLED, + /* 0x1A */ &v60_disassembler::dop59UNHANDLED, + /* 0x1B */ &v60_disassembler::dop59UNHANDLED, + /* 0x1C */ &v60_disassembler::dop59UNHANDLED, + /* 0x1D */ &v60_disassembler::dop59UNHANDLED, + /* 0x1E */ &v60_disassembler::dop59UNHANDLED, + /* 0x1F */ &v60_disassembler::dop59UNHANDLED }; -static int (*const dasm_optable_5A[32])(unsigned ipc, unsigned pc, std::ostream &stream) = -{ - /* 0x00 */ dopCMPCH, - /* 0x01 */ dopCMPCFH, - /* 0x02 */ dopCMPCSH, - /* 0x03 */ dop5AUNHANDLED, - /* 0x04 */ dop5AUNHANDLED, - /* 0x05 */ dop5AUNHANDLED, - /* 0x06 */ dop5AUNHANDLED, - /* 0x07 */ dop5AUNHANDLED, - /* 0x08 */ dopMOVCUH, - /* 0x09 */ dopMOVCDH, - /* 0x0A */ dopMOVCFUH, - /* 0x0B */ dopMOVCFDH, - /* 0x0C */ dopMOVCSH, - /* 0x0D */ dop5AUNHANDLED, - /* 0x0E */ dop5AUNHANDLED, - /* 0x0F */ dop5AUNHANDLED, - /* 0x10 */ dop5AUNHANDLED, - /* 0x11 */ dop5AUNHANDLED, - /* 0x12 */ dop5AUNHANDLED, - /* 0x13 */ dop5AUNHANDLED, - /* 0x14 */ dop5AUNHANDLED, - /* 0x15 */ dop5AUNHANDLED, - /* 0x16 */ dop5AUNHANDLED, - /* 0x17 */ dop5AUNHANDLED, - /* 0x18 */ dopSCHCUH, - /* 0x19 */ dopSCHCDH, - /* 0x1A */ dopSKPCUH, - /* 0x1B */ dopSKPCDH, - /* 0x1C */ dop5AUNHANDLED, - /* 0x1D */ dop5AUNHANDLED, - /* 0x1E */ dop5AUNHANDLED, - /* 0x1F */ dop5AUNHANDLED +u32 (v60_disassembler::*const v60_disassembler::dasm_optable_5A[32])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) = +{ + /* 0x00 */ &v60_disassembler::dopCMPCH, + /* 0x01 */ &v60_disassembler::dopCMPCFH, + /* 0x02 */ &v60_disassembler::dopCMPCSH, + /* 0x03 */ &v60_disassembler::dop5AUNHANDLED, + /* 0x04 */ &v60_disassembler::dop5AUNHANDLED, + /* 0x05 */ &v60_disassembler::dop5AUNHANDLED, + /* 0x06 */ &v60_disassembler::dop5AUNHANDLED, + /* 0x07 */ &v60_disassembler::dop5AUNHANDLED, + /* 0x08 */ &v60_disassembler::dopMOVCUH, + /* 0x09 */ &v60_disassembler::dopMOVCDH, + /* 0x0A */ &v60_disassembler::dopMOVCFUH, + /* 0x0B */ &v60_disassembler::dopMOVCFDH, + /* 0x0C */ &v60_disassembler::dopMOVCSH, + /* 0x0D */ &v60_disassembler::dop5AUNHANDLED, + /* 0x0E */ &v60_disassembler::dop5AUNHANDLED, + /* 0x0F */ &v60_disassembler::dop5AUNHANDLED, + /* 0x10 */ &v60_disassembler::dop5AUNHANDLED, + /* 0x11 */ &v60_disassembler::dop5AUNHANDLED, + /* 0x12 */ &v60_disassembler::dop5AUNHANDLED, + /* 0x13 */ &v60_disassembler::dop5AUNHANDLED, + /* 0x14 */ &v60_disassembler::dop5AUNHANDLED, + /* 0x15 */ &v60_disassembler::dop5AUNHANDLED, + /* 0x16 */ &v60_disassembler::dop5AUNHANDLED, + /* 0x17 */ &v60_disassembler::dop5AUNHANDLED, + /* 0x18 */ &v60_disassembler::dopSCHCUH, + /* 0x19 */ &v60_disassembler::dopSCHCDH, + /* 0x1A */ &v60_disassembler::dopSKPCUH, + /* 0x1B */ &v60_disassembler::dopSKPCDH, + /* 0x1C */ &v60_disassembler::dop5AUNHANDLED, + /* 0x1D */ &v60_disassembler::dop5AUNHANDLED, + /* 0x1E */ &v60_disassembler::dop5AUNHANDLED, + /* 0x1F */ &v60_disassembler::dop5AUNHANDLED }; -static int (*const dasm_optable_5B[32])(unsigned ipc, unsigned pc, std::ostream &stream) = -{ - /* 0x00 */ dopSCH0BSU, - /* 0x01 */ dopSCH0BSD, - /* 0x02 */ dopSCH1BSU, - /* 0x03 */ dopSCH1BSD, - /* 0x04 */ dop5BUNHANDLED, - /* 0x05 */ dop5BUNHANDLED, - /* 0x06 */ dop5BUNHANDLED, - /* 0x07 */ dop5BUNHANDLED, - /* 0x08 */ dopMOVBSU, - /* 0x09 */ dopMOVBSD, - /* 0x0A */ dopNOTBSU, - /* 0x0B */ dopNOTBSD, - /* 0x0C */ dop5BUNHANDLED, - /* 0x0D */ dop5BUNHANDLED, - /* 0x0E */ dop5BUNHANDLED, - /* 0x0F */ dop5BUNHANDLED, - /* 0x10 */ dopANDBSU, - /* 0x11 */ dopANDBSD, - /* 0x12 */ dopANDNBSU, - /* 0x13 */ dopANDNBSD, - /* 0x14 */ dopORBSU, - /* 0x15 */ dopORBSD, - /* 0x16 */ dopORNBSU, - /* 0x17 */ dopORNBSD, - /* 0x18 */ dopXORBSU, - /* 0x19 */ dopXORBSD, - /* 0x1A */ dopXORNBSU, - /* 0x1B */ dopXORNBSD, - /* 0x1C */ dop5BUNHANDLED, - /* 0x1D */ dop5BUNHANDLED, - /* 0x1E */ dop5BUNHANDLED, - /* 0x1F */ dop5BUNHANDLED +u32 (v60_disassembler::*const v60_disassembler::dasm_optable_5B[32])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) = +{ + /* 0x00 */ &v60_disassembler::dopSCH0BSU, + /* 0x01 */ &v60_disassembler::dopSCH0BSD, + /* 0x02 */ &v60_disassembler::dopSCH1BSU, + /* 0x03 */ &v60_disassembler::dopSCH1BSD, + /* 0x04 */ &v60_disassembler::dop5BUNHANDLED, + /* 0x05 */ &v60_disassembler::dop5BUNHANDLED, + /* 0x06 */ &v60_disassembler::dop5BUNHANDLED, + /* 0x07 */ &v60_disassembler::dop5BUNHANDLED, + /* 0x08 */ &v60_disassembler::dopMOVBSU, + /* 0x09 */ &v60_disassembler::dopMOVBSD, + /* 0x0A */ &v60_disassembler::dopNOTBSU, + /* 0x0B */ &v60_disassembler::dopNOTBSD, + /* 0x0C */ &v60_disassembler::dop5BUNHANDLED, + /* 0x0D */ &v60_disassembler::dop5BUNHANDLED, + /* 0x0E */ &v60_disassembler::dop5BUNHANDLED, + /* 0x0F */ &v60_disassembler::dop5BUNHANDLED, + /* 0x10 */ &v60_disassembler::dopANDBSU, + /* 0x11 */ &v60_disassembler::dopANDBSD, + /* 0x12 */ &v60_disassembler::dopANDNBSU, + /* 0x13 */ &v60_disassembler::dopANDNBSD, + /* 0x14 */ &v60_disassembler::dopORBSU, + /* 0x15 */ &v60_disassembler::dopORBSD, + /* 0x16 */ &v60_disassembler::dopORNBSU, + /* 0x17 */ &v60_disassembler::dopORNBSD, + /* 0x18 */ &v60_disassembler::dopXORBSU, + /* 0x19 */ &v60_disassembler::dopXORBSD, + /* 0x1A */ &v60_disassembler::dopXORNBSU, + /* 0x1B */ &v60_disassembler::dopXORNBSD, + /* 0x1C */ &v60_disassembler::dop5BUNHANDLED, + /* 0x1D */ &v60_disassembler::dop5BUNHANDLED, + /* 0x1E */ &v60_disassembler::dop5BUNHANDLED, + /* 0x1F */ &v60_disassembler::dop5BUNHANDLED }; -static int (*const dasm_optable_5C[32])(unsigned ipc, unsigned pc, std::ostream &stream) = -{ - /* 0x00 */ dopCMPFS, - /* 0x01 */ dop5CUNHANDLED, - /* 0x02 */ dop5CUNHANDLED, - /* 0x03 */ dop5CUNHANDLED, - /* 0x04 */ dop5CUNHANDLED, - /* 0x05 */ dop5CUNHANDLED, - /* 0x06 */ dop5CUNHANDLED, - /* 0x07 */ dop5CUNHANDLED, - /* 0x08 */ dopMOVFS, - /* 0x09 */ dopNEGFS, - /* 0x0A */ dopABSFS, - /* 0x0B */ dop5CUNHANDLED, - /* 0x0C */ dop5CUNHANDLED, - /* 0x0D */ dop5CUNHANDLED, - /* 0x0E */ dop5CUNHANDLED, - /* 0x0F */ dop5CUNHANDLED, - /* 0x10 */ dopSCLFS, - /* 0x11 */ dop5CUNHANDLED, - /* 0x12 */ dop5CUNHANDLED, - /* 0x13 */ dop5CUNHANDLED, - /* 0x14 */ dop5CUNHANDLED, - /* 0x15 */ dop5CUNHANDLED, - /* 0x16 */ dop5CUNHANDLED, - /* 0x17 */ dop5CUNHANDLED, - /* 0x18 */ dopADDFS, - /* 0x19 */ dopSUBFS, - /* 0x1A */ dopMULFS, - /* 0x1B */ dopDIVFS, - /* 0x1C */ dop5CUNHANDLED, - /* 0x1D */ dop5CUNHANDLED, - /* 0x1E */ dop5CUNHANDLED, - /* 0x1F */ dop5CUNHANDLED +u32 (v60_disassembler::*const v60_disassembler::dasm_optable_5C[32])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) = +{ + /* 0x00 */ &v60_disassembler::dopCMPFS, + /* 0x01 */ &v60_disassembler::dop5CUNHANDLED, + /* 0x02 */ &v60_disassembler::dop5CUNHANDLED, + /* 0x03 */ &v60_disassembler::dop5CUNHANDLED, + /* 0x04 */ &v60_disassembler::dop5CUNHANDLED, + /* 0x05 */ &v60_disassembler::dop5CUNHANDLED, + /* 0x06 */ &v60_disassembler::dop5CUNHANDLED, + /* 0x07 */ &v60_disassembler::dop5CUNHANDLED, + /* 0x08 */ &v60_disassembler::dopMOVFS, + /* 0x09 */ &v60_disassembler::dopNEGFS, + /* 0x0A */ &v60_disassembler::dopABSFS, + /* 0x0B */ &v60_disassembler::dop5CUNHANDLED, + /* 0x0C */ &v60_disassembler::dop5CUNHANDLED, + /* 0x0D */ &v60_disassembler::dop5CUNHANDLED, + /* 0x0E */ &v60_disassembler::dop5CUNHANDLED, + /* 0x0F */ &v60_disassembler::dop5CUNHANDLED, + /* 0x10 */ &v60_disassembler::dopSCLFS, + /* 0x11 */ &v60_disassembler::dop5CUNHANDLED, + /* 0x12 */ &v60_disassembler::dop5CUNHANDLED, + /* 0x13 */ &v60_disassembler::dop5CUNHANDLED, + /* 0x14 */ &v60_disassembler::dop5CUNHANDLED, + /* 0x15 */ &v60_disassembler::dop5CUNHANDLED, + /* 0x16 */ &v60_disassembler::dop5CUNHANDLED, + /* 0x17 */ &v60_disassembler::dop5CUNHANDLED, + /* 0x18 */ &v60_disassembler::dopADDFS, + /* 0x19 */ &v60_disassembler::dopSUBFS, + /* 0x1A */ &v60_disassembler::dopMULFS, + /* 0x1B */ &v60_disassembler::dopDIVFS, + /* 0x1C */ &v60_disassembler::dop5CUNHANDLED, + /* 0x1D */ &v60_disassembler::dop5CUNHANDLED, + /* 0x1E */ &v60_disassembler::dop5CUNHANDLED, + /* 0x1F */ &v60_disassembler::dop5CUNHANDLED }; -static int (*const dasm_optable_5D[32])(unsigned ipc, unsigned pc, std::ostream &stream) = -{ - /* 0x00 */ dopCMPBFS, - /* 0x01 */ dopCMPBFZ, - /* 0x02 */ dopCMPBFL, - /* 0x03 */ dop5DUNHANDLED, - /* 0x04 */ dop5DUNHANDLED, - /* 0x05 */ dop5DUNHANDLED, - /* 0x06 */ dop5DUNHANDLED, - /* 0x07 */ dop5DUNHANDLED, - /* 0x08 */ dopEXTBFS, - /* 0x09 */ dopEXTBFZ, - /* 0x0A */ dopEXTBFL, - /* 0x0B */ dop5DUNHANDLED, - /* 0x0C */ dop5DUNHANDLED, - /* 0x0D */ dop5DUNHANDLED, - /* 0x0E */ dop5DUNHANDLED, - /* 0x0F */ dop5DUNHANDLED, - /* 0x10 */ dop5DUNHANDLED, - /* 0x11 */ dop5DUNHANDLED, - /* 0x12 */ dop5DUNHANDLED, - /* 0x13 */ dop5DUNHANDLED, - /* 0x14 */ dop5DUNHANDLED, - /* 0x15 */ dop5DUNHANDLED, - /* 0x16 */ dop5DUNHANDLED, - /* 0x17 */ dop5DUNHANDLED, - /* 0x18 */ dopINSBFR, - /* 0x19 */ dopINSBFL, - /* 0x1A */ dop5DUNHANDLED, - /* 0x1B */ dop5DUNHANDLED, - /* 0x1C */ dop5DUNHANDLED, - /* 0x1D */ dop5DUNHANDLED, - /* 0x1E */ dop5DUNHANDLED, - /* 0x1F */ dop5DUNHANDLED +u32 (v60_disassembler::*const v60_disassembler::dasm_optable_5D[32])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) = +{ + /* 0x00 */ &v60_disassembler::dopCMPBFS, + /* 0x01 */ &v60_disassembler::dopCMPBFZ, + /* 0x02 */ &v60_disassembler::dopCMPBFL, + /* 0x03 */ &v60_disassembler::dop5DUNHANDLED, + /* 0x04 */ &v60_disassembler::dop5DUNHANDLED, + /* 0x05 */ &v60_disassembler::dop5DUNHANDLED, + /* 0x06 */ &v60_disassembler::dop5DUNHANDLED, + /* 0x07 */ &v60_disassembler::dop5DUNHANDLED, + /* 0x08 */ &v60_disassembler::dopEXTBFS, + /* 0x09 */ &v60_disassembler::dopEXTBFZ, + /* 0x0A */ &v60_disassembler::dopEXTBFL, + /* 0x0B */ &v60_disassembler::dop5DUNHANDLED, + /* 0x0C */ &v60_disassembler::dop5DUNHANDLED, + /* 0x0D */ &v60_disassembler::dop5DUNHANDLED, + /* 0x0E */ &v60_disassembler::dop5DUNHANDLED, + /* 0x0F */ &v60_disassembler::dop5DUNHANDLED, + /* 0x10 */ &v60_disassembler::dop5DUNHANDLED, + /* 0x11 */ &v60_disassembler::dop5DUNHANDLED, + /* 0x12 */ &v60_disassembler::dop5DUNHANDLED, + /* 0x13 */ &v60_disassembler::dop5DUNHANDLED, + /* 0x14 */ &v60_disassembler::dop5DUNHANDLED, + /* 0x15 */ &v60_disassembler::dop5DUNHANDLED, + /* 0x16 */ &v60_disassembler::dop5DUNHANDLED, + /* 0x17 */ &v60_disassembler::dop5DUNHANDLED, + /* 0x18 */ &v60_disassembler::dopINSBFR, + /* 0x19 */ &v60_disassembler::dopINSBFL, + /* 0x1A */ &v60_disassembler::dop5DUNHANDLED, + /* 0x1B */ &v60_disassembler::dop5DUNHANDLED, + /* 0x1C */ &v60_disassembler::dop5DUNHANDLED, + /* 0x1D */ &v60_disassembler::dop5DUNHANDLED, + /* 0x1E */ &v60_disassembler::dop5DUNHANDLED, + /* 0x1F */ &v60_disassembler::dop5DUNHANDLED }; -static int (*const dasm_optable_5E[32])(unsigned ipc, unsigned pc, std::ostream &stream) = -{ - /* 0x00 */ dopCMPFL, - /* 0x01 */ dop5EUNHANDLED, - /* 0x02 */ dop5EUNHANDLED, - /* 0x03 */ dop5EUNHANDLED, - /* 0x04 */ dop5EUNHANDLED, - /* 0x05 */ dop5EUNHANDLED, - /* 0x06 */ dop5EUNHANDLED, - /* 0x07 */ dop5EUNHANDLED, - /* 0x08 */ dopMOVFL, - /* 0x09 */ dopNEGFL, - /* 0x0A */ dopABSFL, - /* 0x0B */ dop5EUNHANDLED, - /* 0x0C */ dop5EUNHANDLED, - /* 0x0D */ dop5EUNHANDLED, - /* 0x0E */ dop5EUNHANDLED, - /* 0x0F */ dop5EUNHANDLED, - /* 0x10 */ dopSCLFL, - /* 0x11 */ dop5EUNHANDLED, - /* 0x12 */ dop5EUNHANDLED, - /* 0x13 */ dop5EUNHANDLED, - /* 0x14 */ dop5EUNHANDLED, - /* 0x15 */ dop5EUNHANDLED, - /* 0x16 */ dop5EUNHANDLED, - /* 0x17 */ dop5EUNHANDLED, - /* 0x18 */ dopADDFL, - /* 0x19 */ dopSUBFL, - /* 0x1A */ dopMULFL, - /* 0x1B */ dopDIVFL, - /* 0x1C */ dop5EUNHANDLED, - /* 0x1D */ dop5EUNHANDLED, - /* 0x1E */ dop5EUNHANDLED, - /* 0x1F */ dop5EUNHANDLED +u32 (v60_disassembler::*const v60_disassembler::dasm_optable_5E[32])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) = +{ + /* 0x00 */ &v60_disassembler::dopCMPFL, + /* 0x01 */ &v60_disassembler::dop5EUNHANDLED, + /* 0x02 */ &v60_disassembler::dop5EUNHANDLED, + /* 0x03 */ &v60_disassembler::dop5EUNHANDLED, + /* 0x04 */ &v60_disassembler::dop5EUNHANDLED, + /* 0x05 */ &v60_disassembler::dop5EUNHANDLED, + /* 0x06 */ &v60_disassembler::dop5EUNHANDLED, + /* 0x07 */ &v60_disassembler::dop5EUNHANDLED, + /* 0x08 */ &v60_disassembler::dopMOVFL, + /* 0x09 */ &v60_disassembler::dopNEGFL, + /* 0x0A */ &v60_disassembler::dopABSFL, + /* 0x0B */ &v60_disassembler::dop5EUNHANDLED, + /* 0x0C */ &v60_disassembler::dop5EUNHANDLED, + /* 0x0D */ &v60_disassembler::dop5EUNHANDLED, + /* 0x0E */ &v60_disassembler::dop5EUNHANDLED, + /* 0x0F */ &v60_disassembler::dop5EUNHANDLED, + /* 0x10 */ &v60_disassembler::dopSCLFL, + /* 0x11 */ &v60_disassembler::dop5EUNHANDLED, + /* 0x12 */ &v60_disassembler::dop5EUNHANDLED, + /* 0x13 */ &v60_disassembler::dop5EUNHANDLED, + /* 0x14 */ &v60_disassembler::dop5EUNHANDLED, + /* 0x15 */ &v60_disassembler::dop5EUNHANDLED, + /* 0x16 */ &v60_disassembler::dop5EUNHANDLED, + /* 0x17 */ &v60_disassembler::dop5EUNHANDLED, + /* 0x18 */ &v60_disassembler::dopADDFL, + /* 0x19 */ &v60_disassembler::dopSUBFL, + /* 0x1A */ &v60_disassembler::dopMULFL, + /* 0x1B */ &v60_disassembler::dopDIVFL, + /* 0x1C */ &v60_disassembler::dop5EUNHANDLED, + /* 0x1D */ &v60_disassembler::dop5EUNHANDLED, + /* 0x1E */ &v60_disassembler::dop5EUNHANDLED, + /* 0x1F */ &v60_disassembler::dop5EUNHANDLED }; -static int (*const dasm_optable_5F[32])(unsigned ipc, unsigned pc, std::ostream &stream) = -{ - /* 0x00 */ dopCVTWS, - /* 0x01 */ dopCVTSW, - /* 0x02 */ dop5FUNHANDLED, - /* 0x03 */ dop5FUNHANDLED, - /* 0x04 */ dop5FUNHANDLED, - /* 0x05 */ dop5FUNHANDLED, - /* 0x06 */ dop5FUNHANDLED, - /* 0x07 */ dop5FUNHANDLED, - /* 0x08 */ dopCVTLS, - /* 0x09 */ dopCVTLW, - /* 0x0A */ dop5FUNHANDLED, - /* 0x0B */ dop5FUNHANDLED, - /* 0x0C */ dop5FUNHANDLED, - /* 0x0D */ dop5FUNHANDLED, - /* 0x0E */ dop5FUNHANDLED, - /* 0x0F */ dop5FUNHANDLED, - /* 0x10 */ dopCVTSL, - /* 0x11 */ dopCVTWL, - /* 0x12 */ dop5FUNHANDLED, - /* 0x13 */ dop5FUNHANDLED, - /* 0x14 */ dop5FUNHANDLED, - /* 0x15 */ dop5FUNHANDLED, - /* 0x16 */ dop5FUNHANDLED, - /* 0x17 */ dop5FUNHANDLED, - /* 0x18 */ dop5FUNHANDLED, - /* 0x19 */ dop5FUNHANDLED, - /* 0x1A */ dop5FUNHANDLED, - /* 0x1B */ dop5FUNHANDLED, - /* 0x1C */ dop5FUNHANDLED, - /* 0x1D */ dop5FUNHANDLED, - /* 0x1E */ dop5FUNHANDLED, - /* 0x1F */ dop5FUNHANDLED +u32 (v60_disassembler::*const v60_disassembler::dasm_optable_5F[32])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) = +{ + /* 0x00 */ &v60_disassembler::dopCVTWS, + /* 0x01 */ &v60_disassembler::dopCVTSW, + /* 0x02 */ &v60_disassembler::dop5FUNHANDLED, + /* 0x03 */ &v60_disassembler::dop5FUNHANDLED, + /* 0x04 */ &v60_disassembler::dop5FUNHANDLED, + /* 0x05 */ &v60_disassembler::dop5FUNHANDLED, + /* 0x06 */ &v60_disassembler::dop5FUNHANDLED, + /* 0x07 */ &v60_disassembler::dop5FUNHANDLED, + /* 0x08 */ &v60_disassembler::dopCVTLS, + /* 0x09 */ &v60_disassembler::dopCVTLW, + /* 0x0A */ &v60_disassembler::dop5FUNHANDLED, + /* 0x0B */ &v60_disassembler::dop5FUNHANDLED, + /* 0x0C */ &v60_disassembler::dop5FUNHANDLED, + /* 0x0D */ &v60_disassembler::dop5FUNHANDLED, + /* 0x0E */ &v60_disassembler::dop5FUNHANDLED, + /* 0x0F */ &v60_disassembler::dop5FUNHANDLED, + /* 0x10 */ &v60_disassembler::dopCVTSL, + /* 0x11 */ &v60_disassembler::dopCVTWL, + /* 0x12 */ &v60_disassembler::dop5FUNHANDLED, + /* 0x13 */ &v60_disassembler::dop5FUNHANDLED, + /* 0x14 */ &v60_disassembler::dop5FUNHANDLED, + /* 0x15 */ &v60_disassembler::dop5FUNHANDLED, + /* 0x16 */ &v60_disassembler::dop5FUNHANDLED, + /* 0x17 */ &v60_disassembler::dop5FUNHANDLED, + /* 0x18 */ &v60_disassembler::dop5FUNHANDLED, + /* 0x19 */ &v60_disassembler::dop5FUNHANDLED, + /* 0x1A */ &v60_disassembler::dop5FUNHANDLED, + /* 0x1B */ &v60_disassembler::dop5FUNHANDLED, + /* 0x1C */ &v60_disassembler::dop5FUNHANDLED, + /* 0x1D */ &v60_disassembler::dop5FUNHANDLED, + /* 0x1E */ &v60_disassembler::dop5FUNHANDLED, + /* 0x1F */ &v60_disassembler::dop5FUNHANDLED }; -static int (*const dasm_optable_C6[8])(unsigned ipc, unsigned pc, std::ostream &stream) = +u32 (v60_disassembler::*const v60_disassembler::dasm_optable_C6[8])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) = { - /* 0x0 */ dopDBV, - /* 0x1 */ dopDBL, - /* 0x2 */ dopDBE, - /* 0x3 */ dopDBNH, - /* 0x4 */ dopDBN, - /* 0x5 */ dopDBR, - /* 0x6 */ dopDBLT, - /* 0x7 */ dopDBLE + /* 0x0 */ &v60_disassembler::dopDBV, + /* 0x1 */ &v60_disassembler::dopDBL, + /* 0x2 */ &v60_disassembler::dopDBE, + /* 0x3 */ &v60_disassembler::dopDBNH, + /* 0x4 */ &v60_disassembler::dopDBN, + /* 0x5 */ &v60_disassembler::dopDBR, + /* 0x6 */ &v60_disassembler::dopDBLT, + /* 0x7 */ &v60_disassembler::dopDBLE }; -static int (*const dasm_optable_C7[8])(unsigned ipc, unsigned pc, std::ostream &stream) = +u32 (v60_disassembler::*const v60_disassembler::dasm_optable_C7[8])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) = { - /* 0x0 */ dopDBNV, - /* 0x1 */ dopDBNL, - /* 0x2 */ dopDBNE, - /* 0x3 */ dopDBH, - /* 0x4 */ dopDBP, - /* 0x5 */ dopTB, - /* 0x6 */ dopDBGE, - /* 0x7 */ dopDBGT + /* 0x0 */ &v60_disassembler::dopDBNV, + /* 0x1 */ &v60_disassembler::dopDBNL, + /* 0x2 */ &v60_disassembler::dopDBNE, + /* 0x3 */ &v60_disassembler::dopDBH, + /* 0x4 */ &v60_disassembler::dopDBP, + /* 0x5 */ &v60_disassembler::dopTB, + /* 0x6 */ &v60_disassembler::dopDBGE, + /* 0x7 */ &v60_disassembler::dopDBGT }; -static int dop58(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dop58(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { - return dasm_optable_58[readop(pc) & 0x1f](ipc, pc, stream); + return (this->*dasm_optable_58[opcodes.r8(pc) & 0x1f])(ipc, pc, opcodes, stream); } -static int dop59(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dop59(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { - return dasm_optable_59[readop(pc) & 0x1f](ipc, pc, stream); + return (this->*dasm_optable_59[opcodes.r8(pc) & 0x1f])(ipc, pc, opcodes, stream); } -static int dop5A(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dop5A(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { - return dasm_optable_5A[readop(pc) & 0x1f](ipc, pc, stream); + return (this->*dasm_optable_5A[opcodes.r8(pc) & 0x1f])(ipc, pc, opcodes, stream); } -static int dop5B(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dop5B(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { - return dasm_optable_5B[readop(pc) & 0x1f](ipc, pc, stream); + return (this->*dasm_optable_5B[opcodes.r8(pc) & 0x1f])(ipc, pc, opcodes, stream); } -static int dop5C(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dop5C(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { - return dasm_optable_5C[readop(pc) & 0x1f](ipc, pc, stream); + return (this->*dasm_optable_5C[opcodes.r8(pc) & 0x1f])(ipc, pc, opcodes, stream); } -static int dop5D(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dop5D(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { - return dasm_optable_5D[readop(pc) & 0x1f](ipc, pc, stream); + return (this->*dasm_optable_5D[opcodes.r8(pc) & 0x1f])(ipc, pc, opcodes, stream); } -static int dop5E(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dop5E(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { - return dasm_optable_5E[readop(pc) & 0x1f](ipc, pc, stream); + return (this->*dasm_optable_5E[opcodes.r8(pc) & 0x1f])(ipc, pc, opcodes, stream); } -static int dop5F(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dop5F(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { - return dasm_optable_5F[readop(pc) & 0x1f](ipc, pc, stream); + return (this->*dasm_optable_5F[opcodes.r8(pc) & 0x1f])(ipc, pc, opcodes, stream); } -static int dopC6(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dopC6(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { - return dasm_optable_C6[readop(pc) >> 5](ipc, pc, stream); + return (this->*dasm_optable_C6[opcodes.r8(pc) >> 5])(ipc, pc, opcodes, stream); } -static int dopC7(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dopC7(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { - return dasm_optable_C7[readop(pc) >> 5](ipc, pc, stream); + return (this->*dasm_optable_C7[opcodes.r8(pc) >> 5])(ipc, pc, opcodes, stream); } -static int (*const dasm_optable[256])(unsigned ipc, unsigned pc, std::ostream &stream) = -{ - /* 0x00 */ dopHALT, - /* 0x01 */ dopLDTASK, - /* 0x02 */ dopSTPR, - /* 0x03 */ dopGETRA, - /* 0x04 */ dopGETPTE, - /* 0x05 */ dopGETATE, - /* 0x06 */ dopUNHANDLED, - /* 0x07 */ dopUNHANDLED, - /* 0x08 */ dopRVBIT, - /* 0x09 */ dopMOVB, - /* 0x0A */ dopMOVSBH, - /* 0x0B */ dopMOVZBH, - /* 0x0C */ dopMOVSBW, - /* 0x0D */ dopMOVZBW, - /* 0x0E */ dopUNHANDLED, - /* 0x0F */ dopUNHANDLED, - /* 0x10 */ dopCLRTLBA, - /* 0x11 */ dopUNHANDLED, - /* 0x12 */ dopLDPR, - /* 0x13 */ dopUPDPSWW, - /* 0x14 */ dopUPDPTE, - /* 0x15 */ dopUPDATE, - /* 0x16 */ dopUNHANDLED, - /* 0x17 */ dopUNHANDLED, - /* 0x18 */ dopUNHANDLED, - /* 0x19 */ dopMOVTHB, - /* 0x1A */ dopUNHANDLED, - /* 0x1B */ dopMOVH, - /* 0x1C */ dopMOVSHW, - /* 0x1D */ dopMOVZHW, - /* 0x1E */ dopUNHANDLED, - /* 0x1F */ dopUNHANDLED, - /* 0x20 */ dopINB, - /* 0x21 */ dopOUTB, - /* 0x22 */ dopINH, - /* 0x23 */ dopOUTH, - /* 0x24 */ dopINW, - /* 0x25 */ dopOUTW, - /* 0x26 */ dopUNHANDLED, - /* 0x27 */ dopUNHANDLED, - /* 0x28 */ dopUNHANDLED, - /* 0x29 */ dopMOVTWB, - /* 0x2A */ dopUNHANDLED, - /* 0x2B */ dopMOVTWH, - /* 0x2C */ dopRVBYT, - /* 0x2D */ dopMOVW, - /* 0x2E */ dopUNHANDLED, - /* 0x2F */ dopUNHANDLED, - /* 0x30 */ dopUNHANDLED, - /* 0x31 */ dopUNHANDLED, - /* 0x32 */ dopUNHANDLED, - /* 0x33 */ dopUNHANDLED, - /* 0x34 */ dopUNHANDLED, - /* 0x35 */ dopUNHANDLED, - /* 0x36 */ dopUNHANDLED, - /* 0x37 */ dopUNHANDLED, - /* 0x38 */ dopNOTB, - /* 0x39 */ dopNEGB, - /* 0x3A */ dopNOTH, - /* 0x3B */ dopNEGH, - /* 0x3C */ dopNOTW, - /* 0x3D */ dopNEGW, - /* 0x3E */ dopUNHANDLED, - /* 0x3F */ dopMOVD, - /* 0x40 */ dopMOVEAB, - /* 0x41 */ dopXCHB, - /* 0x42 */ dopMOVEAH, - /* 0x43 */ dopXCHH, - /* 0x44 */ dopMOVEAW, - /* 0x45 */ dopXCHW, - /* 0x46 */ dopUNHANDLED, - /* 0x47 */ dopSETF, - /* 0x48 */ dopBSR, - /* 0x49 */ dopCALL, - /* 0x4A */ dopUPDPSWH, - /* 0x4B */ dopCHLVL, - /* 0x4C */ dopCAXI, - /* 0x4D */ dopCHKAR, - /* 0x4E */ dopCHKAW, - /* 0x4F */ dopCHKAE, - /* 0x50 */ dopREMB, - /* 0x51 */ dopREMUB, - /* 0x52 */ dopREMH, - /* 0x53 */ dopREMUH, - /* 0x54 */ dopREMW, - /* 0x55 */ dopREMUW, - /* 0x56 */ dopUNHANDLED, - /* 0x57 */ dopUNHANDLED, - /* 0x58 */ dop58, - /* 0x59 */ dop59, - /* 0x5A */ dop5A, - /* 0x5B */ dop5B, - /* 0x5C */ dop5C, - /* 0x5D */ dop5D, - /* 0x5E */ dop5E, - /* 0x5F */ dop5F, - /* 0x60 */ dopBV8, - /* 0x61 */ dopBNV8, - /* 0x62 */ dopBL8, - /* 0x63 */ dopBNL8, - /* 0x64 */ dopBE8, - /* 0x65 */ dopBNE8, - /* 0x66 */ dopBNH8, - /* 0x67 */ dopBH8, - /* 0x68 */ dopBN8, - /* 0x69 */ dopBP8, - /* 0x6A */ dopBR8, - /* 0x6B */ dopUNHANDLED, - /* 0x6C */ dopBLT8, - /* 0x6D */ dopBGE8, - /* 0x6E */ dopBLE8, - /* 0x6F */ dopBGT8, - /* 0x70 */ dopBV16, - /* 0x71 */ dopBNV16, - /* 0x72 */ dopBL16, - /* 0x73 */ dopBNL16, - /* 0x74 */ dopBE16, - /* 0x75 */ dopBNE16, - /* 0x76 */ dopBNH16, - /* 0x77 */ dopBH16, - /* 0x78 */ dopBN16, - /* 0x79 */ dopBP16, - /* 0x7A */ dopBR16, - /* 0x7B */ dopUNHANDLED, - /* 0x7C */ dopBLT16, - /* 0x7D */ dopBGE16, - /* 0x7E */ dopBLE16, - /* 0x7F */ dopBGT16, - /* 0x80 */ dopADDB, - /* 0x81 */ dopMULB, - /* 0x82 */ dopADDH, - /* 0x83 */ dopMULH, - /* 0x84 */ dopADDW, - /* 0x85 */ dopMULW, - /* 0x86 */ dopMULX, - /* 0x87 */ dopTEST1, - /* 0x88 */ dopORB, - /* 0x89 */ dopROTB, - /* 0x8A */ dopORH, - /* 0x8B */ dopROTH, - /* 0x8C */ dopORW, - /* 0x8D */ dopROTW, - /* 0x8E */ dopUNHANDLED, - /* 0x8F */ dopUNHANDLED, - /* 0x90 */ dopADDCB, - /* 0x91 */ dopMULUB, - /* 0x92 */ dopADDCH, - /* 0x93 */ dopMULUH, - /* 0x94 */ dopADDCW, - /* 0x95 */ dopMULUW, - /* 0x96 */ dopMULUX, - /* 0x97 */ dopSET1, - /* 0x98 */ dopSUBCB, - /* 0x99 */ dopROTCB, - /* 0x9A */ dopSUBCH, - /* 0x9B */ dopROTCH, - /* 0x9C */ dopSUBCW, - /* 0x9D */ dopROTCW, - /* 0x9E */ dopUNHANDLED, - /* 0x9F */ dopUNHANDLED, - /* 0xA0 */ dopANDB, - /* 0xA1 */ dopDIVB, - /* 0xA2 */ dopANDH, - /* 0xA3 */ dopDIVH, - /* 0xA4 */ dopANDW, - /* 0xA5 */ dopDIVW, - /* 0xA6 */ dopDIVX, - /* 0xA7 */ dopCLR1, - /* 0xA8 */ dopSUBB, - /* 0xA9 */ dopSHLB, - /* 0xAA */ dopSUBH, - /* 0xAB */ dopSHLH, - /* 0xAC */ dopSUBW, - /* 0xAD */ dopSHLW, - /* 0xAE */ dopUNHANDLED, - /* 0xAF */ dopUNHANDLED, - /* 0xB0 */ dopXORB, - /* 0xB1 */ dopDIVUB, - /* 0xB2 */ dopXORH, - /* 0xB3 */ dopDIVUH, - /* 0xB4 */ dopXORW, - /* 0xB5 */ dopDIVUW, - /* 0xB6 */ dopDIVUX, - /* 0xB7 */ dopNOT1, - /* 0xB8 */ dopCMPB, - /* 0xB9 */ dopSHAB, - /* 0xBA */ dopCMPH, - /* 0xBB */ dopSHAH, - /* 0xBC */ dopCMPW, - /* 0xBD */ dopSHAW, - /* 0xBE */ dopUNHANDLED, - /* 0xBF */ dopUNHANDLED, - /* 0xC0 */ dopUNHANDLED, - /* 0xC1 */ dopUNHANDLED, - /* 0xC2 */ dopUNHANDLED, - /* 0xC3 */ dopUNHANDLED, - /* 0xC4 */ dopUNHANDLED, - /* 0xC5 */ dopUNHANDLED, - /* 0xC6 */ dopC6, - /* 0xC7 */ dopC7, - /* 0xC8 */ dopBRK, - /* 0xC9 */ dopBRKV, - /* 0xCA */ dopRSR, - /* 0xCB */ dopTRAPFL, - /* 0xCC */ dopDISPOSE, - /* 0xCD */ dopNOP, - /* 0xCE */ dopUNHANDLED, - /* 0xCF */ dopUNHANDLED, - /* 0xD0 */ dopDECB, - /* 0xD1 */ dopDECB, - /* 0xD2 */ dopDECH, - /* 0xD3 */ dopDECH, - /* 0xD4 */ dopDECW, - /* 0xD5 */ dopDECW, - /* 0xD6 */ dopJMP, - /* 0xD7 */ dopJMP, - /* 0xD8 */ dopINCB, - /* 0xD9 */ dopINCB, - /* 0xDA */ dopINCH, - /* 0xDB */ dopINCH, - /* 0xDC */ dopINCW, - /* 0xDD */ dopINCW, - /* 0xDE */ dopPREPARE, - /* 0xDF */ dopPREPARE, - /* 0xE0 */ dopTASI, - /* 0xE1 */ dopTASI, - /* 0xE2 */ dopRET, - /* 0xE3 */ dopRET, - /* 0xE4 */ dopPOPM, - /* 0xE5 */ dopPOPM, - /* 0xE6 */ dopPOP, - /* 0xE7 */ dopPOP, - /* 0xE8 */ dopJSR, - /* 0xE9 */ dopJSR, - /* 0xEA */ dopRETIU, - /* 0xEB */ dopRETIU, - /* 0xEC */ dopPUSHM, - /* 0xED */ dopPUSHM, - /* 0xEE */ dopPUSH, - /* 0xEF */ dopPUSH, - /* 0xF0 */ dopTESTB, - /* 0xF1 */ dopTESTB, - /* 0xF2 */ dopTESTH, - /* 0xF3 */ dopTESTH, - /* 0xF4 */ dopTESTW, - /* 0xF5 */ dopTESTW, - /* 0xF6 */ dopGETPSW, - /* 0xF7 */ dopGETPSW, - /* 0xF8 */ dopTRAP, - /* 0xF9 */ dopTRAP, - /* 0xFA */ dopRETIS, - /* 0xFB */ dopRETIS, - /* 0xFC */ dopSTTASK, - /* 0xFD */ dopSTTASK, - /* 0xFE */ dopCLRTLB, - /* 0xFF */ dopCLRTLB +u32 (v60_disassembler::*const v60_disassembler::dasm_optable[256])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) = +{ + /* 0x00 */ &v60_disassembler::dopHALT, + /* 0x01 */ &v60_disassembler::dopLDTASK, + /* 0x02 */ &v60_disassembler::dopSTPR, + /* 0x03 */ &v60_disassembler::dopGETRA, + /* 0x04 */ &v60_disassembler::dopGETPTE, + /* 0x05 */ &v60_disassembler::dopGETATE, + /* 0x06 */ &v60_disassembler::dopUNHANDLED, + /* 0x07 */ &v60_disassembler::dopUNHANDLED, + /* 0x08 */ &v60_disassembler::dopRVBIT, + /* 0x09 */ &v60_disassembler::dopMOVB, + /* 0x0A */ &v60_disassembler::dopMOVSBH, + /* 0x0B */ &v60_disassembler::dopMOVZBH, + /* 0x0C */ &v60_disassembler::dopMOVSBW, + /* 0x0D */ &v60_disassembler::dopMOVZBW, + /* 0x0E */ &v60_disassembler::dopUNHANDLED, + /* 0x0F */ &v60_disassembler::dopUNHANDLED, + /* 0x10 */ &v60_disassembler::dopCLRTLBA, + /* 0x11 */ &v60_disassembler::dopUNHANDLED, + /* 0x12 */ &v60_disassembler::dopLDPR, + /* 0x13 */ &v60_disassembler::dopUPDPSWW, + /* 0x14 */ &v60_disassembler::dopUPDPTE, + /* 0x15 */ &v60_disassembler::dopUPDATE, + /* 0x16 */ &v60_disassembler::dopUNHANDLED, + /* 0x17 */ &v60_disassembler::dopUNHANDLED, + /* 0x18 */ &v60_disassembler::dopUNHANDLED, + /* 0x19 */ &v60_disassembler::dopMOVTHB, + /* 0x1A */ &v60_disassembler::dopUNHANDLED, + /* 0x1B */ &v60_disassembler::dopMOVH, + /* 0x1C */ &v60_disassembler::dopMOVSHW, + /* 0x1D */ &v60_disassembler::dopMOVZHW, + /* 0x1E */ &v60_disassembler::dopUNHANDLED, + /* 0x1F */ &v60_disassembler::dopUNHANDLED, + /* 0x20 */ &v60_disassembler::dopINB, + /* 0x21 */ &v60_disassembler::dopOUTB, + /* 0x22 */ &v60_disassembler::dopINH, + /* 0x23 */ &v60_disassembler::dopOUTH, + /* 0x24 */ &v60_disassembler::dopINW, + /* 0x25 */ &v60_disassembler::dopOUTW, + /* 0x26 */ &v60_disassembler::dopUNHANDLED, + /* 0x27 */ &v60_disassembler::dopUNHANDLED, + /* 0x28 */ &v60_disassembler::dopUNHANDLED, + /* 0x29 */ &v60_disassembler::dopMOVTWB, + /* 0x2A */ &v60_disassembler::dopUNHANDLED, + /* 0x2B */ &v60_disassembler::dopMOVTWH, + /* 0x2C */ &v60_disassembler::dopRVBYT, + /* 0x2D */ &v60_disassembler::dopMOVW, + /* 0x2E */ &v60_disassembler::dopUNHANDLED, + /* 0x2F */ &v60_disassembler::dopUNHANDLED, + /* 0x30 */ &v60_disassembler::dopUNHANDLED, + /* 0x31 */ &v60_disassembler::dopUNHANDLED, + /* 0x32 */ &v60_disassembler::dopUNHANDLED, + /* 0x33 */ &v60_disassembler::dopUNHANDLED, + /* 0x34 */ &v60_disassembler::dopUNHANDLED, + /* 0x35 */ &v60_disassembler::dopUNHANDLED, + /* 0x36 */ &v60_disassembler::dopUNHANDLED, + /* 0x37 */ &v60_disassembler::dopUNHANDLED, + /* 0x38 */ &v60_disassembler::dopNOTB, + /* 0x39 */ &v60_disassembler::dopNEGB, + /* 0x3A */ &v60_disassembler::dopNOTH, + /* 0x3B */ &v60_disassembler::dopNEGH, + /* 0x3C */ &v60_disassembler::dopNOTW, + /* 0x3D */ &v60_disassembler::dopNEGW, + /* 0x3E */ &v60_disassembler::dopUNHANDLED, + /* 0x3F */ &v60_disassembler::dopMOVD, + /* 0x40 */ &v60_disassembler::dopMOVEAB, + /* 0x41 */ &v60_disassembler::dopXCHB, + /* 0x42 */ &v60_disassembler::dopMOVEAH, + /* 0x43 */ &v60_disassembler::dopXCHH, + /* 0x44 */ &v60_disassembler::dopMOVEAW, + /* 0x45 */ &v60_disassembler::dopXCHW, + /* 0x46 */ &v60_disassembler::dopUNHANDLED, + /* 0x47 */ &v60_disassembler::dopSETF, + /* 0x48 */ &v60_disassembler::dopBSR, + /* 0x49 */ &v60_disassembler::dopCALL, + /* 0x4A */ &v60_disassembler::dopUPDPSWH, + /* 0x4B */ &v60_disassembler::dopCHLVL, + /* 0x4C */ &v60_disassembler::dopCAXI, + /* 0x4D */ &v60_disassembler::dopCHKAR, + /* 0x4E */ &v60_disassembler::dopCHKAW, + /* 0x4F */ &v60_disassembler::dopCHKAE, + /* 0x50 */ &v60_disassembler::dopREMB, + /* 0x51 */ &v60_disassembler::dopREMUB, + /* 0x52 */ &v60_disassembler::dopREMH, + /* 0x53 */ &v60_disassembler::dopREMUH, + /* 0x54 */ &v60_disassembler::dopREMW, + /* 0x55 */ &v60_disassembler::dopREMUW, + /* 0x56 */ &v60_disassembler::dopUNHANDLED, + /* 0x57 */ &v60_disassembler::dopUNHANDLED, + /* 0x58 */ &v60_disassembler::dop58, + /* 0x59 */ &v60_disassembler::dop59, + /* 0x5A */ &v60_disassembler::dop5A, + /* 0x5B */ &v60_disassembler::dop5B, + /* 0x5C */ &v60_disassembler::dop5C, + /* 0x5D */ &v60_disassembler::dop5D, + /* 0x5E */ &v60_disassembler::dop5E, + /* 0x5F */ &v60_disassembler::dop5F, + /* 0x60 */ &v60_disassembler::dopBV8, + /* 0x61 */ &v60_disassembler::dopBNV8, + /* 0x62 */ &v60_disassembler::dopBL8, + /* 0x63 */ &v60_disassembler::dopBNL8, + /* 0x64 */ &v60_disassembler::dopBE8, + /* 0x65 */ &v60_disassembler::dopBNE8, + /* 0x66 */ &v60_disassembler::dopBNH8, + /* 0x67 */ &v60_disassembler::dopBH8, + /* 0x68 */ &v60_disassembler::dopBN8, + /* 0x69 */ &v60_disassembler::dopBP8, + /* 0x6A */ &v60_disassembler::dopBR8, + /* 0x6B */ &v60_disassembler::dopUNHANDLED, + /* 0x6C */ &v60_disassembler::dopBLT8, + /* 0x6D */ &v60_disassembler::dopBGE8, + /* 0x6E */ &v60_disassembler::dopBLE8, + /* 0x6F */ &v60_disassembler::dopBGT8, + /* 0x70 */ &v60_disassembler::dopBV16, + /* 0x71 */ &v60_disassembler::dopBNV16, + /* 0x72 */ &v60_disassembler::dopBL16, + /* 0x73 */ &v60_disassembler::dopBNL16, + /* 0x74 */ &v60_disassembler::dopBE16, + /* 0x75 */ &v60_disassembler::dopBNE16, + /* 0x76 */ &v60_disassembler::dopBNH16, + /* 0x77 */ &v60_disassembler::dopBH16, + /* 0x78 */ &v60_disassembler::dopBN16, + /* 0x79 */ &v60_disassembler::dopBP16, + /* 0x7A */ &v60_disassembler::dopBR16, + /* 0x7B */ &v60_disassembler::dopUNHANDLED, + /* 0x7C */ &v60_disassembler::dopBLT16, + /* 0x7D */ &v60_disassembler::dopBGE16, + /* 0x7E */ &v60_disassembler::dopBLE16, + /* 0x7F */ &v60_disassembler::dopBGT16, + /* 0x80 */ &v60_disassembler::dopADDB, + /* 0x81 */ &v60_disassembler::dopMULB, + /* 0x82 */ &v60_disassembler::dopADDH, + /* 0x83 */ &v60_disassembler::dopMULH, + /* 0x84 */ &v60_disassembler::dopADDW, + /* 0x85 */ &v60_disassembler::dopMULW, + /* 0x86 */ &v60_disassembler::dopMULX, + /* 0x87 */ &v60_disassembler::dopTEST1, + /* 0x88 */ &v60_disassembler::dopORB, + /* 0x89 */ &v60_disassembler::dopROTB, + /* 0x8A */ &v60_disassembler::dopORH, + /* 0x8B */ &v60_disassembler::dopROTH, + /* 0x8C */ &v60_disassembler::dopORW, + /* 0x8D */ &v60_disassembler::dopROTW, + /* 0x8E */ &v60_disassembler::dopUNHANDLED, + /* 0x8F */ &v60_disassembler::dopUNHANDLED, + /* 0x90 */ &v60_disassembler::dopADDCB, + /* 0x91 */ &v60_disassembler::dopMULUB, + /* 0x92 */ &v60_disassembler::dopADDCH, + /* 0x93 */ &v60_disassembler::dopMULUH, + /* 0x94 */ &v60_disassembler::dopADDCW, + /* 0x95 */ &v60_disassembler::dopMULUW, + /* 0x96 */ &v60_disassembler::dopMULUX, + /* 0x97 */ &v60_disassembler::dopSET1, + /* 0x98 */ &v60_disassembler::dopSUBCB, + /* 0x99 */ &v60_disassembler::dopROTCB, + /* 0x9A */ &v60_disassembler::dopSUBCH, + /* 0x9B */ &v60_disassembler::dopROTCH, + /* 0x9C */ &v60_disassembler::dopSUBCW, + /* 0x9D */ &v60_disassembler::dopROTCW, + /* 0x9E */ &v60_disassembler::dopUNHANDLED, + /* 0x9F */ &v60_disassembler::dopUNHANDLED, + /* 0xA0 */ &v60_disassembler::dopANDB, + /* 0xA1 */ &v60_disassembler::dopDIVB, + /* 0xA2 */ &v60_disassembler::dopANDH, + /* 0xA3 */ &v60_disassembler::dopDIVH, + /* 0xA4 */ &v60_disassembler::dopANDW, + /* 0xA5 */ &v60_disassembler::dopDIVW, + /* 0xA6 */ &v60_disassembler::dopDIVX, + /* 0xA7 */ &v60_disassembler::dopCLR1, + /* 0xA8 */ &v60_disassembler::dopSUBB, + /* 0xA9 */ &v60_disassembler::dopSHLB, + /* 0xAA */ &v60_disassembler::dopSUBH, + /* 0xAB */ &v60_disassembler::dopSHLH, + /* 0xAC */ &v60_disassembler::dopSUBW, + /* 0xAD */ &v60_disassembler::dopSHLW, + /* 0xAE */ &v60_disassembler::dopUNHANDLED, + /* 0xAF */ &v60_disassembler::dopUNHANDLED, + /* 0xB0 */ &v60_disassembler::dopXORB, + /* 0xB1 */ &v60_disassembler::dopDIVUB, + /* 0xB2 */ &v60_disassembler::dopXORH, + /* 0xB3 */ &v60_disassembler::dopDIVUH, + /* 0xB4 */ &v60_disassembler::dopXORW, + /* 0xB5 */ &v60_disassembler::dopDIVUW, + /* 0xB6 */ &v60_disassembler::dopDIVUX, + /* 0xB7 */ &v60_disassembler::dopNOT1, + /* 0xB8 */ &v60_disassembler::dopCMPB, + /* 0xB9 */ &v60_disassembler::dopSHAB, + /* 0xBA */ &v60_disassembler::dopCMPH, + /* 0xBB */ &v60_disassembler::dopSHAH, + /* 0xBC */ &v60_disassembler::dopCMPW, + /* 0xBD */ &v60_disassembler::dopSHAW, + /* 0xBE */ &v60_disassembler::dopUNHANDLED, + /* 0xBF */ &v60_disassembler::dopUNHANDLED, + /* 0xC0 */ &v60_disassembler::dopUNHANDLED, + /* 0xC1 */ &v60_disassembler::dopUNHANDLED, + /* 0xC2 */ &v60_disassembler::dopUNHANDLED, + /* 0xC3 */ &v60_disassembler::dopUNHANDLED, + /* 0xC4 */ &v60_disassembler::dopUNHANDLED, + /* 0xC5 */ &v60_disassembler::dopUNHANDLED, + /* 0xC6 */ &v60_disassembler::dopC6, + /* 0xC7 */ &v60_disassembler::dopC7, + /* 0xC8 */ &v60_disassembler::dopBRK, + /* 0xC9 */ &v60_disassembler::dopBRKV, + /* 0xCA */ &v60_disassembler::dopRSR, + /* 0xCB */ &v60_disassembler::dopTRAPFL, + /* 0xCC */ &v60_disassembler::dopDISPOSE, + /* 0xCD */ &v60_disassembler::dopNOP, + /* 0xCE */ &v60_disassembler::dopUNHANDLED, + /* 0xCF */ &v60_disassembler::dopUNHANDLED, + /* 0xD0 */ &v60_disassembler::dopDECB, + /* 0xD1 */ &v60_disassembler::dopDECB, + /* 0xD2 */ &v60_disassembler::dopDECH, + /* 0xD3 */ &v60_disassembler::dopDECH, + /* 0xD4 */ &v60_disassembler::dopDECW, + /* 0xD5 */ &v60_disassembler::dopDECW, + /* 0xD6 */ &v60_disassembler::dopJMP, + /* 0xD7 */ &v60_disassembler::dopJMP, + /* 0xD8 */ &v60_disassembler::dopINCB, + /* 0xD9 */ &v60_disassembler::dopINCB, + /* 0xDA */ &v60_disassembler::dopINCH, + /* 0xDB */ &v60_disassembler::dopINCH, + /* 0xDC */ &v60_disassembler::dopINCW, + /* 0xDD */ &v60_disassembler::dopINCW, + /* 0xDE */ &v60_disassembler::dopPREPARE, + /* 0xDF */ &v60_disassembler::dopPREPARE, + /* 0xE0 */ &v60_disassembler::dopTASI, + /* 0xE1 */ &v60_disassembler::dopTASI, + /* 0xE2 */ &v60_disassembler::dopRET, + /* 0xE3 */ &v60_disassembler::dopRET, + /* 0xE4 */ &v60_disassembler::dopPOPM, + /* 0xE5 */ &v60_disassembler::dopPOPM, + /* 0xE6 */ &v60_disassembler::dopPOP, + /* 0xE7 */ &v60_disassembler::dopPOP, + /* 0xE8 */ &v60_disassembler::dopJSR, + /* 0xE9 */ &v60_disassembler::dopJSR, + /* 0xEA */ &v60_disassembler::dopRETIU, + /* 0xEB */ &v60_disassembler::dopRETIU, + /* 0xEC */ &v60_disassembler::dopPUSHM, + /* 0xED */ &v60_disassembler::dopPUSHM, + /* 0xEE */ &v60_disassembler::dopPUSH, + /* 0xEF */ &v60_disassembler::dopPUSH, + /* 0xF0 */ &v60_disassembler::dopTESTB, + /* 0xF1 */ &v60_disassembler::dopTESTB, + /* 0xF2 */ &v60_disassembler::dopTESTH, + /* 0xF3 */ &v60_disassembler::dopTESTH, + /* 0xF4 */ &v60_disassembler::dopTESTW, + /* 0xF5 */ &v60_disassembler::dopTESTW, + /* 0xF6 */ &v60_disassembler::dopGETPSW, + /* 0xF7 */ &v60_disassembler::dopGETPSW, + /* 0xF8 */ &v60_disassembler::dopTRAP, + /* 0xF9 */ &v60_disassembler::dopTRAP, + /* 0xFA */ &v60_disassembler::dopRETIS, + /* 0xFB */ &v60_disassembler::dopRETIS, + /* 0xFC */ &v60_disassembler::dopSTTASK, + /* 0xFD */ &v60_disassembler::dopSTTASK, + /* 0xFE */ &v60_disassembler::dopCLRTLB, + /* 0xFF */ &v60_disassembler::dopCLRTLB }; -CPU_DISASSEMBLE(v60) +offs_t v60_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - rombase = oprom; - pcbase = pc; - return dasm_optable[oprom[0]](pc, pc+1, stream) | DASMFLAG_SUPPORTED; + return (this->*dasm_optable[opcodes.r8(pc)])(pc, pc+1, opcodes, stream) | SUPPORTED; } -CPU_DISASSEMBLE(v70) +u32 v60_disassembler::opcode_alignment() const { - rombase = oprom; - pcbase = pc; - return dasm_optable[oprom[0]](pc, pc+1, stream) | DASMFLAG_SUPPORTED; + return 1; } diff --git a/src/devices/cpu/v60/v60d.h b/src/devices/cpu/v60/v60d.h new file mode 100644 index 00000000000..6bbef76f47c --- /dev/null +++ b/src/devices/cpu/v60/v60d.h @@ -0,0 +1,359 @@ +// license:BSD-3-Clause +// copyright-holders:Farfetch'd, R. Belmont + +#ifndef MAME_CPU_V60_V60D_H +#define MAME_CPU_V60_V60D_H + +#pragma once + +class v60_disassembler : public util::disasm_interface +{ +public: + v60_disassembler() = default; + virtual ~v60_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *const v60_reg_names[69]; + static u32 (v60_disassembler::*const dasm_optable_58[32])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + static u32 (v60_disassembler::*const dasm_optable_59[32])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + static u32 (v60_disassembler::*const dasm_optable_5A[32])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + static u32 (v60_disassembler::*const dasm_optable_5B[32])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + static u32 (v60_disassembler::*const dasm_optable_5C[32])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + static u32 (v60_disassembler::*const dasm_optable_5D[32])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + static u32 (v60_disassembler::*const dasm_optable_5E[32])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + static u32 (v60_disassembler::*const dasm_optable_5F[32])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + static u32 (v60_disassembler::*const dasm_optable_C6[8])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + static u32 (v60_disassembler::*const dasm_optable_C7[8])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + static u32 (v60_disassembler::*const dasm_optable[256])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + + u32 dop58(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dop58UNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dop59(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dop59UNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dop5A(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dop5AUNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dop5B(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dop5BUNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dop5C(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dop5CUNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dop5D(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dop5DUNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dop5E(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dop5EUNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dop5F(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dop5FUNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopABSFL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopABSFS(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopADDB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopADDCB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopADDCH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopADDCW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopADDDC(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopADDFL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopADDFS(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopADDH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopADDW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopANDB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopANDBSD(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopANDBSU(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopANDH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopANDNBSD(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopANDNBSU(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopANDW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBE16(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBE8(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBGE16(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBGE8(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBGT16(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBGT8(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBH16(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBH8(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBL16(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBL8(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBLE16(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBLE8(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBLT16(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBLT8(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBN16(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBN8(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBNE16(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBNE8(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBNH16(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBNH8(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBNL16(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBNL8(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBNV16(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBNV8(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBP16(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBP8(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBR16(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBR8(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBRK(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBRKV(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBSR(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBV16(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBV8(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopC6(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopC7(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCALL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCAXI(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCHKAE(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCHKAR(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCHKAW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCHLVL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCLR1(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCLRTLB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCLRTLBA(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCMPB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCMPBFL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCMPBFS(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCMPBFZ(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCMPCB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCMPCFB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCMPCFH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCMPCH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCMPCSB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCMPCSH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCMPFL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCMPFS(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCMPH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCMPW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCVTDPZ(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCVTDZP(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCVTLS(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCVTLW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCVTSL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCVTSW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCVTWL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCVTWS(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDBE(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDBGE(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDBGT(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDBH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDBL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDBLE(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDBLT(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDBN(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDBNE(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDBNH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDBNL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDBNV(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDBP(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDBR(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDBV(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDECB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDECH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDECW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDISPOSE(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDIVB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDIVFL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDIVFS(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDIVH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDIVUB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDIVUH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDIVUW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDIVUX(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDIVW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDIVX(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopEXTBFL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopEXTBFS(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopEXTBFZ(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopGETATE(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopGETPSW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopGETPTE(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopGETRA(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopHALT(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopINB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopINCB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopINCH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopINCW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopINH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopINSBFL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopINSBFR(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopINW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopJMP(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopJSR(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopLDPR(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopLDTASK(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVBSD(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVBSU(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVCDB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVCDH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVCFDB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVCFDH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVCFUB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVCFUH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVCSB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVCSH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVCUB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVCUH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVD(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVEAB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVEAH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVEAW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVFL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVFS(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVSBH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVSBW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVSHW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVTHB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVTWB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVTWH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVZBH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVZBW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVZHW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMULB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMULFL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMULFS(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMULH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMULUB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMULUH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMULUW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMULUX(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMULW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMULX(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopNEGB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopNEGFL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopNEGFS(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopNEGH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopNEGW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopNOP(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopNOT1(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopNOTB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopNOTBSD(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopNOTBSU(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopNOTH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopNOTW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopORB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopORBSD(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopORBSU(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopORH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopORNBSD(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopORNBSU(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopORW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopOUTB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopOUTH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopOUTW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopPOP(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopPOPM(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopPREPARE(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopPUSH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopPUSHM(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopREMB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopREMH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopREMUB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopREMUH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopREMUW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopREMW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopRET(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopRETIS(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopRETIU(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopROTB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopROTCB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopROTCH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopROTCW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopROTH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopROTW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopRSR(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopRVBIT(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopRVBYT(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSCH0BSD(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSCH0BSU(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSCH1BSD(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSCH1BSU(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSCHCDB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSCHCDH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSCHCUB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSCHCUH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSCLFL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSCLFS(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSET1(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSETF(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSHAB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSHAH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSHAW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSHLB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSHLH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSHLW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSKPCDB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSKPCDH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSKPCUB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSKPCUH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSTPR(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSTTASK(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSUBB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSUBCB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSUBCH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSUBCW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSUBDC(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSUBFL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSUBFS(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSUBH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSUBRDC(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSUBW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopTASI(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopTB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopTEST1(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopTESTB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopTESTH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopTESTW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopTRAP(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopTRAPFL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopUNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopUPDATE(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopUPDPSWH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopUPDPSWW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopUPDPTE(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopXCHB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopXCHH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopXCHW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopXORB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopXORBSD(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopXORBSU(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopXORH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopXORNBSD(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopXORNBSU(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopXORW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + + void out_AM_Register(int reg, std::ostream &stream); + void out_AM_RegisterIndirect(int reg, int opsize, std::ostream &stream); + void out_AM_RegisterIndirectIndexed(int rn, int rx, int opsize, std::ostream &stream); + void out_AM_Autoincrement(int reg, int opsize, std::ostream &stream); + void out_AM_Autodecrement(int reg, int opsize, std::ostream &stream); + void out_AM_Displacement(int reg, int disp, int opsize, std::ostream &stream); + void out_AM_DisplacementIndexed(int rn, int rx, int disp, int opsize, std::ostream &stream); + void out_AM_PCDisplacement(offs_t pc, int disp, int opsize, std::ostream &stream); + void out_AM_PCDisplacementIndexed(offs_t pc, int disp, int rx, int opsize, std::ostream &stream); + void out_AM_DisplacementIndirect(int reg, int disp, int opsize, std::ostream &stream); + void out_AM_DisplacementIndirectIndexed(int rn, int rx, int disp, int opsize, std::ostream &stream); + void out_AM_PCDisplacementIndirect(offs_t pc, int disp, int opsize, std::ostream &stream); + void out_AM_PCDisplacementIndirectIndexed(offs_t pc, int disp, int rx, int opsize, std::ostream &stream); + void out_AM_DoubleDisplacement(int reg, int disp2, int disp1, int opsize, std::ostream &stream); + void out_AM_PCDoubleDisplacement(offs_t pc, int disp2, int disp1, int opsize, std::ostream &stream); + void out_AM_DirectAddress(unsigned addr, int opsize, std::ostream &stream); + void out_AM_DirectAddressIndexed(unsigned addr, int rx, int opsize, std::ostream &stream); + void out_AM_DirectAddressDeferred(unsigned addr, int opsize, std::ostream &stream); + void out_AM_DirectAddressDeferredIndexed(unsigned addr, int rx, int opsize, std::ostream &stream); + void out_AM_Immediate(unsigned value, int opsize, std::ostream &stream); + u32 decode_AM(unsigned ipc, offs_t pc, int m, int opsize, const data_buffer &opcodes, std::ostream &stream); + u32 decode_F1(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 decode_F2(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 decode_F1F2(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 decode_F3(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 decode_F4a(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 decode_F4b(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 decode_F5(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 decode_F6(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 decode_F7a(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 decode_F7b(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 decode_F7c(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + +}; + +#endif diff --git a/src/devices/cpu/v810/v810.cpp b/src/devices/cpu/v810/v810.cpp index fc6aa5897fe..a7662cb251d 100644 --- a/src/devices/cpu/v810/v810.cpp +++ b/src/devices/cpu/v810/v810.cpp @@ -29,6 +29,7 @@ #include "emu.h" #include "v810.h" +#include "v810dasm.h" #include "debugger.h" #define clkIF 3 @@ -54,10 +55,9 @@ device_memory_interface::space_config_vector v810_device::memory_space_config() } -offs_t v810_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *v810_device::create_disassembler() { - extern CPU_DISASSEMBLE( v810 ); - return CPU_DISASSEMBLE_NAME(v810)(this, stream, pc, oprom, opram, options); + return new v810_disassembler; } @@ -1256,7 +1256,7 @@ const v810_device::opcode_func v810_device::s_OpCodeTable[64] = void v810_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); m_irq_line = 0; diff --git a/src/devices/cpu/v810/v810.h b/src/devices/cpu/v810/v810.h index e136259cc4a..ad2e91a6617 100644 --- a/src/devices/cpu/v810/v810.h +++ b/src/devices/cpu/v810/v810.h @@ -104,9 +104,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 4; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: typedef uint32_t (v810_device::*opcode_func)(uint32_t op); @@ -120,7 +118,7 @@ private: uint8_t m_irq_state; uint8_t m_nmi_line; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_io; uint32_t m_PPC; int m_icount; diff --git a/src/devices/cpu/v810/v810dasm.cpp b/src/devices/cpu/v810/v810dasm.cpp index b88600d353e..3e8410881d5 100644 --- a/src/devices/cpu/v810/v810dasm.cpp +++ b/src/devices/cpu/v810/v810dasm.cpp @@ -6,8 +6,7 @@ *******************************************/ #include "emu.h" -#include "debugger.h" -#include "v810.h" +#include "v810dasm.h" #define I5(x) (((x)&0x1f)|(((x)&0x10)?0xffffffe0:0)) #define UI5(x) ((x)&0x1f) @@ -17,7 +16,7 @@ #define D26(x,y) ((y)|((x&0x3ff)<<16 )|((x&0x200)?0xfc000000:0)) #define D9(x) ((x&0x1ff)|((x&0x100)?0xfffffe00:0)) -static const char *const dRegs[]= +const char *const v810_disassembler::dRegs[]= { "R0","R1","R2","SP","R4", "R5","R6","R7","R8","R9", @@ -39,13 +38,18 @@ static const char *const dRegs[]= #define GET2s(opcode) dRegs[((opcode)>>5)&0x1f] #define GETRs(opcode) dRegs[32+((opcode)&0x1f)] -CPU_DISASSEMBLE(v810) +u32 v810_disassembler::opcode_alignment() const +{ + return 2; +} + +offs_t v810_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint32_t flags = 0; uint32_t opc,opc2; unsigned size; - opc = oprom[0] | (oprom[1] << 8); - opc2 = oprom[2] | (oprom[3] << 8); + opc = opcodes.r16(pc); + opc2 = opcodes.r16(pc+2); switch(opc>>10) { @@ -55,7 +59,7 @@ CPU_DISASSEMBLE(v810) case 0x03: util::stream_format(stream,"CMP %s,%s",GET1s(opc),GET2s(opc)); size=2; break; case 0x04: util::stream_format(stream,"SHL %s,%s",GET1s(opc),GET2s(opc)); size=2; break; case 0x05: util::stream_format(stream,"SHR %s,%s",GET1s(opc),GET2s(opc)); size=2; break; - case 0x06: util::stream_format(stream,"JMP [%s]",GET1s(opc)); size=2; if ((opc&0x1f) == 31) flags = DASMFLAG_STEP_OUT; break; + case 0x06: util::stream_format(stream,"JMP [%s]",GET1s(opc)); size=2; if ((opc&0x1f) == 31) flags = STEP_OUT; break; case 0x07: util::stream_format(stream,"SAR %s,%s",GET1s(opc),GET2s(opc)); size=2; break; case 0x08: util::stream_format(stream,"MUL %s,%s",GET1s(opc),GET2s(opc)); size=2; break; case 0x09: util::stream_format(stream,"DIV %s,%s",GET1s(opc),GET2s(opc)); size=2; break; @@ -74,7 +78,7 @@ CPU_DISASSEMBLE(v810) case 0x16: util::stream_format(stream,"EI"); size=2; break; case 0x17: util::stream_format(stream,"SAR %X,%s",UI5(opc),GET2s(opc)); size=2; break; case 0x18: util::stream_format(stream,"TRAP %X",I5(opc)); size=2; break; - case 0x19: util::stream_format(stream,"RETI"); size=2; flags = DASMFLAG_STEP_OUT; break; + case 0x19: util::stream_format(stream,"RETI"); size=2; flags = STEP_OUT; break; case 0x1a: util::stream_format(stream,"HALT"); size=2; break; case 0x1b: util::stream_format(stream,"Unk 0x1B"); size=2; break; case 0x1c: util::stream_format(stream,"LDSR %s,%s",GET2s(opc),GETRs(opc));size=2; break; @@ -134,7 +138,7 @@ CPU_DISASSEMBLE(v810) case 0x28: util::stream_format(stream,"MOVEA %X, %s, %s",I16(opc2),GET1s(opc),GET2s(opc));size=4; break; case 0x29: util::stream_format(stream,"ADDI %X, %s, %s",I16(opc2),GET1s(opc),GET2s(opc));size=4; break; case 0x2a: util::stream_format(stream,"JR %X",pc+D26(opc,opc2));size=4; break; - case 0x2b: util::stream_format(stream,"JAL %X",pc+D26(opc,opc2));size=4; flags = DASMFLAG_STEP_OVER; break; + case 0x2b: util::stream_format(stream,"JAL %X",pc+D26(opc,opc2));size=4; flags = STEP_OVER; break; case 0x2c: util::stream_format(stream,"ORI %X, %s, %s",UI16(opc2),GET1s(opc),GET2s(opc));size=4; break; case 0x2d: util::stream_format(stream,"ANDI %X, %s, %s",UI16(opc2),GET1s(opc),GET2s(opc));size=4; break; case 0x2e: util::stream_format(stream,"XORI %X, %s, %s",UI16(opc2),GET1s(opc),GET2s(opc));size=4; break; @@ -173,5 +177,5 @@ CPU_DISASSEMBLE(v810) default : size=2; } - return size | flags | DASMFLAG_SUPPORTED; + return size | flags | SUPPORTED; } diff --git a/src/devices/cpu/v810/v810dasm.h b/src/devices/cpu/v810/v810dasm.h new file mode 100644 index 00000000000..3daed05a131 --- /dev/null +++ b/src/devices/cpu/v810/v810dasm.h @@ -0,0 +1,27 @@ +// license:BSD-3-Clause +// copyright-holders:Tomasz Slanina +/******************************************** + NEC V810 (upd70732) disassembler + Tomasz Slanina - analog[at]op.pl +*******************************************/ + + +#ifndef MAME_CPU_V810_V810DASM_H +#define MAME_CPU_V810_V810DASM_H + +#pragma once + +class v810_disassembler : public util::disasm_interface +{ +public: + v810_disassembler() = default; + virtual ~v810_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *const dRegs[]; +}; + +#endif diff --git a/src/devices/cpu/x86log.cpp b/src/devices/cpu/x86log.cpp index 03552877128..b97f2553f11 100644 --- a/src/devices/cpu/x86log.cpp +++ b/src/devices/cpu/x86log.cpp @@ -96,6 +96,30 @@ void x86log_mark_as_data(x86log_context *log, x86code *base, x86code *end, int s of code and reset accumulated information -------------------------------------------------*/ +namespace { + class x86_buf : public util::disasm_interface::data_buffer { + public: + x86_buf(offs_t _base_pc, const u8 *_buf) : base_pc(_base_pc), buf(_buf) {} + ~x86_buf() = default; + + // We know we're on a x86, so we can go short + virtual u8 r8 (offs_t pc) const override { return *(u8 *)(buf + pc - base_pc); } + virtual u16 r16(offs_t pc) const override { return *(u16 *)(buf + pc - base_pc); } + virtual u32 r32(offs_t pc) const override { return *(u32 *)(buf + pc - base_pc); } + virtual u64 r64(offs_t pc) const override { return *(u64 *)(buf + pc - base_pc); } + + private: + offs_t base_pc; + const u8 *buf; + }; + + class x86_config : public i386_disassembler::config { + public: + ~x86_config() = default; + virtual int get_mode() const override { return sizeof(void *) * 8; }; + }; +} + void x86log_disasm_code_range(x86log_context *log, const char *label, x86code *start, x86code *stop) { const log_comment *lastcomment = &log->comment_list[log->comment_count]; @@ -147,7 +171,11 @@ void x86log_disasm_code_range(x86log_context *log, const char *label, x86code *s else { std::stringstream strbuffer; - bytes = i386_dasm_one_ex(strbuffer, (uintptr_t)cur, cur, sizeof(void *) * 8) & DASMFLAG_LENGTHMASK; + offs_t pc = (uintptr_t)cur; + x86_buf buf(pc, cur); + x86_config conf; + i386_disassembler dis(&conf); + bytes = dis.disassemble(strbuffer, pc, buf, buf) & util::disasm_interface::LENGTHMASK; buffer = strbuffer.str(); } diff --git a/src/devices/cpu/z180/z180.cpp b/src/devices/cpu/z180/z180.cpp index a1dda238c60..ba25e51152e 100644 --- a/src/devices/cpu/z180/z180.cpp +++ b/src/devices/cpu/z180/z180.cpp @@ -34,7 +34,7 @@ Package: P = 60-Pin Plastic DIP Temp: S = 0C to +70C E = -40C to +85C -Environmanetal Flow: C = Plastic Standard +Environmental Flow: C = Plastic Standard Example from Ms.Pac-Man/Galaga - 20 year Reunion hardare (see src/mame/drivers/20pacgal.c): @@ -52,6 +52,7 @@ Hitachi HD647180 series: #include "emu.h" #include "z180.h" +#include "z180dasm.h" #include "debugger.h" //#define VERBOSE 1 @@ -89,14 +90,11 @@ z180_device::z180_device(const machine_config &mconfig, const char *tag, device_ { } - -offs_t z180_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *z180_device::create_disassembler() { - extern CPU_DISASSEMBLE( z180 ); - return CPU_DISASSEMBLE_NAME(z180)(this, stream, pc, oprom, opram, options); + return new z180_disassembler; } - #define CF 0x01 #define NF 0x02 #define PF 0x04 @@ -683,7 +681,7 @@ bool z180_device::get_tend1() /* 36 refresh control register */ #define Z180_RCR_REFE 0x80 -#define Z180_RCR_REFW 0x80 +#define Z180_RCR_REFW 0x40 #define Z180_RCR_CYC 0x03 #define Z180_RCR_RESET 0xc0 @@ -1602,6 +1600,7 @@ int z180_device::z180_dma0(int max_cycles) while (count > 0) { + m_extra_cycles = 0; /* last transfer happening now? */ if (bcr0 == 1) { @@ -1611,20 +1610,24 @@ int z180_device::z180_dma0(int max_cycles) { case 0x00: /* memory SAR0+1 to memory DAR0+1 */ m_program->write_byte(dar0++, m_program->read_byte(sar0++)); + cycles += (IO_DCNTL >> 6) * 2; // memory wait states bcr0--; break; case 0x04: /* memory SAR0-1 to memory DAR0+1 */ m_program->write_byte(dar0++, m_program->read_byte(sar0--)); + cycles += (IO_DCNTL >> 6) * 2; // memory wait states bcr0--; break; case 0x08: /* memory SAR0 fixed to memory DAR0+1 */ m_program->write_byte(dar0++, m_program->read_byte(sar0)); + cycles += (IO_DCNTL >> 6) * 2; // memory wait states bcr0--; break; case 0x0c: /* I/O SAR0 fixed to memory DAR0+1 */ if (m_iol & Z180_DREQ0) { m_program->write_byte(dar0++, IN(sar0)); + cycles += IO_DCNTL >> 6; // memory wait states bcr0--; /* edge sensitive DREQ0 ? */ if (IO_DCNTL & Z180_DCNTL_DMS0) @@ -1636,20 +1639,24 @@ int z180_device::z180_dma0(int max_cycles) break; case 0x10: /* memory SAR0+1 to memory DAR0-1 */ m_program->write_byte(dar0--, m_program->read_byte(sar0++)); + cycles += (IO_DCNTL >> 6) * 2; // memory wait states bcr0--; break; case 0x14: /* memory SAR0-1 to memory DAR0-1 */ m_program->write_byte(dar0--, m_program->read_byte(sar0--)); + cycles += (IO_DCNTL >> 6) * 2; // memory wait states bcr0--; break; case 0x18: /* memory SAR0 fixed to memory DAR0-1 */ m_program->write_byte(dar0--, m_program->read_byte(sar0)); + cycles += (IO_DCNTL >> 6) * 2; // memory wait states bcr0--; break; case 0x1c: /* I/O SAR0 fixed to memory DAR0-1 */ if (m_iol & Z180_DREQ0) { m_program->write_byte(dar0--, IN(sar0)); + cycles += IO_DCNTL >> 6; // memory wait states bcr0--; /* edge sensitive DREQ0 ? */ if (IO_DCNTL & Z180_DCNTL_DMS0) @@ -1661,10 +1668,12 @@ int z180_device::z180_dma0(int max_cycles) break; case 0x20: /* memory SAR0+1 to memory DAR0 fixed */ m_program->write_byte(dar0, m_program->read_byte(sar0++)); + cycles += (IO_DCNTL >> 6) * 2; // memory wait states bcr0--; break; case 0x24: /* memory SAR0-1 to memory DAR0 fixed */ m_program->write_byte(dar0, m_program->read_byte(sar0--)); + cycles += (IO_DCNTL >> 6) * 2; // memory wait states bcr0--; break; case 0x28: /* reserved */ @@ -1675,6 +1684,7 @@ int z180_device::z180_dma0(int max_cycles) if (m_iol & Z180_DREQ0) { OUT(dar0, m_program->read_byte(sar0++)); + cycles += IO_DCNTL >> 6; // memory wait states bcr0--; /* edge sensitive DREQ0 ? */ if (IO_DCNTL & Z180_DCNTL_DMS0) @@ -1688,6 +1698,7 @@ int z180_device::z180_dma0(int max_cycles) if (m_iol & Z180_DREQ0) { OUT(dar0, m_program->read_byte(sar0--)); + cycles += IO_DCNTL >> 6; // memory wait states bcr0--; /* edge sensitive DREQ0 ? */ if (IO_DCNTL & Z180_DCNTL_DMS0) @@ -1703,7 +1714,7 @@ int z180_device::z180_dma0(int max_cycles) break; } count--; - cycles += 6; + cycles += 6 + m_extra_cycles; // use extra_cycles for I/O wait states if (cycles > max_cycles) break; } @@ -1756,6 +1767,8 @@ int z180_device::z180_dma1() m_iol |= Z180_TEND1; } + m_extra_cycles = 0; + switch (IO_DCNTL & (Z180_DCNTL_DIM1 | Z180_DCNTL_DIM0)) { case 0x00: /* memory MAR1+1 to I/O IAR1 fixed */ @@ -1772,6 +1785,9 @@ int z180_device::z180_dma1() break; } + cycles += IO_DCNTL >> 6; // memory wait states + cycles += m_extra_cycles; // use extra_cycles for I/O wait states + /* edge sensitive DREQ1 ? */ if (IO_DCNTL & Z180_DCNTL_DIM1) m_iol &= ~Z180_DREQ1; @@ -1919,7 +1935,6 @@ void z180_device::z180_write_iolines(uint32_t data) } } - void z180_device::device_start() { int i, p; @@ -2001,9 +2016,9 @@ void z180_device::device_start() } m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_oprogram = has_space(AS_OPCODES) ? &space(AS_OPCODES) : m_program; - m_odirect = &m_oprogram->direct(); + m_odirect = m_oprogram->direct<0>(); m_iospace = &space(AS_IO); /* set up the state table */ @@ -2503,14 +2518,16 @@ again: ****************************************************************************/ void z180_device::execute_burn(int32_t cycles) { + int extra_cycles = IO_DCNTL >> 6; // memory wait states + /* FIXME: This is not appropriate for dma */ while ( (cycles > 0) ) { - handle_io_timers(3); + handle_io_timers(3 + extra_cycles); /* NOP takes 3 cycles per instruction */ m_R += 1; - m_icount -= 3; - cycles -= 3; + m_icount -= 3 + extra_cycles; + cycles -= 3 + extra_cycles; } } @@ -2538,12 +2555,12 @@ void z180_device::execute_set_input(int irqline, int state) /* the main execute loop will take the interrupt */ } else if(irqline == Z180_INPUT_LINE_DREQ0) { - auto iol = m_iol & ~Z180_DREQ0; + uint32_t iol = m_iol & ~Z180_DREQ0; if(state == ASSERT_LINE) iol |= Z180_DREQ0; z180_write_iolines(iol); } else if(irqline == Z180_INPUT_LINE_DREQ1) { - auto iol = m_iol & ~Z180_DREQ1; + uint32_t iol = m_iol & ~Z180_DREQ1; if(state == ASSERT_LINE) iol |= Z180_DREQ1; z180_write_iolines(iol); diff --git a/src/devices/cpu/z180/z180.h b/src/devices/cpu/z180/z180.h index dca5c963539..57ee654efa8 100644 --- a/src/devices/cpu/z180/z180.h +++ b/src/devices/cpu/z180/z180.h @@ -158,9 +158,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 4; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -188,9 +186,9 @@ private: uint8_t m_dma0_cnt; /* dma0 counter / divide by 20 */ uint8_t m_dma1_cnt; /* dma1 counter / divide by 20 */ address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_oprogram; - direct_read_data *m_odirect; + direct_read_data<0> *m_odirect; address_space *m_iospace; uint8_t m_rtemp; uint32_t m_ioltemp; @@ -202,6 +200,9 @@ private: static const opcode_func s_z180ops[6][0x100]; inline void z180_mmu(); + inline u8 RM(offs_t addr); + inline u8 IN(u16 port); + inline void OUT(u16 port, u8 value); inline void RM16( offs_t addr, PAIR *r ); inline void WM16( offs_t addr, PAIR *r ); inline uint8_t ROP(); diff --git a/src/devices/cpu/z180/z180dasm.cpp b/src/devices/cpu/z180/z180dasm.cpp index c5a3d9f0186..521ec1bfe41 100644 --- a/src/devices/cpu/z180/z180dasm.cpp +++ b/src/devices/cpu/z180/z180dasm.cpp @@ -8,23 +8,9 @@ *****************************************************************************/ #include "emu.h" -#include "debugger.h" -#include "z180.h" +#include "z180dasm.h" -enum e_mnemonics { - zADC ,zADD ,zAND ,zBIT ,zCALL ,zCCF ,zCP ,zCPD , - zCPDR ,zCPI ,zCPIR ,zCPL ,zDAA ,zDB ,zDEC ,zDI , - zDJNZ ,zEI ,zEX ,zEXX ,zHLT ,zIM ,zIN ,zIN0 , - zINC ,zIND ,zINDR ,zINI ,zINIR ,zJP ,zJR ,zLD , - zLDD ,zLDDR ,zLDI ,zLDIR ,zMLT ,zNEG ,zNOP ,zOR , - zOTDM ,zOTDMR ,zOTDR ,zOTIM ,zOTIMR ,zOTIR ,zOUT ,zOUT0 , - zOUTD ,zOUTI ,zPOP ,zPUSH ,zRES ,zRET ,zRETI ,zRETN , - zRL ,zRLA ,zRLC ,zRLCA ,zRLD ,zRR ,zRRA ,zRRC , - zRRCA ,zRRD ,zRST ,zSBC ,zSCF ,zSET ,zSLA ,zSLL , - zSLP ,zSRA ,zSRL ,zSUB ,zTST ,zTSTIO ,zXOR -}; - -static const char *const s_mnemonic[] = { +const char *const z180_disassembler::s_mnemonic[] = { "adc" ,"add" ,"and" ,"bit" ,"call" ,"ccf" ,"cp" ,"cpd" , "cpdr" ,"cpi" ,"cpir" ,"cpl" ,"daa" ,"db" ,"dec" ,"di" , "djnz" ,"ei" ,"ex" ,"exx" ,"halt" ,"im" ,"in" ,"in0" , @@ -37,12 +23,7 @@ static const char *const s_mnemonic[] = { "slp" ,"sra" ,"srl" ,"sub" ,"tst" ,"tstio","xor " }; -struct z80dasm { - uint8_t mnemonic; - const char *arguments; -}; - -static const z80dasm mnemonic_xx_cb[256]= { +const z180_disassembler::z80dasm z180_disassembler::mnemonic_xx_cb[256]= { {zRLC,"b=Y"}, {zRLC,"c=Y"}, {zRLC,"d=Y"}, {zRLC,"e=Y"}, {zRLC,"h=Y"}, {zRLC,"l=Y"}, {zRLC,"Y"}, {zRLC,"a=Y"}, {zRRC,"b=Y"}, {zRRC,"c=Y"}, {zRRC,"d=Y"}, {zRRC,"e=Y"}, @@ -109,7 +90,7 @@ static const z80dasm mnemonic_xx_cb[256]= { {zSET,"h=7,Y"}, {zSET,"l=7,Y"}, {zSET,"7,Y"}, {zSET,"a=7,Y"} }; -static const z80dasm mnemonic_cb[256] = { +const z180_disassembler::z80dasm z180_disassembler::mnemonic_cb[256] = { {zRLC,"b"}, {zRLC,"c"}, {zRLC,"d"}, {zRLC,"e"}, {zRLC,"h"}, {zRLC,"l"}, {zRLC,"(hl)"}, {zRLC,"a"}, {zRRC,"b"}, {zRRC,"c"}, {zRRC,"d"}, {zRRC,"e"}, @@ -176,7 +157,7 @@ static const z80dasm mnemonic_cb[256] = { {zSET,"7,h"}, {zSET,"7,l"}, {zSET,"7,(hl)"},{zSET,"7,a"} }; -static const z80dasm mnemonic_ed[256]= { +const z180_disassembler::z80dasm z180_disassembler::mnemonic_ed[256]= { {zIN0,"b,(B)"}, {zOUT0,"(B),b"},{zDB,"?"}, {zDB,"?"}, {zTST,"b"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zIN0,"c,(B)"}, {zOUT0,"(B),c"},{zDB,"?"}, {zDB,"?"}, @@ -243,7 +224,7 @@ static const z80dasm mnemonic_ed[256]= { {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"} }; -static const z80dasm mnemonic_xx[256]= { +const z180_disassembler::z80dasm z180_disassembler::mnemonic_xx[256]= { {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zADD,"I,bc"}, {zDB,"?"}, {zDB,"?"}, @@ -310,7 +291,7 @@ static const z80dasm mnemonic_xx[256]= { {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"} }; -static const z80dasm mnemonic_main[256]= { +const z180_disassembler::z80dasm z180_disassembler::mnemonic_main[256]= { {zNOP,nullptr}, {zLD,"bc,N"}, {zLD,"(bc),a"}, {zINC,"bc"}, {zINC,"b"}, {zDEC,"b"}, {zLD,"b,B"}, {zRLCA,nullptr}, {zEX,"af,af'"}, {zADD,"hl,bc"}, {zLD,"a,(bc)"}, {zDEC,"bc"}, @@ -377,12 +358,12 @@ static const z80dasm mnemonic_main[256]= { {zCALL,"m,A"}, {zDB,"fd"}, {zCP,"B"}, {zRST,"V"} }; -static char sign(int8_t offset) +char z180_disassembler::sign(int8_t offset) { return (offset < 0)? '-':'+'; } -static int offs(int8_t offset) +int z180_disassembler::offs(int8_t offset) { if (offset < 0) return -offset; return offset; @@ -391,49 +372,48 @@ static int offs(int8_t offset) /**************************************************************************** * Disassemble opcode at PC and return number of bytes it takes ****************************************************************************/ -CPU_DISASSEMBLE(z180) +offs_t z180_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { const z80dasm *d; const char *src, *ixy; - unsigned PC = pc; int8_t offset = 0; uint8_t op, op1 = 0; uint16_t ea; - int pos = 0; + offs_t pos = pc; uint32_t flags = 0; ixy = "oops!!"; - op = oprom[pos++]; + op = opcodes.r8(pos++); switch (op) { case 0xcb: - op = oprom[pos++]; + op = opcodes.r8(pos++); d = &mnemonic_cb[op]; break; case 0xed: - op1 = oprom[pos++]; + op1 = opcodes.r8(pos++); d = &mnemonic_ed[op1]; break; case 0xdd: ixy = "ix"; - op1 = oprom[pos++]; + op1 = opcodes.r8(pos++); if( op1 == 0xcb ) { - offset = (int8_t) opram[pos++]; - op1 = opram[pos++]; /* fourth byte from opbase.ram! */ + offset = (int8_t) params.r8(pos++); + op1 = params.r8(pos++); /* fourth byte from opbase.ram! */ d = &mnemonic_xx_cb[op1]; } else d = &mnemonic_xx[op1]; break; case 0xfd: ixy = "iy"; - op1 = oprom[pos++]; + op1 = opcodes.r8(pos++); if( op1 == 0xcb ) { - offset = (int8_t) opram[pos++]; - op1 = opram[pos++]; /* fourth byte from opbase.ram! */ + offset = (int8_t) params.r8(pos++); + op1 = params.r8(pos++); /* fourth byte from opbase.ram! */ d = &mnemonic_xx_cb[op1]; } else d = &mnemonic_xx[op1]; @@ -455,25 +435,25 @@ CPU_DISASSEMBLE(z180) util::stream_format(stream, "$%02x,$%02x", op, op1); break; case 'A': - ea = opram[pos] + (opram[pos+1] << 8); + ea = params.r16(pos); pos += 2; util::stream_format(stream, "$%04X", ea); break; case 'B': /* Byte op arg */ - ea = opram[pos++]; + ea = params.r8(pos++); util::stream_format(stream, "$%02X", ea); break; case 'N': /* Immediate 16 bit */ - ea = opram[pos] + ( opram[pos+1] << 8 ); + ea = params.r16(pos); pos += 2; util::stream_format(stream, "$%04X", ea); break; case 'O': /* Offset relative to PC */ - offset = (int8_t) opram[pos++]; - util::stream_format(stream, "$%05X", PC + offset + 2); + offset = (int8_t) params.r8(pos++); + util::stream_format(stream, "$%05X", pc + offset + 2); break; case 'P': /* Port number */ - ea = opram[pos++]; + ea = params.r8(pos++); util::stream_format(stream, "$%02X", ea); break; case 'V': /* Restart vector */ @@ -481,12 +461,12 @@ CPU_DISASSEMBLE(z180) util::stream_format(stream, "$%02X", ea); break; case 'W': /* Memory address word */ - ea = opram[pos] + (opram[pos+1] << 8); + ea = params.r16(pos); pos += 2; util::stream_format(stream, "$%05X", ea); break; case 'X': - offset = (int8_t) opram[pos++]; + offset = (int8_t) params.r8(pos++); case 'Y': util::stream_format(stream,"(%s%c$%02x)", ixy, sign(offset), offs(offset)); break; @@ -507,9 +487,14 @@ CPU_DISASSEMBLE(z180) if (d->mnemonic == zCALL || d->mnemonic == zCPDR || d->mnemonic == zCPIR || d->mnemonic == zDJNZ || d->mnemonic == zHLT || d->mnemonic == zINDR || d->mnemonic == zINIR || d->mnemonic == zLDDR || d->mnemonic == zLDIR || d->mnemonic == zOTDR || d->mnemonic == zOTIR || d->mnemonic == zRST) - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; else if (d->mnemonic == zRETN || d->mnemonic == zRET || d->mnemonic == zRETI) - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; - return pos | flags | DASMFLAG_SUPPORTED; + return (pos - pc) | flags | SUPPORTED; +} + +u32 z180_disassembler::opcode_alignment() const +{ + return 1; } diff --git a/src/devices/cpu/z180/z180dasm.h b/src/devices/cpu/z180/z180dasm.h new file mode 100644 index 00000000000..a13c7d92fe1 --- /dev/null +++ b/src/devices/cpu/z180/z180dasm.h @@ -0,0 +1,54 @@ +// license:BSD-3-Clause +// copyright-holders:Juergen Buchmueller +/***************************************************************************** + * + * z180dasm.c + * Portable Z8x180 disassembler + * + *****************************************************************************/ + +#ifndef MAME_CPU_Z180_Z180DASM_H +#define MAME_CPU_Z180_Z180DASM_H + +#pragma once + +class z180_disassembler : public util::disasm_interface +{ +public: + z180_disassembler() = default; + virtual ~z180_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + struct z80dasm { + uint8_t mnemonic; + const char *arguments; + }; + + enum e_mnemonics { + zADC ,zADD ,zAND ,zBIT ,zCALL ,zCCF ,zCP ,zCPD , + zCPDR ,zCPI ,zCPIR ,zCPL ,zDAA ,zDB ,zDEC ,zDI , + zDJNZ ,zEI ,zEX ,zEXX ,zHLT ,zIM ,zIN ,zIN0 , + zINC ,zIND ,zINDR ,zINI ,zINIR ,zJP ,zJR ,zLD , + zLDD ,zLDDR ,zLDI ,zLDIR ,zMLT ,zNEG ,zNOP ,zOR , + zOTDM ,zOTDMR ,zOTDR ,zOTIM ,zOTIMR ,zOTIR ,zOUT ,zOUT0 , + zOUTD ,zOUTI ,zPOP ,zPUSH ,zRES ,zRET ,zRETI ,zRETN , + zRL ,zRLA ,zRLC ,zRLCA ,zRLD ,zRR ,zRRA ,zRRC , + zRRCA ,zRRD ,zRST ,zSBC ,zSCF ,zSET ,zSLA ,zSLL , + zSLP ,zSRA ,zSRL ,zSUB ,zTST ,zTSTIO ,zXOR + }; + + static const char *const s_mnemonic[]; + static const z80dasm mnemonic_xx_cb[256]; + static const z80dasm mnemonic_cb[256]; + static const z80dasm mnemonic_ed[256]; + static const z80dasm mnemonic_xx[256]; + static const z80dasm mnemonic_main[256]; + + static char sign(int8_t offset); + static int offs(int8_t offset); +}; + +#endif diff --git a/src/devices/cpu/z180/z180ops.h b/src/devices/cpu/z180/z180ops.h index 9ffe45cc42d..1c1fa8322f6 100644 --- a/src/devices/cpu/z180/z180ops.h +++ b/src/devices/cpu/z180/z180ops.h @@ -22,17 +22,27 @@ /*************************************************************** * Input a byte from given I/O port ***************************************************************/ -#define IN(port) \ - (((port ^ IO_IOCR) & 0xffc0) == 0) ? \ - z180_readcontrol(port) : m_iospace->read_byte(port) +inline u8 z180_device::IN(u16 port) +{ + if(((port ^ IO_IOCR) & 0xffc0) == 0) + return z180_readcontrol(port); + m_extra_cycles += ((IO_DCNTL & (Z180_DCNTL_IWI1 | Z180_DCNTL_IWI0)) >> 4) + 1; // external I/O wait states + return m_iospace->read_byte(port); +} /*************************************************************** * Output a byte to given I/O port ***************************************************************/ -#define OUT(port,value) \ - if (((port ^ IO_IOCR) & 0xffc0) == 0) \ - z180_writecontrol(port,value); \ - else m_iospace->write_byte(port,value) +inline void z180_device::OUT(u16 port, u8 value) +{ + if (((port ^ IO_IOCR) & 0xffc0) == 0) { + z180_writecontrol(port,value); + } else + { + m_extra_cycles += ((IO_DCNTL & (Z180_DCNTL_IWI1 | Z180_DCNTL_IWI0)) >> 4) + 1; // external I/O wait states + m_iospace->write_byte(port, value); + } +} /*************************************************************** * MMU calculate the memory management lookup table @@ -68,12 +78,16 @@ void z180_device::z180_mmu() /*************************************************************** * Read a byte from given memory location ***************************************************************/ -#define RM(addr) m_program->read_byte(MMU_REMAP_ADDR(addr)) +inline u8 z180_device::RM(offs_t addr) +{ + m_extra_cycles += IO_DCNTL >> 6; // memory wait states + return m_program->read_byte(MMU_REMAP_ADDR(addr)); +} /*************************************************************** * Write a byte to given memory location ***************************************************************/ -#define WM(addr,value) m_program->write_byte(MMU_REMAP_ADDR(addr),value) +#define WM(addr,value) m_extra_cycles += IO_DCNTL >> 6; /* memory wait states */ m_program->write_byte(MMU_REMAP_ADDR(addr),value) /*************************************************************** * Read a word from given memory location @@ -102,6 +116,7 @@ uint8_t z180_device::ROP() { offs_t addr = _PCD; _PC++; + m_extra_cycles += IO_DCNTL >> 6; // memory wait states return m_odirect->read_byte(MMU_REMAP_ADDR(addr)); } @@ -115,6 +130,7 @@ uint8_t z180_device::ARG() { offs_t addr = _PCD; _PC++; + m_extra_cycles += IO_DCNTL >> 6; // memory wait states return m_direct->read_byte(MMU_REMAP_ADDR(addr)); } @@ -122,6 +138,7 @@ uint32_t z180_device::ARG16() { offs_t addr = _PCD; _PC += 2; + m_extra_cycles += (IO_DCNTL >> 6) * 2; // memory wait states return m_direct->read_byte(MMU_REMAP_ADDR(addr)) | (m_direct->read_byte(MMU_REMAP_ADDR(addr+1)) << 8); } diff --git a/src/devices/cpu/z8/z8.cpp b/src/devices/cpu/z8/z8.cpp index 5ef2c5c505d..1f21ebbab49 100644 --- a/src/devices/cpu/z8/z8.cpp +++ b/src/devices/cpu/z8/z8.cpp @@ -22,6 +22,7 @@ #include "emu.h" #include "z8.h" +#include "z8dasm.h" #include "debugger.h" /*************************************************************************** @@ -207,13 +208,12 @@ z8681_device::z8681_device(const machine_config &mconfig, const char *tag, devic { } - -offs_t z8_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *z8_device::create_disassembler() { - extern CPU_DISASSEMBLE( z8 ); - return CPU_DISASSEMBLE_NAME(z8)(this, stream, pc, oprom, opram, options); + return new z8_disassembler; } + device_memory_interface::space_config_vector z8_device::memory_space_config() const { // Separate data space is optional @@ -778,7 +778,7 @@ void z8_device::device_start() /* find address spaces */ m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_data = has_space(AS_DATA) ? &space(AS_DATA) : m_program; /* allocate timers */ diff --git a/src/devices/cpu/z8/z8.h b/src/devices/cpu/z8/z8.h index b7064c82ae7..1f6f8a7c890 100644 --- a/src/devices/cpu/z8/z8.h +++ b/src/devices/cpu/z8/z8.h @@ -91,9 +91,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 3; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; DECLARE_ADDRESS_MAP(program_2kb, 8); DECLARE_ADDRESS_MAP(program_4kb, 8); @@ -103,7 +101,7 @@ private: address_space_config m_data_config; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_data; // callbacks diff --git a/src/devices/cpu/z8/z8dasm.cpp b/src/devices/cpu/z8/z8dasm.cpp index 8cd29344f2a..a832dab8fe9 100644 --- a/src/devices/cpu/z8/z8dasm.cpp +++ b/src/devices/cpu/z8/z8dasm.cpp @@ -1,14 +1,14 @@ // license:BSD-3-Clause // copyright-holders:Curt Coder + #include "emu.h" -#include "debugger.h" -#include "z8.h" +#include "z8dasm.h" /*************************************************************************** CONSTANTS ***************************************************************************/ -static const char *const REGISTER_NAME[256] = +const char *const z8_disassembler::REGISTER_NAME[256] = { "P0", "P1", "P2", "P3", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", @@ -28,7 +28,7 @@ static const char *const REGISTER_NAME[256] = "SIO", "TMR", "T1", "PRE1", "T0", "PRE0", "P2M", "P3M", "P01M", "IPR", "IRQ", "IMR", "FLAGS", "RP", "SPH", "SPL" }; -static const char *const CONDITION_CODE[16] = +const char *const z8_disassembler::CONDITION_CODE[16] = { "F", "LT", "LE", "ULE", "OV", "MI", "Z", "C", "", "GE", "GT", "UGT", "NOV", "PL", "NZ", "NC" @@ -50,8 +50,8 @@ static const char *const CONDITION_CODE[16] = #define DA "%04Xh" #define RA "%04Xh" -#define B0 oprom[0] -#define B1 oprom[1] +#define B0 opcodes.r8(pos) +#define B1 opcodes.r8(pos+1) #define B0H (B0 >> 4) #define B0L (B0 & 0x0f) #define OPH (opcode >> 4) @@ -74,19 +74,24 @@ static const char *const CONDITION_CODE[16] = #define illegal util::stream_format(stream, "Illegal") #define mnemonic(_mnemonic) util::stream_format(stream, "%-5s", _mnemonic) -#define bytes(_count) oprom += (_count - 1) -#define step_over flags = DASMFLAG_STEP_OVER -#define step_out flags = DASMFLAG_STEP_OUT +#define bytes(_count) pos += (_count - 1) +#define step_over flags = STEP_OVER +#define step_out flags = STEP_OUT /*************************************************************************** DISASSEMBLER ***************************************************************************/ -CPU_DISASSEMBLE(z8) +u32 z8_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t z8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - const uint8_t *startrom = oprom; + offs_t pos = pc; uint32_t flags = 0; - uint8_t opcode = *oprom++; + uint8_t opcode = opcodes.r8(pos++); int argc = 0; switch (pc) @@ -97,7 +102,7 @@ CPU_DISASSEMBLE(z8) case 0x0006: case 0x0008: case 0x000a: - util::stream_format(stream, "IRQ%u Vector %04Xh", pc / 2, opcode << 8 | *oprom++); break; + util::stream_format(stream, "IRQ%u Vector %04Xh", pc / 2, opcode << 8 | opcodes.r8(pos++)); break; default: switch (opcode) { @@ -375,5 +380,5 @@ CPU_DISASSEMBLE(z8) } } - return (oprom - startrom) | flags | DASMFLAG_SUPPORTED; + return (pos - pc) | flags | SUPPORTED; } diff --git a/src/devices/cpu/z8/z8dasm.h b/src/devices/cpu/z8/z8dasm.h new file mode 100644 index 00000000000..653b6e0cb26 --- /dev/null +++ b/src/devices/cpu/z8/z8dasm.h @@ -0,0 +1,24 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder + +#ifndef MAME_CPU_Z8_Z8DASM_H +#define MAME_CPU_Z8_Z8DASM_H + +#pragma once + +class z8_disassembler : public util::disasm_interface +{ +public: + z8_disassembler() = default; + virtual ~z8_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *const REGISTER_NAME[256]; + static const char *const CONDITION_CODE[16]; + +}; + +#endif diff --git a/src/devices/cpu/z80/z80.cpp b/src/devices/cpu/z80/z80.cpp index 3dbf3f506d9..3b2fcd99761 100644 --- a/src/devices/cpu/z80/z80.cpp +++ b/src/devices/cpu/z80/z80.cpp @@ -110,6 +110,7 @@ #include "emu.h" #include "debugger.h" #include "z80.h" +#include "z80dasm.h" #define VERBOSE 0 @@ -208,7 +209,7 @@ static const uint8_t cc_op[0x100] = { 5,10,10,10,10,11, 7,11, 5,10,10, 0,10,17, 7,11, /* cb -> cc_cb */ 5,10,10,11,10,11, 7,11, 5, 4,10,11,10, 0, 7,11, /* dd -> cc_xy */ 5,10,10,19,10,11, 7,11, 5, 4,10, 4,10, 0, 7,11, /* ed -> cc_ed */ - 5,10,10, 4,10,11, 7,11, 5, 6,10, 4,10, 0, 7,11 /* fd -> cc_xy */ + 5,10,10, 4,10,11, 7,11, 5, 6,10, 4,10, 0, 7,11 /* fd -> cc_xy */ }; static const uint8_t cc_cb[0x100] = { @@ -235,14 +236,14 @@ static const uint8_t cc_ed[0x100] = { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, -12,12,15,20, 8,14, 8, 9,12,12,15,20, 8,14, 8, 9, -12,12,15,20, 8,14, 8, 9,12,12,15,20, 8,14, 8, 9, -12,12,15,20, 8,14, 8,18,12,12,15,20, 8,14, 8,18, -12,12,15,20, 8,14, 8, 8,12,12,15,20, 8,14, 8, 8, + 12,12,15,20,8,14, 8, 9,12,12,15,20, 8,14, 8, 9, + 12,12,15,20,8,14, 8, 9,12,12,15,20, 8,14, 8, 9, + 12,12,15,20,8,14, 8,18,12,12,15,20, 8,14, 8,18, + 12,12,15,20,8,14, 8, 8,12,12,15,20, 8,14, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, -16,16,16,16, 8, 8, 8, 8,16,16,16,16, 8, 8, 8, 8, -16,16,16,16, 8, 8, 8, 8,16,16,16,16, 8, 8, 8, 8, + 16,16,16,16,8, 8, 8, 8,16,16,16,16, 8, 8, 8, 8, + 16,16,16,16,8, 8, 8, 8,16,16,16,16, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, @@ -258,7 +259,7 @@ static const uint8_t cc_xy[0x100] = { 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19 , 4+4, 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19 , 4+4, 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19 , 4+4, 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19 , 4+4, 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19 , 4+4, 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19 , 4+4, -19 ,19 ,19 ,19 ,19 ,19 , 4+4,19 , 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19 , 4+4, + 19 ,19 ,19 ,19 ,19 ,19 , 4+4,19 , 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19 , 4+4, 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19 , 4+4, 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19 , 4+4, 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19 , 4+4, 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19 , 4+4, 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19 , 4+4, 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19 , 4+4, @@ -266,26 +267,26 @@ static const uint8_t cc_xy[0x100] = { 5+4,10+4,10+4,10+4,10+4,11+4, 7+4,11+4, 5+4,10+4,10+4, 0 ,10+4,17+4, 7+4,11+4, /* cb -> cc_xycb */ 5+4,10+4,10+4,11+4,10+4,11+4, 7+4,11+4, 5+4, 4+4,10+4,11+4,10+4, 4 , 7+4,11+4, /* dd -> cc_xy again */ 5+4,10+4,10+4,19+4,10+4,11+4, 7+4,11+4, 5+4, 4+4,10+4, 4+4,10+4, 4 , 7+4,11+4, /* ed -> cc_ed */ - 5+4,10+4,10+4, 4+4,10+4,11+4, 7+4,11+4, 5+4, 6+4,10+4, 4+4,10+4, 4 , 7+4,11+4 /* fd -> cc_xy again */ + 5+4,10+4,10+4, 4+4,10+4,11+4, 7+4,11+4, 5+4, 6+4,10+4, 4+4,10+4, 4 , 7+4,11+4 /* fd -> cc_xy again */ }; static const uint8_t cc_xycb[0x100] = { -23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, -23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, -23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, -23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, -20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, -20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, -20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, -20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, -23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, -23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, -23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, -23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, -23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, -23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, -23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, -23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23 + 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, + 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, + 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, + 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, + 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, + 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, + 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, + 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, + 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, + 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, + 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, + 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, + 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, + 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, + 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, + 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23 }; /* extra cycles if jr/jp/call taken and 'interrupt latency' on rst 0-7 */ @@ -394,22 +395,27 @@ static const uint8_t cc_ex[0x100] = { } while (0) /*************************************************************** - * Enter halt state; write 1 to fake port on first execution + * Enter halt state; write 1 to callback on first execution ***************************************************************/ inline void z80_device::halt() { PC--; - m_halt = 1; + if (!m_halt) + { + m_halt = 1; + m_halt_cb(1); + } } /*************************************************************** - * Leave halt state; write 0 to fake port + * Leave halt state; write 0 to callback ***************************************************************/ inline void z80_device::leave_halt() { if( m_halt ) { m_halt = 0; + m_halt_cb(0); PC++; } } @@ -564,8 +570,8 @@ inline void z80_device::jp_cond(bool cond) ***************************************************************/ inline void z80_device::jr() { - int8_t a = (int8_t)arg(); /* arg() also increments PC */ - PC += a; /* so don't do PC += arg() */ + int8_t a = (int8_t)arg(); /* arg() also increments PC */ + PC += a; /* so don't do PC += arg() */ WZ = PC; } @@ -609,7 +615,7 @@ inline void z80_device::call_cond(bool cond, uint8_t opcode) } else { - WZ = arg16(); /* implicit call PC+=2; */ + WZ = arg16(); /* implicit call PC+=2; */ } } @@ -655,7 +661,7 @@ inline void z80_device::reti() inline void z80_device::ld_r_a() { m_r = A; - m_r2 = A & 0x80; /* keep bit 7 of r */ + m_r2 = A & 0x80; /* keep bit 7 of r */ } /*************************************************************** @@ -3401,12 +3407,12 @@ void z80_device::device_start() m_program = &space(AS_PROGRAM); m_decrypted_opcodes = has_space(AS_OPCODES) ? &space(AS_OPCODES) : m_program; - m_direct = &m_program->direct(); - m_decrypted_opcodes_direct = &m_decrypted_opcodes->direct(); + m_direct = m_program->direct<0>(); + m_decrypted_opcodes_direct = m_decrypted_opcodes->direct<0>(); m_io = &space(AS_IO); IX = IY = 0xffff; /* IX and IY are FFFF after a reset! */ - F = ZF; /* Zero flag is set */ + F = ZF; /* Zero flag is set */ /* set up the state table */ state_add(STATE_GENPC, "PC", m_pc.w.l).callimport(); @@ -3452,6 +3458,7 @@ void z80_device::device_start() m_irqack_cb.resolve_safe(); m_refresh_cb.resolve_safe(); + m_halt_cb.resolve_safe(); } void nsc800_device::device_start() @@ -3465,6 +3472,8 @@ void nsc800_device::device_start() ****************************************************************************/ void z80_device::device_reset() { + leave_halt(); + PC = 0x0000; m_i = 0; m_r = 0; @@ -3659,14 +3668,13 @@ void z80_device::state_string_export(const device_state_entry &entry, std::strin } //------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t z80_device::disasm_disassemble( std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options ) +util::disasm_interface *z80_device::create_disassembler() { - extern CPU_DISASSEMBLE( z80 ); - return CPU_DISASSEMBLE_NAME(z80)(this, stream, pc, oprom, opram, options); + return new z80_disassembler; } @@ -3697,7 +3705,8 @@ z80_device::z80_device(const machine_config &mconfig, device_type type, const ch m_decrypted_opcodes_config("decrypted_opcodes", ENDIANNESS_LITTLE, 8, 16, 0), m_io_config("io", ENDIANNESS_LITTLE, 8, 16, 0), m_irqack_cb(*this), - m_refresh_cb(*this) + m_refresh_cb(*this), + m_halt_cb(*this) { } diff --git a/src/devices/cpu/z80/z80.h b/src/devices/cpu/z80/z80.h index cf244e24d3c..732e425fd86 100644 --- a/src/devices/cpu/z80/z80.h +++ b/src/devices/cpu/z80/z80.h @@ -13,6 +13,9 @@ #define MCFG_Z80_SET_REFRESH_CALLBACK(_devcb) \ devcb = &z80_device::set_refresh_cb(*device, DEVCB_##_devcb); +#define MCFG_Z80_SET_HALT_CALLBACK(_devcb) \ + devcb = &z80_device::set_halt_cb(*device, DEVCB_##_devcb); + enum { NSC800_RSTA = INPUT_LINE_IRQ0 + 1, @@ -41,6 +44,7 @@ public: void z80_set_cycle_tables(const uint8_t *op, const uint8_t *cb, const uint8_t *ed, const uint8_t *xy, const uint8_t *xycb, const uint8_t *ex); template<class _Object> static devcb_base &set_irqack_cb(device_t &device, _Object object) { return downcast<z80_device &>(device).m_irqack_cb.set_callback(object); } template<class _Object> static devcb_base &set_refresh_cb(device_t &device, _Object object) { return downcast<z80_device &>(device).m_refresh_cb.set_callback(object); } + template<class _Object> static devcb_base &set_halt_cb(device_t &device, _Object object) { return downcast<z80_device &>(device).m_halt_cb.set_callback(object); } protected: z80_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); @@ -66,9 +70,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 4; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; #undef PROTOTYPES #define PROTOTYPES(prefix) \ @@ -242,10 +244,11 @@ protected: address_space *m_program; address_space *m_decrypted_opcodes; address_space *m_io; - direct_read_data *m_direct; - direct_read_data *m_decrypted_opcodes_direct; + direct_read_data<0> *m_direct; + direct_read_data<0> *m_decrypted_opcodes_direct; devcb_write_line m_irqack_cb; devcb_write16 m_refresh_cb; + devcb_write_line m_halt_cb; PAIR m_prvpc; PAIR m_pc; diff --git a/src/devices/cpu/z80/z80daisy_generic.cpp b/src/devices/cpu/z80/z80daisy_generic.cpp new file mode 100644 index 00000000000..57d08c13066 --- /dev/null +++ b/src/devices/cpu/z80/z80daisy_generic.cpp @@ -0,0 +1,117 @@ +// license: BSD-3-Clause +// copyright-holders: Dirk Best +/*************************************************************************** + + Generic Z80 daisy chain device + +***************************************************************************/ + +#include "emu.h" +#include "z80daisy_generic.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(Z80DAISY_GENERIC, z80daisy_generic_device, "z80daisy_generic", "Generic Z80 daisy chain device") + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// z80daisy_generic_device - constructor +//------------------------------------------------- + +z80daisy_generic_device::z80daisy_generic_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, Z80DAISY_GENERIC, tag, owner, clock), + device_z80daisy_interface(mconfig, *this), + m_int_handler(*this), + m_int(0), m_mask(0), m_vector(0xff) +{ +} + +//------------------------------------------------- +// static_set_vector - static configuration +//------------------------------------------------- + +void z80daisy_generic_device::static_set_vector(device_t &device, uint8_t vector) +{ + z80daisy_generic_device &dev = downcast<z80daisy_generic_device &>(device); + dev.m_vector = vector; +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void z80daisy_generic_device::device_start() +{ + // resolve callbacks + m_int_handler.resolve_safe(); + + // register for save states + save_item(NAME(m_int)); + save_item(NAME(m_mask)); + save_item(NAME(m_vector)); +} + +//------------------------------------------------- +// z80daisy_irq_state - return the overall IRQ +// state for this device +//------------------------------------------------- + +int z80daisy_generic_device::z80daisy_irq_state() +{ + if (m_int & ~m_mask) + return Z80_DAISY_INT; + + return 0; +} + +//------------------------------------------------- +// z80daisy_irq_ack - acknowledge an IRQ and +// return the appropriate vector +//------------------------------------------------- + +int z80daisy_generic_device::z80daisy_irq_ack() +{ + return m_vector; +} + +//------------------------------------------------- +// z80daisy_irq_reti - clear the interrupt +// pending state to allow other interrupts through +//------------------------------------------------- + +void z80daisy_generic_device::z80daisy_irq_reti() +{ +} + +//------------------------------------------------- +// update_interrupt() - check interrupt status +//------------------------------------------------- + +void z80daisy_generic_device::update_interrupt() +{ + m_int_handler(m_int & ~m_mask ? ASSERT_LINE : CLEAR_LINE); +} + + +//************************************************************************** +// INTERFACE +//************************************************************************** + +WRITE_LINE_MEMBER( z80daisy_generic_device::int_w ) +{ + m_int = state; + update_interrupt(); +} + +WRITE_LINE_MEMBER( z80daisy_generic_device::mask_w ) +{ + m_mask = state; + update_interrupt(); +} diff --git a/src/devices/cpu/z80/z80daisy_generic.h b/src/devices/cpu/z80/z80daisy_generic.h new file mode 100644 index 00000000000..389c5eda43f --- /dev/null +++ b/src/devices/cpu/z80/z80daisy_generic.h @@ -0,0 +1,71 @@ +// license: BSD-3-Clause +// copyright-holders: Dirk Best +/*************************************************************************** + + Generic Z80 daisy chain device + +***************************************************************************/ + +#ifndef MAME_DEVICES_CPU_Z80_Z80DAISY_GENERIC_H +#define MAME_DEVICES_CPU_Z80_Z80DAISY_GENERIC_H + +#pragma once + +#include "z80daisy.h" + + +//************************************************************************** +// INTERFACE CONFIGURATION MACROS +//************************************************************************** + +#define MCFG_Z80DAISY_GENERIC_ADD(_tag, _vector) \ + MCFG_DEVICE_ADD(_tag, Z80DAISY_GENERIC, 0) \ + z80daisy_generic_device::static_set_vector(*device, _vector); \ + +#define MCFG_Z80DAISY_GENERIC_INT_CB(_devcb) \ + devcb = &z80daisy_generic_device::set_int_handler(*device, DEVCB_##_devcb); + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class z80daisy_generic_device : public device_t, public device_z80daisy_interface +{ +public: + // construction/destruction + z80daisy_generic_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + // callbacks + template <class Object> static devcb_base &set_int_handler(device_t &device, Object &&cb) + { return downcast<z80daisy_generic_device &>(device).m_int_handler.set_callback(std::forward<Object>(cb)); } + + // configuration + static void static_set_vector(device_t &device, uint8_t vector); + + DECLARE_WRITE_LINE_MEMBER(int_w); + DECLARE_WRITE_LINE_MEMBER(mask_w); + +protected: + // device-level overrides + virtual void device_start() override; + + // z80daisy_interface overrides + virtual int z80daisy_irq_state() override; + virtual int z80daisy_irq_ack() override; + virtual void z80daisy_irq_reti() override; + +private: + void update_interrupt(); + + devcb_write_line m_int_handler; + + int m_int; + int m_mask; + int m_vector; +}; + +// device type definition +DECLARE_DEVICE_TYPE(Z80DAISY_GENERIC, z80daisy_generic_device) + +#endif // MAME_DEVICES_CPU_Z80_Z80DAISY_GENERIC_H diff --git a/src/devices/cpu/z80/z80dasm.cpp b/src/devices/cpu/z80/z80dasm.cpp index 2af88954943..b59b3a38eb6 100644 --- a/src/devices/cpu/z80/z80dasm.cpp +++ b/src/devices/cpu/z80/z80dasm.cpp @@ -9,20 +9,8 @@ #include "emu.h" #include "debugger.h" -#include "z80.h" +#include "z80dasm.h" -enum e_mnemonics -{ - zADC ,zADD ,zAND ,zBIT ,zCALL ,zCCF ,zCP ,zCPD , - zCPDR ,zCPI ,zCPIR ,zCPL ,zDAA ,zDB ,zDEC ,zDI , - zDJNZ ,zEI ,zEX ,zEXX ,zHLT ,zIM ,zIN ,zINC , - zIND ,zINDR ,zINI ,zINIR ,zJP ,zJR ,zLD ,zLDD , - zLDDR ,zLDI ,zLDIR ,zNEG ,zNOP ,zOR ,zOTDR ,zOTIR , - zOUT ,zOUTD ,zOUTI ,zPOP ,zPUSH ,zRES ,zRET ,zRETI , - zRETN ,zRL ,zRLA ,zRLC ,zRLCA ,zRLD ,zRR ,zRRA , - zRRC ,zRRCA ,zRRD ,zRST ,zSBC ,zSCF ,zSET ,zSLA , - zSLL ,zSRA ,zSRL ,zSUB ,zXOR -}; static const char *const s_mnemonic[] = { @@ -37,29 +25,20 @@ static const char *const s_mnemonic[] = "sll" ,"sra" ,"srl" ,"sub" ,"xor " }; -#define _OVER DASMFLAG_STEP_OVER -#define _OUT DASMFLAG_STEP_OUT - -static const uint32_t s_flags[] = -{ - 0 ,0 ,0 ,0 ,_OVER,0 ,0 ,0 , - _OVER,0 ,_OVER,0 ,0 ,0 ,0 ,0 , - _OVER,0 ,0 ,0 ,_OVER,0 ,0 ,0 , - 0 ,_OVER,0 ,_OVER,0 ,0 ,0 ,0 , - _OVER,0 ,_OVER,0 ,0 ,0 ,_OVER,_OVER, - 0 ,0 ,0 ,0 ,0 ,0 ,_OUT ,_OUT , - _OUT ,0 ,0 ,0 ,0 ,0 ,0 ,0 , - 0 ,0 ,0 ,_OVER,0 ,0 ,0 ,0 , - 0 ,0 ,0 ,0 ,0 -}; - -struct z80dasm +const u32 z80_disassembler::s_flags[] = { - uint8_t mnemonic; - const char *arguments; + 0 ,0 ,0 ,0 ,STEP_OVER,0 ,0 ,0 , + STEP_OVER,0 ,STEP_OVER,0 ,0 ,0 ,0 ,0 , + STEP_OVER,0 ,0 ,0 ,STEP_OVER,0 ,0 ,0 , + 0 ,STEP_OVER,0 ,STEP_OVER,0 ,0 ,0 ,0 , + STEP_OVER,0 ,STEP_OVER,0 ,0 ,0 ,STEP_OVER,STEP_OVER, + 0 ,0 ,0 ,0 ,0 ,0 ,STEP_OUT ,STEP_OUT , + STEP_OUT ,0 ,0 ,0 ,0 ,0 ,0 ,0 , + 0 ,0 ,0 ,STEP_OVER,0 ,0 ,0 ,0 , + 0 ,0 ,0 ,0 ,0 }; -static const z80dasm mnemonic_xx_cb[256] = +const z80_disassembler::z80dasm z80_disassembler::mnemonic_xx_cb[256] = { {zRLC,"b=Y"}, {zRLC,"c=Y"}, {zRLC,"d=Y"}, {zRLC,"e=Y"}, {zRLC,"h=Y"}, {zRLC,"l=Y"}, {zRLC,"Y"}, {zRLC,"a=Y"}, @@ -127,7 +106,7 @@ static const z80dasm mnemonic_xx_cb[256] = {zSET,"h=7,Y"}, {zSET,"l=7,Y"}, {zSET,"7,Y"}, {zSET,"a=7,Y"} }; -static const z80dasm mnemonic_cb[256] = +const z80_disassembler::z80dasm z80_disassembler::mnemonic_cb[256] = { {zRLC,"b"}, {zRLC,"c"}, {zRLC,"d"}, {zRLC,"e"}, {zRLC,"h"}, {zRLC,"l"}, {zRLC,"(hl)"}, {zRLC,"a"}, @@ -195,7 +174,7 @@ static const z80dasm mnemonic_cb[256] = {zSET,"7,h"}, {zSET,"7,l"}, {zSET,"7,(hl)"},{zSET,"7,a"} }; -static const z80dasm mnemonic_ed[256] = +const z80_disassembler::z80dasm z80_disassembler::mnemonic_ed[256] = { {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, @@ -214,21 +193,21 @@ static const z80dasm mnemonic_ed[256] = {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zIN,"b,(c)"}, {zOUT,"(c),b"}, {zSBC,"hl,bc"}, {zLD,"(W),bc"}, - {zNEG,nullptr}, {zRETN,nullptr}, {zIM,"0"}, {zLD,"i,a"}, + {zNEG,nullptr}, {zRETN,nullptr},{zIM,"0"}, {zLD,"i,a"}, {zIN,"c,(c)"}, {zOUT,"(c),c"}, {zADC,"hl,bc"}, {zLD,"bc,(W)"}, - {zNEG,"*"}, {zRETI,nullptr}, {zIM,"0"}, {zLD,"r,a"}, + {zNEG,"*"}, {zRETI,nullptr},{zIM,"0"}, {zLD,"r,a"}, {zIN,"d,(c)"}, {zOUT,"(c),d"}, {zSBC,"hl,de"}, {zLD,"(W),de"}, - {zNEG,"*"}, {zRETN,nullptr}, {zIM,"1"}, {zLD,"a,i"}, + {zNEG,"*"}, {zRETN,nullptr},{zIM,"1"}, {zLD,"a,i"}, {zIN,"e,(c)"}, {zOUT,"(c),e"}, {zADC,"hl,de"}, {zLD,"de,(W)"}, - {zNEG,"*"}, {zRETI,nullptr}, {zIM,"2"}, {zLD,"a,r"}, + {zNEG,"*"}, {zRETI,nullptr},{zIM,"2"}, {zLD,"a,r"}, {zIN,"h,(c)"}, {zOUT,"(c),h"}, {zSBC,"hl,hl"}, {zLD,"(W),hl"}, - {zNEG,"*"}, {zRETN,nullptr}, {zIM,"0"}, {zRRD,"(hl)"}, + {zNEG,"*"}, {zRETN,nullptr},{zIM,"0"}, {zRRD,"(hl)"}, {zIN,"l,(c)"}, {zOUT,"(c),l"}, {zADC,"hl,hl"}, {zLD,"hl,(W)"}, - {zNEG,"*"}, {zRETI,nullptr}, {zIM,"0"}, {zRLD,"(hl)"}, + {zNEG,"*"}, {zRETI,nullptr},{zIM,"0"}, {zRLD,"(hl)"}, {zIN,"0,(c)"}, {zOUT,"(c),0"}, {zSBC,"hl,sp"}, {zLD,"(W),sp"}, - {zNEG,"*"}, {zRETN,nullptr}, {zIM,"1"}, {zDB,"?"}, + {zNEG,"*"}, {zRETN,nullptr},{zIM,"1"}, {zDB,"?"}, {zIN,"a,(c)"}, {zOUT,"(c),a"}, {zADC,"hl,sp"}, {zLD,"sp,(W)"}, - {zNEG,"*"}, {zRETI,nullptr}, {zIM,"2"}, {zDB,"?"}, + {zNEG,"*"}, {zRETI,nullptr},{zIM,"2"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, @@ -263,7 +242,7 @@ static const z80dasm mnemonic_ed[256] = {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"} }; -static const z80dasm mnemonic_xx[256] = +const z80_disassembler::z80dasm z80_disassembler::mnemonic_xx[256] = { {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, @@ -331,9 +310,9 @@ static const z80dasm mnemonic_xx[256] = {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"} }; -static const z80dasm mnemonic_main[256] = +const z80_disassembler::z80dasm z80_disassembler::mnemonic_main[256] = { - {zNOP,nullptr}, {zLD,"bc,N"}, {zLD,"(bc),a"}, {zINC,"bc"}, + {zNOP,nullptr}, {zLD,"bc,N"}, {zLD,"(bc),a"}, {zINC,"bc"}, {zINC,"b"}, {zDEC,"b"}, {zLD,"b,B"}, {zRLCA,nullptr}, {zEX,"af,af'"}, {zADD,"hl,bc"}, {zLD,"a,(bc)"}, {zDEC,"bc"}, {zINC,"c"}, {zDEC,"c"}, {zLD,"c,B"}, {zRRCA,nullptr}, @@ -383,11 +362,11 @@ static const z80dasm mnemonic_main[256] = {zCP,"h"}, {zCP,"l"}, {zCP,"(hl)"}, {zCP,"a"}, {zRET,"nz"}, {zPOP,"bc"}, {zJP,"nz,A"}, {zJP,"A"}, {zCALL,"nz,A"}, {zPUSH,"bc"}, {zADD,"a,B"}, {zRST,"V"}, - {zRET,"z"}, {zRET,nullptr}, {zJP,"z,A"}, {zDB,"cb"}, + {zRET,"z"}, {zRET,nullptr}, {zJP,"z,A"}, {zDB,"cb"}, {zCALL,"z,A"}, {zCALL,"A"}, {zADC,"a,B"}, {zRST,"V"}, {zRET,"nc"}, {zPOP,"de"}, {zJP,"nc,A"}, {zOUT,"(P),a"}, {zCALL,"nc,A"}, {zPUSH,"de"}, {zSUB,"B"}, {zRST,"V"}, - {zRET,"c"}, {zEXX,nullptr}, {zJP,"c,A"}, {zIN,"a,(P)"}, + {zRET,"c"}, {zEXX,nullptr}, {zJP,"c,A"}, {zIN,"a,(P)"}, {zCALL,"c,A"}, {zDB,"dd"}, {zSBC,"a,B"}, {zRST,"V"}, {zRET,"po"}, {zPOP,"hl"}, {zJP,"po,A"}, {zEX,"(sp),hl"}, {zCALL,"po,A"}, {zPUSH,"hl"}, {zAND,"B"}, {zRST,"V"}, @@ -399,65 +378,73 @@ static const z80dasm mnemonic_main[256] = {zCALL,"m,A"}, {zDB,"fd"}, {zCP,"B"}, {zRST,"V"} }; -static char sign(int8_t offset) +char z80_disassembler::sign(s8 offset) { return (offset < 0)? '-':'+'; } -static int offs(int8_t offset) +u32 z80_disassembler::offs(s8 offset) { - if (offset < 0) return -offset; + if (offset < 0) + return -offset; return offset; } -/**************************************************************************** - * Disassemble opcode at PC and return number of bytes it takes - ****************************************************************************/ -CPU_DISASSEMBLE(z80) +z80_disassembler::z80_disassembler() { - const z80dasm *d; - const char *src, *ixy; - int8_t offset = 0; - uint8_t op, op1 = 0; - uint16_t ea; - int pos = 0; +} - ixy = "oops!!"; +u32 z80_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t z80_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + s8 offset = 0; - op = oprom[pos++]; + offs_t pos = pc; + std::string ixy = "oops!!"; + const z80dasm *d = nullptr; + u8 op = opcodes.r8(pos++); switch (op) { case 0xcb: - op = oprom[pos++]; + op = opcodes.r8(pos++); d = &mnemonic_cb[op]; break; case 0xed: - op1 = oprom[pos++]; - d = &mnemonic_ed[op1]; + d = &mnemonic_ed[opcodes.r8(pos++)]; break; case 0xdd: + { ixy = "ix"; - op1 = oprom[pos++]; + u8 op1 = opcodes.r8(pos++); if( op1 == 0xcb ) { - offset = (int8_t) opram[pos++]; - op1 = opram[pos++]; /* fourth byte from opbase.ram! */ + offset = params.r8(pos++); + op1 = params.r8(pos++); d = &mnemonic_xx_cb[op1]; } - else d = &mnemonic_xx[op1]; + else + d = &mnemonic_xx[op1]; break; + } case 0xfd: + { ixy = "iy"; - op1 = oprom[pos++]; + u8 op1 = opcodes.r8(pos++); if( op1 == 0xcb ) { - offset = (int8_t) opram[pos++]; - op1 = opram[pos++]; /* fourth byte from opbase.ram! */ + offset = params.r8(pos++); + op1 = params.r8(pos++); d = &mnemonic_xx_cb[op1]; } - else d = &mnemonic_xx[op1]; + else + d = &mnemonic_xx[op1]; break; + } default: d = &mnemonic_main[op]; break; @@ -466,47 +453,40 @@ CPU_DISASSEMBLE(z80) if( d->arguments ) { util::stream_format(stream, "%-4s ", s_mnemonic[d->mnemonic]); - src = d->arguments; + const char *src = d->arguments; while( *src ) { switch( *src ) { case '?': /* illegal opcode */ - util::stream_format(stream, "$%02x,$%02x", op, op1 ); + util::stream_format(stream, "$%02x", op ); break; case 'A': - ea = opram[pos+0] + ( opram[pos+1] << 8 ); + util::stream_format(stream, "$%04X", params.r16(pos) ); pos += 2; - util::stream_format(stream, "$%04X", ea ); break; case 'B': /* Byte op arg */ - ea = opram[pos++]; - util::stream_format(stream, "$%02X", ea ); + util::stream_format(stream, "$%02X", params.r8(pos++) ); break; case 'N': /* Immediate 16 bit */ - ea = opram[pos+0] + ( opram[pos+1] << 8 ); + util::stream_format(stream, "$%04X", params.r16(pos) ); pos += 2; - util::stream_format(stream, "$%04X", ea ); break; case 'O': /* Offset relative to PC */ - offset = (int8_t) opram[pos++]; - util::stream_format(stream, "$%04X", (pc + offset + 2) & 0xffff); + util::stream_format(stream, "$%04X", (pc + s8(params.r8(pos++)) + 2) & 0xffff); break; case 'P': /* Port number */ - ea = opram[pos++]; - util::stream_format(stream, "$%02X", ea ); + util::stream_format(stream, "$%02X", params.r8(pos++) ); break; case 'V': /* Restart vector */ - ea = op & 0x38; - util::stream_format(stream, "$%02X", ea ); + util::stream_format(stream, "$%02X", op & 0x38 ); break; case 'W': /* Memory address word */ - ea = opram[pos+0] + ( opram[pos+1] << 8 ); + util::stream_format(stream, "$%04X", params.r16(pos) ); pos += 2; - util::stream_format(stream, "$%04X", ea ); break; case 'X': - offset = (int8_t) opram[pos++]; + offset = params.r8(pos++); /* fall through */ case 'Y': util::stream_format(stream,"(%s%c$%02x)", ixy, sign(offset), offs(offset) ); @@ -525,5 +505,5 @@ CPU_DISASSEMBLE(z80) util::stream_format(stream, "%s", s_mnemonic[d->mnemonic]); } - return pos | s_flags[d->mnemonic] | DASMFLAG_SUPPORTED; + return (pos - pc) | s_flags[d->mnemonic] | SUPPORTED; } diff --git a/src/devices/cpu/z80/z80dasm.h b/src/devices/cpu/z80/z80dasm.h new file mode 100644 index 00000000000..774f4df89a8 --- /dev/null +++ b/src/devices/cpu/z80/z80dasm.h @@ -0,0 +1,56 @@ +// license:BSD-3-Clause +// copyright-holders:Juergen Buchmueller +/***************************************************************************** + * + * z80dasm.h + * Portable Z80 disassembler + * + *****************************************************************************/ + +#ifndef MAME_CPU_Z80_Z80DASM_H +#define MAME_CPU_Z80_Z80DASM_H + +#pragma once + +class z80_disassembler : public util::disasm_interface +{ +public: + z80_disassembler(); + virtual ~z80_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +protected: + struct z80dasm + { + u8 mnemonic; + const char *arguments; + }; + + enum e_mnemonics + { + zADC ,zADD ,zAND ,zBIT ,zCALL ,zCCF ,zCP ,zCPD , + zCPDR ,zCPI ,zCPIR ,zCPL ,zDAA ,zDB ,zDEC ,zDI , + zDJNZ ,zEI ,zEX ,zEXX ,zHLT ,zIM ,zIN ,zINC , + zIND ,zINDR ,zINI ,zINIR ,zJP ,zJR ,zLD ,zLDD , + zLDDR ,zLDI ,zLDIR ,zNEG ,zNOP ,zOR ,zOTDR ,zOTIR , + zOUT ,zOUTD ,zOUTI ,zPOP ,zPUSH ,zRES ,zRET ,zRETI , + zRETN ,zRL ,zRLA ,zRLC ,zRLCA ,zRLD ,zRR ,zRRA , + zRRC ,zRRCA ,zRRD ,zRST ,zSBC ,zSCF ,zSET ,zSLA , + zSLL ,zSRA ,zSRL ,zSUB ,zXOR + }; + + static inline char sign(s8 offset); + static inline u32 offs(s8 offset); + + static const u32 s_flags[]; + static const z80dasm mnemonic_xx_cb[256]; + static const z80dasm mnemonic_cb[256]; + static const z80dasm mnemonic_ed[256]; + static const z80dasm mnemonic_xx[256]; + static const z80dasm mnemonic_main[256]; + +}; + +#endif diff --git a/src/devices/cpu/z8000/8000dasm.cpp b/src/devices/cpu/z8000/8000dasm.cpp index a84d5d285e8..42a7d0abeb3 100644 --- a/src/devices/cpu/z8000/8000dasm.cpp +++ b/src/devices/cpu/z8000/8000dasm.cpp @@ -9,21 +9,543 @@ *****************************************************************************/ #include "emu.h" -#include "z8000.h" -#include "z8000cpu.h" +#include "8000dasm.h" -#include "debugger.h" -#include "debug/debugvw.h" -#include "debug/debugcon.h" +const z8000_disassembler::opcode z8000_disassembler::table[] = { + { 0x0000, 0xffff, 1, 1, ".word %#w0", 0 }, + { 0x0000, 0x000f, 1, 2, "addb %rb3,%#b3", 0 }, + { 0x0010, 0x00ff, 1, 1, "addb %rb3,@%rw2", 0 }, + { 0x0100, 0x010f, 1, 2, "add %rw3,%#w1", 0 }, + { 0x0110, 0x01ff, 1, 1, "add %rw3,@%rw2", 0 }, + { 0x0200, 0x020f, 1, 2, "subb %rb3,%#b3", 0 }, + { 0x0210, 0x02ff, 1, 1, "subb %rb3,@%rw2", 0 }, + { 0x0300, 0x030f, 1, 2, "sub %rw3,%#w1", 0 }, + { 0x0310, 0x03ff, 1, 1, "sub %rw3,@%rw2", 0 }, + { 0x0400, 0x040f, 1, 2, "orb %rb3,%#b3", 0 }, + { 0x0410, 0x04ff, 1, 1, "orb %rb3,@%rw2", 0 }, + { 0x0500, 0x050f, 1, 2, "or %rw3,%#w1", 0 }, + { 0x0510, 0x05ff, 1, 1, "or %rw3,@%rw2", 0 }, + { 0x0600, 0x060f, 1, 2, "andb %rb3,%#b3", 0 }, + { 0x0610, 0x06ff, 1, 1, "andb %rb3,@%rw2", 0 }, + { 0x0700, 0x070f, 1, 2, "and %rw3,%#w1", 0 }, + { 0x0710, 0x07ff, 1, 1, "and %rw3,@%rw2", 0 }, + { 0x0800, 0x080f, 1, 2, "xorb %rb3,%#b3", 0 }, + { 0x0810, 0x08ff, 1, 1, "xorb %rb3,@%rw2", 0 }, + { 0x0900, 0x090f, 1, 2, "xor %rw3,%#w1", 0 }, + { 0x0910, 0x09ff, 1, 1, "xor %rw3,@%rw2", 0 }, + { 0x0a00, 0x0a0f, 1, 2, "cpb %rb3,%#b3", 0 }, + { 0x0a10, 0x0aff, 1, 1, "cpb %rb3,@%rw2", 0 }, + { 0x0b00, 0x0b0f, 1, 2, "cp %rw3,%#w1", 0 }, + { 0x0b10, 0x0bff, 1, 1, "cp %rw3,@%rw2", 0 }, + { 0x0c10, 0x0cf0, 16, 1, "comb @%rw2", 0 }, + { 0x0c11, 0x0cf1, 16, 2, "cpb @%rw2,%#b3", 0 }, + { 0x0c12, 0x0cf2, 16, 1, "negb @%rw2", 0 }, + { 0x0c14, 0x0cf4, 16, 1, "testb @%rw2", 0 }, + { 0x0c15, 0x0cf5, 16, 2, "ldb @%rw2,%#b3", 0 }, + { 0x0c16, 0x0cf6, 16, 1, "tsetb @%rw2", 0 }, + { 0x0c18, 0x0cf8, 16, 1, "clrb @%rw2", 0 }, + { 0x0d10, 0x0df0, 16, 1, "com @%rw2", 0 }, + { 0x0d11, 0x0df1, 16, 2, "cp @%rw2,%#w1", 0 }, + { 0x0d12, 0x0df2, 16, 1, "neg @%rw2", 0 }, + { 0x0d14, 0x0df4, 16, 1, "test @%rw2", 0 }, + { 0x0d15, 0x0df5, 16, 2, "ld @%rw2,%#w1", 0 }, + { 0x0d16, 0x0df6, 16, 1, "tset @%rw2", 0 }, + { 0x0d18, 0x0df8, 16, 1, "clr @%rw2", 0 }, + { 0x0d19, 0x0df9, 16, 2, "push @%rw2,%#w1", 0 }, + { 0x0e00, 0x0eff, 1, 1, "ext0e %#b1", 0 }, + { 0x0f00, 0x0fff, 1, 1, "ext0f %#b1", 0 }, + { 0x1000, 0x100f, 1, 3, "cpl %rl3,%#l1", 0 }, + { 0x1010, 0x10ff, 1, 1, "cpl %rl3,@%rw2", 0 }, + { 0x1111, 0x11ff, 1, 1, "pushl @%rw2,@%rw3", 0 }, + { 0x1200, 0x120f, 1, 3, "subl %rl3,%#l1", 0 }, + { 0x1210, 0x12ff, 1, 1, "subl %rl3,@%rw2", 0 }, + { 0x1311, 0x13ff, 1, 1, "push @%rw2,@%rw3", 0 }, + { 0x1400, 0x140f, 1, 3, "ldl %rl3,%#l1", 0 }, + { 0x1410, 0x14ff, 1, 1, "ldl %rl3,@%rw2", 0 }, + { 0x1511, 0x15ff, 1, 1, "popl @%rw3,@%rw2", 0 }, + { 0x1600, 0x160f, 1, 3, "addl %rl3,%#l1", 0 }, + { 0x1610, 0x16ff, 1, 1, "addl %rl3,@%rw2", 0 }, + { 0x1711, 0x17ff, 1, 1, "pop @%rw3,@%rw2", 0 }, + { 0x1800, 0x180f, 1, 1, "multl %rq3,@%l#1", 0 }, + { 0x1810, 0x18ff, 1, 1, "multl %rq3,@%rw2", 0 }, + { 0x1900, 0x190f, 1, 2, "mult %rl3,%#w1", 0 }, + { 0x1910, 0x19ff, 1, 1, "mult %rl3,@%rw2", 0 }, + { 0x1a00, 0x1a0f, 1, 3, "divl %rq3,%#l1", 0 }, + { 0x1a10, 0x1aff, 1, 1, "divl %rq3,@%rw2", 0 }, + { 0x1b00, 0x1b0f, 1, 2, "div %rl3,%#w1", 0 }, + { 0x1b10, 0x1bff, 1, 1, "div %rl3,@%rw2", 0 }, + { 0x1c11, 0x1cf1, 16, 2, "ldm %rw5,@%rw2,#%n", 0 }, + { 0x1c18, 0x1cf8, 16, 1, "testl @%rw2", 0 }, + { 0x1c19, 0x1cf9, 16, 2, "ldm @%rw2,%rw5,#%n", 0 }, + { 0x1d10, 0x1dff, 1, 1, "ldl @%rw2,%rl3", 0 }, + { 0x1e10, 0x1eff, 1, 1, "jp %c3,@%rl2", 0 }, + { 0x1f10, 0x1ff0, 16, 1, "call %rw2", STEP_OVER }, + { 0x2000, 0x200f, 1, 2, "ldb %rb3,%#b3", 0 }, + { 0x2010, 0x20ff, 1, 1, "ldb %rb3,@%rw2", 0 }, + { 0x2100, 0x210f, 1, 2, "ld %rw3,%#w1", 0 }, + { 0x2110, 0x21ff, 1, 1, "ld %rw3,@%rw2", 0 }, + { 0x2200, 0x220f, 1, 2, "resb %rb5,%rw3", 0 }, + { 0x2210, 0x22ff, 1, 1, "resb @%rw2,%3", 0 }, + { 0x2300, 0x230f, 1, 2, "res %rw5,%rw3", 0 }, + { 0x2310, 0x23ff, 1, 1, "res @%rw2,%3", 0 }, + { 0x2400, 0x240f, 1, 2, "setb %rb5,%rw3", 0 }, + { 0x2410, 0x24ff, 1, 1, "setb @%rw2,%3", 0 }, + { 0x2500, 0x250f, 1, 2, "set %rw5,%rw3", 0 }, + { 0x2510, 0x25ff, 1, 1, "set @%rw2,%3", 0 }, + { 0x2600, 0x260f, 1, 2, "bitb %rb5,%rw3", 0 }, + { 0x2610, 0x26ff, 1, 1, "bitb @%rw2,%3", 0 }, + { 0x2700, 0x270f, 1, 2, "bit %rw5,%rw3", 0 }, + { 0x2710, 0x27ff, 1, 1, "bit @%rw2,%3", 0 }, + { 0x2810, 0x28ff, 1, 1, "incb @%rw2,%+3", 0 }, + { 0x2910, 0x29ff, 1, 1, "inc @%rw2,%+3", 0 }, + { 0x2a10, 0x2aff, 1, 1, "decb @%rw2,%+3", 0 }, + { 0x2b10, 0x2bff, 1, 1, "dec @%rw2,%+3", 0 }, + { 0x2c10, 0x2cff, 1, 1, "exb %rb3,@%rw2", 0 }, + { 0x2d10, 0x2dff, 1, 1, "ex %rw3,@%rw2", 0 }, + { 0x2e10, 0x2eff, 1, 1, "ldb @%rw2,%rb3", 0 }, + { 0x2f10, 0x2fff, 1, 1, "ld @%rw2,%rw3", 0 }, + { 0x3000, 0x300f, 1, 2, "ldrb %rb3,%p1", 0 }, + { 0x3010, 0x30ff, 1, 2, "ldb %rb3,%rw2(%#w1)", 0 }, + { 0x3100, 0x310f, 1, 2, "ldr %rw3,%p1", 0 }, + { 0x3110, 0x31ff, 1, 2, "ld %rw3,%rw2(%#w1)", 0 }, + { 0x3200, 0x320f, 1, 2, "ldrb %p1,%rb3", 0 }, + { 0x3210, 0x32ff, 1, 2, "ldb %rw2(%#w1),%rb3", 0 }, + { 0x3300, 0x330f, 1, 2, "ldr %p1,%rw3", 0 }, + { 0x3310, 0x33ff, 1, 2, "ld %rw2(%#w1),%rw3", 0 }, + { 0x3400, 0x340f, 1, 2, "ldar p%rw3,%p1", 0 }, + { 0x3410, 0x34ff, 1, 2, "lda p%rw3,%rw2(%#w1)", 0 }, + { 0x3500, 0x350f, 1, 2, "ldrl %rl3,%p1", 0 }, + { 0x3510, 0x35ff, 1, 2, "ldl %rl3,%rw2(%#w1)", 0 }, + { 0x3600, 0x3600, 1, 1, "bpt", 0 }, + { 0x3601, 0x36ff, 1, 1, "rsvd36", 0 }, + { 0x3700, 0x370f, 1, 2, "ldrl %p1,%rl3", 0 }, + { 0x3710, 0x37ff, 1, 2, "ldl %rw2(%#w1),%rl3", 0 }, + { 0x3800, 0x38ff, 1, 1, "rsvd38", 0 }, + { 0x3910, 0x39f0, 16, 1, "ldps @%rw2", 0 }, + { 0x3a00, 0x3af0, 16, 2, "%R @%rw6,@%rw2,%rw5", 0 }, + { 0x3a01, 0x3af1, 16, 2, "%R @%rw6,@%rw2,%rw5", 0 }, + { 0x3a02, 0x3af2, 16, 2, "%R @%rw6,@%rw2,%rw5", 0 }, + { 0x3a03, 0x3af3, 16, 2, "%R @%rw6,@%rw2,%rw5", 0 }, + { 0x3a04, 0x3af4, 16, 2, "%R %rb2,%#w1", 0 }, + { 0x3a05, 0x3af5, 16, 2, "%R %rb2,%#w1", 0 }, + { 0x3a06, 0x3af6, 16, 2, "%R %#w1,%rb2", 0 }, + { 0x3a07, 0x3af7, 16, 2, "%R %#w1,%rb2", 0 }, + { 0x3a08, 0x3af8, 16, 2, "%R @%rw6,@%rw2,%rw5", 0 }, + { 0x3a09, 0x3af9, 16, 2, "%R @%rw6,@%rw2,%rw5", 0 }, + { 0x3a0a, 0x3afa, 16, 2, "%R @%rw6,@%rw2,%rw5", 0 }, + { 0x3a0b, 0x3afb, 16, 2, "%R @%rw6,@%rw2,%rw5", 0 }, + { 0x3b00, 0x3bf0, 16, 2, "%R @%rw6,@%rw2,%rw5", 0 }, + { 0x3b01, 0x3bf1, 16, 2, "%R @%rw6,@%rw2,%rw5", 0 }, + { 0x3b02, 0x3bf2, 16, 2, "%R @%rw6,@%rw2,%rw5", 0 }, + { 0x3b03, 0x3bf3, 16, 2, "%R @%rw6,@%rw2,%rw5", 0 }, + { 0x3b04, 0x3bf4, 16, 2, "%R %rw2,%#w1", 0 }, + { 0x3b05, 0x3bf5, 16, 2, "%R %rw2,%#w1", 0 }, + { 0x3b06, 0x3bf6, 16, 2, "%R %#w1,%rw2", 0 }, + { 0x3b07, 0x3bf7, 16, 2, "%R %#w1,%rw2", 0 }, + { 0x3b08, 0x3bf8, 16, 2, "%R @%rw6,@%rw2,%rw5", 0 }, + { 0x3b09, 0x3bf9, 16, 2, "%R @%rw6,@%rw2,%rw5", 0 }, + { 0x3b0a, 0x3bfa, 16, 2, "%R @%rw6,@%rw2,%rb5", 0 }, + { 0x3b0b, 0x3bfb, 16, 2, "%R @%rw6,@%rw2,%rb5", 0 }, + { 0x3c00, 0x3cff, 1, 1, "inb %rb3,@%rw2", 0 }, + { 0x3d00, 0x3dff, 1, 1, "in %rw3,@%rw2", 0 }, + { 0x3e00, 0x3eff, 1, 1, "outb @%rw2,%rb3", 0 }, + { 0x3f00, 0x3fff, 1, 1, "out @%rw2,%rw3", 0 }, + { 0x4000, 0x400f, 1, 2, "addb %rb3,%a1", 0 }, + { 0x4010, 0x40ff, 1, 2, "addb %rb3,%a1(%rw2)", 0 }, + { 0x4100, 0x410f, 1, 2, "add %rw3,%a1", 0 }, + { 0x4110, 0x41ff, 1, 2, "add %rw3,%a1(%rw2)", 0 }, + { 0x4200, 0x420f, 1, 2, "subb %rb3,%a1", 0 }, + { 0x4210, 0x42ff, 1, 2, "subb %rb3,%a1(%rw2)", 0 }, + { 0x4300, 0x430f, 1, 2, "sub %rw3,%a1", 0 }, + { 0x4310, 0x43ff, 1, 2, "sub %rw3,%a1(%rw2)", 0 }, + { 0x4400, 0x440f, 1, 2, "orb %rb3,%a1", 0 }, + { 0x4410, 0x44ff, 1, 2, "orb %rb3,%a1(%rw2)", 0 }, + { 0x4500, 0x450f, 1, 2, "or %rw3,%a1", 0 }, + { 0x4510, 0x45ff, 1, 2, "or %rw3,%a1(%rw2)", 0 }, + { 0x4600, 0x460f, 1, 2, "andb %rb3,%a1", 0 }, + { 0x4610, 0x46ff, 1, 2, "andb %rb3,%a1(%rw2)", 0 }, + { 0x4700, 0x470f, 1, 2, "and %rw3,%a1", 0 }, + { 0x4710, 0x47ff, 1, 2, "and %rw3,%a1(%rw2)", 0 }, + { 0x4800, 0x480f, 1, 2, "xorb %rb3,%a1", 0 }, + { 0x4810, 0x48ff, 1, 2, "xorb %rb3,%a1(%rw2)", 0 }, + { 0x4900, 0x490f, 1, 2, "xor %rw3,%a1", 0 }, + { 0x4910, 0x49ff, 1, 2, "xor %rw3,%a1(%rw2)", 0 }, + { 0x4a00, 0x4a0f, 1, 2, "cpb %rb3,%a1", 0 }, + { 0x4a10, 0x4aff, 1, 2, "cpb %rb3,%a1(%rw2)", 0 }, + { 0x4b00, 0x4b0f, 1, 2, "cp %rw3,%a1", 0 }, + { 0x4b10, 0x4bff, 1, 2, "cp %rw3,%a1(%rw2)", 0 }, + { 0x4c00, 0x4c00, 1, 2, "comb %a1", 0 }, + { 0x4c01, 0x4c01, 1, 3, "cpb %a1,%#b3", 0 }, + { 0x4c02, 0x4c02, 1, 2, "negb %a1", 0 }, + { 0x4c04, 0x4c04, 1, 2, "testb %a1", 0 }, + { 0x4c05, 0x4c05, 1, 3, "ldb %a1,%#b3", 0 }, + { 0x4c06, 0x4c06, 1, 2, "tsetb %a1", 0 }, + { 0x4c08, 0x4c08, 1, 2, "clrb %a1", 0 }, + { 0x4c10, 0x4cf0, 16, 2, "comb %a1(%rw2)", 0 }, + { 0x4c11, 0x4cf1, 16, 3, "cpb %a1(%rw2),%#b3", 0 }, + { 0x4c12, 0x4cf2, 16, 2, "negb %a1(%rw2)", 0 }, + { 0x4c14, 0x4cf4, 16, 2, "testb %a1(%rw2)", 0 }, + { 0x4c15, 0x4cf5, 16, 3, "ldb %a1(%rw2),%#b3", 0 }, + { 0x4c16, 0x4cf6, 16, 2, "tsetb %a1(%rw2)", 0 }, + { 0x4c18, 0x4cf8, 16, 2, "clrb %a1(%rw2)", 0 }, + { 0x4d00, 0x4d00, 1, 2, "com %a1", 0 }, + { 0x4d01, 0x4d01, 1, 3, "cp %a1,%#w2", 0 }, + { 0x4d02, 0x4d02, 1, 2, "neg %a1", 0 }, + { 0x4d04, 0x4d04, 1, 2, "test %a1", 0 }, + { 0x4d05, 0x4d05, 1, 3, "ld %a1,%#w2", 0 }, + { 0x4d06, 0x4d06, 1, 2, "tset %a1", 0 }, + { 0x4d08, 0x4d08, 1, 2, "clr %a1", 0 }, + { 0x4d10, 0x4df0, 16, 2, "com %a1(%rw2)", 0 }, + { 0x4d11, 0x4df1, 16, 3, "cp %a1(%rw2),%#w2", 0 }, + { 0x4d12, 0x4df2, 16, 2, "neg %a1(%rw2)", 0 }, + { 0x4d14, 0x4df4, 16, 2, "test %a1(%rw2)", 0 }, + { 0x4d15, 0x4df5, 16, 3, "ld %a1(%rw2),%#w2", 0 }, + { 0x4d16, 0x4df6, 16, 2, "tset %a1(%rw2)", 0 }, + { 0x4d18, 0x4df8, 16, 2, "clr %a1(%rw2)", 0 }, + { 0x4e11, 0x4ef0, 16, 2, "ldb %a1(%rw2),%rb3", 0 }, + { 0x5000, 0x500f, 1, 2, "cpl %rl3,%a1", 0 }, + { 0x5010, 0x50ff, 1, 2, "cpl %rl3,%a1(%rw2)", 0 }, + { 0x5110, 0x51f0, 16, 2, "pushl @%rw2,%a1", 0 }, + { 0x5111, 0x51f1, 16, 2, "pushl @%rw2,%a1(%rw3)", 0 }, + { 0x5112, 0x51f2, 16, 2, "pushl @%rw2,%a1(%rw3)", 0 }, + { 0x5113, 0x51f3, 16, 2, "pushl @%rw2,%a1(%rw3)", 0 }, + { 0x5114, 0x51f4, 16, 2, "pushl @%rw2,%a1(%rw3)", 0 }, + { 0x5115, 0x51f5, 16, 2, "pushl @%rw2,%a1(%rw3)", 0 }, + { 0x5116, 0x51f6, 16, 2, "pushl @%rw2,%a1(%rw3)", 0 }, + { 0x5117, 0x51f7, 16, 2, "pushl @%rw2,%a1(%rw3)", 0 }, + { 0x5118, 0x51f8, 16, 2, "pushl @%rw2,%a1(%rw3)", 0 }, + { 0x5119, 0x51f9, 16, 2, "pushl @%rw2,%a1(%rw3)", 0 }, + { 0x511a, 0x51fa, 16, 2, "pushl @%rw2,%a1(%rw3)", 0 }, + { 0x511b, 0x51fb, 16, 2, "pushl @%rw2,%a1(%rw3)", 0 }, + { 0x511c, 0x51fc, 16, 2, "pushl @%rw2,%a1(%rw3)", 0 }, + { 0x511d, 0x51fd, 16, 2, "pushl @%rw2,%a1(%rw3)", 0 }, + { 0x511e, 0x51fe, 16, 2, "pushl @%rw2,%a1(%rw3)", 0 }, + { 0x511f, 0x51ff, 16, 2, "pushl @%rw2,%a1(%rw3)", 0 }, + { 0x5200, 0x520f, 1, 2, "subl %rl3,%a1", 0 }, + { 0x5210, 0x52ff, 1, 2, "subl %rl3,%a1(%rw2)", 0 }, + { 0x5310, 0x53f0, 16, 2, "push @%rw2,%a1", 0 }, + { 0x5311, 0x53f1, 16, 2, "push @%rw2,%a1(%rw3)", 0 }, + { 0x5312, 0x53f2, 16, 2, "push @%rw2,%a1(%rw3)", 0 }, + { 0x5313, 0x53f3, 16, 2, "push @%rw2,%a1(%rw3)", 0 }, + { 0x5314, 0x53f4, 16, 2, "push @%rw2,%a1(%rw3)", 0 }, + { 0x5315, 0x53f5, 16, 2, "push @%rw2,%a1(%rw3)", 0 }, + { 0x5316, 0x53f6, 16, 2, "push @%rw2,%a1(%rw3)", 0 }, + { 0x5317, 0x53f7, 16, 2, "push @%rw2,%a1(%rw3)", 0 }, + { 0x5318, 0x53f8, 16, 2, "push @%rw2,%a1(%rw3)", 0 }, + { 0x5319, 0x53f9, 16, 2, "push @%rw2,%a1(%rw3)", 0 }, + { 0x531a, 0x53fa, 16, 2, "push @%rw2,%a1(%rw3)", 0 }, + { 0x531b, 0x53fb, 16, 2, "push @%rw2,%a1(%rw3)", 0 }, + { 0x531c, 0x53fc, 16, 2, "push @%rw2,%a1(%rw3)", 0 }, + { 0x531d, 0x53fd, 16, 2, "push @%rw2,%a1(%rw3)", 0 }, + { 0x531e, 0x53fe, 16, 2, "push @%rw2,%a1(%rw3)", 0 }, + { 0x531f, 0x53ff, 16, 2, "push @%rw2,%a1(%rw3)", 0 }, + { 0x5400, 0x540f, 1, 2, "ldl %rl3,%a1", 0 }, + { 0x5410, 0x54ff, 1, 2, "ldl %rl3,%a1(%rw2)", 0 }, + { 0x5510, 0x55f0, 16, 2, "popl %a1,@%rw2", 0 }, + { 0x5511, 0x55f1, 16, 2, "popl %a1(%rw3),@%rw2", 0 }, + { 0x5512, 0x55f2, 16, 2, "popl %a1(%rw3),@%rw2", 0 }, + { 0x5513, 0x55f3, 16, 2, "popl %a1(%rw3),@%rw2", 0 }, + { 0x5514, 0x55f4, 16, 2, "popl %a1(%rw3),@%rw2", 0 }, + { 0x5515, 0x55f5, 16, 2, "popl %a1(%rw3),@%rw2", 0 }, + { 0x5516, 0x55f6, 16, 2, "popl %a1(%rw3),@%rw2", 0 }, + { 0x5517, 0x55f7, 16, 2, "popl %a1(%rw3),@%rw2", 0 }, + { 0x5518, 0x55f8, 16, 2, "popl %a1(%rw3),@%rw2", 0 }, + { 0x5519, 0x55f9, 16, 2, "popl %a1(%rw3),@%rw2", 0 }, + { 0x551a, 0x55fa, 16, 2, "popl %a1(%rw3),@%rw2", 0 }, + { 0x551b, 0x55fb, 16, 2, "popl %a1(%rw3),@%rw2", 0 }, + { 0x551c, 0x55fc, 16, 2, "popl %a1(%rw3),@%rw2", 0 }, + { 0x551d, 0x55fd, 16, 2, "popl %a1(%rw3),@%rw2", 0 }, + { 0x551e, 0x55fe, 16, 2, "popl %a1(%rw3),@%rw2", 0 }, + { 0x551f, 0x55ff, 16, 2, "popl %a1(%rw3),@%rw2", 0 }, + { 0x5600, 0x560f, 1, 2, "addl %rl3,%a1", 0 }, + { 0x5610, 0x56ff, 1, 2, "addl %rl3,%a1(%rw2)", 0 }, + { 0x5710, 0x57f0, 16, 2, "pop %a1,@%rw2", 0 }, + { 0x5711, 0x57f1, 16, 2, "pop %a1(%rw3),@%rw2", 0 }, + { 0x5712, 0x57f2, 16, 2, "pop %a1(%rw3),@%rw2", 0 }, + { 0x5713, 0x57f3, 16, 2, "pop %a1(%rw3),@%rw2", 0 }, + { 0x5714, 0x57f4, 16, 2, "pop %a1(%rw3),@%rw2", 0 }, + { 0x5715, 0x57f5, 16, 2, "pop %a1(%rw3),@%rw2", 0 }, + { 0x5716, 0x57f6, 16, 2, "pop %a1(%rw3),@%rw2", 0 }, + { 0x5717, 0x57f7, 16, 2, "pop %a1(%rw3),@%rw2", 0 }, + { 0x5718, 0x57f8, 16, 2, "pop %a1(%rw3),@%rw2", 0 }, + { 0x5719, 0x57f9, 16, 2, "pop %a1(%rw3),@%rw2", 0 }, + { 0x571a, 0x57fa, 16, 2, "pop %a1(%rw3),@%rw2", 0 }, + { 0x571b, 0x57fb, 16, 2, "pop %a1(%rw3),@%rw2", 0 }, + { 0x571c, 0x57fc, 16, 2, "pop %a1(%rw3),@%rw2", 0 }, + { 0x571d, 0x57fd, 16, 2, "pop %a1(%rw3),@%rw2", 0 }, + { 0x571e, 0x57fe, 16, 2, "pop %a1(%rw3),@%rw2", 0 }, + { 0x571f, 0x57ff, 16, 2, "pop %a1(%rw3),@%rw2", 0 }, + { 0x5800, 0x580f, 1, 2, "multl %rq3,%a1", 0 }, + { 0x5810, 0x58ff, 1, 2, "multl %rq3,%a1(%rw2)", 0 }, + { 0x5900, 0x590f, 1, 2, "mult %rl3,%a1", 0 }, + { 0x5910, 0x59ff, 1, 2, "mult %rl3,%a1(%rw2)", 0 }, + { 0x5a00, 0x5a0f, 1, 2, "divl %rq3,%a1", 0 }, + { 0x5a10, 0x5aff, 1, 2, "divl %rq3,%a1(%rw2)", 0 }, + { 0x5b00, 0x5b0f, 1, 2, "div %rl3,%a1", 0 }, + { 0x5b10, 0x5bff, 1, 2, "div %rl3,%a1(%rw2)", 0 }, + { 0x5c01, 0x5c01, 1, 3, "ldm %rw5,%a2,#%n", 0 }, + { 0x5c08, 0x5c08, 1, 2, "testl %a1", 0 }, + { 0x5c09, 0x5c09, 1, 3, "ldm %a2,%rw5,#%n", 0 }, + { 0x5c11, 0x5cf1, 16, 3, "ldm %rw5,%a2(%rw2),#%n", 0 }, + { 0x5c18, 0x5cf8, 16, 2, "testl %a1(%rw2)", 0 }, + { 0x5c19, 0x5cf9, 16, 3, "ldm %a2(%rw2),%rw5,#%n", 0 }, + { 0x5d00, 0x5d0f, 1, 2, "ldl %a1,%rl3", 0 }, + { 0x5d10, 0x5dff, 1, 2, "ldl %a1(%rw2),%rl3", 0 }, + { 0x5e00, 0x5e0f, 1, 2, "jp %c3,%a1", 0 }, + { 0x5e10, 0x5eff, 1, 2, "jp %c3,%a1(%rw2)", 0 }, + { 0x5f00, 0x5f00, 1, 2, "call %a1", STEP_OVER }, + { 0x5f10, 0x5ff0, 16, 2, "call %a1(%rw2)", STEP_OVER }, + { 0x6000, 0x600f, 1, 2, "ldb %rb3,%a1", 0 }, + { 0x6010, 0x60ff, 1, 2, "ldb %rb3,%a1(%rw2)", 0 }, + { 0x6100, 0x610f, 1, 2, "ld %rw3,%a1", 0 }, + { 0x6110, 0x61ff, 1, 2, "ld %rw3,%a1(%rw2)", 0 }, + { 0x6200, 0x620f, 1, 2, "resb %a1,%3", 0 }, + { 0x6210, 0x62ff, 1, 2, "resb %a1(%rw2),%3", 0 }, + { 0x6300, 0x630f, 1, 2, "res %a1,%3", 0 }, + { 0x6310, 0x63ff, 1, 2, "res %a1(%rw2),%3", 0 }, + { 0x6400, 0x640f, 1, 2, "setb %a1,%3", 0 }, + { 0x6410, 0x64ff, 1, 2, "setb %a1(%rw2),%3", 0 }, + { 0x6500, 0x650f, 1, 2, "set %a1,%3", 0 }, + { 0x6510, 0x65ff, 1, 2, "set %a1(%rw2),%3", 0 }, + { 0x6600, 0x660f, 1, 2, "bitb %a1,%3", 0 }, + { 0x6610, 0x66ff, 1, 2, "bitb %a1(%rw2),%3", 0 }, + { 0x6700, 0x670f, 1, 2, "bit %a1,%3", 0 }, + { 0x6710, 0x67ff, 1, 2, "bit %a1(%rw2),%3", 0 }, + { 0x6800, 0x680f, 1, 2, "incb %a1,%+3", 0 }, + { 0x6810, 0x68ff, 1, 2, "incb %a1(%rw2),%+3", 0 }, + { 0x6900, 0x690f, 1, 2, "inc %a1,%+3", 0 }, + { 0x6910, 0x69ff, 1, 2, "inc %a1(%rw2),%+3", 0 }, + { 0x6a00, 0x6a0f, 1, 2, "decb %a1,%+3", 0 }, + { 0x6a10, 0x6aff, 1, 2, "decb %a1(%rw2),%+3", 0 }, + { 0x6b00, 0x6b0f, 1, 2, "dec %a1,%+3", 0 }, + { 0x6b10, 0x6bff, 1, 2, "dec %a1(%rw2),%+3", 0 }, + { 0x6c00, 0x6c0f, 1, 2, "exb %rb3,%a1", 0 }, + { 0x6c10, 0x6cff, 1, 2, "exb %rb3,%a1(%rw2)", 0 }, + { 0x6d00, 0x6d0f, 1, 2, "ex %rw3,%a1", 0 }, + { 0x6d10, 0x6dff, 1, 2, "ex %rw3,%a1(%rw2)", 0 }, + { 0x6e00, 0x6e0f, 1, 2, "ldb %a1,%rb3", 0 }, + { 0x6e10, 0x6eff, 1, 2, "ldb %a1(%rw2),%rb3", 0 }, + { 0x6f00, 0x6f0f, 1, 2, "ld %a1,%rw3", 0 }, + { 0x6f10, 0x6fff, 1, 2, "ld %a1(%rw2),%rw3", 0 }, + { 0x7010, 0x70ff, 1, 2, "ldb %rb3,%rw2(%rw5)", 0 }, + { 0x7110, 0x71ff, 1, 2, "ld %rw3,%rw2(%rw5)", 0 }, + { 0x7210, 0x72ff, 1, 2, "ldb %rw2(%rw5),%rb3", 0 }, + { 0x7310, 0x73ff, 1, 2, "ld %rw2(%rw5),%rw3", 0 }, + { 0x7410, 0x74ff, 1, 2, "lda p%rw3,%rw2(%rw5)", 0 }, + { 0x7510, 0x75ff, 1, 2, "ldl %rl3,%rw2(%rw5)", 0 }, + { 0x7600, 0x760f, 1, 2, "lda p%rw3,%a1", 0 }, + { 0x7610, 0x76ff, 1, 2, "lda p%rw3,%a1(%rw2)", 0 }, + { 0x7710, 0x77ff, 1, 2, "ldl %rw2(%rw5),%rl3", 0 }, + { 0x7800, 0x78ff, 1, 1, "rsvd78", 0 }, + { 0x7900, 0x7900, 1, 2, "ldps %a1", 0 }, + { 0x7910, 0x79f0, 16, 2, "ldps %a1(%rw2)", 0 }, + { 0x7a00, 0x7a00, 1, 1, "halt", STEP_OVER }, + { 0x7b00, 0x7b00, 1, 1, "iret", STEP_OUT }, + { 0x7b08, 0x7b08, 1, 1, "mset", 0 }, + { 0x7b09, 0x7b09, 1, 1, "mres", 0 }, + { 0x7b0a, 0x7b0a, 1, 1, "mbit", 0 }, + { 0x7b0d, 0x7bfd, 16, 1, "mreq %rw2", 0 }, + { 0x7c00, 0x7c03, 1, 1, "di %i3", 0 }, + { 0x7c04, 0x7c07, 1, 1, "ei %i3", 0 }, + { 0x7d00, 0x7df0, 16, 1, "ldctl %rw2,ctrl0", 0 }, + { 0x7d01, 0x7df1, 16, 1, "ldctl %rw2,ctrl1", 0 }, + { 0x7d02, 0x7df2, 16, 1, "ldctl %rw2,fcw", 0 }, + { 0x7d03, 0x7df3, 16, 1, "ldctl %rw2,refresh", 0 }, + { 0x7d04, 0x7df4, 16, 1, "ldctl %rw2,psapseg", 0 }, + { 0x7d05, 0x7df5, 16, 1, "ldctl %rw2,psapoff", 0 }, + { 0x7d06, 0x7df6, 16, 1, "ldctl %rw2,nspseg", 0 }, + { 0x7d07, 0x7df7, 16, 1, "ldctl %rw2,nspoff", 0 }, + { 0x7d08, 0x7df8, 16, 1, "ldctl ctrl0,%rw2", 0 }, + { 0x7d09, 0x7df9, 16, 1, "ldctl ctrl1,%rw2", 0 }, + { 0x7d0a, 0x7dfa, 16, 1, "ldctl fcw,%rw2", 0 }, + { 0x7d0b, 0x7dfb, 16, 1, "ldctl refresh,%rw2", 0 }, + { 0x7d0c, 0x7dfc, 16, 1, "ldctl psapseg,%rw2", 0 }, + { 0x7d0d, 0x7dfd, 16, 1, "ldctl psapoff,%rw2", 0 }, + { 0x7d0e, 0x7dfe, 16, 1, "ldctl nspseg,%rw2", 0 }, + { 0x7d0f, 0x7dff, 16, 1, "ldctl nspoff,%rw2", 0 }, + { 0x7e00, 0x7eff, 1, 1, "rsvd7e %#b1", 0 }, + { 0x7f00, 0x7fff, 1, 1, "sc %#b1", STEP_OVER }, + { 0x8000, 0x80ff, 1, 1, "addb %rb3,%rb2", 0 }, + { 0x8100, 0x81ff, 1, 1, "add %rw3,%rw2", 0 }, + { 0x8200, 0x82ff, 1, 1, "subb %rb3,%rb2", 0 }, + { 0x8300, 0x83ff, 1, 1, "sub %rw3,%rw2", 0 }, + { 0x8400, 0x84ff, 1, 1, "orb %rb3,%rb2", 0 }, + { 0x8500, 0x85ff, 1, 1, "or %rw3,%rw2", 0 }, + { 0x8600, 0x86ff, 1, 1, "andb %rb3,%rb2", 0 }, + { 0x8700, 0x87ff, 1, 1, "and %rw3,%rw2", 0 }, + { 0x8800, 0x88ff, 1, 1, "xorb %rb3,%rb2", 0 }, + { 0x8900, 0x89ff, 1, 1, "xor %rw3,%rw2", 0 }, + { 0x8a00, 0x8aff, 1, 1, "cpb %rb3,%rb2", 0 }, + { 0x8b00, 0x8bff, 1, 1, "cp %rw3,%rw2", 0 }, + { 0x8c00, 0x8cf0, 16, 1, "comb %rb2", 0 }, + { 0x8c02, 0x8cf2, 16, 1, "negb %rb2", 0 }, + { 0x8c04, 0x8cf4, 16, 1, "testb %rb2", 0 }, + { 0x8c06, 0x8cf6, 16, 1, "tsetb %rb2", 0 }, + { 0x8c01, 0x8cf1, 16, 1, "ldctlb %rb2,flags", 0 }, + { 0x8c08, 0x8cf8, 16, 1, "clrb %rb2", 0 }, + { 0x8c09, 0x8cf9, 16, 1, "ldctlb flags,%rb2", 0 }, + { 0x8d00, 0x8df0, 16, 1, "com %rw2", 0 }, + { 0x8d01, 0x8df1, 16, 1, "setflg %f2", 0 }, + { 0x8d02, 0x8df2, 16, 1, "neg %rw2", 0 }, + { 0x8d03, 0x8df3, 16, 1, "resflg %f2", 0 }, + { 0x8d04, 0x8df4, 16, 1, "test %rw2", 0 }, + { 0x8d05, 0x8df5, 16, 1, "comflg %f2", 0 }, + { 0x8d06, 0x8df6, 16, 1, "tset %rw2", 0 }, + { 0x8d07, 0x8d07, 1, 1, "nop", 0 }, + { 0x8d08, 0x8df8, 16, 1, "clr %rw2", 0 }, + { 0x8e00, 0x8eff, 1, 1, "ext8e %#b1", 0 }, + { 0x8f00, 0x8fff, 1, 1, "ext8f %#b1", 0 }, + { 0x9000, 0x90ff, 1, 1, "cpl %rl3,%rl2", 0 }, + { 0x9110, 0x91ff, 1, 1, "pushl @%rw2,%rl3", 0 }, + { 0x9200, 0x92ff, 1, 1, "subl %rl3,%rl2", 0 }, + { 0x9310, 0x93ff, 1, 1, "push @%rw2,%rw3", 0 }, + { 0x9400, 0x94ff, 1, 1, "ldl %rl3,%rl2", 0 }, + { 0x9510, 0x95ff, 1, 1, "popl %rl3,@%rw2", 0 }, + { 0x9600, 0x96ff, 1, 1, "addl %rl3,%rl2", 0 }, + { 0x9710, 0x97ff, 1, 1, "pop %rw3,@%rw2", 0 }, + { 0x9800, 0x98ff, 1, 1, "multl %rq3,%rl2", 0 }, + { 0x9900, 0x99ff, 1, 1, "mult %rl3,%rw2", 0 }, + { 0x9a00, 0x9aff, 1, 1, "divl %rq3,%rl2", 0 }, + { 0x9b00, 0x9bff, 1, 1, "div %rl3,%rw2", 0 }, + { 0x9c00, 0x9cf8, 8, 1, "testl %rl2", 0 }, + { 0x9d00, 0x9dff, 1, 1, "rsvd9d", 0 }, + { 0x9e00, 0x9e0f, 1, 1, "ret %c3", STEP_OUT }, + { 0x9f00, 0x9fff, 1, 1, "rsvd9f", 0 }, + { 0xa000, 0xa0ff, 1, 1, "ldb %rb3,%rb2", 0 }, + { 0xa100, 0xa1ff, 1, 1, "ld %rw3,%rw2", 0 }, + { 0xa200, 0xa2ff, 1, 1, "resb %rb2,%3", 0 }, + { 0xa300, 0xa3ff, 1, 1, "res %rw2,%3", 0 }, + { 0xa400, 0xa4ff, 1, 1, "setb %rb2,%3", 0 }, + { 0xa500, 0xa5ff, 1, 1, "set %rw2,%3", 0 }, + { 0xa600, 0xa6ff, 1, 1, "bitb %rb2,%3", 0 }, + { 0xa700, 0xa7ff, 1, 1, "bit %rw2,%3", 0 }, + { 0xa800, 0xa8ff, 1, 1, "incb %rb2,%+3", 0 }, + { 0xa900, 0xa9ff, 1, 1, "inc %rw2,%+3", 0 }, + { 0xaa00, 0xaaff, 1, 1, "decb %rb2,%+3", 0 }, + { 0xab00, 0xabff, 1, 1, "dec %rw2,%+3", 0 }, + { 0xac00, 0xacff, 1, 1, "exb %rb3,%rb2", 0 }, + { 0xad00, 0xadff, 1, 1, "ex %rw3,%rw2", 0 }, + { 0xae00, 0xaeff, 1, 1, "tccb %c3,%rb2", 0 }, + { 0xaf00, 0xafff, 1, 1, "tcc %c3,%rw2", 0 }, + { 0xb000, 0xb0f0, 16, 1, "dab %rb2", 0 }, + { 0xb100, 0xb1f0, 16, 1, "extsb %rw2", 0 }, + { 0xb107, 0xb1f7, 16, 1, "extsl %rq2", 0 }, + { 0xb10a, 0xb1fa, 16, 1, "exts %rl2", 0 }, + { 0xb200, 0xb2f0, 16, 1, "rlb %rb2,%?3", 0 }, + { 0xb201, 0xb2f1, 16, 2, "s%*lb %rb2,%$3", 0 }, + { 0xb202, 0xb2f2, 16, 1, "rlb %rb2,%?3", 0 }, + { 0xb203, 0xb2f3, 16, 2, "sdlb %rb2,%rw5", 0 }, + { 0xb204, 0xb2f4, 16, 1, "rrb %rb2,%?3", 0 }, + { 0xb206, 0xb2f6, 16, 1, "rrb %rb2,%?3", 0 }, + { 0xb208, 0xb2f8, 16, 1, "rlcb %rb2,%?3", 0 }, + { 0xb209, 0xb2f9, 16, 2, "s%*ab %rb2,%$3", 0 }, + { 0xb20a, 0xb2fa, 16, 1, "rlcb %rb2,%?3", 0 }, + { 0xb20b, 0xb2fb, 16, 2, "sdab %rb2,%rw5", 0 }, + { 0xb20c, 0xb2fc, 16, 1, "rrcb %rb2,%?3", 0 }, + { 0xb20e, 0xb2fe, 16, 1, "rrcb %rb2,%?3", 0 }, + { 0xb300, 0xb3f0, 16, 1, "rl %rw2,%?3", 0 }, + { 0xb301, 0xb3f1, 16, 2, "s%*l %rw2,%$3", 0 }, + { 0xb302, 0xb3f2, 16, 1, "rl %rw2,%?3", 0 }, + { 0xb303, 0xb3f3, 16, 2, "sdl %rw2,%rw5", 0 }, + { 0xb304, 0xb3f4, 16, 1, "rr %rw2,%?3", 0 }, + { 0xb305, 0xb3f5, 16, 2, "s%*ll %rl2,%$3", 0 }, + { 0xb306, 0xb3f6, 16, 1, "rr %rw2,%?3", 0 }, + { 0xb307, 0xb3f7, 16, 2, "sdll %rl2,%rw5", 0 }, + { 0xb308, 0xb3f8, 16, 1, "rlc %rw2,%?3", 0 }, + { 0xb309, 0xb3f9, 16, 2, "s%*a %rw2,%$3", 0 }, + { 0xb30a, 0xb3fa, 16, 1, "rlc %rw2,%?3", 0 }, + { 0xb30b, 0xb3fb, 16, 2, "sda %rw2,%rw5", 0 }, + { 0xb30c, 0xb3fc, 16, 1, "rrc %rw2,%?3", 0 }, + { 0xb30d, 0xb3fd, 16, 2, "s%*al %rl2,%$3", 0 }, + { 0xb30e, 0xb3fe, 16, 1, "rrc %rw2,%?3", 0 }, + { 0xb30f, 0xb3ff, 16, 2, "sdal %rl2,%rw5", 0 }, + { 0xb400, 0xb4ff, 1, 1, "adcb %rb3,%rb2", 0 }, + { 0xb500, 0xb5ff, 1, 1, "adc %rw3,%rw2", 0 }, + { 0xb600, 0xb6ff, 1, 1, "sbcb %rb3,%rb2", 0 }, + { 0xb700, 0xb7ff, 1, 1, "sbc %rw3,%rw2", 0 }, + { 0xb810, 0xb8f0, 16, 2, "trib @%rw2,@%rw6,%rb5", 0 }, + { 0xb812, 0xb8f2, 16, 2, "trtib @%rw2,@%rw6,%rb5", 0 }, + { 0xb814, 0xb8f4, 16, 2, "trirb @%rw2,@%rw6,%rb5", 0 }, + { 0xb816, 0xb8f6, 16, 2, "trtirb @%rw2,@%rw6,%rb5", 0 }, + { 0xb818, 0xb8f8, 16, 2, "trdb @%rw2,@%rw6,%rb5", 0 }, + { 0xb81a, 0xb8fa, 16, 2, "trtrb @%rw2,@%rw6,%rb5", 0 }, + { 0xb81c, 0xb8fc, 16, 2, "trdrb @%rw2,@%rw6,%rb5", 0 }, + { 0xb81e, 0xb8fe, 16, 2, "trtdrb @%rw2,@%rw6,%rb5", 0 }, + { 0xb900, 0xb9ff, 16, 1, "rsvdb9", 0 }, + { 0xba10, 0xbaf0, 16, 2, "cpib %rb6,@%rw2,%rw5,%c7", 0 }, + { 0xba11, 0xbaf1, 16, 2, "ldirb @%rw6,@%rw2,%rw5", STEP_OVER }, + { 0xba12, 0xbaf2, 16, 2, "cpsib @%rw6,@%rw2,%rw5,%c7", 0 }, + { 0xba14, 0xbaf4, 16, 2, "cpirb %rb6,@%rw2,%rw5,%c7", STEP_OVER }, + { 0xba16, 0xbaf6, 16, 2, "cpsirb @%rw6,@%rw2,%rw5,%c7", STEP_OVER }, + { 0xba18, 0xbaf8, 16, 2, "cpdb %rb6,@%rw2,%rw5,%c7", 0 }, + { 0xba19, 0xbaf9, 16, 2, "lddrb @%rw2,@%rw6,%rw5", STEP_OVER }, + { 0xba1a, 0xbafa, 16, 2, "cpsdb @%rw6,@%rw2,%rw5,%c7", 0 }, + { 0xba1c, 0xbafc, 16, 2, "cpdrb %rb6,@%rw2,%rw5,%c7", STEP_OVER }, + { 0xba1e, 0xbafe, 16, 2, "cpsdrb @%rw6,@%rw2,%rw5,%c7", STEP_OVER }, + { 0xbb10, 0xbbf0, 16, 2, "cpi %rw6,@%rw2,%rw5,%c7", 0 }, + { 0xbb11, 0xbbf1, 16, 2, "ldir @%rw6,@%rw2,%rw5", STEP_OVER }, + { 0xbb12, 0xbbf2, 16, 2, "cpsi @%rw6,@%rw2,%rw5,%c7", 0 }, + { 0xbb14, 0xbbf4, 16, 2, "cpir %rw6,@%rw2,%rw5,%c7", STEP_OVER }, + { 0xbb16, 0xbbf6, 16, 2, "cpsir @%rw6,@%rw2,%rw5,%c7", STEP_OVER }, + { 0xbb18, 0xbbf8, 16, 2, "cpd %rw6,@%rw2,%rw5,%c7", 0 }, + { 0xbb19, 0xbbf9, 16, 2, "lddr @%rw2,@%rw6,%rw5", STEP_OVER }, + { 0xbb1a, 0xbbfa, 16, 2, "cpsd @%rw6,@%rw2,%rw5,%c7", 0 }, + { 0xbb1c, 0xbbfc, 16, 2, "cpdr %rw6,@%rw2,%rw5,%c7", STEP_OVER }, + { 0xbb1e, 0xbbfe, 16, 2, "cpsdr @%rw6,@%rw2,%rw5,%c7", STEP_OVER }, + { 0xbc00, 0xbcff, 1, 1, "rrdb %rb3,%rb2", 0 }, + { 0xbd00, 0xbdff, 1, 1, "ldk %rw2,%3", 0 }, + { 0xbe00, 0xbeff, 1, 1, "rldb %rb3,%rb2", 0 }, + { 0xbf00, 0xbfff, 1, 1, "rsvdbf", 0 }, + { 0xc000, 0xcfff, 1, 1, "ldb %rb1,%#b1", 0 }, + { 0xd000, 0xdfff, 1, 1, "calr %d2", STEP_OVER }, + { 0xe000, 0xefff, 1, 1, "jr %c1,%d1", 0 }, + { 0xf000, 0xf07f, 1, 1, "dbjnz %rb1,%d0", STEP_OVER }, + { 0xf100, 0xf17f, 1, 1, "dbjnz %rb1,%d0", STEP_OVER }, + { 0xf200, 0xf27f, 1, 1, "dbjnz %rb1,%d0", STEP_OVER }, + { 0xf300, 0xf37f, 1, 1, "dbjnz %rb1,%d0", STEP_OVER }, + { 0xf400, 0xf47f, 1, 1, "dbjnz %rb1,%d0", STEP_OVER }, + { 0xf500, 0xf57f, 1, 1, "dbjnz %rb1,%d0", STEP_OVER }, + { 0xf600, 0xf67f, 1, 1, "dbjnz %rb1,%d0", STEP_OVER }, + { 0xf700, 0xf77f, 1, 1, "dbjnz %rb1,%d0", STEP_OVER }, + { 0xf800, 0xf87f, 1, 1, "dbjnz %rb1,%d0", STEP_OVER }, + { 0xf900, 0xf97f, 1, 1, "dbjnz %rb1,%d0", STEP_OVER }, + { 0xfa00, 0xfa7f, 1, 1, "dbjnz %rb1,%d0", STEP_OVER }, + { 0xfb00, 0xfb7f, 1, 1, "dbjnz %rb1,%d0", STEP_OVER }, + { 0xfc00, 0xfc7f, 1, 1, "dbjnz %rb1,%d0", STEP_OVER }, + { 0xfd00, 0xfd7f, 1, 1, "dbjnz %rb1,%d0", STEP_OVER }, + { 0xfe00, 0xfe7f, 1, 1, "dbjnz %rb1,%d0", STEP_OVER }, + { 0xff00, 0xff7f, 1, 1, "dbjnz %rb1,%d0", STEP_OVER }, + { 0xf080, 0xf0ff, 1, 1, "djnz %rw1,%d0", STEP_OVER }, + { 0xf180, 0xf1ff, 1, 1, "djnz %rw1,%d0", STEP_OVER }, + { 0xf280, 0xf2ff, 1, 1, "djnz %rw1,%d0", STEP_OVER }, + { 0xf380, 0xf3ff, 1, 1, "djnz %rw1,%d0", STEP_OVER }, + { 0xf480, 0xf4ff, 1, 1, "djnz %rw1,%d0", STEP_OVER }, + { 0xf580, 0xf5ff, 1, 1, "djnz %rw1,%d0", STEP_OVER }, + { 0xf680, 0xf6ff, 1, 1, "djnz %rw1,%d0", STEP_OVER }, + { 0xf780, 0xf7ff, 1, 1, "djnz %rw1,%d0", STEP_OVER }, + { 0xf880, 0xf8ff, 1, 1, "djnz %rw1,%d0", STEP_OVER }, + { 0xf980, 0xf9ff, 1, 1, "djnz %rw1,%d0", STEP_OVER }, + { 0xfa80, 0xfaff, 1, 1, "djnz %rw1,%d0", STEP_OVER }, + { 0xfb80, 0xfbff, 1, 1, "djnz %rw1,%d0", STEP_OVER }, + { 0xfc80, 0xfcff, 1, 1, "djnz %rw1,%d0", STEP_OVER }, + { 0xfd80, 0xfdff, 1, 1, "djnz %rw1,%d0", STEP_OVER }, + { 0xfe80, 0xfeff, 1, 1, "djnz %rw1,%d0", STEP_OVER }, + { 0xff80, 0xffff, 1, 1, "djnz %rw1,%d0", STEP_OVER }, + { 0, 0, 0, 0, nullptr, 0} +}; + +z8000_disassembler::z8000_disassembler(config *conf) : m_config(conf) +{ + for (const opcode *opc = table; opc->size; opc++) + for (u32 val = opc->beg; val <= opc->end; val += opc->step) + oplist[val] = opc - table; +} -static int n[16]; /* opcode nibbles */ -static int b[8]; /* opcode bytes */ -static int w[4]; /* opcode words */ -static void GET_OP(const uint8_t *oprom, int i, unsigned offset) +void z8000_disassembler::get_op(const data_buffer &opcodes, int i, offs_t &new_pc, u16 *w, u8 *b, u8 *n) { - uint16_t opcode = (oprom[offset] << 8) | oprom[offset + 1]; + uint16_t opcode = opcodes.r16(new_pc); w[i] = opcode; b[i*2+0] = opcode >> 8; b[i*2+1] = opcode & 0xff; @@ -31,37 +553,40 @@ static void GET_OP(const uint8_t *oprom, int i, unsigned offset) n[i*4+1] = (opcode >> 8) & 0x0f; n[i*4+2] = (opcode >> 4) & 0x0f; n[i*4+3] = opcode & 0x0f; + new_pc += 2; } -static const char *const cc[16] = { +const char *const z8000_disassembler::cc[16] = { "n", "lt", "le", "ule", "pe/ov", "mi", "eq/z", "c/ult", "a", "ge", "gt", "ugt", "po/nov", "pl", "ne/nz", "nc/uge" }; -static const char *const flg[16] = { +const char *const z8000_disassembler::flg[16] = { "", "p/v", "s", "p/v,s", "z", "p/v,z", "s,z", "p/v,s,z", "c", "p/v,c","s,c", "p/v,s,c", "z,c", "p/v,z,c","s,z,c","p/v,s,z,c" }; -static const char *const ints[4] = { +const char *const z8000_disassembler::ints[4] = { "", "vi", "nvi", "vi,nvi" }; -int z8k_segm; /* Current disassembler mode: 0 - non-segmented, 1 - segmented */ -int z8k_segm_mode = Z8K_SEGM_MODE_AUTO; /* User disassembler mode setting: segmented, non-segmented, auto */ +u32 z8000_disassembler::opcode_alignment() const +{ + return 2; +} -CPU_DISASSEMBLE(z8000) +offs_t z8000_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - int new_pc = pc, i, j, tmp; + u8 n[16]; /* opcode nibbles */ + u8 b[8]; /* opcode bytes */ + u16 w[4]; /* opcode words */ + + offs_t new_pc = pc, i, j, tmp; const char *src; - z8002_device::Z8000_dasm o; uint32_t flags = 0; uint32_t old_w; - z8002_device::init_tables(); - - GET_OP(oprom, 0, new_pc - pc); - new_pc += 2; + get_op(opcodes, 0, new_pc, w, b, n); switch (pc) { case 0x0000: @@ -74,11 +599,14 @@ CPU_DISASSEMBLE(z8000) util::stream_format(stream, ".word #%%%04x ;RST PC", w[0]); break; default: - o = z8002_device::dasm(w[0]); - if (o.size > 1) { GET_OP(oprom, 1, new_pc - pc); new_pc += 2; } - if (o.size > 2) { GET_OP(oprom, 2, new_pc - pc); new_pc += 2; } + { + const opcode &o = table[oplist[w[0]]]; + if (o.size > 1) + get_op(opcodes, 1, new_pc, w, b, n); + if (o.size > 2) + get_op(opcodes, 2, new_pc, w, b, n); src = o.dasm; - flags = o.flags; + flags = o.dasmflags; while (*src) { @@ -139,14 +667,14 @@ CPU_DISASSEMBLE(z8000) tmp = ((n[1] & 0x01) << 8) + (n[3] << 4) + (n[7] & 0x08); switch (tmp) { - case 0x000: util::stream_format(stream, "inirb "); flags = DASMFLAG_STEP_OVER; break; + case 0x000: util::stream_format(stream, "inirb "); flags = STEP_OVER; break; case 0x008: util::stream_format(stream, "inib "); break; - case 0x010: util::stream_format(stream, "sinirb"); flags = DASMFLAG_STEP_OVER; break; + case 0x010: util::stream_format(stream, "sinirb"); flags = STEP_OVER; break; case 0x018: util::stream_format(stream, "sinib "); break; - case 0x020: util::stream_format(stream, "otirb "); flags = DASMFLAG_STEP_OVER; break; + case 0x020: util::stream_format(stream, "otirb "); flags = STEP_OVER; break; case 0x028: util::stream_format(stream, "outib "); break; case 0x030: util::stream_format(stream, "soutib"); break; - case 0x038: util::stream_format(stream, "sotirb"); flags = DASMFLAG_STEP_OVER; break; + case 0x038: util::stream_format(stream, "sotirb"); flags = STEP_OVER; break; case 0x040: util::stream_format(stream, "inb "); break; case 0x048: util::stream_format(stream, "inb "); break; case 0x050: util::stream_format(stream, "sinb "); break; @@ -155,22 +683,22 @@ CPU_DISASSEMBLE(z8000) case 0x068: util::stream_format(stream, "outb "); break; case 0x070: util::stream_format(stream, "soutb "); break; case 0x078: util::stream_format(stream, "soutb "); break; - case 0x080: util::stream_format(stream, "indrb "); flags = DASMFLAG_STEP_OVER; break; + case 0x080: util::stream_format(stream, "indrb "); flags = STEP_OVER; break; case 0x088: util::stream_format(stream, "indb "); break; - case 0x090: util::stream_format(stream, "sindrb"); flags = DASMFLAG_STEP_OVER; break; + case 0x090: util::stream_format(stream, "sindrb"); flags = STEP_OVER; break; case 0x098: util::stream_format(stream, "sindb "); break; - case 0x0a0: util::stream_format(stream, "otdrb "); flags = DASMFLAG_STEP_OVER; break; + case 0x0a0: util::stream_format(stream, "otdrb "); flags = STEP_OVER; break; case 0x0a8: util::stream_format(stream, "outdb "); break; case 0x0b0: util::stream_format(stream, "soutdb"); break; - case 0x0b8: util::stream_format(stream, "sotdrb"); flags = DASMFLAG_STEP_OVER; break; - case 0x100: util::stream_format(stream, "inir "); flags = DASMFLAG_STEP_OVER; break; + case 0x0b8: util::stream_format(stream, "sotdrb"); flags = STEP_OVER; break; + case 0x100: util::stream_format(stream, "inir "); flags = STEP_OVER; break; case 0x108: util::stream_format(stream, "ini "); break; - case 0x110: util::stream_format(stream, "sinir "); flags = DASMFLAG_STEP_OVER; break; + case 0x110: util::stream_format(stream, "sinir "); flags = STEP_OVER; break; case 0x118: util::stream_format(stream, "sini "); break; - case 0x120: util::stream_format(stream, "otir "); flags = DASMFLAG_STEP_OVER; break; + case 0x120: util::stream_format(stream, "otir "); flags = STEP_OVER; break; case 0x128: util::stream_format(stream, "outi "); break; case 0x130: util::stream_format(stream, "souti "); break; - case 0x138: util::stream_format(stream, "sotir "); flags = DASMFLAG_STEP_OVER; break; + case 0x138: util::stream_format(stream, "sotir "); flags = STEP_OVER; break; case 0x140: util::stream_format(stream, "in "); break; case 0x148: util::stream_format(stream, "in "); break; case 0x150: util::stream_format(stream, "sin "); break; @@ -179,14 +707,14 @@ CPU_DISASSEMBLE(z8000) case 0x168: util::stream_format(stream, "out "); break; case 0x170: util::stream_format(stream, "sout "); break; case 0x178: util::stream_format(stream, "sout "); break; - case 0x180: util::stream_format(stream, "indr "); flags = DASMFLAG_STEP_OVER; break; + case 0x180: util::stream_format(stream, "indr "); flags = STEP_OVER; break; case 0x188: util::stream_format(stream, "ind "); break; - case 0x190: util::stream_format(stream, "sindr "); flags = DASMFLAG_STEP_OVER; break; + case 0x190: util::stream_format(stream, "sindr "); flags = STEP_OVER; break; case 0x198: util::stream_format(stream, "sind "); break; - case 0x1a0: util::stream_format(stream, "otdr "); flags = DASMFLAG_STEP_OVER; break; + case 0x1a0: util::stream_format(stream, "otdr "); flags = STEP_OVER; break; case 0x1a8: util::stream_format(stream, "outd "); break; case 0x1b0: util::stream_format(stream, "soutd "); break; - case 0x1b8: util::stream_format(stream, "sotdr "); flags = DASMFLAG_STEP_OVER; break; + case 0x1b8: util::stream_format(stream, "sotdr "); flags = STEP_OVER; break; default: util::stream_format(stream, "unk(0x%x)", tmp); } @@ -195,19 +723,19 @@ CPU_DISASSEMBLE(z8000) /* address */ src++; i = *src++ - '0'; - if (z8k_segm) { + if (m_config->get_segmented_mode()) { + uint32_t address; if (w[i] & 0x8000) { old_w = w[i]; for (j = i; j < o.size; j++) w[j] = w[j + 1]; - GET_OP(oprom, o.size - 1, new_pc - pc); - new_pc += 2; - w[i] = ((old_w & 0x7f00) << 16) | (w[i] & 0xffff); + get_op(opcodes, o.size - 1, new_pc, w, b, n); + address = ((old_w & 0x7f00) << 16) | (w[i] & 0xffff); } else { - w[i] = ((w[i] & 0x7f00) << 16) | (w[i] & 0xff); + address = ((w[i] & 0x7f00) << 16) | (w[i] & 0xff); } - util::stream_format(stream, "<%%%02X>%%%04X", (w[i] >> 24) & 0xff, w[i] & 0xffff); + util::stream_format(stream, "<%%%02X>%%%04X", (address >> 24) & 0xff, address & 0xffff); } else util::stream_format(stream, "%%%04x", w[i]); break; @@ -244,7 +772,7 @@ CPU_DISASSEMBLE(z8000) tmp = 0; abort(); } - if (z8k_segm) + if (m_config->get_segmented_mode()) util::stream_format(stream, "<%%%02X>%%%04X", (tmp >> 16) & 0xff, tmp & 0xffff); else util::stream_format(stream, "%%%04x", tmp); @@ -307,7 +835,8 @@ CPU_DISASSEMBLE(z8000) } } else stream << *src++; } - break; + } + break; } - return (new_pc - pc) | flags | DASMFLAG_SUPPORTED; + return (new_pc - pc) | flags | SUPPORTED; } diff --git a/src/devices/cpu/z8000/8000dasm.h b/src/devices/cpu/z8000/8000dasm.h new file mode 100644 index 00000000000..16a2f0974e1 --- /dev/null +++ b/src/devices/cpu/z8000/8000dasm.h @@ -0,0 +1,50 @@ +// license:BSD-3-Clause +// copyright-holders:Juergen Buchmueller,Ernesto Corvi +/***************************************************************************** + * + * 8000dasm.c + * Portable Z8000(2) emulator + * + *****************************************************************************/ + +#ifndef MAME_CPU_Z8000_8000DASM_H +#define MAME_CPU_Z8000_8000DASM_H + +#pragma once + +class z8000_disassembler : public util::disasm_interface +{ +public: + struct config { + virtual ~config() = default; + virtual bool get_segmented_mode() const = 0; + }; + + z8000_disassembler(config *conf); + virtual ~z8000_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + struct opcode { + u16 beg, end, step; + u16 size; + const char *dasm; + offs_t dasmflags; + }; + + static const opcode table[]; + static const char *const cc[16]; + static const char *const flg[16]; + static const char *const ints[4]; + + config *m_config; + + u16 oplist[0x10000]; + + void get_op(const data_buffer &opcodes, int i, offs_t &new_pc, u16 *w, u8 *b, u8 *n); + +}; + +#endif diff --git a/src/devices/cpu/z8000/z8000.cpp b/src/devices/cpu/z8000/z8000.cpp index ef2326ee80c..ce2751723a8 100644 --- a/src/devices/cpu/z8000/z8000.cpp +++ b/src/devices/cpu/z8000/z8000.cpp @@ -22,10 +22,6 @@ //#define VERBOSE 1 #include "logmacro.h" - -extern int z8k_segm; -extern int z8k_segm_mode; - DEFINE_DEVICE_TYPE(Z8001, z8001_device, "z8001", "Zilog Z8001") DEFINE_DEVICE_TYPE(Z8002, z8002_device, "z8002", "Zilog Z8002") @@ -38,7 +34,6 @@ z8002_device::z8002_device(const machine_config &mconfig, const char *tag, devic z8002_device::z8002_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int addrbits, int iobits, int vecmult) : cpu_device(mconfig, type, tag, owner, clock) - , z80_daisy_chain_interface(mconfig, *this) , m_program_config("program", ENDIANNESS_BIG, 16, addrbits, 0) , m_io_config("io", ENDIANNESS_BIG, iobits, 16, 0) , m_mo_out(*this) @@ -55,12 +50,6 @@ z8001_device::z8001_device(const machine_config &mconfig, const char *tag, devic } -offs_t z8002_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) -{ - extern CPU_DISASSEMBLE( z8000 ); - return CPU_DISASSEMBLE_NAME(z8000)(this, stream, pc, oprom, opram, options); -} - device_memory_interface::space_config_vector z8002_device::memory_space_config() const { return space_config_vector { @@ -78,21 +67,14 @@ device_memory_interface::space_config_vector z8001_device::memory_space_config() }; } -/* opcode execution table */ -std::unique_ptr<z8002_device::Z8000_exec const []> z8002_device::z8000_exec; - -/* zero, sign and parity flags for logical byte operations */ -static uint8_t z8000_zsp[256]; - - -int z8002_device::segmented_mode() +bool z8002_device::get_segmented_mode() const { - return 0; + return false; } -int z8001_device::segmented_mode() +bool z8001_device::get_segmented_mode() const { - return (m_fcw & F_SEG) ? 1 : 0; + return (m_fcw & F_SEG) ? true : false; } uint32_t z8002_device::addr_add(uint32_t addr, uint32_t addend) @@ -146,7 +128,7 @@ uint32_t z8002_device::get_addr_operand(int opnum) { uint32_t seg = m_program->read_word(m_pc); m_pc += 2; - if (segmented_mode()) + if (get_segmented_mode()) { if (seg & 0x8000) { @@ -176,7 +158,7 @@ uint32_t z8002_device::get_raw_addr_operand(int opnum) { uint32_t seg = m_program->read_word(m_pc); m_pc += 2; - if (segmented_mode()) + if (get_segmented_mode()) { if (seg & 0x8000) { @@ -652,47 +634,22 @@ void z8002_device::state_string_export(const device_state_entry &entry, std::str } } -void z8001_device::z8k_disass_mode(int ref, const std::vector<std::string> ¶ms) +void z8002_device::init_tables() { - size_t len; - if (params.size() == 1) - { - len = params[0].length(); - if (!core_strnicmp(params[0].c_str(), "segmented", len) || !core_stricmp(params[0].c_str(), "z8001")) { - z8k_segm = true; - z8k_segm_mode = Z8K_SEGM_MODE_SEG; - machine().debugger().console().printf("Disassembler mode set to Z8001/segmented\n"); - } - else if (!core_strnicmp(params[0].c_str(), "non-segmented", len) || !core_stricmp(params[0].c_str(), "z8002")) - { - z8k_segm = false; - z8k_segm_mode = Z8K_SEGM_MODE_NONSEG; - machine().debugger().console().printf("Disassembler mode set to Z8002/non-segmented\n"); - } - else if (!core_strnicmp(params[0].c_str(), "automatic", len)) - { - z8k_segm_mode = Z8K_SEGM_MODE_AUTO; - machine().debugger().console().printf("Disassembler mode set to automatic\n"); - } - else - goto usage; - } - else if (params.size() > 1) - { - usage: - machine().debugger().console().printf("Usage: z8k_disass_mode <mode>\n"); - machine().debugger().console().printf(" set disassembler mode\n"); - machine().debugger().console().printf(" mode: \"segmented\" or \"z8001\" - Z8001 mode\n"); - machine().debugger().console().printf(" \"non-segmented\" or \"z8002\" - Z8002 mode\n"); - machine().debugger().console().printf(" \"automatic\" - automatic mode\n"); - } - else - { - machine().debugger().console().printf("Current disassembler mode: "); - if (z8k_segm_mode == Z8K_SEGM_MODE_AUTO) - machine().debugger().console().printf("automatic, currently "); - machine().debugger().console().printf("%s\n", z8k_segm ? "Z8001/segmented" : "Z8002/non-segmented"); - } + /* set up the zero, sign, parity lookup table */ + for (int i = 0; i < 256; i++) + z8000_zsp[i] = ((i == 0) ? F_Z : 0) | + ((i & 128) ? F_S : 0) | + ((((i>>7)^(i>>6)^(i>>5)^(i>>4)^(i>>3)^(i>>2)^(i>>1)^i) & 1) ? 0 : F_PV); + + for (const Z8000_init *opc = table; opc->size; opc++) + for (u32 val = opc->beg; val <= opc->end; val += opc->step) + z8000_exec[val] = opc - table; +} + +util::disasm_interface *z8002_device::create_disassembler() +{ + return new z8000_disassembler(this); } void z8001_device::device_start() @@ -706,19 +663,11 @@ void z8001_device::device_start() m_data = &space(AS_DATA); else m_data = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); init_tables(); - if (machine().debug_flags & DEBUG_FLAG_ENABLED) - { - using namespace std::placeholders; - machine().debugger().console().register_command("z8k_disass_mode", CMDFLAG_NONE, 0, 0, 1, std::bind(&z8001_device::z8k_disass_mode, this, _1, _2)); - } - - z8k_segm = true; - register_debug_state(); m_icountptr = &m_icount; @@ -737,13 +686,11 @@ void z8002_device::device_start() m_data = &space(AS_DATA); else m_data = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); init_tables(); - z8k_segm = false; - register_debug_state(); m_icountptr = &m_icount; @@ -774,8 +721,6 @@ void z8002_device::device_reset() z8002_device::~z8002_device() { - // FIXME: assumes that these CPUs can't outlive each other - deinit_tables(); } void z8002_device::execute_run() @@ -786,9 +731,6 @@ void z8002_device::execute_run() if (m_irq_req) Interrupt(); - if (z8k_segm_mode == Z8K_SEGM_MODE_AUTO) - z8k_segm = (m_fcw & F_SEG_Z8001()) ? 1 : 0; - m_ppc = m_pc; debugger_instruction_hook(this, m_pc); @@ -800,10 +742,10 @@ void z8002_device::execute_run() { m_op[0] = RDOP(); m_op_valid = 1; - Z8000_exec const *const exec = &z8000_exec[m_op[0]]; + const Z8000_init &exec = table[z8000_exec[m_op[0]]]; - m_icount -= exec->cycles; - (this->*exec->opcode)(); + m_icount -= exec.cycles; + (this->*exec.opcode)(); m_op_valid = 0; } } while (m_icount > 0); diff --git a/src/devices/cpu/z8000/z8000.h b/src/devices/cpu/z8000/z8000.h index aa9382e75d7..4e3f69e5858 100644 --- a/src/devices/cpu/z8000/z8000.h +++ b/src/devices/cpu/z8000/z8000.h @@ -5,8 +5,7 @@ #pragma once -#include "cpu/z80/z80daisy.h" - +#include "8000dasm.h" enum { @@ -33,7 +32,7 @@ enum #define MCFG_Z8000_MO(_devcb) \ devcb = &z8002_device::set_mo_callback(*device, DEVCB_##_devcb); -class z8002_device : public cpu_device, public z80_daisy_chain_interface +class z8002_device : public cpu_device, public z8000_disassembler::config { public: // construction/destruction @@ -43,12 +42,6 @@ public: template <class Object> static devcb_base &set_mo_callback(device_t &device, Object &&cb) { return downcast<z8002_device &>(device).m_mo_out.set_callback(std::forward<Object>(cb)); } DECLARE_WRITE_LINE_MEMBER(mi_w) { m_mi = state; } // XXX: this has to apply in the middle of an insn for now - struct Z8000_dasm { char const *dasm; uint32_t flags; int size; }; - - static void init_tables(); - static void deinit_tables(); - static Z8000_dasm dasm(unsigned w); - protected: z8002_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int addrbits, int iobits, int vecmult); @@ -71,9 +64,9 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 6; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; + + void init_tables(); address_space_config m_program_config; address_space_config m_io_config; @@ -103,14 +96,14 @@ protected: int m_mi; address_space *m_program; address_space *m_data; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_io; int m_icount; int m_vector_mult; void clear_internal_state(); void register_debug_state(); - virtual int segmented_mode(); + virtual bool get_segmented_mode() const override; static inline uint32_t addr_add(uint32_t addr, uint32_t addend); static inline uint32_t addr_sub(uint32_t addr, uint32_t subtrahend); inline uint16_t RDOP(); @@ -630,22 +623,14 @@ private: int beg, end, step; int size, cycles; opcode_func opcode; - const char *dasm; - uint32_t dasmflags; - }; - - /* structure for the opcode execution table / disassembler */ - struct Z8000_exec { - opcode_func opcode; - int cycles; - int size; - const char *dasm; - uint32_t dasmflags; }; /* opcode execution table */ static const Z8000_init table[]; - static std::unique_ptr<Z8000_exec const []> z8000_exec; + u16 z8000_exec[0x10000]; + + /* zero, sign and parity flags for logical byte operations */ + u8 z8000_zsp[256]; }; @@ -663,12 +648,9 @@ protected: // device_memory_interface overrides virtual space_config_vector memory_space_config() const override; - // device_disasm_interface overrides - virtual uint32_t disasm_max_opcode_bytes() const override { return 8; } - address_space_config m_data_config; - virtual int segmented_mode() override; + virtual bool get_segmented_mode() const override; virtual uint32_t adjust_addr_for_nonseg_mode(uint32_t addr) override; virtual uint16_t RDPORT_W(int mode, uint16_t addr) override; virtual void WRPORT_W(int mode, uint16_t addr, uint16_t value) override; @@ -679,9 +661,6 @@ protected: virtual uint32_t F_SEG_Z8001() override; virtual uint32_t PSA_ADDR() override; virtual uint32_t read_irq_vector() override; - -private: - void z8k_disass_mode(int ref, const std::vector<std::string> ¶ms); }; diff --git a/src/devices/cpu/z8000/z8000cpu.h b/src/devices/cpu/z8000/z8000cpu.h index 102cac41f0e..dc65a8dc3df 100644 --- a/src/devices/cpu/z8000/z8000cpu.h +++ b/src/devices/cpu/z8000/z8000cpu.h @@ -42,7 +42,7 @@ #define RQ(n) m_regs.Q[(n) >> 2] /* the register used as stack pointer */ -#define SP (segmented_mode() ? 14 : 15) +#define SP (get_segmented_mode() ? 14 : 15) /* these vectors are based on m_psap */ #define RST (PSA_ADDR() + 0) /* start up m_fcw and m_pc */ diff --git a/src/devices/cpu/z8000/z8000ops.hxx b/src/devices/cpu/z8000/z8000ops.hxx index bde18d4d70b..4599538525f 100644 --- a/src/devices/cpu/z8000/z8000ops.hxx +++ b/src/devices/cpu/z8000/z8000ops.hxx @@ -96,7 +96,7 @@ uint32_t z8002_device::segmented_addr(uint32_t addr) uint32_t z8002_device::addr_from_reg(int regno) { - if (segmented_mode()) + if (get_segmented_mode()) return segmented_addr(RL(regno)); else return RW(regno); @@ -104,7 +104,7 @@ uint32_t z8002_device::addr_from_reg(int regno) void z8002_device::addr_to_reg(int regno, uint32_t addr) { - if (segmented_mode()) { + if (get_segmented_mode()) { uint32_t segaddr = make_segmented_addr(addr); RW(regno) = (RW(regno) & 0x80ff) | ((segaddr >> 16) & 0x7f00); RW(regno | 1) = segaddr & 0xffff; @@ -115,21 +115,21 @@ void z8002_device::addr_to_reg(int regno, uint32_t addr) void z8002_device::add_to_addr_reg(int regno, uint16_t addend) { - if (segmented_mode()) + if (get_segmented_mode()) regno |= 1; RW(regno) += addend; } void z8002_device::sub_from_addr_reg(int regno, uint16_t subtrahend) { - if (segmented_mode()) + if (get_segmented_mode()) regno |= 1; RW(regno) -= subtrahend; } void z8002_device::set_pc(uint32_t addr) { - if (segmented_mode()) + if (get_segmented_mode()) m_pc = addr; else m_pc = (m_pc & 0xffff0000) | (addr & 0xffff); @@ -137,7 +137,7 @@ void z8002_device::set_pc(uint32_t addr) void z8002_device::PUSHW(uint8_t dst, uint16_t value) { - if (segmented_mode()) + if (get_segmented_mode()) RW(dst | 1) -= 2; else RW(dst) -= 2; @@ -147,7 +147,7 @@ void z8002_device::PUSHW(uint8_t dst, uint16_t value) uint16_t z8002_device::POPW(uint8_t src) { uint16_t result = RDMEM_W(AS_DATA, addr_from_reg(src)); - if (segmented_mode()) + if (get_segmented_mode()) RW(src | 1) += 2; else RW(src) += 2; @@ -156,7 +156,7 @@ uint16_t z8002_device::POPW(uint8_t src) void z8002_device::PUSHL(uint8_t dst, uint32_t value) { - if (segmented_mode()) + if (get_segmented_mode()) RW(dst | 1) -= 4; else RW(dst) -= 4; @@ -166,7 +166,7 @@ void z8002_device::PUSHL(uint8_t dst, uint32_t value) uint32_t z8002_device::POPL(uint8_t src) { uint32_t result = RDMEM_L(AS_DATA, addr_from_reg(src)); - if (segmented_mode()) + if (get_segmented_mode()) RW(src | 1) += 4; else RW(src) += 4; @@ -1971,7 +1971,7 @@ void z8002_device::Z1E_ddN0_cccc() void z8002_device::Z1F_ddN0_0000() { GET_DST(OP0,NIB2); - if (segmented_mode()) + if (get_segmented_mode()) PUSHL(SP, make_segmented_addr(m_pc)); else PUSHW(SP, m_pc); @@ -2361,7 +2361,7 @@ void z8002_device::Z34_ssN0_dddd_imm16() GET_DST(OP0,NIB3); GET_SRC(OP0,NIB2); GET_IDX16(OP1); - if (segmented_mode()) { + if (get_segmented_mode()) { RL(dst) = RL(src); } else { @@ -2465,7 +2465,7 @@ void z8002_device::Z39_ssN0_0000() CHECK_PRIVILEGED_INSTR(); GET_SRC(OP0,NIB2); uint16_t fcw; - if (segmented_mode()) { + if (get_segmented_mode()) { uint32_t addr = addr_from_reg(src); fcw = RDMEM_W(AS_DATA, addr + 2); set_pc(segmented_addr(RDMEM_L(AS_DATA, addr + 4))); @@ -3995,7 +3995,7 @@ void z8002_device::Z5E_ddN0_cccc_addr() void z8002_device::Z5F_0000_0000_addr() { GET_ADDR(OP1); - if (segmented_mode()) + if (get_segmented_mode()) PUSHL(SP, make_segmented_addr(m_pc)); else PUSHW(SP, m_pc); @@ -4010,7 +4010,7 @@ void z8002_device::Z5F_ddN0_0000_addr() { GET_DST(OP0,NIB2); GET_ADDR(OP1); - if (segmented_mode()) + if (get_segmented_mode()) PUSHL(SP, make_segmented_addr(m_pc)); else PUSHW(SP, m_pc); @@ -4469,7 +4469,7 @@ void z8002_device::Z74_ssN0_dddd_0000_xxxx_0000_0000() GET_DST(OP0,NIB3); GET_SRC(OP0,NIB2); GET_IDX(OP1,NIB1); - if (segmented_mode()) { + if (get_segmented_mode()) { RL(dst) = RL(src); } else { @@ -4498,7 +4498,7 @@ void z8002_device::Z76_0000_dddd_addr() { GET_DST(OP0,NIB3); GET_ADDR_RAW(OP1); - if (segmented_mode()) { + if (get_segmented_mode()) { RL(dst) = addr; } else { @@ -4516,7 +4516,7 @@ void z8002_device::Z76_ssN0_dddd_addr() GET_SRC(OP0,NIB2); GET_ADDR_RAW(OP1); uint16_t temp = RW(src); // store src in case dst == src - if (segmented_mode()) { + if (get_segmented_mode()) { RL(dst) = addr; } else { @@ -4560,7 +4560,7 @@ void z8002_device::Z79_0000_0000_addr() CHECK_PRIVILEGED_INSTR(); GET_ADDR(OP1); uint16_t fcw; - if (segmented_mode()) { + if (get_segmented_mode()) { fcw = RDMEM_W(AS_DATA, addr + 2); set_pc(segmented_addr(RDMEM_L(AS_DATA, addr + 4))); } @@ -4582,7 +4582,7 @@ void z8002_device::Z79_ssN0_0000_addr() GET_ADDR(OP1); uint16_t fcw; addr = addr_add(addr, RW(src)); - if (segmented_mode()) { + if (get_segmented_mode()) { fcw = RDMEM_W(AS_DATA, addr + 2); set_pc(segmented_addr(RDMEM_L(AS_DATA, addr + 4))); } @@ -4615,7 +4615,7 @@ void z8002_device::Z7B_0000_0000() CHECK_PRIVILEGED_INSTR(); tag = POPW(SP); /* get type tag */ fcw = POPW(SP); /* get m_fcw */ - if (segmented_mode()) + if (get_segmented_mode()) set_pc(segmented_addr(POPL(SP))); else m_pc = POPW(SP); /* get m_pc */ @@ -5289,7 +5289,7 @@ void z8002_device::Z9D_imm8() void z8002_device::Z9E_0000_cccc() { GET_CCC(OP0,NIB3); - if (segmented_mode()) + if (get_segmented_mode()) switch (cc) { case 0: if (CC0) set_pc(segmented_addr(POPL(SP))); break; case 1: if (CC1) set_pc(segmented_addr(POPL(SP))); break; @@ -6746,7 +6746,7 @@ void z8002_device::ZC_dddd_imm8() void z8002_device::ZD_dsp12() { int16_t dsp12 = m_op[0] & 0xfff; - if (segmented_mode()) + if (get_segmented_mode()) PUSHL(SP, make_segmented_addr(m_pc)); else PUSHW(SP, m_pc); diff --git a/src/devices/cpu/z8000/z8000tbl.hxx b/src/devices/cpu/z8000/z8000tbl.hxx index 7ebbeb4d071..0d54009a7f4 100644 --- a/src/devices/cpu/z8000/z8000tbl.hxx +++ b/src/devices/cpu/z8000/z8000tbl.hxx @@ -9,583 +9,525 @@ *****************************************************************************/ const z8002_device::Z8000_init z8002_device::table[] = { -{0x0000,0x000f, 1,2, 7,&z8002_device::Z00_0000_dddd_imm8, "addb %rb3,%#b3", 0}, -{0x0010,0x00ff, 1,1, 7,&z8002_device::Z00_ssN0_dddd, "addb %rb3,@%rw2", 0}, -{0x0100,0x010f, 1,2, 7,&z8002_device::Z01_0000_dddd_imm16, "add %rw3,%#w1", 0}, -{0x0110,0x01ff, 1,1, 7,&z8002_device::Z01_ssN0_dddd, "add %rw3,@%rw2", 0}, -{0x0200,0x020f, 1,2, 7,&z8002_device::Z02_0000_dddd_imm8, "subb %rb3,%#b3", 0}, -{0x0210,0x02ff, 1,1, 7,&z8002_device::Z02_ssN0_dddd, "subb %rb3,@%rw2", 0}, -{0x0300,0x030f, 1,2, 7,&z8002_device::Z03_0000_dddd_imm16, "sub %rw3,%#w1", 0}, -{0x0310,0x03ff, 1,1, 7,&z8002_device::Z03_ssN0_dddd, "sub %rw3,@%rw2", 0}, -{0x0400,0x040f, 1,2, 7,&z8002_device::Z04_0000_dddd_imm8, "orb %rb3,%#b3", 0}, -{0x0410,0x04ff, 1,1, 7,&z8002_device::Z04_ssN0_dddd, "orb %rb3,@%rw2", 0}, -{0x0500,0x050f, 1,2, 7,&z8002_device::Z05_0000_dddd_imm16, "or %rw3,%#w1", 0}, -{0x0510,0x05ff, 1,1, 7,&z8002_device::Z05_ssN0_dddd, "or %rw3,@%rw2", 0}, -{0x0600,0x060f, 1,2, 7,&z8002_device::Z06_0000_dddd_imm8, "andb %rb3,%#b3", 0}, -{0x0610,0x06ff, 1,1, 7,&z8002_device::Z06_ssN0_dddd, "andb %rb3,@%rw2", 0}, -{0x0700,0x070f, 1,2, 7,&z8002_device::Z07_0000_dddd_imm16, "and %rw3,%#w1", 0}, -{0x0710,0x07ff, 1,1, 7,&z8002_device::Z07_ssN0_dddd, "and %rw3,@%rw2", 0}, -{0x0800,0x080f, 1,2, 7,&z8002_device::Z08_0000_dddd_imm8, "xorb %rb3,%#b3", 0}, -{0x0810,0x08ff, 1,1, 7,&z8002_device::Z08_ssN0_dddd, "xorb %rb3,@%rw2", 0}, -{0x0900,0x090f, 1,2, 7,&z8002_device::Z09_0000_dddd_imm16, "xor %rw3,%#w1", 0}, -{0x0910,0x09ff, 1,1, 7,&z8002_device::Z09_ssN0_dddd, "xor %rw3,@%rw2", 0}, -{0x0a00,0x0a0f, 1,2, 7,&z8002_device::Z0A_0000_dddd_imm8, "cpb %rb3,%#b3", 0}, -{0x0a10,0x0aff, 1,1, 7,&z8002_device::Z0A_ssN0_dddd, "cpb %rb3,@%rw2", 0}, -{0x0b00,0x0b0f, 1,2, 7,&z8002_device::Z0B_0000_dddd_imm16, "cp %rw3,%#w1", 0}, -{0x0b10,0x0bff, 1,1, 7,&z8002_device::Z0B_ssN0_dddd, "cp %rw3,@%rw2", 0}, -{0x0c10,0x0cf0,16,1, 12,&z8002_device::Z0C_ddN0_0000, "comb @%rw2", 0}, -{0x0c11,0x0cf1,16,2, 11,&z8002_device::Z0C_ddN0_0001_imm8, "cpb @%rw2,%#b3", 0}, -{0x0c12,0x0cf2,16,1, 12,&z8002_device::Z0C_ddN0_0010, "negb @%rw2", 0}, -{0x0c14,0x0cf4,16,1, 8,&z8002_device::Z0C_ddN0_0100, "testb @%rw2", 0}, -{0x0c15,0x0cf5,16,2, 7,&z8002_device::Z0C_ddN0_0101_imm8, "ldb @%rw2,%#b3", 0}, -{0x0c16,0x0cf6,16,1, 11,&z8002_device::Z0C_ddN0_0110, "tsetb @%rw2", 0}, -{0x0c18,0x0cf8,16,1, 8,&z8002_device::Z0C_ddN0_1000, "clrb @%rw2", 0}, -{0x0d10,0x0df0,16,1, 12,&z8002_device::Z0D_ddN0_0000, "com @%rw2", 0}, -{0x0d11,0x0df1,16,2, 11,&z8002_device::Z0D_ddN0_0001_imm16, "cp @%rw2,%#w1", 0}, -{0x0d12,0x0df2,16,1, 12,&z8002_device::Z0D_ddN0_0010, "neg @%rw2", 0}, -{0x0d14,0x0df4,16,1, 8,&z8002_device::Z0D_ddN0_0100, "test @%rw2", 0}, -{0x0d15,0x0df5,16,2, 11,&z8002_device::Z0D_ddN0_0101_imm16, "ld @%rw2,%#w1", 0}, /* fix cycles ld IR,IM */ -{0x0d16,0x0df6,16,1, 11,&z8002_device::Z0D_ddN0_0110, "tset @%rw2", 0}, -{0x0d18,0x0df8,16,1, 8,&z8002_device::Z0D_ddN0_1000, "clr @%rw2", 0}, -{0x0d19,0x0df9,16,2, 12,&z8002_device::Z0D_ddN0_1001_imm16, "push @%rw2,%#w1", 0}, -{0x0e00,0x0eff, 1,1, 10,&z8002_device::Z0E_imm8, "ext0e %#b1", 0}, -{0x0f00,0x0fff, 1,1, 10,&z8002_device::Z0F_imm8, "ext0f %#b1", 0}, -{0x1000,0x100f, 1,3, 14,&z8002_device::Z10_0000_dddd_imm32, "cpl %rl3,%#l1", 0}, -{0x1010,0x10ff, 1,1, 14,&z8002_device::Z10_ssN0_dddd, "cpl %rl3,@%rw2", 0}, -{0x1111,0x11ff, 1,1, 20,&z8002_device::Z11_ddN0_ssN0, "pushl @%rw2,@%rw3", 0}, -{0x1200,0x120f, 1,3, 14,&z8002_device::Z12_0000_dddd_imm32, "subl %rl3,%#l1", 0}, -{0x1210,0x12ff, 1,1, 14,&z8002_device::Z12_ssN0_dddd, "subl %rl3,@%rw2", 0}, -{0x1311,0x13ff, 1,1, 13,&z8002_device::Z13_ddN0_ssN0, "push @%rw2,@%rw3", 0}, -{0x1400,0x140f, 1,3, 11,&z8002_device::Z14_0000_dddd_imm32, "ldl %rl3,%#l1", 0}, -{0x1410,0x14ff, 1,1, 11,&z8002_device::Z14_ssN0_dddd, "ldl %rl3,@%rw2", 0}, -{0x1511,0x15ff, 1,1, 19,&z8002_device::Z15_ssN0_ddN0, "popl @%rw3,@%rw2", 0}, -{0x1600,0x160f, 1,3, 14,&z8002_device::Z16_0000_dddd_imm32, "addl %rl3,%#l1", 0}, -{0x1610,0x16ff, 1,1, 14,&z8002_device::Z16_ssN0_dddd, "addl %rl3,@%rw2", 0}, -{0x1711,0x17ff, 1,1, 12,&z8002_device::Z17_ssN0_ddN0, "pop @%rw3,@%rw2", 0}, -{0x1800,0x180f, 1,1,282,&z8002_device::Z18_00N0_dddd_imm32, "multl %rq3,@%l#1", 0}, -{0x1810,0x18ff, 1,1,282,&z8002_device::Z18_ssN0_dddd, "multl %rq3,@%rw2", 0}, -{0x1900,0x190f, 1,2, 70,&z8002_device::Z19_0000_dddd_imm16, "mult %rl3,%#w1", 0}, -{0x1910,0x19ff, 1,1, 70,&z8002_device::Z19_ssN0_dddd, "mult %rl3,@%rw2", 0}, -{0x1a00,0x1a0f, 1,3,744,&z8002_device::Z1A_0000_dddd_imm32, "divl %rq3,%#l1", 0}, -{0x1a10,0x1aff, 1,1,744,&z8002_device::Z1A_ssN0_dddd, "divl %rq3,@%rw2", 0}, -{0x1b00,0x1b0f, 1,2,107,&z8002_device::Z1B_0000_dddd_imm16, "div %rl3,%#w1", 0}, -{0x1b10,0x1bff, 1,1,107,&z8002_device::Z1B_ssN0_dddd, "div %rl3,@%rw2", 0}, -{0x1c11,0x1cf1,16,2, 11,&z8002_device::Z1C_ssN0_0001_0000_dddd_0000_nmin1, "ldm %rw5,@%rw2,#%n", 0}, -{0x1c18,0x1cf8,16,1, 13,&z8002_device::Z1C_ddN0_1000, "testl @%rw2", 0}, -{0x1c19,0x1cf9,16,2, 11,&z8002_device::Z1C_ddN0_1001_0000_ssss_0000_nmin1, "ldm @%rw2,%rw5,#%n", 0}, -{0x1d10,0x1dff, 1,1, 11,&z8002_device::Z1D_ddN0_ssss, "ldl @%rw2,%rl3", 0}, -{0x1e10,0x1eff, 1,1, 10,&z8002_device::Z1E_ddN0_cccc, "jp %c3,@%rl2", 0}, -{0x1f10,0x1ff0,16,1, 10,&z8002_device::Z1F_ddN0_0000, "call %rw2", DASMFLAG_STEP_OVER}, -{0x2000,0x200f, 1,2, 7,&z8002_device::Z20_0000_dddd_imm8, "ldb %rb3,%#b3", 0}, -{0x2010,0x20ff, 1,1, 7,&z8002_device::Z20_ssN0_dddd, "ldb %rb3,@%rw2", 0}, -{0x2100,0x210f, 1,2, 7,&z8002_device::Z21_0000_dddd_imm16, "ld %rw3,%#w1", 0}, -{0x2110,0x21ff, 1,1, 7,&z8002_device::Z21_ssN0_dddd, "ld %rw3,@%rw2", 0}, -{0x2200,0x220f, 1,2, 10,&z8002_device::Z22_0000_ssss_0000_dddd_0000_0000, "resb %rb5,%rw3", 0}, -{0x2210,0x22ff, 1,1, 11,&z8002_device::Z22_ddN0_imm4, "resb @%rw2,%3", 0}, -{0x2300,0x230f, 1,2, 10,&z8002_device::Z23_0000_ssss_0000_dddd_0000_0000, "res %rw5,%rw3", 0}, -{0x2310,0x23ff, 1,1, 11,&z8002_device::Z23_ddN0_imm4, "res @%rw2,%3", 0}, -{0x2400,0x240f, 1,2, 10,&z8002_device::Z24_0000_ssss_0000_dddd_0000_0000, "setb %rb5,%rw3", 0}, -{0x2410,0x24ff, 1,1, 11,&z8002_device::Z24_ddN0_imm4, "setb @%rw2,%3", 0}, -{0x2500,0x250f, 1,2, 10,&z8002_device::Z25_0000_ssss_0000_dddd_0000_0000, "set %rw5,%rw3", 0}, -{0x2510,0x25ff, 1,1, 11,&z8002_device::Z25_ddN0_imm4, "set @%rw2,%3", 0}, -{0x2600,0x260f, 1,2, 10,&z8002_device::Z26_0000_ssss_0000_dddd_0000_0000, "bitb %rb5,%rw3", 0}, -{0x2610,0x26ff, 1,1, 8,&z8002_device::Z26_ddN0_imm4, "bitb @%rw2,%3", 0}, -{0x2700,0x270f, 1,2, 10,&z8002_device::Z27_0000_ssss_0000_dddd_0000_0000, "bit %rw5,%rw3", 0}, -{0x2710,0x27ff, 1,1, 8,&z8002_device::Z27_ddN0_imm4, "bit @%rw2,%3", 0}, -{0x2810,0x28ff, 1,1, 11,&z8002_device::Z28_ddN0_imm4m1, "incb @%rw2,%+3", 0}, -{0x2910,0x29ff, 1,1, 11,&z8002_device::Z29_ddN0_imm4m1, "inc @%rw2,%+3", 0}, -{0x2a10,0x2aff, 1,1, 11,&z8002_device::Z2A_ddN0_imm4m1, "decb @%rw2,%+3", 0}, -{0x2b10,0x2bff, 1,1, 11,&z8002_device::Z2B_ddN0_imm4m1, "dec @%rw2,%+3", 0}, -{0x2c10,0x2cff, 1,1, 12,&z8002_device::Z2C_ssN0_dddd, "exb %rb3,@%rw2", 0}, -{0x2d10,0x2dff, 1,1, 12,&z8002_device::Z2D_ssN0_dddd, "ex %rw3,@%rw2", 0}, -{0x2e10,0x2eff, 1,1, 8,&z8002_device::Z2E_ddN0_ssss, "ldb @%rw2,%rb3", 0}, -{0x2f10,0x2fff, 1,1, 8,&z8002_device::Z2F_ddN0_ssss, "ld @%rw2,%rw3", 0}, -{0x3000,0x300f, 1,2, 14,&z8002_device::Z30_0000_dddd_dsp16, "ldrb %rb3,%p1", 0}, -{0x3010,0x30ff, 1,2, 14,&z8002_device::Z30_ssN0_dddd_imm16, "ldb %rb3,%rw2(%#w1)", 0}, -{0x3100,0x310f, 1,2, 14,&z8002_device::Z31_0000_dddd_dsp16, "ldr %rw3,%p1", 0}, -{0x3110,0x31ff, 1,2, 14,&z8002_device::Z31_ssN0_dddd_imm16, "ld %rw3,%rw2(%#w1)", 0}, -{0x3200,0x320f, 1,2, 14,&z8002_device::Z32_0000_ssss_dsp16, "ldrb %p1,%rb3", 0}, -{0x3210,0x32ff, 1,2, 14,&z8002_device::Z32_ddN0_ssss_imm16, "ldb %rw2(%#w1),%rb3", 0}, -{0x3300,0x330f, 1,2, 14,&z8002_device::Z33_0000_ssss_dsp16, "ldr %p1,%rw3", 0}, -{0x3310,0x33ff, 1,2, 14,&z8002_device::Z33_ddN0_ssss_imm16, "ld %rw2(%#w1),%rw3", 0}, -{0x3400,0x340f, 1,2, 15,&z8002_device::Z34_0000_dddd_dsp16, "ldar p%rw3,%p1", 0}, -{0x3410,0x34ff, 1,2, 15,&z8002_device::Z34_ssN0_dddd_imm16, "lda p%rw3,%rw2(%#w1)", 0}, -{0x3500,0x350f, 1,2, 17,&z8002_device::Z35_0000_dddd_dsp16, "ldrl %rl3,%p1", 0}, -{0x3510,0x35ff, 1,2, 17,&z8002_device::Z35_ssN0_dddd_imm16, "ldl %rl3,%rw2(%#w1)", 0}, -{0x3600,0x3600, 1,1, 2,&z8002_device::Z36_0000_0000, "bpt", 0}, -{0x3601,0x36ff, 1,1, 10,&z8002_device::Z36_imm8, "rsvd36", 0}, -{0x3700,0x370f, 1,2, 17,&z8002_device::Z37_0000_ssss_dsp16, "ldrl %p1,%rl3", 0}, -{0x3710,0x37ff, 1,2, 17,&z8002_device::Z37_ddN0_ssss_imm16, "ldl %rw2(%#w1),%rl3", 0}, -{0x3800,0x38ff, 1,1, 10,&z8002_device::Z38_imm8, "rsvd38", 0}, -{0x3910,0x39f0,16,1, 12,&z8002_device::Z39_ssN0_0000, "ldps @%rw2", 0}, -{0x3a00,0x3af0,16,2, 21,&z8002_device::Z3A_ssss_0000_0000_aaaa_dddd_x000, "%R @%rw6,@%rw2,%rw5", 0}, -{0x3a01,0x3af1,16,2, 21,&z8002_device::Z3A_ssss_0001_0000_aaaa_dddd_x000, "%R @%rw6,@%rw2,%rw5", 0}, -{0x3a02,0x3af2,16,2, 21,&z8002_device::Z3A_ssss_0010_0000_aaaa_dddd_x000, "%R @%rw6,@%rw2,%rw5", 0}, -{0x3a03,0x3af3,16,2, 21,&z8002_device::Z3A_ssss_0011_0000_aaaa_dddd_x000, "%R @%rw6,@%rw2,%rw5", 0}, -{0x3a04,0x3af4,16,2, 10,&z8002_device::Z3A_dddd_0100_imm16, "%R %rb2,%#w1", 0}, -{0x3a05,0x3af5,16,2, 10,&z8002_device::Z3A_dddd_0101_imm16, "%R %rb2,%#w1", 0}, -{0x3a06,0x3af6,16,2, 12,&z8002_device::Z3A_ssss_0110_imm16, "%R %#w1,%rb2", 0}, -{0x3a07,0x3af7,16,2, 12,&z8002_device::Z3A_ssss_0111_imm16, "%R %#w1,%rb2", 0}, -{0x3a08,0x3af8,16,2, 21,&z8002_device::Z3A_ssss_1000_0000_aaaa_dddd_x000, "%R @%rw6,@%rw2,%rw5", 0}, -{0x3a09,0x3af9,16,2, 21,&z8002_device::Z3A_ssss_1001_0000_aaaa_dddd_x000, "%R @%rw6,@%rw2,%rw5", 0}, -{0x3a0a,0x3afa,16,2, 21,&z8002_device::Z3A_ssss_1010_0000_aaaa_dddd_x000, "%R @%rw6,@%rw2,%rw5", 0}, -{0x3a0b,0x3afb,16,2, 21,&z8002_device::Z3A_ssss_1011_0000_aaaa_dddd_x000, "%R @%rw6,@%rw2,%rw5", 0}, -{0x3b00,0x3bf0,16,2, 21,&z8002_device::Z3B_ssss_0000_0000_aaaa_dddd_x000, "%R @%rw6,@%rw2,%rw5", 0}, -{0x3b01,0x3bf1,16,2, 21,&z8002_device::Z3B_ssss_0001_0000_aaaa_dddd_x000, "%R @%rw6,@%rw2,%rw5", 0}, -{0x3b02,0x3bf2,16,2, 21,&z8002_device::Z3B_ssss_0010_0000_aaaa_dddd_x000, "%R @%rw6,@%rw2,%rw5", 0}, -{0x3b03,0x3bf3,16,2, 21,&z8002_device::Z3B_ssss_0011_0000_aaaa_dddd_x000, "%R @%rw6,@%rw2,%rw5", 0}, -{0x3b04,0x3bf4,16,2, 12,&z8002_device::Z3B_dddd_0100_imm16, "%R %rw2,%#w1", 0}, -{0x3b05,0x3bf5,16,2, 12,&z8002_device::Z3B_dddd_0101_imm16, "%R %rw2,%#w1", 0}, -{0x3b06,0x3bf6,16,2, 12,&z8002_device::Z3B_ssss_0110_imm16, "%R %#w1,%rw2", 0}, -{0x3b07,0x3bf7,16,2, 12,&z8002_device::Z3B_ssss_0111_imm16, "%R %#w1,%rw2", 0}, -{0x3b08,0x3bf8,16,2, 21,&z8002_device::Z3B_ssss_1000_0000_aaaa_dddd_x000, "%R @%rw6,@%rw2,%rw5", 0}, -{0x3b09,0x3bf9,16,2, 21,&z8002_device::Z3B_ssss_1001_0000_aaaa_dddd_x000, "%R @%rw6,@%rw2,%rw5", 0}, -{0x3b0a,0x3bfa,16,2, 21,&z8002_device::Z3B_ssss_1010_0000_aaaa_dddd_x000, "%R @%rw6,@%rw2,%rb5", 0}, -{0x3b0b,0x3bfb,16,2, 21,&z8002_device::Z3B_ssss_1011_0000_aaaa_dddd_x000, "%R @%rw6,@%rw2,%rb5", 0}, -{0x3c00,0x3cff, 1,1, 10,&z8002_device::Z3C_ssss_dddd, "inb %rb3,@%rw2", 0}, -{0x3d00,0x3dff, 1,1, 10,&z8002_device::Z3D_ssss_dddd, "in %rw3,@%rw2", 0}, -{0x3e00,0x3eff, 1,1, 12,&z8002_device::Z3E_dddd_ssss, "outb @%rw2,%rb3", 0}, -{0x3f00,0x3fff, 1,1, 12,&z8002_device::Z3F_dddd_ssss, "out @%rw2,%rw3", 0}, -{0x4000,0x400f, 1,2, 9,&z8002_device::Z40_0000_dddd_addr, "addb %rb3,%a1", 0}, -{0x4010,0x40ff, 1,2, 10,&z8002_device::Z40_ssN0_dddd_addr, "addb %rb3,%a1(%rw2)", 0}, -{0x4100,0x410f, 1,2, 9,&z8002_device::Z41_0000_dddd_addr, "add %rw3,%a1", 0}, -{0x4110,0x41ff, 1,2, 10,&z8002_device::Z41_ssN0_dddd_addr, "add %rw3,%a1(%rw2)", 0}, -{0x4200,0x420f, 1,2, 9,&z8002_device::Z42_0000_dddd_addr, "subb %rb3,%a1", 0}, -{0x4210,0x42ff, 1,2, 10,&z8002_device::Z42_ssN0_dddd_addr, "subb %rb3,%a1(%rw2)", 0}, -{0x4300,0x430f, 1,2, 9,&z8002_device::Z43_0000_dddd_addr, "sub %rw3,%a1", 0}, -{0x4310,0x43ff, 1,2, 10,&z8002_device::Z43_ssN0_dddd_addr, "sub %rw3,%a1(%rw2)", 0}, -{0x4400,0x440f, 1,2, 9,&z8002_device::Z44_0000_dddd_addr, "orb %rb3,%a1", 0}, -{0x4410,0x44ff, 1,2, 10,&z8002_device::Z44_ssN0_dddd_addr, "orb %rb3,%a1(%rw2)", 0}, -{0x4500,0x450f, 1,2, 9,&z8002_device::Z45_0000_dddd_addr, "or %rw3,%a1", 0}, -{0x4510,0x45ff, 1,2, 10,&z8002_device::Z45_ssN0_dddd_addr, "or %rw3,%a1(%rw2)", 0}, -{0x4600,0x460f, 1,2, 9,&z8002_device::Z46_0000_dddd_addr, "andb %rb3,%a1", 0}, -{0x4610,0x46ff, 1,2, 10,&z8002_device::Z46_ssN0_dddd_addr, "andb %rb3,%a1(%rw2)", 0}, -{0x4700,0x470f, 1,2, 9,&z8002_device::Z47_0000_dddd_addr, "and %rw3,%a1", 0}, -{0x4710,0x47ff, 1,2, 10,&z8002_device::Z47_ssN0_dddd_addr, "and %rw3,%a1(%rw2)", 0}, -{0x4800,0x480f, 1,2, 9,&z8002_device::Z48_0000_dddd_addr, "xorb %rb3,%a1", 0}, -{0x4810,0x48ff, 1,2, 10,&z8002_device::Z48_ssN0_dddd_addr, "xorb %rb3,%a1(%rw2)", 0}, -{0x4900,0x490f, 1,2, 9,&z8002_device::Z49_0000_dddd_addr, "xor %rw3,%a1", 0}, -{0x4910,0x49ff, 1,2, 10,&z8002_device::Z49_ssN0_dddd_addr, "xor %rw3,%a1(%rw2)", 0}, -{0x4a00,0x4a0f, 1,2, 9,&z8002_device::Z4A_0000_dddd_addr, "cpb %rb3,%a1", 0}, -{0x4a10,0x4aff, 1,2, 10,&z8002_device::Z4A_ssN0_dddd_addr, "cpb %rb3,%a1(%rw2)", 0}, -{0x4b00,0x4b0f, 1,2, 9,&z8002_device::Z4B_0000_dddd_addr, "cp %rw3,%a1", 0}, -{0x4b10,0x4bff, 1,2, 10,&z8002_device::Z4B_ssN0_dddd_addr, "cp %rw3,%a1(%rw2)", 0}, -{0x4c00,0x4c00, 1,2, 15,&z8002_device::Z4C_0000_0000_addr, "comb %a1", 0}, -{0x4c01,0x4c01, 1,3, 14,&z8002_device::Z4C_0000_0001_addr_imm8, "cpb %a1,%#b3", 0}, -{0x4c02,0x4c02, 1,2, 15,&z8002_device::Z4C_0000_0010_addr, "negb %a1", 0}, -{0x4c04,0x4c04, 1,2, 11,&z8002_device::Z4C_0000_0100_addr, "testb %a1", 0}, -{0x4c05,0x4c05, 1,3, 14,&z8002_device::Z4C_0000_0101_addr_imm8, "ldb %a1,%#b3", 0}, -{0x4c06,0x4c06, 1,2, 14,&z8002_device::Z4C_0000_0110_addr, "tsetb %a1", 0}, -{0x4c08,0x4c08, 1,2, 11,&z8002_device::Z4C_0000_1000_addr, "clrb %a1", 0}, -{0x4c10,0x4cf0,16,2, 16,&z8002_device::Z4C_ddN0_0000_addr, "comb %a1(%rw2)", 0}, -{0x4c11,0x4cf1,16,3, 15,&z8002_device::Z4C_ddN0_0001_addr_imm8, "cpb %a1(%rw2),%#b3", 0}, -{0x4c12,0x4cf2,16,2, 16,&z8002_device::Z4C_ddN0_0010_addr, "negb %a1(%rw2)", 0}, -{0x4c14,0x4cf4,16,2, 12,&z8002_device::Z4C_ddN0_0100_addr, "testb %a1(%rw2)", 0}, -{0x4c15,0x4cf5,16,3, 15,&z8002_device::Z4C_ddN0_0101_addr_imm8, "ldb %a1(%rw2),%#b3", 0}, -{0x4c16,0x4cf6,16,2, 15,&z8002_device::Z4C_ddN0_0110_addr, "tsetb %a1(%rw2)", 0}, -{0x4c18,0x4cf8,16,2, 12,&z8002_device::Z4C_ddN0_1000_addr, "clrb %a1(%rw2)", 0}, -{0x4d00,0x4d00, 1,2, 15,&z8002_device::Z4D_0000_0000_addr, "com %a1", 0}, -{0x4d01,0x4d01, 1,3, 14,&z8002_device::Z4D_0000_0001_addr_imm16, "cp %a1,%#w2", 0}, -{0x4d02,0x4d02, 1,2, 15,&z8002_device::Z4D_0000_0010_addr, "neg %a1", 0}, -{0x4d04,0x4d04, 1,2, 11,&z8002_device::Z4D_0000_0100_addr, "test %a1", 0}, -{0x4d05,0x4d05, 1,3, 14,&z8002_device::Z4D_0000_0101_addr_imm16, "ld %a1,%#w2", 0}, -{0x4d06,0x4d06, 1,2, 14,&z8002_device::Z4D_0000_0110_addr, "tset %a1", 0}, -{0x4d08,0x4d08, 1,2, 11,&z8002_device::Z4D_0000_1000_addr, "clr %a1", 0}, -{0x4d10,0x4df0,16,2, 16,&z8002_device::Z4D_ddN0_0000_addr, "com %a1(%rw2)", 0}, -{0x4d11,0x4df1,16,3, 15,&z8002_device::Z4D_ddN0_0001_addr_imm16, "cp %a1(%rw2),%#w2", 0}, -{0x4d12,0x4df2,16,2, 16,&z8002_device::Z4D_ddN0_0010_addr, "neg %a1(%rw2)", 0}, -{0x4d14,0x4df4,16,2, 12,&z8002_device::Z4D_ddN0_0100_addr, "test %a1(%rw2)", 0}, -{0x4d15,0x4df5,16,3, 15,&z8002_device::Z4D_ddN0_0101_addr_imm16, "ld %a1(%rw2),%#w2", 0}, -{0x4d16,0x4df6,16,2, 15,&z8002_device::Z4D_ddN0_0110_addr, "tset %a1(%rw2)", 0}, -{0x4d18,0x4df8,16,2, 12,&z8002_device::Z4D_ddN0_1000_addr, "clr %a1(%rw2)", 0}, -{0x4e11,0x4ef0,16,2, 12,&z8002_device::Z4E_ddN0_ssN0_addr, "ldb %a1(%rw2),%rb3", 0}, -{0x5000,0x500f, 1,2, 15,&z8002_device::Z50_0000_dddd_addr, "cpl %rl3,%a1", 0}, -{0x5010,0x50ff, 1,2, 16,&z8002_device::Z50_ssN0_dddd_addr, "cpl %rl3,%a1(%rw2)", 0}, -{0x5110,0x51f0,16,2, 21,&z8002_device::Z51_ddN0_0000_addr, "pushl @%rw2,%a1", 0}, -{0x5111,0x51f1,16,2, 21,&z8002_device::Z51_ddN0_ssN0_addr, "pushl @%rw2,%a1(%rw3)", 0}, -{0x5112,0x51f2,16,2, 21,&z8002_device::Z51_ddN0_ssN0_addr, "pushl @%rw2,%a1(%rw3)", 0}, -{0x5113,0x51f3,16,2, 21,&z8002_device::Z51_ddN0_ssN0_addr, "pushl @%rw2,%a1(%rw3)", 0}, -{0x5114,0x51f4,16,2, 21,&z8002_device::Z51_ddN0_ssN0_addr, "pushl @%rw2,%a1(%rw3)", 0}, -{0x5115,0x51f5,16,2, 21,&z8002_device::Z51_ddN0_ssN0_addr, "pushl @%rw2,%a1(%rw3)", 0}, -{0x5116,0x51f6,16,2, 21,&z8002_device::Z51_ddN0_ssN0_addr, "pushl @%rw2,%a1(%rw3)", 0}, -{0x5117,0x51f7,16,2, 21,&z8002_device::Z51_ddN0_ssN0_addr, "pushl @%rw2,%a1(%rw3)", 0}, -{0x5118,0x51f8,16,2, 21,&z8002_device::Z51_ddN0_ssN0_addr, "pushl @%rw2,%a1(%rw3)", 0}, -{0x5119,0x51f9,16,2, 21,&z8002_device::Z51_ddN0_ssN0_addr, "pushl @%rw2,%a1(%rw3)", 0}, -{0x511a,0x51fa,16,2, 21,&z8002_device::Z51_ddN0_ssN0_addr, "pushl @%rw2,%a1(%rw3)", 0}, -{0x511b,0x51fb,16,2, 21,&z8002_device::Z51_ddN0_ssN0_addr, "pushl @%rw2,%a1(%rw3)", 0}, -{0x511c,0x51fc,16,2, 21,&z8002_device::Z51_ddN0_ssN0_addr, "pushl @%rw2,%a1(%rw3)", 0}, -{0x511d,0x51fd,16,2, 21,&z8002_device::Z51_ddN0_ssN0_addr, "pushl @%rw2,%a1(%rw3)", 0}, -{0x511e,0x51fe,16,2, 21,&z8002_device::Z51_ddN0_ssN0_addr, "pushl @%rw2,%a1(%rw3)", 0}, -{0x511f,0x51ff,16,2, 21,&z8002_device::Z51_ddN0_ssN0_addr, "pushl @%rw2,%a1(%rw3)", 0}, -{0x5200,0x520f, 1,2, 15,&z8002_device::Z52_0000_dddd_addr, "subl %rl3,%a1", 0}, -{0x5210,0x52ff, 1,2, 16,&z8002_device::Z52_ssN0_dddd_addr, "subl %rl3,%a1(%rw2)", 0}, -{0x5310,0x53f0,16,2, 14,&z8002_device::Z53_ddN0_0000_addr, "push @%rw2,%a1", 0}, -{0x5311,0x53f1,16,2, 14,&z8002_device::Z53_ddN0_ssN0_addr, "push @%rw2,%a1(%rw3)", 0}, -{0x5312,0x53f2,16,2, 14,&z8002_device::Z53_ddN0_ssN0_addr, "push @%rw2,%a1(%rw3)", 0}, -{0x5313,0x53f3,16,2, 14,&z8002_device::Z53_ddN0_ssN0_addr, "push @%rw2,%a1(%rw3)", 0}, -{0x5314,0x53f4,16,2, 14,&z8002_device::Z53_ddN0_ssN0_addr, "push @%rw2,%a1(%rw3)", 0}, -{0x5315,0x53f5,16,2, 14,&z8002_device::Z53_ddN0_ssN0_addr, "push @%rw2,%a1(%rw3)", 0}, -{0x5316,0x53f6,16,2, 14,&z8002_device::Z53_ddN0_ssN0_addr, "push @%rw2,%a1(%rw3)", 0}, -{0x5317,0x53f7,16,2, 14,&z8002_device::Z53_ddN0_ssN0_addr, "push @%rw2,%a1(%rw3)", 0}, -{0x5318,0x53f8,16,2, 14,&z8002_device::Z53_ddN0_ssN0_addr, "push @%rw2,%a1(%rw3)", 0}, -{0x5319,0x53f9,16,2, 14,&z8002_device::Z53_ddN0_ssN0_addr, "push @%rw2,%a1(%rw3)", 0}, -{0x531a,0x53fa,16,2, 14,&z8002_device::Z53_ddN0_ssN0_addr, "push @%rw2,%a1(%rw3)", 0}, -{0x531b,0x53fb,16,2, 14,&z8002_device::Z53_ddN0_ssN0_addr, "push @%rw2,%a1(%rw3)", 0}, -{0x531c,0x53fc,16,2, 14,&z8002_device::Z53_ddN0_ssN0_addr, "push @%rw2,%a1(%rw3)", 0}, -{0x531d,0x53fd,16,2, 14,&z8002_device::Z53_ddN0_ssN0_addr, "push @%rw2,%a1(%rw3)", 0}, -{0x531e,0x53fe,16,2, 14,&z8002_device::Z53_ddN0_ssN0_addr, "push @%rw2,%a1(%rw3)", 0}, -{0x531f,0x53ff,16,2, 14,&z8002_device::Z53_ddN0_ssN0_addr, "push @%rw2,%a1(%rw3)", 0}, -{0x5400,0x540f, 1,2, 12,&z8002_device::Z54_0000_dddd_addr, "ldl %rl3,%a1", 0}, -{0x5410,0x54ff, 1,2, 13,&z8002_device::Z54_ssN0_dddd_addr, "ldl %rl3,%a1(%rw2)", 0}, -{0x5510,0x55f0,16,2, 23,&z8002_device::Z55_ssN0_0000_addr, "popl %a1,@%rw2", 0}, -{0x5511,0x55f1,16,2, 23,&z8002_device::Z55_ssN0_ddN0_addr, "popl %a1(%rw3),@%rw2", 0}, -{0x5512,0x55f2,16,2, 23,&z8002_device::Z55_ssN0_ddN0_addr, "popl %a1(%rw3),@%rw2", 0}, -{0x5513,0x55f3,16,2, 23,&z8002_device::Z55_ssN0_ddN0_addr, "popl %a1(%rw3),@%rw2", 0}, -{0x5514,0x55f4,16,2, 23,&z8002_device::Z55_ssN0_ddN0_addr, "popl %a1(%rw3),@%rw2", 0}, -{0x5515,0x55f5,16,2, 23,&z8002_device::Z55_ssN0_ddN0_addr, "popl %a1(%rw3),@%rw2", 0}, -{0x5516,0x55f6,16,2, 23,&z8002_device::Z55_ssN0_ddN0_addr, "popl %a1(%rw3),@%rw2", 0}, -{0x5517,0x55f7,16,2, 23,&z8002_device::Z55_ssN0_ddN0_addr, "popl %a1(%rw3),@%rw2", 0}, -{0x5518,0x55f8,16,2, 23,&z8002_device::Z55_ssN0_ddN0_addr, "popl %a1(%rw3),@%rw2", 0}, -{0x5519,0x55f9,16,2, 23,&z8002_device::Z55_ssN0_ddN0_addr, "popl %a1(%rw3),@%rw2", 0}, -{0x551a,0x55fa,16,2, 23,&z8002_device::Z55_ssN0_ddN0_addr, "popl %a1(%rw3),@%rw2", 0}, -{0x551b,0x55fb,16,2, 23,&z8002_device::Z55_ssN0_ddN0_addr, "popl %a1(%rw3),@%rw2", 0}, -{0x551c,0x55fc,16,2, 23,&z8002_device::Z55_ssN0_ddN0_addr, "popl %a1(%rw3),@%rw2", 0}, -{0x551d,0x55fd,16,2, 23,&z8002_device::Z55_ssN0_ddN0_addr, "popl %a1(%rw3),@%rw2", 0}, -{0x551e,0x55fe,16,2, 23,&z8002_device::Z55_ssN0_ddN0_addr, "popl %a1(%rw3),@%rw2", 0}, -{0x551f,0x55ff,16,2, 23,&z8002_device::Z55_ssN0_ddN0_addr, "popl %a1(%rw3),@%rw2", 0}, -{0x5600,0x560f, 1,2, 15,&z8002_device::Z56_0000_dddd_addr, "addl %rl3,%a1", 0}, -{0x5610,0x56ff, 1,2, 16,&z8002_device::Z56_ssN0_dddd_addr, "addl %rl3,%a1(%rw2)", 0}, -{0x5710,0x57f0,16,2, 16,&z8002_device::Z57_ssN0_0000_addr, "pop %a1,@%rw2", 0}, -{0x5711,0x57f1,16,2, 16,&z8002_device::Z57_ssN0_ddN0_addr, "pop %a1(%rw3),@%rw2", 0}, -{0x5712,0x57f2,16,2, 16,&z8002_device::Z57_ssN0_ddN0_addr, "pop %a1(%rw3),@%rw2", 0}, -{0x5713,0x57f3,16,2, 16,&z8002_device::Z57_ssN0_ddN0_addr, "pop %a1(%rw3),@%rw2", 0}, -{0x5714,0x57f4,16,2, 16,&z8002_device::Z57_ssN0_ddN0_addr, "pop %a1(%rw3),@%rw2", 0}, -{0x5715,0x57f5,16,2, 16,&z8002_device::Z57_ssN0_ddN0_addr, "pop %a1(%rw3),@%rw2", 0}, -{0x5716,0x57f6,16,2, 16,&z8002_device::Z57_ssN0_ddN0_addr, "pop %a1(%rw3),@%rw2", 0}, -{0x5717,0x57f7,16,2, 16,&z8002_device::Z57_ssN0_ddN0_addr, "pop %a1(%rw3),@%rw2", 0}, -{0x5718,0x57f8,16,2, 16,&z8002_device::Z57_ssN0_ddN0_addr, "pop %a1(%rw3),@%rw2", 0}, -{0x5719,0x57f9,16,2, 16,&z8002_device::Z57_ssN0_ddN0_addr, "pop %a1(%rw3),@%rw2", 0}, -{0x571a,0x57fa,16,2, 16,&z8002_device::Z57_ssN0_ddN0_addr, "pop %a1(%rw3),@%rw2", 0}, -{0x571b,0x57fb,16,2, 16,&z8002_device::Z57_ssN0_ddN0_addr, "pop %a1(%rw3),@%rw2", 0}, -{0x571c,0x57fc,16,2, 16,&z8002_device::Z57_ssN0_ddN0_addr, "pop %a1(%rw3),@%rw2", 0}, -{0x571d,0x57fd,16,2, 16,&z8002_device::Z57_ssN0_ddN0_addr, "pop %a1(%rw3),@%rw2", 0}, -{0x571e,0x57fe,16,2, 16,&z8002_device::Z57_ssN0_ddN0_addr, "pop %a1(%rw3),@%rw2", 0}, -{0x571f,0x57ff,16,2, 16,&z8002_device::Z57_ssN0_ddN0_addr, "pop %a1(%rw3),@%rw2", 0}, -{0x5800,0x580f, 1,2,283,&z8002_device::Z58_0000_dddd_addr, "multl %rq3,%a1", 0}, -{0x5810,0x58ff, 1,2,284,&z8002_device::Z58_ssN0_dddd_addr, "multl %rq3,%a1(%rw2)", 0}, -{0x5900,0x590f, 1,2, 71,&z8002_device::Z59_0000_dddd_addr, "mult %rl3,%a1", 0}, -{0x5910,0x59ff, 1,2, 72,&z8002_device::Z59_ssN0_dddd_addr, "mult %rl3,%a1(%rw2)", 0}, -{0x5a00,0x5a0f, 1,2,745,&z8002_device::Z5A_0000_dddd_addr, "divl %rq3,%a1", 0}, -{0x5a10,0x5aff, 1,2,746,&z8002_device::Z5A_ssN0_dddd_addr, "divl %rq3,%a1(%rw2)", 0}, -{0x5b00,0x5b0f, 1,2,108,&z8002_device::Z5B_0000_dddd_addr, "div %rl3,%a1", 0}, -{0x5b10,0x5bff, 1,2,109,&z8002_device::Z5B_ssN0_dddd_addr, "div %rl3,%a1(%rw2)", 0}, -{0x5c01,0x5c01, 1,3, 14,&z8002_device::Z5C_0000_0001_0000_dddd_0000_nmin1_addr, "ldm %rw5,%a2,#%n", 0}, -{0x5c08,0x5c08, 1,2, 16,&z8002_device::Z5C_0000_1000_addr, "testl %a1", 0}, -{0x5c09,0x5c09, 1,3, 14,&z8002_device::Z5C_0000_1001_0000_ssss_0000_nmin1_addr, "ldm %a2,%rw5,#%n", 0}, -{0x5c11,0x5cf1,16,3, 15,&z8002_device::Z5C_ssN0_0001_0000_dddd_0000_nmin1_addr, "ldm %rw5,%a2(%rw2),#%n", 0}, -{0x5c18,0x5cf8,16,2, 17,&z8002_device::Z5C_ddN0_1000_addr, "testl %a1(%rw2)", 0}, -{0x5c19,0x5cf9,16,3, 15,&z8002_device::Z5C_ddN0_1001_0000_ssN0_0000_nmin1_addr, "ldm %a2(%rw2),%rw5,#%n", 0}, -{0x5d00,0x5d0f, 1,2, 15,&z8002_device::Z5D_0000_ssss_addr, "ldl %a1,%rl3", 0}, -{0x5d10,0x5dff, 1,2, 14,&z8002_device::Z5D_ddN0_ssss_addr, "ldl %a1(%rw2),%rl3", 0}, -{0x5e00,0x5e0f, 1,2, 7,&z8002_device::Z5E_0000_cccc_addr, "jp %c3,%a1", 0}, -{0x5e10,0x5eff, 1,2, 8,&z8002_device::Z5E_ddN0_cccc_addr, "jp %c3,%a1(%rw2)", 0}, -{0x5f00,0x5f00, 1,2, 12,&z8002_device::Z5F_0000_0000_addr, "call %a1", DASMFLAG_STEP_OVER}, -{0x5f10,0x5ff0,16,2, 13,&z8002_device::Z5F_ddN0_0000_addr, "call %a1(%rw2)", DASMFLAG_STEP_OVER}, -{0x6000,0x600f, 1,2, 9,&z8002_device::Z60_0000_dddd_addr, "ldb %rb3,%a1", 0}, -{0x6010,0x60ff, 1,2, 10,&z8002_device::Z60_ssN0_dddd_addr, "ldb %rb3,%a1(%rw2)", 0}, -{0x6100,0x610f, 1,2, 9,&z8002_device::Z61_0000_dddd_addr, "ld %rw3,%a1", 0}, -{0x6110,0x61ff, 1,2, 10,&z8002_device::Z61_ssN0_dddd_addr, "ld %rw3,%a1(%rw2)", 0}, -{0x6200,0x620f, 1,2, 13,&z8002_device::Z62_0000_imm4_addr, "resb %a1,%3", 0}, -{0x6210,0x62ff, 1,2, 14,&z8002_device::Z62_ddN0_imm4_addr, "resb %a1(%rw2),%3", 0}, -{0x6300,0x630f, 1,2, 13,&z8002_device::Z63_0000_imm4_addr, "res %a1,%3", 0}, -{0x6310,0x63ff, 1,2, 14,&z8002_device::Z63_ddN0_imm4_addr, "res %a1(%rw2),%3", 0}, -{0x6400,0x640f, 1,2, 13,&z8002_device::Z64_0000_imm4_addr, "setb %a1,%3", 0}, -{0x6410,0x64ff, 1,2, 14,&z8002_device::Z64_ddN0_imm4_addr, "setb %a1(%rw2),%3", 0}, -{0x6500,0x650f, 1,2, 13,&z8002_device::Z65_0000_imm4_addr, "set %a1,%3", 0}, -{0x6510,0x65ff, 1,2, 14,&z8002_device::Z65_ddN0_imm4_addr, "set %a1(%rw2),%3", 0}, -{0x6600,0x660f, 1,2, 10,&z8002_device::Z66_0000_imm4_addr, "bitb %a1,%3", 0}, -{0x6610,0x66ff, 1,2, 11,&z8002_device::Z66_ddN0_imm4_addr, "bitb %a1(%rw2),%3", 0}, -{0x6700,0x670f, 1,2, 10,&z8002_device::Z67_0000_imm4_addr, "bit %a1,%3", 0}, -{0x6710,0x67ff, 1,2, 11,&z8002_device::Z67_ddN0_imm4_addr, "bit %a1(%rw2),%3", 0}, -{0x6800,0x680f, 1,2, 13,&z8002_device::Z68_0000_imm4m1_addr, "incb %a1,%+3", 0}, -{0x6810,0x68ff, 1,2, 14,&z8002_device::Z68_ddN0_imm4m1_addr, "incb %a1(%rw2),%+3", 0}, -{0x6900,0x690f, 1,2, 13,&z8002_device::Z69_0000_imm4m1_addr, "inc %a1,%+3", 0}, -{0x6910,0x69ff, 1,2, 14,&z8002_device::Z69_ddN0_imm4m1_addr, "inc %a1(%rw2),%+3", 0}, -{0x6a00,0x6a0f, 1,2, 13,&z8002_device::Z6A_0000_imm4m1_addr, "decb %a1,%+3", 0}, -{0x6a10,0x6aff, 1,2, 14,&z8002_device::Z6A_ddN0_imm4m1_addr, "decb %a1(%rw2),%+3", 0}, -{0x6b00,0x6b0f, 1,2, 13,&z8002_device::Z6B_0000_imm4m1_addr, "dec %a1,%+3", 0}, -{0x6b10,0x6bff, 1,2, 14,&z8002_device::Z6B_ddN0_imm4m1_addr, "dec %a1(%rw2),%+3", 0}, -{0x6c00,0x6c0f, 1,2, 15,&z8002_device::Z6C_0000_dddd_addr, "exb %rb3,%a1", 0}, -{0x6c10,0x6cff, 1,2, 16,&z8002_device::Z6C_ssN0_dddd_addr, "exb %rb3,%a1(%rw2)", 0}, -{0x6d00,0x6d0f, 1,2, 15,&z8002_device::Z6D_0000_dddd_addr, "ex %rw3,%a1", 0}, -{0x6d10,0x6dff, 1,2, 16,&z8002_device::Z6D_ssN0_dddd_addr, "ex %rw3,%a1(%rw2)", 0}, -{0x6e00,0x6e0f, 1,2, 11,&z8002_device::Z6E_0000_ssss_addr, "ldb %a1,%rb3", 0}, -{0x6e10,0x6eff, 1,2, 11,&z8002_device::Z6E_ddN0_ssss_addr, "ldb %a1(%rw2),%rb3", 0}, -{0x6f00,0x6f0f, 1,2, 11,&z8002_device::Z6F_0000_ssss_addr, "ld %a1,%rw3", 0}, -{0x6f10,0x6fff, 1,2, 12,&z8002_device::Z6F_ddN0_ssss_addr, "ld %a1(%rw2),%rw3", 0}, -{0x7010,0x70ff, 1,2, 14,&z8002_device::Z70_ssN0_dddd_0000_xxxx_0000_0000, "ldb %rb3,%rw2(%rw5)", 0}, -{0x7110,0x71ff, 1,2, 14,&z8002_device::Z71_ssN0_dddd_0000_xxxx_0000_0000, "ld %rw3,%rw2(%rw5)", 0}, -{0x7210,0x72ff, 1,2, 14,&z8002_device::Z72_ddN0_ssss_0000_xxxx_0000_0000, "ldb %rw2(%rw5),%rb3", 0}, -{0x7310,0x73ff, 1,2, 14,&z8002_device::Z73_ddN0_ssss_0000_xxxx_0000_0000, "ld %rw2(%rw5),%rw3", 0}, -{0x7410,0x74ff, 1,2, 15,&z8002_device::Z74_ssN0_dddd_0000_xxxx_0000_0000, "lda p%rw3,%rw2(%rw5)", 0}, -{0x7510,0x75ff, 1,2, 17,&z8002_device::Z75_ssN0_dddd_0000_xxxx_0000_0000, "ldl %rl3,%rw2(%rw5)", 0}, -{0x7600,0x760f, 1,2, 12,&z8002_device::Z76_0000_dddd_addr, "lda p%rw3,%a1", 0}, -{0x7610,0x76ff, 1,2, 13,&z8002_device::Z76_ssN0_dddd_addr, "lda p%rw3,%a1(%rw2)", 0}, -{0x7710,0x77ff, 1,2, 17,&z8002_device::Z77_ddN0_ssss_0000_xxxx_0000_0000, "ldl %rw2(%rw5),%rl3", 0}, -{0x7800,0x78ff, 1,1, 10,&z8002_device::Z78_imm8, "rsvd78", 0}, -{0x7900,0x7900, 1,2, 16,&z8002_device::Z79_0000_0000_addr, "ldps %a1", 0}, -{0x7910,0x79f0,16,2, 17,&z8002_device::Z79_ssN0_0000_addr, "ldps %a1(%rw2)", 0}, -{0x7a00,0x7a00, 1,1, 8,&z8002_device::Z7A_0000_0000, "halt", DASMFLAG_STEP_OVER}, -{0x7b00,0x7b00, 1,1, 13,&z8002_device::Z7B_0000_0000, "iret", DASMFLAG_STEP_OUT}, -{0x7b08,0x7b08, 1,1, 5,&z8002_device::Z7B_0000_1000, "mset", 0}, -{0x7b09,0x7b09, 1,1, 5,&z8002_device::Z7B_0000_1001, "mres", 0}, -{0x7b0a,0x7b0a, 1,1, 7,&z8002_device::Z7B_0000_1010, "mbit", 0}, -{0x7b0d,0x7bfd,16,1, 12,&z8002_device::Z7B_dddd_1101, "mreq %rw2", 0}, -{0x7c00,0x7c03, 1,1, 7,&z8002_device::Z7C_0000_00ii, "di %i3", 0}, -{0x7c04,0x7c07, 1,1, 7,&z8002_device::Z7C_0000_01ii, "ei %i3", 0}, -{0x7d00,0x7df0,16,1, 7,&z8002_device::Z7D_dddd_0ccc, "ldctl %rw2,ctrl0", 0}, -{0x7d01,0x7df1,16,1, 7,&z8002_device::Z7D_dddd_0ccc, "ldctl %rw2,ctrl1", 0}, -{0x7d02,0x7df2,16,1, 7,&z8002_device::Z7D_dddd_0ccc, "ldctl %rw2,fcw", 0}, -{0x7d03,0x7df3,16,1, 7,&z8002_device::Z7D_dddd_0ccc, "ldctl %rw2,refresh", 0}, -{0x7d04,0x7df4,16,1, 7,&z8002_device::Z7D_dddd_0ccc, "ldctl %rw2,psapseg", 0}, -{0x7d05,0x7df5,16,1, 7,&z8002_device::Z7D_dddd_0ccc, "ldctl %rw2,psapoff", 0}, -{0x7d06,0x7df6,16,1, 7,&z8002_device::Z7D_dddd_0ccc, "ldctl %rw2,nspseg", 0}, -{0x7d07,0x7df7,16,1, 7,&z8002_device::Z7D_dddd_0ccc, "ldctl %rw2,nspoff", 0}, -{0x7d08,0x7df8,16,1, 7,&z8002_device::Z7D_ssss_1ccc, "ldctl ctrl0,%rw2", 0}, -{0x7d09,0x7df9,16,1, 7,&z8002_device::Z7D_ssss_1ccc, "ldctl ctrl1,%rw2", 0}, -{0x7d0a,0x7dfa,16,1, 7,&z8002_device::Z7D_ssss_1ccc, "ldctl fcw,%rw2", 0}, -{0x7d0b,0x7dfb,16,1, 7,&z8002_device::Z7D_ssss_1ccc, "ldctl refresh,%rw2", 0}, -{0x7d0c,0x7dfc,16,1, 7,&z8002_device::Z7D_ssss_1ccc, "ldctl psapseg,%rw2", 0}, -{0x7d0d,0x7dfd,16,1, 7,&z8002_device::Z7D_ssss_1ccc, "ldctl psapoff,%rw2", 0}, -{0x7d0e,0x7dfe,16,1, 7,&z8002_device::Z7D_ssss_1ccc, "ldctl nspseg,%rw2", 0}, -{0x7d0f,0x7dff,16,1, 7,&z8002_device::Z7D_ssss_1ccc, "ldctl nspoff,%rw2", 0}, -{0x7e00,0x7eff, 1,1, 10,&z8002_device::Z7E_imm8, "rsvd7e %#b1", 0}, -{0x7f00,0x7fff, 1,1, 33,&z8002_device::Z7F_imm8, "sc %#b1", DASMFLAG_STEP_OVER}, -{0x8000,0x80ff, 1,1, 4,&z8002_device::Z80_ssss_dddd, "addb %rb3,%rb2", 0}, -{0x8100,0x81ff, 1,1, 4,&z8002_device::Z81_ssss_dddd, "add %rw3,%rw2", 0}, -{0x8200,0x82ff, 1,1, 4,&z8002_device::Z82_ssss_dddd, "subb %rb3,%rb2", 0}, -{0x8300,0x83ff, 1,1, 4,&z8002_device::Z83_ssss_dddd, "sub %rw3,%rw2", 0}, -{0x8400,0x84ff, 1,1, 4,&z8002_device::Z84_ssss_dddd, "orb %rb3,%rb2", 0}, -{0x8500,0x85ff, 1,1, 4,&z8002_device::Z85_ssss_dddd, "or %rw3,%rw2", 0}, -{0x8600,0x86ff, 1,1, 4,&z8002_device::Z86_ssss_dddd, "andb %rb3,%rb2", 0}, -{0x8700,0x87ff, 1,1, 4,&z8002_device::Z87_ssss_dddd, "and %rw3,%rw2", 0}, -{0x8800,0x88ff, 1,1, 4,&z8002_device::Z88_ssss_dddd, "xorb %rb3,%rb2", 0}, -{0x8900,0x89ff, 1,1, 4,&z8002_device::Z89_ssss_dddd, "xor %rw3,%rw2", 0}, -{0x8a00,0x8aff, 1,1, 4,&z8002_device::Z8A_ssss_dddd, "cpb %rb3,%rb2", 0}, -{0x8b00,0x8bff, 1,1, 4,&z8002_device::Z8B_ssss_dddd, "cp %rw3,%rw2", 0}, -{0x8c00,0x8cf0,16,1, 7,&z8002_device::Z8C_dddd_0000, "comb %rb2", 0}, -{0x8c02,0x8cf2,16,1, 7,&z8002_device::Z8C_dddd_0010, "negb %rb2", 0}, -{0x8c04,0x8cf4,16,1, 7,&z8002_device::Z8C_dddd_0100, "testb %rb2", 0}, -{0x8c06,0x8cf6,16,1, 7,&z8002_device::Z8C_dddd_0110, "tsetb %rb2", 0}, -{0x8c01,0x8cf1,16,1, 7,&z8002_device::Z8C_dddd_0001, "ldctlb %rb2,flags", 0}, -{0x8c08,0x8cf8,16,1, 7,&z8002_device::Z8C_dddd_1000, "clrb %rb2", 0}, -{0x8c09,0x8cf9,16,1, 7,&z8002_device::Z8C_dddd_1001, "ldctlb flags,%rb2", 0}, -{0x8d00,0x8df0,16,1, 7,&z8002_device::Z8D_dddd_0000, "com %rw2", 0}, -{0x8d01,0x8df1,16,1, 7,&z8002_device::Z8D_imm4_0001, "setflg %f2", 0}, -{0x8d02,0x8df2,16,1, 7,&z8002_device::Z8D_dddd_0010, "neg %rw2", 0}, -{0x8d03,0x8df3,16,1, 7,&z8002_device::Z8D_imm4_0011, "resflg %f2", 0}, -{0x8d04,0x8df4,16,1, 7,&z8002_device::Z8D_dddd_0100, "test %rw2", 0}, -{0x8d05,0x8df5,16,1, 7,&z8002_device::Z8D_imm4_0101, "comflg %f2", 0}, -{0x8d06,0x8df6,16,1, 7,&z8002_device::Z8D_dddd_0110, "tset %rw2", 0}, -{0x8d07,0x8d07, 1,1, 7,&z8002_device::Z8D_0000_0111, "nop", 0}, -{0x8d08,0x8df8,16,1, 7,&z8002_device::Z8D_dddd_1000, "clr %rw2", 0}, -{0x8e00,0x8eff, 1,1, 10,&z8002_device::Z8E_imm8, "ext8e %#b1", 0}, -{0x8f00,0x8fff, 1,1, 10,&z8002_device::Z8F_imm8, "ext8f %#b1", 0}, -{0x9000,0x90ff, 1,1, 8,&z8002_device::Z90_ssss_dddd, "cpl %rl3,%rl2", 0}, -{0x9110,0x91ff, 1,1, 12,&z8002_device::Z91_ddN0_ssss, "pushl @%rw2,%rl3", 0}, -{0x9200,0x92ff, 1,1, 8,&z8002_device::Z92_ssss_dddd, "subl %rl3,%rl2", 0}, -{0x9310,0x93ff, 1,1, 9,&z8002_device::Z93_ddN0_ssss, "push @%rw2,%rw3", 0}, -{0x9400,0x94ff, 1,1, 5,&z8002_device::Z94_ssss_dddd, "ldl %rl3,%rl2", 0}, -{0x9510,0x95ff, 1,1, 12,&z8002_device::Z95_ssN0_dddd, "popl %rl3,@%rw2", 0}, -{0x9600,0x96ff, 1,1, 8,&z8002_device::Z96_ssss_dddd, "addl %rl3,%rl2", 0}, -{0x9710,0x97ff, 1,1, 8,&z8002_device::Z97_ssN0_dddd, "pop %rw3,@%rw2", 0}, -{0x9800,0x98ff, 1,1,282,&z8002_device::Z98_ssss_dddd, "multl %rq3,%rl2", 0}, -{0x9900,0x99ff, 1,1, 70,&z8002_device::Z99_ssss_dddd, "mult %rl3,%rw2", 0}, -{0x9a00,0x9aff, 1,1,744,&z8002_device::Z9A_ssss_dddd, "divl %rq3,%rl2", 0}, -{0x9b00,0x9bff, 1,1,107,&z8002_device::Z9B_ssss_dddd, "div %rl3,%rw2", 0}, -{0x9c00,0x9cf8, 8,1, 13,&z8002_device::Z9C_dddd_1000, "testl %rl2", 0}, -{0x9d00,0x9dff, 1,1, 10,&z8002_device::Z9D_imm8, "rsvd9d", 0}, -{0x9e00,0x9e0f, 1,1, 10,&z8002_device::Z9E_0000_cccc, "ret %c3", DASMFLAG_STEP_OUT}, -{0x9f00,0x9fff, 1,1, 10,&z8002_device::Z9F_imm8, "rsvd9f", 0}, -{0xa000,0xa0ff, 1,1, 3,&z8002_device::ZA0_ssss_dddd, "ldb %rb3,%rb2", 0}, -{0xa100,0xa1ff, 1,1, 3,&z8002_device::ZA1_ssss_dddd, "ld %rw3,%rw2", 0}, -{0xa200,0xa2ff, 1,1, 4,&z8002_device::ZA2_dddd_imm4, "resb %rb2,%3", 0}, -{0xa300,0xa3ff, 1,1, 4,&z8002_device::ZA3_dddd_imm4, "res %rw2,%3", 0}, -{0xa400,0xa4ff, 1,1, 4,&z8002_device::ZA4_dddd_imm4, "setb %rb2,%3", 0}, -{0xa500,0xa5ff, 1,1, 4,&z8002_device::ZA5_dddd_imm4, "set %rw2,%3", 0}, -{0xa600,0xa6ff, 1,1, 4,&z8002_device::ZA6_dddd_imm4, "bitb %rb2,%3", 0}, -{0xa700,0xa7ff, 1,1, 4,&z8002_device::ZA7_dddd_imm4, "bit %rw2,%3", 0}, -{0xa800,0xa8ff, 1,1, 4,&z8002_device::ZA8_dddd_imm4m1, "incb %rb2,%+3", 0}, -{0xa900,0xa9ff, 1,1, 4,&z8002_device::ZA9_dddd_imm4m1, "inc %rw2,%+3", 0}, -{0xaa00,0xaaff, 1,1, 4,&z8002_device::ZAA_dddd_imm4m1, "decb %rb2,%+3", 0}, -{0xab00,0xabff, 1,1, 4,&z8002_device::ZAB_dddd_imm4m1, "dec %rw2,%+3", 0}, -{0xac00,0xacff, 1,1, 6,&z8002_device::ZAC_ssss_dddd, "exb %rb3,%rb2", 0}, -{0xad00,0xadff, 1,1, 6,&z8002_device::ZAD_ssss_dddd, "ex %rw3,%rw2", 0}, -{0xae00,0xaeff, 1,1, 5,&z8002_device::ZAE_dddd_cccc, "tccb %c3,%rb2", 0}, -{0xaf00,0xafff, 1,1, 5,&z8002_device::ZAF_dddd_cccc, "tcc %c3,%rw2", 0}, -{0xb000,0xb0f0,16,1, 5,&z8002_device::ZB0_dddd_0000, "dab %rb2", 0}, -{0xb100,0xb1f0,16,1, 11,&z8002_device::ZB1_dddd_0000, "extsb %rw2", 0}, -{0xb107,0xb1f7,16,1, 11,&z8002_device::ZB1_dddd_0111, "extsl %rq2", 0}, -{0xb10a,0xb1fa,16,1, 11,&z8002_device::ZB1_dddd_1010, "exts %rl2", 0}, -{0xb200,0xb2f0,16,1, 6,&z8002_device::ZB2_dddd_00I0, "rlb %rb2,%?3", 0}, -{0xb201,0xb2f1,16,2, 13,&z8002_device::ZB2_dddd_0001_imm8, "s%*lb %rb2,%$3", 0}, -{0xb202,0xb2f2,16,1, 6,&z8002_device::ZB2_dddd_00I0, "rlb %rb2,%?3", 0}, -{0xb203,0xb2f3,16,2, 15,&z8002_device::ZB2_dddd_0011_0000_ssss_0000_0000, "sdlb %rb2,%rw5", 0}, -{0xb204,0xb2f4,16,1, 6,&z8002_device::ZB2_dddd_01I0, "rrb %rb2,%?3", 0}, -{0xb206,0xb2f6,16,1, 6,&z8002_device::ZB2_dddd_01I0, "rrb %rb2,%?3", 0}, -{0xb208,0xb2f8,16,1, 9,&z8002_device::ZB2_dddd_10I0, "rlcb %rb2,%?3", 0}, -{0xb209,0xb2f9,16,2, 13,&z8002_device::ZB2_dddd_1001_imm8, "s%*ab %rb2,%$3", 0}, -{0xb20a,0xb2fa,16,1, 9,&z8002_device::ZB2_dddd_10I0, "rlcb %rb2,%?3", 0}, -{0xb20b,0xb2fb,16,2, 15,&z8002_device::ZB2_dddd_1011_0000_ssss_0000_0000, "sdab %rb2,%rw5", 0}, -{0xb20c,0xb2fc,16,1, 9,&z8002_device::ZB2_dddd_11I0, "rrcb %rb2,%?3", 0}, -{0xb20e,0xb2fe,16,1, 9,&z8002_device::ZB2_dddd_11I0, "rrcb %rb2,%?3", 0}, -{0xb300,0xb3f0,16,1, 6,&z8002_device::ZB3_dddd_00I0, "rl %rw2,%?3", 0}, -{0xb301,0xb3f1,16,2, 13,&z8002_device::ZB3_dddd_0001_imm8, "s%*l %rw2,%$3", 0}, -{0xb302,0xb3f2,16,1, 6,&z8002_device::ZB3_dddd_00I0, "rl %rw2,%?3", 0}, -{0xb303,0xb3f3,16,2, 15,&z8002_device::ZB3_dddd_0011_0000_ssss_0000_0000, "sdl %rw2,%rw5", 0}, -{0xb304,0xb3f4,16,1, 6,&z8002_device::ZB3_dddd_01I0, "rr %rw2,%?3", 0}, -{0xb305,0xb3f5,16,2, 13,&z8002_device::ZB3_dddd_0101_imm8, "s%*ll %rl2,%$3", 0}, -{0xb306,0xb3f6,16,1, 6,&z8002_device::ZB3_dddd_01I0, "rr %rw2,%?3", 0}, -{0xb307,0xb3f7,16,2, 15,&z8002_device::ZB3_dddd_0111_0000_ssss_0000_0000, "sdll %rl2,%rw5", 0}, -{0xb308,0xb3f8,16,1, 6,&z8002_device::ZB3_dddd_10I0, "rlc %rw2,%?3", 0}, -{0xb309,0xb3f9,16,2, 13,&z8002_device::ZB3_dddd_1001_imm8, "s%*a %rw2,%$3", 0}, -{0xb30a,0xb3fa,16,1, 6,&z8002_device::ZB3_dddd_10I0, "rlc %rw2,%?3", 0}, -{0xb30b,0xb3fb,16,2, 15,&z8002_device::ZB3_dddd_1011_0000_ssss_0000_0000, "sda %rw2,%rw5", 0}, -{0xb30c,0xb3fc,16,1, 6,&z8002_device::ZB3_dddd_11I0, "rrc %rw2,%?3", 0}, -{0xb30d,0xb3fd,16,2, 13,&z8002_device::ZB3_dddd_1101_imm8, "s%*al %rl2,%$3", 0}, -{0xb30e,0xb3fe,16,1, 6,&z8002_device::ZB3_dddd_11I0, "rrc %rw2,%?3", 0}, -{0xb30f,0xb3ff,16,2, 15,&z8002_device::ZB3_dddd_1111_0000_ssss_0000_0000, "sdal %rl2,%rw5", 0}, -{0xb400,0xb4ff, 1,1, 5,&z8002_device::ZB4_ssss_dddd, "adcb %rb3,%rb2", 0}, -{0xb500,0xb5ff, 1,1, 5,&z8002_device::ZB5_ssss_dddd, "adc %rw3,%rw2", 0}, -{0xb600,0xb6ff, 1,1, 5,&z8002_device::ZB6_ssss_dddd, "sbcb %rb3,%rb2", 0}, -{0xb700,0xb7ff, 1,1, 5,&z8002_device::ZB7_ssss_dddd, "sbc %rw3,%rw2", 0}, -{0xb810,0xb8f0,16,2, 25,&z8002_device::ZB8_ddN0_0000_0000_rrrr_ssN0_0000, "trib @%rw2,@%rw6,%rb5", 0}, -{0xb812,0xb8f2,16,2, 25,&z8002_device::ZB8_ddN0_0010_0000_rrrr_ssN0_0000, "trtib @%rw2,@%rw6,%rb5", 0}, -{0xb814,0xb8f4,16,2, 25,&z8002_device::ZB8_ddN0_0100_0000_rrrr_ssN0_0000, "trirb @%rw2,@%rw6,%rb5", 0}, -{0xb816,0xb8f6,16,2, 25,&z8002_device::ZB8_ddN0_0110_0000_rrrr_ssN0_1110, "trtirb @%rw2,@%rw6,%rb5", 0}, -{0xb818,0xb8f8,16,2, 25,&z8002_device::ZB8_ddN0_1000_0000_rrrr_ssN0_0000, "trdb @%rw2,@%rw6,%rb5", 0}, -{0xb81a,0xb8fa,16,2, 25,&z8002_device::ZB8_ddN0_1010_0000_rrrr_ssN0_0000, "trtrb @%rw2,@%rw6,%rb5", 0}, -{0xb81c,0xb8fc,16,2, 25,&z8002_device::ZB8_ddN0_1100_0000_rrrr_ssN0_0000, "trdrb @%rw2,@%rw6,%rb5", 0}, -{0xb81e,0xb8fe,16,2, 25,&z8002_device::ZB8_ddN0_1110_0000_rrrr_ssN0_1110, "trtdrb @%rw2,@%rw6,%rb5", 0}, -{0xb900,0xb9ff,16,1, 10,&z8002_device::ZB9_imm8, "rsvdb9", 0}, -{0xba10,0xbaf0,16,2, 11,&z8002_device::ZBA_ssN0_0000_0000_rrrr_dddd_cccc, "cpib %rb6,@%rw2,%rw5,%c7", 0}, -{0xba11,0xbaf1,16,2, 11,&z8002_device::ZBA_ssN0_0001_0000_rrrr_ddN0_x000, "ldirb @%rw6,@%rw2,%rw5", DASMFLAG_STEP_OVER}, -{0xba12,0xbaf2,16,2, 11,&z8002_device::ZBA_ssN0_0010_0000_rrrr_ddN0_cccc, "cpsib @%rw6,@%rw2,%rw5,%c7", 0}, -{0xba14,0xbaf4,16,2, 11,&z8002_device::ZBA_ssN0_0100_0000_rrrr_dddd_cccc, "cpirb %rb6,@%rw2,%rw5,%c7", DASMFLAG_STEP_OVER}, -{0xba16,0xbaf6,16,2, 11,&z8002_device::ZBA_ssN0_0110_0000_rrrr_ddN0_cccc, "cpsirb @%rw6,@%rw2,%rw5,%c7", DASMFLAG_STEP_OVER}, -{0xba18,0xbaf8,16,2, 11,&z8002_device::ZBA_ssN0_1000_0000_rrrr_dddd_cccc, "cpdb %rb6,@%rw2,%rw5,%c7", 0}, -{0xba19,0xbaf9,16,2, 11,&z8002_device::ZBA_ssN0_1001_0000_rrrr_ddN0_x000, "lddrb @%rw2,@%rw6,%rw5", DASMFLAG_STEP_OVER}, -{0xba1a,0xbafa,16,2, 11,&z8002_device::ZBA_ssN0_1010_0000_rrrr_ddN0_cccc, "cpsdb @%rw6,@%rw2,%rw5,%c7", 0}, -{0xba1c,0xbafc,16,2, 11,&z8002_device::ZBA_ssN0_1100_0000_rrrr_dddd_cccc, "cpdrb %rb6,@%rw2,%rw5,%c7", DASMFLAG_STEP_OVER}, -{0xba1e,0xbafe,16,2, 11,&z8002_device::ZBA_ssN0_1110_0000_rrrr_ddN0_cccc, "cpsdrb @%rw6,@%rw2,%rw5,%c7", DASMFLAG_STEP_OVER}, -{0xbb10,0xbbf0,16,2, 11,&z8002_device::ZBB_ssN0_0000_0000_rrrr_dddd_cccc, "cpi %rw6,@%rw2,%rw5,%c7", 0}, -{0xbb11,0xbbf1,16,2, 11,&z8002_device::ZBB_ssN0_0001_0000_rrrr_ddN0_x000, "ldir @%rw6,@%rw2,%rw5", DASMFLAG_STEP_OVER}, -{0xbb12,0xbbf2,16,2, 11,&z8002_device::ZBB_ssN0_0010_0000_rrrr_ddN0_cccc, "cpsi @%rw6,@%rw2,%rw5,%c7", 0}, -{0xbb14,0xbbf4,16,2, 11,&z8002_device::ZBB_ssN0_0100_0000_rrrr_dddd_cccc, "cpir %rw6,@%rw2,%rw5,%c7", DASMFLAG_STEP_OVER}, -{0xbb16,0xbbf6,16,2, 11,&z8002_device::ZBB_ssN0_0110_0000_rrrr_ddN0_cccc, "cpsir @%rw6,@%rw2,%rw5,%c7", DASMFLAG_STEP_OVER}, -{0xbb18,0xbbf8,16,2, 11,&z8002_device::ZBB_ssN0_1000_0000_rrrr_dddd_cccc, "cpd %rw6,@%rw2,%rw5,%c7", 0}, -{0xbb19,0xbbf9,16,2, 11,&z8002_device::ZBB_ssN0_1001_0000_rrrr_ddN0_x000, "lddr @%rw2,@%rw6,%rw5", DASMFLAG_STEP_OVER}, -{0xbb1a,0xbbfa,16,2, 11,&z8002_device::ZBB_ssN0_1010_0000_rrrr_ddN0_cccc, "cpsd @%rw6,@%rw2,%rw5,%c7", 0}, -{0xbb1c,0xbbfc,16,2, 11,&z8002_device::ZBB_ssN0_1100_0000_rrrr_dddd_cccc, "cpdr %rw6,@%rw2,%rw5,%c7", DASMFLAG_STEP_OVER}, -{0xbb1e,0xbbfe,16,2, 11,&z8002_device::ZBB_ssN0_1110_0000_rrrr_ddN0_cccc, "cpsdr @%rw6,@%rw2,%rw5,%c7", DASMFLAG_STEP_OVER}, -{0xbc00,0xbcff, 1,1, 9,&z8002_device::ZBC_aaaa_bbbb, "rrdb %rb3,%rb2", 0}, -{0xbd00,0xbdff, 1,1, 5,&z8002_device::ZBD_dddd_imm4, "ldk %rw2,%3", 0}, -{0xbe00,0xbeff, 1,1, 9,&z8002_device::ZBE_aaaa_bbbb, "rldb %rb3,%rb2", 0}, -{0xbf00,0xbfff, 1,1, 10,&z8002_device::ZBF_imm8, "rsvdbf", 0}, -{0xc000,0xcfff, 1,1, 5,&z8002_device::ZC_dddd_imm8, "ldb %rb1,%#b1", 0}, -{0xd000,0xdfff, 1,1, 10,&z8002_device::ZD_dsp12, "calr %d2", DASMFLAG_STEP_OVER}, -{0xe000,0xefff, 1,1, 6,&z8002_device::ZE_cccc_dsp8, "jr %c1,%d1", 0}, -{0xf000,0xf07f, 1,1, 11,&z8002_device::ZF_dddd_0dsp7, "dbjnz %rb1,%d0", DASMFLAG_STEP_OVER}, -{0xf100,0xf17f, 1,1, 11,&z8002_device::ZF_dddd_0dsp7, "dbjnz %rb1,%d0", DASMFLAG_STEP_OVER}, -{0xf200,0xf27f, 1,1, 11,&z8002_device::ZF_dddd_0dsp7, "dbjnz %rb1,%d0", DASMFLAG_STEP_OVER}, -{0xf300,0xf37f, 1,1, 11,&z8002_device::ZF_dddd_0dsp7, "dbjnz %rb1,%d0", DASMFLAG_STEP_OVER}, -{0xf400,0xf47f, 1,1, 11,&z8002_device::ZF_dddd_0dsp7, "dbjnz %rb1,%d0", DASMFLAG_STEP_OVER}, -{0xf500,0xf57f, 1,1, 11,&z8002_device::ZF_dddd_0dsp7, "dbjnz %rb1,%d0", DASMFLAG_STEP_OVER}, -{0xf600,0xf67f, 1,1, 11,&z8002_device::ZF_dddd_0dsp7, "dbjnz %rb1,%d0", DASMFLAG_STEP_OVER}, -{0xf700,0xf77f, 1,1, 11,&z8002_device::ZF_dddd_0dsp7, "dbjnz %rb1,%d0", DASMFLAG_STEP_OVER}, -{0xf800,0xf87f, 1,1, 11,&z8002_device::ZF_dddd_0dsp7, "dbjnz %rb1,%d0", DASMFLAG_STEP_OVER}, -{0xf900,0xf97f, 1,1, 11,&z8002_device::ZF_dddd_0dsp7, "dbjnz %rb1,%d0", DASMFLAG_STEP_OVER}, -{0xfa00,0xfa7f, 1,1, 11,&z8002_device::ZF_dddd_0dsp7, "dbjnz %rb1,%d0", DASMFLAG_STEP_OVER}, -{0xfb00,0xfb7f, 1,1, 11,&z8002_device::ZF_dddd_0dsp7, "dbjnz %rb1,%d0", DASMFLAG_STEP_OVER}, -{0xfc00,0xfc7f, 1,1, 11,&z8002_device::ZF_dddd_0dsp7, "dbjnz %rb1,%d0", DASMFLAG_STEP_OVER}, -{0xfd00,0xfd7f, 1,1, 11,&z8002_device::ZF_dddd_0dsp7, "dbjnz %rb1,%d0", DASMFLAG_STEP_OVER}, -{0xfe00,0xfe7f, 1,1, 11,&z8002_device::ZF_dddd_0dsp7, "dbjnz %rb1,%d0", DASMFLAG_STEP_OVER}, -{0xff00,0xff7f, 1,1, 11,&z8002_device::ZF_dddd_0dsp7, "dbjnz %rb1,%d0", DASMFLAG_STEP_OVER}, -{0xf080,0xf0ff, 1,1, 11,&z8002_device::ZF_dddd_1dsp7, "djnz %rw1,%d0", DASMFLAG_STEP_OVER}, -{0xf180,0xf1ff, 1,1, 11,&z8002_device::ZF_dddd_1dsp7, "djnz %rw1,%d0", DASMFLAG_STEP_OVER}, -{0xf280,0xf2ff, 1,1, 11,&z8002_device::ZF_dddd_1dsp7, "djnz %rw1,%d0", DASMFLAG_STEP_OVER}, -{0xf380,0xf3ff, 1,1, 11,&z8002_device::ZF_dddd_1dsp7, "djnz %rw1,%d0", DASMFLAG_STEP_OVER}, -{0xf480,0xf4ff, 1,1, 11,&z8002_device::ZF_dddd_1dsp7, "djnz %rw1,%d0", DASMFLAG_STEP_OVER}, -{0xf580,0xf5ff, 1,1, 11,&z8002_device::ZF_dddd_1dsp7, "djnz %rw1,%d0", DASMFLAG_STEP_OVER}, -{0xf680,0xf6ff, 1,1, 11,&z8002_device::ZF_dddd_1dsp7, "djnz %rw1,%d0", DASMFLAG_STEP_OVER}, -{0xf780,0xf7ff, 1,1, 11,&z8002_device::ZF_dddd_1dsp7, "djnz %rw1,%d0", DASMFLAG_STEP_OVER}, -{0xf880,0xf8ff, 1,1, 11,&z8002_device::ZF_dddd_1dsp7, "djnz %rw1,%d0", DASMFLAG_STEP_OVER}, -{0xf980,0xf9ff, 1,1, 11,&z8002_device::ZF_dddd_1dsp7, "djnz %rw1,%d0", DASMFLAG_STEP_OVER}, -{0xfa80,0xfaff, 1,1, 11,&z8002_device::ZF_dddd_1dsp7, "djnz %rw1,%d0", DASMFLAG_STEP_OVER}, -{0xfb80,0xfbff, 1,1, 11,&z8002_device::ZF_dddd_1dsp7, "djnz %rw1,%d0", DASMFLAG_STEP_OVER}, -{0xfc80,0xfcff, 1,1, 11,&z8002_device::ZF_dddd_1dsp7, "djnz %rw1,%d0", DASMFLAG_STEP_OVER}, -{0xfd80,0xfdff, 1,1, 11,&z8002_device::ZF_dddd_1dsp7, "djnz %rw1,%d0", DASMFLAG_STEP_OVER}, -{0xfe80,0xfeff, 1,1, 11,&z8002_device::ZF_dddd_1dsp7, "djnz %rw1,%d0", DASMFLAG_STEP_OVER}, -{0xff80,0xffff, 1,1, 11,&z8002_device::ZF_dddd_1dsp7, "djnz %rw1,%d0", DASMFLAG_STEP_OVER}, -{0, 0, 0,0, 0,nullptr, nullptr, 0} -}; - - -void z8002_device::init_tables() -{ - /* already initialized? */ - if (z8000_exec) - return; - - const Z8000_init *init; - int i; - - /* allocate the opcode execution and disassembler array */ - std::unique_ptr<Z8000_exec []> exec(new Z8000_exec[0x10000]); - - /* set up the zero, sign, parity lookup table */ - for (i = 0; i < 256; i++) - z8000_zsp[i] = ((i == 0) ? F_Z : 0) | - ((i & 128) ? F_S : 0) | - ((((i>>7)^(i>>6)^(i>>5)^(i>>4)^(i>>3)^(i>>2)^(i>>1)^i) & 1) ? 0 : F_PV); + { 0x0000, 0xffff, 1, 1, 4, &z8002_device::zinvalid }, - /* first set all 64K opcodes to invalid */ - for (i = 0; i < 0x10000; i++) - { - exec[i].opcode = &z8002_device::zinvalid; - exec[i].cycles = 4; - exec[i].size = 1; - exec[i].dasm = ".word %#w0"; - exec[i].dasmflags = 0; - } - - /* now decompose the initialization table */ - for (init = table; init->size; init++) - { - for (i = init->beg; i <= init->end; i += init->step) - { - if (exec[i].opcode != &z8002_device::zinvalid) - osd_printf_error("Z8000 opcode %04x clash '%s'\n", i, exec[i].dasm); - - exec[i].opcode = init->opcode; - exec[i].cycles = init->cycles; - exec[i].size = init->size; - exec[i].dasm = init->dasm; - exec[i].dasmflags = init->dasmflags; - } - } - - z8000_exec = std::move(exec); -} - -void z8002_device::deinit_tables() -{ - z8000_exec = nullptr; -} - -z8002_device::Z8000_dasm z8002_device::dasm(unsigned w) -{ - init_tables(); - Z8000_exec const &exec(z8000_exec[w]); - return Z8000_dasm{ exec.dasm, exec.dasmflags, exec.size }; -} + { 0x0000, 0x000f, 1, 2, 7, &z8002_device::Z00_0000_dddd_imm8 }, + { 0x0010, 0x00ff, 1, 1, 7, &z8002_device::Z00_ssN0_dddd }, + { 0x0100, 0x010f, 1, 2, 7, &z8002_device::Z01_0000_dddd_imm16 }, + { 0x0110, 0x01ff, 1, 1, 7, &z8002_device::Z01_ssN0_dddd }, + { 0x0200, 0x020f, 1, 2, 7, &z8002_device::Z02_0000_dddd_imm8 }, + { 0x0210, 0x02ff, 1, 1, 7, &z8002_device::Z02_ssN0_dddd }, + { 0x0300, 0x030f, 1, 2, 7, &z8002_device::Z03_0000_dddd_imm16 }, + { 0x0310, 0x03ff, 1, 1, 7, &z8002_device::Z03_ssN0_dddd }, + { 0x0400, 0x040f, 1, 2, 7, &z8002_device::Z04_0000_dddd_imm8 }, + { 0x0410, 0x04ff, 1, 1, 7, &z8002_device::Z04_ssN0_dddd }, + { 0x0500, 0x050f, 1, 2, 7, &z8002_device::Z05_0000_dddd_imm16 }, + { 0x0510, 0x05ff, 1, 1, 7, &z8002_device::Z05_ssN0_dddd }, + { 0x0600, 0x060f, 1, 2, 7, &z8002_device::Z06_0000_dddd_imm8 }, + { 0x0610, 0x06ff, 1, 1, 7, &z8002_device::Z06_ssN0_dddd }, + { 0x0700, 0x070f, 1, 2, 7, &z8002_device::Z07_0000_dddd_imm16 }, + { 0x0710, 0x07ff, 1, 1, 7, &z8002_device::Z07_ssN0_dddd }, + { 0x0800, 0x080f, 1, 2, 7, &z8002_device::Z08_0000_dddd_imm8 }, + { 0x0810, 0x08ff, 1, 1, 7, &z8002_device::Z08_ssN0_dddd }, + { 0x0900, 0x090f, 1, 2, 7, &z8002_device::Z09_0000_dddd_imm16 }, + { 0x0910, 0x09ff, 1, 1, 7, &z8002_device::Z09_ssN0_dddd }, + { 0x0a00, 0x0a0f, 1, 2, 7, &z8002_device::Z0A_0000_dddd_imm8 }, + { 0x0a10, 0x0aff, 1, 1, 7, &z8002_device::Z0A_ssN0_dddd }, + { 0x0b00, 0x0b0f, 1, 2, 7, &z8002_device::Z0B_0000_dddd_imm16 }, + { 0x0b10, 0x0bff, 1, 1, 7, &z8002_device::Z0B_ssN0_dddd }, + { 0x0c10, 0x0cf0, 16, 1, 12, &z8002_device::Z0C_ddN0_0000 }, + { 0x0c11, 0x0cf1, 16, 2, 11, &z8002_device::Z0C_ddN0_0001_imm8 }, + { 0x0c12, 0x0cf2, 16, 1, 12, &z8002_device::Z0C_ddN0_0010 }, + { 0x0c14, 0x0cf4, 16, 1, 8, &z8002_device::Z0C_ddN0_0100 }, + { 0x0c15, 0x0cf5, 16, 2, 7, &z8002_device::Z0C_ddN0_0101_imm8 }, + { 0x0c16, 0x0cf6, 16, 1, 11, &z8002_device::Z0C_ddN0_0110 }, + { 0x0c18, 0x0cf8, 16, 1, 8, &z8002_device::Z0C_ddN0_1000 }, + { 0x0d10, 0x0df0, 16, 1, 12, &z8002_device::Z0D_ddN0_0000 }, + { 0x0d11, 0x0df1, 16, 2, 11, &z8002_device::Z0D_ddN0_0001_imm16 }, + { 0x0d12, 0x0df2, 16, 1, 12, &z8002_device::Z0D_ddN0_0010 }, + { 0x0d14, 0x0df4, 16, 1, 8, &z8002_device::Z0D_ddN0_0100 }, + { 0x0d15, 0x0df5, 16, 2, 11, &z8002_device::Z0D_ddN0_0101_imm16 }, /* fix cycles ld IR,IM */ + { 0x0d16, 0x0df6, 16, 1, 11, &z8002_device::Z0D_ddN0_0110 }, + { 0x0d18, 0x0df8, 16, 1, 8, &z8002_device::Z0D_ddN0_1000 }, + { 0x0d19, 0x0df9, 16, 2, 12, &z8002_device::Z0D_ddN0_1001_imm16 }, + { 0x0e00, 0x0eff, 1, 1, 10, &z8002_device::Z0E_imm8 }, + { 0x0f00, 0x0fff, 1, 1, 10, &z8002_device::Z0F_imm8 }, + { 0x1000, 0x100f, 1, 3, 14, &z8002_device::Z10_0000_dddd_imm32 }, + { 0x1010, 0x10ff, 1, 1, 14, &z8002_device::Z10_ssN0_dddd }, + { 0x1111, 0x11ff, 1, 1, 20, &z8002_device::Z11_ddN0_ssN0 }, + { 0x1200, 0x120f, 1, 3, 14, &z8002_device::Z12_0000_dddd_imm32 }, + { 0x1210, 0x12ff, 1, 1, 14, &z8002_device::Z12_ssN0_dddd }, + { 0x1311, 0x13ff, 1, 1, 13, &z8002_device::Z13_ddN0_ssN0 }, + { 0x1400, 0x140f, 1, 3, 11, &z8002_device::Z14_0000_dddd_imm32 }, + { 0x1410, 0x14ff, 1, 1, 11, &z8002_device::Z14_ssN0_dddd }, + { 0x1511, 0x15ff, 1, 1, 19, &z8002_device::Z15_ssN0_ddN0 }, + { 0x1600, 0x160f, 1, 3, 14, &z8002_device::Z16_0000_dddd_imm32 }, + { 0x1610, 0x16ff, 1, 1, 14, &z8002_device::Z16_ssN0_dddd }, + { 0x1711, 0x17ff, 1, 1, 12, &z8002_device::Z17_ssN0_ddN0 }, + { 0x1800, 0x180f, 1, 1, 282, &z8002_device::Z18_00N0_dddd_imm32 }, + { 0x1810, 0x18ff, 1, 1, 282, &z8002_device::Z18_ssN0_dddd }, + { 0x1900, 0x190f, 1, 2, 70, &z8002_device::Z19_0000_dddd_imm16 }, + { 0x1910, 0x19ff, 1, 1, 70, &z8002_device::Z19_ssN0_dddd }, + { 0x1a00, 0x1a0f, 1, 3, 744, &z8002_device::Z1A_0000_dddd_imm32 }, + { 0x1a10, 0x1aff, 1, 1, 744, &z8002_device::Z1A_ssN0_dddd }, + { 0x1b00, 0x1b0f, 1, 2, 107, &z8002_device::Z1B_0000_dddd_imm16 }, + { 0x1b10, 0x1bff, 1, 1, 107, &z8002_device::Z1B_ssN0_dddd }, + { 0x1c11, 0x1cf1, 16, 2, 11, &z8002_device::Z1C_ssN0_0001_0000_dddd_0000_nmin1 }, + { 0x1c18, 0x1cf8, 16, 1, 13, &z8002_device::Z1C_ddN0_1000 }, + { 0x1c19, 0x1cf9, 16, 2, 11, &z8002_device::Z1C_ddN0_1001_0000_ssss_0000_nmin1 }, + { 0x1d10, 0x1dff, 1, 1, 11, &z8002_device::Z1D_ddN0_ssss }, + { 0x1e10, 0x1eff, 1, 1, 10, &z8002_device::Z1E_ddN0_cccc }, + { 0x1f10, 0x1ff0, 16, 1, 10, &z8002_device::Z1F_ddN0_0000 }, + { 0x2000, 0x200f, 1, 2, 7, &z8002_device::Z20_0000_dddd_imm8 }, + { 0x2010, 0x20ff, 1, 1, 7, &z8002_device::Z20_ssN0_dddd }, + { 0x2100, 0x210f, 1, 2, 7, &z8002_device::Z21_0000_dddd_imm16 }, + { 0x2110, 0x21ff, 1, 1, 7, &z8002_device::Z21_ssN0_dddd }, + { 0x2200, 0x220f, 1, 2, 10, &z8002_device::Z22_0000_ssss_0000_dddd_0000_0000 }, + { 0x2210, 0x22ff, 1, 1, 11, &z8002_device::Z22_ddN0_imm4 }, + { 0x2300, 0x230f, 1, 2, 10, &z8002_device::Z23_0000_ssss_0000_dddd_0000_0000 }, + { 0x2310, 0x23ff, 1, 1, 11, &z8002_device::Z23_ddN0_imm4 }, + { 0x2400, 0x240f, 1, 2, 10, &z8002_device::Z24_0000_ssss_0000_dddd_0000_0000 }, + { 0x2410, 0x24ff, 1, 1, 11, &z8002_device::Z24_ddN0_imm4 }, + { 0x2500, 0x250f, 1, 2, 10, &z8002_device::Z25_0000_ssss_0000_dddd_0000_0000 }, + { 0x2510, 0x25ff, 1, 1, 11, &z8002_device::Z25_ddN0_imm4 }, + { 0x2600, 0x260f, 1, 2, 10, &z8002_device::Z26_0000_ssss_0000_dddd_0000_0000 }, + { 0x2610, 0x26ff, 1, 1, 8, &z8002_device::Z26_ddN0_imm4 }, + { 0x2700, 0x270f, 1, 2, 10, &z8002_device::Z27_0000_ssss_0000_dddd_0000_0000 }, + { 0x2710, 0x27ff, 1, 1, 8, &z8002_device::Z27_ddN0_imm4 }, + { 0x2810, 0x28ff, 1, 1, 11, &z8002_device::Z28_ddN0_imm4m1 }, + { 0x2910, 0x29ff, 1, 1, 11, &z8002_device::Z29_ddN0_imm4m1 }, + { 0x2a10, 0x2aff, 1, 1, 11, &z8002_device::Z2A_ddN0_imm4m1 }, + { 0x2b10, 0x2bff, 1, 1, 11, &z8002_device::Z2B_ddN0_imm4m1 }, + { 0x2c10, 0x2cff, 1, 1, 12, &z8002_device::Z2C_ssN0_dddd }, + { 0x2d10, 0x2dff, 1, 1, 12, &z8002_device::Z2D_ssN0_dddd }, + { 0x2e10, 0x2eff, 1, 1, 8, &z8002_device::Z2E_ddN0_ssss }, + { 0x2f10, 0x2fff, 1, 1, 8, &z8002_device::Z2F_ddN0_ssss }, + { 0x3000, 0x300f, 1, 2, 14, &z8002_device::Z30_0000_dddd_dsp16 }, + { 0x3010, 0x30ff, 1, 2, 14, &z8002_device::Z30_ssN0_dddd_imm16 }, + { 0x3100, 0x310f, 1, 2, 14, &z8002_device::Z31_0000_dddd_dsp16 }, + { 0x3110, 0x31ff, 1, 2, 14, &z8002_device::Z31_ssN0_dddd_imm16 }, + { 0x3200, 0x320f, 1, 2, 14, &z8002_device::Z32_0000_ssss_dsp16 }, + { 0x3210, 0x32ff, 1, 2, 14, &z8002_device::Z32_ddN0_ssss_imm16 }, + { 0x3300, 0x330f, 1, 2, 14, &z8002_device::Z33_0000_ssss_dsp16 }, + { 0x3310, 0x33ff, 1, 2, 14, &z8002_device::Z33_ddN0_ssss_imm16 }, + { 0x3400, 0x340f, 1, 2, 15, &z8002_device::Z34_0000_dddd_dsp16 }, + { 0x3410, 0x34ff, 1, 2, 15, &z8002_device::Z34_ssN0_dddd_imm16 }, + { 0x3500, 0x350f, 1, 2, 17, &z8002_device::Z35_0000_dddd_dsp16 }, + { 0x3510, 0x35ff, 1, 2, 17, &z8002_device::Z35_ssN0_dddd_imm16 }, + { 0x3600, 0x3600, 1, 1, 2, &z8002_device::Z36_0000_0000 }, + { 0x3601, 0x36ff, 1, 1, 10, &z8002_device::Z36_imm8 }, + { 0x3700, 0x370f, 1, 2, 17, &z8002_device::Z37_0000_ssss_dsp16 }, + { 0x3710, 0x37ff, 1, 2, 17, &z8002_device::Z37_ddN0_ssss_imm16 }, + { 0x3800, 0x38ff, 1, 1, 10, &z8002_device::Z38_imm8 }, + { 0x3910, 0x39f0, 16, 1, 12, &z8002_device::Z39_ssN0_0000 }, + { 0x3a00, 0x3af0, 16, 2, 21, &z8002_device::Z3A_ssss_0000_0000_aaaa_dddd_x000 }, + { 0x3a01, 0x3af1, 16, 2, 21, &z8002_device::Z3A_ssss_0001_0000_aaaa_dddd_x000 }, + { 0x3a02, 0x3af2, 16, 2, 21, &z8002_device::Z3A_ssss_0010_0000_aaaa_dddd_x000 }, + { 0x3a03, 0x3af3, 16, 2, 21, &z8002_device::Z3A_ssss_0011_0000_aaaa_dddd_x000 }, + { 0x3a04, 0x3af4, 16, 2, 10, &z8002_device::Z3A_dddd_0100_imm16 }, + { 0x3a05, 0x3af5, 16, 2, 10, &z8002_device::Z3A_dddd_0101_imm16 }, + { 0x3a06, 0x3af6, 16, 2, 12, &z8002_device::Z3A_ssss_0110_imm16 }, + { 0x3a07, 0x3af7, 16, 2, 12, &z8002_device::Z3A_ssss_0111_imm16 }, + { 0x3a08, 0x3af8, 16, 2, 21, &z8002_device::Z3A_ssss_1000_0000_aaaa_dddd_x000 }, + { 0x3a09, 0x3af9, 16, 2, 21, &z8002_device::Z3A_ssss_1001_0000_aaaa_dddd_x000 }, + { 0x3a0a, 0x3afa, 16, 2, 21, &z8002_device::Z3A_ssss_1010_0000_aaaa_dddd_x000 }, + { 0x3a0b, 0x3afb, 16, 2, 21, &z8002_device::Z3A_ssss_1011_0000_aaaa_dddd_x000 }, + { 0x3b00, 0x3bf0, 16, 2, 21, &z8002_device::Z3B_ssss_0000_0000_aaaa_dddd_x000 }, + { 0x3b01, 0x3bf1, 16, 2, 21, &z8002_device::Z3B_ssss_0001_0000_aaaa_dddd_x000 }, + { 0x3b02, 0x3bf2, 16, 2, 21, &z8002_device::Z3B_ssss_0010_0000_aaaa_dddd_x000 }, + { 0x3b03, 0x3bf3, 16, 2, 21, &z8002_device::Z3B_ssss_0011_0000_aaaa_dddd_x000 }, + { 0x3b04, 0x3bf4, 16, 2, 12, &z8002_device::Z3B_dddd_0100_imm16 }, + { 0x3b05, 0x3bf5, 16, 2, 12, &z8002_device::Z3B_dddd_0101_imm16 }, + { 0x3b06, 0x3bf6, 16, 2, 12, &z8002_device::Z3B_ssss_0110_imm16 }, + { 0x3b07, 0x3bf7, 16, 2, 12, &z8002_device::Z3B_ssss_0111_imm16 }, + { 0x3b08, 0x3bf8, 16, 2, 21, &z8002_device::Z3B_ssss_1000_0000_aaaa_dddd_x000 }, + { 0x3b09, 0x3bf9, 16, 2, 21, &z8002_device::Z3B_ssss_1001_0000_aaaa_dddd_x000 }, + { 0x3b0a, 0x3bfa, 16, 2, 21, &z8002_device::Z3B_ssss_1010_0000_aaaa_dddd_x000 }, + { 0x3b0b, 0x3bfb, 16, 2, 21, &z8002_device::Z3B_ssss_1011_0000_aaaa_dddd_x000 }, + { 0x3c00, 0x3cff, 1, 1, 10, &z8002_device::Z3C_ssss_dddd }, + { 0x3d00, 0x3dff, 1, 1, 10, &z8002_device::Z3D_ssss_dddd }, + { 0x3e00, 0x3eff, 1, 1, 12, &z8002_device::Z3E_dddd_ssss }, + { 0x3f00, 0x3fff, 1, 1, 12, &z8002_device::Z3F_dddd_ssss }, + { 0x4000, 0x400f, 1, 2, 9, &z8002_device::Z40_0000_dddd_addr }, + { 0x4010, 0x40ff, 1, 2, 10, &z8002_device::Z40_ssN0_dddd_addr }, + { 0x4100, 0x410f, 1, 2, 9, &z8002_device::Z41_0000_dddd_addr }, + { 0x4110, 0x41ff, 1, 2, 10, &z8002_device::Z41_ssN0_dddd_addr }, + { 0x4200, 0x420f, 1, 2, 9, &z8002_device::Z42_0000_dddd_addr }, + { 0x4210, 0x42ff, 1, 2, 10, &z8002_device::Z42_ssN0_dddd_addr }, + { 0x4300, 0x430f, 1, 2, 9, &z8002_device::Z43_0000_dddd_addr }, + { 0x4310, 0x43ff, 1, 2, 10, &z8002_device::Z43_ssN0_dddd_addr }, + { 0x4400, 0x440f, 1, 2, 9, &z8002_device::Z44_0000_dddd_addr }, + { 0x4410, 0x44ff, 1, 2, 10, &z8002_device::Z44_ssN0_dddd_addr }, + { 0x4500, 0x450f, 1, 2, 9, &z8002_device::Z45_0000_dddd_addr }, + { 0x4510, 0x45ff, 1, 2, 10, &z8002_device::Z45_ssN0_dddd_addr }, + { 0x4600, 0x460f, 1, 2, 9, &z8002_device::Z46_0000_dddd_addr }, + { 0x4610, 0x46ff, 1, 2, 10, &z8002_device::Z46_ssN0_dddd_addr }, + { 0x4700, 0x470f, 1, 2, 9, &z8002_device::Z47_0000_dddd_addr }, + { 0x4710, 0x47ff, 1, 2, 10, &z8002_device::Z47_ssN0_dddd_addr }, + { 0x4800, 0x480f, 1, 2, 9, &z8002_device::Z48_0000_dddd_addr }, + { 0x4810, 0x48ff, 1, 2, 10, &z8002_device::Z48_ssN0_dddd_addr }, + { 0x4900, 0x490f, 1, 2, 9, &z8002_device::Z49_0000_dddd_addr }, + { 0x4910, 0x49ff, 1, 2, 10, &z8002_device::Z49_ssN0_dddd_addr }, + { 0x4a00, 0x4a0f, 1, 2, 9, &z8002_device::Z4A_0000_dddd_addr }, + { 0x4a10, 0x4aff, 1, 2, 10, &z8002_device::Z4A_ssN0_dddd_addr }, + { 0x4b00, 0x4b0f, 1, 2, 9, &z8002_device::Z4B_0000_dddd_addr }, + { 0x4b10, 0x4bff, 1, 2, 10, &z8002_device::Z4B_ssN0_dddd_addr }, + { 0x4c00, 0x4c00, 1, 2, 15, &z8002_device::Z4C_0000_0000_addr }, + { 0x4c01, 0x4c01, 1, 3, 14, &z8002_device::Z4C_0000_0001_addr_imm8 }, + { 0x4c02, 0x4c02, 1, 2, 15, &z8002_device::Z4C_0000_0010_addr }, + { 0x4c04, 0x4c04, 1, 2, 11, &z8002_device::Z4C_0000_0100_addr }, + { 0x4c05, 0x4c05, 1, 3, 14, &z8002_device::Z4C_0000_0101_addr_imm8 }, + { 0x4c06, 0x4c06, 1, 2, 14, &z8002_device::Z4C_0000_0110_addr }, + { 0x4c08, 0x4c08, 1, 2, 11, &z8002_device::Z4C_0000_1000_addr }, + { 0x4c10, 0x4cf0, 16, 2, 16, &z8002_device::Z4C_ddN0_0000_addr }, + { 0x4c11, 0x4cf1, 16, 3, 15, &z8002_device::Z4C_ddN0_0001_addr_imm8 }, + { 0x4c12, 0x4cf2, 16, 2, 16, &z8002_device::Z4C_ddN0_0010_addr }, + { 0x4c14, 0x4cf4, 16, 2, 12, &z8002_device::Z4C_ddN0_0100_addr }, + { 0x4c15, 0x4cf5, 16, 3, 15, &z8002_device::Z4C_ddN0_0101_addr_imm8 }, + { 0x4c16, 0x4cf6, 16, 2, 15, &z8002_device::Z4C_ddN0_0110_addr }, + { 0x4c18, 0x4cf8, 16, 2, 12, &z8002_device::Z4C_ddN0_1000_addr }, + { 0x4d00, 0x4d00, 1, 2, 15, &z8002_device::Z4D_0000_0000_addr }, + { 0x4d01, 0x4d01, 1, 3, 14, &z8002_device::Z4D_0000_0001_addr_imm16 }, + { 0x4d02, 0x4d02, 1, 2, 15, &z8002_device::Z4D_0000_0010_addr }, + { 0x4d04, 0x4d04, 1, 2, 11, &z8002_device::Z4D_0000_0100_addr }, + { 0x4d05, 0x4d05, 1, 3, 14, &z8002_device::Z4D_0000_0101_addr_imm16 }, + { 0x4d06, 0x4d06, 1, 2, 14, &z8002_device::Z4D_0000_0110_addr }, + { 0x4d08, 0x4d08, 1, 2, 11, &z8002_device::Z4D_0000_1000_addr }, + { 0x4d10, 0x4df0, 16, 2, 16, &z8002_device::Z4D_ddN0_0000_addr }, + { 0x4d11, 0x4df1, 16, 3, 15, &z8002_device::Z4D_ddN0_0001_addr_imm16 }, + { 0x4d12, 0x4df2, 16, 2, 16, &z8002_device::Z4D_ddN0_0010_addr }, + { 0x4d14, 0x4df4, 16, 2, 12, &z8002_device::Z4D_ddN0_0100_addr }, + { 0x4d15, 0x4df5, 16, 3, 15, &z8002_device::Z4D_ddN0_0101_addr_imm16 }, + { 0x4d16, 0x4df6, 16, 2, 15, &z8002_device::Z4D_ddN0_0110_addr }, + { 0x4d18, 0x4df8, 16, 2, 12, &z8002_device::Z4D_ddN0_1000_addr }, + { 0x4e11, 0x4ef0, 16, 2, 12, &z8002_device::Z4E_ddN0_ssN0_addr }, + { 0x5000, 0x500f, 1, 2, 15, &z8002_device::Z50_0000_dddd_addr }, + { 0x5010, 0x50ff, 1, 2, 16, &z8002_device::Z50_ssN0_dddd_addr }, + { 0x5110, 0x51f0, 16, 2, 21, &z8002_device::Z51_ddN0_0000_addr }, + { 0x5111, 0x51f1, 16, 2, 21, &z8002_device::Z51_ddN0_ssN0_addr }, + { 0x5112, 0x51f2, 16, 2, 21, &z8002_device::Z51_ddN0_ssN0_addr }, + { 0x5113, 0x51f3, 16, 2, 21, &z8002_device::Z51_ddN0_ssN0_addr }, + { 0x5114, 0x51f4, 16, 2, 21, &z8002_device::Z51_ddN0_ssN0_addr }, + { 0x5115, 0x51f5, 16, 2, 21, &z8002_device::Z51_ddN0_ssN0_addr }, + { 0x5116, 0x51f6, 16, 2, 21, &z8002_device::Z51_ddN0_ssN0_addr }, + { 0x5117, 0x51f7, 16, 2, 21, &z8002_device::Z51_ddN0_ssN0_addr }, + { 0x5118, 0x51f8, 16, 2, 21, &z8002_device::Z51_ddN0_ssN0_addr }, + { 0x5119, 0x51f9, 16, 2, 21, &z8002_device::Z51_ddN0_ssN0_addr }, + { 0x511a, 0x51fa, 16, 2, 21, &z8002_device::Z51_ddN0_ssN0_addr }, + { 0x511b, 0x51fb, 16, 2, 21, &z8002_device::Z51_ddN0_ssN0_addr }, + { 0x511c, 0x51fc, 16, 2, 21, &z8002_device::Z51_ddN0_ssN0_addr }, + { 0x511d, 0x51fd, 16, 2, 21, &z8002_device::Z51_ddN0_ssN0_addr }, + { 0x511e, 0x51fe, 16, 2, 21, &z8002_device::Z51_ddN0_ssN0_addr }, + { 0x511f, 0x51ff, 16, 2, 21, &z8002_device::Z51_ddN0_ssN0_addr }, + { 0x5200, 0x520f, 1, 2, 15, &z8002_device::Z52_0000_dddd_addr }, + { 0x5210, 0x52ff, 1, 2, 16, &z8002_device::Z52_ssN0_dddd_addr }, + { 0x5310, 0x53f0, 16, 2, 14, &z8002_device::Z53_ddN0_0000_addr }, + { 0x5311, 0x53f1, 16, 2, 14, &z8002_device::Z53_ddN0_ssN0_addr }, + { 0x5312, 0x53f2, 16, 2, 14, &z8002_device::Z53_ddN0_ssN0_addr }, + { 0x5313, 0x53f3, 16, 2, 14, &z8002_device::Z53_ddN0_ssN0_addr }, + { 0x5314, 0x53f4, 16, 2, 14, &z8002_device::Z53_ddN0_ssN0_addr }, + { 0x5315, 0x53f5, 16, 2, 14, &z8002_device::Z53_ddN0_ssN0_addr }, + { 0x5316, 0x53f6, 16, 2, 14, &z8002_device::Z53_ddN0_ssN0_addr }, + { 0x5317, 0x53f7, 16, 2, 14, &z8002_device::Z53_ddN0_ssN0_addr }, + { 0x5318, 0x53f8, 16, 2, 14, &z8002_device::Z53_ddN0_ssN0_addr }, + { 0x5319, 0x53f9, 16, 2, 14, &z8002_device::Z53_ddN0_ssN0_addr }, + { 0x531a, 0x53fa, 16, 2, 14, &z8002_device::Z53_ddN0_ssN0_addr }, + { 0x531b, 0x53fb, 16, 2, 14, &z8002_device::Z53_ddN0_ssN0_addr }, + { 0x531c, 0x53fc, 16, 2, 14, &z8002_device::Z53_ddN0_ssN0_addr }, + { 0x531d, 0x53fd, 16, 2, 14, &z8002_device::Z53_ddN0_ssN0_addr }, + { 0x531e, 0x53fe, 16, 2, 14, &z8002_device::Z53_ddN0_ssN0_addr }, + { 0x531f, 0x53ff, 16, 2, 14, &z8002_device::Z53_ddN0_ssN0_addr }, + { 0x5400, 0x540f, 1, 2, 12, &z8002_device::Z54_0000_dddd_addr }, + { 0x5410, 0x54ff, 1, 2, 13, &z8002_device::Z54_ssN0_dddd_addr }, + { 0x5510, 0x55f0, 16, 2, 23, &z8002_device::Z55_ssN0_0000_addr }, + { 0x5511, 0x55f1, 16, 2, 23, &z8002_device::Z55_ssN0_ddN0_addr }, + { 0x5512, 0x55f2, 16, 2, 23, &z8002_device::Z55_ssN0_ddN0_addr }, + { 0x5513, 0x55f3, 16, 2, 23, &z8002_device::Z55_ssN0_ddN0_addr }, + { 0x5514, 0x55f4, 16, 2, 23, &z8002_device::Z55_ssN0_ddN0_addr }, + { 0x5515, 0x55f5, 16, 2, 23, &z8002_device::Z55_ssN0_ddN0_addr }, + { 0x5516, 0x55f6, 16, 2, 23, &z8002_device::Z55_ssN0_ddN0_addr }, + { 0x5517, 0x55f7, 16, 2, 23, &z8002_device::Z55_ssN0_ddN0_addr }, + { 0x5518, 0x55f8, 16, 2, 23, &z8002_device::Z55_ssN0_ddN0_addr }, + { 0x5519, 0x55f9, 16, 2, 23, &z8002_device::Z55_ssN0_ddN0_addr }, + { 0x551a, 0x55fa, 16, 2, 23, &z8002_device::Z55_ssN0_ddN0_addr }, + { 0x551b, 0x55fb, 16, 2, 23, &z8002_device::Z55_ssN0_ddN0_addr }, + { 0x551c, 0x55fc, 16, 2, 23, &z8002_device::Z55_ssN0_ddN0_addr }, + { 0x551d, 0x55fd, 16, 2, 23, &z8002_device::Z55_ssN0_ddN0_addr }, + { 0x551e, 0x55fe, 16, 2, 23, &z8002_device::Z55_ssN0_ddN0_addr }, + { 0x551f, 0x55ff, 16, 2, 23, &z8002_device::Z55_ssN0_ddN0_addr }, + { 0x5600, 0x560f, 1, 2, 15, &z8002_device::Z56_0000_dddd_addr }, + { 0x5610, 0x56ff, 1, 2, 16, &z8002_device::Z56_ssN0_dddd_addr }, + { 0x5710, 0x57f0, 16, 2, 16, &z8002_device::Z57_ssN0_0000_addr }, + { 0x5711, 0x57f1, 16, 2, 16, &z8002_device::Z57_ssN0_ddN0_addr }, + { 0x5712, 0x57f2, 16, 2, 16, &z8002_device::Z57_ssN0_ddN0_addr }, + { 0x5713, 0x57f3, 16, 2, 16, &z8002_device::Z57_ssN0_ddN0_addr }, + { 0x5714, 0x57f4, 16, 2, 16, &z8002_device::Z57_ssN0_ddN0_addr }, + { 0x5715, 0x57f5, 16, 2, 16, &z8002_device::Z57_ssN0_ddN0_addr }, + { 0x5716, 0x57f6, 16, 2, 16, &z8002_device::Z57_ssN0_ddN0_addr }, + { 0x5717, 0x57f7, 16, 2, 16, &z8002_device::Z57_ssN0_ddN0_addr }, + { 0x5718, 0x57f8, 16, 2, 16, &z8002_device::Z57_ssN0_ddN0_addr }, + { 0x5719, 0x57f9, 16, 2, 16, &z8002_device::Z57_ssN0_ddN0_addr }, + { 0x571a, 0x57fa, 16, 2, 16, &z8002_device::Z57_ssN0_ddN0_addr }, + { 0x571b, 0x57fb, 16, 2, 16, &z8002_device::Z57_ssN0_ddN0_addr }, + { 0x571c, 0x57fc, 16, 2, 16, &z8002_device::Z57_ssN0_ddN0_addr }, + { 0x571d, 0x57fd, 16, 2, 16, &z8002_device::Z57_ssN0_ddN0_addr }, + { 0x571e, 0x57fe, 16, 2, 16, &z8002_device::Z57_ssN0_ddN0_addr }, + { 0x571f, 0x57ff, 16, 2, 16, &z8002_device::Z57_ssN0_ddN0_addr }, + { 0x5800, 0x580f, 1, 2, 283, &z8002_device::Z58_0000_dddd_addr }, + { 0x5810, 0x58ff, 1, 2, 284, &z8002_device::Z58_ssN0_dddd_addr }, + { 0x5900, 0x590f, 1, 2, 71, &z8002_device::Z59_0000_dddd_addr }, + { 0x5910, 0x59ff, 1, 2, 72, &z8002_device::Z59_ssN0_dddd_addr }, + { 0x5a00, 0x5a0f, 1, 2, 745, &z8002_device::Z5A_0000_dddd_addr }, + { 0x5a10, 0x5aff, 1, 2, 746, &z8002_device::Z5A_ssN0_dddd_addr }, + { 0x5b00, 0x5b0f, 1, 2, 108, &z8002_device::Z5B_0000_dddd_addr }, + { 0x5b10, 0x5bff, 1, 2, 109, &z8002_device::Z5B_ssN0_dddd_addr }, + { 0x5c01, 0x5c01, 1, 3, 14, &z8002_device::Z5C_0000_0001_0000_dddd_0000_nmin1_addr }, + { 0x5c08, 0x5c08, 1, 2, 16, &z8002_device::Z5C_0000_1000_addr }, + { 0x5c09, 0x5c09, 1, 3, 14, &z8002_device::Z5C_0000_1001_0000_ssss_0000_nmin1_addr }, + { 0x5c11, 0x5cf1, 16, 3, 15, &z8002_device::Z5C_ssN0_0001_0000_dddd_0000_nmin1_addr }, + { 0x5c18, 0x5cf8, 16, 2, 17, &z8002_device::Z5C_ddN0_1000_addr }, + { 0x5c19, 0x5cf9, 16, 3, 15, &z8002_device::Z5C_ddN0_1001_0000_ssN0_0000_nmin1_addr }, + { 0x5d00, 0x5d0f, 1, 2, 15, &z8002_device::Z5D_0000_ssss_addr }, + { 0x5d10, 0x5dff, 1, 2, 14, &z8002_device::Z5D_ddN0_ssss_addr }, + { 0x5e00, 0x5e0f, 1, 2, 7, &z8002_device::Z5E_0000_cccc_addr }, + { 0x5e10, 0x5eff, 1, 2, 8, &z8002_device::Z5E_ddN0_cccc_addr }, + { 0x5f00, 0x5f00, 1, 2, 12, &z8002_device::Z5F_0000_0000_addr }, + { 0x5f10, 0x5ff0, 16, 2, 13, &z8002_device::Z5F_ddN0_0000_addr }, + { 0x6000, 0x600f, 1, 2, 9, &z8002_device::Z60_0000_dddd_addr }, + { 0x6010, 0x60ff, 1, 2, 10, &z8002_device::Z60_ssN0_dddd_addr }, + { 0x6100, 0x610f, 1, 2, 9, &z8002_device::Z61_0000_dddd_addr }, + { 0x6110, 0x61ff, 1, 2, 10, &z8002_device::Z61_ssN0_dddd_addr }, + { 0x6200, 0x620f, 1, 2, 13, &z8002_device::Z62_0000_imm4_addr }, + { 0x6210, 0x62ff, 1, 2, 14, &z8002_device::Z62_ddN0_imm4_addr }, + { 0x6300, 0x630f, 1, 2, 13, &z8002_device::Z63_0000_imm4_addr }, + { 0x6310, 0x63ff, 1, 2, 14, &z8002_device::Z63_ddN0_imm4_addr }, + { 0x6400, 0x640f, 1, 2, 13, &z8002_device::Z64_0000_imm4_addr }, + { 0x6410, 0x64ff, 1, 2, 14, &z8002_device::Z64_ddN0_imm4_addr }, + { 0x6500, 0x650f, 1, 2, 13, &z8002_device::Z65_0000_imm4_addr }, + { 0x6510, 0x65ff, 1, 2, 14, &z8002_device::Z65_ddN0_imm4_addr }, + { 0x6600, 0x660f, 1, 2, 10, &z8002_device::Z66_0000_imm4_addr }, + { 0x6610, 0x66ff, 1, 2, 11, &z8002_device::Z66_ddN0_imm4_addr }, + { 0x6700, 0x670f, 1, 2, 10, &z8002_device::Z67_0000_imm4_addr }, + { 0x6710, 0x67ff, 1, 2, 11, &z8002_device::Z67_ddN0_imm4_addr }, + { 0x6800, 0x680f, 1, 2, 13, &z8002_device::Z68_0000_imm4m1_addr }, + { 0x6810, 0x68ff, 1, 2, 14, &z8002_device::Z68_ddN0_imm4m1_addr }, + { 0x6900, 0x690f, 1, 2, 13, &z8002_device::Z69_0000_imm4m1_addr }, + { 0x6910, 0x69ff, 1, 2, 14, &z8002_device::Z69_ddN0_imm4m1_addr }, + { 0x6a00, 0x6a0f, 1, 2, 13, &z8002_device::Z6A_0000_imm4m1_addr }, + { 0x6a10, 0x6aff, 1, 2, 14, &z8002_device::Z6A_ddN0_imm4m1_addr }, + { 0x6b00, 0x6b0f, 1, 2, 13, &z8002_device::Z6B_0000_imm4m1_addr }, + { 0x6b10, 0x6bff, 1, 2, 14, &z8002_device::Z6B_ddN0_imm4m1_addr }, + { 0x6c00, 0x6c0f, 1, 2, 15, &z8002_device::Z6C_0000_dddd_addr }, + { 0x6c10, 0x6cff, 1, 2, 16, &z8002_device::Z6C_ssN0_dddd_addr }, + { 0x6d00, 0x6d0f, 1, 2, 15, &z8002_device::Z6D_0000_dddd_addr }, + { 0x6d10, 0x6dff, 1, 2, 16, &z8002_device::Z6D_ssN0_dddd_addr }, + { 0x6e00, 0x6e0f, 1, 2, 11, &z8002_device::Z6E_0000_ssss_addr }, + { 0x6e10, 0x6eff, 1, 2, 11, &z8002_device::Z6E_ddN0_ssss_addr }, + { 0x6f00, 0x6f0f, 1, 2, 11, &z8002_device::Z6F_0000_ssss_addr }, + { 0x6f10, 0x6fff, 1, 2, 12, &z8002_device::Z6F_ddN0_ssss_addr }, + { 0x7010, 0x70ff, 1, 2, 14, &z8002_device::Z70_ssN0_dddd_0000_xxxx_0000_0000 }, + { 0x7110, 0x71ff, 1, 2, 14, &z8002_device::Z71_ssN0_dddd_0000_xxxx_0000_0000 }, + { 0x7210, 0x72ff, 1, 2, 14, &z8002_device::Z72_ddN0_ssss_0000_xxxx_0000_0000 }, + { 0x7310, 0x73ff, 1, 2, 14, &z8002_device::Z73_ddN0_ssss_0000_xxxx_0000_0000 }, + { 0x7410, 0x74ff, 1, 2, 15, &z8002_device::Z74_ssN0_dddd_0000_xxxx_0000_0000 }, + { 0x7510, 0x75ff, 1, 2, 17, &z8002_device::Z75_ssN0_dddd_0000_xxxx_0000_0000 }, + { 0x7600, 0x760f, 1, 2, 12, &z8002_device::Z76_0000_dddd_addr }, + { 0x7610, 0x76ff, 1, 2, 13, &z8002_device::Z76_ssN0_dddd_addr }, + { 0x7710, 0x77ff, 1, 2, 17, &z8002_device::Z77_ddN0_ssss_0000_xxxx_0000_0000 }, + { 0x7800, 0x78ff, 1, 1, 10, &z8002_device::Z78_imm8 }, + { 0x7900, 0x7900, 1, 2, 16, &z8002_device::Z79_0000_0000_addr }, + { 0x7910, 0x79f0, 16, 2, 17, &z8002_device::Z79_ssN0_0000_addr }, + { 0x7a00, 0x7a00, 1, 1, 8, &z8002_device::Z7A_0000_0000 }, + { 0x7b00, 0x7b00, 1, 1, 13, &z8002_device::Z7B_0000_0000 }, + { 0x7b08, 0x7b08, 1, 1, 5, &z8002_device::Z7B_0000_1000 }, + { 0x7b09, 0x7b09, 1, 1, 5, &z8002_device::Z7B_0000_1001 }, + { 0x7b0a, 0x7b0a, 1, 1, 7, &z8002_device::Z7B_0000_1010 }, + { 0x7b0d, 0x7bfd, 16, 1, 12, &z8002_device::Z7B_dddd_1101 }, + { 0x7c00, 0x7c03, 1, 1, 7, &z8002_device::Z7C_0000_00ii }, + { 0x7c04, 0x7c07, 1, 1, 7, &z8002_device::Z7C_0000_01ii }, + { 0x7d00, 0x7df0, 16, 1, 7, &z8002_device::Z7D_dddd_0ccc }, + { 0x7d01, 0x7df1, 16, 1, 7, &z8002_device::Z7D_dddd_0ccc }, + { 0x7d02, 0x7df2, 16, 1, 7, &z8002_device::Z7D_dddd_0ccc }, + { 0x7d03, 0x7df3, 16, 1, 7, &z8002_device::Z7D_dddd_0ccc }, + { 0x7d04, 0x7df4, 16, 1, 7, &z8002_device::Z7D_dddd_0ccc }, + { 0x7d05, 0x7df5, 16, 1, 7, &z8002_device::Z7D_dddd_0ccc }, + { 0x7d06, 0x7df6, 16, 1, 7, &z8002_device::Z7D_dddd_0ccc }, + { 0x7d07, 0x7df7, 16, 1, 7, &z8002_device::Z7D_dddd_0ccc }, + { 0x7d08, 0x7df8, 16, 1, 7, &z8002_device::Z7D_ssss_1ccc }, + { 0x7d09, 0x7df9, 16, 1, 7, &z8002_device::Z7D_ssss_1ccc }, + { 0x7d0a, 0x7dfa, 16, 1, 7, &z8002_device::Z7D_ssss_1ccc }, + { 0x7d0b, 0x7dfb, 16, 1, 7, &z8002_device::Z7D_ssss_1ccc }, + { 0x7d0c, 0x7dfc, 16, 1, 7, &z8002_device::Z7D_ssss_1ccc }, + { 0x7d0d, 0x7dfd, 16, 1, 7, &z8002_device::Z7D_ssss_1ccc }, + { 0x7d0e, 0x7dfe, 16, 1, 7, &z8002_device::Z7D_ssss_1ccc }, + { 0x7d0f, 0x7dff, 16, 1, 7, &z8002_device::Z7D_ssss_1ccc }, + { 0x7e00, 0x7eff, 1, 1, 10, &z8002_device::Z7E_imm8 }, + { 0x7f00, 0x7fff, 1, 1, 33, &z8002_device::Z7F_imm8 }, + { 0x8000, 0x80ff, 1, 1, 4, &z8002_device::Z80_ssss_dddd }, + { 0x8100, 0x81ff, 1, 1, 4, &z8002_device::Z81_ssss_dddd }, + { 0x8200, 0x82ff, 1, 1, 4, &z8002_device::Z82_ssss_dddd }, + { 0x8300, 0x83ff, 1, 1, 4, &z8002_device::Z83_ssss_dddd }, + { 0x8400, 0x84ff, 1, 1, 4, &z8002_device::Z84_ssss_dddd }, + { 0x8500, 0x85ff, 1, 1, 4, &z8002_device::Z85_ssss_dddd }, + { 0x8600, 0x86ff, 1, 1, 4, &z8002_device::Z86_ssss_dddd }, + { 0x8700, 0x87ff, 1, 1, 4, &z8002_device::Z87_ssss_dddd }, + { 0x8800, 0x88ff, 1, 1, 4, &z8002_device::Z88_ssss_dddd }, + { 0x8900, 0x89ff, 1, 1, 4, &z8002_device::Z89_ssss_dddd }, + { 0x8a00, 0x8aff, 1, 1, 4, &z8002_device::Z8A_ssss_dddd }, + { 0x8b00, 0x8bff, 1, 1, 4, &z8002_device::Z8B_ssss_dddd }, + { 0x8c00, 0x8cf0, 16, 1, 7, &z8002_device::Z8C_dddd_0000 }, + { 0x8c02, 0x8cf2, 16, 1, 7, &z8002_device::Z8C_dddd_0010 }, + { 0x8c04, 0x8cf4, 16, 1, 7, &z8002_device::Z8C_dddd_0100 }, + { 0x8c06, 0x8cf6, 16, 1, 7, &z8002_device::Z8C_dddd_0110 }, + { 0x8c01, 0x8cf1, 16, 1, 7, &z8002_device::Z8C_dddd_0001 }, + { 0x8c08, 0x8cf8, 16, 1, 7, &z8002_device::Z8C_dddd_1000 }, + { 0x8c09, 0x8cf9, 16, 1, 7, &z8002_device::Z8C_dddd_1001 }, + { 0x8d00, 0x8df0, 16, 1, 7, &z8002_device::Z8D_dddd_0000 }, + { 0x8d01, 0x8df1, 16, 1, 7, &z8002_device::Z8D_imm4_0001 }, + { 0x8d02, 0x8df2, 16, 1, 7, &z8002_device::Z8D_dddd_0010 }, + { 0x8d03, 0x8df3, 16, 1, 7, &z8002_device::Z8D_imm4_0011 }, + { 0x8d04, 0x8df4, 16, 1, 7, &z8002_device::Z8D_dddd_0100 }, + { 0x8d05, 0x8df5, 16, 1, 7, &z8002_device::Z8D_imm4_0101 }, + { 0x8d06, 0x8df6, 16, 1, 7, &z8002_device::Z8D_dddd_0110 }, + { 0x8d07, 0x8d07, 1, 1, 7, &z8002_device::Z8D_0000_0111 }, + { 0x8d08, 0x8df8, 16, 1, 7, &z8002_device::Z8D_dddd_1000 }, + { 0x8e00, 0x8eff, 1, 1, 10, &z8002_device::Z8E_imm8 }, + { 0x8f00, 0x8fff, 1, 1, 10, &z8002_device::Z8F_imm8 }, + { 0x9000, 0x90ff, 1, 1, 8, &z8002_device::Z90_ssss_dddd }, + { 0x9110, 0x91ff, 1, 1, 12, &z8002_device::Z91_ddN0_ssss }, + { 0x9200, 0x92ff, 1, 1, 8, &z8002_device::Z92_ssss_dddd }, + { 0x9310, 0x93ff, 1, 1, 9, &z8002_device::Z93_ddN0_ssss }, + { 0x9400, 0x94ff, 1, 1, 5, &z8002_device::Z94_ssss_dddd }, + { 0x9510, 0x95ff, 1, 1, 12, &z8002_device::Z95_ssN0_dddd }, + { 0x9600, 0x96ff, 1, 1, 8, &z8002_device::Z96_ssss_dddd }, + { 0x9710, 0x97ff, 1, 1, 8, &z8002_device::Z97_ssN0_dddd }, + { 0x9800, 0x98ff, 1, 1, 282, &z8002_device::Z98_ssss_dddd }, + { 0x9900, 0x99ff, 1, 1, 70, &z8002_device::Z99_ssss_dddd }, + { 0x9a00, 0x9aff, 1, 1, 744, &z8002_device::Z9A_ssss_dddd }, + { 0x9b00, 0x9bff, 1, 1, 107, &z8002_device::Z9B_ssss_dddd }, + { 0x9c00, 0x9cf8, 8, 1, 13, &z8002_device::Z9C_dddd_1000 }, + { 0x9d00, 0x9dff, 1, 1, 10, &z8002_device::Z9D_imm8 }, + { 0x9e00, 0x9e0f, 1, 1, 10, &z8002_device::Z9E_0000_cccc }, + { 0x9f00, 0x9fff, 1, 1, 10, &z8002_device::Z9F_imm8 }, + { 0xa000, 0xa0ff, 1, 1, 3, &z8002_device::ZA0_ssss_dddd }, + { 0xa100, 0xa1ff, 1, 1, 3, &z8002_device::ZA1_ssss_dddd }, + { 0xa200, 0xa2ff, 1, 1, 4, &z8002_device::ZA2_dddd_imm4 }, + { 0xa300, 0xa3ff, 1, 1, 4, &z8002_device::ZA3_dddd_imm4 }, + { 0xa400, 0xa4ff, 1, 1, 4, &z8002_device::ZA4_dddd_imm4 }, + { 0xa500, 0xa5ff, 1, 1, 4, &z8002_device::ZA5_dddd_imm4 }, + { 0xa600, 0xa6ff, 1, 1, 4, &z8002_device::ZA6_dddd_imm4 }, + { 0xa700, 0xa7ff, 1, 1, 4, &z8002_device::ZA7_dddd_imm4 }, + { 0xa800, 0xa8ff, 1, 1, 4, &z8002_device::ZA8_dddd_imm4m1 }, + { 0xa900, 0xa9ff, 1, 1, 4, &z8002_device::ZA9_dddd_imm4m1 }, + { 0xaa00, 0xaaff, 1, 1, 4, &z8002_device::ZAA_dddd_imm4m1 }, + { 0xab00, 0xabff, 1, 1, 4, &z8002_device::ZAB_dddd_imm4m1 }, + { 0xac00, 0xacff, 1, 1, 6, &z8002_device::ZAC_ssss_dddd }, + { 0xad00, 0xadff, 1, 1, 6, &z8002_device::ZAD_ssss_dddd }, + { 0xae00, 0xaeff, 1, 1, 5, &z8002_device::ZAE_dddd_cccc }, + { 0xaf00, 0xafff, 1, 1, 5, &z8002_device::ZAF_dddd_cccc }, + { 0xb000, 0xb0f0, 16, 1, 5, &z8002_device::ZB0_dddd_0000 }, + { 0xb100, 0xb1f0, 16, 1, 11, &z8002_device::ZB1_dddd_0000 }, + { 0xb107, 0xb1f7, 16, 1, 11, &z8002_device::ZB1_dddd_0111 }, + { 0xb10a, 0xb1fa, 16, 1, 11, &z8002_device::ZB1_dddd_1010 }, + { 0xb200, 0xb2f0, 16, 1, 6, &z8002_device::ZB2_dddd_00I0 }, + { 0xb201, 0xb2f1, 16, 2, 13, &z8002_device::ZB2_dddd_0001_imm8 }, + { 0xb202, 0xb2f2, 16, 1, 6, &z8002_device::ZB2_dddd_00I0 }, + { 0xb203, 0xb2f3, 16, 2, 15, &z8002_device::ZB2_dddd_0011_0000_ssss_0000_0000 }, + { 0xb204, 0xb2f4, 16, 1, 6, &z8002_device::ZB2_dddd_01I0 }, + { 0xb206, 0xb2f6, 16, 1, 6, &z8002_device::ZB2_dddd_01I0 }, + { 0xb208, 0xb2f8, 16, 1, 9, &z8002_device::ZB2_dddd_10I0 }, + { 0xb209, 0xb2f9, 16, 2, 13, &z8002_device::ZB2_dddd_1001_imm8 }, + { 0xb20a, 0xb2fa, 16, 1, 9, &z8002_device::ZB2_dddd_10I0 }, + { 0xb20b, 0xb2fb, 16, 2, 15, &z8002_device::ZB2_dddd_1011_0000_ssss_0000_0000 }, + { 0xb20c, 0xb2fc, 16, 1, 9, &z8002_device::ZB2_dddd_11I0 }, + { 0xb20e, 0xb2fe, 16, 1, 9, &z8002_device::ZB2_dddd_11I0 }, + { 0xb300, 0xb3f0, 16, 1, 6, &z8002_device::ZB3_dddd_00I0 }, + { 0xb301, 0xb3f1, 16, 2, 13, &z8002_device::ZB3_dddd_0001_imm8 }, + { 0xb302, 0xb3f2, 16, 1, 6, &z8002_device::ZB3_dddd_00I0 }, + { 0xb303, 0xb3f3, 16, 2, 15, &z8002_device::ZB3_dddd_0011_0000_ssss_0000_0000 }, + { 0xb304, 0xb3f4, 16, 1, 6, &z8002_device::ZB3_dddd_01I0 }, + { 0xb305, 0xb3f5, 16, 2, 13, &z8002_device::ZB3_dddd_0101_imm8 }, + { 0xb306, 0xb3f6, 16, 1, 6, &z8002_device::ZB3_dddd_01I0 }, + { 0xb307, 0xb3f7, 16, 2, 15, &z8002_device::ZB3_dddd_0111_0000_ssss_0000_0000 }, + { 0xb308, 0xb3f8, 16, 1, 6, &z8002_device::ZB3_dddd_10I0 }, + { 0xb309, 0xb3f9, 16, 2, 13, &z8002_device::ZB3_dddd_1001_imm8 }, + { 0xb30a, 0xb3fa, 16, 1, 6, &z8002_device::ZB3_dddd_10I0 }, + { 0xb30b, 0xb3fb, 16, 2, 15, &z8002_device::ZB3_dddd_1011_0000_ssss_0000_0000 }, + { 0xb30c, 0xb3fc, 16, 1, 6, &z8002_device::ZB3_dddd_11I0 }, + { 0xb30d, 0xb3fd, 16, 2, 13, &z8002_device::ZB3_dddd_1101_imm8 }, + { 0xb30e, 0xb3fe, 16, 1, 6, &z8002_device::ZB3_dddd_11I0 }, + { 0xb30f, 0xb3ff, 16, 2, 15, &z8002_device::ZB3_dddd_1111_0000_ssss_0000_0000 }, + { 0xb400, 0xb4ff, 1, 1, 5, &z8002_device::ZB4_ssss_dddd }, + { 0xb500, 0xb5ff, 1, 1, 5, &z8002_device::ZB5_ssss_dddd }, + { 0xb600, 0xb6ff, 1, 1, 5, &z8002_device::ZB6_ssss_dddd }, + { 0xb700, 0xb7ff, 1, 1, 5, &z8002_device::ZB7_ssss_dddd }, + { 0xb810, 0xb8f0, 16, 2, 25, &z8002_device::ZB8_ddN0_0000_0000_rrrr_ssN0_0000 }, + { 0xb812, 0xb8f2, 16, 2, 25, &z8002_device::ZB8_ddN0_0010_0000_rrrr_ssN0_0000 }, + { 0xb814, 0xb8f4, 16, 2, 25, &z8002_device::ZB8_ddN0_0100_0000_rrrr_ssN0_0000 }, + { 0xb816, 0xb8f6, 16, 2, 25, &z8002_device::ZB8_ddN0_0110_0000_rrrr_ssN0_1110 }, + { 0xb818, 0xb8f8, 16, 2, 25, &z8002_device::ZB8_ddN0_1000_0000_rrrr_ssN0_0000 }, + { 0xb81a, 0xb8fa, 16, 2, 25, &z8002_device::ZB8_ddN0_1010_0000_rrrr_ssN0_0000 }, + { 0xb81c, 0xb8fc, 16, 2, 25, &z8002_device::ZB8_ddN0_1100_0000_rrrr_ssN0_0000 }, + { 0xb81e, 0xb8fe, 16, 2, 25, &z8002_device::ZB8_ddN0_1110_0000_rrrr_ssN0_1110 }, + { 0xb900, 0xb9ff, 16, 1, 10, &z8002_device::ZB9_imm8 }, + { 0xba10, 0xbaf0, 16, 2, 11, &z8002_device::ZBA_ssN0_0000_0000_rrrr_dddd_cccc }, + { 0xba11, 0xbaf1, 16, 2, 11, &z8002_device::ZBA_ssN0_0001_0000_rrrr_ddN0_x000 }, + { 0xba12, 0xbaf2, 16, 2, 11, &z8002_device::ZBA_ssN0_0010_0000_rrrr_ddN0_cccc }, + { 0xba14, 0xbaf4, 16, 2, 11, &z8002_device::ZBA_ssN0_0100_0000_rrrr_dddd_cccc }, + { 0xba16, 0xbaf6, 16, 2, 11, &z8002_device::ZBA_ssN0_0110_0000_rrrr_ddN0_cccc }, + { 0xba18, 0xbaf8, 16, 2, 11, &z8002_device::ZBA_ssN0_1000_0000_rrrr_dddd_cccc }, + { 0xba19, 0xbaf9, 16, 2, 11, &z8002_device::ZBA_ssN0_1001_0000_rrrr_ddN0_x000 }, + { 0xba1a, 0xbafa, 16, 2, 11, &z8002_device::ZBA_ssN0_1010_0000_rrrr_ddN0_cccc }, + { 0xba1c, 0xbafc, 16, 2, 11, &z8002_device::ZBA_ssN0_1100_0000_rrrr_dddd_cccc }, + { 0xba1e, 0xbafe, 16, 2, 11, &z8002_device::ZBA_ssN0_1110_0000_rrrr_ddN0_cccc }, + { 0xbb10, 0xbbf0, 16, 2, 11, &z8002_device::ZBB_ssN0_0000_0000_rrrr_dddd_cccc }, + { 0xbb11, 0xbbf1, 16, 2, 11, &z8002_device::ZBB_ssN0_0001_0000_rrrr_ddN0_x000 }, + { 0xbb12, 0xbbf2, 16, 2, 11, &z8002_device::ZBB_ssN0_0010_0000_rrrr_ddN0_cccc }, + { 0xbb14, 0xbbf4, 16, 2, 11, &z8002_device::ZBB_ssN0_0100_0000_rrrr_dddd_cccc }, + { 0xbb16, 0xbbf6, 16, 2, 11, &z8002_device::ZBB_ssN0_0110_0000_rrrr_ddN0_cccc }, + { 0xbb18, 0xbbf8, 16, 2, 11, &z8002_device::ZBB_ssN0_1000_0000_rrrr_dddd_cccc }, + { 0xbb19, 0xbbf9, 16, 2, 11, &z8002_device::ZBB_ssN0_1001_0000_rrrr_ddN0_x000 }, + { 0xbb1a, 0xbbfa, 16, 2, 11, &z8002_device::ZBB_ssN0_1010_0000_rrrr_ddN0_cccc }, + { 0xbb1c, 0xbbfc, 16, 2, 11, &z8002_device::ZBB_ssN0_1100_0000_rrrr_dddd_cccc }, + { 0xbb1e, 0xbbfe, 16, 2, 11, &z8002_device::ZBB_ssN0_1110_0000_rrrr_ddN0_cccc }, + { 0xbc00, 0xbcff, 1, 1, 9, &z8002_device::ZBC_aaaa_bbbb }, + { 0xbd00, 0xbdff, 1, 1, 5, &z8002_device::ZBD_dddd_imm4 }, + { 0xbe00, 0xbeff, 1, 1, 9, &z8002_device::ZBE_aaaa_bbbb }, + { 0xbf00, 0xbfff, 1, 1, 10, &z8002_device::ZBF_imm8 }, + { 0xc000, 0xcfff, 1, 1, 5, &z8002_device::ZC_dddd_imm8 }, + { 0xd000, 0xdfff, 1, 1, 10, &z8002_device::ZD_dsp12 }, + { 0xe000, 0xefff, 1, 1, 6, &z8002_device::ZE_cccc_dsp8 }, + { 0xf000, 0xf07f, 1, 1, 11, &z8002_device::ZF_dddd_0dsp7 }, + { 0xf100, 0xf17f, 1, 1, 11, &z8002_device::ZF_dddd_0dsp7 }, + { 0xf200, 0xf27f, 1, 1, 11, &z8002_device::ZF_dddd_0dsp7 }, + { 0xf300, 0xf37f, 1, 1, 11, &z8002_device::ZF_dddd_0dsp7 }, + { 0xf400, 0xf47f, 1, 1, 11, &z8002_device::ZF_dddd_0dsp7 }, + { 0xf500, 0xf57f, 1, 1, 11, &z8002_device::ZF_dddd_0dsp7 }, + { 0xf600, 0xf67f, 1, 1, 11, &z8002_device::ZF_dddd_0dsp7 }, + { 0xf700, 0xf77f, 1, 1, 11, &z8002_device::ZF_dddd_0dsp7 }, + { 0xf800, 0xf87f, 1, 1, 11, &z8002_device::ZF_dddd_0dsp7 }, + { 0xf900, 0xf97f, 1, 1, 11, &z8002_device::ZF_dddd_0dsp7 }, + { 0xfa00, 0xfa7f, 1, 1, 11, &z8002_device::ZF_dddd_0dsp7 }, + { 0xfb00, 0xfb7f, 1, 1, 11, &z8002_device::ZF_dddd_0dsp7 }, + { 0xfc00, 0xfc7f, 1, 1, 11, &z8002_device::ZF_dddd_0dsp7 }, + { 0xfd00, 0xfd7f, 1, 1, 11, &z8002_device::ZF_dddd_0dsp7 }, + { 0xfe00, 0xfe7f, 1, 1, 11, &z8002_device::ZF_dddd_0dsp7 }, + { 0xff00, 0xff7f, 1, 1, 11, &z8002_device::ZF_dddd_0dsp7 }, + { 0xf080, 0xf0ff, 1, 1, 11, &z8002_device::ZF_dddd_1dsp7 }, + { 0xf180, 0xf1ff, 1, 1, 11, &z8002_device::ZF_dddd_1dsp7 }, + { 0xf280, 0xf2ff, 1, 1, 11, &z8002_device::ZF_dddd_1dsp7 }, + { 0xf380, 0xf3ff, 1, 1, 11, &z8002_device::ZF_dddd_1dsp7 }, + { 0xf480, 0xf4ff, 1, 1, 11, &z8002_device::ZF_dddd_1dsp7 }, + { 0xf580, 0xf5ff, 1, 1, 11, &z8002_device::ZF_dddd_1dsp7 }, + { 0xf680, 0xf6ff, 1, 1, 11, &z8002_device::ZF_dddd_1dsp7 }, + { 0xf780, 0xf7ff, 1, 1, 11, &z8002_device::ZF_dddd_1dsp7 }, + { 0xf880, 0xf8ff, 1, 1, 11, &z8002_device::ZF_dddd_1dsp7 }, + { 0xf980, 0xf9ff, 1, 1, 11, &z8002_device::ZF_dddd_1dsp7 }, + { 0xfa80, 0xfaff, 1, 1, 11, &z8002_device::ZF_dddd_1dsp7 }, + { 0xfb80, 0xfbff, 1, 1, 11, &z8002_device::ZF_dddd_1dsp7 }, + { 0xfc80, 0xfcff, 1, 1, 11, &z8002_device::ZF_dddd_1dsp7 }, + { 0xfd80, 0xfdff, 1, 1, 11, &z8002_device::ZF_dddd_1dsp7 }, + { 0xfe80, 0xfeff, 1, 1, 11, &z8002_device::ZF_dddd_1dsp7 }, + { 0xff80, 0xffff, 1, 1, 11, &z8002_device::ZF_dddd_1dsp7 }, + { 0, 0, 0, 0, 0, nullptr }, +}; |