From 4f6b319dfe79700043cf3d4327e083644846aca6 Mon Sep 17 00:00:00 2001 From: Dirk Best Date: Fri, 29 Nov 2024 21:03:26 +0100 Subject: bus/amiga/zorro: Add support for the RIPPLE IDE controller --- scripts/src/bus.lua | 2 + src/devices/bus/amiga/zorro/cards.cpp | 3 + src/devices/bus/amiga/zorro/ripple.cpp | 233 +++++++++++++++++++++++++++++++++ src/devices/bus/amiga/zorro/ripple.h | 73 +++++++++++ src/mame/amiga/amiga.cpp | 8 ++ 5 files changed, 319 insertions(+) create mode 100644 src/devices/bus/amiga/zorro/ripple.cpp create mode 100644 src/devices/bus/amiga/zorro/ripple.h diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index 764abec93ac..d7fdfe15364 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -4688,6 +4688,8 @@ if (BUSES["ZORRO"]~=null) then MAME_DIR .. "src/devices/bus/amiga/zorro/action_replay.h", MAME_DIR .. "src/devices/bus/amiga/zorro/buddha.cpp", MAME_DIR .. "src/devices/bus/amiga/zorro/buddha.h", + MAME_DIR .. "src/devices/bus/amiga/zorro/ripple.cpp", + MAME_DIR .. "src/devices/bus/amiga/zorro/ripple.h", } end 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 m_ata_0; + required_device m_ata_1; + required_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 diff --git a/src/mame/amiga/amiga.cpp b/src/mame/amiga/amiga.cpp index a730260f849..1f607a0ca9a 100644 --- a/src/mame/amiga/amiga.cpp +++ b/src/mame/amiga/amiga.cpp @@ -2331,6 +2331,14 @@ ROM_START( a2000 ) ROMX_LOAD("kick40063.u2", 0x00000, 0x80000, CRC(fc24ae0d) SHA1(3b7f1493b27e212830f989f26ca76c02049f09ca), ROM_GROUPWORD | ROM_BIOS(3)) ROM_SYSTEM_BIOS(4, "logica2", "Logica Diagnostic 2.0") ROMX_LOAD("logica2.u2", 0x00000, 0x80000, CRC(8484f426) SHA1(ba10d16166b2e2d6177c979c99edf8462b21651e), ROM_GROUPWORD | ROM_BIOS(4)) +#if 0 // not enabled yet, kickstart 3.2 is new and actively sold + ROM_SYSTEM_BIOS(5, "kick32", "Kickstart 3.2 (47.96)") + ROMX_LOAD("kick47096.u2", 0x00000, 0x80000, CRC(8173d7b6) SHA1(b88e364daf23c9c9920e548b0d3d944e65b1031d), ROM_GROUPWORD | ROM_BIOS(5)) + ROM_SYSTEM_BIOS(6, "kick321", "Kickstart 3.2 (47.102)") + ROMX_LOAD("kick47102.u2", 0x00000, 0x80000, CRC(4f078456) SHA1(8f64ada68a7f128ba782e8dc9fa583344171590a), ROM_GROUPWORD | ROM_BIOS(6)) + ROM_SYSTEM_BIOS(7, "kick322", "Kickstart 3.2 (47.111)") + ROMX_LOAD("kick47111.u2", 0x00000, 0x80000, CRC(e4458462) SHA1(7d5ebe686b69d59a863cc77a36b2cd60359a9ed2), ROM_GROUPWORD | ROM_BIOS(7)) +#endif ROM_END // Amiga 2000CR chip location: U500 -- cgit v1.2.3