Separate V50/V53 common peripherals and former device from V33 base; add V40 type for future use

This commit is contained in:
AJR 2019-10-20 23:17:20 -04:00
parent 9cb25537bd
commit e84674d577
4 changed files with 377 additions and 254 deletions

View File

@ -371,32 +371,48 @@ void nec_common_device::external_int()
/*****************************************************************************/
void nec_common_device::set_int_line(int state)
{
m_irq_state = state;
if (state == CLEAR_LINE)
m_pending_irq &= ~INT_IRQ;
else
{
m_pending_irq |= INT_IRQ;
m_halted = 0;
}
}
void nec_common_device::set_nmi_line(int state)
{
if (m_nmi_state == state)
return;
m_nmi_state = state;
if (state != CLEAR_LINE)
{
m_pending_irq |= NMI_IRQ;
m_halted = 0;
}
}
void nec_common_device::set_poll_line(int state)
{
m_poll_state = state;
}
void nec_common_device::execute_set_input(int irqline, int state)
{
switch (irqline)
{
case 0:
m_irq_state = state;
if (state == CLEAR_LINE)
m_pending_irq &= ~INT_IRQ;
else
{
m_pending_irq |= INT_IRQ;
m_halted = 0;
}
break;
case INPUT_LINE_NMI:
if (m_nmi_state == state) return;
m_nmi_state = state;
if (state != CLEAR_LINE)
{
m_pending_irq |= NMI_IRQ;
m_halted = 0;
}
break;
case NEC_INPUT_LINE_POLL:
m_poll_state = state;
break;
case 0:
set_int_line(state);
break;
case INPUT_LINE_NMI:
set_nmi_line(state);
break;
case NEC_INPUT_LINE_POLL:
set_poll_line(state);
break;
}
}

View File

@ -21,6 +21,8 @@ enum
class nec_common_device : public cpu_device
{
friend class device_v5x_interface;
protected:
// construction/destruction
nec_common_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, bool is_16bit, uint8_t prefetch_size, uint8_t prefetch_cycles, uint32_t chip_type, address_map_constructor internal_port_map = address_map_constructor());
@ -49,6 +51,10 @@ protected:
// device_disasm_interface overrides
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
void set_int_line(int state);
void set_nmi_line(int state);
void set_poll_line(int state);
private:
address_space_config m_program_config;
address_space_config m_io_config;

View File

