References: R. Brown, "INT 15 - OS HOOK - DEVICE POST (AT,PS)", in The x86 Interrupt List. https://www.cs.cmu.edu/~ralf/files.html [Updated: 2018-02-28].
F. v. Gilluwe, The Undocumented PC. Boston, MA: Addison-Wesley, 1997, p. 780.
Signed-off-by: Lev Kujawski lkujaw@member.fsf.org --- src/system.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/src/system.c b/src/system.c index 438e60e..ec99347 100644 --- a/src/system.c +++ b/src/system.c @@ -232,6 +232,7 @@ handle_1590(struct bregs *regs) static void handle_1591(struct bregs *regs) { + set_code_success(regs); }
// keyboard intercept
References: F. v. Gilluwe, The Undocumented PC. Boston, MA: Addison-Wesley, 1997, p. 605.
Signed-off-by: Lev Kujawski lkujaw@member.fsf.org --- src/disk.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/src/disk.c b/src/disk.c index 0328fbd..14a99db 100644 --- a/src/disk.c +++ b/src/disk.c @@ -776,4 +776,10 @@ handle_76(void) debug_isr(DEBUG_ISR_76); SET_BDA(disk_interrupt_flag, 0xff); pic_eoi2(); + + // Chain any installed interrupt completion handlers. + struct bregs br; + memset(&br, 0, sizeof(br)); + br.ax = 0x9100; + call16_int(0x15, &br); }
In accord with the El Torito specification[1], SeaBIOS now signals failure (AH=1 and CF) whenever attempts are made to terminate disk emulation (0x4B) for non-emulated drives. The prior behavior of always returning success caused the Solaris 9 Device Configuration Assistant (DCA) diskette (d1_image) to fail to boot as it was unable to access the non-existent underlying drive.
References:
[1]: "CF - Clear if system released CF - Set if system not in emulation mode"
C. E. Stevens and S. Merkin, '"El Torito" Bootable CD-ROM Format Specification', Phoenix Technologies and IBM, 1994, p. 17.
Signed-off-by: Lev Kujawski lkujaw@member.fsf.org --- src/disk.c | 82 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 36 deletions(-)
diff --git a/src/disk.c b/src/disk.c index 14a99db..6a25015 100644 --- a/src/disk.c +++ b/src/disk.c @@ -568,6 +568,33 @@ disk_1349(struct bregs *regs, struct drive_s *drive_fl) regs->ah = DISK_RET_ECHANGED; }
+// El Torito - Terminate disk emulation +static void +disk_134b(struct bregs *regs, struct drive_s *drive_fl) +{ + if (CONFIG_CDROM_BOOT && regs->dl == GET_LOW(CDEmu.emulated_drive)) { + if ((regs->dl >= EXTSTART_CD) || + (CONFIG_CDROM_EMU && GET_LOW(CDEmu.media))) + { + memcpy_far(regs->ds, (void*)(regs->si+0), + SEG_LOW, &CDEmu, sizeof(CDEmu)); + + // If we have to terminate emulation + if (regs->al == 0x00) { + // FIXME ElTorito Various. Should be handled accordingly to spec + SET_LOW(CDEmu.media, 0x00); // bye bye + + // XXX - update floppy/hd count. + } + + disk_ret(regs, DISK_RET_SUCCESS); + return; + } + } + + disk_ret(regs, DISK_RET_EPARAM); +} + static void disk_134e01(struct bregs *regs, struct drive_s *drive_fl) { @@ -650,6 +677,7 @@ disk_13(struct bregs *regs, struct drive_s *drive_fl) case 0x47: disk_1347(regs, drive_fl); break; case 0x48: disk_1348(regs, drive_fl); break; case 0x49: disk_1349(regs, drive_fl); break; + case 0x4b: disk_134b(regs, drive_fl); break; case 0x4e: disk_134e(regs, drive_fl); break; default: disk_13XX(regs, drive_fl); break; } @@ -675,23 +703,6 @@ floppy_13(struct bregs *regs, struct drive_s *drive_fl) } }
-// ElTorito - Terminate disk emu -static void -cdemu_134b(struct bregs *regs) -{ - memcpy_far(regs->ds, (void*)(regs->si+0), SEG_LOW, &CDEmu, sizeof(CDEmu)); - - // If we have to terminate emulation - if (regs->al == 0x00) { - // FIXME ElTorito Various. Should be handled accordingly to spec - SET_LOW(CDEmu.media, 0x00); // bye bye - - // XXX - update floppy/hd count. - } - - disk_ret(regs, DISK_RET_SUCCESS); -} -
/**************************************************************** * Entry points @@ -743,27 +754,26 @@ handle_13(struct bregs *regs) debug_enter(regs, DEBUG_HDL_13); u8 extdrive = regs->dl;
- if (CONFIG_CDROM_EMU) { - if (regs->ah == 0x4b) { - cdemu_134b(regs); - return; - } - if (GET_LOW(CDEmu.media)) { - u8 emudrive = GET_LOW(CDEmu.emulated_drive); - if (extdrive == emudrive) { - // Access to an emulated drive. - struct drive_s *cdemu_gf = GET_GLOBAL(cdemu_drive_gf); - if (regs->ah > 0x16) { - // Only old-style commands supported. - disk_13XX(regs, cdemu_gf); - return; - } + if (CONFIG_CDROM_EMU && GET_LOW(CDEmu.media)) { + const u8 emudrive = GET_LOW(CDEmu.emulated_drive); + + if (extdrive == emudrive) { + // Access to an emulated drive. + struct drive_s *cdemu_gf = GET_GLOBAL(cdemu_drive_gf); + + if (regs->ah <= 0x16 || regs->ah == 0x4b) { disk_13(regs, cdemu_gf); - return; + } else { + // Only old-style commands supported. + disk_13XX(regs, cdemu_gf); } - if (extdrive < EXTSTART_CD && ((emudrive ^ extdrive) & 0x80) == 0) - // Adjust id to make room for emulated drive. - extdrive--; + + return; + } + + if (extdrive < EXTSTART_CD && ((emudrive ^ extdrive) & 0x80) == 0) { + // Adjust id to make room for emulated drive. + extdrive--; } } handle_legacy_disk(regs, extdrive);
On Fri, May 20, 2022 at 03:19:03PM +0000, Lev Kujawski wrote:
In accord with the El Torito specification[1], SeaBIOS now signals failure (AH=1 and CF) whenever attempts are made to terminate disk emulation (0x4B) for non-emulated drives. The prior behavior of always returning success caused the Solaris 9 Device Configuration Assistant (DCA) diskette (d1_image) to fail to boot as it was unable to access the non-existent underlying drive.
References:
[1]: "CF - Clear if system released CF - Set if system not in emulation mode"
C. E. Stevens and S. Merkin, '"El Torito" Bootable CD-ROM Format Specification', Phoenix Technologies and IBM, 1994, p. 17.
Thanks.
I noticed a bit of "code movement" in this patch. Is the only functional change to return DISK_RET_EPARAM when 134b is invoked on a non-emulated drive?
Cheers, -Kevin
Kevin O'Connor writes:
On Fri, May 20, 2022 at 03:19:03PM +0000, Lev Kujawski wrote:
In accord with the El Torito specification[1], SeaBIOS now signals failure (AH=1 and CF) whenever attempts are made to terminate disk emulation (0x4B) for non-emulated drives. The prior behavior of always returning success caused the Solaris 9 Device Configuration Assistant (DCA) diskette (d1_image) to fail to boot as it was unable to access the non-existent underlying drive.
References:
[1]: "CF - Clear if system released CF - Set if system not in emulation mode"
C. E. Stevens and S. Merkin, '"El Torito" Bootable CD-ROM Format Specification', Phoenix Technologies and IBM, 1994, p. 17.
Thanks.
I noticed a bit of "code movement" in this patch. Is the only functional change to return DISK_RET_EPARAM when 134b is invoked on a non-emulated drive?
Cheers, -Kevin
Hi Kevin,
I decided to separate out the El Torito termination handler because it seemed the cleanest way to deal with the following three cases:
a) CONFIG_CDROM_BOOT=n
Old behavior: Prints a debug message about an unimplemented call New behavior: Just return failure
b) CONFIG_CDROM_BOOT=y and CONFIG_CDROM_EMU=n
Old behavior: Unimplemented call again New behavior: Fill in the CD-ROM specification table (no emulation)
For example, the Solaris install CD does not use disk emulation but still expects to get this table from the BIOS.
c) CONFIG_CDROM_BOOT=y and CONFIG_CDROM_EMU=y
(As described in the patch)
Kind regards, Lev Kujawski
On Fri, May 20, 2022 at 03:19:01PM +0000, Lev Kujawski wrote:
References: R. Brown, "INT 15 - OS HOOK - DEVICE POST (AT,PS)", in The x86 Interrupt List. https://www.cs.cmu.edu/~ralf/files.html [Updated: 2018-02-28].
F. v. Gilluwe, The Undocumented PC. Boston, MA: Addison-Wesley, 1997, p. 780.
Thanks. Is there some program that now works because of this change? We use "rbil" quite a bit as a reference, but we also know it is not a complete reference. So, it helps to know what real-world programs a change is known to impact. Same comment on patch 2.
Cheers, -Kevin