diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index 0ad54bc8d7d..e62f05fddc4 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -335,6 +335,8 @@ if (BUSES["BBC_FDC"]~=null) then MAME_DIR .. "src/devices/bus/bbc/fdc/microware.h", MAME_DIR .. "src/devices/bus/bbc/fdc/opus.cpp", MAME_DIR .. "src/devices/bus/bbc/fdc/opus.h", + MAME_DIR .. "src/devices/bus/bbc/fdc/solidisk.cpp", + MAME_DIR .. "src/devices/bus/bbc/fdc/solidisk.h", MAME_DIR .. "src/devices/bus/bbc/fdc/watford.cpp", MAME_DIR .. "src/devices/bus/bbc/fdc/watford.h", } diff --git a/src/devices/bus/bbc/fdc/fdc.cpp b/src/devices/bus/bbc/fdc/fdc.cpp index fb5f88f153f..d90cda52d53 100644 --- a/src/devices/bus/bbc/fdc/fdc.cpp +++ b/src/devices/bus/bbc/fdc/fdc.cpp @@ -98,7 +98,7 @@ void bbc_fdc_slot_device::write(offs_t offset, uint8_t data) #include "cv1797.h" #include "microware.h" #include "opus.h" -//#include "solidisk.h" +#include "solidisk.h" #include "watford.h" @@ -115,9 +115,9 @@ void bbc_fdc_devices(device_slot_interface &device) device.option_add("opus2791", BBC_OPUS2791); device.option_add("opus2793", BBC_OPUS2793); device.option_add("opus1770", BBC_OPUS1770); - //device.option_add("stl8271", BBC_STL8271); - //device.option_add("stl1770_1", BBC_STL1770_1); - //device.option_add("stl1770_2", BBC_STL1770_2); + device.option_add("stl1770_1", BBC_STL1770_1); + device.option_add("stl1770_2", BBC_STL1770_2); + device.option_add("stldfdc_1", BBC_STLDFDC_1); device.option_add("weddb2", BBC_WEDDB2); device.option_add("weddb3", BBC_WEDDB3); } diff --git a/src/devices/bus/bbc/fdc/solidisk.cpp b/src/devices/bus/bbc/fdc/solidisk.cpp new file mode 100644 index 00000000000..94921bf4b97 --- /dev/null +++ b/src/devices/bus/bbc/fdc/solidisk.cpp @@ -0,0 +1,359 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Solidisk 1770 Issue 2 FDC + + http://chrisacorns.computinghistory.org.uk/8bit_Upgrades/Solidisk_1770DDFS.html + + Solidisk Dual FDC + http://chrisacorns.computinghistory.org.uk/8bit_Upgrades/Solidisk_dfdc.html + +**********************************************************************/ + + +#include "emu.h" +#include "solidisk.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(BBC_STL1770_1, bbc_stl1770_1_device, "bbc_stl1770_1", "Solidisk 1770 DDFS Issue 1 FDC") +DEFINE_DEVICE_TYPE(BBC_STL1770_2, bbc_stl1770_2_device, "bbc_stl1770_2", "Solidisk 1770 DDFS Issue 2 FDC") +DEFINE_DEVICE_TYPE(BBC_STLDFDC_1, bbc_stldfdc_1_device, "bbc_stldfdc_1", "Solidisk 8271/1770 DFDC Issue 1 FDC") + + +//------------------------------------------------- +// FLOPPY_FORMATS( floppy_formats ) +//------------------------------------------------- + +FLOPPY_FORMATS_MEMBER( bbc_stlfdc_device::floppy_formats ) + FLOPPY_ACORN_SSD_FORMAT, + FLOPPY_ACORN_DSD_FORMAT, + FLOPPY_ACORN_ADFS_OLD_FORMAT, + FLOPPY_FSD_FORMAT +FLOPPY_FORMATS_END + +static void bbc_floppies_525(device_slot_interface &device) +{ + device.option_add("525sssd", FLOPPY_525_SSSD); + device.option_add("525sd", FLOPPY_525_SD); + device.option_add("525ssdd", FLOPPY_525_SSDD); + device.option_add("525dd", FLOPPY_525_DD); + device.option_add("525qd", FLOPPY_525_QD); +} + +//------------------------------------------------- +// INPUT_PORTS( stldfdc ) +//------------------------------------------------- + +INPUT_PORTS_START( stldfdc ) + PORT_START("DFDC") + PORT_CONFNAME(0x01, 0x00, "Dual FDC Select") PORT_CHANGED_MEMBER(DEVICE_SELF, bbc_stlfdc_device, fdc_changed, 0) + PORT_CONFSETTING(0x00, "8271") + PORT_CONFSETTING(0x01, "1770") +INPUT_PORTS_END + + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor bbc_stldfdc_1_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(stldfdc); +} + +//------------------------------------------------- +// ROM( solidisk ) +//------------------------------------------------- + +ROM_START( stl1770_1 ) + ROM_REGION(0x4000, "dfs_rom", 0) + ROM_SYSTEM_BIOS(0, "dfs21j", "DFS 2.1J (1770)") + ROMX_LOAD("solidisk-dfs-2.1j.rom", 0x0000, 0x4000, CRC(b60296f1) SHA1(22e60d4dda37335f61c27a92ba76ccc3e2102c4e), ROM_BIOS(0)) +ROM_END + +ROM_START( stl1770_2 ) + ROM_REGION(0x4000, "dfs_rom", 0) + ROM_SYSTEM_BIOS(0, "stl22m", "DFS 2.2M Issue 2") + ROMX_LOAD("solidisk-dfs-2.2m-iss2.rom", 0x0000, 0x4000, CRC(defe42ec) SHA1(78ee759c0f762bc2717d8454a88f117516d28325), ROM_BIOS(0)) +ROM_END + +ROM_START( stldfdc_1 ) + ROM_REGION(0x4000, "dfs_rom", 0) + ROM_SYSTEM_BIOS(0, "dfs21", "DFS 2.1 (Mar 85)") + ROMX_LOAD("solidisk-dfs-8271-1770-2.1.rom", 0x0000, 0x4000, CRC(cc83d913) SHA1(c761102ac11be629676339e9e496fb78734e4399), ROM_BIOS(0)) +ROM_END + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +void bbc_stl1770_1_device::device_add_mconfig(machine_config &config) +{ + WD1770(config, m_wd1770, DERIVED_CLOCK(1, 1)); + m_wd1770->drq_wr_callback().set(DEVICE_SELF_OWNER, FUNC(bbc_fdc_slot_device::drq_w)); + + FLOPPY_CONNECTOR(config, m_floppy[0], bbc_floppies_525, "525qd", bbc_stlfdc_device::floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, m_floppy[1], bbc_floppies_525, "525qd", bbc_stlfdc_device::floppy_formats).enable_sound(true); +} + +void bbc_stl1770_2_device::device_add_mconfig(machine_config &config) +{ + WD1770(config, m_wd1770, DERIVED_CLOCK(1, 1)); + m_wd1770->intrq_wr_callback().set(DEVICE_SELF_OWNER, FUNC(bbc_fdc_slot_device::intrq_w)); + m_wd1770->drq_wr_callback().set(DEVICE_SELF_OWNER, FUNC(bbc_fdc_slot_device::drq_w)); + + FLOPPY_CONNECTOR(config, m_floppy[0], bbc_floppies_525, "525qd", bbc_stlfdc_device::floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, m_floppy[1], bbc_floppies_525, "525qd", bbc_stlfdc_device::floppy_formats).enable_sound(true); +} + +void bbc_stldfdc_1_device::device_add_mconfig(machine_config& config) +{ + bbc_stl1770_1_device::device_add_mconfig(config); + + I8271(config, m_i8271, DERIVED_CLOCK(1, 2)); + m_i8271->intrq_wr_callback().set(DEVICE_SELF_OWNER, FUNC(bbc_fdc_slot_device::intrq_w)); + m_i8271->hdl_wr_callback().set(FUNC(bbc_stldfdc_1_device::motor_w)); + m_i8271->opt_wr_callback().set(FUNC(bbc_stldfdc_1_device::side_w)); +} + + +const tiny_rom_entry *bbc_stl1770_1_device::device_rom_region() const +{ + return ROM_NAME( stl1770_1 ); +} + +const tiny_rom_entry *bbc_stl1770_2_device::device_rom_region() const +{ + return ROM_NAME( stl1770_2 ); +} + +const tiny_rom_entry *bbc_stldfdc_1_device::device_rom_region() const +{ + return ROM_NAME( stldfdc_1 ); +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// bbc_stlfdc_device - constructor +//------------------------------------------------- + +bbc_stlfdc_device::bbc_stlfdc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, type, tag, owner, clock) + , device_bbc_fdc_interface(mconfig, *this) + , m_wd1770(*this, "wd1770") + , m_i8271(*this, "i8271") + , m_floppy(*this, "%u", 0) + , m_dfdc(*this, "DFDC") +{ +} + +bbc_stl1770_1_device::bbc_stl1770_1_device(const machine_config& mconfig, device_type type, const char* tag, device_t* owner, uint32_t clock) + : bbc_stlfdc_device(mconfig, type, tag, owner, clock) +{ +} + +bbc_stl1770_1_device::bbc_stl1770_1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : bbc_stlfdc_device(mconfig, BBC_STL1770_1, tag, owner, clock) +{ +} + +bbc_stl1770_2_device::bbc_stl1770_2_device(const machine_config& mconfig, device_type type, const char* tag, device_t* owner, uint32_t clock) + : bbc_stlfdc_device(mconfig, type, tag, owner, clock) +{ +} + +bbc_stl1770_2_device::bbc_stl1770_2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : bbc_stlfdc_device(mconfig, BBC_STL1770_2, tag, owner, clock) +{ +} + +bbc_stldfdc_1_device::bbc_stldfdc_1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : bbc_stl1770_1_device(mconfig, BBC_STLDFDC_1, tag, owner, clock) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void bbc_stl1770_1_device::device_start() +{ +} + +void bbc_stl1770_2_device::device_start() +{ +} + +void bbc_stldfdc_1_device::device_start() +{ +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void bbc_stldfdc_1_device::device_reset() +{ + switch (m_dfdc->read()) + { + case 0: + m_i8271->set_floppies(m_floppy[0], m_floppy[1]); + break; + + case 1: + m_wd1770->set_floppy(m_floppy[0]->get_device()); + break; + } +} + + +//************************************************************************** +// IMPLEMENTATION +//************************************************************************** + +INPUT_CHANGED_MEMBER(bbc_stlfdc_device::fdc_changed) +{ + device_reset(); +} + +WRITE_LINE_MEMBER(bbc_stlfdc_device::motor_w) +{ + if (m_floppy[0]->get_device()) m_floppy[0]->get_device()->mon_w(!state); + if (m_floppy[1]->get_device()) m_floppy[1]->get_device()->mon_w(!state); + m_i8271->ready_w(!state); +} + +WRITE_LINE_MEMBER(bbc_stlfdc_device::side_w) +{ + if (m_floppy[0]->get_device()) m_floppy[0]->get_device()->ss_w(state); + if (m_floppy[1]->get_device()) m_floppy[1]->get_device()->ss_w(state); +} + + +uint8_t bbc_stl1770_1_device::read(offs_t offset) +{ + return m_wd1770->read(offset & 0x03); +} + +void bbc_stl1770_1_device::write(offs_t offset, uint8_t data) +{ + if (offset & 0x04) + { + floppy_image_device *floppy = nullptr; + + // bit 0: drive select + switch (BIT(data, 0)) + { + case 0: floppy = m_floppy[0]->get_device(); break; + case 1: floppy = m_floppy[1]->get_device(); break; + } + m_wd1770->set_floppy(floppy); + + // bit 1: side select + if (floppy) + floppy->ss_w(BIT(data, 1)); + + // bit 2: density + m_wd1770->dden_w(BIT(data, 2)); + } + + m_wd1770->write(offset & 0x03, data); +} + + +uint8_t bbc_stl1770_2_device::read(offs_t offset) +{ + uint8_t data; + + if (offset & 0x04) + { + data = m_wd1770->read(offset & 0x03); + } + else + { + data = 0xfe; + } + return data; +} + +void bbc_stl1770_2_device::write(offs_t offset, uint8_t data) +{ + if (offset & 0x04) + { + m_wd1770->write(offset & 0x03, data); + } + else + { + floppy_image_device *floppy = nullptr; + + // bit 0, 1: drive select + if (BIT(data, 0)) floppy = m_floppy[0]->get_device(); + if (BIT(data, 1)) floppy = m_floppy[1]->get_device(); + m_wd1770->set_floppy(floppy); + + // bit 2: side select + if (floppy) + floppy->ss_w(BIT(data, 2)); + + // bit 3: density + m_wd1770->dden_w(BIT(data, 3)); + + // bit 5: reset + m_wd1770->mr_w(BIT(data, 5)); + } +} + + +uint8_t bbc_stldfdc_1_device::read(offs_t offset) +{ + uint8_t data = 0xff; + + switch (m_dfdc->read()) + { + case 0: + if (offset & 0x04) + { + data = m_i8271->data_r(); + } + else + { + data = m_i8271->read(offset & 0x03); + } + break; + + case 1: + data = bbc_stl1770_1_device::read(offset); + break; + } + + return data; +} + +void bbc_stldfdc_1_device::write(offs_t offset, uint8_t data) +{ + switch (m_dfdc->read()) + { + case 0: + if (offset & 0x04) + { + m_i8271->data_w(data); + } + else + { + m_i8271->write(offset & 0x03, data); + } + break; + + case 1: + bbc_stl1770_1_device::write(offset, data); + break; + } +} diff --git a/src/devices/bus/bbc/fdc/solidisk.h b/src/devices/bus/bbc/fdc/solidisk.h new file mode 100644 index 00000000000..1676d6fa54c --- /dev/null +++ b/src/devices/bus/bbc/fdc/solidisk.h @@ -0,0 +1,113 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Solidisk 8271/1770 FDC + +**********************************************************************/ + + +#ifndef MAME_BUS_BBC_FDC_SOLIDISK_H +#define MAME_BUS_BBC_FDC_SOLIDISK_H + +#pragma once + +#include "fdc.h" +#include "machine/i8271.h" +#include "imagedev/floppy.h" +#include "machine/wd_fdc.h" +#include "formats/acorn_dsk.h" +#include "formats/fsd_dsk.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class bbc_stlfdc_device : + public device_t, + public device_bbc_fdc_interface +{ +public: + DECLARE_FLOPPY_FORMATS(floppy_formats); + DECLARE_INPUT_CHANGED_MEMBER(fdc_changed); + +protected: + // construction/destruction + bbc_stlfdc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + + DECLARE_WRITE_LINE_MEMBER(motor_w); + DECLARE_WRITE_LINE_MEMBER(side_w); + + required_device m_wd1770; + optional_device m_i8271; + required_device_array m_floppy; + optional_ioport m_dfdc; +}; + + +class bbc_stl1770_1_device : public bbc_stlfdc_device +{ +public: + bbc_stl1770_1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + bbc_stl1770_1_device(const machine_config& mconfig, device_type type, const char* tag, device_t* owner, uint32_t clock); + + // device-level overrides + virtual void device_start() override; + + virtual void device_add_mconfig(machine_config& config) override; + virtual const tiny_rom_entry* device_rom_region() const override; + + virtual uint8_t read(offs_t offset) override; + virtual void write(offs_t offset, uint8_t data) override; +}; + + +class bbc_stl1770_2_device : public bbc_stlfdc_device +{ +public: + bbc_stl1770_2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + bbc_stl1770_2_device(const machine_config& mconfig, device_type type, const char* tag, device_t* owner, uint32_t clock); + + // device-level overrides + virtual void device_start() override; + + virtual void device_add_mconfig(machine_config& config) override; + virtual const tiny_rom_entry* device_rom_region() const override; + + virtual uint8_t read(offs_t offset) override; + virtual void write(offs_t offset, uint8_t data) override; +}; + + +class bbc_stldfdc_1_device : public bbc_stl1770_1_device +{ +public: + // construction/destruction + bbc_stldfdc_1_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + // optional information overrides + virtual void device_add_mconfig(machine_config& config) override; + virtual const tiny_rom_entry* device_rom_region() const override; + virtual ioport_constructor device_input_ports() const override; + + virtual uint8_t read(offs_t offset) override; + virtual void write(offs_t offset, uint8_t data) override; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(BBC_STL1770_1, bbc_stl1770_1_device) +DECLARE_DEVICE_TYPE(BBC_STL1770_2, bbc_stl1770_2_device) +DECLARE_DEVICE_TYPE(BBC_STLDFDC_1, bbc_stldfdc_1_device) + + +#endif /* MAME_BUS_BBC_FDC_SOLIDISK_H */ diff --git a/src/devices/machine/i8271.cpp b/src/devices/machine/i8271.cpp index 7d11e3aa26a..f70f1395f66 100644 --- a/src/devices/machine/i8271.cpp +++ b/src/devices/machine/i8271.cpp @@ -3,7 +3,6 @@ #include "emu.h" #include "i8271.h" -#include "imagedev/floppy.h" DEFINE_DEVICE_TYPE(I8271, i8271_device, "i8271", "Intel 8271 FDC") @@ -121,15 +120,23 @@ bool i8271_device::get_ready(int fid) return !external_ready; } -void i8271_device::set_floppy(floppy_image_device *flop) +void i8271_device::set_floppies(floppy_connector *f0, floppy_connector *f1) { - for(auto & elem : flopi) { - if(elem.dev) - elem.dev->setup_index_pulse_cb(floppy_image_device::index_pulse_cb()); - elem.dev = flop; + if (f0) { + flopi[0].dev = f0->get_device(); + if (flopi[0].dev != nullptr) + flopi[0].dev->setup_index_pulse_cb(floppy_image_device::index_pulse_cb(&i8271_device::index_callback, this)); } - if(flop) - flop->setup_index_pulse_cb(floppy_image_device::index_pulse_cb(&i8271_device::index_callback, this)); + else + flopi[0].dev = nullptr; + + if (f1) { + flopi[1].dev = f0->get_device(); + if (flopi[1].dev != nullptr) + flopi[1].dev->setup_index_pulse_cb(floppy_image_device::index_pulse_cb(&i8271_device::index_callback, this)); + } + else + flopi[1].dev = nullptr; } uint8_t i8271_device::sr_r() diff --git a/src/devices/machine/i8271.h b/src/devices/machine/i8271.h index 88e9a6146e6..9d02f2497d3 100644 --- a/src/devices/machine/i8271.h +++ b/src/devices/machine/i8271.h @@ -6,6 +6,7 @@ #pragma once #include "fdc_pll.h" +#include "imagedev/floppy.h" class floppy_image_device; @@ -35,7 +36,7 @@ public: void set_ready_line_connected(bool ready); void set_select_lines_connected(bool select); - void set_floppy(floppy_image_device *image); + void set_floppies(floppy_connector* f0, floppy_connector* f1); void soft_reset(); void map(address_map &map);