mirror of
https://github.com/holub/mame
synced 2025-04-22 08:22:15 +03:00
nmi and dma improvements
* nmi boot diagnostics pass * floppy dma read and write working
This commit is contained in:
parent
198df16bfa
commit
aac9e23e36
@ -18,26 +18,23 @@
|
||||
#include "emu.h"
|
||||
#include "interpro_ioga.h"
|
||||
|
||||
#define LOG_HWINT_ENABLE ((1<<2) | LOG_GENERAL)
|
||||
#define LOG_DMA_ENABLE ((1<<2) | LOG_GENERAL)
|
||||
|
||||
#define LOG_GENERAL (1 << 31)
|
||||
|
||||
#define LOG_HWINT(interrupt, ...) if (LOG_HWINT_ENABLE & (1 << interrupt)) logerror(__VA_ARGS__)
|
||||
#define LOG_DMA(channel, ...) if (LOG_DMA_ENABLE & (1 << channel)) logerror(__VA_ARGS__)
|
||||
#define LOG_GENERAL (1 << 31)
|
||||
#define LOG_HWINT_ENABLE ((1<<3) | LOG_GENERAL)
|
||||
#define LOG_DMA_ENABLE ((1<<IOGA_DMA_FLOPPY) | LOG_GENERAL)
|
||||
#define LOG_TIMER_ENABLE 0
|
||||
|
||||
#define VERBOSE 0
|
||||
|
||||
#if VERBOSE
|
||||
#define LOG_TIMER_MASK 0xff
|
||||
#define LOG_TIMER(timer, ...) if (LOG_TIMER_MASK & (1 << timer)) logerror(__VA_ARGS__)
|
||||
#define LOG_INTERRUPT(...) logerror(__VA_ARGS__)
|
||||
#define LOG_IOGA(...) logerror(__VA_ARGS__)
|
||||
#define LOG_INTERRUPT(...) logerror(__VA_ARGS__)
|
||||
#define LOG_TIMER(timer, ...) if (LOG_TIMER_ENABLE & (1 << timer)) logerror(__VA_ARGS__)
|
||||
#define LOG_HWINT(interrupt, ...) if (LOG_HWINT_ENABLE & (1 << interrupt)) logerror(__VA_ARGS__)
|
||||
#define LOG_DMA(channel, ...) if (LOG_DMA_ENABLE & (1 << channel)) logerror(__VA_ARGS__)
|
||||
#else
|
||||
#define LOG_TIMER_MASK 0x00
|
||||
#define LOG_TIMER(timer, ...)
|
||||
#define LOG_INTERRUPT(...)
|
||||
#define LOG_IOGA(...)
|
||||
#define LOG_TIMER(timer, ...)
|
||||
#define LOG_HWINT(interrupt, ...)
|
||||
#define LOG_DMA(channel, ...)
|
||||
#endif
|
||||
|
||||
DEVICE_ADDRESS_MAP_START(map, 32, interpro_ioga_device)
|
||||
@ -73,10 +70,10 @@ interpro_ioga_device::interpro_ioga_device(const machine_config &mconfig, const
|
||||
m_out_irq_func(*this),
|
||||
m_memory_space(nullptr),
|
||||
m_dma_channel{
|
||||
{ 0,0,0,0,false, 0, {*this}, {*this} },
|
||||
{ 0,0,0,0,false, 0, {*this}, {*this} },
|
||||
{ 0,0,0,0,false, 0, {*this}, {*this} },
|
||||
{ 0,0,0,0,false, 0, {*this}, {*this} } },
|
||||
{ 0,0,0,0,false, 0, {*this}, {*this}, ARBCTL_BGR_PLOT },
|
||||
{ 0,0,0,0,false, 0, {*this}, {*this}, ARBCTL_BGR_SCSI },
|
||||
{ 0,0,0,0,false, 0, {*this}, {*this}, ARBCTL_BGR_FDC },
|
||||
{ 0,0,0,0,false, 0, {*this}, {*this}, ARBCTL_BGR_SER0 | ARBCTL_BGR_SER1 | ARBCTL_BGR_SER2 } },
|
||||
m_fdc_tc_func(*this)
|
||||
{
|
||||
}
|
||||
@ -151,6 +148,7 @@ void interpro_ioga_device::device_reset()
|
||||
// initialise interrupt state
|
||||
m_active_interrupt_type = IOGA_INTERRUPT_NONE;
|
||||
m_hwint_forced = 0;
|
||||
m_nmi_pending = false;
|
||||
m_nmi_state = CLEAR_LINE;
|
||||
m_irq_state = CLEAR_LINE;
|
||||
m_int_line = 0;
|
||||
@ -351,30 +349,22 @@ bool interpro_ioga_device::irq(int state)
|
||||
|
||||
void interpro_ioga_device::set_nmi_line(int state)
|
||||
{
|
||||
LOG_INTERRUPT("set_nmi_line(%d)\n", state);
|
||||
LOG_INTERRUPT("nmi: set_nmi_line(%d)\n", state);
|
||||
switch (state)
|
||||
{
|
||||
case ASSERT_LINE:
|
||||
#if 0
|
||||
if ((m_nmictrl & IOGA_NMI_ENABLE) == IOGA_NMI_ENABLE)
|
||||
{
|
||||
// if edge triggered mode, clear enable in
|
||||
if (m_nmictrl & IOGA_NMI_EDGE)
|
||||
m_nmictrl &= ~IOGA_NMI_ENABLE_IN;
|
||||
}
|
||||
#endif
|
||||
m_nmictrl |= NMI_PENDING;
|
||||
m_nmi_pending = true;
|
||||
break;
|
||||
|
||||
case CLEAR_LINE:
|
||||
m_nmictrl &= ~NMI_PENDING;
|
||||
m_nmi_pending = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void interpro_ioga_device::set_irq_line(int irq, int state)
|
||||
{
|
||||
LOG_HWINT(irq, "set_irq_line(%d, %d)\n", irq, state);
|
||||
LOG_HWINT(irq, "irq: set_irq_line(%d, %d)\n", irq, state);
|
||||
switch (state)
|
||||
{
|
||||
case ASSERT_LINE:
|
||||
@ -385,7 +375,7 @@ void interpro_ioga_device::set_irq_line(int irq, int state)
|
||||
|
||||
case CLEAR_LINE:
|
||||
// clear pending bit
|
||||
m_int_line &= (1 << irq);
|
||||
m_int_line &= ~(1 << irq);
|
||||
m_hwicr[irq] &= ~IOGA_INTERRUPT_PENDING;
|
||||
break;
|
||||
}
|
||||
@ -393,7 +383,7 @@ void interpro_ioga_device::set_irq_line(int irq, int state)
|
||||
|
||||
void interpro_ioga_device::set_irq_soft(int irq, int state)
|
||||
{
|
||||
LOG_INTERRUPT("set_irq_soft(%d, %d)\n", irq, state);
|
||||
LOG_INTERRUPT("irq: set_irq_soft(%d, %d)\n", irq, state);
|
||||
switch (state)
|
||||
{
|
||||
case ASSERT_LINE:
|
||||
@ -440,7 +430,7 @@ IRQ_CALLBACK_MEMBER(interpro_ioga_device::inta_cb)
|
||||
|
||||
// fall through to return interrupt vector
|
||||
case -1:
|
||||
// return vector for current interrupt without clearing irq line
|
||||
// return vector for current interrupt without clearing pending flag
|
||||
switch (m_active_interrupt_type)
|
||||
{
|
||||
case IOGA_INTERRUPT_INTERNAL:
|
||||
@ -463,9 +453,8 @@ IRQ_CALLBACK_MEMBER(interpro_ioga_device::inta_cb)
|
||||
break;
|
||||
|
||||
case INPUT_LINE_NMI:
|
||||
// clear pending flag
|
||||
m_nmictrl &= ~NMI_PENDING;
|
||||
m_active_interrupt_type = IOGA_INTERRUPT_NONE;
|
||||
m_nmi_pending = false;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -490,11 +479,21 @@ void interpro_ioga_device::interrupt_clock()
|
||||
return;
|
||||
|
||||
// check for pending nmi
|
||||
if (m_nmictrl & NMI_PENDING)
|
||||
if (m_nmi_pending)
|
||||
{
|
||||
m_active_interrupt_type = IOGA_INTERRUPT_NMI;
|
||||
nmi(ASSERT_LINE);
|
||||
return;
|
||||
// check if nmi is enabled
|
||||
if ((m_nmictrl & NMI_IE) == NMI_IE)
|
||||
{
|
||||
LOG_INTERRUPT("nmi: accepting nmi\n");
|
||||
|
||||
// if level triggered, disable input from pin
|
||||
if ((m_nmictrl & NMI_EDGE) == 0)
|
||||
m_nmictrl &= ~NMI_ENABLE2;
|
||||
|
||||
m_active_interrupt_type = IOGA_INTERRUPT_NMI;
|
||||
nmi(ASSERT_LINE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// scan all hardware interrupts
|
||||
@ -509,7 +508,7 @@ void interpro_ioga_device::interrupt_clock()
|
||||
// check if masked
|
||||
if (m_hwicr[i] & irq_enable_mask[i]) //(external ? IRQ_ENABLE_EXTERNAL : IRQ_ENABLE_INTERNAL))
|
||||
{
|
||||
LOG_HWINT(i, "accepting interrupt %d - %s (%s)\n", i, interrupt_source[i], external ? "external" : "internal");
|
||||
LOG_HWINT(i, "irq: accepting interrupt %d - %s (%s)\n", i, interrupt_source[i], external ? "external" : "internal");
|
||||
|
||||
m_active_interrupt_type = external ? IOGA_INTERRUPT_EXTERNAL : IOGA_INTERRUPT_INTERNAL;
|
||||
m_active_interrupt_number = i;
|
||||
@ -557,15 +556,19 @@ WRITE16_MEMBER(interpro_ioga_device::icr_w)
|
||||
* FIXME: should we only flag a forced interrupt if pending is written high from low?
|
||||
*/
|
||||
|
||||
LOG_HWINT(offset, "interrupt vector %d set to 0x%04x at %s\n", offset, data, machine().describe_context());
|
||||
#if 1
|
||||
LOG_HWINT(offset, "irq: interrupt vector %d = 0x%04x (%s)\n", offset, data, machine().describe_context());
|
||||
|
||||
if (data & IOGA_INTERRUPT_PENDING)
|
||||
{
|
||||
// record interrupt pending forced
|
||||
m_hwint_forced |= 1 << offset;
|
||||
|
||||
// store all bits except pending
|
||||
m_hwicr[offset] = (m_hwicr[offset] & IOGA_INTERRUPT_PENDING) | (data & ~IOGA_INTERRUPT_PENDING);
|
||||
}
|
||||
else if (m_hwint_forced & 1 << offset)
|
||||
{
|
||||
// interrupt is being forced
|
||||
m_hwicr[offset] = data;
|
||||
|
||||
// clear forced flag
|
||||
@ -575,16 +578,8 @@ WRITE16_MEMBER(interpro_ioga_device::icr_w)
|
||||
m_hwicr[offset] |= IOGA_INTERRUPT_PENDING;
|
||||
}
|
||||
else
|
||||
// otherwise just store the value
|
||||
m_hwicr[offset] = data;
|
||||
#else
|
||||
if (data & IOGA_INTERRUPT_PENDING)
|
||||
m_hwint_forced |= 1 << offset;
|
||||
|
||||
if (data & IOGA_INTERRUPT_ENABLE_EXTERNAL)
|
||||
m_hwicr[offset] = data;
|
||||
else
|
||||
m_hwicr[offset] = data & ~IOGA_INTERRUPT_PENDING;
|
||||
#endif
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(interpro_ioga_device::softint_w)
|
||||
@ -608,36 +603,13 @@ WRITE8_MEMBER(interpro_ioga_device::softint_w)
|
||||
|
||||
WRITE8_MEMBER(interpro_ioga_device::nmictrl_w)
|
||||
{
|
||||
LOG_INTERRUPT("nmictrl = 0x%02x (%s)\n", data, machine().describe_context());
|
||||
LOG_INTERRUPT("nmi: nmictrl = 0x%02x, nmi_pending = %d (%s)\n", data, m_nmi_pending, machine().describe_context());
|
||||
|
||||
#if 0
|
||||
// save the existing value
|
||||
uint8_t previous = m_nmictrl;
|
||||
// check for a forced nmi (NMI_NEGPOL written from 1 to 0 with NMI_IE set)
|
||||
if ((m_nmictrl & NMI_NEGPOL) && (data & (NMI_NEGPOL | NMI_IE)) == NMI_IE)
|
||||
m_nmi_pending = true;
|
||||
|
||||
// store the written value
|
||||
m_nmictrl = data;
|
||||
|
||||
// force an nmi when pending bit is written low
|
||||
if (previous & NMI_PENDING && !(data & NMI_PENDING))
|
||||
set_nmi_line(ASSERT_LINE);
|
||||
#else
|
||||
#if 0
|
||||
if (data & NMI_PENDING)
|
||||
{
|
||||
m_nmi_forced = true;
|
||||
m_nmictrl = (m_nmictrl & NMI_PENDING) | (data & ~NMI_PENDING);
|
||||
}
|
||||
else if (m_nmi_forced)
|
||||
{
|
||||
m_nmi_forced = false;
|
||||
|
||||
m_nmictrl = data | NMI_PENDING;
|
||||
}
|
||||
else
|
||||
m_nmictrl = data;
|
||||
#endif
|
||||
m_nmictrl = data & ~NMI_PENDING;
|
||||
#endif
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(interpro_ioga_device::softint_vector_w)
|
||||
@ -658,135 +630,77 @@ WRITE16_MEMBER(interpro_ioga_device::softint_vector_w)
|
||||
******************************************************************************/
|
||||
void interpro_ioga_device::dma_clock(int channel)
|
||||
{
|
||||
// transfer data between device and main memory
|
||||
struct dma &dma_channel = m_dma_channel[channel];
|
||||
|
||||
// TODO: virtual memory?
|
||||
|
||||
// handle device to memory dma
|
||||
if (m_dma_channel[channel].drq_state)
|
||||
// if bus grant is not enabled, set the busy flag (iogadiag test 7.0265)
|
||||
if (!(m_arbctl & dma_channel.arb_mask))
|
||||
{
|
||||
if (!m_dma_channel[channel].dma_active)
|
||||
{
|
||||
LOG_DMA(channel, "dma: transfer from device started, channel = %d, control 0x%08x, real address 0x%08x count 0x%08x\n",
|
||||
channel, m_dma_channel[channel].control, m_dma_channel[channel].real_address, m_dma_channel[channel].transfer_count);
|
||||
m_dma_channel[channel].dma_active = true;
|
||||
}
|
||||
dma_channel.control |= DMA_CTRL_BUSY;
|
||||
m_dma_channel[channel].control |= DMA_CTRL_BUSY;
|
||||
m_dma_timer->adjust(attotime::from_hz(clock()), channel);
|
||||
|
||||
// while the device is requesting a data transfer and the transfer count is not zero
|
||||
while (m_dma_channel[channel].drq_state && m_dma_channel[channel].transfer_count)
|
||||
{
|
||||
// transfer from the device to memory
|
||||
m_memory_space->write_byte(m_dma_channel[channel].real_address, m_dma_channel[channel].device_r());
|
||||
|
||||
// increment addresses and decrement count
|
||||
m_dma_channel[channel].real_address++;
|
||||
m_dma_channel[channel].virtual_address++;
|
||||
m_dma_channel[channel].transfer_count--;
|
||||
}
|
||||
|
||||
// if there are no more bytes remaining, terminate the transfer
|
||||
if (m_dma_channel[channel].transfer_count == 0)
|
||||
{
|
||||
LOG_DMA(channel, "dma: transfer from device completed, control 0x%08x, real address 0x%08x count 0x%08x\n",
|
||||
m_dma_channel[channel].control, m_dma_channel[channel].real_address, m_dma_channel[channel].transfer_count);
|
||||
|
||||
if (channel == IOGA_DMA_FLOPPY)
|
||||
{
|
||||
LOG_DMA(channel, "dma: asserting fdc terminal count line\n");
|
||||
|
||||
m_fdc_tc_func(ASSERT_LINE);
|
||||
m_fdc_tc_func(CLEAR_LINE);
|
||||
}
|
||||
|
||||
m_dma_channel[channel].dma_active = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else // memory to device dma
|
||||
else
|
||||
dma_channel.control &= ~DMA_CTRL_BUSY;
|
||||
|
||||
// if the channel isn't active yet, make it active and log something
|
||||
if (!dma_channel.dma_active)
|
||||
{
|
||||
// get access to the bus
|
||||
LOG_DMA(channel, "dma: transfer %s device begun, channel = %d, control 0x%08x, real address 0x%08x, virtual address 0x%08x, count 0x%08x\n",
|
||||
(dma_channel.control & DMA_CTRL_WRITE) ? "to" : "from",
|
||||
channel, dma_channel.control, dma_channel.real_address, dma_channel.virtual_address, dma_channel.transfer_count);
|
||||
dma_channel.dma_active = true;
|
||||
}
|
||||
|
||||
// transfer data while the device is requesting a data transfer and the transfer count is not zero
|
||||
while (dma_channel.drq_state && dma_channel.transfer_count)
|
||||
{
|
||||
// transfer from the memory to device or device to memory
|
||||
if (dma_channel.control & DMA_CTRL_WRITE)
|
||||
dma_channel.device_w(m_memory_space->read_byte(dma_channel.real_address));
|
||||
else
|
||||
m_memory_space->write_byte(dma_channel.real_address, dma_channel.device_r());
|
||||
|
||||
// increment addresses and decrement count
|
||||
dma_channel.real_address++;
|
||||
dma_channel.virtual_address++;
|
||||
dma_channel.transfer_count--;
|
||||
}
|
||||
|
||||
// if there are no more bytes remaining, terminate the transfer
|
||||
if (dma_channel.transfer_count == 0)
|
||||
{
|
||||
LOG_DMA(channel, "dma: transfer %s device ended, channel = %d, control 0x%08x, real address 0x%08x, virtual address 0x%08x, count 0x%08x\n",
|
||||
(dma_channel.control & DMA_CTRL_WRITE) ? "to" : "from",
|
||||
channel, dma_channel.control, dma_channel.real_address, dma_channel.virtual_address, dma_channel.transfer_count);
|
||||
|
||||
if (channel == IOGA_DMA_FLOPPY)
|
||||
{
|
||||
// iogadiag test 7.0265
|
||||
u32 mask = 0;
|
||||
LOG_DMA(channel, "dma: asserting fdc terminal count line\n");
|
||||
|
||||
switch (channel)
|
||||
{
|
||||
case IOGA_DMA_PLOTTER:
|
||||
mask = ARBCTL_BGR_PLOT;
|
||||
break;
|
||||
|
||||
case IOGA_DMA_SCSI:
|
||||
mask = ARBCTL_BGR_SCSI;
|
||||
break;
|
||||
|
||||
case IOGA_DMA_FLOPPY:
|
||||
mask = ARBCTL_BGR_FDC;
|
||||
break;
|
||||
}
|
||||
|
||||
// if bus grant is not enabled, set the busy flag
|
||||
if (!(m_arbctl & mask))
|
||||
{
|
||||
LOG_DMA(channel, "dma: delay for bus grant channel %d\n", channel);
|
||||
|
||||
m_dma_channel[channel].control |= IOGA_DMA_CTRL_BUSY;
|
||||
m_dma_timer->adjust(attotime::from_hz(clock()), channel);
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
m_dma_channel[channel].control &= ~IOGA_DMA_CTRL_BUSY;
|
||||
m_fdc_tc_func(ASSERT_LINE);
|
||||
m_fdc_tc_func(CLEAR_LINE);
|
||||
}
|
||||
|
||||
if (!m_dma_channel[channel].dma_active)
|
||||
{
|
||||
LOG_DMA(channel, "dma: transfer to device begun, channel %d, control 0x%08x, real address 0x%08x, count 0x%08x\n",
|
||||
channel, m_dma_channel[channel].control, m_dma_channel[channel].real_address, m_dma_channel[channel].transfer_count);
|
||||
m_dma_channel[channel].dma_active = true;
|
||||
}
|
||||
|
||||
while (m_dma_channel[channel].transfer_count)
|
||||
{
|
||||
// transfer from memory to the device
|
||||
m_dma_channel[channel].device_w(m_memory_space->read_byte(m_dma_channel[channel].real_address));
|
||||
|
||||
// increment addresses and decrement count
|
||||
m_dma_channel[channel].real_address++;
|
||||
m_dma_channel[channel].virtual_address++;
|
||||
m_dma_channel[channel].transfer_count--;
|
||||
}
|
||||
|
||||
// TODO: do we need the floppy terminal count line here?
|
||||
|
||||
m_dma_channel[channel].control |= IOGA_DMA_CTRL_TCZERO;
|
||||
m_dma_channel[channel].dma_active = false;
|
||||
|
||||
// TODO: do we need to throw an interrupt?
|
||||
LOG_DMA(channel, "dma: transfer to device ended, channel %d, control 0x%08x, real address 0x%08x, count 0x%08x\n",
|
||||
channel, m_dma_channel[channel].control, m_dma_channel[channel].real_address, m_dma_channel[channel].transfer_count);
|
||||
|
||||
// dma ctrl = 0xbf000600
|
||||
// = 0xff000600
|
||||
// = 0x63xxxxxx
|
||||
// 600 = scsi channel?
|
||||
// b = 1011
|
||||
// f = 1111
|
||||
// 6 = 0101
|
||||
// -> bit 0x4 = read/write?
|
||||
dma_channel.control |= DMA_CTRL_TCZERO;
|
||||
dma_channel.dma_active = false;
|
||||
}
|
||||
}
|
||||
|
||||
void interpro_ioga_device::drq(int state, int channel)
|
||||
{
|
||||
// this member is called when the device has data ready for reading via dma
|
||||
// a device is requesting a dma data transfer (read or write)
|
||||
m_dma_channel[channel].drq_state = state;
|
||||
|
||||
if (state)
|
||||
{
|
||||
LOG_DMA(channel, "dma: recieved drq for channel %d\n", channel);
|
||||
LOG_DMA(channel, "dma: drq for channel %d asserted\n", channel);
|
||||
|
||||
// TODO: check if dma is enabled
|
||||
m_dma_timer->adjust(attotime::zero, channel);
|
||||
}
|
||||
else
|
||||
LOG_DMA(channel, "dma: drq for channel %d deasserted\n", channel);
|
||||
}
|
||||
/*
|
||||
0x94: error address reg: expect 0x7f200000 after bus error (from dma virtual address)
|
||||
@ -823,26 +737,26 @@ void interpro_ioga_device::dma_w(address_space &space, offs_t offset, u32 data,
|
||||
switch (offset)
|
||||
{
|
||||
case 0:
|
||||
LOG_DMA(channel, "channel %d real address = 0x%08x (%s)\n", channel, data, machine().describe_context());
|
||||
LOG_DMA(channel, "dma: channel %d real address = 0x%08x (%s)\n", channel, data, machine().describe_context());
|
||||
m_dma_channel[channel].real_address = data;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
LOG_DMA(channel, "channel %d virtual address = 0x%08x (%s)\n", channel, data, machine().describe_context());
|
||||
LOG_DMA(channel, "dma: channel %d virtual address = 0x%08x (%s)\n", channel, data, machine().describe_context());
|
||||
m_dma_channel[channel].virtual_address = data & ~0x3;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
LOG_DMA(channel, "channel %d transfer count = 0x%08x (%s)\n", channel, data, machine().describe_context());
|
||||
LOG_DMA(channel, "dma: channel %d transfer count = 0x%08x (%s)\n", channel, data, machine().describe_context());
|
||||
m_dma_channel[channel].transfer_count = data;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
LOG_DMA(channel, "channel %d control = 0x%08x (%s)\n", channel, data, machine().describe_context());
|
||||
m_dma_channel[channel].control = data & IOGA_DMA_CTRL_WMASK;
|
||||
LOG_DMA(channel, "dma: channel %d control = 0x%08x (%s)\n", channel, data, machine().describe_context());
|
||||
m_dma_channel[channel].control = data & DMA_CTRL_WMASK;
|
||||
|
||||
// start dma transfer if necessary
|
||||
if (data & IOGA_DMA_CTRL_START)
|
||||
// start a forced dma transfer if necessary
|
||||
if ((data & DMA_CTRL_FORCED) == DMA_CTRL_FORCED)
|
||||
m_dma_timer->adjust(attotime::from_hz(clock()), channel);
|
||||
break;
|
||||
}
|
||||
@ -863,9 +777,17 @@ void interpro_ioga_device::dma_serial_w(address_space &space, offs_t offset, u32
|
||||
int channel = offset >> 1;
|
||||
|
||||
if (offset & 1)
|
||||
{
|
||||
LOG_DMA(IOGA_DMA_SERIAL, "dma: channel %d(%d) control = 0x%08x, mask = 0x%08x (%s)\n", IOGA_DMA_SERIAL, channel, data, mem_mask, machine().describe_context());
|
||||
|
||||
m_dma_serial[channel].control = (m_dma_serial[channel].control & ~mem_mask) | data;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_DMA(IOGA_DMA_SERIAL, "dma: channel %d(%d) address = 0x%08x, mask = 0x%08x (%s)\n", IOGA_DMA_SERIAL, channel, data, mem_mask, machine().describe_context());
|
||||
|
||||
m_dma_serial[channel].address = (m_dma_serial[channel].address & ~mem_mask) | data;
|
||||
}
|
||||
}
|
||||
|
||||
READ32_MEMBER(interpro_ioga_device::error_businfo_r)
|
||||
@ -876,4 +798,11 @@ READ32_MEMBER(interpro_ioga_device::error_businfo_r)
|
||||
m_error_businfo = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(interpro_ioga_device::arbctl_w)
|
||||
{
|
||||
LOG_DMA(31, "dma: arbctl = 0x%04x (%s)\n", data, machine().describe_context());
|
||||
|
||||
m_arbctl = data;
|
||||
}
|
||||
|
@ -60,22 +60,18 @@
|
||||
#define IOGA_DMA_FLOPPY 2
|
||||
#define IOGA_DMA_SERIAL 3
|
||||
|
||||
// dma write values
|
||||
#define IOGA_DMA_CTRL_WMASK 0xfd000e00
|
||||
// dma control register
|
||||
|
||||
// are these "commands"?
|
||||
#define IOGA_DMA_CTRL_RESET_L 0x61000000 // do not clear bus error bit
|
||||
#define IOGA_DMA_CTRL_RESET 0x60400000 // clear bus error bit
|
||||
|
||||
// uncertain about these
|
||||
#define IOGA_DMA_CTRL_START 0x10000000
|
||||
#define IOGA_DMA_CTRL_WRITE 0x40000000 // indicates memory to device transfer
|
||||
#define IOGA_DMA_CTRL_BUSY 0x02000000
|
||||
#define IOGA_DMA_CTRL_BERR 0x00400000 // iogadiag code expects 0x60400000 on bus error
|
||||
#define IOGA_DMA_CTRL_ENABLE 0x20000000
|
||||
#define IOGA_DMA_CTRL_X 0x00800000 // another error bit?
|
||||
#define IOGA_DMA_CTRL_Y 0x01000000 // turned off if either of two above are found
|
||||
#define IOGA_DMA_CTRL_TCZERO 0x00000001
|
||||
|
||||
// DMA_ENABLE, INT_ENABLE,
|
||||
|
||||
//#define IOGA_DMA_CTRL_START 0x63000800 // perhaps start a transfer? - maybe the 8 is the channel?
|
||||
#define IOGA_DMA_CTRL_UNK1 0x60000000 // don't know yet
|
||||
#define IOGA_DMA_CTRL_UNK2 0x67000600 // forced berr with nmi and interrupts disabled
|
||||
#define IOGA_DMA_CTRL_UNK3 0xbf000600 // set by scsidiag before executing scsi "transfer information" command
|
||||
@ -138,7 +134,7 @@ public:
|
||||
ARBCTL_BGR_ETHA = 0x0100
|
||||
};
|
||||
DECLARE_READ16_MEMBER(arbctl_r) { return m_arbctl; }
|
||||
DECLARE_WRITE16_MEMBER(arbctl_w) { m_arbctl = data; }
|
||||
DECLARE_WRITE16_MEMBER(arbctl_w);
|
||||
DECLARE_READ32_MEMBER(timer2_r) { return m_timer_reg[2]; }
|
||||
DECLARE_READ32_MEMBER(timer3_r);
|
||||
|
||||
@ -174,11 +170,13 @@ public:
|
||||
|
||||
enum nmictrl_mask
|
||||
{
|
||||
NMI_EDGE = 0x02,
|
||||
NMI_PENDING = 0x08,
|
||||
NMI_ENABLE_IN = 0x10,
|
||||
NMI_ALL = 0x01,
|
||||
NMI_ENABLE1 = 0x02,
|
||||
NMI_EDGE = 0x04,
|
||||
NMI_NEGPOL = 0x08,
|
||||
NMI_ENABLE2 = 0x10,
|
||||
|
||||
NMI_ENABLE = NMI_ENABLE_IN | NMI_EDGE
|
||||
NMI_IE = NMI_ENABLE1 | NMI_ENABLE2
|
||||
};
|
||||
DECLARE_READ8_MEMBER(nmictrl_r) { return m_nmictrl; }
|
||||
DECLARE_WRITE8_MEMBER(nmictrl_w);
|
||||
@ -186,6 +184,17 @@ public:
|
||||
DECLARE_READ16_MEMBER(softint_vector_r) { return m_swicr[offset]; }
|
||||
DECLARE_WRITE16_MEMBER(softint_vector_w);
|
||||
|
||||
enum dma_ctrl_mask
|
||||
{
|
||||
DMA_CTRL_TCZERO = 0x00000001, // transfer count zero
|
||||
DMA_CTRL_BERR = 0x00400000, // bus error
|
||||
DMA_CTRL_BUSY = 0x02000000, // set until arbiter grants bus access
|
||||
|
||||
DMA_CTRL_WRITE = 0x40000000, // indicates memory to device transfer
|
||||
DMA_CTRL_FORCED = 0x60000000,
|
||||
|
||||
DMA_CTRL_WMASK = 0xfd000e00 // writable fields
|
||||
};
|
||||
DECLARE_READ32_MEMBER(dma_plotter_r) { return dma_r(space, offset, mem_mask, IOGA_DMA_PLOTTER); }
|
||||
DECLARE_WRITE32_MEMBER(dma_plotter_w) { dma_w(space, offset, data, mem_mask, IOGA_DMA_PLOTTER); }
|
||||
DECLARE_READ32_MEMBER(dma_scsi_r) { return dma_r(space, offset, mem_mask, IOGA_DMA_SCSI); }
|
||||
@ -263,6 +272,8 @@ private:
|
||||
int drq_state;
|
||||
devcb_read8 device_r;
|
||||
devcb_write8 device_w;
|
||||
|
||||
const u16 arb_mask;
|
||||
} m_dma_channel[IOGA_DMA_CHANNELS];
|
||||
u32 m_dma_plotter_eosl;
|
||||
|
||||
@ -278,7 +289,7 @@ private:
|
||||
u32 m_active_interrupt_number;
|
||||
|
||||
u32 m_hwint_forced;
|
||||
//bool m_nmi_forced;
|
||||
bool m_nmi_pending;
|
||||
|
||||
u16 m_hwicr[IOGA_INTERRUPT_COUNT];
|
||||
u8 m_softint;
|
||||
|
Loading…
Reference in New Issue
Block a user