diff options
Diffstat (limited to 'src/devices/machine/dmac.cpp')
-rw-r--r-- | src/devices/machine/dmac.cpp | 644 |
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); } |