@ -6,11 +6,12 @@
* CPU cores within each device are as follows:
*
* Device CPU
* V40 (µPD70208) V20 (µPD70108)
* V50 (µPD70216) V30 (µPD70116)
* V53 (µPD70236) V33 (µPD70136)
* V53A (µPD70236A) V33A (µPD70136A)
*
* The peripherals are nearly identical between all three devices:
* The peripherals are nearly identical between all four devices:
*
* Name Description Device
* TCU Timer/Counter Unit µPD71054/i8254 subset
@ -34,52 +35,303 @@
#define VERBOSE 0
#include "logmacro.h"
DEFINE_DEVICE_TYPE(V40, v40_device, "v40", "NEC V40")
DEFINE_DEVICE_TYPE(V50, v50_device, "v50", "NEC V50")
DEFINE_DEVICE_TYPE(V53, v53_device, "v53", "NEC V53")
DEFINE_DEVICE_TYPE(V53A, v53a_device, "v53a", "NEC V53A")
WRITE8_MEMBER(v5x_base_device::SULA_w)
WRITE8_MEMBER(device_v5x_interface::SULA_w)
{
LOG("SULA_w %02x\n", data);
if (VERBOSE)
device().logerror("SULA_w %02x\n", data);
m_SULA = data;
install_peripheral_io();
}
WRITE8_MEMBER(v5x_base_device::TULA_w)
WRITE8_MEMBER(device_v5x_interface::TULA_w)
{
LOG("TULA_w %02x\n", data);
if (VERBOSE)
device().logerror("TULA_w %02x\n", data);
m_TULA = data;
install_peripheral_io();
}
WRITE8_MEMBER(v5x_base_device::IULA_w)
WRITE8_MEMBER(device_v5x_interface::IULA_w)
{
LOG("IULA_w %02x\n", data);
if (VERBOSE)
device().logerror("IULA_w %02x\n", data);
m_IULA = data;
install_peripheral_io();
}
WRITE8_MEMBER(v5x_base_device::DULA_w)
WRITE8_MEMBER(device_v5x_interface::DULA_w)
{
LOG("DULA_w %02x\n", data);
if (VERBOSE)
device().logerror("DULA_w %02x\n", data);
m_DULA = data;
install_peripheral_io();
}
WRITE8_MEMBER(v5x_base_device::OPHA_w)
WRITE8_MEMBER(device_v5x_interface::OPHA_w)
{
LOG("OPHA_w %02x\n", data);
if (VERBOSE)
device().logerror("OPHA_w %02x\n", data);
m_OPHA = data;
install_peripheral_io();
}
WRITE8_MEMBER(v5x_base_device::OPSEL_w)
WRITE8_MEMBER(device_v5x_interface::OPSEL_w)
{
LOG("OPSEL_w %02x\n", data);
if (VERBOSE)
device().logerror("OPSEL_w %02x\n", data);
m_OPSEL = data;
install_peripheral_io();
}
void device_v5x_interface::interface_pre_reset()
{
m_OPSEL= 0x00;
// peripheral addresses
m_SULA = 0x00;
m_TULA = 0x00;
m_IULA = 0x00;
m_DULA = 0x00;
m_OPHA = 0x00;
}
void device_v5x_interface::interface_post_start()
{
device().save_item(NAME(m_OPSEL));
device().save_item(NAME(m_SULA));
device().save_item(NAME(m_TULA));
device().save_item(NAME(m_IULA));
device().save_item(NAME(m_DULA));
device().save_item(NAME(m_OPHA));
}
void device_v5x_interface::interface_post_load()
{
install_peripheral_io();
}
// the external interface provides no external access to the usual IRQ line of the V33, everything goes through the interrupt controller
void device_v5x_interface::v5x_set_input(int irqline, int state)
{
switch (irqline)
{
case INPUT_LINE_IRQ0: m_icu->ir0_w(state); break;
case INPUT_LINE_IRQ1: m_icu->ir1_w(state); break;
case INPUT_LINE_IRQ2: m_icu->ir2_w(state); break;
case INPUT_LINE_IRQ3: m_icu->ir3_w(state); break;
case INPUT_LINE_IRQ4: m_icu->ir4_w(state); break;
case INPUT_LINE_IRQ5: m_icu->ir5_w(state); break;
case INPUT_LINE_IRQ6: m_icu->ir6_w(state); break;
case INPUT_LINE_IRQ7: m_icu->ir7_w(state); break;
case INPUT_LINE_NMI: downcast<nec_common_device &>(device()).set_nmi_line(state); break;
case NEC_INPUT_LINE_POLL: downcast<nec_common_device &>(device()).set_poll_line(state); break;
}
}
// for hooking the interrupt controller output up to the core
WRITE_LINE_MEMBER(device_v5x_interface::internal_irq_w)
{
downcast<nec_common_device &>(device()).set_int_line(state);
}
void device_v5x_interface::v5x_add_mconfig(machine_config &config)
{
PIT8254(config, m_tcu, 0);
m_tcu->set_clk<0>(device().clock());
m_tcu->set_clk<1>(device().clock());
m_tcu->set_clk<2>(device().clock());
V5X_DMAU(config, m_dmau, 4000000);
V5X_ICU(config, m_icu, 0);
m_icu->out_int_callback().set(FUNC(device_v5x_interface::internal_irq_w));
m_icu->in_sp_callback().set_constant(1);
m_icu->read_slave_ack_callback().set(FUNC(device_v5x_interface::get_pic_ack));
V5X_SCU(config, m_scu, 0);
}
device_v5x_interface::device_v5x_interface(const machine_config &mconfig, nec_common_device &device)
: device_interface(device, "v5x")
, m_tcu(device, "tcu")
, m_dmau(device, "dmau")
, m_icu(device, "icu")
, m_scu(device, "scu")
{
}
WRITE8_MEMBER(v50_base_device::OPCN_w)
{
// bit 7: unused
// bit 6: unused
// bit 5: unused
// bit 4: unused
// bit 3: IRSW
// bit 2: IRSW
// bit 1: PF
// bit 0: PF
LOG("OPCN_w %02x\n", data);
m_OPCN = data;
install_peripheral_io();
}
void v50_base_device::device_reset()
{
nec_common_device::device_reset();
m_OPCN = 0;
}
void v50_base_device::device_start()
{
nec_common_device::device_start();
set_irq_acknowledge_callback(device_irq_acknowledge_delegate(FUNC(v5x_icu_device::inta_cb), m_icu.target()));
save_item(NAME(m_OPCN));
}
void v40_device::install_peripheral_io()
{
// unmap everything in I/O space up to the fixed position registers (we avoid overwriting them, it isn't a valid config)
space(AS_IO).unmap_readwrite(0x1000, 0xfeff);
if (m_OPSEL & OPSEL_DS)
{
u16 const base = ((m_OPHA << 8) | m_DULA) & 0xfff0;
space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x0f,
read8sm_delegate(FUNC(v5x_dmau_device::read), m_dmau.target()),
write8sm_delegate(FUNC(v5x_dmau_device::write), m_dmau.target()));
}
if (m_OPSEL & OPSEL_IS)
{
u16 const base = ((m_OPHA << 8) | m_IULA) & 0xfff0;
space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x01,
read8sm_delegate(FUNC(v5x_icu_device::read), m_icu.target()),
write8sm_delegate(FUNC(v5x_icu_device::write), m_icu.target()));
}
if (m_OPSEL & OPSEL_TS)
{
u16 const base = ((m_OPHA << 8) | m_TULA) & 0xfff0;
space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x03,
read8sm_delegate(FUNC(pit8253_device::read), m_tcu.target()),
write8sm_delegate(FUNC(pit8253_device::write), m_tcu.target()));
}
if (m_OPSEL & OPSEL_SS)
{
u16 const base = ((m_OPHA << 8) | m_SULA) & 0xfff0;
space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x03,
read8sm_delegate(FUNC(v5x_scu_device::read), m_scu.target()),
write8sm_delegate(FUNC(v5x_scu_device::write), m_scu.target()));
}
}
void v50_device::install_peripheral_io()
{
// unmap everything in I/O space up to the fixed position registers (we avoid overwriting them, it isn't a valid config)
space(AS_IO).unmap_readwrite(0x1000, 0xfeff);
if (m_OPSEL & OPSEL_DS)
{
u16 const base = ((m_OPHA << 8) | m_DULA) & 0xfffe;
space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x0f,
read8sm_delegate(FUNC(v5x_dmau_device::read), m_dmau.target()),
write8sm_delegate(FUNC(v5x_dmau_device::write), m_dmau.target()), 0xffff);
}
if (m_OPSEL & OPSEL_IS)
{
u16 const base = ((m_OPHA << 8) | m_IULA) & 0xfffe;
space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x03,
read8sm_delegate(FUNC(v5x_icu_device::read), m_icu.target()),
write8sm_delegate(FUNC(v5x_icu_device::write), m_icu.target()), 0x00ff);
}
if (m_OPSEL & OPSEL_TS)
{
u16 const base = ((m_OPHA << 8) | m_TULA) & 0xfffe;
space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x07,
read8sm_delegate(FUNC(pit8253_device::read), m_tcu.target()),
write8sm_delegate(FUNC(pit8253_device::write), m_tcu.target()), 0x00ff);
}
if (m_OPSEL & OPSEL_SS)
{
u16 const base = ((m_OPHA << 8) | m_SULA) & 0xfffe;
space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x07,
read8sm_delegate(FUNC(v5x_scu_device::read), m_scu.target()),
write8sm_delegate(FUNC(v5x_scu_device::write), m_scu.target()), 0x00ff);
}
}
void v50_base_device::internal_port_map(address_map &map)
{
map(0xfff0, 0xfff0).w(FUNC(v50_base_device::TCKS_w));
map(0xfff2, 0xfff2).w(FUNC(v50_base_device::RFC_w));
map(0xfff4, 0xfff4).w(FUNC(v50_base_device::WMB0_w)); // actually WMB on V50
map(0xfff5, 0xfff5).w(FUNC(v50_base_device::WCY1_w));
map(0xfff6, 0xfff6).w(FUNC(v50_base_device::WCY2_w));
map(0xfff8, 0xfff8).w(FUNC(v50_base_device::SULA_w));
map(0xfff9, 0xfff9).w(FUNC(v50_base_device::TULA_w));
map(0xfffa, 0xfffa).w(FUNC(v50_base_device::IULA_w));
map(0xfffb, 0xfffb).w(FUNC(v50_base_device::DULA_w));
map(0xfffc, 0xfffc).w(FUNC(v50_base_device::OPHA_w));
map(0xfffd, 0xfffd).w(FUNC(v50_base_device::OPSEL_w));
map(0xfffe, 0xfffe).w(FUNC(v50_base_device::OPCN_w));
}
void v50_base_device::execute_set_input(int irqline, int state)
{
v5x_set_input(irqline, state);
}
void v50_base_device::device_add_mconfig(machine_config &config)
{
v5x_add_mconfig(config);
// V50 timer 0 is internally connected to INT0
m_tcu->out_handler<0>().set(m_icu, FUNC(pic8259_device::ir0_w));
}
v50_base_device::v50_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, bool is_16bit, uint8_t prefetch_size, uint8_t prefetch_cycles, uint32_t chip_type)
: nec_common_device(mconfig, type, tag, owner, clock, is_16bit, prefetch_size, prefetch_cycles, chip_type, address_map_constructor(FUNC(v50_base_device::internal_port_map), this))
, device_v5x_interface(mconfig, *this)
{
}
v40_device::v40_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: v50_base_device(mconfig, V40, tag, owner, clock, false, 4, 4, V20_TYPE)
{
}
v50_device::v50_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: v50_base_device(mconfig, V50, tag, owner, clock, true, 6, 2, V30_TYPE)
{
}
WRITE8_MEMBER(v53_device::SCTL_w)
{
// bit 7: unused
@ -96,83 +348,22 @@ WRITE8_MEMBER(v53_device::SCTL_w)
install_peripheral_io();
}
WRITE8_MEMBER(v50_device::OPCN_w)
{
// bit 7: unused
// bit 6: unused
// bit 5: unused
// bit 4: unused
// bit 3: IRSW
// bit 2: IRSW
// bit 1: PF
// bit 0: PF
LOG("OPCN_w %02x\n", data);
m_OPCN = data;
install_peripheral_io();
}
void v5x_base_device::device_reset()
{
v33_base_device::device_reset();
m_OPSEL= 0x00;
// peripheral addresses
m_SULA = 0x00;
m_TULA = 0x00;
m_IULA = 0x00;
m_DULA = 0x00;
m_OPHA = 0x00;
}
void v50_device::device_reset()
{
v5x_base_device::device_reset();
m_OPCN = 0;
}
void v53_device::device_reset()
{
v5x_base_device::device_reset();
v33_base_device::device_reset();
m_SCTL = 0x00;
}
void v5x_base_device::device_start()
void v53_device::device_start()
{
v33_base_device::device_start();
set_irq_acknowledge_callback(device_irq_acknowledge_delegate(FUNC(v5x_icu_device::inta_cb), m_icu.target()));
save_item(NAME(m_OPSEL));
save_item(NAME(m_SULA));
save_item(NAME(m_TULA));
save_item(NAME(m_IULA));
save_item(NAME(m_DULA));
save_item(NAME(m_OPHA));
}
void v50_device::device_start()
{
v5x_base_device::device_start();
save_item(NAME(m_OPCN));
}
void v53_device::device_start()
{
v5x_base_device::device_start();
save_item(NAME(m_SCTL));
}
void v5x_base_device::device_post_load()
{
install_peripheral_io();
}
void v53_device::install_peripheral_io()
{
// unmap everything in I/O space up to the fixed position registers (we avoid overwriting them, it isn't a valid config)
@ -254,67 +445,6 @@ WRITE_LINE_MEMBER(v53_device::hack_w)
LOG("hack_w not in 71071mode\n");
}
void v50_device::install_peripheral_io()
{
// unmap everything in I/O space up to the fixed position registers (we avoid overwriting them, it isn't a valid config)
space(AS_IO).unmap_readwrite(0x1000, 0xfeff);
if (m_OPSEL & OPSEL_DS)
{
u16 const base = ((m_OPHA << 8) | m_DULA) & 0xfffe;
space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x0f,
read8sm_delegate(FUNC(v5x_dmau_device::read), m_dmau.target()),
write8sm_delegate(FUNC(v5x_dmau_device::write), m_dmau.target()), 0xffff);
}
if (m_OPSEL & OPSEL_IS)
{
u16 const base = ((m_OPHA << 8) | m_IULA) & 0xfffe;
space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x03,
read8sm_delegate(FUNC(v5x_icu_device::read), m_icu.target()),
write8sm_delegate(FUNC(v5x_icu_device::write), m_icu.target()), 0x00ff);
}
if (m_OPSEL & OPSEL_TS)
{
u16 const base = ((m_OPHA << 8) | m_TULA) & 0xfffe;
space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x07,
read8sm_delegate(FUNC(pit8253_device::read), m_tcu.target()),
write8sm_delegate(FUNC(pit8253_device::write), m_tcu.target()), 0x00ff);
}
if (m_OPSEL & OPSEL_SS)
{
u16 const base = ((m_OPHA << 8) | m_SULA) & 0xfffe;
space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x07,
read8sm_delegate(FUNC(v5x_scu_device::read), m_scu.target()),
write8sm_delegate(FUNC(v5x_scu_device::write), m_scu.target()), 0x00ff);
}
}
void v50_device::internal_port_map(address_map &map)
{
map(0xfff0, 0xfff0).w(FUNC(v50_device::TCKS_w));
map(0xfff2, 0xfff2).w(FUNC(v50_device::RFC_w));
map(0xfff4, 0xfff4).w(FUNC(v50_device::WMB0_w)); // actually WMB on V50
map(0xfff5, 0xfff5).w(FUNC(v50_device::WCY1_w));
map(0xfff6, 0xfff6).w(FUNC(v50_device::WCY2_w));
map(0xfff8, 0xfff8).w(FUNC(v50_device::SULA_w));
map(0xfff9, 0xfff9).w(FUNC(v50_device::TULA_w));
map(0xfffa, 0xfffa).w(FUNC(v50_device::IULA_w));
map(0xfffb, 0xfffb).w(FUNC(v50_device::DULA_w));
map(0xfffc, 0xfffc).w(FUNC(v50_device::OPHA_w));
map(0xfffd, 0xfffd).w(FUNC(v50_device::OPSEL_w));
map(0xfffe, 0xfffe).w(FUNC(v50_device::OPCN_w));
}
void v53_device::internal_port_map(address_map &map)
{
v33_internal_port_map(map);
@ -346,72 +476,19 @@ void v53_device::internal_port_map(address_map &map)
// 0xffff reserved
}
// the external interface provides no external access to the usual IRQ line of the V33, everything goes through the interrupt controller
void v5x_base_device::execute_set_input(int irqline, int state)
void v53_device::execute_set_input(int irqline, int state)
{
switch (irqline)
{
case INPUT_LINE_IRQ0: m_icu->ir0_w(state); break;
case INPUT_LINE_IRQ1: m_icu->ir1_w(state); break;
case INPUT_LINE_IRQ2: m_icu->ir2_w(state); break;
case INPUT_LINE_IRQ3: m_icu->ir3_w(state); break;
case INPUT_LINE_IRQ4: m_icu->ir4_w(state); break;
case INPUT_LINE_IRQ5: m_icu->ir5_w(state); break;
case INPUT_LINE_IRQ6: m_icu->ir6_w(state); break;
case INPUT_LINE_IRQ7: m_icu->ir7_w(state); break;
case INPUT_LINE_NMI: nec_common_device::execute_set_input(irqline, state); break;
case NEC_INPUT_LINE_POLL: nec_common_device::execute_set_input(irqline, state); break;
}
v5x_set_input(irqline, state);
}
// for hooking the interrupt controller output up to the core
WRITE_LINE_MEMBER(v5x_base_device::internal_irq_w)
{
nec_common_device::execute_set_input(0, state);
}
void v5x_base_device::device_add_mconfig(machine_config &config)
{
PIT8254(config, m_tcu, 0);
m_tcu->set_clk<0>(clock());
m_tcu->set_clk<1>(clock());
m_tcu->set_clk<2>(clock());
V5X_DMAU(config, m_dmau, 4000000);
V5X_ICU(config, m_icu, 0);
m_icu->out_int_callback().set(FUNC(v5x_base_device::internal_irq_w));
m_icu->in_sp_callback().set_constant(1);
m_icu->read_slave_ack_callback().set(FUNC(v5x_base_device::get_pic_ack));
V5X_SCU(config, m_scu, 0);
}
void v50_device::device_add_mconfig(machine_config &config)
{
v5x_base_device::device_add_mconfig(config);
// V50 timer 0 is internally connected to INT0
m_tcu->out_handler<0>().set(m_icu, FUNC(pic8259_device::ir0_w));
}
v5x_base_device::v5x_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, address_map_constructor port_map)
: v33_base_device(mconfig, type, tag, owner, clock, port_map)
, m_tcu(*this, "tcu")
, m_dmau(*this, "dmau")
, m_icu(*this, "icu")
, m_scu(*this, "scu")
{
}
v50_device::v50_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: v5x_base_device(mconfig, V50, tag, owner, clock, address_map_constructor(FUNC(v50_device::internal_port_map), this))
void v53_device::device_add_mconfig(machine_config &config)
{
v5x_add_mconfig(config);
}
v53_device::v53_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
: v5x_base_device(mconfig, type, tag, owner, clock, address_map_constructor(FUNC(v53_device::internal_port_map), this))
: v33_base_device(mconfig, type, tag, owner, clock, address_map_constructor(FUNC(v53_device::internal_port_map), this))
, device_v5x_interface(mconfig, *this)
{
}

