mirror of
https://github.com/holub/mame
synced 2025-06-05 12:26:35 +03:00
Add disassemblers for NEC 78K/0, 78K/I and 78K/II MCU types
hotd2: Make "Gun Sense" board a separate device
This commit is contained in:
parent
7ae638551e
commit
d7db95aea9
@ -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
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
|
238
src/devices/cpu/upd78k/upd78k0.cpp
Normal file
238
src/devices/cpu/upd78k/upd78k0.cpp
Normal file
@ -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<u8>(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<u16>(UPD78K0_AX + n, std::array<const char *, 4>{{"AX", "BC", "DE", "HL"}}[n],
|
||||
[this, iram, n]() { return static_cast<u16 *>(iram)[(debug_register_base() >> 1) | n]; },
|
||||
[this, iram, n](u16 data) { static_cast<u16 *>(iram)[(debug_register_base() >> 1) | n] = data; }
|
||||
);
|
||||
for (int n = 0; n < 8; n++)
|
||||
state_add<u8>(UPD78K0_X + n, std::array<const char *, 8>{{"X", "A", "C", "B", "E", "D", "L", "H"}}[n],
|
||||
[this, iram, n]() { return static_cast<u8 *>(iram)[BYTE_XOR_LE(debug_register_base() | n)]; },
|
||||
[this, iram, n](u8 data) { static_cast<u8 *>(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<util::disasm_interface> upd78053_device::create_disassembler()
|
||||
{
|
||||
return std::make_unique<upd78054_disassembler>();
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// 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
|
||||
}
|
107
src/devices/cpu/upd78k/upd78k0.h
Normal file
107
src/devices/cpu/upd78k/upd78k0.h
Normal file
@ -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 <typename X>
|
||||
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<X>(subclock));
|
||||
}
|
||||
|
||||
protected:
|
||||
// device_disasm_interface overrides
|
||||
virtual std::unique_ptr<util::disasm_interface> 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
|
1348
src/devices/cpu/upd78k/upd78k0d.cpp
Normal file
1348
src/devices/cpu/upd78k/upd78k0d.cpp
Normal file
File diff suppressed because it is too large
Load Diff
160
src/devices/cpu/upd78k/upd78k0d.h
Normal file
160
src/devices/cpu/upd78k/upd78k0d.h
Normal file
@ -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
|
840
src/devices/cpu/upd78k/upd78k1d.cpp
Normal file
840
src/devices/cpu/upd78k/upd78k1d.cpp
Normal file
@ -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
|
||||
};
|
65
src/devices/cpu/upd78k/upd78k1d.h
Normal file
65
src/devices/cpu/upd78k/upd78k1d.h
Normal file
@ -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
|
217
src/devices/cpu/upd78k/upd78k2.cpp
Normal file
217
src/devices/cpu/upd78k/upd78k2.cpp
Normal file
@ -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<u8>(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<u16>(UPD78K2_AX + n, std::array<const char *, 4>{{"AX", "BC", "DE", "HL"}}[n],
|
||||
[this, iram, n]() { return static_cast<u16 *>(iram)[(register_base() >> 1) | n]; },
|
||||
[this, iram, n](u16 data) { static_cast<u16 *>(iram)[(register_base() >> 1) | n] = data; }
|
||||
);
|
||||
for (int n = 0; n < 8; n++)
|
||||
state_add<u8>(UPD78K2_X + n, std::array<const char *, 8>{{"X", "A", "C", "B", "E", "D", "L", "H"}}[n],
|
||||
[this, iram, n]() { return static_cast<u8 *>(iram)[BYTE_XOR_LE(register_base() | n)]; },
|
||||
[this, iram, n](u8 data) { static_cast<u8 *>(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<util::disasm_interface> upd78213_device::create_disassembler()
|
||||
{
|
||||
return std::make_unique<upd78214_disassembler>();
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// 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
|
||||
}
|
96
src/devices/cpu/upd78k/upd78k2.h
Normal file
96
src/devices/cpu/upd78k/upd78k2.h
Normal file
@ -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<util::disasm_interface> 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
|
584
src/devices/cpu/upd78k/upd78k2d.cpp
Normal file
584
src/devices/cpu/upd78k/upd78k2d.cpp
Normal file
@ -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
|
||||
};
|
85
src/devices/cpu/upd78k/upd78k2d.h
Normal file
85
src/devices/cpu/upd78k/upd78k2d.h
Normal file
@ -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
|
179
src/devices/cpu/upd78k/upd78kd.cpp
Normal file
179
src/devices/cpu/upd78k/upd78kd.cpp
Normal file
@ -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"
|
||||
};
|
50
src/devices/cpu/upd78k/upd78kd.h
Normal file
50
src/devices/cpu/upd78k/upd78kd.h
Normal file
@ -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
|
@ -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<upd78053_device> m_cit1500;
|
||||
required_device<upd78053_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
|
||||
|
@ -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 )
|
||||
|
@ -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);
|
||||
|
53
src/mame/machine/gunsense.cpp
Normal file
53
src/mame/machine/gunsense.cpp
Normal file
@ -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);
|
||||
}
|
24
src/mame/machine/gunsense.h
Normal file
24
src/mame/machine/gunsense.h
Normal file
@ -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
|
@ -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; } },
|
||||
|
Loading…
Reference in New Issue
Block a user