From c5211dd5f1a52f9918eeae0785fcea547f9eca2a Mon Sep 17 00:00:00 2001 From: "E. C. Masloch" Date: Thu, 20 Feb 2025 09:55:59 +0100 Subject: [PATCH 1/2] set CY before calling 21.71 or 21.73 DOS functions (LFN, FAT32) Between the current lDOS kernel (which doesn't support 21.73), SRDISK, and dosemu2 revision 6a2f4f527 the return from 21.7303 somehow is with both Carry Flag and AX preserved. This makes the DIR command think that the call is supported when it isn't. The proper check is to call with CY set before the call. --- cmd/dir.c | 2 ++ lib/lfnfuncs.c | 6 ++++++ lib/prprompt.c | 1 + suppl/src/_getdcwd.c | 1 + suppl/src/dfntruen.c | 1 + 5 files changed, 11 insertions(+) diff --git a/cmd/dir.c b/cmd/dir.c index 26c6c1d5..6f9d37ae 100644 --- a/cmd/dir.c +++ b/cmd/dir.c @@ -291,6 +291,7 @@ static void printLFNname(char *shortName, char *ext) dprintf(("[LFN: path %s\n",pathbuffer)); /* LFN get canonical LFN */ + r.r_flags = 1; /* CY before 21.71 calls! */ r.r_ax = 0x7160; r.r_cx = 0x8002; r.r_si = FP_OFF( pathbuffer ); @@ -760,6 +761,7 @@ static int dir_print_free(unsigned long dirs) displayString(TEXT_DIR_FTR_DIRS, buffer); rootname[0] = toupper(*path); + r.r_flags = 1; /* CY before 21.73 calls! */ r.r_ax = 0x7303; r.r_ds = FP_SEG(rootname); r.r_dx = FP_OFF(rootname); diff --git a/lib/lfnfuncs.c b/lib/lfnfuncs.c index 169eb22b..e2d04886 100644 --- a/lib/lfnfuncs.c +++ b/lib/lfnfuncs.c @@ -53,6 +53,7 @@ const char * getshortfilename( const char *longfilename ) r.r_di = FP_OFF( shortfilename ); shortfilename[0] = '\0'; r.r_cx = 0x8001; /* Get short filename */ + r.r_flags = 1; /* CY before 21.71 calls! */ r.r_ax = 0x7160;/* LFN truename function */ intrpt( 0x21, &r ); @@ -82,6 +83,7 @@ static int __creat_or_truncate( const char * filename, int mode, int code ) r.r_bx = O_WRONLY; r.r_cx = mode; r.r_dx = code; + r.r_flags = 1; /* CY before 21.71 calls! */ r.r_ax = 0x716C; intrpt( 0x21, &r ); @@ -129,6 +131,7 @@ int lfnrename( const char *oldfilename, const char *newfilename ) r.r_dx = FP_OFF( oldfilename ); r.r_es = FP_SEG( newfilename ); r.r_di = FP_OFF( newfilename ); + r.r_flags = 1; /* CY before 21.71 calls! */ r.r_ax = 0x7156; intrpt( 0x21, &r ); @@ -181,6 +184,7 @@ int lfnfindfirst( const char *path, struct lfnffblk *buf, unsigned attr ) r.r_di = FP_OFF( &lfnblock ); /* LFN find block goes in ES:DI */ r.r_si = 1; /* Use DOS date/time format */ r.r_cx = attr; + r.r_flags = 1; /* CY before 21.71 calls! */ r.r_ax = 0x714E; /* LFN Findfirst */ intrpt( 0x21, &r ); @@ -226,6 +230,7 @@ int lfnfindnext( struct lfnffblk *buf ) r.r_di = FP_OFF( &lfnblock ); /* The LFN find block */ r.r_bx = buf->lfnax; /* The lfn handle set by findfirst */ r.r_si = 1; /* Use DOS times */ + r.r_flags = 1; /* CY before 21.71 calls! */ r.r_ax = 0x714F; intrpt( 0x21, &r ); @@ -247,6 +252,7 @@ int lfnfindclose( struct lfnffblk *buf ) if( !buf->lfnsup || !__supportlfns ) return( 0 ); r.r_bx = buf->lfnax; /* Findfirst handle */ + r.r_flags = 1; /* CY before 21.71 calls! */ r.r_ax = 0x71A1; /* LFN findclose */ intrpt( 0x21, &r ); diff --git a/lib/prprompt.c b/lib/prprompt.c index 365fc65e..727b30f1 100644 --- a/lib/prprompt.c +++ b/lib/prprompt.c @@ -140,6 +140,7 @@ void displayPrompt(const char *pr) d = getdisk(); + r.r_flags = 1; /* CY before 21.71 calls! */ r.r_ax = 0x7147; r.r_dx = 0; r.r_si = FP_OFF(pathname); diff --git a/suppl/src/_getdcwd.c b/suppl/src/_getdcwd.c index 289c0476..197c22db 100644 --- a/suppl/src/_getdcwd.c +++ b/suppl/src/_getdcwd.c @@ -156,6 +156,7 @@ char *_getdcwd(int drive, char Xbuf[], unsigned length) r.r_dx = drive; r.r_ds = FP_SEG(buf); #ifdef FEATURE_LONG_FILENAMES + r.r_flags = 1; /* CY before 21.71 calls! */ r.r_ax = 0x7147; #else r.r_ax = 0x4700; diff --git a/suppl/src/dfntruen.c b/suppl/src/dfntruen.c index 364f214b..a50d4340 100644 --- a/suppl/src/dfntruen.c +++ b/suppl/src/dfntruen.c @@ -105,6 +105,7 @@ char *dfntruename(const char * const fnam) chkHeap if((h = eno_malloc(DFN_FILENAME_BUFFER_LENGTH)) != 0) { #ifdef FEATURE_LONG_FILENAMES + r.r_flags = 1; /* CY before 21.71 calls! */ r.r_ax = 0x7160; r.r_cx = 0x8002; #else From 88c2152777e79111e2ff0bb2a12423040ea4abee Mon Sep 17 00:00:00 2001 From: "E. C. Masloch" Date: Thu, 20 Feb 2025 11:02:50 +0100 Subject: [PATCH 2/2] dir.c: allow 21.7303 to return NC, ax=0 to mean supported (EDR-DOS) EDR-DOS returns NC, AX = 0000h from 21.7303. This was incorrectly detected as "not supported" here. CF unchanged and AL = 00h is the typical error return, albeit CF unchanged AX unchanged has also been observed (on dosemu2 + lDOS + SRDISK). Reference on the correct "unsupported" return: https://sourceforge.net/p/freedos/mailman/message/59128382/ Incorrect interrupt list entry: https://fd.lod.bz/rbil/interrup/dos_kernel/217303.html --- cmd/dir.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cmd/dir.c b/cmd/dir.c index 6f9d37ae..31a577ae 100644 --- a/cmd/dir.c +++ b/cmd/dir.c @@ -772,8 +772,10 @@ static int dir_print_free(unsigned long dirs) /* Note: RBIL carry clear and al==0 also means unimplemented alternately carry set and ax==undefined (usually unchanged) for unimplemented - */ - if(!( r.r_flags & 1 ) && ( r.r_ax & 0xFF) ) { + ecm: RBIL is wrong, CF unchanged al=0 is the typical error return. + EDR-DOS returns NC ax=0 so checking for al!=0 here was wrong. + */ + if(!( r.r_flags & 1 ) && ( r.r_ax != 0x7300 ) ) { dprintf(("[DIR: Using FAT32 info]\n")); clustersize = FAT32_Free_Space.sectors_per_cluster * FAT32_Free_Space.bytes_per_sector;