summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author R. Belmont <rb6502@users.noreply.github.com>2017-06-24 19:46:36 -0400
committer GitHub <noreply@github.com>2017-06-24 19:46:36 -0400
commit8601018f06fce38142d34520b086a3d0bf717696 (patch)
tree0a711f29d2cea17bc98bae579ad0238b0c8d8c87
parent32f89a1018946997a00db84ba2a3e7246734c6b3 (diff)
parentaac9e23e365600950fa47c070f9bcd7a0b36c832 (diff)
Merge pull request #2399 from pmackinlay/interpro
added diagnostic 7-seg led
-rw-r--r--src/mame/drivers/interpro.cpp34
-rw-r--r--src/mame/includes/interpro.h3
-rw-r--r--src/mame/layout/interpro.lay25
-rw-r--r--src/mame/machine/interpro_ioga.cpp309
-rw-r--r--src/mame/machine/interpro_ioga.h41
5 files changed, 196 insertions, 216 deletions
diff --git a/src/mame/drivers/interpro.cpp b/src/mame/drivers/interpro.cpp
index dc3ea441252..9f3dbe4de75 100644
--- a/src/mame/drivers/interpro.cpp
+++ b/src/mame/drivers/interpro.cpp
@@ -6,8 +6,11 @@
#define NEW_SCSI 1
#include "includes/interpro.h"
+
#include "debugger.h"
+#include "interpro.lh"
+
#define VERBOSE 0
#if VERBOSE
#define LOG_SYSTEM(...) logerror(__VA_ARGS__)
@@ -31,12 +34,21 @@ void interpro_state::machine_reset()
m_sreg_ctrl1 = CTRL1_FLOPRDY;
}
+WRITE16_MEMBER(interpro_state::sreg_led_w)
+{
+ // 7-segment decode patterns (hex digits) borrowed from wico.cpp (mc14495)
+ static const u8 patterns[16] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71 };
+
+ output().set_digit_value(0, patterns[data & 0xf]);
+}
+
WRITE16_MEMBER(interpro_state::sreg_ctrl1_w)
{
LOG_SYSTEM("system control register 1 write data 0x%x (%s)\n", data, machine().describe_context());
+ // check if led decimal point changes state
if ((data ^ m_sreg_ctrl1) & CTRL1_LEDDP)
- LOG_SYSTEM("LED decimal point %s\n", data & CTRL1_LEDDP ? "on" : "off");
+ output().set_digit_value(0, (output().get_digit_value(0) + 0x80) & 0xff);
m_sreg_ctrl1 = data;
}
@@ -73,13 +85,13 @@ READ8_MEMBER(interpro_state::idprom_r)
static u8 idprom[] = {
// module type id
- 0x00, 0x00, 0x00, 0x00, // board type MSMT/MPCB - detected by feature[3]
- '1', '2', '3', // board number
- 'A', // board revision
+ 'M', 'S', 'M', 'T', // board type MSMT/MPCB - detected by feature[3]
+ '1', '4', '5', // board number
+ '0', // board revision
// ECO bytes
- 0x87, 0x65, 0x43, 0x21,
- 0xbb, 0xcc, 0xdd, 0xee,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
// the following 8 bytes are "feature bytes"
@@ -91,7 +103,7 @@ READ8_MEMBER(interpro_state::idprom_r)
// 0x00, // 2500 series
0x00, 0x00,
- 0x80, // board type, 0x80 = MPCB, 0x00 = MSMT
+ 0x00, // board type, 0x80 = MPCB, 0x00 = MSMT
// for the system boards, these bytes contain cpu clock speed (as femtoseconds per cycle, big-endian)
(u8)(speed >> 24), (u8)(speed >> 16), (u8)(speed >> 8), (u8)(speed >> 0),
@@ -149,8 +161,10 @@ READ8_MEMBER(interpro_state::slot0_r)
};
#else
static u8 slot0[] = {
- 0x00, 0x00, 0x00, 0x00, '1', '1', '1', 'A', // board
- 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // eco
+ 'M', 'S', 'M', 'T', // board type
+ '0', '7', '0', // board
+ 'B', // board revision
+ 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // eco
0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, // features
0xff, 0xff, // reserved
0x05, 0x00, // family
@@ -535,6 +549,8 @@ static MACHINE_CONFIG_START(ip2800)
// srx arbiter gate array
MCFG_DEVICE_ADD(INTERPRO_SRARB_TAG, INTERPRO_SRARB, 0)
+ MCFG_DEFAULT_LAYOUT(layout_interpro)
+
MACHINE_CONFIG_END
ROM_START(ip2800)
diff --git a/src/mame/includes/interpro.h b/src/mame/includes/interpro.h
index e4163ae1278..11f382f79f6 100644
--- a/src/mame/includes/interpro.h
+++ b/src/mame/includes/interpro.h
@@ -119,7 +119,7 @@ public:
ERROR_BUSHOG = 0x0080
};
DECLARE_READ16_MEMBER(sreg_error_r);
- DECLARE_WRITE16_MEMBER(sreg_led_w) { m_sreg_led = data; }
+ DECLARE_WRITE16_MEMBER(sreg_led_w);
enum sreg_status_mask
{
@@ -187,7 +187,6 @@ protected:
private:
u16 m_sreg_error;
- u16 m_sreg_led;
u16 m_sreg_status;
u16 m_sreg_ctrl1;
u16 m_sreg_ctrl2;
diff --git a/src/mame/layout/interpro.lay b/src/mame/layout/interpro.lay
new file mode 100644
index 00000000000..b6263ed90f3
--- /dev/null
+++ b/src/mame/layout/interpro.lay
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!--
+license:CC0
+copyright-holders:Patrick Mackinlay
+Intergraph InterPro 2x00 layout.
+
+For now, this is only used to display the (internal) diagnostic 7-segment LED. In the future, it
+should be expanded to handle the monitor(s), system unit power/disk lights, and keyboard.
+-->
+<mamelayout version="2">
+ <element name="digit" defstate="0">
+ <led7seg>
+ <color red="1.0" green="0.0" blue="0.0" />
+ </led7seg>
+ </element>
+
+ <view name="Default Layout">
+ <bezel name="digit0" element="digit">
+ <bounds x="850" y="0" width="40" height="50" />
+ </bezel>
+ <screen index="0">
+ <bounds x="0" y="0" width="800" height="600" />
+ </screen>
+ </view>
+</mamelayout>
diff --git a/src/mame/machine/interpro_ioga.cpp b/src/mame/machine/interpro_ioga.cpp
index 937072f346f..044612fd90e 100644
--- a/src/mame/machine/interpro_ioga.cpp
+++ b/src/mame/machine/interpro_ioga.cpp
@@ -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
-
- // TODO: virtual memory?
+ struct dma &dma_channel = m_dma_channel[channel];
- // 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
- {
- // get access to the bus
- {
- // iogadiag test 7.0265
- u32 mask = 0;
-
- 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;
- }
+ else
+ dma_channel.control &= ~DMA_CTRL_BUSY;
- // 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);
+ // if the channel isn't active yet, make it active and log something
+ if (!dma_channel.dma_active)
+ {
+ 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;
+ }
- m_dma_channel[channel].control |= IOGA_DMA_CTRL_BUSY;
- m_dma_timer->adjust(attotime::from_hz(clock()), channel);
+ // 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());
- return;
- }
- else
- m_dma_channel[channel].control &= ~IOGA_DMA_CTRL_BUSY;
- }
+ // increment addresses and decrement count
+ dma_channel.real_address++;
+ dma_channel.virtual_address++;
+ dma_channel.transfer_count--;
+ }
- 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;
- }
+ // 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);
- while (m_dma_channel[channel].transfer_count)
+ if (channel == IOGA_DMA_FLOPPY)
{
- // transfer from memory to the device
- m_dma_channel[channel].device_w(m_memory_space->read_byte(m_dma_channel[channel].real_address));
+ LOG_DMA(channel, "dma: asserting fdc terminal count line\n");
- // increment addresses and decrement count
- m_dma_channel[channel].real_address++;
- m_dma_channel[channel].virtual_address++;
- m_dma_channel[channel].transfer_count--;
+ m_fdc_tc_func(ASSERT_LINE);
+ m_fdc_tc_func(CLEAR_LINE);
}
- // 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;
-} \ No newline at end of file
+}
+
+WRITE16_MEMBER(interpro_ioga_device::arbctl_w)
+{
+ LOG_DMA(31, "dma: arbctl = 0x%04x (%s)\n", data, machine().describe_context());
+
+ m_arbctl = data;
+}
diff --git a/src/mame/machine/interpro_ioga.h b/src/mame/machine/interpro_ioga.h
index 3af18cf395e..7102d551a77 100644
--- a/src/mame/machine/interpro_ioga.h
+++ b/src/mame/machine/interpro_ioga.h
@@ -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;