:p
atchew
Login
Kevin, thanks for the review. All three points addressed, plus the error code question, which turned out to deserve its own patch as you suggested. 1/3 floppy_drive_seek(), as you asked -- it also removes the reason for the second recalibrate you asked about. The seek in my v1 went straight to floppy_drive_pio() and left floppy_track[] in the BDA stale; the recalibrate was there to repair that, not because the head needed to move. With the BDA kept correct the head can simply stay on cylinder 1, and floppy_prep() seeks where it wants anyway. 2/3 The probe itself, now returning a status code rather than a bool. Behaviour is unchanged from today apart from the wait: an empty drive still answers DISK_RET_EMEDIA, just in 0.11 s instead of 10 s. 3/3 The error code, separate as you preferred. On 3/3 -- you asked whether I am sure a traditional BIOS answers differently. I was not, and said so; here is what I found since. 0xC0 does not appear in the classic INT 13h status tables at all (helppc, the Wikipedia table for AH=01h, techhelp). It has been in SeaBIOS since the initial checkin f076a3ee, without a comment or a source. Bochs BIOS, which SeaBIOS descends from, answers 0x80 here ("SET_AH(0x80); // drive not ready (timeout)") and has no READ ID media sensing at all -- that arrived with your e7c5a7ef in 2013, and DISK_RET_EMEDIA came along with it. Guests agree. Building SeaBIOS to return each code in turn on an empty drive. My guests are German-language, so their messages are quoted as they appear, with the English sense in brackets: PC-DOS 7, "dir a:" 0x80 "Nicht bereit beim Lesen von Laufwerk A" [not ready reading drive A] 0xC0 "Allgemeiner Fehler beim Lesen von Laufwerk A" [general failure reading drive A] 0xAA same message as 0xC0 0x99 same message as 0xC0 <- an invented code 0x06 no message at all; DOS retries forever Windows for Workgroups 3.11, File Manager, drive A: 0x80 "In Laufwerk A ist kein Datenträger eingelegt. Legen Sie einen Datenträger ein, und versuchen Sie es erneut." [Wiederholen] [there is no disk in drive A; insert one and try again] 0xC0 "Der Datenträger in Laufwerk A ist nicht formatiert. Möchten Sie, daß der Datenträger jetzt formatiert wird?" [Ja] [Nein] [the disk in drive A is not formatted; format it now?] DOS gives 0xC0 the same message as the invented 0x99, so it does not recognise the code. Windows does recognise it -- and offers to format a diskette that is not in the drive. The two failures are distinct, and 2/3 is what makes them distinguishable in the first place: an absent medium is now known as such, so it can be reported as "not ready", while floppy_media_sense() keeps DISK_RET_EMEDIA for a medium it cannot read. Tested: empty drive; diskette present; cold start with a freshly inserted medium, where the change line is set and a naive probe would call the drive empty; boot from a diskette; and the guests PC-DOS 7, IBM DOS 5.02, Windows for Workgroups 3.11 and OS/2 2.11. Each commit builds and was measured separately -- 1/3 changes nothing, 2/3 takes an INT 13h read of an empty A: from 10.12 s to 0.11 s, 3/3 changes the code it answers with. Still not verified against real hardware; I have none with a floppy drive. The gating on CMOS types 2..5 and the "when in doubt, say present" fallback are meant to keep that safe, but a second opinion on drives without a change line would be welcome. Christian Quante (3): floppy: add floppy_drive_seek() floppy: detect an empty drive via the disk change line floppy: report an empty drive as not ready src/hw/floppy.c | 75 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 68 insertions(+), 7 deletions(-) -- 2.53.0 _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
Wrap the SEEK command and the BDA bookkeeping that goes with it, the way floppy_drive_recal() already does for RECALIBRATE. No functional change; the next patch gains a second caller. Signed-off-by: Christian Quante <christian@quante.one> --- src/hw/floppy.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/hw/floppy.c b/src/hw/floppy.c index XXXXXXX..XXXXXXX 100644 --- a/src/hw/floppy.c +++ b/src/hw/floppy.c @@ -XXX,XX +XXX,XX @@ floppy_drive_recal(u8 floppyid) return DISK_RET_SUCCESS; } +static int +floppy_drive_seek(u8 floppyid, u8 cylinder) +{ + dprintf(2, "Floppy_drive_seek %d to %d\n", floppyid, cylinder); + u8 param[2]; + param[0] = floppyid; + param[1] = cylinder; + int ret = floppy_drive_pio(floppyid, FC_SEEK, param); + if (ret) + return ret; + + SET_BDA(floppy_track[floppyid], cylinder); + return DISK_RET_SUCCESS; +} + static int floppy_drive_specify(void) { @@ -XXX,XX +XXX,XX @@ floppy_prep(struct drive_s *drive_gf, u8 cylinder) } // Seek to cylinder if needed. - u8 lastcyl = GET_BDA(floppy_track[floppyid]); - if (cylinder != lastcyl) { - u8 param[2]; - param[0] = floppyid; - param[1] = cylinder; - int ret = floppy_drive_pio(floppyid, FC_SEEK, param); + if (cylinder != GET_BDA(floppy_track[floppyid])) { + int ret = floppy_drive_seek(floppyid, cylinder); if (ret) return ret; - SET_BDA(floppy_track[floppyid], cylinder); } return DISK_RET_SUCCESS; -- 2.53.0 _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
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 and read DIR again. 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, and report any uncertainty as success, 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. Measured with qemu-system-x86_64, "-machine pc -device floppy, drive-type=144" and no medium, INT 13h AH=02h on drive A: before 0.11 s, AH = 0x20 (controller failure) after 0.11 s, AH = 0xC0 (no media) QEMU completes READ ID successfully on an empty drive, which hides the timeout; a fix for that is on qemu-devel [1]. With it applied, so that READ ID never completes as on real hardware, the same read takes 10.12 s before this change and 0.11 s after it. 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> --- src/hw/floppy.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/hw/floppy.c b/src/hw/floppy.c index XXXXXXX..XXXXXXX 100644 --- a/src/hw/floppy.c +++ b/src/hw/floppy.c @@ -XXX,XX +XXX,XX @@ #define PORT_FD_DATA 0x03f5 #define PORT_FD_DIR 0x03f7 +// Digital Input Register (read) +#define FLOPPY_DIR_DSKCHG 0x80 + #define FLOPPY_SIZE_CODE 0x02 // 512 byte sectors #define FLOPPY_DATALEN 0xff // Not used - because size code is 0x02 #define FLOPPY_MOTOR_TICKS 37 // ~2 seconds @@ -XXX,XX +XXX,XX @@ floppy_drive_readid(u8 floppyid, u8 data_rate, u8 head) return 0; } +// Only the 1.2MB 5.25" drive and the 3.5" drives have a disk change line. On +// the older 5.25" types the pin is not driven and reads back as a permanent +// "changed". +static int +floppy_has_changeline(u8 ftype) +{ + return ftype >= 2 && ftype <= 5; +} + +// Determine whether a diskette is present, without waiting for a command to +// time out. The disk change line latches when the medium is removed and is +// cleared only by a step pulse with a diskette in the drive. The caller has +// just recalibrated, which leaves the head on cylinder 0 and need not step at +// all, so step to cylinder 1 and look again. The head is left there; the +// caller seeks to the cylinder it wants anyway. +// +// Report DISK_RET_EMEDIA only when the drive is known to be empty -- any +// uncertainty is reported as success, so this can only ever fall back to the +// previous behaviour. +static int +floppy_check_media(struct drive_s *drive_gf, u8 floppyid) +{ + if (!floppy_has_changeline(GET_GLOBALFLAT(drive_gf->floppy_type))) + return DISK_RET_SUCCESS; + + // The caller has just recalibrated this drive, so it is selected in the + // DOR and the DIR reflects its change line. + if (!(inb(PORT_FD_DIR) & FLOPPY_DIR_DSKCHG)) + return DISK_RET_SUCCESS; + + int ret = floppy_drive_seek(floppyid, 1); + if (ret) + return DISK_RET_SUCCESS; + + if (!(inb(PORT_FD_DIR) & FLOPPY_DIR_DSKCHG)) + return DISK_RET_SUCCESS; + + dprintf(2, "Floppy_check_media %d: no medium\n", floppyid); + return DISK_RET_EMEDIA; +} + static int floppy_media_sense(struct drive_s *drive_gf) { @@ -XXX,XX +XXX,XX @@ floppy_prep(struct drive_s *drive_gf, u8 cylinder) if (ret) return ret; + // An empty drive gives no index pulses, so the READ ID that + // floppy_media_sense() issues would never complete and would wait out + // its timeout once per data rate. Ask the disk change line instead. + ret = floppy_check_media(drive_gf, floppyid); + if (ret) + return ret; + // Sense media. ret = floppy_media_sense(drive_gf); if (ret) -- 2.53.0 _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
An empty drive and an unreadable diskette are different failures, and until the previous patch SeaBIOS could not tell them apart: both ended up in floppy_media_sense() exhausting the data rates and returning DISK_RET_EMEDIA (0xC0). Now that the disk change line identifies an absent medium, report it as DISK_RET_ETIMEOUT (0x80), the code the INT 13h documentation gives for "time out, drive not ready". floppy_media_sense() keeps DISK_RET_EMEDIA for a medium it cannot read. 0xC0 does not appear in the classic INT 13h status tables at all, and guests treat it accordingly. Measured on an empty drive, with SeaBIOS patched to return each code in turn. The guests here are German-language, so their messages are quoted as they appear, with the English sense in brackets: PC-DOS 7, "dir a:" 0x80 "Nicht bereit beim Lesen von Laufwerk A" [not ready reading drive A] 0xC0 "Allgemeiner Fehler beim Lesen von Laufwerk A" [general failure reading drive A] 0xAA same message as 0xC0 0x99 same message as 0xC0 <- invented, not a real code 0x06 no message at all; DOS retries forever Windows for Workgroups 3.11, File Manager, drive A: 0x80 "In Laufwerk A ist kein Datenträger eingelegt. Legen Sie einen Datenträger ein, und versuchen Sie es erneut." [Wiederholen] [there is no disk in drive A; insert one and try again] 0xC0 "Der Datenträger in Laufwerk A ist nicht formatiert. Möchten Sie, daß der Datenträger jetzt formatiert wird?" [Ja] [Nein] [the disk in drive A is not formatted; format it now?] DOS gives 0xC0 the same message as the invented code 0x99, which is to say it does not recognise it. Windows does recognise it, and offers to format a diskette that is not there. Both are correct with 0x80. Bochs BIOS, from which SeaBIOS descends, returns 0x80 here as well ("SET_AH(0x80); // drive not ready (timeout)"). It has no READ ID media sensing; that arrived in SeaBIOS with commit e7c5a7ef, and DISK_RET_EMEDIA came with it. OS/2 2.11 and Linux are unaffected: both drive the controller through their own drivers rather than INT 13h. Not verified against real hardware -- I have none with a floppy drive. Signed-off-by: Christian Quante <christian@quante.one> --- src/hw/floppy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hw/floppy.c b/src/hw/floppy.c index XXXXXXX..XXXXXXX 100644 --- a/src/hw/floppy.c +++ b/src/hw/floppy.c @@ -XXX,XX +XXX,XX @@ floppy_check_media(struct drive_s *drive_gf, u8 floppyid) return DISK_RET_SUCCESS; dprintf(2, "Floppy_check_media %d: no medium\n", floppyid); - return DISK_RET_EMEDIA; + return DISK_RET_ETIMEOUT; } static int -- 2.53.0 _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
Kevin, thanks again -- both points fixed, and the 0x0C/0xC0 transposition you dug up is now in 3/3 where it belongs. 2/3 A failed seek is passed up rather than reported as success, and the head goes back to cylinder 0 once a medium is found, so the READ ID in floppy_media_sense() runs on the same track it always did. You were right to flag that -- it was a behaviour change I had waved through with a comment instead of fixing. 3/3 Unchanged apart from the commit message, which now credits where 0xC0 came from. Changes since v2: - floppy_check_media() passes a seek error up (was: masked as success) - it seeks back to cylinder 0 when a medium is present - commit message of 2/3 no longer claims the head is simply left behind - commit message of 2/3 says where the ten-second figure comes from - commit message of 3/3 carries the Bochs 0x0C history A clarification on the timing, because v2 conflated two things that are not the same. The ten-second wait is a real-hardware effect and does not appear under QEMU at all: QEMU completes READ ID on an empty drive (a bug of its own), and the fix on qemu-devel makes the command fail immediately rather than never complete -- so neither of them shows the wait. The figure comes from a further change that makes QEMU leave READ ID unfinished the way hardware does. That one is local and not proposed upstream; it could not be until this series is in place, or every access to an empty drive under QEMU would cost ten seconds. INT 13h AH=02h on an empty A:, SeaBIOS 1.17.0, each commit built and measured on its own: QEMU made to behave like hardware (READ ID never completes) upstream 10.13 s AH = 0xC0 1/3 floppy_drive_seek() 10.13 s AH = 0xC0 (no functional change) 2/3 disk change probe 0.11 s AH = 0xC0 3/3 not ready 0.11 s AH = 0x80 QEMU as it stands today (READ ID succeeds on an empty drive) upstream 0.11 s AH = 0x20 1/3 0.11 s AH = 0x20 2/3 0.11 s AH = 0xC0 3/3 0.11 s AH = 0x80 So on stock QEMU the series saves no time -- there is no wait to save -- but it still turns "controller failure" into "not ready". The wait it removes is the one on real hardware. The extra seek back to cylinder 0 costs no measurable time. A diskette in the drive is still read, and booting from one -- including the cold start where the change line is set for a freshly inserted medium -- is unchanged. Still not verified against real hardware; I have none with a floppy drive. Christian Quante (3): floppy: add floppy_drive_seek() floppy: detect an empty drive via the disk change line floppy: report an empty drive as not ready src/hw/floppy.c | 77 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 70 insertions(+), 7 deletions(-) -- 2.53.0 _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
Wrap the SEEK command and the BDA bookkeeping that goes with it, the way floppy_drive_recal() already does for RECALIBRATE. No functional change; the next patch gains a second caller. Signed-off-by: Christian Quante <christian@quante.one> --- src/hw/floppy.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/hw/floppy.c b/src/hw/floppy.c index XXXXXXX..XXXXXXX 100644 --- a/src/hw/floppy.c +++ b/src/hw/floppy.c @@ -XXX,XX +XXX,XX @@ floppy_drive_recal(u8 floppyid) return DISK_RET_SUCCESS; } +static int +floppy_drive_seek(u8 floppyid, u8 cylinder) +{ + dprintf(2, "Floppy_drive_seek %d to %d\n", floppyid, cylinder); + u8 param[2]; + param[0] = floppyid; + param[1] = cylinder; + int ret = floppy_drive_pio(floppyid, FC_SEEK, param); + if (ret) + return ret; + + SET_BDA(floppy_track[floppyid], cylinder); + return DISK_RET_SUCCESS; +} + static int floppy_drive_specify(void) { @@ -XXX,XX +XXX,XX @@ floppy_prep(struct drive_s *drive_gf, u8 cylinder) } // Seek to cylinder if needed. - u8 lastcyl = GET_BDA(floppy_track[floppyid]); - if (cylinder != lastcyl) { - u8 param[2]; - param[0] = floppyid; - param[1] = cylinder; - int ret = floppy_drive_pio(floppyid, FC_SEEK, param); + if (cylinder != GET_BDA(floppy_track[floppyid])) { + int ret = floppy_drive_seek(floppyid, cylinder); if (ret) return ret; - SET_BDA(floppy_track[floppyid], cylinder); } return DISK_RET_SUCCESS; -- 2.53.0 _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
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> --- src/hw/floppy.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/hw/floppy.c b/src/hw/floppy.c index XXXXXXX..XXXXXXX 100644 --- a/src/hw/floppy.c +++ b/src/hw/floppy.c @@ -XXX,XX +XXX,XX @@ #define PORT_FD_DATA 0x03f5 #define PORT_FD_DIR 0x03f7 +// Digital Input Register (read) +#define FLOPPY_DIR_DSKCHG 0x80 + #define FLOPPY_SIZE_CODE 0x02 // 512 byte sectors #define FLOPPY_DATALEN 0xff // Not used - because size code is 0x02 #define FLOPPY_MOTOR_TICKS 37 // ~2 seconds @@ -XXX,XX +XXX,XX @@ floppy_drive_readid(u8 floppyid, u8 data_rate, u8 head) return 0; } +// Only the 1.2MB 5.25" drive and the 3.5" drives have a disk change line. On +// the older 5.25" types the pin is not driven and reads back as a permanent +// "changed". +static int +floppy_has_changeline(u8 ftype) +{ + return ftype >= 2 && ftype <= 5; +} + +// Determine whether a diskette is present, without waiting for a command to +// time out. The disk change line latches when the medium is removed and is +// cleared only by a step pulse with a diskette in the drive. The caller has +// just recalibrated, which leaves the head on cylinder 0 and need not step at +// all, so step to cylinder 1 and look again. +// +// Report DISK_RET_EMEDIA only when the drive is known to be empty -- an older +// drive without a change line is reported as present, so this can only ever +// fall back to the previous behaviour. +static int +floppy_check_media(struct drive_s *drive_gf, u8 floppyid) +{ + if (!floppy_has_changeline(GET_GLOBALFLAT(drive_gf->floppy_type))) + return DISK_RET_SUCCESS; + + // The caller has just recalibrated this drive, so it is selected in the + // DOR and the DIR reflects its change line. + if (!(inb(PORT_FD_DIR) & FLOPPY_DIR_DSKCHG)) + return DISK_RET_SUCCESS; + + int ret = floppy_drive_seek(floppyid, 1); + if (ret) + return ret; + + if (inb(PORT_FD_DIR) & FLOPPY_DIR_DSKCHG) { + dprintf(2, "Floppy_check_media %d: no medium\n", floppyid); + return DISK_RET_EMEDIA; + } + + // A medium is present. Put the head back on cylinder 0, where the caller + // left it, so that media sensing reads the track it always did. + return floppy_drive_seek(floppyid, 0); +} + static int floppy_media_sense(struct drive_s *drive_gf) { @@ -XXX,XX +XXX,XX @@ floppy_prep(struct drive_s *drive_gf, u8 cylinder) if (ret) return ret; + // An empty drive gives no index pulses, so the READ ID that + // floppy_media_sense() issues would never complete and would wait out + // its timeout once per data rate. Ask the disk change line instead. + ret = floppy_check_media(drive_gf, floppyid); + if (ret) + return ret; + // Sense media. ret = floppy_media_sense(drive_gf); if (ret) -- 2.53.0 _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
An empty drive and an unreadable diskette are different failures, and until the previous patch SeaBIOS could not tell them apart: both ended up in floppy_media_sense() exhausting the data rates and returning DISK_RET_EMEDIA (0xC0). Now that the disk change line identifies an absent medium, report it as DISK_RET_ETIMEOUT (0x80), which the INT 13h tables give as "time out, drive not ready". floppy_media_sense() keeps DISK_RET_EMEDIA for a medium it cannot read. Kevin O'Connor traced where 0xC0 came from: Bochs BIOS answers 0x0C here, "media type not found", and the value was transposed when the code was brought over at the initial checkin f076a3ee. Ralf Brown's interrupt list gives 0x0C as "unsupported track or invalid media" -- so 0xC0 has never been an INT 13h status code at all. It does not appear in the classic tables, and guests treat it accordingly. Measured on an empty drive, with SeaBIOS patched to return each code in turn. The guests here are German-language, so their messages are quoted as they appear, with the English sense in brackets: PC-DOS 7, "dir a:" 0x80 "Nicht bereit beim Lesen von Laufwerk A" [not ready reading drive A] 0xC0 "Allgemeiner Fehler beim Lesen von Laufwerk A" [general failure reading drive A] 0xAA same message as 0xC0 0x99 same message as 0xC0 <- invented, not a real code 0x06 no message at all; DOS retries forever Windows for Workgroups 3.11, File Manager, drive A: 0x80 "In Laufwerk A ist kein Datenträger eingelegt. Legen Sie einen Datenträger ein, und versuchen Sie es erneut." [Wiederholen] [there is no disk in drive A; insert one and try again] 0xC0 "Der Datenträger in Laufwerk A ist nicht formatiert. Möchten Sie, daß der Datenträger jetzt formatiert wird?" [Ja] [Nein] [the disk in drive A is not formatted; format it now?] DOS gives 0xC0 the same message as the invented code 0x99, which is to say it does not recognise it. Windows does recognise it, and offers to format a diskette that is not there. Both are correct with 0x80. OS/2 2.11 and Linux are unaffected: both drive the controller through their own drivers rather than INT 13h. Not verified against real hardware -- I have none with a floppy drive. Signed-off-by: Christian Quante <christian@quante.one> --- src/hw/floppy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hw/floppy.c b/src/hw/floppy.c index XXXXXXX..XXXXXXX 100644 --- a/src/hw/floppy.c +++ b/src/hw/floppy.c @@ -XXX,XX +XXX,XX @@ floppy_has_changeline(u8 ftype) // just recalibrated, which leaves the head on cylinder 0 and need not step at // all, so step to cylinder 1 and look again. // -// Report DISK_RET_EMEDIA only when the drive is known to be empty -- an older +// Report a missing medium only when the drive is known to be empty -- an older // drive without a change line is reported as present, so this can only ever // fall back to the previous behaviour. static int @@ -XXX,XX +XXX,XX @@ floppy_check_media(struct drive_s *drive_gf, u8 floppyid) if (inb(PORT_FD_DIR) & FLOPPY_DIR_DSKCHG) { dprintf(2, "Floppy_check_media %d: no medium\n", floppyid); - return DISK_RET_EMEDIA; + return DISK_RET_ETIMEOUT; } // A medium is present. Put the head back on cylinder 0, where the caller -- 2.53.0 _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org