floppy: detect an empty drive via the disk change line

floppy_prep() recalibrates and then calls floppy_media_sense(), which
issues READ ID once per data rate.  A drive with no medium spins no
diskette and therefore produces no index pulses, so a real controller
never completes READ ID and every attempt waits out FLOPPY_IRQ_TIMEOUT.
Booting with an empty drive, or an INT 13h read of an empty A:, costs
about ten seconds.

The disk change line answers the same question immediately.  It latches
when the medium is removed and is cleared only by a step pulse with a
diskette in the drive.  A recalibrate leaves the head on cylinder 0 and
need not step at all, so seek to cylinder 1, read DIR again, and seek back
if a medium turns out to be present, so that media sensing reads the track
it always did.  Linux's floppy driver has done exactly this since 2.0 and
never issues READ ID.

Only the 1.2MB 5.25" drive and the 3.5" drives have the change line
(CMOS types 2..5); on the older 5.25" types the pin is not driven and
reads back as a permanent "changed".  Restrict the probe to those types,
so that the code can only ever fall back to the current behaviour.

The error code is unchanged: floppy_media_sense() already reports
DISK_RET_EMEDIA once it has exhausted the data rates, so an empty drive
still answers DISK_RET_EMEDIA -- just without the wait.

The wait is a real-hardware effect and cannot be reproduced on QEMU as it
stands: QEMU completes READ ID on an empty drive and hands back a made-up
sector ID, so media sensing never blocks.  That is a bug of its own, and a
fix is on qemu-devel [1] -- but it makes READ ID fail immediately rather
than never complete, so it does not bring the wait back either.  To measure
what this patch removes I made QEMU leave the command unfinished the way
hardware does.  That change is local and not proposed upstream: it would
need this series in place first, or every access to an empty drive under
QEMU would cost ten seconds.

INT 13h AH=02h on an empty A:, "-machine pc -device floppy,drive-type=144":

  QEMU made to behave like hardware    10.13 s  ->  0.11 s
  QEMU as it stands today               0.11 s  ->  0.11 s

So on stock QEMU this patch neither costs nor saves time; what it changes
there is the error code, which 3/3 is about.  Booting from a diskette is
unaffected, including the cold start where the change line is set for a
freshly inserted medium.

[1] https://lore.kernel.org/qemu-devel/20260710113134.43012-1-christian@quante.one/

Signed-off-by: Christian Quante <christian@quante.one>
1 file changed
tree: 0575ad1ea397ae975975a52309b13909a08fc6c8
  1. docs/
  2. scripts/
  3. src/
  4. vgasrc/
  5. .gitignore
  6. COPYING
  7. COPYING.LESSER
  8. Makefile
  9. README