// license:BSD-3-Clause // copyright-holders:Nigel Barnes /********************************************************************** ALA13 - Acorn Plus 3 http://chrisacorns.computinghistory.org.uk/8bit_Upgrades/Acorn_Plus3.html The Acorn Plus 3 was a hardware module that connected independently of the Plus 1 and provided a double-density 3.5" disc drive connected through a WD1770 drive controller and an ADFS ROM. There were two versions of the Plus 3 produced: A Single-sided and a Double-sided drive version. **********************************************************************/ #include "emu.h" #include "plus3.h" #include "formats/acorn_dsk.h" //************************************************************************** // DEVICE DEFINITIONS //************************************************************************** DEFINE_DEVICE_TYPE(ELECTRON_PLUS3, electron_plus3_device, "electron_plus3", "Acorn Plus 3 Disc Expansion") //------------------------------------------------- // FLOPPY_FORMATS( plus3 ) //------------------------------------------------- void electron_plus3_device::floppy_formats(format_registration &fr) { fr.add_mfm_containers(); fr.add(FLOPPY_ACORN_SSD_FORMAT); fr.add(FLOPPY_ACORN_DSD_FORMAT); fr.add(FLOPPY_ACORN_ADFS_OLD_FORMAT); } void electron_floppies(device_slot_interface &device) { device.option_add("35dd", FLOPPY_35_DD); device.option_add("525qd", FLOPPY_525_QD); } //------------------------------------------------- // ROM( plus3 ) //------------------------------------------------- ROM_START( plus3 ) // Bank 4 Disc ROM_REGION(0x4000, "exp_rom", 0) ROM_DEFAULT_BIOS("adfs100") // ADFS ROM_SYSTEM_BIOS(0, "adfs100", "Acorn ADFS 1.00") ROMX_LOAD("adfs.rom", 0x0000, 0x4000, CRC(3289bdc6) SHA1(e7c7a1094d50a3579751df2007269067c8ff6812), ROM_BIOS(0)) ROM_SYSTEM_BIOS(1, "adfs113", "PRES ADFS 1.13") ROMX_LOAD("pres_adfs_113.rom", 0x0000, 0x4000, CRC(f06ca04a) SHA1(3c8221d63457c552aa2c9a502db632ce1dea66b4), ROM_BIOS(1)) ROM_SYSTEM_BIOS(2, "adfs115", "PRES ADFS 1.15") ROMX_LOAD("pres_adfs_115.rom", 0x0000, 0x4000, CRC(8f81edc3) SHA1(32007425058a7b0f8bd5c17b3c22552aa3a03eca), ROM_BIOS(2)) // DFS ROM_SYSTEM_BIOS(3, "dfs200", "Advanced 1770 DFS 2.00") ROMX_LOAD("acp_dfs1770_200.rom", 0x0000, 0x4000, CRC(5a3a13c7) SHA1(d5dad7ab5a0237c44d0426cd85a8ec86545747e0), ROM_BIOS(3)) ROM_SYSTEM_BIOS(4, "dfs210", "Advanced 1770 DFS 2.10") ROMX_LOAD("acp_dfs1770_210.rom", 0x0000, 0x4000, CRC(b0661992) SHA1(c62f1290f689788dad6a2df30ace083eb827cffe), ROM_BIOS(4)) ROM_END //------------------------------------------------- // device_add_mconfig - add device configuration //------------------------------------------------- void electron_plus3_device::device_add_mconfig(machine_config &config) { /* fdc */ WD1770(config, m_fdc, DERIVED_CLOCK(1, 2)); FLOPPY_CONNECTOR(config, m_floppy0, electron_floppies, "35dd", floppy_formats).set_fixed(true); m_floppy0->enable_sound(true); FLOPPY_CONNECTOR(config, m_floppy1, electron_floppies, nullptr, floppy_formats); m_floppy1->enable_sound(true); /* pass-through */ ELECTRON_EXPANSION_SLOT(config, m_exp, DERIVED_CLOCK(1, 1), electron_expansion_devices, nullptr); m_exp->irq_handler().set(DEVICE_SELF_OWNER, FUNC(electron_expansion_slot_device::irq_w)); m_exp->nmi_handler().set(DEVICE_SELF_OWNER, FUNC(electron_expansion_slot_device::nmi_w)); } const tiny_rom_entry *electron_plus3_device::device_rom_region() const { return ROM_NAME( plus3 ); } //************************************************************************** // LIVE DEVICE //************************************************************************** //------------------------------------------------- // electron_plus3_device - constructor //------------------------------------------------- electron_plus3_device::electron_plus3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, ELECTRON_PLUS3, tag, owner, clock) , device_electron_expansion_interface(mconfig, *this) , m_exp(*this, "exp") , m_exp_rom(*this, "exp_rom") , m_fdc(*this, "fdc") , m_floppy0(*this, "fdc:0") , m_floppy1(*this, "fdc:1") , m_romsel(0) { } //------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- void electron_plus3_device::device_start() { } //------------------------------------------------- // expbus_r - expansion data read //------------------------------------------------- uint8_t electron_plus3_device::expbus_r(offs_t offset) { uint8_t data = 0xff; if (offset >= 0x8000 && offset < 0xc000) { if (m_romsel == 4) { data = m_exp_rom->base()[offset & 0x3fff]; } } else if (offset == 0xfcc0) { data = 0xff; } else if (offset >= 0xfcc4 && offset < 0xfcc8) { data = m_fdc->read(offset & 0x03); } data &= m_exp->expbus_r(offset); return data; } //------------------------------------------------- // expbus_w - expansion data write //------------------------------------------------- void electron_plus3_device::expbus_w(offs_t offset, uint8_t data) { m_exp->expbus_w(offset, data); if (offset == 0xfcc0) { wd1770_status_w(data); } else if (offset >= 0xfcc4 && offset < 0xfcc8) { m_fdc->write(offset & 0x03, data); } else if ((offset == 0xfe05) && !(data & 0xf0)) { m_romsel = data & 0x0f; } } //************************************************************************** // IMPLEMENTATION //************************************************************************** void electron_plus3_device::wd1770_status_w(uint8_t data) { floppy_image_device *floppy = nullptr; m_drive_control = data; // bit 0, 1: drive select if (BIT(data, 0)) floppy = m_floppy0->get_device(); if (BIT(data, 1)) floppy = m_floppy1->get_device(); m_fdc->set_floppy(floppy); // bit 2: side select if (floppy) floppy->ss_w(BIT(data, 2)); // bit 3: density m_fdc->dden_w(BIT(data, 3)); // bit 5: reset m_fdc->mr_w(BIT(data, 5)); }