mc68000: Add floppy support

This commit is contained in:
Dirk Best 2023-05-01 03:51:28 +02:00
parent 806694682e
commit 402dd6aba0
7 changed files with 248 additions and 5 deletions

View File

@ -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",
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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<fd1793_device> m_fdc;
required_device_array<floppy_connector, 8> 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

View File

@ -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

View File

@ -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);

View File

@ -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: