From a09ab93312723acf33f0a364dc49c0558ab61116 Mon Sep 17 00:00:00 2001 From: MetalliC <0vetal0@gmail.com> Date: Sun, 21 Jun 2020 19:44:01 +0300 Subject: spectrum/d40.cpp add "MDOS 2" UPD765-based floppy controller --- src/devices/bus/spectrum/d40.cpp | 290 ++++++++++++++++++++++++++++++++------- src/devices/bus/spectrum/d40.h | 83 +++++++++-- src/devices/bus/spectrum/exp.cpp | 3 +- 3 files changed, 313 insertions(+), 63 deletions(-) diff --git a/src/devices/bus/spectrum/d40.cpp b/src/devices/bus/spectrum/d40.cpp index 693eae074b0..d25b7eaad83 100644 --- a/src/devices/bus/spectrum/d40.cpp +++ b/src/devices/bus/spectrum/d40.cpp @@ -3,7 +3,12 @@ /********************************************************************** Didaktik D40/D80 disk interface - (C) 1991 Didaktik Scalica + (C) 1991 Didaktik Skalica + + useful commands: + CAT - files list + LIST * - system information + LOAD *"filename" - load program **********************************************************************/ @@ -16,8 +21,9 @@ // DEVICE DEFINITIONS //************************************************************************** -DEFINE_DEVICE_TYPE(SPECTRUM_D40, spectrum_d40_device, "spectrum_d40", "Didaktik D40 disk interface") -DEFINE_DEVICE_TYPE(SPECTRUM_D80, spectrum_d80_device, "spectrum_d80", "Didaktik D80 disk interface") +DEFINE_DEVICE_TYPE(SPECTRUM_D40, spectrum_d40_device, "spectrum_d40", "Didaktik D40") +DEFINE_DEVICE_TYPE(SPECTRUM_D80, spectrum_d80_device, "spectrum_d80", "Didaktik D80 (MDOS 1, 2793 FDC)") +DEFINE_DEVICE_TYPE(SPECTRUM_D80V2, spectrum_d80v2_device, "spectrum_d80v2", "Didaktik D80 (MDOS 2, 8272 FDC)") //------------------------------------------------- // INPUT_PORTS @@ -25,14 +31,14 @@ DEFINE_DEVICE_TYPE(SPECTRUM_D80, spectrum_d80_device, "spectrum_d80", "Didaktik INPUT_PORTS_START(d40) PORT_START("BUTTON") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("Snapshot Button") PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHANGED_MEMBER(DEVICE_SELF, spectrum_d40_device, snapshot_button, 0) + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("Snapshot Button") PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHANGED_MEMBER(DEVICE_SELF, spectrum_d40base_device, snapshot_button, 0) INPUT_PORTS_END //------------------------------------------------- // input_ports - device-specific input ports //------------------------------------------------- -ioport_constructor spectrum_d40_device::device_input_ports() const +ioport_constructor spectrum_d40base_device::device_input_ports() const { return INPUT_PORTS_NAME(d40); } @@ -55,6 +61,10 @@ FLOPPY_FORMATS_MEMBER(spectrum_d40_device::floppy_formats) FLOPPY_D40D80_FORMAT FLOPPY_FORMATS_END +FLOPPY_FORMATS_MEMBER(spectrum_d80v2_device::floppy_formats) + FLOPPY_PC_FORMAT +FLOPPY_FORMATS_END + //------------------------------------------------- // ROM //------------------------------------------------- @@ -64,10 +74,15 @@ ROM_START(d40) ROM_DEFAULT_BIOS("mdos11") ROM_SYSTEM_BIOS(0, "mdos11", "MDOS 1.0 (1991)") ROMX_LOAD("mdos10.bin", 0x0000, 0x4000, CRC(e6b70939) SHA1(308c4b5daf6bb1f05c68a447129d723da423326e), ROM_BIOS(0)) - ROM_SYSTEM_BIOS(1, "mdos12", "MDOS 1.0+ (1992)") + ROM_SYSTEM_BIOS(1, "mdos12", "MDOS 1.0+ (1992)") // possible unofficial modification ROMX_LOAD("mdos10p.bin", 0x0000, 0x4000, CRC(92c45741) SHA1(b8473235feecff4eccbace56a90cf1d8c79506eb), ROM_BIOS(1)) - ROM_SYSTEM_BIOS(2, "mdos2", "MDOS 2.0 (1993)") // doesn't work, from different board type with GM82C765B FDC - ROMX_LOAD("mdos20.bin", 0x0000, 0x4000, CRC(9e79d022) SHA1(e8d3355051fb287dd0dda34ba8824442130c8254), ROM_BIOS(2)) +ROM_END + +ROM_START(d80v2) + ROM_REGION(0x4000, "rom", 0) + ROM_DEFAULT_BIOS("mdos2") + ROM_SYSTEM_BIOS(0, "mdos2", "MDOS 2.0 (1993)") + ROMX_LOAD("mdos20.bin", 0x0000, 0x4000, CRC(9e79d022) SHA1(e8d3355051fb287dd0dda34ba8824442130c8254), ROM_BIOS(0)) ROM_END //------------------------------------------------- @@ -82,6 +97,8 @@ void spectrum_d40_device::device_add_mconfig(machine_config &config) FLOPPY_CONNECTOR(config, "fdc:0", didaktik_floppies, "525dd", spectrum_d40_device::floppy_formats).enable_sound(true); FLOPPY_CONNECTOR(config, "fdc:1", didaktik_floppies, "525dd", spectrum_d40_device::floppy_formats).enable_sound(true); + I8255(config, m_ppi); + /* software list */ //SOFTWARE_LIST(config, "flop_list").set_original("spectrum_d40_flop"); } @@ -94,6 +111,20 @@ void spectrum_d80_device::device_add_mconfig(machine_config &config) FLOPPY_CONNECTOR(config, "fdc:0", didaktik_floppies, "35dd", spectrum_d80_device::floppy_formats).enable_sound(true); FLOPPY_CONNECTOR(config, "fdc:1", didaktik_floppies, "35dd", spectrum_d80_device::floppy_formats).enable_sound(true); + I8255(config, m_ppi); + + /* software list */ + //SOFTWARE_LIST(config, "flop_list").set_original("spectrum_d40_flop"); +} + +void spectrum_d80v2_device::device_add_mconfig(machine_config &config) +{ + WD37C65C(config, m_fdc, 16_MHz_XTAL); // actually GM82C765B + FLOPPY_CONNECTOR(config, "fdc:0", didaktik_floppies, "35dd", spectrum_d80v2_device::floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, "fdc:1", didaktik_floppies, "35dd", spectrum_d80v2_device::floppy_formats).enable_sound(true); + + I8255(config, m_ppi); + /* software list */ //SOFTWARE_LIST(config, "flop_list").set_original("spectrum_d40_flop"); } @@ -103,25 +134,39 @@ const tiny_rom_entry *spectrum_d40_device::device_rom_region() const return ROM_NAME(d40); } +const tiny_rom_entry *spectrum_d80v2_device::device_rom_region() const +{ + return ROM_NAME(d80v2); +} + //************************************************************************** // LIVE DEVICE //************************************************************************** //------------------------------------------------- -// spectrum_d40_device - constructor +// spectrum_d40base_device - constructor //------------------------------------------------- -spectrum_d40_device::spectrum_d40_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) +spectrum_d40base_device::spectrum_d40base_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_spectrum_expansion_interface(mconfig, *this) , m_rom(*this, "rom") + , m_ppi(*this, "ppi") + , m_snap(*this, "BUTTON") +{ +} + +spectrum_d40_device::spectrum_d40_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : spectrum_d40base_device(mconfig, SPECTRUM_D40, tag, owner, clock) , m_fdc(*this, "fdc") , m_floppy(*this, "fdc:%u", 0) { } -spectrum_d40_device::spectrum_d40_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : spectrum_d40_device(mconfig, SPECTRUM_D40, tag, owner, clock) +spectrum_d40_device::spectrum_d40_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + :spectrum_d40base_device(mconfig, type, tag, owner, clock) + , m_fdc(*this, "fdc") + , m_floppy(*this, "fdc:%u", 0) { } @@ -130,41 +175,50 @@ spectrum_d80_device::spectrum_d80_device(const machine_config &mconfig, const ch { } +spectrum_d80v2_device::spectrum_d80v2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : spectrum_d40base_device(mconfig, SPECTRUM_D80V2, tag, owner, clock) + , m_fdc(*this, "fdc") + , m_floppy(*this, "fdc:%u", 0) +{ +} + //------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- -void spectrum_d40_device::device_start() +void spectrum_d40base_device::device_start() { std::fill(std::begin(m_ram), std::end(m_ram), 0); save_item(NAME(m_romcs)); save_item(NAME(m_ram)); - save_item(NAME(m_control)); save_item(NAME(m_snap_flag)); + save_item(NAME(m_8255_reset)); + save_item(NAME(m_8255_enable)); } //------------------------------------------------- // device_reset - device-specific reset //------------------------------------------------- -void spectrum_d40_device::device_reset() +void spectrum_d40base_device::device_reset() { m_romcs = 0; - m_control = 0; m_snap_flag = 0; + m_8255_reset = 0; + m_8255_enable = 0; } //************************************************************************** -// IMPLEMENTATION spectrum_d40_device +// IMPLEMENTATION spectrum_d40base_device //************************************************************************** -READ_LINE_MEMBER(spectrum_d40_device::romcs) +READ_LINE_MEMBER(spectrum_d40base_device::romcs) { return m_romcs; } -void spectrum_d40_device::pre_opcode_fetch(offs_t offset) +void spectrum_d40base_device::pre_opcode_fetch(offs_t offset) { if (!machine().side_effects_disabled()) { @@ -173,72 +227,79 @@ void spectrum_d40_device::pre_opcode_fetch(offs_t offset) case 0x0000: case 0x0008: m_romcs = 1; + nmi_check(); break; case 0x0066: if (!m_romcs) { m_romcs = 1; m_snap_flag = 1; + nmi_check(); } break; case 0x1700: - m_romcs = 0; + if (!m_snap_flag) + m_romcs = 0; + nmi_check(); break; } } } -uint8_t spectrum_d40_device::iorq_r(offs_t offset) +uint8_t spectrum_d40base_device::iorq_r(offs_t offset) { uint8_t data = 0xff; switch (offset & 0xf9) { case 0x81: // FDC - data = m_fdc->read((offset >> 1) & 0x03); + data = fdc0_r(offset); + break; + case 0x89: // FDC + data = fdc1_r(offset); break; } + if (!BIT(offset, 7) && m_8255_enable) // 1F/3F/5F/7F + data = m_ppi->read((offset >> 5) & 3); + return data; } -void spectrum_d40_device::iorq_w(offs_t offset, uint8_t data) +void spectrum_d40base_device::iorq_w(offs_t offset, uint8_t data) { switch (offset & 0xf9) { case 0x81: // FDC - m_fdc->write((offset >> 1) & 0x03, data); + fdc0_w(offset, data); break; case 0x89: // control port - { - m_control = data; - - floppy_image_device* floppy = nullptr; - if (BIT(data, 0)) - floppy = m_floppy[0]->get_device(); - else if (BIT(data, 1)) - floppy = m_floppy[1]->get_device(); - m_fdc->set_floppy(floppy); - - m_floppy[0]->get_device()->mon_w(BIT(data, 2) ? 0 : 1); - m_floppy[1]->get_device()->mon_w(BIT(data, 3) ? 0 : 1); - } + fdc1_w(offset, data); break; case 0x91: // PPI reset - // TODO PPI + m_8255_reset = BIT(data, 5); + if (!m_8255_reset) + { + m_ppi->reset(); + m_8255_enable = 0; + } break; case 0x99: // PPI enable - // TODO PPI + if (m_8255_reset) + m_8255_enable = BIT(data, 4); break; } + + if (!BIT(offset, 7) && m_8255_enable) // 1F/3F/5F/7F + m_ppi->write((offset >> 5) & 3, data); } -uint8_t spectrum_d40_device::mreq_r(offs_t offset) +uint8_t spectrum_d40base_device::mreq_r(offs_t offset) { if (m_snap_flag && offset == 0x66) { - m_snap_flag = 0; - return 0xc7; + m_snap_flag = 0; // hacky, real hardware reset this latch by Z80 /WR line + return 0xc7; // RST 0 inject } uint8_t data = 0xff; @@ -254,7 +315,7 @@ uint8_t spectrum_d40_device::mreq_r(offs_t offset) return data; } -void spectrum_d40_device::mreq_w(offs_t offset, uint8_t data) +void spectrum_d40base_device::mreq_w(offs_t offset, uint8_t data) { if (m_romcs) { @@ -263,17 +324,152 @@ void spectrum_d40_device::mreq_w(offs_t offset, uint8_t data) } } -INPUT_CHANGED_MEMBER(spectrum_d40_device::snapshot_button) +INPUT_CHANGED_MEMBER(spectrum_d40base_device::snapshot_button) +{ + nmi_check(); +} + +void spectrum_d40base_device::nmi_check() { - m_slot->nmi_w((!newval && oldval && !m_romcs) ? ASSERT_LINE : CLEAR_LINE); + int state = CLEAR_LINE; + + if (!m_romcs && m_snap->read()) + state = ASSERT_LINE; + + m_slot->nmi_w(state); +} + +//************************************************************************** +// IMPLEMENTATION spectrum_d40_device +//************************************************************************** + +void spectrum_d40_device::device_start() +{ + spectrum_d40base_device::device_start(); + save_item(NAME(m_control)); + save_item(NAME(m_intrq)); + save_item(NAME(m_drq)); +} + +void spectrum_d40_device::device_reset() +{ + spectrum_d40base_device::device_reset(); + m_control = 0; + m_intrq = 0; + m_drq = 0; +} + +uint8_t spectrum_d40_device::fdc0_r(offs_t offset) +{ + return m_fdc->read((offset >> 1) & 0x03); +} + +void spectrum_d40_device::fdc0_w(offs_t offset, uint8_t data) +{ + m_fdc->write((offset >> 1) & 0x03, data); +} + +void spectrum_d40_device::fdc1_w(offs_t offset, uint8_t data) +{ + m_control = data; + + floppy_image_device* floppy = nullptr; + if (BIT(data, 0)) + floppy = m_floppy[0]->get_device(); + else if (BIT(data, 1)) + floppy = m_floppy[1]->get_device(); + m_fdc->set_floppy(floppy); + + m_floppy[0]->get_device()->mon_w(BIT(data, 2) ? 0 : 1); + m_floppy[1]->get_device()->mon_w(BIT(data, 3) ? 0 : 1); + + nmi_check(); } void spectrum_d40_device::fdc_intrq_w(int state) { - m_slot->nmi_w((state && BIT(m_control, 7)) ? ASSERT_LINE : CLEAR_LINE); + m_intrq = state; + nmi_check(); } void spectrum_d40_device::fdc_drq_w(int state) { - m_slot->nmi_w((state && BIT(m_control, 6)) ? ASSERT_LINE : CLEAR_LINE); + m_drq = state; + nmi_check(); +} + +void spectrum_d40_device::nmi_check() +{ + int state = CLEAR_LINE; + + if (!m_romcs && m_snap->read()) + state = ASSERT_LINE; + + if (m_intrq && BIT(m_control, 7)) + state = ASSERT_LINE; + + if (m_drq && BIT(m_control, 6)) + state = ASSERT_LINE; + + m_slot->nmi_w(state); +} + +//************************************************************************** +// IMPLEMENTATION spectrum_d80v2_device +//************************************************************************** + +void spectrum_d80v2_device::pre_opcode_fetch(offs_t offset) +{ + if (!machine().side_effects_disabled()) + { + switch (offset) + { + case 0x0000: + case 0x0008: + case 0x0066: + m_romcs = 1; + nmi_check(); + break; + case 0x1700: + m_romcs = 0; + nmi_check(); + break; + } + } +} + +uint8_t spectrum_d80v2_device::fdc0_r(offs_t offset) +{ + return BIT(offset, 2) ? m_fdc->fifo_r() : m_fdc->msr_r(); +} + +uint8_t spectrum_d80v2_device::fdc1_r(offs_t offset) +{ + return m_fdc->dor_r(); +} + +void spectrum_d80v2_device::fdc0_w(offs_t offset, uint8_t data) +{ + if (BIT(offset, 2)) + m_fdc->fifo_w(data); +} + +void spectrum_d80v2_device::fdc1_w(offs_t offset, uint8_t data) +{ + m_fdc->dor_w(data); +} + +uint8_t spectrum_d80v2_device::mreq_r(offs_t offset) +{ + uint8_t data = 0xff; + + if (m_romcs) + { + if (offset < 0x3800) + data = m_rom->base()[offset]; + else + data = m_ram[offset & 0x7ff]; + } + + return data; } diff --git a/src/devices/bus/spectrum/d40.h b/src/devices/bus/spectrum/d40.h index 42bd876bf0a..2cef4143814 100644 --- a/src/devices/bus/spectrum/d40.h +++ b/src/devices/bus/spectrum/d40.h @@ -15,32 +15,29 @@ //#include "softlist.h" #include "imagedev/floppy.h" #include "machine/wd_fdc.h" +#include "machine/upd765.h" +#include "machine/i8255.h" #include "formats/d40_dsk.h" +#include "formats/pc_dsk.h" //************************************************************************** // TYPE DEFINITIONS //************************************************************************** -class spectrum_d40_device: public device_t, public device_spectrum_expansion_interface +class spectrum_d40base_device: public device_t, public device_spectrum_expansion_interface { public: - // construction/destruction - spectrum_d40_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - - DECLARE_FLOPPY_FORMATS(floppy_formats); DECLARE_INPUT_CHANGED_MEMBER(snapshot_button); protected: - spectrum_d40_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + spectrum_d40base_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_reset() override; // optional information overrides - virtual void device_add_mconfig(machine_config &config) override; virtual ioport_constructor device_input_ports() const override; - virtual const tiny_rom_entry *device_rom_region() const override; virtual void pre_opcode_fetch(offs_t offset) override; virtual uint8_t mreq_r(offs_t offset) override; @@ -49,31 +46,89 @@ protected: virtual void iorq_w(offs_t offset, uint8_t data) override; virtual DECLARE_READ_LINE_MEMBER(romcs) override; - void fdc_intrq_w(int state); - void fdc_drq_w(int state); + virtual uint8_t fdc0_r(offs_t offset) { return 0xff; }; + virtual uint8_t fdc1_r(offs_t offset) { return 0xff; }; + virtual void fdc0_w(offs_t offset, uint8_t data) { }; + virtual void fdc1_w(offs_t offset, uint8_t data) { }; + virtual void nmi_check(); required_memory_region m_rom; - required_device m_fdc; - required_device_array m_floppy; + required_device m_ppi; + required_ioport m_snap; int m_romcs; uint8_t m_ram[2 * 1024]; - uint8_t m_control; int m_snap_flag; + int m_8255_reset; + int m_8255_enable; +}; + +class spectrum_d40_device : + public spectrum_d40base_device +{ +public: + spectrum_d40_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + DECLARE_FLOPPY_FORMATS(floppy_formats); +protected: + spectrum_d40_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + virtual void device_add_mconfig(machine_config &config) override; + virtual const tiny_rom_entry *device_rom_region() const override; + + virtual void device_start() override; + virtual void device_reset() override; + + required_device m_fdc; + required_device_array m_floppy; + + virtual uint8_t fdc0_r(offs_t offset) override; + virtual void fdc0_w(offs_t offset, uint8_t data) override; + virtual void fdc1_w(offs_t offset, uint8_t data) override; + void fdc_intrq_w(int state); + void fdc_drq_w(int state); + virtual void nmi_check() override; + + uint8_t m_control; + int m_intrq; + int m_drq; }; class spectrum_d80_device : public spectrum_d40_device { public: - // construction/destruction spectrum_d80_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + virtual void device_add_mconfig(machine_config &config) override; +}; + +class spectrum_d80v2_device : + public spectrum_d40base_device +{ +public: + spectrum_d80v2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + DECLARE_FLOPPY_FORMATS(floppy_formats); protected: virtual void device_add_mconfig(machine_config &config) override; + virtual const tiny_rom_entry *device_rom_region() const override; + + virtual void pre_opcode_fetch(offs_t offset) override; + virtual uint8_t mreq_r(offs_t offset) override; + + required_device m_fdc; + required_device_array m_floppy; + + virtual uint8_t fdc0_r(offs_t offset) override; + virtual uint8_t fdc1_r(offs_t offset) override; + virtual void fdc0_w(offs_t offset, uint8_t data) override; + virtual void fdc1_w(offs_t offset, uint8_t data) override; }; // device type definition DECLARE_DEVICE_TYPE(SPECTRUM_D40, spectrum_d40_device) DECLARE_DEVICE_TYPE(SPECTRUM_D80, spectrum_d80_device) +DECLARE_DEVICE_TYPE(SPECTRUM_D80V2, spectrum_d80v2_device) #endif // MAME_BUS_SPECTRUM_D40_H diff --git a/src/devices/bus/spectrum/exp.cpp b/src/devices/bus/spectrum/exp.cpp index 10fac7b65d8..57b8bceaa8a 100644 --- a/src/devices/bus/spectrum/exp.cpp +++ b/src/devices/bus/spectrum/exp.cpp @@ -197,6 +197,7 @@ void spectrum_expansion_devices(device_slot_interface &device) device.option_add("plusd", SPECTRUM_PLUSD); device.option_add("d40", SPECTRUM_D40); device.option_add("d80", SPECTRUM_D80); + device.option_add("d80v2", SPECTRUM_D80V2); device.option_add("protek", SPECTRUM_PROTEK); device.option_add("specdrum", SPECTRUM_SPECDRUM); device.option_add("uslot", SPECTRUM_USLOT); @@ -216,8 +217,6 @@ void spec128_expansion_devices(device_slot_interface &device) device.option_add("mikroplus", SPECTRUM_MIKROPLUS); device.option_add("mprint", SPECTRUM_MPRINT); device.option_add("opus", SPECTRUM_OPUS); - //device.option_add("d40", SPECTRUM_D40); - //device.option_add("d80", SPECTRUM_D80); //device.option_add("plusd", SPECTRUM_PLUSD); device.option_add("plus2test", SPECTRUM_PLUS2TEST); device.option_add("protek", SPECTRUM_PROTEK); -- cgit v1.2.3