mirror of
https://github.com/holub/mame
synced 2025-04-19 23:12:11 +03:00
New machines marked as NOT_WORKING
---------------------------------- Roland D-50 (Ver. 2.xx) [DBWBP, depblue] New NOT_WORKING clones ---------------------- Roland D-50 (Ver. 1.xx) [DBWBP] Roland D-550 [DBWBP] Add disassembler for NEC 78K/III architecture [AJR]
This commit is contained in:
parent
2d3e38c384
commit
9ce46c7cd5
@ -3145,6 +3145,8 @@ if (CPUS["UPD78K"]~=null) then
|
||||
MAME_DIR .. "src/devices/cpu/upd78k/upd78k0.h",
|
||||
MAME_DIR .. "src/devices/cpu/upd78k/upd78k2.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/upd78k/upd78k2.h",
|
||||
MAME_DIR .. "src/devices/cpu/upd78k/upd78k3.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/upd78k/upd78k3.h",
|
||||
}
|
||||
end
|
||||
|
||||
@ -3157,4 +3159,6 @@ if (CPUS["UPD78K"]~=null or _OPTIONS["with-tools"]) then
|
||||
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")
|
||||
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/upd78k/upd78k3d.cpp")
|
||||
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/upd78k/upd78k3d.h")
|
||||
end
|
||||
|
@ -3211,6 +3211,7 @@ files {
|
||||
createMESSProjects(_target, _subtarget, "roland")
|
||||
files {
|
||||
MAME_DIR .. "src/mame/drivers/roland_cm32p.cpp",
|
||||
MAME_DIR .. "src/mame/drivers/roland_d50.cpp",
|
||||
MAME_DIR .. "src/mame/drivers/roland_d110.cpp",
|
||||
MAME_DIR .. "src/mame/drivers/roland_mt32.cpp",
|
||||
MAME_DIR .. "src/mame/drivers/roland_sc55.cpp",
|
||||
|
347
src/devices/cpu/upd78k/upd78k3.cpp
Normal file
347
src/devices/cpu/upd78k/upd78k3.cpp
Normal file
@ -0,0 +1,347 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
/****************************************************************************
|
||||
|
||||
NEC 78K/III series 16/8-bit single-chip microcontrollers
|
||||
|
||||
Currently these devices are just stubs with no actual execution core.
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "upd78k3.h"
|
||||
#include "upd78k3d.h"
|
||||
|
||||
// device type definition
|
||||
DEFINE_DEVICE_TYPE(UPD78312, upd78312_device, "upd78312", "NEC uPD78312")
|
||||
|
||||
//**************************************************************************
|
||||
// 78K/III CORE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// upd78k3_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
upd78k3_device::upd78k3_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, 16, 0, mem_map)
|
||||
, m_iram_config("IRAM", ENDIANNESS_LITTLE, 16, 8, 0, address_map_constructor(FUNC(upd78k3_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 upd78k3_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 upd78k3_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 upd78k3_device::register_base() const noexcept
|
||||
{
|
||||
return 0x80 | (~m_psw & 0x7000) >> 8;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// state_add_psw - overridable method for PSW
|
||||
// state registration
|
||||
//-------------------------------------------------
|
||||
|
||||
void upd78k3_device::state_add_psw()
|
||||
{
|
||||
state_add(UPD78K3_PSW, "PSW", m_psw).mask(0xf0fd);
|
||||
state_add(STATE_GENFLAGS, "FLAGS", m_psw).mask(0xf0fd).formatstr("%12s").noshow();
|
||||
state_add<u8>(UPD78K3_PSWL, "PSWL",
|
||||
[this]() { return m_psw & 0x00ff; },
|
||||
[this](u8 data) { m_psw = (m_psw & 0xff00) | data; }
|
||||
).mask(0xfd).noshow();
|
||||
state_add<u8>(UPD78K3_PSWH, "PSWH",
|
||||
[this]() { return (m_psw & 0xff00) >> 8; },
|
||||
[this](u8 data) { m_psw = (m_psw & 0x00ff) | u16(data) << 8; }
|
||||
).mask(0xf0).noshow();
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void upd78k3_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(UPD78K3_PC, "PC", m_pc);
|
||||
state_add(STATE_GENPC, "GENPC", m_pc).noshow();
|
||||
state_add(STATE_GENPCBASE, "GENPCBASE", m_ppc).noshow();
|
||||
state_add_psw();
|
||||
state_add<u8>(UPD78K3_RBS, "RBS",
|
||||
[this]() { return (m_psw & 7000) >> 12; },
|
||||
[this](u8 data) { m_psw = (m_psw & 0x8fff) | u16(data) << 12; }
|
||||
).mask(7).noshow();
|
||||
state_add(UPD78K3_SP, "SP", m_sp);
|
||||
void *iram = memshare("iram")->ptr();
|
||||
for (int n = 0; n < 4; n++)
|
||||
state_add<u16>(UPD78K3_RP0 + n, string_format("RP%d", n).c_str(),
|
||||
[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; }
|
||||
).formatstr("%9s");
|
||||
for (int n = 0; n < 2; n++)
|
||||
state_add<u16>(UPD78K3_AX + n, std::array<const char *, 2>{{"AX", "BC"}}[n],
|
||||
[this, iram, n]() { return static_cast<u16 *>(iram)[register_base() >> 1 | (m_psw & 0x0020) >> 4 | n]; },
|
||||
[this, iram, n](u16 data) { static_cast<u16 *>(iram)[register_base() >> 1 | (m_psw & 0x0020) >> 4 | n] = data; }
|
||||
).noshow();
|
||||
for (int n = 0; n < 4; n++)
|
||||
{
|
||||
state_add<u16>(UPD78K3_VP + n, std::array<const char *, 4>{{"VP", "UP", "DE", "HL"}}[n],
|
||||
[this, iram, n]() { return static_cast<u16 *>(iram)[register_base() >> 1 | 0x04 | n]; },
|
||||
[this, iram, n](u16 data) { static_cast<u16 *>(iram)[register_base() >> 1 | 0x04 | n] = data; }
|
||||
);
|
||||
state_add<u16>(UPD78K3_RP4 + n, string_format("RP%d", 4 + n).c_str(),
|
||||
[this, iram, n]() { return static_cast<u16 *>(iram)[register_base() >> 1 | 0x04 | n]; },
|
||||
[this, iram, n](u16 data) { static_cast<u16 *>(iram)[register_base() >> 1 | 0x04 | n] = data; }
|
||||
).noshow();
|
||||
}
|
||||
for (int n = 0; n < 16; n++)
|
||||
state_add<u8>(UPD78K3_R0 + n, string_format("R%d", n).c_str(),
|
||||
[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();
|
||||
for (int n = 0; n < 4; n++)
|
||||
state_add<u8>(UPD78K3_X + n, std::array<const char *, 4>{{"X", "A", "C", "B"}}[n],
|
||||
[this, iram, n]() { return static_cast<u8 *>(iram)[BYTE_XOR_LE(register_base() | (m_psw & 0x0020) >> 3 | n)]; },
|
||||
[this, iram, n](u8 data) { static_cast<u8 *>(iram)[BYTE_XOR_LE(register_base() | (m_psw & 0x0020) >> 3 | n)] = data; }
|
||||
).noshow();
|
||||
for (int n = 0; n < 8; n++)
|
||||
state_add<u8>(UPD78K3_VPL + n, std::array<const char *, 8>{{"VPL", "VPH", "UPL", "UPH", "E", "D", "L", "H"}}[n],
|
||||
[this, iram, n]() { return static_cast<u8 *>(iram)[BYTE_XOR_LE(register_base() | 0x08 | n)]; },
|
||||
[this, iram, n](u8 data) { static_cast<u8 *>(iram)[BYTE_XOR_LE(register_base() | 0x08 | n)] = data; }
|
||||
).noshow();
|
||||
|
||||
// save state
|
||||
save_item(NAME(m_pc));
|
||||
save_item(NAME(m_ppc));
|
||||
save_item(NAME(m_sp));
|
||||
save_item(NAME(m_psw));
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_reset - device-specific reset
|
||||
//-------------------------------------------------
|
||||
|
||||
void upd78k3_device::device_reset()
|
||||
{
|
||||
// PC will be initialized from vector following reset
|
||||
m_psw = 0x0000;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// execute_run -
|
||||
//-------------------------------------------------
|
||||
|
||||
void upd78k3_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 upd78k3_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%c%c%c",
|
||||
(m_psw & 0x7000) >> 12,
|
||||
BIT(m_psw, 15) ? 'U' : '.',
|
||||
BIT(m_psw, 7) ? 'S' : '.',
|
||||
BIT(m_psw, 6) ? 'Z' : '.',
|
||||
BIT(m_psw, 5) ? 'R' : '.',
|
||||
BIT(m_psw, 4) ? 'A' : '.',
|
||||
BIT(m_psw, 3) ? 'I' : '.',
|
||||
BIT(m_psw, 2) ? 'V' : '.',
|
||||
BIT(m_psw, 0) ? 'C' : '.');
|
||||
break;
|
||||
|
||||
#if 0 // doesn't compile because value() is protected
|
||||
case UPD78K3_RP0:
|
||||
str = string_format("%04X %s", entry.value(), BIT(m_psw, 5) ? " " : "(AX)");
|
||||
break;
|
||||
|
||||
case UPD78K3_RP1:
|
||||
str = string_format("%04X %s", entry.value(), BIT(m_psw, 5) ? " " : "(BC)");
|
||||
break;
|
||||
|
||||
case UPD78K3_RP2:
|
||||
str = string_format("%04X %s", entry.value(), BIT(m_psw, 5) ? "(AX)" : " ");
|
||||
break;
|
||||
|
||||
case UPD78K3_RP3:
|
||||
str = string_format("%04X %s", entry.value(), BIT(m_psw, 5) ? "(BC)" : " ");
|
||||
break;
|
||||
#else // nasty and inefficient workaround
|
||||
case UPD78K3_RP0:
|
||||
str = string_format("%04X %s", const_cast<upd78k3_device &>(*this).state_int(UPD78K3_RP0), BIT(m_psw, 5) ? " " : "(AX)");
|
||||
break;
|
||||
|
||||
case UPD78K3_RP1:
|
||||
str = string_format("%04X %s", const_cast<upd78k3_device &>(*this).state_int(UPD78K3_RP1), BIT(m_psw, 5) ? " " : "(BC)");
|
||||
break;
|
||||
|
||||
case UPD78K3_RP2:
|
||||
str = string_format("%04X %s", const_cast<upd78k3_device &>(*this).state_int(UPD78K3_RP2), BIT(m_psw, 5) ? "(AX)" : " ");
|
||||
break;
|
||||
|
||||
case UPD78K3_RP3:
|
||||
str = string_format("%04X %s", const_cast<upd78k3_device &>(*this).state_int(UPD78K3_RP3), BIT(m_psw, 5) ? "(BC)" : " ");
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// 78K/III SUBSERIES DEVICES
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// upd78312_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
upd78312_device::upd78312_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: upd78k3_device(mconfig, UPD78312, tag, owner, clock,
|
||||
address_map_constructor(FUNC(upd78312_device::mem_map), this),
|
||||
address_map_constructor(FUNC(upd78312_device::sfr_map), this))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// create_disassembler -
|
||||
//-------------------------------------------------
|
||||
|
||||
std::unique_ptr<util::disasm_interface> upd78312_device::create_disassembler()
|
||||
{
|
||||
return std::make_unique<upd78312_disassembler>();
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// mem_map - type-specific internal memory map
|
||||
// (excluding IRAM and SFRs)
|
||||
//-------------------------------------------------
|
||||
|
||||
void upd78312_device::mem_map(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x1fff).rom().region(DEVICE_SELF, 0); // 8K mask ROM
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// sfr_map - type-specific SFR map
|
||||
//-------------------------------------------------
|
||||
|
||||
void upd78312_device::sfr_map(address_map &map)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// state_add_psw - overridable method for PSW
|
||||
// state registration
|
||||
//-------------------------------------------------
|
||||
|
||||
void upd78312_device::state_add_psw()
|
||||
{
|
||||
state_add(UPD78K3_PSW, "PSW", m_psw).mask(0x72ff);
|
||||
state_add(STATE_GENFLAGS, "FLAGS", m_psw).mask(0x72ff).formatstr("%13s").noshow();
|
||||
state_add<u8>(UPD78K3_PSWL, "PSWL",
|
||||
[this]() { return m_psw & 0x00ff; },
|
||||
[this](u8 data) { m_psw = (m_psw & 0xff00) | data; }
|
||||
).noshow();
|
||||
state_add<u8>(UPD78K3_PSWH, "PSWH",
|
||||
[this]() { return (m_psw & 0xff00) >> 8; },
|
||||
[this](u8 data) { m_psw = (m_psw & 0x00ff) | u16(data) << 8; }
|
||||
).mask(0x72).noshow();
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// state_string_export -
|
||||
//-------------------------------------------------
|
||||
|
||||
void upd78312_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%c%c%c%c",
|
||||
(m_psw & 0x7000) >> 12,
|
||||
BIT(m_psw, 9) ? 'I' : '.',
|
||||
BIT(m_psw, 7) ? 'S' : '.',
|
||||
BIT(m_psw, 6) ? 'Z' : '.',
|
||||
BIT(m_psw, 5) ? 'R' : '.',
|
||||
BIT(m_psw, 4) ? 'A' : '.',
|
||||
BIT(m_psw, 3) ? 'I' : '.',
|
||||
BIT(m_psw, 2) ? 'V' : '.',
|
||||
BIT(m_psw, 1) ? '-' : '+',
|
||||
BIT(m_psw, 0) ? 'C' : '.');
|
||||
break;
|
||||
|
||||
default:
|
||||
upd78k3_device::state_string_export(entry, str);
|
||||
break;
|
||||
}
|
||||
}
|
114
src/devices/cpu/upd78k/upd78k3.h
Normal file
114
src/devices/cpu/upd78k/upd78k3.h
Normal file
@ -0,0 +1,114 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
/**********************************************************************
|
||||
|
||||
NEC 78K/III series 16/8-bit single-chip microcontrollers
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef MAME_CPU_UPD78K_UPD78K3_H
|
||||
#define MAME_CPU_UPD78K_UPD78K3_H
|
||||
|
||||
#pragma once
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
// ======================> upd78k3_device
|
||||
|
||||
class upd78k3_device : public cpu_device
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
UPD78K3_PC,
|
||||
UPD78K3_PSW, UPD78K3_PSWL, UPD78K3_PSWH, UPD78K3_RBS, UPD78K3_SP,
|
||||
UPD78K3_RP0, UPD78K3_RP1, UPD78K3_RP2, UPD78K3_RP3,
|
||||
UPD78K3_RP4, UPD78K3_RP5, UPD78K3_RP6, UPD78K3_RP7,
|
||||
UPD78K3_AX, UPD78K3_BC,
|
||||
UPD78K3_VP, UPD78K3_UP, UPD78K3_DE, UPD78K3_HL,
|
||||
UPD78K3_R0, UPD78K3_R1, UPD78K3_R2, UPD78K3_R3,
|
||||
UPD78K3_R4, UPD78K3_R5, UPD78K3_R6, UPD78K3_R7,
|
||||
UPD78K3_R8, UPD78K3_R9, UPD78K3_R10, UPD78K3_R11,
|
||||
UPD78K3_R12, UPD78K3_R13, UPD78K3_R14, UPD78K3_R15,
|
||||
UPD78K3_X, UPD78K3_A, UPD78K3_C, UPD78K3_B,
|
||||
UPD78K3_VPL, UPD78K3_VPH, UPD78K3_UPL, UPD78K3_UPH,
|
||||
UPD78K3_E, UPD78K3_D, UPD78K3_L, UPD78K3_H
|
||||
};
|
||||
|
||||
// TODO: callbacks and configuration thereof
|
||||
|
||||
protected:
|
||||
upd78k3_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;
|
||||
|
||||
virtual void state_add_psw();
|
||||
|
||||
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;
|
||||
protected:
|
||||
u16 m_psw;
|
||||
private:
|
||||
u16 m_sp;
|
||||
s32 m_icount;
|
||||
};
|
||||
|
||||
// ======================> upd78312_device
|
||||
|
||||
class upd78312_device : public upd78k3_device
|
||||
{
|
||||
public:
|
||||
// device type constructor
|
||||
upd78312_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;
|
||||
|
||||
// device_state_interface overrides
|
||||
virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
|
||||
|
||||
// upd78k3_device overrides
|
||||
virtual void state_add_psw() 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(UPD78312, upd78312_device)
|
||||
|
||||
#endif // MAME_CPU_UPD78K_UPD7832_H
|
1648
src/devices/cpu/upd78k/upd78k3d.cpp
Normal file
1648
src/devices/cpu/upd78k/upd78k3d.cpp
Normal file
File diff suppressed because it is too large
Load Diff
164
src/devices/cpu/upd78k/upd78k3d.h
Normal file
164
src/devices/cpu/upd78k/upd78k3d.h
Normal file
@ -0,0 +1,164 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
|
||||
#ifndef MAME_CPU_UPD78K_UPD78K3D_H
|
||||
#define MAME_CPU_UPD78K_UPD78K3D_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "upd78kd.h"
|
||||
|
||||
class upd78k3_disassembler : public upd78k_family_disassembler
|
||||
{
|
||||
protected:
|
||||
upd78k3_disassembler(const char *const sfr_names[], const char *const sfrp_names[], const char *const psw_bits[], bool has_macw, bool has_macsw);
|
||||
upd78k3_disassembler(const char *const sfr_names[], const char *const sfrp_names[], const char *const ix_bases[]);
|
||||
|
||||
// register and mnemonic tables
|
||||
static const char *const s_r_names[16];
|
||||
static const char *const s_rp_names[8];
|
||||
static const char *const s_ix_bases[5];
|
||||
static const char *const s_psw_bits[16];
|
||||
static const char *const s_alu_ops[8];
|
||||
static const char *const s_16bit_ops[4];
|
||||
static const char *const s_bool_ops[4];
|
||||
static const char *const s_shift_ops[2][4];
|
||||
static const char *const s_bcond[8];
|
||||
static const char *const s_bcond_07f8[6];
|
||||
static const char *const s_cmpscond[4];
|
||||
|
||||
// disasm_interface overrides
|
||||
virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override;
|
||||
|
||||
// disassembly helpers
|
||||
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_04(std::ostream &stream);
|
||||
virtual offs_t dasm_05xx(std::ostream &stream, u8 op2);
|
||||
virtual offs_t dasm_06xx(std::ostream &stream, u8 op2, offs_t pc, const data_buffer &opcodes);
|
||||
virtual offs_t dasm_07xx(std::ostream &stream, u8 op2, 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);
|
||||
offs_t dasm_09xx_sfrmov(std::ostream &stream, u8 sfr, offs_t pc, const data_buffer &opcodes);
|
||||
virtual offs_t dasm_0axx(std::ostream &stream, u8 op2, offs_t pc, const data_buffer &opcodes);
|
||||
offs_t dasm_15xx(std::ostream &stream, u8 op2);
|
||||
virtual offs_t dasm_16xx(std::ostream &stream, u8 op1, u8 op2);
|
||||
virtual offs_t dasm_24xx(std::ostream &stream, u8 op, u8 rr);
|
||||
virtual offs_t dasm_2a(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_3c(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);
|
||||
virtual offs_t dasm_88xx(std::ostream &stream, u8 op, u8 rr);
|
||||
|
||||
// parameters
|
||||
const char *const *const m_ix_bases;
|
||||
const char *const *const m_psw_bits;
|
||||
const bool m_has_macw;
|
||||
const bool m_has_macsw;
|
||||
};
|
||||
|
||||
class upd78312_disassembler : public upd78k3_disassembler
|
||||
{
|
||||
public:
|
||||
upd78312_disassembler();
|
||||
|
||||
protected:
|
||||
// upd78k3_disassembler overrides
|
||||
virtual offs_t dasm_04(std::ostream &stream) override;
|
||||
virtual offs_t dasm_05xx(std::ostream &stream, u8 op2) override;
|
||||
virtual offs_t dasm_06xx(std::ostream &stream, u8 op2, offs_t pc, const data_buffer &opcodes) override;
|
||||
virtual offs_t dasm_07xx(std::ostream &stream, u8 op2, offs_t pc, const data_buffer &opcodes) override;
|
||||
virtual offs_t dasm_09xx(std::ostream &stream, u8 op2, offs_t pc, const data_buffer &opcodes) override;
|
||||
virtual offs_t dasm_0axx(std::ostream &stream, u8 op2, offs_t pc, const data_buffer &opcodes) override;
|
||||
virtual offs_t dasm_16xx(std::ostream &stream, u8 op1, u8 op2) override;
|
||||
virtual offs_t dasm_50(std::ostream &stream, u8 op) override;
|
||||
|
||||
private:
|
||||
// SFR tables
|
||||
static const char *const s_sfr_names[256];
|
||||
static const char *const s_sfrp_names[128];
|
||||
|
||||
// PSW table
|
||||
static const char *const s_psw_bits[16];
|
||||
};
|
||||
|
||||
class upd78322_disassembler : public upd78k3_disassembler
|
||||
{
|
||||
public:
|
||||
upd78322_disassembler();
|
||||
|
||||
private:
|
||||
// SFR tables
|
||||
static const char *const s_sfr_names[256];
|
||||
static const char *const s_sfrp_names[128];
|
||||
};
|
||||
|
||||
class upd78328_disassembler : public upd78k3_disassembler
|
||||
{
|
||||
public:
|
||||
upd78328_disassembler();
|
||||
|
||||
private:
|
||||
// SFR tables
|
||||
static const char *const s_sfr_names[256];
|
||||
static const char *const s_sfrp_names[128];
|
||||
};
|
||||
|
||||
class upd78334_disassembler : public upd78k3_disassembler
|
||||
{
|
||||
public:
|
||||
upd78334_disassembler();
|
||||
|
||||
private:
|
||||
// SFR tables
|
||||
static const char *const s_sfr_names[256];
|
||||
static const char *const s_sfrp_names[128];
|
||||
};
|
||||
|
||||
class upd78352_disassembler : public upd78k3_disassembler
|
||||
{
|
||||
public:
|
||||
upd78352_disassembler();
|
||||
|
||||
private:
|
||||
// SFR tables
|
||||
static const char *const s_sfr_names[256];
|
||||
static const char *const s_sfrp_names[128];
|
||||
};
|
||||
|
||||
class upd78356_disassembler : public upd78k3_disassembler
|
||||
{
|
||||
public:
|
||||
upd78356_disassembler();
|
||||
|
||||
private:
|
||||
// SFR tables
|
||||
static const char *const s_sfr_names[256];
|
||||
static const char *const s_sfrp_names[128];
|
||||
};
|
||||
|
||||
class upd78366a_disassembler : public upd78k3_disassembler
|
||||
{
|
||||
public:
|
||||
upd78366a_disassembler();
|
||||
|
||||
private:
|
||||
// SFR tables
|
||||
static const char *const s_sfr_names[256];
|
||||
static const char *const s_sfrp_names[128];
|
||||
};
|
||||
|
||||
class upd78372_disassembler : public upd78k3_disassembler
|
||||
{
|
||||
public:
|
||||
upd78372_disassembler();
|
||||
|
||||
private:
|
||||
// SFR tables
|
||||
static const char *const s_sfr_names[256];
|
||||
static const char *const s_sfrp_names[128];
|
||||
};
|
||||
|
||||
#endif // MAME_CPU_UPD78K_UPD78K3D_H
|
@ -105,6 +105,18 @@ void upd78k_family_disassembler::format_sfrp(std::ostream &stream, u8 addr)
|
||||
util::stream_format(stream, "0%04XH", 0xff00 + addr);
|
||||
}
|
||||
|
||||
void upd78k_family_disassembler::format_count(std::ostream &stream, u8 n)
|
||||
{
|
||||
if (n < 0x0a)
|
||||
util::stream_format(stream, "%d", n);
|
||||
else
|
||||
{
|
||||
if (n >= 0x0a)
|
||||
stream << "0";
|
||||
util::stream_format(stream, "%02XH", n);
|
||||
}
|
||||
}
|
||||
|
||||
void upd78k_family_disassembler::format_saddrp(std::ostream &stream, u8 addr)
|
||||
{
|
||||
if (addr < 0x20)
|
||||
|
@ -25,6 +25,7 @@ protected:
|
||||
void format_saddr(std::ostream &stream, u8 addr);
|
||||
void format_sfrp(std::ostream &stream, u8 addr);
|
||||
void format_saddrp(std::ostream &stream, u8 addr);
|
||||
void format_count(std::ostream &stream, u8 n);
|
||||
|
||||
// generic illegal instruction dissasembly
|
||||
offs_t dasm_illegal(std::ostream &stream, u8 op);
|
||||
|
110
src/mame/drivers/roland_d50.cpp
Normal file
110
src/mame/drivers/roland_d50.cpp
Normal file
@ -0,0 +1,110 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
/****************************************************************************
|
||||
|
||||
Skeleton driver for Roland D-50/D-550.
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/upd78k/upd78k3.h"
|
||||
|
||||
class roland_d50_state : public driver_device
|
||||
{
|
||||
public:
|
||||
roland_d50_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_maincpu(*this, "maincpu")
|
||||
{
|
||||
}
|
||||
|
||||
void d50(machine_config &config);
|
||||
|
||||
private:
|
||||
void mem_map(address_map &map);
|
||||
|
||||
required_device<upd78312_device> m_maincpu;
|
||||
};
|
||||
|
||||
|
||||
void roland_d50_state::mem_map(address_map &map)
|
||||
{
|
||||
// Internal ROM is enabled at 0000–1FFF (+5V pullup on EA pin)
|
||||
map(0x2000, 0xfdff).rom().region("progrom", 0x2000); // TODO: banking
|
||||
}
|
||||
|
||||
|
||||
static INPUT_PORTS_START(d50)
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
void roland_d50_state::d50(machine_config &config)
|
||||
{
|
||||
UPD78312(config, m_maincpu, 12_MHz_XTAL);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &roland_d50_state::mem_map);
|
||||
|
||||
// LCD unit is LM402802 (D-50) or LM402551 (D-550)
|
||||
|
||||
//MB87136(config, "synthe", 32.768_MHz_XTAL);
|
||||
}
|
||||
|
||||
|
||||
ROM_START(d50)
|
||||
ROM_REGION(0x10000, "progrom", 0)
|
||||
ROM_SYSTEM_BIOS(0, "v2.22", "ROM Version 2.22")
|
||||
ROMX_LOAD("d-50_222.bin", 0x00000, 0x10000, CRC(e92c69f9) SHA1(fd783abc7fbd4abe2dedfe89d59e396b5e687a27), ROM_BIOS(0))
|
||||
ROM_SYSTEM_BIOS(1, "v2.20", "ROM Version 2.20 (CFW, patched)")
|
||||
ROMX_LOAD("roland_d50_220rw_cfw_patched.bin", 0x00000, 0x10000, CRC(8901640e) SHA1(abbc0026c64c55a6cbaca5e3e5dcb1a7536e91b3), ROM_BIOS(1))
|
||||
ROM_SYSTEM_BIOS(2, "v2.10", "ROM Version 2.10")
|
||||
ROMX_LOAD("d50 - v.2.10 - ic22 - 27c512.bin", 0x00000, 0x10000, CRC(d1387c54) SHA1(904cf9daf296a66d3c4969266541983081e19471), ROM_BIOS(2))
|
||||
|
||||
ROM_REGION(0x2000, "maincpu", 0)
|
||||
ROM_LOAD("d78312g-022_15179266.ic25", 0x0000, 0x2000, NO_DUMP) // 8-digit Roland part number not printed on IC
|
||||
ROM_COPY("progrom", 0x0000, 0x0000, 0x2000)
|
||||
|
||||
ROM_REGION(0x40000, "pcma", 0)
|
||||
ROM_LOAD("tc532000p-7469.ic30", 0x00000, 0x40000, NO_DUMP)
|
||||
|
||||
ROM_REGION(0x40000, "pcmb", 0)
|
||||
ROM_LOAD("tc532000p-7470.ic29", 0x00000, 0x40000, NO_DUMP)
|
||||
ROM_END
|
||||
|
||||
ROM_START(d50a)
|
||||
ROM_REGION(0x10000, "progrom", 0)
|
||||
ROM_SYSTEM_BIOS(0, "v1.06", "ROM Version 1.06")
|
||||
ROMX_LOAD("d50-v1.06.bin", 0x00000, 0x10000, CRC(ccba4e46) SHA1(ce56321226dbbf7dbfac2ad344da447ad6448ee8), ROM_BIOS(0))
|
||||
|
||||
ROM_REGION(0x2000, "maincpu", 0)
|
||||
ROM_LOAD("d78312g-017_15179261.ic25", 0x0000, 0x2000, NO_DUMP) // not compatible with newer firmware
|
||||
ROM_COPY("progrom", 0x0000, 0x0000, 0x2000)
|
||||
|
||||
ROM_REGION(0x40000, "pcma", 0)
|
||||
ROM_LOAD("tc532000p-7469.ic30", 0x00000, 0x40000, NO_DUMP)
|
||||
|
||||
ROM_REGION(0x40000, "pcmb", 0)
|
||||
ROM_LOAD("tc532000p-7470.ic29", 0x00000, 0x40000, NO_DUMP)
|
||||
ROM_END
|
||||
|
||||
ROM_START(d550)
|
||||
ROM_REGION(0x10000, "progrom", 0)
|
||||
ROM_SYSTEM_BIOS(0, "v1.02", "ROM Version 1.02")
|
||||
ROMX_LOAD("roland d-550 v1.02 eprom firmware.bin", 0x00000, 0x10000, CRC(11b54d24) SHA1(d11bdb50c49edababec73a936346a6f918dd0949), ROM_BIOS(0))
|
||||
ROM_SYSTEM_BIOS(1, "v1.01", "ROM Version 1.01")
|
||||
ROMX_LOAD("roland_d-550_ver_1.01.bin", 0x00000, 0x10000, CRC(c267019f) SHA1(314616d14b91e8c8733aee5dd64736fda8ff6904), ROM_BIOS(1))
|
||||
ROM_SYSTEM_BIOS(2, "v1.0.0", "ROM Version 1.0.0")
|
||||
ROMX_LOAD("d-550__1.0.0.mbm27c512.ic22.bin", 0x00000, 0x10000, CRC(f8ec84c3) SHA1(00b2b74009bdc0747e11bf57d4dc6c39424c7669), ROM_BIOS(2))
|
||||
|
||||
ROM_REGION(0x2000, "maincpu", 0)
|
||||
ROM_LOAD("d78312g-022_15179266.ic25", 0x0000, 0x2000, NO_DUMP)
|
||||
ROM_COPY("progrom", 0x0000, 0x0000, 0x2000)
|
||||
|
||||
ROM_REGION(0x40000, "pcma", 0)
|
||||
ROM_LOAD("tc532000p-7469.ic30", 0x00000, 0x40000, NO_DUMP)
|
||||
|
||||
ROM_REGION(0x40000, "pcmb", 0)
|
||||
ROM_LOAD("tc532000p-7470.ic29", 0x00000, 0x40000, NO_DUMP)
|
||||
ROM_END
|
||||
|
||||
SYST(1987, d50, 0, 0, d50, d50, roland_d50_state, empty_init, "Roland", "D-50 (Ver. 2.xx)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
|
||||
SYST(1987, d50a, d50, 0, d50, d50, roland_d50_state, empty_init, "Roland", "D-50 (Ver. 1.xx)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
|
||||
SYST(1987, d550, d50, 0, d50, d50, roland_d50_state, empty_init, "Roland", "D-550", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
|
@ -34460,6 +34460,11 @@ hangzo
|
||||
@source:roland_cm32p.cpp
|
||||
cm32p //
|
||||
|
||||
@source:roland_d50.cpp
|
||||
d50 //
|
||||
d50a //
|
||||
d550 //
|
||||
|
||||
@source:roland_d110.cpp
|
||||
d110 //
|
||||
|
||||
|
@ -739,6 +739,7 @@ riscpc.cpp
|
||||
rm380z.cpp
|
||||
rmnimbus.cpp
|
||||
roland_cm32p.cpp
|
||||
roland_d50.cpp
|
||||
roland_d110.cpp
|
||||
roland_mt32.cpp
|
||||
roland_sc55.cpp
|
||||
|
@ -163,6 +163,7 @@ using util::BIT;
|
||||
#include "cpu/upd78k/upd78k0d.h"
|
||||
#include "cpu/upd78k/upd78k1d.h"
|
||||
#include "cpu/upd78k/upd78k2d.h"
|
||||
#include "cpu/upd78k/upd78k3d.h"
|
||||
#include "cpu/v60/v60d.h"
|
||||
#include "cpu/v810/v810dasm.h"
|
||||
#include "cpu/vt50/vt50dasm.h"
|
||||
@ -551,6 +552,14 @@ static const dasm_table_entry dasm_table[] =
|
||||
{ "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; } },
|
||||
{ "upd78312", le, 0, []() -> util::disasm_interface * { return new upd78312_disassembler; } },
|
||||
{ "upd78322", le, 0, []() -> util::disasm_interface * { return new upd78322_disassembler; } },
|
||||
{ "upd78328", le, 0, []() -> util::disasm_interface * { return new upd78328_disassembler; } },
|
||||
{ "upd78334", le, 0, []() -> util::disasm_interface * { return new upd78334_disassembler; } },
|
||||
{ "upd78352", le, 0, []() -> util::disasm_interface * { return new upd78352_disassembler; } },
|
||||
{ "upd78356", le, 0, []() -> util::disasm_interface * { return new upd78356_disassembler; } },
|
||||
{ "upd78366a", le, 0, []() -> util::disasm_interface * { return new upd78366a_disassembler; } },
|
||||
{ "upd78372", le, 0, []() -> util::disasm_interface * { return new upd78372_disassembler; } },
|
||||
{ "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; } },
|
||||
|
Loading…
Reference in New Issue
Block a user