Rewrote timer code.

The new code is based on timestamps, rather than delays. This eliminates the
need to update every timer in timer_process(), which cost a non-trivial amount
of CPU time on low-end machines.

This involved changes to every user of the timer code, so this change almost
certainly introduces bugs.
This commit is contained in:
SarahW 2018-08-02 22:06:10 +01:00
commit a7d006b637
79 changed files with 1050 additions and 1033 deletions

View file

@ -70,7 +70,7 @@ typedef struct mfm_t
uint16_t buffer[256];
int irqstat;
int callback;
pc_timer_t callback_timer;
mfm_drive_t drives[2];
} mfm_t;
@ -215,18 +215,14 @@ void mfm_write(uint16_t port, uint8_t val, void *p)
// pclog("Restore\n");
mfm->command &= ~0x0f; /*Mask off step rate*/
mfm->status = STAT_BUSY;
timer_clock();
mfm->callback = 200*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&mfm->callback_timer, 200*IDE_TIME);
break;
case CMD_SEEK:
// pclog("Seek to cylinder %i\n", mfm->cylinder);
mfm->command &= ~0x0f; /*Mask off step rate*/
mfm->status = STAT_BUSY;
timer_clock();
mfm->callback = 200*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&mfm->callback_timer, 200*IDE_TIME);
break;
default:
@ -239,9 +235,7 @@ void mfm_write(uint16_t port, uint8_t val, void *p)
if (val & 2)
fatal("Read with ECC\n");
mfm->status = STAT_BUSY;
timer_clock();
mfm->callback = 200*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&mfm->callback_timer, 200*IDE_TIME);
break;
case CMD_WRITE: case CMD_WRITE+1:
@ -258,9 +252,7 @@ void mfm_write(uint16_t port, uint8_t val, void *p)
// pclog("Read verify %i sectors from sector %i cylinder %i head %i\n",mfm->secount,mfm->sector,mfm->cylinder,mfm->head);
mfm->command &= ~1;
mfm->status = STAT_BUSY;
timer_clock();
mfm->callback = 200 * IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&mfm->callback_timer, 200 * IDE_TIME);
break;
case CMD_FORMAT:
@ -271,24 +263,18 @@ void mfm_write(uint16_t port, uint8_t val, void *p)
case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */
mfm->status = STAT_BUSY;
timer_clock();
mfm->callback = 30*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&mfm->callback_timer, 30*IDE_TIME);
break;
case CMD_DIAGNOSE: /* Execute Drive Diagnostics */
mfm->status = STAT_BUSY;
timer_clock();
mfm->callback = 200*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&mfm->callback_timer, 200*IDE_TIME);
break;
default:
pclog("Bad MFM command %02X\n", val);
mfm->status = STAT_BUSY;
timer_clock();
mfm->callback = 200*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&mfm->callback_timer, 200*IDE_TIME);
break;
}
}
@ -297,9 +283,7 @@ void mfm_write(uint16_t port, uint8_t val, void *p)
case 0x3F6: /* Device control */
if ((mfm->fdisk & 4) && !(val & 4))
{
timer_clock();
mfm->callback = 500*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&mfm->callback_timer, 500*IDE_TIME);
mfm->reset = 1;
mfm->status = STAT_BUSY;
// pclog("MFM Reset\n");
@ -307,9 +291,7 @@ void mfm_write(uint16_t port, uint8_t val, void *p)
if (val & 4)
{
/*Drive held in reset*/
timer_clock();
mfm->callback = 0;
timer_update_outstanding();
timer_disable(&mfm->callback_timer);
mfm->status = STAT_BUSY;
}
mfm->fdisk = val;
@ -331,9 +313,7 @@ void mfm_writew(uint16_t port, uint16_t val, void *p)
{
mfm->pos = 0;
mfm->status = STAT_BUSY;
timer_clock();
mfm->callback = 6*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&mfm->callback_timer, 6*IDE_TIME);
}
}
@ -402,9 +382,7 @@ uint16_t mfm_readw(uint16_t port, void *p)
{
mfm_next_sector(mfm);
mfm->status = STAT_BUSY;
timer_clock();
mfm->callback = 6*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&mfm->callback_timer, 6*IDE_TIME);
}
}
}
@ -430,7 +408,7 @@ void mfm_callback(void *p)
off64_t addr;
// pclog("mfm_callback: command=%02x reset=%i\n", mfm->command, mfm->reset);
mfm->callback = 0;
if (mfm->reset)
{
mfm->status = STAT_READY | STAT_DSC;
@ -562,7 +540,7 @@ void *mfm_init()
io_sethandler(0x01f1, 0x0007, mfm_read, NULL, NULL, mfm_write, NULL, NULL, mfm);
io_sethandler(0x03f6, 0x0001, NULL, NULL, NULL, mfm_write, NULL, NULL, mfm);
timer_add(mfm_callback, &mfm->callback, &mfm->callback, mfm);
timer_add(&mfm->callback_timer, mfm_callback, mfm, 0);
return mfm;
}