From 402dd6aba09c74a4c0e1f918116c95ebef936e8d Mon Sep 17 00:00:00 2001 From: Dirk Best Date: Mon, 1 May 2023 03:51:28 +0200 Subject: [PATCH] mc68000: Add floppy support --- scripts/src/bus.lua | 2 + src/devices/bus/mc68000/cards.cpp | 2 + src/devices/bus/mc68000/floppy.cpp | 169 +++++++++++++++++++++++++++++ src/devices/bus/mc68000/floppy.h | 48 ++++++++ src/devices/bus/mc68000/sysbus.cpp | 18 +++ src/devices/bus/mc68000/sysbus.h | 6 + src/mame/mc/mc68000.cpp | 8 +- 7 files changed, 248 insertions(+), 5 deletions(-) create mode 100644 src/devices/bus/mc68000/floppy.cpp create mode 100644 src/devices/bus/mc68000/floppy.h diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index 120c688f22b..81a00d18fb7 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -5250,6 +5250,8 @@ if (BUSES["MC68000_SYSBUS"]~=null) then MAME_DIR .. "src/devices/bus/mc68000/sysbus.h", MAME_DIR .. "src/devices/bus/mc68000/cards.cpp", MAME_DIR .. "src/devices/bus/mc68000/cards.h", + MAME_DIR .. "src/devices/bus/mc68000/floppy.cpp", + MAME_DIR .. "src/devices/bus/mc68000/floppy.h", MAME_DIR .. "src/devices/bus/mc68000/ram.cpp", MAME_DIR .. "src/devices/bus/mc68000/ram.h", } diff --git a/src/devices/bus/mc68000/cards.cpp b/src/devices/bus/mc68000/cards.cpp index 97389721bec..2cebfd660af 100644 --- a/src/devices/bus/mc68000/cards.cpp +++ b/src/devices/bus/mc68000/cards.cpp @@ -9,9 +9,11 @@ #include "emu.h" #include "cards.h" +#include "floppy.h" #include "ram.h" void mc68000_sysbus_cards(device_slot_interface &device) { + device.option_add("floppy", MC68000_FLOPPY); device.option_add("ram", MC68000_RAM); } diff --git a/src/devices/bus/mc68000/floppy.cpp b/src/devices/bus/mc68000/floppy.cpp new file mode 100644 index 00000000000..abc14640f17 --- /dev/null +++ b/src/devices/bus/mc68000/floppy.cpp @@ -0,0 +1,169 @@ +// license: BSD-3-Clause +// copyright-holders: Dirk Best +/*************************************************************************** + + mc-68000-Computer Floppy Interface Card + + TODO: + - Jumpers can change the meaning of some lines + + Notes: + - Has two bus interfaces and supports up to 8 drives + - Can either use the 1793 or 1797 + +***************************************************************************/ + +#include "emu.h" +#include "floppy.h" + +#define VERBOSE 0 + +DEFINE_DEVICE_TYPE(MC68000_FLOPPY, mc68000_floppy_device, "mc68000_floppy", "mc-68000 Floppy Interface") + +mc68000_floppy_device::mc68000_floppy_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, MC68000_FLOPPY, tag, owner, clock), + device_mc68000_sysbus_card_interface(mconfig, *this), + m_fdc(*this, "fdc"), + m_floppy(*this, "fdc:%u", 0U), + m_latch(0x00) +{ +} + +// very flexible regarding drive support, we just add the most common ones +static void mc68000_bus1_floppies(device_slot_interface &device) +{ + device.option_add("35dd", FLOPPY_35_DD); + device.option_add("525qd", FLOPPY_525_QD); +} + +static void mc68000_bus2_floppies(device_slot_interface &device) +{ + device.option_add("8dsdd", FLOPPY_8_DSDD); +} + +void mc68000_floppy_device::device_add_mconfig(machine_config &config) +{ + FD1793(config, m_fdc, 16_MHz_XTAL / 8); + m_fdc->intrq_wr_callback().set(FUNC(mc68000_floppy_device::intrq_w)); + m_fdc->drq_wr_callback().set(FUNC(mc68000_floppy_device::drq_w)); + + // floppy drive bus 1 + FLOPPY_CONNECTOR(config, m_floppy[0], mc68000_bus1_floppies, "525qd", floppy_image_device::default_mfm_floppy_formats); + FLOPPY_CONNECTOR(config, m_floppy[1], mc68000_bus1_floppies, "525qd", floppy_image_device::default_mfm_floppy_formats); + FLOPPY_CONNECTOR(config, m_floppy[2], mc68000_bus1_floppies, nullptr, floppy_image_device::default_mfm_floppy_formats); + FLOPPY_CONNECTOR(config, m_floppy[3], mc68000_bus1_floppies, nullptr, floppy_image_device::default_mfm_floppy_formats); + + // floppy drive bus 2 + FLOPPY_CONNECTOR(config, m_floppy[4], mc68000_bus2_floppies, nullptr, floppy_image_device::default_mfm_floppy_formats); + FLOPPY_CONNECTOR(config, m_floppy[5], mc68000_bus2_floppies, nullptr, floppy_image_device::default_mfm_floppy_formats); + FLOPPY_CONNECTOR(config, m_floppy[6], mc68000_bus2_floppies, nullptr, floppy_image_device::default_mfm_floppy_formats); + FLOPPY_CONNECTOR(config, m_floppy[7], mc68000_bus2_floppies, nullptr, floppy_image_device::default_mfm_floppy_formats); +} + +void mc68000_floppy_device::device_start() +{ + // register for save states + save_item(NAME(m_latch)); +} + +void mc68000_floppy_device::device_reset() +{ + m_latch = 0x00; +} + +uint16_t mc68000_floppy_device::floppy_r(offs_t offset, uint16_t mem_mask) +{ + uint16_t data = 0xffff; + + if (ACCESSING_BITS_8_15) + { + switch (offset & 0x07) + { + case 0: + case 1: + case 2: + case 3: + data &= (m_fdc->read(offset & 0x03) << 8) | 0xff; + break; + + case 4: + // 7------- intrq from fdc + // -6------ drq from fdc + // --543210 write only + + data &= (m_latch << 8) | 0xff; + } + } + + return data & mem_mask; +} + +void mc68000_floppy_device::floppy_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + if (VERBOSE) + logerror("floppy_w: %06x = %04x & %04x\n", offset, data, mem_mask); + + if (ACCESSING_BITS_8_15) + { + data >>= 8; + + switch (offset & 0x07) + { + case 0: + case 1: + case 2: + case 3: + m_fdc->write(offset & 0x03, data); + break; + + case 4: + // 76------ read only + // --5----- side select + // ---4---- force ready + // ----3--- density select + // -----2-- bus select + // ------10 drive select + + floppy_image_device *floppy = nullptr; + + if (BIT(data, 2)) + { + // bus 1, drives 0 to 3 at 1 MHz + floppy = m_floppy[0 + (data & 0x03)]->get_device(); + m_fdc->set_clock_scale(0.5); + } + else + { + // bus 2, drives 4 to 7 at 2 MHz + floppy = m_floppy[4 + (data & 0x03)]->get_device(); + m_fdc->set_clock_scale(1.0); + } + + m_fdc->set_floppy(floppy); + + if (floppy) + { + // TODO: motor should only run for a few seconds after each access (for bus 1) + floppy->mon_w(0); + floppy->ss_w(BIT(data, 5)); + } + + m_fdc->dden_w(BIT(data, 3)); + m_fdc->set_force_ready(BIT(data, 4)); + } + } +} + +void mc68000_floppy_device::intrq_w(int state) +{ + m_latch &= ~(1 << 7); + m_latch |= state << 7; +} + +void mc68000_floppy_device::drq_w(int state) +{ + m_latch &= ~(1 << 6); + m_latch |= state << 6; + + m_bus->irq6_w(state); +} diff --git a/src/devices/bus/mc68000/floppy.h b/src/devices/bus/mc68000/floppy.h new file mode 100644 index 00000000000..e516e83cde5 --- /dev/null +++ b/src/devices/bus/mc68000/floppy.h @@ -0,0 +1,48 @@ +// license: BSD-3-Clause +// copyright-holders: Dirk Best +/*************************************************************************** + + mc-68000-Computer Floppy Interface Card + +***************************************************************************/ + +#ifndef MAME_BUS_MC68000_FLOPPY_H +#define MAME_BUS_MC68000_FLOPPY_H + +#pragma once + +#include "sysbus.h" +#include "machine/wd_fdc.h" +#include "imagedev/floppy.h" + + +class mc68000_floppy_device : public device_t, public device_mc68000_sysbus_card_interface +{ +public: + // construction/destruction + mc68000_floppy_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + virtual uint16_t floppy_r(offs_t offset, uint16_t mem_mask = ~0) override; + virtual void floppy_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0) override; + +protected: + // device_t implementation + virtual void device_add_mconfig(machine_config &config) override; + virtual void device_start() override; + virtual void device_reset() override; + +private: + required_device m_fdc; + required_device_array m_floppy; + + uint8_t m_latch; + + void intrq_w(int state); + void drq_w(int state); +}; + +// device type definition +DECLARE_DEVICE_TYPE(MC68000_FLOPPY, mc68000_floppy_device) + + +#endif // MAME_BUS_MC68000_FLOPPY_H diff --git a/src/devices/bus/mc68000/sysbus.cpp b/src/devices/bus/mc68000/sysbus.cpp index 42ca57240f6..bf7ad7b78db 100644 --- a/src/devices/bus/mc68000/sysbus.cpp +++ b/src/devices/bus/mc68000/sysbus.cpp @@ -80,6 +80,24 @@ void mc68000_sysbus_device::slot_w(int slot, offs_t offset, uint16_t data, uint1 logerror("Write to unused slot %d: %06x = %04x & %04x\n", slot, offset, data, mem_mask); } +uint16_t mc68000_sysbus_device::floppy_r(offs_t offset, uint16_t mem_mask) +{ + uint16_t data = 0xffff; + + for (int i = 0; i < 8; i++) + if (m_device_list[i]) + data &= m_device_list[i]->floppy_r(offset, mem_mask); + + return data; +} + +void mc68000_sysbus_device::floppy_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + for (int i = 0; i < 8; i++) + if (m_device_list[i]) + m_device_list[i]->floppy_w(offset, data, mem_mask); +} + //************************************************************************** // SLOT DEVICE diff --git a/src/devices/bus/mc68000/sysbus.h b/src/devices/bus/mc68000/sysbus.h index e6fef9fc34d..2d9af7d87f8 100644 --- a/src/devices/bus/mc68000/sysbus.h +++ b/src/devices/bus/mc68000/sysbus.h @@ -85,6 +85,9 @@ public: uint16_t slot_r(int slot, offs_t offset, uint16_t mem_mask = ~0); void slot_w(int slot, offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + uint16_t floppy_r(offs_t offset, uint16_t mem_mask = ~0); + void floppy_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + protected: // device_t implementation virtual void device_start() override; @@ -153,6 +156,9 @@ public: virtual uint16_t slot_r(offs_t offset, uint16_t mem_mask = ~0) { return 0xffff; } virtual void slot_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0) { } + virtual uint16_t floppy_r(offs_t offset, uint16_t mem_mask = ~0) { return 0xffff; } + virtual void floppy_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0) { } + protected: device_mc68000_sysbus_card_interface(const machine_config &mconfig, device_t &device); diff --git a/src/mame/mc/mc68000.cpp b/src/mame/mc/mc68000.cpp index 6f2db053e48..1f4af3a43c4 100644 --- a/src/mame/mc/mc68000.cpp +++ b/src/mame/mc/mc68000.cpp @@ -14,7 +14,6 @@ TODO: - Better keyboard - - Floppy - Cassette - Color/brightness levels - Sound @@ -46,7 +45,7 @@ #define LOG_IO_READ (1U << 1) #define LOG_IO_WRITE (1U << 2) -#define VERBOSE (LOG_GENERAL | LOG_IO_WRITE) +//#define VERBOSE (LOG_GENERAL | LOG_IO_WRITE | LOG_IO_READ) #include "logmacro.h" @@ -167,8 +166,7 @@ uint16_t mc68000_state::memory_r(offs_t offset, uint16_t mem_mask) break; case 2: - LOGMASKED(LOG_IO_READ, "Unhandled floppy access\n"); - data = 0xffff; + data = m_sysbus->floppy_r(offset >> 1, mem_mask); break; case 3: @@ -259,7 +257,7 @@ void mc68000_state::memory_w(offs_t offset, uint16_t data, uint16_t mem_mask) break; case 2: - LOGMASKED(LOG_IO_WRITE, "Unhandled floppy access\n"); + m_sysbus->floppy_w(offset >> 1, data, mem_mask); break; case 3: