[SeaBIOS] [PATCH] Fixes to the floppy driver, so it works on real (not emulated) hardware

Nikolay Nikolov nickysn at gmail.com
Sat Feb 3 02:41:16 CET 2018


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:
> 
> 1) 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.
> 
> 2) 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



More information about the SeaBIOS mailing list