diff options
Diffstat (limited to 'src/devices/cpu/mcs96')
-rw-r--r-- | src/devices/cpu/mcs96/i8x9x.cpp | 23 | ||||
-rw-r--r-- | src/devices/cpu/mcs96/i8x9x.h | 3 | ||||
-rw-r--r-- | src/devices/cpu/mcs96/i8x9xd.cpp | 19 | ||||
-rw-r--r-- | src/devices/cpu/mcs96/i8x9xd.h | 26 | ||||
-rw-r--r-- | src/devices/cpu/mcs96/i8xc196.cpp | 5 | ||||
-rw-r--r-- | src/devices/cpu/mcs96/i8xc196.h | 3 | ||||
-rw-r--r-- | src/devices/cpu/mcs96/i8xc196d.cpp | 18 | ||||
-rw-r--r-- | src/devices/cpu/mcs96/i8xc196d.h | 26 | ||||
-rw-r--r-- | src/devices/cpu/mcs96/mcs96.cpp | 272 | ||||
-rw-r--r-- | src/devices/cpu/mcs96/mcs96.h | 40 | ||||
-rw-r--r-- | src/devices/cpu/mcs96/mcs96d.cpp | 278 | ||||
-rw-r--r-- | src/devices/cpu/mcs96/mcs96d.h | 64 | ||||
-rw-r--r-- | src/devices/cpu/mcs96/mcs96make.py | 25 |
13 files changed, 463 insertions, 339 deletions
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() |