From 94cdc63a802deb67ef2367ee1aa0aa604aec5e2e Mon Sep 17 00:00:00 2001 From: arbee Date: Sun, 27 Oct 2024 21:59:46 -0400 Subject: [PATCH] apple/pseudovia.cpp: Split out the pseudo-VIA device used by RBV, V8, VASP, and Sonora. [R. Belmont] * This device was previously copy-pasted almost verbatim between those 4 devices, and it will be appearing in PowerBooks in the future as well. apple/mac*.cpp: All 68020 and 68030 Macintoshes that didn't come with an FPU but were able to be fitted with one later now gate it behind a configuration switch. [R. Belmont] * You must completely exit out of the driver to for changes take effect. This may be relaxed in the future. --- src/mame/apple/maciici.cpp | 18 +- src/mame/apple/maciivx.cpp | 20 ++- src/mame/apple/maclc.cpp | 26 ++- src/mame/apple/maclc3.cpp | 24 ++- src/mame/apple/pseudovia.cpp | 300 ++++++++++++++++++++++++++++++++++ src/mame/apple/pseudovia.h | 51 ++++++ src/mame/apple/rbv.cpp | 67 ++++---- src/mame/apple/rbv.h | 8 + src/mame/apple/sonora.cpp | 214 ++---------------------- src/mame/apple/sonora.h | 13 +- src/mame/apple/v8.cpp | 307 ++++++----------------------------- src/mame/apple/v8.h | 26 +-- src/mame/apple/vasp.cpp | 254 +++-------------------------- src/mame/apple/vasp.h | 11 +- 14 files changed, 571 insertions(+), 768 deletions(-) create mode 100644 src/mame/apple/pseudovia.cpp create mode 100644 src/mame/apple/pseudovia.h diff --git a/src/mame/apple/maciici.cpp b/src/mame/apple/maciici.cpp index a42efbdd47f..eac97889ade 100644 --- a/src/mame/apple/maciici.cpp +++ b/src/mame/apple/maciici.cpp @@ -68,7 +68,8 @@ public: m_floppy(*this, "fdc:%d", 0U), m_scc(*this, "scc"), m_rtc(*this, "rtc"), - m_egret(*this, "egret") + m_egret(*this, "egret"), + m_config(*this, "config") { } @@ -96,6 +97,7 @@ private: required_device m_scc; optional_device m_rtc; optional_device m_egret; + optional_ioport m_config; void set_via2_interrupt(int value); void field_interrupts(); @@ -203,6 +205,11 @@ void maciici_state::machine_reset() m_maincpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); } + if (m_config) + { + m_maincpu->set_fpu_enable(BIT(m_config->read(), 0)); + } + // put ROM mirror at 0 address_space &space = m_maincpu->space(AS_PROGRAM); const u32 memory_size = std::min((u32)0x3fffff, m_rom_size); @@ -502,6 +509,13 @@ void maciici_state::devsel_w(uint8_t devsel) static INPUT_PORTS_START(maciici) INPUT_PORTS_END +static INPUT_PORTS_START(maciisi) + PORT_START("config") + PORT_CONFNAME(0x01, 0x00, "FPU") + PORT_CONFSETTING(0x00, "No FPU") + PORT_CONFSETTING(0x01, "FPU Present") +INPUT_PORTS_END + /*************************************************************************** MACHINE DRIVERS ***************************************************************************/ @@ -687,4 +701,4 @@ ROM_END } // anonymous namespace COMP(1989, maciici, 0, 0, maciici, maciici, maciici_state, empty_init, "Apple Computer", "Macintosh IIci", MACHINE_SUPPORTS_SAVE) -COMP(1990, maciisi, 0, 0, maciisi, maciici, maciici_state, empty_init, "Apple Computer", "Macintosh IIsi", MACHINE_SUPPORTS_SAVE) +COMP(1990, maciisi, 0, 0, maciisi, maciisi, maciici_state, empty_init, "Apple Computer", "Macintosh IIsi", MACHINE_SUPPORTS_SAVE) diff --git a/src/mame/apple/maciivx.cpp b/src/mame/apple/maciivx.cpp index 8ecffcc9fd6..2c8699fe7d8 100644 --- a/src/mame/apple/maciivx.cpp +++ b/src/mame/apple/maciivx.cpp @@ -68,6 +68,7 @@ public: m_scsihelp(*this, "scsihelp"), m_scc(*this, "scc"), m_egret(*this, "egret"), + m_config(*this, "config"), m_cur_floppy(nullptr), m_hdsel(0) { @@ -93,8 +94,10 @@ private: required_device m_scsihelp; required_device m_scc; required_device m_egret; + optional_ioport m_config; virtual void machine_start() override ATTR_COLD; + virtual void machine_reset() override ATTR_COLD; u16 scc_r(offs_t offset) { @@ -139,6 +142,14 @@ void maciivx_state::machine_start() save_item(NAME(m_hdsel)); } +void maciivx_state::machine_reset() +{ + if (m_config) + { + m_maincpu->set_fpu_enable(BIT(m_config->read(), 0)); + } +} + /*************************************************************************** ADDRESS MAPS ***************************************************************************/ @@ -285,6 +296,13 @@ void maciivx_state::hdsel_w(int state) static INPUT_PORTS_START( maciivx ) INPUT_PORTS_END +static INPUT_PORTS_START( maciivi ) + PORT_START("config") + PORT_CONFNAME(0x01, 0x00, "FPU") + PORT_CONFSETTING(0x00, "No FPU") + PORT_CONFSETTING(0x01, "FPU Present") +INPUT_PORTS_END + /*************************************************************************** MACHINE DRIVERS ***************************************************************************/ @@ -424,4 +442,4 @@ ROM_END } // anonymous namespace COMP(1993, maciivx, 0, 0, maciivx, maciivx, maciivx_state, empty_init, "Apple Computer", "Macintosh IIvx", MACHINE_SUPPORTS_SAVE) -COMP(1993, maciivi, maciivx, 0, maciivi, maciivx, maciivx_state, empty_init, "Apple Computer", "Macintosh IIvi", MACHINE_SUPPORTS_SAVE) +COMP(1993, maciivi, maciivx, 0, maciivi, maciivi, maciivx_state, empty_init, "Apple Computer", "Macintosh IIvi", MACHINE_SUPPORTS_SAVE) diff --git a/src/mame/apple/maclc.cpp b/src/mame/apple/maclc.cpp index 275f643118f..754c1b3a849 100644 --- a/src/mame/apple/maclc.cpp +++ b/src/mame/apple/maclc.cpp @@ -74,6 +74,7 @@ public: m_scc(*this, "scc"), m_egret(*this, "egret"), m_cuda(*this, "cuda"), + m_config(*this, "config"), m_cur_floppy(nullptr), m_hdsel(0) { @@ -102,8 +103,10 @@ private: required_device m_scc; optional_device m_egret; optional_device m_cuda; + optional_ioport m_config; virtual void machine_start() override ATTR_COLD; + virtual void machine_reset() override ATTR_COLD; u16 scc_r(offs_t offset) { @@ -159,6 +162,14 @@ void maclc_state::machine_start() save_item(NAME(m_hdsel)); } +void maclc_state::machine_reset() +{ + if (m_config) + { + m_maincpu->set_fpu_enable(BIT(m_config->read(), 0)); + } +} + /*************************************************************************** ADDRESS MAPS ***************************************************************************/ @@ -306,6 +317,14 @@ void maclc_state::hdsel_w(int state) ***************************************************************************/ static INPUT_PORTS_START( maclc ) + PORT_START("config") + PORT_CONFNAME(0x01, 0x00, "FPU") + PORT_CONFSETTING(0x00, "No FPU") + PORT_CONFSETTING(0x01, "FPU Present") +INPUT_PORTS_END + +// mactv doesn't have a way to add an FPU +static INPUT_PORTS_START( mactv ) INPUT_PORTS_END /*************************************************************************** @@ -386,8 +405,8 @@ void maclc_state::maclc_base(machine_config &config) nubus.set_space(m_maincpu, AS_PROGRAM); nubus.set_address_mask(0x80ffffff); // V8 supports interrupts for slots $C, $D, and $E, but the LC, LC II, and Color Classic - // only hook the slot $E IRQ up to the PDS slot. - nubus.out_irqe_callback().set(m_v8, FUNC(v8_device::slot_irq_w<0x20>)); + // only hook the slot $E IRQ up to the PDS slot. ($C/$D/$E are 0/1/2 on the schematics). + nubus.out_irqe_callback().set(m_v8, FUNC(v8_device::slot2_irq_w)); MACADB(config, m_macadb, C15M); @@ -491,6 +510,7 @@ void maclc_state::mactv(machine_config &config) maclc_base(config); M68030(config.replace(), m_maincpu, C32M); + m_maincpu->set_fpu_enable(false); // this machine has no FPU and no ability to add one m_maincpu->set_addrmap(AS_PROGRAM, &maclc_state::maccclassic_map); m_maincpu->set_dasm_override(std::function(&mac68k_dasm_override), "mac68k_dasm_override"); @@ -595,4 +615,4 @@ COMP(1990, maclc, 0, 0, maclc, maclc, maclc_state, empty_init, "Apple Computer COMP(1991, maclc2, 0, 0, maclc2, maclc, maclc_state, empty_init, "Apple Computer", "Macintosh LC II", MACHINE_SUPPORTS_SAVE) COMP(1991, macclas2, 0, 0, macclas2, maclc, maclc_state, empty_init, "Apple Computer", "Macintosh Classic II", MACHINE_SUPPORTS_SAVE) COMP(1993, maccclas, 0, 0, maccclas, maclc, maclc_state, empty_init, "Apple Computer", "Macintosh Color Classic", MACHINE_SUPPORTS_SAVE) -COMP(1994, mactv, 0, 0, mactv, maclc, maclc_state, empty_init, "Apple Computer", "Macintosh TV", MACHINE_SUPPORTS_SAVE) +COMP(1994, mactv, 0, 0, mactv, mactv, maclc_state, empty_init, "Apple Computer", "Macintosh TV", MACHINE_SUPPORTS_SAVE) diff --git a/src/mame/apple/maclc3.cpp b/src/mame/apple/maclc3.cpp index 586cf75c2b1..077e8eb8c10 100644 --- a/src/mame/apple/maclc3.cpp +++ b/src/mame/apple/maclc3.cpp @@ -64,7 +64,8 @@ public: m_scsihelp(*this, "scsihelp"), m_scc(*this, "scc"), m_egret(*this, "egret"), - m_cuda(*this, "cuda") + m_cuda(*this, "cuda"), + m_config(*this, "config") { } @@ -92,8 +93,10 @@ private: required_device m_scc; optional_device m_egret; optional_device m_cuda; + required_ioport m_config; virtual void machine_start() override ATTR_COLD; + virtual void machine_reset() override ATTR_COLD; u16 scc_r(offs_t offset) { @@ -127,6 +130,14 @@ void macvail_state::machine_start() m_sonora->set_ram_info((u32 *) m_ram->pointer(), m_ram->size()); } +void macvail_state::machine_reset() +{ + if (m_config) + { + m_maincpu->set_fpu_enable(BIT(m_config->read(), 0)); + } +} + /*************************************************************************** ADDRESS MAPS ***************************************************************************/ @@ -232,6 +243,10 @@ void macvail_state::scsi_drq_w(offs_t offset, u32 data, u32 mem_mask) ***************************************************************************/ static INPUT_PORTS_START( macadb ) + PORT_START("config") + PORT_CONFNAME(0x01, 0x00, "FPU") + PORT_CONFSETTING(0x00, "No FPU") + PORT_CONFSETTING(0x01, "FPU Present") INPUT_PORTS_END /*************************************************************************** @@ -313,9 +328,9 @@ void macvail_state::maclc3_base(machine_config &config) nubus_device &nubus(NUBUS(config, "pds", 0)); nubus.set_space(m_maincpu, AS_PROGRAM); // LC III style PDS cards have slot IRQs $C, $D, and $E connected - nubus.out_irqc_callback().set(m_sonora, FUNC(sonora_device::slot_irq_w<0x08>)); - nubus.out_irqd_callback().set(m_sonora, FUNC(sonora_device::slot_irq_w<0x10>)); - nubus.out_irqe_callback().set(m_sonora, FUNC(sonora_device::slot_irq_w<0x20>)); + nubus.out_irqc_callback().set(m_sonora, FUNC(sonora_device::slot0_irq_w)); + nubus.out_irqd_callback().set(m_sonora, FUNC(sonora_device::slot1_irq_w)); + nubus.out_irqe_callback().set(m_sonora, FUNC(sonora_device::slot2_irq_w)); NUBUS_SLOT(config, "lcpds", "pds", mac_pdslc_cards, nullptr); MACADB(config, m_macadb, C15M); @@ -325,6 +340,7 @@ void macvail_state::maclc3(machine_config &config) { maclc3_base(config); m_maincpu->set_addrmap(AS_PROGRAM, &macvail_state::maclc3_map); + m_maincpu->set_fpu_enable(false); // this machine has no FPU EGRET(config, m_egret, XTAL(32'768)); m_egret->set_default_bios_tag("341s0851"); diff --git a/src/mame/apple/pseudovia.cpp b/src/mame/apple/pseudovia.cpp new file mode 100644 index 00000000000..4aa5837b892 --- /dev/null +++ b/src/mame/apple/pseudovia.cpp @@ -0,0 +1,300 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +/* + Apple pseudo-VIA device + Emulation by R. Belmont + + A "pseudo-VIA" is a 2-port GPIO interface and interrupt controller + with a 6522 compatible-ish register layout. The 6522's timers, + shift register, and data direction registers are all missing. + + This first appeared in the Mac IIci's RBV chip, and also showed + up in V8/Eagle/Spice/Tinker Bell, Sonora/Ardbeg, and VASP. + + Quadras used a fairly different pseudo-VIA that acts + much closer to a "real" VIA. (And a real 6522 in the + Quadra 700/900/950). +*/ + +#include "emu.h" +#include "pseudovia.h" + +#define LOG_IRQ (1U << 1) + +#define VERBOSE (0) +#include "logmacro.h" + +DEFINE_DEVICE_TYPE(APPLE_PSEUDOVIA, pseudovia_device, "pseudovia", "Apple pseudo-VIA") + +pseudovia_device::pseudovia_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, APPLE_PSEUDOVIA, tag, owner, clock), + m_write_irq(*this), + m_in_a_handler(*this, 0), + m_in_b_handler(*this, 0), + m_in_config_handler(*this, 0), + m_in_video_handler(*this, 0), + m_out_a_handler(*this), + m_out_b_handler(*this), + m_out_config_handler(*this), + m_out_video_handler(*this) +{ +} + +void pseudovia_device::device_start() +{ + save_item(NAME(m_pseudovia_regs)); + save_item(NAME(m_pseudovia_ier)); + save_item(NAME(m_pseudovia_ifr)); + + m_pseudovia_ier = m_pseudovia_ifr = 0; +} + +void pseudovia_device::device_reset() +{ + std::fill_n(m_pseudovia_regs, 256, 0); + m_pseudovia_regs[2] = 0x7f; +} + +void pseudovia_device::vbl_irq_w(int state) +{ + if (!state) + { + return; + } + + m_pseudovia_regs[2] &= ~0x40; // set vblank signal + + if (m_pseudovia_regs[0x12] & 0x40) + { + pseudovia_recalc_irqs(); + } +} + +template +void pseudovia_device::slot_irq_w(int state) +{ + if (state) + { + m_pseudovia_regs[2] &= ~mask; + } + else + { + m_pseudovia_regs[2] |= mask; + } + + pseudovia_recalc_irqs(); +} + +template void pseudovia_device::slot_irq_w<0x40>(int state); +template void pseudovia_device::slot_irq_w<0x20>(int state); +template void pseudovia_device::slot_irq_w<0x10>(int state); +template void pseudovia_device::slot_irq_w<0x08>(int state); +template void pseudovia_device::slot_irq_w<0x04>(int state); +template void pseudovia_device::slot_irq_w<0x02>(int state); +template void pseudovia_device::slot_irq_w<0x01>(int state); + +void pseudovia_device::asc_irq_w(int state) +{ + if (state == ASSERT_LINE) + { + m_pseudovia_regs[3] |= 0x10; // any VIA 2 interrupt | sound interrupt + pseudovia_recalc_irqs(); + } + else + { + m_pseudovia_regs[3] &= ~0x10; + pseudovia_recalc_irqs(); + } +} + +void pseudovia_device::pseudovia_recalc_irqs() +{ + // check slot interrupts and bubble them down to IFR + uint8_t slot_irqs = (~m_pseudovia_regs[2]) & 0x78; + slot_irqs &= (m_pseudovia_regs[0x12] & 0x78); + + if (slot_irqs) + { + m_pseudovia_regs[3] |= 2; // any slot + } + else // no slot irqs, clear the pending bit + { + m_pseudovia_regs[3] &= ~2; // any slot + } + + uint8_t ifr = (m_pseudovia_regs[3] & m_pseudovia_ier) & 0x1b; + + LOGMASKED(LOG_IRQ, "%s: slot_irqs %02x IFR %02x\n", slot_irqs, ifr); + + if (ifr != 0) + { + m_pseudovia_regs[3] = ifr | 0x80; + m_pseudovia_ifr = ifr | 0x80; + + m_write_irq(ASSERT_LINE); + } + else + { + m_write_irq(CLEAR_LINE); + } +} + +uint8_t pseudovia_device::read(offs_t offset) +{ + u8 data = 0; + if (offset < 0x100) + { + data = m_pseudovia_regs[offset]; + + if (offset == 0) + { + data = m_in_b_handler(); + } + + if (offset == 1) + { + data = m_in_config_handler(); + } + + if (offset == 0x10) + { + data &= ~0x38; + data |= m_in_video_handler(); + } + + // bit 7 of these registers always reads as 0 on pseudo-VIAs + if ((offset == 0x12) || (offset == 0x13)) + { + data &= ~0x80; + } + } + else + { + offset >>= 9; + switch (offset) + { + case 1: // Port A + data = m_in_a_handler(); + break; + + case 13: // IFR + data = m_pseudovia_ifr; + break; + + case 14: // IER + data = m_pseudovia_ier; + break; + + default: + LOG("pseudovia_r: Unknown pseudo-VIA register %d access\n", offset); + break; + } + } + return data; +} + +void pseudovia_device::write(offs_t offset, uint8_t data) +{ + if (offset < 0x100) + { + switch (offset) + { + case 0x00: + m_out_b_handler(data); + break; + + case 0x01: + m_out_config_handler(data); + break; + + case 0x02: + m_pseudovia_regs[offset] |= (data & 0x40); + pseudovia_recalc_irqs(); + break; + + case 0x03: // write here to ack + if (data & 0x80) // 1 bits write 1s + { + m_pseudovia_regs[offset] |= data & 0x7f; + m_pseudovia_ifr |= data & 0x7f; + } + else // 1 bits write 0s + { + m_pseudovia_regs[offset] &= ~(data & 0x7f); + m_pseudovia_ifr &= ~(data & 0x7f); + } + pseudovia_recalc_irqs(); + break; + + case 0x10: + m_pseudovia_regs[offset] = data; + m_out_video_handler(data); + break; + + case 0x12: + if (data & 0x80) // 1 bits write 1s + { + m_pseudovia_regs[offset] |= data & 0x7f; + } + else // 1 bits write 0s + { + m_pseudovia_regs[offset] &= ~(data & 0x7f); + } + pseudovia_recalc_irqs(); + break; + + case 0x13: + if (data & 0x80) // 1 bits write 1s + { + m_pseudovia_regs[offset] |= data & 0x7f; + + if (data == 0xff) + m_pseudovia_regs[offset] = 0x1f; // I don't know why this is special, but the IIci ROM's POST demands it + } + else // 1 bits write 0s + { + m_pseudovia_regs[offset] &= ~(data & 0x7f); + } + break; + + default: + m_pseudovia_regs[offset] = data; + break; + } + } + else + { + offset >>= 9; + + switch (offset) + { + case 1: // Port A + m_out_a_handler(data); + break; + + case 13: // IFR + if (data & 0x80) + { + data = 0x7f; + } + pseudovia_recalc_irqs(); + break; + + case 14: // IER + if (data & 0x80) // 1 bits write 1s + { + m_pseudovia_ier |= data & 0x7f; + } + else // 1 bits write 0s + { + m_pseudovia_ier &= ~(data & 0x7f); + } + pseudovia_recalc_irqs(); + break; + + default: + LOG("pseudovia_w: Unknown extended pseudo-VIA register %d access\n", offset); + break; + } + } +} diff --git a/src/mame/apple/pseudovia.h b/src/mame/apple/pseudovia.h new file mode 100644 index 00000000000..d31b90699b5 --- /dev/null +++ b/src/mame/apple/pseudovia.h @@ -0,0 +1,51 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont + +#ifndef MAME_APPLE_PSEUDOVIA_H +#define MAME_APPLE_PSEUDOVIA_H + +#pragma once + +class pseudovia_device : public device_t +{ +public: + pseudovia_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + // interface routines + auto readpa_handler() { return m_in_a_handler.bind(); } + auto readpb_handler() { return m_in_b_handler.bind(); } + auto readconfig_handler() { return m_in_config_handler.bind(); } + auto readvideo_handler() { return m_in_video_handler.bind(); } + auto writepa_handler() { return m_out_a_handler.bind(); } + auto writepb_handler() { return m_out_b_handler.bind(); } + auto writeconfig_handler() { return m_out_config_handler.bind(); } + auto writevideo_handler() { return m_out_video_handler.bind(); } + auto irq_callback() { return m_write_irq.bind(); } + + uint8_t read(offs_t offset); + void write(offs_t offset, uint8_t data); + + template void slot_irq_w(int state); + void vbl_irq_w(int state); + void scc_irq_w(int state); + void asc_irq_w(int state); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + +private: + devcb_write_line m_write_irq; + devcb_read8 m_in_a_handler, m_in_b_handler, m_in_config_handler, m_in_video_handler; + devcb_write8 m_out_a_handler, m_out_b_handler, m_out_config_handler, m_out_video_handler; + + uint8_t m_pseudovia_regs[256], m_pseudovia_ier, m_pseudovia_ifr; + + void pseudovia_recalc_irqs(); +}; + +// device type definition +DECLARE_DEVICE_TYPE(APPLE_PSEUDOVIA, pseudovia_device) + +#endif // MAME_APPLE_PSEUDOVIA_H diff --git a/src/mame/apple/rbv.cpp b/src/mame/apple/rbv.cpp index a6b53d52a4e..2eae80bac74 100644 --- a/src/mame/apple/rbv.cpp +++ b/src/mame/apple/rbv.cpp @@ -47,7 +47,7 @@ ioport_constructor rbv_device::device_input_ports() const void rbv_device::map(address_map &map) { map(0x00000000, 0x00000007).rw(FUNC(rbv_device::dac_r), FUNC(rbv_device::dac_w)).mirror(0x00f00000); - map(0x00002000, 0x00003fff).rw(FUNC(rbv_device::pseudovia_r), FUNC(rbv_device::pseudovia_w)).mirror(0x00f00000); + map(0x00002000, 0x00003fff).rw(m_pseudovia, FUNC(pseudovia_device::read), FUNC(pseudovia_device::write)).mirror(0x00f00000); } //------------------------------------------------- @@ -61,10 +61,15 @@ void rbv_device::device_add_mconfig(machine_config &config) m_screen->set_size(1024, 768); m_screen->set_visarea(0, 640 - 1, 0, 480 - 1); m_screen->set_screen_update(FUNC(rbv_device::screen_update)); - m_screen->screen_vblank().set(FUNC(rbv_device::slot_irq_w<0x40>)); + m_screen->screen_vblank().set(m_pseudovia, FUNC(pseudovia_device::slot_irq_w<0x40>)); config.set_default_layout(layout_monitors); PALETTE(config, m_palette).set_entries(256); + + APPLE_PSEUDOVIA(config, m_pseudovia, C15M); + m_pseudovia->readvideo_handler().set(FUNC(rbv_device::via2_video_config_r)); + m_pseudovia->writevideo_handler().set(FUNC(rbv_device::via2_video_config_w)); + m_pseudovia->irq_callback().set(FUNC(rbv_device::via2_irq_w)); } //------------------------------------------------- @@ -77,7 +82,8 @@ rbv_device::rbv_device(const machine_config &mconfig, const char *tag, device_t write_irq(*this), m_montype(*this, "MONTYPE"), m_screen(*this, "screen"), - m_palette(*this, "palette") + m_palette(*this, "palette"), + m_pseudovia(*this, "pseudovia") { } @@ -90,13 +96,9 @@ void rbv_device::device_start() m_6015_timer = timer_alloc(FUNC(rbv_device::mac_6015_tick), this); m_6015_timer->adjust(attotime::never); - save_item(NAME(m_pseudovia_regs)); - save_item(NAME(m_pseudovia_ier)); - save_item(NAME(m_pseudovia_ifr)); save_item(NAME(m_pal_address)); save_item(NAME(m_pal_idx)); - m_pseudovia_ier = m_pseudovia_ifr = 0; m_pal_address = m_pal_idx = 0; } @@ -108,16 +110,6 @@ void rbv_device::device_reset() { // start 60.15 Hz timer m_6015_timer->adjust(attotime::from_hz(60.15), 0, attotime::from_hz(60.15)); - - std::fill_n(m_pseudovia_regs, 256, 0); - m_pseudovia_regs[0] = 0x4f; - m_pseudovia_regs[1] = 0x06; - m_pseudovia_regs[2] = 0x7f; - m_pseudovia_regs[3] = 0; - m_pseudovia_ier = 0; - m_pseudovia_ifr = 0; - - m_pseudovia_regs[0x10] = 0x40; // video off } void rbv_device::set_ram_info(u32 *ram, u32 size) @@ -135,16 +127,7 @@ TIMER_CALLBACK_MEMBER(rbv_device::mac_6015_tick) template void rbv_device::slot_irq_w(int state) { - if (state) - { - m_pseudovia_regs[2] &= ~mask; - } - else - { - m_pseudovia_regs[2] |= mask; - } - - pseudovia_recalc_irqs(); + m_pseudovia->slot_irq_w(state); } template void rbv_device::slot_irq_w<0x40>(int state); @@ -157,16 +140,7 @@ template void rbv_device::slot_irq_w<0x01>(int state); void rbv_device::asc_irq_w(int state) { - if (state == ASSERT_LINE) - { - m_pseudovia_regs[3] |= 0x10; // any VIA 2 interrupt | sound interrupt - pseudovia_recalc_irqs(); - } - else - { - m_pseudovia_regs[3] &= ~0x10; - pseudovia_recalc_irqs(); - } + m_pseudovia->asc_irq_w(state); } void rbv_device::pseudovia_recalc_irqs() @@ -199,6 +173,21 @@ void rbv_device::pseudovia_recalc_irqs() } } +u8 rbv_device::via2_video_config_r() +{ + return m_montype->read() << 3; +} + +void rbv_device::via2_video_config_w(u8 data) +{ + m_video_config = data; +} + +void rbv_device::via2_irq_w(int state) +{ + write_irq(state); +} + uint8_t rbv_device::pseudovia_r(offs_t offset) { int data = 0; @@ -403,7 +392,7 @@ u32 rbv_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const } // video disabled? - if (m_pseudovia_regs[0x10] & 0x40) + if (m_video_config & 0x40) { bitmap.fill(0, cliprect); return 0; @@ -411,7 +400,7 @@ u32 rbv_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const const pen_t *pens = m_palette->pens(); - switch (m_pseudovia_regs[0x10] & 7) + switch (m_video_config & 7) { case 0: // 1bpp { diff --git a/src/mame/apple/rbv.h b/src/mame/apple/rbv.h index 91c311aaf46..f3ede511913 100644 --- a/src/mame/apple/rbv.h +++ b/src/mame/apple/rbv.h @@ -6,6 +6,8 @@ #pragma once +#include "pseudovia.h" + #include "emupal.h" #include "screen.h" @@ -45,17 +47,23 @@ private: required_ioport m_montype; required_device m_screen; required_device m_palette; + required_device m_pseudovia; emu_timer *m_6015_timer; u8 m_pseudovia_regs[256], m_pseudovia_ier, m_pseudovia_ifr; u8 m_pal_address, m_pal_idx; u32 *m_ram_ptr; u32 m_ram_size; + u8 m_video_config; uint8_t pseudovia_r(offs_t offset); void pseudovia_w(offs_t offset, uint8_t data); void pseudovia_recalc_irqs(); + u8 via2_video_config_r(); + void via2_video_config_w(u8 data); + void via2_irq_w(int state); + TIMER_CALLBACK_MEMBER(mac_6015_tick); u8 dac_r(offs_t offset); diff --git a/src/mame/apple/sonora.cpp b/src/mame/apple/sonora.cpp index 961ba4841d7..581bef5abb2 100644 --- a/src/mame/apple/sonora.cpp +++ b/src/mame/apple/sonora.cpp @@ -53,7 +53,7 @@ void sonora_device::map(address_map &map) map(0x10000000, 0x10001fff).rw(FUNC(sonora_device::mac_via_r), FUNC(sonora_device::mac_via_w)).mirror(0x00fc0000); map(0x10014000, 0x10015fff).rw(m_asc, FUNC(asc_device::read), FUNC(asc_device::write)).mirror(0x00f00000); map(0x10016000, 0x10017fff).rw(FUNC(sonora_device::swim_r), FUNC(sonora_device::swim_w)).mirror(0x00f00000); - map(0x10026000, 0x10027fff).rw(FUNC(sonora_device::pseudovia_r), FUNC(sonora_device::pseudovia_w)).mirror(0x00f00000); + map(0x10026000, 0x10027fff).rw(m_pseudovia, FUNC(pseudovia_device::read), FUNC(pseudovia_device::write)).mirror(0x00f00000); map(0x10f24000, 0x10f24003).rw(m_video, FUNC(mac_video_sonora_device::dac_r), FUNC(mac_video_sonora_device::dac_w)); map(0x10f28000, 0x10f28007).rw(m_video, FUNC(mac_video_sonora_device::vctrl_r), FUNC(mac_video_sonora_device::vctrl_w)); @@ -67,7 +67,7 @@ void sonora_device::map(address_map &map) void sonora_device::device_add_mconfig(machine_config &config) { MAC_VIDEO_SONORA(config, m_video); - m_video->screen_vblank().set(FUNC(sonora_device::slot_irq_w<0x40>)); + m_video->screen_vblank().set(m_pseudovia, FUNC(pseudovia_device::slot_irq_w<0x40>)); R65NC22(config, m_via1, C7M / 10); m_via1->readpa_handler().set(FUNC(sonora_device::via_in_a)); @@ -77,11 +77,13 @@ void sonora_device::device_add_mconfig(machine_config &config) m_via1->cb2_handler().set(FUNC(sonora_device::via_out_cb2)); m_via1->irq_handler().set(FUNC(sonora_device::via1_irq)); + APPLE_PSEUDOVIA(config, m_pseudovia, C15M); + m_pseudovia->irq_callback().set(FUNC(sonora_device::via2_irq)); ASC(config, m_asc, C15M, asc_device::asc_type::SONORA); m_asc->add_route(0, tag(), 1.0); m_asc->add_route(1, tag(), 1.0); - m_asc->irqf_callback().set(FUNC(sonora_device::asc_irq)); + m_asc->irqf_callback().set(m_pseudovia, FUNC(pseudovia_device::asc_irq_w)); SWIM2(config, m_fdc, C15M); m_fdc->devsel_cb().set(FUNC(sonora_device::devsel_w)); @@ -105,6 +107,7 @@ sonora_device::sonora_device(const machine_config &mconfig, const char *tag, dev m_maincpu(*this, finder_base::DUMMY_TAG), m_video(*this, "sonora_video"), m_via1(*this, "via1"), + m_pseudovia(*this, "pseudovia"), m_asc(*this, "asc"), m_fdc(*this, "fdc"), m_floppy(*this, "fdc:%d", 0U), @@ -133,15 +136,10 @@ void sonora_device::device_start() save_item(NAME(m_via2_interrupt)); save_item(NAME(m_scc_interrupt)); save_item(NAME(m_last_taken_interrupt)); - save_item(NAME(m_pseudovia_regs)); - save_item(NAME(m_pseudovia_ier)); - save_item(NAME(m_pseudovia_ifr)); save_item(NAME(m_hdsel)); m_rom_ptr = &m_rom[0]; m_rom_size = m_rom.length() << 2; - - m_pseudovia_ier = m_pseudovia_ifr = 0; } //------------------------------------------------- @@ -157,8 +155,6 @@ void sonora_device::device_reset() // start 60.15 Hz timer m_6015_timer->adjust(attotime::from_hz(60.15), 0, attotime::from_hz(60.15)); - std::fill_n(m_pseudovia_regs, 256, 0); - m_pseudovia_regs[2] = 0x7f; m_via_interrupt = m_via2_interrupt = m_scc_interrupt = 0; m_last_taken_interrupt = -1; m_hdsel = 0; @@ -298,205 +294,19 @@ void sonora_device::scc_irq_w(int state) field_interrupts(); } -template -void sonora_device::slot_irq_w(int state) +void sonora_device::slot0_irq_w(int state) { - if (state) - { - m_pseudovia_regs[2] &= ~mask; - } - else - { - m_pseudovia_regs[2] |= mask; - } - - pseudovia_recalc_irqs(); + m_pseudovia->slot_irq_w<0x08>(state); } -template void sonora_device::slot_irq_w<0x40>(int state); -template void sonora_device::slot_irq_w<0x20>(int state); -template void sonora_device::slot_irq_w<0x10>(int state); -template void sonora_device::slot_irq_w<0x08>(int state); -template void sonora_device::slot_irq_w<0x04>(int state); -template void sonora_device::slot_irq_w<0x02>(int state); -template void sonora_device::slot_irq_w<0x01>(int state); - -void sonora_device::asc_irq(int state) +void sonora_device::slot1_irq_w(int state) { - if (state == ASSERT_LINE) - { - m_pseudovia_regs[3] |= 0x10; // any VIA 2 interrupt | sound interrupt - pseudovia_recalc_irqs(); - } - else - { - m_pseudovia_regs[3] &= ~0x10; - pseudovia_recalc_irqs(); - } + m_pseudovia->slot_irq_w<0x10>(state); } -void sonora_device::pseudovia_recalc_irqs() +void sonora_device::slot2_irq_w(int state) { - // check slot interrupts and bubble them down to IFR - uint8_t slot_irqs = (~m_pseudovia_regs[2]) & 0x78; - slot_irqs &= (m_pseudovia_regs[0x12] & 0x78); - - if (slot_irqs) - { - m_pseudovia_regs[3] |= 2; // any slot - } - else // no slot irqs, clear the pending bit - { - m_pseudovia_regs[3] &= ~2; // any slot - } - - uint8_t ifr = (m_pseudovia_regs[3] & m_pseudovia_ier) & 0x1b; - - if (ifr != 0) - { - m_pseudovia_regs[3] = ifr | 0x80; - m_pseudovia_ifr = ifr | 0x80; - - via2_irq(ASSERT_LINE); - } - else - { - via2_irq(CLEAR_LINE); - } -} - -uint8_t sonora_device::pseudovia_r(offs_t offset) -{ - int data = 0; - - if (offset < 0x100) - { - data = m_pseudovia_regs[offset]; - - if (offset == 0x10) - { - data &= ~0x38; - } - - // bit 7 of these registers always reads as 0 on pseudo-VIAs - if ((offset == 0x12) || (offset == 0x13)) - { - data &= ~0x80; - } - } - else - { - offset >>= 9; - - switch (offset) - { - case 13: // IFR - data = m_pseudovia_ifr; - break; - - case 14: // IER - data = m_pseudovia_ier; - break; - - default: - logerror("pseudovia_r: Unknown pseudo-VIA register %d access\n", offset); - break; - } - } - return data; -} - -void sonora_device::pseudovia_w(offs_t offset, uint8_t data) -{ - if (offset < 0x100) - { - switch (offset) - { - case 0x02: - m_pseudovia_regs[offset] |= (data & 0x40); - pseudovia_recalc_irqs(); - break; - - case 0x03: // write here to ack - if (data & 0x80) // 1 bits write 1s - { - m_pseudovia_regs[offset] |= data & 0x7f; - m_pseudovia_ifr |= data & 0x7f; - } - else // 1 bits write 0s - { - m_pseudovia_regs[offset] &= ~(data & 0x7f); - m_pseudovia_ifr &= ~(data & 0x7f); - } - pseudovia_recalc_irqs(); - break; - - case 0x10: - m_pseudovia_regs[offset] = data; - break; - - case 0x12: - if (data & 0x80) // 1 bits write 1s - { - m_pseudovia_regs[offset] |= data & 0x7f; - } - else // 1 bits write 0s - { - m_pseudovia_regs[offset] &= ~(data & 0x7f); - } - pseudovia_recalc_irqs(); - break; - - case 0x13: - if (data & 0x80) // 1 bits write 1s - { - m_pseudovia_regs[offset] |= data & 0x7f; - - if (data == 0xff) - m_pseudovia_regs[offset] = 0x1f; // I don't know why this is special, but the IIci ROM's POST demands it - } - else // 1 bits write 0s - { - m_pseudovia_regs[offset] &= ~(data & 0x7f); - } - break; - - default: - m_pseudovia_regs[offset] = data; - break; - } - } - else - { - offset >>= 9; - - switch (offset) - { - case 13: // IFR - if (data & 0x80) - { - data = 0x7f; - } - pseudovia_recalc_irqs(); - break; - - case 14: // IER - if (data & 0x80) // 1 bits write 1s - { - m_pseudovia_ier |= data & 0x7f; - } - else // 1 bits write 0s - { - m_pseudovia_ier &= ~(data & 0x7f); - } - pseudovia_recalc_irqs(); - break; - - default: - logerror("pseudovia_w: Unknown extended pseudo-VIA register %d access\n", offset); - break; - } - } + m_pseudovia->slot_irq_w<0x20>(state); } void sonora_device::cb1_w(int state) diff --git a/src/mame/apple/sonora.h b/src/mame/apple/sonora.h index b55d05a049e..b6ee52517cd 100644 --- a/src/mame/apple/sonora.h +++ b/src/mame/apple/sonora.h @@ -6,6 +6,8 @@ #pragma once +#include "pseudovia.h" + #include "machine/6522via.h" #include "machine/applefdintf.h" #include "machine/mv_sonora.h" @@ -40,8 +42,10 @@ public: void cb1_w(int state); void cb2_w(int state); - template void slot_irq_w(int state); void scc_irq_w(int state); + void slot0_irq_w(int state); + void slot1_irq_w(int state); + void slot2_irq_w(int state); void pixel_clock_w(u32 pclk) { m_video->set_pixel_clock(pclk); } @@ -60,6 +64,7 @@ private: required_device m_maincpu; required_device m_video; required_device m_via1; + required_device m_pseudovia; required_device m_asc; required_device m_fdc; required_device_array m_floppy; @@ -69,7 +74,6 @@ private: sound_stream *m_stream; emu_timer *m_6015_timer; int m_via_interrupt, m_via2_interrupt, m_scc_interrupt, m_last_taken_interrupt; - uint8_t m_pseudovia_regs[256], m_pseudovia_ier, m_pseudovia_ifr; floppy_image_device *m_cur_floppy = nullptr; int m_hdsel; bool m_overlay; @@ -78,10 +82,6 @@ private: u32 rom_switch_r(offs_t offset); - uint8_t pseudovia_r(offs_t offset); - void pseudovia_w(offs_t offset, uint8_t data); - void pseudovia_recalc_irqs(); - uint16_t mac_via_r(offs_t offset); void mac_via_w(offs_t offset, uint16_t data, uint16_t mem_mask); @@ -94,7 +94,6 @@ private: void via_out_cb2(int state); void via1_irq(int state); void via2_irq(int state); - void asc_irq(int state); TIMER_CALLBACK_MEMBER(mac_6015_tick); void phases_w(uint8_t phases); diff --git a/src/mame/apple/v8.cpp b/src/mame/apple/v8.cpp index 1661828697b..e1a3798e8c9 100644 --- a/src/mame/apple/v8.cpp +++ b/src/mame/apple/v8.cpp @@ -87,7 +87,7 @@ void v8_device::map(address_map &map) map(0x500000, 0x501fff).rw(FUNC(v8_device::mac_via_r), FUNC(v8_device::mac_via_w)); map(0x514000, 0x515fff).rw(m_asc, FUNC(asc_device::read), FUNC(asc_device::write)); map(0x524000, 0x525fff).rw(FUNC(v8_device::dac_r), FUNC(v8_device::dac_w)); - map(0x526000, 0x527fff).rw(FUNC(v8_device::pseudovia_r), FUNC(v8_device::pseudovia_w)); + map(0x526000, 0x527fff).rw(m_pseudovia, FUNC(pseudovia_device::read), FUNC(pseudovia_device::write)); map(0x540000, 0x5bffff).rw(FUNC(v8_device::vram_r), FUNC(v8_device::vram_w)); } @@ -101,7 +101,7 @@ void v8_device::device_add_mconfig(machine_config &config) SCREEN(config, m_screen, SCREEN_TYPE_RASTER); m_screen->set_raw(25175000, 800, 0, 640, 525, 0, 480); m_screen->set_screen_update(FUNC(v8_device::screen_update)); - m_screen->screen_vblank().set(FUNC(v8_device::slot_irq_w<0x40>)); + m_screen->screen_vblank().set(m_pseudovia, FUNC(pseudovia_device::slot_irq_w<0x40>)); config.set_default_layout(layout_monitors); PALETTE(config, m_palette).set_entries(256); @@ -115,9 +115,17 @@ void v8_device::device_add_mconfig(machine_config &config) m_via1->irq_handler().set(FUNC(v8_device::via1_irq)); ASC(config, m_asc, C15M, asc_device::asc_type::V8); - m_asc->irqf_callback().set(FUNC(v8_device::asc_irq)); + m_asc->irqf_callback().set(m_pseudovia, FUNC(pseudovia_device::asc_irq_w)); m_asc->add_route(0, tag(), 1.0); m_asc->add_route(1, tag(), 1.0); + + APPLE_PSEUDOVIA(config, m_pseudovia, C15M); + m_pseudovia->writepb_handler().set(FUNC(v8_device::via2_pb_w)); + m_pseudovia->readconfig_handler().set(FUNC(v8_device::via2_config_r)); + m_pseudovia->writeconfig_handler().set(FUNC(v8_device::via2_config_w)); + m_pseudovia->readvideo_handler().set(FUNC(v8_device::via2_video_config_r)); + m_pseudovia->writevideo_handler().set(FUNC(v8_device::via2_video_config_w)); + m_pseudovia->irq_callback().set(FUNC(v8_device::via2_irq)); } //------------------------------------------------- @@ -136,7 +144,9 @@ v8_device::v8_device(const machine_config &mconfig, device_type type, const char m_screen(*this, "screen"), m_palette(*this, "palette"), m_asc(*this, "asc"), + m_pseudovia(*this, "pseudovia"), m_overlay(false), + m_video_config(0), write_pb4(*this), write_pb5(*this), write_cb2(*this), @@ -146,6 +156,7 @@ v8_device::v8_device(const machine_config &mconfig, device_type type, const char m_montype(*this, "MONTYPE"), m_via1(*this, "via1"), m_rom(*this, finder_base::DUMMY_TAG), + m_config(0), m_baseIs4M(false) { } @@ -168,16 +179,14 @@ void v8_device::device_start() save_item(NAME(m_via2_interrupt)); save_item(NAME(m_scc_interrupt)); save_item(NAME(m_last_taken_interrupt)); - save_item(NAME(m_pseudovia_regs)); - save_item(NAME(m_pseudovia_ier)); - save_item(NAME(m_pseudovia_ifr)); save_item(NAME(m_pal_address)); save_item(NAME(m_pal_idx)); save_item(NAME(m_pal_control)); save_item(NAME(m_pal_colkey)); + save_item(NAME(m_config)); + save_item(NAME(m_video_config)); save_item(NAME(m_overlay)); - m_pseudovia_ier = m_pseudovia_ifr = 0; m_pal_address = m_pal_idx = m_pal_control = m_pal_colkey = 0; } @@ -190,13 +199,6 @@ void v8_device::device_reset() // start 60.15 Hz timer m_6015_timer->adjust(attotime::from_hz(60.15), 0, attotime::from_hz(60.15)); - std::fill_n(m_pseudovia_regs, 256, 0); - m_pseudovia_regs[0] = 0x4f; - m_pseudovia_regs[1] = 0x06; - m_pseudovia_regs[2] = 0x7f; - m_pseudovia_regs[3] = 0; - m_pseudovia_ier = 0; - m_pseudovia_ifr = 0; m_via_interrupt = m_via2_interrupt = m_scc_interrupt = 0; m_last_taken_interrupt = -1; @@ -322,230 +324,35 @@ void v8_device::scc_irq_w(int state) field_interrupts(); } -template -void v8_device::slot_irq_w(int state) +void v8_device::slot2_irq_w(int state) { - if (state) - { - m_pseudovia_regs[2] &= ~mask; - } - else - { - m_pseudovia_regs[2] |= mask; - } - - pseudovia_recalc_irqs(); + m_pseudovia->slot_irq_w<0x20>(state); } -template void v8_device::slot_irq_w<0x40>(int state); -template void v8_device::slot_irq_w<0x20>(int state); -template void v8_device::slot_irq_w<0x10>(int state); -template void v8_device::slot_irq_w<0x08>(int state); -template void v8_device::slot_irq_w<0x04>(int state); -template void v8_device::slot_irq_w<0x02>(int state); -template void v8_device::slot_irq_w<0x01>(int state); - -void v8_device::asc_irq(int state) +u8 v8_device::via2_config_r() { - if (state == ASSERT_LINE) - { - m_pseudovia_regs[3] |= 0x10; // any VIA 2 interrupt | sound interrupt - pseudovia_recalc_irqs(); - } - else - { - m_pseudovia_regs[3] &= ~0x10; - pseudovia_recalc_irqs(); - } + return m_config | 0x04; } -void v8_device::pseudovia_recalc_irqs() +void v8_device::via2_config_w(u8 data) { - // check slot interrupts and bubble them down to IFR - u8 slot_irqs = (~m_pseudovia_regs[2]) & 0x78; - slot_irqs &= (m_pseudovia_regs[0x12] & 0x78); - - if (slot_irqs) - { - m_pseudovia_regs[3] |= 2; // any slot - } - else // no slot irqs, clear the pending bit - { - m_pseudovia_regs[3] &= ~2; // any slot - } - - u8 ifr = (m_pseudovia_regs[3] & m_pseudovia_ier) & 0x1b; - - if (ifr != 0) - { - m_pseudovia_regs[3] = ifr | 0x80; - m_pseudovia_ifr = ifr | 0x80; - - via2_irq(ASSERT_LINE); - } - else - { - via2_irq(CLEAR_LINE); - } + m_config = data; + ram_size(data); } -u8 v8_device::pseudovia_r(offs_t offset) +u8 v8_device::via2_video_config_r() { - int data = 0; - - if (offset < 0x100) - { - data = m_pseudovia_regs[offset]; - - if (offset == 0x10) - { - data &= ~0x38; - data |= (m_montype->read() << 3); - } - - // bit 7 of these registers always reads as 0 on pseudo-VIAs - if ((offset == 0x12) || (offset == 0x13)) - { - data &= ~0x80; - } - } - else - { - offset >>= 9; - - switch (offset) - { - case 13: // IFR - data = m_pseudovia_ifr; - break; - - case 14: // IER - data = m_pseudovia_ier; - break; - - default: - logerror("pseudovia_r: Unknown pseudo-VIA register %d access\n", offset); - break; - } - } - return data; + return m_montype->read() << 3; } -void v8_device::pseudovia_w(offs_t offset, u8 data) +void v8_device::via2_video_config_w(u8 data) { - if (offset < 0x100) - { - switch (offset) - { - case 0x00: // 24/32 bit switch in bit 3 (&8) - write_hmmu_enable(BIT(data, 3)); - break; + m_video_config = data; +} - /* V8 config: - bit 0 = Apple II mode (4bpp 560x384) (TODO) - bit 1 = 512Row - bit 2 = VRAM present - bits 3-4 = always read 0, can't write - bit 5 = bank B (motherboard soldered) size, 0 = 4MB, 1 = 2MB - bits 6-7 = bank A (SIMM) size, - 0 = 0MB - 1 = 2MB - 2 = 4MB - 3 = 8MB - */ - case 0x01: - if (m_pseudovia_regs[offset] != data) - { - ram_size(data); - } - m_pseudovia_regs[offset] = data | 0x04; // we always have VRAM - break; - - case 0x02: - m_pseudovia_regs[offset] |= (data & 0x40); - pseudovia_recalc_irqs(); - break; - - case 0x03: // write here to ack - if (data & 0x80) // 1 bits write 1s - { - m_pseudovia_regs[offset] |= data & 0x7f; - m_pseudovia_ifr |= data & 0x7f; - } - else // 1 bits write 0s - { - m_pseudovia_regs[offset] &= ~(data & 0x7f); - m_pseudovia_ifr &= ~(data & 0x7f); - } - pseudovia_recalc_irqs(); - break; - - case 0x10: - m_pseudovia_regs[offset] = data; - break; - - case 0x12: - if (data & 0x80) // 1 bits write 1s - { - m_pseudovia_regs[offset] |= data & 0x7f; - } - else // 1 bits write 0s - { - m_pseudovia_regs[offset] &= ~(data & 0x7f); - } - pseudovia_recalc_irqs(); - break; - - case 0x13: - if (data & 0x80) // 1 bits write 1s - { - m_pseudovia_regs[offset] |= data & 0x7f; - - if (data == 0xff) - m_pseudovia_regs[offset] = 0x1f; // I don't know why this is special, but the IIci ROM's POST demands it - } - else // 1 bits write 0s - { - m_pseudovia_regs[offset] &= ~(data & 0x7f); - } - break; - - default: - m_pseudovia_regs[offset] = data; - break; - } - } - else - { - offset >>= 9; - - switch (offset) - { - case 13: // IFR - if (data & 0x80) - { - data = 0x7f; - } - pseudovia_recalc_irqs(); - break; - - case 14: // IER - if (data & 0x80) // 1 bits write 1s - { - m_pseudovia_ier |= data & 0x7f; - } - else // 1 bits write 0s - { - m_pseudovia_ier &= ~(data & 0x7f); - } - pseudovia_recalc_irqs(); - break; - - default: - logerror("pseudovia_w: Unknown extended pseudo-VIA register %d access\n", offset); - break; - } - } +void v8_device::via2_pb_w(u8 data) +{ + write_hmmu_enable(BIT(data, 3)); } void v8_device::ram_size(u8 config) @@ -765,7 +572,7 @@ u32 v8_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const const pen_t *pens = m_palette->pens(); - switch (m_pseudovia_regs[0x10] & 7) + switch (m_video_config & 7) { case 0: // 1bpp { @@ -889,7 +696,9 @@ void eagle_device::device_add_mconfig(machine_config &config) ASC(config.replace(), m_asc, C15M, asc_device::asc_type::EAGLE); m_asc->add_route(0, tag(), 1.0); m_asc->add_route(1, tag(), 1.0); - m_asc->irqf_callback().set(FUNC(eagle_device::asc_irq)); + m_asc->irqf_callback().set(m_pseudovia, FUNC(pseudovia_device::asc_irq_w)); + + m_pseudovia->readvideo_handler().set(FUNC(eagle_device::via2_video_config_r)); } eagle_device::eagle_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) @@ -902,17 +711,9 @@ u8 eagle_device::via_in_a() return 0x93; } -u8 eagle_device::pseudovia_r(offs_t offset) +u8 eagle_device::via2_video_config_r() { - if (offset < 0x100) - { - if (offset == 0x10) - { - return 0; - } - } - - return v8_device::pseudovia_r(offset); + return 0; } u32 eagle_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) @@ -970,7 +771,7 @@ void spice_device::device_add_mconfig(machine_config &config) ASC(config.replace(), m_asc, C15M, asc_device::asc_type::SONORA); m_asc->add_route(0, tag(), 1.0); m_asc->add_route(1, tag(), 1.0); - m_asc->irqf_callback().set(FUNC(spice_device::asc_irq)); + m_asc->irqf_callback().set(m_pseudovia, FUNC(pseudovia_device::asc_irq_w)); SWIM2(config, m_fdc, C15M); m_fdc->devsel_cb().set(FUNC(spice_device::devsel_w)); @@ -978,6 +779,8 @@ void spice_device::device_add_mconfig(machine_config &config) applefdintf_device::add_35_hd(config, m_floppy[0]); applefdintf_device::add_35_nc(config, m_floppy[1]); + + m_pseudovia->readvideo_handler().set(FUNC(spice_device::via2_video_config_r)); } spice_device::spice_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) @@ -1006,17 +809,9 @@ u8 spice_device::via_in_a() return 0x83; } -u8 spice_device::pseudovia_r(offs_t offset) +u8 spice_device::via2_video_config_r() { - if (offset < 0x100) - { - if (offset == 0x10) - { - return 0x02<<3; - } - } - - return v8_device::pseudovia_r(offset); + return 0x02 << 3; } u32 spice_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) @@ -1026,7 +821,7 @@ u32 spice_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, con vres = 384; const pen_t *pens = m_palette->pens(); - switch (m_pseudovia_regs[0x10] & 7) + switch (m_video_config & 7) { case 0: // 1bpp { @@ -1191,6 +986,8 @@ void tinkerbell_device::device_add_mconfig(machine_config &config) { spice_device::device_add_mconfig(config); m_screen->set_raw(25175000, 800, 0, 640, 525, 0, 480); + + m_pseudovia->readvideo_handler().set(FUNC(tinkerbell_device::via2_video_config_r)); } tinkerbell_device::tinkerbell_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) @@ -1203,17 +1000,9 @@ u8 tinkerbell_device::via_in_a() return 0x84; } -u8 tinkerbell_device::pseudovia_r(offs_t offset) +u8 tinkerbell_device::via2_video_config_r() { - if (offset < 0x100) - { - if (offset == 0x10) - { - return 0x06 << 3; // ID as an Apple 13" 640x480 monitor - } - } - - return v8_device::pseudovia_r(offset); + return 0x06 << 3; // ID as an Apple 13" 640x480 monitor } u32 tinkerbell_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) @@ -1223,7 +1012,7 @@ u32 tinkerbell_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap vres = 480; const pen_t *pens = m_palette->pens(); - switch (m_pseudovia_regs[0x10] & 7) + switch (m_video_config & 7) { case 0: // 1bpp { diff --git a/src/mame/apple/v8.h b/src/mame/apple/v8.h index 2ad5d617cc7..153b1246b29 100644 --- a/src/mame/apple/v8.h +++ b/src/mame/apple/v8.h @@ -6,6 +6,8 @@ #pragma once +#include "pseudovia.h" + #include "machine/6522via.h" #include "machine/applefdintf.h" #include "machine/swim2.h" @@ -40,19 +42,21 @@ public: void cb2_w(int state); template void slot_irq_w(int state); void scc_irq_w(int state); + void slot2_irq_w(int state); protected: required_device m_maincpu; required_device m_screen; required_device m_palette; required_device m_asc; + required_device m_pseudovia; std::unique_ptr m_vram; - u8 m_pseudovia_regs[256]; u32 *m_ram_ptr; u32 m_ram_size; bool m_overlay; + u8 m_video_config; v8_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); @@ -64,10 +68,6 @@ protected: virtual void sound_stream_update(sound_stream &stream, std::vector const &inputs, std::vector &outputs) override; - virtual u8 pseudovia_r(offs_t offset); - - void asc_irq(int state); - virtual void ram_size(u8 config); private: @@ -81,15 +81,17 @@ private: sound_stream *m_stream; emu_timer *m_6015_timer; int m_via_interrupt, m_via2_interrupt, m_scc_interrupt, m_last_taken_interrupt; - u8 m_pseudovia_ier, m_pseudovia_ifr; - u8 m_pal_address, m_pal_idx, m_pal_control, m_pal_colkey; + u8 m_pal_address, m_pal_idx, m_pal_control, m_pal_colkey, m_config; bool m_baseIs4M; u32 rom_switch_r(offs_t offset); - void pseudovia_w(offs_t offset, u8 data); - void pseudovia_recalc_irqs(); + void via2_pb_w(u8 data); + u8 via2_config_r(); + void via2_config_w(u8 data); + u8 via2_video_config_r(); + void via2_video_config_w(u8 data); u16 mac_via_r(offs_t offset); void mac_via_w(offs_t offset, u16 data, u16 mem_mask); @@ -126,7 +128,7 @@ protected: private: u8 via_in_a() override; - u8 pseudovia_r(offs_t offset) override; + u8 via2_video_config_r(); virtual u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) override; }; @@ -158,7 +160,7 @@ private: virtual u8 via_in_a() override; virtual void via_out_a(u8 data) override; - virtual u8 pseudovia_r(offs_t offset) override; + u8 via2_video_config_r(); virtual u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) override; u16 swim_r(offs_t offset, u16 mem_mask); @@ -181,7 +183,7 @@ protected: private: virtual u8 via_in_a() override; - virtual u8 pseudovia_r(offs_t offset) override; + u8 via2_video_config_r(); virtual u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) override; }; diff --git a/src/mame/apple/vasp.cpp b/src/mame/apple/vasp.cpp index 23ff2add9bf..b7277387123 100644 --- a/src/mame/apple/vasp.cpp +++ b/src/mame/apple/vasp.cpp @@ -56,7 +56,7 @@ void vasp_device::map(address_map &map) map(0x10000000, 0x10001fff).rw(FUNC(vasp_device::mac_via_r), FUNC(vasp_device::mac_via_w)).mirror(0x00f00000); map(0x10014000, 0x10015fff).rw(m_asc, FUNC(asc_device::read), FUNC(asc_device::write)).mirror(0x00f00000); map(0x10024000, 0x10025fff).rw(FUNC(vasp_device::dac_r), FUNC(vasp_device::dac_w)).mirror(0x00f00000); - map(0x10026000, 0x10027fff).rw(FUNC(vasp_device::pseudovia_r), FUNC(vasp_device::pseudovia_w)).mirror(0x00f00000); + map(0x10026000, 0x10027fff).rw(m_pseudovia, FUNC(pseudovia_device::read), FUNC(pseudovia_device::write)).mirror(0x00f00000); map(0x20000000, 0x200fffff).ram().mirror(0x0ff00000).rw(FUNC(vasp_device::vram_r), FUNC(vasp_device::vram_w)); } @@ -72,7 +72,7 @@ void vasp_device::device_add_mconfig(machine_config &config) m_screen->set_size(1024, 768); m_screen->set_visarea(0, 640 - 1, 0, 480 - 1); m_screen->set_screen_update(FUNC(vasp_device::screen_update)); - m_screen->screen_vblank().set(FUNC(vasp_device::vbl_w)); + m_screen->screen_vblank().set(m_pseudovia, FUNC(pseudovia_device::vbl_irq_w)); config.set_default_layout(layout_monitors); PALETTE(config, m_palette).set_entries(256); @@ -85,10 +85,15 @@ void vasp_device::device_add_mconfig(machine_config &config) m_via1->cb2_handler().set(FUNC(vasp_device::via_out_cb2)); m_via1->irq_handler().set(FUNC(vasp_device::via1_irq)); + APPLE_PSEUDOVIA(config, m_pseudovia, C15M); + m_pseudovia->readvideo_handler().set(FUNC(vasp_device::via2_video_config_r)); + m_pseudovia->writevideo_handler().set(FUNC(vasp_device::via2_video_config_w)); + m_pseudovia->irq_callback().set(FUNC(vasp_device::via2_irq)); + ASC(config, m_asc, C15M, asc_device::asc_type::VASP); m_asc->add_route(0, tag(), 1.0); m_asc->add_route(1, tag(), 1.0); - m_asc->irqf_callback().set(FUNC(vasp_device::asc_irq)); + m_asc->irqf_callback().set(m_pseudovia, FUNC(pseudovia_device::asc_irq_w)); } //------------------------------------------------- @@ -108,9 +113,11 @@ vasp_device::vasp_device(const machine_config &mconfig, const char *tag, device_ m_screen(*this, "screen"), m_palette(*this, "palette"), m_via1(*this, "via1"), + m_pseudovia(*this, "pseudovia"), m_asc(*this, "asc"), m_rom(*this, finder_base::DUMMY_TAG), - m_overlay(false) + m_overlay(false), + m_video_config(0) { } @@ -132,19 +139,16 @@ void vasp_device::device_start() save_item(NAME(m_via2_interrupt)); save_item(NAME(m_scc_interrupt)); save_item(NAME(m_last_taken_interrupt)); - save_item(NAME(m_pseudovia_regs)); - save_item(NAME(m_pseudovia_ier)); - save_item(NAME(m_pseudovia_ifr)); save_item(NAME(m_pal_address)); save_item(NAME(m_pal_idx)); save_item(NAME(m_pal_control)); save_item(NAME(m_pal_colkey)); save_item(NAME(m_overlay)); + save_item(NAME(m_video_config)); m_rom_ptr = &m_rom[0]; m_rom_size = m_rom.length() << 2; - m_pseudovia_ier = m_pseudovia_ifr = 0; m_pal_address = m_pal_idx = m_pal_control = m_pal_colkey = 0; } @@ -157,13 +161,6 @@ void vasp_device::device_reset() // start 60.15 Hz timer m_6015_timer->adjust(attotime::from_hz(60.15), 0, attotime::from_hz(60.15)); - std::fill_n(m_pseudovia_regs, 256, 0); - m_pseudovia_regs[0] = 0x4f; - m_pseudovia_regs[1] = 0x06; - m_pseudovia_regs[2] = 0x7f; - m_pseudovia_regs[3] = 0; - m_pseudovia_ier = 0; - m_pseudovia_ifr = 0; m_via_interrupt = m_via2_interrupt = m_scc_interrupt = 0; m_last_taken_interrupt = -1; @@ -294,240 +291,29 @@ void vasp_device::scc_irq_w(int state) field_interrupts(); } -void vasp_device::vbl_w(int state) -{ - if (!state) - { - return; - } - - m_pseudovia_regs[2] &= ~0x40; // set vblank signal - - if (m_pseudovia_regs[0x12] & 0x40) - { - pseudovia_recalc_irqs(); - } -} - void vasp_device::slot0_irq_w(int state) { - if (state) - { - m_pseudovia_regs[2] &= ~0x08; - } - else - { - m_pseudovia_regs[2] |= 0x08; - } - - pseudovia_recalc_irqs(); + m_pseudovia->slot_irq_w<0x08>(state); } void vasp_device::slot1_irq_w(int state) { - if (state) - { - m_pseudovia_regs[2] &= ~0x10; - } - else - { - m_pseudovia_regs[2] |= 0x10; - } - - pseudovia_recalc_irqs(); + m_pseudovia->slot_irq_w<0x10>(state); } void vasp_device::slot2_irq_w(int state) { - if (state) - { - m_pseudovia_regs[2] &= ~0x20; - } - else - { - m_pseudovia_regs[2] |= 0x20; - } - - pseudovia_recalc_irqs(); + m_pseudovia->slot_irq_w<0x20>(state); } -void vasp_device::asc_irq(int state) +u8 vasp_device::via2_video_config_r() { - if (state == ASSERT_LINE) - { - m_pseudovia_regs[3] |= 0x10; // any VIA 2 interrupt | sound interrupt - pseudovia_recalc_irqs(); - } - else - { - m_pseudovia_regs[3] &= ~0x10; - pseudovia_recalc_irqs(); - } + return m_montype->read() << 3; } -void vasp_device::pseudovia_recalc_irqs() +void vasp_device::via2_video_config_w(u8 data) { - // check slot interrupts and bubble them down to IFR - uint8_t slot_irqs = (~m_pseudovia_regs[2]) & 0x78; - slot_irqs &= (m_pseudovia_regs[0x12] & 0x78); - - if (slot_irqs) - { - m_pseudovia_regs[3] |= 2; // any slot - } - else // no slot irqs, clear the pending bit - { - m_pseudovia_regs[3] &= ~2; // any slot - } - - uint8_t ifr = (m_pseudovia_regs[3] & m_pseudovia_ier) & 0x1b; - - if (ifr != 0) - { - m_pseudovia_regs[3] = ifr | 0x80; - m_pseudovia_ifr = ifr | 0x80; - - via2_irq(ASSERT_LINE); - } - else - { - via2_irq(CLEAR_LINE); - } -} - -uint8_t vasp_device::pseudovia_r(offs_t offset) -{ - int data = 0; - - if (offset < 0x100) - { - data = m_pseudovia_regs[offset]; - - if (offset == 0x10) - { - data &= ~0x38; - data |= (m_montype->read() << 3); - } - - // bit 7 of these registers always reads as 0 on pseudo-VIAs - if ((offset == 0x12) || (offset == 0x13)) - { - data &= ~0x80; - } - } - else - { - offset >>= 9; - - switch (offset) - { - case 13: // IFR - data = m_pseudovia_ifr; - break; - - case 14: // IER - data = m_pseudovia_ier; - break; - - default: - logerror("pseudovia_r: Unknown pseudo-VIA register %d access\n", offset); - break; - } - } - return data; -} - -void vasp_device::pseudovia_w(offs_t offset, uint8_t data) -{ - if (offset < 0x100) - { - switch (offset) - { - case 0x02: - m_pseudovia_regs[offset] |= (data & 0x40); - pseudovia_recalc_irqs(); - break; - - case 0x03: // write here to ack - if (data & 0x80) // 1 bits write 1s - { - m_pseudovia_regs[offset] |= data & 0x7f; - m_pseudovia_ifr |= data & 0x7f; - } - else // 1 bits write 0s - { - m_pseudovia_regs[offset] &= ~(data & 0x7f); - m_pseudovia_ifr &= ~(data & 0x7f); - } - pseudovia_recalc_irqs(); - break; - - case 0x10: - m_pseudovia_regs[offset] = data; - break; - - case 0x12: - if (data & 0x80) // 1 bits write 1s - { - m_pseudovia_regs[offset] |= data & 0x7f; - } - else // 1 bits write 0s - { - m_pseudovia_regs[offset] &= ~(data & 0x7f); - } - pseudovia_recalc_irqs(); - break; - - case 0x13: - if (data & 0x80) // 1 bits write 1s - { - m_pseudovia_regs[offset] |= data & 0x7f; - - if (data == 0xff) - m_pseudovia_regs[offset] = 0x1f; // I don't know why this is special, but the IIci ROM's POST demands it - } - else // 1 bits write 0s - { - m_pseudovia_regs[offset] &= ~(data & 0x7f); - } - break; - - default: - m_pseudovia_regs[offset] = data; - break; - } - } - else - { - offset >>= 9; - - switch (offset) - { - case 13: // IFR - if (data & 0x80) - { - data = 0x7f; - } - pseudovia_recalc_irqs(); - break; - - case 14: // IER - if (data & 0x80) // 1 bits write 1s - { - m_pseudovia_ier |= data & 0x7f; - } - else // 1 bits write 0s - { - m_pseudovia_ier &= ~(data & 0x7f); - } - pseudovia_recalc_irqs(); - break; - - default: - logerror("pseudovia_w: Unknown extended pseudo-VIA register %d access\n", offset); - break; - } - } + m_video_config = data; } void vasp_device::cb1_w(int state) @@ -677,7 +463,7 @@ u32 vasp_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, cons const pen_t *pens = m_palette->pens(); - switch (m_pseudovia_regs[0x10] & 7) + switch (m_video_config & 7) { case 0: // 1bpp { diff --git a/src/mame/apple/vasp.h b/src/mame/apple/vasp.h index a079be8a47a..5341af968cf 100644 --- a/src/mame/apple/vasp.h +++ b/src/mame/apple/vasp.h @@ -6,6 +6,8 @@ #pragma once +#include "pseudovia.h" + #include "machine/6522via.h" #include "sound/asc.h" #include "emupal.h" @@ -40,7 +42,6 @@ public: void cb1_w(int state); void cb2_w(int state); - void vbl_w(int state); void scc_irq_w(int state); void slot0_irq_w(int state); void slot1_irq_w(int state); @@ -64,6 +65,7 @@ private: required_device m_screen; required_device m_palette; required_device m_via1; + required_device m_pseudovia; required_device m_asc; required_region_ptr m_rom; @@ -71,17 +73,16 @@ private: sound_stream *m_stream; emu_timer *m_6015_timer; int m_via_interrupt, m_via2_interrupt, m_scc_interrupt, m_last_taken_interrupt; - u8 m_pseudovia_regs[256], m_pseudovia_ier, m_pseudovia_ifr; u8 m_pal_address, m_pal_idx, m_pal_control, m_pal_colkey; bool m_overlay; u32 *m_ram_ptr, *m_rom_ptr; u32 m_ram_size, m_rom_size; + u8 m_video_config; u32 rom_switch_r(offs_t offset); - uint8_t pseudovia_r(offs_t offset); - void pseudovia_w(offs_t offset, uint8_t data); - void pseudovia_recalc_irqs(); + u8 via2_video_config_r(); + void via2_video_config_w(u8 data); uint16_t mac_via_r(offs_t offset); void mac_via_w(offs_t offset, uint16_t data, uint16_t mem_mask);