View File

@ -13,47 +13,46 @@
#include "machine/pic8259.h"
#include "machine/pit8253.h"
class v5x_base_device : public v33_base_device
class device_v5x_interface : public device_interface
{
public:
// TCU
template <unsigned Timer> void set_clk(double clk) { subdevice<pit8253_device>("tcu")->set_clk<Timer>(clk); }
template <unsigned Timer> void set_clk(const XTAL &xtal) { subdevice<pit8253_device>("tcu")->set_clk<Timer>(xtal.dvalue()); }
template <unsigned Timer> auto out_handler() { return subdevice<pit8253_device>("tcu")->out_handler<Timer>(); }
template <unsigned Timer> void set_clk(double clk) { device().subdevice<pit8253_device>("tcu")->set_clk<Timer>(clk); }
template <unsigned Timer> void set_clk(const XTAL &xtal) { device().subdevice<pit8253_device>("tcu")->set_clk<Timer>(xtal.dvalue()); }
template <unsigned Timer> auto out_handler() { return device().subdevice<pit8253_device>("tcu")->out_handler<Timer>(); }
// DMAU
auto out_hreq_cb() { return subdevice<v5x_dmau_device>("dmau")->out_hreq_callback(); }
auto out_eop_cb() { return subdevice<v5x_dmau_device>("dmau")->out_eop_callback(); }
auto in_memr_cb() { return subdevice<v5x_dmau_device>("dmau")->in_memr_callback(); }
auto in_mem16r_cb() { return subdevice<v5x_dmau_device>("dmau")->in_mem16r_callback(); }
auto out_memw_cb() { return subdevice<v5x_dmau_device>("dmau")->out_memw_callback(); }
auto out_mem16w_cb() { return subdevice<v5x_dmau_device>("dmau")->out_mem16w_callback(); }
template <unsigned Channel> auto in_ior_cb() { return subdevice<v5x_dmau_device>("dmau")->in_ior_callback<Channel>(); }
template <unsigned Channel> auto in_io16r_cb() { return subdevice<v5x_dmau_device>("dmau")->in_io16r_callback<Channel>(); }
template <unsigned Channel> auto out_iow_cb() { return subdevice<v5x_dmau_device>("dmau")->out_iow_callback<Channel>(); }
template <unsigned Channel> auto out_io16w_cb() { return subdevice<v5x_dmau_device>("dmau")->out_io16w_callback<Channel>(); }
template <unsigned Channel> auto out_dack_cb() { return subdevice<v5x_dmau_device>("dmau")->out_dack_callback<Channel>(); }
auto out_hreq_cb() { return device().subdevice<v5x_dmau_device>("dmau")->out_hreq_callback(); }
auto out_eop_cb() { return device().subdevice<v5x_dmau_device>("dmau")->out_eop_callback(); }
auto in_memr_cb() { return device().subdevice<v5x_dmau_device>("dmau")->in_memr_callback(); }
auto in_mem16r_cb() { return device().subdevice<v5x_dmau_device>("dmau")->in_mem16r_callback(); }
auto out_memw_cb() { return device().subdevice<v5x_dmau_device>("dmau")->out_memw_callback(); }
auto out_mem16w_cb() { return device().subdevice<v5x_dmau_device>("dmau")->out_mem16w_callback(); }
template <unsigned Channel> auto in_ior_cb() { return device().subdevice<v5x_dmau_device>("dmau")->in_ior_callback<Channel>(); }
template <unsigned Channel> auto in_io16r_cb() { return device().subdevice<v5x_dmau_device>("dmau")->in_io16r_callback<Channel>(); }
template <unsigned Channel> auto out_iow_cb() { return device().subdevice<v5x_dmau_device>("dmau")->out_iow_callback<Channel>(); }
template <unsigned Channel> auto out_io16w_cb() { return device().subdevice<v5x_dmau_device>("dmau")->out_io16w_callback<Channel>(); }
template <unsigned Channel> auto out_dack_cb() { return device().subdevice<v5x_dmau_device>("dmau")->out_dack_callback<Channel>(); }
// SCU
auto txd_handler_cb() { return subdevice<v5x_scu_device>("scu")->txd_handler(); }
auto dtr_handler_cb() { return subdevice<v5x_scu_device>("scu")->dtr_handler(); }
auto rts_handler_cb() { return subdevice<v5x_scu_device>("scu")->rts_handler(); }
auto rxrdy_handler_cb() { return subdevice<v5x_scu_device>("scu")->rxrdy_handler(); }
auto txrdy_handler_cb() { return subdevice<v5x_scu_device>("scu")->txrdy_handler(); }
auto txempty_handler_cb() { return subdevice<v5x_scu_device>("scu")->txempty_handler(); }
auto syndet_handler_cb() { return subdevice<v5x_scu_device>("scu")->syndet_handler(); }
auto txd_handler_cb() { return device().subdevice<v5x_scu_device>("scu")->txd_handler(); }
auto dtr_handler_cb() { return device().subdevice<v5x_scu_device>("scu")->dtr_handler(); }
auto rts_handler_cb() { return device().subdevice<v5x_scu_device>("scu")->rts_handler(); }
auto rxrdy_handler_cb() { return device().subdevice<v5x_scu_device>("scu")->rxrdy_handler(); }
auto txrdy_handler_cb() { return device().subdevice<v5x_scu_device>("scu")->txrdy_handler(); }
auto txempty_handler_cb() { return device().subdevice<v5x_scu_device>("scu")->txempty_handler(); }
auto syndet_handler_cb() { return device().subdevice<v5x_scu_device>("scu")->syndet_handler(); }
protected:
v5x_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, address_map_constructor port_map);
device_v5x_interface(const machine_config &mconfig, nec_common_device &device);
// device_interface overrides
virtual void device_add_mconfig(machine_config &config) override;
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_post_load() override;
virtual void interface_post_start() override;
virtual void interface_pre_reset() override;
virtual void interface_post_load() override;
// device_execute_interface overrides
virtual void execute_set_input(int inputnum, int state) override;
void v5x_set_input(int inputnum, int state);
void v5x_add_mconfig(machine_config &config);
virtual void install_peripheral_io() = 0;
@ -101,22 +100,24 @@ protected:
u8 m_OPHA;
};
class v50_device : public v5x_base_device
class v50_base_device : public nec_common_device, public device_v5x_interface
{
public:
v50_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
template <unsigned Channel> DECLARE_WRITE_LINE_MEMBER(dreq_w) { m_dmau->dreq_w<Channel>(state); }
DECLARE_WRITE_LINE_MEMBER(hack_w) { m_dmau->hack_w(state); }
protected:
// device_interface overrides
v50_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, bool is_16bit, uint8_t prefetch_size, uint8_t prefetch_cycles, uint32_t chip_type);
// device-specific overrides
virtual void device_add_mconfig(machine_config &config) override;
virtual void device_start() override;
virtual void device_reset() override;
// device_execute_interface overrides
virtual void execute_set_input(int inputnum, int state) override;
void internal_port_map(address_map &map);
virtual void install_peripheral_io() override;
DECLARE_WRITE8_MEMBER(OPCN_w);
@ -124,7 +125,25 @@ private:
u8 m_OPCN;
};
class v53_device : public v5x_base_device
class v40_device : public v50_base_device
{
public:
v40_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
protected:
virtual void install_peripheral_io() override;
};
class v50_device : public v50_base_device
{
public:
v50_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
protected:
virtual void install_peripheral_io() override;
};
class v53_device : public v33_base_device, public device_v5x_interface
{
public:
v53_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
@ -146,10 +165,14 @@ public:
protected:
v53_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
// device_interface overrides
// device-specific overrides
virtual void device_add_mconfig(machine_config &config) override;
virtual void device_start() override;
virtual void device_reset() override;
// device_execute_interface overrides
virtual void execute_set_input(int inputnum, int state) override;
void internal_port_map(address_map &map);
virtual void install_peripheral_io() override;
@ -165,6 +188,7 @@ public:
v53a_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};
DECLARE_DEVICE_TYPE(V40, v40_device)
DECLARE_DEVICE_TYPE(V50, v50_device)
DECLARE_DEVICE_TYPE(V53, v53_device)
DECLARE_DEVICE_TYPE(V53A, v53a_device)