mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +03:00
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.
This commit is contained in:
parent
e2965b559c
commit
94cdc63a80
@ -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<z80scc_device> m_scc;
|
||||
optional_device<rtc3430042_device> m_rtc;
|
||||
optional_device<egret_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)
|
||||
|
@ -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<mac_scsi_helper_device> m_scsihelp;
|
||||
required_device<z80scc_device> m_scc;
|
||||
required_device<egret_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)
|
||||
|
@ -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<z80scc_device> m_scc;
|
||||
optional_device<egret_device> m_egret;
|
||||
optional_device<cuda_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)
|
||||
|
@ -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<z80scc_device> m_scc;
|
||||
optional_device<egret_device> m_egret;
|
||||
optional_device<cuda_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");
|
||||
|
300
src/mame/apple/pseudovia.cpp
Normal file
300
src/mame/apple/pseudovia.cpp
Normal file
@ -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 <u8 mask>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
51
src/mame/apple/pseudovia.h
Normal file
51
src/mame/apple/pseudovia.h
Normal file
@ -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 <u8 mask> 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
|
@ -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 <u8 mask>
|
||||
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<mask>(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
|
||||
{
|
||||
|
@ -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<screen_device> m_screen;
|
||||
required_device<palette_device> m_palette;
|
||||
required_device<pseudovia_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);
|
||||
|
@ -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 <u8 mask>
|
||||
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)
|
||||
|
@ -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 <u8 mask> 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<cpu_device> m_maincpu;
|
||||
required_device<mac_video_sonora_device> m_video;
|
||||
required_device<via6522_device> m_via1;
|
||||
required_device<pseudovia_device> m_pseudovia;
|
||||
required_device<asc_device> m_asc;
|
||||
required_device<applefdintf_device> m_fdc;
|
||||
required_device_array<floppy_connector, 2> 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);
|
||||
|
@ -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 <u8 mask>
|
||||
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
|
||||
{
|
||||
|
@ -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 <u8 mask> void slot_irq_w(int state);
|
||||
void scc_irq_w(int state);
|
||||
void slot2_irq_w(int state);
|
||||
|
||||
protected:
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<palette_device> m_palette;
|
||||
required_device<asc_device> m_asc;
|
||||
required_device<pseudovia_device> m_pseudovia;
|
||||
|
||||
std::unique_ptr<u32 []> 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<read_stream_view> const &inputs, std::vector<write_stream_view> &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;
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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<screen_device> m_screen;
|
||||
required_device<palette_device> m_palette;
|
||||
required_device<via6522_device> m_via1;
|
||||
required_device<pseudovia_device> m_pseudovia;
|
||||
required_device<asc_device> m_asc;
|
||||
required_region_ptr<u32> 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);
|
||||
|
Loading…
Reference in New Issue
Block a user