diff --git a/build.bat b/build.bat index 8a58445..b58a944 100644 --- a/build.bat +++ b/build.bat @@ -1,86 +1,135 @@ -@echo off +:-@echo off -rem batch file to build everything +:- batch file to build everything -rem $Id$ +:- $Id$ -rem $Log$ -rem Revision 1.5 2001/07/09 22:19:30 bartoldeman -rem LBA/FCB/FAT/SYS/Ctrl-C/ioctl fixes + memory savings -rem -rem Revision 1.4 2001/03/22 04:13:30 bartoldeman -rem Change LF to CR/LF in batch files. -rem -rem Revision 1.3 2000/05/25 20:56:19 jimtabor -rem Fixed project history -rem -rem Revision 1.2 2000/05/14 17:05:39 jimtabor -rem Cleanup CRs -rem -rem Revision 1.1.1.1 2000/05/06 19:34:53 jhall1 -rem The FreeDOS Kernel. A DOS kernel that aims to be 100% compatible with -rem MS-DOS. Distributed under the GNU GPL. -rem -rem Revision 1.5 1999/08/25 03:59:14 jprice -rem New build batch files. -rem -rem Revision 1.4 1999/08/25 03:38:16 jprice -rem New build config -rem -rem Revision 1.3 1999/04/23 03:46:02 jprice -rem Improved by jprice -rem -rem Revision 1.2 1999/04/17 19:13:29 jprice -rem ror4 patches -rem -rem Revision 1.1.1.1 1999/03/29 15:39:13 jprice -rem New version without IPL.SYS -rem -rem Revision 1.5 1999/02/09 04:47:54 jprice -rem Make makefile use common config.mak file -rem -rem Revision 1.4 1999/01/30 08:29:10 jprice -rem Clean up -rem -rem Revision 1.3 1999/01/30 07:49:16 jprice -rem Clean up -rem +:- $Log$ +:- Revision 1.6 2001/11/04 19:47:37 bartoldeman +:- kernel 2025a changes: see history.txt +:- +:- Revision 1.5 2001/07/09 22:19:30 bartoldeman +:- LBA/FCB/FAT/SYS/Ctrl-C/ioctl fixes + memory savings +:- +:- Revision 1.4 2001/03/22 04:13:30 bartoldeman +:- Change LF to CR/LF in batch files. +:- +:- Revision 1.3 2000/05/25 20:56:19 jimtabor +:- Fixed project history +:- +:- Revision 1.2 2000/05/14 17:05:39 jimtabor +:- Cleanup CRs +:- +:- Revision 1.1.1.1 2000/05/06 19:34:53 jhall1 +:- The FreeDOS Kernel. A DOS kernel that aims to be 100% compatible with +:- MS-DOS. Distributed under the GNU GPL. +:- +:- Revision 1.5 1999/08/25 03:59:14 jprice +:- New build batch files. +:- +:- Revision 1.4 1999/08/25 03:38:16 jprice +:- New build config +:- +:- Revision 1.3 1999/04/23 03:46:02 jprice +:- Improved by jprice +:- +:- Revision 1.2 1999/04/17 19:13:29 jprice +:- ror4 patches +:- +:- Revision 1.1.1.1 1999/03/29 15:39:13 jprice +:- New version without IPL.SYS +:- +:- Revision 1.5 1999/02/09 04:47:54 jprice +:- Make makefile use common config.mak file +:- +:- Revision 1.4 1999/01/30 08:29:10 jprice +:- Clean up +:- +:- Revision 1.3 1999/01/30 07:49:16 jprice +:- Clean up +:- -if not exist config.bat goto noconfigbat -if not exist config.mak goto noconfigmak -goto start +set XERROR= -:noconfigbat -echo You must copy CONFIG.B to CONFIG.BAT and edit it to reflect your setup! -goto end -:noconfigmak -echo You must copy CONFIG.M to CONFIG.MAK and edit it to reflect your setup! -goto end +if not exist config.bat echo You must copy CONFIG.B to CONFIG.BAT and edit it to reflect your setup! +if not exist config.bat goto end + +if not \%1 == \-r goto norebuild + del kernel\*.obj + del lib\libm.lib +:norebuild + -:start call config.bat -cd lib -%MAKE% -flibm.mak +set XERROR= + +:********************************************************************** +:* DONE with preferences - following is command line handling +:* +:* options on the commandline overwrite your default settings +:* +:* options handled ( case significant !! ) +:* +:* BUILD [fat32|fat16] [msc|wc|tc|tcpp] [86|186|386] +:* +:********************************************************************** + +:loop_commandline + +if \%1 == \ goto done_with_commandline + +if %1 == fat32 set XFAT=32 +if %1 == fat16 set XFAT=16 + +if %1 == msc set COMPILER=MSCL8 +if %1 == wc set COMPILER=WATCOM +if %1 == tc set COMPILER=TC2 +if %1 == tcpp set COMPILER=TURBOCPP + + +if %1 == 86 set XCPU=86 +if %1 == 186 set XCPU=186 +if %1 == 386 set XCPU=386 + +shift +goto loop_commandline + +:done_with_commandline + +if \%COMPILER% == \ echo you MUST define a COMPILER variable in CONFIG.BAT +if \%COMPILER% == \ goto end + +:************************************************************************ +:* finally - we are going to compile +:************************************************************************ + +cd utils +%MAKE% production +if errorlevel 1 goto abort + +cd ..\lib +%MAKE% if errorlevel 1 goto abort cd ..\drivers -%MAKE% -fdevice.mak production +%MAKE% production if errorlevel 1 goto abort + cd ..\boot -%MAKE% -fboot.mak production +%MAKE% production if errorlevel 1 goto abort cd ..\sys -%MAKE% -fbin2c.mak production -if errorlevel 1 goto abort -%MAKE% -fsys.mak production +%MAKE% production if errorlevel 1 goto abort +:start + cd ..\kernel -%MAKE% -fkernel.mak production +%MAKE% production if errorlevel 1 goto abort cd.. @@ -90,9 +139,14 @@ cd.. if exist build2.bat call build2 -goto end +@goto end :abort cd .. +set XERROR=1 :end -set MAKE= +:***** cleanup ****** +@set MAKE= +@set COMPILER= +@set XCPU= +@set XFAT= diff --git a/clean.bat b/clean.bat index db83b74..f7fe99a 100644 --- a/clean.bat +++ b/clean.bat @@ -5,6 +5,9 @@ rem batch file to clean everything rem $Id$ rem $Log$ +rem Revision 1.5 2001/11/04 19:47:37 bartoldeman +rem kernel 2025a changes: see history.txt +rem rem Revision 1.4 2001/03/22 04:13:30 bartoldeman rem Change LF to CR/LF in batch files. rem @@ -47,23 +50,26 @@ echo You must copy CONFIG.M to CONFIG.MAK and edit it to reflect your setup! goto end :start +@set COMPILER=tc2 call config.bat -cd lib -%MAKE% -flibm.mak clean +cd utils +%MAKE% clean + +cd ..\lib +%MAKE% clean cd ..\drivers -%MAKE% -fdevice.mak clean +%MAKE% clean cd ..\boot -%MAKE% -fboot.mak clean +%MAKE% clean cd ..\sys -%MAKE% -fbin2c.mak clean -%MAKE% -fsys.mak clean +%MAKE% clean cd ..\kernel -%MAKE% -fkernel.mak clean +%MAKE% clean cd ..\hdr del *.bak @@ -74,3 +80,4 @@ del *.bak :end set MAKE= +set COMPILER= diff --git a/clobber.bat b/clobber.bat index 7c436e9..96d3230 100644 --- a/clobber.bat +++ b/clobber.bat @@ -4,6 +4,9 @@ rem batch file to clobber everything rem $Id$ rem $Log$ +rem Revision 1.5 2001/11/04 19:47:37 bartoldeman +rem kernel 2025a changes: see history.txt +rem rem Revision 1.4 2001/03/22 04:13:30 bartoldeman rem Change LF to CR/LF in batch files. rem @@ -40,23 +43,27 @@ echo You must copy CONFIG.M to CONFIG.MAK and edit it to reflect your setup! goto end :start +set COMPILER=tc2 call config.bat -cd lib -%MAKE% -flibm.mak clobber +cd utils +%MAKE% clobber + +cd ..\lib +%MAKE% clobber cd ..\drivers -%MAKE% -fdevice.mak clobber +%MAKE% clobber cd ..\boot -%MAKE% -fboot.mak clobber +%MAKE% clobber cd ..\sys -%MAKE% -fbin2c.mak clobber -%MAKE% -fsys.mak clobber +%MAKE% clobber +%MAKE% clobber cd ..\kernel -%MAKE% -fkernel.mak clobber +%MAKE% clobber cd ..\hdr del *.bak @@ -68,3 +75,4 @@ del status.me :end set MAKE= +set COMPILER= \ No newline at end of file diff --git a/config.b b/config.b index 3f5bf68..d9a230d 100644 --- a/config.b +++ b/config.b @@ -1 +1,23 @@ +rem ********************************************************************** +rem - define your MAKE type here, pick one of them +rem ********************************************************************** + set MAKE=c:\tc201\make +rem set MAKE=c:\watcom\binw\wmake /ms +rem set MAKE=c:\msvc\bin\nmake /nologo + +rem ********************************************************************** +rem - define your COMPILER type here, pick one of them +rem ********************************************************************** + +set COMPILER=TC2 +rem set COMPILER=TURBOCPP +rem set COMPILER=TC3 +rem set COMPILER=BC5 +rem set COMPILER=MSCL8 + +rem warning: watcom can compile but the result does not work yet. +rem set COMPILER=WATCOM + +rem skip MS compiler in buildall. +rem set SKIPMS=yes diff --git a/config.m b/config.m index d08787b..8ecc114 100644 --- a/config.m +++ b/config.m @@ -6,11 +6,44 @@ # NOTICE! You must edit and rename this file to CONFIG.MAK! # ################################################################ -# These are generic definitions -RM=..\utils\rm -f +#********************************************************************* +# determine your compiler settings +# +# you have to +# search for NASM - and set the path for NASM +# search for ??_BASE - and set the path to your compiler +# search for LINK - and set the path to your linker +# +#********************************************************************* -# Give path to nasm here (or if it's in your path just uncomment the line). -#NASM=nasm +#********************************************************************** +#- define where to find NASM - remember - it should not be protected +# mode DJGPP version if you're using Windows NT/2k/XP to compile +#********************************************************************** + +NASM=c:\bin\nasm16 + +#********************************************************************** +#- where is the BASE dir of your compiler(s) ?? +#********************************************************************** + +WC_BASE=C:\watcom +MS_BASE=C:\msvc +TC2_BASE=C:\tc201 +TP1_BASE=C:\tcpp +TC3_BASE=C:\tc3 +BC5_BASE=C:\bc5 + +#********************************************************************** +#- select your default target: required CPU and what FAT system to support +#********************************************************************** + +#XCPU=86 +#XCPU=186 +#XCPU=386 + +#XFAT=16 +#XFAT=32 # Give extra Turbo C compiler flags here # such as -DDEBUG : extra DEBUG output @@ -18,50 +51,33 @@ RM=..\utils\rm -f # -DWITHFAT32 : compile with FAT32 support #ALLCFLAGS=-DDEBUG +!include "..\mkfiles\generic.mak" -# Use these for Turbo C 2.01 -#COMPILER=TC2 -#COMPILERPATH=c:\tc201 -#CC=$(COMPILERPATH)\tcc -#LINK=$(COMPILERPATH)\tlink -#LIBUTIL=$(COMPILERPATH)\tlib -#LIBPATH=$(COMPILERPATH)\lib -#CLIB=$(COMPILERPATH)\lib\cs.lib -#INCLUDEPATH=$(COMPILERPATH)\include -#MATH_EXTRACT=*LDIV *LLSH *LURSH *LXMUL *LRSH *SPUSH *SCOPY -#MATH_INSERT=+LDIV +LLSH +LURSH +LXMUL +LRSH +SPUSH +SCOPY +#********************************************************************** +#- which linker to use: WATCOM wlink is not suitable for linking +#********************************************************************** +# Turbo Link +#LINK=$(TC2_BASE)\tlink /m/c +LINK=d:\util\tlink /m/c +# Microsoft Link +#LINK=$(COMPILERBIN)\link /ONERROR:NOEXE /ma +# VAL: you need VAL95, NOT the one in LANG1.ZIP (yet); +# look at the software list on www.freedos.org. +# VAL complains about MODEND record missing for Watcom compiled objects! +# LINK=c:\bin\val /MP /NCI -# Use these for Turbo C 3.0 -#COMPILER=TC3 -#COMPILERPATH=c:\tc -#CC=$(COMPILERPATH)\bin\tcc -#LINK=$(COMPILERPATH)\bin\tlink -#LIBUTIL=$(COMPILERPATH)\bin\tlib -#LIBPATH=$(COMPILERPATH)\lib -#CLIB=$(COMPILERPATH)\lib\cs.lib -#INCLUDEPATH=$(COMPILERPATH)\include -#MATH_EXTRACT=*H_LDIV *H_LLSH *H_LURSH *N_LXMUL *F_LXMUL *H_LRSH *H_SPUSH *N_SCOPY *F_SCOPY -#MATH_INSERT=+H_LDIV +H_LLSH +H_LURSH +N_LXMUL +F_LXMUL +H_LRSH +H_SPUSH +N_SCOPY +F_SCOPY - - -# Use these for Borland C++ -#COMPILER=BC5 -#COMPILERPATH=c:\bc5 -#CC=$(COMPILERPATH)\bin\tcc -#LINK=$(COMPILERPATH)\bin\tlink -#LIBUTIL=$(COMPILERPATH)\bin\tlib -#LIBPATH=$(COMPILERPATH)\lib -#CLIB=$(COMPILERPATH)\lib\cs.lib -#INCLUDEPATH=$(COMPILERPATH)\include -#MATH_EXTRACT=*H_LDIV *H_LLSH *H_LURSH *N_LXMUL *F_LXMUL *H_LRSH *H_SPUSH *N_SCOPY *F_SCOPY -#MATH_INSERT=+H_LDIV +H_LLSH +H_LURSH +N_LXMUL +F_LXMUL +H_LRSH +H_SPUSH +N_SCOPY +F_SCOPY - +# use a ; to end the LINK command line? +LINKTERM=; + # # $Id$ # # $Log$ +# Revision 1.9 2001/11/04 19:47:37 bartoldeman +# kernel 2025a changes: see history.txt +# # Revision 1.8 2001/09/23 20:39:43 bartoldeman # FAT32 support, misc fixes, INT2F/AH=12 support, drive B: handling # diff --git a/docs/build.txt b/docs/build.txt index 4421bc5..2e492f4 100644 --- a/docs/build.txt +++ b/docs/build.txt @@ -23,11 +23,17 @@ you put the tools. *TE******* Make sure to use the NASMR version, as the DosExtender version _seems_ to produce wrong code. the tested version is NASM98R, 06/04/99, 202.606 bytes. +*Bart***** This is probably only true for Windows NT/2k/XP; In that + case you could use the Win32 version anyway. +Look at +ftp://ftp.kernel.org/pub/software/devel/nasm +or a mirror of ftp.kernel.org. This program will now compile with Turbo C 2.01 (now freely available!), Turbo C 3.0, Borland C 4.51 & 5.01. It should work with -other Borland compilers as well. +other Borland compilers and Microsoft C as well. Watcom C can compile +it but the result does not work yet. If you feel hardy, read on to understand the directory structure. A more complete description of the build environment is contained in a @@ -70,6 +76,9 @@ component. Study the makefile to better understand this. $Id$ $Log$ +Revision 1.5 2001/11/04 19:47:39 bartoldeman +kernel 2025a changes: see history.txt + Revision 1.4 2001/07/09 22:19:33 bartoldeman LBA/FCB/FAT/SYS/Ctrl-C/ioctl fixes + memory savings diff --git a/docs/history.txt b/docs/history.txt index 74e1634..50407d2 100644 --- a/docs/history.txt +++ b/docs/history.txt @@ -1,3 +1,50 @@ +2001 Nov xx - Build 2025a +-------- Bart Oldeman (bart.oldeman@bristol.ac.uk) ++ Changes tom + * config.sys processing: placing ? on the left side of '=' like + ?device= or device ?= + asks for this single line + fill the available HMA with buffers + * added kernel configuration options to sys.com, small area at 60:xx + * readblock optimized to read as many data as possible in one + int13 request - great speedups for large reads + * some more SDA variables need to be updated for the network + redirector (the sft index) + * reduce stack usage in task.c, fattab.c, ioctl.c, execrh.asm, inthndlr.c + * protect high part of 32-bit registers (stacks.inc) + * moved copyright messages to init data to save a bit of memory + * added relocinf, patchobj, sorted + some more output of exeflat + * UMB fixes ++ Fixes Bart, Victor, Tom + * more FAT32 fixes - to work with device drivers + * fixed overflow problem with more than 2048 directory entries + * various space saving changes, dir_init_fnode ++ Changes Bart, Tom + * many makefile changes to enable compilation with different + compilers (MS, Watcom, Borland). Watcom compiles but the result + does not run yet. ++ Changes Bart + * support for IOCTL AX=440D, CL=40,41,42,61,62 for + read/write/format track - this enables R. Nordier format to work + * default floppy type depends on the drive + * rewrote many parts of int2f.asm to have a cleaner remote_xxx + interface with less code and stack usage. + * limit for int21/ah=36 is FFF6 total/free sectors + * made the rtc clock reading code a bit more robust - assumes + there is no rtc if the returned date is zero + * removed non-necessary code in dosnames.c because we're always + dealing with a TRUENAME there + * added zero extending of files, but removed it (unless you force + it) since MSDOS doesn't zero-extend files either + * wrote a source for exeflat, removed all binaries from the source + * added more INT2F/AH=12 functions to solve some MSCDEX issues + * changed BAD sector handling : only ....FF7 is recognized as BAD, + but FORMAT information from initdisk will only give ....FEF as + the largest cluster (for safety), so ....FF0-....FF6 are not used + for newly formatted disks (here .... is either nothing, F, or + FFFF, FAT12/FAT16/FAT32). + * more fatfs/fatdir clean-ups - now unnecessary fields dfull, + dremote and dsize removed from fnodes. 2001 Sep 24 - Build 2025 -------- Bart Oldeman (bart.oldeman@bristol.ac.uk) + Fixes Victor diff --git a/drivers/floppy.asm b/drivers/floppy.asm index 876c77a..1fb4de4 100644 --- a/drivers/floppy.asm +++ b/drivers/floppy.asm @@ -30,6 +30,9 @@ ; $Id$ ; ; $Log$ +; Revision 1.9 2001/11/04 19:47:39 bartoldeman +; kernel 2025a changes: see history.txt +; ; Revision 1.8 2001/09/23 20:39:44 bartoldeman ; FAT32 support, misc fixes, INT2F/AH=12 support, drive B: handling ; @@ -223,6 +226,18 @@ _fl_rd_status: ret +; +; Format Sectors +; +; COUNT fl_format(WORD drive, WORD head, WORD track, WORD sector, WORD count, BYTE FAR *buffer); +; +; Formats one or more tracks, sector should be 0. +; +; Returns 0 if successful, error code otherwise. + global _fl_format +_fl_format: + mov ah, 5 + jmp short fl_common ; ; Read Sectors ; @@ -294,15 +309,7 @@ fl_error: ret - %if 0 - global _fl_format -_fl_format: - - xor ax,ax - ret - - ; ; ; Get number of disks @@ -463,3 +470,54 @@ global _fl_readkey _fl_readkey: xor ah, ah int 16h ret + +global _fl_setdisktype +_fl_setdisktype: + push bp + mov bp, sp + mov dl,[bp+4] ; drive number + mov al,[bp+6] ; disk type + mov ah,17h + int 13h + mov al,ah + xor ah,ah + pop bp + ret + +global _fl_setmediatype +_fl_setmediatype: + push bp + mov bp, sp + push di + + mov dl,[bp+4] ; drive number + mov bx,[bp+6] ; number of tracks + dec bx ; should be highest track + mov ch,bl ; low 8 bits of cyl number + + xor bl,bl ; extract bits 8+9 to cl + shr bx,1 + shr bx,1 + + mov cl,[bp+8] ; sectors/track + and cl,03fh ; mask to sector field bits 5-0 + or cl,bl ; or in bits 7-6 + + mov ah,18h + int 13h + mov al,ah + mov ah,0 + jc skipint1e + mov bx,es + xor dx,dx + mov es,dx + cli + mov [es:0x1e*4 ], di + mov [es:0x1e*4+2], bx ; set int 0x1e table to es:di (bx:di) + sti +skipint1e: + pop di + pop bp + ret + + diff --git a/drivers/rdatclk.asm b/drivers/rdatclk.asm index df4fdee..7339158 100644 --- a/drivers/rdatclk.asm +++ b/drivers/rdatclk.asm @@ -73,14 +73,27 @@ segment HMA_TEXT ; global _ReadATClock _ReadATClock: - mov ah,2 + push bp + mov bp, sp + xor cx, cx ; cx=dx=0 check if present + xor dx, dx ; if it returns non-zero + clc ; necessary according to RBIL + mov ah,4 int 1ah - jnc @RdAT1140 - sbb ax,ax + jc @RdATerror + + or cx, cx + jnz @RdAT1140 + or dx, dx + jnz @RdAT1140 +@RdATerror: mov ax, 1 + pop bp ret @RdAT1140: - push bp - mov bp,sp + clc + mov ah, 2 + int 1ah + jc @RdATerror ; bcdSeconds = 10 ; bcdMinutes = 8 ; bcdHours = 6 @@ -91,11 +104,13 @@ _ReadATClock: mov byte [bx],cl ;Minutes mov bx,word [bp+10] ;bcdSeconds mov byte [bx],dh ;Seconds + clc mov ah,4 int 1ah + jc @RdATerror mov bx,word [bp+4] ;bcdDays mov word [bx],dx ;Days mov word [bx+2],cx sub ax,ax - pop bp + pop bp ret diff --git a/fdkernel.lsm b/fdkernel.lsm index cd187e8..839365d 100644 --- a/fdkernel.lsm +++ b/fdkernel.lsm @@ -1,7 +1,7 @@ Begin3 Title: The FreeDOS Kernel -Version: 1.1.24 -Entered-date: 2 Jun 2001 +Version: 1.1.25 +Entered-date: 26 Sep 2001 Description: The FreeDOS Kernel. Keywords: kernel freedos dos msdos Author: (developers) diff --git a/hdr/cds.h b/hdr/cds.h index 27ca283..dba497e 100644 --- a/hdr/cds.h +++ b/hdr/cds.h @@ -34,6 +34,9 @@ static BYTE *Cds_hRcsId = "$Id$"; /* * $Log$ + * Revision 1.5 2001/11/04 19:47:39 bartoldeman + * kernel 2025a changes: see history.txt + * * Revision 1.4 2001/04/15 03:21:50 bartoldeman * See history.txt for the list of fixes. * @@ -87,14 +90,14 @@ struct cds _cdsRedirRec; struct { - WORD _cdsStrtClst; + UWORD _cdsStrtClst; UWORD _cdsParam; } _cdsRedir; } _cdsUnion; - WORD cdsStoreUData; + UWORD cdsStoreUData; WORD cdsJoinOffset; diff --git a/hdr/dcb.h b/hdr/dcb.h index 3061a22..966ec4b 100644 --- a/hdr/dcb.h +++ b/hdr/dcb.h @@ -36,6 +36,9 @@ static BYTE *clock_hRcsId = "$Id$"; /* * $Log$ + * Revision 1.6 2001/11/04 19:47:39 bartoldeman + * kernel 2025a changes: see history.txt + * * Revision 1.5 2001/09/23 20:39:44 bartoldeman * FAT32 support, misc fixes, INT2F/AH=12 support, drive B: handling * @@ -101,18 +104,9 @@ struct dpb UWORD dpb_fatstrt; /* FAT start sector */ UBYTE dpb_fats; /* # of FAT copies */ UWORD dpb_dirents; /* # of dir entries */ -#ifdef WITHFAT32 - UWORD dpb_wdata; /* start of data area */ - UWORD dpb_wsize; /* # of clusters+1 on media */ - UWORD dpb_wfatsize; /* # of sectors / FAT */ -#else UWORD dpb_data; /* start of data area */ UWORD dpb_size; /* # of clusters+1 on media */ UWORD dpb_fatsize; /* # of sectors / FAT */ -#define dpb_wdata dpb_data -#define dpb_wsize dpb_size -#define dpb_wfatsize dpb_fatsize -#endif UWORD dpb_dirstrt; /* start sec. of root dir */ struct dhdr FAR * /* pointer to device header */ dpb_device; @@ -120,36 +114,40 @@ struct dpb BYTE dpb_flags; /* -1 = force MEDIA CHK */ struct dpb FAR * /* next dpb in chain */ dpb_next; /* -1 = end */ -#ifdef WITHFAT32 - UWORD dpb_wcluster; /* cluster # of first free */ + UWORD dpb_cluster; /* cluster # of first free */ /* -1 if not known */ - ULONG dpb_nfreeclst; /* number of free clusters */ +#ifndef WITHFAT32 + UWORD dpb_nfreeclst; /* number of free clusters */ /* -1 if not known */ +#else + union + { + struct + { + UWORD dpb_nfreeclst_lo; + UWORD dpb_nfreeclst_hi; + } dpb_nfreeclst_st; + ULONG _dpb_xnfreeclst; /* number of free clusters */ + /* -1 if not known */ + } dpb_nfreeclst_un; + #define dpb_nfreeclst dpb_nfreeclst_un.dpb_nfreeclst_st.dpb_nfreeclst_lo + #define dpb_xnfreeclst dpb_nfreeclst_un._dpb_xnfreeclst + UWORD dpb_xflags; /* extended flags, see bpb */ UWORD dpb_xfsinfosec; /* FS info sector number, */ /* 0xFFFF if unknown */ UWORD dpb_xbackupsec; /* backup boot sector number */ /* 0xFFFF if unknown */ - ULONG dpb_data; - ULONG dpb_size; /* # of clusters+1 on media */ - ULONG dpb_fatsize; /* # of sectors / FAT */ + ULONG dpb_xdata; + ULONG dpb_xsize; /* # of clusters+1 on media */ + ULONG dpb_xfatsize; /* # of sectors / FAT */ ULONG dpb_xrootclst; /* starting cluster of root dir */ - ULONG dpb_cluster; /* cluster # of first free */ + ULONG dpb_xcluster; /* cluster # of first free */ /* -1 if not known */ -#else - UWORD dpb_cluster; /* cluster # of first free */ - /* -1 if not known */ -#define dpb_wcluster dpb_cluster - UWORD dpb_nfreeclst; /* number of free clusters */ - /* -1 if not known */ -#endif +#endif }; #define UNKNCLUSTER 0x0000 /* see RBIL INT 21/AH=52 entry */ -#ifdef WITHFAT32 -#define UNKNCLSTFREE 0xffffffffl /* unknown for DOS */ -#else +#define XUNKNCLSTFREE 0xffffffffl /* unknown for DOS */ #define UNKNCLSTFREE 0xffff /* unknown for DOS */ -#endif -#define UNKNCLSTFREE16 0xffff /* unknown for DOS */ diff --git a/hdr/device.h b/hdr/device.h index f3f9eaf..5a499f6 100644 --- a/hdr/device.h +++ b/hdr/device.h @@ -35,6 +35,9 @@ static BYTE *device_hRcsId = "$Id$"; /* * $Log$ + * Revision 1.9 2001/11/04 19:47:39 bartoldeman + * kernel 2025a changes: see history.txt + * * Revision 1.8 2001/09/23 20:39:44 bartoldeman * FAT32 support, misc fixes, INT2F/AH=12 support, drive B: handling * @@ -321,7 +324,7 @@ typedef struct ddtstruct { UWORD ddt_part; /* partition (FFFFh = primary, 0001h = extended) always 0001h for DOS 5+ */ - UWORD ddt_absyl; /* absolute cylinder number of partition's + UWORD ddt_abscyl; /* absolute cylinder number of partition's start on physical drive (FFFFh if primary partition in DOS 4.x)*/ } ddt_hd; @@ -361,6 +364,24 @@ struct gblkio UWORD gbio_nsecs; }; +struct gblkfv /* for format / verify track */ +{ + UBYTE gbfv_spcfunbit; + UWORD gbfv_head; + UWORD gbfv_cyl; + UWORD gbfv_ntracks; +}; + +struct gblkrw /* for read / write track */ +{ + UBYTE gbrw_spcfunbit; + UWORD gbrw_head; + UWORD gbrw_cyl; + UWORD gbrw_sector; + UWORD gbrw_nsecs; + UBYTE FAR * gbrw_buffer; +}; + struct Gioc_media { WORD ioc_level; diff --git a/hdr/dirmatch.h b/hdr/dirmatch.h index 6956f20..52c2567 100644 --- a/hdr/dirmatch.h +++ b/hdr/dirmatch.h @@ -36,6 +36,9 @@ static BYTE *dirmatch_hRcsId = "$Id$"; /* * $Log$ + * Revision 1.7 2001/11/04 19:47:39 bartoldeman + * kernel 2025a changes: see history.txt + * * Revision 1.6 2001/09/23 20:39:44 bartoldeman * FAT32 support, misc fixes, INT2F/AH=12 support, drive B: handling * @@ -120,10 +123,8 @@ typedef struct f_dnew:1; BITS /* fnode is assigned to dir */ f_ddir:1; - BITS /* directory is full */ - f_dfull:1; BITS /* filler to avoid a bad bug (feature?) in */ - f_filler:11; /* TC 2.01 */ + f_filler:12; /* TC 2.01 */ } dm_flags; /* file flags */ diff --git a/hdr/fat.h b/hdr/fat.h index 7259deb..fb1736e 100644 --- a/hdr/fat.h +++ b/hdr/fat.h @@ -36,6 +36,9 @@ static BYTE *fat_hRcsId = "$Id$"; /* * $Log$ + * Revision 1.9 2001/11/04 19:47:39 bartoldeman + * kernel 2025a changes: see history.txt + * * Revision 1.8 2001/09/23 20:39:44 bartoldeman * FAT32 support, misc fixes, INT2F/AH=12 support, drive B: handling * @@ -121,10 +124,6 @@ static BYTE *fat_hRcsId = "$Id$"; * (ULONG) cluster_size \ + (ULONG) data_start)) -#define clus2phys(cl_no,cl_size,d_st) ((ULONG) (((ULONG) cl_no - 2L) \ - * (ULONG) cl_size \ - + (ULONG) d_st)) - /* Test for 16 bit or 12 bit FAT */ #define SIZEOF_CLST16 2 #define SIZEOF_CLST32 4 @@ -135,9 +134,13 @@ static BYTE *fat_hRcsId = "$Id$"; /* int ISFAT32(struct dpb FAR *dpbp);*/ #define ISFAT32(x) _ISFAT32(x) +/* #define _ISFAT32(dpbp) (((dpbp)->dpb_size)>FAT_MAGIC16 && ((dpbp)->dpb_size)<=FAT_MAGIC32 ) +*/ +#define _ISFAT32(dpbp) (((dpbp)->dpb_fatsize)==0) #define ISFAT16(dpbp) (((dpbp)->dpb_size)>FAT_MAGIC && ((dpbp)->dpb_size)<=FAT_MAGIC16 ) -#define ISFAT12(dpbp) (((dpbp)->dpb_size)<=FAT_MAGIC) +#define ISFAT12(dpbp) ((((dpbp)->dpb_size)-1)b_next) + { + if (blknolow <= getblkno(bp) && + getblkno(bp) <= blknohigh && + (bp->b_flag & BFR_VALID) && (bp->b_unit == dsk)) + { + flush1(bp); + } + } + + return FALSE; +} + + void dumpBufferCache(void) { struct buffer FAR *bp; @@ -535,7 +559,7 @@ BOOL flush(void) bp = bp->b_next; } - int2f_Remote_call(REM_FLUSHALL, 0, 0, 0, 0, 0, 0); + remote_flushall(); return (ok); } diff --git a/kernel/config.c b/kernel/config.c index 751c151..243beb0 100644 --- a/kernel/config.c +++ b/kernel/config.c @@ -89,6 +89,9 @@ static BYTE *RcsId = "$Id$"; /* * $Log$ + * Revision 1.29 2001/11/04 19:47:39 bartoldeman + * kernel 2025a changes: see history.txt + * * Revision 1.28 2001/09/23 20:39:44 bartoldeman * FAT32 support, misc fixes, INT2F/AH=12 support, drive B: handling * @@ -293,8 +296,11 @@ STATIC COUNT nPass = 0; STATIC BYTE szLine[256] = {0}; STATIC BYTE szBuf[256] = {0}; -int singleStep = FALSE; -int SkipAllConfig = FALSE; +BYTE singleStep = FALSE; /* F8 processing */ +BYTE SkipAllConfig = FALSE; /* F5 processing */ +BYTE askThisSingleCommand = FALSE; /* ?device= device?= */ + + INIT VOID zumcb_init(UCOUNT seg, UWORD size); INIT VOID mumcb_init(UCOUNT seg, UWORD size); @@ -817,7 +823,7 @@ ULONG GetBiosTime(VOID) { return *(ULONG FAR *)(MK_FP(0x40,0x6c)); } -GetBiosKey(int timeout) +UWORD GetBiosKey(int timeout) { iregs r; @@ -854,11 +860,15 @@ INIT BOOL SkipLine(char *pLine) if (!initialized) { - initialized = TRUE; + initialized = TRUE; - printf("Press F8 to trace or F5 to skip CONFIG.SYS/AUTOEXEC.BAT"); + if (InitKernelConfig.SkipConfigSeconds < 0) + return FALSE; + + if (InitKernelConfig.SkipConfigSeconds > 0) + printf("Press F8 to trace or F5 to skip CONFIG.SYS/AUTOEXEC.BAT"); - key = GetBiosKey(2); /* wait 2 seconds */ + key = GetBiosKey(InitKernelConfig.SkipConfigSeconds); /* wait 2 seconds */ if (key == 0x3f00) /* F5 */ { @@ -874,11 +884,13 @@ INIT BOOL SkipLine(char *pLine) if (SkipAllConfig) printf("Skipping CONFIG.SYS/AUTOEXEC.BAT\n"); } + + if (SkipAllConfig) return TRUE; - if (!singleStep) + if (!askThisSingleCommand && !singleStep) return FALSE; printf("%s[Y,N]?", pLine); @@ -923,7 +935,7 @@ INIT BYTE *GetNumArg(BYTE * pLine, COUNT * pnArg) { /* look for NUMBER */ pLine = skipwh(pLine); - if (!isnum(pLine)) + if (!isnum(pLine) && *pLine != '-') { CfgFailure(pLine); return (BYTE *) 0; @@ -949,7 +961,7 @@ INIT void Config_Buffers(BYTE * pLine) return; /* Got the value, assign either default or new value */ - Config.cfgBuffers = max(Config.cfgBuffers, nBuffers); + Config.cfgBuffers = (nBuffers < 0 ? nBuffers : max(Config.cfgBuffers, nBuffers)); } INIT STATIC VOID sysScreenMode(BYTE * pLine) @@ -1284,8 +1296,12 @@ INIT BOOL LoadDevice(BYTE * pLine, COUNT top, COUNT mode) #endif - if (init_DosExec(3, &eb, szBuf) == SUCCESS) - { + if ((result = init_DosExec(3, &eb, szBuf)) != SUCCESS) + { + CfgFailure(pLine); + return result; + } + strcpy(szBuf, pLine); /* TE this fixes the loading of devices drivers with @@ -1321,9 +1337,7 @@ INIT BOOL LoadDevice(BYTE * pLine, COUNT top, COUNT mode) HMAState = HMA_DONE; config_init_buffers( Config.cfgBuffers); } - } - else - CfgFailure(pLine); + return result; } @@ -1402,6 +1416,8 @@ INIT BYTE * INIT BYTE * scan(BYTE * s, BYTE * d) { + askThisSingleCommand = FALSE; + s = skipwh(s); while (*s && !(*s == 0x0d @@ -1409,11 +1425,20 @@ INIT BYTE * || *s == ' ' || *s == '\t' || *s == '=')) - *d++ = *s++; + { + if (*s == '?') + { + askThisSingleCommand = TRUE; + s++; + } + else + *d++ = *s++; + } *d = '\0'; return s; } +/* INIT BYTE *scan_seperator(BYTE * s, BYTE * d) { s = skipwh(s); @@ -1422,6 +1447,7 @@ INIT BYTE *scan_seperator(BYTE * s, BYTE * d) *d = '\0'; return s; } +*/ INIT BOOL isnum(BYTE * pLine) { @@ -1432,8 +1458,15 @@ INIT BOOL isnum(BYTE * pLine) INIT BYTE *GetNumber(REG BYTE * pszString, REG COUNT * pnNum) { BYTE Base = 10; + BOOL Sign = FALSE; *pnNum = 0; + if (*pszString == '-') + { + pszString++; + Sign = TRUE; + } + while (isnum(pszString) || toupper(*pszString) == 'X') { if (toupper(*pszString) == 'X') @@ -1444,6 +1477,8 @@ INIT BYTE *GetNumber(REG BYTE * pszString, REG COUNT * pnNum) else *pnNum = *pnNum * Base + (*pszString++ - '0'); } + if (Sign) + *pnNum = -*pnNum; return pszString; } @@ -1577,6 +1612,13 @@ VOID config_init_buffers(COUNT anzBuffers) struct buffer FAR *pbuffer; int HMAcount = 0; BYTE FAR *tmplpBase = lpBase; + BOOL fillhma = TRUE; + + if (anzBuffers < 0) + { + anzBuffers = -anzBuffers; + fillhma = FALSE; + } anzBuffers = max(anzBuffers,6); if (anzBuffers > 99) @@ -1614,6 +1656,7 @@ VOID config_init_buffers(COUNT anzBuffers) /* now, we can have quite some buffers in HMA -- up to 37 for KE38616. so we fill the HMA with buffers + but not if the BUFFERS count is negative ;-) */ if (i < (anzBuffers - 1)) @@ -1628,6 +1671,8 @@ VOID config_init_buffers(COUNT anzBuffers) pbuffer->b_next = ConfigAlloc(sizeof (struct buffer)); } } + else if (fillhma) + pbuffer->b_next = HMAalloc(sizeof (struct buffer)); if (pbuffer->b_next == NULL) break; diff --git a/kernel/dosfns.c b/kernel/dosfns.c index b51c030..e96fb90 100644 --- a/kernel/dosfns.c +++ b/kernel/dosfns.c @@ -37,6 +37,9 @@ static BYTE *dosfnsRcsId = "$Id$"; * /// Added SHARE support. 2000/09/04 Ron Cemer * * $Log$ + * Revision 1.29 2001/11/04 19:47:39 bartoldeman + * kernel 2025a changes: see history.txt + * * Revision 1.28 2001/09/26 01:06:05 bartoldeman * Change dir gives error for path too long, 2025 without test. * @@ -212,7 +215,7 @@ f_node_ptr xlt_fd(COUNT); /* /// Added for SHARE. - Ron Cemer */ -int share_installed = 0; +BYTE share_installed = 0; /* DOS calls this to see if it's okay to open the file. Returns a file_table entry number to use (>= 0) if okay @@ -313,9 +316,13 @@ sft FAR *idx_to_sft(COUNT SftIndex) for (sp = sfthead; sp != (sfttbl FAR *) - 1; sp = sp->sftt_next) { - if (SftIndex < sp->sftt_count) + if (SftIndex < sp->sftt_count) + { + lpCurSft = (sft FAR *) & (sp->sftt_table[SftIndex]); + /* finally, point to the right entry */ - return (sft FAR *) & (sp->sftt_table[SftIndex]); + return lpCurSft; + } else SftIndex -= sp->sftt_count; } @@ -346,14 +353,13 @@ sft FAR *get_sft(UCOUNT hndl) * binary reads, while for 0x40 the type of read (binary/text) depends on what * the SFT says. -- ror4 */ -UCOUNT GenericRead(COUNT hndl, UCOUNT n, BYTE FAR * bp, COUNT FAR * err, +UCOUNT GenericReadSft(sft FAR *s, UCOUNT n, BYTE FAR * bp, COUNT FAR * err, BOOL force_binary) { - sft FAR *s; UCOUNT ReadCount; /* Get the SFT block that contains the SFT */ - if ((s = get_sft(hndl)) == (sft FAR *) - 1) + if (s == (sft FAR *) - 1) { *err = DE_INVLDHNDL; return 0; @@ -372,8 +378,17 @@ UCOUNT GenericRead(COUNT hndl, UCOUNT n, BYTE FAR * bp, COUNT FAR * err, */ if (s->sft_flags & SFT_FSHARED) { - ReadCount = Remote_RW(REM_READ, n, bp, s, err); - return *err == SUCCESS ? ReadCount : 0; + COUNT rc; + BYTE FAR *save_dta; + + save_dta = dta; + lpCurSft = s; + current_filepos = s->sft_posit; /* needed for MSCDEX */ + dta = bp; + ReadCount = remote_read(s, n, &rc); + dta = save_dta; + *err = rc; + return rc == SUCCESS ? ReadCount : 0; } /* Do a device read if device */ if (s->sft_flags & SFT_FDEVICE) @@ -448,16 +463,8 @@ UCOUNT GenericRead(COUNT hndl, UCOUNT n, BYTE FAR * bp, COUNT FAR * err, /* /// End of additions for SHARE - Ron Cemer */ ReadCount = readblock(s->sft_status, bp, n, &rc); - if (rc != SUCCESS) - { - *err = rc; - return 0; - } - else - { - *err = SUCCESS; - return ReadCount; - } + *err = rc; + return (rc == SUCCESS ? ReadCount : 0); } *err = SUCCESS; return 0; @@ -470,13 +477,12 @@ UCOUNT DosRead(COUNT hndl, UCOUNT n, BYTE FAR * bp, COUNT FAR * err) } #endif -UCOUNT DosWrite(COUNT hndl, UCOUNT n, BYTE FAR * bp, COUNT FAR * err) +UCOUNT DosWriteSft(sft FAR *s, UCOUNT n, BYTE FAR * bp, COUNT FAR * err) { - sft FAR *s; UCOUNT WriteCount; /* Get the SFT block that contains the SFT */ - if ((s = get_sft(hndl)) == (sft FAR *) - 1) + if (s == (sft FAR *) - 1) { *err = DE_INVLDHNDL; return 0; @@ -493,8 +499,17 @@ UCOUNT DosWrite(COUNT hndl, UCOUNT n, BYTE FAR * bp, COUNT FAR * err) if (s->sft_flags & SFT_FSHARED) { - WriteCount = Remote_RW(REM_WRITE, n, bp, s, err); - return *err == SUCCESS ? WriteCount : 0; + COUNT rc; + BYTE FAR *save_dta; + + save_dta = dta; + lpCurSft = s; + current_filepos = s->sft_posit; /* needed for MSCDEX */ + dta = bp; + WriteCount = remote_write(s, n, &rc); + dta = save_dta; + *err = rc; + return rc == SUCCESS ? WriteCount : 0; } /* Do a device write if device */ @@ -621,6 +636,7 @@ UCOUNT DosWrite(COUNT hndl, UCOUNT n, BYTE FAR * bp, COUNT FAR * err) /* /// End of additions for SHARE - Ron Cemer */ WriteCount = writeblock(s->sft_status, bp, n, &rc); + s->sft_size = dos_getcufsize(s->sft_status); /* if (rc < SUCCESS) */ if (rc == DE_ACCESS || /* -5 Access denied */ rc == DE_INVLDHNDL ) /* -6 Invalid handle */ @@ -640,13 +656,11 @@ UCOUNT DosWrite(COUNT hndl, UCOUNT n, BYTE FAR * bp, COUNT FAR * err) COUNT SftSeek(sft FAR *s, LONG new_pos, COUNT mode) { - ULONG data; - /* Test for invalid mode */ if (mode < 0 || mode > 2) return DE_INVLDFUNC; - lpCurSft = (sfttbl FAR *) s; + lpCurSft = s; if (s->sft_flags & SFT_FSHARED) { @@ -664,8 +678,7 @@ COUNT SftSeek(sft FAR *s, LONG new_pos, COUNT mode) */ if ((s->sft_mode & SFT_MDENYREAD) || (s->sft_mode & SFT_MDENYNONE)) { - int2f_Remote_call(REM_LSEEK, 0, (UWORD) FP_SEG(new_pos), (UWORD) FP_OFF(new_pos), (VOID FAR *) s, 0, (VOID FAR *)&data); - s->sft_posit = data; + s->sft_posit = remote_lseek(s, new_pos); return SUCCESS; } else @@ -743,11 +756,18 @@ sft FAR *get_free_sft(COUNT *sft_idx) REG COUNT i = sp->sftt_count; sft FAR *sfti = sp->sftt_table; - for(sys_idx += i; i >= 1 ; sfti++, i--) + for(; --i >= 0 ; sys_idx++, sfti++) { if (sfti->sft_count == 0) { - *sft_idx = sys_idx - i; + *sft_idx = sys_idx; + + /* MS NET uses this on open/creat TE*/ + { + extern WORD current_sft_idx; + current_sft_idx = sys_idx; + } + return sfti; } } @@ -801,7 +821,8 @@ COUNT DosCreatSft(BYTE * fname, COUNT attrib) COUNT drive; /* NEVER EVER allow directories to be created */ - if (attrib & 0xff & ~(D_RDONLY|D_HIDDEN|D_SYSTEM|D_ARCHIVE)) + attrib &= 0xff; + if (attrib & ~(D_RDONLY|D_HIDDEN|D_SYSTEM|D_ARCHIVE)) { return DE_ACCESS; } @@ -815,7 +836,7 @@ COUNT DosCreatSft(BYTE * fname, COUNT attrib) sftp->sft_shroff = -1; /* /// Added for SHARE - Ron Cemer */ sftp->sft_psp = cu_psp; sftp->sft_mode = SFT_MRDWR; - sftp->sft_attrib = attrib & 0xff; + sftp->sft_attrib = attrib; sftp->sft_psp = cu_psp; /* check for a device */ @@ -831,9 +852,8 @@ COUNT DosCreatSft(BYTE * fname, COUNT attrib) } if (current_ldt->cdsFlags & CDSNETWDRV) { - lpCurSft = (sfttbl FAR *)sftp; - sftp->sft_mode = attrib; - result = -int2f_Remote_call(REM_CREATE, 0, 0, 0, (VOID FAR *) sftp, 0, MK_FP(0, attrib)); + lpCurSft = sftp; + result = remote_creat(sftp, attrib); if (result == SUCCESS) { sftp->sft_count += 1; return sft_idx; @@ -1019,8 +1039,9 @@ COUNT DosOpenSft(BYTE * fname, COUNT mode) } if (current_ldt->cdsFlags & CDSNETWDRV) { - lpCurSft = (sfttbl FAR *)sftp; - result = -int2f_Remote_call(REM_OPEN, 0, 0, 0, (VOID FAR *) sftp, 0, MK_FP(0, mode)); + lpCurSft = sftp; + result = remote_open(sftp, mode); + /* printf("open SFT %d = %p\n",sft_idx,sftp); */ if (result == SUCCESS) { sftp->sft_count += 1; return sft_idx; @@ -1058,6 +1079,7 @@ COUNT DosOpenSft(BYTE * fname, COUNT mode) if ((sftp->sft_attrib & (D_DIR | D_VOLID)) || ((sftp->sft_attrib & D_RDONLY) && (mode != O_RDONLY))) { + dos_close(sftp->sft_status); return DE_ACCESS; } @@ -1106,40 +1128,43 @@ COUNT DosOpen(BYTE FAR * fname, COUNT mode) COUNT DosCloseSft(WORD sft_idx) { - sft FAR *s = idx_to_sft(sft_idx); + sft FAR *sftp = idx_to_sft(sft_idx); - if (s == (sft FAR *) - 1) + if (sftp == (sft FAR *) - 1) return DE_INVLDHNDL; /* If this is not opened another error */ /* The second condition is a sanity check and necessary for FcbCloseAll */ - if (s->sft_count == 0 || (s->sft_count == 1 && s->sft_psp != cu_psp)) + if (sftp->sft_count == 0 || (sftp->sft_count == 1 && sftp->sft_psp != cu_psp)) return DE_ACCESS; - lpCurSft = (sfttbl FAR *) s; + lpCurSft = sftp; /* remote sub sft_count. */ - if (s->sft_flags & SFT_FSHARED) - return -int2f_Remote_call(REM_CLOSE, 0, 0, 0, (VOID FAR *) s, 0, 0); + if (sftp->sft_flags & SFT_FSHARED) + { + /* printf("closing SFT %d = %p\n",sft_idx,sftp); */ + return remote_close(sftp); + } /* now just drop the count if a device, else */ /* call file system handler */ - s->sft_count -= 1; - if (s->sft_flags & SFT_FDEVICE) + sftp->sft_count -= 1; + if (sftp->sft_flags & SFT_FDEVICE) return SUCCESS; else { - if (s->sft_count > 0) + if (sftp->sft_count > 0) return SUCCESS; else { /* /// Added for SHARE *** CURLY BRACES ADDED ALSO!!! ***. - Ron Cemer */ if (IsShareInstalled()) { - if (s->sft_shroff >= 0) share_close_file(s->sft_shroff); - s->sft_shroff = -1; + if (sftp->sft_shroff >= 0) share_close_file(sftp->sft_shroff); + sftp->sft_shroff = -1; } /* /// End of additions for SHARE. - Ron Cemer */ - return dos_close(s->sft_status); + return dos_close(sftp->sft_status); } } } @@ -1161,10 +1186,6 @@ VOID DosGetFree(UBYTE drive, COUNT FAR * spc, COUNT FAR * navc, COUNT FAR * bps, struct dpb FAR *dpbp; struct cds FAR *cdsp; COUNT rg[4]; -#ifdef WITHFAT32 - UCOUNT shift = 0; - ULONG cluster_size, ntotal, nfree; -#endif /* next - "log" in the drive */ drive = (drive == 0 ? default_drive : drive - 1); @@ -1181,7 +1202,7 @@ VOID DosGetFree(UBYTE drive, COUNT FAR * spc, COUNT FAR * navc, COUNT FAR * bps, if (cdsp->cdsFlags & CDSNETWDRV) { - int2f_Remote_call(REM_GETSPACE, 0, 0, 0, cdsp, 0, &rg); + remote_getfree(cdsp, rg); *spc = (COUNT) rg[0]; *nc = (COUNT) rg[1]; @@ -1193,27 +1214,6 @@ VOID DosGetFree(UBYTE drive, COUNT FAR * spc, COUNT FAR * navc, COUNT FAR * bps, dpbp = CDSp->cds_table[drive].cdsDpb; if (dpbp == NULL || media_check(dpbp) < 0) return; -#ifdef WITHFAT32 - cluster_size = (dpbp->dpb_clsmask + 1) * dpbp->dpb_secsize; - ntotal = dpbp->dpb_size - 1; - if (ISFAT32(dpbp)) while (cluster_size <= 0x7fff) { - cluster_size <<= 1; - ntotal >>= 1; - shift++; - } - /* get the data available from dpb */ - *nc = (UCOUNT)ntotal; - if (ntotal > 0xfffe) - *nc = 0xfffe; - *spc = (dpbp->dpb_clsmask + 1) << shift; - *bps = dpbp->dpb_secsize; - - /* now tell fs to give us free cluster */ - /* count */ - nfree = dos_free(dpbp) >> shift; - if (nfree > 0xfffe) nfree = 0xfffe; - *navc = (UCOUNT)nfree; -#else /* get the data available from dpb */ *nc = dpbp->dpb_size - 1; *spc = dpbp->dpb_clsmask + 1; @@ -1221,8 +1221,32 @@ VOID DosGetFree(UBYTE drive, COUNT FAR * spc, COUNT FAR * navc, COUNT FAR * bps, /* now tell fs to give us free cluster */ /* count */ - *navc = dos_free(dpbp); +#ifdef WITHFAT32 + if (ISFAT32(dpbp)) + { + ULONG cluster_size, ntotal, nfree; + + /* we shift ntotal until it is equal to or below 0xfff6 */ + cluster_size = (ULONG)dpbp->dpb_secsize << dpbp->dpb_shftcnt; + ntotal = dpbp->dpb_xsize - 1; + nfree = dos_free(dpbp); + while (ntotal > FAT_MAGIC16 && cluster_size < 0x8000) + { + cluster_size <<= 1; + *spc <<= 1; + ntotal >>= 1; + nfree >>= 1; + } + /* get the data available from dpb */ + *nc = ntotal > FAT_MAGIC16 ? FAT_MAGIC16 : (UCOUNT)ntotal; + + /* now tell fs to give us free cluster */ + /* count */ + *navc = nfree > FAT_MAGIC16 ? FAT_MAGIC16 : (UCOUNT)nfree; + return; + } #endif + *navc = (COUNT)dos_free(dpbp); } #ifdef WITHFAT32 @@ -1248,7 +1272,7 @@ COUNT DosGetExtFree(BYTE FAR *DriveString, struct xfreespace FAR *xfsp) if (cdsp->cdsFlags & CDSNETWDRV) { - int2f_Remote_call(REM_GETSPACE, 0, 0, 0, cdsp, 0, &rg); + remote_getfree(cdsp, rg); xfsp->xfs_clussize = rg[0]; xfsp->xfs_totalclusters = rg[1]; @@ -1259,7 +1283,7 @@ COUNT DosGetExtFree(BYTE FAR *DriveString, struct xfreespace FAR *xfsp) if (dpbp == NULL || media_check(dpbp) < 0) return DE_INVLDDRV; xfsp->xfs_secsize = dpbp->dpb_secsize; - xfsp->xfs_totalclusters = dpbp->dpb_size; + xfsp->xfs_totalclusters = (ISFAT32(dpbp) ? dpbp->dpb_xsize : dpbp->dpb_size); xfsp->xfs_freeclusters = dos_free(dpbp); xfsp->xfs_clussize = dpbp->dpb_clsmask + 1; } @@ -1301,7 +1325,6 @@ COUNT DosGetCuDir(UBYTE drive, BYTE FAR * s) #undef CHDIR_DEBUG COUNT DosChangeDir(BYTE FAR * s) { - REG struct cds FAR *cdsp; REG COUNT drive; COUNT result; BYTE FAR *p; @@ -1319,51 +1342,38 @@ COUNT DosChangeDir(BYTE FAR * s) } result = truename(s, PriPathName, FALSE); - if (result != SUCCESS) { - return result; + if (result != SUCCESS) { + return result; } - cdsp = &CDSp->cds_table[drive]; - current_ldt = cdsp; + current_ldt = &CDSp->cds_table[drive]; - if (strlen(PriPathName) > sizeof(cdsp->cdsCurrentPath)-1) + if (strlen(PriPathName) > sizeof(current_ldt->cdsCurrentPath)-1) return DE_PATHNOTFND; - if (cdsp->cdsFlags & CDSNETWDRV) - { #if defined(CHDIR_DEBUG) - printf("Remote Chdir: n='"); - p = s; while(*p) printf("%c", *p++); - printf("' p='"); - p = PriPathName; while(*p) printf("%c", *p++); - printf("'\n"); + printf("Remote Chdir: n='%Fs' p='%Fs\n",s,PriPathName); #endif - result = -int2f_Remote_call(REM_CHDIR, 0, 0, 0, PriPathName, 0, 0); + /* now get fs to change to new */ + /* directory */ + result = (current_ldt->cdsFlags & CDSNETWDRV) ? remote_chdir() : + dos_cd(current_ldt, PriPathName); #if defined(CHDIR_DEBUG) - printf("status = %04x, new_path='", result); - p = cdsd->cdsCurrentPath; while(p) printf("%c", *p++) - printf("'\n"); + printf("status = %04x, new_path='%Fs'\n", result, cdsd->cdsCurrentPath); #endif - if (result != SUCCESS) { - return DE_PATHNOTFND; - } + if (result != SUCCESS) + return result; /* + Copy the path to the current directory + structure. + Some redirectors do not write back to the CDS. SHSUCdX needs this. jt */ - fstrncpy(cdsp->cdsCurrentPath,&PriPathName[0],sizeof(cdsp->cdsCurrentPath)-1); - if (PriPathName[7] == 0) - cdsp->cdsCurrentPath[8] = 0; /* Need two Zeros at the end */ - - } else { - /* now get fs to change to new */ - /* directory */ - result = dos_cd(cdsp, PriPathName); - } - if (result == SUCCESS) { - fstrncpy(cdsp->cdsCurrentPath,&PriPathName[0],sizeof(cdsp->cdsCurrentPath)-1); - } - return result; + fstrcpy(current_ldt->cdsCurrentPath,PriPathName); + if (PriPathName[7] == 0) + current_ldt->cdsCurrentPath[8] = 0; /* Need two Zeros at the end */ + return SUCCESS; } STATIC VOID pop_dmp(dmatch FAR * dmp) @@ -1431,7 +1441,7 @@ COUNT DosFindFirst(UCOUNT attr, BYTE FAR * name) dta = (BYTE FAR *)TempBuffer; rc = current_ldt->cdsFlags & CDSNETWDRV ? - -int2f_Remote_call(REM_FINDFIRST, 0, 0, 0, (VOID FAR *)current_ldt, 0, 0) : + remote_findfirst((VOID FAR *)current_ldt) : dos_findfirst(attr, PriPathName); dta = p; @@ -1477,7 +1487,7 @@ COUNT DosFindNext(void) p = dta; dta = (BYTE FAR *)TempBuffer; rc = (((dmatch *)TempBuffer)->dm_drive & 0x80) ? - -int2f_Remote_call(REM_FINDNEXT, 0, 0, 0, (VOID FAR *)current_ldt, 0, 0) : + remote_findnext((VOID FAR *)current_ldt) : dos_findnext(); dta = p; @@ -1540,9 +1550,7 @@ COUNT DosSetFtimeSft(WORD sft_idx, date dp, time tp) COUNT DosGetFattr(BYTE FAR * name) { - UWORD srfa[5]; COUNT result, drive; - struct cds FAR *last_cds; if (IsDevice(name)) { return DE_FILENOTFND; @@ -1567,13 +1575,10 @@ COUNT DosGetFattr(BYTE FAR * name) return 0x10; } - if (CDSp->cds_table[drive].cdsFlags & CDSNETWDRV) + current_ldt = &CDSp->cds_table[drive]; + if (current_ldt->cdsFlags & CDSNETWDRV) { - last_cds = current_ldt; - current_ldt = &CDSp->cds_table[drive]; - result = -int2f_Remote_call(REM_GETATTRZ, 0, 0, 0, 0, 0, (VOID FAR *) srfa); - current_ldt = last_cds; - return (result < SUCCESS ? result : srfa[0]); + return remote_getfattr(); } else { /* /// Use truename()'s result, which we already have in PriPathName. @@ -1612,7 +1617,6 @@ COUNT DosGetFattr(BYTE FAR * name) COUNT DosSetFattr(BYTE FAR * name, UWORD attrp) { COUNT result, drive; - struct cds FAR *last_cds; if (IsDevice(name) ) { return DE_FILENOTFND; @@ -1628,13 +1632,10 @@ COUNT DosSetFattr(BYTE FAR * name, UWORD attrp) return result; } - if (CDSp->cds_table[drive].cdsFlags & CDSNETWDRV) + current_ldt = &CDSp->cds_table[drive]; + if (current_ldt->cdsFlags & CDSNETWDRV) { - last_cds = current_ldt; - current_ldt = &CDSp->cds_table[drive]; - result = -int2f_Remote_call(REM_SETATTR, 0, 0, 0, 0, 0, MK_FP(0, attrp)); - current_ldt = last_cds; - return result; + return remote_setfattr(attrp); } else { /* /// Use truename()'s result, which we already have in PriPathName. @@ -1655,18 +1656,16 @@ COUNT DosSetFattr(BYTE FAR * name, UWORD attrp) UBYTE DosSelectDrv(UBYTE drv) { - struct cds FAR *cdsp = &CDSp->cds_table[drv]; + current_ldt = &CDSp->cds_table[drv]; - if ((drv < lastdrive) && (cdsp->cdsFlags & CDSVALID)) + if ((drv < lastdrive) && (current_ldt->cdsFlags & CDSVALID)) /* && ((cdsp->cdsFlags & CDSNETWDRV) || (cdsp->cdsDpb!=NULL && media_check(cdsp->cdsDpb)==SUCCESS))) */ - { - current_ldt = cdsp; default_drive = drv; - } + return lastdrive; } @@ -1687,8 +1686,8 @@ COUNT DosDelete(BYTE FAR *path) return result; } current_ldt = &CDSp->cds_table[drive]; - if (CDSp->cds_table[drive].cdsFlags & CDSNETWDRV) { - return -int2f_Remote_call(REM_DELETE, 0, 0, 0, 0, 0, 0); + if (current_ldt->cdsFlags & CDSNETWDRV) { + return remote_delete(); } else { return dos_delete(PriPathName); } @@ -1708,8 +1707,8 @@ COUNT DosRenameTrue(BYTE * path1, BYTE * path2) return DE_INVLDDRV; } current_ldt = &CDSp->cds_table[drive1]; - if (CDSp->cds_table[drive1].cdsFlags & CDSNETWDRV) { - return -int2f_Remote_call(REM_RENAME, 0, 0, 0, 0, 0, 0); + if (current_ldt->cdsFlags & CDSNETWDRV) { + return remote_rename(); } else { return dos_rename(PriPathName, SecPathName); } @@ -1749,8 +1748,8 @@ COUNT DosMkdir(BYTE FAR * dir) return result; } current_ldt = &CDSp->cds_table[drive]; - if (CDSp->cds_table[drive].cdsFlags & CDSNETWDRV) { - return -int2f_Remote_call(REM_MKDIR, 0, 0, 0, 0, 0, 0); + if (current_ldt->cdsFlags & CDSNETWDRV) { + return remote_mkdir(); } else { return dos_mkdir(PriPathName); } @@ -1774,7 +1773,7 @@ COUNT DosRmdir(BYTE FAR * dir) } current_ldt = &CDSp->cds_table[drive]; if (CDSp->cds_table[drive].cdsFlags & CDSNETWDRV) { - return -int2f_Remote_call(REM_RMDIR, 0, 0, 0, 0, 0, 0); + return remote_rmdir(); } else { return dos_rmdir(PriPathName); } diff --git a/kernel/dosnames.c b/kernel/dosnames.c index b513204..e5d2195 100644 --- a/kernel/dosnames.c +++ b/kernel/dosnames.c @@ -36,6 +36,9 @@ static BYTE *dosnamesRcsId = "$Id$"; /* * $Log$ + * Revision 1.12 2001/11/04 19:47:39 bartoldeman + * kernel 2025a changes: see history.txt + * * Revision 1.11 2001/07/24 16:56:29 bartoldeman * fixes for FCBs, DJGPP ls, DBLBYTE, dyninit allocation (2024e). * @@ -139,6 +142,7 @@ VOID XlateLcase(BYTE * szFname, COUNT nChars); VOID DosTrimPath(BYTE * lpszPathNamep); /* Should be converted to a portable version after v1.0 is released. */ +#if 0 VOID XlateLcase(BYTE * szFname, COUNT nChars) { while (nChars--) @@ -148,6 +152,7 @@ VOID XlateLcase(BYTE * szFname, COUNT nChars) ++szFname; } } +#endif VOID SpacePad(BYTE * szString, COUNT nChars) { @@ -156,12 +161,14 @@ VOID SpacePad(BYTE * szString, COUNT nChars) for (i = strlen(szString); i < nChars; i++) szString[i] = ' '; } + /* MSD durring an FindFirst search string looks like this; (*), & (.) == Current directory *.* (\) == Root directory *.* (..) == Back one directory *.* + This always has a "truename" as input, so we may do some shortcuts */ COUNT ParseDosName(BYTE * lpszFileName, COUNT * pnDrive, @@ -187,26 +194,11 @@ COUNT ParseDosName(BYTE * lpszFileName, lpszLclFile = lpszLclExt = lpszLclDir = 0; nDirCnt = nFileCnt = nExtCnt = 0; - /* Start by cheking for a drive specifier ... */ - if (DriveChar(*lpszFileName) && ':' == lpszFileName[1]) - { - /* found a drive, fetch it and bump pointer past drive */ - /* NB: this code assumes ASCII */ - if (pnDrive) - { - *pnDrive = *lpszFileName - 'A'; - if (*pnDrive > 26) - *pnDrive -= ('a' - 'A'); - } - lpszFileName += 2; - } - else - { - if (pnDrive) - { - *pnDrive = -1; - } - } + /* found a drive, fetch it and bump pointer past drive */ + /* NB: this code assumes ASCII */ + if (pnDrive) + *pnDrive = *lpszFileName - 'A'; + lpszFileName += 2; if (!pszDir && !pszFile && !pszExt) return SUCCESS; @@ -214,11 +206,15 @@ COUNT ParseDosName(BYTE * lpszFileName, lpszLclDir = lpszLclFile = lpszFileName; while (DirChar(*lpszFileName)) { - if (PathSep(*lpszFileName)) + if (*lpszFileName == '\\') lpszLclFile = lpszFileName + 1; ++lpszFileName; } nDirCnt = FP_OFF(lpszLclFile) - FP_OFF(lpszLclDir); + /* Fix lengths to maximums allowed by MS-DOS. */ + if (nDirCnt > PARSE_MAX-1) + nDirCnt = PARSE_MAX-1; + /* Parse out the file name portion. */ lpszFileName = lpszLclFile; while (bAllowWildcards ? WildChar(*lpszFileName) : NameChar(*lpszFileName)) @@ -231,36 +227,19 @@ COUNT ParseDosName(BYTE * lpszFileName, /* Lixing Yuan Patch */ if (bAllowWildcards) /* for find first */ { - if (*lpszFileName == '.') - lpszFileName++; - if (*lpszFileName == '.') - lpszFileName++; if (*lpszFileName != '\0') return DE_FILENOTFND; if (nDirCnt == 1) /* for d:\ */ return DE_NFILES; if (pszDir) { - if ((lpszFileName - lpszLclFile) == 2) /* for tail DotDot */ - nDirCnt += 2; - if (nDirCnt > PARSE_MAX-1) - nDirCnt = PARSE_MAX-1; - bcopy(lpszLclDir, pszDir, nDirCnt); - if (((lpszFileName - lpszLclFile) == 2) && (nDirCnt < PARSE_MAX)) - pszDir[nDirCnt++] = '\\'; /* make DosTrimPath() enjoy, for tail DotDot */ + memcpy(pszDir, lpszLclDir, nDirCnt); pszDir[nDirCnt] = '\0'; - DosTrimPath(pszDir); } if (pszFile) - { - *pszFile++ = '*'; - *pszFile = '\0'; - } + memcpy(pszFile, "????????", FNAME_SIZE+1); if (pszExt) - { - *pszExt++ = '*'; - *pszExt = '\0'; - } + memcpy(pszExt, "???", FEXT_SIZE+1); return SUCCESS; } else @@ -288,36 +267,25 @@ COUNT ParseDosName(BYTE * lpszFileName, else if (*lpszFileName) return DE_FILENOTFND; - /* Fix lengths to maximums allowed by MS-DOS. */ - if (nDirCnt > PARSE_MAX-1) - nDirCnt = PARSE_MAX-1; - if (nFileCnt > FNAME_SIZE) - nFileCnt = FNAME_SIZE; - if (nExtCnt > FEXT_SIZE) - nExtCnt = FEXT_SIZE; - /* Finally copy whatever the user wants extracted to the user's */ /* buffers. */ if (pszDir) { - bcopy(lpszLclDir, pszDir, nDirCnt); + memcpy(pszDir, lpszLclDir, nDirCnt); pszDir[nDirCnt] = '\0'; } if (pszFile) { - bcopy(lpszLclFile, pszFile, nFileCnt); + memcpy(pszFile, lpszLclFile, nFileCnt); pszFile[nFileCnt] = '\0'; } if (pszExt) { - bcopy(lpszLclExt, pszExt, nExtCnt); + memcpy(pszExt, lpszLclExt, nExtCnt); pszExt[nExtCnt] = '\0'; } /* Clean up before leaving */ - if (pszDir) - DosTrimPath(pszDir); - return SUCCESS; } @@ -412,7 +380,6 @@ COUNT ParseDosPath(BYTE * lpszFileName, return SUCCESS; } -#endif VOID DosTrimPath(BYTE * lpszPathNamep) { @@ -526,4 +493,5 @@ VOID DosTrimPath(BYTE * lpszPathNamep) ++lpszNext; } } +#endif diff --git a/kernel/dsk.c b/kernel/dsk.c index 1e6d8ef..43a3996 100644 --- a/kernel/dsk.c +++ b/kernel/dsk.c @@ -34,6 +34,9 @@ static BYTE *dskRcsId = "$Id$"; /* * $Log$ + * Revision 1.21 2001/11/04 19:47:39 bartoldeman + * kernel 2025a changes: see history.txt + * * Revision 1.20 2001/09/23 20:39:44 bartoldeman * FAT32 support, misc fixes, INT2F/AH=12 support, drive B: handling * @@ -173,9 +176,12 @@ COUNT ASMCFUNC fl_readdasd(WORD); COUNT ASMCFUNC fl_diskchanged(WORD); COUNT ASMCFUNC fl_rd_status(WORD); -COUNT ASMCFUNC fl_read(WORD, WORD, WORD, WORD, WORD, BYTE FAR *); -COUNT ASMCFUNC fl_write(WORD, WORD, WORD, WORD, WORD, BYTE FAR *); -COUNT ASMCFUNC fl_verify(WORD, WORD, WORD, WORD, WORD, BYTE FAR *); +COUNT ASMCFUNC fl_format(WORD, WORD, WORD, WORD, WORD, UBYTE FAR *); +COUNT ASMCFUNC fl_read(WORD, WORD, WORD, WORD, WORD, UBYTE FAR *); +COUNT ASMCFUNC fl_write(WORD, WORD, WORD, WORD, WORD, UBYTE FAR *); +COUNT ASMCFUNC fl_verify(WORD, WORD, WORD, WORD, WORD, UBYTE FAR *); +COUNT ASMCFUNC fl_setdisktype(WORD, WORD); +COUNT ASMCFUNC fl_setmediatype(WORD, WORD, WORD); VOID ASMCFUNC fl_readkey(VOID); extern COUNT ASMCFUNC fl_lba_ReadWrite (BYTE drive, WORD mode, @@ -188,13 +194,16 @@ BOOL fl_reset(); COUNT fl_readdasd(); COUNT fl_diskchanged(); COUNT fl_rd_status(); +COUNT fl_format(); COUNT fl_read(); COUNT fl_write(); COUNT fl_verify(); VOID fl_readkey(); +COUNT fl_setmediatype(); +COUNT fl_setdisktype(); #endif -#define NENTRY 26 /* total size of dispatch table */ +#define NENTRY 26 /* total size of dispatch table */ extern BYTE FAR nblk_rel; @@ -206,6 +215,8 @@ extern int FAR ASMCFUNC Get_nblk_rel(void); #define LBA_WRITE 0x4300 UWORD LBA_WRITE_VERIFY = 0x4302; #define LBA_VERIFY 0x4400 +#define LBA_FORMAT 0xffff /* fake number for FORMAT track + (only for NON-LBA floppies now!) */ /* this buffer must not overlap a 64K boundary due to DMA transfers @@ -405,12 +416,17 @@ STATIC WORD diskchange(ddt *pddt) WORD mediachk(rqptr rp, ddt *pddt) { /* check floppy status */ - if (pddt->ddt_descflags & DF_DISKCHANGE) + if (pddt->ddt_descflags & DF_REFORMAT) + { + pddt->ddt_descflags &= ~DF_REFORMAT; + rp->r_mcretcode = M_CHANGED; + } + else if (pddt->ddt_descflags & DF_DISKCHANGE) { pddt->ddt_descflags &= ~DF_DISKCHANGE; rp->r_mcretcode = M_DONT_KNOW; } - else + else { rp->r_mcretcode = diskchange(pddt); } @@ -574,6 +590,7 @@ static getbpb(ddt *pddt) return failure(E_FAILURE); } pddt->ddt_ncyl = (count + head * sector - 1) / (head * sector); + tmark(); #ifdef DSK_DEBUG @@ -617,10 +634,23 @@ static WORD IoctlQueblk(rqptr rp, ddt *pddt) } +COUNT Genblockio(ddt *pddt, UWORD mode, WORD head, WORD track, WORD sector, + WORD count, VOID FAR *buffer) +{ + UWORD transferred; + + /* apparently sector is ZERO, not ONE based !!! */ + return LBA_Transfer(pddt, mode, buffer, + ((ULONG)track * pddt->ddt_bpb.bpb_nheads + head) * + (ULONG)pddt->ddt_bpb.bpb_nsecs + + pddt->ddt_offset + sector, + count, &transferred); +} + STATIC WORD Genblkdev(rqptr rp,ddt *pddt) { int ret; - bpb FAR *pbpb; + bpb *pbpb; #ifdef WITHFAT32 int extended = 0; @@ -631,60 +661,143 @@ STATIC WORD Genblkdev(rqptr rp,ddt *pddt) return failure(E_CMD); switch(rp->r_count & 0xff){ - case 0x60: /* get device parameters */ + case 0x40: /* set device parameters */ { struct gblkio FAR * gblp = (struct gblkio FAR *) rp->r_trans; - REG COUNT x = 5,y = 1,z = 0; - if (!hd(pddt->ddt_descflags)){ - y = 2; - x = 8; /* any odd ball drives return this */ - switch(pddt->ddt_bpb.bpb_nsize) - { - case 640: - case 720: /* 320-360 */ - x = 0; - z = 1; - break; - case 1440: /* 720 */ - x = 2; - break; - case 2400: /* 1.2 */ - x = 1; - break; - case 2880: /* 1.44 */ - x = 7; - break; - case 5760: /* 2.88 almost forgot this one*/ - x = 9; - break; - } - } - gblp->gbio_devtype = (UBYTE) x; - gblp->gbio_devattrib = (UWORD) y; - gblp->gbio_media = (UBYTE) z; - gblp->gbio_ncyl = pddt->ddt_ncyl; + pddt->ddt_type = gblp->gbio_devtype; + pddt->ddt_descflags &= ~3; + pddt->ddt_descflags |= (gblp->gbio_devattrib & 3) + | (DF_DPCHANGED | DF_REFORMAT); + pddt->ddt_ncyl = gblp->gbio_ncyl; /* use default dpb or current bpb? */ pbpb = (gblp->gbio_spcfunbit & 0x01) == 0 ? &pddt->ddt_defbpb : &pddt->ddt_bpb; #ifdef WITHFAT32 - if (!extended) fmemcpy(&gblp->gbio_bpb, pbpb, BPB_SIZEOF); + if (!extended) fmemcpy(pbpb, &gblp->gbio_bpb, BPB_SIZEOF); else #endif - fmemcpy(&gblp->gbio_bpb, pbpb, sizeof(gblp->gbio_bpb)); - gblp->gbio_nsecs = pbpb->bpb_nsector; + fmemcpy(pbpb, &gblp->gbio_bpb, sizeof(gblp->gbio_bpb)); + /*pbpb->bpb_nsector = gblp->gbio_nsecs;*/ break; } - case 0x66: /* get volume serial number */ + case 0x41: /* write track */ { - struct Gioc_media FAR * gioc = (struct Gioc_media FAR *) rp->r_trans; + struct gblkrw FAR * rw = (struct gblkrw FAR *) rp->r_trans; + ret = Genblockio(pddt, LBA_WRITE, rw->gbrw_head, rw->gbrw_cyl, + rw->gbrw_sector, rw->gbrw_nsecs, rw->gbrw_buffer); + if (ret != 0) + return dskerr(ret); + } + break; + case 0x42: /* format/verify track */ + { + struct gblkfv FAR * fv = (struct gblkfv FAR *) rp->r_trans; + COUNT tracks; + struct thst {UBYTE track, head, sector, type;} *addrfield, afentry; - ret = getbpb(pddt); - if (ret != 0) - return (ret); + if (hd(pddt->ddt_descflags)) + { + /* XXX no low-level formatting for hard disks implemented */ + fv->gbfv_spcfunbit = 1; /* "not supported by bios" */ + pddt->ddt_descflags &= ~DF_DPCHANGED; + return S_DONE; + } + if (pddt->ddt_descflags & DF_DPCHANGED) + { + pddt->ddt_descflags &= ~DF_DPCHANGED; - gioc->ioc_serialno = pddt->ddt_serialno; - fmemcpy(gioc->ioc_volume, pddt->ddt_volume,11); - fmemcpy(gioc->ioc_fstype, pddt->ddt_fstype,8); + /* first try newer setmediatype function */ + ret = fl_setmediatype(pddt->ddt_driveno, pddt->ddt_ncyl, + pddt->ddt_bpb.bpb_nsecs); + if (ret == 0xc) + { + /* specified tracks, sectors/track not allowed for drive */ + fv->gbfv_spcfunbit = 2; + return dskerr(ret); + } + else if (ret == 0x80) { + fv->gbfv_spcfunbit = 3; /* no disk in drive */ + return dskerr(ret); + } + else if (ret != 0) + /* otherwise, setdisktype */ + { + COUNT type = 0; + if ((fv->gbfv_spcfunbit & 1) && + (ret = fl_read(pddt->ddt_driveno,0,0,1,1,DiskTransferBuffer)) != 0) + { + fv->gbfv_spcfunbit = 3; /* no disk in drive */ + return dskerr(ret); + } + if (pddt->ddt_ncyl == 40 && + (pddt->ddt_bpb.bpb_nsecs == 9 || pddt->ddt_bpb.bpb_nsecs == 8)) + { + if (pddt->ddt_type == 0) + type = 1; /* 320/360K disk in 360K drive */ + else if (pddt->ddt_type == 1) + type = 2; /* 320/360K disk in 1.2M drive */ + } + else if (pddt->ddt_type == 1 && pddt->ddt_ncyl == 80 && + pddt->ddt_bpb.bpb_nsecs == 15) + type = 3; /* 1.2M disk in 1.2M drive */ + else if ((pddt->ddt_type == 2 || pddt->ddt_type == 7) && + pddt->ddt_ncyl == 80 && pddt->ddt_bpb.bpb_nsecs == 15 + ) + type = 4; /* 720kb disk in 1.44M or 720kb drive */ + + if (type == 0) + { + /* specified tracks, sectors/track not allowed for drive */ + fv->gbfv_spcfunbit = 2; + return dskerr(0xc); + } + fl_setdisktype(pddt->ddt_driveno, type); + } + } + if (fv->gbfv_spcfunbit & 1) return S_DONE; + + afentry.type = 2; /* 512 byte sectors */ + afentry.track = fv->gbfv_cyl; + afentry.head = fv->gbfv_head; + + for (tracks = fv->gbfv_spcfunbit & 2 ? fv->gbfv_ntracks : 1; tracks > 0; + tracks--) + { + addrfield = (struct thst *)DiskTransferBuffer; + + if (afentry.track > pddt->ddt_ncyl) + return failure(E_FAILURE); + + for (afentry.sector = 1; afentry.sector <= pddt->ddt_bpb.bpb_nsecs; + afentry.sector++) + memcpy(addrfield++, &afentry, sizeof(afentry)); + + ret = Genblockio(pddt, LBA_FORMAT, afentry.head, afentry.track, 0, + pddt->ddt_bpb.bpb_nsecs, DiskTransferBuffer); + if (ret != 0) + return dskerr(ret); + } + afentry.head++; + if (afentry.head >= pddt->ddt_bpb.bpb_nheads) + { + afentry.head = 0; + afentry.track++; + } + } + + /* fall through to verify */ + + case 0x62: /* verify track */ + { + struct gblkfv FAR * fv = (struct gblkfv FAR *) rp->r_trans; + + ret = Genblockio(pddt, LBA_VERIFY, fv->gbfv_head, fv->gbfv_cyl, 0, + (fv->gbfv_spcfunbit ? + fv->gbfv_ntracks * pddt->ddt_defbpb.bpb_nsecs : + pddt->ddt_defbpb.bpb_nsecs), DiskTransferBuffer); + if (ret != 0) + return dskerr(ret); + fv->gbfv_spcfunbit = 0; /* success */ } break; case 0x46: /* set volume serial number */ @@ -706,12 +819,6 @@ STATIC WORD Genblkdev(rqptr rp,ddt *pddt) return (dskerr(ret)); } break; - case 0x67: /* get access flag */ - { - struct Access_info FAR * ai = (struct Access_info FAR *) rp->r_trans; - ai->AI_Flag = pddt->ddt_descflags & DF_NOACCESS ? 0 : 1; /* bit 9 */ - } - break; case 0x47: /* set access flag */ { struct Access_info FAR * ai = (struct Access_info FAR *) rp->r_trans; @@ -719,6 +826,53 @@ STATIC WORD Genblkdev(rqptr rp,ddt *pddt) pddt->ddt_descflags |= (ai->AI_Flag ? 0 : DF_NOACCESS); } break; + case 0x60: /* get device parameters */ + { + struct gblkio FAR * gblp = (struct gblkio FAR *) rp->r_trans; + + gblp->gbio_devtype = pddt->ddt_type; + gblp->gbio_devattrib = pddt->ddt_descflags & 3; + /* 360 kb disk in 1.2 MB drive */ + gblp->gbio_media = (pddt->ddt_type == 1) && (pddt->ddt_ncyl == 40); + gblp->gbio_ncyl = pddt->ddt_ncyl; + /* use default dpb or current bpb? */ + pbpb = (gblp->gbio_spcfunbit & 0x01) == 0 ? &pddt->ddt_defbpb : &pddt->ddt_bpb; +#ifdef WITHFAT32 + if (!extended) fmemcpy(&gblp->gbio_bpb, pbpb, BPB_SIZEOF); + else +#endif + fmemcpy(&gblp->gbio_bpb, pbpb, sizeof(gblp->gbio_bpb)); + /*gblp->gbio_nsecs = pbpb->bpb_nsector;*/ + break; + } + case 0x61: /* read track */ + { + struct gblkrw FAR * rw = (struct gblkrw FAR *) rp->r_trans; + ret = Genblockio(pddt, LBA_READ, rw->gbrw_head, rw->gbrw_cyl, + rw->gbrw_sector, rw->gbrw_nsecs, rw->gbrw_buffer); + if (ret != 0) + return dskerr(ret); + } + break; + case 0x66: /* get volume serial number */ + { + struct Gioc_media FAR * gioc = (struct Gioc_media FAR *) rp->r_trans; + + ret = getbpb(pddt); + if (ret != 0) + return (ret); + + gioc->ioc_serialno = pddt->ddt_serialno; + fmemcpy(gioc->ioc_volume, pddt->ddt_volume,11); + fmemcpy(gioc->ioc_fstype, pddt->ddt_fstype,8); + } + break; + case 0x67: /* get access flag */ + { + struct Access_info FAR * ai = (struct Access_info FAR *) rp->r_trans; + ai->AI_Flag = pddt->ddt_descflags & DF_NOACCESS ? 0 : 1; /* bit 9 */ + } + break; default: return failure(E_CMD); } @@ -859,7 +1013,7 @@ STATIC unsigned DMA_max_transfer(void FAR *buffer, unsigned count) /* int LBA_Transfer( ddt *pddt, physical characteristics of drive - UWORD mode, LBA_READ/WRITE/WRITE_VERIFY + UWORD mode, LBA_READ/WRITE/WRITE_VERIFY/VERIFY VOID FAR *buffer, user buffer ULONG LBA_address, absolute sector address unsigned totaltodo, number of sectors to transfer @@ -898,11 +1052,14 @@ int LBA_Transfer(ddt *pddt ,UWORD mode, VOID FAR *buffer, int num_retries; + /* only low-level format floppies for now ! */ + if (mode == LBA_FORMAT && hd(pddt->ddt_descflags)) + return 0; + /* optionally change from A: to B: or back */ play_dj(pddt); *transferred = 0; - /* if (LBA_address+totaltodo > pddt->total_sectors) { @@ -940,7 +1097,7 @@ int LBA_Transfer(ddt *pddt ,UWORD mode, VOID FAR *buffer, for ( num_retries = 0; num_retries < N_RETRY; num_retries++) { - if (pddt->ddt_LBASupported) + if (pddt->ddt_LBASupported && mode != LBA_FORMAT) { dap.number_of_blocks = count; @@ -985,7 +1142,9 @@ int LBA_Transfer(ddt *pddt ,UWORD mode, VOID FAR *buffer, return 1; } - error_code = (mode == LBA_READ ? fl_read : fl_write)( + error_code = (mode == LBA_READ ? fl_read : + mode == LBA_VERIFY ? fl_verify : + mode == LBA_FORMAT ? fl_format : fl_write)( pddt->ddt_driveno, chs.Head, (UWORD)chs.Cylinder, chs.Sector, count, transfer_address); diff --git a/kernel/entry.asm b/kernel/entry.asm index 30a8914..e32fbe3 100644 --- a/kernel/entry.asm +++ b/kernel/entry.asm @@ -28,6 +28,9 @@ ; $Id$ ; ; $Log$ +; Revision 1.15 2001/11/04 19:47:39 bartoldeman +; kernel 2025a changes: see history.txt +; ; Revision 1.14 2001/09/23 20:39:44 bartoldeman ; FAT32 support, misc fixes, INT2F/AH=12 support, drive B: handling ; @@ -278,9 +281,12 @@ reloc_call_int21_handler: ; sti PUSH$ALL + mov bp,sp + + ProtectHighPartOfRegistersOn386 ; - ; Create kernel refernce frame. + ; Create kernel reference frame. ; ; NB: At this point, SS != DS and won't be set that way ; until later when which stack to run on is determined. @@ -300,7 +306,7 @@ int21_reentry: int21_user: call dos_crit_sect - mov bp,sp + push ss push bp call _int21_syscall @@ -319,7 +325,6 @@ int21_user: int21_1: mov si,ss ; save user stack, to be retored later - mov bx,sp ; @@ -329,8 +334,8 @@ int21_1: ; mov word [_lpUserStack+2],ss mov word [_user_r+2],ss - mov word [_lpUserStack],sp ; store and init - mov word [_user_r],sp ; store and init + mov word [_lpUserStack],bp ; store and init + mov word [_user_r],bp ; store and init ; ; Decide which stack to run on. @@ -363,7 +368,7 @@ int21_onerrorstack: sti push si ; user SS:SP - push bx + push bp call _int21_service jmp short int21_exit_nodec @@ -395,7 +400,7 @@ int21_normalentry: ; push si ; user SS:SP - push bx + push bp call _int21_service int21_exit: dec byte [_InDOS] @@ -407,14 +412,21 @@ int21_exit: dec byte [_InDOS] int21_exit_nodec: - pop bx ; get back user stack + pop bp ; get back user stack pop si +%IFDEF I386 + sub bp,8 +%endif + cli mov ss,si - mov sp,bx - sti -int21_ret: POP$ALL + mov sp,bp + +int21_ret: + RestoreHighPartOfRegistersOn386 + + POP$ALL ; ; ... and return. diff --git a/kernel/execrh.asm b/kernel/execrh.asm index 4754aef..656d585 100644 --- a/kernel/execrh.asm +++ b/kernel/execrh.asm @@ -30,6 +30,9 @@ ; $Id$ ; ; $Log$ +; Revision 1.8 2001/11/04 19:47:39 bartoldeman +; kernel 2025a changes: see history.txt +; ; Revision 1.7 2001/04/21 22:32:53 bartoldeman ; Init DS=Init CS, fixed stack overflow problems and misc bugs. ; @@ -105,33 +108,26 @@ segment HMA_TEXT _execrh: push bp ; perform c entry mov bp,sp -; push bx ; random char on display push si - push es ; sometimes it get lost push ds ; sp=bp-8 lds si,[bp+8] ; ds:si = device header les bx,[bp+4] ; es:bx = request header - push bp - push ds - push si ; needed later - mov ax, [si+6] + + mov ax, [si+6] ; construct strategy address mov [bp+8], ax - call far[bp+8] ; call far the strategy - pop si ; these were saved - pop ds - pop bp + + mov si, [si+8] ; save 'interrupt' address - mov ax, [si+8] - mov [bp+8], ax + call far[bp+8] ; call far the strategy + + mov [bp+8],si ; construct interrupt address call far[bp+8] ; call far the interrupt sti ; damm driver turn off ints cld ; has gone backwards pop ds - pop es pop si -; pop bx pop bp ret diff --git a/kernel/fatdir.c b/kernel/fatdir.c index 50b3c30..91e2a8a 100644 --- a/kernel/fatdir.c +++ b/kernel/fatdir.c @@ -36,6 +36,9 @@ static BYTE *fatdirRcsId = "$Id$"; /* * $Log$ + * Revision 1.24 2001/11/04 19:47:39 bartoldeman + * kernel 2025a changes: see history.txt + * * Revision 1.23 2001/09/23 20:39:44 bartoldeman * FAT32 support, misc fixes, INT2F/AH=12 support, drive B: handling * @@ -193,6 +196,38 @@ static BYTE *fatdirRcsId = "$Id$"; * Initial revision. */ +/* Description. + * Initialize a fnode so that it will point to the directory with + * dirstart starting cluster; in case of passing dirstart == 0 + * fnode will point to the start of a root directory */ +VOID dir_init_fnode(f_node_ptr fnp, CLUSTER dirstart) +{ + /* reset the directory flags */ + fnp->f_flags.f_dmod = FALSE; + fnp->f_flags.f_droot = FALSE; + fnp->f_flags.f_ddir = TRUE; + fnp->f_flags.f_dnew = TRUE; + fnp->f_diroff = fnp->f_offset = fnp->f_cluster_offset = fnp->f_highwater = 0l; + + /* root directory */ + if (dirstart == 0) + { +#ifdef WITHFAT32 + if (ISFAT32(fnp->f_dpb)) + { + fnp->f_cluster = fnp->f_dirstart = fnp->f_dpb->dpb_xrootclst; + } + else +#endif + { + fnp->f_dirstart = 0l; + fnp->f_flags.f_droot = TRUE; + } + } + else /* non-root */ + fnp->f_cluster = fnp->f_dirstart = dirstart; +} + f_node_ptr dir_open(BYTE * dirname) { f_node_ptr fnp; @@ -269,31 +304,11 @@ f_node_ptr dir_open(BYTE * dirname) return (f_node_ptr)0; } - fnp->f_dsize = DIRENT_SIZE * fnp->f_dpb->dpb_dirents; - - fnp->f_diroff = 0l; - fnp->f_flags.f_dmod = FALSE; /* a brand new fnode */ - fnp->f_flags.f_dnew = TRUE; - fnp->f_flags.f_dremote = FALSE; - - fnp->f_dirstart = 0; - /* Walk the directory tree to find the starting cluster */ /* */ - /* Set the root flags since we always start from the root */ + /* Start from the root directory (dirstart = 0) */ - fnp->f_flags.f_droot = TRUE; -#ifdef WITHFAT32 - if (ISFAT32(fnp->f_dpb)) { - fnp->f_flags.f_droot = FALSE; - fnp->f_flags.f_ddir = TRUE; - fnp->f_offset = 0l; - fnp->f_cluster_offset = 0l; - fnp->f_highwater = 0l; - fnp->f_cluster = fnp->f_dpb->dpb_xrootclst; - fnp->f_dirstart = fnp->f_dpb->dpb_xrootclst; - } -#endif + dir_init_fnode(fnp, 0); for (p = pszPath; *p != '\0';) { @@ -336,7 +351,7 @@ f_node_ptr dir_open(BYTE * dirname) DosUpFMem((BYTE FAR *) TempBuffer, FNAME_SIZE + FEXT_SIZE); - while (dir_read(fnp) == DIRENT_SIZE) + while (dir_read(fnp) == 1) { if (fnp->f_dir.dir_name[0] != '\0' && fnp->f_dir.dir_name[0] != DELETED) { @@ -358,149 +373,122 @@ f_node_ptr dir_open(BYTE * dirname) { /* make certain we've moved off */ /* root */ - fnp->f_flags.f_droot = FALSE; - fnp->f_flags.f_ddir = TRUE; - /* set up for file read/write */ - fnp->f_offset = 0l; - fnp->f_cluster_offset = 0l; /*JPP */ - fnp->f_highwater = 0l; - fnp->f_cluster = getdstart(fnp->f_dir); - fnp->f_dirstart = fnp->f_cluster; - /* reset the directory flags */ - fnp->f_diroff = 0l; - fnp->f_flags.f_dmod = FALSE; - fnp->f_flags.f_dnew = TRUE; - fnp->f_dsize = DIRENT_SIZE * fnp->f_dpb->dpb_dirents; - + dir_init_fnode(fnp, getdstart(fnp->f_dir)); } } return fnp; } +/* Description. + * Read next consequitive directory entry, pointed by fnp. + * If some error occures the other critical + * fields aren't changed, except those used for caching. + * The fnp->f_diroff always corresponds to the directory entry + * which has been read. + * Return value. + * 1 - all OK, directory entry having been read is not empty. + * 0 - Directory entry is empty. + * DE_HNDLDSKFULL - Disk full + * DE_SEEK - Other error from map_cluster + * DE_TOOMANY - Too many files in root dir. + * DE_BLKINVLD - Invalid block + * Note. Empty directory entries always resides at the end of the directory. */ COUNT dir_read(REG f_node_ptr fnp) { -/* REG i; */ -/* REG j; */ - struct buffer FAR *bp; REG UWORD secsize = fnp->f_dpb->dpb_secsize; + ULONG new_diroff = fnp->f_diroff; /* Directories need to point to their current offset, not for */ /* next op. Therefore, if it is anything other than the first */ /* directory entry, we will update the offset on entry rather */ /* than wait until exit. If it was new, clear the special new */ /* flag. */ - if (fnp->f_flags.f_dnew) - fnp->f_flags.f_dnew = FALSE; - else - fnp->f_diroff += DIRENT_SIZE; + if (!fnp->f_flags.f_dnew) + new_diroff += DIRENT_SIZE; /* Determine if we hit the end of the directory. If we have, */ /* bump the offset back to the end and exit. If not, fill the */ /* dirent portion of the fnode, clear the f_dmod bit and leave, */ /* but only for root directories */ - if (fnp->f_flags.f_droot && fnp->f_diroff >= fnp->f_dsize) + + if (fnp->f_flags.f_droot) { - fnp->f_diroff -= DIRENT_SIZE; - return 0; + if (new_diroff >= DIRENT_SIZE * (ULONG)fnp->f_dpb->dpb_dirents) + return DE_TOOMANY; + + bp = getblock((ULONG) (new_diroff / secsize + + fnp->f_dpb->dpb_dirstrt), + fnp->f_dpb->dpb_unit); +#ifdef DISPLAY_GETBLOCK + printf("DIR (dir_read)\n"); +#endif } else { - if (fnp->f_flags.f_droot) - { - if ((fnp->f_diroff / secsize - + fnp->f_dpb->dpb_dirstrt) - >= fnp->f_dpb->dpb_data) - { - fnp->f_flags.f_dfull = TRUE; - return 0; - } + COUNT rc; + + /* Do a "seek" to the directory position */ + fnp->f_offset = new_diroff; - bp = getblock((ULONG) (fnp->f_diroff / secsize - + fnp->f_dpb->dpb_dirstrt), - fnp->f_dpb->dpb_unit); + /* Search through the FAT to find the block */ + /* that this entry is in. */ #ifdef DISPLAY_GETBLOCK - printf("DIR (dir_read)\n"); + printf("dir_read: "); #endif - } - else - { + if ((rc = map_cluster(fnp, XFR_READ)) != SUCCESS) + return rc; - /* Do a "seek" to the directory position */ - fnp->f_offset = fnp->f_diroff; + /* If the returned cluster is FREE, LAST_CLUSTER */ + /* LONG_LAST_CLUSTER, return "disk as full" */ - /* Search through the FAT to find the block */ - /* that this entry is in. */ + if (fnp->f_cluster == FREE || last_link(fnp)) + return DE_HNDLDSKFULL; + + /* Compute the block within the cluster and the */ + /* offset within the block. */ + fnp->f_sector = (fnp->f_offset / secsize) & fnp->f_dpb->dpb_clsmask; + fnp->f_boff = fnp->f_offset % secsize; + + /* Get the block we need from cache */ + bp = getblock(clus2phys(fnp->f_cluster, fnp->f_dpb) + fnp->f_sector, + fnp->f_dpb->dpb_unit); #ifdef DISPLAY_GETBLOCK - printf("dir_read: "); + printf("DIR (dir_read)\n"); #endif - if (map_cluster(fnp, XFR_READ) != SUCCESS) - { - fnp->f_flags.f_dfull = TRUE; - return 0; - } - - /* If the returned cluster is FREE, return zero */ - /* bytes read. */ - if (fnp->f_cluster == FREE) - return 0; - - /* If the returned cluster is LAST_CLUSTER or */ - /* LONG_LAST_CLUSTER, return zero bytes read */ - /* and set the directory as full. */ - - if (last_link(fnp)) - { - fnp->f_diroff -= DIRENT_SIZE; - fnp->f_flags.f_dfull = TRUE; - return 0; - } - - /* Compute the block within the cluster and the */ - /* offset within the block. */ - fnp->f_sector = (fnp->f_offset / secsize) & fnp->f_dpb->dpb_clsmask; - fnp->f_boff = fnp->f_offset % secsize; - - /* Get the block we need from cache */ - bp = getblock((ULONG) clus2phys(fnp->f_cluster, - (fnp->f_dpb->dpb_clsmask + 1), - fnp->f_dpb->dpb_data) - + fnp->f_sector, - fnp->f_dpb->dpb_unit); -#ifdef DISPLAY_GETBLOCK - printf("DIR (dir_read)\n"); -#endif - } - - /* Now that we have the block for our entry, get the */ - /* directory entry. */ - if (bp == NULL) - { - fnp->f_flags.f_dfull = TRUE; - return 0; - } - - bp->b_flag &= ~(BFR_DATA | BFR_FAT); - bp->b_flag |= BFR_DIR | BFR_VALID; - - getdirent((BYTE FAR *) & bp->b_buffer[((UWORD)fnp->f_diroff) % fnp->f_dpb->dpb_secsize], - (struct dirent FAR *)&fnp->f_dir); - - /* Update the fnode's directory info */ - fnp->f_flags.f_dfull = FALSE; - fnp->f_flags.f_dmod = FALSE; - - /* and for efficiency, stop when we hit the first */ - /* unused entry. */ - if (fnp->f_dir.dir_name[0] == '\0') - return 0; - else - return DIRENT_SIZE; } + + /* Now that we have the block for our entry, get the */ + /* directory entry. */ + if (bp == NULL) + return DE_BLKINVLD; + + bp->b_flag &= ~(BFR_DATA | BFR_FAT); + bp->b_flag |= BFR_DIR | BFR_VALID; + + getdirent((BYTE FAR *) & bp->b_buffer[((UWORD)new_diroff) % fnp->f_dpb->dpb_secsize], + (struct dirent FAR *)&fnp->f_dir); + + /* Update the fnode's directory info */ + fnp->f_flags.f_dmod = FALSE; + fnp->f_flags.f_dnew = FALSE; + fnp->f_diroff = new_diroff; + + /* and for efficiency, stop when we hit the first */ + /* unused entry. */ + /* either returns 1 or 0 */ + return (fnp->f_dir.dir_name[0] != '\0'); } +/* Description. + * Writes directory entry pointed by fnp to disk. In case of erroneous + * situation fnode is released. + * Return value. + * TRUE - all OK. + * FALSE - error occured (fnode is released). + */ #ifndef IPL -COUNT dir_write(REG f_node_ptr fnp) +BOOL dir_write(REG f_node_ptr fnp) { struct buffer FAR *bp; REG UWORD secsize = fnp->f_dpb->dpb_secsize; @@ -539,19 +527,12 @@ COUNT dir_write(REG f_node_ptr fnp) #ifdef DISPLAY_GETBLOCK printf("dir_write: "); #endif - if (map_cluster(fnp, XFR_READ) != SUCCESS) - { - fnp->f_flags.f_dfull = TRUE; - release_f_node(fnp); - return 0; - } - - /* If the returned cluster is FREE, return zero */ - /* bytes read. */ - if (fnp->f_cluster == FREE) + /* If map_cluster gives an error or the returned cluster is FREE, + return FALSE */ + if (map_cluster(fnp, XFR_READ) != SUCCESS || fnp->f_cluster == FREE) { release_f_node(fnp); - return 0; + return FALSE; } /* Compute the block within the cluster and the */ @@ -560,10 +541,7 @@ COUNT dir_write(REG f_node_ptr fnp) fnp->f_boff = fnp->f_offset % secsize; /* Get the block we need from cache */ - bp = getblock((ULONG) clus2phys(fnp->f_cluster, - (fnp->f_dpb->dpb_clsmask + 1), - fnp->f_dpb->dpb_data) - + fnp->f_sector, + bp = getblock(clus2phys(fnp->f_cluster, fnp->f_dpb) + fnp->f_sector, fnp->f_dpb->dpb_unit); bp->b_flag &= ~(BFR_DATA | BFR_FAT); bp->b_flag |= BFR_DIR | BFR_VALID; @@ -577,7 +555,7 @@ COUNT dir_write(REG f_node_ptr fnp) if (bp == NULL) { release_f_node(fnp); - return 0; + return FALSE; } if (fnp->f_flags.f_dnew && fnp->f_dir.dir_attrib != D_LFN) @@ -588,7 +566,7 @@ COUNT dir_write(REG f_node_ptr fnp) bp->b_flag &= ~(BFR_DATA | BFR_FAT); bp->b_flag |= BFR_DIR | BFR_DIRTY | BFR_VALID; } - return DIRENT_SIZE; + return TRUE; } #endif @@ -643,24 +621,20 @@ COUNT dos_findfirst(UCOUNT attr, BYTE *name) printf("ff %s\n", local_ext); */ - /* Now build a directory. */ - if (!szDirName[2]) - fstrcpy(&szDirName[0], current_ldt->cdsCurrentPath); - /* Build the match pattern out of the passed string */ /* copy the part of the pattern which belongs to the filename and is fixed */ - for (p = local_name, i = 0; i < FNAME_SIZE && *p && *p != '*'; ++p, ++i) + for (p = local_name, i = 0; i < FNAME_SIZE && *p; ++p, ++i) SearchDir.dir_name[i] = *p; for (; i < FNAME_SIZE; ++i) - SearchDir.dir_name[i] = *p == '*' ? '?' : ' '; + SearchDir.dir_name[i] = ' '; /* and the extension (don't forget to add trailing spaces)... */ - for (p = local_ext, i = 0; i < FEXT_SIZE && *p && *p != '*'; ++p, ++i) + for (p = local_ext, i = 0; i < FEXT_SIZE && *p; ++p, ++i) SearchDir.dir_ext[i] = *p; for (; i < FEXT_SIZE; ++i) - SearchDir.dir_ext[i] = *p == '*' ? '?' : ' '; + SearchDir.dir_ext[i] = ' '; /* Convert everything to uppercase. */ DosUpFMem(SearchDir.dir_name, FNAME_SIZE + FEXT_SIZE); @@ -703,7 +677,7 @@ COUNT dos_findfirst(UCOUNT attr, BYTE *name) if (attr == D_VOLID) { /* Now do the search */ - while (dir_read(fnp) == DIRENT_SIZE) + while (dir_read(fnp) == 1) { /* Test the attribute and return first found */ if ((fnp->f_dir.dir_attrib & ~(D_RDONLY | D_ARCHIVE)) == D_VOLID) @@ -767,13 +741,13 @@ COUNT dos_findnext(void) return DE_NFILES; } - fnp->f_dsize = DIRENT_SIZE * (fnp->f_dpb)->dpb_dirents; + dir_init_fnode(fnp, dmp->dm_dircluster); /* Search through the directory to find the entry, but do a */ /* seek first. */ if (dmp->dm_entry > 0) { - fnp->f_diroff = (dmp->dm_entry - 1) * DIRENT_SIZE; + fnp->f_diroff = (ULONG)(dmp->dm_entry - 1) * DIRENT_SIZE; fnp->f_flags.f_dnew = FALSE; } else @@ -782,26 +756,8 @@ COUNT dos_findnext(void) fnp->f_flags.f_dnew = TRUE; } - fnp->f_offset = fnp->f_diroff; - - fnp->f_dir.dir_start = dmp->dm_dircluster; -#ifdef WITHFAT32 - fnp->f_dir.dir_start_high = dmp->dm_dircluster >> 16; -#endif - - fnp->f_cluster = fnp->f_dirstart = - dmp->dm_dircluster; - - fnp->f_flags.f_droot = fnp->f_dirstart == 0; - fnp->f_flags.f_ddir = TRUE; - - - fnp->f_flags.f_dfull = FALSE; - - fnp->f_cluster_offset = 0l; /*JPP */ - /* Loop through the directory */ - while (dir_read(fnp) == DIRENT_SIZE) + while (dir_read(fnp) == 1) { ++dmp->dm_entry; if (fnp->f_dir.dir_name[0] != '\0' && fnp->f_dir.dir_name[0] != DELETED diff --git a/kernel/fatfs.c b/kernel/fatfs.c index 28b2623..3da3c89 100644 --- a/kernel/fatfs.c +++ b/kernel/fatfs.c @@ -47,6 +47,9 @@ BYTE *RcsId = "$Id$"; * performance killer on large drives. (~0.5 sec /dos_mkdir) TE * * $Log$ + * Revision 1.25 2001/11/04 19:47:39 bartoldeman + * kernel 2025a changes: see history.txt + * * Revision 1.24 2001/09/23 20:39:44 bartoldeman * FAT32 support, misc fixes, INT2F/AH=12 support, drive B: handling * @@ -279,6 +282,18 @@ BOOL first_fat(f_node_ptr); COUNT map_cluster(f_node_ptr, COUNT); STATIC VOID shrink_file(f_node_ptr fnp); +ULONG clus2phys(CLUSTER cl_no, struct dpb FAR *dpbp) +{ + CLUSTER data = +#ifdef WITHFAT32 + ISFAT32(dpbp) ? + dpbp->dpb_xdata : +#endif + dpbp->dpb_data; + return ((ULONG)(cl_no - 2) << dpbp->dpb_shftcnt) + data; +} + + /************************************************************************/ /* */ /* Internal file handlers - open, create, read, write, close, etc. */ @@ -380,7 +395,6 @@ COUNT dos_close(COUNT fd) fnp->f_dir.dir_date = dos_getdate(); } - shrink_file(fnp); /* reduce allocated filesize in FAT */ fnp->f_dir.dir_size = fnp->f_highwater; merge_file_changes(fnp, FALSE); /* /// Added - Ron Cemer */ } @@ -469,7 +483,7 @@ STATIC BOOL find_fname(f_node_ptr fnp, BYTE * fname, BYTE * fext) { BOOL found = FALSE; - while (dir_read(fnp) == DIRENT_SIZE) + while (dir_read(fnp) == 1) { if (fnp->f_dir.dir_name[0] != '\0') { @@ -488,46 +502,26 @@ STATIC BOOL find_fname(f_node_ptr fnp, BYTE * fname, BYTE * fext) return found; } -/* STATIC BOOL find_full_fname(f_node_ptr fnp, f_node_ptr lfnp, BYTE * fname, - BYTE * fext) -{ - BOOL found = FALSE; - - lfnp->f_cluster = LONG_LAST_CLUSTER; - while (dir_read(fnp) == DIRENT_SIZE) - { - if (fnp->f_dir.dir_name[0] != '\0') - { - if (fnp->f_dir.dir_name[0] == DELETED) - continue; - - if (fnp->f_dir.dir_attrib != 0xf) lfnp->f_cluster = LONG_LAST_CLUSTER; - else if (lfnp->f_cluster == LONG_LAST_CLUSTER) - memcpy(lfnp, struct fnp, sizeof(f_node)); - - if (fcmp(fname, (BYTE *)fnp->f_dir.dir_name, FNAME_SIZE) - && fcmp(fext, (BYTE *)fnp->f_dir.dir_ext, FEXT_SIZE) - && ((fnp->f_dir.dir_attrib & D_VOLID) == 0)) - { - found = TRUE; - break; - } - } - } - return found; -} */ - -/* input: fnp with valid non-LFN directory entry, not equal to '..' or -'.' */ -void remove_lfn_entries(f_node_ptr fnp) +/* Description. + * Remove entries with D_LFN attribute preceeding the directory entry + * pointed by fnp, fnode isn't modified (I hope). + * Return value. + * SUCCESS - completed successfully. + * ERROR - error occured. + * input: fnp with valid non-LFN directory entry, not equal to '..' or + * '.' + */ +COUNT remove_lfn_entries(f_node_ptr fnp) { ULONG original_diroff = fnp->f_diroff; + COUNT rc; + while (TRUE) { if(fnp->f_diroff == 0) break; fnp->f_diroff -= 2*DIRENT_SIZE; - /* it cannot / should not get below 0 because of '.' and '..' - but maybe add another check for robustness */ - dir_read(fnp); + /* it cannot / should not get below 0 because of '.' and '..' */ + if ((rc = dir_read(fnp)) < 0) + return rc; if (fnp->f_dir.dir_attrib != D_LFN) break; fnp->f_dir.dir_name[0] = DELETED; @@ -535,7 +529,9 @@ void remove_lfn_entries(f_node_ptr fnp) dir_write(fnp); } fnp->f_diroff = original_diroff - DIRENT_SIZE; - dir_read(fnp); + if ((rc = dir_read(fnp)) < 0) + return rc; + return SUCCESS; } /* /// Added - Ron Cemer */ /* If more than one f_node has a file open, and a write @@ -590,7 +586,6 @@ STATIC int is_same_file(f_node_ptr fnp1, f_node_ptr fnp2) { (BYTE *)fnp2->f_dir.dir_ext, FEXT_SIZE)) && ((fnp1->f_dir.dir_attrib & D_VOLID) == 0) && ((fnp2->f_dir.dir_attrib & D_VOLID) == 0) - && (fnp1->f_flags.f_dremote == fnp2->f_flags.f_dremote) && (fnp1->f_diroff == fnp2->f_diroff) && (fnp1->f_dirstart == fnp2->f_dirstart) && (fnp1->f_dpb == fnp2->f_dpb); @@ -612,13 +607,7 @@ COUNT dos_creat(BYTE * path, COUNT attrib) { REG f_node_ptr fnp; - /* NEVER EVER allow directories to be created */ - if (attrib & ~(D_RDONLY|D_HIDDEN|D_SYSTEM|D_ARCHIVE)) - { - return DE_ACCESS; - } - - /* first split the passed dir into comopnents (i.e. - */ + /* first split the passed dir into components (i.e. - */ /* path to new directory and name of new directory */ if ((fnp = split_path(path, szFileName, szFileExt)) == NULL) { @@ -692,7 +681,7 @@ COUNT dos_creat(BYTE * path, COUNT attrib) fnp->f_flags.f_ddate = FALSE; fnp->f_flags.f_dnew = FALSE; fnp->f_flags.f_ddir = TRUE; - if (dir_write(fnp) != DIRENT_SIZE) + if (!dir_write(fnp)) { release_f_node(fnp); return DE_ACCESS; @@ -716,6 +705,29 @@ COUNT dos_creat(BYTE * path, COUNT attrib) return xlt_fnp(fnp); } +STATIC COUNT delete_dir_entry(f_node_ptr fnp) +{ + COUNT rc; + + /* Ok, so we can delete. Start out by */ + /* clobbering all FAT entries for this file */ + /* (or, in English, truncate the FAT). */ + if ((rc=remove_lfn_entries(fnp)) < 0) + return rc; + + wipe_out(fnp); + *(fnp->f_dir.dir_name) = DELETED; + + /* The directory has been modified, so set the */ + /* bit before closing it, allowing it to be */ + /* updated */ + fnp->f_flags.f_dmod = TRUE; + dir_close(fnp); + + /* SUCCESSful completion, return it */ + return SUCCESS; +} + COUNT dos_delete(BYTE * path) { REG f_node_ptr fnp; @@ -741,22 +753,7 @@ COUNT dos_delete(BYTE * path) return DE_ACCESS; } - /* Ok, so we can delete. Start out by */ - /* clobbering all FAT entries for this file */ - /* (or, in English, truncate the FAT). */ - remove_lfn_entries(fnp); - wipe_out(fnp); - fnp->f_dir.dir_size = 0l; - *(fnp->f_dir.dir_name) = DELETED; - - /* The directory has been modified, so set the */ - /* bit before closing it, allowing it to be */ - /* updated */ - fnp->f_flags.f_dmod = TRUE; - dir_close(fnp); - - /* SUCCESSful completion, return it */ - return SUCCESS; + return delete_dir_entry(fnp); } else { @@ -826,7 +823,7 @@ COUNT dos_rmdir(BYTE * path) /* Now search through the directory and make certain */ /* that there are no entries. */ found = FALSE; - while (dir_read(fnp1) == DIRENT_SIZE) + while (dir_read(fnp1) == 1) { if (fnp1->f_dir.dir_name[0] == '\0') break; @@ -846,23 +843,7 @@ COUNT dos_rmdir(BYTE * path) dir_close(fnp); return DE_ACCESS; } - - /* Ok, so we can delete. Start out by */ - /* clobbering all FAT entries for this file */ - /* (or, in English, truncate the FAT). */ - remove_lfn_entries(fnp); - wipe_out(fnp); - fnp->f_dir.dir_size = 0l; - *(fnp->f_dir.dir_name) = DELETED; - - /* The directory has been modified, so set the */ - /* bit before closing it, allowing it to be */ - /* updated */ - fnp->f_flags.f_dmod = TRUE; - dir_close(fnp); - - /* SUCCESSful completion, return it */ - return SUCCESS; + return delete_dir_entry(fnp); } else { @@ -877,6 +858,7 @@ COUNT dos_rename(BYTE * path1, BYTE * path2) REG f_node_ptr fnp1; REG f_node_ptr fnp2; BOOL is_free; + COUNT ret; /* first split the passed target into compnents (i.e. - path to */ /* new file name and name of new file name */ @@ -927,15 +909,15 @@ COUNT dos_rename(BYTE * path1, BYTE * path2) /* Otherwise just expand the directory */ else if (!is_free && !(fnp2->f_flags.f_droot)) { - COUNT ret; - if ((ret = extend_dir(fnp2)) != SUCCESS) { dir_close(fnp1); return ret; } } - remove_lfn_entries(fnp1); + + if ((ret=remove_lfn_entries(fnp1)) < 0) + return ret; /* put the fnode's name into the directory. */ bcopy(szFileName, (BYTE *)fnp2->f_dir.dir_name, FNAME_SIZE); @@ -960,7 +942,6 @@ COUNT dos_rename(BYTE * path1, BYTE * path2) fnp2->f_highwater = fnp2->f_offset = fnp1->f_dir.dir_size; /* Ok, so we can delete this one. Save the file info. */ - fnp1->f_dir.dir_size = 0l; *(fnp1->f_dir.dir_name) = DELETED; dir_close(fnp1); @@ -971,23 +952,16 @@ COUNT dos_rename(BYTE * path1, BYTE * path2) } /* */ -/* wipe out all FAT entries for create, delete, etc. */ +/* wipe out all FAT entries starting from st for create, delete, etc. */ /* */ -STATIC VOID wipe_out(f_node_ptr fnp) +STATIC VOID wipe_out_clusters(struct dpb FAR *dpbp, CLUSTER st) { - REG CLUSTER st, - next; - struct dpb FAR *dpbp = fnp->f_dpb; + REG CLUSTER next; - /* if already free or not valid file, just exit */ - if ((fnp == NULL) || checkdstart(fnp->f_dir, FREE)) - return; - /* Loop from start until either a FREE entry is */ /* encountered (due to a fractured file system) of the */ /* last cluster is encountered. */ - for (st = getdstart(fnp->f_dir); - st != LONG_LAST_CLUSTER;) + while (st != LONG_LAST_CLUSTER) { /* get the next cluster pointed to */ next = next_cluster(dpbp, st); @@ -1000,6 +974,14 @@ STATIC VOID wipe_out(f_node_ptr fnp) link_fat(dpbp, st, FREE); /* and the start of free space pointer */ +#ifdef WITHFAT32 + if (ISFAT32(dpbp)) + { + if ((dpbp->dpb_xcluster == UNKNCLUSTER) + || (dpbp->dpb_xcluster > st)) + dpbp->dpb_xcluster = st; + } else +#endif if ((dpbp->dpb_cluster == UNKNCLUSTER) || (dpbp->dpb_cluster > st)) dpbp->dpb_cluster = st; @@ -1012,17 +994,26 @@ STATIC VOID wipe_out(f_node_ptr fnp) #endif } +/* */ +/* wipe out all FAT entries for create, delete, etc. */ +/* */ +STATIC VOID wipe_out(f_node_ptr fnp) +{ + /* if already free or not valid file, just exit */ + if ((fnp == NULL) || checkdstart(fnp->f_dir, FREE)) + return; + + wipe_out_clusters(fnp->f_dpb, getdstart(fnp->f_dir)); +} + STATIC BOOL find_free(f_node_ptr fnp) { - while (dir_read(fnp) == DIRENT_SIZE) - { - if (fnp->f_dir.dir_name[0] == '\0' - || fnp->f_dir.dir_name[0] == DELETED) - { + COUNT rc; + + while ((rc = dir_read(fnp)) == 1) + if (fnp->f_dir.dir_name[0] == DELETED) return TRUE; - } - } - return !fnp->f_flags.f_dfull; + return rc >= 0; } /* */ @@ -1199,45 +1190,69 @@ BOOL dos_setfsize(COUNT fd, LONG size) /* */ STATIC CLUSTER find_fat_free(f_node_ptr fnp) { - REG CLUSTER idx; + REG CLUSTER idx, size; + struct dpb FAR *dpbp = fnp->f_dpb; #ifdef DISPLAY_GETBLOCK printf("[find_fat_free]\n"); #endif - /* Start from optimized lookup point for start of FAT */ - if (fnp->f_dpb->dpb_cluster != UNKNCLUSTER) - idx = fnp->f_dpb->dpb_cluster; - else - idx = 2; + /* Start from optimized lookup point for start of FAT */ + idx = 2; + size = dpbp->dpb_size; + +#ifdef WITHFAT32 + if (ISFAT32(dpbp)) + { + if (dpbp->dpb_xcluster != UNKNCLUSTER) + idx = dpbp->dpb_xcluster; + size = dpbp->dpb_xsize; + } else +#endif + if (dpbp->dpb_cluster != UNKNCLUSTER) + idx = dpbp->dpb_cluster; /* Search the FAT table looking for the first free */ /* entry. */ - for (; idx <= fnp->f_dpb->dpb_size; idx++) + for (; idx <= size; idx++) { - if (next_cluster(fnp->f_dpb, idx) == FREE) + if (next_cluster(dpbp, idx) == FREE) break; } /* No empty clusters, disk is FULL! */ - if (idx > fnp->f_dpb->dpb_size) - { - fnp->f_dpb->dpb_cluster = UNKNCLUSTER; #ifdef WITHFAT32 - if (ISFAT32(fnp->f_dpb)) write_fsinfo(fnp->f_dpb); -#endif + if (ISFAT32(dpbp)) + { + if (idx > dpbp->dpb_xsize) + { + dpbp->dpb_xcluster = UNKNCLUSTER; + write_fsinfo(dpbp); + dir_close(fnp); + return LONG_LAST_CLUSTER; + } + if (dpbp->dpb_xnfreeclst != XUNKNCLSTFREE) + dpbp->dpb_xnfreeclst--; /* TE: moved from link_fat() */ + + /* return the free entry */ + dpbp->dpb_xcluster = idx; + write_fsinfo(dpbp); + return idx; + } +#endif + + if (idx > dpbp->dpb_size) + { + dpbp->dpb_cluster = UNKNCLUSTER; dir_close(fnp); return LONG_LAST_CLUSTER; } - if (fnp->f_dpb->dpb_nfreeclst != UNKNCLSTFREE) - fnp->f_dpb->dpb_nfreeclst--; /* TE: moved from link_fat() */ + if (dpbp->dpb_nfreeclst != UNKNCLSTFREE) + dpbp->dpb_nfreeclst--; /* TE: moved from link_fat() */ /* return the free entry */ - fnp->f_dpb->dpb_cluster = idx; -#ifdef WITHFAT32 - if (ISFAT32(fnp->f_dpb)) write_fsinfo(fnp->f_dpb); -#endif + dpbp->dpb_cluster = idx; return idx; } @@ -1250,6 +1265,7 @@ COUNT dos_mkdir(BYTE * dir) REG f_node_ptr fnp; REG COUNT idx; struct buffer FAR *bp; + struct dpb FAR *dpbp; CLUSTER free_fat, parent; COUNT ret; @@ -1273,10 +1289,6 @@ COUNT dos_mkdir(BYTE * dir) dir_close(fnp); return DE_PATHNOTFND; } - - - - /* Check that we don't have a duplicate name, so if we */ /* find one, it's an error. */ @@ -1286,7 +1298,6 @@ COUNT dos_mkdir(BYTE * dir) return DE_ACCESS; } - /* Reset the directory by a close followed by */ /* an open */ fnp->f_flags.f_dmod = FALSE; @@ -1353,15 +1364,14 @@ COUNT dos_mkdir(BYTE * dir) /* Mark the cluster in the FAT as used */ fnp->f_cluster = free_fat; setdstart(fnp->f_dir, free_fat); - link_fat(fnp->f_dpb, free_fat, LONG_LAST_CLUSTER); + dpbp = fnp->f_dpb; + link_fat(dpbp, free_fat, LONG_LAST_CLUSTER); /* Craft the new directory. Note that if we're in a new */ /* directory just under the root, ".." pointer is 0. */ /* as we are overwriting it completely, don't read first */ - bp = getblockOver((ULONG) clus2phys(free_fat, - (fnp->f_dpb->dpb_clsmask + 1), - fnp->f_dpb->dpb_data), - fnp->f_dpb->dpb_unit); + bp = getblockOver(clus2phys(free_fat, dpbp), + dpbp->dpb_unit); #ifdef DISPLAY_GETBLOCK printf("FAT (dos_mkdir)\n"); #endif @@ -1386,7 +1396,7 @@ COUNT dos_mkdir(BYTE * dir) /* create the ".." entry */ bcopy(".. ", (BYTE *) DirEntBuffer.dir_name, FNAME_SIZE); #ifdef WITHFAT32 - if (ISFAT32(fnp->f_dpb) && parent == fnp->f_dpb->dpb_xrootclst) { + if (ISFAT32(dpbp) && parent == dpbp->dpb_xrootclst) { parent = 0; } #endif @@ -1402,14 +1412,12 @@ COUNT dos_mkdir(BYTE * dir) bp->b_flag |= BFR_DIRTY | BFR_VALID; /* clear out the rest of the blocks in the cluster */ - for (idx = 1; idx < (fnp->f_dpb->dpb_clsmask + 1); idx++) + for (idx = 1; idx <= dpbp->dpb_clsmask; idx++) { /* as we are overwriting it completely, don't read first */ - bp = getblockOver((ULONG) clus2phys(getdstart(fnp->f_dir), - (fnp->f_dpb->dpb_clsmask + 1), - fnp->f_dpb->dpb_data) + idx, - fnp->f_dpb->dpb_unit); + bp = getblockOver(clus2phys(getdstart(fnp->f_dir), dpbp) + idx, + dpbp->dpb_unit); #ifdef DISPLAY_GETBLOCK printf("DIR (dos_mkdir)\n"); #endif @@ -1424,7 +1432,7 @@ COUNT dos_mkdir(BYTE * dir) } /* flush the drive buffers so that all info is written */ - flush_buffers((COUNT) (fnp->f_dpb->dpb_unit)); + flush_buffers((COUNT) (dpbp->dpb_unit)); /* Close the directory so that the entry is updated */ fnp->f_flags.f_dmod = TRUE; @@ -1474,24 +1482,22 @@ STATIC COUNT extend_dir(f_node_ptr fnp) return DE_HNDLDSKFULL; } - /* clear out the rest of the blocks in the cluster */ - for (idx = 0; idx < (fnp->f_dpb->dpb_clsmask + 1); idx++) + /* clear out the blocks in the cluster */ + for (idx = 0; idx <= fnp->f_dpb->dpb_clsmask; idx++) { REG struct buffer FAR *bp; - bp = getblockOver((ULONG) clus2phys(fnp->f_cluster, - (fnp->f_dpb->dpb_clsmask + 1), - fnp->f_dpb->dpb_data) + idx, - fnp->f_dpb->dpb_unit); + /* as we are overwriting it completely, don't read first */ + bp = getblockOver(clus2phys(fnp->f_cluster, fnp->f_dpb) + idx, + fnp->f_dpb->dpb_unit); #ifdef DISPLAY_GETBLOCK printf("DIR (extend_dir)\n"); #endif - if (bp == NULL) - { + if (bp == NULL) { dir_close(fnp); return DE_BLKINVLD; } - fmemset(bp->b_buffer,0, BUFFERSIZE); + fmemset(bp->b_buffer, 0, BUFFERSIZE); bp->b_flag |= BFR_DIRTY | BFR_VALID; if (idx != 0) @@ -1556,7 +1562,7 @@ COUNT map_cluster(REG f_node_ptr fnp, COUNT mode) #endif /* The variable clssize will be used later. */ - clssize = (ULONG)fnp->f_dpb->dpb_secsize * (fnp->f_dpb->dpb_clsmask + 1); + clssize = (ULONG)fnp->f_dpb->dpb_secsize << fnp->f_dpb->dpb_shftcnt; /* If someone did a seek, but no writes have occured, we will */ /* need to initialize the fnode. */ @@ -1605,7 +1611,7 @@ COUNT map_cluster(REG f_node_ptr fnp, COUNT mode) if (!extend(fnp)) { dir_close(fnp); - return DE_HNDLDSKFULL; + return DE_HNDLDSKFULL; } } fnp->f_back = fnp->f_cluster; @@ -1622,6 +1628,72 @@ COUNT map_cluster(REG f_node_ptr fnp, COUNT mode) return SUCCESS; } +/* + comments read optimization for large reads: read total clusters in one piece + + running a program like + + while (1) { + read(fd, header, sizeof(header)); // small read + read(fd, buffer, header.size); // where size is large, up to 63K + // with average ~32K + } + + FreeDOS 2025 is really slow. + on a P200 with modern 30GB harddisk, doing above for a 14.5 MB file + + MSDOS 6.22 clustersize 8K ~2.5 sec (accumulates over clusters, reads for 63 sectors seen), + IBM PCDOS 7.0 8K ~4.3 + IBM PCDOS 7.0 16K ~2.8 + FreeDOS ke2025 ~17.5 + + with the read optimization (ke2025a), + + clustersize 8K ~6.5 sec + clustersize 16K ~4.2 sec + + it was verified with IBM feature tool, + that the drive read ahead cache (says it) is on. still this huge difference ;-) + + + it's coded pretty conservative to avoid all special cases, + so it shouldn't break anything :-) + + possible further optimization: + + collect read across clusters (if file is not fragmented). + MSDOS does this (as readcounts up to 63 sectors where seen) + specially important for diskettes, where clustersize is 1 sector + + the same should be done for writes as well + + + the time to compile the complete kernel (on some P200) is + reduced from 67 to 56 seconds - in an otherwise identical configuration. + + it's not clear if this improvement shows up elsewhere, but it shouldn't harm either + + + TE 10/18/01 14:00 + + collect read across clusters (if file is not fragmented) done. + + seems still to work :-)) + + no large performance gains visible, but should now work _much_ + better for the people, that complain about slow floppy access + + the + fnp->f_offset +to_xfer < fnp->f_highwater && avoid EOF problems + + condition can probably _carefully_ be dropped + + + TE 10/18/01 19:00 + +*/ + + /* Read block from disk */ UCOUNT readblock(COUNT fd, VOID FAR * buffer, UCOUNT count, COUNT * err) { @@ -1631,6 +1703,7 @@ UCOUNT readblock(COUNT fd, VOID FAR * buffer, UCOUNT count, COUNT * err) UCOUNT ret_cnt = 0; UWORD secsize; UCOUNT to_xfer = count; + ULONG currentblock; #if defined( DEBUG ) && 0 if (bDumpRdWrParms) @@ -1734,8 +1807,8 @@ UCOUNT readblock(COUNT fd, VOID FAR * buffer, UCOUNT count, COUNT * err) return ret_cnt; default: - dir_close(fnp); *err = DE_HNDLDSKFULL; + dir_close(fnp); return ret_cnt; case SUCCESS: @@ -1744,10 +1817,84 @@ UCOUNT readblock(COUNT fd, VOID FAR * buffer, UCOUNT count, COUNT * err) } /* Compute the block within the cluster and the offset */ - /* within the block. */ + /* within the block. */ fnp->f_sector = (fnp->f_offset / secsize) & fnp->f_dpb->dpb_clsmask; fnp->f_boff = fnp->f_offset & (secsize - 1); + + + + currentblock = clus2phys(fnp->f_cluster, fnp->f_dpb) + fnp->f_sector; + + /* see comments above */ + + if (!fnp->f_flags.f_ddir && /* don't experiment with directories yet */ + fnp->f_boff == 0 ) /* complete sectors only */ + { + static ULONG startoffset; + UCOUNT sectors_to_read,sectors_wanted; + + + startoffset = fnp->f_offset; + + /* avoid EOF problems */ + sectors_wanted = ((UCOUNT) min(fnp->f_highwater - fnp->f_offset, to_xfer)) / + secsize; + + if (sectors_wanted < 2) + goto normal_read; + + sectors_to_read = fnp->f_dpb->dpb_clsmask + 1 - fnp->f_sector; + + sectors_to_read = min(sectors_to_read, sectors_wanted); + + fnp->f_offset += sectors_to_read*secsize; + + while (sectors_to_read < sectors_wanted) + { + if (map_cluster(fnp, XFR_READ) != SUCCESS) + break; + + if (clus2phys(fnp->f_cluster, fnp->f_dpb) != currentblock + sectors_to_read) + break; + + sectors_to_read += fnp->f_dpb->dpb_clsmask + 1; + + sectors_to_read = min(sectors_to_read, sectors_wanted); + + fnp->f_offset = startoffset + sectors_to_read*secsize; + + } + + xfr_cnt = sectors_to_read * secsize; + + /* avoid caching trouble */ + + DeleteBlockInBufferCache(currentblock, + currentblock + sectors_to_read - 1, + fnp->f_dpb->dpb_unit); + + if (dskxfer(fnp->f_dpb->dpb_unit, + currentblock, + (VOID FAR *) buffer, sectors_to_read, DSKREAD)) + { + fnp->f_offset = startoffset; + *err = DE_BLKINVLD; + return ret_cnt; + } + + + goto update_pointers; + } + + + + + + /* normal read: just the old, buffer = sector based read */ +normal_read: + + #ifdef DSK_DEBUG printf("read %d links; dir offset %ld, cluster %lx\n", fnp->f_count, @@ -1764,9 +1911,7 @@ UCOUNT readblock(COUNT fd, VOID FAR * buffer, UCOUNT count, COUNT * err) } /* Get the block we need from cache */ - bp = getblock((ULONG) clus2phys(fnp->f_cluster, - (fnp->f_dpb->dpb_clsmask + 1), - fnp->f_dpb->dpb_data) + fnp->f_sector, + bp = getblock(currentblock /*clus2phys(fnp->f_cluster, fnp->f_dpb) + fnp->f_sector*/, fnp->f_dpb->dpb_unit); #ifdef DISPLAY_GETBLOCK @@ -1800,16 +1945,115 @@ UCOUNT readblock(COUNT fd, VOID FAR * buffer, UCOUNT count, COUNT * err) bp->b_flag |= BFR_UNCACHE; } + /* update pointers and counters */ + fnp->f_offset += xfr_cnt; + +update_pointers: ret_cnt += xfr_cnt; to_xfer -= xfr_cnt; - fnp->f_offset += xfr_cnt; buffer = add_far((VOID FAR *) buffer, (ULONG) xfr_cnt); } *err = SUCCESS; return ret_cnt; } +/* extends a file from f_highwater to f_offset */ +/* Proper OS's write zeros in between, but DOS just adds */ +/* garbage sectors, and lets the caller do the zero filling */ +/* if you prefer you can have this enabled using */ +/* #define WRITEZEROS 1 */ +/* but because we want to be compatible, we don't do this by */ +/* default */ +STATIC COUNT dos_extend(f_node_ptr fnp) +{ +#ifdef WRITEZEROS + struct buffer FAR *bp; + UCOUNT xfr_cnt = 0; + /* The variable secsize will be used later. */ + UWORD secsize = fnp->f_dpb->dpb_secsize; + ULONG count; +#endif + + if (fnp->f_offset <= fnp->f_highwater) + return SUCCESS; + +#ifdef WRITEZEROS + count = fnp->f_offset - fnp->f_highwater; + fnp->f_offset = fnp->f_highwater; + while (count > 0) + { +#endif + switch (map_cluster(fnp, XFR_WRITE)) + { + case DE_SEEK: + dir_close(fnp); + return DE_SEEK; + + default: + dir_close(fnp); + return DE_HNDLDSKFULL; + + case SUCCESS: + merge_file_changes(fnp, FALSE); /* /// Added - Ron Cemer */ + break; + } + +#ifdef WRITEZEROS + /* Compute the block within the cluster and the offset */ + /* within the block. */ + fnp->f_sector = + (fnp->f_offset / secsize) & fnp->f_dpb->dpb_clsmask; + fnp->f_boff = fnp->f_offset & (secsize - 1); + +#ifdef DSK_DEBUG + printf("write %d links; dir offset %ld, cluster %d\n", + fnp->f_count, + fnp->f_diroff, + fnp->f_cluster); +#endif + + xfr_cnt = count < (ULONG)secsize - fnp->f_boff ? + (UWORD) count : + secsize - fnp->f_boff; + + /* get a buffer to store the block in */ + if ( (fnp->f_boff == 0) && (xfr_cnt == secsize) ) { + bp = getblockOver(clus2phys(fnp->f_cluster, fnp->f_dpb) + fnp->f_sector, + fnp->f_dpb->dpb_unit); + + } else { + bp = getblock(clus2phys(fnp->f_cluster, fnp->f_dpb) + fnp->f_sector, + fnp->f_dpb->dpb_unit); + } + if (bp == NULL) { + return DE_BLKINVLD; + } + + + /* set a block to zero */ + fmemset((BYTE FAR *) & bp->b_buffer[fnp->f_boff], 0, xfr_cnt); + bp->b_flag |= BFR_DIRTY | BFR_VALID; + + if (xfr_cnt == sizeof(bp->b_buffer)) /* probably not used later */ + { + bp->b_flag |= BFR_UNCACHE; + } + + /* update pointers and counters */ + count -= xfr_cnt; + fnp->f_offset += xfr_cnt; + fnp->f_highwater = fnp->f_offset; + fnp->f_dir.dir_size = fnp->f_highwater; + merge_file_changes(fnp, FALSE); /* /// Added - Ron Cemer */ + } +#else + fnp->f_highwater = fnp->f_offset; + merge_file_changes(fnp, FALSE); /* /// Added - Ron Cemer */ +#endif + return SUCCESS; +} + /* Write block to disk */ UCOUNT writeblock(COUNT fd, VOID FAR * buffer, UCOUNT count, COUNT * err) { @@ -1827,6 +2071,7 @@ UCOUNT writeblock(COUNT fd, VOID FAR * buffer, UCOUNT count, COUNT * err) fd, (COUNT) FP_SEG(buffer), (COUNT) FP_OFF(buffer), count); } #endif + /* Translate the fd into an fnode pointer, since all internal */ /* operations are achieved through fnodes. */ fnp = xlt_fd(fd); @@ -1840,8 +2085,6 @@ UCOUNT writeblock(COUNT fd, VOID FAR * buffer, UCOUNT count, COUNT * err) return 0; } -/* /// BUG!!! Moved from below next block because we should NOT be able - to truncate the file if we can't write to it. - Ron Cemer */ /* test that we have a valid mode for this fnode */ if (fnp->f_mode != WRONLY && fnp->f_mode != RDWR) { @@ -1852,7 +2095,11 @@ UCOUNT writeblock(COUNT fd, VOID FAR * buffer, UCOUNT count, COUNT * err) fnp->f_flags.f_dmod = TRUE; /* mark file as modified */ fnp->f_flags.f_ddate = FALSE; /* set date not valid any more */ - + /* extend file from fnp->f_highwater to fnp->f_offset */ + *err = dos_extend(fnp); + if (*err != SUCCESS) + return 0; + /* Test that we are really about to do a data transfer. If the */ /* count is zero and the mode is XFR_READ, just exit. (Any */ /* read with a count of zero is a nop). */ @@ -1866,43 +2113,12 @@ UCOUNT writeblock(COUNT fd, VOID FAR * buffer, UCOUNT count, COUNT * err) { /* NOTE: doing this up front made a lot of headaches later :-( TE */ /* FAT allocation has to be extended if necessary TE */ - - *err = SUCCESS; - if (fnp->f_highwater < fnp->f_offset) - { - switch (map_cluster(fnp, XFR_WRITE)) - { - case DE_SEEK: - *err = DE_SEEK; - dir_close(fnp); - break; - - default: - dir_close(fnp); - *err = DE_HNDLDSKFULL; - break; - - case SUCCESS: - break; - } - } - - fnp->f_highwater = fnp->f_offset; - merge_file_changes(fnp, FALSE); /* /// Added - Ron Cemer */ + /* Now done in dos_extend BO */ + /* remove all the following allocated clusters in shrink_file */ + shrink_file(fnp); return 0; } -/* /// BUG!!! Moved to above previous block because we should NOT be able - to truncate the file if we can't write to it. - Ron Cemer */ - /* test that we have a valid mode for this fnode */ -/* - if (fnp->f_mode != WRONLY && fnp->f_mode != RDWR) - { - *err = DE_INVLDACC; - return 0; - } -*/ - /* The variable secsize will be used later. */ secsize = fnp->f_dpb->dpb_secsize; @@ -1989,7 +2205,7 @@ UCOUNT writeblock(COUNT fd, VOID FAR * buffer, UCOUNT count, COUNT * err) if (!extend(fnp)) { dir_close(fnp); - *err = DE_HNDLDSKFULL; + *err = DE_HNDLDSKFULL; return ret_cnt; } merge_file_changes(fnp, FALSE); /* /// Added - Ron Cemer */ @@ -2030,15 +2246,11 @@ UCOUNT writeblock(COUNT fd, VOID FAR * buffer, UCOUNT count, COUNT * err) potential problems. - Ron Cemer */ if ( (fnp->f_boff == 0) && (xfr_cnt == secsize) ) { - bp = getblockOver((ULONG) clus2phys(fnp->f_cluster, - (fnp->f_dpb->dpb_clsmask + 1), - fnp->f_dpb->dpb_data) + fnp->f_sector, + bp = getblockOver(clus2phys(fnp->f_cluster, fnp->f_dpb) + fnp->f_sector, fnp->f_dpb->dpb_unit); } else { - bp = getblock((ULONG) clus2phys(fnp->f_cluster, - (fnp->f_dpb->dpb_clsmask + 1), - fnp->f_dpb->dpb_data) + fnp->f_sector, + bp = getblock(clus2phys(fnp->f_cluster, fnp->f_dpb) + fnp->f_sector, fnp->f_dpb->dpb_unit); } if (bp == NULL) { @@ -2082,59 +2294,6 @@ UCOUNT writeblock(COUNT fd, VOID FAR * buffer, UCOUNT count, COUNT * err) return ret_cnt; } -COUNT dos_read(COUNT fd, VOID FAR * buffer, UCOUNT count) -{ - COUNT err; - UCOUNT xfr; - - xfr = readblock(fd, buffer, count, &err); - return err != SUCCESS ? err : xfr; -} - -#ifndef IPL -COUNT dos_write(COUNT fd, VOID FAR * buffer, UCOUNT count) -{ - REG f_node_ptr fnp; - COUNT err, - xfr; - - /* First test if we need to fill to new EOF. */ - - /* Translate the fd into an fnode pointer, since all internal */ - /* operations are achieved through fnodes. */ - fnp = xlt_fd(fd); - - /* If the fd was invalid because it was out of range or the */ - /* requested file was not open, tell the caller and exit */ - /* note: an invalid fd is indicated by a 0 return */ - if (fnp == (f_node_ptr)0 || fnp->f_count <= 0) - { - return DE_INVLDHNDL; - } - - /* Future note: for security purposes, this should be set to */ - /* blocks of 0. This satisfies spec and guarantees no secure */ - /* info is written to disk. */ - /* Also, with real memory management, this may cause a page */ - /* fault. */ - if (fnp->f_offset > fnp->f_highwater) - { - ULONG lCount = fnp->f_offset - fnp->f_highwater; - - while (lCount > 0) - { - writeblock(fd, buffer, - lCount > 512l ? 512 : (UCOUNT) lCount, - &err); - lCount -= 512; - } - } - - xfr = writeblock(fd, buffer, count, &err); - return err != SUCCESS ? err : xfr; -} -#endif - /* Position the file pointer to the desired offset */ /* Returns a long current offset or a negative error code */ LONG dos_lseek(COUNT fd, LONG foffset, COUNT origin) @@ -2181,31 +2340,34 @@ CLUSTER dos_free(struct dpb FAR *dpbp) /* cluster start at 2 and run to max_cluster+2 */ REG CLUSTER i; REG CLUSTER cnt = 0; -/* UWORD max_cluster = ( ((ULONG) dpbp->dpb_size - * * (ULONG) (dpbp->dpb_clsmask + 1) - (dpbp->dpb_data + 1) ) - * / (dpbp->dpb_clsmask + 1) ) + 2; - */ + CLUSTER max_cluster = dpbp->dpb_size + 1; -/*?? UWORD max_cluster = ( ((ULONG) dpbp->dpb_size * (ULONG) (dpbp->dpb_clsmask + 1)) - / (dpbp->dpb_clsmask + 1) ) + 1; -*/ - CLUSTER max_cluster = dpbp->dpb_size + 1; - - if (dpbp->dpb_nfreeclst != UNKNCLSTFREE) - return dpbp->dpb_nfreeclst; - else - { - for (i = 2; i < max_cluster; i++) - { - if (next_cluster(dpbp, i) == 0) - ++cnt; - } - dpbp->dpb_nfreeclst = cnt; #ifdef WITHFAT32 - if (ISFAT32(dpbp)) write_fsinfo(dpbp); -#endif + if (ISFAT32(dpbp)) + { + if (dpbp->dpb_xnfreeclst != XUNKNCLSTFREE) + return dpbp->dpb_xnfreeclst; + max_cluster = dpbp->dpb_xsize + 1; + } + else +#endif + if (dpbp->dpb_nfreeclst != UNKNCLSTFREE) + return dpbp->dpb_nfreeclst; + + for (i = 2; i < max_cluster; i++) + { + if (next_cluster(dpbp, i) == 0) + ++cnt; + } +#ifdef WITHFAT32 + if (ISFAT32(dpbp)) { + dpbp->dpb_xnfreeclst = cnt; + write_fsinfo(dpbp); return cnt; } +#endif + dpbp->dpb_nfreeclst = cnt; + return cnt; } @@ -2215,22 +2377,19 @@ COUNT dos_cd(struct cds FAR * cdsp, BYTE *PathName) { f_node_ptr fnp; - /* first check for valid drive */ - if (cdsp->cdsDpb == 0) - return DE_INVLDDRV; + /* first check for valid drive */ + if (cdsp->cdsDpb == 0) + return DE_INVLDDRV; - if ((media_check(cdsp->cdsDpb) < 0)) - return DE_INVLDDRV; + if ((media_check(cdsp->cdsDpb) < 0)) + return DE_INVLDDRV; /* now test for its existance. If it doesn't, return an error. */ - /* If it does, copy the path to the current directory */ - /* structure. */ if ((fnp = dir_open(PathName)) == NULL) return DE_PATHNOTFND; cdsp->cdsStrtClst = fnp->f_dirstart; dir_close(fnp); - fstrncpy(cdsp->cdsCurrentPath,&PathName[0],sizeof(cdsp->cdsCurrentPath)-1); return SUCCESS; } #endif @@ -2342,7 +2501,7 @@ VOID bpb_to_dpb(bpb FAR *bpbp, REG struct dpb FAR * dpbp) #endif { ULONG size; - REG COUNT i; + REG UWORD shftcnt; dpbp->dpb_mdb = bpbp->bpb_mdesc; dpbp->dpb_secsize = bpbp->bpb_nbyte; @@ -2353,37 +2512,36 @@ VOID bpb_to_dpb(bpb FAR *bpbp, REG struct dpb FAR * dpbp) size = bpbp->bpb_nsize == 0 ? bpbp->bpb_huge : (ULONG) bpbp->bpb_nsize; - dpbp->dpb_wfatsize = bpbp->bpb_nfsect; + dpbp->dpb_fatsize = bpbp->bpb_nfsect; dpbp->dpb_dirstrt = dpbp->dpb_fatstrt - + dpbp->dpb_fats * dpbp->dpb_wfatsize; - dpbp->dpb_wdata = dpbp->dpb_dirstrt - + ((DIRENT_SIZE * dpbp->dpb_dirents + + dpbp->dpb_fats * dpbp->dpb_fatsize; + dpbp->dpb_data = dpbp->dpb_dirstrt + + ((DIRENT_SIZE * (ULONG)dpbp->dpb_dirents + (dpbp->dpb_secsize - 1)) / dpbp->dpb_secsize); /* Michal Meller patch to jimtabor */ - dpbp->dpb_wsize = ((size - dpbp->dpb_wdata) - / ((ULONG) bpbp->bpb_nsector) + 1); + dpbp->dpb_size = ((size - dpbp->dpb_data) + / ((ULONG) bpbp->bpb_nsector) + 1); dpbp->dpb_flags = 0; - dpbp->dpb_wcluster = UNKNCLUSTER; + dpbp->dpb_cluster = UNKNCLUSTER; /* number of free clusters */ - *((UWORD FAR *)(&dpbp->dpb_nfreeclst)) = UNKNCLSTFREE16; + dpbp->dpb_nfreeclst = UNKNCLSTFREE; #ifdef WITHFAT32 if (extended) { - dpbp->dpb_fatsize = bpbp->bpb_nfsect == 0 ? bpbp->bpb_xnfsect + dpbp->dpb_xfatsize = bpbp->bpb_nfsect == 0 ? bpbp->bpb_xnfsect : bpbp->bpb_nfsect; - dpbp->dpb_cluster = UNKNCLUSTER; - dpbp->dpb_nfreeclst = UNKNCLSTFREE; /* number of free clusters */ + dpbp->dpb_xcluster = UNKNCLUSTER; + dpbp->dpb_xnfreeclst = XUNKNCLSTFREE; /* number of free clusters */ dpbp->dpb_xflags = 0; dpbp->dpb_xfsinfosec = 0xffff; dpbp->dpb_xbackupsec = 0xffff; dpbp->dpb_xrootclst = 0; - dpbp->dpb_size = ((size - (dpbp->dpb_fatstrt + dpbp->dpb_fats - * dpbp->dpb_fatsize)) - / ((ULONG) bpbp->bpb_nsector) + 1); - + dpbp->dpb_xdata = dpbp->dpb_data; + dpbp->dpb_xsize = dpbp->dpb_size; + if (ISFAT32(dpbp)) { dpbp->dpb_xflags = bpbp->bpb_xflags; @@ -2391,26 +2549,19 @@ VOID bpb_to_dpb(bpb FAR *bpbp, REG struct dpb FAR * dpbp) dpbp->dpb_xbackupsec = bpbp->bpb_xbackupsec; dpbp->dpb_dirents = 0; dpbp->dpb_dirstrt = 0xffff; - dpbp->dpb_wsize = 0; - dpbp->dpb_data = dpbp->dpb_fatstrt + dpbp->dpb_fats * dpbp->dpb_fatsize; + dpbp->dpb_size = 0; + dpbp->dpb_xdata = dpbp->dpb_fatstrt + dpbp->dpb_fats * dpbp->dpb_xfatsize; + dpbp->dpb_xsize = ((size - dpbp->dpb_xdata) + / ((ULONG) bpbp->bpb_nsector) + 1); dpbp->dpb_xrootclst = bpbp->bpb_xrootclst; read_fsinfo(dpbp); } - else - { - dpbp->dpb_data = dpbp->dpb_wdata; - dpbp->dpb_size = dpbp->dpb_wsize; - } } #endif - for (i = 1, dpbp->dpb_shftcnt = 0; - i < (sizeof(dpbp->dpb_shftcnt) * 8); /* 8 bit bytes in C */ - dpbp->dpb_shftcnt++, i <<= 1) - { - if (i >= bpbp->bpb_nsector) - break; - } + for (shftcnt = 0; (bpbp->bpb_nsector >> shftcnt) > 1; shftcnt++) + ; + dpbp->dpb_shftcnt = shftcnt; } COUNT media_check(REG struct dpb FAR * dpbp) @@ -2538,22 +2689,16 @@ struct dhdr FAR *select_unit(COUNT drive) this code corrects this Unfortunately, this code _nearly_ works, but fails one of the - Apps tested (VB ISAM); so it's disabled for the moment + Apps tested (VB ISAM); BO: confirmation??? */ STATIC VOID shrink_file(f_node_ptr fnp) { -#if 0 - UNREFERENCED_PARAMETER(fnp); -#else ULONG lastoffset = fnp->f_offset; /* has to be saved */ CLUSTER next,st; struct dpb FAR *dpbp = fnp->f_dpb; - if (fnp->f_flags.f_ddir || (fnp->f_dir.dir_attrib & D_DIR)) /* can't shrink dirs */ - return; - fnp->f_offset = fnp->f_highwater; /* end of file */ if (fnp->f_offset) fnp->f_offset--; /* last existing cluster */ @@ -2588,30 +2733,10 @@ STATIC VOID shrink_file(f_node_ptr fnp) link_fat(dpbp, st,LONG_LAST_CLUSTER); } - for ( st = next; st != LONG_LAST_CLUSTER; st = next) - { - /* get the next cluster pointed to */ - next = next_cluster(dpbp, st); + wipe_out_clusters(dpbp, next); - /* just exit if a damaged file system exists */ - if (next == FREE) - return; - - /* zap the FAT pointed to */ - link_fat(dpbp, st, FREE); - - /* and the start of free space pointer */ - if ((dpbp->dpb_cluster == UNKNCLUSTER) - || (dpbp->dpb_cluster > st)) - dpbp->dpb_cluster = st; - } - done: fnp->f_offset = lastoffset; /* has to be restored */ -#ifdef WITHFAT32 - if (ISFAT32(dpbp)) write_fsinfo(dpbp); -#endif +} -#endif -} diff --git a/kernel/fattab.c b/kernel/fattab.c index 1943259..35c36b5 100644 --- a/kernel/fattab.c +++ b/kernel/fattab.c @@ -35,6 +35,9 @@ static BYTE *RcsId = "$Id$"; /* * $Log$ + * Revision 1.9 2001/11/04 19:47:39 bartoldeman + * kernel 2025a changes: see history.txt + * * Revision 1.8 2001/09/23 20:39:44 bartoldeman * FAT32 support, misc fixes, INT2F/AH=12 support, drive B: handling * @@ -167,22 +170,27 @@ struct buffer FAR *getFATblock(CLUSTER cluster, struct dpb FAR *dpbp) if (ISFAT32(dpbp) && (dpbp->dpb_xflags & FAT_NO_MIRRORING)) { /* we must modify the active fat, it's number is in the 0-3 bits of dpb_xflags */ - sector += (dpbp->dpb_xflags & 0xf) * dpbp->dpb_fatsize; + sector += (dpbp->dpb_xflags & 0xf) * dpbp->dpb_xfatsize; } #endif bp = getblock(sector, dpbp->dpb_unit); if (bp) - { - bp->b_flag &= ~(BFR_DATA | BFR_DIR); - bp->b_flag |= BFR_FAT | BFR_VALID; - bp->b_copies = dpbp->dpb_fats; + { + bp->b_flag &= ~(BFR_DATA | BFR_DIR); + bp->b_flag |= BFR_FAT | BFR_VALID; + bp->b_copies = dpbp->dpb_fats; + bp->b_offset = dpbp->dpb_fatsize; #ifdef WITHFAT32 - if (ISFAT32(dpbp) && (dpbp->dpb_xflags & FAT_NO_MIRRORING)) bp->b_copies = 1; -#endif - bp->b_offset = dpbp->dpb_fatsize; + if (ISFAT32(dpbp)) + { + if (dpbp->dpb_xflags & FAT_NO_MIRRORING) + bp->b_copies = 1; + bp->b_offset = dpbp->dpb_xfatsize; } +#endif + } return bp; } @@ -197,8 +205,8 @@ void read_fsinfo(struct dpb FAR *dpbp) bp->b_flag |= BFR_VALID; fip = (struct fsinfo FAR *) & bp->b_buffer[0x1e4]; - dpbp->dpb_nfreeclst = fip->fi_nfreeclst; - dpbp->dpb_cluster = fip->fi_cluster; + dpbp->dpb_xnfreeclst = fip->fi_nfreeclst; + dpbp->dpb_xcluster = fip->fi_cluster; } void write_fsinfo(struct dpb FAR *dpbp) @@ -211,8 +219,8 @@ void write_fsinfo(struct dpb FAR *dpbp) bp->b_flag |= BFR_VALID | BFR_DIRTY; fip = (struct fsinfo FAR *) & bp->b_buffer[0x1e4]; - fip->fi_nfreeclst = dpbp->dpb_nfreeclst; - fip->fi_cluster = dpbp->dpb_cluster; + fip->fi_nfreeclst = dpbp->dpb_xnfreeclst; + fip->fi_cluster = dpbp->dpb_xcluster; } #endif @@ -250,28 +258,37 @@ UCOUNT link_fat(struct dpb FAR *dpbp, CLUSTER Cluster1, REG CLUSTER Cluster2) /* update the free space count */ - if (res == SUCCESS) + if (res == SUCCESS && Cluster2 == FREE) + { +#ifdef WITHFAT32 + if (ISFAT32(dpbp) && dpbp->dpb_xnfreeclst != XUNKNCLSTFREE) + { + /* update the free space count for returned */ + /* cluster */ + ++dpbp->dpb_xnfreeclst; + write_fsinfo(dpbp); + } else +#endif if (dpbp->dpb_nfreeclst != UNKNCLSTFREE) - { - if (Cluster2 == FREE) - { + ++dpbp->dpb_nfreeclst; + } + + /*if (Cluster2 == FREE) + { */ /* update the free space count for returned */ /* cluster */ - ++dpbp->dpb_nfreeclst; - } + /* ++dpbp->dpb_nfreeclst; + }*/ /* update the free space count for removed */ /* cluster */ /* BUG: was counted twice for 2nd,.. cluster. moved to find_fat_free() */ - + /* BO: don't completely understand this yet - leave here for now as + a comment */ /* else { --dpbp->dpb_nfreeclst; } */ - } -#ifdef WITHFAT32 - if (ISFAT32(dpbp)) write_fsinfo(dpbp); -#endif return res; } @@ -382,25 +399,10 @@ UCOUNT link_fat12(struct dpb FAR *dpbp, CLUSTER Cluster1, CLUSTER Cluster2) /* Given the disk parameters, and a cluster number, this function looks at the FAT, and returns the next cluster in the clain. */ CLUSTER next_cluster(struct dpb FAR *dpbp, CLUSTER ClusterNum) -{ - if (ClusterNum == LONG_LAST_CLUSTER) printf("fatal error: trying to do next_cluster(dpbp, EOC)!\n"); - if (ISFAT12(dpbp)) - return next_cl12(dpbp, ClusterNum); - else if (ISFAT16(dpbp)) - return next_cl16(dpbp, ClusterNum); -#ifdef WITHFAT32 - else if (ISFAT32(dpbp)) - return next_cl32(dpbp, ClusterNum); -#endif - else - return LONG_LAST_CLUSTER; -} - -#ifdef WITHFAT32 -CLUSTER next_cl32(struct dpb FAR *dpbp, CLUSTER ClusterNum) { struct buffer FAR *bp; - UDWORD res; + if (ClusterNum == LONG_LAST_CLUSTER) printf("fatal error: trying to do next_cluster(dpbp, EOC)!\n"); + /* Get the block that this cluster is in */ bp = getFATblock(ClusterNum, dpbp); @@ -408,162 +410,96 @@ CLUSTER next_cl32(struct dpb FAR *dpbp, CLUSTER ClusterNum) if (bp == NULL) return DE_BLKINVLD; - res = *(UDWORD FAR *)&(bp->b_buffer[(UCOUNT)((ClusterNum * SIZEOF_CLST32) % dpbp->dpb_secsize)]); - if (res > LONG_BAD) return LONG_LAST_CLUSTER; - - return res; -} -#endif - -CLUSTER next_cl16(struct dpb FAR *dpbp, CLUSTER ClusterNum) -{ - struct buffer FAR *bp; - UWORD res; - - /* Get the block that this cluster is in */ - bp = getFATblock( ClusterNum, dpbp); - - if (bp == NULL) - return DE_BLKINVLD; - -#ifndef I86 - UCOUNT idx; - - /* form an index so that we can read the block as a */ - /* byte array */ - idx = (ClusterNum * SIZEOF_CLST16) % dpbp->dpb_secsize; - - /* Get the cluster number, */ - - fgetword((VOID FAR *) & (bp->b_buffer[idx]), (WORD FAR *) & res); - -#else - /* this saves 2 WORDS of stack :-) */ - - res = *(UWORD FAR *)&(bp->b_buffer[(UCOUNT)((ClusterNum * SIZEOF_CLST16) % dpbp->dpb_secsize)]); -#endif - if ((res & MASK16) == MASK16) return LONG_LAST_CLUSTER; - else if ((res & BAD16) == BAD16) return LONG_BAD; - - return res; -} - -#if 0 - /* old version - correct, but a bit complicated coded. - it's also on one of the critical stack path's - */ - -UWORD next_cl12(struct dpb FAR *dpbp, REG UCOUNT ClusterNum) -{ - REG UBYTE FAR *fbp0, - FAR * fbp1; - UCOUNT idx; - struct buffer FAR *bp, - FAR * bp1; - - /* Get the block that this cluster is in */ - bp = getFATblock(ClusterNum , dpbp); - - if (bp == NULL) - return LONG_BAD; - - /* form an index so that we can read the block as a */ - /* byte array */ - idx = (((ClusterNum << 1) + ClusterNum) >> 1) % dpbp->dpb_secsize; - - /* Test to see if the cluster straddles the block. If it */ - /* does, get the next block and use both to form the */ - /* the FAT word. Otherwise, just point to the next */ - /* block. */ - if (idx >= dpbp->dpb_secsize - 1) + if (ISFAT12(dpbp)) { - bp1 = getFATblock(ClusterNum +1, dpbp); - - if (bp1 == 0) - return LONG_BAD; - - fbp1 = (UBYTE FAR *) & (bp1->b_buffer[0]); - } - else - fbp1 = (UBYTE FAR *) & (bp->b_buffer[idx + 1]); - fbp0 = (UBYTE FAR *) & (bp->b_buffer[idx]); - - /* Now to unpack the contents of the FAT entry. Odd and */ - /* even bytes are packed differently. */ - if (ClusterNum & 0x01) - ClusterNum = ((*fbp0 & 0xf0) >> 4) | (*fbp1 << 4); - else - ClusterNum = *fbp0 | ((*fbp1 & 0x0f) << 8); - - if ((ClusterNum & MASK) == MASK) - ClusterNum = LONG_LAST_CLUSTER; - else if ((ClusterNum & BAD) == BAD) - ClusterNum = LONG_BAD; - return ClusterNum; -} -#else - /* new version - 50 byte smaller, saves 10 bytes on stack :-) - */ - -CLUSTER next_cl12(struct dpb FAR *dpbp, REG CLUSTER ClusterNum) -{ - union { + union { UBYTE bytes[2]; UCOUNT word; } clusterbuff; - UCOUNT idx; - struct buffer FAR *bp; + UCOUNT idx; - /* Get the block that this cluster is in */ - bp = getFATblock(ClusterNum , dpbp); - - if (bp == NULL) - return LONG_BAD; + /* form an index so that we can read the block as a */ + /* byte array */ + idx = (UCOUNT)(((ClusterNum << 1) + ClusterNum) >> 1) % dpbp->dpb_secsize; - /* form an index so that we can read the block as a */ - /* byte array */ - idx = (UCOUNT)(((ClusterNum << 1) + ClusterNum) >> 1) % dpbp->dpb_secsize; + clusterbuff.bytes[0] = bp->b_buffer[idx]; - clusterbuff.bytes[0] = bp->b_buffer[idx]; - - clusterbuff.bytes[1] = bp->b_buffer[idx+1]; /* next byte, will be overwritten, + clusterbuff.bytes[1] = bp->b_buffer[idx+1]; /* next byte, will be overwritten, if not valid */ - /* Test to see if the cluster straddles the block. If it */ - /* does, get the next block and use both to form the */ - /* the FAT word. Otherwise, just point to the next */ - /* block. */ - if (idx >= dpbp->dpb_secsize - 1) - { - bp = getFATblock(ClusterNum +1, dpbp); + /* Test to see if the cluster straddles the block. If it */ + /* does, get the next block and use both to form the */ + /* the FAT word. Otherwise, just point to the next */ + /* block. */ + if (idx >= dpbp->dpb_secsize - 1) + { + bp = getFATblock(ClusterNum +1, dpbp); - if (bp == 0) - return LONG_BAD; + if (bp == 0) + return LONG_BAD; - clusterbuff.bytes[1] = bp->b_buffer[0]; - } - - /* Now to unpack the contents of the FAT entry. Odd and */ - /* even bytes are packed differently. */ + clusterbuff.bytes[1] = bp->b_buffer[0]; + } + /* Now to unpack the contents of the FAT entry. Odd and */ + /* even bytes are packed differently. */ + #ifndef I86 /* the latter assumes byte ordering */ - if (ClusterNum & 0x01) - ClusterNum = ((clusterbuff.byte[0] & 0xf0) >> 4) | (clusterbuff.byte[1] << 4); - else - ClusterNum = clusterbuff.byte[0] | ((clusterbuff.byte[0] & 0x0f) << 8); + if (ClusterNum & 0x01) + idx = ((clusterbuff.byte[0] & 0xf0) >> 4) | (clusterbuff.byte[1] << 4); + else + idx = clusterbuff.byte[0] | ((clusterbuff.byte[0] & 0x0f) << 8); #else - if (ClusterNum & 0x01) - ClusterNum = (unsigned short)clusterbuff.word >> 4; - else - ClusterNum = clusterbuff.word & 0x0fff; + if (ClusterNum & 0x01) + idx = (unsigned short)clusterbuff.word >> 4; + else + idx = clusterbuff.word & 0x0fff; #endif - if ((ClusterNum & MASK12) == MASK12) - ClusterNum = LONG_LAST_CLUSTER; - else if ((ClusterNum & BAD12) == BAD12) - ClusterNum = LONG_BAD; - return ClusterNum; -} + if (idx >= MASK12) + return LONG_LAST_CLUSTER; + if (idx == BAD12) + return LONG_BAD; + return idx; + } + else if (ISFAT16(dpbp)) + { + UWORD res; + +#ifndef I86 + UCOUNT idx; + + /* form an index so that we can read the block as a */ + /* byte array */ + idx = (ClusterNum * SIZEOF_CLST16) % dpbp->dpb_secsize; + + /* Get the cluster number, */ + + fgetword((VOID FAR *) & (bp->b_buffer[idx]), (WORD FAR *) & res); + +#else + /* this saves 2 WORDS of stack :-) */ + + res = *(UWORD FAR *)&(bp->b_buffer[(UCOUNT)((ClusterNum * SIZEOF_CLST16) % dpbp->dpb_secsize)]); +#endif + if (res >= MASK16) return LONG_LAST_CLUSTER; + if (res == BAD16) return LONG_BAD; + + return res; + } +#ifdef WITHFAT32 + else if (ISFAT32(dpbp)) + { + UDWORD res; + + res = *(UDWORD FAR *)&(bp->b_buffer[(UCOUNT)((ClusterNum * SIZEOF_CLST32) % dpbp->dpb_secsize)]); + if (res > LONG_BAD) return LONG_LAST_CLUSTER; + + return res; + } #endif + return LONG_LAST_CLUSTER; +} + diff --git a/kernel/fcbfns.c b/kernel/fcbfns.c index 5da0c18..f207945 100644 --- a/kernel/fcbfns.c +++ b/kernel/fcbfns.c @@ -35,6 +35,9 @@ static BYTE *RcsId = "$Id$"; /* * $Log$ + * Revision 1.19 2001/11/04 19:47:39 bartoldeman + * kernel 2025a changes: see history.txt + * * Revision 1.18 2001/09/23 20:39:44 bartoldeman * FAT32 support, misc fixes, INT2F/AH=12 support, drive B: handling * @@ -180,12 +183,8 @@ VOID FatGetDrvData(UCOUNT drive, COUNT FAR * spc, COUNT FAR * bps, { struct dpb FAR *dpbp; struct cds FAR *cdsp; -#ifdef WITHFAT32 - UCOUNT shift = 0; - ULONG cluster_size, ntotal; -#endif - /* first check for valid drive */ + /* first check for valid drive */ *spc = -1; drive = (drive == 0 ? default_drive : drive - 1); @@ -218,22 +217,24 @@ VOID FatGetDrvData(UCOUNT drive, COUNT FAR * spc, COUNT FAR * bps, return; } -#ifdef WITHFAT32 - cluster_size = (dpbp->dpb_clsmask + 1) * dpbp->dpb_secsize; - ntotal = dpbp->dpb_size - 1; - while (cluster_size <= 0x7fff) { - cluster_size <<= 1; - ntotal >>= 1; - shift++; - } - /* get the data available from dpb */ - if (ntotal > 0xfffe) ntotal = 0xfffe; - *nc = (UCOUNT)ntotal; - *spc = (dpbp->dpb_clsmask + 1) << shift; -#else - /* get the data vailable from dpb */ + /* get the data available from dpb */ *nc = dpbp->dpb_size - 1; *spc = dpbp->dpb_clsmask + 1; +#ifdef WITHFAT32 + if (ISFAT32(dpbp)) + { + ULONG cluster_size, ntotal; + + cluster_size = (ULONG)dpbp->dpb_secsize << dpbp->dpb_shftcnt; + ntotal = dpbp->dpb_xsize - 1; + while (ntotal > FAT_MAGIC16 && cluster_size < 0x8000) { + cluster_size <<= 1; + *spc <<= 1; + ntotal >>= 1; + } + /* get the data available from dpb */ + *nc = ntotal > FAT_MAGIC16 ? FAT_MAGIC16 : (UCOUNT)ntotal; + } #endif *bps = dpbp->dpb_secsize; @@ -432,16 +433,8 @@ BOOL FcbRead(xfcb FAR * lpXfcb, COUNT * nErrorCode) return FALSE; } - if (s->sft_flags & SFT_FSHARED) - { - nRead = Remote_RW(REM_READ, lpFcb->fcb_recsiz, p->ps_dta, s, nErrorCode); - } - else - { - - /* Do the read */ - nRead = dos_read(s->sft_status, p->ps_dta, lpFcb->fcb_recsiz); - } + /* Do the read */ + nRead = DosReadSft(s, lpFcb->fcb_recsiz, p->ps_dta, nErrorCode); /* Now find out how we will return and do it. */ if (nRead == lpFcb->fcb_recsiz) @@ -462,14 +455,7 @@ BOOL FcbRead(xfcb FAR * lpXfcb, COUNT * nErrorCode) } else { - COUNT nIdx, - nCount; - BYTE FAR *lpDta; - - nCount = lpFcb->fcb_recsiz - nRead; - lpDta = (BYTE FAR *) & (p->ps_dta[nRead]); - for (nIdx = 0; nIdx < nCount; nIdx++) - *lpDta++ = 0; + fmemset(&p->ps_dta[nRead], 0, lpFcb->fcb_recsiz - nRead); *nErrorCode = FCB_ERR_EOF; FcbNextRecord(lpFcb); return FALSE; @@ -503,17 +489,7 @@ BOOL FcbWrite(xfcb FAR * lpXfcb, COUNT * nErrorCode) return FALSE; } - if (s->sft_flags & SFT_FSHARED) - { - nWritten = Remote_RW(REM_WRITE, lpFcb->fcb_recsiz, p->ps_dta, s, nErrorCode); - } - else - { - - /* Do the read */ - nWritten = dos_write(s->sft_status, p->ps_dta, lpFcb->fcb_recsiz); - s->sft_size = dos_getcufsize(s->sft_status); - } + nWritten = DosWriteSft(s, lpFcb->fcb_recsiz, p->ps_dta, nErrorCode); /* Now find out how we will return and do it. */ if (nWritten == lpFcb->fcb_recsiz) @@ -578,14 +554,13 @@ BOOL FcbSetRandom(xfcb FAR * lpXfcb) BOOL FcbCalcRec(xfcb FAR * lpXfcb) { - UWORD div=128; - + /* Convert to fcb if necessary */ lpFcb = ExtFcbToFcb(lpXfcb); /* Now update the fcb and compute where we need to position */ /* to. */ - lpFcb->fcb_cublock = lpFcb->fcb_rndm / div; + lpFcb->fcb_cublock = lpFcb->fcb_rndm / 128; lpFcb->fcb_curec = lpFcb->fcb_rndm & 127; return TRUE; diff --git a/kernel/globals.h b/kernel/globals.h index d1db37a..9c52a6a 100644 --- a/kernel/globals.h +++ b/kernel/globals.h @@ -36,6 +36,9 @@ static BYTE *Globals_hRcsId = "$Id$"; /* * $Log$ + * Revision 1.18 2001/11/04 19:47:39 bartoldeman + * kernel 2025a changes: see history.txt + * * Revision 1.17 2001/09/23 20:39:44 bartoldeman * FAT32 support, misc fixes, INT2F/AH=12 support, drive B: handling * @@ -376,15 +379,16 @@ GLOBAL WORD bDumpRdWrParms #endif #endif -GLOBAL BYTE copyright[] -#ifdef MAIN -= "(C) Copyright 1995-2001 Pasquale J. Villani and The FreeDOS Project.\n\ -All Rights Reserved. This is free software and comes with ABSOLUTELY NO\n\ -WARRANTY; you can redistribute it and/or modify it under the terms of the\n\ -GNU General Public License as published by the Free Software Foundation;\n\ -either version 2, or (at your option) any later version.\n" +#if 0 /* defined in MAIN.C now to save low memory */ + +GLOBAL BYTE copyright[] = + "(C) Copyright 1995-2001 Pasquale J. Villani and The FreeDOS Project.\n" + "All Rights Reserved. This is free software and comes with ABSOLUTELY NO\n" + "WARRANTY; you can redistribute it and/or modify it under the terms of the\n" + "GNU General Public License as published by the Free Software Foundation;\n" + "either version 2, or (at your option) any later version.\n"; + #endif -; GLOBAL BYTE os_release[] #ifdef MAIN @@ -536,7 +540,7 @@ extern request /* I/O Request packets */ extern fcb FAR * lpFcb; /* Pointer to users fcb */ -extern sfttbl +extern sft FAR * lpCurSft; extern BYTE @@ -548,8 +552,8 @@ extern BYTE extern BYTE BootDrive, /* Drive we came up from */ scr_pos; /* screen position for bs, ht, etc */ -extern WORD - NumFloppies; /* How many floppies we have */ +/*extern WORD + NumFloppies; !!*/ /* How many floppies we have */ extern keyboard kb_buf; @@ -578,9 +582,9 @@ GLOBAL f_node_ptr f_nodes; /* pointer to the array */ GLOBAL UWORD f_nodes_cnt; /* number of allocated f_nodes */ -GLOBAL iregs - FAR * ustackp, /* user stack */ - FAR * kstackp; /* kernel stack */ +/*!! GLOBAL iregs + FAR * ustackp, /* user stack */ +/*!! FAR * kstackp; */ /* kernel stack */ /* */ /* Function prototypes - automatically generated */ diff --git a/kernel/init-mod.h b/kernel/init-mod.h index 102e641..f18c449 100644 --- a/kernel/init-mod.h +++ b/kernel/init-mod.h @@ -21,6 +21,10 @@ #include "nls.h" #include "buffer.h" +#include "KConfig.h" +extern struct _KernelConfig InitKernelConfig; + + /* * The null macro `INIT' can be used to allow the reader to differentiate * between functions defined in `INIT_TEXT' and those defined in `_TEXT'. @@ -76,7 +80,7 @@ extern fmemcmp(BYTE far *s1, BYTE FAR *s2, unsigned len); /* Start of configuration variables */ struct config { - UBYTE cfgBuffers; + BYTE cfgBuffers; /* number of buffers in the system */ UBYTE cfgFiles; /* number of available files */ @@ -152,7 +156,7 @@ void ASMCFUNC init_call_intr(int nr, iregs *rp); UCOUNT ASMCFUNC read(int fd, void *buf, UCOUNT count); int ASMCFUNC open(const char *pathname, int flags); int ASMCFUNC close(int fd); -int ASMCFUNC dup2(int oldfd, int newfd); +int ASMCFUNC dup2(int oldfd, int newfd); int ASMCFUNC allocmem(UWORD size, seg *segp); INIT VOID ASMCFUNC init_PSPInit(seg psp_seg); INIT VOID ASMCFUNC init_PSPSet(seg psp_seg); diff --git a/kernel/initdisk.c b/kernel/initdisk.c index bedf800..5ee1343 100644 --- a/kernel/initdisk.c +++ b/kernel/initdisk.c @@ -148,6 +148,15 @@ extern UWORD DOSFAR LBA_WRITE_VERIFY; /* the 8.4GB boundary */ #define EXTENDED_LBA 0x0f /* like 0x05, but it is supposed to end past */ +/* Let's play it safe and do not allow partitions with clusters above * + * or equal to 0xff0/0xfff0/0xffffff0 to be created * + * the problem with fff0-fff6 is that they might be interpreted as BAD * + * even though the standard BAD value is ...ff7 */ + +#define FAT12MAX (FAT_MAGIC-7) +#define FAT16MAX (FAT_MAGIC16-7) +#define FAT32MAX (FAT_MAGIC32-7) + #define IsExtPartition(parttyp) ((parttyp) == EXTENDED || \ (parttyp) == EXTENDED_LBA ) @@ -231,6 +240,65 @@ COUNT init_readdasd(UBYTE drive) return 0; } +typedef struct +{ + UWORD bpb_nbyte; /* Bytes per Sector */ + UBYTE bpb_nsector; /* Sectors per Allocation Unit */ + UWORD bpb_nreserved; /* # Reserved Sectors */ + UBYTE bpb_nfat; /* # FAT's */ + UWORD bpb_ndirent; /* # Root Directory entries */ + UWORD bpb_nsize; /* Size in sectors */ + UBYTE bpb_mdesc; /* MEDIA Descriptor Byte */ + UWORD bpb_nfsect; /* FAT size in sectors */ + UWORD bpb_nsecs; /* Sectors per track */ + UWORD bpb_nheads; /* Number of heads */ +} floppy_bpb; + +floppy_bpb floppy_bpbs[5] = { +/* copied from Brian Reifsnyder's FORMAT, bpb.h */ + {SEC_SIZE,2,1,2,112, 720,0xfd,2, 9,2}, /* FD360 5.25 DS */ + {SEC_SIZE,1,1,2,224,2400,0xf9,7,15,2}, /* FD1200 5.25 HD */ + {SEC_SIZE,2,1,2,112,1440,0xf9,3, 9,2}, /* FD720 3.5 LD */ + {SEC_SIZE,1,1,2,224,2880,0xf0,9,18,2}, /* FD1440 3.5 HD */ + {SEC_SIZE,2,1,2,240,5760,0xf0,9,36,2} /* FD2880 3.5 ED */ +}; + +COUNT init_getdriveparm(UBYTE drive, bpb FAR *pbpbarray) +{ + static iregs regs; + + if (drive & 0x80) + return 5; + regs.a.b.h = 0x08; + regs.d.b.l = drive; + init_call_intr(0x13,®s); + if (regs.flags & 1) + return 0; /* return 320-360 for XTs */ + + switch(regs.b.b.l) + { + case 1: /* 320-360 */ + fmemcpy(pbpbarray, &floppy_bpbs[0], sizeof(floppy_bpb)); + return 0; + case 2: /* 1.2 */ + fmemcpy(pbpbarray, &floppy_bpbs[1], sizeof(floppy_bpb)); + return 1; + case 3: /* 720 */ + fmemcpy(pbpbarray, &floppy_bpbs[2], sizeof(floppy_bpb)); + return 2; + case 4: /* 1.44 */ + fmemcpy(pbpbarray, &floppy_bpbs[3], sizeof(floppy_bpb)); + return 7; + case 5: /* 2.88 almost forgot this one*/ + case 6: + fmemcpy(pbpbarray, &floppy_bpbs[4], sizeof(floppy_bpb)); + return 9; + } + /* any odd ball drives return this */ + fmemcpy(pbpbarray, &floppy_bpbs[0], sizeof(floppy_bpb)); + return 8; +} + /* translate LBA sectors into CHS addressing copied and pasted from dsk.c! @@ -280,11 +348,11 @@ VOID CalculateFATData(ddt FAR *pddt, ULONG NumSectors, UBYTE FileSystem) /* FAT related items */ defbpb->bpb_nfat = 2; - defbpb->bpb_ndirent = 512; /* normal value of number of entries in root dir - should be 0 for FAT32 drives */ - defbpb->bpb_nreserved = 1; /* 0x20 for FAT32 */ + defbpb->bpb_ndirent = (FileSystem == FAT32 || FileSystem == FAT32_LBA) ? 0 : 512; + /* normal value of number of entries in root dir */ + defbpb->bpb_nreserved = (FileSystem == FAT32 || FileSystem == FAT32_LBA) ? 0x20 : 1; - fatdata = NumSectors - cdiv (defbpb->bpb_ndirent * 32, defbpb->bpb_nbyte) - + fatdata = NumSectors - cdiv (defbpb->bpb_ndirent * DIRENT_SIZE, defbpb->bpb_nbyte) - defbpb->bpb_nreserved; maxclustsize = 128; #ifdef DEBUG @@ -299,10 +367,10 @@ VOID CalculateFATData(ddt FAR *pddt, ULONG NumSectors, UBYTE FileSystem) defbpb->bpb_nsector = 8; /* Force maximal fatdata=32696 sectors since with our only possible sector size (512 bytes) this is the maximum for 4k clusters. - #clus*secperclus+#fats*fatlength= 4084 * 8 + 2 * 12 = 32696. + #clus*secperclus+#fats*fatlength= 4077 * 8 + 2 * 12 = 32640. max FAT12 size for FreeDOS = 16,728,064 bytes */ - if (fatdata > 32696) - fatdata = 32696; + if (fatdata > 32640) + fatdata = 32640; /* The factor 2 below avoids cut-off errors for nr_fats == 1. * The "defbpb->bpb_nfat*3" is for the reserved first two FAT entries */ clust = 2*((ULONG) fatdata * defbpb->bpb_nbyte + defbpb->bpb_nfat*3) / @@ -313,10 +381,10 @@ VOID CalculateFATData(ddt FAR *pddt, ULONG NumSectors, UBYTE FileSystem) * not really present cluster. */ clust = (fatdata - defbpb->bpb_nfat*fatlength)/defbpb->bpb_nsector; maxclust = (fatlength * 2 * defbpb->bpb_nbyte) / 3; - if (maxclust > FAT_MAGIC) - maxclust = FAT_MAGIC; + if (maxclust > FAT12MAX) + maxclust = FAT12MAX; DebugPrintf(( "FAT12: #clu=%lu, fatlen=%lu, maxclu=%lu, limit=%u\n", - clust, fatlength, maxclust, FAT_MAGIC )); + clust, fatlength, maxclust, FATMAX12 )); if (clust > maxclust-2) { clust = maxclust-2; DebugPrintf(( "FAT12: too many clusters: setting to maxclu-2\n" )); @@ -333,10 +401,10 @@ VOID CalculateFATData(ddt FAR *pddt, ULONG NumSectors, UBYTE FileSystem) /* Force maximal fatdata=8387584 sectors (NumSectors=8387617) since with our only possible sectorsize (512 bytes) this is the maximum we can address with 64k clusters - #clus*secperclus+#fats*fatlength=65524 * 128 + 2 * 256=8387584. - max FAT16 size for FreeDOS = 4,294,180,864 bytes = 4GiB-786,432 */ - if (fatdata > 8387584ul) - fatdata = 8387584ul; + #clus*secperclus+#fats*fatlength=65517 * 128 + 2 * 256=8386688. + max FAT16 size for FreeDOS = 4,293,984,256 bytes = 4GiB-983,040 */ + if (fatdata > 8386688ul) + fatdata = 8386688ul; do { DebugPrintf(( "Trying with %d sectors/cluster:\n", defbpb->bpb_nsector )); @@ -348,8 +416,8 @@ VOID CalculateFATData(ddt FAR *pddt, ULONG NumSectors, UBYTE FileSystem) * not really present cluster. */ clust = (fatdata - defbpb->bpb_nfat*fatlength)/defbpb->bpb_nsector; maxclust = (fatlength * defbpb->bpb_nbyte) / 2; - if (maxclust > FAT_MAGIC16) - maxclust = FAT_MAGIC16; + if (maxclust > FAT16MAX) + maxclust = FAT16MAX; DebugPrintf(( "FAT16: #clu=%lu, fatlen=%lu, maxclu=%lu, limit=%u\n", clust, fatlength, maxclust, FAT_MAGIC16 )); if (clust > maxclust-2) { @@ -372,10 +440,11 @@ VOID CalculateFATData(ddt FAR *pddt, ULONG NumSectors, UBYTE FileSystem) #ifdef WITHFAT32 case FAT32: + case FAT32_LBA: /* For FAT32, use 4k clusters on sufficiently large file systems, * otherwise 1 sector per cluster. This is also what M$'s format * command does for FAT32. */ - defbpb->bpb_nsector = (NumSectors >= 512*1024 ? 8 : 1); + defbpb->bpb_nsector = (NumSectors >= 512*1024ul ? 8 : 1); do { /* simple calculation - no long long available */ clust = (ULONG)fatdata / defbpb->bpb_nsector; @@ -389,11 +458,11 @@ VOID CalculateFATData(ddt FAR *pddt, ULONG NumSectors, UBYTE FileSystem) * not really present cluster. */ clust = (fatdata - defbpb->bpb_nfat*fatlength)/defbpb->bpb_nsector; maxclust = (fatlength * defbpb->bpb_nbyte) / 4; - if (maxclust > FAT_MAGIC32) - maxclust = FAT_MAGIC32; + if (maxclust > FAT32MAX) + maxclust = FAT32MAX; DebugPrintf(( "FAT32: #clu=%u, fatlen=%u, maxclu=%u, limit=%u\n", - clust, fatlength, maxclust, FAT_MAGIC32 )); - if (clust > maxclust) + clust, fatlength, maxclust, FATMAX32 )); + if (clust > maxclust-2) { clust = 0; DebugPrintf(( "FAT32: too many clusters\n" )); @@ -404,6 +473,12 @@ VOID CalculateFATData(ddt FAR *pddt, ULONG NumSectors, UBYTE FileSystem) } while (defbpb->bpb_nsector && defbpb->bpb_nsector <= maxclustsize); defbpb->bpb_nfsect = 0; defbpb->bpb_xnfsect = fatlength; + /* set up additional FAT32 fields */ + defbpb->bpb_xflags = 0; + defbpb->bpb_xfsversion = 0; + defbpb->bpb_xrootclst = 2; + defbpb->bpb_xfsinfosec = 1; + defbpb->bpb_xbackupsec = 6; fmemcpy(pddt->ddt_fstype, MSDOS_FAT32_SIGN, 8); break; #endif @@ -413,7 +488,7 @@ VOID CalculateFATData(ddt FAR *pddt, ULONG NumSectors, UBYTE FileSystem) void DosDefinePartition(struct DriveParamS *driveParam, - ULONG StartSector, struct PartTableEntry *pEntry) + ULONG StartSector, struct PartTableEntry *pEntry, int extendedPartNo, int PrimaryNum) { ddt FAR *pddt = DynAlloc("ddt", 1, sizeof(ddt)); struct CHS chs; @@ -452,22 +527,32 @@ void DosDefinePartition(struct DriveParamS *driveParam, pddt->ddt_serialno = 0x12345678l; /* drive inaccessible until bldbpb successful */ pddt->ddt_descflags = init_readdasd(pddt->ddt_driveno) | DF_NOACCESS; + pddt->ddt_type = 5; fmemcpy(&pddt->ddt_bpb, &pddt->ddt_defbpb, sizeof(bpb)); -#ifdef _BETA_ /* Alain whishes to keep this in later versions, too */ - LBA_to_CHS(&chs,StartSector,driveParam); + /* Alain whishes to keep this in later versions, too + Tom likes this too, so he made it configurable by SYS CONFIG ... + */ - printf("%c: disk %02x", - 'A' + nUnits, - driveParam->driveno); + if (InitKernelConfig.InitDiskShowDriveAssignment) + { + LBA_to_CHS(&chs,StartSector,driveParam); + + printf("%c: HD%d", + 'A' + nUnits, + (driveParam->driveno & 0x7f)+1); + + if (extendedPartNo) printf(" Ext:%d", extendedPartNo); + else printf(" Pri:%d", PrimaryNum + 1); + + printCHS(" CHS= ",&chs); + + printf(" start = %5luMB,size =%5lu", + StartSector/2048,pEntry->NumSect/2048); + + printf("\n"); + } - printCHS(" CHS= ",&chs); - - printf(" start = %5luMB,size =%5lu", - StartSector/2048,pEntry->NumSect/2048); - - printf("\n"); -#endif nUnits++; @@ -660,7 +745,7 @@ ConvPartTableEntryToIntern(struct PartTableEntry *pEntry, UBYTE FAR * pDisk) ScanForPrimaryPartitions(struct DriveParamS *driveParam,int scan_type, struct PartTableEntry *pEntry, ULONG startSector, - int partitionsToIgnore + int partitionsToIgnore, int extendedPartNo ) { int i; @@ -755,7 +840,7 @@ ScanForPrimaryPartitions(struct DriveParamS *driveParam,int scan_type, } /* else its a diagnostic message only */ -#ifdef _BETA_ +#ifdef DEBUG printf("found and using LBA partition %u FS %02x", i, pEntry->FileSystem); printCHS(" start ",&chs); @@ -771,7 +856,8 @@ ScanForPrimaryPartitions(struct DriveParamS *driveParam,int scan_type, partitionsToIgnore |= 1 << i; - DosDefinePartition(driveParam,partitionStart, pEntry); + DosDefinePartition(driveParam,partitionStart, pEntry, + extendedPartNo, i); if (scan_type == SCAN_PRIMARYBOOT || scan_type == SCAN_PRIMARY ) @@ -912,7 +998,7 @@ strange_restart: { PartitionsToIgnore = ScanForPrimaryPartitions(&driveParam,scanType, - PTable, RelSectorOffset,PartitionsToIgnore); + PTable, RelSectorOffset,PartitionsToIgnore,num_extended_found); } if (scanType != SCAN_EXTENDED) @@ -1075,48 +1161,33 @@ I don't know, if I did it right, but I tried to do it that way. TE ***********************************************************************/ - - void ReadAllPartitionTables(void) { UBYTE foundPartitions[MAX_HARD_DRIVE]; int HardDrive; int nHardDisk = BIOS_nrdrives(); - bpb FAR *pbpbarray; int Unit; ddt FAR *pddt; static iregs regs; - /* Setup media info and BPBs arrays for floppies (this is a 360kb flop) */ + /* Setup media info and BPBs arrays for floppies */ for (Unit = 0; Unit < nUnits; Unit++) { pddt = DynAlloc("ddt", 1, sizeof(ddt)); - pbpbarray = &pddt->ddt_defbpb; - - pbpbarray->bpb_nbyte = SEC_SIZE; - pbpbarray->bpb_nsector = 2; - pbpbarray->bpb_nreserved = 1; - pbpbarray->bpb_nfat = 2; - pbpbarray->bpb_ndirent = 112; - pbpbarray->bpb_nsize = 360*2; - pbpbarray->bpb_mdesc = 0xfd; - pbpbarray->bpb_nfsect = 2; - pbpbarray->bpb_nheads = 2; - pbpbarray->bpb_nsecs = 9; - pddt->ddt_driveno = 0; pddt->ddt_logdriveno = Unit; - pddt->ddt_ncyl = 40; + pddt->ddt_type = init_getdriveparm(0, &pddt->ddt_defbpb); + pddt->ddt_ncyl = (pddt->ddt_type & 7) ? 80 : 40; pddt->ddt_LBASupported = FALSE; pddt->ddt_descflags = init_readdasd(0); pddt->ddt_offset = 0l; pddt->ddt_serialno = 0x12345678l; - fmemcpy(&pddt->ddt_bpb, pbpbarray, sizeof(bpb)); - } - + fmemcpy(&pddt->ddt_bpb, &pddt->ddt_defbpb, sizeof(bpb)); + } + /* this is a quick patch - see if B: exists test for A: also, need not exist @@ -1124,7 +1195,9 @@ void ReadAllPartitionTables(void) init_call_intr(0x11,®s); /* get equipment list */ if ((regs.a.x & 1) && (regs.a.x & 0xc0)) { pddt->ddt_driveno = 1; + pddt->ddt_type = init_getdriveparm(1, &pddt->ddt_defbpb); pddt->ddt_descflags = init_readdasd(1); + pddt->ddt_ncyl = (pddt->ddt_type & 7) ? 80 : 40; /* floppy drives installed and a B: drive */ /*if ((r.a.x & 1)==0) */ /* no floppy drives installed */ } else { /* set up the DJ method : multiple logical drives */ @@ -1145,28 +1218,57 @@ void ReadAllPartitionTables(void) for (HardDrive = 0; HardDrive < nHardDisk; HardDrive++) BIOS_drive_reset(HardDrive); - - /* Process primary partition table 1 partition only */ - for (HardDrive = 0; HardDrive < nHardDisk; HardDrive++) - { - foundPartitions[HardDrive] = - ProcessDisk(SCAN_PRIMARYBOOT, HardDrive, 0); - - if (foundPartitions[HardDrive] == 0) - foundPartitions[HardDrive] = ProcessDisk(SCAN_PRIMARY, HardDrive, 0); - } - /* Process extended partition table */ - for (HardDrive = 0; HardDrive < nHardDisk; HardDrive++) + + if (InitKernelConfig.DLASortByDriveNo == 0) { - ProcessDisk(SCAN_EXTENDED, HardDrive , 0); - } + /* printf("Drive Letter Assignment - DOS order \n"); */ + + + /* Process primary partition table 1 partition only */ + for (HardDrive = 0; HardDrive < nHardDisk; HardDrive++) + { + foundPartitions[HardDrive] = + ProcessDisk(SCAN_PRIMARYBOOT, HardDrive, 0); + + if (foundPartitions[HardDrive] == 0) + foundPartitions[HardDrive] = ProcessDisk(SCAN_PRIMARY, HardDrive, 0); + } - /* Process primary a 2nd time */ - for (HardDrive = 0; HardDrive < nHardDisk; HardDrive++) - { - ProcessDisk(SCAN_PRIMARY2, HardDrive ,foundPartitions[HardDrive]); + /* Process extended partition table */ + for (HardDrive = 0; HardDrive < nHardDisk; HardDrive++) + { + ProcessDisk(SCAN_EXTENDED, HardDrive , 0); + } + + /* Process primary a 2nd time */ + for (HardDrive = 0; HardDrive < nHardDisk; HardDrive++) + { + ProcessDisk(SCAN_PRIMARY2, HardDrive ,foundPartitions[HardDrive]); + } } + else + { + printf("Drive Letter Assignment - sorted by drive\n"); + + + /* Process primary partition table 1 partition only */ + for (HardDrive = 0; HardDrive < nHardDisk; HardDrive++) + { + foundPartitions[HardDrive] = + ProcessDisk(SCAN_PRIMARYBOOT, HardDrive, 0); + + if (foundPartitions[HardDrive] == 0) + foundPartitions[HardDrive] = ProcessDisk(SCAN_PRIMARY, HardDrive, 0); + + /* Process extended partition table */ + ProcessDisk(SCAN_EXTENDED, HardDrive , 0); + + + /* Process primary a 2nd time */ + ProcessDisk(SCAN_PRIMARY2, HardDrive ,foundPartitions[HardDrive]); + } + } } /* disk initialization: returns number of units */ diff --git a/kernel/int2f.asm b/kernel/int2f.asm index d73bdba..6f89f12 100644 --- a/kernel/int2f.asm +++ b/kernel/int2f.asm @@ -30,6 +30,9 @@ ; $Id$ ; ; $Log$ +; Revision 1.14 2001/11/04 19:47:39 bartoldeman +; kernel 2025a changes: see history.txt +; ; Revision 1.13 2001/09/23 20:39:44 bartoldeman ; FAT32 support, misc fixes, INT2F/AH=12 support, drive B: handling ; @@ -200,161 +203,254 @@ IntDosCal: iret - - ; Int 2F Multipurpose Remote System Calls ; ; added by James Tabor jimtabor@infohwy.com +; changed by Bart Oldeman ; -; int_2f_Remote_call(ax,bx,cx,dx,[es:di],si, return data * ptr) ; assume ss == ds after setup of stack in entry ; sumtimes return data *ptr is the push stack word -; - global _int2f_Remote_call -_int2f_Remote_call: +; + + global _remote_rmdir +_remote_rmdir: + mov al, 01h + jmp short call_int2f + + global _remote_mkdir +_remote_mkdir: + mov al, 03h + jmp short call_int2f + + global _remote_chdir +_remote_chdir: + mov al, 05h + jmp short call_int2f + + global _remote_close +_remote_close: + mov al, 06h + jmp short call_int2f + + global _remote_read +_remote_read: mov al, 08h + jmp short call_int2f + + global _remote_write +_remote_write: mov al, 09h + jmp short call_int2f + + global _remote_getfree +_remote_getfree: + mov al, 0ch + jmp short call_int2f + + global _remote_setfattr +_remote_setfattr: + mov al, 0eh + jmp short call_int2f + + global _remote_getfattr +_remote_getfattr: + mov al, 0fh + jmp short call_int2f + + global _remote_rename +_remote_rename: + mov al, 11h + jmp short call_int2f + + global _remote_delete +_remote_delete: + mov al, 13h + jmp short call_int2f + + global _remote_open +_remote_open: + mov al, 16h + jmp short call_int2f + + global _remote_creat +_remote_creat: + mov al, 17h + jmp short call_int2f + + global _remote_findfirst +_remote_findfirst: + mov al, 1bh + jmp short call_int2f + + global _remote_findnext +_remote_findnext: + mov al, 1ch + jmp short call_int2f + + global _remote_close_all +_remote_close_all: + mov al, 1dh + jmp short call_int2f + + global _remote_doredirect +_remote_doredirect: + mov al, 1eh + jmp short call_int2f + + global _remote_printset +_remote_printset: + mov al, 1fh + jmp short call_int2f + + global _remote_flushall +_remote_flushall: + mov al, 20h + jmp short call_int2f + + global _remote_lseek +_remote_lseek: + mov al, 21h + jmp short call_int2f + + global _QRemote_Fn +_QRemote_Fn + mov al, 23h + jmp short call_int2f + + global _remote_printredir +_remote_printredir: + mov al, 25h + +call_int2f: + mov ah, 11h push bp mov bp,sp push es - push ds push si push di push dx push cx push bx - push ss ; hay, did I say assume - pop ds + cmp al, 0eh + je remote_setfattr + cmp al, 0fh + je remote_getfattr + cmp al, 1eh + je print_doredir + cmp al, 1fh + je print_doredir + cmp al, 21h ; 21h, Lseek from eof + je lseekeof + cmp al, 23h + je qremote_fn + cmp al, 25h + je remote_printredir - mov si,[bp+16] - les di,[bp+12] - mov dx,[bp+10] - mov cx,[bp+8] - mov bx,[bp+6] - mov ax,[bp+4] - - cmp al,08h ; R/W Remote File - je short int2f_r_1 - cmp al,09h - jne short int2f_r_2 -int2f_r_1: - call int2f_call - jnc short int2f_skip1 - jmp int2f_rfner -int2f_skip1: + les di, [bp+4] + cmp al, 08h + je remote_rw + cmp al, 09h + je remote_rw + cmp al, 0ch + je remote_getfree + +int2f_call_push: + push word [bp+8] ; very fakey, HaHa ;) +int2f_call: + stc ; set to fail + int 2fh + pop bx + jc no_clear_ax +clear_ax: xor ax,ax - les di,[bp+18] ; do return data stuff - mov [es:di],cx - jmp int2f_rfner -int2f_r_2: - cmp al,0ch ; Get Remote DPB - jne short int2f_r_3 - call int2f_call - jc int2f_rfner - les di,[bp+18] - mov [es:di+0],ax - mov [es:di+2],bx - mov [es:di+4],cx - mov [es:di+6],dx - xor ax,ax - jmp short int2f_rfner -int2f_r_3: - cmp al,0fh ; Get Remote File Attrib - jne short int2f_r_4 - call int2f_call - jc short int2f_rfner - mov si,di - les di,[bp+18] ; pointer to struct - mov [es:di+0],ax - mov [es:di+2],si ; lo - mov [es:di+4],bx ; high - mov [es:di+6],cx - mov [es:di+8],dx - xor ax,ax - jmp short int2f_rfner -int2f_r_4: - cmp al,01eh - je short int2f_r_5 - cmp al,01fh - jne short int2f_r_6 -int2f_r_5: - push ds - push word [bp+20] - pop ds - call int2f_call - pop ds - jc short int2f_rfner - xor ax,ax - jmp short int2f_rfner -int2f_r_6: - cmp al,021h ; Lseek from eof - jne short int2f_r_7 - call int2f_call - jc short int2f_rfner - les di,[bp+18] - mov [es:di],ax - mov [es:di+2],dx - xor ax,ax - jmp short int2f_rfner -int2f_r_7: - cmp al,022h ; Terminate process - jne short int2f_r_8 - mov ds,[_cu_psp] - call int2f_call - jmp short int2f_rfner -; -; everything else goes through here. -; -int2f_r_8: - call int2f_call - jc int2f_rfner - xor ax,ax -int2f_rfner: +no_clear_ax: + neg ax +no_neg_ax: pop bx pop cx pop dx pop di pop si - pop ds pop es pop bp ret -; -; Pull this one out of the Chain. -; - global _QRemote_Fn -_QRemote_Fn - push bp - mov bp,sp - push es + +lseekeof: + mov dx, [bp+8] + mov cx, [bp+10] + jmp int2f_call_push + +remote_getfattr: + stc ; set to fail + int 2fh + jc no_clear_ax + jmp short no_neg_ax + +remote_setfattr: + push word [bp+4] + jmp short int2f_call + +print_doredir: push ds - push si - push di - mov ax,1123h + mov si,[bp+14] + les di,[bp+10] + mov dx,[bp+8] + mov cx,[bp+6] + mov bx,[bp+4] + + mov ds, [bp+18] + push word [bp+16] ; very fakey, HaHa ;) + stc ; set to fail + int 2fh + pop bx + pop ds + jc no_clear_ax + jmp short clear_ax + +remote_getfree: + stc ; set to fail + int 2fh + jc no_clear_ax + mov di,[bp+8] + mov [di],ax + mov [di+2],bx + mov [di+4],cx + mov [di+6],dx + jmp short clear_ax + +remote_printredir: + mov dx, [bp+4] + push word [bp+6] + jmp short int2f_call + +qremote_fn: lds si,[bp+4] les di,[bp+8] stc int 2fh mov ax,0xffff - jc QRemote_Fn_out - xor ax,ax -QRemote_Fn_out: - pop di - pop si - pop ds - pop es - pop bp - ret + jc no_neg_ax + jmp short clear_ax - -int2f_call: - push bp - push word [bp+18] ; very fakey, HaHa ;) +remote_rw: mov cx, [bp+8] stc ; set to fail int 2fh - pop bp - pop bp - ret + jc int2f_carry + xor ax, ax +int2f_carry: neg ax + mov di, [bp+10] + mov [di], ax + mov ax, cx + jmp short no_neg_ax + global _remote_process_end +_remote_process_end: ; Terminate process + mov ds, [_cu_psp] + mov al, 22h + call call_int2f + push ss + pop ds + ret + %if 0 ; int_2f_111e_call(iregs FAR *iregs) ; diff --git a/kernel/inthndlr.c b/kernel/inthndlr.c index 7b3161c..38d1403 100644 --- a/kernel/inthndlr.c +++ b/kernel/inthndlr.c @@ -37,6 +37,9 @@ BYTE *RcsId = "$Id$"; /* * $Log$ + * Revision 1.32 2001/11/04 19:47:39 bartoldeman + * kernel 2025a changes: see history.txt + * * Revision 1.31 2001/09/23 20:39:44 bartoldeman * FAT32 support, misc fixes, INT2F/AH=12 support, drive B: handling * @@ -301,14 +304,22 @@ VOID ASMCFUNC int21_syscall(iregs FAR * irp) { /* Get Ctrl-C flag */ case 0x00: - irp->DL = break_ena ? TRUE : FALSE; + irp->DL = break_ena; break; /* Set Ctrl-C flag */ case 0x01: - break_ena = irp->DL ? TRUE : FALSE; + break_ena = irp->DL != 0; break; + case 0x02: /* andrew schulman: get/set extended control break */ + { + UBYTE tmp = break_ena; + irp->DL = break_ena; + break_ena = tmp != 0; + } + + /* Get Boot Drive */ case 0x05: irp->DL = BootDrive; @@ -322,8 +333,6 @@ VOID ASMCFUNC int21_syscall(iregs FAR * irp) irp->DH = version_flags; /* bit3:runs in ROM,bit 4: runs in HMA*/ break; - case 0x02: /* andrew schulman: get/set extended control break - should be done */ case 0x03: /* DOS 7 does not set AL */ case 0x07: /* neither here */ @@ -377,9 +386,7 @@ VOID ASMCFUNC int21_syscall(iregs FAR * irp) VOID ASMCFUNC int21_service(iregs FAR * r) { - COUNT rc = 0, - rc1; - psp FAR *p = MK_FP(cu_psp, 0); + COUNT rc = 0; void FAR *FP_DS_DX = MK_FP(r->DS, r->DX); /* this is saved so often, that this saves ~100 bytes */ @@ -387,7 +394,7 @@ VOID ASMCFUNC int21_service(iregs FAR * r) #define CLEAR_CARRY_FLAG() r->FLAGS &= ~FLG_CARRY #define SET_CARRY_FLAG() r->FLAGS |= FLG_CARRY - p->ps_stack = (BYTE FAR *) r; + ((psp FAR *)MK_FP(cu_psp, 0))->ps_stack = (BYTE FAR *) r; #ifdef DEBUG if (bDumpRegs) @@ -785,13 +792,10 @@ dispatch: /* Set Date */ case 0x2b: rc = DosSetDate( - (BYTE FAR *) & (r->DH), /* Month */ - (BYTE FAR *) & (r->DL), /* MonthDay */ - (COUNT FAR *) & (r->CX)); /* Year */ - if (rc != SUCCESS) - r->AL = 0xff; - else - r->AL = 0; + r->DH, /* Month */ + r->DL, /* MonthDay */ + r->CX); /* Year */ + r->AL = (rc != SUCCESS ? 0xff : 0); break; /* Get Time */ @@ -806,14 +810,11 @@ dispatch: /* Set Date */ case 0x2d: rc = DosSetTime( - (BYTE FAR *) & (r->CH), /* Hour */ - (BYTE FAR *) & (r->CL), /* Minutes */ - (BYTE FAR *) & (r->DH), /* Seconds */ - (BYTE FAR *) & (r->DL)); /* Hundredths */ - if (rc != SUCCESS) - r->AL = 0xff; - else - r->AL = 0; + r->CH, /* Hour */ + r->CL, /* Minutes */ + r->DH, /* Seconds */ + r->DL); /* Hundredths */ + r->AL = (rc != SUCCESS ? 0xff : 0); break; /* Set verify flag */ @@ -1048,20 +1049,16 @@ dispatch: /* Dos Read */ case 0x3f: - rc1 = DosRead(r->BX, r->CX, FP_DS_DX, (COUNT FAR *) & rc); + r->AX = DosRead(r->BX, r->CX, FP_DS_DX, (COUNT FAR *) & rc); if (rc != SUCCESS) goto error_exit; - else - r->AX = rc1; break; /* Dos Write */ case 0x40: - rc1 = DosWrite(r->BX, r->CX, FP_DS_DX, (COUNT FAR *) & rc); + r->AX = DosWrite(r->BX, r->CX, FP_DS_DX, (COUNT FAR *) & rc); if (rc != SUCCESS) goto error_exit; - else - r->AX = rc1; break; /* Dos Delete File */ @@ -1075,7 +1072,7 @@ dispatch: case 0x42: { ULONG lrc; - if ((rc = DosSeek(r->BX, (LONG) ((((LONG) (r->CX)) << 16) + r->DX), r->AL, &lrc)) < 0) + if ((rc = DosSeek(r->BX, (LONG) ((((LONG) (r->CX)) << 16) | r->DX), r->AL, &lrc)) < 0) goto error_exit; else { @@ -1243,13 +1240,8 @@ dispatch: /* dta for this call is set on entry. This */ /* needs to be changed for new versions. */ if ((rc = DosFindNext()) < 0) - { - if (rc == DE_FILENOTFND) - rc = DE_NFILES; goto error_exit; - } - else - r->AX = -SUCCESS; + r->AX = -SUCCESS; break; /* case 0x50: @@ -1363,10 +1355,12 @@ dispatch: break; case 0x03: - if (uppermem_root) { + if (uppermem_root) /* always error if not exists */ + { DosUmbLink(r->BL); break; - } /* else fall through */ + } + /* else fall through */ default: goto error_invalid; @@ -1463,7 +1457,7 @@ dispatch: case 0x07: case 0x08: case 0x09: - rc = -int2f_Remote_call(REM_PRINTREDIR, 0, 0, r->DX, 0, 0, (MK_FP(0, Int21AX))); + rc = remote_printredir(r->DX, Int21AX); if (rc != SUCCESS) goto error_exit; CLEAR_CARRY_FLAG(); @@ -1486,7 +1480,7 @@ dispatch: break; default: - rc = -int2f_Remote_call(REM_PRINTSET, r->BX, r->CX, r->DX, (MK_FP(r->ES, r->DI)), r->SI, (MK_FP(r->DS, Int21AX))); + rc = remote_printset(r->BX, r->CX, r->DX, (MK_FP(r->ES, r->DI)), r->SI, (MK_FP(r->DS, Int21AX))); if (rc != SUCCESS) goto error_exit; r->AX=SUCCESS; break; @@ -1515,7 +1509,7 @@ dispatch: int_2f_111e_call(r); break;*/ - rc = -int2f_Remote_call(REM_DOREDIRECT, r->BX, r->CX, r->DX, + rc = remote_doredirect(r->BX, r->CX, r->DX, (MK_FP(r->ES, r->DI)), r->SI, (MK_FP(r->DS, Int21AX))); if (rc != SUCCESS) goto error_exit; @@ -1561,21 +1555,17 @@ dispatch: /* UNDOCUMENTED: Double byte and korean tables */ case 0x63: { -#define DBLBYTE -#ifdef DBLBYTE - static char dbcsTable[2] = + static char dbcsTable[4] = { - 0, 0 + 0, 0, 0, 0 }; - void FAR *dp = &dbcsTable; - - r->DS = FP_SEG(dp); - r->SI = FP_OFF(dp); - r->AL = 0; -#else + r->DS = FP_SEG(&dbcsTable); + r->SI = FP_OFF(&dbcsTable); +#if 0 /* not really supported, but will pass. */ r->AL = 0x00; /*jpp: according to interrupt list */ - /*Bart: fails for PQDI: use the above again */ + /*Bart: fails for PQDI and WATCOM utilities: + use the above again */ #endif break; } @@ -1819,17 +1809,31 @@ break_out: { DWORD nfreeclst = xdffp->xdff_f.setdpbcounts.nfreeclst; DWORD cluster = xdffp->xdff_f.setdpbcounts.cluster; - if ((dpb->dpb_xfsinfosec == 0xffff && (nfreeclst != 0 || + if (ISFAT32(dpb)) + { + if ((dpb->dpb_xfsinfosec == 0xffff && (nfreeclst != 0 || cluster != 0)) || - nfreeclst == 1 || nfreeclst > dpb->dpb_size || + nfreeclst == 1 || nfreeclst > dpb->dpb_xsize || + cluster == 1 || cluster > dpb->dpb_xsize) + { + r->AX = -DE_INVLDPARM; + goto error_out; + } + dpb->dpb_xnfreeclst = nfreeclst; + dpb->dpb_xcluster = cluster; + write_fsinfo(dpb); + } + else + { + if (nfreeclst == 1 || nfreeclst > dpb->dpb_size || cluster == 1 || cluster > dpb->dpb_size) { r->AX = -DE_INVLDPARM; goto error_out; } - dpb->dpb_nfreeclst = nfreeclst; - dpb->dpb_cluster = cluster; - write_fsinfo(dpb); + dpb->dpb_nfreeclst = nfreeclst; + dpb->dpb_cluster = cluster; + } break; } case 0x01: @@ -1856,13 +1860,14 @@ rebuild_dpb: struct buffer FAR *bp; bpb FAR *bpbp; DWORD newmirroring = xdffp->xdff_f.setmirroring.newmirroring; - if (newmirroring != -1 && newmirroring & ~(0xf | 0x80)) + + if (newmirroring != -1 && (ISFAT32(dpb) && (newmirroring & ~(0xf | 0x80)))) { r->AX = -DE_INVLDPARM; goto error_out; } - xdffp->xdff_f.setmirroring.oldmirroring = dpb->dpb_xflags; - if (newmirroring != -1) + xdffp->xdff_f.setmirroring.oldmirroring = (ISFAT32(dpb) ? dpb->dpb_xflags : 0); + if (newmirroring != -1 && ISFAT32(dpb)) { bp = getblock(1, dpb->dpb_unit); bp->b_flag &= ~(BFR_DATA | BFR_DIR | BFR_FAT); @@ -1877,8 +1882,8 @@ rebuild_dpb: struct buffer FAR *bp; bpb FAR *bpbp; DWORD rootclst = xdffp->xdff_f.setroot.newrootclst; - if (rootclst != -1 && (rootclst == 1 || - rootclst > dpb->dpb_size)) + if (!ISFAT32(dpb) || (rootclst != -1 && (rootclst == 1 || + rootclst > dpb->dpb_xsize))) { r->AX = -DE_INVLDPARM; goto error_out; @@ -2115,19 +2120,52 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs r) case 0x03: /* get DOS data segment */ r.ds = FP_SEG(&nul_dev); - break; + break; + + case 0x06: /* invoke critical error */ + + /* code, drive number, error, device header */ + r.ax &= 0xff00; + r.ax |= CriticalError( + r.callerARG1 >> 8, + (r.callerARG1 & (EFLG_CHAR << 8)) ? 0 : r.callerARG1 & 0xff, + r.di, + MK_FP(r.bp,r.si)); + break; case 0x08: /* decrease SFT reference count */ { - UWORD FAR *SFTp = MK_FP(r.es,r.di); + sft FAR *p = MK_FP(r.es,r.di); - r.ax = *SFTp; - - if (--*SFTp == 0) --*SFTp; + r.ax = p->sft_count; + if (--p->sft_count == 0) --p->sft_count; } break; + case 0x0c: /* perform "device open" for device, set owner for FCB */ + + if (lpCurSft->sft_flags & SFT_FDEVICE) + { + request rq; + + rq.r_unit = 0; + rq.r_status = 0; + rq.r_command = C_OPEN; + rq.r_length = sizeof(request); + execrh((request FAR *) & rq, lpCurSft->sft_dev); + } + + /* just do it always, not just for FCBs */ + lpCurSft->sft_psp = cu_psp; + break; + + case 0x0d: /* get dos date/time */ + + r.ax = dos_getdate(); + r.dx = dos_gettime(); + break; + case 0x12: /* get length of asciiz string */ r.cx = fstrlen(MK_FP(r.es, r.di))+1; @@ -2135,6 +2173,44 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs r) break; + case 0x16: /* get address of system file table entry - used by NET.EXE + BX system file table entry number ( such as returned from 2F/1220) + returns + ES:DI pointer to SFT entry */ + { + sft FAR *p = get_sft(r.bx); + + r.es = FP_SEG(p); + r.di = FP_OFF(p); + break; + } + + case 0x17: /* get current directory structure for drive - used by NET.EXE + STACK: drive (0=A:,1=B,...) + ; returns + ; CF set if error + ; DS:SI pointer to CDS for drive + ; + ; called like + ; push 2 (c-drive) + ; mov ax,1217 + ; int 2f + ; + ; probable use: get sizeof(CDSentry) + */ + { + UWORD drv = r.callerARG1 & 0xff; + + if (drv >= lastdrive) + r.flags |= FLG_CARRY; + else + { + r.ds = FP_SEG(CDSp); + r.si = FP_OFF(&CDSp->cds_table[drv]); + r.flags &= ~FLG_CARRY; + } + break; + } case 0x18: /* get caller's registers */ @@ -2152,6 +2228,25 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs r) truename(MK_FP(r.ds,r.si), MK_FP(r.es,r.di),0); break; + + case 0x23: /* check if character device */ + { + struct dhdr FAR *dhp; + + dhp = IsDevice((BYTE FAR *)DirEntBuffer.dir_name); + + if (dhp) + { + r.bx = (r.bx & 0xff) | (dhp->dh_attr <<8); + r.flags &= ~FLG_CARRY; + } + else { + r.flags |= FLG_CARRY; + } + + } + + break; case 0x25: /* get length of asciiz string */ @@ -2178,48 +2273,11 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs r) doesn't work!! */ break; - case 0x16: /* get address of system file table entry - used by NET.EXE - BX system file table entry number ( such as returned from 2F/1220) - returns - ES:DI pointer to SFT entry */ - { - sft FAR *p = get_sft(r.bx); - - r.es = FP_SEG(p); - r.di = FP_OFF(p); - break; - } - - - case 0x17: /* get current directory structure for drive - used by NET.EXE - STACK: drive (0=A:,1=B,...) - ; returns - ; CF set if error - ; DS:SI pointer to CDS for drive - ; - ; called like - ; push 2 (c-drive) - ; mov ax,1217 - ; int 2f - ; - ; probable use: get sizeof(CDSentry) - */ - { - UWORD drv = r.callerARG1 & 0xff; - - if (drv >= lastdrive) - r.flags |= FLG_CARRY; - else - { - r.ds = FP_SEG(CDSp); - r.si = FP_OFF(&CDSp->cds_table[drv]); - r.flags &= ~FLG_CARRY; - } - break; - } default: - printf("unknown internal dos function INT2F/12%02x\n",function); - - } + printf("unimplemented internal dos function INT2F/12%02x\n",function); + r.flags |= FLG_CARRY; + break; + + } } diff --git a/kernel/io.asm b/kernel/io.asm index 1708c9b..a3a389f 100644 --- a/kernel/io.asm +++ b/kernel/io.asm @@ -28,6 +28,9 @@ ; $Header$ ; ; $Log$ +; Revision 1.11 2001/11/04 19:47:39 bartoldeman +; kernel 2025a changes: see history.txt +; ; Revision 1.10 2001/09/23 20:39:44 bartoldeman ; FAT32 support, misc fixes, INT2F/AH=12 support, drive B: handling ; @@ -81,7 +84,7 @@ extern ComTable:wrt TGROUP extern uPrtNo:wrt TGROUP extern CommonNdRdExit:wrt TGROUP - extern _NumFloppies:wrt DGROUP +;!! extern _NumFloppies:wrt DGROUP extern blk_stk_top:wrt DGROUP extern clk_stk_top:wrt DGROUP extern _reloc_call_blk_driver diff --git a/kernel/ioctl.c b/kernel/ioctl.c index f6daef2..eeca65d 100644 --- a/kernel/ioctl.c +++ b/kernel/ioctl.c @@ -35,6 +35,9 @@ static BYTE *RcsId = "$Id$"; /* * $Log$ + * Revision 1.12 2001/11/04 19:47:39 bartoldeman + * kernel 2025a changes: see history.txt + * * Revision 1.11 2001/07/22 01:58:58 bartoldeman * Support for Brian's FORMAT, DJGPP libc compilation, cleanups, MSCDEX * @@ -124,13 +127,37 @@ static BYTE *RcsId = "$Id$"; * WARNING: this code is non-portable (8086 specific). */ +/* TE 10/29/01 + + although device drivers have only 20 pushes available for them, + MS NET plays by its own rules + + at least TE's network card driver DM9PCI (some 10$ NE2000 clone) does: + with SP=8DC before calling down to execrh, and SP=8CC when + callf [interrupt], DM9PCI touches DOSDS:792, + 14 bytes into error stack :-((( + + so some optimizations were made. + this uses the fact, that only CharReq device buffer is ever used. + fortunately, this saves some code as well :-) + +*/ + + COUNT DosDevIOctl(iregs FAR * r) { sft FAR *s; struct dpb FAR *dpbp; - struct cds FAR *cdsp; - BYTE FAR *pBuffer = MK_FP(r->DS, r->DX); - COUNT nMode , dev; + COUNT nMode; + + /* commonly used, shouldn't harm to do front up */ + + CharReqHdr.r_length = sizeof(request); + CharReqHdr.r_trans = MK_FP(r->DS, r->DX); + CharReqHdr.r_status = 0; + CharReqHdr.r_count = r->CX; + + /* Test that the handle is valid */ switch (r->AL) @@ -169,14 +196,14 @@ COUNT DosDevIOctl(iregs FAR * r) /* JPP - changed to use default drive if drive=0 */ /* JT Fixed it */ - dev = ( r->BL == 0 ? default_drive : r->BL - 1); + CharReqHdr.r_unit = ( r->BL == 0 ? default_drive : r->BL - 1); - if (dev >= lastdrive) + if (CharReqHdr.r_unit >= lastdrive) return DE_INVLDDRV; else { - cdsp = &CDSp->cds_table[dev]; - dpbp = cdsp->cdsDpb; +/* cdsp = &CDSp->cds_table[CharReqHdr.r_unit]; */ + dpbp = CDSp->cds_table[CharReqHdr.r_unit].cdsDpb; } break; @@ -234,11 +261,7 @@ COUNT DosDevIOctl(iregs FAR * r) || ((r->AL == 0x0c) && (s->sft_dev->dh_attr & ATTR_GENIOCTL))) { CharReqHdr.r_unit = 0; - CharReqHdr.r_length = sizeof(request); CharReqHdr.r_command = nMode; - CharReqHdr.r_count = r->CX; - CharReqHdr.r_trans = pBuffer; - CharReqHdr.r_status = 0; execrh((request FAR *) & CharReqHdr, s->sft_dev); if (CharReqHdr.r_status & S_ERROR) @@ -287,12 +310,7 @@ COUNT DosDevIOctl(iregs FAR * r) } - CharReqHdr.r_unit = dev; - CharReqHdr.r_length = sizeof(request); CharReqHdr.r_command = nMode; - CharReqHdr.r_count = r->CX; - CharReqHdr.r_trans = pBuffer; - CharReqHdr.r_status = 0; execrh((request FAR *) & CharReqHdr, dpbp->dpb_device); @@ -348,7 +366,7 @@ COUNT DosDevIOctl(iregs FAR * r) return DE_INVLDFUNC; case 0x09: - if(cdsp->cdsFlags & CDSNETWDRV) + if(CDSp->cds_table[CharReqHdr.r_unit].cdsFlags & CDSNETWDRV) { r->DX = ATTR_REMOTE ; r->AX = S_DONE|S_BUSY; @@ -384,12 +402,7 @@ COUNT DosDevIOctl(iregs FAR * r) { - CharReqHdr.r_unit = dev; - CharReqHdr.r_length = sizeof(request); CharReqHdr.r_command = nMode; - CharReqHdr.r_count = r->CX; - CharReqHdr.r_trans = pBuffer; - CharReqHdr.r_status = 0; execrh((request FAR *) & CharReqHdr, dpbp->dpb_device); diff --git a/kernel/kernel.asm b/kernel/kernel.asm index 5898e3a..c0cd5c3 100644 --- a/kernel/kernel.asm +++ b/kernel/kernel.asm @@ -28,6 +28,9 @@ ; $Id$ ; ; $Log$ +; Revision 1.19 2001/11/04 19:47:39 bartoldeman +; kernel 2025a changes: see history.txt +; ; Revision 1.18 2001/09/23 20:39:44 bartoldeman ; FAT32 support, misc fixes, INT2F/AH=12 support, drive B: handling ; @@ -156,8 +159,51 @@ segment PSP STACK_SIZE equ 384/2 ; stack allocated in words +;************************************************************ +; KERNEL BEGINS HERE, i.e. this is byte 0 of KERNEL.SYS +;************************************************************ + ..start: -entry: +entry: + jmp short realentry + +;************************************************************ +; KERNEL CONFIGURATION AREA +; this is copied up on the very beginning +; it's a good idea to keep this in sync with KConfig.h +;************************************************************ + global _LowKernelConfig +_LowKernelConfig: + db 'CONFIG' ; constant + dw configend-configstart; size of config area + ; to be checked !!! + +configstart: + +DLASortByDriveNo db 0 ; sort disks by drive order +InitDiskShowDriveAssignment db 1 ; +SkipConfigSeconds db 2 ; + +configend: + +;************************************************************ +; KERNEL CONFIGURATION AREA END +;************************************************************ + + +;************************************************************ +; KERNEL real entry (at ~60:20) +; +; moves the INIT part of kernel.sys to high memory (~9000:0) +; then jumps there +; to aid debugging, some '123' messages are output +; this area is discardable and used as temporary PSP for the +; init sequence +;************************************************************ + + +realentry: ; execution continues here + push ax push bx pushf @@ -249,11 +295,12 @@ cont: ; inititalize api stacks for high water tests jns floppy add bl,3-1-128 floppy: mov byte [_BootDrive],bl ; tell where we came from - int 11h - mov cl,6 - shr al,cl - inc al - mov byte [_NumFloppies],al ; and how many + +;!! int 11h +;!! mov cl,6 +;!! shr al,cl +;!! inc al +;!! mov byte [_NumFloppies],al ; and how many mov ax,cs mov ds,ax @@ -262,6 +309,12 @@ floppy: mov byte [_BootDrive],bl ; tell where we came from segment INIT_TEXT_END + +;************************************************************ +; KERNEL CODE AREA END +; the NUL device +;************************************************************ + segment _TEXT ; @@ -288,6 +341,11 @@ _nul_intr: +;************************************************************ +; KERNEL FIXED DATA AREA +;************************************************************ + + segment _FIXED_DATA ; Because of the following bytes of data, THIS MODULE MUST BE THE FIRST @@ -365,8 +423,14 @@ setverPtr dw 0,0 ; 0037 setver list _LoL_nbuffers dw 1 ; 003F number of buffers dw 1 ; 0041 size of pre-read buffer global _BootDrive -_BootDrive db 1 ; 0043 drive we booted from +_BootDrive db 1 ; 0043 drive we booted from + +%IFNDEF I386 db 0 ; 0044 cpu type (1 if >=386) +%ELSE + db 1 ; 0044 cpu type (1 if >=386) +%ENDIF + dw 0 ; 0045 Extended memory in KBytes buf_info: global _firstbuf @@ -595,11 +659,12 @@ _lpCurSft times 2 dw 0 ;27e - Current SFT _current_ldt times 2 dw 0 ;282 - Current CDS global _lpFcb _lpFcb times 2 dw 0 ;286 - pointer to callers FCB - global current_ifn -current_ifn dw 0 ;28A - SFT index for next open + global _current_sft_idx +_current_sft_idx dw 0 ;28A - SFT index for next open + ; used by MS NET ; Pad to 05b2h - times (292h - ($ - _internal_data)) db 0 + times (292h - ($ - _internal_data)) db 0 dw __PriPathBuffer ; 292 - "sda_WFP_START" offset in DOS DS of first filename argument dw __SecPathBuffer ; 294 - "sda_REN_WFP" offset in DOS DS of second filename argument @@ -641,22 +706,23 @@ _disk_api_tos: global _char_api_tos _char_api_tos: apistk_top: - + db 0 ; 780 ??? _VolChange db 0 ;781 - volume change _VirtOpen db 0 ;782 - virtual open flag ; controlled variables end at offset 78Ch so pad to end times (78ch - ($ - _internal_data)) db 0 _swap_indos: + ; ; end of controlled variables ; segment _BSS - global _NumFloppies -_NumFloppies resw 1 -intr_dos_stk resw 1 -intr_dos_seg resw 1 +;!! global _NumFloppies +;!!_NumFloppies resw 1 +;!!intr_dos_stk resw 1 +;!!intr_dos_seg resw 1 global _ram_top diff --git a/kernel/lfnapi.c b/kernel/lfnapi.c index 71211ee..22ea140 100644 --- a/kernel/lfnapi.c +++ b/kernel/lfnapi.c @@ -49,7 +49,7 @@ COUNT lfn_allocate_inode() COUNT lfn_free_inode(COUNT handle) { f_node_ptr fnp = xlt_fd(handle); - if (fnp == 0 || fnp->f_count <= 0) return E_INVLHNDL; + if (fnp == 0 || fnp->f_count <= 0) return E_INVLDHNDL; release_f_node(fnp); } @@ -90,7 +90,7 @@ COUNT lfn_dir_read(COUNT handle, lfn_inode_ptr lip) name string */ ULONG original_diroff; f_node_ptr fnp = xlt_fd(handle); - if (fnp == 0 || fnp->f_count <= 0) return E_INVLHNDL; + if (fnp == 0 || fnp->f_count <= 0) return E_INVLDHNDL; if (lfnp->l_dirstart == 0) { @@ -102,13 +102,13 @@ COUNT lfn_dir_read(COUNT handle, lfn_inode_ptr lip) while (TRUE) { - if (dir_read(fnp) != DIRENT_SIZE) return E_IOERROR; - if (fnp->f_dir.dir_name[0] != DELETED && fnp->f_dir.dir_name[0] != 0 - && fnp->f_dir.dir_attrib != D_LFN) + if (dir_read(fnp) <= 0) return E_IOERROR; + if (fnp->f_dir.dir_name[0] != DELETED && fnp->f_dir.dir_name[0] != '\0' + && fnp->f_dir.dir_attrib != D_LFN) { - fmemcpy(lip->l_dir, fnp->f_dir, sizeof(struct dirent)); + fmemcpy(lip->l_dir, fnp->f_dir, sizeof(struct dirent)); lip->l_diroff = fnp->f_diroff; - lip->l_dirstart = fnp->f_dirstart; + lip->l_dirstart = fnp->f_dirstart; break; } } @@ -118,11 +118,11 @@ COUNT lfn_dir_read(COUNT handle, lfn_inode_ptr lip) { if (fnp->f_diroff == 0) break; fnp->f_diroff -= 2*DIRENT_SIZE; - if (dir_read(fnp) != DIRENT_SIZE) return E_IOERROR; + if (dir_read(fnp) <= 0) return E_IOERROR; if (fnp->f_dir.dir_name[0] == '\0' || fnp->f_dir.dir_name[0] == DELETED) break; if (!lfn_to_unicode(lip->name, - (UBYTE FAR *)fnp->f_dir, index)) break; + (UBYTE FAR *)fnp->f_dir, index)) break; } if (lip->name[0] == 0) diff --git a/kernel/main.c b/kernel/main.c index 2293cab..07c41c9 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -32,6 +32,12 @@ #include "dyndata.h" #include "init-dat.h" +GLOBAL BYTE copyright[] = + "(C) Copyright 1995-2001 Pasquale J. Villani and The FreeDOS Project.\n" + "All Rights Reserved. This is free software and comes with ABSOLUTELY NO\n" + "WARRANTY; you can redistribute it and/or modify it under the terms of the\n" + "GNU General Public License as published by the Free Software Foundation;\n" + "either version 2, or (at your option) any later version.\n"; /* @@ -53,7 +59,7 @@ GLOBAL BYTE DOSFAR default_drive; /* default drive for dos */ GLOBAL BYTE DOSFAR os_release[]; -GLOBAL BYTE DOSFAR copyright[]; +/* GLOBAL BYTE DOSFAR copyright[]; */ GLOBAL seg DOSFAR RootPsp; /* Root process -- do not abort */ extern struct dpb FAR * DOSFAR DPBp; /* First drive Parameter Block */ @@ -73,8 +79,14 @@ extern BYTE FAR _HMATextEnd[]; static BYTE *mainRcsId = "$Id$"; #endif +struct _KernelConfig InitKernelConfig = {0}; + + /* * $Log$ + * Revision 1.22 2001/11/04 19:47:39 bartoldeman + * kernel 2025a changes: see history.txt + * * Revision 1.21 2001/09/23 20:39:44 bartoldeman * FAT32 support, misc fixes, INT2F/AH=12 support, drive B: handling * @@ -264,8 +276,9 @@ INIT VOID ASMCFUNC FreeDOSmain(void) DosDataSeg = (__segment)&DATASTART; DosTextSeg = (__segment)&prn_dev; #endif - - + + fmemcpy(&InitKernelConfig,&LowKernelConfig,sizeof(InitKernelConfig)); + setvec(0, int0_handler); /* zero divide */ setvec(1, empty_handler); /* single step */ @@ -417,7 +430,7 @@ INIT VOID FsConfig(VOID) dup2(STDIN, STDOUT); /* 2 is /dev/con (stderr) */ - dup2(STDIN, STDERR); + dup2(STDIN, STDERR); /* 3 is /dev/aux */ open("AUX", O_RDWR); diff --git a/kernel/memmgr.c b/kernel/memmgr.c index 3537ed2..fa89de7 100644 --- a/kernel/memmgr.c +++ b/kernel/memmgr.c @@ -35,6 +35,9 @@ static BYTE *memmgrRcsId = "$Id$"; /* * $Log$ + * Revision 1.16 2001/11/04 19:47:39 bartoldeman + * kernel 2025a changes: see history.txt + * * Revision 1.15 2001/09/23 20:39:44 bartoldeman * FAT32 support, misc fixes, INT2F/AH=12 support, drive B: handling * @@ -569,27 +572,28 @@ COUNT DosMemCheck(void) COUNT FreeProcessMem(UWORD ps) { mcb FAR *p; - COUNT x = 0; + BYTE oldumbstate = uppermem_link; - /* Initialize */ - p = para2far(first_mcb); + /* link in upper memory to free those , too */ + DosUmbLink(1); + + /* Search through all memory blocks */ + for (p = para2far(first_mcb);; p = nxtMCB(p)) + { + + if (!mcbValid(p)) /* check for corruption */ + return DE_MCBDESTRY; - /* Search through memory blocks */ - while (mcbValid(p)) /* check for corruption */ - { if (p->m_psp == ps) - DosMemFree(FP_SEG(p)); - - /* not corrupted - if last we're OK! */ - if (p->m_type == MCB_LAST){ - if(x) - return DE_MCBDESTRY; - return SUCCESS; + DosMemFree(FP_SEG(p)); + + if (p->m_type == MCB_LAST) + break; } - p = nxtMCB(p); - } - return DE_MCBDESTRY; + DosUmbLink(oldumbstate); + + return SUCCESS; } #if 0 @@ -661,6 +665,9 @@ VOID DosUmbLink(BYTE n) REG mcb FAR *p; REG mcb FAR *q; mcb FAR *end_of_conv_mem = para2far(ram_top*64-1); + + if (uppermem_root == 0) + return; q = p = para2far(first_mcb); /* like a xor thing! */ diff --git a/kernel/misc.c b/kernel/misc.c index fa26a11..784d7d7 100644 --- a/kernel/misc.c +++ b/kernel/misc.c @@ -34,6 +34,9 @@ static BYTE *miscRcsId = "$Id$"; /* * $Log$ + * Revision 1.6 2001/11/04 19:47:39 bartoldeman + * kernel 2025a changes: see history.txt + * * Revision 1.5 2001/04/15 03:21:50 bartoldeman * See history.txt for the list of fixes. * @@ -92,7 +95,7 @@ static BYTE *miscRcsId = "$Id$"; */ #include "globals.h" -#ifndef ASMSUPT +#ifndef I86 VOID scopy(REG BYTE * s, REG BYTE * d) { diff --git a/kernel/network.c b/kernel/network.c index e941e7f..aab61c8 100644 --- a/kernel/network.c +++ b/kernel/network.c @@ -36,6 +36,9 @@ static BYTE *RcsId = "$Id$"; /* * $Log$ + * Revision 1.15 2001/11/04 19:47:39 bartoldeman + * kernel 2025a changes: see history.txt + * * Revision 1.14 2001/07/24 16:56:29 bartoldeman * fixes for FCBs, DJGPP ls, DBLBYTE, dyninit allocation (2024e). * @@ -108,28 +111,3 @@ VOID set_machine_name(BYTE FAR * netname, UWORD name_num) fmemcpy(&net_name, netname, 15); net_set_count++; } - -/* - * Read/Write from/to remote file. - * SFT gets updated with the amount of bytes r/w. - * - */ -UCOUNT Remote_RW(UWORD func, UCOUNT n, BYTE FAR * bp, sft FAR * s, COUNT FAR * err) -{ - - BYTE FAR *save_dta; - UWORD rc, - rx; - - save_dta = dta; - lpCurSft = (sfttbl FAR *) s; - current_filepos = s->sft_posit; /* needed for MSCDEX */ - dta = bp; - rx = int2f_Remote_call(func, 0, n, 0, (VOID FAR *) s, 0, (VOID FAR *) & rc); - dta = save_dta; - *err = -rx; - return ((UCOUNT) rc); -} - - - diff --git a/kernel/nls_load.c b/kernel/nls_load.c index f3bf199..ac8f657 100644 --- a/kernel/nls_load.c +++ b/kernel/nls_load.c @@ -40,6 +40,9 @@ static BYTE *RcsId = "$Id$"; /* * $Log$ + * Revision 1.2 2001/11/04 19:47:39 bartoldeman + * kernel 2025a changes: see history.txt + * * Revision 1.1 2000/08/06 05:50:17 jimtabor * Add new files and update cvs with patches and changes * @@ -58,7 +61,7 @@ static int err(void) #define readStruct(s) readStructure(&(s), sizeof(s), fd) static int readStructure(void *buf, int size, COUNT fd) -{ if(dos_read(fd, buf, size) == size) +{ if(DosRead(fd, buf, size) == size) return 1; return err(); @@ -66,14 +69,14 @@ static int readStructure(void *buf, int size, COUNT fd) /* Evaluate each argument only once */ #define readFct(p,f) readFct_((p), (f), fd) int readFct_(void *buf, struct csys_function *fct, COUNT fd) -{ if(dos_lseek(fd, fct->csys_rpos, 0) >= 0) +{ if(DosLseek(fd, fct->csys_rpos, 0) >= 0) return readStructure(buf, fct->csys_length, fd); return err(); } #define seek(n) rseek((LONG)(n), fd) static rseek(LONG rpos, COUNT fd) -{ if(dos_lseek(fd, rpos, 1) >= 0) +{ if(DosLseek(fd, rpos, 1) >= 0) return 1; return err(); @@ -84,18 +87,18 @@ COUNT csysOpen(void) { COUNT fd; struct nlsCSys_fileHeader header; - if((fd = dos_open((BYTE FAR*)filename, 0)) < 0) { + if((fd = DosOpen((BYTE FAR*)filename, 0)) < 0) { printf("Cannot open: \"%s\"\n", filename); return 1; } - if(dos_read(fd, &header, sizeof(header)) != sizeof(header); + if(DosRead(fd, &header, sizeof(header)) != sizeof(header); || strcmp(header.csys_idstring, CSYS_FD_IDSTRING) != 0 - || dos_lseek(fd, (LONG)sizeof(csys_completeFileHeader), 0) + || DosLseek(fd, (LONG)sizeof(csys_completeFileHeader), 0) != (LONG)sizeof(csys_completeFileHeader)) { printf("No valid COUNTRY.SYS: \"%s\"\n\nTry NLSFUNC /i %s\n" , filename, filename); - dos_close(fd); + DosClose(fd); return -1; } @@ -265,7 +268,7 @@ int csysLoadPackage(COUNT fd) } /* OK --> update the rpos member */ - fct.csys_rpos += dos_ltell(fd); + fct.csys_rpos += DosLtell(fd); totalSize += fct.csys_length; ++numFct; } while(--numE); @@ -379,7 +382,7 @@ INIT BOOL LoadCountryInfo(char *fnam) strcpy(filename, fnam); if((fd = csysOpen()) >= 0) { rc = csysLoadPackage(fd); - dos_close(fd); + DosClose(fd); return rc; } } else diff --git a/kernel/prf.c b/kernel/prf.c index d43a352..0bb613f 100644 --- a/kernel/prf.c +++ b/kernel/prf.c @@ -30,7 +30,7 @@ /*#define DOSEMU*/ -#ifdef FORINIT +#ifdef _INIT #define fstrlen reloc_call_fstrlen #define put_console init_put_console #define ltob init_ltob @@ -50,6 +50,9 @@ static BYTE *prfRcsId = "$Id$"; /* * $Log$ + * Revision 1.13 2001/11/04 19:47:39 bartoldeman + * kernel 2025a changes: see history.txt + * * Revision 1.12 2001/09/23 20:39:44 bartoldeman * FAT32 support, misc fixes, INT2F/AH=12 support, drive B: handling * @@ -78,6 +81,9 @@ static BYTE *prfRcsId = "$Id$"; * recoded for smaller object footprint, added main() for testing+QA * * $Log$ + * Revision 1.13 2001/11/04 19:47:39 bartoldeman + * kernel 2025a changes: see history.txt + * * Revision 1.12 2001/09/23 20:39:44 bartoldeman * FAT32 support, misc fixes, INT2F/AH=12 support, drive B: handling * diff --git a/kernel/proto.h b/kernel/proto.h index 93211a5..0fe04b5 100644 --- a/kernel/proto.h +++ b/kernel/proto.h @@ -34,6 +34,9 @@ static BYTE *Proto_hRcsId = "$Id$"; /* * $Log$ + * Revision 1.23 2001/11/04 19:47:39 bartoldeman + * kernel 2025a changes: see history.txt + * * Revision 1.22 2001/09/23 20:39:44 bartoldeman * FAT32 support, misc fixes, INT2F/AH=12 support, drive B: handling * @@ -200,6 +203,7 @@ BOOL flush_buffers(REG COUNT dsk); BOOL flush1(struct buffer FAR * bp); BOOL flush(void); BOOL fill(REG struct buffer FAR * bp, ULONG blkno, COUNT dsk); +BOOL DeleteBlockInBufferCache(ULONG blknolow, ULONG blknohigh, COUNT dsk); /* *** Changed on 9/4/00 BER */ UWORD dskxfer(COUNT dsk, ULONG blkno, VOID FAR * buf, UWORD numblocks, COUNT mode); /* *** End of change */ @@ -227,12 +231,15 @@ struct dpb FAR *GetDriveDPB(UBYTE drive, COUNT *rc); BYTE FAR *get_root(BYTE FAR *); BOOL fnmatch(BYTE FAR *, BYTE FAR *, COUNT, COUNT); BOOL check_break(void); -UCOUNT GenericRead(COUNT hndl, UCOUNT n, BYTE FAR * bp, COUNT FAR * err, +UCOUNT GenericReadSft(sft far *sftp, UCOUNT n, BYTE FAR * bp, COUNT FAR * err, BOOL force_binary); COUNT SftSeek(sft FAR *sftp, LONG new_pos, COUNT mode); /* COUNT DosRead(COUNT hndl, UCOUNT n, BYTE FAR * bp, COUNT FAR * err); */ -#define DosRead(hndl,n,bp,err) GenericRead(hndl, n, bp, err,FALSE) -UCOUNT DosWrite(COUNT hndl, UCOUNT n, BYTE FAR * bp, COUNT FAR * err); +#define GenericRead(hndl, n, bp, err, t) GenericReadSft(get_sft(hndl), n, bp, err, t) +#define DosRead(hndl, n, bp, err) GenericRead(hndl, n, bp, err, FALSE) +#define DosReadSft(sftp, n, bp, err) GenericReadSft(sftp, n, bp, err, FALSE) +UCOUNT DosWriteSft(sft FAR *sftp, UCOUNT n, BYTE FAR * bp, COUNT FAR * err); +#define DosWrite(hndl, n, bp, err) DosWriteSft(get_sft(hndl), n, bp, err) COUNT DosSeek(COUNT hndl, LONG new_pos, COUNT mode, ULONG * set_pos); COUNT DosCreat(BYTE FAR * fname, COUNT attrib); COUNT DosCreatSft(BYTE * fname, COUNT attrib); @@ -286,9 +293,10 @@ COUNT char_error(request * rq, struct dhdr FAR * lpDevice); COUNT block_error(request * rq, COUNT nDrive, struct dhdr FAR * lpDevice); /* fatdir.c */ +VOID dir_init_fnode(f_node_ptr fnp, CLUSTER dirstart); f_node_ptr dir_open(BYTE * dirname); COUNT dir_read(REG f_node_ptr fnp); -COUNT dir_write(REG f_node_ptr fnp); +BOOL dir_write(REG f_node_ptr fnp); VOID dir_close(REG f_node_ptr fnp); COUNT dos_findfirst(UCOUNT attr, BYTE * name); COUNT dos_findnext(void); @@ -296,6 +304,7 @@ void ConvertName83ToNameSZ(BYTE FAR *destSZ, BYTE FAR *srcFCBName); int FileName83Length(BYTE *filename83); /* fatfs.c */ +ULONG clus2phys(CLUSTER cl_no, struct dpb FAR *dpbp); COUNT dos_open(BYTE * path, COUNT flag); BOOL fcmp(BYTE * s1, BYTE * s2, COUNT n); BOOL fcmp_wild(BYTE FAR * s1, BYTE FAR * s2, COUNT n); @@ -499,9 +508,9 @@ VOID break_handler(void); /* systime.c */ VOID DosGetTime(BYTE FAR * hp, BYTE FAR * mp, BYTE FAR * sp, BYTE FAR * hdp); -COUNT DosSetTime(BYTE FAR * hp, BYTE FAR * mp, BYTE FAR * sp, BYTE FAR * hdp); +COUNT DosSetTime(BYTE h, BYTE m, BYTE s, BYTE hd); VOID DosGetDate(BYTE FAR * wdp, BYTE FAR * mp, BYTE FAR * mdp, COUNT FAR * yp); -COUNT DosSetDate(BYTE FAR * mp, BYTE FAR * mdp, COUNT FAR * yp); +COUNT DosSetDate(UWORD Month, UWORD DayOfMonth, UWORD Year); UWORD *is_leap_year_monthdays(UWORD year); UWORD DaysFromYearMonthDay(UWORD Year, UWORD Month, UWORD DayOfMonth); @@ -523,13 +532,32 @@ COUNT get_verify_drive(char FAR * src); COUNT ASMCFUNC truename(char FAR * src, char FAR * dest, COUNT t); /* network.c */ -COUNT ASMCFUNC int2f_Remote_call(UWORD func, UWORD b, UCOUNT n, UWORD d, VOID FAR * s, UWORD i, VOID FAR * data); +COUNT ASMCFUNC remote_doredirect(UWORD b, UCOUNT n, UWORD d, VOID FAR * s, UWORD i, VOID FAR * data); +COUNT ASMCFUNC remote_printset(UWORD b, UCOUNT n, UWORD d, VOID FAR * s, UWORD i, VOID FAR * data); +COUNT ASMCFUNC remote_rename(VOID); +COUNT ASMCFUNC remote_delete(VOID); +COUNT ASMCFUNC remote_chdir(VOID); +COUNT ASMCFUNC remote_mkdir(VOID); +COUNT ASMCFUNC remote_rmdir(VOID); +COUNT ASMCFUNC remote_close_all(VOID); +COUNT ASMCFUNC remote_process_end(VOID); +COUNT ASMCFUNC remote_flushall(VOID); +COUNT ASMCFUNC remote_findfirst(VOID FAR *s); +COUNT ASMCFUNC remote_findnext(VOID FAR *s); +COUNT ASMCFUNC remote_getfattr(VOID); +COUNT ASMCFUNC remote_getfree(VOID FAR *s, VOID *d); +COUNT ASMCFUNC remote_open(sft FAR *s, COUNT mode); +LONG ASMCFUNC remote_lseek(sft FAR *s, LONG new_pos); +UCOUNT ASMCFUNC remote_read(sft FAR *s, UCOUNT n, COUNT * err); +UCOUNT ASMCFUNC remote_write(sft FAR *s, UCOUNT n, COUNT * err); +COUNT ASMCFUNC remote_creat(sft FAR *s, COUNT attr); +COUNT ASMCFUNC remote_setfattr(COUNT attr); +COUNT ASMCFUNC remote_printredir(UCOUNT dx, UCOUNT ax); +COUNT ASMCFUNC remote_close(sft FAR *s); COUNT ASMCFUNC QRemote_Fn(char FAR * s, char FAR * d); UWORD get_machine_name(BYTE FAR * netname); VOID set_machine_name(BYTE FAR * netname, UWORD name_num); -UCOUNT Remote_RW(UWORD func, UCOUNT n, BYTE FAR * bp, sft FAR * s, COUNT FAR * err); -COUNT Remote_find(UWORD func); /* procsupt.asm */ VOID ASMCFUNC exec_user(iregs FAR * irp); diff --git a/kernel/strings.c b/kernel/strings.c index c9a89ee..b23fa75 100644 --- a/kernel/strings.c +++ b/kernel/strings.c @@ -34,6 +34,9 @@ static BYTE *stringsRcsId = "$Id$"; /* * $Log$ + * Revision 1.6 2001/11/04 19:47:39 bartoldeman + * kernel 2025a changes: see history.txt + * * Revision 1.5 2001/04/15 03:21:50 bartoldeman * See history.txt for the list of fixes. * @@ -97,7 +100,7 @@ static BYTE *stringsRcsId = "$Id$"; * Initial revision. */ -#ifndef ASMSUPT +#ifndef I86 COUNT strlen(REG BYTE * s) { REG WORD cnt = 0; diff --git a/kernel/syspack.c b/kernel/syspack.c index 2947bac..992f682 100644 --- a/kernel/syspack.c +++ b/kernel/syspack.c @@ -36,6 +36,9 @@ static BYTE *syspackRcsId = "$Id$"; /* * $Log$ + * Revision 1.5 2001/11/04 19:47:39 bartoldeman + * kernel 2025a changes: see history.txt + * * Revision 1.4 2001/09/23 20:39:44 bartoldeman * FAT32 support, misc fixes, INT2F/AH=12 support, drive B: handling * @@ -164,4 +167,4 @@ VOID putdirent(struct dirent FAR * dp, BYTE FAR * vp) for (i = 0, p = (BYTE FAR *) & vp[DIR_RESERVED]; i < 10; i++) *p++ = NULL; } -#endif \ No newline at end of file +#endif diff --git a/kernel/systime.c b/kernel/systime.c index c614b7d..4599c0c 100644 --- a/kernel/systime.c +++ b/kernel/systime.c @@ -37,6 +37,9 @@ static BYTE *RcsId = "$Id$"; /* * $Log$ + * Revision 1.7 2001/11/04 19:47:39 bartoldeman + * kernel 2025a changes: see history.txt + * * Revision 1.6 2001/08/19 12:58:36 bartoldeman * Time and date fixes, Ctrl-S/P, findfirst/next, FCBs, buffers, tsr unloading * @@ -166,17 +169,17 @@ VOID DosGetTime(BYTE FAR * hp, BYTE FAR * mp, BYTE FAR * sp, BYTE FAR * hdp) *hdp = ClkRecord.clkHundredths; } -COUNT DosSetTime(BYTE FAR * hp, BYTE FAR * mp, BYTE FAR * sp, BYTE FAR * hdp) +COUNT DosSetTime(BYTE h, BYTE m, BYTE s, BYTE hd) { BYTE Month, DayOfMonth, DayOfWeek; COUNT Year; DosGetDate((BYTE FAR *) & DayOfWeek, (BYTE FAR *) & Month, (BYTE FAR *) & DayOfMonth, (COUNT FAR *) & Year); - ClkRecord.clkHours = *hp; - ClkRecord.clkMinutes = *mp; - ClkRecord.clkSeconds = *sp; - ClkRecord.clkHundredths = *hdp; + ClkRecord.clkHours = h; + ClkRecord.clkMinutes = m; + ClkRecord.clkSeconds = s; + ClkRecord.clkHundredths = hd; ClkRecord.clkDays = DaysFromYearMonthDay(Year, Month, DayOfMonth); @@ -232,15 +235,12 @@ COUNT FAR *yp; *wdp = (ClkRecord.clkDays + 2) % 7; } -COUNT DosSetDate(mp, mdp, yp) -BYTE FAR *mp, - FAR * mdp; -COUNT FAR *yp; +COUNT DosSetDate(Month, DayOfMonth, Year) +UWORD Month, + DayOfMonth, + Year; { - UWORD *pdays, Month, DayOfMonth,Year; - Month = *mp; - DayOfMonth = *mdp; - Year = *yp; + UWORD *pdays; pdays = is_leap_year_monthdays(Year); if (Year < 1980 || Year > 2099 diff --git a/kernel/task.c b/kernel/task.c index a7bbd8e..4c7b76a 100644 --- a/kernel/task.c +++ b/kernel/task.c @@ -35,6 +35,9 @@ static BYTE *RcsId = "$Id$"; /* * $Log$ + * Revision 1.19 2001/11/04 19:47:39 bartoldeman + * kernel 2025a changes: see history.txt + * * Revision 1.18 2001/09/23 20:39:44 bartoldeman * FAT32 support, misc fixes, INT2F/AH=12 support, drive B: handling * @@ -313,7 +316,7 @@ COUNT ChildEnv(exec_blk FAR * exp, UWORD * pChildEnvSeg, char far * pathname) /* The following code is 8086 dependant */ VOID new_psp(psp FAR * p, int psize) { - REG COUNT i; + REG COUNT i; psp FAR *q = MK_FP(cu_psp, 0); /* Clear out new psp first */ @@ -356,6 +359,7 @@ VOID new_psp(psp FAR * p, int psize) /* user stack pointer - int 21 */ p->ps_stack = q->ps_stack; /* file table - 0xff is unused */ + for (i = 0; i < 20; i++) p->ps_files[i] = 0xff; @@ -390,7 +394,7 @@ VOID new_psp(psp FAR * p, int psize) RootPsp = FP_SEG(p); } -static UWORD patchPSP(UWORD pspseg, UWORD envseg, exec_blk FAR *exb, +STATIC UWORD patchPSP(UWORD pspseg, UWORD envseg, exec_blk FAR *exb, BYTE FAR * fnam) { psp FAR *psp; @@ -475,6 +479,9 @@ COUNT DosComLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode) { return rc; } + + /* COMFILES will always be loaded in largest area. is that true TE*/ + /* Now find out how many paragraphs are available */ if ((rc = DosMemLargest((seg FAR *) & asize)) != SUCCESS) { @@ -483,7 +490,7 @@ COUNT DosComLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode) } com_size = asize; - if ( ModeLoadHigh && uppermem_root) + if ( ModeLoadHigh ) { DosUmbLink(1); /* link in UMB's */ } @@ -519,7 +526,7 @@ COUNT DosComLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode) else mem = exp->load.load_seg; - if ( ModeLoadHigh && uppermem_root) + if ( ModeLoadHigh ) { DosUmbLink(UMBstate); /* restore link state */ } @@ -539,16 +546,19 @@ COUNT DosComLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode) sp = MK_FP(mem, 0); else { /* test the filesize against the allocated memory */ - UWORD tmp = 16; - + sp = MK_FP(mem, sizeof(psp)); /* This is a potential problem, what to do with .COM files larger than the allocated memory? MS DOS always only loads the very first 64KB - sizeof(psp) bytes. -- 1999/04/21 ska */ - if ((ULONG)com_size > (ULONG)asize * tmp) /* less memory than the .COM file has */ - (ULONG)com_size = (ULONG)asize * tmp; /* << 4 */ + + /* BUG !! in case of LH, memory may be smaller then 64K TE*/ + + + if ((ULONG)com_size > ((ULONG)asize << 4)) /* less memory than the .COM file has */ + (ULONG)com_size = (ULONG)asize << 4; } do { @@ -581,6 +591,12 @@ COUNT DosComLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode) { case LOADNGO: { + /* BUG !! + this works only, if COMSIZE >= 64K + in case of LH, this is not necessarily true + */ + + *((UWORD FAR *) MK_FP(mem, 0xfffe)) = (UWORD) 0; /* build the user area on the stack */ @@ -603,8 +619,8 @@ COUNT DosComLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode) --InDOS; exec_user(irp); - /* We should never be here */ - fatal("KERNEL RETURNED!!!"); + /* We should never be here + fatal("KERNEL RETURNED!!!"); */ break; } case LOAD: @@ -634,10 +650,11 @@ VOID return_user(void) setvec(0x24, p->ps_isv24); /* And free all process memory if not a TSR return */ - int2f_Remote_call(REM_PROCESS_END, 0, 0, 0, 0, 0, 0); + remote_process_end(); /* might be a good idea to do that after closing + but doesn't help NET either TE */ if (!tsr) { - int2f_Remote_call(REM_CLOSEALL, 0, 0, 0, 0, 0, 0); + remote_close_all(); for (i = 0; i < p->ps_maxfiles; i++) { DosClose(i); @@ -645,6 +662,7 @@ VOID return_user(void) FcbCloseAll(); FreeProcessMem(cu_psp); } + cu_psp = p->ps_parent; q = MK_FP(cu_psp, 0); @@ -662,25 +680,14 @@ VOID return_user(void) COUNT DosExeLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode) { - COUNT rc, + COUNT rc; /*err, */ /*env_size,*/ - i; - UCOUNT nBytesRead; + UWORD mem, env, asize, start_seg; - ULONG image_size; - ULONG image_offset; - BYTE FAR *sp; - psp FAR *p; - psp FAR *q = MK_FP(cu_psp, 0); - mcb FAR *mp; - iregs FAR *irp; - UWORD reloc[2]; - seg FAR *spot; - LONG exe_size; int ModeLoadHigh = mode & 0x80; UBYTE UMBstate = uppermem_link; @@ -696,17 +703,23 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode) } else mem = exp->load.load_seg; + + + { + ULONG image_size; + ULONG image_offset; + LONG exe_size; + mcb FAR *mp; + /* compute image offset from the header */ - asize = 16; - image_offset = (ULONG)header.exHeaderSize * asize; + image_offset = (ULONG)header.exHeaderSize * 16; /* compute image size by removing the offset from the */ /* number pages scaled to bytes plus the remainder and */ /* the psp */ /* First scale the size */ - asize = 512; - image_size = (ULONG)header.exPages * asize; + image_size = (ULONG)header.exPages * 512; /* remove the offset */ image_size -= image_offset; @@ -716,7 +729,7 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode) if (mode != OVERLAY) { - if ( ModeLoadHigh && uppermem_root) + if ( ModeLoadHigh ) { DosUmbLink(1); /* link in UMB's */ mem_access_mode |= ModeLoadHigh; @@ -765,7 +778,7 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode) exe_size = asize; -/* /// Removed closing curly brace. We should not attempt to allocate + /* /// Removed closing curly brace. We should not attempt to allocate memory if we are overlaying the current process, because the new process will simply re-use the block we already have allocated. This was causing execl() to fail in applications which use it to @@ -822,7 +835,7 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode) asize = exe_size; /* /// End of additions. Jun 11, 2000 - rbc */ - if ( ModeLoadHigh && uppermem_root) + if ( ModeLoadHigh ) { mem_access_mode &= ~ModeLoadHigh; /* restore old situation */ DosUmbLink(UMBstate); /* restore link state */ @@ -875,6 +888,9 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode) if (exe_size > 0) { + UCOUNT nBytesRead; + BYTE FAR *sp; + if (mode != OVERLAY) { if ((header.exMinAlloc == 0) && (header.exMaxAlloc == 0)) @@ -894,8 +910,13 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode) } while (nBytesRead && exe_size > 0); } - - /* relocate the image for new segment */ + } + + { /* relocate the image for new segment */ + COUNT i; + UWORD reloc[2]; + seg FAR *spot; + doslseek(rc, (LONG) header.exRelocTable, 0); for (i = 0; i < header.exRelocItems; i++) { @@ -915,7 +936,8 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode) *spot += start_seg; } } - + } + /* and finally close the file */ DosClose(rc); @@ -923,6 +945,11 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode) if (mode == OVERLAY) return SUCCESS; + + { + psp FAR *p; + psp FAR *q = MK_FP(cu_psp, 0); + /* point to the PSP so we can build it */ p = MK_FP(mem, 0); setvec(0x22, (VOID(INRPT FAR *) (VOID)) MK_FP(user_r->CS, user_r->IP)); @@ -939,8 +966,9 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode) switch (mode) { case LOADNGO: + { /* build the user area on the stack */ - irp = MK_FP(header.exInitSS + start_seg, + iregs FAR *irp = MK_FP(header.exInitSS + start_seg, ((header.exInitSP - sizeof(iregs)) & 0xffff)); /* start allocating REGs */ @@ -963,9 +991,10 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode) if (InDOS) --InDOS; exec_user(irp); - /* We should never be here */ - fatal("KERNEL RETURNED!!!"); + /* We should never be here + fatal("KERNEL RETURNED!!!"); */ break; + } case LOAD: cu_psp = mem; @@ -974,6 +1003,7 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode) exp->exec.start_addr = MK_FP(header.exInitCS + start_seg, header.exInitIP); return SUCCESS; } + } return DE_INVLDFMT; } diff --git a/kernel/turboc.cfg b/kernel/turboc.cfg index fa63626..73162d2 100644 --- a/kernel/turboc.cfg +++ b/kernel/turboc.cfg @@ -1,4 +1,3 @@ --1- -f- -ff- -O diff --git a/readme.txt b/readme.txt index 43048a5..3d52068 100644 --- a/readme.txt +++ b/readme.txt @@ -13,14 +13,6 @@ See the DOCS directory for more documentation and information about the FreeDOS Kernel. -AGREEMENT ---------- -All users of the FreeDOS kernel must accept the disclaimer of -warranty and license terms contained in the file "COPYING" in order -to use it. You may not, under any circumstance, use this operating -system or any component without first reading and agreeing to the -terms of the license. - BUG REPORTS ----------- If you have found a bug, think you have found a bug, or would just diff --git a/sys/sys.c b/sys/sys.c index 77dc7c4..c2ed358 100644 --- a/sys/sys.c +++ b/sys/sys.c @@ -26,9 +26,12 @@ ***************************************************************/ /* $Log$ - * Revision 1.10 2001/09/24 02:28:14 bartoldeman - * Minor printf fixes. + * Revision 1.11 2001/11/04 19:47:39 bartoldeman + * kernel 2025a changes: see history.txt * +/* Revision 1.10 2001/09/24 02:28:14 bartoldeman +/* Minor printf fixes. +/* /* Revision 1.9 2001/09/24 02:21:14 bartoldeman /* SYS and printer fixes /* @@ -160,7 +163,8 @@ #include #endif #include -#include +/*#include */ +#define MAXPATH 260 #include "portab.h" #include "b_fat12.h" @@ -169,7 +173,7 @@ #include "b_fat32.h" #endif -BYTE pgm[] = "sys"; +BYTE pgm[] = "SYS"; void put_boot(COUNT); BOOL check_space(COUNT, BYTE *); @@ -257,6 +261,7 @@ UBYTE newboot[SEC_SIZE], oldboot[SEC_SIZE]; #define SBSIZE32 (sizeof(struct bootsectortype32) - SBOFFSET) +int FDKrnConfigMain(int argc,char **argv); int main(int argc, char **argv) { @@ -267,6 +272,11 @@ int main(int argc, char **argv) WORD slen; printf("FreeDOS System Installer " SYS_VERSION "\n\n"); + + if (memicmp(argv[1],"CONFIG",6) == 0) + { + exit(FDKrnConfigMain(argc,argv)); + } if (argc == 2) { @@ -294,6 +304,7 @@ int main(int argc, char **argv) printf("Usage: %s [source] drive\n", pgm); printf(" source = A:,B:,C:\\KERNEL\\BIN\\,etc., or current directory if not given\n"); printf(" drive = A,B,etc.\n"); + printf("%s CONFIG /help\n",pgm); exit(1); } @@ -307,7 +318,13 @@ int main(int argc, char **argv) if ((strlen(srcPath) > 1) && (srcPath[1] == ':')) /* src specifies drive */ srcDrive = toupper(*srcPath) - 'A'; else /* src doesn't specify drive, so assume current drive */ + { +#ifdef __TURBOC__ srcDrive = getdisk(); +#else + _dos_getdrive(&srcDrive); +#endif + } /* Don't try root if src==dst drive or source path given */ if ( (drive == srcDrive) || (*srcPath && ((srcPath[1] != ':') || ((srcPath[1] == ':') && srcPath[2]))) ) @@ -700,7 +717,7 @@ BOOL copy(COUNT drive, BYTE * srcPath, BYTE * rootPath, BYTE * file) copied += ret; } -#ifdef __TURBO__ +#ifdef __TURBOC__ { struct ftime ftime; getftime(fdin, &ftime);