summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus
diff options
context:
space:
mode:
author Dirk Best <mail@dirk-best.de>2024-11-29 21:03:26 +0100
committer Dirk Best <mail@dirk-best.de>2024-11-29 21:03:26 +0100
commit4f6b319dfe79700043cf3d4327e083644846aca6 (patch)
treed9f9e174200ba4f3230d8b46446edb449bba369c /src/devices/bus
parent8850e57088c05f8ef44f4442cf0605f5b2b7bd9a (diff)
bus/amiga/zorro: Add support for the RIPPLE IDE controller
Diffstat (limited to 'src/devices/bus')
-rw-r--r--src/devices/bus/amiga/zorro/cards.cpp3
-rw-r--r--src/devices/bus/amiga/zorro/ripple.cpp233
-rw-r--r--src/devices/bus/amiga/zorro/ripple.h73
3 files changed, 309 insertions, 0 deletions
diff --git a/src/devices/bus/amiga/zorro/cards.cpp b/src/devices/bus/amiga/zorro/cards.cpp
index 27b5e6afd6b..83f30491bc7 100644
--- a/src/devices/bus/amiga/zorro/cards.cpp
+++ b/src/devices/bus/amiga/zorro/cards.cpp
@@ -16,6 +16,7 @@
#include "a590.h"
#include "action_replay.h"
#include "buddha.h"
+#include "ripple.h"
void a1000_expansion_cards(device_slot_interface &device)
@@ -45,6 +46,7 @@ void zorro2_cards(device_slot_interface &device)
device.option_add("a2091", ZORRO_A2091);
device.option_add("a2232", ZORRO_A2232);
device.option_add("buddha", ZORRO_BUDDHA);
+ device.option_add("ripple", ZORRO_RIPPLE);
}
void zorro3_cards(device_slot_interface &device)
@@ -55,4 +57,5 @@ void zorro3_cards(device_slot_interface &device)
device.option_add("a2091", ZORRO_A2091);
device.option_add("a2232", ZORRO_A2232);
device.option_add("buddha", ZORRO_BUDDHA);
+ device.option_add("ripple", ZORRO_RIPPLE);
}
diff --git a/src/devices/bus/amiga/zorro/ripple.cpp b/src/devices/bus/amiga/zorro/ripple.cpp
new file mode 100644
index 00000000000..39ca1c350da
--- /dev/null
+++ b/src/devices/bus/amiga/zorro/ripple.cpp
@@ -0,0 +1,233 @@
+// license: GPL-2.0+
+// copyright-holders: Dirk Best
+/***************************************************************************
+
+ RIPPLE IDE
+
+ Zorro-II IDE interface for Amiga 2000/3000/4000
+
+ Notes:
+ - See https://github.com/LIV2/RIPPLE-IDE
+ - To enable boot from CD-ROM you need CDFileSystem from OS 3.2.1 or
+ later, then you can issue the command "LoadModule L:CDFileSystem"
+ - If you have the correct version of CDFileSystem you can also flash
+ it to the controller with "lideflash -C L:CDFileSystem"
+
+ TODO:
+ - Verify cs1 access
+
+***************************************************************************/
+
+#include "emu.h"
+#include "ripple.h"
+
+#define VERBOSE 1
+#include "logmacro.h"
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE(ZORRO_RIPPLE, bus::amiga::zorro::ripple_ide_device, "zorro_ripple", "RIPPLE IDE Interface")
+
+namespace bus::amiga::zorro {
+
+ripple_ide_device::ripple_ide_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, ZORRO_RIPPLE, tag, owner, clock),
+ device_zorro2_card_interface(mconfig, *this),
+ m_ata_0(*this, "ata_0"),
+ m_ata_1(*this, "ata_1"),
+ m_flash(*this, "flash")
+{
+}
+
+
+//**************************************************************************
+// ADDRESS MAPS
+//**************************************************************************
+
+void ripple_ide_device::mmio_map(address_map &map)
+{
+ map(0x01000, 0x01fff).rw(FUNC(ripple_ide_device::ide0_cs0_r), FUNC(ripple_ide_device::ide0_cs0_w));
+ map(0x02000, 0x02fff).rw(FUNC(ripple_ide_device::ide1_cs0_r), FUNC(ripple_ide_device::ide1_cs0_w));
+ map(0x05000, 0x05fff).rw(FUNC(ripple_ide_device::ide0_cs1_r), FUNC(ripple_ide_device::ide0_cs1_w));
+ map(0x06000, 0x06fff).rw(FUNC(ripple_ide_device::ide1_cs1_r), FUNC(ripple_ide_device::ide1_cs1_w));
+ map(0x08000, 0x08fff).w(FUNC(ripple_ide_device::bank_select_w));
+ map(0x10000, 0x1ffff).rw(FUNC(ripple_ide_device::banked_flash_r), FUNC(ripple_ide_device::banked_flash_w)).umask16(0xff00);
+}
+
+
+//**************************************************************************
+// MACHINE DEFINITIONS
+//**************************************************************************
+
+void ripple_ide_device::device_add_mconfig(machine_config &config)
+{
+ ATA_INTERFACE(config, m_ata_0).options(ata_devices, nullptr, nullptr, false);
+ ATA_INTERFACE(config, m_ata_1).options(ata_devices, nullptr, nullptr, false);
+
+ SST_39SF010(config, "flash");
+}
+
+
+//**************************************************************************
+// ROM DEFINITIONS
+//**************************************************************************
+
+ROM_START( lide )
+ ROM_REGION(0x20000, "flash", ROMREGION_ERASEFF)
+ ROM_DEFAULT_BIOS("40.8")
+ ROM_SYSTEM_BIOS(0, "40.8", "Release 40.8")
+ ROMX_LOAD("lide_40-8.rom", 0x0000, 0x8000, CRC(3f021472) SHA1(83762ef5a883e5c43ad321eaa03fde7454f70785), ROM_BIOS(0))
+ROM_END
+
+const tiny_rom_entry *ripple_ide_device::device_rom_region() const
+{
+ return ROM_NAME( lide );
+}
+
+
+//**************************************************************************
+// MACHINE EMULATION
+//**************************************************************************
+
+void ripple_ide_device::device_start()
+{
+ // register for save states
+ save_item(NAME(m_base_address));
+ save_item(NAME(m_flash_bank));
+}
+
+void ripple_ide_device::device_reset()
+{
+ m_flash_bank = 0;
+}
+
+void ripple_ide_device::bank_select_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+{
+ if (ACCESSING_BITS_8_15)
+ m_flash_bank = data >> 14;
+}
+
+uint8_t ripple_ide_device::banked_flash_r(offs_t offset)
+{
+ return m_flash->read(m_flash_bank << 15 | offset);
+}
+
+void ripple_ide_device::banked_flash_w(offs_t offset, uint8_t data)
+{
+ m_flash->write(m_flash_bank << 15 | offset, data);
+}
+
+uint16_t ripple_ide_device::ide0_cs0_r(offs_t offset, uint16_t mem_mask)
+{
+ return m_ata_0->cs0_swap_r(offset >> 8, mem_mask);
+}
+
+void ripple_ide_device::ide0_cs0_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+{
+ m_ata_0->cs0_swap_w(offset >> 8, data, mem_mask);
+}
+
+uint16_t ripple_ide_device::ide0_cs1_r(offs_t offset, uint16_t mem_mask)
+{
+ return m_ata_0->cs1_swap_r(offset >> 8, mem_mask);
+}
+
+void ripple_ide_device::ide0_cs1_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+{
+ m_ata_0->cs1_swap_w(offset >> 8, data, mem_mask);
+}
+
+uint16_t ripple_ide_device::ide1_cs0_r(offs_t offset, uint16_t mem_mask)
+{
+ return m_ata_1->cs0_swap_r(offset >> 8, mem_mask);
+}
+
+void ripple_ide_device::ide1_cs0_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+{
+ m_ata_1->cs0_swap_w(offset >> 8, data, mem_mask);
+}
+
+uint16_t ripple_ide_device::ide1_cs1_r(offs_t offset, uint16_t mem_mask)
+{
+ return m_ata_1->cs1_swap_r(offset >> 8, mem_mask);
+}
+
+void ripple_ide_device::ide1_cs1_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+{
+ m_ata_1->cs1_swap_w(offset >> 8, data, mem_mask);
+}
+
+
+//**************************************************************************
+// AUTOCONFIG
+//**************************************************************************
+
+void ripple_ide_device::autoconfig_base_address(offs_t address)
+{
+ LOG("autoconfig_base_address received: 0x%06x\n", address);
+ LOG("-> installing ripple ide\n");
+
+ // save base address so that the tap can reconfigure our space
+ m_base_address = address;
+
+ // stop responding to default autoconfig
+ m_slot->space().unmap_readwrite(0xe80000, 0xe8007f);
+
+ // flash occupies our space until the ide registers are switched in
+ m_slot->space().install_readwrite_handler(address, address + 0x1ffff,
+ emu::rw_delegate(m_flash, FUNC(intelfsh8_device::read)),
+ emu::rw_delegate(m_flash, FUNC(intelfsh8_device::write)), 0xff00);
+
+ // install write tap to handle switching in ide registers
+ m_write_tap.remove();
+ m_write_tap = m_slot->space().install_write_tap(
+ address, address + 0x1ffff,
+ "rom_disable_w",
+ [this] (offs_t offset, uint16_t &data, uint16_t mem_mask)
+ {
+ m_write_tap.remove();
+
+ // ripple registers are now available
+ m_slot->space().install_device(m_base_address, m_base_address + 0x1ffff, *this, &ripple_ide_device::mmio_map);
+
+ // we need to repeat the write here as this tap won't hit it yet
+ // the initial write will instead hit the flash, but it's harmless
+ m_slot->space().write_word(offset, data, mem_mask);
+ },
+ &m_write_tap
+ );
+
+ // we're done
+ m_slot->cfgout_w(0);
+}
+
+void ripple_ide_device::cfgin_w(int state)
+{
+ LOG("configin_w (%d)\n", state);
+
+ if (state == 0)
+ {
+ // setup autoconfig
+ autoconfig_board_type(BOARD_TYPE_ZORRO2);
+ autoconfig_board_size(BOARD_SIZE_128K);
+ autoconfig_link_into_memory(false);
+ autoconfig_rom_vector_valid(true);
+ autoconfig_multi_device(false);
+ autoconfig_8meg_preferred(false);
+ autoconfig_can_shutup(true);
+ autoconfig_product(7);
+ autoconfig_manufacturer(5194);
+ autoconfig_serial(0x00000000);
+ autoconfig_rom_vector(0x0008);
+
+ // install autoconfig handler
+ m_slot->space().install_readwrite_handler(0xe80000, 0xe8007f,
+ read16_delegate(*this, FUNC(amiga_autoconfig::autoconfig_read)),
+ write16_delegate(*this, FUNC(amiga_autoconfig::autoconfig_write)), 0xffff);
+ }
+}
+
+} // namespace bus::amiga::zorro
diff --git a/src/devices/bus/amiga/zorro/ripple.h b/src/devices/bus/amiga/zorro/ripple.h
new file mode 100644
index 00000000000..d967f4c1584
--- /dev/null
+++ b/src/devices/bus/amiga/zorro/ripple.h
@@ -0,0 +1,73 @@
+// license: GPL-2.0+
+// copyright-holders: Dirk Best
+/***************************************************************************
+
+ RIPPLE IDE
+
+ Zorro-II IDE interface for Amiga 2000/3000/4000
+
+***************************************************************************/
+
+#ifndef MAME_BUS_AMIGA_ZORRO_RIPPLE_H
+#define MAME_BUS_AMIGA_ZORRO_RIPPLE_H
+
+#pragma once
+
+#include "zorro.h"
+#include "machine/autoconfig.h"
+#include "machine/intelfsh.h"
+#include "bus/ata/ataintf.h"
+
+namespace bus::amiga::zorro {
+
+class ripple_ide_device : public device_t, public device_zorro2_card_interface, public amiga_autoconfig
+{
+public:
+ ripple_ide_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
+ virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD;
+
+ virtual void device_start() override ATTR_COLD;
+ virtual void device_reset() override ATTR_COLD;
+
+ // device_zorro2_card_interface overrides
+ virtual void cfgin_w(int state) override;
+
+ // amiga_autoconfig overrides
+ virtual void autoconfig_base_address(offs_t address) override;
+
+private:
+ void mmio_map(address_map &map) ATTR_COLD;
+
+ // flash
+ void bank_select_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
+ uint8_t banked_flash_r(offs_t offset);
+ void banked_flash_w(offs_t offset, uint8_t data);
+
+ // ide register
+ uint16_t ide0_cs0_r(offs_t offset, uint16_t mem_mask = ~0);
+ void ide0_cs0_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
+ uint16_t ide0_cs1_r(offs_t offset, uint16_t mem_mask = ~0);
+ void ide0_cs1_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
+ uint16_t ide1_cs0_r(offs_t offset, uint16_t mem_mask = ~0);
+ void ide1_cs0_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
+ uint16_t ide1_cs1_r(offs_t offset, uint16_t mem_mask = ~0);
+ void ide1_cs1_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
+
+ required_device<ata_interface_device> m_ata_0;
+ required_device<ata_interface_device> m_ata_1;
+ required_device<sst_39sf010_device> m_flash;
+ memory_passthrough_handler m_write_tap;
+
+ offs_t m_base_address = 0;
+ uint8_t m_flash_bank = 0;
+};
+
+} // namespace bus::amiga::zorro
+
+// device type declaration
+DECLARE_DEVICE_TYPE_NS(ZORRO_RIPPLE, bus::amiga::zorro, ripple_ide_device)
+
+#endif // MAME_BUS_AMIGA_ZORRO_RIPPLE_H