From c08313ab62ed236fc9a11f1c558cc335b93de30c Mon Sep 17 00:00:00 2001 From: Bernd Boeckmann Date: Mon, 4 Mar 2024 22:09:40 +0100 Subject: [PATCH] fix issue #144 by correcting getbpb return code getbpb now returns 0 instead of S_DONE in case of an uninitialized partition, copying the default BPB into the BPB. The previous return of S_DONE in case of uninitialized partitions resulted in rp->r_bpptr not getting set in bldbpb. This in combination with indicating success resulted in garbage returned via rp->r_bpptr. The DPB values are now being set to the default BPB ones in media_check https://github.com/FDOS/kernel/blob/ea951d8136444e334f06a313465b5844f738354e/kernel/fatfs.c#L1728 via call to bpb_to_dpb in case of an uninitialized partition. This may have side effects. But because DF_NOACCESS is still set, I think it is the right way to do it. The commit also masks high bit of AL for INT25/26 containing the drive number. Some programs may set the bit according to RBIL: "examination of CPWIN386.CPL indicates that if this call fails with error 0408h on an old-style (<32M) call, one should retry the call with the high bit of the drive number in AL set" Leaving the bit set may render the given drive number unusable. It should do no harm to mask it to increase the chance of the operation to succeed. Also, the AH should be set to zero, because drive is given only in AL. --- kernel/dsk.c | 2 +- kernel/inthndlr.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/kernel/dsk.c b/kernel/dsk.c index 654f8b98..70c4a8f8 100644 --- a/kernel/dsk.c +++ b/kernel/dsk.c @@ -392,7 +392,7 @@ STATIC WORD getbpb(ddt * pddt) { /* copy default bpb to be sure that there is no bogus data */ memcpy(pbpbarray, &pddt->ddt_defbpb, sizeof(bpb)); - return S_DONE; + return 0; } pddt->ddt_descflags &= ~DF_NOACCESS; /* set drive to accessible */ diff --git a/kernel/inthndlr.c b/kernel/inthndlr.c index 50035123..089cbbc3 100644 --- a/kernel/inthndlr.c +++ b/kernel/inthndlr.c @@ -1820,7 +1820,9 @@ VOID ASMCFUNC int2526_handler(WORD mode, struct int25regs FAR * r) else mode = DSKREADINT25; - drv = r->ax; + drv = r->ax & 0x7f; /* according to RBIL, some programs may try with */ + /* high bit of AL set, so mask it together with AH */ + /* otherwise we might access a non-existing unit */ if (drv >= lastdrive) {