diff options
author | 2019-01-06 22:20:47 -0500 | |
---|---|---|
committer | 2019-01-06 22:20:47 -0500 | |
commit | 26412cd8292a30ce81d4db3685c4e204a8996d1a (patch) | |
tree | 6dbd1313392641df85e69c2159f23ad8fb6d6577 | |
parent | cd48a8d4190501ee91630df72c58b1b28773833e (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.
-rw-r--r-- | src/mame/drivers/decstation.cpp | 16 | ||||
-rw-r--r-- | src/mame/machine/decioga.cpp | 37 | ||||
-rw-r--r-- | src/mame/machine/decioga.h | 12 |
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; |