summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/dmac.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/dmac.cpp')
-rw-r--r--src/devices/machine/dmac.cpp644
1 files changed, 357 insertions, 287 deletions
diff --git a/src/devices/machine/dmac.cpp b/src/devices/machine/dmac.cpp
index fd939c981c4..06574584585 100644
--- a/src/devices/machine/dmac.cpp
+++ b/src/devices/machine/dmac.cpp
@@ -1,428 +1,498 @@
-// license:GPL-2.0+
-// copyright-holders:Dirk Best
+// license: GPL-2.0+
+// copyright-holders: Dirk Best
/***************************************************************************
DMAC
DMA controller used in Amiga systems
-BOARDS:
- CBM A590/A2091 HD controller: Prod=514/3($202/$3) (@$e90000 64K)
- CBM A2052/58. RAM I 590/2091.RAM Prod=514/10($202/$a) (@$200000 2meg mem)
+ Notes:
+ - Part numbers: 390563-01 and 390563-02
+ - Emulated is the old variant
+
+ TODO:
+ - SCSI
+ - Support newer variant
+ - DAWR
+ - Data corruption when installing WB31
+ - FIFO?
***************************************************************************/
#include "emu.h"
#include "dmac.h"
-#define VERBOSE 1
-#include "logmacro.h"
-
+#define LOG_REGS (1 << 1)
+#define LOG_INT (1 << 2)
+#define LOG_DMA (1 << 3)
-//**************************************************************************
-// DEVICE DEFINITIONS
-//**************************************************************************
+#define VERBOSE (LOG_GENERAL | LOG_REGS | LOG_INT)
-DEFINE_DEVICE_TYPE(AMIGA_DMAC, amiga_dmac_device, "amiga_dmac", "Amiga DMAC DMA Controller")
+#include "logmacro.h"
//**************************************************************************
-// LIVE DEVICE
+// TYPE DEFINITIONS
//**************************************************************************
-//-------------------------------------------------
-// amiga_dmac_device - constructor
-//-------------------------------------------------
+DEFINE_DEVICE_TYPE(AMIGA_DMAC, amiga_dmac_device, "amiga_dmac", "Amiga DMAC DMA Controller")
amiga_dmac_device::amiga_dmac_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, AMIGA_DMAC, tag, owner, clock),
amiga_autoconfig(),
- m_cfgout_handler(*this),
- m_int_handler(*this),
- m_xdack_handler(*this),
- m_scsi_read_handler(*this, 0),
- m_scsi_write_handler(*this),
- m_io_read_handler(*this, 0),
- m_io_write_handler(*this),
+ m_cfgout_cb(*this),
+ m_int_cb(*this),
+ m_css_read_cb(*this, 0),
+ m_css_write_cb(*this),
+ m_csx0_read_cb(*this, 0),
+ m_csx0_write_cb(*this),
+ m_csx1_read_cb(*this, 0),
+ m_csx1_write_cb(*this),
+ m_sdack_read_cb(*this, 0),
+ m_sdack_write_cb(*this),
+ m_xdack_read_cb(*this, 0),
+ m_xdack_write_cb(*this),
+ m_rom(*this, finder_base::DUMMY_TAG),
m_space(nullptr),
- m_rom(nullptr),
m_ram(nullptr),
m_ram_size(-1),
- m_configured(false),
- m_rst(-1),
m_cntr(0),
m_istr(0),
m_wtc(0),
m_acr(0),
- m_dma_active(false)
+ m_intx(false),
+ m_sdreq(false),
+ m_xdreq(false),
+ m_autoconfig_dmac_done(false),
+ m_autoconfig_ram_done(false),
+ m_dmac_address(0),
+ m_ram_address(0)
{
}
-//-------------------------------------------------
-// device_start - device-specific startup
-//-------------------------------------------------
-void amiga_dmac_device::device_start()
+//**************************************************************************
+// ADDRESS MAPS
+//**************************************************************************
+
+void amiga_dmac_device::map(address_map &map)
{
+ map(0x0000, 0x003f).rw(FUNC(amiga_dmac_device::autoconfig_r), FUNC(amiga_dmac_device::autoconfig_w));
+ map(0x0040, 0x0041).r(FUNC(amiga_dmac_device::istr_r));
+ map(0x0042, 0x0043).rw(FUNC(amiga_dmac_device::cntr_r), FUNC(amiga_dmac_device::cntr_w));
+ map(0x0080, 0x0081).w(FUNC(amiga_dmac_device::wtc_hi_w));
+ map(0x0082, 0x0083).w(FUNC(amiga_dmac_device::wtc_lo_w));
+ map(0x0084, 0x0085).w(FUNC(amiga_dmac_device::acr_hi_w));
+ map(0x0086, 0x0087).w(FUNC(amiga_dmac_device::acr_lo_w));
+ map(0x008e, 0x008f).w(FUNC(amiga_dmac_device::dawr_w));
+ map(0x0090, 0x0093).rw(FUNC(amiga_dmac_device::css_r), FUNC(amiga_dmac_device::css_w)).umask16(0x00ff);
+ map(0x00a0, 0x00a7).rw(FUNC(amiga_dmac_device::csx0_r), FUNC(amiga_dmac_device::csx0_w)).umask16(0x00ff);
+ map(0x00c0, 0x00c7).rw(FUNC(amiga_dmac_device::csx1_r), FUNC(amiga_dmac_device::csx1_w)).umask16(0x00ff);
+ map(0x00e0, 0x00e1).rw(FUNC(amiga_dmac_device::st_dma_r), FUNC(amiga_dmac_device::st_dma_w));
+ map(0x00e2, 0x00e3).rw(FUNC(amiga_dmac_device::sp_dma_r), FUNC(amiga_dmac_device::sp_dma_w));
+ map(0x00e4, 0x00e5).rw(FUNC(amiga_dmac_device::cint_r), FUNC(amiga_dmac_device::cint_w));
+ map(0x00e8, 0x00e9).rw(FUNC(amiga_dmac_device::flush_r), FUNC(amiga_dmac_device::flush_w));
}
-//-------------------------------------------------
-// device_reset - device-specific reset
-//-------------------------------------------------
-void amiga_dmac_device::device_reset()
+//**************************************************************************
+// MACHINE EMULATION
+//**************************************************************************
+
+void amiga_dmac_device::device_start()
{
- // fifo empty
- m_istr |= ISTR_FE_FLG;
+ m_dma_timer = timer_alloc(FUNC(amiga_dmac_device::update_dma), this);
+
+ // register for save states
+ save_item(NAME(m_ram_size));
+ save_item(NAME(m_cntr));
+ save_item(NAME(m_istr));
+ save_item(NAME(m_wtc));
+ save_item(NAME(m_acr));
+ save_item(NAME(m_intx));
+ save_item(NAME(m_sdreq));
+ save_item(NAME(m_xdreq));
+ save_item(NAME(m_autoconfig_dmac_done));
+ save_item(NAME(m_autoconfig_ram_done));
+ save_item(NAME(m_dmac_address));
+ save_item(NAME(m_ram_address));
}
-void amiga_dmac_device::autoconfig_base_address(offs_t address)
+void amiga_dmac_device::update_interrupts()
{
- LOG("%s('%s'): autoconfig_base_address received: 0x%06x\n", shortname(), basetag(), address);
+ // check external interrupt line
+ if (m_intx)
+ m_istr |= ISTR_INTS;
+ else
+ m_istr &= ~ISTR_INTS;
- if (!m_configured && m_ram_size > 0)
+ if (m_istr & ISTR_INT_MASK)
{
- LOG("-> installing ram (%d bytes)\n", m_ram_size);
-
- // install access to the ram space
- if (address)
- m_space->install_ram(address, address + (m_ram_size - 1), m_ram);
-
- // prepare autoconfig for main device
- autoconfig_board_size(BOARD_SIZE_64K);
- autoconfig_product(0x03); // or 0x02 for rev 1
- autoconfig_rom_vector(0x2000);
- autoconfig_rom_vector_valid(true);
- autoconfig_link_into_memory(false);
- autoconfig_multi_device(false);
+ LOGMASKED(LOG_INT, "Found active interrupt: %02x\n", m_istr);
- // first device configured
- m_configured = true;
+ m_istr |= ISTR_INT_F;
+ m_istr |= ISTR_INT_P;
}
else
{
- LOG("-> installing dmac\n");
+ LOGMASKED(LOG_INT, "No active interrupt\n");
- // internal dmac registers
- m_space->install_read_handler(address, address + 0xff,
- read16_delegate(*this, FUNC(amiga_dmac_device::register_read)), 0xffff);
- m_space->install_write_handler(address, address + 0xff,
- write16s_delegate(*this, FUNC(amiga_dmac_device::register_write)), 0xffff);
-
- // install access to the rom space
- if (m_rom)
- {
- m_space->install_rom(address + 0x2000, address + 0x7fff, m_rom + 0x2000);
- m_space->install_rom(address + 0x8000, address + 0xffff, m_rom);
- }
+ m_istr &= ~ISTR_INT_F;
+ m_istr &= ~ISTR_INT_P;
+ }
- // stop responding to autoconfig
- m_space->unmap_readwrite(0xe80000, 0xe8007f);
+ // clear pending if interrupts disabled
+ if (!(m_cntr & CNTR_INTEN))
+ {
+ LOGMASKED(LOG_INT, "Interrupts are disabled\n");
- // we're done
- m_cfgout_handler(0);
+ m_istr &= ~ISTR_INT_P;
}
+
+ // finally update interrupt line
+ m_int_cb((m_istr & ISTR_INT_P) ? 1 : 0);
}
-void amiga_dmac_device::check_interrupts()
+TIMER_CALLBACK_MEMBER(amiga_dmac_device::update_dma)
{
- // interrupts enabled?
- if (m_cntr & CNTR_INTEN)
+ if (m_sdreq && (m_cntr & CNTR_PDMD))
{
- // any interrupts pending?
- if (m_istr & ISTR_INT_MASK)
- m_istr |= ISTR_INT_P;
- else
- m_istr &= ~ISTR_INT_P;
+ LOGMASKED(LOG_DMA, "scsi dma, acr=%08x, wtc=%08x\n", m_acr, m_wtc);
}
- else
- m_istr &= ~ISTR_INT_P;
+ else if (m_xdreq && !(m_cntr & CNTR_PDMD))
+ {
+ LOGMASKED(LOG_DMA, "xt dma, acr=%08x, wtc=%08x\n", m_acr, m_wtc);
- // finally update interrupt line
- m_int_handler((m_istr & ISTR_INT_P) ? 1 : 0);
+ if (m_cntr & CNTR_DDIR)
+ {
+ // host -> peripheral
+ uint8_t data = m_space->read_byte(m_acr);
+ LOGMASKED(LOG_DMA, "Write to device: %02x\n", data);
+ m_xdack_write_cb(data);
+ }
+ else
+ {
+ // peripheral -> host
+ uint8_t data = m_xdack_read_cb();
+ LOGMASKED(LOG_DMA, "Read from device: %02x\n", data);
+ m_space->write_byte(m_acr, data);
+ }
+
+ m_acr++;
+
+ if (m_cntr & CNTR_TCEN)
+ {
+ // we count words
+ if ((m_acr & 1) == 0)
+ {
+ if (--m_wtc == 0)
+ {
+ LOGMASKED(LOG_DMA, "Terminal count\n");
+
+ m_istr |= ISTR_E_INT;
+ update_interrupts();
+ }
+ }
+ }
+ }
}
void amiga_dmac_device::stop_dma()
{
- m_dma_active = false;
+ m_dma_timer->adjust(attotime::never);
+
m_istr &= ~ISTR_E_INT;
- check_interrupts();
+ update_interrupts();
}
void amiga_dmac_device::start_dma()
{
- m_dma_active = true;
+ m_dma_timer->adjust(attotime::zero, 0, clocks_to_attotime(1));
}
-
-//**************************************************************************
-// IMPLEMENTATION
-//**************************************************************************
-
-uint16_t amiga_dmac_device::register_read(address_space &space, offs_t offset, uint16_t mem_mask)
+uint16_t amiga_dmac_device::autoconfig_r(offs_t offset, uint16_t mem_mask)
{
- uint16_t data = 0xffff;
+ return autoconfig_read(*m_space, offset, mem_mask);
+}
- // autoconfig handles this
- if (offset < 0x20)
- return autoconfig_read(space, offset, mem_mask);
+void amiga_dmac_device::autoconfig_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+{
+ autoconfig_write(*m_space, data, mem_mask);
+}
- switch (offset)
- {
- case 0x20:
- data = m_istr;
+uint16_t amiga_dmac_device::istr_r(offs_t offset, uint16_t mem_mask)
+{
+ return m_istr;
+}
- // reading clears fifo status (?)
- m_istr &= ~0x0f;
- check_interrupts();
+uint16_t amiga_dmac_device::cntr_r(offs_t offset, uint16_t mem_mask)
+{
+ return m_cntr;
+}
- LOG("%s('%s'): read istr %04x [mask = %04x]\n", shortname(), basetag(), data, mem_mask);
+void amiga_dmac_device::cntr_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+{
+ LOGMASKED(LOG_REGS, "cntr_w: %04x & %04x\n", data, mem_mask);
- break;
+ COMBINE_DATA(&m_cntr);
+ update_interrupts();
+}
- case 0x21:
- data = m_cntr;
+void amiga_dmac_device::wtc_hi_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+{
+ LOGMASKED(LOG_REGS, "wtc_hi_w: %04x & %04x\n", data, mem_mask);
- LOG("%s('%s'): read cntr %04x [mask = %04x]\n", shortname(), basetag(), data, mem_mask);
+ m_wtc &= (~(uint32_t) mem_mask) << 16 | 0x0000ffff;
+ m_wtc |= ((uint32_t) data & mem_mask) << 16;
+}
- break;
+void amiga_dmac_device::wtc_lo_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+{
+ LOGMASKED(LOG_REGS, "wtc_lo_w: %04x & %04x\n", data, mem_mask);
- case 0x48:
- case 0x49:
- data = m_scsi_read_handler(offset);
+ m_wtc &= 0xffff0000 & (~mem_mask);
+ m_wtc |= data & mem_mask;
+}
- LOG("%s('%s'): read scsi register @ %02x %04x [mask = %04x]\n", shortname(), basetag(), offset, data, mem_mask);
+void amiga_dmac_device::acr_hi_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+{
+ LOGMASKED(LOG_REGS, "acr_hi_w: %04x & %04x\n", data, mem_mask);
- break;
+ m_acr &= (~(uint32_t) mem_mask) << 16 | 0x0000ffff;
+ m_acr |= ((uint32_t) data & mem_mask) << 16;
+}
- case 0x50:
- case 0x51:
- case 0x52:
- case 0x53:
- LOG("%s('%s'): read xt register @ %02x %04x [mask = %04x]\n", shortname(), basetag(), offset, data, mem_mask);
+void amiga_dmac_device::acr_lo_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+{
+ LOGMASKED(LOG_REGS, "acr_lo_w: %04x & %04x\n", data, mem_mask);
- break;
+ m_acr &= 0xffff0000 & (~mem_mask);
+ m_acr |= (data & mem_mask) & 0xfffc; // 0xfffe for rev 2
+}
- case 0x70:
- LOG("%s('%s'): read dma start strobe %04x [mask = %04x]\n", shortname(), basetag(), data, mem_mask);
+void amiga_dmac_device::dawr_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+{
+ LOGMASKED(LOG_REGS, "dawr_w: %04x & %04x\n", data, mem_mask);
+}
- start_dma();
- break;
+// chip select lines
+uint8_t amiga_dmac_device::css_r(offs_t offset) { return m_css_read_cb(offset); }
+void amiga_dmac_device::css_w(offs_t offset, uint8_t data) { m_css_write_cb(offset, data); }
+uint8_t amiga_dmac_device::csx0_r(offs_t offset) { return m_csx0_read_cb(offset); }
+void amiga_dmac_device::csx0_w(offs_t offset, uint8_t data) { m_csx0_write_cb(offset, data); }
+uint8_t amiga_dmac_device::csx1_r(offs_t offset) { return m_csx1_read_cb(offset); }
+void amiga_dmac_device::csx1_w(offs_t offset, uint8_t data) { m_csx1_write_cb(offset, data); }
- case 0x71:
- LOG("%s('%s'): read dma stop strobe %04x [mask = %04x]\n", shortname(), basetag(), data, mem_mask);
+uint16_t amiga_dmac_device::st_dma_r(offs_t offset, uint16_t mem_mask)
+{
+ LOGMASKED(LOG_DMA, "st_dma_r\n");
- stop_dma();
- break;
+ start_dma();
+ return 0;
+}
- case 0x72:
- LOG("%s('%s'): read clear irq strobe %04x [mask = %04x]\n", shortname(), basetag(), data, mem_mask);
+void amiga_dmac_device::st_dma_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+{
+ LOGMASKED(LOG_DMA, "st_dma_w\n");
- // clear all interrupts
- m_istr &= ~ISTR_INT_MASK;
- check_interrupts();
- break;
+ start_dma();
+}
- case 0x74:
- LOG("%s('%s'): read flush fifo strobe %04x [mask = %04x]\n", shortname(), basetag(), data, mem_mask);
+uint16_t amiga_dmac_device::sp_dma_r(offs_t offset, uint16_t mem_mask)
+{
+ LOGMASKED(LOG_DMA, "sp_dma_r\n");
- m_istr |= ISTR_FE_FLG;
- break;
+ stop_dma();
+ return 0;
+}
- default:
- LOG("%s('%s'): register_read %04x @ %02x [mask = %04x]\n", shortname(), basetag(), data, offset, mem_mask);
- }
+void amiga_dmac_device::sp_dma_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+{
+ LOGMASKED(LOG_REGS, "sp_dma_w\n");
- return data;
+ stop_dma();
}
-void amiga_dmac_device::register_write(offs_t offset, uint16_t data, uint16_t mem_mask)
+uint16_t amiga_dmac_device::cint_r(offs_t offset, uint16_t mem_mask)
{
- switch (offset)
- {
- case 0x21:
- LOG("%s('%s'): write cntr %04x [mask = %04x]\n", shortname(), basetag(), data, mem_mask);
+ LOGMASKED(LOG_INT, "cint_r\n");
- m_cntr = data;
- check_interrupts();
- break;
+ m_istr = 0;
+ update_interrupts();
- case 0x40:
- LOG("%s('%s'): write wtc hi %04x [mask = %04x]\n", shortname(), basetag(), data, mem_mask);
+ return 0;
+}
- m_wtc &= 0x0000ffff;
- m_wtc |= ((uint32_t) data) << 16;
- break;
+void amiga_dmac_device::cint_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+{
+ LOGMASKED(LOG_INT, "cint_w\n");
- case 0x41:
- LOG("%s('%s'): write wtc lo %04x [mask = %04x]\n", shortname(), basetag(), data, mem_mask);
+ m_istr = 0;
+ update_interrupts();
+}
- m_wtc &= 0xffff0000;
- m_wtc |= data;
- break;
+uint16_t amiga_dmac_device::flush_r(offs_t offset, uint16_t mem_mask)
+{
+ LOGMASKED(LOG_REGS, "flush_r\n");
- case 0x42:
- LOG("%s('%s'): write acr hi %04x [mask = %04x]\n", shortname(), basetag(), data, mem_mask);
+ return 0;
+}
- m_acr &= 0x0000ffff;
- m_acr |= ((uint32_t) data) << 16;
- break;
+void amiga_dmac_device::flush_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+{
+ LOGMASKED(LOG_REGS, "flush_w\n");
+}
- case 0x43:
- LOG("%s('%s'): write acr lo %04x [mask = %04x]\n", shortname(), basetag(), data, mem_mask);
+void amiga_dmac_device::ramsz_w(int state)
+{
+ LOG("ramsz_w: %d\n", state);
- m_acr &= 0xffff0000;
- m_acr |= data;
- break;
+ switch (state)
+ {
+ case 0: m_ram_size = 0x000000; break;
+ case 1: m_ram_size = 0x080000; break;
+ case 2: m_ram_size = 0x100000; break;
+ case 3: m_ram_size = 0x200000; break;
+ }
+}
- case 0x47:
- LOG("%s('%s'): write dawr %04x [mask = %04x]\n", shortname(), basetag(), data, mem_mask);
- break;
+void amiga_dmac_device::rst_w(int state)
+{
+ if (state == 0)
+ {
+ if (m_autoconfig_dmac_done)
+ {
+ LOG("unmapping dmac, base = %06x\n", m_dmac_address);
+ m_space->unmap_readwrite(m_dmac_address, m_dmac_address + 0xffff);
- case 0x48:
- case 0x49:
- LOG("%s('%s'): write scsi register @ %02x %04x [mask = %04x]\n", shortname(), basetag(), offset, data, mem_mask);
+ m_autoconfig_dmac_done = false;
+ }
- m_scsi_write_handler(offset, data, 0xff);
- break;
+ if (m_autoconfig_ram_done)
+ {
+ LOG("unmapping ram, base = %06x, size = %06x\n", m_ram_address, m_ram_size);
+ m_space->unmap_readwrite(m_ram_address, m_ram_address + m_ram_size - 1);
- case 0x50:
- case 0x51:
- case 0x52:
- case 0x53:
- LOG("%s('%s'): write xt register @ %02x %04x [mask = %04x]\n", shortname(), basetag(), offset, data, mem_mask);
- break;
+ m_ram_size = 0;
+ m_autoconfig_ram_done = false;
+ }
- case 0x70:
- LOG("%s('%s'): write dma start strobe %04x [mask = %04x]\n", shortname(), basetag(), data, mem_mask);
+ m_istr = 0;
+ m_istr |= ISTR_FE_FLG; // fifo empty
+ m_cntr = 0;
+ }
+}
- start_dma();
- break;
+void amiga_dmac_device::intx_w(int state)
+{
+ LOGMASKED(LOG_INT, "intx_w: %d\n", state);
- case 0x71:
- LOG("%s('%s'): write dma stop strobe %04x [mask = %04x]\n", shortname(), basetag(), data, mem_mask);
+ m_intx = bool(state);
+ update_interrupts();
+}
- stop_dma();
- break;
+void amiga_dmac_device::sdreq_w(int state)
+{
+ LOGMASKED(LOG_DMA, "sdreq_w: %d\n", state);
- case 0x72:
- LOG("%s('%s'): write clear irq strobe %04x [mask = %04x]\n", shortname(), basetag(), data, mem_mask);
+ m_sdreq = bool(state);
+}
- // clear all interrupts
- m_istr &= ~ISTR_INT_MASK;
- check_interrupts();
- break;
+void amiga_dmac_device::xdreq_w(int state)
+{
+ LOGMASKED(LOG_DMA, "xdreq_w: %d\n", state);
- case 0x74:
- LOG("%s('%s'): write flush fifo strobe %04x [mask = %04x]\n", shortname(), basetag(), data, mem_mask);
+ m_xdreq = bool(state);
+}
- m_istr |= ISTR_FE_FLG;
- break;
- default:
- LOG("%s('%s'): write %04x @ %02x [mask = %04x]\n", shortname(), basetag(), data, offset, mem_mask);
- }
-}
+//**************************************************************************
+// AUTOCONFIG
+//**************************************************************************
-// this signal tells us to expose our autoconfig values
-void amiga_dmac_device::configin_w(int state)
+void amiga_dmac_device::autoconfig_base_address(offs_t address)
{
- LOG("%s('%s'): configin_w (%d)\n", shortname(), basetag(), state);
+ LOG("autoconfig_base_address received: 0x%06x\n", address);
- if (state == 0 && !m_configured)
+ if (!m_autoconfig_ram_done && m_ram_size > 0)
{
- // common autoconfig values
- autoconfig_board_type(BOARD_TYPE_ZORRO2);
- autoconfig_manufacturer(0x0202);
- autoconfig_serial(0x00000000);
- autoconfig_8meg_preferred(false);
- autoconfig_can_shutup(true);
+ LOG("-> installing dmac memory, size = %06x\n", m_ram_size);
- // if we have ram, configure it first
- if (m_ram_size > 0)
- {
- // product id 10
- autoconfig_product(0x0a);
+ m_space->install_ram(address, address + m_ram_size - 1, m_ram);
- // board size
- switch (m_ram_size)
- {
- case 0x080000: autoconfig_board_size(BOARD_SIZE_512K); break;
- case 0x100000: autoconfig_board_size(BOARD_SIZE_1M); break;
- case 0x200000: autoconfig_board_size(BOARD_SIZE_2M); break;
- }
+ m_ram_address = address;
+ m_autoconfig_ram_done = true;
- // no rom and link into free memory
- autoconfig_rom_vector_valid(false);
- autoconfig_link_into_memory(true);
+ // configure next
+ configin_w(0);
+ }
+ else
+ {
+ LOG("-> installing dmac registers\n");
- // the main device follows
- autoconfig_multi_device(true);
- }
- else
+ m_space->install_device(address, address + 0x7fff, *this, &amiga_dmac_device::map);
+
+ if (m_rom)
{
- // just setup autoconfig for the main device
- autoconfig_board_size(BOARD_SIZE_64K);
- autoconfig_product(0x03); // or 0x02 for rev 1
- autoconfig_rom_vector(0x2000);
- autoconfig_rom_vector_valid(true);
- autoconfig_link_into_memory(false);
-
- // no more devices after this
- autoconfig_multi_device(false);
+ m_space->install_rom(address + 0x2000, address + 0x7fff, m_rom->base() + 0x2000);
+ m_space->install_rom(address + 0x8000, address + 0xffff, m_rom->base());
}
- // install autoconfig handler
- m_space->install_readwrite_handler(0xe80000, 0xe8007f,
- read16_delegate(*this, FUNC(amiga_autoconfig::autoconfig_read)),
- write16_delegate(*this, FUNC(amiga_autoconfig::autoconfig_write)), 0xffff);
- }
-}
+ m_space->unmap_readwrite(0xe80000, 0xe8007f);
-// this sets the ram size depending on the line voltage
-void amiga_dmac_device::ramsz_w(int state)
-{
- LOG("%s('%s'): ramsz_w (%d)\n", shortname(), basetag(), state);
+ m_dmac_address = address;
+ m_autoconfig_dmac_done = true;
- switch (state)
- {
- case 0: m_ram_size = 0x000000; break;
- case 1: m_ram_size = 0x080000; break;
- case 2: m_ram_size = 0x100000; break;
- case 3: m_ram_size = 0x200000; break;
+ // we're done
+ m_cfgout_cb(0);
}
}
-// reset the device
-void amiga_dmac_device::rst_w(int state)
+void amiga_dmac_device::configin_w(int state)
{
- LOG("%s('%s'): rst_w (%d)\n", shortname(), basetag(), state);
+ if (state != 0)
+ return;
- if (m_rst == 1 && state == 0)
- device_reset();
-
- m_rst = state;
-}
-
-// external interrupt
-void amiga_dmac_device::intx_w(int state)
-{
- LOG("%s('%s'): intx_w (%d)\n", shortname(), basetag(), state);
+ if (!m_autoconfig_ram_done && m_ram_size > 0)
+ {
+ LOG("autoconfig for memory\n");
- if (state)
- m_istr |= ISTR_INTS;
+ // setup autoconfig for memory
+ autoconfig_board_type(BOARD_TYPE_ZORRO2);
+ switch (m_ram_size)
+ {
+ case 0x080000: autoconfig_board_size(BOARD_SIZE_512K); break;
+ case 0x100000: autoconfig_board_size(BOARD_SIZE_1M); break;
+ case 0x200000: autoconfig_board_size(BOARD_SIZE_2M); break;
+ }
+ autoconfig_link_into_memory(true);
+ autoconfig_rom_vector_valid(false);
+ autoconfig_multi_device(true);
+ autoconfig_8meg_preferred(false);
+ autoconfig_can_shutup(true);
+ autoconfig_product(10);
+ autoconfig_manufacturer(514);
+ autoconfig_serial(0x00000000);
+ }
else
- m_istr &= ~ISTR_INTS;
-
- check_interrupts();
-}
-
-// data request
-void amiga_dmac_device::xdreq_w(int state)
-{
- LOG("%s('%s'): xdreq_w (%d)\n", shortname(), basetag(), state);
-
- if (m_dma_active)
{
+ LOG("autoconfig for registers\n");
+
+ autoconfig_board_type(BOARD_TYPE_ZORRO2);
+ autoconfig_board_size(BOARD_SIZE_64K);
+ autoconfig_link_into_memory(false);
+ autoconfig_rom_vector(0x2000);
+ autoconfig_rom_vector_valid(true);
+ autoconfig_multi_device(false);
+ autoconfig_8meg_preferred(false);
+ autoconfig_can_shutup(true);
+ autoconfig_product(2); // or 3 for rev 2
+ autoconfig_manufacturer(514);
+ autoconfig_serial(0x00000000);
}
+
+ // install autoconfig handler
+ m_space->install_readwrite_handler(0xe80000, 0xe8007f,
+ read16_delegate(*this, FUNC(amiga_autoconfig::autoconfig_read)),
+ write16_delegate(*this, FUNC(amiga_autoconfig::autoconfig_write)), 0xffff);
}