summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices
diff options
context:
space:
mode:
author 987123879113 <63495610+987123879113@users.noreply.github.com>2021-03-02 14:03:35 +0900
committer GitHub <noreply@github.com>2021-03-02 16:03:35 +1100
commiteb2ea5d355f54fa741e4a7e4cc208a0dd46bb5a7 (patch)
tree82fb32e06517911dc0d7bf6983e1efaf27388056 /src/devices
parent8c9c79217e7db72a733204ca5086e28911456bcd (diff)
-machine/fdc37c665gt.cpp: Reimplemented with floppy and parallel support.
-mahine/upd765.cpp: Implemented sector-based termination conditions for read commands.
Diffstat (limited to 'src/devices')
-rw-r--r--src/devices/machine/fdc37c665gt.cpp467
-rw-r--r--src/devices/machine/fdc37c665gt.h122
-rw-r--r--src/devices/machine/upd765.cpp20
3 files changed, 563 insertions, 46 deletions
diff --git a/src/devices/machine/fdc37c665gt.cpp b/src/devices/machine/fdc37c665gt.cpp
index 90f78c77e54..d95acc0358c 100644
--- a/src/devices/machine/fdc37c665gt.cpp
+++ b/src/devices/machine/fdc37c665gt.cpp
@@ -1,58 +1,463 @@
// license:BSD-3-Clause
-// copyright-holders:smf
+// copyright-holders: Samuele Zannoli, windyfairy
+/***************************************************************************
+
+FDC37C665GT.h
+
+SMSC FDC37C665GT High Performance Multi-Mode Parallel Port Super I/O Floppy Disk Controllers
+
+***************************************************************************/
+
#include "emu.h"
-#include "fdc37c665gt.h"
+#include "machine/fdc37c665gt.h"
+
+#define LOG_CONFIG (1U << 1) // Show global configuration changes
+
+#define VERBOSE (LOG_GENERAL | LOG_CONFIG)
+// #define LOG_OUTPUT_STREAM std::cout
+
+#include "logmacro.h"
+
+#define LOGCONFIG(...) LOGMASKED(LOG_CONFIG, __VA_ARGS__)
+
+DEFINE_DEVICE_TYPE(FDC37C665GT, fdc37c665gt_device, "fdc37c665gt", "FDC37C665GT")
-fdc37c665gt_device::fdc37c665gt_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
- device_t(mconfig, FDC37C665GT, tag, owner, clock),
- m_uart1(*this, "uart1"),
- m_uart2(*this, "uart2")
+fdc37c665gt_device::fdc37c665gt_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, upd765_family_device::mode_t floppy_mode)
+ : device_t(mconfig, FDC37C665GT, tag, owner, clock)
+ , mode(OperatingMode::Run)
+ , config_key_step(0)
+ , config_index(0)
+ , m_floppy_mode(floppy_mode)
+ , m_fintr_callback(*this)
+ , m_fdrq_callback(*this)
+ , m_pintr1_callback(*this)
+ , m_irq3_callback(*this)
+ , m_irq4_callback(*this)
+ , m_txd1_callback(*this)
+ , m_ndtr1_callback(*this)
+ , m_nrts1_callback(*this)
+ , m_txd2_callback(*this)
+ , m_ndtr2_callback(*this)
+ , m_nrts2_callback(*this)
+ , m_fdc(*this, "fdc")
+ , m_serial(*this, "uart%u", 1)
+ , m_lpt(*this, "lpt")
{
}
+void fdc37c665gt_device::device_start()
+{
+ m_fintr_callback.resolve_safe();
+ m_fdrq_callback.resolve_safe();
+ m_pintr1_callback.resolve_safe();
+ m_irq3_callback.resolve_safe();
+ m_irq4_callback.resolve_safe();
+ m_txd1_callback.resolve_safe();
+ m_ndtr1_callback.resolve_safe();
+ m_nrts1_callback.resolve_safe();
+ m_txd2_callback.resolve_safe();
+ m_ndtr2_callback.resolve_safe();
+ m_nrts2_callback.resolve_safe();
+
+ // Configuration registers and related bits aren't affected by soft resets
+ // Default addresses
+ com_addresses[0] = 0x3f8;
+ com_addresses[1] = 0x2f8;
+ com_addresses[2] = 0x338;
+ com_addresses[3] = 0x238;
+
+ device_addresses[LogicalDevice::IDE] = 0x1f0;
+ device_addresses[LogicalDevice::FDC] = 0x3f0;
+ device_addresses[LogicalDevice::Parallel] = 0x278;
+ device_addresses[LogicalDevice::Serial1] = 0; // COM port
+ device_addresses[LogicalDevice::Serial2] = 1; // COM port
+
+ const uint8_t configuration_registers_defaults[] = {
+ 0x3b, 0x9f, 0xdc, 0x78, 0x00,
+ 0x00, 0xff, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x66, 0x01, 0x00
+ };
+
+ // Set the value first and then use write_configuration_register because some flags
+ // rely on other flags being initialized properly first
+ std::copy(std::begin(configuration_registers_defaults), std::end(configuration_registers_defaults), std::begin(configuration_registers));
+ for (int i = 0; i < std::size(configuration_registers_defaults); i++) {
+ write_configuration_register(i, configuration_registers_defaults[i]);
+ }
+}
+
+void fdc37c665gt_device::device_add_mconfig(machine_config &config)
+{
+ // floppy disc controller
+ N82077AA(config, m_fdc, 24_MHz_XTAL, m_floppy_mode);
+ m_fdc->intrq_wr_callback().set(FUNC(fdc37c665gt_device::irq_floppy_w));
+
+ // parallel port
+ PC_LPT(config, m_lpt);
+ m_lpt->irq_handler().set(FUNC(fdc37c665gt_device::irq_parallel_w));
+
+ // serial ports
+ NS16550(config, m_serial[0], clock() / 13);
+ m_serial[0]->out_int_callback().set(FUNC(fdc37c665gt_device::irq_serial1_w));
+ m_serial[0]->out_tx_callback().set(FUNC(fdc37c665gt_device::txd_serial1_w));
+ m_serial[0]->out_dtr_callback().set(FUNC(fdc37c665gt_device::dtr_serial1_w));
+ m_serial[0]->out_rts_callback().set(FUNC(fdc37c665gt_device::rts_serial1_w));
+
+ NS16550(config, m_serial[1], clock() / 13);
+ m_serial[1]->out_int_callback().set(FUNC(fdc37c665gt_device::irq_serial2_w));
+ m_serial[1]->out_tx_callback().set(FUNC(fdc37c665gt_device::txd_serial2_w));
+ m_serial[1]->out_dtr_callback().set(FUNC(fdc37c665gt_device::dtr_serial2_w));
+ m_serial[1]->out_rts_callback().set(FUNC(fdc37c665gt_device::rts_serial2_w));
+}
+
uint8_t fdc37c665gt_device::read(offs_t offset)
{
- uint8_t data = 0;
+ // TODO: IDE not implemented
+
+ // Parallel port
+ if (offset >= device_addresses[LogicalDevice::Parallel] && offset <= device_addresses[LogicalDevice::Parallel] + 2) {
+ if (!enabled_logical[LogicalDevice::Parallel]) {
+ return 0;
+ }
- if ((offset & 0x3f8) == 0x3f8)
- {
- data = m_uart1->ins8250_r(offset & 7);
+ return m_lpt->read(offset - device_addresses[LogicalDevice::Parallel]);
}
- else if ((offset & 0x3f8) == 0x2f8)
- {
- data = m_uart2->ins8250_r(offset & 7);
+
+ // Serial 1
+ if (offset >= com_addresses[device_addresses[LogicalDevice::Serial1]] && offset <= com_addresses[device_addresses[LogicalDevice::Serial1]] + 7) {
+ if (!enabled_logical[LogicalDevice::Serial1]) {
+ return 0;
+ }
+
+ return m_serial[0]->ins8250_r(offset - device_addresses[LogicalDevice::Serial1]);
+ }
+
+ // Serial 2
+ if (offset >= com_addresses[device_addresses[LogicalDevice::Serial2]] && offset <= com_addresses[device_addresses[LogicalDevice::Serial2]] + 7) {
+ if (!enabled_logical[LogicalDevice::Serial2]) {
+ return 0;
+ }
+
+ return m_serial[1]->ins8250_r(offset - device_addresses[LogicalDevice::Serial2]);
}
- else
- {
- printf("fdc37c665gt_device::read %04x %02x\n", offset, data);
+
+ // FDC, +6 is used by IDE
+ if ((offset >= device_addresses[LogicalDevice::FDC] && offset <= device_addresses[LogicalDevice::FDC] + 5)
+ || offset == device_addresses[LogicalDevice::FDC] + 7) {
+ if (!enabled_logical[LogicalDevice::FDC]) {
+ return 0;
+ }
+
+ switch (offset - device_addresses[LogicalDevice::FDC]) {
+ case 0: return m_fdc->sra_r();
+ case 1: return m_fdc->srb_r();
+ case 2: return m_fdc->dor_r();
+ case 3: return m_fdc->tdr_r();
+ case 4: return m_fdc->msr_r();
+ case 5: return m_fdc->fifo_r();
+ case 7: return m_fdc->dir_r();
+ }
}
- return data;
+
+ return 0;
}
void fdc37c665gt_device::write(offs_t offset, uint8_t data)
{
- if ((offset & 0x3f8) == 0x3f8)
- {
- m_uart1->ins8250_w(offset & 7, data);
+ // TODO: IDE not implemented
+
+ // Parallel port
+ if (offset >= device_addresses[LogicalDevice::Parallel] && offset <= device_addresses[LogicalDevice::Parallel] + 2) {
+ if (!enabled_logical[LogicalDevice::Parallel]) {
+ return;
+ }
+
+ m_lpt->write(offset - device_addresses[LogicalDevice::Parallel], data);
+ return;
}
- else if ((offset & 0x3f8) == 0x2f8)
- {
- m_uart2->ins8250_w(offset & 7, data);
+
+ // Serial 1
+ if (offset >= device_addresses[LogicalDevice::Serial1] && offset <= device_addresses[LogicalDevice::Serial1] + 7) {
+ if (!enabled_logical[LogicalDevice::Serial1]) {
+ return;
+ }
+
+ m_serial[0]->ins8250_w(offset - device_addresses[LogicalDevice::Serial1], data);
+ return;
}
- else
- {
- printf("fdc37c665gt_device::write %04x %02x\n", offset, data);
+
+ // Serial 2
+ if (offset >= device_addresses[LogicalDevice::Serial2] && offset <= device_addresses[LogicalDevice::Serial2] + 7) {
+ if (!enabled_logical[LogicalDevice::Serial2]) {
+ return;
+ }
+
+ m_serial[1]->ins8250_w(offset - device_addresses[LogicalDevice::Serial2], data);
+ return;
+ }
+
+ // FDC, +6 is used by IDE
+ if ((offset >= device_addresses[LogicalDevice::FDC] && offset <= device_addresses[LogicalDevice::FDC] + 5)
+ || offset == device_addresses[LogicalDevice::FDC] + 7) {
+ auto fdc_offset = offset - device_addresses[LogicalDevice::FDC];
+
+ if ((!enabled_logical[LogicalDevice::FDC] && fdc_offset > 1)) {
+ return;
+ }
+
+ switch (fdc_offset) {
+ case 0: // FDC37C665GT Configuration
+ if (mode == OperatingMode::Run) {
+ if (data != 0x55) {
+ config_key_step = 0;
+ return;
+ }
+
+ config_key_step++;
+ if (config_key_step > 1) {
+ config_key_step = 0;
+ mode = OperatingMode::Configuration;
+ }
+ } else {
+ if (data == 0xaa) {
+ mode = OperatingMode::Run;
+ return;
+ }
+
+ config_index = data;
+ }
+ return;
+
+ case 1: // FDC37C665GT Configuration
+ if (mode == OperatingMode::Run) {
+ config_key_step = 0;
+ return;
+ }
+
+ write_configuration_register(config_index, data & 0xff);
+ return;
+
+ case 2: m_fdc->dor_w(data); return;
+ case 3: m_fdc->tdr_w(data); return;
+ case 4: m_fdc->dsr_w(data); return;
+ case 5: m_fdc->fifo_w(data); return;
+ case 7: m_fdc->ccr_w(data); return;
+ }
}
}
-void fdc37c665gt_device::device_start()
+void fdc37c665gt_device::write_configuration_register(int index, int data)
+{
+ if (BIT(configuration_registers[1], 7) == 0) {
+ // Bit 7 of CR1 is LOCK CRx
+ // When this is set to 0, it can only be set back to 1 by a hard reset or power-up reset
+ LOGCONFIG("IGNORED configuration register cr[%02x] = %02x\n", index, data);
+ return;
+ }
+
+ configuration_registers[index] = data;
+ LOGCONFIG("Modified configuration register cr[%02x] = %02x\n", index, data);
+
+ if (index == 0) {
+ enabled_logical[LogicalDevice::IDE] = BIT(configuration_registers[index], 1);
+ enabled_logical[LogicalDevice::FDC] = BIT(configuration_registers[index], 3) && BIT(configuration_registers[index], 4);
+ } else if (index == 1) {
+ enabled_logical[LogicalDevice::Parallel] = BIT(configuration_registers[index], 2) && BIT(configuration_registers[index], 3);
+
+ auto lpt_port = BIT(configuration_registers[index], 0, 2);
+ if (lpt_port == 0) {
+ enabled_logical[LogicalDevice::Parallel] = false; // Disabled
+ } else if (lpt_port == 1) {
+ device_addresses[LogicalDevice::Parallel] = 0x3bc;
+ } else if (lpt_port == 2) {
+ device_addresses[LogicalDevice::Parallel] = 0x378;
+ } else if (lpt_port == 3) {
+ device_addresses[LogicalDevice::Parallel] = 0x278; // Default
+ }
+
+ auto com34 = BIT(configuration_registers[index], 5, 2);
+ if (com34 == 0) {
+ com_addresses[2] = 0x338;
+ com_addresses[3] = 0x238;
+ } else if (com34 == 1) {
+ com_addresses[2] = 0x3e8;
+ com_addresses[3] = 0x2e8;
+ } else if (com34 == 2) {
+ com_addresses[2] = 0x2e8;
+ com_addresses[3] = 0x2e0;
+ } else if (com34 == 3) {
+ com_addresses[2] = 0x220;
+ com_addresses[3] = 0x228;
+ }
+ } else if (index == 2) {
+ enabled_logical[LogicalDevice::Serial1] = BIT(configuration_registers[index], 2) && BIT(configuration_registers[index], 3);
+ device_addresses[LogicalDevice::Serial1] = BIT(configuration_registers[index], 0, 2);
+
+ enabled_logical[LogicalDevice::Serial2] = BIT(configuration_registers[index], 6) && BIT(configuration_registers[index], 7);
+ device_addresses[LogicalDevice::Serial2] = BIT(configuration_registers[index], 4, 2);
+ } else if (index == 3) {
+ auto floppy_mode = BIT(configuration_registers[index], 5, 2);
+
+ // 2 is reserved/unused
+ if (floppy_mode == 3) {
+ m_floppy_mode = upd765_family_device::mode_t::AT;
+ } else if (floppy_mode == 1) {
+ m_floppy_mode = upd765_family_device::mode_t::PS2;
+ } else if (floppy_mode == 0) {
+ m_floppy_mode = upd765_family_device::mode_t::M30;
+ }
+
+ m_fdc->set_mode(m_floppy_mode);
+ } else if (index == 4) {
+ // Set clock speeds for MIDI modes (clock divisor becomes 12 instead of 13)
+ m_serial[0]->set_unscaled_clock(clock() / (13 - BIT(configuration_registers[4], 4)));
+ m_serial[1]->set_unscaled_clock(clock() / (13 - BIT(configuration_registers[5], 5)));
+ } else if (index == 5) {
+ auto fdc_port = BIT(configuration_registers[index], 0);
+ if (fdc_port == 0) {
+ device_addresses[LogicalDevice::FDC] = 0x3f0;
+ } else if (fdc_port == 1) {
+ device_addresses[LogicalDevice::FDC] = 0x370;
+ }
+ }
+}
+
+WRITE_LINE_MEMBER(fdc37c665gt_device::irq_floppy_w)
{
+ if (!enabled_logical[LogicalDevice::FDC]) {
+ return;
+ }
+
+ m_fintr_callback(state);
}
-void fdc37c665gt_device::device_add_mconfig(machine_config &config)
+WRITE_LINE_MEMBER(fdc37c665gt_device::irq_parallel_w)
{
- NS16550(config, m_uart1, XTAL(24'000'000)/13);
- NS16550(config, m_uart2, XTAL(24'000'000)/13);
+ if (!enabled_logical[LogicalDevice::Parallel]) {
+ return;
+ }
+
+ m_pintr1_callback(state);
}
-DEFINE_DEVICE_TYPE(FDC37C665GT, fdc37c665gt_device, "fdc37c665gt", "FDC37C665GT")
+WRITE_LINE_MEMBER(fdc37c665gt_device::irq_serial1_w)
+{
+ if (!enabled_logical[LogicalDevice::Serial1]) {
+ return;
+ }
+
+ m_irq4_callback(state);
+}
+
+WRITE_LINE_MEMBER(fdc37c665gt_device::txd_serial1_w)
+{
+ if (!enabled_logical[LogicalDevice::Serial1]) {
+ return;
+ }
+
+ m_txd1_callback(state);
+}
+
+WRITE_LINE_MEMBER(fdc37c665gt_device::dtr_serial1_w)
+{
+ if (!enabled_logical[LogicalDevice::Serial1]) {
+ return;
+ }
+
+ m_ndtr1_callback(state);
+}
+
+WRITE_LINE_MEMBER(fdc37c665gt_device::rts_serial1_w)
+{
+ if (!enabled_logical[LogicalDevice::Serial1]) {
+ return;
+ }
+
+ m_nrts1_callback(state);
+}
+
+WRITE_LINE_MEMBER(fdc37c665gt_device::irq_serial2_w)
+{
+ if (!enabled_logical[LogicalDevice::Serial2]) {
+ return;
+ }
+
+ m_irq3_callback(state);
+}
+
+WRITE_LINE_MEMBER(fdc37c665gt_device::txd_serial2_w)
+{
+ if (!enabled_logical[LogicalDevice::Serial2]) {
+ return;
+ }
+
+ m_txd2_callback(state);
+}
+
+WRITE_LINE_MEMBER(fdc37c665gt_device::dtr_serial2_w)
+{
+ if (!enabled_logical[LogicalDevice::Serial2]) {
+ return;
+ }
+
+ m_ndtr2_callback(state);
+}
+
+WRITE_LINE_MEMBER(fdc37c665gt_device::rts_serial2_w)
+{
+ if (!enabled_logical[LogicalDevice::Serial2]) {
+ return;
+ }
+
+ m_nrts2_callback(state);
+}
+
+WRITE_LINE_MEMBER(fdc37c665gt_device::rxd1_w)
+{
+ m_serial[0]->rx_w(state);
+}
+
+WRITE_LINE_MEMBER(fdc37c665gt_device::ndcd1_w)
+{
+ m_serial[0]->dcd_w(state);
+}
+
+WRITE_LINE_MEMBER(fdc37c665gt_device::ndsr1_w)
+{
+ m_serial[0]->dsr_w(state);
+}
+
+WRITE_LINE_MEMBER(fdc37c665gt_device::nri1_w)
+{
+ m_serial[0]->ri_w(state);
+}
+
+WRITE_LINE_MEMBER(fdc37c665gt_device::ncts1_w)
+{
+ m_serial[0]->cts_w(state);
+}
+
+WRITE_LINE_MEMBER(fdc37c665gt_device::rxd2_w)
+{
+ m_serial[1]->rx_w(state);
+}
+
+WRITE_LINE_MEMBER(fdc37c665gt_device::ndcd2_w)
+{
+ m_serial[1]->dcd_w(state);
+}
+
+WRITE_LINE_MEMBER(fdc37c665gt_device::ndsr2_w)
+{
+ m_serial[1]->dsr_w(state);
+}
+
+WRITE_LINE_MEMBER(fdc37c665gt_device::nri2_w)
+{
+ m_serial[1]->ri_w(state);
+}
+
+WRITE_LINE_MEMBER(fdc37c665gt_device::ncts2_w)
+{
+ m_serial[1]->cts_w(state);
+}
diff --git a/src/devices/machine/fdc37c665gt.h b/src/devices/machine/fdc37c665gt.h
index df733078aae..6b90fc8341e 100644
--- a/src/devices/machine/fdc37c665gt.h
+++ b/src/devices/machine/fdc37c665gt.h
@@ -1,37 +1,133 @@
// license:BSD-3-Clause
-// copyright-holders:smf
-/*
-* fdc37c665gt.h
-*
-*/
+// copyright-holders: Samuele Zannoli, windyfairy
+/***************************************************************************
+
+FDC37C665GT.h
+
+SMSC FDC37C665GT High Performance Multi-Mode Parallel Port Super I/O Floppy Disk Controllers
+
+***************************************************************************/
#ifndef MAME_MACHINE_FDC37C665GT_H
#define MAME_MACHINE_FDC37C665GT_H
#pragma once
-#include "ins8250.h"
+// floppy disk controller
+#include "machine/upd765.h"
+#include "imagedev/floppy.h"
+#include "formats/pc_dsk.h"
+// parallel port
+#include "machine/pc_lpt.h"
+// serial port
+#include "machine/ins8250.h"
class fdc37c665gt_device : public device_t
{
public:
- // construction/destruction
- fdc37c665gt_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ fdc37c665gt_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : fdc37c665gt_device(mconfig, tag, owner, clock, upd765_family_device::mode_t::AT)
+ { }
+
+ fdc37c665gt_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, upd765_family_device::mode_t floppy_mode);
+
+ // optional information overrides
+ virtual void device_add_mconfig(machine_config &config) override;
+ // to access io ports
uint8_t read(offs_t offset);
void write(offs_t offset, uint8_t data);
+ auto fintr() { return m_fintr_callback.bind(); }
+ auto fdrq() { return m_fdrq_callback.bind(); }
+ auto txd1() { return m_txd1_callback.bind(); }
+ auto ndtr1() { return m_ndtr1_callback.bind(); }
+ auto nrts1() { return m_nrts1_callback.bind(); }
+ auto txd2() { return m_txd2_callback.bind(); }
+ auto ndtr2() { return m_ndtr2_callback.bind(); }
+ auto nrts2() { return m_nrts2_callback.bind(); }
+
+ // chip pins for uarts
+ DECLARE_WRITE_LINE_MEMBER(rxd1_w);
+ DECLARE_WRITE_LINE_MEMBER(ndcd1_w);
+ DECLARE_WRITE_LINE_MEMBER(ndsr1_w);
+ DECLARE_WRITE_LINE_MEMBER(nri1_w);
+ DECLARE_WRITE_LINE_MEMBER(ncts1_w);
+ DECLARE_WRITE_LINE_MEMBER(rxd2_w);
+ DECLARE_WRITE_LINE_MEMBER(ndcd2_w);
+ DECLARE_WRITE_LINE_MEMBER(ndsr2_w);
+ DECLARE_WRITE_LINE_MEMBER(nri2_w);
+ DECLARE_WRITE_LINE_MEMBER(ncts2_w);
+
protected:
// device-level overrides
virtual void device_start() override;
- virtual void device_add_mconfig(machine_config &config) override;
+
+ // for the internal floppy controller
+ DECLARE_WRITE_LINE_MEMBER(irq_floppy_w);
+
+ // for the internal parallel port
+ DECLARE_WRITE_LINE_MEMBER(irq_parallel_w);
+
+ // for the internal uarts
+ DECLARE_WRITE_LINE_MEMBER(irq_serial1_w);
+ DECLARE_WRITE_LINE_MEMBER(txd_serial1_w);
+ DECLARE_WRITE_LINE_MEMBER(dtr_serial1_w);
+ DECLARE_WRITE_LINE_MEMBER(rts_serial1_w);
+ DECLARE_WRITE_LINE_MEMBER(irq_serial2_w);
+ DECLARE_WRITE_LINE_MEMBER(txd_serial2_w);
+ DECLARE_WRITE_LINE_MEMBER(dtr_serial2_w);
+ DECLARE_WRITE_LINE_MEMBER(rts_serial2_w);
private:
- required_device<ns16550_device> m_uart1;
- required_device<ns16550_device> m_uart2;
+ // put your private members here
+ enum OperatingMode
+ {
+ Run = 0,
+ Configuration = 1
+ } mode;
+
+ enum LogicalDevice
+ {
+ FDC = 0,
+ IDE,
+ Parallel,
+ Serial1,
+ Serial2,
+
+ LogicalDeviceEnd
+ };
+
+ int config_key_step;
+ int config_index;
+ bool enabled_logical[LogicalDevice::LogicalDeviceEnd];
+ int device_addresses[LogicalDevice::LogicalDeviceEnd];
+ int com_addresses[4];
+
+ upd765_family_device::mode_t m_floppy_mode;
+
+ uint8_t configuration_registers[16];
+
+ devcb_write_line m_fintr_callback;
+ devcb_write_line m_fdrq_callback;
+ devcb_write_line m_pintr1_callback; // Parallel
+ devcb_write_line m_irq3_callback; // Serial Port COM1/COM3
+ devcb_write_line m_irq4_callback; // Serial Port COM2/COM4
+
+ devcb_write_line m_txd1_callback;
+ devcb_write_line m_ndtr1_callback;
+ devcb_write_line m_nrts1_callback;
+ devcb_write_line m_txd2_callback;
+ devcb_write_line m_ndtr2_callback;
+ devcb_write_line m_nrts2_callback;
+
+ required_device<n82077aa_device> m_fdc;
+ required_device_array<ns16550_device, 2> m_serial;
+ required_device<pc_lpt_device> m_lpt;
+
+ void write_configuration_register(int index, int data);
};
-// device type definition
-DECLARE_DEVICE_TYPE(FDC37C665GT, fdc37c665gt_device)
+DECLARE_DEVICE_TYPE(FDC37C665GT, fdc37c665gt_device);
#endif // MAME_MACHINE_FDC37C665GT_H
diff --git a/src/devices/machine/upd765.cpp b/src/devices/machine/upd765.cpp
index f2eff71730e..1ad53ec9ae0 100644
--- a/src/devices/machine/upd765.cpp
+++ b/src/devices/machine/upd765.cpp
@@ -679,8 +679,8 @@ uint8_t upd765_family_device::fifo_pop(bool internal)
memmove(fifo, fifo+1, fifo_pos);
if(!fifo_write && !fifo_pos)
disable_transfer();
- int thr = fifocfg & 15;
- if(fifo_write && fifo_expected && (fifo_pos <= thr || (fifocfg & 0x20)))
+ int thr = fifocfg & FIF_THR;
+ if(fifo_write && fifo_expected && (fifo_pos <= thr || (fifocfg & FIF_DIS)))
enable_transfer();
return r;
}
@@ -977,6 +977,13 @@ void upd765_family_device::live_run(attotime limit)
return;
}
+ if (
+ ((command[0] & 0x08) == 0 && cur_live.data_reg == 0xf8) // Encountered deleted sector during read data
+ || ((command[0] & 0x08) != 0 && cur_live.data_reg == 0xfb) // Encountered normal sector during read deleted data
+ ) {
+ st2 |= ST2_CM;
+ }
+
cur_live.bit_counter = 0;
cur_live.state = READ_SECTOR_DATA;
break;
@@ -1882,6 +1889,15 @@ void upd765_family_device::read_data_continue(floppy_info &fi)
fi.sub_state = COMMAND_DONE;
break;
}
+
+ if ((st2 & ST2_CM) && !(command[0] & 0x20)) {
+ // Encountered terminating sector while in non-skip mode.
+ // This will stop reading when a normal data sector is encountered during read deleted data,
+ // or when a deleted sector is encountered during a read data command.
+ fi.sub_state = COMMAND_DONE;
+ break;
+ }
+
bool done = tc_done;
if(command[4] == command[6]) {
if(command[0] & 0x80) {