mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +03:00
machine/applepic.cpp: Cleaned up IRQ handling, finished and tested DMA. [R. Belmont]
machine/swim1.cpp: Cleaned up DAT1BYTE output handling, added timer so the disk spins when you aren't polling it. [R. Belmont] machine/swim2.cpp: Cleaned up DAT1BYTE output handling. [R. Belmont] apple/dafb.cpp: Added support for the Quadra 950's standalone DAFB II with 16-bit color. [R. Belmont] apple/macadb.cpp: Major cleanup, removed ADB modem HLE, now echoes ADB line state changes so everyone stays in sync. [R. Belmont] apple/maciifx.cpp: Cleanup/modernization and corrected SWIM hookup for IOP control. Now can boot floppies. [R. Belmont] apple/macquadra700.cpp: Cleanup/modernization and added the Quadra 900 and 950. [R. Belmont] New WORKING machines -------------------- Macintosh Quadra 900 [R. Belmont] Macintosh Quadra 950 [R. Belmont]
This commit is contained in:
parent
ab2451cb8d
commit
a97c06e24c
@ -19,6 +19,18 @@ DEFINE_DEVICE_TYPE(APPLEPIC, applepic_device, "applepic", "Apple 343S1021 PIC")
|
||||
|
||||
const std::string_view applepic_device::s_interrupt_names[8] = { "0", "DMA 1", "DMA 2", "peripheral", "host", "timer", "6", "7" };
|
||||
|
||||
static constexpr int IRQ_DMA1 = 1;
|
||||
static constexpr int IRQ_DMA2 = 2;
|
||||
static constexpr int IRQ_PERIPHERAL = 3;
|
||||
static constexpr int IRQ_HOST = 4;
|
||||
static constexpr int IRQ_TIMER = 5;
|
||||
|
||||
static constexpr u8 DMAEN = 0x01; // 1 = channel enabled
|
||||
static constexpr u8 DREQ = 0x02; // 1 = DREQ line for this channel is active
|
||||
static constexpr u8 DMADIR = 0x04; // 1 = I/O to RAM, 0 = RAM to I/O
|
||||
static constexpr u8 DENxONx = 0x08; // 1 = enable this channel when the other channel completes a transfer
|
||||
static constexpr int DIOASHIFT = 0x04; // right shift amount for I/O offset bits
|
||||
|
||||
applepic_device::applepic_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: device_t(mconfig, APPLEPIC, tag, owner, clock)
|
||||
, m_iopcpu(*this, "iopcpu")
|
||||
@ -28,6 +40,7 @@ applepic_device::applepic_device(const machine_config &mconfig, const char *tag,
|
||||
, m_gpin_callback(*this, 0)
|
||||
, m_gpout_callback(*this)
|
||||
, m_timer1(nullptr)
|
||||
, m_dma_timer(nullptr)
|
||||
, m_timer_last_expired(attotime::zero)
|
||||
, m_ram_address(0)
|
||||
, m_status_reg(0x80)
|
||||
@ -43,6 +56,7 @@ applepic_device::applepic_device(const machine_config &mconfig, const char *tag,
|
||||
channel.control = 0;
|
||||
channel.map = 0;
|
||||
channel.tc = 0;
|
||||
channel.req = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,6 +87,9 @@ void applepic_device::device_start()
|
||||
// Initialize timer
|
||||
m_timer1 = timer_alloc(FUNC(applepic_device::timer1_callback), this);
|
||||
|
||||
// get a timer for the DMA
|
||||
m_dma_timer = timer_alloc(FUNC(applepic_device::dma_timer_callback), this);
|
||||
|
||||
// Save internal state
|
||||
save_item(NAME(m_timer_last_expired));
|
||||
save_item(NAME(m_ram_address));
|
||||
@ -96,6 +113,13 @@ void applepic_device::device_reset()
|
||||
m_iopcpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
|
||||
m_iopcpu->set_input_line(r65c02_device::IRQ_LINE, CLEAR_LINE);
|
||||
m_hint_callback(CLEAR_LINE);
|
||||
|
||||
for (dma_channel &channel : m_dma_channel)
|
||||
{
|
||||
channel.control = 0;
|
||||
}
|
||||
|
||||
m_dma_timer->adjust(attotime::zero, 0, clocks_to_attotime(8));
|
||||
}
|
||||
|
||||
u8 applepic_device::host_r(offs_t offset)
|
||||
@ -154,7 +178,7 @@ void applepic_device::host_w(offs_t offset, u8 data)
|
||||
m_iopcpu->set_input_line(INPUT_LINE_RESET, BIT(data, 2) ? CLEAR_LINE : ASSERT_LINE);
|
||||
}
|
||||
if (BIT(data, 3))
|
||||
set_interrupt(4);
|
||||
set_interrupt(IRQ_HOST);
|
||||
if ((m_status_reg & data & 0x30) != 0)
|
||||
{
|
||||
m_status_reg &= ~(data & 0x30);
|
||||
@ -178,30 +202,40 @@ void applepic_device::pint_w(int state)
|
||||
{
|
||||
m_status_reg |= 0x40;
|
||||
if (!BIT(m_scc_control, 0))
|
||||
set_interrupt(3);
|
||||
set_interrupt(IRQ_PERIPHERAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_status_reg &= 0xbf;
|
||||
if (!BIT(m_scc_control, 0))
|
||||
reset_interrupt(3);
|
||||
reset_interrupt(IRQ_PERIPHERAL);
|
||||
}
|
||||
}
|
||||
|
||||
void applepic_device::reqa_w(int state)
|
||||
{
|
||||
if (state == ASSERT_LINE)
|
||||
m_dma_channel[0].control |= 0x02;
|
||||
m_dma_channel[0].req = state;
|
||||
if (state)
|
||||
{
|
||||
m_dma_channel[0].control |= DREQ;
|
||||
}
|
||||
else
|
||||
m_dma_channel[0].control &= 0xfd;
|
||||
{
|
||||
m_dma_channel[0].control &= ~DREQ;
|
||||
}
|
||||
}
|
||||
|
||||
void applepic_device::reqb_w(int state)
|
||||
{
|
||||
if (state == ASSERT_LINE)
|
||||
m_dma_channel[1].control |= 0x02;
|
||||
m_dma_channel[1].req = state;
|
||||
if (state)
|
||||
{
|
||||
m_dma_channel[1].control |= DREQ;
|
||||
}
|
||||
else
|
||||
m_dma_channel[1].control &= 0xfd;
|
||||
{
|
||||
m_dma_channel[1].control &= ~DREQ;
|
||||
}
|
||||
}
|
||||
|
||||
u8 applepic_device::timer_r(offs_t offset)
|
||||
@ -212,7 +246,7 @@ u8 applepic_device::timer_r(offs_t offset)
|
||||
else
|
||||
{
|
||||
if (offset == 0 && !machine().side_effects_disabled())
|
||||
reset_interrupt(5);
|
||||
reset_interrupt(IRQ_TIMER);
|
||||
return reg & 0x00ff;
|
||||
}
|
||||
}
|
||||
@ -224,7 +258,7 @@ void applepic_device::timer_w(offs_t offset, u8 data)
|
||||
m_timer_latch = u16(data) << 8 | (m_timer_latch & 0x00ff);
|
||||
if (offset == 1)
|
||||
{
|
||||
reset_interrupt(5);
|
||||
reset_interrupt(IRQ_TIMER);
|
||||
m_timer1->adjust(clocks_to_attotime(m_timer_latch * 8 + 12));
|
||||
}
|
||||
}
|
||||
@ -242,7 +276,7 @@ u16 applepic_device::get_timer_count() const
|
||||
|
||||
TIMER_CALLBACK_MEMBER(applepic_device::timer1_callback)
|
||||
{
|
||||
set_interrupt(5);
|
||||
set_interrupt(IRQ_TIMER);
|
||||
if (BIT(m_timer_dpll_control, 0))
|
||||
m_timer1->adjust(clocks_to_attotime((m_timer_latch + 2) * 8));
|
||||
else
|
||||
@ -284,7 +318,7 @@ void applepic_device::dma_channel_w(offs_t offset, u8 data)
|
||||
switch (offset & 7)
|
||||
{
|
||||
case 0:
|
||||
channel.control = (data & 0xfd) | (channel.control & 0x02);
|
||||
channel.control = ((data & ~DREQ) | (channel.control & DREQ));
|
||||
break;
|
||||
|
||||
case 1:
|
||||
@ -300,7 +334,7 @@ void applepic_device::dma_channel_w(offs_t offset, u8 data)
|
||||
break;
|
||||
|
||||
case 4:
|
||||
channel.tc = (data & 0x07) | (channel.tc & 0x0ff);
|
||||
channel.tc = ((data & 0x07) << 8) | (channel.tc & 0x0ff);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -309,6 +343,44 @@ void applepic_device::dma_channel_w(offs_t offset, u8 data)
|
||||
}
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(applepic_device::dma_timer_callback)
|
||||
{
|
||||
for (int ch = 0; ch < 2; ch++)
|
||||
{
|
||||
auto &channel = m_dma_channel[ch];
|
||||
auto other_channel = m_dma_channel[ch ^ 1];
|
||||
|
||||
if ((channel.control & DMAEN) && (channel.req) && (channel.tc > 0))
|
||||
{
|
||||
if (channel.control & DMADIR)
|
||||
{
|
||||
const u8 xfer = m_prd_callback(channel.control >> DIOASHIFT);
|
||||
m_iopcpu->space(AS_PROGRAM).write_byte(channel.map, xfer);
|
||||
}
|
||||
else
|
||||
{
|
||||
const u8 xfer = m_iopcpu->space(AS_PROGRAM).read_byte(channel.map);
|
||||
m_pwr_callback(channel.control >> DIOASHIFT, xfer);
|
||||
}
|
||||
|
||||
channel.map++;
|
||||
channel.tc--;
|
||||
|
||||
// if this channel completed, handle the DEN1ON2/DEN2ON1 alternating transfer bits and IRQ
|
||||
if (channel.tc == 0)
|
||||
{
|
||||
channel.control &= ~DMAEN;
|
||||
if (other_channel.control & DENxONx)
|
||||
{
|
||||
other_channel.control |= DMAEN;
|
||||
}
|
||||
|
||||
set_interrupt(IRQ_DMA1 + ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u8 applepic_device::scc_control_r()
|
||||
{
|
||||
return m_scc_control;
|
||||
@ -318,9 +390,9 @@ void applepic_device::scc_control_w(u8 data)
|
||||
{
|
||||
m_scc_control = data;
|
||||
if (!BIT(data, 0) && BIT(m_status_reg, 6))
|
||||
set_interrupt(3);
|
||||
set_interrupt(IRQ_PERIPHERAL);
|
||||
else
|
||||
reset_interrupt(3);
|
||||
reset_interrupt(IRQ_PERIPHERAL);
|
||||
m_gpout_callback[1](BIT(data, 7));
|
||||
}
|
||||
|
||||
|
@ -51,12 +51,14 @@ private:
|
||||
u8 control;
|
||||
u16 map;
|
||||
u16 tc;
|
||||
bool req;
|
||||
};
|
||||
|
||||
u8 timer_r(offs_t offset);
|
||||
void timer_w(offs_t offset, u8 data);
|
||||
u16 get_timer_count() const;
|
||||
TIMER_CALLBACK_MEMBER(timer1_callback);
|
||||
TIMER_CALLBACK_MEMBER(dma_timer_callback);
|
||||
u8 dma_channel_r(offs_t offset);
|
||||
void dma_channel_w(offs_t offset, u8 data);
|
||||
u8 scc_control_r();
|
||||
@ -89,7 +91,7 @@ private:
|
||||
devcb_write_line::array<2> m_gpout_callback;
|
||||
|
||||
// internal state
|
||||
emu_timer *m_timer1;
|
||||
emu_timer *m_timer1, *m_dma_timer;
|
||||
attotime m_timer_last_expired;
|
||||
u16 m_ram_address;
|
||||
u8 m_status_reg;
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include "emu.h"
|
||||
#include "swim1.h"
|
||||
|
||||
#define VERBOSE 0
|
||||
#define VERBOSE (0)
|
||||
#include "logmacro.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE(SWIM1, swim1_device, "swim1", "Apple SWIM1 (Sander/Wozniak Integrated Machine) version 1 floppy controller")
|
||||
@ -26,6 +26,8 @@ void swim1_device::device_start()
|
||||
applefdintf_device::device_start();
|
||||
|
||||
m_timer = timer_alloc(FUNC(swim1_device::update), this);
|
||||
m_sync_timer = timer_alloc(FUNC(swim1_device::ism_periodic_sync), this);
|
||||
|
||||
save_item(NAME(m_last_sync));
|
||||
save_item(NAME(m_flux_write_start));
|
||||
save_item(NAME(m_flux_write));
|
||||
@ -104,7 +106,7 @@ void swim1_device::device_reset()
|
||||
m_devsel_cb(0);
|
||||
m_sel35_cb(true);
|
||||
m_hdsel_cb(false);
|
||||
m_dat1byte_cb(0);
|
||||
m_dat1byte_cb(CLEAR_LINE);
|
||||
}
|
||||
|
||||
void swim1_device::set_floppy(floppy_image_device *floppy)
|
||||
@ -174,11 +176,11 @@ u8 swim1_device::ism_read(offs_t offset)
|
||||
{
|
||||
ism_sync();
|
||||
|
||||
// static const char *const names[] = {
|
||||
// "data", "mark", "crc", "param", "phases", "setup", "status", "handshake"
|
||||
// };
|
||||
static const char *const names[] = {
|
||||
"data", "mark", "crc", "param", "phases", "setup", "status", "handshake"
|
||||
};
|
||||
|
||||
// LOG("read ism %s\n", names[offset & 7]);
|
||||
LOG("read ism %s\n", names[offset & 7]);
|
||||
switch(offset & 7) {
|
||||
case 0x0: { // data
|
||||
u16 r = ism_fifo_pop();
|
||||
@ -227,9 +229,9 @@ u8 swim1_device::ism_read(offs_t offset)
|
||||
if(!(m_ism_fifo[m_ism_fifo_pos - 1] & M_CRC0))
|
||||
h |= 0x02;
|
||||
}
|
||||
// rddata on 4
|
||||
// rddata on 3
|
||||
if(!m_floppy || m_floppy->wpt_r())
|
||||
h |= 0x08;
|
||||
h |= 0x0c;
|
||||
if(m_ism_error)
|
||||
h |= 0x20;
|
||||
if(m_ism_mode & 0x10) {
|
||||
@ -249,7 +251,7 @@ u8 swim1_device::ism_read(offs_t offset)
|
||||
}
|
||||
|
||||
default:
|
||||
// logerror("read %s\n", names[offset & 7]);
|
||||
logerror("read %s\n", names[offset & 7]);
|
||||
break;
|
||||
}
|
||||
return 0xff;
|
||||
@ -315,8 +317,7 @@ void swim1_device::ism_write(offs_t offset, u8 data)
|
||||
m_ism_mode &= ~data;
|
||||
m_ism_param_idx = 0;
|
||||
ism_show_mode();
|
||||
if(data & 0x10)
|
||||
m_dat1byte_cb((m_ism_fifo_pos != 0) ? 1 : 0);
|
||||
ism_update_dat1byte();
|
||||
if(!(m_ism_mode & 0x40)) {
|
||||
LOG("switch to iwm\n");
|
||||
u8 ism_devsel = m_ism_mode & 0x80 ? (m_ism_mode >> 1) & 3 : 0;
|
||||
@ -328,8 +329,7 @@ void swim1_device::ism_write(offs_t offset, u8 data)
|
||||
case 0x7:
|
||||
m_ism_mode |= data;
|
||||
ism_show_mode();
|
||||
if(data & 0x10)
|
||||
m_dat1byte_cb((m_ism_fifo_pos != 2) ? 1 : 0);
|
||||
ism_update_dat1byte();
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -345,6 +345,13 @@ void swim1_device::ism_write(offs_t offset, u8 data)
|
||||
if((m_ism_mode ^ prev_mode) & 0x20)
|
||||
m_hdsel_cb((m_ism_mode >> 5) & 1);
|
||||
|
||||
if ((m_ism_mode ^ prev_mode) & 0x40) {
|
||||
if (m_ism_mode & 0x40)
|
||||
m_sync_timer->adjust(attotime::zero, 0, attotime::from_hz(clock()/16));
|
||||
else
|
||||
m_sync_timer->adjust(attotime::never);
|
||||
}
|
||||
|
||||
if((m_ism_mode & 0x18) == 0x18 && ((prev_mode & 0x18) != 0x18)) {
|
||||
// Entering write mode
|
||||
m_ism_current_bit = 0;
|
||||
@ -558,9 +565,12 @@ void swim1_device::iwm_control(int offset, u8 data)
|
||||
if(data & 0x40) {
|
||||
m_ism_mode |= 0x40;
|
||||
LOG("switch to ism\n");
|
||||
|
||||
u8 ism_devsel = m_ism_mode & 0x80 ? (m_ism_mode >> 1) & 3 : 0;
|
||||
if(ism_devsel != m_iwm_devsel)
|
||||
m_devsel_cb(ism_devsel);
|
||||
|
||||
m_sync_timer->adjust(attotime::zero, 0, attotime::from_hz(clock()/16));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -607,24 +617,18 @@ attotime swim1_device::cycles_to_time(u64 cycles) const
|
||||
void swim1_device::ism_fifo_clear()
|
||||
{
|
||||
m_ism_fifo_pos = 0;
|
||||
m_dat1byte_cb((m_ism_mode & 0x10) ? 1 : 0);
|
||||
ism_update_dat1byte();
|
||||
ism_crc_clear();
|
||||
}
|
||||
|
||||
bool swim1_device::ism_fifo_push(u16 data)
|
||||
{
|
||||
if(m_ism_fifo_pos == 2)
|
||||
{
|
||||
return true;
|
||||
m_ism_fifo[m_ism_fifo_pos ++] = data;
|
||||
if(m_ism_mode & 0x10) {
|
||||
// write
|
||||
if(m_ism_fifo_pos == 2)
|
||||
m_dat1byte_cb(0);
|
||||
} else {
|
||||
// read
|
||||
if(m_ism_fifo_pos == 1)
|
||||
m_dat1byte_cb(1);
|
||||
}
|
||||
m_ism_fifo[m_ism_fifo_pos ++] = data;
|
||||
ism_update_dat1byte();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -635,15 +639,7 @@ u16 swim1_device::ism_fifo_pop()
|
||||
u16 r = m_ism_fifo[0];
|
||||
m_ism_fifo[0] = m_ism_fifo[1];
|
||||
m_ism_fifo_pos --;
|
||||
if(m_ism_mode & 0x10) {
|
||||
// write
|
||||
if(m_ism_fifo_pos == 1)
|
||||
m_dat1byte_cb(1);
|
||||
} else {
|
||||
// read
|
||||
if(m_ism_fifo_pos == 0)
|
||||
m_dat1byte_cb(0);
|
||||
}
|
||||
ism_update_dat1byte();
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -861,6 +857,14 @@ void swim1_device::iwm_sync()
|
||||
}
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(swim1_device::ism_periodic_sync)
|
||||
{
|
||||
if (m_ism_mode & 0x40)
|
||||
{
|
||||
ism_sync();
|
||||
}
|
||||
}
|
||||
|
||||
void swim1_device::ism_sync()
|
||||
{
|
||||
u64 next_sync = time_to_cycles(machine().time());
|
||||
@ -1210,3 +1214,17 @@ void swim1_device::sync()
|
||||
else
|
||||
return iwm_sync();
|
||||
}
|
||||
|
||||
void swim1_device::ism_update_dat1byte()
|
||||
{
|
||||
if (m_ism_mode & 0x10)
|
||||
{
|
||||
// write: Does FIFO have room?
|
||||
m_dat1byte_cb((m_ism_fifo_pos < 2) ? ASSERT_LINE : CLEAR_LINE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// read: is FIFO not empty?
|
||||
m_dat1byte_cb((m_ism_fifo_pos > 0) ? ASSERT_LINE : CLEAR_LINE);
|
||||
}
|
||||
}
|
||||
|
@ -112,6 +112,9 @@ private:
|
||||
u8 m_iwm_to_ism_counter;
|
||||
u8 m_iwm_devsel;
|
||||
|
||||
emu_timer *m_sync_timer;
|
||||
TIMER_CALLBACK_MEMBER(ism_periodic_sync);
|
||||
|
||||
u64 time_to_cycles(const attotime &tm) const;
|
||||
attotime cycles_to_time(u64 cycles) const;
|
||||
void flush_write(u64 when = 0);
|
||||
@ -134,6 +137,7 @@ private:
|
||||
u8 ism_read(offs_t offset);
|
||||
void ism_write(offs_t offset, u8 data);
|
||||
void ism_sync();
|
||||
void ism_update_dat1byte();
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(SWIM1, swim1_device)
|
||||
|
@ -71,7 +71,7 @@ void swim2_device::device_reset()
|
||||
m_devsel_cb(0);
|
||||
m_sel35_cb(true);
|
||||
m_hdsel_cb(false);
|
||||
m_dat1byte_cb(0);
|
||||
m_dat1byte_cb(CLEAR_LINE);
|
||||
m_flux_write_start = 0;
|
||||
m_flux_write_count = 0;
|
||||
std::fill(m_flux_write.begin(), m_flux_write.end(), 0);
|
||||
@ -280,15 +280,13 @@ void swim2_device::write(offs_t offset, u8 data)
|
||||
m_mode |= 0x40;
|
||||
m_param_idx = 0;
|
||||
show_mode();
|
||||
if(data & 0x10)
|
||||
m_dat1byte_cb((m_fifo_pos != 0) ? 1 : 0);
|
||||
update_dat1byte();
|
||||
break;
|
||||
|
||||
case 7: // mode set
|
||||
m_mode |= data;
|
||||
show_mode();
|
||||
if(data & 0x10)
|
||||
m_dat1byte_cb((m_fifo_pos != 2) ? 1 : 0);
|
||||
update_dat1byte();
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -369,7 +367,7 @@ attotime swim2_device::cycles_to_time(u64 cycles) const
|
||||
void swim2_device::fifo_clear()
|
||||
{
|
||||
m_fifo_pos = 0;
|
||||
m_dat1byte_cb((m_mode & 0x10) ? 1 : 0);
|
||||
update_dat1byte();
|
||||
crc_clear();
|
||||
}
|
||||
|
||||
@ -378,15 +376,7 @@ bool swim2_device::fifo_push(u16 data)
|
||||
if(m_fifo_pos == 2)
|
||||
return true;
|
||||
m_fifo[m_fifo_pos ++] = data;
|
||||
if(m_mode & 0x10) {
|
||||
// write
|
||||
if(m_fifo_pos == 2)
|
||||
m_dat1byte_cb(0);
|
||||
} else {
|
||||
// read
|
||||
if(m_fifo_pos == 1)
|
||||
m_dat1byte_cb(1);
|
||||
}
|
||||
update_dat1byte();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -397,15 +387,7 @@ u16 swim2_device::fifo_pop()
|
||||
u16 r = m_fifo[0];
|
||||
m_fifo[0] = m_fifo[1];
|
||||
m_fifo_pos --;
|
||||
if(m_mode & 0x10) {
|
||||
// write
|
||||
if(m_fifo_pos == 1)
|
||||
m_dat1byte_cb(1);
|
||||
} else {
|
||||
// read
|
||||
if(m_fifo_pos == 0)
|
||||
m_dat1byte_cb(0);
|
||||
}
|
||||
update_dat1byte();
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -567,3 +549,17 @@ void swim2_device::sync()
|
||||
|
||||
m_last_sync = next_sync;
|
||||
}
|
||||
|
||||
void swim2_device::update_dat1byte()
|
||||
{
|
||||
if (m_mode & 0x10)
|
||||
{
|
||||
// write: Does FIFO have room?
|
||||
m_dat1byte_cb((m_fifo_pos < 2) ? ASSERT_LINE : CLEAR_LINE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// read: is FIFO not empty?
|
||||
m_dat1byte_cb((m_fifo_pos > 0) ? ASSERT_LINE : CLEAR_LINE);
|
||||
}
|
||||
}
|
||||
|
@ -69,6 +69,8 @@ private:
|
||||
|
||||
void crc_update(int bit);
|
||||
void crc_clear();
|
||||
|
||||
void update_dat1byte();
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(SWIM2, swim2_device)
|
||||
|
@ -11,16 +11,20 @@
|
||||
off /DTACK on pseudo-DMA reads and writes.
|
||||
|
||||
Shipping configurations:
|
||||
DAFB - original standalone chip, Quadra 700 and 900 (returns versions 0 and 1)
|
||||
DAFB II - revised standalone chip with 15 bpp support added (uses AC842a CODEC instead of AC842) (returns version 2)
|
||||
DAFB - original standalone chip, Quadra 700 and 900 (returns versions 0, 1, and 2)
|
||||
DAFB II - revised standalone chip with 15 bpp support added (uses AC842a CODEC instead of AC842) (returns version 3)
|
||||
Used in Quadra 950.
|
||||
MEMC - DAFB II without the Turbo SCSI logic, in the djMEMC and MEMCjr memory controllers. (returns version 3)
|
||||
Used in LC 475, LC 575, Quadra 605, Quadra 610, Quadra 650, and Quadra 800.
|
||||
This version uses a DP8534 timing generator instead of the DP8531 and an AC842a DAC instead of AC842.
|
||||
Valkyrie - This video used in the LC/Performa/Quadra 630 and LC580 is stated by the developer note to be very similar to DAFB.
|
||||
DaMFB - DAFB II with a PowerPC bus interface instead of 68040. Used in the HPV card for the PowerMac 6100/7100/8100.
|
||||
Platinum - DAFB II with 4 MB VRAM support and a blitter bolted on.
|
||||
|
||||
The "Valkyrie" chip used in the LC/Performa/Quadra 630 and 580 and the Power Macintosh 5200/6200 is stated by
|
||||
Apple's developer note to be "very similar" to DAFB but its register interface is entirely different.
|
||||
Valkyrie implements a small set of fixed video modes that are selected by number rather than a fully programmable
|
||||
CRTC as is found in DAFB.
|
||||
|
||||
The Turbo SCSI block moved into the IOSB and PrimeTime I/O ASICs for the machines where DAFB moved into the
|
||||
memory controller. It was enhanced slightly to allow longword pseudo-DMA transfers.
|
||||
|
||||
@ -52,9 +56,11 @@
|
||||
#define LOG_TURBOSCSI (1U << 5)
|
||||
|
||||
#define VERBOSE (0)
|
||||
|
||||
#include "logmacro.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE(DAFB, dafb_device, "macdafb", "Apple DAFB video")
|
||||
DEFINE_DEVICE_TYPE(DAFB_Q950, dafb_q950_device, "macdafb_q950", "Apple DAFB II video")
|
||||
DEFINE_DEVICE_TYPE(DAFB_MEMC, dafb_memc_device, "macdafb_djmemc", "Apple DAFB II video (djMEMC integrated)")
|
||||
DEFINE_DEVICE_TYPE(DAFB_MEMCJR, dafb_memcjr_device, "macdafb_memcjr", "Apple DAFB II video (MEMCjr integrated)")
|
||||
|
||||
@ -94,13 +100,25 @@ dafb_base::dafb_base(const machine_config &mconfig, device_type type, const char
|
||||
}
|
||||
|
||||
dafb_device::dafb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
|
||||
dafb_base(mconfig, DAFB, tag, owner, clock),
|
||||
dafb_device(mconfig, DAFB, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
dafb_device::dafb_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) :
|
||||
dafb_base(mconfig, type, tag, owner, clock),
|
||||
m_maincpu(*this, finder_base::DUMMY_TAG)
|
||||
{
|
||||
m_drq[0] = m_drq[1] = 0;
|
||||
m_ncr[0] = m_ncr[1] = nullptr;
|
||||
}
|
||||
|
||||
|
||||
dafb_q950_device::dafb_q950_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
|
||||
dafb_device(mconfig, DAFB_Q950, tag, owner, clock),
|
||||
m_pcbr1(0)
|
||||
{
|
||||
}
|
||||
|
||||
dafb_memc_device::dafb_memc_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
|
||||
dafb_base(mconfig, DAFB_MEMC, tag, owner, clock),
|
||||
m_pcbr1(0),
|
||||
@ -216,6 +234,11 @@ ioport_constructor dafb_base::device_input_ports() const
|
||||
return INPUT_PORTS_NAME(monitor_config);
|
||||
}
|
||||
|
||||
ioport_constructor dafb_q950_device::device_input_ports() const
|
||||
{
|
||||
return INPUT_PORTS_NAME(monitor_config_noconv);
|
||||
}
|
||||
|
||||
ioport_constructor dafb_memc_device::device_input_ports() const
|
||||
{
|
||||
return INPUT_PORTS_NAME(monitor_config_noconv);
|
||||
@ -1064,6 +1087,88 @@ void dafb_device::turboscsi_drq_w(int state)
|
||||
template void dafb_device::turboscsi_drq_w<0>(int state);
|
||||
template void dafb_device::turboscsi_drq_w<1>(int state);
|
||||
|
||||
// ************************************************************************
|
||||
// dafb_q950_device overrides/additions
|
||||
// ************************************************************************
|
||||
void dafb_q950_device::device_start()
|
||||
{
|
||||
m_dafb_version = 3;
|
||||
dafb_base::device_start();
|
||||
}
|
||||
|
||||
u32 dafb_q950_device::ramdac_r(offs_t offset)
|
||||
{
|
||||
switch (offset << 2)
|
||||
{
|
||||
case 0x20:
|
||||
if ((m_pal_address == 1) && ((m_ac842_pbctrl & 0x06) == 0x06))
|
||||
{
|
||||
LOGMASKED(LOG_RAMDAC, "Read %02x from PCBR1\n", m_pcbr1);
|
||||
return m_pcbr1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return dafb_base::ramdac_r(offset);
|
||||
}
|
||||
|
||||
default:
|
||||
return dafb_base::ramdac_r(offset);
|
||||
}
|
||||
}
|
||||
|
||||
void dafb_q950_device::ramdac_w(offs_t offset, u32 data)
|
||||
{
|
||||
switch (offset << 2)
|
||||
{
|
||||
case 0x20:
|
||||
if ((m_pal_address == 1) && ((m_ac842_pbctrl & 0x06) == 0x06))
|
||||
{
|
||||
LOGMASKED(LOG_RAMDAC, "%02x to AC842a PCBR1\n", data);
|
||||
m_pcbr1 = (data & 0xf0) | 0x01; // AC842a version ID
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGMASKED(LOG_RAMDAC, "%02x to AC842a PCBR0, & 0x1c = %02x\n", data, data & 0x1c);
|
||||
m_ac842_pbctrl = data;
|
||||
if (((m_pcbr1 & 0xc0) == 0xc0) && ((data & 0x06) == 0x06))
|
||||
{
|
||||
m_mode = 5; // 16 bpp (x555)
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (data & 0x1c)
|
||||
{
|
||||
case 0x00:
|
||||
m_mode = 0; // 1bpp
|
||||
break;
|
||||
|
||||
case 0x08:
|
||||
m_mode = 1; // 2bpp
|
||||
break;
|
||||
|
||||
case 0x10:
|
||||
m_mode = 2; // 4bpp
|
||||
break;
|
||||
|
||||
case 0x18:
|
||||
m_mode = 3; // 8bpp
|
||||
break;
|
||||
|
||||
case 0x1c:
|
||||
m_mode = 4; // 24bpp
|
||||
break;
|
||||
}
|
||||
}
|
||||
recalc_mode();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
dafb_base::ramdac_w(offset, data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ************************************************************************
|
||||
// dafb_memc_device overrides/additions
|
||||
// ************************************************************************
|
||||
|
@ -101,7 +101,7 @@ private:
|
||||
TIMER_CALLBACK_MEMBER(cursor_tick);
|
||||
};
|
||||
|
||||
// Discrete DAFB: Quadra 700 & 900, includes "TurboSCSI"
|
||||
// Discrete DAFB II: Quadra 950, includes "TurboSCSI"
|
||||
class dafb_device: public dafb_base
|
||||
{
|
||||
public:
|
||||
@ -120,6 +120,8 @@ public:
|
||||
template <int bus> void turboscsi_dma_w(offs_t offset, u16 data, u16 mem_mask);
|
||||
|
||||
protected:
|
||||
dafb_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
|
||||
|
||||
virtual void device_start() override;
|
||||
|
||||
private:
|
||||
@ -127,6 +129,22 @@ private:
|
||||
ncr53c94_device *m_ncr[2];
|
||||
};
|
||||
|
||||
class dafb_q950_device : public dafb_device
|
||||
{
|
||||
public:
|
||||
dafb_q950_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
|
||||
|
||||
protected:
|
||||
virtual void device_start() override;
|
||||
virtual ioport_constructor device_input_ports() const override;
|
||||
|
||||
virtual u32 ramdac_r(offs_t offset) override;
|
||||
virtual void ramdac_w(offs_t offset, u32 data) override;
|
||||
|
||||
private:
|
||||
u8 m_pcbr1;
|
||||
};
|
||||
|
||||
class dafb_memc_device: public dafb_base
|
||||
{
|
||||
public:
|
||||
@ -171,6 +189,7 @@ private:
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(DAFB, dafb_device)
|
||||
DECLARE_DEVICE_TYPE(DAFB_Q950, dafb_q950_device)
|
||||
DECLARE_DEVICE_TYPE(DAFB_MEMC, dafb_memc_device)
|
||||
DECLARE_DEVICE_TYPE(DAFB_MEMCJR, dafb_memcjr_device)
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -17,25 +17,18 @@ class macadb_device : public device_t
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
macadb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
macadb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||
|
||||
void set_mcu_mode(bool bMCUMode) { m_bIsMCUMode = bMCUMode; }
|
||||
|
||||
auto via_clock_callback() { return write_via_clock.bind(); }
|
||||
auto via_data_callback() { return write_via_data.bind(); }
|
||||
auto adb_data_callback() { return write_adb_data.bind(); }
|
||||
auto adb_irq_callback() { return write_adb_irq.bind(); }
|
||||
|
||||
required_ioport m_mouse0, m_mouse1, m_mouse2;
|
||||
required_ioport_array<8> m_keys;
|
||||
devcb_write_line write_via_clock, write_via_data, write_adb_data, write_adb_irq;
|
||||
devcb_write_line write_adb_data, write_adb_irq;
|
||||
|
||||
void adb_data_w(int state);
|
||||
void adb_linechange_w(int state);
|
||||
|
||||
void adb_vblank();
|
||||
void mac_adb_newaction(int state);
|
||||
int32_t get_adb_state(void) { return m_adb_state; }
|
||||
void adb_vblank() {}
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
@ -44,46 +37,42 @@ protected:
|
||||
virtual void device_reset() override;
|
||||
|
||||
private:
|
||||
bool m_bIsMCUMode;
|
||||
|
||||
uint64_t m_last_adb_time;
|
||||
|
||||
emu_timer *m_adb_timer;
|
||||
u64 m_last_adb_time;
|
||||
emu_timer *m_timer;
|
||||
|
||||
/* keyboard matrix to detect transition */
|
||||
u16 m_key_matrix[9];
|
||||
|
||||
// ADB HLE state
|
||||
int32_t m_adb_state, m_adb_waiting_cmd, m_adb_datasize;
|
||||
int32_t m_adb_command, m_adb_send, m_adb_timer_ticks, m_adb_extclock, m_adb_direction;
|
||||
int32_t m_adb_listenreg, m_adb_listenaddr, m_adb_last_talk, m_adb_srq_switch;
|
||||
int32_t m_adb_stream_ptr;
|
||||
int32_t m_adb_linestate;
|
||||
u8 m_adb_buffer[257], m_last_kbd[2], m_last_mouse[2], m_keyboard_handler, m_mouse_handler;
|
||||
bool m_adb_srqflag;
|
||||
int m_adb_linein;
|
||||
bool m_waiting_cmd;
|
||||
s32 m_datasize;
|
||||
s32 m_command, m_direction;
|
||||
u8 m_listenreg, m_listenaddr;
|
||||
s32 m_srq_switch, m_stream_ptr, m_linestate;
|
||||
u8 m_buffer[16], m_last_kbd[2], m_last_mouse[2];
|
||||
u8 m_keyboard_handler, m_mouse_handler;
|
||||
bool m_srqflag;
|
||||
s32 m_linein;
|
||||
|
||||
#define kADBKeyBufSize 32
|
||||
uint8_t m_adb_keybuf[kADBKeyBufSize];
|
||||
uint8_t m_adb_keybuf_start;
|
||||
uint8_t m_adb_keybuf_end;
|
||||
static constexpr int kADBKeyBufSize = 32;
|
||||
u8 m_keybuf[kADBKeyBufSize];
|
||||
u8 m_keybuf_start;
|
||||
u8 m_keybuf_end;
|
||||
|
||||
// ADB mouse state
|
||||
int m_adb_mouseaddr;
|
||||
int m_adb_lastmousex, m_adb_lastmousey, m_adb_lastbutton, m_adb_mouse_initialized;
|
||||
u8 m_mouseaddr;
|
||||
s32 m_lastmousex, m_lastmousey, m_lastbutton;
|
||||
|
||||
// ADB keyboard state
|
||||
int m_adb_keybaddr;
|
||||
int m_adb_keybinitialized, m_adb_currentkeys[2], m_adb_modifiers;
|
||||
u8 m_keybaddr;
|
||||
s32 m_currentkeys[2], m_modifiers;
|
||||
|
||||
int adb_pollkbd(int update);
|
||||
int adb_pollmouse();
|
||||
void adb_accummouse( uint8_t *MouseX, uint8_t *MouseY );
|
||||
bool adb_pollkbd(int update);
|
||||
bool adb_pollmouse();
|
||||
void adb_accummouse(u8 *MouseX, u8 *MouseY );
|
||||
void adb_talk();
|
||||
|
||||
inline void set_adb_line(int linestate) { write_adb_data(linestate); }
|
||||
|
||||
TIMER_CALLBACK_MEMBER(mac_adb_tick);
|
||||
TIMER_CALLBACK_MEMBER(timer_tick);
|
||||
};
|
||||
|
||||
// device type definition
|
||||
|
@ -67,7 +67,12 @@ public:
|
||||
m_scc(*this, "scc"),
|
||||
m_asc(*this, "asc"),
|
||||
m_cur_floppy(nullptr),
|
||||
m_hdsel(0)
|
||||
m_hdsel(0),
|
||||
m_last_taken_interrupt(-1),
|
||||
m_overlay(true),
|
||||
m_rom_ptr(nullptr),
|
||||
m_rom_size(0),
|
||||
m_adb_in(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -100,8 +105,8 @@ private:
|
||||
emu_timer *m_6015_timer;
|
||||
|
||||
bool m_overlay;
|
||||
u32 *m_rom_ptr = nullptr;
|
||||
u32 m_rom_size = 0;
|
||||
u32 *m_rom_ptr;
|
||||
u32 m_rom_size;
|
||||
|
||||
int m_adb_in;
|
||||
|
||||
@ -117,6 +122,7 @@ private:
|
||||
|
||||
void phases_w(uint8_t phases);
|
||||
void devsel_w(uint8_t devsel);
|
||||
void fdc_hdsel(int state);
|
||||
|
||||
uint32_t biu_r(offs_t offset, uint32_t mem_mask = ~0);
|
||||
void biu_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
|
||||
@ -129,13 +135,13 @@ private:
|
||||
uint8_t maciifx_8010_r();
|
||||
uint8_t maciifx_8040_r();
|
||||
|
||||
uint16_t mac_via_r(offs_t offset);
|
||||
void mac_via_w(offs_t offset, uint16_t data, uint16_t mem_mask);
|
||||
uint8_t mac_via_in_a();
|
||||
uint8_t mac_via_in_b();
|
||||
void mac_via_out_a(uint8_t data);
|
||||
void mac_via_out_b(uint8_t data);
|
||||
void mac_via_sync();
|
||||
uint16_t via_r(offs_t offset);
|
||||
void via_w(offs_t offset, uint16_t data, uint16_t mem_mask);
|
||||
uint8_t via_in_a();
|
||||
uint8_t via_in_b();
|
||||
void via_out_a(uint8_t data);
|
||||
void via_out_b(uint8_t data);
|
||||
void via_sync();
|
||||
|
||||
uint32_t rom_switch_r(offs_t offset);
|
||||
|
||||
@ -200,7 +206,7 @@ void maciifx_state::maciifx_map(address_map &map)
|
||||
{
|
||||
map(0x40000000, 0x4007ffff).r(FUNC(maciifx_state::rom_switch_r)).mirror(0x0ff80000);
|
||||
|
||||
map(0x50000000, 0x50001fff).rw(FUNC(maciifx_state::mac_via_r), FUNC(maciifx_state::mac_via_w)).mirror(0x00f00000);
|
||||
map(0x50000000, 0x50001fff).rw(FUNC(maciifx_state::via_r), FUNC(maciifx_state::via_w)).mirror(0x00f00000);
|
||||
map(0x50004000, 0x50005fff).rw("sccpic", FUNC(applepic_device::host_r), FUNC(applepic_device::host_w)).mirror(0x00f00000).umask32(0xff00ff00);
|
||||
map(0x50004000, 0x50005fff).rw("sccpic", FUNC(applepic_device::host_r), FUNC(applepic_device::host_w)).mirror(0x00f00000).umask32(0x00ff00ff);
|
||||
map(0x50008010, 0x50008010).r(FUNC(maciifx_state::maciifx_8010_r)).mirror(0x00f00000);
|
||||
@ -215,10 +221,10 @@ void maciifx_state::maciifx_map(address_map &map)
|
||||
map(0x50018000, 0x50019fff).rw(FUNC(maciifx_state::biu_r), FUNC(maciifx_state::biu_w)).mirror(0x00f00000);
|
||||
map(0x5001a000, 0x5001bfff).rw(FUNC(maciifx_state::oss_r), FUNC(maciifx_state::oss_w)).mirror(0x00f00000);
|
||||
map(0x50024000, 0x50027fff).r(FUNC(maciifx_state::buserror_r)).mirror(0x00f00000); // must bus error on access here so ROM can determine we're an FMC
|
||||
map(0x50040000, 0x50041fff).rw(FUNC(maciifx_state::mac_via_r), FUNC(maciifx_state::mac_via_w)).mirror(0x00f00000);
|
||||
map(0x50040000, 0x50041fff).rw(FUNC(maciifx_state::via_r), FUNC(maciifx_state::via_w)).mirror(0x00f00000);
|
||||
}
|
||||
|
||||
void maciifx_state::mac_via_sync()
|
||||
void maciifx_state::via_sync()
|
||||
{
|
||||
// The via runs at 783.36KHz while the main cpu runs at 15MHz or
|
||||
// more, so we need to sync the access with the via clock. Plus
|
||||
@ -241,7 +247,7 @@ void maciifx_state::mac_via_sync()
|
||||
m_maincpu->adjust_icount(-int(main_cycle - cycle));
|
||||
}
|
||||
|
||||
uint16_t maciifx_state::mac_via_r(offs_t offset)
|
||||
uint16_t maciifx_state::via_r(offs_t offset)
|
||||
{
|
||||
uint16_t data;
|
||||
|
||||
@ -249,19 +255,19 @@ uint16_t maciifx_state::mac_via_r(offs_t offset)
|
||||
offset &= 0x0f;
|
||||
|
||||
if (!machine().side_effects_disabled())
|
||||
mac_via_sync();
|
||||
via_sync();
|
||||
|
||||
data = m_via1->read(offset);
|
||||
|
||||
return (data & 0xff) | (data << 8);
|
||||
}
|
||||
|
||||
void maciifx_state::mac_via_w(offs_t offset, uint16_t data, uint16_t mem_mask)
|
||||
void maciifx_state::via_w(offs_t offset, uint16_t data, uint16_t mem_mask)
|
||||
{
|
||||
offset >>= 8;
|
||||
offset &= 0x0f;
|
||||
|
||||
mac_via_sync();
|
||||
via_sync();
|
||||
|
||||
if (ACCESSING_BITS_0_7)
|
||||
m_via1->write(offset, data & 0xff);
|
||||
@ -269,37 +275,22 @@ void maciifx_state::mac_via_w(offs_t offset, uint16_t data, uint16_t mem_mask)
|
||||
m_via1->write(offset, (data >> 8) & 0xff);
|
||||
}
|
||||
|
||||
uint8_t maciifx_state::mac_via_in_a()
|
||||
uint8_t maciifx_state::via_in_a()
|
||||
{
|
||||
return 0xd3; // PA6 | PA4 | PA1
|
||||
}
|
||||
|
||||
uint8_t maciifx_state::mac_via_in_b()
|
||||
uint8_t maciifx_state::via_in_b()
|
||||
{
|
||||
int val = m_rtc->data_r();
|
||||
|
||||
// printf("%s VIA1 IN_B = %02x\n", machine().describe_context().c_str(), val);
|
||||
|
||||
return val;
|
||||
return m_rtc->data_r();
|
||||
}
|
||||
|
||||
void maciifx_state::mac_via_out_a(uint8_t data)
|
||||
void maciifx_state::via_out_a(uint8_t data)
|
||||
{
|
||||
int hdsel = BIT(data, 5);
|
||||
if (hdsel != m_hdsel)
|
||||
{
|
||||
if (m_cur_floppy)
|
||||
{
|
||||
m_cur_floppy->ss_w(hdsel);
|
||||
}
|
||||
}
|
||||
m_hdsel = hdsel;
|
||||
}
|
||||
|
||||
void maciifx_state::mac_via_out_b(uint8_t data)
|
||||
void maciifx_state::via_out_b(uint8_t data)
|
||||
{
|
||||
// printf("%s VIA1 OUT B: %02x\n", machine().describe_context().c_str(), data);
|
||||
|
||||
m_rtc->ce_w((data & 0x04) >> 2);
|
||||
m_rtc->data_w(data & 0x01);
|
||||
m_rtc->clk_w((data >> 1) & 0x01);
|
||||
@ -376,43 +367,69 @@ void maciifx_state::phases_w(uint8_t phases)
|
||||
void maciifx_state::devsel_w(uint8_t devsel)
|
||||
{
|
||||
if (devsel == 1)
|
||||
{
|
||||
m_cur_floppy = m_floppy[0]->get_device();
|
||||
}
|
||||
else if (devsel == 2)
|
||||
{
|
||||
m_cur_floppy = m_floppy[1]->get_device();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cur_floppy = nullptr;
|
||||
}
|
||||
|
||||
m_fdc->set_floppy(m_cur_floppy);
|
||||
if (m_cur_floppy)
|
||||
{
|
||||
m_cur_floppy->ss_w(m_hdsel);
|
||||
}
|
||||
}
|
||||
|
||||
void maciifx_state::fdc_hdsel(int state)
|
||||
{
|
||||
if (state != m_hdsel)
|
||||
{
|
||||
if (m_cur_floppy)
|
||||
{
|
||||
m_cur_floppy->ss_w(state);
|
||||
}
|
||||
}
|
||||
m_hdsel = state;
|
||||
}
|
||||
|
||||
uint32_t maciifx_state::biu_r(offs_t offset, uint32_t mem_mask)
|
||||
{
|
||||
// printf("biu_r @ %x, mask %08x\n", offset, mem_mask);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void maciifx_state::biu_w(offs_t offset, uint32_t data, uint32_t mem_mask)
|
||||
{
|
||||
// printf("biu_w %x @ %x, mask %08x\n", data, offset, mem_mask);
|
||||
}
|
||||
|
||||
template <int N>
|
||||
void maciifx_state::oss_interrupt(int state)
|
||||
{
|
||||
if (state == ASSERT_LINE)
|
||||
{
|
||||
m_oss_regs[N >= 8 ? 0x202 : 0x203] |= 1 << (N & 7);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_oss_regs[N >= 8 ? 0x202 : 0x203] &= ~(1 << (N & 7));
|
||||
}
|
||||
|
||||
int take_interrupt = 0;
|
||||
for (int n = 0; n < 8; n++)
|
||||
{
|
||||
if (BIT(m_oss_regs[0x203], n) && take_interrupt < m_oss_regs[n])
|
||||
{
|
||||
take_interrupt = m_oss_regs[n];
|
||||
}
|
||||
if (BIT(m_oss_regs[0x202], n) && take_interrupt < m_oss_regs[8 + n])
|
||||
{
|
||||
take_interrupt = m_oss_regs[8 + n];
|
||||
}
|
||||
}
|
||||
|
||||
if (m_last_taken_interrupt > -1)
|
||||
@ -439,25 +456,26 @@ TIMER_CALLBACK_MEMBER(maciifx_state::oss_6015_tick)
|
||||
|
||||
uint8_t maciifx_state::oss_r(offs_t offset)
|
||||
{
|
||||
// printf("oss_r @ %x\n", offset);
|
||||
// if (offset <= 0xe) // for interrupt mask registers, we're intended to return something different than is written in the low 3 bits (?)
|
||||
// {
|
||||
// return m_oss_regs[offset]<<4;
|
||||
// }
|
||||
|
||||
if (offset < std::size(m_oss_regs))
|
||||
{
|
||||
return m_oss_regs[offset];
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void maciifx_state::oss_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
// printf("oss_w %x @ %x\n", data, offset);
|
||||
if (offset == 0x207)
|
||||
{
|
||||
oss_interrupt<10>(CLEAR_LINE);
|
||||
}
|
||||
else if (offset < std::size(m_oss_regs))
|
||||
{
|
||||
m_oss_regs[offset] = data;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t maciifx_state::buserror_r()
|
||||
@ -500,6 +518,7 @@ void maciifx_state::maciifx(machine_config &config)
|
||||
SWIM1(config, m_fdc, C15M);
|
||||
m_fdc->devsel_cb().set(FUNC(maciifx_state::devsel_w));
|
||||
m_fdc->phases_cb().set(FUNC(maciifx_state::phases_w));
|
||||
m_fdc->hdsel_cb().set(FUNC(maciifx_state::fdc_hdsel));
|
||||
|
||||
applefdintf_device::add_35_hd(config, m_floppy[0]);
|
||||
applefdintf_device::add_35_nc(config, m_floppy[1]);
|
||||
@ -560,10 +579,10 @@ void maciifx_state::maciifx(machine_config &config)
|
||||
m_asc->irqf_callback().set(FUNC(maciifx_state::oss_interrupt<8>));
|
||||
|
||||
R65NC22(config, m_via1, C7M / 10);
|
||||
m_via1->readpa_handler().set(FUNC(maciifx_state::mac_via_in_a));
|
||||
m_via1->readpb_handler().set(FUNC(maciifx_state::mac_via_in_b));
|
||||
m_via1->writepa_handler().set(FUNC(maciifx_state::mac_via_out_a));
|
||||
m_via1->writepb_handler().set(FUNC(maciifx_state::mac_via_out_b));
|
||||
m_via1->readpa_handler().set(FUNC(maciifx_state::via_in_a));
|
||||
m_via1->readpb_handler().set(FUNC(maciifx_state::via_in_b));
|
||||
m_via1->writepa_handler().set(FUNC(maciifx_state::via_out_a));
|
||||
m_via1->writepb_handler().set(FUNC(maciifx_state::via_out_b));
|
||||
m_via1->irq_handler().set(FUNC(maciifx_state::oss_interrupt<11>));
|
||||
|
||||
MACADB(config, m_macadb, C15M);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -936,6 +936,8 @@ maclc580 // April 3, 1995 Apple Macintosh LC/Performa 580
|
||||
|
||||
@source:apple/macquadra700.cpp
|
||||
macqd700 // 1991 Apple Macintosh Quadra 700
|
||||
macqd900 // 1991 Apple Macintosh Quadra 900
|
||||
macqd950 // 1992 Apple Macintosh Quadra 950
|
||||
|
||||
@source:apple/macquadra800.cpp
|
||||
macqd800 // 1993 Apple Macintosh Quadra 800
|
||||
|
Loading…
Reference in New Issue
Block a user