On Sat, 2018-02-03 at 00:09 +0200, Nikolay Nikolov wrote:
On Tue, 2018-01-30 at 22:23 -0500, Kevin O'Connor wrote:
@@ -199,8 +205,9 @@ floppy_wait_irq(void) { u8 frs = GET_BDA(floppy_recalibration_status); SET_BDA(floppy_recalibration_status, frs & ~FRS_IRQ);
- u32 end = timer_calc(FLOPPY_IRQ_TIMEOUT); for (;;) {
if (!GET_BDA(floppy_motor_counter)) {
if (timer_check(end)) {
The floppy_motor_counter is an external variable that some legacy programs may inspect. I'm not sure we can not update it here. What's the reason for changing the timeout to use timer_calc()?
Previously, it didn't behave well on real hardware. It set the timer to the FLOPPY_MOTOR_TICKS value in the beginning of the disk operation, which turned off the motor way too early, before the operation can complete. The value in FLOPPY_MOTOR_TICKS must be set _after_ the operation, so it keeps the motor spinning for 2 seconds _after_ the operation, so in case, there's a new disk operation that follows soon, it keeps the motor spinning and avoids having to wait the spin-up time (FLOPPY_STARTUP_TIME) again.
However, since you mentioned it, I decided to do some actual tests on computers with different BIOSes and inspect the value. I wrote a TSR, which hooks the IRQ 0 timer interrupt and displays it in hex in the upper left part of the screen. Then I watched what happens during and after accessing the floppy and the results are not exactly what my patch does. But, unfortunately the behaviour was different on the two computers that I tested:
- IBM PS/2 Model 76:
The value gets decremented all the time, even when there isn't any floppy operation. So, when it reaches 0, the motors are turned off, but the value wraps back to 0xFF and continues counting down back to 0, where the motors are again turned off (even if they were already off), ad infinitum.
In the beginning of an actual floppy operation, it is set to 0xFF, so it doesn't turn off the motor any time soon. It still counts down, however the BIOS doesn't seem to use it as a timeout.
After the operation, the value is changed to the FLOPPY_MOTOR_TICKS constant, so it turns the motor off 2 seconds after the operation.
- AWARD BIOS, Gigabyte GA-K8NF-9 rev 1.0 (the motherboard I'm
porting Coreboot+SeaBIOS to)
Same as the IBM PS/2 Model 76, except, when the value reaches 0, it stays at 0.
The only difference with my patch is, my patch keeps the value at 0xFF, during the operation, while the AWARD BIOS keeps counting down, even though it still doesn't use it as timeout.
Honestly, I don't know which behaviour is more correct. I kinda like AWARD's behaviour better, because it doesn't periodically poke into the floppy controller's DOR register, when there's no floppy operation.
On the other hand, IBM could be more "IBM compatible" :)
I can also test Phoenix and AMI BIOS under AMD SimNow (not on real hardware), since I don't have any computer with a floppy and any of these BIOSes.
I also have other vintage IBMs with floppies, but I suspect they're going to behave the same way as model 76.
Ok, tested "Phoenix ServerBIOS" and "AMI BIOS" and they behave like AWARD. Also tested IBM 5150 (the first IBM PC), it behaves like the IBM PS/2 Model 76. I guess, that's how early IBMs used to behave back then. I guess, nowadays we'd better follow AWARD, Phoenix and AMI BIOS?
Nikolay