mirror of
https://github.com/holub/mame
synced 2025-04-22 08:22:15 +03:00
machine/wd_fdc.cpp: Don’t clear DRQ on LDB/INTR, and fix spurious READ TRACk/ADDR FM mark syncs. (#11041) [Peter Phillips, Tim Lindner]
Fixes SuperUtility 3 (MT08511) and Marble Maze on TRS-80 Color Computer.
This commit is contained in:
parent
ce4015da60
commit
6ea69b0ed9
@ -136,6 +136,16 @@ static const char *const states[] =
|
||||
"WRITE_SECTOR_PRE_BYTE"
|
||||
};
|
||||
|
||||
template <unsigned B> inline uint32_t wd_fdc_device_base::live_info::shift_reg_low() const
|
||||
{
|
||||
return shift_reg & make_bitmask<uint32_t>(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())
|
||||
|
@ -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 <unsigned B> uint32_t shift_reg_low() const;
|
||||
uint8_t shift_reg_data() const;
|
||||
};
|
||||
|
||||
enum {
|
||||
|
Loading…
Reference in New Issue
Block a user