From fa3dc593672604e479f49b3fa10f494df3e7cb2a Mon Sep 17 00:00:00 2001 From: Andrew Bird Date: Tue, 21 Mar 2023 18:34:50 +0000 Subject: [PATCH] DosGetExtFree: Use new redirector function 11a3 To be able to return free space on larger non local disks, the redirector needs an extension. Dosemu2 has implemented this function and FDPP has an almost identical patch to this. If the extension is not implemented by your chosen redirector, then fallback to the standard 110c function is done for int21/7303. With this patch up to 2TB (with Dosemu2 reporting in 512 blocks) can be displayed. --- hdr/network.h | 3 +++ kernel/dosfns.c | 47 +++++++++++++++++++++++++++++++++++++++-------- kernel/int2f.asm | 3 +++ kernel/proto.h | 1 + 4 files changed, 46 insertions(+), 8 deletions(-) diff --git a/hdr/network.h b/hdr/network.h index dcb66f0..7e33e5c 100644 --- a/hdr/network.h +++ b/hdr/network.h @@ -59,6 +59,9 @@ #define REM_PRINTREDIR 0x1125 #define REM_EXTOC 0x112e +/* Redirector extensions */ +#define REM_GETLARGESPACE 0x11a3 + struct rgds { UWORD r_spc; UWORD r_navc; diff --git a/kernel/dosfns.c b/kernel/dosfns.c index f9655f8..3a8451f 100644 --- a/kernel/dosfns.c +++ b/kernel/dosfns.c @@ -771,7 +771,7 @@ UWORD DosGetFree(UBYTE drive, UWORD * navc, UWORD * bps, UWORD * nc) /* navc==NULL means: called from FatGetDrvData, fcbfns.c */ struct dpb FAR *dpbp; struct cds FAR *cdsp; - COUNT rg[4]; + COUNT rg[5]; /* add space for SI, although it's unused here */ UWORD spc; /* first check for valid drive */ @@ -876,7 +876,7 @@ COUNT DosGetExtFree(BYTE FAR * DriveString, struct xfreespace FAR * xfsp) { struct dpb FAR *dpbp; struct cds FAR *cdsp; - UCOUNT rg[4]; + UCOUNT rg[5]; /* ensure all fields known value - clear reserved bytes & set xfs_version.actual to 0 */ fmemset(xfsp, 0, sizeof(struct xfreespace)); @@ -899,13 +899,44 @@ COUNT DosGetExtFree(BYTE FAR * DriveString, struct xfreespace FAR * xfsp) if (cdsp->cdsFlags & CDSNETWDRV) { - if (remote_getfree(cdsp, rg) != SUCCESS) - return DE_INVLDDRV; + /* Try redirector extension */ + if (remote_getfree_11a3(cdsp, rg) != SUCCESS) + { + /* Fallback */ + if (remote_getfree(cdsp, rg) != SUCCESS) + return DE_INVLDDRV; - xfsp->xfs_clussize = rg[0]; - xfsp->xfs_totalclusters = rg[1]; - xfsp->xfs_secsize = rg[2]; - xfsp->xfs_freeclusters = rg[3]; + xfsp->xfs_clussize = rg[0]; + xfsp->xfs_totalclusters = rg[1]; + xfsp->xfs_secsize = rg[2]; + xfsp->xfs_freeclusters = rg[3]; + } + else /* Supports extension */ + { + UDWORD total, avail; + UDWORD bps, spc; + + bps = rg[4]; + spc = 1; + total = (((UDWORD)rg[0] << 16UL) | rg[1]); + avail = (((UDWORD)rg[2] << 16UL) | rg[3]); + + while (total > 0x00ffffff && spc < 128) { + spc *= 2; + avail /= 2; + total /= 2; + } + while (total > 0x00ffffff && bps < 32768) { + bps *= 2; + avail /= 2; + total /= 2; + } + + xfsp->xfs_secsize = bps; + xfsp->xfs_clussize = spc; + xfsp->xfs_totalclusters = total; + xfsp->xfs_freeclusters = avail; + } } else { diff --git a/kernel/int2f.asm b/kernel/int2f.asm index 70f1bca..8ab31fc 100644 --- a/kernel/int2f.asm +++ b/kernel/int2f.asm @@ -428,6 +428,8 @@ call_int2f: push cx ; arg cmp al, 0ch je remote_getfree + cmp al, 0xa3 + je remote_getfree cmp al, 1eh je remote_print_doredir cmp al, 1fh @@ -478,6 +480,7 @@ remote_getfree: mov [di+2],bx mov [di+4],cx mov [di+6],dx + mov [di+8],si ; for REM_GETLARGEFREE, unused on REM_GETFREE jmp short ret_set_ax_to_carry remote_rw: diff --git a/kernel/proto.h b/kernel/proto.h index f8fa240..551d03b 100644 --- a/kernel/proto.h +++ b/kernel/proto.h @@ -377,6 +377,7 @@ int network_redirector_fp(unsigned cmd, void far *s); long ASMPASCAL network_redirector_mx(unsigned cmd, void far *s, void *arg); #define remote_rw(cmd,s,arg) network_redirector_mx(cmd, s, (void *)arg) #define remote_getfree(s,d) (int)network_redirector_mx(REM_GETSPACE, s, d) +#define remote_getfree_11a3(s,d) (int)network_redirector_mx(REM_GETLARGESPACE, s, d) #define remote_lseek(s,new_pos) network_redirector_mx(REM_LSEEK, s, &new_pos) #define remote_setfattr(attr) (int)network_redirector_mx(REM_SETATTR, NULL, (void *)attr) #define remote_printredir(dx,ax) (int)network_redirector_mx(REM_PRINTREDIR, MK_FP(0,dx),(void *)ax)