mc6843: add a delay reading the CRC

Code using programmed I/O may read the last byte of a sector and then
expect to have some time to store that to memory before receiving an
interrupt on the completion of the command. The interrupt was
occurring on the last read and the last byte was being lost by some
drivers. This change adds a delay after reading the last byte, roughly
the time needed to read the 16 bit CRC, before the end of a read
command is processed.

Avoid side effects when these are disabled.
This commit is contained in:
68bit 2020-07-19 10:45:29 +10:00
parent f3ce4a494e
commit fde727af91
2 changed files with 50 additions and 13 deletions

View File

@ -56,6 +56,7 @@
/* coarse delays */
#define DELAY_SEEK attotime::from_usec( 100 ) /* track seek time */
#define DELAY_ADDR attotime::from_usec( 100 ) /* search-address time */
#define DELAY_CRC attotime::from_usec( 64 ) /* read crc time */
@ -68,7 +69,7 @@ static const char *const mc6843_cmd[16] =
DEFINE_DEVICE_TYPE(MC6843, mc6843_device, "mc5843", "Motorola MC6843 FDC")
DEFINE_DEVICE_TYPE(MC6843, mc6843_device, "mc6843", "Motorola MC6843 FDC")
mc6843_device::mc6843_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, MC6843, tag, owner, clock),
@ -90,6 +91,7 @@ mc6843_device::mc6843_device(const machine_config &mconfig, const char *tag, dev
m_data_idx(0),
m_data_id(0),
m_index_pulse(0),
m_crc_wait(0),
m_timer_cont(nullptr)
{
for (auto & elem : m_data)
@ -124,6 +126,7 @@ void mc6843_device::device_start()
save_item(NAME(m_data_size));
save_item(NAME(m_data_idx));
save_item(NAME(m_data_id));
save_item(NAME(m_crc_wait));
}
//-------------------------------------------------
@ -155,6 +158,7 @@ void mc6843_device::device_reset()
m_data_size = 0;
m_data_idx = 0;
m_crc_wait = 0;
m_timer_cont->adjust( attotime::never );
}
@ -219,6 +223,7 @@ void mc6843_device::set_index_pulse( int index_pulse )
void mc6843_device::cmd_end( )
{
int cmd = m_CMR & 0x0f;
if ( ( cmd == CMD_STZ ) || ( cmd == CMD_SEK ) )
{
m_ISR |= 0x02; /* set Settling Time Complete */
@ -392,7 +397,11 @@ void mc6843_device::cont_SR( )
status_update( );
}
void mc6843_device::finish_SR( )
{
m_crc_wait = 0;
cmd_end( );
}
/* Single / Multiple Sector Write bottom half */
void mc6843_device::cont_SW( )
@ -430,12 +439,17 @@ void mc6843_device::device_timer(emu_timer &timer, device_timer_id id, int param
{
case CMD_STZ: finish_STZ( ); break;
case CMD_SEK: finish_SEK( ); break;
case CMD_SSR: cont_SR( ); break;
case CMD_SSR:
case CMD_MSR:
if ( m_crc_wait )
finish_SR( );
else
cont_SR( );
break;
case CMD_SSW: cont_SW( ); break;
case CMD_RCR: finish_RCR( ); break;
case CMD_SWD: cont_SW( ); break;
case CMD_MSW: cont_SW( ); break;
case CMD_MSR: cont_SR( ); break;
}
}
break;
@ -460,6 +474,12 @@ uint8_t mc6843_device::read(offs_t offset)
{
int cmd = m_CMR & 0x0f;
if (machine().side_effects_disabled())
{
data = m_data[0];
break;
}
LOG( "%f %s mc6843_r: data input cmd=%s(%i), pos=%i/%i, GCR=%i, ",
machine().time().as_double(), machine().describe_context(),
mc6843_cmd[cmd], cmd, m_data_idx,
@ -487,13 +507,15 @@ uint8_t mc6843_device::read(offs_t offset)
m_SAR++;
if ( m_GCR == 0xff )
{
cmd_end( );
m_crc_wait = 1;
m_timer_cont->adjust( DELAY_CRC );
}
else if ( m_SAR > 26 )
{
m_STRB |= 0x08; /* set Sector Address Undetected */
cmd_end( );
m_crc_wait = 1;
m_timer_cont->adjust( DELAY_CRC );
}
else
{
@ -502,7 +524,8 @@ uint8_t mc6843_device::read(offs_t offset)
}
else
{
cmd_end( );
m_crc_wait = 1;
m_timer_cont->adjust( DELAY_CRC );
}
}
}
@ -524,6 +547,8 @@ uint8_t mc6843_device::read(offs_t offset)
case 1: /* Current-Track Address Register (CTAR) */
data = m_CTAR;
if (machine().side_effects_disabled())
break;
LOG( "%f %s mc6843_r: read CTAR %i (actual=%i)\n",
machine().time().as_double(), machine().describe_context(), data,
floppy_image()->floppy_drive_get_current_track());
@ -531,6 +556,8 @@ uint8_t mc6843_device::read(offs_t offset)
case 2: /* Interrupt Status Register (ISR) */
data = m_ISR;
if (machine().side_effects_disabled())
break;
LOG( "%f %s mc6843_r: read ISR %02X: cmd=%scomplete settle=%scomplete sense-rq=%i STRB=%i\n",
machine().time().as_double(), machine().describe_context(), data,
(data & 1) ? "" : "not-" , (data & 2) ? "" : "not-",
@ -546,17 +573,20 @@ uint8_t mc6843_device::read(offs_t offset)
/* update */
legacy_floppy_image_device* img = floppy_image( );
int flag = img->floppy_drive_get_flag_state( FLOPPY_DRIVE_READY);
m_STRA &= 0xa3;
data = m_STRA & 0xa3;
if ( flag & FLOPPY_DRIVE_READY )
m_STRA |= 0x04;
data |= 0x04;
m_STRA |= !img->floppy_tk00_r() << 3;
m_STRA |= !img->floppy_wpt_r() << 4;
data |= !img->floppy_tk00_r() << 3;
data |= !img->floppy_wpt_r() << 4;
if ( m_index_pulse )
m_STRA |= 0x40;
data |= 0x40;
data = m_STRA;
if (machine().side_effects_disabled())
break;
m_STRA = data;
LOG( "%f %s mc6843_r: read STRA %02X: data-rq=%i del-dta=%i ready=%i t0=%i wp=%i trk-dif=%i idx=%i busy=%i\n",
machine().time().as_double(), machine().describe_context(), data,
data & 1, (data >> 1) & 1, (data >> 2) & 1, (data >> 3) & 1,
@ -566,6 +596,8 @@ uint8_t mc6843_device::read(offs_t offset)
case 4: /* Status Register B (STRB) */
data = m_STRB;
if (machine().side_effects_disabled())
break;
LOG( "%f %s mc6843_r: read STRB %02X: data-err=%i CRC-err=%i dta--mrk-err=%i sect-mrk-err=%i seek-err=%i fi=%i wr-err=%i hard-err=%i\n",
machine().time().as_double(), machine().describe_context(), data,
data & 1, (data >> 1) & 1, (data >> 2) & 1, (data >> 3) & 1,
@ -578,6 +610,8 @@ uint8_t mc6843_device::read(offs_t offset)
case 7: /* Logical-Track Address Register (LTAR) */
data = m_LTAR;
if (machine().side_effects_disabled())
break;
LOG( "%f %s mc6843_r: read LTAR %i (actual=%i)\n",
machine().time().as_double(), machine().describe_context(), data,
floppy_image()->floppy_drive_get_current_track());
@ -682,6 +716,7 @@ void mc6843_device::write(offs_t offset, uint8_t data)
uint8_t filler = 0xe5; /* standard Thomson filler */
LOG( "%f %s mc6843_w: address id detected track=%i sector=%i\n", machine().time().as_double(), machine().describe_context(), track, sector);
img->floppy_drive_format_sector( m_side, sector, track, 0, sector, 0, filler );
m_data_idx = 0;
}
else
{

View File

@ -75,6 +75,7 @@ private:
uint32_t m_data_idx; /* current read/write position in data */
uint32_t m_data_id; /* chrd_id for sector write */
uint8_t m_index_pulse;
uint8_t m_crc_wait;
/* trigger delayed actions (bottom halves) */
emu_timer* m_timer_cont;
@ -88,6 +89,7 @@ private:
int address_search_read(chrn_id* id);
void finish_RCR();
void cont_SR();
void finish_SR();
void cont_SW();
};