diff --git a/scripts/src/cpu.lua b/scripts/src/cpu.lua index 57a3c900c03..0913af02d75 100644 --- a/scripts/src/cpu.lua +++ b/scripts/src/cpu.lua @@ -3133,3 +3133,28 @@ if (CPUS["XAVIX2"]~=null or _OPTIONS["with-tools"]) then table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/xavix2/xavix2d.cpp") table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/xavix2/xavix2d.h") end + +-------------------------------------------------- +-- NEC 78K +--@src/devices/cpu/upd78k/upd78k.h,CPUS["UPD78K"] = true +-------------------------------------------------- + +if (CPUS["UPD78K"]~=null) then + files { + MAME_DIR .. "src/devices/cpu/upd78k/upd78k0.cpp", + MAME_DIR .. "src/devices/cpu/upd78k/upd78k0.h", + MAME_DIR .. "src/devices/cpu/upd78k/upd78k2.cpp", + MAME_DIR .. "src/devices/cpu/upd78k/upd78k2.h", + } +end + +if (CPUS["UPD78K"]~=null or _OPTIONS["with-tools"]) then + table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/upd78k/upd78kd.cpp") + table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/upd78k/upd78kd.h") + table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/upd78k/upd78k0d.cpp") + table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/upd78k/upd78k0d.h") + table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/upd78k/upd78k1d.cpp") + table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/upd78k/upd78k1d.h") + table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/upd78k/upd78k2d.cpp") + table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/upd78k/upd78k2d.h") +end diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index 7716cea4eeb..c3e13736f05 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -138,6 +138,7 @@ CPUS["HPC"] = true --CPUS["BCP"] = true --CPUS["CR16B"] = true CPUS["FR"] = true +CPUS["UPD78K"] = true -------------------------------------------------- -- specify available sound cores @@ -3391,6 +3392,8 @@ files { MAME_DIR .. "src/mame/drivers/y2.cpp", MAME_DIR .. "src/mame/video/powervr2.cpp", MAME_DIR .. "src/mame/video/powervr2.h", + MAME_DIR .. "src/mame/machine/gunsense.cpp", + MAME_DIR .. "src/mame/machine/gunsense.h", MAME_DIR .. "src/mame/machine/naomi.cpp", MAME_DIR .. "src/mame/machine/naomig1.cpp", MAME_DIR .. "src/mame/machine/naomig1.h", diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 6be8c987e68..0b6e93516e7 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -156,6 +156,7 @@ CPUS["RX01"] = true CPUS["GTRON"] = true CPUS["M88000"] = true CPUS["XAVIX2"] = true +CPUS["UPD78K"] = true -------------------------------------------------- -- specify available sound cores; some of these are diff --git a/src/devices/cpu/upd78k/upd78k0.cpp b/src/devices/cpu/upd78k/upd78k0.cpp new file mode 100644 index 00000000000..ff87be3553c --- /dev/null +++ b/src/devices/cpu/upd78k/upd78k0.cpp @@ -0,0 +1,238 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/**************************************************************************** + + NEC 78K/0 series 8-bit single-chip microcontrollers + + Currently these devices are just stubs with no actual execution core. + +****************************************************************************/ + +#include "emu.h" +#include "upd78k0.h" +#include "upd78k0d.h" + +// device type definition +DEFINE_DEVICE_TYPE(UPD78053, upd78053_device, "upd78053", "NEC uPD78053") + +//************************************************************************** +// 78K/0 CORE +//************************************************************************** + +//------------------------------------------------- +// upd78k0_device - constructor +//------------------------------------------------- + +upd78k0_device::upd78k0_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u16 iram_size, address_map_constructor mem_map, address_map_constructor sfr_map) + : cpu_device(mconfig, type, tag, owner, clock) + , m_program_config("program", ENDIANNESS_LITTLE, 8, 16, 0, mem_map) + , m_iram_config("internal high-speed RAM", ENDIANNESS_LITTLE, 16, iram_size > 0x200 ? 10 : iram_size > 0x100 ? 9 : 8, 0, + address_map_constructor(FUNC(upd78k0_device::iram_map), this)) + , m_sfr_config("SFR", ENDIANNESS_LITTLE, 16, 8, 0, sfr_map) + , m_iram_size(iram_size) + , m_program_space(nullptr) + , m_program_cache(nullptr) + , m_iram_cache(nullptr) + , m_sfr_space(nullptr) + , m_subclock(0) + , m_pc(0) + , m_ppc(0) + , m_psw(0) + , m_sp(0) + , m_icount(0) +{ +} + + +//------------------------------------------------- +// iram_map - type-universal IRAM map +//------------------------------------------------- + +void upd78k0_device::iram_map(address_map &map) +{ + if (m_iram_size > 0x200) + map(0x400 - m_iram_size, 0x3ff).ram().share("iram"); + else if (m_iram_size > 0x100) + map(0x200 - m_iram_size, 0x1ff).ram().share("iram"); + else + map(0x00, 0xff).ram().share("iram"); +} + + +//------------------------------------------------- +// memory_space_config - return a vector of +// address space configurations for this device +//------------------------------------------------- + +device_memory_interface::space_config_vector upd78k0_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 upd78k0_device::register_base() const noexcept +{ + return (BIT(m_psw, 5) ? 0x3e0 : 0x3f0) | (~m_psw & 0x08); +} + + +//------------------------------------------------- +// debug_register_base - determine current base of +// register file relative to start of IRAM +//------------------------------------------------- + +inline u16 upd78k0_device::debug_register_base() const noexcept +{ + return (m_iram_size - 0x20) | (BIT(m_psw, 5) ? 0 : 0x10) | (~m_psw & 0x08); +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void upd78k0_device::device_start() +{ + // get address spaces and access caches + m_program_space = &space(AS_PROGRAM); + m_program_cache = m_program_space->cache<0, 0, ENDIANNESS_LITTLE>(); + m_iram_cache = space(AS_DATA).cache<1, 0, ENDIANNESS_LITTLE>(); + m_sfr_space = &space(AS_IO); + + set_icountptr(m_icount); + + // debug state + state_add(UPD78K0_PC, "PC", m_pc); + state_add(STATE_GENPC, "GENPC", m_pc).noshow(); + state_add(STATE_GENPCBASE, "GENPCBASE", m_ppc).noshow(); + state_add(UPD78K0_PSW, "PSW", m_psw).mask(0xfb); + state_add(STATE_GENFLAGS, "FLAGS", m_psw).mask(0xfb).formatstr("%9s").noshow(); + state_add(UPD78K0_RBS, "RBS", + [this]() { return bitswap<2>(m_psw, 5, 3); }, + [this](u8 data) { m_psw = (m_psw & 0xd7) | (data & 2) << 4 | (data & 1) << 3; } + ).mask(3).noshow(); + state_add(UPD78K0_SP, "SP", m_sp); + void *iram = memshare("iram")->ptr(); + for (int n = 0; n < 4; n++) + state_add(UPD78K0_AX + n, std::array{{"AX", "BC", "DE", "HL"}}[n], + [this, iram, n]() { return static_cast(iram)[(debug_register_base() >> 1) | n]; }, + [this, iram, n](u16 data) { static_cast(iram)[(debug_register_base() >> 1) | n] = data; } + ); + for (int n = 0; n < 8; n++) + state_add(UPD78K0_X + n, std::array{{"X", "A", "C", "B", "E", "D", "L", "H"}}[n], + [this, iram, n]() { return static_cast(iram)[BYTE_XOR_LE(debug_register_base() | n)]; }, + [this, iram, n](u8 data) { static_cast(iram)[BYTE_XOR_LE(debug_register_base() | n)] = data; } + ).noshow(); + + // save state + save_item(NAME(m_pc)); + save_item(NAME(m_ppc)); + save_item(NAME(m_sp)); + save_item(NAME(m_psw)); +} + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void upd78k0_device::device_reset() +{ + // PC will be initialized from vector following reset + m_psw = 0x02; +} + + +//------------------------------------------------- +// execute_run - +//------------------------------------------------- + +void upd78k0_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 - export state as a string +//------------------------------------------------- + +void upd78k0_device::state_string_export(const device_state_entry &entry, std::string &str) const +{ + switch (entry.index()) + { + case STATE_GENFLAGS: + str = string_format("RB%d:%c%c%c%c%c", + (BIT(m_psw, 5) ? 2 : 0) | (BIT(m_psw, 3) ? 1 : 0), + BIT(m_psw, 7) ? 'I' : '.', + BIT(m_psw, 6) ? 'Z' : '.', + BIT(m_psw, 4) ? 'A' : '.', + BIT(m_psw, 1) ? 'P' : '.', + BIT(m_psw, 0) ? 'C' : '.'); + break; + } +} + + +//************************************************************************** +// 78K/0 SUBSERIES DEVICES +//************************************************************************** + +//------------------------------------------------- +// upd78053_device - constructor +//------------------------------------------------- + +upd78053_device::upd78053_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : upd78k0_device(mconfig, UPD78053, tag, owner, clock, 0x400, + address_map_constructor(FUNC(upd78053_device::mem_map), this), + address_map_constructor(FUNC(upd78053_device::sfr_map), this)) +{ +} + + +//------------------------------------------------- +// create_disassembler - +//------------------------------------------------- + +std::unique_ptr upd78053_device::create_disassembler() +{ + return std::make_unique(); +} + + +//------------------------------------------------- +// mem_map - type-specific internal memory map +// (excluding high-speed RAM and SFRs) +//------------------------------------------------- + +void upd78053_device::mem_map(address_map &map) +{ + map(0x0000, 0x5fff).rom().region(DEVICE_SELF, 0); // 24K mask ROM + map(0xfa80, 0xfabf).unmaprw(); // reserved + map(0xfac0, 0xfadf).ram().share("buffer"); // buffer RAM + map(0xfae0, 0xfaff).unmaprw(); // reserved +} + + +//------------------------------------------------- +// sfr_map - type-specific SFR map +//------------------------------------------------- + +void upd78053_device::sfr_map(address_map &map) +{ + // TODO +} diff --git a/src/devices/cpu/upd78k/upd78k0.h b/src/devices/cpu/upd78k/upd78k0.h new file mode 100644 index 00000000000..84c7fca788a --- /dev/null +++ b/src/devices/cpu/upd78k/upd78k0.h @@ -0,0 +1,107 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/********************************************************************** + + NEC 78K/0 series 8-bit single-chip microcontrollers + +**********************************************************************/ + +#ifndef MAME_CPU_UPD78K_UPD78K0_H +#define MAME_CPU_UPD78K_UPD78K0_H + +#pragma once + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> upd78k0_device + +class upd78k0_device : public cpu_device +{ +public: + enum { + UPD78K0_PC, UPD78K0_PSW, UPD78K0_RBS, UPD78K0_SP, + UPD78K0_AX, UPD78K0_BC, + UPD78K0_DE, UPD78K0_HL, + UPD78K0_X, UPD78K0_A, UPD78K0_C, UPD78K0_B, + UPD78K0_D, UPD78K0_E, UPD78K0_H, UPD78K0_L + }; + + // configuration (TODO: callbacks) + void set_subclock(u32 clock) { m_subclock = clock; } + void set_subclock(const XTAL &xtal) { m_subclock = xtal.value(); } + +protected: + upd78k0_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u16 iram_size, 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; + + // 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; + inline u16 debug_register_base() const noexcept; + + // address spaces, caches & configuration + address_space_config m_program_config; + address_space_config m_iram_config; + address_space_config m_sfr_config; + const u16 m_iram_size; + address_space *m_program_space; + memory_access_cache<0, 0, ENDIANNESS_LITTLE> *m_program_cache; + memory_access_cache<1, 0, ENDIANNESS_LITTLE> *m_iram_cache; + address_space *m_sfr_space; + + // miscellaneous configuration + u32 m_subclock; + + // core registers and execution state + u16 m_pc; + u16 m_ppc; + u8 m_psw; + u16 m_sp; + s32 m_icount; +}; + +// ======================> upd78053_device + +class upd78053_device : public upd78k0_device +{ +public: + // device type constructors + upd78053_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + template + upd78053_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock, X &&subclock) + : upd78053_device(mconfig, tag, owner, clock) + { + set_subclock(std::forward(subclock)); + } + +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(UPD78053, upd78053_device) + +#endif // MAME_CPU_UPD78K_UPD78K0_H diff --git a/src/devices/cpu/upd78k/upd78k0d.cpp b/src/devices/cpu/upd78k/upd78k0d.cpp new file mode 100644 index 00000000000..233b5fbdd50 --- /dev/null +++ b/src/devices/cpu/upd78k/upd78k0d.cpp @@ -0,0 +1,1348 @@ +// license:BSD-3-Clause +// copyright-holders:AJR + +// Note: FFD0–FFDF defined as "External access area" on various models but *cannot* use SFR addressing! + +#include "emu.h" +#include "upd78k0d.h" + +upd78k0_disassembler::upd78k0_disassembler(const char *const sfr_names[], const char *const sfrp_names[]) + : upd78k_8reg_disassembler(sfr_names, sfrp_names) +{ +} + +const char *const upd78k0_disassembler::s_alu_ops[8] = +{ + "ADD", + "SUB", + "ADDC", + "SUBC", + "CMP", + "AND", + "OR", + "XOR" +}; + +const char *const upd78k0_disassembler::s_bool_ops[4] = +{ + "MOV1", + "AND1", + "OR1", + "XOR1" +}; + +offs_t upd78k0_disassembler::dasm_31(std::ostream &stream, offs_t pc, const upd78k0_disassembler::data_buffer &opcodes) +{ + u8 op2 = opcodes.r8(pc + 1); + if (op2 < 0x80) + { + if ((op2 & 0x0d) == 0x01) + { + util::stream_format(stream, "%-8s", BIT(op2, 1) ? "BF" : "BTCLR"); + u8 saddr = opcodes.r8(pc + 2); + if (saddr == 0x1e) + util::stream_format(stream, "%s,", s_psw_bits[(op2 & 0x70) >> 4]); + else + { + format_saddr(stream, saddr); + util::stream_format(stream, ".%d,", (op2 & 0x70) >> 4); + } + format_jdisp8(stream, pc + 4, opcodes.r8(pc + 3)); + return 4 | SUPPORTED; + } + else switch (op2 & 0x0f) + { + case 0x05: + util::stream_format(stream, "%-8s", "BTCLR"); + format_sfr(stream, opcodes.r8(pc + 2)); + util::stream_format(stream, ".%d,", (op2 & 0x70) >> 4); + format_jdisp8(stream, pc + 4, opcodes.r8(pc + 3)); + return 4 | SUPPORTED; + + case 0x06: + util::stream_format(stream, "%-8s", "BT"); + format_sfr(stream, opcodes.r8(pc + 2)); + util::stream_format(stream, ".%d,", (op2 & 0x70) >> 4); + format_jdisp8(stream, pc + 4, opcodes.r8(pc + 3)); + return 4 | SUPPORTED; + + case 0x07: + util::stream_format(stream, "%-8s", "BF"); + format_sfr(stream, opcodes.r8(pc + 2)); + util::stream_format(stream, ".%d,", (op2 & 0x70) >> 4); + format_jdisp8(stream, pc + 4, opcodes.r8(pc + 3)); + return 4 | SUPPORTED; + + case 0x0d: + util::stream_format(stream, "%-8sA.%d,", "BTCLR", (op2 & 0x70) >> 4); + format_jdisp8(stream, pc + 3, opcodes.r8(pc + 2)); + return 3 | SUPPORTED; + + case 0x0e: + util::stream_format(stream, "%-8sA.%d,", "BT", (op2 & 0x70) >> 4); + format_jdisp8(stream, pc + 3, opcodes.r8(pc + 2)); + return 3 | SUPPORTED; + + case 0x0f: + util::stream_format(stream, "%-8sA.%d,", "BF", (op2 & 0x70) >> 4); + format_jdisp8(stream, pc + 3, opcodes.r8(pc + 2)); + return 3 | SUPPORTED; + + default: + return dasm_illegal2(stream, 0x31, op2); + } + } + else if ((op2 & 0xef) == 0x80) + { + util::stream_format(stream, "%-8s[HL]", BIT(op2, 4) ? "ROR4" : "ROL4"); + return 2 | SUPPORTED; + } + else if (op2 == 0x82) + { + util::stream_format(stream, "%-8sC", "DIVUW"); + return 2 | SUPPORTED; + } + else if (op2 == 0x88) + { + util::stream_format(stream, "%-8sX", "MULU"); + return 2 | SUPPORTED; + } + else if (op2 == 0x98) + { + util::stream_format(stream, "%-8sAX", "BR"); + return 2 | SUPPORTED; + } + else switch (op2 & 0x0f) + { + case 0x05: + util::stream_format(stream, "%-8s[HL].%d,", "BTCLR", (op2 & 0x70) >> 4); + format_jdisp8(stream, pc + 3, opcodes.r8(pc + 2)); + return 3 | SUPPORTED; + + case 0x06: + util::stream_format(stream, "%-8s[HL].%d,", "BT", (op2 & 0x70) >> 4); + format_jdisp8(stream, pc + 3, opcodes.r8(pc + 2)); + return 3 | SUPPORTED; + + case 0x07: + util::stream_format(stream, "%-8s[HL].%d,", "BF", (op2 & 0x70) >> 4); + format_jdisp8(stream, pc + 3, opcodes.r8(pc + 2)); + return 3 | SUPPORTED; + + case 0x0a: case 0x0b: + if (op2 < 0x90) + { + util::stream_format(stream, "%-8sA,[HL+%s]", op2 < 0x80 ? s_alu_ops[(op2 & 0x70) >> 4] : "XCH", s_r_names[op2 & 0x07]); + return 2 | SUPPORTED; + } + else + return dasm_illegal2(stream, 0x31, op2); + + default: + return dasm_illegal2(stream, 0x31, op2); + } +} + +offs_t upd78k0_disassembler::dasm_61(std::ostream &stream, offs_t pc, const upd78k0_disassembler::data_buffer &opcodes) +{ + u8 op2 = opcodes.r8(pc + 1); + if (op2 < 0x80) + { + if ((op2 & 0x0f) != 0x09) + { + util::stream_format(stream, "%-8s", s_alu_ops[(op2 & 0x70) >> 4]); + if (BIT(op2, 3)) + util::stream_format(stream, "A,%s", s_r_names[op2 & 0x07]); + else + util::stream_format(stream, "%s,A", s_r_names[op2 & 0x07]); + return 2 | SUPPORTED; + } + else + return dasm_illegal2(stream, 0x61, op2); + } + else if ((op2 & 0xef) == 0x80) + { + util::stream_format(stream, "ADJB%c", BIT(op2, 4) ? 'S' : 'A'); + return 2 | SUPPORTED; + } + else if ((op2 & 0xd7) == 0xd0) + { + util::stream_format(stream, "%-8sRB%d", "SEL", (op2 & 0x20) >> 4 | (op2 & 0x08) >> 3); + return 2 | SUPPORTED; + } + else switch (op2 & 0x0f) + { + case 0x09: + util::stream_format(stream, "%-8sA.%d,CY", "MOV1", (op2 & 0x70) >> 4); + return 2 | SUPPORTED; + + case 0x0a: case 0x0b: + util::stream_format(stream, "%-8sA.%d", BIT(op2, 0) ? "CLR1" : "SET1", (op2 & 0x70) >> 4); + return 2 | SUPPORTED; + + case 0x0c: case 0x0d: case 0x0e: case 0x0f: + util::stream_format(stream, "%-8sCY,A.%d", s_bool_ops[op2 & 0x03], (op2 & 0x70) >> 4); + return 2 | SUPPORTED; + + default: + return dasm_illegal2(stream, 0x61, op2); + } +} + +offs_t upd78k0_disassembler::dasm_71(std::ostream &stream, offs_t pc, const upd78k0_disassembler::data_buffer &opcodes) +{ + u8 op2 = opcodes.r8(pc + 1); + if (op2 < 0x80) + { + if (op2 == 0x00) + { + stream << "STOP"; + return 2 | SUPPORTED; + } + else if (op2 == 0x10) + { + stream << "HALT"; + return 2 | SUPPORTED; + } + else switch (op2 & 0x0f) + { + case 0x01: + { + util::stream_format(stream, "%-8s", "MOV1"); + u8 saddr = opcodes.r8(pc + 2); + if (saddr == 0x1e) + stream << s_psw_bits[(op2 & 0x70) >> 4]; + else + { + format_saddr(stream, saddr); + util::stream_format(stream, ".%d", (op2 & 0x70) >> 4); + } + stream << ",CY"; + return 3 | SUPPORTED; + } + + case 0x04: case 0x05: case 0x06: case 0x07: + { + util::stream_format(stream, "%-8sCY,", s_bool_ops[op2 & 0x03]); + u8 saddr = opcodes.r8(pc + 2); + if (saddr == 0x1e) + stream << s_psw_bits[(op2 & 0x70) >> 4]; + else + { + format_saddr(stream, saddr); + util::stream_format(stream, ".%d", (op2 & 0x70) >> 4); + } + return 3 | SUPPORTED; + } + + case 0x09: + util::stream_format(stream, "%-8s", "MOV1"); + format_sfr(stream, opcodes.r8(pc + 2)); + util::stream_format(stream, ".%d,CY", (op2 & 0x70) >> 4); + return 3 | SUPPORTED; + + case 0x0a: case 0x0b: + util::stream_format(stream, "%-8s", BIT(op2, 0) ? "CLR1" : "SET1"); + format_sfr(stream, opcodes.r8(pc + 2)); + util::stream_format(stream, ".%d", (op2 & 0x70) >> 4); + return 3 | SUPPORTED; + + case 0x0c: case 0x0d: case 0x0e: case 0x0f: + util::stream_format(stream, "%-8sCY,", s_bool_ops[op2 & 0x03]); + format_sfr(stream, opcodes.r8(pc + 2)); + util::stream_format(stream, ".%d", (op2 & 0x70) >> 4); + return 3 | SUPPORTED; + + default: + return dasm_illegal2(stream, 0x71, op2); + } + } + else switch (op2 & 0x0f) + { + case 0x01: + util::stream_format(stream, "%-8s[HL].%d,CY", "MOV1", (op2 & 0x70) >> 4); + return 2 | SUPPORTED; + + case 0x02: case 0x03: + util::stream_format(stream, "%-8s[HL].%d", BIT(op2, 0) ? "CLR1" : "SET1", (op2 & 0x70) >> 4); + return 2 | SUPPORTED; + + case 0x04: case 0x05: case 0x06: case 0x07: + util::stream_format(stream, "%-8sCY,[HL].%d", s_bool_ops[op2 & 0x03], (op2 & 0x70) >> 4); + return 2 | SUPPORTED; + + default: + return dasm_illegal2(stream, 0x71, op2); + } +} + +offs_t upd78k0_disassembler::disassemble(std::ostream &stream, offs_t pc, const upd78k0_disassembler::data_buffer &opcodes, const upd78k0_disassembler::data_buffer ¶ms) +{ + u8 op = opcodes.r8(pc); + switch (op) + { + case 0x00: + stream << "NOP"; + return 1 | SUPPORTED; + + case 0x01: + util::stream_format(stream, "%-8sCY", "NOT1"); + return 1 | SUPPORTED; + + case 0x02: + util::stream_format(stream, "%-8sAX,", "MOVW"); + format_abs16(stream, opcodes.r16(pc + 1)); + return 3 | SUPPORTED; + + case 0x03: + util::stream_format(stream, "%-8s", "MOVW"); + format_abs16(stream, opcodes.r16(pc + 1)); + stream << ",AX"; + return 3 | SUPPORTED; + + case 0x04: + util::stream_format(stream, "%-8s", "DBNZ"); + format_saddr(stream, opcodes.r8(pc + 1)); + stream << ","; + format_jdisp8(stream, pc + 3, opcodes.r8(pc + 2)); + return 3 | SUPPORTED; + + case 0x05: case 0x07: + util::stream_format(stream, "%-8sA,[%s]", "XCH", s_rp_names[(op & 0x06) >> 1]); + return 1 | SUPPORTED; + + case 0x08: case 0x18: case 0x28: case 0x38: case 0x48: case 0x58: case 0x68: case 0x78: + util::stream_format(stream, "%-8sA,", s_alu_ops[(op & 0x70) >> 4]); + format_abs16(stream, opcodes.r16(pc + 1)); + return 3 | SUPPORTED; + + case 0x09: case 0x19: case 0x29: case 0x39: case 0x49: case 0x59: case 0x69: case 0x79: + util::stream_format(stream, "%-8sA,", s_alu_ops[(op & 0x70) >> 4]); + format_ix_disp8(stream, "HL", opcodes.r8(pc + 1)); + return 2 | SUPPORTED; + + case 0x0a: case 0x1a: case 0x2a: case 0x3a: case 0x4a: case 0x5a: case 0x6a: case 0x7a: + case 0x0b: case 0x1b: case 0x2b: case 0x3b: case 0x4b: case 0x5b: case 0x6b: case 0x7b: + { + u8 saddr = opcodes.r8(pc + 1); + if ((op & 0x70) == 0x70 && saddr == 0x1e) + util::stream_format(stream, "%cI", BIT(op, 0) ? 'D' : 'E'); + else + { + util::stream_format(stream, "%-8s", BIT(op, 0) ? "CLR1" : "SET1"); + if (saddr == 0x1e) + stream << s_psw_bits[(op & 0x70) >> 4]; + else + { + format_saddr(stream, saddr); + util::stream_format(stream, ".%d", (op & 0x70) >> 4); + } + } + return 2 | SUPPORTED; + } + + case 0x0c: case 0x1c: case 0x2c: case 0x3c: case 0x4c: case 0x5c: case 0x6c: case 0x7c: + util::stream_format(stream, "%-8s", "CALLF"); + format_abs16(stream, 0x0800 | u16(op & 0x70) << 4 | opcodes.r8(pc + 1)); + return 2 | STEP_OVER | SUPPORTED; + + case 0x0d: case 0x1d: case 0x2d: case 0x3d: case 0x4d: case 0x5d: case 0x6d: case 0x7d: + util::stream_format(stream, "%-8sA,", s_alu_ops[(op & 0x70) >> 4]); + format_imm8(stream, opcodes.r8(pc + 1)); + return 2 | SUPPORTED; + + case 0x0e: case 0x1e: case 0x2e: case 0x3e: case 0x4e: case 0x5e: case 0x6e: case 0x7e: + util::stream_format(stream, "%-8sA,", s_alu_ops[(op & 0x70) >> 4]); + format_saddr(stream, opcodes.r8(pc + 1)); + return 2 | SUPPORTED; + + case 0x0f: case 0x1f: case 0x2f: case 0x3f: case 0x4f: case 0x5f: case 0x6f: case 0x7f: + util::stream_format(stream, "%-8sA,[HL]", s_alu_ops[(op & 0x70) >> 4]); + return 1 | SUPPORTED; + + case 0x10: case 0x12: case 0x14: case 0x16: + util::stream_format(stream, "%-8s%s,", "MOVW", s_rp_names[(op & 0x06) >> 1]); + format_imm16(stream, opcodes.r16(pc + 1)); + return 3 | SUPPORTED; + + case 0x11: + { + util::stream_format(stream, "%-8s", "MOV"); + u8 saddr = opcodes.r8(pc + 1); + if (saddr == 0x1e) + stream << "PSW"; + else + format_saddr(stream, saddr); + stream << ","; + format_imm8(stream, opcodes.r8(pc + 2)); + return 3 | SUPPORTED; + } + + case 0x13: + util::stream_format(stream, "%-8s", "MOV"); + format_sfr(stream, opcodes.r8(pc + 1)); + stream << ","; + format_imm8(stream, opcodes.r8(pc + 2)); + return 3 | SUPPORTED; + + case 0x20: case 0x21: + util::stream_format(stream, "%-8sCY", BIT(op, 0) ? "CLR1" : "SET1"); + return 1 | SUPPORTED; + + case 0x22: case 0x23: + util::stream_format(stream, "%-8sPSW", BIT(op, 0) ? "POP" : "PUSH"); + return 1 | SUPPORTED; + + case 0x24: case 0x26: + util::stream_format(stream, "%-8sA,1", BIT(op, 1) ? "ROL" : "ROR"); + return 1 | SUPPORTED; + + case 0x25: case 0x27: + util::stream_format(stream, "%-8sA,1", BIT(op, 1) ? "ROLC" : "RORC"); + return 1 | SUPPORTED; + + case 0x30: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: + util::stream_format(stream, "%-8sA,%s", "XCH", s_r_names[op & 0x07]); + return 1 | SUPPORTED; + + case 0x31: + return dasm_31(stream, pc, opcodes); + + case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: + case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57: + util::stream_format(stream, "%-8s%s", BIT(op, 4) ? "DEC" : "INC", s_r_names[op & 0x07]); + return 1 | SUPPORTED; + + case 0x60: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: + util::stream_format(stream, "%-8sA,%s", "MOV", s_r_names[op & 0x07]); + return 1 | SUPPORTED; + + case 0x61: + return dasm_61(stream, pc, opcodes); + + case 0x70: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77: + util::stream_format(stream, "%-8s%s,A", "MOV", s_r_names[op & 0x07]); + return 1 | SUPPORTED; + + case 0x71: + return dasm_71(stream, pc, opcodes); + + case 0x80: case 0x82: case 0x84: case 0x86: + case 0x90: case 0x92: case 0x94: case 0x96: + util::stream_format(stream, "%-8s%s", BIT(op, 4) ? "DECW" : "INCW", s_rp_names[(op & 0x06) >> 1]); + return 1 | SUPPORTED; + + case 0x81: case 0x91: + util::stream_format(stream, "%-8s", BIT(op, 4) ? "DEC" : "INC"); + format_saddr(stream, opcodes.r8(pc + 1)); + return 2 | SUPPORTED; + + case 0x83: case 0x93: + util::stream_format(stream, "%-8sA,", "XCH"); + if (BIT(op, 4)) + format_sfr(stream, opcodes.r8(pc + 1)); + else + format_saddr(stream, opcodes.r8(pc + 1)); + return 2 | SUPPORTED; + + case 0x85: case 0x87: + util::stream_format(stream, "%-8sA,[%s]", "MOV", s_rp_names[(op & 0x06) >> 1]); + return 1 | SUPPORTED; + + case 0x88: case 0x98: case 0xa8: case 0xb8: case 0xc8: case 0xd8: case 0xe8: case 0xf8: + util::stream_format(stream, "%-8s", s_alu_ops[(op & 0x70) >> 4]); + format_saddr(stream, opcodes.r8(pc + 1)); + stream << ","; + format_imm8(stream, opcodes.r8(pc + 2)); + return 3 | SUPPORTED; + + case 0x89: + { + util::stream_format(stream, "%-8sAX,", "MOVW"); + u8 saddrp = opcodes.r8(pc + 1); + if (saddrp == 0x1c) + stream << "SP"; + else + format_saddrp(stream, saddrp); + return 2 | SUPPORTED; + } + + case 0x8a: case 0x8b: + util::stream_format(stream, "%-8s%s,", "DBNZ", s_r_names[op & 0x07]); + format_jdisp8(stream, pc + 2, opcodes.r8(pc + 1)); + return 2 | SUPPORTED; + + case 0x8c: case 0x9c: case 0xac: case 0xbc: case 0xcc: case 0xdc: case 0xec: case 0xfc: + { + util::stream_format(stream, "%-8s", "BT"); + u8 saddr = opcodes.r8(pc + 1); + if (saddr == 0x1e) + util::stream_format(stream, "%s,", s_psw_bits[(op & 0x70) >> 4]); + else + { + format_saddr(stream, saddr); + util::stream_format(stream, ".%d,", (op & 0x70) >> 4); + } + format_jdisp8(stream, pc + 3, opcodes.r8(pc + 2)); + return 3 | SUPPORTED; + } + + case 0x8d: case 0x9d: + util::stream_format(stream, "%-8s", BIT(op, 4) ? "BNC" : "BC"); + format_jdisp8(stream, pc + 2, opcodes.r8(pc + 1)); + return 2 | SUPPORTED; + + case 0x8e: + util::stream_format(stream, "%-8sA,", "MOV"); + format_abs16(stream, opcodes.r16(pc + 1)); + return 3 | SUPPORTED; + + case 0x8f: case 0x9f: + util::stream_format(stream, "RET%c", BIT(op, 4) ? 'B' : 'I'); + return 2 | STEP_OUT | SUPPORTED; + + case 0x95: case 0x97: + util::stream_format(stream, "%-8s[%s],A", "MOV", s_rp_names[(op & 0x06) >> 1]); + return 1 | SUPPORTED; + + case 0x99: + { + util::stream_format(stream, "%-8s", "MOVW"); + u8 saddrp = opcodes.r8(pc + 1); + if (saddrp == 0x1c) + stream << "SP"; + else + format_saddrp(stream, saddrp); + stream << ",AX"; + return 2 | SUPPORTED; + } + + case 0x9a: + util::stream_format(stream, "%-8s", "CALL"); + format_abs16(stream, opcodes.r16(pc + 1)); + return 3 | STEP_OVER | SUPPORTED; + + case 0x9b: + util::stream_format(stream, "%-8s", "BR"); + format_abs16(stream, opcodes.r16(pc + 1)); + return 3 | SUPPORTED; + + case 0x9e: + util::stream_format(stream, "%-8s", "MOV"); + format_abs16(stream, opcodes.r16(pc + 1)); + stream << ",A"; + return 3 | SUPPORTED; + + case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7: + util::stream_format(stream, "%-8s%s,", "MOV", s_r_names[op & 0x07]); + format_imm8(stream, opcodes.r8(pc + 1)); + return 2 | SUPPORTED; + + case 0xa9: + util::stream_format(stream, "%-8sAX,", "MOVW"); + format_sfrp(stream, opcodes.r8(pc + 1)); + return 2 | SUPPORTED; + + case 0xaa: case 0xab: + util::stream_format(stream, "%-8sA,[HL+%s]", "MOV", s_r_names[op & 0x07]); + return 1 | SUPPORTED; + + case 0xad: case 0xbd: + util::stream_format(stream, "%-8s", BIT(op, 4) ? "BNZ" : "BZ"); + format_jdisp8(stream, pc + 2, opcodes.r8(pc + 1)); + return 2 | SUPPORTED; + + case 0xae: + util::stream_format(stream, "%-8sA,", "MOV"); + format_ix_disp8(stream, "HL", opcodes.r8(pc + 1)); + return 2 | SUPPORTED; + + case 0xaf: + stream << "RET"; + return 1 | STEP_OUT | SUPPORTED; + + case 0xb0: case 0xb2: case 0xb4: case 0xb6: + util::stream_format(stream, "%-8s%s", "POP", s_rp_names[(op & 0x06) >> 1]); + return 1 | SUPPORTED; + + case 0xb1: case 0xb3: case 0xb5: case 0xb7: + util::stream_format(stream, "%-8s%s", "PUSH", s_rp_names[(op & 0x06) >> 1]); + return 1 | SUPPORTED; + + case 0xb9: + util::stream_format(stream, "%-8s", "MOVW"); + format_sfrp(stream, opcodes.r8(pc + 1)); + stream << ",AX"; + return 2 | SUPPORTED; + + case 0xba: case 0xbb: + util::stream_format(stream, "%-8s[HL+%s],A", "MOV", s_r_names[op & 0x07]); + return 1 | SUPPORTED; + + case 0xbe: + util::stream_format(stream, "%-8s", "MOV"); + format_ix_disp8(stream, "HL", opcodes.r8(pc + 1)); + stream << ",A"; + return 2 | SUPPORTED; + + case 0xbf: + stream << "BRK"; + return 1 | STEP_OVER | SUPPORTED; + + case 0xc1: case 0xc3: case 0xc5: case 0xc7: case 0xc9: case 0xcb: case 0xcd: case 0xcf: + case 0xd1: case 0xd3: case 0xd5: case 0xd7: case 0xd9: case 0xdb: case 0xdd: case 0xdf: + case 0xe1: case 0xe3: case 0xe5: case 0xe7: case 0xe9: case 0xeb: case 0xed: case 0xef: + case 0xf1: case 0xf3: case 0xf5: case 0xf7: case 0xf9: case 0xfb: case 0xfd: case 0xff: + util::stream_format(stream, "%-8s[%04XH]", "CALLT", u16(op & 0x7e)); + return 1 | STEP_OVER | SUPPORTED; + + case 0xc2: case 0xc4: case 0xc6: + case 0xe2: case 0xe4: case 0xe6: + util::stream_format(stream, "%-8sAX,%s", BIT(op, 5) ? "XCHW" : "MOVW", s_rp_names[(op & 0x06) >> 1]); + return 1 | SUPPORTED; + + case 0xca: + util::stream_format(stream, "%-8sAX,", "ADDW"); + format_imm16(stream, opcodes.r16(pc + 1)); + return 3 | SUPPORTED; + + case 0xce: + util::stream_format(stream, "%-8sA,", "XCH"); + format_abs16(stream, opcodes.r16(pc + 1)); + return 3 | SUPPORTED; + + case 0xd2: case 0xd4: case 0xd6: + util::stream_format(stream, "%-8s%s,AX", "MOVW", s_rp_names[(op & 0x06) >> 1]); + return 1 | SUPPORTED; + + case 0xda: + util::stream_format(stream, "%-8sAX,", "SUBW"); + format_imm16(stream, opcodes.r16(pc + 1)); + return 3 | SUPPORTED; + + case 0xde: + util::stream_format(stream, "%-8s", "XCH"); + format_ix_disp8(stream, "HL", opcodes.r8(pc + 1)); + stream << ",A"; + return 2 | SUPPORTED; + + case 0xea: + util::stream_format(stream, "%-8sAX,", "CMPW"); + format_imm16(stream, opcodes.r16(pc + 1)); + return 3 | SUPPORTED; + + case 0xee: + { + util::stream_format(stream, "%-8s", "MOVW"); + u8 saddrp = opcodes.r8(pc + 1); + if (saddrp == 0x1c) + stream << "SP"; + else + format_saddrp(stream, saddrp); + stream << ","; + format_imm16(stream, opcodes.r16(pc + 2)); + return 4 | SUPPORTED; + } + + case 0xf0: + { + util::stream_format(stream, "%-8sA,", "MOV"); + u8 saddr = opcodes.r8(pc + 1); + if (saddr == 0x1e) + stream << "PSW"; + else + format_saddr(stream, saddr); + return 2 | SUPPORTED; + } + + case 0xf2: + { + util::stream_format(stream, "%-8s", "MOV"); + u8 saddr = opcodes.r8(pc + 1); + if (saddr == 0x1e) + stream << "PSW"; + else + format_saddr(stream, saddr); + stream << ",A"; + return 2 | SUPPORTED; + } + + case 0xf4: + util::stream_format(stream, "%-8sA,", "MOV"); + format_sfr(stream, opcodes.r8(pc + 1)); + return 2 | SUPPORTED; + + case 0xf6: + util::stream_format(stream, "%-8s", "MOV"); + format_sfr(stream, opcodes.r8(pc + 1)); + stream << ",A"; + return 2 | SUPPORTED; + + case 0xfa: + util::stream_format(stream, "%-8s", "BR"); + format_jdisp8(stream, pc + 2, opcodes.r8(pc + 1)); + return 2 | SUPPORTED; + + case 0xfe: + util::stream_format(stream, "%-8s", "MOVW"); + format_sfrp(stream, opcodes.r8(pc + 1)); + stream << ","; + format_imm16(stream, opcodes.r16(pc + 2)); + return 4 | SUPPORTED; + + default: + return dasm_illegal(stream, op); + } +} + +const char *const upd78k0_disassembler::s_common_sfrp_names[128] = +{ + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "CR00", "CR01", "TM0", nullptr, "TMS", 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, 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, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "IF0", nullptr, "MK0", nullptr, "PR0", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr +}; + +upd78014_disassembler::upd78014_disassembler() + : upd78k0_disassembler(s_sfr_names, s_common_sfrp_names) +{ +} + +const char *const upd78014_disassembler::s_sfr_names[256] = +{ + "P0", "P1", "P2", "P3", "P4", "P5", "P6", nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "CR10", "CR20", + "TM1", "TM2", "SIO0", "SIO1", nullptr, nullptr, nullptr, "ADCR", + "PM0", "PM1", "PM2", "PM3", nullptr, "PM5", "PM6", 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, + "TCL0", "TCL1", "TCL2", "TCL3", nullptr, nullptr, nullptr, "SCS", + "TMC0", "TMC1", "TMC2", nullptr, nullptr, nullptr, "TOC0", "TOC1", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "CSIM0", "SBIC", "SVA", "SINT", nullptr, nullptr, nullptr, nullptr, + "CSIM1", "ADTC", "ADTP", nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "ADM", nullptr, nullptr, nullptr, "ADIS", 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, 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, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "IF0L", "IF0H", nullptr, nullptr, "MK0L", "MK0H", nullptr, nullptr, + "PR0L", "PR0H", nullptr, nullptr, "INTM0", nullptr, nullptr, nullptr, + "IMS", nullptr, nullptr, nullptr, nullptr, nullptr, "KRM", "PUO", + "MM", "WDTM", "OSTS", "PCC", nullptr, nullptr, nullptr, nullptr +}; + +upd78024_disassembler::upd78024_disassembler() + : upd78k0_disassembler(s_sfr_names, s_common_sfrp_names) +{ +} + +const char *const upd78024_disassembler::s_sfr_names[256] = +{ + "P0", "P1", "P2", "P3", nullptr, nullptr, nullptr, nullptr, + "P8", "P9", "P10", "P11", nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "CR10", "CR20", + "TM1", "TM2", "SIO0", "SIO1", nullptr, nullptr, nullptr, "ADCR", + "PM0", "PM1", "PM2", "PM3", nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, "PM11", nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "TCL0", "TCL1", "TCL2", "TCL3", nullptr, nullptr, nullptr, "SCS", + "TMC0", "TMC1", "TMC2", nullptr, nullptr, nullptr, "TOC0", "TOC1", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "CSIM0", "SBIC", "SVA", "SINT", nullptr, nullptr, nullptr, nullptr, + "CSIM1", 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, nullptr, "ADIS", 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, + "DSPM0", "DSPM1", 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, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "IF0L", "IF0H", nullptr, nullptr, "MK0L", "MK0H", nullptr, nullptr, + "PR0L", "PR0H", nullptr, nullptr, "INTM0", nullptr, nullptr, nullptr, + "IMS", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "PUO", + nullptr, "WDTM", "OSTS", "PCC", nullptr, nullptr, nullptr, nullptr +}; + +upd78044a_disassembler::upd78044a_disassembler() + : upd78k0_disassembler(s_sfr_names, s_common_sfrp_names) +{ +} + +const char *const upd78044a_disassembler::s_sfr_names[256] = +{ + "P0", "P1", "P2", "P3", nullptr, nullptr, nullptr, "P7", + "P8", "P9", "P10", "P11", "P12", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "CR10", "CR20", + "TM1", "TM2", "SIO0", "SIO1", nullptr, nullptr, nullptr, "ADCR", + "PM0", "PM1", "PM2", "PM3", nullptr, nullptr, nullptr, "PM7", + nullptr, nullptr, nullptr, "PM11", "PM12", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "TCL0", "TCL1", "TCL2", "TCL3", nullptr, nullptr, nullptr, "SCS", + "TMC0", "TMC1", "TMC2", nullptr, nullptr, nullptr, "TOC0", "TOC1", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "CSIM0", "SBIC", "SVA", "SINT", nullptr, nullptr, nullptr, nullptr, + "CSIM1", "ADTC", "ADTP", "ADTI", nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "ADM", nullptr, nullptr, nullptr, "ADIS", 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, + "DSPM0", "DSPM1", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "UDM", "UDC", "UDCC", 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, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "IF0L", "IF0H", nullptr, nullptr, "MK0L", "MK0H", nullptr, nullptr, + "PR0L", "PR0H", nullptr, nullptr, "INTM0", nullptr, nullptr, nullptr, + "IMS", nullptr, nullptr, nullptr, "IXS", nullptr, nullptr, "PUO", + nullptr, "WDTM", "OSTS", "PCC", nullptr, nullptr, nullptr, nullptr +}; + +upd78054_disassembler::upd78054_disassembler() + : upd78k0_disassembler(s_sfr_names, s_common_sfrp_names) +{ +} + +const char *const upd78054_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, "CR10", "CR20", + "TM1", "TM2", "SIO0", "SIO1", nullptr, nullptr, nullptr, "ADCR", + "PM0", "PM1", "PM2", "PM3", nullptr, "PM5", "PM6", "PM7", + nullptr, nullptr, nullptr, nullptr, "PM12", "PM13", nullptr, nullptr, + "RTBL", "RTBH", nullptr, nullptr, "RTPM", nullptr, "RTPC", nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "TCL0", "TCL1", "TCL2", "TCL3", nullptr, nullptr, nullptr, "SCS", + "TMC0", "TMC1", "TMC2", nullptr, "CRC0", nullptr, "TOC0", "TOC1", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "CSIM0", "SBIC", "SVA", "SINT", nullptr, nullptr, nullptr, nullptr, + "CSIM1", "ADTC", "ADTP", "ADTI", nullptr, nullptr, nullptr, nullptr, + "ASIM", "ASIS", "CSIM2", "BRGC", "SIO2", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "ADM", nullptr, nullptr, nullptr, "ADIS", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "DACS0", "DACS1", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "DAM", 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, 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, + "IF0L", "IF0H", "IF1L", nullptr, "MK0L", "MK0H", "MK1L", nullptr, + "PR0L", "PR0H", "PR1L", nullptr, "INTM0", "INTM1", nullptr, nullptr, + "IMS", nullptr, "OSMS", "PUOH", nullptr, nullptr, "KRM", "PUOL", + "MM", "WDTM", "OSTS", "PCC", nullptr, nullptr, nullptr, nullptr +}; + +upd78064_disassembler::upd78064_disassembler() + : upd78k0_disassembler(s_sfr_names, s_common_sfrp_names) +{ +} + +const char *const upd78064_disassembler::s_sfr_names[256] = +{ + "P0", "P1", "P2", "P3", nullptr, nullptr, nullptr, "P7", + "P8", "P9", "P10", "P11", nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "CR10", "CR20", + "TM1", "TM2", "SIO0", "SIO1", nullptr, nullptr, nullptr, "ADCR", + "PM0", "PM1", "PM2", "PM3", nullptr, nullptr, nullptr, "PM7", + "PM8", "PM9", "PM10", "PM11", nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "TCL0", "TCL1", "TCL2", "TCL3", nullptr, nullptr, nullptr, "SCS", + "TMC0", "TMC1", "TMC2", nullptr, "CRC0", nullptr, "TOC0", "TOC1", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "CSIM0", "SBIC", "SVA", "SINT", nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "ASIM", "ASIS", "CSIM2", "BRGC", "SIO2", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "ADM", nullptr, nullptr, nullptr, "ADIS", 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, nullptr, nullptr, nullptr, + "LDCM", nullptr, "LCDC", nullptr, nullptr, nullptr, nullptr, nullptr, + "KRM", 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, + "IF0L", "IF0H", "IF1L", nullptr, "MK0L", "MK0H", "MK1L", nullptr, + "PR0L", "PR0H", "PR1L", nullptr, "INTM0", "INTM1", nullptr, nullptr, + "IMS", nullptr, "OSMS", "PUOH", nullptr, nullptr, nullptr, "PUOL", + nullptr, "WDTM", "OSTS", "PCC", nullptr, nullptr, nullptr, nullptr +}; + +upd78078_disassembler::upd78078_disassembler() + : upd78k0_disassembler(s_sfr_names, s_sfrp_names) +{ +} + +const char *const upd78078_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, "CR10", "CR20", + "TM1", "TM2", "SIO0", "SIO1", nullptr, nullptr, nullptr, "ADCR", + "PM0", "PM1", "PM2", "PM3", nullptr, "PM5", "PM6", "PM7", + "PM8", "PM9", "PM10", nullptr, "PM12", "PM13", nullptr, nullptr, + "RTBL", "RTBH", nullptr, nullptr, "RTPM", nullptr, "RTPC", nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "EBTS", + "TCL0", "TCL1", "TCL2", "TCL3", nullptr, nullptr, nullptr, "SCS", + "TMC0", "TMC1", "TMC2", nullptr, "CRC0", nullptr, "TOC0", "TOC1", + "CR50", "TM5", "TCL5", "TMC5", "CR60", "TM6", "TCL6", "TMC6", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "CSIM0", "SBIC", "SVA", "SINT", nullptr, nullptr, nullptr, nullptr, + "CSIM1", "ADTC", "ADTP", "ADTI", nullptr, nullptr, nullptr, nullptr, + "ASIM", "ASIS", "CSIM2", "BRGC", "SIO2", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "ADM", nullptr, nullptr, nullptr, "ADIS", nullptr, nullptr, nullptr, + nullptr, nullptr, "CORCN", nullptr, nullptr, nullptr, nullptr, nullptr, + "DACS0", "DACS1", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "DAM", 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, 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, + "IF0L", "IF0H", "IF1L", nullptr, "MK0L", "MK0H", "MK1L", nullptr, + "PR0L", "PR0H", "PR1L", nullptr, "INTM0", "INTM1", nullptr, nullptr, + "IMS", nullptr, "OSMS", "PUOH", "IXS", nullptr, "KRM", "PUOL", + "MM", "WDTM", "OSTS", "PCC", nullptr, nullptr, nullptr, nullptr +}; + +const char *const upd78078_disassembler::s_sfrp_names[128] = +{ + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "CR00", "CR01", "TM0", nullptr, "TMS", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, "CORAD0", "CORAD1", 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, 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, nullptr, nullptr, + "IF0", nullptr, "MK0", nullptr, "PR0", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr +}; + +upd78083_disassembler::upd78083_disassembler() + : upd78k0_disassembler(s_sfr_names, s_sfrp_names) +{ +} + +const char *const upd78083_disassembler::s_sfr_names[256] = +{ + "P0", "P1", nullptr, "P3", nullptr, "P5", nullptr, "P7", + nullptr, nullptr, "P10", nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "ADCR", + "PM0", "PM1", nullptr, "PM3", nullptr, "PM5", nullptr, "PM7", + nullptr, nullptr, "PM10", nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "TCL0", nullptr, "TCL2", nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "CR50", "TM5", "TCL5", "TMC5", "CR60", "TM6", "TCL6", "TMC6", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "ASIM", "ASIS", "CSIM2", "BRGC", "SIO2", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "ADM", nullptr, nullptr, nullptr, "ADIS", 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, 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, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "IF0L", "IF0H", "IF1L", nullptr, "MK0L", "MK0H", "MK1L", nullptr, + "PR0L", "PR0H", "PR1L", nullptr, "INTM0", "INTM1", nullptr, nullptr, + "IMS", nullptr, "OSMS", "PUOH", nullptr, nullptr, nullptr, "PUOL", + nullptr, "WDTM", "OSTS", "PCC", nullptr, nullptr, nullptr, nullptr +}; + +const char *const upd78083_disassembler::s_sfrp_names[128] = +{ + 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, + 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, + 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, + "IF0", nullptr, "MK0", nullptr, "PR0", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr +}; + +upd780024a_disassembler::upd780024a_disassembler() + : upd78k0_disassembler(s_sfr_names, s_sfrp_names) +{ +} + +const char *const upd780024a_disassembler::s_sfr_names[256] = +{ + "P0", "P1", "P2", "P3", "P4", "P5", nullptr, "P7", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "CR50", "CR51", "TM50", "TM51", nullptr, nullptr, nullptr, nullptr, + "SIO0", nullptr, "SIO30", "SIO31", nullptr, nullptr, nullptr, nullptr, + "PM0", nullptr, "PM2", "PM3", "PM4", "PM5", nullptr, "PM7", + nullptr, nullptr, nullptr, "PM11", nullptr, nullptr, nullptr, nullptr, + "PU0", nullptr, "PU2", "PU3", "PU4", "PU5", nullptr, "PU7", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "CKS", "WTM", "WDCS", nullptr, nullptr, nullptr, nullptr, "MEM", + "EGP", "EGN", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "TMC0", "PRM0", "CRC0", "TOC0", nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "TMC50", "TCL50", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "TMC51", "TCL51", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "ADM0", "ADS0", 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, + "ASIM0", "ASIM1", "BRGC0", nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "CSIM30", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "CSIM31", 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, + "IF0L", "IF0H", "IF1L", nullptr, "MK0L", "MK0H", "MK1L", nullptr, + "PR0L", "PR0H", "PR1L", nullptr, nullptr, nullptr, nullptr, nullptr, + "IMS", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, "WDTM", "OSTS", "PCC", nullptr, nullptr, nullptr, nullptr +}; + +const char *const upd780024a_disassembler::s_sfrp_names[128] = +{ + nullptr, nullptr, nullptr, nullptr, nullptr, "CR00", "CR01", "TM0", + nullptr, "TM5", nullptr, "ADCR0", 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, 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, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "IF0", nullptr, "MK0", nullptr, "PR0", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr +}; + +upd780065_disassembler::upd780065_disassembler() + : upd78k0_disassembler(s_sfr_names, s_sfrp_names) +{ +} + +const char *const upd780065_disassembler::s_sfr_names[256] = +{ + "P0", nullptr, "P2", "P3", "P4", "P5", "P6", "P7", + "P8", "P9", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "CR50", "CR51", "TM50", "TM51", nullptr, "ADCR0", nullptr, "SIO1", + "SIO30", "SIO31", "SIO0", nullptr, nullptr, nullptr, nullptr, "ADCR", + "PM0", nullptr, "PM2", "PM3", "PM4", "PM5", "PM6", "PM7", + "PM8", "PM9", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "PU0", nullptr, "PU2", "PU3", "PU4", "PU5", "PU6", "PU7", + "PU8", "PU9", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "CKS", "WTM", "WDCS", nullptr, nullptr, nullptr, nullptr, "MEM", + "EGP", "EGN", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "TMC0", "PRM0", "CRC0", "TOC0", nullptr, nullptr, nullptr, nullptr, + "CSIM1", "ADTC0", "ADTP0", "ADTI0", nullptr, nullptr, nullptr, nullptr, + "TMC50", "TCL50", "TMC51", "TCL51", nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "ADM0", "ADS0", 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, + "ASIM0", "ASIS1", "BRGC0", nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "CSIM0", "CSIM31", 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, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "IF0L", "IF0H", "IF1L", nullptr, "MK0L", "MK0H", "MK1L", nullptr, + "PR0L", "PR0H", "PR1L", nullptr, nullptr, nullptr, nullptr, nullptr, + "IMS", nullptr, nullptr, nullptr, "IXS", nullptr, nullptr, nullptr, + "MM", "WDTM", "OSTS", "PCC", nullptr, nullptr, nullptr, nullptr +}; + +const char *const upd780065_disassembler::s_sfrp_names[128] = +{ + nullptr, nullptr, nullptr, nullptr, nullptr, "CR00", "CR01", "TM0", + nullptr, "TM5", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, "CORAD0", "CORAD1", 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, 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, nullptr, nullptr, + "IF0", nullptr, "MK0", nullptr, "PR0", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr +}; + +upd780988_disassembler::upd780988_disassembler() + : upd78k0_disassembler(s_sfr_names, s_sfrp_names) +{ +} + +const char *const upd780988_disassembler::s_sfr_names[256] = +{ + "P0", "P1", "P2", "P3", "P4", "P5", "P6", "TM52", + "BFCM0L", nullptr, "BFCM1L", nullptr, "BFCM2L", nullptr, "BFCM3", nullptr, + nullptr, nullptr, nullptr, nullptr, "TM50", "TM51", "CR50", "CR51", + nullptr, nullptr, "SIO00", "SIO01", nullptr, nullptr, nullptr, "SIO3", + "PM0", nullptr, "PM2", "PM3", "PM4", "PM5", "PM6", nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "PU0", nullptr, "PU2", "PU3", "PU4", "PU5", "PU6", nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, "WDCS", nullptr, nullptr, nullptr, nullptr, "MEM", + "EGP", "EGN", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "TMC00", "PRM00", "CRC00", "TOC00", nullptr, nullptr, nullptr, nullptr, + "TMC01", "PRM01", "CRC01", "TOC01", nullptr, nullptr, nullptr, nullptr, + "TMC50", "TCL50", nullptr, nullptr, "TMC51", "TCL51", nullptr, nullptr, + "TMC52", "TCL52", "CR52", nullptr, "EGP5", "EGN5", nullptr, nullptr, + "ADM0", "ADS0", nullptr, nullptr, "RTBL00", "RTBH00", "RTPM00", "RTPC00", + nullptr, "FLPMC", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "TMC7", "TMM7", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, "DTIME", nullptr, "RTBL01", "RTBH01", "RTPM01", "RTPC01", + "ASIM00", "ASIS00", "BRGC00", nullptr, nullptr, nullptr, nullptr, nullptr, + "ASIM01", "ASIS01", "BRGC01", nullptr, nullptr, nullptr, nullptr, nullptr, + "CSIM3", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "DCCTL0", nullptr, nullptr, nullptr, "DCCTL1", 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, + "IF0L", "IF0H", "IF1L", nullptr, "MK0L", "MK0H", "MK1L", nullptr, + "PR0L", "PR0H", "PR1L", nullptr, nullptr, nullptr, nullptr, nullptr, + "IMS", nullptr, nullptr, nullptr, "IXS", nullptr, nullptr, nullptr, + "MM", "WDTM", "OSTS", "PCC", nullptr, nullptr, nullptr, nullptr +}; + +const char *const upd780988_disassembler::s_sfrp_names[128] = +{ + nullptr, nullptr, nullptr, nullptr, "BFCM0", "BFCM1", "BFCM2", "BFCM3", + "TM00", "TM01", "TM5", "CR5", "ADCR0", 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, "CR000", "CR010", nullptr, nullptr, "CR001", "CR011", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, "CM0", "CM1", "CM2", "CM3", 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, + "IF0", nullptr, "MK0", nullptr, "PR0", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr +}; + +upd78k0kx1_disassembler::upd78k0kx1_disassembler() + : upd78k0_disassembler(s_sfr_names, s_sfrp_names) +{ +} + +const char *const upd78k0kx1_disassembler::s_sfr_names[256] = +{ + "P0", "P1", "P2", "P3", "P4", "P5", "P6", "P7", + nullptr, nullptr, "RXB6", "TXB6", "P12", "P13", "P14", "SIO10", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "TM50", "CR50", + "CMP00", "CMP10", "CMP01", "CMP11", nullptr, nullptr, nullptr, "TM51", + "PM0", "PM1", nullptr, "PM3", "PM4", "PM5", "PM6", "PM7", + "ADM", "ADS", "PFM", "PFT", "PM12", nullptr, "PM14", nullptr, + "PU0", "PU1", nullptr, "PU3", "PU4", "PU5", "PU6", "PU7", + nullptr, nullptr, nullptr, nullptr, "PU12", nullptr, "PU14", nullptr, + "CKS", "CR51", nullptr, "TMC51", nullptr, nullptr, nullptr, "MEM", + "EGP", "EGN", "SIO11", nullptr, "SOTB11", nullptr, nullptr, "ISC", + "ASIM6", nullptr, nullptr, "ASIS6", nullptr, "ASIF6", "CKSR6", "BRGC6", + "ASICL6", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "SDR0L", "SDR0H", "MDA0LL", "MDA0LH", "MDA0HL", "MDA0HH", "MDB0L", "MDB0H", + "DMUC0", "TMHMD0", "TCL50", "TMC50", "TMHMD1", "TMCYC1", "KRM", "WTM", + "ASIM0", "BRGC0", "RXB0", "ASIS0", "TXS0", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "CSIM10", "CSIC10", nullptr, nullptr, "SOTB10", nullptr, nullptr, nullptr, + "CSIM11", "CSIC11", nullptr, nullptr, "TCL51", nullptr, nullptr, nullptr, + "CSIMA0", "CSIS0", "CSIT0", "BRGAC0", "ADTP0", "ADTI0", "SIOA0", "ADTC3", + "WDTM", "WDTE", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "RCM", "MCM", "MOC", "OSTC", "OSTS", nullptr, nullptr, nullptr, + nullptr, "CLM", nullptr, nullptr, "RESF", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "TMC01", "PRM01", + "CRC01", "TOC01", "TMC00", "PRM00", "CRC00", "TOC00", "LVIM", "LVIS", + 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, + "IF0L", "IF0H", "IF1L", "IF1H", "MK0L", "MK0H", "MK1L", "MK1H", + "PR0L", "PR0H", "PR1L", "PR1H", nullptr, nullptr, nullptr, nullptr, + "IMS", nullptr, nullptr, nullptr, "IXS", nullptr, nullptr, nullptr, + "MM", nullptr, nullptr, "PCC", nullptr, nullptr, nullptr, nullptr +}; + +const char *const upd78k0kx1_disassembler::s_sfrp_names[128] = +{ + nullptr, nullptr, nullptr, nullptr, "ADCR", nullptr, nullptr, nullptr, + "TM00", "CR000", "CR010", 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, + "SDR0", "MDA0L", "MDA0H", "MDB0", 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, + "TM01", "CR001", "CR011", nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "IF0", "IF1", "MK0", "MK1", "PR0", "PR1", nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr +}; + +upd78k0kx2_disassembler::upd78k0kx2_disassembler() + : upd78k0_disassembler(s_sfr_names, s_sfrp_names) +{ +} + +const char *const upd78k0kx2_disassembler::s_sfr_names[256] = +{ + "P0", "P1", "P2", "P3", "P4", "P5", "P6", "P7", + nullptr, "ADCRH", "RXB6", "TXB6", "P12", "P13", "P14", "SIO10", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "TM50", "CR50", + "CMP00", "CMP10", "CMP01", "CMP11", nullptr, nullptr, nullptr, "TM51", + "PM0", "PM1", "PM2", "PM3", "PM4", "PM5", "PM6", "PM7", + "ADM", "ADS", nullptr, nullptr, "PM12", nullptr, "PM14", "ADPC", + "PU0", "PU1", nullptr, "PU3", "PU4", "PU5", "PU6", "PU7", + nullptr, nullptr, nullptr, nullptr, "PU12", nullptr, "PU14", nullptr, + "CKS", "CR51", nullptr, "TMC51", nullptr, nullptr, nullptr, nullptr, + "EGP", "EGN", "SIO11", nullptr, "SOTB11", nullptr, nullptr, "ISC", + "ASIM6", nullptr, nullptr, "ASIS6", nullptr, "ASIF6", "CKSR6", "BRGC6", + "ASICL6", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "SDR0L", "SDR0H", "MDA0LL", "MDA0LH", "MDA0HL", "MDA0HH", "MDB0L", "MDB0H", + "DMUC0", "TMHMD0", "TCL50", "TMC50", "TMHMD1", "TMCYC1", "KRM", "WTM", + "ASIM0", "BRGC0", "RXB0", "ASIS0", "TXS0", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "CSIM10", "CSIC10", nullptr, nullptr, "SOTB10", nullptr, nullptr, nullptr, + "CSIM11", "CSIC11", nullptr, nullptr, "TCL51", nullptr, nullptr, nullptr, + "CSIMA0", "CSIS0", "CSIT0", "BRGAC0", "ADTP0", "ADTI0", "SIOA0", "ADTC3", + nullptr, "WDTE", nullptr, nullptr, nullptr, nullptr, nullptr, "OSCCTL", + "RCM", "MCM", "MOC", "OSTC", "OSTS", "IIC0", "IICC0", "SVA0", + "IICCL0", "IICX0", "IICS0", "IICF0", "RESF", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "TMC01", "PRM01", + "CRC01", "TOC01", "TMC00", "PRM00", "CRC00", "TOC00", "LVIM", "LVIS", + 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, + "IF0L", "IF0H", "IF1L", "IF1H", "MK0L", "MK0H", "MK1L", "MK1H", + "PR0L", "PR0H", "PR1L", "PR1H", nullptr, nullptr, nullptr, nullptr, + "IMS", nullptr, nullptr, "BANK", "IXS", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, "PCC", nullptr, nullptr, nullptr, nullptr +}; + +const char *const upd78k0kx2_disassembler::s_sfrp_names[128] = +{ + nullptr, nullptr, nullptr, nullptr, "ADCR", nullptr, nullptr, nullptr, + "TM00", "CR000", "CR010", 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, + "SDR0", "MDA0L", "MDA0H", "MDB0", 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, + "TM01", "CR001", "CR011", nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "IF0", "IF1", "MK0", "MK1", "PR0", "PR1", nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr +}; diff --git a/src/devices/cpu/upd78k/upd78k0d.h b/src/devices/cpu/upd78k/upd78k0d.h new file mode 100644 index 00000000000..8094853e165 --- /dev/null +++ b/src/devices/cpu/upd78k/upd78k0d.h @@ -0,0 +1,160 @@ +// license:BSD-3-Clause +// copyright-holders:AJR + +#ifndef MAME_CPU_UPD78K_UPD78K0D_H +#define MAME_CPU_UPD78K_UPD78K0D_H + +#pragma once + +#include "upd78kd.h" + +class upd78k0_disassembler : public upd78k_8reg_disassembler +{ +protected: + upd78k0_disassembler(const char *const sfr_names[], const char *const sfrp_names[]); + + // disasm_interface overrides + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + + // SFR tables + static const char *const s_common_sfrp_names[128]; + +private: + // mnemonic tables + static const char *const s_alu_ops[8]; + static const char *const s_bool_ops[4]; + + // disassembly helpers + offs_t dasm_31(std::ostream &stream, offs_t pc, const data_buffer &opcodes); + offs_t dasm_61(std::ostream &stream, offs_t pc, const data_buffer &opcodes); + offs_t dasm_71(std::ostream &stream, offs_t pc, const data_buffer &opcodes); +}; + +class upd78014_disassembler : public upd78k0_disassembler +{ +public: + upd78014_disassembler(); + +private: + // SFR tables + static const char *const s_sfr_names[256]; +}; + +class upd78024_disassembler : public upd78k0_disassembler +{ +public: + upd78024_disassembler(); + +private: + // SFR tables + static const char *const s_sfr_names[256]; +}; + +class upd78044a_disassembler : public upd78k0_disassembler +{ +public: + upd78044a_disassembler(); + +private: + // SFR tables + static const char *const s_sfr_names[256]; +}; + +class upd78054_disassembler : public upd78k0_disassembler +{ +public: + upd78054_disassembler(); + +private: + // SFR tables + static const char *const s_sfr_names[256]; +}; + +class upd78064_disassembler : public upd78k0_disassembler +{ +public: + upd78064_disassembler(); + +private: + // SFR tables + static const char *const s_sfr_names[256]; +}; + +class upd78078_disassembler : public upd78k0_disassembler +{ +public: + upd78078_disassembler(); + +private: + // SFR tables + static const char *const s_sfr_names[256]; + static const char *const s_sfrp_names[128]; +}; + +class upd78083_disassembler : public upd78k0_disassembler +{ +public: + upd78083_disassembler(); + +private: + // SFR tables + static const char *const s_sfr_names[256]; + static const char *const s_sfrp_names[128]; +}; + +class upd780024a_disassembler : public upd78k0_disassembler +{ +public: + upd780024a_disassembler(); + +private: + // SFR tables + static const char *const s_sfr_names[256]; + static const char *const s_sfrp_names[128]; +}; + +class upd780065_disassembler : public upd78k0_disassembler +{ +public: + upd780065_disassembler(); + +private: + // SFR tables + static const char *const s_sfr_names[256]; + static const char *const s_sfrp_names[128]; +}; + +class upd780988_disassembler : public upd78k0_disassembler +{ +public: + upd780988_disassembler(); + +private: + // SFR tables + static const char *const s_sfr_names[256]; + static const char *const s_sfrp_names[128]; +}; + +class upd78k0kx1_disassembler : public upd78k0_disassembler +{ +public: + upd78k0kx1_disassembler(); + +private: + // SFR tables + static const char *const s_sfr_names[256]; + static const char *const s_sfrp_names[128]; +}; + +class upd78k0kx2_disassembler : public upd78k0_disassembler +{ +public: + upd78k0kx2_disassembler(); + +private: + // SFR tables + static const char *const s_sfr_names[256]; + static const char *const s_sfrp_names[128]; +}; + +#endif // MAME_CPU_UPD78K_UPD78K0D_H diff --git a/src/devices/cpu/upd78k/upd78k1d.cpp b/src/devices/cpu/upd78k/upd78k1d.cpp new file mode 100644 index 00000000000..e6581d48986 --- /dev/null +++ b/src/devices/cpu/upd78k/upd78k1d.cpp @@ -0,0 +1,840 @@ +// license:BSD-3-Clause +// copyright-holders:AJR + +#include "emu.h" +#include "upd78k1d.h" + +upd78k1_disassembler::upd78k1_disassembler(const char *const sfr_names[], const char *const sfrp_names[]) + : upd78k_8reg_disassembler(sfr_names, sfrp_names) +{ +} + +const char *const upd78k1_disassembler::s_alu_ops[8] = +{ + "ADD", + "ADDC", + "SUB", + "SUBC", + "AND", + "XOR", + "OR", + "CMP" +}; + +const char *const upd78k1_disassembler::s_alu_ops16[3] = +{ + "ADDW", + "SUBW", + "CMPW" +}; + +const char *const upd78k1_disassembler::s_bool_ops[4] = +{ + "MOV1", + "AND1", + "OR1", + "XOR1" +}; + +const char *const upd78k1_disassembler::s_shift_ops[2][4] = +{ + { "RORC", "ROR", "SHR", "SHRW" }, + { "ROLC", "ROL", "SHL", "SHLW" } +}; + +const char *const upd78k1_disassembler::s_bcond[4] = +{ + "BNZ", + "BZ", + "BNC", + "BC" +}; + +offs_t upd78k1_disassembler::dasm_01xx(std::ostream &stream, u8 op2, offs_t pc, const upd78k1_disassembler::data_buffer &opcodes) +{ + if (op2 >= 0x1d && op2 < 0x20) + { + util::stream_format(stream, "%-8sAX,", s_alu_ops16[op2 - 0x1d]); + format_sfrp(stream, opcodes.r8(pc + 2)); + return 3 | SUPPORTED; + } + else if (op2 == 0x21) + { + util::stream_format(stream, "%-8sA,", "XCH"); + format_sfr(stream, opcodes.r8(pc + 2)); + return 3 | SUPPORTED; + } + else if ((op2 & 0xf8) == 0x68) + { + util::stream_format(stream, "%-8sA,", s_alu_ops[op2 & 0x07]); + format_sfr(stream, opcodes.r8(pc + 2)); + stream << ","; + format_imm8(stream, opcodes.r8(pc + 3)); + return 4 | SUPPORTED; + } + else if ((op2 & 0xf8) == 0x98) + { + util::stream_format(stream, "%-8sA,", s_alu_ops[op2 & 0x07]); + format_sfr(stream, opcodes.r8(pc + 2)); + return 3 | SUPPORTED; + } + else + return dasm_illegal2(stream, 0x01, op2); +} + +offs_t upd78k1_disassembler::dasm_02xx(std::ostream &stream, u8 op1, u8 op2, offs_t pc, const upd78k1_disassembler::data_buffer &opcodes) +{ + if (!BIT(op1, 0) && BIT(op2, 3)) + return dasm_illegal2(stream, op1, op2); + else if ((op2 & 0xf0) == 0x10) + { + util::stream_format(stream, "%-8s", "MOV1"); + if (BIT(op1, 0)) + util::stream_format(stream, "%s.%d,CY", s_r_names[(op2 & 0x08) >> 3], op2 & 0x07); + else + util::stream_format(stream, "%s,CY", s_psw_bits[op2 & 0x07]); + return 2 | SUPPORTED; + } + else if (op2 < 0x70) + { + util::stream_format(stream, "%-8sCY,", s_bool_ops[(op2 & 0x60) >> 5]); + if (BIT(op2, 4)) + stream << "/"; + if (BIT(op1, 0)) + util::stream_format(stream, "%s.%d", s_r_names[(op2 & 0x08) >> 3], op2 & 0x07); + else + util::stream_format(stream, "%s", s_psw_bits[op2 & 0x07]); + return 2 | SUPPORTED; + } + else if (op2 < (BIT(op2, 3) ? 0xa0 : 0x80)) + { + util::stream_format(stream, "%-8s", op2 < 0x80 ? "NOT1" : BIT(op2, 4) ? "CLR1" : "SET1"); + if (BIT(op1, 0)) + util::stream_format(stream, "%s.%d", s_r_names[(op2 & 0x08) >> 3], op2 & 0x07); + else + util::stream_format(stream, "%s", s_psw_bits[op2 & 0x07]); + return 2 | SUPPORTED; + } + else if ((op2 & 0xe0) == 0xa0 || (op2 & 0xf0) == 0xd0) + { + util::stream_format(stream, "%-8s", BIT(op2, 6) ? "BTCLR" : BIT(op2, 4) ? "BT" : "BF"); + if (BIT(op1, 0)) + util::stream_format(stream, "%s.%d,", s_r_names[(op2 & 0x08) >> 3], op2 & 0x07); + else + util::stream_format(stream, "%s,", s_psw_bits[op2 & 0x07]); + format_jdisp8(stream, pc + 4, opcodes.r8(pc + 3)); + return 3 | SUPPORTED; + } + else + return dasm_illegal2(stream, op1, op2); +} + +offs_t upd78k1_disassembler::dasm_05xx(std::ostream &stream, u8 op2, offs_t pc, const upd78k1_disassembler::data_buffer &opcodes) +{ + if ((op2 & 0xe8) == 0x08) + { + // not valid with A or X as operand + util::stream_format(stream, "%-8s%s", BIT(op2, 4) ? "DIVUW" : "MULUW", s_r_names[op2 & 0x07]); + return 2 | SUPPORTED; + } + else if ((op2 & 0xf8) == 0x38) + { + // not valid with A or X as operand; not available on µPD78134 + util::stream_format(stream, "%-8s%s", "MULSW", s_r_names[op2 & 0x07]); + return 2 | SUPPORTED; + } + else if ((op2 & 0xe9) == 0x48) + { + // CALL rp not available on µPD78134 + util::stream_format(stream, "%-8s%s", BIT(op2, 4) ? "CALL" : "BR", s_rp_names[(op2 & 0x06) >> 1]); + return 2 | (BIT(op2, 4) ? STEP_OVER : 0) | SUPPORTED; + } + else if ((op2 & 0xed) == 0x89) + { + util::stream_format(stream, "%-8s[%c]", BIT(op2, 4) ? "ROL4" : "ROR4", BIT(op2, 1) ? 'D' : 'E'); + return 2 | SUPPORTED; + } + else if ((op2 & 0xfc) == 0xa8) + { + util::stream_format(stream, "%-8sRB%d", "SEL", op2 & 0x03); + return 2 | SUPPORTED; + } + else + return dasm_illegal2(stream, 0x05, op2); +} + +offs_t upd78k1_disassembler::dasm_06(std::ostream &stream, offs_t pc, const upd78k1_disassembler::data_buffer &opcodes) +{ + return dasm_illegal(stream, 0x06); +} + +offs_t upd78k1_disassembler::dasm_08xx(std::ostream &stream, u8 op2, offs_t pc, const upd78k1_disassembler::data_buffer &opcodes) +{ + if ((op2 & 0xf0) == 0x10) + { + util::stream_format(stream, "%-8s", "MOV1"); + if (BIT(op2, 3)) + format_sfr(stream, opcodes.r8(pc + 2)); + else + format_saddr(stream, opcodes.r8(pc + 2)); + util::stream_format(stream, ".%d,CY", op2 & 0x07); + return 3 | SUPPORTED; + } + else if (op2 < 0x70) + { + util::stream_format(stream, "%-8sCY,", s_bool_ops[(op2 & 0x60) >> 5]); + if (BIT(op2, 4)) + stream << "/"; + if (BIT(op2, 3)) + format_sfr(stream, opcodes.r8(pc + 2)); + else + format_saddr(stream, opcodes.r8(pc + 2)); + util::stream_format(stream, ".%d", op2 & 0x07); + return 3 | SUPPORTED; + } + else if (op2 < (BIT(op2, 3) ? 0xa0 : 0x80)) + { + util::stream_format(stream, "%-8s", op2 < 0x80 ? "NOT1" : BIT(op2, 4) ? "CLR1" : "SET1"); + if (BIT(op2, 3)) + format_sfr(stream, opcodes.r8(pc + 2)); + else + format_saddr(stream, opcodes.r8(pc + 2)); + util::stream_format(stream, ".%d", op2 & 0x07); + return 3 | SUPPORTED; + } + else if ((op2 & 0xe0) == 0xa0 || (op2 & 0xf0) == 0xd0) + { + util::stream_format(stream, "%-8s", BIT(op2, 6) ? "BTCLR" : BIT(op2, 4) ? "BT" : "BF"); + if (BIT(op2, 3)) + format_sfr(stream, opcodes.r8(pc + 2)); + else + format_saddr(stream, opcodes.r8(pc + 2)); + util::stream_format(stream, ".%d,", op2 & 0x07); + format_jdisp8(stream, pc + 4, opcodes.r8(pc + 3)); + return 4 | SUPPORTED; + } + else + return dasm_illegal2(stream, 0x08, op2); +} + +offs_t upd78k1_disassembler::dasm_09xx(std::ostream &stream, u8 op2, offs_t pc, const upd78k1_disassembler::data_buffer &opcodes) +{ + if (op2 == 0xc0) + { + util::stream_format(stream, "%-8sSTBC,", "MOV"); + u8 nbyte = opcodes.r8(pc + 2); + u8 pbyte = opcodes.r8(pc + 3); + if ((nbyte ^ 0xff) == pbyte) + format_imm8(stream, pbyte); + else + stream << "invalid"; + return 4 | SUPPORTED; + } + else if ((op2 & 0xfe) == 0xf0) + { + // not available on µPD78134 + util::stream_format(stream, "%-8s", "MOV"); + if (!BIT(op2, 0)) + stream << "A,"; + format_abs16(stream, opcodes.r16(pc + 2)); + if (BIT(op2, 0)) + stream << ",A"; + return 4 | SUPPORTED; + } + else + return dasm_illegal2(stream, 0x09, op2); +} + +offs_t upd78k1_disassembler::dasm_0axx(std::ostream &stream, u8 op2, offs_t pc, const upd78k1_disassembler::data_buffer &opcodes) +{ + if ((op2 & 0x50) == 0x10 && (BIT(op2, 7) ? (op2 & 0x0f) == 0x00 : BIT(op2, 3) || (op2 & 0x03) == 0)) + { + // word[A], word[B] modes only available for MOV on µPD78134 + util::stream_format(stream, "%-8s", BIT(op2, 3) ? s_alu_ops[op2 & 0x07] : BIT(op2, 2) ? "XCH" : "MOV"); + if (!BIT(op2, 7)) + stream << "A,"; + format_ix_disp16(stream, BIT(op2, 5) ? "B" : "A", opcodes.r16(pc + 2)); + if (BIT(op2, 7)) + stream << ",A"; + return 4 | SUPPORTED; + } + else + return dasm_illegal2(stream, 0x0a, op2); +} + +offs_t upd78k1_disassembler::dasm_16xx(std::ostream &stream, u8 op2, const upd78k1_disassembler::data_buffer &opcodes) +{ + if ((op2 & 0xc0) == 0x40 && (BIT(op2, 3) || (!BIT(op2, 5) && (op2 & 0x03) == 0))) + { + // [DE] modes and XCH A, [HL] not available on µPD78134 + util::stream_format(stream, "%-8sA,", BIT(op2, 3) ? s_alu_ops[op2 & 0x07] : BIT(op2, 2) ? "XCH" : "MOV"); + if (BIT(op2, 5)) + util::stream_format(stream, "[%c]", BIT(op2, 4) ? 'D' : 'E'); + else + util::stream_format(stream, "[%s]", BIT(op2, 4) ? "HL" : "DE"); + return 2 | SUPPORTED; + } + else + return dasm_illegal2(stream, 0x16, op2); +} + +offs_t upd78k1_disassembler::dasm_25(std::ostream &stream, offs_t pc, const upd78k1_disassembler::data_buffer &opcodes) +{ + return dasm_illegal(stream, 0x25); +} + +offs_t upd78k1_disassembler::dasm_29(std::ostream &stream, offs_t pc, const upd78k1_disassembler::data_buffer &opcodes) +{ + return dasm_illegal(stream, 0x29); +} + +offs_t upd78k1_disassembler::dasm_38(std::ostream &stream, u8 op, offs_t pc, const upd78k1_disassembler::data_buffer &opcodes) +{ + return dasm_illegal(stream, op); +} + +offs_t upd78k1_disassembler::dasm_43(std::ostream &stream, offs_t pc, const upd78k1_disassembler::data_buffer &opcodes) +{ + return dasm_illegal(stream, 0x43); +} + +offs_t upd78k1_disassembler::dasm_50(std::ostream &stream, u8 op) +{ + if ((op & 0x0e) == 0x06) + { + util::stream_format(stream, "RET%s", BIT(op, 0) ? "I" : ""); + return 1 | STEP_OUT | SUPPORTED; + } + else if (!BIT(op, 1)) + { + // [DE+], [HL+], [DE] modes not available on µPD78134 + util::stream_format(stream, "%-8s", "MOV"); + if (BIT(op, 3)) + stream << "A,"; + util::stream_format(stream, "[%s%s]", BIT(op, 0) ? "HL" : "DE", BIT(op, 2) ? "" : "+"); + if (!BIT(op, 3)) + stream << ",A"; + return 1 | SUPPORTED; + } + else + return dasm_illegal(stream, op); +} + +offs_t upd78k1_disassembler::dasm_78(std::ostream &stream, u8 op, offs_t pc, const upd78k1_disassembler::data_buffer &opcodes) +{ + if ((op & 0x03) == 0x03) + util::stream_format(stream, "%-8sA,[%c]", "XCH", BIT(op, 2) ? 'D' : 'E'); + else + { + util::stream_format(stream, "%-8s", "MOV"); + if (BIT(op, 2)) + stream << "A,"; + util::stream_format(stream, "[%c%s]", BIT(op, 1) ? 'D' : 'E', BIT(op, 0) ? "+" : ""); + if (!BIT(op, 2)) + stream << ",A"; + } + return 1 | SUPPORTED; +} + +offs_t upd78k1_disassembler::disassemble(std::ostream &stream, offs_t pc, const upd78k1_disassembler::data_buffer &opcodes, const upd78k1_disassembler::data_buffer ¶ms) +{ + u8 op = opcodes.r8(pc); + switch (op & 0xf8) + { + case 0x00: + switch (op) + { + case 0x00: + stream << "NOP"; + return 1 | SUPPORTED; + + case 0x01: + return dasm_01xx(stream, opcodes.r8(pc + 1), pc, opcodes); + + case 0x02: case 0x03: + return dasm_02xx(stream, op, opcodes.r8(pc + 1), pc, opcodes); + + case 0x05: + return dasm_05xx(stream, opcodes.r8(pc + 1), pc, opcodes); + + case 0x06: + return dasm_06(stream, pc, opcodes); + + default: + return dasm_illegal(stream, op); + } + + case 0x08: + switch (op) + { + case 0x08: + return dasm_08xx(stream, opcodes.r8(pc + 1), pc, opcodes); + + case 0x09: + return dasm_09xx(stream, opcodes.r8(pc + 1), pc, opcodes); + + case 0x0a: + return dasm_0axx(stream, opcodes.r8(pc + 1), pc, opcodes); + + case 0x0b: + { + util::stream_format(stream, "%-8s", "MOVW"); + u8 sfrp = opcodes.r8(pc + 1); + if (sfrp == 0xfc) + stream << "SP"; + else + format_sfrp(stream, sfrp); + stream << ","; + format_imm16(stream, opcodes.r16(pc + 2)); + return 4 | SUPPORTED; + } + + case 0x0c: + util::stream_format(stream, "%-8s", "MOVW"); + format_saddrp(stream, opcodes.r8(pc + 1)); + stream << ","; + format_imm16(stream, opcodes.r16(pc + 2)); + return 4 | SUPPORTED; + + case 0x0e: case 0x0f: + util::stream_format(stream, "ADJB%c", BIT(op, 0) ? 'S' : 'A'); + return 1 | SUPPORTED; + + default: + return dasm_illegal(stream, op); + } + + case 0x10: + if (!BIT(op, 2)) + { + if (BIT(op, 0)) + { + util::stream_format(stream, "%-8s", "MOVW"); + if (!BIT(op, 1)) + stream << "AX,"; + u8 sfrp = opcodes.r8(pc + 1); + if (sfrp == 0xfc) + stream << "SP"; + else + format_sfrp(stream, sfrp); + if (BIT(op, 1)) + stream << ",AX"; + } + else + { + util::stream_format(stream, "%-8s", "MOV"); + if (!BIT(op, 1)) + stream << "A,"; + u8 sfr = opcodes.r8(pc + 1); + if (sfr == 0xfe) + stream << "PSW"; + else + format_sfr(stream, sfr); + if (BIT(op, 1)) + stream << ",A"; + } + return 2 | SUPPORTED; + } + else if (op == 0x14) + { + util::stream_format(stream, "%-8s", "BR"); + format_jdisp8(stream, pc + 2, opcodes.r8(pc + 1)); + return 2 | SUPPORTED; + } + else if (op == 0x16) + return dasm_16xx(stream, opcodes.r8(pc + 1), opcodes); + else + return dasm_illegal(stream, op); + + case 0x18: + if (BIT(op, 2)) + { + util::stream_format(stream, "%-8sAX,", op == 0x1c ? "MOVW" : s_alu_ops16[op - 0x1d]); + format_saddrp(stream, opcodes.r8(pc + 1)); + return 2 | SUPPORTED; + } + else if (op == 0x1a) + { + util::stream_format(stream, "%-8s", "MOVW"); + format_saddrp(stream, opcodes.r8(pc + 1)); + stream << ",AX"; + return 2 | SUPPORTED; + } + else + return dasm_illegal(stream, op); + + case 0x20: + switch (op) + { + case 0x20: case 0x21: + util::stream_format(stream, "%-8sA,", BIT(op, 0) ? "XCH" : "MOV"); + format_saddr(stream, opcodes.r8(pc + 1)); + return 2 | SUPPORTED; + + case 0x22: + util::stream_format(stream, "%-8s", "MOV"); + format_saddr(stream, opcodes.r8(pc + 1)); + stream << ",A"; + return 2 | SUPPORTED; + + case 0x24: + { + u8 rr = opcodes.r8(pc + 1); + if ((rr & 0x88) == 0x00) + { + util::stream_format(stream, "%-8s%s,%s", "MOV", s_r_names[(rr & 0x70) >> 4], s_r_names[rr & 0x07]); + return 2 | SUPPORTED; + } + else if ((rr & 0x99) == 0x08) + { + util::stream_format(stream, "%-8s%s,%s", "MOVW", s_rp_names[(rr & 0x60) >> 5], s_rp_names[(rr & 0x06) >> 1]); + return 2 | SUPPORTED; + } + else + return dasm_illegal2(stream, op, rr); + } + + case 0x25: + return dasm_25(stream, pc, opcodes); + + case 0x26: case 0x27: + util::stream_format(stream, "%-8s", BIT(op, 0) ? "DEC" : "INC"); + format_saddr(stream, opcodes.r8(pc + 1)); + return 2 | SUPPORTED; + + default: + return dasm_illegal(stream, op); + } + + case 0x28: + if ((op & 0x03) == 0x00) + { + util::stream_format(stream, "%-8s", BIT(op, 2) ? "BR" : "CALL"); + format_abs16(stream, opcodes.r16(pc + 1)); + return 3 | (BIT(op, 2) ? 0 : STEP_OVER) | SUPPORTED; + } + else if (BIT(op, 2)) + { + util::stream_format(stream, "%-8sAX,", s_alu_ops16[op - 0x2d]); + format_imm16(stream, opcodes.r16(pc + 1)); + return 3 | SUPPORTED; + } + else if (op == 0x2b) + { + util::stream_format(stream, "%-8s", "MOV"); + u8 sfr = opcodes.r8(pc + 1); + if (sfr == 0xfe) + stream << "PSW"; + else + format_sfr(stream, sfr); + stream << ","; + format_imm8(stream, opcodes.r8(pc + 2)); + return 3 | SUPPORTED; + } + else if (op == 0x29) + return dasm_29(stream, pc, opcodes); + else + return dasm_illegal(stream, op); + + case 0x30: + if (BIT(op, 2)) + { + util::stream_format(stream, "%-8s%s", "POP", s_rp_names[op & 0x03]); + return 1 | SUPPORTED; + } + else if (BIT(op, 1)) + { + util::stream_format(stream, "%-8s%s,", "DBNZ", s_r_names[op & 0x07]); + format_jdisp8(stream, pc + 2, opcodes.r8(pc + 1)); + return 2 | SUPPORTED; + } + else + { + u8 n = opcodes.r8(pc + 1); + util::stream_format(stream, "%-8s", s_shift_ops[op & 0x01][(n & 0xc0) >> 6]); + if (n < 0xc0) + { + util::stream_format(stream, "%s,%d", s_r_names[n & 0x07], (n & 0x38) >> 3); + return 2 | SUPPORTED; + } + else if (!BIT(n, 0)) + { + util::stream_format(stream, "%s,%d", s_rp_names[(n & 0x06) >> 1], (n & 0x38) >> 3); + return 2 | SUPPORTED; + } + else + return dasm_illegal2(stream, op, n); + } + + case 0x38: + if (BIT(op, 2)) + { + util::stream_format(stream, "%-8s%s", "PUSH", s_rp_names[op & 0x03]); + return 1 | SUPPORTED; + } + else if (BIT(op, 1)) + { + util::stream_format(stream, "%-8s", BIT(op, 0) ? "DBNZ" : "MOV"); + format_saddr(stream, opcodes.r8(pc + 1)); + stream << ","; + if (BIT(op, 0)) + format_jdisp8(stream, pc + 3, opcodes.r8(pc + 2)); + else + format_imm8(stream, opcodes.r8(pc + 2)); + return 3 | SUPPORTED; + } + else + return dasm_38(stream, op, pc, opcodes); + + case 0x40: + if (BIT(op, 2)) + { + util::stream_format(stream, "%-8s%s", "INCW", s_rp_names[op & 0x03]); + return 1 | SUPPORTED; + } + else if (BIT(op, 1)) + { + if (BIT(op, 0)) + return dasm_43(stream, pc, opcodes); + else + { + util::stream_format(stream, "%-8sCY", "NOT1"); + return 1 | SUPPORTED; + } + } + else + { + util::stream_format(stream, "%-8sCY", BIT(op, 0) ? "SET1" : "CLR1"); + return 1 | SUPPORTED; + } + + case 0x48: + if (BIT(op, 2)) + util::stream_format(stream, "%-8s%s", "DECW", s_rp_names[op & 0x03]); + else if (BIT(op, 1)) + util::stream_format(stream, "%cI", BIT(op, 0) ? 'E' : 'D'); + else + util::stream_format(stream, "%-8sPSW", BIT(op, 0) ? "PUSH" : "POP"); + return 1 | SUPPORTED; + + case 0x50: case 0x58: + return dasm_50(stream, op); + + case 0x60: + if (BIT(op, 0)) + return dasm_illegal(stream, op); + else + { + util::stream_format(stream, "%-8s%s,", "MOVW", s_rp_names[(op & 0x06) >> 1]); + format_imm16(stream, opcodes.r16(pc + 1)); + return 3 | SUPPORTED; + } + + case 0x68: + util::stream_format(stream, "%-8s", s_alu_ops[op & 0x07]); + format_saddr(stream, opcodes.r8(pc + 1)); + stream << ","; + format_imm8(stream, opcodes.r8(pc + 2)); + return 3 | SUPPORTED; + + case 0x70: + util::stream_format(stream, "%-8s", "BT"); + format_saddr(stream, opcodes.r8(pc + 1)); + util::stream_format(stream, ".%d,", op & 0x07); + format_jdisp8(stream, pc + 3, opcodes.r8(pc + 2)); + return 3 | SUPPORTED; + + case 0x78: + return dasm_78(stream, op, pc, opcodes); + + case 0x80: + if (BIT(op, 2)) + return dasm_illegal(stream, op); + else + { + util::stream_format(stream, "%-8s", s_bcond[op & 0x03]); + format_jdisp8(stream, pc + 2, opcodes.r8(pc + 1)); + return 2 | SUPPORTED; + } + + case 0x88: + { + u8 rr = opcodes.r8(pc + 1); + if ((rr & 0x88) == 0x00) + { + util::stream_format(stream, "%-8s%s,%s", s_alu_ops[op & 0x07], s_r_names[(rr & 0x70) >> 4], s_r_names[rr & 0x07]); + return 2 | SUPPORTED; + } + else if ((rr & 0xf9) == 0x08 && (op == 0x88 || op == 0x8a || op == 0x8f)) + { + util::stream_format(stream, "%-8sAX,%s", std::string(s_alu_ops[op & 0x07]) + "W", s_rp_names[(rr & 0x06) >> 1]); + return 2 | SUPPORTED; + } + else + return dasm_illegal2(stream, op, rr); + } + + case 0x90: + util::stream_format(stream, "%-8s", "CALLF"); + format_abs16(stream, 0x0800 | u16(op & 0x07) << 8 | opcodes.r8(pc + 1)); + return 2 | STEP_OVER | SUPPORTED; + + case 0x98: + util::stream_format(stream, "%-8sA,", s_alu_ops[op & 0x07]); + format_saddr(stream, opcodes.r8(pc + 1)); + return 2 | SUPPORTED; + + case 0xa0: case 0xb0: + util::stream_format(stream, "%-8s", BIT(op, 4) ? "SET1" : "CLR1"); + format_saddr(stream, opcodes.r8(pc + 1)); + util::stream_format(stream, ".%d", op & 0x07); + return 2 | SUPPORTED; + + case 0xa8: + util::stream_format(stream, "%-8sA,", s_alu_ops[op & 0x07]); + format_imm8(stream, opcodes.r8(pc + 1)); + return 2 | SUPPORTED; + + case 0xb8: + util::stream_format(stream, "%-8s%s,", "MOV", s_r_names[op & 0x07]); + format_imm8(stream, opcodes.r8(pc + 1)); + return 2 | SUPPORTED; + + case 0xc0: case 0xc8: + util::stream_format(stream, "%-8s%s", BIT(op, 3) ? "DEC" : "INC", s_r_names[op & 0x07]); + return 1 | SUPPORTED; + + case 0xd0: case 0xd8: + util::stream_format(stream, "%-8sA,%s", BIT(op, 3) ? "XCH" : "MOV", s_r_names[op & 0x07]); + return 1 | SUPPORTED; + + case 0xe0: case 0xe8: case 0xf0: case 0xf8: + util::stream_format(stream, "%-8s[%04XH]", "CALLT", u16(op & 0x3f) << 1); + return 1 | STEP_OVER | SUPPORTED; + + default: // can't happen here, though compilers believe it could + return dasm_illegal(stream, op); + } +} + +upd78138_disassembler::upd78138_disassembler() + : upd78k1_disassembler(s_sfr_names, s_sfrp_names) +{ +} + +const char *const upd78138_disassembler::s_sfr_names[256] = +{ + "P0", "P1", "P2", "P3", "P4", "P5", "P6", "P7", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, "CPT2L", "PRM3", nullptr, nullptr, + "PM0", "PM1", nullptr, "PM3", nullptr, "PM5", "PM6", "PM7", + "PM8", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "TMC0", "TMC1", "CPTM", nullptr, nullptr, "TM3", "CR30", "CPT30", + "PUO", nullptr, nullptr, "PMC3", nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, "P0L", "P0H", "RTPC", nullptr, nullptr, nullptr, + "ICR", nullptr, nullptr, "EDVC", "ECC1", "ECC0", "EC", nullptr, + "TOM0", "TOC0", "TOM1", "TOC1", nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "ADM", nullptr, "ADCR", nullptr, nullptr, nullptr, nullptr, nullptr, + "PWMC", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "CLOM", + "CSIM", nullptr, "SBIC", nullptr, nullptr, nullptr, "SIO", 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, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "STBC", nullptr, nullptr, nullptr, "MM", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "IMS", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "IF0L", "IF0H", nullptr, nullptr, "MK0L", "MK0H", nullptr, nullptr, + "PR0L", "PR0H", nullptr, nullptr, "ISM0L", "ISM0H", nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, "INTM0", "INTM1", nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr +}; + +const char *const upd78138_disassembler::s_sfrp_names[128] = +{ + nullptr, nullptr, nullptr, nullptr, "CR00", "CR01", "CR02", "CR10", + "CR11", "CR12", "CPT0", "CPT1", "CPT2H", "CPT3", nullptr, "CR20", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "TM0", "TM1", "FRC", "TM2", 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, "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, 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, + "IF0", nullptr, "MK0", nullptr, "PR0", nullptr, "ISM0", nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr +}; + +upd78148_disassembler::upd78148_disassembler() + : upd78k1_disassembler(s_sfr_names, s_sfrp_names) +{ +} + +const char *const upd78148_disassembler::s_sfr_names[256] = +{ + "P0", "P1", "P2", "P3", "P4", "P5", "P6", "P7", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, "CPT2L", "PRM3", nullptr, nullptr, + "PM0", "PM1", nullptr, "PM3", nullptr, "PM5", "PM6", nullptr, + "PM8", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "TMC0", "TMC1", "CPTM", "TM6", "TM7", "TM3", "CR30", "CPT30", + "PUO", "PMC1", "CPT3L", "PMC3", nullptr, nullptr, "P1L", "P1H", + "PMC8", "PMC9", "P0L", "P0H", "RTPC", "TRGS", "P8L", "WM", + "ICR", "UDC", "CRC", "EDVC", "ECC1", "ECC0", "EC", "PRM4", + "TOM0", "TOC0", "TOM1", "TOC1", "TM4", "CR40", "TM5", "CR50", + "P8", "P9", "AMPM", "UDCC", "ADM0", "ADM1", "ADCR0", "ADCR1", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "PWMC0", "PWMC1", nullptr, nullptr, nullptr, nullptr, "PWM2", "PWM3", + nullptr, nullptr, "PWM4", "CR41", nullptr, nullptr, "TMC2", "CLOM", + "CSIM0", "CSIM1", "SBIC", nullptr, "ADTC1", "ADTP1", "SIO0", "SIO1", + 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, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "STBC", nullptr, nullptr, nullptr, "MM", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "IMS", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "IF0L", "IF0H", "IF1L", nullptr, "MK0L", "MK0H", "MK1L", nullptr, + "PR0L", "PR0H", "PR1L", nullptr, "ISM0L", "ISM0H", "ISM1L", nullptr, + nullptr, nullptr, nullptr, nullptr, "INTM0", "INTM1", nullptr, nullptr, + nullptr, nullptr, nullptr, "CC", nullptr, nullptr, nullptr, nullptr +}; + +const char *const upd78148_disassembler::s_sfrp_names[128] = +{ + nullptr, nullptr, nullptr, nullptr, "CR00", "CR01", "CR02", "CR10", + "CR11", "CR12", "CPT0", "CPT1", "CPT2H", "CPT3H", nullptr, "CR20", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "MULL", "MULH", + "TM0", "TM1", "FRC", "TM2", nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, "CR13", nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, "PWM0", "PWM1", nullptr, nullptr, nullptr, "PWM5", 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, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "IF0", nullptr, "MK0", nullptr, "PR0", nullptr, "ISM0", nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr +}; diff --git a/src/devices/cpu/upd78k/upd78k1d.h b/src/devices/cpu/upd78k/upd78k1d.h new file mode 100644 index 00000000000..e09a36dd13e --- /dev/null +++ b/src/devices/cpu/upd78k/upd78k1d.h @@ -0,0 +1,65 @@ +// license:BSD-3-Clause +// copyright-holders:AJR + +#ifndef MAME_CPU_UPD78K_UPD78K1D_H +#define MAME_CPU_UPD78K_UPD78K1D_H + +#pragma once + +#include "upd78kd.h" + +class upd78k1_disassembler : public upd78k_8reg_disassembler +{ +protected: + upd78k1_disassembler(const char *const sfr_names[], const char *const sfrp_names[]); + + // mnemonic tables + static const char *const s_alu_ops[8]; + static const char *const s_alu_ops16[3]; + static const char *const s_bool_ops[4]; + static const char *const s_shift_ops[2][4]; + static const char *const s_bcond[4]; + + // disasm_interface overrides + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + + // disassembly helpers + virtual offs_t dasm_01xx(std::ostream &stream, u8 op2, offs_t pc, const data_buffer &opcodes); + offs_t dasm_02xx(std::ostream &stream, u8 op1, u8 op2, offs_t pc, const data_buffer &opcodes); + virtual offs_t dasm_05xx(std::ostream &stream, u8 op2, offs_t pc, const data_buffer &opcodes); + virtual offs_t dasm_06(std::ostream &stream, offs_t pc, const data_buffer &opcodes); + offs_t dasm_08xx(std::ostream &stream, u8 op2, offs_t pc, const data_buffer &opcodes); + virtual offs_t dasm_09xx(std::ostream &stream, u8 op2, offs_t pc, const data_buffer &opcodes); + virtual offs_t dasm_0axx(std::ostream &stream, u8 op2, offs_t pc, const data_buffer &opcodes); + virtual offs_t dasm_16xx(std::ostream &stream, u8 op2, const data_buffer &opcodes); + virtual offs_t dasm_25(std::ostream &stream, offs_t pc, const data_buffer &opcodes); + virtual offs_t dasm_29(std::ostream &stream, offs_t pc, const data_buffer &opcodes); + virtual offs_t dasm_38(std::ostream &stream, u8 op, offs_t pc, const data_buffer &opcodes); + virtual offs_t dasm_43(std::ostream &stream, offs_t pc, const data_buffer &opcodes); + virtual offs_t dasm_50(std::ostream &stream, u8 op); + virtual offs_t dasm_78(std::ostream &stream, u8 op, offs_t pc, const data_buffer &opcodes); +}; + +class upd78138_disassembler : public upd78k1_disassembler +{ +public: + upd78138_disassembler(); + +private: + // SFR tables + static const char *const s_sfr_names[256]; + static const char *const s_sfrp_names[128]; +}; + +class upd78148_disassembler : public upd78k1_disassembler +{ +public: + upd78148_disassembler(); + +private: + // SFR tables + static const char *const s_sfr_names[256]; + static const char *const s_sfrp_names[128]; +}; + +#endif // MAME_CPU_UPD78K_UPD78K1D_H diff --git a/src/devices/cpu/upd78k/upd78k2.cpp b/src/devices/cpu/upd78k/upd78k2.cpp new file mode 100644 index 00000000000..75de4feb465 --- /dev/null +++ b/src/devices/cpu/upd78k/upd78k2.cpp @@ -0,0 +1,217 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/**************************************************************************** + + NEC 78K/II series 8-bit single-chip microcontrollers + + Currently these devices are just stubs with no actual execution core. + +****************************************************************************/ + +#include "emu.h" +#include "upd78k2.h" +#include "upd78k2d.h" + +// device type definition +DEFINE_DEVICE_TYPE(UPD78213, upd78213_device, "upd78213", "NEC uPD78213") + +//************************************************************************** +// 78K/II CORE +//************************************************************************** + +//------------------------------------------------- +// upd78k2_device - constructor +//------------------------------------------------- + +upd78k2_device::upd78k2_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, 8, 0, address_map_constructor(FUNC(upd78k2_device::iram_map), this)) + , m_sfr_config("SFR", ENDIANNESS_LITTLE, 16, 8, 0, sfr_map) + , m_program_space(nullptr) + , m_program_cache(nullptr) + , m_iram_cache(nullptr) + , m_sfr_space(nullptr) + , m_pc(0) + , m_ppc(0) + , m_psw(0) + , m_sp(0) + , m_icount(0) +{ +} + + +//------------------------------------------------- +// iram_map - type-universal IRAM map +//------------------------------------------------- + +void upd78k2_device::iram_map(address_map &map) +{ + map(0x00, 0xff).ram().share("iram"); +} + + +//------------------------------------------------- +// memory_space_config - return a vector of +// address space configurations for this device +//------------------------------------------------- + +device_memory_interface::space_config_vector upd78k2_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 u8 upd78k2_device::register_base() const noexcept +{ + return (BIT(m_psw, 5) ? 0xe0 : 0xf0) | (~m_psw & 0x08); +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void upd78k2_device::device_start() +{ + // get address spaces and access caches + m_program_space = &space(AS_PROGRAM); + m_program_cache = m_program_space->cache<0, 0, ENDIANNESS_LITTLE>(); + m_iram_cache = space(AS_DATA).cache<1, 0, ENDIANNESS_LITTLE>(); + m_sfr_space = &space(AS_IO); + + set_icountptr(m_icount); + + // debug state + state_add(UPD78K2_PC, "PC", m_pc); + state_add(STATE_GENPC, "GENPC", m_pc).noshow(); + state_add(STATE_GENPCBASE, "GENPCBASE", m_ppc).noshow(); + state_add(UPD78K2_PSW, "PSW", m_psw).mask(0xfb); + state_add(STATE_GENFLAGS, "FLAGS", m_psw).mask(0xfb).formatstr("%9s").noshow(); + state_add(UPD78K2_RBS, "RBS", + [this]() { return bitswap<2>(m_psw, 5, 3); }, + [this](u8 data) { m_psw = (m_psw & 0xd7) | (data & 2) << 4 | (data & 1) << 3; } + ).mask(3).noshow(); + state_add(UPD78K2_SP, "SP", m_sp); + void *iram = memshare("iram")->ptr(); + for (int n = 0; n < 4; n++) + state_add(UPD78K2_AX + n, std::array{{"AX", "BC", "DE", "HL"}}[n], + [this, iram, n]() { return static_cast(iram)[(register_base() >> 1) | n]; }, + [this, iram, n](u16 data) { static_cast(iram)[(register_base() >> 1) | n] = data; } + ); + for (int n = 0; n < 8; n++) + state_add(UPD78K2_X + n, std::array{{"X", "A", "C", "B", "E", "D", "L", "H"}}[n], + [this, iram, n]() { return static_cast(iram)[BYTE_XOR_LE(register_base() | n)]; }, + [this, iram, n](u8 data) { static_cast(iram)[BYTE_XOR_LE(register_base() | n)] = data; } + ).noshow(); + + // save state + save_item(NAME(m_pc)); + save_item(NAME(m_ppc)); + save_item(NAME(m_sp)); + save_item(NAME(m_psw)); +} + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void upd78k2_device::device_reset() +{ + // PC will be initialized from vector following reset + m_psw = 0x02; +} + + +//------------------------------------------------- +// execute_run - +//------------------------------------------------- + +void upd78k2_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 upd78k2_device::state_string_export(const device_state_entry &entry, std::string &str) const +{ + switch (entry.index()) + { + case STATE_GENFLAGS: + str = string_format("RB%d:%c%c%c%c%c", + (BIT(m_psw, 5) ? 2 : 0) | (BIT(m_psw, 3) ? 1 : 0), + BIT(m_psw, 7) ? 'I' : '.', + BIT(m_psw, 6) ? 'Z' : '.', + BIT(m_psw, 4) ? 'A' : '.', + BIT(m_psw, 1) ? 'P' : '.', + BIT(m_psw, 0) ? 'C' : '.'); + break; + } +} + + +//************************************************************************** +// 78K/II SUBSERIES DEVICES +//************************************************************************** + +//------------------------------------------------- +// upd78213_device - constructor +//------------------------------------------------- + +upd78213_device::upd78213_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : upd78k2_device(mconfig, UPD78213, tag, owner, clock, + address_map_constructor(FUNC(upd78213_device::mem_map), this), + address_map_constructor(FUNC(upd78213_device::sfr_map), this)) +{ +} + + +//------------------------------------------------- +// create_disassembler - +//------------------------------------------------- + +std::unique_ptr upd78213_device::create_disassembler() +{ + return std::make_unique(); +} + + +//------------------------------------------------- +// mem_map - type-specific internal memory map +// (excluding IRAM and SFRs) +//------------------------------------------------- + +void upd78213_device::mem_map(address_map &map) +{ + // no ROM + map(0x0fd00, 0x0fdff).ram(); // PRAM +} + + +//------------------------------------------------- +// sfr_map - type-specific SFR map +//------------------------------------------------- + +void upd78213_device::sfr_map(address_map &map) +{ + // TODO +} diff --git a/src/devices/cpu/upd78k/upd78k2.h b/src/devices/cpu/upd78k/upd78k2.h new file mode 100644 index 00000000000..e059bf1cb81 --- /dev/null +++ b/src/devices/cpu/upd78k/upd78k2.h @@ -0,0 +1,96 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/********************************************************************** + + NEC 78K/II series 8-bit single-chip microcontrollers + +**********************************************************************/ + +#ifndef MAME_CPU_UPD78K_UPD78K2_H +#define MAME_CPU_UPD78K_UPD78K2_H + +#pragma once + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> upd78k2_device + +class upd78k2_device : public cpu_device +{ +public: + enum { + UPD78K2_PC, UPD78K2_PSW, UPD78K2_RBS, UPD78K2_SP, + UPD78K2_AX, UPD78K2_BC, + UPD78K2_DE, UPD78K2_HL, + UPD78K2_X, UPD78K2_A, UPD78K2_C, UPD78K2_B, + UPD78K2_D, UPD78K2_E, UPD78K2_H, UPD78K2_L + }; + + // TODO: callbacks and configuration thereof + +protected: + upd78k2_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 u8 register_base() const noexcept; + + // address spaces, caches & configuration + address_space_config m_program_config; + address_space_config m_iram_config; + address_space_config m_sfr_config; + address_space *m_program_space; + memory_access_cache<0, 0, ENDIANNESS_LITTLE> *m_program_cache; + memory_access_cache<1, 0, ENDIANNESS_LITTLE> *m_iram_cache; + address_space *m_sfr_space; + + // core registers and execution state + u16 m_pc; + u16 m_ppc; + u8 m_psw; + u16 m_sp; + s32 m_icount; +}; + +// ======================> upd78213_device + +class upd78213_device : public upd78k2_device +{ +public: + // device type constructor + upd78213_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(UPD78213, upd78213_device) + +#endif // MAME_CPU_UPD78K_UPD78K2_H diff --git a/src/devices/cpu/upd78k/upd78k2d.cpp b/src/devices/cpu/upd78k/upd78k2d.cpp new file mode 100644 index 00000000000..75abce3425f --- /dev/null +++ b/src/devices/cpu/upd78k/upd78k2d.cpp @@ -0,0 +1,584 @@ +// license:BSD-3-Clause +// copyright-holders:AJR + +#include "emu.h" +#include "upd78k2d.h" + +upd78k2_disassembler::upd78k2_disassembler(const char *const sfr_names[], const char *const sfrp_names[]) + : upd78k1_disassembler(sfr_names, sfrp_names) +{ +} + +offs_t upd78k2_disassembler::dasm_01xx(std::ostream &stream, u8 op2, offs_t pc, const upd78k2_disassembler::data_buffer &opcodes) +{ + if (op2 == 0x05) + { + u8 op3 = opcodes.r8(pc + 3); + if ((op3 & 0xed) == 0x89) + { + util::stream_format(stream, "%-8s&[%s]", BIT(op3, 4) ? "ROL4" : "ROR4", BIT(op3, 1) ? "HL" : "DE"); + return 3 | SUPPORTED; + } + else if ((op3 & 0xfa) == 0xe2) + { + util::stream_format(stream, "%-8s", "MOVW"); + if (BIT(op3, 2)) + util::stream_format(stream, "&[%s],AX", BIT(op3, 0) ? "HL" : "DE"); + else + util::stream_format(stream, "AX,&[%s]", BIT(op3, 0) ? "HL" : "DE"); + return 3 | SUPPORTED; + } + else + return dasm_illegal3(stream, 0x01, op2, op3); + } + else if (op2 == 0x06) + { + u8 op3 = opcodes.r8(pc + 3); + if ((op3 & 0x70) < 0x30 && (BIT(op3, 7) ? (op3 & 0x0f) == 0 : BIT(op3, 3) || (op3 & 0x03) == 0)) + { + util::stream_format(stream, "%-8s", BIT(op3, 3) ? s_alu_ops[op3 & 0x07] : BIT(op2, 2) ? "XCH" : "MOV"); + if (!BIT(op3, 7)) + stream << "A,"; + stream << "&"; + format_ix_disp8(stream, BIT(op3, 5) ? "HL" : BIT(op3, 4) ? "SP" : "DE", opcodes.r8(pc + 3)); + if (BIT(op3, 7)) + stream << ",A"; + return 4 | SUPPORTED; + } + else + return dasm_illegal3(stream, 0x01, op2, op3); + } + else if (op2 == 0x09) + { + u8 op3 = opcodes.r8(pc + 3); + if ((op3 & 0xfe) == 0xf0) + { + util::stream_format(stream, "%-8s", "MOV"); + if (!BIT(op3, 0)) + stream << "A,"; + stream << "&"; + format_abs16(stream, opcodes.r16(pc + 3)); + if (BIT(op3, 0)) + stream << ",A"; + return 5 | SUPPORTED; + } + else + return dasm_illegal3(stream, 0x01, op2, op3); + } + else if (op2 == 0x0a) + { + u8 op3 = opcodes.r8(pc + 3); + if (!BIT(op3, 6) && (BIT(op3, 7) ? (op3 & 0x0f) == 0 : BIT(op3, 3) || (op3 & 0x03) == 0)) + { + util::stream_format(stream, "%-8s", BIT(op2, 3) ? s_alu_ops[op3 & 0x07] : BIT(op3, 2) ? "XCH" : "MOV"); + if (!BIT(op2, 7)) + stream << "A,"; + stream << "&"; + if (BIT(op2, 4)) + format_ix_disp16(stream, BIT(op2, 5) ? "B" : "A", opcodes.r16(pc + 2)); + else + format_ix_disp16(stream, BIT(op2, 5) ? "HL" : "DE", opcodes.r16(pc + 2)); + if (BIT(op2, 7)) + stream << ",A"; + return 5 | SUPPORTED; + } + else + return dasm_illegal3(stream, 0x01, op2, op3); + } + else if (op2 == 0x16) + { + u8 op3 = opcodes.r8(pc + 3); + if ((op3 & 0x60) != 0x60 && (BIT(op3, 7) ? (op3 & 0x0f) == 0x00 : BIT(op3, 3) || (op3 & 0x03) == 0x00)) + { + util::stream_format(stream, "%-8s", BIT(op3, 3) ? s_alu_ops[op3 & 0x07] : BIT(op3, 2) ? "XCH" : "MOV"); + if (!BIT(op3, 7)) + stream << "A,"; + util::stream_format(stream, "&[%s%s]", BIT(op3, 4) ? "HL" : "DE", BIT(op3, 6) ? "" : BIT(op3, 5) ? "-" : "+"); + if (BIT(op3, 7)) + stream << ",A"; + return 3 | SUPPORTED; + } + else + return dasm_illegal3(stream, 0x01, op2, op3); + } + else if ((op2 & 0xf0) == 0x50 && (op2 & 0x06) != 0x06) + { + util::stream_format(stream, "%-8s", "MOV"); + if (BIT(op2, 3)) + stream << "A,"; + util::stream_format(stream, "&[%s%s]", BIT(op2, 0) ? "HL" : "DE", BIT(op2, 2) ? "" : BIT(op2, 1) ? "-" : "+"); + if (!BIT(op2, 3)) + stream << ",A"; + return 2 | SUPPORTED; + } + else + return upd78k1_disassembler::dasm_01xx(stream, op2, pc, opcodes); +} + +offs_t upd78k2_disassembler::dasm_05xx(std::ostream &stream, u8 op2, offs_t pc, const upd78k2_disassembler::data_buffer &opcodes) +{ + if ((op2 & 0xe8) == 0x08) + { + util::stream_format(stream, "%-8s%s", BIT(op2, 4) ? "DIVUW" : "MULU", s_r_names[op2 & 0x07]); + return 2 | SUPPORTED; + } + else if ((op2 & 0xe9) == 0x48) + { + util::stream_format(stream, "%-8s%s", BIT(op2, 4) ? "CALL" : "BR", s_rp_names[(op2 & 0x06) >> 1]); + return 2 | (BIT(op2, 4) ? STEP_OVER : 0) | SUPPORTED; + } + else if ((op2 & 0xed) == 0x89) + { + util::stream_format(stream, "%-8s[%s]", BIT(op2, 4) ? "ROL4" : "ROR4", BIT(op2, 1) ? "HL" : "DE"); + return 2 | SUPPORTED; + } + else if ((op2 & 0xfc) == 0xa8) + { + util::stream_format(stream, "%-8sRB%d", "SEL", op2 & 0x03); + return 2 | SUPPORTED; + } + else if ((op2 & 0xfe) == 0xc8) + { + util::stream_format(stream, "%-8sSP", BIT(op2, 0) ? "DECW" : "INCW"); + return 2 | SUPPORTED; + } + else if ((op2 & 0xfa) == 0xe2) + { + util::stream_format(stream, "%-8s", "MOVW"); + if (BIT(op2, 2)) + util::stream_format(stream, "[%s],AX", BIT(op2, 0) ? "HL" : "DE"); + else + util::stream_format(stream, "AX,[%s]", BIT(op2, 0) ? "HL" : "DE"); + return 2 | SUPPORTED; + } + else + return dasm_illegal2(stream, 0x05, op2); +} + +offs_t upd78k2_disassembler::dasm_06(std::ostream &stream, offs_t pc, const upd78k2_disassembler::data_buffer &opcodes) +{ + u8 op2 = opcodes.r8(pc + 1); + if ((op2 & 0x70) < 0x30 && (BIT(op2, 7) ? (op2 & 0x0f) == 0 : BIT(op2, 3) || (op2 & 0x03) == 0)) + { + util::stream_format(stream, "%-8s", BIT(op2, 3) ? s_alu_ops[op2 & 0x07] : BIT(op2, 2) ? "XCH" : "MOV"); + if (!BIT(op2, 7)) + stream << "A,"; + format_ix_disp8(stream, BIT(op2, 5) ? "HL" : BIT(op2, 4) ? "SP" : "DE", opcodes.r8(pc + 2)); + if (BIT(op2, 7)) + stream << ",A"; + return 3 | SUPPORTED; + } + else + return dasm_illegal2(stream, 0x06, op2); +} + +offs_t upd78k2_disassembler::dasm_0axx(std::ostream &stream, u8 op2, offs_t pc, const upd78k2_disassembler::data_buffer &opcodes) +{ + if (!BIT(op2, 6) && (BIT(op2, 7) ? (op2 & 0x0f) == 0 : BIT(op2, 3) || (op2 & 0x03) == 0)) + { + util::stream_format(stream, "%-8s", BIT(op2, 3) ? s_alu_ops[op2 & 0x07] : BIT(op2, 2) ? "XCH" : "MOV"); + if (!BIT(op2, 7)) + stream << "A,"; + if (BIT(op2, 4)) + format_ix_disp16(stream, BIT(op2, 5) ? "B" : "A", opcodes.r16(pc + 2)); + else + format_ix_disp16(stream, BIT(op2, 5) ? "HL" : "DE", opcodes.r16(pc + 2)); + if (BIT(op2, 7)) + stream << ",A"; + return 4 | SUPPORTED; + } + else + return dasm_illegal2(stream, 0x0a, op2); +} + +offs_t upd78k2_disassembler::dasm_16xx(std::ostream &stream, u8 op2, const upd78k2_disassembler::data_buffer &opcodes) +{ + if ((op2 & 0x60) != 0x60 && (BIT(op2, 7) ? (op2 & 0x0f) == 0x00 : BIT(op2, 3) || (op2 & 0x03) == 0x00)) + { + util::stream_format(stream, "%-8s", BIT(op2, 3) ? s_alu_ops[op2 & 0x07] : BIT(op2, 2) ? "XCH" : "MOV"); + if (!BIT(op2, 7)) + stream << "A,"; + util::stream_format(stream, "[%s%s]", BIT(op2, 4) ? "HL" : "DE", BIT(op2, 6) ? "" : BIT(op2, 5) ? "-" : "+"); + if (BIT(op2, 7)) + stream << ",A"; + return 2 | SUPPORTED; + } + else + return dasm_illegal2(stream, 0x16, op2); +} + +offs_t upd78k2_disassembler::dasm_25(std::ostream &stream, offs_t pc, const upd78k2_disassembler::data_buffer &opcodes) +{ + u8 rr = opcodes.r8(pc + 1); + if ((rr & 0x88) == 0x00) + { + util::stream_format(stream, "%-8s%s,%s", "XCH", s_r_names[(rr & 0x70) >> 4], s_r_names[rr & 0x07]); + return 2 | SUPPORTED; + } + else + return dasm_illegal2(stream, 0x25, rr); +} + +offs_t upd78k2_disassembler::dasm_29(std::ostream &stream, offs_t pc, const upd78k2_disassembler::data_buffer &opcodes) +{ + util::stream_format(stream, "%-8s", "PUSH"); + format_sfr(stream, opcodes.r8(pc + 1)); + return 2 | SUPPORTED; +} + +offs_t upd78k2_disassembler::dasm_38(std::ostream &stream, u8 op, offs_t pc, const upd78k2_disassembler::data_buffer &opcodes) +{ + util::stream_format(stream, "%-8s", BIT(op, 0) ? "XCH" : "MOV"); + format_saddr(stream, opcodes.r8(pc + 1)); + stream << ","; + format_saddr(stream, opcodes.r8(pc + 2)); + return 3 | SUPPORTED; +} + +offs_t upd78k2_disassembler::dasm_43(std::ostream &stream, offs_t pc, const upd78k2_disassembler::data_buffer &opcodes) +{ + util::stream_format(stream, "%-8s", "POP"); + format_sfr(stream, opcodes.r8(pc + 1)); + return 2 | SUPPORTED; +} + +offs_t upd78k2_disassembler::dasm_50(std::ostream &stream, u8 op) +{ + if ((op & 0x06) == 0x06) + { + if (op == 0x5e) + { + stream << "BRK"; + return 1 | STEP_OVER | SUPPORTED; + } + else + { + util::stream_format(stream, "RET%s", BIT(op, 3) ? "B" : BIT(op, 0) ? "I" : ""); + return 1 | STEP_OUT | SUPPORTED; + } + } + else + { + util::stream_format(stream, "%-8s", "MOV"); + if (BIT(op, 3)) + stream << "A,"; + util::stream_format(stream, "[%s%s]", BIT(op, 0) ? "HL" : "DE", BIT(op, 2) ? "" : BIT(op, 1) ? "-" : "+"); + if (!BIT(op, 3)) + stream << ",A"; + return 1 | SUPPORTED; + } +} + +offs_t upd78k2_disassembler::dasm_78(std::ostream &stream, u8 op, offs_t pc, const upd78k2_disassembler::data_buffer &opcodes) +{ + util::stream_format(stream, "%-8s", s_alu_ops[op & 0x07]); + format_saddr(stream, opcodes.r8(pc + 1)); + stream << ","; + format_saddr(stream, opcodes.r8(pc + 2)); + return 3 | SUPPORTED; +} + +upd78214_disassembler::upd78214_disassembler() + : upd78k2_disassembler(s_sfr_names, s_sfrp_names) +{ +} + +const char *const upd78214_disassembler::s_sfr_names[256] = +{ + "P0", nullptr, "P2", "P3", "P4", "P5", "P6", "P7", + nullptr, nullptr, "P0L", "P0H", "RTPC", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, "CR10", "CR20", "CR21", "CR30", + nullptr, nullptr, "CR22", nullptr, "CR11", nullptr, nullptr, nullptr, + "PM0", nullptr, nullptr, "PM3", nullptr, "PM5", "PM6", nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "CRC0", "TOC", "CRC1", nullptr, "CRC2", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "PUO", nullptr, nullptr, "PMC3", nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, "TM1", nullptr, "TM2", nullptr, "TM3", nullptr, + nullptr, nullptr, nullptr, nullptr, "PRM0", "TMC0", "PRM1", "TMC1", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "ADM", nullptr, "ADCR", nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "CSIM", nullptr, "SBIC", nullptr, nullptr, nullptr, "SIO", nullptr, + "ASIM", nullptr, "ASIS", nullptr, "RXB", nullptr, "TXS", nullptr, + "BRGC", 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, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "STBC", nullptr, nullptr, nullptr, "MM", "PW", "RFM", nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // external SFRs + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // external SFRs + "IF0L", "IF0H", nullptr, nullptr, "MK0L", "MK0H", nullptr, nullptr, + "PR0L", "PR0H", nullptr, nullptr, "ISM0L", "ISM0H", nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, "INTM0", "INTM1", nullptr, nullptr, + "IST", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr +}; + +const char *const upd78214_disassembler::s_sfrp_names[128] = +{ + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "CR00", "CR01", nullptr, nullptr, "CR02", 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, + "TM0", 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, 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, + "IF0", nullptr, "MK0", nullptr, "PR0", nullptr, "ISM0", nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr +}; + +upd78218a_disassembler::upd78218a_disassembler() + : upd78k2_disassembler(s_sfr_names, s_sfrp_names) +{ +} + +const char *const upd78218a_disassembler::s_sfr_names[256] = +{ + "P0", nullptr, "P2", "P3", "P4", "P5", "P6", "P7", + nullptr, nullptr, "P0L", "P0H", "RTPC", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, "CR10", "CR20", "CR21", "CR30", + nullptr, nullptr, "CR22", nullptr, "CR11", nullptr, nullptr, nullptr, + "PM0", nullptr, nullptr, "PM3", nullptr, "PM5", "PM6", nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "CRC0", "TOC", "CRC1", nullptr, "CRC2", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "PUO", nullptr, nullptr, "PMC3", nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, "TM1", nullptr, "TM2", nullptr, "TM3", nullptr, + nullptr, nullptr, nullptr, nullptr, "PRM0", "TMC0", "PRM1", "TMC1", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "ADM", nullptr, "ADCR", nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, "OSPC", nullptr, nullptr, + "CSIM", nullptr, "SBIC", nullptr, nullptr, nullptr, "SIO", nullptr, + "ASIM", nullptr, "ASIS", nullptr, "RXB", nullptr, "TXS", nullptr, + "BRGC", 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, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "STBC", nullptr, nullptr, nullptr, "MM", "PW", "RFM", 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, + "IF0L", "IF0H", nullptr, nullptr, "MK0L", "MK0H", nullptr, nullptr, + "PR0L", "PR0H", nullptr, nullptr, "ISM0L", "ISM0H", nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, "INTM0", "INTM1", nullptr, nullptr, + "IST", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr +}; + +const char *const upd78218a_disassembler::s_sfrp_names[128] = +{ + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "CR00", "CR01", nullptr, nullptr, "CR02", 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, + "TM0", 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, 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, + "IF0", nullptr, "MK0", nullptr, "PR0", nullptr, "ISM0", nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr +}; + +upd78224_disassembler::upd78224_disassembler() + : upd78k2_disassembler(s_sfr_names, s_sfrp_names) +{ +} + +const char *const upd78224_disassembler::s_sfr_names[256] = +{ + "P0", "P1", "P2", "P3", "P4", "P5", "P6", "P7", + nullptr, nullptr, "P0L", "P0H", "RTPC", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, "CR10", "CR20", "CR21", "CR30", + nullptr, nullptr, "CR22", nullptr, "CR11", nullptr, nullptr, nullptr, + "PM0", "PM1", nullptr, "PM3", nullptr, "PM5", "PM6", nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "CRC0", "TOC", "CRC1", nullptr, "CRC2", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, "PMC3", nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, "TM1", nullptr, "TM2", nullptr, "TM3", nullptr, + nullptr, nullptr, nullptr, nullptr, "PRM0", "TMC0", "PRM1", "TMC1", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "PMT", "PT", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "CSIM", nullptr, "SBIC", nullptr, nullptr, nullptr, "SIO", nullptr, + "ASIM", nullptr, "ASIS", nullptr, "RXB", nullptr, "TXS", 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, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "STBC", nullptr, nullptr, nullptr, "MM", "PW", "RFM", 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, + "IF0L", "IF0H", nullptr, nullptr, "MK0L", "MK0H", nullptr, nullptr, + "PR0L", "PR0H", nullptr, nullptr, "ISM0L", "ISM0H", nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, "INTM0", "INTM1", nullptr, nullptr, + "IST", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr +}; + +const char *const upd78224_disassembler::s_sfrp_names[128] = +{ + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "CR00", "CR01", nullptr, nullptr, "CR02", 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, + "TM0", 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, 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, + "IF0", nullptr, "MK0", nullptr, "PR0", nullptr, "ISM0", nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr +}; + +upd78234_disassembler::upd78234_disassembler() + : upd78k2_disassembler(s_sfr_names, s_sfrp_names) +{ +} + +const char *const upd78234_disassembler::s_sfr_names[256] = +{ + "P0", "P1", "P2", "P3", "P4", "P5", "P6", "P7", + nullptr, nullptr, "P0L", "P0H", "RTPC", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, "CR10", "CR20", "CR21", "CR30", + nullptr, nullptr, "CR22", nullptr, "CR11", nullptr, nullptr, nullptr, + "PM0", "PM1", nullptr, "PM3", nullptr, "PM5", "PM6", nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "CRC0", "TOC", "CRC1", nullptr, "CRC2", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "PUO", nullptr, nullptr, "PMC3", nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, "TM1", nullptr, "TM2", nullptr, "TM3", nullptr, + nullptr, nullptr, nullptr, nullptr, "PRM0", "TMC0", "PRM1", "TMC1", + "DACS0", "DACS1", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "ADM", nullptr, "ADCR", nullptr, nullptr, nullptr, nullptr, nullptr, + "PWMC", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, "OSPC", nullptr, nullptr, + "CSIM", nullptr, "SBIC", nullptr, nullptr, nullptr, "SIO", nullptr, + "ASIM", nullptr, "ASIS", nullptr, "RXB", nullptr, "TXS", nullptr, + "BRGC", 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, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "STBC", nullptr, nullptr, nullptr, "MM", "PW", "RFM", nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "IMS", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // external SFRs + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // external SFRs + "IF0L", "IF0H", nullptr, nullptr, "MK0L", "MK0H", nullptr, nullptr, + "PR0L", "PR0H", nullptr, nullptr, "ISM0L", "ISM0H", nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, "INTM0", "INTM1", nullptr, nullptr, + "IST", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr +}; + +const char *const upd78234_disassembler::s_sfrp_names[128] = +{ + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "CR00", "CR01", nullptr, nullptr, "CR02", 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, + "TM0", nullptr, nullptr, nullptr, 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, 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, + "IF0", nullptr, "MK0", nullptr, "PR0", nullptr, "ISM0", nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr +}; + +upd78244_disassembler::upd78244_disassembler() + : upd78k2_disassembler(s_sfr_names, s_sfrp_names) +{ +} + +const char *const upd78244_disassembler::s_sfr_names[256] = +{ + "P0", nullptr, "P2", "P3", "P4", "P5", "P6", "P7", + nullptr, nullptr, "P0L", "P0H", "RTPC", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, "CR10", "CR20", "CR21", "CR30", + nullptr, nullptr, "CR22", nullptr, "CR11", nullptr, nullptr, nullptr, + "PM0", nullptr, nullptr, "PM3", nullptr, "PM5", "PM6", nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "CRC0", "TOC", "CRC1", nullptr, "CRC2", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "PUO", nullptr, nullptr, "PMC3", nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, "TM1", nullptr, "TM2", nullptr, "TM3", nullptr, + nullptr, nullptr, nullptr, nullptr, "PRM0", "TMC0", "PRM1", "TMC1", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "ADM", nullptr, "ADCR", nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "EWC", nullptr, nullptr, nullptr, nullptr, "OSPC", nullptr, nullptr, + "CSIM", nullptr, "SBIC", nullptr, nullptr, nullptr, "SIO", nullptr, + "ASIM", nullptr, "ASIS", nullptr, "RXB", nullptr, "TXS", nullptr, + "BRGC", 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, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "STBC", nullptr, nullptr, nullptr, "MM", "PW", "RFM", nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // external SFRs + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // external SFRs + "IF0L", "IF0H", nullptr, nullptr, "MK0L", "MK0H", nullptr, nullptr, + "PR0L", "PR0H", nullptr, nullptr, "ISM0L", "ISM0H", nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, "INTM0", "INTM1", nullptr, nullptr, + "IST", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr +}; + +const char *const upd78244_disassembler::s_sfrp_names[128] = +{ + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "CR00", "CR01", nullptr, nullptr, "CR02", 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, + "TM0", 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, 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, + "IF0", nullptr, "MK0", nullptr, "PR0", nullptr, "ISM0", nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr +}; diff --git a/src/devices/cpu/upd78k/upd78k2d.h b/src/devices/cpu/upd78k/upd78k2d.h new file mode 100644 index 00000000000..28fbb134676 --- /dev/null +++ b/src/devices/cpu/upd78k/upd78k2d.h @@ -0,0 +1,85 @@ +// license:BSD-3-Clause +// copyright-holders:AJR + +#ifndef MAME_CPU_UPD78K_UPD78K2D_H +#define MAME_CPU_UPD78K_UPD78K2D_H + +#pragma once + +#include "upd78k1d.h" + +class upd78k2_disassembler : public upd78k1_disassembler +{ +protected: + upd78k2_disassembler(const char *const sfr_names[], const char *const sfrp_names[]); + + // disassembly helper overrides + virtual offs_t dasm_01xx(std::ostream &stream, u8 op2, offs_t pc, const data_buffer &opcodes) override; + virtual offs_t dasm_05xx(std::ostream &stream, u8 op2, offs_t pc, const data_buffer &opcodes) override; + virtual offs_t dasm_06(std::ostream &stream, 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 op2, const data_buffer &opcodes) override; + virtual offs_t dasm_25(std::ostream &stream, offs_t pc, const data_buffer &opcodes) override; + virtual offs_t dasm_29(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_43(std::ostream &stream, offs_t pc, const data_buffer &opcodes) override; + virtual offs_t dasm_50(std::ostream &stream, u8 op) override; + virtual offs_t dasm_78(std::ostream &stream, u8 op, offs_t pc, const data_buffer &opcodes) override; +}; + +class upd78214_disassembler : public upd78k2_disassembler +{ +public: + upd78214_disassembler(); + +private: + // SFR tables + static const char *const s_sfr_names[256]; + static const char *const s_sfrp_names[128]; +}; + +class upd78218a_disassembler : public upd78k2_disassembler +{ +public: + upd78218a_disassembler(); + +private: + // SFR tables + static const char *const s_sfr_names[256]; + static const char *const s_sfrp_names[128]; +}; + +class upd78224_disassembler : public upd78k2_disassembler +{ +public: + upd78224_disassembler(); + +private: + // SFR tables + static const char *const s_sfr_names[256]; + static const char *const s_sfrp_names[128]; +}; + +class upd78234_disassembler : public upd78k2_disassembler +{ +public: + upd78234_disassembler(); + +private: + // SFR tables + static const char *const s_sfr_names[256]; + static const char *const s_sfrp_names[128]; +}; + +class upd78244_disassembler : public upd78k2_disassembler +{ +public: + upd78244_disassembler(); + +private: + // SFR tables + static const char *const s_sfr_names[256]; + static const char *const s_sfrp_names[128]; +}; + +#endif // MAME_CPU_UPD78K_UPD78K2D_H diff --git a/src/devices/cpu/upd78k/upd78kd.cpp b/src/devices/cpu/upd78k/upd78kd.cpp new file mode 100644 index 00000000000..71c3eb9715c --- /dev/null +++ b/src/devices/cpu/upd78k/upd78kd.cpp @@ -0,0 +1,179 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/*************************************************************************** + + This is the base for several NEC 78K family disassemblers. These have + more or less incompatible instruction decodings, so this file mostly + contains common helpers. + +***************************************************************************/ + +#include "emu.h" +#include "upd78kd.h" + +upd78k_family_disassembler::upd78k_family_disassembler(const char *const sfr_names[], const char *const sfrp_names[]) + : util::disasm_interface() + , m_sfr_names(sfr_names) + , m_sfrp_names(sfrp_names) +{ +} + +u32 upd78k_family_disassembler::opcode_alignment() const +{ + return 1; +} + +void upd78k_family_disassembler::format_imm8(std::ostream &stream, u8 d) +{ + if (d < 0xa0) + util::stream_format(stream, "#%02XH", d); + else + util::stream_format(stream, "#0%02XH", d); +} + +void upd78k_family_disassembler::format_imm16(std::ostream &stream, u16 d) +{ + if (d < 0xa000) + util::stream_format(stream, "#%04XH", d); + else + util::stream_format(stream, "#0%04XH", d); +} + +void upd78k_family_disassembler::format_ix_disp8(std::ostream &stream, const char *r, u8 d) +{ + if (d < 0xa0) + util::stream_format(stream, "[%s+%02XH]", r, d); + else + util::stream_format(stream, "[%s+0%02XH]", r, d); +} + +void upd78k_family_disassembler::format_ix_disp16(std::ostream &stream, const char *r, u16 d) +{ + if (d > 0xff00) // assume these are effectively small negative offsets + { + stream << "-"; + d = 0x10000 - d; + } + if (d < 0x000a) + util::stream_format(stream, "%d[%s]", d, r); + else + { + if (d < 0x0010 || d >= (d < 0x0100 ? 0x00a0 : d < 0x1000 ? 0x0a00 : 0xa000)) + stream << "0"; + util::stream_format(stream, "%XH[%s]", d, r); + } +} + +void upd78k_family_disassembler::format_abs16(std::ostream &stream, u16 addr) +{ + if (addr < 0xa000) + util::stream_format(stream, "!%04XH", addr); + else + util::stream_format(stream, "!0%04XH", addr); +} + +void upd78k_family_disassembler::format_jdisp8(std::ostream &stream, offs_t pc, u8 disp) +{ + u16 addr = pc + s8(disp); + if (addr < 0xa000) + util::stream_format(stream, "$%04XH", addr); + else + util::stream_format(stream, "$0%04XH", addr); +} + +void upd78k_family_disassembler::format_sfr(std::ostream &stream, u8 addr) +{ + if (m_sfr_names[addr] != nullptr) + stream << m_sfr_names[addr]; + else + util::stream_format(stream, "0%04XH", 0xff00 + addr); +} + +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); +} + +void upd78k_family_disassembler::format_sfrp(std::ostream &stream, u8 addr) +{ + if (!BIT(addr, 0) && m_sfrp_names[addr >> 1] != nullptr) + stream << m_sfrp_names[addr >> 1]; + else + util::stream_format(stream, "0%04XH", 0xff00 + addr); +} + +void upd78k_family_disassembler::format_saddrp(std::ostream &stream, u8 addr) +{ + if (addr < 0x20) + format_sfrp(stream, addr); + else + util::stream_format(stream, "0%04XH", 0xfe00 + addr); +} + +offs_t upd78k_family_disassembler::dasm_illegal(std::ostream &stream, u8 op) +{ + if (op < 0xa0) + util::stream_format(stream, "%-8s%02XH", "DB", op); + else + util::stream_format(stream, "%-8s0%02XH", "DB", op); + return 1 | SUPPORTED; +} + +offs_t upd78k_family_disassembler::dasm_illegal2(std::ostream &stream, u8 op1, u8 op2) +{ + if (op2 < 0xa0) + util::stream_format(stream, "%-8s%02XH,%02XH", "DB", op1, op2); + else + util::stream_format(stream, "%-8s%02XH,0%02XH", "DB", op1, op2); + return 2 | SUPPORTED; +} + +offs_t upd78k_family_disassembler::dasm_illegal3(std::ostream &stream, u8 op1, u8 op2, u8 op3) +{ + if (op3 < 0xa0) + util::stream_format(stream, "%-8s%02XH,%02XH,%02XH", "DB", op1, op2, op3); + else + util::stream_format(stream, "%-8s%02XH,%02XH,0%02XH", "DB", op1, op2, op3); + return 3 | SUPPORTED; +} + +// 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) +{ +} + +const char *const upd78k_8reg_disassembler::s_r_names[8] = +{ + "X", + "A", + "C", + "B", + "E", + "D", + "L", + "H" +}; + +const char *const upd78k_8reg_disassembler::s_rp_names[4] = +{ + "AX", + "BC", + "DE", + "HL" +}; + +const char *const upd78k_8reg_disassembler::s_psw_bits[8] = +{ + "CY", + "ISP", + "PSW.2", + "RBS0", + "AC", + "RBS1", + "Z", + "IE" +}; diff --git a/src/devices/cpu/upd78k/upd78kd.h b/src/devices/cpu/upd78k/upd78kd.h new file mode 100644 index 00000000000..2356a3cbbb8 --- /dev/null +++ b/src/devices/cpu/upd78k/upd78kd.h @@ -0,0 +1,50 @@ +// license:BSD-3-Clause +// copyright-holders:AJR + +#ifndef MAME_CPU_UPD78K_UPD78KD_H +#define MAME_CPU_UPD78K_UPD78KD_H + +#pragma once + +class upd78k_family_disassembler : public util::disasm_interface +{ +protected: + upd78k_family_disassembler(const char *const sfr_names[], const char *const sfrp_names[]); + + // disasm_interface overrides + virtual u32 opcode_alignment() const override; + + // formatting helpers + void format_imm8(std::ostream &stream, u8 d); + void format_imm16(std::ostream &stream, u16 d); + void format_ix_disp8(std::ostream &stream, const char *r, u8 d); + void format_ix_disp16(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); + void format_sfr(std::ostream &stream, u8 addr); + void format_saddr(std::ostream &stream, u8 addr); + void format_sfrp(std::ostream &stream, u8 addr); + void format_saddrp(std::ostream &stream, u8 addr); + + // generic illegal instruction dissasembly + offs_t dasm_illegal(std::ostream &stream, u8 op); + offs_t dasm_illegal2(std::ostream &stream, u8 op1, u8 op2); + offs_t dasm_illegal3(std::ostream &stream, u8 op1, u8 op2, u8 op3); + +private: + const char *const *const m_sfr_names; + const char *const *const m_sfrp_names; +}; + +class upd78k_8reg_disassembler : public upd78k_family_disassembler +{ +protected: + upd78k_8reg_disassembler(const char *const sfr_names[], const char *const sfrp_names[]); + + // tables + static const char *const s_r_names[8]; + static const char *const s_rp_names[4]; + static const char *const s_psw_bits[8]; +}; + +#endif // MAME_CPU_UPD78K_UPD78KD_H diff --git a/src/mame/drivers/cit1500.cpp b/src/mame/drivers/cit1500.cpp index 3744f4644bb..0979c1539df 100644 --- a/src/mame/drivers/cit1500.cpp +++ b/src/mame/drivers/cit1500.cpp @@ -36,7 +36,7 @@ DS1302S trickle-charge timekeeping ****************************************************************************/ #include "emu.h" -//#include "cpu/upd78k0/upd78054.h" +#include "cpu/upd78k/upd78k0.h" //#include "machine/ds1302.h" //#include "video/upd7225.h" //#include "screen.h" @@ -46,26 +46,33 @@ class cit1500_state : public driver_device public: cit1500_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) + , m_cit1500(*this, "cit1500") { } void cit1500(machine_config &config); private: - //void mem_map(address_map &map); + void mem_map(address_map &map); - //required_device m_cit1500; + required_device m_cit1500; }; +void cit1500_state::mem_map(address_map &map) +{ + map(0x6000, 0xfa7f).rom().region("cit1600", 0x6000); // TODO: banked +} + + static INPUT_PORTS_START(cit1500) INPUT_PORTS_END void cit1500_state::cit1500(machine_config &config) { - //UPD78053(config, m_cit1500, 5_MHz_XTAL, 32.768_kHz_XTAL); - //m_cit1500->set_addrmap(AS_PROGRAM, &cit1500_state::mem_map); + UPD78053(config, m_cit1500, 5_MHz_XTAL, 32.768_kHz_XTAL); + m_cit1500->set_addrmap(AS_PROGRAM, &cit1500_state::mem_map); //UPD7225(config, "cit1400"); @@ -76,23 +83,25 @@ void cit1500_state::cit1500(machine_config &config) ROM_START(trmavia) - ROM_REGION(0x6000, "cit1500", 0) // 24K internal mask ROM - ROM_LOAD("citesa_ics1_7ce52872aa_0143h8l01", 0x0000, 0x6000, NO_DUMP) - ROM_REGION(0x20000, "cit1600", 0) // external program ROM ROM_LOAD("3cq-1039-e-183cf58-3a-28-06-01_m27w101.cit1600", 0x00000, 0x20000, CRC(db6bff63) SHA1(1b33ad98112d2946edc9444c8e6df4b4da778377)) + ROM_REGION(0x6000, "cit1500", 0) // 24K internal mask ROM + ROM_LOAD("citesa_ics1_7ce52872aa_0143h8l01", 0x0000, 0x6000, NO_DUMP) + ROM_COPY("cit1600", 0x06000, 0x0000, 2) // hack to provide at least a reset vector + ROM_REGION(0x1000, "cit1300", 0) ROM_LOAD("tpe-2c-eaaa_24lc32a.cit1300", 0x0000, 0x1000, CRC(141d94e0) SHA1(f76a920a4eb6476999b5b59a1bf9eaa7b616cd0b)) ROM_END ROM_START(teletup) - ROM_REGION(0x6000, "cit1500", 0) // 24K internal mask ROM - ROM_LOAD("citesa_ics1_7ce52872aa_0143h8l01", 0x0000, 0x6000, NO_DUMP) - ROM_REGION(0x20000, "cit1600", 0) // external program ROM ROM_LOAD("3cq-1043-ae-1616d87-3d-16-11-00_27v101.cit1600", 0x00000, 0x20000, CRC(656c3ac5) SHA1(abcda259826d91a8f8c66a64066bd3da017a61af)) + ROM_REGION(0x6000, "cit1500", 0) // 24K internal mask ROM + ROM_LOAD("citesa_ics1_7ce52872aa_0143h8l01", 0x0000, 0x6000, NO_DUMP) + ROM_COPY("cit1600", 0x06000, 0x0000, 2) // hack to provide at least a reset vector + ROM_REGION(0x1000, "cit1300", 0) ROM_LOAD("tue2a-xbaa_br24c32.cit1300", 0x0000, 0x1000, CRC(dd447884) SHA1(8ae677f46cd39015355a38a7f1147a7abc412674)) ROM_END diff --git a/src/mame/drivers/naomi.cpp b/src/mame/drivers/naomi.cpp index a167665eedf..71b2e2cf0e2 100644 --- a/src/mame/drivers/naomi.cpp +++ b/src/mame/drivers/naomi.cpp @@ -1625,6 +1625,7 @@ Premier Eleven #include "emu.h" #include "includes/naomi.h" +#include "machine/gunsense.h" #include "emupal.h" #include "screen.h" #include "speaker.h" @@ -3087,6 +3088,16 @@ void naomi_state::naomim2_kb(machine_config &config) dcctrl1.set_port_tags("P2.M", "P2.LD", "P2.KC1", "P2.KC2", "P2.KC3", "P2.KC4", "P2.KC5", "P2.KC6"); } +/* + * Naomi M2 with Gun Sense board + */ + +void naomi_state::naomim2_gun(machine_config &config) +{ + naomim2(config); + SEGA_GUNSENSE(config, "gun_board"); +} + /* * Naomi GD with Keyboard controllers */ @@ -3412,15 +3423,6 @@ OFF OFF ON Australia */ -/* - Gun board info: - "838-13143-nn IC BD GUN SENSE xxx" board, D78213 MCU based, was used in big number of Model2 / Model3 / NAOMI / Chihiro / Lindbergh games. - known firmwares: - EPR-20006A oldest revision? - EPR-21262 - older revision, used in: 04 HOD (House of the Dead), 06 JPT (Jurassic Park The Lost World). - TG12 - newer revision, used in: 08 SPY, 09 SPY UR, 11 SPY UR EXTRA - Confidential Mission and later games, backward compatible with older games as well. -*/ - // bios for House of the Dead 2 #define HOTD2_BIOS \ ROM_REGION( 0x200000, "maincpu", 0) \ @@ -3431,11 +3433,7 @@ OFF OFF ON Australia ROM_SYSTEM_BIOS( 2, "bios2", "HOTD2 (Japan)" ) \ ROM_LOAD16_WORD_SWAP_BIOS( 2, "epr-21329.ic27", 0x000000, 0x200000, CRC(d99e5b9b) SHA1(453ffb41b6197cac6d12e7814bb1d7281ccf1659) ) \ ROM_SYSTEM_BIOS( 3, "bios3", "HOTD2 (Proto)" ) \ - ROM_LOAD16_WORD_SWAP_BIOS( 3, "hotd2biosproto.ic27", 0x000000, 0x200000, CRC(ea74e967) SHA1(e4d037480eb6555d335a8ab9cd6c56122335586d) ) \ - ROM_REGION( 0x10000, "gunboard", 0 ) \ - ROM_LOAD( "epr-20006a.ic2",0x00000, 0x10000, CRC(45f310dc) SHA1(b7cf40a1671dc351b607d8d6bba0d51ea128eb75) ) \ - ROM_LOAD( "epr-21262.ic2", 0x00000, 0x10000, CRC(c9adf9b6) SHA1(fc2a331430ef2f009f653b242220599c824cd1d2) ) \ - ROM_LOAD( "tg12.ic2", 0x00000, 0x10000, CRC(2c9600b1) SHA1(91813a43851c48d400fde41b1198dabf55bade2d) ) + ROM_LOAD16_WORD_SWAP_BIOS( 3, "hotd2biosproto.ic27", 0x000000, 0x200000, CRC(ea74e967) SHA1(e4d037480eb6555d335a8ab9cd6c56122335586d) ) #define F355DLX_BIOS \ ROM_REGION( 0x200000, "maincpu", 0) \ @@ -11358,16 +11356,16 @@ ROM_END /* GDROM */ GAME( 2001, naomigd, 0, naomi, naomi, naomi_state, init_naomi, ROT0, "Sega", "Naomi GD-ROM Bios", GAME_FLAGS|MACHINE_IS_BIOS_ROOT ) /* 834-xxxxx (Sega Naomi cart with game specific BIOS sets) */ -/* 13636-01 */ GAME( 1998, hotd2, hod2bios, naomim2, hotd2, naomi_state, init_hotd2, ROT0, "Sega", "The House of the Dead 2 (USA)", GAME_FLAGS ) /* specific BIOS "hod2bios" needed */ -/* 13636 */ GAME( 1998, hotd2o, hotd2, naomim2, hotd2, naomi_state, init_hotd2, ROT0, "Sega", "The House of the Dead 2", GAME_FLAGS ) /* specific BIOS "hod2bios" needed */ -/* ????? */ GAME( 1998, hotd2e, hotd2, naomim2, hotd2, naomi_state, init_hotd2, ROT0, "Sega", "The House of the Dead 2 (Export)", GAME_FLAGS ) /* specific BIOS "hod2bios" needed */ -/* none */ GAME( 1998, hotd2p, hotd2, naomim2, hotd2, naomi_state, init_hotd2, ROT0, "Sega", "The House of the Dead 2 (prototype)", GAME_FLAGS ) /* specific BIOS "hod2bios" needed */ -/* 13842 */ GAME( 1999, f355, f355dlx, naomim2, naomi, naomi_state, empty_init, ROT0, "Sega", "Ferrari F355 Challenge (deluxe, no link)", GAME_FLAGS ) /* specific BIOS "f355dlx" needed */ -/* none */ GAME( 1999, f355p, f355, naomim2, naomi, naomi_state, empty_init, ROT0, "Sega", "Ferrari F355 Challenge (private show version)", GAME_FLAGS ) /* specific BIOS epr-21862p or epr-21864p needed */ -/* 13950 */ GAME( 1999, f355twin, f355bios, naomim2, naomi, naomi_state, empty_init, ROT0, "Sega", "Ferrari F355 Challenge (twin/deluxe)", GAME_FLAGS ) /* specific BIOS "f355bios" needed */ -/* 13950P */ GAME( 1999, f355twinp,f355twin, naomim2, naomi, naomi_state, empty_init, ROT0, "Sega", "Ferrari F355 Challenge (twin/deluxe, preview)", GAME_FLAGS ) /* specific BIOS "f355bios" needed */ -/* none */ GAME( 2001, f355twn2, f355bios, naomim2, naomi, naomi_state, empty_init, ROT0, "Sega", "Ferrari F355 Challenge 2 - International Course Edition (twin/deluxe)", GAME_FLAGS ) /* specific BIOS "f355bios" needed */ -/* ????? */ GAME( 1999, alpilot, airlbios, naomim2, naomi, naomi_state, empty_init, ROT0, "Sega", "Airline Pilots (World, Rev B)", GAME_FLAGS ) // have "Sega Airlines" texts on airplanes, deluxe/multiboard setup uses specific BIOS "airlbios" +/* 13636-01 */ GAME( 1998, hotd2, hod2bios, naomim2_gun, hotd2, naomi_state, init_hotd2, ROT0, "Sega", "The House of the Dead 2 (USA)", GAME_FLAGS ) /* specific BIOS "hod2bios" needed */ +/* 13636 */ GAME( 1998, hotd2o, hotd2, naomim2_gun, hotd2, naomi_state, init_hotd2, ROT0, "Sega", "The House of the Dead 2", GAME_FLAGS ) /* specific BIOS "hod2bios" needed */ +/* ????? */ GAME( 1998, hotd2e, hotd2, naomim2_gun, hotd2, naomi_state, init_hotd2, ROT0, "Sega", "The House of the Dead 2 (Export)", GAME_FLAGS ) /* specific BIOS "hod2bios" needed */ +/* none */ GAME( 1998, hotd2p, hotd2, naomim2_gun, hotd2, naomi_state, init_hotd2, ROT0, "Sega", "The House of the Dead 2 (prototype)", GAME_FLAGS ) /* specific BIOS "hod2bios" needed */ +/* 13842 */ GAME( 1999, f355, f355dlx, naomim2, naomi, naomi_state, empty_init, ROT0, "Sega", "Ferrari F355 Challenge (deluxe, no link)", GAME_FLAGS ) /* specific BIOS "f355dlx" needed */ +/* none */ GAME( 1999, f355p, f355, naomim2, naomi, naomi_state, empty_init, ROT0, "Sega", "Ferrari F355 Challenge (private show version)", GAME_FLAGS ) /* specific BIOS epr-21862p or epr-21864p needed */ +/* 13950 */ GAME( 1999, f355twin, f355bios, naomim2, naomi, naomi_state, empty_init, ROT0, "Sega", "Ferrari F355 Challenge (twin/deluxe)", GAME_FLAGS ) /* specific BIOS "f355bios" needed */ +/* 13950P */ GAME( 1999, f355twinp,f355twin, naomim2, naomi, naomi_state, empty_init, ROT0, "Sega", "Ferrari F355 Challenge (twin/deluxe, preview)", GAME_FLAGS ) /* specific BIOS "f355bios" needed */ +/* none */ GAME( 2001, f355twn2, f355bios, naomim2, naomi, naomi_state, empty_init, ROT0, "Sega", "Ferrari F355 Challenge 2 - International Course Edition (twin/deluxe)", GAME_FLAGS ) /* specific BIOS "f355bios" needed */ +/* ????? */ GAME( 1999, alpilot, airlbios, naomim2, naomi, naomi_state, empty_init, ROT0, "Sega", "Airline Pilots (World, Rev B)", GAME_FLAGS ) // have "Sega Airlines" texts on airplanes, deluxe/multiboard setup uses specific BIOS "airlbios" /* 840-xxxxx (Sega Naomi cart games)*/ /* 0001 */ GAME( 1998, dybbnao, naomi, naomim2, dybbnao, naomi_state, init_naomi, ROT0, "Sega", "Dynamite Baseball NAOMI (Japan)", GAME_FLAGS ) diff --git a/src/mame/includes/naomi.h b/src/mame/includes/naomi.h index 9c6a3173851..677d02e9124 100644 --- a/src/mame/includes/naomi.h +++ b/src/mame/includes/naomi.h @@ -27,6 +27,7 @@ naomi.h -> NAOMI includes #include "machine/jvsdev.h" #include "machine/jvs13551.h" #include "machine/m3comm.h" +#include "machine/gunsense.h" #include "dc.h" enum { @@ -50,6 +51,7 @@ class naomi_state : public dc_state void naomi_base(machine_config &config); void naomim2(machine_config &config); void naomim2_kb(machine_config &config); + void naomim2_gun(machine_config &config); void naomi(machine_config &config); void naomim1(machine_config &config); void naomigd(machine_config &config); diff --git a/src/mame/machine/gunsense.cpp b/src/mame/machine/gunsense.cpp new file mode 100644 index 00000000000..9f7ccd1e39c --- /dev/null +++ b/src/mame/machine/gunsense.cpp @@ -0,0 +1,53 @@ +// license:BSD-3-Clause +// copyright-holders:AJR + +#include "emu.h" +#include "gunsense.h" + +#include "cpu/upd78k/upd78k2.h" + +// device type definition +DEFINE_DEVICE_TYPE(SEGA_GUNSENSE, sega_gunsense_board_device, "gunsense", "Sega 838-13143 Gun Sense Board") + +sega_gunsense_board_device::sega_gunsense_board_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, SEGA_GUNSENSE, tag, owner, clock) +{ +} + +void sega_gunsense_board_device::device_start() +{ +} + + +void sega_gunsense_board_device::mem_map(address_map &map) +{ + map(0x00000, 0x0fcff).rom().region("gunmcu", 0); +} + + +void sega_gunsense_board_device::device_add_mconfig(machine_config &config) +{ + upd78213_device &mcu(UPD78213(config, "gunmcu", 12'000'000)); // clock unknown + mcu.set_addrmap(AS_PROGRAM, &sega_gunsense_board_device::mem_map); +} + +/* + Gun board info: + "838-13143-nn IC BD GUN SENSE xxx" board, D78213 MCU based, was used in big number of Model2 / Model3 / NAOMI / Chihiro / Lindbergh games. + known firmwares: + EPR-20006A oldest revision? + EPR-21262 - older revision, used in: 04 HOD (House of the Dead 2), 06 JPT (Jurassic Park The Lost World). + TG12 - newer revision, used in: 08 SPY, 09 SPY UR, 11 SPY UR EXTRA - Confidential Mission and later games, backward compatible with older games as well. +*/ + +ROM_START(gunsense) + ROM_REGION( 0x10000, "gunmcu", 0 ) + ROM_LOAD( "epr-20006a.ic2",0x00000, 0x10000, CRC(45f310dc) SHA1(b7cf40a1671dc351b607d8d6bba0d51ea128eb75) ) \ + ROM_LOAD( "epr-21262.ic2", 0x00000, 0x10000, CRC(c9adf9b6) SHA1(fc2a331430ef2f009f653b242220599c824cd1d2) ) \ + ROM_LOAD( "tg12.ic2", 0x00000, 0x10000, CRC(2c9600b1) SHA1(91813a43851c48d400fde41b1198dabf55bade2d) ) +ROM_END + +const tiny_rom_entry *sega_gunsense_board_device::device_rom_region() const +{ + return ROM_NAME(gunsense); +} diff --git a/src/mame/machine/gunsense.h b/src/mame/machine/gunsense.h new file mode 100644 index 00000000000..82c77f8127f --- /dev/null +++ b/src/mame/machine/gunsense.h @@ -0,0 +1,24 @@ +// license:BSD-3-Clause +// copyright-holders:AJR + +#ifndef MAME_MACHINE_GUNSENSE_H +#define MAME_MACHINE_GUNSENSE_H + +class sega_gunsense_board_device : public device_t +{ +public: + sega_gunsense_board_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); + +protected: + virtual void device_start() override; + virtual void device_add_mconfig(machine_config &config) override; + virtual const tiny_rom_entry *device_rom_region() const override; + +private: + void mem_map(address_map &map); +}; + +// device type declaration +DECLARE_DEVICE_TYPE(SEGA_GUNSENSE, sega_gunsense_board_device) + +#endif // MAME_MACHINE_GUNSENSE_H diff --git a/src/tools/unidasm.cpp b/src/tools/unidasm.cpp index 808f5020d57..084aebf54d3 100644 --- a/src/tools/unidasm.cpp +++ b/src/tools/unidasm.cpp @@ -160,6 +160,9 @@ using util::BIT; #include "cpu/unsp/unspdasm.h" #include "cpu/upd7725/dasm7725.h" #include "cpu/upd7810/upd7810_dasm.h" +#include "cpu/upd78k/upd78k0d.h" +#include "cpu/upd78k/upd78k1d.h" +#include "cpu/upd78k/upd78k2d.h" #include "cpu/v60/v60d.h" #include "cpu/v810/v810dasm.h" #include "cpu/vt50/vt50dasm.h" @@ -529,9 +532,28 @@ static const dasm_table_entry dasm_table[] = { "unsp20", be, -1, []() -> util::disasm_interface * { return new unsp_20_disassembler; } }, { "upd7725", be, -2, []() -> util::disasm_interface * { return new necdsp_disassembler; } }, { "upd7801", le, 0, []() -> util::disasm_interface * { return new upd7801_disassembler; } }, + { "upd78c05", le, 0, []() -> util::disasm_interface * { return new upd78c05_disassembler; } }, { "upd7807", le, 0, []() -> util::disasm_interface * { return new upd7807_disassembler; } }, { "upd7810", le, 0, []() -> util::disasm_interface * { return new upd7810_disassembler; } }, - { "upd78c05", le, 0, []() -> util::disasm_interface * { return new upd78c05_disassembler; } }, + { "upd78014", le, 0, []() -> util::disasm_interface * { return new upd78014_disassembler; } }, + { "upd78024", le, 0, []() -> util::disasm_interface * { return new upd78024_disassembler; } }, + { "upd78044a", le, 0, []() -> util::disasm_interface * { return new upd78044a_disassembler; } }, + { "upd78054", le, 0, []() -> util::disasm_interface * { return new upd78054_disassembler; } }, + { "upd78064", le, 0, []() -> util::disasm_interface * { return new upd78064_disassembler; } }, + { "upd78078", le, 0, []() -> util::disasm_interface * { return new upd78078_disassembler; } }, + { "upd78083", le, 0, []() -> util::disasm_interface * { return new upd78083_disassembler; } }, + { "upd78138", le, 0, []() -> util::disasm_interface * { return new upd78138_disassembler; } }, + { "upd78148", le, 0, []() -> util::disasm_interface * { return new upd78148_disassembler; } }, + { "upd78214", le, 0, []() -> util::disasm_interface * { return new upd78214_disassembler; } }, + { "upd78218a", le, 0, []() -> util::disasm_interface * { return new upd78218a_disassembler; } }, + { "upd78224", le, 0, []() -> util::disasm_interface * { return new upd78224_disassembler; } }, + { "upd78234", le, 0, []() -> util::disasm_interface * { return new upd78234_disassembler; } }, + { "upd78244", le, 0, []() -> util::disasm_interface * { return new upd78244_disassembler; } }, + { "upd780024a", le, 0, []() -> util::disasm_interface * { return new upd780024a_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; } }, + { "upd78k0kx2", le, 0, []() -> util::disasm_interface * { return new upd78k0kx2_disassembler; } }, { "upi41", le, 0, []() -> util::disasm_interface * { return new mcs48_disassembler(true, false); } }, { "v60", le, 0, []() -> util::disasm_interface * { return new v60_disassembler; } }, { "v810", le, 0, []() -> util::disasm_interface * { return new v810_disassembler; } },