From 6ea69b0ed967c898911d51fba9b6084b506e9849 Mon Sep 17 00:00:00 2001 From: tim lindner Date: Thu, 30 Mar 2023 10:22:58 -0700 Subject: [PATCH] =?UTF-8?q?machine/wd=5Ffdc.cpp:=20Don=E2=80=99t=20clear?= =?UTF-8?q?=20DRQ=20=20on=20LDB/INTR,=20and=20fix=20spurious=20READ=20TRAC?= =?UTF-8?q?k/ADDR=20FM=20mark=20syncs.=20(#11041)=20[Peter=20Phillips,=20T?= =?UTF-8?q?im=20Lindner]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes SuperUtility 3 (MT08511) and Marble Maze on TRS-80 Color Computer. --- src/devices/machine/wd_fdc.cpp | 107 +++++++++++++++------------------ src/devices/machine/wd_fdc.h | 4 +- 2 files changed, 50 insertions(+), 61 deletions(-) diff --git a/src/devices/machine/wd_fdc.cpp b/src/devices/machine/wd_fdc.cpp index 16f0decaf3f..1ee3815c17e 100644 --- a/src/devices/machine/wd_fdc.cpp +++ b/src/devices/machine/wd_fdc.cpp @@ -136,6 +136,16 @@ static const char *const states[] = "WRITE_SECTOR_PRE_BYTE" }; +template inline uint32_t wd_fdc_device_base::live_info::shift_reg_low() const +{ + return shift_reg & make_bitmask(B); +} + +inline uint8_t wd_fdc_device_base::live_info::shift_reg_data() const +{ + return bitswap<8>(shift_reg, 14, 12, 10, 8, 6, 4, 2, 0); +} + wd_fdc_device_base::wd_fdc_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, type, tag, owner, clock), intrq_cb(*this), @@ -1079,7 +1089,6 @@ void wd_fdc_device_base::interrupt_start() main_state = sub_state = cur_live.state = IDLE; cur_live.tm = attotime::never; status &= ~S_BUSY; - drop_drq(); motor_timeout = 0; } else { // when a force interrupt command is issued and there is no @@ -1718,7 +1727,7 @@ void wd_fdc_device_base::reset_data_sync() cur_live.data_separator_phase = false; cur_live.bit_counter = 0; - cur_live.data_reg = bitswap<8>(cur_live.shift_reg, 14, 12, 10, 8, 6, 4, 2, 0); + cur_live.data_reg = cur_live.shift_reg_data(); } bool wd_fdc_device_base::write_one_bit(const attotime &limit) @@ -1804,24 +1813,17 @@ void wd_fdc_device_base::live_run(attotime limit) if(read_one_bit(limit)) return; - LOGSHIFT("%s: shift = %04x data=%02x c=%d\n", cur_live.tm.to_string(), cur_live.shift_reg, - (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) | - (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) | - (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) | - (cur_live.shift_reg & 0x0100 ? 0x10 : 0x00) | - (cur_live.shift_reg & 0x0040 ? 0x08 : 0x00) | - (cur_live.shift_reg & 0x0010 ? 0x04 : 0x00) | - (cur_live.shift_reg & 0x0004 ? 0x02 : 0x00) | - (cur_live.shift_reg & 0x0001 ? 0x01 : 0x00), + LOGSHIFT("%s: shift = %08x data=%02x c=%d\n", cur_live.tm.to_string(), cur_live.shift_reg, + cur_live.shift_reg_data(), cur_live.bit_counter); - if(!dden && cur_live.shift_reg == 0x4489) { + if(!dden && cur_live.shift_reg_low<16>() == 0x4489) { cur_live.crc = 0x443b; reset_data_sync(); cur_live.state = READ_HEADER_BLOCK_HEADER; } - if(dden && cur_live.shift_reg == 0xf57e) { + if(dden && cur_live.shift_reg_low<23>() == 0x2af57e) { cur_live.crc = 0xef21; reset_data_sync(); if(main_state == READ_ID) @@ -1836,15 +1838,8 @@ void wd_fdc_device_base::live_run(attotime limit) if(read_one_bit(limit)) return; - LOGSHIFT("%s: shift = %04x data=%02x counter=%d\n", cur_live.tm.to_string(), cur_live.shift_reg, - (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) | - (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) | - (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) | - (cur_live.shift_reg & 0x0100 ? 0x10 : 0x00) | - (cur_live.shift_reg & 0x0040 ? 0x08 : 0x00) | - (cur_live.shift_reg & 0x0010 ? 0x04 : 0x00) | - (cur_live.shift_reg & 0x0004 ? 0x02 : 0x00) | - (cur_live.shift_reg & 0x0001 ? 0x01 : 0x00), + LOGSHIFT("%s: shift = %08x data=%02x counter=%d\n", cur_live.tm.to_string(), cur_live.shift_reg, + cur_live.shift_reg_data(), cur_live.bit_counter); if(cur_live.bit_counter & 15) @@ -1853,7 +1848,7 @@ void wd_fdc_device_base::live_run(attotime limit) int slot = cur_live.bit_counter >> 4; if(slot < 3) { - if(cur_live.shift_reg != 0x4489) + if(cur_live.shift_reg_low<16>() != 0x4489) cur_live.state = SEARCH_ADDRESS_MARK_HEADER; break; } @@ -1924,15 +1919,8 @@ void wd_fdc_device_base::live_run(attotime limit) if(read_one_bit(limit)) return; - LOGSHIFT("%s: shift = %04x data=%02x c=%d.%x\n", cur_live.tm.to_string(), cur_live.shift_reg, - (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) | - (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) | - (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) | - (cur_live.shift_reg & 0x0100 ? 0x10 : 0x00) | - (cur_live.shift_reg & 0x0040 ? 0x08 : 0x00) | - (cur_live.shift_reg & 0x0010 ? 0x04 : 0x00) | - (cur_live.shift_reg & 0x0004 ? 0x02 : 0x00) | - (cur_live.shift_reg & 0x0001 ? 0x01 : 0x00), + LOGSHIFT("%s: shift = %08x data=%02x c=%d.%x\n", cur_live.tm.to_string(), cur_live.shift_reg, + cur_live.shift_reg_data(), cur_live.bit_counter >> 4, cur_live.bit_counter & 15); if(!dden) { @@ -1941,7 +1929,7 @@ void wd_fdc_device_base::live_run(attotime limit) return; } - if(cur_live.bit_counter >= 28*16 && cur_live.shift_reg == 0x4489) { + if(cur_live.bit_counter >= 28*16 && cur_live.shift_reg_low<16>() == 0x4489) { cur_live.crc = 0x443b; reset_data_sync(); cur_live.state = READ_DATA_BLOCK_HEADER; @@ -1952,12 +1940,12 @@ void wd_fdc_device_base::live_run(attotime limit) return; } - if(cur_live.bit_counter >= 11*16 && (cur_live.shift_reg == 0xf56a || cur_live.shift_reg == 0xf56b || - cur_live.shift_reg == 0xf56e || cur_live.shift_reg == 0xf56f)) { + if(cur_live.bit_counter >= 11*16 && (cur_live.shift_reg_low<16>() == 0xf56a || cur_live.shift_reg_low<16>() == 0xf56b || + cur_live.shift_reg_low<16>() == 0xf56e || cur_live.shift_reg_low<16>() == 0xf56f)) { cur_live.crc = - cur_live.shift_reg == 0xf56a ? 0x8fe7 : - cur_live.shift_reg == 0xf56b ? 0x9fc6 : - cur_live.shift_reg == 0xf56e ? 0xafa5 : + cur_live.shift_reg_low<16>() == 0xf56a ? 0x8fe7 : + cur_live.shift_reg_low<16>() == 0xf56b ? 0x9fc6 : + cur_live.shift_reg_low<16>() == 0xf56e ? 0xafa5 : 0xbf84; reset_data_sync(); @@ -1980,15 +1968,8 @@ void wd_fdc_device_base::live_run(attotime limit) if(read_one_bit(limit)) return; - LOGSHIFT("%s: shift = %04x data=%02x counter=%d\n", cur_live.tm.to_string(), cur_live.shift_reg, - (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) | - (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) | - (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) | - (cur_live.shift_reg & 0x0100 ? 0x10 : 0x00) | - (cur_live.shift_reg & 0x0040 ? 0x08 : 0x00) | - (cur_live.shift_reg & 0x0010 ? 0x04 : 0x00) | - (cur_live.shift_reg & 0x0004 ? 0x02 : 0x00) | - (cur_live.shift_reg & 0x0001 ? 0x01 : 0x00), + LOGSHIFT("%s: shift = %08x data=%02x counter=%d\n", cur_live.tm.to_string(), cur_live.shift_reg, + cur_live.shift_reg_data(), cur_live.bit_counter); if(cur_live.bit_counter & 15) @@ -1997,7 +1978,7 @@ void wd_fdc_device_base::live_run(attotime limit) int slot = cur_live.bit_counter >> 4; if(slot < 3) { - if(cur_live.shift_reg != 0x4489) { + if(cur_live.shift_reg_low<16>() != 0x4489) { live_delay(SEARCH_ADDRESS_MARK_DATA_FAILED); return; } @@ -2061,17 +2042,26 @@ void wd_fdc_device_base::live_run(attotime limit) if(read_one_bit(limit)) return; + if(dden) { + //FM Prefix match + if(cur_live.shift_reg_low<17>() == 0xabd5) { // 17-bit match + cur_live.data_separator_phase = false; + cur_live.bit_counter = 5*2; // prefix is 5 of 8 bits + cur_live.data_reg = 0xff; + break; + } else if(cur_live.bit_counter == 16) { + cur_live.data_separator_phase = false; + cur_live.bit_counter = 0; + live_delay(READ_TRACK_DATA_BYTE); + return; + } + break; + } + // !dden if(cur_live.bit_counter != 16 // MFM resyncs - && !(!dden && (cur_live.shift_reg == 0x4489 - || cur_live.shift_reg == 0x5224)) - // FM resyncs - && !(dden && (cur_live.shift_reg == 0xf57e // FM IDAM - || cur_live.shift_reg == 0xf56f // FM DAM - || cur_live.shift_reg == 0xf56a // FM DDAM - || cur_live.shift_reg == 0xf56b // FM DDAM - || cur_live.shift_reg == 0xf56e // FM DDAM - || cur_live.shift_reg == 0xf56f)) // FM DDAM + && !((cur_live.shift_reg_low<16>() == 0x4489 + || cur_live.shift_reg_low<16>() == 0x5224)) ) break; @@ -2387,9 +2377,6 @@ void wd_fdc_device_base::set_drq() { if(drq) { status |= S_LOST; - drq = false; - if(!drq_cb.isnull()) - drq_cb(false); } else if(!(status & S_LOST)) { drq = true; if(!drq_cb.isnull()) diff --git a/src/devices/machine/wd_fdc.h b/src/devices/machine/wd_fdc.h index 32310e6b638..96259138efc 100644 --- a/src/devices/machine/wd_fdc.h +++ b/src/devices/machine/wd_fdc.h @@ -254,12 +254,14 @@ private: attotime tm; int state, next_state; - uint16_t shift_reg; + uint32_t shift_reg; uint16_t crc; int bit_counter, byte_counter, previous_type; bool data_separator_phase, data_bit_context; uint8_t data_reg; uint8_t idbuf[6]; + template uint32_t shift_reg_low() const; + uint8_t shift_reg_data() const; }; enum {