mirror of
https://github.com/holub/mame
synced 2025-07-02 16:49:22 +03:00
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.
This commit is contained in:
parent
cd48a8d419
commit
26412cd829
@ -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));
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user