nmi and dma improvements

* nmi boot diagnostics pass
* floppy dma read and write working
This commit is contained in:
Patrick Mackinlay 2017-06-23 11:19:38 +07:00
parent 198df16bfa
commit aac9e23e36
2 changed files with 149 additions and 209 deletions

View File

@ -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;
}

View File

@ -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;