diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 28f5ef7ae..6a408bf50 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -9,7 +9,7 @@ * Implementation of the IDE emulation for hard disks and ATAPI * CD-ROM devices. * - * Version: @(#)hdc_ide.c 1.0.63 2019/11/01 + * Version: @(#)hdc_ide.c 1.0.64 2019/11/06 * * Authors: Sarah Walker, * Miran Grca, @@ -1156,18 +1156,9 @@ static void dev_reset(ide_t *ide) { ide_set_signature(ide); - ide->error = 1; /*No error detected*/ - if (ide->type == IDE_ATAPI) { - ide->sc->status = 0; - ide->sc->error = 1; - ide_irq_raise(ide); - if (ide->stop) - ide->stop(ide->sc); - } else { - ide->atastat = DRDY_STAT | DSC_STAT; - ide->error = 1; - } + if ((ide->type == IDE_ATAPI) && ide->stop) + ide->stop(ide->sc); } @@ -1189,30 +1180,47 @@ ide_write_devctl(uint16_t addr, uint8_t val, void *priv) return; dev->diag = 0; - + if ((val & 4) && !(ide->fdisk & 4)) { /* Reset toggled from 0 to 1, initiate reset procedure. */ if (ide->type == IDE_ATAPI) ide->sc->callback = 0.0; ide_set_callback(ide->board, 0.0); - ide->atastat = BSY_STAT; - if (ide->type == IDE_ATAPI) - ide->sc->status = BSY_STAT; - dev_reset(ide); } else if (!(val & 4) && (ide->fdisk & 4)) { /* Reset toggled from 1 to 0. */ if (!(ch & 1)) { - /* Currently active device is 0, fire the timer. */ - if (ide->type == IDE_ATAPI) - ide->sc->callback = 0.4; - ide_set_callback(ide->board, 0.4); + /* Currently active device is 0, use the device 0 reset protocol. */ + /* Device 0. */ + dev_reset(ide); + ide->atastat = BSY_STAT; + ide->error = 1; + if (ide->type == IDE_ATAPI) { + ide->sc->status = BSY_STAT; + ide->sc->error = 1; + } + + /* Device 1. */ + dev_reset(ide_other); + ide_other->atastat = BSY_STAT; + ide_other->error = 1; + if (ide_other->type == IDE_ATAPI) { + ide_other->sc->status = BSY_STAT; + ide_other->sc->error = 1; + } + + /* Fire the timer. */ + dev->diag = 0; ide->reset = 1; + ide_set_callback(ide->board, 500 * IDE_TIME); } else { /* Currently active device is 1, simply reset the status and the active device. */ - ide->atastat = 0x50; - if (ide->type == IDE_ATAPI) - ide->sc->status = DRDY_STAT | DSC_STAT; + dev_reset(ide); ide->atastat = DRDY_STAT | DSC_STAT; + ide->error = 1; + if (ide->type == IDE_ATAPI) { + ide->sc->status = DRDY_STAT | DSC_STAT; + ide->sc->error = 1; + } dev->cur_dev &= ~1; } } @@ -1494,18 +1502,32 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) return; case WIN_DRIVE_DIAGNOSTICS: /* Execute Drive Diagnostics */ - ide->atastat = BSY_STAT; - dev_reset(ide); - if (!(ch & 1)) - dev_reset(ide_other); - dev->diag = 1; + dev->cur_dev &= ~1; + ide = ide_drives[ch & ~1]; + ide_other = ide_drives[ch | 1]; + /* Device 0. */ + dev_reset(ide); + ide->atastat = BSY_STAT; + ide->error = 1; if (ide->type == IDE_ATAPI) { ide->sc->status = BSY_STAT; - ide->sc->callback = 0.4; + ide->sc->error = 1; } - ide_set_callback(ide->board, 0.4); + + /* Device 1. */ + dev_reset(ide_other); + ide_other->atastat = BSY_STAT; + ide_other->error = 1; + if (ide_other->type == IDE_ATAPI) { + ide_other->sc->status = BSY_STAT; + ide_other->sc->error = 1; + } + + /* Fire the timer. */ + dev->diag = 1; ide->reset = 1; + ide_set_callback(ide->board, 200 * IDE_TIME); return; case WIN_PIDENTIFY: /* Identify Packet Device */ @@ -1825,12 +1847,6 @@ ide_callback(void *priv) if (ide->reset) { ide_log("CALLBACK RESET %i %i\n", ide->reset,ch); - ide = ide_drives[ch & ~1]; - ide_other = ide_drives[ch | 1]; - - if (!dev->diag) - dev_reset(ide_other); - ide->atastat = DRDY_STAT | DSC_STAT; if (ide->type == IDE_ATAPI) ide->sc->status = DRDY_STAT | DSC_STAT; @@ -1845,13 +1861,8 @@ ide_callback(void *priv) dev->diag = 0; ide_irq_raise(ide); } - - if (ide->type == IDE_ATAPI) - ide->sc->callback = 0.0; - if (ide_other->type == IDE_ATAPI) - ide_other->sc->callback = 0.0; - ide_set_callback(ide->board, 0.0); ide->reset = 0; + ide_set_callback(ide->board, 0.0); return; }