test for uninitialized dpb on INT25,26 and always allow rw block zero

The problem is that ISFAT32 macro only tests for dpb->fatsize = 0, and
not also for xfatsize != 0. So the ISFAT32 macro returns a
"false positive" on uninitialized dpbs, where both fatsize and xfatsize
are zero.

This fixes https://github.com/FDOS/kernel/issues/200. However, the dpb
is not properly initialized via a media check by an INT25,26 yet.

This commit makes sure that written sectors are removed from the
block cache.
This commit is contained in:
Bernd Boeckmann 2025-06-02 11:21:36 +02:00
parent 654e7b7a6c
commit 8d29d66148

View File

@ -1812,6 +1812,7 @@ VOID ASMCFUNC int2526_handler(WORD mode, struct int25regs FAR * r)
UWORD nblks; UWORD nblks;
BYTE FAR *buf; BYTE FAR *buf;
UBYTE drv; UBYTE drv;
struct dpb FAR *dpbp;
if (mode == 0x26) if (mode == 0x26)
mode = DSKWRITEINT26; mode = DSKWRITEINT26;
@ -1822,17 +1823,23 @@ VOID ASMCFUNC int2526_handler(WORD mode, struct int25regs FAR * r)
/* high bit of AL set, so mask it together with AH */ /* high bit of AL set, so mask it together with AH */
/* otherwise we might access a non-existing unit */ /* otherwise we might access a non-existing unit */
if (drv >= lastdrive) dpbp = get_dpb(drv);
if (drv >= lastdrive || dpbp == NULL)
{ {
r->ax = 0x201; r->ax = 0x201;
SET_CARRY_FLAG(); SET_CARRY_FLAG();
return; return;
} }
nblks = r->cx;
blkno = r->dx;
#ifdef WITHFAT32 #ifdef WITHFAT32
{ {
struct dpb FAR *dpbp = get_dpb(drv); /* if reading / writing block other than bootsecter,
if (dpbp != NULL && ISFAT32(dpbp)) prevent using INT25,26 on initialized FAT32 */
if ((blkno != 0) && ISFAT32(dpbp) && (dpbp->dpb_xfatsize != 0))
{ {
r->ax = 0x207; r->ax = 0x207;
SET_CARRY_FLAG(); SET_CARRY_FLAG();
@ -1841,9 +1848,6 @@ VOID ASMCFUNC int2526_handler(WORD mode, struct int25regs FAR * r)
} }
#endif #endif
nblks = r->cx;
blkno = r->dx;
buf = MK_FP(r->ds, r->bx); buf = MK_FP(r->ds, r->bx);
if (nblks == 0xFFFF) if (nblks == 0xFFFF)
@ -1856,6 +1860,7 @@ VOID ASMCFUNC int2526_handler(WORD mode, struct int25regs FAR * r)
InDOS++; InDOS++;
DeleteBlockInBufferCache(blkno, blkno, drv, XFR_WRITE);
r->ax = dskxfer(drv, blkno, buf, nblks, mode); r->ax = dskxfer(drv, blkno, buf, nblks, mode);
CLEAR_CARRY_FLAG(); CLEAR_CARRY_FLAG();