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:
AJR 2020-02-10 23:41:06 -05:00
parent 7ae638551e
commit d7db95aea9
21 changed files with 4142 additions and 36 deletions

View File

@ -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

View File

@ -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",

View File

@ -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

View 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
}

View 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

File diff suppressed because it is too large Load Diff

View 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 &params) 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

View 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 &params)
{
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
};

View 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 &params) 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

View 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
}

View 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

View 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
};

View 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

View 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"
};

View 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

View File

@ -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

View File

@ -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 )

View File

@ -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);

View 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);
}

View 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

View File

@ -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; } },