summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine
diff options
context:
space:
mode:
author 68bit <info@68bit.org>2020-07-19 10:45:29 +1000
committer 68bit <info@68bit.org>2020-07-29 14:13:46 +1000
commitfde727af9151b4abfc2c5f2c3bff97a7dc44753a (patch)
treea73445ddc08f023bf767e048cb12d89aee43acd3 /src/devices/machine
parentf3ce4a494e831ef8b0aab6564f03a92eb2f843c0 (diff)
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.
Diffstat (limited to 'src/devices/machine')
-rw-r--r--src/devices/machine/mc6843.cpp61
-rw-r--r--src/devices/machine/mc6843.h2
2 files changed, 50 insertions, 13 deletions
diff --git a/src/devices/machine/mc6843.cpp b/src/devices/machine/mc6843.cpp
index 597cc7ee865..74945094b40 100644
--- a/src/devices/machine/mc6843.cpp
+++ b/src/devices/machine/mc6843.cpp
@@ -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
{
diff --git a/src/devices/machine/mc6843.h b/src/devices/machine/mc6843.h
index 895e80d9458..488b4671026 100644
--- a/src/devices/machine/mc6843.h
+++ b/src/devices/machine/mc6843.h
@@ -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();
};