diff --git a/src/devices/cpu/upd78k/upd78k3d.cpp b/src/devices/cpu/upd78k/upd78k3d.cpp index 87cfb6bf4c8..0adfd848cfd 100644 --- a/src/devices/cpu/upd78k/upd78k3d.cpp +++ b/src/devices/cpu/upd78k/upd78k3d.cpp @@ -5,7 +5,7 @@ #include "upd78k3d.h" upd78k3_disassembler::upd78k3_disassembler(const char *const sfr_names[], const char *const sfrp_names[], const char *const psw_bits[], bool has_macw, bool has_macsw) - : upd78k_family_disassembler(sfr_names, sfrp_names) + : upd78k_family_disassembler(sfr_names, sfrp_names, 0xfe00) , m_ix_bases(s_ix_bases) , m_psw_bits(psw_bits) , m_has_macw(has_macw) @@ -13,8 +13,8 @@ upd78k3_disassembler::upd78k3_disassembler(const char *const sfr_names[], const { } -upd78k3_disassembler::upd78k3_disassembler(const char *const sfr_names[], const char *const sfrp_names[], const char *const ix_bases[]) - : upd78k_family_disassembler(sfr_names, sfrp_names) +upd78k3_disassembler::upd78k3_disassembler(const char *const sfr_names[], const char *const sfrp_names[], const char *const ix_bases[], u16 saddr_ram_base) + : upd78k_family_disassembler(sfr_names, sfrp_names, saddr_ram_base) , m_ix_bases(ix_bases) , m_psw_bits(s_psw_bits) , m_has_macw(true) @@ -552,9 +552,9 @@ offs_t upd78k3_disassembler::dasm_16xx(std::ostream &stream, u8 op1, u8 op2) stream << "A,"; stream << "["; - if (BIT(op1, 0) && BIT(op2, 6)) - util::stream_format(stream, "%s+", m_ix_bases[4]); - if ((op2 & 0x60) == 0x60) + if (BIT(op1, 0) && (op2 & 0x60) == 0x40) + util::stream_format(stream, "%s+%s", m_ix_bases[4], BIT(op2, 4) ? "HL" : "DE"); + else if ((op2 & 0x60) == 0x60) stream << m_ix_bases[BIT(op2, 4) ? 3 : 4]; else { diff --git a/src/devices/cpu/upd78k/upd78k3d.h b/src/devices/cpu/upd78k/upd78k3d.h index 09853502e80..f9fd0442c1e 100644 --- a/src/devices/cpu/upd78k/upd78k3d.h +++ b/src/devices/cpu/upd78k/upd78k3d.h @@ -12,7 +12,7 @@ class upd78k3_disassembler : public upd78k_family_disassembler { protected: upd78k3_disassembler(const char *const sfr_names[], const char *const sfrp_names[], const char *const psw_bits[], bool has_macw, bool has_macsw); - upd78k3_disassembler(const char *const sfr_names[], const char *const sfrp_names[], const char *const ix_bases[]); + upd78k3_disassembler(const char *const sfr_names[], const char *const sfrp_names[], const char *const ix_bases[], u16 saddr_ram_base); // register and mnemonic tables static const char *const s_r_names[16]; diff --git a/src/devices/cpu/upd78k/upd78k4.cpp b/src/devices/cpu/upd78k/upd78k4.cpp new file mode 100644 index 00000000000..242442746f1 --- /dev/null +++ b/src/devices/cpu/upd78k/upd78k4.cpp @@ -0,0 +1,275 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/**************************************************************************** + + NEC 78K/IV series 16/8-bit single-chip microcontrollers + + Currently these devices are just stubs with no actual execution core. + +****************************************************************************/ + +#include "emu.h" +#include "upd78k4.h" +#include "upd78k4d.h" + +// device type definition +DEFINE_DEVICE_TYPE(UPD784031, upd784031_device, "upd784031", "NEC uPD784031") + +//************************************************************************** +// 78K/IV CORE +//************************************************************************** + +//------------------------------------------------- +// upd78k4_device - constructor +//------------------------------------------------- + +upd78k4_device::upd78k4_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, address_map_constructor mem_map, address_map_constructor sfr_map) + : cpu_device(mconfig, type, tag, owner, clock) + , m_program_config("program", ENDIANNESS_LITTLE, 8, 20, 0, mem_map) + , m_iram_config("iram", ENDIANNESS_LITTLE, 16, 9, 0, address_map_constructor(FUNC(upd78k4_device::iram_map), this)) + , m_sfr_config("sfr", ENDIANNESS_LITTLE, 16, 8, 0, sfr_map) + , m_iram(*this, "iram") + , m_pc(0) + , m_ppc(0) + , m_psw(0) + , m_sp(0) + , m_exp_reg{0, 0, 0, 0} + , m_icount(0) +{ +} + + +//------------------------------------------------- +// iram_map - type-universal IRAM map +//------------------------------------------------- + +void upd78k4_device::iram_map(address_map &map) +{ + map(0x000, 0x1ff).ram().share("iram"); +} + + +//------------------------------------------------- +// memory_space_config - return a vector of +// address space configurations for this device +//------------------------------------------------- + +device_memory_interface::space_config_vector upd78k4_device::memory_space_config() const +{ + return space_config_vector { + std::make_pair(AS_PROGRAM, &m_program_config), + std::make_pair(AS_DATA, &m_iram_config), + std::make_pair(AS_IO, &m_sfr_config) + }; +} + + +//------------------------------------------------- +// register_base - determine current base of +// register file in IRAM +//------------------------------------------------- + +inline u16 upd78k4_device::register_base() const noexcept +{ + return 0x180 | (~m_psw & 0x7000) >> 8; +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void upd78k4_device::device_start() +{ + // get address spaces and access caches + space(AS_PROGRAM).specific(m_program_space); + space(AS_PROGRAM).cache(m_program_cache); + space(AS_DATA).cache(m_iram_cache); + space(AS_IO).specific(m_sfr_space); + + set_icountptr(m_icount); + + // debug state + state_add(UPD78K4_PC, "PC", m_pc).mask(0xfffff); + state_add(STATE_GENPC, "GENPC", m_pc).mask(0xfffff).noshow(); + state_add(STATE_GENPCBASE, "GENPCBASE", m_ppc).mask(0xfffff).noshow(); + state_add(UPD78K4_PSW, "PSW", m_psw).mask(0xf0fd); + state_add(STATE_GENFLAGS, "FLAGS", m_psw).mask(0xf0fd).formatstr("%12s").noshow(); + state_add(UPD78K4_PSWL, "PSWL", + [this]() { return m_psw & 0x00ff; }, + [this](u8 data) { m_psw = (m_psw & 0xff00) | data; } + ).mask(0xfd).noshow(); + state_add(UPD78K4_PSWH, "PSWH", + [this]() { return (m_psw & 0xff00) >> 8; }, + [this](u8 data) { m_psw = (m_psw & 0x00ff) | u16(data) << 8; } + ).mask(0xf0).noshow(); + state_add(UPD78K4_RBS, "RBS", + [this]() { return BIT(m_psw, 12, 3); }, + [this](u8 data) { m_psw = (m_psw & 0x8fff) | u16(data) << 12; } + ).mask(7).noshow(); + state_add(UPD78K4_SP, "SP", m_sp).mask(0xffffff); + for (int n = 0; n < 4; n++) + state_add(UPD78K4_RP0 + n, string_format("RP%d", n).c_str(), + [this, n]() { return m_iram[register_base() >> 1 | n]; }, + [this, n](u16 data) { m_iram[register_base() >> 1 | n] = data; } + ).formatstr("%9s"); + for (int n = 0; n < 2; n++) + state_add(UPD78K4_AX + n, std::array{{"AX", "BC"}}[n], + [this, n]() { return m_iram[register_base() >> 1 | (m_psw & 0x0020) >> 4 | n]; }, + [this, n](u16 data) { m_iram[register_base() >> 1 | (m_psw & 0x0020) >> 4 | n] = data; } + ).noshow(); + for (int n = 0; n < 4; n++) + { + const char *rgname = std::array{{"VVP", "UUP", "TDE", "WHL"}}[n]; + state_add(UPD78K4_VVP + n, rgname, + [this, n]() { return u32(m_exp_reg[n]) << 16 | m_iram[register_base() >> 1 | 0x04 | n]; }, + [this, n](u32 data) { m_exp_reg[n] = data >> 16; m_iram[register_base() >> 1 | 0x04 | n] = data & 0xffff; } + ).mask(0xffffff); + state_add(UPD78K4_VP + n, rgname + 1, + [this, n]() { return m_iram[register_base() >> 1 | 0x04 | n]; }, + [this, n](u16 data) { m_iram[register_base() >> 1 | 0x04 | n] = data; } + ).noshow(); + state_add(UPD78K4_RP4 + n, string_format("RP%d", 4 + n).c_str(), + [this, n]() { return m_iram[register_base() >> 1 | 0x04 | n]; }, + [this, n](u16 data) { m_iram[register_base() >> 1 | 0x04 | n] = data; } + ).noshow(); + state_add(UPD78K4_V + n, std::array{{"V", "U", "T", "W"}}[n], m_exp_reg[n]).noshow(); + } + for (int n = 0; n < 16; n++) + state_add(UPD78K4_R0 + n, string_format("R%d", n).c_str(), + [this, n]() { return reinterpret_cast(&m_iram[0])[BYTE_XOR_LE(register_base() | n)]; }, + [this, n](u8 data) { reinterpret_cast(&m_iram[0])[BYTE_XOR_LE(register_base() | n)] = data; } + ).noshow(); + for (int n = 0; n < 4; n++) + state_add(UPD78K4_X + n, std::array{{"X", "A", "C", "B"}}[n], + [this, n]() { return reinterpret_cast(&m_iram[0])[BYTE_XOR_LE(register_base() | (m_psw & 0x0020) >> 3 | n)]; }, + [this, n](u8 data) { reinterpret_cast(&m_iram[0])[BYTE_XOR_LE(register_base() | (m_psw & 0x0020) >> 3 | n)] = data; } + ).noshow(); + for (int n = 0; n < 8; n++) + state_add(UPD78K4_VPL + n, std::array{{"VPL", "VPH", "UPL", "UPH", "E", "D", "L", "H"}}[n], + [this, n]() { return reinterpret_cast(&m_iram[0])[BYTE_XOR_LE(register_base() | 0x08 | n)]; }, + [this, n](u8 data) { reinterpret_cast(&m_iram[0])[BYTE_XOR_LE(register_base() | 0x08 | n)] = data; } + ).noshow(); + + // save state + save_item(NAME(m_pc)); + save_item(NAME(m_ppc)); + save_item(NAME(m_sp)); + save_item(NAME(m_exp_reg)); + save_item(NAME(m_psw)); +} + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void upd78k4_device::device_reset() +{ + // PC will be initialized from vector following reset + m_psw = 0x0000; +} + + +//------------------------------------------------- +// execute_run - +//------------------------------------------------- + +void upd78k4_device::execute_run() +{ + m_pc = m_program_cache.read_word(0); + m_ppc = m_pc; + debugger_instruction_hook(m_pc); + + // TODO + m_icount = 0; +} + + +//------------------------------------------------- +// state_string_export - +//------------------------------------------------- + +void upd78k4_device::state_string_export(const device_state_entry &entry, std::string &str) const +{ + switch (entry.index()) + { + case STATE_GENFLAGS: + str = string_format("%c RB%d:%c%c%c%c%c%c0%c", + BIT(m_psw, 15) ? 'U' : '.', + (m_psw & 0x7000) >> 12, + BIT(m_psw, 7) ? 'S' : '.', + BIT(m_psw, 6) ? 'Z' : '.', + BIT(m_psw, 5) ? 'R' : '.', + BIT(m_psw, 4) ? 'A' : '.', + BIT(m_psw, 3) ? 'I' : '.', + BIT(m_psw, 2) ? 'V' : '.', + BIT(m_psw, 0) ? 'C' : '.'); + break; + + case UPD78K4_RP0: + str = string_format("%04X %s", m_iram[register_base() >> 1], BIT(m_psw, 5) ? " " : "(AX)"); + break; + + case UPD78K4_RP1: + str = string_format("%04X %s", m_iram[register_base() >> 1 | 1], BIT(m_psw, 5) ? " " : "(BC)"); + break; + + case UPD78K4_RP2: + str = string_format("%04X %s", m_iram[register_base() >> 1 | 2], BIT(m_psw, 5) ? "(AX)" : " "); + break; + + case UPD78K4_RP3: + str = string_format("%04X %s", m_iram[register_base() >> 1 | 3], BIT(m_psw, 5) ? "(BC)" : " "); + break; + } +} + + +//************************************************************************** +// 78K/IV SUBSERIES DEVICES +//************************************************************************** + +//------------------------------------------------- +// upd784031_device - constructor +//------------------------------------------------- + +upd784031_device::upd784031_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : upd78k4_device(mconfig, UPD784031, tag, owner, clock, + address_map_constructor(FUNC(upd784031_device::sfr_map), this), + address_map_constructor(FUNC(upd784031_device::sfr_map), this)) +{ +} + + +//------------------------------------------------- +// create_disassembler - +//------------------------------------------------- + +std::unique_ptr upd784031_device::create_disassembler() +{ + return std::make_unique(); +} + + +//------------------------------------------------- +// mem_map - type-specific internal memory map +// (excluding IRAM and SFRs) +//------------------------------------------------- + +void upd784031_device::mem_map(address_map &map) +{ + // no ROM + //map(0x0f700, 0x0fcff).ram(); // PRAM (TODO: LOCATION 0H) + map(0xff700, 0xffcff).ram(); // PRAM (LOCATION 0FH) +} + + +//------------------------------------------------- +// sfr_map - type-specific SFR map +//------------------------------------------------- + +void upd784031_device::sfr_map(address_map &map) +{ + // TODO +} diff --git a/src/devices/cpu/upd78k/upd78k4.h b/src/devices/cpu/upd78k/upd78k4.h new file mode 100644 index 00000000000..435600b563c --- /dev/null +++ b/src/devices/cpu/upd78k/upd78k4.h @@ -0,0 +1,110 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/********************************************************************** + + NEC 78K/IV series 16/8-bit single-chip microcontrollers + +**********************************************************************/ + +#ifndef MAME_CPU_UPD78K_UPD78K4_H +#define MAME_CPU_UPD78K_UPD78K4_H + +#pragma once + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> upd78k4_device + +class upd78k4_device : public cpu_device +{ +public: + enum { + UPD78K4_PC, + UPD78K4_PSW, UPD78K4_PSWL, UPD78K4_PSWH, UPD78K4_RBS, UPD78K4_SP, + UPD78K4_VVP, UPD78K4_UUP, UPD78K4_TDE, UPD78K4_WHL, + UPD78K4_RP0, UPD78K4_RP1, UPD78K4_RP2, UPD78K4_RP3, + UPD78K4_RP4, UPD78K4_RP5, UPD78K4_RP6, UPD78K4_RP7, + UPD78K4_AX, UPD78K4_BC, + UPD78K4_VP, UPD78K4_UP, UPD78K4_DE, UPD78K4_HL, + UPD78K4_R0, UPD78K4_R1, UPD78K4_R2, UPD78K4_R3, + UPD78K4_R4, UPD78K4_R5, UPD78K4_R6, UPD78K4_R7, + UPD78K4_R8, UPD78K4_R9, UPD78K4_R10, UPD78K4_R11, + UPD78K4_R12, UPD78K4_R13, UPD78K4_R14, UPD78K4_R15, + UPD78K4_X, UPD78K4_A, UPD78K4_C, UPD78K4_B, + UPD78K4_VPL, UPD78K4_VPH, UPD78K4_UPL, UPD78K4_UPH, + UPD78K4_E, UPD78K4_D, UPD78K4_L, UPD78K4_H, + UPD78K4_V, UPD78K4_U, UPD78K4_T, UPD78K4_W + }; + + // TODO: callbacks and configuration thereof + +protected: + upd78k4_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, address_map_constructor mem_map, address_map_constructor sfr_map); + + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + // device_execute_interface overrides + virtual void execute_run() override; + virtual u64 execute_clocks_to_cycles(u64 clocks) const noexcept override { return (clocks + 2 - 1) / 2; } + virtual u64 execute_cycles_to_clocks(u64 cycles) const noexcept override { return (cycles * 2); } + + // 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; + +private: + // internal memory map + void iram_map(address_map &map); + + // internal helpers + inline u16 register_base() const noexcept; + +private: + // address spaces, caches & configuration + address_space_config m_program_config; + address_space_config m_iram_config; + address_space_config m_sfr_config; + required_shared_ptr m_iram; + + memory_access<20, 0, 0, ENDIANNESS_LITTLE>::cache m_program_cache; + memory_access< 9, 1, 0, ENDIANNESS_LITTLE>::cache m_iram_cache; + memory_access<20, 0, 0, ENDIANNESS_LITTLE>::specific m_program_space; + memory_access< 8, 1, 0, ENDIANNESS_LITTLE>::specific m_sfr_space; + + // core registers and execution state + u32 m_pc; + u32 m_ppc; + u16 m_psw; + u32 m_sp; + u8 m_exp_reg[4]; + s32 m_icount; +}; + +// ======================> upd784031_device + +class upd784031_device : public upd78k4_device +{ +public: + // device type constructor + upd784031_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + +protected: + // device_disasm_interface overrides + virtual std::unique_ptr create_disassembler() override; + +private: + // type-specific internal memory maps + void mem_map(address_map &map); + void sfr_map(address_map &map); +}; + +// device type declaration +DECLARE_DEVICE_TYPE(UPD784031, upd784031_device) + +#endif // MAME_CPU_UPD78K_UPD78K4_H diff --git a/src/devices/cpu/upd78k/upd78k4d.cpp b/src/devices/cpu/upd78k/upd78k4d.cpp new file mode 100644 index 00000000000..7a45cfefadb --- /dev/null +++ b/src/devices/cpu/upd78k/upd78k4d.cpp @@ -0,0 +1,1408 @@ +// license:BSD-3-Clause +// copyright-holders:AJR + +#include "emu.h" +#include "upd78k4d.h" + +upd78k4_disassembler::upd78k4_disassembler(const char *const sfr_names[], const char *const sfrp_names[]) + : upd78k3_disassembler(sfr_names, sfrp_names, s_ix_bases, 0xfd00) +{ +} + +const char *const upd78k4_disassembler::s_ix_bases[5] = +{ + "TDE", + "SP", + "WHL", + "UUP", + "VVP" +}; + +const char *const upd78k4_disassembler::s_imm24_offsets[4] = +{ + "DE", + "A", + "HL", + "B" +}; + +const char *const upd78k4_disassembler::s_rg_names[4] = +{ + "VVP", // RG4 + "UUP", // RG5 + "TDE", // RG6 + "WHL" // RG7 +}; + + +void upd78k4_disassembler::format_imm24(std::ostream &stream, u32 d) +{ + if (d < 0xa00000) + util::stream_format(stream, "#%06XH", d); + else + util::stream_format(stream, "#0%06XH", d); +} + +void upd78k4_disassembler::format_abs20(std::ostream &stream, u32 addr) +{ + if (addr < 0xa0000) + util::stream_format(stream, "!!%05XH", addr); + else + util::stream_format(stream, "!!0%05XH", addr); +} + +void upd78k4_disassembler::format_abs24(std::ostream &stream, u32 addr) +{ + if (addr < 0xa00000) + util::stream_format(stream, "!!%06XH", addr); + else + util::stream_format(stream, "!!0%06XH", addr); +} + +void upd78k4_disassembler::format_saddr1(std::ostream &stream, u8 addr) +{ + util::stream_format(stream, "0%04XH", 0xfe00 + addr); +} + +void upd78k4_disassembler::format_saddrp1(std::ostream &stream, u8 addr) +{ + util::stream_format(stream, "0%04XH", 0xfe00 + addr); +} + +void upd78k4_disassembler::format_saddrg1(std::ostream &stream, u8 addr) +{ + util::stream_format(stream, "0%04XH", 0xfe00 + addr); +} + +void upd78k4_disassembler::format_saddrg2(std::ostream &stream, u8 addr) +{ + util::stream_format(stream, "0%04XH", (addr < 0x20 ? 0xff00 : 0xfd00) + addr); +} + +void upd78k4_disassembler::format_jdisp8(std::ostream &stream, offs_t pc, u8 disp) +{ + u32 addr = (pc + s8(disp)) & 0xfffff; + if (addr < 0xa0000) + util::stream_format(stream, "$%05XH", addr); + else + util::stream_format(stream, "$0%05XH", addr); +} + +void upd78k4_disassembler::format_jdisp16(std::ostream &stream, offs_t pc, u16 disp) +{ + u32 addr = (pc + s16(disp)) & 0xfffff; + if (addr < 0xa0000) + util::stream_format(stream, "$!%05XH", addr); + else + util::stream_format(stream, "$!0%05XH", addr); +} + + +offs_t upd78k4_disassembler::dasm_05xx(std::ostream &stream, u8 op2) +{ + if ((op2 & 0xc9) == 0x41) + { + util::stream_format(stream, "%-8s", BIT(op2, 4) ? "CALL" : "BR"); + if (BIT(op2, 5)) + util::stream_format(stream, "[%s]", s_rg_names[BIT(op2, 1, 2)]); + else + stream << s_rg_names[BIT(op2, 1, 2)]; + return 2 | (BIT(op2, 4) ? STEP_OVER : 0) | SUPPORTED; + } + else if ((op2 & 0xf1) == 0xc1) + { + util::stream_format(stream, "%-8s", "MOV"); + if (!BIT(op2, 3)) + stream << "A,"; + stream << s_rg_names[BIT(op2, 1, 2)][0]; + if (BIT(op2, 3)) + stream << ",A"; + return 2 | SUPPORTED; + } + else if ((op2 & 0xfe) == 0xf8) + { + util::stream_format(stream, "%-8sSP", BIT(op2, 0) ? "DECG" : "INCG"); + return 2 | SUPPORTED; + } + else if ((op2 & 0xfe) == 0xfa) + { + util::stream_format(stream, "%-8s%s", "MOVG", BIT(op2, 0) ? "WHL,SP" : "SP,WHL"); + return 2 | SUPPORTED; + } + else if (op2 == 0xfc) + { + stream << "SWRS"; + return 2 | SUPPORTED; + } + else + return upd78k3_disassembler::dasm_05xx(stream, op2); +} + +offs_t upd78k4_disassembler::dasm_06xx(std::ostream &stream, u8 op2, offs_t pc, const upd78k4_disassembler::data_buffer &opcodes) +{ + if ((op2 & 0x70) < 0x50 && (op2 & 0x0f) == 0x02) + { + util::stream_format(stream, "%-8s", "MOVG"); + if (!BIT(op2, 7)) + stream << "WHL,"; + if (BIT(op2, 7)) + stream << ",WHL"; + format_ix_disp8(stream, s_ix_bases[(op2 & 0x70) >> 4], opcodes.r8(pc + 2)); + return 3 | SUPPORTED; + } + else + return upd78k3_disassembler::dasm_06xx(stream, op2, pc, opcodes); +} + +offs_t upd78k4_disassembler::dasm_07xx(std::ostream &stream, u8 op2, offs_t pc, const upd78k4_disassembler::data_buffer &opcodes) +{ + if ((op2 & 0x68) == 0x28 || ((op2 & 0x7b) == 0x30 && op2 != 0xb4)) + { + util::stream_format(stream, "%-8s", s_alu_ops[op2 & 0x07]); + if (!BIT(op2, 7)) + stream << "A,"; + stream << "["; + if (BIT(op2, 4)) + { + stream << "%"; + format_saddrg2(stream, opcodes.r8(pc + 2)); + } + else + format_saddrp(stream, opcodes.r8(pc + 2)); + stream << "]"; + if (BIT(op2, 7)) + stream << ",A"; + return 3 | SUPPORTED; + } + else if ((op2 & 0x6b) == 0x21 && (op2 & 0x84) != 0x84) + { + util::stream_format(stream, "%-8s", BIT(op2, 2) ? "XCHW" : "MOVW"); + if (!BIT(op2, 7)) + stream << "AX,"; + stream << "["; + if (BIT(op2, 4)) + { + stream << "%"; + format_saddrg2(stream, opcodes.r8(pc + 2)); + } + else + format_saddrp(stream, opcodes.r8(pc + 2)); + stream << "]"; + if (BIT(op2, 7)) + stream << ",AX"; + return 3 | SUPPORTED; + } + else if ((op2 & 0x7f) == 0x32) + { + util::stream_format(stream, "%-8s", "MOVG"); + if (!BIT(op2, 7)) + stream << "WHL,"; + stream << "[%"; + format_saddrg2(stream, opcodes.r8(pc + 2)); + stream << "]"; + if (BIT(op2, 7)) + stream << ",WHL"; + return 3 | SUPPORTED; + } + else if ((op2 & 0xf9) == 0x61) + { + util::stream_format(stream, "%-8s%c,", "MOV", s_rg_names[BIT(op2, 1, 2)][0]); + format_imm8(stream, opcodes.r8(pc + 2)); + return 3 | SUPPORTED; + } + else if ((op2 & 0xfe) == 0xda) + { + util::stream_format(stream, "%-8s", BIT(op2, 0) ? "PUSH" : "POP"); + format_sfr(stream, opcodes.r8(pc + 2)); + return 3 | SUPPORTED; + } + else if (op2 == 0x95) + { + util::stream_format(stream, "%-8s", "MACSW"); + format_count(stream, opcodes.r8(pc + 2)); + return 3 | SUPPORTED; + } + else + return upd78k3_disassembler::dasm_07xx(stream, op2, pc, opcodes); +} + +offs_t upd78k4_disassembler::dasm_09xx(std::ostream &stream, u8 op2, offs_t pc, const upd78k4_disassembler::data_buffer &opcodes) +{ + if (op2 == 0x20) + { + util::stream_format(stream, "%-8sSP,", "MOVG"); + format_imm24(stream, u32(opcodes.r8(pc + 4)) << 16 | opcodes.r16(pc + 2)); + return 5 | SUPPORTED; + } + else if ((op2 & 0xfe) == 0x28) + { + util::stream_format(stream, "%-8sSP,", BIT(op2, 0) ? "SUBWG" : "ADDWG"); + format_imm16(stream, opcodes.r16(pc + 2)); + return 4 | SUPPORTED; + } + else if ((op2 & 0xee) == 0x40) + { + util::stream_format(stream, "%-8s", BIT(op2, 0) ? "MOVW" : "MOV"); + if (BIT(op2, 4)) + { + format_abs24(stream, u32(opcodes.r8(pc + 2)) << 16 | opcodes.r16(pc + 3)); + stream << ","; + if (BIT(op2, 0)) + { + format_imm16(stream, opcodes.r16(pc + 5)); + return 7 | SUPPORTED; + } + else + { + format_imm8(stream, opcodes.r8(pc + 5)); + return 6 | SUPPORTED; + } + } + else + { + format_abs16(stream, opcodes.r16(pc + 2)); + stream << ","; + if (BIT(op2, 0)) + { + format_imm16(stream, opcodes.r16(pc + 4)); + return 6 | SUPPORTED; + } + else + { + format_imm8(stream, opcodes.r8(pc + 4)); + return 5 | SUPPORTED; + } + } + } + else if (op2 == 0x64) + { + util::stream_format(stream, "%-8s", "SACW"); + u8 post1 = opcodes.r8(pc + 2); + u8 post2 = opcodes.r8(pc + 3); + if (post1 == 0x41 && post2 == 0x46) + util::stream_format(stream, "[%s+],[%s+]", s_ix_bases[0], s_ix_bases[2]); + else + stream << "invalid"; + return 4 | SUPPORTED; + } + else if ((op2 & 0xe9) == 0x89) + { + util::stream_format(stream, "%-8s%s", BIT(op2, 4) ? "POP" : "PUSH", s_rg_names[BIT(op2, 1, 2)]); + return 2 | SUPPORTED; + } + else if (op2 == 0xb0) + { + util::stream_format(stream, "%-8s", "RETCSB"); + format_abs16(stream, opcodes.r16(pc + 2)); + return 4 | SUPPORTED; + } + else if (op2 == 0xc1) + { + util::stream_format(stream, "%-8s ", "LOCATION"); + u16 w = opcodes.r16(pc + 2); + if (w == 0x01fe) + stream << "0H"; + else if (w == 0x00ff) + stream << "0FH"; + else + stream << "invalid"; + return 4 | SUPPORTED; + } + else if (op2 == 0xd0) + { + u8 op3 = opcodes.r8(pc + 2); + if ((op3 & 0xf0) == 0x10) + { + util::stream_format(stream, "%-8s", "MOV1"); + if (BIT(op3, 3)) + format_abs24(stream, u32(opcodes.r8(pc + 3)) << 16 | opcodes.r16(pc + 4)); + else + format_abs16(stream, opcodes.r16(pc + 3)); + util::stream_format(stream, ".%d,CY", op3 & 0x07); + return (BIT(op3, 3) ? 6 : 5) | SUPPORTED; + } + else if (op3 < 0x70) + { + util::stream_format(stream, "%-8sCY,", s_bool_ops[BIT(op3, 5, 2)]); + if (BIT(op3, 4)) + stream << "/"; + if (BIT(op3, 3)) + format_abs24(stream, u32(opcodes.r8(pc + 3)) << 16 | opcodes.r16(pc + 4)); + else + format_abs16(stream, opcodes.r16(pc + 3)); + util::stream_format(stream, ".%d", op3 & 0x07); + return (BIT(op3, 3) ? 6 : 5) | SUPPORTED; + } + else if (op3 < 0xa0) + { + util::stream_format(stream, "%-8s", op3 < 0x80 ? "NOT1" : BIT(op3, 4) ? "CLR1" : "SET1"); + if (BIT(op3, 3)) + format_abs24(stream, u32(opcodes.r8(pc + 3)) << 16 | opcodes.r16(pc + 4)); + else + format_abs16(stream, opcodes.r16(pc + 3)); + util::stream_format(stream, ".%d", op3 & 0x07); + return (BIT(op3, 3) ? 6 : 5) | SUPPORTED; + } + else if (op3 < 0xe0) + { + if (BIT(op3, 6)) + util::stream_format(stream, "%-8s", BIT(op3, 4) ? "BTCLR" : "BFSET"); + else + util::stream_format(stream, "%-8s", BIT(op3, 4) ? "BT" : "BF"); + if (BIT(op3, 3)) + { + format_abs24(stream, u32(opcodes.r8(pc + 3)) << 16 | opcodes.r16(pc + 4)); + util::stream_format(stream, ".%d,", op3 & 0x07); + format_jdisp8(stream, pc + 7, opcodes.r8(pc + 6)); + return 7 | SUPPORTED; + } + else + { + format_abs16(stream, opcodes.r16(pc + 3)); + util::stream_format(stream, ".%d,", op3 & 0x07); + format_jdisp8(stream, pc + 6, opcodes.r8(pc + 5)); + return 6 | SUPPORTED; + } + } + else + return dasm_illegal3(stream, 0x09, 0xd0, op3); + } + else if (op2 >= 0xe0) + { + util::stream_format(stream, "%-8s", op2 >= 0xf0 ? "CALL" : "BR"); + format_abs20(stream, u32(op2 & 0x0f) << 16 | opcodes.r16(pc + 2)); + return 4 | (op2 >= 0xf0 ? STEP_OVER : 0) | SUPPORTED; + } + else + return upd78k3_disassembler::dasm_09xx(stream, op2, pc, opcodes); +} + +offs_t upd78k4_disassembler::dasm_0axx(std::ostream &stream, u8 op2, offs_t pc, const upd78k4_disassembler::data_buffer &opcodes) +{ + if (!BIT(op2, 6) && (BIT(op2, 3) || (op2 & (BIT(op2, 7) ? 0x06 : 0x02)) == 0x00 || (op2 & 0x0f) == 0x02)) + { + if (BIT(op2, 3)) + util::stream_format(stream, "%-8s", s_alu_ops[op2 & 0x07]); + else if ((op2 & 0x0f) == 0x02) + util::stream_format(stream, "%-8s", "MOVG"); + else if (BIT(op2, 0)) + util::stream_format(stream, "%-8s", BIT(op2, 2) ? "XCHW" : "MOVW"); + else + util::stream_format(stream, "%-8s", BIT(op2, 2) ? "XCH" : "MOV"); + if ((op2 & 0x8b) == 0x01) + stream << "AX,"; + else if ((op2 & 0x8b) == 0x02) + stream << "WHL,"; + else if (!BIT(op2, 7)) + stream << "A,"; + + u32 imm24 = u32(opcodes.r8(pc + 4)) << 16 | opcodes.r16(pc + 2); + if (imm24 >= 0xa00000) + stream << "0"; + util::stream_format(stream, "%06XH[%s]", imm24, s_imm24_offsets[BIT(op2, 4, 2)]); + + if ((op2 & 0x8b) == 0x81) + stream << ",AX"; + else if ((op2 & 0x8b) == 0x82) + stream << ",WHL"; + else if (BIT(op2, 7)) + stream << ",A"; + return 5 | SUPPORTED; + } + else if ((op2 & 0x68) == 0x48) + { + util::stream_format(stream, "%-8s", s_alu_ops[op2 & 0x07]); + if (!BIT(op2, 7)) + stream << "A,"; + if (BIT(op2, 4)) + format_abs24(stream, u32(opcodes.r8(pc + 4)) << 16 | opcodes.r16(pc + 2)); + else + format_abs16(stream, opcodes.r16(pc + 2)); + if (BIT(op2, 7)) + stream << ",A"; + return (BIT(op2, 4) ? 5 : 4) | SUPPORTED; + } + else if ((op2 & 0xef) == 0x45) + { + util::stream_format(stream, "%-8sAX,", "XCHW"); + if (BIT(op2, 4)) + { + format_abs24(stream, u32(opcodes.r8(pc + 4)) << 16 | opcodes.r16(pc + 2)); + return 5 | SUPPORTED; + } + else + { + format_abs16(stream, opcodes.r16(pc + 2)); + return 4 | SUPPORTED; + } + } + else + return dasm_illegal2(stream, 0x0a, op2); +} + +offs_t upd78k4_disassembler::dasm_16xx(std::ostream &stream, u8 op1, u8 op2) +{ + if (BIT(op1, 0) && (op2 & 0x60) == 0x60 && (BIT(op2, 3) || (op2 & (BIT(op2, 7) ? 0x06 : 0x02)) == 0x00)) + { + if (BIT(op2, 3)) + util::stream_format(stream, "%-8s", s_alu_ops[op2 & 0x07]); + else if (BIT(op2, 0)) + util::stream_format(stream, "%-8s", BIT(op2, 2) ? "XCHW" : "MOVW"); + else + util::stream_format(stream, "%-8s", BIT(op2, 2) ? "XCH" : "MOV"); + if ((op2 & 0x8b) == 0x01) + stream << "AX,"; + else if (!BIT(op2, 7)) + stream << "A,"; + util::stream_format(stream, "[%s+C]", m_ix_bases[(op2 & 0x10) >> 3]); + if ((op2 & 0x8b) == 0x81) + stream << ",AX"; + else if (BIT(op2, 7)) + stream << ",A"; + return 2 | SUPPORTED; + } + else if ((op2 & 0x0f) == 0x02 && (BIT(op1, 0) || (op2 & 0xd0) != 0x10)) + { + util::stream_format(stream, "%-8s", "MOVG"); + if (!BIT(op2, 7)) + stream << "WHL,"; + stream << "["; + if (BIT(op1, 0) && (op2 & 0x60) == 0x40) + util::stream_format(stream, "%s+%s", s_ix_bases[4], BIT(op2, 4) ? "HL" : "DE"); + else if ((op2 & 0x60) == 0x60) + stream << s_ix_bases[BIT(op2, 4) ? 3 : 4]; + else + { + stream << s_ix_bases[(op2 & 0x10) >> 3]; + if (BIT(op1, 0)) + util::stream_format(stream, "+%c", BIT(op2, 6) ? 'C' : BIT(op2, 5) ? 'B' : 'A'); + else + stream << (BIT(op2, 5) ? "-" : "+"); + } + stream << "]"; + if (BIT(op2, 7)) + stream << ",WHL"; + return 2 | SUPPORTED; + } + else + return upd78k3_disassembler::dasm_16xx(stream, op1, op2); +} + +offs_t upd78k4_disassembler::dasm_24xx(std::ostream &stream, u8 op, u8 rr) +{ + if (!BIT(op, 0) && (rr & 0x99) == 0x99) + { + util::stream_format(stream, "%-8s%s,%s", "MOVG", s_rg_names[BIT(rr, 5, 2)], s_rg_names[BIT(rr, 1, 2)]); + return 2 | SUPPORTED; + } + else + return upd78k3_disassembler::dasm_24xx(stream, op, rr); +} + +offs_t upd78k4_disassembler::dasm_2a(std::ostream &stream, offs_t pc, const upd78k4_disassembler::data_buffer &opcodes) +{ + u8 op2 = opcodes.r8(pc + 1); + if ((op2 & 0xc0) == 0 && (BIT(op2, 3) || (op2 & 0x03) == 0)) + { + if (BIT(op2, 3)) + util::stream_format(stream, "%-8s", s_alu_ops[op2 & 0x07]); + else + util::stream_format(stream, "%-8s", BIT(op2, 2) ? "XCH" : "MOV"); + if (BIT(op2, 5)) + format_saddr1(stream, opcodes.r8(pc + 3)); + else + format_saddr(stream, opcodes.r8(pc + 3)); + stream << ","; + if (BIT(op2, 4)) + format_saddr1(stream, opcodes.r8(pc + 2)); + else + format_saddr(stream, opcodes.r8(pc + 2)); + return 4 | SUPPORTED; + } + else + return dasm_illegal2(stream, 0x2a, op2); +} + +offs_t upd78k4_disassembler::dasm_38(std::ostream &stream, u8 op, offs_t pc, const upd78k4_disassembler::data_buffer &opcodes) +{ + u8 op2 = opcodes.r8(pc + 1); + if (!BIT(op2, 3) && (op2 & 0x03) != 0x03 && (!BIT(op, 0) || !BIT(op2, 2))) + { + util::stream_format(stream, "%-8s", BIT(op2, 2) ? "XCH" : "MOV"); + if (!BIT(op2, 2)) + util::stream_format(stream, "%s,", s_r_names[BIT(op2, 4, 4)]); + if (BIT(op2, 1)) + format_sfr(stream, opcodes.r8(pc + 2)); + else if (BIT(op2, 0)) + format_saddr1(stream, opcodes.r8(pc + 2)); + else + format_saddr(stream, opcodes.r8(pc + 2)); + if (BIT(op2, 2)) + util::stream_format(stream, ",%s", s_r_names[BIT(op2, 4, 4)]); + return 3 | SUPPORTED; + } + else if ((op2 & 0x18) == 0x08 && (op2 & 0x03) != 0x03 && (!BIT(op, 0) || !BIT(op2, 2))) + { + util::stream_format(stream, "%-8s", BIT(op2, 2) ? "XCHW" : "MOVW"); + if (!BIT(op2, 2)) + util::stream_format(stream, "%s,", s_rp_names[BIT(op2, 5, 3)]); + if (BIT(op2, 1)) + format_sfrp(stream, opcodes.r8(pc + 2)); + else if (BIT(op2, 0)) + format_saddrp1(stream, opcodes.r8(pc + 2)); + else + format_saddrp(stream, opcodes.r8(pc + 2)); + if (BIT(op2, 2)) + util::stream_format(stream, ",%s", s_rp_names[BIT(op2, 5, 3)]); + return 3 | SUPPORTED; + } + else if (!BIT(op, 0) && (op2 & 0x9a) == 0x98) + { + util::stream_format(stream, "%-8s", "MOVG"); + if (!BIT(op2, 2)) + util::stream_format(stream, "%s,", s_rg_names[BIT(op2, 5, 2)]); + if (BIT(op2, 0)) + format_saddrg1(stream, opcodes.r8(pc + 2)); + else + format_saddrg2(stream, opcodes.r8(pc + 2)); + if (BIT(op2, 2)) + util::stream_format(stream, ",%s", s_rg_names[BIT(op2, 5, 2)]); + return 3 | SUPPORTED; + } + else if (!BIT(op, 0) && (op2 & 0x9f) == 0x9b) + { + util::stream_format(stream, "%-8s%s,", "MOVG", s_rg_names[BIT(op2, 5, 2)]); + format_imm24(stream, u32(opcodes.r8(pc + 4)) << 16 | opcodes.r16(pc + 2)); + return 5 | SUPPORTED; + } + else + return dasm_illegal2(stream, op, op2); +} + +offs_t upd78k4_disassembler::dasm_3c(std::ostream &stream, u8 op, offs_t pc, const upd78k4_disassembler::data_buffer &opcodes) +{ + if (op == 0x3f) + { + util::stream_format(stream, "%-8s", "CALL"); + format_jdisp16(stream, pc, opcodes.r16(pc + 1)); + return 3 | STEP_OVER | SUPPORTED; + } + else + { + u8 op2 = opcodes.r8(pc + 1); + if (op == 0x3e) + { + if ((op2 & 0x0d) < 0x05) + { + util::stream_format(stream, "%-8s", BIT(op2, 2) ? "XCH" : "MOV"); + if (!BIT(op2, 0)) + util::stream_format(stream, "%s,", s_r_names[BIT(op2, 4, 4)]); + if (BIT(op2, 1)) + format_abs24(stream, u32(opcodes.r8(pc + 2)) << 16 | opcodes.r16(pc + 3)); + else + format_abs16(stream, opcodes.r16(pc + 2)); + if (BIT(op2, 0)) + util::stream_format(stream, ",%s", s_r_names[BIT(op2, 4, 4)]); + return (BIT(op2, 1) ? 5 : 4) | SUPPORTED; + } + else if ((op2 & 0x1c) == 0x08) + { + util::stream_format(stream, "%-8s", "MOVW"); + if (!BIT(op2, 0)) + util::stream_format(stream, "%s,", s_rp_names[BIT(op2, 5, 3)]); + if (BIT(op2, 1)) + format_abs24(stream, u32(opcodes.r8(pc + 2)) << 16 | opcodes.r16(pc + 3)); + else + format_abs16(stream, opcodes.r16(pc + 2)); + if (BIT(op2, 0)) + util::stream_format(stream, ",%s", s_rp_names[BIT(op2, 5, 3)]); + return (BIT(op2, 1) ? 5 : 4) | SUPPORTED; + } + else if ((op2 & 0x9e) == 0x9a) + { + util::stream_format(stream, "%-8s", "MOVG"); + if (!BIT(op2, 0)) + util::stream_format(stream, "%s,", s_rg_names[BIT(op2, 5, 2)]); + format_abs24(stream, u32(opcodes.r8(pc + 2)) << 16 | opcodes.r16(pc + 3)); + if (BIT(op2, 0)) + util::stream_format(stream, ",%s", s_rg_names[BIT(op2, 5, 2)]); + return 5 | SUPPORTED; + } + else if ((op2 & 0x9d) == 0x0d) + { + util::stream_format(stream, "%-8s%s", BIT(op2, 1) ? "DECW" : "INCW", s_rp_names[BIT(op2, 5, 2)]); + return 2 | SUPPORTED; + } + else if ((op2 & 0x9d) == 0x9d) + { + util::stream_format(stream, "%-8s%s", BIT(op2, 1) ? "DECG" : "INCG", s_rg_names[BIT(op2, 5, 2)]); + return 2 | SUPPORTED; + } + else + return dasm_illegal2(stream, 0x3e, op2); + } + else if (op == 0x3d) + { + if ((op2 & 0xf0) == 0x10) + { + util::stream_format(stream, "%-8s[%s].%d,CY", "MOV1", s_rg_names[BIT(op2, 3) ? 3 : 2], op2 & 0x07); + return 2 | SUPPORTED; + } + else if (op2 < 0x70) + { + util::stream_format(stream, "%-8sCY,", s_bool_ops[BIT(op2, 5, 2)]); + if (BIT(op2, 4)) + stream << "/"; + util::stream_format(stream, "[%s].%d", s_rg_names[BIT(op2, 3) ? 3 : 2], op2 & 0x07); + return 2 | SUPPORTED; + } + else if (op2 < 0xa0) + { + util::stream_format(stream, "%-8s", op2 < 0x80 ? "NOT1" : BIT(op2, 4) ? "CLR1" : "SET1"); + util::stream_format(stream, "[%s].%d", s_rg_names[BIT(op2, 3) ? 3 : 2], op2 & 0x07); + return 2 | SUPPORTED; + } + else if (op2 < 0xe0) + { + if (BIT(op2, 6)) + util::stream_format(stream, "%-8s", BIT(op2, 4) ? "BTCLR" : "BFSET"); + else + util::stream_format(stream, "%-8s", BIT(op2, 4) ? "BT" : "BF"); + util::stream_format(stream, "[%s].%d", s_rg_names[BIT(op2, 3) ? 3 : 2], op2 & 0x07); + format_jdisp8(stream, pc + 3, opcodes.r8(pc + 2)); + return 3 | SUPPORTED; + } + else + return dasm_illegal2(stream, 0x3d, op2); + } + else + { + if (op2 == 0x05) + { + u8 op3 = opcodes.r8(pc + 2); + if ((op3 & 0xe8) == 0x08) + { + util::stream_format(stream, "%-8s%s", BIT(op3, 4) ? "DIVUW" : "MULU", s_r_names[op3 & 0x0f]); + return 2 | SUPPORTED; + } + else + return dasm_illegal3(stream, 0x3c, 0x05, op3); + } + else if (op2 == 0x07) + { + u8 op3 = opcodes.r8(pc + 2); + if ((op3 & 0x68) == 0x28 || (op3 & 0x7f) == 0x30 || op3 == 0x34) + { + util::stream_format(stream, "%-8s", BIT(op3, 3) ? s_alu_ops[op3 & 0x07] : BIT(op3, 2) ? "XCH" : "MOV"); + if (!BIT(op3, 7)) + stream << "A,"; + stream << "["; + if (BIT(op3, 4)) + { + stream << "%"; + format_saddrg1(stream, opcodes.r8(pc + 3)); + } + else + format_saddrp1(stream, opcodes.r8(pc + 3)); + stream << "]"; + if (BIT(op3, 7)) + stream << ",A"; + return 4 | SUPPORTED; + } + else if ((op3 & 0x6b) == 0x21 && (op3 & 0x84) != 0x84) + { + util::stream_format(stream, "%-8s", BIT(op3, 2) ? "XCHW" : "MOVW"); + if (!BIT(op3, 7)) + stream << "AX,"; + stream << "["; + if (BIT(op3, 4)) + { + stream << "%"; + format_saddrg1(stream, opcodes.r8(pc + 3)); + } + else + format_saddrp1(stream, opcodes.r8(pc + 3)); + stream << "]"; + if (BIT(op3, 7)) + stream << ",AX"; + return 4 | SUPPORTED; + } + else if ((op3 & 0x7f) == 0x32) + { + util::stream_format(stream, "%-8s", "MOVG"); + if (!BIT(op3, 7)) + stream << "WHL,"; + stream << "[%"; + format_saddrg1(stream, opcodes.r8(pc + 3)); + stream << "]"; + if (BIT(op3, 7)) + stream << ",WHL"; + return 4 | SUPPORTED; + } + else if ((op3 & 0xfe) == 0xe8) + { + util::stream_format(stream, "%-8s", BIT(op3, 0) ? "DECW" : "INCW"); + format_saddrp1(stream, opcodes.r8(pc + 3)); + return 4 | SUPPORTED; + } + else + return dasm_illegal3(stream, 0x3c, 0x07, op3); + } + else if (op2 == 0x08) + { + u8 op3 = opcodes.r8(pc + 2); + if ((op3 & 0xf8) == 0x10) + { + util::stream_format(stream, "%-8s", "MOV1"); + format_saddr1(stream, opcodes.r8(pc + 3)); + util::stream_format(stream, ".%d,CY", op3 & 0x07); + return 4 | SUPPORTED; + } + else if (op3 < 0x70 && !BIT(op3, 3)) + { + util::stream_format(stream, "%-8sCY,", s_bool_ops[BIT(op3, 5, 2)]); + if (BIT(op3, 4)) + stream << "/"; + format_saddr1(stream, opcodes.r8(pc + 3)); + util::stream_format(stream, ".%d", op3 & 0x07); + return 4 | SUPPORTED; + } + else if (op3 < 0xa0 && !BIT(op3, 3)) + { + util::stream_format(stream, "%-8s", op3 < 0x80 ? "NOT1" : BIT(op3, 4) ? "CLR1" : "SET1"); + format_saddr1(stream, opcodes.r8(pc + 3)); + util::stream_format(stream, ".%d", op3 & 0x07); + return 4 | SUPPORTED; + } + else if (op3 < 0xe0 && !BIT(op3, 3)) + { + if (BIT(op3, 6)) + util::stream_format(stream, "%-8s", BIT(op3, 4) ? "BTCLR" : "BFSET"); + else + util::stream_format(stream, "%-8s", BIT(op3, 4) ? "BT" : "BF"); + format_saddr1(stream, opcodes.r8(pc + 3)); + util::stream_format(stream, ".%d,", op3 & 0x07); + format_jdisp8(stream, pc + 5, opcodes.r8(pc + 4)); + return 5 | SUPPORTED; + } + else + return dasm_illegal3(stream, 0x3c, 0x08, op3); + } + else if ((op2 & 0xfc) == 0x0c) + { + util::stream_format(stream, "%-8s", s_16bit_ops[op2 & 0x03]); + format_saddrp1(stream, opcodes.r8(pc + 2)); + stream << ","; + format_imm16(stream, opcodes.r16(pc + 3)); + return 5 | SUPPORTED; + } + else if ((op2 & 0xfe) == 0x18) + { + util::stream_format(stream, "%-8s", "MOV"); + if (!BIT(op2, 0)) + stream << "A,"; + stream << "["; + format_saddrp1(stream, opcodes.r8(pc + 2)); + stream << "]"; + if (BIT(op2, 0)) + stream << ",A"; + return 3 | SUPPORTED; + } + else if (op2 == 0x23) + { + util::stream_format(stream, "%-8sA,[", "XCH"); + format_saddrp1(stream, opcodes.r8(pc + 2)); + stream << "]"; + return 3 | SUPPORTED; + } + else if ((op2 & 0xfe) == 0x24) + { + u8 rr = opcodes.r8(pc + 2); + if (!BIT(rr, 3)) + { + util::stream_format(stream, "%-8s%s,%s", BIT(op2, 0) ? "XCH" : "MOV", s_r_names[BIT(rr, 4, 4)], s_r_names[(rr & 0x07) | 8]); + return 3 | SUPPORTED; + } + else + return dasm_illegal3(stream, op, op2, rr); + } + else if ((op2 & 0xfe) == 0x30) + { + u8 nr = opcodes.r8(pc + 2); + if (nr < 0xc0) + { + util::stream_format(stream, "%-8s%s,%d", s_shift_ops[BIT(op2, 0)][BIT(nr, 6, 2)], s_r_names[(nr & 0x07) | 8], BIT(nr, 3, 3)); + return 3 | SUPPORTED; + } + else + return dasm_illegal3(stream, 0x3c, op2, nr); + } + else if (op2 == 0x3a) + { + util::stream_format(stream, "%-8s", "MOV"); + format_saddr1(stream, opcodes.r8(pc + 2)); + stream << ","; + format_imm8(stream, opcodes.r8(pc + 3)); + return 4 | SUPPORTED; + } + else if ((op2 & 0xf8) == 0x68) + { + util::stream_format(stream, "%-8s", s_alu_ops[op2 & 0x07]); + format_saddr1(stream, opcodes.r8(pc + 2)); + stream << ","; + format_imm8(stream, opcodes.r8(pc + 3)); + return 4 | SUPPORTED; + } + else if ((op2 & 0xf8) == 0x88) + { + u8 rr = opcodes.r8(pc + 2); + if (!BIT(rr, 3)) + { + util::stream_format(stream, "%-8s%s,%s", s_alu_ops[op2 & 0x07], s_r_names[BIT(rr, 4, 4)], s_r_names[(rr & 0x07) | 8]); + return 3 | SUPPORTED; + } + else + return dasm_illegal3(stream, 0x3c, op2, rr); + } + else if ((op2 & 0xe8) == 0xa0) + { + util::stream_format(stream, "%-8s", BIT(op2, 4) ? "SET1" : "CLR1"); + format_saddr1(stream, opcodes.r8(pc + 2)); + util::stream_format(stream, ".%d", op2 & 0x07); + return 3 | SUPPORTED; + } + else if ((op2 & 0xf8) == 0xb8) + { + util::stream_format(stream, "%-8s%s,", "MOV", s_r_names[op2 & 0x0f]); + format_imm8(stream, opcodes.r8(pc + 2)); + return 3 | SUPPORTED; + } + else if ((op2 & 0xf0) == 0xc0) + { + util::stream_format(stream, "%-8s%s", BIT(op2, 3) ? "DEC" : "INC", s_r_names[(op2 & 0x07) | 8]); + return 2 | SUPPORTED; + } + else if ((op2 & 0xf0) == 0xd0) + { + util::stream_format(stream, "%-8sA,%s", BIT(op2, 3) ? "XCH" : "MOV", s_r_names[(op2 & 0x07) | 8]); + return 2 | SUPPORTED; + } + else + return dasm_illegal2(stream, 0x3c, op2); + } + } +} + +offs_t upd78k4_disassembler::dasm_43(std::ostream &stream, offs_t pc, const upd78k4_disassembler::data_buffer &opcodes) +{ + util::stream_format(stream, "%-8s", "BR"); + format_jdisp16(stream, pc, opcodes.r16(pc + 1)); + return 3 | SUPPORTED; +} + +offs_t upd78k4_disassembler::dasm_78(std::ostream &stream, u8 op, offs_t pc, const upd78k4_disassembler::data_buffer &opcodes) +{ + u8 op2 = opcodes.r8(pc + 1); + if ((op2 & 0x0f) < 0x07) + { + util::stream_format(stream, "%-8s", s_alu_ops[op & 0x07]); + if (!BIT(op2, 2)) + util::stream_format(stream, "%s,", s_r_names[BIT(op2, 4, 4)]); + if (BIT(op2, 1)) + { + if (BIT(op2, 0)) + format_imm8(stream, opcodes.r16(pc + 2)); + else + format_sfr(stream, opcodes.r8(pc + 2)); + } + else + { + if (BIT(op2, 0)) + format_saddr1(stream, opcodes.r8(pc + 2)); + else + format_saddr(stream, opcodes.r8(pc + 2)); + } + if (BIT(op2, 2)) + util::stream_format(stream, ",%s", s_r_names[BIT(op2, 4, 4)]); + return 3 | SUPPORTED; + } + else if ((op2 & 0x18) == 0x08 && (op2 & 0x0f) != 0x0f && (op == 0x78 || op == 0x7a || op == 0x7f)) + { + util::stream_format(stream, "%-8s", op == 0x7f ? "CMPW" : op == 0x7a ? "SUBW" : "ADDW"); + if (!BIT(op2, 2)) + util::stream_format(stream, "%s,", s_rp_names[BIT(op2, 5, 3)]); + if ((op2 & 0x0f) == 0x0b) + { + format_imm16(stream, opcodes.r16(pc + 2)); + return 4 | SUPPORTED; + } + else + { + if (BIT(op2, 1)) + format_sfrp(stream, opcodes.r8(pc + 2)); + else if (BIT(op2, 0)) + format_saddrp1(stream, opcodes.r8(pc + 2)); + else + format_saddrp(stream, opcodes.r8(pc + 2)); + if (BIT(op2, 2)) + util::stream_format(stream, ",%s", s_rp_names[BIT(op2, 5, 3)]); + return 3 | SUPPORTED; + } + } + else if ((op & 0x05) == 0 && (op2 & 0xfe) == 0xf8) + { + util::stream_format(stream, "%-8sWHL,", BIT(op, 1) ? "SUBG" : "ADDG"); + if (BIT(op2, 0)) + format_saddrg1(stream, opcodes.r8(pc + 2)); + else + format_saddrg2(stream, opcodes.r8(pc + 2)); + return 3 | SUPPORTED; + } + else if ((op & 0x05) == 0 && (op2 & 0x9f) == 0x9b) + { + util::stream_format(stream, "%-8s%s,", BIT(op, 1) ? "SUBG" : "ADDG", s_rg_names[BIT(op2, 5, 2)]); + format_imm24(stream, u32(opcodes.r8(pc + 4)) << 16 | opcodes.r16(pc + 2)); + return 5 | SUPPORTED; + } + else + return dasm_illegal2(stream, op, op2); +} + +offs_t upd78k4_disassembler::dasm_88xx(std::ostream &stream, u8 op, u8 rr) +{ + if ((op & 0xfd) == 0x88 && (rr & 0x99) == 0x99) + { + util::stream_format(stream, "%-8s%s,%s", BIT(op, 1) ? "SUBG" : "ADDG", s_rg_names[BIT(rr, 5, 2)], s_rg_names[BIT(rr, 1, 2)]); + return 2 | SUPPORTED; + } + else + return upd78k3_disassembler::dasm_88xx(stream, op, rr); +} + + +upd784026_disassembler::upd784026_disassembler() + : upd78k4_disassembler(s_sfr_names, s_sfrp_names) +{ +} + +const char *const upd784026_disassembler::s_sfr_names[256] = +{ + "P0", "P1", "P2", "P3", "P4", "P5", "P6", "P7", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "P0L", "P0H", + nullptr, nullptr, nullptr, nullptr, "CR10", nullptr, "CR11", nullptr, + "CR20", nullptr, "CR21", nullptr, "CR30", nullptr, nullptr, nullptr, + "PM0", "PM1", nullptr, "PM3", "PM4", "PM5", "PM6", "PM7", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "RTPC", nullptr, + "CRC0", "TOC", "CRC1", "CRC2", nullptr, nullptr, nullptr, nullptr, + "CR12", nullptr, "CR22", nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, "PMC1", nullptr, "PMC3", nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "PUO", nullptr, + nullptr, nullptr, "TM1", nullptr, "TM2", nullptr, "TM3", nullptr, + nullptr, nullptr, nullptr, nullptr, "PRM0", "TMC0", "PRM1", "TMC1", + "DACS0", "DACS1", "DAM", nullptr, nullptr, nullptr, nullptr, nullptr, + "ADM", nullptr, "ADCR", nullptr, nullptr, nullptr, nullptr, nullptr, + "PWMC", "PWPR", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, "OSPC", nullptr, nullptr, + "SBIC", nullptr, "CSIM", nullptr, "CSIM1", "CSIM2", "SIO", nullptr, + "ASIM", "ASIM2", "ASIS", "ASIS2", "SIO1", "SIO2", nullptr, nullptr, + "BRGC", "BRGC2", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "INTM0", "INTM1", nullptr, nullptr, "SCS0", nullptr, nullptr, nullptr, + "ISPR", nullptr, "IMC", nullptr, "MK0L", "MK0H", "MK1L", nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "STBC", nullptr, "WDM", nullptr, "MM", "HLDM", "CLOM", "PWC1", + nullptr, nullptr, nullptr, nullptr, "RFM", "RFA", nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // external access + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // external access + "PIC0", "PIC1", "PIC2", "PIC3", "CIC00", "CIC01", "CIC10", "CIC11", + "CIC20", "CIC21", "CIC30", "PIC4", "PIC5", "ADIC", "SERIC", "SRIC", + "STIC", "CSIIC", "SERIC2", "SRIC2", "STIC2", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, "IMS", nullptr, nullptr, nullptr +}; + +const char *const upd784026_disassembler::s_sfrp_names[128] = +{ + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "CR00", "CR01", "CR10W", "CR11W", "CR20W", "CR21W", "CR30W", nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, "CR02", "CR12W", "CR22W", nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "TM0", "TM1W", "TM2W", "TM3W", nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, "PWM0", "PWM1", nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "MK0", nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, "PWC2", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr +}; + +upd784038_disassembler::upd784038_disassembler() + : upd78k4_disassembler(s_sfr_names, s_sfrp_names) +{ +} + +const char *const upd784038_disassembler::s_sfr_names[256] = +{ + "P0", "P1", "P2", "P3", "P4", "P5", "P6", "P7", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "P0L", "P0H", + nullptr, nullptr, nullptr, nullptr, "CR10", nullptr, "CR11", nullptr, + "CR20", nullptr, "CR21", nullptr, "CR30", nullptr, nullptr, nullptr, + "PM0", "PM1", nullptr, "PM3", "PM4", "PM5", "PM6", "PM7", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "RTPC", nullptr, + "CRC0", "TOC", "CRC1", "CRC2", nullptr, nullptr, nullptr, nullptr, + "CR12", nullptr, "CR22", nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, "PMC1", nullptr, "PMC3", nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "PUO", nullptr, + nullptr, nullptr, "TM1", nullptr, "TM2", nullptr, "TM3", nullptr, + nullptr, nullptr, nullptr, nullptr, "PRM0", "TMC0", "PRM1", "TMC1", + "DACS0", "DACS1", "DAM", nullptr, nullptr, nullptr, nullptr, nullptr, + "ADM", nullptr, "ADCR", nullptr, nullptr, nullptr, nullptr, nullptr, + "PWMC", "PWPR", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, "OSPC", nullptr, nullptr, + "IICC", "SPRM", "CSIM", nullptr, "CSIM1", "CSIM2", "SIO", nullptr, + "ASIM", "ASIM2", "ASIS", "ASIS2", "SIO1", "SIO2", nullptr, nullptr, + "BRGC", "BRGC2", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "INTM0", "INTM1", nullptr, nullptr, "SCS0", nullptr, nullptr, nullptr, + "ISPR", nullptr, "IMC", nullptr, "MK0L", "MK0H", "MK1L", nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "STBC", nullptr, "WDM", nullptr, "MM", "HLDM", "CLOM", "PWC1", + nullptr, nullptr, nullptr, nullptr, "RFM", "RFA", nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // external access + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // external access + "PIC0", "PIC1", "PIC2", "PIC3", "CIC00", "CIC01", "CIC10", "CIC11", + "CIC20", "CIC21", "CIC30", "PIC4", "PIC5", "ADIC", "SERIC", "SRIC", + "STIC", "CSIIC", "SERIC2", "SRIC2", "STIC2", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, "IMS", nullptr, nullptr, nullptr +}; + +const char *const upd784038_disassembler::s_sfrp_names[128] = +{ + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "CR00", "CR01", "CR10W", "CR11W", "CR20W", "CR21W", "CR30W", nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, "CR02", "CR12W", "CR22W", nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "TM0", "TM1W", "TM2W", "TM3W", nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, "PWM0", "PWM1", nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "MK0", nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, "PWC2", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr +}; + +upd784046_disassembler::upd784046_disassembler() + : upd78k4_disassembler(s_sfr_names, s_sfrp_names) +{ +} + +const char *const upd784046_disassembler::s_sfr_names[256] = +{ + "P0", "P1", "P2", "P3", "P4", "P5", "P6", "P7", + "P8", "P9", nullptr, nullptr, nullptr, nullptr, "P0L", nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "PM0", "PM1", "PM2", "PM3", "PM4", "PM5", "PM6", nullptr, + "PM8", "PM9", nullptr, nullptr, nullptr, nullptr, "RTPC", "PRDC", + "TUM0", "TMC", "TOC0", "TOC1", "TUM2", "TMC2", "TOC2", "TMC4", + "PRM", "PRM2", "PRM4", "NPC", "INTM0", "INTM1", "IEF1", "IEF2", + nullptr, "PMC1", "PMC2", "PMC3", nullptr, nullptr, nullptr, nullptr, + nullptr, "PMC9", nullptr, nullptr, nullptr, nullptr, "PUOL", "PUOH", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "ADM", nullptr, + nullptr, "ADCR0H", nullptr, "ADCR1H", nullptr, "ADCR2H", nullptr, "ADCR3H", + nullptr, "ADCR4H", nullptr, "ADCR5H", nullptr, "ADCR6H", nullptr, "ADCR7H", + nullptr, nullptr, nullptr, nullptr, "CSIM1", "CSIM2", nullptr, nullptr, + "ASIM", "ASIM2", "ASIS", "ASIS2", "SIO1", "SIO2", nullptr, nullptr, + "BRGC", "BRGC2", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "ISPR", nullptr, "IMC", nullptr, "MK0L", "MK0H", "MK1L", "MK1H", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "STBC", nullptr, "WDM", nullptr, "MM", nullptr, nullptr, "PWC1", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "OSTS", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // external access + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // external access + "OVIC0", "OVIC1", "OVIC4", "PIC0", "PIC1", "PIC2", "PIC3", "PIC4", + "PIC5", "PIC6", "CMIC10", "CMIC11", "CMIC20", "CMIC21", "CMIC30", "CMIC31", + "CMIC40", "CMIC41", "SERIC", "SRIC", "STIC", "SERIC2", "SRIC2", "STIC2", + "ADIC", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr +}; + +const char *const upd784046_disassembler::s_sfrp_names[128] = +{ + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "TM0", "CC00", "CC01", "CC02", "CC03", "TM1", "CM10", "CM11", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "TM2", "CM20", "CM21", "TM3", "CM30", "CM31", nullptr, nullptr, + "TM4", "CM40", "CM41", nullptr, nullptr, nullptr, nullptr, nullptr, + "ADCR0", "ADCR1", "ADCR2", "ADCR3", "ADCR4", "ADCR5", "ADCR6", "ADCR7", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "MK0", "MK1", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, "PWC2", "BW", nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr +}; + +upd784054_disassembler::upd784054_disassembler() + : upd78k4_disassembler(s_sfr_names, s_sfrp_names) +{ +} + +const char *const upd784054_disassembler::s_sfr_names[256] = +{ + "P0", "P1", "P2", "P3", "P4", "P5", "P6", "P7", + "P8", "P9", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "PM0", "PM1", "PM2", "PM3", "PM4", "PM5", "PM6", nullptr, + nullptr, "PM9", nullptr, nullptr, nullptr, nullptr, nullptr, "PRDC", + "TUM0", "TMC", "TOC0", "TOC1", nullptr, nullptr, nullptr, "TMC4", + "PRM", nullptr, "PRM4", "NPC", "INTM0", "INTM1", "IEF1", "IEF2", + nullptr, nullptr, "PMC2", "PMC3", nullptr, nullptr, nullptr, nullptr, + nullptr, "PMC9", nullptr, nullptr, nullptr, nullptr, "PUOL", "PUOH", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "ADM", nullptr, + nullptr, "ADCR0H", nullptr, "ADCR1H", nullptr, "ADCR2H", nullptr, "ADCR3H", + nullptr, "ADCR4H", nullptr, "ADCR5H", nullptr, "ADCR6H", nullptr, "ADCR7H", + nullptr, nullptr, nullptr, nullptr, "CSIM1", "CSIM2", nullptr, nullptr, + "ASIM", "ASIM2", "ASIS", "ASIS2", "SIO1", "SIO2", nullptr, nullptr, + "BRGC", "BRGC2", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "ISPR", nullptr, "IMC", nullptr, "MK0L", "MK0H", "MK1L", "MK1H", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "STBC", nullptr, "WDM", nullptr, "MM", nullptr, nullptr, "PWC1", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "OSTS", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // external access + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // external access + "OVIC0", "OVIC1", "OVIC4", "PIC0", "PIC1", "PIC2", "PIC3", "PIC4", + "PIC5", "PIC6", "CMIC10", "CMIC11", nullptr, nullptr, nullptr, nullptr, + "CMIC40", "CMIC41", "SERIC", "SRIC", "STIC", "SERIC2", "SRIC2", "STIC2", + "ADIC", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr +}; + +const char *const upd784054_disassembler::s_sfrp_names[128] = +{ + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "TM0", "CC00", "CC01", "CC02", "CC03", "TM1", "CM10", "CM11", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "TM4", "CM40", "CM41", nullptr, nullptr, nullptr, nullptr, nullptr, + "ADCR0", "ADCR1", "ADCR2", "ADCR3", "ADCR4", "ADCR5", "ADCR6", "ADCR7", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "MK0", "MK1", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, "PWC2", "BW", nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr +}; + +upd784216_disassembler::upd784216_disassembler() + : upd78k4_disassembler(s_sfr_names, s_sfrp_names) +{ +} + +const char *const upd784216_disassembler::s_sfr_names[256] = +{ + "P0", "P1", "P2", "P3", "P4", "P5", "P6", "P7", + "P8", "P9", "P10", nullptr, "P12", "P13", nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "CRC0", nullptr, + "TMC0", nullptr, "TOC0", nullptr, "PRM0", nullptr, nullptr, nullptr, + "PM0", nullptr, "PM2", "PM3", "PM4", "PM5", "PM6", "PM7", + "PM8", "PM9", "PM10", nullptr, "PM12", "PM13", nullptr, nullptr, + "PU0", nullptr, "PU2", "PU3", nullptr, nullptr, nullptr, "PU7", + "PU8", nullptr, "PU10", nullptr, "PU12", nullptr, nullptr, nullptr, + "CKS", nullptr, "PF2", nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "PUO", nullptr, + "TM1", "TM2", "CR10", "CR20", "TMC1", "TMC2", "PRM1", "PRM2", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "TM5", "TM6", "TM7", "TM8", "CR50", "CR60", "CR70", "CR80", + "TMC5", "TMC6", "TMC7", "TMC8", "PRM5", "PRM6", "PRM7", "PRM8", + "ASIM1", "ASIM2", "ASIS1", "ASIS2", "TXS1/RXB1", "TXS2/RXB2", "BRGC1", "BRGC2", + nullptr, nullptr, "CC", nullptr, nullptr, nullptr, nullptr, nullptr, + "ADM", "ADIS", nullptr, "ADCR", "DACS0", "DACS1", "DAM0", "DAM1", + nullptr, nullptr, nullptr, nullptr, "EBTS", nullptr, nullptr, nullptr, + "CSIM0", "CSIM1", "CSIM2", nullptr, "SIO0", "SIO1", "SIO2", nullptr, + "RTBL", "RTBH", "RTPM", "RTPC", "WTM", nullptr, nullptr, nullptr, + "EGP0", nullptr, "EGN0", nullptr, nullptr, nullptr, nullptr, nullptr, + "ISPR", "SNMI", "IMC", nullptr, "MK0L", "MK0H", "MK1L", "MK1H", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "STBC", nullptr, "WDM", nullptr, "MM", nullptr, nullptr, "PWC1", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "PCS", "OSTS", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // external access + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // external access + "WDTIC", "PIC0", "PIC1", "PIC2", "PIC3", "PIC4", "PIC5", "PIC6", + "CSIIC0", "SERIC1", "SRIC1", "STIC1", "SERIC2", "SRIC2", "STIC2", "TMIC3", + "TMIC00", "TMIC01", "TMIC1", "TMIC2", "ADIC", "TMIC5", "TMIC6", "TMIC7", + "TMIC8", "WTIC", "KRIC", nullptr, nullptr, nullptr, nullptr, nullptr +}; + +const char *const upd784216_disassembler::s_sfrp_names[128] = +{ + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "TM0", "CR00", "CR01", nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "TM1W", "CR1W", "TMC1W", "PRM1W", nullptr, nullptr, nullptr, nullptr, + "TM5W", "TM7W", "CR5W", "CR7W", "TMC5W", "TMC7W", "PRM5W", "PRM7W", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "MK0", "MK1", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr +}; + +upd784218_disassembler::upd784218_disassembler() + : upd78k4_disassembler(s_sfr_names, s_sfrp_names) +{ +} + +const char *const upd784218_disassembler::s_sfr_names[256] = +{ + "P0", "P1", "P2", "P3", "P4", "P5", "P6", "P7", + "P8", "P9", "P10", nullptr, "P12", "P13", nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "CRC0", nullptr, + "TMC0", nullptr, "TOC0", nullptr, "PRM0", nullptr, nullptr, nullptr, + "PM0", nullptr, "PM2", "PM3", "PM4", "PM5", "PM6", "PM7", + "PM8", "PM9", "PM10", nullptr, "PM12", "PM13", nullptr, nullptr, + "PU0", nullptr, "PU2", "PU3", nullptr, nullptr, nullptr, "PU7", + "PU8", nullptr, "PU10", nullptr, "PU12", nullptr, nullptr, nullptr, + "CKS", nullptr, "PF2", nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "PUO", nullptr, + "TM1", "TM2", "CR10", "CR20", "TMC1", "TMC2", "PRM1", "PRM2", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "TM5", "TM6", "TM7", "TM8", "CR50", "CR60", "CR70", "CR80", + "TMC5", "TMC6", "TMC7", "TMC8", "PRM5", "PRM6", "PRM7", "PRM8", + "ASIM1", "ASIM2", "ASIS1", "ASIS2", "TXS1/RXB1", "TXS2/RXB2", "BRGC1", "BRGC2", + nullptr, nullptr, "CC", nullptr, nullptr, nullptr, nullptr, nullptr, + "ADM", "ADIS", nullptr, "ADCR", "DACS0", "DACS1", "DAM0", "DAM1", + "CORC", "CORAH", nullptr, nullptr, "EBTS", "EXAE", nullptr, nullptr, + "CSIM0", "CSIM1", "CSIM2", nullptr, "SIO0", "SIO1", "SIO2", nullptr, + "RTBL", "RTBH", "RTPM", "RTPC", "WTM", nullptr, nullptr, nullptr, + "EGP0", nullptr, "EGN0", nullptr, nullptr, nullptr, nullptr, nullptr, + "ISPR", "SNMI", "IMC", nullptr, "MK0L", "MK0H", "MK1L", "MK1H", + "IICC0", nullptr, "SRPM0", nullptr, "SVA0", nullptr, "IICS0", nullptr, + "IIC0", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "STBC", nullptr, "WDM", nullptr, "MM", nullptr, nullptr, "PWC1", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "PCS", "OSTS", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // external access + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // external access + "WDTIC", "PIC0", "PIC1", "PIC2", "PIC3", "PIC4", "PIC5", "PIC6", + "CSIIC0", "SERIC1", "SRIC1", "STIC1", "SERIC2", "SRIC2", "STIC2", "TMIC3", + "TMIC00", "TMIC01", "TMIC1", "TMIC2", "ADIC", "TMIC5", "TMIC6", "TMIC7", + "TMIC8", "WTIC", "KRIC", nullptr, nullptr, nullptr, nullptr, nullptr +}; + +const char *const upd784218_disassembler::s_sfrp_names[128] = +{ + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "TM0", "CR00", "CR01", nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "TM1W", "CR1W", "TMC1W", "PRM1W", nullptr, nullptr, nullptr, nullptr, + "TM5W", "TM7W", "CR5W", "CR7W", "TMC5W", "TMC7W", "PRM5W", "PRM7W", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, "CORAL", nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "MK0", "MK1", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr +}; + +upd784225_disassembler::upd784225_disassembler() + : upd78k4_disassembler(s_sfr_names, s_sfrp_names) +{ +} + +const char *const upd784225_disassembler::s_sfr_names[256] = +{ + "P0", "P1", "P2", "P3", "P4", "P5", "P6", "P7", + nullptr, nullptr, nullptr, nullptr, "P12", "P13", nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "CRC0", nullptr, + "TMC0", nullptr, "TOC0", nullptr, "PRM0", nullptr, nullptr, nullptr, + "PM0", nullptr, "PM2", "PM3", "PM4", "PM5", "PM6", "PM7", + nullptr, nullptr, nullptr, nullptr, "PM12", "PM13", nullptr, nullptr, + "PU0", nullptr, "PU2", "PU3", nullptr, nullptr, nullptr, "PU7", + nullptr, nullptr, nullptr, nullptr, "PU12", nullptr, nullptr, nullptr, + "CKS", nullptr, "PF2", nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "PUO", nullptr, + "TM1", "TM2", "CR10", "CR20", "TMC1", "TMC2", "PRM1", "PRM2", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "TM5", "TM6", nullptr, nullptr, "CR50", "CR60", nullptr, nullptr, + "TMC5", "TMC6", nullptr, nullptr, "PRM5", "PRM6", nullptr, nullptr, + "ASIM1", "ASIM2", "ASIS1", "ASIS2", "TXS1/RXB1", "TXS2/RXB2", "BRGC1", "BRGC2", + nullptr, nullptr, "CC", nullptr, nullptr, nullptr, nullptr, nullptr, + "ADM", "ADIS", nullptr, "ADCR", "DACS0", "DACS1", "DAM0", "DAM1", + "CORC", "CORAH", nullptr, nullptr, nullptr, "EXAE", nullptr, nullptr, + "CSIM0", "CSIM1", "CSIM2", nullptr, "SIO0", "SIO1", "SIO2", nullptr, + "RTBL", "RTBH", "RTPM", "RTPC", "WTM", nullptr, nullptr, nullptr, + "EGP0", nullptr, "EGN0", nullptr, nullptr, nullptr, nullptr, nullptr, + "ISPR", "SNMI", "IMC", nullptr, "MK0L", "MK0H", "MK1L", "MK1H", + "IICC0", nullptr, "SRPM0", nullptr, "SVA0", nullptr, "IICS0", nullptr, + "IIC0", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "STBC", nullptr, "WDM", nullptr, "MM", nullptr, nullptr, "PWC1", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "PCS", "OSTS", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // external access + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // external access + "WDTIC", "PIC0", "PIC1", "PIC2", "PIC3", "PIC4", "PIC5", "PIC6", + "CSIIC0", "SERIC1", "SRIC1", "STIC1", "SERIC2", "SRIC2", "STIC2", "TMIC3", + "TMIC00", "TMIC01", "TMIC1", "TMIC2", "ADIC", "TMIC5", "TMIC6", nullptr, + nullptr, "WTIC", nullptr, nullptr, "IMS", nullptr, nullptr, nullptr +}; + +const char *const upd784225_disassembler::s_sfrp_names[128] = +{ + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "TM0", "CR00", "CR01", nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "TM1W", "CR1W", "TMC1W", "PRM1W", nullptr, nullptr, nullptr, nullptr, + "TM5W", "TM7W", "CR5W", "CR7W", "TMC5W", nullptr, "PRM5W", nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, "CORAL", nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "MK0", "MK1", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, "PWC2", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr +}; diff --git a/src/devices/cpu/upd78k/upd78k4d.h b/src/devices/cpu/upd78k/upd78k4d.h new file mode 100644 index 00000000000..3ebd0b1008c --- /dev/null +++ b/src/devices/cpu/upd78k/upd78k4d.h @@ -0,0 +1,128 @@ +// license:BSD-3-Clause +// copyright-holders:AJR + +#ifndef MAME_CPU_UPD78K_UPD78K4D_H +#define MAME_CPU_UPD78K_UPD78K4D_H + +#pragma once + +#include "upd78k3d.h" + +class upd78k4_disassembler : public upd78k3_disassembler +{ +protected: + upd78k4_disassembler(const char *const sfr_names[], const char *const sfrp_names[]); + + // register and mnemonic tables + static const char *const s_ix_bases[5]; + static const char *const s_imm24_offsets[4]; + static const char *const s_rg_names[4]; + + // upd78k_family_disassembler overrides + virtual void format_jdisp8(std::ostream &stream, offs_t pc, u8 disp) override; + + // upd78k3_disassembler overrides + virtual offs_t dasm_05xx(std::ostream &stream, u8 op2) override; + virtual offs_t dasm_06xx(std::ostream &stream, u8 op2, offs_t pc, const data_buffer &opcodes) override; + virtual offs_t dasm_07xx(std::ostream &stream, u8 op2, offs_t pc, const data_buffer &opcodes) override; + virtual offs_t dasm_09xx(std::ostream &stream, u8 op2, offs_t pc, const data_buffer &opcodes) override; + virtual offs_t dasm_0axx(std::ostream &stream, u8 op2, offs_t pc, const data_buffer &opcodes) override; + virtual offs_t dasm_16xx(std::ostream &stream, u8 op1, u8 op2) override; + virtual offs_t dasm_24xx(std::ostream &stream, u8 op, u8 rr) override; + virtual offs_t dasm_2a(std::ostream &stream, offs_t pc, const data_buffer &opcodes) override; + virtual offs_t dasm_38(std::ostream &stream, u8 op, offs_t pc, const data_buffer &opcodes) override; + virtual offs_t dasm_3c(std::ostream &stream, u8 op, offs_t pc, const data_buffer &opcodes) override; + virtual offs_t dasm_43(std::ostream &stream, offs_t pc, const data_buffer &opcodes) override; + virtual offs_t dasm_78(std::ostream &stream, u8 op, offs_t pc, const data_buffer &opcodes) override; + virtual offs_t dasm_88xx(std::ostream &stream, u8 op, u8 rr) override; + +private: + // formatting helpers + void format_imm24(std::ostream &stream, u32 d); + void format_abs20(std::ostream &stream, u32 addr); + void format_abs24(std::ostream &stream, u32 addr); + void format_saddr1(std::ostream &stream, u8 addr); + void format_saddrp1(std::ostream &stream, u8 addr); + void format_saddrg1(std::ostream &stream, u8 addr); + void format_saddrg2(std::ostream &stream, u8 addr); + void format_jdisp16(std::ostream &stream, offs_t pc, u16 disp); +}; + +class upd784026_disassembler : public upd78k4_disassembler +{ +public: + upd784026_disassembler(); + +private: + // SFR tables + static const char *const s_sfr_names[256]; + static const char *const s_sfrp_names[128]; +}; + +class upd784038_disassembler : public upd78k4_disassembler +{ +public: + upd784038_disassembler(); + +private: + // SFR tables + static const char *const s_sfr_names[256]; + static const char *const s_sfrp_names[128]; +}; + +class upd784046_disassembler : public upd78k4_disassembler +{ +public: + upd784046_disassembler(); + +private: + // SFR tables + static const char *const s_sfr_names[256]; + static const char *const s_sfrp_names[128]; +}; + +class upd784054_disassembler : public upd78k4_disassembler +{ +public: + upd784054_disassembler(); + +private: + // SFR tables + static const char *const s_sfr_names[256]; + static const char *const s_sfrp_names[128]; +}; + +class upd784216_disassembler : public upd78k4_disassembler +{ +public: + upd784216_disassembler(); + +private: + // SFR tables + static const char *const s_sfr_names[256]; + static const char *const s_sfrp_names[128]; +}; + +class upd784218_disassembler : public upd78k4_disassembler +{ +public: + upd784218_disassembler(); + +private: + // SFR tables + static const char *const s_sfr_names[256]; + static const char *const s_sfrp_names[128]; +}; + +class upd784225_disassembler : public upd78k4_disassembler +{ +public: + upd784225_disassembler(); + +private: + // SFR tables + static const char *const s_sfr_names[256]; + static const char *const s_sfrp_names[128]; +}; + +#endif // MAME_CPU_UPD78K_UPD78K3D_H diff --git a/src/devices/cpu/upd78k/upd78kd.cpp b/src/devices/cpu/upd78k/upd78kd.cpp index a7c91c488ce..11a697401c7 100644 --- a/src/devices/cpu/upd78k/upd78kd.cpp +++ b/src/devices/cpu/upd78k/upd78kd.cpp @@ -11,10 +11,11 @@ #include "emu.h" #include "upd78kd.h" -upd78k_family_disassembler::upd78k_family_disassembler(const char *const sfr_names[], const char *const sfrp_names[]) +upd78k_family_disassembler::upd78k_family_disassembler(const char *const sfr_names[], const char *const sfrp_names[], u16 saddr_ram_base) : util::disasm_interface() , m_sfr_names(sfr_names) , m_sfrp_names(sfrp_names) + , m_saddr_ram_base(saddr_ram_base) { } @@ -101,7 +102,7 @@ void upd78k_family_disassembler::format_saddr(std::ostream &stream, u8 addr) if (addr < 0x20) format_sfr(stream, addr); else - util::stream_format(stream, "0%04XH", 0xfe00 + addr); + util::stream_format(stream, "0%04XH", m_saddr_ram_base + addr); } void upd78k_family_disassembler::format_sfrp(std::ostream &stream, u8 addr) @@ -161,7 +162,7 @@ offs_t upd78k_family_disassembler::dasm_illegal3(std::ostream &stream, u8 op1, u // For families with 4 banks of 8 registers and only one PSW byte upd78k_8reg_disassembler::upd78k_8reg_disassembler(const char *const sfr_names[], const char *const sfrp_names[]) - : upd78k_family_disassembler(sfr_names, sfrp_names) + : upd78k_family_disassembler(sfr_names, sfrp_names, 0xfe00) { } diff --git a/src/devices/cpu/upd78k/upd78kd.h b/src/devices/cpu/upd78k/upd78kd.h index 2dabff37edc..88789d2e38f 100644 --- a/src/devices/cpu/upd78k/upd78kd.h +++ b/src/devices/cpu/upd78k/upd78kd.h @@ -9,7 +9,7 @@ class upd78k_family_disassembler : public util::disasm_interface { protected: - upd78k_family_disassembler(const char *const sfr_names[], const char *const sfrp_names[]); + upd78k_family_disassembler(const char *const sfr_names[], const char *const sfrp_names[], u16 saddr_ram_base); // disasm_interface overrides virtual u32 opcode_alignment() const override; @@ -21,7 +21,7 @@ protected: void format_ix_disp16(std::ostream &stream, const char *r, u16 d); void format_ix_base16(std::ostream &stream, const char *r, u16 d); void format_abs16(std::ostream &stream, u16 addr); - void format_jdisp8(std::ostream &stream, offs_t pc, u8 disp); + virtual void format_jdisp8(std::ostream &stream, offs_t pc, u8 disp); void format_sfr(std::ostream &stream, u8 addr); void format_saddr(std::ostream &stream, u8 addr); void format_sfrp(std::ostream &stream, u8 addr); @@ -36,6 +36,7 @@ protected: private: const char *const *const m_sfr_names; const char *const *const m_sfrp_names; + const u16 m_saddr_ram_base; }; class upd78k_8reg_disassembler : public upd78k_family_disassembler diff --git a/src/mame/drivers/viper.cpp b/src/mame/drivers/viper.cpp index 179a6ae17ad..89afd33405c 100644 --- a/src/mame/drivers/viper.cpp +++ b/src/mame/drivers/viper.cpp @@ -404,6 +404,7 @@ The golf club acts like a LED gun. PCB power input is 12V. #include "emu.h" #include "cpu/powerpc/ppc.h" +#include "cpu/upd78k/upd78k4.h" #include "bus/ata/ataintf.h" #include "bus/ata/idehd.h" #include "machine/lpci.h" @@ -447,6 +448,7 @@ public: void viper(machine_config &config); void viper_ppp(machine_config &config); + void viper_omz(machine_config &config); void init_viper(); void init_vipercf(); @@ -502,6 +504,7 @@ private: void viper_map(address_map &map); void viper_ppp_map(address_map &map); + void omz3d_map(address_map &map); TIMER_CALLBACK_MEMBER(epic_global_timer_callback); TIMER_CALLBACK_MEMBER(ds2430_timer_callback); @@ -2725,6 +2728,19 @@ void viper_state::viper_ppp(machine_config &config) m_maincpu->set_addrmap(AS_PROGRAM, &viper_state::viper_ppp_map); } +void viper_state::omz3d_map(address_map &map) +{ + map(0x00000, 0x0ffff).rom().region("ioboard", 0); +} + +void viper_state::viper_omz(machine_config &config) +{ + viper(config); + + upd784031_device &omz3dcpu(UPD784031(config, "omz3dcpu", 12000000)); + omz3dcpu.set_addrmap(AS_PROGRAM, &viper_state::omz3d_map); +} + /*****************************************************************************/ void viper_state::init_viper() @@ -3405,7 +3421,7 @@ GAME(2001, gticlub2, kviper, viper, gticlub2, viper_state, init_viperc GAME(2001, gticlub2ea,gticlub2, viper, gticlub2ea, viper_state, init_vipercf, ROT0, "Konami", "GTI Club: Corso Italiano (ver EAA)", MACHINE_NOT_WORKING) GAME(2001, jpark3, kviper, viper, jpark3, viper_state, init_vipercf, ROT0, "Konami", "Jurassic Park 3 (ver EBC)", MACHINE_NOT_WORKING) GAME(2001, jpark3u, jpark3, viper, jpark3, viper_state, init_vipercf, ROT0, "Konami", "Jurassic Park 3 (ver UBC)", MACHINE_NOT_WORKING) -GAME(2001, mocapglf, kviper, viper, mocapglf, viper_state, init_vipercf, ROT90, "Konami", "Mocap Golf (ver UAA)", MACHINE_NOT_WORKING) +GAME(2001, mocapglf, kviper, viper_omz, mocapglf, viper_state, init_vipercf, ROT90, "Konami", "Mocap Golf (ver UAA)", MACHINE_NOT_WORKING) GAME(2001, mocapb, kviper, viper, mocapb, viper_state, init_vipercf, ROT90, "Konami", "Mocap Boxing (ver AAB)", MACHINE_NOT_WORKING) GAME(2001, mocapbj, mocapb, viper, mocapb, viper_state, init_vipercf, ROT90, "Konami", "Mocap Boxing (ver JAA)", MACHINE_NOT_WORKING) GAME(2001, p911, kviper, viper, p911, viper_state, init_vipercf, ROT90, "Konami", "Police 911 (ver AAE)", MACHINE_NOT_WORKING) diff --git a/src/tools/unidasm.cpp b/src/tools/unidasm.cpp index c691149945a..d367936056b 100644 --- a/src/tools/unidasm.cpp +++ b/src/tools/unidasm.cpp @@ -183,6 +183,7 @@ using util::BIT; #include "cpu/upd78k/upd78k1d.h" #include "cpu/upd78k/upd78k2d.h" #include "cpu/upd78k/upd78k3d.h" +#include "cpu/upd78k/upd78k4d.h" #include "cpu/v60/v60d.h" #include "cpu/v810/v810dasm.h" #include "cpu/v850/v850dasm.h" @@ -634,6 +635,13 @@ static const dasm_table_entry dasm_table[] = { "upd78356", le, 0, []() -> util::disasm_interface * { return new upd78356_disassembler; } }, { "upd78366a", le, 0, []() -> util::disasm_interface * { return new upd78366a_disassembler; } }, { "upd78372", le, 0, []() -> util::disasm_interface * { return new upd78372_disassembler; } }, + { "upd784026", le, 0, []() -> util::disasm_interface * { return new upd784026_disassembler; } }, + { "upd784038", le, 0, []() -> util::disasm_interface * { return new upd784038_disassembler; } }, + { "upd784046", le, 0, []() -> util::disasm_interface * { return new upd784046_disassembler; } }, + { "upd784054", le, 0, []() -> util::disasm_interface * { return new upd784054_disassembler; } }, + { "upd784216", le, 0, []() -> util::disasm_interface * { return new upd784216_disassembler; } }, + { "upd784218", le, 0, []() -> util::disasm_interface * { return new upd784218_disassembler; } }, + { "upd784225", le, 0, []() -> util::disasm_interface * { return new upd784225_disassembler; } }, { "upd780065", le, 0, []() -> util::disasm_interface * { return new upd780065_disassembler; } }, { "upd780988", le, 0, []() -> util::disasm_interface * { return new upd78083_disassembler; } }, { "upd78k0kx1", le, 0, []() -> util::disasm_interface * { return new upd78k0kx1_disassembler; } },