diff options
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 |
commit | eb2ea5d355f54fa741e4a7e4cc208a0dd46bb5a7 (patch) | |
tree | 82fb32e06517911dc0d7bf6983e1efaf27388056 /src/devices | |
parent | 8c9c79217e7db72a733204ca5086e28911456bcd (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.cpp | 467 | ||||
-rw-r--r-- | src/devices/machine/fdc37c665gt.h | 122 | ||||
-rw-r--r-- | src/devices/machine/upd765.cpp | 20 |
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) { |