diff options
author | 2018-10-31 20:47:18 +0700 | |
---|---|---|
committer | 2018-11-01 11:47:28 +0700 | |
commit | 0bb396ae6f5ca1e5b7fba19ffb0aa590871ebe60 (patch) | |
tree | 12a7a60f53bd75b8d6ef9ef64c80f71599e4601f /src/devices/cpu/nec | |
parent | faba94708cc4826442c386e87712527bb0dd663a (diff) |
v53: overhaul
An attempt to add the NEC V50 to the existing V53/V53A devices. Also overhauled for devcb3, and made some required changes to the peripherals. Because this is a pretty wide-ranging change, I thought I'd solicit feedback before merging it.
* v53: refactor and add v50, devcb3, use templates and other general cleanup
* am9517a: add 16 bit transfer support to v5x_dmau variant
* i8251: minor tidy on v5x_scu variant
* hng64: update to match v53 changes
* mpc3000: update to match v53 changes
Diffstat (limited to 'src/devices/cpu/nec')
-rw-r--r-- | src/devices/cpu/nec/v53.cpp | 629 | ||||
-rw-r--r-- | src/devices/cpu/nec/v53.h | 344 |
2 files changed, 362 insertions, 611 deletions
diff --git a/src/devices/cpu/nec/v53.cpp b/src/devices/cpu/nec/v53.cpp index 5b31c6bcb7e..1d20dd544e7 100644 --- a/src/devices/cpu/nec/v53.cpp +++ b/src/devices/cpu/nec/v53.cpp @@ -1,137 +1,86 @@ // license:BSD-3-Clause // copyright-holders:Bryan McPhail -/* V53 */ - -// V33 / V33A cores with onboard peripherals - -// Interrupt Controller is uPD71059 equivalent (a PIC8259 clone?) -// DMA Controller can operate in modes providing a subset of the uPD71071 or uPD71037 functionality (some modes unavailable / settings ignored) (uPD71071 mode is an extended 8237A, uPD71037 mode is plain 8237A) -// Serial Controller is based on the uPD71051 but with some changes (i8251 clone?) -// Timer Unit is functionally identical to uPD71054 (which in turn is said to be the same as a pit8253) +/* + * NEC V5x devices consist of a V3x CPU core plus integrated peripherals. The + * CPU cores within each device are as follows: + * + * Device CPU + * V50/µPD70216 V30/µPD70116 + * V53/µPD70236 V33/µPD70136 + * V53A/µPD70236A V33A//µPD70136A + * + * The peripherals are nearly identical between all three devices: + * + * Name Description Device + * TCU Timer/Counter Unit µPD71054/i8254 subset + * DMAU DMA Control Unit µPD71071 equivalent + * ICU Interrupt control Unit µPD71059/i8259 equivalent + * SCU Serial Control Unit µPD71051/i8251 subset (async only) + * + * The V53/V53A DMAU also supports a configurable µPD71037/i8237A mode. + * + * Sources: + * + * http://www.chipfind.net/datasheet/pdf/nec/upd70236.pdf + * https://datasheet.datasheetarchive.com/originals/scans/Scans-107/DSASCANS15-59637.pdf + * + */ #include "emu.h" #include "v53.h" #include "necpriv.h" +#define VERBOSE 0 +#include "logmacro.h" - +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(v53_base_device::BSEL_w) -{ - //printf("v53: BSEL_w %02x\n", data); -} - -WRITE8_MEMBER(v53_base_device::BADR_w) -{ - //printf("v53: BADR_w %02x\n", data); -} - -WRITE8_MEMBER(v53_base_device::BRC_w) -{ - //printf("v53: BRC_w %02x\n", data); -} - -WRITE8_MEMBER(v53_base_device::WMB0_w) -{ - //printf("v53: WMB0_w %02x\n", data); -} - -WRITE8_MEMBER(v53_base_device::WCY1_w) -{ - //printf("v53: WCY1_w %02x\n", data); -} - -WRITE8_MEMBER(v53_base_device::WCY0_w) -{ - //printf("v53: WCY0_w %02x\n", data); -} - -WRITE8_MEMBER(v53_base_device::WAC_w) -{ - //printf("v53: WAC_w %02x\n", data); -} - -WRITE8_MEMBER(v53_base_device::TCKS_w) -{ - //printf("v53: TCKS_w %02x\n", data); -} - -WRITE8_MEMBER(v53_base_device::SBCR_w) -{ - //printf("v53: SBCR_w %02x\n", data); -} - -WRITE8_MEMBER(v53_base_device::REFC_w) -{ - //printf("v53: REFC_w %02x\n", data); -} - -WRITE8_MEMBER(v53_base_device::WMB1_w) -{ - //printf("v53: WMB1_w %02x\n", data); -} - -WRITE8_MEMBER(v53_base_device::WCY2_w) -{ - //printf("v53: WCY2_w %02x\n", data); -} - -WRITE8_MEMBER(v53_base_device::WCY3_w) +WRITE8_MEMBER(v5x_base_device::SULA_w) { - //printf("v53: WCY3_w %02x\n", data); -} - -WRITE8_MEMBER(v53_base_device::WCY4_w) -{ - //printf("v53: WCY4_w %02x\n", data); -} - -WRITE8_MEMBER(v53_base_device::SULA_w) -{ - //printf("v53: SULA_w %02x\n", data); + LOG("SULA_w %02x\n", data); m_SULA = data; install_peripheral_io(); } -WRITE8_MEMBER(v53_base_device::TULA_w) +WRITE8_MEMBER(v5x_base_device::TULA_w) { - //printf("v53: TULA_w %02x\n", data); + LOG("TULA_w %02x\n", data); m_TULA = data; install_peripheral_io(); } -WRITE8_MEMBER(v53_base_device::IULA_w) +WRITE8_MEMBER(v5x_base_device::IULA_w) { - //printf("v53: IULA_w %02x\n", data); + LOG("IULA_w %02x\n", data); m_IULA = data; install_peripheral_io(); } -WRITE8_MEMBER(v53_base_device::DULA_w) +WRITE8_MEMBER(v5x_base_device::DULA_w) { - //printf("v53: DULA_w %02x\n", data); + LOG("DULA_w %02x\n", data); m_DULA = data; install_peripheral_io(); } -WRITE8_MEMBER(v53_base_device::OPHA_w) +WRITE8_MEMBER(v5x_base_device::OPHA_w) { - //printf("v53: OPHA_w %02x\n", data); + LOG("OPHA_w %02x\n", data); m_OPHA = data; install_peripheral_io(); } -WRITE8_MEMBER(v53_base_device::OPSEL_w) +WRITE8_MEMBER(v5x_base_device::OPSEL_w) { - //printf("v53: OPSEL_w %02x\n", data); + LOG("OPSEL_w %02x\n", data); m_OPSEL = data; install_peripheral_io(); } -WRITE8_MEMBER(v53_base_device::SCTL_w) +WRITE8_MEMBER(v53_device::SCTL_w) { // bit 7: unused // bit 6: unused @@ -142,10 +91,27 @@ WRITE8_MEMBER(v53_base_device::SCTL_w) // bit 1: uPD71037 DMA mode enable (otherwise in uPD71071 mode) // bit 0: Onboard pripheral I/O maps to 8-bit boundaries? (otherwise 16-bit) - //printf("v53: SCTL_w %02x\n", data); + LOG("SCTL_w %02x\n", data); m_SCTL = data; 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(); +} + /* m_WCY0 = 0x07; m_WCY1 = 0x77; @@ -172,11 +138,10 @@ m_DST = 0x00; m_DMK = 0x0f; */ -void v53_base_device::device_reset() +void v5x_base_device::device_reset() { v33_base_device::device_reset(); - m_SCTL = 0x00; m_OPSEL= 0x00; // peripheral addresses @@ -185,61 +150,56 @@ void v53_base_device::device_reset() m_IULA = 0x00; m_DULA = 0x00; m_OPHA = 0x00; +} + +void v50_device::device_reset() +{ + v5x_base_device::device_reset(); + + m_OPCN = 0; +} - m_simk = 0x03; +void v53_device::device_reset() +{ + v5x_base_device::device_reset(); + + m_SCTL = 0x00; } -void v53_base_device::device_start() +void v5x_base_device::device_start() { v33_base_device::device_start(); - m_txd_handler.resolve_safe(); - m_rts_handler.resolve_safe(); - m_dtr_handler.resolve_safe(); - m_rxrdy_handler.resolve_safe(); - m_txrdy_handler.resolve_safe(); - m_txempty_handler.resolve_safe(); - - m_out0_handler.resolve_safe(); - m_out1_handler.resolve_safe(); - m_out2_handler.resolve_safe(); - - m_out_hreq_cb.resolve_safe(); - m_out_eop_cb.resolve_safe(); - m_in_memr_cb.resolve_safe(0); - m_out_memw_cb.resolve_safe(); - m_in_ior_0_cb.resolve_safe(0); - m_in_ior_1_cb.resolve_safe(0); - m_in_ior_2_cb.resolve_safe(0); - m_in_ior_3_cb.resolve_safe(0); - m_out_iow_0_cb.resolve_safe(); - m_out_iow_1_cb.resolve_safe(); - m_out_iow_2_cb.resolve_safe(); - m_out_iow_3_cb.resolve_safe(); - m_out_dack_0_cb.resolve_safe(); - m_out_dack_1_cb.resolve_safe(); - m_out_dack_2_cb.resolve_safe(); - m_out_dack_3_cb.resolve_safe(); - - set_irq_acknowledge_callback(device_irq_acknowledge_delegate(FUNC(pic8259_device::inta_cb), (pic8259_device*)m_v53icu)); + set_irq_acknowledge_callback(device_irq_acknowledge_delegate(FUNC(v5x_icu_device::inta_cb), m_icu.target())); - save_item(NAME(m_SCTL)); 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_simk)); + save_item(NAME(m_SCTL)); } -void v53_base_device::device_post_load() +void v5x_base_device::device_post_load() { install_peripheral_io(); } -void v53_base_device::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) space(AS_IO).unmap_readwrite(0x1000, 0xfeff); // todo, we need to have a way to NOT unmap things defined in the drivers, but instead have this act as an overlay mapping / unampping only!! @@ -248,12 +208,11 @@ void v53_base_device::install_peripheral_io() // the hng64.c games first set everything up in 8-bit mode, then // do the procedure again in 16-bit mode before using them?! - int IOAG = m_SCTL & 1; + int const IOAG = m_SCTL & 1; - if (m_OPSEL & 0x01) // DMA Unit available + if (m_OPSEL & OPSEL_DS) { - uint16_t base = (m_OPHA << 8) | m_DULA; - base &= 0xfffe; + u16 const base = ((m_OPHA << 8) | m_DULA) & 0xfffe; if (m_SCTL & 0x02) // uPD71037 mode { @@ -265,232 +224,169 @@ void v53_base_device::install_peripheral_io() } } else // uPD71071 mode - { - space(AS_IO).install_readwrite_handler(base+0x00, base+0x0f, read8_delegate(FUNC(upd71071_v53_device::read), (upd71071_v53_device*)m_v53dmau), write8_delegate(FUNC(upd71071_v53_device::write), (upd71071_v53_device*)m_v53dmau), 0xffff); - } + space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x0f, + read8_delegate(FUNC(v5x_dmau_device::read), m_dmau.target()), + write8_delegate(FUNC(v5x_dmau_device::write), m_dmau.target()), 0xffff); } - if (m_OPSEL & 0x02) // Interrupt Control Unit available + if (m_OPSEL & OPSEL_IS) { - uint16_t base = (m_OPHA << 8) | m_IULA; - base &= 0xfffe; + u16 const base = ((m_OPHA << 8) | m_IULA) & 0xfffe; if (IOAG) // 8-bit - { - space(AS_IO).install_readwrite_handler(base+0x00, base+0x01, read8sm_delegate(FUNC(pic8259_device::read), (pic8259_device*)m_v53icu), write8sm_delegate(FUNC(pic8259_device::write), (pic8259_device*)m_v53icu), 0xffff); - } + 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()), 0xffff); else - { - space(AS_IO).install_readwrite_handler(base+0x00, base+0x03, read8sm_delegate(FUNC(pic8259_device::read), (pic8259_device*)m_v53icu), write8sm_delegate(FUNC(pic8259_device::write), (pic8259_device*)m_v53icu), 0x00ff); - } + 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 & 0x04) // Timer Control Unit available + if (m_OPSEL & OPSEL_TS) { - uint16_t base = (m_OPHA << 8) | m_TULA; - //printf("installing TCU to %04x\n", base); - base &= 0xfffe; + u16 const base = ((m_OPHA << 8) | m_TULA) & 0xfffe; if (IOAG) // 8-bit - { - space(AS_IO).install_readwrite_handler(base+0x00, base+0x01, read8_delegate(FUNC(v53_base_device::tmu_tst0_r), this), write8_delegate(FUNC(v53_base_device::tmu_tct0_w), this), 0x00ff); - space(AS_IO).install_readwrite_handler(base+0x00, base+0x01, read8_delegate(FUNC(v53_base_device::tmu_tst1_r), this), write8_delegate(FUNC(v53_base_device::tmu_tct1_w), this), 0xff00); - space(AS_IO).install_readwrite_handler(base+0x02, base+0x03, read8_delegate(FUNC(v53_base_device::tmu_tst2_r), this), write8_delegate(FUNC(v53_base_device::tmu_tct2_w), this), 0x00ff); - space(AS_IO).install_write_handler(base+0x02, base+0x03, write8_delegate(FUNC(v53_base_device::tmu_tmd_w), this), 0xff00); - } + 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()), 0xffff); else - { - space(AS_IO).install_readwrite_handler(base+0x00, base+0x01, read8_delegate(FUNC(v53_base_device::tmu_tst0_r), this), write8_delegate(FUNC(v53_base_device::tmu_tct0_w), this), 0x00ff); - space(AS_IO).install_readwrite_handler(base+0x02, base+0x03, read8_delegate(FUNC(v53_base_device::tmu_tst1_r), this), write8_delegate(FUNC(v53_base_device::tmu_tct1_w), this), 0x00ff); - space(AS_IO).install_readwrite_handler(base+0x04, base+0x05, read8_delegate(FUNC(v53_base_device::tmu_tst2_r), this), write8_delegate(FUNC(v53_base_device::tmu_tct2_w), this), 0x00ff); - space(AS_IO).install_write_handler(base+0x06, base+0x07, write8_delegate(FUNC(v53_base_device::tmu_tmd_w), this), 0x00ff); - } + 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 & 0x08) // Serial Control Unit available + if (m_OPSEL & OPSEL_SS) { - uint16_t base = (m_OPHA << 8) | m_SULA; - base &= 0xfffe; + u16 const base = ((m_OPHA << 8) | m_SULA) & 0xfffe; if (IOAG) // 8-bit - { - space(AS_IO).install_readwrite_handler(base+0x00, base+0x01, read8smo_delegate(FUNC(v53_scu_device::data_r), m_v53scu.target()), write8smo_delegate(FUNC(v53_scu_device::data_w), m_v53scu.target()), 0x00ff); - space(AS_IO).install_readwrite_handler(base+0x00, base+0x01, read8smo_delegate(FUNC(v53_scu_device::status_r), m_v53scu.target()), write8smo_delegate(FUNC(v53_scu_device::command_w), m_v53scu.target()), 0xff00); - space(AS_IO).install_write_handler(base+0x02, base+0x03, write8smo_delegate(FUNC(v53_scu_device::mode_w), m_v53scu.target()), 0x00ff); - space(AS_IO).install_readwrite_handler(base+0x02, base+0x03, read8_delegate(FUNC(v53_base_device::scu_simk_r), this), write8_delegate(FUNC(v53_base_device::scu_simk_w), this), 0xff00); - } + 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()), 0xffff); else - { - space(AS_IO).install_readwrite_handler(base+0x00, base+0x01, read8smo_delegate(FUNC(v53_scu_device::data_r), m_v53scu.target()), write8smo_delegate(FUNC(v53_scu_device::data_w), m_v53scu.target()), 0x00ff); - space(AS_IO).install_readwrite_handler(base+0x02, base+0x03, read8smo_delegate(FUNC(v53_scu_device::status_r), m_v53scu.target()), write8smo_delegate(FUNC(v53_scu_device::command_w), m_v53scu.target()), 0x00ff); - space(AS_IO).install_write_handler(base+0x04, base+0x05, write8smo_delegate(FUNC(v53_scu_device::mode_w), m_v53scu.target()), 0x00ff); - space(AS_IO).install_readwrite_handler(base+0x06, base+0x07, read8_delegate(FUNC(v53_base_device::scu_simk_r), this), write8_delegate(FUNC(v53_base_device::scu_simk_w), this), 0x00ff); - - } + 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); } - -} - - - -/*** SCU ***/ - - -READ8_MEMBER(v53_base_device::scu_simk_r) -{ - //printf("v53: scu_simk_r\n"); - return m_simk; } -WRITE8_MEMBER(v53_base_device::scu_simk_w) -{ - m_simk = data; - //printf("v53: scu_simk_w %02x\n", data); -} - - - -/*** TCU ***/ - -WRITE8_MEMBER(v53_base_device::tmu_tct0_w) { m_v53tcu->write(0, data); } -WRITE8_MEMBER(v53_base_device::tmu_tct1_w) { m_v53tcu->write(1, data); } -WRITE8_MEMBER(v53_base_device::tmu_tct2_w) { m_v53tcu->write(2, data); } -WRITE8_MEMBER(v53_base_device::tmu_tmd_w) { m_v53tcu->write(3, data); } - - -READ8_MEMBER(v53_base_device::tmu_tst0_r) { return m_v53tcu->read(0); } -READ8_MEMBER(v53_base_device::tmu_tst1_r) { return m_v53tcu->read(1); } -READ8_MEMBER(v53_base_device::tmu_tst2_r) { return m_v53tcu->read(2); } - - - - - -/*** DMA ***/ - -// could be wrong / nonexistent -WRITE_LINE_MEMBER(v53_base_device::dreq0_w) +WRITE_LINE_MEMBER(v53_device::hack_w) { if (!(m_SCTL & 0x02)) - { - m_v53dmau->dreq0_w(state); - } + m_dmau->hack_w(state); else - { - //printf("v53: dreq0 not in 71071mode\n"); - } + LOG("hack_w not in 71071mode\n"); } -WRITE_LINE_MEMBER(v53_base_device::dreq1_w) +void v50_device::install_peripheral_io() { - if (!(m_SCTL & 0x02)) - { - m_v53dmau->dreq1_w(state); - } - else - { - //printf("v53: dreq1 not in 71071mode\n"); - } -} + // 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); // todo, we need to have a way to NOT unmap things defined in the drivers, but instead have this act as an overlay mapping / unampping only!! -WRITE_LINE_MEMBER(v53_base_device::dreq2_w) -{ - if (!(m_SCTL & 0x02)) - { - m_v53dmau->dreq2_w(state); - } - else + if (m_OPSEL & OPSEL_DS) { - //printf("v53: dreq2 not in 71071mode\n"); - } -} + u16 const base = ((m_OPHA << 8) | m_DULA) & 0xfffe; -WRITE_LINE_MEMBER(v53_base_device::dreq3_w) -{ - if (!(m_SCTL & 0x02)) - { - m_v53dmau->dreq3_w(state); + space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x0f, + read8_delegate(FUNC(v5x_dmau_device::read), m_dmau.target()), + write8_delegate(FUNC(v5x_dmau_device::write), m_dmau.target()), 0xffff); } - else + + if (m_OPSEL & OPSEL_IS) { - //printf("v53: dreq3 not in 71071mode\n"); + 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); } -} -WRITE_LINE_MEMBER(v53_base_device::hack_w) -{ - if (!(m_SCTL & 0x02)) + if (m_OPSEL & OPSEL_TS) { - m_v53dmau->hack_w(state); + 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); } - else + + if (m_OPSEL & OPSEL_SS) { - //printf("v53: hack_w not in 71071mode\n"); + 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); } } -/* General stuff */ - -void v53_base_device::v53_internal_port_map(address_map &map) +void v50_device::internal_port_map(address_map &map) { v33_internal_port_map(map); - map(0xffe0, 0xffe0).w(FUNC(v53_base_device::BSEL_w)); // 0xffe0 // uPD71037 DMA mode bank selection register - map(0xffe1, 0xffe1).w(FUNC(v53_base_device::BADR_w)); // 0xffe1 // uPD71037 DMA mode bank register peripheral mapping (also uses OPHA) -// AM_RANGE(0xffe2, 0xffe3) // (reserved , 0x00ff) // 0xffe2 -// AM_RANGE(0xffe2, 0xffe3) // (reserved , 0xff00) // 0xffe3 -// AM_RANGE(0xffe4, 0xffe5) // (reserved , 0x00ff) // 0xffe4 -// AM_RANGE(0xffe4, 0xffe5) // (reserved , 0xff00) // 0xffe5 -// AM_RANGE(0xffe6, 0xffe7) // (reserved , 0x00ff) // 0xffe6 -// AM_RANGE(0xffe6, 0xffe7) // (reserved , 0xff00) // 0xffe7 -// AM_RANGE(0xffe8, 0xffe9) // (reserved , 0x00ff) // 0xffe8 - map(0xffe9, 0xffe9).w(FUNC(v53_base_device::BRC_w)); // 0xffe9 // baud rate counter (used for serial peripheral) - map(0xffea, 0xffea).w(FUNC(v53_base_device::WMB0_w)); // 0xffea // waitstate control - map(0xffeb, 0xffeb).w(FUNC(v53_base_device::WCY1_w)); // 0xffeb // waitstate control - map(0xffec, 0xffec).w(FUNC(v53_base_device::WCY0_w)); // 0xffec // waitstate control - map(0xffed, 0xffed).w(FUNC(v53_base_device::WAC_w)); // 0xffed // waitstate control -// AM_RANGE(0xffee, 0xffef) // (reserved , 0x00ff) // 0xffee -// AM_RANGE(0xffee, 0xffef) // (reserved , 0xff00) // 0xffef - map(0xfff0, 0xfff0).w(FUNC(v53_base_device::TCKS_w)); // 0xfff0 // timer clocks - map(0xfff1, 0xfff1).w(FUNC(v53_base_device::SBCR_w)); // 0xfff1 // internal clock divider, halt behavior etc. - map(0xfff2, 0xfff2).w(FUNC(v53_base_device::REFC_w)); // 0xfff2 // ram refresh control - map(0xfff3, 0xfff3).w(FUNC(v53_base_device::WMB1_w)); // 0xfff3 // waitstate control - map(0xfff4, 0xfff4).w(FUNC(v53_base_device::WCY2_w)); // 0xfff4 // waitstate control - map(0xfff5, 0xfff5).w(FUNC(v53_base_device::WCY3_w)); // 0xfff5 // waitstate control - map(0xfff6, 0xfff6).w(FUNC(v53_base_device::WCY4_w)); // 0xfff6 // waitstate control -// AM_RANGE(0xfff6, 0xfff7) // (reserved , 0xff00) // 0xfff7 - map(0xfff8, 0xfff8).w(FUNC(v53_base_device::SULA_w)); // 0xfff8 // peripheral mapping - map(0xfff9, 0xfff9).w(FUNC(v53_base_device::TULA_w)); // 0xfff9 // peripheral mapping - map(0xfffa, 0xfffa).w(FUNC(v53_base_device::IULA_w)); // 0xfffa // peripheral mapping - map(0xfffb, 0xfffb).w(FUNC(v53_base_device::DULA_w)); // 0xfffb // peripheral mapping - map(0xfffc, 0xfffc).w(FUNC(v53_base_device::OPHA_w)); // 0xfffc // peripheral mapping (upper bits, common) - map(0xfffd, 0xfffd).w(FUNC(v53_base_device::OPSEL_w)); // 0xfffd // peripheral enabling - map(0xfffe, 0xfffe).w(FUNC(v53_base_device::SCTL_w)); // 0xfffe // peripheral configuration (& byte / word mapping) -// AM_RANGE(0xfffe, 0xffff) // (reserved , 0xff00) // 0xffff -} + 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)); -READ8_MEMBER(v53_base_device::get_pic_ack) -{ - return 0; + 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); + map(0xffe0, 0xffe0).w(FUNC(v53_device::BSEL_w)); // uPD71037 DMA mode bank selection register + map(0xffe1, 0xffe1).w(FUNC(v53_device::BADR_w)); // uPD71037 DMA mode bank register peripheral mapping (also uses OPHA) + // 0xffe2-0xffe9 reserved + map(0xffe9, 0xffe9).w(FUNC(v53_device::BRC_w)); // baud rate counter (used for serial peripheral) + map(0xffea, 0xffea).w(FUNC(v53_device::WMB0_w)); // waitstate control + map(0xffeb, 0xffeb).w(FUNC(v53_device::WCY1_w)); // waitstate control + map(0xffec, 0xffec).w(FUNC(v53_device::WCY0_w)); // waitstate control + map(0xffed, 0xffed).w(FUNC(v53_device::WAC_w)); // waitstate control + // 0xffee-0xffef reserved + map(0xfff0, 0xfff0).w(FUNC(v53_device::TCKS_w)); // timer clocks + map(0xfff1, 0xfff1).w(FUNC(v53_device::SBCR_w)); // internal clock divider, halt behavior etc. + map(0xfff2, 0xfff2).w(FUNC(v53_device::RFC_w)); // ram refresh control + map(0xfff3, 0xfff3).w(FUNC(v53_device::WMB1_w)); // waitstate control + map(0xfff4, 0xfff4).w(FUNC(v53_device::WCY2_w)); // waitstate control + map(0xfff5, 0xfff5).w(FUNC(v53_device::WCY3_w)); // waitstate control + map(0xfff6, 0xfff6).w(FUNC(v53_device::WCY4_w)); // waitstate control + // 0xfff6 reserved + map(0xfff8, 0xfff8).w(FUNC(v53_device::SULA_w)); // scu mapping + map(0xfff9, 0xfff9).w(FUNC(v53_device::TULA_w)); // tcu mapping + map(0xfffa, 0xfffa).w(FUNC(v53_device::IULA_w)); // icu mapping + map(0xfffb, 0xfffb).w(FUNC(v53_device::DULA_w)); // dmau mapping + map(0xfffc, 0xfffc).w(FUNC(v53_device::OPHA_w)); // peripheral mapping (upper bits, common) + map(0xfffd, 0xfffd).w(FUNC(v53_device::OPSEL_w)); // peripheral enabling + map(0xfffe, 0xfffe).w(FUNC(v53_device::SCTL_w)); // peripheral configuration (& byte / word mapping) + // 0xffff reserved +} // the external interface provides no external access to the usual IRQ line of the V33, everything goes through the interrupt controller -void v53_base_device::execute_set_input(int irqline, int state) +void v5x_base_device::execute_set_input(int irqline, int state) { switch (irqline) { - case INPUT_LINE_IRQ0: m_v53icu->ir0_w(state); break; - case INPUT_LINE_IRQ1: m_v53icu->ir1_w(state); break; - case INPUT_LINE_IRQ2: m_v53icu->ir2_w(state); break; - case INPUT_LINE_IRQ3: m_v53icu->ir3_w(state); break; - case INPUT_LINE_IRQ4: m_v53icu->ir4_w(state); break; - case INPUT_LINE_IRQ5: m_v53icu->ir5_w(state); break; - case INPUT_LINE_IRQ6: m_v53icu->ir6_w(state); break; - case INPUT_LINE_IRQ7: m_v53icu->ir7_w(state); break; + 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; @@ -498,102 +394,61 @@ void v53_base_device::execute_set_input(int irqline, int state) } // for hooking the interrupt controller output up to the core -WRITE_LINE_MEMBER(v53_base_device::internal_irq_w) +WRITE_LINE_MEMBER(v5x_base_device::internal_irq_w) { nec_common_device::execute_set_input(0, state); } - -void v53_base_device::device_add_mconfig(machine_config &config) +void v5x_base_device::device_add_mconfig(machine_config &config) { - PIT8254(config, m_v53tcu, 0); // functionality identical to uPD71054 - m_v53tcu->set_clk<0>(16000000); // manual implicitly claims that these runs at same speed as the CPU - m_v53tcu->set_clk<1>(16000000); - m_v53tcu->set_clk<2>(16000000); - m_v53tcu->out_handler<0>().set([this] (int state) { m_out0_handler(state); }); - m_v53tcu->out_handler<1>().set([this] (int state) { m_out1_handler(state); }); - m_v53tcu->out_handler<2>().set([this] (int state) { m_out2_handler(state); }); - - V53_DMAU(config, m_v53dmau, 4000000); - m_v53dmau->out_hreq_callback().set([this] (int state) { m_out_hreq_cb(state); }); - m_v53dmau->out_eop_callback().set([this] (int state) { m_out_eop_cb(state); }); - m_v53dmau->in_memr_callback().set([this] (address_space &space, offs_t offset) { return m_in_memr_cb(space, offset); }); - m_v53dmau->out_memw_callback().set([this] (address_space &space, offs_t offset, uint8_t data) { m_out_memw_cb(space, offset, data); }); - m_v53dmau->in_ior_callback<0>().set([this] (address_space &space, offs_t offset) { return m_in_ior_0_cb(space, offset); }); - m_v53dmau->in_ior_callback<1>().set([this] (address_space &space, offs_t offset) { return m_in_ior_1_cb(space, offset); }); - m_v53dmau->in_ior_callback<2>().set([this] (address_space &space, offs_t offset) { return m_in_ior_2_cb(space, offset); }); - m_v53dmau->in_ior_callback<3>().set([this] (address_space &space, offs_t offset) { return m_in_ior_3_cb(space, offset); }); - m_v53dmau->out_iow_callback<0>().set([this] (address_space &space, offs_t offset, uint8_t data) { m_out_iow_0_cb(space, offset, data); }); - m_v53dmau->out_iow_callback<1>().set([this] (address_space &space, offs_t offset, uint8_t data) { m_out_iow_1_cb(space, offset, data); }); - m_v53dmau->out_iow_callback<2>().set([this] (address_space &space, offs_t offset, uint8_t data) { m_out_iow_2_cb(space, offset, data); }); - m_v53dmau->out_iow_callback<3>().set([this] (address_space &space, offs_t offset, uint8_t data) { m_out_iow_3_cb(space, offset, data); }); - m_v53dmau->out_dack_callback<0>().set([this] (int state) { m_out_dack_0_cb(state); }); - m_v53dmau->out_dack_callback<1>().set([this] (int state) { m_out_dack_1_cb(state); }); - m_v53dmau->out_dack_callback<2>().set([this] (int state) { m_out_dack_2_cb(state); }); - m_v53dmau->out_dack_callback<3>().set([this] (int state) { m_out_dack_3_cb(state); }); - - PIC8259(config, m_v53icu, 0); - m_v53icu->out_int_callback().set(FUNC(v53_base_device::internal_irq_w)); - m_v53icu->in_sp_callback().set_constant(1); - m_v53icu->read_slave_ack_callback().set(FUNC(v53_base_device::get_pic_ack)); - - V53_SCU(config, m_v53scu, 0); - m_v53scu->txd_handler().set(FUNC(v53_base_device::scu_txd_trampoline_cb)); - m_v53scu->dtr_handler().set(FUNC(v53_base_device::scu_dtr_trampoline_cb)); - m_v53scu->rts_handler().set(FUNC(v53_base_device::scu_rts_trampoline_cb)); - m_v53scu->rxrdy_handler().set(FUNC(v53_base_device::scu_rxrdy_trampoline_cb)); - m_v53scu->txrdy_handler().set(FUNC(v53_base_device::scu_txrdy_trampoline_cb)); - m_v53scu->txempty_handler().set(FUNC(v53_base_device::scu_txempty_trampoline_cb)); - m_v53scu->syndet_handler().set(FUNC(v53_base_device::scu_syndet_trampoline_cb)); + 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)); +} -v53_base_device::v53_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : - v33_base_device(mconfig, type, tag, owner, clock, address_map_constructor(FUNC(v53_base_device::v53_internal_port_map), this)), - m_v53tcu(*this, "pit"), - m_v53dmau(*this, "upd71071dma"), - m_v53icu(*this, "upd71059pic"), - m_v53scu(*this, "v53scu"), - // SCU - m_txd_handler(*this), - m_dtr_handler(*this), - m_rts_handler(*this), - m_rxrdy_handler(*this), - m_txrdy_handler(*this), - m_txempty_handler(*this), - m_syndet_handler(*this), - // TCU - m_out0_handler(*this), - m_out1_handler(*this), - m_out2_handler(*this), - // DMAU - m_out_hreq_cb(*this), - m_out_eop_cb(*this), - m_in_memr_cb(*this), - m_out_memw_cb(*this), - m_in_ior_0_cb(*this), - m_in_ior_1_cb(*this), - m_in_ior_2_cb(*this), - m_in_ior_3_cb(*this), - m_out_iow_0_cb(*this), - m_out_iow_1_cb(*this), - m_out_iow_2_cb(*this), - m_out_iow_3_cb(*this), - m_out_dack_0_cb(*this), - m_out_dack_1_cb(*this), - m_out_dack_2_cb(*this), - m_out_dack_3_cb(*this) +v5x_base_device::v5x_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) + : v33_base_device(mconfig, type, tag, owner, clock, address_map_constructor(FUNC(v5x_base_device::internal_port_map), this)) + , 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) +{ +} -v53_device::v53_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : v53_base_device(mconfig, V53, tag, owner, clock) +v53_device::v53_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : v5x_base_device(mconfig, V53, tag, owner, clock) { } +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) +{ +} -v53a_device::v53a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : v53_base_device(mconfig, V53A, tag, owner, clock) +v53a_device::v53a_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : v53_device(mconfig, V53A, tag, owner, clock) { } diff --git a/src/devices/cpu/nec/v53.h b/src/devices/cpu/nec/v53.h index 70909a619bd..47ed9a70c5b 100644 --- a/src/devices/cpu/nec/v53.h +++ b/src/devices/cpu/nec/v53.h @@ -1,6 +1,6 @@ // license:BSD-3-Clause // copyright-holders:Bryan McPhail -/* V53 */ + #ifndef MAME_CPU_NEC_V53_H #define MAME_CPU_NEC_V53_H @@ -13,264 +13,160 @@ #include "machine/pic8259.h" #include "machine/pit8253.h" -// SCU - -#define MCFG_V53_SCU_TXD_HANDLER(_devcb) \ - downcast<v53_base_device &>(*device).set_txd_handler(DEVCB_##_devcb); - -#define MCFG_V53_SCU_DTR_HANDLER(_devcb) \ - downcast<v53_base_device &>(*device).set_dtr_handler(DEVCB_##_devcb); - -#define MCFG_V53_SCU_RTS_HANDLER(_devcb) \ - downcast<v53_base_device &>(*device).set_rts_handler(DEVCB_##_devcb); - -#define MCFG_V53_SCU_RXRDY_HANDLER(_devcb) \ - downcast<v53_base_device &>(*device).set_rxrdy_handler(DEVCB_##_devcb); - -#define MCFG_V53_SCU_TXRDY_HANDLER(_devcb) \ - downcast<v53_base_device &>(*device).set_txrdy_handler(DEVCB_##_devcb); - -#define MCFG_V53_SCU_TXEMPTY_HANDLER(_devcb) \ - downcast<v53_base_device &>(*device).set_txempty_handler(DEVCB_##_devcb); - -#define MCFG_V53_SCU_SYNDET_HANDLER(_devcb) \ - downcast<v53_base_device &>(*device).set_syndet_handler(DEVCB_##_devcb); - -// TCU -#define MCFG_V53_TCU_CLK0(_clk) \ - downcast<v53_base_device &>(*device).set_clk0(_clk); - -#define MCFG_V53_TCU_CLK1(_clk) \ - downcast<v53_base_device &>(*device).set_clk1(_clk); - -#define MCFG_V53_TCU_CLK2(_clk) \ - downcast<v53_base_device &>(*device).set_clk2(_clk); - -#define MCFG_V53_TCU_OUT0_HANDLER(_devcb) \ - downcast<v53_base_device &>(*device).set_out0_handler(DEVCB_##_devcb); - -#define MCFG_V53_TCU_OUT1_HANDLER(_devcb) \ - downcast<v53_base_device &>(*device).set_out1_handler(DEVCB_##_devcb); - -#define MCFG_V53_TCU_OUT2_HANDLER(_devcb) \ - downcast<v53_base_device &>(*device).set_out2_handler(DEVCB_##_devcb); - -// DMAU - -#define MCFG_V53_DMAU_OUT_HREQ_CB(_devcb) \ - downcast<v53_base_device &>(*device).set_out_hreq_callback(DEVCB_##_devcb); - -#define MCFG_V53_DMAU_OUT_EOP_CB(_devcb) \ - downcast<v53_base_device &>(*device).set_out_eop_callback(DEVCB_##_devcb); - -#define MCFG_V53_DMAU_IN_MEMR_CB(_devcb) \ - downcast<v53_base_device &>(*device).set_in_memr_callback(DEVCB_##_devcb); - -#define MCFG_V53_DMAU_OUT_MEMW_CB(_devcb) \ - downcast<v53_base_device &>(*device).set_out_memw_callback(DEVCB_##_devcb); - -#define MCFG_V53_DMAU_IN_IOR_0_CB(_devcb) \ - downcast<v53_base_device &>(*device).set_in_ior_0_callback(DEVCB_##_devcb); - -#define MCFG_V53_DMAU_IN_IOR_1_CB(_devcb) \ - downcast<v53_base_device &>(*device).set_in_ior_1_callback(DEVCB_##_devcb); - -#define MCFG_V53_DMAU_IN_IOR_2_CB(_devcb) \ - downcast<v53_base_device &>(*device).set_in_ior_2_callback(DEVCB_##_devcb); - -#define MCFG_V53_DMAU_IN_IOR_3_CB(_devcb) \ - downcast<v53_base_device &>(*device).set_in_ior_3_callback(DEVCB_##_devcb); - -#define MCFG_V53_DMAU_OUT_IOW_0_CB(_devcb) \ - downcast<v53_base_device &>(*device).set_out_iow_0_callback(DEVCB_##_devcb); - -#define MCFG_V53_DMAU_OUT_IOW_1_CB(_devcb) \ - downcast<v53_base_device &>(*device).set_out_iow_1_callback(DEVCB_##_devcb); - -#define MCFG_V53_DMAU_OUT_IOW_2_CB(_devcb) \ - downcast<v53_base_device &>(*device).set_out_iow_2_callback(DEVCB_##_devcb); - -#define MCFG_V53_DMAU_OUT_IOW_3_CB(_devcb) \ - downcast<v53_base_device &>(*device).set_out_iow_3_callback(DEVCB_##_devcb); - -#define MCFG_V53_DMAU_OUT_DACK_0_CB(_devcb) \ - downcast<v53_base_device &>(*device).set_out_dack_0_callback(DEVCB_##_devcb); +class v5x_base_device : public v33_base_device +{ +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>(); } -#define MCFG_V53_DMAU_OUT_DACK_1_CB(_devcb) \ - downcast<v53_base_device &>(*device).set_out_dack_1_callback(DEVCB_##_devcb); + // 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>(); } -#define MCFG_V53_DMAU_OUT_DACK_2_CB(_devcb) \ - downcast<v53_base_device &>(*device).set_out_dack_2_callback(DEVCB_##_devcb); + // 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(); } -#define MCFG_V53_DMAU_OUT_DACK_3_CB(_devcb) \ - downcast<v53_base_device &>(*device).set_out_dack_3_callback(DEVCB_##_devcb); +protected: + v5x_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); + // 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; + // device_execute_interface overrides + virtual void execute_set_input(int inputnum, int state) override; -class v53_base_device : public v33_base_device -{ -public: - DECLARE_WRITE8_MEMBER(BSEL_w); - DECLARE_WRITE8_MEMBER(BADR_w); - DECLARE_WRITE8_MEMBER(BRC_w); - DECLARE_WRITE8_MEMBER(WMB0_w); - DECLARE_WRITE8_MEMBER(WCY1_w); - DECLARE_WRITE8_MEMBER(WCY0_w); - DECLARE_WRITE8_MEMBER(WAC_w); - DECLARE_WRITE8_MEMBER(TCKS_w); - DECLARE_WRITE8_MEMBER(SBCR_w); - DECLARE_WRITE8_MEMBER(REFC_w); - DECLARE_WRITE8_MEMBER(WMB1_w); - DECLARE_WRITE8_MEMBER(WCY2_w); - DECLARE_WRITE8_MEMBER(WCY3_w); - DECLARE_WRITE8_MEMBER(WCY4_w); + virtual void internal_port_map(address_map &map) = 0; + virtual void install_peripheral_io() = 0; + + DECLARE_WRITE8_MEMBER(BSEL_w) {} + DECLARE_WRITE8_MEMBER(BADR_w) {} + DECLARE_WRITE8_MEMBER(BRC_w) {} + DECLARE_WRITE8_MEMBER(WMB0_w) {} + DECLARE_WRITE8_MEMBER(WCY1_w) {} + DECLARE_WRITE8_MEMBER(WCY0_w) {} + DECLARE_WRITE8_MEMBER(WAC_w) {} + DECLARE_WRITE8_MEMBER(TCKS_w) {} + DECLARE_WRITE8_MEMBER(SBCR_w) {} + DECLARE_WRITE8_MEMBER(RFC_w) {} + DECLARE_WRITE8_MEMBER(WMB1_w) {} + DECLARE_WRITE8_MEMBER(WCY2_w) {} + DECLARE_WRITE8_MEMBER(WCY3_w) {} + DECLARE_WRITE8_MEMBER(WCY4_w) {} DECLARE_WRITE8_MEMBER(SULA_w); DECLARE_WRITE8_MEMBER(TULA_w); DECLARE_WRITE8_MEMBER(IULA_w); DECLARE_WRITE8_MEMBER(DULA_w); DECLARE_WRITE8_MEMBER(OPHA_w); DECLARE_WRITE8_MEMBER(OPSEL_w); - DECLARE_WRITE8_MEMBER(SCTL_w); - - // SCU - DECLARE_READ8_MEMBER(scu_simk_r); - DECLARE_WRITE8_MEMBER(scu_simk_w); - template <class Object> devcb_base &set_txd_handler(Object &&cb) { return m_txd_handler.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_dtr_handler(Object &&cb) { return m_dtr_handler.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_rts_handler(Object &&cb) { return m_rts_handler.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_rxrdy_handler(Object &&cb) { return m_rxrdy_handler.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_txrdy_handler(Object &&cb) { return m_txrdy_handler.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_txempty_handler(Object &&cb) { return m_txempty_handler.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_syndet_handler(Object &&cb) { return m_syndet_handler.set_callback(std::forward<Object>(cb)); } - DECLARE_WRITE_LINE_MEMBER(scu_txd_trampoline_cb) { m_txd_handler(state); } - DECLARE_WRITE_LINE_MEMBER(scu_dtr_trampoline_cb) { m_dtr_handler(state); } - DECLARE_WRITE_LINE_MEMBER(scu_rts_trampoline_cb) { m_rts_handler(state); } - DECLARE_WRITE_LINE_MEMBER(scu_rxrdy_trampoline_cb) { m_rxrdy_handler(state); } /* should we mask this here based on m_simk? it can mask the interrupt */ - DECLARE_WRITE_LINE_MEMBER(scu_txrdy_trampoline_cb) { m_txrdy_handler(state); } /* should we mask this here based on m_simk? it can mask the interrupt */ - DECLARE_WRITE_LINE_MEMBER(scu_txempty_trampoline_cb) { m_txempty_handler(state); } - DECLARE_WRITE_LINE_MEMBER(scu_syndet_trampoline_cb) { m_syndet_handler(state); } + DECLARE_READ8_MEMBER(get_pic_ack) { return 0; } + DECLARE_WRITE_LINE_MEMBER(internal_irq_w); - // TCU - DECLARE_READ8_MEMBER(tmu_tst0_r); - DECLARE_WRITE8_MEMBER(tmu_tct0_w); - DECLARE_READ8_MEMBER(tmu_tst1_r); - DECLARE_WRITE8_MEMBER(tmu_tct1_w); - DECLARE_READ8_MEMBER(tmu_tst2_r); - DECLARE_WRITE8_MEMBER(tmu_tct2_w); - DECLARE_WRITE8_MEMBER(tmu_tmd_w); -// void set_clk0(double clk0) { m_clk0 = clk0; } -// void set_clk1(double clk1) { m_clk1 = clk1; } -// void set_clk2(double clk2) { m_clk2 = clk2; } - template <class Object> devcb_base &set_out0_handler(Object &&cb) { return m_out0_handler.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_out1_handler(Object &&cb) { return m_out1_handler.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_out2_handler(Object &&cb) { return m_out2_handler.set_callback(std::forward<Object>(cb)); } + required_device<pit8253_device> m_tcu; + required_device<v5x_dmau_device> m_dmau; + required_device<v5x_icu_device> m_icu; + required_device<v5x_scu_device> m_scu; + + enum opsel_mask + { + OPSEL_DS = 0x01, // dmau enabled + OPSEL_IS = 0x02, // icu enabled + OPSEL_TS = 0x04, // tcu enabled + OPSEL_SS = 0x08, // scu enabled + }; + u8 m_OPSEL; + + u8 m_SULA; + u8 m_TULA; + u8 m_IULA; + u8 m_DULA; + u8 m_OPHA; +}; - // DMAU - template<class Object> devcb_base &set_out_hreq_callback(Object &&cb) { return m_out_hreq_cb.set_callback(std::forward<Object>(cb)); } - template<class Object> devcb_base &set_out_eop_callback(Object &&cb) { return m_out_eop_cb.set_callback(std::forward<Object>(cb)); } - template<class Object> devcb_base &set_in_memr_callback(Object &&cb) { return m_in_memr_cb.set_callback(std::forward<Object>(cb)); } - template<class Object> devcb_base &set_out_memw_callback(Object &&cb) { return m_out_memw_cb.set_callback(std::forward<Object>(cb)); } - template<class Object> devcb_base &set_in_ior_0_callback(Object &&cb) { return m_in_ior_0_cb.set_callback(std::forward<Object>(cb)); } - template<class Object> devcb_base &set_in_ior_1_callback(Object &&cb) { return m_in_ior_1_cb.set_callback(std::forward<Object>(cb)); } - template<class Object> devcb_base &set_in_ior_2_callback(Object &&cb) { return m_in_ior_2_cb.set_callback(std::forward<Object>(cb)); } - template<class Object> devcb_base &set_in_ior_3_callback(Object &&cb) { return m_in_ior_3_cb.set_callback(std::forward<Object>(cb)); } - template<class Object> devcb_base &set_out_iow_0_callback(Object &&cb) { return m_out_iow_0_cb.set_callback(std::forward<Object>(cb)); } - template<class Object> devcb_base &set_out_iow_1_callback(Object &&cb) { return m_out_iow_1_cb.set_callback(std::forward<Object>(cb)); } - template<class Object> devcb_base &set_out_iow_2_callback(Object &&cb) { return m_out_iow_2_cb.set_callback(std::forward<Object>(cb)); } - template<class Object> devcb_base &set_out_iow_3_callback(Object &&cb) { return m_out_iow_3_cb.set_callback(std::forward<Object>(cb)); } - template<class Object> devcb_base &set_out_dack_0_callback(Object &&cb) { return m_out_dack_0_cb.set_callback(std::forward<Object>(cb)); } - template<class Object> devcb_base &set_out_dack_1_callback(Object &&cb) { return m_out_dack_1_cb.set_callback(std::forward<Object>(cb)); } - template<class Object> devcb_base &set_out_dack_2_callback(Object &&cb) { return m_out_dack_2_cb.set_callback(std::forward<Object>(cb)); } - template<class Object> devcb_base &set_out_dack_3_callback(Object &&cb) { return m_out_dack_3_cb.set_callback(std::forward<Object>(cb)); } +class v50_device : public v5x_base_device +{ +public: + v50_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); - DECLARE_WRITE_LINE_MEMBER(dreq0_w); - DECLARE_WRITE_LINE_MEMBER(dreq1_w); - DECLARE_WRITE_LINE_MEMBER(dreq2_w); - DECLARE_WRITE_LINE_MEMBER(dreq3_w); - DECLARE_WRITE_LINE_MEMBER(hack_w); + 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); } - void v53_internal_port_map(address_map &map); protected: - v53_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); - - // device-level overrides + // 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 execute_set_input(int inputnum, int state) override; - void install_peripheral_io(); + virtual void internal_port_map(address_map &map) override; + virtual void install_peripheral_io() override; - uint8_t m_SCTL; - uint8_t m_OPSEL; + DECLARE_WRITE8_MEMBER(OPCN_w); - uint8_t m_SULA; - uint8_t m_TULA; - uint8_t m_IULA; - uint8_t m_DULA; - uint8_t m_OPHA; - - uint8_t m_simk; - - required_device<pit8253_device> m_v53tcu; - required_device<upd71071_v53_device> m_v53dmau; - required_device<pic8259_device> m_v53icu; - required_device<v53_scu_device> m_v53scu; - - // SCU - devcb_write_line m_txd_handler; - devcb_write_line m_dtr_handler; - devcb_write_line m_rts_handler; - devcb_write_line m_rxrdy_handler; - devcb_write_line m_txrdy_handler; - devcb_write_line m_txempty_handler; - devcb_write_line m_syndet_handler; +private: + u8 m_OPCN; +}; - // TCU -// double m_clk0; -// double m_clk1; -// double m_clk2; - devcb_write_line m_out0_handler; - devcb_write_line m_out1_handler; - devcb_write_line m_out2_handler; +class v53_device : public v5x_base_device +{ +public: + v53_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + template <unsigned Channel> DECLARE_WRITE_LINE_MEMBER(dreq_w) + { + // dreq0 could be wrong / nonexistent + if (!(m_SCTL & 0x02)) + { + m_dmau->dreq_w<Channel>(state); + } + else + { + logerror("dreq%d not in 71071mode\n", Channel); + } + } + DECLARE_WRITE_LINE_MEMBER(hack_w); +protected: + v53_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); - // DMAU - devcb_write_line m_out_hreq_cb; - devcb_write_line m_out_eop_cb; - devcb_read8 m_in_memr_cb; - devcb_write8 m_out_memw_cb; - devcb_read8 m_in_ior_0_cb; - devcb_read8 m_in_ior_1_cb; - devcb_read8 m_in_ior_2_cb; - devcb_read8 m_in_ior_3_cb; - devcb_write8 m_out_iow_0_cb; - devcb_write8 m_out_iow_1_cb; - devcb_write8 m_out_iow_2_cb; - devcb_write8 m_out_iow_3_cb; - devcb_write_line m_out_dack_0_cb; - devcb_write_line m_out_dack_1_cb; - devcb_write_line m_out_dack_2_cb; - devcb_write_line m_out_dack_3_cb; + // device_interface overrides + virtual void device_start() override; + virtual void device_reset() override; - DECLARE_READ8_MEMBER(get_pic_ack); - DECLARE_WRITE_LINE_MEMBER(internal_irq_w); -}; + virtual void internal_port_map(address_map &map) override; + virtual void install_peripheral_io() override; + DECLARE_WRITE8_MEMBER(SCTL_w); -class v53_device : public v53_base_device -{ -public: - v53_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); +private: + u8 m_SCTL; }; -class v53a_device : public v53_base_device +class v53a_device : public v53_device { public: - v53a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + v53a_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); }; +DECLARE_DEVICE_TYPE(V50, v50_device) DECLARE_DEVICE_TYPE(V53, v53_device) DECLARE_DEVICE_TYPE(V53A, v53a_device) |