summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
author arbee <rb6502@users.noreply.github.com>2019-01-06 22:20:47 -0500
committer arbee <rb6502@users.noreply.github.com>2019-01-06 22:20:47 -0500
commit26412cd8292a30ce81d4db3685c4e204a8996d1a (patch)
tree6dbd1313392641df85e69c2159f23ad8fb6d6577 /src
parentcd48a8d4190501ee91630df72c58b1b28773833e (diff)
ds5k133: Preliminary LANCE DMA hookup [R. Belmont]
If you can parse this comment from the Linux driver, please help :) * The IOASIC LANCE devices use a shared memory region. This region * as seen from the CPU is (max) 128 kB long and has to be on an 128 kB * boundary. The LANCE sees this as a 64 kB long continuous memory * region. * * The LANCE's DMA address is used as an index in this buffer and DMA * takes place in bursts of eight 16-bit words which are packed into * four 32-bit words by the IOASIC. This leads to a strange padding: * 16 bytes of valid data followed by a 16 byte gap :-(. I get the first part, which is that since the DMA engine works in words and LANCE works in half-words that each half-word for LANCE is packed into one word from the CPU's point of view. The second part not so much.
Diffstat (limited to 'src')
-rw-r--r--src/mame/drivers/decstation.cpp16
-rw-r--r--src/mame/machine/decioga.cpp37
-rw-r--r--src/mame/machine/decioga.h12
3 files changed, 62 insertions, 3 deletions
diff --git a/src/mame/drivers/decstation.cpp b/src/mame/drivers/decstation.cpp
index c75668f2e13..02ea55b3b86 100644
--- a/src/mame/drivers/decstation.cpp
+++ b/src/mame/drivers/decstation.cpp
@@ -103,6 +103,7 @@ public:
protected:
DECLARE_READ_LINE_MEMBER(brcond0_r) { return ASSERT_LINE; }
DECLARE_WRITE_LINE_MEMBER(ioga_irq_w);
+ DECLARE_WRITE_LINE_MEMBER(dz_irq_w);
DECLARE_READ32_MEMBER(cfb_r);
DECLARE_WRITE32_MEMBER(cfb_w);
@@ -238,9 +239,9 @@ READ32_MEMBER(decstation_state::cfb_r)
{
uint32_t addr = offset << 2;
-// logerror("cfb_r: reading at %x\n", addr);
+ //logerror("cfb_r: reading at %x\n", addr);
- if (addr < 0x800000)
+ if (addr < 0x80000)
{
return m_vrom_ptr[addr>>2] & 0xff;
}
@@ -551,6 +552,11 @@ WRITE_LINE_MEMBER(decstation_state::ioga_irq_w)
m_maincpu->set_input_line(INPUT_LINE_IRQ3, state);
}
+WRITE_LINE_MEMBER(decstation_state::dz_irq_w)
+{
+ m_maincpu->set_input_line(INPUT_LINE_IRQ2, state);
+}
+
void decstation_state::machine_start()
{
if (m_vrom)
@@ -562,6 +568,8 @@ void decstation_state::machine_start()
void decstation_state::machine_reset()
{
+ m_ioga->set_dma_space(&m_maincpu->space(AS_PROGRAM));
+
m_copy_src = 1;
m_entry = 0;
m_stage = 0;
@@ -662,6 +670,8 @@ MACHINE_CONFIG_START(decstation_state::kn01)
m_scantimer->configure_scanline(FUNC(decstation_state::scanline_timer), "screen", 0, 1);
DC7085(config, m_dz, 0);
+ m_dz->int_cb().set(FUNC(decstation_state::dz_irq_w));
+ m_dz->ch1_tx_cb().set("dc7085:ch1", FUNC(dc7085_channel::rx_w));
AM79C90(config, m_lance, XTAL(12'500'000));
@@ -684,6 +694,8 @@ MACHINE_CONFIG_START(decstation_state::kn02ba)
AM79C90(config, m_lance, XTAL(12'500'000));
m_lance->intr_out().set("ioga", FUNC(dec_ioga_device::lance_irq_w));
+ m_lance->dma_in().set("ioga", FUNC(dec_ioga_device::lance_dma_r));
+ m_lance->dma_out().set("ioga", FUNC(dec_ioga_device::lance_dma_w));
DECSTATION_IOGA(config, m_ioga, XTAL(12'500'000));
m_ioga->irq_out().set(FUNC(decstation_state::ioga_irq_w));
diff --git a/src/mame/machine/decioga.cpp b/src/mame/machine/decioga.cpp
index 3c039a9b6e0..46c2a204e10 100644
--- a/src/mame/machine/decioga.cpp
+++ b/src/mame/machine/decioga.cpp
@@ -10,10 +10,18 @@
#include "emu.h"
#include "decioga.h"
+#define LOG_DMA (1U << 0)
+#define LOG_LANCE_DMA (1U << 1)
+
+#define VERBOSE (LOG_DMA|LOG_LANCE_DMA)
+
+#include "logmacro.h"
+
DEFINE_DEVICE_TYPE(DECSTATION_IOGA, dec_ioga_device, "decioga", "DECstation I/O Gate Array")
void dec_ioga_device::map(address_map &map)
{
+ map(0x040000, 0x0400ff).rw(FUNC(dec_ioga_device::dmaptr_r), FUNC(dec_ioga_device::dmaptr_w));
map(0x040100, 0x040103).rw(FUNC(dec_ioga_device::csr_r), FUNC(dec_ioga_device::csr_w));
map(0x040110, 0x040113).rw(FUNC(dec_ioga_device::intr_r), FUNC(dec_ioga_device::intr_w));
map(0x040120, 0x040123).rw(FUNC(dec_ioga_device::imsk_r), FUNC(dec_ioga_device::imsk_w));
@@ -91,6 +99,17 @@ WRITE32_MEMBER(dec_ioga_device::imsk_w)
COMBINE_DATA(&m_imsk);
}
+READ32_MEMBER(dec_ioga_device::dmaptr_r)
+{
+ return m_dmaptrs[offset/4];
+}
+
+WRITE32_MEMBER(dec_ioga_device::dmaptr_w)
+{
+ COMBINE_DATA(&m_dmaptrs[offset/4]);
+ LOGMASKED(LOG_DMA, "DECIOGA: %08x to DMA pointer %x (addr %x)\n", data, offset/4, offset*4);
+}
+
WRITE_LINE_MEMBER(dec_ioga_device::rtc_irq_w)
{
if (state == ASSERT_LINE)
@@ -138,3 +157,21 @@ WRITE_LINE_MEMBER(dec_ioga_device::scc1_irq_w)
}
recalc_irq();
}
+
+// DMA handlers
+void dec_ioga_device::set_dma_space(address_space *space)
+{
+ m_maincpu_space = space;
+}
+
+READ16_MEMBER(dec_ioga_device::lance_dma_r)
+{
+ LOGMASKED(LOG_LANCE_DMA, "lance_dma_r: %08x (phys %08x)\n", offset, (offset<<1) + (m_dmaptrs[2]>>3));
+ return m_maincpu_space->read_word((offset<<1) + (m_dmaptrs[2]>>3));
+}
+
+WRITE16_MEMBER(dec_ioga_device::lance_dma_w)
+{
+ LOGMASKED(LOG_LANCE_DMA, "lance_dma_w: %04x to %08x\n", data, offset);
+ m_maincpu_space->write_word((offset<<1) + (m_dmaptrs[2]>>3), data);
+}
diff --git a/src/mame/machine/decioga.h b/src/mame/machine/decioga.h
index 28e7ce53990..25ec5fe5e40 100644
--- a/src/mame/machine/decioga.h
+++ b/src/mame/machine/decioga.h
@@ -28,6 +28,11 @@ public:
// multiplex irq output
auto irq_out() { return m_irq_out_cb.bind(); }
+ // DMA interface
+ void set_dma_space(address_space *space);
+ DECLARE_READ16_MEMBER(lance_dma_r);
+ DECLARE_WRITE16_MEMBER(lance_dma_w);
+
protected:
virtual void device_start() override;
virtual void device_reset() override;
@@ -38,9 +43,14 @@ protected:
DECLARE_WRITE32_MEMBER(intr_w);
DECLARE_READ32_MEMBER(imsk_r);
DECLARE_WRITE32_MEMBER(imsk_w);
+ DECLARE_READ32_MEMBER(dmaptr_r);
+ DECLARE_WRITE32_MEMBER(dmaptr_w);
+
+ address_space *m_maincpu_space;
private:
- uint32_t m_csr, m_intr, m_imsk;
+ u32 m_csr, m_intr, m_imsk;
+ u32 m_dmaptrs[0x10];
devcb_write_line m_irq_out_cb;