From 8d29d6614806b14466ba4b3a9816112acd9b6b40 Mon Sep 17 00:00:00 2001 From: Bernd Boeckmann Date: Mon, 2 Jun 2025 11:21:36 +0200 Subject: [PATCH] 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. --- kernel/inthndlr.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/kernel/inthndlr.c b/kernel/inthndlr.c index ce3fc5d..096df9f 100644 --- a/kernel/inthndlr.c +++ b/kernel/inthndlr.c @@ -1812,6 +1812,7 @@ VOID ASMCFUNC int2526_handler(WORD mode, struct int25regs FAR * r) UWORD nblks; BYTE FAR *buf; UBYTE drv; + struct dpb FAR *dpbp; if (mode == 0x26) 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 */ /* otherwise we might access a non-existing unit */ - if (drv >= lastdrive) + dpbp = get_dpb(drv); + + if (drv >= lastdrive || dpbp == NULL) { r->ax = 0x201; SET_CARRY_FLAG(); return; } + nblks = r->cx; + blkno = r->dx; + #ifdef WITHFAT32 { - struct dpb FAR *dpbp = get_dpb(drv); - if (dpbp != NULL && ISFAT32(dpbp)) + /* if reading / writing block other than bootsecter, + prevent using INT25,26 on initialized FAT32 */ + if ((blkno != 0) && ISFAT32(dpbp) && (dpbp->dpb_xfatsize != 0)) { r->ax = 0x207; SET_CARRY_FLAG(); @@ -1841,9 +1848,6 @@ VOID ASMCFUNC int2526_handler(WORD mode, struct int25regs FAR * r) } #endif - nblks = r->cx; - blkno = r->dx; - buf = MK_FP(r->ds, r->bx); if (nblks == 0xFFFF) @@ -1856,6 +1860,7 @@ VOID ASMCFUNC int2526_handler(WORD mode, struct int25regs FAR * r) InDOS++; + DeleteBlockInBufferCache(blkno, blkno, drv, XFR_WRITE); r->ax = dskxfer(drv, blkno, buf, nblks, mode); CLEAR_CARRY_FLAG();