Fixed PCJr seeking not to break the FDC implementation. Now seeking will take the "correct" amount of time for each system and the seek time is based on the track count. E.g. 40 track FDD system causes 40 track seek time to be 80/40 * 6ms * 40 tracks + 50ms = 480ms + 50ms -> 530ms.

80 track system full seek is 80/80 * 6ms * 80 + 50ms = 530ms, 40 track seek would take 240 + 50 = 290ms.
This commit is contained in:
Toni Riikonen
2025-09-16 14:53:39 +03:00
parent c2e06b58a5
commit 8032541ab9
2 changed files with 12 additions and 17 deletions

View File

@@ -675,16 +675,21 @@ fdc_seek_complete_interrupt(fdc_t *fdc, int drive)
return;
}
if (FDC_FLAG_PCJR & fdc->flags) {
fdc->fintr = 1;
fdc->interrupt = -4;
fdc_callback(fdc);
return;
}
fdc_log("FDD %c: Seek complete interrupt\n", 0x41 + drive);
fdc->fintr = 1;
fdc->st0 = 0x20 | (drive & 3);
if (fdd_get_head(drive))
fdc->st0 |= 0x04;
fdc_int(fdc, 1);
fdc->stat = (fdc->stat & 0xf) | 0x80;
}
@@ -1927,17 +1932,7 @@ fdc_callback(void *priv)
case 0x0f: /*Seek*/
fdc->st0 = 0x20 | (fdc->params[0] & 3);
fdc->stat = 0x80 | (1 << fdc->rw_drive);
if (fdc->flags & FDC_FLAG_PCJR) {
fdc->fintr = 1;
fdc->interrupt = -4;
timer_set_delay_u64(&fdc->timer, 1024 * TIMER_USEC);
} else {
fdc->interrupt = -3;
// 10 seconds before timeout -> error, Usually BIOS gets angry before this happens
// FDD does the seeking and calls callback when done
timer_set_delay_u64(&fdc->timer, 1024 * 1024 * 10 * TIMER_USEC);
// fdc_callback(fdc); // Immediate callback causes seek to be instant
}
// Interrupts and callbacks in the fdd callback function
return;
case 0x10: /*Version*/
case 0x18: /*NSC*/

View File

@@ -278,7 +278,7 @@ fdd_seek_complete_callback(void *priv)
fdd_log("fdd_seek_complete_callback(drive=%d) - TIMER FIRED! seek_in_progress=1\n", drive->id);
fdd_log("Notifying FDC of seek completion\n");
fdd_do_seek(drive->id, fdd[drive->id].track);
fdc_seek_complete_interrupt(fdd_fdc, drive->id);
}
@@ -313,13 +313,13 @@ fdd_seek(int drive, int track_diff)
// Count actual seek time (6ms per track + 50ms base)
// 80 tracks -> 50 + 6 * 80 = 530ms
uint64_t seek_time_us = (50000 + (abs(track_diff) * 6000)) * TIMER_USEC;
double seek_ratio = 80.0 / (double)drive_types[fdd[drive].type].max_track;
uint64_t seek_time_us = (50000 + (abs(actual_track_diff) * 6000 * seek_ratio)) * TIMER_USEC;
if (!fdd_seek_timer[drive].callback) {
timer_add(&(fdd_seek_timer[drive]), fdd_seek_complete_callback, &drives[drive], 0);
}
timer_set_delay_u64(&fdd_seek_timer[drive], seek_time_us);
fdd_do_seek(drive, fdd[drive].track);
timer_set_delay_u64(&fdd_seek_timer[drive], seek_time_us);
}
int