diff --git a/src/disk/hdc_esdi_at.c b/src/disk/hdc_esdi_at.c index 65184094a..042a6020a 100644 --- a/src/disk/hdc_esdi_at.c +++ b/src/disk/hdc_esdi_at.c @@ -129,23 +129,24 @@ esdi_at_log(const char *fmt, ...) static __inline void irq_raise(esdi_t *esdi) { - if (!(esdi->fdisk & 2)) - picint(1 << 14); - esdi->irqstat = 1; + if (!(esdi->fdisk & 2)) + picint_common(1 << 14, PIC_IRQ_EDGE, 1, NULL); } static __inline void -irq_lower(UNUSED(esdi_t *esdi)) +irq_lower(esdi_t *esdi) { - picintc(1 << 14); + esdi->irqstat = 0; + if (!(esdi->fdisk & 2)) + picint_common(1 << 14, PIC_IRQ_EDGE, 0, NULL); } static __inline void -irq_update(UNUSED(esdi_t *esdi)) +irq_update(esdi_t *esdi) { - if (esdi->irqstat && !((pic2.irr | pic2.isr) & 0x40) && !(esdi->fdisk & 2)) - picint(1 << 14); + uint8_t set = !(esdi->fdisk & 2) && esdi->irqstat; + picint_common(1 << 14, PIC_IRQ_EDGE, set, NULL); } static void @@ -263,6 +264,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv) double seek_time; double xfer_time; off64_t addr; + uint8_t old; esdi_at_log("WD1007 write(%04x, %02x)\n", port, val); @@ -411,15 +413,15 @@ esdi_write(uint16_t port, uint8_t val, void *priv) esdi_set_callback(esdi, 500 * HDC_TIME); esdi->reset = 1; esdi->status = STAT_BUSY; - } - - if (val & 0x04) { + } else if (!(esdi->fdisk & 0x04) && (val & 0x04)) { /* Drive held in reset. */ esdi_set_callback(esdi, 0); esdi->status = STAT_BUSY; } + old = esdi->fdisk; esdi->fdisk = val; - irq_update(esdi); + if (!(val & 0x02) && (old & 0x02)) + irq_update(esdi); break; default: diff --git a/src/disk/hdc_st506_at.c b/src/disk/hdc_st506_at.c index 41499591d..c8c35d7d5 100644 --- a/src/disk/hdc_st506_at.c +++ b/src/disk/hdc_st506_at.c @@ -134,26 +134,27 @@ st506_at_log(const char *fmt, ...) # define st506_at_log(fmt, ...) #endif -static inline void +static __inline void irq_raise(mfm_t *mfm) { - if (!(mfm->fdisk & 2)) - picint(1 << 14); - mfm->irqstat = 1; + if (!(mfm->fdisk & 2)) + picint_common(1 << 14, PIC_IRQ_EDGE, 1, NULL); } -static inline void -irq_lower(UNUSED(mfm_t *mfm)) +static __inline void +irq_lower(mfm_t *mfm) { - picintc(1 << 14); + mfm->irqstat = 0; + if (!(mfm->fdisk & 2)) + picint_common(1 << 14, PIC_IRQ_EDGE, 0, NULL); } -static void +static __inline void irq_update(mfm_t *mfm) { - if (mfm->irqstat && !((pic2.irr | pic2.isr) & 0x40) && !(mfm->fdisk & 2)) - picint(1 << 14); + uint8_t set = !(mfm->fdisk & 2) && mfm->irqstat; + picint_common(1 << 14, PIC_IRQ_EDGE, set, NULL); } /* @@ -378,6 +379,7 @@ static void mfm_write(uint16_t port, uint8_t val, void *priv) { mfm_t *mfm = (mfm_t *) priv; + uint8_t old; st506_at_log("WD1003 write(%04x, %02x)\n", port, val); @@ -408,7 +410,7 @@ mfm_write(uint16_t port, uint8_t val, void *priv) case 0x01f6: /* drive/head */ mfm->head = val & 0xF; - mfm->drvsel = (val & 0x10) ? 1 : 0; + mfm->drvsel = !!(val & 0x10); if (mfm->drives[mfm->drvsel].present) mfm->status = STAT_READY | STAT_DSC; else @@ -425,15 +427,15 @@ mfm_write(uint16_t port, uint8_t val, void *priv) timer_set_delay_u64(&mfm->callback_timer, 500 * MFM_TIME); mfm->reset = 1; mfm->status = STAT_BUSY; - } - - if (val & 0x04) { + } else if (!(mfm->fdisk & 0x04) && (val & 0x04)) { /* Drive held in reset. */ timer_disable(&mfm->callback_timer); mfm->status = STAT_BUSY; } + old = mfm->fdisk; mfm->fdisk = val; - irq_update(mfm); + if (!(val & 0x02) && (old & 0x02)) + irq_update(mfm); break; default: